Updated spirv-cross.

This commit is contained in:
Бранимир Караџић 2019-11-15 21:33:36 -08:00
parent e3ef70dd0f
commit f38bf2b3a2
6 changed files with 140 additions and 20 deletions

View File

@ -56,7 +56,7 @@ set(spirv-compiler-options "")
set(spirv-compiler-defines "")
set(spirv-cross-link-flags "")
message(STATUS "Finding Git version for SPIRV-Cross.")
message(STATUS "SPIRV-Cross: Finding Git version for SPIRV-Cross.")
set(spirv-cross-build-version "unknown")
find_package(Git)
if (GIT_FOUND)
@ -67,9 +67,9 @@ if (GIT_FOUND)
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
message(STATUS "Git hash: ${spirv-cross-build-version}")
message(STATUS "SPIRV-Cross: Git hash: ${spirv-cross-build-version}")
else()
message(STATUS "Git not found, using unknown build version.")
message(STATUS "SPIRV-Cross: Git not found, using unknown build version.")
endif()
string(TIMESTAMP spirv-cross-timestamp)
@ -308,7 +308,7 @@ if (SPIRV_CROSS_STATIC)
endif()
set(spirv-cross-abi-major 0)
set(spirv-cross-abi-minor 20)
set(spirv-cross-abi-minor 21)
set(spirv-cross-abi-patch 0)
if (SPIRV_CROSS_SHARED)
@ -453,14 +453,14 @@ if (SPIRV_CROSS_CLI)
if ((${spirv-cross-glslang} MATCHES "NOTFOUND") OR (${spirv-cross-spirv-as} MATCHES "NOTFOUND") OR (${spirv-cross-spirv-val} MATCHES "NOTFOUND") OR (${spirv-cross-spirv-opt} MATCHES "NOTFOUND"))
set(SPIRV_CROSS_ENABLE_TESTS OFF)
message("Could not find glslang or SPIRV-Tools build under external/. Run ./checkout_glslang_spirv_tools.sh and ./build_glslang_spirv_tools.sh. Testing will be disabled.")
message("SPIRV-Cross: Testing will be disabled for SPIRV-Cross. Could not find glslang or SPIRV-Tools build under external/. To enable testing, run ./checkout_glslang_spirv_tools.sh and ./build_glslang_spirv_tools.sh first.")
else()
set(SPIRV_CROSS_ENABLE_TESTS ON)
message("Found glslang and SPIRV-Tools. Enabling test suite.")
message("Found glslangValidator in: ${spirv-cross-glslang}.")
message("Found spirv-as in: ${spirv-cross-spirv-as}.")
message("Found spirv-val in: ${spirv-cross-spirv-val}.")
message("Found spirv-opt in: ${spirv-cross-spirv-opt}.")
message("SPIRV-Cross: Found glslang and SPIRV-Tools. Enabling test suite.")
message("SPIRV-Cross: Found glslangValidator in: ${spirv-cross-glslang}.")
message("SPIRV-Cross: Found spirv-as in: ${spirv-cross-spirv-as}.")
message("SPIRV-Cross: Found spirv-val in: ${spirv-cross-spirv-val}.")
message("SPIRV-Cross: Found spirv-opt in: ${spirv-cross-spirv-opt}.")
endif()
set(spirv-cross-externals
@ -577,7 +577,7 @@ if (SPIRV_CROSS_CLI)
WORKING_DIRECTORY $<TARGET_FILE_DIR:spirv-cross>)
endif()
elseif(NOT ${PYTHONINTERP_FOUND})
message(WARNING "Testing disabled. Could not find python3. If you have python3 installed try running "
message(WARNING "SPIRV-Cross: Testing disabled. Could not find python3. If you have python3 installed try running "
"cmake with -DPYTHON_EXECUTABLE:FILEPATH=/path/to/python3 to help it find the executable")
endif()
endif()

View File

@ -552,6 +552,7 @@ struct CLIArguments
bool hlsl = false;
bool hlsl_compat = false;
bool hlsl_support_nonzero_base = false;
HLSLBindingFlags hlsl_binding_flags = 0;
bool vulkan_semantics = false;
bool flatten_multidimensional_arrays = false;
bool use_420pack_extension = true;
@ -614,6 +615,7 @@ static void print_help()
"\t[--shader-model]\n"
"\t[--hlsl-enable-compat]\n"
"\t[--hlsl-support-nonzero-basevertex-baseinstance]\n"
"\t[--hlsl-auto-binding (push, cbv, srv, uav, sampler, all)]\n"
"\t[--separate-shader-objects]\n"
"\t[--pls-in format input-name]\n"
"\t[--pls-out format output-name]\n"
@ -736,6 +738,27 @@ static ExecutionModel stage_to_execution_model(const std::string &stage)
SPIRV_CROSS_THROW("Invalid stage.");
}
static HLSLBindingFlags hlsl_resource_type_to_flag(const std::string &arg)
{
if (arg == "push")
return HLSL_BINDING_AUTO_PUSH_CONSTANT_BIT;
else if (arg == "cbv")
return HLSL_BINDING_AUTO_CBV_BIT;
else if (arg == "srv")
return HLSL_BINDING_AUTO_SRV_BIT;
else if (arg == "uav")
return HLSL_BINDING_AUTO_UAV_BIT;
else if (arg == "sampler")
return HLSL_BINDING_AUTO_SAMPLER_BIT;
else if (arg == "all")
return HLSL_BINDING_AUTO_ALL;
else
{
fprintf(stderr, "Invalid resource type for --hlsl-auto-binding: %s\n", arg.c_str());
return 0;
}
}
static string compile_iteration(const CLIArguments &args, std::vector<uint32_t> spirv_file)
{
Parser spirv_parser(move(spirv_file));
@ -939,6 +962,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->set_hlsl_options(hlsl_opts);
hlsl->set_resource_binding_flags(args.hlsl_binding_flags);
}
if (build_dummy_sampler)
@ -1089,6 +1113,9 @@ static int main_inner(int argc, char *argv[])
cbs.add("--hlsl-enable-compat", [&args](CLIParser &) { args.hlsl_compat = true; });
cbs.add("--hlsl-support-nonzero-basevertex-baseinstance",
[&args](CLIParser &) { args.hlsl_support_nonzero_base = true; });
cbs.add("--hlsl-auto-binding", [&args](CLIParser &parser) {
args.hlsl_binding_flags |= hlsl_resource_type_to_flag(parser.next_string());
});
cbs.add("--vulkan-semantics", [&args](CLIParser &) { args.vulkan_semantics = true; });
cbs.add("--flatten-multidimensional-arrays", [&args](CLIParser &) { args.flatten_multidimensional_arrays = true; });
cbs.add("--no-420pack-extension", [&args](CLIParser &) { args.use_420pack_extension = false; });

