2025-05-15 08:02:49 +10:00
|
|
|
From f18e3a53d307c87bbe7e0d70918cbc252d58c5d1 Mon Sep 17 00:00:00 2001
|
2025-05-07 07:49:36 +10:00
|
|
|
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
|
|
|
|
Date: Wed, 7 May 2025 07:27:09 +1000
|
2025-05-13 09:05:49 +10:00
|
|
|
Subject: [PATCH] Updated vkd3d to 960244bf1ea66755b0fbe11c4d40fa0fbf211d97.
|
2025-05-07 07:49:36 +10:00
|
|
|
|
|
|
|
---
|
|
|
|
libs/vkd3d/libs/vkd3d-shader/dxil.c | 87 +++++++----------
|
|
|
|
libs/vkd3d/libs/vkd3d-shader/fx.c | 90 +++++++++++-------
|
|
|
|
libs/vkd3d/libs/vkd3d/command.c | 131 ++++++++++++++++----------
|
|
|
|
libs/vkd3d/libs/vkd3d/device.c | 121 +++++++++++++++++++++++-
|
|
|
|
libs/vkd3d/libs/vkd3d/vkd3d_private.h | 20 +++-
|
|
|
|
5 files changed, 308 insertions(+), 141 deletions(-)
|
|
|
|
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c
|
|
|
|
index 52bab40b553..da872afc265 100644
|
|
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c
|
|
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c
|
|
|
|
@@ -648,6 +648,8 @@ enum sm6_value_type
|
|
|
|
VALUE_TYPE_ICB,
|
|
|
|
VALUE_TYPE_HANDLE,
|
|
|
|
VALUE_TYPE_SSA,
|
|
|
|
+ VALUE_TYPE_UNDEFINED,
|
|
|
|
+ VALUE_TYPE_INVALID,
|
|
|
|
};
|
|
|
|
|
|
|
|
struct sm6_function_data
|
|
|
|
@@ -674,7 +676,6 @@ struct sm6_value
|
|
|
|
const struct sm6_type *type;
|
|
|
|
enum sm6_value_type value_type;
|
|
|
|
unsigned int structure_stride;
|
|
|
|
- bool is_undefined;
|
|
|
|
bool is_back_ref;
|
|
|
|
union
|
|
|
|
{
|
|
|
|
@@ -2243,6 +2244,8 @@ static inline bool sm6_value_is_register(const struct sm6_value *value)
|
|
|
|
{
|
|
|
|
case VALUE_TYPE_REG:
|
|
|
|
case VALUE_TYPE_SSA:
|
|
|
|
+ case VALUE_TYPE_UNDEFINED:
|
|
|
|
+ case VALUE_TYPE_INVALID:
|
|
|
|
return true;
|
|
|
|
|
|
|
|
default:
|
|
|
|
@@ -2407,6 +2410,10 @@ static enum vkd3d_data_type vkd3d_data_type_from_sm6_type(const struct sm6_type
|
|
|
|
|
|
|
|
static void sm6_register_from_value(struct vkd3d_shader_register *reg, const struct sm6_value *value)
|
|
|
|
{
|
|
|
|
+ enum vkd3d_data_type data_type;
|
|
|
|
+
|
|
|
|
+ data_type = vkd3d_data_type_from_sm6_type(sm6_type_get_scalar_type(value->type, 0));
|
|
|
|
+
|
|
|
|
switch (value->value_type)
|
|
|
|
{
|
|
|
|
case VALUE_TYPE_REG:
|
|
|
|
@@ -2414,11 +2421,15 @@ static void sm6_register_from_value(struct vkd3d_shader_register *reg, const str
|
|
|
|
break;
|
|
|
|
|
|
|
|
case VALUE_TYPE_SSA:
|
|
|
|
- register_init_with_id(reg, VKD3DSPR_SSA, vkd3d_data_type_from_sm6_type(
|
|
|
|
- sm6_type_get_scalar_type(value->type, 0)), value->u.ssa.id);
|
|
|
|
+ register_init_with_id(reg, VKD3DSPR_SSA, data_type, value->u.ssa.id);
|
|
|
|
reg->dimension = sm6_type_is_scalar(value->type) ? VSIR_DIMENSION_SCALAR : VSIR_DIMENSION_VEC4;
|
|
|
|
break;
|
|
|
|
|
|
|
|
+ case VALUE_TYPE_UNDEFINED:
|
|
|
|
+ case VALUE_TYPE_INVALID:
|
|
|
|
+ vsir_register_init(reg, VKD3DSPR_UNDEF, data_type, 0);
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
case VALUE_TYPE_FUNCTION:
|
|
|
|
case VALUE_TYPE_HANDLE:
|
|
|
|
case VALUE_TYPE_ICB:
|
|
|
|
@@ -2445,32 +2456,6 @@ static void sm6_parser_init_ssa_value(struct sm6_parser *sm6, struct sm6_value *
|
|
|
|
sm6_register_from_value(&value->reg, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
-static void register_init_ssa_vector(struct vkd3d_shader_register *reg, const struct sm6_type *type,
|
|
|
|
- unsigned int component_count, struct sm6_value *value, struct sm6_parser *sm6)
|
|
|
|
-{
|
|
|
|
- enum vkd3d_data_type data_type;
|
|
|
|
- unsigned int id;
|
|
|
|
-
|
|
|
|
- if (value && register_is_ssa(&value->reg) && value->reg.idx[0].offset)
|
|
|
|
- {
|
|
|
|
- id = value->reg.idx[0].offset;
|
|
|
|
- TRACE("Using forward-allocated id %u.\n", id);
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- id = sm6_parser_alloc_ssa_id(sm6);
|
|
|
|
- }
|
|
|
|
- data_type = vkd3d_data_type_from_sm6_type(sm6_type_get_scalar_type(type, 0));
|
|
|
|
- register_init_with_id(reg, VKD3DSPR_SSA, data_type, id);
|
|
|
|
- reg->dimension = component_count > 1 ? VSIR_DIMENSION_VEC4 : VSIR_DIMENSION_SCALAR;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void register_init_ssa_scalar(struct vkd3d_shader_register *reg, const struct sm6_type *type,
|
|
|
|
- struct sm6_value *value, struct sm6_parser *sm6)
|
|
|
|
-{
|
|
|
|
- register_init_ssa_vector(reg, sm6_type_get_scalar_type(type, 0), 1, value, sm6);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
static void register_make_constant_uint(struct vkd3d_shader_register *reg, unsigned int value)
|
|
|
|
{
|
|
|
|
vsir_register_init(reg, VKD3DSPR_IMMCONST, VKD3D_DATA_UINT, 0);
|
|
|
|
@@ -3406,16 +3391,16 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const
|
|
|
|
|
|
|
|
case CST_CODE_UNDEF:
|
|
|
|
dxil_record_validate_operand_max_count(record, 0, sm6);
|
|
|
|
- dst->reg.type = VKD3DSPR_UNDEF;
|
|
|
|
- /* Mark as explicitly undefined, not the result of a missing constant code or instruction. */
|
|
|
|
- dst->is_undefined = true;
|
|
|
|
+ dst->value_type = VALUE_TYPE_UNDEFINED;
|
|
|
|
+ sm6_register_from_value(&dst->reg, dst);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
FIXME("Unhandled constant code %u.\n", record->code);
|
|
|
|
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
|
|
|
|
"Constant code %u is unhandled.", record->code);
|
|
|
|
- dst->reg.type = VKD3DSPR_UNDEF;
|
|
|
|
+ dst->value_type = VALUE_TYPE_INVALID;
|
|
|
|
+ sm6_register_from_value(&dst->reg, dst);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
@@ -4602,7 +4587,7 @@ static bool sm6_parser_emit_coordinate_construct(struct sm6_parser *sm6, const s
|
|
|
|
|
|
|
|
for (component_count = 0; component_count < max_operands; ++component_count)
|
|
|
|
{
|
|
|
|
- if (!z_operand && operands[component_count]->is_undefined)
|
|
|
|
+ if (!z_operand && operands[component_count]->value_type == VALUE_TYPE_UNDEFINED)
|
|
|
|
break;
|
|
|
|
sm6_register_from_value(&operand_regs[component_count], operands[component_count]);
|
|
|
|
}
|
|
|
|
@@ -4838,7 +4823,7 @@ static void sm6_parser_emit_dx_atomic_binop(struct sm6_parser *sm6, enum dx_intr
|
|
|
|
|
|
|
|
for (i = coord_idx + coord_count; i < coord_idx + 3; ++i)
|
|
|
|
{
|
|
|
|
- if (!operands[i]->is_undefined)
|
|
|
|
+ if (operands[i]->value_type != VALUE_TYPE_UNDEFINED)
|
|
|
|
{
|
|
|
|
WARN("Ignoring unexpected operand.\n");
|
|
|
|
vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS,
|
|
|
|
@@ -4857,13 +4842,13 @@ static void sm6_parser_emit_dx_atomic_binop(struct sm6_parser *sm6, enum dx_intr
|
|
|
|
src_param_init_from_value(&src_params[1], operands[4]);
|
|
|
|
src_param_init_from_value(&src_params[1 + is_cmp_xchg], operands[5]);
|
|
|
|
|
|
|
|
+ sm6_parser_init_ssa_value(sm6, dst);
|
|
|
|
+
|
|
|
|
dst_params = instruction_dst_params_alloc(ins, 2, sm6);
|
|
|
|
dst_param_init(&dst_params[0]);
|
|
|
|
- register_init_ssa_scalar(&dst_params[0].reg, dst->type, dst, sm6);
|
|
|
|
+ sm6_register_from_value(&dst_params[0].reg, dst);
|
|
|
|
dst_param_init(&dst_params[1]);
|
|
|
|
sm6_register_from_handle(sm6, &resource->u.handle, &dst_params[1].reg);
|
|
|
|
-
|
|
|
|
- dst->reg = dst_params[0].reg;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sm6_parser_emit_dx_barrier(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
|
|
|
|
@@ -5393,7 +5378,7 @@ static void sm6_parser_emit_dx_get_dimensions(struct sm6_parser *sm6, enum dx_in
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
- if (!operands[1]->is_undefined)
|
|
|
|
+ if (operands[1]->value_type != VALUE_TYPE_UNDEFINED)
|
|
|
|
{
|
|
|
|
WARN("Ignoring unexpected operand.\n");
|
|
|
|
vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS,
|
|
|
|
@@ -5450,7 +5435,7 @@ static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrin
|
|
|
|
row_index = sm6_value_get_constant_uint(operands[0]);
|
|
|
|
column_index = sm6_value_get_constant_uint(operands[2]);
|
|
|
|
|
|
|
|
- if (is_control_point && operands[3]->is_undefined)
|
|
|
|
+ if (is_control_point && operands[3]->value_type == VALUE_TYPE_UNDEFINED)
|
|
|
|
{
|
|
|
|
/* dxcompiler will compile source which does this, so let it pass. */
|
|
|
|
WARN("Control point id is undefined.\n");
|
|
|
|
@@ -5493,7 +5478,7 @@ static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrin
|
|
|
|
if (e->register_count > 1)
|
|
|
|
register_index_address_init(&src_param->reg.idx[count++], operands[1], sm6);
|
|
|
|
|
|
|
|
- if (!is_patch_constant && !operands[3]->is_undefined)
|
|
|
|
+ if (!is_patch_constant && operands[3]->value_type != VALUE_TYPE_UNDEFINED)
|
|
|
|
{
|
|
|
|
VKD3D_ASSERT(src_param->reg.idx_count > count);
|
|
|
|
register_index_address_init(&src_param->reg.idx[count], operands[3], sm6);
|
|
|
|
@@ -6004,13 +5989,14 @@ static void sm6_parser_emit_dx_sincos(struct sm6_parser *sm6, enum dx_intrinsic_
|
|
|
|
return;
|
|
|
|
src_param_init_from_value(src_param, operands[0]);
|
|
|
|
|
|
|
|
+ sm6_parser_init_ssa_value(sm6, dst);
|
|
|
|
+
|
|
|
|
index = op == DX_COS;
|
|
|
|
dst_params = instruction_dst_params_alloc(ins, 2, sm6);
|
|
|
|
dst_param_init(&dst_params[0]);
|
|
|
|
dst_param_init(&dst_params[1]);
|
|
|
|
- register_init_ssa_scalar(&dst_params[index].reg, dst->type, dst, sm6);
|
|
|
|
+ sm6_register_from_value(&dst_params[index].reg, dst);
|
|
|
|
vsir_dst_param_init_null(&dst_params[index ^ 1]);
|
|
|
|
- dst->reg = dst_params[index].reg;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sm6_parser_emit_dx_split_double(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
|
|
|
|
@@ -6619,16 +6605,13 @@ static bool sm6_parser_validate_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_
|
|
|
|
static void sm6_parser_emit_unhandled(struct sm6_parser *sm6, struct vkd3d_shader_instruction *ins,
|
|
|
|
struct sm6_value *dst)
|
|
|
|
{
|
|
|
|
- const struct sm6_type *type;
|
|
|
|
-
|
|
|
|
ins->opcode = VKD3DSIH_NOP;
|
|
|
|
|
|
|
|
if (!dst->type)
|
|
|
|
return;
|
|
|
|
|
|
|
|
- type = sm6_type_get_scalar_type(dst->type, 0);
|
|
|
|
- vsir_register_init(&dst->reg, VKD3DSPR_UNDEF, vkd3d_data_type_from_sm6_type(type), 0);
|
|
|
|
- /* dst->is_undefined is not set here because it flags only explicitly undefined values. */
|
|
|
|
+ dst->value_type = VALUE_TYPE_INVALID;
|
|
|
|
+ sm6_register_from_value(&dst->reg, dst);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sm6_parser_decode_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
|
|
|
|
@@ -7115,14 +7098,14 @@ static void sm6_parser_emit_cmpxchg(struct sm6_parser *sm6, const struct dxil_re
|
|
|
|
src_param_init_from_value(&src_params[1], cmp);
|
|
|
|
src_param_init_from_value(&src_params[2], new);
|
|
|
|
|
|
|
|
+ sm6_parser_init_ssa_value(sm6, dst);
|
|
|
|
+
|
|
|
|
if (!(dst_params = instruction_dst_params_alloc(ins, 2, sm6)))
|
|
|
|
return;
|
|
|
|
- register_init_ssa_scalar(&dst_params[0].reg, dst->type, dst, sm6);
|
|
|
|
+ sm6_register_from_value(&dst_params[0].reg, dst);
|
|
|
|
dst_param_init(&dst_params[0]);
|
|
|
|
dst_params[1].reg = reg;
|
|
|
|
dst_param_init(&dst_params[1]);
|
|
|
|
-
|
|
|
|
- dst->reg = dst_params[0].reg;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sm6_parser_emit_extractval(struct sm6_parser *sm6, const struct dxil_record *record,
|
|
|
|
@@ -7404,7 +7387,7 @@ static void sm6_parser_emit_phi(struct sm6_parser *sm6, const struct dxil_record
|
|
|
|
}
|
|
|
|
|
|
|
|
dst->type = type;
|
|
|
|
- register_init_ssa_scalar(&dst->reg, type, dst, sm6);
|
|
|
|
+ sm6_parser_init_ssa_value(sm6, dst);
|
|
|
|
|
|
|
|
if (!(phi = sm6_block_phi_require_space(code_block, sm6)))
|
|
|
|
return;
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/fx.c b/libs/vkd3d/libs/vkd3d-shader/fx.c
|
|
|
|
index c93f01039ef..6f67af2f7e8 100644
|
|
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/fx.c
|
|
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/fx.c
|
|
|
|
@@ -2655,38 +2655,31 @@ fx_4_states[] =
|
|
|
|
{ "ComputeShader", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_COMPUTESHADER, 1, 1, 58 },
|
|
|
|
};
|
|
|
|
|
|
|
|
-static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl_state_block_entry *entry,
|
|
|
|
- struct fx_write_context *fx)
|
|
|
|
+static const struct fx_4_state fx_5_blend_states[] =
|
|
|
|
{
|
|
|
|
- static const struct fx_4_state fx_5_blend_states[] =
|
|
|
|
- {
|
|
|
|
- { "AlphaToCoverageEnable", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 36, bool_values },
|
|
|
|
- { "BlendEnable", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 8, 37, bool_values },
|
|
|
|
- { "SrcBlend", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 38, blend_values },
|
|
|
|
- { "DestBlend", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 39, blend_values },
|
|
|
|
- { "BlendOp", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 40, blendop_values },
|
|
|
|
- { "SrcBlendAlpha", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 41, blend_values },
|
|
|
|
- { "DestBlendAlpha", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 42, blend_values },
|
|
|
|
- { "BlendOpAlpha", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 43, blendop_values },
|
|
|
|
- { "RenderTargetWriteMask", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT8, 1, 8, 44 },
|
|
|
|
- };
|
|
|
|
+ { "AlphaToCoverageEnable", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 36, bool_values },
|
|
|
|
+ { "BlendEnable", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 8, 37, bool_values },
|
|
|
|
+ { "SrcBlend", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 38, blend_values },
|
|
|
|
+ { "DestBlend", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 39, blend_values },
|
|
|
|
+ { "BlendOp", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 40, blendop_values },
|
|
|
|
+ { "SrcBlendAlpha", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 41, blend_values },
|
|
|
|
+ { "DestBlendAlpha", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 42, blend_values },
|
|
|
|
+ { "BlendOpAlpha", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 43, blendop_values },
|
|
|
|
+ { "RenderTargetWriteMask", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT8, 1, 8, 44 },
|
|
|
|
+};
|
|
|
|
|
|
|
|
- struct state_table
|
|
|
|
- {
|
|
|
|
- const struct fx_4_state *ptr;
|
|
|
|
- unsigned int count;
|
|
|
|
- } table;
|
|
|
|
+struct fx_4_state_table
|
|
|
|
+{
|
|
|
|
+ const struct fx_4_state *ptr;
|
|
|
|
+ unsigned int count;
|
|
|
|
+};
|
|
|
|
|
|
|
|
- const struct hlsl_type *type = hlsl_get_multiarray_element_type(var->data_type);
|
|
|
|
- struct replace_state_context replace_context;
|
|
|
|
- const struct fx_4_state *state = NULL;
|
|
|
|
- struct hlsl_type *state_type = NULL;
|
|
|
|
- struct hlsl_ctx *ctx = fx->ctx;
|
|
|
|
- enum hlsl_base_type base_type;
|
|
|
|
- struct hlsl_ir_node *node;
|
|
|
|
- unsigned int i;
|
|
|
|
+static struct fx_4_state_table fx_4_get_state_table(enum hlsl_type_class type_class,
|
|
|
|
+ unsigned int major, unsigned int minor)
|
|
|
|
+{
|
|
|
|
+ struct fx_4_state_table table;
|
|
|
|
|
|
|
|
- if (type->class == HLSL_CLASS_BLEND_STATE && ctx->profile->major_version == 5)
|
|
|
|
+ if (type_class == HLSL_CLASS_BLEND_STATE && (major == 5 || (major == 4 && minor == 1)))
|
|
|
|
{
|
|
|
|
table.ptr = fx_5_blend_states;
|
|
|
|
table.count = ARRAY_SIZE(fx_5_blend_states);
|
|
|
|
@@ -2697,6 +2690,24 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl
|
|
|
|
table.count = ARRAY_SIZE(fx_4_states);
|
|
|
|
}
|
|
|
|
|
|
|
|
+ return table;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var,
|
|
|
|
+ struct hlsl_state_block_entry *entry, struct fx_write_context *fx)
|
|
|
|
+{
|
|
|
|
+ const struct hlsl_type *type = hlsl_get_multiarray_element_type(var->data_type);
|
|
|
|
+ struct replace_state_context replace_context;
|
|
|
|
+ const struct fx_4_state *state = NULL;
|
|
|
|
+ struct hlsl_type *state_type = NULL;
|
|
|
|
+ struct hlsl_ctx *ctx = fx->ctx;
|
|
|
|
+ enum hlsl_base_type base_type;
|
|
|
|
+ struct fx_4_state_table table;
|
|
|
|
+ struct hlsl_ir_node *node;
|
|
|
|
+ unsigned int i;
|
|
|
|
+
|
|
|
|
+ table = fx_4_get_state_table(type->class, ctx->profile->major_version, ctx->profile->minor_version);
|
|
|
|
+
|
|
|
|
for (i = 0; i < table.count; ++i)
|
|
|
|
{
|
|
|
|
if (type->class == table.ptr[i].container
|
|
|
|
@@ -3439,7 +3450,11 @@ struct fx_parser
|
|
|
|
struct vkd3d_shader_message_context *message_context;
|
|
|
|
struct vkd3d_string_buffer buffer;
|
|
|
|
unsigned int indent;
|
|
|
|
- unsigned int version;
|
|
|
|
+ struct
|
|
|
|
+ {
|
|
|
|
+ unsigned int major;
|
|
|
|
+ unsigned int minor;
|
|
|
|
+ } version;
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
const uint8_t *ptr;
|
|
|
|
@@ -4904,16 +4919,18 @@ static void fx_4_parse_state_object_initializer(struct fx_parser *parser, uint32
|
|
|
|
};
|
|
|
|
const struct rhs_named_value *named_value;
|
|
|
|
struct fx_5_shader shader = { 0 };
|
|
|
|
+ struct fx_4_state_table table;
|
|
|
|
unsigned int shader_type = 0;
|
|
|
|
uint32_t i, j, comp_count;
|
|
|
|
struct fx_4_state *state;
|
|
|
|
|
|
|
|
+ table = fx_4_get_state_table(type_class, parser->version.major, parser->version.minor);
|
|
|
|
+
|
|
|
|
for (i = 0; i < count; ++i)
|
|
|
|
{
|
|
|
|
fx_parser_read_u32s(parser, &entry, sizeof(entry));
|
|
|
|
|
|
|
|
- if (!(state = bsearch(&entry.id, fx_4_states, ARRAY_SIZE(fx_4_states),
|
|
|
|
- sizeof(*fx_4_states), fx_4_state_id_compare)))
|
|
|
|
+ if (!(state = bsearch(&entry.id, table.ptr, table.count, sizeof(*table.ptr), fx_4_state_id_compare)))
|
|
|
|
{
|
|
|
|
fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA, "Unrecognized state id %#x.", entry.id);
|
|
|
|
break;
|
|
|
|
@@ -5183,7 +5200,7 @@ static void fx_parse_fx_4_technique(struct fx_parser *parser)
|
|
|
|
name = fx_4_get_string(parser, technique.name);
|
|
|
|
|
|
|
|
parse_fx_print_indent(parser);
|
|
|
|
- vkd3d_string_buffer_printf(&parser->buffer, "technique%u %s", parser->version, name);
|
|
|
|
+ vkd3d_string_buffer_printf(&parser->buffer, "technique%u %s", parser->version.major == 4 ? 10 : 11, name);
|
|
|
|
fx_parse_fx_4_annotations(parser);
|
|
|
|
|
|
|
|
vkd3d_string_buffer_printf(&parser->buffer, "\n");
|
|
|
|
@@ -5277,7 +5294,6 @@ static void fx_4_parse(struct fx_parser *parser)
|
|
|
|
} header;
|
|
|
|
uint32_t i;
|
|
|
|
|
|
|
|
- parser->version = 10;
|
|
|
|
fx_parser_read_u32s(parser, &header, sizeof(header));
|
|
|
|
parser->buffer_count = header.buffer_count;
|
|
|
|
parser->object_count = header.object_count;
|
|
|
|
@@ -5331,7 +5347,6 @@ static void fx_5_parse(struct fx_parser *parser)
|
|
|
|
uint32_t class_instance_element_count;
|
|
|
|
} header;
|
|
|
|
|
|
|
|
- parser->version = 11;
|
|
|
|
fx_parser_read_u32s(parser, &header, sizeof(header));
|
|
|
|
parser->buffer_count = header.buffer_count;
|
|
|
|
parser->object_count = header.object_count;
|
|
|
|
@@ -5390,13 +5405,20 @@ int fx_parse(const struct vkd3d_shader_compile_info *compile_info,
|
|
|
|
switch (version)
|
|
|
|
{
|
|
|
|
case 0xfeff0901:
|
|
|
|
+ parser.version.major = 3;
|
|
|
|
fx_2_parse(&parser);
|
|
|
|
break;
|
|
|
|
case 0xfeff1001:
|
|
|
|
+ parser.version.major = 4;
|
|
|
|
+ fx_4_parse(&parser);
|
|
|
|
+ break;
|
|
|
|
case 0xfeff1011:
|
|
|
|
+ parser.version.major = 4;
|
|
|
|
+ parser.version.minor = 1;
|
|
|
|
fx_4_parse(&parser);
|
|
|
|
break;
|
|
|
|
case 0xfeff2001:
|
|
|
|
+ parser.version.major = 5;
|
|
|
|
fx_5_parse(&parser);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d/command.c b/libs/vkd3d/libs/vkd3d/command.c
|
|
|
|
index 1ff58f97565..e487ed0b9ad 100644
|
|
|
|
--- a/libs/vkd3d/libs/vkd3d/command.c
|
|
|
|
+++ b/libs/vkd3d/libs/vkd3d/command.c
|
|
|
|
@@ -31,6 +31,43 @@ static void d3d12_command_queue_submit_locked(struct d3d12_command_queue *queue)
|
|
|
|
static HRESULT d3d12_command_queue_flush_ops(struct d3d12_command_queue *queue, bool *flushed_any);
|
|
|
|
static HRESULT d3d12_command_queue_flush_ops_locked(struct d3d12_command_queue *queue, bool *flushed_any);
|
|
|
|
|
|
|
|
+static void vkd3d_null_event_signal(struct vkd3d_null_event *e)
|
|
|
|
+{
|
|
|
|
+ vkd3d_mutex_lock(&e->mutex);
|
|
|
|
+ e->signalled = true;
|
|
|
|
+ vkd3d_cond_signal(&e->cond);
|
|
|
|
+ vkd3d_mutex_unlock(&e->mutex);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void vkd3d_null_event_wait(struct vkd3d_null_event *e)
|
|
|
|
+{
|
|
|
|
+ vkd3d_mutex_lock(&e->mutex);
|
|
|
|
+ while (!e->signalled)
|
|
|
|
+ vkd3d_cond_wait(&e->cond, &e->mutex);
|
|
|
|
+ e->signalled = false;
|
|
|
|
+ vkd3d_mutex_unlock(&e->mutex);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void vkd3d_null_event_cleanup(struct vkd3d_null_event *e)
|
|
|
|
+{
|
|
|
|
+ vkd3d_cond_destroy(&e->cond);
|
|
|
|
+ vkd3d_mutex_destroy(&e->mutex);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void vkd3d_null_event_init(struct vkd3d_null_event *e)
|
|
|
|
+{
|
|
|
|
+ vkd3d_mutex_init(&e->mutex);
|
|
|
|
+ vkd3d_cond_init(&e->cond);
|
|
|
|
+ e->signalled = false;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+HRESULT vkd3d_signal_null_event(HANDLE h)
|
|
|
|
+{
|
|
|
|
+ vkd3d_null_event_signal(h);
|
|
|
|
+
|
|
|
|
+ return S_OK;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
HRESULT vkd3d_queue_create(struct d3d12_device *device,
|
|
|
|
uint32_t family_index, const VkQueueFamilyProperties *properties, struct vkd3d_queue **queue)
|
|
|
|
{
|
|
|
|
@@ -753,8 +790,6 @@ static HRESULT d3d12_fence_add_vk_semaphore(struct d3d12_fence *fence, VkSemapho
|
|
|
|
|
|
|
|
static void d3d12_fence_signal_external_events_locked(struct d3d12_fence *fence)
|
|
|
|
{
|
|
|
|
- struct d3d12_device *device = fence->device;
|
|
|
|
- bool signal_null_event_cond = false;
|
|
|
|
unsigned int i, j;
|
|
|
|
|
|
|
|
for (i = 0, j = 0; i < fence->event_count; ++i)
|
|
|
|
@@ -763,28 +798,16 @@ static void d3d12_fence_signal_external_events_locked(struct d3d12_fence *fence)
|
|
|
|
|
|
|
|
if (current->value <= fence->value)
|
|
|
|
{
|
|
|
|
- if (current->event)
|
|
|
|
- {
|
|
|
|
- device->signal_event(current->event);
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- *current->latch = true;
|
|
|
|
- signal_null_event_cond = true;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- if (i != j)
|
|
|
|
- fence->events[j] = *current;
|
|
|
|
- ++j;
|
|
|
|
+ current->signal(current->event);
|
|
|
|
+ continue;
|
|
|
|
}
|
|
|
|
+
|
|
|
|
+ if (i != j)
|
|
|
|
+ fence->events[j] = *current;
|
|
|
|
+ ++j;
|
|
|
|
}
|
|
|
|
|
|
|
|
fence->event_count = j;
|
|
|
|
-
|
|
|
|
- if (signal_null_event_cond)
|
|
|
|
- vkd3d_cond_broadcast(&fence->null_event_cond);
|
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT d3d12_fence_signal(struct d3d12_fence *fence, uint64_t value, VkFence vk_fence, bool on_cpu)
|
|
|
|
@@ -978,7 +1001,6 @@ static void d3d12_fence_decref(struct d3d12_fence *fence)
|
|
|
|
vkd3d_free(fence->events);
|
|
|
|
vkd3d_free(fence->semaphores);
|
|
|
|
vkd3d_mutex_destroy(&fence->mutex);
|
|
|
|
- vkd3d_cond_destroy(&fence->null_event_cond);
|
|
|
|
vkd3d_free(fence);
|
|
|
|
|
|
|
|
d3d12_device_release(device);
|
|
|
|
@@ -1047,12 +1069,30 @@ static UINT64 STDMETHODCALLTYPE d3d12_fence_GetCompletedValue(ID3D12Fence1 *ifac
|
|
|
|
return completed_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
+bool d3d12_fence_add_waiting_event(struct d3d12_fence *fence,
|
|
|
|
+ HANDLE event, PFN_vkd3d_signal_event signal, uint64_t value)
|
|
|
|
+{
|
|
|
|
+ struct vkd3d_waiting_event *e;
|
|
|
|
+
|
|
|
|
+ if (!vkd3d_array_reserve((void **)&fence->events, &fence->events_size,
|
|
|
|
+ fence->event_count + 1, sizeof(*fence->events)))
|
|
|
|
+ return false;
|
|
|
|
+
|
|
|
|
+ e = &fence->events[fence->event_count++];
|
|
|
|
+ e->event = event;
|
|
|
|
+ e->signal = signal;
|
|
|
|
+ e->value = value;
|
|
|
|
+
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
static HRESULT STDMETHODCALLTYPE d3d12_fence_SetEventOnCompletion(ID3D12Fence1 *iface,
|
|
|
|
UINT64 value, HANDLE event)
|
|
|
|
{
|
|
|
|
struct d3d12_fence *fence = impl_from_ID3D12Fence1(iface);
|
|
|
|
+ struct vkd3d_null_event null_event;
|
|
|
|
+ PFN_vkd3d_signal_event signal;
|
|
|
|
unsigned int i;
|
|
|
|
- bool latch = false;
|
|
|
|
|
|
|
|
TRACE("iface %p, value %#"PRIx64", event %p.\n", iface, value, event);
|
|
|
|
|
|
|
|
@@ -1078,30 +1118,29 @@ static HRESULT STDMETHODCALLTYPE d3d12_fence_SetEventOnCompletion(ID3D12Fence1 *
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- if (!vkd3d_array_reserve((void **)&fence->events, &fence->events_size,
|
|
|
|
- fence->event_count + 1, sizeof(*fence->events)))
|
|
|
|
+ signal = fence->device->signal_event;
|
|
|
|
+ if (!event)
|
|
|
|
+ {
|
|
|
|
+ vkd3d_null_event_init(&null_event);
|
|
|
|
+ event = &null_event;
|
|
|
|
+ signal = vkd3d_signal_null_event;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!d3d12_fence_add_waiting_event(fence, event, signal, value))
|
|
|
|
{
|
|
|
|
WARN("Failed to add event.\n");
|
|
|
|
vkd3d_mutex_unlock(&fence->mutex);
|
|
|
|
return E_OUTOFMEMORY;
|
|
|
|
}
|
|
|
|
|
|
|
|
- fence->events[fence->event_count].value = value;
|
|
|
|
- fence->events[fence->event_count].event = event;
|
|
|
|
- fence->events[fence->event_count].latch = &latch;
|
|
|
|
- ++fence->event_count;
|
|
|
|
+ vkd3d_mutex_unlock(&fence->mutex);
|
|
|
|
|
|
|
|
- /* If event is NULL, we need to block until the fence value completes.
|
|
|
|
- * Implement this in a uniform way where we pretend we have a dummy event.
|
|
|
|
- * A NULL fence->events[].event means that we should set latch to true
|
|
|
|
- * and signal a condition variable instead of calling external signal_event callback. */
|
|
|
|
- if (!event)
|
|
|
|
+ if (event == &null_event)
|
|
|
|
{
|
|
|
|
- while (!latch)
|
|
|
|
- vkd3d_cond_wait(&fence->null_event_cond, &fence->mutex);
|
|
|
|
+ vkd3d_null_event_wait(&null_event);
|
|
|
|
+ vkd3d_null_event_cleanup(&null_event);
|
|
|
|
}
|
|
|
|
|
|
|
|
- vkd3d_mutex_unlock(&fence->mutex);
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
@@ -1159,7 +1198,7 @@ static const struct ID3D12Fence1Vtbl d3d12_fence_vtbl =
|
|
|
|
d3d12_fence_GetCreationFlags,
|
|
|
|
};
|
|
|
|
|
|
|
|
-static struct d3d12_fence *unsafe_impl_from_ID3D12Fence(ID3D12Fence *iface)
|
|
|
|
+struct d3d12_fence *unsafe_impl_from_ID3D12Fence(ID3D12Fence *iface)
|
|
|
|
{
|
|
|
|
ID3D12Fence1 *iface1;
|
|
|
|
|
|
|
|
@@ -1185,8 +1224,6 @@ static HRESULT d3d12_fence_init(struct d3d12_fence *fence, struct d3d12_device *
|
|
|
|
|
|
|
|
vkd3d_mutex_init(&fence->mutex);
|
|
|
|
|
|
|
|
- vkd3d_cond_init(&fence->null_event_cond);
|
|
|
|
-
|
|
|
|
if ((fence->flags = flags))
|
|
|
|
FIXME("Ignoring flags %#x.\n", flags);
|
|
|
|
|
|
|
|
@@ -1201,8 +1238,8 @@ static HRESULT d3d12_fence_init(struct d3d12_fence *fence, struct d3d12_device *
|
|
|
|
&fence->timeline_semaphore)) < 0)
|
|
|
|
{
|
|
|
|
WARN("Failed to create timeline semaphore, vr %d.\n", vr);
|
|
|
|
- hr = hresult_from_vk_result(vr);
|
|
|
|
- goto fail_destroy_null_cond;
|
|
|
|
+ vkd3d_mutex_destroy(&fence->mutex);
|
|
|
|
+ return hresult_from_vk_result(vr);
|
|
|
|
}
|
|
|
|
|
|
|
|
fence->semaphores = NULL;
|
|
|
|
@@ -1213,20 +1250,14 @@ static HRESULT d3d12_fence_init(struct d3d12_fence *fence, struct d3d12_device *
|
|
|
|
|
|
|
|
if (FAILED(hr = vkd3d_private_store_init(&fence->private_store)))
|
|
|
|
{
|
|
|
|
- goto fail_destroy_timeline_semaphore;
|
|
|
|
+ VK_CALL(vkDestroySemaphore(device->vk_device, fence->timeline_semaphore, NULL));
|
|
|
|
+ vkd3d_mutex_destroy(&fence->mutex);
|
|
|
|
+ return hr;
|
|
|
|
}
|
|
|
|
|
|
|
|
d3d12_device_add_ref(fence->device = device);
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
-
|
|
|
|
-fail_destroy_timeline_semaphore:
|
|
|
|
- VK_CALL(vkDestroySemaphore(device->vk_device, fence->timeline_semaphore, NULL));
|
|
|
|
-fail_destroy_null_cond:
|
|
|
|
- vkd3d_cond_destroy(&fence->null_event_cond);
|
|
|
|
- vkd3d_mutex_destroy(&fence->mutex);
|
|
|
|
-
|
|
|
|
- return hr;
|
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT d3d12_fence_create(struct d3d12_device *device,
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d/device.c b/libs/vkd3d/libs/vkd3d/device.c
|
|
|
|
index 15affcee9cb..b2636fd5585 100644
|
|
|
|
--- a/libs/vkd3d/libs/vkd3d/device.c
|
|
|
|
+++ b/libs/vkd3d/libs/vkd3d/device.c
|
|
|
|
@@ -4901,14 +4901,131 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePipelineLibrary(ID3D12Device
|
|
|
|
return DXGI_ERROR_UNSUPPORTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
+struct waiting_event_semaphore
|
|
|
|
+{
|
|
|
|
+ HANDLE event;
|
|
|
|
+ PFN_vkd3d_signal_event signal;
|
|
|
|
+ uint32_t value;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static HRESULT waiting_event_semaphore_signal(HANDLE h)
|
|
|
|
+{
|
|
|
|
+ struct waiting_event_semaphore *s = h;
|
|
|
|
+
|
|
|
|
+ if (vkd3d_atomic_decrement_u32(&s->value))
|
|
|
|
+ return S_OK;
|
|
|
|
+
|
|
|
|
+ if (s->event)
|
|
|
|
+ s->signal(s->event);
|
|
|
|
+ vkd3d_free(s);
|
|
|
|
+
|
|
|
|
+ return S_OK;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static HRESULT waiting_event_semaphore_signal_first(HANDLE h)
|
|
|
|
+{
|
|
|
|
+ struct waiting_event_semaphore *s = h;
|
|
|
|
+ HANDLE event;
|
|
|
|
+
|
|
|
|
+ if ((event = vkd3d_atomic_exchange_ptr(&s->event, NULL)))
|
|
|
|
+ s->signal(event);
|
|
|
|
+
|
|
|
|
+ return waiting_event_semaphore_signal(h);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static bool waiting_event_semaphore_cancel(struct waiting_event_semaphore *s)
|
|
|
|
+{
|
|
|
|
+ bool ret;
|
|
|
|
+
|
|
|
|
+ ret = !vkd3d_atomic_exchange_ptr(&s->event, NULL);
|
|
|
|
+ waiting_event_semaphore_signal(s);
|
|
|
|
+
|
|
|
|
+ return ret;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
static HRESULT STDMETHODCALLTYPE d3d12_device_SetEventOnMultipleFenceCompletion(ID3D12Device9 *iface,
|
|
|
|
ID3D12Fence *const *fences, const UINT64 *values, UINT fence_count,
|
|
|
|
D3D12_MULTIPLE_FENCE_WAIT_FLAGS flags, HANDLE event)
|
|
|
|
{
|
|
|
|
- FIXME("iface %p, fences %p, values %p, fence_count %u, flags %#x, event %p stub!\n",
|
|
|
|
+ struct d3d12_device *device = impl_from_ID3D12Device9(iface);
|
|
|
|
+ struct vkd3d_null_event null_event;
|
|
|
|
+ struct waiting_event_semaphore *s;
|
|
|
|
+ PFN_vkd3d_signal_event signal;
|
|
|
|
+ struct d3d12_fence *fence;
|
|
|
|
+ HRESULT hr = S_OK;
|
|
|
|
+ unsigned int i;
|
|
|
|
+
|
|
|
|
+ TRACE("iface %p, fences %p, values %p, fence_count %u, flags %#x, event %p.\n",
|
|
|
|
iface, fences, values, fence_count, flags, event);
|
|
|
|
|
|
|
|
- return E_NOTIMPL;
|
|
|
|
+ if (flags & ~D3D12_MULTIPLE_FENCE_WAIT_FLAG_ANY)
|
|
|
|
+ {
|
|
|
|
+ FIXME("Unhandled flags %#x.\n", flags & ~D3D12_MULTIPLE_FENCE_WAIT_FLAG_ANY);
|
|
|
|
+ return E_NOTIMPL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!fence_count)
|
|
|
|
+ return E_INVALIDARG;
|
|
|
|
+
|
|
|
|
+ if (fence_count == 1)
|
|
|
|
+ return ID3D12Fence_SetEventOnCompletion(fences[0], values[0], event);
|
|
|
|
+
|
|
|
|
+ if (!(s = vkd3d_malloc(sizeof(*s))))
|
|
|
|
+ {
|
|
|
|
+ WARN("Failed to allocate semaphore memory.\n");
|
|
|
|
+ return E_OUTOFMEMORY;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ signal = device->signal_event;
|
|
|
|
+ if (!event)
|
|
|
|
+ {
|
|
|
|
+ vkd3d_null_event_init(&null_event);
|
|
|
|
+ event = &null_event;
|
|
|
|
+ signal = vkd3d_signal_null_event;
|
|
|
|
+ }
|
|
|
|
+ s->event = event;
|
|
|
|
+ s->signal = signal;
|
|
|
|
+ s->value = fence_count;
|
|
|
|
+
|
|
|
|
+ if (flags & D3D12_MULTIPLE_FENCE_WAIT_FLAG_ANY)
|
|
|
|
+ signal = waiting_event_semaphore_signal_first;
|
|
|
|
+ else
|
|
|
|
+ signal = waiting_event_semaphore_signal;
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < fence_count; ++i)
|
|
|
|
+ {
|
|
|
|
+ fence = unsafe_impl_from_ID3D12Fence(fences[i]);
|
|
|
|
+
|
|
|
|
+ vkd3d_mutex_lock(&fence->mutex);
|
|
|
|
+
|
|
|
|
+ if (values[i] <= fence->value)
|
|
|
|
+ {
|
|
|
|
+ vkd3d_mutex_unlock(&fence->mutex);
|
|
|
|
+ signal(s);
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!d3d12_fence_add_waiting_event(fence, s, signal, values[i]))
|
|
|
|
+ {
|
|
|
|
+ WARN("Failed to add event.\n");
|
|
|
|
+ /* If the event was already signalled, we don't need to fail here.
|
|
|
|
+ * Note that cancel() will also return "true" for any subsequent
|
|
|
|
+ * cancel() calls; that's fine, because we already failed in that
|
|
|
|
+ * case. */
|
|
|
|
+ if (!waiting_event_semaphore_cancel(s))
|
|
|
|
+ hr = E_OUTOFMEMORY;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ vkd3d_mutex_unlock(&fence->mutex);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (event == &null_event)
|
|
|
|
+ {
|
|
|
|
+ vkd3d_null_event_wait(&null_event);
|
|
|
|
+ vkd3d_null_event_cleanup(&null_event);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return hr;
|
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT STDMETHODCALLTYPE d3d12_device_SetResidencyPriority(ID3D12Device9 *iface,
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/libs/vkd3d/vkd3d_private.h
|
|
|
|
index e0e44248053..7e54738b19e 100644
|
|
|
|
--- a/libs/vkd3d/libs/vkd3d/vkd3d_private.h
|
|
|
|
+++ b/libs/vkd3d/libs/vkd3d/vkd3d_private.h
|
|
|
|
@@ -357,6 +357,18 @@ HRESULT vkd3d_set_private_data(struct vkd3d_private_store *store,
|
|
|
|
const GUID *tag, unsigned int data_size, const void *data);
|
|
|
|
HRESULT vkd3d_set_private_data_interface(struct vkd3d_private_store *store, const GUID *tag, const IUnknown *object);
|
|
|
|
|
|
|
|
+struct vkd3d_null_event
|
|
|
|
+{
|
|
|
|
+ struct vkd3d_mutex mutex;
|
|
|
|
+ struct vkd3d_cond cond;
|
|
|
|
+ bool signalled;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+void vkd3d_null_event_cleanup(struct vkd3d_null_event *e);
|
|
|
|
+void vkd3d_null_event_init(struct vkd3d_null_event *e);
|
|
|
|
+void vkd3d_null_event_wait(struct vkd3d_null_event *e);
|
|
|
|
+HRESULT vkd3d_signal_null_event(HANDLE h);
|
|
|
|
+
|
|
|
|
struct vkd3d_signaled_semaphore
|
|
|
|
{
|
|
|
|
uint64_t value;
|
|
|
|
@@ -385,13 +397,12 @@ struct d3d12_fence
|
|
|
|
uint64_t value;
|
|
|
|
uint64_t max_pending_value;
|
|
|
|
struct vkd3d_mutex mutex;
|
|
|
|
- struct vkd3d_cond null_event_cond;
|
|
|
|
|
|
|
|
struct vkd3d_waiting_event
|
|
|
|
{
|
|
|
|
- uint64_t value;
|
|
|
|
HANDLE event;
|
|
|
|
- bool *latch;
|
|
|
|
+ PFN_vkd3d_signal_event signal;
|
|
|
|
+ uint64_t value;
|
|
|
|
} *events;
|
|
|
|
size_t events_size;
|
|
|
|
size_t event_count;
|
|
|
|
@@ -411,8 +422,11 @@ struct d3d12_fence
|
|
|
|
struct vkd3d_private_store private_store;
|
|
|
|
};
|
|
|
|
|
|
|
|
+bool d3d12_fence_add_waiting_event(struct d3d12_fence *fence,
|
|
|
|
+ HANDLE event, PFN_vkd3d_signal_event signal, uint64_t value);
|
|
|
|
HRESULT d3d12_fence_create(struct d3d12_device *device, uint64_t initial_value,
|
|
|
|
D3D12_FENCE_FLAGS flags, struct d3d12_fence **fence);
|
|
|
|
+struct d3d12_fence *unsafe_impl_from_ID3D12Fence(ID3D12Fence *iface);
|
|
|
|
|
|
|
|
VkResult vkd3d_create_timeline_semaphore(const struct d3d12_device *device, uint64_t initial_value,
|
|
|
|
VkSemaphore *timeline_semaphore);
|
|
|
|
--
|
|
|
|
2.47.2
|
|
|
|
|