wine-staging/patches/vkd3d-latest/0002-Updated-vkd3d-to-c8cc1b1a2476a4c518756fd7604d37e8c16.patch

1778 lines
77 KiB
Diff
Raw Permalink Normal View History

2024-08-19 14:49:47 -07:00
From 5942f59d8cade40d6bb21f8c46fc05fcee79dbb3 Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Tue, 20 Aug 2024 06:47:55 +1000
Subject: [PATCH] Updated vkd3d to c8cc1b1a2476a4c518756fd7604d37e8c1611af3.
---
libs/vkd3d/include/private/vkd3d_memory.h | 3 +-
libs/vkd3d/include/vkd3d_shader.h | 2 +-
libs/vkd3d/libs/vkd3d-common/debug.c | 1 -
libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 2 +-
libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 10 +-
libs/vkd3d/libs/vkd3d-shader/dxil.c | 4 +-
libs/vkd3d/libs/vkd3d-shader/fx.c | 389 +++++++++++++++---
libs/vkd3d/libs/vkd3d-shader/glsl.c | 6 +-
libs/vkd3d/libs/vkd3d-shader/hlsl.c | 45 +-
libs/vkd3d/libs/vkd3d-shader/hlsl.h | 10 +-
libs/vkd3d/libs/vkd3d-shader/hlsl.l | 2 +
libs/vkd3d/libs/vkd3d-shader/hlsl.y | 125 ++++--
libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 2 +
libs/vkd3d/libs/vkd3d-shader/ir.c | 36 +-
libs/vkd3d/libs/vkd3d-shader/tpf.c | 94 +++--
.../libs/vkd3d-shader/vkd3d_shader_private.h | 1 -
libs/vkd3d/libs/vkd3d/resource.c | 2 +-
libs/vkd3d/libs/vkd3d/state.c | 12 +-
libs/vkd3d/libs/vkd3d/vkd3d_private.h | 3 +-
19 files changed, 582 insertions(+), 167 deletions(-)
diff --git a/libs/vkd3d/include/private/vkd3d_memory.h b/libs/vkd3d/include/private/vkd3d_memory.h
index 682d35c03c6..e191dc11b73 100644
--- a/libs/vkd3d/include/private/vkd3d_memory.h
+++ b/libs/vkd3d/include/private/vkd3d_memory.h
@@ -19,7 +19,6 @@
#ifndef __VKD3D_MEMORY_H
#define __VKD3D_MEMORY_H
-#include <assert.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
@@ -44,7 +43,7 @@ static inline void *vkd3d_realloc(void *ptr, size_t size)
static inline void *vkd3d_calloc(size_t count, size_t size)
{
void *ptr;
- assert(count <= ~(size_t)0 / size);
+ VKD3D_ASSERT(count <= ~(size_t)0 / size);
if (!(ptr = calloc(count, size)))
ERR("Out of memory.\n");
return ptr;
diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h
index d4756810065..d37d8ebad9e 100644
--- a/libs/vkd3d/include/vkd3d_shader.h
+++ b/libs/vkd3d/include/vkd3d_shader.h
@@ -1876,7 +1876,7 @@ enum vkd3d_shader_sysval_semantic
VKD3D_SHADER_SV_VIEWPORT_ARRAY_INDEX = 0x05,
/** Vertex ID; SV_VertexID in Direct3D. */
VKD3D_SHADER_SV_VERTEX_ID = 0x06,
- /** Primtive ID; SV_PrimitiveID in Direct3D. */
+ /** Primitive ID; SV_PrimitiveID in Direct3D. */
VKD3D_SHADER_SV_PRIMITIVE_ID = 0x07,
/** Instance ID; SV_InstanceID in Direct3D. */
VKD3D_SHADER_SV_INSTANCE_ID = 0x08,
diff --git a/libs/vkd3d/libs/vkd3d-common/debug.c b/libs/vkd3d/libs/vkd3d-common/debug.c
index 4bfc19bd9a1..9a92f0ead02 100644
--- a/libs/vkd3d/libs/vkd3d-common/debug.c
+++ b/libs/vkd3d/libs/vkd3d-common/debug.c
@@ -22,7 +22,6 @@
#include "vkd3d_common.h"
-#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <inttypes.h>
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
index 2c2f0c43ece..77e9711300f 100644
--- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
+++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
@@ -2251,7 +2251,7 @@ static const char *get_semantic_register_name(enum vkd3d_shader_sysval_semantic
case VKD3D_SHADER_SV_DEPTH_GREATER_EQUAL: return "oDepthGE";
case VKD3D_SHADER_SV_DEPTH_LESS_EQUAL: return "oDepthLE";
/* SV_Coverage has name vCoverage when used as an input,
- * but it doens't appear in the signature in that case. */
+ * but it doesn't appear in the signature in that case. */
case VKD3D_SHADER_SV_COVERAGE: return "oMask";
case VKD3D_SHADER_SV_STENCIL_REF: return "oStencilRef";
default: return "??";
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
index a4c038a233a..d05394c3ab7 100644
--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
@@ -1523,6 +1523,8 @@ D3DXPARAMETER_CLASS hlsl_sm1_class(const struct hlsl_type *type)
case HLSL_CLASS_DOMAIN_SHADER:
case HLSL_CLASS_HULL_SHADER:
case HLSL_CLASS_GEOMETRY_SHADER:
+ case HLSL_CLASS_BLEND_STATE:
+ case HLSL_CLASS_NULL:
break;
}
@@ -1626,6 +1628,8 @@ D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type)
case HLSL_CLASS_DOMAIN_SHADER:
case HLSL_CLASS_HULL_SHADER:
case HLSL_CLASS_GEOMETRY_SHADER:
+ case HLSL_CLASS_BLEND_STATE:
+ case HLSL_CLASS_NULL:
break;
}
@@ -1826,17 +1830,17 @@ void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buff
break;
case HLSL_TYPE_INT:
- uni.f = var->default_values[k].value.i;
+ uni.f = var->default_values[k].number.i;
break;
case HLSL_TYPE_UINT:
case HLSL_TYPE_BOOL:
- uni.f = var->default_values[k].value.u;
+ uni.f = var->default_values[k].number.u;
break;
case HLSL_TYPE_HALF:
case HLSL_TYPE_FLOAT:
- uni.u = var->default_values[k].value.u;
+ uni.u = var->default_values[k].number.u;
break;
default:
diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c
index 2a0bbe1a625..4a17c62292b 100644
--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c
+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c
@@ -4298,7 +4298,7 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco
if (!(flags & FP_ALLOW_UNSAFE_ALGEBRA))
ins->flags |= VKD3DSI_PRECISE_X;
flags &= ~FP_ALLOW_UNSAFE_ALGEBRA;
- /* SPIR-V FPFastMathMode is only available in the Kernel executon model. */
+ /* SPIR-V FPFastMathMode is only available in the Kernel execution model. */
silence_warning = !(flags & ~(FP_NO_NAN | FP_NO_INF | FP_NO_SIGNED_ZEROS | FP_ALLOW_RECIPROCAL));
break;
case VKD3DSIH_IADD:
@@ -5211,7 +5211,7 @@ static void sm6_parser_emit_dx_get_dimensions(struct sm6_parser *sm6, enum dx_in
instruction_dst_param_init_temp_vector(ins++, sm6);
state->temp_idx = 1;
- /* DXIL does not have an instrinsic for sample info, and resinfo is expected to return
+ /* DXIL does not have an intrinsic for sample info, and resinfo is expected to return
* the sample count in .w for MS textures. The result is always a struct of 4 x uint32. */
vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_SAMPLE_INFO);
ins->flags = VKD3DSI_SAMPLE_INFO_UINT;
diff --git a/libs/vkd3d/libs/vkd3d-shader/fx.c b/libs/vkd3d/libs/vkd3d-shader/fx.c
index e3ebbafb3f4..a1d1fd6572f 100644
--- a/libs/vkd3d/libs/vkd3d-shader/fx.c
+++ b/libs/vkd3d/libs/vkd3d-shader/fx.c
@@ -111,7 +111,7 @@ static void get_state_block_function_components(const struct state_block_functio
{
unsigned int i;
- assert(comp_count <= info->max_args);
+ VKD3D_ASSERT(comp_count <= info->max_args);
if (info->min_args == info->max_args)
{
@@ -205,6 +205,8 @@ struct fx_write_context
uint32_t sampler_state_count;
uint32_t depth_stencil_state_count;
uint32_t rasterizer_state_count;
+ uint32_t blend_state_count;
+ uint32_t string_count;
int status;
bool child_effect;
@@ -565,6 +567,9 @@ static const char * get_fx_4_type_name(const struct hlsl_type *type)
case HLSL_CLASS_PIXEL_SHADER:
return "PixelShader";
+ case HLSL_CLASS_STRING:
+ return "String";
+
default:
return type->name;
}
@@ -636,6 +641,8 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co
case HLSL_CLASS_DOMAIN_SHADER:
case HLSL_CLASS_HULL_SHADER:
case HLSL_CLASS_GEOMETRY_SHADER:
+ case HLSL_CLASS_BLEND_STATE:
+ case HLSL_CLASS_STRING:
put_u32_unaligned(buffer, 2);
break;
@@ -648,9 +655,9 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co
case HLSL_CLASS_PASS:
case HLSL_CLASS_TECHNIQUE:
case HLSL_CLASS_CONSTANT_BUFFER:
+ case HLSL_CLASS_NULL:
vkd3d_unreachable();
- case HLSL_CLASS_STRING:
case HLSL_CLASS_VOID:
FIXME("Writing type class %u is not implemented.\n", type->class);
set_status(fx, VKD3D_ERROR_NOT_IMPLEMENTED);
@@ -754,6 +761,14 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co
{
put_u32_unaligned(buffer, 3);
}
+ else if (type->class == HLSL_CLASS_BLEND_STATE)
+ {
+ put_u32_unaligned(buffer, 2);
+ }
+ else if (type->class == HLSL_CLASS_STRING)
+ {
+ put_u32_unaligned(buffer, 1);
+ }
else if (hlsl_is_numeric_type(type))
{
numeric_desc = get_fx_4_numeric_type_description(type, fx);
@@ -879,6 +894,13 @@ static uint32_t write_fx_2_string(const char *string, struct fx_write_context *f
return offset;
}
+static uint32_t get_fx_2_type_class(const struct hlsl_type *type)
+{
+ if (type->class == HLSL_CLASS_MATRIX)
+ return D3DXPC_MATRIX_ROWS;
+ return hlsl_sm1_class(type);
+}
+
static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *name, const struct hlsl_semantic *semantic,
struct fx_write_context *fx)
{
@@ -897,7 +919,7 @@ static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *n
semantic_offset = semantic->raw_name ? write_string(semantic->raw_name, fx) : 0;
offset = put_u32(buffer, hlsl_sm1_base_type(type));
- put_u32(buffer, hlsl_sm1_class(type));
+ put_u32(buffer, get_fx_2_type_class(type));
put_u32(buffer, name_offset);
put_u32(buffer, semantic_offset);
put_u32(buffer, elements_count);
@@ -1078,12 +1100,14 @@ static bool is_type_supported_fx_2(struct hlsl_ctx *ctx, const struct hlsl_type
case HLSL_CLASS_DOMAIN_SHADER:
case HLSL_CLASS_HULL_SHADER:
case HLSL_CLASS_GEOMETRY_SHADER:
+ case HLSL_CLASS_BLEND_STATE:
return false;
case HLSL_CLASS_EFFECT_GROUP:
case HLSL_CLASS_PASS:
case HLSL_CLASS_TECHNIQUE:
case HLSL_CLASS_CONSTANT_BUFFER:
+ case HLSL_CLASS_NULL:
/* This cannot appear as an extern variable. */
break;
}
@@ -1234,7 +1258,7 @@ static uint32_t write_fx_4_default_value(struct hlsl_type *value_type, struct hl
for (j = 0; j < comp_count; ++j)
{
- put_u32_unaligned(buffer, value->value.u);
+ put_u32_unaligned(buffer, value->number.u);
value++;
}
break;
@@ -1264,6 +1288,27 @@ static uint32_t write_fx_4_default_value(struct hlsl_type *value_type, struct hl
return offset;
}
+static void write_fx_4_string_initializer(struct hlsl_ir_var *var, struct fx_write_context *fx)
+{
+ uint32_t elements_count = hlsl_get_multiarray_size(var->data_type), i;
+ const struct hlsl_default_value *value = var->default_values;
+ struct vkd3d_bytecode_buffer *buffer = &fx->structured;
+ struct hlsl_ctx *ctx = fx->ctx;
+ uint32_t offset;
+
+ if (!value)
+ {
+ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "String objects have to be initialized.");
+ return;
+ }
+
+ for (i = 0; i < elements_count; ++i, ++value)
+ {
+ offset = write_fx_4_string(value->string, fx);
+ put_u32(buffer, 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;
@@ -1322,6 +1367,10 @@ static void write_fx_4_annotation(struct hlsl_ir_var *var, struct fx_write_conte
offset = write_fx_4_default_value(var->data_type, var->default_values, fx);
put_u32(buffer, offset);
}
+ else if (type->class == HLSL_CLASS_STRING)
+ {
+ write_fx_4_string_initializer(var, fx);
+ }
else
{
hlsl_fixme(ctx, &var->loc, "Writing annotations for type class %u is not implemented.", type->class);
@@ -1429,17 +1478,28 @@ static void write_fx_4_state_assignment(const struct hlsl_ir_var *var, struct hl
set_u32(buffer, rhs_offset, value_offset);
}
-static bool state_block_contains_state(const char *name, unsigned int start, struct hlsl_state_block *block)
+static bool state_block_contains_state(const struct hlsl_state_block_entry *entry, unsigned int start_index,
+ struct hlsl_state_block *block)
{
unsigned int i;
- for (i = start; i < block->count; ++i)
+ for (i = start_index; i < block->count; ++i)
{
- if (block->entries[i]->is_function_call)
+ const struct hlsl_state_block_entry *cur = block->entries[i];
+
+ if (cur->is_function_call)
continue;
- if (!ascii_strcasecmp(block->entries[i]->name, name))
- return true;
+ if (ascii_strcasecmp(cur->name, entry->name))
+ continue;
+
+ if (cur->lhs_has_index != entry->lhs_has_index)
+ continue;
+
+ if (cur->lhs_has_index && cur->lhs_index != entry->lhs_index)
+ continue;
+
+ return true;
}
return false;
@@ -1451,6 +1511,24 @@ struct replace_state_context
struct hlsl_ir_var *var;
};
+static bool lower_null_constant(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
+{
+ struct hlsl_ir_node *c;
+
+ if (instr->type != HLSL_IR_CONSTANT)
+ return false;
+ if (instr->data_type->class != HLSL_CLASS_NULL)
+ return false;
+
+ if (!(c = hlsl_new_uint_constant(ctx, 0, &instr->loc)))
+ return false;
+
+ list_add_before(&instr->entry, &c->entry);
+ hlsl_replace_node(instr, c);
+
+ return true;
+}
+
static bool replace_state_block_constant(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
{
struct replace_state_context *replace_context = context;
@@ -1480,17 +1558,6 @@ 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,
@@ -1505,6 +1572,9 @@ enum state_property_component_type
FX_TEXTURE,
FX_DEPTHSTENCILVIEW,
FX_RENDERTARGETVIEW,
+ FX_BLEND,
+ FX_VERTEXSHADER,
+ FX_PIXELSHADER,
};
static inline bool is_object_fx_type(enum state_property_component_type type)
@@ -1519,6 +1589,9 @@ static inline bool is_object_fx_type(enum state_property_component_type type)
case FX_TEXTURE:
case FX_RENDERTARGETVIEW:
case FX_DEPTHSTENCILVIEW:
+ case FX_BLEND:
+ case FX_VERTEXSHADER:
+ case FX_PIXELSHADER:
return true;
default:
return false;
@@ -1545,6 +1618,12 @@ static inline enum hlsl_type_class hlsl_type_class_from_fx_type(enum state_prope
return HLSL_CLASS_RENDER_TARGET_VIEW;
case FX_DEPTHSTENCILVIEW:
return HLSL_CLASS_DEPTH_STENCIL_VIEW;
+ case FX_BLEND:
+ return HLSL_CLASS_BLEND_STATE;
+ case FX_VERTEXSHADER:
+ return HLSL_CLASS_VERTEX_SHADER;
+ case FX_PIXELSHADER:
+ return HLSL_CLASS_PIXEL_SHADER;
default:
vkd3d_unreachable();
}
@@ -1663,6 +1742,51 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl
{ NULL }
};
+ static const struct rhs_named_value blend_values[] =
+ {
+ { "ZERO", 1 },
+ { "ONE", 2 },
+ { "SRC_COLOR", 3 },
+ { "INV_SRC_COLOR", 4 },
+ { "SRC_ALPHA", 5 },
+ { "INV_SRC_ALPHA", 6 },
+ { "DEST_ALPHA", 7 },
+ { "INV_DEST_ALPHA", 8 },
+ { "DEST_COLOR", 9 },
+ { "INV_DEST_COLOR", 10 },
+ { "SRC_ALPHA_SAT", 11 },
+ { "BLEND_FACTOR", 14 },
+ { "INV_BLEND_FACTOR", 15 },
+ { "SRC1_COLOR", 16 },
+ { "INV_SRC1_COLOR", 17 },
+ { "SRC1_ALPHA", 18 },
+ { "INV_SRC1_ALPHA", 19 },
+ { NULL }
+ };
+
+ static const struct rhs_named_value blendop_values[] =
+ {
+ { "ADD", 1 },
+ { "SUBTRACT", 2 },
+ { "REV_SUBTRACT", 3 },
+ { "MIN", 4 },
+ { "MAX", 5 },
+ { NULL }
+ };
+
+ static const struct rhs_named_value bool_values[] =
+ {
+ { "FALSE", 0 },
+ { "TRUE", 1 },
+ { NULL }
+ };
+
+ static const struct rhs_named_value null_values[] =
+ {
+ { "NULL", 0 },
+ { NULL }
+ };
+
static const struct state
{
const char *name;
@@ -1676,29 +1800,33 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl
}
states[] =
{
- { "RasterizerState", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_RASTERIZER, 1, 1, 0 },
- { "DepthStencilState", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_DEPTHSTENCIL, 1, 1, 1 },
-
+ { "RasterizerState", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_RASTERIZER, 1, 1, 0 },
+ { "DepthStencilState", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_DEPTHSTENCIL, 1, 1, 1 },
+ { "BlendState", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_BLEND, 1, 1, 2 },
{ "RenderTargetView", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_RENDERTARGETVIEW, 1, 8, 3 },
{ "DepthStencilView", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_DEPTHSTENCILVIEW, 1, 1, 4 },
- { "DS_StencilRef", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 9 },
+ { "VertexShader", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_VERTEXSHADER, 1, 1, 6 },
+ { "PixelShader", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_PIXELSHADER, 1, 1, 7 },
+ { "DS_StencilRef", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 9 },
+ { "AB_BlendFactor", HLSL_CLASS_PASS, HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 10 },
+ { "AB_SampleMask", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 11 },
{ "FillMode", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 12, fill_values },
{ "CullMode", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 13, cull_values },
- { "FrontCounterClockwise", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 14 },
+ { "FrontCounterClockwise", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 14, bool_values },
{ "DepthBias", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 15 },
{ "DepthBiasClamp", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 16 },
{ "SlopeScaledDepthBias", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 17 },
- { "DepthClipEnable", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 18 },
- { "ScissorEnable", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 19 },
- { "MultisampleEnable", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 20 },
- { "AntializedLineEnable", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 21 },
+ { "DepthClipEnable", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 18, bool_values },
+ { "ScissorEnable", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 19, bool_values },
+ { "MultisampleEnable", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 20, bool_values },
+ { "AntializedLineEnable", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 21, bool_values },
- { "DepthEnable", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 22 },
+ { "DepthEnable", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 22, bool_values },
{ "DepthWriteMask", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 23, depth_write_mask_values },
{ "DepthFunc", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 24, comparison_values },
- { "StencilEnable", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 25 },
+ { "StencilEnable", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 25, bool_values },
{ "StencilReadMask", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_UINT8, 1, 1, 26 },
{ "StencilWriteMask", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_UINT8, 1, 1, 27 },
{ "FrontFaceStencilFail", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 28, stencil_op_values },
@@ -1720,12 +1848,45 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl
{ "BorderColor", HLSL_CLASS_SAMPLER, HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 52 },
{ "MinLOD", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 53 },
{ "MaxLOD", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 54 },
- { "Texture", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_TEXTURE, 1, 1, 55 },
+ { "Texture", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_TEXTURE, 1, 1, 55, null_values },
{ "HullShader", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_HULLSHADER, 1, 1, 56 },
{ "DomainShader", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_DOMAINSHADER, 1, 1, 57 },
{ "ComputeShader", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_COMPUTESHADER, 1, 1, 58 },
};
+
+ static const struct state fx_4_blend_states[] =
+ {
+ { "AlphaToCoverageEnable", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 36, bool_values },
+ { "BlendEnable", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 8, 37, bool_values },
+ { "SrcBlend", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 38, blend_values },
+ { "DestBlend", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 39, blend_values },
+ { "BlendOp", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 40, blendop_values },
+ { "SrcBlendAlpha", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 41, blend_values },
+ { "DestBlendAlpha", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 42, blend_values },
+ { "BlendOpAlpha", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 43, blendop_values },
+ { "RenderTargetWriteMask", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT8, 1, 8, 44 },
+ };
+
+ static const struct state fx_5_blend_states[] =
+ {
+ { "AlphaToCoverageEnable", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 36, bool_values },
+ { "BlendEnable", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 8, 37, bool_values },
+ { "SrcBlend", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 38, blend_values },
+ { "DestBlend", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 39, blend_values },
+ { "BlendOp", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 40, blendop_values },
+ { "SrcBlendAlpha", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 41, blend_values },
+ { "DestBlendAlpha", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 42, blend_values },
+ { "BlendOpAlpha", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 43, blendop_values },
+ { "RenderTargetWriteMask", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT8, 1, 8, 44 },
+ };
+
+ struct state_table
+ {
+ const struct state *ptr;
+ unsigned int count;
+ } table;
+
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;
@@ -1733,15 +1894,33 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl
const struct state *state = NULL;
struct hlsl_ctx *ctx = fx->ctx;
enum hlsl_base_type base_type;
- struct hlsl_ir_load *load;
unsigned int i;
- for (i = 0; i < ARRAY_SIZE(states); ++i)
+ if (type->class == HLSL_CLASS_BLEND_STATE)
{
- if (type->class == states[i].container
- && !ascii_strcasecmp(entry->name, states[i].name))
+ if (ctx->profile->major_version == 4)
{
- state = &states[i];
+ table.ptr = fx_4_blend_states;
+ table.count = ARRAY_SIZE(fx_4_blend_states);
+ }
+ else
+ {
+ table.ptr = fx_5_blend_states;
+ table.count = ARRAY_SIZE(fx_5_blend_states);
+ }
+ }
+ else
+ {
+ table.ptr = states;
+ table.count = ARRAY_SIZE(states);
+ }
+
+ for (i = 0; i < table.count; ++i)
+ {
+ if (type->class == table.ptr[i].container
+ && !ascii_strcasecmp(entry->name, table.ptr[i].name))
+ {
+ state = &table.ptr[i];
break;
}
}
@@ -1786,8 +1965,9 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl
replace_context.var = var;
/* Turn named constants to actual constants. */
+ hlsl_transform_ir(ctx, lower_null_constant, entry->instrs, NULL);
hlsl_transform_ir(ctx, replace_state_block_constant, entry->instrs, &replace_context);
- fold_state_value(ctx, entry);
+ hlsl_run_const_passes(ctx, entry->instrs);
/* Now cast and run folding again. */
@@ -1798,7 +1978,8 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl
switch (node->type)
{
case HLSL_IR_LOAD:
- load = hlsl_ir_load(node);
+ {
+ struct hlsl_ir_load *load = hlsl_ir_load(node);
if (load->src.path_len)
hlsl_fixme(ctx, &ctx->location, "Arrays are not supported for RHS.");
@@ -1810,6 +1991,26 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl
}
break;
+ }
+ case HLSL_IR_CONSTANT:
+ {
+ struct hlsl_ir_constant *c = hlsl_ir_constant(node);
+ struct hlsl_type *data_type = c->node.data_type;
+
+ if (data_type->class == HLSL_CLASS_SCALAR && data_type->e.numeric.type == HLSL_TYPE_UINT)
+ {
+ if (c->value.u[0].u != 0)
+ hlsl_error(ctx, &ctx->location, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX,
+ "Only 0 integer constants are allowed for object-typed fields.");
+ }
+ else
+ {
+ hlsl_error(ctx, &ctx->location, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX,
+ "Unexpected constant used for object-typed field.");
+ }
+
+ break;
+ }
default:
hlsl_fixme(ctx, &ctx->location, "Unhandled node type for object-typed field.");
}
@@ -1857,11 +2058,27 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl
hlsl_src_remove(entry->args);
hlsl_src_from_node(entry->args, cast);
- fold_state_value(ctx, entry);
+ hlsl_run_const_passes(ctx, entry->instrs);
}
}
-static unsigned int decompose_fx_4_state_block(struct hlsl_ir_var *var, struct hlsl_state_block *block,
+static bool decompose_fx_4_state_add_entries(struct hlsl_state_block *block, unsigned int entry_index,
+ unsigned int count)
+{
+ if (!vkd3d_array_reserve((void **)&block->entries, &block->capacity, block->count + count, sizeof(*block->entries)))
+ return false;
+
+ if (entry_index != block->count - 1)
+ {
+ memmove(&block->entries[entry_index + count + 1], &block->entries[entry_index + 1],
+ (block->count - entry_index - 1) * sizeof(*block->entries));
+ }
+ block->count += count;
+
+ return true;
+}
+
+static unsigned int decompose_fx_4_state_function_call(struct hlsl_ir_var *var, struct hlsl_state_block *block,
unsigned int entry_index, struct fx_write_context *fx)
{
struct hlsl_state_block_entry *entry = block->entries[entry_index];
@@ -1891,15 +2108,8 @@ static unsigned int decompose_fx_4_state_block(struct hlsl_ir_var *var, struct h
return 1;
}
- if (!vkd3d_array_reserve((void **)&block->entries, &block->capacity, block->count + entry->args_count - 1,
- sizeof(*block->entries)))
+ if (!decompose_fx_4_state_add_entries(block, entry_index, entry->args_count - 1))
return 1;
- if (entry_index != block->count - 1)
- {
- memmove(&block->entries[entry_index + entry->args_count], &block->entries[entry_index + 1],
- (block->count - entry_index - 1) * sizeof(*block->entries));
- }
- block->count += entry->args_count - 1;
get_state_block_function_components(info, components, entry->args_count);
@@ -1915,6 +2125,62 @@ static unsigned int decompose_fx_4_state_block(struct hlsl_ir_var *var, struct h
return entry->args_count;
}
+/* For some states assignment sets all of the elements. This behaviour is limited to certain states of BlendState
+ object, and only when fx_5_0 profile is used. */
+static unsigned int decompose_fx_4_state_block_expand_array(struct hlsl_ir_var *var, struct hlsl_state_block *block,
+ unsigned int entry_index, struct fx_write_context *fx)
+{
+ static const char *states[] = { "SrcBlend", "DestBlend", "BlendOp", "SrcBlendAlpha", "DestBlendAlpha", "BlendOpAlpha" };
+ const struct hlsl_type *type = hlsl_get_multiarray_element_type(var->data_type);
+ struct hlsl_state_block_entry *entry = block->entries[entry_index];
+ static const unsigned int array_size = 8;
+ struct hlsl_ctx *ctx = fx->ctx;
+ bool found = false;
+ unsigned int i;
+
+ if (type->class != HLSL_CLASS_BLEND_STATE)
+ return 1;
+ if (ctx->profile->major_version != 5)
+ return 1;
+ if (entry->lhs_has_index)
+ return 1;
+
+ for (i = 0; i < ARRAY_SIZE(states); ++i)
+ {
+ if (!ascii_strcasecmp(entry->name, states[i]))
+ {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ return 1;
+
+ if (!decompose_fx_4_state_add_entries(block, entry_index, array_size - 1))
+ return 1;
+
+ block->entries[entry_index]->lhs_has_index = true;
+ for (i = 1; i < array_size; ++i)
+ {
+ block->entries[entry_index + i] = clone_stateblock_entry(ctx, entry,
+ entry->name, true, i, 0);
+ }
+
+ return array_size;
+}
+
+static unsigned int decompose_fx_4_state_block(struct hlsl_ir_var *var, struct hlsl_state_block *block,
+ unsigned int entry_index, struct fx_write_context *fx)
+{
+ struct hlsl_state_block_entry *entry = block->entries[entry_index];
+
+ if (entry->is_function_call)
+ return decompose_fx_4_state_function_call(var, block, entry_index, fx);
+
+ return decompose_fx_4_state_block_expand_array(var, block, entry_index, fx);
+}
+
static void write_fx_4_state_block(struct hlsl_ir_var *var, unsigned int block_index,
uint32_t count_offset, struct fx_write_context *fx)
{
@@ -1936,7 +2202,7 @@ static void write_fx_4_state_block(struct hlsl_ir_var *var, unsigned int block_i
struct hlsl_state_block_entry *entry = block->entries[i];
/* Skip if property is reassigned later. This will use the last assignment. */
- if (state_block_contains_state(entry->name, i + 1, block))
+ if (state_block_contains_state(entry, i + 1, block))
continue;
/* Resolve special constant names and property names. */
@@ -2069,6 +2335,16 @@ static void write_fx_4_object_variable(struct hlsl_ir_var *var, struct fx_write_
fx->rasterizer_state_count += elements_count;
break;
+ case HLSL_CLASS_BLEND_STATE:
+ write_fx_4_state_object_initializer(var, fx);
+ fx->blend_state_count += elements_count;
+ break;
+
+ case HLSL_CLASS_STRING:
+ write_fx_4_string_initializer(var, fx);
+ fx->string_count += elements_count;
+ break;
+
default:
hlsl_fixme(ctx, &ctx->location, "Writing initializer for object class %u is not implemented.",
type->class);
@@ -2170,6 +2446,9 @@ static bool is_supported_object_variable(const struct hlsl_ctx *ctx, const struc
case HLSL_CLASS_RENDER_TARGET_VIEW:
case HLSL_CLASS_SAMPLER:
case HLSL_CLASS_TEXTURE:
+ case HLSL_CLASS_BLEND_STATE:
+ case HLSL_CLASS_VERTEX_SHADER:
+ case HLSL_CLASS_STRING:
return true;
case HLSL_CLASS_COMPUTE_SHADER:
case HLSL_CLASS_DOMAIN_SHADER:
@@ -2183,8 +2462,6 @@ static bool is_supported_object_variable(const struct hlsl_ctx *ctx, const struc
if (type->e.resource.rasteriser_ordered)
return false;
return true;
- case HLSL_CLASS_VERTEX_SHADER:
- return true;
default:
return false;
@@ -2237,10 +2514,10 @@ static int hlsl_fx_4_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out)
put_u32(&buffer, fx.shared_object_count);
put_u32(&buffer, fx.technique_count);
size_offset = put_u32(&buffer, 0); /* Unstructured size. */
- put_u32(&buffer, 0); /* String count. */
+ put_u32(&buffer, fx.string_count);
put_u32(&buffer, fx.texture_count);
put_u32(&buffer, fx.depth_stencil_state_count);
- put_u32(&buffer, 0); /* Blend state count. */
+ put_u32(&buffer, fx.blend_state_count);
put_u32(&buffer, fx.rasterizer_state_count);
put_u32(&buffer, fx.sampler_state_count);
put_u32(&buffer, fx.rtv_count);
@@ -2295,10 +2572,10 @@ static int hlsl_fx_5_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out)
put_u32(&buffer, fx.shared_object_count);
put_u32(&buffer, fx.technique_count);
size_offset = put_u32(&buffer, 0); /* Unstructured size. */
- put_u32(&buffer, 0); /* String count. */
+ put_u32(&buffer, fx.string_count);
put_u32(&buffer, fx.texture_count);
put_u32(&buffer, fx.depth_stencil_state_count);
- put_u32(&buffer, 0); /* Blend state count. */
+ put_u32(&buffer, fx.blend_state_count);
put_u32(&buffer, fx.rasterizer_state_count);
put_u32(&buffer, fx.sampler_state_count);
put_u32(&buffer, fx.rtv_count);
diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c
index 10e12ea56f2..d1f02ab568b 100644
--- a/libs/vkd3d/libs/vkd3d-shader/glsl.c
+++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c
@@ -115,7 +115,7 @@ static void glsl_src_init(struct glsl_src *glsl_src, struct vkd3d_glsl_generator
if (reg->non_uniform)
vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
- "Internal compiler error: Unhandled 'non-uniform' modifer.");
+ "Internal compiler error: Unhandled 'non-uniform' modifier.");
if (vsir_src->modifiers)
vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
"Internal compiler error: Unhandled source modifier(s) %#x.", vsir_src->modifiers);
@@ -138,10 +138,10 @@ static uint32_t glsl_dst_init(struct glsl_dst *glsl_dst, struct vkd3d_glsl_gener
if (ins->flags & VKD3DSI_PRECISE_XYZW)
vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
- "Internal compiler error: Unhandled 'precise' modifer.");
+ "Internal compiler error: Unhandled 'precise' modifier.");
if (vsir_dst->reg.non_uniform)
vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
- "Internal compiler error: Unhandled 'non-uniform' modifer.");
+ "Internal compiler error: Unhandled 'non-uniform' modifier.");
glsl_dst->vsir = vsir_dst;
glsl_dst->register_name = vkd3d_string_buffer_get(&gen->string_buffers);
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c
index 7f85195382d..bd5baacd83d 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c
@@ -167,7 +167,14 @@ void hlsl_free_var(struct hlsl_ir_var *decl)
for (k = 0; k <= HLSL_REGSET_LAST_OBJECT; ++k)
vkd3d_free((void *)decl->objects_usage[k]);
- vkd3d_free(decl->default_values);
+ if (decl->default_values)
+ {
+ unsigned int component_count = hlsl_type_component_count(decl->data_type);
+
+ for (k = 0; k < component_count; ++k)
+ vkd3d_free((void *)decl->default_values[k].string);
+ vkd3d_free(decl->default_values);
+ }
for (i = 0; i < decl->state_block_count; ++i)
hlsl_free_state_block(decl->state_blocks[i]);
@@ -385,6 +392,8 @@ static void hlsl_type_calculate_reg_size(struct hlsl_ctx *ctx, struct hlsl_type
case HLSL_CLASS_DOMAIN_SHADER:
case HLSL_CLASS_HULL_SHADER:
case HLSL_CLASS_GEOMETRY_SHADER:
+ case HLSL_CLASS_BLEND_STATE:
+ case HLSL_CLASS_NULL:
break;
}
}
@@ -459,6 +468,8 @@ static bool type_is_single_component(const struct hlsl_type *type)
case HLSL_CLASS_DOMAIN_SHADER:
case HLSL_CLASS_HULL_SHADER:
case HLSL_CLASS_GEOMETRY_SHADER:
+ case HLSL_CLASS_BLEND_STATE:
+ case HLSL_CLASS_NULL:
return true;
case HLSL_CLASS_VECTOR:
@@ -615,6 +626,7 @@ unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_ty
case HLSL_CLASS_DOMAIN_SHADER:
case HLSL_CLASS_HULL_SHADER:
case HLSL_CLASS_GEOMETRY_SHADER:
+ case HLSL_CLASS_BLEND_STATE:
VKD3D_ASSERT(idx == 0);
break;
@@ -624,6 +636,7 @@ unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_ty
case HLSL_CLASS_VOID:
case HLSL_CLASS_SCALAR:
case HLSL_CLASS_CONSTANT_BUFFER:
+ case HLSL_CLASS_NULL:
vkd3d_unreachable();
}
type = next_type;
@@ -922,6 +935,7 @@ static const char * get_case_insensitive_typename(const char *name)
"texture",
"vector",
"vertexshader",
+ "string",
};
unsigned int i;
@@ -1019,6 +1033,8 @@ unsigned int hlsl_type_component_count(const struct hlsl_type *type)
case HLSL_CLASS_DOMAIN_SHADER:
case HLSL_CLASS_HULL_SHADER:
case HLSL_CLASS_GEOMETRY_SHADER:
+ case HLSL_CLASS_BLEND_STATE:
+ case HLSL_CLASS_NULL:
return 1;
case HLSL_CLASS_EFFECT_GROUP:
@@ -1110,6 +1126,8 @@ bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2
case HLSL_CLASS_DOMAIN_SHADER:
case HLSL_CLASS_HULL_SHADER:
case HLSL_CLASS_GEOMETRY_SHADER:
+ case HLSL_CLASS_BLEND_STATE:
+ case HLSL_CLASS_NULL:
return true;
}
@@ -1459,7 +1477,7 @@ struct hlsl_ir_node *hlsl_new_constant(struct hlsl_ctx *ctx, struct hlsl_type *t
{
struct hlsl_ir_constant *c;
- VKD3D_ASSERT(type->class <= HLSL_CLASS_VECTOR);
+ VKD3D_ASSERT(type->class <= HLSL_CLASS_VECTOR || type->class == HLSL_CLASS_NULL);
if (!(c = hlsl_alloc(ctx, sizeof(*c))))
return NULL;
@@ -1522,6 +1540,12 @@ struct hlsl_ir_node *hlsl_new_string_constant(struct hlsl_ctx *ctx, const char *
return &s->node;
}
+struct hlsl_ir_node *hlsl_new_null_constant(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc)
+{
+ struct hlsl_constant_value value = { 0 };
+ return hlsl_new_constant(ctx, ctx->builtin_types.null, &value, loc);
+}
+
struct hlsl_ir_node *hlsl_new_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op,
struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS],
struct hlsl_type *data_type, const struct vkd3d_shader_location *loc)
@@ -2562,6 +2586,8 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru
case HLSL_CLASS_DOMAIN_SHADER:
case HLSL_CLASS_HULL_SHADER:
case HLSL_CLASS_GEOMETRY_SHADER:
+ case HLSL_CLASS_BLEND_STATE:
+ case HLSL_CLASS_NULL:
break;
}
@@ -3262,9 +3288,15 @@ void hlsl_dump_var_default_values(const struct hlsl_ir_var *var)
vkd3d_string_buffer_printf(&buffer, "var \"%s\" default values:", var->name);
for (k = 0; k < component_count; ++k)
{
- if (k % 4 == 0)
+ bool is_string = var->default_values[k].string;
+
+ if (k % 4 == 0 || is_string)
vkd3d_string_buffer_printf(&buffer, "\n ");
- vkd3d_string_buffer_printf(&buffer, " 0x%08x", var->default_values[k].value.u);
+
+ if (is_string)
+ vkd3d_string_buffer_printf(&buffer, " %s", debugstr_a(var->default_values[k].string));
+ else
+ vkd3d_string_buffer_printf(&buffer, " 0x%08x", var->default_values[k].number.u);
}
vkd3d_string_buffer_printf(&buffer, "\n");
@@ -3922,8 +3954,10 @@ static void declare_predefined_types(struct hlsl_ctx *ctx)
ctx->builtin_types.sampler[bt] = type;
}
- ctx->builtin_types.string = hlsl_new_simple_type(ctx, "STRING", HLSL_CLASS_STRING);
ctx->builtin_types.Void = hlsl_new_simple_type(ctx, "void", HLSL_CLASS_VOID);
+ ctx->builtin_types.null = hlsl_new_type(ctx, "NULL", HLSL_CLASS_NULL, HLSL_TYPE_UINT, 1, 1);
+ ctx->builtin_types.string = hlsl_new_simple_type(ctx, "string", HLSL_CLASS_STRING);
+ hlsl_scope_add_type(ctx->globals, ctx->builtin_types.string);
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));
@@ -3937,6 +3971,7 @@ static void declare_predefined_types(struct hlsl_ctx *ctx)
hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "DomainShader", HLSL_CLASS_DOMAIN_SHADER));
hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "HullShader", HLSL_CLASS_HULL_SHADER));
hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "GeometryShader", HLSL_CLASS_GEOMETRY_SHADER));
+ hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "BlendState", HLSL_CLASS_BLEND_STATE));
for (i = 0; i < ARRAY_SIZE(effect_types); ++i)
{
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
index 7e8cd774ae2..22e25b23988 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
@@ -96,7 +96,9 @@ enum hlsl_type_class
HLSL_CLASS_HULL_SHADER,
HLSL_CLASS_GEOMETRY_SHADER,
HLSL_CLASS_CONSTANT_BUFFER,
+ HLSL_CLASS_BLEND_STATE,
HLSL_CLASS_VOID,
+ HLSL_CLASS_NULL,
};
enum hlsl_base_type
@@ -408,7 +410,7 @@ struct hlsl_attribute
/* Reservation of a register and/or an offset for objects inside constant buffers, to be used as a
* starting point of their allocation. They are available through the register(·) and the
- * packoffset(·) syntaxes, respectivelly.
+ * packoffset(·) syntaxes, respectively.
* The constant buffer offset is measured register components. */
struct hlsl_reg_reservation
{
@@ -454,8 +456,10 @@ struct hlsl_ir_var
* This pointer is NULL for others. */
struct hlsl_default_value
{
+ /* Default value, in case the component is a string, otherwise it is NULL. */
+ const char *string;
/* Default value, in case the component is a numeric value. */
- union hlsl_constant_value_component value;
+ union hlsl_constant_value_component number;
} *default_values;
/* A dynamic array containing the state block on the variable's declaration, if any.
@@ -998,6 +1002,7 @@ struct hlsl_ctx
struct hlsl_type *sampler[HLSL_SAMPLER_DIM_LAST_SAMPLER + 1];
struct hlsl_type *string;
struct hlsl_type *Void;
+ struct hlsl_type *null;
} builtin_types;
/* List of the instruction nodes for initializing static variables. */
@@ -1450,6 +1455,7 @@ struct hlsl_type *hlsl_new_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim
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_null_constant(struct hlsl_ctx *ctx, 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,
const struct vkd3d_shader_location *loc);
struct hlsl_ir_var *hlsl_new_var(struct hlsl_ctx *ctx, const char *name, struct hlsl_type *type,
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.l b/libs/vkd3d/libs/vkd3d-shader/hlsl.l
index b4db142f6c2..0c02b27817e 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.l
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.l
@@ -107,6 +107,7 @@ matrix {return KW_MATRIX; }
namespace {return KW_NAMESPACE; }
nointerpolation {return KW_NOINTERPOLATION; }
noperspective {return KW_NOPERSPECTIVE; }
+NULL {return KW_NULL; }
out {return KW_OUT; }
packoffset {return KW_PACKOFFSET; }
pass {return KW_PASS; }
@@ -144,6 +145,7 @@ stateblock {return KW_STATEBLOCK; }
stateblock_state {return KW_STATEBLOCK_STATE; }
static {return KW_STATIC; }
string {return KW_STRING; }
+String {return KW_STRING; }
struct {return KW_STRUCT; }
switch {return KW_SWITCH; }
tbuffer {return KW_TBUFFER; }
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
index 30bd53d0c49..3f319dea0d8 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
@@ -304,6 +304,26 @@ static bool implicit_compatible_data_types(struct hlsl_ctx *ctx, struct hlsl_typ
}
}
+ if (src->class == HLSL_CLASS_NULL)
+ {
+ switch (dst->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_STRING:
+ case HLSL_CLASS_TEXTURE:
+ case HLSL_CLASS_UAV:
+ case HLSL_CLASS_VERTEX_SHADER:
+ return true;
+ default:
+ break;
+ }
+ }
+
return hlsl_types_are_componentwise_equal(ctx, src, dst);
}
@@ -331,6 +351,9 @@ static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct hlsl_block *bl
if (hlsl_types_are_equal(src_type, dst_type))
return node;
+ if (src_type->class == HLSL_CLASS_NULL)
+ return node;
+
if (src_type->class > HLSL_CLASS_VECTOR || dst_type->class > HLSL_CLASS_VECTOR)
{
unsigned int src_comp_count = hlsl_type_component_count(src_type);
@@ -575,11 +598,10 @@ static void check_loop_attributes(struct hlsl_ctx *ctx, const struct parse_attri
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Unroll attribute can't be used with 'fastopt' attribute.");
}
-static union hlsl_constant_value_component evaluate_static_expression(struct hlsl_ctx *ctx,
+static struct hlsl_default_value evaluate_static_expression(struct hlsl_ctx *ctx,
struct hlsl_block *block, struct hlsl_type *dst_type, const struct vkd3d_shader_location *loc)
{
- union hlsl_constant_value_component ret = {0};
- struct hlsl_ir_constant *constant;
+ struct hlsl_default_value ret = {0};
struct hlsl_ir_node *node;
struct hlsl_block expr;
struct hlsl_src src;
@@ -631,8 +653,16 @@ static union hlsl_constant_value_component evaluate_static_expression(struct hls
if (node->type == HLSL_IR_CONSTANT)
{
- constant = hlsl_ir_constant(node);
- ret = constant->value.u[0];
+ struct hlsl_ir_constant *constant = hlsl_ir_constant(node);
+
+ ret.number = constant->value.u[0];
+ }
+ else if (node->type == HLSL_IR_STRING_CONSTANT)
+ {
+ struct hlsl_ir_string_constant *string = hlsl_ir_string_constant(node);
+
+ if (!(ret.string = vkd3d_strdup(string->string)))
+ return ret;
}
else if (node->type == HLSL_IR_STRING_CONSTANT)
{
@@ -652,10 +682,11 @@ static union hlsl_constant_value_component evaluate_static_expression(struct hls
static unsigned int evaluate_static_expression_as_uint(struct hlsl_ctx *ctx, struct hlsl_block *block,
const struct vkd3d_shader_location *loc)
{
- union hlsl_constant_value_component res;
+ struct hlsl_default_value res;
res = evaluate_static_expression(ctx, block, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc);
- return res.u;
+ VKD3D_ASSERT(!res.string);
+ return res.number.u;
}
static struct hlsl_block *create_loop(struct hlsl_ctx *ctx, enum loop_type type,
@@ -1868,49 +1899,51 @@ static struct hlsl_ir_node *add_binary_dot_expr(struct hlsl_ctx *ctx, struct hls
return add_expr(ctx, instrs, op, args, ret_type, loc);
}
-static struct hlsl_block *add_binary_expr_merge(struct hlsl_ctx *ctx, struct hlsl_block *block1,
- struct hlsl_block *block2, enum hlsl_ir_expr_op op, const struct vkd3d_shader_location *loc)
+static struct hlsl_ir_node *add_binary_expr(struct hlsl_ctx *ctx, struct hlsl_block *block, enum hlsl_ir_expr_op op,
+ struct hlsl_ir_node *lhs, struct hlsl_ir_node *rhs, const struct vkd3d_shader_location *loc)
{
- struct hlsl_ir_node *arg1 = node_from_block(block1), *arg2 = node_from_block(block2);
-
- hlsl_block_add_block(block1, block2);
- destroy_block(block2);
-
switch (op)
{
case HLSL_OP2_ADD:
case HLSL_OP2_DIV:
case HLSL_OP2_MOD:
case HLSL_OP2_MUL:
- add_binary_arithmetic_expr(ctx, block1, op, arg1, arg2, loc);
- break;
+ return add_binary_arithmetic_expr(ctx, block, op, lhs, rhs, loc);
case HLSL_OP2_BIT_AND:
case HLSL_OP2_BIT_OR:
case HLSL_OP2_BIT_XOR:
- add_binary_bitwise_expr(ctx, block1, op, arg1, arg2, loc);
- break;
+ return add_binary_bitwise_expr(ctx, block, op, lhs, rhs, loc);
case HLSL_OP2_LESS:
case HLSL_OP2_GEQUAL:
case HLSL_OP2_EQUAL:
case HLSL_OP2_NEQUAL:
- add_binary_comparison_expr(ctx, block1, op, arg1, arg2, loc);
- break;
+ return add_binary_comparison_expr(ctx, block, op, lhs, rhs, loc);
case HLSL_OP2_LOGIC_AND:
case HLSL_OP2_LOGIC_OR:
- add_binary_logical_expr(ctx, block1, op, arg1, arg2, loc);
- break;
+ return add_binary_logical_expr(ctx, block, op, lhs, rhs, loc);
case HLSL_OP2_LSHIFT:
case HLSL_OP2_RSHIFT:
- add_binary_shift_expr(ctx, block1, op, arg1, arg2, loc);
- break;
+ return add_binary_shift_expr(ctx, block, op, lhs, rhs, loc);
default:
vkd3d_unreachable();
}
+}
+
+static struct hlsl_block *add_binary_expr_merge(struct hlsl_ctx *ctx, struct hlsl_block *block1,
+ struct hlsl_block *block2, enum hlsl_ir_expr_op op, const struct vkd3d_shader_location *loc)
+{
+ struct hlsl_ir_node *arg1 = node_from_block(block1), *arg2 = node_from_block(block2);
+
+ hlsl_block_add_block(block1, block2);
+ destroy_block(block2);
+
+ if (add_binary_expr(ctx, block1, op, arg1, arg2, loc) == NULL)
+ return NULL;
return block1;
}
@@ -2034,7 +2067,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct hlsl_blo
enum hlsl_ir_expr_op op = op_from_assignment(assign_op);
VKD3D_ASSERT(op);
- if (!(rhs = add_binary_arithmetic_expr(ctx, block, op, lhs, rhs, &rhs->loc)))
+ if (!(rhs = add_binary_expr(ctx, block, op, lhs, rhs, &rhs->loc)))
return NULL;
}
@@ -2350,7 +2383,7 @@ static void initialize_var_components(struct hlsl_ctx *ctx, struct hlsl_block *i
if (!hlsl_clone_block(ctx, &block, instrs))
return;
- default_value.value = evaluate_static_expression(ctx, &block, dst_comp_type, &src->loc);
+ default_value = evaluate_static_expression(ctx, &block, dst_comp_type, &src->loc);
if (dst->is_param)
dst_index = *store_index;
@@ -2908,14 +2941,17 @@ static bool add_user_call(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *fu
struct hlsl_ir_node *comp;
struct hlsl_block store_block;
- value.u[0] = param->default_values[j].value;
- if (!(comp = hlsl_new_constant(ctx, type, &value, loc)))
- return false;
- hlsl_block_add_instr(args->instrs, comp);
+ if (!param->default_values[j].string)
+ {
+ value.u[0] = param->default_values[j].number;
+ if (!(comp = hlsl_new_constant(ctx, type, &value, loc)))
+ return false;
+ hlsl_block_add_instr(args->instrs, comp);
- if (!hlsl_new_store_component(ctx, &store_block, &param_deref, j, comp))
- return false;
- hlsl_block_add_block(args->instrs, &store_block);
+ if (!hlsl_new_store_component(ctx, &store_block, &param_deref, j, comp))
+ return false;
+ hlsl_block_add_block(args->instrs, &store_block);
+ }
}
}
@@ -6050,6 +6086,7 @@ static bool state_block_add_entry(struct hlsl_state_block *state_block, struct h
%token KW_NAMESPACE
%token KW_NOINTERPOLATION
%token KW_NOPERSPECTIVE
+%token KW_NULL
%token KW_OUT
%token KW_PACKOFFSET
%token KW_PASS
@@ -7304,12 +7341,6 @@ type_no_void:
{
validate_texture_format_type(ctx, $3, &@3);
- if (hlsl_version_lt(ctx, 4, 1))
- {
- hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
- "Multisampled texture object declaration needs sample count for profile %s.", ctx->profile->name);
- }
-
$$ = hlsl_new_texture_type(ctx, $1, $3, 0);
}
| texture_ms_type '<' type ',' shift_expr '>'
@@ -7433,6 +7464,10 @@ type_no_void:
{
$$ = hlsl_get_type(ctx->cur_scope, "RasterizerState", true, true);
}
+ | KW_BLENDSTATE
+ {
+ $$ = hlsl_get_type(ctx->cur_scope, "BlendState", true, true);
+ }
type:
type_no_void
@@ -8323,6 +8358,18 @@ primary_expr:
YYABORT;
}
}
+ | KW_NULL
+ {
+ struct hlsl_ir_node *c;
+
+ if (!(c = hlsl_new_null_constant(ctx, &@1)))
+ YYABORT;
+ if (!($$ = make_block(ctx, c)))
+ {
+ hlsl_free_instr(c);
+ YYABORT;
+ }
+ }
| VAR_IDENTIFIER
{
struct hlsl_ir_load *load;
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
index 049461cdb7d..a695eefabf6 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
@@ -1648,6 +1648,8 @@ static bool copy_propagation_transform_load(struct hlsl_ctx *ctx,
case HLSL_CLASS_RENDER_TARGET_VIEW:
case HLSL_CLASS_DEPTH_STENCIL_VIEW:
case HLSL_CLASS_GEOMETRY_SHADER:
+ case HLSL_CLASS_BLEND_STATE:
+ case HLSL_CLASS_NULL:
break;
case HLSL_CLASS_MATRIX:
diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c
index c1b8582af6d..6dbe30b1553 100644
--- a/libs/vkd3d/libs/vkd3d-shader/ir.c
+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c
@@ -3831,11 +3831,16 @@ static void vsir_cfg_compute_dominators(struct vsir_cfg *cfg)
{
struct vsir_block *block2 = &cfg->blocks[j];
- if (block2->label == 0)
+ if (block2->label == 0 || !vsir_block_dominates(block, block2))
continue;
- if (vsir_block_dominates(block, block2))
- vkd3d_string_buffer_printf(&cfg->debug_buffer, " %u", block2->label);
+ if (cfg->debug_buffer.content_size > 512)
+ {
+ TRACE("%s...\n", cfg->debug_buffer.buffer);
+ vkd3d_string_buffer_clear(&cfg->debug_buffer);
+ vkd3d_string_buffer_printf(&cfg->debug_buffer, "Block %u dominates: ...", block->label);
+ }
+ vkd3d_string_buffer_printf(&cfg->debug_buffer, " %u", block2->label);
}
TRACE("%s\n", cfg->debug_buffer.buffer);
vkd3d_string_buffer_clear(&cfg->debug_buffer);
@@ -3927,7 +3932,16 @@ static enum vkd3d_result vsir_cfg_compute_loops(struct vsir_cfg *cfg)
vkd3d_string_buffer_printf(&cfg->debug_buffer, "Back edge %u -> %u with loop:", block->label, header->label);
for (k = 0; k < loop->count; ++k)
+ {
+ if (cfg->debug_buffer.content_size > 512)
+ {
+ TRACE("%s...\n", cfg->debug_buffer.buffer);
+ vkd3d_string_buffer_clear(&cfg->debug_buffer);
+ vkd3d_string_buffer_printf(&cfg->debug_buffer, "Back edge %u -> %u with loop: ...",
+ block->label, header->label);
+ }
vkd3d_string_buffer_printf(&cfg->debug_buffer, " %u", loop->blocks[k]->label);
+ }
TRACE("%s\n", cfg->debug_buffer.buffer);
vkd3d_string_buffer_clear(&cfg->debug_buffer);
@@ -4150,7 +4164,15 @@ static enum vkd3d_result vsir_cfg_sort_nodes(struct vsir_cfg *cfg)
vkd3d_string_buffer_printf(&cfg->debug_buffer, "Block order:");
for (i = 0; i < cfg->order.count; ++i)
+ {
+ if (cfg->debug_buffer.content_size > 512)
+ {
+ TRACE("%s...\n", cfg->debug_buffer.buffer);
+ vkd3d_string_buffer_clear(&cfg->debug_buffer);
+ vkd3d_string_buffer_printf(&cfg->debug_buffer, "Block order: ...");
+ }
vkd3d_string_buffer_printf(&cfg->debug_buffer, " %u", cfg->order.blocks[i]->label);
+ }
TRACE("%s\n", cfg->debug_buffer.buffer);
vkd3d_string_buffer_clear(&cfg->debug_buffer);
@@ -4204,7 +4226,7 @@ static enum vkd3d_result vsir_cfg_generate_synthetic_loop_intervals(struct vsir_
ACTION_EXTEND,
} action = ACTION_CREATE_NEW;
- /* We've already contructed loop intervals for the back
+ /* We've already constructed loop intervals for the back
* edges, there's nothing more to do. */
if (vsir_block_dominates(successor, block))
continue;
@@ -4462,7 +4484,7 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg)
VKD3D_ASSERT(inner_loop->type == STRUCTURE_TYPE_LOOP);
/* Otherwise, if one of the branches is
- * continueing the inner loop we're inside,
+ * continue-ing the inner loop we're inside,
* make sure it's the false branch (because it
* will be optimized out later). */
if (action_true.jump_type == JUMP_CONTINUE && action_true.target == inner_loop->u.loop.idx)
@@ -5104,14 +5126,14 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_jump(struct vsir_cfg *cfg,
struct vsir_cfg_emit_target *target = cfg->target;
const struct vkd3d_shader_location no_loc = {0};
/* Encode the jump target as the loop index plus a bit to remember whether
- * we're breaking or continueing. */
+ * we're breaking or continue-ing. */
unsigned int jump_target = jump->target << 1;
enum vkd3d_shader_opcode opcode;
switch (jump->type)
{
case JUMP_CONTINUE:
- /* If we're continueing the loop we're directly inside, then we can emit a
+ /* If we're continue-ing the loop we're directly inside, then we can emit a
* `continue'. Otherwise we first have to break all the loops between here
* and the loop to continue, recording our intention to continue
* in the lowest bit of jump_target. */
diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c
index d6d5bbc1c07..84f641cc316 100644
--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c
+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c
@@ -22,6 +22,7 @@
*/
#include "hlsl.h"
+#include "vkd3d_shader_private.h"
#define SM4_MAX_SRC_COUNT 6
#define SM4_MAX_DST_COUNT 2
@@ -3006,6 +3007,8 @@ static D3D_SHADER_VARIABLE_CLASS sm4_class(const struct hlsl_type *type)
case HLSL_CLASS_DOMAIN_SHADER:
case HLSL_CLASS_HULL_SHADER:
case HLSL_CLASS_GEOMETRY_SHADER:
+ case HLSL_CLASS_BLEND_STATE:
+ case HLSL_CLASS_NULL:
break;
}
vkd3d_unreachable();
@@ -3107,8 +3110,6 @@ static D3D_SHADER_INPUT_TYPE sm4_resource_type(const struct hlsl_type *type)
{
switch (type->class)
{
- case HLSL_CLASS_ARRAY:
- return sm4_resource_type(type->e.array.type);
case HLSL_CLASS_SAMPLER:
return D3D_SIT_SAMPLER;
case HLSL_CLASS_TEXTURE:
@@ -3124,9 +3125,6 @@ static D3D_SHADER_INPUT_TYPE sm4_resource_type(const struct hlsl_type *type)
static D3D_RESOURCE_RETURN_TYPE sm4_resource_format(const struct hlsl_type *type)
{
- if (type->class == HLSL_CLASS_ARRAY)
- return sm4_resource_format(type->e.array.type);
-
switch (type->e.resource.format->e.numeric.type)
{
case HLSL_TYPE_DOUBLE:
@@ -3151,9 +3149,6 @@ static D3D_RESOURCE_RETURN_TYPE sm4_resource_format(const struct hlsl_type *type
static D3D_SRV_DIMENSION sm4_rdef_resource_dimension(const struct hlsl_type *type)
{
- if (type->class == HLSL_CLASS_ARRAY)
- return sm4_rdef_resource_dimension(type->e.array.type);
-
switch (type->sampler_dim)
{
case HLSL_SAMPLER_DIM_1D:
@@ -3190,11 +3185,18 @@ struct extern_resource
const struct hlsl_buffer *buffer;
char *name;
- struct hlsl_type *data_type;
bool is_user_packed;
+ /* The data type of a single component of the resource.
+ * This might be different from the data type of the resource itself in 4.0
+ * profiles, where an array (or multi-dimensional array) is handled as a
+ * single resource, unlike in 5.0. */
+ struct hlsl_type *component_type;
+
enum hlsl_regset regset;
unsigned int id, space, index, bind_count;
+
+ struct vkd3d_shader_location loc;
};
static int sm4_compare_extern_resources(const void *a, const void *b)
@@ -3289,14 +3291,16 @@ static struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, un
extern_resources[*count].buffer = NULL;
extern_resources[*count].name = name;
- extern_resources[*count].data_type = component_type;
extern_resources[*count].is_user_packed = !!var->reg_reservation.reg_type;
+ extern_resources[*count].component_type = component_type;
+
extern_resources[*count].regset = regset;
extern_resources[*count].id = var->regs[regset].id;
extern_resources[*count].space = var->regs[regset].space;
extern_resources[*count].index = var->regs[regset].index + regset_offset;
extern_resources[*count].bind_count = 1;
+ extern_resources[*count].loc = var->loc;
++*count;
}
@@ -3333,17 +3337,19 @@ static struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, un
extern_resources[*count].buffer = NULL;
extern_resources[*count].name = name;
- extern_resources[*count].data_type = var->data_type;
/* For some reason 5.1 resources aren't marked as
* user-packed, but cbuffers still are. */
extern_resources[*count].is_user_packed = hlsl_version_lt(ctx, 5, 1)
&& !!var->reg_reservation.reg_type;
+ extern_resources[*count].component_type = hlsl_type_get_component_type(ctx, var->data_type, 0);
+
extern_resources[*count].regset = r;
extern_resources[*count].id = var->regs[r].id;
extern_resources[*count].space = var->regs[r].space;
extern_resources[*count].index = var->regs[r].index;
extern_resources[*count].bind_count = var->bind_count[r];
+ extern_resources[*count].loc = var->loc;
++*count;
}
@@ -3374,14 +3380,16 @@ static struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, un
extern_resources[*count].buffer = buffer;
extern_resources[*count].name = name;
- extern_resources[*count].data_type = NULL;
extern_resources[*count].is_user_packed = !!buffer->reservation.reg_type;
+ extern_resources[*count].component_type = NULL;
+
extern_resources[*count].regset = HLSL_REGSET_NUMERIC;
extern_resources[*count].id = buffer->reg.id;
extern_resources[*count].space = buffer->reg.space;
extern_resources[*count].index = buffer->reg.index;
extern_resources[*count].bind_count = 1;
+ extern_resources[*count].loc = buffer->loc;
++*count;
}
@@ -3458,13 +3466,13 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc)
if (resource->buffer)
put_u32(&buffer, resource->buffer->type == HLSL_BUFFER_CONSTANT ? D3D_SIT_CBUFFER : D3D_SIT_TBUFFER);
else
- put_u32(&buffer, sm4_resource_type(resource->data_type));
+ put_u32(&buffer, sm4_resource_type(resource->component_type));
if (resource->regset == HLSL_REGSET_TEXTURES || resource->regset == HLSL_REGSET_UAVS)
{
- unsigned int dimx = hlsl_type_get_component_type(ctx, resource->data_type, 0)->e.resource.format->dimx;
+ unsigned int dimx = resource->component_type->e.resource.format->dimx;
- put_u32(&buffer, sm4_resource_format(resource->data_type));
- put_u32(&buffer, sm4_rdef_resource_dimension(resource->data_type));
+ put_u32(&buffer, sm4_resource_format(resource->component_type));
+ put_u32(&buffer, sm4_rdef_resource_dimension(resource->component_type));
put_u32(&buffer, ~0u); /* FIXME: multisample count */
flags |= (dimx - 1) << VKD3D_SM4_SIF_TEXTURE_COMPONENTS_SHIFT;
}
@@ -3593,6 +3601,13 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc)
unsigned int comp_offset;
enum hlsl_regset regset;
+ if (comp_type->class == HLSL_CLASS_STRING)
+ {
+ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
+ "Cannot write string default value.");
+ continue;
+ }
+
comp_offset = hlsl_type_get_component_offset(ctx, var->data_type, k, &regset);
if (regset == HLSL_REGSET_NUMERIC)
{
@@ -3600,7 +3615,7 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc)
hlsl_fixme(ctx, &var->loc, "Write double default values.");
set_u32(&buffer, default_value_offset + comp_offset * sizeof(uint32_t),
- var->default_values[k].value.u);
+ var->default_values[k].number.u);
}
}
}
@@ -4269,7 +4284,6 @@ static void write_sm4_dcl_constant_buffer(const struct tpf_writer *tpf, const st
static void write_sm4_dcl_samplers(const struct tpf_writer *tpf, const struct extern_resource *resource)
{
- struct hlsl_type *component_type;
unsigned int i;
struct sm4_instruction instr =
{
@@ -4279,13 +4293,11 @@ static void write_sm4_dcl_samplers(const struct tpf_writer *tpf, const struct ex
.dst_count = 1,
};
- component_type = hlsl_type_get_component_type(tpf->ctx, resource->data_type, 0);
+ VKD3D_ASSERT(resource->regset == HLSL_REGSET_SAMPLERS);
- if (component_type->sampler_dim == HLSL_SAMPLER_DIM_COMPARISON)
+ if (resource->component_type->sampler_dim == HLSL_SAMPLER_DIM_COMPARISON)
instr.extra_bits |= VKD3D_SM4_SAMPLER_COMPARISON << VKD3D_SM4_SAMPLER_MODE_SHIFT;
- VKD3D_ASSERT(resource->regset == HLSL_REGSET_SAMPLERS);
-
for (i = 0; i < resource->bind_count; ++i)
{
if (resource->var && !resource->var->objects_usage[HLSL_REGSET_SAMPLERS][i].used)
@@ -4317,11 +4329,12 @@ static void write_sm4_dcl_textures(const struct tpf_writer *tpf, const struct ex
enum hlsl_regset regset = uav ? HLSL_REGSET_UAVS : HLSL_REGSET_TEXTURES;
struct hlsl_type *component_type;
struct sm4_instruction instr;
+ bool multisampled;
unsigned int i;
VKD3D_ASSERT(resource->regset == regset);
- component_type = hlsl_type_get_component_type(tpf->ctx, resource->data_type, 0);
+ component_type = resource->component_type;
for (i = 0; i < resource->bind_count; ++i)
{
@@ -4339,6 +4352,16 @@ static void write_sm4_dcl_textures(const struct tpf_writer *tpf, const struct ex
.idx_count = 1,
};
+ multisampled = component_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS
+ || component_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY;
+
+ if (hlsl_version_lt(tpf->ctx, 4, 1) && multisampled && !component_type->sample_count)
+ {
+ hlsl_error(tpf->ctx, &resource->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
+ "Multisampled texture object declaration needs sample count for profile %s.",
+ tpf->ctx->profile->name);
+ }
+
if (hlsl_version_ge(tpf->ctx, 5, 1))
{
VKD3D_ASSERT(!i);
@@ -4358,18 +4381,18 @@ static void write_sm4_dcl_textures(const struct tpf_writer *tpf, const struct ex
if (uav)
{
- switch (resource->data_type->sampler_dim)
+ switch (component_type->sampler_dim)
{
- case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER:
- instr.opcode = VKD3D_SM5_OP_DCL_UAV_STRUCTURED;
- instr.byte_stride = resource->data_type->e.resource.format->reg_size[HLSL_REGSET_NUMERIC] * 4;
- break;
- default:
- instr.opcode = VKD3D_SM5_OP_DCL_UAV_TYPED;
- break;
+ case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER:
+ instr.opcode = VKD3D_SM5_OP_DCL_UAV_STRUCTURED;
+ instr.byte_stride = component_type->e.resource.format->reg_size[HLSL_REGSET_NUMERIC] * 4;
+ break;
+ default:
+ instr.opcode = VKD3D_SM5_OP_DCL_UAV_TYPED;
+ break;
}
- if (resource->data_type->e.resource.rasteriser_ordered)
+ if (component_type->e.resource.rasteriser_ordered)
instr.opcode |= VKD3DSUF_RASTERISER_ORDERED_VIEW << VKD3D_SM5_UAV_FLAGS_SHIFT;
}
else
@@ -4378,11 +4401,8 @@ static void write_sm4_dcl_textures(const struct tpf_writer *tpf, const struct ex
}
instr.extra_bits |= (sm4_resource_dimension(component_type) << VKD3D_SM4_RESOURCE_TYPE_SHIFT);
- if (component_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS
- || component_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY)
- {
+ if (multisampled)
instr.extra_bits |= component_type->sample_count << VKD3D_SM4_RESOURCE_SAMPLE_COUNT_SHIFT;
- }
write_sm4_instruction(tpf, &instr);
}
@@ -6082,7 +6102,7 @@ static void write_sm4_sfi0(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc)
extern_resources = sm4_get_extern_resources(ctx, &extern_resources_count);
for (unsigned int i = 0; i < extern_resources_count; ++i)
{
- if (extern_resources[i].data_type && extern_resources[i].data_type->e.resource.rasteriser_ordered)
+ if (extern_resources[i].component_type && extern_resources[i].component_type->e.resource.rasteriser_ordered)
*flags |= VKD3D_SM4_REQUIRES_ROVS;
}
sm4_free_extern_resources(extern_resources, extern_resources_count);
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
index 13b4dab76d1..ef66a8ca07a 100644
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -51,7 +51,6 @@
#include "vkd3d_shader.h"
#include "wine/list.h"
-#include <assert.h>
#include <inttypes.h>
#include <limits.h>
#include <stdbool.h>
diff --git a/libs/vkd3d/libs/vkd3d/resource.c b/libs/vkd3d/libs/vkd3d/resource.c
index ac29088b9cb..6d6820d3752 100644
--- a/libs/vkd3d/libs/vkd3d/resource.c
+++ b/libs/vkd3d/libs/vkd3d/resource.c
@@ -2184,7 +2184,7 @@ static HRESULT vkd3d_bind_heap_memory(struct d3d12_device *device,
goto allocate_memory;
}
- /* Syncronisation is not required for binding, but vkMapMemory() may be called
+ /* Synchronisation is not required for binding, but vkMapMemory() may be called
* from another thread and it requires exclusive access. */
vkd3d_mutex_lock(&heap->mutex);
diff --git a/libs/vkd3d/libs/vkd3d/state.c b/libs/vkd3d/libs/vkd3d/state.c
index 0bdb7ea524d..519d1a2d85f 100644
--- a/libs/vkd3d/libs/vkd3d/state.c
+++ b/libs/vkd3d/libs/vkd3d/state.c
@@ -635,14 +635,18 @@ static HRESULT d3d12_root_signature_init_push_constants(struct d3d12_root_signat
for (i = 0; i < desc->NumParameters; ++i)
{
const D3D12_ROOT_PARAMETER *p = &desc->pParameters[i];
+ D3D12_SHADER_VISIBILITY visibility;
+
if (p->ParameterType != D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS)
continue;
- VKD3D_ASSERT(p->ShaderVisibility <= D3D12_SHADER_VISIBILITY_PIXEL);
- push_constants[p->ShaderVisibility].stageFlags = use_vk_heaps ? VK_SHADER_STAGE_ALL
- : stage_flags_from_visibility(p->ShaderVisibility);
- push_constants[p->ShaderVisibility].size += align(p->u.Constants.Num32BitValues, 4) * sizeof(uint32_t);
+ visibility = use_vk_heaps ? D3D12_SHADER_VISIBILITY_ALL : p->ShaderVisibility;
+ VKD3D_ASSERT(visibility <= D3D12_SHADER_VISIBILITY_PIXEL);
+
+ push_constants[visibility].stageFlags = stage_flags_from_visibility(visibility);
+ push_constants[visibility].size += align(p->u.Constants.Num32BitValues, 4) * sizeof(uint32_t);
}
+
if (push_constants[D3D12_SHADER_VISIBILITY_ALL].size)
{
/* When D3D12_SHADER_VISIBILITY_ALL is used we use a single push
diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/libs/vkd3d/vkd3d_private.h
index a4bd2202f39..ba4e2e8488d 100644
--- a/libs/vkd3d/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/libs/vkd3d/vkd3d_private.h
@@ -37,7 +37,6 @@
#include "vkd3d.h"
#include "vkd3d_shader.h"
-#include <assert.h>
#include <inttypes.h>
#include <limits.h>
#include <stdbool.h>
@@ -679,7 +678,7 @@ static inline void *d3d12_desc_get_object_ref(const volatile struct d3d12_desc *
void *view;
/* Some games, e.g. Shadow of the Tomb Raider, GRID 2019, and Horizon Zero Dawn, write descriptors
- * from multiple threads without syncronisation. This is apparently valid in Windows. */
+ * from multiple threads without synchronisation. This is apparently valid in Windows. */
for (;;)
{
do
--
2.43.0