summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_opengl/gl_device.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/renderer_opengl/gl_device.cpp')
-rw-r--r--src/video_core/renderer_opengl/gl_device.cpp42
1 files changed, 42 insertions, 0 deletions
diff --git a/src/video_core/renderer_opengl/gl_device.cpp b/src/video_core/renderer_opengl/gl_device.cpp
index b30d5be74..5cfa97fc2 100644
--- a/src/video_core/renderer_opengl/gl_device.cpp
+++ b/src/video_core/renderer_opengl/gl_device.cpp
@@ -17,6 +17,9 @@ namespace OpenGL {
namespace {
+// One uniform block is reserved for emulation purposes
+constexpr u32 ReservedUniformBlocks = 1;
+
template <typename T>
T GetInteger(GLenum pname) {
GLint temporary;
@@ -48,6 +51,22 @@ bool HasExtension(const std::vector<std::string_view>& images, std::string_view
return std::find(images.begin(), images.end(), extension) != images.end();
}
+constexpr Device::BaseBindings operator+(Device::BaseBindings lhs, Device::BaseBindings rhs) {
+ return Device::BaseBindings{lhs.uniform_buffer + rhs.uniform_buffer,
+ lhs.shader_storage_buffer + rhs.shader_storage_buffer,
+ lhs.sampler + rhs.sampler, lhs.image + rhs.image};
+}
+
+Device::BaseBindings BuildBaseBindings(GLenum uniform_blocks, GLenum shader_storage_blocks,
+ GLenum texture_image_units, GLenum image_uniforms) noexcept {
+ return Device::BaseBindings{
+ GetInteger<u32>(uniform_blocks) - ReservedUniformBlocks,
+ GetInteger<u32>(shader_storage_blocks),
+ GetInteger<u32>(texture_image_units),
+ GetInteger<u32>(image_uniforms),
+ };
+}
+
} // Anonymous namespace
Device::Device() {
@@ -56,6 +75,29 @@ Device::Device() {
const bool is_nvidia = vendor == "NVIDIA Corporation";
+ // Reserve the first UBO for emulation bindings
+ base_bindings[0] = BaseBindings{ReservedUniformBlocks, 0, 0, 0};
+ base_bindings[1] = base_bindings[0] + BuildBaseBindings(GL_MAX_VERTEX_UNIFORM_BLOCKS,
+ GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS,
+ GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS,
+ GL_MAX_VERTEX_IMAGE_UNIFORMS);
+ base_bindings[2] =
+ base_bindings[1] + BuildBaseBindings(GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS,
+ GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS,
+ GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS,
+ GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS);
+ base_bindings[3] =
+ base_bindings[2] + BuildBaseBindings(GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS,
+ GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS,
+ GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS,
+ GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS);
+ base_bindings[4] = base_bindings[3] + BuildBaseBindings(GL_MAX_GEOMETRY_UNIFORM_BLOCKS,
+ GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS,
+ GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS,
+ GL_MAX_GEOMETRY_IMAGE_UNIFORMS);
+ // Compute doesn't need any of that
+ base_bindings[5] = BaseBindings{0, 0, 0, 0};
+
uniform_buffer_alignment = GetInteger<std::size_t>(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT);
shader_storage_alignment = GetInteger<std::size_t>(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT);
max_vertex_attributes = GetInteger<u32>(GL_MAX_VERTEX_ATTRIBS);