Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl_codegen.c | 47 +++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 16 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 78b229101..b4fcfd278 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -21,6 +21,22 @@ #include "hlsl.h" #include <stdio.h>
+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; +} + /* Split uniforms into two variables representing the constant and temp * registers, and copy the former to the latter, so that writes to uniforms * work. */ @@ -141,6 +157,21 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct list *instrs, struct struct hlsl_ir_var *output; struct hlsl_ir_load *load;
+ if (type->type == HLSL_CLASS_MATRIX) + { + struct hlsl_type *vector_type = hlsl_get_vector_type(ctx, type->base_type, minor_size(type)); + struct hlsl_semantic vector_semantic = *semantic; + unsigned int i; + + for (i = 0; i < major_size(type); ++i) + { + append_output_copy(ctx, instrs, var, vector_type, 4 * i, modifiers, &vector_semantic); + ++vector_semantic.index; + } + + return; + } + if (!(name = hlsl_get_string_buffer(ctx))) return; vkd3d_string_buffer_printf(name, "<output-%s%u>", semantic->name, semantic->index); @@ -847,22 +878,6 @@ static bool split_struct_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr 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 bool split_matrix_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { const struct hlsl_ir_node *rhs;
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl_codegen.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index b4fcfd278..6f5247449 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -84,6 +84,21 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct list *instrs, struct struct hlsl_ir_load *load; struct hlsl_ir_var *input;
+ if (type->type == HLSL_CLASS_MATRIX) + { + struct hlsl_type *vector_type = hlsl_get_vector_type(ctx, type->base_type, minor_size(type)); + struct hlsl_semantic vector_semantic = *semantic; + unsigned int i; + + for (i = 0; i < major_size(type); ++i) + { + prepend_input_copy(ctx, instrs, var, vector_type, 4 * i, modifiers, &vector_semantic); + ++vector_semantic.index; + } + + return; + } + if (!(name = hlsl_get_string_buffer(ctx))) return; vkd3d_string_buffer_printf(name, "<input-%s%u>", semantic->name, semantic->index);
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- v5: New patch.
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, 134 insertions(+), 34 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..f97e7bde9 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -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) { @@ -116,6 +114,27 @@ 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); + + 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, 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); + // fixme zf: un-magic this + ID3D12Device_CreateUnorderedAccessView(device, resource->resource, + NULL, NULL, get_cpu_descriptor_handle(test_context, runner->heap, resource->r.slot + 32)); + break; + case RESOURCE_TYPE_VERTEX_BUFFER: resource->resource = create_upload_buffer(device, params->data_size, params->data); break; @@ -192,6 +211,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 +221,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 +304,12 @@ 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: + // fixme zf: un-magic + ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, resource->root_index, + get_gpu_descriptor_handle(test_context, runner->heap, resource->r.slot + 32)); + 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);
On Tue, 7 Jun 2022 at 23:48, Zebediah Figura zfigura@codeweavers.com wrote:
// fixme zf: un-magic this
ID3D12Device_CreateUnorderedAccessView(device, resource->resource,
NULL, NULL, get_cpu_descriptor_handle(test_context, runner->heap, resource->r.slot + 32));
break;
Some left-over magic? :)
case RESOURCE_TYPE_UAV:
// fixme zf: un-magic
ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, resource->root_index,
get_gpu_descriptor_handle(test_context, runner->heap, resource->r.slot + 32));
break;
Likewise.
Hi,
Il 07/06/22 23:29, Zebediah Figura ha scritto:
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);
// fixme zf: un-magic this
ID3D12Device_CreateUnorderedAccessView(device, resource->resource,
NULL, NULL, get_cpu_descriptor_handle(test_context, runner->heap, resource->r.slot + 32));
break;
Is that intended, or should this have been un-magiced before submission? It feels magic indeed (though so far much of D3D12 and Vulkan feels somewhat magic to me)!
Same thing for the Vulkan runner.
Giovanni.
Prepare to allow for dynamically changing the bound attachments in consecutive draw calls.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- v5: New patch.
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: Giovanni Mascellani gmascellani@codeweavers.com
Il 07/06/22 23:29, Zebediah Figura ha scritto:
Prepare to allow for dynamically changing the bound attachments in consecutive draw calls.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
v5: New patch.
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: Zebediah Figura zfigura@codeweavers.com --- v5: New patch.
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 f97e7bde9..b916de3c2 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, @@ -157,18 +171,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; @@ -192,6 +207,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++; @@ -231,6 +256,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; } @@ -258,6 +289,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) { @@ -272,15 +305,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); @@ -299,6 +329,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)); @@ -320,11 +357,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);
@@ -338,16 +375,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; } @@ -355,13 +398,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); }
@@ -370,7 +408,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, };
@@ -394,5 +432,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: Giovanni Mascellani gmascellani@codeweavers.com
Il 07/06/22 23:29, Zebediah Figura ha scritto:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
v5: New patch.
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 f97e7bde9..b916de3c2 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,
@@ -157,18 +171,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;
@@ -192,6 +207,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++;
@@ -231,6 +256,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; }
@@ -258,6 +289,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) {
@@ -272,15 +305,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);
@@ -299,6 +329,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));
@@ -320,11 +357,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);
@@ -338,16 +375,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;
}
@@ -355,13 +398,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);
}
@@ -370,7 +408,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, };
@@ -394,5 +432,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: Zebediah Figura zfigura@codeweavers.com --- v5: New patch.
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 b916de3c2..02d625c64 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -381,16 +381,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: Giovanni Mascellani gmascellani@codeweavers.com
Il 07/06/22 23:29, Zebediah Figura ha scritto:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
v5: New patch.
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 b916de3c2..02d625c64 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -381,16 +381,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: Zebediah Figura zfigura@codeweavers.com --- v5: New patch.
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: Giovanni Mascellani gmascellani@codeweavers.com
Il 07/06/22 23:29, Zebediah Figura ha scritto:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
v5: New patch.
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;
From: Giovanni Mascellani gmascellani@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- v5: Expand to bind and test all used render targets.
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: Giovanni Mascellani gmascellani@codeweavers.com
Il 07/06/22 23:29, Zebediah Figura ha scritto:
From: Giovanni Mascellani gmascellani@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
v5: Expand to bind and test all used render targets.
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)
From: Giovanni Mascellani gmascellani@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Francisco Casas fcasas@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl_codegen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 6f5247449..1a5e9055a 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -1378,7 +1378,7 @@ static void allocate_variable_temp_register(struct hlsl_ctx *ctx, struct hlsl_ir var->last_read, var->data_type->reg_size); else var->reg = allocate_register(ctx, liveness, var->first_write, - var->last_read, var->data_type->dimx); + var->last_read, hlsl_type_component_count(var->data_type)); TRACE("Allocated %s to %s (liveness %u-%u).\n", var->name, debug_register('r', var->reg, var->data_type), var->first_write, var->last_read); }
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 | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index faac562ab..23c48cdc8 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -266,7 +266,7 @@ static bool implicit_compatible_data_types(struct hlsl_type *t1, struct hlsl_typ return false; }
-static struct hlsl_ir_node *add_implicit_conversion(struct hlsl_ctx *ctx, struct list *instrs, +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) { struct hlsl_type *src_type = node->data_type; @@ -275,6 +275,17 @@ static struct hlsl_ir_node *add_implicit_conversion(struct hlsl_ctx *ctx, struct 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; +} + +static struct hlsl_ir_node *add_implicit_conversion(struct hlsl_ctx *ctx, struct list *instrs, + struct hlsl_ir_node *node, struct hlsl_type *dst_type, const struct vkd3d_shader_location *loc) +{ + struct hlsl_type *src_type = node->data_type; + if (!implicit_compatible_data_types(src_type, dst_type)) { struct vkd3d_string_buffer *src_string, *dst_string; @@ -293,10 +304,7 @@ static struct hlsl_ir_node *add_implicit_conversion(struct hlsl_ctx *ctx, struct hlsl_warning(ctx, loc, VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION, "Implicit truncation of %s type.", src_type->type == HLSL_CLASS_VECTOR ? "vector" : "matrix");
- if (!(cast = hlsl_new_cast(ctx, node, dst_type, loc))) - return NULL; - list_add_tail(instrs, &cast->node.entry); - return &cast->node; + return add_cast(ctx, instrs, node, dst_type, loc); }
static DWORD add_modifiers(struct hlsl_ctx *ctx, DWORD modifiers, DWORD mod, const struct vkd3d_shader_location loc) @@ -3718,7 +3726,6 @@ unary_expr: { struct hlsl_type *src_type = node_from_list($6)->data_type; struct hlsl_type *dst_type; - struct hlsl_ir_expr *cast; unsigned int i;
if ($2) @@ -3746,12 +3753,11 @@ unary_expr: YYABORT; }
- if (!(cast = hlsl_new_cast(ctx, node_from_list($6), dst_type, &@3))) + if (!add_cast(ctx, $6, node_from_list($6), dst_type, &@3)) { hlsl_free_instr_list($6); YYABORT; } - list_add_tail($6, &cast->node.entry); $$ = $6; }
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 23c48cdc8..f85d42527 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)
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 | 54 +++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 31 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index f85d42527..687569e83 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -674,7 +674,7 @@ static bool add_record_load(struct hlsl_ctx *ctx, struct list *instrs, struct hl return !!add_load(ctx, instrs, record, &c->node, field->type, loc); }
-static struct hlsl_ir_expr *add_binary_arithmetic_expr(struct hlsl_ctx *ctx, struct list *instrs, +static struct hlsl_ir_node *add_binary_arithmetic_expr(struct hlsl_ctx *ctx, struct list *instrs, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, const struct vkd3d_shader_location *loc);
@@ -682,8 +682,7 @@ static struct hlsl_ir_node *add_matrix_scalar_load(struct hlsl_ctx *ctx, struct struct hlsl_ir_node *matrix, struct hlsl_ir_node *x, struct hlsl_ir_node *y, const struct vkd3d_shader_location *loc) { - struct hlsl_ir_node *major, *minor; - struct hlsl_ir_expr *mul, *add; + struct hlsl_ir_node *major, *minor, *mul, *add; struct hlsl_ir_constant *four; struct hlsl_ir_load *load; struct hlsl_type *type = matrix->data_type, *scalar_type; @@ -708,10 +707,10 @@ static struct hlsl_ir_node *add_matrix_scalar_load(struct hlsl_ctx *ctx, struct if (!(mul = add_binary_arithmetic_expr(ctx, instrs, HLSL_OP2_MUL, &four->node, major, loc))) return NULL;
- if (!(add = add_binary_arithmetic_expr(ctx, instrs, HLSL_OP2_ADD, &mul->node, minor, loc))) + if (!(add = add_binary_arithmetic_expr(ctx, instrs, HLSL_OP2_ADD, mul, minor, loc))) return NULL;
- if (!(load = add_load(ctx, instrs, matrix, &add->node, scalar_type, *loc))) + if (!(load = add_load(ctx, instrs, matrix, add, scalar_type, *loc))) return NULL;
return &load->node; @@ -1202,7 +1201,7 @@ static bool expr_common_shape(struct hlsl_ctx *ctx, struct hlsl_type *t1, struct return true; }
-static struct hlsl_ir_expr *add_expr(struct hlsl_ctx *ctx, struct list *instrs, +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) { @@ -1217,7 +1216,7 @@ static struct hlsl_ir_expr *add_expr(struct hlsl_ctx *ctx, struct list *instrs, hlsl_src_from_node(&expr->operands[i], operands[i]); list_add_tail(instrs, &expr->node.entry);
- return expr; + return &expr->node; }
static void check_integer_type(struct hlsl_ctx *ctx, const struct hlsl_ir_node *instr) @@ -1241,7 +1240,7 @@ static void check_integer_type(struct hlsl_ctx *ctx, const struct hlsl_ir_node * } }
-static struct hlsl_ir_expr *add_unary_arithmetic_expr(struct hlsl_ctx *ctx, struct list *instrs, +static struct hlsl_ir_node *add_unary_arithmetic_expr(struct hlsl_ctx *ctx, struct list *instrs, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, const struct vkd3d_shader_location *loc) { struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {arg}; @@ -1249,7 +1248,7 @@ static struct hlsl_ir_expr *add_unary_arithmetic_expr(struct hlsl_ctx *ctx, stru return add_expr(ctx, instrs, op, args, arg->data_type, loc); }
-static struct hlsl_ir_expr *add_unary_bitwise_expr(struct hlsl_ctx *ctx, struct list *instrs, +static struct hlsl_ir_node *add_unary_bitwise_expr(struct hlsl_ctx *ctx, struct list *instrs, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, const struct vkd3d_shader_location *loc) { check_integer_type(ctx, arg); @@ -1257,7 +1256,7 @@ static struct hlsl_ir_expr *add_unary_bitwise_expr(struct hlsl_ctx *ctx, struct return add_unary_arithmetic_expr(ctx, instrs, op, arg, loc); }
-static struct hlsl_ir_expr *add_unary_logical_expr(struct hlsl_ctx *ctx, struct list *instrs, +static struct hlsl_ir_node *add_unary_logical_expr(struct hlsl_ctx *ctx, struct list *instrs, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, const struct vkd3d_shader_location *loc) { struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {0}; @@ -1272,7 +1271,7 @@ static struct hlsl_ir_expr *add_unary_logical_expr(struct hlsl_ctx *ctx, struct return add_expr(ctx, instrs, op, args, bool_type, loc); }
-static struct hlsl_ir_expr *add_binary_arithmetic_expr(struct hlsl_ctx *ctx, struct list *instrs, +static struct hlsl_ir_node *add_binary_arithmetic_expr(struct hlsl_ctx *ctx, struct list *instrs, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, const struct vkd3d_shader_location *loc) { @@ -1307,7 +1306,7 @@ static struct list *add_binary_arithmetic_expr_merge(struct hlsl_ctx *ctx, struc return list1; }
-static struct hlsl_ir_expr *add_binary_bitwise_expr(struct hlsl_ctx *ctx, struct list *instrs, +static struct hlsl_ir_node *add_binary_bitwise_expr(struct hlsl_ctx *ctx, struct list *instrs, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, const struct vkd3d_shader_location *loc) { @@ -1329,7 +1328,7 @@ static struct list *add_binary_bitwise_expr_merge(struct hlsl_ctx *ctx, struct l return list1; }
-static struct hlsl_ir_expr *add_binary_comparison_expr(struct hlsl_ctx *ctx, struct list *instrs, +static struct hlsl_ir_node *add_binary_comparison_expr(struct hlsl_ctx *ctx, struct list *instrs, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, struct vkd3d_shader_location *loc) { @@ -1365,7 +1364,7 @@ static struct list *add_binary_comparison_expr_merge(struct hlsl_ctx *ctx, struc return list1; }
-static struct hlsl_ir_expr *add_binary_logical_expr(struct hlsl_ctx *ctx, struct list *instrs, +static struct hlsl_ir_node *add_binary_logical_expr(struct hlsl_ctx *ctx, struct list *instrs, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, const struct vkd3d_shader_location *loc) { @@ -1400,7 +1399,7 @@ static struct list *add_binary_logical_expr_merge(struct hlsl_ctx *ctx, struct l return list1; }
-static struct hlsl_ir_expr *add_binary_shift_expr(struct hlsl_ctx *ctx, struct list *instrs, +static struct hlsl_ir_node *add_binary_shift_expr(struct hlsl_ctx *ctx, struct list *instrs, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, const struct vkd3d_shader_location *loc) { @@ -1509,22 +1508,17 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in
if (assign_op == ASSIGN_OP_SUB) { - struct hlsl_ir_expr *expr; - - if (!(expr = add_unary_arithmetic_expr(ctx, instrs, HLSL_OP1_NEG, rhs, &rhs->loc))) + if (!(rhs = add_unary_arithmetic_expr(ctx, instrs, HLSL_OP1_NEG, rhs, &rhs->loc))) return NULL; - rhs = &expr->node; assign_op = ASSIGN_OP_ADD; } if (assign_op != ASSIGN_OP_ASSIGN) { enum hlsl_ir_expr_op op = op_from_assignment(assign_op); - struct hlsl_ir_expr *expr;
assert(op); - if (!(expr = add_binary_arithmetic_expr(ctx, instrs, op, lhs, rhs, &rhs->loc))) + if (!(rhs = add_binary_arithmetic_expr(ctx, instrs, op, lhs, rhs, &rhs->loc))) return NULL; - rhs = &expr->node; }
if (lhs_type->type <= HLSL_CLASS_LAST_NUMERIC) @@ -1894,12 +1888,12 @@ static bool intrinsic_abs(struct hlsl_ctx *ctx, static bool intrinsic_clamp(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { - struct hlsl_ir_expr *max; + struct hlsl_ir_node *max;
if (!(max = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MAX, params->args[0], params->args[1], loc))) return false;
- return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MIN, &max->node, params->args[2], loc); + return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MIN, max, params->args[2], loc); }
static bool intrinsic_cross(struct hlsl_ctx *ctx, @@ -1907,8 +1901,7 @@ static bool intrinsic_cross(struct hlsl_ctx *ctx, { struct hlsl_ir_swizzle *arg1_swzl1, *arg1_swzl2, *arg2_swzl1, *arg2_swzl2; struct hlsl_ir_node *arg1 = params->args[0], *arg2 = params->args[1]; - struct hlsl_ir_node *arg1_cast, *arg2_cast, *mul1_neg; - struct hlsl_ir_expr *mul1, *mul2; + struct hlsl_ir_node *arg1_cast, *arg2_cast, *mul1_neg, *mul1, *mul2; struct hlsl_type *cast_type; enum hlsl_base_type base;
@@ -1937,7 +1930,7 @@ static bool intrinsic_cross(struct hlsl_ctx *ctx, &arg1_swzl1->node, &arg2_swzl1->node, loc))) return false;
- if (!(mul1_neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, &mul1->node, *loc))) + if (!(mul1_neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, mul1, *loc))) return false; list_add_tail(params->instrs, &mul1_neg->entry);
@@ -1953,7 +1946,7 @@ static bool intrinsic_cross(struct hlsl_ctx *ctx, &arg1_swzl2->node, &arg2_swzl2->node, loc))) return false;
- return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_ADD, &mul2->node, mul1_neg, loc); + return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_ADD, mul2, mul1_neg, loc); }
static bool intrinsic_floor(struct hlsl_ctx *ctx, @@ -1982,8 +1975,7 @@ static bool intrinsic_min(struct hlsl_ctx *ctx, static bool intrinsic_pow(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { - struct hlsl_ir_node *log, *exp, *arg; - struct hlsl_ir_expr *mul; + struct hlsl_ir_node *log, *exp, *arg, *mul;
if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) return false; @@ -1995,7 +1987,7 @@ static bool intrinsic_pow(struct hlsl_ctx *ctx, if (!(mul = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, params->args[1], log, loc))) return false;
- if (!(exp = hlsl_new_unary_expr(ctx, HLSL_OP1_EXP2, &mul->node, *loc))) + if (!(exp = hlsl_new_unary_expr(ctx, HLSL_OP1_EXP2, mul, *loc))) return false; list_add_tail(params->instrs, &exp->entry); return true;
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)
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)