vkd3d-shader/hlsl: Handle error instructions in add_shader_compilation().
[vkd3d.git] / tests / shader_runner_gl.c
blob83e659b3ce23caf2dee35f3b6ddd49c8a4b02133
1 /*
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
19 #include "config.h"
21 #ifdef HAVE_OPENGL
23 #ifndef __MINGW32__
24 #define WIDL_C_INLINE_WRAPPERS
25 #endif
26 #define COBJMACROS
27 #define VKD3D_TEST_NO_DEFS
28 #define GL_GLEXT_PROTOTYPES
29 #include <EGL/egl.h>
30 #include <EGL/eglext.h>
31 #include <GL/gl.h>
32 #include "shader_runner.h"
33 #include "vkd3d_d3dcompiler.h"
35 static PFNGLDEPTHBOUNDSEXTPROC p_glDepthBoundsEXT;
36 static PFNGLSPECIALIZESHADERPROC p_glSpecializeShader;
38 enum shading_language
40 GLSL,
41 SPIR_V,
44 struct format_info
46 enum DXGI_FORMAT f;
47 unsigned int component_count;
48 bool is_integer;
49 bool is_shadow;
50 GLenum internal_format;
51 GLenum format;
52 GLenum type;
55 struct gl_resource
57 struct resource r;
59 const struct format_info *format;
60 GLuint id, tbo_id;
61 GLenum target;
64 static struct gl_resource *gl_resource(struct resource *r)
66 return CONTAINING_RECORD(r, struct gl_resource, r);
69 struct gl_runner
71 struct shader_runner r;
72 struct shader_runner_caps caps;
74 EGLDisplay display;
75 EGLContext context;
77 uint32_t attribute_map;
78 GLuint fbo_id;
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')
97 --length;
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)))
106 return true;
109 return false;
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",
130 "GL_ARB_copy_image",
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))
143 return false;
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))
152 return false;
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;
165 return true;
168 static bool check_egl_client_extension(const char *extension)
170 const char *extensions, *p;
171 size_t len;
173 if (!(extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS)))
174 return false;
176 len = strlen(extension);
177 for (;;)
179 if (!(p = strchr(extensions, ' ')))
180 p = &extensions[strlen(extensions)];
181 if (p - extensions == len && !memcmp(extensions, extension, len))
182 return true;
183 if (!*p)
184 break;
185 extensions = p + 1;
187 return false;
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)
199 return true;
202 return false;
205 static const struct format_info *get_format_info(enum DXGI_FORMAT format, bool is_shadow)
207 size_t i;
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;
238 uint32_t ret = 0;
239 GLint support;
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;
246 return ret;
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;
255 EGLContext context;
256 EGLDisplay display;
257 EGLBoolean ret;
258 GLuint vao;
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,
266 EGL_NONE,
269 static const enum DXGI_FORMAT formats[] =
271 DXGI_FORMAT_UNKNOWN,
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");
284 return false;
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");
294 return false;
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);
309 continue;
312 if (!eglInitialize(display, NULL, NULL))
314 trace("Failed to initialise EGL display connection for device %u.\n", i);
315 continue;
318 if (!eglBindAPI(EGL_OPENGL_API))
320 trace("Failed to bind OpenGL API for device %u.\n", i);
321 eglTerminate(display);
322 continue;
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);
329 continue;
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);
337 continue;
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);
351 continue;
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);
362 continue;
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;
388 break;
391 free(devices);
393 if (!runner->context)
395 skip("Failed to find a usable OpenGL device.\n");
396 return false;
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);
410 glFrontFace(GL_CW);
411 glProvokingVertex(GL_FIRST_VERTEX_CONVENTION);
412 glGenVertexArrays(1, &vao);
413 glBindVertexArray(vao);
415 return true;
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)
427 EGLBoolean ret;
429 reset_combined_samplers(runner);
431 if (runner->fbo_id)
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;
445 GLenum target;
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;
451 else
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);
465 return false;
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);
476 else
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);
481 else
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);
487 if (!params->data)
488 return true;
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;
499 return true;
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))
534 return NULL;
535 break;
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);
541 break;
544 return &resource->r;
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);
562 else
564 glDeleteTextures(1, &resource->id);
566 break;
568 case RESOURCE_TYPE_VERTEX_BUFFER:
569 glDeleteBuffers(1, &resource->id);
570 break;
573 free(resource);
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;
591 char *messages;
592 int ret;
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);
621 if (ret)
622 return false;
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;
664 else
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;
706 else
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;
711 break;
713 default:
714 break;
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);
734 if (ret)
735 return false;
737 return true;
740 static void trace_info_log(GLuint id, bool program)
742 const char *p, *end, *line;
743 GLint length = 0;
744 char *log;
746 if (program)
747 glGetProgramiv(id, GL_INFO_LOG_LENGTH, &length);
748 else
749 glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length);
751 if (length <= 1)
752 return;
754 log = malloc(length);
755 if (program)
756 glGetProgramInfoLog(id, length, NULL, log);
757 else
758 glGetShaderInfoLog(id, length, NULL, log);
759 log[length - 1] = '\n';
761 trace("Info log received from %s #%u:\n", program ? "program" : "shader", id);
763 p = log;
764 end = &log[length];
765 while (p < end)
767 line = p;
768 if ((p = memchr(line, '\n', end - line)))
769 ++p;
770 else
771 p = end;
772 trace(" %.*s", (int)(p - line), line);
774 free(log);
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;
782 GLint status, size;
783 const char *name;
784 GLuint id;
786 switch (shader_type)
788 case SHADER_TYPE_VS:
789 gl_shader_type = GL_VERTEX_SHADER;
790 name = "vertex";
791 break;
793 case SHADER_TYPE_PS:
794 gl_shader_type = GL_FRAGMENT_SHADER;
795 name = "fragment";
796 break;
798 case SHADER_TYPE_HS:
799 gl_shader_type = GL_TESS_CONTROL_SHADER;
800 name = "tessellation control";
801 break;
803 case SHADER_TYPE_DS:
804 gl_shader_type = GL_TESS_EVALUATION_SHADER;
805 name = "tessellation evaluation";
806 break;
808 case SHADER_TYPE_CS:
809 gl_shader_type = GL_COMPUTE_SHADER;
810 name = "compute";
811 break;
813 default:
814 fatal_error("Unhandled shader type %#x.\n", shader_type);
817 if (!compile_shader(runner, shader_type, source, &target))
818 return 0;
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);
826 else
828 glsl_source = target.code;
829 size = target.size;
830 glShaderSource(id, 1, &glsl_source, &size);
831 glCompileShader(id);
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);
839 return id;
842 static GLuint compile_compute_shader_program(struct gl_runner *runner)
844 GLuint program_id, cs_id;
845 ID3D10Blob *cs_blob;
846 GLint status;
848 reset_combined_samplers(runner);
849 if (!(cs_blob = compile_hlsl(&runner->r, SHADER_TYPE_CS)))
850 return 0;
852 cs_id = create_shader(runner, SHADER_TYPE_CS, cs_blob);
853 ID3D10Blob_Release(cs_blob);
854 if (!cs_id)
855 return 0;
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);
866 return program_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;
873 unsigned int i;
875 program_id = compile_compute_shader_program(runner);
876 todo_if(runner->r.is_todo) ok(program_id, "Failed to compile shader program.\n");
877 if (!program_id)
878 return false;
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:
899 break;
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);
905 else
906 glBindImageTexture(resource->r.desc.slot, resource->id, 0, GL_TRUE,
907 0, GL_READ_WRITE, resource->format->internal_format);
908 break;
912 glDispatchCompute(x, y, z);
914 glDeleteBuffers(1, &ubo_id);
915 glDeleteProgram(program_id);
917 return true;
920 static GLenum get_topology_gl(D3D_PRIMITIVE_TOPOLOGY topology)
922 switch (topology)
924 case D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST:
925 return GL_TRIANGLES;
927 case D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP:
928 return GL_TRIANGLE_STRIP;
930 default:
931 if (topology >= D3D_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST
932 && topology <= D3D_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST)
933 return GL_PATCHES;
934 fatal_error("Unhandled topology %#x.\n", topology);
938 static GLenum get_texture_wrap_gl(D3D12_TEXTURE_ADDRESS_MODE mode)
940 switch (mode)
942 case D3D12_TEXTURE_ADDRESS_MODE_WRAP:
943 return GL_REPEAT;
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;
957 default:
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)
969 if (filter & 0x1)
970 return filter & 0x10 ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR_MIPMAP_NEAREST;
971 else
972 return filter & 0x10 ? GL_NEAREST_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST;
975 static GLenum get_compare_op_gl(D3D12_COMPARISON_FUNC op)
977 switch (op)
979 case D3D12_COMPARISON_FUNC_NEVER:
980 return GL_NEVER;
981 case D3D12_COMPARISON_FUNC_LESS:
982 return GL_LESS;
983 case D3D12_COMPARISON_FUNC_EQUAL:
984 return GL_EQUAL;
985 case D3D12_COMPARISON_FUNC_LESS_EQUAL:
986 return GL_LEQUAL;
987 case D3D12_COMPARISON_FUNC_GREATER:
988 return GL_GREATER;
989 case D3D12_COMPARISON_FUNC_NOT_EQUAL:
990 return GL_NOTEQUAL;
991 case D3D12_COMPARISON_FUNC_GREATER_EQUAL:
992 return GL_GEQUAL;
993 case D3D12_COMPARISON_FUNC_ALWAYS:
994 return GL_ALWAYS;
995 default:
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;
1004 bool succeeded;
1005 GLint status;
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;
1029 if (!succeeded)
1030 goto fail;
1032 if (!(vs_id = create_shader(runner, SHADER_TYPE_VS, *vs_blob)))
1033 goto fail;
1035 if (!(fs_id = create_shader(runner, SHADER_TYPE_PS, fs_blob)))
1036 goto fail;
1037 ID3D10Blob_Release(fs_blob);
1038 fs_blob = NULL;
1040 if (hs_blob)
1042 if (!(hs_id = create_shader(runner, SHADER_TYPE_HS, hs_blob)))
1043 goto fail;
1044 ID3D10Blob_Release(hs_blob);
1045 hs_blob = NULL;
1048 if (ds_blob)
1050 if (!(ds_id = create_shader(runner, SHADER_TYPE_DS, ds_blob)))
1051 goto fail;
1052 ID3D10Blob_Release(ds_blob);
1053 ds_blob = NULL;
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);
1062 if (hs_id)
1063 glAttachShader(program_id, hs_id);
1064 if (ds_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);
1071 if (ds_id)
1072 glDeleteShader(ds_id);
1073 if (hs_id)
1074 glDeleteShader(hs_id);
1075 glDeleteShader(fs_id);
1076 glDeleteShader(vs_id);
1078 return program_id;
1080 fail:
1081 if (gs_blob)
1082 ID3D10Blob_Release(gs_blob);
1083 if (ds_blob)
1084 ID3D10Blob_Release(ds_blob);
1085 if (hs_blob)
1086 ID3D10Blob_Release(hs_blob);
1087 if (fs_blob)
1088 ID3D10Blob_Release(fs_blob);
1089 if (*vs_blob)
1090 ID3D10Blob_Release(*vs_blob);
1091 return 0;
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;
1111 break;
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;
1118 break;
1120 default:
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];
1136 struct
1138 GLuint id;
1139 GLsizei stride;
1140 } vbo_info[MAX_RESOURCES];
1141 GLuint program_id, ubo_id = 0;
1142 ID3D10Blob *vs_blob;
1143 uint32_t map;
1144 int ret;
1145 struct
1147 GLuint id;
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");
1153 if (!program_id)
1154 return false;
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];
1172 GLuint id;
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));
1180 if (sampler->func)
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);
1203 else
1204 glBindTexture(gl_resource(resource)->target, gl_resource(resource)->id);
1206 if (s->sampler_index == VKD3D_SHADER_DUMMY_SAMPLER_INDEX)
1207 continue;
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);
1214 fb_width = ~0u;
1215 fb_height = ~0u;
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;
1235 break;
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;
1251 break;
1253 case RESOURCE_TYPE_TEXTURE:
1254 break;
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);
1262 else
1264 glBindImageTexture(resource->r.desc.slot, resource->id, 0, GL_TRUE,
1265 0, GL_READ_WRITE, resource->format->internal_format);
1267 break;
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)
1275 continue;
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;
1280 break;
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]);
1312 else
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)
1322 if (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);
1340 return true;
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)
1350 return false;
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);
1359 return true;
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;
1374 size_t slice_pitch;
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;
1384 rb->depth = 1;
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;
1401 GLuint resolved;
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);
1428 else
1430 glBindTexture(resource->target, resource->id);
1431 glGetTexImage(resource->target, level, resource->format->format, resource->format->type, rb->data);
1432 if (layer)
1433 memcpy(rb->data, (const uint8_t *)rb->data + layer * slice_pitch, slice_pitch);
1436 return rb;
1439 static void gl_runner_release_readback(struct shader_runner *runner, struct resource_readback *rb)
1441 free(rb->data);
1442 free(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))
1462 return;
1463 run_shader_tests(&runner.r, &runner.caps, &gl_runner_ops, NULL);
1464 gl_runner_cleanup(&runner);
1467 void run_shader_tests_gl(void)
1469 run_tests(SPIR_V);
1470 run_tests(GLSL);
1473 #endif