Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- v6: avoid magic numbers...
tests/shader_runner.c | 38 +++++++++++++++++++--------- tests/shader_runner.h | 2 ++ tests/shader_runner_d3d11.c | 31 ++++++++++++++++++----- tests/shader_runner_d3d12.c | 37 +++++++++++++++++++++------ tests/shader_runner_d3d9.c | 12 ++++++--- tests/shader_runner_vulkan.c | 48 ++++++++++++++++++++++++++++-------- 6 files changed, 130 insertions(+), 38 deletions(-)
diff --git a/tests/shader_runner.c b/tests/shader_runner.c index 05e2a8a41..83f804ad3 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -78,14 +78,13 @@ enum parse_state STATE_PREPROC, STATE_PREPROC_INVALID, STATE_REQUIRE, + STATE_RESOURCE, STATE_SAMPLER, STATE_SHADER_INVALID_PIXEL, STATE_SHADER_INVALID_PIXEL_TODO, STATE_SHADER_PIXEL, STATE_SHADER_VERTEX, - STATE_TEXTURE, STATE_TEST, - STATE_VERTEX_BUFFER, };
static bool match_string(const char *line, const char *token, const char **const rest) @@ -314,6 +313,13 @@ static void parse_input_layout_directive(struct shader_runner *runner, const cha element->index = 0; }
+void init_resource(struct resource *resource, const struct resource_params *params) +{ + resource->type = params->type; + resource->slot = params->slot; + resource->size = params->data_size; +} + static void set_resource(struct shader_runner *runner, struct resource *resource) { size_t i; @@ -617,8 +623,7 @@ void run_shader_tests(struct shader_runner *runner, int argc, char **argv, const goto out; break;
- case STATE_TEXTURE: - case STATE_VERTEX_BUFFER: + case STATE_RESOURCE: set_resource(runner, runner->ops->create_resource(runner, ¤t_resource)); free(current_resource.data); break; @@ -766,7 +771,7 @@ void run_shader_tests(struct shader_runner *runner, int argc, char **argv, const } else if (sscanf(line, "[texture %u]\n", &index)) { - state = STATE_TEXTURE; + state = STATE_RESOURCE;
memset(¤t_resource, 0, sizeof(current_resource));
@@ -776,9 +781,21 @@ void run_shader_tests(struct shader_runner *runner, int argc, char **argv, const current_resource.data_type = TEXTURE_DATA_FLOAT; current_resource.texel_size = 16; } + else if (sscanf(line, "[uav %u]\n", &index)) + { + state = STATE_RESOURCE; + + memset(¤t_resource, 0, sizeof(current_resource)); + + current_resource.slot = index; + current_resource.type = RESOURCE_TYPE_UAV; + current_resource.format = DXGI_FORMAT_R32G32B32A32_FLOAT; + current_resource.data_type = TEXTURE_DATA_FLOAT; + current_resource.texel_size = 16; + } else if (sscanf(line, "[vertex buffer %u]\n", &index)) { - state = STATE_VERTEX_BUFFER; + state = STATE_RESOURCE;
memset(¤t_resource, 0, sizeof(current_resource));
@@ -844,13 +861,12 @@ void run_shader_tests(struct shader_runner *runner, int argc, char **argv, const parse_require_directive(runner, line); break;
- case STATE_SAMPLER: - parse_sampler_directive(current_sampler, line); + case STATE_RESOURCE: + parse_resource_directive(¤t_resource, line); break;
- case STATE_TEXTURE: - case STATE_VERTEX_BUFFER: - parse_resource_directive(¤t_resource, line); + case STATE_SAMPLER: + parse_sampler_directive(current_sampler, line); break;
case STATE_TEST: diff --git a/tests/shader_runner.h b/tests/shader_runner.h index 6ed0109e6..60f894583 100644 --- a/tests/shader_runner.h +++ b/tests/shader_runner.h @@ -54,6 +54,7 @@ struct sampler enum resource_type { RESOURCE_TYPE_TEXTURE, + RESOURCE_TYPE_UAV, RESOURCE_TYPE_VERTEX_BUFFER, };
@@ -130,6 +131,7 @@ struct shader_runner_ops void fatal_error(const char *format, ...) VKD3D_NORETURN VKD3D_PRINTF_FUNC(1, 2);
unsigned int get_vb_stride(const struct shader_runner *runner, unsigned int slot); +void init_resource(struct resource *resource, const struct resource_params *params);
void run_shader_tests(struct shader_runner *runner, int argc, char **argv, const struct shader_runner_ops *ops);
diff --git a/tests/shader_runner_d3d11.c b/tests/shader_runner_d3d11.c index 6edbdf75e..b80a8b65f 100644 --- a/tests/shader_runner_d3d11.c +++ b/tests/shader_runner_d3d11.c @@ -44,6 +44,7 @@ struct d3d11_resource
ID3D11Resource *resource; ID3D11ShaderResourceView *srv; + ID3D11UnorderedAccessView *uav; };
static struct d3d11_resource *d3d11_resource(struct resource *r) @@ -374,13 +375,12 @@ static struct resource *d3d11_runner_create_resource(struct shader_runner *r, co HRESULT hr;
resource = calloc(1, sizeof(*resource)); - - resource->r.slot = params->slot; - resource->r.type = params->type; + init_resource(&resource->r, params);
switch (params->type) { case RESOURCE_TYPE_TEXTURE: + case RESOURCE_TYPE_UAV: { D3D11_TEXTURE2D_DESC desc = {0};
@@ -391,7 +391,10 @@ static struct resource *d3d11_runner_create_resource(struct shader_runner *r, co desc.Format = params->format; desc.SampleDesc.Count = 1; desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + if (params->type == RESOURCE_TYPE_UAV) + desc.BindFlags = D3D11_BIND_UNORDERED_ACCESS; + else + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
resource_data.pSysMem = params->data; resource_data.SysMemPitch = params->width * params->texel_size; @@ -399,8 +402,11 @@ static struct resource *d3d11_runner_create_resource(struct shader_runner *r, co
hr = ID3D11Device_CreateTexture2D(device, &desc, &resource_data, (ID3D11Texture2D **)&resource->resource); ok(hr == S_OK, "Failed to create texture, hr %#lx.\n", hr); - hr = ID3D11Device_CreateShaderResourceView(device, resource->resource, NULL, &resource->srv); - ok(hr == S_OK, "Failed to create shader resource view, hr %#lx.\n", hr); + if (params->type == RESOURCE_TYPE_UAV) + hr = ID3D11Device_CreateUnorderedAccessView(device, resource->resource, NULL, &resource->uav); + else + hr = ID3D11Device_CreateShaderResourceView(device, resource->resource, NULL, &resource->srv); + ok(hr == S_OK, "Failed to create view, hr %#lx.\n", hr); break; }
@@ -420,14 +426,18 @@ static void d3d11_runner_destroy_resource(struct shader_runner *r, struct resour ID3D11Resource_Release(resource->resource); if (resource->srv) ID3D11ShaderResourceView_Release(resource->srv); + if (resource->uav) + ID3D11UnorderedAccessView_Release(resource->uav); free(resource); }
static bool d3d11_runner_draw(struct shader_runner *r, D3D_PRIMITIVE_TOPOLOGY primitive_topology, unsigned int vertex_count) { + ID3D11UnorderedAccessView *uavs[D3D11_PS_CS_UAV_REGISTER_COUNT] = {0}; struct d3d11_shader_runner *runner = d3d11_shader_runner(r); ID3D11DeviceContext *context = runner->immediate_context; + unsigned int min_uav_slot = ARRAY_SIZE(uavs); ID3D11Device *device = runner->device; ID3D10Blob *vs_code, *ps_code; ID3D11Buffer *cb = NULL; @@ -472,6 +482,11 @@ static bool d3d11_runner_draw(struct shader_runner *r, ID3D11DeviceContext_PSSetShaderResources(context, resource->r.slot, 1, &resource->srv); break;
+ case RESOURCE_TYPE_UAV: + uavs[resource->r.slot] = resource->uav; + min_uav_slot = min(min_uav_slot, resource->r.slot); + break; + case RESOURCE_TYPE_VERTEX_BUFFER: ID3D11DeviceContext_IASetVertexBuffers(context, resource->r.slot, 1, (ID3D11Buffer **)&resource->resource, &stride, &offset); @@ -479,6 +494,10 @@ static bool d3d11_runner_draw(struct shader_runner *r, } }
+ ID3D11DeviceContext_OMSetRenderTargetsAndUnorderedAccessViews(context, + D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL, NULL, NULL, + min_uav_slot, ARRAY_SIZE(uavs) - min_uav_slot, &uavs[min_uav_slot], NULL); + for (i = 0; i < runner->r.sampler_count; ++i) { struct sampler *sampler = &runner->r.samplers[i]; diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index 22c9b2266..ec08fea54 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -79,7 +79,7 @@ static ID3D10Blob *compile_shader(const struct d3d12_shader_runner *runner, cons return blob; }
-#define MAX_RESOURCE_DESCRIPTORS 256 +#define MAX_RESOURCE_DESCRIPTORS (MAX_RESOURCES * 2)
static struct resource *d3d12_runner_create_resource(struct shader_runner *r, const struct resource_params *params) { @@ -90,9 +90,7 @@ static struct resource *d3d12_runner_create_resource(struct shader_runner *r, co struct d3d12_resource *resource;
resource = calloc(1, sizeof(*resource)); - resource->r.slot = params->slot; - resource->r.type = params->type; - resource->r.size = params->data_size; + init_resource(&resource->r, params);
switch (params->type) { @@ -101,9 +99,6 @@ static struct resource *d3d12_runner_create_resource(struct shader_runner *r, co runner->heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, MAX_RESOURCE_DESCRIPTORS);
- if (params->slot >= MAX_RESOURCE_DESCRIPTORS) - fatal_error("Resource slot %u is too high; please increase MAX_RESOURCE_DESCRIPTORS.\n", params->slot); - resource->resource = create_default_texture(device, params->width, params->height, params->format, 0, D3D12_RESOURCE_STATE_COPY_DEST); resource_data.pData = params->data; @@ -116,6 +111,23 @@ static struct resource *d3d12_runner_create_resource(struct shader_runner *r, co NULL, get_cpu_descriptor_handle(test_context, runner->heap, resource->r.slot)); break;
+ case RESOURCE_TYPE_UAV: + if (!runner->heap) + runner->heap = create_gpu_descriptor_heap(device, + D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, MAX_RESOURCE_DESCRIPTORS); + + resource->resource = create_default_texture(device, params->width, params->height, + params->format, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST); + resource_data.pData = params->data; + resource_data.SlicePitch = resource_data.RowPitch = params->width * params->texel_size; + upload_texture_data(resource->resource, &resource_data, 1, test_context->queue, test_context->list); + reset_command_list(test_context->list, test_context->allocator); + transition_resource_state(test_context->list, resource->resource, + D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + ID3D12Device_CreateUnorderedAccessView(device, resource->resource, + NULL, NULL, get_cpu_descriptor_handle(test_context, runner->heap, resource->r.slot + MAX_RESOURCES)); + break; + case RESOURCE_TYPE_VERTEX_BUFFER: resource->resource = create_upload_buffer(device, params->data_size, params->data); break; @@ -192,6 +204,7 @@ static bool d3d12_runner_draw(struct shader_runner *r, switch (resource->r.type) { case RESOURCE_TYPE_TEXTURE: + case RESOURCE_TYPE_UAV: range = &resource->descriptor_range;
resource->root_index = root_signature_desc.NumParameters++; @@ -201,7 +214,10 @@ static bool d3d12_runner_draw(struct shader_runner *r, root_param->DescriptorTable.pDescriptorRanges = range; root_param->ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
- range->RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + if (resource->r.type == RESOURCE_TYPE_UAV) + range->RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; + else + range->RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; range->NumDescriptors = 1; range->BaseShaderRegister = resource->r.slot; range->RegisterSpace = 0; @@ -281,6 +297,11 @@ static bool d3d12_runner_draw(struct shader_runner *r, get_gpu_descriptor_handle(test_context, runner->heap, resource->r.slot)); break;
+ case RESOURCE_TYPE_UAV: + ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, resource->root_index, + get_gpu_descriptor_handle(test_context, runner->heap, resource->r.slot + MAX_RESOURCES)); + break; + case RESOURCE_TYPE_VERTEX_BUFFER: vbv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(resource->resource); vbv.StrideInBytes = get_vb_stride(&runner->r, resource->r.slot); diff --git a/tests/shader_runner_d3d9.c b/tests/shader_runner_d3d9.c index b9ec55b4e..417d68750 100644 --- a/tests/shader_runner_d3d9.c +++ b/tests/shader_runner_d3d9.c @@ -222,9 +222,7 @@ static struct resource *d3d9_runner_create_resource(struct shader_runner *r, con void *data;
resource = calloc(1, sizeof(*resource)); - resource->r.slot = params->slot; - resource->r.type = params->type; - resource->r.size = params->data_size; + init_resource(&resource->r, params);
switch (params->type) { @@ -257,6 +255,10 @@ static struct resource *d3d9_runner_create_resource(struct shader_runner *r, con ok(hr == D3D_OK, "Failed to unmap texture, hr %#lx.\n", hr); break;
+ case RESOURCE_TYPE_UAV: + fatal_error("UAVs are not supported.\n"); + break; + case RESOURCE_TYPE_VERTEX_BUFFER: hr = IDirect3DDevice9_CreateVertexBuffer(device, params->data_size, D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT, &resource->vb, NULL); @@ -366,6 +368,10 @@ static bool d3d9_runner_draw(struct shader_runner *r, ok(hr == D3D_OK, "Failed to set texture, hr %#lx.\n", hr); break;
+ case RESOURCE_TYPE_UAV: + assert(0); + break; + case RESOURCE_TYPE_VERTEX_BUFFER: for (j = 0; j < runner->r.input_element_count; ++j) { diff --git a/tests/shader_runner_vulkan.c b/tests/shader_runner_vulkan.c index 601eb5a17..f5a0e7ec3 100644 --- a/tests/shader_runner_vulkan.c +++ b/tests/shader_runner_vulkan.c @@ -245,17 +245,25 @@ static struct resource *vulkan_runner_create_resource(struct shader_runner *r, c void *data;
resource = calloc(1, sizeof(*resource)); - - resource->r.slot = params->slot; - resource->r.type = params->type; + init_resource(&resource->r, params);
switch (params->type) { case RESOURCE_TYPE_TEXTURE: + case RESOURCE_TYPE_UAV: + { + VkImageUsageFlagBits usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; + VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + format = vkd3d_get_vk_format(params->format);
- resource->image = create_2d_image(runner, params->width, params->height, - VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, format, &resource->memory); + if (params->type == RESOURCE_TYPE_UAV) + { + layout = VK_IMAGE_LAYOUT_GENERAL; + usage |= VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + } + + resource->image = create_2d_image(runner, params->width, params->height, usage, format, &resource->memory); resource->view = create_2d_image_view(runner, resource->image, format);
staging_buffer = create_buffer(runner, params->data_size, @@ -277,14 +285,14 @@ static struct resource *vulkan_runner_create_resource(struct shader_runner *r, c VK_CALL(vkCmdCopyBufferToImage(runner->cmd_buffer, staging_buffer, resource->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion));
- transition_image_layout(runner, resource->image, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + transition_image_layout(runner, resource->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, layout);
end_command_buffer(runner);
VK_CALL(vkFreeMemory(device, staging_memory, NULL)); VK_CALL(vkDestroyBuffer(device, staging_buffer, NULL)); break; + }
case RESOURCE_TYPE_VERTEX_BUFFER: resource->buffer = create_buffer(runner, params->data_size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, @@ -383,8 +391,12 @@ static bool compile_shader(const struct vulkan_shader_runner *runner, const char break;
case RESOURCE_TYPE_TEXTURE: + case RESOURCE_TYPE_UAV: binding = &bindings[interface_info.binding_count++]; - binding->type = VKD3D_SHADER_DESCRIPTOR_TYPE_SRV; + if (resource->r.type == RESOURCE_TYPE_UAV) + binding->type = VKD3D_SHADER_DESCRIPTOR_TYPE_UAV; + else + binding->type = VKD3D_SHADER_DESCRIPTOR_TYPE_SRV; binding->register_space = 0; binding->register_index = resource->r.slot; binding->shader_visibility = VKD3D_SHADER_VISIBILITY_ALL; @@ -557,6 +569,7 @@ static VkPipeline create_pipeline(const struct vulkan_shader_runner *runner, switch (resource->r.type) { case RESOURCE_TYPE_TEXTURE: + case RESOURCE_TYPE_UAV: break;
case RESOURCE_TYPE_VERTEX_BUFFER: @@ -662,12 +675,16 @@ static VkDescriptorSetLayout create_descriptor_set_layout(struct vulkan_shader_r break;
case RESOURCE_TYPE_TEXTURE: + case RESOURCE_TYPE_UAV: binding = &bindings[set_desc.bindingCount++];
resource->binding = binding_index++;
binding->binding = resource->binding; - binding->descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + if (resource->r.type == RESOURCE_TYPE_UAV) + binding->descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + else + binding->descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; binding->descriptorCount = 1; binding->stageFlags = VK_SHADER_STAGE_ALL; binding->pImmutableSamplers = NULL; @@ -729,6 +746,7 @@ static void bind_resources(struct vulkan_shader_runner *runner, VkPipelineBindPo switch (resource->r.type) { case RESOURCE_TYPE_TEXTURE: + case RESOURCE_TYPE_UAV: image_info.imageView = resource->view; image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
@@ -739,6 +757,12 @@ static void bind_resources(struct vulkan_shader_runner *runner, VkPipelineBindPo write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; write.pImageInfo = &image_info;
+ if (resource->r.type == RESOURCE_TYPE_UAV) + { + image_info.imageLayout = VK_IMAGE_LAYOUT_GENERAL; + write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + } + VK_CALL(vkUpdateDescriptorSets(runner->device, 1, &write, 0, NULL)); break;
@@ -967,7 +991,7 @@ static bool init_vulkan_runner(struct vulkan_shader_runner *runner) VkInstanceCreateInfo instance_desc = {.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO}; VkDeviceCreateInfo device_desc = {.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO}; VkPhysicalDeviceFeatures ret_features, features; - VkDescriptorPoolSize descriptor_pool_sizes[2]; + VkDescriptorPoolSize descriptor_pool_sizes[3]; VkAttachmentDescription attachment_desc = {0}; static const float queue_priority = 1.0f; VkSubpassDescription subpass_desc = {0}; @@ -1049,7 +1073,9 @@ static bool init_vulkan_runner(struct vulkan_shader_runner *runner) } \ features.x = VK_TRUE
+ ENABLE_FEATURE(fragmentStoresAndAtomics); ENABLE_FEATURE(shaderImageGatherExtended); + ENABLE_FEATURE(shaderStorageImageWriteWithoutFormat);
if ((vr = VK_CALL(vkCreateDevice(runner->phys_device, &device_desc, NULL, &device)))) { @@ -1115,6 +1141,8 @@ static bool init_vulkan_runner(struct vulkan_shader_runner *runner) descriptor_pool_sizes[0].descriptorCount = MAX_RESOURCES; descriptor_pool_sizes[1].type = VK_DESCRIPTOR_TYPE_SAMPLER; descriptor_pool_sizes[1].descriptorCount = MAX_SAMPLERS; + descriptor_pool_sizes[2].type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + descriptor_pool_sizes[2].descriptorCount = MAX_RESOURCES;
descriptor_pool_desc.maxSets = 1; descriptor_pool_desc.poolSizeCount = ARRAY_SIZE(descriptor_pool_sizes);
Prepare to allow for dynamically changing the bound attachments in consecutive draw calls.
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- tests/shader_runner_vulkan.c | 99 +++++++++++++++++++----------------- 1 file changed, 53 insertions(+), 46 deletions(-)
diff --git a/tests/shader_runner_vulkan.c b/tests/shader_runner_vulkan.c index f5a0e7ec3..d62792d65 100644 --- a/tests/shader_runner_vulkan.c +++ b/tests/shader_runner_vulkan.c @@ -58,13 +58,11 @@ struct vulkan_shader_runner VkQueue queue; VkCommandPool command_pool; VkCommandBuffer cmd_buffer; - VkRenderPass render_pass; VkDescriptorPool descriptor_pool;
VkImage render_target; VkDeviceMemory rt_memory; VkImageView rtv; - VkFramebuffer fb;
struct vulkan_sampler { @@ -504,7 +502,7 @@ static VkPipelineLayout create_pipeline_layout(const struct vulkan_shader_runner return pipeline_layout; }
-static VkPipeline create_pipeline(const struct vulkan_shader_runner *runner, +static VkPipeline create_pipeline(const struct vulkan_shader_runner *runner, VkRenderPass render_pass, VkPipelineLayout pipeline_layout, D3D_PRIMITIVE_TOPOLOGY primitive_topology) { VkPipelineInputAssemblyStateCreateInfo ia_desc = {.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO}; @@ -620,7 +618,7 @@ static VkPipeline create_pipeline(const struct vulkan_shader_runner *runner, pipeline_desc.pMultisampleState = &ms_desc; pipeline_desc.pColorBlendState = &blend_desc; pipeline_desc.layout = pipeline_layout; - pipeline_desc.renderPass = runner->render_pass; + pipeline_desc.renderPass = render_pass; pipeline_desc.subpass = 0;
VK_CALL(vkCreateGraphicsPipelines(runner->device, VK_NULL_HANDLE, 1, &pipeline_desc, NULL, &pipeline)); @@ -782,6 +780,48 @@ static void bind_resources(struct vulkan_shader_runner *runner, VkPipelineBindPo /* The descriptor set will be freed by resetting the descriptor pool. */ }
+static void create_render_pass_and_framebuffer(struct vulkan_shader_runner *runner, + VkRenderPass *render_pass, VkFramebuffer *fb) +{ + VkRenderPassCreateInfo render_pass_desc = {.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO}; + VkFramebufferCreateInfo fb_desc = {.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO}; + VkAttachmentDescription attachment_desc = {0}; + VkSubpassDescription subpass_desc = {0}; + VkAttachmentReference color_ref = {0}; + + attachment_desc.format = VK_FORMAT_R32G32B32A32_SFLOAT; + attachment_desc.samples = VK_SAMPLE_COUNT_1_BIT; + attachment_desc.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + attachment_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + attachment_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attachment_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + attachment_desc.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + attachment_desc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + + color_ref.attachment = 0; + color_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + + subpass_desc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; + subpass_desc.colorAttachmentCount = 1; + subpass_desc.pColorAttachments = &color_ref; + + render_pass_desc.attachmentCount = 1; + render_pass_desc.pAttachments = &attachment_desc; + render_pass_desc.subpassCount = 1; + render_pass_desc.pSubpasses = &subpass_desc; + + VK_CALL(vkCreateRenderPass(runner->device, &render_pass_desc, NULL, render_pass)); + + fb_desc.renderPass = *render_pass; + fb_desc.attachmentCount = 1; + fb_desc.pAttachments = &runner->rtv; + fb_desc.width = RENDER_TARGET_WIDTH; + fb_desc.height = RENDER_TARGET_HEIGHT; + fb_desc.layers = 1; + + VK_CALL(vkCreateFramebuffer(runner->device, &fb_desc, NULL, fb)); +} + static bool vulkan_runner_draw(struct shader_runner *r, D3D_PRIMITIVE_TOPOLOGY primitive_topology, unsigned int vertex_count) { @@ -794,16 +834,20 @@ static bool vulkan_runner_draw(struct shader_runner *r, VkDescriptorSetLayout set_layout; VkPipelineLayout pipeline_layout; VkDevice device = runner->device; + VkRenderPass render_pass; VkClearRect clear_rect; VkPipeline pipeline; + VkFramebuffer fb; bool ret = true; unsigned int i;
+ create_render_pass_and_framebuffer(runner, &render_pass, &fb); + /* Create this before compiling shaders, it will assign resource bindings. */ set_layout = create_descriptor_set_layout(runner);
pipeline_layout = create_pipeline_layout(runner, set_layout); - if (!(pipeline = create_pipeline(runner, pipeline_layout, primitive_topology))) + if (!(pipeline = create_pipeline(runner, render_pass, pipeline_layout, primitive_topology))) { ret = false; goto out; @@ -811,8 +855,8 @@ static bool vulkan_runner_draw(struct shader_runner *r,
begin_command_buffer(runner);
- pass_begin_desc.renderPass = runner->render_pass; - pass_begin_desc.framebuffer = runner->fb; + pass_begin_desc.renderPass = render_pass; + pass_begin_desc.framebuffer = fb; pass_begin_desc.renderArea = rt_rect;
VK_CALL(vkCmdBeginRenderPass(cmd_buffer, &pass_begin_desc, VK_SUBPASS_CONTENTS_INLINE)); @@ -845,6 +889,8 @@ out:
VK_CALL(vkDestroyPipelineLayout(device, pipeline_layout, NULL)); VK_CALL(vkDestroyDescriptorSetLayout(device, set_layout, NULL)); + VK_CALL(vkDestroyRenderPass(device, render_pass, NULL)); + VK_CALL(vkDestroyFramebuffer(device, fb, NULL));
return ret; } @@ -985,17 +1031,12 @@ static bool init_vulkan_runner(struct vulkan_shader_runner *runner) VkDescriptorPoolCreateInfo descriptor_pool_desc = {.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO}; VkCommandBufferAllocateInfo cmd_buffer_desc = {.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO}; VkCommandPoolCreateInfo command_pool_desc = {.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO}; - VkRenderPassCreateInfo render_pass_desc = {.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO}; VkDeviceQueueCreateInfo queue_desc = {.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO}; - VkFramebufferCreateInfo fb_desc = {.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO}; VkInstanceCreateInfo instance_desc = {.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO}; VkDeviceCreateInfo device_desc = {.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO}; VkPhysicalDeviceFeatures ret_features, features; VkDescriptorPoolSize descriptor_pool_sizes[3]; - VkAttachmentDescription attachment_desc = {0}; static const float queue_priority = 1.0f; - VkSubpassDescription subpass_desc = {0}; - VkAttachmentReference color_ref = {0}; VkFormatProperties format_props; uint32_t count, graphics_index; VkDevice device; @@ -1100,43 +1141,11 @@ static bool init_vulkan_runner(struct vulkan_shader_runner *runner)
VK_CALL(vkAllocateCommandBuffers(device, &cmd_buffer_desc, &runner->cmd_buffer));
- attachment_desc.format = VK_FORMAT_R32G32B32A32_SFLOAT; - attachment_desc.samples = VK_SAMPLE_COUNT_1_BIT; - attachment_desc.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - attachment_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attachment_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachment_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachment_desc.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - attachment_desc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - - color_ref.attachment = 0; - color_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - - subpass_desc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass_desc.colorAttachmentCount = 1; - subpass_desc.pColorAttachments = &color_ref; - - render_pass_desc.attachmentCount = 1; - render_pass_desc.pAttachments = &attachment_desc; - render_pass_desc.subpassCount = 1; - render_pass_desc.pSubpasses = &subpass_desc; - - VK_CALL(vkCreateRenderPass(device, &render_pass_desc, NULL, &runner->render_pass)); - runner->render_target = create_2d_image(runner, RENDER_TARGET_WIDTH, RENDER_TARGET_HEIGHT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_FORMAT_R32G32B32A32_SFLOAT, &runner->rt_memory); runner->rtv = create_2d_image_view(runner, runner->render_target, VK_FORMAT_R32G32B32A32_SFLOAT);
- fb_desc.renderPass = runner->render_pass; - fb_desc.attachmentCount = 1; - fb_desc.pAttachments = &runner->rtv; - fb_desc.width = RENDER_TARGET_WIDTH; - fb_desc.height = RENDER_TARGET_HEIGHT; - fb_desc.layers = 1; - - VK_CALL(vkCreateFramebuffer(device, &fb_desc, NULL, &runner->fb)); - descriptor_pool_sizes[0].type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; descriptor_pool_sizes[0].descriptorCount = MAX_RESOURCES; descriptor_pool_sizes[1].type = VK_DESCRIPTOR_TYPE_SAMPLER; @@ -1169,12 +1178,10 @@ static void cleanup_vulkan_runner(struct vulkan_shader_runner *runner) VkDevice device = runner->device;
VK_CALL(vkFreeMemory(device, runner->rt_memory, NULL)); - VK_CALL(vkDestroyFramebuffer(device, runner->fb, NULL)); VK_CALL(vkDestroyImageView(device, runner->rtv, NULL)); VK_CALL(vkDestroyImage(device, runner->render_target, NULL));
VK_CALL(vkDestroyDescriptorPool(device, runner->descriptor_pool, NULL)); - VK_CALL(vkDestroyRenderPass(device, runner->render_pass, NULL)); VK_CALL(vkFreeCommandBuffers(device, runner->command_pool, 1, &runner->cmd_buffer)); VK_CALL(vkDestroyCommandPool(device, runner->command_pool, NULL)); VK_CALL(vkDestroyDevice(device, NULL));
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- tests/shader_runner.c | 57 ++++++++++++++- tests/shader_runner.h | 6 +- tests/shader_runner_d3d11.c | 70 +++++++++--------- tests/shader_runner_d3d12.c | 86 ++++++++++++++++------ tests/shader_runner_d3d9.c | 69 +++++++++--------- tests/shader_runner_vulkan.c | 133 ++++++++++++++++++++--------------- 6 files changed, 270 insertions(+), 151 deletions(-)
diff --git a/tests/shader_runner.c b/tests/shader_runner.c index 83f804ad3..f367027f7 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -317,7 +317,27 @@ void init_resource(struct resource *resource, const struct resource_params *para { resource->type = params->type; resource->slot = params->slot; + resource->format = params->format; resource->size = params->data_size; + resource->texel_size = params->texel_size; + resource->width = params->width; + resource->height = params->height; +} + +static struct resource *get_resource(struct shader_runner *runner, enum resource_type type, unsigned int slot) +{ + struct resource *resource; + size_t i; + + for (i = 0; i < runner->resource_count; ++i) + { + resource = runner->resources[i]; + + if (resource->type == type && resource->slot == slot) + return resource; + } + + return NULL; }
static void set_resource(struct shader_runner *runner, struct resource *resource) @@ -373,6 +393,20 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) "{\n" "}";
+ if (!get_resource(runner, RESOURCE_TYPE_RENDER_TARGET, 0)) + { + memset(¶ms, 0, sizeof(params)); + params.slot = 0; + params.type = RESOURCE_TYPE_RENDER_TARGET; + params.format = DXGI_FORMAT_R32G32B32A32_FLOAT; + params.data_type = TEXTURE_DATA_FLOAT; + params.texel_size = 16; + params.width = RENDER_TARGET_WIDTH; + params.height = RENDER_TARGET_HEIGHT; + + set_resource(runner, runner->ops->create_resource(runner, ¶ms)); + } + vkd3d_array_reserve((void **)&runner->input_elements, &runner->input_element_capacity, 1, sizeof(*runner->input_elements)); element = &runner->input_elements[0]; @@ -399,9 +433,24 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) else if (match_string(line, "draw", &line)) { D3D_PRIMITIVE_TOPOLOGY topology; + struct resource_params params; unsigned int vertex_count; char *rest;
+ if (!get_resource(runner, RESOURCE_TYPE_RENDER_TARGET, 0)) + { + memset(¶ms, 0, sizeof(params)); + params.slot = 0; + params.type = RESOURCE_TYPE_RENDER_TARGET; + params.format = DXGI_FORMAT_R32G32B32A32_FLOAT; + params.data_type = TEXTURE_DATA_FLOAT; + params.texel_size = 16; + params.width = RENDER_TARGET_WIDTH; + params.height = RENDER_TARGET_HEIGHT; + + set_resource(runner, runner->ops->create_resource(runner, ¶ms)); + } + if (match_string(line, "triangle list", &line)) topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; else if (match_string(line, "triangle strip", &line)) @@ -419,15 +468,19 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) { unsigned int left, top, right, bottom, ulps; struct resource_readback *rb; + struct resource *resource; int ret, len; RECT rect;
if (runner->last_render_failed) return;
+ resource = get_resource(runner, RESOURCE_TYPE_RENDER_TARGET, 0); + rb = runner->ops->get_resource_readback(runner, resource); + if (match_string(line, "all", &line)) { - set_rect(&rect, 0, 0, RENDER_TARGET_WIDTH, RENDER_TARGET_HEIGHT); + set_rect(&rect, 0, 0, resource->width, resource->height); } else if (sscanf(line, "( %d , %d , %d , %d )%n", &left, &top, &right, &bottom, &len) == 4) { @@ -444,8 +497,6 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) fatal_error("Malformed probe arguments '%s'.\n", line); }
- rb = runner->ops->get_rt_readback(runner); - if (match_string(line, "rgba", &line)) { struct vec4 v; diff --git a/tests/shader_runner.h b/tests/shader_runner.h index 60f894583..19a48ee85 100644 --- a/tests/shader_runner.h +++ b/tests/shader_runner.h @@ -53,6 +53,7 @@ struct sampler
enum resource_type { + RESOURCE_TYPE_RENDER_TARGET, RESOURCE_TYPE_TEXTURE, RESOURCE_TYPE_UAV, RESOURCE_TYPE_VERTEX_BUFFER, @@ -76,7 +77,10 @@ struct resource unsigned int slot; enum resource_type type;
+ DXGI_FORMAT format; unsigned int size; + unsigned int texel_size; + unsigned int width, height; };
struct input_element @@ -124,7 +128,7 @@ struct shader_runner_ops struct resource *(*create_resource)(struct shader_runner *runner, const struct resource_params *params); void (*destroy_resource)(struct shader_runner *runner, struct resource *resource); bool (*draw)(struct shader_runner *runner, D3D_PRIMITIVE_TOPOLOGY primitive_topology, unsigned int vertex_count); - struct resource_readback *(*get_rt_readback)(struct shader_runner *runner); + struct resource_readback *(*get_resource_readback)(struct shader_runner *runner, struct resource *resource); void (*release_readback)(struct shader_runner *runner, struct resource_readback *rb); };
diff --git a/tests/shader_runner_d3d11.c b/tests/shader_runner_d3d11.c index b80a8b65f..8999622d3 100644 --- a/tests/shader_runner_d3d11.c +++ b/tests/shader_runner_d3d11.c @@ -43,6 +43,8 @@ struct d3d11_resource struct resource r;
ID3D11Resource *resource; + ID3D11Texture2D *texture; + ID3D11RenderTargetView *rtv; ID3D11ShaderResourceView *srv; ID3D11UnorderedAccessView *uav; }; @@ -59,8 +61,6 @@ struct d3d11_shader_runner ID3D11Device *device; HWND window; IDXGISwapChain *swapchain; - ID3D11Texture2D *rt; - ID3D11RenderTargetView *rtv; ID3D11DeviceContext *immediate_context; };
@@ -276,20 +276,8 @@ static IDXGISwapChain *create_swapchain(ID3D11Device *device, HWND window)
static BOOL init_test_context(struct d3d11_shader_runner *runner) { - const D3D11_TEXTURE2D_DESC texture_desc = - { - .Width = RENDER_TARGET_WIDTH, - .Height = RENDER_TARGET_HEIGHT, - .MipLevels = 1, - .ArraySize = 1, - .Format = DXGI_FORMAT_R32G32B32A32_FLOAT, - .SampleDesc.Count = 1, - .Usage = D3D11_USAGE_DEFAULT, - .BindFlags = D3D11_BIND_RENDER_TARGET, - }; unsigned int rt_width, rt_height; D3D11_VIEWPORT vp; - HRESULT hr; RECT rect;
memset(runner, 0, sizeof(*runner)); @@ -308,16 +296,8 @@ static BOOL init_test_context(struct d3d11_shader_runner *runner) 0, 0, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, NULL, NULL); runner->swapchain = create_swapchain(runner->device, runner->window);
- hr = ID3D11Device_CreateTexture2D(runner->device, &texture_desc, NULL, &runner->rt); - ok(hr == S_OK, "Failed to create texture, hr %#lx.\n", hr); - - hr = ID3D11Device_CreateRenderTargetView(runner->device, (ID3D11Resource *)runner->rt, NULL, &runner->rtv); - ok(hr == S_OK, "Failed to create rendertarget view, hr %#lx.\n", hr); - ID3D11Device_GetImmediateContext(runner->device, &runner->immediate_context);
- ID3D11DeviceContext_OMSetRenderTargets(runner->immediate_context, 1, &runner->rtv, NULL); - vp.TopLeftX = 0.0f; vp.TopLeftY = 0.0f; vp.Width = rt_width; @@ -334,8 +314,6 @@ static void destroy_test_context(struct d3d11_shader_runner *runner) ULONG ref;
ID3D11DeviceContext_Release(runner->immediate_context); - ID3D11RenderTargetView_Release(runner->rtv); - ID3D11Texture2D_Release(runner->rt); IDXGISwapChain_Release(runner->swapchain); DestroyWindow(runner->window);
@@ -379,6 +357,7 @@ static struct resource *d3d11_runner_create_resource(struct shader_runner *r, co
switch (params->type) { + case RESOURCE_TYPE_RENDER_TARGET: case RESOURCE_TYPE_TEXTURE: case RESOURCE_TYPE_UAV: { @@ -393,17 +372,29 @@ static struct resource *d3d11_runner_create_resource(struct shader_runner *r, co desc.Usage = D3D11_USAGE_DEFAULT; if (params->type == RESOURCE_TYPE_UAV) desc.BindFlags = D3D11_BIND_UNORDERED_ACCESS; + else if (params->type == RESOURCE_TYPE_RENDER_TARGET) + desc.BindFlags = D3D11_BIND_RENDER_TARGET; else desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
- resource_data.pSysMem = params->data; - resource_data.SysMemPitch = params->width * params->texel_size; - resource_data.SysMemSlicePitch = params->height * resource_data.SysMemPitch; - - hr = ID3D11Device_CreateTexture2D(device, &desc, &resource_data, (ID3D11Texture2D **)&resource->resource); + if (params->data) + { + resource_data.pSysMem = params->data; + resource_data.SysMemPitch = params->width * params->texel_size; + resource_data.SysMemSlicePitch = params->height * resource_data.SysMemPitch; + hr = ID3D11Device_CreateTexture2D(device, &desc, &resource_data, &resource->texture); + } + else + { + hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &resource->texture); + } ok(hr == S_OK, "Failed to create texture, hr %#lx.\n", hr); + + resource->resource = (ID3D11Resource *)resource->texture; if (params->type == RESOURCE_TYPE_UAV) hr = ID3D11Device_CreateUnorderedAccessView(device, resource->resource, NULL, &resource->uav); + else if (params->type == RESOURCE_TYPE_RENDER_TARGET) + hr = ID3D11Device_CreateRenderTargetView(device, resource->resource, NULL, &resource->rtv); else hr = ID3D11Device_CreateShaderResourceView(device, resource->resource, NULL, &resource->srv); ok(hr == S_OK, "Failed to create view, hr %#lx.\n", hr); @@ -424,6 +415,8 @@ static void d3d11_runner_destroy_resource(struct shader_runner *r, struct resour struct d3d11_resource *resource = d3d11_resource(res);
ID3D11Resource_Release(resource->resource); + if (resource->rtv) + ID3D11RenderTargetView_Release(resource->rtv); if (resource->srv) ID3D11ShaderResourceView_Release(resource->srv); if (resource->uav) @@ -435,11 +428,13 @@ static bool d3d11_runner_draw(struct shader_runner *r, D3D_PRIMITIVE_TOPOLOGY primitive_topology, unsigned int vertex_count) { ID3D11UnorderedAccessView *uavs[D3D11_PS_CS_UAV_REGISTER_COUNT] = {0}; + ID3D11RenderTargetView *rtvs[D3D11_PS_CS_UAV_REGISTER_COUNT] = {0}; struct d3d11_shader_runner *runner = d3d11_shader_runner(r); ID3D11DeviceContext *context = runner->immediate_context; unsigned int min_uav_slot = ARRAY_SIZE(uavs); ID3D11Device *device = runner->device; ID3D10Blob *vs_code, *ps_code; + unsigned int rtv_count = 0; ID3D11Buffer *cb = NULL; ID3D11VertexShader *vs; ID3D11PixelShader *ps; @@ -478,6 +473,11 @@ static bool d3d11_runner_draw(struct shader_runner *r,
switch (resource->r.type) { + case RESOURCE_TYPE_RENDER_TARGET: + rtvs[resource->r.slot] = resource->rtv; + rtv_count = max(rtv_count, resource->r.slot + 1); + break; + case RESOURCE_TYPE_TEXTURE: ID3D11DeviceContext_PSSetShaderResources(context, resource->r.slot, 1, &resource->srv); break; @@ -494,8 +494,7 @@ static bool d3d11_runner_draw(struct shader_runner *r, } }
- ID3D11DeviceContext_OMSetRenderTargetsAndUnorderedAccessViews(context, - D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL, NULL, NULL, + ID3D11DeviceContext_OMSetRenderTargetsAndUnorderedAccessViews(context, rtv_count, rtvs, NULL, min_uav_slot, ARRAY_SIZE(uavs) - min_uav_slot, &uavs[min_uav_slot], NULL);
for (i = 0; i < runner->r.sampler_count; ++i) @@ -565,15 +564,16 @@ struct d3d11_resource_readback ID3D11Resource *resource; };
-static struct resource_readback *d3d11_runner_get_rt_readback(struct shader_runner *r) +static struct resource_readback *d3d11_runner_get_resource_readback(struct shader_runner *r, struct resource *res) { struct d3d11_shader_runner *runner = d3d11_shader_runner(r); struct d3d11_resource_readback *rb = malloc(sizeof(*rb)); + struct d3d11_resource *resource = d3d11_resource(res); D3D11_TEXTURE2D_DESC texture_desc; D3D11_MAPPED_SUBRESOURCE map_desc; HRESULT hr;
- ID3D11Texture2D_GetDesc(runner->rt, &texture_desc); + ID3D11Texture2D_GetDesc(resource->texture, &texture_desc); texture_desc.Usage = D3D11_USAGE_STAGING; texture_desc.BindFlags = 0; texture_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; @@ -581,7 +581,7 @@ static struct resource_readback *d3d11_runner_get_rt_readback(struct shader_runn hr = ID3D11Device_CreateTexture2D(runner->device, &texture_desc, NULL, (ID3D11Texture2D **)&rb->resource); ok(hr == S_OK, "Failed to create texture, hr %#lx.\n", hr);
- ID3D11DeviceContext_CopyResource(runner->immediate_context, rb->resource, (ID3D11Resource *)runner->rt); + ID3D11DeviceContext_CopyResource(runner->immediate_context, rb->resource, resource->resource); hr = ID3D11DeviceContext_Map(runner->immediate_context, rb->resource, 0, D3D11_MAP_READ, 0, &map_desc); ok(hr == S_OK, "Failed to map texture, hr %#lx.\n", hr);
@@ -608,7 +608,7 @@ static const struct shader_runner_ops d3d11_runner_ops = .create_resource = d3d11_runner_create_resource, .destroy_resource = d3d11_runner_destroy_resource, .draw = d3d11_runner_draw, - .get_rt_readback = d3d11_runner_get_rt_readback, + .get_resource_readback = d3d11_runner_get_resource_readback, .release_readback = d3d11_runner_release_readback, };
diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index ec08fea54..79d5b8ebb 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -44,7 +44,7 @@ struct d3d12_shader_runner
struct test_context test_context;
- ID3D12DescriptorHeap *heap; + ID3D12DescriptorHeap *heap, *rtv_heap; };
static struct d3d12_shader_runner *d3d12_shader_runner(struct shader_runner *r) @@ -94,6 +94,20 @@ static struct resource *d3d12_runner_create_resource(struct shader_runner *r, co
switch (params->type) { + case RESOURCE_TYPE_RENDER_TARGET: + if (!runner->rtv_heap) + runner->rtv_heap = create_cpu_descriptor_heap(device, + D3D12_DESCRIPTOR_HEAP_TYPE_RTV, MAX_RESOURCE_DESCRIPTORS); + + if (params->slot >= D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT) + fatal_error("RTV slot %u is too high.\n", params->slot); + + resource->resource = create_default_texture(device, params->width, params->height, + params->format, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET, D3D12_RESOURCE_STATE_RENDER_TARGET); + ID3D12Device_CreateRenderTargetView(device, resource->resource, + NULL, get_cpu_rtv_handle(test_context, runner->rtv_heap, resource->r.slot)); + break; + case RESOURCE_TYPE_TEXTURE: if (!runner->heap) runner->heap = create_gpu_descriptor_heap(device, @@ -150,18 +164,19 @@ static bool d3d12_runner_draw(struct shader_runner *r, struct d3d12_shader_runner *runner = d3d12_shader_runner(r); struct test_context *test_context = &runner->test_context;
+ D3D12_CPU_DESCRIPTOR_HANDLE rtvs[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0}; ID3D12GraphicsCommandList *command_list = test_context->list; D3D12_ROOT_SIGNATURE_DESC root_signature_desc = {0}; + D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc = {0}; D3D12_ROOT_PARAMETER root_params[3], *root_param; ID3D12CommandQueue *queue = test_context->queue; D3D12_INPUT_ELEMENT_DESC *input_element_descs; D3D12_STATIC_SAMPLER_DESC static_samplers[1]; ID3D12Device *device = test_context->device; - D3D12_INPUT_LAYOUT_DESC input_layout; static const float clear_color[4]; + unsigned int uniform_index = 0; ID3D10Blob *vs_code, *ps_code; - D3D12_SHADER_BYTECODE vs, ps; - unsigned int uniform_index; + unsigned int rtv_count = 0; ID3D12PipelineState *pso; HRESULT hr; size_t i; @@ -185,6 +200,16 @@ static bool d3d12_runner_draw(struct shader_runner *r, root_signature_desc.pStaticSamplers = static_samplers; root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;
+ pso_desc.VS.pShaderBytecode = ID3D10Blob_GetBufferPointer(vs_code); + pso_desc.VS.BytecodeLength = ID3D10Blob_GetBufferSize(vs_code); + pso_desc.PS.pShaderBytecode = ID3D10Blob_GetBufferPointer(ps_code); + pso_desc.PS.BytecodeLength = ID3D10Blob_GetBufferSize(ps_code); + pso_desc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID; + pso_desc.RasterizerState.CullMode = D3D12_CULL_MODE_BACK; + pso_desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + pso_desc.SampleDesc.Count = 1; + pso_desc.SampleMask = ~(UINT)0; + if (runner->r.uniform_count) { uniform_index = root_signature_desc.NumParameters++; @@ -224,6 +249,12 @@ static bool d3d12_runner_draw(struct shader_runner *r, range->OffsetInDescriptorsFromTableStart = 0; break;
+ case RESOURCE_TYPE_RENDER_TARGET: + pso_desc.RTVFormats[resource->r.slot] = resource->r.format; + pso_desc.NumRenderTargets = max(pso_desc.NumRenderTargets, resource->r.slot + 1); + pso_desc.BlendState.RenderTarget[resource->r.slot].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL; + break; + case RESOURCE_TYPE_VERTEX_BUFFER: break; } @@ -251,6 +282,8 @@ static bool d3d12_runner_draw(struct shader_runner *r, hr = create_root_signature(device, &root_signature_desc, &test_context->root_signature); ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
+ pso_desc.pRootSignature = test_context->root_signature; + input_element_descs = calloc(runner->r.input_element_count, sizeof(*input_element_descs)); for (i = 0; i < runner->r.input_element_count; ++i) { @@ -265,15 +298,12 @@ static bool d3d12_runner_draw(struct shader_runner *r, desc->InputSlotClass = D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA; }
- input_layout.pInputElementDescs = input_element_descs; - input_layout.NumElements = runner->r.input_element_count; + pso_desc.InputLayout.pInputElementDescs = input_element_descs; + pso_desc.InputLayout.NumElements = runner->r.input_element_count;
- vs.pShaderBytecode = ID3D10Blob_GetBufferPointer(vs_code); - vs.BytecodeLength = ID3D10Blob_GetBufferSize(vs_code); - ps.pShaderBytecode = ID3D10Blob_GetBufferPointer(ps_code); - ps.BytecodeLength = ID3D10Blob_GetBufferSize(ps_code); - pso = create_pipeline_state(device, test_context->root_signature, - test_context->render_target_desc.Format, &vs, &ps, &input_layout); + hr = ID3D12Device_CreateGraphicsPipelineState(device, &pso_desc, + &IID_ID3D12PipelineState, (void **)&pso); + ok(hr == S_OK, "Failed to create state, hr %#x.\n", hr); ID3D10Blob_Release(vs_code); ID3D10Blob_Release(ps_code); free(input_element_descs); @@ -292,6 +322,13 @@ static bool d3d12_runner_draw(struct shader_runner *r,
switch (resource->r.type) { + case RESOURCE_TYPE_RENDER_TARGET: + rtvs[resource->r.slot] = get_cpu_rtv_handle(test_context, runner->rtv_heap, resource->r.slot); + ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, + rtvs[resource->r.slot], clear_color, 0, NULL); + rtv_count = max(rtv_count, resource->r.slot + 1); + break; + case RESOURCE_TYPE_TEXTURE: ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, resource->root_index, get_gpu_descriptor_handle(test_context, runner->heap, resource->r.slot)); @@ -312,11 +349,11 @@ static bool d3d12_runner_draw(struct shader_runner *r, } }
- ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &test_context->rtv, false, NULL); + ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, rtv_count, rtvs, false, NULL); + ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &test_context->scissor_rect); ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &test_context->viewport); ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, primitive_topology); - ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, test_context->rtv, clear_color, 0, NULL); ID3D12GraphicsCommandList_SetPipelineState(command_list, pso); ID3D12GraphicsCommandList_DrawInstanced(command_list, vertex_count, 1, 0, 0);
@@ -330,16 +367,22 @@ static bool d3d12_runner_draw(struct shader_runner *r, return true; }
-static struct resource_readback *d3d12_runner_get_rt_readback(struct shader_runner *r) +static struct resource_readback *d3d12_runner_get_resource_readback(struct shader_runner *r, struct resource *res) { struct d3d12_shader_runner *runner = d3d12_shader_runner(r); struct test_context *test_context = &runner->test_context; struct d3d12_resource_readback *rb = malloc(sizeof(*rb)); + struct d3d12_resource *resource = d3d12_resource(res);
- transition_resource_state(test_context->list, test_context->render_target, + assert(resource->r.type == RESOURCE_TYPE_RENDER_TARGET); + + transition_resource_state(test_context->list, resource->resource, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); - get_texture_readback_with_command_list(test_context->render_target, 0, rb, + get_texture_readback_with_command_list(resource->resource, 0, rb, test_context->queue, test_context->list); + reset_command_list(test_context->list, test_context->allocator); + transition_resource_state(test_context->list, resource->resource, + D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
return &rb->rb; } @@ -347,13 +390,8 @@ static struct resource_readback *d3d12_runner_get_rt_readback(struct shader_runn static void d3d12_runner_release_readback(struct shader_runner *r, struct resource_readback *rb) { struct d3d12_resource_readback *d3d12_rb = CONTAINING_RECORD(rb, struct d3d12_resource_readback, rb); - struct d3d12_shader_runner *runner = d3d12_shader_runner(r); - struct test_context *test_context = &runner->test_context;
release_resource_readback(d3d12_rb); - reset_command_list(test_context->list, test_context->allocator); - transition_resource_state(test_context->list, test_context->render_target, - D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET); free(d3d12_rb); }
@@ -362,7 +400,7 @@ static const struct shader_runner_ops d3d12_runner_ops = .create_resource = d3d12_runner_create_resource, .destroy_resource = d3d12_runner_destroy_resource, .draw = d3d12_runner_draw, - .get_rt_readback = d3d12_runner_get_rt_readback, + .get_resource_readback = d3d12_runner_get_resource_readback, .release_readback = d3d12_runner_release_readback, };
@@ -386,5 +424,7 @@ void run_shader_tests_d3d12(int argc, char **argv)
if (runner.heap) ID3D12DescriptorHeap_Release(runner.heap); + if (runner.rtv_heap) + ID3D12DescriptorHeap_Release(runner.rtv_heap); destroy_test_context(&runner.test_context); } diff --git a/tests/shader_runner_d3d9.c b/tests/shader_runner_d3d9.c index 417d68750..583b7ca73 100644 --- a/tests/shader_runner_d3d9.c +++ b/tests/shader_runner_d3d9.c @@ -29,6 +29,7 @@ struct d3d9_resource { struct resource r;
+ IDirect3DSurface9 *surface; IDirect3DTexture9 *texture; IDirect3DVertexBuffer9 *vb; }; @@ -43,7 +44,6 @@ struct d3d9_shader_runner struct shader_runner r;
IDirect3DDevice9 *device; - IDirect3DSurface9 *rt; HWND window; };
@@ -151,18 +151,6 @@ static bool init_test_context(struct d3d9_shader_runner *runner) return false; }
- if (FAILED(hr = IDirect3DDevice9_CreateRenderTarget(runner->device, RENDER_TARGET_WIDTH, RENDER_TARGET_HEIGHT, - D3DFMT_A32B32G32R32F, D3DMULTISAMPLE_NONE, 0, FALSE, &runner->rt, NULL))) - { - skip("Failed to create an A32B32G32R32F surface, hr %#lx.\n", hr); - IDirect3DDevice9_Release(runner->device); - DestroyWindow(runner->window); - return false; - } - ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr); - hr = IDirect3DDevice9_SetRenderTarget(runner->device, 0, runner->rt); - ok(hr == D3D_OK, "Failed to set render target, hr %#lx.\n", hr); - return true; }
@@ -170,7 +158,6 @@ static void destroy_test_context(struct d3d9_shader_runner *runner) { ULONG ref;
- IDirect3DSurface9_Release(runner->rt); ref = IDirect3DDevice9_Release(runner->device); ok(!ref, "Device has %lu references left.\n", ref); DestroyWindow(runner->window); @@ -224,24 +211,30 @@ static struct resource *d3d9_runner_create_resource(struct shader_runner *r, con resource = calloc(1, sizeof(*resource)); init_resource(&resource->r, params);
+ switch (params->format) + { + case DXGI_FORMAT_R32G32B32A32_FLOAT: + format = D3DFMT_A32B32G32R32F; + break; + + case DXGI_FORMAT_R32_FLOAT: + format = D3DFMT_R32F; + break; + + default: + format = D3DFMT_UNKNOWN; + break; + } + switch (params->type) { + case RESOURCE_TYPE_RENDER_TARGET: + hr = IDirect3DDevice9_CreateRenderTarget(device, params->width, params->height, + format, D3DMULTISAMPLE_NONE, 0, FALSE, &resource->surface, NULL); + ok(hr == D3D_OK, "Failed to create render target, hr %#lx.\n", hr); + break; + case RESOURCE_TYPE_TEXTURE: - switch (params->format) - { - case DXGI_FORMAT_R32G32B32A32_FLOAT: - format = D3DFMT_A32B32G32R32F; - break; - - case DXGI_FORMAT_R32_FLOAT: - format = D3DFMT_R32F; - break; - - default: - format = D3DFMT_UNKNOWN; - break; - } - hr = IDirect3DDevice9_CreateTexture(device, params->width, params->height, 1, D3DUSAGE_DYNAMIC, format, D3DPOOL_DEFAULT, &resource->texture, NULL); ok(hr == D3D_OK, "Failed to create texture, hr %#lx.\n", hr); @@ -279,6 +272,8 @@ static void d3d9_runner_destroy_resource(struct shader_runner *r, struct resourc { struct d3d9_resource *resource = d3d9_resource(res);
+ if (resource->surface) + IDirect3DSurface9_Release(resource->surface); if (resource->texture) IDirect3DTexture9_Release(resource->texture); if (resource->vb) @@ -363,6 +358,11 @@ static bool d3d9_runner_draw(struct shader_runner *r,
switch (resource->r.type) { + case RESOURCE_TYPE_RENDER_TARGET: + hr = IDirect3DDevice9_SetRenderTarget(device, resource->r.slot, resource->surface); + ok(hr == D3D_OK, "Failed to set render target, hr %#lx.\n", hr); + break; + case RESOURCE_TYPE_TEXTURE: hr = IDirect3DDevice9_SetTexture(device, resource->r.slot, (IDirect3DBaseTexture9 *)resource->texture); ok(hr == D3D_OK, "Failed to set texture, hr %#lx.\n", hr); @@ -461,21 +461,24 @@ struct d3d9_resource_readback IDirect3DSurface9 *surface; };
-static struct resource_readback *d3d9_runner_get_rt_readback(struct shader_runner *r) +static struct resource_readback *d3d9_runner_get_resource_readback(struct shader_runner *r, struct resource *res) { struct d3d9_shader_runner *runner = d3d9_shader_runner(r); struct d3d9_resource_readback *rb = malloc(sizeof(*rb)); + struct d3d9_resource *resource = d3d9_resource(res); D3DLOCKED_RECT map_desc; D3DSURFACE_DESC desc; HRESULT hr;
- hr = IDirect3DSurface9_GetDesc(runner->rt, &desc); + assert(resource->r.type == RESOURCE_TYPE_RENDER_TARGET); + + hr = IDirect3DSurface9_GetDesc(resource->surface, &desc); ok(hr == D3D_OK, "Failed to get surface desc, hr %#lx.\n", hr); hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(runner->device, desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &rb->surface, NULL); ok(hr == D3D_OK, "Failed to create surface, hr %#lx.\n", hr);
- hr = IDirect3DDevice9Ex_GetRenderTargetData(runner->device, runner->rt, rb->surface); + hr = IDirect3DDevice9Ex_GetRenderTargetData(runner->device, resource->surface, rb->surface); ok(hr == D3D_OK, "Failed to get render target data, hr %#lx.\n", hr);
hr = IDirect3DSurface9_LockRect(rb->surface, &map_desc, NULL, D3DLOCK_READONLY); @@ -504,7 +507,7 @@ static const struct shader_runner_ops d3d9_runner_ops = .create_resource = d3d9_runner_create_resource, .destroy_resource = d3d9_runner_destroy_resource, .draw = d3d9_runner_draw, - .get_rt_readback = d3d9_runner_get_rt_readback, + .get_resource_readback = d3d9_runner_get_resource_readback, .release_readback = d3d9_runner_release_readback, };
diff --git a/tests/shader_runner_vulkan.c b/tests/shader_runner_vulkan.c index d62792d65..adb69a7ce 100644 --- a/tests/shader_runner_vulkan.c +++ b/tests/shader_runner_vulkan.c @@ -60,10 +60,6 @@ struct vulkan_shader_runner VkCommandBuffer cmd_buffer; VkDescriptorPool descriptor_pool;
- VkImage render_target; - VkDeviceMemory rt_memory; - VkImageView rtv; - struct vulkan_sampler { VkSampler vk_sampler; @@ -247,6 +243,19 @@ static struct resource *vulkan_runner_create_resource(struct shader_runner *r, c
switch (params->type) { + case RESOURCE_TYPE_RENDER_TARGET: + format = vkd3d_get_vk_format(params->format); + + resource->image = create_2d_image(runner, params->width, params->height, + VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, format, &resource->memory); + resource->view = create_2d_image_view(runner, resource->image, format); + + begin_command_buffer(runner); + transition_image_layout(runner, resource->image, + VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + end_command_buffer(runner); + break; + case RESOURCE_TYPE_TEXTURE: case RESOURCE_TYPE_UAV: { @@ -385,6 +394,7 @@ static bool compile_shader(const struct vulkan_shader_runner *runner, const char
switch (resource->r.type) { + case RESOURCE_TYPE_RENDER_TARGET: case RESOURCE_TYPE_VERTEX_BUFFER: break;
@@ -514,7 +524,7 @@ static VkPipeline create_pipeline(const struct vulkan_shader_runner *runner, VkR VkPipelineViewportStateCreateInfo vp_desc = {.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO}; static const VkRect2D rt_rect = {.extent.width = RENDER_TARGET_WIDTH, .extent.height = RENDER_TARGET_HEIGHT}; VkGraphicsPipelineCreateInfo pipeline_desc = {.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO}; - VkPipelineColorBlendAttachmentState attachment_desc = {0}; + VkPipelineColorBlendAttachmentState attachment_desc[MAX_RESOURCES] = {0}; VkVertexInputAttributeDescription input_attributes[32]; VkVertexInputBindingDescription input_bindings[32]; struct vkd3d_shader_signature vs_input_signature; @@ -560,6 +570,9 @@ static VkPipeline create_pipeline(const struct vulkan_shader_runner *runner, VkR input_desc.pVertexAttributeDescriptions = input_attributes; input_desc.pVertexBindingDescriptions = input_bindings;
+ blend_desc.attachmentCount = 0; + blend_desc.pAttachments = attachment_desc; + for (i = 0; i < runner->r.resource_count; ++i) { const struct vulkan_resource *resource = vulkan_resource(runner->r.resources[i]); @@ -570,6 +583,12 @@ static VkPipeline create_pipeline(const struct vulkan_shader_runner *runner, VkR case RESOURCE_TYPE_UAV: break;
+ case RESOURCE_TYPE_RENDER_TARGET: + attachment_desc[blend_desc.attachmentCount++].colorWriteMask = + VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT + | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; + break; + case RESOURCE_TYPE_VERTEX_BUFFER: { VkVertexInputBindingDescription *binding = &input_bindings[input_desc.vertexBindingDescriptionCount++]; @@ -603,12 +622,6 @@ static VkPipeline create_pipeline(const struct vulkan_shader_runner *runner, VkR
ms_desc.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
- blend_desc.attachmentCount = 1; - blend_desc.pAttachments = &attachment_desc; - - attachment_desc.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT - | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; - pipeline_desc.stageCount = ARRAY_SIZE(stage_desc); pipeline_desc.pStages = stage_desc; pipeline_desc.pVertexInputState = &input_desc; @@ -669,6 +682,7 @@ static VkDescriptorSetLayout create_descriptor_set_layout(struct vulkan_shader_r
switch (resource->r.type) { + case RESOURCE_TYPE_RENDER_TARGET: case RESOURCE_TYPE_VERTEX_BUFFER: break;
@@ -768,6 +782,9 @@ static void bind_resources(struct vulkan_shader_runner *runner, VkPipelineBindPo if (bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS) VK_CALL(vkCmdBindVertexBuffers(cmd_buffer, resource->r.slot, 1, &resource->buffer, &zero_offset)); break; + + case RESOURCE_TYPE_RENDER_TARGET: + break; } }
@@ -785,36 +802,53 @@ static void create_render_pass_and_framebuffer(struct vulkan_shader_runner *runn { VkRenderPassCreateInfo render_pass_desc = {.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO}; VkFramebufferCreateInfo fb_desc = {.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO}; - VkAttachmentDescription attachment_desc = {0}; + VkAttachmentDescription attachment_descs[MAX_RESOURCES] = {0}; + VkAttachmentReference color_refs[MAX_RESOURCES] = {0}; VkSubpassDescription subpass_desc = {0}; - VkAttachmentReference color_ref = {0}; + VkImageView rtvs[MAX_RESOURCES]; + unsigned int rt_count = 0; + unsigned int i;
- attachment_desc.format = VK_FORMAT_R32G32B32A32_SFLOAT; - attachment_desc.samples = VK_SAMPLE_COUNT_1_BIT; - attachment_desc.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - attachment_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attachment_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachment_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachment_desc.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - attachment_desc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + for (i = 0; i < runner->r.resource_count; ++i) + { + const struct vulkan_resource *resource = vulkan_resource(runner->r.resources[i]); + VkAttachmentDescription *attachment_desc = &attachment_descs[rt_count]; + VkAttachmentReference *color_ref = &color_refs[rt_count];
- color_ref.attachment = 0; - color_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + if (resource->r.type != RESOURCE_TYPE_RENDER_TARGET) + continue; + + attachment_desc->format = vkd3d_get_vk_format(resource->r.format); + attachment_desc->samples = VK_SAMPLE_COUNT_1_BIT; + attachment_desc->loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + attachment_desc->storeOp = VK_ATTACHMENT_STORE_OP_STORE; + attachment_desc->stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attachment_desc->stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + attachment_desc->initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + attachment_desc->finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + + color_ref->attachment = rt_count; + color_ref->layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + + rtvs[rt_count] = resource->view; + + ++rt_count; + }
subpass_desc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass_desc.colorAttachmentCount = 1; - subpass_desc.pColorAttachments = &color_ref; + subpass_desc.colorAttachmentCount = rt_count; + subpass_desc.pColorAttachments = color_refs;
- render_pass_desc.attachmentCount = 1; - render_pass_desc.pAttachments = &attachment_desc; + render_pass_desc.attachmentCount = rt_count; + render_pass_desc.pAttachments = attachment_descs; render_pass_desc.subpassCount = 1; render_pass_desc.pSubpasses = &subpass_desc;
VK_CALL(vkCreateRenderPass(runner->device, &render_pass_desc, NULL, render_pass));
fb_desc.renderPass = *render_pass; - fb_desc.attachmentCount = 1; - fb_desc.pAttachments = &runner->rtv; + fb_desc.attachmentCount = rt_count; + fb_desc.pAttachments = rtvs; fb_desc.width = RENDER_TARGET_WIDTH; fb_desc.height = RENDER_TARGET_HEIGHT; fb_desc.layers = 1; @@ -902,37 +936,40 @@ struct vulkan_resource_readback VkBuffer buffer; };
-static struct resource_readback *vulkan_runner_get_rt_readback(struct shader_runner *r) +static struct resource_readback *vulkan_runner_get_resource_readback(struct shader_runner *r, struct resource *res) { struct vulkan_shader_runner *runner = vulkan_shader_runner(r); struct vulkan_resource_readback *rb = malloc(sizeof(*rb)); + struct vulkan_resource *resource = vulkan_resource(res); VkDevice device = runner->device; VkBufferImageCopy region = {0};
- rb->rb.width = RENDER_TARGET_WIDTH; - rb->rb.height = RENDER_TARGET_HEIGHT; + assert(resource->r.type == RESOURCE_TYPE_RENDER_TARGET); + + rb->rb.width = resource->r.width; + rb->rb.height = resource->r.height; rb->rb.depth = 1;
- rb->rb.row_pitch = rb->rb.width * sizeof(struct vec4); + rb->rb.row_pitch = rb->rb.width * resource->r.texel_size;
- rb->buffer = create_buffer(runner, rb->rb.row_pitch * RENDER_TARGET_HEIGHT, + rb->buffer = create_buffer(runner, rb->rb.row_pitch * rb->rb.height, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &rb->memory);
begin_command_buffer(runner);
- transition_image_layout(runner, runner->render_target, + transition_image_layout(runner, resource->image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; region.imageSubresource.layerCount = 1; - region.imageExtent.width = RENDER_TARGET_WIDTH; - region.imageExtent.height = RENDER_TARGET_HEIGHT; + region.imageExtent.width = resource->r.width; + region.imageExtent.height = resource->r.height; region.imageExtent.depth = 1;
- VK_CALL(vkCmdCopyImageToBuffer(runner->cmd_buffer, runner->render_target, + VK_CALL(vkCmdCopyImageToBuffer(runner->cmd_buffer, resource->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, rb->buffer, 1, ®ion));
- transition_image_layout(runner, runner->render_target, + transition_image_layout(runner, resource->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
end_command_buffer(runner); @@ -959,7 +996,7 @@ static const struct shader_runner_ops vulkan_runner_ops = .create_resource = vulkan_runner_create_resource, .destroy_resource = vulkan_runner_destroy_resource, .draw = vulkan_runner_draw, - .get_rt_readback = vulkan_runner_get_rt_readback, + .get_resource_readback = vulkan_runner_get_resource_readback, .release_readback = vulkan_runner_release_readback, };
@@ -1141,11 +1178,6 @@ static bool init_vulkan_runner(struct vulkan_shader_runner *runner)
VK_CALL(vkAllocateCommandBuffers(device, &cmd_buffer_desc, &runner->cmd_buffer));
- runner->render_target = create_2d_image(runner, RENDER_TARGET_WIDTH, RENDER_TARGET_HEIGHT, - VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, - VK_FORMAT_R32G32B32A32_SFLOAT, &runner->rt_memory); - runner->rtv = create_2d_image_view(runner, runner->render_target, VK_FORMAT_R32G32B32A32_SFLOAT); - descriptor_pool_sizes[0].type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; descriptor_pool_sizes[0].descriptorCount = MAX_RESOURCES; descriptor_pool_sizes[1].type = VK_DESCRIPTOR_TYPE_SAMPLER; @@ -1159,13 +1191,6 @@ static bool init_vulkan_runner(struct vulkan_shader_runner *runner)
VK_CALL(vkCreateDescriptorPool(device, &descriptor_pool_desc, NULL, &runner->descriptor_pool));
- begin_command_buffer(runner); - - transition_image_layout(runner, runner->render_target, - VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); - - end_command_buffer(runner); - return true;
out_destroy_instance: @@ -1177,10 +1202,6 @@ static void cleanup_vulkan_runner(struct vulkan_shader_runner *runner) { VkDevice device = runner->device;
- VK_CALL(vkFreeMemory(device, runner->rt_memory, NULL)); - VK_CALL(vkDestroyImageView(device, runner->rtv, NULL)); - VK_CALL(vkDestroyImage(device, runner->render_target, NULL)); - VK_CALL(vkDestroyDescriptorPool(device, runner->descriptor_pool, NULL)); VK_CALL(vkFreeCommandBuffers(device, runner->command_pool, 1, &runner->cmd_buffer)); VK_CALL(vkDestroyCommandPool(device, runner->command_pool, NULL));
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- Makefile.am | 1 + tests/shader_runner.c | 22 ++++++++++++-- tests/shader_runner_d3d12.c | 10 +++++-- tests/shader_runner_vulkan.c | 12 ++++---- tests/uav.shader_test | 56 ++++++++++++++++++++++++++++++++++++ 5 files changed, 90 insertions(+), 11 deletions(-) create mode 100644 tests/uav.shader_test
diff --git a/Makefile.am b/Makefile.am index dd3ce1ff6..400dc8aae 100644 --- a/Makefile.am +++ b/Makefile.am @@ -132,6 +132,7 @@ vkd3d_shader_tests = \ tests/texture-load.shader_test \ tests/texture-load-typed.shader_test \ tests/trigonometry.shader_test \ + tests/uav.shader_test \ tests/writemask-assignop-0.shader_test \ tests/writemask-assignop-1.shader_test \ tests/writemask-assignop-2.shader_test \ diff --git a/tests/shader_runner.c b/tests/shader_runner.c index f367027f7..e2dc2dda6 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -370,6 +370,8 @@ static void set_uniforms(struct shader_runner *runner, size_t offset, size_t cou
static void parse_test_directive(struct shader_runner *runner, const char *line) { + char *rest; + runner->is_todo = false;
if (match_string(line, "todo", &line)) @@ -475,19 +477,33 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) if (runner->last_render_failed) return;
- resource = get_resource(runner, RESOURCE_TYPE_RENDER_TARGET, 0); + if (match_string(line, "uav", &line)) + { + unsigned int slot = strtoul(line, &rest, 10); + + if (rest == line) + fatal_error("Malformed UAV index '%s'.\n", line); + line = rest; + + resource = get_resource(runner, RESOURCE_TYPE_UAV, slot); + } + else + { + resource = get_resource(runner, RESOURCE_TYPE_RENDER_TARGET, 0); + } + rb = runner->ops->get_resource_readback(runner, resource);
if (match_string(line, "all", &line)) { set_rect(&rect, 0, 0, resource->width, resource->height); } - else if (sscanf(line, "( %d , %d , %d , %d )%n", &left, &top, &right, &bottom, &len) == 4) + else if (sscanf(line, " ( %d , %d , %d , %d )%n", &left, &top, &right, &bottom, &len) == 4) { set_rect(&rect, left, top, right, bottom); line += len; } - else if (sscanf(line, "( %u , %u )%n", &left, &top, &len) == 2) + else if (sscanf(line, " ( %u , %u )%n", &left, &top, &len) == 2) { set_rect(&rect, left, top, left + 1, top + 1); line += len; diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index 79d5b8ebb..871b50222 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -373,16 +373,20 @@ static struct resource_readback *d3d12_runner_get_resource_readback(struct shade struct test_context *test_context = &runner->test_context; struct d3d12_resource_readback *rb = malloc(sizeof(*rb)); struct d3d12_resource *resource = d3d12_resource(res); + D3D12_RESOURCE_STATES state;
- assert(resource->r.type == RESOURCE_TYPE_RENDER_TARGET); + if (resource->r.type == RESOURCE_TYPE_RENDER_TARGET) + state = D3D12_RESOURCE_STATE_RENDER_TARGET; + else + state = D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
transition_resource_state(test_context->list, resource->resource, - D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); + state, D3D12_RESOURCE_STATE_COPY_SOURCE); get_texture_readback_with_command_list(resource->resource, 0, rb, test_context->queue, test_context->list); reset_command_list(test_context->list, test_context->allocator); transition_resource_state(test_context->list, resource->resource, - D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET); + D3D12_RESOURCE_STATE_COPY_SOURCE, state);
return &rb->rb; } diff --git a/tests/shader_runner_vulkan.c b/tests/shader_runner_vulkan.c index adb69a7ce..190441263 100644 --- a/tests/shader_runner_vulkan.c +++ b/tests/shader_runner_vulkan.c @@ -943,8 +943,12 @@ static struct resource_readback *vulkan_runner_get_resource_readback(struct shad struct vulkan_resource *resource = vulkan_resource(res); VkDevice device = runner->device; VkBufferImageCopy region = {0}; + VkImageLayout layout;
- assert(resource->r.type == RESOURCE_TYPE_RENDER_TARGET); + if (resource->r.type == RESOURCE_TYPE_RENDER_TARGET) + layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + else + layout = VK_IMAGE_LAYOUT_GENERAL;
rb->rb.width = resource->r.width; rb->rb.height = resource->r.height; @@ -957,8 +961,7 @@ static struct resource_readback *vulkan_runner_get_resource_readback(struct shad
begin_command_buffer(runner);
- transition_image_layout(runner, resource->image, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + transition_image_layout(runner, resource->image, layout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; region.imageSubresource.layerCount = 1; @@ -969,8 +972,7 @@ static struct resource_readback *vulkan_runner_get_resource_readback(struct shad VK_CALL(vkCmdCopyImageToBuffer(runner->cmd_buffer, resource->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, rb->buffer, 1, ®ion));
- transition_image_layout(runner, resource->image, - VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + transition_image_layout(runner, resource->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, layout);
end_command_buffer(runner);
diff --git a/tests/uav.shader_test b/tests/uav.shader_test new file mode 100644 index 000000000..09ca05ece --- /dev/null +++ b/tests/uav.shader_test @@ -0,0 +1,56 @@ +[require] +shader model >= 5.0 + +[pixel shader fail] +RWTexture2D<float4> u; + +float4 main() : sv_target +{ + /* All four components must be written in a single statement. */ + u[uint2(0, 0)].xy = float4(1, 2); + u[uint2(0, 0)].zw = float4(3, 4); + return 0; +} + +[pixel shader fail] +Texture2D<float4> u; + +float4 main() : sv_target +{ + /* SRVs are not writable. */ + u[uint2(0, 0)].xyzw = float4(1, 2, 3, 4); + return 0; +} + +[uav 1] +format r32 float +size (2, 2) + +0.1 0.2 +0.3 0.4 + +[uav 2] +size (1, 1) + +0.5 0.6 0.7 0.8 + +[pixel shader] +RWTexture2D<float> u; +RWTexture2D<float4> v; + +float4 main() : sv_target +{ + u[uint2(0, 0)] = 0.5; + u[uint2(0, 1)].x = 0.6; + u[uint2(1, 1)] = 0.7; + v[uint2(0, 0)].yxwz = float4(1, 2, 3, 4); + return 0; +} + +[test] +todo draw quad +probe uav 1 (0, 0) r (0.5) +probe uav 1 (0, 1) r (0.6) +probe uav 1 (1, 0) r (0.2) +probe uav 1 (1, 1) r (0.7) +probe uav 2 (0, 0) rgba (2.0, 1.0, 4.0, 3.0)
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- Makefile.am | 1 + tests/multiple-rt.shader_test | 19 +++++++++++++++++++ tests/shader_runner.c | 26 ++++++++++++++++++++++++-- 3 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 tests/multiple-rt.shader_test
diff --git a/Makefile.am b/Makefile.am index 400dc8aae..6e827175a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -108,6 +108,7 @@ vkd3d_shader_tests = \ tests/hlsl-vector-indexing-uniform.shader_test \ tests/logic-operations.shader_test \ tests/math.shader_test \ + tests/multiple-rt.shader_test \ tests/nointerpolation.shader_test \ tests/pow.shader_test \ tests/preproc-if.shader_test \ diff --git a/tests/multiple-rt.shader_test b/tests/multiple-rt.shader_test new file mode 100644 index 000000000..59e4acbbe --- /dev/null +++ b/tests/multiple-rt.shader_test @@ -0,0 +1,19 @@ +[render target 0] +format r32g32b32a32 float +size (640, 480) + +[render target 1] +format r32g32b32a32 float +size (640, 480) + +[pixel shader] +void main(out float4 o0 : sv_target0, out float4 o1 : sv_target1) +{ + o0 = float4(0.1, 0.2, 0.3, 0.4); + o1 = float4(0.5, 0.6, 0.7, 0.8); +} + +[test] +draw quad +probe render target 0 all rgba (0.1, 0.2, 0.3, 0.4) +probe render target 1 all rgba (0.5, 0.6, 0.7, 0.8) diff --git a/tests/shader_runner.c b/tests/shader_runner.c index e2dc2dda6..25986b316 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -468,7 +468,7 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) } else if (match_string(line, "probe", &line)) { - unsigned int left, top, right, bottom, ulps; + unsigned int left, top, right, bottom, ulps, slot; struct resource_readback *rb; struct resource *resource; int ret, len; @@ -479,7 +479,7 @@ static void parse_test_directive(struct shader_runner *runner, const char *line)
if (match_string(line, "uav", &line)) { - unsigned int slot = strtoul(line, &rest, 10); + slot = strtoul(line, &rest, 10);
if (rest == line) fatal_error("Malformed UAV index '%s'.\n", line); @@ -487,6 +487,16 @@ static void parse_test_directive(struct shader_runner *runner, const char *line)
resource = get_resource(runner, RESOURCE_TYPE_UAV, slot); } + else if (match_string(line, "render target", &line)) + { + slot = strtoul(line, &rest, 10); + + if (rest == line) + fatal_error("Malformed render target index '%s'.\n", line); + line = rest; + + resource = get_resource(runner, RESOURCE_TYPE_RENDER_TARGET, slot); + } else { resource = get_resource(runner, RESOURCE_TYPE_RENDER_TARGET, 0); @@ -836,6 +846,18 @@ void run_shader_tests(struct shader_runner *runner, int argc, char **argv, const current_sampler->v_address = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; current_sampler->w_address = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; } + else if (sscanf(line, "[render target %u]\n", &index)) + { + state = STATE_RESOURCE; + + memset(¤t_resource, 0, sizeof(current_resource)); + + current_resource.slot = index; + current_resource.type = RESOURCE_TYPE_RENDER_TARGET; + current_resource.format = DXGI_FORMAT_R32G32B32A32_FLOAT; + current_resource.data_type = TEXTURE_DATA_FLOAT; + current_resource.texel_size = 16; + } else if (sscanf(line, "[texture %u]\n", &index)) { state = STATE_RESOURCE;
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Giovanni Mascellani gmascellani@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- Makefile.am | 1 + tests/matrix-semantics.shader_test | 102 +++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 tests/matrix-semantics.shader_test
diff --git a/Makefile.am b/Makefile.am index 6e827175a..bdbf8e408 100644 --- a/Makefile.am +++ b/Makefile.am @@ -108,6 +108,7 @@ vkd3d_shader_tests = \ tests/hlsl-vector-indexing-uniform.shader_test \ tests/logic-operations.shader_test \ tests/math.shader_test \ + tests/matrix-semantics.shader_test \ tests/multiple-rt.shader_test \ tests/nointerpolation.shader_test \ tests/pow.shader_test \ diff --git a/tests/matrix-semantics.shader_test b/tests/matrix-semantics.shader_test new file mode 100644 index 000000000..1be504064 --- /dev/null +++ b/tests/matrix-semantics.shader_test @@ -0,0 +1,102 @@ +[pixel shader] +float4x1 main() : sv_target +{ + return float4(1.0, 2.0, 3.0, 4.0); +} + +[test] +todo draw quad +probe all rgba (1.0, 2.0, 3.0, 4.0) + +[pixel shader] +row_major float1x4 main() : sv_target +{ + return float4(1.0, 2.0, 3.0, 4.0); +} + +[test] +todo draw quad +probe all rgba (1.0, 2.0, 3.0, 4.0) + +[require] +shader model >= 4.0 + +[render target 0] +format r32 float +size (640, 480) + +[render target 1] +format r32 float +size (640, 480) + +[render target 2] +format r32 float +size (640, 480) + +[render target 3] +format r32 float +size (640, 480) + +[pixel shader] +row_major float4x1 main() : sv_target +{ + return float4(1.0, 2.0, 3.0, 4.0); +} + +[test] +todo draw quad +probe render target 0 all r (1.0) +probe render target 1 all r (2.0) +probe render target 2 all r (3.0) +probe render target 3 all r (4.0) + +[pixel shader] +float1x4 main() : sv_target +{ + return float4(1.0, 2.0, 3.0, 4.0); +} + +[test] +todo draw quad +probe render target 0 all r (1.0) +probe render target 1 all r (2.0) +probe render target 2 all r (3.0) +probe render target 3 all r (4.0) + +[pixel shader fail todo] +void main(out float1x2 x : sv_target0, out float1x2 y : sv_target1) +{ + x = float2(1.0, 2.0); + y = float2(5.0, 6.0); +} + +[pixel shader] +void main(out float1x2 x : sv_target0, out float1x2 y : sv_target2) +{ + x = float2(1.0, 2.0); + y = float2(5.0, 6.0); +} + +[test] +todo draw quad +probe render target 0 all r (1.0) +probe render target 1 all r (2.0) +probe render target 2 all r (5.0) +probe render target 3 all r (6.0) + +[render target 0] +format r32g32b32a32 float +size (640, 480) + +[pixel shader] +void main(out row_major float1x4 x : sv_target0, out float1x2 y : sv_target1) +{ + x = float4(1.0, 2.0, 3.0, 4.0); + y = float2(5.0, 6.0); +} + +[test] +todo draw quad +probe render target 0 all rgba (1.0, 2.0, 3.0, 4.0) +probe render target 1 all r (5.0) +probe render target 2 all r (6.0)
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Giovanni Mascellani gmascellani@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl.y | 93 ++++++++++++++++++- tests/hlsl-duplicate-modifiers.shader_test | 2 +- tests/hlsl-initializer-matrix.shader_test | 2 +- ...lsl-return-implicit-conversion.shader_test | 8 +- tests/hlsl-shape.shader_test | 10 +- tests/matrix-semantics.shader_test | 12 +-- 6 files changed, 106 insertions(+), 21 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index cf0f51f2d..687569e83 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -266,6 +266,9 @@ static bool implicit_compatible_data_types(struct hlsl_type *t1, struct hlsl_typ return false; }
+static struct hlsl_ir_load *add_load(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *var_node, + struct hlsl_ir_node *offset, struct hlsl_type *data_type, const struct vkd3d_shader_location loc); + static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *node, struct hlsl_type *dst_type, const struct vkd3d_shader_location *loc) { @@ -275,10 +278,92 @@ static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct list *instrs, if (hlsl_types_are_equal(src_type, dst_type)) return node;
- if (!(cast = hlsl_new_cast(ctx, node, dst_type, loc))) - return NULL; - list_add_tail(instrs, &cast->node.entry); - return &cast->node; + if ((src_type->type == HLSL_CLASS_MATRIX || dst_type->type == HLSL_CLASS_MATRIX) + && src_type->type <= HLSL_CLASS_LAST_NUMERIC && dst_type->type <= HLSL_CLASS_LAST_NUMERIC) + { + struct vkd3d_string_buffer *name; + static unsigned int counter = 0; + struct hlsl_ir_load *load; + struct hlsl_ir_var *var; + unsigned int dst_idx; + bool broadcast; + + broadcast = src_type->dimx == 1 && src_type->dimy == 1; + assert(dst_type->dimx * dst_type->dimy <= src_type->dimx * src_type->dimy || broadcast); + if (src_type->type == HLSL_CLASS_MATRIX && dst_type->type == HLSL_CLASS_MATRIX && !broadcast) + { + assert(dst_type->dimx <= src_type->dimx); + assert(dst_type->dimy <= src_type->dimy); + } + + name = vkd3d_string_buffer_get(&ctx->string_buffers); + vkd3d_string_buffer_printf(name, "<cast-%u>", counter++); + var = hlsl_new_synthetic_var(ctx, name->buffer, dst_type, *loc); + vkd3d_string_buffer_release(&ctx->string_buffers, name); + if (!var) + return NULL; + + for (dst_idx = 0; dst_idx < dst_type->dimx * dst_type->dimy; ++dst_idx) + { + struct hlsl_type *src_scalar_type, *dst_scalar_type; + unsigned int src_idx, src_offset, dst_offset; + struct hlsl_ir_store *store; + struct hlsl_ir_constant *c; + + if (broadcast) + { + src_idx = 0; + } + else + { + if (src_type->type == HLSL_CLASS_MATRIX && dst_type->type == HLSL_CLASS_MATRIX) + { + unsigned int x = dst_idx % dst_type->dimx, y = dst_idx / dst_type->dimx; + + src_idx = y * src_type->dimx + x; + } + else + { + src_idx = dst_idx; + } + } + + dst_offset = hlsl_compute_component_offset(ctx, dst_type, dst_idx, &dst_scalar_type); + src_offset = hlsl_compute_component_offset(ctx, src_type, src_idx, &src_scalar_type); + + if (!(c = hlsl_new_uint_constant(ctx, src_offset, loc))) + return NULL; + list_add_tail(instrs, &c->node.entry); + + if (!(load = add_load(ctx, instrs, node, &c->node, src_scalar_type, *loc))) + return NULL; + + if (!(cast = hlsl_new_cast(ctx, &load->node, dst_scalar_type, loc))) + return NULL; + list_add_tail(instrs, &cast->node.entry); + + if (!(c = hlsl_new_uint_constant(ctx, dst_offset, loc))) + return NULL; + list_add_tail(instrs, &c->node.entry); + + if (!(store = hlsl_new_store(ctx, var, &c->node, &cast->node, 0, *loc))) + return NULL; + list_add_tail(instrs, &store->node.entry); + } + + if (!(load = hlsl_new_load(ctx, var, NULL, dst_type, *loc))) + return NULL; + list_add_tail(instrs, &load->node.entry); + + return &load->node; + } + else + { + if (!(cast = hlsl_new_cast(ctx, node, dst_type, loc))) + return NULL; + list_add_tail(instrs, &cast->node.entry); + return &cast->node; + } }
static struct hlsl_ir_node *add_implicit_conversion(struct hlsl_ctx *ctx, struct list *instrs, diff --git a/tests/hlsl-duplicate-modifiers.shader_test b/tests/hlsl-duplicate-modifiers.shader_test index fcae12da8..6491701ae 100644 --- a/tests/hlsl-duplicate-modifiers.shader_test +++ b/tests/hlsl-duplicate-modifiers.shader_test @@ -7,5 +7,5 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (0.1, 0.2, 0.3, 0.4) diff --git a/tests/hlsl-initializer-matrix.shader_test b/tests/hlsl-initializer-matrix.shader_test index ea9de9c03..7e12b0a00 100644 --- a/tests/hlsl-initializer-matrix.shader_test +++ b/tests/hlsl-initializer-matrix.shader_test @@ -55,7 +55,7 @@ float4 main() : SV_TARGET }
[test] -todo draw quad +draw quad probe all rgba (21, 22, 31, 32)
diff --git a/tests/hlsl-return-implicit-conversion.shader_test b/tests/hlsl-return-implicit-conversion.shader_test index bf99d9cbd..545340eb3 100644 --- a/tests/hlsl-return-implicit-conversion.shader_test +++ b/tests/hlsl-return-implicit-conversion.shader_test @@ -5,7 +5,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (0.4, 0.3, 0.2, 0.1)
[pixel shader] @@ -15,7 +15,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (0.4, 0.3, 0.2, 0.1)
[pixel shader] @@ -25,7 +25,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (0.4, 0.3, 0.2, 0.1)
[pixel shader] @@ -35,7 +35,7 @@ float4x1 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (0.4, 0.3, 0.2, 0.1)
[pixel shader] diff --git a/tests/hlsl-shape.shader_test b/tests/hlsl-shape.shader_test index 57d59534b..65cc322c1 100644 --- a/tests/hlsl-shape.shader_test +++ b/tests/hlsl-shape.shader_test @@ -211,7 +211,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 4.0, 6.0, 8.0)
[pixel shader] @@ -235,7 +235,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 4.0, 6.0, 8.0)
[pixel shader] @@ -260,7 +260,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 4.0, 6.0, 8.0)
[pixel shader] @@ -309,7 +309,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 4.0, 0.0, 0.0)
[pixel shader] @@ -321,7 +321,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 4.0, 0.0, 0.0)
[pixel shader] diff --git a/tests/matrix-semantics.shader_test b/tests/matrix-semantics.shader_test index 1be504064..43f467ecd 100644 --- a/tests/matrix-semantics.shader_test +++ b/tests/matrix-semantics.shader_test @@ -5,7 +5,7 @@ float4x1 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (1.0, 2.0, 3.0, 4.0)
[pixel shader] @@ -15,7 +15,7 @@ row_major float1x4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (1.0, 2.0, 3.0, 4.0)
[require] @@ -44,7 +44,7 @@ row_major float4x1 main() : sv_target }
[test] -todo draw quad +draw quad probe render target 0 all r (1.0) probe render target 1 all r (2.0) probe render target 2 all r (3.0) @@ -57,7 +57,7 @@ float1x4 main() : sv_target }
[test] -todo draw quad +draw quad probe render target 0 all r (1.0) probe render target 1 all r (2.0) probe render target 2 all r (3.0) @@ -78,7 +78,7 @@ void main(out float1x2 x : sv_target0, out float1x2 y : sv_target2) }
[test] -todo draw quad +draw quad probe render target 0 all r (1.0) probe render target 1 all r (2.0) probe render target 2 all r (5.0) @@ -96,7 +96,7 @@ void main(out row_major float1x4 x : sv_target0, out float1x2 y : sv_target1) }
[test] -todo draw quad +draw quad probe render target 0 all rgba (1.0, 2.0, 3.0, 4.0) probe render target 1 all r (5.0) probe render target 2 all r (6.0)
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Giovanni Mascellani gmascellani@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl.y | 74 ++++++++++++++++++++++++++++++++++++ tests/hlsl-shape.shader_test | 30 +++++++-------- 2 files changed, 89 insertions(+), 15 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 687569e83..2aee51533 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1201,6 +1201,22 @@ static bool expr_common_shape(struct hlsl_ctx *ctx, struct hlsl_type *t1, struct return true; }
+static unsigned int minor_size(const struct hlsl_type *type) +{ + if (type->modifiers & HLSL_MODIFIER_ROW_MAJOR) + return type->dimx; + else + return type->dimy; +} + +static unsigned int major_size(const struct hlsl_type *type) +{ + if (type->modifiers & HLSL_MODIFIER_ROW_MAJOR) + return type->dimy; + else + return type->dimx; +} + static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs, enum hlsl_ir_expr_op op, struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], struct hlsl_type *type, const struct vkd3d_shader_location *loc) @@ -1208,6 +1224,64 @@ static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_expr *expr; unsigned int i;
+ if (type->type == HLSL_CLASS_MATRIX) + { + struct vkd3d_string_buffer *name; + static unsigned int counter = 0; + struct hlsl_type *vector_type; + struct hlsl_ir_load *load; + struct hlsl_ir_var *var; + + vector_type = hlsl_get_vector_type(ctx, type->base_type, minor_size(type)); + + name = vkd3d_string_buffer_get(&ctx->string_buffers); + vkd3d_string_buffer_printf(name, "<split_op-%u>", counter++); + var = hlsl_new_synthetic_var(ctx, name->buffer, type, *loc); + vkd3d_string_buffer_release(&ctx->string_buffers, name); + if (!var) + return NULL; + + for (i = 0; i < major_size(type); i++) + { + struct hlsl_ir_node *value, *vector_operands[HLSL_MAX_OPERANDS] = { NULL }; + struct hlsl_ir_store *store; + struct hlsl_ir_constant *c; + unsigned int j; + + if (!(c = hlsl_new_uint_constant(ctx, 4 * i, loc))) + return NULL; + list_add_tail(instrs, &c->node.entry); + + for (j = 0; j < HLSL_MAX_OPERANDS; j++) + { + if (operands[j]) + { + struct hlsl_type *vector_arg_type; + struct hlsl_ir_load *load; + + vector_arg_type = hlsl_get_vector_type(ctx, operands[j]->data_type->base_type, minor_size(type)); + + if (!(load = add_load(ctx, instrs, operands[j], &c->node, vector_arg_type, *loc))) + return NULL; + vector_operands[j] = &load->node; + } + } + + if (!(value = add_expr(ctx, instrs, op, vector_operands, vector_type, loc))) + return NULL; + + if (!(store = hlsl_new_store(ctx, var, &c->node, value, 0, *loc))) + return NULL; + list_add_tail(instrs, &store->node.entry); + } + + if (!(load = hlsl_new_load(ctx, var, NULL, type, *loc))) + return NULL; + list_add_tail(instrs, &load->node.entry); + + return &load->node; + } + if (!(expr = hlsl_alloc(ctx, sizeof(*expr)))) return NULL; init_node(&expr->node, HLSL_IR_EXPR, type, *loc); diff --git a/tests/hlsl-shape.shader_test b/tests/hlsl-shape.shader_test index 65cc322c1..b96f0fd22 100644 --- a/tests/hlsl-shape.shader_test +++ b/tests/hlsl-shape.shader_test @@ -93,7 +93,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 4.0, 7.0, 9.0)
[pixel shader] @@ -107,7 +107,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 4.0, 7.0, 9.0)
[pixel shader] @@ -122,7 +122,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 4.0, 6.0, 8.0)
[pixel shader] @@ -137,7 +137,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 4.0, 6.0, 8.0)
[pixel shader] @@ -152,7 +152,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 7.0, 12.0, 17.0)
[pixel shader] @@ -167,7 +167,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 7.0, 12.0, 17.0)
[pixel shader] @@ -183,7 +183,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 4.0, 6.0, 0.0)
[pixel shader] @@ -199,7 +199,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (9.0, 11.0, 13.0, 0.0)
[pixel shader] @@ -223,7 +223,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 4.0, 6.0, 8.0)
[pixel shader] @@ -247,7 +247,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 4.0, 6.0, 8.0)
[pixel shader] @@ -273,7 +273,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 4.0, 6.0, 8.0)
[pixel shader] @@ -285,7 +285,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 3.0, 4.0, 5.0)
[pixel shader] @@ -297,7 +297,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 3.0, 4.0, 5.0)
[pixel shader] @@ -336,7 +336,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 3.0, 4.0, 5.0)
[pixel shader] @@ -351,5 +351,5 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (6.0, 7.0, 8.0, 9.0)
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Giovanni Mascellani gmascellani@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl.y | 118 ++++++++++++++++++++++++ tests/hlsl-majority-pragma.shader_test | 2 +- tests/hlsl-majority-typedef.shader_test | 2 +- tests/hlsl-mul.shader_test | 36 ++++---- 4 files changed, 138 insertions(+), 20 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 2aee51533..df5fda472 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -2046,6 +2046,123 @@ static bool intrinsic_min(struct hlsl_ctx *ctx, return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MIN, params->args[0], params->args[1], loc); }
+static bool intrinsic_mul(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *arg1 = params->args[0], *arg2 = params->args[1], *cast1, *cast2; + enum hlsl_base_type base = expr_common_base_type(arg1->data_type->base_type, arg2->data_type->base_type); + struct hlsl_type *cast_type1 = arg1->data_type, *cast_type2 = arg2->data_type, *matrix_type, *ret_type; + unsigned int i, j, k, vect_count = 0; + struct vkd3d_string_buffer *name; + static unsigned int counter = 0; + struct hlsl_ir_load *load; + struct hlsl_ir_var *var; + + if (arg1->data_type->type == HLSL_CLASS_SCALAR || arg2->data_type->type == HLSL_CLASS_SCALAR) + return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, arg1, arg2, loc); + + if (arg1->data_type->type == HLSL_CLASS_VECTOR) + { + vect_count++; + cast_type1 = hlsl_get_matrix_type(ctx, base, arg1->data_type->dimx, 1); + } + if (arg2->data_type->type == HLSL_CLASS_VECTOR) + { + vect_count++; + cast_type2 = hlsl_get_matrix_type(ctx, base, 1, arg2->data_type->dimx); + } + + matrix_type = hlsl_get_matrix_type(ctx, base, cast_type2->dimx, cast_type1->dimy); + + if (vect_count == 0) + { + ret_type = matrix_type; + } + else if (vect_count == 1) + { + assert(matrix_type->dimx == 1 || matrix_type->dimy == 1); + ret_type = hlsl_get_vector_type(ctx, base, matrix_type->dimx * matrix_type->dimy); + } + else + { + assert(matrix_type->dimx == 1 && matrix_type->dimy == 1); + ret_type = hlsl_get_scalar_type(ctx, base); + } + + if (!(cast1 = add_implicit_conversion(ctx, params->instrs, arg1, cast_type1, loc))) + return false; + + if (!(cast2 = add_implicit_conversion(ctx, params->instrs, arg2, cast_type2, loc))) + return false; + + name = vkd3d_string_buffer_get(&ctx->string_buffers); + vkd3d_string_buffer_printf(name, "<mul-%u>", counter++); + var = hlsl_new_synthetic_var(ctx, name->buffer, matrix_type, *loc); + vkd3d_string_buffer_release(&ctx->string_buffers, name); + if (!var) + return false; + + for (i = 0; i < matrix_type->dimx; ++i) + for (j = 0; j < matrix_type->dimy; ++j) + { + struct hlsl_ir_node *node = NULL; + struct hlsl_type *scalar_type; + struct hlsl_ir_store *store; + struct hlsl_ir_constant *c; + unsigned int offset; + + for (k = 0; k < cast_type1->dimx && k < cast_type2->dimy; ++k) + { + struct hlsl_ir_load *value1, *value2; + struct hlsl_ir_node *mul; + + offset = hlsl_compute_component_offset(ctx, cast_type1, j * cast_type1->dimx + k, &scalar_type); + if (!(c = hlsl_new_uint_constant(ctx, offset, loc))) + return false; + list_add_tail(params->instrs, &c->node.entry); + + if (!(value1 = add_load(ctx, params->instrs, cast1, &c->node, scalar_type, *loc))) + return false; + + offset = hlsl_compute_component_offset(ctx, cast_type2, k * cast_type2->dimx + i, &scalar_type); + if (!(c = hlsl_new_uint_constant(ctx, offset, loc))) + return false; + list_add_tail(params->instrs, &c->node.entry); + + if (!(value2 = add_load(ctx, params->instrs, cast2, &c->node, scalar_type, *loc))) + return false; + + if (!(mul = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, &value1->node, &value2->node, loc))) + return false; + + if (node) + { + if (!(node = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_ADD, node, mul, loc))) + return false; + } + else + { + node = mul; + } + } + + offset = hlsl_compute_component_offset(ctx, matrix_type, j * matrix_type->dimx + i, &scalar_type); + if (!(c = hlsl_new_uint_constant(ctx, offset, loc))) + return false; + list_add_tail(params->instrs, &c->node.entry); + + if (!(store = hlsl_new_store(ctx, var, &c->node, node, 0, *loc))) + return false; + list_add_tail(params->instrs, &store->node.entry); + } + + if (!(load = hlsl_new_load(ctx, var, NULL, matrix_type, *loc))) + return false; + list_add_tail(params->instrs, &load->node.entry); + + return !!add_implicit_conversion(ctx, params->instrs, &load->node, ret_type, loc); +} + static bool intrinsic_pow(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -2106,6 +2223,7 @@ intrinsic_functions[] = {"floor", 1, true, intrinsic_floor}, {"max", 2, true, intrinsic_max}, {"min", 2, true, intrinsic_min}, + {"mul", 2, true, intrinsic_mul}, {"pow", 2, true, intrinsic_pow}, {"round", 1, true, intrinsic_round}, {"saturate", 1, true, intrinsic_saturate}, diff --git a/tests/hlsl-majority-pragma.shader_test b/tests/hlsl-majority-pragma.shader_test index a9f917ff8..e7fc75cde 100644 --- a/tests/hlsl-majority-pragma.shader_test +++ b/tests/hlsl-majority-pragma.shader_test @@ -17,5 +17,5 @@ uniform 0 float4 0.1 0.2 0.0 0.0 uniform 4 float4 0.3 0.4 0.0 0.0 uniform 8 float4 0.1 0.3 0.0 0.0 uniform 12 float4 0.2 0.4 0.0 0.0 -todo draw quad +draw quad probe all rgba (0.17, 0.39, 0.17, 0.39) 1 diff --git a/tests/hlsl-majority-typedef.shader_test b/tests/hlsl-majority-typedef.shader_test index 192c96db1..1460e9a08 100644 --- a/tests/hlsl-majority-typedef.shader_test +++ b/tests/hlsl-majority-typedef.shader_test @@ -18,5 +18,5 @@ uniform 0 float4 0.1 0.2 0.0 0.0 uniform 4 float4 0.3 0.4 0.0 0.0 uniform 8 float4 0.1 0.3 0.0 0.0 uniform 12 float4 0.2 0.4 0.0 0.0 -todo draw quad +draw quad probe all rgba (0.17, 0.39, 0.17, 0.39) 1 diff --git a/tests/hlsl-mul.shader_test b/tests/hlsl-mul.shader_test index 1d137e696..7b4531873 100644 --- a/tests/hlsl-mul.shader_test +++ b/tests/hlsl-mul.shader_test @@ -12,7 +12,7 @@ float4 main(float4 pos : sv_position) : sv_target }
[test] -todo draw quad +draw quad probe all rgba (30.0, 70.0, 110.0, 150.0)
[pixel shader] @@ -28,7 +28,7 @@ float4 main(float4 pos : sv_position) : sv_target }
[test] -todo draw quad +draw quad probe all rgba (90.0, 100.0, 110.0, 120.0)
[pixel shader] @@ -44,7 +44,7 @@ float4 main(float4 pos : sv_position) : sv_target }
[test] -todo draw quad +draw quad probe all rgba (14.0, 38.0, 62.0, 86.0)
[pixel shader] @@ -60,7 +60,7 @@ float4 main(float4 pos : sv_position) : sv_target }
[test] -todo draw quad +draw quad probe all rgba (38.0, 44.0, 50.0, 56.0)
[pixel shader] @@ -75,7 +75,7 @@ float4 main(float4 pos : sv_position) : sv_target }
[test] -todo draw quad +draw quad probe all rgba (14.0, 32.0, 50.0, 0.0)
[pixel shader] @@ -90,7 +90,7 @@ float4 main(float4 pos : sv_position) : sv_target }
[test] -todo draw quad +draw quad probe all rgba (30.0, 36.0, 42.0, 0.0)
[pixel shader] @@ -106,7 +106,7 @@ float4 main(float4 pos : sv_position) : sv_target }
[test] -todo draw quad +draw quad probe all rgba (50.0, 60.0, 70.0, 80.0)
[pixel shader] @@ -122,7 +122,7 @@ float4 main(float4 pos : sv_position) : sv_target }
[test] -todo draw quad +draw quad probe all rgba (50.0, 60.0, 70.0, 80.0)
[pixel shader] @@ -138,7 +138,7 @@ float4 main(float4 pos : sv_position) : sv_target }
[test] -todo draw quad +draw quad probe all rgba (10.0, 20.0, 30.0, 40.0)
[pixel shader] @@ -154,7 +154,7 @@ float4 main(float4 pos : sv_position) : sv_target }
[test] -todo draw quad +draw quad probe all rgba (10.0, 50.0, 90.0, 130.0)
[pixel shader] @@ -170,7 +170,7 @@ float4 main(float4 pos : sv_position) : sv_target }
[test] -todo draw quad +draw quad probe all rgba (10.0, 20.0, 30.0, 40.0)
[pixel shader] @@ -186,7 +186,7 @@ float4 main(float4 pos : sv_position) : sv_target }
[test] -todo draw quad +draw quad probe all rgba (10.0, 50.0, 90.0, 130.0)
[pixel shader] @@ -202,7 +202,7 @@ float4 main(float4 pos : sv_position) : sv_target }
[test] -todo draw quad +draw quad probe all rgba (90.0, 100.0, 110.0, 120.0)
[pixel shader] @@ -218,7 +218,7 @@ float4 main(float4 pos : sv_position) : sv_target }
[test] -todo draw quad +draw quad probe all rgba (5.0, 10.0, 15.0, 20.0)
[pixel shader] @@ -234,7 +234,7 @@ float4 main(float4 pos : sv_position) : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 4.0, 6.0, 8.0)
[pixel shader] @@ -250,7 +250,7 @@ float4 main(float4 pos : sv_position) : sv_target }
[test] -todo draw quad +draw quad probe all rgba (30.0, 70.0, 110.0, 150.0)
[pixel shader] @@ -268,7 +268,7 @@ float4 main(float4 pos : sv_position) : sv_target }
[test] -todo draw quad +draw quad probe all rgba (83.0, 98.0, 113.0, 128.0)
[pixel shader] @@ -286,5 +286,5 @@ float4 main(float4 pos : sv_position) : sv_target }
[test] -todo draw quad +draw quad probe all rgba (78.0, 96.0, 114.0, 0.0)
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
Il 09/06/22 01:18, Zebediah Figura ha scritto:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
v6: avoid magic numbers...
tests/shader_runner.c | 38 +++++++++++++++++++--------- tests/shader_runner.h | 2 ++ tests/shader_runner_d3d11.c | 31 ++++++++++++++++++----- tests/shader_runner_d3d12.c | 37 +++++++++++++++++++++------ tests/shader_runner_d3d9.c | 12 ++++++--- tests/shader_runner_vulkan.c | 48 ++++++++++++++++++++++++++++-------- 6 files changed, 130 insertions(+), 38 deletions(-)
diff --git a/tests/shader_runner.c b/tests/shader_runner.c index 05e2a8a41..83f804ad3 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -78,14 +78,13 @@ enum parse_state STATE_PREPROC, STATE_PREPROC_INVALID, STATE_REQUIRE,
- STATE_RESOURCE, STATE_SAMPLER, STATE_SHADER_INVALID_PIXEL, STATE_SHADER_INVALID_PIXEL_TODO, STATE_SHADER_PIXEL, STATE_SHADER_VERTEX,
STATE_TEXTURE, STATE_TEST,
STATE_VERTEX_BUFFER, };
static bool match_string(const char *line, const char *token, const char **const rest)
@@ -314,6 +313,13 @@ static void parse_input_layout_directive(struct shader_runner *runner, const cha element->index = 0; }
+void init_resource(struct resource *resource, const struct resource_params *params) +{
- resource->type = params->type;
- resource->slot = params->slot;
- resource->size = params->data_size;
+}
- static void set_resource(struct shader_runner *runner, struct resource *resource) { size_t i;
@@ -617,8 +623,7 @@ void run_shader_tests(struct shader_runner *runner, int argc, char **argv, const goto out; break;
case STATE_TEXTURE:
case STATE_VERTEX_BUFFER:
case STATE_RESOURCE: set_resource(runner, runner->ops->create_resource(runner, ¤t_resource)); free(current_resource.data); break;
@@ -766,7 +771,7 @@ void run_shader_tests(struct shader_runner *runner, int argc, char **argv, const } else if (sscanf(line, "[texture %u]\n", &index)) {
state = STATE_TEXTURE;
state = STATE_RESOURCE; memset(¤t_resource, 0, sizeof(current_resource));
@@ -776,9 +781,21 @@ void run_shader_tests(struct shader_runner *runner, int argc, char **argv, const current_resource.data_type = TEXTURE_DATA_FLOAT; current_resource.texel_size = 16; }
else if (sscanf(line, "[uav %u]\n", &index))
{
state = STATE_RESOURCE;
memset(¤t_resource, 0, sizeof(current_resource));
current_resource.slot = index;
current_resource.type = RESOURCE_TYPE_UAV;
current_resource.format = DXGI_FORMAT_R32G32B32A32_FLOAT;
current_resource.data_type = TEXTURE_DATA_FLOAT;
current_resource.texel_size = 16;
} else if (sscanf(line, "[vertex buffer %u]\n", &index)) {
state = STATE_VERTEX_BUFFER;
state = STATE_RESOURCE; memset(¤t_resource, 0, sizeof(current_resource));
@@ -844,13 +861,12 @@ void run_shader_tests(struct shader_runner *runner, int argc, char **argv, const parse_require_directive(runner, line); break;
case STATE_SAMPLER:
parse_sampler_directive(current_sampler, line);
case STATE_RESOURCE:
parse_resource_directive(¤t_resource, line); break;
case STATE_TEXTURE:
case STATE_VERTEX_BUFFER:
parse_resource_directive(¤t_resource, line);
case STATE_SAMPLER:
parse_sampler_directive(current_sampler, line); break; case STATE_TEST:
diff --git a/tests/shader_runner.h b/tests/shader_runner.h index 6ed0109e6..60f894583 100644 --- a/tests/shader_runner.h +++ b/tests/shader_runner.h @@ -54,6 +54,7 @@ struct sampler enum resource_type { RESOURCE_TYPE_TEXTURE,
- RESOURCE_TYPE_UAV, RESOURCE_TYPE_VERTEX_BUFFER, };
@@ -130,6 +131,7 @@ struct shader_runner_ops void fatal_error(const char *format, ...) VKD3D_NORETURN VKD3D_PRINTF_FUNC(1, 2);
unsigned int get_vb_stride(const struct shader_runner *runner, unsigned int slot); +void init_resource(struct resource *resource, const struct resource_params *params);
void run_shader_tests(struct shader_runner *runner, int argc, char **argv, const struct shader_runner_ops *ops);
diff --git a/tests/shader_runner_d3d11.c b/tests/shader_runner_d3d11.c index 6edbdf75e..b80a8b65f 100644 --- a/tests/shader_runner_d3d11.c +++ b/tests/shader_runner_d3d11.c @@ -44,6 +44,7 @@ struct d3d11_resource
ID3D11Resource *resource; ID3D11ShaderResourceView *srv;
ID3D11UnorderedAccessView *uav; };
static struct d3d11_resource *d3d11_resource(struct resource *r)
@@ -374,13 +375,12 @@ static struct resource *d3d11_runner_create_resource(struct shader_runner *r, co HRESULT hr;
resource = calloc(1, sizeof(*resource));
- resource->r.slot = params->slot;
- resource->r.type = params->type;
init_resource(&resource->r, params);
switch (params->type) { case RESOURCE_TYPE_TEXTURE:
case RESOURCE_TYPE_UAV: { D3D11_TEXTURE2D_DESC desc = {0};
@@ -391,7 +391,10 @@ static struct resource *d3d11_runner_create_resource(struct shader_runner *r, co desc.Format = params->format; desc.SampleDesc.Count = 1; desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
if (params->type == RESOURCE_TYPE_UAV)
desc.BindFlags = D3D11_BIND_UNORDERED_ACCESS;
else
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; resource_data.pSysMem = params->data; resource_data.SysMemPitch = params->width * params->texel_size;
@@ -399,8 +402,11 @@ static struct resource *d3d11_runner_create_resource(struct shader_runner *r, co
hr = ID3D11Device_CreateTexture2D(device, &desc, &resource_data, (ID3D11Texture2D **)&resource->resource); ok(hr == S_OK, "Failed to create texture, hr %#lx.\n", hr);
hr = ID3D11Device_CreateShaderResourceView(device, resource->resource, NULL, &resource->srv);
ok(hr == S_OK, "Failed to create shader resource view, hr %#lx.\n", hr);
if (params->type == RESOURCE_TYPE_UAV)
hr = ID3D11Device_CreateUnorderedAccessView(device, resource->resource, NULL, &resource->uav);
else
hr = ID3D11Device_CreateShaderResourceView(device, resource->resource, NULL, &resource->srv);
ok(hr == S_OK, "Failed to create view, hr %#lx.\n", hr); break; }
@@ -420,14 +426,18 @@ static void d3d11_runner_destroy_resource(struct shader_runner *r, struct resour ID3D11Resource_Release(resource->resource); if (resource->srv) ID3D11ShaderResourceView_Release(resource->srv);
if (resource->uav)
ID3D11UnorderedAccessView_Release(resource->uav); free(resource);
}
static bool d3d11_runner_draw(struct shader_runner *r, D3D_PRIMITIVE_TOPOLOGY primitive_topology, unsigned int vertex_count) {
ID3D11UnorderedAccessView *uavs[D3D11_PS_CS_UAV_REGISTER_COUNT] = {0}; struct d3d11_shader_runner *runner = d3d11_shader_runner(r); ID3D11DeviceContext *context = runner->immediate_context;
unsigned int min_uav_slot = ARRAY_SIZE(uavs); ID3D11Device *device = runner->device; ID3D10Blob *vs_code, *ps_code; ID3D11Buffer *cb = NULL;
@@ -472,6 +482,11 @@ static bool d3d11_runner_draw(struct shader_runner *r, ID3D11DeviceContext_PSSetShaderResources(context, resource->r.slot, 1, &resource->srv); break;
case RESOURCE_TYPE_UAV:
uavs[resource->r.slot] = resource->uav;
min_uav_slot = min(min_uav_slot, resource->r.slot);
break;
case RESOURCE_TYPE_VERTEX_BUFFER: ID3D11DeviceContext_IASetVertexBuffers(context, resource->r.slot, 1, (ID3D11Buffer **)&resource->resource, &stride, &offset);
@@ -479,6 +494,10 @@ static bool d3d11_runner_draw(struct shader_runner *r, } }
- ID3D11DeviceContext_OMSetRenderTargetsAndUnorderedAccessViews(context,
D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL, NULL, NULL,
min_uav_slot, ARRAY_SIZE(uavs) - min_uav_slot, &uavs[min_uav_slot], NULL);
for (i = 0; i < runner->r.sampler_count; ++i) { struct sampler *sampler = &runner->r.samplers[i];
diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index 22c9b2266..ec08fea54 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -79,7 +79,7 @@ static ID3D10Blob *compile_shader(const struct d3d12_shader_runner *runner, cons return blob; }
-#define MAX_RESOURCE_DESCRIPTORS 256 +#define MAX_RESOURCE_DESCRIPTORS (MAX_RESOURCES * 2)
static struct resource *d3d12_runner_create_resource(struct shader_runner *r, const struct resource_params *params) { @@ -90,9 +90,7 @@ static struct resource *d3d12_runner_create_resource(struct shader_runner *r, co struct d3d12_resource *resource;
resource = calloc(1, sizeof(*resource));
- resource->r.slot = params->slot;
- resource->r.type = params->type;
- resource->r.size = params->data_size;
init_resource(&resource->r, params);
switch (params->type) {
@@ -101,9 +99,6 @@ static struct resource *d3d12_runner_create_resource(struct shader_runner *r, co runner->heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, MAX_RESOURCE_DESCRIPTORS);
if (params->slot >= MAX_RESOURCE_DESCRIPTORS)
fatal_error("Resource slot %u is too high; please increase MAX_RESOURCE_DESCRIPTORS.\n", params->slot);
resource->resource = create_default_texture(device, params->width, params->height, params->format, 0, D3D12_RESOURCE_STATE_COPY_DEST); resource_data.pData = params->data;
@@ -116,6 +111,23 @@ static struct resource *d3d12_runner_create_resource(struct shader_runner *r, co NULL, get_cpu_descriptor_handle(test_context, runner->heap, resource->r.slot)); break;
case RESOURCE_TYPE_UAV:
if (!runner->heap)
runner->heap = create_gpu_descriptor_heap(device,
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, MAX_RESOURCE_DESCRIPTORS);
resource->resource = create_default_texture(device, params->width, params->height,
params->format, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST);
resource_data.pData = params->data;
resource_data.SlicePitch = resource_data.RowPitch = params->width * params->texel_size;
upload_texture_data(resource->resource, &resource_data, 1, test_context->queue, test_context->list);
reset_command_list(test_context->list, test_context->allocator);
transition_resource_state(test_context->list, resource->resource,
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
ID3D12Device_CreateUnorderedAccessView(device, resource->resource,
NULL, NULL, get_cpu_descriptor_handle(test_context, runner->heap, resource->r.slot + MAX_RESOURCES));
break;
case RESOURCE_TYPE_VERTEX_BUFFER: resource->resource = create_upload_buffer(device, params->data_size, params->data); break;
@@ -192,6 +204,7 @@ static bool d3d12_runner_draw(struct shader_runner *r, switch (resource->r.type) { case RESOURCE_TYPE_TEXTURE:
case RESOURCE_TYPE_UAV: range = &resource->descriptor_range; resource->root_index = root_signature_desc.NumParameters++;
@@ -201,7 +214,10 @@ static bool d3d12_runner_draw(struct shader_runner *r, root_param->DescriptorTable.pDescriptorRanges = range; root_param->ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
range->RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
if (resource->r.type == RESOURCE_TYPE_UAV)
range->RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
else
range->RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; range->NumDescriptors = 1; range->BaseShaderRegister = resource->r.slot; range->RegisterSpace = 0;
@@ -281,6 +297,11 @@ static bool d3d12_runner_draw(struct shader_runner *r, get_gpu_descriptor_handle(test_context, runner->heap, resource->r.slot)); break;
case RESOURCE_TYPE_UAV:
ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, resource->root_index,
get_gpu_descriptor_handle(test_context, runner->heap, resource->r.slot + MAX_RESOURCES));
break;
case RESOURCE_TYPE_VERTEX_BUFFER: vbv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(resource->resource); vbv.StrideInBytes = get_vb_stride(&runner->r, resource->r.slot);
diff --git a/tests/shader_runner_d3d9.c b/tests/shader_runner_d3d9.c index b9ec55b4e..417d68750 100644 --- a/tests/shader_runner_d3d9.c +++ b/tests/shader_runner_d3d9.c @@ -222,9 +222,7 @@ static struct resource *d3d9_runner_create_resource(struct shader_runner *r, con void *data;
resource = calloc(1, sizeof(*resource));
- resource->r.slot = params->slot;
- resource->r.type = params->type;
- resource->r.size = params->data_size;
init_resource(&resource->r, params);
switch (params->type) {
@@ -257,6 +255,10 @@ static struct resource *d3d9_runner_create_resource(struct shader_runner *r, con ok(hr == D3D_OK, "Failed to unmap texture, hr %#lx.\n", hr); break;
case RESOURCE_TYPE_UAV:
fatal_error("UAVs are not supported.\n");
break;
case RESOURCE_TYPE_VERTEX_BUFFER: hr = IDirect3DDevice9_CreateVertexBuffer(device, params->data_size, D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT, &resource->vb, NULL);
@@ -366,6 +368,10 @@ static bool d3d9_runner_draw(struct shader_runner *r, ok(hr == D3D_OK, "Failed to set texture, hr %#lx.\n", hr); break;
case RESOURCE_TYPE_UAV:
assert(0);
break;
case RESOURCE_TYPE_VERTEX_BUFFER: for (j = 0; j < runner->r.input_element_count; ++j) {
diff --git a/tests/shader_runner_vulkan.c b/tests/shader_runner_vulkan.c index 601eb5a17..f5a0e7ec3 100644 --- a/tests/shader_runner_vulkan.c +++ b/tests/shader_runner_vulkan.c @@ -245,17 +245,25 @@ static struct resource *vulkan_runner_create_resource(struct shader_runner *r, c void *data;
resource = calloc(1, sizeof(*resource));
- resource->r.slot = params->slot;
- resource->r.type = params->type;
init_resource(&resource->r, params);
switch (params->type) { case RESOURCE_TYPE_TEXTURE:
case RESOURCE_TYPE_UAV:
{
VkImageUsageFlagBits usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
format = vkd3d_get_vk_format(params->format);
resource->image = create_2d_image(runner, params->width, params->height,
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, format, &resource->memory);
if (params->type == RESOURCE_TYPE_UAV)
{
layout = VK_IMAGE_LAYOUT_GENERAL;
usage |= VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
}
resource->image = create_2d_image(runner, params->width, params->height, usage, format, &resource->memory); resource->view = create_2d_image_view(runner, resource->image, format); staging_buffer = create_buffer(runner, params->data_size,
@@ -277,14 +285,14 @@ static struct resource *vulkan_runner_create_resource(struct shader_runner *r, c VK_CALL(vkCmdCopyBufferToImage(runner->cmd_buffer, staging_buffer, resource->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion));
transition_image_layout(runner, resource->image,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
transition_image_layout(runner, resource->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, layout); end_command_buffer(runner); VK_CALL(vkFreeMemory(device, staging_memory, NULL)); VK_CALL(vkDestroyBuffer(device, staging_buffer, NULL)); break;
} case RESOURCE_TYPE_VERTEX_BUFFER: resource->buffer = create_buffer(runner, params->data_size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
@@ -383,8 +391,12 @@ static bool compile_shader(const struct vulkan_shader_runner *runner, const char break;
case RESOURCE_TYPE_TEXTURE:
case RESOURCE_TYPE_UAV: binding = &bindings[interface_info.binding_count++];
binding->type = VKD3D_SHADER_DESCRIPTOR_TYPE_SRV;
if (resource->r.type == RESOURCE_TYPE_UAV)
binding->type = VKD3D_SHADER_DESCRIPTOR_TYPE_UAV;
else
binding->type = VKD3D_SHADER_DESCRIPTOR_TYPE_SRV; binding->register_space = 0; binding->register_index = resource->r.slot; binding->shader_visibility = VKD3D_SHADER_VISIBILITY_ALL;
@@ -557,6 +569,7 @@ static VkPipeline create_pipeline(const struct vulkan_shader_runner *runner, switch (resource->r.type) { case RESOURCE_TYPE_TEXTURE:
case RESOURCE_TYPE_UAV: break; case RESOURCE_TYPE_VERTEX_BUFFER:
@@ -662,12 +675,16 @@ static VkDescriptorSetLayout create_descriptor_set_layout(struct vulkan_shader_r break;
case RESOURCE_TYPE_TEXTURE:
case RESOURCE_TYPE_UAV: binding = &bindings[set_desc.bindingCount++]; resource->binding = binding_index++; binding->binding = resource->binding;
binding->descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
if (resource->r.type == RESOURCE_TYPE_UAV)
binding->descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
else
binding->descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; binding->descriptorCount = 1; binding->stageFlags = VK_SHADER_STAGE_ALL; binding->pImmutableSamplers = NULL;
@@ -729,6 +746,7 @@ static void bind_resources(struct vulkan_shader_runner *runner, VkPipelineBindPo switch (resource->r.type) { case RESOURCE_TYPE_TEXTURE:
case RESOURCE_TYPE_UAV: image_info.imageView = resource->view; image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
@@ -739,6 +757,12 @@ static void bind_resources(struct vulkan_shader_runner *runner, VkPipelineBindPo write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; write.pImageInfo = &image_info;
if (resource->r.type == RESOURCE_TYPE_UAV)
{
image_info.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
}
VK_CALL(vkUpdateDescriptorSets(runner->device, 1, &write, 0, NULL)); break;
@@ -967,7 +991,7 @@ static bool init_vulkan_runner(struct vulkan_shader_runner *runner) VkInstanceCreateInfo instance_desc = {.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO}; VkDeviceCreateInfo device_desc = {.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO}; VkPhysicalDeviceFeatures ret_features, features;
- VkDescriptorPoolSize descriptor_pool_sizes[2];
- VkDescriptorPoolSize descriptor_pool_sizes[3]; VkAttachmentDescription attachment_desc = {0}; static const float queue_priority = 1.0f; VkSubpassDescription subpass_desc = {0};
@@ -1049,7 +1073,9 @@ static bool init_vulkan_runner(struct vulkan_shader_runner *runner) } \ features.x = VK_TRUE
ENABLE_FEATURE(fragmentStoresAndAtomics); ENABLE_FEATURE(shaderImageGatherExtended);
ENABLE_FEATURE(shaderStorageImageWriteWithoutFormat);
if ((vr = VK_CALL(vkCreateDevice(runner->phys_device, &device_desc, NULL, &device)))) {
@@ -1115,6 +1141,8 @@ static bool init_vulkan_runner(struct vulkan_shader_runner *runner) descriptor_pool_sizes[0].descriptorCount = MAX_RESOURCES; descriptor_pool_sizes[1].type = VK_DESCRIPTOR_TYPE_SAMPLER; descriptor_pool_sizes[1].descriptorCount = MAX_SAMPLERS;
descriptor_pool_sizes[2].type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
descriptor_pool_sizes[2].descriptorCount = MAX_RESOURCES;
descriptor_pool_desc.maxSets = 1; descriptor_pool_desc.poolSizeCount = ARRAY_SIZE(descriptor_pool_sizes);