Add more improvements to optional tess/geo shaders

This commit is contained in:
Wojtek Figat
2024-04-04 18:35:26 +02:00
parent d12630d815
commit 84e04de23d
13 changed files with 131 additions and 39 deletions

View File

@@ -126,13 +126,17 @@ bool GPUShader::Create(MemoryReadStream& stream)
LOG(Warning, "Failed to create {} Shader program '{}' ({}).", ::ToString(type), String(initializer.Name), name);
continue;
}
GPUShaderProgram* shader = CreateGPUShaderProgram(type, initializer, cache, cacheSize, stream);
if (shader == nullptr)
{
#if !GPU_ALLOW_TESSELLATION_SHADERS
if (type == ShaderStage::Hull || type == ShaderStage::Domain)
continue;
#endif
GPUShaderProgram* shader = CreateGPUShaderProgram(type, initializer, cache, cacheSize, stream);
if (shader == nullptr)
{
#if !GPU_ALLOW_GEOMETRY_SHADERS
if (type == ShaderStage::Geometry)
continue;
#endif
LOG(Error, "Failed to create {} Shader program '{}' ({}).", ::ToString(type), String(initializer.Name), name);
return true;
}

View File

@@ -49,7 +49,8 @@ GPUContextDX11::GPUContextDX11(GPUDeviceDX11* device, ID3D11DeviceContext* conte
, _omDirtyFlag(false)
, _rtCount(0)
, _rtDepth(nullptr)
, _srDirtyFlag(false)
, _srMaskDirtyGraphics(0)
, _srMaskDirtyCompute(0)
, _uaDirtyFlag(false)
, _cbDirtyFlag(false)
, _currentState(nullptr)
@@ -80,8 +81,9 @@ void GPUContextDX11::FrameBegin()
// Setup
_omDirtyFlag = false;
_uaDirtyFlag = false;
_srDirtyFlag = false;
_cbDirtyFlag = false;
_srMaskDirtyGraphics = 0;
_srMaskDirtyCompute = 0;
_rtCount = 0;
_currentState = nullptr;
_rtDepth = nullptr;
@@ -97,9 +99,13 @@ void GPUContextDX11::FrameBegin()
CurrentRasterizerState = nullptr;
CurrentDepthStencilState = nullptr;
CurrentVS = nullptr;
#if GPU_ALLOW_TESSELLATION_SHADERS
CurrentHS = nullptr;
CurrentDS = nullptr;
#endif
#if GPU_ALLOW_GEOMETRY_SHADERS
CurrentGS = nullptr;
#endif
CurrentPS = nullptr;
CurrentCS = nullptr;
CurrentPrimitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED;
@@ -117,7 +123,9 @@ void GPUContextDX11::FrameBegin()
_device->_samplerShadowPCF
};
_context->VSSetSamplers(0, ARRAY_COUNT(samplers), samplers);
#if GPU_ALLOW_TESSELLATION_SHADERS
_context->DSSetSamplers(0, ARRAY_COUNT(samplers), samplers);
#endif
_context->PSSetSamplers(0, ARRAY_COUNT(samplers), samplers);
_context->CSSetSamplers(0, ARRAY_COUNT(samplers), samplers);
}
@@ -284,13 +292,18 @@ void GPUContextDX11::SetStencilRef(uint32 value)
void GPUContextDX11::ResetSR()
{
_srDirtyFlag = false;
_srMaskDirtyGraphics = MAX_uint32;
_srMaskDirtyCompute = MAX_uint32;
Platform::MemoryClear(_srHandles, sizeof(_srHandles));
_context->VSSetShaderResources(0, ARRAY_COUNT(_srHandles), _srHandles);
#if GPU_ALLOW_TESSELLATION_SHADERS
_context->HSSetShaderResources(0, ARRAY_COUNT(_srHandles), _srHandles);
_context->DSSetShaderResources(0, ARRAY_COUNT(_srHandles), _srHandles);
#endif
#if GPU_ALLOW_GEOMETRY_SHADERS
_context->GSSetShaderResources(0, ARRAY_COUNT(_srHandles), _srHandles);
#endif
_context->PSSetShaderResources(0, ARRAY_COUNT(_srHandles), _srHandles);
_context->CSSetShaderResources(0, ARRAY_COUNT(_srHandles), _srHandles);
}
@@ -310,9 +323,13 @@ void GPUContextDX11::ResetCB()
Platform::MemoryClear(_cbHandles, sizeof(_cbHandles));
_context->VSSetConstantBuffers(0, ARRAY_COUNT(_cbHandles), _cbHandles);
#if GPU_ALLOW_TESSELLATION_SHADERS
_context->HSSetConstantBuffers(0, ARRAY_COUNT(_cbHandles), _cbHandles);
_context->DSSetConstantBuffers(0, ARRAY_COUNT(_cbHandles), _cbHandles);
#endif
#if GPU_ALLOW_GEOMETRY_SHADERS
_context->GSSetConstantBuffers(0, ARRAY_COUNT(_cbHandles), _cbHandles);
#endif
_context->PSSetConstantBuffers(0, ARRAY_COUNT(_cbHandles), _cbHandles);
_context->CSSetConstantBuffers(0, ARRAY_COUNT(_cbHandles), _cbHandles);
}
@@ -341,7 +358,8 @@ void GPUContextDX11::BindSR(int32 slot, GPUResourceView* view)
auto handle = view ? ((IShaderResourceDX11*)view->GetNativePtr())->SRV() : nullptr;
if (_srHandles[slot] != handle)
{
_srDirtyFlag = true;
_srMaskDirtyGraphics |= 1 << slot;
_srMaskDirtyCompute |= 1 << slot;
_srHandles[slot] = handle;
if (view)
*view->LastRenderTime = _lastRenderTime;
@@ -399,7 +417,9 @@ void GPUContextDX11::BindSampler(int32 slot, GPUSampler* sampler)
{
const auto samplerDX11 = sampler ? static_cast<GPUSamplerDX11*>(sampler)->SamplerState : nullptr;
_context->VSSetSamplers(slot, 1, &samplerDX11);
#if GPU_ALLOW_TESSELLATION_SHADERS
_context->DSSetSamplers(slot, 1, &samplerDX11);
#endif
_context->PSSetSamplers(slot, 1, &samplerDX11);
_context->CSSetSamplers(slot, 1, &samplerDX11);
}
@@ -538,9 +558,13 @@ void GPUContextDX11::SetState(GPUPipelineState* state)
ID3D11RasterizerState* rasterizerState = nullptr;
ID3D11DepthStencilState* depthStencilState = nullptr;
GPUShaderProgramVSDX11* vs = nullptr;
#if GPU_ALLOW_TESSELLATION_SHADERS
GPUShaderProgramHSDX11* hs = nullptr;
GPUShaderProgramDSDX11* ds = nullptr;
#endif
#if GPU_ALLOW_GEOMETRY_SHADERS
GPUShaderProgramGSDX11* gs = nullptr;
#endif
GPUShaderProgramPSDX11* ps = nullptr;
D3D11_PRIMITIVE_TOPOLOGY primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED;
@@ -554,9 +578,13 @@ void GPUContextDX11::SetState(GPUPipelineState* state)
ASSERT(_currentState->VS != nullptr);
vs = _currentState->VS;
#if GPU_ALLOW_TESSELLATION_SHADERS
hs = _currentState->HS;
ds = _currentState->DS;
#endif
#if GPU_ALLOW_GEOMETRY_SHADERS
gs = _currentState->GS;
#endif
ps = _currentState->PS;
primitiveTopology = _currentState->PrimitiveTopology;
@@ -590,6 +618,7 @@ void GPUContextDX11::SetState(GPUPipelineState* state)
_context->VSSetShader(vs ? vs->GetBufferHandleDX11() : nullptr, nullptr, 0);
_context->IASetInputLayout(vs ? vs->GetInputLayoutDX11() : nullptr);
}
#if GPU_ALLOW_TESSELLATION_SHADERS
if (CurrentHS != hs)
{
#if DX11_CLEAR_SR_ON_STAGE_DISABLE
@@ -612,6 +641,8 @@ void GPUContextDX11::SetState(GPUPipelineState* state)
CurrentDS = ds;
_context->DSSetShader(ds ? ds->GetBufferHandleDX11() : nullptr, nullptr, 0);
}
#endif
#if GPU_ALLOW_GEOMETRY_SHADERS
if (CurrentGS != gs)
{
#if DX11_CLEAR_SR_ON_STAGE_DISABLE
@@ -623,6 +654,7 @@ void GPUContextDX11::SetState(GPUPipelineState* state)
CurrentGS = gs;
_context->GSSetShader(gs ? gs->GetBufferHandleDX11() : nullptr, nullptr, 0);
}
#endif
if (CurrentPS != ps)
{
#if DX11_CLEAR_SR_ON_STAGE_DISABLE
@@ -669,7 +701,9 @@ void GPUContextDX11::ClearState()
_device->_samplerShadowPCF
};
_context->VSSetSamplers(0, ARRAY_COUNT(samplers), samplers);
#if GPU_ALLOW_TESSELLATION_SHADERS
_context->DSSetSamplers(0, ARRAY_COUNT(samplers), samplers);
#endif
_context->PSSetSamplers(0, ARRAY_COUNT(samplers), samplers);
_context->CSSetSamplers(0, ARRAY_COUNT(samplers), samplers);
#endif
@@ -804,25 +838,32 @@ void GPUContextDX11::CopySubresource(GPUResource* dstResource, uint32 dstSubreso
void GPUContextDX11::flushSRVs()
{
if (_srDirtyFlag)
#define FLUSH_STAGE(STAGE) if (Current##STAGE) _context->STAGE##SetShaderResources(0, ARRAY_COUNT(_srHandles), _srHandles)
if (CurrentCS)
{
_srDirtyFlag = false;
// Flush with the driver
// TODO: don't bind SRV to all stages and all slots (use mask for bind diff?)
#define FLUSH_STAGE(STAGE) \
if (Current##STAGE) \
{ \
_context->STAGE##SetShaderResources(0, ARRAY_COUNT(_srHandles), _srHandles); \
}
FLUSH_STAGE(VS);
FLUSH_STAGE(HS);
FLUSH_STAGE(DS);
FLUSH_STAGE(GS);
FLUSH_STAGE(PS);
FLUSH_STAGE(CS);
#undef FLUSH_STAGE
if (_srMaskDirtyCompute)
{
_srMaskDirtyCompute = 0;
FLUSH_STAGE(CS);
}
}
else
{
if (_srMaskDirtyGraphics)
{
_srMaskDirtyGraphics = 0;
FLUSH_STAGE(VS);
#if GPU_ALLOW_TESSELLATION_SHADERS
FLUSH_STAGE(HS);
FLUSH_STAGE(DS);
#endif
#if GPU_ALLOW_GEOMETRY_SHADERS
FLUSH_STAGE(GS);
#endif
FLUSH_STAGE(PS);
}
}
#undef FLUSH_STAGE
}
void GPUContextDX11::flushUAVs()
@@ -848,15 +889,15 @@ void GPUContextDX11::flushCBs()
// Flush with the driver
// TODO: don't bind CBV to all stages and all slots (use mask for bind diff? eg. cache mask from last flush and check if there is a diff + include mask from diff slots?)
#define FLUSH_STAGE(STAGE) \
if (Current##STAGE) \
{ \
_context->STAGE##SetConstantBuffers(0, ARRAY_COUNT(_cbHandles), _cbHandles); \
}
#define FLUSH_STAGE(STAGE) if (Current##STAGE) _context->STAGE##SetConstantBuffers(0, ARRAY_COUNT(_cbHandles), _cbHandles)
FLUSH_STAGE(VS);
#if GPU_ALLOW_TESSELLATION_SHADERS
FLUSH_STAGE(HS);
FLUSH_STAGE(DS);
#endif
#if GPU_ALLOW_GEOMETRY_SHADERS
FLUSH_STAGE(GS);
#endif
FLUSH_STAGE(PS);
FLUSH_STAGE(CS);
#undef FLUSH_STAGE

View File

@@ -32,7 +32,8 @@ private:
ID3D11RenderTargetView* _rtHandles[GPU_MAX_RT_BINDED];
// Shader Resources
bool _srDirtyFlag;
uint32 _srMaskDirtyGraphics;
uint32 _srMaskDirtyCompute;
ID3D11ShaderResourceView* _srHandles[GPU_MAX_SR_BINDED];
// Unordered Access
@@ -55,9 +56,13 @@ private:
ID3D11RasterizerState* CurrentRasterizerState;
ID3D11DepthStencilState* CurrentDepthStencilState;
GPUShaderProgramVSDX11* CurrentVS;
#if GPU_ALLOW_TESSELLATION_SHADERS
GPUShaderProgramHSDX11* CurrentHS;
GPUShaderProgramDSDX11* CurrentDS;
#endif
#if GPU_ALLOW_GEOMETRY_SHADERS
GPUShaderProgramGSDX11* CurrentGS;
#endif
GPUShaderProgramPSDX11* CurrentPS;
GPUShaderProgramCSDX11* CurrentCS;
D3D11_PRIMITIVE_TOPOLOGY CurrentPrimitiveTopology;

View File

@@ -8,9 +8,13 @@ void GPUPipelineStateDX11::OnReleaseGPU()
{
BlendState = nullptr;
VS = nullptr;
#if GPU_ALLOW_TESSELLATION_SHADERS
HS = nullptr;
DS = nullptr;
#endif
#if GPU_ALLOW_GEOMETRY_SHADERS
GS = nullptr;
#endif
PS = nullptr;
}
@@ -30,9 +34,13 @@ bool GPUPipelineStateDX11::Init(const Description& desc)
// Cache shaders
VS = (GPUShaderProgramVSDX11*)desc.VS;
#if GPU_ALLOW_TESSELLATION_SHADERS
HS = desc.HS ? (GPUShaderProgramHSDX11*)desc.HS : nullptr;
DS = desc.DS ? (GPUShaderProgramDSDX11*)desc.DS : nullptr;
#endif
#if GPU_ALLOW_GEOMETRY_SHADERS
GS = desc.GS ? (GPUShaderProgramGSDX11*)desc.GS : nullptr;
#endif
PS = desc.PS ? (GPUShaderProgramPSDX11*)desc.PS : nullptr;
// Primitive Topology
@@ -44,8 +52,10 @@ bool GPUPipelineStateDX11::Init(const Description& desc)
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST,
};
PrimitiveTopology = D3D11_primTypes[static_cast<int32>(desc.PrimitiveTopology)];
#if GPU_ALLOW_TESSELLATION_SHADERS
if (HS)
PrimitiveTopology = (D3D11_PRIMITIVE_TOPOLOGY)((int32)D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST + (HS->GetControlPointsCount() - 1));
#endif
// States
DepthStencilStateIndex = static_cast<int32>(desc.DepthFunc) + (desc.DepthEnable ? 0 : 9) + (desc.DepthWriteEnable ? 0 : 18);

View File

@@ -19,9 +19,13 @@ public:
int32 RasterizerStateIndex;
ID3D11BlendState* BlendState = nullptr;
GPUShaderProgramVSDX11* VS = nullptr;
#if GPU_ALLOW_TESSELLATION_SHADERS
GPUShaderProgramHSDX11* HS = nullptr;
GPUShaderProgramDSDX11* DS = nullptr;
#endif
#if GPU_ALLOW_GEOMETRY_SHADERS
GPUShaderProgramGSDX11* GS = nullptr;
#endif
GPUShaderProgramPSDX11* PS = nullptr;
D3D11_PRIMITIVE_TOPOLOGY PrimitiveTopology;

View File

@@ -119,6 +119,13 @@ GPUShaderProgram* GPUShaderDX11::CreateGPUShaderProgram(ShaderStage type, const
shader = New<GPUShaderProgramDSDX11>(initializer, buffer);
break;
}
#else
case ShaderStage::Hull:
{
int32 controlPointsCount;
stream.ReadInt32(&controlPointsCount);
break;
}
#endif
#if GPU_ALLOW_GEOMETRY_SHADERS
case ShaderStage::Geometry:

View File

@@ -163,9 +163,13 @@ bool GPUPipelineStateDX12::Init(const Description& desc)
if (shader->Header.UaDimensions[i]) \
Header.UaDimensions[i] = shader->Header.UaDimensions[i]; \
}
#if GPU_ALLOW_TESSELLATION_SHADERS
INIT_SHADER_STAGE(HS, GPUShaderProgramHSDX12);
INIT_SHADER_STAGE(DS, GPUShaderProgramDSDX12);
#endif
#if GPU_ALLOW_GEOMETRY_SHADERS
INIT_SHADER_STAGE(GS, GPUShaderProgramGSDX12);
#endif
INIT_SHADER_STAGE(VS, GPUShaderProgramVSDX12);
INIT_SHADER_STAGE(PS, GPUShaderProgramPSDX12);
const static D3D12_PRIMITIVE_TOPOLOGY_TYPE primTypes1[] =
@@ -184,11 +188,13 @@ bool GPUPipelineStateDX12::Init(const Description& desc)
};
psDesc.PrimitiveTopologyType = primTypes1[(int32)desc.PrimitiveTopology];
PrimitiveTopology = primTypes2[(int32)desc.PrimitiveTopology];
#if GPU_ALLOW_TESSELLATION_SHADERS
if (desc.HS)
{
psDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH;
PrimitiveTopology = (D3D_PRIMITIVE_TOPOLOGY)((int32)D3D_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST + (desc.HS->GetControlPointsCount() - 1));
}
#endif
// Depth State
psDesc.DepthStencilState.DepthEnable = !!desc.DepthEnable;

