From e4f9ce0379aed68efa73669b836b1d5818883419 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Fri, 6 Mar 2020 05:08:16 -0300 Subject: [PATCH 1/8] vk_rasterizer: Support disabled uniform buffers --- src/video_core/renderer_vulkan/vk_rasterizer.cpp | 7 +++++++ src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 3fe28c2042..9d7f5831be 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -909,6 +909,13 @@ void RasterizerVulkan::SetupComputeImages(const ShaderEntries& entries) { void RasterizerVulkan::SetupConstBuffer(const ConstBufferEntry& entry, const Tegra::Engines::ConstBufferInfo& buffer) { + if (!buffer.enabled) { + // Set values to zero to unbind buffers + update_descriptor_queue.AddBuffer(buffer_cache.GetEmptyBuffer(sizeof(float)), 0, + sizeof(float)); + return; + } + // Align the size to avoid bad std140 interactions const std::size_t size = Common::AlignUp(CalculateConstBufferSize(entry, buffer), 4 * sizeof(float)); diff --git a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp index 171d78afcf..d9ea3cc21e 100644 --- a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp +++ b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp @@ -73,7 +73,8 @@ VKBuffer* VKStagingBufferPool::TryGetReservedBuffer(std::size_t size, bool host_ VKBuffer& VKStagingBufferPool::CreateStagingBuffer(std::size_t size, bool host_visible) { const auto usage = vk::BufferUsageFlagBits::eTransferSrc | vk::BufferUsageFlagBits::eTransferDst | - vk::BufferUsageFlagBits::eStorageBuffer | vk::BufferUsageFlagBits::eIndexBuffer; + vk::BufferUsageFlagBits::eUniformBuffer | vk::BufferUsageFlagBits::eStorageBuffer | + vk::BufferUsageFlagBits::eIndexBuffer; const u32 log2 = Common::Log2Ceil64(size); const vk::BufferCreateInfo buffer_ci({}, 1ULL << log2, usage, vk::SharingMode::eExclusive, 0, nullptr); From 16cfbb068c786eda21f7a1d307da5cc702eb6db9 Mon Sep 17 00:00:00 2001 From: Nguyen Dac Nam Date: Sun, 8 Mar 2020 10:06:59 +0700 Subject: [PATCH 2/8] vk_reasterizer: fix mistype on SetupGraphicsImages This should use Maxwell3D engine. Fixed some GPU error on Kirby and maybe other games. --- src/video_core/renderer_vulkan/vk_rasterizer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 3fe28c2042..3d9fd0e6c0 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -848,7 +848,7 @@ void RasterizerVulkan::SetupGraphicsTextures(const ShaderEntries& entries, std:: void RasterizerVulkan::SetupGraphicsImages(const ShaderEntries& entries, std::size_t stage) { MICROPROFILE_SCOPE(Vulkan_Images); - const auto& gpu = system.GPU().KeplerCompute(); + const auto& gpu = system.GPU().Maxwell3D(); for (const auto& entry : entries.images) { const auto tic = GetTextureInfo(gpu, entry, stage).tic; SetupImage(tic, entry); From 59d0d34dce3fa3be6374f6a2740d69c1f622547a Mon Sep 17 00:00:00 2001 From: FearlessTobi Date: Mon, 24 Feb 2020 18:34:00 +0100 Subject: [PATCH 3/8] cubeb_sink: Don't discard other channels when performing downmixing Previously, when performing downmixing, we would discard all channels except the left and right one. This implementation respects them when mixing down to Stereo. It is taken from this document: http://www.atsc.org/wp-content/uploads/2015/03/A52-201212-17.pdf. Fixes Luigis Mansion 3 cutscene and Bayonetta audio. --- src/audio_core/cubeb_sink.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/audio_core/cubeb_sink.cpp b/src/audio_core/cubeb_sink.cpp index 7047ed9cf6..c4e0e30fed 100644 --- a/src/audio_core/cubeb_sink.cpp +++ b/src/audio_core/cubeb_sink.cpp @@ -8,6 +8,7 @@ #include "audio_core/cubeb_sink.h" #include "audio_core/stream.h" #include "audio_core/time_stretch.h" +#include "common/assert.h" #include "common/logging/log.h" #include "common/ring_buffer.h" #include "core/settings.h" @@ -65,12 +66,25 @@ public: void EnqueueSamples(u32 source_num_channels, const std::vector& samples) override { if (source_num_channels > num_channels) { // Downsample 6 channels to 2 + ASSERT_MSG(source_num_channels == 6, "Channel count must be 6"); + std::vector buf; buf.reserve(samples.size() * num_channels / source_num_channels); for (std::size_t i = 0; i < samples.size(); i += source_num_channels) { - for (std::size_t ch = 0; ch < num_channels; ch++) { - buf.push_back(samples[i + ch]); - } + // Downmixing implementation taken from the ATSC standard + const s16 left{samples[i + 0]}; + const s16 right{samples[i + 1]}; + const s16 center{samples[i + 2]}; + const s16 surround_left{samples[i + 4]}; + const s16 surround_right{samples[i + 5]}; + // Not used in the ATSC reference implementation + [[maybe_unused]] const s16 low_frequency_effects { samples[i + 3] }; + + constexpr s32 clev{707}; // center mixing level coefficient + constexpr s32 slev{707}; // surround mixing level coefficient + + buf.push_back(left + (clev * center / 1000) + (slev * surround_left / 1000)); + buf.push_back(right + (clev * center / 1000) + (slev * surround_right / 1000)); } queue.Push(buf); return; From e4bc3c33426d6e0968d64ddb84a41966b3c37f19 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Mon, 24 Feb 2020 19:43:57 -0300 Subject: [PATCH 4/8] gl_rasterizer: Implement polygon modes and fill rectangles --- src/video_core/engines/maxwell_3d.h | 22 +++++++++- .../renderer_opengl/gl_rasterizer.cpp | 40 +++++++++++++++++++ .../renderer_opengl/gl_rasterizer.h | 3 ++ .../renderer_opengl/gl_state_tracker.cpp | 10 +++++ .../renderer_opengl/gl_state_tracker.h | 11 +++++ .../renderer_opengl/maxwell_to_gl.h | 13 ++++++ .../renderer_opengl/renderer_opengl.cpp | 2 + 7 files changed, 99 insertions(+), 2 deletions(-) diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 491cff3707..ed7fc8fdd9 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -524,6 +524,12 @@ public: FractionalEven = 2, }; + enum class PolygonMode : u32 { + Point = 0x1b00, + Line = 0x1b01, + Fill = 0x1b02, + }; + struct RenderTargetConfig { u32 address_high; u32 address_low; @@ -705,7 +711,12 @@ public: s32 clear_stencil; - INSERT_UNION_PADDING_WORDS(0x7); + INSERT_UNION_PADDING_WORDS(0x2); + + PolygonMode polygon_mode_front; + PolygonMode polygon_mode_back; + + INSERT_UNION_PADDING_WORDS(0x3); u32 polygon_offset_point_enable; u32 polygon_offset_line_enable; @@ -764,7 +775,11 @@ public: BitField<12, 4, u32> viewport; } clear_flags; - INSERT_UNION_PADDING_WORDS(0x19); + INSERT_UNION_PADDING_WORDS(0x10); + + u32 fill_rectangle; + + INSERT_UNION_PADDING_WORDS(0x8); std::array vertex_attrib_format; @@ -1422,6 +1437,8 @@ ASSERT_REG_POSITION(depth_mode, 0x35F); ASSERT_REG_POSITION(clear_color[0], 0x360); ASSERT_REG_POSITION(clear_depth, 0x364); ASSERT_REG_POSITION(clear_stencil, 0x368); +ASSERT_REG_POSITION(polygon_mode_front, 0x36B); +ASSERT_REG_POSITION(polygon_mode_back, 0x36C); ASSERT_REG_POSITION(polygon_offset_point_enable, 0x370); ASSERT_REG_POSITION(polygon_offset_line_enable, 0x371); ASSERT_REG_POSITION(polygon_offset_fill_enable, 0x372); @@ -1435,6 +1452,7 @@ ASSERT_REG_POSITION(rt_separate_frag_data, 0x3EB); ASSERT_REG_POSITION(depth_bounds, 0x3E7); ASSERT_REG_POSITION(zeta, 0x3F8); ASSERT_REG_POSITION(clear_flags, 0x43E); +ASSERT_REG_POSITION(fill_rectangle, 0x44F); ASSERT_REG_POSITION(vertex_attrib_format, 0x458); ASSERT_REG_POSITION(rt_control, 0x487); ASSERT_REG_POSITION(zeta_width, 0x48a); diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 55324e6d5a..90124e1149 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -487,6 +487,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) { SyncViewport(); SyncRasterizeEnable(); + SyncPolygonModes(); SyncColorMask(); SyncFragmentColorClampState(); SyncMultiSampleState(); @@ -1097,6 +1098,45 @@ void RasterizerOpenGL::SyncRasterizeEnable() { oglEnable(GL_RASTERIZER_DISCARD, gpu.regs.rasterize_enable == 0); } +void RasterizerOpenGL::SyncPolygonModes() { + auto& gpu = system.GPU().Maxwell3D(); + auto& flags = gpu.dirty.flags; + if (!flags[Dirty::PolygonModes]) { + return; + } + flags[Dirty::PolygonModes] = false; + + if (gpu.regs.fill_rectangle) { + if (!GLAD_GL_NV_fill_rectangle) { + LOG_ERROR(Render_OpenGL, "GL_NV_fill_rectangle used and not supported"); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + return; + } + + flags[Dirty::PolygonModeFront] = true; + flags[Dirty::PolygonModeBack] = true; + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL_RECTANGLE_NV); + return; + } + + if (gpu.regs.polygon_mode_front == gpu.regs.polygon_mode_back) { + flags[Dirty::PolygonModeFront] = false; + flags[Dirty::PolygonModeBack] = false; + glPolygonMode(GL_FRONT_AND_BACK, MaxwellToGL::PolygonMode(gpu.regs.polygon_mode_front)); + return; + } + + if (flags[Dirty::PolygonModeFront]) { + flags[Dirty::PolygonModeFront] = false; + glPolygonMode(GL_FRONT, MaxwellToGL::PolygonMode(gpu.regs.polygon_mode_front)); + } + + if (flags[Dirty::PolygonModeBack]) { + flags[Dirty::PolygonModeBack] = false; + glPolygonMode(GL_BACK, MaxwellToGL::PolygonMode(gpu.regs.polygon_mode_back)); + } +} + void RasterizerOpenGL::SyncColorMask() { auto& gpu = system.GPU().Maxwell3D(); auto& flags = gpu.dirty.flags; diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index b24c6661b4..e5681d6df6 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -178,6 +178,9 @@ private: /// Syncs the rasterizer enable state to match the guest state void SyncRasterizeEnable(); + /// Syncs polygon modes to match the guest state + void SyncPolygonModes(); + /// Syncs Color Mask void SyncColorMask(); diff --git a/src/video_core/renderer_opengl/gl_state_tracker.cpp b/src/video_core/renderer_opengl/gl_state_tracker.cpp index 1e43c9ec00..3f3bdf812c 100644 --- a/src/video_core/renderer_opengl/gl_state_tracker.cpp +++ b/src/video_core/renderer_opengl/gl_state_tracker.cpp @@ -94,6 +94,15 @@ void SetupDirtyShaders(Tables& tables) { Shaders); } +void SetupDirtyPolygonModes(Tables& tables) { + tables[0][OFF(polygon_mode_front)] = PolygonModeFront; + tables[0][OFF(polygon_mode_back)] = PolygonModeBack; + + tables[1][OFF(polygon_mode_front)] = PolygonModes; + tables[1][OFF(polygon_mode_back)] = PolygonModes; + tables[0][OFF(fill_rectangle)] = PolygonModes; +} + void SetupDirtyDepthTest(Tables& tables) { auto& table = tables[0]; table[OFF(depth_test_enable)] = DepthTest; @@ -211,6 +220,7 @@ void StateTracker::Initialize() { SetupDirtyVertexArrays(tables); SetupDirtyVertexFormat(tables); SetupDirtyShaders(tables); + SetupDirtyPolygonModes(tables); SetupDirtyDepthTest(tables); SetupDirtyStencilTest(tables); SetupDirtyAlphaTest(tables); diff --git a/src/video_core/renderer_opengl/gl_state_tracker.h b/src/video_core/renderer_opengl/gl_state_tracker.h index e084829111..b882d75c3a 100644 --- a/src/video_core/renderer_opengl/gl_state_tracker.h +++ b/src/video_core/renderer_opengl/gl_state_tracker.h @@ -59,6 +59,10 @@ enum : u8 { Shaders, ClipDistances, + PolygonModes, + PolygonModeFront, + PolygonModeBack, + ColorMask, FrontFace, CullTest, @@ -111,6 +115,13 @@ public: flags[OpenGL::Dirty::VertexInstance0 + 1] = true; } + void NotifyPolygonModes() { + auto& flags = system.GPU().Maxwell3D().dirty.flags; + flags[OpenGL::Dirty::PolygonModes] = true; + flags[OpenGL::Dirty::PolygonModeFront] = true; + flags[OpenGL::Dirty::PolygonModeBack] = true; + } + void NotifyViewport0() { auto& flags = system.GPU().Maxwell3D().dirty.flags; flags[OpenGL::Dirty::Viewports] = true; diff --git a/src/video_core/renderer_opengl/maxwell_to_gl.h b/src/video_core/renderer_opengl/maxwell_to_gl.h index 494e38e7a0..89f0e04ef5 100644 --- a/src/video_core/renderer_opengl/maxwell_to_gl.h +++ b/src/video_core/renderer_opengl/maxwell_to_gl.h @@ -488,5 +488,18 @@ inline GLenum LogicOp(Maxwell::LogicOperation operation) { return GL_COPY; } +inline GLenum PolygonMode(Maxwell::PolygonMode polygon_mode) { + switch (polygon_mode) { + case Maxwell::PolygonMode::Point: + return GL_POINT; + case Maxwell::PolygonMode::Line: + return GL_LINE; + case Maxwell::PolygonMode::Fill: + return GL_FILL; + } + UNREACHABLE_MSG("Invalid polygon mode={}", static_cast(polygon_mode)); + return GL_FILL; +} + } // namespace MaxwellToGL } // namespace OpenGL diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index a51410660d..d03b29c22e 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -577,6 +577,7 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) { // TODO: Signal state tracker about these changes state_tracker.NotifyScreenDrawVertexArray(); + state_tracker.NotifyPolygonModes(); state_tracker.NotifyViewport0(); state_tracker.NotifyScissor0(); state_tracker.NotifyColorMask0(); @@ -612,6 +613,7 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) { glDisable(GL_ALPHA_TEST); glDisablei(GL_BLEND, 0); glDisablei(GL_SCISSOR_TEST, 0); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glCullFace(GL_BACK); glFrontFace(GL_CW); glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); From 835790809954bb5962f8893320b8f5c3ad82d6a0 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Wed, 11 Mar 2020 01:03:01 -0300 Subject: [PATCH 5/8] gl_shader_manager: Fix interaction between graphics and compute After a compute shader was set to the pipeline, no graphics shader was invoked again. To address this use glUseProgram to bind compute shaders (without state tracking) and call glUseProgram(0) when transitioning out of it back to the graphics pipeline. --- .../renderer_opengl/gl_rasterizer.cpp | 5 ++- .../renderer_opengl/gl_shader_manager.cpp | 31 +++++++++++++------ .../renderer_opengl/gl_shader_manager.h | 29 +++++++++-------- .../renderer_opengl/renderer_opengl.cpp | 3 +- 4 files changed, 39 insertions(+), 29 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 55324e6d5a..4e41385733 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -565,7 +565,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) { bind_ubo_pushbuffer.Bind(); bind_ssbo_pushbuffer.Bind(); - program_manager.Update(); + program_manager.BindGraphicsPipeline(); if (texture_cache.TextureBarrier()) { glTextureBarrier(); @@ -627,8 +627,7 @@ void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) { const ProgramVariant variant(launch_desc.block_dim_x, launch_desc.block_dim_y, launch_desc.block_dim_z, launch_desc.shared_alloc, launch_desc.local_pos_alloc); - glUseProgramStages(program_manager.GetHandle(), GL_COMPUTE_SHADER_BIT, - kernel->GetHandle(variant)); + program_manager.BindComputeShader(kernel->GetHandle(variant)); const std::size_t buffer_size = Tegra::Engines::KeplerCompute::NumConstBuffers * diff --git a/src/video_core/renderer_opengl/gl_shader_manager.cpp b/src/video_core/renderer_opengl/gl_shader_manager.cpp index 15f3cd0669..9c7b0adbd7 100644 --- a/src/video_core/renderer_opengl/gl_shader_manager.cpp +++ b/src/video_core/renderer_opengl/gl_shader_manager.cpp @@ -2,21 +2,29 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include + #include "common/common_types.h" #include "video_core/engines/maxwell_3d.h" #include "video_core/renderer_opengl/gl_shader_manager.h" namespace OpenGL::GLShader { -using Tegra::Engines::Maxwell3D; +ProgramManager::ProgramManager() = default; ProgramManager::~ProgramManager() = default; void ProgramManager::Create() { - pipeline.Create(); + graphics_pipeline.Create(); + glBindProgramPipeline(graphics_pipeline.handle); } -void ProgramManager::Update() { +void ProgramManager::BindGraphicsPipeline() { + if (!is_graphics_bound) { + is_graphics_bound = true; + glUseProgram(0); + } + // Avoid updating the pipeline when values have no changed if (old_state == current_state) { return; @@ -25,16 +33,21 @@ void ProgramManager::Update() { // Workaround for AMD bug static constexpr GLenum all_used_stages{GL_VERTEX_SHADER_BIT | GL_GEOMETRY_SHADER_BIT | GL_FRAGMENT_SHADER_BIT}; - glUseProgramStages(pipeline.handle, all_used_stages, 0); - - glUseProgramStages(pipeline.handle, GL_VERTEX_SHADER_BIT, current_state.vertex_shader); - glUseProgramStages(pipeline.handle, GL_GEOMETRY_SHADER_BIT, current_state.geometry_shader); - glUseProgramStages(pipeline.handle, GL_FRAGMENT_SHADER_BIT, current_state.fragment_shader); + const GLuint handle = graphics_pipeline.handle; + glUseProgramStages(handle, all_used_stages, 0); + glUseProgramStages(handle, GL_VERTEX_SHADER_BIT, current_state.vertex_shader); + glUseProgramStages(handle, GL_GEOMETRY_SHADER_BIT, current_state.geometry_shader); + glUseProgramStages(handle, GL_FRAGMENT_SHADER_BIT, current_state.fragment_shader); old_state = current_state; } -void MaxwellUniformData::SetFromRegs(const Maxwell3D& maxwell) { +void ProgramManager::BindComputeShader(GLuint program) { + is_graphics_bound = false; + glUseProgram(program); +} + +void MaxwellUniformData::SetFromRegs(const Tegra::Engines::Maxwell3D& maxwell) { const auto& regs = maxwell.regs; // Y_NEGATE controls what value S2R returns for the Y_DIRECTION system value. diff --git a/src/video_core/renderer_opengl/gl_shader_manager.h b/src/video_core/renderer_opengl/gl_shader_manager.h index e94cd75aa0..d2e47f2a90 100644 --- a/src/video_core/renderer_opengl/gl_shader_manager.h +++ b/src/video_core/renderer_opengl/gl_shader_manager.h @@ -28,11 +28,16 @@ static_assert(sizeof(MaxwellUniformData) < 16384, class ProgramManager { public: + explicit ProgramManager(); ~ProgramManager(); void Create(); - void Update(); + /// Updates the graphics pipeline and binds it. + void BindGraphicsPipeline(); + + /// Binds a compute shader. + void BindComputeShader(GLuint program); void UseVertexShader(GLuint program) { current_state.vertex_shader = program; @@ -46,33 +51,27 @@ public: current_state.fragment_shader = program; } - GLuint GetHandle() const { - return pipeline.handle; - } - - void UseTrivialFragmentShader() { - current_state.fragment_shader = 0; - } - private: struct PipelineState { - bool operator==(const PipelineState& rhs) const { + bool operator==(const PipelineState& rhs) const noexcept { return vertex_shader == rhs.vertex_shader && fragment_shader == rhs.fragment_shader && geometry_shader == rhs.geometry_shader; } - bool operator!=(const PipelineState& rhs) const { + bool operator!=(const PipelineState& rhs) const noexcept { return !operator==(rhs); } - GLuint vertex_shader{}; - GLuint fragment_shader{}; - GLuint geometry_shader{}; + GLuint vertex_shader = 0; + GLuint fragment_shader = 0; + GLuint geometry_shader = 0; }; - OGLPipeline pipeline; + OGLPipeline graphics_pipeline; + OGLPipeline compute_pipeline; PipelineState current_state; PipelineState old_state; + bool is_graphics_bound = true; }; } // namespace OpenGL::GLShader diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index a51410660d..c05677cd92 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -443,7 +443,6 @@ void RendererOpenGL::InitOpenGLObjects() { // Create program pipeline program_manager.Create(); - glBindProgramPipeline(program_manager.GetHandle()); // Generate VBO handle for drawing vertex_buffer.Create(); @@ -596,7 +595,7 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) { program_manager.UseVertexShader(vertex_program.handle); program_manager.UseGeometryShader(0); program_manager.UseFragmentShader(fragment_program.handle); - program_manager.Update(); + program_manager.BindGraphicsPipeline(); glEnable(GL_CULL_FACE); if (screen_info.display_srgb) { From e891ff9a0cbd5466fff302ff73862f3a73440efd Mon Sep 17 00:00:00 2001 From: Vitor Kiguchi Date: Wed, 11 Mar 2020 14:02:30 -0300 Subject: [PATCH 6/8] framebuffer_layout.h: drop the use of enum for screen dimensions. +clang format --- src/core/frontend/framebuffer_layout.cpp | 4 ++-- src/core/frontend/framebuffer_layout.h | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/core/frontend/framebuffer_layout.cpp b/src/core/frontend/framebuffer_layout.cpp index 2dc795d562..68a0e09069 100644 --- a/src/core/frontend/framebuffer_layout.cpp +++ b/src/core/frontend/framebuffer_layout.cpp @@ -48,8 +48,8 @@ FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale) { u32 width, height; if (Settings::values.use_docked_mode) { - width = ScreenDocked::WidthDocked * res_scale; - height = ScreenDocked::HeightDocked * res_scale; + width = ScreenDocked::Width * res_scale; + height = ScreenDocked::Height * res_scale; } else { width = ScreenUndocked::Width * res_scale; height = ScreenUndocked::Height * res_scale; diff --git a/src/core/frontend/framebuffer_layout.h b/src/core/frontend/framebuffer_layout.h index e9d0a40d39..15ecfb13dd 100644 --- a/src/core/frontend/framebuffer_layout.h +++ b/src/core/frontend/framebuffer_layout.h @@ -8,15 +8,15 @@ namespace Layout { -enum ScreenUndocked : u32 { - Width = 1280, - Height = 720, -}; +namespace ScreenUndocked { +constexpr u32 Width = 1280; +constexpr u32 Height = 720; +} // namespace ScreenUndocked -enum ScreenDocked : u32 { - WidthDocked = 1920, - HeightDocked = 1080, -}; +namespace ScreenDocked { +constexpr u32 Width = 1920; +constexpr u32 Height = 1080; +} // namespace ScreenDocked enum class AspectRatio { Default, From 448856695a5eebfccf46b69918cd18369c849e15 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Thu, 12 Mar 2020 10:50:48 -0400 Subject: [PATCH 7/8] Microprofile: Allow accessing token. --- externals/microprofile/microprofile.h | 1 + 1 file changed, 1 insertion(+) diff --git a/externals/microprofile/microprofile.h b/externals/microprofile/microprofile.h index cdb312b878..c1556d10c1 100644 --- a/externals/microprofile/microprofile.h +++ b/externals/microprofile/microprofile.h @@ -243,6 +243,7 @@ typedef uint32_t ThreadIdType; #define MICROPROFILE_DEFINE_GPU(var, name, color) MicroProfileToken g_mp_##var = MicroProfileGetToken("GPU", name, color, MicroProfileTokenTypeGpu) #define MICROPROFILE_TOKEN_PASTE0(a, b) a ## b #define MICROPROFILE_TOKEN_PASTE(a, b) MICROPROFILE_TOKEN_PASTE0(a,b) +#define MICROPROFILE_TOKEN(var) g_mp_##var #define MICROPROFILE_SCOPE(var) MicroProfileScopeHandler MICROPROFILE_TOKEN_PASTE(foo, __LINE__)(g_mp_##var) #define MICROPROFILE_SCOPE_TOKEN(token) MicroProfileScopeHandler MICROPROFILE_TOKEN_PASTE(foo, __LINE__)(token) #define MICROPROFILE_SCOPEI(group, name, color) static MicroProfileToken MICROPROFILE_TOKEN_PASTE(g_mp,__LINE__) = MicroProfileGetToken(group, name, color, MicroProfileTokenTypeCpu); MicroProfileScopeHandler MICROPROFILE_TOKEN_PASTE(foo,__LINE__)( MICROPROFILE_TOKEN_PASTE(g_mp,__LINE__)) From 95b804ff0565a653109c1a7f7326eecc838fee5c Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Thu, 12 Mar 2020 10:52:44 -0400 Subject: [PATCH 8/8] NVFlinger: Do the microprofile Flip after processing a valid frame. --- src/core/hle/service/nvflinger/nvflinger.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp index 1341522103..437bc5dee9 100644 --- a/src/core/hle/service/nvflinger/nvflinger.cpp +++ b/src/core/hle/service/nvflinger/nvflinger.cpp @@ -191,8 +191,6 @@ void NVFlinger::Compose() { // Search for a queued buffer and acquire it auto buffer = buffer_queue.AcquireBuffer(); - MicroProfileFlip(); - if (!buffer) { continue; } @@ -206,6 +204,8 @@ void NVFlinger::Compose() { gpu.WaitFence(fence.id, fence.value); } + MicroProfileFlip(); + // Now send the buffer to the GPU for drawing. // TODO(Subv): Support more than just disp0. The display device selection is probably based // on which display we're drawing (Default, Internal, External, etc)