From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/dxil.c | 75 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+)
diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index a001f6f06..eeabc1c19 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -228,6 +228,13 @@ enum dxil_component_type COMPONENT_TYPE_PACKEDU8X32 = 18, };
+enum dxil_sampler_kind +{ + SAMPLER_KIND_DEFAULT = 0, + SAMPLER_KIND_COMPARISON = 1, + SAMPLER_KIND_MONO = 2, +}; + enum dxil_semantic_kind { SEMANTIC_KIND_ARBITRARY = 0, @@ -6755,6 +6762,70 @@ static enum vkd3d_result sm6_parser_resources_load_cbv(struct sm6_parser *sm6, return VKD3D_OK; }
+static enum vkd3d_result sm6_parser_resources_load_sampler(struct sm6_parser *sm6, + const struct sm6_metadata_node *node, struct sm6_descriptor_info *d, struct vkd3d_shader_instruction *ins) +{ + struct vkd3d_shader_register *reg; + unsigned int kind; + + if (node->operand_count < 7) + { + WARN("Invalid operand count %u.\n", node->operand_count); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND_COUNT, + "Invalid operand count %u for a sampler descriptor.", node->operand_count); + return VKD3D_ERROR_INVALID_SHADER; + } + if (node->operand_count > 7 && node->operands[7]) + { + WARN("Ignoring %u extra operands.\n", node->operand_count - 7); + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS, + "Ignoring %u extra operands for a sampler descriptor.", node->operand_count - 7); + } + + vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_DCL_SAMPLER); + ins->resource_type = VKD3D_SHADER_RESOURCE_NONE; + + if (!sm6_metadata_get_uint_value(sm6, node->operands[6], &kind)) + { + WARN("Failed to load sampler mode.\n"); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES, + "Sampler mode metadata value is not an integer."); + return VKD3D_ERROR_INVALID_SHADER; + } + switch (kind) + { + case SAMPLER_KIND_DEFAULT: + break; + case SAMPLER_KIND_COMPARISON: + ins->flags = VKD3DSI_SAMPLER_COMPARISON_MODE; + break; + default: + FIXME("Ignoring sampler kind %u.\n", kind); + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS, + "Ignoring sampler kind %u.", kind); + break; + } + + ins->declaration.sampler.src.swizzle = VKD3D_SHADER_NO_SWIZZLE; + ins->declaration.sampler.src.modifiers = VKD3DSPSM_NONE; + + reg = &ins->declaration.sampler.src.reg; + vsir_register_init(reg, VKD3DSPR_SAMPLER, VKD3D_DATA_UNUSED, 3); + reg->idx[0].offset = d->id; + reg->idx[1].offset = d->range.first; + reg->idx[2].offset = d->range.last; + + ins->declaration.sampler.range = d->range; + + d->resource_type = ins->resource_type; + d->kind = RESOURCE_KIND_SAMPLER; + d->reg_type = VKD3DSPR_SAMPLER; + d->reg_data_type = VKD3D_DATA_UNUSED; + d->resource_data_type = VKD3D_DATA_UNUSED; + + return VKD3D_OK; +} + static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6, enum vkd3d_shader_descriptor_type type, const struct sm6_metadata_node *descriptor_node) { @@ -6831,6 +6902,10 @@ static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6, if ((ret = sm6_parser_resources_load_uav(sm6, node, d, ins)) < 0) return ret; break; + case VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER: + if ((ret = sm6_parser_resources_load_sampler(sm6, node, d, ins)) < 0) + return ret; + break; default: FIXME("Unsupported descriptor type %u.\n", type); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES,
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/dxil.c | 68 +++++++++++++++++-- tests/hlsl/cbuffer.shader_test | 2 +- tests/hlsl/object-references.shader_test | 2 +- ...egister-reservations-resources.shader_test | 4 +- tests/hlsl/sampler-offset.shader_test | 6 +- tests/hlsl/sampler.shader_test | 4 +- tests/hlsl/static-initializer.shader_test | 4 +- 7 files changed, 75 insertions(+), 15 deletions(-)
diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index eeabc1c19..c4b917c6e 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -376,6 +376,7 @@ enum dx_intrinsic_opcode DX_UBFE = 52, DX_CREATE_HANDLE = 57, DX_CBUFFER_LOAD_LEGACY = 59, + DX_SAMPLE = 60, DX_TEXTURE_LOAD = 66, DX_TEXTURE_STORE = 67, DX_BUFFER_LOAD = 68, @@ -2428,6 +2429,26 @@ static bool sm6_value_validate_is_texture_handle(const struct sm6_value *value, return true; }
+static bool sm6_value_validate_is_sampler_handle(const struct sm6_value *value, enum dx_intrinsic_opcode op, + struct sm6_parser *sm6) +{ + enum dxil_resource_kind kind; + + if (!sm6_value_validate_is_handle(value, sm6)) + return false; + + kind = value->u.handle.d->kind; + if (kind != RESOURCE_KIND_SAMPLER) + { + WARN("Resource kind %u for op %u is not a sampler.\n", kind, op); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCE_HANDLE, + "Resource kind %u for sample operation %u is not a sampler.", kind, op); + return false; + } + + return true; +} + static bool sm6_value_validate_is_pointer(const struct sm6_value *value, struct sm6_parser *sm6) { if (!sm6_type_is_pointer(value->type)) @@ -3661,11 +3682,10 @@ static bool sm6_parser_emit_composite_construct(struct sm6_parser *sm6, const st }
static bool sm6_parser_emit_coordinate_construct(struct sm6_parser *sm6, const struct sm6_value **operands, - const struct sm6_value *z_operand, struct function_emission_state *state, + unsigned int max_operands, const struct sm6_value *z_operand, struct function_emission_state *state, struct vkd3d_shader_register *reg) { const struct vkd3d_shader_register *operand_regs[VKD3D_VEC4_SIZE]; - const unsigned int max_operands = 3; unsigned int component_count;
for (component_count = 0; component_count < max_operands; ++component_count) @@ -4047,6 +4067,45 @@ static void instruction_set_texel_offset(struct vkd3d_shader_instruction *ins, ins->texel_offset.w = sm6_value_get_texel_offset(operands[2]); }
+static void sm6_parser_emit_dx_sample(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, + const struct sm6_value **operands, struct function_emission_state *state) +{ + const struct sm6_value *resource, *sampler; + struct vkd3d_shader_src_param *src_params; + struct vkd3d_shader_instruction *ins; + struct vkd3d_shader_register coord; + const unsigned int clamp_idx = 9; + + resource = operands[0]; + sampler = operands[1]; + if (!sm6_value_validate_is_texture_handle(resource, op, sm6) + || !sm6_value_validate_is_sampler_handle(sampler, op, sm6)) + { + return; + } + + if (!sm6_parser_emit_coordinate_construct(sm6, &operands[2], VKD3D_VEC4_SIZE, NULL, state, &coord)) + return; + + ins = state->ins; + instruction_init_with_resource(ins, VKD3DSIH_SAMPLE, resource, sm6); + src_params = instruction_src_params_alloc(ins, 3, sm6); + + if (!sm6_value_is_undef(operands[clamp_idx])) + { + FIXME("Ignoring LOD clamp value.\n"); + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS, + "Ignoring LOD clamp value for a sample operation."); + } + + src_param_init_vector_from_reg(&src_params[0], &coord); + src_param_init_vector_from_reg(&src_params[1], &resource->u.handle.reg); + src_param_init_vector_from_reg(&src_params[2], &sampler->u.handle.reg); + instruction_set_texel_offset(ins, &operands[6], sm6); + + instruction_dst_param_init_ssa_vector(ins, VKD3D_VEC4_SIZE, sm6); +} + static void sm6_parser_emit_dx_sincos(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state) { @@ -4157,7 +4216,7 @@ static void sm6_parser_emit_dx_texture_load(struct sm6_parser *sm6, enum dx_intr is_uav = resource->u.handle.d->type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV;
mip_level_or_sample_count = (resource_type != VKD3D_SHADER_RESOURCE_BUFFER) ? operands[1] : NULL; - if (!sm6_parser_emit_coordinate_construct(sm6, &operands[2], + if (!sm6_parser_emit_coordinate_construct(sm6, &operands[2], 3, is_multisample ? NULL : mip_level_or_sample_count, state, &coord)) { return; @@ -4194,7 +4253,7 @@ static void sm6_parser_emit_dx_texture_store(struct sm6_parser *sm6, enum dx_int if (!sm6_value_validate_is_texture_handle(resource, op, sm6)) return;
- if (!sm6_parser_emit_coordinate_construct(sm6, &operands[1], NULL, state, &coord)) + if (!sm6_parser_emit_coordinate_construct(sm6, &operands[1], 3, NULL, state, &coord)) return;
write_mask = sm6_value_get_constant_uint(operands[8]); @@ -4297,6 +4356,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = [DX_ROUND_PI ] = {"g", "R", sm6_parser_emit_dx_unary}, [DX_ROUND_Z ] = {"g", "R", sm6_parser_emit_dx_unary}, [DX_RSQRT ] = {"g", "R", sm6_parser_emit_dx_unary}, + [DX_SAMPLE ] = {"o", "HHffffiiif", sm6_parser_emit_dx_sample}, [DX_SIN ] = {"g", "R", sm6_parser_emit_dx_sincos}, [DX_SPLIT_DOUBLE ] = {"S", "d", sm6_parser_emit_dx_split_double}, [DX_SQRT ] = {"g", "R", sm6_parser_emit_dx_unary}, diff --git a/tests/hlsl/cbuffer.shader_test b/tests/hlsl/cbuffer.shader_test index 62f1cd28c..ee19ea5f0 100644 --- a/tests/hlsl/cbuffer.shader_test +++ b/tests/hlsl/cbuffer.shader_test @@ -499,7 +499,7 @@ float4 main() : sv_target uniform 0 float4 1.0 0.0 0.0 0.0 uniform 4 float4 0.0 2.0 0.0 0.0 uniform 8 float4 0.0 0.0 3.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (1.0, 2.0, 0.0, 4.0)
diff --git a/tests/hlsl/object-references.shader_test b/tests/hlsl/object-references.shader_test index 698df0117..26f7a52ad 100644 --- a/tests/hlsl/object-references.shader_test +++ b/tests/hlsl/object-references.shader_test @@ -46,7 +46,7 @@ float4 main() : sv_target }
[test] -todo(sm>=6) draw quad +draw quad probe all rgba (77.77, 77.77, 77.77, 77.77)
diff --git a/tests/hlsl/register-reservations-resources.shader_test b/tests/hlsl/register-reservations-resources.shader_test index 1fa1e9163..b1007de63 100644 --- a/tests/hlsl/register-reservations-resources.shader_test +++ b/tests/hlsl/register-reservations-resources.shader_test @@ -224,8 +224,8 @@ float4 main() : sv_target }
[test] -todo draw quad -todo probe all rgba (0.5, 0.5, 0.5, 99.0) +todo(sm<6) draw quad +todo(sm<6) probe all rgba (0.5, 0.5, 0.5, 99.0)
[pixel shader] diff --git a/tests/hlsl/sampler-offset.shader_test b/tests/hlsl/sampler-offset.shader_test index 498a8ed3a..6f8357dfa 100644 --- a/tests/hlsl/sampler-offset.shader_test +++ b/tests/hlsl/sampler-offset.shader_test @@ -22,7 +22,7 @@ float4 main() : sv_target }
[test] -todo(sm>=6) draw quad +draw quad probe all rgba (0.1, 0.2, 0.5, 0.0)
@@ -36,7 +36,7 @@ float4 main() : sv_target }
[test] -todo(sm>=6) draw quad +draw quad probe all rgba (0.2, 0.2, 0.0, 0.4)
@@ -50,5 +50,5 @@ float4 main() : sv_target }
[test] -todo(sm>=6) draw quad +draw quad probe all rgba (0.0, 0.2, 0.0, 0.4) diff --git a/tests/hlsl/sampler.shader_test b/tests/hlsl/sampler.shader_test index 9a5fa6df4..17b09c0ec 100644 --- a/tests/hlsl/sampler.shader_test +++ b/tests/hlsl/sampler.shader_test @@ -17,7 +17,7 @@ float4 main() : sv_target }
[test] -todo(sm<4 | sm>=6) draw quad +todo(sm<4) draw quad probe all rgba (0.25, 0, 0.25, 0)
[pixel shader todo(sm<4)] @@ -30,7 +30,7 @@ float4 main() : sv_target }
[test] -todo(sm<4 | sm>=6) draw quad +todo(sm<4) draw quad probe all rgba (0.25, 0, 0.25, 0)
[pixel shader fail] diff --git a/tests/hlsl/static-initializer.shader_test b/tests/hlsl/static-initializer.shader_test index 0c51bac76..e7cfa9f55 100644 --- a/tests/hlsl/static-initializer.shader_test +++ b/tests/hlsl/static-initializer.shader_test @@ -147,7 +147,7 @@ float4 main() : sv_target }
[test] -todo(sm<4 | sm>=6) draw quad +todo(sm<4) draw quad probe all rgba (1, 2, 3, 4)
@@ -163,7 +163,7 @@ float4 main() : sv_target }
[test] -todo(sm<4 | sm>=6) draw quad +todo(sm<4) draw quad probe all rgba (1, 2, 3, 4)
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/dxil.c | 35 +++++++++++++++++++++++++----- tests/hlsl/sample-grad.shader_test | 6 ++--- 2 files changed, 33 insertions(+), 8 deletions(-)
diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index c4b917c6e..c399a10f3 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -33,7 +33,7 @@ static const uint64_t ALLOCA_FLAG_IN_ALLOCA = 0x20; static const uint64_t ALLOCA_FLAG_EXPLICIT_TYPE = 0x40; static const uint64_t ALLOCA_ALIGNMENT_MASK = ALLOCA_FLAG_IN_ALLOCA - 1; static const unsigned int SHADER_DESCRIPTOR_TYPE_COUNT = 4; -static const size_t MAX_IR_INSTRUCTIONS_PER_DXIL_INSTRUCTION = 5; +static const size_t MAX_IR_INSTRUCTIONS_PER_DXIL_INSTRUCTION = 11;
static const unsigned int dx_max_thread_group_size[3] = {1024, 1024, 64};
@@ -377,6 +377,7 @@ enum dx_intrinsic_opcode DX_CREATE_HANDLE = 57, DX_CBUFFER_LOAD_LEGACY = 59, DX_SAMPLE = 60, + DX_SAMPLE_GRAD = 63, DX_TEXTURE_LOAD = 66, DX_TEXTURE_STORE = 67, DX_BUFFER_LOAD = 68, @@ -4070,11 +4071,11 @@ static void instruction_set_texel_offset(struct vkd3d_shader_instruction *ins, static void sm6_parser_emit_dx_sample(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state) { + struct vkd3d_shader_register coord, ddx, ddy; const struct sm6_value *resource, *sampler; struct vkd3d_shader_src_param *src_params; struct vkd3d_shader_instruction *ins; - struct vkd3d_shader_register coord; - const unsigned int clamp_idx = 9; + unsigned int clamp_idx;
resource = operands[0]; sampler = operands[1]; @@ -4087,9 +4088,32 @@ static void sm6_parser_emit_dx_sample(struct sm6_parser *sm6, enum dx_intrinsic_ if (!sm6_parser_emit_coordinate_construct(sm6, &operands[2], VKD3D_VEC4_SIZE, NULL, state, &coord)) return;
+ if (op == DX_SAMPLE_GRAD) + { + if (!sm6_parser_emit_coordinate_construct(sm6, &operands[9], 3, NULL, state, &ddx)) + return; + if (!sm6_parser_emit_coordinate_construct(sm6, &operands[12], 3, NULL, state, &ddy)) + return; + } + ins = state->ins; - instruction_init_with_resource(ins, VKD3DSIH_SAMPLE, resource, sm6); - src_params = instruction_src_params_alloc(ins, 3, sm6); + switch (op) + { + case DX_SAMPLE: + instruction_init_with_resource(ins, VKD3DSIH_SAMPLE, resource, sm6); + src_params = instruction_src_params_alloc(ins, 3, sm6); + clamp_idx = 9; + break; + case DX_SAMPLE_GRAD: + instruction_init_with_resource(ins, VKD3DSIH_SAMPLE_GRAD, resource, sm6); + src_params = instruction_src_params_alloc(ins, 5, sm6); + src_param_init_vector_from_reg(&src_params[3], &ddx); + src_param_init_vector_from_reg(&src_params[4], &ddy); + clamp_idx = 15; + break; + default: + vkd3d_unreachable(); + }
if (!sm6_value_is_undef(operands[clamp_idx])) { @@ -4357,6 +4381,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = [DX_ROUND_Z ] = {"g", "R", sm6_parser_emit_dx_unary}, [DX_RSQRT ] = {"g", "R", sm6_parser_emit_dx_unary}, [DX_SAMPLE ] = {"o", "HHffffiiif", sm6_parser_emit_dx_sample}, + [DX_SAMPLE_GRAD ] = {"o", "HHffffiiifffffff", sm6_parser_emit_dx_sample}, [DX_SIN ] = {"g", "R", sm6_parser_emit_dx_sincos}, [DX_SPLIT_DOUBLE ] = {"S", "d", sm6_parser_emit_dx_split_double}, [DX_SQRT ] = {"g", "R", sm6_parser_emit_dx_unary}, diff --git a/tests/hlsl/sample-grad.shader_test b/tests/hlsl/sample-grad.shader_test index 298037a77..c37da299c 100644 --- a/tests/hlsl/sample-grad.shader_test +++ b/tests/hlsl/sample-grad.shader_test @@ -26,11 +26,11 @@ float4 main() : sv_target
[test] uniform 0 float4 0.0 0.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (1.0, 0.0, 1.0, 0.0) uniform 0 float4 1.0 1.0 1.0 1.0 -todo(sm>=6) draw quad +draw quad probe all rgba (0.0, 0.0, 1.0, 0.0) uniform 0 float4 2.0 2.0 2.0 2.0 -todo(sm>=6) draw quad +draw quad probe all rgba (0.0, 0.0, 1.0, 0.0)