diff --git a/rpcs3/Emu/RSX/GL/glutils/program.cpp b/rpcs3/Emu/RSX/GL/glutils/program.cpp index 8421df0b7d..f3d7a85f48 100644 --- a/rpcs3/Emu/RSX/GL/glutils/program.cpp +++ b/rpcs3/Emu/RSX/GL/glutils/program.cpp @@ -8,8 +8,109 @@ namespace gl { namespace glsl { + void patch_macros_INTEL(std::string& source) + { + auto read_token = [&source](size_t start) -> std::tuple + { + size_t string_begin = std::string::npos, i = start; + for (size_t count = 0; i < source.length(); ++i) + { + const auto& c = source[i]; + const auto is_space = std::isspace(c); + + if (string_begin == std::string::npos) + { + if (c == '\n') break; + if (is_space) continue; + + string_begin = i; + } + + if (is_space) + { + if (!count) break; + } + else if (c == '(') + { + count++; + } + else if (c == ')') + { + count--; + } + } + + return std::make_tuple(string_begin, i - 1); + }; + + auto is_exempt = [&source](const std::string_view& token) -> bool + { + const char* handled_keywords[] = + { + "SSBO_LOCATION(x)", + "UBO_LOCATION(x)", + "IMAGE_LOCATION(x)" + }; + + for (const auto& keyword : handled_keywords) + { + if (token.starts_with(keyword)) + { + return false; + } + } + + return true; + }; + + size_t prev_loc = 0; + while (true) + { + // Find macro define blocks and remove the outer-most brackets around the expression part + const auto next_loc = source.find("#define", prev_loc); + if (next_loc == std::string::npos) + { + break; + } + + prev_loc = next_loc + 1; + + const auto [name_start, name_end] = read_token(next_loc + ("#define"sv).length()); + if (name_start == std::string::npos) + { + break; + } + + const auto macro_name = std::string_view(source.data() + name_start, source.data() + name_end + 1); + if (is_exempt(macro_name)) + { + continue; + } + + const auto [expr_start, expr_end] = read_token(name_end + 1); + if (expr_start == std::string::npos) + { + continue; + } + + if (source[expr_start] == '(' && source[expr_end] == ')') + { + rsx_log.notice("[Compiler warning] We'll remove brackets around the expression named '%s'. Add it to exclusion list if this is not desired.", macro_name); + + source[expr_start] = ' '; + source[expr_end] = ' '; + } + } + } + void shader::precompile() { + if (gl::get_driver_caps().vendor_INTEL) + { + // Workaround for broken macro expansion. + patch_macros_INTEL(source); + } + const char* str = source.c_str(); const GLint length = ::narrow(source.length()); diff --git a/rpcs3/Emu/RSX/Program/GLSLSnippets/GPUDeswizzle.glsl b/rpcs3/Emu/RSX/Program/GLSLSnippets/GPUDeswizzle.glsl index b34d3b3cba..9a487a8257 100644 --- a/rpcs3/Emu/RSX/Program/GLSLSnippets/GPUDeswizzle.glsl +++ b/rpcs3/Emu/RSX/Program/GLSLSnippets/GPUDeswizzle.glsl @@ -1,13 +1,12 @@ R"( #version 450 -#define SSBO_BASE_LOCATION %loc -#define SSBO(x) (SSBO_BASE_LOCATION + x) +#define SSBO_LOCATION(x) (x + %loc) layout(local_size_x = %ws, local_size_y = 1, local_size_z = 1) in; -layout(%set, binding=SSBO(0), std430) buffer ssbo0{ uint data_in[]; }; -layout(%set, binding=SSBO(1), std430) buffer ssbo1{ uint data_out[]; }; +layout(%set, binding=SSBO_LOCATION(0), std430) buffer ssbo0{ uint data_in[]; }; +layout(%set, binding=SSBO_LOCATION(1), std430) buffer ssbo1{ uint data_out[]; }; layout(%push_block) uniform parameters { uint image_width;