diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 34e58f34..dcbba46e 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -6197,6 +6197,52 @@ static bool add_sample_grad_method_call(struct hlsl_ctx *ctx, struct hlsl_block return true; } +static bool add_store_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *object, + const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *offset, *rhs, *store; + struct hlsl_deref resource_deref; + unsigned int value_dim; + + if (params->args_count != 2) + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, + "Wrong number of arguments to method '%s': expected 2.", name); + return false; + } + + if (!strcmp(name, "Store")) + value_dim = 1; + else if (!strcmp(name, "Store2")) + value_dim = 2; + else if (!strcmp(name, "Store3")) + value_dim = 3; + else + value_dim = 4; + + if (!(offset = add_implicit_conversion(ctx, block, params->args[0], + hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc))) + return false; + + if (!(rhs = add_implicit_conversion(ctx, block, params->args[1], + hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, value_dim), loc))) + return false; + + if (!hlsl_init_deref_from_index_chain(ctx, &resource_deref, object)) + return false; + + if (!(store = hlsl_new_resource_store(ctx, &resource_deref, offset, rhs, loc))) + { + hlsl_cleanup_deref(&resource_deref); + return false; + } + + hlsl_block_add_instr(block, store); + hlsl_cleanup_deref(&resource_deref); + + return true; +} + static const struct method_function { const char *name; @@ -6204,7 +6250,7 @@ static const struct method_function const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc); char valid_dims[HLSL_SAMPLER_DIM_MAX + 1]; } -object_methods[] = +texture_methods[] = { { "Gather", add_gather_method_call, "00010101001000" }, { "GatherAlpha", add_gather_method_call, "00010101001000" }, @@ -6224,6 +6270,14 @@ object_methods[] = { "SampleLevel", add_sample_lod_method_call, "00111111001000" }, }; +static const struct method_function uav_methods[] = +{ + { "Store", add_store_method_call, "00000000000001" }, + { "Store2", add_store_method_call, "00000000000001" }, + { "Store3", add_store_method_call, "00000000000001" }, + { "Store4", add_store_method_call, "00000000000001" }, +}; + static int object_method_function_name_compare(const void *a, const void *b) { const struct method_function *func = b; @@ -6235,7 +6289,8 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, stru const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { const struct hlsl_type *object_type = object->data_type; - const struct method_function *method; + const struct method_function *method, *methods; + unsigned int count; if (object_type->class == HLSL_CLASS_ERROR) { @@ -6252,7 +6307,17 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, stru } } - if (object_type->class != HLSL_CLASS_TEXTURE || object_type->sampler_dim == HLSL_SAMPLER_DIM_GENERIC) + if (object_type->class == HLSL_CLASS_TEXTURE) + { + count = ARRAY_SIZE(texture_methods); + methods = texture_methods; + } + else if (object_type->class == HLSL_CLASS_UAV) + { + count = ARRAY_SIZE(uav_methods); + methods = uav_methods; + } + else { struct vkd3d_string_buffer *string; @@ -6263,7 +6328,7 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, stru return false; } - method = bsearch(name, object_methods, ARRAY_SIZE(object_methods), sizeof(*method), + method = bsearch(name, methods, count, sizeof(*method), object_method_function_name_compare); if (method && method->valid_dims[object_type->sampler_dim] == '1') diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c index 21ac2299..028a2189 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -3491,6 +3491,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_RAW_BUFFER: case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER: return D3D_SRV_DIMENSION_BUFFER; default: @@ -4019,6 +4020,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_RAW_BUFFER: case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER: return VKD3D_SM4_RESOURCE_BUFFER; default: @@ -4808,6 +4810,9 @@ static void write_sm4_dcl_textures(const struct tpf_compiler *tpf, const struct instr.opcode = VKD3D_SM5_OP_DCL_UAV_STRUCTURED; instr.byte_stride = component_type->e.resource.format->reg_size[HLSL_REGSET_NUMERIC] * 4; break; + case HLSL_SAMPLER_DIM_RAW_BUFFER: + instr.opcode = VKD3D_SM5_OP_DCL_UAV_RAW; + break; default: instr.opcode = VKD3D_SM5_OP_DCL_UAV_TYPED; break; @@ -5548,24 +5553,6 @@ static void write_sm4_cast(const struct tpf_compiler *tpf, const struct hlsl_ir_ } } -static void write_sm4_store_uav_typed(const struct tpf_compiler *tpf, const struct hlsl_deref *dst, - const struct hlsl_ir_node *coords, const struct hlsl_ir_node *value) -{ - struct sm4_instruction instr; - - memset(&instr, 0, sizeof(instr)); - instr.opcode = VKD3D_SM5_OP_STORE_UAV_TYPED; - - sm4_register_from_deref(tpf, &instr.dsts[0].reg, &instr.dsts[0].write_mask, dst, &instr); - instr.dst_count = 1; - - sm4_src_from_node(tpf, &instr.srcs[0], coords, VKD3DSP_WRITEMASK_ALL); - sm4_src_from_node(tpf, &instr.srcs[1], value, VKD3DSP_WRITEMASK_ALL); - instr.src_count = 2; - - write_sm4_instruction(tpf, &instr); -} - static void write_sm4_rasterizer_sample_count(const struct tpf_compiler *tpf, const struct hlsl_ir_node *dst) { struct sm4_instruction instr; @@ -6352,6 +6339,8 @@ static void write_sm4_resource_load(const struct tpf_compiler *tpf, const struct static void write_sm4_resource_store(const struct tpf_compiler *tpf, const struct hlsl_ir_resource_store *store) { struct hlsl_type *resource_type = hlsl_deref_get_type(tpf->ctx, &store->resource); + struct hlsl_ir_node *coords = store->coords.node, *value = store->value.node; + struct sm4_instruction instr; if (!store->resource.var->is_uniform) { @@ -6365,7 +6354,25 @@ static void write_sm4_resource_store(const struct tpf_compiler *tpf, const struc return; } - write_sm4_store_uav_typed(tpf, &store->resource, store->coords.node, store->value.node); + memset(&instr, 0, sizeof(instr)); + + sm4_register_from_deref(tpf, &instr.dsts[0].reg, &instr.dsts[0].write_mask, &store->resource, &instr); + instr.dst_count = 1; + if (resource_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER) + { + instr.opcode = VKD3D_SM5_OP_STORE_RAW; + instr.dsts[0].write_mask = vkd3d_write_mask_from_component_count(value->data_type->dimx); + } + else + { + instr.opcode = VKD3D_SM5_OP_STORE_UAV_TYPED; + } + + sm4_src_from_node(tpf, &instr.srcs[0], coords, VKD3DSP_WRITEMASK_ALL); + sm4_src_from_node(tpf, &instr.srcs[1], value, VKD3DSP_WRITEMASK_ALL); + instr.src_count = 2; + + write_sm4_instruction(tpf, &instr); } static void write_sm4_store(const struct tpf_compiler *tpf, const struct hlsl_ir_store *store) diff --git a/tests/hlsl/uav-rwbyteaddressbuffer.shader_test b/tests/hlsl/uav-rwbyteaddressbuffer.shader_test index edf3b5a0..6b0ca6ff 100644 --- a/tests/hlsl/uav-rwbyteaddressbuffer.shader_test +++ b/tests/hlsl/uav-rwbyteaddressbuffer.shader_test @@ -7,7 +7,7 @@ size (raw_buffer, 4) 1 2 3 4 -[pixel shader todo] +[pixel shader] RWByteAddressBuffer u : register(u1); float4 main() : sv_target @@ -18,12 +18,12 @@ float4 main() : sv_target } [test] -todo(sm<6) draw quad +todo(glsl) draw quad probe uav 1 (0) ri (10) if(sm<6) probe uav 1 (1) ri (11) if(sm>=6) probe uav 1 (1) r (11.1) -[pixel shader todo] +[pixel shader] RWByteAddressBuffer u : register(u1); float4 main() : sv_target @@ -34,10 +34,10 @@ float4 main() : sv_target } [test] -todo(sm<6) draw quad +todo(glsl) draw quad probe uav 1 (0) rgbaui(10, 11, 12, 13) -[pixel shader todo] +[pixel shader] RWByteAddressBuffer u : register(u1); float4 main() : sv_target @@ -48,10 +48,10 @@ float4 main() : sv_target } [test] -todo(sm<6) draw quad +todo(glsl) draw quad probe uav 1 (0) rgbaui(20, 21, 22, 23) -[pixel shader todo] +[pixel shader] RWByteAddressBuffer u : register(u1); float4 main() : sv_target @@ -62,14 +62,14 @@ float4 main() : sv_target } [test] -todo(sm<6) draw quad +todo(glsl) draw quad probe uav 1 (0) rgbaui(20, 21, 22, 23) [require] shader model >= 5.0 float64 -[pixel shader todo] +[pixel shader] RWByteAddressBuffer u : register(u1); float4 main() : sv_target @@ -79,7 +79,7 @@ float4 main() : sv_target } [test] -todo(sm<6) draw quad +todo(glsl) draw quad if(sm<6) probe uav 1 (0) ri (12) if(sm>=6) probe uav 1 (0) rd (12.2)