Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/KhronosGroup/SPIRV-Cross.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans-Kristian Arntzen <post@arntzen-software.no>2021-04-22 14:54:43 +0300
committerHans-Kristian Arntzen <post@arntzen-software.no>2021-04-22 17:03:08 +0300
commit532f65583e7a1703458d0c2e162a1f93b91abf16 (patch)
tree5423ee69083ae9ed9e52c27068e33e0d18480e12 /spirv_hlsl.cpp
parentd137abeef57b2f3fdbdab0ad5590fe99a44ba546 (diff)
Rewrite how non-uniform qualifiers are handled.
Remove all shenanigans with propagation, and only consume nonuniform qualifiers exactly where needed (last minute).
Diffstat (limited to 'spirv_hlsl.cpp')
-rw-r--r--spirv_hlsl.cpp91
1 files changed, 48 insertions, 43 deletions
diff --git a/spirv_hlsl.cpp b/spirv_hlsl.cpp
index 52c0a167..1dfb96a2 100644
--- a/spirv_hlsl.cpp
+++ b/spirv_hlsl.cpp
@@ -2235,7 +2235,7 @@ void CompilerHLSL::emit_push_constant_block(const SPIRVariable &var)
string CompilerHLSL::to_sampler_expression(uint32_t id)
{
- auto expr = join("_", to_expression(id));
+ auto expr = join("_", to_non_uniform_aware_expression(id));
auto index = expr.find_first_of('[');
if (index == string::npos)
{
@@ -2740,13 +2740,16 @@ void CompilerHLSL::emit_texture_op(const Instruction &i, bool sparse)
bool proj = false;
const uint32_t *opt = nullptr;
auto *combined_image = maybe_get<SPIRCombinedImageSampler>(img);
- auto img_expr = to_expression(combined_image ? combined_image->image : img);
- inherited_expressions.push_back(coord);
+ if (combined_image && has_decoration(img, DecorationNonUniform))
+ {
+ set_decoration(combined_image->image, DecorationNonUniform);
+ set_decoration(combined_image->sampler, DecorationNonUniform);
+ }
- // Make sure non-uniform decoration is back-propagated to where it needs to be.
- if (has_decoration(img, DecorationNonUniformEXT))
- propagate_nonuniform_qualifier(img);
+ auto img_expr = to_non_uniform_aware_expression(combined_image ? combined_image->image : img);
+
+ inherited_expressions.push_back(coord);
switch (op)
{
@@ -3002,7 +3005,7 @@ void CompilerHLSL::emit_texture_op(const Instruction &i, bool sparse)
{
string sampler_expr;
if (combined_image)
- sampler_expr = to_expression(combined_image->sampler);
+ sampler_expr = to_non_uniform_aware_expression(combined_image->sampler);
else
sampler_expr = to_sampler_expression(img);
expr += sampler_expr;
@@ -3798,6 +3801,10 @@ void CompilerHLSL::read_access_chain(string *expr, const string &lhs, const SPIR
SPIRV_CROSS_THROW("Reading types other than 32-bit from ByteAddressBuffer not yet supported, unless SM 6.2 and "
"native 16-bit types are enabled.");
+ string base = chain.base;
+ if (has_decoration(chain.self, DecorationNonUniform))
+ convert_non_uniform_expression(base, chain.self);
+
bool templated_load = hlsl_options.shader_model >= 62;
string load_expr;
@@ -3830,7 +3837,7 @@ void CompilerHLSL::read_access_chain(string *expr, const string &lhs, const SPIR
if (templated_load)
load_op = "Load";
- load_expr = join(chain.base, ".", load_op, template_expr, "(", chain.dynamic_index, chain.static_index, ")");
+ load_expr = join(base, ".", load_op, template_expr, "(", chain.dynamic_index, chain.static_index, ")");
}
else if (type.columns == 1)
{
@@ -3852,7 +3859,7 @@ void CompilerHLSL::read_access_chain(string *expr, const string &lhs, const SPIR
for (uint32_t r = 0; r < type.vecsize; r++)
{
- load_expr += join(chain.base, ".Load", template_expr, "(", chain.dynamic_index,
+ load_expr += join(base, ".Load", template_expr, "(", chain.dynamic_index,
chain.static_index + r * chain.matrix_stride, ")");
if (r + 1 < type.vecsize)
load_expr += ", ";
@@ -3901,7 +3908,7 @@ void CompilerHLSL::read_access_chain(string *expr, const string &lhs, const SPIR
for (uint32_t c = 0; c < type.columns; c++)
{
- load_expr += join(chain.base, ".", load_op, template_expr, "(", chain.dynamic_index,
+ load_expr += join(base, ".", load_op, template_expr, "(", chain.dynamic_index,
chain.static_index + c * chain.matrix_stride, ")");
if (c + 1 < type.columns)
load_expr += ", ";
@@ -3930,7 +3937,7 @@ void CompilerHLSL::read_access_chain(string *expr, const string &lhs, const SPIR
{
for (uint32_t r = 0; r < type.vecsize; r++)
{
- load_expr += join(chain.base, ".Load", template_expr, "(", chain.dynamic_index,
+ load_expr += join(base, ".Load", template_expr, "(", chain.dynamic_index,
chain.static_index + c * (type.width / 8) + r * chain.matrix_stride, ")");
if ((r + 1 < type.vecsize) || (c + 1 < type.columns))
@@ -3967,9 +3974,6 @@ void CompilerHLSL::emit_load(const Instruction &instruction)
uint32_t id = ops[1];
uint32_t ptr = ops[2];
- if (has_decoration(ptr, DecorationNonUniformEXT))
- propagate_nonuniform_qualifier(ptr);
-
auto &type = get<SPIRType>(result_type);
bool composite_load = !type.array.empty() || type.basetype == SPIRType::Struct;
@@ -4108,9 +4112,6 @@ void CompilerHLSL::write_access_chain(const SPIRAccessChain &chain, uint32_t val
// Make sure we trigger a read of the constituents in the access chain.
track_expression_read(chain.self);
- if (has_decoration(chain.self, DecorationNonUniformEXT))
- propagate_nonuniform_qualifier(chain.self);
-
SPIRType target_type;
target_type.basetype = SPIRType::UInt;
target_type.vecsize = type.vecsize;
@@ -4134,6 +4135,10 @@ void CompilerHLSL::write_access_chain(const SPIRAccessChain &chain, uint32_t val
bool templated_store = hlsl_options.shader_model >= 62;
+ auto base = chain.base;
+ if (has_decoration(chain.self, DecorationNonUniform))
+ convert_non_uniform_expression(base, chain.self);
+
string template_expr;
if (templated_store)
template_expr = join("<", type_to_glsl(type), ">");
@@ -4169,7 +4174,7 @@ void CompilerHLSL::write_access_chain(const SPIRAccessChain &chain, uint32_t val
}
else
store_op = "Store";
- statement(chain.base, ".", store_op, template_expr, "(", chain.dynamic_index, chain.static_index, ", ",
+ statement(base, ".", store_op, template_expr, "(", chain.dynamic_index, chain.static_index, ", ",
store_expr, ");");
}
else if (type.columns == 1)
@@ -4200,7 +4205,7 @@ void CompilerHLSL::write_access_chain(const SPIRAccessChain &chain, uint32_t val
store_expr = join(bitcast_op, "(", store_expr, ")");
}
- statement(chain.base, ".Store", template_expr, "(", chain.dynamic_index,
+ statement(base, ".Store", template_expr, "(", chain.dynamic_index,
chain.static_index + chain.matrix_stride * r, ", ", store_expr, ");");
}
}
@@ -4244,7 +4249,7 @@ void CompilerHLSL::write_access_chain(const SPIRAccessChain &chain, uint32_t val
store_expr = join(bitcast_op, "(", store_expr, ")");
}
- statement(chain.base, ".", store_op, template_expr, "(", chain.dynamic_index,
+ statement(base, ".", store_op, template_expr, "(", chain.dynamic_index,
chain.static_index + c * chain.matrix_stride, ", ", store_expr, ");");
}
}
@@ -4268,7 +4273,7 @@ void CompilerHLSL::write_access_chain(const SPIRAccessChain &chain, uint32_t val
auto bitcast_op = bitcast_glsl_op(target_type, type);
if (!bitcast_op.empty())
store_expr = join(bitcast_op, "(", store_expr, ")");
- statement(chain.base, ".Store", template_expr, "(", chain.dynamic_index,
+ statement(base, ".Store", template_expr, "(", chain.dynamic_index,
chain.static_index + c * (type.width / 8) + r * chain.matrix_stride, ", ", store_expr, ");");
}
}
@@ -4370,9 +4375,6 @@ void CompilerHLSL::emit_access_chain(const Instruction &instruction)
inherit_expression_dependencies(ops[1], ops[i]);
add_implied_read_expression(e, ops[i]);
}
-
- if (has_decoration(ops[1], DecorationNonUniformEXT))
- propagate_nonuniform_qualifier(ops[1]);
}
else
{
@@ -4472,13 +4474,16 @@ void CompilerHLSL::emit_atomic(const uint32_t *ops, uint32_t length, spv::Op op)
if (data_type.storage == StorageClassImage || !chain)
{
- statement(atomic_op, "(", to_expression(ops[0]), ", ", to_expression(ops[3]), ", ", to_expression(tmp_id),
- ");");
+ statement(atomic_op, "(", to_non_uniform_aware_expression(ops[0]), ", ",
+ to_expression(ops[3]), ", ", to_expression(tmp_id), ");");
}
else
{
+ string base = chain->base;
+ if (has_decoration(chain->self, DecorationNonUniform))
+ convert_non_uniform_expression(base, chain->self);
// RWByteAddress buffer is always uint in its underlying type.
- statement(chain->base, ".", atomic_op, "(", chain->dynamic_index, chain->static_index, ", ",
+ statement(base, ".", atomic_op, "(", chain->dynamic_index, chain->static_index, ", ",
to_expression(ops[3]), ", ", to_expression(tmp_id), ");");
}
}
@@ -4496,14 +4501,17 @@ void CompilerHLSL::emit_atomic(const uint32_t *ops, uint32_t length, spv::Op op)
SPIRType::BaseType expr_type;
if (data_type.storage == StorageClassImage || !chain)
{
- statement(atomic_op, "(", to_expression(ops[2]), ", ", value_expr, ", ", to_name(id), ");");
+ statement(atomic_op, "(", to_non_uniform_aware_expression(ops[2]), ", ", value_expr, ", ", to_name(id), ");");
expr_type = data_type.basetype;
}
else
{
// RWByteAddress buffer is always uint in its underlying type.
+ string base = chain->base;
+ if (has_decoration(chain->self, DecorationNonUniform))
+ convert_non_uniform_expression(base, chain->self);
expr_type = SPIRType::UInt;
- statement(chain->base, ".", atomic_op, "(", chain->dynamic_index, chain->static_index, ", ", value_expr,
+ statement(base, ".", atomic_op, "(", chain->dynamic_index, chain->static_index, ", ", value_expr,
", ", to_name(id), ");");
}
@@ -5136,7 +5144,7 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
auto dummy_samples_levels = join(get_fallback_name(id), "_dummy_parameter");
statement("uint ", dummy_samples_levels, ";");
- auto expr = join("spvTextureSize(", to_expression(ops[2]), ", ",
+ auto expr = join("spvTextureSize(", to_non_uniform_aware_expression(ops[2]), ", ",
bitcast_expression(SPIRType::UInt, ops[3]), ", ", dummy_samples_levels, ")");
auto &restype = get<SPIRType>(ops[0]);
@@ -5162,9 +5170,9 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
string expr;
if (uav)
- expr = join("spvImageSize(", to_expression(ops[2]), ", ", dummy_samples_levels, ")");
+ expr = join("spvImageSize(", to_non_uniform_aware_expression(ops[2]), ", ", dummy_samples_levels, ")");
else
- expr = join("spvTextureSize(", to_expression(ops[2]), ", 0u, ", dummy_samples_levels, ")");
+ expr = join("spvTextureSize(", to_non_uniform_aware_expression(ops[2]), ", 0u, ", dummy_samples_levels, ")");
auto &restype = get<SPIRType>(ops[0]);
expr = bitcast_expression(restype, SPIRType::UInt, expr);
@@ -5194,9 +5202,9 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
statement(variable_decl(type, to_name(id)), ";");
if (uav)
- statement("spvImageSize(", to_expression(ops[2]), ", ", to_name(id), ");");
+ statement("spvImageSize(", to_non_uniform_aware_expression(ops[2]), ", ", to_name(id), ");");
else
- statement("spvTextureSize(", to_expression(ops[2]), ", 0u, ", to_name(id), ");");
+ statement("spvTextureSize(", to_non_uniform_aware_expression(ops[2]), ", 0u, ", to_name(id), ");");
auto &restype = get<SPIRType>(ops[0]);
auto expr = bitcast_expression(restype, SPIRType::UInt, to_name(id));
@@ -5227,16 +5235,16 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
if (operands != ImageOperandsSampleMask || instruction.length != 6)
SPIRV_CROSS_THROW("Multisampled image used in OpImageRead, but unexpected operand mask was used.");
uint32_t sample = ops[5];
- imgexpr = join(to_expression(ops[2]), ".Load(int2(gl_FragCoord.xy), ", to_expression(sample), ")");
+ imgexpr = join(to_non_uniform_aware_expression(ops[2]), ".Load(int2(gl_FragCoord.xy), ", to_expression(sample), ")");
}
else
- imgexpr = join(to_expression(ops[2]), ".Load(int3(int2(gl_FragCoord.xy), 0))");
+ imgexpr = join(to_non_uniform_aware_expression(ops[2]), ".Load(int3(int2(gl_FragCoord.xy), 0))");
pure = true;
}
else
{
- imgexpr = join(to_expression(ops[2]), "[", to_expression(ops[3]), "]");
+ imgexpr = join(to_non_uniform_aware_expression(ops[2]), "[", to_expression(ops[3]), "]");
// The underlying image type in HLSL depends on the image format, unlike GLSL, where all images are "vec4",
// except that the underlying type changes how the data is interpreted.
@@ -5285,7 +5293,7 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
value_expr = remap_swizzle(narrowed_type, expression_type(ops[2]).vecsize, value_expr);
}
- statement(to_expression(ops[0]), "[", to_expression(ops[1]), "] = ", value_expr, ";");
+ statement(to_non_uniform_aware_expression(ops[0]), "[", to_expression(ops[1]), "] = ", value_expr, ";");
if (var && variable_storage_is_aliased(*var))
flush_all_aliased_variables();
break;
@@ -5297,10 +5305,7 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
uint32_t id = ops[1];
auto expr = to_expression(ops[2]);
- if (has_decoration(id, DecorationNonUniformEXT) || has_decoration(ops[2], DecorationNonUniformEXT))
- convert_non_uniform_expression(expression_type(ops[2]), expr);
expr += join("[", to_expression(ops[3]), "]");
-
auto &e = set<SPIRExpression>(id, expr, result_type, true);
// When using the pointer, we need to know which variable it is actually loaded from.
@@ -5478,7 +5483,7 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
case OpArrayLength:
{
- auto *var = maybe_get<SPIRVariable>(ops[2]);
+ auto *var = maybe_get_backing_variable(ops[2]);
if (!var)
SPIRV_CROSS_THROW("Array length must point directly to an SSBO block.");
@@ -5488,7 +5493,7 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
// This must be 32-bit uint, so we're good to go.
emit_uninitialized_temporary_expression(ops[0], ops[1]);
- statement(to_expression(ops[2]), ".GetDimensions(", to_expression(ops[1]), ");");
+ statement(to_non_uniform_aware_expression(ops[2]), ".GetDimensions(", to_expression(ops[1]), ");");
uint32_t offset = type_struct_member_offset(type, ops[3]);
uint32_t stride = type_struct_member_array_stride(type, ops[3]);
statement(to_expression(ops[1]), " = (", to_expression(ops[1]), " - ", offset, ") / ", stride, ";");