Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GenerateMips updated to handle sRGB better #246

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions Src/ResourceUploadBatch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,16 @@ namespace
{
#ifdef _GAMING_XBOX_SCARLETT
#include "XboxGamingScarlettGenerateMips_main.inc"
#include "XboxGamingScarlettGenerateMips_sRGB.inc"
#elif defined(_GAMING_XBOX)
#include "XboxGamingXboxOneGenerateMips_main.inc"
#include "XboxGamingXboxOneGenerateMips_sRGB.inc"
#elif defined(_XBOX_ONE) && defined(_TITLE)
#include "XboxOneGenerateMips_main.inc"
#include "XboxOneGenerateMips_sRGB.inc"
#else
#include "GenerateMips_main.inc"
#include "GenerateMips_sRGB.inc"
#endif

bool FormatIsUAVCompatible(_In_ ID3D12Device* device, bool typedUAVLoadAdditionalFormats, DXGI_FORMAT format) noexcept
Expand Down Expand Up @@ -222,12 +226,14 @@ namespace

ComPtr<ID3D12RootSignature> rootSignature;
ComPtr<ID3D12PipelineState> generateMipsPSO;
ComPtr<ID3D12PipelineState> generateMipsPSO_sRGB;

GenerateMipsResources(
_In_ ID3D12Device* device)
{
rootSignature = CreateGenMipsRootSignature(device);
generateMipsPSO = CreateGenMipsPipelineState(device, rootSignature.Get(), GenerateMips_main, sizeof(GenerateMips_main));
generateMipsPSO_sRGB = CreateGenMipsPipelineState(device, rootSignature.Get(), GenerateMips_sRGB, sizeof(GenerateMips_sRGB));
}

GenerateMipsResources(const GenerateMipsResources&) = delete;
Expand Down Expand Up @@ -476,7 +482,7 @@ class ResourceUploadBatch::Impl
// This is true of BGRA or sRGB textures, for example.
if (uavCompat)
{
GenerateMips_UnorderedAccessPath(resource);
GenerateMips_UnorderedAccessPath(resource, false);
}
else if (!mTypedUAVLoadAdditionalFormats)
{
Expand Down Expand Up @@ -645,7 +651,8 @@ class ResourceUploadBatch::Impl
private:
// Resource is UAV compatible
void GenerateMips_UnorderedAccessPath(
_In_ ID3D12Resource* resource)
_In_ ID3D12Resource* resource,
bool srgb)
{
#if defined(_MSC_VER) || !defined(_WIN32)
const auto desc = resource->GetDesc();
Expand Down Expand Up @@ -759,7 +766,7 @@ class ResourceUploadBatch::Impl
uav2srvDesc.Transition.StateAfter = D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE;

// based on format, select srgb or not
ComPtr<ID3D12PipelineState> pso = mGenMipsResources->generateMipsPSO;
ComPtr<ID3D12PipelineState> pso = srgb ? mGenMipsResources->generateMipsPSO_sRGB : mGenMipsResources->generateMipsPSO;

// Set up state
mList->SetComputeRootSignature(mGenMipsResources->rootSignature.Get());
Expand Down Expand Up @@ -899,7 +906,7 @@ class ResourceUploadBatch::Impl
TransitionResource(mList.Get(), resourceCopy.Get(), D3D12_RESOURCE_STATE_COPY_DEST, originalState);

// Generate the mips
GenerateMips_UnorderedAccessPath(resourceCopy.Get());
GenerateMips_UnorderedAccessPath(resourceCopy.Get(), FormatIsSRGB(resourceDesc.Format));

// Direct copy back
D3D12_RESOURCE_BARRIER barrier[2] = {};
Expand Down Expand Up @@ -1019,7 +1026,7 @@ class ResourceUploadBatch::Impl
aliasBarrier[1].Transition.StateAfter = originalState;

mList->ResourceBarrier(2, aliasBarrier);
GenerateMips_UnorderedAccessPath(resourceCopy.Get());
GenerateMips_UnorderedAccessPath(resourceCopy.Get(), FormatIsSRGB(resourceDesc.Format));

// Direct copy back RGB to BGR
aliasBarrier[0].Aliasing.pResourceBefore = resourceCopy.Get();
Expand Down
24 changes: 17 additions & 7 deletions Src/Shaders/CompileShaders.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ if not exist %XBOXFXC% goto needxdk
goto continue

:continuegxdk
set XBOXOPTS=/D__XBOX_PER_THREAD_SCRATCH_SIZE_LIMIT_IN_BYTES=0
set XBOXOPTS=-HV 2021 /D__XBOX_PER_THREAD_SCRATCH_SIZE_LIMIT_IN_BYTES=0
if %2.==scarlett. (
set XBOXPREFIX=XboxGamingScarlett
set XBOXDXC="%GameDKLatest%\GXDK\bin\Scarlett\DXC.exe"
Expand All @@ -49,11 +49,12 @@ if not exist %XBOXDXC% goto needgxdk
goto continue

:continuedxil
set DXILOPTS=-HV 2021
if defined DirectXShaderCompiler goto dxcviaenv
set PCDXC="%WindowsSdkVerBinPath%%FXCARCH%\dxc.exe"
if exist %PCDXC% goto continue
if exist %PCDXC% goto dxilver
set PCDXC="%WindowsSdkBinPath%%WindowsSDKVersion%\%FXCARCH%\dxc.exe"
if exist %PCDXC% goto continue
if exist %PCDXC% goto dxilver

set PCDXC=dxc.exe
goto continue
Expand All @@ -63,6 +64,14 @@ set PCDXC="%DirectXShaderCompiler%"
if exist %PCDXC% goto continue
goto needdxil

:dxilver
if not defined WindowsSDKVersion goto continue
REM known DXC.EXE versions that don't support -HV 2021
if not "x%WindowsSDKVersion:10.0.19041.0=%"=="x%WindowsSDKVersion%" set DXILOPTS=%DXILOPTS:-HV 2021=%
if not "x%WindowsSDKVersion:10.0.20348.0=%"=="x%WindowsSDKVersion%" set DXILOPTS=%DXILOPTS:-HV 2021=%
if not "x%WindowsSDKVersion:10.0.22000.0=%"=="x%WindowsSDKVersion%" set DXILOPTS=%DXILOPTS:-HV 2021=%
goto continue

:continuepc
set PCOPTS=

Expand Down Expand Up @@ -256,6 +265,7 @@ call :CompileShader%1 PostProcess ps PSMerge
call :CompileShader%1 PostProcess ps PSBloomCombine

call :CompileComputeShader%1 GenerateMips main
call :CompileComputeShader%1 GenerateMips sRGB

call :CompileShader%1 ToneMap vs VSQuad
call :CompileShader%1 ToneMap ps PSCopy
Expand Down Expand Up @@ -307,14 +317,14 @@ echo %fxc%
exit /b

:CompileShaderdxil
set dxc=%PCDXC% "%1.fx" %FXCOPTS% /T%2_6_0 /E%3 "/Fh%CompileShadersOutput%\%1_%3.inc" "/Fd%CompileShadersOutput%\%1_%3.pdb" /Vn%1_%3
set dxc=%PCDXC% "%1.fx" %FXCOPTS% /T%2_6_0 %DXILOPTS% /E%3 "/Fh%CompileShadersOutput%\%1_%3.inc" "/Fd%CompileShadersOutput%\%1_%3.pdb" /Vn%1_%3
echo.
echo %dxc%
%dxc% || set error=1
exit /b

:CompileComputeShaderdxil
set dxc=%PCDXC% "%1.hlsl" %FXCOPTS% /Tcs_6_0 /E%2 "/Fh%CompileShadersOutput%\%1_%2.inc" "/Fd%CompileShadersOutput%\%1_%2.pdb" /Vn%1_%2
set dxc=%PCDXC% "%1.hlsl" %FXCOPTS% /Tcs_6_0 %DXILOPTS% /E%2 "/Fh%CompileShadersOutput%\%1_%2.inc" "/Fd%CompileShadersOutput%\%1_%2.pdb" /Vn%1_%2
echo.
echo %dxc%
%dxc% || set error=1
Expand All @@ -335,14 +345,14 @@ echo %fxc%
exit /b

:CompileShadergxdk
set dxc=%XBOXDXC% "%1.fx" %FXCOPTS% -HV 2021 /T%2_6_0 %XBOXOPTS% /E%3 "/Fh%CompileShadersOutput%\%XBOXPREFIX%%1_%3.inc" "/Fd%CompileShadersOutput%\%XBOXPREFIX%%1_%3.pdb" /Vn%1_%3
set dxc=%XBOXDXC% "%1.fx" %FXCOPTS% /T%2_6_0 %XBOXOPTS% /E%3 "/Fh%CompileShadersOutput%\%XBOXPREFIX%%1_%3.inc" "/Fd%CompileShadersOutput%\%XBOXPREFIX%%1_%3.pdb" /Vn%1_%3
echo.
echo %dxc%
%dxc% || set error=1
exit /b

:CompileComputeShadergxdk
set dxc=%XBOXDXC% "%1.hlsl" %FXCOPTS% -HV 2021 /Tcs_6_0 %XBOXOPTS% /E%2 "/Fh%CompileShadersOutput%\%XBOXPREFIX%%1_%2.inc" "/Fd%CompileShadersOutput%\%XBOXPREFIX%%1_%2.pdb" /Vn%1_%2
set dxc=%XBOXDXC% "%1.hlsl" %FXCOPTS% /Tcs_6_0 %XBOXOPTS% /E%2 "/Fh%CompileShadersOutput%\%XBOXPREFIX%%1_%2.inc" "/Fd%CompileShadersOutput%\%XBOXPREFIX%%1_%2.pdb" /Vn%1_%2
echo.
echo %dxc%
%dxc% || set error=1
Expand Down
46 changes: 46 additions & 0 deletions Src/Shaders/GenerateMips.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,49 @@ void main(uint3 DTid : SV_DispatchThreadID)
{
OutMip[DTid.xy] = Mip(DTid.xy);
}

float3 ApplySRGBCurve(float3 x)
{
#if __HLSL_VERSION >= 2021
// This is exactly the sRGB curve
//return select(x < 0.0031308, 12.92 * x, 1.055 * pow(abs(x), 1.0 / 2.4) - 0.055);

// This is cheaper but nearly equivalent to the exact sRGB curve
return select(x < 0.0031308, 12.92 * x, 1.13005 * sqrt(abs(x - 0.00228)) - 0.13448 * x + 0.005719);
#else
float3 result;
if (x.r < 0.0031308)
{
result.r = 12.92 * x.r;
}
else
{
result.r = 1.055 * pow(abs(x.r), 1.0 / 2.4) - 0.055;
}
if (x.g < 0.0031308)
{
result.g = 12.92 * x.g;
}
else
{
result.g = 1.055 * pow(abs(x.g), 1.0 / 2.4) - 0.055;
}
if (x.b < 0.0031308)
{
result.b = 12.92 * x.b;
}
else
{
result.b = 1.055 * pow(abs(x.b), 1.0 / 2.4) - 0.055;
}
return result;
#endif
}

[RootSignature(GenerateMipsRS)]
[numthreads(8, 8, 1)]
void sRGB(uint3 DTid : SV_DispatchThreadID)
{
float4 Linear = Mip(DTid.xy);
OutMip[DTid.xy] = float4(ApplySRGBCurve(Linear.rgb), Linear.a);
}
Loading