|
@@ -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(
|
|
|
|
|
- operation, "Lod", {TextureArgument{Type::Float, meta->lod}, TextureOffset{}});
|
|
|
|
|
|
|
+ std::string expr{};
|
|
|
|
|
+
|
|
|
|
|
+ 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 + ')';
|
|
|
}
|
|
}
|