wine-staging/patches/vkd3d-latest/0003-Updated-vkd3d-to-3dc43e8945f68c42268b8d5e43525b9e108.patch
2024-07-09 09:33:03 +10:00

1884 lines
75 KiB
Diff

From 15652871b2e9951be700c7baf1988ae5db09ccad Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Tue, 9 Jul 2024 07:22:05 +1000
Subject: [PATCH] Updated vkd3d to 3dc43e8945f68c42268b8d5e43525b9e10806f77.
---
libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 24 +-
libs/vkd3d/libs/vkd3d-shader/fx.c | 454 +++++++++++++++++---
libs/vkd3d/libs/vkd3d-shader/hlsl.c | 52 +++
libs/vkd3d/libs/vkd3d-shader/hlsl.h | 7 +
libs/vkd3d/libs/vkd3d-shader/hlsl.l | 4 +-
libs/vkd3d/libs/vkd3d-shader/hlsl.y | 306 ++++++++++---
libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 41 +-
libs/vkd3d/libs/vkd3d-shader/ir.c | 31 +-
libs/vkd3d/libs/vkd3d-shader/tpf.c | 3 +
libs/vkd3d/libs/vkd3d/command.c | 5 +-
libs/vkd3d/libs/vkd3d/device.c | 1 +
libs/vkd3d/libs/vkd3d/vkd3d_private.h | 1 +
12 files changed, 793 insertions(+), 136 deletions(-)
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
index 3665b99aed7..2482efc55d2 100644
--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
@@ -1497,13 +1497,16 @@ D3DXPARAMETER_CLASS hlsl_sm1_class(const struct hlsl_type *type)
case HLSL_CLASS_TEXTURE:
case HLSL_CLASS_VERTEX_SHADER:
return D3DXPC_OBJECT;
+ case HLSL_CLASS_DEPTH_STENCIL_STATE:
case HLSL_CLASS_DEPTH_STENCIL_VIEW:
case HLSL_CLASS_EFFECT_GROUP:
case HLSL_CLASS_PASS:
+ case HLSL_CLASS_RASTERIZER_STATE:
case HLSL_CLASS_RENDER_TARGET_VIEW:
case HLSL_CLASS_TECHNIQUE:
case HLSL_CLASS_UAV:
case HLSL_CLASS_VOID:
+ case HLSL_CLASS_CONSTANT_BUFFER:
break;
}
@@ -1593,13 +1596,16 @@ D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type)
case HLSL_CLASS_VERTEX_SHADER:
return D3DXPT_VERTEXSHADER;
+ case HLSL_CLASS_DEPTH_STENCIL_STATE:
case HLSL_CLASS_DEPTH_STENCIL_VIEW:
case HLSL_CLASS_EFFECT_GROUP:
case HLSL_CLASS_PASS:
+ case HLSL_CLASS_RASTERIZER_STATE:
case HLSL_CLASS_RENDER_TARGET_VIEW:
case HLSL_CLASS_TECHNIQUE:
case HLSL_CLASS_UAV:
case HLSL_CLASS_VOID:
+ case HLSL_CLASS_CONSTANT_BUFFER:
break;
}
@@ -1859,7 +1865,7 @@ struct sm1_instruction
D3DSHADER_PARAM_SRCMOD_TYPE mod;
unsigned int swizzle;
uint32_t reg;
- } srcs[3];
+ } srcs[4];
unsigned int src_count;
unsigned int has_dst;
@@ -2567,6 +2573,8 @@ static void write_sm1_resource_load(struct hlsl_ctx *ctx, struct vkd3d_bytecode_
{
const struct hlsl_ir_resource_load *load = hlsl_ir_resource_load(instr);
struct hlsl_ir_node *coords = load->coords.node;
+ struct hlsl_ir_node *ddx = load->ddx.node;
+ struct hlsl_ir_node *ddy = load->ddy.node;
unsigned int sampler_offset, reg_id;
struct sm1_instruction sm1_instr;
@@ -2607,6 +2615,20 @@ static void write_sm1_resource_load(struct hlsl_ctx *ctx, struct vkd3d_bytecode_
sm1_instr.opcode |= VKD3DSI_TEXLD_BIAS << VKD3D_SM1_INSTRUCTION_FLAGS_SHIFT;
break;
+ case HLSL_RESOURCE_SAMPLE_GRAD:
+ sm1_instr.opcode = D3DSIO_TEXLDD;
+
+ sm1_instr.srcs[2].type = D3DSPR_TEMP;
+ sm1_instr.srcs[2].reg = ddx->reg.id;
+ sm1_instr.srcs[2].swizzle = hlsl_swizzle_from_writemask(ddx->reg.writemask);
+
+ sm1_instr.srcs[3].type = D3DSPR_TEMP;
+ sm1_instr.srcs[3].reg = ddy->reg.id;
+ sm1_instr.srcs[3].swizzle = hlsl_swizzle_from_writemask(ddy->reg.writemask);
+
+ sm1_instr.src_count += 2;
+ break;
+
default:
hlsl_fixme(ctx, &instr->loc, "Resource load type %u.", load->load_type);
return;
diff --git a/libs/vkd3d/libs/vkd3d-shader/fx.c b/libs/vkd3d/libs/vkd3d-shader/fx.c
index 3ba0a9ba994..75f10a18253 100644
--- a/libs/vkd3d/libs/vkd3d-shader/fx.c
+++ b/libs/vkd3d/libs/vkd3d-shader/fx.c
@@ -63,6 +63,7 @@ struct fx_write_context_ops
uint32_t (*write_string)(const char *string, struct fx_write_context *fx);
void (*write_technique)(struct hlsl_ir_var *var, struct fx_write_context *fx);
void (*write_pass)(struct hlsl_ir_var *var, struct fx_write_context *fx);
+ void (*write_annotation)(struct hlsl_ir_var *var, struct fx_write_context *fx);
bool are_child_effects_supported;
};
@@ -94,6 +95,8 @@ struct fx_write_context
uint32_t texture_count;
uint32_t uav_count;
uint32_t sampler_state_count;
+ uint32_t depth_stencil_state_count;
+ uint32_t rasterizer_state_count;
int status;
bool child_effect;
@@ -128,8 +131,41 @@ static void write_pass(struct hlsl_ir_var *var, struct fx_write_context *fx)
fx->ops->write_pass(var, fx);
}
+static uint32_t write_annotations(struct hlsl_scope *scope, struct fx_write_context *fx)
+{
+ struct hlsl_ctx *ctx = fx->ctx;
+ struct hlsl_ir_var *v;
+ uint32_t count = 0;
+
+ if (!scope)
+ return 0;
+
+ LIST_FOR_EACH_ENTRY(v, &scope->vars, struct hlsl_ir_var, scope_entry)
+ {
+ if (!v->default_values)
+ hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX,
+ "Annotation variable is missing default value.");
+
+ fx->ops->write_annotation(v, fx);
+ ++count;
+ }
+
+ return count;
+}
+
+static void write_fx_4_annotations(struct hlsl_scope *scope, struct fx_write_context *fx)
+{
+ struct vkd3d_bytecode_buffer *buffer = &fx->structured;
+ uint32_t count_offset, count;
+
+ count_offset = put_u32(buffer, 0);
+ count = write_annotations(scope, fx);
+ set_u32(buffer, count_offset, count);
+}
+
static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_context *fx);
static const char * get_fx_4_type_name(const struct hlsl_type *type);
+static void write_fx_4_annotation(struct hlsl_ir_var *var, struct fx_write_context *fx);
static uint32_t write_type(const struct hlsl_type *type, struct fx_write_context *fx)
{
@@ -279,9 +315,9 @@ static void write_fx_4_pass(struct hlsl_ir_var *var, struct fx_write_context *fx
name_offset = write_string(var->name, fx);
put_u32(buffer, name_offset);
put_u32(buffer, 0); /* Assignment count. */
- put_u32(buffer, 0); /* Annotation count. */
- /* TODO: annotations */
+ write_fx_4_annotations(var->annotations, fx);
+
/* TODO: assignments */
}
@@ -402,6 +438,9 @@ static const char * get_fx_4_type_name(const struct hlsl_type *type)
case HLSL_CLASS_UAV:
return uav_type_names[type->sampler_dim];
+ case HLSL_CLASS_DEPTH_STENCIL_STATE:
+ return "DepthStencilState";
+
case HLSL_CLASS_DEPTH_STENCIL_VIEW:
return "DepthStencilView";
@@ -421,10 +460,20 @@ static const char * get_fx_4_type_name(const struct hlsl_type *type)
static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_context *fx)
{
+ struct field_offsets
+ {
+ uint32_t name;
+ uint32_t semantic;
+ uint32_t offset;
+ uint32_t type;
+ };
+ uint32_t name_offset, offset, total_size, packed_size, stride, numeric_desc;
struct vkd3d_bytecode_buffer *buffer = &fx->unstructured;
- uint32_t name_offset, offset, size, stride, numeric_desc;
+ struct field_offsets *field_offsets = NULL;
+ struct hlsl_ctx *ctx = fx->ctx;
uint32_t elements_count = 0;
const char *name;
+ size_t i;
/* Resolve arrays to element type and number of elements. */
if (type->class == HLSL_CLASS_ARRAY)
@@ -436,6 +485,22 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co
name = get_fx_4_type_name(type);
name_offset = write_string(name, fx);
+ if (type->class == HLSL_CLASS_STRUCT)
+ {
+ if (!(field_offsets = hlsl_calloc(ctx, type->e.record.field_count, sizeof(*field_offsets))))
+ return 0;
+
+ for (i = 0; i < type->e.record.field_count; ++i)
+ {
+ const struct hlsl_struct_field *field = &type->e.record.fields[i];
+
+ field_offsets[i].name = write_string(field->name, fx);
+ field_offsets[i].semantic = write_string(field->semantic.raw_name, fx);
+ field_offsets[i].offset = field->reg_offset[HLSL_REGSET_NUMERIC];
+ field_offsets[i].type = write_type(field->type, fx);
+ }
+ }
+
offset = put_u32_unaligned(buffer, name_offset);
switch (type->class)
@@ -446,8 +511,10 @@ 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_STATE:
case HLSL_CLASS_DEPTH_STENCIL_VIEW:
case HLSL_CLASS_PIXEL_SHADER:
+ case HLSL_CLASS_RASTERIZER_STATE:
case HLSL_CLASS_RENDER_TARGET_VIEW:
case HLSL_CLASS_SAMPLER:
case HLSL_CLASS_TEXTURE:
@@ -464,6 +531,7 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co
case HLSL_CLASS_EFFECT_GROUP:
case HLSL_CLASS_PASS:
case HLSL_CLASS_TECHNIQUE:
+ case HLSL_CLASS_CONSTANT_BUFFER:
vkd3d_unreachable();
case HLSL_CLASS_STRING:
@@ -473,34 +541,40 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co
return 0;
}
- size = stride = type->reg_size[HLSL_REGSET_NUMERIC] * sizeof(float);
+ /* Structures can only contain numeric fields, this is validated during variable declaration. */
+ total_size = stride = type->reg_size[HLSL_REGSET_NUMERIC] * sizeof(float);
+ packed_size = 0;
+ if (type->class == HLSL_CLASS_STRUCT || hlsl_is_numeric_type(type))
+ packed_size = hlsl_type_component_count(type) * sizeof(float);
if (elements_count)
- size *= elements_count;
+ {
+ total_size *= elements_count;
+ packed_size *= elements_count;
+ }
stride = align(stride, 4 * sizeof(float));
put_u32_unaligned(buffer, elements_count);
- put_u32_unaligned(buffer, size); /* Total size. */
- put_u32_unaligned(buffer, stride); /* Stride. */
- put_u32_unaligned(buffer, size);
+ put_u32_unaligned(buffer, total_size);
+ put_u32_unaligned(buffer, stride);
+ put_u32_unaligned(buffer, packed_size);
if (type->class == HLSL_CLASS_STRUCT)
{
- size_t i;
-
put_u32_unaligned(buffer, type->e.record.field_count);
for (i = 0; i < type->e.record.field_count; ++i)
{
- const struct hlsl_struct_field *field = &type->e.record.fields[i];
- uint32_t semantic_offset, field_type_offset;
+ const struct field_offsets *field = &field_offsets[i];
- name_offset = write_string(field->name, fx);
- semantic_offset = write_string(field->semantic.raw_name, fx);
- field_type_offset = write_type(field->type, fx);
+ put_u32_unaligned(buffer, field->name);
+ put_u32_unaligned(buffer, field->semantic);
+ put_u32_unaligned(buffer, field->offset);
+ put_u32_unaligned(buffer, field->type);
+ }
- put_u32_unaligned(buffer, name_offset);
- put_u32_unaligned(buffer, semantic_offset);
- put_u32_unaligned(buffer, field->reg_offset[HLSL_REGSET_NUMERIC]);
- put_u32_unaligned(buffer, field_type_offset);
+ if (ctx->profile->major_version == 5)
+ {
+ put_u32_unaligned(buffer, 0); /* Base class type */
+ put_u32_unaligned(buffer, 0); /* Interface count */
}
}
else if (type->class == HLSL_CLASS_TEXTURE)
@@ -556,6 +630,14 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co
{
put_u32_unaligned(buffer, 6);
}
+ else if (type->class == HLSL_CLASS_RASTERIZER_STATE)
+ {
+ put_u32_unaligned(buffer, 4);
+ }
+ else if (type->class == HLSL_CLASS_DEPTH_STENCIL_STATE)
+ {
+ put_u32_unaligned(buffer, 3);
+ }
else if (hlsl_is_numeric_type(type))
{
numeric_desc = get_fx_4_numeric_type_description(type, fx);
@@ -565,9 +647,9 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co
{
FIXME("Type %u is not supported.\n", type->class);
set_status(fx, VKD3D_ERROR_NOT_IMPLEMENTED);
- return 0;
}
+ vkd3d_free(field_offsets);
return offset;
}
@@ -581,8 +663,9 @@ static void write_fx_4_technique(struct hlsl_ir_var *var, struct fx_write_contex
name_offset = write_string(var->name, fx);
put_u32(buffer, name_offset);
count_offset = put_u32(buffer, 0);
- put_u32(buffer, 0); /* Annotation count. */
+ write_fx_4_annotations(var->annotations, fx);
+ count = 0;
LIST_FOR_EACH_ENTRY(pass, &var->scope->vars, struct hlsl_ir_var, scope_entry)
{
write_pass(pass, fx);
@@ -617,7 +700,7 @@ static void write_group(struct hlsl_ir_var *var, struct fx_write_context *fx)
put_u32(buffer, name_offset);
count_offset = put_u32(buffer, 0); /* Technique count */
- put_u32(buffer, 0); /* Annotation count */
+ write_fx_4_annotations(var ? var->annotations : NULL, fx);
count = fx->technique_count;
write_techniques(var ? var->scope : fx->ctx->globals, fx);
@@ -853,8 +936,10 @@ 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_STATE:
case HLSL_CLASS_DEPTH_STENCIL_VIEW:
case HLSL_CLASS_UAV:
+ case HLSL_CLASS_RASTERIZER_STATE:
case HLSL_CLASS_RENDER_TARGET_VIEW:
case HLSL_CLASS_VOID:
return false;
@@ -862,6 +947,7 @@ static bool is_type_supported_fx_2(struct hlsl_ctx *ctx, const struct hlsl_type
case HLSL_CLASS_EFFECT_GROUP:
case HLSL_CLASS_PASS:
case HLSL_CLASS_TECHNIQUE:
+ case HLSL_CLASS_CONSTANT_BUFFER:
/* This cannot appear as an extern variable. */
break;
}
@@ -975,9 +1061,72 @@ static const struct fx_write_context_ops fx_4_ops =
.write_string = write_fx_4_string,
.write_technique = write_fx_4_technique,
.write_pass = write_fx_4_pass,
+ .write_annotation = write_fx_4_annotation,
.are_child_effects_supported = true,
};
+static uint32_t write_fx_4_default_value(struct hlsl_type *value_type, struct hlsl_default_value *value,
+ struct fx_write_context *fx)
+{
+ const struct hlsl_type *type = hlsl_get_multiarray_element_type(value_type);
+ uint32_t elements_count = hlsl_get_multiarray_size(value_type), i, j;
+ struct vkd3d_bytecode_buffer *buffer = &fx->unstructured;
+ struct hlsl_ctx *ctx = fx->ctx;
+ uint32_t offset = buffer->size;
+ unsigned int comp_count;
+
+ if (!value)
+ return 0;
+
+ comp_count = hlsl_type_component_count(type);
+
+ for (i = 0; i < elements_count; ++i)
+ {
+ switch (type->class)
+ {
+ case HLSL_CLASS_SCALAR:
+ case HLSL_CLASS_VECTOR:
+ case HLSL_CLASS_MATRIX:
+ {
+ switch (type->e.numeric.type)
+ {
+ case HLSL_TYPE_FLOAT:
+ case HLSL_TYPE_INT:
+ case HLSL_TYPE_UINT:
+ case HLSL_TYPE_BOOL:
+
+ for (j = 0; j < comp_count; ++j)
+ {
+ put_u32_unaligned(buffer, value->value.u);
+ value++;
+ }
+ break;
+ default:
+ hlsl_fixme(ctx, &ctx->location, "Writing default values for numeric type %u is not implemented.",
+ type->e.numeric.type);
+ }
+
+ break;
+ }
+ case HLSL_CLASS_STRUCT:
+ {
+ struct hlsl_struct_field *fields = type->e.record.fields;
+
+ for (j = 0; j < type->e.record.field_count; ++j)
+ {
+ write_fx_4_default_value(fields[i].type, value, fx);
+ value += hlsl_type_component_count(fields[i].type);
+ }
+ break;
+ }
+ default:
+ hlsl_fixme(ctx, &ctx->location, "Writing default values for class %u is not implemented.", type->class);
+ }
+ }
+
+ return offset;
+}
+
static void write_fx_4_numeric_variable(struct hlsl_ir_var *var, bool shared, struct fx_write_context *fx)
{
struct vkd3d_bytecode_buffer *buffer = &fx->structured;
@@ -987,7 +1136,6 @@ static void write_fx_4_numeric_variable(struct hlsl_ir_var *var, bool shared, st
{
HAS_EXPLICIT_BIND_POINT = 0x4,
};
- struct hlsl_ctx *ctx = fx->ctx;
if (var->has_explicit_bind_point)
flags |= HAS_EXPLICIT_BIND_POINT;
@@ -1001,7 +1149,7 @@ static void write_fx_4_numeric_variable(struct hlsl_ir_var *var, bool shared, st
semantic_offset = put_u32(buffer, semantic_offset); /* Semantic */
put_u32(buffer, var->buffer_offset * 4); /* Offset in the constant buffer, in bytes. */
- value_offset = put_u32(buffer, 0); /* Default value offset */
+ value_offset = put_u32(buffer, 0);
put_u32(buffer, flags); /* Flags */
if (shared)
@@ -1010,19 +1158,39 @@ static void write_fx_4_numeric_variable(struct hlsl_ir_var *var, bool shared, st
}
else
{
- /* FIXME: write default value */
- set_u32(buffer, value_offset, 0);
- if (var->default_values)
- hlsl_fixme(fx->ctx, &var->loc, "Write default values.\n");
+ uint32_t offset = write_fx_4_default_value(var->data_type, var->default_values, fx);
+ set_u32(buffer, value_offset, offset);
- put_u32(buffer, 0); /* Annotations count */
- if (has_annotations(var))
- hlsl_fixme(ctx, &ctx->location, "Writing annotations for numeric variables is not implemented.");
+ write_fx_4_annotations(var->annotations, fx);
fx->numeric_variable_count++;
}
}
+static void write_fx_4_annotation(struct hlsl_ir_var *var, struct fx_write_context *fx)
+{
+ const struct hlsl_type *type = hlsl_get_multiarray_element_type(var->data_type);
+ struct vkd3d_bytecode_buffer *buffer = &fx->structured;
+ uint32_t name_offset, type_offset, offset;
+ struct hlsl_ctx *ctx = fx->ctx;
+
+ name_offset = write_string(var->name, fx);
+ type_offset = write_type(var->data_type, fx);
+
+ put_u32(buffer, name_offset);
+ put_u32(buffer, type_offset);
+
+ if (hlsl_is_numeric_type(type))
+ {
+ offset = write_fx_4_default_value(var->data_type, var->default_values, fx);
+ put_u32(buffer, offset);
+ }
+ else
+ {
+ hlsl_fixme(ctx, &var->loc, "Writing annotations for type class %u is not implemented.", type->class);
+ }
+}
+
struct rhs_named_value
{
const char *name;
@@ -1164,6 +1332,41 @@ static bool replace_state_block_constant(struct hlsl_ctx *ctx, struct hlsl_ir_no
return true;
}
+static void fold_state_value(struct hlsl_ctx *ctx, struct hlsl_state_block_entry *entry)
+{
+ bool progress;
+
+ do
+ {
+ progress = hlsl_transform_ir(ctx, hlsl_fold_constant_exprs, entry->instrs, NULL);
+ progress |= hlsl_copy_propagation_execute(ctx, entry->instrs);
+ } while (progress);
+}
+
+enum state_property_component_type
+{
+ FX_BOOL,
+ FX_FLOAT,
+ FX_UINT,
+ FX_UINT8,
+};
+
+static inline enum hlsl_base_type hlsl_type_from_fx_type(enum state_property_component_type type)
+{
+ switch (type)
+ {
+ case FX_BOOL:
+ return HLSL_TYPE_BOOL;
+ case FX_FLOAT:
+ return HLSL_TYPE_FLOAT;
+ case FX_UINT:
+ case FX_UINT8:
+ return HLSL_TYPE_UINT;
+ default:
+ vkd3d_unreachable();
+ }
+}
+
static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl_state_block_entry *entry,
struct fx_write_context *fx)
{
@@ -1213,37 +1416,112 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl
{ NULL }
};
+ static const struct rhs_named_value depth_write_mask_values[] =
+ {
+ { "ZERO", 0 },
+ { "ALL", 1 },
+ { NULL }
+ };
+
+ static const struct rhs_named_value comparison_values[] =
+ {
+ { "NEVER", 1 },
+ { "LESS", 2 },
+ { "EQUAL", 3 },
+ { "LESS_EQUAL", 4 },
+ { "GREATER", 5 },
+ { "NOT_EQUAL", 6 },
+ { "GREATER_EQUAL", 7 },
+ { "ALWAYS", 8 },
+ { NULL }
+ };
+
+ static const struct rhs_named_value stencil_op_values[] =
+ {
+ { "KEEP", 1 },
+ { "ZERO", 2 },
+ { "REPLACE", 3 },
+ { "INCR_SAT", 4 },
+ { "DECR_SAT", 5 },
+ { "INVERT", 6 },
+ { "INCR", 7 },
+ { "DECR", 8 },
+ { NULL }
+ };
+
+ static const struct rhs_named_value fill_values[] =
+ {
+ { "WIREFRAME", 2 },
+ { "SOLID", 3 },
+ { NULL }
+ };
+
+ static const struct rhs_named_value cull_values[] =
+ {
+ { "NONE", 1 },
+ { "FRONT", 2 },
+ { "BACK", 3 },
+ { NULL }
+ };
+
static const struct state
{
const char *name;
enum hlsl_type_class container;
- enum hlsl_base_type type;
+ enum hlsl_type_class class;
+ enum state_property_component_type type;
unsigned int dimx;
uint32_t id;
const struct rhs_named_value *values;
}
states[] =
{
- { "Filter", HLSL_CLASS_SAMPLER, HLSL_TYPE_UINT, 1, 45, filter_values },
- { "AddressU", HLSL_CLASS_SAMPLER, HLSL_TYPE_UINT, 1, 46, address_values },
- { "AddressV", HLSL_CLASS_SAMPLER, HLSL_TYPE_UINT, 1, 47, address_values },
- { "AddressW", HLSL_CLASS_SAMPLER, HLSL_TYPE_UINT, 1, 48, address_values },
- { "MipLODBias", HLSL_CLASS_SAMPLER, HLSL_TYPE_FLOAT, 1, 49 },
- { "MaxAnisotropy", HLSL_CLASS_SAMPLER, HLSL_TYPE_UINT, 1, 50 },
- { "ComparisonFunc", HLSL_CLASS_SAMPLER, HLSL_TYPE_UINT, 1, 51, compare_func_values },
- { "BorderColor", HLSL_CLASS_SAMPLER, HLSL_TYPE_FLOAT, 4, 52 },
- { "MinLOD", HLSL_CLASS_SAMPLER, HLSL_TYPE_FLOAT, 1, 53 },
- { "MaxLOD", HLSL_CLASS_SAMPLER, HLSL_TYPE_FLOAT, 1, 54 },
+ { "FillMode", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 12, fill_values },
+ { "CullMode", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 13, cull_values },
+ { "FrontCounterClockwise", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 14 },
+ { "DepthBias", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 15 },
+ { "DepthBiasClamp", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 16 },
+ { "SlopeScaledDepthBias", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 17 },
+ { "DepthClipEnable", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 18 },
+ { "ScissorEnable", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 19 },
+ { "MultisampleEnable", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 20 },
+ { "AntializedLineEnable", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 21 },
+
+ { "DepthEnable", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 22 },
+ { "DepthWriteMask", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 23, depth_write_mask_values },
+ { "DepthFunc", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 24, comparison_values },
+ { "StencilEnable", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 25 },
+ { "StencilReadMask", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_UINT8, 1, 26 },
+ { "StencilWriteMask", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_UINT8, 1, 27 },
+ { "FrontFaceStencilFail", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 28, stencil_op_values },
+ { "FrontFaceStencilDepthFail", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 29, stencil_op_values },
+ { "FrontFaceStencilPass", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 30, stencil_op_values },
+ { "FrontFaceStencilFunc", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 31, comparison_values },
+ { "BackFaceStencilFail", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 32, stencil_op_values },
+ { "BackFaceStencilDepthFail", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 33, stencil_op_values },
+ { "BackFaceStencilPass", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 34, stencil_op_values },
+ { "BackFaceStencilFunc", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 35, comparison_values },
+
+ { "Filter", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 45, filter_values },
+ { "AddressU", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 46, address_values },
+ { "AddressV", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 47, address_values },
+ { "AddressW", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 48, address_values },
+ { "MipLODBias", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 49 },
+ { "MaxAnisotropy", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 50 },
+ { "ComparisonFunc", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 51, compare_func_values },
+ { "BorderColor", HLSL_CLASS_SAMPLER, HLSL_CLASS_VECTOR, FX_FLOAT, 4, 52 },
+ { "MinLOD", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 53 },
+ { "MaxLOD", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 54 },
/* TODO: "Texture" field */
};
const struct hlsl_type *type = hlsl_get_multiarray_element_type(var->data_type);
struct replace_state_context replace_context;
+ struct hlsl_type *state_type = NULL;
struct hlsl_ir_node *node, *cast;
const struct state *state = NULL;
struct hlsl_ctx *ctx = fx->ctx;
- struct hlsl_type *state_type;
+ enum hlsl_base_type base_type;
unsigned int i;
- bool progress;
for (i = 0; i < ARRAY_SIZE(states); ++i)
{
@@ -1273,28 +1551,54 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl
replace_context.values = state->values;
replace_context.var = var;
- /* Turned named constants to actual constants. */
+ /* Turn named constants to actual constants. */
hlsl_transform_ir(ctx, replace_state_block_constant, entry->instrs, &replace_context);
+ fold_state_value(ctx, entry);
- if (state->dimx)
- state_type = hlsl_get_vector_type(ctx, state->type, state->dimx);
- else
- state_type = hlsl_get_scalar_type(ctx, state->type);
+ /* Now cast and run folding again. */
- /* Cast to expected property type. */
- node = entry->args->node;
- if (!(cast = hlsl_new_cast(ctx, node, state_type, &var->loc)))
- return;
- list_add_after(&node->entry, &cast->entry);
-
- hlsl_src_remove(entry->args);
- hlsl_src_from_node(entry->args, cast);
+ base_type = hlsl_type_from_fx_type(state->type);
+ switch (state->class)
+ {
+ case HLSL_CLASS_VECTOR:
+ state_type = hlsl_get_vector_type(ctx, base_type, state->dimx);
+ break;
+ case HLSL_CLASS_SCALAR:
+ state_type = hlsl_get_scalar_type(ctx, base_type);
+ break;
+ case HLSL_CLASS_TEXTURE:
+ hlsl_fixme(ctx, &ctx->location, "Object type fields are not supported.");
+ break;
+ default:
+ ;
+ }
- do
+ if (state_type)
{
- progress = hlsl_transform_ir(ctx, hlsl_fold_constant_exprs, entry->instrs, NULL);
- progress |= hlsl_copy_propagation_execute(ctx, entry->instrs);
- } while (progress);
+ node = entry->args->node;
+ if (!(cast = hlsl_new_cast(ctx, node, state_type, &var->loc)))
+ return;
+ list_add_after(&node->entry, &cast->entry);
+
+ /* FX_UINT8 values are using 32-bits in the binary. Mask higher 24 bits for those. */
+ if (state->type == FX_UINT8)
+ {
+ struct hlsl_ir_node *mask;
+
+ if (!(mask = hlsl_new_uint_constant(ctx, 0xff, &var->loc)))
+ return;
+ list_add_after(&cast->entry, &mask->entry);
+
+ if (!(cast = hlsl_new_binary_expr(ctx, HLSL_OP2_BIT_AND, cast, mask)))
+ return;
+ list_add_after(&mask->entry, &cast->entry);
+ }
+
+ hlsl_src_remove(entry->args);
+ hlsl_src_from_node(entry->args, cast);
+
+ fold_state_value(ctx, entry);
+ }
}
static void write_fx_4_state_object_initializer(struct hlsl_ir_var *var, struct fx_write_context *fx)
@@ -1387,19 +1691,27 @@ static void write_fx_4_object_variable(struct hlsl_ir_var *var, struct fx_write_
fx->dsv_count += elements_count;
break;
+ case HLSL_CLASS_DEPTH_STENCIL_STATE:
+ write_fx_4_state_object_initializer(var, fx);
+ fx->depth_stencil_state_count += elements_count;
+ break;
+
case HLSL_CLASS_SAMPLER:
write_fx_4_state_object_initializer(var, fx);
fx->sampler_state_count += elements_count;
break;
+ case HLSL_CLASS_RASTERIZER_STATE:
+ write_fx_4_state_object_initializer(var, fx);
+ fx->rasterizer_state_count += elements_count;
+ break;
+
default:
hlsl_fixme(ctx, &ctx->location, "Writing initializer for object type %u is not implemented.",
type->e.numeric.type);
}
- put_u32(buffer, 0); /* Annotations count */
- if (has_annotations(var))
- hlsl_fixme(ctx, &ctx->location, "Writing annotations for object variables is not implemented.");
+ write_fx_4_annotations(var->annotations, fx);
++fx->object_variable_count;
}
@@ -1442,9 +1754,7 @@ static void write_fx_4_buffer(struct hlsl_buffer *b, struct fx_write_context *fx
}
else
{
- put_u32(buffer, 0); /* Annotations count */
- if (b->annotations)
- hlsl_fixme(ctx, &b->loc, "Writing annotations for buffers is not implemented.");
+ write_fx_4_annotations(b->annotations, fx);
++fx->buffer_count;
}
@@ -1490,8 +1800,10 @@ static bool is_supported_object_variable(const struct hlsl_ctx *ctx, const struc
switch (type->class)
{
+ case HLSL_CLASS_DEPTH_STENCIL_STATE:
case HLSL_CLASS_DEPTH_STENCIL_VIEW:
case HLSL_CLASS_PIXEL_SHADER:
+ case HLSL_CLASS_RASTERIZER_STATE:
case HLSL_CLASS_RENDER_TARGET_VIEW:
case HLSL_CLASS_SAMPLER:
case HLSL_CLASS_TEXTURE:
@@ -1558,9 +1870,9 @@ static int hlsl_fx_4_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out)
size_offset = put_u32(&buffer, 0); /* Unstructured size. */
put_u32(&buffer, 0); /* String count. */
put_u32(&buffer, fx.texture_count);
- put_u32(&buffer, 0); /* Depth stencil state count. */
+ put_u32(&buffer, fx.depth_stencil_state_count);
put_u32(&buffer, 0); /* Blend state count. */
- put_u32(&buffer, 0); /* Rasterizer state count. */
+ put_u32(&buffer, fx.rasterizer_state_count);
put_u32(&buffer, fx.sampler_state_count);
put_u32(&buffer, fx.rtv_count);
put_u32(&buffer, fx.dsv_count);
@@ -1616,9 +1928,9 @@ static int hlsl_fx_5_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out)
size_offset = put_u32(&buffer, 0); /* Unstructured size. */
put_u32(&buffer, 0); /* String count. */
put_u32(&buffer, fx.texture_count);
- put_u32(&buffer, 0); /* Depth stencil state count. */
+ put_u32(&buffer, fx.depth_stencil_state_count);
put_u32(&buffer, 0); /* Blend state count. */
- put_u32(&buffer, 0); /* Rasterizer state count. */
+ put_u32(&buffer, fx.rasterizer_state_count);
put_u32(&buffer, fx.sampler_state_count);
put_u32(&buffer, fx.rtv_count);
put_u32(&buffer, fx.dsv_count);
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c
index c69af4e94bb..a157590c97a 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c
@@ -369,15 +369,18 @@ 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_STATE:
case HLSL_CLASS_DEPTH_STENCIL_VIEW:
case HLSL_CLASS_EFFECT_GROUP:
case HLSL_CLASS_PASS:
case HLSL_CLASS_PIXEL_SHADER:
+ case HLSL_CLASS_RASTERIZER_STATE:
case HLSL_CLASS_RENDER_TARGET_VIEW:
case HLSL_CLASS_STRING:
case HLSL_CLASS_TECHNIQUE:
case HLSL_CLASS_VERTEX_SHADER:
case HLSL_CLASS_VOID:
+ case HLSL_CLASS_CONSTANT_BUFFER:
break;
}
}
@@ -437,11 +440,13 @@ static bool type_is_single_component(const struct hlsl_type *type)
{
switch (type->class)
{
+ case HLSL_CLASS_DEPTH_STENCIL_STATE:
case HLSL_CLASS_DEPTH_STENCIL_VIEW:
case HLSL_CLASS_PIXEL_SHADER:
case HLSL_CLASS_SCALAR:
case HLSL_CLASS_SAMPLER:
case HLSL_CLASS_STRING:
+ case HLSL_CLASS_RASTERIZER_STATE:
case HLSL_CLASS_RENDER_TARGET_VIEW:
case HLSL_CLASS_TEXTURE:
case HLSL_CLASS_UAV:
@@ -452,6 +457,7 @@ static bool type_is_single_component(const struct hlsl_type *type)
case HLSL_CLASS_MATRIX:
case HLSL_CLASS_STRUCT:
case HLSL_CLASS_ARRAY:
+ case HLSL_CLASS_CONSTANT_BUFFER:
return false;
case HLSL_CLASS_EFFECT_GROUP:
@@ -530,6 +536,12 @@ static unsigned int traverse_path_from_component_index(struct hlsl_ctx *ctx,
vkd3d_unreachable();
}
+ case HLSL_CLASS_CONSTANT_BUFFER:
+ {
+ *type_ptr = type->e.resource.format;
+ return traverse_path_from_component_index(ctx, type_ptr, index_ptr);
+ }
+
default:
vkd3d_unreachable();
}
@@ -581,8 +593,10 @@ unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_ty
}
break;
+ case HLSL_CLASS_DEPTH_STENCIL_STATE:
case HLSL_CLASS_DEPTH_STENCIL_VIEW:
case HLSL_CLASS_PIXEL_SHADER:
+ case HLSL_CLASS_RASTERIZER_STATE:
case HLSL_CLASS_RENDER_TARGET_VIEW:
case HLSL_CLASS_SAMPLER:
case HLSL_CLASS_STRING:
@@ -597,6 +611,7 @@ unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_ty
case HLSL_CLASS_TECHNIQUE:
case HLSL_CLASS_VOID:
case HLSL_CLASS_SCALAR:
+ case HLSL_CLASS_CONSTANT_BUFFER:
vkd3d_unreachable();
}
type = next_type;
@@ -870,6 +885,20 @@ struct hlsl_type *hlsl_new_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim
return type;
}
+struct hlsl_type *hlsl_new_cb_type(struct hlsl_ctx *ctx, struct hlsl_type *format)
+{
+ struct hlsl_type *type;
+
+ if (!(type = hlsl_alloc(ctx, sizeof(*type))))
+ return NULL;
+ type->class = HLSL_CLASS_CONSTANT_BUFFER;
+ type->dimy = 1;
+ type->e.resource.format = format;
+ hlsl_type_calculate_reg_size(ctx, type);
+ list_add_tail(&ctx->types, &type->entry);
+ return type;
+}
+
static const char * get_case_insensitive_typename(const char *name)
{
static const char *const names[] =
@@ -961,8 +990,13 @@ 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_CONSTANT_BUFFER:
+ return hlsl_type_component_count(type->e.resource.format);
+
+ case HLSL_CLASS_DEPTH_STENCIL_STATE:
case HLSL_CLASS_DEPTH_STENCIL_VIEW:
case HLSL_CLASS_PIXEL_SHADER:
+ case HLSL_CLASS_RASTERIZER_STATE:
case HLSL_CLASS_RENDER_TARGET_VIEW:
case HLSL_CLASS_SAMPLER:
case HLSL_CLASS_STRING:
@@ -1043,10 +1077,15 @@ bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2
case HLSL_CLASS_TECHNIQUE:
return t1->e.version == t2->e.version;
+ case HLSL_CLASS_CONSTANT_BUFFER:
+ return hlsl_types_are_equal(t1->e.resource.format, t2->e.resource.format);
+
+ case HLSL_CLASS_DEPTH_STENCIL_STATE:
case HLSL_CLASS_DEPTH_STENCIL_VIEW:
case HLSL_CLASS_EFFECT_GROUP:
case HLSL_CLASS_PASS:
case HLSL_CLASS_PIXEL_SHADER:
+ case HLSL_CLASS_RASTERIZER_STATE:
case HLSL_CLASS_RENDER_TARGET_VIEW:
case HLSL_CLASS_STRING:
case HLSL_CLASS_VERTEX_SHADER:
@@ -2413,10 +2452,21 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru
}
return string;
+ case HLSL_CLASS_CONSTANT_BUFFER:
+ vkd3d_string_buffer_printf(string, "ConstantBuffer");
+ if ((inner_string = hlsl_type_to_string(ctx, type->e.resource.format)))
+ {
+ vkd3d_string_buffer_printf(string, "<%s>", inner_string->buffer);
+ hlsl_release_string_buffer(ctx, inner_string);
+ }
+ return string;
+
+ case HLSL_CLASS_DEPTH_STENCIL_STATE:
case HLSL_CLASS_DEPTH_STENCIL_VIEW:
case HLSL_CLASS_EFFECT_GROUP:
case HLSL_CLASS_PASS:
case HLSL_CLASS_PIXEL_SHADER:
+ case HLSL_CLASS_RASTERIZER_STATE:
case HLSL_CLASS_RENDER_TARGET_VIEW:
case HLSL_CLASS_SAMPLER:
case HLSL_CLASS_STRING:
@@ -3761,9 +3811,11 @@ 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, "DepthStencilState", HLSL_CLASS_DEPTH_STENCIL_STATE));
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, "pixelshader", HLSL_CLASS_PIXEL_SHADER));
+ hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "RasterizerState", HLSL_CLASS_RASTERIZER_STATE));
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));
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
index 179cc219e68..3e0d55a7f7d 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
@@ -78,10 +78,12 @@ enum hlsl_type_class
HLSL_CLASS_LAST_NUMERIC = HLSL_CLASS_MATRIX,
HLSL_CLASS_STRUCT,
HLSL_CLASS_ARRAY,
+ HLSL_CLASS_DEPTH_STENCIL_STATE,
HLSL_CLASS_DEPTH_STENCIL_VIEW,
HLSL_CLASS_EFFECT_GROUP,
HLSL_CLASS_PASS,
HLSL_CLASS_PIXEL_SHADER,
+ HLSL_CLASS_RASTERIZER_STATE,
HLSL_CLASS_RENDER_TARGET_VIEW,
HLSL_CLASS_SAMPLER,
HLSL_CLASS_STRING,
@@ -89,6 +91,7 @@ enum hlsl_type_class
HLSL_CLASS_TEXTURE,
HLSL_CLASS_UAV,
HLSL_CLASS_VERTEX_SHADER,
+ HLSL_CLASS_CONSTANT_BUFFER,
HLSL_CLASS_VOID,
};
@@ -385,6 +388,7 @@ struct hlsl_attribute
#define HLSL_STORAGE_LINEAR 0x00010000
#define HLSL_MODIFIER_SINGLE 0x00020000
#define HLSL_MODIFIER_EXPORT 0x00040000
+#define HLSL_STORAGE_ANNOTATION 0x00080000
#define HLSL_TYPE_MODIFIERS_MASK (HLSL_MODIFIER_PRECISE | HLSL_MODIFIER_VOLATILE | \
HLSL_MODIFIER_CONST | HLSL_MODIFIER_ROW_MAJOR | \
@@ -838,6 +842,8 @@ struct hlsl_scope
bool loop;
/* The scope was created for the switch statement. */
bool _switch;
+ /* The scope contains annotation variables. */
+ bool annotations;
};
struct hlsl_profile_info
@@ -1391,6 +1397,7 @@ struct hlsl_type *hlsl_new_texture_type(struct hlsl_ctx *ctx, enum hlsl_sampler_
unsigned int sample_count);
struct hlsl_type *hlsl_new_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim,
struct hlsl_type *format, bool rasteriser_ordered);
+struct hlsl_type *hlsl_new_cb_type(struct hlsl_ctx *ctx, struct hlsl_type *format);
struct hlsl_ir_node *hlsl_new_uint_constant(struct hlsl_ctx *ctx, unsigned int n,
const struct vkd3d_shader_location *loc);
struct hlsl_ir_node *hlsl_new_unary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg,
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.l b/libs/vkd3d/libs/vkd3d-shader/hlsl.l
index 91418775e1b..55993dac2b4 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.l
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.l
@@ -198,7 +198,9 @@ while {return KW_WHILE; }
struct hlsl_ctx *ctx = yyget_extra(yyscanner);
yylval->name = hlsl_strdup(ctx, yytext);
- if (hlsl_get_var(ctx->cur_scope, yytext) || hlsl_get_function(ctx, yytext))
+ if (hlsl_version_ge(ctx, 5, 1) && !strcmp(yytext, "ConstantBuffer"))
+ return KW_CONSTANTBUFFER;
+ else if (hlsl_get_var(ctx->cur_scope, yytext) || hlsl_get_function(ctx, yytext))
return VAR_IDENTIFIER;
else if (hlsl_get_type(ctx->cur_scope, yytext, true, true))
return TYPE_IDENTIFIER;
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
index 9c75c87d36e..a02692399f7 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
@@ -1214,12 +1214,42 @@ static bool add_effect_group(struct hlsl_ctx *ctx, const char *name, struct hlsl
return true;
}
-static bool parse_reservation_index(const char *string, char *type, uint32_t *index)
+static bool parse_reservation_index(struct hlsl_ctx *ctx, const char *string, unsigned int bracket_offset,
+ struct hlsl_reg_reservation *reservation)
{
- if (!sscanf(string + 1, "%u", index))
- return false;
+ char *endptr;
+
+ reservation->reg_type = ascii_tolower(string[0]);
+
+ /* Prior to SM5.1, fxc simply ignored bracket offsets for 'b' types. */
+ if (reservation->reg_type == 'b' && hlsl_version_lt(ctx, 5, 1))
+ {
+ bracket_offset = 0;
+ }
+
+ if (string[1] == '\0')
+ {
+ reservation->reg_index = bracket_offset;
+ return true;
+ }
+
+ reservation->reg_index = strtoul(string + 1, &endptr, 10) + bracket_offset;
+
+ if (*endptr)
+ {
+ /* fxc for SM >= 4 treats all parse failures for 'b' types as successes,
+ * setting index to -1. It will later fail while validating slot limits. */
+ if (reservation->reg_type == 'b' && hlsl_version_ge(ctx, 4, 0))
+ {
+ reservation->reg_index = -1;
+ return true;
+ }
+
+ /* All other types tolerate leftover characters. */
+ if (endptr == string + 1)
+ return false;
+ }
- *type = ascii_tolower(string[0]);
return true;
}
@@ -2194,6 +2224,9 @@ static unsigned int get_component_index_from_default_initializer_index(struct hl
if (ctx->profile->major_version < 4)
return index;
+ if (ctx->profile->type == VKD3D_SHADER_TYPE_EFFECT)
+ return index;
+
switch (type->class)
{
case HLSL_CLASS_MATRIX:
@@ -2346,6 +2379,7 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v)
struct hlsl_semantic new_semantic;
uint32_t modifiers = v->modifiers;
bool unbounded_res_array = false;
+ bool constant_buffer = false;
struct hlsl_ir_var *var;
struct hlsl_type *type;
bool local = true;
@@ -2365,6 +2399,12 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v)
unbounded_res_array |= (v->arrays.sizes[i] == HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT);
}
+ if (type->class == HLSL_CLASS_CONSTANT_BUFFER)
+ {
+ type = type->e.resource.format;
+ constant_buffer = true;
+ }
+
if (unbounded_res_array)
{
if (v->arrays.count == 1)
@@ -2446,7 +2486,16 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v)
return;
}
- var->buffer = ctx->cur_buffer;
+ if (constant_buffer && ctx->cur_scope == ctx->globals)
+ {
+ if (!(var_name = vkd3d_strdup(v->name)))
+ return;
+ var->buffer = hlsl_new_buffer(ctx, HLSL_BUFFER_CONSTANT, var_name, modifiers, &v->reg_reservation, NULL, &v->loc);
+ }
+ else
+ {
+ var->buffer = ctx->cur_buffer;
+ }
if (var->buffer == ctx->globals_buffer)
{
@@ -2469,8 +2518,11 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v)
if (!(modifiers & HLSL_STORAGE_STATIC))
var->storage_modifiers |= HLSL_STORAGE_UNIFORM;
- if (ctx->profile->major_version < 5 && (var->storage_modifiers & HLSL_STORAGE_UNIFORM))
+ if ((ctx->profile->major_version < 5 || ctx->profile->type == VKD3D_SHADER_TYPE_EFFECT)
+ && (var->storage_modifiers & HLSL_STORAGE_UNIFORM))
+ {
check_invalid_object_fields(ctx, var);
+ }
if ((func = hlsl_get_first_func_decl(ctx, var->name)))
{
@@ -2576,11 +2628,19 @@ static struct hlsl_block *initialize_vars(struct hlsl_ctx *ctx, struct list *var
unsigned int size, k;
is_default_values_initializer = (ctx->cur_buffer != ctx->globals_buffer)
- || (var->storage_modifiers & HLSL_STORAGE_UNIFORM);
+ || (var->storage_modifiers & HLSL_STORAGE_UNIFORM)
+ || ctx->cur_scope->annotations;
if (is_default_values_initializer)
{
- assert(!var->default_values);
+ /* Default values might have been allocated already for another variable of the same name,
+ in the same scope. */
+ if (var->default_values)
+ {
+ free_parse_variable_def(v);
+ continue;
+ }
+
if (!(var->default_values = hlsl_calloc(ctx, component_count, sizeof(*var->default_values))))
{
free_parse_variable_def(v);
@@ -4233,6 +4293,7 @@ static bool intrinsic_tanh(struct hlsl_ctx *ctx,
static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer *params,
const struct vkd3d_shader_location *loc, const char *name, enum hlsl_sampler_dim dim)
{
+ unsigned int sampler_dim = hlsl_sampler_dim_count(dim);
struct hlsl_resource_load_params load_params = { 0 };
const struct hlsl_type *sampler_type;
struct hlsl_ir_node *coords, *sample;
@@ -4244,11 +4305,6 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer *
return false;
}
- if (params->args_count == 4)
- {
- hlsl_fixme(ctx, loc, "Samples with gradients are not implemented.");
- }
-
sampler_type = params->args[0]->data_type;
if (sampler_type->class != HLSL_CLASS_SAMPLER
|| (sampler_type->sampler_dim != dim && sampler_type->sampler_dim != HLSL_SAMPLER_DIM_GENERIC))
@@ -4272,12 +4328,12 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer *
else
load_params.type = HLSL_RESOURCE_SAMPLE_LOD_BIAS;
- if (!(c = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, Y, Z, W), hlsl_sampler_dim_count(dim), params->args[1], loc)))
+ if (!(c = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, Y, Z, W), sampler_dim, params->args[1], loc)))
return false;
hlsl_block_add_instr(params->instrs, c);
- if (!(coords = add_implicit_conversion(ctx, params->instrs, c, hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT,
- hlsl_sampler_dim_count(dim)), loc)))
+ if (!(coords = add_implicit_conversion(ctx, params->instrs, c,
+ hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc)))
{
return false;
}
@@ -4304,14 +4360,13 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer *
if (hlsl_version_ge(ctx, 4, 0))
{
- unsigned int count = hlsl_sampler_dim_count(dim);
struct hlsl_ir_node *divisor;
- if (!(divisor = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(W, W, W, W), count, coords, loc)))
+ if (!(divisor = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(W, W, W, W), sampler_dim, coords, loc)))
return false;
hlsl_block_add_instr(params->instrs, divisor);
- if (!(coords = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, Y, Z, W), count, coords, loc)))
+ if (!(coords = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, Y, Z, W), sampler_dim, coords, loc)))
return false;
hlsl_block_add_instr(params->instrs, coords);
@@ -4325,12 +4380,34 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer *
load_params.type = HLSL_RESOURCE_SAMPLE_PROJ;
}
}
+ else if (params->args_count == 4) /* Gradient sampling. */
+ {
+ if (!(coords = add_implicit_conversion(ctx, params->instrs, params->args[1],
+ hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc)))
+ {
+ return false;
+ }
+
+ if (!(load_params.ddx = add_implicit_conversion(ctx, params->instrs, params->args[2],
+ hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc)))
+ {
+ return false;
+ }
+
+ if (!(load_params.ddy = add_implicit_conversion(ctx, params->instrs, params->args[3],
+ hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc)))
+ {
+ return false;
+ }
+
+ load_params.type = HLSL_RESOURCE_SAMPLE_GRAD;
+ }
else
{
load_params.type = HLSL_RESOURCE_SAMPLE;
if (!(coords = add_implicit_conversion(ctx, params->instrs, params->args[1],
- hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, hlsl_sampler_dim_count(dim)), loc)))
+ hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc)))
{
return false;
}
@@ -4386,6 +4463,12 @@ static bool intrinsic_tex1D(struct hlsl_ctx *ctx,
return intrinsic_tex(ctx, params, loc, "tex1D", HLSL_SAMPLER_DIM_1D);
}
+static bool intrinsic_tex1Dgrad(struct hlsl_ctx *ctx,
+ const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
+{
+ return intrinsic_tex(ctx, params, loc, "tex1Dgrad", HLSL_SAMPLER_DIM_1D);
+}
+
static bool intrinsic_tex2D(struct hlsl_ctx *ctx,
const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
{
@@ -4398,6 +4481,12 @@ static bool intrinsic_tex2Dbias(struct hlsl_ctx *ctx,
return intrinsic_tex(ctx, params, loc, "tex2Dbias", HLSL_SAMPLER_DIM_2D);
}
+static bool intrinsic_tex2Dgrad(struct hlsl_ctx *ctx,
+ const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
+{
+ return intrinsic_tex(ctx, params, loc, "tex2Dgrad", HLSL_SAMPLER_DIM_2D);
+}
+
static bool intrinsic_tex2Dlod(struct hlsl_ctx *ctx,
const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
{
@@ -4416,6 +4505,12 @@ static bool intrinsic_tex3D(struct hlsl_ctx *ctx,
return intrinsic_tex(ctx, params, loc, "tex3D", HLSL_SAMPLER_DIM_3D);
}
+static bool intrinsic_tex3Dgrad(struct hlsl_ctx *ctx,
+ const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
+{
+ return intrinsic_tex(ctx, params, loc, "tex3Dgrad", HLSL_SAMPLER_DIM_3D);
+}
+
static bool intrinsic_tex3Dproj(struct hlsl_ctx *ctx,
const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
{
@@ -4428,6 +4523,12 @@ static bool intrinsic_texCUBE(struct hlsl_ctx *ctx,
return intrinsic_tex(ctx, params, loc, "texCUBE", HLSL_SAMPLER_DIM_CUBE);
}
+static bool intrinsic_texCUBEgrad(struct hlsl_ctx *ctx,
+ const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
+{
+ return intrinsic_tex(ctx, params, loc, "texCUBEgrad", HLSL_SAMPLER_DIM_CUBE);
+}
+
static bool intrinsic_texCUBEproj(struct hlsl_ctx *ctx,
const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
{
@@ -4617,13 +4718,17 @@ intrinsic_functions[] =
{"tan", 1, true, intrinsic_tan},
{"tanh", 1, true, intrinsic_tanh},
{"tex1D", -1, false, intrinsic_tex1D},
+ {"tex1Dgrad", 4, false, intrinsic_tex1Dgrad},
{"tex2D", -1, false, intrinsic_tex2D},
{"tex2Dbias", 2, false, intrinsic_tex2Dbias},
+ {"tex2Dgrad", 4, false, intrinsic_tex2Dgrad},
{"tex2Dlod", 2, false, intrinsic_tex2Dlod},
{"tex2Dproj", 2, false, intrinsic_tex2Dproj},
{"tex3D", -1, false, intrinsic_tex3D},
+ {"tex3Dgrad", 4, false, intrinsic_tex3Dgrad},
{"tex3Dproj", 2, false, intrinsic_tex3Dproj},
{"texCUBE", -1, false, intrinsic_texCUBE},
+ {"texCUBEgrad", 4, false, intrinsic_texCUBEgrad},
{"texCUBEproj", 2, false, intrinsic_texCUBEproj},
{"transpose", 1, true, intrinsic_transpose},
{"trunc", 1, true, intrinsic_trunc},
@@ -5693,6 +5798,7 @@ static bool state_block_add_entry(struct hlsl_state_block *state_block, struct h
%token KW_BREAK
%token KW_BUFFER
%token KW_CASE
+%token KW_CONSTANTBUFFER
%token KW_CBUFFER
%token KW_CENTROID
%token KW_COLUMN_MAJOR
@@ -5883,6 +5989,8 @@ static bool state_block_add_entry(struct hlsl_state_block *state_block, struct h
%type <if_body> if_body
+%type <intval> array
+
%type <modifiers> var_modifiers
%type <name> any_identifier
@@ -5954,19 +6062,31 @@ pass:
annotations_list:
variables_def_typed ';'
+ {
+ struct hlsl_block *block;
+
+ block = initialize_vars(ctx, $1);
+ destroy_block(block);
+ }
| annotations_list variables_def_typed ';'
+ {
+ struct hlsl_block *block;
+
+ block = initialize_vars(ctx, $2);
+ destroy_block(block);
+ }
annotations_opt:
%empty
{
$$ = NULL;
}
- | '<' scope_start '>'
+ | '<' annotations_scope_start '>'
{
hlsl_pop_scope(ctx);
$$ = NULL;
}
- | '<' scope_start annotations_list '>'
+ | '<' annotations_scope_start annotations_list '>'
{
struct hlsl_scope *scope = ctx->cur_scope;
@@ -6494,6 +6614,13 @@ switch_scope_start:
ctx->cur_scope->_switch = true;
}
+annotations_scope_start:
+ %empty
+ {
+ hlsl_push_scope(ctx);
+ ctx->cur_scope->annotations = true;
+ }
+
var_identifier:
VAR_IDENTIFIER
| NEW_IDENTIFIER
@@ -6545,22 +6672,34 @@ register_reservation:
':' KW_REGISTER '(' any_identifier ')'
{
memset(&$$, 0, sizeof($$));
- if (!parse_reservation_index($4, &$$.reg_type, &$$.reg_index))
+ if (!parse_reservation_index(ctx, $4, 0, &$$))
hlsl_error(ctx, &@4, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
"Invalid register reservation '%s'.", $4);
vkd3d_free($4);
}
+ | ':' KW_REGISTER '(' any_identifier '[' expr ']' ')'
+ {
+ memset(&$$, 0, sizeof($$));
+ if (!parse_reservation_index(ctx, $4, evaluate_static_expression_as_uint(ctx, $6, &@6), &$$))
+ {
+ hlsl_error(ctx, &@4, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
+ "Invalid register reservation '%s'.", $4);
+ }
+
+ vkd3d_free($4);
+ vkd3d_free($6);
+ }
| ':' KW_REGISTER '(' any_identifier ',' any_identifier ')'
{
memset(&$$, 0, sizeof($$));
- if (parse_reservation_index($6, &$$.reg_type, &$$.reg_index))
+ if (parse_reservation_index(ctx, $6, 0, &$$))
{
hlsl_fixme(ctx, &@4, "Reservation shader target %s.", $4);
}
else if (parse_reservation_space($6, &$$.reg_space))
{
- if (!parse_reservation_index($4, &$$.reg_type, &$$.reg_index))
+ if (!parse_reservation_index(ctx, $4, 0, &$$))
hlsl_error(ctx, &@4, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
"Invalid register reservation '%s'.", $4);
}
@@ -6573,12 +6712,45 @@ register_reservation:
vkd3d_free($4);
vkd3d_free($6);
}
+ | ':' KW_REGISTER '(' any_identifier '[' expr ']' ',' any_identifier ')'
+ {
+ memset(&$$, 0, sizeof($$));
+
+ if (!parse_reservation_space($9, &$$.reg_space))
+ hlsl_error(ctx, &@9, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
+ "Invalid register space reservation '%s'.", $9);
+
+ if (!parse_reservation_index(ctx, $4, evaluate_static_expression_as_uint(ctx, $6, &@6), &$$))
+ {
+ hlsl_error(ctx, &@4, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
+ "Invalid register reservation '%s'.", $4);
+ }
+
+ vkd3d_free($4);
+ vkd3d_free($6);
+ vkd3d_free($9);
+ }
+ | ':' KW_REGISTER '(' any_identifier ',' any_identifier '[' expr ']' ')'
+ {
+ hlsl_fixme(ctx, &@4, "Reservation shader target %s.", $4);
+
+ memset(&$$, 0, sizeof($$));
+ if (!parse_reservation_index(ctx, $6, evaluate_static_expression_as_uint(ctx, $8, &@8), &$$))
+ {
+ hlsl_error(ctx, &@6, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
+ "Invalid register reservation '%s'.", $6);
+ }
+
+ vkd3d_free($4);
+ vkd3d_free($6);
+ vkd3d_free($8);
+ }
| ':' KW_REGISTER '(' any_identifier ',' any_identifier ',' any_identifier ')'
{
hlsl_fixme(ctx, &@4, "Reservation shader target %s.", $4);
memset(&$$, 0, sizeof($$));
- if (!parse_reservation_index($6, &$$.reg_type, &$$.reg_index))
+ if (!parse_reservation_index(ctx, $6, 0, &$$))
hlsl_error(ctx, &@6, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
"Invalid register reservation '%s'.", $6);
@@ -6590,6 +6762,26 @@ register_reservation:
vkd3d_free($6);
vkd3d_free($8);
}
+ | ':' KW_REGISTER '(' any_identifier ',' any_identifier '[' expr ']' ',' any_identifier ')'
+ {
+ hlsl_fixme(ctx, &@4, "Reservation shader target %s.", $4);
+
+ memset(&$$, 0, sizeof($$));
+ if (!parse_reservation_index(ctx, $6, evaluate_static_expression_as_uint(ctx, $8, &@8), &$$))
+ {
+ hlsl_error(ctx, &@6, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
+ "Invalid register reservation '%s'.", $6);
+ }
+
+ if (!parse_reservation_space($11, &$$.reg_space))
+ hlsl_error(ctx, &@11, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
+ "Invalid register space reservation '%s'.", $11);
+
+ vkd3d_free($4);
+ vkd3d_free($6);
+ vkd3d_free($8);
+ vkd3d_free($11);
+ }
packoffset_reservation:
':' KW_PACKOFFSET '(' any_identifier ')'
@@ -6962,6 +7154,10 @@ type_no_void:
{
$$ = hlsl_get_type(ctx->cur_scope, "RenderTargetView", true, true);
}
+ | KW_DEPTHSTENCILSTATE
+ {
+ $$ = hlsl_get_type(ctx->cur_scope, "DepthStencilState", true, true);
+ }
| KW_DEPTHSTENCILVIEW
{
$$ = hlsl_get_type(ctx->cur_scope, "DepthStencilView", true, true);
@@ -6974,6 +7170,17 @@ type_no_void:
{
$$ = hlsl_get_type(ctx->cur_scope, "PixelShader", true, true);
}
+ | KW_CONSTANTBUFFER '<' type '>'
+ {
+ if ($3->class != HLSL_CLASS_STRUCT)
+ hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
+ "ConstantBuffer<...> requires user-defined structure type.");
+ $$ = hlsl_new_cb_type(ctx, $3);
+ }
+ | KW_RASTERIZERSTATE
+ {
+ $$ = hlsl_get_type(ctx->cur_scope, "RasterizerState", true, true);
+ }
type:
type_no_void
@@ -7258,52 +7465,43 @@ variable_def_typed:
$$->modifiers_loc = @1;
}
-arrays:
- %empty
+array:
+ '[' ']'
{
- $$.sizes = NULL;
- $$.count = 0;
+ $$ = HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT;
}
- | '[' expr ']' arrays
+ | '[' expr ']'
{
- uint32_t *new_array;
- unsigned int size;
-
- size = evaluate_static_expression_as_uint(ctx, $2, &@2);
-
- destroy_block($2);
-
- $$ = $4;
+ $$ = evaluate_static_expression_as_uint(ctx, $2, &@2);
- if (!size)
+ if (!$$)
{
hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_INVALID_SIZE,
"Array size is not a positive integer constant.");
- vkd3d_free($$.sizes);
YYABORT;
}
- if (size > 65536)
+ if ($$ > 65536)
{
hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_INVALID_SIZE,
- "Array size %u is not between 1 and 65536.", size);
- vkd3d_free($$.sizes);
+ "Array size %u is not between 1 and 65536.", $$);
YYABORT;
}
- if (!(new_array = hlsl_realloc(ctx, $$.sizes, ($$.count + 1) * sizeof(*new_array))))
- {
- vkd3d_free($$.sizes);
- YYABORT;
- }
- $$.sizes = new_array;
- $$.sizes[$$.count++] = size;
+ destroy_block($2);
+ }
+
+arrays:
+ %empty
+ {
+ $$.sizes = NULL;
+ $$.count = 0;
}
- | '[' ']' arrays
+ | array arrays
{
uint32_t *new_array;
- $$ = $3;
+ $$ = $2;
if (!(new_array = hlsl_realloc(ctx, $$.sizes, ($$.count + 1) * sizeof(*new_array))))
{
@@ -7312,7 +7510,7 @@ arrays:
}
$$.sizes = new_array;
- $$.sizes[$$.count++] = HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT;
+ $$.sizes[$$.count++] = $1;
}
var_modifiers:
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
index 36270b159a5..33845b0d4bf 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
@@ -1631,9 +1631,11 @@ static bool copy_propagation_transform_load(struct hlsl_ctx *ctx,
switch (type->class)
{
+ case HLSL_CLASS_DEPTH_STENCIL_STATE:
case HLSL_CLASS_SCALAR:
case HLSL_CLASS_VECTOR:
case HLSL_CLASS_PIXEL_SHADER:
+ case HLSL_CLASS_RASTERIZER_STATE:
case HLSL_CLASS_SAMPLER:
case HLSL_CLASS_TEXTURE:
case HLSL_CLASS_UAV:
@@ -1643,6 +1645,7 @@ static bool copy_propagation_transform_load(struct hlsl_ctx *ctx,
case HLSL_CLASS_MATRIX:
case HLSL_CLASS_ARRAY:
case HLSL_CLASS_STRUCT:
+ case HLSL_CLASS_CONSTANT_BUFFER:
/* FIXME: Actually we shouldn't even get here, but we don't split
* matrices yet. */
return false;
@@ -2562,11 +2565,11 @@ static bool lower_combined_samples(struct hlsl_ctx *ctx, struct hlsl_ir_node *in
case HLSL_RESOURCE_RESINFO:
case HLSL_RESOURCE_SAMPLE_CMP:
case HLSL_RESOURCE_SAMPLE_CMP_LZ:
- case HLSL_RESOURCE_SAMPLE_GRAD:
case HLSL_RESOURCE_SAMPLE_INFO:
return false;
case HLSL_RESOURCE_SAMPLE:
+ case HLSL_RESOURCE_SAMPLE_GRAD:
case HLSL_RESOURCE_SAMPLE_LOD:
case HLSL_RESOURCE_SAMPLE_LOD_BIAS:
case HLSL_RESOURCE_SAMPLE_PROJ:
@@ -4598,6 +4601,7 @@ static void sort_uniforms_by_numeric_bind_count(struct hlsl_ctx *ctx)
static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func)
{
+ struct register_allocator allocator_used = {0};
struct register_allocator allocator = {0};
struct hlsl_ir_var *var;
@@ -4606,6 +4610,7 @@ 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 bind_count = var->bind_count[HLSL_REGSET_NUMERIC];
if (!var->is_uniform || reg_size == 0)
continue;
@@ -4618,12 +4623,15 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi
assert(reg_size % 4 == 0);
for (i = 0; i < reg_size / 4; ++i)
{
- if (get_available_writemask(&allocator, 1, UINT_MAX, reg_idx + i) != VKD3DSP_WRITEMASK_ALL)
+ if (i < bind_count)
{
- hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
- "Overlapping register() reservations on 'c%u'.", reg_idx + i);
+ if (get_available_writemask(&allocator_used, 1, UINT_MAX, reg_idx + i) != VKD3DSP_WRITEMASK_ALL)
+ {
+ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
+ "Overlapping register() reservations on 'c%u'.", reg_idx + i);
+ }
+ record_allocation(ctx, &allocator_used, reg_idx + i, VKD3DSP_WRITEMASK_ALL, 1, UINT_MAX);
}
-
record_allocation(ctx, &allocator, reg_idx + i, VKD3DSP_WRITEMASK_ALL, 1, UINT_MAX);
}
@@ -4636,6 +4644,8 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi
}
}
+ vkd3d_free(allocator_used.allocations);
+
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
{
unsigned int alloc_size = 4 * var->bind_count[HLSL_REGSET_NUMERIC];
@@ -4777,7 +4787,7 @@ static const struct hlsl_buffer *get_reserved_buffer(struct hlsl_ctx *ctx, uint3
LIST_FOR_EACH_ENTRY(buffer, &ctx->buffers, const struct hlsl_buffer, entry)
{
- if (buffer->used_size && buffer->reservation.reg_type == 'b'
+ if (buffer->reservation.reg_type == 'b'
&& buffer->reservation.reg_space == space && buffer->reservation.reg_index == index)
return buffer;
}
@@ -4925,6 +4935,14 @@ void hlsl_calculate_buffer_offsets(struct hlsl_ctx *ctx)
}
}
+static unsigned int get_max_cbuffer_reg_index(struct hlsl_ctx *ctx)
+{
+ if (hlsl_version_ge(ctx, 5, 1))
+ return UINT_MAX;
+
+ return 13;
+}
+
static void allocate_buffers(struct hlsl_ctx *ctx)
{
struct hlsl_buffer *buffer;
@@ -4956,6 +4974,12 @@ static void allocate_buffers(struct hlsl_ctx *ctx)
{
const struct hlsl_buffer *reserved_buffer = get_reserved_buffer(ctx,
reservation->reg_space, reservation->reg_index);
+ unsigned int max_index = get_max_cbuffer_reg_index(ctx);
+
+ if (buffer->reservation.reg_index > max_index)
+ hlsl_error(ctx, &buffer->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
+ "Buffer reservation cb%u exceeds target's maximum (cb%u).",
+ buffer->reservation.reg_index, max_index);
if (reserved_buffer && reserved_buffer != buffer)
{
@@ -4980,9 +5004,14 @@ static void allocate_buffers(struct hlsl_ctx *ctx)
}
else if (!reservation->reg_type)
{
+ unsigned int max_index = get_max_cbuffer_reg_index(ctx);
while (get_reserved_buffer(ctx, 0, index))
++index;
+ if (index > max_index)
+ hlsl_error(ctx, &buffer->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
+ "Too many buffers allocated, target's maximum is %u.", max_index);
+
buffer->reg.space = 0;
buffer->reg.index = index;
if (hlsl_version_ge(ctx, 5, 1))
diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c
index 5f99be632f2..e5432cb35ce 100644
--- a/libs/vkd3d/libs/vkd3d-shader/ir.c
+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c
@@ -1899,13 +1899,42 @@ static enum vkd3d_result vsir_program_normalise_combined_samplers(struct vsir_pr
ins->src_count = 3;
break;
+ case VKD3DSIH_TEXLDD:
+ if (!(srcs = shader_src_param_allocator_get(&program->instructions.src_params, 5)))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+ memset(srcs, 0, sizeof(*srcs) * 5);
+
+ ins->opcode = VKD3DSIH_SAMPLE_GRAD;
+
+ srcs[0] = ins->src[0];
+
+ srcs[1].reg.type = VKD3DSPR_RESOURCE;
+ srcs[1].reg.idx[0] = ins->src[1].reg.idx[0];
+ srcs[1].reg.idx[1] = ins->src[1].reg.idx[0];
+ srcs[1].reg.idx_count = 2;
+ srcs[1].reg.data_type = VKD3D_DATA_RESOURCE;
+ srcs[1].reg.dimension = VSIR_DIMENSION_VEC4;
+ srcs[1].swizzle = VKD3D_SHADER_NO_SWIZZLE;
+
+ srcs[2].reg.type = VKD3DSPR_SAMPLER;
+ srcs[2].reg.idx[0] = ins->src[1].reg.idx[0];
+ srcs[2].reg.idx[1] = ins->src[1].reg.idx[0];
+ srcs[2].reg.idx_count = 2;
+ srcs[2].reg.data_type = VKD3D_DATA_SAMPLER;
+
+ srcs[3] = ins->src[2];
+ srcs[4] = ins->src[3];
+
+ ins->src = srcs;
+ ins->src_count = 5;
+ break;
+
case VKD3DSIH_TEXBEM:
case VKD3DSIH_TEXBEML:
case VKD3DSIH_TEXCOORD:
case VKD3DSIH_TEXDEPTH:
case VKD3DSIH_TEXDP3:
case VKD3DSIH_TEXDP3TEX:
- case VKD3DSIH_TEXLDD:
case VKD3DSIH_TEXLDL:
case VKD3DSIH_TEXM3x2PAD:
case VKD3DSIH_TEXM3x2TEX:
diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c
index 24206ae9a4d..ca7cdfd5217 100644
--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c
+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c
@@ -2984,11 +2984,13 @@ 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_STATE:
case HLSL_CLASS_DEPTH_STENCIL_VIEW:
case HLSL_CLASS_EFFECT_GROUP:
case HLSL_CLASS_STRUCT:
case HLSL_CLASS_PASS:
case HLSL_CLASS_PIXEL_SHADER:
+ case HLSL_CLASS_RASTERIZER_STATE:
case HLSL_CLASS_RENDER_TARGET_VIEW:
case HLSL_CLASS_SAMPLER:
case HLSL_CLASS_STRING:
@@ -2997,6 +2999,7 @@ static D3D_SHADER_VARIABLE_CLASS sm4_class(const struct hlsl_type *type)
case HLSL_CLASS_UAV:
case HLSL_CLASS_VERTEX_SHADER:
case HLSL_CLASS_VOID:
+ case HLSL_CLASS_CONSTANT_BUFFER:
break;
}
vkd3d_unreachable();
diff --git a/libs/vkd3d/libs/vkd3d/command.c b/libs/vkd3d/libs/vkd3d/command.c
index 6c463be8d60..2354938c08d 100644
--- a/libs/vkd3d/libs/vkd3d/command.c
+++ b/libs/vkd3d/libs/vkd3d/command.c
@@ -2034,11 +2034,12 @@ static bool vk_barrier_parameters_from_d3d12_resource_state(unsigned int state,
if (vk_queue_flags & VK_QUEUE_GRAPHICS_BIT)
{
queue_shader_stages |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
- | VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT
- | VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT
| VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
if (device->vk_info.geometry_shaders)
queue_shader_stages |= VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT;
+ if (device->vk_info.tessellation_shaders)
+ queue_shader_stages |= VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT
+ | VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT;
}
if (vk_queue_flags & VK_QUEUE_COMPUTE_BIT)
queue_shader_stages |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
diff --git a/libs/vkd3d/libs/vkd3d/device.c b/libs/vkd3d/libs/vkd3d/device.c
index 674e46fe5c5..2bbc170504e 100644
--- a/libs/vkd3d/libs/vkd3d/device.c
+++ b/libs/vkd3d/libs/vkd3d/device.c
@@ -1644,6 +1644,7 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device,
vulkan_info->device_limits = physical_device_info->properties2.properties.limits;
vulkan_info->sparse_properties = physical_device_info->properties2.properties.sparseProperties;
vulkan_info->geometry_shaders = physical_device_info->features2.features.geometryShader;
+ vulkan_info->tessellation_shaders = physical_device_info->features2.features.tessellationShader;
vulkan_info->sparse_binding = features->sparseBinding;
vulkan_info->sparse_residency_3d = features->sparseResidencyImage3D;
vulkan_info->rasterization_stream = physical_device_info->xfb_properties.transformFeedbackRasterizationStreamSelect;
diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/libs/vkd3d/vkd3d_private.h
index a55e967cdfc..7acd39d65be 100644
--- a/libs/vkd3d/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/libs/vkd3d/vkd3d_private.h
@@ -147,6 +147,7 @@ struct vkd3d_vulkan_info
bool rasterization_stream;
bool transform_feedback_queries;
bool geometry_shaders;
+ bool tessellation_shaders;
bool uav_read_without_format;
--
2.43.0