mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-01-28 22:04:43 -08:00
1884 lines
75 KiB
Diff
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
|
|
|