mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-22 13:55:38 +00:00
dep/reshadefx: Support generating GLSL ES
This commit is contained in:
parent
bcc2042154
commit
ba5d1a109e
|
@ -352,12 +352,13 @@ namespace reshadefx
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a back-end implementation for GLSL code generation.
|
/// Creates a back-end implementation for GLSL code generation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="gles">Generate GLSL ES code instead of core OpenGL.</param>
|
||||||
/// <param name="vulkan_semantics">Generate GLSL for OpenGL or for Vulkan.</param>
|
/// <param name="vulkan_semantics">Generate GLSL for OpenGL or for Vulkan.</param>
|
||||||
/// <param name="debug_info">Whether to append debug information like line directives to the generated code.</param>
|
/// <param name="debug_info">Whether to append debug information like line directives to the generated code.</param>
|
||||||
/// <param name="uniforms_to_spec_constants">Whether to convert uniform variables to specialization constants.</param>
|
/// <param name="uniforms_to_spec_constants">Whether to convert uniform variables to specialization constants.</param>
|
||||||
/// <param name="enable_16bit_types">Use real 16-bit types for the minimum precision types "min16int", "min16uint" and "min16float".</param>
|
/// <param name="enable_16bit_types">Use real 16-bit types for the minimum precision types "min16int", "min16uint" and "min16float".</param>
|
||||||
/// <param name="flip_vert_y">Insert code to flip the Y component of the output position in vertex shaders.</param>
|
/// <param name="flip_vert_y">Insert code to flip the Y component of the output position in vertex shaders.</param>
|
||||||
codegen *create_codegen_glsl(bool vulkan_semantics, bool debug_info, bool uniforms_to_spec_constants, bool enable_16bit_types = false, bool flip_vert_y = false);
|
codegen *create_codegen_glsl(bool gles, bool vulkan_semantics, bool debug_info, bool uniforms_to_spec_constants, bool enable_16bit_types = false, bool flip_vert_y = false);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a back-end implementation for HLSL code generation.
|
/// Creates a back-end implementation for HLSL code generation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -13,11 +13,12 @@
|
||||||
|
|
||||||
using namespace reshadefx;
|
using namespace reshadefx;
|
||||||
|
|
||||||
|
namespace {
|
||||||
class codegen_glsl final : public codegen
|
class codegen_glsl final : public codegen
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
codegen_glsl(bool vulkan_semantics, bool debug_info, bool uniforms_to_spec_constants, bool enable_16bit_types, bool flip_vert_y)
|
codegen_glsl(bool gles, bool vulkan_semantics, bool debug_info, bool uniforms_to_spec_constants, bool enable_16bit_types, bool flip_vert_y)
|
||||||
: _debug_info(debug_info), _vulkan_semantics(vulkan_semantics), _uniforms_to_spec_constants(uniforms_to_spec_constants), _enable_16bit_types(enable_16bit_types), _flip_vert_y(flip_vert_y)
|
: _gles(gles), _debug_info(debug_info), _vulkan_semantics(vulkan_semantics), _uniforms_to_spec_constants(uniforms_to_spec_constants), _enable_16bit_types(enable_16bit_types), _flip_vert_y(flip_vert_y)
|
||||||
{
|
{
|
||||||
// Create default block and reserve a memory block to avoid frequent reallocations
|
// Create default block and reserve a memory block to avoid frequent reallocations
|
||||||
std::string &block = _blocks.emplace(0, std::string()).first->second;
|
std::string &block = _blocks.emplace(0, std::string()).first->second;
|
||||||
|
@ -41,6 +42,7 @@ private:
|
||||||
std::string _compute_block;
|
std::string _compute_block;
|
||||||
std::unordered_map<id, std::string> _names;
|
std::unordered_map<id, std::string> _names;
|
||||||
std::unordered_map<id, std::string> _blocks;
|
std::unordered_map<id, std::string> _blocks;
|
||||||
|
bool _gles = false;
|
||||||
bool _debug_info = false;
|
bool _debug_info = false;
|
||||||
bool _vulkan_semantics = false;
|
bool _vulkan_semantics = false;
|
||||||
bool _uniforms_to_spec_constants = false;
|
bool _uniforms_to_spec_constants = false;
|
||||||
|
@ -755,7 +757,7 @@ private:
|
||||||
if (!global)
|
if (!global)
|
||||||
code += '\t';
|
code += '\t';
|
||||||
|
|
||||||
if (initializer_value != 0 && type.has(type::q_const))
|
if (initializer_value != 0 && (type.has(type::q_const) && !_gles))
|
||||||
code += "const ";
|
code += "const ";
|
||||||
|
|
||||||
write_type(code, type);
|
write_type(code, type);
|
||||||
|
@ -843,8 +845,8 @@ private:
|
||||||
_blocks.at(0) += "#ifdef ENTRY_POINT_" + func.unique_name + '\n';
|
_blocks.at(0) += "#ifdef ENTRY_POINT_" + func.unique_name + '\n';
|
||||||
if (stype == shader_type::cs)
|
if (stype == shader_type::cs)
|
||||||
_blocks.at(0) += "layout(local_size_x = " + std::to_string(num_threads[0]) +
|
_blocks.at(0) += "layout(local_size_x = " + std::to_string(num_threads[0]) +
|
||||||
", local_size_y = " + std::to_string(num_threads[1]) +
|
", local_size_y = " + std::to_string(num_threads[1]) +
|
||||||
", local_size_z = " + std::to_string(num_threads[2]) + ") in;\n";
|
", local_size_z = " + std::to_string(num_threads[2]) + ") in;\n";
|
||||||
|
|
||||||
function_info entry_point;
|
function_info entry_point;
|
||||||
entry_point.return_type = { type::t_void };
|
entry_point.return_type = { type::t_void };
|
||||||
|
@ -1004,7 +1006,7 @@ private:
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (member.type.is_boolean())
|
if (member.type.is_boolean() || (_gles && member.type.is_integral()))
|
||||||
{
|
{
|
||||||
write_type<false, false>(code, member.type);
|
write_type<false, false>(code, member.type);
|
||||||
code += '(';
|
code += '(';
|
||||||
|
@ -1012,7 +1014,7 @@ private:
|
||||||
|
|
||||||
code += semantic_to_builtin(std::move(in_param_name), member.semantic, stype);
|
code += semantic_to_builtin(std::move(in_param_name), member.semantic, stype);
|
||||||
|
|
||||||
if (member.type.is_boolean())
|
if (member.type.is_boolean() || (_gles && member.type.is_integral()))
|
||||||
code += ')';
|
code += ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1097,7 +1099,7 @@ private:
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (param_type.is_boolean())
|
if (param_type.is_boolean() || (_gles && param_type.is_integral()))
|
||||||
{
|
{
|
||||||
write_type<false, false>(code, param_type);
|
write_type<false, false>(code, param_type);
|
||||||
code += '(';
|
code += '(';
|
||||||
|
@ -1105,7 +1107,7 @@ private:
|
||||||
|
|
||||||
code += semantic_to_builtin("_in_param" + std::to_string(i), func.parameter_list[i].semantic, stype);
|
code += semantic_to_builtin("_in_param" + std::to_string(i), func.parameter_list[i].semantic, stype);
|
||||||
|
|
||||||
if (param_type.is_boolean())
|
if (param_type.is_boolean() || (_gles && param_type.is_integral()))
|
||||||
code += ')';
|
code += ')';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1345,9 +1347,31 @@ private:
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
expr_code += '.';
|
// can't swizzle scalars
|
||||||
for (unsigned int i = 0; i < 4 && op.swizzle[i] >= 0; ++i)
|
if (_gles && op.from.is_scalar())
|
||||||
expr_code += "xyzw"[op.swizzle[i]];
|
{
|
||||||
|
// => e.g. vec3(expr, expr, expr).xyz
|
||||||
|
type.clear();
|
||||||
|
write_type<false, false>(type, op.to);
|
||||||
|
std::string new_code = type;
|
||||||
|
new_code += '(';
|
||||||
|
|
||||||
|
const unsigned int components = op.to.components();
|
||||||
|
for (unsigned int i = 0; i < components; ++i)
|
||||||
|
{
|
||||||
|
if (i > 0)
|
||||||
|
new_code += ',';
|
||||||
|
new_code += '(' + expr_code + ')';
|
||||||
|
}
|
||||||
|
new_code += ')';
|
||||||
|
expr_code = std::move(new_code);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
expr_code += '.';
|
||||||
|
for (unsigned int i = 0; i < 4 && op.swizzle[i] >= 0; ++i)
|
||||||
|
expr_code += "xyzw"[op.swizzle[i]];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1812,7 +1836,7 @@ private:
|
||||||
|
|
||||||
write_location(code, loc);
|
write_location(code, loc);
|
||||||
|
|
||||||
if (flags != 0)
|
if (flags != 0 && !_gles)
|
||||||
{
|
{
|
||||||
_enable_control_flow_attributes = true;
|
_enable_control_flow_attributes = true;
|
||||||
|
|
||||||
|
@ -1896,7 +1920,7 @@ private:
|
||||||
code += _blocks.at(prev_block);
|
code += _blocks.at(prev_block);
|
||||||
|
|
||||||
std::string attributes;
|
std::string attributes;
|
||||||
if (flags != 0)
|
if (flags != 0 && !_gles)
|
||||||
{
|
{
|
||||||
_enable_control_flow_attributes = true;
|
_enable_control_flow_attributes = true;
|
||||||
|
|
||||||
|
@ -2158,8 +2182,9 @@ private:
|
||||||
_blocks.at(0) += "{\n" + _blocks.at(_last_block) + "}\n";
|
_blocks.at(0) += "{\n" + _blocks.at(_last_block) + "}\n";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
codegen *reshadefx::create_codegen_glsl(bool vulkan_semantics, bool debug_info, bool uniforms_to_spec_constants, bool enable_16bit_types, bool flip_vert_y)
|
codegen *reshadefx::create_codegen_glsl(bool gles, bool vulkan_semantics, bool debug_info, bool uniforms_to_spec_constants, bool enable_16bit_types, bool flip_vert_y)
|
||||||
{
|
{
|
||||||
return new codegen_glsl(vulkan_semantics, debug_info, uniforms_to_spec_constants, enable_16bit_types, flip_vert_y);
|
return new codegen_glsl(gles, vulkan_semantics, debug_info, uniforms_to_spec_constants, enable_16bit_types, flip_vert_y);
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,15 +81,15 @@ static std::unique_ptr<reshadefx::codegen> CreateRFXCodegen()
|
||||||
case RenderAPI::Metal:
|
case RenderAPI::Metal:
|
||||||
{
|
{
|
||||||
return std::unique_ptr<reshadefx::codegen>(reshadefx::create_codegen_glsl(
|
return std::unique_ptr<reshadefx::codegen>(reshadefx::create_codegen_glsl(
|
||||||
true, debug_info, uniforms_to_spec_constants, false, (rapi == RenderAPI::Vulkan)));
|
false, true, debug_info, uniforms_to_spec_constants, false, (rapi == RenderAPI::Vulkan)));
|
||||||
}
|
}
|
||||||
|
|
||||||
case RenderAPI::OpenGL:
|
case RenderAPI::OpenGL:
|
||||||
case RenderAPI::OpenGLES:
|
case RenderAPI::OpenGLES:
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
return std::unique_ptr<reshadefx::codegen>(
|
return std::unique_ptr<reshadefx::codegen>(reshadefx::create_codegen_glsl(
|
||||||
reshadefx::create_codegen_glsl(false, debug_info, uniforms_to_spec_constants, false, true));
|
(rapi == RenderAPI::OpenGLES), false, debug_info, uniforms_to_spec_constants, false, true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1099,14 +1099,18 @@ bool PostProcessing::ReShadeFXShader::CompilePipeline(GPUTexture::Format format,
|
||||||
|
|
||||||
const std::string_view code(mod.code.data(), mod.code.size());
|
const std::string_view code(mod.code.data(), mod.code.size());
|
||||||
|
|
||||||
auto get_shader = [needs_main_defn, &code](const std::string& name, const std::vector<Sampler>& samplers,
|
auto get_shader = [api, needs_main_defn, &code](const std::string& name, const std::vector<Sampler>& samplers,
|
||||||
GPUShaderStage stage) {
|
GPUShaderStage stage) {
|
||||||
std::string real_code;
|
std::string real_code;
|
||||||
if (needs_main_defn)
|
if (needs_main_defn)
|
||||||
{
|
{
|
||||||
// dFdx/dFdy are not defined in the vertex shader.
|
// dFdx/dFdy are not defined in the vertex shader.
|
||||||
const char* defns = (stage == GPUShaderStage::Vertex) ? "#define dFdx(x) x\n#define dFdy(x) x\n" : "";
|
const char* defns = (stage == GPUShaderStage::Vertex) ? "#define dFdx(x) x\n#define dFdy(x) x\n" : "";
|
||||||
real_code = fmt::format("#version 460 core\n#define ENTRY_POINT_{}\n{}\n{}", name, defns, code);
|
const char* precision = (api == RenderAPI::OpenGLES) ?
|
||||||
|
"precision highp float;\nprecision highp int;\nprecision highp sampler2D;\n" :
|
||||||
|
"";
|
||||||
|
real_code = fmt::format("#version {}\n#define ENTRY_POINT_{}\n{}\n{}\n{}",
|
||||||
|
(api == RenderAPI::OpenGLES) ? "320 es" : "460 core", name, defns, precision, code);
|
||||||
|
|
||||||
for (const Sampler& sampler : samplers)
|
for (const Sampler& sampler : samplers)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue