summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--externals/microprofile/microprofile.h1
-rw-r--r--src/audio_core/cubeb_sink.cpp20
-rw-r--r--src/core/frontend/framebuffer_layout.cpp4
-rw-r--r--src/core/frontend/framebuffer_layout.h16
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.cpp4
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp5
-rw-r--r--src/video_core/renderer_opengl/gl_shader_manager.cpp31
-rw-r--r--src/video_core/renderer_opengl/gl_shader_manager.h29
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp3
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp9
-rw-r--r--src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp3
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);