summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_opengl/gl_shader_cache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/renderer_opengl/gl_shader_cache.cpp')
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.cpp78
1 files changed, 44 insertions, 34 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp
index ac8a9e6b7..e859a900c 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp
@@ -168,8 +168,12 @@ GLShader::ProgramResult CreateProgram(const Device& device, Maxwell::ShaderProgr
}
CachedProgram SpecializeShader(const std::string& code, const GLShader::ShaderEntries& entries,
- Maxwell::ShaderProgram program_type, BaseBindings base_bindings,
- GLenum primitive_mode, bool hint_retrievable = false) {
+ Maxwell::ShaderProgram program_type, const ProgramVariant& variant,
+ bool hint_retrievable = false) {
+ 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 = "#version 430 core\n"
"#extension GL_ARB_separate_shader_objects : enable\n\n";
source += fmt::format("#define EMULATION_UBO_BINDING {}\n", base_bindings.cbuf++);
@@ -187,6 +191,14 @@ CachedProgram SpecializeShader(const std::string& code, const GLShader::ShaderEn
base_bindings.sampler++);
}
+ // 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", i);
+ }
+
if (program_type == Maxwell::ShaderProgram::Geometry) {
const auto [glsl_topology, debug_name, max_vertices] =
GetPrimitiveDescription(primitive_mode);
@@ -261,20 +273,18 @@ CachedShader::CachedShader(VAddr cpu_addr, u64 unique_identifier,
shader_length = entries.shader_length;
}
-std::tuple<GLuint, BaseBindings> CachedShader::GetProgramHandle(GLenum primitive_mode,
- BaseBindings base_bindings) {
+std::tuple<GLuint, BaseBindings> CachedShader::GetProgramHandle(const ProgramVariant& variant) {
GLuint handle{};
if (program_type == Maxwell::ShaderProgram::Geometry) {
- handle = GetGeometryShader(primitive_mode, base_bindings);
+ handle = GetGeometryShader(variant);
} else {
- const auto [entry, is_cache_miss] = programs.try_emplace(base_bindings);
+ const auto [entry, is_cache_miss] = programs.try_emplace(variant);
auto& program = entry->second;
if (is_cache_miss) {
- program = TryLoadProgram(primitive_mode, base_bindings);
+ program = TryLoadProgram(variant);
if (!program) {
- program =
- SpecializeShader(code, entries, program_type, base_bindings, primitive_mode);
- disk_cache.SaveUsage(GetUsage(primitive_mode, base_bindings));
+ program = SpecializeShader(code, entries, program_type, variant);
+ disk_cache.SaveUsage(GetUsage(variant));
}
LabelGLObject(GL_PROGRAM, program->handle, cpu_addr);
@@ -283,6 +293,7 @@ std::tuple<GLuint, BaseBindings> CachedShader::GetProgramHandle(GLenum primitive
handle = program->handle;
}
+ auto base_bindings{variant.base_bindings};
base_bindings.cbuf += static_cast<u32>(entries.const_buffers.size()) + RESERVED_UBOS;
base_bindings.gmem += static_cast<u32>(entries.global_memory_entries.size());
base_bindings.sampler += static_cast<u32>(entries.samplers.size());
@@ -290,43 +301,42 @@ std::tuple<GLuint, BaseBindings> CachedShader::GetProgramHandle(GLenum primitive
return {handle, base_bindings};
}
-GLuint CachedShader::GetGeometryShader(GLenum primitive_mode, BaseBindings base_bindings) {
- const auto [entry, is_cache_miss] = geometry_programs.try_emplace(base_bindings);
+GLuint CachedShader::GetGeometryShader(const ProgramVariant& variant) {
+ const auto [entry, is_cache_miss] = geometry_programs.try_emplace(variant);
auto& programs = entry->second;
- switch (primitive_mode) {
+ switch (variant.primitive_mode) {
case GL_POINTS:
- return LazyGeometryProgram(programs.points, base_bindings, primitive_mode);
+ return LazyGeometryProgram(programs.points, variant);
case GL_LINES:
case GL_LINE_STRIP:
- return LazyGeometryProgram(programs.lines, base_bindings, primitive_mode);
+ return LazyGeometryProgram(programs.lines, variant);
case GL_LINES_ADJACENCY:
case GL_LINE_STRIP_ADJACENCY:
- return LazyGeometryProgram(programs.lines_adjacency, base_bindings, primitive_mode);
+ return LazyGeometryProgram(programs.lines_adjacency, variant);
case GL_TRIANGLES:
case GL_TRIANGLE_STRIP:
case GL_TRIANGLE_FAN:
- return LazyGeometryProgram(programs.triangles, base_bindings, primitive_mode);
+ return LazyGeometryProgram(programs.triangles, variant);
case GL_TRIANGLES_ADJACENCY:
case GL_TRIANGLE_STRIP_ADJACENCY:
- return LazyGeometryProgram(programs.triangles_adjacency, base_bindings, primitive_mode);
+ return LazyGeometryProgram(programs.triangles_adjacency, variant);
default:
UNREACHABLE_MSG("Unknown primitive mode.");
- return LazyGeometryProgram(programs.points, base_bindings, primitive_mode);
+ return LazyGeometryProgram(programs.points, variant);
}
}
-GLuint CachedShader::LazyGeometryProgram(CachedProgram& target_program, BaseBindings base_bindings,
- GLenum primitive_mode) {
+GLuint CachedShader::LazyGeometryProgram(CachedProgram& target_program,
+ const ProgramVariant& variant) {
if (target_program) {
return target_program->handle;
}
- const auto [glsl_name, debug_name, vertices] = GetPrimitiveDescription(primitive_mode);
- target_program = TryLoadProgram(primitive_mode, base_bindings);
+ const auto [glsl_name, debug_name, vertices] = GetPrimitiveDescription(variant.primitive_mode);
+ target_program = TryLoadProgram(variant);
if (!target_program) {
- target_program =
- SpecializeShader(code, entries, program_type, base_bindings, primitive_mode);
- disk_cache.SaveUsage(GetUsage(primitive_mode, base_bindings));
+ target_program = SpecializeShader(code, entries, program_type, variant);
+ disk_cache.SaveUsage(GetUsage(variant));
}
LabelGLObject(GL_PROGRAM, target_program->handle, cpu_addr, debug_name);
@@ -334,18 +344,19 @@ GLuint CachedShader::LazyGeometryProgram(CachedProgram& target_program, BaseBind
return target_program->handle;
};
-CachedProgram CachedShader::TryLoadProgram(GLenum primitive_mode,
- BaseBindings base_bindings) const {
- const auto found = precompiled_programs.find(GetUsage(primitive_mode, base_bindings));
+CachedProgram CachedShader::TryLoadProgram(const ProgramVariant& variant) const {
+ const auto found = precompiled_programs.find(GetUsage(variant));
if (found == precompiled_programs.end()) {
return {};
}
return found->second;
}
-ShaderDiskCacheUsage CachedShader::GetUsage(GLenum primitive_mode,
- BaseBindings base_bindings) const {
- return {unique_identifier, base_bindings, primitive_mode};
+ShaderDiskCacheUsage CachedShader::GetUsage(const ProgramVariant& variant) const {
+ ShaderDiskCacheUsage usage;
+ usage.unique_identifier = unique_identifier;
+ usage.variant = variant;
+ return usage;
}
ShaderCacheOpenGL::ShaderCacheOpenGL(RasterizerOpenGL& rasterizer, Core::System& system,
@@ -411,8 +422,7 @@ void ShaderCacheOpenGL::LoadDiskCache(const std::atomic_bool& stop_loading,
}
if (!shader) {
shader = SpecializeShader(unspecialized.code, unspecialized.entries,
- unspecialized.program_type, usage.bindings,
- usage.primitive, true);
+ unspecialized.program_type, usage.variant, true);
}
std::scoped_lock lock(mutex);