video_core/engines: Move ConstBufferInfo out of Maxwell3D

This commit is contained in:
ReinUsesLisp 2019-05-31 17:33:21 -03:00
parent de33ad25f5
commit 2f2a61887a
6 changed files with 69 additions and 54 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,8 +322,8 @@ 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, primitive_mode, base_bindings);
SetupTextures(stage_enum, shader, program_handle, base_bindings); SetupTextures(stage_enum, shader, program_handle, base_bindings);
// Workaround for Intel drivers. // Workaround for Intel drivers.
@ -776,54 +776,53 @@ 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);
if (!buffer.enabled) {
// Set values to zero to unbind buffers
bind_ubo_pushbuffer.Push(0, 0, 0);
continue;
}
std::size_t size = 0;
if (used_buffer.IsIndirect()) {
// Buffer is accessed indirectly, so upload the entire thing
size = buffer.size;
if (size > MaxConstbufferSize) {
LOG_WARNING(Render_OpenGL, "Indirect constbuffer size {} exceeds maximum {}", size,
MaxConstbufferSize);
size = MaxConstbufferSize;
}
} else {
// Buffer is accessed directly, upload just what we use
size = used_buffer.GetSize();
}
// 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");
const GLintptr const_buffer_offset =
buffer_cache.UploadMemory(buffer.address, size, device.GetUniformBufferAlignment());
bind_ubo_pushbuffer.Push(buffer_cache.GetHandle(), const_buffer_offset, size);
} }
} }
void RasterizerOpenGL::SetupConstBuffer(const Tegra::Engines::ConstBufferInfo& buffer,
const GLShader::ConstBufferEntry& entry) {
if (!buffer.enabled) {
// Set values to zero to unbind buffers
bind_ubo_pushbuffer.Push(0, 0, 0);
return;
}
std::size_t size;
if (entry.IsIndirect()) {
// Buffer is accessed indirectly, so upload the entire thing
size = buffer.size;
if (size > MaxConstbufferSize) {
LOG_WARNING(Render_OpenGL, "Indirect constbuffer size {} exceeds maximum {}", size,
MaxConstbufferSize);
size = MaxConstbufferSize;
}
} else {
// Buffer is accessed directly, upload just what we use
size = entry.GetSize();
}
// 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, "Constant buffer is too big");
const std::size_t alignment = device.GetUniformBufferAlignment();
const GLintptr offset = buffer_cache.UploadMemory(buffer.address, size, alignment);
bind_ubo_pushbuffer.Push(buffer_cache.GetHandle(), 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, GLenum primitive_mode,
BaseBindings base_bindings) { BaseBindings base_bindings) {

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,8 +107,12 @@ 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,