View File

@@ -98,6 +98,13 @@ GPUShaderProgram* GPUShaderDX12::CreateGPUShaderProgram(ShaderStage type, const
shader = New<GPUShaderProgramDSDX12>(initializer, header, cacheBytes, cacheSize);
break;
}
#else
case ShaderStage::Hull:
{
int32 controlPointsCount;
stream.ReadInt32(&controlPointsCount);
break;
}
#endif
#if GPU_ALLOW_GEOMETRY_SHADERS
case ShaderStage::Geometry:

View File

@@ -280,8 +280,10 @@ bool GPUPipelineStateVulkan::Init(const Description& desc)
_descInputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
break;
}
#if GPU_ALLOW_TESSELLATION_SHADERS
if (desc.HS)
_descInputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
#endif
_desc.pInputAssemblyState = &_descInputAssembly;
#if GPU_ALLOW_TESSELLATION_SHADERS

View File

@@ -207,6 +207,13 @@ GPUShaderProgram* GPUShaderVulkan::CreateGPUShaderProgram(ShaderStage type, cons
shader = New<GPUShaderProgramDSVulkan>(_device, initializer, header->DescriptorInfo, shaderModule);
break;
}
#else
case ShaderStage::Hull:
{
int32 controlPointsCount;
stream.ReadInt32(&controlPointsCount);
break;
}
#endif
#if GPU_ALLOW_GEOMETRY_SHADERS
case ShaderStage::Geometry:

