mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 06:09:50 -06:00
VideoBackends / VideoCommon: add new uniform buffer object for custom shader materials (slot 3, geometry shader buffer moves to slot 4 if available)
This commit is contained in:
@ -167,7 +167,7 @@ void VertexManager::UpdateGeometryShaderConstants()
|
||||
if (!geometry_shader_manager.dirty || !ReserveConstantStorage())
|
||||
return;
|
||||
|
||||
Gfx::GetInstance()->SetConstantBuffer(2, m_uniform_stream_buffer.GetCurrentGPUPointer());
|
||||
Gfx::GetInstance()->SetConstantBuffer(3, m_uniform_stream_buffer.GetCurrentGPUPointer());
|
||||
std::memcpy(m_uniform_stream_buffer.GetCurrentHostPointer(), &geometry_shader_manager.constants,
|
||||
sizeof(GeometryShaderConstants));
|
||||
m_uniform_stream_buffer.CommitMemory(sizeof(GeometryShaderConstants));
|
||||
@ -180,23 +180,41 @@ void VertexManager::UpdatePixelShaderConstants()
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& pixel_shader_manager = system.GetPixelShaderManager();
|
||||
|
||||
if (!pixel_shader_manager.dirty || !ReserveConstantStorage())
|
||||
if (!ReserveConstantStorage())
|
||||
return;
|
||||
|
||||
Gfx::GetInstance()->SetConstantBuffer(0, m_uniform_stream_buffer.GetCurrentGPUPointer());
|
||||
std::memcpy(m_uniform_stream_buffer.GetCurrentHostPointer(), &pixel_shader_manager.constants,
|
||||
sizeof(PixelShaderConstants));
|
||||
m_uniform_stream_buffer.CommitMemory(sizeof(PixelShaderConstants));
|
||||
ADDSTAT(g_stats.this_frame.bytes_uniform_streamed, sizeof(PixelShaderConstants));
|
||||
pixel_shader_manager.dirty = false;
|
||||
if (pixel_shader_manager.dirty)
|
||||
{
|
||||
Gfx::GetInstance()->SetConstantBuffer(0, m_uniform_stream_buffer.GetCurrentGPUPointer());
|
||||
std::memcpy(m_uniform_stream_buffer.GetCurrentHostPointer(), &pixel_shader_manager.constants,
|
||||
sizeof(PixelShaderConstants));
|
||||
m_uniform_stream_buffer.CommitMemory(sizeof(PixelShaderConstants));
|
||||
ADDSTAT(g_stats.this_frame.bytes_uniform_streamed, sizeof(PixelShaderConstants));
|
||||
pixel_shader_manager.dirty = false;
|
||||
}
|
||||
|
||||
if (pixel_shader_manager.custom_constants_dirty)
|
||||
{
|
||||
Gfx::GetInstance()->SetConstantBuffer(2, m_uniform_stream_buffer.GetCurrentGPUPointer());
|
||||
std::memcpy(m_uniform_stream_buffer.GetCurrentHostPointer(),
|
||||
pixel_shader_manager.custom_constants.data(),
|
||||
pixel_shader_manager.custom_constants.size());
|
||||
m_uniform_stream_buffer.CommitMemory(
|
||||
static_cast<u32>(pixel_shader_manager.custom_constants.size()));
|
||||
pixel_shader_manager.custom_constants_dirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool VertexManager::ReserveConstantStorage()
|
||||
{
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& pixel_shader_manager = system.GetPixelShaderManager();
|
||||
|
||||
static constexpr u32 reserve_size =
|
||||
static_cast<u32>(std::max({sizeof(PixelShaderConstants), sizeof(VertexShaderConstants),
|
||||
sizeof(GeometryShaderConstants)}));
|
||||
if (m_uniform_stream_buffer.ReserveMemory(reserve_size,
|
||||
const u32 custom_constants_size = static_cast<u32>(pixel_shader_manager.custom_constants.size());
|
||||
if (m_uniform_stream_buffer.ReserveMemory(reserve_size + custom_constants_size,
|
||||
D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT))
|
||||
{
|
||||
return true;
|
||||
@ -214,6 +232,9 @@ bool VertexManager::ReserveConstantStorage()
|
||||
|
||||
void VertexManager::UploadAllConstants()
|
||||
{
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& pixel_shader_manager = system.GetPixelShaderManager();
|
||||
|
||||
// We are free to re-use parts of the buffer now since we're uploading all constants.
|
||||
const u32 pixel_constants_offset = 0;
|
||||
constexpr u32 vertex_constants_offset =
|
||||
@ -222,7 +243,11 @@ void VertexManager::UploadAllConstants()
|
||||
constexpr u32 geometry_constants_offset =
|
||||
Common::AlignUp(vertex_constants_offset + sizeof(VertexShaderConstants),
|
||||
D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT);
|
||||
const u32 allocation_size = geometry_constants_offset + sizeof(GeometryShaderConstants);
|
||||
constexpr u32 custom_pixel_constants_offset =
|
||||
Common::AlignUp(geometry_constants_offset + sizeof(GeometryShaderConstants),
|
||||
D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT);
|
||||
const u32 allocation_size = custom_pixel_constants_offset +
|
||||
static_cast<u32>(pixel_shader_manager.custom_constants.size());
|
||||
|
||||
// Allocate everything at once.
|
||||
// We should only be here if the buffer was full and a command buffer was submitted anyway.
|
||||
@ -239,10 +264,10 @@ void VertexManager::UploadAllConstants()
|
||||
Gfx::GetInstance()->SetConstantBuffer(1, m_uniform_stream_buffer.GetCurrentGPUPointer() +
|
||||
vertex_constants_offset);
|
||||
Gfx::GetInstance()->SetConstantBuffer(2, m_uniform_stream_buffer.GetCurrentGPUPointer() +
|
||||
custom_pixel_constants_offset);
|
||||
Gfx::GetInstance()->SetConstantBuffer(3, m_uniform_stream_buffer.GetCurrentGPUPointer() +
|
||||
geometry_constants_offset);
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& pixel_shader_manager = system.GetPixelShaderManager();
|
||||
auto& vertex_shader_manager = system.GetVertexShaderManager();
|
||||
auto& geometry_shader_manager = system.GetGeometryShaderManager();
|
||||
|
||||
@ -253,6 +278,12 @@ void VertexManager::UploadAllConstants()
|
||||
&vertex_shader_manager.constants, sizeof(VertexShaderConstants));
|
||||
std::memcpy(m_uniform_stream_buffer.GetCurrentHostPointer() + geometry_constants_offset,
|
||||
&geometry_shader_manager.constants, sizeof(GeometryShaderConstants));
|
||||
if (!pixel_shader_manager.custom_constants.empty())
|
||||
{
|
||||
std::memcpy(m_uniform_stream_buffer.GetCurrentHostPointer() + custom_pixel_constants_offset,
|
||||
pixel_shader_manager.custom_constants.data(),
|
||||
pixel_shader_manager.custom_constants.size());
|
||||
}
|
||||
|
||||
// Finally, flush buffer memory after copying
|
||||
m_uniform_stream_buffer.CommitMemory(allocation_size);
|
||||
|
Reference in New Issue
Block a user