GLSL: Implement GL_EXT_shader_framebuffer_fetch.
This commit is contained in:
parent
c2655ab291
commit
04e877df12
10
main.cpp
10
main.cpp
@ -525,6 +525,7 @@ struct CLIArguments
|
|||||||
bool msl_force_native_arrays = false;
|
bool msl_force_native_arrays = false;
|
||||||
bool glsl_emit_push_constant_as_ubo = false;
|
bool glsl_emit_push_constant_as_ubo = false;
|
||||||
bool glsl_emit_ubo_as_plain_uniforms = false;
|
bool glsl_emit_ubo_as_plain_uniforms = false;
|
||||||
|
SmallVector<pair<uint32_t, uint32_t>> glsl_ext_framebuffer_fetch;
|
||||||
bool vulkan_glsl_disable_ext_samplerless_texture_functions = false;
|
bool vulkan_glsl_disable_ext_samplerless_texture_functions = false;
|
||||||
bool emit_line_directives = false;
|
bool emit_line_directives = false;
|
||||||
bool enable_storage_image_qualifier_deduction = true;
|
bool enable_storage_image_qualifier_deduction = true;
|
||||||
@ -599,6 +600,7 @@ static void print_help()
|
|||||||
"\t[--disable-storage-image-qualifier-deduction]\n"
|
"\t[--disable-storage-image-qualifier-deduction]\n"
|
||||||
"\t[--glsl-emit-push-constant-as-ubo]\n"
|
"\t[--glsl-emit-push-constant-as-ubo]\n"
|
||||||
"\t[--glsl-emit-ubo-as-plain-uniforms]\n"
|
"\t[--glsl-emit-ubo-as-plain-uniforms]\n"
|
||||||
|
"\t[--glsl-remap-ext-framebuffer-fetch input-attachment color-location]\n"
|
||||||
"\t[--vulkan-glsl-disable-ext-samplerless-texture-functions]\n"
|
"\t[--vulkan-glsl-disable-ext-samplerless-texture-functions]\n"
|
||||||
"\t[--msl]\n"
|
"\t[--msl]\n"
|
||||||
"\t[--msl-version <MMmmpp>]\n"
|
"\t[--msl-version <MMmmpp>]\n"
|
||||||
@ -949,6 +951,9 @@ static string compile_iteration(const CLIArguments &args, std::vector<uint32_t>
|
|||||||
opts.enable_storage_image_qualifier_deduction = args.enable_storage_image_qualifier_deduction;
|
opts.enable_storage_image_qualifier_deduction = args.enable_storage_image_qualifier_deduction;
|
||||||
compiler->set_common_options(opts);
|
compiler->set_common_options(opts);
|
||||||
|
|
||||||
|
for (auto &fetch : args.glsl_ext_framebuffer_fetch)
|
||||||
|
compiler->remap_ext_framebuffer_fetch(fetch.first, fetch.second);
|
||||||
|
|
||||||
// Set HLSL specific options.
|
// Set HLSL specific options.
|
||||||
if (args.hlsl)
|
if (args.hlsl)
|
||||||
{
|
{
|
||||||
@ -1125,6 +1130,11 @@ static int main_inner(int argc, char *argv[])
|
|||||||
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("--glsl-emit-push-constant-as-ubo", [&args](CLIParser &) { args.glsl_emit_push_constant_as_ubo = true; });
|
||||||
cbs.add("--glsl-emit-ubo-as-plain-uniforms", [&args](CLIParser &) { args.glsl_emit_ubo_as_plain_uniforms = true; });
|
cbs.add("--glsl-emit-ubo-as-plain-uniforms", [&args](CLIParser &) { args.glsl_emit_ubo_as_plain_uniforms = true; });
|
||||||
|
cbs.add("--glsl-remap-ext-framebuffer-fetch", [&args](CLIParser &parser) {
|
||||||
|
uint32_t input_index = parser.next_uint();
|
||||||
|
uint32_t color_attachment = parser.next_uint();
|
||||||
|
args.glsl_ext_framebuffer_fetch.push_back({ input_index, color_attachment });
|
||||||
|
});
|
||||||
cbs.add("--vulkan-glsl-disable-ext-samplerless-texture-functions",
|
cbs.add("--vulkan-glsl-disable-ext-samplerless-texture-functions",
|
||||||
[&args](CLIParser &) { args.vulkan_glsl_disable_ext_samplerless_texture_functions = true; });
|
[&args](CLIParser &) { args.vulkan_glsl_disable_ext_samplerless_texture_functions = true; });
|
||||||
cbs.add("--disable-storage-image-qualifier-deduction",
|
cbs.add("--disable-storage-image-qualifier-deduction",
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
#version 310 es
|
||||||
|
#extension GL_EXT_shader_framebuffer_fetch : require
|
||||||
|
precision mediump float;
|
||||||
|
precision highp int;
|
||||||
|
|
||||||
|
mediump vec4 uSubpass0;
|
||||||
|
mediump vec4 uSubpass1;
|
||||||
|
|
||||||
|
layout(location = 0) inout vec3 FragColor;
|
||||||
|
layout(location = 1) inout vec4 FragColor2;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
uSubpass0.xyz = FragColor;
|
||||||
|
uSubpass1 = FragColor2;
|
||||||
|
FragColor = uSubpass0.xyz + uSubpass1.xyz;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
|||||||
|
#version 100
|
||||||
|
#extension GL_EXT_shader_framebuffer_fetch : require
|
||||||
|
#extension GL_EXT_draw_buffers : require
|
||||||
|
precision mediump float;
|
||||||
|
precision highp int;
|
||||||
|
|
||||||
|
mediump vec4 uSubpass0;
|
||||||
|
mediump vec4 uSubpass1;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
uSubpass0 = gl_LastFragData[0];
|
||||||
|
uSubpass1 = gl_LastFragData[1];
|
||||||
|
gl_FragData[0] = uSubpass0.xyz + uSubpass1.xyz;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
|||||||
|
#version 310 es
|
||||||
|
precision mediump float;
|
||||||
|
|
||||||
|
layout(input_attachment_index = 0, set = 0, binding = 0) uniform mediump subpassInput uSubpass0;
|
||||||
|
layout(input_attachment_index = 1, set = 0, binding = 1) uniform mediump subpassInput uSubpass1;
|
||||||
|
layout(location = 0) out vec3 FragColor;
|
||||||
|
layout(location = 1) out vec4 FragColor2;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
FragColor.rgb = subpassLoad(uSubpass0).rgb + subpassLoad(uSubpass1).rgb;
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
#version 310 es
|
||||||
|
precision mediump float;
|
||||||
|
|
||||||
|
layout(input_attachment_index = 0, set = 0, binding = 0) uniform mediump subpassInput uSubpass0;
|
||||||
|
layout(input_attachment_index = 1, set = 0, binding = 1) uniform mediump subpassInput uSubpass1;
|
||||||
|
layout(location = 0) out vec3 FragColor;
|
||||||
|
layout(location = 1) out vec4 FragColor2;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
FragColor.rgb = subpassLoad(uSubpass0).rgb + subpassLoad(uSubpass1).rgb;
|
||||||
|
}
|
126
spirv_glsl.cpp
126
spirv_glsl.cpp
@ -370,6 +370,12 @@ void CompilerGLSL::remap_pls_variables()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CompilerGLSL::remap_ext_framebuffer_fetch(uint32_t input_attachment_index, uint32_t color_location)
|
||||||
|
{
|
||||||
|
subpass_to_framebuffer_fetch_attachment.push_back({ input_attachment_index, color_location });
|
||||||
|
inout_color_attachments.insert(color_location);
|
||||||
|
}
|
||||||
|
|
||||||
void CompilerGLSL::find_static_extensions()
|
void CompilerGLSL::find_static_extensions()
|
||||||
{
|
{
|
||||||
ir.for_each_typed_id<SPIRType>([&](uint32_t, const SPIRType &type) {
|
ir.for_each_typed_id<SPIRType>([&](uint32_t, const SPIRType &type) {
|
||||||
@ -455,7 +461,20 @@ void CompilerGLSL::find_static_extensions()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!pls_inputs.empty() || !pls_outputs.empty())
|
if (!pls_inputs.empty() || !pls_outputs.empty())
|
||||||
|
{
|
||||||
|
if (execution.model != ExecutionModelFragment)
|
||||||
|
SPIRV_CROSS_THROW("Can only use GL_EXT_shader_pixel_local_storage in fragment shaders.");
|
||||||
require_extension_internal("GL_EXT_shader_pixel_local_storage");
|
require_extension_internal("GL_EXT_shader_pixel_local_storage");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!inout_color_attachments.empty())
|
||||||
|
{
|
||||||
|
if (execution.model != ExecutionModelFragment)
|
||||||
|
SPIRV_CROSS_THROW("Can only use GL_EXT_shader_framebuffer_fetch in fragment shaders.");
|
||||||
|
if (options.vulkan_semantics)
|
||||||
|
SPIRV_CROSS_THROW("Cannot use EXT_shader_framebuffer_fetch in Vulkan GLSL.");
|
||||||
|
require_extension_internal("GL_EXT_shader_framebuffer_fetch");
|
||||||
|
}
|
||||||
|
|
||||||
if (options.separate_shader_objects && !options.es && options.version < 410)
|
if (options.separate_shader_objects && !options.es && options.version < 410)
|
||||||
require_extension_internal("GL_ARB_separate_shader_objects");
|
require_extension_internal("GL_ARB_separate_shader_objects");
|
||||||
@ -519,6 +538,8 @@ string CompilerGLSL::compile()
|
|||||||
update_active_builtins();
|
update_active_builtins();
|
||||||
analyze_image_and_sampler_usage();
|
analyze_image_and_sampler_usage();
|
||||||
analyze_interlocked_resource_usage();
|
analyze_interlocked_resource_usage();
|
||||||
|
if (!inout_color_attachments.empty())
|
||||||
|
emit_inout_fragment_outputs_copy_to_subpass_inputs();
|
||||||
|
|
||||||
// Shaders might cast unrelated data to pointers of non-block types.
|
// Shaders might cast unrelated data to pointers of non-block types.
|
||||||
// Find all such instances and make sure we can cast the pointers to a synthesized block type.
|
// Find all such instances and make sure we can cast the pointers to a synthesized block type.
|
||||||
@ -1519,6 +1540,9 @@ string CompilerGLSL::layout_for_variable(const SPIRVariable &var)
|
|||||||
if (is_legacy())
|
if (is_legacy())
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
|
if (subpass_input_is_framebuffer_fetch(var.self))
|
||||||
|
return "";
|
||||||
|
|
||||||
SmallVector<string> attr;
|
SmallVector<string> attr;
|
||||||
|
|
||||||
auto &type = get<SPIRType>(var.basetype);
|
auto &type = get<SPIRType>(var.basetype);
|
||||||
@ -2031,12 +2055,22 @@ const char *CompilerGLSL::to_storage_qualifiers_glsl(const SPIRVariable &var)
|
|||||||
{
|
{
|
||||||
auto &execution = get_entry_point();
|
auto &execution = get_entry_point();
|
||||||
|
|
||||||
|
if (subpass_input_is_framebuffer_fetch(var.self))
|
||||||
|
return "";
|
||||||
|
|
||||||
if (var.storage == StorageClassInput || var.storage == StorageClassOutput)
|
if (var.storage == StorageClassInput || var.storage == StorageClassOutput)
|
||||||
{
|
{
|
||||||
if (is_legacy() && execution.model == ExecutionModelVertex)
|
if (is_legacy() && execution.model == ExecutionModelVertex)
|
||||||
return var.storage == StorageClassInput ? "attribute " : "varying ";
|
return var.storage == StorageClassInput ? "attribute " : "varying ";
|
||||||
else if (is_legacy() && execution.model == ExecutionModelFragment)
|
else if (is_legacy() && execution.model == ExecutionModelFragment)
|
||||||
return "varying "; // Fragment outputs are renamed so they never hit this case.
|
return "varying "; // Fragment outputs are renamed so they never hit this case.
|
||||||
|
else if (execution.model == ExecutionModelFragment && var.storage == StorageClassOutput)
|
||||||
|
{
|
||||||
|
if (inout_color_attachments.count(get_decoration(var.self, DecorationLocation)) != 0)
|
||||||
|
return "inout ";
|
||||||
|
else
|
||||||
|
return "out ";
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return var.storage == StorageClassInput ? "in " : "out ";
|
return var.storage == StorageClassInput ? "in " : "out ";
|
||||||
}
|
}
|
||||||
@ -2229,7 +2263,7 @@ void CompilerGLSL::emit_interface_block(const SPIRVariable &var)
|
|||||||
void CompilerGLSL::emit_uniform(const SPIRVariable &var)
|
void CompilerGLSL::emit_uniform(const SPIRVariable &var)
|
||||||
{
|
{
|
||||||
auto &type = get<SPIRType>(var.basetype);
|
auto &type = get<SPIRType>(var.basetype);
|
||||||
if (type.basetype == SPIRType::Image && type.image.sampled == 2)
|
if (type.basetype == SPIRType::Image && type.image.sampled == 2 && type.image.dim != DimSubpassData)
|
||||||
{
|
{
|
||||||
if (!options.es && options.version < 420)
|
if (!options.es && options.version < 420)
|
||||||
require_extension_internal("GL_ARB_shader_image_load_store");
|
require_extension_internal("GL_ARB_shader_image_load_store");
|
||||||
@ -3025,9 +3059,18 @@ void CompilerGLSL::emit_resources()
|
|||||||
ir.for_each_typed_id<SPIRVariable>([&](uint32_t, SPIRVariable &var) {
|
ir.for_each_typed_id<SPIRVariable>([&](uint32_t, SPIRVariable &var) {
|
||||||
auto &type = this->get<SPIRType>(var.basetype);
|
auto &type = this->get<SPIRType>(var.basetype);
|
||||||
|
|
||||||
|
bool is_hidden = is_hidden_variable(var);
|
||||||
|
|
||||||
|
// Unused output I/O variables might still be required to implement framebuffer fetch.
|
||||||
|
if (var.storage == StorageClassOutput && !is_legacy() &&
|
||||||
|
inout_color_attachments.count(get_decoration(var.self, DecorationLocation)) != 0)
|
||||||
|
{
|
||||||
|
is_hidden = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (var.storage != StorageClassFunction && type.pointer &&
|
if (var.storage != StorageClassFunction && type.pointer &&
|
||||||
(var.storage == StorageClassInput || var.storage == StorageClassOutput) &&
|
(var.storage == StorageClassInput || var.storage == StorageClassOutput) &&
|
||||||
interface_variable_exists_in_entry_point(var.self) && !is_hidden_variable(var))
|
interface_variable_exists_in_entry_point(var.self) && !is_hidden)
|
||||||
{
|
{
|
||||||
emit_interface_block(var);
|
emit_interface_block(var);
|
||||||
emitted = true;
|
emitted = true;
|
||||||
@ -9993,7 +10036,11 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
|
|||||||
}
|
}
|
||||||
else if (type.image.dim == DimSubpassData)
|
else if (type.image.dim == DimSubpassData)
|
||||||
{
|
{
|
||||||
if (options.vulkan_semantics)
|
if (var && subpass_input_is_framebuffer_fetch(var->self))
|
||||||
|
{
|
||||||
|
imgexpr = to_expression(var->self);
|
||||||
|
}
|
||||||
|
else if (options.vulkan_semantics)
|
||||||
{
|
{
|
||||||
// With Vulkan semantics, use the proper Vulkan GLSL construct.
|
// With Vulkan semantics, use the proper Vulkan GLSL construct.
|
||||||
if (type.image.ms)
|
if (type.image.ms)
|
||||||
@ -11237,6 +11284,13 @@ string CompilerGLSL::image_type_glsl(const SPIRType &type, uint32_t id)
|
|||||||
|
|
||||||
if (type.basetype == SPIRType::Image && type.image.dim == DimSubpassData && options.vulkan_semantics)
|
if (type.basetype == SPIRType::Image && type.image.dim == DimSubpassData && options.vulkan_semantics)
|
||||||
return res + "subpassInput" + (type.image.ms ? "MS" : "");
|
return res + "subpassInput" + (type.image.ms ? "MS" : "");
|
||||||
|
else if (type.basetype == SPIRType::Image && type.image.dim == DimSubpassData &&
|
||||||
|
subpass_input_is_framebuffer_fetch(id))
|
||||||
|
{
|
||||||
|
SPIRType sampled_type = get<SPIRType>(type.image.type);
|
||||||
|
sampled_type.vecsize = 4;
|
||||||
|
return type_to_glsl(sampled_type);
|
||||||
|
}
|
||||||
|
|
||||||
// If we're emulating subpassInput with samplers, force sampler2D
|
// If we're emulating subpassInput with samplers, force sampler2D
|
||||||
// so we don't have to specify format.
|
// so we don't have to specify format.
|
||||||
@ -13513,3 +13567,69 @@ void CompilerGLSL::emit_copy_logical_type(uint32_t lhs_id, uint32_t lhs_type_id,
|
|||||||
emit_store_statement(lhs_id, rhs_id);
|
emit_store_statement(lhs_id, rhs_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CompilerGLSL::subpass_input_is_framebuffer_fetch(uint32_t id) const
|
||||||
|
{
|
||||||
|
if (!has_decoration(id, DecorationInputAttachmentIndex))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
uint32_t input_attachment_index = get_decoration(id, DecorationInputAttachmentIndex);
|
||||||
|
for (auto &remap : subpass_to_framebuffer_fetch_attachment)
|
||||||
|
if (remap.first == input_attachment_index)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SPIRVariable *CompilerGLSL::find_subpass_input_by_attachment_index(uint32_t index) const
|
||||||
|
{
|
||||||
|
const SPIRVariable *ret = nullptr;
|
||||||
|
ir.for_each_typed_id<SPIRVariable>([&](uint32_t, const SPIRVariable &var) {
|
||||||
|
if (has_decoration(var.self, DecorationInputAttachmentIndex) &&
|
||||||
|
get_decoration(var.self, DecorationInputAttachmentIndex) == index)
|
||||||
|
{
|
||||||
|
ret = &var;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SPIRVariable *CompilerGLSL::find_color_output_by_location(uint32_t location) const
|
||||||
|
{
|
||||||
|
const SPIRVariable *ret = nullptr;
|
||||||
|
ir.for_each_typed_id<SPIRVariable>([&](uint32_t, const SPIRVariable &var) {
|
||||||
|
if (var.storage == StorageClassOutput && get_decoration(var.self, DecorationLocation) == location)
|
||||||
|
ret = &var;
|
||||||
|
});
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CompilerGLSL::emit_inout_fragment_outputs_copy_to_subpass_inputs()
|
||||||
|
{
|
||||||
|
for (auto &remap : subpass_to_framebuffer_fetch_attachment)
|
||||||
|
{
|
||||||
|
auto *subpass_var = find_subpass_input_by_attachment_index(remap.first);
|
||||||
|
auto *output_var = find_color_output_by_location(remap.second);
|
||||||
|
if (!subpass_var)
|
||||||
|
continue;
|
||||||
|
if (!output_var)
|
||||||
|
SPIRV_CROSS_THROW("Need to declare the corresponding fragment output variable to be able to read from it.");
|
||||||
|
if (is_array(get<SPIRType>(output_var->basetype)))
|
||||||
|
SPIRV_CROSS_THROW("Cannot use GL_EXT_shader_framebuffer_fetch with arrays of color outputs.");
|
||||||
|
|
||||||
|
auto &func = get<SPIRFunction>(get_entry_point().self);
|
||||||
|
func.fixup_hooks_in.push_back([=]() {
|
||||||
|
if (is_legacy())
|
||||||
|
{
|
||||||
|
statement(to_expression(subpass_var->self), " = ", "gl_LastFragData[",
|
||||||
|
get_decoration(output_var->self, DecorationLocation), "];");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint32_t num_rt_components = this->get<SPIRType>(output_var->basetype).vecsize;
|
||||||
|
statement(to_expression(subpass_var->self), vector_swizzle(num_rt_components, 0), " = ",
|
||||||
|
to_expression(output_var->self), ";");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -156,6 +156,10 @@ public:
|
|||||||
remap_pls_variables();
|
remap_pls_variables();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Redirect a subpassInput reading from input_attachment_index to instead load its value from
|
||||||
|
// the color attachment at location = color_location. Requires ESSL.
|
||||||
|
void remap_ext_framebuffer_fetch(uint32_t input_attachment_index, uint32_t color_location);
|
||||||
|
|
||||||
explicit CompilerGLSL(std::vector<uint32_t> spirv_)
|
explicit CompilerGLSL(std::vector<uint32_t> spirv_)
|
||||||
: Compiler(std::move(spirv_))
|
: Compiler(std::move(spirv_))
|
||||||
{
|
{
|
||||||
@ -663,6 +667,14 @@ protected:
|
|||||||
void emit_pls();
|
void emit_pls();
|
||||||
void remap_pls_variables();
|
void remap_pls_variables();
|
||||||
|
|
||||||
|
// GL_EXT_shader_framebuffer_fetch support.
|
||||||
|
std::vector<std::pair<uint32_t, uint32_t>> subpass_to_framebuffer_fetch_attachment;
|
||||||
|
std::unordered_set<uint32_t> inout_color_attachments;
|
||||||
|
bool subpass_input_is_framebuffer_fetch(uint32_t id) const;
|
||||||
|
void emit_inout_fragment_outputs_copy_to_subpass_inputs();
|
||||||
|
const SPIRVariable *find_subpass_input_by_attachment_index(uint32_t index) const;
|
||||||
|
const SPIRVariable *find_color_output_by_location(uint32_t location) const;
|
||||||
|
|
||||||
// A variant which takes two sets of name. The secondary is only used to verify there are no collisions,
|
// A variant which takes two sets of name. The secondary is only used to verify there are no collisions,
|
||||||
// but the set is not updated when we have found a new name.
|
// but the set is not updated when we have found a new name.
|
||||||
// Used primarily when adding block interface names.
|
// Used primarily when adding block interface names.
|
||||||
|
@ -4857,8 +4857,7 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
|
|||||||
convert_non_uniform_expression(expression_type(ops[2]), expr);
|
convert_non_uniform_expression(expression_type(ops[2]), expr);
|
||||||
expr += join("[", to_expression(ops[3]), "]");
|
expr += join("[", to_expression(ops[3]), "]");
|
||||||
|
|
||||||
auto &e =
|
auto &e = set<SPIRExpression>(id, expr, result_type, true);
|
||||||
set<SPIRExpression>(id, expr, result_type, true);
|
|
||||||
|
|
||||||
// When using the pointer, we need to know which variable it is actually loaded from.
|
// When using the pointer, we need to know which variable it is actually loaded from.
|
||||||
auto *var = maybe_get_backing_variable(ops[2]);
|
auto *var = maybe_get_backing_variable(ops[2]);
|
||||||
|
@ -440,13 +440,19 @@ def cross_compile(shader, vulkan, spirv, invalid_spirv, eliminate, is_legacy, fl
|
|||||||
extra_args += ['--vulkan-glsl-disable-ext-samplerless-texture-functions']
|
extra_args += ['--vulkan-glsl-disable-ext-samplerless-texture-functions']
|
||||||
if '.no-qualifier-deduction.' in shader:
|
if '.no-qualifier-deduction.' in shader:
|
||||||
extra_args += ['--disable-storage-image-qualifier-deduction']
|
extra_args += ['--disable-storage-image-qualifier-deduction']
|
||||||
|
if '.framebuffer-fetch.' in shader:
|
||||||
|
extra_args += ['--glsl-remap-ext-framebuffer-fetch', '0', '0']
|
||||||
|
extra_args += ['--glsl-remap-ext-framebuffer-fetch', '1', '1']
|
||||||
|
extra_args += ['--glsl-remap-ext-framebuffer-fetch', '2', '2']
|
||||||
|
extra_args += ['--glsl-remap-ext-framebuffer-fetch', '3', '3']
|
||||||
|
|
||||||
spirv_cross_path = paths.spirv_cross
|
spirv_cross_path = paths.spirv_cross
|
||||||
|
|
||||||
# A shader might not be possible to make valid GLSL from, skip validation for this case.
|
# A shader might not be possible to make valid GLSL from, skip validation for this case.
|
||||||
if not ('nocompat' in glsl_path):
|
if (not ('nocompat' in glsl_path)) or (not vulkan):
|
||||||
subprocess.check_call([spirv_cross_path, '--entry', 'main', '--output', glsl_path, spirv_path] + extra_args)
|
subprocess.check_call([spirv_cross_path, '--entry', 'main', '--output', glsl_path, spirv_path] + extra_args)
|
||||||
validate_shader(glsl_path, False, paths)
|
if not 'nocompat' in glsl_path:
|
||||||
|
validate_shader(glsl_path, False, paths)
|
||||||
else:
|
else:
|
||||||
remove_file(glsl_path)
|
remove_file(glsl_path)
|
||||||
glsl_path = None
|
glsl_path = None
|
||||||
|
Loading…
Reference in New Issue
Block a user