View File

@@ -87,7 +87,7 @@ bool ColorGradingPass::Init()
bool ColorGradingPass::setupResources()
{
// Wait for shader
if (!_shader->IsLoaded())
if (!_shader || !_shader->IsLoaded())
return true;
const auto shader = _shader->GetShader();

View File

@@ -46,7 +46,6 @@ void EyeAdaptationPass::Render(RenderContext& renderContext, GPUTexture* colorBu
renderContext.Buffers->LastEyeAdaptationTime = 0.0f;
if ((view.Flags & ViewFlags::EyeAdaptation) == ViewFlags::None || settings.Mode == EyeAdaptationMode::None || checkIfSkipPass())
return;
PROFILE_GPU_CPU("Eye Adaptation");
// Setup constants
@@ -218,14 +217,15 @@ String EyeAdaptationPass::ToString() const
bool EyeAdaptationPass::Init()
{
_canUseHistogram = GPUDevice::Instance->Limits.HasCompute;
auto device = GPUDevice::Instance;
_canUseHistogram = device->Limits.HasCompute;
// Create pipeline states
_psManual = GPUDevice::Instance->CreatePipelineState();
_psLuminanceMap = GPUDevice::Instance->CreatePipelineState();
_psBlendLuminance = GPUDevice::Instance->CreatePipelineState();
_psApplyLuminance = GPUDevice::Instance->CreatePipelineState();
_psHistogram = GPUDevice::Instance->CreatePipelineState();
_psManual = device->CreatePipelineState();
_psLuminanceMap = device->CreatePipelineState();
_psBlendLuminance = device->CreatePipelineState();
_psApplyLuminance = device->CreatePipelineState();
_psHistogram = device->CreatePipelineState();
// Load shaders
_shader = Content::LoadAsyncInternal<Shader>(TEXT("Shaders/EyeAdaptation"));

View File

@@ -29,7 +29,6 @@ GPUBuffer* HistogramPass::Render(RenderContext& renderContext, GPUTexture* color
auto context = device->GetMainContext();
if (checkIfSkipPass() || !_isSupported)
return nullptr;
PROFILE_GPU_CPU("Histogram");
// Setup constants