| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "gpu/command_buffer/service/gles2_cmd_apply_framebuffer_attachment_cmaa
_intel.h" | 5 #include "gpu/command_buffer/service/gles2_cmd_apply_framebuffer_attachment_cmaa
_intel.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "gpu/command_buffer/service/framebuffer_manager.h" | 8 #include "gpu/command_buffer/service/framebuffer_manager.h" |
| 9 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 9 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
| 10 #include "ui/gl/gl_context.h" | 10 #include "ui/gl/gl_context.h" |
| 11 #include "ui/gl/gl_gl_api_implementation.h" | 11 #include "ui/gl/gl_gl_api_implementation.h" |
| 12 #include "ui/gl/gl_version_info.h" | 12 #include "ui/gl/gl_version_info.h" |
| 13 | 13 |
| 14 #define SHADER(Src) #Src | 14 #define SHADER(Src) #Src |
| 15 | 15 |
| 16 namespace gpu { | 16 namespace gpu { |
| 17 | 17 |
| 18 ApplyFramebufferAttachmentCMAAINTELResourceManager:: | 18 ApplyFramebufferAttachmentCMAAINTELResourceManager:: |
| 19 ApplyFramebufferAttachmentCMAAINTELResourceManager() | 19 ApplyFramebufferAttachmentCMAAINTELResourceManager() |
| 20 : initialized_(false), | 20 : initialized_(false), |
| 21 textures_initialized_(false), | 21 textures_initialized_(false), |
| 22 is_in_gamma_correct_mode_(false), | 22 is_in_gamma_correct_mode_(false), |
| 23 supports_usampler_(true), | 23 supports_usampler_(true), |
| 24 supports_r8_image_(true), | 24 supports_r8_image_(true), |
| 25 supports_r8_read_format_(true), | 25 supports_r8_read_format_(true), |
| 26 is_gles31_compatible_(false), | 26 is_gles31_compatible_(false), |
| 27 frame_id_(0), | 27 frame_id_(0), |
| 28 width_(0), | 28 width_(0), |
| 29 height_(0), | 29 height_(0), |
| 30 copy_to_framebuffer_shader_(0), | |
| 31 copy_to_image_shader_(0), | |
| 32 edges0_shader_(0), | 30 edges0_shader_(0), |
| 33 edges1_shader_(0), | 31 edges1_shader_(0), |
| 34 edges_combine_shader_(0), | 32 edges_combine_shader_(0), |
| 35 process_and_apply_shader_(0), | 33 process_and_apply_shader_(0), |
| 36 debug_display_edges_shader_(0), | 34 debug_display_edges_shader_(0), |
| 37 cmaa_framebuffer_(0), | 35 cmaa_framebuffer_(0), |
| 38 copy_framebuffer_(0), | 36 copy_framebuffer_(0), |
| 39 rgba8_texture_(0), | 37 rgba8_texture_(0), |
| 40 working_color_texture_(0), | 38 working_color_texture_(0), |
| 41 edges0_texture_(0), | 39 edges0_texture_(0), |
| 42 edges1_texture_(0), | 40 edges1_texture_(0), |
| 43 mini4_edge_texture_(0), | 41 mini4_edge_texture_(0), |
| 44 mini4_edge_depth_texture_(0), | 42 mini4_edge_depth_texture_(0), |
| 45 edges1_shader_result_texture_float4_slot1_(0), | 43 edges1_shader_result_texture_float4_slot1_(0), |
| 46 edges1_shader_result_texture_(0), | 44 edges1_shader_result_texture_(0), |
| 47 edges_combine_shader_result_texture_float4_slot1_(0), | 45 edges_combine_shader_result_texture_float4_slot1_(0), |
| 48 process_and_apply_shader_result_texture_float4_slot1_(0), | 46 process_and_apply_shader_result_texture_float4_slot1_(0), |
| 49 edges_combine_shader_result_texture_slot2_(0), | 47 edges_combine_shader_result_texture_slot2_(0) {} |
| 50 copy_to_image_shader_outTexture_(0) {} | |
| 51 | 48 |
| 52 ApplyFramebufferAttachmentCMAAINTELResourceManager:: | 49 ApplyFramebufferAttachmentCMAAINTELResourceManager:: |
| 53 ~ApplyFramebufferAttachmentCMAAINTELResourceManager() { | 50 ~ApplyFramebufferAttachmentCMAAINTELResourceManager() { |
| 54 Destroy(); | 51 Destroy(); |
| 55 } | 52 } |
| 56 | 53 |
| 57 void ApplyFramebufferAttachmentCMAAINTELResourceManager::Initialize( | 54 void ApplyFramebufferAttachmentCMAAINTELResourceManager::Initialize( |
| 58 gles2::GLES2Decoder* decoder) { | 55 gles2::GLES2Decoder* decoder) { |
| 59 DCHECK(decoder); | 56 DCHECK(decoder); |
| 60 is_gles31_compatible_ = | 57 is_gles31_compatible_ = |
| 61 decoder->GetGLContext()->GetVersionInfo()->IsAtLeastGLES(3, 1); | 58 decoder->GetGLContext()->GetVersionInfo()->IsAtLeastGLES(3, 1); |
| 62 | 59 |
| 63 copy_to_image_shader_ = CreateProgram("", vert_str_, copy_frag_str_); | |
| 64 copy_to_framebuffer_shader_ = | |
| 65 CreateProgram("#define OUT_FBO 1\n", vert_str_, copy_frag_str_); | |
| 66 | |
| 67 // Check if RGBA8UI is supported as an FBO colour target with depth. | 60 // Check if RGBA8UI is supported as an FBO colour target with depth. |
| 68 // If not supported, GLSL needs to convert the data to/from float so there is | 61 // If not supported, GLSL needs to convert the data to/from float so there is |
| 69 // a small extra cost. | 62 // a small extra cost. |
| 70 { | 63 { |
| 71 GLuint rgba8ui_texture = 0, depth_texture = 0; | 64 GLuint rgba8ui_texture = 0, depth_texture = 0; |
| 72 glGenTextures(1, &rgba8ui_texture); | 65 glGenTextures(1, &rgba8ui_texture); |
| 73 glBindTexture(GL_TEXTURE_2D, rgba8ui_texture); | 66 glBindTexture(GL_TEXTURE_2D, rgba8ui_texture); |
| 74 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8UI, 4, 4); | 67 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8UI, 4, 4); |
| 75 | 68 |
| 76 glGenTextures(1, &depth_texture); | 69 glGenTextures(1, &depth_texture); |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 182 edges1_shader_result_texture_float4_slot1_ = | 175 edges1_shader_result_texture_float4_slot1_ = |
| 183 glGetUniformLocation(edges0_shader_, "g_resultTextureFlt4Slot1"); | 176 glGetUniformLocation(edges0_shader_, "g_resultTextureFlt4Slot1"); |
| 184 edges1_shader_result_texture_ = | 177 edges1_shader_result_texture_ = |
| 185 glGetUniformLocation(edges1_shader_, "g_resultTexture"); | 178 glGetUniformLocation(edges1_shader_, "g_resultTexture"); |
| 186 edges_combine_shader_result_texture_float4_slot1_ = | 179 edges_combine_shader_result_texture_float4_slot1_ = |
| 187 glGetUniformLocation(edges_combine_shader_, "g_resultTextureFlt4Slot1"); | 180 glGetUniformLocation(edges_combine_shader_, "g_resultTextureFlt4Slot1"); |
| 188 edges_combine_shader_result_texture_slot2_ = | 181 edges_combine_shader_result_texture_slot2_ = |
| 189 glGetUniformLocation(edges_combine_shader_, "g_resultTextureSlot2"); | 182 glGetUniformLocation(edges_combine_shader_, "g_resultTextureSlot2"); |
| 190 process_and_apply_shader_result_texture_float4_slot1_ = glGetUniformLocation( | 183 process_and_apply_shader_result_texture_float4_slot1_ = glGetUniformLocation( |
| 191 process_and_apply_shader_, "g_resultTextureFlt4Slot1"); | 184 process_and_apply_shader_, "g_resultTextureFlt4Slot1"); |
| 192 copy_to_image_shader_outTexture_ = | |
| 193 glGetUniformLocation(copy_to_image_shader_, "outTexture"); | |
| 194 | 185 |
| 195 initialized_ = true; | 186 initialized_ = true; |
| 196 } | 187 } |
| 197 | 188 |
| 198 void ApplyFramebufferAttachmentCMAAINTELResourceManager::Destroy() { | 189 void ApplyFramebufferAttachmentCMAAINTELResourceManager::Destroy() { |
| 199 if (!initialized_) | 190 if (!initialized_) |
| 200 return; | 191 return; |
| 201 | 192 |
| 202 ReleaseTextures(); | 193 ReleaseTextures(); |
| 203 | 194 |
| 204 glDeleteProgram(copy_to_image_shader_); | |
| 205 glDeleteProgram(copy_to_framebuffer_shader_); | |
| 206 glDeleteProgram(process_and_apply_shader_); | 195 glDeleteProgram(process_and_apply_shader_); |
| 207 glDeleteProgram(edges_combine_shader_); | 196 glDeleteProgram(edges_combine_shader_); |
| 208 glDeleteProgram(edges1_shader_); | 197 glDeleteProgram(edges1_shader_); |
| 209 glDeleteProgram(edges0_shader_); | 198 glDeleteProgram(edges0_shader_); |
| 210 glDeleteProgram(debug_display_edges_shader_); | 199 glDeleteProgram(debug_display_edges_shader_); |
| 211 | 200 |
| 212 initialized_ = false; | 201 initialized_ = false; |
| 213 } | 202 } |
| 214 | 203 |
| 215 // Apply CMAA(Conservative Morphological Anti-Aliasing) algorithm to the | 204 // Apply CMAA(Conservative Morphological Anti-Aliasing) algorithm to the |
| 216 // color attachments of currently bound draw framebuffer. | 205 // color attachments of currently bound draw framebuffer. |
| 217 // Reference GL_INTEL_framebuffer_CMAA for details. | 206 // Reference GL_INTEL_framebuffer_CMAA for details. |
| 218 void ApplyFramebufferAttachmentCMAAINTELResourceManager:: | 207 void ApplyFramebufferAttachmentCMAAINTELResourceManager:: |
| 219 ApplyFramebufferAttachmentCMAAINTEL(gles2::GLES2Decoder* decoder, | 208 ApplyFramebufferAttachmentCMAAINTEL(gles2::GLES2Decoder* decoder, |
| 220 gles2::Framebuffer* framebuffer) { | 209 gles2::Framebuffer* framebuffer) { |
| 221 DCHECK(decoder); | 210 DCHECK(decoder); |
| 222 DCHECK(initialized_); | 211 DCHECK(initialized_); |
| 223 if (!framebuffer) | 212 if (!framebuffer) |
| 224 return; | 213 return; |
| 225 | 214 |
| 226 GLuint last_framebuffer = framebuffer->service_id(); | 215 glDisable(GL_SCISSOR_TEST); |
| 216 glDisable(GL_STENCIL_TEST); |
| 217 glDisable(GL_CULL_FACE); |
| 218 glDisable(GL_BLEND); |
| 227 | 219 |
| 228 // Process each color attachment of the current draw framebuffer. | 220 // Process each color attachment of the current draw framebuffer. |
| 229 uint32_t max_draw_buffers = decoder->GetContextGroup()->max_draw_buffers(); | 221 uint32_t max_draw_buffers = decoder->GetContextGroup()->max_draw_buffers(); |
| 230 for (uint32_t i = 0; i < max_draw_buffers; i++) { | 222 for (uint32_t i = 0; i < max_draw_buffers; i++) { |
| 231 const gles2::Framebuffer::Attachment* attachment = | 223 const gles2::Framebuffer::Attachment* attachment = |
| 232 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0 + i); | 224 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0 + i); |
| 233 if (attachment && attachment->IsTextureAttachment()) { | 225 if (attachment && attachment->IsTextureAttachment()) { |
| 234 // Get the texture info. | 226 // Get the texture info. |
| 235 GLuint source_texture_client_id = attachment->object_name(); | 227 GLuint source_texture_client_id = attachment->object_name(); |
| 236 GLuint source_texture = 0; | 228 GLuint source_texture = 0; |
| 237 if (!decoder->GetServiceTextureId(source_texture_client_id, | 229 if (!decoder->GetServiceTextureId(source_texture_client_id, |
| 238 &source_texture)) | 230 &source_texture)) |
| 239 continue; | 231 continue; |
| 240 GLsizei width = attachment->width(); | 232 GLsizei width = attachment->width(); |
| 241 GLsizei height = attachment->height(); | 233 GLsizei height = attachment->height(); |
| 242 GLenum internal_format = attachment->internal_format(); | 234 GLenum internal_format = attachment->internal_format(); |
| 243 | 235 |
| 244 // Resize internal structures - only if needed. | 236 // Resize internal structures - only if needed. |
| 245 OnSize(width, height); | 237 OnSize(width, height); |
| 246 | 238 |
| 247 // CMAA internally expects GL_RGBA8 textures. | 239 // CMAA internally expects GL_RGBA8 textures. |
| 248 // Process using a GL_RGBA8 copy if this is not the case. | 240 // Process using a GL_RGBA8 copy if this is not the case. |
| 249 bool do_copy = internal_format != GL_RGBA8; | 241 bool do_copy = internal_format != GL_RGBA8; |
| 250 | 242 |
| 251 // Copy source_texture to rgba8_texture_ | 243 // Copy source_texture to rgba8_texture_ |
| 252 if (do_copy) { | 244 if (do_copy) { |
| 253 CopyTexture(source_texture, rgba8_texture_, false); | 245 glBindFramebufferEXT(GL_FRAMEBUFFER, copy_framebuffer_); |
| 246 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, |
| 247 GL_TEXTURE_2D, source_texture, 0); |
| 248 CopyTexture(rgba8_texture_); |
| 254 } | 249 } |
| 255 | 250 |
| 256 // CMAA Effect | 251 // CMAA Effect |
| 257 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, last_framebuffer); | |
| 258 if (do_copy) { | 252 if (do_copy) { |
| 259 ApplyCMAAEffectTexture(rgba8_texture_, rgba8_texture_); | 253 ApplyCMAAEffectTexture(rgba8_texture_, rgba8_texture_); |
| 260 } else { | 254 } else { |
| 261 ApplyCMAAEffectTexture(source_texture, source_texture); | 255 ApplyCMAAEffectTexture(source_texture, source_texture); |
| 262 } | 256 } |
| 263 | 257 |
| 264 // Copy rgba8_texture_ to source_texture | 258 // Copy rgba8_texture_ to source_texture |
| 265 if (do_copy) { | 259 if (do_copy) { |
| 266 // Move source_texture to the first color attachment of the copy fbo. | |
| 267 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, last_framebuffer); | |
| 268 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, | |
| 269 GL_TEXTURE_2D, 0, 0); | |
| 270 glBindFramebufferEXT(GL_FRAMEBUFFER, copy_framebuffer_); | |
| 271 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | |
| 272 GL_TEXTURE_2D, source_texture, 0); | |
| 273 | |
| 274 CopyTexture(rgba8_texture_, source_texture, true); | |
| 275 | |
| 276 // Restore color attachments | |
| 277 glBindFramebufferEXT(GL_FRAMEBUFFER, copy_framebuffer_); | 260 glBindFramebufferEXT(GL_FRAMEBUFFER, copy_framebuffer_); |
| 278 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | 261 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, |
| 279 GL_TEXTURE_2D, rgba8_texture_, 0); | 262 GL_TEXTURE_2D, rgba8_texture_, 0); |
| 280 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, last_framebuffer); | 263 CopyTexture(source_texture); |
| 281 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, | |
| 282 GL_TEXTURE_2D, source_texture, 0); | |
| 283 } | 264 } |
| 265 decoder->RestoreTextureState(source_texture); |
| 284 } | 266 } |
| 285 } | 267 } |
| 286 | 268 |
| 287 // Restore state | 269 // Restore state |
| 288 decoder->RestoreAllAttributes(); | 270 decoder->RestoreAllAttributes(); |
| 289 decoder->RestoreTextureUnitBindings(0); | 271 decoder->RestoreTextureUnitBindings(0); |
| 290 decoder->RestoreTextureUnitBindings(1); | 272 decoder->RestoreTextureUnitBindings(1); |
| 291 decoder->RestoreActiveTexture(); | 273 decoder->RestoreActiveTexture(); |
| 292 decoder->RestoreProgramBindings(); | 274 decoder->RestoreProgramBindings(); |
| 293 decoder->RestoreBufferBindings(); | 275 decoder->RestoreBufferBindings(); |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 557 glDeleteTextures(1, &edges0_texture_); | 539 glDeleteTextures(1, &edges0_texture_); |
| 558 glDeleteTextures(1, &edges1_texture_); | 540 glDeleteTextures(1, &edges1_texture_); |
| 559 glDeleteTextures(1, &mini4_edge_texture_); | 541 glDeleteTextures(1, &mini4_edge_texture_); |
| 560 glDeleteTextures(1, &mini4_edge_depth_texture_); | 542 glDeleteTextures(1, &mini4_edge_depth_texture_); |
| 561 glDeleteTextures(1, &working_color_texture_); | 543 glDeleteTextures(1, &working_color_texture_); |
| 562 } | 544 } |
| 563 textures_initialized_ = false; | 545 textures_initialized_ = false; |
| 564 } | 546 } |
| 565 | 547 |
| 566 void ApplyFramebufferAttachmentCMAAINTELResourceManager::CopyTexture( | 548 void ApplyFramebufferAttachmentCMAAINTELResourceManager::CopyTexture( |
| 567 GLint source, | 549 GLint dest) { |
| 568 GLint dest, | |
| 569 bool via_fbo) { | |
| 570 glViewport(0, 0, width_, height_); | |
| 571 glActiveTexture(GL_TEXTURE0); | 550 glActiveTexture(GL_TEXTURE0); |
| 572 glBindTexture(GL_TEXTURE_2D, source); | 551 glBindTexture(GL_TEXTURE_2D, dest); |
| 552 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| 553 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| 554 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| 555 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| 573 | 556 |
| 574 if (!via_fbo) { | 557 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, width_, height_); |
| 575 glUseProgram(copy_to_image_shader_); | |
| 576 if (!is_gles31_compatible_) { | |
| 577 glUniform1i(copy_to_image_shader_outTexture_, 0); | |
| 578 } | |
| 579 glBindImageTextureEXT(0, dest, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8); | |
| 580 } else { | |
| 581 glDisable(GL_DEPTH_TEST); | |
| 582 glDisable(GL_STENCIL_TEST); | |
| 583 glDisable(GL_CULL_FACE); | |
| 584 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); | |
| 585 glDepthMask(GL_FALSE); | |
| 586 glDisable(GL_BLEND); | |
| 587 glUseProgram(copy_to_framebuffer_shader_); | |
| 588 } | |
| 589 | |
| 590 glDrawArrays(GL_TRIANGLES, 0, 3); | |
| 591 glUseProgram(0); | |
| 592 glBindTexture(GL_TEXTURE_2D, 0); | |
| 593 } | 558 } |
| 594 | 559 |
| 595 GLuint ApplyFramebufferAttachmentCMAAINTELResourceManager::CreateProgram( | 560 GLuint ApplyFramebufferAttachmentCMAAINTELResourceManager::CreateProgram( |
| 596 const char* defines, | 561 const char* defines, |
| 597 const char* vs_source, | 562 const char* vs_source, |
| 598 const char* fs_source) { | 563 const char* fs_source) { |
| 599 GLuint program = glCreateProgram(); | 564 GLuint program = glCreateProgram(); |
| 600 | 565 |
| 601 GLuint vs = CreateShader(GL_VERTEX_SHADER, defines, vs_source); | 566 GLuint vs = CreateShader(GL_VERTEX_SHADER, defines, vs_source); |
| 602 GLuint fs = CreateShader(GL_FRAGMENT_SHADER, defines, fs_source); | 567 GLuint fs = CreateShader(GL_FRAGMENT_SHADER, defines, fs_source); |
| (...skipping 1271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1874 CombineEdges(); | 1839 CombineEdges(); |
| 1875 \n#endif\n | 1840 \n#endif\n |
| 1876 \n#if defined BLUR_EDGES\n | 1841 \n#if defined BLUR_EDGES\n |
| 1877 BlurEdges(); | 1842 BlurEdges(); |
| 1878 \n#endif\n | 1843 \n#endif\n |
| 1879 \n#if defined DISPLAY_EDGES\n | 1844 \n#if defined DISPLAY_EDGES\n |
| 1880 DisplayEdges(); | 1845 DisplayEdges(); |
| 1881 \n#endif\n | 1846 \n#endif\n |
| 1882 } | 1847 } |
| 1883 ); | 1848 ); |
| 1884 | |
| 1885 const char | |
| 1886 ApplyFramebufferAttachmentCMAAINTELResourceManager::copy_frag_str_[] = | |
| 1887 SHADER( | |
| 1888 precision highp float; | |
| 1889 layout(binding = 0) uniform highp sampler2D inTexture; | |
| 1890 layout(location = 0) out vec4 outColor; | |
| 1891 \n#ifdef GL_ES\n | |
| 1892 layout(binding = 0, rgba8) restrict writeonly uniform highp | |
| 1893 image2D outTexture; | |
| 1894 \n#else\n | |
| 1895 layout(rgba8) restrict writeonly uniform highp image2D outTexture; | |
| 1896 \n#endif\n | |
| 1897 | |
| 1898 void main() { | |
| 1899 ivec2 screenPosI = ivec2( gl_FragCoord.xy ); | |
| 1900 vec4 pixel = texelFetch(inTexture, screenPosI, 0); | |
| 1901 \n#ifdef OUT_FBO\n | |
| 1902 outColor = pixel; | |
| 1903 \n#else\n | |
| 1904 imageStore(outTexture, screenPosI, pixel); | |
| 1905 \n#endif\n | |
| 1906 } | |
| 1907 ); | |
| 1908 /* clang-format on */ | 1849 /* clang-format on */ |
| 1909 | 1850 |
| 1910 } // namespace gpu | 1851 } // namespace gpu |
| OLD | NEW |