diff options
Diffstat (limited to 'src/video_core/renderer_opengl')
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); } }; |
