mirror of https://github.com/bkaradzic/bgfx
Updated spirv-cross.
This commit is contained in:
parent
6a0b5b5b5c
commit
b249692519
|
@ -277,6 +277,8 @@ static void print_resources(const Compiler &compiler, const char *tag, const Sma
|
|||
fprintf(stderr, " (Set : %u)", compiler.get_decoration(res.id, DecorationDescriptorSet));
|
||||
if (mask.get(DecorationBinding))
|
||||
fprintf(stderr, " (Binding : %u)", compiler.get_decoration(res.id, DecorationBinding));
|
||||
if (static_cast<const CompilerGLSL &>(compiler).variable_is_depth_or_compare(res.id))
|
||||
fprintf(stderr, " (comparison)");
|
||||
if (mask.get(DecorationInputAttachmentIndex))
|
||||
fprintf(stderr, " (Attachment : %u)", compiler.get_decoration(res.id, DecorationInputAttachmentIndex));
|
||||
if (mask.get(DecorationNonReadable))
|
||||
|
@ -560,6 +562,7 @@ struct CLIArguments
|
|||
bool hlsl_compat = false;
|
||||
bool hlsl_support_nonzero_base = false;
|
||||
bool hlsl_force_storage_buffer_as_uav = false;
|
||||
bool hlsl_nonwritable_uav_texture_as_srv = false;
|
||||
HLSLBindingFlags hlsl_binding_flags = 0;
|
||||
bool vulkan_semantics = false;
|
||||
bool flatten_multidimensional_arrays = false;
|
||||
|
@ -632,6 +635,7 @@ static void print_help()
|
|||
"\t[--hlsl-support-nonzero-basevertex-baseinstance]\n"
|
||||
"\t[--hlsl-auto-binding (push, cbv, srv, uav, sampler, all)]\n"
|
||||
"\t[--hlsl-force-storage-buffer-as-uav]\n"
|
||||
"\t[--hlsl-nonwritable-uav-texture-as-srv]\n"
|
||||
"\t[--separate-shader-objects]\n"
|
||||
"\t[--pls-in format input-name]\n"
|
||||
"\t[--pls-out format output-name]\n"
|
||||
|
@ -988,6 +992,7 @@ static string compile_iteration(const CLIArguments &args, std::vector<uint32_t>
|
|||
|
||||
hlsl_opts.support_nonzero_base_vertex_base_instance = args.hlsl_support_nonzero_base;
|
||||
hlsl_opts.force_storage_buffer_as_uav = args.hlsl_force_storage_buffer_as_uav;
|
||||
hlsl_opts.nonwritable_uav_texture_as_srv = args.hlsl_nonwritable_uav_texture_as_srv;
|
||||
hlsl->set_hlsl_options(hlsl_opts);
|
||||
hlsl->set_resource_binding_flags(args.hlsl_binding_flags);
|
||||
}
|
||||
|
@ -1053,14 +1058,6 @@ static string compile_iteration(const CLIArguments &args, std::vector<uint32_t>
|
|||
}
|
||||
}
|
||||
|
||||
if (args.dump_resources)
|
||||
{
|
||||
print_resources(*compiler, res);
|
||||
print_push_constant_resources(*compiler, res.push_constant_buffers);
|
||||
print_spec_constants(*compiler);
|
||||
print_capabilities_and_extensions(*compiler);
|
||||
}
|
||||
|
||||
if (combined_image_samplers)
|
||||
{
|
||||
compiler->build_combined_image_samplers();
|
||||
|
@ -1092,7 +1089,17 @@ static string compile_iteration(const CLIArguments &args, std::vector<uint32_t>
|
|||
static_cast<CompilerHLSL *>(compiler.get())->add_vertex_attribute_remap(remap);
|
||||
}
|
||||
|
||||
return compiler->compile();
|
||||
auto ret = compiler->compile();
|
||||
|
||||
if (args.dump_resources)
|
||||
{
|
||||
print_resources(*compiler, res);
|
||||
print_push_constant_resources(*compiler, res.push_constant_buffers);
|
||||
print_spec_constants(*compiler);
|
||||
print_capabilities_and_extensions(*compiler);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int main_inner(int argc, char *argv[])
|
||||
|
@ -1154,6 +1161,8 @@ static int main_inner(int argc, char *argv[])
|
|||
});
|
||||
cbs.add("--hlsl-force-storage-buffer-as-uav",
|
||||
[&args](CLIParser &) { args.hlsl_force_storage_buffer_as_uav = true; });
|
||||
cbs.add("--hlsl-nonwritable-uav-texture-as-srv",
|
||||
[&args](CLIParser &) { args.hlsl_nonwritable_uav_texture_as_srv = true; });
|
||||
cbs.add("--vulkan-semantics", [&args](CLIParser &) { args.vulkan_semantics = true; });
|
||||
cbs.add("-V", [&args](CLIParser &) { args.vulkan_semantics = true; });
|
||||
cbs.add("--flatten-multidimensional-arrays", [&args](CLIParser &) { args.flatten_multidimensional_arrays = true; });
|
||||
|
|
|
@ -481,6 +481,10 @@ spvc_result spvc_compiler_options_set_uint(spvc_compiler_options options, spvc_c
|
|||
case SPVC_COMPILER_OPTION_HLSL_FORCE_STORAGE_BUFFER_AS_UAV:
|
||||
options->hlsl.force_storage_buffer_as_uav = value != 0;
|
||||
break;
|
||||
|
||||
case SPVC_COMPILER_OPTION_HLSL_NONWRITABLE_UAV_TEXTURE_AS_SRV:
|
||||
options->hlsl.nonwritable_uav_texture_as_srv = value != 0;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if SPIRV_CROSS_C_API_MSL
|
||||
|
@ -707,6 +711,23 @@ spvc_result spvc_compiler_flatten_buffer_block(spvc_compiler compiler, spvc_vari
|
|||
#endif
|
||||
}
|
||||
|
||||
spvc_bool spvc_compiler_variable_is_depth_or_compare(spvc_compiler compiler, spvc_variable_id id)
|
||||
{
|
||||
#if SPIRV_CROSS_C_API_GLSL
|
||||
if (compiler->backend == SPVC_BACKEND_NONE)
|
||||
{
|
||||
compiler->context->report_error("Cross-compilation related option used on NONE backend which only supports reflection.");
|
||||
return SPVC_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
return static_cast<CompilerGLSL *>(compiler->compiler.get())->variable_is_depth_or_compare(id) ? SPVC_TRUE : SPVC_FALSE;
|
||||
#else
|
||||
(void)id;
|
||||
compiler->context->report_error("Cross-compilation related option used on NONE backend which only supports reflection.");
|
||||
return SPVC_FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
spvc_result spvc_compiler_hlsl_set_root_constants_layout(spvc_compiler compiler,
|
||||
const spvc_hlsl_root_constants *constant_info,
|
||||
size_t count)
|
||||
|
|
|
@ -33,7 +33,7 @@ extern "C" {
|
|||
/* Bumped if ABI or API breaks backwards compatibility. */
|
||||
#define SPVC_C_API_VERSION_MAJOR 0
|
||||
/* Bumped if APIs or enumerations are added in a backwards compatible way. */
|
||||
#define SPVC_C_API_VERSION_MINOR 28
|
||||
#define SPVC_C_API_VERSION_MINOR 30
|
||||
/* Bumped if internal implementation details change. */
|
||||
#define SPVC_C_API_VERSION_PATCH 0
|
||||
|
||||
|
@ -580,6 +580,8 @@ typedef enum spvc_compiler_option
|
|||
|
||||
SPVC_COMPILER_OPTION_FORCE_ZERO_INITIALIZED_VARIABLES = 54 | SPVC_COMPILER_OPTION_COMMON_BIT,
|
||||
|
||||
SPVC_COMPILER_OPTION_HLSL_NONWRITABLE_UAV_TEXTURE_AS_SRV = 55 | SPVC_COMPILER_OPTION_HLSL_BIT,
|
||||
|
||||
SPVC_COMPILER_OPTION_INT_MAX = 0x7fffffff
|
||||
} spvc_compiler_option;
|
||||
|
||||
|
@ -640,6 +642,8 @@ SPVC_PUBLIC_API spvc_result spvc_compiler_add_header_line(spvc_compiler compiler
|
|||
SPVC_PUBLIC_API spvc_result spvc_compiler_require_extension(spvc_compiler compiler, const char *ext);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_flatten_buffer_block(spvc_compiler compiler, spvc_variable_id id);
|
||||
|
||||
SPVC_PUBLIC_API spvc_bool spvc_compiler_variable_is_depth_or_compare(spvc_compiler compiler, spvc_variable_id id);
|
||||
|
||||
/*
|
||||
* HLSL specifics.
|
||||
* Maps to C++ API.
|
||||
|
|
|
@ -2543,7 +2543,7 @@ void CompilerGLSL::fixup_image_load_store_access()
|
|||
|
||||
ir.for_each_typed_id<SPIRVariable>([&](uint32_t var, const SPIRVariable &) {
|
||||
auto &vartype = expression_type(var);
|
||||
if (vartype.basetype == SPIRType::Image)
|
||||
if (vartype.basetype == SPIRType::Image && vartype.image.sampled == 2)
|
||||
{
|
||||
// Very old glslangValidator and HLSL compilers do not emit required qualifiers here.
|
||||
// Solve this by making the image access as restricted as possible and loosen up if we need to.
|
||||
|
@ -13702,3 +13702,8 @@ void CompilerGLSL::emit_inout_fragment_outputs_copy_to_subpass_inputs()
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
bool CompilerGLSL::variable_is_depth_or_compare(VariableID id) const
|
||||
{
|
||||
return image_is_comparison(get<SPIRType>(get<SPIRVariable>(id).basetype), id);
|
||||
}
|
||||
|
|
|
@ -228,6 +228,14 @@ public:
|
|||
// The name of the uniform array will be the same as the interface block name.
|
||||
void flatten_buffer_block(VariableID id);
|
||||
|
||||
// After compilation, query if a variable ID was used as a depth resource.
|
||||
// This is meaningful for MSL since descriptor types depend on this knowledge.
|
||||
// Cases which return true:
|
||||
// - Images which are declared with depth = 1 image type.
|
||||
// - Samplers which are statically used at least once with Dref opcodes.
|
||||
// - Images which are statically used at least once with Dref opcodes.
|
||||
bool variable_is_depth_or_compare(VariableID id) const;
|
||||
|
||||
protected:
|
||||
void reset();
|
||||
void emit_function(SPIRFunction &func, const Bitset &return_flags);
|
||||
|
|
|
@ -210,6 +210,8 @@ string CompilerHLSL::image_type_hlsl_modern(const SPIRType &type, uint32_t id)
|
|||
bool typed_load = false;
|
||||
uint32_t components = 4;
|
||||
|
||||
bool force_image_srv = hlsl_options.nonwritable_uav_texture_as_srv && has_decoration(id, DecorationNonWritable);
|
||||
|
||||
switch (type.image.dim)
|
||||
{
|
||||
case Dim1D:
|
||||
|
@ -239,7 +241,14 @@ string CompilerHLSL::image_type_hlsl_modern(const SPIRType &type, uint32_t id)
|
|||
if (interlocked_resources.count(id))
|
||||
return join("RasterizerOrderedBuffer<", image_format_to_type(type.image.format, imagetype.basetype),
|
||||
">");
|
||||
return join("RWBuffer<", image_format_to_type(type.image.format, imagetype.basetype), ">");
|
||||
|
||||
typed_load = !force_image_srv && type.image.sampled == 2;
|
||||
|
||||
const char *rw = force_image_srv ? "" : "RW";
|
||||
return join(rw, "Buffer<",
|
||||
typed_load ? image_format_to_type(type.image.format, imagetype.basetype) :
|
||||
join(type_to_glsl(imagetype), components),
|
||||
">");
|
||||
}
|
||||
else
|
||||
SPIRV_CROSS_THROW("Sampler buffers must be either sampled or unsampled. Cannot deduce in runtime.");
|
||||
|
@ -252,9 +261,14 @@ string CompilerHLSL::image_type_hlsl_modern(const SPIRType &type, uint32_t id)
|
|||
}
|
||||
const char *arrayed = type.image.arrayed ? "Array" : "";
|
||||
const char *ms = type.image.ms ? "MS" : "";
|
||||
const char *rw = typed_load ? "RW" : "";
|
||||
const char *rw = typed_load && !force_image_srv ? "RW" : "";
|
||||
|
||||
if (force_image_srv)
|
||||
typed_load = false;
|
||||
|
||||
if (typed_load && interlocked_resources.count(id))
|
||||
rw = "RasterizerOrdered";
|
||||
|
||||
return join(rw, "Texture", dim, ms, arrayed, "<",
|
||||
typed_load ? image_format_to_type(type.image.format, imagetype.basetype) :
|
||||
join(type_to_glsl(imagetype), components),
|
||||
|
@ -2970,10 +2984,18 @@ string CompilerHLSL::to_resource_binding(const SPIRVariable &var)
|
|||
|
||||
case SPIRType::Image:
|
||||
if (type.image.sampled == 2 && type.image.dim != DimSubpassData)
|
||||
{
|
||||
if (has_decoration(var.self, DecorationNonWritable) && hlsl_options.nonwritable_uav_texture_as_srv)
|
||||
{
|
||||
space = 't'; // SRV
|
||||
resource_flags = HLSL_BINDING_AUTO_SRV_BIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
space = 'u'; // UAV
|
||||
resource_flags = HLSL_BINDING_AUTO_UAV_BIT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
space = 't'; // SRV
|
||||
|
@ -4813,7 +4835,12 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
|
|||
imgexpr = join(to_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.
|
||||
if (var && !subpass_data)
|
||||
|
||||
bool force_srv =
|
||||
hlsl_options.nonwritable_uav_texture_as_srv && var && has_decoration(var->self, DecorationNonWritable);
|
||||
pure = force_srv;
|
||||
|
||||
if (var && !subpass_data && !force_srv)
|
||||
imgexpr = remap_swizzle(get<SPIRType>(result_type),
|
||||
image_format_to_components(get<SPIRType>(var->basetype).image.format), imgexpr);
|
||||
}
|
||||
|
|
|
@ -113,6 +113,11 @@ public:
|
|||
// Forces a storage buffer to always be declared as UAV, even if the readonly decoration is used.
|
||||
// By default, a readonly storage buffer will be declared as ByteAddressBuffer (SRV) instead.
|
||||
bool force_storage_buffer_as_uav = false;
|
||||
|
||||
// Forces any storage image type marked as NonWritable to be considered an SRV instead.
|
||||
// For this to work with function call parameters, NonWritable must be considered to be part of the type system
|
||||
// so that NonWritable image arguments are also translated to Texture rather than RWTexture.
|
||||
bool nonwritable_uav_texture_as_srv = false;
|
||||
};
|
||||
|
||||
explicit CompilerHLSL(std::vector<uint32_t> spirv_)
|
||||
|
|
|
@ -174,6 +174,7 @@ void CompilerMSL::build_implicit_builtins()
|
|||
if (need_subpass_input && (!msl_options.is_ios() || !msl_options.ios_use_framebuffer_fetch_subpasses) &&
|
||||
builtin == BuiltInFragCoord)
|
||||
{
|
||||
mark_implicit_builtin(StorageClassInput, BuiltInFragCoord, var.self);
|
||||
builtin_frag_coord_id = var.self;
|
||||
has_frag_coord = true;
|
||||
}
|
||||
|
@ -181,6 +182,7 @@ void CompilerMSL::build_implicit_builtins()
|
|||
if (need_sample_pos && builtin == BuiltInSampleId)
|
||||
{
|
||||
builtin_sample_id_id = var.self;
|
||||
mark_implicit_builtin(StorageClassInput, BuiltInSampleId, var.self);
|
||||
has_sample_id = true;
|
||||
}
|
||||
|
||||
|
@ -190,18 +192,22 @@ void CompilerMSL::build_implicit_builtins()
|
|||
{
|
||||
case BuiltInVertexIndex:
|
||||
builtin_vertex_idx_id = var.self;
|
||||
mark_implicit_builtin(StorageClassInput, BuiltInVertexIndex, var.self);
|
||||
has_vertex_idx = true;
|
||||
break;
|
||||
case BuiltInBaseVertex:
|
||||
builtin_base_vertex_id = var.self;
|
||||
mark_implicit_builtin(StorageClassInput, BuiltInBaseVertex, var.self);
|
||||
has_base_vertex = true;
|
||||
break;
|
||||
case BuiltInInstanceIndex:
|
||||
builtin_instance_idx_id = var.self;
|
||||
mark_implicit_builtin(StorageClassInput, BuiltInInstanceIndex, var.self);
|
||||
has_instance_idx = true;
|
||||
break;
|
||||
case BuiltInBaseInstance:
|
||||
builtin_base_instance_id = var.self;
|
||||
mark_implicit_builtin(StorageClassInput, BuiltInBaseInstance, var.self);
|
||||
has_base_instance = true;
|
||||
break;
|
||||
default:
|
||||
|
@ -215,10 +221,12 @@ void CompilerMSL::build_implicit_builtins()
|
|||
{
|
||||
case BuiltInInvocationId:
|
||||
builtin_invocation_id_id = var.self;
|
||||
mark_implicit_builtin(StorageClassInput, BuiltInInvocationId, var.self);
|
||||
has_invocation_id = true;
|
||||
break;
|
||||
case BuiltInPrimitiveId:
|
||||
builtin_primitive_id_id = var.self;
|
||||
mark_implicit_builtin(StorageClassInput, BuiltInPrimitiveId, var.self);
|
||||
has_primitive_id = true;
|
||||
break;
|
||||
default:
|
||||
|
@ -229,12 +237,14 @@ void CompilerMSL::build_implicit_builtins()
|
|||
if ((need_subgroup_mask || needs_subgroup_invocation_id) && builtin == BuiltInSubgroupLocalInvocationId)
|
||||
{
|
||||
builtin_subgroup_invocation_id_id = var.self;
|
||||
mark_implicit_builtin(StorageClassInput, BuiltInSubgroupLocalInvocationId, var.self);
|
||||
has_subgroup_invocation_id = true;
|
||||
}
|
||||
|
||||
if (need_subgroup_ge_mask && builtin == BuiltInSubgroupSize)
|
||||
{
|
||||
builtin_subgroup_size_id = var.self;
|
||||
mark_implicit_builtin(StorageClassInput, BuiltInSubgroupSize, var.self);
|
||||
has_subgroup_size = true;
|
||||
}
|
||||
|
||||
|
@ -245,10 +255,12 @@ void CompilerMSL::build_implicit_builtins()
|
|||
case BuiltInInstanceIndex:
|
||||
// The view index here is derived from the instance index.
|
||||
builtin_instance_idx_id = var.self;
|
||||
mark_implicit_builtin(StorageClassInput, BuiltInInstanceIndex, var.self);
|
||||
has_instance_idx = true;
|
||||
break;
|
||||
case BuiltInViewIndex:
|
||||
builtin_view_idx_id = var.self;
|
||||
mark_implicit_builtin(StorageClassInput, BuiltInViewIndex, var.self);
|
||||
has_view_idx = true;
|
||||
break;
|
||||
default:
|
||||
|
@ -645,7 +657,10 @@ void CompilerMSL::mark_implicit_builtin(StorageClass storage, BuiltIn builtin, u
|
|||
|
||||
assert(active_builtins != nullptr);
|
||||
active_builtins->set(builtin);
|
||||
get_entry_point().interface_variables.push_back(id);
|
||||
|
||||
auto &var = get_entry_point().interface_variables;
|
||||
if (find(begin(var), end(var), VariableID(id)) == end(var))
|
||||
var.push_back(id);
|
||||
}
|
||||
|
||||
uint32_t CompilerMSL::build_constant_uint_array_pointer()
|
||||
|
@ -10505,7 +10520,12 @@ string CompilerMSL::to_member_reference(uint32_t base, const SPIRType &type, uin
|
|||
|
||||
if (var)
|
||||
{
|
||||
bool is_buffer_variable = var->storage == StorageClassUniform || var->storage == StorageClassStorageBuffer;
|
||||
// Only allow -> dereference for block types. This is so we get expressions like
|
||||
// buffer[i]->first_member.second_member, rather than buffer[i]->first->second.
|
||||
bool is_block = has_decoration(type.self, DecorationBlock) || has_decoration(type.self, DecorationBufferBlock);
|
||||
|
||||
bool is_buffer_variable =
|
||||
is_block && (var->storage == StorageClassUniform || var->storage == StorageClassStorageBuffer);
|
||||
declared_as_pointer = is_buffer_variable && is_array(get<SPIRType>(var->basetype));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue