yuzu-emu
/
yuzu-mainline
Archived
1
0
Fork 0

Merge pull request #2562 from ReinUsesLisp/split-cbuf-upload

video_core/engines: Move ConstBufferInfo out of Maxwell3D
This commit is contained in:
bunnei 2019-06-17 22:35:04 -04:00 committed by GitHub
commit c7b5c245e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 74 additions and 61 deletions

View File

@ -3,6 +3,7 @@ add_library(video_core STATIC
dma_pusher.h dma_pusher.h
debug_utils/debug_utils.cpp debug_utils/debug_utils.cpp
debug_utils/debug_utils.h debug_utils/debug_utils.h
engines/const_buffer_info.h
engines/engine_upload.cpp engines/engine_upload.cpp
engines/engine_upload.h engines/engine_upload.h
engines/fermi_2d.cpp engines/fermi_2d.cpp

View File

@ -0,0 +1,17 @@
// Copyright 2019 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "common/common_types.h"
namespace Tegra::Engines {
struct ConstBufferInfo {
GPUVAddr address;
u32 size;
bool enabled;
};
} // namespace Tegra::Engines

View File

@ -396,12 +396,10 @@ void Maxwell3D::ProcessCBBind(Regs::ShaderStage stage) {
auto& shader = state.shader_stages[static_cast<std::size_t>(stage)]; auto& shader = state.shader_stages[static_cast<std::size_t>(stage)];
auto& bind_data = regs.cb_bind[static_cast<std::size_t>(stage)]; auto& bind_data = regs.cb_bind[static_cast<std::size_t>(stage)];
ASSERT(bind_data.index < Regs::MaxConstBuffers);
auto& buffer = shader.const_buffers[bind_data.index]; auto& buffer = shader.const_buffers[bind_data.index];
ASSERT(bind_data.index < Regs::MaxConstBuffers);
buffer.enabled = bind_data.valid.Value() != 0; buffer.enabled = bind_data.valid.Value() != 0;
buffer.index = bind_data.index;
buffer.address = regs.const_buffer.BufferAddress(); buffer.address = regs.const_buffer.BufferAddress();
buffer.size = regs.const_buffer.cb_size; buffer.size = regs.const_buffer.cb_size;
} }

View File

