Add statically disabled geometry shaders on mobile

This commit is contained in:
Wojtek Figat
2024-03-30 22:08:44 +01:00
parent 369c19bd5d
commit e1944bce96
17 changed files with 74 additions and 8 deletions

View File

@@ -45,6 +45,11 @@
#define GPU_ALLOW_TESSELLATION_SHADERS 1
#endif
// True if allow geometry shaders
#ifndef GPU_ALLOW_GEOMETRY_SHADERS
#define GPU_ALLOW_GEOMETRY_SHADERS 1
#endif
// Enable/disable creating GPU resources on separate threads (otherwise only the main thread can be used)
#define GPU_ENABLE_ASYNC_RESOURCES_CREATION 1

View File

@@ -103,7 +103,11 @@ public:
/// <returns>The shader object.</returns>
API_FUNCTION() FORCE_INLINE GPUShaderProgramHS* GetHS(const StringAnsiView& name, int32 permutationIndex = 0) const
{
#if GPU_ALLOW_TESSELLATION_SHADERS
return static_cast<GPUShaderProgramHS*>(GetShader(ShaderStage::Hull, name, permutationIndex));
#else
return nullptr;
#endif
}
/// <summary>
@@ -114,7 +118,11 @@ public:
/// <returns>The shader object.</returns>
API_FUNCTION() FORCE_INLINE GPUShaderProgramDS* GetDS(const StringAnsiView& name, int32 permutationIndex = 0) const
{
#if GPU_ALLOW_TESSELLATION_SHADERS
return static_cast<GPUShaderProgramDS*>(GetShader(ShaderStage::Domain, name, permutationIndex));
#else
return nullptr;
#endif
}
/// <summary>
@@ -125,7 +133,11 @@ public:
/// <returns>The shader object.</returns>
API_FUNCTION() FORCE_INLINE GPUShaderProgramGS* GetGS(const StringAnsiView& name, int32 permutationIndex = 0) const
{
#if GPU_ALLOW_GEOMETRY_SHADERS
return static_cast<GPUShaderProgramGS*>(GetShader(ShaderStage::Geometry, name, permutationIndex));
#else
return nullptr;
#endif
}
/// <summary>

View File

@@ -352,7 +352,7 @@ bool GPUDeviceDX11::Init()
_device->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS2, &featureDataD3D11Options2, sizeof(featureDataD3D11Options2));
limits.HasCompute = d3D10XHardwareOptions.ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x != 0;
limits.HasTessellation = GPU_ALLOW_TESSELLATION_SHADERS;
limits.HasGeometryShaders = true;
limits.HasGeometryShaders = GPU_ALLOW_GEOMETRY_SHADERS;
limits.HasInstancing = true;
limits.HasVolumeTextureRendering = true;
limits.HasDrawIndirect = true;
@@ -376,7 +376,7 @@ bool GPUDeviceDX11::Init()
{
limits.HasCompute = false;
limits.HasTessellation = false;
limits.HasGeometryShaders = true;
limits.HasGeometryShaders = GPU_ALLOW_GEOMETRY_SHADERS;
limits.HasInstancing = true;
limits.HasVolumeTextureRendering = false;
limits.HasDrawIndirect = false;

View File

@@ -92,6 +92,7 @@ GPUShaderProgram* GPUShaderDX11::CreateGPUShaderProgram(ShaderStage type, const
shader = New<GPUShaderProgramVSDX11>(initializer, buffer, inputLayout, inputLayoutSize);
break;
}
#if GPU_ALLOW_TESSELLATION_SHADERS
case ShaderStage::Hull:
{
// Read control points
@@ -118,6 +119,8 @@ GPUShaderProgram* GPUShaderDX11::CreateGPUShaderProgram(ShaderStage type, const
shader = New<GPUShaderProgramDSDX11>(initializer, buffer);
break;
}
#endif
#if GPU_ALLOW_GEOMETRY_SHADERS
case ShaderStage::Geometry:
{
// Create shader
@@ -129,6 +132,7 @@ GPUShaderProgram* GPUShaderDX11::CreateGPUShaderProgram(ShaderStage type, const
shader = New<GPUShaderProgramGSDX11>(initializer, buffer);
break;
}
#endif
case ShaderStage::Pixel:
{
// Create shader

View File

@@ -122,6 +122,7 @@ public:
}
};
#if GPU_ALLOW_TESSELLATION_SHADERS
/// <summary>
/// Hull Shader for DirectX 11 backend.
/// </summary>
@@ -159,7 +160,9 @@ public:
{
}
};
#endif
#if GPU_ALLOW_GEOMETRY_SHADERS
/// <summary>
/// Geometry Shader for DirectX 11 backend.
/// </summary>
@@ -177,6 +180,7 @@ public:
{
}
};
#endif
/// <summary>
/// Pixel Shader for DirectX 11 backend.

View File

@@ -374,7 +374,7 @@ bool GPUDeviceDX12::Init()
auto& limits = Limits;
limits.HasCompute = true;
limits.HasTessellation = GPU_ALLOW_TESSELLATION_SHADERS;
limits.HasGeometryShaders = true;
limits.HasGeometryShaders = GPU_ALLOW_GEOMETRY_SHADERS;
limits.HasInstancing = true;
limits.HasVolumeTextureRendering = true;
limits.HasDrawIndirect = true;

View File

@@ -85,6 +85,7 @@ GPUShaderProgram* GPUShaderDX12::CreateGPUShaderProgram(ShaderStage type, const
shader = New<GPUShaderProgramVSDX12>(initializer, header, cacheBytes, cacheSize, inputLayout, inputLayoutSize);
break;
}
#if GPU_ALLOW_TESSELLATION_SHADERS
case ShaderStage::Hull:
{
int32 controlPointsCount;
@@ -97,11 +98,14 @@ GPUShaderProgram* GPUShaderDX12::CreateGPUShaderProgram(ShaderStage type, const
shader = New<GPUShaderProgramDSDX12>(initializer, header, cacheBytes, cacheSize);
break;
}
#endif
#if GPU_ALLOW_GEOMETRY_SHADERS
case ShaderStage::Geometry:
{
shader = New<GPUShaderProgramGSDX12>(initializer, header, cacheBytes, cacheSize);
break;
}
#endif
case ShaderStage::Pixel:
{
shader = New<GPUShaderProgramPSDX12>(initializer, header, cacheBytes, cacheSize);

View File

@@ -79,6 +79,7 @@ public:
}
};
#if GPU_ALLOW_TESSELLATION_SHADERS
/// <summary>
/// Hull Shader for DirectX 12 backend.
/// </summary>
@@ -105,7 +106,9 @@ public:
{
}
};
#endif
#if GPU_ALLOW_GEOMETRY_SHADERS
/// <summary>
/// Geometry Shader for DirectX 12 backend.
/// </summary>
@@ -118,6 +121,7 @@ public:
{
}
};
#endif
/// <summary>
/// Pixel Shader for DirectX 12 backend.

View File

@@ -28,8 +28,10 @@ namespace DescriptorSet
Vertex,
// Pixel shader stage
Pixel,
#if GPU_ALLOW_GEOMETRY_SHADERS
// Geometry shader stage
Geometry,
#endif
#if GPU_ALLOW_TESSELLATION_SHADERS
// Hull shader stage
Hull,

View File

@@ -1691,10 +1691,10 @@ bool GPUDeviceVulkan::Init()
#else
limits.HasTessellation = false;
#endif
#if PLATFORM_ANDROID || PLATFORM_IOS
limits.HasGeometryShaders = false; // Don't even try GS on mobile
#if GPU_ALLOW_GEOMETRY_SHADERS
limits.HasGeometryShaders = !!PhysicalDeviceFeatures.geometryShader && PhysicalDeviceLimits.maxBoundDescriptorSets > (uint32_t)DescriptorSet::Geometry;
#else
limits.HasGeometryShaders = !!PhysicalDeviceFeatures.geometryShader;
limits.HasGeometryShaders = false;
#endif
limits.HasInstancing = true;
limits.HasVolumeTextureRendering = true;

View File

@@ -141,7 +141,9 @@ PipelineLayoutVulkan* GPUPipelineStateVulkan::GetLayout()
INIT_SHADER_STAGE(Hull, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
INIT_SHADER_STAGE(Domain, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
#endif
#if GPU_ALLOW_GEOMETRY_SHADERS
INIT_SHADER_STAGE(Geometry, VK_SHADER_STAGE_GEOMETRY_BIT);
#endif
INIT_SHADER_STAGE(Pixel, VK_SHADER_STAGE_FRAGMENT_BIT);
#undef INIT_SHADER_STAGE
_layout = _device->GetOrCreateLayout(descriptorSetLayoutInfo);
@@ -257,7 +259,9 @@ bool GPUPipelineStateVulkan::Init(const Description& desc)
INIT_SHADER_STAGE(HS, Hull, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
INIT_SHADER_STAGE(DS, Domain, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
#endif
#if GPU_ALLOW_GEOMETRY_SHADERS
INIT_SHADER_STAGE(GS, Geometry, VK_SHADER_STAGE_GEOMETRY_BIT);
#endif
INIT_SHADER_STAGE(PS, Pixel, VK_SHADER_STAGE_FRAGMENT_BIT);
#undef INIT_SHADER_STAGE
_desc.pStages = _shaderStages;

View File

@@ -107,6 +107,7 @@ public:
}
};
#if GPU_ALLOW_TESSELLATION_SHADERS
/// <summary>
/// Hull Shader for Vulkan backend.
/// </summary>
@@ -146,7 +147,9 @@ public:
{
}
};
#endif
#if GPU_ALLOW_GEOMETRY_SHADERS
/// <summary>
/// Geometry Shader for Vulkan backend.
/// </summary>
@@ -165,6 +168,7 @@ public:
{
}
};
#endif
/// <summary>
/// Pixel Shader for Vulkan backend.

View File

