Skip to content

Commit e9301ac

Browse files
azhirnovTheMostDiligent
authored andcommitted
Added subsampled render targets for VRS (API250011)
1 parent 087d058 commit e9301ac

24 files changed

+380
-71
lines changed

Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -211,10 +211,8 @@ class TexFormatToViewFormatConverter
211211
#undef INIT_TVIEW_FORMAT_INFO
212212
// clang-format on
213213

214-
m_ViewFormats[TEX_FORMAT_R8_UINT][TEXTURE_VIEW_SHADING_RATE - 1] = TEX_FORMAT_R8_UINT;
215-
m_ViewFormats[TEX_FORMAT_R8_TYPELESS][TEXTURE_VIEW_SHADING_RATE - 1] = TEX_FORMAT_R8_UINT;
216-
m_ViewFormats[TEX_FORMAT_RG8_UNORM][TEXTURE_VIEW_SHADING_RATE - 1] = TEX_FORMAT_RG8_UNORM;
217-
m_ViewFormats[TEX_FORMAT_RG8_TYPELESS][TEXTURE_VIEW_SHADING_RATE - 1] = TEX_FORMAT_RG8_UNORM;
214+
m_ViewFormats[TEX_FORMAT_R8_UINT][TEXTURE_VIEW_SHADING_RATE - 1] = TEX_FORMAT_R8_UINT;
215+
m_ViewFormats[TEX_FORMAT_RG8_UNORM][TEXTURE_VIEW_SHADING_RATE - 1] = TEX_FORMAT_RG8_UNORM;
218216
}
219217

220218
TEXTURE_FORMAT GetViewFormat(TEXTURE_FORMAT Format, TEXTURE_VIEW_TYPE ViewType, Uint32 BindFlags)

Graphics/GraphicsEngine/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ set(SOURCE
9292
src/RenderDeviceBase.cpp
9393
src/ResourceMappingBase.cpp
9494
src/ShaderBindingTableBase.cpp
95+
src/SamplerBase.cpp
9596
src/RenderPassBase.cpp
9697
src/TextureBase.cpp
9798
src/TopLevelASBase.cpp

Graphics/GraphicsEngine/include/DeviceContextBase.hpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,6 +1104,34 @@ inline bool DeviceContextBase<ImplementationTraits>::SetRenderTargets(const SetR
11041104
bBindRenderTargets = true;
11051105
}
11061106

1107+
#ifdef DILIGENT_DEVELOPMENT
1108+
const auto& SRProps = m_pDevice->GetAdapterInfo().ShadingRate;
1109+
if (m_pBoundShadingRateMap &&
1110+
(SRProps.CapFlags & SHADING_RATE_CAP_FLAG_NON_SUBSAMPLED_RENDER_TARGET) == 0 &&
1111+
!m_pDevice->GetDeviceInfo().IsMetalDevice())
1112+
{
1113+
VERIFY((SRProps.CapFlags & SHADING_RATE_CAP_FLAG_SUBSAMPLED_RENDER_TARGET) != 0,
1114+
"One of NON_SUBSAMPLED_RENDER_TARGET or SUBSAMPLED_RENDER_TARGET caps must be presented if texture-based VRS is supported");
1115+
1116+
for (Uint32 i = 0; i < m_NumBoundRenderTargets; ++i)
1117+
{
1118+
if (auto& pRTV = m_pBoundRenderTargets[i])
1119+
{
1120+
DEV_CHECK_ERR((pRTV->GetTexture()->GetDesc().MiscFlags & MISC_TEXTURE_FLAG_SUBSAMPLED) != 0,
1121+
"Render target used with shading rate map must be created with MISC_TEXTURE_FLAG_SUBSAMPLED flag when "
1122+
"SHADING_RATE_CAP_FLAG_NON_SUBSAMPLED_RENDER_TARGET capability is not present.");
1123+
}
1124+
}
1125+
1126+
if (m_pBoundDepthStencil)
1127+
{
1128+
DEV_CHECK_ERR((m_pBoundDepthStencil->GetTexture()->GetDesc().MiscFlags & MISC_TEXTURE_FLAG_SUBSAMPLED) != 0,
1129+
"Depth-stencil target used with shading rate map must be created with MISC_TEXTURE_FLAG_SUBSAMPLED flag when "
1130+
"SHADING_RATE_CAP_FLAG_NON_SUBSAMPLED_RENDER_TARGET capability is not present.");
1131+
}
1132+
}
1133+
#endif
1134+
11071135
return bBindRenderTargets;
11081136
}
11091137