View File

@ -769,6 +769,26 @@ spvc_variable_id spvc_compiler_hlsl_remap_num_workgroups_builtin(spvc_compiler c
#endif
}
spvc_result spvc_compiler_hlsl_set_resource_binding_flags(spvc_compiler compiler,
spvc_hlsl_binding_flags flags)
{
#if SPIRV_CROSS_C_API_HLSL
if (compiler->backend != SPVC_BACKEND_HLSL)
{
compiler->context->report_error("HLSL function used on a non-HLSL backend.");
return SPVC_ERROR_INVALID_ARGUMENT;
}
auto &hlsl = *static_cast<CompilerHLSL *>(compiler->compiler.get());
hlsl.set_resource_binding_flags(flags);
return SPVC_SUCCESS;
#else
(void)flags;
compiler->context->report_error("HLSL function used on a non-HLSL backend.");
return SPVC_ERROR_INVALID_ARGUMENT;
#endif
}
spvc_bool spvc_compiler_msl_is_rasterization_disabled(spvc_compiler compiler)
{
#if SPIRV_CROSS_C_API_MSL

View File

@ -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 20
#define SPVC_C_API_VERSION_MINOR 21
/* Bumped if internal implementation details change. */
#define SPVC_C_API_VERSION_PATCH 0
@ -466,6 +466,18 @@ typedef struct spvc_msl_sampler_ycbcr_conversion
*/
SPVC_PUBLIC_API void spvc_msl_sampler_ycbcr_conversion_init(spvc_msl_sampler_ycbcr_conversion *conv);
/* Maps to C++ API. */
typedef enum spvc_hlsl_binding_flag_bits
{
SPVC_HLSL_BINDING_AUTO_PUSH_CONSTANT_BIT = 1 << 0,
SPVC_HLSL_BINDING_AUTO_CBV_BIT = 1 << 1,
SPVC_HLSL_BINDING_AUTO_SRV_BIT = 1 << 2,
SPVC_HLSL_BINDING_AUTO_UAV_BIT = 1 << 3,
SPVC_HLSL_BINDING_AUTO_SAMPLER_BIT = 1 << 4,
SPVC_HLSL_BINDING_AUTO_ALL = 0x7fffffff
} spvc_hlsl_binding_flag_bits;
typedef unsigned spvc_hlsl_binding_flags;
/* Maps to the various spirv_cross::Compiler*::Option structures. See C++ API for defaults and details. */
typedef enum spvc_compiler_option
{
@ -606,6 +618,9 @@ SPVC_PUBLIC_API spvc_result spvc_compiler_hlsl_add_vertex_attribute_remap(spvc_c
size_t remaps);
SPVC_PUBLIC_API spvc_variable_id spvc_compiler_hlsl_remap_num_workgroups_builtin(spvc_compiler compiler);
SPVC_PUBLIC_API spvc_result spvc_compiler_hlsl_set_resource_binding_flags(spvc_compiler compiler,
spvc_hlsl_binding_flags flags);
/*
* MSL specifics.
* Maps to C++ API.

View File

@ -1980,7 +1980,7 @@ void CompilerHLSL::emit_push_constant_block(const SPIRVariable &var)
auto &memb = ir.meta[type.self].members;
statement("cbuffer SPIRV_CROSS_RootConstant_", to_name(var.self),
to_resource_register('b', layout.binding, layout.space));
to_resource_register(HLSL_BINDING_AUTO_PUSH_CONSTANT_BIT, 'b', layout.binding, layout.space));
begin_scope();
// Index of the next field in the generated root constant constant buffer
@ -2943,21 +2943,31 @@ string CompilerHLSL::to_resource_binding(const SPIRVariable &var)
const auto &type = get<SPIRType>(var.basetype);
char space = '\0';
HLSLBindingFlags resource_flags = 0;
switch (type.basetype)
{
case SPIRType::SampledImage:
space = 't'; // SRV
resource_flags = HLSL_BINDING_AUTO_SRV_BIT;
break;
case SPIRType::Image:
if (type.image.sampled == 2 && type.image.dim != DimSubpassData)
{
space = 'u'; // UAV
resource_flags = HLSL_BINDING_AUTO_UAV_BIT;
}
else
{
space = 't'; // SRV
resource_flags = HLSL_BINDING_AUTO_SRV_BIT;
}
break;
case SPIRType::Sampler:
space = 's';
resource_flags = HLSL_BINDING_AUTO_SAMPLER_BIT;
break;
case SPIRType::Struct:
@ -2970,18 +2980,26 @@ string CompilerHLSL::to_resource_binding(const SPIRVariable &var)
Bitset flags = ir.get_buffer_block_flags(var);
bool is_readonly = flags.get(DecorationNonWritable);
space = is_readonly ? 't' : 'u'; // UAV
resource_flags = is_readonly ? HLSL_BINDING_AUTO_SRV_BIT : HLSL_BINDING_AUTO_UAV_BIT;
}
else if (has_decoration(type.self, DecorationBlock))
{
space = 'b'; // Constant buffers
resource_flags = HLSL_BINDING_AUTO_CBV_BIT;
}
}
else if (storage == StorageClassPushConstant)
{
space = 'b'; // Constant buffers
resource_flags = HLSL_BINDING_AUTO_PUSH_CONSTANT_BIT;
}
else if (storage == StorageClassStorageBuffer)
{
// UAV or SRV depending on readonly flag.
Bitset flags = ir.get_buffer_block_flags(var);
bool is_readonly = flags.get(DecorationNonWritable);
space = is_readonly ? 't' : 'u';
resource_flags = is_readonly ? HLSL_BINDING_AUTO_SRV_BIT : HLSL_BINDING_AUTO_UAV_BIT;
}
break;
@ -2993,7 +3011,7 @@ string CompilerHLSL::to_resource_binding(const SPIRVariable &var)
if (!space)
return "";
return to_resource_register(space, get_decoration(var.self, DecorationBinding),
return to_resource_register(resource_flags, space, get_decoration(var.self, DecorationBinding),
get_decoration(var.self, DecorationDescriptorSet));
}
@ -3003,16 +3021,21 @@ string CompilerHLSL::to_resource_binding_sampler(const SPIRVariable &var)
if (!has_decoration(var.self, DecorationBinding))
return "";
return to_resource_register('s', get_decoration(var.self, DecorationBinding),
return to_resource_register(HLSL_BINDING_AUTO_SAMPLER_BIT, 's', get_decoration(var.self, DecorationBinding),
get_decoration(var.self, DecorationDescriptorSet));
}
string CompilerHLSL::to_resource_register(char space, uint32_t binding, uint32_t space_set)
string CompilerHLSL::to_resource_register(uint32_t flags, char space, uint32_t binding, uint32_t space_set)
{
if (hlsl_options.shader_model >= 51)
return join(" : register(", space, binding, ", space", space_set, ")");
if ((flags & resource_binding_flags) == 0)
{
if (hlsl_options.shader_model >= 51)
return join(" : register(", space, binding, ", space", space_set, ")");
else
return join(" : register(", space, binding, ")");
}
else
return join(" : register(", space, binding, ")");
return "";
}
void CompilerHLSL::emit_modern_uniform(const SPIRVariable &var)
@ -4893,6 +4916,11 @@ VariableID CompilerHLSL::remap_num_workgroups_builtin()
return variable_id;
}
void CompilerHLSL::set_resource_binding_flags(HLSLBindingFlags flags)
{
resource_binding_flags = flags;
}
void CompilerHLSL::validate_shader_model()
{
// Check for nonuniform qualifier.

View File

@ -41,6 +41,32 @@ struct RootConstants
uint32_t space;
};
// For finer control, decorations may be removed from specific resources instead with unset_decoration().
enum HLSLBindingFlagBits
{
// Push constant (root constant) resources will be declared as CBVs (b-space) without a register() declaration.
// A register will be automatically assigned by the D3D compiler, but must therefore be reflected in D3D-land.
// Push constants do not normally have a DecorationBinding set, but if they do, this can be used to ignore it.
HLSL_BINDING_AUTO_PUSH_CONSTANT_BIT = 1 << 0,
// cbuffer resources will be declared as CBVs (b-space) without a register() declaration.
// A register will be automatically assigned, but must be reflected in D3D-land.
HLSL_BINDING_AUTO_CBV_BIT = 1 << 1,
// All SRVs (t-space) will be declared without a register() declaration.
HLSL_BINDING_AUTO_SRV_BIT = 1 << 2,
// All UAVs (u-space) will be declared without a register() declaration.
HLSL_BINDING_AUTO_UAV_BIT = 1 << 3,
// All samplers (s-space) will be declared without a register() declaration.
HLSL_BINDING_AUTO_SAMPLER_BIT = 1 << 4,
// No resources will be declared with register().
HLSL_BINDING_AUTO_ALL = 0x7fffffff
};
using HLSLBindingFlags = uint32_t;
class CompilerHLSL : public CompilerGLSL
{
public:
@ -116,6 +142,9 @@ public:
// so the calling application should declare explicit bindings on this ID before calling compile().
VariableID remap_num_workgroups_builtin();
// Controls how resource bindings are declared in the output HLSL.
void set_resource_binding_flags(HLSLBindingFlags flags);
private:
std::string type_to_glsl(const SPIRType &type, uint32_t id = 0) override;
std::string image_type_hlsl(const SPIRType &type, uint32_t id);
@ -149,7 +178,7 @@ private:
std::string to_sampler_expression(uint32_t id);
std::string to_resource_binding(const SPIRVariable &var);
std::string to_resource_binding_sampler(const SPIRVariable &var);
std::string to_resource_register(char space, uint32_t binding, uint32_t set);
std::string to_resource_register(HLSLBindingFlags flags, char space, uint32_t binding, uint32_t set);
void emit_sampled_image_op(uint32_t result_type, uint32_t result_id, uint32_t image_id, uint32_t samp_id) override;
void emit_access_chain(const Instruction &instruction);
void emit_load(const Instruction &instruction);
@ -221,6 +250,7 @@ private:
std::string to_semantic(uint32_t location, spv::ExecutionModel em, spv::StorageClass sc);
uint32_t num_workgroups_builtin = 0;
HLSLBindingFlags resource_binding_flags = 0;
// Custom root constant layout, which should be emitted
// when translating push constant ranges.