diff options
Diffstat (limited to '')
-rw-r--r-- | src/core/hle/service/audio/audren_u.cpp | 2 | ||||
-rw-r--r-- | src/video_core/debug_utils/debug_utils.h | 6 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 36 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 5 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 4 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_resource_manager.h | 2 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 23 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_state.cpp | 79 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_state.h | 43 | ||||
-rw-r--r-- | src/yuzu/main.cpp | 2 |
10 files changed, 72 insertions, 130 deletions
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp index 2188b5625..3dfb3fb52 100644 --- a/src/core/hle/service/audio/audren_u.cpp +++ b/src/core/hle/service/audio/audren_u.cpp @@ -150,7 +150,7 @@ private: UpdateDataHeader() {} UpdateDataHeader(const AudioRendererParameter& config) { - revision = config.revision; + revision = Common::MakeMagic('R', 'E', 'V', '4'); // 5.1.0 Revision behavior_size = 0xb0; memory_pools_size = (config.effect_count + (config.voice_count * 4)) * 0x10; voices_size = config.voice_count * 0x10; diff --git a/src/video_core/debug_utils/debug_utils.h b/src/video_core/debug_utils/debug_utils.h index bbba8e380..9382a75e5 100644 --- a/src/video_core/debug_utils/debug_utils.h +++ b/src/video_core/debug_utils/debug_utils.h @@ -55,8 +55,10 @@ public: virtual ~BreakPointObserver() { auto context = context_weak.lock(); if (context) { - std::unique_lock<std::mutex> lock(context->breakpoint_mutex); - context->breakpoint_observers.remove(this); + { + std::unique_lock<std::mutex> lock(context->breakpoint_mutex); + context->breakpoint_observers.remove(this); + } // If we are the last observer to be destroyed, tell the debugger context that // it is free to continue. In particular, this is required for a proper yuzu diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 3ba20f978..3fbf8e1f9 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -197,8 +197,8 @@ void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset) { ASSERT_MSG(!gpu.regs.shader_config[0].enable, "VertexA is unsupported!"); // Next available bindpoints to use when uploading the const buffers and textures to the GLSL - // shaders. - u32 current_constbuffer_bindpoint = 0; + // shaders. The constbuffer bindpoint starts after the shader stage configuration bind points. + u32 current_constbuffer_bindpoint = uniform_buffers.size(); u32 current_texture_bindpoint = 0; for (unsigned index = 1; index < Maxwell::MaxShaderProgram; ++index) { @@ -437,7 +437,7 @@ void RasterizerOpenGL::DrawArrays() { // Unbind textures for potential future use as framebuffer attachments for (auto& texture_unit : state.texture_units) { - texture_unit.texture_2d = 0; + texture_unit.Unbind(); } state.Apply(); @@ -608,27 +608,39 @@ u32 RasterizerOpenGL::SetupConstBuffers(Maxwell::ShaderStage stage, GLuint progr boost::optional<VAddr> addr = gpu.memory_manager->GpuToCpuAddress(buffer.address); - std::vector<u8> data; + size_t size = 0; + if (used_buffer.IsIndirect()) { // Buffer is accessed indirectly, so upload the entire thing - data.resize(buffer.size * sizeof(float)); + size = buffer.size * sizeof(float); + + if (size > MaxConstbufferSize) { + NGLOG_ERROR(HW_GPU, "indirect constbuffer size {} exceeds maximum {}", size, + MaxConstbufferSize); + size = MaxConstbufferSize; + } } else { // Buffer is accessed directly, upload just what we use - data.resize(used_buffer.GetSize() * sizeof(float)); + size = used_buffer.GetSize() * sizeof(float); } + // Align the actual size so it ends up being a multiple of vec4 to meet the OpenGL std140 + // UBO alignment requirements. + size = Common::AlignUp(size, sizeof(GLvec4)); + ASSERT_MSG(size <= MaxConstbufferSize, "Constbuffer too big"); + + std::vector<u8> data(size); Memory::ReadBlock(*addr, data.data(), data.size()); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer_draw_state.ssbo); - glBufferData(GL_SHADER_STORAGE_BUFFER, data.size(), data.data(), GL_DYNAMIC_DRAW); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); + glBindBuffer(GL_UNIFORM_BUFFER, buffer_draw_state.ssbo); + glBufferData(GL_UNIFORM_BUFFER, data.size(), data.data(), GL_DYNAMIC_DRAW); + glBindBuffer(GL_UNIFORM_BUFFER, 0); // Now configure the bindpoint of the buffer inside the shader std::string buffer_name = used_buffer.GetName(); - GLuint index = - glGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, buffer_name.c_str()); + GLuint index = glGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, buffer_name.c_str()); if (index != -1) - glShaderStorageBlockBinding(program, index, buffer_draw_state.bindpoint); + glUniformBlockBinding(program, index, buffer_draw_state.bindpoint); } state.Apply(); diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index b7c8cf843..4762983c9 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -54,6 +54,11 @@ public: OGLShader shader; }; + /// Maximum supported size that a constbuffer can have in bytes. + static constexpr size_t MaxConstbufferSize = 0x10000; + static_assert(MaxConstbufferSize % sizeof(GLvec4) == 0, + "The maximum size of a constbuffer must be a multiple of the size of GLvec4"); + private: class SamplerInfo { public: diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 61d670dcb..857164ff6 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -46,7 +46,7 @@ struct FormatTuple { static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_format_tuples = {{ {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, false}, // ABGR8 - {GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, false}, // B5G6R5 + {GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV, false}, // B5G6R5 {GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, false}, // A2B10G10R10 {GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, false}, // A1B5G5R5 {GL_R8, GL_RED, GL_UNSIGNED_BYTE, false}, // R8 @@ -645,7 +645,7 @@ void CachedSurface::DownloadGLTexture(const MathUtil::Rectangle<u32>& rect, GLui glActiveTexture(GL_TEXTURE0); glGetTexImage(GL_TEXTURE_2D, 0, tuple.format, tuple.type, &gl_buffer[buffer_offset]); } else { - state.ResetTexture(texture.handle); + state.UnbindTexture(texture.handle); state.draw.read_framebuffer = read_fb_handle; state.Apply(); diff --git a/src/video_core/renderer_opengl/gl_resource_manager.h b/src/video_core/renderer_opengl/gl_resource_manager.h index 93f9172e7..0fed93ca5 100644 --- a/src/video_core/renderer_opengl/gl_resource_manager.h +++ b/src/video_core/renderer_opengl/gl_resource_manager.h @@ -38,7 +38,7 @@ public: if (handle == 0) return; glDeleteTextures(1, &handle); - OpenGLState::GetCurState().ResetTexture(handle).Apply(); + OpenGLState::GetCurState().UnbindTexture(handle).Apply(); handle = 0; } diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 65fed77ef..46eaad021 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -9,6 +9,7 @@ #include "common/assert.h" #include "common/common_types.h" #include "video_core/engines/shader_bytecode.h" +#include "video_core/renderer_opengl/gl_rasterizer.h" #include "video_core/renderer_opengl/gl_shader_decompiler.h" namespace GLShader { @@ -397,7 +398,8 @@ public: /// Generates code representing a uniform (C buffer) register, interpreted as the input type. std::string GetUniform(u64 index, u64 offset, GLSLRegister::Type type) { declr_const_buffers[index].MarkAsUsed(index, offset, stage); - std::string value = 'c' + std::to_string(index) + '[' + std::to_string(offset) + ']'; + std::string value = 'c' + std::to_string(index) + '[' + std::to_string(offset / 4) + "][" + + std::to_string(offset % 4) + ']'; if (type == GLSLRegister::Type::Float) { return value; @@ -411,8 +413,12 @@ public: std::string GetUniformIndirect(u64 index, s64 offset, const Register& index_reg, GLSLRegister::Type type) { declr_const_buffers[index].MarkAsUsedIndirect(index, stage); - std::string value = 'c' + std::to_string(index) + "[(floatBitsToInt(" + - GetRegister(index_reg, 0) + ") + " + std::to_string(offset) + ") / 4]"; + + std::string final_offset = "((floatBitsToInt(" + GetRegister(index_reg, 0) + ") + " + + std::to_string(offset) + ") / 4)"; + + std::string value = + 'c' + std::to_string(index) + '[' + final_offset + " / 4][" + final_offset + " % 4]"; if (type == GLSLRegister::Type::Float) { return value; @@ -454,9 +460,10 @@ public: unsigned const_buffer_layout = 0; for (const auto& entry : GetConstBuffersDeclarations()) { - declarations.AddLine("layout(std430) buffer " + entry.GetName()); + declarations.AddLine("layout(std140) uniform " + entry.GetName()); declarations.AddLine('{'); - declarations.AddLine(" float c" + std::to_string(entry.GetIndex()) + "[];"); + declarations.AddLine(" vec4 c" + std::to_string(entry.GetIndex()) + + "[MAX_CONSTBUFFER_ELEMENTS];"); declarations.AddLine("};"); declarations.AddNewLine(); ++const_buffer_layout; @@ -804,6 +811,7 @@ private: if (!opcode) { NGLOG_CRITICAL(HW_GPU, "Unhandled instruction: {0:x}", instr.value); UNREACHABLE(); + return offset + 1; } shader.AddLine("// " + std::to_string(offset) + ": " + opcode->GetName()); @@ -1713,7 +1721,10 @@ private: }; // namespace Decompiler std::string GetCommonDeclarations() { - return "bool exec_shader();"; + std::string declarations = "bool exec_shader();\n"; + declarations += "#define MAX_CONSTBUFFER_ELEMENTS " + + std::to_string(RasterizerOpenGL::MaxConstbufferSize / (sizeof(GLvec4))); + return declarations; } boost::optional<ProgramResult> DecompileProgram(const ProgramCode& program_code, u32 main_offset, diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp index 1f1e48425..2e8a422a8 100644 --- a/src/video_core/renderer_opengl/gl_state.cpp +++ b/src/video_core/renderer_opengl/gl_state.cpp @@ -48,24 +48,9 @@ OpenGLState::OpenGLState() { logic_op = GL_COPY; for (auto& texture_unit : texture_units) { - texture_unit.texture_2d = 0; - texture_unit.sampler = 0; - texture_unit.swizzle.r = GL_RED; - texture_unit.swizzle.g = GL_GREEN; - texture_unit.swizzle.b = GL_BLUE; - texture_unit.swizzle.a = GL_ALPHA; + texture_unit.Reset(); } - lighting_lut.texture_buffer = 0; - - fog_lut.texture_buffer = 0; - - proctex_lut.texture_buffer = 0; - proctex_diff_lut.texture_buffer = 0; - proctex_color_map.texture_buffer = 0; - proctex_alpha_map.texture_buffer = 0; - proctex_noise_lut.texture_buffer = 0; - draw.read_framebuffer = 0; draw.draw_framebuffer = 0; draw.vertex_array = 0; @@ -223,54 +208,12 @@ void OpenGLState::Apply() const { if (current.enabled != new_state.enabled || current.bindpoint != new_state.bindpoint || current.ssbo != new_state.ssbo) { if (new_state.enabled) { - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, new_state.bindpoint, new_state.ssbo); + glBindBufferBase(GL_UNIFORM_BUFFER, new_state.bindpoint, new_state.ssbo); } } } } - // Lighting LUTs - if (lighting_lut.texture_buffer != cur_state.lighting_lut.texture_buffer) { - glActiveTexture(TextureUnits::LightingLUT.Enum()); - glBindTexture(GL_TEXTURE_BUFFER, lighting_lut.texture_buffer); - } - - // Fog LUT - if (fog_lut.texture_buffer != cur_state.fog_lut.texture_buffer) { - glActiveTexture(TextureUnits::FogLUT.Enum()); - glBindTexture(GL_TEXTURE_BUFFER, fog_lut.texture_buffer); - } - - // ProcTex Noise LUT - if (proctex_noise_lut.texture_buffer != cur_state.proctex_noise_lut.texture_buffer) { - glActiveTexture(TextureUnits::ProcTexNoiseLUT.Enum()); - glBindTexture(GL_TEXTURE_BUFFER, proctex_noise_lut.texture_buffer); - } - - // ProcTex Color Map - if (proctex_color_map.texture_buffer != cur_state.proctex_color_map.texture_buffer) { - glActiveTexture(TextureUnits::ProcTexColorMap.Enum()); - glBindTexture(GL_TEXTURE_BUFFER, proctex_color_map.texture_buffer); - } - - // ProcTex Alpha Map - if (proctex_alpha_map.texture_buffer != cur_state.proctex_alpha_map.texture_buffer) { - glActiveTexture(TextureUnits::ProcTexAlphaMap.Enum()); - glBindTexture(GL_TEXTURE_BUFFER, proctex_alpha_map.texture_buffer); - } - - // ProcTex LUT - if (proctex_lut.texture_buffer != cur_state.proctex_lut.texture_buffer) { - glActiveTexture(TextureUnits::ProcTexLUT.Enum()); - glBindTexture(GL_TEXTURE_BUFFER, proctex_lut.texture_buffer); - } - - // ProcTex Diff LUT - if (proctex_diff_lut.texture_buffer != cur_state.proctex_diff_lut.texture_buffer) { - glActiveTexture(TextureUnits::ProcTexDiffLUT.Enum()); - glBindTexture(GL_TEXTURE_BUFFER, proctex_diff_lut.texture_buffer); - } - // Framebuffer if (draw.read_framebuffer != cur_state.draw.read_framebuffer) { glBindFramebuffer(GL_READ_FRAMEBUFFER, draw.read_framebuffer); @@ -338,26 +281,12 @@ void OpenGLState::Apply() const { cur_state = *this; } -OpenGLState& OpenGLState::ResetTexture(GLuint handle) { +OpenGLState& OpenGLState::UnbindTexture(GLuint handle) { for (auto& unit : texture_units) { if (unit.texture_2d == handle) { - unit.texture_2d = 0; + unit.Unbind(); } } - if (lighting_lut.texture_buffer == handle) - lighting_lut.texture_buffer = 0; - if (fog_lut.texture_buffer == handle) - fog_lut.texture_buffer = 0; - if (proctex_noise_lut.texture_buffer == handle) - proctex_noise_lut.texture_buffer = 0; - if (proctex_color_map.texture_buffer == handle) - proctex_color_map.texture_buffer = 0; - if (proctex_alpha_map.texture_buffer == handle) - proctex_alpha_map.texture_buffer = 0; - if (proctex_lut.texture_buffer == handle) - proctex_lut.texture_buffer = 0; - if (proctex_diff_lut.texture_buffer == handle) - proctex_diff_lut.texture_buffer = 0; return *this; } diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h index 839e50e93..3398d7c04 100644 --- a/src/video_core/renderer_opengl/gl_state.h +++ b/src/video_core/renderer_opengl/gl_state.h @@ -91,35 +91,20 @@ public: GLint b; // GL_TEXTURE_SWIZZLE_B GLint a; // GL_TEXTURE_SWIZZLE_A } swizzle; - } texture_units[32]; - - struct { - GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER - } lighting_lut; - - struct { - GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER - } fog_lut; - - struct { - GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER - } proctex_noise_lut; - struct { - GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER - } proctex_color_map; - - struct { - GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER - } proctex_alpha_map; - - struct { - GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER - } proctex_lut; - - struct { - GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER - } proctex_diff_lut; + void Unbind() { + texture_2d = 0; + swizzle.r = GL_RED; + swizzle.g = GL_GREEN; + swizzle.b = GL_BLUE; + swizzle.a = GL_ALPHA; + } + + void Reset() { + Unbind(); + sampler = 0; + } + } texture_units[32]; struct { GLuint read_framebuffer; // GL_READ_FRAMEBUFFER_BINDING @@ -165,7 +150,7 @@ public: void Apply() const; /// Resets any references to the given resource - OpenGLState& ResetTexture(GLuint handle); + OpenGLState& UnbindTexture(GLuint handle); OpenGLState& ResetSampler(GLuint handle); OpenGLState& ResetProgram(GLuint handle); OpenGLState& ResetPipeline(GLuint handle); diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 97be548d7..00a3e9632 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -334,8 +334,6 @@ bool GMainWindow::SupportsRequiredGLExtensions() { unsupported_ext.append("ARB_program_interface_query"); if (!GLAD_GL_ARB_separate_shader_objects) unsupported_ext.append("ARB_separate_shader_objects"); - if (!GLAD_GL_ARB_shader_storage_buffer_object) - unsupported_ext.append("ARB_shader_storage_buffer_object"); if (!GLAD_GL_ARB_vertex_attrib_binding) unsupported_ext.append("ARB_vertex_attrib_binding"); |