From 7a3d9f859ea9571d19d388781f91855a4e06f122 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Thu, 3 Aug 2023 08:38:38 +1000 Subject: [PATCH 3/3] Updated vkd3d to b4bb3931c5e7e59496c07c2d4e3b6cfd3bf91cf1. --- include/d3d12.idl | 66 +++ libs/vkd3d/include/private/vkd3d_common.h | 15 + libs/vkd3d/include/vkd3d_shader.h | 59 ++- libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 104 +++- libs/vkd3d/libs/vkd3d-shader/dxil.c | 59 ++- libs/vkd3d/libs/vkd3d-shader/hlsl.c | 32 +- libs/vkd3d/libs/vkd3d-shader/hlsl.h | 4 +- libs/vkd3d/libs/vkd3d-shader/hlsl.y | 494 ++++++++++++------ libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 152 +++--- libs/vkd3d/libs/vkd3d-shader/ir.c | 159 +++++- libs/vkd3d/libs/vkd3d-shader/preproc.l | 140 +++-- libs/vkd3d/libs/vkd3d-shader/spirv.c | 164 ++++-- libs/vkd3d/libs/vkd3d-shader/tpf.c | 83 ++- .../libs/vkd3d-shader/vkd3d_shader_main.c | 9 + .../libs/vkd3d-shader/vkd3d_shader_private.h | 15 +- libs/vkd3d/libs/vkd3d/command.c | 451 +++++++++------- libs/vkd3d/libs/vkd3d/device.c | 20 +- libs/vkd3d/libs/vkd3d/resource.c | 238 ++++++++- libs/vkd3d/libs/vkd3d/vkd3d_private.h | 55 +- 19 files changed, 1756 insertions(+), 563 deletions(-) diff --git a/include/d3d12.idl b/include/d3d12.idl index c6064939e1f..5811608b94f 100644 --- a/include/d3d12.idl +++ b/include/d3d12.idl @@ -44,6 +44,7 @@ const UINT D3D12_DEFAULT_STENCIL_WRITE_MASK = 0xff; const UINT D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND = 0xffffffff; cpp_quote("#define D3D12_FLOAT32_MAX (3.402823466e+38f)") const UINT D3D12_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT = 32; +const UINT D3D12_PACKED_TILE = 0xffffffff; const UINT D3D12_UAV_SLOT_COUNT = 64; const UINT D3D12_REQ_CONSTANT_BUFFER_ELEMENT_COUNT = 4096; const UINT D3D12_REQ_IMMEDIATE_CONSTANT_BUFFER_ELEMENT_COUNT = 4096; @@ -72,6 +73,7 @@ const UINT D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT = 4096; const UINT D3D12_STANDARD_MAXIMUM_ELEMENT_ALIGNMENT_BYTE_MULTIPLE = 4; const UINT D3D12_TEXTURE_DATA_PITCH_ALIGNMENT = 256; const UINT D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT = 512; +const UINT D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES = 65536; const UINT D3D12_UAV_COUNTER_PLACEMENT_ALIGNMENT = 4096; const UINT D3D12_VS_INPUT_REGISTER_COUNT = 32; const UINT D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE = 16; @@ -1853,6 +1855,24 @@ typedef struct D3D12_WRITEBUFFERIMMEDIATE_PARAMETER UINT32 Value; } D3D12_WRITEBUFFERIMMEDIATE_PARAMETER; +typedef enum D3D12_PROTECTED_RESOURCE_SESSION_FLAGS +{ + D3D12_PROTECTED_RESOURCE_SESSION_FLAG_NONE = 0, +} D3D12_PROTECTED_RESOURCE_SESSION_FLAGS; +cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_PROTECTED_RESOURCE_SESSION_FLAGS);") + +typedef enum D3D12_PROTECTED_SESSION_STATUS +{ + D3D12_PROTECTED_SESSION_STATUS_OK = 0, + D3D12_PROTECTED_SESSION_STATUS_INVALID = 1, +} D3D12_PROTECTED_SESSION_STATUS; + +typedef struct D3D12_PROTECTED_RESOURCE_SESSION_DESC +{ + UINT NodeMask; + D3D12_PROTECTED_RESOURCE_SESSION_FLAGS Flags; +} D3D12_PROTECTED_RESOURCE_SESSION_DESC; + [ uuid(c4fec28f-7966-4e95-9f94-f431cb56c3b8), object, @@ -2214,6 +2234,41 @@ interface ID3D12GraphicsCommandList2 : ID3D12GraphicsCommandList1 const D3D12_WRITEBUFFERIMMEDIATE_MODE *modes); } +[ + uuid(a1533d18-0ac1-4084-85b9-89a96116806b), + object, + local, + pointer_default(unique) +] +interface ID3D12ProtectedSession : ID3D12DeviceChild +{ + HRESULT GetStatusFence(REFIID riid, void **fence); + + D3D12_PROTECTED_SESSION_STATUS GetSessionStatus(); +} + +[ + uuid(6cd696f4-f289-40cc-8091-5a6c0a099c3d), + object, + local, + pointer_default(unique) +] +interface ID3D12ProtectedResourceSession : ID3D12ProtectedSession +{ + D3D12_PROTECTED_RESOURCE_SESSION_DESC GetDesc(); +} + +[ + uuid(6fda83a7-b84c-4e38-9ac8-c7bd22016b3d), + object, + local, + pointer_default(unique) +] +interface ID3D12GraphicsCommandList3 : ID3D12GraphicsCommandList2 +{ + void SetProtectedResourceSession(ID3D12ProtectedResourceSession *protected_resource_session); +} + typedef enum D3D12_TILE_RANGE_FLAGS { D3D12_TILE_RANGE_FLAG_NONE = 0x0, @@ -2378,6 +2433,17 @@ interface ID3D12Fence : ID3D12Pageable HRESULT Signal(UINT64 value); } +[ + uuid(433685fe-e22b-4ca0-a8db-b5b4f4dd0e4a), + object, + local, + pointer_default(unique) +] +interface ID3D12Fence1 : ID3D12Fence +{ + D3D12_FENCE_FLAGS GetCreationFlags(); +} + [ uuid(6102dee4-af59-4b09-b999-b44d73f09b24), object, diff --git a/libs/vkd3d/include/private/vkd3d_common.h b/libs/vkd3d/include/private/vkd3d_common.h index 0263fc47297..f7d98f327f1 100644 --- a/libs/vkd3d/include/private/vkd3d_common.h +++ b/libs/vkd3d/include/private/vkd3d_common.h @@ -193,6 +193,21 @@ static inline int vkd3d_u32_compare(uint32_t x, uint32_t y) return (x > y) - (x < y); } +static inline bool bitmap_clear(uint32_t *map, unsigned int idx) +{ + return map[idx >> 5] &= ~(1u << (idx & 0x1f)); +} + +static inline bool bitmap_set(uint32_t *map, unsigned int idx) +{ + return map[idx >> 5] |= (1u << (idx & 0x1f)); +} + +static inline bool bitmap_is_set(const uint32_t *map, unsigned int idx) +{ + return map[idx >> 5] & (1u << (idx & 0x1f)); +} + static inline int ascii_isupper(int c) { return 'A' <= c && c <= 'Z'; diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h index 6c17a07b9d2..d6653d18e56 100644 --- a/libs/vkd3d/include/vkd3d_shader.h +++ b/libs/vkd3d/include/vkd3d_shader.h @@ -139,6 +139,14 @@ enum vkd3d_shader_compile_option_formatting_flags VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_FORMATTING_FLAGS), }; +enum vkd3d_shader_compile_option_pack_matrix_order +{ + VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_ROW_MAJOR = 0x00000001, + VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_COLUMN_MAJOR = 0x00000002, + + VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_ORDER), +}; + enum vkd3d_shader_compile_option_name { /** @@ -169,6 +177,15 @@ enum vkd3d_shader_compile_option_name * \since 1.7 */ VKD3D_SHADER_COMPILE_OPTION_WRITE_TESS_GEOM_POINT_SIZE = 0x00000006, + /** + * This option specifies default matrix packing order. It's only supported for HLSL source type. + * Explicit variable modifiers or pragmas will take precedence. + * + * \a value is a member of enum vkd3d_shader_compile_option_pack_matrix_order. + * + * \since 1.9 + */ + VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_ORDER = 0x00000007, VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_NAME), }; @@ -332,6 +349,25 @@ struct vkd3d_shader_parameter } u; }; +/** + * Symbolic register indices for mapping uniform constant register sets in + * legacy Direct3D bytecode to constant buffer views in the target environment. + * + * Members of this enumeration are used in + * \ref vkd3d_shader_resource_binding.register_index. + * + * \since 1.9 + */ +enum vkd3d_shader_d3dbc_constant_register +{ + /** The float constant register set, c# in Direct3D assembly. */ + VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER = 0x0, + /** The integer constant register set, i# in Direct3D assembly. */ + VKD3D_SHADER_D3DBC_INT_CONSTANT_REGISTER = 0x1, + /** The boolean constant register set, b# in Direct3D assembly. */ + VKD3D_SHADER_D3DBC_BOOL_CONSTANT_REGISTER = 0x2, +}; + /** * Describes the mapping of a single resource or resource array to its binding * point in the target environment. @@ -356,7 +392,14 @@ struct vkd3d_shader_resource_binding * support multiple register spaces, this parameter must be set to 0. */ unsigned int register_space; - /** Register index of the DXBC resource. */ + /** + * Register index of the Direct3D resource. + * + * For legacy Direct3D shaders, vkd3d-shader maps each constant register + * set to a single constant buffer view. This parameter names the register + * set to map, and must be a member of + * enum vkd3d_shader_d3dbc_constant_register. + */ unsigned int register_index; /** Shader stage(s) to which the resource is visible. */ enum vkd3d_shader_visibility shader_visibility; @@ -1330,6 +1373,20 @@ struct vkd3d_shader_descriptor_info * A chained structure enumerating the descriptors declared by a shader. * * This structure extends vkd3d_shader_compile_info. + * + * When scanning a legacy Direct3D shader, vkd3d-shader enumerates each + * constant register set used by the shader as a single constant buffer + * descriptor, as follows: + * - The \ref vkd3d_shader_descriptor_info.type field is set to + * VKD3D_SHADER_DESCRIPTOR_TYPE_CBV. + * - The \ref vkd3d_shader_descriptor_info.register_space field is set to zero. + * - The \ref vkd3d_shader_descriptor_info.register_index field is set to a + * member of enum vkd3d_shader_d3dbc_constant_register denoting which set + * is used. + * - The \ref vkd3d_shader_descriptor_info.count field is set to one. + * + * In summary, there may be up to three such descriptors, one for each register + * set used by the shader: float, integer, and boolean. */ struct vkd3d_shader_scan_descriptor_info { diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c index 369112ce18d..fe739339bd1 100644 --- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c @@ -214,6 +214,9 @@ struct vkd3d_shader_sm1_parser bool abort; struct vkd3d_shader_parser p; + +#define MAX_CONSTANT_COUNT 8192 + uint32_t constant_def_mask[3][MAX_CONSTANT_COUNT / 32]; }; /* This table is not order or position dependent. */ @@ -729,12 +732,60 @@ static bool add_signature_element_from_semantic(struct vkd3d_shader_sm1_parser * semantic->usage_idx, sysval, reg->idx[0].offset, true, mask); } -static void shader_sm1_scan_register(struct vkd3d_shader_sm1_parser *sm1, const struct vkd3d_shader_register *reg, unsigned int mask) +static void record_constant_register(struct vkd3d_shader_sm1_parser *sm1, + enum vkd3d_shader_d3dbc_constant_register set, uint32_t index, bool from_def) { + struct vkd3d_shader_desc *desc = &sm1->p.shader_desc; + + desc->flat_constant_count[set].used = max(desc->flat_constant_count[set].used, index + 1); + if (from_def) + { + /* d3d shaders have a maximum of 8192 constants; we should not overrun + * this array. */ + assert((index / 32) <= ARRAY_SIZE(sm1->constant_def_mask[set])); + bitmap_set(sm1->constant_def_mask[set], index); + } +} + +static void shader_sm1_scan_register(struct vkd3d_shader_sm1_parser *sm1, + const struct vkd3d_shader_register *reg, unsigned int mask, bool from_def) +{ + struct vkd3d_shader_desc *desc = &sm1->p.shader_desc; uint32_t register_index = reg->idx[0].offset; - if (reg->type == VKD3DSPR_TEMP) - sm1->p.shader_desc.temp_count = max(sm1->p.shader_desc.temp_count, register_index + 1); + switch (reg->type) + { + case VKD3DSPR_TEMP: + desc->temp_count = max(desc->temp_count, register_index + 1); + break; + + case VKD3DSPR_CONST: + record_constant_register(sm1, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER, register_index, from_def); + break; + + case VKD3DSPR_CONST2: + record_constant_register(sm1, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER, 2048 + register_index, from_def); + break; + + case VKD3DSPR_CONST3: + record_constant_register(sm1, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER, 4096 + register_index, from_def); + break; + + case VKD3DSPR_CONST4: + record_constant_register(sm1, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER, 6144 + register_index, from_def); + break; + + case VKD3DSPR_CONSTINT: + record_constant_register(sm1, VKD3D_SHADER_D3DBC_INT_CONSTANT_REGISTER, register_index, from_def); + break; + + case VKD3DSPR_CONSTBOOL: + record_constant_register(sm1, VKD3D_SHADER_D3DBC_BOOL_CONSTANT_REGISTER, register_index, from_def); + break; + + default: + break; + } add_signature_element_from_register(sm1, reg, false, mask); } @@ -1076,16 +1127,19 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str { shader_sm1_read_dst_param(sm1, &p, dst_param); shader_sm1_read_immconst(sm1, &p, &src_params[0], VKD3D_IMMCONST_VEC4, VKD3D_DATA_FLOAT); + shader_sm1_scan_register(sm1, &dst_param->reg, dst_param->write_mask, true); } else if (ins->handler_idx == VKD3DSIH_DEFB) { shader_sm1_read_dst_param(sm1, &p, dst_param); shader_sm1_read_immconst(sm1, &p, &src_params[0], VKD3D_IMMCONST_SCALAR, VKD3D_DATA_UINT); + shader_sm1_scan_register(sm1, &dst_param->reg, dst_param->write_mask, true); } else if (ins->handler_idx == VKD3DSIH_DEFI) { shader_sm1_read_dst_param(sm1, &p, dst_param); shader_sm1_read_immconst(sm1, &p, &src_params[0], VKD3D_IMMCONST_VEC4, VKD3D_DATA_INT); + shader_sm1_scan_register(sm1, &dst_param->reg, dst_param->write_mask, true); } else { @@ -1093,7 +1147,7 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str if (ins->dst_count) { shader_sm1_read_dst_param(sm1, &p, dst_param); - shader_sm1_scan_register(sm1, &dst_param->reg, dst_param->write_mask); + shader_sm1_scan_register(sm1, &dst_param->reg, dst_param->write_mask, false); } /* Predication token */ @@ -1104,7 +1158,7 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str for (i = 0; i < ins->src_count; ++i) { shader_sm1_read_src_param(sm1, &p, &src_params[i]); - shader_sm1_scan_register(sm1, &src_params[i].reg, mask_from_swizzle(src_params[i].swizzle)); + shader_sm1_scan_register(sm1, &src_params[i].reg, mask_from_swizzle(src_params[i].swizzle), false); } } @@ -1212,12 +1266,30 @@ static enum vkd3d_result shader_sm1_init(struct vkd3d_shader_sm1_parser *sm1, return VKD3D_OK; } +static uint32_t get_external_constant_count(struct vkd3d_shader_sm1_parser *sm1, + enum vkd3d_shader_d3dbc_constant_register set) +{ + unsigned int j; + + /* Find the highest constant index which is not written by a DEF + * instruction. We can't (easily) use an FFZ function for this since it + * needs to be limited by the highest used register index. */ + for (j = sm1->p.shader_desc.flat_constant_count[set].used; j > 0; --j) + { + if (!bitmap_is_set(sm1->constant_def_mask[set], j - 1)) + return j; + } + + return 0; +} + int vkd3d_shader_sm1_parser_create(const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser **parser) { struct vkd3d_shader_instruction_array *instructions; struct vkd3d_shader_instruction *ins; struct vkd3d_shader_sm1_parser *sm1; + unsigned int i; int ret; if (!(sm1 = vkd3d_calloc(1, sizeof(*sm1)))) @@ -1257,6 +1329,9 @@ int vkd3d_shader_sm1_parser_create(const struct vkd3d_shader_compile_info *compi *parser = &sm1->p; + for (i = 0; i < ARRAY_SIZE(sm1->p.shader_desc.flat_constant_count); ++i) + sm1->p.shader_desc.flat_constant_count[i].external = get_external_constant_count(sm1, i); + return sm1->p.failed ? VKD3D_ERROR_INVALID_SHADER : VKD3D_OK; } @@ -1959,7 +2034,12 @@ static void write_sm1_sampler_dcls(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b if (var->objects_usage[HLSL_REGSET_SAMPLERS][i].used) { sampler_dim = var->objects_usage[HLSL_REGSET_SAMPLERS][i].sampler_dim; - assert(sampler_dim != HLSL_SAMPLER_DIM_GENERIC); + if (sampler_dim == HLSL_SAMPLER_DIM_GENERIC) + { + /* These can appear in sm4-style combined sample instructions. */ + hlsl_fixme(ctx, &var->loc, "Generic samplers need to be lowered."); + continue; + } reg_id = var->regs[HLSL_REGSET_SAMPLERS].id + i; write_sm1_sampler_dcl(ctx, buffer, reg_id, sampler_dim); @@ -2362,7 +2442,6 @@ static void write_sm1_instructions(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b int hlsl_sm1_write(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, struct vkd3d_shader_code *out) { struct vkd3d_bytecode_buffer buffer = {0}; - int ret; put_u32(&buffer, sm1_version(ctx->profile->type, ctx->profile->major_version, ctx->profile->minor_version)); @@ -2375,10 +2454,17 @@ int hlsl_sm1_write(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun put_u32(&buffer, D3DSIO_END); - if (!(ret = buffer.status)) + if (buffer.status) + ctx->result = buffer.status; + + if (!ctx->result) { out->code = buffer.data; out->size = buffer.size; } - return ret; + else + { + vkd3d_free(buffer.data); + } + return ctx->result; } diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c index 53a4c2da4ba..f9efe47f95d 100644 --- a/libs/vkd3d/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c @@ -208,6 +208,7 @@ struct sm6_value { const struct sm6_type *type; enum sm6_value_type value_type; + bool is_undefined; union { struct sm6_function_data function; @@ -1726,8 +1727,16 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const WARN("Unhandled constant array.\n"); break; + case CST_CODE_UNDEF: + dxil_record_validate_operand_max_count(record, 0, sm6); + dst->u.reg.type = VKD3DSPR_UNDEF; + /* Mark as explicitly undefined, not the result of a missing constant code or instruction. */ + dst->is_undefined = true; + break; + default: FIXME("Unhandled constant code %u.\n", record->code); + dst->u.reg.type = VKD3DSPR_UNDEF; break; } @@ -1737,6 +1746,27 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const return VKD3D_OK; } +static struct vkd3d_shader_instruction *sm6_parser_require_space(struct sm6_parser *sm6, size_t extra) +{ + if (!shader_instruction_array_reserve(&sm6->p.instructions, sm6->p.instructions.count + extra)) + { + ERR("Failed to allocate instruction.\n"); + return NULL; + } + return &sm6->p.instructions.elements[sm6->p.instructions.count]; +} + +/* Space should be reserved before calling this. It is intended to require no checking of the returned pointer. */ +static struct vkd3d_shader_instruction *sm6_parser_add_instruction(struct sm6_parser *sm6, + enum vkd3d_shader_opcode handler_idx) +{ + struct vkd3d_shader_instruction *ins = sm6_parser_require_space(sm6, 1); + assert(ins); + shader_instruction_init(ins, handler_idx); + ++sm6->p.instructions.count; + return ins; +} + static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6) { const struct dxil_block *block = &sm6->root_block; @@ -1767,7 +1797,8 @@ static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6) break; case MODULE_CODE_VERSION: - dxil_record_validate_operand_count(record, 1, 1, sm6); + if (!dxil_record_validate_operand_count(record, 1, 1, sm6)) + return VKD3D_ERROR_INVALID_SHADER; if ((version = record->operands[0]) != 1) { FIXME("Unsupported format version %#"PRIx64".\n", version); @@ -1931,6 +1962,21 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const return VKD3D_OK; } +static bool sm6_block_emit_instructions(struct sm6_block *block, struct sm6_parser *sm6) +{ + struct vkd3d_shader_instruction *ins = sm6_parser_require_space(sm6, block->instruction_count + 1); + + if (!ins) + return false; + + memcpy(ins, block->instructions, block->instruction_count * sizeof(*block->instructions)); + sm6->p.instructions.count += block->instruction_count; + + sm6_parser_add_instruction(sm6, VKD3DSIH_RET); + + return true; +} + static enum vkd3d_result sm6_parser_module_init(struct sm6_parser *sm6, const struct dxil_block *block, unsigned int level) { @@ -2065,6 +2111,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t struct vkd3d_shader_version version; struct dxil_block *block; enum vkd3d_result ret; + unsigned int i; count = byte_code_size / sizeof(*byte_code); if (count < 6) @@ -2254,6 +2301,16 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t return ret; } + for (i = 0; i < sm6->function_count; ++i) + { + if (!sm6_block_emit_instructions(sm6->functions[i].blocks[0], sm6)) + { + vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, + "Out of memory emitting shader instructions."); + return VKD3D_ERROR_OUT_OF_MEMORY; + } + } + dxil_block_destroy(&sm6->root_block); return VKD3D_OK; diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c index ab508502623..4ed7712b0aa 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c @@ -2544,6 +2544,8 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru [HLSL_RESOURCE_GATHER_GREEN] = "gather_green", [HLSL_RESOURCE_GATHER_BLUE] = "gather_blue", [HLSL_RESOURCE_GATHER_ALPHA] = "gather_alpha", + [HLSL_RESOURCE_SAMPLE_INFO] = "sample_info", + [HLSL_RESOURCE_RESINFO] = "resinfo", }; assert(load->load_type < ARRAY_SIZE(type_names)); @@ -2551,8 +2553,11 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru dump_deref(buffer, &load->resource); vkd3d_string_buffer_printf(buffer, ", sampler = "); dump_deref(buffer, &load->sampler); - vkd3d_string_buffer_printf(buffer, ", coords = "); - dump_src(buffer, &load->coords); + if (load->coords.node) + { + vkd3d_string_buffer_printf(buffer, ", coords = "); + dump_src(buffer, &load->coords); + } if (load->sample_index.node) { vkd3d_string_buffer_printf(buffer, ", sample index = "); @@ -3296,9 +3301,11 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) } } -static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const char *source_name, +static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info *compile_info, const struct hlsl_profile_info *profile, struct vkd3d_shader_message_context *message_context) { + unsigned int i; + memset(ctx, 0, sizeof(*ctx)); ctx->profile = profile; @@ -3307,7 +3314,7 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const char *source_name, if (!(ctx->source_files = hlsl_alloc(ctx, sizeof(*ctx->source_files)))) return false; - if (!(ctx->source_files[0] = hlsl_strdup(ctx, source_name ? source_name : ""))) + if (!(ctx->source_files[0] = hlsl_strdup(ctx, compile_info->source_name ? compile_info->source_name : ""))) { vkd3d_free(ctx->source_files); return false; @@ -3346,6 +3353,19 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const char *source_name, return false; ctx->cur_buffer = ctx->globals_buffer; + for (i = 0; i < compile_info->option_count; ++i) + { + const struct vkd3d_shader_compile_option *option = &compile_info->options[i]; + + if (option->name == VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_ORDER) + { + if (option->value == VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_ROW_MAJOR) + ctx->matrix_majority = HLSL_MODIFIER_ROW_MAJOR; + else if (option->value == VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_COLUMN_MAJOR) + ctx->matrix_majority = HLSL_MODIFIER_COLUMN_MAJOR; + } + } + return true; } @@ -3380,6 +3400,8 @@ static void hlsl_ctx_cleanup(struct hlsl_ctx *ctx) vkd3d_free((void *)buffer->name); vkd3d_free(buffer); } + + vkd3d_free(ctx->constant_defs.regs); } int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d_shader_compile_info *compile_info, @@ -3421,7 +3443,7 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d return VKD3D_ERROR_INVALID_ARGUMENT; } - if (!hlsl_ctx_init(&ctx, compile_info->source_name, profile, message_context)) + if (!hlsl_ctx_init(&ctx, compile_info, profile, message_context)) return VKD3D_ERROR_OUT_OF_MEMORY; if ((ret = hlsl_lexer_compile(&ctx, hlsl)) == 2) diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h index 1a4b995abbf..b1928312066 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h @@ -634,6 +634,8 @@ enum hlsl_resource_load_type HLSL_RESOURCE_GATHER_GREEN, HLSL_RESOURCE_GATHER_BLUE, HLSL_RESOURCE_GATHER_ALPHA, + HLSL_RESOURCE_SAMPLE_INFO, + HLSL_RESOURCE_RESINFO, }; struct hlsl_ir_resource_load @@ -1074,7 +1076,7 @@ struct vkd3d_string_buffer *hlsl_component_to_string(struct hlsl_ctx *ctx, const struct vkd3d_string_buffer *hlsl_modifiers_to_string(struct hlsl_ctx *ctx, unsigned int modifiers); const char *hlsl_node_type_to_string(enum hlsl_ir_node_type type); -struct hlsl_ir_node *hlsl_add_conditional(struct hlsl_ctx *ctx, struct list *instrs, +struct hlsl_ir_node *hlsl_add_conditional(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *condition, struct hlsl_ir_node *if_true, struct hlsl_ir_node *if_false); void hlsl_add_function(struct hlsl_ctx *ctx, char *name, struct hlsl_ir_function_decl *decl); bool hlsl_add_var(struct hlsl_ctx *ctx, struct hlsl_ir_var *decl, bool local_var); diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y index 6bf87f8f916..0695f7864bf 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y @@ -146,14 +146,6 @@ static struct list *block_to_list(struct hlsl_block *block) return &block->instrs; } -static struct hlsl_block *list_to_block(struct list *list) -{ - /* This is a temporary hack to ease the transition from lists to blocks. - * It takes advantage of the fact that an allocated hlsl_block pointer is - * byte-compatible with an allocated list pointer. */ - return CONTAINING_RECORD(list, struct hlsl_block, instrs); -} - static struct hlsl_block *make_empty_block(struct hlsl_ctx *ctx) { struct hlsl_block *block; @@ -172,12 +164,6 @@ static struct list *make_empty_list(struct hlsl_ctx *ctx) return list; } -static void destroy_instr_list(struct list *list) -{ - hlsl_free_instr_list(list); - vkd3d_free(list); -} - static void destroy_block(struct hlsl_block *block) { hlsl_block_cleanup(block); @@ -308,7 +294,7 @@ static bool implicit_compatible_data_types(struct hlsl_ctx *ctx, struct hlsl_typ return hlsl_types_are_componentwise_equal(ctx, src, dst); } -static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct list *instrs, +static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *node, struct hlsl_type *dst_type, const struct vkd3d_shader_location *loc) { struct hlsl_type *src_type = node->data_type; @@ -345,7 +331,7 @@ static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct list *instrs, { struct hlsl_ir_node *component_load; struct hlsl_type *dst_comp_type; - struct hlsl_block block; + struct hlsl_block store_block; unsigned int src_idx; if (broadcast) @@ -365,21 +351,21 @@ static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct list *instrs, dst_comp_type = hlsl_type_get_component_type(ctx, dst_type, dst_idx); - if (!(component_load = hlsl_add_load_component(ctx, instrs, node, src_idx, loc))) + if (!(component_load = hlsl_add_load_component(ctx, block_to_list(block), node, src_idx, loc))) return NULL; if (!(cast = hlsl_new_cast(ctx, component_load, dst_comp_type, loc))) return NULL; - list_add_tail(instrs, &cast->entry); + hlsl_block_add_instr(block, cast); - if (!hlsl_new_store_component(ctx, &block, &var_deref, dst_idx, cast)) + if (!hlsl_new_store_component(ctx, &store_block, &var_deref, dst_idx, cast)) return NULL; - list_move_tail(instrs, &block.instrs); + hlsl_block_add_block(block, &store_block); } if (!(load = hlsl_new_var_load(ctx, var, loc))) return NULL; - list_add_tail(instrs, &load->node.entry); + hlsl_block_add_instr(block, &load->node); return &load->node; } @@ -387,12 +373,12 @@ static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct list *instrs, { if (!(cast = hlsl_new_cast(ctx, node, dst_type, loc))) return NULL; - list_add_tail(instrs, &cast->entry); + hlsl_block_add_instr(block, cast); return cast; } } -static struct hlsl_ir_node *add_implicit_conversion(struct hlsl_ctx *ctx, struct list *instrs, +static struct hlsl_ir_node *add_implicit_conversion(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *node, struct hlsl_type *dst_type, const struct vkd3d_shader_location *loc) { struct hlsl_type *src_type = node->data_type; @@ -418,7 +404,7 @@ static struct hlsl_ir_node *add_implicit_conversion(struct hlsl_ctx *ctx, struct hlsl_warning(ctx, loc, VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION, "Implicit truncation of %s type.", src_type->class == HLSL_CLASS_VECTOR ? "vector" : "matrix"); - return add_cast(ctx, instrs, node, dst_type, loc); + return add_cast(ctx, block, node, dst_type, loc); } static DWORD add_modifiers(struct hlsl_ctx *ctx, DWORD modifiers, DWORD mod, @@ -665,7 +651,7 @@ static bool add_return(struct hlsl_ctx *ctx, struct hlsl_block *block, { struct hlsl_ir_node *store; - if (!(return_value = add_implicit_conversion(ctx, block_to_list(block), return_value, return_type, loc))) + if (!(return_value = add_implicit_conversion(ctx, block, return_value, return_type, loc))) return false; if (!(store = hlsl_new_simple_store(ctx, ctx->cur_function->return_var, return_value))) @@ -736,7 +722,7 @@ static struct hlsl_ir_node *add_binary_arithmetic_expr(struct hlsl_ctx *ctx, str enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, const struct vkd3d_shader_location *loc); -static bool add_array_access(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *array, +static bool add_array_access(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *array, struct hlsl_ir_node *index, const struct vkd3d_shader_location *loc) { const struct hlsl_type *expr_type = array->data_type, *index_type = index->data_type; @@ -759,13 +745,13 @@ static bool add_array_access(struct hlsl_ctx *ctx, struct list *instrs, struct h return false; } - if (!(index = add_implicit_conversion(ctx, instrs, index, + if (!(index = add_implicit_conversion(ctx, block, index, hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, dim_count), &index->loc))) return false; if (!(return_index = hlsl_new_index(ctx, array, index, loc))) return false; - list_add_tail(instrs, &return_index->entry); + hlsl_block_add_instr(block, return_index); return true; } @@ -778,7 +764,7 @@ static bool add_array_access(struct hlsl_ctx *ctx, struct list *instrs, struct h if (!(cast = hlsl_new_cast(ctx, index, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), &index->loc))) return false; - list_add_tail(instrs, &cast->entry); + hlsl_block_add_instr(block, cast); index = cast; if (expr_type->class != HLSL_CLASS_ARRAY && expr_type->class != HLSL_CLASS_VECTOR && expr_type->class != HLSL_CLASS_MATRIX) @@ -792,7 +778,7 @@ static bool add_array_access(struct hlsl_ctx *ctx, struct list *instrs, struct h if (!(return_index = hlsl_new_index(ctx, array, index, loc))) return false; - list_add_tail(instrs, &return_index->entry); + hlsl_block_add_instr(block, return_index); return true; } @@ -1117,17 +1103,17 @@ static struct hlsl_ir_function_decl *get_func_decl(struct rb_tree *funcs, return NULL; } -static struct list *make_list(struct hlsl_ctx *ctx, struct hlsl_ir_node *node) +static struct hlsl_block *make_block(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr) { - struct list *list; + struct hlsl_block *block; - if (!(list = make_empty_list(ctx))) + if (!(block = make_empty_block(ctx))) { - hlsl_free_instr(node); + hlsl_free_instr(instr); return NULL; } - list_add_tail(list, &node->entry); - return list; + hlsl_block_add_instr(block, instr); + return block; } static unsigned int evaluate_static_expression_as_uint(struct hlsl_ctx *ctx, struct hlsl_block *block, @@ -1165,7 +1151,7 @@ static unsigned int evaluate_static_expression_as_uint(struct hlsl_ctx *ctx, str return 0; hlsl_block_add_block(&expr, block); - if (!add_implicit_conversion(ctx, &expr.instrs, node_from_block(&expr), + if (!add_implicit_conversion(ctx, &expr, node_from_block(&expr), hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc)) { hlsl_block_cleanup(&expr); @@ -1323,7 +1309,7 @@ static bool expr_common_shape(struct hlsl_ctx *ctx, struct hlsl_type *t1, struct return true; } -static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs, +static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct hlsl_block *block, enum hlsl_ir_expr_op op, struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], struct hlsl_type *type, const struct vkd3d_shader_location *loc) { @@ -1347,38 +1333,38 @@ static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs, for (i = 0; i < type->dimy * type->dimx; ++i) { struct hlsl_ir_node *value, *cell_operands[HLSL_MAX_OPERANDS] = { NULL }; - struct hlsl_block block; + struct hlsl_block store_block; unsigned int j; for (j = 0; j < HLSL_MAX_OPERANDS; j++) { if (operands[j]) { - if (!(load = hlsl_add_load_component(ctx, instrs, operands[j], i, loc))) + if (!(load = hlsl_add_load_component(ctx, block_to_list(block), operands[j], i, loc))) return NULL; cell_operands[j] = load; } } - if (!(value = add_expr(ctx, instrs, op, cell_operands, scalar_type, loc))) + if (!(value = add_expr(ctx, block, op, cell_operands, scalar_type, loc))) return NULL; - if (!hlsl_new_store_component(ctx, &block, &var_deref, i, value)) + if (!hlsl_new_store_component(ctx, &store_block, &var_deref, i, value)) return NULL; - list_move_tail(instrs, &block.instrs); + hlsl_block_add_block(block, &store_block); } if (!(var_load = hlsl_new_var_load(ctx, var, loc))) return NULL; - list_add_tail(instrs, &var_load->node.entry); + hlsl_block_add_instr(block, &var_load->node); return &var_load->node; } if (!(expr = hlsl_new_expr(ctx, op, operands, type, loc))) return NULL; - list_add_tail(instrs, &expr->entry); + hlsl_block_add_instr(block, expr); return expr; } @@ -1409,7 +1395,7 @@ static struct hlsl_ir_node *add_unary_arithmetic_expr(struct hlsl_ctx *ctx, stru { struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {arg}; - return add_expr(ctx, block_to_list(block), op, args, arg->data_type, loc); + return add_expr(ctx, block, op, args, arg->data_type, loc); } static struct hlsl_ir_node *add_unary_bitwise_expr(struct hlsl_ctx *ctx, struct hlsl_block *block, @@ -1429,10 +1415,10 @@ static struct hlsl_ir_node *add_unary_logical_expr(struct hlsl_ctx *ctx, struct bool_type = hlsl_get_numeric_type(ctx, arg->data_type->class, HLSL_TYPE_BOOL, arg->data_type->dimx, arg->data_type->dimy); - if (!(args[0] = add_implicit_conversion(ctx, block_to_list(block), arg, bool_type, loc))) + if (!(args[0] = add_implicit_conversion(ctx, block, arg, bool_type, loc))) return NULL; - return add_expr(ctx, block_to_list(block), op, args, bool_type, loc); + return add_expr(ctx, block, op, args, bool_type, loc); } static struct hlsl_type *get_common_numeric_type(struct hlsl_ctx *ctx, const struct hlsl_ir_node *arg1, @@ -1457,13 +1443,13 @@ static struct hlsl_ir_node *add_binary_arithmetic_expr(struct hlsl_ctx *ctx, str common_type = get_common_numeric_type(ctx, arg1, arg2, loc); - if (!(args[0] = add_implicit_conversion(ctx, block_to_list(block), arg1, common_type, loc))) + if (!(args[0] = add_implicit_conversion(ctx, block, arg1, common_type, loc))) return NULL; - if (!(args[1] = add_implicit_conversion(ctx, block_to_list(block), arg2, common_type, loc))) + if (!(args[1] = add_implicit_conversion(ctx, block, arg2, common_type, loc))) return NULL; - return add_expr(ctx, block_to_list(block), op, args, common_type, loc); + return add_expr(ctx, block, op, args, common_type, loc); } static struct hlsl_ir_node *add_binary_bitwise_expr(struct hlsl_ctx *ctx, struct hlsl_block *block, @@ -1492,13 +1478,13 @@ static struct hlsl_ir_node *add_binary_comparison_expr(struct hlsl_ctx *ctx, str common_type = hlsl_get_numeric_type(ctx, type, base, dimx, dimy); return_type = hlsl_get_numeric_type(ctx, type, HLSL_TYPE_BOOL, dimx, dimy); - if (!(args[0] = add_implicit_conversion(ctx, block_to_list(block), arg1, common_type, loc))) + if (!(args[0] = add_implicit_conversion(ctx, block, arg1, common_type, loc))) return NULL; - if (!(args[1] = add_implicit_conversion(ctx, block_to_list(block), arg2, common_type, loc))) + if (!(args[1] = add_implicit_conversion(ctx, block, arg2, common_type, loc))) return NULL; - return add_expr(ctx, block_to_list(block), op, args, return_type, loc); + return add_expr(ctx, block, op, args, return_type, loc); } static struct hlsl_ir_node *add_binary_logical_expr(struct hlsl_ctx *ctx, struct hlsl_block *block, @@ -1515,13 +1501,13 @@ static struct hlsl_ir_node *add_binary_logical_expr(struct hlsl_ctx *ctx, struct common_type = hlsl_get_numeric_type(ctx, type, HLSL_TYPE_BOOL, dimx, dimy); - if (!(args[0] = add_implicit_conversion(ctx, block_to_list(block), arg1, common_type, loc))) + if (!(args[0] = add_implicit_conversion(ctx, block, arg1, common_type, loc))) return NULL; - if (!(args[1] = add_implicit_conversion(ctx, block_to_list(block), arg2, common_type, loc))) + if (!(args[1] = add_implicit_conversion(ctx, block, arg2, common_type, loc))) return NULL; - return add_expr(ctx, block_to_list(block), op, args, common_type, loc); + return add_expr(ctx, block, op, args, common_type, loc); } static struct hlsl_ir_node *add_binary_shift_expr(struct hlsl_ctx *ctx, struct hlsl_block *block, @@ -1546,13 +1532,13 @@ static struct hlsl_ir_node *add_binary_shift_expr(struct hlsl_ctx *ctx, struct h return_type = hlsl_get_numeric_type(ctx, type, base, dimx, dimy); integer_type = hlsl_get_numeric_type(ctx, type, HLSL_TYPE_INT, dimx, dimy); - if (!(args[0] = add_implicit_conversion(ctx, block_to_list(block), arg1, return_type, loc))) + if (!(args[0] = add_implicit_conversion(ctx, block, arg1, return_type, loc))) return NULL; - if (!(args[1] = add_implicit_conversion(ctx, block_to_list(block), arg2, integer_type, loc))) + if (!(args[1] = add_implicit_conversion(ctx, block, arg2, integer_type, loc))) return NULL; - return add_expr(ctx, block_to_list(block), op, args, return_type, loc); + return add_expr(ctx, block, op, args, return_type, loc); } static struct hlsl_ir_node *add_binary_dot_expr(struct hlsl_ctx *ctx, struct hlsl_block *instrs, @@ -1599,13 +1585,13 @@ static struct hlsl_ir_node *add_binary_dot_expr(struct hlsl_ctx *ctx, struct hls common_type = hlsl_get_vector_type(ctx, base, dim); ret_type = hlsl_get_scalar_type(ctx, base); - if (!(args[0] = add_implicit_conversion(ctx, block_to_list(instrs), arg1, common_type, loc))) + if (!(args[0] = add_implicit_conversion(ctx, instrs, arg1, common_type, loc))) return NULL; - if (!(args[1] = add_implicit_conversion(ctx, block_to_list(instrs), arg2, common_type, loc))) + if (!(args[1] = add_implicit_conversion(ctx, instrs, arg2, common_type, loc))) return NULL; - return add_expr(ctx, block_to_list(instrs), op, args, ret_type, loc); + 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, @@ -1711,7 +1697,7 @@ static bool invert_swizzle(unsigned int *swizzle, unsigned int *writemask, unsig return true; } -static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *lhs, +static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *lhs, enum parse_assign_op assign_op, struct hlsl_ir_node *rhs) { struct hlsl_type *lhs_type = lhs->data_type; @@ -1720,7 +1706,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in if (assign_op == ASSIGN_OP_SUB) { - if (!(rhs = add_unary_arithmetic_expr(ctx, list_to_block(instrs), HLSL_OP1_NEG, rhs, &rhs->loc))) + if (!(rhs = add_unary_arithmetic_expr(ctx, block, HLSL_OP1_NEG, rhs, &rhs->loc))) return NULL; assign_op = ASSIGN_OP_ADD; } @@ -1729,14 +1715,14 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in enum hlsl_ir_expr_op op = op_from_assignment(assign_op); assert(op); - if (!(rhs = add_binary_arithmetic_expr(ctx, list_to_block(instrs), op, lhs, rhs, &rhs->loc))) + if (!(rhs = add_binary_arithmetic_expr(ctx, block, op, lhs, rhs, &rhs->loc))) return NULL; } if (lhs_type->class <= HLSL_CLASS_LAST_NUMERIC) writemask = (1 << lhs_type->dimx) - 1; - if (!(rhs = add_implicit_conversion(ctx, instrs, rhs, lhs_type, &rhs->loc))) + if (!(rhs = add_implicit_conversion(ctx, block, rhs, lhs_type, &rhs->loc))) return NULL; while (lhs->type != HLSL_IR_LOAD && lhs->type != HLSL_IR_INDEX) @@ -1765,7 +1751,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in { return NULL; } - list_add_tail(instrs, &new_swizzle->entry); + hlsl_block_add_instr(block, new_swizzle); lhs = swizzle->val.node; rhs = new_swizzle; @@ -1811,7 +1797,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in hlsl_cleanup_deref(&resource_deref); return NULL; } - list_add_tail(instrs, &store->entry); + hlsl_block_add_instr(block, store); hlsl_cleanup_deref(&resource_deref); } else if (lhs->type == HLSL_IR_INDEX && hlsl_index_is_noncontiguous(hlsl_ir_index(lhs))) @@ -1830,13 +1816,13 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in if (!(c = hlsl_new_uint_constant(ctx, i, &lhs->loc))) return NULL; - list_add_tail(instrs, &c->entry); + hlsl_block_add_instr(block, c); if (!(cell = hlsl_new_index(ctx, &row->node, c, &lhs->loc))) return NULL; - list_add_tail(instrs, &cell->entry); + hlsl_block_add_instr(block, cell); - if (!(load = hlsl_add_load_component(ctx, instrs, rhs, k++, &rhs->loc))) + if (!(load = hlsl_add_load_component(ctx, block_to_list(block), rhs, k++, &rhs->loc))) return NULL; if (!hlsl_init_deref_from_index_chain(ctx, &deref, cell)) @@ -1847,7 +1833,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in hlsl_cleanup_deref(&deref); return NULL; } - list_add_tail(instrs, &store->entry); + hlsl_block_add_instr(block, store); hlsl_cleanup_deref(&deref); } } @@ -1864,7 +1850,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in hlsl_cleanup_deref(&deref); return NULL; } - list_add_tail(instrs, &store->entry); + hlsl_block_add_instr(block, store); hlsl_cleanup_deref(&deref); } @@ -1873,7 +1859,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in * the last instruction in the list, we do need to copy. */ if (!(copy = hlsl_new_copy(ctx, rhs))) return NULL; - list_add_tail(instrs, ©->entry); + hlsl_block_add_instr(block, copy); return copy; } @@ -1891,7 +1877,7 @@ static bool add_increment(struct hlsl_ctx *ctx, struct hlsl_block *block, bool d return false; hlsl_block_add_instr(block, one); - if (!add_assignment(ctx, block_to_list(block), lhs, decrement ? ASSIGN_OP_SUB : ASSIGN_OP_ADD, one)) + if (!add_assignment(ctx, block, lhs, decrement ? ASSIGN_OP_SUB : ASSIGN_OP_ADD, one)) return false; if (post) @@ -1930,7 +1916,7 @@ static void initialize_var_components(struct hlsl_ctx *ctx, struct hlsl_block *i dst_comp_type = hlsl_type_get_component_type(ctx, dst->data_type, *store_index); - if (!(conv = add_implicit_conversion(ctx, block_to_list(instrs), load, dst_comp_type, &src->loc))) + if (!(conv = add_implicit_conversion(ctx, instrs, load, dst_comp_type, &src->loc))) return; if (!hlsl_new_store_component(ctx, &block, &dst_deref, *store_index, conv)) @@ -2183,14 +2169,14 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v) } } -static struct list *initialize_vars(struct hlsl_ctx *ctx, struct list *var_list) +static struct hlsl_block *initialize_vars(struct hlsl_ctx *ctx, struct list *var_list) { struct parse_variable_def *v, *v_next; - struct list *statements_list; + struct hlsl_block *initializers; struct hlsl_ir_var *var; struct hlsl_type *type; - if (!(statements_list = make_empty_list(ctx))) + if (!(initializers = make_empty_block(ctx))) { LIST_FOR_EACH_ENTRY_SAFE(v, v_next, var_list, struct parse_variable_def, entry) { @@ -2239,13 +2225,13 @@ static struct list *initialize_vars(struct hlsl_ctx *ctx, struct list *var_list) assert(v->initializer.args_count == 1); hlsl_block_add_instr(v->initializer.instrs, &load->node); - add_assignment(ctx, block_to_list(v->initializer.instrs), &load->node, ASSIGN_OP_ASSIGN, v->initializer.args[0]); + add_assignment(ctx, v->initializer.instrs, &load->node, ASSIGN_OP_ASSIGN, v->initializer.args[0]); } if (var->storage_modifiers & HLSL_STORAGE_STATIC) hlsl_block_add_block(&ctx->static_initializers, v->initializer.instrs); else - list_move_tail(statements_list, &v->initializer.instrs->instrs); + hlsl_block_add_block(initializers, v->initializer.instrs); } else if (var->storage_modifiers & HLSL_STORAGE_STATIC) { @@ -2266,7 +2252,7 @@ static struct list *initialize_vars(struct hlsl_ctx *ctx, struct list *var_list) } hlsl_block_add_instr(&ctx->static_initializers, zero); - if (!(cast = add_cast(ctx, &ctx->static_initializers.instrs, zero, var->data_type, &var->loc))) + if (!(cast = add_cast(ctx, &ctx->static_initializers, zero, var->data_type, &var->loc))) { free_parse_variable_def(v); continue; @@ -2283,7 +2269,7 @@ static struct list *initialize_vars(struct hlsl_ctx *ctx, struct list *var_list) } vkd3d_free(var_list); - return statements_list; + return initializers; } struct find_function_call_args @@ -2364,7 +2350,7 @@ static struct hlsl_ir_node *intrinsic_float_convert_arg(struct hlsl_ctx *ctx, return arg; type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_FLOAT, type->dimx, type->dimy); - return add_implicit_conversion(ctx, block_to_list(params->instrs), arg, type, loc); + return add_implicit_conversion(ctx, params->instrs, arg, type, loc); } static bool convert_args(struct hlsl_ctx *ctx, const struct parse_initializer *params, @@ -2376,7 +2362,7 @@ static bool convert_args(struct hlsl_ctx *ctx, const struct parse_initializer *p { struct hlsl_ir_node *new_arg; - if (!(new_arg = add_implicit_conversion(ctx, block_to_list(params->instrs), params->args[i], type, loc))) + if (!(new_arg = add_implicit_conversion(ctx, params->instrs, params->args[i], type, loc))) return false; params->args[i] = new_arg; } @@ -2569,7 +2555,7 @@ static bool intrinsic_asfloat(struct hlsl_ctx *ctx, data_type = convert_numeric_type(ctx, data_type, HLSL_TYPE_FLOAT); operands[0] = params->args[0]; - return add_expr(ctx, block_to_list(params->instrs), HLSL_OP1_REINTERPRET, operands, data_type, loc); + return add_expr(ctx, params->instrs, HLSL_OP1_REINTERPRET, operands, data_type, loc); } static bool intrinsic_asuint(struct hlsl_ctx *ctx, @@ -2605,7 +2591,7 @@ static bool intrinsic_asuint(struct hlsl_ctx *ctx, data_type = convert_numeric_type(ctx, data_type, HLSL_TYPE_UINT); operands[0] = params->args[0]; - return add_expr(ctx, block_to_list(params->instrs), HLSL_OP1_REINTERPRET, operands, data_type, loc); + return add_expr(ctx, params->instrs, HLSL_OP1_REINTERPRET, operands, data_type, loc); } static bool intrinsic_clamp(struct hlsl_ctx *ctx, @@ -2677,10 +2663,10 @@ static bool intrinsic_cross(struct hlsl_ctx *ctx, cast_type = hlsl_get_vector_type(ctx, base, 3); - if (!(arg1_cast = add_implicit_conversion(ctx, block_to_list(params->instrs), arg1, cast_type, loc))) + if (!(arg1_cast = add_implicit_conversion(ctx, params->instrs, arg1, cast_type, loc))) return false; - if (!(arg2_cast = add_implicit_conversion(ctx, block_to_list(params->instrs), arg2, cast_type, loc))) + if (!(arg2_cast = add_implicit_conversion(ctx, params->instrs, arg2, cast_type, loc))) return false; if (!(arg1_swzl1 = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Z, X, Y, Z), 3, arg1_cast, loc))) @@ -2879,7 +2865,7 @@ static bool intrinsic_fmod(struct hlsl_ctx *ctx, const struct parse_initializer if (!(ge = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_GEQUAL, div, zero, loc))) return false; - if (!(select = hlsl_add_conditional(ctx, block_to_list(params->instrs), ge, frac, neg_frac))) + if (!(select = hlsl_add_conditional(ctx, params->instrs, ge, frac, neg_frac))) return false; return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, select, y, loc); @@ -3042,7 +3028,7 @@ static bool intrinsic_lit(struct hlsl_ctx *ctx, if (!(specular_pow = add_pow_expr(ctx, params->instrs, n_h, m, loc))) return false; - if (!(load = hlsl_add_conditional(ctx, block_to_list(params->instrs), specular_or, zero, specular_pow))) + if (!(load = hlsl_add_conditional(ctx, params->instrs, specular_or, zero, specular_pow))) return false; if (!hlsl_new_store_component(ctx, &block, &var_deref, 2, load)) @@ -3163,10 +3149,10 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, ret_type = hlsl_get_scalar_type(ctx, base); } - if (!(cast1 = add_implicit_conversion(ctx, block_to_list(params->instrs), arg1, cast_type1, loc))) + if (!(cast1 = add_implicit_conversion(ctx, params->instrs, arg1, cast_type1, loc))) return false; - if (!(cast2 = add_implicit_conversion(ctx, block_to_list(params->instrs), arg2, cast_type2, loc))) + if (!(cast2 = add_implicit_conversion(ctx, params->instrs, arg2, cast_type2, loc))) return false; if (!(var = hlsl_new_synthetic_var(ctx, "mul", matrix_type, loc))) @@ -3216,7 +3202,7 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, return false; hlsl_block_add_instr(params->instrs, &load->node); - return !!add_implicit_conversion(ctx, block_to_list(params->instrs), &load->node, ret_type, loc); + return !!add_implicit_conversion(ctx, params->instrs, &load->node, ret_type, loc); } static bool intrinsic_normalize(struct hlsl_ctx *ctx, @@ -3328,7 +3314,7 @@ static bool intrinsic_sign(struct hlsl_ctx *ctx, if (!(lt = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_LESS, zero, arg, loc))) return false; - if (!(op1 = add_implicit_conversion(ctx, block_to_list(params->instrs), lt, int_type, loc))) + if (!(op1 = add_implicit_conversion(ctx, params->instrs, lt, int_type, loc))) return false; /* Check if arg < 0, cast bool to int and invert (meaning true is -1) */ @@ -3336,7 +3322,7 @@ static bool intrinsic_sign(struct hlsl_ctx *ctx, if (!(lt = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_LESS, arg, zero, loc))) return false; - if (!(op2 = add_implicit_conversion(ctx, block_to_list(params->instrs), lt, int_type, loc))) + if (!(op2 = add_implicit_conversion(ctx, params->instrs, lt, int_type, loc))) return false; if (!(neg = add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_NEG, op2, loc))) @@ -3441,7 +3427,7 @@ static bool intrinsic_step(struct hlsl_ctx *ctx, type = ge->data_type; type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_FLOAT, type->dimx, type->dimy); - return !!add_implicit_conversion(ctx, block_to_list(params->instrs), ge, type, loc); + return !!add_implicit_conversion(ctx, params->instrs, ge, type, loc); } static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer *params, @@ -3476,7 +3462,7 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * hlsl_release_string_buffer(ctx, string); } - if (!(coords = add_implicit_conversion(ctx, block_to_list(params->instrs), params->args[1], + if (!(coords = add_implicit_conversion(ctx, params->instrs, params->args[1], hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, hlsl_sampler_dim_count(dim)), loc))) coords = params->args[1]; @@ -3684,7 +3670,14 @@ static int intrinsic_function_name_compare(const void *a, const void *b) return strcmp(a, func->name); } -static struct list *add_call(struct hlsl_ctx *ctx, const char *name, +static struct hlsl_ir_node *hlsl_new_void_expr(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0}; + + return hlsl_new_expr(ctx, HLSL_OP0_VOID, operands, ctx->builtin_types.Void, loc); +} + +static struct hlsl_block *add_call(struct hlsl_ctx *ctx, const char *name, struct parse_initializer *args, const struct vkd3d_shader_location *loc) { struct intrinsic_function *intrinsic; @@ -3706,7 +3699,7 @@ static struct list *add_call(struct hlsl_ctx *ctx, const char *name, { struct hlsl_ir_node *cast; - if (!(cast = add_cast(ctx, block_to_list(args->instrs), arg, param->data_type, &arg->loc))) + if (!(cast = add_cast(ctx, args->instrs, arg, param->data_type, &arg->loc))) goto fail; args->args[i] = cast; arg = cast; @@ -3743,7 +3736,7 @@ static struct list *add_call(struct hlsl_ctx *ctx, const char *name, goto fail; hlsl_block_add_instr(args->instrs, &load->node); - if (!add_assignment(ctx, block_to_list(args->instrs), arg, ASSIGN_OP_ASSIGN, &load->node)) + if (!add_assignment(ctx, args->instrs, arg, ASSIGN_OP_ASSIGN, &load->node)) goto fail; } } @@ -3758,10 +3751,9 @@ static struct list *add_call(struct hlsl_ctx *ctx, const char *name, } else { - struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0}; struct hlsl_ir_node *expr; - if (!(expr = hlsl_new_expr(ctx, HLSL_OP0_VOID, operands, ctx->builtin_types.Void, loc))) + if (!(expr = hlsl_new_void_expr(ctx, loc))) goto fail; hlsl_block_add_instr(args->instrs, expr); } @@ -3812,7 +3804,7 @@ static struct list *add_call(struct hlsl_ctx *ctx, const char *name, goto fail; } vkd3d_free(args->args); - return block_to_list(args->instrs); + return args->instrs; fail: free_parse_initializer(args); @@ -3890,7 +3882,7 @@ static bool raise_invalid_method_object_type(struct hlsl_ctx *ctx, const struct return false; } -static bool add_load_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object, +static bool add_load_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) { const struct hlsl_type *object_type = object->data_type; @@ -3918,7 +3910,7 @@ static bool add_load_method_call(struct hlsl_ctx *ctx, struct list *instrs, stru } if (multisampled) { - if (!(load_params.sample_index = add_implicit_conversion(ctx, instrs, params->args[1], + if (!(load_params.sample_index = add_implicit_conversion(ctx, block, params->args[1], hlsl_get_scalar_type(ctx, HLSL_TYPE_INT), loc))) return false; } @@ -3926,7 +3918,7 @@ static bool add_load_method_call(struct hlsl_ctx *ctx, struct list *instrs, stru assert(offset_dim); if (params->args_count > 1 + multisampled) { - if (!(load_params.texel_offset = add_implicit_conversion(ctx, instrs, params->args[1 + multisampled], + if (!(load_params.texel_offset = add_implicit_conversion(ctx, block, params->args[1 + multisampled], hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) return false; } @@ -3936,7 +3928,7 @@ static bool add_load_method_call(struct hlsl_ctx *ctx, struct list *instrs, stru } /* +1 for the mipmap level for non-multisampled textures */ - if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[0], + if (!(load_params.coords = add_implicit_conversion(ctx, block, params->args[0], hlsl_get_vector_type(ctx, HLSL_TYPE_INT, sampler_dim + !multisampled), loc))) return false; @@ -3945,11 +3937,11 @@ static bool add_load_method_call(struct hlsl_ctx *ctx, struct list *instrs, stru if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) return false; - list_add_tail(instrs, &load->entry); + hlsl_block_add_instr(block, load); return true; } -static bool add_sample_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object, +static bool add_sample_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) { const struct hlsl_type *object_type = object->data_type; @@ -3986,13 +3978,13 @@ static bool add_sample_method_call(struct hlsl_ctx *ctx, struct list *instrs, st return false; } - if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[1], + if (!(load_params.coords = add_implicit_conversion(ctx, block, params->args[1], hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) return false; if (offset_dim && params->args_count > 2) { - if (!(load_params.texel_offset = add_implicit_conversion(ctx, instrs, params->args[2], + if (!(load_params.texel_offset = add_implicit_conversion(ctx, block, params->args[2], hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) return false; } @@ -4008,12 +4000,12 @@ static bool add_sample_method_call(struct hlsl_ctx *ctx, struct list *instrs, st if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) return false; - list_add_tail(instrs, &load->entry); + hlsl_block_add_instr(block, load); return true; } -static bool add_sample_cmp_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object, +static bool add_sample_cmp_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) { const struct hlsl_type *object_type = object->data_type; @@ -4056,17 +4048,17 @@ static bool add_sample_cmp_method_call(struct hlsl_ctx *ctx, struct list *instrs return false; } - if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[1], + if (!(load_params.coords = add_implicit_conversion(ctx, block, params->args[1], hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) return false; - if (!(load_params.cmp = add_implicit_conversion(ctx, instrs, params->args[2], + if (!(load_params.cmp = add_implicit_conversion(ctx, block, params->args[2], hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc))) load_params.cmp = params->args[2]; if (offset_dim && params->args_count > 3) { - if (!(load_params.texel_offset = add_implicit_conversion(ctx, instrs, params->args[2], + if (!(load_params.texel_offset = add_implicit_conversion(ctx, block, params->args[2], hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) return false; } @@ -4082,12 +4074,12 @@ static bool add_sample_cmp_method_call(struct hlsl_ctx *ctx, struct list *instrs if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) return false; - list_add_tail(instrs, &load->entry); + hlsl_block_add_instr(block, load); return true; } -static bool add_gather_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object, +static bool add_gather_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) { const struct hlsl_type *object_type = object->data_type; @@ -4154,7 +4146,7 @@ static bool add_gather_method_call(struct hlsl_ctx *ctx, struct list *instrs, st } else if (offset_dim && params->args_count > 2) { - if (!(load_params.texel_offset = add_implicit_conversion(ctx, instrs, params->args[2], + if (!(load_params.texel_offset = add_implicit_conversion(ctx, block, params->args[2], hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) return false; } @@ -4179,7 +4171,7 @@ static bool add_gather_method_call(struct hlsl_ctx *ctx, struct list *instrs, st return false; } - if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[1], + if (!(load_params.coords = add_implicit_conversion(ctx, block, params->args[1], hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) return false; @@ -4189,11 +4181,187 @@ static bool add_gather_method_call(struct hlsl_ctx *ctx, struct list *instrs, st if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) return false; - list_add_tail(instrs, &load->entry); + hlsl_block_add_instr(block, load); + return true; +} + +static bool add_assignment_from_component(struct hlsl_ctx *ctx, struct hlsl_block *instrs, struct hlsl_ir_node *dest, + struct hlsl_ir_node *src, unsigned int component, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *load; + + if (!dest) + return true; + + if (!(load = hlsl_add_load_component(ctx, block_to_list(instrs), src, component, loc))) + return false; + + if (!add_assignment(ctx, instrs, dest, ASSIGN_OP_ASSIGN, load)) + return false; + return true; } -static bool add_sample_lod_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object, +static bool add_getdimensions_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) +{ + const struct hlsl_type *object_type = object->data_type; + bool uint_resinfo, has_uint_arg, has_float_arg; + struct hlsl_resource_load_params load_params; + struct hlsl_ir_node *sample_info, *res_info; + struct hlsl_ir_node *zero = NULL, *void_ret; + struct hlsl_type *uint_type, *float_type; + unsigned int i, j; + enum func_argument + { + ARG_MIP_LEVEL, + ARG_WIDTH, + ARG_HEIGHT, + ARG_ELEMENT_COUNT, + ARG_LEVEL_COUNT, + ARG_SAMPLE_COUNT, + ARG_MAX_ARGS, + }; + struct hlsl_ir_node *args[ARG_MAX_ARGS] = { 0 }; + static const struct overload + { + enum hlsl_sampler_dim sampler_dim; + unsigned int args_count; + enum func_argument args[ARG_MAX_ARGS]; + } + overloads[] = + { + { HLSL_SAMPLER_DIM_1D, 1, { ARG_WIDTH } }, + { HLSL_SAMPLER_DIM_1D, 3, { ARG_MIP_LEVEL, ARG_WIDTH, ARG_LEVEL_COUNT } }, + { HLSL_SAMPLER_DIM_1DARRAY, 2, { ARG_WIDTH, ARG_ELEMENT_COUNT } }, + { HLSL_SAMPLER_DIM_1DARRAY, 4, { ARG_MIP_LEVEL, ARG_WIDTH, ARG_ELEMENT_COUNT, ARG_LEVEL_COUNT } }, + { HLSL_SAMPLER_DIM_2D, 2, { ARG_WIDTH, ARG_HEIGHT } }, + { HLSL_SAMPLER_DIM_2D, 4, { ARG_MIP_LEVEL, ARG_WIDTH, ARG_HEIGHT, ARG_LEVEL_COUNT } }, + { HLSL_SAMPLER_DIM_2DARRAY, 3, { ARG_WIDTH, ARG_HEIGHT, ARG_ELEMENT_COUNT } }, + { HLSL_SAMPLER_DIM_2DARRAY, 5, { ARG_MIP_LEVEL, ARG_WIDTH, ARG_HEIGHT, ARG_ELEMENT_COUNT, ARG_LEVEL_COUNT } }, + { HLSL_SAMPLER_DIM_3D, 3, { ARG_WIDTH, ARG_HEIGHT, ARG_ELEMENT_COUNT } }, + { HLSL_SAMPLER_DIM_3D, 5, { ARG_MIP_LEVEL, ARG_WIDTH, ARG_HEIGHT, ARG_ELEMENT_COUNT, ARG_LEVEL_COUNT } }, + { HLSL_SAMPLER_DIM_CUBE, 2, { ARG_WIDTH, ARG_HEIGHT } }, + { HLSL_SAMPLER_DIM_CUBE, 4, { ARG_MIP_LEVEL, ARG_WIDTH, ARG_HEIGHT, ARG_LEVEL_COUNT } }, + { HLSL_SAMPLER_DIM_CUBEARRAY, 3, { ARG_WIDTH, ARG_HEIGHT, ARG_ELEMENT_COUNT } }, + { HLSL_SAMPLER_DIM_CUBEARRAY, 5, { ARG_MIP_LEVEL, ARG_WIDTH, ARG_HEIGHT, ARG_ELEMENT_COUNT, ARG_LEVEL_COUNT } }, + { HLSL_SAMPLER_DIM_2DMS, 3, { ARG_WIDTH, ARG_HEIGHT, ARG_SAMPLE_COUNT } }, + { HLSL_SAMPLER_DIM_2DMSARRAY, 4, { ARG_WIDTH, ARG_HEIGHT, ARG_ELEMENT_COUNT, ARG_SAMPLE_COUNT } }, + }; + const struct overload *o = NULL; + + if (object_type->sampler_dim > HLSL_SAMPLER_DIM_LAST_TEXTURE) + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "GetDimensions() is not defined for this type."); + } + + uint_type = hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT); + float_type = hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT); + has_uint_arg = has_float_arg = false; + for (i = 0; i < ARRAY_SIZE(overloads); ++i) + { + const struct overload *iter = &overloads[i]; + + if (iter->sampler_dim == object_type->sampler_dim && iter->args_count == params->args_count) + { + for (j = 0; j < params->args_count; ++j) + { + args[iter->args[j]] = params->args[j]; + + /* Input parameter. */ + if (iter->args[j] == ARG_MIP_LEVEL) + { + if (!(args[ARG_MIP_LEVEL] = add_implicit_conversion(ctx, block, args[ARG_MIP_LEVEL], + hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc))) + { + return false; + } + + continue; + } + + has_float_arg |= hlsl_types_are_equal(params->args[j]->data_type, float_type); + has_uint_arg |= hlsl_types_are_equal(params->args[j]->data_type, uint_type); + + if (params->args[j]->data_type->class != HLSL_CLASS_SCALAR) + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Expected scalar arguments."); + break; + } + } + o = iter; + break; + } + } + uint_resinfo = !has_float_arg && has_uint_arg; + + if (!o) + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_type_to_string(ctx, object_type))) + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, + "Unexpected number of arguments %u for %s.%s().", params->args_count, string->buffer, name); + hlsl_release_string_buffer(ctx, string); + } + } + + if (!args[ARG_MIP_LEVEL]) + { + if (!(zero = hlsl_new_uint_constant(ctx, 0, loc))) + return false; + hlsl_block_add_instr(block, zero); + args[ARG_MIP_LEVEL] = zero; + } + + memset(&load_params, 0, sizeof(load_params)); + load_params.type = HLSL_RESOURCE_RESINFO; + load_params.resource = object; + load_params.lod = args[ARG_MIP_LEVEL]; + load_params.format = hlsl_get_vector_type(ctx, uint_resinfo ? HLSL_TYPE_UINT : HLSL_TYPE_FLOAT, 4); + + if (!(res_info = hlsl_new_resource_load(ctx, &load_params, loc))) + return false; + hlsl_block_add_instr(block, res_info); + + if (!add_assignment_from_component(ctx, block, args[ARG_WIDTH], res_info, 0, loc)) + return false; + + if (!add_assignment_from_component(ctx, block, args[ARG_HEIGHT], res_info, 1, loc)) + return false; + + if (!add_assignment_from_component(ctx, block, args[ARG_ELEMENT_COUNT], res_info, + object_type->sampler_dim == HLSL_SAMPLER_DIM_1DARRAY ? 1 : 2, loc)) + { + return false; + } + + if (!add_assignment_from_component(ctx, block, args[ARG_LEVEL_COUNT], res_info, 3, loc)) + return false; + + if (args[ARG_SAMPLE_COUNT]) + { + memset(&load_params, 0, sizeof(load_params)); + load_params.type = HLSL_RESOURCE_SAMPLE_INFO; + load_params.resource = object; + load_params.format = args[ARG_SAMPLE_COUNT]->data_type; + if (!(sample_info = hlsl_new_resource_load(ctx, &load_params, loc))) + return false; + hlsl_block_add_instr(block, sample_info); + + if (!add_assignment(ctx, block, args[ARG_SAMPLE_COUNT], ASSIGN_OP_ASSIGN, sample_info)) + return false; + } + + if (!(void_ret = hlsl_new_void_expr(ctx, loc))) + return false; + hlsl_block_add_instr(block, void_ret); + + return true; +} + +static bool add_sample_lod_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) { const struct hlsl_type *object_type = object->data_type; @@ -4235,17 +4403,17 @@ static bool add_sample_lod_method_call(struct hlsl_ctx *ctx, struct list *instrs return false; } - if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[1], + if (!(load_params.coords = add_implicit_conversion(ctx, block, params->args[1], hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) load_params.coords = params->args[1]; - if (!(load_params.lod = add_implicit_conversion(ctx, instrs, params->args[2], + if (!(load_params.lod = add_implicit_conversion(ctx, block, params->args[2], hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc))) load_params.lod = params->args[2]; if (offset_dim && params->args_count > 3) { - if (!(load_params.texel_offset = add_implicit_conversion(ctx, instrs, params->args[3], + if (!(load_params.texel_offset = add_implicit_conversion(ctx, block, params->args[3], hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) return false; } @@ -4259,11 +4427,11 @@ static bool add_sample_lod_method_call(struct hlsl_ctx *ctx, struct list *instrs if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) return false; - list_add_tail(instrs, &load->entry); + hlsl_block_add_instr(block, load); return true; } -static bool add_sample_grad_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object, +static bool add_sample_grad_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) { const struct hlsl_type *object_type = object->data_type; @@ -4302,21 +4470,21 @@ static bool add_sample_grad_method_call(struct hlsl_ctx *ctx, struct list *instr return false; } - if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[1], + if (!(load_params.coords = add_implicit_conversion(ctx, block, params->args[1], hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) load_params.coords = params->args[1]; - if (!(load_params.ddx = add_implicit_conversion(ctx, instrs, params->args[2], + if (!(load_params.ddx = add_implicit_conversion(ctx, block, params->args[2], hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) load_params.ddx = params->args[2]; - if (!(load_params.ddy = add_implicit_conversion(ctx, instrs, params->args[3], + if (!(load_params.ddy = add_implicit_conversion(ctx, block, params->args[3], hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) load_params.ddy = params->args[3]; if (offset_dim && params->args_count > 4) { - if (!(load_params.texel_offset = add_implicit_conversion(ctx, instrs, params->args[4], + if (!(load_params.texel_offset = add_implicit_conversion(ctx, block, params->args[4], hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) return false; } @@ -4330,14 +4498,14 @@ static bool add_sample_grad_method_call(struct hlsl_ctx *ctx, struct list *instr if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) return false; - list_add_tail(instrs, &load->entry); + hlsl_block_add_instr(block, load); return true; } static const struct method_function { const char *name; - bool (*handler)(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object, + bool (*handler)(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); } object_methods[] = @@ -4348,6 +4516,8 @@ object_methods[] = { "GatherGreen", add_gather_method_call }, { "GatherRed", add_gather_method_call }, + { "GetDimensions", add_getdimensions_method_call }, + { "Load", add_load_method_call }, { "Sample", add_sample_method_call }, @@ -4365,7 +4535,7 @@ static int object_method_function_name_compare(const void *a, const void *b) return strcmp(a, func->name); } -static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object, +static bool add_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) { const struct hlsl_type *object_type = object->data_type; @@ -4386,7 +4556,7 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl if ((method = bsearch(name, object_methods, ARRAY_SIZE(object_methods), sizeof(*method), object_method_function_name_compare))) { - return method->handler(ctx, instrs, object, name, params, loc); + return method->handler(ctx, block, object, name, params, loc); } else { @@ -4557,10 +4727,6 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type %token C_INTEGER %token PRE_LINE -%type declaration -%type declaration_statement -%type primary_expr -%type struct_declaration_without_vars %type type_specs %type variables_def %type variables_def_typed @@ -4586,6 +4752,8 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type %type bitxor_expr %type compound_statement %type conditional_expr +%type declaration +%type declaration_statement %type equality_expr %type expr %type expr_optional @@ -4597,11 +4765,13 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type %type loop_statement %type mul_expr %type postfix_expr +%type primary_expr %type relational_expr %type shift_expr %type selection_statement %type statement %type statement_list +%type struct_declaration_without_vars %type unary_expr %type boolean @@ -4661,9 +4831,9 @@ hlsl_prog: | hlsl_prog buffer_declaration buffer_body | hlsl_prog declaration_statement { - if (!list_empty($2)) + if (!list_empty(&$2->instrs)) hlsl_fixme(ctx, &@2, "Uniform initializer."); - destroy_instr_list($2); + destroy_block($2); } | hlsl_prog preproc_directive | hlsl_prog ';' @@ -4731,7 +4901,7 @@ struct_declaration_without_vars: hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, "Modifiers are not allowed on struct type declarations."); - if (!($$ = make_empty_list(ctx))) + if (!($$ = make_empty_block(ctx))) YYABORT; } @@ -5515,7 +5685,7 @@ declaration_statement: | struct_declaration_without_vars | typedef { - if (!($$ = make_empty_list(ctx))) + if (!($$ = make_empty_block(ctx))) YYABORT; } @@ -5912,9 +6082,6 @@ statement_list: statement: declaration_statement - { - $$ = list_to_block($1); - } | expr_statement | compound_statement | jump_statement @@ -6006,7 +6173,7 @@ loop_statement: } | attribute_list_optional KW_FOR '(' scope_start declaration expr_statement expr_optional ')' statement { - $$ = create_loop(ctx, LOOP_FOR, &$1, list_to_block($5), $6, $7, $9, &@2); + $$ = create_loop(ctx, LOOP_FOR, &$1, $5, $6, $7, $9, &@2); hlsl_pop_scope(ctx); } @@ -6042,7 +6209,7 @@ primary_expr: if (!(c = hlsl_new_float_constant(ctx, $1, &@1))) YYABORT; - if (!($$ = make_list(ctx, c))) + if (!($$ = make_block(ctx, c))) YYABORT; } | C_INTEGER @@ -6051,7 +6218,7 @@ primary_expr: if (!(c = hlsl_new_int_constant(ctx, $1, &@1))) YYABORT; - if (!($$ = make_list(ctx, c))) + if (!($$ = make_block(ctx, c))) YYABORT; } | boolean @@ -6060,7 +6227,7 @@ primary_expr: if (!(c = hlsl_new_bool_constant(ctx, $1, &@1))) YYABORT; - if (!($$ = make_list(ctx, c))) + if (!($$ = make_block(ctx, c))) { hlsl_free_instr(c); YYABORT; @@ -6078,12 +6245,12 @@ primary_expr: } if (!(load = hlsl_new_var_load(ctx, var, &@1))) YYABORT; - if (!($$ = make_list(ctx, &load->node))) + if (!($$ = make_block(ctx, &load->node))) YYABORT; } | '(' expr ')' { - $$ = block_to_list($2); + $$ = $2; } | var_identifier '(' func_arguments ')' { @@ -6106,7 +6273,7 @@ primary_expr: YYABORT; if (!(load = hlsl_new_var_load(ctx, var, &@1))) YYABORT; - if (!($$ = make_list(ctx, &load->node))) + if (!($$ = make_block(ctx, &load->node))) YYABORT; } else @@ -6118,9 +6285,6 @@ primary_expr: postfix_expr: primary_expr - { - $$ = list_to_block($1); - } | postfix_expr OP_INC { if (!add_increment(ctx, $1, false, true, &@2)) @@ -6185,7 +6349,7 @@ postfix_expr: hlsl_block_add_block($3, $1); destroy_block($1); - if (!add_array_access(ctx, block_to_list($3), array, index, &@2)) + if (!add_array_access(ctx, $3, array, index, &@2)) { destroy_block($3); YYABORT; @@ -6236,7 +6400,7 @@ postfix_expr: hlsl_block_add_block($1, $5.instrs); vkd3d_free($5.instrs); - if (!add_method_call(ctx, block_to_list($1), object, $3, &$5, &@3)) + if (!add_method_call(ctx, $1, object, $3, &$5, &@3)) { destroy_block($1); vkd3d_free($5.args); @@ -6324,7 +6488,7 @@ unary_expr: YYABORT; } - if (!add_cast(ctx, block_to_list($6), node_from_block($6), dst_type, &@3)) + if (!add_cast(ctx, $6, node_from_block($6), dst_type, &@3)) { destroy_block($6); YYABORT; @@ -6455,13 +6619,13 @@ conditional_expr: if (!(common_type = get_common_numeric_type(ctx, first, second, &@3))) YYABORT; - if (!(first = add_implicit_conversion(ctx, block_to_list($1), first, common_type, &@3))) + if (!(first = add_implicit_conversion(ctx, $1, first, common_type, &@3))) YYABORT; - if (!(second = add_implicit_conversion(ctx, block_to_list($1), second, common_type, &@5))) + if (!(second = add_implicit_conversion(ctx, $1, second, common_type, &@5))) YYABORT; - if (!hlsl_add_conditional(ctx, block_to_list($1), cond, first, second)) + if (!hlsl_add_conditional(ctx, $1, cond, first, second)) YYABORT; $$ = $1; } @@ -6480,7 +6644,7 @@ assignment_expr: } hlsl_block_add_block($3, $1); destroy_block($1); - if (!add_assignment(ctx, block_to_list($3), lhs, $2, rhs)) + if (!add_assignment(ctx, $3, lhs, $2, rhs)) YYABORT; $$ = $3; } diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c index 09a3ea4ca08..4f5a5b02a67 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c @@ -574,6 +574,37 @@ bool hlsl_transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx, return progress; } +typedef bool (*PFN_lower_func)(struct hlsl_ctx *, struct hlsl_ir_node *, struct hlsl_block *); + +static bool call_lower_func(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + PFN_lower_func func = context; + struct hlsl_block block; + + hlsl_block_init(&block); + if (func(ctx, instr, &block)) + { + struct hlsl_ir_node *replacement = LIST_ENTRY(list_tail(&block.instrs), struct hlsl_ir_node, entry); + + list_move_before(&instr->entry, &block.instrs); + hlsl_replace_node(instr, replacement); + return true; + } + else + { + hlsl_block_cleanup(&block); + return false; + } +} + +/* Specific form of transform_ir() for passes which convert a single instruction + * to a block of one or more instructions. This helper takes care of setting up + * the block and calling hlsl_replace_node_with_block(). */ +static bool lower_ir(struct hlsl_ctx *ctx, PFN_lower_func func, struct hlsl_block *block) +{ + return hlsl_transform_ir(ctx, call_lower_func, block, func); +} + static bool transform_instr_derefs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { bool res; @@ -2087,9 +2118,11 @@ static bool lower_combined_samples(struct hlsl_ctx *ctx, struct hlsl_ir_node *in case HLSL_RESOURCE_GATHER_GREEN: case HLSL_RESOURCE_GATHER_BLUE: case HLSL_RESOURCE_GATHER_ALPHA: + case HLSL_RESOURCE_RESINFO: case HLSL_RESOURCE_SAMPLE_CMP: case HLSL_RESOURCE_SAMPLE_CMP_LZ: case HLSL_RESOURCE_SAMPLE_GRAD: + case HLSL_RESOURCE_SAMPLE_INFO: return false; case HLSL_RESOURCE_SAMPLE: @@ -2356,7 +2389,7 @@ static bool lower_casts_to_bool(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr return true; } -struct hlsl_ir_node *hlsl_add_conditional(struct hlsl_ctx *ctx, struct list *instrs, +struct hlsl_ir_node *hlsl_add_conditional(struct hlsl_ctx *ctx, struct hlsl_block *instrs, struct hlsl_ir_node *condition, struct hlsl_ir_node *if_true, struct hlsl_ir_node *if_false) { struct hlsl_block then_block, else_block; @@ -2382,18 +2415,18 @@ struct hlsl_ir_node *hlsl_add_conditional(struct hlsl_ctx *ctx, struct list *ins if (!(iff = hlsl_new_if(ctx, condition, &then_block, &else_block, &condition->loc))) return NULL; - list_add_tail(instrs, &iff->entry); + hlsl_block_add_instr(instrs, iff); if (!(load = hlsl_new_var_load(ctx, var, &condition->loc))) return NULL; - list_add_tail(instrs, &load->node.entry); + hlsl_block_add_instr(instrs, &load->node); return &load->node; } -static bool lower_int_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +static bool lower_int_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { - struct hlsl_ir_node *arg1, *arg2, *xor, *and, *abs1, *abs2, *div, *neg, *cast1, *cast2, *cast3, *cond, *high_bit; + struct hlsl_ir_node *arg1, *arg2, *xor, *and, *abs1, *abs2, *div, *neg, *cast1, *cast2, *cast3, *high_bit; struct hlsl_type *type = instr->data_type, *utype; struct hlsl_constant_value high_bit_value; struct hlsl_ir_expr *expr; @@ -2414,56 +2447,52 @@ static bool lower_int_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, if (!(xor = hlsl_new_binary_expr(ctx, HLSL_OP2_BIT_XOR, arg1, arg2))) return false; - list_add_before(&instr->entry, &xor->entry); + hlsl_block_add_instr(block, xor); for (i = 0; i < type->dimx; ++i) high_bit_value.u[i].u = 0x80000000; if (!(high_bit = hlsl_new_constant(ctx, type, &high_bit_value, &instr->loc))) return false; - list_add_before(&instr->entry, &high_bit->entry); + hlsl_block_add_instr(block, high_bit); if (!(and = hlsl_new_binary_expr(ctx, HLSL_OP2_BIT_AND, xor, high_bit))) return false; - list_add_before(&instr->entry, &and->entry); + hlsl_block_add_instr(block, and); if (!(abs1 = hlsl_new_unary_expr(ctx, HLSL_OP1_ABS, arg1, &instr->loc))) return false; - list_add_before(&instr->entry, &abs1->entry); + hlsl_block_add_instr(block, abs1); if (!(cast1 = hlsl_new_cast(ctx, abs1, utype, &instr->loc))) return false; - list_add_before(&instr->entry, &cast1->entry); + hlsl_block_add_instr(block, cast1); if (!(abs2 = hlsl_new_unary_expr(ctx, HLSL_OP1_ABS, arg2, &instr->loc))) return false; - list_add_before(&instr->entry, &abs2->entry); + hlsl_block_add_instr(block, abs2); if (!(cast2 = hlsl_new_cast(ctx, abs2, utype, &instr->loc))) return false; - list_add_before(&instr->entry, &cast2->entry); + hlsl_block_add_instr(block, cast2); if (!(div = hlsl_new_binary_expr(ctx, HLSL_OP2_DIV, cast1, cast2))) return false; - list_add_before(&instr->entry, &div->entry); + hlsl_block_add_instr(block, div); if (!(cast3 = hlsl_new_cast(ctx, div, type, &instr->loc))) return false; - list_add_before(&instr->entry, &cast3->entry); + hlsl_block_add_instr(block, cast3); if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, cast3, &instr->loc))) return false; - list_add_before(&instr->entry, &neg->entry); - - if (!(cond = hlsl_add_conditional(ctx, &instr->entry, and, neg, cast3))) - return false; - hlsl_replace_node(instr, cond); + hlsl_block_add_instr(block, neg); - return true; + return hlsl_add_conditional(ctx, block, and, neg, cast3); } -static bool lower_int_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +static bool lower_int_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { - struct hlsl_ir_node *arg1, *arg2, *and, *abs1, *abs2, *div, *neg, *cast1, *cast2, *cast3, *cond, *high_bit; + struct hlsl_ir_node *arg1, *arg2, *and, *abs1, *abs2, *div, *neg, *cast1, *cast2, *cast3, *high_bit; struct hlsl_type *type = instr->data_type, *utype; struct hlsl_constant_value high_bit_value; struct hlsl_ir_expr *expr; @@ -2486,45 +2515,41 @@ static bool lower_int_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, high_bit_value.u[i].u = 0x80000000; if (!(high_bit = hlsl_new_constant(ctx, type, &high_bit_value, &instr->loc))) return false; - list_add_before(&instr->entry, &high_bit->entry); + hlsl_block_add_instr(block, high_bit); if (!(and = hlsl_new_binary_expr(ctx, HLSL_OP2_BIT_AND, arg1, high_bit))) return false; - list_add_before(&instr->entry, &and->entry); + hlsl_block_add_instr(block, and); if (!(abs1 = hlsl_new_unary_expr(ctx, HLSL_OP1_ABS, arg1, &instr->loc))) return false; - list_add_before(&instr->entry, &abs1->entry); + hlsl_block_add_instr(block, abs1); if (!(cast1 = hlsl_new_cast(ctx, abs1, utype, &instr->loc))) return false; - list_add_before(&instr->entry, &cast1->entry); + hlsl_block_add_instr(block, cast1); if (!(abs2 = hlsl_new_unary_expr(ctx, HLSL_OP1_ABS, arg2, &instr->loc))) return false; - list_add_before(&instr->entry, &abs2->entry); + hlsl_block_add_instr(block, abs2); if (!(cast2 = hlsl_new_cast(ctx, abs2, utype, &instr->loc))) return false; - list_add_before(&instr->entry, &cast2->entry); + hlsl_block_add_instr(block, cast2); if (!(div = hlsl_new_binary_expr(ctx, HLSL_OP2_MOD, cast1, cast2))) return false; - list_add_before(&instr->entry, &div->entry); + hlsl_block_add_instr(block, div); if (!(cast3 = hlsl_new_cast(ctx, div, type, &instr->loc))) return false; - list_add_before(&instr->entry, &cast3->entry); + hlsl_block_add_instr(block, cast3); if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, cast3, &instr->loc))) return false; - list_add_before(&instr->entry, &neg->entry); - - if (!(cond = hlsl_add_conditional(ctx, &instr->entry, and, neg, cast3))) - return false; - hlsl_replace_node(instr, cond); + hlsl_block_add_instr(block, neg); - return true; + return hlsl_add_conditional(ctx, block, and, neg, cast3); } static bool lower_int_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) @@ -2608,9 +2633,9 @@ static bool lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void return false; } -static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { - struct hlsl_ir_node *arg1, *arg2, *mul1, *neg1, *ge, *neg2, *div, *mul2, *frc, *cond, *one; + struct hlsl_ir_node *arg1, *arg2, *mul1, *neg1, *ge, *neg2, *div, *mul2, *frc, *cond, *one, *mul3; struct hlsl_type *type = instr->data_type, *btype; struct hlsl_constant_value one_value; struct hlsl_ir_expr *expr; @@ -2631,47 +2656,45 @@ static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr if (!(mul1 = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, arg2, arg1))) return false; - list_add_before(&instr->entry, &mul1->entry); + hlsl_block_add_instr(block, mul1); if (!(neg1 = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, mul1, &instr->loc))) return false; - list_add_before(&instr->entry, &neg1->entry); + hlsl_block_add_instr(block, neg1); if (!(ge = hlsl_new_binary_expr(ctx, HLSL_OP2_GEQUAL, mul1, neg1))) return false; ge->data_type = btype; - list_add_before(&instr->entry, &ge->entry); + hlsl_block_add_instr(block, ge); if (!(neg2 = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, arg2, &instr->loc))) return false; - list_add_before(&instr->entry, &neg2->entry); + hlsl_block_add_instr(block, neg2); - if (!(cond = hlsl_add_conditional(ctx, &instr->entry, ge, arg2, neg2))) + if (!(cond = hlsl_add_conditional(ctx, block, ge, arg2, neg2))) return false; for (i = 0; i < type->dimx; ++i) one_value.u[i].f = 1.0f; if (!(one = hlsl_new_constant(ctx, type, &one_value, &instr->loc))) return false; - list_add_before(&instr->entry, &one->entry); + hlsl_block_add_instr(block, one); if (!(div = hlsl_new_binary_expr(ctx, HLSL_OP2_DIV, one, cond))) return false; - list_add_before(&instr->entry, &div->entry); + hlsl_block_add_instr(block, div); if (!(mul2 = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, div, arg1))) return false; - list_add_before(&instr->entry, &mul2->entry); + hlsl_block_add_instr(block, mul2); if (!(frc = hlsl_new_unary_expr(ctx, HLSL_OP1_FRACT, mul2, &instr->loc))) return false; - list_add_before(&instr->entry, &frc->entry); + hlsl_block_add_instr(block, frc); - expr->op = HLSL_OP2_MUL; - hlsl_src_remove(&expr->operands[0]); - hlsl_src_remove(&expr->operands[1]); - hlsl_src_from_node(&expr->operands[0], frc); - hlsl_src_from_node(&expr->operands[1], cond); + if (!(mul3 = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, frc, cond))) + return false; + hlsl_block_add_instr(block, mul3); return true; } @@ -2683,8 +2706,8 @@ static bool lower_discard_neg(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_type *arg_type, *cmp_type; struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = { 0 }; struct hlsl_ir_jump *jump; + struct hlsl_block block; unsigned int i, count; - struct list instrs; if (instr->type != HLSL_IR_JUMP) return false; @@ -2692,38 +2715,38 @@ static bool lower_discard_neg(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, if (jump->type != HLSL_IR_JUMP_DISCARD_NEG) return false; - list_init(&instrs); + hlsl_block_init(&block); arg_type = jump->condition.node->data_type; if (!(zero = hlsl_new_constant(ctx, arg_type, &zero_value, &instr->loc))) return false; - list_add_tail(&instrs, &zero->entry); + hlsl_block_add_instr(&block, zero); operands[0] = jump->condition.node; operands[1] = zero; cmp_type = hlsl_get_numeric_type(ctx, arg_type->class, HLSL_TYPE_BOOL, arg_type->dimx, arg_type->dimy); if (!(cmp = hlsl_new_expr(ctx, HLSL_OP2_LESS, operands, cmp_type, &instr->loc))) return false; - list_add_tail(&instrs, &cmp->entry); + hlsl_block_add_instr(&block, cmp); if (!(bool_false = hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_BOOL), &zero_value, &instr->loc))) return false; - list_add_tail(&instrs, &bool_false->entry); + hlsl_block_add_instr(&block, bool_false); or = bool_false; count = hlsl_type_component_count(cmp_type); for (i = 0; i < count; ++i) { - if (!(load = hlsl_add_load_component(ctx, &instrs, cmp, i, &instr->loc))) + if (!(load = hlsl_add_load_component(ctx, &block.instrs, cmp, i, &instr->loc))) return false; if (!(or = hlsl_new_binary_expr(ctx, HLSL_OP2_LOGIC_OR, or, load))) return NULL; - list_add_tail(&instrs, &or->entry); + hlsl_block_add_instr(&block, or); } - list_move_tail(&instr->entry, &instrs); + list_move_tail(&instr->entry, &block.instrs); hlsl_src_remove(&jump->condition); hlsl_src_from_node(&jump->condition, or); jump->type = HLSL_IR_JUMP_DISCARD_NZ; @@ -2953,7 +2976,8 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop load->sampler.offset.node->last_read = last_read; } - load->coords.node->last_read = last_read; + if (load->coords.node) + load->coords.node->last_read = last_read; if (load->texel_offset.node) load->texel_offset.node->last_read = last_read; if (load->lod.node) @@ -4268,10 +4292,10 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry hlsl_transform_ir(ctx, lower_narrowing_casts, body, NULL); hlsl_transform_ir(ctx, lower_casts_to_bool, body, NULL); hlsl_transform_ir(ctx, lower_int_dot, body, NULL); - hlsl_transform_ir(ctx, lower_int_division, body, NULL); - hlsl_transform_ir(ctx, lower_int_modulus, body, NULL); + lower_ir(ctx, lower_int_division, body); + lower_ir(ctx, lower_int_modulus, body); hlsl_transform_ir(ctx, lower_int_abs, body, NULL); - hlsl_transform_ir(ctx, lower_float_modulus, body, NULL); + lower_ir(ctx, lower_float_modulus, body); hlsl_transform_ir(ctx, fold_redundant_casts, body, NULL); do { diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c index 9eefb82c226..d74f81afc39 100644 --- a/libs/vkd3d/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d/libs/vkd3d-shader/ir.c @@ -247,13 +247,13 @@ static void shader_register_init(struct vkd3d_shader_register *reg, enum vkd3d_s reg->immconst_type = VKD3D_IMMCONST_SCALAR; } -static void shader_instruction_init(struct vkd3d_shader_instruction *ins, enum vkd3d_shader_opcode handler_idx) +void shader_instruction_init(struct vkd3d_shader_instruction *ins, enum vkd3d_shader_opcode handler_idx) { memset(ins, 0, sizeof(*ins)); ins->handler_idx = handler_idx; } -enum vkd3d_result instruction_array_flatten_hull_shader_phases(struct vkd3d_shader_instruction_array *src_instructions) +static enum vkd3d_result instruction_array_flatten_hull_shader_phases(struct vkd3d_shader_instruction_array *src_instructions) { struct hull_flattener flattener = {*src_instructions}; struct vkd3d_shader_instruction_array *instructions; @@ -388,7 +388,7 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p return VKD3D_OK; } -enum vkd3d_result instruction_array_normalise_hull_shader_control_point_io( +static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_io( struct vkd3d_shader_instruction_array *src_instructions, const struct shader_signature *input_signature) { struct vkd3d_shader_instruction_array *instructions; @@ -999,7 +999,7 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi shader_instruction_init(ins, VKD3DSIH_NOP); } -enum vkd3d_result instruction_array_normalise_io_registers(struct vkd3d_shader_instruction_array *instructions, +static enum vkd3d_result instruction_array_normalise_io_registers(struct vkd3d_shader_instruction_array *instructions, enum vkd3d_shader_type shader_type, struct shader_signature *input_signature, struct shader_signature *output_signature, struct shader_signature *patch_constant_signature) { @@ -1070,3 +1070,154 @@ enum vkd3d_result instruction_array_normalise_io_registers(struct vkd3d_shader_i *instructions = normaliser.instructions; return VKD3D_OK; } + +struct flat_constant_def +{ + enum vkd3d_shader_d3dbc_constant_register set; + uint32_t index; + uint32_t value[4]; +}; + +struct flat_constants_normaliser +{ + struct vkd3d_shader_parser *parser; + struct flat_constant_def *defs; + size_t def_count, defs_capacity; +}; + +static bool get_flat_constant_register_type(const struct vkd3d_shader_register *reg, + enum vkd3d_shader_d3dbc_constant_register *set, uint32_t *index) +{ + static const struct + { + enum vkd3d_shader_register_type type; + enum vkd3d_shader_d3dbc_constant_register set; + uint32_t offset; + } + regs[] = + { + {VKD3DSPR_CONST, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER, 0}, + {VKD3DSPR_CONST2, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER, 2048}, + {VKD3DSPR_CONST3, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER, 4096}, + {VKD3DSPR_CONST4, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER, 6144}, + {VKD3DSPR_CONSTINT, VKD3D_SHADER_D3DBC_INT_CONSTANT_REGISTER, 0}, + {VKD3DSPR_CONSTBOOL, VKD3D_SHADER_D3DBC_BOOL_CONSTANT_REGISTER, 0}, + }; + + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(regs); ++i) + { + if (reg->type == regs[i].type) + { + if (reg->idx[0].rel_addr) + { + FIXME("Unhandled relative address.\n"); + return false; + } + + *set = regs[i].set; + *index = regs[i].offset + reg->idx[0].offset; + return true; + } + } + + return false; +} + +static void shader_register_normalise_flat_constants(struct vkd3d_shader_src_param *param, + const struct flat_constants_normaliser *normaliser) +{ + enum vkd3d_shader_d3dbc_constant_register set; + uint32_t index; + size_t i, j; + + if (!get_flat_constant_register_type(¶m->reg, &set, &index)) + return; + + for (i = 0; i < normaliser->def_count; ++i) + { + if (normaliser->defs[i].set == set && normaliser->defs[i].index == index) + { + param->reg.type = VKD3DSPR_IMMCONST; + param->reg.idx_count = 0; + param->reg.immconst_type = VKD3D_IMMCONST_VEC4; + for (j = 0; j < 4; ++j) + param->reg.u.immconst_uint[j] = normaliser->defs[i].value[j]; + return; + } + } + + param->reg.type = VKD3DSPR_CONSTBUFFER; + param->reg.idx[0].offset = set; /* register ID */ + param->reg.idx[1].offset = set; /* register index */ + param->reg.idx[2].offset = index; /* buffer index */ + param->reg.idx_count = 3; +} + +static enum vkd3d_result instruction_array_normalise_flat_constants(struct vkd3d_shader_parser *parser) +{ + struct flat_constants_normaliser normaliser = {.parser = parser}; + unsigned int i, j; + + for (i = 0; i < parser->instructions.count; ++i) + { + struct vkd3d_shader_instruction *ins = &parser->instructions.elements[i]; + + if (ins->handler_idx == VKD3DSIH_DEF || ins->handler_idx == VKD3DSIH_DEFI || ins->handler_idx == VKD3DSIH_DEFB) + { + struct flat_constant_def *def; + + if (!vkd3d_array_reserve((void **)&normaliser.defs, &normaliser.defs_capacity, + normaliser.def_count + 1, sizeof(*normaliser.defs))) + { + vkd3d_free(normaliser.defs); + return VKD3D_ERROR_OUT_OF_MEMORY; + } + + def = &normaliser.defs[normaliser.def_count++]; + + get_flat_constant_register_type((struct vkd3d_shader_register *)&ins->dst[0].reg, &def->set, &def->index); + for (j = 0; j < 4; ++j) + def->value[j] = ins->src[0].reg.u.immconst_uint[j]; + + vkd3d_shader_instruction_make_nop(ins); + } + else + { + for (j = 0; j < ins->src_count; ++j) + shader_register_normalise_flat_constants((struct vkd3d_shader_src_param *)&ins->src[j], &normaliser); + } + } + + vkd3d_free(normaliser.defs); + return VKD3D_OK; +} + +enum vkd3d_result vkd3d_shader_normalise(struct vkd3d_shader_parser *parser) +{ + struct vkd3d_shader_instruction_array *instructions = &parser->instructions; + enum vkd3d_result result = VKD3D_OK; + + if (parser->shader_desc.is_dxil) + return result; + + if (parser->shader_version.type == VKD3D_SHADER_TYPE_HULL + && (result = instruction_array_flatten_hull_shader_phases(instructions)) >= 0) + { + result = instruction_array_normalise_hull_shader_control_point_io(instructions, + &parser->shader_desc.input_signature); + } + if (result >= 0) + result = instruction_array_normalise_io_registers(instructions, parser->shader_version.type, + &parser->shader_desc.input_signature, &parser->shader_desc.output_signature, + &parser->shader_desc.patch_constant_signature); + + if (result >= 0) + result = instruction_array_normalise_flat_constants(parser); + + if (result >= 0 && TRACE_ON()) + vkd3d_shader_trace(instructions, &parser->shader_version); + + return result; +} diff --git a/libs/vkd3d/libs/vkd3d-shader/preproc.l b/libs/vkd3d/libs/vkd3d-shader/preproc.l index 94079696280..6fb61eff6c3 100644 --- a/libs/vkd3d/libs/vkd3d-shader/preproc.l +++ b/libs/vkd3d/libs/vkd3d-shader/preproc.l @@ -30,6 +30,13 @@ #define YY_DECL static int preproc_lexer_lex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param, yyscan_t yyscanner) +static struct preproc_macro *preproc_get_top_macro(struct preproc_ctx *ctx) +{ + if (!ctx->expansion_count) + return NULL; + return ctx->expansion_stack[ctx->expansion_count - 1].macro; +} + static void update_location(struct preproc_ctx *ctx); #define YY_USER_ACTION update_location(yyget_extra(yyscanner)); @@ -125,7 +132,20 @@ INT_SUFFIX [uUlL]{0,2} const char *p; if (!ctx->last_was_newline) - return T_HASHSTRING; + { + struct preproc_macro *macro; + + /* Stringification is only done for function-like macro bodies. + * Anywhere else, we need to parse it as two separate tokens. + * We could use a state for this, but yyless() is easier and cheap. + */ + + if ((macro = preproc_get_top_macro(ctx)) && macro->arg_count) + return T_HASHSTRING; + + yyless(1); + return T_TEXT; + } for (p = yytext + 1; strchr(" \t", *p); ++p) ; @@ -219,13 +239,6 @@ static bool preproc_is_writing(struct preproc_ctx *ctx) return file->if_stack[file->if_count - 1].current_true; } -static struct preproc_macro *preproc_get_top_macro(struct preproc_ctx *ctx) -{ - if (!ctx->expansion_count) - return NULL; - return ctx->expansion_stack[ctx->expansion_count - 1].macro; -} - /* Concatenation is not done for object-like macros, but is done for both * function-like macro bodies and their arguments. */ static bool should_concat(struct preproc_ctx *ctx) @@ -334,6 +347,43 @@ static bool preproc_push_expansion(struct preproc_ctx *ctx, return true; } +static void preproc_stringify(struct preproc_ctx *ctx, struct vkd3d_string_buffer *buffer, const char *text) +{ + const struct preproc_text *expansion; + const char *p = text + 1; + unsigned int i; + + while (*p == ' ' || *p == '\t') + ++p; + + vkd3d_string_buffer_printf(buffer, "\""); + if ((expansion = find_arg_expansion(ctx, p))) + { + size_t len = expansion->text.content_size; + size_t start = 0; + + while (len && strchr(" \t\r\n", expansion->text.buffer[len - 1])) + --len; + + while (start < len && strchr(" \t\r\n", expansion->text.buffer[start])) + ++start; + + for (i = start; i < len; ++i) + { + char c = expansion->text.buffer[i]; + + if (c == '\\' || c == '"') + vkd3d_string_buffer_printf(buffer, "\\"); + vkd3d_string_buffer_printf(buffer, "%c", c); + } + } + else + { + vkd3d_string_buffer_printf(buffer, "%s", p); + } + vkd3d_string_buffer_printf(buffer, "\""); +} + int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner) { struct preproc_ctx *ctx = yyget_extra(scanner); @@ -441,9 +491,6 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner) switch (func_state->state) { case STATE_NONE: - { - struct preproc_macro *macro; - if (token == T_CONCAT && should_concat(ctx)) { while (ctx->buffer.content_size @@ -452,37 +499,17 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner) break; } - /* Stringification, however, is only done for function-like - * macro bodies. */ - if (token == T_HASHSTRING && (macro = preproc_get_top_macro(ctx)) && macro->arg_count) + if (token == T_HASHSTRING) { - const struct preproc_text *expansion; - const char *p = text + 1; - unsigned int i; + struct vkd3d_string_buffer buffer; if (ctx->current_directive) return return_token(token, lval, text); - while (*p == ' ' || *p == '\t') - ++p; - - vkd3d_string_buffer_printf(&ctx->buffer, "\""); - if ((expansion = find_arg_expansion(ctx, p))) - { - for (i = 0; i < expansion->text.content_size; ++i) - { - char c = expansion->text.buffer[i]; - - if (c == '\\' || c == '"') - vkd3d_string_buffer_printf(&ctx->buffer, "\\"); - vkd3d_string_buffer_printf(&ctx->buffer, "%c", c); - } - } - else - { - vkd3d_string_buffer_printf(&ctx->buffer, "%s", p); - } - vkd3d_string_buffer_printf(&ctx->buffer, "\""); + vkd3d_string_buffer_init(&buffer); + preproc_stringify(ctx, &buffer, text); + vkd3d_string_buffer_printf(&ctx->buffer, "%s", buffer.buffer); + vkd3d_string_buffer_cleanup(&buffer); break; } @@ -586,7 +613,6 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner) else vkd3d_string_buffer_printf(&ctx->buffer, "%s ", text); break; - } case STATE_IDENTIFIER: if (token == '(') @@ -628,6 +654,41 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner) switch (token) { + /* Most text gets left alone (e.g. if it contains macros, + * the macros should be evaluated later). + * Arguments are a special case, and are replaced with + * their values immediately. */ + case T_IDENTIFIER: + case T_IDENTIFIER_PAREN: + { + const struct preproc_text *expansion; + + if ((expansion = find_arg_expansion(ctx, text))) + { + preproc_push_expansion(ctx, expansion, NULL); + continue; + } + + if (current_arg) + preproc_text_add(current_arg, text); + break; + } + + /* Stringification is another special case. Unsurprisingly, + * we need to stringify if this is an argument. More + * surprisingly, we need to stringify even if it's not. */ + case T_HASHSTRING: + { + struct vkd3d_string_buffer buffer; + + vkd3d_string_buffer_init(&buffer); + preproc_stringify(ctx, &buffer, text); + if (current_arg) + preproc_text_add(current_arg, buffer.buffer); + vkd3d_string_buffer_cleanup(&buffer); + break; + } + case T_NEWLINE: if (current_arg) preproc_text_add(current_arg, " "); @@ -686,6 +747,9 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner) if (current_arg) preproc_text_add(current_arg, text); } + + if (current_arg) + preproc_text_add(current_arg, " "); break; } } diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c index 9725a5c7e25..d71f0a698d9 100644 --- a/libs/vkd3d/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c @@ -199,6 +199,21 @@ enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval_indexed(enum vkd3d } } +static inline bool register_is_undef(const struct vkd3d_shader_register *reg) +{ + return reg->type == VKD3DSPR_UNDEF; +} + +static inline bool register_is_constant(const struct vkd3d_shader_register *reg) +{ + return (reg->type == VKD3DSPR_IMMCONST || reg->type == VKD3DSPR_IMMCONST64); +} + +static inline bool register_is_constant_or_undef(const struct vkd3d_shader_register *reg) +{ + return register_is_constant(reg) || register_is_undef(reg); +} + #define VKD3D_SPIRV_VERSION 0x00010000 #define VKD3D_SPIRV_GENERATOR_ID 18 #define VKD3D_SPIRV_GENERATOR_VERSION 8 @@ -1746,6 +1761,38 @@ static uint32_t vkd3d_spirv_get_type_id(struct vkd3d_spirv_builder *builder, } } +static uint32_t vkd3d_spirv_get_type_id_for_data_type(struct vkd3d_spirv_builder *builder, + enum vkd3d_data_type data_type, unsigned int component_count) +{ + uint32_t scalar_id; + + if (component_count == 1) + { + switch (data_type) + { + case VKD3D_DATA_FLOAT: + case VKD3D_DATA_SNORM: + case VKD3D_DATA_UNORM: + return vkd3d_spirv_get_op_type_float(builder, 32); + break; + case VKD3D_DATA_INT: + case VKD3D_DATA_UINT: + return vkd3d_spirv_get_op_type_int(builder, 32, data_type == VKD3D_DATA_INT); + break; + case VKD3D_DATA_DOUBLE: + return vkd3d_spirv_get_op_type_float(builder, 64); + default: + FIXME("Unhandled data type %#x.\n", data_type); + return 0; + } + } + else + { + scalar_id = vkd3d_spirv_get_type_id_for_data_type(builder, data_type, 1); + return vkd3d_spirv_get_op_type_vector(builder, scalar_id, component_count); + } +} + static void vkd3d_spirv_builder_init(struct vkd3d_spirv_builder *builder, const char *entry_point) { vkd3d_spirv_stream_init(&builder->debug_stream); @@ -2429,13 +2476,6 @@ static struct spirv_compiler *spirv_compiler_create(const struct vkd3d_shader_ve compiler->shader_type = shader_version->type; - compiler->input_signature = shader_desc->input_signature; - compiler->output_signature = shader_desc->output_signature; - compiler->patch_constant_signature = shader_desc->patch_constant_signature; - memset(&shader_desc->input_signature, 0, sizeof(shader_desc->input_signature)); - memset(&shader_desc->output_signature, 0, sizeof(shader_desc->output_signature)); - memset(&shader_desc->patch_constant_signature, 0, sizeof(shader_desc->patch_constant_signature)); - if ((shader_interface = vkd3d_find_struct(compile_info->next, INTERFACE_INFO))) { compiler->xfb_info = vkd3d_find_struct(compile_info->next, TRANSFORM_FEEDBACK_INFO); @@ -2536,13 +2576,13 @@ static bool spirv_compiler_check_shader_visibility(const struct spirv_compiler * } static struct vkd3d_push_constant_buffer_binding *spirv_compiler_find_push_constant_buffer( - const struct spirv_compiler *compiler, const struct vkd3d_shader_constant_buffer *cb) + const struct spirv_compiler *compiler, const struct vkd3d_shader_register_range *range) { - unsigned int register_space = cb->range.space; - unsigned int reg_idx = cb->range.first; + unsigned int register_space = range->space; + unsigned int reg_idx = range->first; unsigned int i; - if (cb->range.first != cb->range.last) + if (range->first != range->last) return NULL; for (i = 0; i < compiler->shader_interface.push_constant_buffer_count; ++i) @@ -3211,7 +3251,7 @@ static bool spirv_compiler_get_register_info(const struct spirv_compiler *compil struct vkd3d_symbol reg_symbol, *symbol; struct rb_entry *entry; - assert(reg->type != VKD3DSPR_IMMCONST && reg->type != VKD3DSPR_IMMCONST64); + assert(!register_is_constant_or_undef(reg)); if (reg->type == VKD3DSPR_TEMP) { @@ -3553,6 +3593,19 @@ static uint32_t spirv_compiler_emit_load_constant64(struct spirv_compiler *compi vkd3d_component_type_from_data_type(reg->data_type), component_count, values); } +static uint32_t spirv_compiler_emit_load_undef(struct spirv_compiler *compiler, + const struct vkd3d_shader_register *reg, DWORD write_mask) +{ + unsigned int component_count = vkd3d_write_mask_component_count(write_mask); + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; + uint32_t type_id; + + assert(reg->type == VKD3DSPR_UNDEF); + + type_id = vkd3d_spirv_get_type_id_for_data_type(builder, reg->data_type, component_count); + return vkd3d_spirv_build_op_undef(builder, &builder->global_stream, type_id); +} + static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler, const struct vkd3d_shader_register *reg, DWORD swizzle, DWORD write_mask, const struct vkd3d_shader_register_info *reg_info) @@ -3563,7 +3616,7 @@ static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler, enum vkd3d_shader_component_type component_type; unsigned int skipped_component_mask; - assert(reg->type != VKD3DSPR_IMMCONST && reg->type != VKD3DSPR_IMMCONST64); + assert(!register_is_constant_or_undef(reg)); assert(vkd3d_write_mask_component_count(write_mask) == 1); component_idx = vkd3d_write_mask_get_component_idx(write_mask); @@ -3615,6 +3668,8 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, return spirv_compiler_emit_load_constant(compiler, reg, swizzle, write_mask); else if (reg->type == VKD3DSPR_IMMCONST64) return spirv_compiler_emit_load_constant64(compiler, reg, swizzle, write_mask); + else if (reg->type == VKD3DSPR_UNDEF) + return spirv_compiler_emit_load_undef(compiler, reg, write_mask); component_count = vkd3d_write_mask_component_count(write_mask); component_type = vkd3d_component_type_from_data_type(reg->data_type); @@ -3827,7 +3882,7 @@ static void spirv_compiler_emit_store_reg(struct spirv_compiler *compiler, unsigned int src_write_mask = write_mask; uint32_t type_id; - assert(reg->type != VKD3DSPR_IMMCONST && reg->type != VKD3DSPR_IMMCONST64); + assert(!register_is_constant_or_undef(reg)); if (!spirv_compiler_get_register_info(compiler, reg, ®_info)) return; @@ -5477,28 +5532,24 @@ static uint32_t spirv_compiler_build_descriptor_variable(struct spirv_compiler * return var_id; } -static void spirv_compiler_emit_dcl_constant_buffer(struct spirv_compiler *compiler, - const struct vkd3d_shader_instruction *instruction) +static void spirv_compiler_emit_constant_buffer(struct spirv_compiler *compiler, unsigned int size, + const struct vkd3d_shader_register_range *range, const struct vkd3d_shader_register *reg) { - const struct vkd3d_shader_constant_buffer *cb = &instruction->declaration.cb; struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; uint32_t vec4_id, array_type_id, length_id, struct_id, var_id; const SpvStorageClass storage_class = SpvStorageClassUniform; - const struct vkd3d_shader_register *reg = &cb->src.reg; struct vkd3d_push_constant_buffer_binding *push_cb; struct vkd3d_descriptor_variable_info var_info; struct vkd3d_symbol reg_symbol; - assert(!(instruction->flags & ~VKD3DSI_INDEXED_DYNAMIC)); - - if ((push_cb = spirv_compiler_find_push_constant_buffer(compiler, cb))) + if ((push_cb = spirv_compiler_find_push_constant_buffer(compiler, range))) { /* Push constant buffers are handled in * spirv_compiler_emit_push_constant_buffers(). */ - unsigned int cb_size_in_bytes = cb->size * VKD3D_VEC4_SIZE * sizeof(uint32_t); + unsigned int cb_size_in_bytes = size * VKD3D_VEC4_SIZE * sizeof(uint32_t); push_cb->reg = *reg; - push_cb->size = cb->size; + push_cb->size = size; if (cb_size_in_bytes > push_cb->pc.size) { WARN("Constant buffer size %u exceeds push constant size %u.\n", @@ -5508,17 +5559,17 @@ static void spirv_compiler_emit_dcl_constant_buffer(struct spirv_compiler *compi } vec4_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); - length_id = spirv_compiler_get_constant_uint(compiler, cb->size); + length_id = spirv_compiler_get_constant_uint(compiler, size); array_type_id = vkd3d_spirv_build_op_type_array(builder, vec4_id, length_id); vkd3d_spirv_build_op_decorate1(builder, array_type_id, SpvDecorationArrayStride, 16); struct_id = vkd3d_spirv_build_op_type_struct(builder, &array_type_id, 1); vkd3d_spirv_build_op_decorate(builder, struct_id, SpvDecorationBlock, NULL, 0); vkd3d_spirv_build_op_member_decorate1(builder, struct_id, 0, SpvDecorationOffset, 0); - vkd3d_spirv_build_op_name(builder, struct_id, "cb%u_struct", cb->size); + vkd3d_spirv_build_op_name(builder, struct_id, "cb%u_struct", size); var_id = spirv_compiler_build_descriptor_variable(compiler, storage_class, struct_id, - reg, &cb->range, VKD3D_SHADER_RESOURCE_BUFFER, false, &var_info); + reg, range, VKD3D_SHADER_RESOURCE_BUFFER, false, &var_info); vkd3d_symbol_make_register(®_symbol, reg); vkd3d_symbol_set_register_info(®_symbol, var_id, storage_class, @@ -5528,6 +5579,16 @@ static void spirv_compiler_emit_dcl_constant_buffer(struct spirv_compiler *compi spirv_compiler_put_symbol(compiler, ®_symbol); } +static void spirv_compiler_emit_dcl_constant_buffer(struct spirv_compiler *compiler, + const struct vkd3d_shader_instruction *instruction) +{ + const struct vkd3d_shader_constant_buffer *cb = &instruction->declaration.cb; + + assert(!(instruction->flags & ~VKD3DSI_INDEXED_DYNAMIC)); + + spirv_compiler_emit_constant_buffer(compiler, cb->size, &cb->range, &cb->src.reg); +} + static void spirv_compiler_emit_dcl_immediate_constant_buffer(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { @@ -6641,7 +6702,7 @@ static void spirv_compiler_emit_mov(struct spirv_compiler *compiler, uint32_t components[VKD3D_VEC4_SIZE]; unsigned int i, component_count; - if (src->reg.type == VKD3DSPR_IMMCONST || src->reg.type == VKD3DSPR_IMMCONST64 || dst->modifiers || src->modifiers) + if (register_is_constant_or_undef(&src->reg) || dst->modifiers || src->modifiers) goto general_implementation; spirv_compiler_get_register_info(compiler, &dst->reg, &dst_reg_info); @@ -9436,6 +9497,26 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, return ret; } +static void spirv_compiler_emit_sm1_constant_buffer(struct spirv_compiler *compiler, + const struct vkd3d_shader_desc *desc, enum vkd3d_shader_d3dbc_constant_register set, + enum vkd3d_data_type data_type) +{ + struct vkd3d_shader_register_range range = {.space = 0, .first = set, .last = set}; + uint32_t count = desc->flat_constant_count[set].external; + struct vkd3d_shader_register reg = + { + .type = VKD3DSPR_CONSTBUFFER, + .idx[0].offset = set, /* register ID */ + .idx[1].offset = set, /* register index */ + .idx[2].offset = count, /* size */ + .idx_count = 3, + .data_type = data_type, + }; + + if (count) + spirv_compiler_emit_constant_buffer(compiler, count, &range, ®); +} + static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_parser *parser, struct vkd3d_shader_code *spirv) @@ -9443,6 +9524,7 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, const struct vkd3d_shader_spirv_target_info *info = compiler->spirv_target_info; const struct vkd3d_shader_spirv_domain_shader_target_info *ds_info; struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; + struct vkd3d_shader_desc *shader_desc = &parser->shader_desc; struct vkd3d_shader_instruction_array instructions; enum vkd3d_result result = VKD3D_OK; unsigned int i; @@ -9450,24 +9532,28 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, if (parser->shader_desc.temp_count) spirv_compiler_emit_temps(compiler, parser->shader_desc.temp_count); + spirv_compiler_emit_sm1_constant_buffer(compiler, &parser->shader_desc, + VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER, VKD3D_DATA_FLOAT); + spirv_compiler_emit_sm1_constant_buffer(compiler, &parser->shader_desc, + VKD3D_SHADER_D3DBC_INT_CONSTANT_REGISTER, VKD3D_DATA_INT); + spirv_compiler_emit_sm1_constant_buffer(compiler, &parser->shader_desc, + VKD3D_SHADER_D3DBC_BOOL_CONSTANT_REGISTER, VKD3D_DATA_UINT); + compiler->location.column = 0; compiler->location.line = 1; + if ((result = vkd3d_shader_normalise(parser)) < 0) + return result; + instructions = parser->instructions; memset(&parser->instructions, 0, sizeof(parser->instructions)); - if (compiler->shader_type == VKD3D_SHADER_TYPE_HULL - && (result = instruction_array_flatten_hull_shader_phases(&instructions)) >= 0) - { - result = instruction_array_normalise_hull_shader_control_point_io(&instructions, - &compiler->input_signature); - } - if (result >= 0) - result = instruction_array_normalise_io_registers(&instructions, parser->shader_version.type, - &compiler->input_signature, &compiler->output_signature, &compiler->patch_constant_signature); - - if (result >= 0 && TRACE_ON()) - vkd3d_shader_trace(&instructions, &parser->shader_version); + compiler->input_signature = shader_desc->input_signature; + compiler->output_signature = shader_desc->output_signature; + compiler->patch_constant_signature = shader_desc->patch_constant_signature; + memset(&shader_desc->input_signature, 0, sizeof(shader_desc->input_signature)); + memset(&shader_desc->output_signature, 0, sizeof(shader_desc->output_signature)); + memset(&shader_desc->patch_constant_signature, 0, sizeof(shader_desc->patch_constant_signature)); if (compiler->shader_type != VKD3D_SHADER_TYPE_HULL) spirv_compiler_emit_shader_signature_outputs(compiler); diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c index 801c688a297..351943e2e53 100644 --- a/libs/vkd3d/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c @@ -2627,7 +2627,8 @@ bool hlsl_sm4_usage_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semant return true; } -static void add_section(struct dxbc_writer *dxbc, uint32_t tag, struct vkd3d_bytecode_buffer *buffer) +static void add_section(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc, + uint32_t tag, struct vkd3d_bytecode_buffer *buffer) { /* Native D3DDisassemble() expects at least the sizes of the ISGN and OSGN * sections to be aligned. Without this, the sections themselves will be @@ -2635,6 +2636,9 @@ static void add_section(struct dxbc_writer *dxbc, uint32_t tag, struct vkd3d_byt size_t size = bytecode_align(buffer); dxbc_writer_add_section(dxbc, tag, buffer->data, size); + + if (buffer->status < 0) + ctx->result = buffer->status; } static void write_sm4_signature(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc, bool output) @@ -2742,7 +2746,7 @@ static void write_sm4_signature(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc, set_u32(&buffer, count_position, i); - add_section(dxbc, output ? TAG_OSGN : TAG_ISGN, &buffer); + add_section(ctx, dxbc, output ? TAG_OSGN : TAG_ISGN, &buffer); } static D3D_SHADER_VARIABLE_CLASS sm4_class(const struct hlsl_type *type) @@ -2830,6 +2834,22 @@ static D3D_SHADER_VARIABLE_TYPE sm4_base_type(const struct hlsl_type *type) return D3D_SVT_VERTEXSHADER; case HLSL_TYPE_VOID: return D3D_SVT_VOID; + case HLSL_TYPE_UAV: + switch (type->sampler_dim) + { + case HLSL_SAMPLER_DIM_1D: + return D3D_SVT_RWTEXTURE1D; + case HLSL_SAMPLER_DIM_2D: + return D3D_SVT_RWTEXTURE2D; + case HLSL_SAMPLER_DIM_3D: + return D3D_SVT_RWTEXTURE3D; + case HLSL_SAMPLER_DIM_1DARRAY: + return D3D_SVT_RWTEXTURE1DARRAY; + case HLSL_SAMPLER_DIM_2DARRAY: + return D3D_SVT_RWTEXTURE2DARRAY; + default: + vkd3d_unreachable(); + } default: vkd3d_unreachable(); } @@ -3341,7 +3361,7 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) creator_offset = put_string(&buffer, vkd3d_shader_get_version(NULL, NULL)); set_u32(&buffer, creator_position, creator_offset); - add_section(dxbc, TAG_RDEF, &buffer); + add_section(ctx, dxbc, TAG_RDEF, &buffer); sm4_free_extern_resources(extern_resources, extern_resources_count); } @@ -4283,6 +4303,53 @@ static void write_sm4_sample(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer write_sm4_instruction(buffer, &instr); } +static void write_sm4_sampleinfo(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, + const struct hlsl_ir_resource_load *load) +{ + const struct hlsl_deref *resource = &load->resource; + const struct hlsl_ir_node *dst = &load->node; + struct sm4_instruction instr; + + assert(dst->data_type->base_type == HLSL_TYPE_UINT || dst->data_type->base_type == HLSL_TYPE_FLOAT); + + memset(&instr, 0, sizeof(instr)); + instr.opcode = VKD3D_SM4_OP_SAMPLE_INFO; + if (dst->data_type->base_type == HLSL_TYPE_UINT) + instr.opcode |= VKD3DSI_SAMPLE_INFO_UINT << VKD3D_SM4_INSTRUCTION_FLAGS_SHIFT; + + sm4_dst_from_node(&instr.dsts[0], dst); + instr.dst_count = 1; + + sm4_src_from_deref(ctx, &instr.srcs[0], resource, instr.dsts[0].writemask); + instr.src_count = 1; + + write_sm4_instruction(buffer, &instr); +} + +static void write_sm4_resinfo(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, + const struct hlsl_ir_resource_load *load) +{ + const struct hlsl_deref *resource = &load->resource; + const struct hlsl_ir_node *dst = &load->node; + struct sm4_instruction instr; + + assert(dst->data_type->base_type == HLSL_TYPE_UINT || dst->data_type->base_type == HLSL_TYPE_FLOAT); + + memset(&instr, 0, sizeof(instr)); + instr.opcode = VKD3D_SM4_OP_RESINFO; + if (dst->data_type->base_type == HLSL_TYPE_UINT) + instr.opcode |= VKD3DSI_RESINFO_UINT << VKD3D_SM4_INSTRUCTION_FLAGS_SHIFT; + + sm4_dst_from_node(&instr.dsts[0], dst); + instr.dst_count = 1; + + sm4_src_from_node(&instr.srcs[0], load->lod.node, VKD3DSP_WRITEMASK_ALL); + sm4_src_from_deref(ctx, &instr.srcs[1], resource, instr.dsts[0].writemask); + instr.src_count = 2; + + write_sm4_instruction(buffer, &instr); +} + static bool type_is_float(const struct hlsl_type *type) { return type->base_type == HLSL_TYPE_FLOAT || type->base_type == HLSL_TYPE_HALF; @@ -5101,6 +5168,14 @@ static void write_sm4_resource_load(struct hlsl_ctx *ctx, write_sm4_gather(ctx, buffer, &load->node, &load->resource, &load->sampler, coords, HLSL_SWIZZLE(W, W, W, W), texel_offset); break; + + case HLSL_RESOURCE_SAMPLE_INFO: + write_sm4_sampleinfo(ctx, buffer, load); + break; + + case HLSL_RESOURCE_RESINFO: + write_sm4_resinfo(ctx, buffer, load); + break; } } @@ -5306,7 +5381,7 @@ static void write_sm4_shdr(struct hlsl_ctx *ctx, set_u32(&buffer, token_count_position, bytecode_get_size(&buffer) / sizeof(uint32_t)); - add_section(dxbc, TAG_SHDR, &buffer); + add_section(ctx, dxbc, TAG_SHDR, &buffer); sm4_free_extern_resources(extern_resources, extern_resources_count); } diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c index 33d8c60e59a..d59cd704ceb 100644 --- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c @@ -1152,6 +1152,15 @@ static int scan_with_parser(const struct vkd3d_shader_compile_info *compile_info } } + for (i = 0; i < ARRAY_SIZE(parser->shader_desc.flat_constant_count); ++i) + { + struct vkd3d_shader_register_range range = {.space = 0, .first = i, .last = i}; + + if (parser->shader_desc.flat_constant_count[i].external) + vkd3d_shader_scan_add_descriptor(&context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, + &range, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT, 0); + } + if (!ret && signature_info) { if (!vkd3d_shader_signature_from_shader_signature(&signature_info->input, &parser->shader_desc.input_signature) diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h index 0e93f3a556a..d35f49a63a2 100644 --- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h @@ -507,6 +507,7 @@ enum vkd3d_shader_register_type VKD3DSPR_DEPTHOUTLE, VKD3DSPR_RASTERIZER, VKD3DSPR_OUTSTENCILREF, + VKD3DSPR_UNDEF, VKD3DSPR_INVALID = ~0u, }; @@ -840,6 +841,11 @@ struct vkd3d_shader_desc struct shader_signature patch_constant_signature; uint32_t temp_count; + + struct + { + uint32_t used, external; + } flat_constant_count[3]; }; struct vkd3d_shader_register_semantic @@ -971,6 +977,8 @@ struct vkd3d_shader_instruction } declaration; }; +void shader_instruction_init(struct vkd3d_shader_instruction *ins, enum vkd3d_shader_opcode handler_idx); + static inline bool vkd3d_shader_instruction_has_texel_offset(const struct vkd3d_shader_instruction *ins) { return ins->texel_offset.u || ins->texel_offset.v || ins->texel_offset.w; @@ -1398,11 +1406,6 @@ void dxbc_writer_add_section(struct dxbc_writer *dxbc, uint32_t tag, const void void dxbc_writer_init(struct dxbc_writer *dxbc); int dxbc_writer_write(struct dxbc_writer *dxbc, struct vkd3d_shader_code *code); -enum vkd3d_result instruction_array_flatten_hull_shader_phases(struct vkd3d_shader_instruction_array *instructions); -enum vkd3d_result instruction_array_normalise_hull_shader_control_point_io( - struct vkd3d_shader_instruction_array *instructions, const struct shader_signature *input_signature); -enum vkd3d_result instruction_array_normalise_io_registers(struct vkd3d_shader_instruction_array *instructions, - enum vkd3d_shader_type shader_type, struct shader_signature *input_signature, - struct shader_signature *output_signature, struct shader_signature *patch_constant_signature); +enum vkd3d_result vkd3d_shader_normalise(struct vkd3d_shader_parser *parser); #endif /* __VKD3D_SHADER_PRIVATE_H */ diff --git a/libs/vkd3d/libs/vkd3d/command.c b/libs/vkd3d/libs/vkd3d/command.c index 53cb5d9582c..8b5f7899cf3 100644 --- a/libs/vkd3d/libs/vkd3d/command.c +++ b/libs/vkd3d/libs/vkd3d/command.c @@ -454,9 +454,9 @@ static const struct d3d12_root_parameter *root_signature_get_root_descriptor( } /* ID3D12Fence */ -static struct d3d12_fence *impl_from_ID3D12Fence(ID3D12Fence *iface) +static struct d3d12_fence *impl_from_ID3D12Fence1(ID3D12Fence1 *iface) { - return CONTAINING_RECORD(iface, struct d3d12_fence, ID3D12Fence_iface); + return CONTAINING_RECORD(iface, struct d3d12_fence, ID3D12Fence1_iface); } static VkResult d3d12_fence_create_vk_fence(struct d3d12_fence *fence, VkFence *vk_fence) @@ -900,18 +900,19 @@ static void d3d12_fence_signal_timeline_semaphore(struct d3d12_fence *fence, uin vkd3d_mutex_unlock(&fence->mutex); } -static HRESULT STDMETHODCALLTYPE d3d12_fence_QueryInterface(ID3D12Fence *iface, +static HRESULT STDMETHODCALLTYPE d3d12_fence_QueryInterface(ID3D12Fence1 *iface, REFIID riid, void **object) { TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); - if (IsEqualGUID(riid, &IID_ID3D12Fence) + if (IsEqualGUID(riid, &IID_ID3D12Fence1) + || IsEqualGUID(riid, &IID_ID3D12Fence) || IsEqualGUID(riid, &IID_ID3D12Pageable) || IsEqualGUID(riid, &IID_ID3D12DeviceChild) || IsEqualGUID(riid, &IID_ID3D12Object) || IsEqualGUID(riid, &IID_IUnknown)) { - ID3D12Fence_AddRef(iface); + ID3D12Fence1_AddRef(iface); *object = iface; return S_OK; } @@ -922,9 +923,9 @@ static HRESULT STDMETHODCALLTYPE d3d12_fence_QueryInterface(ID3D12Fence *iface, return E_NOINTERFACE; } -static ULONG STDMETHODCALLTYPE d3d12_fence_AddRef(ID3D12Fence *iface) +static ULONG STDMETHODCALLTYPE d3d12_fence_AddRef(ID3D12Fence1 *iface) { - struct d3d12_fence *fence = impl_from_ID3D12Fence(iface); + struct d3d12_fence *fence = impl_from_ID3D12Fence1(iface); ULONG refcount = InterlockedIncrement(&fence->refcount); TRACE("%p increasing refcount to %u.\n", fence, refcount); @@ -937,9 +938,9 @@ static void d3d12_fence_incref(struct d3d12_fence *fence) InterlockedIncrement(&fence->internal_refcount); } -static ULONG STDMETHODCALLTYPE d3d12_fence_Release(ID3D12Fence *iface) +static ULONG STDMETHODCALLTYPE d3d12_fence_Release(ID3D12Fence1 *iface) { - struct d3d12_fence *fence = impl_from_ID3D12Fence(iface); + struct d3d12_fence *fence = impl_from_ID3D12Fence1(iface); ULONG refcount = InterlockedDecrement(&fence->refcount); TRACE("%p decreasing refcount to %u.\n", fence, refcount); @@ -972,10 +973,10 @@ static void d3d12_fence_decref(struct d3d12_fence *fence) } } -static HRESULT STDMETHODCALLTYPE d3d12_fence_GetPrivateData(ID3D12Fence *iface, +static HRESULT STDMETHODCALLTYPE d3d12_fence_GetPrivateData(ID3D12Fence1 *iface, REFGUID guid, UINT *data_size, void *data) { - struct d3d12_fence *fence = impl_from_ID3D12Fence(iface); + struct d3d12_fence *fence = impl_from_ID3D12Fence1(iface); TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); @@ -983,10 +984,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_fence_GetPrivateData(ID3D12Fence *iface, return vkd3d_get_private_data(&fence->private_store, guid, data_size, data); } -static HRESULT STDMETHODCALLTYPE d3d12_fence_SetPrivateData(ID3D12Fence *iface, +static HRESULT STDMETHODCALLTYPE d3d12_fence_SetPrivateData(ID3D12Fence1 *iface, REFGUID guid, UINT data_size, const void *data) { - struct d3d12_fence *fence = impl_from_ID3D12Fence(iface); + struct d3d12_fence *fence = impl_from_ID3D12Fence1(iface); TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); @@ -994,37 +995,37 @@ static HRESULT STDMETHODCALLTYPE d3d12_fence_SetPrivateData(ID3D12Fence *iface, return vkd3d_set_private_data(&fence->private_store, guid, data_size, data); } -static HRESULT STDMETHODCALLTYPE d3d12_fence_SetPrivateDataInterface(ID3D12Fence *iface, +static HRESULT STDMETHODCALLTYPE d3d12_fence_SetPrivateDataInterface(ID3D12Fence1 *iface, REFGUID guid, const IUnknown *data) { - struct d3d12_fence *fence = impl_from_ID3D12Fence(iface); + struct d3d12_fence *fence = impl_from_ID3D12Fence1(iface); TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); return vkd3d_set_private_data_interface(&fence->private_store, guid, data); } -static HRESULT STDMETHODCALLTYPE d3d12_fence_SetName(ID3D12Fence *iface, const WCHAR *name) +static HRESULT STDMETHODCALLTYPE d3d12_fence_SetName(ID3D12Fence1 *iface, const WCHAR *name) { - struct d3d12_fence *fence = impl_from_ID3D12Fence(iface); + struct d3d12_fence *fence = impl_from_ID3D12Fence1(iface); TRACE("iface %p, name %s.\n", iface, debugstr_w(name, fence->device->wchar_size)); return name ? S_OK : E_INVALIDARG; } -static HRESULT STDMETHODCALLTYPE d3d12_fence_GetDevice(ID3D12Fence *iface, REFIID iid, void **device) +static HRESULT STDMETHODCALLTYPE d3d12_fence_GetDevice(ID3D12Fence1 *iface, REFIID iid, void **device) { - struct d3d12_fence *fence = impl_from_ID3D12Fence(iface); + struct d3d12_fence *fence = impl_from_ID3D12Fence1(iface); TRACE("iface %p, iid %s, device %p.\n", iface, debugstr_guid(iid), device); return d3d12_device_query_interface(fence->device, iid, device); } -static UINT64 STDMETHODCALLTYPE d3d12_fence_GetCompletedValue(ID3D12Fence *iface) +static UINT64 STDMETHODCALLTYPE d3d12_fence_GetCompletedValue(ID3D12Fence1 *iface) { - struct d3d12_fence *fence = impl_from_ID3D12Fence(iface); + struct d3d12_fence *fence = impl_from_ID3D12Fence1(iface); uint64_t completed_value; TRACE("iface %p.\n", iface); @@ -1035,10 +1036,10 @@ static UINT64 STDMETHODCALLTYPE d3d12_fence_GetCompletedValue(ID3D12Fence *iface return completed_value; } -static HRESULT STDMETHODCALLTYPE d3d12_fence_SetEventOnCompletion(ID3D12Fence *iface, +static HRESULT STDMETHODCALLTYPE d3d12_fence_SetEventOnCompletion(ID3D12Fence1 *iface, UINT64 value, HANDLE event) { - struct d3d12_fence *fence = impl_from_ID3D12Fence(iface); + struct d3d12_fence *fence = impl_from_ID3D12Fence1(iface); unsigned int i; bool latch = false; @@ -1106,9 +1107,9 @@ static HRESULT d3d12_fence_signal_cpu_timeline_semaphore(struct d3d12_fence *fen return d3d12_device_flush_blocked_queues(fence->device); } -static HRESULT STDMETHODCALLTYPE d3d12_fence_Signal(ID3D12Fence *iface, UINT64 value) +static HRESULT STDMETHODCALLTYPE d3d12_fence_Signal(ID3D12Fence1 *iface, UINT64 value) { - struct d3d12_fence *fence = impl_from_ID3D12Fence(iface); + struct d3d12_fence *fence = impl_from_ID3D12Fence1(iface); TRACE("iface %p, value %#"PRIx64".\n", iface, value); @@ -1117,7 +1118,16 @@ static HRESULT STDMETHODCALLTYPE d3d12_fence_Signal(ID3D12Fence *iface, UINT64 v return d3d12_fence_signal(fence, value, VK_NULL_HANDLE, true); } -static const struct ID3D12FenceVtbl d3d12_fence_vtbl = +static D3D12_FENCE_FLAGS STDMETHODCALLTYPE d3d12_fence_GetCreationFlags(ID3D12Fence1 *iface) +{ + struct d3d12_fence *fence = impl_from_ID3D12Fence1(iface); + + TRACE("iface %p.\n", iface); + + return fence->flags; +} + +static const struct ID3D12Fence1Vtbl d3d12_fence_vtbl = { /* IUnknown methods */ d3d12_fence_QueryInterface, @@ -1134,14 +1144,18 @@ static const struct ID3D12FenceVtbl d3d12_fence_vtbl = d3d12_fence_GetCompletedValue, d3d12_fence_SetEventOnCompletion, d3d12_fence_Signal, + /* ID3D12Fence1 methods */ + d3d12_fence_GetCreationFlags, }; static struct d3d12_fence *unsafe_impl_from_ID3D12Fence(ID3D12Fence *iface) { - if (!iface) + ID3D12Fence1 *iface1; + + if (!(iface1 = (ID3D12Fence1 *)iface)) return NULL; - assert(iface->lpVtbl == &d3d12_fence_vtbl); - return impl_from_ID3D12Fence(iface); + assert(iface1->lpVtbl == &d3d12_fence_vtbl); + return impl_from_ID3D12Fence1(iface1); } static HRESULT d3d12_fence_init(struct d3d12_fence *fence, struct d3d12_device *device, @@ -1151,7 +1165,7 @@ static HRESULT d3d12_fence_init(struct d3d12_fence *fence, struct d3d12_device * VkResult vr; HRESULT hr; - fence->ID3D12Fence_iface.lpVtbl = &d3d12_fence_vtbl; + fence->ID3D12Fence1_iface.lpVtbl = &d3d12_fence_vtbl; fence->internal_refcount = 1; fence->refcount = 1; @@ -1162,7 +1176,7 @@ static HRESULT d3d12_fence_init(struct d3d12_fence *fence, struct d3d12_device * vkd3d_cond_init(&fence->null_event_cond); - if (flags) + if ((fence->flags = flags)) FIXME("Ignoring flags %#x.\n", flags); fence->events = NULL; @@ -1316,32 +1330,26 @@ static HRESULT d3d12_command_allocator_allocate_command_buffer(struct d3d12_comm return hr; } - allocator->current_command_list = list; - - return S_OK; -} - -static void d3d12_command_allocator_free_command_buffer(struct d3d12_command_allocator *allocator, - struct d3d12_command_list *list) -{ - struct d3d12_device *device = allocator->device; - const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; - - TRACE("allocator %p, list %p.\n", allocator, list); - - if (allocator->current_command_list == list) - allocator->current_command_list = NULL; - if (!vkd3d_array_reserve((void **)&allocator->command_buffers, &allocator->command_buffers_size, allocator->command_buffer_count + 1, sizeof(*allocator->command_buffers))) { WARN("Failed to add command buffer.\n"); VK_CALL(vkFreeCommandBuffers(device->vk_device, allocator->vk_command_pool, 1, &list->vk_command_buffer)); - return; + return E_OUTOFMEMORY; } - allocator->command_buffers[allocator->command_buffer_count++] = list->vk_command_buffer; + + allocator->current_command_list = list; + + return S_OK; +} + +static void d3d12_command_allocator_remove_command_list(struct d3d12_command_allocator *allocator, + const struct d3d12_command_list *list) +{ + if (allocator->current_command_list == list) + allocator->current_command_list = NULL; } static bool d3d12_command_allocator_add_render_pass(struct d3d12_command_allocator *allocator, VkRenderPass pass) @@ -1911,10 +1919,32 @@ HRESULT d3d12_command_allocator_create(struct d3d12_device *device, return S_OK; } +static void d3d12_command_signature_incref(struct d3d12_command_signature *signature) +{ + vkd3d_atomic_increment(&signature->internal_refcount); +} + +static void d3d12_command_signature_decref(struct d3d12_command_signature *signature) +{ + unsigned int refcount = vkd3d_atomic_decrement(&signature->internal_refcount); + + if (!refcount) + { + struct d3d12_device *device = signature->device; + + vkd3d_private_store_destroy(&signature->private_store); + + vkd3d_free((void *)signature->desc.pArgumentDescs); + vkd3d_free(signature); + + d3d12_device_release(device); + } +} + /* ID3D12CommandList */ -static inline struct d3d12_command_list *impl_from_ID3D12GraphicsCommandList2(ID3D12GraphicsCommandList2 *iface) +static inline struct d3d12_command_list *impl_from_ID3D12GraphicsCommandList3(ID3D12GraphicsCommandList3 *iface) { - return CONTAINING_RECORD(iface, struct d3d12_command_list, ID3D12GraphicsCommandList2_iface); + return CONTAINING_RECORD(iface, struct d3d12_command_list, ID3D12GraphicsCommandList3_iface); } static void d3d12_command_list_invalidate_current_framebuffer(struct d3d12_command_list *list) @@ -2260,12 +2290,13 @@ static void d3d12_command_list_track_resource_usage(struct d3d12_command_list *l } } -static HRESULT STDMETHODCALLTYPE d3d12_command_list_QueryInterface(ID3D12GraphicsCommandList2 *iface, +static HRESULT STDMETHODCALLTYPE d3d12_command_list_QueryInterface(ID3D12GraphicsCommandList3 *iface, REFIID iid, void **object) { TRACE("iface %p, iid %s, object %p.\n", iface, debugstr_guid(iid), object); - if (IsEqualGUID(iid, &IID_ID3D12GraphicsCommandList2) + if (IsEqualGUID(iid, &IID_ID3D12GraphicsCommandList3) + || IsEqualGUID(iid, &IID_ID3D12GraphicsCommandList2) || IsEqualGUID(iid, &IID_ID3D12GraphicsCommandList1) || IsEqualGUID(iid, &IID_ID3D12GraphicsCommandList) || IsEqualGUID(iid, &IID_ID3D12CommandList) @@ -2273,7 +2304,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_list_QueryInterface(ID3D12Graphic || IsEqualGUID(iid, &IID_ID3D12Object) || IsEqualGUID(iid, &IID_IUnknown)) { - ID3D12GraphicsCommandList2_AddRef(iface); + ID3D12GraphicsCommandList3_AddRef(iface); *object = iface; return S_OK; } @@ -2284,9 +2315,9 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_list_QueryInterface(ID3D12Graphic return E_NOINTERFACE; } -static ULONG STDMETHODCALLTYPE d3d12_command_list_AddRef(ID3D12GraphicsCommandList2 *iface) +static ULONG STDMETHODCALLTYPE d3d12_command_list_AddRef(ID3D12GraphicsCommandList3 *iface) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ULONG refcount = InterlockedIncrement(&list->refcount); TRACE("%p increasing refcount to %u.\n", list, refcount); @@ -2299,9 +2330,9 @@ static void vkd3d_pipeline_bindings_cleanup(struct vkd3d_pipeline_bindings *bind vkd3d_free(bindings->vk_uav_counter_views); } -static ULONG STDMETHODCALLTYPE d3d12_command_list_Release(ID3D12GraphicsCommandList2 *iface) +static ULONG STDMETHODCALLTYPE d3d12_command_list_Release(ID3D12GraphicsCommandList3 *iface) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ULONG refcount = InterlockedDecrement(&list->refcount); TRACE("%p decreasing refcount to %u.\n", list, refcount); @@ -2314,7 +2345,7 @@ static ULONG STDMETHODCALLTYPE d3d12_command_list_Release(ID3D12GraphicsCommandL /* When command pool is destroyed, all command buffers are implicitly freed. */ if (list->allocator) - d3d12_command_allocator_free_command_buffer(list->allocator, list); + d3d12_command_allocator_remove_command_list(list->allocator, list); vkd3d_pipeline_bindings_cleanup(&list->pipeline_bindings[VKD3D_PIPELINE_BIND_POINT_COMPUTE]); vkd3d_pipeline_bindings_cleanup(&list->pipeline_bindings[VKD3D_PIPELINE_BIND_POINT_GRAPHICS]); @@ -2327,66 +2358,66 @@ static ULONG STDMETHODCALLTYPE d3d12_command_list_Release(ID3D12GraphicsCommandL return refcount; } -static HRESULT STDMETHODCALLTYPE d3d12_command_list_GetPrivateData(ID3D12GraphicsCommandList2 *iface, +static HRESULT STDMETHODCALLTYPE d3d12_command_list_GetPrivateData(ID3D12GraphicsCommandList3 *iface, REFGUID guid, UINT *data_size, void *data) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); return vkd3d_get_private_data(&list->private_store, guid, data_size, data); } -static HRESULT STDMETHODCALLTYPE d3d12_command_list_SetPrivateData(ID3D12GraphicsCommandList2 *iface, +static HRESULT STDMETHODCALLTYPE d3d12_command_list_SetPrivateData(ID3D12GraphicsCommandList3 *iface, REFGUID guid, UINT data_size, const void *data) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); return vkd3d_set_private_data(&list->private_store, guid, data_size, data); } -static HRESULT STDMETHODCALLTYPE d3d12_command_list_SetPrivateDataInterface(ID3D12GraphicsCommandList2 *iface, +static HRESULT STDMETHODCALLTYPE d3d12_command_list_SetPrivateDataInterface(ID3D12GraphicsCommandList3 *iface, REFGUID guid, const IUnknown *data) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); return vkd3d_set_private_data_interface(&list->private_store, guid, data); } -static HRESULT STDMETHODCALLTYPE d3d12_command_list_SetName(ID3D12GraphicsCommandList2 *iface, const WCHAR *name) +static HRESULT STDMETHODCALLTYPE d3d12_command_list_SetName(ID3D12GraphicsCommandList3 *iface, const WCHAR *name) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); TRACE("iface %p, name %s.\n", iface, debugstr_w(name, list->device->wchar_size)); return name ? S_OK : E_INVALIDARG; } -static HRESULT STDMETHODCALLTYPE d3d12_command_list_GetDevice(ID3D12GraphicsCommandList2 *iface, REFIID iid, void **device) +static HRESULT STDMETHODCALLTYPE d3d12_command_list_GetDevice(ID3D12GraphicsCommandList3 *iface, REFIID iid, void **device) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); TRACE("iface %p, iid %s, device %p.\n", iface, debugstr_guid(iid), device); return d3d12_device_query_interface(list->device, iid, device); } -static D3D12_COMMAND_LIST_TYPE STDMETHODCALLTYPE d3d12_command_list_GetType(ID3D12GraphicsCommandList2 *iface) +static D3D12_COMMAND_LIST_TYPE STDMETHODCALLTYPE d3d12_command_list_GetType(ID3D12GraphicsCommandList3 *iface) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); TRACE("iface %p.\n", iface); return list->type; } -static HRESULT STDMETHODCALLTYPE d3d12_command_list_Close(ID3D12GraphicsCommandList2 *iface) +static HRESULT STDMETHODCALLTYPE d3d12_command_list_Close(ID3D12GraphicsCommandList3 *iface) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); const struct vkd3d_vk_device_procs *vk_procs; VkResult vr; @@ -2412,7 +2443,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_list_Close(ID3D12GraphicsCommandL if (list->allocator) { - d3d12_command_allocator_free_command_buffer(list->allocator, list); + d3d12_command_allocator_remove_command_list(list->allocator, list); list->allocator = NULL; } @@ -2430,7 +2461,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_list_Close(ID3D12GraphicsCommandL static void d3d12_command_list_reset_state(struct d3d12_command_list *list, ID3D12PipelineState *initial_pipeline_state) { - ID3D12GraphicsCommandList2 *iface = &list->ID3D12GraphicsCommandList2_iface; + ID3D12GraphicsCommandList3 *iface = &list->ID3D12GraphicsCommandList3_iface; memset(list->strides, 0, sizeof(list->strides)); list->primitive_topology = D3D_PRIMITIVE_TOPOLOGY_POINTLIST; @@ -2466,14 +2497,14 @@ static void d3d12_command_list_reset_state(struct d3d12_command_list *list, list->descriptor_heap_count = 0; - ID3D12GraphicsCommandList2_SetPipelineState(iface, initial_pipeline_state); + ID3D12GraphicsCommandList3_SetPipelineState(iface, initial_pipeline_state); } -static HRESULT STDMETHODCALLTYPE d3d12_command_list_Reset(ID3D12GraphicsCommandList2 *iface, +static HRESULT STDMETHODCALLTYPE d3d12_command_list_Reset(ID3D12GraphicsCommandList3 *iface, ID3D12CommandAllocator *allocator, ID3D12PipelineState *initial_pipeline_state) { struct d3d12_command_allocator *allocator_impl = unsafe_impl_from_ID3D12CommandAllocator(allocator); - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); HRESULT hr; TRACE("iface %p, allocator %p, initial_pipeline_state %p.\n", @@ -2500,7 +2531,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_list_Reset(ID3D12GraphicsCommandL return hr; } -static void STDMETHODCALLTYPE d3d12_command_list_ClearState(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_ClearState(ID3D12GraphicsCommandList3 *iface, ID3D12PipelineState *pipeline_state) { FIXME("iface %p, pipline_state %p stub!\n", iface, pipeline_state); @@ -3186,6 +3217,20 @@ static void command_list_flush_vk_heap_updates(struct d3d12_command_list *list) } } +static void command_list_add_descriptor_heap(struct d3d12_command_list *list, struct d3d12_descriptor_heap *heap) +{ + if (!contains_heap(list->descriptor_heaps, list->descriptor_heap_count, heap)) + { + if (list->descriptor_heap_count == ARRAY_SIZE(list->descriptor_heaps)) + { + /* Descriptors can be written after binding. */ + FIXME("Flushing descriptor updates while list %p is not closed.\n", list); + command_list_flush_vk_heap_updates(list); + } + list->descriptor_heaps[list->descriptor_heap_count++] = heap; + } +} + static void d3d12_command_list_bind_descriptor_heap(struct d3d12_command_list *list, enum vkd3d_pipeline_bind_point bind_point, struct d3d12_descriptor_heap *heap) { @@ -3210,18 +3255,6 @@ static void d3d12_command_list_bind_descriptor_heap(struct d3d12_command_list *l bindings->sampler_heap_id = heap->serial_id; } - if (!contains_heap(list->descriptor_heaps, list->descriptor_heap_count, heap)) - { - if (list->descriptor_heap_count == ARRAY_SIZE(list->descriptor_heaps)) - { - /* Descriptors can be written after binding. */ - FIXME("Flushing descriptor updates while list %p is not closed.\n", list); - command_list_flush_vk_heap_updates(list); - list->descriptor_heap_count = 0; - } - list->descriptor_heaps[list->descriptor_heap_count++] = heap; - } - vkd3d_mutex_lock(&heap->vk_sets_mutex); for (set = 0; set < ARRAY_SIZE(heap->vk_descriptor_sets); ++set) @@ -3354,11 +3387,11 @@ static void d3d12_command_list_check_index_buffer_strip_cut_value(struct d3d12_c } } -static void STDMETHODCALLTYPE d3d12_command_list_DrawInstanced(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_DrawInstanced(ID3D12GraphicsCommandList3 *iface, UINT vertex_count_per_instance, UINT instance_count, UINT start_vertex_location, UINT start_instance_location) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); const struct vkd3d_vk_device_procs *vk_procs; TRACE("iface %p, vertex_count_per_instance %u, instance_count %u, " @@ -3378,11 +3411,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_DrawInstanced(ID3D12GraphicsCom instance_count, start_vertex_location, start_instance_location)); } -static void STDMETHODCALLTYPE d3d12_command_list_DrawIndexedInstanced(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_DrawIndexedInstanced(ID3D12GraphicsCommandList3 *iface, UINT index_count_per_instance, UINT instance_count, UINT start_vertex_location, INT base_vertex_location, UINT start_instance_location) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); const struct vkd3d_vk_device_procs *vk_procs; TRACE("iface %p, index_count_per_instance %u, instance_count %u, start_vertex_location %u, " @@ -3404,10 +3437,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_DrawIndexedInstanced(ID3D12Grap instance_count, start_vertex_location, base_vertex_location, start_instance_location)); } -static void STDMETHODCALLTYPE d3d12_command_list_Dispatch(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_Dispatch(ID3D12GraphicsCommandList3 *iface, UINT x, UINT y, UINT z) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); const struct vkd3d_vk_device_procs *vk_procs; TRACE("iface %p, x %u, y %u, z %u.\n", iface, x, y, z); @@ -3423,10 +3456,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_Dispatch(ID3D12GraphicsCommandL VK_CALL(vkCmdDispatch(list->vk_command_buffer, x, y, z)); } -static void STDMETHODCALLTYPE d3d12_command_list_CopyBufferRegion(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_CopyBufferRegion(ID3D12GraphicsCommandList3 *iface, ID3D12Resource *dst, UINT64 dst_offset, ID3D12Resource *src, UINT64 src_offset, UINT64 byte_count) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); struct d3d12_resource *dst_resource, *src_resource; const struct vkd3d_vk_device_procs *vk_procs; VkBufferCopy buffer_copy; @@ -3708,11 +3741,11 @@ static bool validate_d3d12_box(const D3D12_BOX *box) && box->back > box->front; } -static void STDMETHODCALLTYPE d3d12_command_list_CopyTextureRegion(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_CopyTextureRegion(ID3D12GraphicsCommandList3 *iface, const D3D12_TEXTURE_COPY_LOCATION *dst, UINT dst_x, UINT dst_y, UINT dst_z, const D3D12_TEXTURE_COPY_LOCATION *src, const D3D12_BOX *src_box) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); struct d3d12_resource *dst_resource, *src_resource; const struct vkd3d_format *src_format, *dst_format; const struct vkd3d_vk_device_procs *vk_procs; @@ -3833,10 +3866,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyTextureRegion(ID3D12Graphic } } -static void STDMETHODCALLTYPE d3d12_command_list_CopyResource(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_CopyResource(ID3D12GraphicsCommandList3 *iface, ID3D12Resource *dst, ID3D12Resource *src) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); struct d3d12_resource *dst_resource, *src_resource; const struct vkd3d_format *dst_format, *src_format; const struct vkd3d_vk_device_procs *vk_procs; @@ -3903,7 +3936,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyResource(ID3D12GraphicsComm } } -static void STDMETHODCALLTYPE d3d12_command_list_CopyTiles(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_CopyTiles(ID3D12GraphicsCommandList3 *iface, ID3D12Resource *tiled_resource, const D3D12_TILED_RESOURCE_COORDINATE *tile_region_start_coordinate, const D3D12_TILE_REGION_SIZE *tile_region_size, ID3D12Resource *buffer, UINT64 buffer_offset, D3D12_TILE_COPY_FLAGS flags) @@ -3914,11 +3947,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyTiles(ID3D12GraphicsCommand buffer, buffer_offset, flags); } -static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresource(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresource(ID3D12GraphicsCommandList3 *iface, ID3D12Resource *dst, UINT dst_sub_resource_idx, ID3D12Resource *src, UINT src_sub_resource_idx, DXGI_FORMAT format) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); const struct vkd3d_format *src_format, *dst_format, *vk_format; struct d3d12_resource *dst_resource, *src_resource; const struct vkd3d_vk_device_procs *vk_procs; @@ -3981,10 +4014,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresource(ID3D12Graphi VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &vk_image_resolve)); } -static void STDMETHODCALLTYPE d3d12_command_list_IASetPrimitiveTopology(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_IASetPrimitiveTopology(ID3D12GraphicsCommandList3 *iface, D3D12_PRIMITIVE_TOPOLOGY topology) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); TRACE("iface %p, topology %#x.\n", iface, topology); @@ -3995,11 +4028,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_IASetPrimitiveTopology(ID3D12Gr d3d12_command_list_invalidate_current_pipeline(list); } -static void STDMETHODCALLTYPE d3d12_command_list_RSSetViewports(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_RSSetViewports(ID3D12GraphicsCommandList3 *iface, UINT viewport_count, const D3D12_VIEWPORT *viewports) { VkViewport vk_viewports[D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); const struct vkd3d_vk_device_procs *vk_procs; unsigned int i; @@ -4033,10 +4066,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_RSSetViewports(ID3D12GraphicsCo VK_CALL(vkCmdSetViewport(list->vk_command_buffer, 0, viewport_count, vk_viewports)); } -static void STDMETHODCALLTYPE d3d12_command_list_RSSetScissorRects(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_RSSetScissorRects(ID3D12GraphicsCommandList3 *iface, UINT rect_count, const D3D12_RECT *rects) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); VkRect2D vk_rects[D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; const struct vkd3d_vk_device_procs *vk_procs; unsigned int i; @@ -4061,10 +4094,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_RSSetScissorRects(ID3D12Graphic VK_CALL(vkCmdSetScissor(list->vk_command_buffer, 0, rect_count, vk_rects)); } -static void STDMETHODCALLTYPE d3d12_command_list_OMSetBlendFactor(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_OMSetBlendFactor(ID3D12GraphicsCommandList3 *iface, const FLOAT blend_factor[4]) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); const struct vkd3d_vk_device_procs *vk_procs; TRACE("iface %p, blend_factor %p.\n", iface, blend_factor); @@ -4073,10 +4106,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetBlendFactor(ID3D12Graphics VK_CALL(vkCmdSetBlendConstants(list->vk_command_buffer, blend_factor)); } -static void STDMETHODCALLTYPE d3d12_command_list_OMSetStencilRef(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_OMSetStencilRef(ID3D12GraphicsCommandList3 *iface, UINT stencil_ref) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); const struct vkd3d_vk_device_procs *vk_procs; TRACE("iface %p, stencil_ref %u.\n", iface, stencil_ref); @@ -4085,11 +4118,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetStencilRef(ID3D12GraphicsC VK_CALL(vkCmdSetStencilReference(list->vk_command_buffer, VK_STENCIL_FRONT_AND_BACK, stencil_ref)); } -static void STDMETHODCALLTYPE d3d12_command_list_SetPipelineState(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_SetPipelineState(ID3D12GraphicsCommandList3 *iface, ID3D12PipelineState *pipeline_state) { struct d3d12_pipeline_state *state = unsafe_impl_from_ID3D12PipelineState(pipeline_state); - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); TRACE("iface %p, pipeline_state %p.\n", iface, pipeline_state); @@ -4140,10 +4173,10 @@ static unsigned int d3d12_find_ds_multiplanar_transition(const D3D12_RESOURCE_BA return 0; } -static void STDMETHODCALLTYPE d3d12_command_list_ResourceBarrier(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_ResourceBarrier(ID3D12GraphicsCommandList3 *iface, UINT barrier_count, const D3D12_RESOURCE_BARRIER *barriers) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); bool have_aliasing_barriers = false, have_split_barriers = false; const struct vkd3d_vk_device_procs *vk_procs; const struct vkd3d_vulkan_info *vk_info; @@ -4366,13 +4399,13 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResourceBarrier(ID3D12GraphicsC WARN("Issuing split barrier(s) on D3D12_RESOURCE_BARRIER_FLAG_END_ONLY.\n"); } -static void STDMETHODCALLTYPE d3d12_command_list_ExecuteBundle(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_ExecuteBundle(ID3D12GraphicsCommandList3 *iface, ID3D12GraphicsCommandList *command_list) { FIXME("iface %p, command_list %p stub!\n", iface, command_list); } -static void STDMETHODCALLTYPE d3d12_command_list_SetDescriptorHeaps(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_SetDescriptorHeaps(ID3D12GraphicsCommandList3 *iface, UINT heap_count, ID3D12DescriptorHeap *const *heaps) { TRACE("iface %p, heap_count %u, heaps %p.\n", iface, heap_count, heaps); @@ -4398,10 +4431,10 @@ static void d3d12_command_list_set_root_signature(struct d3d12_command_list *lis d3d12_command_list_invalidate_root_parameters(list, bind_point); } -static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootSignature(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootSignature(ID3D12GraphicsCommandList3 *iface, ID3D12RootSignature *root_signature) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); TRACE("iface %p, root_signature %p.\n", iface, root_signature); @@ -4409,10 +4442,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootSignature(ID3D12G unsafe_impl_from_ID3D12RootSignature(root_signature)); } -static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootSignature(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootSignature(ID3D12GraphicsCommandList3 *iface, ID3D12RootSignature *root_signature) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); TRACE("iface %p, root_signature %p.\n", iface, root_signature); @@ -4425,6 +4458,7 @@ static void d3d12_command_list_set_descriptor_table(struct d3d12_command_list *l { struct vkd3d_pipeline_bindings *bindings = &list->pipeline_bindings[bind_point]; const struct d3d12_root_signature *root_signature = bindings->root_signature; + struct d3d12_descriptor_heap *descriptor_heap; struct d3d12_desc *desc; assert(root_signature_get_descriptor_table(root_signature, index)); @@ -4435,15 +4469,25 @@ static void d3d12_command_list_set_descriptor_table(struct d3d12_command_list *l if (bindings->descriptor_tables[index] == desc) return; + descriptor_heap = d3d12_desc_get_descriptor_heap(desc); + if (!(descriptor_heap->desc.Flags & D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE)) + { + /* GetGPUDescriptorHandleForHeapStart() returns a null handle in this case, + * but a CPU handle could be passed. */ + WARN("Descriptor heap %p is not shader visible.\n", descriptor_heap); + return; + } + command_list_add_descriptor_heap(list, descriptor_heap); + bindings->descriptor_tables[index] = desc; bindings->descriptor_table_dirty_mask |= (uint64_t)1 << index; bindings->descriptor_table_active_mask |= (uint64_t)1 << index; } -static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootDescriptorTable(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootDescriptorTable(ID3D12GraphicsCommandList3 *iface, UINT root_parameter_index, D3D12_GPU_DESCRIPTOR_HANDLE base_descriptor) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); TRACE("iface %p, root_parameter_index %u, base_descriptor %#"PRIx64".\n", iface, root_parameter_index, base_descriptor.ptr); @@ -4452,10 +4496,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootDescriptorTable(I root_parameter_index, base_descriptor); } -static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootDescriptorTable(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootDescriptorTable(ID3D12GraphicsCommandList3 *iface, UINT root_parameter_index, D3D12_GPU_DESCRIPTOR_HANDLE base_descriptor) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); TRACE("iface %p, root_parameter_index %u, base_descriptor %#"PRIx64".\n", iface, root_parameter_index, base_descriptor.ptr); @@ -4477,10 +4521,10 @@ static void d3d12_command_list_set_root_constants(struct d3d12_command_list *lis c->stage_flags, c->offset + offset * sizeof(uint32_t), count * sizeof(uint32_t), data)); } -static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstant(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstant(ID3D12GraphicsCommandList3 *iface, UINT root_parameter_index, UINT data, UINT dst_offset) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); TRACE("iface %p, root_parameter_index %u, data 0x%08x, dst_offset %u.\n", iface, root_parameter_index, data, dst_offset); @@ -4489,10 +4533,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstant(ID3 root_parameter_index, dst_offset, 1, &data); } -static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRoot32BitConstant(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRoot32BitConstant(ID3D12GraphicsCommandList3 *iface, UINT root_parameter_index, UINT data, UINT dst_offset) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); TRACE("iface %p, root_parameter_index %u, data 0x%08x, dst_offset %u.\n", iface, root_parameter_index, data, dst_offset); @@ -4501,10 +4545,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRoot32BitConstant(ID root_parameter_index, dst_offset, 1, &data); } -static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstants(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstants(ID3D12GraphicsCommandList3 *iface, UINT root_parameter_index, UINT constant_count, const void *data, UINT dst_offset) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); TRACE("iface %p, root_parameter_index %u, constant_count %u, data %p, dst_offset %u.\n", iface, root_parameter_index, constant_count, data, dst_offset); @@ -4513,10 +4557,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstants(ID root_parameter_index, dst_offset, constant_count, data); } -static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRoot32BitConstants(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRoot32BitConstants(ID3D12GraphicsCommandList3 *iface, UINT root_parameter_index, UINT constant_count, const void *data, UINT dst_offset) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); TRACE("iface %p, root_parameter_index %u, constant_count %u, data %p, dst_offset %u.\n", iface, root_parameter_index, constant_count, data, dst_offset); @@ -4578,9 +4622,9 @@ static void d3d12_command_list_set_root_cbv(struct d3d12_command_list *list, } static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootConstantBufferView( - ID3D12GraphicsCommandList2 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) + ID3D12GraphicsCommandList3 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n", iface, root_parameter_index, address); @@ -4589,9 +4633,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootConstantBufferVie } static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootConstantBufferView( - ID3D12GraphicsCommandList2 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) + ID3D12GraphicsCommandList3 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n", iface, root_parameter_index, address); @@ -4650,9 +4694,9 @@ static void d3d12_command_list_set_root_descriptor(struct d3d12_command_list *li } static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootShaderResourceView( - ID3D12GraphicsCommandList2 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) + ID3D12GraphicsCommandList3 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n", iface, root_parameter_index, address); @@ -4662,9 +4706,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootShaderResourceVie } static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootShaderResourceView( - ID3D12GraphicsCommandList2 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) + ID3D12GraphicsCommandList3 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n", iface, root_parameter_index, address); @@ -4674,9 +4718,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootShaderResourceVi } static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootUnorderedAccessView( - ID3D12GraphicsCommandList2 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) + ID3D12GraphicsCommandList3 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n", iface, root_parameter_index, address); @@ -4686,9 +4730,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootUnorderedAccessVi } static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootUnorderedAccessView( - ID3D12GraphicsCommandList2 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) + ID3D12GraphicsCommandList3 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n", iface, root_parameter_index, address); @@ -4697,10 +4741,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootUnorderedAccessV root_parameter_index, address); } -static void STDMETHODCALLTYPE d3d12_command_list_IASetIndexBuffer(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_IASetIndexBuffer(ID3D12GraphicsCommandList3 *iface, const D3D12_INDEX_BUFFER_VIEW *view) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); const struct vkd3d_vk_device_procs *vk_procs; struct d3d12_resource *resource; enum VkIndexType index_type; @@ -4740,10 +4784,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_IASetIndexBuffer(ID3D12Graphics view->BufferLocation - resource->gpu_address, index_type)); } -static void STDMETHODCALLTYPE d3d12_command_list_IASetVertexBuffers(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_IASetVertexBuffers(ID3D12GraphicsCommandList3 *iface, UINT start_slot, UINT view_count, const D3D12_VERTEX_BUFFER_VIEW *views) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); const struct vkd3d_null_resources *null_resources; struct vkd3d_gpu_va_allocator *gpu_va_allocator; VkDeviceSize offsets[ARRAY_SIZE(list->strides)]; @@ -4798,10 +4842,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_IASetVertexBuffers(ID3D12Graphi d3d12_command_list_invalidate_current_pipeline(list); } -static void STDMETHODCALLTYPE d3d12_command_list_SOSetTargets(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_SOSetTargets(ID3D12GraphicsCommandList3 *iface, UINT start_slot, UINT view_count, const D3D12_STREAM_OUTPUT_BUFFER_VIEW *views) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); VkDeviceSize offsets[ARRAY_SIZE(list->so_counter_buffers)]; VkDeviceSize sizes[ARRAY_SIZE(list->so_counter_buffers)]; VkBuffer buffers[ARRAY_SIZE(list->so_counter_buffers)]; @@ -4863,11 +4907,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_SOSetTargets(ID3D12GraphicsComm VK_CALL(vkCmdBindTransformFeedbackBuffersEXT(list->vk_command_buffer, first, count, buffers, offsets, sizes)); } -static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(ID3D12GraphicsCommandList3 *iface, UINT render_target_descriptor_count, const D3D12_CPU_DESCRIPTOR_HANDLE *render_target_descriptors, BOOL single_descriptor_handle, const D3D12_CPU_DESCRIPTOR_HANDLE *depth_stencil_descriptor) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); const struct d3d12_rtv_desc *rtv_desc; const struct d3d12_dsv_desc *dsv_desc; VkFormat prev_dsv_format; @@ -5068,12 +5112,12 @@ static void d3d12_command_list_clear(struct d3d12_command_list *list, } } -static void STDMETHODCALLTYPE d3d12_command_list_ClearDepthStencilView(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_ClearDepthStencilView(ID3D12GraphicsCommandList3 *iface, D3D12_CPU_DESCRIPTOR_HANDLE dsv, D3D12_CLEAR_FLAGS flags, float depth, UINT8 stencil, UINT rect_count, const D3D12_RECT *rects) { const union VkClearValue clear_value = {.depthStencil = {depth, stencil}}; - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); const struct d3d12_dsv_desc *dsv_desc = d3d12_dsv_desc_from_cpu_handle(dsv); struct VkAttachmentDescription attachment_desc; struct VkAttachmentReference ds_reference; @@ -5117,10 +5161,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearDepthStencilView(ID3D12Gra &clear_value, rect_count, rects); } -static void STDMETHODCALLTYPE d3d12_command_list_ClearRenderTargetView(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_ClearRenderTargetView(ID3D12GraphicsCommandList3 *iface, D3D12_CPU_DESCRIPTOR_HANDLE rtv, const FLOAT color[4], UINT rect_count, const D3D12_RECT *rects) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); const struct d3d12_rtv_desc *rtv_desc = d3d12_rtv_desc_from_cpu_handle(rtv); struct VkAttachmentDescription attachment_desc; struct VkAttachmentReference color_reference; @@ -5365,11 +5409,11 @@ static const struct vkd3d_format *vkd3d_fixup_clear_uav_uint_colour(struct d3d12 } } -static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewUint(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewUint(ID3D12GraphicsCommandList3 *iface, D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle, D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle, ID3D12Resource *resource, const UINT values[4], UINT rect_count, const D3D12_RECT *rects) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); struct vkd3d_view *descriptor, *uint_view = NULL; struct d3d12_device *device = list->device; struct vkd3d_texture_view_desc view_desc; @@ -5431,11 +5475,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewUint(ID vkd3d_view_decref(uint_view, device); } -static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewFloat(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewFloat(ID3D12GraphicsCommandList3 *iface, D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle, D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle, ID3D12Resource *resource, const float values[4], UINT rect_count, const D3D12_RECT *rects) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); struct d3d12_resource *resource_impl; VkClearColorValue colour; struct vkd3d_view *view; @@ -5451,16 +5495,16 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewFloat(I d3d12_command_list_clear_uav(list, resource_impl, view, &colour, rect_count, rects); } -static void STDMETHODCALLTYPE d3d12_command_list_DiscardResource(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_DiscardResource(ID3D12GraphicsCommandList3 *iface, ID3D12Resource *resource, const D3D12_DISCARD_REGION *region) { FIXME_ONCE("iface %p, resource %p, region %p stub!\n", iface, resource, region); } -static void STDMETHODCALLTYPE d3d12_command_list_BeginQuery(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_BeginQuery(ID3D12GraphicsCommandList3 *iface, ID3D12QueryHeap *heap, D3D12_QUERY_TYPE type, UINT index) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); struct d3d12_query_heap *query_heap = unsafe_impl_from_ID3D12QueryHeap(heap); const struct vkd3d_vk_device_procs *vk_procs; VkQueryControlFlags flags = 0; @@ -5487,10 +5531,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_BeginQuery(ID3D12GraphicsComman VK_CALL(vkCmdBeginQuery(list->vk_command_buffer, query_heap->vk_query_pool, index, flags)); } -static void STDMETHODCALLTYPE d3d12_command_list_EndQuery(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_EndQuery(ID3D12GraphicsCommandList3 *iface, ID3D12QueryHeap *heap, D3D12_QUERY_TYPE type, UINT index) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); struct d3d12_query_heap *query_heap = unsafe_impl_from_ID3D12QueryHeap(heap); const struct vkd3d_vk_device_procs *vk_procs; @@ -5532,12 +5576,12 @@ static size_t get_query_stride(D3D12_QUERY_TYPE type) return sizeof(uint64_t); } -static void STDMETHODCALLTYPE d3d12_command_list_ResolveQueryData(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_ResolveQueryData(ID3D12GraphicsCommandList3 *iface, ID3D12QueryHeap *heap, D3D12_QUERY_TYPE type, UINT start_index, UINT query_count, ID3D12Resource *dst_buffer, UINT64 aligned_dst_buffer_offset) { const struct d3d12_query_heap *query_heap = unsafe_impl_from_ID3D12QueryHeap(heap); - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); struct d3d12_resource *buffer = unsafe_impl_from_ID3D12Resource(dst_buffer); const struct vkd3d_vk_device_procs *vk_procs; unsigned int i, first, count; @@ -5613,10 +5657,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResolveQueryData(ID3D12Graphics } } -static void STDMETHODCALLTYPE d3d12_command_list_SetPredication(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_SetPredication(ID3D12GraphicsCommandList3 *iface, ID3D12Resource *buffer, UINT64 aligned_buffer_offset, D3D12_PREDICATION_OP operation) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); struct d3d12_resource *resource = unsafe_impl_from_ID3D12Resource(buffer); const struct vkd3d_vulkan_info *vk_info = &list->device->vk_info; const struct vkd3d_vk_device_procs *vk_procs; @@ -5685,19 +5729,19 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetPredication(ID3D12GraphicsCo } } -static void STDMETHODCALLTYPE d3d12_command_list_SetMarker(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_SetMarker(ID3D12GraphicsCommandList3 *iface, UINT metadata, const void *data, UINT size) { FIXME("iface %p, metadata %#x, data %p, size %u stub!\n", iface, metadata, data, size); } -static void STDMETHODCALLTYPE d3d12_command_list_BeginEvent(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_BeginEvent(ID3D12GraphicsCommandList3 *iface, UINT metadata, const void *data, UINT size) { FIXME("iface %p, metadata %#x, data %p, size %u stub!\n", iface, metadata, data, size); } -static void STDMETHODCALLTYPE d3d12_command_list_EndEvent(ID3D12GraphicsCommandList2 *iface) +static void STDMETHODCALLTYPE d3d12_command_list_EndEvent(ID3D12GraphicsCommandList3 *iface) { FIXME("iface %p stub!\n", iface); } @@ -5706,14 +5750,14 @@ STATIC_ASSERT(sizeof(VkDispatchIndirectCommand) == sizeof(D3D12_DISPATCH_ARGUMEN STATIC_ASSERT(sizeof(VkDrawIndexedIndirectCommand) == sizeof(D3D12_DRAW_INDEXED_ARGUMENTS)); STATIC_ASSERT(sizeof(VkDrawIndirectCommand) == sizeof(D3D12_DRAW_ARGUMENTS)); -static void STDMETHODCALLTYPE d3d12_command_list_ExecuteIndirect(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_ExecuteIndirect(ID3D12GraphicsCommandList3 *iface, ID3D12CommandSignature *command_signature, UINT max_command_count, ID3D12Resource *arg_buffer, UINT64 arg_buffer_offset, ID3D12Resource *count_buffer, UINT64 count_buffer_offset) { struct d3d12_command_signature *sig_impl = unsafe_impl_from_ID3D12CommandSignature(command_signature); struct d3d12_resource *count_impl = unsafe_impl_from_ID3D12Resource(count_buffer); struct d3d12_resource *arg_impl = unsafe_impl_from_ID3D12Resource(arg_buffer); - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); const D3D12_COMMAND_SIGNATURE_DESC *signature_desc; const struct vkd3d_vk_device_procs *vk_procs; unsigned int i; @@ -5731,6 +5775,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_ExecuteIndirect(ID3D12GraphicsC return; } + d3d12_command_signature_incref(sig_impl); + signature_desc = &sig_impl->desc; for (i = 0; i < signature_desc->NumArgumentDescs; ++i) { @@ -5793,6 +5839,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_ExecuteIndirect(ID3D12GraphicsC if (!d3d12_command_list_update_compute_state(list)) { WARN("Failed to update compute state, ignoring dispatch.\n"); + d3d12_command_signature_decref(sig_impl); return; } @@ -5805,9 +5852,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_ExecuteIndirect(ID3D12GraphicsC break; } } + + d3d12_command_signature_decref(sig_impl); } -static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT(ID3D12GraphicsCommandList3 *iface, ID3D12Resource *dst_buffer, UINT64 dst_offset, ID3D12Resource *src_buffer, UINT64 src_offset, UINT dependent_resource_count, ID3D12Resource * const *dependent_resources, @@ -5820,7 +5869,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT(ID3D12Grap dependent_resource_count, dependent_resources, dependent_sub_resource_ranges); } -static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT64(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT64(ID3D12GraphicsCommandList3 *iface, ID3D12Resource *dst_buffer, UINT64 dst_offset, ID3D12Resource *src_buffer, UINT64 src_offset, UINT dependent_resource_count, ID3D12Resource * const *dependent_resources, @@ -5833,20 +5882,20 @@ static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT64(ID3D12Gr dependent_resource_count, dependent_resources, dependent_sub_resource_ranges); } -static void STDMETHODCALLTYPE d3d12_command_list_OMSetDepthBounds(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_OMSetDepthBounds(ID3D12GraphicsCommandList3 *iface, FLOAT min, FLOAT max) { FIXME("iface %p, min %.8e, max %.8e stub!\n", iface, min, max); } -static void STDMETHODCALLTYPE d3d12_command_list_SetSamplePositions(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_SetSamplePositions(ID3D12GraphicsCommandList3 *iface, UINT sample_count, UINT pixel_count, D3D12_SAMPLE_POSITION *sample_positions) { FIXME("iface %p, sample_count %u, pixel_count %u, sample_positions %p stub!\n", iface, sample_count, pixel_count, sample_positions); } -static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresourceRegion(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresourceRegion(ID3D12GraphicsCommandList3 *iface, ID3D12Resource *dst_resource, UINT dst_sub_resource_idx, UINT dst_x, UINT dst_y, ID3D12Resource *src_resource, UINT src_sub_resource_idx, D3D12_RECT *src_rect, DXGI_FORMAT format, D3D12_RESOLVE_MODE mode) @@ -5858,16 +5907,16 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresourceRegion(ID3D12 src_resource, src_sub_resource_idx, src_rect, format, mode); } -static void STDMETHODCALLTYPE d3d12_command_list_SetViewInstanceMask(ID3D12GraphicsCommandList2 *iface, UINT mask) +static void STDMETHODCALLTYPE d3d12_command_list_SetViewInstanceMask(ID3D12GraphicsCommandList3 *iface, UINT mask) { FIXME("iface %p, mask %#x stub!\n", iface, mask); } -static void STDMETHODCALLTYPE d3d12_command_list_WriteBufferImmediate(ID3D12GraphicsCommandList2 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_WriteBufferImmediate(ID3D12GraphicsCommandList3 *iface, UINT count, const D3D12_WRITEBUFFERIMMEDIATE_PARAMETER *parameters, const D3D12_WRITEBUFFERIMMEDIATE_MODE *modes) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); struct d3d12_resource *resource; unsigned int i; @@ -5880,7 +5929,13 @@ static void STDMETHODCALLTYPE d3d12_command_list_WriteBufferImmediate(ID3D12Grap } } -static const struct ID3D12GraphicsCommandList2Vtbl d3d12_command_list_vtbl = +static void STDMETHODCALLTYPE d3d12_command_list_SetProtectedResourceSession(ID3D12GraphicsCommandList3 *iface, + ID3D12ProtectedResourceSession *protected_session) +{ + FIXME("iface %p, protected_session %p stub!\n", iface, protected_session); +} + +static const struct ID3D12GraphicsCommandList3Vtbl d3d12_command_list_vtbl = { /* IUnknown methods */ d3d12_command_list_QueryInterface, @@ -5956,6 +6011,8 @@ static const struct ID3D12GraphicsCommandList2Vtbl d3d12_command_list_vtbl = d3d12_command_list_SetViewInstanceMask, /* ID3D12GraphicsCommandList2 methods */ d3d12_command_list_WriteBufferImmediate, + /* ID3D12GraphicsCommandList3 methods */ + d3d12_command_list_SetProtectedResourceSession, }; static struct d3d12_command_list *unsafe_impl_from_ID3D12CommandList(ID3D12CommandList *iface) @@ -5963,7 +6020,7 @@ static struct d3d12_command_list *unsafe_impl_from_ID3D12CommandList(ID3D12Comma if (!iface) return NULL; assert(iface->lpVtbl == (struct ID3D12CommandListVtbl *)&d3d12_command_list_vtbl); - return CONTAINING_RECORD(iface, struct d3d12_command_list, ID3D12GraphicsCommandList2_iface); + return CONTAINING_RECORD(iface, struct d3d12_command_list, ID3D12GraphicsCommandList3_iface); } static HRESULT d3d12_command_list_init(struct d3d12_command_list *list, struct d3d12_device *device, @@ -5972,7 +6029,7 @@ static HRESULT d3d12_command_list_init(struct d3d12_command_list *list, struct d { HRESULT hr; - list->ID3D12GraphicsCommandList2_iface.lpVtbl = &d3d12_command_list_vtbl; + list->ID3D12GraphicsCommandList3_iface.lpVtbl = &d3d12_command_list_vtbl; list->refcount = 1; list->type = type; @@ -7299,16 +7356,7 @@ static ULONG STDMETHODCALLTYPE d3d12_command_signature_Release(ID3D12CommandSign TRACE("%p decreasing refcount to %u.\n", signature, refcount); if (!refcount) - { - struct d3d12_device *device = signature->device; - - vkd3d_private_store_destroy(&signature->private_store); - - vkd3d_free((void *)signature->desc.pArgumentDescs); - vkd3d_free(signature); - - d3d12_device_release(device); - } + d3d12_command_signature_decref(signature); return refcount; } @@ -7415,6 +7463,7 @@ HRESULT d3d12_command_signature_create(struct d3d12_device *device, const D3D12_ object->ID3D12CommandSignature_iface.lpVtbl = &d3d12_command_signature_vtbl; object->refcount = 1; + object->internal_refcount = 1; object->desc = *desc; if (!(object->desc.pArgumentDescs = vkd3d_calloc(desc->NumArgumentDescs, sizeof(*desc->pArgumentDescs)))) diff --git a/libs/vkd3d/libs/vkd3d/device.c b/libs/vkd3d/libs/vkd3d/device.c index b9a8943cc08..a2e1f13dec3 100644 --- a/libs/vkd3d/libs/vkd3d/device.c +++ b/libs/vkd3d/libs/vkd3d/device.c @@ -2657,8 +2657,8 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandList(ID3D12Device *if initial_pipeline_state, &object))) return hr; - return return_interface(&object->ID3D12GraphicsCommandList2_iface, - &IID_ID3D12GraphicsCommandList2, riid, command_list); + return return_interface(&object->ID3D12GraphicsCommandList3_iface, + &IID_ID3D12GraphicsCommandList3, riid, command_list); } /* Direct3D feature levels restrict which formats can be optionally supported. */ @@ -3414,6 +3414,7 @@ static void STDMETHODCALLTYPE d3d12_device_CopyDescriptors(ID3D12Device *iface, struct d3d12_device *device = impl_from_ID3D12Device(iface); unsigned int dst_range_idx, dst_idx, src_range_idx, src_idx; unsigned int dst_range_size, src_range_size; + struct d3d12_descriptor_heap *dst_heap; const struct d3d12_desc *src; struct d3d12_desc *dst; @@ -3443,13 +3444,14 @@ static void STDMETHODCALLTYPE d3d12_device_CopyDescriptors(ID3D12Device *iface, src_range_size = src_descriptor_range_sizes ? src_descriptor_range_sizes[src_range_idx] : 1; dst = d3d12_desc_from_cpu_handle(dst_descriptor_range_offsets[dst_range_idx]); + dst_heap = d3d12_desc_get_descriptor_heap(dst); src = d3d12_desc_from_cpu_handle(src_descriptor_range_offsets[src_range_idx]); for (; dst_idx < dst_range_size && src_idx < src_range_size; ++dst_idx, ++src_idx) { if (dst[dst_idx].s.u.object == src[src_idx].s.u.object) continue; - d3d12_desc_copy(&dst[dst_idx], &src[src_idx], device); + d3d12_desc_copy(&dst[dst_idx], &src[src_idx], dst_heap, device); } if (dst_idx >= dst_range_size) @@ -3747,7 +3749,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateFence(ID3D12Device *iface, if (FAILED(hr = d3d12_fence_create(device, initial_value, flags, &object))) return hr; - return return_interface(&object->ID3D12Fence_iface, &IID_ID3D12Fence, riid, fence); + return return_interface(&object->ID3D12Fence1_iface, &IID_ID3D12Fence1, riid, fence); } static HRESULT STDMETHODCALLTYPE d3d12_device_GetDeviceRemovedReason(ID3D12Device *iface) @@ -3891,12 +3893,18 @@ static void STDMETHODCALLTYPE d3d12_device_GetResourceTiling(ID3D12Device *iface UINT *sub_resource_tiling_count, UINT first_sub_resource_tiling, D3D12_SUBRESOURCE_TILING *sub_resource_tilings) { - FIXME("iface %p, resource %p, total_tile_count %p, packed_mip_info %p, " + const struct d3d12_resource *resource_impl = impl_from_ID3D12Resource(resource); + struct d3d12_device *device = impl_from_ID3D12Device(iface); + + TRACE("iface %p, resource %p, total_tile_count %p, packed_mip_info %p, " "standard_title_shape %p, sub_resource_tiling_count %p, " - "first_sub_resource_tiling %u, sub_resource_tilings %p stub!\n", + "first_sub_resource_tiling %u, sub_resource_tilings %p.\n", iface, resource, total_tile_count, packed_mip_info, standard_tile_shape, sub_resource_tiling_count, first_sub_resource_tiling, sub_resource_tilings); + + d3d12_resource_get_tiling(device, resource_impl, total_tile_count, packed_mip_info, standard_tile_shape, + sub_resource_tiling_count, first_sub_resource_tiling, sub_resource_tilings); } static LUID * STDMETHODCALLTYPE d3d12_device_GetAdapterLuid(ID3D12Device *iface, LUID *luid) diff --git a/libs/vkd3d/libs/vkd3d/resource.c b/libs/vkd3d/libs/vkd3d/resource.c index 4c07d326504..cd3856c2937 100644 --- a/libs/vkd3d/libs/vkd3d/resource.c +++ b/libs/vkd3d/libs/vkd3d/resource.c @@ -971,6 +971,11 @@ HRESULT vkd3d_get_image_allocation_info(struct d3d12_device *device, return hr; } +static void d3d12_resource_tile_info_cleanup(struct d3d12_resource *resource) +{ + vkd3d_free(resource->tiles.subresources); +} + static void d3d12_resource_destroy(struct d3d12_resource *resource, struct d3d12_device *device) { const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; @@ -986,6 +991,8 @@ static void d3d12_resource_destroy(struct d3d12_resource *resource, struct d3d12 else VK_CALL(vkDestroyImage(device->vk_device, resource->u.vk_image, NULL)); + d3d12_resource_tile_info_cleanup(resource); + if (resource->heap) d3d12_heap_resource_destroyed(resource->heap); } @@ -1057,9 +1064,193 @@ static void d3d12_resource_get_level_box(const struct d3d12_resource *resource, box->back = d3d12_resource_desc_get_depth(&resource->desc, level); } -static void d3d12_resource_init_tiles(struct d3d12_resource *resource) +static void compute_image_subresource_size_in_tiles(const VkExtent3D *tile_extent, + const struct D3D12_RESOURCE_DESC *desc, unsigned int miplevel_idx, + struct vkd3d_tiled_region_extent *size) +{ + unsigned int width, height, depth; + + width = d3d12_resource_desc_get_width(desc, miplevel_idx); + height = d3d12_resource_desc_get_height(desc, miplevel_idx); + depth = d3d12_resource_desc_get_depth(desc, miplevel_idx); + size->width = (width + tile_extent->width - 1) / tile_extent->width; + size->height = (height + tile_extent->height - 1) / tile_extent->height; + size->depth = (depth + tile_extent->depth - 1) / tile_extent->depth; +} + +void d3d12_resource_get_tiling(struct d3d12_device *device, const struct d3d12_resource *resource, + UINT *total_tile_count, D3D12_PACKED_MIP_INFO *packed_mip_info, D3D12_TILE_SHAPE *standard_tile_shape, + UINT *subresource_tiling_count, UINT first_subresource_tiling, + D3D12_SUBRESOURCE_TILING *subresource_tilings) { - resource->tiles.subresource_count = d3d12_resource_desc_get_sub_resource_count(&resource->desc); + unsigned int i, subresource, subresource_count, miplevel_idx, count; + const struct vkd3d_subresource_tile_info *tile_info; + const VkExtent3D *tile_extent; + + tile_extent = &resource->tiles.tile_extent; + + if (packed_mip_info) + { + packed_mip_info->NumStandardMips = resource->tiles.standard_mip_count; + packed_mip_info->NumPackedMips = resource->desc.MipLevels - packed_mip_info->NumStandardMips; + packed_mip_info->NumTilesForPackedMips = !!resource->tiles.packed_mip_tile_count; /* non-zero dummy value */ + packed_mip_info->StartTileIndexInOverallResource = packed_mip_info->NumPackedMips + ? resource->tiles.subresources[resource->tiles.standard_mip_count].offset : 0; + } + + if (standard_tile_shape) + { + /* D3D12 docs say tile shape is cleared to zero if there is no standard mip, but drivers don't to do this. */ + standard_tile_shape->WidthInTexels = tile_extent->width; + standard_tile_shape->HeightInTexels = tile_extent->height; + standard_tile_shape->DepthInTexels = tile_extent->depth; + } + + if (total_tile_count) + *total_tile_count = resource->tiles.total_count; + + if (!subresource_tiling_count) + return; + + subresource_count = resource->tiles.subresource_count; + + count = subresource_count - min(first_subresource_tiling, subresource_count); + count = min(count, *subresource_tiling_count); + + for (i = 0; i < count; ++i) + { + subresource = i + first_subresource_tiling; + miplevel_idx = subresource % resource->desc.MipLevels; + if (miplevel_idx >= resource->tiles.standard_mip_count) + { + memset(&subresource_tilings[i], 0, sizeof(subresource_tilings[i])); + subresource_tilings[i].StartTileIndexInOverallResource = D3D12_PACKED_TILE; + continue; + } + + tile_info = &resource->tiles.subresources[subresource]; + subresource_tilings[i].StartTileIndexInOverallResource = tile_info->offset; + subresource_tilings[i].WidthInTiles = tile_info->extent.width; + subresource_tilings[i].HeightInTiles = tile_info->extent.height; + subresource_tilings[i].DepthInTiles = tile_info->extent.depth; + } + *subresource_tiling_count = i; +} + +static bool d3d12_resource_init_tiles(struct d3d12_resource *resource, struct d3d12_device *device) +{ + unsigned int i, start_idx, subresource_count, tile_count, miplevel_idx; + const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; + VkSparseImageMemoryRequirements *sparse_requirements_array; + VkSparseImageMemoryRequirements sparse_requirements = {0}; + struct vkd3d_subresource_tile_info *tile_info; + VkMemoryRequirements requirements; + const VkExtent3D *tile_extent; + uint32_t requirement_count; + + subresource_count = d3d12_resource_desc_get_sub_resource_count(&resource->desc); + + if (!(resource->tiles.subresources = vkd3d_calloc(subresource_count, sizeof(*resource->tiles.subresources)))) + { + ERR("Failed to allocate subresource info array.\n"); + return false; + } + + if (d3d12_resource_is_buffer(resource)) + { + assert(subresource_count == 1); + + VK_CALL(vkGetBufferMemoryRequirements(device->vk_device, resource->u.vk_buffer, &requirements)); + if (requirements.alignment > D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES) + FIXME("Vulkan device tile size is greater than the standard D3D12 tile size.\n"); + + tile_info = &resource->tiles.subresources[0]; + tile_info->offset = 0; + tile_info->extent.width = align(resource->desc.Width, D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES) + / D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES; + tile_info->extent.height = 1; + tile_info->extent.depth = 1; + tile_info->count = tile_info->extent.width; + + resource->tiles.tile_extent.width = D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES; + resource->tiles.tile_extent.height = 1; + resource->tiles.tile_extent.depth = 1; + resource->tiles.total_count = tile_info->extent.width; + resource->tiles.subresource_count = 1; + resource->tiles.standard_mip_count = 1; + resource->tiles.packed_mip_tile_count = 0; + } + else + { + VK_CALL(vkGetImageMemoryRequirements(device->vk_device, resource->u.vk_image, &requirements)); + if (requirements.alignment > D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES) + FIXME("Vulkan device tile size is greater than the standard D3D12 tile size.\n"); + + requirement_count = 0; + VK_CALL(vkGetImageSparseMemoryRequirements(device->vk_device, resource->u.vk_image, &requirement_count, NULL)); + if (!(sparse_requirements_array = vkd3d_calloc(requirement_count, sizeof(*sparse_requirements_array)))) + { + ERR("Failed to allocate sparse requirements array.\n"); + return false; + } + VK_CALL(vkGetImageSparseMemoryRequirements(device->vk_device, resource->u.vk_image, + &requirement_count, sparse_requirements_array)); + + for (i = 0; i < requirement_count; ++i) + { + if (sparse_requirements_array[i].formatProperties.aspectMask & resource->format->vk_aspect_mask) + { + if (sparse_requirements.formatProperties.aspectMask) + { + WARN("Ignoring properties for aspect mask %#x.\n", + sparse_requirements_array[i].formatProperties.aspectMask); + } + else + { + sparse_requirements = sparse_requirements_array[i]; + } + } + } + vkd3d_free(sparse_requirements_array); + if (!sparse_requirements.formatProperties.aspectMask) + { + WARN("Failed to get sparse requirements.\n"); + return false; + } + + resource->tiles.tile_extent = sparse_requirements.formatProperties.imageGranularity; + resource->tiles.subresource_count = subresource_count; + resource->tiles.standard_mip_count = sparse_requirements.imageMipTailSize + ? sparse_requirements.imageMipTailFirstLod : resource->desc.MipLevels; + resource->tiles.packed_mip_tile_count = (resource->tiles.standard_mip_count < resource->desc.MipLevels) + ? sparse_requirements.imageMipTailSize / requirements.alignment : 0; + + for (i = 0, start_idx = 0; i < subresource_count; ++i) + { + miplevel_idx = i % resource->desc.MipLevels; + + tile_extent = &sparse_requirements.formatProperties.imageGranularity; + tile_info = &resource->tiles.subresources[i]; + compute_image_subresource_size_in_tiles(tile_extent, &resource->desc, miplevel_idx, &tile_info->extent); + tile_info->offset = start_idx; + tile_info->count = 0; + + if (miplevel_idx < resource->tiles.standard_mip_count) + { + tile_count = tile_info->extent.width * tile_info->extent.height * tile_info->extent.depth; + start_idx += tile_count; + tile_info->count = tile_count; + } + else if (miplevel_idx == resource->tiles.standard_mip_count) + { + tile_info->count = 1; /* Non-zero dummy value */ + start_idx += 1; + } + } + resource->tiles.total_count = start_idx; + } + + return true; } /* ID3D12Resource */ @@ -2013,7 +2204,11 @@ HRESULT d3d12_reserved_resource_create(struct d3d12_device *device, desc, initial_state, optimized_clear_value, &object))) return hr; - d3d12_resource_init_tiles(object); + if (!d3d12_resource_init_tiles(object, device)) + { + d3d12_resource_Release(&object->ID3D12Resource_iface); + return E_OUTOFMEMORY; + } TRACE("Created reserved resource %p.\n", object); @@ -2411,13 +2606,11 @@ void d3d12_desc_flush_vk_heap_updates_locked(struct d3d12_descriptor_heap *descr descriptor_writes_free_object_refs(&writes, device); } -static void d3d12_desc_mark_as_modified(struct d3d12_desc *dst) +static void d3d12_desc_mark_as_modified(struct d3d12_desc *dst, struct d3d12_descriptor_heap *descriptor_heap) { - struct d3d12_descriptor_heap *descriptor_heap; unsigned int i, head; i = dst->index; - descriptor_heap = d3d12_desc_get_descriptor_heap(dst); head = descriptor_heap->dirty_list_head; /* Only one thread can swap the value away from zero. */ @@ -2431,14 +2624,20 @@ static void d3d12_desc_mark_as_modified(struct d3d12_desc *dst) } } -void d3d12_desc_write_atomic(struct d3d12_desc *dst, const struct d3d12_desc *src, - struct d3d12_device *device) +static inline void descriptor_heap_write_atomic(struct d3d12_descriptor_heap *descriptor_heap, struct d3d12_desc *dst, + const struct d3d12_desc *src, struct d3d12_device *device) { void *object = src->s.u.object; d3d12_desc_replace(dst, object, device); - if (device->use_vk_heaps && object && !dst->next) - d3d12_desc_mark_as_modified(dst); + if (descriptor_heap->use_vk_heaps && object && !dst->next) + d3d12_desc_mark_as_modified(dst, descriptor_heap); +} + +void d3d12_desc_write_atomic(struct d3d12_desc *dst, const struct d3d12_desc *src, + struct d3d12_device *device) +{ + descriptor_heap_write_atomic(d3d12_desc_get_descriptor_heap(dst), dst, src, device); } static void d3d12_desc_destroy(struct d3d12_desc *descriptor, struct d3d12_device *device) @@ -2446,7 +2645,9 @@ static void d3d12_desc_destroy(struct d3d12_desc *descriptor, struct d3d12_devic d3d12_desc_replace(descriptor, NULL, device); } -void d3d12_desc_copy(struct d3d12_desc *dst, const struct d3d12_desc *src, +/* This is a major performance bottleneck for some games, so do not load the device + * pointer from dst_heap. In some cases device will not be used. */ +void d3d12_desc_copy(struct d3d12_desc *dst, const struct d3d12_desc *src, struct d3d12_descriptor_heap *dst_heap, struct d3d12_device *device) { struct d3d12_desc tmp; @@ -2454,7 +2655,7 @@ void d3d12_desc_copy(struct d3d12_desc *dst, const struct d3d12_desc *src, assert(dst != src); tmp.s.u.object = d3d12_desc_get_object_ref(src, device); - d3d12_desc_write_atomic(dst, &tmp, device); + descriptor_heap_write_atomic(dst_heap, dst, &tmp, device); } static VkDeviceSize vkd3d_get_required_texel_buffer_alignment(const struct d3d12_device *device, @@ -3853,7 +4054,15 @@ static D3D12_GPU_DESCRIPTOR_HANDLE * STDMETHODCALLTYPE d3d12_descriptor_heap_Get TRACE("iface %p, descriptor %p.\n", iface, descriptor); - descriptor->ptr = (uint64_t)(intptr_t)heap->descriptors; + if (heap->desc.Flags & D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE) + { + descriptor->ptr = (uint64_t)(intptr_t)heap->descriptors; + } + else + { + WARN("Heap %p is not shader-visible.\n", iface); + descriptor->ptr = 0; + } return descriptor; } @@ -3956,7 +4165,7 @@ static HRESULT d3d12_descriptor_heap_vk_descriptor_sets_init(struct d3d12_descri descriptor_heap->vk_descriptor_pool = VK_NULL_HANDLE; memset(descriptor_heap->vk_descriptor_sets, 0, sizeof(descriptor_heap->vk_descriptor_sets)); - if (!device->use_vk_heaps || (desc->Type != D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV + if (!descriptor_heap->use_vk_heaps || (desc->Type != D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV && desc->Type != D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER)) return S_OK; @@ -3987,6 +4196,7 @@ static HRESULT d3d12_descriptor_heap_init(struct d3d12_descriptor_heap *descript if (FAILED(hr = vkd3d_private_store_init(&descriptor_heap->private_store))) return hr; + descriptor_heap->use_vk_heaps = device->use_vk_heaps && (desc->Flags & D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE); d3d12_descriptor_heap_vk_descriptor_sets_init(descriptor_heap, device, desc); vkd3d_mutex_init(&descriptor_heap->vk_sets_mutex); diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/libs/vkd3d/vkd3d_private.h index c5259420acf..4bd6812b16e 100644 --- a/libs/vkd3d/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/libs/vkd3d/vkd3d_private.h @@ -253,6 +253,11 @@ static inline void vkd3d_cond_destroy(struct vkd3d_cond *cond) { } +static inline unsigned int vkd3d_atomic_increment(unsigned int volatile *x) +{ + return InterlockedIncrement((LONG volatile *)x); +} + static inline unsigned int vkd3d_atomic_decrement(unsigned int volatile *x) { return InterlockedDecrement((LONG volatile *)x); @@ -387,6 +392,15 @@ static inline unsigned int vkd3d_atomic_decrement(unsigned int volatile *x) } # else # error "vkd3d_atomic_decrement() not implemented for this platform" +# endif /* HAVE_SYNC_SUB_AND_FETCH */ + +# if HAVE_SYNC_ADD_AND_FETCH +static inline unsigned int vkd3d_atomic_increment(unsigned int volatile *x) +{ + return __sync_add_and_fetch(x, 1); +} +# else +# error "vkd3d_atomic_increment() not implemented for this platform" # endif /* HAVE_SYNC_ADD_AND_FETCH */ # if HAVE_SYNC_BOOL_COMPARE_AND_SWAP @@ -602,10 +616,12 @@ struct vkd3d_signaled_semaphore /* ID3D12Fence */ struct d3d12_fence { - ID3D12Fence ID3D12Fence_iface; + ID3D12Fence1 ID3D12Fence1_iface; LONG internal_refcount; LONG refcount; + D3D12_FENCE_FLAGS flags; + uint64_t value; uint64_t max_pending_value; struct vkd3d_mutex mutex; @@ -673,9 +689,28 @@ struct d3d12_heap *unsafe_impl_from_ID3D12Heap(ID3D12Heap *iface); #define VKD3D_RESOURCE_DEDICATED_HEAP 0x00000008 #define VKD3D_RESOURCE_LINEAR_TILING 0x00000010 +struct vkd3d_tiled_region_extent +{ + unsigned int width; + unsigned int height; + unsigned int depth; +}; + +struct vkd3d_subresource_tile_info +{ + unsigned int offset; + unsigned int count; + struct vkd3d_tiled_region_extent extent; +}; + struct d3d12_resource_tile_info { + VkExtent3D tile_extent; + unsigned int total_count; + unsigned int standard_mip_count; + unsigned int packed_mip_tile_count; unsigned int subresource_count; + struct vkd3d_subresource_tile_info *subresources; }; /* ID3D12Resource */ @@ -728,6 +763,10 @@ static inline bool d3d12_resource_is_texture(const struct d3d12_resource *resour bool d3d12_resource_is_cpu_accessible(const struct d3d12_resource *resource); HRESULT d3d12_resource_validate_desc(const D3D12_RESOURCE_DESC *desc, struct d3d12_device *device); +void d3d12_resource_get_tiling(struct d3d12_device *device, const struct d3d12_resource *resource, + UINT *total_tile_count, D3D12_PACKED_MIP_INFO *packed_mip_info, D3D12_TILE_SHAPE *standard_tile_shape, + UINT *sub_resource_tiling_count, UINT first_sub_resource_tiling, + D3D12_SUBRESOURCE_TILING *sub_resource_tilings); HRESULT d3d12_committed_resource_create(struct d3d12_device *device, const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags, @@ -868,8 +907,9 @@ static inline void *d3d12_desc_get_object_ref(const volatile struct d3d12_desc * { do { - view = src->s.u.object; - } while (view && !vkd3d_view_incref(view)); + if (!(view = src->s.u.object)) + return NULL; + } while (!vkd3d_view_incref(view)); /* Check if the object is still in src to handle the case where it was * already freed and reused elsewhere when the refcount was incremented. */ @@ -895,7 +935,10 @@ static inline void d3d12_desc_copy_raw(struct d3d12_desc *dst, const struct d3d1 dst->s = src->s; } -void d3d12_desc_copy(struct d3d12_desc *dst, const struct d3d12_desc *src, struct d3d12_device *device); +struct d3d12_descriptor_heap; + +void d3d12_desc_copy(struct d3d12_desc *dst, const struct d3d12_desc *src, struct d3d12_descriptor_heap *dst_heap, + struct d3d12_device *device); void d3d12_desc_create_cbv(struct d3d12_desc *descriptor, struct d3d12_device *device, const D3D12_CONSTANT_BUFFER_VIEW_DESC *desc); void d3d12_desc_create_srv(struct d3d12_desc *descriptor, @@ -998,6 +1041,7 @@ struct d3d12_descriptor_heap D3D12_DESCRIPTOR_HEAP_DESC desc; struct d3d12_device *device; + bool use_vk_heaps; struct vkd3d_private_store private_store; @@ -1382,7 +1426,7 @@ enum vkd3d_pipeline_bind_point /* ID3D12CommandList */ struct d3d12_command_list { - ID3D12GraphicsCommandList2 ID3D12GraphicsCommandList2_iface; + ID3D12GraphicsCommandList3 ID3D12GraphicsCommandList3_iface; LONG refcount; D3D12_COMMAND_LIST_TYPE type; @@ -1575,6 +1619,7 @@ struct d3d12_command_signature { ID3D12CommandSignature ID3D12CommandSignature_iface; LONG refcount; + unsigned int internal_refcount; D3D12_COMMAND_SIGNATURE_DESC desc; -- 2.40.1