GLSL: Support emitting push constant block as a plain UBO.
This commit is contained in:
parent
66f32eca72
commit
0474848d4a
@ -195,7 +195,7 @@ endif()
|
||||
|
||||
if (SPIRV_CROSS_SHARED)
|
||||
set(spirv-cross-abi-major 0)
|
||||
set(spirv-cross-abi-minor 2)
|
||||
set(spirv-cross-abi-minor 3)
|
||||
set(spirv-cross-abi-patch 0)
|
||||
set(SPIRV_CROSS_VERSION ${spirv-cross-abi-major}.${spirv-cross-abi-minor}.${spirv-cross-abi-patch})
|
||||
set(SPIRV_CROSS_INSTALL_LIB_DIR ${CMAKE_INSTALL_PREFIX}/lib)
|
||||
|
4
main.cpp
4
main.cpp
@ -496,6 +496,7 @@ struct CLIArguments
|
||||
bool msl_pad_fragment_output = false;
|
||||
bool msl_domain_lower_left = false;
|
||||
bool msl_argument_buffers = false;
|
||||
bool glsl_emit_push_constant_as_ubo = false;
|
||||
vector<uint32_t> msl_discrete_descriptor_sets;
|
||||
vector<PLSArg> pls_in;
|
||||
vector<PLSArg> pls_out;
|
||||
@ -547,6 +548,7 @@ static void print_help()
|
||||
"\t[--iterations iter]\n"
|
||||
"\t[--cpp]\n"
|
||||
"\t[--cpp-interface-name <name>]\n"
|
||||
"\t[--glsl-emit-push-constant-as-ubo]\n"
|
||||
"\t[--msl]\n"
|
||||
"\t[--msl-version <MMmmpp>]\n"
|
||||
"\t[--msl-capture-output]\n"
|
||||
@ -714,6 +716,7 @@ static int main_inner(int argc, char *argv[])
|
||||
cbs.add("--reflect", [&args](CLIParser &parser) { args.reflect = parser.next_value_string("json"); });
|
||||
cbs.add("--cpp-interface-name", [&args](CLIParser &parser) { args.cpp_interface_name = parser.next_string(); });
|
||||
cbs.add("--metal", [&args](CLIParser &) { args.msl = true; }); // Legacy compatibility
|
||||
cbs.add("--glsl-emit-push-constant-as-ubo", [&args](CLIParser &) { args.glsl_emit_push_constant_as_ubo = true; });
|
||||
cbs.add("--msl", [&args](CLIParser &) { args.msl = true; });
|
||||
cbs.add("--hlsl", [&args](CLIParser &) { args.hlsl = true; });
|
||||
cbs.add("--hlsl-enable-compat", [&args](CLIParser &) { args.hlsl_compat = true; });
|
||||
@ -986,6 +989,7 @@ static int main_inner(int argc, char *argv[])
|
||||
opts.vertex.fixup_clipspace = args.fixup;
|
||||
opts.vertex.flip_vert_y = args.yflip;
|
||||
opts.vertex.support_nonzero_base_instance = args.support_nonzero_baseinstance;
|
||||
opts.emit_push_constant_as_uniform_buffer = args.glsl_emit_push_constant_as_ubo;
|
||||
compiler->set_common_options(opts);
|
||||
|
||||
// Set HLSL specific options.
|
||||
|
@ -0,0 +1,14 @@
|
||||
#version 450
|
||||
|
||||
layout(std140) uniform UBO
|
||||
{
|
||||
float ubo[4];
|
||||
} _14;
|
||||
|
||||
layout(location = 0) out float FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = _14.ubo[1];
|
||||
}
|
||||
|
@ -0,0 +1,14 @@
|
||||
#version 450
|
||||
|
||||
layout(push_constant, std140) uniform UBO
|
||||
{
|
||||
float ubo[4];
|
||||
} _14;
|
||||
|
||||
layout(location = 0) out float FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = _14.ubo[1];
|
||||
}
|
||||
|
@ -0,0 +1,14 @@
|
||||
#version 450
|
||||
|
||||
layout(std140) uniform UBO
|
||||
{
|
||||
float ubo[4];
|
||||
} _14;
|
||||
|
||||
layout(location = 0) out float FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = _14.ubo[1];
|
||||
}
|
||||
|
@ -0,0 +1,14 @@
|
||||
#version 450
|
||||
|
||||
layout(push_constant, std140) uniform UBO
|
||||
{
|
||||
float ubo[4];
|
||||
} _14;
|
||||
|
||||
layout(location = 0) out float FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = _14.ubo[1];
|
||||
}
|
||||
|
13
shaders/vulkan/frag/push-constant-as-ubo.push-ubo.vk.frag
Normal file
13
shaders/vulkan/frag/push-constant-as-ubo.push-ubo.vk.frag
Normal file
@ -0,0 +1,13 @@
|
||||
#version 450
|
||||
|
||||
layout(push_constant, std140) uniform UBO
|
||||
{
|
||||
float ubo[4];
|
||||
};
|
||||
|
||||
layout(location = 0) out float FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = ubo[1];
|
||||
}
|
@ -316,14 +316,19 @@ spvc_result spvc_compiler_create_compiler_options(spvc_compiler compiler, spvc_c
|
||||
{
|
||||
case SPVC_BACKEND_MSL:
|
||||
opt->backend_flags |= SPVC_COMPILER_OPTION_MSL_BIT | SPVC_COMPILER_OPTION_COMMON_BIT;
|
||||
opt->glsl = static_cast<CompilerMSL *>(compiler->compiler.get())->get_common_options();
|
||||
opt->msl = static_cast<CompilerMSL *>(compiler->compiler.get())->get_msl_options();
|
||||
break;
|
||||
|
||||
case SPVC_BACKEND_HLSL:
|
||||
opt->backend_flags |= SPVC_COMPILER_OPTION_HLSL_BIT | SPVC_COMPILER_OPTION_COMMON_BIT;
|
||||
opt->glsl = static_cast<CompilerHLSL *>(compiler->compiler.get())->get_common_options();
|
||||
opt->hlsl = static_cast<CompilerHLSL *>(compiler->compiler.get())->get_hlsl_options();
|
||||
break;
|
||||
|
||||
case SPVC_BACKEND_GLSL:
|
||||
opt->backend_flags |= SPVC_COMPILER_OPTION_GLSL_BIT | SPVC_COMPILER_OPTION_COMMON_BIT;
|
||||
opt->glsl = static_cast<CompilerGLSL *>(compiler->compiler.get())->get_common_options();
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -474,6 +479,10 @@ spvc_result spvc_compiler_options_set_uint(spvc_compiler_options options, spvc_c
|
||||
options->msl.argument_buffers = value != 0;
|
||||
break;
|
||||
|
||||
case SPVC_COMPILER_OPTION_GLSL_EMIT_PUSH_CONSTANT_AS_UNIFORM_BUFFER:
|
||||
options->glsl.emit_push_constant_as_uniform_buffer = value != 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
options->context->report_error("Unknown option.");
|
||||
return SPVC_ERROR_INVALID_ARGUMENT;
|
||||
|
@ -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 2
|
||||
#define SPVC_C_API_VERSION_MINOR 3
|
||||
/* Bumped if internal implementation details change. */
|
||||
#define SPVC_C_API_VERSION_PATCH 0
|
||||
|
||||
@ -420,6 +420,8 @@ typedef enum spvc_compiler_option
|
||||
SPVC_COMPILER_OPTION_MSL_PLATFORM = 31 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_ARGUMENT_BUFFERS = 32 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
|
||||
SPVC_COMPILER_OPTION_GLSL_EMIT_PUSH_CONSTANT_AS_UNIFORM_BUFFER = 33 | SPVC_COMPILER_OPTION_GLSL_BIT,
|
||||
|
||||
SPVC_COMPILER_OPTION_INT_MAX = 0x7fffffff
|
||||
} spvc_compiler_option;
|
||||
|
||||
|
@ -1365,10 +1365,12 @@ string CompilerGLSL::layout_for_variable(const SPIRVariable &var)
|
||||
bool push_constant_block = options.vulkan_semantics && var.storage == StorageClassPushConstant;
|
||||
bool ssbo_block = var.storage == StorageClassStorageBuffer ||
|
||||
(var.storage == StorageClassUniform && typeflags.get(DecorationBufferBlock));
|
||||
bool emulated_ubo = var.storage == StorageClassPushConstant && options.emit_push_constant_as_uniform_buffer;
|
||||
bool ubo_block = var.storage == StorageClassUniform && typeflags.get(DecorationBlock);
|
||||
|
||||
// Instead of adding explicit offsets for every element here, just assume we're using std140 or std430.
|
||||
// If SPIR-V does not comply with either layout, we cannot really work around it.
|
||||
if (can_use_buffer_blocks && var.storage == StorageClassUniform && typeflags.get(DecorationBlock))
|
||||
if (can_use_buffer_blocks && (ubo_block || emulated_ubo))
|
||||
{
|
||||
if (buffer_is_packing_standard(type, BufferPackingStd140))
|
||||
attr.push_back("std140");
|
||||
@ -1379,7 +1381,7 @@ string CompilerGLSL::layout_for_variable(const SPIRVariable &var)
|
||||
// however, we can only use layout(offset) on the block itself, not any substructs, so the substructs better be the appropriate layout.
|
||||
// Enhanced layouts seem to always work in Vulkan GLSL, so no need for extensions there.
|
||||
if (options.es && !options.vulkan_semantics)
|
||||
SPIRV_CROSS_THROW("Push constant block cannot be expressed as neither std430 nor std140. ES-targets do "
|
||||
SPIRV_CROSS_THROW("Uniform buffer block cannot be expressed as std140. ES-targets do "
|
||||
"not support GL_ARB_enhanced_layouts.");
|
||||
if (!options.es && !options.vulkan_semantics && options.version < 440)
|
||||
require_extension_internal("GL_ARB_enhanced_layouts");
|
||||
@ -1461,6 +1463,8 @@ void CompilerGLSL::emit_push_constant_block(const SPIRVariable &var)
|
||||
emit_buffer_block_flattened(var);
|
||||
else if (options.vulkan_semantics)
|
||||
emit_push_constant_block_vulkan(var);
|
||||
else if (options.emit_push_constant_as_uniform_buffer)
|
||||
emit_buffer_block_native(var);
|
||||
else
|
||||
emit_push_constant_block_glsl(var);
|
||||
}
|
||||
|
@ -96,6 +96,9 @@ public:
|
||||
// If disabled on older targets, binding decorations will be stripped.
|
||||
bool enable_420pack_extension = true;
|
||||
|
||||
// In non-Vulkan GLSL, emit push constant blocks as UBOs rather than plain uniforms.
|
||||
bool emit_push_constant_as_uniform_buffer = false;
|
||||
|
||||
enum Precision
|
||||
{
|
||||
DontCare,
|
||||
|
@ -302,7 +302,7 @@ def validate_shader(shader, vulkan, paths):
|
||||
else:
|
||||
subprocess.check_call([paths.glslang, shader])
|
||||
|
||||
def cross_compile(shader, vulkan, spirv, invalid_spirv, eliminate, is_legacy, flatten_ubo, sso, flatten_dim, opt, paths):
|
||||
def cross_compile(shader, vulkan, spirv, invalid_spirv, eliminate, is_legacy, flatten_ubo, sso, flatten_dim, opt, push_ubo, paths):
|
||||
spirv_path = create_temporary()
|
||||
glsl_path = create_temporary(os.path.basename(shader))
|
||||
|
||||
@ -335,6 +335,8 @@ def cross_compile(shader, vulkan, spirv, invalid_spirv, eliminate, is_legacy, fl
|
||||
extra_args += ['--separate-shader-objects']
|
||||
if flatten_dim:
|
||||
extra_args += ['--flatten-multidimensional-arrays']
|
||||
if push_ubo:
|
||||
extra_args += ['--glsl-emit-push-constant-as-ubo']
|
||||
|
||||
spirv_cross_path = './spirv-cross'
|
||||
|
||||
@ -496,6 +498,9 @@ def shader_is_flatten_dimensions(shader):
|
||||
def shader_is_noopt(shader):
|
||||
return '.noopt.' in shader
|
||||
|
||||
def shader_is_push_ubo(shader):
|
||||
return '.push-ubo.' in shader
|
||||
|
||||
def test_shader(stats, shader, update, keep, opt, paths):
|
||||
joined_path = os.path.join(shader[0], shader[1])
|
||||
vulkan = shader_is_vulkan(shader[1])
|
||||
@ -508,9 +513,10 @@ def test_shader(stats, shader, update, keep, opt, paths):
|
||||
sso = shader_is_sso(shader[1])
|
||||
flatten_dim = shader_is_flatten_dimensions(shader[1])
|
||||
noopt = shader_is_noopt(shader[1])
|
||||
push_ubo = shader_is_push_ubo(shader[1])
|
||||
|
||||
print('Testing shader:', joined_path)
|
||||
spirv, glsl, vulkan_glsl = cross_compile(joined_path, vulkan, is_spirv, invalid_spirv, eliminate, is_legacy, flatten_ubo, sso, flatten_dim, opt and (not noopt), paths)
|
||||
spirv, glsl, vulkan_glsl = cross_compile(joined_path, vulkan, is_spirv, invalid_spirv, eliminate, is_legacy, flatten_ubo, sso, flatten_dim, opt and (not noopt), push_ubo, paths)
|
||||
|
||||
# Only test GLSL stats if we have a shader following GL semantics.
|
||||
if stats and (not vulkan) and (not is_spirv) and (not desktop):
|
||||
|
Loading…
Reference in New Issue
Block a user