1
0
Fork 0
forked from suyu/suyu

Merge pull request #4129 from Morph1984/texture-shadow-lod-workaround

gl_shader_decompiler: Workaround textureLod when GL_EXT_texture_shadow_lod is not available
This commit is contained in:
Rodrigo Locatti 2020-06-24 01:51:15 -03:00 committed by GitHub
commit b66ccaa376
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 50 additions and 7 deletions

View file

@ -216,6 +216,7 @@ Device::Device()
has_shader_ballot = GLAD_GL_ARB_shader_ballot; has_shader_ballot = GLAD_GL_ARB_shader_ballot;
has_vertex_viewport_layer = GLAD_GL_ARB_shader_viewport_layer_array; has_vertex_viewport_layer = GLAD_GL_ARB_shader_viewport_layer_array;
has_image_load_formatted = HasExtension(extensions, "GL_EXT_shader_image_load_formatted"); has_image_load_formatted = HasExtension(extensions, "GL_EXT_shader_image_load_formatted");
has_texture_shadow_lod = HasExtension(extensions, "GL_EXT_texture_shadow_lod");
has_astc = IsASTCSupported(); has_astc = IsASTCSupported();
has_variable_aoffi = TestVariableAoffi(); has_variable_aoffi = TestVariableAoffi();
has_component_indexing_bug = is_amd; has_component_indexing_bug = is_amd;
@ -245,6 +246,7 @@ Device::Device(std::nullptr_t) {
has_shader_ballot = true; has_shader_ballot = true;
has_vertex_viewport_layer = true; has_vertex_viewport_layer = true;
has_image_load_formatted = true; has_image_load_formatted = true;
has_texture_shadow_lod = true;
has_variable_aoffi = true; has_variable_aoffi = true;
} }

View file

@ -68,6 +68,10 @@ public:
return has_image_load_formatted; return has_image_load_formatted;
} }
bool HasTextureShadowLod() const {
return has_texture_shadow_lod;
}
bool HasASTC() const { bool HasASTC() const {
return has_astc; return has_astc;
} }
@ -110,6 +114,7 @@ private:
bool has_shader_ballot{}; bool has_shader_ballot{};
bool has_vertex_viewport_layer{}; bool has_vertex_viewport_layer{};
bool has_image_load_formatted{}; bool has_image_load_formatted{};
bool has_texture_shadow_lod{};
bool has_astc{}; bool has_astc{};
bool has_variable_aoffi{}; bool has_variable_aoffi{};
bool has_component_indexing_bug{}; bool has_component_indexing_bug{};

View file

@ -37,6 +37,7 @@ using Tegra::Shader::IpaMode;
using Tegra::Shader::IpaSampleMode; using Tegra::Shader::IpaSampleMode;
using Tegra::Shader::PixelImap; using Tegra::Shader::PixelImap;
using Tegra::Shader::Register; using Tegra::Shader::Register;
using Tegra::Shader::TextureType;
using VideoCommon::Shader::BuildTransformFeedback; using VideoCommon::Shader::BuildTransformFeedback;
using VideoCommon::Shader::Registry; using VideoCommon::Shader::Registry;
@ -526,6 +527,9 @@ private:
if (device.HasImageLoadFormatted()) { if (device.HasImageLoadFormatted()) {
code.AddLine("#extension GL_EXT_shader_image_load_formatted : require"); code.AddLine("#extension GL_EXT_shader_image_load_formatted : require");
} }
if (device.HasTextureShadowLod()) {
code.AddLine("#extension GL_EXT_texture_shadow_lod : require");
}
if (device.HasWarpIntrinsics()) { if (device.HasWarpIntrinsics()) {
code.AddLine("#extension GL_NV_gpu_shader5 : require"); code.AddLine("#extension GL_NV_gpu_shader5 : require");
code.AddLine("#extension GL_NV_shader_thread_group : require"); code.AddLine("#extension GL_NV_shader_thread_group : require");
@ -909,13 +913,13 @@ private:
return "samplerBuffer"; return "samplerBuffer";
} }
switch (sampler.type) { switch (sampler.type) {
case Tegra::Shader::TextureType::Texture1D: case TextureType::Texture1D:
return "sampler1D"; return "sampler1D";
case Tegra::Shader::TextureType::Texture2D: case TextureType::Texture2D:
return "sampler2D"; return "sampler2D";
case Tegra::Shader::TextureType::Texture3D: case TextureType::Texture3D:
return "sampler3D"; return "sampler3D";
case Tegra::Shader::TextureType::TextureCube: case TextureType::TextureCube:
return "samplerCube"; return "samplerCube";
default: default:
UNREACHABLE(); UNREACHABLE();
@ -1380,8 +1384,19 @@ private:
const std::size_t count = operation.GetOperandsCount(); const std::size_t count = operation.GetOperandsCount();
const bool has_array = meta->sampler.is_array; const bool has_array = meta->sampler.is_array;
const bool has_shadow = meta->sampler.is_shadow; const bool has_shadow = meta->sampler.is_shadow;
const bool workaround_lod_array_shadow_as_grad =
!device.HasTextureShadowLod() && function_suffix == "Lod" && meta->sampler.is_shadow &&
((meta->sampler.type == TextureType::Texture2D && meta->sampler.is_array) ||
meta->sampler.type == TextureType::TextureCube);
std::string expr = "texture";
if (workaround_lod_array_shadow_as_grad) {
expr += "Grad";
} else {
expr += function_suffix;
}
std::string expr = "texture" + function_suffix;
if (!meta->aoffi.empty()) { if (!meta->aoffi.empty()) {
expr += "Offset"; expr += "Offset";
} else if (!meta->ptp.empty()) { } else if (!meta->ptp.empty()) {
@ -1415,6 +1430,16 @@ private:
expr += ')'; expr += ')';
} }
if (workaround_lod_array_shadow_as_grad) {
switch (meta->sampler.type) {
case TextureType::Texture2D:
return expr + ", vec2(0.0), vec2(0.0))";
case TextureType::TextureCube:
return expr + ", vec3(0.0), vec3(0.0))";
}
UNREACHABLE();
}
for (const auto& variant : extras) { for (const auto& variant : extras) {
if (const auto argument = std::get_if<TextureArgument>(&variant)) { if (const auto argument = std::get_if<TextureArgument>(&variant)) {
expr += GenerateTextureArgument(*argument); expr += GenerateTextureArgument(*argument);
@ -2041,8 +2066,19 @@ private:
const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); const auto meta = std::get_if<MetaTexture>(&operation.GetMeta());
ASSERT(meta); ASSERT(meta);
std::string expr = GenerateTexture( std::string expr{};
operation, "Lod", {TextureArgument{Type::Float, meta->lod}, TextureOffset{}});
if (!device.HasTextureShadowLod() && meta->sampler.is_shadow &&
((meta->sampler.type == TextureType::Texture2D && meta->sampler.is_array) ||
meta->sampler.type == TextureType::TextureCube)) {
LOG_ERROR(Render_OpenGL,
"Device lacks GL_EXT_texture_shadow_lod, using textureGrad as a workaround");
expr = GenerateTexture(operation, "Lod", {});
} else {
expr = GenerateTexture(operation, "Lod",
{TextureArgument{Type::Float, meta->lod}, TextureOffset{}});
}
if (meta->sampler.is_shadow) { if (meta->sampler.is_shadow) {
expr = "vec4(" + expr + ')'; expr = "vec4(" + expr + ')';
} }