aboutsummaryrefslogtreecommitdiff
path: root/src/video_core/renderer_opengl
diff options
context:
space:
mode:
authorReinUsesLisp <reinuseslisp@airmail.cc>2019-11-06 04:32:43 -0300
committerReinUsesLisp <reinuseslisp@airmail.cc>2019-11-22 21:28:47 -0300
commit32c1bc6a67820f9df21c8f64f4df078b015aa7da (patch)
tree141df885726a01fbd7d999d6ee314b4d11c8ce56 /src/video_core/renderer_opengl
parentc52f37f259372485ac5902d9cae8de327c984a55 (diff)
shader/texture: Deduce texture buffers from locker
Instead of specializing shaders to separate texture buffers from 1D textures, use the locker to deduce them while they are being decoded.
Diffstat (limited to 'src/video_core/renderer_opengl')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp45
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h15
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.cpp12
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp39
-rw-r--r--src/video_core/renderer_opengl/gl_shader_disk_cache.cpp33
-rw-r--r--src/video_core/renderer_opengl/gl_shader_disk_cache.h8
6 files changed, 47 insertions, 105 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 05f8e511b..b76de71ec 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -271,9 +271,9 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) {
const auto stage = static_cast<Maxwell::ShaderStage>(index == 0 ? 0 : index - 1);
SetupDrawConstBuffers(stage, shader);
SetupDrawGlobalMemory(stage, shader);
- const auto texture_buffer_usage{SetupDrawTextures(stage, shader, base_bindings)};
+ SetupDrawTextures(stage, shader, base_bindings);
- const ProgramVariant variant{base_bindings, primitive_mode, texture_buffer_usage};
+ const ProgramVariant variant{base_bindings, primitive_mode};
const auto [program_handle, next_bindings] = shader->GetProgramHandle(variant);
switch (program) {
@@ -303,7 +303,7 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) {
// When VertexA is enabled, we have dual vertex shaders
if (program == Maxwell::ShaderProgram::VertexA) {
// VertexB was combined with VertexA, so we skip the VertexB iteration
- index++;
+ ++index;
}
base_bindings = next_bindings;
@@ -732,11 +732,10 @@ void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) {
}
auto kernel = shader_cache.GetComputeKernel(code_addr);
- ProgramVariant variant;
- variant.texture_buffer_usage = SetupComputeTextures(kernel);
+ SetupComputeTextures(kernel);
SetupComputeImages(kernel);
- const auto [program, next_bindings] = kernel->GetProgramHandle(variant);
+ const auto [program, next_bindings] = kernel->GetProgramHandle({});
state.draw.shader_program = program;
state.draw.program_pipeline = 0;
@@ -918,9 +917,8 @@ void RasterizerOpenGL::SetupGlobalMemory(const GLShader::GlobalMemoryEntry& entr
bind_ssbo_pushbuffer.Push(ssbo, buffer_offset, static_cast<GLsizeiptr>(size));
}
-TextureBufferUsage RasterizerOpenGL::SetupDrawTextures(Maxwell::ShaderStage stage,
- const Shader& shader,
- BaseBindings base_bindings) {
+void RasterizerOpenGL::SetupDrawTextures(Maxwell::ShaderStage stage, const Shader& shader,
+ BaseBindings base_bindings) {
MICROPROFILE_SCOPE(OpenGL_Texture);
const auto& gpu = system.GPU();
const auto& maxwell3d = gpu.Maxwell3D();
@@ -929,8 +927,6 @@ TextureBufferUsage RasterizerOpenGL::SetupDrawTextures(Maxwell::ShaderStage stag
ASSERT_MSG(base_bindings.sampler + entries.size() <= std::size(state.textures),
"Exceeded the number of active textures.");
- TextureBufferUsage texture_buffer_usage{0};
-
for (u32 bindpoint = 0; bindpoint < entries.size(); ++bindpoint) {
const auto& entry = entries[bindpoint];
const auto texture = [&] {
@@ -943,15 +939,11 @@ TextureBufferUsage RasterizerOpenGL::SetupDrawTextures(Maxwell::ShaderStage stag
return maxwell3d.GetTextureInfo(tex_handle);
}();
- if (SetupTexture(base_bindings.sampler + bindpoint, texture, entry)) {
- texture_buffer_usage.set(bindpoint);
- }
+ SetupTexture(base_bindings.sampler + bindpoint, texture, entry);
}
-
- return texture_buffer_usage;
}
-TextureBufferUsage RasterizerOpenGL::SetupComputeTextures(const Shader& kernel) {
+void RasterizerOpenGL::SetupComputeTextures(const Shader& kernel) {
MICROPROFILE_SCOPE(OpenGL_Texture);
const auto& compute = system.GPU().KeplerCompute();
const auto& entries = kernel->GetShaderEntries().samplers;
@@ -959,8 +951,6 @@ TextureBufferUsage RasterizerOpenGL::SetupComputeTextures(const Shader& kernel)
ASSERT_MSG(entries.size() <= std::size(state.textures),
"Exceeded the number of active textures.");
- TextureBufferUsage texture_buffer_usage{0};
-
for (u32 bindpoint = 0; bindpoint < entries.size(); ++bindpoint) {
const auto& entry = entries[bindpoint];
const auto texture = [&] {
@@ -972,34 +962,29 @@ TextureBufferUsage RasterizerOpenGL::SetupComputeTextures(const Shader& kernel)
return compute.GetTextureInfo(tex_handle);
}();
- if (SetupTexture(bindpoint, texture, entry)) {
- texture_buffer_usage.set(bindpoint);
- }
+ SetupTexture(bindpoint, texture, entry);
}
-
- return texture_buffer_usage;
}
-bool RasterizerOpenGL::SetupTexture(u32 binding, const Tegra::Texture::FullTextureInfo& texture,
+void RasterizerOpenGL::SetupTexture(u32 binding, const Tegra::Texture::FullTextureInfo& texture,
const GLShader::SamplerEntry& entry) {
- state.samplers[binding] = sampler_cache.GetSampler(texture.tsc);
-
const auto view = texture_cache.GetTextureSurface(texture.tic, entry);
if (!view) {
// Can occur when texture addr is null or its memory is unmapped/invalid
+ state.samplers[binding] = 0;
state.textures[binding] = 0;
- return false;
+ return;
}
state.textures[binding] = view->GetTexture();
if (view->GetSurfaceParams().IsBuffer()) {
- return true;
+ return;
}
+ state.samplers[binding] = sampler_cache.GetSampler(texture.tsc);
// Apply swizzle to textures that are not buffers.
view->ApplySwizzle(texture.tic.x_source, texture.tic.y_source, texture.tic.z_source,
texture.tic.w_source);
- return false;
}
void RasterizerOpenGL::SetupComputeImages(const Shader& shader) {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index bd6fe5c3a..0e0819d59 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -107,16 +107,15 @@ private:
/// Syncs all the state, shaders, render targets and textures setting before a draw call.
void DrawPrelude();
- /// Configures the current textures to use for the draw command. Returns shaders texture buffer
- /// usage.
- TextureBufferUsage SetupDrawTextures(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage,
- const Shader& shader, BaseBindings base_bindings);
+ /// Configures the current textures to use for the draw command.
+ void SetupDrawTextures(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, const Shader& shader,
+ BaseBindings base_bindings);
- /// Configures the textures used in a compute shader. Returns texture buffer usage.
- TextureBufferUsage SetupComputeTextures(const Shader& kernel);
+ /// Configures the textures used in a compute shader.
+ void SetupComputeTextures(const Shader& kernel);
- /// Configures a texture. Returns true when the texture is a texture buffer.
- bool SetupTexture(u32 binding, const Tegra::Texture::FullTextureInfo& texture,
+ /// Configures a texture.
+ void SetupTexture(u32 binding, const Tegra::Texture::FullTextureInfo& texture,
const GLShader::SamplerEntry& entry);
/// Configures images in a compute shader.
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp
index 04a239a39..7ce06a978 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp
@@ -270,7 +270,6 @@ CachedProgram BuildShader(const Device& device, u64 unique_identifier, ProgramTy
auto base_bindings{variant.base_bindings};
const auto primitive_mode{variant.primitive_mode};
- const auto texture_buffer_usage{variant.texture_buffer_usage};
std::string source = fmt::format(R"(// {}
#version 430 core
@@ -317,17 +316,6 @@ CachedProgram BuildShader(const Device& device, u64 unique_identifier, ProgramTy
fmt::format("#define IMAGE_BINDING_{} {}\n", image.GetIndex(), base_bindings.image++);
}
- // Transform 1D textures to texture samplers by declaring its preprocessor macros.
- for (std::size_t i = 0; i < texture_buffer_usage.size(); ++i) {
- if (!texture_buffer_usage.test(i)) {
- continue;
- }
- source += fmt::format("#define SAMPLER_{}_IS_BUFFER\n", i);
- }
- if (texture_buffer_usage.any()) {
- source += '\n';
- }
-
if (program_type == ProgramType::Geometry) {
const auto [glsl_topology, debug_name, max_vertices] =
GetPrimitiveDescription(primitive_mode);
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 4f2b49170..51c80bf32 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -658,9 +658,11 @@ private:
const std::string description{"layout (binding = SAMPLER_BINDING_" +
std::to_string(sampler.GetIndex()) + ") uniform"};
std::string sampler_type = [&]() {
+ if (sampler.IsBuffer()) {
+ return "samplerBuffer";
+ }
switch (sampler.GetType()) {
case Tegra::Shader::TextureType::Texture1D:
- // Special cased, read below.
return "sampler1D";
case Tegra::Shader::TextureType::Texture2D:
return "sampler2D";
@@ -680,19 +682,7 @@ private:
sampler_type += "Shadow";
}
- if (sampler.GetType() == Tegra::Shader::TextureType::Texture1D) {
- // 1D textures can be aliased to texture buffers, hide the declarations behind a
- // preprocessor flag and use one or the other from the GPU state. This has to be
- // done because shaders don't have enough information to determine the texture type.
- EmitIfdefIsBuffer(sampler);
- code.AddLine("{} samplerBuffer {};", description, name);
- code.AddLine("#else");
- code.AddLine("{} {} {};", description, sampler_type, name);
- code.AddLine("#endif");
- } else {
- // The other texture types (2D, 3D and cubes) don't have this issue.
- code.AddLine("{} {} {};", description, sampler_type, name);
- }
+ code.AddLine("{} {} {};", description, sampler_type, name);
}
if (!samplers.empty()) {
code.AddNewLine();
@@ -1749,27 +1739,14 @@ private:
expr += ", ";
}
- // Store a copy of the expression without the lod to be used with texture buffers
- std::string expr_buffer = expr;
-
- if (meta->lod) {
+ if (meta->lod && !meta->sampler.IsBuffer()) {
expr += ", ";
expr += Visit(meta->lod).AsInt();
}
expr += ')';
expr += GetSwizzle(meta->element);
- expr_buffer += ')';
- expr_buffer += GetSwizzle(meta->element);
-
- const std::string tmp{code.GenerateTemporary()};
- EmitIfdefIsBuffer(meta->sampler);
- code.AddLine("float {} = {};", tmp, expr_buffer);
- code.AddLine("#else");
- code.AddLine("float {} = {};", tmp, expr);
- code.AddLine("#endif");
-
- return {tmp, Type::Float};
+ return {std::move(expr), Type::Float};
}
Expression ImageLoad(Operation operation) {
@@ -2214,10 +2191,6 @@ private:
return GetDeclarationWithSuffix(static_cast<u32>(image.GetIndex()), "image");
}
- void EmitIfdefIsBuffer(const Sampler& sampler) {
- code.AddLine("#ifdef SAMPLER_{}_IS_BUFFER", sampler.GetIndex());
- }
-
std::string GetDeclarationWithSuffix(u32 index, std::string_view name) const {
return fmt::format("{}_{}_{}", name, index, suffix);
}
diff --git a/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp b/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp
index 184a565e6..3f4daf28d 100644
--- a/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp
@@ -28,34 +28,35 @@ using VideoCommon::Shader::KeyMap;
namespace {
+using ShaderCacheVersionHash = std::array<u8, 64>;
+
+enum class TransferableEntryKind : u32 {
+ Raw,
+ Usage,
+};
+
struct ConstBufferKey {
- u32 cbuf;
- u32 offset;
- u32 value;
+ u32 cbuf{};
+ u32 offset{};
+ u32 value{};
};
struct BoundSamplerKey {
- u32 offset;
- Tegra::Engines::SamplerDescriptor sampler;
+ u32 offset{};
+ Tegra::Engines::SamplerDescriptor sampler{};
};
struct BindlessSamplerKey {
- u32 cbuf;
- u32 offset;
- Tegra::Engines::SamplerDescriptor sampler;
-};
-
-using ShaderCacheVersionHash = std::array<u8, 64>;
-
-enum class TransferableEntryKind : u32 {
- Raw,
- Usage,
+ u32 cbuf{};
+ u32 offset{};
+ Tegra::Engines::SamplerDescriptor sampler{};
};
-constexpr u32 NativeVersion = 5;
+constexpr u32 NativeVersion = 6;
// Making sure sizes doesn't change by accident
static_assert(sizeof(BaseBindings) == 16);
+static_assert(sizeof(ProgramVariant) == 20);
ShaderCacheVersionHash GetShaderCacheVersionHash() {
ShaderCacheVersionHash hash{};
diff --git a/src/video_core/renderer_opengl/gl_shader_disk_cache.h b/src/video_core/renderer_opengl/gl_shader_disk_cache.h
index db23ada93..55311dc6d 100644
--- a/src/video_core/renderer_opengl/gl_shader_disk_cache.h
+++ b/src/video_core/renderer_opengl/gl_shader_disk_cache.h
@@ -4,7 +4,6 @@
#pragma once
-#include <bitset>
#include <optional>
#include <string>
#include <tuple>
@@ -37,7 +36,6 @@ struct ShaderDiskCacheDump;
using ProgramCode = std::vector<u64>;
using ShaderDumpsMap = std::unordered_map<ShaderDiskCacheUsage, ShaderDiskCacheDump>;
-using TextureBufferUsage = std::bitset<64>;
/// Allocated bindings used by an OpenGL shader program
struct BaseBindings {
@@ -61,11 +59,10 @@ static_assert(std::is_trivially_copyable_v<BaseBindings>);
struct ProgramVariant {
BaseBindings base_bindings;
GLenum primitive_mode{};
- TextureBufferUsage texture_buffer_usage{};
bool operator==(const ProgramVariant& rhs) const {
- return std::tie(base_bindings, primitive_mode, texture_buffer_usage) ==
- std::tie(rhs.base_bindings, rhs.primitive_mode, rhs.texture_buffer_usage);
+ return std::tie(base_bindings, primitive_mode) ==
+ std::tie(rhs.base_bindings, rhs.primitive_mode);
}
bool operator!=(const ProgramVariant& rhs) const {
@@ -112,7 +109,6 @@ template <>
struct hash<OpenGL::ProgramVariant> {
std::size_t operator()(const OpenGL::ProgramVariant& variant) const noexcept {
return std::hash<OpenGL::BaseBindings>()(variant.base_bindings) ^
- std::hash<OpenGL::TextureBufferUsage>()(variant.texture_buffer_usage) ^
(static_cast<std::size_t>(variant.primitive_mode) << 6);
}
};