forked from suyu/suyu
glsl: Use textureGrad fallback when EXT_texture_shadow_lod is unsupported
This commit is contained in:
parent
d12f2b8ccf
commit
747b8556a4
4 changed files with 42 additions and 8 deletions
|
@ -282,8 +282,10 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile
|
||||||
void EmitContext::SetupExtensions(std::string&) {
|
void EmitContext::SetupExtensions(std::string&) {
|
||||||
// TODO: track this usage
|
// TODO: track this usage
|
||||||
header += "#extension GL_ARB_sparse_texture2 : enable\n"
|
header += "#extension GL_ARB_sparse_texture2 : enable\n"
|
||||||
"#extension GL_EXT_texture_shadow_lod : enable\n"
|
|
||||||
"#extension GL_EXT_shader_image_load_formatted : enable\n";
|
"#extension GL_EXT_shader_image_load_formatted : enable\n";
|
||||||
|
if (profile.support_gl_texture_shadow_lod) {
|
||||||
|
header += "#extension GL_EXT_texture_shadow_lod : enable\n";
|
||||||
|
}
|
||||||
if (info.uses_int64) {
|
if (info.uses_int64) {
|
||||||
header += "#extension GL_ARB_gpu_shader_int64 : enable\n";
|
header += "#extension GL_ARB_gpu_shader_int64 : enable\n";
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "shader_recompiler/backend/glsl/emit_glsl_instructions.h"
|
#include "shader_recompiler/backend/glsl/emit_glsl_instructions.h"
|
||||||
#include "shader_recompiler/frontend/ir/modifiers.h"
|
#include "shader_recompiler/frontend/ir/modifiers.h"
|
||||||
#include "shader_recompiler/frontend/ir/value.h"
|
#include "shader_recompiler/frontend/ir/value.h"
|
||||||
|
#include "shader_recompiler/profile.h"
|
||||||
|
|
||||||
namespace Shader::Backend::GLSL {
|
namespace Shader::Backend::GLSL {
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -67,14 +68,14 @@ std::string TexelFetchCastToInt(std::string_view value, const IR::TextureInstInf
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ShadowSamplerVecCast(TextureType type) {
|
bool NeedsShadowLodExt(TextureType type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case TextureType::ColorArray2D:
|
case TextureType::ColorArray2D:
|
||||||
case TextureType::ColorCube:
|
case TextureType::ColorCube:
|
||||||
case TextureType::ColorArrayCube:
|
case TextureType::ColorArrayCube:
|
||||||
return "vec4";
|
return true;
|
||||||
default:
|
default:
|
||||||
return "vec3";
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,7 +222,22 @@ void EmitImageSampleDrefImplicitLod([[maybe_unused]] EmitContext& ctx,
|
||||||
}
|
}
|
||||||
const auto texture{Texture(ctx, info, index)};
|
const auto texture{Texture(ctx, info, index)};
|
||||||
const auto bias{info.has_bias ? fmt::format(",{}", bias_lc) : ""};
|
const auto bias{info.has_bias ? fmt::format(",{}", bias_lc) : ""};
|
||||||
const auto cast{ShadowSamplerVecCast(info.type)};
|
const bool needs_shadow_ext{NeedsShadowLodExt(info.type)};
|
||||||
|
const auto cast{needs_shadow_ext ? "vec4" : "vec3"};
|
||||||
|
const bool use_grad{!ctx.profile.support_gl_texture_shadow_lod &&
|
||||||
|
ctx.stage != Stage::Fragment && needs_shadow_ext};
|
||||||
|
if (use_grad) {
|
||||||
|
// LOG_WARNING(..., "Device lacks GL_EXT_texture_shadow_lod. Using textureGrad fallback");
|
||||||
|
if (info.type == TextureType::ColorArrayCube) {
|
||||||
|
// LOG_WARNING(..., "textureGrad does not support ColorArrayCube. Stubbing");
|
||||||
|
ctx.AddF32("{}=0.0f;", inst);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto d_cast{info.type == TextureType::ColorArray2D ? "vec2" : "vec3"};
|
||||||
|
ctx.AddF32("{}=textureGrad({},{}({},{}),{}(0),{}(0));", inst, texture, cast, coords, dref,
|
||||||
|
d_cast, d_cast);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!offset.IsEmpty()) {
|
if (!offset.IsEmpty()) {
|
||||||
const auto offset_str{GetOffsetVec(ctx, offset)};
|
const auto offset_str{GetOffsetVec(ctx, offset)};
|
||||||
if (ctx.stage == Stage::Fragment) {
|
if (ctx.stage == Stage::Fragment) {
|
||||||
|
@ -263,15 +279,29 @@ void EmitImageSampleDrefExplicitLod([[maybe_unused]] EmitContext& ctx,
|
||||||
throw NotImplementedException("EmitImageSampleDrefExplicitLod Lod clamp samples");
|
throw NotImplementedException("EmitImageSampleDrefExplicitLod Lod clamp samples");
|
||||||
}
|
}
|
||||||
const auto texture{Texture(ctx, info, index)};
|
const auto texture{Texture(ctx, info, index)};
|
||||||
const auto cast{ShadowSamplerVecCast(info.type)};
|
const bool needs_shadow_ext{NeedsShadowLodExt(info.type)};
|
||||||
|
const bool use_grad{!ctx.profile.support_gl_texture_shadow_lod && needs_shadow_ext};
|
||||||
|
const auto cast{needs_shadow_ext ? "vec4" : "vec3"};
|
||||||
|
if (use_grad) {
|
||||||
|
// LOG_WARNING(..., "Device lacks GL_EXT_texture_shadow_lod. Using textureGrad fallback");
|
||||||
|
if (info.type == TextureType::ColorArrayCube) {
|
||||||
|
// LOG_WARNING(..., "textureGrad does not support ColorArrayCube. Stubbing");
|
||||||
|
ctx.AddF32("{}=0.0f;", inst);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto d_cast{info.type == TextureType::ColorArray2D ? "vec2" : "vec3"};
|
||||||
|
ctx.AddF32("{}=textureGrad({},{}({},{}),{}(0),{}(0));", inst, texture, cast, coords, dref,
|
||||||
|
d_cast, d_cast);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!offset.IsEmpty()) {
|
if (!offset.IsEmpty()) {
|
||||||
const auto offset_str{GetOffsetVec(ctx, offset)};
|
const auto offset_str{GetOffsetVec(ctx, offset)};
|
||||||
if (info.type == TextureType::ColorArrayCube) {
|
if (info.type == TextureType::ColorArrayCube) {
|
||||||
ctx.AddF32("{}=textureLodOffset({},{},{},{},{});", inst, texture, coords, dref, lod_lc,
|
ctx.AddF32("{}=textureLodOffset({},{},{},{},{});", inst, texture, coords, dref, lod_lc,
|
||||||
offset_str);
|
offset_str);
|
||||||
} else {
|
} else {
|
||||||
ctx.AddF32("{}=textureLodOffset({},vec3({},{}),{},{});", inst, texture, coords, dref,
|
ctx.AddF32("{}=textureLodOffset({},{}({},{}),{},{});", inst, texture, cast, coords,
|
||||||
lod_lc, offset_str);
|
dref, lod_lc, offset_str);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (info.type == TextureType::ColorArrayCube) {
|
if (info.type == TextureType::ColorArrayCube) {
|
||||||
|
|
|
@ -86,6 +86,7 @@ struct Profile {
|
||||||
bool support_gl_nv_gpu_shader_5{};
|
bool support_gl_nv_gpu_shader_5{};
|
||||||
bool support_gl_amd_gpu_shader_half_float{};
|
bool support_gl_amd_gpu_shader_half_float{};
|
||||||
bool support_gl_vertex_viewport_layer{};
|
bool support_gl_vertex_viewport_layer{};
|
||||||
|
bool support_gl_texture_shadow_lod{};
|
||||||
|
|
||||||
bool warp_size_potentially_larger_than_guest{};
|
bool warp_size_potentially_larger_than_guest{};
|
||||||
|
|
||||||
|
|
|
@ -226,6 +226,7 @@ ShaderCache::ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindo
|
||||||
.support_gl_nv_gpu_shader_5 = device.HasNvGpuShader5(),
|
.support_gl_nv_gpu_shader_5 = device.HasNvGpuShader5(),
|
||||||
.support_gl_amd_gpu_shader_half_float = device.HasAmdShaderHalfFloat(),
|
.support_gl_amd_gpu_shader_half_float = device.HasAmdShaderHalfFloat(),
|
||||||
.support_gl_vertex_viewport_layer = device.HasVertexViewportLayer(),
|
.support_gl_vertex_viewport_layer = device.HasVertexViewportLayer(),
|
||||||
|
.support_gl_texture_shadow_lod = device.HasTextureShadowLod(),
|
||||||
|
|
||||||
.warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyLargerThanGuest(),
|
.warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyLargerThanGuest(),
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue