Updated vkd3d-latest patchset

Squashed for release.
This commit is contained in:
Alistair Leslie-Hughes 2024-05-18 13:09:40 +10:00
parent 05c875caa5
commit a78e9f3998
8 changed files with 8108 additions and 10434 deletions

View File

@ -1,892 +0,0 @@
From ddfe189d39a3dd3f1c99773c57bb0650e39e8354 Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Wed, 24 Apr 2024 09:05:20 +1000
Subject: [PATCH] Updated vkd3d to 46fca3f9f4a9b47b32e9dfbacda0f3d19536c02c.
---
libs/vkd3d/include/private/vkd3d_common.h | 2 +
libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 12 +-
libs/vkd3d/libs/vkd3d-shader/dxil.c | 2 +-
libs/vkd3d/libs/vkd3d-shader/fx.c | 77 +++++++----
libs/vkd3d/libs/vkd3d-shader/hlsl.c | 44 +++++--
libs/vkd3d/libs/vkd3d-shader/hlsl.h | 12 +-
libs/vkd3d/libs/vkd3d-shader/hlsl.y | 32 +++--
libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 5 +
libs/vkd3d/libs/vkd3d-shader/ir.c | 137 ++++++++++++++++----
libs/vkd3d/libs/vkd3d-shader/tpf.c | 5 +
10 files changed, 248 insertions(+), 80 deletions(-)
diff --git a/libs/vkd3d/include/private/vkd3d_common.h b/libs/vkd3d/include/private/vkd3d_common.h
index 1da73bcfb2e..b0e9230dab6 100644
--- a/libs/vkd3d/include/private/vkd3d_common.h
+++ b/libs/vkd3d/include/private/vkd3d_common.h
@@ -340,6 +340,8 @@ static inline int vkd3d_u32_compare(uint32_t x, uint32_t y)
return (x > y) - (x < y);
}
+#define VKD3D_BITMAP_SIZE(x) (((x) + 0x1f) >> 5)
+
static inline bool bitmap_clear(uint32_t *map, unsigned int idx)
{
return map[idx >> 5] &= ~(1u << (idx & 0x1f));
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
index ace7694a59e..55d9ecf707d 100644
--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
@@ -216,7 +216,7 @@ struct vkd3d_shader_sm1_parser
struct vkd3d_shader_parser p;
#define MAX_CONSTANT_COUNT 8192
- uint32_t constant_def_mask[3][MAX_CONSTANT_COUNT / 32];
+ uint32_t constant_def_mask[3][VKD3D_BITMAP_SIZE(MAX_CONSTANT_COUNT)];
};
/* This table is not order or position dependent. */
@@ -1517,6 +1517,11 @@ D3DXPARAMETER_CLASS hlsl_sm1_class(const struct hlsl_type *type)
case HLSL_CLASS_STRING:
case HLSL_CLASS_TEXTURE:
return D3DXPC_OBJECT;
+ case HLSL_CLASS_DEPTH_STENCIL_VIEW:
+ case HLSL_CLASS_EFFECT_GROUP:
+ case HLSL_CLASS_PASS:
+ case HLSL_CLASS_RENDER_TARGET_VIEW:
+ case HLSL_CLASS_TECHNIQUE:
case HLSL_CLASS_UAV:
case HLSL_CLASS_VOID:
break;
@@ -1614,6 +1619,11 @@ D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type)
case HLSL_CLASS_STRING:
return D3DXPT_STRING;
+ case HLSL_CLASS_DEPTH_STENCIL_VIEW:
+ case HLSL_CLASS_EFFECT_GROUP:
+ case HLSL_CLASS_PASS:
+ case HLSL_CLASS_RENDER_TARGET_VIEW:
+ case HLSL_CLASS_TECHNIQUE:
case HLSL_CLASS_UAV:
case HLSL_CLASS_VOID:
break;
diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c
index d07d5adee70..6a1fb6bddb7 100644
--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c
+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c
@@ -805,7 +805,7 @@ struct sm6_parser
struct vkd3d_shader_dst_param *output_params;
struct vkd3d_shader_dst_param *input_params;
struct vkd3d_shader_dst_param *patch_constant_params;
- uint32_t io_regs_declared[(VKD3DSPR_COUNT + 0x1f) / 0x20];
+ uint32_t io_regs_declared[VKD3D_BITMAP_SIZE(VKD3DSPR_COUNT)];
struct sm6_function *functions;
size_t function_count;
diff --git a/libs/vkd3d/libs/vkd3d-shader/fx.c b/libs/vkd3d/libs/vkd3d-shader/fx.c
index 98443797543..168378e6b42 100644
--- a/libs/vkd3d/libs/vkd3d-shader/fx.c
+++ b/libs/vkd3d/libs/vkd3d-shader/fx.c
@@ -222,7 +222,7 @@ static bool technique_matches_version(const struct hlsl_ir_var *var, const struc
{
const struct hlsl_type *type = var->data_type;
- if (type->base_type != HLSL_TYPE_TECHNIQUE)
+ if (type->class != HLSL_CLASS_TECHNIQUE)
return false;
return type->e.version >= fx->min_technique_version && type->e.version <= fx->max_technique_version;
@@ -353,8 +353,6 @@ static const char * get_fx_4_type_name(const struct hlsl_type *type)
{
[HLSL_TYPE_PIXELSHADER] = "PixelShader",
[HLSL_TYPE_VERTEXSHADER] = "VertexShader",
- [HLSL_TYPE_RENDERTARGETVIEW] = "RenderTargetView",
- [HLSL_TYPE_DEPTHSTENCILVIEW] = "DepthStencilView",
};
static const char * const texture_type_names[] =
{
@@ -380,19 +378,30 @@ static const char * get_fx_4_type_name(const struct hlsl_type *type)
[HLSL_SAMPLER_DIM_STRUCTURED_BUFFER] = "RWStructuredBuffer",
};
- if (type->class == HLSL_CLASS_TEXTURE)
- return texture_type_names[type->sampler_dim];
+ switch (type->class)
+ {
+ case HLSL_CLASS_TEXTURE:
+ return texture_type_names[type->sampler_dim];
- if (type->class == HLSL_CLASS_UAV)
- return uav_type_names[type->sampler_dim];
+ case HLSL_CLASS_UAV:
+ return uav_type_names[type->sampler_dim];
+
+ case HLSL_CLASS_DEPTH_STENCIL_VIEW:
+ return "DepthStencilView";
+
+ case HLSL_CLASS_RENDER_TARGET_VIEW:
+ return "RenderTargetView";
+
+ case HLSL_CLASS_OBJECT:
+ switch (type->base_type)
+ {
+ case HLSL_TYPE_PIXELSHADER:
+ case HLSL_TYPE_VERTEXSHADER:
+ return object_type_names[type->base_type];
+ default:
+ return type->name;
+ }
- switch (type->base_type)
- {
- case HLSL_TYPE_PIXELSHADER:
- case HLSL_TYPE_VERTEXSHADER:
- case HLSL_TYPE_RENDERTARGETVIEW:
- case HLSL_TYPE_DEPTHSTENCILVIEW:
- return object_type_names[type->base_type];
default:
return type->name;
}
@@ -426,7 +435,9 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co
put_u32_unaligned(buffer, 1);
break;
+ case HLSL_CLASS_DEPTH_STENCIL_VIEW:
case HLSL_CLASS_OBJECT:
+ case HLSL_CLASS_RENDER_TARGET_VIEW:
case HLSL_CLASS_TEXTURE:
case HLSL_CLASS_UAV:
put_u32_unaligned(buffer, 2);
@@ -437,6 +448,9 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co
break;
case HLSL_CLASS_ARRAY:
+ case HLSL_CLASS_EFFECT_GROUP:
+ case HLSL_CLASS_PASS:
+ case HLSL_CLASS_TECHNIQUE:
vkd3d_unreachable();
case HLSL_CLASS_SAMPLER:
@@ -510,21 +524,25 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co
put_u32_unaligned(buffer, uav_type[type->sampler_dim]);
}
+ else if (type->class == HLSL_CLASS_DEPTH_STENCIL_VIEW)
+ {
+ put_u32_unaligned(buffer, 20);
+ }
+ else if (type->class == HLSL_CLASS_RENDER_TARGET_VIEW)
+ {
+ put_u32_unaligned(buffer, 19);
+ }
else if (type->class == HLSL_CLASS_OBJECT)
{
static const uint32_t object_type[] =
{
[HLSL_TYPE_PIXELSHADER] = 5,
[HLSL_TYPE_VERTEXSHADER] = 6,
- [HLSL_TYPE_RENDERTARGETVIEW] = 19,
- [HLSL_TYPE_DEPTHSTENCILVIEW] = 20,
};
switch (type->base_type)
{
- case HLSL_TYPE_DEPTHSTENCILVIEW:
case HLSL_TYPE_PIXELSHADER:
- case HLSL_TYPE_RENDERTARGETVIEW:
case HLSL_TYPE_VERTEXSHADER:
put_u32_unaligned(buffer, object_type[type->base_type]);
break;
@@ -533,11 +551,17 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co
return 0;
}
}
- else /* Numeric type */
+ else if (hlsl_is_numeric_type(type))
{
numeric_desc = get_fx_4_numeric_type_description(type, fx);
put_u32_unaligned(buffer, numeric_desc);
}
+ else
+ {
+ FIXME("Type %u is not supported.\n", type->class);
+ set_status(fx, VKD3D_ERROR_NOT_IMPLEMENTED);
+ return 0;
+ }
return offset;
}
@@ -618,7 +642,7 @@ static void write_groups(struct fx_write_context *fx)
{
const struct hlsl_type *type = var->data_type;
- if (type->base_type == HLSL_TYPE_EFFECT_GROUP)
+ if (type->class == HLSL_CLASS_EFFECT_GROUP)
write_group(var, fx);
}
}
@@ -831,9 +855,17 @@ static bool is_type_supported_fx_2(struct hlsl_ctx *ctx, const struct hlsl_type
hlsl_fixme(ctx, loc, "Write fx 2.0 parameter class %#x.", type->class);
return false;
+ case HLSL_CLASS_DEPTH_STENCIL_VIEW:
case HLSL_CLASS_UAV:
+ case HLSL_CLASS_RENDER_TARGET_VIEW:
case HLSL_CLASS_VOID:
return false;
+
+ case HLSL_CLASS_EFFECT_GROUP:
+ case HLSL_CLASS_PASS:
+ case HLSL_CLASS_TECHNIQUE:
+ /* This cannot appear as an extern variable. */
+ break;
}
vkd3d_unreachable();
@@ -1011,6 +1043,7 @@ static void write_fx_4_object_variable(struct hlsl_ir_var *var, struct fx_write_
/* Initializer */
switch (type->class)
{
+ case HLSL_CLASS_RENDER_TARGET_VIEW:
case HLSL_CLASS_TEXTURE:
case HLSL_CLASS_UAV:
break;
@@ -1018,8 +1051,6 @@ static void write_fx_4_object_variable(struct hlsl_ir_var *var, struct fx_write_
case HLSL_CLASS_OBJECT:
switch (type->base_type)
{
- case HLSL_TYPE_RENDERTARGETVIEW:
- break;
case HLSL_TYPE_PIXELSHADER:
case HLSL_TYPE_VERTEXSHADER:
/* FIXME: write shader blobs, once parser support works. */
@@ -1118,6 +1149,7 @@ static bool is_object_variable(const struct hlsl_ir_var *var)
switch (type->class)
{
+ case HLSL_CLASS_RENDER_TARGET_VIEW:
case HLSL_CLASS_SAMPLER:
case HLSL_CLASS_TEXTURE:
case HLSL_CLASS_UAV:
@@ -1128,7 +1160,6 @@ static bool is_object_variable(const struct hlsl_ir_var *var)
{
case HLSL_TYPE_PIXELSHADER:
case HLSL_TYPE_VERTEXSHADER:
- case HLSL_TYPE_RENDERTARGETVIEW:
return true;
default:
return false;
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c
index 5dd80ff1c3f..4fc1493bdce 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c
@@ -363,8 +363,13 @@ static void hlsl_type_calculate_reg_size(struct hlsl_ctx *ctx, struct hlsl_type
type->reg_size[HLSL_REGSET_UAVS] = 1;
break;
+ case HLSL_CLASS_DEPTH_STENCIL_VIEW:
+ case HLSL_CLASS_EFFECT_GROUP:
case HLSL_CLASS_OBJECT:
+ case HLSL_CLASS_PASS:
+ case HLSL_CLASS_RENDER_TARGET_VIEW:
case HLSL_CLASS_STRING:
+ case HLSL_CLASS_TECHNIQUE:
case HLSL_CLASS_VOID:
break;
}
@@ -425,10 +430,12 @@ static bool type_is_single_component(const struct hlsl_type *type)
{
switch (type->class)
{
+ case HLSL_CLASS_DEPTH_STENCIL_VIEW:
case HLSL_CLASS_SCALAR:
case HLSL_CLASS_OBJECT:
case HLSL_CLASS_SAMPLER:
case HLSL_CLASS_STRING:
+ case HLSL_CLASS_RENDER_TARGET_VIEW:
case HLSL_CLASS_TEXTURE:
case HLSL_CLASS_UAV:
return true;
@@ -439,6 +446,9 @@ static bool type_is_single_component(const struct hlsl_type *type)
case HLSL_CLASS_ARRAY:
return false;
+ case HLSL_CLASS_EFFECT_GROUP:
+ case HLSL_CLASS_PASS:
+ case HLSL_CLASS_TECHNIQUE:
case HLSL_CLASS_VOID:
break;
}
@@ -561,7 +571,9 @@ unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_ty
}
break;
+ case HLSL_CLASS_DEPTH_STENCIL_VIEW:
case HLSL_CLASS_OBJECT:
+ case HLSL_CLASS_RENDER_TARGET_VIEW:
case HLSL_CLASS_SAMPLER:
case HLSL_CLASS_STRING:
case HLSL_CLASS_TEXTURE:
@@ -569,6 +581,9 @@ unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_ty
assert(idx == 0);
break;
+ case HLSL_CLASS_EFFECT_GROUP:
+ case HLSL_CLASS_PASS:
+ case HLSL_CLASS_TECHNIQUE:
case HLSL_CLASS_VOID:
vkd3d_unreachable();
}
@@ -934,13 +949,18 @@ unsigned int hlsl_type_component_count(const struct hlsl_type *type)
case HLSL_CLASS_ARRAY:
return hlsl_type_component_count(type->e.array.type) * type->e.array.elements_count;
+ case HLSL_CLASS_DEPTH_STENCIL_VIEW:
case HLSL_CLASS_OBJECT:
+ case HLSL_CLASS_RENDER_TARGET_VIEW:
case HLSL_CLASS_SAMPLER:
case HLSL_CLASS_STRING:
case HLSL_CLASS_TEXTURE:
case HLSL_CLASS_UAV:
return 1;
+ case HLSL_CLASS_EFFECT_GROUP:
+ case HLSL_CLASS_PASS:
+ case HLSL_CLASS_TECHNIQUE:
case HLSL_CLASS_VOID:
break;
}
@@ -997,9 +1017,9 @@ bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2
if (t1->class == HLSL_CLASS_ARRAY)
return t1->e.array.elements_count == t2->e.array.elements_count
&& hlsl_types_are_equal(t1->e.array.type, t2->e.array.type);
- if (t1->class == HLSL_CLASS_OBJECT)
+ if (t1->class == HLSL_CLASS_TECHNIQUE)
{
- if (t1->base_type == HLSL_TYPE_TECHNIQUE && t1->e.version != t2->e.version)
+ if (t1->e.version != t2->e.version)
return false;
}
@@ -1089,9 +1109,8 @@ struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old,
type->e.resource.format = old->e.resource.format;
break;
- case HLSL_CLASS_OBJECT:
- if (type->base_type == HLSL_TYPE_TECHNIQUE)
- type->e.version = old->e.version;
+ case HLSL_CLASS_TECHNIQUE:
+ type->e.version = old->e.version;
break;
default:
@@ -2355,9 +2374,14 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru
}
return string;
+ case HLSL_CLASS_DEPTH_STENCIL_VIEW:
+ case HLSL_CLASS_EFFECT_GROUP:
case HLSL_CLASS_OBJECT:
+ case HLSL_CLASS_PASS:
+ case HLSL_CLASS_RENDER_TARGET_VIEW:
case HLSL_CLASS_SAMPLER:
case HLSL_CLASS_STRING:
+ case HLSL_CLASS_TECHNIQUE:
case HLSL_CLASS_VOID:
break;
}
@@ -3533,12 +3557,8 @@ static void declare_predefined_types(struct hlsl_ctx *ctx)
{"dword", HLSL_CLASS_SCALAR, HLSL_TYPE_UINT, 1, 1},
{"vector", HLSL_CLASS_VECTOR, HLSL_TYPE_FLOAT, 4, 1},
{"matrix", HLSL_CLASS_MATRIX, HLSL_TYPE_FLOAT, 4, 4},
- {"fxgroup", HLSL_CLASS_OBJECT, HLSL_TYPE_EFFECT_GROUP, 1, 1},
- {"pass", HLSL_CLASS_OBJECT, HLSL_TYPE_PASS, 1, 1},
{"pixelshader", HLSL_CLASS_OBJECT, HLSL_TYPE_PIXELSHADER, 1, 1},
{"vertexshader", HLSL_CLASS_OBJECT, HLSL_TYPE_VERTEXSHADER, 1, 1},
- {"RenderTargetView",HLSL_CLASS_OBJECT, HLSL_TYPE_RENDERTARGETVIEW, 1, 1},
- {"DepthStencilView",HLSL_CLASS_OBJECT, HLSL_TYPE_DEPTHSTENCILVIEW, 1, 1},
};
static const struct
@@ -3650,6 +3670,10 @@ static void declare_predefined_types(struct hlsl_ctx *ctx)
}
ctx->builtin_types.Void = hlsl_new_simple_type(ctx, "void", HLSL_CLASS_VOID);
+ hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "DepthStencilView", HLSL_CLASS_DEPTH_STENCIL_VIEW));
+ hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "fxgroup", HLSL_CLASS_EFFECT_GROUP));
+ hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "pass", HLSL_CLASS_PASS));
+ hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "RenderTargetView", HLSL_CLASS_RENDER_TARGET_VIEW));
hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "STRING", HLSL_CLASS_STRING));
hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "texture", HLSL_CLASS_TEXTURE));
@@ -3662,7 +3686,7 @@ static void declare_predefined_types(struct hlsl_ctx *ctx)
for (i = 0; i < ARRAY_SIZE(technique_types); ++i)
{
- type = hlsl_new_type(ctx, technique_types[i].name, HLSL_CLASS_OBJECT, HLSL_TYPE_TECHNIQUE, 1, 1);
+ type = hlsl_new_simple_type(ctx, technique_types[i].name, HLSL_CLASS_TECHNIQUE);
type->e.version = technique_types[i].version;
hlsl_scope_add_type(ctx->globals, type);
}
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
index 5e3010c4353..1e5f0805152 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
@@ -79,8 +79,13 @@ enum hlsl_type_class
HLSL_CLASS_STRUCT,
HLSL_CLASS_ARRAY,
HLSL_CLASS_OBJECT,
+ HLSL_CLASS_DEPTH_STENCIL_VIEW,
+ HLSL_CLASS_EFFECT_GROUP,
+ HLSL_CLASS_PASS,
+ HLSL_CLASS_RENDER_TARGET_VIEW,
HLSL_CLASS_SAMPLER,
HLSL_CLASS_STRING,
+ HLSL_CLASS_TECHNIQUE,
HLSL_CLASS_TEXTURE,
HLSL_CLASS_UAV,
HLSL_CLASS_VOID,
@@ -97,11 +102,6 @@ enum hlsl_base_type
HLSL_TYPE_LAST_SCALAR = HLSL_TYPE_BOOL,
HLSL_TYPE_PIXELSHADER,
HLSL_TYPE_VERTEXSHADER,
- HLSL_TYPE_PASS,
- HLSL_TYPE_RENDERTARGETVIEW,
- HLSL_TYPE_DEPTHSTENCILVIEW,
- HLSL_TYPE_TECHNIQUE,
- HLSL_TYPE_EFFECT_GROUP,
};
enum hlsl_sampler_dim
@@ -145,8 +145,6 @@ struct hlsl_type
enum hlsl_type_class class;
/* If class is <= HLSL_CLASS_LAST_NUMERIC, then base_type is <= HLSL_TYPE_LAST_SCALAR.
* If class is HLSL_CLASS_OBJECT, then base_type is > HLSL_TYPE_LAST_SCALAR.
- * If class is HLSL_CLASS_OBJECT and base_type is HLSL_TYPE_TECHNIQUE, additional version
- * field is used to distinguish between technique types.
* Otherwise, base_type is not used. */
enum hlsl_base_type base_type;
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
index f99f322d8d1..0eed15c5a91 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
@@ -656,6 +656,16 @@ static unsigned int initializer_size(const struct parse_initializer *initializer
return count;
}
+static void cleanup_parse_attribute_list(struct parse_attribute_list *attr_list)
+{
+ unsigned int i = 0;
+
+ assert(attr_list);
+ for (i = 0; i < attr_list->count; ++i)
+ hlsl_free_attribute((struct hlsl_attribute *) attr_list->attrs[i]);
+ vkd3d_free(attr_list->attrs);
+}
+
static void free_parse_initializer(struct parse_initializer *initializer)
{
destroy_block(initializer->instrs);
@@ -6033,11 +6043,7 @@ attribute_list:
$$ = $1;
if (!(new_array = vkd3d_realloc($$.attrs, ($$.count + 1) * sizeof(*$$.attrs))))
{
- unsigned int i;
-
- for (i = 0; i < $$.count; ++i)
- hlsl_free_attribute((void *)$$.attrs[i]);
- vkd3d_free($$.attrs);
+ cleanup_parse_attribute_list(&$$);
YYABORT;
}
$$.attrs = new_array;
@@ -6243,11 +6249,7 @@ func_prototype:
}
else
{
- unsigned int i;
-
- for (i = 0; i < $1.count; ++i)
- hlsl_free_attribute((void *)$1.attrs[i]);
- vkd3d_free($1.attrs);
+ cleanup_parse_attribute_list(&$1);
}
$$ = $2;
}
@@ -7358,6 +7360,7 @@ selection_statement:
{
destroy_block($6.then_block);
destroy_block($6.else_block);
+ cleanup_parse_attribute_list(&$1);
YYABORT;
}
@@ -7365,10 +7368,12 @@ selection_statement:
{
destroy_block($6.then_block);
destroy_block($6.else_block);
+ cleanup_parse_attribute_list(&$1);
YYABORT;
}
destroy_block($6.then_block);
destroy_block($6.else_block);
+ cleanup_parse_attribute_list(&$1);
$$ = $4;
hlsl_block_add_instr($$, instr);
@@ -7391,21 +7396,25 @@ loop_statement:
{
$$ = create_loop(ctx, LOOP_WHILE, &$1, NULL, $5, NULL, $7, &@3);
hlsl_pop_scope(ctx);
+ cleanup_parse_attribute_list(&$1);
}
| attribute_list_optional loop_scope_start KW_DO statement KW_WHILE '(' expr ')' ';'
{
$$ = create_loop(ctx, LOOP_DO_WHILE, &$1, NULL, $7, NULL, $4, &@3);
hlsl_pop_scope(ctx);
+ cleanup_parse_attribute_list(&$1);
}
| attribute_list_optional loop_scope_start KW_FOR '(' expr_statement expr_statement expr_optional ')' statement
{
$$ = create_loop(ctx, LOOP_FOR, &$1, $5, $6, $7, $9, &@3);
hlsl_pop_scope(ctx);
+ cleanup_parse_attribute_list(&$1);
}
| attribute_list_optional loop_scope_start KW_FOR '(' declaration expr_statement expr_optional ')' statement
{
$$ = create_loop(ctx, LOOP_FOR, &$1, $5, $6, $7, $9, &@3);
hlsl_pop_scope(ctx);
+ cleanup_parse_attribute_list(&$1);
}
switch_statement:
@@ -7418,6 +7427,7 @@ switch_statement:
{
destroy_switch_cases($8);
destroy_block($5);
+ cleanup_parse_attribute_list(&$1);
YYABORT;
}
@@ -7428,6 +7438,7 @@ switch_statement:
if (!s)
{
destroy_block($5);
+ cleanup_parse_attribute_list(&$1);
YYABORT;
}
@@ -7435,6 +7446,7 @@ switch_statement:
hlsl_block_add_instr($$, s);
hlsl_pop_scope(ctx);
+ cleanup_parse_attribute_list(&$1);
}
switch_case:
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
index f6cccfe8bea..a6d6b336b40 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
@@ -1638,7 +1638,12 @@ static bool copy_propagation_transform_load(struct hlsl_ctx *ctx,
* matrices yet. */
return false;
+ case HLSL_CLASS_DEPTH_STENCIL_VIEW:
+ case HLSL_CLASS_EFFECT_GROUP:
+ case HLSL_CLASS_PASS:
+ case HLSL_CLASS_RENDER_TARGET_VIEW:
case HLSL_CLASS_STRING:
+ case HLSL_CLASS_TECHNIQUE:
case HLSL_CLASS_VOID:
vkd3d_unreachable();
}
diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c
index 1f8d60c62ac..59b74c065d8 100644
--- a/libs/vkd3d/libs/vkd3d-shader/ir.c
+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c
@@ -2917,8 +2917,7 @@ static enum vkd3d_result vsir_block_init(struct vsir_block *block, unsigned int
if (block_count > SIZE_MAX - (sizeof(*block->dominates) * CHAR_BIT - 1))
return VKD3D_ERROR_OUT_OF_MEMORY;
- block_count = align(block_count, sizeof(*block->dominates) * CHAR_BIT);
- byte_count = block_count / CHAR_BIT;
+ byte_count = VKD3D_BITMAP_SIZE(block_count) * sizeof(*block->dominates);
assert(label);
memset(block, 0, sizeof(*block));
@@ -3098,6 +3097,8 @@ struct vsir_cfg
{
struct vkd3d_shader_message_context *message_context;
struct vsir_program *program;
+ size_t function_begin;
+ size_t function_end;
struct vsir_block *blocks;
struct vsir_block *entry;
size_t block_count;
@@ -3342,25 +3343,19 @@ static void vsir_cfg_dump_structured_program(struct vsir_cfg *cfg)
}
static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program *program,
- struct vkd3d_shader_message_context *message_context, struct vsir_cfg_emit_target *target)
+ struct vkd3d_shader_message_context *message_context, struct vsir_cfg_emit_target *target,
+ size_t *pos)
{
struct vsir_block *current_block = NULL;
enum vkd3d_result ret;
size_t i;
- if (program->shader_version.type == VKD3D_SHADER_TYPE_HULL)
- {
- FIXME("Hull shaders are not supported.\n");
- vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED,
- "The structurizer does not support hull shaders.");
- return VKD3D_ERROR_INVALID_SHADER;
- }
-
memset(cfg, 0, sizeof(*cfg));
cfg->message_context = message_context;
cfg->program = program;
cfg->block_count = program->block_count;
cfg->target = target;
+ cfg->function_begin = *pos;
vsir_block_list_init(&cfg->order);
@@ -3370,9 +3365,10 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program
if (TRACE_ON())
vkd3d_string_buffer_init(&cfg->debug_buffer);
- for (i = 0; i < program->instructions.count; ++i)
+ for (i = *pos; i < program->instructions.count; ++i)
{
struct vkd3d_shader_instruction *instruction = &program->instructions.elements[i];
+ bool finish = false;
switch (instruction->handler_idx)
{
@@ -3404,11 +3400,24 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program
current_block = NULL;
break;
+ case VKD3DSIH_HS_CONTROL_POINT_PHASE:
+ case VKD3DSIH_HS_FORK_PHASE:
+ case VKD3DSIH_HS_JOIN_PHASE:
+ assert(!current_block);
+ finish = true;
+ break;
+
default:
break;
}
+
+ if (finish)
+ break;
}
+ *pos = i;
+ cfg->function_end = *pos;
+
for (i = 0; i < cfg->block_count; ++i)
{
struct vsir_block *block = &cfg->blocks[i];
@@ -4881,12 +4890,13 @@ static enum vkd3d_result vsir_cfg_emit_structured_program(struct vsir_cfg *cfg)
}
static enum vkd3d_result vsir_program_structurize_function(struct vsir_program *program,
- struct vkd3d_shader_message_context *message_context, struct vsir_cfg_emit_target *target)
+ struct vkd3d_shader_message_context *message_context, struct vsir_cfg_emit_target *target,
+ size_t *pos)
{
enum vkd3d_result ret;
struct vsir_cfg cfg;
- if ((ret = vsir_cfg_init(&cfg, program, message_context, target)) < 0)
+ if ((ret = vsir_cfg_init(&cfg, program, message_context, target, pos)) < 0)
return ret;
vsir_cfg_compute_dominators(&cfg);
@@ -4919,7 +4929,7 @@ static enum vkd3d_result vsir_program_structurize(struct vsir_program *program,
{
struct vsir_cfg_emit_target target = {0};
enum vkd3d_result ret;
- unsigned int i;
+ size_t i;
target.jump_target_temp_idx = program->temp_count;
target.temp_count = program->temp_count + 1;
@@ -4927,19 +4937,41 @@ static enum vkd3d_result vsir_program_structurize(struct vsir_program *program,
if (!reserve_instructions(&target.instructions, &target.ins_capacity, program->instructions.count))
return VKD3D_ERROR_OUT_OF_MEMORY;
- /* Copy declarations until the first block. */
- for (i = 0; i < program->instructions.count; ++i)
+ for (i = 0; i < program->instructions.count;)
{
struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
- if (ins->handler_idx == VKD3DSIH_LABEL)
- break;
+ switch (ins->handler_idx)
+ {
+ case VKD3DSIH_LABEL:
+ assert(program->shader_version.type != VKD3D_SHADER_TYPE_HULL);
+ TRACE("Structurizing a non-hull shader.\n");
+ if ((ret = vsir_program_structurize_function(program, message_context,
+ &target, &i)) < 0)
+ goto fail;
+ assert(i == program->instructions.count);
+ break;
- target.instructions[target.ins_count++] = *ins;
- }
+ case VKD3DSIH_HS_CONTROL_POINT_PHASE:
+ case VKD3DSIH_HS_FORK_PHASE:
+ case VKD3DSIH_HS_JOIN_PHASE:
+ assert(program->shader_version.type == VKD3D_SHADER_TYPE_HULL);
+ TRACE("Structurizing phase %u of a hull shader.\n", ins->handler_idx);
+ target.instructions[target.ins_count++] = *ins;
+ ++i;
+ if ((ret = vsir_program_structurize_function(program, message_context,
+ &target, &i)) < 0)
+ goto fail;
+ break;
- if ((ret = vsir_program_structurize_function(program, message_context, &target)) < 0)
- goto fail;
+ default:
+ if (!reserve_instructions(&target.instructions, &target.ins_capacity, target.ins_count + 1))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+ target.instructions[target.ins_count++] = *ins;
+ ++i;
+ break;
+ }
+ }
vkd3d_free(program->instructions.elements);
program->instructions.elements = target.instructions;
@@ -5001,6 +5033,9 @@ static enum vkd3d_result vsir_cfg_materialize_undominated_ssas_to_temps(struct v
struct vsir_block *block = &cfg->blocks[i];
struct vkd3d_shader_instruction *ins;
+ if (block->label == 0)
+ continue;
+
for (ins = block->begin; ins <= block->end; ++ins)
{
for (j = 0; j < ins->dst_count; ++j)
@@ -5016,6 +5051,9 @@ static enum vkd3d_result vsir_cfg_materialize_undominated_ssas_to_temps(struct v
struct vsir_block *block = &cfg->blocks[i];
struct vkd3d_shader_instruction *ins;
+ if (block->label == 0)
+ continue;
+
for (ins = block->begin; ins <= block->end; ++ins)
{
for (j = 0; j < ins->src_count; ++j)
@@ -5028,7 +5066,7 @@ static enum vkd3d_result vsir_cfg_materialize_undominated_ssas_to_temps(struct v
TRACE("Emitting temps for %u values with undominated usage.\n", alloc.next_temp_idx - program->temp_count);
- for (i = 0; i < program->instructions.count; ++i)
+ for (i = cfg->function_begin; i < cfg->function_end; ++i)
{
struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
@@ -5047,13 +5085,14 @@ done:
return VKD3D_OK;
}
-static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps(struct vsir_program *program,
- struct vkd3d_shader_message_context *message_context)
+static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps_in_function(
+ struct vsir_program *program, struct vkd3d_shader_message_context *message_context,
+ size_t *pos)
{
enum vkd3d_result ret;
struct vsir_cfg cfg;
- if ((ret = vsir_cfg_init(&cfg, program, message_context, NULL)) < 0)
+ if ((ret = vsir_cfg_init(&cfg, program, message_context, NULL, pos)) < 0)
return ret;
vsir_cfg_compute_dominators(&cfg);
@@ -5065,6 +5104,47 @@ static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps(stru
return ret;
}
+static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps(struct vsir_program *program,
+ struct vkd3d_shader_message_context *message_context)
+{
+ enum vkd3d_result ret;
+ size_t i;
+
+ for (i = 0; i < program->instructions.count;)
+ {
+ struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
+
+ switch (ins->handler_idx)
+ {
+ case VKD3DSIH_LABEL:
+ assert(program->shader_version.type != VKD3D_SHADER_TYPE_HULL);
+ TRACE("Materializing undominated SSAs in a non-hull shader.\n");
+ if ((ret = vsir_program_materialize_undominated_ssas_to_temps_in_function(
+ program, message_context, &i)) < 0)
+ return ret;
+ assert(i == program->instructions.count);
+ break;
+
+ case VKD3DSIH_HS_CONTROL_POINT_PHASE:
+ case VKD3DSIH_HS_FORK_PHASE:
+ case VKD3DSIH_HS_JOIN_PHASE:
+ assert(program->shader_version.type == VKD3D_SHADER_TYPE_HULL);
+ TRACE("Materializing undominated SSAs in phase %u of a hull shader.\n", ins->handler_idx);
+ ++i;
+ if ((ret = vsir_program_materialize_undominated_ssas_to_temps_in_function(
+ program, message_context, &i)) < 0)
+ return ret;
+ break;
+
+ default:
+ ++i;
+ break;
+ }
+ }
+
+ return VKD3D_OK;
+}
+
struct validation_context
{
struct vkd3d_shader_message_context *message_context;
@@ -5890,7 +5970,8 @@ static void vsir_validate_instruction(struct validation_context *ctx)
unsigned int value_idx = 2 * i;
unsigned int label_idx = 2 * i + 1;
- if (!register_is_constant(&instruction->src[value_idx].reg) && !register_is_ssa(&instruction->src[value_idx].reg))
+ if (!register_is_constant_or_undef(&instruction->src[value_idx].reg)
+ && !register_is_ssa(&instruction->src[value_idx].reg))
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE,
"Invalid value register for incoming %zu of type %#x in PHI instruction, "
"expected SSA, IMMCONST or IMMCONST64.", i, instruction->src[value_idx].reg.type);
diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c
index 6ee06c02d74..708ab6268a7 100644
--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c
+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c
@@ -3006,10 +3006,15 @@ static D3D_SHADER_VARIABLE_CLASS sm4_class(const struct hlsl_type *type)
return D3D_SVC_VECTOR;
case HLSL_CLASS_ARRAY:
+ case HLSL_CLASS_DEPTH_STENCIL_VIEW:
+ case HLSL_CLASS_EFFECT_GROUP:
case HLSL_CLASS_STRUCT:
case HLSL_CLASS_OBJECT:
+ case HLSL_CLASS_PASS:
+ case HLSL_CLASS_RENDER_TARGET_VIEW:
case HLSL_CLASS_SAMPLER:
case HLSL_CLASS_STRING:
+ case HLSL_CLASS_TECHNIQUE:
case HLSL_CLASS_TEXTURE:
case HLSL_CLASS_UAV:
case HLSL_CLASS_VOID:
--
2.43.0

View File

@ -1,953 +0,0 @@
From e91e957dbee71d7729e7e6fe7aa6c04bf13c360b Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Sun, 28 Apr 2024 09:46:44 +1000
Subject: [PATCH] Updated vkd3d to 13e1491941a1af32ddfc1019fa304231fd121c4d.
---
libs/vkd3d/include/private/vkd3d_common.h | 63 +++++++
libs/vkd3d/include/vkd3d_types.h | 6 +
libs/vkd3d/libs/vkd3d-common/blob.c | 3 +
libs/vkd3d/libs/vkd3d-common/error.c | 6 +
libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 61 ++++++-
libs/vkd3d/libs/vkd3d-shader/ir.c | 122 +++++++++++++-
libs/vkd3d/libs/vkd3d/cache.c | 195 ++++++++++++++++++++++
libs/vkd3d/libs/vkd3d/device.c | 36 +++-
libs/vkd3d/libs/vkd3d/resource.c | 24 +--
libs/vkd3d/libs/vkd3d/vkd3d_main.c | 2 +-
libs/vkd3d/libs/vkd3d/vkd3d_private.h | 92 ++--------
11 files changed, 497 insertions(+), 113 deletions(-)
diff --git a/libs/vkd3d/include/private/vkd3d_common.h b/libs/vkd3d/include/private/vkd3d_common.h
index b0e9230dab6..2d950b4f7aa 100644
--- a/libs/vkd3d/include/private/vkd3d_common.h
+++ b/libs/vkd3d/include/private/vkd3d_common.h
@@ -340,6 +340,11 @@ static inline int vkd3d_u32_compare(uint32_t x, uint32_t y)
return (x > y) - (x < y);
}
+static inline int vkd3d_u64_compare(uint64_t x, uint64_t y)
+{
+ return (x > y) - (x < y);
+}
+
#define VKD3D_BITMAP_SIZE(x) (((x) + 0x1f) >> 5)
static inline bool bitmap_clear(uint32_t *map, unsigned int idx)
@@ -431,6 +436,64 @@ static inline uint32_t vkd3d_atomic_increment_u32(uint32_t volatile *x)
return vkd3d_atomic_add_fetch_u32(x, 1);
}
+static inline bool vkd3d_atomic_compare_exchange_u32(uint32_t volatile *x, uint32_t expected, uint32_t val)
+{
+#if HAVE_SYNC_BOOL_COMPARE_AND_SWAP
+ return __sync_bool_compare_and_swap(x, expected, val);
+#elif defined(_WIN32)
+ return InterlockedCompareExchange((LONG *)x, val, expected) == expected;
+#else
+# error "vkd3d_atomic_compare_exchange_u32() not implemented for this platform"
+#endif
+}
+
+static inline bool vkd3d_atomic_compare_exchange_ptr(void * volatile *x, void *expected, void *val)
+{
+#if HAVE_SYNC_BOOL_COMPARE_AND_SWAP
+ return __sync_bool_compare_and_swap(x, expected, val);
+#elif defined(_WIN32)
+ return InterlockedCompareExchangePointer(x, val, expected) == expected;
+#else
+# error "vkd3d_atomic_compare_exchange_ptr() not implemented for this platform"
+#endif
+}
+
+static inline uint32_t vkd3d_atomic_exchange_u32(uint32_t volatile *x, uint32_t val)
+{
+#if HAVE_ATOMIC_EXCHANGE_N
+ return __atomic_exchange_n(x, val, __ATOMIC_SEQ_CST);
+#elif defined(_WIN32)
+ return InterlockedExchange((LONG *)x, val);
+#else
+ uint32_t expected;
+
+ do
+ {
+ expected = *x;
+ } while (!vkd3d_atomic_compare_exchange_u32(x, expected, val));
+
+ return expected;
+#endif
+}
+
+static inline void *vkd3d_atomic_exchange_ptr(void * volatile *x, void *val)
+{
+#if HAVE_ATOMIC_EXCHANGE_N
+ return __atomic_exchange_n(x, val, __ATOMIC_SEQ_CST);
+#elif defined(_WIN32)
+ return InterlockedExchangePointer(x, val);
+#else
+ void *expected;
+
+ do
+ {
+ expected = *x;
+ } while (!vkd3d_atomic_compare_exchange_ptr(x, expected, val));
+
+ return expected;
+#endif
+}
+
struct vkd3d_mutex
{
#ifdef _WIN32
diff --git a/libs/vkd3d/include/vkd3d_types.h b/libs/vkd3d/include/vkd3d_types.h
index 017eaf11806..dc5a7c064ae 100644
--- a/libs/vkd3d/include/vkd3d_types.h
+++ b/libs/vkd3d/include/vkd3d_types.h
@@ -53,6 +53,12 @@ enum vkd3d_result
VKD3D_ERROR_INVALID_SHADER = -4,
/** The operation is not implemented in this version of vkd3d. */
VKD3D_ERROR_NOT_IMPLEMENTED = -5,
+ /** The object or entry already exists. \since 1.12 */
+ VKD3D_ERROR_KEY_ALREADY_EXISTS = -6,
+ /** The requested object was not found. \since 1.12 */
+ VKD3D_ERROR_NOT_FOUND = -7,
+ /** The output buffer is larger than the requested object \since 1.12. */
+ VKD3D_ERROR_MORE_DATA = -8,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_RESULT),
};
diff --git a/libs/vkd3d/libs/vkd3d-common/blob.c b/libs/vkd3d/libs/vkd3d-common/blob.c
index 6bc95dc55c4..c2c6ad67804 100644
--- a/libs/vkd3d/libs/vkd3d-common/blob.c
+++ b/libs/vkd3d/libs/vkd3d-common/blob.c
@@ -16,6 +16,9 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#ifndef __MINGW32__
+#define WIDL_C_INLINE_WRAPPERS
+#endif
#define COBJMACROS
#define CONST_VTABLE
diff --git a/libs/vkd3d/libs/vkd3d-common/error.c b/libs/vkd3d/libs/vkd3d-common/error.c
index b8350a5404c..2f978c4977d 100644
--- a/libs/vkd3d/libs/vkd3d-common/error.c
+++ b/libs/vkd3d/libs/vkd3d-common/error.c
@@ -35,6 +35,12 @@ HRESULT hresult_from_vkd3d_result(int vkd3d_result)
return E_INVALIDARG;
case VKD3D_ERROR_NOT_IMPLEMENTED:
return E_NOTIMPL;
+ case VKD3D_ERROR_KEY_ALREADY_EXISTS:
+ return DXGI_ERROR_ALREADY_EXISTS;
+ case VKD3D_ERROR_NOT_FOUND:
+ return DXGI_ERROR_NOT_FOUND;
+ case VKD3D_ERROR_MORE_DATA:
+ return DXGI_ERROR_MORE_DATA;
default:
FIXME("Unhandled vkd3d result %d.\n", vkd3d_result);
return E_FAIL;
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
index 55d9ecf707d..09e4f596241 100644
--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
@@ -1813,6 +1813,7 @@ static uint32_t sm1_encode_register_type(D3DSHADER_PARAM_REGISTER_TYPE type)
struct sm1_instruction
{
D3DSHADER_INSTRUCTION_OPCODE_TYPE opcode;
+ unsigned int flags;
struct sm1_dst_register
{
@@ -1852,6 +1853,8 @@ static void write_sm1_instruction(struct hlsl_ctx *ctx, struct vkd3d_bytecode_bu
uint32_t token = instr->opcode;
unsigned int i;
+ token |= VKD3D_SM1_INSTRUCTION_FLAGS_MASK & (instr->flags << VKD3D_SM1_INSTRUCTION_FLAGS_SHIFT);
+
if (ctx->profile->major_version > 1)
token |= (instr->has_dst + instr->src_count) << D3DSI_INSTLENGTH_SHIFT;
put_u32(buffer, token);
@@ -2414,6 +2417,49 @@ static void write_sm1_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b
}
}
+static void write_sm1_block(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer,
+ const struct hlsl_block *block);
+
+static void write_sm1_if(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_node *instr)
+{
+ const struct hlsl_ir_if *iff = hlsl_ir_if(instr);
+ const struct hlsl_ir_node *condition;
+ struct sm1_instruction sm1_ifc, sm1_else, sm1_endif;
+
+ condition = iff->condition.node;
+ assert(condition->data_type->dimx == 1 && condition->data_type->dimy == 1);
+
+ sm1_ifc = (struct sm1_instruction)
+ {
+ .opcode = D3DSIO_IFC,
+ .flags = VKD3D_SHADER_REL_OP_NE, /* Make it a "if_ne" instruction. */
+
+ .srcs[0].type = D3DSPR_TEMP,
+ .srcs[0].swizzle = hlsl_swizzle_from_writemask(condition->reg.writemask),
+ .srcs[0].reg = condition->reg.id,
+ .srcs[0].mod = 0,
+
+ .srcs[1].type = D3DSPR_TEMP,
+ .srcs[1].swizzle = hlsl_swizzle_from_writemask(condition->reg.writemask),
+ .srcs[1].reg = condition->reg.id,
+ .srcs[1].mod = D3DSPSM_NEG,
+
+ .src_count = 2,
+ };
+ write_sm1_instruction(ctx, buffer, &sm1_ifc);
+ write_sm1_block(ctx, buffer, &iff->then_block);
+
+ if (!list_empty(&iff->else_block.instrs))
+ {
+ sm1_else = (struct sm1_instruction){.opcode = D3DSIO_ELSE};
+ write_sm1_instruction(ctx, buffer, &sm1_else);
+ write_sm1_block(ctx, buffer, &iff->else_block);
+ }
+
+ sm1_endif = (struct sm1_instruction){.opcode = D3DSIO_ENDIF};
+ write_sm1_instruction(ctx, buffer, &sm1_endif);
+}
+
static void write_sm1_jump(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_node *instr)
{
const struct hlsl_ir_jump *jump = hlsl_ir_jump(instr);
@@ -2614,12 +2660,12 @@ static void write_sm1_swizzle(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer
write_sm1_instruction(ctx, buffer, &sm1_instr);
}
-static void write_sm1_instructions(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer,
- const struct hlsl_ir_function_decl *entry_func)
+static void write_sm1_block(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer,
+ const struct hlsl_block *block)
{
const struct hlsl_ir_node *instr;
- LIST_FOR_EACH_ENTRY(instr, &entry_func->body.instrs, struct hlsl_ir_node, entry)
+ LIST_FOR_EACH_ENTRY(instr, &block->instrs, struct hlsl_ir_node, entry)
{
if (instr->data_type)
{
@@ -2643,6 +2689,13 @@ static void write_sm1_instructions(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b
write_sm1_expr(ctx, buffer, instr);
break;
+ case HLSL_IR_IF:
+ if (hlsl_version_ge(ctx, 2, 1))
+ write_sm1_if(ctx, buffer, instr);
+ else
+ hlsl_fixme(ctx, &instr->loc, "Flatten \"if\" conditionals branches.");
+ break;
+
case HLSL_IR_JUMP:
write_sm1_jump(ctx, buffer, instr);
break;
@@ -2680,7 +2733,7 @@ int hlsl_sm1_write(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun
write_sm1_constant_defs(ctx, &buffer);
write_sm1_semantic_dcls(ctx, &buffer);
write_sm1_sampler_dcls(ctx, &buffer);
- write_sm1_instructions(ctx, &buffer, entry_func);
+ write_sm1_block(ctx, &buffer, &entry_func->body);
put_u32(&buffer, D3DSIO_END);
diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c
index 59b74c065d8..121b0fe3a6c 100644
--- a/libs/vkd3d/libs/vkd3d-shader/ir.c
+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c
@@ -82,6 +82,106 @@ static bool vsir_instruction_init_with_params(struct vsir_program *program,
return true;
}
+static bool get_opcode_from_rel_op(enum vkd3d_shader_rel_op rel_op, enum vkd3d_data_type data_type,
+ enum vkd3d_shader_opcode *opcode, bool *requires_swap)
+{
+ switch (rel_op)
+ {
+ case VKD3D_SHADER_REL_OP_LT:
+ case VKD3D_SHADER_REL_OP_GT:
+ *requires_swap = (rel_op == VKD3D_SHADER_REL_OP_GT);
+ if (data_type == VKD3D_DATA_FLOAT)
+ {
+ *opcode = VKD3DSIH_LTO;
+ return true;
+ }
+ break;
+
+ case VKD3D_SHADER_REL_OP_GE:
+ case VKD3D_SHADER_REL_OP_LE:
+ *requires_swap = (rel_op == VKD3D_SHADER_REL_OP_LE);
+ if (data_type == VKD3D_DATA_FLOAT)
+ {
+ *opcode = VKD3DSIH_GEO;
+ return true;
+ }
+ break;
+
+ case VKD3D_SHADER_REL_OP_EQ:
+ *requires_swap = false;
+ if (data_type == VKD3D_DATA_FLOAT)
+ {
+ *opcode = VKD3DSIH_EQO;
+ return true;
+ }
+ break;
+
+ case VKD3D_SHADER_REL_OP_NE:
+ *requires_swap = false;
+ if (data_type == VKD3D_DATA_FLOAT)
+ {
+ *opcode = VKD3DSIH_NEO;
+ return true;
+ }
+ break;
+ }
+ return false;
+}
+
+static enum vkd3d_result vsir_program_lower_ifc(struct vsir_program *program,
+ struct vkd3d_shader_instruction *ifc, unsigned int *tmp_idx,
+ struct vkd3d_shader_message_context *message_context)
+{
+ struct vkd3d_shader_instruction_array *instructions = &program->instructions;
+ size_t pos = ifc - instructions->elements;
+ struct vkd3d_shader_instruction *ins;
+ enum vkd3d_shader_opcode opcode;
+ bool swap;
+
+ if (!shader_instruction_array_insert_at(instructions, pos + 1, 2))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+
+ if (*tmp_idx == ~0u)
+ *tmp_idx = program->temp_count++;
+
+ /* Replace ifc comparison with actual comparison, saving the result in the tmp register. */
+ if (!(get_opcode_from_rel_op(ifc->flags, ifc->src[0].reg.data_type, &opcode, &swap)))
+ {
+ vkd3d_shader_error(message_context, &ifc->location, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED,
+ "Aborting due to not yet implemented feature: opcode for rel_op %u and data type %u.",
+ ifc->flags, ifc->src[0].reg.data_type);
+ return VKD3D_ERROR_NOT_IMPLEMENTED;
+ }
+
+ ins = &instructions->elements[pos + 1];
+ if (!vsir_instruction_init_with_params(program, ins, &ifc->location, opcode, 1, 2))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+
+ vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1);
+ ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4;
+ ins->dst[0].reg.idx[0].offset = *tmp_idx;
+ ins->dst[0].write_mask = VKD3DSP_WRITEMASK_0;
+
+ ins->src[0] = ifc->src[swap];
+ ins->src[1] = ifc->src[!swap];
+
+ /* Create new if instruction using the previous result. */
+ ins = &instructions->elements[pos + 2];
+ if (!vsir_instruction_init_with_params(program, ins, &ifc->location, VKD3DSIH_IF, 0, 1))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+ ins->flags = VKD3D_SHADER_CONDITIONAL_OP_NZ;
+
+ vsir_register_init(&ins->src[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1);
+ ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4;
+ ins->src[0].reg.idx[0].offset = *tmp_idx;
+ ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X);
+
+ /* Make the original instruction no-op */
+ vkd3d_shader_instruction_make_nop(ifc);
+
+ return VKD3D_OK;
+}
+
static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program,
struct vkd3d_shader_instruction *texkill, unsigned int *tmp_idx)
{
@@ -210,7 +310,8 @@ static enum vkd3d_result vsir_program_lower_precise_mad(struct vsir_program *pro
return VKD3D_OK;
}
-static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *program)
+static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *program,
+ struct vkd3d_shader_message_context *message_context)
{
struct vkd3d_shader_instruction_array *instructions = &program->instructions;
unsigned int tmp_idx = ~0u, i;
@@ -222,6 +323,11 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr
switch (ins->handler_idx)
{
+ case VKD3DSIH_IFC:
+ if ((ret = vsir_program_lower_ifc(program, ins, &tmp_idx, message_context)) < 0)
+ return ret;
+ break;
+
case VKD3DSIH_TEXKILL:
if ((ret = vsir_program_lower_texkill(program, ins, &tmp_idx)) < 0)
return ret;
@@ -4992,12 +5098,12 @@ static void register_map_undominated_use(struct vkd3d_shader_register *reg, stru
{
unsigned int i;
- if (!register_is_ssa(reg))
- return;
-
- i = reg->idx[0].offset;
- if (alloc->table[i] == UINT_MAX && !vsir_block_dominates(origin_blocks[i], block))
- alloc->table[i] = alloc->next_temp_idx++;
+ if (register_is_ssa(reg))
+ {
+ i = reg->idx[0].offset;
+ if (alloc->table[i] == UINT_MAX && !vsir_block_dominates(origin_blocks[i], block))
+ alloc->table[i] = alloc->next_temp_idx++;
+ }
for (i = 0; i < reg->idx_count; ++i)
if (reg->idx[i].rel_addr)
@@ -6056,7 +6162,7 @@ enum vkd3d_result vsir_program_normalise(struct vsir_program *program, uint64_t
{
enum vkd3d_result result = VKD3D_OK;
- if ((result = vsir_program_lower_instructions(program)) < 0)
+ if ((result = vsir_program_lower_instructions(program, message_context)) < 0)
return result;
if (program->shader_version.major >= 6)
diff --git a/libs/vkd3d/libs/vkd3d/cache.c b/libs/vkd3d/libs/vkd3d/cache.c
index 56ba6990420..a0a29ed30cb 100644
--- a/libs/vkd3d/libs/vkd3d/cache.c
+++ b/libs/vkd3d/libs/vkd3d/cache.c
@@ -18,11 +18,60 @@
#include "vkd3d_private.h"
+struct vkd3d_cache_entry_header
+{
+ uint64_t hash;
+ uint64_t key_size;
+ uint64_t value_size;
+};
+
struct vkd3d_shader_cache
{
unsigned int refcount;
+ struct vkd3d_mutex lock;
+
+ struct rb_tree tree;
};
+struct shader_cache_entry
+{
+ struct vkd3d_cache_entry_header h;
+ struct rb_entry entry;
+ uint8_t *payload;
+};
+
+struct shader_cache_key
+{
+ uint64_t hash;
+ const void *key;
+ uint64_t key_size;
+};
+
+static int vkd3d_shader_cache_compare_key(const void *key, const struct rb_entry *entry)
+{
+ const struct shader_cache_entry *e = RB_ENTRY_VALUE(entry, struct shader_cache_entry, entry);
+ const struct shader_cache_key *k = key;
+ int ret;
+
+ if ((ret = vkd3d_u64_compare(k->hash, e->h.hash)))
+ return ret;
+ if ((ret = vkd3d_u64_compare(k->key_size, e->h.key_size)))
+ return ret;
+
+ /* Until now we have not seen an actual hash collision. If the key didn't match it was always
+ * due to a bug in the serialization code or memory corruption. If you see this FIXME please
+ * investigate. */
+ if ((ret = memcmp(k->key, e->payload, k->key_size)))
+ FIXME("Actual case of a hash collision found.\n");
+ return ret;
+}
+
+static void vkd3d_shader_cache_add_entry(struct vkd3d_shader_cache *cache,
+ struct shader_cache_entry *e)
+{
+ rb_put(&cache->tree, &e->h.hash, &e->entry);
+}
+
int vkd3d_shader_open_cache(struct vkd3d_shader_cache **cache)
{
struct vkd3d_shader_cache *object;
@@ -34,6 +83,9 @@ int vkd3d_shader_open_cache(struct vkd3d_shader_cache **cache)
return VKD3D_ERROR_OUT_OF_MEMORY;
object->refcount = 1;
+ rb_init(&object->tree, vkd3d_shader_cache_compare_key);
+ vkd3d_mutex_init(&object->lock);
+
*cache = object;
return VKD3D_OK;
@@ -46,6 +98,13 @@ unsigned int vkd3d_shader_cache_incref(struct vkd3d_shader_cache *cache)
return refcount;
}
+static void vkd3d_shader_cache_destroy_entry(struct rb_entry *entry, void *context)
+{
+ struct shader_cache_entry *e = RB_ENTRY_VALUE(entry, struct shader_cache_entry, entry);
+ vkd3d_free(e->payload);
+ vkd3d_free(e);
+}
+
unsigned int vkd3d_shader_cache_decref(struct vkd3d_shader_cache *cache)
{
unsigned int refcount = vkd3d_atomic_decrement_u32(&cache->refcount);
@@ -54,6 +113,142 @@ unsigned int vkd3d_shader_cache_decref(struct vkd3d_shader_cache *cache)
if (refcount)
return refcount;
+ rb_destroy(&cache->tree, vkd3d_shader_cache_destroy_entry, NULL);
+ vkd3d_mutex_destroy(&cache->lock);
+
vkd3d_free(cache);
return 0;
}
+
+static uint64_t vkd3d_shader_cache_hash_key(const void *key, size_t size)
+{
+ static const uint64_t fnv_prime = 0x00000100000001b3;
+ uint64_t hash = 0xcbf29ce484222325;
+ const uint8_t *k = key;
+ size_t i;
+
+ for (i = 0; i < size; ++i)
+ hash = (hash ^ k[i]) * fnv_prime;
+
+ return hash;
+}
+
+static void vkd3d_shader_cache_lock(struct vkd3d_shader_cache *cache)
+{
+ vkd3d_mutex_lock(&cache->lock);
+}
+
+static void vkd3d_shader_cache_unlock(struct vkd3d_shader_cache *cache)
+{
+ vkd3d_mutex_unlock(&cache->lock);
+}
+
+int vkd3d_shader_cache_put(struct vkd3d_shader_cache *cache,
+ const void *key, size_t key_size, const void *value, size_t value_size)
+{
+ struct shader_cache_entry *e;
+ struct shader_cache_key k;
+ struct rb_entry *entry;
+ enum vkd3d_result ret;
+
+ TRACE("%p, %p, %#zx, %p, %#zx.\n", cache, key, key_size, value, value_size);
+
+ k.hash = vkd3d_shader_cache_hash_key(key, key_size);
+ k.key = key;
+ k.key_size = key_size;
+
+ vkd3d_shader_cache_lock(cache);
+
+ entry = rb_get(&cache->tree, &k);
+ e = entry ? RB_ENTRY_VALUE(entry, struct shader_cache_entry, entry) : NULL;
+
+ if (e)
+ {
+ WARN("Key already exists, returning VKD3D_ERROR_KEY_ALREADY_EXISTS.\n");
+ ret = VKD3D_ERROR_KEY_ALREADY_EXISTS;
+ goto done;
+ }
+
+ e = vkd3d_malloc(sizeof(*e));
+ if (!e)
+ {
+ ret = VKD3D_ERROR_OUT_OF_MEMORY;
+ goto done;
+ }
+ e->payload = vkd3d_malloc(key_size + value_size);
+ if (!e->payload)
+ {
+ vkd3d_free(e);
+ ret = VKD3D_ERROR_OUT_OF_MEMORY;
+ goto done;
+ }
+
+ e->h.key_size = key_size;
+ e->h.value_size = value_size;
+ e->h.hash = k.hash;
+ memcpy(e->payload, key, key_size);
+ memcpy(e->payload + key_size, value, value_size);
+
+ vkd3d_shader_cache_add_entry(cache, e);
+ TRACE("Cache entry %#"PRIx64" stored.\n", k.hash);
+ ret = VKD3D_OK;
+
+done:
+ vkd3d_shader_cache_unlock(cache);
+ return ret;
+}
+
+int vkd3d_shader_cache_get(struct vkd3d_shader_cache *cache,
+ const void *key, size_t key_size, void *value, size_t *value_size)
+{
+ struct shader_cache_entry *e;
+ struct shader_cache_key k;
+ struct rb_entry *entry;
+ enum vkd3d_result ret;
+ size_t size_in;
+
+ TRACE("%p, %p, %#zx, %p, %p.\n", cache, key, key_size, value, value_size);
+
+ size_in = *value_size;
+
+ k.hash = vkd3d_shader_cache_hash_key(key, key_size);
+ k.key = key;
+ k.key_size = key_size;
+
+ vkd3d_shader_cache_lock(cache);
+
+ entry = rb_get(&cache->tree, &k);
+ if (!entry)
+ {
+ WARN("Entry not found.\n");
+ ret = VKD3D_ERROR_NOT_FOUND;
+ goto done;
+ }
+
+ e = RB_ENTRY_VALUE(entry, struct shader_cache_entry, entry);
+
+ *value_size = e->h.value_size;
+ if (!value)
+ {
+ TRACE("Found item %#"PRIx64", returning needed size %#"PRIx64".\n",
+ e->h.hash, e->h.value_size);
+ ret = VKD3D_OK;
+ goto done;
+ }
+
+ if (size_in < e->h.value_size)
+ {
+ WARN("Output buffer is too small for item %#"PRIx64", got %#zx want %#"PRIx64".\n",
+ e->h.hash, size_in, e->h.value_size);
+ ret = VKD3D_ERROR_MORE_DATA;
+ goto done;
+ }
+
+ memcpy(value, e->payload + e->h.key_size, e->h.value_size);
+ ret = VKD3D_OK;
+ TRACE("Returning cached item %#"PRIx64".\n", e->h.hash);
+
+done:
+ vkd3d_shader_cache_unlock(cache);
+ return ret;
+}
diff --git a/libs/vkd3d/libs/vkd3d/device.c b/libs/vkd3d/libs/vkd3d/device.c
index a394e3f7592..cb2b6ad0364 100644
--- a/libs/vkd3d/libs/vkd3d/device.c
+++ b/libs/vkd3d/libs/vkd3d/device.c
@@ -2685,19 +2685,43 @@ static HRESULT STDMETHODCALLTYPE d3d12_cache_session_GetDevice(ID3D12ShaderCache
static HRESULT STDMETHODCALLTYPE d3d12_cache_session_FindValue(ID3D12ShaderCacheSession *iface,
const void *key, UINT key_size, void *value, UINT *value_size)
{
- FIXME("iface %p, key %p, key_size %#x, value %p, value_size %p stub!\n",
+ struct d3d12_cache_session *session = impl_from_ID3D12ShaderCacheSession(iface);
+ enum vkd3d_result ret;
+ size_t size;
+
+ TRACE("iface %p, key %p, key_size %#x, value %p, value_size %p.\n",
iface, key, key_size, value, value_size);
- return DXGI_ERROR_NOT_FOUND;
+ if (!value_size)
+ {
+ WARN("value_size is NULL, returning E_INVALIDARG.\n");
+ return E_INVALIDARG;
+ }
+
+ size = *value_size;
+ ret = vkd3d_shader_cache_get(session->cache, key, key_size, value, &size);
+ *value_size = size;
+
+ return hresult_from_vkd3d_result(ret);
}
static HRESULT STDMETHODCALLTYPE d3d12_cache_session_StoreValue(ID3D12ShaderCacheSession *iface,
const void *key, UINT key_size, const void *value, UINT value_size)
{
- FIXME("iface %p, key %p, key_size %#x, value %p, value_size %u stub!\n", iface, key, key_size,
- value, value_size);
+ struct d3d12_cache_session *session = impl_from_ID3D12ShaderCacheSession(iface);
+ enum vkd3d_result ret;
- return E_NOTIMPL;
+ TRACE("iface %p, key %p, key_size %#x, value %p, value_size %u.\n",
+ iface, key, key_size, value, value_size);
+
+ if (!key || !key_size || !value || !value_size)
+ {
+ WARN("Invalid input parameters, returning E_INVALIDARG.\n");
+ return E_INVALIDARG;
+ }
+
+ ret = vkd3d_shader_cache_put(session->cache, key, key_size, value, value_size);
+ return hresult_from_vkd3d_result(ret);
}
static void STDMETHODCALLTYPE d3d12_cache_session_SetDeleteOnDestroy(ID3D12ShaderCacheSession *iface)
@@ -2833,7 +2857,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_QueryInterface(ID3D12Device9 *ifac
|| IsEqualGUID(riid, &IID_ID3D12Object)
|| IsEqualGUID(riid, &IID_IUnknown))
{
- ID3D12Device_AddRef(iface);
+ ID3D12Device9_AddRef(iface);
*object = iface;
return S_OK;
}
diff --git a/libs/vkd3d/libs/vkd3d/resource.c b/libs/vkd3d/libs/vkd3d/resource.c
index 179999148bc..7a2f464c98e 100644
--- a/libs/vkd3d/libs/vkd3d/resource.c
+++ b/libs/vkd3d/libs/vkd3d/resource.c
@@ -1271,7 +1271,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_QueryInterface(ID3D12Resource2 *
|| IsEqualGUID(riid, &IID_ID3D12Object)
|| IsEqualGUID(riid, &IID_IUnknown))
{
- ID3D12Resource_AddRef(iface);
+ ID3D12Resource2_AddRef(iface);
*object = iface;
return S_OK;
}
@@ -2350,16 +2350,16 @@ static void *vkd3d_desc_object_cache_get(struct vkd3d_desc_object_cache *cache)
i = vkd3d_atomic_increment_u32(&cache->next_index) & HEAD_INDEX_MASK;
for (;;)
{
- if (vkd3d_atomic_compare_exchange(&cache->heads[i].spinlock, 0, 1))
+ if (vkd3d_atomic_compare_exchange_u32(&cache->heads[i].spinlock, 0, 1))
{
if ((u.object = cache->heads[i].head))
{
vkd3d_atomic_decrement_u32(&cache->free_count);
cache->heads[i].head = u.header->next;
- vkd3d_atomic_exchange(&cache->heads[i].spinlock, 0);
+ vkd3d_atomic_exchange_u32(&cache->heads[i].spinlock, 0);
return u.object;
}
- vkd3d_atomic_exchange(&cache->heads[i].spinlock, 0);
+ vkd3d_atomic_exchange_u32(&cache->heads[i].spinlock, 0);
}
/* Keeping a free count avoids uncertainty over when this loop should terminate,
* which could result in excess allocations gradually increasing without limit. */
@@ -2381,7 +2381,7 @@ static void vkd3d_desc_object_cache_push(struct vkd3d_desc_object_cache *cache,
i = vkd3d_atomic_increment_u32(&cache->next_index) & HEAD_INDEX_MASK;
for (;;)
{
- if (vkd3d_atomic_compare_exchange(&cache->heads[i].spinlock, 0, 1))
+ if (vkd3d_atomic_compare_exchange_u32(&cache->heads[i].spinlock, 0, 1))
break;
i = (i + 1) & HEAD_INDEX_MASK;
}
@@ -2389,7 +2389,7 @@ static void vkd3d_desc_object_cache_push(struct vkd3d_desc_object_cache *cache,
head = cache->heads[i].head;
u.header->next = head;
cache->heads[i].head = u.object;
- vkd3d_atomic_exchange(&cache->heads[i].spinlock, 0);
+ vkd3d_atomic_exchange_u32(&cache->heads[i].spinlock, 0);
vkd3d_atomic_increment_u32(&cache->free_count);
}
@@ -2473,7 +2473,7 @@ void vkd3d_view_decref(void *view, struct d3d12_device *device)
static inline void d3d12_desc_replace(struct d3d12_desc *dst, void *view, struct d3d12_device *device)
{
- if ((view = vkd3d_atomic_exchange_pointer(&dst->s.u.object, view)))
+ if ((view = vkd3d_atomic_exchange_ptr(&dst->s.u.object, view)))
vkd3d_view_decref(view, device);
}
@@ -2652,7 +2652,7 @@ void d3d12_desc_flush_vk_heap_updates_locked(struct d3d12_descriptor_heap *descr
union d3d12_desc_object u;
unsigned int i, next;
- if ((i = vkd3d_atomic_exchange(&descriptor_heap->dirty_list_head, UINT_MAX)) == UINT_MAX)
+ if ((i = vkd3d_atomic_exchange_u32(&descriptor_heap->dirty_list_head, UINT_MAX)) == UINT_MAX)
return;
writes.null_vk_cbv_info.buffer = VK_NULL_HANDLE;
@@ -2667,7 +2667,7 @@ void d3d12_desc_flush_vk_heap_updates_locked(struct d3d12_descriptor_heap *descr
for (; i != UINT_MAX; i = next)
{
src = &descriptors[i];
- next = vkd3d_atomic_exchange(&src->next, 0);
+ next = vkd3d_atomic_exchange_u32(&src->next, 0);
next = (int)next >> 1;
/* A race exists here between updating src->next and getting the current object. The best
@@ -2695,13 +2695,13 @@ static void d3d12_desc_mark_as_modified(struct d3d12_desc *dst, struct d3d12_des
head = descriptor_heap->dirty_list_head;
/* Only one thread can swap the value away from zero. */
- if (!vkd3d_atomic_compare_exchange(&dst->next, 0, (head << 1) | 1))
+ if (!vkd3d_atomic_compare_exchange_u32(&dst->next, 0, (head << 1) | 1))
return;
/* Now it is safe to modify 'next' to another nonzero value if necessary. */
- while (!vkd3d_atomic_compare_exchange(&descriptor_heap->dirty_list_head, head, i))
+ while (!vkd3d_atomic_compare_exchange_u32(&descriptor_heap->dirty_list_head, head, i))
{
head = descriptor_heap->dirty_list_head;
- vkd3d_atomic_exchange(&dst->next, (head << 1) | 1);
+ vkd3d_atomic_exchange_u32(&dst->next, (head << 1) | 1);
}
}
diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_main.c b/libs/vkd3d/libs/vkd3d/vkd3d_main.c
index 29305fbdc63..c7431bd821b 100644
--- a/libs/vkd3d/libs/vkd3d/vkd3d_main.c
+++ b/libs/vkd3d/libs/vkd3d/vkd3d_main.c
@@ -71,7 +71,7 @@ HRESULT vkd3d_create_device(const struct vkd3d_device_create_info *create_info,
if (!device)
{
- ID3D12Device_Release(&object->ID3D12Device9_iface);
+ ID3D12Device9_Release(&object->ID3D12Device9_iface);
return S_FALSE;
}
diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/libs/vkd3d/vkd3d_private.h
index 5f60c8d90ad..d1fa866d9e3 100644
--- a/libs/vkd3d/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/libs/vkd3d/vkd3d_private.h
@@ -19,6 +19,9 @@
#ifndef __VKD3D_PRIVATE_H
#define __VKD3D_PRIVATE_H
+#ifndef __MINGW32__
+#define WIDL_C_INLINE_WRAPPERS
+#endif
#define COBJMACROS
#define NONAMELESSUNION
#define VK_NO_PROTOTYPES
@@ -194,93 +197,14 @@ struct vkd3d_instance
unsigned int refcount;
};
-#ifdef _WIN32
-
-union vkd3d_thread_handle
-{
- void *handle;
-};
-
-static inline bool vkd3d_atomic_compare_exchange(unsigned int volatile *x, unsigned int cmp, unsigned int xchg)
-{
- return InterlockedCompareExchange((LONG volatile *)x, xchg, cmp) == cmp;
-}
-
-static inline unsigned int vkd3d_atomic_exchange(unsigned int volatile *x, unsigned int val)
-{
- return InterlockedExchange((LONG volatile *)x, val);
-}
-
-static inline bool vkd3d_atomic_compare_exchange_pointer(void * volatile *x, void *cmp, void *xchg)
-{
- return InterlockedCompareExchangePointer(x, xchg, cmp) == cmp;
-}
-
-static inline void *vkd3d_atomic_exchange_pointer(void * volatile *x, void *val)
-{
- return InterlockedExchangePointer(x, val);
-}
-
-#else /* _WIN32 */
-
-#include <pthread.h>
-
union vkd3d_thread_handle
{
+#ifndef _WIN32
pthread_t pthread;
+#endif
void *handle;
};
-# if HAVE_SYNC_BOOL_COMPARE_AND_SWAP
-static inline bool vkd3d_atomic_compare_exchange(unsigned int volatile *x, unsigned int cmp, unsigned int xchg)
-{
- return __sync_bool_compare_and_swap(x, cmp, xchg);
-}
-
-static inline bool vkd3d_atomic_compare_exchange_pointer(void * volatile *x, void *cmp, void *xchg)
-{
- return __sync_bool_compare_and_swap(x, cmp, xchg);
-}
-# else
-# error "vkd3d_atomic_compare_exchange() not implemented for this platform"
-# endif
-
-# if HAVE_ATOMIC_EXCHANGE_N
-static inline unsigned int vkd3d_atomic_exchange(unsigned int volatile *x, unsigned int val)
-{
- return __atomic_exchange_n(x, val, __ATOMIC_SEQ_CST);
-}
-
-static inline void *vkd3d_atomic_exchange_pointer(void * volatile *x, void *val)
-{
- return __atomic_exchange_n(x, val, __ATOMIC_SEQ_CST);
-}
-# elif HAVE_SYNC_BOOL_COMPARE_AND_SWAP
-static inline unsigned int vkd3d_atomic_exchange(unsigned int volatile *x, unsigned int val)
-{
- unsigned int i;
- do
- {
- i = *x;
- } while (!__sync_bool_compare_and_swap(x, i, val));
- return i;
-}
-
-static inline void *vkd3d_atomic_exchange_pointer(void * volatile *x, void *val)
-{
- void *p;
- do
- {
- p = *x;
- } while (!__sync_bool_compare_and_swap(x, p, val));
- return p;
-}
-# else
-# error "vkd3d_atomic_exchange() not implemented for this platform"
-# endif
-
-#endif /* _WIN32 */
-
HRESULT vkd3d_create_thread(struct vkd3d_instance *instance,
PFN_vkd3d_thread thread_main, void *data, union vkd3d_thread_handle *thread);
HRESULT vkd3d_join_thread(struct vkd3d_instance *instance, union vkd3d_thread_handle *thread);
@@ -742,7 +666,7 @@ static inline bool vkd3d_view_incref(void *desc)
if (refcount <= 0)
return false;
}
- while (!vkd3d_atomic_compare_exchange(&h->refcount, refcount, refcount + 1));
+ while (!vkd3d_atomic_compare_exchange_u32(&h->refcount, refcount, refcount + 1));
return true;
}
@@ -1852,5 +1776,9 @@ struct vkd3d_shader_cache;
int vkd3d_shader_open_cache(struct vkd3d_shader_cache **cache);
unsigned int vkd3d_shader_cache_incref(struct vkd3d_shader_cache *cache);
unsigned int vkd3d_shader_cache_decref(struct vkd3d_shader_cache *cache);
+int vkd3d_shader_cache_put(struct vkd3d_shader_cache *cache,
+ const void *key, size_t key_size, const void *value, size_t value_size);
+int vkd3d_shader_cache_get(struct vkd3d_shader_cache *cache,
+ const void *key, size_t key_size, void *value, size_t *value_size);
#endif /* __VKD3D_PRIVATE_H */
--
2.43.0

View File

@ -1,937 +0,0 @@
From 9cd79b111e612defc44743beab2de36703bb1786 Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Wed, 15 May 2024 08:23:37 +1000
Subject: [PATCH] Updated vkd3d to 9e57039fce4040c8bfadaa73bf449c005912a83e.
---
libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 5 +
libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 8 +-
libs/vkd3d/libs/vkd3d-shader/dxil.c | 55 +++++
libs/vkd3d/libs/vkd3d-shader/hlsl.h | 7 +-
libs/vkd3d/libs/vkd3d-shader/hlsl.y | 3 +
libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 193 +++++++++++++-----
libs/vkd3d/libs/vkd3d-shader/ir.c | 9 +-
libs/vkd3d/libs/vkd3d-shader/spirv.c | 149 +++++++++++++-
.../libs/vkd3d-shader/vkd3d_shader_main.c | 2 +-
.../libs/vkd3d-shader/vkd3d_shader_private.h | 5 +
libs/vkd3d/libs/vkd3d/device.c | 97 ++++++++-
11 files changed, 463 insertions(+), 70 deletions(-)
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
index f2ad39f2f07..9abc2c4db70 100644
--- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
+++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
@@ -332,8 +332,10 @@ static const char * const shader_opcode_names[] =
[VKD3DSIH_WAVE_ACTIVE_BIT_AND ] = "wave_active_bit_and",
[VKD3DSIH_WAVE_ACTIVE_BIT_OR ] = "wave_active_bit_or",
[VKD3DSIH_WAVE_ACTIVE_BIT_XOR ] = "wave_active_bit_xor",
+ [VKD3DSIH_WAVE_ALL_BIT_COUNT ] = "wave_all_bit_count",
[VKD3DSIH_WAVE_ALL_TRUE ] = "wave_all_true",
[VKD3DSIH_WAVE_ANY_TRUE ] = "wave_any_true",
+ [VKD3DSIH_WAVE_IS_FIRST_LANE ] = "wave_is_first_lane",
[VKD3DSIH_WAVE_OP_ADD ] = "wave_op_add",
[VKD3DSIH_WAVE_OP_IMAX ] = "wave_op_imax",
[VKD3DSIH_WAVE_OP_IMIN ] = "wave_op_imin",
@@ -342,6 +344,9 @@ static const char * const shader_opcode_names[] =
[VKD3DSIH_WAVE_OP_MUL ] = "wave_op_mul",
[VKD3DSIH_WAVE_OP_UMAX ] = "wave_op_umax",
[VKD3DSIH_WAVE_OP_UMIN ] = "wave_op_umin",
+ [VKD3DSIH_WAVE_PREFIX_BIT_COUNT ] = "wave_prefix_bit_count",
+ [VKD3DSIH_WAVE_READ_LANE_AT ] = "wave_read_lane_at",
+ [VKD3DSIH_WAVE_READ_LANE_FIRST ] = "wave_read_lane_first",
[VKD3DSIH_XOR ] = "xor",
};
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
index 24a95224349..7c7c71e3c9a 100644
--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
@@ -1713,7 +1713,7 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffe
for (r = 0; r <= HLSL_REGSET_LAST; ++r)
{
- if (var->semantic.name || !var->regs[r].allocated)
+ if (var->semantic.name || !var->regs[r].allocated || !var->last_read)
continue;
++uniform_count;
@@ -1751,14 +1751,14 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffe
for (r = 0; r <= HLSL_REGSET_LAST; ++r)
{
- if (var->semantic.name || !var->regs[r].allocated)
+ if (var->semantic.name || !var->regs[r].allocated || !var->last_read)
continue;
put_u32(buffer, 0); /* name */
if (r == HLSL_REGSET_NUMERIC)
{
put_u32(buffer, vkd3d_make_u32(D3DXRS_FLOAT4, var->regs[r].id));
- put_u32(buffer, var->data_type->reg_size[r] / 4);
+ put_u32(buffer, var->bind_count[r]);
}
else
{
@@ -1780,7 +1780,7 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffe
{
size_t var_offset, name_offset;
- if (var->semantic.name || !var->regs[r].allocated)
+ if (var->semantic.name || !var->regs[r].allocated || !var->last_read)
continue;
var_offset = vars_start + (uniform_count * 5 * sizeof(uint32_t));
diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c
index 29f736364dc..605e97530c1 100644
--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c
+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c
@@ -446,17 +446,22 @@ enum dx_intrinsic_opcode
DX_STORE_PATCH_CONSTANT = 106,
DX_OUTPUT_CONTROL_POINT_ID = 107,
DX_PRIMITIVE_ID = 108,
+ DX_WAVE_IS_FIRST_LANE = 110,
DX_WAVE_GET_LANE_INDEX = 111,
DX_WAVE_GET_LANE_COUNT = 112,
DX_WAVE_ANY_TRUE = 113,
DX_WAVE_ALL_TRUE = 114,
DX_WAVE_ACTIVE_ALL_EQUAL = 115,
DX_WAVE_ACTIVE_BALLOT = 116,
+ DX_WAVE_READ_LANE_AT = 117,
+ DX_WAVE_READ_LANE_FIRST = 118,
DX_WAVE_ACTIVE_OP = 119,
DX_WAVE_ACTIVE_BIT = 120,
DX_WAVE_PREFIX_OP = 121,
DX_LEGACY_F32TOF16 = 130,
DX_LEGACY_F16TOF32 = 131,
+ DX_WAVE_ALL_BIT_COUNT = 135,
+ DX_WAVE_PREFIX_BIT_COUNT = 136,
DX_RAW_BUFFER_LOAD = 139,
DX_RAW_BUFFER_STORE = 140,
};
@@ -3816,6 +3821,8 @@ static enum vkd3d_shader_register_type register_type_from_dxil_semantic_kind(
{
switch (sysval_semantic)
{
+ case VKD3D_SHADER_SV_COVERAGE:
+ return VKD3DSPR_COVERAGE;
case VKD3D_SHADER_SV_DEPTH:
return VKD3DSPR_DEPTHOUT;
case VKD3D_SHADER_SV_DEPTH_GREATER_EQUAL:
@@ -4489,6 +4496,25 @@ static bool sm6_parser_emit_coordinate_construct(struct sm6_parser *sm6, const s
return sm6_parser_emit_reg_composite_construct(sm6, operand_regs, component_count, state, reg);
}
+static enum vkd3d_shader_opcode sm6_dx_map_void_op(enum dx_intrinsic_opcode op)
+{
+ switch (op)
+ {
+ case DX_WAVE_IS_FIRST_LANE:
+ return VKD3DSIH_WAVE_IS_FIRST_LANE;
+ default:
+ vkd3d_unreachable();
+ }
+}
+
+static void sm6_parser_emit_dx_void(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
+ const struct sm6_value **operands, struct function_emission_state *state)
+{
+ struct vkd3d_shader_instruction *ins = state->ins;
+ vsir_instruction_init(ins, &sm6->p.location, sm6_dx_map_void_op(op));
+ instruction_dst_param_init_ssa_scalar(ins, sm6);
+}
+
static enum vkd3d_shader_opcode map_dx_unary_op(enum dx_intrinsic_opcode op)
{
switch (op)
@@ -4555,10 +4581,16 @@ static enum vkd3d_shader_opcode map_dx_unary_op(enum dx_intrinsic_opcode op)
return VKD3DSIH_F16TOF32;
case DX_WAVE_ACTIVE_ALL_EQUAL:
return VKD3DSIH_WAVE_ACTIVE_ALL_EQUAL;
+ case DX_WAVE_ALL_BIT_COUNT:
+ return VKD3DSIH_WAVE_ALL_BIT_COUNT;
case DX_WAVE_ALL_TRUE:
return VKD3DSIH_WAVE_ALL_TRUE;
case DX_WAVE_ANY_TRUE:
return VKD3DSIH_WAVE_ANY_TRUE;
+ case DX_WAVE_PREFIX_BIT_COUNT:
+ return VKD3DSIH_WAVE_PREFIX_BIT_COUNT;
+ case DX_WAVE_READ_LANE_FIRST:
+ return VKD3DSIH_WAVE_READ_LANE_FIRST;
default:
vkd3d_unreachable();
}
@@ -4594,6 +4626,8 @@ static enum vkd3d_shader_opcode map_dx_binary_op(enum dx_intrinsic_opcode op, co
return VKD3DSIH_UMAX;
case DX_UMIN:
return VKD3DSIH_UMIN;
+ case DX_WAVE_READ_LANE_AT:
+ return VKD3DSIH_WAVE_READ_LANE_AT;
default:
vkd3d_unreachable();
}
@@ -6233,11 +6267,16 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] =
[DX_WAVE_ACTIVE_BALLOT ] = {"V", "1", sm6_parser_emit_dx_wave_active_ballot},
[DX_WAVE_ACTIVE_BIT ] = {"m", "Rc", sm6_parser_emit_dx_wave_active_bit},
[DX_WAVE_ACTIVE_OP ] = {"n", "Rcc", sm6_parser_emit_dx_wave_op},
+ [DX_WAVE_ALL_BIT_COUNT ] = {"i", "1", sm6_parser_emit_dx_unary},
[DX_WAVE_ALL_TRUE ] = {"1", "1", sm6_parser_emit_dx_unary},
[DX_WAVE_ANY_TRUE ] = {"1", "1", sm6_parser_emit_dx_unary},
[DX_WAVE_GET_LANE_COUNT ] = {"i", "", sm6_parser_emit_dx_wave_builtin},
[DX_WAVE_GET_LANE_INDEX ] = {"i", "", sm6_parser_emit_dx_wave_builtin},
+ [DX_WAVE_IS_FIRST_LANE ] = {"1", "", sm6_parser_emit_dx_void},
+ [DX_WAVE_PREFIX_BIT_COUNT ] = {"i", "1", sm6_parser_emit_dx_unary},
[DX_WAVE_PREFIX_OP ] = {"n", "Rcc", sm6_parser_emit_dx_wave_op},
+ [DX_WAVE_READ_LANE_AT ] = {"n", "Ri", sm6_parser_emit_dx_binary},
+ [DX_WAVE_READ_LANE_FIRST ] = {"n", "R", sm6_parser_emit_dx_unary},
};
static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struct sm6_value *value, char info_type,
@@ -6697,6 +6736,15 @@ static void sm6_parser_emit_cmp2(struct sm6_parser *sm6, const struct dxil_recor
code = record->operands[i++];
+ /* dxcompiler occasionally emits bool not-equal-to-false, which is a no-op. Bool comparisons
+ * do not otherwise occur, so deleting these avoids the need for backend support. */
+ if (sm6_type_is_bool(type_a) && code == ICMP_NE && sm6_value_is_constant_zero(b))
+ {
+ ins->handler_idx = VKD3DSIH_NOP;
+ *dst = *a;
+ return;
+ }
+
if ((!is_int && !is_fp) || is_int != (code >= ICMP_EQ))
{
FIXME("Invalid operation %"PRIu64" on type class %u.\n", code, type_a->class);
@@ -8407,8 +8455,11 @@ static const enum vkd3d_shader_sysval_semantic sysval_semantic_table[] =
[SEMANTIC_KIND_VERTEXID] = VKD3D_SHADER_SV_VERTEX_ID,
[SEMANTIC_KIND_INSTANCEID] = VKD3D_SHADER_SV_INSTANCE_ID,
[SEMANTIC_KIND_POSITION] = VKD3D_SHADER_SV_POSITION,
+ [SEMANTIC_KIND_CLIPDISTANCE] = VKD3D_SHADER_SV_CLIP_DISTANCE,
+ [SEMANTIC_KIND_CULLDISTANCE] = VKD3D_SHADER_SV_CULL_DISTANCE,
[SEMANTIC_KIND_PRIMITIVEID] = VKD3D_SHADER_SV_PRIMITIVE_ID,
[SEMANTIC_KIND_ISFRONTFACE] = VKD3D_SHADER_SV_IS_FRONT_FACE,
+ [SEMANTIC_KIND_COVERAGE] = VKD3D_SHADER_SV_COVERAGE,
[SEMANTIC_KIND_TARGET] = VKD3D_SHADER_SV_TARGET,
[SEMANTIC_KIND_DEPTH] = VKD3D_SHADER_SV_DEPTH,
[SEMANTIC_KIND_DEPTHLESSEQUAL] = VKD3D_SHADER_SV_DEPTH_LESS_EQUAL,
@@ -9358,6 +9409,10 @@ static enum vkd3d_result sm6_parser_read_signature(struct sm6_parser *sm6, const
e->used_mask <<= index;
}
+ /* DXIL reads/writes uint for bool I/O. */
+ if (e->component_type == VKD3D_SHADER_COMPONENT_BOOL)
+ e->component_type = VKD3D_SHADER_COMPONENT_UINT;
+
m = element_node->operands[4];
if (!sm6_metadata_value_is_node(m))
{
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
index a89e43f9bf2..08a017874ae 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
@@ -447,9 +447,10 @@ struct hlsl_ir_var
enum hlsl_sampler_dim sampler_dim;
struct vkd3d_shader_location first_sampler_dim_loc;
} *objects_usage[HLSL_REGSET_LAST_OBJECT + 1];
- /* Minimum number of binds required to include all object components actually used in the shader.
- * It may be less than the allocation size, e.g. for texture arrays. */
- unsigned int bind_count[HLSL_REGSET_LAST_OBJECT + 1];
+ /* Minimum number of binds required to include all components actually used in the shader.
+ * It may be less than the allocation size, e.g. for texture arrays.
+ * The bind_count for HLSL_REGSET_NUMERIC is only used in uniforms for now. */
+ unsigned int bind_count[HLSL_REGSET_LAST + 1];
/* Whether the shader performs dereferences with non-constant offsets in the variable. */
bool indexable;
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
index 79317bb0545..c6b6219eb4b 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
@@ -168,6 +168,9 @@ static struct list *make_empty_list(struct hlsl_ctx *ctx)
static void destroy_block(struct hlsl_block *block)
{
+ if (!block)
+ return;
+
hlsl_block_cleanup(block);
vkd3d_free(block);
}
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
index 8882deaf6cd..26179042082 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
@@ -4248,34 +4248,67 @@ static bool track_object_components_sampler_dim(struct hlsl_ctx *ctx, struct hls
return false;
}
-static bool track_object_components_usage(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
+static void register_deref_usage(struct hlsl_ctx *ctx, struct hlsl_deref *deref)
{
- struct hlsl_ir_resource_load *load;
- struct hlsl_ir_var *var;
- enum hlsl_regset regset;
+ struct hlsl_ir_var *var = deref->var;
+ enum hlsl_regset regset = hlsl_deref_get_regset(ctx, deref);
+ uint32_t required_bind_count;
+ struct hlsl_type *type;
unsigned int index;
- if (instr->type != HLSL_IR_RESOURCE_LOAD)
- return false;
-
- load = hlsl_ir_resource_load(instr);
- var = load->resource.var;
+ if (!hlsl_regset_index_from_deref(ctx, deref, regset, &index))
+ return;
- regset = hlsl_deref_get_regset(ctx, &load->resource);
+ if (regset <= HLSL_REGSET_LAST_OBJECT)
+ {
+ var->objects_usage[regset][index].used = true;
+ var->bind_count[regset] = max(var->bind_count[regset], index + 1);
+ }
+ else if (regset == HLSL_REGSET_NUMERIC)
+ {
+ type = hlsl_deref_get_type(ctx, deref);
- if (!hlsl_regset_index_from_deref(ctx, &load->resource, regset, &index))
- return false;
+ hlsl_regset_index_from_deref(ctx, deref, regset, &index);
+ required_bind_count = align(index + type->reg_size[regset], 4) / 4;
+ var->bind_count[regset] = max(var->bind_count[regset], required_bind_count);
+ }
+ else
+ {
+ vkd3d_unreachable();
+ }
+}
- var->objects_usage[regset][index].used = true;
- var->bind_count[regset] = max(var->bind_count[regset], index + 1);
- if (load->sampler.var)
+static bool track_components_usage(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
+{
+ switch (instr->type)
{
- var = load->sampler.var;
- if (!hlsl_regset_index_from_deref(ctx, &load->sampler, HLSL_REGSET_SAMPLERS, &index))
- return false;
+ case HLSL_IR_LOAD:
+ {
+ struct hlsl_ir_load *load = hlsl_ir_load(instr);
+
+ if (!load->src.var->is_uniform)
+ return false;
+
+ /* These will are handled by validate_static_object_references(). */
+ if (hlsl_deref_get_regset(ctx, &load->src) != HLSL_REGSET_NUMERIC)
+ return false;
+
+ register_deref_usage(ctx, &load->src);
+ break;
+ }
+
+ case HLSL_IR_RESOURCE_LOAD:
+ register_deref_usage(ctx, &hlsl_ir_resource_load(instr)->resource);
+ if (hlsl_ir_resource_load(instr)->sampler.var)
+ register_deref_usage(ctx, &hlsl_ir_resource_load(instr)->sampler);
+ break;
- var->objects_usage[HLSL_REGSET_SAMPLERS][index].used = true;
- var->bind_count[HLSL_REGSET_SAMPLERS] = max(var->bind_count[HLSL_REGSET_SAMPLERS], index + 1);
+ case HLSL_IR_RESOURCE_STORE:
+ register_deref_usage(ctx, &hlsl_ir_resource_store(instr)->resource);
+ break;
+
+ default:
+ break;
}
return false;
@@ -4520,16 +4553,52 @@ static void allocate_const_registers_recurse(struct hlsl_ctx *ctx,
}
}
+static void sort_uniform_by_numeric_bind_count(struct list *sorted, struct hlsl_ir_var *to_sort)
+{
+ struct hlsl_ir_var *var;
+
+ list_remove(&to_sort->extern_entry);
+
+ LIST_FOR_EACH_ENTRY(var, sorted, struct hlsl_ir_var, extern_entry)
+ {
+ uint32_t to_sort_size = to_sort->bind_count[HLSL_REGSET_NUMERIC];
+ uint32_t var_size = var->bind_count[HLSL_REGSET_NUMERIC];
+
+ if (to_sort_size > var_size)
+ {
+ list_add_before(&var->extern_entry, &to_sort->extern_entry);
+ return;
+ }
+ }
+
+ list_add_tail(sorted, &to_sort->extern_entry);
+}
+
+static void sort_uniforms_by_numeric_bind_count(struct hlsl_ctx *ctx)
+{
+ struct list sorted = LIST_INIT(sorted);
+ struct hlsl_ir_var *var, *next;
+
+ LIST_FOR_EACH_ENTRY_SAFE(var, next, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
+ {
+ if (var->is_uniform)
+ sort_uniform_by_numeric_bind_count(&sorted, var);
+ }
+ list_move_tail(&ctx->extern_vars, &sorted);
+}
+
static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func)
{
struct register_allocator allocator = {0};
struct hlsl_ir_var *var;
+ sort_uniforms_by_numeric_bind_count(ctx);
+
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
{
unsigned int reg_size = var->data_type->reg_size[HLSL_REGSET_NUMERIC];
- if (!var->is_uniform || !var->last_read || reg_size == 0)
+ if (!var->is_uniform || reg_size == 0)
continue;
if (var->reg_reservation.reg_type == 'c')
@@ -4560,15 +4629,14 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
{
- unsigned int reg_size = var->data_type->reg_size[HLSL_REGSET_NUMERIC];
+ unsigned int alloc_size = 4 * var->bind_count[HLSL_REGSET_NUMERIC];
- if (!var->is_uniform || !var->last_read || reg_size == 0)
+ if (!var->is_uniform || alloc_size == 0)
continue;
if (!var->regs[HLSL_REGSET_NUMERIC].allocated)
{
- var->regs[HLSL_REGSET_NUMERIC] = allocate_numeric_registers_for_type(ctx, &allocator,
- 1, UINT_MAX, var->data_type);
+ var->regs[HLSL_REGSET_NUMERIC] = allocate_range(ctx, &allocator, 1, UINT_MAX, alloc_size);
TRACE("Allocated %s to %s.\n", var->name,
debug_register('c', var->regs[HLSL_REGSET_NUMERIC], var->data_type));
}
@@ -5102,14 +5170,15 @@ bool hlsl_component_index_range_from_deref(struct hlsl_ctx *ctx, const struct hl
return true;
}
+/* Retrieves true if the index is constant, and false otherwise. In the latter case, the maximum
+ * possible index is retrieved, assuming there is not out-of-bounds access. */
bool hlsl_regset_index_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref,
enum hlsl_regset regset, unsigned int *index)
{
struct hlsl_type *type = deref->var->data_type;
+ bool index_is_constant = true;
unsigned int i;
- assert(regset <= HLSL_REGSET_LAST_OBJECT);
-
*index = 0;
for (i = 0; i < deref->path_len; ++i)
@@ -5118,37 +5187,62 @@ bool hlsl_regset_index_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref
unsigned int idx = 0;
assert(path_node);
- if (path_node->type != HLSL_IR_CONSTANT)
- return false;
+ if (path_node->type == HLSL_IR_CONSTANT)
+ {
+ /* We should always have generated a cast to UINT. */
+ assert(path_node->data_type->class == HLSL_CLASS_SCALAR
+ && path_node->data_type->e.numeric.type == HLSL_TYPE_UINT);
- /* We should always have generated a cast to UINT. */
- assert(path_node->data_type->class == HLSL_CLASS_SCALAR
- && path_node->data_type->e.numeric.type == HLSL_TYPE_UINT);
+ idx = hlsl_ir_constant(path_node)->value.u[0].u;
- idx = hlsl_ir_constant(path_node)->value.u[0].u;
+ switch (type->class)
+ {
+ case HLSL_CLASS_ARRAY:
+ if (idx >= type->e.array.elements_count)
+ return false;
- switch (type->class)
+ *index += idx * type->e.array.type->reg_size[regset];
+ break;
+
+ case HLSL_CLASS_STRUCT:
+ *index += type->e.record.fields[idx].reg_offset[regset];
+ break;
+
+ case HLSL_CLASS_MATRIX:
+ *index += 4 * idx;
+ break;
+
+ default:
+ vkd3d_unreachable();
+ }
+ }
+ else
{
- case HLSL_CLASS_ARRAY:
- if (idx >= type->e.array.elements_count)
- return false;
+ index_is_constant = false;
- *index += idx * type->e.array.type->reg_size[regset];
- break;
+ switch (type->class)
+ {
+ case HLSL_CLASS_ARRAY:
+ idx = type->e.array.elements_count - 1;
+ *index += idx * type->e.array.type->reg_size[regset];
+ break;
- case HLSL_CLASS_STRUCT:
- *index += type->e.record.fields[idx].reg_offset[regset];
- break;
+ case HLSL_CLASS_MATRIX:
+ idx = hlsl_type_major_size(type) - 1;
+ *index += idx * 4;
+ break;
- default:
- vkd3d_unreachable();
+ default:
+ vkd3d_unreachable();
+ }
}
type = hlsl_get_element_type_from_path_index(ctx, type, path_node);
}
- assert(type->reg_size[regset] == 1);
- return true;
+ assert(!(regset <= HLSL_REGSET_LAST_OBJECT) || (type->reg_size[regset] == 1));
+ assert(!(regset == HLSL_REGSET_NUMERIC) || type->reg_size[regset] <= 4);
+ return index_is_constant;
}
bool hlsl_offset_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, unsigned int *offset)
@@ -5440,7 +5534,12 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry
hlsl_transform_ir(ctx, track_object_components_sampler_dim, body, NULL);
if (profile->major_version >= 4)
hlsl_transform_ir(ctx, lower_combined_samples, body, NULL);
- hlsl_transform_ir(ctx, track_object_components_usage, body, NULL);
+
+ do
+ compute_liveness(ctx, entry_func);
+ while (hlsl_transform_ir(ctx, dce, body, NULL));
+
+ hlsl_transform_ir(ctx, track_components_usage, body, NULL);
sort_synthetic_separated_samplers_first(ctx);
if (profile->major_version < 4)
diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c
index c6ecbdd9e46..2c78447e382 100644
--- a/libs/vkd3d/libs/vkd3d-shader/ir.c
+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c
@@ -5748,11 +5748,6 @@ static void vsir_validate_instruction(struct validation_context *ctx)
instruction->declaration.max_tessellation_factor);
return;
- /* The DXIL parser can generate these outside phases, but this is not an issue. */
- case VKD3DSIH_DCL_INPUT:
- case VKD3DSIH_DCL_OUTPUT:
- return;
-
case VKD3DSIH_DCL_INPUT_PRIMITIVE:
if (instruction->declaration.primitive_type.type == VKD3D_PT_UNDEFINED
|| instruction->declaration.primitive_type.type >= VKD3D_PT_COUNT)
@@ -5810,7 +5805,9 @@ static void vsir_validate_instruction(struct validation_context *ctx)
break;
}
- if (version->type == VKD3D_SHADER_TYPE_HULL && ctx->phase == VKD3DSIH_INVALID)
+ /* Only DCL instructions may occur outside hull shader phases. */
+ if (!vsir_instruction_is_dcl(instruction) && version->type == VKD3D_SHADER_TYPE_HULL
+ && ctx->phase == VKD3DSIH_INVALID)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_HANDLER,
"Instruction %#x appear before any phase instruction in a hull shader.",
instruction->handler_idx);
diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c
index 813e20fdcd7..4ee8e6bba4c 100644
--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c
@@ -1760,6 +1760,45 @@ static uint32_t vkd3d_spirv_build_op_group_nonuniform_ballot(struct vkd3d_spirv_
result_type, vkd3d_spirv_get_op_scope_subgroup(builder), val_id);
}
+static uint32_t vkd3d_spirv_build_op_group_nonuniform_ballot_bit_count(struct vkd3d_spirv_builder *builder,
+ uint32_t result_type, SpvGroupOperation group_op, uint32_t val_id)
+{
+ vkd3d_spirv_enable_capability(builder, SpvCapabilityGroupNonUniformBallot);
+ return vkd3d_spirv_build_op_tr3(builder, &builder->function_stream, SpvOpGroupNonUniformBallotBitCount,
+ result_type, vkd3d_spirv_get_op_scope_subgroup(builder), group_op, val_id);
+}
+
+static uint32_t vkd3d_spirv_build_op_group_nonuniform_elect(struct vkd3d_spirv_builder *builder)
+{
+ vkd3d_spirv_enable_capability(builder, SpvCapabilityGroupNonUniform);
+ return vkd3d_spirv_build_op_tr1(builder, &builder->function_stream, SpvOpGroupNonUniformElect,
+ vkd3d_spirv_get_op_type_bool(builder), vkd3d_spirv_get_op_scope_subgroup(builder));
+}
+
+static uint32_t vkd3d_spirv_build_op_group_nonuniform_broadcast(struct vkd3d_spirv_builder *builder,
+ uint32_t result_type, uint32_t val_id, uint32_t lane_id)
+{
+ vkd3d_spirv_enable_capability(builder, SpvCapabilityGroupNonUniformBallot);
+ return vkd3d_spirv_build_op_tr3(builder, &builder->function_stream, SpvOpGroupNonUniformBroadcast, result_type,
+ vkd3d_spirv_get_op_scope_subgroup(builder), val_id, lane_id);
+}
+
+static uint32_t vkd3d_spirv_build_op_group_nonuniform_shuffle(struct vkd3d_spirv_builder *builder,
+ uint32_t result_type, uint32_t val_id, uint32_t lane_id)
+{
+ vkd3d_spirv_enable_capability(builder, SpvCapabilityGroupNonUniformShuffle);
+ return vkd3d_spirv_build_op_tr3(builder, &builder->function_stream, SpvOpGroupNonUniformShuffle, result_type,
+ vkd3d_spirv_get_op_scope_subgroup(builder), val_id, lane_id);
+}
+
+static uint32_t vkd3d_spirv_build_op_group_nonuniform_broadcast_first(struct vkd3d_spirv_builder *builder,
+ uint32_t result_type, uint32_t val_id)
+{
+ vkd3d_spirv_enable_capability(builder, SpvCapabilityGroupNonUniformBallot);
+ return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, SpvOpGroupNonUniformBroadcastFirst,
+ result_type, vkd3d_spirv_get_op_scope_subgroup(builder), val_id);
+}
+
static uint32_t vkd3d_spirv_build_op_glsl_std450_tr1(struct vkd3d_spirv_builder *builder,
enum GLSLstd450 op, uint32_t result_type, uint32_t operand)
{
@@ -3602,8 +3641,9 @@ static void spirv_compiler_emit_dereference_register(struct spirv_compiler *comp
indexes[index_count++] = spirv_compiler_emit_register_addressing(compiler, &reg->idx[0]);
}
+ /* Alignment is supported only in the Kernel execution model and is an optimisation only. */
if (reg->alignment)
- WARN("Ignoring alignment %u.\n", reg->alignment);
+ TRACE("Ignoring alignment %u.\n", reg->alignment);
if (index_count)
{
@@ -5827,7 +5867,7 @@ static void spirv_compiler_emit_dcl_global_flags(struct spirv_compiler *compiler
if (flags & ~(VKD3DSGF_REFACTORING_ALLOWED | VKD3DSGF_ENABLE_RAW_AND_STRUCTURED_BUFFERS))
FIXME("Unhandled global flags %#"PRIx64".\n", (uint64_t)flags);
- else
+ else if (flags)
WARN("Unhandled global flags %#"PRIx64".\n", (uint64_t)flags);
}
@@ -5889,8 +5929,9 @@ static void spirv_compiler_emit_dcl_indexable_temp(struct spirv_compiler *compil
vsir_register_init(&reg, VKD3DSPR_IDXTEMP, VKD3D_DATA_FLOAT, 1);
reg.idx[0].offset = temp->register_idx;
+ /* Alignment is supported only in the Kernel execution model and is an optimisation only. */
if (temp->alignment)
- WARN("Ignoring alignment %u.\n", temp->alignment);
+ TRACE("Ignoring alignment %u.\n", temp->alignment);
function_location = spirv_compiler_get_current_function_location(compiler);
vkd3d_spirv_begin_function_stream_insertion(builder, function_location);
@@ -9801,18 +9842,26 @@ static void spirv_compiler_emit_wave_bool_op(struct spirv_compiler *compiler,
spirv_compiler_emit_store_dst(compiler, dst, val_id);
}
-static void spirv_compiler_emit_wave_active_ballot(struct spirv_compiler *compiler,
- const struct vkd3d_shader_instruction *instruction)
+static uint32_t spirv_compiler_emit_group_nonuniform_ballot(struct spirv_compiler *compiler,
+ const struct vkd3d_shader_src_param *src)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
- const struct vkd3d_shader_dst_param *dst = instruction->dst;
- const struct vkd3d_shader_src_param *src = instruction->src;
uint32_t type_id, val_id;
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, VKD3D_VEC4_SIZE);
val_id = spirv_compiler_emit_load_src(compiler, src, VKD3DSP_WRITEMASK_0);
val_id = vkd3d_spirv_build_op_group_nonuniform_ballot(builder, type_id, val_id);
+ return val_id;
+}
+
+static void spirv_compiler_emit_wave_active_ballot(struct spirv_compiler *compiler,
+ const struct vkd3d_shader_instruction *instruction)
+{
+ const struct vkd3d_shader_dst_param *dst = instruction->dst;
+ uint32_t val_id;
+
+ val_id = spirv_compiler_emit_group_nonuniform_ballot(compiler, instruction->src);
spirv_compiler_emit_store_dst(compiler, dst, val_id);
}
@@ -9871,6 +9920,79 @@ static void spirv_compiler_emit_wave_alu_op(struct spirv_compiler *compiler,
spirv_compiler_emit_store_dst(compiler, dst, val_id);
}
+static void spirv_compiler_emit_wave_bit_count(struct spirv_compiler *compiler,
+ const struct vkd3d_shader_instruction *instruction)
+{
+ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
+ const struct vkd3d_shader_dst_param *dst = instruction->dst;
+ SpvGroupOperation group_op;
+ uint32_t type_id, val_id;
+
+ group_op = (instruction->handler_idx == VKD3DSIH_WAVE_PREFIX_BIT_COUNT) ? SpvGroupOperationExclusiveScan
+ : SpvGroupOperationReduce;
+
+ val_id = spirv_compiler_emit_group_nonuniform_ballot(compiler, instruction->src);
+ type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1);
+ val_id = vkd3d_spirv_build_op_group_nonuniform_ballot_bit_count(builder, type_id, group_op, val_id);
+
+ spirv_compiler_emit_store_dst(compiler, dst, val_id);
+}
+
+static void spirv_compiler_emit_wave_is_first_lane(struct spirv_compiler *compiler,
+ const struct vkd3d_shader_instruction *instruction)
+{
+ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
+ const struct vkd3d_shader_dst_param *dst = instruction->dst;
+ uint32_t val_id;
+
+ val_id = vkd3d_spirv_build_op_group_nonuniform_elect(builder);
+ spirv_compiler_emit_store_dst(compiler, dst, val_id);
+}
+
+static void spirv_compiler_emit_wave_read_lane_at(struct spirv_compiler *compiler,
+ const struct vkd3d_shader_instruction *instruction)
+{
+ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
+ const struct vkd3d_shader_dst_param *dst = instruction->dst;
+ const struct vkd3d_shader_src_param *src = instruction->src;
+ uint32_t type_id, lane_id, val_id;
+
+ type_id = vkd3d_spirv_get_type_id_for_data_type(builder, dst->reg.data_type,
+ vsir_write_mask_component_count(dst->write_mask));
+ val_id = spirv_compiler_emit_load_src(compiler, &src[0], dst->write_mask);
+ lane_id = spirv_compiler_emit_load_src(compiler, &src[1], VKD3DSP_WRITEMASK_0);
+
+ /* TODO: detect values loaded from a const buffer? */
+ if (register_is_constant_or_undef(&src[1].reg))
+ {
+ /* Uniform lane_id only. */
+ val_id = vkd3d_spirv_build_op_group_nonuniform_broadcast(builder, type_id, val_id, lane_id);
+ }
+ else
+ {
+ /* WaveReadLaneAt supports non-uniform lane ids, so if lane_id is not constant it may not be uniform. */
+ val_id = vkd3d_spirv_build_op_group_nonuniform_shuffle(builder, type_id, val_id, lane_id);
+ }
+
+ spirv_compiler_emit_store_dst(compiler, dst, val_id);
+}
+
+static void spirv_compiler_emit_wave_read_lane_first(struct spirv_compiler *compiler,
+ const struct vkd3d_shader_instruction *instruction)
+{
+ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
+ const struct vkd3d_shader_dst_param *dst = instruction->dst;
+ const struct vkd3d_shader_src_param *src = instruction->src;
+ uint32_t type_id, val_id;
+
+ type_id = vkd3d_spirv_get_type_id_for_data_type(builder, dst->reg.data_type,
+ vsir_write_mask_component_count(dst->write_mask));
+ val_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask);
+ val_id = vkd3d_spirv_build_op_group_nonuniform_broadcast_first(builder, type_id, val_id);
+
+ spirv_compiler_emit_store_dst(compiler, dst, val_id);
+}
+
/* This function is called after declarations are processed. */
static void spirv_compiler_emit_main_prolog(struct spirv_compiler *compiler)
{
@@ -10236,6 +10358,19 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler,
case VKD3DSIH_WAVE_OP_UMIN:
spirv_compiler_emit_wave_alu_op(compiler, instruction);
break;
+ case VKD3DSIH_WAVE_ALL_BIT_COUNT:
+ case VKD3DSIH_WAVE_PREFIX_BIT_COUNT:
+ spirv_compiler_emit_wave_bit_count(compiler, instruction);
+ break;
+ case VKD3DSIH_WAVE_IS_FIRST_LANE:
+ spirv_compiler_emit_wave_is_first_lane(compiler, instruction);
+ break;
+ case VKD3DSIH_WAVE_READ_LANE_AT:
+ spirv_compiler_emit_wave_read_lane_at(compiler, instruction);
+ break;
+ case VKD3DSIH_WAVE_READ_LANE_FIRST:
+ spirv_compiler_emit_wave_read_lane_first(compiler, instruction);
+ break;
case VKD3DSIH_DCL:
case VKD3DSIH_DCL_HS_MAX_TESSFACTOR:
case VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT:
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
index 29b2c1482a9..c15dae52c50 100644
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -2004,7 +2004,7 @@ void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator,
{
void *params;
- if (count > allocator->count - allocator->index)
+ if (!allocator->current || count > allocator->count - allocator->index)
{
struct vkd3d_shader_param_node *next;
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
index bf9d3038f08..742189cefbb 100644
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -533,8 +533,10 @@ enum vkd3d_shader_opcode
VKD3DSIH_WAVE_ACTIVE_BIT_AND,
VKD3DSIH_WAVE_ACTIVE_BIT_OR,
VKD3DSIH_WAVE_ACTIVE_BIT_XOR,
+ VKD3DSIH_WAVE_ALL_BIT_COUNT,
VKD3DSIH_WAVE_ALL_TRUE,
VKD3DSIH_WAVE_ANY_TRUE,
+ VKD3DSIH_WAVE_IS_FIRST_LANE,
VKD3DSIH_WAVE_OP_ADD,
VKD3DSIH_WAVE_OP_IMAX,
VKD3DSIH_WAVE_OP_IMIN,
@@ -543,6 +545,9 @@ enum vkd3d_shader_opcode
VKD3DSIH_WAVE_OP_MUL,
VKD3DSIH_WAVE_OP_UMAX,
VKD3DSIH_WAVE_OP_UMIN,
+ VKD3DSIH_WAVE_PREFIX_BIT_COUNT,
+ VKD3DSIH_WAVE_READ_LANE_AT,
+ VKD3DSIH_WAVE_READ_LANE_FIRST,
VKD3DSIH_XOR,
VKD3DSIH_INVALID,
diff --git a/libs/vkd3d/libs/vkd3d/device.c b/libs/vkd3d/libs/vkd3d/device.c
index 36d8433939a..8b817264e63 100644
--- a/libs/vkd3d/libs/vkd3d/device.c
+++ b/libs/vkd3d/libs/vkd3d/device.c
@@ -3487,12 +3487,20 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device9
return E_INVALIDARG;
}
+ if (data->HighestShaderModel != D3D_SHADER_MODEL_5_1
+ && (data->HighestShaderModel < D3D_SHADER_MODEL_6_0
+ || data->HighestShaderModel > D3D_HIGHEST_SHADER_MODEL))
+ {
+ WARN("Unknown shader model %#x.\n", data->HighestShaderModel);
+ return E_INVALIDARG;
+ }
+
TRACE("Request shader model %#x.\n", data->HighestShaderModel);
#ifdef VKD3D_SHADER_UNSUPPORTED_DXIL
- data->HighestShaderModel = D3D_SHADER_MODEL_6_0;
+ data->HighestShaderModel = min(data->HighestShaderModel, D3D_SHADER_MODEL_6_0);
#else
- data->HighestShaderModel = D3D_SHADER_MODEL_5_1;
+ data->HighestShaderModel = min(data->HighestShaderModel, D3D_SHADER_MODEL_5_1);
#endif
TRACE("Shader model %#x.\n", data->HighestShaderModel);
@@ -3911,6 +3919,91 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device9
return S_OK;
}
+ case D3D12_FEATURE_D3D12_OPTIONS14:
+ {
+ D3D12_FEATURE_DATA_D3D12_OPTIONS14 *data = feature_data;
+
+ if (feature_data_size != sizeof(*data))
+ {
+ WARN("Invalid size %u.\n", feature_data_size);
+ }
+
+ data->AdvancedTextureOpsSupported = FALSE;
+ data->WriteableMSAATexturesSupported = FALSE;
+ data->IndependentFrontAndBackStencilRefMaskSupported = FALSE;
+
+ TRACE("Advanced texture ops %#x.\n", data->AdvancedTextureOpsSupported);
+ TRACE("Writeable MSAA textures %#x.\n", data->WriteableMSAATexturesSupported);
+ TRACE("Independent front and back stencil ref mask %#x.\n", data->IndependentFrontAndBackStencilRefMaskSupported);
+ return S_OK;
+ }
+
+ case D3D12_FEATURE_D3D12_OPTIONS15:
+ {
+ D3D12_FEATURE_DATA_D3D12_OPTIONS15 *data = feature_data;
+
+ if (feature_data_size != sizeof(*data))
+ {
+ WARN("Invalid size %u.\n", feature_data_size);
+ }
+
+ data->TriangleFanSupported = FALSE;
+ data->DynamicIndexBufferStripCutSupported = FALSE;
+
+ TRACE("Triangle fan %#x.\n", data->TriangleFanSupported);
+ TRACE("Dynamic index buffer strip cut %#x.\n", data->DynamicIndexBufferStripCutSupported);
+ return S_OK;
+ }
+
+ case D3D12_FEATURE_D3D12_OPTIONS16:
+ {
+ D3D12_FEATURE_DATA_D3D12_OPTIONS16 *data = feature_data;
+
+ if (feature_data_size != sizeof(*data))
+ {
+ WARN("Invalid size %u.\n", feature_data_size);
+ }
+
+ data->DynamicDepthBiasSupported = FALSE;
+ data->GPUUploadHeapSupported = FALSE;
+
+ TRACE("Dynamic depth bias %#x.\n", data->DynamicDepthBiasSupported);
+ TRACE("GPU upload heap %#x.\n", data->GPUUploadHeapSupported);
+ return S_OK;
+ }
+
+ case D3D12_FEATURE_D3D12_OPTIONS17:
+ {
+ D3D12_FEATURE_DATA_D3D12_OPTIONS17 *data = feature_data;
+
+ if (feature_data_size != sizeof(*data))
+ {
+ WARN("Invalid size %u.\n", feature_data_size);
+ }
+
+ data->NonNormalizedCoordinateSamplersSupported = FALSE;
+ data->ManualWriteTrackingResourceSupported = FALSE;
+
+ TRACE("Non-normalized coordinate samplers %#x.\n", data->NonNormalizedCoordinateSamplersSupported);
+ TRACE("Manual write tracking resource %#x.\n", data->ManualWriteTrackingResourceSupported);
+ return S_OK;
+ }
+
+ case D3D12_FEATURE_D3D12_OPTIONS18:
+ {
+ D3D12_FEATURE_DATA_D3D12_OPTIONS18 *data = feature_data;
+
+ if (feature_data_size != sizeof(*data))
+ {
+ WARN("Invalid size %u.\n", feature_data_size);
+ }
+
+ data->RenderPassesValid = FALSE;
+
+ TRACE("Render passes valid %#x.\n", data->RenderPassesValid);
+ return S_OK;
+ }
+
default:
FIXME("Unhandled feature %#x.\n", feature);
return E_NOTIMPL;
--
2.43.0

View File

@ -1,153 +0,0 @@
From cda6dd1902e0113ad3730c1f696138b668bbfacb Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Thu, 16 May 2024 11:56:37 +1000
Subject: [PATCH] Updated vkd3d to 061dc390367b4c83022d5fe1255f8d38f6b7ce9c.
---
libs/vkd3d/libs/vkd3d-shader/hlsl.h | 1 +
libs/vkd3d/libs/vkd3d-shader/hlsl.y | 13 ++--
libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 69 ++++++++++++---------
3 files changed, 47 insertions(+), 36 deletions(-)
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
index 08a017874ae..27814f3a56f 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
@@ -1250,6 +1250,7 @@ bool hlsl_clone_block(struct hlsl_ctx *ctx, struct hlsl_block *dst_block, const
void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl *func);
+void hlsl_run_const_passes(struct hlsl_ctx *ctx, struct hlsl_block *body);
int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func,
enum vkd3d_shader_target_type target_type, struct vkd3d_shader_code *out);
int hlsl_emit_effect_binary(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out);
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
index c6b6219eb4b..9c1bdef926d 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
@@ -1293,7 +1293,7 @@ static unsigned int evaluate_static_expression_as_uint(struct hlsl_ctx *ctx, str
struct hlsl_ir_node *node;
struct hlsl_block expr;
unsigned int ret = 0;
- bool progress;
+ struct hlsl_src src;
LIST_FOR_EACH_ENTRY(node, &block->instrs, struct hlsl_ir_node, entry)
{
@@ -1330,13 +1330,12 @@ static unsigned int evaluate_static_expression_as_uint(struct hlsl_ctx *ctx, str
return 0;
}
- do
- {
- progress = hlsl_transform_ir(ctx, hlsl_fold_constant_exprs, &expr, NULL);
- progress |= hlsl_copy_propagation_execute(ctx, &expr);
- } while (progress);
+ /* Wrap the node into a src to allow the reference to survive the multiple const passes. */
+ hlsl_src_from_node(&src, node_from_block(&expr));
+ hlsl_run_const_passes(ctx, &expr);
+ node = src.node;
+ hlsl_src_remove(&src);
- node = node_from_block(&expr);
if (node->type == HLSL_IR_CONSTANT)
{
constant = hlsl_ir_constant(node);
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
index 26179042082..27f16af51c5 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
@@ -5408,6 +5408,44 @@ static void remove_unreachable_code(struct hlsl_ctx *ctx, struct hlsl_block *bod
}
}
+void hlsl_run_const_passes(struct hlsl_ctx *ctx, struct hlsl_block *body)
+{
+ bool progress;
+
+ lower_ir(ctx, lower_matrix_swizzles, body);
+ lower_ir(ctx, lower_index_loads, body);
+
+ lower_ir(ctx, lower_broadcasts, body);
+ while (hlsl_transform_ir(ctx, fold_redundant_casts, body, NULL));
+ do
+ {
+ progress = hlsl_transform_ir(ctx, split_array_copies, body, NULL);
+ progress |= hlsl_transform_ir(ctx, split_struct_copies, body, NULL);
+ }
+ while (progress);
+ hlsl_transform_ir(ctx, split_matrix_copies, body, NULL);
+
+ lower_ir(ctx, lower_narrowing_casts, body);
+ lower_ir(ctx, lower_int_dot, body);
+ lower_ir(ctx, lower_int_division, body);
+ lower_ir(ctx, lower_int_modulus, body);
+ lower_ir(ctx, lower_int_abs, body);
+ lower_ir(ctx, lower_casts_to_bool, body);
+ lower_ir(ctx, lower_float_modulus, body);
+ hlsl_transform_ir(ctx, fold_redundant_casts, body, NULL);
+
+ do
+ {
+ progress = hlsl_transform_ir(ctx, hlsl_fold_constant_exprs, body, NULL);
+ progress |= hlsl_transform_ir(ctx, hlsl_fold_constant_identities, body, NULL);
+ progress |= hlsl_transform_ir(ctx, hlsl_fold_constant_swizzles, body, NULL);
+ progress |= hlsl_copy_propagation_execute(ctx, body);
+ progress |= hlsl_transform_ir(ctx, fold_swizzle_chains, body, NULL);
+ progress |= hlsl_transform_ir(ctx, remove_trivial_swizzles, body, NULL);
+ progress |= hlsl_transform_ir(ctx, remove_trivial_conditional_branches, body, NULL);
+ } while (progress);
+}
+
int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func,
enum vkd3d_shader_target_type target_type, struct vkd3d_shader_code *out)
{
@@ -5416,7 +5454,6 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry
struct recursive_call_ctx recursive_call_ctx;
struct hlsl_ir_var *var;
unsigned int i;
- bool progress;
list_move_head(&body->instrs, &ctx->static_initializers.instrs);
@@ -5494,35 +5531,9 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry
{
hlsl_transform_ir(ctx, lower_discard_neg, body, NULL);
}
- lower_ir(ctx, lower_broadcasts, body);
- while (hlsl_transform_ir(ctx, fold_redundant_casts, body, NULL));
- do
- {
- progress = hlsl_transform_ir(ctx, split_array_copies, body, NULL);
- progress |= hlsl_transform_ir(ctx, split_struct_copies, body, NULL);
- }
- while (progress);
- hlsl_transform_ir(ctx, split_matrix_copies, body, NULL);
- lower_ir(ctx, lower_narrowing_casts, body);
- lower_ir(ctx, lower_int_dot, body);
- lower_ir(ctx, lower_int_division, body);
- lower_ir(ctx, lower_int_modulus, body);
- lower_ir(ctx, lower_int_abs, body);
- lower_ir(ctx, lower_casts_to_bool, body);
- lower_ir(ctx, lower_float_modulus, body);
- hlsl_transform_ir(ctx, fold_redundant_casts, body, NULL);
- do
- {
- progress = hlsl_transform_ir(ctx, hlsl_fold_constant_exprs, body, NULL);
- progress |= hlsl_transform_ir(ctx, hlsl_fold_constant_identities, body, NULL);
- progress |= hlsl_transform_ir(ctx, hlsl_fold_constant_swizzles, body, NULL);
- progress |= hlsl_copy_propagation_execute(ctx, body);
- progress |= hlsl_transform_ir(ctx, fold_swizzle_chains, body, NULL);
- progress |= hlsl_transform_ir(ctx, remove_trivial_swizzles, body, NULL);
- progress |= hlsl_transform_ir(ctx, remove_trivial_conditional_branches, body, NULL);
- }
- while (progress);
+ hlsl_run_const_passes(ctx, body);
+
remove_unreachable_code(ctx, body);
hlsl_transform_ir(ctx, normalize_switch_cases, body, NULL);
--
2.43.0