diff options
| -rw-r--r-- | externals/microprofile/microprofile.h | 1 | ||||
| -rw-r--r-- | src/audio_core/cubeb_sink.cpp | 20 | ||||
| -rw-r--r-- | src/core/frontend/framebuffer_layout.cpp | 4 | ||||
| -rw-r--r-- | src/core/frontend/framebuffer_layout.h | 16 | ||||
| -rw-r--r-- | src/core/hle/service/nvflinger/nvflinger.cpp | 4 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 5 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_manager.cpp | 31 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_manager.h | 29 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.cpp | 3 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.cpp | 9 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp | 3 | 
11 files changed, 79 insertions, 46 deletions
| diff --git a/externals/microprofile/microprofile.h b/externals/microprofile/microprofile.h index cdb312b87..c1556d10c 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__)) diff --git a/src/audio_core/cubeb_sink.cpp b/src/audio_core/cubeb_sink.cpp index 7047ed9cf..c4e0e30fe 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<s16>& 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<s16> 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; diff --git a/src/core/frontend/framebuffer_layout.cpp b/src/core/frontend/framebuffer_layout.cpp index 2dc795d56..68a0e0906 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 e9d0a40d3..15ecfb13d 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, diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp index 134152210..437bc5dee 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) diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 90124e114..8e48a6482 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -566,7 +566,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(); @@ -628,8 +628,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 15f3cd066..9c7b0adbd 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 <glad/glad.h> +  #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 e94cd75aa..d2e47f2a9 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 d03b29c22..12333e8c9 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(); @@ -597,7 +596,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) { diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index b402fb268..2bcb17b56 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -854,7 +854,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); @@ -915,6 +915,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 171d78afc..d9ea3cc21 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); | 
