@@ -123,6 +123,9 @@ XM_ALIGNED_STRUCT(16) SpriteBatch::Impl : public AlignedNew<SpriteBatch::Impl>
123123 bool mSetViewport ;
124124 D3D12_VIEWPORT mViewPort ;
125125 D3D12_GPU_DESCRIPTOR_HANDLE mSampler ;
126+ std::function<void __cdecl ()> mCustomCallback ;
127+
128+ XMMATRIX GetViewportTransform (_In_ DXGI_MODE_ROTATION rotation);
126129
127130private:
128131 // Implementation helper methods.
@@ -143,8 +146,6 @@ XM_ALIGNED_STRUCT(16) SpriteBatch::Impl : public AlignedNew<SpriteBatch::Impl>
143146 FXMVECTOR textureSize,
144147 FXMVECTOR inverseTextureSize) noexcept ;
145148
146- XMMATRIX GetViewportTransform (_In_ DXGI_MODE_ROTATION rotation);
147-
148149 // Constants.
149150 static constexpr size_t MaxBatchSize = 2048 ;
150151 static constexpr size_t MinBatchSize = 128 ;
@@ -175,6 +176,8 @@ XM_ALIGNED_STRUCT(16) SpriteBatch::Impl : public AlignedNew<SpriteBatch::Impl>
175176 // mSpriteQueue array, and we take care to keep them in order when sorting is disabled.
176177 std::vector<SpriteInfo const *> mSortedSprites ;
177178
179+ // Custom flags.
180+ bool mCustomCBV ;
178181
179182 // Mode settings from the last Begin call.
180183 bool mInBeginEndPair ;
@@ -438,6 +441,7 @@ SpriteBatch::Impl::Impl(ID3D12Device* device,
438441 mSampler {},
439442 mSpriteQueueCount (0 ),
440443 mSpriteQueueArraySize(0 ),
444+ mCustomCBV(false ),
441445 mInBeginEndPair(false ),
442446 mSortMode(SpriteSortMode_Deferred),
443447 mTransformMatrix(MatrixIdentity),
@@ -475,6 +479,7 @@ SpriteBatch::Impl::Impl(ID3D12Device* device,
475479 if (psoDesc.customRootSignature )
476480 {
477481 mRootSignature = psoDesc.customRootSignature ;
482+ mCustomCBV = psoDesc.customCBV ;
478483 }
479484 else
480485 {
@@ -558,8 +563,10 @@ void SpriteBatch::Impl::End()
558563
559564 // Break circular reference chains, in case the state lambda closed
560565 // over an object that holds a reference to this SpriteBatch.
561- mCommandList = nullptr ;
566+ mCustomCallback = nullptr ;
567+
562568 mInBeginEndPair = false ;
569+ mCommandList = nullptr ;
563570}
564571
565572
@@ -679,13 +686,22 @@ void SpriteBatch::Impl::PrepareForRendering()
679686 // Set the index buffer.
680687 commandList->IASetIndexBuffer (&mDeviceResources ->indexBufferView );
681688
682- // Set the transform matrix.
683- const XMMATRIX transformMatrix = (mRotation == DXGI_MODE_ROTATION_UNSPECIFIED )
684- ? mTransformMatrix
685- : (mTransformMatrix * GetViewportTransform (mRotation ));
689+ if (!mCustomCBV )
690+ {
691+ // Set the transform matrix.
692+ const XMMATRIX transformMatrix = (mRotation == DXGI_MODE_ROTATION_UNSPECIFIED )
693+ ? mTransformMatrix
694+ : (mTransformMatrix * GetViewportTransform (mRotation ));
695+
696+ mConstantBuffer = GraphicsMemory::Get (mDeviceResources ->mDevice ).AllocateConstant (transformMatrix);
697+ commandList->SetGraphicsRootConstantBufferView (RootParameterIndex::ConstantBuffer, mConstantBuffer .GpuAddress ());
698+ }
686699
687- mConstantBuffer = GraphicsMemory::Get (mDeviceResources ->mDevice ).AllocateConstant (transformMatrix);
688- commandList->SetGraphicsRootConstantBufferView (RootParameterIndex::ConstantBuffer, mConstantBuffer .GpuAddress ());
700+ // Hook lets custom rendering scenarios bind custom resources.
701+ if (mCustomCallback )
702+ {
703+ mCustomCallback ();
704+ }
689705}
690706
691707
@@ -1062,20 +1078,60 @@ SpriteBatch& SpriteBatch::operator= (SpriteBatch&&) noexcept = default;
10621078SpriteBatch::~SpriteBatch () = default ;
10631079
10641080
1081+ // Begin using static sampler
1082+ _Use_decl_annotations_
1083+ void XM_CALLCONV SpriteBatch::Begin (
1084+ ID3D12GraphicsCommandList* commandList,
1085+ SpriteSortMode sortMode,
1086+ FXMMATRIX transformMatrix)
1087+ {
1088+ pImpl->Begin (commandList, sortMode, transformMatrix);
1089+ }
1090+
1091+
1092+ // Begin with heap-based sampler
1093+ _Use_decl_annotations_
1094+ void XM_CALLCONV SpriteBatch::Begin (
1095+ ID3D12GraphicsCommandList* commandList,
1096+ D3D12_GPU_DESCRIPTOR_HANDLE sampler,
1097+ SpriteSortMode sortMode,
1098+ FXMMATRIX transformMatrix)
1099+ {
1100+ if (!sampler.ptr )
1101+ throw std::invalid_argument (" Invalid heap-based sampler for Begin" );
1102+
1103+ if (!pImpl->mSampler .ptr )
1104+ {
1105+ DebugTrace (" ERROR: sampler version of Begin requires SpriteBatch was created with a heap-based sampler\n " );
1106+ throw std::runtime_error (" SpriteBatch::Begin" );
1107+ }
1108+
1109+ pImpl->mSampler = sampler;
1110+
1111+ pImpl->Begin (commandList, sortMode, transformMatrix);
1112+ }
1113+
1114+
1115+ // Begin using static sampler and custom lambda
10651116_Use_decl_annotations_
10661117void XM_CALLCONV SpriteBatch::Begin (
10671118 ID3D12GraphicsCommandList* commandList,
1119+ std::function<void __cdecl ()> setCustomCallback,
10681120 SpriteSortMode sortMode,
10691121 FXMMATRIX transformMatrix)
10701122{
1123+ pImpl->mCustomCallback = setCustomCallback;
1124+
10711125 pImpl->Begin (commandList, sortMode, transformMatrix);
10721126}
10731127
10741128
1129+ // Begin with heap-based sampler and custom lambda
10751130_Use_decl_annotations_
10761131void XM_CALLCONV SpriteBatch::Begin (
10771132 ID3D12GraphicsCommandList* commandList,
10781133 D3D12_GPU_DESCRIPTOR_HANDLE sampler,
1134+ std::function<void __cdecl ()> setCustomCallback,
10791135 SpriteSortMode sortMode,
10801136 FXMMATRIX transformMatrix)
10811137{
@@ -1089,6 +1145,7 @@ void XM_CALLCONV SpriteBatch::Begin(
10891145 }
10901146
10911147 pImpl->mSampler = sampler;
1148+ pImpl->mCustomCallback = setCustomCallback;
10921149
10931150 pImpl->Begin (commandList, sortMode, transformMatrix);
10941151}
@@ -1254,3 +1311,8 @@ void SpriteBatch::SetViewport(const D3D12_VIEWPORT& viewPort)
12541311 pImpl->mSetViewport = true ;
12551312 pImpl->mViewPort = viewPort;
12561313}
1314+
1315+ void SpriteBatch::GetViewportTransform (XMMATRIX & transformMatrix) const
1316+ {
1317+ transformMatrix = pImpl->GetViewportTransform (pImpl->mRotation );
1318+ }
0 commit comments