Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
-- v11: tests: Add RWBuffer writing test. tests: Add support for UAV buffers in the d3d11 runner. tests: Add support for UAV buffers to d3d12 runner. tests: Rename readback helper to be more generic.
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/d3d_asm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d-shader/d3d_asm.c index 9438bfac..3357b450 100644 --- a/libs/vkd3d-shader/d3d_asm.c +++ b/libs/vkd3d-shader/d3d_asm.c @@ -661,8 +661,9 @@ static void shader_dump_decl_usage(struct vkd3d_d3d_asm_compiler *compiler, else if (semantic->resource.reg.reg.type == VKD3DSPR_RESOURCE || semantic->resource.reg.reg.type == VKD3DSPR_UAV) { if (semantic->resource.reg.reg.type == VKD3DSPR_RESOURCE) - shader_addline(buffer, "_resource_"); + shader_addline(buffer, "_resource");
+ shader_addline(buffer, "_"); shader_dump_resource_type(compiler, semantic->resource_type); if (semantic->resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS || semantic->resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY)
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/hlsl.c | 22 ++++++++++++++++------ libs/vkd3d-shader/hlsl.h | 34 +++++++++++++++++++--------------- libs/vkd3d-shader/hlsl.l | 1 + libs/vkd3d-shader/hlsl.y | 7 ++++++- libs/vkd3d-shader/tpf.c | 4 ++++ 5 files changed, 46 insertions(+), 22 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 617aef30..ed6e6ee0 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -1935,7 +1935,7 @@ static int compare_function_decl_rb(const void *key, const struct rb_entry *entr
struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const struct hlsl_type *type) { - struct vkd3d_string_buffer *string; + struct vkd3d_string_buffer *string, *inner_string;
static const char *const base_types[] = { @@ -1975,7 +1975,6 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru
case HLSL_CLASS_ARRAY: { - struct vkd3d_string_buffer *inner_string; const struct hlsl_type *t;
for (t = type; t->class == HLSL_CLASS_ARRAY; t = t->e.array.type) @@ -2027,13 +2026,24 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru
assert(type->sampler_dim < ARRAY_SIZE(dimensions)); assert(type->e.resource_format->base_type < ARRAY_SIZE(base_types)); - vkd3d_string_buffer_printf(string, "Texture%s<%s%u>", dimensions[type->sampler_dim], - base_types[type->e.resource_format->base_type], type->e.resource_format->dimx); + vkd3d_string_buffer_printf(string, "Texture%s", dimensions[type->sampler_dim]); + if ((inner_string = hlsl_type_to_string(ctx, type->e.resource_format))) + { + vkd3d_string_buffer_printf(string, "<%s>", inner_string->buffer); + hlsl_release_string_buffer(ctx, inner_string); + } return string;
case HLSL_TYPE_UAV: - vkd3d_string_buffer_printf(string, "RWTexture%s<%s%u>", dimensions[type->sampler_dim], - base_types[type->e.resource_format->base_type], type->e.resource_format->dimx); + if (type->sampler_dim == HLSL_SAMPLER_DIM_BUFFER) + vkd3d_string_buffer_printf(string, "RWBuffer"); + else + vkd3d_string_buffer_printf(string, "RWTexture%s", dimensions[type->sampler_dim]); + if ((inner_string = hlsl_type_to_string(ctx, type->e.resource_format))) + { + vkd3d_string_buffer_printf(string, "<%s>", inner_string->buffer); + hlsl_release_string_buffer(ctx, inner_string); + } return string;
default: diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 6a4e314d..8319cfdf 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -104,18 +104,20 @@ enum hlsl_base_type
enum hlsl_sampler_dim { - HLSL_SAMPLER_DIM_GENERIC, - HLSL_SAMPLER_DIM_1D, - HLSL_SAMPLER_DIM_2D, - HLSL_SAMPLER_DIM_3D, - HLSL_SAMPLER_DIM_CUBE, - HLSL_SAMPLER_DIM_LAST_SAMPLER = HLSL_SAMPLER_DIM_CUBE, - HLSL_SAMPLER_DIM_1DARRAY, - HLSL_SAMPLER_DIM_2DARRAY, - HLSL_SAMPLER_DIM_2DMS, - HLSL_SAMPLER_DIM_2DMSARRAY, - HLSL_SAMPLER_DIM_CUBEARRAY, - HLSL_SAMPLER_DIM_MAX = HLSL_SAMPLER_DIM_CUBEARRAY, + HLSL_SAMPLER_DIM_GENERIC, + HLSL_SAMPLER_DIM_1D, + HLSL_SAMPLER_DIM_2D, + HLSL_SAMPLER_DIM_3D, + HLSL_SAMPLER_DIM_CUBE, + HLSL_SAMPLER_DIM_LAST_SAMPLER = HLSL_SAMPLER_DIM_CUBE, + HLSL_SAMPLER_DIM_1DARRAY, + HLSL_SAMPLER_DIM_2DARRAY, + HLSL_SAMPLER_DIM_2DMS, + HLSL_SAMPLER_DIM_2DMSARRAY, + HLSL_SAMPLER_DIM_CUBEARRAY, + HLSL_SAMPLER_DIM_LAST_TEXTURE = HLSL_SAMPLER_DIM_CUBEARRAY, + HLSL_SAMPLER_DIM_BUFFER, + HLSL_SAMPLER_DIM_MAX = HLSL_SAMPLER_DIM_BUFFER, };
enum hlsl_regset @@ -143,9 +145,10 @@ struct hlsl_type enum hlsl_base_type base_type;
/* If base_type is HLSL_TYPE_SAMPLER, then sampler_dim is <= HLSL_SAMPLER_DIM_LAST_SAMPLER. - * If base_type is HLSL_TYPE_TEXTURE, then sampler_dim can have any value of the enum. - * If base_type is HLSL_TYPE_UAV, them sampler_dim must be one of HLSL_SAMPLER_DIM_1D, - * HLSL_SAMPLER_DIM_2D, HLSL_SAMPLER_DIM_3D, HLSL_SAMPLER_DIM_1DARRAY, or HLSL_SAMPLER_DIM_2DARRAY. + * If base_type is HLSL_TYPE_TEXTURE, then sampler_dim is <= HLSL_SAMPLER_DIM_LAST_TEXTURE. + * If base_type is HLSL_TYPE_UAV, then sampler_dim must be one of HLSL_SAMPLER_DIM_1D, + * HLSL_SAMPLER_DIM_2D, HLSL_SAMPLER_DIM_3D, HLSL_SAMPLER_DIM_1DARRAY, HLSL_SAMPLER_DIM_2DARRAY, + * or HLSL_SAMPLER_DIM_BUFFER. * Otherwise, sampler_dim is not used */ enum hlsl_sampler_dim sampler_dim; /* Name, in case the type is a named struct or a typedef. */ @@ -1023,6 +1026,7 @@ static inline unsigned int hlsl_sampler_dim_count(enum hlsl_sampler_dim dim) switch (dim) { case HLSL_SAMPLER_DIM_1D: + case HLSL_SAMPLER_DIM_BUFFER: return 1; case HLSL_SAMPLER_DIM_1DARRAY: case HLSL_SAMPLER_DIM_2D: diff --git a/libs/vkd3d-shader/hlsl.l b/libs/vkd3d-shader/hlsl.l index 6c2324c7..1bc92789 100644 --- a/libs/vkd3d-shader/hlsl.l +++ b/libs/vkd3d-shader/hlsl.l @@ -104,6 +104,7 @@ RasterizerState {return KW_RASTERIZERSTATE; } RenderTargetView {return KW_RENDERTARGETVIEW; } return {return KW_RETURN; } register {return KW_REGISTER; } +RWBuffer {return KW_RWBUFFER; } RWTexture1D {return KW_RWTEXTURE1D; } RWTexture2D {return KW_RWTEXTURE2D; } RWTexture3D {return KW_RWTEXTURE3D; } diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 86f23665..9e33759b 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -4144,6 +4144,7 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type %token KW_RETURN %token KW_REGISTER %token KW_ROW_MAJOR +%token KW_RWBUFFER %token KW_RWTEXTURE1D %token KW_RWTEXTURE2D %token KW_RWTEXTURE3D @@ -4953,7 +4954,11 @@ texture_ms_type: }
uav_type: - KW_RWTEXTURE1D + KW_RWBUFFER + { + $$ = HLSL_SAMPLER_DIM_BUFFER; + } + | KW_RWTEXTURE1D { $$ = HLSL_SAMPLER_DIM_1D; } diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c index eadad3b9..4a7093b5 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -2957,6 +2957,8 @@ static D3D_SRV_DIMENSION sm4_rdef_resource_dimension(const struct hlsl_type *typ return D3D_SRV_DIMENSION_TEXTURE2DMSARRAY; case HLSL_SAMPLER_DIM_CUBEARRAY: return D3D_SRV_DIMENSION_TEXTURECUBEARRAY; + case HLSL_SAMPLER_DIM_BUFFER: + return D3D_SRV_DIMENSION_BUFFER; default: vkd3d_unreachable(); } @@ -3256,6 +3258,8 @@ static enum vkd3d_sm4_resource_type sm4_resource_dimension(const struct hlsl_typ return VKD3D_SM4_RESOURCE_TEXTURE_2DMSARRAY; case HLSL_SAMPLER_DIM_CUBEARRAY: return VKD3D_SM4_RESOURCE_TEXTURE_CUBEARRAY; + case HLSL_SAMPLER_DIM_BUFFER: + return VKD3D_SM4_RESOURCE_BUFFER; default: vkd3d_unreachable(); }
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/hlsl.c | 2 ++ libs/vkd3d-shader/hlsl.h | 6 ++++-- libs/vkd3d-shader/hlsl.l | 1 + libs/vkd3d-shader/hlsl.y | 5 +++++ libs/vkd3d-shader/tpf.c | 37 ++++++++++++++++++++++++++++++++++--- 5 files changed, 46 insertions(+), 5 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index ed6e6ee0..e0d2fbb8 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -2037,6 +2037,8 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru case HLSL_TYPE_UAV: if (type->sampler_dim == HLSL_SAMPLER_DIM_BUFFER) vkd3d_string_buffer_printf(string, "RWBuffer"); + else if (type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) + vkd3d_string_buffer_printf(string, "RWStructuredBuffer"); else vkd3d_string_buffer_printf(string, "RWTexture%s", dimensions[type->sampler_dim]); if ((inner_string = hlsl_type_to_string(ctx, type->e.resource_format))) diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 8319cfdf..c55c7916 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -117,7 +117,8 @@ enum hlsl_sampler_dim HLSL_SAMPLER_DIM_CUBEARRAY, HLSL_SAMPLER_DIM_LAST_TEXTURE = HLSL_SAMPLER_DIM_CUBEARRAY, HLSL_SAMPLER_DIM_BUFFER, - HLSL_SAMPLER_DIM_MAX = HLSL_SAMPLER_DIM_BUFFER, + HLSL_SAMPLER_DIM_STRUCTURED_BUFFER, + HLSL_SAMPLER_DIM_MAX = HLSL_SAMPLER_DIM_STRUCTURED_BUFFER, };
enum hlsl_regset @@ -148,7 +149,7 @@ struct hlsl_type * If base_type is HLSL_TYPE_TEXTURE, then sampler_dim is <= HLSL_SAMPLER_DIM_LAST_TEXTURE. * If base_type is HLSL_TYPE_UAV, then sampler_dim must be one of HLSL_SAMPLER_DIM_1D, * HLSL_SAMPLER_DIM_2D, HLSL_SAMPLER_DIM_3D, HLSL_SAMPLER_DIM_1DARRAY, HLSL_SAMPLER_DIM_2DARRAY, - * or HLSL_SAMPLER_DIM_BUFFER. + * HLSL_SAMPLER_DIM_BUFFER, or HLSL_SAMPLER_DIM_STRUCTURED_BUFFER. * Otherwise, sampler_dim is not used */ enum hlsl_sampler_dim sampler_dim; /* Name, in case the type is a named struct or a typedef. */ @@ -1027,6 +1028,7 @@ static inline unsigned int hlsl_sampler_dim_count(enum hlsl_sampler_dim dim) { case HLSL_SAMPLER_DIM_1D: case HLSL_SAMPLER_DIM_BUFFER: + case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER: return 1; case HLSL_SAMPLER_DIM_1DARRAY: case HLSL_SAMPLER_DIM_2D: diff --git a/libs/vkd3d-shader/hlsl.l b/libs/vkd3d-shader/hlsl.l index 1bc92789..e9ae3ccf 100644 --- a/libs/vkd3d-shader/hlsl.l +++ b/libs/vkd3d-shader/hlsl.l @@ -105,6 +105,7 @@ RenderTargetView {return KW_RENDERTARGETVIEW; } return {return KW_RETURN; } register {return KW_REGISTER; } RWBuffer {return KW_RWBUFFER; } +RWStructuredBuffer {return KW_RWSTRUCTUREDBUFFER; } RWTexture1D {return KW_RWTEXTURE1D; } RWTexture2D {return KW_RWTEXTURE2D; } RWTexture3D {return KW_RWTEXTURE3D; } diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 9e33759b..c0477c4d 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -4145,6 +4145,7 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type %token KW_REGISTER %token KW_ROW_MAJOR %token KW_RWBUFFER +%token KW_RWSTRUCTUREDBUFFER %token KW_RWTEXTURE1D %token KW_RWTEXTURE2D %token KW_RWTEXTURE3D @@ -4958,6 +4959,10 @@ uav_type: { $$ = HLSL_SAMPLER_DIM_BUFFER; } + | KW_RWSTRUCTUREDBUFFER + { + $$ = HLSL_SAMPLER_DIM_STRUCTURED_BUFFER; + } | KW_RWTEXTURE1D { $$ = HLSL_SAMPLER_DIM_1D; diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c index 4a7093b5..371f0b65 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -2958,6 +2958,7 @@ static D3D_SRV_DIMENSION sm4_rdef_resource_dimension(const struct hlsl_type *typ case HLSL_SAMPLER_DIM_CUBEARRAY: return D3D_SRV_DIMENSION_TEXTURECUBEARRAY; case HLSL_SAMPLER_DIM_BUFFER: + case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER: return D3D_SRV_DIMENSION_BUFFER; default: vkd3d_unreachable(); @@ -3259,6 +3260,7 @@ static enum vkd3d_sm4_resource_type sm4_resource_dimension(const struct hlsl_typ case HLSL_SAMPLER_DIM_CUBEARRAY: return VKD3D_SM4_RESOURCE_TEXTURE_CUBEARRAY; case HLSL_SAMPLER_DIM_BUFFER: + case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER: return VKD3D_SM4_RESOURCE_BUFFER; default: vkd3d_unreachable(); @@ -3334,6 +3336,8 @@ struct sm4_instruction } srcs[4]; unsigned int src_count;
+ unsigned int byte_stride; + uint32_t idx[3]; unsigned int idx_count; }; @@ -3568,6 +3572,8 @@ static void write_sm4_instruction(struct vkd3d_bytecode_buffer *buffer, const st for (i = 0; i < instr->src_count; ++i) size += sm4_register_order(&instr->srcs[i].reg); size += instr->idx_count; + if (instr->byte_stride) + ++size;
token |= (size << VKD3D_SM4_INSTRUCTION_LENGTH_SHIFT);
@@ -3622,6 +3628,9 @@ static void write_sm4_instruction(struct vkd3d_bytecode_buffer *buffer, const st } }
+ if (instr->byte_stride) + put_u32(buffer, instr->byte_stride); + for (j = 0; j < instr->idx_count; ++j) put_u32(buffer, instr->idx[j]); } @@ -3707,9 +3716,6 @@ static void write_sm4_dcl_textures(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b
instr = (struct sm4_instruction) { - .opcode = (uav ? VKD3D_SM5_OP_DCL_UAV_TYPED : VKD3D_SM4_OP_DCL_RESOURCE) - | (sm4_resource_dimension(component_type) << VKD3D_SM4_RESOURCE_TYPE_SHIFT), - .dsts[0].reg.type = uav ? VKD3D_SM5_RT_UAV : VKD3D_SM4_RT_RESOURCE, .dsts[0].reg.idx = {var->regs[regset].id + i}, .dsts[0].reg.idx_count = 1, @@ -3719,6 +3725,25 @@ static void write_sm4_dcl_textures(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b .idx_count = 1, };
+ if (uav) + { + switch (var->data_type->sampler_dim) + { + case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER: + instr.opcode = VKD3D_SM5_OP_DCL_UAV_STRUCTURED; + instr.byte_stride = var->data_type->e.resource_format->reg_size[HLSL_REGSET_NUMERIC] * 4; + break; + default: + instr.opcode = VKD3D_SM5_OP_DCL_UAV_TYPED; + break; + } + } + else + { + instr.opcode = VKD3D_SM4_OP_DCL_RESOURCE; + } + instr.opcode |= (sm4_resource_dimension(component_type) << VKD3D_SM4_RESOURCE_TYPE_SHIFT); + if (component_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS || component_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY) { @@ -4928,6 +4953,12 @@ static void write_sm4_resource_store(struct hlsl_ctx *ctx, return; }
+ if (resource_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) + { + hlsl_fixme(ctx, &store->node.loc, "Structured buffers store is not implemented.\n"); + return; + } + write_sm4_store_uav_typed(ctx, buffer, &store->resource, store->coords.node, store->value.node); }
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- Makefile.am | 4 +- libs/vkd3d-shader/hlsl.y | 38 +++- tests/uav-rwbuffer.shader_test | 64 +++++++ tests/uav-rwstructuredbuffer.shader_test | 57 ++++++ ....shader_test => uav-rwtexture.shader_test} | 168 ++++++++++++++++++ 5 files changed, 324 insertions(+), 7 deletions(-) create mode 100644 tests/uav-rwbuffer.shader_test create mode 100644 tests/uav-rwstructuredbuffer.shader_test rename tests/{uav.shader_test => uav-rwtexture.shader_test} (57%)
diff --git a/Makefile.am b/Makefile.am index e06d0eeb..8db1bf8c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -173,9 +173,11 @@ vkd3d_shader_tests = \ tests/texture-load-offset.shader_test \ tests/texture-load-typed.shader_test \ tests/trigonometry.shader_test \ - tests/uav.shader_test \ tests/uav-load.shader_test \ tests/uav-out-param.shader_test \ + tests/uav-rwbuffer.shader_test \ + tests/uav-rwstructuredbuffer.shader_test \ + tests/uav-rwtexture.shader_test \ tests/writemask-assignop-0.shader_test \ tests/writemask-assignop-1.shader_test \ tests/writemask-assignop-2.shader_test \ diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index c0477c4d..4261922d 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -5095,16 +5095,42 @@ type_no_void: } | uav_type '<' type '>' { - if ($3->class > HLSL_CLASS_VECTOR) - { - struct vkd3d_string_buffer *string; + struct vkd3d_string_buffer *string = hlsl_type_to_string(ctx, $3);
- string = hlsl_type_to_string(ctx, $3); + if (!type_contains_only_numerics($3)) + { if (string) hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "UAV data type %s is not scalar or vector.", string->buffer); - hlsl_release_string_buffer(ctx, string); + "UAV type %s is not numeric.", string->buffer); } + + switch ($1) + { + case HLSL_SAMPLER_DIM_BUFFER: + case HLSL_SAMPLER_DIM_1D: + case HLSL_SAMPLER_DIM_2D: + case HLSL_SAMPLER_DIM_3D: + if ($3->class == HLSL_CLASS_ARRAY) + { + if (string) + hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "This type of UAV does not support array type."); + } + else if (hlsl_type_component_count($3) > 4) + { + if (string) + hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "UAV data type %s size exceeds maximum size.", string->buffer); + } + break; + case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER: + break; + default: + vkd3d_unreachable(); + } + + hlsl_release_string_buffer(ctx, string); + $$ = hlsl_new_uav_type(ctx, $1, $3); } | TYPE_IDENTIFIER diff --git a/tests/uav-rwbuffer.shader_test b/tests/uav-rwbuffer.shader_test new file mode 100644 index 00000000..f6334a5c --- /dev/null +++ b/tests/uav-rwbuffer.shader_test @@ -0,0 +1,64 @@ +[require] +shader model >= 5.0 + +[pixel shader] +struct s +{ + float3 a; +}; + +RWBuffer<float4> u : register(u2); +RWBuffer<float> u1; +RWBuffer<float2x2> u2; +RWBuffer<struct s> u3; + +float4 main() : sv_target1 +{ + u[0] = float4(11.1, 12.2, 13.3, 14.4); + return 0; +} + +% Type size is too wide +[pixel shader fail] +struct s +{ + float3 a; + float2 b; +}; +RWBuffer<struct s> u; + +float4 main() : sv_target1 +{ + return 0; +} + +% Array type +[pixel shader fail] +typedef float arr[2]; +RWBuffer<arr> u; + +float4 main() : sv_target1 +{ + return 0; +} + +% Object types +[pixel shader fail] +RWBuffer<Texture2D> u; + +float4 main() : sv_target1 +{ + return 0; +} + +[pixel shader fail] +struct s +{ + Texture2D t; +}; +RWBuffer<struct s> u; + +float4 main() : sv_target1 +{ + return 0; +} diff --git a/tests/uav-rwstructuredbuffer.shader_test b/tests/uav-rwstructuredbuffer.shader_test new file mode 100644 index 00000000..5ea67329 --- /dev/null +++ b/tests/uav-rwstructuredbuffer.shader_test @@ -0,0 +1,57 @@ +[require] +shader model >= 5.0 + +[pixel shader todo] +struct s +{ + float3 a; +}; + +struct s2 +{ + float4x4 f1, f2, f3; +}; + +RWStructuredBuffer<float4> u : register(u2); +RWStructuredBuffer<float> u1; +RWStructuredBuffer<float2x2> u2; +RWStructuredBuffer<struct s> u3; +RWStructuredBuffer<float4x4> u4; +RWStructuredBuffer<struct s2> u5; + +float4 main() : sv_target1 +{ + u[0] = float4(11.1, 12.2, 13.3, 14.4); + return 0; +} + +% Array type +[pixel shader] +typedef float arr[2]; +RWStructuredBuffer<arr> u; + +float4 main() : sv_target1 +{ + return 0; +} + +% Object types +[pixel shader fail] +RWStructuredBuffer<Texture2D> u; + +float4 main() : sv_target1 +{ + return 0; +} + +[pixel shader fail] +struct s +{ + Texture2D t; +}; +RWStructuredBuffer<struct s> u; + +float4 main() : sv_target1 +{ + return 0; +} diff --git a/tests/uav.shader_test b/tests/uav-rwtexture.shader_test similarity index 57% rename from tests/uav.shader_test rename to tests/uav-rwtexture.shader_test index 9740575c..07c28cb8 100644 --- a/tests/uav.shader_test +++ b/tests/uav-rwtexture.shader_test @@ -161,3 +161,171 @@ float4 main() : sv_target1 draw quad probe uav 2 (0, 0) rgba (1.1, 1.2, 1.3, 1.4) probe uav 3 (0, 0) rgba (2.1, 2.2, 2.3, 2.4) + +% RWTexture1D types +[pixel shader] +struct s +{ + float3 a; +}; + +RWTexture1D<float4> u : register(u2); +RWTexture1D<float> u1; +RWTexture1D<float2x2> u2; +RWTexture1D<struct s> u3; + +float4 main() : sv_target1 +{ + u[0] = float4(11.1, 12.2, 13.3, 14.4); + return 0; +} + +% RWTexture2D types +[pixel shader] +struct s +{ + float3 a; +}; + +RWTexture2D<float4> u : register(u2); +RWTexture2D<float> u1; +RWTexture2D<float2x2> u2; +RWTexture2D<struct s> u3; + +float4 main() : sv_target1 +{ + u[int2(0, 0)] = float4(11.1, 12.2, 13.3, 14.4); + return 0; +} + +% RWTexture3D types +[pixel shader] +struct s +{ + float3 a; +}; + +RWTexture3D<float4> u : register(u2); +RWTexture3D<float> u1; +RWTexture3D<float2x2> u2; +RWTexture3D<struct s> u3; + +float4 main() : sv_target1 +{ + u[int3(0, 0, 0)] = float4(11.1, 12.2, 13.3, 14.4); + return 0; +} + +% Type is too wide +[pixel shader fail] +struct s +{ + float3 a; + float2 b; +}; +RWTexture1D<struct s> u; + +float4 main() : sv_target1 +{ + return 0; +} + +[pixel shader fail] +struct s +{ + float3 a; + float2 b; +}; +RWTexture2D<struct s> u; + +float4 main() : sv_target1 +{ + return 0; +} + +[pixel shader fail] +struct s +{ + float3 a; + float2 b; +}; +RWTexture3D<struct s> u; + +float4 main() : sv_target1 +{ + return 0; +} + +% Array type +[pixel shader fail] +typedef float arr[2]; +RWTexture1D<arr> u; + +float4 main() : sv_target1 +{ + return 0; +} + +% Object types +[pixel shader fail] +RWTexture1D<Texture2D> u; + +float4 main() : sv_target1 +{ + return 0; +} + +[pixel shader fail] +RWTexture2D<Texture2D> u; + +float4 main() : sv_target1 +{ + return 0; +} + +[pixel shader fail] +RWTexture3D<Texture2D> u; + +float4 main() : sv_target1 +{ + return 0; +} + +[pixel shader fail] +struct s +{ + Texture2D t; +}; + +RWTexture1D<struct s> u; + +float4 main() : sv_target1 +{ + return 0; +} + +[pixel shader fail] +struct s +{ + Texture2D t; +}; + +RWTexture2D<struct s> u; + +float4 main() : sv_target1 +{ + return 0; +} + +[pixel shader fail] +struct s +{ + Texture2D t; +}; + +RWTexture3D<struct s> u; + +float4 main() : sv_target1 +{ + return 0; +}
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- tests/shader_runner.c | 23 +++++++ tests/shader_runner.h | 1 + tests/shader_runner_d3d11.c | 7 ++- tests/shader_runner_d3d12.c | 4 ++ tests/shader_runner_d3d9.c | 2 + tests/shader_runner_vulkan.c | 118 +++++++++++++++++++++++++++-------- tests/vulkan_procs.h | 2 + 7 files changed, 128 insertions(+), 29 deletions(-)
diff --git a/tests/shader_runner.c b/tests/shader_runner.c index b51145c7..89137355 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -567,6 +567,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, "buffer uav", &line)) + { + slot = strtoul(line, &rest, 10); + + if (rest == line) + fatal_error("Malformed buffer UAV index '%s'.\n", line); + line = rest; + + resource = get_resource(runner, RESOURCE_TYPE_BUFFER_UAV, slot); + } else if (match_string(line, "render target", &line)) { slot = strtoul(line, &rest, 10); @@ -1035,6 +1045,19 @@ void run_shader_tests(struct shader_runner *runner, const struct shader_runner_o current_resource.texel_size = 16; current_resource.level_count = 1; } + else if (sscanf(line, "[buffer uav %u]\n", &index)) + { + state = STATE_RESOURCE; + + memset(¤t_resource, 0, sizeof(current_resource)); + + current_resource.slot = index; + current_resource.type = RESOURCE_TYPE_BUFFER_UAV; + current_resource.format = DXGI_FORMAT_R32G32B32A32_FLOAT; + current_resource.data_type = TEXTURE_DATA_FLOAT; + current_resource.texel_size = 16; + current_resource.level_count = 1; + } else if (sscanf(line, "[vertex buffer %u]\n", &index)) { state = STATE_RESOURCE; diff --git a/tests/shader_runner.h b/tests/shader_runner.h index 8962a8fc..7a2498f4 100644 --- a/tests/shader_runner.h +++ b/tests/shader_runner.h @@ -58,6 +58,7 @@ enum resource_type RESOURCE_TYPE_RENDER_TARGET, RESOURCE_TYPE_TEXTURE, RESOURCE_TYPE_UAV, + RESOURCE_TYPE_BUFFER_UAV, RESOURCE_TYPE_VERTEX_BUFFER, };
diff --git a/tests/shader_runner_d3d11.c b/tests/shader_runner_d3d11.c index a6b9c693..e9179b58 100644 --- a/tests/shader_runner_d3d11.c +++ b/tests/shader_runner_d3d11.c @@ -350,6 +350,7 @@ 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: + case RESOURCE_TYPE_BUFFER_UAV: { D3D11_SUBRESOURCE_DATA resource_data[2]; D3D11_TEXTURE2D_DESC desc = {0}; @@ -364,7 +365,7 @@ 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; - if (params->type == RESOURCE_TYPE_UAV) + if (params->type == RESOURCE_TYPE_UAV || params->type == RESOURCE_TYPE_BUFFER_UAV) desc.BindFlags = D3D11_BIND_UNORDERED_ACCESS; else if (params->type == RESOURCE_TYPE_RENDER_TARGET) desc.BindFlags = D3D11_BIND_RENDER_TARGET; @@ -394,7 +395,7 @@ static struct resource *d3d11_runner_create_resource(struct shader_runner *r, co ok(hr == S_OK, "Failed to create texture, hr %#lx.\n", hr);
resource->resource = (ID3D11Resource *)resource->texture; - if (params->type == RESOURCE_TYPE_UAV) + if (params->type == RESOURCE_TYPE_UAV || params->type == RESOURCE_TYPE_BUFFER_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); @@ -485,6 +486,7 @@ 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;
@@ -571,6 +573,7 @@ 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; diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index c73dbf64..7d9d1cd2 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -145,6 +145,7 @@ static struct resource *d3d12_runner_create_resource(struct shader_runner *r, co break;
case RESOURCE_TYPE_UAV: + case RESOURCE_TYPE_BUFFER_UAV: if (!runner->heap) runner->heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, MAX_RESOURCE_DESCRIPTORS); @@ -213,6 +214,7 @@ 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;
resource->root_index = root_signature_desc.NumParameters++; @@ -314,6 +316,7 @@ static bool d3d12_runner_dispatch(struct shader_runner *r, unsigned int x, unsig break;
case RESOURCE_TYPE_UAV: + case RESOURCE_TYPE_BUFFER_UAV: ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, resource->root_index, get_gpu_descriptor_handle(test_context, runner->heap, resource->r.slot + MAX_RESOURCES)); break; @@ -447,6 +450,7 @@ static bool d3d12_runner_draw(struct shader_runner *r, break;
case RESOURCE_TYPE_UAV: + case RESOURCE_TYPE_BUFFER_UAV: ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, resource->root_index, get_gpu_descriptor_handle(test_context, runner->heap, resource->r.slot + MAX_RESOURCES)); break; diff --git a/tests/shader_runner_d3d9.c b/tests/shader_runner_d3d9.c index 973b2342..15a5ab3e 100644 --- a/tests/shader_runner_d3d9.c +++ b/tests/shader_runner_d3d9.c @@ -258,6 +258,7 @@ 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;
@@ -383,6 +384,7 @@ 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_vulkan.c b/tests/shader_runner_vulkan.c index 670a454d..ce9ac7e8 100644 --- a/tests/shader_runner_vulkan.c +++ b/tests/shader_runner_vulkan.c @@ -34,8 +34,9 @@ struct vulkan_resource struct resource r;
VkBuffer buffer; + VkBufferView buffer_view; VkImage image; - VkImageView view; + VkImageView image_view; VkDeviceMemory memory;
uint32_t binding; @@ -177,6 +178,21 @@ static VkBuffer create_buffer(const struct vulkan_shader_runner *runner, VkDevic return buffer; }
+static VkBufferView create_buffer_view(const struct vulkan_shader_runner *runner, VkBuffer buffer, + VkFormat format) +{ + VkBufferViewCreateInfo view_info = {.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO}; + VkBufferView view; + + view_info.buffer = buffer; + view_info.format = format; + view_info.range = VK_WHOLE_SIZE; + + VK_CALL(vkCreateBufferView(runner->device, &view_info, NULL, &view)); + + return view; +} + static VkImage create_2d_image(const struct vulkan_shader_runner *runner, uint32_t width, uint32_t height, uint32_t level_count, VkImageUsageFlags usage, VkFormat format, VkDeviceMemory *memory) { @@ -249,7 +265,7 @@ static struct resource *vulkan_runner_create_resource(struct shader_runner *r, c
resource->image = create_2d_image(runner, params->width, params->height, params->level_count, 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); + resource->image_view = create_2d_image_view(runner, resource->image, format);
begin_command_buffer(runner); transition_image_layout(runner, resource->image, @@ -274,7 +290,7 @@ static struct resource *vulkan_runner_create_resource(struct shader_runner *r, c
resource->image = create_2d_image(runner, params->width, params->height, params->level_count, usage, format, &resource->memory); - resource->view = create_2d_image_view(runner, resource->image, format); + 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); @@ -315,6 +331,18 @@ static struct resource *vulkan_runner_create_resource(struct shader_runner *r, c 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)); + break; + case RESOURCE_TYPE_VERTEX_BUFFER: resource->buffer = create_buffer(runner, params->data_size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &resource->memory); @@ -338,10 +366,12 @@ static void vulkan_runner_destroy_resource(struct shader_runner *r, struct resou VK_CALL(vkFreeMemory(device, resource->memory, NULL)); if (resource->image) VK_CALL(vkDestroyImage(device, resource->image, NULL)); - if (resource->view) - VK_CALL(vkDestroyImageView(device, resource->view, NULL)); + if (resource->image_view) + VK_CALL(vkDestroyImageView(device, resource->image_view, NULL)); if (resource->buffer) VK_CALL(vkDestroyBuffer(device, resource->buffer, NULL)); + if (resource->buffer_view) + VK_CALL(vkDestroyBufferView(device, resource->buffer_view, NULL));
free(resource); } @@ -415,15 +445,19 @@ static bool compile_shader(const struct vulkan_shader_runner *runner, const char
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) + if (resource->r.type == RESOURCE_TYPE_UAV || resource->r.type == RESOURCE_TYPE_BUFFER_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; - binding->flags = VKD3D_SHADER_BINDING_FLAG_IMAGE; + if (resource->r.type == RESOURCE_TYPE_BUFFER_UAV) + binding->flags = VKD3D_SHADER_BINDING_FLAG_BUFFER; + else + binding->flags = VKD3D_SHADER_BINDING_FLAG_IMAGE; binding->binding.set = 0; binding->binding.binding = resource->binding; binding->binding.count = 1; @@ -596,6 +630,7 @@ static VkPipeline create_graphics_pipeline(const struct vulkan_shader_runner *ru { case RESOURCE_TYPE_TEXTURE: case RESOURCE_TYPE_UAV: + case RESOURCE_TYPE_BUFFER_UAV: break;
case RESOURCE_TYPE_RENDER_TARGET: @@ -724,6 +759,7 @@ 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++; @@ -731,6 +767,8 @@ static VkDescriptorSetLayout create_descriptor_set_layout(struct vulkan_shader_r 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; else binding->descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; binding->descriptorCount = 1; @@ -796,7 +834,7 @@ static void bind_resources(struct vulkan_shader_runner *runner, VkPipelineBindPo { case RESOURCE_TYPE_TEXTURE: case RESOURCE_TYPE_UAV: - image_info.imageView = resource->view; + image_info.imageView = resource->image_view; image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
write.dstSet = descriptor_set; @@ -815,6 +853,17 @@ static void bind_resources(struct vulkan_shader_runner *runner, VkPipelineBindPo VK_CALL(vkUpdateDescriptorSets(runner->device, 1, &write, 0, NULL)); break;
+ 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; + + VK_CALL(vkUpdateDescriptorSets(runner->device, 1, &write, 0, NULL)); + break; + case RESOURCE_TYPE_VERTEX_BUFFER: if (bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS) VK_CALL(vkCmdBindVertexBuffers(cmd_buffer, resource->r.slot, 1, &resource->buffer, &zero_offset)); @@ -867,7 +916,7 @@ static void create_render_pass_and_framebuffer(struct vulkan_shader_runner *runn color_ref->attachment = rt_count; color_ref->layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
- rtvs[rt_count] = resource->view; + rtvs[rt_count] = resource->image_view;
++rt_count; } @@ -1011,11 +1060,6 @@ static struct resource_readback *vulkan_runner_get_resource_readback(struct shad VkBufferImageCopy region = {0}; VkImageLayout layout;
- 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; rb->rb.depth = 1; @@ -1025,24 +1069,42 @@ 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);
- begin_command_buffer(runner); + if (resource->r.type == RESOURCE_TYPE_BUFFER_UAV) + { + void *data; + + VK_CALL(vkMapMemory(device, resource->memory, 0, VK_WHOLE_SIZE, 0, &data)); + VK_CALL(vkMapMemory(device, rb->memory, 0, VK_WHOLE_SIZE, 0, &rb->rb.data)); + memcpy(rb->rb.data, data, rb->rb.row_pitch * rb->rb.height); + VK_CALL(vkUnmapMemory(device, resource->memory)); + } + else + { + if (resource->r.type == RESOURCE_TYPE_RENDER_TARGET) + layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + else + layout = VK_IMAGE_LAYOUT_GENERAL;
- transition_image_layout(runner, resource->image, layout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + begin_command_buffer(runner);
- region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - region.imageSubresource.layerCount = 1; - region.imageExtent.width = resource->r.width; - region.imageExtent.height = resource->r.height; - region.imageExtent.depth = 1; + transition_image_layout(runner, resource->image, layout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
- VK_CALL(vkCmdCopyImageToBuffer(runner->cmd_buffer, resource->image, - VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, rb->buffer, 1, ®ion)); + region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + region.imageSubresource.layerCount = 1; + region.imageExtent.width = resource->r.width; + region.imageExtent.height = resource->r.height; + region.imageExtent.depth = 1;
- transition_image_layout(runner, resource->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, layout); + VK_CALL(vkCmdCopyImageToBuffer(runner->cmd_buffer, resource->image, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, rb->buffer, 1, ®ion));
- end_command_buffer(runner); + transition_image_layout(runner, resource->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, layout); + + end_command_buffer(runner); + + VK_CALL(vkMapMemory(device, rb->memory, 0, VK_WHOLE_SIZE, 0, &rb->rb.data)); + }
- VK_CALL(vkMapMemory(device, rb->memory, 0, VK_WHOLE_SIZE, 0, &rb->rb.data)); return &rb->rb; }
@@ -1141,7 +1203,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[3]; + VkDescriptorPoolSize descriptor_pool_sizes[4]; static const float queue_priority = 1.0f; VkFormatProperties format_props; uint32_t count, graphics_index; @@ -1253,6 +1315,8 @@ static bool init_vulkan_runner(struct vulkan_shader_runner *runner) 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_sizes[3].type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; + descriptor_pool_sizes[3].descriptorCount = MAX_RESOURCES;
descriptor_pool_desc.maxSets = 1; descriptor_pool_desc.poolSizeCount = ARRAY_SIZE(descriptor_pool_sizes); diff --git a/tests/vulkan_procs.h b/tests/vulkan_procs.h index 9d70b499..1829133b 100644 --- a/tests/vulkan_procs.h +++ b/tests/vulkan_procs.h @@ -65,6 +65,7 @@ VK_DEVICE_PFN(vkCmdFillBuffer) VK_DEVICE_PFN(vkCmdPipelineBarrier) VK_DEVICE_PFN(vkCmdPushConstants) VK_DEVICE_PFN(vkCreateBuffer) +VK_DEVICE_PFN(vkCreateBufferView) VK_DEVICE_PFN(vkCreateCommandPool) VK_DEVICE_PFN(vkCreateComputePipelines) VK_DEVICE_PFN(vkCreateDescriptorPool) @@ -78,6 +79,7 @@ VK_DEVICE_PFN(vkCreateRenderPass) VK_DEVICE_PFN(vkCreateSampler) VK_DEVICE_PFN(vkCreateShaderModule) VK_DEVICE_PFN(vkDestroyBuffer) +VK_DEVICE_PFN(vkDestroyBufferView) VK_DEVICE_PFN(vkDestroyCommandPool) VK_DEVICE_PFN(vkDestroyDescriptorPool) VK_DEVICE_PFN(vkDestroyDescriptorSetLayout)
From: Nikolay Sivov nsivov@codeweavers.com
--- tests/d3d12.c | 124 ++++++++++++++++++------------------ tests/d3d12_test_utils.h | 20 +++--- tests/hlsl_d3d12.c | 6 +- tests/shader_runner_d3d12.c | 2 +- 4 files changed, 76 insertions(+), 76 deletions(-)
diff --git a/tests/d3d12.c b/tests/d3d12.c index 23e1e97c..307e57f1 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -271,13 +271,13 @@ static const struct uvec4 *get_readback_uvec4(struct resource_readback *rb, unsi }
#define check_sub_resource_float(a, b, c, d, e, f) check_sub_resource_float_(__LINE__, a, b, c, d, e, f) -static void check_sub_resource_float_(unsigned int line, ID3D12Resource *texture, +static void check_sub_resource_float_(unsigned int line, ID3D12Resource *resource, unsigned int sub_resource_idx, ID3D12CommandQueue *queue, ID3D12GraphicsCommandList *command_list, float expected, unsigned int max_diff) { struct d3d12_resource_readback rb;
- get_texture_readback_with_command_list(texture, sub_resource_idx, &rb, queue, command_list); + get_resource_readback_with_command_list(resource, sub_resource_idx, &rb, queue, command_list); check_readback_data_float_(line, &rb.rb, NULL, expected, max_diff); release_resource_readback(&rb); } @@ -312,13 +312,13 @@ static void check_readback_data_uint8_(unsigned int line, struct resource_readba }
#define check_sub_resource_uint8(a, b, c, d, e, f) check_sub_resource_uint8_(__LINE__, a, b, c, d, e, f) -static void check_sub_resource_uint8_(unsigned int line, ID3D12Resource *texture, +static void check_sub_resource_uint8_(unsigned int line, ID3D12Resource *resource, unsigned int sub_resource_idx, ID3D12CommandQueue *queue, ID3D12GraphicsCommandList *command_list, uint8_t expected, unsigned int max_diff) { struct d3d12_resource_readback rb;
- get_texture_readback_with_command_list(texture, sub_resource_idx, &rb, queue, command_list); + get_resource_readback_with_command_list(resource, sub_resource_idx, &rb, queue, command_list); check_readback_data_uint8_(line, &rb.rb, NULL, expected, max_diff); release_resource_readback(&rb); } @@ -353,13 +353,13 @@ static void check_readback_data_uint16_(unsigned int line, struct resource_readb }
#define check_sub_resource_uint16(a, b, c, d, e, f) check_sub_resource_uint16_(__LINE__, a, b, c, d, e, f) -static void check_sub_resource_uint16_(unsigned int line, ID3D12Resource *texture, +static void check_sub_resource_uint16_(unsigned int line, ID3D12Resource *resource, unsigned int sub_resource_idx, ID3D12CommandQueue *queue, ID3D12GraphicsCommandList *command_list, uint16_t expected, unsigned int max_diff) { struct d3d12_resource_readback rb;
- get_texture_readback_with_command_list(texture, sub_resource_idx, &rb, queue, command_list); + get_resource_readback_with_command_list(resource, sub_resource_idx, &rb, queue, command_list); check_readback_data_uint16_(line, &rb.rb, NULL, expected, max_diff); release_resource_readback(&rb); } @@ -394,19 +394,19 @@ static void check_readback_data_uint64_(unsigned int line, struct resource_readb }
#define check_sub_resource_uint64(a, b, c, d, e, f) check_sub_resource_uint64_(__LINE__, a, b, c, d, e, f) -static void check_sub_resource_uint64_(unsigned int line, ID3D12Resource *texture, +static void check_sub_resource_uint64_(unsigned int line, ID3D12Resource *resource, unsigned int sub_resource_idx, ID3D12CommandQueue *queue, ID3D12GraphicsCommandList *command_list, uint64_t expected, unsigned int max_diff) { struct d3d12_resource_readback rb;
- get_texture_readback_with_command_list(texture, sub_resource_idx, &rb, queue, command_list); + get_resource_readback_with_command_list(resource, sub_resource_idx, &rb, queue, command_list); check_readback_data_uint64_(line, &rb.rb, NULL, expected, max_diff); release_resource_readback(&rb); }
#define check_sub_resource_uvec4(a, b, c, d, e) check_sub_resource_uvec4_(__LINE__, a, b, c, d, e) -static void check_sub_resource_uvec4_(unsigned int line, ID3D12Resource *texture, +static void check_sub_resource_uvec4_(unsigned int line, ID3D12Resource *resource, unsigned int sub_resource_idx, ID3D12CommandQueue *queue, ID3D12GraphicsCommandList *command_list, const struct uvec4 *expected_value) { @@ -415,7 +415,7 @@ static void check_sub_resource_uvec4_(unsigned int line, ID3D12Resource *texture unsigned int x = 0, y; bool all_match = true;
- get_texture_readback_with_command_list(texture, sub_resource_idx, &rb, queue, command_list); + get_resource_readback_with_command_list(resource, sub_resource_idx, &rb, queue, command_list); for (y = 0; y < rb.rb.height; ++y) { for (x = 0; x < rb.rb.width; ++x) @@ -4762,7 +4762,7 @@ static void test_clear_render_target_view(void) ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtv_handle, green, 0, NULL); transition_resource_state(command_list, resource, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); - get_texture_readback_with_command_list(resource, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(resource, 0, &rb, queue, command_list); set_box(&box, 0, 0, 0, 32, 32, 2); check_readback_data_uint(&rb.rb, &box, 0xbf4c7f19, 1); set_box(&box, 0, 0, 2, 32, 32, 4); @@ -4781,7 +4781,7 @@ static void test_clear_render_target_view(void) ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtv_handle, green, 0, NULL); transition_resource_state(command_list, resource, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); - get_texture_readback_with_command_list(resource, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(resource, 0, &rb, queue, command_list); set_box(&box, 0, 0, 4, 32, 32, 30); check_readback_data_uint(&rb.rb, &box, 0xbf4c7f19, 1); set_box(&box, 0, 0, 30, 32, 32, 32); @@ -5221,7 +5221,7 @@ static void test_clear_unordered_access_view_image(void)
for (layer = 0; layer < tests[i].image_layers / image_depth; ++layer) { - get_texture_readback_with_command_list(texture, + get_resource_readback_with_command_list(texture, tests[i].mip_level + (layer * tests[i].image_mips), &rb, queue, command_list);
@@ -6092,7 +6092,7 @@ static void test_append_aligned_element(void)
transition_resource_state(command_list, context.render_target, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); - get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); color = get_readback_uint(&rb.rb, 80, 16, 0); ok(compare_color(color, 0xff0000ff, 1), "Got unexpected color 0x%08x.\n", color); color = get_readback_uint(&rb.rb, 240, 16, 0); @@ -6370,7 +6370,7 @@ static void test_fragment_coords(void) transition_resource_state(command_list, context.render_target, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
- get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); all_match = true; for (y = 0; y < rb.rb.height; ++y) { @@ -6532,7 +6532,7 @@ static void test_fractional_viewports(void) transition_resource_state(command_list, context.render_target, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
- get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); for (y = 0; y < rb.rb.height; ++y) { for (x = 0; x < rb.rb.width; ++x) @@ -6611,7 +6611,7 @@ static void test_scissor(void) transition_resource_state(command_list, context.render_target, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
- get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); color = get_readback_uint(&rb.rb, 320, 60, 0); ok(compare_color(color, 0xff0000ff, 1), "Got unexpected color 0x%08x.\n", color); color = get_readback_uint(&rb.rb, 80, 240, 0); @@ -6848,7 +6848,7 @@ static void test_draw_depth_only(void) } transition_resource_state(command_list, ds.texture, D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_COPY_SOURCE); - get_texture_readback_with_command_list(ds.texture, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(ds.texture, 0, &rb, queue, command_list); for (i = 0; i < 4; ++i) { for (j = 0; j < 4; ++j) @@ -7498,7 +7498,7 @@ static void test_bundle_state_inheritance(void) transition_resource_state(command_list, context.render_target, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
- get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); for (y = 0; y < rb.rb.height; ++y) { for (x = 0; x < rb.rb.width; ++x) @@ -7535,7 +7535,7 @@ static void test_bundle_state_inheritance(void) transition_resource_state(command_list, context.render_target, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
- get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); for (y = 0; y < rb.rb.height; ++y) { for (x = 0; x < rb.rb.width; ++x) @@ -13505,7 +13505,7 @@ static void test_sample_instructions(void)
x_step = desc.rt_width / tests[i].texture->width; y_step = desc.rt_height / tests[i].texture->height; - get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); for (y = 0; y < tests[i].texture->height; ++y) { for (x = 0; x < tests[i].texture->width; ++x) @@ -13957,7 +13957,7 @@ static void test_gather(void)
transition_resource_state(command_list, context.render_target, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); - get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); for (y = 0; y < rb.rb.height; ++y) { for (x = 0; x < rb.rb.width; ++x) @@ -13995,7 +13995,7 @@ static void test_gather(void)
transition_resource_state(command_list, context.render_target, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); - get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); for (y = 0; y < rb.rb.height; ++y) { for (x = 0; x < rb.rb.width; ++x) @@ -14033,7 +14033,7 @@ static void test_gather(void)
transition_resource_state(command_list, context.render_target, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); - get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); for (y = 0; y < rb.rb.height; ++y) { for (x = 0; x < rb.rb.width; ++x) @@ -14071,7 +14071,7 @@ static void test_gather(void)
transition_resource_state(command_list, context.render_target, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); - get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); for (y = 0; y < rb.rb.height; ++y) { for (x = 0; x < rb.rb.width; ++x) @@ -14107,7 +14107,7 @@ static void test_gather(void)
transition_resource_state(command_list, context.render_target, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); - get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); for (y = 0; y < rb.rb.height; ++y) { for (x = 0; x < rb.rb.width; ++x) @@ -14297,7 +14297,7 @@ static void test_gather_c(void)
transition_resource_state(command_list, context.render_target, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); - get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); for (y = 0; y < rb.rb.height; ++y) { for (x = 0; x < rb.rb.width; ++x) @@ -14335,7 +14335,7 @@ static void test_gather_c(void)
transition_resource_state(command_list, context.render_target, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); - get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); for (y = 0; y < rb.rb.height; ++y) { for (x = 0; x < rb.rb.width; ++x) @@ -14371,7 +14371,7 @@ static void test_gather_c(void)
transition_resource_state(command_list, context.render_target, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); - get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); for (y = 0; y < rb.rb.height; ++y) { for (x = 0; x < rb.rb.width; ++x) @@ -14804,7 +14804,7 @@ static void test_sample_c_lz(void) transition_resource_state(command_list, context.render_target, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
- get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); /* Avoid testing values affected by seamless cube map filtering. */ set_rect(&rect, 100, 100, 540, 380); check_readback_data_float(&rb.rb, &rect, tests[i].expected, 2); @@ -14856,7 +14856,7 @@ static void test_sample_c_lz(void) transition_resource_state(command_list, context.render_target, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
- get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); /* Avoid testing values affected by seamless cube map filtering. */ set_rect(&rect, 100, 100, 540, 380); check_readback_data_float(&rb.rb, &rect, tests[i].expected, 2); @@ -16704,7 +16704,7 @@ static void test_update_descriptor_tables(void)
transition_resource_state(command_list, context.render_target, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); - get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); set_box(&box, 0, 0, 0, 16, 32, 1); check_readback_data_uint(&rb.rb, &box, 0xff00407f, 1); set_box(&box, 16, 0, 0, 32, 32, 1); @@ -16837,7 +16837,7 @@ static void test_update_descriptor_heap_after_closing_command_list(void)
transition_resource_state(command_list, context.render_target, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); - get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); value = get_readback_uint(&rb.rb, 0, 0, 0); todo_if(binding_tier < D3D12_RESOURCE_BINDING_TIER_3) ok(value == 0xff00ff00, "Got unexpected value %#x.\n", value); @@ -18329,7 +18329,7 @@ static void test_copy_descriptors_range_sizes(void) transition_resource_state(command_list, context.render_target, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
- get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); for (i = 0; i < desc.rt_width; ++i) { set_box(&box, i, 0, 0, i + 1, desc.rt_height, 1); @@ -22170,7 +22170,7 @@ static void test_uav_load(void) transition_sub_resource_state(command_list, rt_texture, 0, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
- get_texture_readback_with_command_list(rt_texture, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(rt_texture, 0, &rb, queue, command_list); for (y = 0; y < 4; ++y) { for (x = 0; x < 4; ++x) @@ -22520,7 +22520,7 @@ static void test_cs_uav_store(void)
transition_sub_resource_state(command_list, resource, 0, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE); - get_texture_readback_with_command_list(resource, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(resource, 0, &rb, queue, command_list); set_rect(&rect, 0, 0, 16, 32); check_readback_data_float(&rb.rb, &rect, 0.5f, 2); set_rect(&rect, 0, 32, rb.rb.width, rb.rb.height); @@ -22550,7 +22550,7 @@ static void test_cs_uav_store(void)
transition_sub_resource_state(command_list, resource, 0, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE); - get_texture_readback_with_command_list(resource, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(resource, 0, &rb, queue, command_list); set_rect(&rect, 0, 0, 60, 60); check_readback_data_float(&rb.rb, &rect, 0.6f, 2); set_rect(&rect, 0, 60, rb.rb.width, rb.rb.height); @@ -23720,7 +23720,7 @@ static void test_buffer_srv(void) transition_sub_resource_state(command_list, context.render_target, 0, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
- get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); for (y = 0; y < 4; ++y) { for (x = 0; x < 4; ++x) @@ -24598,7 +24598,7 @@ static void test_execute_indirect(void)
transition_resource_state(command_list, context.render_target, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); - get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); set_box(&box, 0, 0, 0, 32, 8, 1); check_readback_data_uint(&rb.rb, &box, 0xffffff00, 0); set_box(&box, 24, 8, 0, 32, 32, 1); @@ -25184,14 +25184,14 @@ static void test_instance_id(void)
transition_resource_state(command_list, context.render_target, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); - get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); for (j = 0; j < ARRAY_SIZE(expected_results); ++j) check_readback_data_uint(&rb.rb, &expected_results[j].box, tests[i].expected_colors[j], 1); release_resource_readback(&rb); reset_command_list(command_list, context.allocator); transition_resource_state(command_list, render_target, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); - get_texture_readback_with_command_list(render_target, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(render_target, 0, &rb, queue, command_list); for (j = 0; j < ARRAY_SIZE(expected_results); ++j) check_readback_data_uint(&rb.rb, &expected_results[j].box, expected_results[j].instance_id, 0); release_resource_readback(&rb); @@ -25618,7 +25618,7 @@ static void test_copy_texture(void)
transition_resource_state(command_list, dst_texture, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COPY_SOURCE); - get_texture_readback_with_command_list(dst_texture, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(dst_texture, 0, &rb, queue, command_list); for (y = 0; y < 4; ++y) { for (x = 0; x < 4; ++x) @@ -25988,7 +25988,7 @@ static void test_copy_buffer_texture(void) D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COPY_SOURCE);
got = expected = 0; - get_texture_readback_with_command_list(dst_texture, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(dst_texture, 0, &rb, queue, command_list); for (z = 0; z < 64; ++z) { for (y = 0; y < 100; ++y) @@ -26020,7 +26020,7 @@ static void test_copy_buffer_texture(void)
reset_command_list(command_list, context.allocator); got = expected = 0; - get_texture_readback_with_command_list(dst_texture, 1, &rb, queue, command_list); + get_resource_readback_with_command_list(dst_texture, 1, &rb, queue, command_list); for (z = 0; z < 32; ++z) { for (y = 0; y < 50; ++y) @@ -26163,7 +26163,7 @@ static void test_copy_block_compressed_texture(void) transition_resource_state(command_list, dst_buffer, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COPY_SOURCE);
- get_texture_readback_with_command_list(texture, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(texture, 0, &rb, queue, command_list); for (y = 0; y < 8 / format_block_height(DXGI_FORMAT_BC2_UNORM); ++y) { for (x = 0; x < 8 / format_block_width(DXGI_FORMAT_BC2_UNORM); ++x) @@ -26195,7 +26195,7 @@ static void test_copy_block_compressed_texture(void) got.x, got.y, got.z, got.w, x, y, expected.x, expected.y, expected.z, expected.w);
reset_command_list(command_list, context.allocator); - get_texture_readback_with_command_list(texture, 2, &rb, queue, command_list); + get_resource_readback_with_command_list(texture, 2, &rb, queue, command_list); block_id = 1; expected.x = block_id << 8 | 0; expected.y = block_id << 8 | 1; @@ -26208,7 +26208,7 @@ static void test_copy_block_compressed_texture(void) got.x, got.y, got.z, got.w, expected.x, expected.y, expected.z, expected.w);
reset_command_list(command_list, context.allocator); - get_texture_readback_with_command_list(texture, 3, &rb, queue, command_list); + get_resource_readback_with_command_list(texture, 3, &rb, queue, command_list); block_id = 2; expected.x = block_id << 8 | 0; expected.y = block_id << 8 | 1; @@ -27175,7 +27175,7 @@ static void test_geometry_shader(void) transition_resource_state(command_list, texture, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
- get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); color = get_readback_uint(&rb.rb, 320, 190, 0); ok(compare_color(color, 0xff0000ff, 1), "Got unexpected color 0x%08x.\n", color); color = get_readback_uint(&rb.rb, 255, 240, 0); @@ -27189,7 +27189,7 @@ static void test_geometry_shader(void) release_resource_readback(&rb);
reset_command_list(command_list, context.allocator); - get_texture_readback_with_command_list(texture, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(texture, 0, &rb, queue, command_list); color = get_readback_uint(&rb.rb, 320, 190, 0); ok(compare_color(color, 0xff0000ff, 1), "Got unexpected color 0x%08x.\n", color); color = get_readback_uint(&rb.rb, 255, 240, 0); @@ -30216,7 +30216,7 @@ static void check_clip_distance(struct test_context *context, ID3D12PipelineStat ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 1, 0, 0); transition_resource_state(command_list, context->render_target, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); - get_texture_readback_with_command_list(context->render_target, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(context->render_target, 0, &rb, queue, command_list); set_box(&box, 0, 0, 0, 320, 480, 1); check_readback_data_uint(&rb.rb, &box, 0xff00ff00, 1); set_box(&box, 320, 0, 0, 320, 480, 1); @@ -30249,7 +30249,7 @@ static void check_clip_distance(struct test_context *context, ID3D12PipelineStat ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 1, 0, 0); transition_resource_state(command_list, context->render_target, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); - get_texture_readback_with_command_list(context->render_target, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(context->render_target, 0, &rb, queue, command_list); set_box(&box, 0, 0, 0, 640, 240, 1); check_readback_data_uint(&rb.rb, &box, 0xff00ff00, 0); set_box(&box, 0, 240, 0, 640, 240, 1); @@ -30890,7 +30890,7 @@ static void test_clip_distance(void) transition_resource_state(command_list, context.render_target, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
- get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); set_box(&box, 0, 0, 0, 320, 240, 1); check_readback_data_uint(&rb.rb, &box, 0xff00ff00, 1); set_box(&box, 0, 240, 0, 320, 480, 1); @@ -31149,7 +31149,7 @@ static void test_combined_clip_and_cull_distances(void) } else { - get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); color = get_readback_uint(&rb.rb, 160, 240, 0); ok(color == expected_color[0], "Got unexpected color 0x%08x.\n", color); color = get_readback_uint(&rb.rb, 480, 240, 0); @@ -31435,7 +31435,7 @@ static void test_64kb_texture_alignment(void) reset_command_list(command_list, context.allocator); transition_resource_state(command_list, textures[1], D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COPY_SOURCE); - get_texture_readback_with_command_list(textures[1], 0, &rb, queue, command_list); + get_resource_readback_with_command_list(textures[1], 0, &rb, queue, command_list); set_box(&box, 0, 0, 0, resource_desc.Width, resource_desc.Height, 1); check_readback_data_uint(&rb.rb, &box, 0xcafef00d, 0); release_resource_readback(&rb); @@ -31448,7 +31448,7 @@ static void test_64kb_texture_alignment(void)
/* If the heap could not be used, the texture is not aliased. */ reset_command_list(command_list, context.allocator); - get_texture_readback_with_command_list(textures[1], 0, &rb, queue, command_list); + get_resource_readback_with_command_list(textures[1], 0, &rb, queue, command_list); check_readback_data_uint(&rb.rb, &box, 0xdeadbeef, 0); release_resource_readback(&rb);
@@ -32533,7 +32533,7 @@ static void test_shader_sample_position(void) transition_resource_state(command_list, readback_texture, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COPY_SOURCE);
- get_texture_readback_with_command_list(readback_texture, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(readback_texture, 0, &rb, queue, command_list); for (i = 0; i < resource_desc.SampleDesc.Count; ++i) { const struct vec4 *position = get_readback_vec4(&rb.rb, i, 0); @@ -32885,7 +32885,7 @@ static void test_primitive_restart(void)
transition_resource_state(command_list, context.render_target, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); - get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); if (tests[i].full_quad) { todo_if(tests[i].is_todo) @@ -33250,7 +33250,7 @@ static void test_read_write_subresource(void)
transition_resource_state(command_list, dst_texture, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COPY_SOURCE); - get_texture_readback_with_command_list(dst_texture, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(dst_texture, 0, &rb, queue, command_list); for (z = 0; z < 64; ++z) { for (y = 0; y < 100; ++y) @@ -34062,7 +34062,7 @@ static void test_conditional_rendering(void) transition_resource_state(command_list, context.render_target, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
- get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); bug_if(is_radv_device(context.device)) todo check_readback_data_uint(&rb.rb, NULL, 0xffffffff, 0); release_resource_readback(&rb); @@ -34115,7 +34115,7 @@ static void test_conditional_rendering(void) transition_resource_state(command_list, context.render_target, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
- get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(context.render_target, 0, &rb, queue, command_list); todo check_readback_data_uint(&rb.rb, NULL, 0xffffffff, 0); release_resource_readback(&rb); reset_command_list(command_list, context.allocator); @@ -34232,7 +34232,7 @@ static void test_conditional_rendering(void) transition_resource_state(command_list, texture_copy, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COPY_SOURCE);
- get_texture_readback_with_command_list(texture_copy, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(texture_copy, 0, &rb, queue, command_list); todo check_readback_data_uint(&rb.rb, NULL, r8g8b8a8_data[1], 0); release_resource_readback(&rb);
@@ -34297,7 +34297,7 @@ static void test_conditional_rendering(void) transition_resource_state(command_list, texture_copy, D3D12_RESOURCE_STATE_RESOLVE_DEST, D3D12_RESOURCE_STATE_COPY_SOURCE);
- get_texture_readback_with_command_list(texture_copy, 0, &rb, queue, command_list); + get_resource_readback_with_command_list(texture_copy, 0, &rb, queue, command_list); bug_if(is_radv_device(context.device)) todo check_readback_data_uint(&rb.rb, NULL, r8g8b8a8_data[1], 0); release_resource_readback(&rb); diff --git a/tests/d3d12_test_utils.h b/tests/d3d12_test_utils.h index b6a99d43..47f24334 100644 --- a/tests/d3d12_test_utils.h +++ b/tests/d3d12_test_utils.h @@ -417,7 +417,7 @@ struct d3d12_resource_readback ID3D12Resource *resource; };
-static void get_texture_readback_with_command_list(ID3D12Resource *texture, unsigned int sub_resource, +static void get_resource_readback_with_command_list(ID3D12Resource *resource, unsigned int sub_resource, struct d3d12_resource_readback *rb, ID3D12CommandQueue *queue, ID3D12GraphicsCommandList *command_list) { D3D12_TEXTURE_COPY_LOCATION dst_location, src_location; @@ -430,12 +430,12 @@ static void get_texture_readback_with_command_list(ID3D12Resource *texture, unsi uint64_t buffer_size; HRESULT hr;
- hr = ID3D12Resource_GetDevice(texture, &IID_ID3D12Device, (void **)&device); + hr = ID3D12Resource_GetDevice(resource, &IID_ID3D12Device, (void **)&device); assert_that(hr == S_OK, "Failed to get device, hr %#x.\n", hr);
- resource_desc = ID3D12Resource_GetDesc(texture); + resource_desc = ID3D12Resource_GetDesc(resource); assert_that(resource_desc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER, - "Resource %p is not texture.\n", texture); + "Resource %p is not texture.\n", resource);
miplevel = sub_resource % resource_desc.MipLevels; rb->rb.width = max(1, resource_desc.Width >> miplevel); @@ -459,10 +459,10 @@ static void get_texture_readback_with_command_list(ID3D12Resource *texture, unsi hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE, &resource_desc, D3D12_RESOURCE_STATE_RESOLVE_DEST, NULL, &IID_ID3D12Resource, (void **)&src_resource); - assert_that(hr == S_OK, "Failed to create texture, hr %#x.\n", hr); + assert_that(hr == S_OK, "Failed to create resource, hr %#x.\n", hr);
ID3D12GraphicsCommandList_ResolveSubresource(command_list, - src_resource, 0, texture, sub_resource, resource_desc.Format); + src_resource, 0, resource, sub_resource, resource_desc.Format); transition_resource_state(command_list, src_resource, D3D12_RESOURCE_STATE_RESOLVE_DEST, D3D12_RESOURCE_STATE_COPY_SOURCE);
@@ -470,7 +470,7 @@ static void get_texture_readback_with_command_list(ID3D12Resource *texture, unsi } else { - src_resource = texture; + src_resource = resource; }
buffer_size = rb->rb.row_pitch * rb->rb.height * rb->rb.depth; @@ -497,7 +497,7 @@ static void get_texture_readback_with_command_list(ID3D12Resource *texture, unsi wait_queue_idle(device, queue); ID3D12Device_Release(device);
- if (src_resource != texture) + if (src_resource != resource) ID3D12Resource_Release(src_resource);
read_range.Begin = 0; @@ -560,7 +560,7 @@ static inline void check_sub_resource_uint_(unsigned int line, ID3D12Resource *t { struct d3d12_resource_readback rb;
- get_texture_readback_with_command_list(texture, sub_resource_idx, &rb, queue, command_list); + get_resource_readback_with_command_list(texture, sub_resource_idx, &rb, queue, command_list); check_readback_data_uint_(line, &rb.rb, NULL, expected, max_diff); release_resource_readback(&rb); } @@ -572,7 +572,7 @@ static inline void check_sub_resource_vec4_(unsigned int line, ID3D12Resource *t { struct d3d12_resource_readback rb;
- get_texture_readback_with_command_list(texture, sub_resource_idx, &rb, queue, command_list); + get_resource_readback_with_command_list(texture, sub_resource_idx, &rb, queue, command_list); check_readback_data_vec4_(line, &rb.rb, NULL, expected, max_diff); release_resource_readback(&rb); } diff --git a/tests/hlsl_d3d12.c b/tests/hlsl_d3d12.c index 16624024..85a1548f 100644 --- a/tests/hlsl_d3d12.c +++ b/tests/hlsl_d3d12.c @@ -502,7 +502,7 @@ static void test_thread_id(void)
transition_resource_state(command_list, textures[0], D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE); - get_texture_readback_with_command_list(textures[0], 0, &rb, context.queue, command_list); + get_resource_readback_with_command_list(textures[0], 0, &rb, context.queue, command_list); for (x = 0; x < 16; ++x) { for (y = 0; y < 8; ++y) @@ -525,7 +525,7 @@ static void test_thread_id(void)
transition_resource_state(command_list, textures[1], D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE); - get_texture_readback_with_command_list(textures[1], 0, &rb, context.queue, command_list); + get_resource_readback_with_command_list(textures[1], 0, &rb, context.queue, command_list); for (x = 0; x < 16; ++x) { for (y = 0; y < 8; ++y) @@ -548,7 +548,7 @@ static void test_thread_id(void)
transition_resource_state(command_list, textures[2], D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE); - get_texture_readback_with_command_list(textures[2], 0, &rb, context.queue, command_list); + get_resource_readback_with_command_list(textures[2], 0, &rb, context.queue, command_list); for (x = 0; x < 16; ++x) { for (y = 0; y < 8; ++y) diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index 7d9d1cd2..0fcc66da 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -498,7 +498,7 @@ static struct resource_readback *d3d12_runner_get_resource_readback(struct shade
transition_resource_state(test_context->list, resource->resource, state, D3D12_RESOURCE_STATE_COPY_SOURCE); - get_texture_readback_with_command_list(resource->resource, 0, rb, + get_resource_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,
From: Nikolay Sivov nsivov@codeweavers.com
--- tests/d3d12.c | 25 --------- tests/d3d12_test_utils.h | 101 ++++++++++++++++++++++++------------ tests/shader_runner_d3d12.c | 29 ++++++++++- 3 files changed, 96 insertions(+), 59 deletions(-)
diff --git a/tests/d3d12.c b/tests/d3d12.c index 307e57f1..dc850bff 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -137,31 +137,6 @@ static void uav_barrier(ID3D12GraphicsCommandList *list, ID3D12Resource *resourc ID3D12GraphicsCommandList_ResourceBarrier(list, 1, &barrier); }
-#define upload_buffer_data(a, b, c, d, e, f) upload_buffer_data_(__LINE__, a, b, c, d, e, f) -static void upload_buffer_data_(unsigned int line, ID3D12Resource *buffer, size_t offset, - size_t size, const void *data, ID3D12CommandQueue *queue, ID3D12GraphicsCommandList *command_list) -{ - ID3D12Resource *upload_buffer; - ID3D12Device *device; - HRESULT hr; - - hr = ID3D12Resource_GetDevice(buffer, &IID_ID3D12Device, (void **)&device); - ok_(line)(SUCCEEDED(hr), "Failed to get device, hr %#x.\n", hr); - - upload_buffer = create_upload_buffer_(line, device, size, data); - - ID3D12GraphicsCommandList_CopyBufferRegion(command_list, buffer, offset, - upload_buffer, 0, size); - - hr = ID3D12GraphicsCommandList_Close(command_list); - ok_(line)(SUCCEEDED(hr), "Failed to close command list, hr %#x.\n", hr); - exec_command_list(queue, command_list); - wait_queue_idle(device, queue); - - ID3D12Resource_Release(upload_buffer); - ID3D12Device_Release(device); -} - static const DXGI_FORMAT depth_stencil_formats[] = { DXGI_FORMAT_R32G8X24_TYPELESS, diff --git a/tests/d3d12_test_utils.h b/tests/d3d12_test_utils.h index 47f24334..dc6bf07f 100644 --- a/tests/d3d12_test_utils.h +++ b/tests/d3d12_test_utils.h @@ -420,7 +420,6 @@ struct d3d12_resource_readback static void get_resource_readback_with_command_list(ID3D12Resource *resource, unsigned int sub_resource, struct d3d12_resource_readback *rb, ID3D12CommandQueue *queue, ID3D12GraphicsCommandList *command_list) { - D3D12_TEXTURE_COPY_LOCATION dst_location, src_location; D3D12_HEAP_PROPERTIES heap_properties; D3D12_RESOURCE_DESC resource_desc; ID3D12Resource *src_resource; @@ -434,8 +433,6 @@ static void get_resource_readback_with_command_list(ID3D12Resource *resource, un assert_that(hr == S_OK, "Failed to get device, hr %#x.\n", hr);
resource_desc = ID3D12Resource_GetDesc(resource); - assert_that(resource_desc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER, - "Resource %p is not texture.\n", resource);
miplevel = sub_resource % resource_desc.MipLevels; rb->rb.width = max(1, resource_desc.Width >> miplevel); @@ -444,10 +441,13 @@ static void get_resource_readback_with_command_list(ID3D12Resource *resource, un rb->rb.height = align(rb->rb.height, format_block_height(resource_desc.Format)); rb->rb.depth = resource_desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D ? max(1, resource_desc.DepthOrArraySize >> miplevel) : 1; - rb->rb.row_pitch = align(rb->rb.width * format_size(resource_desc.Format), D3D12_TEXTURE_DATA_PITCH_ALIGNMENT); + rb->rb.row_pitch = rb->rb.width * format_size(resource_desc.Format); + if (resource_desc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER) + rb->rb.row_pitch = align(rb->rb.row_pitch, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT); rb->rb.data = NULL;
- if (resource_desc.SampleDesc.Count > 1) + src_resource = resource; + if (resource_desc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER && resource_desc.SampleDesc.Count > 1) { memset(&heap_properties, 0, sizeof(heap_properties)); heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT; @@ -468,28 +468,33 @@ static void get_resource_readback_with_command_list(ID3D12Resource *resource, un
sub_resource = 0; } - else - { - src_resource = resource; - }
buffer_size = rb->rb.row_pitch * rb->rb.height * rb->rb.depth; rb->resource = create_readback_buffer(device, buffer_size);
- dst_location.pResource = rb->resource; - dst_location.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; - dst_location.PlacedFootprint.Offset = 0; - dst_location.PlacedFootprint.Footprint.Format = resource_desc.Format; - dst_location.PlacedFootprint.Footprint.Width = rb->rb.width; - dst_location.PlacedFootprint.Footprint.Height = rb->rb.height; - dst_location.PlacedFootprint.Footprint.Depth = rb->rb.depth; - dst_location.PlacedFootprint.Footprint.RowPitch = rb->rb.row_pitch; - - src_location.pResource = src_resource; - src_location.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; - src_location.SubresourceIndex = sub_resource; - - ID3D12GraphicsCommandList_CopyTextureRegion(command_list, &dst_location, 0, 0, 0, &src_location, NULL); + if (resource_desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) + { + ID3D12GraphicsCommandList_CopyResource(command_list, rb->resource, resource); + } + else + { + D3D12_TEXTURE_COPY_LOCATION dst_location, src_location; + + dst_location.pResource = rb->resource; + dst_location.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + dst_location.PlacedFootprint.Offset = 0; + dst_location.PlacedFootprint.Footprint.Format = resource_desc.Format; + dst_location.PlacedFootprint.Footprint.Width = rb->rb.width; + dst_location.PlacedFootprint.Footprint.Height = rb->rb.height; + dst_location.PlacedFootprint.Footprint.Depth = rb->rb.depth; + dst_location.PlacedFootprint.Footprint.RowPitch = rb->rb.row_pitch; + + src_location.pResource = src_resource; + src_location.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + src_location.SubresourceIndex = sub_resource; + + ID3D12GraphicsCommandList_CopyTextureRegion(command_list, &dst_location, 0, 0, 0, &src_location, NULL); + } hr = ID3D12GraphicsCommandList_Close(command_list); assert_that(hr == S_OK, "Failed to close command list, hr %#x.\n", hr);
@@ -696,18 +701,25 @@ static inline void upload_texture_data_(unsigned int line, ID3D12Resource *textu } ID3D12Resource_Unmap(upload_buffer, 0, NULL);
- for (i = 0; i < sub_resource_count; ++i) + if (resource_desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) { - dst_location.pResource = texture; - dst_location.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; - dst_location.SubresourceIndex = i; + ID3D12GraphicsCommandList_CopyResource(command_list, texture, upload_buffer); + } + else + { + for (i = 0; i < sub_resource_count; ++i) + { + dst_location.pResource = texture; + dst_location.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + dst_location.SubresourceIndex = i;
- src_location.pResource = upload_buffer; - src_location.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; - src_location.PlacedFootprint = layouts[i]; + src_location.pResource = upload_buffer; + src_location.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + src_location.PlacedFootprint = layouts[i];
- ID3D12GraphicsCommandList_CopyTextureRegion(command_list, - &dst_location, 0, 0, 0, &src_location, NULL); + ID3D12GraphicsCommandList_CopyTextureRegion(command_list, + &dst_location, 0, 0, 0, &src_location, NULL); + } }
hr = ID3D12GraphicsCommandList_Close(command_list); @@ -724,6 +736,31 @@ static inline void upload_texture_data_(unsigned int line, ID3D12Resource *textu free(row_sizes); }
+#define upload_buffer_data(a, b, c, d, e, f) upload_buffer_data_(__LINE__, a, b, c, d, e, f) +static inline void upload_buffer_data_(unsigned int line, ID3D12Resource *buffer, size_t offset, + size_t size, const void *data, ID3D12CommandQueue *queue, ID3D12GraphicsCommandList *command_list) +{ + ID3D12Resource *upload_buffer; + ID3D12Device *device; + HRESULT hr; + + hr = ID3D12Resource_GetDevice(buffer, &IID_ID3D12Device, (void **)&device); + ok_(line)(SUCCEEDED(hr), "Failed to get device, hr %#x.\n", hr); + + upload_buffer = create_upload_buffer_(line, device, size, data); + + ID3D12GraphicsCommandList_CopyBufferRegion(command_list, buffer, offset, + upload_buffer, 0, size); + + hr = ID3D12GraphicsCommandList_Close(command_list); + ok_(line)(SUCCEEDED(hr), "Failed to close command list, hr %#x.\n", hr); + exec_command_list(queue, command_list); + wait_queue_idle(device, queue); + + ID3D12Resource_Release(upload_buffer); + ID3D12Device_Release(device); +} + static HRESULT create_root_signature(ID3D12Device *device, const D3D12_ROOT_SIGNATURE_DESC *desc, ID3D12RootSignature **root_signature) { diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index 0fcc66da..6765c5ce 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -145,7 +145,6 @@ static struct resource *d3d12_runner_create_resource(struct shader_runner *r, co break;
case RESOURCE_TYPE_UAV: - case RESOURCE_TYPE_BUFFER_UAV: if (!runner->heap) runner->heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, MAX_RESOURCE_DESCRIPTORS); @@ -161,6 +160,30 @@ static struct resource *d3d12_runner_create_resource(struct shader_runner *r, co 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(resource->resource, 0, params->data_size, resource_data, + 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); + + 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; @@ -224,7 +247,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) + if (resource->r.type == RESOURCE_TYPE_UAV || resource->r.type == RESOURCE_TYPE_BUFFER_UAV) range->RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; else range->RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; @@ -432,6 +455,8 @@ static bool d3d12_runner_draw(struct shader_runner *r, if (runner->r.uniform_count) ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, uniform_index, runner->r.uniform_count, runner->r.uniforms, 0); + if (runner->heap) + ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &runner->heap); for (i = 0; i < runner->r.resource_count; ++i) { struct d3d12_resource *resource = d3d12_resource(runner->r.resources[i]);
From: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- tests/shader_runner_d3d11.c | 66 +++++++++++++++++++++++++++++-------- 1 file changed, 52 insertions(+), 14 deletions(-)
diff --git a/tests/shader_runner_d3d11.c b/tests/shader_runner_d3d11.c index e9179b58..3907e785 100644 --- a/tests/shader_runner_d3d11.c +++ b/tests/shader_runner_d3d11.c @@ -44,6 +44,7 @@ struct d3d11_resource struct resource r;
ID3D11Resource *resource; + ID3D11Buffer *buffer; ID3D11Texture2D *texture; ID3D11RenderTargetView *rtv; ID3D11ShaderResourceView *srv; @@ -350,7 +351,6 @@ 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: - case RESOURCE_TYPE_BUFFER_UAV: { D3D11_SUBRESOURCE_DATA resource_data[2]; D3D11_TEXTURE2D_DESC desc = {0}; @@ -365,7 +365,7 @@ 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; - if (params->type == RESOURCE_TYPE_UAV || params->type == RESOURCE_TYPE_BUFFER_UAV) + 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; @@ -395,7 +395,7 @@ static struct resource *d3d11_runner_create_resource(struct shader_runner *r, co ok(hr == S_OK, "Failed to create texture, hr %#lx.\n", hr);
resource->resource = (ID3D11Resource *)resource->texture; - if (params->type == RESOURCE_TYPE_UAV || params->type == RESOURCE_TYPE_BUFFER_UAV) + 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); @@ -405,9 +405,26 @@ static struct resource *d3d11_runner_create_resource(struct shader_runner *r, co 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); + break; + } + case RESOURCE_TYPE_VERTEX_BUFFER: - resource->resource = (ID3D11Resource *)create_buffer(device, - D3D11_BIND_VERTEX_BUFFER, params->data_size, params->data); + resource->buffer = create_buffer(device, D3D11_BIND_VERTEX_BUFFER, params->data_size, params->data); + resource->resource = (ID3D11Resource *)resource->buffer; break; }
@@ -652,15 +669,36 @@ static struct resource_readback *d3d11_runner_get_resource_readback(struct shade struct d3d11_resource *resource = d3d11_resource(res); D3D11_TEXTURE2D_DESC texture_desc; D3D11_MAPPED_SUBRESOURCE map_desc; + D3D11_BUFFER_DESC buffer_desc; HRESULT hr;
- 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); + 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); + break; + + case RESOURCE_TYPE_VERTEX_BUFFER: + case RESOURCE_TYPE_TEXTURE: + assert(0); + }
ID3D11DeviceContext_CopyResource(runner->immediate_context, rb->resource, resource->resource); hr = ID3D11DeviceContext_Map(runner->immediate_context, rb->resource, 0, D3D11_MAP_READ, 0, &map_desc); @@ -668,8 +706,8 @@ static struct resource_readback *d3d11_runner_get_resource_readback(struct shade
rb->rb.data = map_desc.pData; rb->rb.row_pitch = map_desc.RowPitch; - rb->rb.width = texture_desc.Width; - rb->rb.height = texture_desc.Height; + rb->rb.width = resource->r.width; + rb->rb.height = resource->r.height; rb->rb.depth = 1; return &rb->rb; }
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- tests/uav-rwbuffer.shader_test | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+)
diff --git a/tests/uav-rwbuffer.shader_test b/tests/uav-rwbuffer.shader_test index f6334a5c..9e6805a1 100644 --- a/tests/uav-rwbuffer.shader_test +++ b/tests/uav-rwbuffer.shader_test @@ -1,6 +1,15 @@ [require] shader model >= 5.0
+% UAVs are implicitly allocated starting from the highest render target slot. +% They cannot overlap render target slots, and also cannot be allocated any +% lower than the highest render target. +% This ceases to be true with shader model 5.1. + +[render target 1] +format r32g32b32a32 float +size (640, 480) + [pixel shader] struct s { @@ -62,3 +71,21 @@ float4 main() : sv_target1 { return 0; } + +[buffer uav 2] +size (1, 1) + +0.1 0.2 0.3 0.4 + +[pixel shader] +RWBuffer<float4> u : register(u2); + +float4 main() : sv_target1 +{ + u[0] = float4(11.1, 12.2, 13.3, 14.4); + return 0; +} + +[test] +draw quad +probe buffer uav 2 (0, 0) rgba (11.1, 12.2, 13.3, 14.4)
On Thu May 18 09:39:05 2023 +0000, Giovanni Mascellani wrote:
Yeah, approving changes quickly is precisely the reason why it's better to make commits as easy to review as possible.
Yes, I forgot about this part. Split now and pushed.
Giovanni Mascellani (@giomasce) commented about tests/shader_runner_vulkan.c:
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));
That's probably out of scope (since the problem already exists), but I don't think we're guaranteed to have coherent memory here, so we should flush before unmapping. Or request coherent memory (though in practice we're probably going to get coherent memory anyway).
This merge request was approved by Giovanni Mascellani.
This merge request was approved by Zebediah Figura.
Francisco Casas (@fcasas) commented about libs/vkd3d-shader/hlsl.y:
"UAV type %s is not numeric.", string->buffer); }
switch ($1)
{
case HLSL_SAMPLER_DIM_BUFFER:
case HLSL_SAMPLER_DIM_1D:
case HLSL_SAMPLER_DIM_2D:
case HLSL_SAMPLER_DIM_3D:
if ($3->class == HLSL_CLASS_ARRAY)
{
if (string)
hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
"This type of UAV does not support array type.");
}
else if (hlsl_type_component_count($3) > 4)
I suspect this should be the reg_size of HLSL_REGSET_NUMERIC instead, since types with <=4 components but with more than 4 32-bit components, such as `RWBuffer<double3>`, are not allowed.
On Fri May 19 06:25:39 2023 +0000, Francisco Casas wrote:
I suspect this should be the reg_size of HLSL_REGSET_NUMERIC instead, since types with <=4 components but with more than 4 32-bit components, such as `RWBuffer<double3>`, are not allowed.
Ah well, it makes sense.
On Fri May 19 09:12:35 2023 +0000, Giovanni Mascellani wrote:
Ah well, it makes sense.
This does not work for float2x2 for example. It probably should be using component_count * reg_size_of_component, or something like that. Except that we don't seem to support doubles. I'm going to add a todo for this.