From: Francisco Casas fcasas@codeweavers.com
If in the same shader_test file we have both a [buffer uav n] and a [uav n] with the same slot "n", we want the last one to override the first one instead of passing both resources to the backends.
Same for [buffer srv n] and [texture n] after we introduce SRV buffers. --- tests/shader_runner.c | 13 ++- tests/shader_runner.h | 9 +- tests/shader_runner_d3d11.c | 190 ++++++++++++++++-------------- tests/shader_runner_d3d12.c | 65 +++++------ tests/shader_runner_d3d9.c | 2 - tests/shader_runner_gl.c | 123 +++++++++++--------- tests/shader_runner_vulkan.c | 220 +++++++++++++++++++---------------- 7 files changed, 342 insertions(+), 280 deletions(-)
diff --git a/tests/shader_runner.c b/tests/shader_runner.c index fe5ee5972..5447a08ea 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -505,6 +505,7 @@ static void parse_input_layout_directive(struct shader_runner *runner, const cha void init_resource(struct resource *resource, const struct resource_params *params) { resource->type = params->type; + resource->dimension = params->dimension; resource->slot = params->slot; resource->format = params->format; resource->size = params->data_size; @@ -698,6 +699,7 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) memset(¶ms, 0, sizeof(params)); params.slot = 0; params.type = RESOURCE_TYPE_RENDER_TARGET; + params.dimension = RESOURCE_DIMENSION_2D; params.format = DXGI_FORMAT_R32G32B32A32_FLOAT; params.data_type = TEXTURE_DATA_FLOAT; params.texel_size = 16; @@ -724,6 +726,7 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) memset(¶ms, 0, sizeof(params)); params.slot = 0; params.type = RESOURCE_TYPE_VERTEX_BUFFER; + params.dimension = RESOURCE_DIMENSION_BUFFER; params.data = malloc(sizeof(quad)); memcpy(params.data, quad, sizeof(quad)); params.data_size = sizeof(quad); @@ -746,6 +749,7 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) memset(¶ms, 0, sizeof(params)); params.slot = 0; params.type = RESOURCE_TYPE_RENDER_TARGET; + params.dimension = RESOURCE_DIMENSION_2D; params.format = DXGI_FORMAT_R32G32B32A32_FLOAT; params.data_type = TEXTURE_DATA_FLOAT; params.texel_size = 16; @@ -798,7 +802,7 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) fatal_error("Malformed buffer UAV index '%s'.\n", line); line = rest;
- resource = shader_runner_get_resource(runner, RESOURCE_TYPE_BUFFER_UAV, slot); + resource = shader_runner_get_resource(runner, RESOURCE_TYPE_UAV, slot); } else if (match_string(line, "render target", &line)) { @@ -1506,6 +1510,7 @@ void run_shader_tests(struct shader_runner *runner, const struct shader_runner_o
current_resource.slot = index; current_resource.type = RESOURCE_TYPE_RENDER_TARGET; + current_resource.dimension = RESOURCE_DIMENSION_2D; current_resource.format = DXGI_FORMAT_R32G32B32A32_FLOAT; current_resource.data_type = TEXTURE_DATA_FLOAT; current_resource.texel_size = 16; @@ -1519,6 +1524,7 @@ void run_shader_tests(struct shader_runner *runner, const struct shader_runner_o
current_resource.slot = index; current_resource.type = RESOURCE_TYPE_TEXTURE; + current_resource.dimension = RESOURCE_DIMENSION_2D; current_resource.format = DXGI_FORMAT_R32G32B32A32_FLOAT; current_resource.data_type = TEXTURE_DATA_FLOAT; current_resource.texel_size = 16; @@ -1532,6 +1538,7 @@ void run_shader_tests(struct shader_runner *runner, const struct shader_runner_o
current_resource.slot = index; current_resource.type = RESOURCE_TYPE_UAV; + current_resource.dimension = RESOURCE_DIMENSION_2D; current_resource.format = DXGI_FORMAT_R32G32B32A32_FLOAT; current_resource.data_type = TEXTURE_DATA_FLOAT; current_resource.texel_size = 16; @@ -1544,7 +1551,8 @@ void run_shader_tests(struct shader_runner *runner, const struct shader_runner_o memset(¤t_resource, 0, sizeof(current_resource));
current_resource.slot = index; - current_resource.type = RESOURCE_TYPE_BUFFER_UAV; + current_resource.type = RESOURCE_TYPE_UAV; + current_resource.dimension = RESOURCE_DIMENSION_BUFFER; current_resource.format = DXGI_FORMAT_R32G32B32A32_FLOAT; current_resource.data_type = TEXTURE_DATA_FLOAT; current_resource.texel_size = 16; @@ -1558,6 +1566,7 @@ void run_shader_tests(struct shader_runner *runner, const struct shader_runner_o
current_resource.slot = index; current_resource.type = RESOURCE_TYPE_VERTEX_BUFFER; + current_resource.dimension = RESOURCE_DIMENSION_BUFFER; current_resource.data_type = TEXTURE_DATA_FLOAT; } else if (!strcmp(line, "[test]\n")) diff --git a/tests/shader_runner.h b/tests/shader_runner.h index a17fa485b..a17ad2a80 100644 --- a/tests/shader_runner.h +++ b/tests/shader_runner.h @@ -69,14 +69,20 @@ enum resource_type RESOURCE_TYPE_RENDER_TARGET, RESOURCE_TYPE_TEXTURE, RESOURCE_TYPE_UAV, - RESOURCE_TYPE_BUFFER_UAV, RESOURCE_TYPE_VERTEX_BUFFER, };
+enum resource_dimension +{ + RESOURCE_DIMENSION_BUFFER, + RESOURCE_DIMENSION_2D, +}; + struct resource_params { unsigned int slot; enum resource_type type; + enum resource_dimension dimension;
DXGI_FORMAT format; enum texture_data_type data_type; @@ -91,6 +97,7 @@ struct resource { unsigned int slot; enum resource_type type; + enum resource_dimension dimension;
DXGI_FORMAT format; unsigned int size; diff --git a/tests/shader_runner_d3d11.c b/tests/shader_runner_d3d11.c index 1e22d44ef..c38285d07 100644 --- a/tests/shader_runner_d3d11.c +++ b/tests/shader_runner_d3d11.c @@ -361,12 +361,87 @@ static ID3D11Buffer *create_buffer(ID3D11Device *device, unsigned int bind_flags return buffer; }
+static void init_resource_2d(struct d3d11_shader_runner *runner, struct d3d11_resource *resource, + const struct resource_params *params) +{ + D3D11_SUBRESOURCE_DATA resource_data[2]; + ID3D11Device *device = runner->device; + D3D11_TEXTURE2D_DESC desc = {0}; + HRESULT hr; + + if (params->level_count > ARRAY_SIZE(resource_data)) + fatal_error("Level count %u is too high.\n", params->level_count); + + desc.Width = params->width; + desc.Height = params->height; + desc.MipLevels = params->level_count; + desc.ArraySize = 1; + desc.Format = params->format; + desc.SampleDesc.Count = 1; + 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; + + if (params->data) + { + unsigned int buffer_offset = 0; + + for (unsigned int level = 0; level < params->level_count; ++level) + { + unsigned int level_width = get_level_dimension(params->width, level); + unsigned int level_height = get_level_dimension(params->height, level); + + resource_data[level].pSysMem = ¶ms->data[buffer_offset]; + resource_data[level].SysMemPitch = level_width * params->texel_size; + resource_data[level].SysMemSlicePitch = level_height * resource_data[level].SysMemPitch; + buffer_offset += resource_data[level].SysMemSlicePitch; + } + 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); +} + +static void init_resource_uav_buffer(struct d3d11_shader_runner *runner, struct d3d11_resource *resource, + const struct resource_params *params) +{ + D3D11_UNORDERED_ACCESS_VIEW_DESC uav_desc; + ID3D11Device *device = runner->device; + HRESULT hr; + + resource->buffer = create_buffer(device, D3D11_BIND_UNORDERED_ACCESS, params->data_size, params->data); + resource->resource = (ID3D11Resource *)resource->buffer; + + uav_desc.Format = params->format; + uav_desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER; + uav_desc.Buffer.FirstElement = 0; + uav_desc.Buffer.NumElements = params->data_size / params->texel_size; + uav_desc.Buffer.Flags = 0; + hr = ID3D11Device_CreateUnorderedAccessView(device, resource->resource, &uav_desc, &resource->uav); + ok(hr == S_OK, "Failed to create view, hr %#lx.\n", hr); +} + static struct resource *d3d11_runner_create_resource(struct shader_runner *r, const struct resource_params *params) { struct d3d11_shader_runner *runner = d3d11_shader_runner(r); ID3D11Device *device = runner->device; struct d3d11_resource *resource; - HRESULT hr;
resource = calloc(1, sizeof(*resource)); init_resource(&resource->r, params); @@ -375,77 +450,15 @@ static struct resource *d3d11_runner_create_resource(struct shader_runner *r, co { case RESOURCE_TYPE_RENDER_TARGET: case RESOURCE_TYPE_TEXTURE: - case RESOURCE_TYPE_UAV: - { - D3D11_SUBRESOURCE_DATA resource_data[2]; - D3D11_TEXTURE2D_DESC desc = {0}; - - if (params->level_count > ARRAY_SIZE(resource_data)) - fatal_error("Level count %u is too high.\n", params->level_count); - - desc.Width = params->width; - desc.Height = params->height; - desc.MipLevels = params->level_count; - desc.ArraySize = 1; - desc.Format = params->format; - desc.SampleDesc.Count = 1; - 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; - - if (params->data) - { - unsigned int buffer_offset = 0; - - for (unsigned int level = 0; level < params->level_count; ++level) - { - unsigned int level_width = get_level_dimension(params->width, level); - unsigned int level_height = get_level_dimension(params->height, level); - - resource_data[level].pSysMem = ¶ms->data[buffer_offset]; - resource_data[level].SysMemPitch = level_width * params->texel_size; - resource_data[level].SysMemSlicePitch = level_height * resource_data[level].SysMemPitch; - buffer_offset += resource_data[level].SysMemSlicePitch; - } - 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); + init_resource_2d(runner, resource, params); break; - } - - case RESOURCE_TYPE_BUFFER_UAV: - { - D3D11_UNORDERED_ACCESS_VIEW_DESC uav_desc; - - resource->buffer = create_buffer(device, D3D11_BIND_UNORDERED_ACCESS, params->data_size, params->data); - resource->resource = (ID3D11Resource *)resource->buffer;
- uav_desc.Format = params->format; - uav_desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER; - uav_desc.Buffer.FirstElement = 0; - uav_desc.Buffer.NumElements = params->data_size / params->texel_size; - uav_desc.Buffer.Flags = 0; - hr = ID3D11Device_CreateUnorderedAccessView(device, resource->resource, &uav_desc, &resource->uav); - ok(hr == S_OK, "Failed to create view, hr %#lx.\n", hr); + case RESOURCE_TYPE_UAV: + if (params->dimension == RESOURCE_DIMENSION_BUFFER) + init_resource_uav_buffer(runner, resource, params); + else + init_resource_2d(runner, resource, params); break; - }
case RESOURCE_TYPE_VERTEX_BUFFER: resource->buffer = create_buffer(device, D3D11_BIND_VERTEX_BUFFER, params->data_size, params->data); @@ -528,7 +541,6 @@ static bool d3d11_runner_dispatch(struct shader_runner *r, unsigned int x, unsig break;
case RESOURCE_TYPE_UAV: - case RESOURCE_TYPE_BUFFER_UAV: ID3D11DeviceContext_CSSetUnorderedAccessViews(context, resource->r.slot, 1, &resource->uav, NULL); break;
@@ -615,7 +627,6 @@ static bool d3d11_runner_draw(struct shader_runner *r, break;
case RESOURCE_TYPE_UAV: - case RESOURCE_TYPE_BUFFER_UAV: uavs[resource->r.slot] = resource->uav; min_uav_slot = min(min_uav_slot, resource->r.slot); break; @@ -699,25 +710,28 @@ static struct resource_readback *d3d11_runner_get_resource_readback(struct shade
switch (resource->r.type) { - case RESOURCE_TYPE_BUFFER_UAV: - ID3D11Buffer_GetDesc(resource->buffer, &buffer_desc); - buffer_desc.Usage = D3D11_USAGE_STAGING; - buffer_desc.BindFlags = 0; - buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - buffer_desc.MiscFlags = 0; - hr = ID3D11Device_CreateBuffer(runner->device, &buffer_desc, NULL, (ID3D11Buffer **)&rb->resource); - ok(hr == S_OK, "Failed to create buffer, hr %#lx.\n", hr); - break; - case RESOURCE_TYPE_RENDER_TARGET: case RESOURCE_TYPE_UAV: - ID3D11Texture2D_GetDesc(resource->texture, &texture_desc); - texture_desc.Usage = D3D11_USAGE_STAGING; - texture_desc.BindFlags = 0; - texture_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - texture_desc.MiscFlags = 0; - hr = ID3D11Device_CreateTexture2D(runner->device, &texture_desc, NULL, (ID3D11Texture2D **)&rb->resource); - ok(hr == S_OK, "Failed to create texture, hr %#lx.\n", hr); + if (resource->r.dimension == RESOURCE_DIMENSION_BUFFER) + { + ID3D11Buffer_GetDesc(resource->buffer, &buffer_desc); + buffer_desc.Usage = D3D11_USAGE_STAGING; + buffer_desc.BindFlags = 0; + buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + buffer_desc.MiscFlags = 0; + hr = ID3D11Device_CreateBuffer(runner->device, &buffer_desc, NULL, (ID3D11Buffer **)&rb->resource); + ok(hr == S_OK, "Failed to create buffer, hr %#lx.\n", hr); + } + else + { + ID3D11Texture2D_GetDesc(resource->texture, &texture_desc); + texture_desc.Usage = D3D11_USAGE_STAGING; + texture_desc.BindFlags = 0; + texture_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + texture_desc.MiscFlags = 0; + hr = ID3D11Device_CreateTexture2D(runner->device, &texture_desc, NULL, (ID3D11Texture2D **)&rb->resource); + ok(hr == S_OK, "Failed to create texture, hr %#lx.\n", hr); + } break;
case RESOURCE_TYPE_VERTEX_BUFFER: diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index 16cfec1ba..b320c07fd 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -185,39 +185,37 @@ static struct resource *d3d12_runner_create_resource(struct shader_runner *r, co runner->heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, MAX_RESOURCE_DESCRIPTORS);
- resource->resource = create_default_texture2d(device, params->width, params->height, 1, params->level_count, - params->format, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST); - upload_texture_data_with_states(resource->resource, resource_data, - params->level_count, test_context->queue, test_context->list, - RESOURCE_STATE_DO_NOT_CHANGE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); - reset_command_list(test_context->list, test_context->allocator); - ID3D12Device_CreateUnorderedAccessView(device, resource->resource, - NULL, NULL, get_cpu_descriptor_handle(test_context, runner->heap, resource->r.slot + MAX_RESOURCES)); + if (params->dimension == RESOURCE_DIMENSION_BUFFER) + { + D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc = { 0 }; + + resource->resource = create_default_buffer(device, params->data_size, + D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST); + upload_buffer_data_with_states(resource->resource, 0, params->data_size, resource_data[0].pData, + test_context->queue, test_context->list, + RESOURCE_STATE_DO_NOT_CHANGE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + reset_command_list(test_context->list, test_context->allocator); + + uav_desc.Format = params->format; + uav_desc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER; + uav_desc.Buffer.NumElements = params->width * params->height; + + ID3D12Device_CreateUnorderedAccessView(device, resource->resource, + NULL, &uav_desc, get_cpu_descriptor_handle(test_context, runner->heap, resource->r.slot + MAX_RESOURCES)); + } + else + { + resource->resource = create_default_texture2d(device, params->width, params->height, 1, params->level_count, + params->format, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST); + upload_texture_data_with_states(resource->resource, resource_data, + params->level_count, test_context->queue, test_context->list, + RESOURCE_STATE_DO_NOT_CHANGE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + reset_command_list(test_context->list, test_context->allocator); + ID3D12Device_CreateUnorderedAccessView(device, resource->resource, + NULL, NULL, get_cpu_descriptor_handle(test_context, runner->heap, resource->r.slot + MAX_RESOURCES)); + } break;
- case RESOURCE_TYPE_BUFFER_UAV: - { - D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc = { 0 }; - - if (!runner->heap) - runner->heap = create_gpu_descriptor_heap(device, - D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, MAX_RESOURCE_DESCRIPTORS); - - resource->resource = create_default_buffer(device, params->data_size, - D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST); - upload_buffer_data_with_states(resource->resource, 0, params->data_size, resource_data[0].pData, - test_context->queue, test_context->list, - RESOURCE_STATE_DO_NOT_CHANGE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); - reset_command_list(test_context->list, test_context->allocator); - - uav_desc.Format = params->format; - uav_desc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER; - uav_desc.Buffer.NumElements = params->width * params->height; - - ID3D12Device_CreateUnorderedAccessView(device, resource->resource, - NULL, &uav_desc, get_cpu_descriptor_handle(test_context, runner->heap, resource->r.slot + MAX_RESOURCES)); - break; - } case RESOURCE_TYPE_VERTEX_BUFFER: resource->resource = create_upload_buffer(device, params->data_size, params->data); break; @@ -273,7 +271,6 @@ static ID3D12RootSignature *d3d12_runner_create_root_signature(struct d3d12_shad { case RESOURCE_TYPE_TEXTURE: case RESOURCE_TYPE_UAV: - case RESOURCE_TYPE_BUFFER_UAV: range = &resource->descriptor_range;
if (base_resource && resource->r.type == base_resource->r.type && resource->r.slot == slot + 1) @@ -291,7 +288,7 @@ static ID3D12RootSignature *d3d12_runner_create_root_signature(struct d3d12_shad root_param->DescriptorTable.pDescriptorRanges = range; root_param->ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
- if (resource->r.type == RESOURCE_TYPE_UAV || resource->r.type == RESOURCE_TYPE_BUFFER_UAV) + if (resource->r.type == RESOURCE_TYPE_UAV) range->RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; else range->RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; @@ -395,7 +392,6 @@ static bool d3d12_runner_dispatch(struct shader_runner *r, unsigned int x, unsig break;
case RESOURCE_TYPE_UAV: - case RESOURCE_TYPE_BUFFER_UAV: if (resource->descriptor_range.NumDescriptors) ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, resource->root_index, get_gpu_descriptor_handle(test_context, runner->heap, resource->r.slot + MAX_RESOURCES)); @@ -538,7 +534,6 @@ static bool d3d12_runner_draw(struct shader_runner *r, break;
case RESOURCE_TYPE_UAV: - case RESOURCE_TYPE_BUFFER_UAV: if (resource->descriptor_range.NumDescriptors) ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, resource->root_index, get_gpu_descriptor_handle(test_context, runner->heap, resource->r.slot + MAX_RESOURCES)); diff --git a/tests/shader_runner_d3d9.c b/tests/shader_runner_d3d9.c index 3440e89c3..113073cdc 100644 --- a/tests/shader_runner_d3d9.c +++ b/tests/shader_runner_d3d9.c @@ -264,7 +264,6 @@ static struct resource *d3d9_runner_create_resource(struct shader_runner *r, con }
case RESOURCE_TYPE_UAV: - case RESOURCE_TYPE_BUFFER_UAV: fatal_error("UAVs are not supported.\n"); break;
@@ -390,7 +389,6 @@ static bool d3d9_runner_draw(struct shader_runner *r, break;
case RESOURCE_TYPE_UAV: - case RESOURCE_TYPE_BUFFER_UAV: vkd3d_unreachable();
case RESOURCE_TYPE_VERTEX_BUFFER: diff --git a/tests/shader_runner_gl.c b/tests/shader_runner_gl.c index a898d021b..98bc699fa 100644 --- a/tests/shader_runner_gl.c +++ b/tests/shader_runner_gl.c @@ -299,10 +299,46 @@ static const struct format_info *get_format_info(enum DXGI_FORMAT format) fatal_error("Failed to find format info for format %#x.\n", format); }
+static void init_resource_2d(struct gl_resource *resource, const struct resource_params *params) +{ + unsigned int offset, w, h, i; + + resource->format = get_format_info(params->format); + glGenTextures(1, &resource->id); + glBindTexture(GL_TEXTURE_2D, resource->id); + glTexStorage2D(GL_TEXTURE_2D, params->level_count, + resource->format->internal_format, params->width, params->height); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); + if (!params->data) + return; + + for (i = 0, offset = 0; i < params->level_count; ++i) + { + w = get_level_dimension(params->width, i); + h = get_level_dimension(params->height, i); + glTexSubImage2D(GL_TEXTURE_2D, i, 0, 0, w, h, resource->format->format, + resource->format->type, params->data + offset); + offset += w * h * params->texel_size; + } +} + +static void init_resource_buffer(struct gl_resource *resource, const struct resource_params *params) +{ + resource->format = get_format_info(params->format); + + glGenBuffers(1, &resource->id); + glBindBuffer(GL_TEXTURE_BUFFER, resource->id); + glBufferData(GL_TEXTURE_BUFFER, params->data_size, params->data, GL_STATIC_DRAW); + + glGenTextures(1, &resource->tbo_id); + glBindTexture(GL_TEXTURE_BUFFER, resource->tbo_id); + glTexBuffer(GL_TEXTURE_BUFFER, resource->format->internal_format, resource->id); +} + static struct resource *gl_runner_create_resource(struct shader_runner *r, const struct resource_params *params) { struct gl_resource *resource; - unsigned int offset, w, h, i;
resource = calloc(1, sizeof(*resource)); init_resource(&resource->r, params); @@ -311,37 +347,14 @@ static struct resource *gl_runner_create_resource(struct shader_runner *r, const { case RESOURCE_TYPE_RENDER_TARGET: case RESOURCE_TYPE_TEXTURE: - case RESOURCE_TYPE_UAV: - resource->format = get_format_info(params->format); - glGenTextures(1, &resource->id); - glBindTexture(GL_TEXTURE_2D, resource->id); - glTexStorage2D(GL_TEXTURE_2D, params->level_count, - resource->format->internal_format, params->width, params->height); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); - if (!params->data) - break; - - for (i = 0, offset = 0; i < params->level_count; ++i) - { - w = get_level_dimension(params->width, i); - h = get_level_dimension(params->height, i); - glTexSubImage2D(GL_TEXTURE_2D, i, 0, 0, w, h, resource->format->format, - resource->format->type, params->data + offset); - offset += w * h * params->texel_size; - } + init_resource_2d(resource, params); break;
- case RESOURCE_TYPE_BUFFER_UAV: - resource->format = get_format_info(params->format); - - glGenBuffers(1, &resource->id); - glBindBuffer(GL_TEXTURE_BUFFER, resource->id); - glBufferData(GL_TEXTURE_BUFFER, params->data_size, params->data, GL_STATIC_DRAW); - - glGenTextures(1, &resource->tbo_id); - glBindTexture(GL_TEXTURE_BUFFER, resource->tbo_id); - glTexBuffer(GL_TEXTURE_BUFFER, resource->format->internal_format, resource->id); + case RESOURCE_TYPE_UAV: + if (params->dimension == RESOURCE_DIMENSION_BUFFER) + init_resource_buffer(resource, params); + else + init_resource_2d(resource, params); break;
case RESOURCE_TYPE_VERTEX_BUFFER: @@ -362,13 +375,21 @@ static void gl_runner_destroy_resource(struct shader_runner *r, struct resource { case RESOURCE_TYPE_RENDER_TARGET: case RESOURCE_TYPE_TEXTURE: - case RESOURCE_TYPE_UAV: glDeleteTextures(1, &resource->id); break;
- case RESOURCE_TYPE_BUFFER_UAV: - glDeleteTextures(1, &resource->tbo_id); - /* Fall-through. */ + case RESOURCE_TYPE_UAV: + if (res->dimension == RESOURCE_DIMENSION_BUFFER) + { + glDeleteTextures(1, &resource->tbo_id); + glDeleteBuffers(1, &resource->id); + } + else + { + glDeleteTextures(1, &resource->id); + } + break; + case RESOURCE_TYPE_VERTEX_BUFFER: glDeleteBuffers(1, &resource->id); break; @@ -486,13 +507,12 @@ static bool compile_shader(struct gl_runner *runner, ID3DBlob *blob, struct vkd3 switch (resource->r.type) { case RESOURCE_TYPE_UAV: - case RESOURCE_TYPE_BUFFER_UAV: binding = &bindings[interface_info.binding_count++]; binding->type = VKD3D_SHADER_DESCRIPTOR_TYPE_UAV; binding->register_space = 0; binding->register_index = resource->r.slot; binding->shader_visibility = VKD3D_SHADER_VISIBILITY_ALL; - if (resource->r.type == RESOURCE_TYPE_BUFFER_UAV) + if (resource->r.dimension == RESOURCE_DIMENSION_BUFFER) binding->flags = VKD3D_SHADER_BINDING_FLAG_BUFFER; else binding->flags = VKD3D_SHADER_BINDING_FLAG_IMAGE; @@ -621,16 +641,13 @@ static bool gl_runner_dispatch(struct shader_runner *r, unsigned int x, unsigned { case RESOURCE_TYPE_RENDER_TARGET: case RESOURCE_TYPE_VERTEX_BUFFER: - break; - case RESOURCE_TYPE_TEXTURE: - case RESOURCE_TYPE_BUFFER_UAV: - trace("RESOURCE TYPE %#x.\n", resource->r.type); break;
case RESOURCE_TYPE_UAV: - glBindImageTexture(resource->r.slot, resource->id, 0, GL_TRUE, - 0, GL_READ_WRITE, resource->format->internal_format); + if (resource->r.dimension != RESOURCE_DIMENSION_BUFFER) + glBindImageTexture(resource->r.slot, resource->id, 0, GL_TRUE, + 0, GL_READ_WRITE, resource->format->internal_format); break; } } @@ -857,13 +874,16 @@ static bool gl_runner_draw(struct shader_runner *r, break;
case RESOURCE_TYPE_UAV: - glBindImageTexture(resource->r.slot, resource->id, 0, GL_TRUE, - 0, GL_READ_WRITE, resource->format->internal_format); - break; - - case RESOURCE_TYPE_BUFFER_UAV: - glBindImageTexture(resource->r.slot, resource->tbo_id, 0, GL_TRUE, - 0, GL_READ_WRITE, resource->format->internal_format); + if (resource->r.dimension == RESOURCE_DIMENSION_BUFFER) + { + glBindImageTexture(resource->r.slot, resource->tbo_id, 0, GL_TRUE, + 0, GL_READ_WRITE, resource->format->internal_format); + } + else + { + glBindImageTexture(resource->r.slot, resource->id, 0, GL_TRUE, + 0, GL_READ_WRITE, resource->format->internal_format); + } break;
case RESOURCE_TYPE_VERTEX_BUFFER: @@ -944,8 +964,7 @@ static struct resource_readback *gl_runner_get_resource_readback(struct shader_r struct gl_resource *resource = gl_resource(res); struct resource_readback *rb;
- if (resource->r.type != RESOURCE_TYPE_RENDER_TARGET && resource->r.type != RESOURCE_TYPE_UAV - && resource->r.type != RESOURCE_TYPE_BUFFER_UAV) + if (resource->r.type != RESOURCE_TYPE_RENDER_TARGET && resource->r.type != RESOURCE_TYPE_UAV) fatal_error("Unhandled resource type %#x.\n", resource->r.type);
rb = malloc(sizeof(*rb)); @@ -957,7 +976,7 @@ static struct resource_readback *gl_runner_get_resource_readback(struct shader_r rb->row_pitch = rb->width * resource->r.texel_size; rb->data = malloc(rb->row_pitch * rb->height);
- if (resource->r.type == RESOURCE_TYPE_BUFFER_UAV) + if (resource->r.dimension == RESOURCE_DIMENSION_BUFFER) { glBindBuffer(GL_TEXTURE_BUFFER, resource->id); glGetBufferSubData(GL_TEXTURE_BUFFER, 0, rb->row_pitch * rb->height, rb->data); diff --git a/tests/shader_runner_vulkan.c b/tests/shader_runner_vulkan.c index 0aa611071..73b0149e4 100644 --- a/tests/shader_runner_vulkan.c +++ b/tests/shader_runner_vulkan.c @@ -262,14 +262,87 @@ static VkImageView create_2d_image_view(const struct vulkan_shader_runner *runne return view; }
+static void resource_init_2d(struct vulkan_shader_runner *runner, struct vulkan_resource *resource, + const struct resource_params *params) +{ + VkImageUsageFlagBits usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; + VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + VkFormat format = vkd3d_get_vk_format(params->format); + VkDevice device = runner->device; + unsigned int buffer_offset = 0; + VkDeviceMemory staging_memory; + VkBuffer staging_buffer; + void *data; + + 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, params->level_count, + usage, format, &resource->memory); + resource->image_view = create_2d_image_view(runner, resource->image, format); + + staging_buffer = create_buffer(runner, params->data_size, + VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &staging_memory); + VK_CALL(vkMapMemory(device, staging_memory, 0, VK_WHOLE_SIZE, 0, &data)); + memcpy(data, params->data, params->data_size); + VK_CALL(vkUnmapMemory(device, staging_memory)); + + begin_command_buffer(runner); + + transition_image_layout(runner, resource->image, + VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + + for (unsigned int level = 0; level < params->level_count; ++level) + { + unsigned int level_width = get_level_dimension(params->width, level); + unsigned int level_height = get_level_dimension(params->height, level); + VkBufferImageCopy region = {0}; + + region.bufferOffset = buffer_offset; + region.imageSubresource.mipLevel = level; + region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + region.imageSubresource.layerCount = 1; + region.imageExtent.width = level_width; + region.imageExtent.height = level_height; + region.imageExtent.depth = 1; + VK_CALL(vkCmdCopyBufferToImage(runner->cmd_buffer, staging_buffer, resource->image, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion)); + + buffer_offset += level_width * level_height * params->texel_size; + } + + 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)); +} + +static void resource_init_buffer(struct vulkan_shader_runner *runner, struct vulkan_resource *resource, + const struct resource_params *params) +{ + VkFormat format = vkd3d_get_vk_format(params->format); + VkDevice device = runner->device; + void *data; + + resource->buffer = create_buffer(runner, params->data_size, VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &resource->memory); + resource->buffer_view = create_buffer_view(runner, resource->buffer, format); + + VK_CALL(vkMapMemory(device, resource->memory, 0, VK_WHOLE_SIZE, 0, &data)); + memcpy(data, params->data, params->data_size); + VK_CALL(vkUnmapMemory(device, resource->memory)); +} + static struct resource *vulkan_runner_create_resource(struct shader_runner *r, const struct resource_params *params) { struct vulkan_shader_runner *runner = vulkan_shader_runner(r); - struct vulkan_resource *resource; VkDevice device = runner->device; - VkDeviceMemory staging_memory; - VkBuffer staging_buffer; VkFormat format; void *data;
@@ -292,73 +365,14 @@ static struct resource *vulkan_runner_create_resource(struct shader_runner *r, c break;
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; - unsigned int buffer_offset = 0; - - format = vkd3d_get_vk_format(params->format); - - 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, params->level_count, - usage, format, &resource->memory); - resource->image_view = create_2d_image_view(runner, resource->image, format); - - staging_buffer = create_buffer(runner, params->data_size, - VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &staging_memory); - VK_CALL(vkMapMemory(device, staging_memory, 0, VK_WHOLE_SIZE, 0, &data)); - memcpy(data, params->data, params->data_size); - VK_CALL(vkUnmapMemory(device, staging_memory)); - - begin_command_buffer(runner); - - transition_image_layout(runner, resource->image, - VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); - - for (unsigned int level = 0; level < params->level_count; ++level) - { - unsigned int level_width = get_level_dimension(params->width, level); - unsigned int level_height = get_level_dimension(params->height, level); - VkBufferImageCopy region = {0}; - - region.bufferOffset = buffer_offset; - region.imageSubresource.mipLevel = level; - region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - region.imageSubresource.layerCount = 1; - region.imageExtent.width = level_width; - region.imageExtent.height = level_height; - region.imageExtent.depth = 1; - VK_CALL(vkCmdCopyBufferToImage(runner->cmd_buffer, staging_buffer, resource->image, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion)); - - buffer_offset += level_width * level_height * params->texel_size; - } - - 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)); + resource_init_2d(runner, resource, params); break; - } - - case RESOURCE_TYPE_BUFFER_UAV: - format = vkd3d_get_vk_format(params->format);
- resource->buffer = create_buffer(runner, params->data_size, VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &resource->memory); - resource->buffer_view = create_buffer_view(runner, resource->buffer, format); - - VK_CALL(vkMapMemory(device, resource->memory, 0, VK_WHOLE_SIZE, 0, &data)); - memcpy(data, params->data, params->data_size); - VK_CALL(vkUnmapMemory(device, resource->memory)); + case RESOURCE_TYPE_UAV: + if (params->dimension == RESOURCE_DIMENSION_BUFFER) + resource_init_buffer(runner, resource, params); + else + resource_init_2d(runner, resource, params); break;
case RESOURCE_TYPE_VERTEX_BUFFER: @@ -499,16 +513,15 @@ static bool compile_shader(struct vulkan_shader_runner *runner, const char *sour
case RESOURCE_TYPE_TEXTURE: case RESOURCE_TYPE_UAV: - case RESOURCE_TYPE_BUFFER_UAV: binding = &bindings[interface_info.binding_count++]; - if (resource->r.type == RESOURCE_TYPE_UAV || resource->r.type == RESOURCE_TYPE_BUFFER_UAV) + 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; - if (resource->r.type == RESOURCE_TYPE_BUFFER_UAV) + if (resource->r.dimension == RESOURCE_DIMENSION_BUFFER) binding->flags = VKD3D_SHADER_BINDING_FLAG_BUFFER; else binding->flags = VKD3D_SHADER_BINDING_FLAG_IMAGE; @@ -691,7 +704,6 @@ static VkPipeline create_graphics_pipeline(struct vulkan_shader_runner *runner, { case RESOURCE_TYPE_TEXTURE: case RESOURCE_TYPE_UAV: - case RESOURCE_TYPE_BUFFER_UAV: break;
case RESOURCE_TYPE_RENDER_TARGET: @@ -822,18 +834,22 @@ static VkDescriptorSetLayout create_descriptor_set_layout(struct vulkan_shader_r
case RESOURCE_TYPE_TEXTURE: case RESOURCE_TYPE_UAV: - case RESOURCE_TYPE_BUFFER_UAV: binding = &bindings[set_desc.bindingCount++];
resource->binding = binding_index++;
binding->binding = resource->binding; if (resource->r.type == RESOURCE_TYPE_UAV) - binding->descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; - else if (resource->r.type == RESOURCE_TYPE_BUFFER_UAV) - binding->descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; + { + if (resource->r.dimension == RESOURCE_DIMENSION_BUFFER) + binding->descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; + else + 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; @@ -897,34 +913,38 @@ static void bind_resources(struct vulkan_shader_runner *runner, VkPipelineBindPo { case RESOURCE_TYPE_TEXTURE: case RESOURCE_TYPE_UAV: - image_info.imageView = resource->image_view; - image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - - write.dstSet = descriptor_set; - write.dstBinding = resource->binding; - write.dstArrayElement = 0; - write.descriptorCount = 1; - write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; - write.pImageInfo = &image_info; - - if (resource->r.type == RESOURCE_TYPE_UAV) + if (resource->r.dimension == RESOURCE_DIMENSION_BUFFER) { - image_info.imageLayout = VK_IMAGE_LAYOUT_GENERAL; - write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + assert(resource->r.type == RESOURCE_TYPE_UAV); + write.dstSet = descriptor_set; + write.dstBinding = resource->binding; + write.dstArrayElement = 0; + write.descriptorCount = 1; + write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; + write.pTexelBufferView = &resource->buffer_view; + + VK_CALL(vkUpdateDescriptorSets(runner->device, 1, &write, 0, NULL)); } + else + { + image_info.imageView = resource->image_view; + image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
- VK_CALL(vkUpdateDescriptorSets(runner->device, 1, &write, 0, NULL)); - break; + write.dstSet = descriptor_set; + write.dstBinding = resource->binding; + write.dstArrayElement = 0; + write.descriptorCount = 1; + write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + write.pImageInfo = &image_info;
- case RESOURCE_TYPE_BUFFER_UAV: - write.dstSet = descriptor_set; - write.dstBinding = resource->binding; - write.dstArrayElement = 0; - write.descriptorCount = 1; - write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; - write.pTexelBufferView = &resource->buffer_view; + 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)); + VK_CALL(vkUpdateDescriptorSets(runner->device, 1, &write, 0, NULL)); + } break;
case RESOURCE_TYPE_VERTEX_BUFFER: @@ -1132,7 +1152,7 @@ static struct resource_readback *vulkan_runner_get_resource_readback(struct shad 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);
- if (resource->r.type == RESOURCE_TYPE_BUFFER_UAV) + if (resource->r.type == RESOURCE_TYPE_UAV && resource->r.dimension == RESOURCE_DIMENSION_BUFFER) { void *data;