Graphics/GraphicsEngine/include/FramebufferBase.hpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
namespace Diligent
4040
{
4141

42-
void ValidateFramebufferDesc(const FramebufferDesc& Desc, RENDER_DEVICE_TYPE DevType) noexcept(false);
42+
void ValidateFramebufferDesc(const FramebufferDesc& Desc, IRenderDevice* pDevice) noexcept(false);
4343

4444
/// Template class implementing base functionality of the framebuffer object.
4545

@@ -68,8 +68,7 @@ class FramebufferBase : public DeviceObjectBase<typename EngineImplTraits::Frame
6868
TDeviceObjectBase{pRefCounters, pDevice, Desc, bIsDeviceInternal},
6969
m_pRenderPass{Desc.pRenderPass}
7070
{
71-
const auto& DeviceInfo = pDevice->GetDeviceInfo();
72-
ValidateFramebufferDesc(this->m_Desc, DeviceInfo.Type);
71+
ValidateFramebufferDesc(this->m_Desc, pDevice);
7372

7473
if (this->m_Desc.Width == 0 || this->m_Desc.Height == 0 || this->m_Desc.NumArraySlices == 0)
7574
{

Graphics/GraphicsEngine/include/RenderDeviceBase.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ struct hash<Diligent::SamplerDesc>
6262
static_cast<int>(SamDesc.AddressU),
6363
static_cast<int>(SamDesc.AddressV),
6464
static_cast<int>(SamDesc.AddressW),
65+
static_cast<int>(SamDesc.Flags),
6566
SamDesc.MipLODBias,
6667
SamDesc.MaxAnisotropy,
6768
static_cast<int>(SamDesc.ComparisonFunc),

Graphics/GraphicsEngine/include/SamplerBase.hpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@
3737
namespace Diligent
3838
{
3939

40+
/// Validates sampler description and throws an exception in case of an error.
41+
void ValidateSamplerDesc(const SamplerDesc& Desc, const IRenderDevice* pDevice) noexcept(false);
42+
4043
/// Template class implementing base functionality of the sampler object.
4144

4245
/// \tparam EngineImplTraits - Engine implementation type traits.
@@ -59,7 +62,9 @@ class SamplerBase : public DeviceObjectBase<typename EngineImplTraits::SamplerIn
5962
/// must not keep a strong reference to the device.
6063
SamplerBase(IReferenceCounters* pRefCounters, RenderDeviceImplType* pDevice, const SamplerDesc& SamDesc, bool bIsDeviceInternal = false) :
6164
TDeviceObjectBase{pRefCounters, pDevice, SamDesc, bIsDeviceInternal}
62-
{}
65+
{
66+
ValidateSamplerDesc(this->m_Desc, pDevice);
67+
}
6368

6469
~SamplerBase()
6570
{

Graphics/GraphicsEngine/include/ShaderResourceVariableBase.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,10 @@ bool VerifySamplerBinding(const PipelineResourceDesc& ResDesc,
499499
{
500500
RESOURCE_VALIDATION_FAILURE("Buffer range can't be specified for samplers.");
501501
}
502+
if (pSamplerImpl != nullptr && (pSamplerImpl->GetDesc().Flags & SAMPLER_FLAG_SUBSAMPLED) != 0)
503+
{
504+
RESOURCE_VALIDATION_FAILURE("Subsampled sampler must be added as an immutable sampler to the PSO or resource signature");
505+
}
502506
return VerifyResourceBinding("sampler", ResDesc, BindInfo, pSamplerImpl, pCachedSampler, SignatureName);
503507
}
504508

Graphics/GraphicsEngine/interface/APIInfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
/// \file
3131
/// Diligent API information
3232

33-
#define DILIGENT_API_VERSION 250010
33+
#define DILIGENT_API_VERSION 250011
3434

3535
#include "../../../Primitives/interface/BasicTypes.h"
3636

Graphics/GraphicsEngine/interface/GraphicsTypes.h

Lines changed: 56 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2450,57 +2450,87 @@ typedef struct ShadingRateMode ShadingRateMode;
24502450
DILIGENT_TYPED_ENUM(SHADING_RATE_CAP_FLAGS, Uint16)
24512451
{
24522452
/// No shading rate capabilities.
2453-
SHADING_RATE_CAP_FLAG_NONE = 0,
2453+
SHADING_RATE_CAP_FLAG_NONE = 0,
24542454

24552455
/// Shading rate can be specified for the whole draw call using IDeviceContext::SetShadingRate().
2456-
SHADING_RATE_CAP_FLAG_PER_DRAW = 1u << 0,
2456+
SHADING_RATE_CAP_FLAG_PER_DRAW = 1u << 0,
24572457

24582458
/// Shading rate can be specified in the vertex shader for each primitive and combined with the base rate.
24592459
/// Use IDeviceContext::SetShadingRate() to set base rate and per-primitive combiner.
2460-
SHADING_RATE_CAP_FLAG_PER_PRIMITIVE = 1u << 1,
2460+
SHADING_RATE_CAP_FLAG_PER_PRIMITIVE = 1u << 1,
24612461

24622462
/// Shading rate is specified by a texture, each texel defines a shading rate for the tile.
24632463
/// Supported tile size is specified in ShadingRateProperties::MinTileSize/MaxTileSize.
24642464
/// Use IDeviceContext::SetShadingRate() to set the base rate and texture combiner.
24652465
/// Use IDeviceContext::SetRenderTargetsExt() to set the shading rate texture.
2466-
SHADING_RATE_CAP_FLAG_TEXTURE_BASED = 1u << 2,
2466+
SHADING_RATE_CAP_FLAG_TEXTURE_BASED = 1u << 2,
24672467

24682468
/// Allows to set zero bits in GraphicsPipelineDesc::SampleMask
24692469
/// with the enabled variable rate shading.
2470-
SHADING_RATE_CAP_FLAG_SAMPLE_MASK = 1u << 3,
2470+
SHADING_RATE_CAP_FLAG_SAMPLE_MASK = 1u << 3,
24712471

24722472
/// Allows to get or set SampleMask in the shader with enabled variable rate shading.
24732473
/// HLSL: SV_Coverage, GLSL: gl_SampleMaskIn, gl_SampleMask.
2474-
SHADING_RATE_CAP_FLAG_SHADER_SAMPLE_MASK = 1u << 4,
2474+
SHADING_RATE_CAP_FLAG_SHADER_SAMPLE_MASK = 1u << 4,
24752475

24762476
/// Allows to write depth and stencil from the pixel shader.
2477-
SHADING_RATE_CAP_FLAG_SHADER_DEPTH_STENCIL_WRITE = 1u << 5,
2477+
SHADING_RATE_CAP_FLAG_SHADER_DEPTH_STENCIL_WRITE = 1u << 5,
24782478

24792479
/// Allows to use per primitive shading rate when multiple viewports are used.
24802480
SHADING_RATE_CAP_FLAG_PER_PRIMITIVE_WITH_MULTIPLE_VIEWPORTS = 1u << 6,
24812481

24822482
/// Shading rate attachment for render pass must be the same for all subpasses.
24832483
/// See SubpassDesc::pShadingRateAttachment.
2484-
SHADING_RATE_CAP_FLAG_SAME_TEXTURE_FOR_WHOLE_RENDERPASS = 1u << 7,
2484+
SHADING_RATE_CAP_FLAG_SAME_TEXTURE_FOR_WHOLE_RENDERPASS = 1u << 7,
24852485

24862486
/// Allows to use texture 2D array for shading rate.
2487-
SHADING_RATE_CAP_FLAG_TEXTURE_ARRAY = 1u << 8,
2487+
SHADING_RATE_CAP_FLAG_TEXTURE_ARRAY = 1u << 8,
24882488

24892489
/// Allows to read current shading rate in the pixel shader.
24902490
/// HLSL: in SV_ShadingRate, GLSL: gl_ShadingRate.
2491-
SHADING_RATE_CAP_FLAG_SHADING_RATE_SHADER_INPUT = 1u << 9,
2492-
2493-
/// Indicates that VRS texture is accessed on the GPU side.
2494-
/// If the flag is not set, the texture content is accessed
2495-
/// on the CPU side when render pass begins.
2496-
SHADING_RATE_CAP_FLAG_TEXTURE_DEVICE_ACCESS = 1u << 10,
2491+
SHADING_RATE_CAP_FLAG_SHADING_RATE_SHADER_INPUT = 1u << 9,
24972492

24982493
/// Indicates that driver may generate additional fragment shader invocations
24992494
/// in order to make transitions between fragment areas with different shading rates more smooth.
2500-
SHADING_RATE_CAP_FLAG_ADDITIONAL_INVOCATIONS = 1u << 11,
2495+
SHADING_RATE_CAP_FLAG_ADDITIONAL_INVOCATIONS = 1u << 10,
2496+
2497+
/// Indicates that there are no additional requirements for render targets
2498+
/// that are used in texture-based VRS rendering.
2499+
SHADING_RATE_CAP_FLAG_NON_SUBSAMPLED_RENDER_TARGET = 1u << 11,
2500+
2501+
/// Indicates that render targets that are used in texture-based VRS rendering
2502+
/// must be created with MISC_TEXTURE_FLAG_SUBSAMPLED flag.
2503+
/// Intermediate targets must be scaled to the final resolution in a separate pass.
2504+
/// Intermediate targets can only be sampled with an immutable sampler created with SAMPLER_FLAG_SUBSAMPLED flag.
2505+
/// If supported, rendering to the subsampled render targets may be more optimal.
2506+
///
2507+
/// \note Both NON_SUBSAMPLED and SUBSAMPLED modes may be supported by a device.
2508+
SHADING_RATE_CAP_FLAG_SUBSAMPLED_RENDER_TARGET = 1u << 12
25012509
};
25022510
DEFINE_FLAG_ENUM_OPERATORS(SHADING_RATE_CAP_FLAGS);
25032511

2512+
/// Defines how the shading rate texture is accessed
2513+
DILIGENT_TYPED_ENUM(SHADING_RATE_TEXTURE_ACCESS, Uint8)
2514+
{
2515+
/// Shading rate texture access type is unknown
2516+
SHADING_RATE_TEXTURE_ACCESS_UNKNOWN = 0,
2517+
2518+
/// Shading rate texture is accessed by the GPU when command buffer is executed.
2519+
SHADING_RATE_TEXTURE_ACCESS_ON_GPU,
2520+
2521+
/// Shading rate texture is accessed by the CPU when command buffer is submitted
2522+
/// for execution. An application is not allowed to modify the texture until the command
2523+
/// buffer is executed by the GPU. Feneces or other synchronization methods must be used
2524+
/// to control the access to the texture.
2525+
SHADING_RATE_TEXTURE_ACCESS_ON_SUBMIT,
2526+
2527+
/// Shading rate texture is accessed by the CPU when SetRenderTargetsEx or BeginRenderPass
2528+
/// command is executed. An application is not allowed to modify the texture until the
2529+
/// command buffer is executed by GPU. Feneces or other synchronization methods must be used
2530+
/// to control the access to the texture.
2531+
SHADING_RATE_TEXTURE_ACCESS_ON_SET_RTV
2532+
};
2533+
25042534
/// Shading rate properties
25052535
struct ShadingRateProperties
25062536
{
@@ -2509,7 +2539,7 @@ struct ShadingRateProperties
25092539
ShadingRateMode ShadingRates [DILIGENT_MAX_SHADING_RATES] DEFAULT_INITIALIZER({});
25102540

25112541
/// The number of valid elements in ShadingRates array.
2512-
Uint32 NumShadingRates DEFAULT_INITIALIZER(0);
2542+
Uint8 NumShadingRates DEFAULT_INITIALIZER(0);
25132543

25142544
/// Shading rate capability flags, see Diligent::SHADING_RATE_CAP_FLAGS.
25152545
SHADING_RATE_CAP_FLAGS CapFlags DEFAULT_INITIALIZER(SHADING_RATE_CAP_FLAG_NONE);
@@ -2520,13 +2550,22 @@ struct ShadingRateProperties
25202550
/// Indicates which shading rate texture format is used by this device (see Diligent::SHADING_RATE_FORMAT).
25212551
SHADING_RATE_FORMAT Format DEFAULT_INITIALIZER(SHADING_RATE_FORMAT_UNKNOWN);
25222552

2553+
/// Shading rate texture access type (see Diligent::SHADING_RATE_TEXTURE_ACCESS).
2554+
SHADING_RATE_TEXTURE_ACCESS ShadingRateTextureAccess DEFAULT_INITIALIZER(SHADING_RATE_TEXTURE_ACCESS_UNKNOWN);
2555+
2556+
/// Indicates which bind flags are allowed for shading rate texture.
2557+
BIND_FLAGS BindFlags DEFAULT_INITIALIZER(BIND_NONE);
2558+
25232559
/// Minimal supported tile size.
25242560
/// Shading rate texture size must be less than or equal to (framebuffer_size / MinTileSize).
25252561
Uint32 MinTileSize[2] DEFAULT_INITIALIZER({});
25262562

25272563
/// Maximum supported tile size.
25282564
/// Shading rate texture size must be greater than or equal to (framebuffer_size / MaxTileSize).
25292565
Uint32 MaxTileSize[2] DEFAULT_INITIALIZER({});
2566+
2567+
/// Maximum size of the texture array created with MISC_TEXTURE_FLAG_SUBSAMPLED flag.
2568+
Uint32 MaxSabsampledArraySlices DEFAULT_INITIALIZER(0);
25302569
};
25312570
typedef struct ShadingRateProperties ShadingRateProperties;
25322571

Graphics/GraphicsEngine/interface/Sampler.h

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,23 @@ static const INTERFACE_ID IID_Sampler =
4242

4343
// clang-format off
4444

45+
/// Sampler flags
46+
DILIGENT_TYPED_ENUM(SAMPLER_FLAGS, Uint8)
47+
{
48+
SAMPLER_FLAG_NONE = 0,
49+
50+
/// Specifies that the sampler will read from a subsampled texture created with MISC_TEXTURE_FLAG_SUBSAMPLED flag.
51+
/// Requires SHADING_RATE_CAP_FLAG_SUBSAMPLED_RENDER_TARGET capability.
52+
SAMPLER_FLAG_SUBSAMPLED = 1u << 0,
53+
54+
/// Specifies that the GPU is allowed to use fast approximation when reconstructing full-resolution value from
55+
/// the subsampled texture accessed by the sampler.
56+
/// Requires SHADING_RATE_CAP_FLAG_SUBSAMPLED_RENDER_TARGET capability.
57+
SAMPLER_FLAG_SUBSAMPLED_COARSE_RECONSTRUCTION = 1u << 1,
58+
};
59+
DEFINE_FLAG_ENUM_OPERATORS(SAMPLER_FLAGS)
60+
61+
4562
/// Sampler description
4663

4764
/// This structure describes the sampler state which is used in a call to
@@ -83,6 +100,9 @@ struct SamplerDesc DILIGENT_DERIVE(DeviceObjectAttribs)
83100
/// Default value: Diligent::TEXTURE_ADDRESS_CLAMP.
84101
TEXTURE_ADDRESS_MODE AddressW DEFAULT_INITIALIZER(TEXTURE_ADDRESS_CLAMP);
85102

103+
/// Sampler flags, see Diligent::SAMPLER_FLAGS for details.
104+
SAMPLER_FLAGS Flags DEFAULT_INITIALIZER(SAMPLER_FLAG_NONE);
105+
86106
/// Offset from the calculated mipmap level. For example, if a sampler calculates that a texture
87107
/// should be sampled at mipmap level 1.2 and MipLODBias is 2.3, then the texture will be sampled at
88108
/// mipmap level 3.5. Default value: 0.
@@ -123,13 +143,15 @@ struct SamplerDesc DILIGENT_DERIVE(DeviceObjectAttribs)
123143
Uint32 _MaxAnisotropy = SamplerDesc{}.MaxAnisotropy,
124144
COMPARISON_FUNCTION _ComparisonFunc = SamplerDesc{}.ComparisonFunc,
125145
float _MinLOD = SamplerDesc{}.MinLOD,
126-
float _MaxLOD = SamplerDesc{}.MaxLOD) :
146+
float _MaxLOD = SamplerDesc{}.MaxLOD,
147+
SAMPLER_FLAGS _Flags = SamplerDesc{}.Flags) :
127148
MinFilter {_MinFilter },
128149
MagFilter {_MagFilter },
129150
MipFilter {_MipFilter },
130151
AddressU {_AddressU },
131152
AddressV {_AddressV },
132153
AddressW {_AddressW },
154+
Flags {_Flags },
133155
MipLODBias {_MipLODBias },
134156
MaxAnisotropy {_MaxAnisotropy },
135157
ComparisonFunc {_ComparisonFunc},
@@ -157,6 +179,7 @@ struct SamplerDesc DILIGENT_DERIVE(DeviceObjectAttribs)
157179
AddressU == RHS.AddressU &&
158180
AddressV == RHS.AddressV &&
159181
AddressW == RHS.AddressW &&
182+
Flags == RHS.Flags &&
160183
MipLODBias == RHS.MipLODBias &&
161184
MaxAnisotropy == RHS.MaxAnisotropy &&
162185
ComparisonFunc == RHS.ComparisonFunc &&

0 commit comments

Comments
 (0)