@@ -136,6 +136,10 @@ namespace plume {
136136 return DXGI_FORMAT_R32_TYPELESS ;
137137 case RenderFormat::D32_FLOAT :
138138 return DXGI_FORMAT_D32_FLOAT ;
139+ case RenderFormat::D32_FLOAT_S8_UINT :
140+ // In order to be able to create both depth-stencil and shader resource views,
141+ // we must use R32G8X24_TYPELESS as the base type and specialize later.
142+ return DXGI_FORMAT_R32G8X24_TYPELESS ;
139143 case RenderFormat::R32_FLOAT :
140144 return DXGI_FORMAT_R32_FLOAT ;
141145 case RenderFormat::R32_UINT :
@@ -224,6 +228,29 @@ namespace plume {
224228 }
225229 }
226230
231+ static DXGI_FORMAT toDXGITextureView (RenderFormat format) {
232+ const DXGI_FORMAT dxgiFormat = toDXGI (format);
233+ if (dxgiFormat == DXGI_FORMAT_D32_FLOAT ) {
234+ // D3D12 and Vulkan disagree on whether D32 is usable as a texture view format.
235+ // We just make D3D12 use R32 instead.
236+ return DXGI_FORMAT_R32_FLOAT ;
237+ }
238+ if (dxgiFormat == DXGI_FORMAT_R32G8X24_TYPELESS ) {
239+ // Specialize into depth view of depth-stencil texture.
240+ return DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS ;
241+ }
242+ return dxgiFormat;
243+ }
244+
245+ static DXGI_FORMAT toDXGIDepthStencilView (RenderFormat format) {
246+ const DXGI_FORMAT dxgiFormat = toDXGI (format);
247+ if (dxgiFormat == DXGI_FORMAT_R32G8X24_TYPELESS ) {
248+ // Specialize into full depth-stencil view.
249+ return DXGI_FORMAT_D32_FLOAT_S8X24_UINT ;
250+ }
251+ return dxgiFormat;
252+ }
253+
227254 static D3D12_BLEND toD3D12 (RenderBlend blend) {
228255 switch (blend) {
229256 case RenderBlend::ZERO :
@@ -472,6 +499,30 @@ namespace plume {
472499 }
473500 }
474501
502+ static D3D12_STENCIL_OP toD3D12 (RenderStencilOp function) {
503+ switch (function) {
504+ case RenderStencilOp::KEEP :
505+ return D3D12_STENCIL_OP_KEEP ;
506+ case RenderStencilOp::ZERO :
507+ return D3D12_STENCIL_OP_ZERO ;
508+ case RenderStencilOp::REPLACE :
509+ return D3D12_STENCIL_OP_REPLACE ;
510+ case RenderStencilOp::INCREMENT_AND_CLAMP :
511+ return D3D12_STENCIL_OP_INCR_SAT ;
512+ case RenderStencilOp::DECREMENT_AND_CLAMP :
513+ return D3D12_STENCIL_OP_DECR_SAT ;
514+ case RenderStencilOp::INVERT :
515+ return D3D12_STENCIL_OP_INVERT ;
516+ case RenderStencilOp::INCREMENT_AND_WRAP :
517+ return D3D12_STENCIL_OP_INCR ;
518+ case RenderStencilOp::DECREMENT_AND_WRAP :
519+ return D3D12_STENCIL_OP_DECR ;
520+ default :
521+ assert (false && " Unknown stencil operation." );
522+ return D3D12_STENCIL_OP_KEEP ;
523+ }
524+ }
525+
475526 static D3D12_PRIMITIVE_TOPOLOGY toD3D12 (RenderPrimitiveTopology topology) {
476527 switch (topology) {
477528 case RenderPrimitiveTopology::POINT_LIST :
@@ -1664,12 +1715,14 @@ namespace plume {
16641715
16651716 void D3D12CommandList::drawInstanced (uint32_t vertexCountPerInstance, uint32_t instanceCount, uint32_t startVertexLocation, uint32_t startInstanceLocation) {
16661717 checkTopology ();
1718+ checkStencilRef ();
16671719 checkFramebufferSamplePositions ();
16681720 d3d->DrawInstanced (vertexCountPerInstance, instanceCount, startVertexLocation, startInstanceLocation);
16691721 }
16701722
16711723 void D3D12CommandList::drawIndexedInstanced (uint32_t indexCountPerInstance, uint32_t instanceCount, uint32_t startIndexLocation, int32_t baseVertexLocation, uint32_t startInstanceLocation) {
16721724 checkTopology ();
1725+ checkStencilRef ();
16731726 checkFramebufferSamplePositions ();
16741727 d3d->DrawIndexedInstanced (indexCountPerInstance, instanceCount, startIndexLocation, baseVertexLocation, startInstanceLocation);
16751728 }
@@ -1900,7 +1953,7 @@ namespace plume {
19001953 d3d->ClearRenderTargetView (targetFramebuffer->colorHandles [attachmentIndex], colorValue.rgba , clearRectsCount, (clearRectsCount > 0 ) ? rectVector.data () : nullptr );
19011954 }
19021955
1903- void D3D12CommandList::clearDepth (bool clearDepth, float depthValue, const RenderRect *clearRects, uint32_t clearRectsCount) {
1956+ void D3D12CommandList::clearDepthStencil (bool clearDepth, bool clearStencil, float depthValue, uint32_t stencilValue , const RenderRect *clearRects, uint32_t clearRectsCount) {
19041957 assert (targetFramebuffer != nullptr );
19051958 assert (targetFramebuffer->depthHandle .ptr != 0 );
19061959 assert ((clearRectsCount == 0 ) || (clearRects != nullptr ));
@@ -1916,8 +1969,13 @@ namespace plume {
19161969 }
19171970
19181971 D3D12_CLEAR_FLAGS clearFlags = {};
1919- clearFlags |= clearDepth ? D3D12_CLEAR_FLAG_DEPTH : D3D12_CLEAR_FLAGS (0 );
1920- d3d->ClearDepthStencilView (targetFramebuffer->depthHandle , clearFlags, depthValue, 0 , clearRectsCount, (clearRectsCount > 0 ) ? rectVector.data () : nullptr );
1972+ if (clearDepth) {
1973+ clearFlags |= D3D12_CLEAR_FLAG_DEPTH ;
1974+ }
1975+ if (clearStencil) {
1976+ clearFlags |= D3D12_CLEAR_FLAG_STENCIL ;
1977+ }
1978+ d3d->ClearDepthStencilView (targetFramebuffer->depthHandle , clearFlags, depthValue, stencilValue, clearRectsCount, (clearRectsCount > 0 ) ? rectVector.data () : nullptr );
19211979 }
19221980
19231981 void D3D12CommandList::copyBufferRegion (RenderBufferReference dstBuffer, RenderBufferReference srcBuffer, uint64_t size) {
@@ -2085,6 +2143,17 @@ namespace plume {
20852143 activeTopology = graphicsPipeline->topology ;
20862144 }
20872145 }
2146+
2147+ void D3D12CommandList::checkStencilRef () {
2148+ assert (activeGraphicsPipeline != nullptr );
2149+ assert (activeGraphicsPipeline->type == D3D12Pipeline::Type::Graphics);
2150+
2151+ const D3D12GraphicsPipeline *graphicsPipeline = static_cast <const D3D12GraphicsPipeline *>(activeGraphicsPipeline);
2152+ if (activeStencilRef != graphicsPipeline->stencilRef ) {
2153+ d3d->OMSetStencilRef (graphicsPipeline->stencilRef );
2154+ activeStencilRef = graphicsPipeline->stencilRef ;
2155+ }
2156+ }
20882157
20892158 void D3D12CommandList::checkFramebufferSamplePositions () {
20902159 if (!targetFramebufferSamplePositionsSet && (targetFramebuffer != nullptr )) {
@@ -2430,16 +2499,11 @@ namespace plume {
24302499 assert (texture != nullptr );
24312500
24322501 this ->texture = texture;
2433- this ->format = toDXGI (desc.format );
2502+ this ->format = toDXGITextureView (desc.format );
24342503 this ->dimension = desc.dimension ;
24352504 this ->mipLevels = desc.mipLevels ;
24362505 this ->mipSlice = desc.mipSlice ;
24372506 this ->shader4ComponentMapping = toD3D12 (desc.componentMapping );
2438-
2439- // D3D12 and Vulkan disagree on whether D32 is usable as a texture view format. We just make D3D12 use R32 instead.
2440- if (format == DXGI_FORMAT_D32_FLOAT ) {
2441- format = DXGI_FORMAT_R32_FLOAT ;
2442- }
24432507 }
24442508
24452509 D3D12TextureView::~D3D12TextureView () { }
@@ -2566,7 +2630,7 @@ namespace plume {
25662630 targetHeapDepth = true ;
25672631
25682632 D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc = {};
2569- dsvDesc.Format = toDXGI (desc.format );
2633+ dsvDesc.Format = toDXGIDepthStencilView (desc.format );
25702634
25712635 const bool isMSAA = (desc.multisampling .sampleCount > RenderSampleCount::COUNT_1 );
25722636 switch (desc.dimension ) {
@@ -2820,6 +2884,17 @@ namespace plume {
28202884 psoDesc.DepthStencilState .DepthEnable = desc.depthEnabled ;
28212885 psoDesc.DepthStencilState .DepthWriteMask = desc.depthWriteEnabled ? D3D12_DEPTH_WRITE_MASK_ALL : D3D12_DEPTH_WRITE_MASK_ZERO ;
28222886 psoDesc.DepthStencilState .DepthFunc = toD3D12 (desc.depthFunction );
2887+ psoDesc.DepthStencilState .StencilEnable = desc.stencilEnabled ;
2888+ psoDesc.DepthStencilState .StencilReadMask = desc.stencilReadMask ;
2889+ psoDesc.DepthStencilState .StencilWriteMask = desc.stencilWriteMask ;
2890+ psoDesc.DepthStencilState .FrontFace .StencilFailOp = toD3D12 (desc.stencilFrontFace .failOp );
2891+ psoDesc.DepthStencilState .FrontFace .StencilDepthFailOp = toD3D12 (desc.stencilFrontFace .depthFailOp );
2892+ psoDesc.DepthStencilState .FrontFace .StencilPassOp = toD3D12 (desc.stencilFrontFace .passOp );
2893+ psoDesc.DepthStencilState .FrontFace .StencilFunc = toD3D12 (desc.stencilFrontFace .compareFunction );
2894+ psoDesc.DepthStencilState .BackFace .StencilFailOp = toD3D12 (desc.stencilBackFace .failOp );
2895+ psoDesc.DepthStencilState .BackFace .StencilDepthFailOp = toD3D12 (desc.stencilBackFace .depthFailOp );
2896+ psoDesc.DepthStencilState .BackFace .StencilPassOp = toD3D12 (desc.stencilBackFace .passOp );
2897+ psoDesc.DepthStencilState .BackFace .StencilFunc = toD3D12 (desc.stencilBackFace .compareFunction );
28232898 psoDesc.NumRenderTargets = desc.renderTargetCount ;
28242899 psoDesc.BlendState .AlphaToCoverageEnable = desc.alphaToCoverageEnabled ;
28252900
@@ -2840,7 +2915,7 @@ namespace plume {
28402915 targetDesc.RenderTargetWriteMask = renderDesc.renderTargetWriteMask ;
28412916 }
28422917
2843- psoDesc.DSVFormat = toDXGI (desc.depthTargetFormat );
2918+ psoDesc.DSVFormat = toDXGIDepthStencilView (desc.depthTargetFormat );
28442919
28452920 std::vector<D3D12_INPUT_ELEMENT_DESC > inputElements;
28462921 for (uint32_t i = 0 ; i < desc.inputElementsCount ; i++) {
0 commit comments