@ -15,6 +15,7 @@
#include "common/common_funcs.h" #include "common/common_funcs.h"
#include "common/common_types.h" #include "common/common_types.h"
#include "common/math_util.h" #include "common/math_util.h"
#include "video_core/engines/const_buffer_info.h"
#include "video_core/engines/engine_upload.h" #include "video_core/engines/engine_upload.h"
#include "video_core/gpu.h" #include "video_core/gpu.h"
#include "video_core/macro_interpreter.h" #include "video_core/macro_interpreter.h"
@ -1112,13 +1113,6 @@ public:
static_assert(std::is_trivially_copyable_v<Regs>, "Maxwell3D Regs must be trivially copyable"); static_assert(std::is_trivially_copyable_v<Regs>, "Maxwell3D Regs must be trivially copyable");
struct State { struct State {
struct ConstBufferInfo {
GPUVAddr address;
u32 index;
u32 size;
bool enabled;
};
struct ShaderStageInfo { struct ShaderStageInfo {
std::array<ConstBufferInfo, Regs::MaxConstBuffers> const_buffers; std::array<ConstBufferInfo, Regs::MaxConstBuffers> const_buffers;
}; };

View File

@ -322,9 +322,9 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) {
} }
const auto stage_enum = static_cast<Maxwell::ShaderStage>(stage); const auto stage_enum = static_cast<Maxwell::ShaderStage>(stage);
SetupConstBuffers(stage_enum, shader, program_handle, base_bindings); SetupDrawConstBuffers(stage_enum, shader);
SetupGlobalRegions(stage_enum, shader, program_handle, base_bindings); SetupGlobalRegions(stage_enum, shader);
SetupTextures(stage_enum, shader, program_handle, base_bindings); SetupTextures(stage_enum, shader, base_bindings);
// Workaround for Intel drivers. // Workaround for Intel drivers.
// When a clip distance is enabled but not set in the shader it crops parts of the screen // When a clip distance is enabled but not set in the shader it crops parts of the screen
@ -776,29 +776,30 @@ bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& config,
return true; return true;
} }
void RasterizerOpenGL::SetupConstBuffers(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, void RasterizerOpenGL::SetupDrawConstBuffers(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage,
const Shader& shader, GLuint program_handle, const Shader& shader) {
BaseBindings base_bindings) {
MICROPROFILE_SCOPE(OpenGL_UBO); MICROPROFILE_SCOPE(OpenGL_UBO);
const auto& gpu = system.GPU(); const auto stage_index = static_cast<std::size_t>(stage);
const auto& maxwell3d = gpu.Maxwell3D(); const auto& shader_stage = system.GPU().Maxwell3D().state.shader_stages[stage_index];
const auto& shader_stage = maxwell3d.state.shader_stages[static_cast<std::size_t>(stage)];
const auto& entries = shader->GetShaderEntries().const_buffers; const auto& entries = shader->GetShaderEntries().const_buffers;
// Upload only the enabled buffers from the 16 constbuffers of each shader stage // Upload only the enabled buffers from the 16 constbuffers of each shader stage
for (u32 bindpoint = 0; bindpoint < entries.size(); ++bindpoint) { for (u32 bindpoint = 0; bindpoint < entries.size(); ++bindpoint) {
const auto& used_buffer = entries[bindpoint]; const auto& entry = entries[bindpoint];
const auto& buffer = shader_stage.const_buffers[used_buffer.GetIndex()]; SetupConstBuffer(shader_stage.const_buffers[entry.GetIndex()], entry);
}
}
void RasterizerOpenGL::SetupConstBuffer(const Tegra::Engines::ConstBufferInfo& buffer,
const GLShader::ConstBufferEntry& entry) {
if (!buffer.enabled) { if (!buffer.enabled) {
// Set values to zero to unbind buffers // Set values to zero to unbind buffers
bind_ubo_pushbuffer.Push(0, 0, 0); bind_ubo_pushbuffer.Push(0, 0, 0);
continue; return;
} }
std::size_t size = 0; std::size_t size;
if (entry.IsIndirect()) {
if (used_buffer.IsIndirect()) {
// Buffer is accessed indirectly, so upload the entire thing // Buffer is accessed indirectly, so upload the entire thing
size = buffer.size; size = buffer.size;
@ -809,24 +810,21 @@ void RasterizerOpenGL::SetupConstBuffers(Tegra::Engines::Maxwell3D::Regs::Shader
} }
} else { } else {
// Buffer is accessed directly, upload just what we use // Buffer is accessed directly, upload just what we use
size = used_buffer.GetSize(); size = entry.GetSize();
} }
// Align the actual size so it ends up being a multiple of vec4 to meet the OpenGL std140 // Align the actual size so it ends up being a multiple of vec4 to meet the OpenGL std140
// UBO alignment requirements. // UBO alignment requirements.
size = Common::AlignUp(size, sizeof(GLvec4)); size = Common::AlignUp(size, sizeof(GLvec4));
ASSERT_MSG(size <= MaxConstbufferSize, "Constbuffer too big"); ASSERT_MSG(size <= MaxConstbufferSize, "Constant buffer is too big");
const GLintptr const_buffer_offset = const std::size_t alignment = device.GetUniformBufferAlignment();
buffer_cache.UploadMemory(buffer.address, size, device.GetUniformBufferAlignment()); const GLintptr offset = buffer_cache.UploadMemory(buffer.address, size, alignment);
bind_ubo_pushbuffer.Push(buffer_cache.GetHandle(), offset, size);
bind_ubo_pushbuffer.Push(buffer_cache.GetHandle(), const_buffer_offset, size);
}
} }
void RasterizerOpenGL::SetupGlobalRegions(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, void RasterizerOpenGL::SetupGlobalRegions(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage,
const Shader& shader, GLenum primitive_mode, const Shader& shader) {
BaseBindings base_bindings) {
const auto& entries = shader->GetShaderEntries().global_memory_entries; const auto& entries = shader->GetShaderEntries().global_memory_entries;
for (std::size_t bindpoint = 0; bindpoint < entries.size(); ++bindpoint) { for (std::size_t bindpoint = 0; bindpoint < entries.size(); ++bindpoint) {
const auto& entry{entries[bindpoint]}; const auto& entry{entries[bindpoint]};
@ -840,7 +838,7 @@ void RasterizerOpenGL::SetupGlobalRegions(Tegra::Engines::Maxwell3D::Regs::Shade
} }
void RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, const Shader& shader, void RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, const Shader& shader,
GLuint program_handle, BaseBindings base_bindings) { BaseBindings base_bindings) {
MICROPROFILE_SCOPE(OpenGL_Texture); MICROPROFILE_SCOPE(OpenGL_Texture);
const auto& gpu = system.GPU(); const auto& gpu = system.GPU();
const auto& maxwell3d = gpu.Maxwell3D(); const auto& maxwell3d = gpu.Maxwell3D();

View File

@ -17,6 +17,7 @@
#include <glad/glad.h> #include <glad/glad.h>
#include "common/common_types.h" #include "common/common_types.h"
#include "video_core/engines/const_buffer_info.h"
#include "video_core/engines/maxwell_3d.h" #include "video_core/engines/maxwell_3d.h"
#include "video_core/rasterizer_cache.h" #include "video_core/rasterizer_cache.h"
#include "video_core/rasterizer_interface.h" #include "video_core/rasterizer_interface.h"
@ -27,6 +28,7 @@
#include "video_core/renderer_opengl/gl_resource_manager.h" #include "video_core/renderer_opengl/gl_resource_manager.h"
#include "video_core/renderer_opengl/gl_sampler_cache.h" #include "video_core/renderer_opengl/gl_sampler_cache.h"
#include "video_core/renderer_opengl/gl_shader_cache.h" #include "video_core/renderer_opengl/gl_shader_cache.h"
#include "video_core/renderer_opengl/gl_shader_decompiler.h"
#include "video_core/renderer_opengl/gl_shader_manager.h" #include "video_core/renderer_opengl/gl_shader_manager.h"
#include "video_core/renderer_opengl/gl_state.h" #include "video_core/renderer_opengl/gl_state.h"
#include "video_core/renderer_opengl/utils.h" #include "video_core/renderer_opengl/utils.h"
@ -105,17 +107,20 @@ private:
bool preserve_contents = true, std::optional<std::size_t> single_color_target = {}); bool preserve_contents = true, std::optional<std::size_t> single_color_target = {});
/// Configures the current constbuffers to use for the draw command. /// Configures the current constbuffers to use for the draw command.
void SetupConstBuffers(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, const Shader& shader, void SetupDrawConstBuffers(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage,
GLuint program_handle, BaseBindings base_bindings); const Shader& shader);
/// Configures a constant buffer.
void SetupConstBuffer(const Tegra::Engines::ConstBufferInfo& buffer,
const GLShader::ConstBufferEntry& entry);
/// Configures the current global memory entries to use for the draw command. /// Configures the current global memory entries to use for the draw command.
void SetupGlobalRegions(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, void SetupGlobalRegions(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage,
const Shader& shader, GLenum primitive_mode, const Shader& shader);
BaseBindings base_bindings);
/// Configures the current textures to use for the draw command. /// Configures the current textures to use for the draw command.
void SetupTextures(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, const Shader& shader, void SetupTextures(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, const Shader& shader,
GLuint program_handle, BaseBindings base_bindings); BaseBindings base_bindings);
/// Syncs the viewport and depth range to match the guest state /// Syncs the viewport and depth range to match the guest state
void SyncViewport(OpenGLState& current_state); void SyncViewport(OpenGLState& current_state);