2 * Copyright 2023 Henri Verbeet for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #define WIDL_C_INLINE_WRAPPERS
27 #define VKD3D_TEST_NO_DEFS
28 #define GL_GLEXT_PROTOTYPES
30 #include <EGL/eglext.h>
32 #include "shader_runner.h"
33 #include "vkd3d_d3dcompiler.h"
35 static PFNGLDEPTHBOUNDSEXTPROC p_glDepthBoundsEXT
;
36 static PFNGLSPECIALIZESHADERPROC p_glSpecializeShader
;
47 unsigned int component_count
;
50 GLenum internal_format
;
59 const struct format_info
*format
;
64 static struct gl_resource
*gl_resource(struct resource
*r
)
66 return CONTAINING_RECORD(r
, struct gl_resource
, r
);
71 struct shader_runner r
;
72 struct shader_runner_caps caps
;
77 uint32_t attribute_map
;
80 enum vkd3d_shader_tessellator_output_primitive output_primitive
;
81 enum vkd3d_shader_tessellator_partitioning partitioning
;
83 struct vkd3d_shader_combined_resource_sampler
*combined_samplers
;
84 unsigned int combined_sampler_count
;
85 enum shading_language language
;
88 static struct gl_runner
*gl_runner(struct shader_runner
*r
)
90 return CONTAINING_RECORD(r
, struct gl_runner
, r
);
93 static void debug_output(GLenum source
, GLenum type
, GLuint id
, GLenum severity
,
94 GLsizei length
, const GLchar
*message
, const void *userParam
)
96 if (message
[length
- 1] == '\n')
98 trace("%.*s\n", length
, message
);
101 static bool check_extension(GLenum name
, const char *extension
, GLint extension_count
)
103 for (GLint i
= 0; i
< extension_count
; ++i
)
105 if (!strcmp(extension
, (const char *)glGetStringi(name
, i
)))
112 static bool check_gl_extension(const char *extension
, GLint extension_count
)
114 return check_extension(GL_EXTENSIONS
, extension
, extension_count
);
117 static bool check_spirv_extension(const char *extension
, GLint extension_count
)
119 return check_extension(GL_SPIR_V_EXTENSIONS
, extension
, extension_count
);
122 static bool check_gl_extensions(struct gl_runner
*runner
)
124 GLint count
, spirv_count
= 0;
126 static const char *required_extensions
[] =
128 "GL_ARB_clip_control",
129 "GL_ARB_compute_shader",
131 "GL_ARB_internalformat_query",
132 "GL_ARB_sampler_objects",
133 "GL_ARB_shader_image_load_store",
134 "GL_ARB_tessellation_shader",
135 "GL_ARB_texture_storage",
138 glGetIntegerv(GL_NUM_EXTENSIONS
, &count
);
140 if (runner
->language
== SPIR_V
)
142 if (!check_gl_extension("GL_ARB_gl_spirv", count
))
145 if (check_gl_extension("GL_ARB_spirv_extensions", count
))
146 glGetIntegerv(GL_NUM_SPIR_V_EXTENSIONS
, &spirv_count
);
149 for (unsigned int i
= 0; i
< ARRAY_SIZE(required_extensions
); ++i
)
151 if (!check_gl_extension(required_extensions
[i
], count
))
155 if (check_gl_extension("GL_ARB_gpu_shader_fp64", count
))
156 runner
->caps
.shader_caps
[SHADER_CAP_FLOAT64
] = true;
157 if (check_gl_extension("GL_ARB_gpu_shader_int64", count
))
158 runner
->caps
.shader_caps
[SHADER_CAP_INT64
] = true;
159 if (check_gl_extension("GL_ARB_shader_viewport_layer_array", count
) && (runner
->language
== GLSL
160 || check_spirv_extension("SPV_EXT_shader_viewport_index_layer", spirv_count
)))
161 runner
->caps
.shader_caps
[SHADER_CAP_RT_VP_ARRAY_INDEX
] = true;
162 if (check_gl_extension("GL_EXT_depth_bounds_test", count
))
163 runner
->caps
.shader_caps
[SHADER_CAP_DEPTH_BOUNDS
] = true;
168 static bool check_egl_client_extension(const char *extension
)
170 const char *extensions
, *p
;
173 if (!(extensions
= eglQueryString(EGL_NO_DISPLAY
, EGL_EXTENSIONS
)))
176 len
= strlen(extension
);
179 if (!(p
= strchr(extensions
, ' ')))
180 p
= &extensions
[strlen(extensions
)];
181 if (p
- extensions
== len
&& !memcmp(extensions
, extension
, len
))
190 static bool check_glsl_support(void)
192 const enum vkd3d_shader_target_type
*target_types
;
193 unsigned int count
, i
;
195 target_types
= vkd3d_shader_get_supported_target_types(VKD3D_SHADER_SOURCE_DXBC_TPF
, &count
);
196 for (i
= 0; i
< count
; ++i
)
198 if (target_types
[i
] == VKD3D_SHADER_TARGET_GLSL
)
205 static const struct format_info
*get_format_info(enum DXGI_FORMAT format
, bool is_shadow
)
209 static const struct format_info format_info
[] =
211 {DXGI_FORMAT_UNKNOWN
, 1, true, false, GL_R32UI
, GL_RED_INTEGER
, GL_UNSIGNED_INT
},
212 {DXGI_FORMAT_R32G32B32A32_FLOAT
, 4, false, false, GL_RGBA32F
, GL_RGBA
, GL_FLOAT
},
213 {DXGI_FORMAT_R32G32B32A32_UINT
, 4, true, false, GL_RGBA32UI
, GL_RGBA_INTEGER
, GL_UNSIGNED_INT
},
214 {DXGI_FORMAT_R32G32B32A32_SINT
, 4, true, false, GL_RGBA32I
, GL_RGBA_INTEGER
, GL_INT
},
215 {DXGI_FORMAT_R32G32_FLOAT
, 2, false, false, GL_RG32F
, GL_RG
, GL_FLOAT
},
216 {DXGI_FORMAT_R32G32_UINT
, 2, true, false, GL_RG32UI
, GL_RG_INTEGER
, GL_UNSIGNED_INT
},
217 {DXGI_FORMAT_R32G32_SINT
, 2, true, false, GL_RG32I
, GL_RG_INTEGER
, GL_INT
},
218 {DXGI_FORMAT_R32_FLOAT
, 1, false, false, GL_R32F
, GL_RED
, GL_FLOAT
},
219 {DXGI_FORMAT_R32_FLOAT
, 1, false, true, GL_DEPTH_COMPONENT32F
, GL_DEPTH_COMPONENT
, GL_FLOAT
},
220 {DXGI_FORMAT_D32_FLOAT
, 1, false, true, GL_DEPTH_COMPONENT32F
, GL_DEPTH_COMPONENT
, GL_FLOAT
},
221 {DXGI_FORMAT_R32_UINT
, 1, true, false, GL_R32UI
, GL_RED_INTEGER
, GL_UNSIGNED_INT
},
222 {DXGI_FORMAT_R32_SINT
, 1, true, false, GL_R32I
, GL_RED_INTEGER
, GL_INT
},
223 {DXGI_FORMAT_R32_TYPELESS
, 1, true, false, GL_R32UI
, GL_RED_INTEGER
, GL_UNSIGNED_INT
},
226 for (i
= 0; i
< ARRAY_SIZE(format_info
); ++i
)
228 if (format_info
[i
].f
== format
&& format_info
[i
].is_shadow
== is_shadow
)
229 return &format_info
[i
];
232 fatal_error("Failed to find format info for format %#x.\n", format
);
235 static uint32_t get_format_support(struct gl_runner
*runner
, enum DXGI_FORMAT format
)
237 GLenum gl_format
= get_format_info(format
, false)->internal_format
;
241 /* TODO: Probably check for more targets instead of just GL_TEXTURE_2D. */
242 glGetInternalformativ(GL_TEXTURE_2D
, gl_format
, GL_SHADER_IMAGE_LOAD
, 1, &support
);
243 if (support
!= GL_NONE
)
244 ret
|= FORMAT_CAP_UAV_LOAD
;
249 static bool gl_runner_init(struct gl_runner
*runner
, enum shading_language language
)
251 PFNEGLQUERYDEVICESEXTPROC eglQueryDevicesEXT
;
252 const char *glsl_version
= NULL
;
253 EGLint count
, extension_count
;
254 EGLDeviceEXT
*devices
;
260 static const EGLint attributes
[] =
262 EGL_CONTEXT_OPENGL_PROFILE_MASK
, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT
,
263 EGL_CONTEXT_FLAGS_KHR
, EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR
,
264 EGL_CONTEXT_MAJOR_VERSION
, 3,
265 EGL_CONTEXT_MINOR_VERSION
, 2,
269 static const enum DXGI_FORMAT formats
[] =
272 DXGI_FORMAT_R32_FLOAT
,
273 DXGI_FORMAT_R32_UINT
,
274 DXGI_FORMAT_R32_SINT
,
275 DXGI_FORMAT_R32G32B32A32_FLOAT
,
276 DXGI_FORMAT_R32G32B32A32_UINT
,
277 DXGI_FORMAT_R32G32B32A32_SINT
,
280 if (language
== GLSL
&& !check_glsl_support())
282 skip("GLSL support is not enabled. If this is unintentional, "
283 "add -DVKD3D_SHADER_UNSUPPORTED_GLSL to CPPFLAGS.\n");
287 memset(runner
, 0, sizeof(*runner
));
288 runner
->language
= language
;
290 if (!check_egl_client_extension("EGL_EXT_device_enumeration")
291 || !(eglQueryDevicesEXT
= (void *)eglGetProcAddress("eglQueryDevicesEXT")))
293 skip("Failed to retrieve eglQueryDevicesEXT.\n");
297 ret
= eglQueryDevicesEXT(0, NULL
, &count
);
298 ok(ret
, "Failed to query device count.\n");
300 devices
= calloc(count
, sizeof(*devices
));
301 ret
= eglQueryDevicesEXT(count
, devices
, &count
);
302 ok(ret
, "Failed to query devices.\n");
304 for (unsigned int i
= 0; i
< count
; ++i
)
306 if ((display
= eglGetPlatformDisplay(EGL_PLATFORM_DEVICE_EXT
, devices
[i
], NULL
)) == EGL_NO_DISPLAY
)
308 trace("Failed to get EGL display connection for device %u.\n", i
);
312 if (!eglInitialize(display
, NULL
, NULL
))
314 trace("Failed to initialise EGL display connection for device %u.\n", i
);
318 if (!eglBindAPI(EGL_OPENGL_API
))
320 trace("Failed to bind OpenGL API for device %u.\n", i
);
321 eglTerminate(display
);
325 if ((context
= eglCreateContext(display
, NULL
, EGL_NO_CONTEXT
, attributes
)) == EGL_NO_CONTEXT
)
327 trace("Failed to create EGL context for device %u.\n", i
);
328 eglTerminate(display
);
332 if (!eglMakeCurrent(display
, EGL_NO_SURFACE
, EGL_NO_SURFACE
, context
))
334 trace("Failed to make EGL context current for device %u.\n", i
);
335 eglDestroyContext(display
, context
);
336 eglTerminate(display
);
340 glsl_version
= (const char *)glGetString(GL_SHADING_LANGUAGE_VERSION
);
341 if (language
== GLSL
)
343 unsigned int major
, minor
;
344 sscanf(glsl_version
, "%u.%u", &major
, &minor
);
345 if (major
< 4 || (major
== 4 && minor
< 40))
347 trace("Device %u does not support GLSL 4.40.\n", i
);
348 eglMakeCurrent(display
, EGL_NO_SURFACE
, EGL_NO_SURFACE
, EGL_NO_CONTEXT
);
349 eglDestroyContext(display
, context
);
350 eglTerminate(display
);
355 memset(&runner
->caps
, 0, sizeof(runner
->caps
));
356 if (!check_gl_extensions(runner
))
358 trace("Device %u lacks required extensions.\n", i
);
359 eglMakeCurrent(display
, EGL_NO_SURFACE
, EGL_NO_SURFACE
, EGL_NO_CONTEXT
);
360 eglDestroyContext(display
, context
);
361 eglTerminate(display
);
364 runner
->caps
.runner
= language
== SPIR_V
? "OpenGL/SPIR-V" : "OpenGL/GLSL";
365 runner
->caps
.minimum_shader_model
= SHADER_MODEL_4_0
;
366 runner
->caps
.maximum_shader_model
= SHADER_MODEL_5_1
;
367 runner
->caps
.shader_caps
[SHADER_CAP_GEOMETRY_SHADER
] = true;
369 runner
->caps
.tag_count
= 0;
370 runner
->caps
.tags
[runner
->caps
.tag_count
++] = "opengl";
371 if (runner
->language
== GLSL
)
372 runner
->caps
.tags
[runner
->caps
.tag_count
++] = "glsl";
373 if (strncmp((const char *)glGetString(GL_RENDERER
), "llvmpipe ", 9) == 0)
374 runner
->caps
.tags
[runner
->caps
.tag_count
++] = "llvmpipe";
376 glGetIntegerv(GL_NUM_EXTENSIONS
, &extension_count
);
377 if (check_gl_extension("GL_ARB_internalformat_query2", extension_count
))
379 for (unsigned int j
= 0; j
< ARRAY_SIZE(formats
); ++j
)
381 runner
->caps
.format_caps
[formats
[j
]] = get_format_support(runner
, formats
[j
]);
385 trace("Using device %u.\n", i
);
386 runner
->display
= display
;
387 runner
->context
= context
;
393 if (!runner
->context
)
395 skip("Failed to find a usable OpenGL device.\n");
399 trace(" GL_VENDOR: %s\n", glGetString(GL_VENDOR
));
400 trace(" GL_RENDERER: %s\n", glGetString(GL_RENDERER
));
401 trace(" GL_VERSION: %s\n", glGetString(GL_VERSION
));
402 trace("GL_SHADING_LANGUAGE_VERSION: %s\n", glsl_version
);
404 p_glDepthBoundsEXT
= (void *)eglGetProcAddress("glDepthBoundsEXT");
405 p_glSpecializeShader
= (void *)eglGetProcAddress("glSpecializeShader");
407 glDebugMessageControl(GL_DONT_CARE
, GL_DONT_CARE
, GL_DEBUG_SEVERITY_NOTIFICATION
, 0, NULL
, GL_FALSE
);
408 glDebugMessageCallback(debug_output
, NULL
);
409 glClipControl(GL_UPPER_LEFT
, GL_ZERO_TO_ONE
);
411 glProvokingVertex(GL_FIRST_VERTEX_CONVENTION
);
412 glGenVertexArrays(1, &vao
);
413 glBindVertexArray(vao
);
418 static void reset_combined_samplers(struct gl_runner
*runner
)
420 free(runner
->combined_samplers
);
421 runner
->combined_samplers
= NULL
;
422 runner
->combined_sampler_count
= 0;
425 static void gl_runner_cleanup(struct gl_runner
*runner
)
429 reset_combined_samplers(runner
);
432 glDeleteFramebuffers(1, &runner
->fbo_id
);
434 ret
= eglMakeCurrent(runner
->display
, EGL_NO_SURFACE
, EGL_NO_SURFACE
, EGL_NO_CONTEXT
);
435 ok(ret
, "Failed to release current EGL context.\n");
436 ret
= eglDestroyContext(runner
->display
, runner
->context
);
437 ok(ret
, "Failed to destroy EGL context.\n");
438 ret
= eglTerminate(runner
->display
);
439 ok(ret
, "Failed to terminate EGL display connection.\n");
442 static bool init_resource_2d(struct gl_resource
*resource
, const struct resource_params
*params
)
444 unsigned int offset
, w
, h
, i
;
447 if (params
->desc
.sample_count
> 1)
448 target
= GL_TEXTURE_2D_MULTISAMPLE
;
449 else if (params
->desc
.depth
> 1)
450 target
= GL_TEXTURE_2D_ARRAY
;
452 target
= GL_TEXTURE_2D
;
453 resource
->target
= target
;
455 resource
->format
= get_format_info(params
->desc
.format
, params
->is_shadow
);
457 if (params
->desc
.sample_count
> 1)
459 GLint max_sample_count
;
461 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE
, resource
->format
->internal_format
, GL_SAMPLES
, 1, &max_sample_count
);
462 if (max_sample_count
< params
->desc
.sample_count
)
464 trace("Format #%x with sample count %u is not supported; skipping.\n", params
->desc
.format
, params
->desc
.sample_count
);
469 glGenTextures(1, &resource
->id
);
470 glBindTexture(target
, resource
->id
);
471 if (params
->desc
.sample_count
> 1)
473 glTexStorage2DMultisample(target
, params
->desc
.sample_count
,
474 resource
->format
->internal_format
, params
->desc
.width
, params
->desc
.height
, GL_FALSE
);
478 if (params
->desc
.depth
> 1)
479 glTexStorage3D(target
, params
->desc
.level_count
, resource
->format
->internal_format
,
480 params
->desc
.width
, params
->desc
.height
, params
->desc
.depth
);
482 glTexStorage2D(target
, params
->desc
.level_count
, resource
->format
->internal_format
,
483 params
->desc
.width
, params
->desc
.height
);
484 glTexParameteri(target
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
485 glTexParameteri(target
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST_MIPMAP_NEAREST
);
490 for (i
= 0, offset
= 0; i
< params
->desc
.level_count
; ++i
)
492 w
= get_level_dimension(params
->desc
.width
, i
);
493 h
= get_level_dimension(params
->desc
.height
, i
);
494 glTexSubImage2D(target
, i
, 0, 0, w
, h
, resource
->format
->format
,
495 resource
->format
->type
, params
->data
+ offset
);
496 offset
+= w
* h
* params
->desc
.texel_size
;
502 static void init_resource_buffer(struct gl_resource
*resource
, const struct resource_params
*params
)
504 GLenum target
= GL_TEXTURE_BUFFER
;
506 resource
->format
= get_format_info(params
->desc
.format
, false);
507 resource
->target
= target
;
509 glGenBuffers(1, &resource
->id
);
510 glBindBuffer(target
, resource
->id
);
511 glBufferData(target
, params
->data_size
, params
->data
, GL_STATIC_DRAW
);
513 glGenTextures(1, &resource
->tbo_id
);
514 glBindTexture(target
, resource
->tbo_id
);
515 glTexBuffer(target
, resource
->format
->internal_format
, resource
->id
);
518 static struct resource
*gl_runner_create_resource(struct shader_runner
*r
, const struct resource_params
*params
)
520 struct gl_resource
*resource
;
522 resource
= calloc(1, sizeof(*resource
));
523 init_resource(&resource
->r
, params
);
525 switch (params
->desc
.type
)
527 case RESOURCE_TYPE_RENDER_TARGET
:
528 case RESOURCE_TYPE_DEPTH_STENCIL
:
529 case RESOURCE_TYPE_TEXTURE
:
530 case RESOURCE_TYPE_UAV
:
531 if (params
->desc
.dimension
== RESOURCE_DIMENSION_BUFFER
)
532 init_resource_buffer(resource
, params
);
533 else if (!init_resource_2d(resource
, params
))
537 case RESOURCE_TYPE_VERTEX_BUFFER
:
538 glGenBuffers(1, &resource
->id
);
539 glBindBuffer(GL_ARRAY_BUFFER
, resource
->id
);
540 glBufferData(GL_ARRAY_BUFFER
, params
->data_size
, params
->data
, GL_STATIC_DRAW
);
547 static void gl_runner_destroy_resource(struct shader_runner
*r
, struct resource
*res
)
549 struct gl_resource
*resource
= gl_resource(res
);
551 switch (resource
->r
.desc
.type
)
553 case RESOURCE_TYPE_RENDER_TARGET
:
554 case RESOURCE_TYPE_DEPTH_STENCIL
:
555 case RESOURCE_TYPE_TEXTURE
:
556 case RESOURCE_TYPE_UAV
:
557 if (res
->desc
.dimension
== RESOURCE_DIMENSION_BUFFER
)
559 glDeleteTextures(1, &resource
->tbo_id
);
560 glDeleteBuffers(1, &resource
->id
);
564 glDeleteTextures(1, &resource
->id
);
568 case RESOURCE_TYPE_VERTEX_BUFFER
:
569 glDeleteBuffers(1, &resource
->id
);
576 static bool compile_shader(struct gl_runner
*runner
, enum shader_type shader_type
,
577 ID3DBlob
*blob
, struct vkd3d_shader_code
*out
)
579 struct vkd3d_shader_spirv_target_info spirv_info
= {.type
= VKD3D_SHADER_STRUCTURE_TYPE_SPIRV_TARGET_INFO
};
580 struct vkd3d_shader_interface_info interface_info
= {.type
= VKD3D_SHADER_STRUCTURE_TYPE_INTERFACE_INFO
};
581 struct vkd3d_shader_compile_info info
= {.type
= VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO
};
582 struct vkd3d_shader_resource_binding bindings
[MAX_RESOURCES
+ 1 /* CBV */];
583 struct vkd3d_shader_scan_combined_resource_sampler_info combined_sampler_info
;
584 struct vkd3d_shader_scan_hull_shader_tessellation_info tessellation_info
;
585 struct vkd3d_shader_spirv_domain_shader_target_info domain_info
;
586 struct vkd3d_shader_combined_resource_sampler
*sampler
;
587 enum vkd3d_shader_spirv_extension spirv_extensions
[1];
588 struct vkd3d_shader_resource_binding
*binding
;
589 struct vkd3d_shader_parameter parameters
[1];
590 unsigned int count
, i
;
594 const struct vkd3d_shader_compile_option options
[] =
596 {VKD3D_SHADER_COMPILE_OPTION_API_VERSION
, VKD3D_SHADER_API_VERSION_1_14
},
597 {VKD3D_SHADER_COMPILE_OPTION_FRAGMENT_COORDINATE_ORIGIN
,
598 VKD3D_SHADER_COMPILE_OPTION_FRAGMENT_COORDINATE_ORIGIN_LOWER_LEFT
},
599 {VKD3D_SHADER_COMPILE_OPTION_FEATURE
, shader_runner_caps_get_feature_flags(&runner
->caps
)},
602 info
.next
= &combined_sampler_info
;
603 info
.source
.code
= ID3D10Blob_GetBufferPointer(blob
);
604 info
.source
.size
= ID3D10Blob_GetBufferSize(blob
);
605 info
.source_type
= VKD3D_SHADER_SOURCE_DXBC_TPF
;
606 info
.target_type
= runner
->language
== SPIR_V
? VKD3D_SHADER_TARGET_SPIRV_BINARY
: VKD3D_SHADER_TARGET_GLSL
;
607 info
.options
= options
;
608 info
.option_count
= ARRAY_SIZE(options
);
609 info
.log_level
= VKD3D_SHADER_LOG_WARNING
;
611 combined_sampler_info
.type
= VKD3D_SHADER_STRUCTURE_TYPE_SCAN_COMBINED_RESOURCE_SAMPLER_INFO
;
612 combined_sampler_info
.next
= &tessellation_info
;
614 tessellation_info
.type
= VKD3D_SHADER_STRUCTURE_TYPE_SCAN_HULL_SHADER_TESSELLATION_INFO
;
615 tessellation_info
.next
= NULL
;
617 ret
= vkd3d_shader_scan(&info
, &messages
);
618 if (messages
&& vkd3d_test_state
.debug_level
)
619 trace("%s\n", messages
);
620 vkd3d_shader_free_messages(messages
);
624 if (shader_type
== SHADER_TYPE_HS
)
626 runner
->output_primitive
= tessellation_info
.output_primitive
;
627 runner
->partitioning
= tessellation_info
.partitioning
;
630 count
= runner
->combined_sampler_count
+ combined_sampler_info
.combined_sampler_count
;
631 if (count
&& !(runner
->combined_samplers
= realloc(runner
->combined_samplers
,
632 count
* sizeof(*runner
->combined_samplers
))))
633 fatal_error("Failed to allocate combined samplers array.\n");
634 for (i
= 0; i
< combined_sampler_info
.combined_sampler_count
; ++i
)
636 const struct vkd3d_shader_combined_resource_sampler_info
*s
= &combined_sampler_info
.combined_samplers
[i
];
638 sampler
= &runner
->combined_samplers
[runner
->combined_sampler_count
];
639 sampler
->resource_space
= s
->resource_space
;
640 sampler
->resource_index
= s
->resource_index
;
641 sampler
->sampler_space
= s
->sampler_space
;
642 sampler
->sampler_index
= s
->sampler_index
;
643 sampler
->shader_visibility
= VKD3D_SHADER_VISIBILITY_ALL
;
644 /* We don't know if this combined sampler was created from a SRV buffer or a SRV image, so
645 * we pass both flags, otherwise the combined sampler won't be recognized when emitting the
646 * SPIR-V, which will result in a failing assertion. */
647 sampler
->flags
= VKD3D_SHADER_BINDING_FLAG_IMAGE
| VKD3D_SHADER_BINDING_FLAG_BUFFER
;
648 sampler
->binding
.set
= 0;
649 sampler
->binding
.binding
= runner
->combined_sampler_count
++;
650 sampler
->binding
.count
= 1;
652 vkd3d_shader_free_scan_combined_resource_sampler_info(&combined_sampler_info
);
654 if (runner
->language
== SPIR_V
)
656 info
.next
= &spirv_info
;
657 spirv_info
.next
= &interface_info
;
658 spirv_info
.environment
= VKD3D_SHADER_SPIRV_ENVIRONMENT_OPENGL_4_5
;
659 spirv_info
.extensions
= spirv_extensions
;
660 spirv_info
.extension_count
= 0;
661 if (runner
->caps
.shader_caps
[SHADER_CAP_RT_VP_ARRAY_INDEX
])
662 spirv_extensions
[spirv_info
.extension_count
++] = VKD3D_SHADER_SPIRV_EXTENSION_EXT_VIEWPORT_INDEX_LAYER
;
666 info
.next
= &interface_info
;
669 if (shader_type
== SHADER_TYPE_DS
)
671 interface_info
.next
= &domain_info
;
673 domain_info
.type
= VKD3D_SHADER_STRUCTURE_TYPE_SPIRV_DOMAIN_SHADER_TARGET_INFO
;
674 domain_info
.next
= NULL
;
675 domain_info
.output_primitive
= runner
->output_primitive
;
676 domain_info
.partitioning
= runner
->partitioning
;
679 if (runner
->r
.uniform_count
)
681 binding
= &bindings
[interface_info
.binding_count
++];
682 binding
->type
= VKD3D_SHADER_DESCRIPTOR_TYPE_CBV
;
683 binding
->register_space
= 0;
684 binding
->register_index
= 0;
685 binding
->shader_visibility
= VKD3D_SHADER_VISIBILITY_ALL
;
686 binding
->flags
= VKD3D_SHADER_BINDING_FLAG_BUFFER
;
687 binding
->binding
.set
= 0;
688 binding
->binding
.binding
= 0;
689 binding
->binding
.count
= 1;
692 for (i
= 0; i
< runner
->r
.resource_count
; ++i
)
694 const struct gl_resource
*resource
= gl_resource(runner
->r
.resources
[i
]);
696 switch (resource
->r
.desc
.type
)
698 case RESOURCE_TYPE_UAV
:
699 binding
= &bindings
[interface_info
.binding_count
++];
700 binding
->type
= VKD3D_SHADER_DESCRIPTOR_TYPE_UAV
;
701 binding
->register_space
= 0;
702 binding
->register_index
= resource
->r
.desc
.slot
;
703 binding
->shader_visibility
= VKD3D_SHADER_VISIBILITY_ALL
;
704 if (resource
->r
.desc
.dimension
== RESOURCE_DIMENSION_BUFFER
)
705 binding
->flags
= VKD3D_SHADER_BINDING_FLAG_BUFFER
;
707 binding
->flags
= VKD3D_SHADER_BINDING_FLAG_IMAGE
;
708 binding
->binding
.set
= 0;
709 binding
->binding
.binding
= resource
->r
.desc
.slot
;
710 binding
->binding
.count
= 1;
718 interface_info
.bindings
= bindings
;
719 interface_info
.combined_samplers
= runner
->combined_samplers
;
720 interface_info
.combined_sampler_count
= runner
->combined_sampler_count
;
722 parameters
[0].name
= VKD3D_SHADER_PARAMETER_NAME_RASTERIZER_SAMPLE_COUNT
;
723 parameters
[0].type
= VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT
;
724 parameters
[0].data_type
= VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32
;
725 parameters
[0].u
.immediate_constant
.u
.u32
= runner
->r
.sample_count
;
727 spirv_info
.parameter_count
= ARRAY_SIZE(parameters
);
728 spirv_info
.parameters
= parameters
;
730 ret
= vkd3d_shader_compile(&info
, out
, &messages
);
731 if (messages
&& vkd3d_test_state
.debug_level
)
732 trace("%s\n", messages
);
733 vkd3d_shader_free_messages(messages
);
740 static void trace_info_log(GLuint id
, bool program
)
742 const char *p
, *end
, *line
;
747 glGetProgramiv(id
, GL_INFO_LOG_LENGTH
, &length
);
749 glGetShaderiv(id
, GL_INFO_LOG_LENGTH
, &length
);
754 log
= malloc(length
);
756 glGetProgramInfoLog(id
, length
, NULL
, log
);
758 glGetShaderInfoLog(id
, length
, NULL
, log
);
759 log
[length
- 1] = '\n';
761 trace("Info log received from %s #%u:\n", program
? "program" : "shader", id
);
768 if ((p
= memchr(line
, '\n', end
- line
)))
772 trace(" %.*s", (int)(p
- line
), line
);
777 static GLuint
create_shader(struct gl_runner
*runner
, enum shader_type shader_type
, ID3D10Blob
*source
)
779 struct vkd3d_shader_code target
;
780 const GLchar
*glsl_source
;
781 GLenum gl_shader_type
;
789 gl_shader_type
= GL_VERTEX_SHADER
;
794 gl_shader_type
= GL_FRAGMENT_SHADER
;
799 gl_shader_type
= GL_TESS_CONTROL_SHADER
;
800 name
= "tessellation control";
804 gl_shader_type
= GL_TESS_EVALUATION_SHADER
;
805 name
= "tessellation evaluation";
809 gl_shader_type
= GL_COMPUTE_SHADER
;
814 fatal_error("Unhandled shader type %#x.\n", shader_type
);
817 if (!compile_shader(runner
, shader_type
, source
, &target
))
820 id
= glCreateShader(gl_shader_type
);
821 if (runner
->language
== SPIR_V
)
823 glShaderBinary(1, &id
, GL_SHADER_BINARY_FORMAT_SPIR_V
, target
.code
, target
.size
);
824 p_glSpecializeShader(id
, "main", 0, NULL
, NULL
);
828 glsl_source
= target
.code
;
830 glShaderSource(id
, 1, &glsl_source
, &size
);
833 vkd3d_shader_free_shader_code(&target
);
835 glGetShaderiv(id
, GL_COMPILE_STATUS
, &status
);
836 ok(status
, "Failed to compile %s shader.\n", name
);
837 trace_info_log(id
, false);
842 static GLuint
compile_compute_shader_program(struct gl_runner
*runner
)
844 GLuint program_id
, cs_id
;
848 reset_combined_samplers(runner
);
849 if (!(cs_blob
= compile_hlsl(&runner
->r
, SHADER_TYPE_CS
)))
852 cs_id
= create_shader(runner
, SHADER_TYPE_CS
, cs_blob
);
853 ID3D10Blob_Release(cs_blob
);
857 program_id
= glCreateProgram();
858 glAttachShader(program_id
, cs_id
);
859 glLinkProgram(program_id
);
860 glGetProgramiv(program_id
, GL_LINK_STATUS
, &status
);
861 ok(status
, "Failed to link program.\n");
862 trace_info_log(program_id
, true);
864 glDeleteShader(cs_id
);
869 static bool gl_runner_dispatch(struct shader_runner
*r
, unsigned int x
, unsigned int y
, unsigned int z
)
871 struct gl_runner
*runner
= gl_runner(r
);
872 GLuint program_id
, ubo_id
= 0;
875 program_id
= compile_compute_shader_program(runner
);
876 todo_if(runner
->r
.is_todo
) ok(program_id
, "Failed to compile shader program.\n");
879 glUseProgram(program_id
);
881 if (runner
->r
.uniform_count
)
883 glGenBuffers(1, &ubo_id
);
884 glBindBufferBase(GL_UNIFORM_BUFFER
, 0, ubo_id
);
885 glBufferData(GL_UNIFORM_BUFFER
, runner
->r
.uniform_count
* sizeof(*runner
->r
.uniforms
),
886 runner
->r
.uniforms
, GL_STATIC_DRAW
);
889 for (i
= 0; i
< runner
->r
.resource_count
; ++i
)
891 struct gl_resource
*resource
= gl_resource(runner
->r
.resources
[i
]);
893 switch (resource
->r
.desc
.type
)
895 case RESOURCE_TYPE_RENDER_TARGET
:
896 case RESOURCE_TYPE_DEPTH_STENCIL
:
897 case RESOURCE_TYPE_VERTEX_BUFFER
:
898 case RESOURCE_TYPE_TEXTURE
:
901 case RESOURCE_TYPE_UAV
:
902 if (resource
->r
.desc
.dimension
== RESOURCE_DIMENSION_BUFFER
)
903 glBindImageTexture(resource
->r
.desc
.slot
, resource
->tbo_id
, 0, GL_TRUE
,
904 0, GL_READ_WRITE
, resource
->format
->internal_format
);
906 glBindImageTexture(resource
->r
.desc
.slot
, resource
->id
, 0, GL_TRUE
,
907 0, GL_READ_WRITE
, resource
->format
->internal_format
);
912 glDispatchCompute(x
, y
, z
);
914 glDeleteBuffers(1, &ubo_id
);
915 glDeleteProgram(program_id
);
920 static GLenum
get_topology_gl(D3D_PRIMITIVE_TOPOLOGY topology
)
924 case D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST
:
927 case D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP
:
928 return GL_TRIANGLE_STRIP
;
931 if (topology
>= D3D_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST
932 && topology
<= D3D_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST
)
934 fatal_error("Unhandled topology %#x.\n", topology
);
938 static GLenum
get_texture_wrap_gl(D3D12_TEXTURE_ADDRESS_MODE mode
)
942 case D3D12_TEXTURE_ADDRESS_MODE_WRAP
:
945 case D3D12_TEXTURE_ADDRESS_MODE_MIRROR
:
946 return GL_MIRRORED_REPEAT
;
948 case D3D12_TEXTURE_ADDRESS_MODE_CLAMP
:
949 return GL_CLAMP_TO_EDGE
;
951 case D3D12_TEXTURE_ADDRESS_MODE_BORDER
:
952 return GL_CLAMP_TO_BORDER_ARB
;
954 case D3D12_TEXTURE_ADDRESS_MODE_MIRROR_ONCE
:
955 return GL_MIRROR_CLAMP_TO_EDGE
;
958 fatal_error("Unhandled address mode %#x.\n", mode
);
962 static GLenum
get_texture_filter_mag_gl(D3D12_FILTER filter
)
964 return filter
& 0x4 ? GL_LINEAR
: GL_NEAREST
;
967 static GLenum
get_texture_filter_min_gl(D3D12_FILTER filter
)
970 return filter
& 0x10 ? GL_LINEAR_MIPMAP_LINEAR
: GL_LINEAR_MIPMAP_NEAREST
;
972 return filter
& 0x10 ? GL_NEAREST_MIPMAP_LINEAR
: GL_NEAREST_MIPMAP_NEAREST
;
975 static GLenum
get_compare_op_gl(D3D12_COMPARISON_FUNC op
)
979 case D3D12_COMPARISON_FUNC_NEVER
:
981 case D3D12_COMPARISON_FUNC_LESS
:
983 case D3D12_COMPARISON_FUNC_EQUAL
:
985 case D3D12_COMPARISON_FUNC_LESS_EQUAL
:
987 case D3D12_COMPARISON_FUNC_GREATER
:
989 case D3D12_COMPARISON_FUNC_NOT_EQUAL
:
991 case D3D12_COMPARISON_FUNC_GREATER_EQUAL
:
993 case D3D12_COMPARISON_FUNC_ALWAYS
:
996 fatal_error("Unhandled compare op %#x.\n", op
);
1000 static GLuint
compile_graphics_shader_program(struct gl_runner
*runner
, ID3D10Blob
**vs_blob
)
1002 ID3D10Blob
*fs_blob
, *hs_blob
= NULL
, *ds_blob
= NULL
, *gs_blob
= NULL
;
1003 GLuint program_id
, vs_id
, fs_id
, hs_id
= 0, ds_id
= 0;
1007 reset_combined_samplers(runner
);
1009 *vs_blob
= compile_hlsl(&runner
->r
, SHADER_TYPE_VS
);
1010 fs_blob
= compile_hlsl(&runner
->r
, SHADER_TYPE_PS
);
1011 succeeded
= *vs_blob
&& fs_blob
;
1013 if (runner
->r
.shader_source
[SHADER_TYPE_HS
])
1015 hs_blob
= compile_hlsl(&runner
->r
, SHADER_TYPE_HS
);
1016 succeeded
= succeeded
&& hs_blob
;
1018 if (runner
->r
.shader_source
[SHADER_TYPE_DS
])
1020 ds_blob
= compile_hlsl(&runner
->r
, SHADER_TYPE_DS
);
1021 succeeded
= succeeded
&& ds_blob
;
1023 if (runner
->r
.shader_source
[SHADER_TYPE_GS
])
1025 gs_blob
= compile_hlsl(&runner
->r
, SHADER_TYPE_GS
);
1026 succeeded
= succeeded
&& gs_blob
;
1032 if (!(vs_id
= create_shader(runner
, SHADER_TYPE_VS
, *vs_blob
)))
1035 if (!(fs_id
= create_shader(runner
, SHADER_TYPE_PS
, fs_blob
)))
1037 ID3D10Blob_Release(fs_blob
);
1042 if (!(hs_id
= create_shader(runner
, SHADER_TYPE_HS
, hs_blob
)))
1044 ID3D10Blob_Release(hs_blob
);
1050 if (!(ds_id
= create_shader(runner
, SHADER_TYPE_DS
, ds_blob
)))
1052 ID3D10Blob_Release(ds_blob
);
1056 /* TODO: compile and use the gs blobs too, but currently this
1057 * point is not reached because compile_hlsl() fails on these. */
1059 program_id
= glCreateProgram();
1060 glAttachShader(program_id
, vs_id
);
1061 glAttachShader(program_id
, fs_id
);
1063 glAttachShader(program_id
, hs_id
);
1065 glAttachShader(program_id
, ds_id
);
1066 glLinkProgram(program_id
);
1067 glGetProgramiv(program_id
, GL_LINK_STATUS
, &status
);
1068 ok(status
, "Failed to link program.\n");
1069 trace_info_log(program_id
, true);
1072 glDeleteShader(ds_id
);
1074 glDeleteShader(hs_id
);
1075 glDeleteShader(fs_id
);
1076 glDeleteShader(vs_id
);
1082 ID3D10Blob_Release(gs_blob
);
1084 ID3D10Blob_Release(ds_blob
);
1086 ID3D10Blob_Release(hs_blob
);
1088 ID3D10Blob_Release(fs_blob
);
1090 ID3D10Blob_Release(*vs_blob
);
1094 static void gl_runner_clear(struct shader_runner
*r
, struct resource
*res
, const struct vec4
*clear_value
)
1096 struct gl_resource
*resource
= gl_resource(res
);
1097 struct gl_runner
*runner
= gl_runner(r
);
1098 GLbitfield clear_mask
;
1100 if (!runner
->fbo_id
)
1101 glGenFramebuffers(1, &runner
->fbo_id
);
1102 glBindFramebuffer(GL_FRAMEBUFFER
, runner
->fbo_id
);
1104 switch (resource
->r
.desc
.type
)
1106 case RESOURCE_TYPE_RENDER_TARGET
:
1107 glFramebufferTexture(GL_FRAMEBUFFER
, GL_COLOR_ATTACHMENT0
, resource
->id
, 0);
1108 glColorMask(GL_TRUE
, GL_TRUE
, GL_TRUE
, GL_TRUE
);
1109 glClearColor(clear_value
->x
, clear_value
->y
, clear_value
->z
, clear_value
->w
);
1110 clear_mask
= GL_COLOR_BUFFER_BIT
;
1113 case RESOURCE_TYPE_DEPTH_STENCIL
:
1114 glFramebufferTexture(GL_FRAMEBUFFER
, GL_DEPTH_ATTACHMENT
, resource
->id
, 0);
1115 glDepthMask(GL_TRUE
);
1116 glClearDepthf(clear_value
->x
);
1117 clear_mask
= GL_DEPTH_BUFFER_BIT
;
1121 fatal_error("Clears are not implemented for resource type %u.\n", resource
->r
.desc
.type
);
1124 glScissor(0, 0, res
->desc
.width
, res
->desc
.height
);
1125 glClear(clear_mask
);
1128 static bool gl_runner_draw(struct shader_runner
*r
,
1129 D3D_PRIMITIVE_TOPOLOGY topology
, unsigned int vertex_count
, unsigned int instance_count
)
1131 unsigned int attribute_idx
, fb_width
, fb_height
, rt_count
, i
, j
;
1132 struct vkd3d_shader_signature vs_input_signature
;
1133 struct gl_runner
*runner
= gl_runner(r
);
1134 struct vkd3d_shader_code vs_dxbc
;
1135 uint8_t *attribute_offsets
[32];
1140 } vbo_info
[MAX_RESOURCES
];
1141 GLuint program_id
, ubo_id
= 0;
1142 ID3D10Blob
*vs_blob
;
1148 } sampler_info
[MAX_SAMPLERS
];
1149 GLenum draw_buffers
[8];
1151 program_id
= compile_graphics_shader_program(runner
, &vs_blob
);
1152 todo_if(runner
->r
.is_todo
) ok(program_id
, "Failed to compile shader program.\n");
1155 glUseProgram(program_id
);
1157 if (runner
->r
.uniform_count
)
1159 glGenBuffers(1, &ubo_id
);
1160 glBindBufferBase(GL_UNIFORM_BUFFER
, 0, ubo_id
);
1161 glBufferData(GL_UNIFORM_BUFFER
, runner
->r
.uniform_count
* sizeof(*runner
->r
.uniforms
),
1162 runner
->r
.uniforms
, GL_STATIC_DRAW
);
1165 if (!runner
->fbo_id
)
1166 glGenFramebuffers(1, &runner
->fbo_id
);
1167 glBindFramebuffer(GL_FRAMEBUFFER
, runner
->fbo_id
);
1169 for (i
= 0; i
< runner
->r
.sampler_count
; ++i
)
1171 struct sampler
*sampler
= &runner
->r
.samplers
[i
];
1174 glGenSamplers(1, &id
);
1175 glSamplerParameteri(id
, GL_TEXTURE_WRAP_S
, get_texture_wrap_gl(sampler
->u_address
));
1176 glSamplerParameteri(id
, GL_TEXTURE_WRAP_T
, get_texture_wrap_gl(sampler
->v_address
));
1177 glSamplerParameteri(id
, GL_TEXTURE_WRAP_R
, get_texture_wrap_gl(sampler
->w_address
));
1178 glSamplerParameteri(id
, GL_TEXTURE_MAG_FILTER
, get_texture_filter_mag_gl(sampler
->filter
));
1179 glSamplerParameteri(id
, GL_TEXTURE_MIN_FILTER
, get_texture_filter_min_gl(sampler
->filter
));
1182 glSamplerParameteri(id
, GL_TEXTURE_COMPARE_MODE
, GL_COMPARE_REF_TO_TEXTURE
);
1183 glSamplerParameteri(id
, GL_TEXTURE_COMPARE_FUNC
, get_compare_op_gl(sampler
->func
));
1185 sampler_info
[i
].id
= id
;
1188 for (i
= 0; i
< runner
->combined_sampler_count
; ++i
)
1190 const struct vkd3d_shader_combined_resource_sampler
*s
= &runner
->combined_samplers
[i
];
1191 struct resource
*resource
;
1192 struct sampler
*sampler
;
1194 if (s
->resource_space
|| s
->sampler_space
)
1195 fatal_error("Unsupported register space.\n");
1197 if (!(resource
= shader_runner_get_resource(r
, RESOURCE_TYPE_TEXTURE
, s
->resource_index
)))
1198 fatal_error("Resource not found.\n");
1200 glActiveTexture(GL_TEXTURE0
+ s
->binding
.binding
);
1201 if (resource
->desc
.dimension
== RESOURCE_DIMENSION_BUFFER
)
1202 glBindTexture(gl_resource(resource
)->target
, gl_resource(resource
)->tbo_id
);
1204 glBindTexture(gl_resource(resource
)->target
, gl_resource(resource
)->id
);
1206 if (s
->sampler_index
== VKD3D_SHADER_DUMMY_SAMPLER_INDEX
)
1209 if (!(sampler
= shader_runner_get_sampler(r
, s
->sampler_index
)))
1210 fatal_error("Sampler not found.\n");
1211 glBindSampler(s
->binding
.binding
, sampler_info
[sampler
- r
->samplers
].id
);
1216 memset(vbo_info
, 0, sizeof(vbo_info
));
1217 memset(draw_buffers
, 0, sizeof(draw_buffers
));
1218 for (i
= 0, rt_count
= 0; i
< runner
->r
.resource_count
; ++i
)
1220 struct gl_resource
*resource
= gl_resource(runner
->r
.resources
[i
]);
1222 switch (resource
->r
.desc
.type
)
1224 case RESOURCE_TYPE_RENDER_TARGET
:
1225 glFramebufferTexture(GL_FRAMEBUFFER
, GL_COLOR_ATTACHMENT0
+ resource
->r
.desc
.slot
, resource
->id
, 0);
1226 if (resource
->r
.desc
.slot
>= ARRAY_SIZE(draw_buffers
))
1227 fatal_error("Unsupported render target index %u.\n", resource
->r
.desc
.slot
);
1228 draw_buffers
[resource
->r
.desc
.slot
] = GL_COLOR_ATTACHMENT0
+ resource
->r
.desc
.slot
;
1229 if (resource
->r
.desc
.slot
>= rt_count
)
1230 rt_count
= resource
->r
.desc
.slot
+ 1;
1231 if (resource
->r
.desc
.width
< fb_width
)
1232 fb_width
= resource
->r
.desc
.width
;
1233 if (resource
->r
.desc
.height
< fb_height
)
1234 fb_height
= resource
->r
.desc
.height
;
1237 case RESOURCE_TYPE_DEPTH_STENCIL
:
1238 glFramebufferTexture(GL_FRAMEBUFFER
, GL_DEPTH_ATTACHMENT
, resource
->id
, 0);
1239 glEnable(GL_DEPTH_TEST
);
1240 glDepthMask(GL_TRUE
);
1241 glDepthFunc(get_compare_op_gl(runner
->r
.depth_func
));
1242 if (runner
->r
.depth_bounds
)
1244 glEnable(GL_DEPTH_BOUNDS_TEST_EXT
);
1245 p_glDepthBoundsEXT(runner
->r
.depth_min
, runner
->r
.depth_max
);
1247 if (resource
->r
.desc
.width
< fb_width
)
1248 fb_width
= resource
->r
.desc
.width
;
1249 if (resource
->r
.desc
.height
< fb_height
)
1250 fb_height
= resource
->r
.desc
.height
;
1253 case RESOURCE_TYPE_TEXTURE
:
1256 case RESOURCE_TYPE_UAV
:
1257 if (resource
->r
.desc
.dimension
== RESOURCE_DIMENSION_BUFFER
)
1259 glBindImageTexture(resource
->r
.desc
.slot
, resource
->tbo_id
, 0, GL_TRUE
,
1260 0, GL_READ_WRITE
, resource
->format
->internal_format
);
1264 glBindImageTexture(resource
->r
.desc
.slot
, resource
->id
, 0, GL_TRUE
,
1265 0, GL_READ_WRITE
, resource
->format
->internal_format
);
1269 case RESOURCE_TYPE_VERTEX_BUFFER
:
1270 assert(resource
->r
.desc
.slot
< ARRAY_SIZE(vbo_info
));
1271 vbo_info
[resource
->r
.desc
.slot
].id
= resource
->id
;
1272 for (j
= 0; j
< runner
->r
.input_element_count
; ++j
)
1274 if (runner
->r
.input_elements
[j
].slot
!= resource
->r
.desc
.slot
)
1276 assert(j
< ARRAY_SIZE(attribute_offsets
));
1277 attribute_offsets
[j
] = (uint8_t *)(uintptr_t)vbo_info
[resource
->r
.desc
.slot
].stride
;
1278 vbo_info
[resource
->r
.desc
.slot
].stride
+= runner
->r
.input_elements
[j
].texel_size
;
1284 glEnable(GL_SAMPLE_MASK
);
1285 glSampleMaski(0, runner
->r
.sample_mask
);
1286 glViewport(0, 0, fb_width
, fb_height
);
1287 glScissor(0, 0, fb_width
, fb_height
);
1288 glDrawBuffers(rt_count
, draw_buffers
);
1290 vs_dxbc
.code
= ID3D10Blob_GetBufferPointer(vs_blob
);
1291 vs_dxbc
.size
= ID3D10Blob_GetBufferSize(vs_blob
);
1292 ret
= vkd3d_shader_parse_input_signature(&vs_dxbc
, &vs_input_signature
, NULL
);
1293 ok(!ret
, "Failed to parse input signature, error %d.\n", ret
);
1295 map
= runner
->attribute_map
;
1296 for (i
= 0, runner
->attribute_map
= 0; i
< runner
->r
.input_element_count
; ++i
)
1298 const struct input_element
*element
= &runner
->r
.input_elements
[i
];
1299 const struct vkd3d_shader_signature_element
*signature_element
;
1300 const struct format_info
*format
;
1302 signature_element
= vkd3d_shader_find_signature_element(&vs_input_signature
,
1303 element
->name
, element
->index
, 0);
1304 ok(signature_element
, "Cannot find signature element %s%u.\n", element
->name
, element
->index
);
1305 attribute_idx
= signature_element
->register_index
;
1306 format
= get_format_info(element
->format
, false);
1308 glBindBuffer(GL_ARRAY_BUFFER
, vbo_info
[element
->slot
].id
);
1309 if (format
->is_integer
)
1310 glVertexAttribIPointer(attribute_idx
, format
->component_count
, format
->type
,
1311 vbo_info
[element
->slot
].stride
, attribute_offsets
[i
]);
1313 glVertexAttribPointer(attribute_idx
, format
->component_count
, format
->type
,
1314 GL_FALSE
, vbo_info
[element
->slot
].stride
, attribute_offsets
[i
]);
1315 glEnableVertexAttribArray(attribute_idx
);
1316 runner
->attribute_map
|= attribute_idx
;
1318 vkd3d_shader_free_shader_signature(&vs_input_signature
);
1319 map
&= ~runner
->attribute_map
;
1320 for (attribute_idx
= 0; map
; ++attribute_idx
, map
>>= 1)
1323 glDisableVertexAttribArray(attribute_idx
);
1326 if (runner
->r
.shader_source
[SHADER_TYPE_HS
])
1327 glPatchParameteri(GL_PATCH_VERTICES
, max(topology
- D3D_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST
+ 1, 1));
1329 glDrawArraysInstanced(get_topology_gl(topology
), 0, vertex_count
, instance_count
);
1331 for (i
= 0; i
< runner
->r
.sampler_count
; ++i
)
1333 glDeleteSamplers(1, &sampler_info
[i
].id
);
1335 glDeleteBuffers(1, &ubo_id
);
1337 ID3D10Blob_Release(vs_blob
);
1338 glDeleteProgram(program_id
);
1343 static bool gl_runner_copy(struct shader_runner
*r
, struct resource
*src
, struct resource
*dst
)
1345 struct gl_resource
*s
= gl_resource(src
);
1346 struct gl_resource
*d
= gl_resource(dst
);
1347 unsigned int l
, w
, h
;
1349 if (src
->desc
.dimension
== RESOURCE_DIMENSION_BUFFER
|| src
->desc
.depth
> 1)
1352 for (l
= 0; l
< src
->desc
.level_count
; ++l
)
1354 w
= get_level_dimension(src
->desc
.width
, l
);
1355 h
= get_level_dimension(src
->desc
.height
, l
);
1356 glCopyImageSubData(s
->id
, s
->target
, l
, 0, 0, 0, d
->id
, d
->target
, l
, 0, 0, 0, w
, h
, 1);
1362 struct gl_resource_readback
1364 struct resource_readback rb
;
1367 static struct resource_readback
*gl_runner_get_resource_readback(struct shader_runner
*r
,
1368 struct resource
*res
, unsigned int sub_resource_idx
)
1370 struct gl_resource
*resource
= gl_resource(res
);
1371 struct gl_runner
*runner
= gl_runner(r
);
1372 struct resource_readback
*rb
;
1373 unsigned int layer
, level
;
1376 if (resource
->r
.desc
.type
!= RESOURCE_TYPE_RENDER_TARGET
&& resource
->r
.desc
.type
!= RESOURCE_TYPE_DEPTH_STENCIL
1377 && resource
->r
.desc
.type
!= RESOURCE_TYPE_UAV
)
1378 fatal_error("Unhandled resource type %#x.\n", resource
->r
.desc
.type
);
1380 rb
= malloc(sizeof(*rb
));
1382 rb
->width
= resource
->r
.desc
.width
;
1383 rb
->height
= resource
->r
.desc
.height
;
1386 rb
->row_pitch
= rb
->width
* resource
->r
.desc
.texel_size
;
1387 slice_pitch
= rb
->row_pitch
* rb
->height
;
1388 rb
->data
= calloc(slice_pitch
, resource
->r
.desc
.depth
);
1390 level
= sub_resource_idx
% resource
->r
.desc
.level_count
;
1391 layer
= sub_resource_idx
/ resource
->r
.desc
.level_count
;
1393 if (resource
->r
.desc
.dimension
== RESOURCE_DIMENSION_BUFFER
)
1395 glBindBuffer(resource
->target
, resource
->id
);
1396 glGetBufferSubData(resource
->target
, 0, slice_pitch
, rb
->data
);
1398 else if (resource
->r
.desc
.sample_count
> 1)
1400 GLuint src_fbo
, dst_fbo
;
1403 glGenTextures(1, &resolved
);
1404 glBindTexture(GL_TEXTURE_2D
, resolved
);
1405 glTexStorage2D(GL_TEXTURE_2D
, resource
->r
.desc
.level_count
,
1406 resource
->format
->internal_format
, resource
->r
.desc
.width
, resource
->r
.desc
.height
);
1408 glGenFramebuffers(1, &src_fbo
);
1409 glGenFramebuffers(1, &dst_fbo
);
1411 glBindFramebuffer(GL_READ_FRAMEBUFFER
, src_fbo
);
1412 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
, dst_fbo
);
1414 glFramebufferTexture(GL_READ_FRAMEBUFFER
, GL_COLOR_ATTACHMENT0
, resource
->id
, 0);
1415 glFramebufferTexture(GL_DRAW_FRAMEBUFFER
, GL_COLOR_ATTACHMENT0
, resolved
, 0);
1417 glBlitFramebuffer(0, 0, resource
->r
.desc
.width
, resource
->r
.desc
.height
,
1418 0, 0, resource
->r
.desc
.width
, resource
->r
.desc
.height
, GL_COLOR_BUFFER_BIT
, GL_NEAREST
);
1420 glBindFramebuffer(GL_FRAMEBUFFER
, runner
->fbo_id
);
1421 glDeleteFramebuffers(1, &src_fbo
);
1422 glDeleteFramebuffers(1, &dst_fbo
);
1424 glGetTexImage(GL_TEXTURE_2D
, 0, resource
->format
->format
, resource
->format
->type
, rb
->data
);
1426 glDeleteTextures(1, &resolved
);
1430 glBindTexture(resource
->target
, resource
->id
);
1431 glGetTexImage(resource
->target
, level
, resource
->format
->format
, resource
->format
->type
, rb
->data
);
1433 memcpy(rb
->data
, (const uint8_t *)rb
->data
+ layer
* slice_pitch
, slice_pitch
);
1439 static void gl_runner_release_readback(struct shader_runner
*runner
, struct resource_readback
*rb
)
1445 static const struct shader_runner_ops gl_runner_ops
=
1447 .create_resource
= gl_runner_create_resource
,
1448 .destroy_resource
= gl_runner_destroy_resource
,
1449 .dispatch
= gl_runner_dispatch
,
1450 .clear
= gl_runner_clear
,
1451 .draw
= gl_runner_draw
,
1452 .copy
= gl_runner_copy
,
1453 .get_resource_readback
= gl_runner_get_resource_readback
,
1454 .release_readback
= gl_runner_release_readback
,
1457 static void run_tests(enum shading_language language
)
1459 struct gl_runner runner
;
1461 if (!gl_runner_init(&runner
, language
))
1463 run_shader_tests(&runner
.r
, &runner
.caps
, &gl_runner_ops
, NULL
);
1464 gl_runner_cleanup(&runner
);
1467 void run_shader_tests_gl(void)