diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 26e66640b..80626a939 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -37,7 +37,8 @@ MICROPROFILE_DEFINE(OpenGL_CacheManagement, "OpenGL", "Cache Mgmt", MP_RGB(100, RasterizerOpenGL::RasterizerOpenGL() : shader_dirty(true), vertex_buffer(GL_ARRAY_BUFFER, VERTEX_BUFFER_SIZE), uniform_buffer(GL_UNIFORM_BUFFER, UNIFORM_BUFFER_SIZE), - index_buffer(GL_ELEMENT_ARRAY_BUFFER, INDEX_BUFFER_SIZE) { + index_buffer(GL_ELEMENT_ARRAY_BUFFER, INDEX_BUFFER_SIZE), + texture_buffer(GL_TEXTURE_BUFFER, TEXTURE_BUFFER_SIZE) { allow_shadow = GLAD_GL_ARB_shader_image_load_store && GLAD_GL_ARB_shader_image_size && GLAD_GL_ARB_framebuffer_no_attachments; @@ -125,6 +126,17 @@ RasterizerOpenGL::RasterizerOpenGL() // Create render framebuffer framebuffer.Create(); + // Allocate and bind texture buffer lut textures + texture_buffer_lut_rg.Create(); + texture_buffer_lut_rgba.Create(); + state.texture_buffer_lut_rg.texture_buffer = texture_buffer_lut_rg.handle; + state.texture_buffer_lut_rgba.texture_buffer = texture_buffer_lut_rgba.handle; + state.Apply(); + glActiveTexture(TextureUnits::TextureBufferLUT_RG.Enum()); + glTexBuffer(GL_TEXTURE_BUFFER, GL_RG32F, texture_buffer.GetHandle()); + glActiveTexture(TextureUnits::TextureBufferLUT_RGBA.Enum()); + glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, texture_buffer.GetHandle()); + // Allocate and bind lighting lut textures lighting_lut.Create(); state.lighting_lut.texture_buffer = lighting_lut.handle; @@ -1931,6 +1943,12 @@ void RasterizerOpenGL::SyncShadowBias() { } void RasterizerOpenGL::SyncAndUploadLUTs() { + constexpr size_t max_size = sizeof(GLvec2) * 256 * Pica::LightingRegs::NumLightingSampler + + sizeof(GLvec2) * 128 + // fog + sizeof(GLvec2) * 128 * 3 + // proctex: noise + color + alpha + sizeof(GLvec4) * 256 + // proctex + sizeof(GLvec4) * 256; // proctex diff + // Sync the lighting luts for (unsigned index = 0; index < uniform_block_data.lut_dirty.size(); index++) { if (uniform_block_data.lut_dirty[index]) { diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 08816cc69..dd1fdae7f 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -266,6 +266,7 @@ private: static constexpr size_t VERTEX_BUFFER_SIZE = 32 * 1024 * 1024; static constexpr size_t INDEX_BUFFER_SIZE = 1 * 1024 * 1024; static constexpr size_t UNIFORM_BUFFER_SIZE = 2 * 1024 * 1024; + static constexpr size_t TEXTURE_BUFFER_SIZE = 1 * 1024 * 1024; OGLVertexArray sw_vao; // VAO for software shader draw OGLVertexArray hw_vao; // VAO for hardware shader / accelerate draw @@ -275,6 +276,7 @@ private: OGLStreamBuffer vertex_buffer; OGLStreamBuffer uniform_buffer; OGLStreamBuffer index_buffer; + OGLStreamBuffer texture_buffer; OGLFramebuffer framebuffer; GLint uniform_buffer_alignment; size_t uniform_size_aligned_vs; @@ -283,6 +285,9 @@ private: SamplerInfo texture_cube_sampler; + OGLTexture texture_buffer_lut_rg; + OGLTexture texture_buffer_lut_rgba; + OGLBuffer lighting_lut_buffer; OGLTexture lighting_lut; std::array, Pica::LightingRegs::NumLightingSampler> lighting_lut_data{}; diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp index 6a8f1df44..0d3a955a4 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.cpp +++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp @@ -1222,6 +1222,8 @@ uniform sampler2D tex0; uniform sampler2D tex1; uniform sampler2D tex2; uniform samplerCube tex_cube; +uniform samplerBuffer texture_buffer_lut_rg; +uniform samplerBuffer texture_buffer_lut_rgba; uniform samplerBuffer lighting_lut; uniform samplerBuffer fog_lut; uniform samplerBuffer proctex_noise_lut; diff --git a/src/video_core/renderer_opengl/gl_shader_manager.cpp b/src/video_core/renderer_opengl/gl_shader_manager.cpp index e70b5d87a..66b2db9ed 100644 --- a/src/video_core/renderer_opengl/gl_shader_manager.cpp +++ b/src/video_core/renderer_opengl/gl_shader_manager.cpp @@ -55,6 +55,8 @@ static void SetShaderSamplerBindings(GLuint shader) { SetShaderSamplerBinding(shader, "tex_cube", TextureUnits::TextureCube); // Set the texture samplers to correspond to different lookup table texture units + SetShaderSamplerBinding(shader, "texture_buffer_lut_rg", TextureUnits::TextureBufferLUT_RG); + SetShaderSamplerBinding(shader, "texture_buffer_lut_rgba", TextureUnits::TextureBufferLUT_RGBA); SetShaderSamplerBinding(shader, "lighting_lut", TextureUnits::LightingLUT); SetShaderSamplerBinding(shader, "fog_lut", TextureUnits::FogLUT); SetShaderSamplerBinding(shader, "proctex_noise_lut", TextureUnits::ProcTexNoiseLUT); diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp index 95dbd591b..217cdb316 100644 --- a/src/video_core/renderer_opengl/gl_state.cpp +++ b/src/video_core/renderer_opengl/gl_state.cpp @@ -55,6 +55,9 @@ OpenGLState::OpenGLState() { texture_cube_unit.texture_cube = 0; texture_cube_unit.sampler = 0; + texture_buffer_lut_rg.texture_buffer = 0; + texture_buffer_lut_rgba.texture_buffer = 0; + lighting_lut.texture_buffer = 0; fog_lut.texture_buffer = 0; @@ -221,6 +224,19 @@ void OpenGLState::Apply() const { glBindSampler(TextureUnits::TextureCube.id, texture_cube_unit.sampler); } + // Texture buffer LUTs + if (texture_buffer_lut_rg.texture_buffer != cur_state.texture_buffer_lut_rg.texture_buffer) { + glActiveTexture(TextureUnits::TextureBufferLUT_RG.Enum()); + glBindTexture(GL_TEXTURE_BUFFER, texture_buffer_lut_rg.texture_buffer); + } + + // Texture buffer LUTs + if (texture_buffer_lut_rgba.texture_buffer != + cur_state.texture_buffer_lut_rgba.texture_buffer) { + glActiveTexture(TextureUnits::TextureBufferLUT_RGBA.Enum()); + glBindTexture(GL_TEXTURE_BUFFER, texture_buffer_lut_rgba.texture_buffer); + } + // Lighting LUTs if (lighting_lut.texture_buffer != cur_state.lighting_lut.texture_buffer) { glActiveTexture(TextureUnits::LightingLUT.Enum()); @@ -374,6 +390,10 @@ OpenGLState& OpenGLState::ResetTexture(GLuint handle) { } if (texture_cube_unit.texture_cube == handle) texture_cube_unit.texture_cube = 0; + if (texture_buffer_lut_rg.texture_buffer == handle) + texture_buffer_lut_rg.texture_buffer = 0; + if (texture_buffer_lut_rgba.texture_buffer == handle) + texture_buffer_lut_rgba.texture_buffer = 0; if (lighting_lut.texture_buffer == handle) lighting_lut.texture_buffer = 0; if (fog_lut.texture_buffer == handle) diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h index ebc217349..64ded0b80 100644 --- a/src/video_core/renderer_opengl/gl_state.h +++ b/src/video_core/renderer_opengl/gl_state.h @@ -28,6 +28,8 @@ constexpr TextureUnit ProcTexAlphaMap{7}; constexpr TextureUnit ProcTexLUT{8}; constexpr TextureUnit ProcTexDiffLUT{9}; constexpr TextureUnit TextureCube{10}; +constexpr TextureUnit TextureBufferLUT_RG{11}; +constexpr TextureUnit TextureBufferLUT_RGBA{12}; } // namespace TextureUnits @@ -103,6 +105,14 @@ public: GLuint sampler; // GL_SAMPLER_BINDING } texture_cube_unit; + struct { + GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER + } texture_buffer_lut_rg; + + struct { + GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER + } texture_buffer_lut_rgba; + struct { GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER } lighting_lut;