mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-09-10 18:20:58 +02:00
Merge pull request #13877 from iwubcode/vertex_shader_custom_uniforms
VideoBackends: allow custom pixel uniforms to be passed to the vertex shader as well
This commit is contained in:
@@ -59,6 +59,7 @@ void StateManager::Apply()
|
||||
|
||||
const bool dirtyConstants = m_dirtyFlags.test(DirtyFlag_PixelConstants) ||
|
||||
m_dirtyFlags.test(DirtyFlag_VertexConstants) ||
|
||||
m_dirtyFlags.test(DirtyFlag_CustomConstants) ||
|
||||
m_dirtyFlags.test(DirtyFlag_GeometryConstants);
|
||||
const bool dirtyShaders = m_dirtyFlags.test(DirtyFlag_PixelShader) ||
|
||||
m_dirtyFlags.test(DirtyFlag_VertexShader) ||
|
||||
@@ -69,18 +70,12 @@ void StateManager::Apply()
|
||||
if (dirtyConstants)
|
||||
{
|
||||
if (m_current.pixelConstants[0] != m_pending.pixelConstants[0] ||
|
||||
m_current.pixelConstants[1] != m_pending.pixelConstants[1] ||
|
||||
m_current.pixelConstants[2] != m_pending.pixelConstants[2])
|
||||
m_current.pixelConstants[1] != m_pending.pixelConstants[1])
|
||||
{
|
||||
u32 count = 1;
|
||||
if (m_pending.pixelConstants[1])
|
||||
count++;
|
||||
if (m_pending.pixelConstants[2])
|
||||
count++;
|
||||
D3D::context->PSSetConstantBuffers(0, count, m_pending.pixelConstants.data());
|
||||
D3D::context->PSSetConstantBuffers(0, 1, &m_pending.pixelConstants[0]);
|
||||
D3D::context->PSSetConstantBuffers(1, 1, &m_pending.pixelConstants[1]);
|
||||
m_current.pixelConstants[0] = m_pending.pixelConstants[0];
|
||||
m_current.pixelConstants[1] = m_pending.pixelConstants[1];
|
||||
m_current.pixelConstants[2] = m_pending.pixelConstants[2];
|
||||
}
|
||||
|
||||
if (m_current.vertexConstants != m_pending.vertexConstants)
|
||||
@@ -90,6 +85,13 @@ void StateManager::Apply()
|
||||
m_current.vertexConstants = m_pending.vertexConstants;
|
||||
}
|
||||
|
||||
if (m_current.customConstants != m_pending.customConstants)
|
||||
{
|
||||
D3D::context->PSSetConstantBuffers(2, 1, &m_pending.customConstants);
|
||||
D3D::context->VSSetConstantBuffers(2, 1, &m_pending.customConstants);
|
||||
m_current.customConstants = m_pending.customConstants;
|
||||
}
|
||||
|
||||
if (m_current.geometryConstants != m_pending.geometryConstants)
|
||||
{
|
||||
D3D::context->GSSetConstantBuffers(0, 1, &m_pending.geometryConstants);
|
||||
|
@@ -91,16 +91,13 @@ public:
|
||||
m_pending.samplers[index] = sampler;
|
||||
}
|
||||
|
||||
void SetPixelConstants(ID3D11Buffer* buffer0, ID3D11Buffer* buffer1 = nullptr,
|
||||
ID3D11Buffer* buffer2 = nullptr)
|
||||
void SetPixelConstants(ID3D11Buffer* buffer0, ID3D11Buffer* buffer1 = nullptr)
|
||||
{
|
||||
if (m_current.pixelConstants[0] != buffer0 || m_current.pixelConstants[1] != buffer1 ||
|
||||
m_current.pixelConstants[2] != buffer2)
|
||||
if (m_current.pixelConstants[0] != buffer0 || m_current.pixelConstants[1] != buffer1)
|
||||
m_dirtyFlags.set(DirtyFlag_PixelConstants);
|
||||
|
||||
m_pending.pixelConstants[0] = buffer0;
|
||||
m_pending.pixelConstants[1] = buffer1;
|
||||
m_pending.pixelConstants[2] = buffer2;
|
||||
}
|
||||
|
||||
void SetVertexConstants(ID3D11Buffer* buffer)
|
||||
@@ -111,6 +108,14 @@ public:
|
||||
m_pending.vertexConstants = buffer;
|
||||
}
|
||||
|
||||
void SetCustomConstants(ID3D11Buffer* buffer)
|
||||
{
|
||||
if (m_current.customConstants != buffer)
|
||||
m_dirtyFlags.set(DirtyFlag_CustomConstants);
|
||||
|
||||
m_pending.customConstants = buffer;
|
||||
}
|
||||
|
||||
void SetGeometryConstants(ID3D11Buffer* buffer)
|
||||
{
|
||||
if (m_current.geometryConstants != buffer)
|
||||
@@ -232,6 +237,7 @@ private:
|
||||
DirtyFlag_Sampler0 = DirtyFlag_Texture0 + VideoCommon::MAX_PIXEL_SHADER_SAMPLERS,
|
||||
DirtyFlag_PixelConstants = DirtyFlag_Sampler0 + VideoCommon::MAX_PIXEL_SHADER_SAMPLERS,
|
||||
DirtyFlag_VertexConstants,
|
||||
DirtyFlag_CustomConstants, // Custom shader constants used by both vertex/pixel stages
|
||||
DirtyFlag_GeometryConstants,
|
||||
|
||||
DirtyFlag_VertexBuffer,
|
||||
@@ -255,8 +261,9 @@ private:
|
||||
{
|
||||
std::array<ID3D11ShaderResourceView*, VideoCommon::MAX_PIXEL_SHADER_SAMPLERS> textures;
|
||||
std::array<ID3D11SamplerState*, VideoCommon::MAX_PIXEL_SHADER_SAMPLERS> samplers;
|
||||
std::array<ID3D11Buffer*, 3> pixelConstants;
|
||||
std::array<ID3D11Buffer*, 2> pixelConstants;
|
||||
ID3D11Buffer* vertexConstants;
|
||||
ID3D11Buffer* customConstants;
|
||||
ID3D11Buffer* geometryConstants;
|
||||
ID3D11Buffer* vertexBuffer;
|
||||
ID3D11Buffer* indexBuffer;
|
||||
|
@@ -290,24 +290,23 @@ void VertexManager::UploadUniforms()
|
||||
|
||||
if (pixel_shader_manager.custom_constants_dirty)
|
||||
{
|
||||
if (m_last_custom_pixel_buffer_size < pixel_shader_manager.custom_constants.size())
|
||||
if (m_last_custom_buffer_size < pixel_shader_manager.custom_constants.size())
|
||||
{
|
||||
m_custom_pixel_constant_buffer =
|
||||
m_custom_constant_buffer =
|
||||
AllocateConstantBuffer(static_cast<u32>(pixel_shader_manager.custom_constants.size()));
|
||||
}
|
||||
UpdateConstantBuffer(m_custom_pixel_constant_buffer.Get(),
|
||||
UpdateConstantBuffer(m_custom_constant_buffer.Get(),
|
||||
pixel_shader_manager.custom_constants.data(),
|
||||
static_cast<u32>(pixel_shader_manager.custom_constants.size()));
|
||||
m_last_custom_pixel_buffer_size = pixel_shader_manager.custom_constants.size();
|
||||
m_last_custom_buffer_size = pixel_shader_manager.custom_constants.size();
|
||||
pixel_shader_manager.custom_constants_dirty = false;
|
||||
}
|
||||
|
||||
D3D::stateman->SetPixelConstants(
|
||||
m_pixel_constant_buffer.Get(),
|
||||
g_ActiveConfig.bEnablePixelLighting ? m_vertex_constant_buffer.Get() : nullptr,
|
||||
pixel_shader_manager.custom_constants.empty() ? nullptr :
|
||||
m_custom_pixel_constant_buffer.Get());
|
||||
g_ActiveConfig.bEnablePixelLighting ? m_vertex_constant_buffer.Get() : nullptr);
|
||||
D3D::stateman->SetVertexConstants(m_vertex_constant_buffer.Get());
|
||||
D3D::stateman->SetGeometryConstants(m_geometry_constant_buffer.Get());
|
||||
D3D::stateman->SetCustomConstants(m_custom_constant_buffer.Get());
|
||||
}
|
||||
} // namespace DX11
|
||||
|
@@ -68,8 +68,8 @@ private:
|
||||
ComPtr<ID3D11Buffer> m_geometry_constant_buffer = nullptr;
|
||||
ComPtr<ID3D11Buffer> m_pixel_constant_buffer = nullptr;
|
||||
|
||||
ComPtr<ID3D11Buffer> m_custom_pixel_constant_buffer = nullptr;
|
||||
std::size_t m_last_custom_pixel_buffer_size = 0;
|
||||
ComPtr<ID3D11Buffer> m_custom_constant_buffer = nullptr;
|
||||
std::size_t m_last_custom_buffer_size = 0;
|
||||
|
||||
ComPtr<ID3D11Buffer> m_texel_buffer = nullptr;
|
||||
std::array<ComPtr<ID3D11ShaderResourceView>, NUM_TEXEL_BUFFER_FORMATS> m_texel_buffer_views;
|
||||
|
@@ -160,7 +160,7 @@ void Gfx::SetPipeline(const AbstractPipeline* pipeline)
|
||||
m_dirty_bits |= DirtyState_RootSignature | DirtyState_PS_CBV | DirtyState_VS_CBV |
|
||||
DirtyState_GS_CBV | DirtyState_SRV_Descriptor |
|
||||
DirtyState_Sampler_Descriptor | DirtyState_UAV_Descriptor |
|
||||
DirtyState_VS_SRV_Descriptor | DirtyState_PS_CUS_CBV;
|
||||
DirtyState_VS_SRV_Descriptor | DirtyState_CUS_CBV;
|
||||
}
|
||||
if (dx_pipeline->UseIntegerRTV() != m_state.using_integer_rtv)
|
||||
{
|
||||
@@ -524,7 +524,7 @@ bool Gfx::ApplyState()
|
||||
DirtyState_ScissorRect | DirtyState_PS_UAV | DirtyState_PS_CBV | DirtyState_VS_CBV |
|
||||
DirtyState_GS_CBV | DirtyState_SRV_Descriptor | DirtyState_Sampler_Descriptor |
|
||||
DirtyState_UAV_Descriptor | DirtyState_VertexBuffer | DirtyState_IndexBuffer |
|
||||
DirtyState_PrimitiveTopology | DirtyState_VS_SRV_Descriptor | DirtyState_PS_CUS_CBV);
|
||||
DirtyState_PrimitiveTopology | DirtyState_VS_SRV_Descriptor | DirtyState_CUS_CBV);
|
||||
|
||||
auto* const cmdlist = g_dx_context->GetCommandList();
|
||||
auto* const pipeline = static_cast<const DXPipeline*>(m_current_pipeline);
|
||||
@@ -575,8 +575,10 @@ bool Gfx::ApplyState()
|
||||
}
|
||||
}
|
||||
|
||||
if (dirty_bits & DirtyState_PS_CUS_CBV)
|
||||
if (dirty_bits & DirtyState_CUS_CBV)
|
||||
{
|
||||
cmdlist->SetGraphicsRootConstantBufferView(ROOT_PARAMETER_VS_CUS_CBV,
|
||||
m_state.constant_buffers[2]);
|
||||
cmdlist->SetGraphicsRootConstantBufferView(ROOT_PARAMETER_PS_CUS_CBV,
|
||||
m_state.constant_buffers[2]);
|
||||
}
|
||||
|
@@ -112,7 +112,7 @@ private:
|
||||
DirtyState_PS_UAV = (1 << 7),
|
||||
DirtyState_PS_CBV = (1 << 8),
|
||||
DirtyState_VS_CBV = (1 << 9),
|
||||
DirtyState_PS_CUS_CBV = (1 << 10),
|
||||
DirtyState_CUS_CBV = (1 << 10),
|
||||
DirtyState_GS_CBV = (1 << 11),
|
||||
DirtyState_SRV_Descriptor = (1 << 12),
|
||||
DirtyState_Sampler_Descriptor = (1 << 13),
|
||||
@@ -129,7 +129,7 @@ private:
|
||||
DirtyState_All =
|
||||
DirtyState_Framebuffer | DirtyState_Pipeline | DirtyState_Textures | DirtyState_Samplers |
|
||||
DirtyState_Viewport | DirtyState_ScissorRect | DirtyState_ComputeImageTexture |
|
||||
DirtyState_PS_UAV | DirtyState_PS_CBV | DirtyState_VS_CBV | DirtyState_PS_CUS_CBV |
|
||||
DirtyState_PS_UAV | DirtyState_PS_CBV | DirtyState_VS_CBV | DirtyState_CUS_CBV |
|
||||
DirtyState_GS_CBV | DirtyState_SRV_Descriptor | DirtyState_Sampler_Descriptor |
|
||||
DirtyState_UAV_Descriptor | DirtyState_VertexBuffer | DirtyState_IndexBuffer |
|
||||
DirtyState_PrimitiveTopology | DirtyState_RootSignature | DirtyState_ComputeRootSignature |
|
||||
|
@@ -141,6 +141,7 @@ void VertexManager::UploadUniforms()
|
||||
UpdateVertexShaderConstants();
|
||||
UpdateGeometryShaderConstants();
|
||||
UpdatePixelShaderConstants();
|
||||
UpdateCustomShaderConstants();
|
||||
}
|
||||
|
||||
void VertexManager::UpdateVertexShaderConstants()
|
||||
@@ -192,6 +193,15 @@ void VertexManager::UpdatePixelShaderConstants()
|
||||
ADDSTAT(g_stats.this_frame.bytes_uniform_streamed, sizeof(PixelShaderConstants));
|
||||
pixel_shader_manager.dirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
void VertexManager::UpdateCustomShaderConstants()
|
||||
{
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& pixel_shader_manager = system.GetPixelShaderManager();
|
||||
|
||||
if (!ReserveConstantStorage())
|
||||
return;
|
||||
|
||||
if (pixel_shader_manager.custom_constants_dirty)
|
||||
{
|
||||
|
@@ -35,6 +35,7 @@ protected:
|
||||
void UpdateVertexShaderConstants();
|
||||
void UpdateGeometryShaderConstants();
|
||||
void UpdatePixelShaderConstants();
|
||||
void UpdateCustomShaderConstants();
|
||||
|
||||
// Allocates storage in the uniform buffer of the specified size. If this storage cannot be
|
||||
// allocated immediately, the current command buffer will be submitted and all stage's
|
||||
|
@@ -339,7 +339,7 @@ bool DXContext::CreateRootSignatures()
|
||||
bool DXContext::CreateGXRootSignature()
|
||||
{
|
||||
// GX:
|
||||
// - 4 constant buffers (bindings 0-3), 0/1/2 visible in PS, 2 visible in VS, 1 visible in GS.
|
||||
// - 4 constant buffers (bindings 0-3), 0/1/2 visible in PS, 3 visible in VS, 1 visible in GS.
|
||||
// - VideoCommon::MAX_PIXEL_SHADER_SAMPLERS textures (visible in PS).
|
||||
// - VideoCommon::MAX_PIXEL_SHADER_SAMPLERS samplers (visible in PS).
|
||||
// - 1 UAV (visible in PS).
|
||||
@@ -359,8 +359,10 @@ bool DXContext::CreateGXRootSignature()
|
||||
param_count++;
|
||||
SetRootParamCBV(¶ms[param_count], 1, D3D12_SHADER_VISIBILITY_VERTEX);
|
||||
param_count++;
|
||||
if (g_ActiveConfig.UseVSForLinePointExpand())
|
||||
SetRootParamCBV(¶ms[param_count], 2, D3D12_SHADER_VISIBILITY_VERTEX);
|
||||
param_count++;
|
||||
if (g_ActiveConfig.UseVSForLinePointExpand())
|
||||
SetRootParamCBV(¶ms[param_count], 3, D3D12_SHADER_VISIBILITY_VERTEX);
|
||||
else
|
||||
SetRootParamCBV(¶ms[param_count], 0, D3D12_SHADER_VISIBILITY_GEOMETRY);
|
||||
param_count++;
|
||||
|
@@ -26,6 +26,7 @@ enum ROOT_PARAMETER
|
||||
ROOT_PARAMETER_PS_SAMPLERS,
|
||||
ROOT_PARAMETER_VS_CBV,
|
||||
ROOT_PARAMETER_VS_CBV2,
|
||||
ROOT_PARAMETER_VS_CUS_CBV,
|
||||
ROOT_PARAMETER_GS_CBV,
|
||||
ROOT_PARAMETER_VS_SRV,
|
||||
ROOT_PARAMETER_BASE_VERTEX_CONSTANT,
|
||||
|
@@ -70,7 +70,7 @@ enum UNIFORM_BUFFER_DESCRIPTOR_SET_BINDING
|
||||
{
|
||||
UBO_DESCRIPTOR_SET_BINDING_PS,
|
||||
UBO_DESCRIPTOR_SET_BINDING_VS,
|
||||
UBO_DESCRIPTOR_SET_BINDING_PS_CUST,
|
||||
UBO_DESCRIPTOR_SET_BINDING_CUST,
|
||||
UBO_DESCRIPTOR_SET_BINDING_GS,
|
||||
NUM_UBO_DESCRIPTOR_SET_BINDINGS
|
||||
};
|
||||
|
@@ -115,8 +115,8 @@ bool ObjectCache::CreateDescriptorSetLayouts()
|
||||
VK_SHADER_STAGE_FRAGMENT_BIT},
|
||||
{UBO_DESCRIPTOR_SET_BINDING_VS, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1,
|
||||
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT},
|
||||
{UBO_DESCRIPTOR_SET_BINDING_PS_CUST, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1,
|
||||
VK_SHADER_STAGE_FRAGMENT_BIT},
|
||||
{UBO_DESCRIPTOR_SET_BINDING_CUST, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1,
|
||||
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT},
|
||||
{UBO_DESCRIPTOR_SET_BINDING_GS, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1,
|
||||
VK_SHADER_STAGE_GEOMETRY_BIT},
|
||||
}};
|
||||
|
@@ -496,8 +496,8 @@ void StateTracker::UpdateGXDescriptorSet()
|
||||
continue;
|
||||
}
|
||||
|
||||
// If custom pixel shaders haven't been used, their buffer range is 0
|
||||
if (i == UBO_DESCRIPTOR_SET_BINDING_PS_CUST && m_bindings.gx_ubo_bindings[i].range == 0)
|
||||
// If custom shaders haven't been used, their buffer range is 0
|
||||
if (i == UBO_DESCRIPTOR_SET_BINDING_CUST && m_bindings.gx_ubo_bindings[i].range == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@@ -261,7 +261,7 @@ void VertexManager::UpdatePixelShaderConstants()
|
||||
if (pixel_shader_manager.custom_constants_dirty)
|
||||
{
|
||||
StateTracker::GetInstance()->SetGXUniformBuffer(
|
||||
UBO_DESCRIPTOR_SET_BINDING_PS_CUST, m_uniform_stream_buffer->GetBuffer(),
|
||||
UBO_DESCRIPTOR_SET_BINDING_CUST, m_uniform_stream_buffer->GetBuffer(),
|
||||
m_uniform_stream_buffer->GetCurrentOffset(),
|
||||
static_cast<u32>(pixel_shader_manager.custom_constants.size()));
|
||||
std::memcpy(m_uniform_stream_buffer->GetCurrentHostPointer(),
|
||||
@@ -337,7 +337,7 @@ void VertexManager::UploadAllConstants()
|
||||
if (!pixel_shader_manager.custom_constants.empty())
|
||||
{
|
||||
StateTracker::GetInstance()->SetGXUniformBuffer(
|
||||
UBO_DESCRIPTOR_SET_BINDING_PS_CUST, m_uniform_stream_buffer->GetBuffer(),
|
||||
UBO_DESCRIPTOR_SET_BINDING_CUST, m_uniform_stream_buffer->GetBuffer(),
|
||||
m_uniform_stream_buffer->GetCurrentOffset() + custom_pixel_constants_offset,
|
||||
custom_constants_size);
|
||||
}
|
||||
|
Reference in New Issue
Block a user