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)
|
if (SPIRV_CROSS_SHARED)
|
||||||
set(spirv-cross-abi-major 0)
|
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-abi-patch 0)
|
||||||
set(SPIRV_CROSS_VERSION ${spirv-cross-abi-major}.${spirv-cross-abi-minor}.${spirv-cross-abi-patch})
|
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)
|
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_pad_fragment_output = false;
|
||||||
bool msl_domain_lower_left = false;
|
bool msl_domain_lower_left = false;
|
||||||
bool msl_argument_buffers = false;
|
bool msl_argument_buffers = false;
|
||||||
|
bool glsl_emit_push_constant_as_ubo = false;
|
||||||
vector<uint32_t> msl_discrete_descriptor_sets;
|
vector<uint32_t> msl_discrete_descriptor_sets;
|
||||||
vector<PLSArg> pls_in;
|
vector<PLSArg> pls_in;
|
||||||
vector<PLSArg> pls_out;
|
vector<PLSArg> pls_out;
|
||||||
@ -547,6 +548,7 @@ static void print_help()
|
|||||||
"\t[--iterations iter]\n"
|
"\t[--iterations iter]\n"
|
||||||
"\t[--cpp]\n"
|
"\t[--cpp]\n"
|
||||||
"\t[--cpp-interface-name <name>]\n"
|
"\t[--cpp-interface-name <name>]\n"
|
||||||
|
"\t[--glsl-emit-push-constant-as-ubo]\n"
|
||||||
"\t[--msl]\n"
|
"\t[--msl]\n"
|
||||||
"\t[--msl-version <MMmmpp>]\n"
|
"\t[--msl-version <MMmmpp>]\n"
|
||||||
"\t[--msl-capture-output]\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("--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("--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("--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("--msl", [&args](CLIParser &) { args.msl = true; });
|
||||||
cbs.add("--hlsl", [&args](CLIParser &) { args.hlsl = true; });
|
cbs.add("--hlsl", [&args](CLIParser &) { args.hlsl = true; });
|
||||||
cbs.add("--hlsl-enable-compat", [&args](CLIParser &) { args.hlsl_compat = 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.fixup_clipspace = args.fixup;
|
||||||
opts.vertex.flip_vert_y = args.yflip;
|
opts.vertex.flip_vert_y = args.yflip;
|
||||||
opts.vertex.support_nonzero_base_instance = args.support_nonzero_baseinstance;
|
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);
|
compiler->set_common_options(opts);
|
||||||
|
|
||||||
// Set HLSL specific options.
|
// 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:
|
case SPVC_BACKEND_MSL:
|
||||||
opt->backend_flags |= SPVC_COMPILER_OPTION_MSL_BIT | SPVC_COMPILER_OPTION_COMMON_BIT;
|
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;
|
break;
|
||||||
|
|
||||||
case SPVC_BACKEND_HLSL:
|
case SPVC_BACKEND_HLSL:
|
||||||
opt->backend_flags |= SPVC_COMPILER_OPTION_HLSL_BIT | SPVC_COMPILER_OPTION_COMMON_BIT;
|
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;
|
break;
|
||||||
|
|
||||||
case SPVC_BACKEND_GLSL:
|
case SPVC_BACKEND_GLSL:
|
||||||
opt->backend_flags |= SPVC_COMPILER_OPTION_GLSL_BIT | SPVC_COMPILER_OPTION_COMMON_BIT;
|
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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -474,6 +479,10 @@ spvc_result spvc_compiler_options_set_uint(spvc_compiler_options options, spvc_c
|
|||||||
options->msl.argument_buffers = value != 0;
|
options->msl.argument_buffers = value != 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SPVC_COMPILER_OPTION_GLSL_EMIT_PUSH_CONSTANT_AS_UNIFORM_BUFFER:
|
||||||
|
options->glsl.emit_push_constant_as_uniform_buffer = value != 0;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
options->context->report_error("Unknown option.");
|
options->context->report_error("Unknown option.");
|
||||||
return SPVC_ERROR_INVALID_ARGUMENT;
|
return SPVC_ERROR_INVALID_ARGUMENT;
|
||||||
|
@ -33,7 +33,7 @@ extern "C" {
|
|||||||
/* Bumped if ABI or API breaks backwards compatibility. */
|
/* Bumped if ABI or API breaks backwards compatibility. */
|
||||||
#define SPVC_C_API_VERSION_MAJOR 0
|
#define SPVC_C_API_VERSION_MAJOR 0
|
||||||
/* Bumped if APIs or enumerations are added in a backwards compatible way. */
|
/* 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. */
|
/* Bumped if internal implementation details change. */
|
||||||
#define SPVC_C_API_VERSION_PATCH 0
|
#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_PLATFORM = 31 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||||
SPVC_COMPILER_OPTION_MSL_ARGUMENT_BUFFERS = 32 | 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_INT_MAX = 0x7fffffff
|
||||||
} spvc_compiler_option;
|
} 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 push_constant_block = options.vulkan_semantics && var.storage == StorageClassPushConstant;
|
||||||
bool ssbo_block = var.storage == StorageClassStorageBuffer ||
|
bool ssbo_block = var.storage == StorageClassStorageBuffer ||
|
||||||
(var.storage == StorageClassUniform && typeflags.get(DecorationBufferBlock));
|
(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.
|
// 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 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))
|
if (buffer_is_packing_standard(type, BufferPackingStd140))
|
||||||
attr.push_back("std140");
|
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.
|
// 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.
|
// Enhanced layouts seem to always work in Vulkan GLSL, so no need for extensions there.
|
||||||
if (options.es && !options.vulkan_semantics)
|
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.");
|
"not support GL_ARB_enhanced_layouts.");
|
||||||
if (!options.es && !options.vulkan_semantics && options.version < 440)
|
if (!options.es && !options.vulkan_semantics && options.version < 440)
|
||||||
require_extension_internal("GL_ARB_enhanced_layouts");
|
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);
|
emit_buffer_block_flattened(var);
|
||||||
else if (options.vulkan_semantics)
|
else if (options.vulkan_semantics)
|
||||||
emit_push_constant_block_vulkan(var);
|
emit_push_constant_block_vulkan(var);
|
||||||
|
else if (options.emit_push_constant_as_uniform_buffer)
|
||||||
|
emit_buffer_block_native(var);
|
||||||
else
|
else
|
||||||
emit_push_constant_block_glsl(var);
|
emit_push_constant_block_glsl(var);
|
||||||
}
|
}
|
||||||
|
@ -96,6 +96,9 @@ public:
|
|||||||
// If disabled on older targets, binding decorations will be stripped.
|
// If disabled on older targets, binding decorations will be stripped.
|
||||||
bool enable_420pack_extension = true;
|
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
|
enum Precision
|
||||||
{
|
{
|
||||||
DontCare,
|
DontCare,
|
||||||
|
@ -302,7 +302,7 @@ def validate_shader(shader, vulkan, paths):
|
|||||||
else:
|
else:
|
||||||
subprocess.check_call([paths.glslang, shader])
|
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()
|
spirv_path = create_temporary()
|
||||||
glsl_path = create_temporary(os.path.basename(shader))
|
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']
|
extra_args += ['--separate-shader-objects']
|
||||||
if flatten_dim:
|
if flatten_dim:
|
||||||
extra_args += ['--flatten-multidimensional-arrays']
|
extra_args += ['--flatten-multidimensional-arrays']
|
||||||
|
if push_ubo:
|
||||||
|
extra_args += ['--glsl-emit-push-constant-as-ubo']
|
||||||
|
|
||||||
spirv_cross_path = './spirv-cross'
|
spirv_cross_path = './spirv-cross'
|
||||||
|
|
||||||
@ -496,6 +498,9 @@ def shader_is_flatten_dimensions(shader):
|
|||||||
def shader_is_noopt(shader):
|
def shader_is_noopt(shader):
|
||||||
return '.noopt.' in 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):
|
def test_shader(stats, shader, update, keep, opt, paths):
|
||||||
joined_path = os.path.join(shader[0], shader[1])
|
joined_path = os.path.join(shader[0], shader[1])
|
||||||
vulkan = shader_is_vulkan(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])
|
sso = shader_is_sso(shader[1])
|
||||||
flatten_dim = shader_is_flatten_dimensions(shader[1])
|
flatten_dim = shader_is_flatten_dimensions(shader[1])
|
||||||
noopt = shader_is_noopt(shader[1])
|
noopt = shader_is_noopt(shader[1])
|
||||||
|
push_ubo = shader_is_push_ubo(shader[1])
|
||||||
|
|
||||||
print('Testing shader:', joined_path)
|
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.
|
# Only test GLSL stats if we have a shader following GL semantics.
|
||||||
if stats and (not vulkan) and (not is_spirv) and (not desktop):
|
if stats and (not vulkan) and (not is_spirv) and (not desktop):
|
||||||
|
Loading…
Reference in New Issue
Block a user