@@ -194,6 +194,7 @@ GPUShaderProgram* GPUShaderVulkan::CreateGPUShaderProgram(ShaderStage type, cons
break;
}
#if GPU_ALLOW_TESSELLATION_SHADERS
case ShaderStage::Hull:
{
int32 controlPointsCount;
@@ -206,11 +207,14 @@ GPUShaderProgram* GPUShaderVulkan::CreateGPUShaderProgram(ShaderStage type, cons
shader = New<GPUShaderProgramDSVulkan>(_device, initializer, header->DescriptorInfo, shaderModule);
break;
}
#endif
#if GPU_ALLOW_GEOMETRY_SHADERS
case ShaderStage::Geometry:
{
shader = New<GPUShaderProgramGSVulkan>(_device, initializer, header->DescriptorInfo, shaderModule);
break;
}
#endif
case ShaderStage::Pixel:
{
shader = New<GPUShaderProgramPSVulkan>(_device, initializer, header->DescriptorInfo, shaderModule);

View File

@@ -35,4 +35,7 @@
#define USE_MONO_AOT_MODE MONO_AOT_MODE_NONE
#define GPU_ALLOW_TESSELLATION_SHADERS 0 // Tess on mobile is not well supported
#define GPU_ALLOW_GEOMETRY_SHADERS 0 // Don't even try GS on mobile
#endif

View File

@@ -18,7 +18,7 @@
#define USE_MONO_AOT 1
#define USE_MONO_AOT_MODE MONO_AOT_MODE_FULL
// MoltenVK has artifacts when using tess so disable it
#define GPU_ALLOW_TESSELLATION_SHADERS 0
#define GPU_ALLOW_TESSELLATION_SHADERS 0 // MoltenVK has artifacts when using tess so disable it
#define GPU_ALLOW_GEOMETRY_SHADERS 0 // Don't even try GS on mobile
#endif

View File

@@ -52,7 +52,9 @@ bool ColorGradingPass::Init()
{
// Detect if can use volume texture (3d) for a LUT (faster, requires geometry shader)
const auto device = GPUDevice::Instance;
#if GPU_ALLOW_GEOMETRY_SHADERS
_useVolumeTexture = device->Limits.HasGeometryShaders && device->Limits.HasVolumeTextureRendering;
#endif
// Pick a proper LUT pixels format
_lutFormat = PixelFormat::R10G10B10A2_UNorm;
@@ -101,6 +103,7 @@ bool ColorGradingPass::setupResources()
if (!_psLut.IsValid())
{
StringAnsiView psName;
#if GPU_ALLOW_GEOMETRY_SHADERS
if (_useVolumeTexture)
{
psDesc.VS = shader->GetVS("VS_WriteToSlice");
@@ -108,6 +111,7 @@ bool ColorGradingPass::setupResources()
psName = "PS_Lut3D";
}
else
#endif
{
psName = "PS_Lut2D";
}
@@ -139,11 +143,13 @@ GPUTexture* ColorGradingPass::RenderLUT(RenderContext& renderContext)
// For a 3D texture, the viewport is 16x16 (per slice), for a 2D texture, it's unwrapped to 256x16
const int32 LutSize = 32; // this must match value in shader (see ColorGrading.shader and PostProcessing.shader)
GPUTextureDescription lutDesc;
#if GPU_ALLOW_GEOMETRY_SHADERS
if (_useVolumeTexture)
{
lutDesc = GPUTextureDescription::New3D(LutSize, LutSize, LutSize, 1, _lutFormat);
}
else
#endif
{
lutDesc = GPUTextureDescription::New2D(LutSize * LutSize, LutSize, 1, _lutFormat);
}
@@ -192,6 +198,7 @@ GPUTexture* ColorGradingPass::RenderLUT(RenderContext& renderContext)
context->BindSR(0, useLut ? colorGrading.LutTexture->GetTexture() : nullptr);
// Draw
#if GPU_ALLOW_GEOMETRY_SHADERS
if (_useVolumeTexture)
{
context->SetRenderTarget(lut->ViewVolume());
@@ -201,6 +208,7 @@ GPUTexture* ColorGradingPass::RenderLUT(RenderContext& renderContext)
context->DrawFullscreenTriangle(numInstances);
}
else
#endif
{
context->SetRenderTarget(lut->View());
context->DrawFullscreenTriangle();

View File

@@ -63,12 +63,14 @@ bool DepthOfFieldPass::Init()
{
_psDofDepthBlurGeneration = GPUDevice::Instance->CreatePipelineState();
_psDoNotGenerateBokeh = GPUDevice::Instance->CreatePipelineState();
#if GPU_ALLOW_GEOMETRY_SHADERS
if (_platformSupportsBokeh)
{
_psBokehGeneration = GPUDevice::Instance->CreatePipelineState();
_psBokeh = GPUDevice::Instance->CreatePipelineState();
_psBokehComposite = GPUDevice::Instance->CreatePipelineState();
}
#endif
}
// Load shaders
@@ -137,6 +139,7 @@ bool DepthOfFieldPass::setupResources()
if (_psDoNotGenerateBokeh->Init(psDesc))
return true;
}
#if GPU_ALLOW_GEOMETRY_SHADERS
if (_platformSupportsBokeh)
{
if (!_psBokehGeneration->IsValid())
@@ -171,6 +174,7 @@ bool DepthOfFieldPass::setupResources()
if (_bokehIndirectArgsBuffer->Init(GPUBufferDescription::Argument(&indirectArgsBufferInitData, sizeof(indirectArgsBufferInitData))))
return true;
}
#endif
return false;
}
@@ -296,6 +300,7 @@ void DepthOfFieldPass::Render(RenderContext& renderContext, GPUTexture*& frame,
auto dofFormat = renderContext.Buffers->GetOutputFormat();
tempDesc = GPUTextureDescription::New2D(dofWidth, dofHeight, dofFormat);
#if GPU_ALLOW_GEOMETRY_SHADERS
// Do the bokeh point generation, or just do a copy if disabled
bool isBokehGenerationEnabled = dofSettings.BokehEnabled && _platformSupportsBokeh && dofSettings.BokehBrightness > 0.0f && dofSettings.BokehSize > 0.0f;
if (isBokehGenerationEnabled)
@@ -329,6 +334,7 @@ void DepthOfFieldPass::Render(RenderContext& renderContext, GPUTexture*& frame,
context->DrawFullscreenTriangle();
}
else
#endif
{
// Generate bokeh points
context->BindSR(0, frame);
@@ -380,6 +386,7 @@ void DepthOfFieldPass::Render(RenderContext& renderContext, GPUTexture*& frame,
context->ResetSR();
}
#if GPU_ALLOW_GEOMETRY_SHADERS
// Render the bokeh points
if (isBokehGenerationEnabled)
{
@@ -418,6 +425,7 @@ void DepthOfFieldPass::Render(RenderContext& renderContext, GPUTexture*& frame,
RenderTargetPool::Release(bokehTarget);
Swap(frame, tmp);
}
#endif
RenderTargetPool::Release(depthBlurTarget);
}