diff --git a/tests/shader_runner.c b/tests/shader_runner.c index 12aba75ed..1e2cda160 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -581,24 +581,20 @@ static void parse_resource_directive(struct resource_params *resource, const cha } else if (match_string(line, "size", &line)) { + resource->desc.height = resource->desc.depth = resource->desc.layer_count = 1; + if (sscanf(line, "( buffer , %u ) ", &resource->desc.width) == 1) { resource->desc.dimension = RESOURCE_DIMENSION_BUFFER; - resource->desc.height = 1; - resource->desc.depth = 1; } else if (sscanf(line, "( raw_buffer , %u ) ", &resource->desc.width) == 1) { resource->desc.dimension = RESOURCE_DIMENSION_BUFFER; - resource->desc.height = 1; - resource->desc.depth = 1; resource->is_raw = true; } else if (sscanf(line, "( counter_buffer , %u ) ", &resource->desc.width) == 1) { resource->desc.dimension = RESOURCE_DIMENSION_BUFFER; - resource->desc.height = 1; - resource->desc.depth = 1; resource->is_uav_counter = true; resource->stride = sizeof(uint32_t); resource->desc.texel_size = resource->stride; @@ -609,19 +605,22 @@ static void parse_resource_directive(struct resource_params *resource, const cha else if (sscanf(line, "( 2d , %u , %u ) ", &resource->desc.width, &resource->desc.height) == 2) { resource->desc.dimension = RESOURCE_DIMENSION_2D; - resource->desc.depth = 1; } else if (sscanf(line, "( 2dms , %u , %u , %u ) ", &resource->desc.sample_count, &resource->desc.width, &resource->desc.height) == 3) { resource->desc.dimension = RESOURCE_DIMENSION_2D; - resource->desc.depth = 1; } else if (sscanf(line, "( 2darray , %u , %u , %u ) ", &resource->desc.width, &resource->desc.height, - &resource->desc.depth) == 3) + &resource->desc.layer_count) == 3) { resource->desc.dimension = RESOURCE_DIMENSION_2D; } + else if (sscanf(line, "( 3d , %u , %u , %u ) ", &resource->desc.width, &resource->desc.height, + &resource->desc.depth) == 3) + { + resource->desc.dimension = RESOURCE_DIMENSION_3D; + } else { fatal_error("Malformed resource size '%s'.\n", line); @@ -653,7 +652,7 @@ static void parse_resource_directive(struct resource_params *resource, const cha if (rest == line) break; - if (resource->desc.depth > 1) + if (resource->desc.layer_count > 1) fatal_error("Upload not implemented for 2d arrays.\n"); vkd3d_array_reserve((void **)&resource->data, &resource->data_capacity, resource->data_size + sizeof(u), 1); @@ -768,6 +767,7 @@ static void set_default_target(struct shader_runner *runner) params.desc.width = RENDER_TARGET_WIDTH; params.desc.height = RENDER_TARGET_HEIGHT; params.desc.depth = 1; + params.desc.layer_count = 1; params.desc.level_count = 1; set_resource(runner, ¶ms); diff --git a/tests/shader_runner.h b/tests/shader_runner.h index ec6190721..da1442a74 100644 --- a/tests/shader_runner.h +++ b/tests/shader_runner.h @@ -85,6 +85,7 @@ enum resource_dimension { RESOURCE_DIMENSION_BUFFER, RESOURCE_DIMENSION_2D, + RESOURCE_DIMENSION_3D, }; struct resource_desc @@ -96,7 +97,7 @@ struct resource_desc DXGI_FORMAT format; unsigned int texel_size; unsigned int width, height, depth; - unsigned int level_count; + unsigned int layer_count, level_count; unsigned int sample_count; }; diff --git a/tests/shader_runner_d3d11.c b/tests/shader_runner_d3d11.c index 1bcfde1aa..bb457cfde 100644 --- a/tests/shader_runner_d3d11.c +++ b/tests/shader_runner_d3d11.c @@ -46,6 +46,7 @@ struct d3d11_resource ID3D11Resource *resource; ID3D11Buffer *buffer; ID3D11Texture2D *texture; + ID3D11Texture3D *texture_3d; ID3D11RenderTargetView *rtv; ID3D11DepthStencilView *dsv; ID3D11ShaderResourceView *srv; @@ -394,6 +395,51 @@ static ID3D11Buffer *create_buffer(ID3D11Device *device, unsigned int bind_flags return buffer; } +static unsigned int get_bind_flags(const struct resource_params *params) +{ + if (params->desc.type == RESOURCE_TYPE_UAV) + return D3D11_BIND_UNORDERED_ACCESS; + else if (params->desc.type == RESOURCE_TYPE_RENDER_TARGET) + return D3D11_BIND_RENDER_TARGET; + else if (params->desc.type == RESOURCE_TYPE_DEPTH_STENCIL) + return D3D11_BIND_DEPTH_STENCIL; + else + return D3D11_BIND_SHADER_RESOURCE; +} + +static void init_subresource_data(D3D11_SUBRESOURCE_DATA *resource_data, const struct resource_params *params) +{ + unsigned int buffer_offset = 0; + + for (unsigned int level = 0; level < params->desc.level_count; ++level) + { + unsigned int level_width = get_level_dimension(params->desc.width, level); + unsigned int level_height = get_level_dimension(params->desc.height, level); + unsigned int level_depth = get_level_dimension(params->desc.depth, level); + + resource_data[level].pSysMem = ¶ms->data[buffer_offset]; + resource_data[level].SysMemPitch = level_width * params->desc.texel_size; + resource_data[level].SysMemSlicePitch = level_height * resource_data[level].SysMemPitch; + buffer_offset += level_depth * resource_data[level].SysMemSlicePitch; + } +} + +static void create_identity_view(ID3D11Device *device, + struct d3d11_resource *resource, const struct resource_params *params) +{ + HRESULT hr; + + if (params->desc.type == RESOURCE_TYPE_UAV) + hr = ID3D11Device_CreateUnorderedAccessView(device, resource->resource, NULL, &resource->uav); + else if (params->desc.type == RESOURCE_TYPE_RENDER_TARGET) + hr = ID3D11Device_CreateRenderTargetView(device, resource->resource, NULL, &resource->rtv); + else if (params->desc.type == RESOURCE_TYPE_DEPTH_STENCIL) + hr = ID3D11Device_CreateDepthStencilView(device, resource->resource, NULL, &resource->dsv); + else + hr = ID3D11Device_CreateShaderResourceView(device, resource->resource, NULL, &resource->srv); + ok(hr == S_OK, "Failed to create view, hr %#lx.\n", hr); +} + static bool init_resource_2d(struct d3d11_shader_runner *runner, struct d3d11_resource *resource, const struct resource_params *params) { @@ -423,36 +469,18 @@ static bool init_resource_2d(struct d3d11_shader_runner *runner, struct d3d11_re desc.Width = params->desc.width; desc.Height = params->desc.height; desc.MipLevels = params->desc.level_count; - desc.ArraySize = params->desc.depth; + desc.ArraySize = params->desc.layer_count; desc.Format = params->desc.format; desc.SampleDesc.Count = max(params->desc.sample_count, 1); desc.Usage = D3D11_USAGE_DEFAULT; - if (params->desc.type == RESOURCE_TYPE_UAV) - desc.BindFlags = D3D11_BIND_UNORDERED_ACCESS; - else if (params->desc.type == RESOURCE_TYPE_RENDER_TARGET) - desc.BindFlags = D3D11_BIND_RENDER_TARGET; - else if (params->desc.type == RESOURCE_TYPE_DEPTH_STENCIL) - desc.BindFlags = D3D11_BIND_DEPTH_STENCIL; - else - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + desc.BindFlags = get_bind_flags(params); if (params->data) { - unsigned int buffer_offset = 0; - if (params->desc.sample_count > 1) fatal_error("Cannot upload data to a multisampled texture.\n"); - for (unsigned int level = 0; level < params->desc.level_count; ++level) - { - unsigned int level_width = get_level_dimension(params->desc.width, level); - unsigned int level_height = get_level_dimension(params->desc.height, level); - - resource_data[level].pSysMem = ¶ms->data[buffer_offset]; - resource_data[level].SysMemPitch = level_width * params->desc.texel_size; - resource_data[level].SysMemSlicePitch = level_height * resource_data[level].SysMemPitch; - buffer_offset += resource_data[level].SysMemSlicePitch; - } + init_subresource_data(resource_data, params); hr = ID3D11Device_CreateTexture2D(device, &desc, resource_data, &resource->texture); } else @@ -462,16 +490,42 @@ static bool init_resource_2d(struct d3d11_shader_runner *runner, struct d3d11_re ok(hr == S_OK, "Failed to create texture, hr %#lx.\n", hr); resource->resource = (ID3D11Resource *)resource->texture; - if (params->desc.type == RESOURCE_TYPE_UAV) - hr = ID3D11Device_CreateUnorderedAccessView(device, resource->resource, NULL, &resource->uav); - else if (params->desc.type == RESOURCE_TYPE_RENDER_TARGET) - hr = ID3D11Device_CreateRenderTargetView(device, resource->resource, NULL, &resource->rtv); - else if (params->desc.type == RESOURCE_TYPE_DEPTH_STENCIL) - hr = ID3D11Device_CreateDepthStencilView(device, resource->resource, NULL, &resource->dsv); - else - hr = ID3D11Device_CreateShaderResourceView(device, resource->resource, NULL, &resource->srv); - ok(hr == S_OK, "Failed to create view, hr %#lx.\n", hr); + create_identity_view(device, resource, params); + return true; +} +static bool init_resource_3d(struct d3d11_shader_runner *runner, struct d3d11_resource *resource, + const struct resource_params *params) +{ + D3D11_SUBRESOURCE_DATA resource_data[3]; + ID3D11Device *device = runner->device; + D3D11_TEXTURE3D_DESC desc = {0}; + HRESULT hr; + + if (params->desc.level_count > ARRAY_SIZE(resource_data)) + fatal_error("Level count %u is too high.\n", params->desc.level_count); + + desc.Width = params->desc.width; + desc.Height = params->desc.height; + desc.Depth = params->desc.depth; + desc.MipLevels = params->desc.level_count; + desc.Format = params->desc.format; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = get_bind_flags(params); + + if (params->data) + { + init_subresource_data(resource_data, params); + hr = ID3D11Device_CreateTexture3D(device, &desc, resource_data, &resource->texture_3d); + } + else + { + hr = ID3D11Device_CreateTexture3D(device, &desc, NULL, &resource->texture_3d); + } + ok(hr == S_OK, "Failed to create texture, hr %#lx.\n", hr); + + resource->resource = (ID3D11Resource *)resource->texture_3d; + create_identity_view(device, resource, params); return true; } @@ -546,14 +600,18 @@ static struct resource *d3d11_runner_create_resource(struct shader_runner *r, co case RESOURCE_TYPE_TEXTURE: if (params->desc.dimension == RESOURCE_DIMENSION_BUFFER) init_resource_srv_buffer(runner, resource, params); - else if (!init_resource_2d(runner, resource, params)) + else if (params->desc.dimension == RESOURCE_DIMENSION_2D && !init_resource_2d(runner, resource, params)) + return NULL; + else if (params->desc.dimension == RESOURCE_DIMENSION_3D && !init_resource_3d(runner, resource, params)) return NULL; break; case RESOURCE_TYPE_UAV: if (params->desc.dimension == RESOURCE_DIMENSION_BUFFER) init_resource_uav_buffer(runner, resource, params); - else if (!init_resource_2d(runner, resource, params)) + else if (params->desc.dimension == RESOURCE_DIMENSION_2D && !init_resource_2d(runner, resource, params)) + return NULL; + else if (params->desc.dimension == RESOURCE_DIMENSION_3D && !init_resource_3d(runner, resource, params)) return NULL; break; @@ -945,7 +1003,6 @@ static struct resource_readback *d3d11_runner_get_resource_readback(struct shade struct d3d11_resource_readback *rb = malloc(sizeof(*rb)); ID3D11Resource *resolved_resource = NULL, *src_resource; struct d3d11_resource *resource = d3d11_resource(res); - D3D11_TEXTURE2D_DESC texture_desc; D3D11_MAPPED_SUBRESOURCE map_desc; D3D11_BUFFER_DESC buffer_desc; bool is_ms = false; @@ -967,8 +1024,10 @@ static struct resource_readback *d3d11_runner_get_resource_readback(struct shade hr = ID3D11Device_CreateBuffer(runner->device, &buffer_desc, NULL, (ID3D11Buffer **)&rb->resource); ok(hr == S_OK, "Failed to create buffer, hr %#lx.\n", hr); } - else + else if (resource->r.desc.dimension == RESOURCE_DIMENSION_2D) { + D3D11_TEXTURE2D_DESC texture_desc; + ID3D11Texture2D_GetDesc(resource->texture, &texture_desc); is_ms = texture_desc.SampleDesc.Count > 1; texture_desc.SampleDesc.Count = 1; @@ -991,6 +1050,19 @@ static struct resource_readback *d3d11_runner_get_resource_readback(struct shade src_resource = resolved_resource; } } + else if (resource->r.desc.dimension == RESOURCE_DIMENSION_3D) + { + D3D11_TEXTURE3D_DESC texture_desc; + + ID3D11Texture3D_GetDesc(resource->texture_3d, &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_CreateTexture3D(runner->device, &texture_desc, + NULL, (ID3D11Texture3D **)&rb->resource); + ok(hr == S_OK, "Failed to create texture, hr %#lx.\n", hr); + } break; case RESOURCE_TYPE_VERTEX_BUFFER: @@ -1013,7 +1085,7 @@ static struct resource_readback *d3d11_runner_get_resource_readback(struct shade rb->rb.row_pitch = map_desc.RowPitch; rb->rb.width = resource->r.desc.width; rb->rb.height = resource->r.desc.height; - rb->rb.depth = 1; + rb->rb.depth = resource->r.desc.depth; rb->sub_resource_idx = sub_resource_idx; return &rb->rb; diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index a31a47800..599d2012a 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -98,11 +98,12 @@ static struct resource *d3d12_runner_create_resource(struct shader_runner *r, co { unsigned int level_width = get_level_dimension(params->desc.width, level); unsigned int level_height = get_level_dimension(params->desc.height, level); + unsigned int level_depth = get_level_dimension(params->desc.depth, level); resource_data[level].pData = ¶ms->data[buffer_offset]; resource_data[level].RowPitch = level_width * params->desc.texel_size; resource_data[level].SlicePitch = level_height * resource_data[level].RowPitch; - buffer_offset += resource_data[level].SlicePitch; + buffer_offset += level_depth * resource_data[level].SlicePitch; } state = resource_get_state(&resource->r); @@ -122,7 +123,7 @@ static struct resource *d3d12_runner_create_resource(struct shader_runner *r, co resource->resource = create_default_texture_(__FILE__, __LINE__, device, D3D12_RESOURCE_DIMENSION_TEXTURE2D, params->desc.width, params->desc.height, - params->desc.depth, params->desc.level_count, params->desc.sample_count, + params->desc.layer_count, params->desc.level_count, params->desc.sample_count, params->desc.format, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET, initial_state); ID3D12Device_CreateRenderTargetView(device, resource->resource, NULL, get_cpu_rtv_handle(test_context, runner->rtv_heap, resource->r.desc.slot)); @@ -168,12 +169,26 @@ static struct resource *d3d12_runner_create_resource(struct shader_runner *r, co } else { + D3D12_RESOURCE_DIMENSION dimension; + unsigned int depth; + if (params->desc.sample_count > 1 && params->desc.level_count > 1) fatal_error("Multisampled texture has multiple levels.\n"); + if (params->desc.dimension == RESOURCE_DIMENSION_2D) + { + dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + depth = params->desc.layer_count; + } + else + { + dimension = D3D12_RESOURCE_DIMENSION_TEXTURE3D; + depth = params->desc.depth; + } + resource->resource = create_default_texture_(__FILE__, __LINE__, device, - D3D12_RESOURCE_DIMENSION_TEXTURE2D, params->desc.width, params->desc.height, - params->desc.depth, params->desc.level_count, params->desc.sample_count, params->desc.format, + dimension, params->desc.width, params->desc.height, depth, + params->desc.level_count, params->desc.sample_count, params->desc.format, /* Multisampled textures must have ALLOW_RENDER_TARGET set. */ (params->desc.sample_count > 1) ? D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET : 0, initial_state); if (params->data) @@ -220,9 +235,25 @@ static struct resource *d3d12_runner_create_resource(struct shader_runner *r, co } else { - resource->resource = create_default_texture2d(device, params->desc.width, - params->desc.height, params->desc.depth, params->desc.level_count, - params->desc.format, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, initial_state); + D3D12_RESOURCE_DIMENSION dimension; + unsigned int depth; + + if (params->desc.dimension == RESOURCE_DIMENSION_2D) + { + dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + depth = params->desc.layer_count; + } + else + { + dimension = D3D12_RESOURCE_DIMENSION_TEXTURE3D; + depth = params->desc.depth; + } + + resource->resource = create_default_texture_(__FILE__, __LINE__, device, + dimension, params->desc.width, params->desc.height, depth, + params->desc.level_count, 1, params->desc.format, + D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, initial_state); + if (params->data) { upload_texture_data_with_states(resource->resource, resource_data, params->desc.level_count, diff --git a/tests/shader_runner_d3d9.c b/tests/shader_runner_d3d9.c index 871f451a2..5445e960b 100644 --- a/tests/shader_runner_d3d9.c +++ b/tests/shader_runner_d3d9.c @@ -34,6 +34,7 @@ struct d3d9_resource IDirect3DSurface9 *surface; IDirect3DTexture9 *texture; IDirect3DVertexBuffer9 *vb; + IDirect3DVolumeTexture9 *volume; }; static struct d3d9_resource *d3d9_resource(struct resource *r) @@ -189,7 +190,6 @@ static struct resource *d3d9_runner_create_resource(struct shader_runner *r, con struct d3d9_shader_runner *runner = d3d9_shader_runner(r); IDirect3DDevice9 *device = runner->device; struct d3d9_resource *resource; - D3DLOCKED_RECT map_desc; D3DFORMAT format; HRESULT hr; void *data; @@ -226,36 +226,71 @@ static struct resource *d3d9_runner_create_resource(struct shader_runner *r, con case RESOURCE_TYPE_TEXTURE: { + unsigned int src_buffer_offset = 0; + if (params->desc.dimension == RESOURCE_DIMENSION_BUFFER) { fatal_error("Buffer resources are not supported.\n"); break; } - - unsigned int src_buffer_offset = 0; - - hr = IDirect3DDevice9_CreateTexture(device, params->desc.width, params->desc.height, - params->desc.level_count, 0, format, D3DPOOL_MANAGED, &resource->texture, NULL); - ok(hr == D3D_OK, "Failed to create texture, hr %#lx.\n", hr); - - for (unsigned int level = 0; level < params->desc.level_count; ++level) + else if (params->desc.dimension == RESOURCE_DIMENSION_2D) { - unsigned int level_width = get_level_dimension(params->desc.width, level); - unsigned int level_height = get_level_dimension(params->desc.height, level); - unsigned int src_row_pitch = level_width * params->desc.texel_size; - unsigned int src_slice_pitch = level_height * src_row_pitch; + hr = IDirect3DDevice9_CreateTexture(device, params->desc.width, params->desc.height, + params->desc.level_count, 0, format, D3DPOOL_MANAGED, &resource->texture, NULL); + ok(hr == D3D_OK, "Failed to create texture, hr %#lx.\n", hr); - hr = IDirect3DTexture9_LockRect(resource->texture, level, &map_desc, NULL, 0); - ok(hr == D3D_OK, "Failed to map texture, hr %#lx.\n", hr); - for (unsigned int y = 0; y < level_height; ++y) - memcpy(&((char *)map_desc.pBits)[y * map_desc.Pitch], - ¶ms->data[src_buffer_offset + y * src_row_pitch], src_row_pitch); - hr = IDirect3DTexture9_UnlockRect(resource->texture, level); - ok(hr == D3D_OK, "Failed to unmap texture, hr %#lx.\n", hr); + for (unsigned int level = 0; level < params->desc.level_count; ++level) + { + unsigned int level_width = get_level_dimension(params->desc.width, level); + unsigned int level_height = get_level_dimension(params->desc.height, level); + unsigned int src_row_pitch = level_width * params->desc.texel_size; + unsigned int src_slice_pitch = level_height * src_row_pitch; + D3DLOCKED_RECT map_desc; - src_buffer_offset += src_slice_pitch; + hr = IDirect3DTexture9_LockRect(resource->texture, level, &map_desc, NULL, 0); + ok(hr == D3D_OK, "Failed to map texture, hr %#lx.\n", hr); + for (unsigned int y = 0; y < level_height; ++y) + memcpy(&((uint8_t *)map_desc.pBits)[y * map_desc.Pitch], + ¶ms->data[src_buffer_offset + y * src_row_pitch], src_row_pitch); + hr = IDirect3DTexture9_UnlockRect(resource->texture, level); + ok(hr == D3D_OK, "Failed to unmap texture, hr %#lx.\n", hr); + + src_buffer_offset += src_slice_pitch; + } + break; + } + else if (params->desc.dimension == RESOURCE_DIMENSION_3D) + { + hr = IDirect3DDevice9_CreateVolumeTexture(device, + params->desc.width, params->desc.height, params->desc.depth, + params->desc.level_count, 0, format, D3DPOOL_MANAGED, &resource->volume, NULL); + ok(hr == D3D_OK, "Failed to create texture, hr %#lx.\n", hr); + + for (unsigned int level = 0; level < params->desc.level_count; ++level) + { + unsigned int level_width = get_level_dimension(params->desc.width, level); + unsigned int level_height = get_level_dimension(params->desc.height, level); + unsigned int level_depth = get_level_dimension(params->desc.depth, level); + unsigned int src_row_pitch = level_width * params->desc.texel_size; + unsigned int src_slice_pitch = level_height * src_row_pitch; + D3DLOCKED_BOX map_desc; + + hr = IDirect3DVolumeTexture9_LockBox(resource->volume, level, &map_desc, NULL, 0); + ok(hr == D3D_OK, "Failed to map texture, hr %#lx.\n", hr); + for (unsigned int z = 0; z < level_depth; ++z) + { + for (unsigned int y = 0; y < level_height; ++y) + memcpy(&((uint8_t *)map_desc.pBits)[z * map_desc.SlicePitch + y * map_desc.RowPitch], + ¶ms->data[src_buffer_offset + z * src_slice_pitch + y * src_row_pitch], + src_row_pitch); + } + hr = IDirect3DVolumeTexture9_UnlockBox(resource->volume, level); + ok(hr == D3D_OK, "Failed to unmap texture, hr %#lx.\n", hr); + + src_buffer_offset += (src_slice_pitch * level_depth); + } + break; } - break; } case RESOURCE_TYPE_UAV: @@ -288,6 +323,8 @@ static void d3d9_runner_destroy_resource(struct shader_runner *r, struct resourc IDirect3DTexture9_Release(resource->texture); if (resource->vb) IDirect3DVertexBuffer9_Release(resource->vb); + if (resource->volume) + IDirect3DVolumeTexture9_Release(resource->volume); free(resource); } @@ -421,7 +458,12 @@ static bool d3d9_runner_draw(struct shader_runner *r, case RESOURCE_TYPE_TEXTURE: assert(resource->r.desc.dimension != RESOURCE_DIMENSION_BUFFER); - hr = IDirect3DDevice9_SetTexture(device, resource->r.desc.slot, (IDirect3DBaseTexture9 *)resource->texture); + if (resource->r.desc.dimension == RESOURCE_DIMENSION_2D) + hr = IDirect3DDevice9_SetTexture(device, resource->r.desc.slot, + (IDirect3DBaseTexture9 *)resource->texture); + else + hr = IDirect3DDevice9_SetTexture(device, resource->r.desc.slot, + (IDirect3DBaseTexture9 *)resource->volume); ok(hr == D3D_OK, "Failed to set texture, hr %#lx.\n", hr); break; diff --git a/tests/shader_runner_gl.c b/tests/shader_runner_gl.c index d282d00ac..a2a2570c1 100644 --- a/tests/shader_runner_gl.c +++ b/tests/shader_runner_gl.c @@ -441,17 +441,24 @@ static void gl_runner_cleanup(struct gl_runner *runner) ok(ret, "Failed to terminate EGL display connection.\n"); } -static bool init_resource_2d(struct gl_resource *resource, const struct resource_params *params) +static bool init_resource_texture(struct gl_resource *resource, const struct resource_params *params) { - unsigned int offset, w, h, i; + unsigned int offset, w, h, d, i; GLenum target; - if (params->desc.sample_count > 1) - target = GL_TEXTURE_2D_MULTISAMPLE; - else if (params->desc.depth > 1) - target = GL_TEXTURE_2D_ARRAY; + if (params->desc.dimension == RESOURCE_DIMENSION_2D) + { + if (params->desc.sample_count > 1) + target = GL_TEXTURE_2D_MULTISAMPLE; + else if (params->desc.layer_count > 1) + target = GL_TEXTURE_2D_ARRAY; + else + target = GL_TEXTURE_2D; + } else - target = GL_TEXTURE_2D; + { + target = GL_TEXTURE_3D; + } resource->target = target; resource->format = get_format_info(params->desc.format, params->is_shadow); @@ -477,9 +484,12 @@ static bool init_resource_2d(struct gl_resource *resource, const struct resource } else { - if (params->desc.depth > 1) + if (params->desc.dimension == RESOURCE_DIMENSION_3D) glTexStorage3D(target, params->desc.level_count, resource->format->internal_format, params->desc.width, params->desc.height, params->desc.depth); + else if (params->desc.layer_count > 1) + glTexStorage3D(target, params->desc.level_count, resource->format->internal_format, + params->desc.width, params->desc.height, params->desc.layer_count); else glTexStorage2D(target, params->desc.level_count, resource->format->internal_format, params->desc.width, params->desc.height); @@ -493,9 +503,26 @@ static bool init_resource_2d(struct gl_resource *resource, const struct resource { w = get_level_dimension(params->desc.width, i); h = get_level_dimension(params->desc.height, i); - glTexSubImage2D(target, i, 0, 0, w, h, resource->format->format, - resource->format->type, params->data + offset); - offset += w * h * params->desc.texel_size; + d = get_level_dimension(params->desc.depth, i); + + if (params->desc.dimension == RESOURCE_DIMENSION_3D) + { + glTexSubImage3D(target, i, 0, 0, 0, w, h, d, resource->format->format, + resource->format->type, params->data + offset); + offset += w * h * d * params->desc.texel_size; + } + else if (params->desc.layer_count > 1) + { + glTexSubImage3D(target, i, 0, 0, 0, w, h, params->desc.layer_count, resource->format->format, + resource->format->type, params->data + offset); + offset += w * h * params->desc.layer_count * params->desc.texel_size; + } + else + { + glTexSubImage2D(target, i, 0, 0, w, h, resource->format->format, + resource->format->type, params->data + offset); + offset += w * h * params->desc.texel_size; + } } return true; @@ -532,7 +559,7 @@ static struct resource *gl_runner_create_resource(struct shader_runner *r, const case RESOURCE_TYPE_UAV: if (params->desc.dimension == RESOURCE_DIMENSION_BUFFER) init_resource_buffer(resource, params); - else if (!init_resource_2d(resource, params)) + else if (!init_resource_texture(resource, params)) return NULL; break; @@ -1349,16 +1376,17 @@ static bool gl_runner_copy(struct shader_runner *r, struct resource *src, struct { struct gl_resource *s = gl_resource(src); struct gl_resource *d = gl_resource(dst); - unsigned int l, w, h; + unsigned int l, w, h, z; - if (src->desc.dimension == RESOURCE_DIMENSION_BUFFER || src->desc.depth > 1) + if (src->desc.dimension == RESOURCE_DIMENSION_BUFFER || src->desc.layer_count > 1) return false; for (l = 0; l < src->desc.level_count; ++l) { w = get_level_dimension(src->desc.width, l); h = get_level_dimension(src->desc.height, l); - glCopyImageSubData(s->id, s->target, l, 0, 0, 0, d->id, d->target, l, 0, 0, 0, w, h, 1); + z = get_level_dimension(src->desc.depth, l); + glCopyImageSubData(s->id, s->target, l, 0, 0, 0, d->id, d->target, l, 0, 0, 0, w, h, z); } return true; @@ -1386,7 +1414,7 @@ static struct resource_readback *gl_runner_get_resource_readback(struct shader_r rb->width = resource->r.desc.width; rb->height = resource->r.desc.height; - rb->depth = 1; + rb->depth = resource->r.desc.depth; rb->row_pitch = rb->width * resource->r.desc.texel_size; slice_pitch = rb->row_pitch * rb->height; diff --git a/tests/shader_runner_metal.m b/tests/shader_runner_metal.m index 65126f861..492496d58 100644 --- a/tests/shader_runner_metal.m +++ b/tests/shader_runner_metal.m @@ -258,16 +258,27 @@ static void init_resource_texture(struct metal_runner *runner, } desc = [[MTLTextureDescriptor alloc] init]; - if (params->desc.sample_count > 1) - desc.textureType = params->desc.depth > 1 ? MTLTextureType2DMultisampleArray - : MTLTextureType2DMultisample; - else - desc.textureType = params->desc.depth > 1 ? MTLTextureType2DArray : MTLTextureType2D; + switch (params->desc.dimension) + { + case RESOURCE_DIMENSION_2D: + if (params->desc.sample_count > 1) + desc.textureType = params->desc.layer_count > 1 ? MTLTextureType2DMultisampleArray + : MTLTextureType2DMultisample; + else + desc.textureType = params->desc.layer_count > 1 ? MTLTextureType2DArray : MTLTextureType2D; + break; + case RESOURCE_DIMENSION_3D: + desc.textureType = MTLTextureType3D; + break; + default: + fatal_error("Unhandled resource dimension %#x.\n", params->desc.dimension); + } desc.pixelFormat = get_metal_pixel_format(params->desc.format); ok(desc.pixelFormat != MTLPixelFormatInvalid, "Unhandled pixel format %#x.\n", params->desc.format); desc.width = params->desc.width; desc.height = params->desc.height; - desc.arrayLength = params->desc.depth; + desc.depth = params->desc.depth; + desc.arrayLength = params->desc.layer_count; desc.mipmapLevelCount = params->desc.level_count; desc.sampleCount = max(params->desc.sample_count, 1); desc.storageMode = MTLStorageModePrivate; @@ -293,15 +304,13 @@ static void init_resource_texture(struct metal_runner *runner, if (params->data) { - unsigned int buffer_offset = 0, level, level_width, level_height; + unsigned int buffer_offset = 0, level, level_width, level_height, level_depth; id command_buffer; id blit; id upload_texture; if (params->desc.sample_count > 1) fatal_error("Cannot upload data to a multisampled texture.\n"); - if (params->desc.depth > 1) - fatal_error("Uploading data to a texture array is not supported.\n"); desc.storageMode = MTLStorageModeManaged; upload_texture = [[device newTextureWithDescriptor:desc] autorelease]; @@ -310,13 +319,14 @@ static void init_resource_texture(struct metal_runner *runner, { level_width = get_level_dimension(params->desc.width, level); level_height = get_level_dimension(params->desc.height, level); - [upload_texture replaceRegion:MTLRegionMake2D(0, 0, level_width, level_height) + level_depth = get_level_dimension(params->desc.depth, level); + [upload_texture replaceRegion:MTLRegionMake3D(0, 0, 0, level_width, level_height, level_depth) mipmapLevel:level slice:0 withBytes:¶ms->data[buffer_offset] bytesPerRow:level_width * params->desc.texel_size bytesPerImage:level_height * level_width * params->desc.texel_size]; - buffer_offset += level_height * level_width * params->desc.texel_size; + buffer_offset += level_depth * level_height * level_width * params->desc.texel_size; } command_buffer = [runner->queue commandBuffer]; @@ -896,7 +906,7 @@ static struct resource_readback *metal_runner_get_resource_readback(struct shade rb = malloc(sizeof(*rb)); rb->rb.width = resource->r.desc.width; rb->rb.height = resource->r.desc.height; - rb->rb.depth = 1; + rb->rb.depth = resource->r.desc.depth; rb->rb.row_pitch = rb->rb.width * resource->r.desc.texel_size; rb->buffer = [runner->device newBufferWithLength:rb->rb.row_pitch * rb->rb.height options:DEFAULT_BUFFER_RESOURCE_OPTIONS | MTLResourceStorageModeManaged]; diff --git a/tests/shader_runner_vulkan.c b/tests/shader_runner_vulkan.c index 922cb017d..17bc90d90 100644 --- a/tests/shader_runner_vulkan.c +++ b/tests/shader_runner_vulkan.c @@ -85,7 +85,7 @@ static struct vulkan_shader_runner *vulkan_shader_runner(struct shader_runner *r return CONTAINING_RECORD(r, struct vulkan_shader_runner, r); } -static void resource_init_2d(struct vulkan_shader_runner *runner, struct vulkan_resource *resource, +static void resource_init_texture(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; @@ -93,11 +93,12 @@ static void resource_init_2d(struct vulkan_shader_runner *runner, struct vulkan_ const struct vulkan_test_context *context = &runner->context; VkFormat format = vkd3d_get_vk_format(params->desc.format); const struct resource_desc *desc = ¶ms->desc; - uint32_t layer_count = desc->depth; + uint32_t layer_count = desc->layer_count; VkDevice device = context->device; unsigned int buffer_offset = 0; VkDeviceMemory staging_memory; VkBuffer staging_buffer; + VkImageType image_type; void *data; if (params->desc.type == RESOURCE_TYPE_UAV) @@ -106,10 +107,15 @@ static void resource_init_2d(struct vulkan_shader_runner *runner, struct vulkan_ usage |= VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; } - resource->image = create_vulkan_2d_image(context, desc->width, desc->height, - desc->level_count, desc->depth, desc->sample_count, usage, format, &resource->memory); - resource->image_view = create_vulkan_2d_image_view(context, - resource->image, format, VK_IMAGE_ASPECT_COLOR_BIT, layer_count); + if (params->desc.dimension == RESOURCE_DIMENSION_3D) + image_type = VK_IMAGE_TYPE_3D; + else + image_type = VK_IMAGE_TYPE_2D; + + resource->image = create_vulkan_image(context, image_type, desc->width, desc->height, desc->depth, + desc->level_count, desc->layer_count, desc->sample_count, usage, format, &resource->memory); + resource->image_view = create_vulkan_image_view(context, + resource->image, format, VK_IMAGE_ASPECT_COLOR_BIT, image_type, layer_count); if (!params->data) { @@ -135,6 +141,7 @@ static void resource_init_2d(struct vulkan_shader_runner *runner, struct vulkan_ { unsigned int level_width = get_level_dimension(params->desc.width, level); unsigned int level_height = get_level_dimension(params->desc.height, level); + unsigned int level_depth = get_level_dimension(params->desc.depth, level); VkBufferImageCopy region = {0}; region.bufferOffset = buffer_offset; @@ -143,11 +150,11 @@ static void resource_init_2d(struct vulkan_shader_runner *runner, struct vulkan_ region.imageSubresource.layerCount = 1; region.imageExtent.width = level_width; region.imageExtent.height = level_height; - region.imageExtent.depth = 1; + region.imageExtent.depth = level_depth; VK_CALL(vkCmdCopyBufferToImage(context->cmd_buffer, staging_buffer, resource->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion)); - buffer_offset += level_width * level_height * params->desc.texel_size; + buffer_offset += level_depth * level_width * level_height * params->desc.texel_size; } transition_image_layout(context, resource->image, VK_IMAGE_ASPECT_COLOR_BIT, @@ -191,7 +198,7 @@ static struct resource *vulkan_runner_create_resource(struct shader_runner *r, c struct vulkan_shader_runner *runner = vulkan_shader_runner(r); const struct vulkan_test_context *context = &runner->context; const struct resource_desc *desc = ¶ms->desc; - unsigned int layer_count = desc->depth; + unsigned int layer_count = desc->layer_count; VkDevice device = context->device; struct vulkan_resource *resource; VkFormat format; @@ -205,11 +212,11 @@ static struct resource *vulkan_runner_create_resource(struct shader_runner *r, c case RESOURCE_TYPE_RENDER_TARGET: format = vkd3d_get_vk_format(params->desc.format); - resource->image = create_vulkan_2d_image(context, desc->width, - desc->height, desc->level_count, desc->depth, desc->sample_count, + resource->image = create_vulkan_image(context, VK_IMAGE_TYPE_2D, + desc->width, desc->height, 1, desc->level_count, desc->layer_count, desc->sample_count, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, format, &resource->memory); - resource->image_view = create_vulkan_2d_image_view(context, - resource->image, format, VK_IMAGE_ASPECT_COLOR_BIT, layer_count); + resource->image_view = create_vulkan_image_view(context, + resource->image, format, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_TYPE_2D, layer_count); begin_command_buffer(context); transition_image_layout(context, resource->image, VK_IMAGE_ASPECT_COLOR_BIT, 0, @@ -220,12 +227,12 @@ static struct resource *vulkan_runner_create_resource(struct shader_runner *r, c case RESOURCE_TYPE_DEPTH_STENCIL: format = vkd3d_get_vk_format(params->desc.format); - resource->image = create_vulkan_2d_image(context, desc->width, - desc->height, desc->level_count, desc->depth, desc->sample_count, + resource->image = create_vulkan_image(context, VK_IMAGE_TYPE_2D, + desc->width, desc->height, 1, desc->level_count, desc->layer_count, desc->sample_count, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, format, &resource->memory); - resource->image_view = create_vulkan_2d_image_view(context, - resource->image, format, VK_IMAGE_ASPECT_DEPTH_BIT, layer_count); + resource->image_view = create_vulkan_image_view(context, + resource->image, format, VK_IMAGE_ASPECT_DEPTH_BIT, VK_IMAGE_TYPE_2D, layer_count); begin_command_buffer(context); transition_image_layout(context, resource->image, VK_IMAGE_ASPECT_DEPTH_BIT, 0, layer_count, @@ -238,7 +245,7 @@ static struct resource *vulkan_runner_create_resource(struct shader_runner *r, c if (params->desc.dimension == RESOURCE_DIMENSION_BUFFER) resource_init_buffer(runner, resource, params); else - resource_init_2d(runner, resource, params); + resource_init_texture(runner, resource, params); break; case RESOURCE_TYPE_VERTEX_BUFFER: @@ -1133,8 +1140,8 @@ static void create_render_pass_and_framebuffer(struct vulkan_shader_runner *runn runner->rt_size.width = resource->r.desc.width; if (resource->r.desc.height < runner->rt_size.height) runner->rt_size.height = resource->r.desc.height; - if (resource->r.desc.depth < layer_count) - layer_count = resource->r.desc.depth; + if (resource->r.desc.layer_count < layer_count) + layer_count = resource->r.desc.layer_count; views[view_count++] = resource->image_view; } @@ -1274,7 +1281,7 @@ static void vulkan_runner_clear(struct shader_runner *r, struct resource *res, c fb_desc.pAttachments = &resource->image_view; fb_desc.width = width; fb_desc.height = height; - fb_desc.layers = resource->r.desc.depth; + fb_desc.layers = resource->r.desc.layer_count; VK_CALL(vkCreateFramebuffer(device, &fb_desc, NULL, &fb)); begin_desc.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; @@ -1376,7 +1383,7 @@ static bool vulkan_runner_copy(struct shader_runner *r, struct resource *src, st VkImageCopy vk_image_copy; unsigned int l; - if (src->desc.dimension == RESOURCE_DIMENSION_BUFFER || src->desc.depth > 1) + if (src->desc.dimension == RESOURCE_DIMENSION_BUFFER || src->desc.layer_count > 1) return false; if (src->desc.type == RESOURCE_TYPE_DEPTH_STENCIL) @@ -1394,7 +1401,6 @@ static bool vulkan_runner_copy(struct shader_runner *r, struct resource *src, st vk_image_copy.srcOffset = (VkOffset3D){.x = 0, .y = 0, .z = 0}; vk_image_copy.dstSubresource = vk_image_copy.srcSubresource; vk_image_copy.dstOffset = vk_image_copy.srcOffset; - vk_image_copy.extent.depth = 1; for (l = 0; l < src->desc.level_count; ++l) { @@ -1402,6 +1408,7 @@ static bool vulkan_runner_copy(struct shader_runner *r, struct resource *src, st vk_image_copy.dstSubresource.mipLevel = l; vk_image_copy.extent.width = get_level_dimension(src->desc.width, l); vk_image_copy.extent.height = get_level_dimension(src->desc.height, l); + vk_image_copy.extent.depth = get_level_dimension(src->desc.depth, l); VK_CALL(vkCmdCopyImage(context->cmd_buffer, s->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, d->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &vk_image_copy)); @@ -1433,14 +1440,16 @@ static struct resource_readback *vulkan_runner_get_resource_readback(struct shad VkBufferImageCopy region = {0}; unsigned int layer, level; VkImageLayout layout; + size_t slice_pitch; rb->rb.width = resource->r.desc.width; rb->rb.height = resource->r.desc.height; - rb->rb.depth = 1; + rb->rb.depth = resource->r.desc.depth; rb->rb.row_pitch = rb->rb.width * resource->r.desc.texel_size; + slice_pitch = rb->rb.row_pitch * rb->rb.height; - rb->buffer = create_vulkan_buffer(context, rb->rb.row_pitch * rb->rb.height, + rb->buffer = create_vulkan_buffer(context, slice_pitch * rb->rb.depth, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &rb->memory); if (resource->r.desc.type == RESOURCE_TYPE_UAV && resource->r.desc.dimension == RESOURCE_DIMENSION_BUFFER) @@ -1475,7 +1484,7 @@ static struct resource_readback *vulkan_runner_get_resource_readback(struct shad region.imageSubresource.layerCount = 1; region.imageExtent.width = resource->r.desc.width; region.imageExtent.height = resource->r.desc.height; - region.imageExtent.depth = 1; + region.imageExtent.depth = resource->r.desc.depth; if (resource->r.desc.sample_count > 1) { @@ -1490,8 +1499,9 @@ static struct resource_readback *vulkan_runner_get_resource_readback(struct shad resolve_region.extent.depth = 1; resolved_desc.sample_count = 1; - resolved_image = create_vulkan_2d_image(context, resolved_desc.width, resolved_desc.height, - resolved_desc.level_count, resolved_desc.depth, resolved_desc.sample_count, + resolved_image = create_vulkan_image(context, VK_IMAGE_TYPE_2D, + resolved_desc.width, resolved_desc.height, resolved_desc.depth, + resolved_desc.level_count, resolved_desc.layer_count, resolved_desc.sample_count, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, vkd3d_get_vk_format(resource->r.desc.format), &resolved_memory); transition_image_layout(context, resolved_image, VK_IMAGE_ASPECT_COLOR_BIT, layer, diff --git a/tests/vulkan_utils.h b/tests/vulkan_utils.h index 57497b22d..660f31c8c 100644 --- a/tests/vulkan_utils.h +++ b/tests/vulkan_utils.h @@ -167,19 +167,19 @@ static inline VkBufferView create_vulkan_buffer_view(const struct vulkan_test_co return view; } -static inline VkImage create_vulkan_2d_image(const struct vulkan_test_context *context, unsigned int width, - unsigned int height, unsigned int level_count, unsigned int layer_count, unsigned int sample_count, - VkImageUsageFlags usage, VkFormat format, VkDeviceMemory *memory) +static inline VkImage create_vulkan_image(const struct vulkan_test_context *context, VkImageType image_type, + unsigned int width, unsigned int height, unsigned int depth, unsigned int level_count, unsigned int layer_count, + unsigned int sample_count, VkImageUsageFlags usage, VkFormat format, VkDeviceMemory *memory) { VkImageCreateInfo image_info = {.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO}; VkMemoryRequirements memory_reqs; VkImage image; - image_info.imageType = VK_IMAGE_TYPE_2D; + image_info.imageType = image_type; image_info.format = format; image_info.extent.width = width; image_info.extent.height = height; - image_info.extent.depth = 1; + image_info.extent.depth = depth; image_info.mipLevels = level_count; image_info.arrayLayers = layer_count; image_info.samples = max(sample_count, 1); @@ -197,14 +197,17 @@ static inline VkImage create_vulkan_2d_image(const struct vulkan_test_context *c return image; } -static inline VkImageView create_vulkan_2d_image_view(const struct vulkan_test_context *context, - VkImage image, VkFormat format, VkImageAspectFlags aspect_mask, unsigned int layer_count) +static inline VkImageView create_vulkan_image_view(const struct vulkan_test_context *context, VkImage image, + VkFormat format, VkImageAspectFlags aspect_mask, VkImageType image_type, unsigned int layer_count) { VkImageViewCreateInfo view_info = {.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO}; VkImageView view; view_info.image = image; - view_info.viewType = (layer_count > 1) ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D; + if (image_type == VK_IMAGE_TYPE_2D) + view_info.viewType = (layer_count > 1) ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D; + else if (image_type == VK_IMAGE_TYPE_3D) + view_info.viewType = VK_IMAGE_VIEW_TYPE_3D; view_info.format = format; view_info.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; view_info.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;