From 5942f59d8cade40d6bb21f8c46fc05fcee79dbb3 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Tue, 20 Aug 2024 06:47:55 +1000 Subject: [PATCH] Updated vkd3d to c8cc1b1a2476a4c518756fd7604d37e8c1611af3. --- libs/vkd3d/include/private/vkd3d_memory.h | 3 +- libs/vkd3d/include/vkd3d_shader.h | 2 +- libs/vkd3d/libs/vkd3d-common/debug.c | 1 - libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 2 +- libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 10 +- libs/vkd3d/libs/vkd3d-shader/dxil.c | 4 +- libs/vkd3d/libs/vkd3d-shader/fx.c | 389 +++++++++++++++--- libs/vkd3d/libs/vkd3d-shader/glsl.c | 6 +- libs/vkd3d/libs/vkd3d-shader/hlsl.c | 45 +- libs/vkd3d/libs/vkd3d-shader/hlsl.h | 10 +- libs/vkd3d/libs/vkd3d-shader/hlsl.l | 2 + libs/vkd3d/libs/vkd3d-shader/hlsl.y | 125 ++++-- libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 2 + libs/vkd3d/libs/vkd3d-shader/ir.c | 36 +- libs/vkd3d/libs/vkd3d-shader/tpf.c | 94 +++-- .../libs/vkd3d-shader/vkd3d_shader_private.h | 1 - libs/vkd3d/libs/vkd3d/resource.c | 2 +- libs/vkd3d/libs/vkd3d/state.c | 12 +- libs/vkd3d/libs/vkd3d/vkd3d_private.h | 3 +- 19 files changed, 582 insertions(+), 167 deletions(-) diff --git a/libs/vkd3d/include/private/vkd3d_memory.h b/libs/vkd3d/include/private/vkd3d_memory.h index 682d35c03c6..e191dc11b73 100644 --- a/libs/vkd3d/include/private/vkd3d_memory.h +++ b/libs/vkd3d/include/private/vkd3d_memory.h @@ -19,7 +19,6 @@ #ifndef __VKD3D_MEMORY_H #define __VKD3D_MEMORY_H -#include #include #include #include @@ -44,7 +43,7 @@ static inline void *vkd3d_realloc(void *ptr, size_t size) static inline void *vkd3d_calloc(size_t count, size_t size) { void *ptr; - assert(count <= ~(size_t)0 / size); + VKD3D_ASSERT(count <= ~(size_t)0 / size); if (!(ptr = calloc(count, size))) ERR("Out of memory.\n"); return ptr; diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h index d4756810065..d37d8ebad9e 100644 --- a/libs/vkd3d/include/vkd3d_shader.h +++ b/libs/vkd3d/include/vkd3d_shader.h @@ -1876,7 +1876,7 @@ enum vkd3d_shader_sysval_semantic VKD3D_SHADER_SV_VIEWPORT_ARRAY_INDEX = 0x05, /** Vertex ID; SV_VertexID in Direct3D. */ VKD3D_SHADER_SV_VERTEX_ID = 0x06, - /** Primtive ID; SV_PrimitiveID in Direct3D. */ + /** Primitive ID; SV_PrimitiveID in Direct3D. */ VKD3D_SHADER_SV_PRIMITIVE_ID = 0x07, /** Instance ID; SV_InstanceID in Direct3D. */ VKD3D_SHADER_SV_INSTANCE_ID = 0x08, diff --git a/libs/vkd3d/libs/vkd3d-common/debug.c b/libs/vkd3d/libs/vkd3d-common/debug.c index 4bfc19bd9a1..9a92f0ead02 100644 --- a/libs/vkd3d/libs/vkd3d-common/debug.c +++ b/libs/vkd3d/libs/vkd3d-common/debug.c @@ -22,7 +22,6 @@ #include "vkd3d_common.h" -#include #include #include #include diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c index 2c2f0c43ece..77e9711300f 100644 --- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c @@ -2251,7 +2251,7 @@ static const char *get_semantic_register_name(enum vkd3d_shader_sysval_semantic case VKD3D_SHADER_SV_DEPTH_GREATER_EQUAL: return "oDepthGE"; case VKD3D_SHADER_SV_DEPTH_LESS_EQUAL: return "oDepthLE"; /* SV_Coverage has name vCoverage when used as an input, - * but it doens't appear in the signature in that case. */ + * but it doesn't appear in the signature in that case. */ case VKD3D_SHADER_SV_COVERAGE: return "oMask"; case VKD3D_SHADER_SV_STENCIL_REF: return "oStencilRef"; default: return "??"; diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c index a4c038a233a..d05394c3ab7 100644 --- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c @@ -1523,6 +1523,8 @@ D3DXPARAMETER_CLASS hlsl_sm1_class(const struct hlsl_type *type) case HLSL_CLASS_DOMAIN_SHADER: case HLSL_CLASS_HULL_SHADER: case HLSL_CLASS_GEOMETRY_SHADER: + case HLSL_CLASS_BLEND_STATE: + case HLSL_CLASS_NULL: break; } @@ -1626,6 +1628,8 @@ D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type) case HLSL_CLASS_DOMAIN_SHADER: case HLSL_CLASS_HULL_SHADER: case HLSL_CLASS_GEOMETRY_SHADER: + case HLSL_CLASS_BLEND_STATE: + case HLSL_CLASS_NULL: break; } @@ -1826,17 +1830,17 @@ void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buff break; case HLSL_TYPE_INT: - uni.f = var->default_values[k].value.i; + uni.f = var->default_values[k].number.i; break; case HLSL_TYPE_UINT: case HLSL_TYPE_BOOL: - uni.f = var->default_values[k].value.u; + uni.f = var->default_values[k].number.u; break; case HLSL_TYPE_HALF: case HLSL_TYPE_FLOAT: - uni.u = var->default_values[k].value.u; + uni.u = var->default_values[k].number.u; break; default: diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c index 2a0bbe1a625..4a17c62292b 100644 --- a/libs/vkd3d/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c @@ -4298,7 +4298,7 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco if (!(flags & FP_ALLOW_UNSAFE_ALGEBRA)) ins->flags |= VKD3DSI_PRECISE_X; flags &= ~FP_ALLOW_UNSAFE_ALGEBRA; - /* SPIR-V FPFastMathMode is only available in the Kernel executon model. */ + /* SPIR-V FPFastMathMode is only available in the Kernel execution model. */ silence_warning = !(flags & ~(FP_NO_NAN | FP_NO_INF | FP_NO_SIGNED_ZEROS | FP_ALLOW_RECIPROCAL)); break; case VKD3DSIH_IADD: @@ -5211,7 +5211,7 @@ static void sm6_parser_emit_dx_get_dimensions(struct sm6_parser *sm6, enum dx_in instruction_dst_param_init_temp_vector(ins++, sm6); state->temp_idx = 1; - /* DXIL does not have an instrinsic for sample info, and resinfo is expected to return + /* DXIL does not have an intrinsic for sample info, and resinfo is expected to return * the sample count in .w for MS textures. The result is always a struct of 4 x uint32. */ vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_SAMPLE_INFO); ins->flags = VKD3DSI_SAMPLE_INFO_UINT; diff --git a/libs/vkd3d/libs/vkd3d-shader/fx.c b/libs/vkd3d/libs/vkd3d-shader/fx.c index e3ebbafb3f4..a1d1fd6572f 100644 --- a/libs/vkd3d/libs/vkd3d-shader/fx.c +++ b/libs/vkd3d/libs/vkd3d-shader/fx.c @@ -111,7 +111,7 @@ static void get_state_block_function_components(const struct state_block_functio { unsigned int i; - assert(comp_count <= info->max_args); + VKD3D_ASSERT(comp_count <= info->max_args); if (info->min_args == info->max_args) { @@ -205,6 +205,8 @@ struct fx_write_context uint32_t sampler_state_count; uint32_t depth_stencil_state_count; uint32_t rasterizer_state_count; + uint32_t blend_state_count; + uint32_t string_count; int status; bool child_effect; @@ -565,6 +567,9 @@ static const char * get_fx_4_type_name(const struct hlsl_type *type) case HLSL_CLASS_PIXEL_SHADER: return "PixelShader"; + case HLSL_CLASS_STRING: + return "String"; + default: return type->name; } @@ -636,6 +641,8 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co case HLSL_CLASS_DOMAIN_SHADER: case HLSL_CLASS_HULL_SHADER: case HLSL_CLASS_GEOMETRY_SHADER: + case HLSL_CLASS_BLEND_STATE: + case HLSL_CLASS_STRING: put_u32_unaligned(buffer, 2); break; @@ -648,9 +655,9 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co case HLSL_CLASS_PASS: case HLSL_CLASS_TECHNIQUE: case HLSL_CLASS_CONSTANT_BUFFER: + case HLSL_CLASS_NULL: vkd3d_unreachable(); - case HLSL_CLASS_STRING: case HLSL_CLASS_VOID: FIXME("Writing type class %u is not implemented.\n", type->class); set_status(fx, VKD3D_ERROR_NOT_IMPLEMENTED); @@ -754,6 +761,14 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co { put_u32_unaligned(buffer, 3); } + else if (type->class == HLSL_CLASS_BLEND_STATE) + { + put_u32_unaligned(buffer, 2); + } + else if (type->class == HLSL_CLASS_STRING) + { + put_u32_unaligned(buffer, 1); + } else if (hlsl_is_numeric_type(type)) { numeric_desc = get_fx_4_numeric_type_description(type, fx); @@ -879,6 +894,13 @@ static uint32_t write_fx_2_string(const char *string, struct fx_write_context *f return offset; } +static uint32_t get_fx_2_type_class(const struct hlsl_type *type) +{ + if (type->class == HLSL_CLASS_MATRIX) + return D3DXPC_MATRIX_ROWS; + return hlsl_sm1_class(type); +} + static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *name, const struct hlsl_semantic *semantic, struct fx_write_context *fx) { @@ -897,7 +919,7 @@ static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *n semantic_offset = semantic->raw_name ? write_string(semantic->raw_name, fx) : 0; offset = put_u32(buffer, hlsl_sm1_base_type(type)); - put_u32(buffer, hlsl_sm1_class(type)); + put_u32(buffer, get_fx_2_type_class(type)); put_u32(buffer, name_offset); put_u32(buffer, semantic_offset); put_u32(buffer, elements_count); @@ -1078,12 +1100,14 @@ static bool is_type_supported_fx_2(struct hlsl_ctx *ctx, const struct hlsl_type case HLSL_CLASS_DOMAIN_SHADER: case HLSL_CLASS_HULL_SHADER: case HLSL_CLASS_GEOMETRY_SHADER: + case HLSL_CLASS_BLEND_STATE: return false; case HLSL_CLASS_EFFECT_GROUP: case HLSL_CLASS_PASS: case HLSL_CLASS_TECHNIQUE: case HLSL_CLASS_CONSTANT_BUFFER: + case HLSL_CLASS_NULL: /* This cannot appear as an extern variable. */ break; } @@ -1234,7 +1258,7 @@ static uint32_t write_fx_4_default_value(struct hlsl_type *value_type, struct hl for (j = 0; j < comp_count; ++j) { - put_u32_unaligned(buffer, value->value.u); + put_u32_unaligned(buffer, value->number.u); value++; } break; @@ -1264,6 +1288,27 @@ static uint32_t write_fx_4_default_value(struct hlsl_type *value_type, struct hl return offset; } +static void write_fx_4_string_initializer(struct hlsl_ir_var *var, struct fx_write_context *fx) +{ + uint32_t elements_count = hlsl_get_multiarray_size(var->data_type), i; + const struct hlsl_default_value *value = var->default_values; + struct vkd3d_bytecode_buffer *buffer = &fx->structured; + struct hlsl_ctx *ctx = fx->ctx; + uint32_t offset; + + if (!value) + { + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "String objects have to be initialized."); + return; + } + + for (i = 0; i < elements_count; ++i, ++value) + { + offset = write_fx_4_string(value->string, fx); + put_u32(buffer, offset); + } +} + static void write_fx_4_numeric_variable(struct hlsl_ir_var *var, bool shared, struct fx_write_context *fx) { struct vkd3d_bytecode_buffer *buffer = &fx->structured; @@ -1322,6 +1367,10 @@ static void write_fx_4_annotation(struct hlsl_ir_var *var, struct fx_write_conte offset = write_fx_4_default_value(var->data_type, var->default_values, fx); put_u32(buffer, offset); } + else if (type->class == HLSL_CLASS_STRING) + { + write_fx_4_string_initializer(var, fx); + } else { hlsl_fixme(ctx, &var->loc, "Writing annotations for type class %u is not implemented.", type->class); @@ -1429,17 +1478,28 @@ static void write_fx_4_state_assignment(const struct hlsl_ir_var *var, struct hl set_u32(buffer, rhs_offset, value_offset); } -static bool state_block_contains_state(const char *name, unsigned int start, struct hlsl_state_block *block) +static bool state_block_contains_state(const struct hlsl_state_block_entry *entry, unsigned int start_index, + struct hlsl_state_block *block) { unsigned int i; - for (i = start; i < block->count; ++i) + for (i = start_index; i < block->count; ++i) { - if (block->entries[i]->is_function_call) + const struct hlsl_state_block_entry *cur = block->entries[i]; + + if (cur->is_function_call) continue; - if (!ascii_strcasecmp(block->entries[i]->name, name)) - return true; + if (ascii_strcasecmp(cur->name, entry->name)) + continue; + + if (cur->lhs_has_index != entry->lhs_has_index) + continue; + + if (cur->lhs_has_index && cur->lhs_index != entry->lhs_index) + continue; + + return true; } return false; @@ -1451,6 +1511,24 @@ struct replace_state_context struct hlsl_ir_var *var; }; +static bool lower_null_constant(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + struct hlsl_ir_node *c; + + if (instr->type != HLSL_IR_CONSTANT) + return false; + if (instr->data_type->class != HLSL_CLASS_NULL) + return false; + + if (!(c = hlsl_new_uint_constant(ctx, 0, &instr->loc))) + return false; + + list_add_before(&instr->entry, &c->entry); + hlsl_replace_node(instr, c); + + return true; +} + static bool replace_state_block_constant(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { struct replace_state_context *replace_context = context; @@ -1480,17 +1558,6 @@ static bool replace_state_block_constant(struct hlsl_ctx *ctx, struct hlsl_ir_no return true; } -static void fold_state_value(struct hlsl_ctx *ctx, struct hlsl_state_block_entry *entry) -{ - bool progress; - - do - { - progress = hlsl_transform_ir(ctx, hlsl_fold_constant_exprs, entry->instrs, NULL); - progress |= hlsl_copy_propagation_execute(ctx, entry->instrs); - } while (progress); -} - enum state_property_component_type { FX_BOOL, @@ -1505,6 +1572,9 @@ enum state_property_component_type FX_TEXTURE, FX_DEPTHSTENCILVIEW, FX_RENDERTARGETVIEW, + FX_BLEND, + FX_VERTEXSHADER, + FX_PIXELSHADER, }; static inline bool is_object_fx_type(enum state_property_component_type type) @@ -1519,6 +1589,9 @@ static inline bool is_object_fx_type(enum state_property_component_type type) case FX_TEXTURE: case FX_RENDERTARGETVIEW: case FX_DEPTHSTENCILVIEW: + case FX_BLEND: + case FX_VERTEXSHADER: + case FX_PIXELSHADER: return true; default: return false; @@ -1545,6 +1618,12 @@ static inline enum hlsl_type_class hlsl_type_class_from_fx_type(enum state_prope return HLSL_CLASS_RENDER_TARGET_VIEW; case FX_DEPTHSTENCILVIEW: return HLSL_CLASS_DEPTH_STENCIL_VIEW; + case FX_BLEND: + return HLSL_CLASS_BLEND_STATE; + case FX_VERTEXSHADER: + return HLSL_CLASS_VERTEX_SHADER; + case FX_PIXELSHADER: + return HLSL_CLASS_PIXEL_SHADER; default: vkd3d_unreachable(); } @@ -1663,6 +1742,51 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl { NULL } }; + static const struct rhs_named_value blend_values[] = + { + { "ZERO", 1 }, + { "ONE", 2 }, + { "SRC_COLOR", 3 }, + { "INV_SRC_COLOR", 4 }, + { "SRC_ALPHA", 5 }, + { "INV_SRC_ALPHA", 6 }, + { "DEST_ALPHA", 7 }, + { "INV_DEST_ALPHA", 8 }, + { "DEST_COLOR", 9 }, + { "INV_DEST_COLOR", 10 }, + { "SRC_ALPHA_SAT", 11 }, + { "BLEND_FACTOR", 14 }, + { "INV_BLEND_FACTOR", 15 }, + { "SRC1_COLOR", 16 }, + { "INV_SRC1_COLOR", 17 }, + { "SRC1_ALPHA", 18 }, + { "INV_SRC1_ALPHA", 19 }, + { NULL } + }; + + static const struct rhs_named_value blendop_values[] = + { + { "ADD", 1 }, + { "SUBTRACT", 2 }, + { "REV_SUBTRACT", 3 }, + { "MIN", 4 }, + { "MAX", 5 }, + { NULL } + }; + + static const struct rhs_named_value bool_values[] = + { + { "FALSE", 0 }, + { "TRUE", 1 }, + { NULL } + }; + + static const struct rhs_named_value null_values[] = + { + { "NULL", 0 }, + { NULL } + }; + static const struct state { const char *name; @@ -1676,29 +1800,33 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl } states[] = { - { "RasterizerState", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_RASTERIZER, 1, 1, 0 }, - { "DepthStencilState", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_DEPTHSTENCIL, 1, 1, 1 }, - + { "RasterizerState", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_RASTERIZER, 1, 1, 0 }, + { "DepthStencilState", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_DEPTHSTENCIL, 1, 1, 1 }, + { "BlendState", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_BLEND, 1, 1, 2 }, { "RenderTargetView", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_RENDERTARGETVIEW, 1, 8, 3 }, { "DepthStencilView", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_DEPTHSTENCILVIEW, 1, 1, 4 }, - { "DS_StencilRef", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 9 }, + { "VertexShader", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_VERTEXSHADER, 1, 1, 6 }, + { "PixelShader", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_PIXELSHADER, 1, 1, 7 }, + { "DS_StencilRef", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 9 }, + { "AB_BlendFactor", HLSL_CLASS_PASS, HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 10 }, + { "AB_SampleMask", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 11 }, { "FillMode", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 12, fill_values }, { "CullMode", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 13, cull_values }, - { "FrontCounterClockwise", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 14 }, + { "FrontCounterClockwise", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 14, bool_values }, { "DepthBias", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 15 }, { "DepthBiasClamp", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 16 }, { "SlopeScaledDepthBias", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 17 }, - { "DepthClipEnable", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 18 }, - { "ScissorEnable", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 19 }, - { "MultisampleEnable", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 20 }, - { "AntializedLineEnable", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 21 }, + { "DepthClipEnable", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 18, bool_values }, + { "ScissorEnable", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 19, bool_values }, + { "MultisampleEnable", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 20, bool_values }, + { "AntializedLineEnable", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 21, bool_values }, - { "DepthEnable", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 22 }, + { "DepthEnable", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 22, bool_values }, { "DepthWriteMask", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 23, depth_write_mask_values }, { "DepthFunc", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 24, comparison_values }, - { "StencilEnable", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 25 }, + { "StencilEnable", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 25, bool_values }, { "StencilReadMask", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_UINT8, 1, 1, 26 }, { "StencilWriteMask", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_UINT8, 1, 1, 27 }, { "FrontFaceStencilFail", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 28, stencil_op_values }, @@ -1720,12 +1848,45 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl { "BorderColor", HLSL_CLASS_SAMPLER, HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 52 }, { "MinLOD", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 53 }, { "MaxLOD", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 54 }, - { "Texture", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_TEXTURE, 1, 1, 55 }, + { "Texture", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_TEXTURE, 1, 1, 55, null_values }, { "HullShader", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_HULLSHADER, 1, 1, 56 }, { "DomainShader", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_DOMAINSHADER, 1, 1, 57 }, { "ComputeShader", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_COMPUTESHADER, 1, 1, 58 }, }; + + static const struct state fx_4_blend_states[] = + { + { "AlphaToCoverageEnable", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 36, bool_values }, + { "BlendEnable", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 8, 37, bool_values }, + { "SrcBlend", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 38, blend_values }, + { "DestBlend", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 39, blend_values }, + { "BlendOp", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 40, blendop_values }, + { "SrcBlendAlpha", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 41, blend_values }, + { "DestBlendAlpha", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 42, blend_values }, + { "BlendOpAlpha", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 43, blendop_values }, + { "RenderTargetWriteMask", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT8, 1, 8, 44 }, + }; + + static const struct state fx_5_blend_states[] = + { + { "AlphaToCoverageEnable", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 36, bool_values }, + { "BlendEnable", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 8, 37, bool_values }, + { "SrcBlend", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 38, blend_values }, + { "DestBlend", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 39, blend_values }, + { "BlendOp", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 40, blendop_values }, + { "SrcBlendAlpha", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 41, blend_values }, + { "DestBlendAlpha", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 42, blend_values }, + { "BlendOpAlpha", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 43, blendop_values }, + { "RenderTargetWriteMask", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT8, 1, 8, 44 }, + }; + + struct state_table + { + const struct state *ptr; + unsigned int count; + } table; + const struct hlsl_type *type = hlsl_get_multiarray_element_type(var->data_type); struct replace_state_context replace_context; struct hlsl_type *state_type = NULL; @@ -1733,15 +1894,33 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl const struct state *state = NULL; struct hlsl_ctx *ctx = fx->ctx; enum hlsl_base_type base_type; - struct hlsl_ir_load *load; unsigned int i; - for (i = 0; i < ARRAY_SIZE(states); ++i) + if (type->class == HLSL_CLASS_BLEND_STATE) { - if (type->class == states[i].container - && !ascii_strcasecmp(entry->name, states[i].name)) + if (ctx->profile->major_version == 4) { - state = &states[i]; + table.ptr = fx_4_blend_states; + table.count = ARRAY_SIZE(fx_4_blend_states); + } + else + { + table.ptr = fx_5_blend_states; + table.count = ARRAY_SIZE(fx_5_blend_states); + } + } + else + { + table.ptr = states; + table.count = ARRAY_SIZE(states); + } + + for (i = 0; i < table.count; ++i) + { + if (type->class == table.ptr[i].container + && !ascii_strcasecmp(entry->name, table.ptr[i].name)) + { + state = &table.ptr[i]; break; } } @@ -1786,8 +1965,9 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl replace_context.var = var; /* Turn named constants to actual constants. */ + hlsl_transform_ir(ctx, lower_null_constant, entry->instrs, NULL); hlsl_transform_ir(ctx, replace_state_block_constant, entry->instrs, &replace_context); - fold_state_value(ctx, entry); + hlsl_run_const_passes(ctx, entry->instrs); /* Now cast and run folding again. */ @@ -1798,7 +1978,8 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl switch (node->type) { case HLSL_IR_LOAD: - load = hlsl_ir_load(node); + { + struct hlsl_ir_load *load = hlsl_ir_load(node); if (load->src.path_len) hlsl_fixme(ctx, &ctx->location, "Arrays are not supported for RHS."); @@ -1810,6 +1991,26 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl } break; + } + case HLSL_IR_CONSTANT: + { + struct hlsl_ir_constant *c = hlsl_ir_constant(node); + struct hlsl_type *data_type = c->node.data_type; + + if (data_type->class == HLSL_CLASS_SCALAR && data_type->e.numeric.type == HLSL_TYPE_UINT) + { + if (c->value.u[0].u != 0) + hlsl_error(ctx, &ctx->location, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, + "Only 0 integer constants are allowed for object-typed fields."); + } + else + { + hlsl_error(ctx, &ctx->location, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, + "Unexpected constant used for object-typed field."); + } + + break; + } default: hlsl_fixme(ctx, &ctx->location, "Unhandled node type for object-typed field."); } @@ -1857,11 +2058,27 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl hlsl_src_remove(entry->args); hlsl_src_from_node(entry->args, cast); - fold_state_value(ctx, entry); + hlsl_run_const_passes(ctx, entry->instrs); } } -static unsigned int decompose_fx_4_state_block(struct hlsl_ir_var *var, struct hlsl_state_block *block, +static bool decompose_fx_4_state_add_entries(struct hlsl_state_block *block, unsigned int entry_index, + unsigned int count) +{ + if (!vkd3d_array_reserve((void **)&block->entries, &block->capacity, block->count + count, sizeof(*block->entries))) + return false; + + if (entry_index != block->count - 1) + { + memmove(&block->entries[entry_index + count + 1], &block->entries[entry_index + 1], + (block->count - entry_index - 1) * sizeof(*block->entries)); + } + block->count += count; + + return true; +} + +static unsigned int decompose_fx_4_state_function_call(struct hlsl_ir_var *var, struct hlsl_state_block *block, unsigned int entry_index, struct fx_write_context *fx) { struct hlsl_state_block_entry *entry = block->entries[entry_index]; @@ -1891,15 +2108,8 @@ static unsigned int decompose_fx_4_state_block(struct hlsl_ir_var *var, struct h return 1; } - if (!vkd3d_array_reserve((void **)&block->entries, &block->capacity, block->count + entry->args_count - 1, - sizeof(*block->entries))) + if (!decompose_fx_4_state_add_entries(block, entry_index, entry->args_count - 1)) return 1; - if (entry_index != block->count - 1) - { - memmove(&block->entries[entry_index + entry->args_count], &block->entries[entry_index + 1], - (block->count - entry_index - 1) * sizeof(*block->entries)); - } - block->count += entry->args_count - 1; get_state_block_function_components(info, components, entry->args_count); @@ -1915,6 +2125,62 @@ static unsigned int decompose_fx_4_state_block(struct hlsl_ir_var *var, struct h return entry->args_count; } +/* For some states assignment sets all of the elements. This behaviour is limited to certain states of BlendState + object, and only when fx_5_0 profile is used. */ +static unsigned int decompose_fx_4_state_block_expand_array(struct hlsl_ir_var *var, struct hlsl_state_block *block, + unsigned int entry_index, struct fx_write_context *fx) +{ + static const char *states[] = { "SrcBlend", "DestBlend", "BlendOp", "SrcBlendAlpha", "DestBlendAlpha", "BlendOpAlpha" }; + const struct hlsl_type *type = hlsl_get_multiarray_element_type(var->data_type); + struct hlsl_state_block_entry *entry = block->entries[entry_index]; + static const unsigned int array_size = 8; + struct hlsl_ctx *ctx = fx->ctx; + bool found = false; + unsigned int i; + + if (type->class != HLSL_CLASS_BLEND_STATE) + return 1; + if (ctx->profile->major_version != 5) + return 1; + if (entry->lhs_has_index) + return 1; + + for (i = 0; i < ARRAY_SIZE(states); ++i) + { + if (!ascii_strcasecmp(entry->name, states[i])) + { + found = true; + break; + } + } + + if (!found) + return 1; + + if (!decompose_fx_4_state_add_entries(block, entry_index, array_size - 1)) + return 1; + + block->entries[entry_index]->lhs_has_index = true; + for (i = 1; i < array_size; ++i) + { + block->entries[entry_index + i] = clone_stateblock_entry(ctx, entry, + entry->name, true, i, 0); + } + + return array_size; +} + +static unsigned int decompose_fx_4_state_block(struct hlsl_ir_var *var, struct hlsl_state_block *block, + unsigned int entry_index, struct fx_write_context *fx) +{ + struct hlsl_state_block_entry *entry = block->entries[entry_index]; + + if (entry->is_function_call) + return decompose_fx_4_state_function_call(var, block, entry_index, fx); + + return decompose_fx_4_state_block_expand_array(var, block, entry_index, fx); +} + static void write_fx_4_state_block(struct hlsl_ir_var *var, unsigned int block_index, uint32_t count_offset, struct fx_write_context *fx) { @@ -1936,7 +2202,7 @@ static void write_fx_4_state_block(struct hlsl_ir_var *var, unsigned int block_i struct hlsl_state_block_entry *entry = block->entries[i]; /* Skip if property is reassigned later. This will use the last assignment. */ - if (state_block_contains_state(entry->name, i + 1, block)) + if (state_block_contains_state(entry, i + 1, block)) continue; /* Resolve special constant names and property names. */ @@ -2069,6 +2335,16 @@ static void write_fx_4_object_variable(struct hlsl_ir_var *var, struct fx_write_ fx->rasterizer_state_count += elements_count; break; + case HLSL_CLASS_BLEND_STATE: + write_fx_4_state_object_initializer(var, fx); + fx->blend_state_count += elements_count; + break; + + case HLSL_CLASS_STRING: + write_fx_4_string_initializer(var, fx); + fx->string_count += elements_count; + break; + default: hlsl_fixme(ctx, &ctx->location, "Writing initializer for object class %u is not implemented.", type->class); @@ -2170,6 +2446,9 @@ static bool is_supported_object_variable(const struct hlsl_ctx *ctx, const struc case HLSL_CLASS_RENDER_TARGET_VIEW: case HLSL_CLASS_SAMPLER: case HLSL_CLASS_TEXTURE: + case HLSL_CLASS_BLEND_STATE: + case HLSL_CLASS_VERTEX_SHADER: + case HLSL_CLASS_STRING: return true; case HLSL_CLASS_COMPUTE_SHADER: case HLSL_CLASS_DOMAIN_SHADER: @@ -2183,8 +2462,6 @@ static bool is_supported_object_variable(const struct hlsl_ctx *ctx, const struc if (type->e.resource.rasteriser_ordered) return false; return true; - case HLSL_CLASS_VERTEX_SHADER: - return true; default: return false; @@ -2237,10 +2514,10 @@ static int hlsl_fx_4_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) put_u32(&buffer, fx.shared_object_count); put_u32(&buffer, fx.technique_count); size_offset = put_u32(&buffer, 0); /* Unstructured size. */ - put_u32(&buffer, 0); /* String count. */ + put_u32(&buffer, fx.string_count); put_u32(&buffer, fx.texture_count); put_u32(&buffer, fx.depth_stencil_state_count); - put_u32(&buffer, 0); /* Blend state count. */ + put_u32(&buffer, fx.blend_state_count); put_u32(&buffer, fx.rasterizer_state_count); put_u32(&buffer, fx.sampler_state_count); put_u32(&buffer, fx.rtv_count); @@ -2295,10 +2572,10 @@ static int hlsl_fx_5_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) put_u32(&buffer, fx.shared_object_count); put_u32(&buffer, fx.technique_count); size_offset = put_u32(&buffer, 0); /* Unstructured size. */ - put_u32(&buffer, 0); /* String count. */ + put_u32(&buffer, fx.string_count); put_u32(&buffer, fx.texture_count); put_u32(&buffer, fx.depth_stencil_state_count); - put_u32(&buffer, 0); /* Blend state count. */ + put_u32(&buffer, fx.blend_state_count); put_u32(&buffer, fx.rasterizer_state_count); put_u32(&buffer, fx.sampler_state_count); put_u32(&buffer, fx.rtv_count); diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c index 10e12ea56f2..d1f02ab568b 100644 --- a/libs/vkd3d/libs/vkd3d-shader/glsl.c +++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c @@ -115,7 +115,7 @@ static void glsl_src_init(struct glsl_src *glsl_src, struct vkd3d_glsl_generator if (reg->non_uniform) vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, - "Internal compiler error: Unhandled 'non-uniform' modifer."); + "Internal compiler error: Unhandled 'non-uniform' modifier."); if (vsir_src->modifiers) vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, "Internal compiler error: Unhandled source modifier(s) %#x.", vsir_src->modifiers); @@ -138,10 +138,10 @@ static uint32_t glsl_dst_init(struct glsl_dst *glsl_dst, struct vkd3d_glsl_gener if (ins->flags & VKD3DSI_PRECISE_XYZW) vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, - "Internal compiler error: Unhandled 'precise' modifer."); + "Internal compiler error: Unhandled 'precise' modifier."); if (vsir_dst->reg.non_uniform) vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, - "Internal compiler error: Unhandled 'non-uniform' modifer."); + "Internal compiler error: Unhandled 'non-uniform' modifier."); glsl_dst->vsir = vsir_dst; glsl_dst->register_name = vkd3d_string_buffer_get(&gen->string_buffers); diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c index 7f85195382d..bd5baacd83d 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c @@ -167,7 +167,14 @@ void hlsl_free_var(struct hlsl_ir_var *decl) for (k = 0; k <= HLSL_REGSET_LAST_OBJECT; ++k) vkd3d_free((void *)decl->objects_usage[k]); - vkd3d_free(decl->default_values); + if (decl->default_values) + { + unsigned int component_count = hlsl_type_component_count(decl->data_type); + + for (k = 0; k < component_count; ++k) + vkd3d_free((void *)decl->default_values[k].string); + vkd3d_free(decl->default_values); + } for (i = 0; i < decl->state_block_count; ++i) hlsl_free_state_block(decl->state_blocks[i]); @@ -385,6 +392,8 @@ static void hlsl_type_calculate_reg_size(struct hlsl_ctx *ctx, struct hlsl_type case HLSL_CLASS_DOMAIN_SHADER: case HLSL_CLASS_HULL_SHADER: case HLSL_CLASS_GEOMETRY_SHADER: + case HLSL_CLASS_BLEND_STATE: + case HLSL_CLASS_NULL: break; } } @@ -459,6 +468,8 @@ static bool type_is_single_component(const struct hlsl_type *type) case HLSL_CLASS_DOMAIN_SHADER: case HLSL_CLASS_HULL_SHADER: case HLSL_CLASS_GEOMETRY_SHADER: + case HLSL_CLASS_BLEND_STATE: + case HLSL_CLASS_NULL: return true; case HLSL_CLASS_VECTOR: @@ -615,6 +626,7 @@ unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_ty case HLSL_CLASS_DOMAIN_SHADER: case HLSL_CLASS_HULL_SHADER: case HLSL_CLASS_GEOMETRY_SHADER: + case HLSL_CLASS_BLEND_STATE: VKD3D_ASSERT(idx == 0); break; @@ -624,6 +636,7 @@ unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_ty case HLSL_CLASS_VOID: case HLSL_CLASS_SCALAR: case HLSL_CLASS_CONSTANT_BUFFER: + case HLSL_CLASS_NULL: vkd3d_unreachable(); } type = next_type; @@ -922,6 +935,7 @@ static const char * get_case_insensitive_typename(const char *name) "texture", "vector", "vertexshader", + "string", }; unsigned int i; @@ -1019,6 +1033,8 @@ unsigned int hlsl_type_component_count(const struct hlsl_type *type) case HLSL_CLASS_DOMAIN_SHADER: case HLSL_CLASS_HULL_SHADER: case HLSL_CLASS_GEOMETRY_SHADER: + case HLSL_CLASS_BLEND_STATE: + case HLSL_CLASS_NULL: return 1; case HLSL_CLASS_EFFECT_GROUP: @@ -1110,6 +1126,8 @@ bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2 case HLSL_CLASS_DOMAIN_SHADER: case HLSL_CLASS_HULL_SHADER: case HLSL_CLASS_GEOMETRY_SHADER: + case HLSL_CLASS_BLEND_STATE: + case HLSL_CLASS_NULL: return true; } @@ -1459,7 +1477,7 @@ struct hlsl_ir_node *hlsl_new_constant(struct hlsl_ctx *ctx, struct hlsl_type *t { struct hlsl_ir_constant *c; - VKD3D_ASSERT(type->class <= HLSL_CLASS_VECTOR); + VKD3D_ASSERT(type->class <= HLSL_CLASS_VECTOR || type->class == HLSL_CLASS_NULL); if (!(c = hlsl_alloc(ctx, sizeof(*c)))) return NULL; @@ -1522,6 +1540,12 @@ struct hlsl_ir_node *hlsl_new_string_constant(struct hlsl_ctx *ctx, const char * return &s->node; } +struct hlsl_ir_node *hlsl_new_null_constant(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc) +{ + struct hlsl_constant_value value = { 0 }; + return hlsl_new_constant(ctx, ctx->builtin_types.null, &value, loc); +} + struct hlsl_ir_node *hlsl_new_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], struct hlsl_type *data_type, const struct vkd3d_shader_location *loc) @@ -2562,6 +2586,8 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru case HLSL_CLASS_DOMAIN_SHADER: case HLSL_CLASS_HULL_SHADER: case HLSL_CLASS_GEOMETRY_SHADER: + case HLSL_CLASS_BLEND_STATE: + case HLSL_CLASS_NULL: break; } @@ -3262,9 +3288,15 @@ void hlsl_dump_var_default_values(const struct hlsl_ir_var *var) vkd3d_string_buffer_printf(&buffer, "var \"%s\" default values:", var->name); for (k = 0; k < component_count; ++k) { - if (k % 4 == 0) + bool is_string = var->default_values[k].string; + + if (k % 4 == 0 || is_string) vkd3d_string_buffer_printf(&buffer, "\n "); - vkd3d_string_buffer_printf(&buffer, " 0x%08x", var->default_values[k].value.u); + + if (is_string) + vkd3d_string_buffer_printf(&buffer, " %s", debugstr_a(var->default_values[k].string)); + else + vkd3d_string_buffer_printf(&buffer, " 0x%08x", var->default_values[k].number.u); } vkd3d_string_buffer_printf(&buffer, "\n"); @@ -3922,8 +3954,10 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) ctx->builtin_types.sampler[bt] = type; } - ctx->builtin_types.string = hlsl_new_simple_type(ctx, "STRING", HLSL_CLASS_STRING); ctx->builtin_types.Void = hlsl_new_simple_type(ctx, "void", HLSL_CLASS_VOID); + ctx->builtin_types.null = hlsl_new_type(ctx, "NULL", HLSL_CLASS_NULL, HLSL_TYPE_UINT, 1, 1); + ctx->builtin_types.string = hlsl_new_simple_type(ctx, "string", HLSL_CLASS_STRING); + hlsl_scope_add_type(ctx->globals, ctx->builtin_types.string); hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "DepthStencilView", HLSL_CLASS_DEPTH_STENCIL_VIEW)); hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "DepthStencilState", HLSL_CLASS_DEPTH_STENCIL_STATE)); hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "fxgroup", HLSL_CLASS_EFFECT_GROUP)); @@ -3937,6 +3971,7 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "DomainShader", HLSL_CLASS_DOMAIN_SHADER)); hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "HullShader", HLSL_CLASS_HULL_SHADER)); hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "GeometryShader", HLSL_CLASS_GEOMETRY_SHADER)); + hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "BlendState", HLSL_CLASS_BLEND_STATE)); for (i = 0; i < ARRAY_SIZE(effect_types); ++i) { diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h index 7e8cd774ae2..22e25b23988 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h @@ -96,7 +96,9 @@ enum hlsl_type_class HLSL_CLASS_HULL_SHADER, HLSL_CLASS_GEOMETRY_SHADER, HLSL_CLASS_CONSTANT_BUFFER, + HLSL_CLASS_BLEND_STATE, HLSL_CLASS_VOID, + HLSL_CLASS_NULL, }; enum hlsl_base_type @@ -408,7 +410,7 @@ struct hlsl_attribute /* Reservation of a register and/or an offset for objects inside constant buffers, to be used as a * starting point of their allocation. They are available through the register(·) and the - * packoffset(·) syntaxes, respectivelly. + * packoffset(·) syntaxes, respectively. * The constant buffer offset is measured register components. */ struct hlsl_reg_reservation { @@ -454,8 +456,10 @@ struct hlsl_ir_var * This pointer is NULL for others. */ struct hlsl_default_value { + /* Default value, in case the component is a string, otherwise it is NULL. */ + const char *string; /* Default value, in case the component is a numeric value. */ - union hlsl_constant_value_component value; + union hlsl_constant_value_component number; } *default_values; /* A dynamic array containing the state block on the variable's declaration, if any. @@ -998,6 +1002,7 @@ struct hlsl_ctx struct hlsl_type *sampler[HLSL_SAMPLER_DIM_LAST_SAMPLER + 1]; struct hlsl_type *string; struct hlsl_type *Void; + struct hlsl_type *null; } builtin_types; /* List of the instruction nodes for initializing static variables. */ @@ -1450,6 +1455,7 @@ struct hlsl_type *hlsl_new_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim struct hlsl_type *hlsl_new_cb_type(struct hlsl_ctx *ctx, struct hlsl_type *format); struct hlsl_ir_node *hlsl_new_uint_constant(struct hlsl_ctx *ctx, unsigned int n, const struct vkd3d_shader_location *loc); +struct hlsl_ir_node *hlsl_new_null_constant(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc); struct hlsl_ir_node *hlsl_new_unary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, const struct vkd3d_shader_location *loc); struct hlsl_ir_var *hlsl_new_var(struct hlsl_ctx *ctx, const char *name, struct hlsl_type *type, diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.l b/libs/vkd3d/libs/vkd3d-shader/hlsl.l index b4db142f6c2..0c02b27817e 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.l +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.l @@ -107,6 +107,7 @@ matrix {return KW_MATRIX; } namespace {return KW_NAMESPACE; } nointerpolation {return KW_NOINTERPOLATION; } noperspective {return KW_NOPERSPECTIVE; } +NULL {return KW_NULL; } out {return KW_OUT; } packoffset {return KW_PACKOFFSET; } pass {return KW_PASS; } @@ -144,6 +145,7 @@ stateblock {return KW_STATEBLOCK; } stateblock_state {return KW_STATEBLOCK_STATE; } static {return KW_STATIC; } string {return KW_STRING; } +String {return KW_STRING; } struct {return KW_STRUCT; } switch {return KW_SWITCH; } tbuffer {return KW_TBUFFER; } diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y index 30bd53d0c49..3f319dea0d8 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y @@ -304,6 +304,26 @@ static bool implicit_compatible_data_types(struct hlsl_ctx *ctx, struct hlsl_typ } } + if (src->class == HLSL_CLASS_NULL) + { + switch (dst->class) + { + case HLSL_CLASS_DEPTH_STENCIL_STATE: + case HLSL_CLASS_DEPTH_STENCIL_VIEW: + case HLSL_CLASS_PIXEL_SHADER: + case HLSL_CLASS_RASTERIZER_STATE: + case HLSL_CLASS_RENDER_TARGET_VIEW: + case HLSL_CLASS_SAMPLER: + case HLSL_CLASS_STRING: + case HLSL_CLASS_TEXTURE: + case HLSL_CLASS_UAV: + case HLSL_CLASS_VERTEX_SHADER: + return true; + default: + break; + } + } + return hlsl_types_are_componentwise_equal(ctx, src, dst); } @@ -331,6 +351,9 @@ static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct hlsl_block *bl if (hlsl_types_are_equal(src_type, dst_type)) return node; + if (src_type->class == HLSL_CLASS_NULL) + return node; + if (src_type->class > HLSL_CLASS_VECTOR || dst_type->class > HLSL_CLASS_VECTOR) { unsigned int src_comp_count = hlsl_type_component_count(src_type); @@ -575,11 +598,10 @@ static void check_loop_attributes(struct hlsl_ctx *ctx, const struct parse_attri hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Unroll attribute can't be used with 'fastopt' attribute."); } -static union hlsl_constant_value_component evaluate_static_expression(struct hlsl_ctx *ctx, +static struct hlsl_default_value evaluate_static_expression(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_type *dst_type, const struct vkd3d_shader_location *loc) { - union hlsl_constant_value_component ret = {0}; - struct hlsl_ir_constant *constant; + struct hlsl_default_value ret = {0}; struct hlsl_ir_node *node; struct hlsl_block expr; struct hlsl_src src; @@ -631,8 +653,16 @@ static union hlsl_constant_value_component evaluate_static_expression(struct hls if (node->type == HLSL_IR_CONSTANT) { - constant = hlsl_ir_constant(node); - ret = constant->value.u[0]; + struct hlsl_ir_constant *constant = hlsl_ir_constant(node); + + ret.number = constant->value.u[0]; + } + else if (node->type == HLSL_IR_STRING_CONSTANT) + { + struct hlsl_ir_string_constant *string = hlsl_ir_string_constant(node); + + if (!(ret.string = vkd3d_strdup(string->string))) + return ret; } else if (node->type == HLSL_IR_STRING_CONSTANT) { @@ -652,10 +682,11 @@ static union hlsl_constant_value_component evaluate_static_expression(struct hls static unsigned int evaluate_static_expression_as_uint(struct hlsl_ctx *ctx, struct hlsl_block *block, const struct vkd3d_shader_location *loc) { - union hlsl_constant_value_component res; + struct hlsl_default_value res; res = evaluate_static_expression(ctx, block, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc); - return res.u; + VKD3D_ASSERT(!res.string); + return res.number.u; } static struct hlsl_block *create_loop(struct hlsl_ctx *ctx, enum loop_type type, @@ -1868,49 +1899,51 @@ static struct hlsl_ir_node *add_binary_dot_expr(struct hlsl_ctx *ctx, struct hls return add_expr(ctx, instrs, op, args, ret_type, loc); } -static struct hlsl_block *add_binary_expr_merge(struct hlsl_ctx *ctx, struct hlsl_block *block1, - struct hlsl_block *block2, enum hlsl_ir_expr_op op, const struct vkd3d_shader_location *loc) +static struct hlsl_ir_node *add_binary_expr(struct hlsl_ctx *ctx, struct hlsl_block *block, enum hlsl_ir_expr_op op, + struct hlsl_ir_node *lhs, struct hlsl_ir_node *rhs, const struct vkd3d_shader_location *loc) { - struct hlsl_ir_node *arg1 = node_from_block(block1), *arg2 = node_from_block(block2); - - hlsl_block_add_block(block1, block2); - destroy_block(block2); - switch (op) { case HLSL_OP2_ADD: case HLSL_OP2_DIV: case HLSL_OP2_MOD: case HLSL_OP2_MUL: - add_binary_arithmetic_expr(ctx, block1, op, arg1, arg2, loc); - break; + return add_binary_arithmetic_expr(ctx, block, op, lhs, rhs, loc); case HLSL_OP2_BIT_AND: case HLSL_OP2_BIT_OR: case HLSL_OP2_BIT_XOR: - add_binary_bitwise_expr(ctx, block1, op, arg1, arg2, loc); - break; + return add_binary_bitwise_expr(ctx, block, op, lhs, rhs, loc); case HLSL_OP2_LESS: case HLSL_OP2_GEQUAL: case HLSL_OP2_EQUAL: case HLSL_OP2_NEQUAL: - add_binary_comparison_expr(ctx, block1, op, arg1, arg2, loc); - break; + return add_binary_comparison_expr(ctx, block, op, lhs, rhs, loc); case HLSL_OP2_LOGIC_AND: case HLSL_OP2_LOGIC_OR: - add_binary_logical_expr(ctx, block1, op, arg1, arg2, loc); - break; + return add_binary_logical_expr(ctx, block, op, lhs, rhs, loc); case HLSL_OP2_LSHIFT: case HLSL_OP2_RSHIFT: - add_binary_shift_expr(ctx, block1, op, arg1, arg2, loc); - break; + return add_binary_shift_expr(ctx, block, op, lhs, rhs, loc); default: vkd3d_unreachable(); } +} + +static struct hlsl_block *add_binary_expr_merge(struct hlsl_ctx *ctx, struct hlsl_block *block1, + struct hlsl_block *block2, enum hlsl_ir_expr_op op, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *arg1 = node_from_block(block1), *arg2 = node_from_block(block2); + + hlsl_block_add_block(block1, block2); + destroy_block(block2); + + if (add_binary_expr(ctx, block1, op, arg1, arg2, loc) == NULL) + return NULL; return block1; } @@ -2034,7 +2067,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct hlsl_blo enum hlsl_ir_expr_op op = op_from_assignment(assign_op); VKD3D_ASSERT(op); - if (!(rhs = add_binary_arithmetic_expr(ctx, block, op, lhs, rhs, &rhs->loc))) + if (!(rhs = add_binary_expr(ctx, block, op, lhs, rhs, &rhs->loc))) return NULL; } @@ -2350,7 +2383,7 @@ static void initialize_var_components(struct hlsl_ctx *ctx, struct hlsl_block *i if (!hlsl_clone_block(ctx, &block, instrs)) return; - default_value.value = evaluate_static_expression(ctx, &block, dst_comp_type, &src->loc); + default_value = evaluate_static_expression(ctx, &block, dst_comp_type, &src->loc); if (dst->is_param) dst_index = *store_index; @@ -2908,14 +2941,17 @@ static bool add_user_call(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *fu struct hlsl_ir_node *comp; struct hlsl_block store_block; - value.u[0] = param->default_values[j].value; - if (!(comp = hlsl_new_constant(ctx, type, &value, loc))) - return false; - hlsl_block_add_instr(args->instrs, comp); + if (!param->default_values[j].string) + { + value.u[0] = param->default_values[j].number; + if (!(comp = hlsl_new_constant(ctx, type, &value, loc))) + return false; + hlsl_block_add_instr(args->instrs, comp); - if (!hlsl_new_store_component(ctx, &store_block, ¶m_deref, j, comp)) - return false; - hlsl_block_add_block(args->instrs, &store_block); + if (!hlsl_new_store_component(ctx, &store_block, ¶m_deref, j, comp)) + return false; + hlsl_block_add_block(args->instrs, &store_block); + } } } @@ -6050,6 +6086,7 @@ static bool state_block_add_entry(struct hlsl_state_block *state_block, struct h %token KW_NAMESPACE %token KW_NOINTERPOLATION %token KW_NOPERSPECTIVE +%token KW_NULL %token KW_OUT %token KW_PACKOFFSET %token KW_PASS @@ -7304,12 +7341,6 @@ type_no_void: { validate_texture_format_type(ctx, $3, &@3); - if (hlsl_version_lt(ctx, 4, 1)) - { - hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "Multisampled texture object declaration needs sample count for profile %s.", ctx->profile->name); - } - $$ = hlsl_new_texture_type(ctx, $1, $3, 0); } | texture_ms_type '<' type ',' shift_expr '>' @@ -7433,6 +7464,10 @@ type_no_void: { $$ = hlsl_get_type(ctx->cur_scope, "RasterizerState", true, true); } + | KW_BLENDSTATE + { + $$ = hlsl_get_type(ctx->cur_scope, "BlendState", true, true); + } type: type_no_void @@ -8323,6 +8358,18 @@ primary_expr: YYABORT; } } + | KW_NULL + { + struct hlsl_ir_node *c; + + if (!(c = hlsl_new_null_constant(ctx, &@1))) + YYABORT; + if (!($$ = make_block(ctx, c))) + { + hlsl_free_instr(c); + YYABORT; + } + } | VAR_IDENTIFIER { struct hlsl_ir_load *load; diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c index 049461cdb7d..a695eefabf6 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c @@ -1648,6 +1648,8 @@ static bool copy_propagation_transform_load(struct hlsl_ctx *ctx, case HLSL_CLASS_RENDER_TARGET_VIEW: case HLSL_CLASS_DEPTH_STENCIL_VIEW: case HLSL_CLASS_GEOMETRY_SHADER: + case HLSL_CLASS_BLEND_STATE: + case HLSL_CLASS_NULL: break; case HLSL_CLASS_MATRIX: diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c index c1b8582af6d..6dbe30b1553 100644 --- a/libs/vkd3d/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d/libs/vkd3d-shader/ir.c @@ -3831,11 +3831,16 @@ static void vsir_cfg_compute_dominators(struct vsir_cfg *cfg) { struct vsir_block *block2 = &cfg->blocks[j]; - if (block2->label == 0) + if (block2->label == 0 || !vsir_block_dominates(block, block2)) continue; - if (vsir_block_dominates(block, block2)) - vkd3d_string_buffer_printf(&cfg->debug_buffer, " %u", block2->label); + if (cfg->debug_buffer.content_size > 512) + { + TRACE("%s...\n", cfg->debug_buffer.buffer); + vkd3d_string_buffer_clear(&cfg->debug_buffer); + vkd3d_string_buffer_printf(&cfg->debug_buffer, "Block %u dominates: ...", block->label); + } + vkd3d_string_buffer_printf(&cfg->debug_buffer, " %u", block2->label); } TRACE("%s\n", cfg->debug_buffer.buffer); vkd3d_string_buffer_clear(&cfg->debug_buffer); @@ -3927,7 +3932,16 @@ static enum vkd3d_result vsir_cfg_compute_loops(struct vsir_cfg *cfg) vkd3d_string_buffer_printf(&cfg->debug_buffer, "Back edge %u -> %u with loop:", block->label, header->label); for (k = 0; k < loop->count; ++k) + { + if (cfg->debug_buffer.content_size > 512) + { + TRACE("%s...\n", cfg->debug_buffer.buffer); + vkd3d_string_buffer_clear(&cfg->debug_buffer); + vkd3d_string_buffer_printf(&cfg->debug_buffer, "Back edge %u -> %u with loop: ...", + block->label, header->label); + } vkd3d_string_buffer_printf(&cfg->debug_buffer, " %u", loop->blocks[k]->label); + } TRACE("%s\n", cfg->debug_buffer.buffer); vkd3d_string_buffer_clear(&cfg->debug_buffer); @@ -4150,7 +4164,15 @@ static enum vkd3d_result vsir_cfg_sort_nodes(struct vsir_cfg *cfg) vkd3d_string_buffer_printf(&cfg->debug_buffer, "Block order:"); for (i = 0; i < cfg->order.count; ++i) + { + if (cfg->debug_buffer.content_size > 512) + { + TRACE("%s...\n", cfg->debug_buffer.buffer); + vkd3d_string_buffer_clear(&cfg->debug_buffer); + vkd3d_string_buffer_printf(&cfg->debug_buffer, "Block order: ..."); + } vkd3d_string_buffer_printf(&cfg->debug_buffer, " %u", cfg->order.blocks[i]->label); + } TRACE("%s\n", cfg->debug_buffer.buffer); vkd3d_string_buffer_clear(&cfg->debug_buffer); @@ -4204,7 +4226,7 @@ static enum vkd3d_result vsir_cfg_generate_synthetic_loop_intervals(struct vsir_ ACTION_EXTEND, } action = ACTION_CREATE_NEW; - /* We've already contructed loop intervals for the back + /* We've already constructed loop intervals for the back * edges, there's nothing more to do. */ if (vsir_block_dominates(successor, block)) continue; @@ -4462,7 +4484,7 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg) VKD3D_ASSERT(inner_loop->type == STRUCTURE_TYPE_LOOP); /* Otherwise, if one of the branches is - * continueing the inner loop we're inside, + * continue-ing the inner loop we're inside, * make sure it's the false branch (because it * will be optimized out later). */ if (action_true.jump_type == JUMP_CONTINUE && action_true.target == inner_loop->u.loop.idx) @@ -5104,14 +5126,14 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_jump(struct vsir_cfg *cfg, struct vsir_cfg_emit_target *target = cfg->target; const struct vkd3d_shader_location no_loc = {0}; /* Encode the jump target as the loop index plus a bit to remember whether - * we're breaking or continueing. */ + * we're breaking or continue-ing. */ unsigned int jump_target = jump->target << 1; enum vkd3d_shader_opcode opcode; switch (jump->type) { case JUMP_CONTINUE: - /* If we're continueing the loop we're directly inside, then we can emit a + /* If we're continue-ing the loop we're directly inside, then we can emit a * `continue'. Otherwise we first have to break all the loops between here * and the loop to continue, recording our intention to continue * in the lowest bit of jump_target. */ diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c index d6d5bbc1c07..84f641cc316 100644 --- a/libs/vkd3d/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c @@ -22,6 +22,7 @@ */ #include "hlsl.h" +#include "vkd3d_shader_private.h" #define SM4_MAX_SRC_COUNT 6 #define SM4_MAX_DST_COUNT 2 @@ -3006,6 +3007,8 @@ static D3D_SHADER_VARIABLE_CLASS sm4_class(const struct hlsl_type *type) case HLSL_CLASS_DOMAIN_SHADER: case HLSL_CLASS_HULL_SHADER: case HLSL_CLASS_GEOMETRY_SHADER: + case HLSL_CLASS_BLEND_STATE: + case HLSL_CLASS_NULL: break; } vkd3d_unreachable(); @@ -3107,8 +3110,6 @@ static D3D_SHADER_INPUT_TYPE sm4_resource_type(const struct hlsl_type *type) { switch (type->class) { - case HLSL_CLASS_ARRAY: - return sm4_resource_type(type->e.array.type); case HLSL_CLASS_SAMPLER: return D3D_SIT_SAMPLER; case HLSL_CLASS_TEXTURE: @@ -3124,9 +3125,6 @@ static D3D_SHADER_INPUT_TYPE sm4_resource_type(const struct hlsl_type *type) static D3D_RESOURCE_RETURN_TYPE sm4_resource_format(const struct hlsl_type *type) { - if (type->class == HLSL_CLASS_ARRAY) - return sm4_resource_format(type->e.array.type); - switch (type->e.resource.format->e.numeric.type) { case HLSL_TYPE_DOUBLE: @@ -3151,9 +3149,6 @@ static D3D_RESOURCE_RETURN_TYPE sm4_resource_format(const struct hlsl_type *type static D3D_SRV_DIMENSION sm4_rdef_resource_dimension(const struct hlsl_type *type) { - if (type->class == HLSL_CLASS_ARRAY) - return sm4_rdef_resource_dimension(type->e.array.type); - switch (type->sampler_dim) { case HLSL_SAMPLER_DIM_1D: @@ -3190,11 +3185,18 @@ struct extern_resource const struct hlsl_buffer *buffer; char *name; - struct hlsl_type *data_type; bool is_user_packed; + /* The data type of a single component of the resource. + * This might be different from the data type of the resource itself in 4.0 + * profiles, where an array (or multi-dimensional array) is handled as a + * single resource, unlike in 5.0. */ + struct hlsl_type *component_type; + enum hlsl_regset regset; unsigned int id, space, index, bind_count; + + struct vkd3d_shader_location loc; }; static int sm4_compare_extern_resources(const void *a, const void *b) @@ -3289,14 +3291,16 @@ static struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, un extern_resources[*count].buffer = NULL; extern_resources[*count].name = name; - extern_resources[*count].data_type = component_type; extern_resources[*count].is_user_packed = !!var->reg_reservation.reg_type; + extern_resources[*count].component_type = component_type; + extern_resources[*count].regset = regset; extern_resources[*count].id = var->regs[regset].id; extern_resources[*count].space = var->regs[regset].space; extern_resources[*count].index = var->regs[regset].index + regset_offset; extern_resources[*count].bind_count = 1; + extern_resources[*count].loc = var->loc; ++*count; } @@ -3333,17 +3337,19 @@ static struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, un extern_resources[*count].buffer = NULL; extern_resources[*count].name = name; - extern_resources[*count].data_type = var->data_type; /* For some reason 5.1 resources aren't marked as * user-packed, but cbuffers still are. */ extern_resources[*count].is_user_packed = hlsl_version_lt(ctx, 5, 1) && !!var->reg_reservation.reg_type; + extern_resources[*count].component_type = hlsl_type_get_component_type(ctx, var->data_type, 0); + extern_resources[*count].regset = r; extern_resources[*count].id = var->regs[r].id; extern_resources[*count].space = var->regs[r].space; extern_resources[*count].index = var->regs[r].index; extern_resources[*count].bind_count = var->bind_count[r]; + extern_resources[*count].loc = var->loc; ++*count; } @@ -3374,14 +3380,16 @@ static struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, un extern_resources[*count].buffer = buffer; extern_resources[*count].name = name; - extern_resources[*count].data_type = NULL; extern_resources[*count].is_user_packed = !!buffer->reservation.reg_type; + extern_resources[*count].component_type = NULL; + extern_resources[*count].regset = HLSL_REGSET_NUMERIC; extern_resources[*count].id = buffer->reg.id; extern_resources[*count].space = buffer->reg.space; extern_resources[*count].index = buffer->reg.index; extern_resources[*count].bind_count = 1; + extern_resources[*count].loc = buffer->loc; ++*count; } @@ -3458,13 +3466,13 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) if (resource->buffer) put_u32(&buffer, resource->buffer->type == HLSL_BUFFER_CONSTANT ? D3D_SIT_CBUFFER : D3D_SIT_TBUFFER); else - put_u32(&buffer, sm4_resource_type(resource->data_type)); + put_u32(&buffer, sm4_resource_type(resource->component_type)); if (resource->regset == HLSL_REGSET_TEXTURES || resource->regset == HLSL_REGSET_UAVS) { - unsigned int dimx = hlsl_type_get_component_type(ctx, resource->data_type, 0)->e.resource.format->dimx; + unsigned int dimx = resource->component_type->e.resource.format->dimx; - put_u32(&buffer, sm4_resource_format(resource->data_type)); - put_u32(&buffer, sm4_rdef_resource_dimension(resource->data_type)); + put_u32(&buffer, sm4_resource_format(resource->component_type)); + put_u32(&buffer, sm4_rdef_resource_dimension(resource->component_type)); put_u32(&buffer, ~0u); /* FIXME: multisample count */ flags |= (dimx - 1) << VKD3D_SM4_SIF_TEXTURE_COMPONENTS_SHIFT; } @@ -3593,6 +3601,13 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) unsigned int comp_offset; enum hlsl_regset regset; + if (comp_type->class == HLSL_CLASS_STRING) + { + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Cannot write string default value."); + continue; + } + comp_offset = hlsl_type_get_component_offset(ctx, var->data_type, k, ®set); if (regset == HLSL_REGSET_NUMERIC) { @@ -3600,7 +3615,7 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) hlsl_fixme(ctx, &var->loc, "Write double default values."); set_u32(&buffer, default_value_offset + comp_offset * sizeof(uint32_t), - var->default_values[k].value.u); + var->default_values[k].number.u); } } } @@ -4269,7 +4284,6 @@ static void write_sm4_dcl_constant_buffer(const struct tpf_writer *tpf, const st static void write_sm4_dcl_samplers(const struct tpf_writer *tpf, const struct extern_resource *resource) { - struct hlsl_type *component_type; unsigned int i; struct sm4_instruction instr = { @@ -4279,13 +4293,11 @@ static void write_sm4_dcl_samplers(const struct tpf_writer *tpf, const struct ex .dst_count = 1, }; - component_type = hlsl_type_get_component_type(tpf->ctx, resource->data_type, 0); + VKD3D_ASSERT(resource->regset == HLSL_REGSET_SAMPLERS); - if (component_type->sampler_dim == HLSL_SAMPLER_DIM_COMPARISON) + if (resource->component_type->sampler_dim == HLSL_SAMPLER_DIM_COMPARISON) instr.extra_bits |= VKD3D_SM4_SAMPLER_COMPARISON << VKD3D_SM4_SAMPLER_MODE_SHIFT; - VKD3D_ASSERT(resource->regset == HLSL_REGSET_SAMPLERS); - for (i = 0; i < resource->bind_count; ++i) { if (resource->var && !resource->var->objects_usage[HLSL_REGSET_SAMPLERS][i].used) @@ -4317,11 +4329,12 @@ static void write_sm4_dcl_textures(const struct tpf_writer *tpf, const struct ex enum hlsl_regset regset = uav ? HLSL_REGSET_UAVS : HLSL_REGSET_TEXTURES; struct hlsl_type *component_type; struct sm4_instruction instr; + bool multisampled; unsigned int i; VKD3D_ASSERT(resource->regset == regset); - component_type = hlsl_type_get_component_type(tpf->ctx, resource->data_type, 0); + component_type = resource->component_type; for (i = 0; i < resource->bind_count; ++i) { @@ -4339,6 +4352,16 @@ static void write_sm4_dcl_textures(const struct tpf_writer *tpf, const struct ex .idx_count = 1, }; + multisampled = component_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS + || component_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY; + + if (hlsl_version_lt(tpf->ctx, 4, 1) && multisampled && !component_type->sample_count) + { + hlsl_error(tpf->ctx, &resource->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Multisampled texture object declaration needs sample count for profile %s.", + tpf->ctx->profile->name); + } + if (hlsl_version_ge(tpf->ctx, 5, 1)) { VKD3D_ASSERT(!i); @@ -4358,18 +4381,18 @@ static void write_sm4_dcl_textures(const struct tpf_writer *tpf, const struct ex if (uav) { - switch (resource->data_type->sampler_dim) + switch (component_type->sampler_dim) { - case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER: - instr.opcode = VKD3D_SM5_OP_DCL_UAV_STRUCTURED; - instr.byte_stride = resource->data_type->e.resource.format->reg_size[HLSL_REGSET_NUMERIC] * 4; - break; - default: - instr.opcode = VKD3D_SM5_OP_DCL_UAV_TYPED; - break; + case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER: + instr.opcode = VKD3D_SM5_OP_DCL_UAV_STRUCTURED; + instr.byte_stride = component_type->e.resource.format->reg_size[HLSL_REGSET_NUMERIC] * 4; + break; + default: + instr.opcode = VKD3D_SM5_OP_DCL_UAV_TYPED; + break; } - if (resource->data_type->e.resource.rasteriser_ordered) + if (component_type->e.resource.rasteriser_ordered) instr.opcode |= VKD3DSUF_RASTERISER_ORDERED_VIEW << VKD3D_SM5_UAV_FLAGS_SHIFT; } else @@ -4378,11 +4401,8 @@ static void write_sm4_dcl_textures(const struct tpf_writer *tpf, const struct ex } instr.extra_bits |= (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) - { + if (multisampled) instr.extra_bits |= component_type->sample_count << VKD3D_SM4_RESOURCE_SAMPLE_COUNT_SHIFT; - } write_sm4_instruction(tpf, &instr); } @@ -6082,7 +6102,7 @@ static void write_sm4_sfi0(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) extern_resources = sm4_get_extern_resources(ctx, &extern_resources_count); for (unsigned int i = 0; i < extern_resources_count; ++i) { - if (extern_resources[i].data_type && extern_resources[i].data_type->e.resource.rasteriser_ordered) + if (extern_resources[i].component_type && extern_resources[i].component_type->e.resource.rasteriser_ordered) *flags |= VKD3D_SM4_REQUIRES_ROVS; } sm4_free_extern_resources(extern_resources, extern_resources_count); diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h index 13b4dab76d1..ef66a8ca07a 100644 --- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h @@ -51,7 +51,6 @@ #include "vkd3d_shader.h" #include "wine/list.h" -#include #include #include #include diff --git a/libs/vkd3d/libs/vkd3d/resource.c b/libs/vkd3d/libs/vkd3d/resource.c index ac29088b9cb..6d6820d3752 100644 --- a/libs/vkd3d/libs/vkd3d/resource.c +++ b/libs/vkd3d/libs/vkd3d/resource.c @@ -2184,7 +2184,7 @@ static HRESULT vkd3d_bind_heap_memory(struct d3d12_device *device, goto allocate_memory; } - /* Syncronisation is not required for binding, but vkMapMemory() may be called + /* Synchronisation is not required for binding, but vkMapMemory() may be called * from another thread and it requires exclusive access. */ vkd3d_mutex_lock(&heap->mutex); diff --git a/libs/vkd3d/libs/vkd3d/state.c b/libs/vkd3d/libs/vkd3d/state.c index 0bdb7ea524d..519d1a2d85f 100644 --- a/libs/vkd3d/libs/vkd3d/state.c +++ b/libs/vkd3d/libs/vkd3d/state.c @@ -635,14 +635,18 @@ static HRESULT d3d12_root_signature_init_push_constants(struct d3d12_root_signat for (i = 0; i < desc->NumParameters; ++i) { const D3D12_ROOT_PARAMETER *p = &desc->pParameters[i]; + D3D12_SHADER_VISIBILITY visibility; + if (p->ParameterType != D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS) continue; - VKD3D_ASSERT(p->ShaderVisibility <= D3D12_SHADER_VISIBILITY_PIXEL); - push_constants[p->ShaderVisibility].stageFlags = use_vk_heaps ? VK_SHADER_STAGE_ALL - : stage_flags_from_visibility(p->ShaderVisibility); - push_constants[p->ShaderVisibility].size += align(p->u.Constants.Num32BitValues, 4) * sizeof(uint32_t); + visibility = use_vk_heaps ? D3D12_SHADER_VISIBILITY_ALL : p->ShaderVisibility; + VKD3D_ASSERT(visibility <= D3D12_SHADER_VISIBILITY_PIXEL); + + push_constants[visibility].stageFlags = stage_flags_from_visibility(visibility); + push_constants[visibility].size += align(p->u.Constants.Num32BitValues, 4) * sizeof(uint32_t); } + if (push_constants[D3D12_SHADER_VISIBILITY_ALL].size) { /* When D3D12_SHADER_VISIBILITY_ALL is used we use a single push diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/libs/vkd3d/vkd3d_private.h index a4bd2202f39..ba4e2e8488d 100644 --- a/libs/vkd3d/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/libs/vkd3d/vkd3d_private.h @@ -37,7 +37,6 @@ #include "vkd3d.h" #include "vkd3d_shader.h" -#include #include #include #include @@ -679,7 +678,7 @@ static inline void *d3d12_desc_get_object_ref(const volatile struct d3d12_desc * void *view; /* Some games, e.g. Shadow of the Tomb Raider, GRID 2019, and Horizon Zero Dawn, write descriptors - * from multiple threads without syncronisation. This is apparently valid in Windows. */ + * from multiple threads without synchronisation. This is apparently valid in Windows. */ for (;;) { do -- 2.43.0