summaryrefslogtreecommitdiffstats
path: root/Projects/Asteroids/src/asteroids_DE.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Projects/Asteroids/src/asteroids_DE.cpp')
-rw-r--r--Projects/Asteroids/src/asteroids_DE.cpp137
1 files changed, 91 insertions, 46 deletions
diff --git a/Projects/Asteroids/src/asteroids_DE.cpp b/Projects/Asteroids/src/asteroids_DE.cpp
index 35fb0da..ba1dc4d 100644
--- a/Projects/Asteroids/src/asteroids_DE.cpp
+++ b/Projects/Asteroids/src/asteroids_DE.cpp
@@ -73,17 +73,24 @@ namespace Diligent
namespace AsteroidsDE {
-struct DrawConstantBuffer {
- DirectX::XMFLOAT4X4 mWorld;
+struct DrawConstantBuffer
+{
DirectX::XMFLOAT4X4 mViewProjection;
- DirectX::XMFLOAT3 mSurfaceColor;
+ DirectX::XMFLOAT4X4 mWorld;
+ DirectX::XMFLOAT3 mSurfaceColor;
float unused0;
DirectX::XMFLOAT3 mDeepColor;
float unused1;
+};
- Uint32 mTextureIndex;
- Uint32 unused3[3];
+struct AsteroidData
+{
+ DirectX::XMFLOAT4X4 mWorld;
+ DirectX::XMFLOAT3 mSurfaceColor;
+ float unused0;
+ DirectX::XMFLOAT3 mDeepColor;
+ Uint32 mTextureIndex;
};
struct SkyboxConstantBuffer {
@@ -239,13 +246,30 @@ Asteroids::Asteroids(const Settings &settings, AsteroidsSimulation* asteroids, G
mBackBufferHeight = mSwapChain->GetDesc().Height;
const auto MaxAsteroidsInSubset = (NUM_ASTEROIDS + mNumSubsets - 1) / mNumSubsets;
+ {
+ BufferDesc desc;
+ desc.Name = "Asteroids constant buffer";
+ // In bindless mode we will be updating the buffer with UpdateBuffer method
+ desc.Usage = (m_BindingMode == BindingMode::Bindless) ? USAGE_DEFAULT : USAGE_DYNAMIC;
+ desc.CPUAccessFlags = CPU_ACCESS_WRITE;
+ desc.BindFlags = BIND_UNIFORM_BUFFER;
+ // In bindless mode, we will only write view-projection matrix
+ desc.uiSizeInBytes = static_cast<Uint32>( (m_BindingMode == BindingMode::Bindless) ? sizeof(DirectX::XMFLOAT4X4) : sizeof(DrawConstantBuffer) );
+ mDevice->CreateBuffer(desc, nullptr, &mDrawConstantBuffer);
+ if (m_BindingMode != BindingMode::Bindless)
+ Barriers.emplace_back(mDrawConstantBuffer, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_CONSTANT_BUFFER, true);
+ }
+
if (m_BindingMode == BindingMode::Bindless)
{
{
+ // In Direct3D there is no easy way to pass draw call number into the shader,
+ // so we will use this auxiliary buffer that solely contains integers in ascending order
+ // (0, 1, 2, ...) and we will acess it with FirstInstanceLocation.
BufferDesc desc;
- desc.Name = "Instance ID buffer";
- desc.Usage = USAGE_STATIC;
- desc.BindFlags = BIND_VERTEX_BUFFER;
+ desc.Name = "Instance ID buffer";
+ desc.Usage = USAGE_STATIC;
+ desc.BindFlags = BIND_VERTEX_BUFFER;
desc.uiSizeInBytes = static_cast<Uint32>(sizeof(Uint32)) * MaxAsteroidsInSubset;
std::vector<Uint32> Ids(MaxAsteroidsInSubset);
for (Uint32 i=0; i < Ids.size(); ++i)
@@ -254,14 +278,17 @@ Asteroids::Asteroids(const Settings &settings, AsteroidsSimulation* asteroids, G
mDevice->CreateBuffer(desc, &Data, &mInstanceIDBuffer);
Barriers.emplace_back(mInstanceIDBuffer, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_VERTEX_BUFFER, true);
}
+
{
+ // Structured buffer that contains asteroid data. Evey thread needs to use
+ // its own buffer.
BufferDesc desc;
- desc.Name = "Asteroids data buffer";
- desc.Usage = USAGE_DYNAMIC;
- desc.BindFlags = BIND_SHADER_RESOURCE;
- desc.Mode = BUFFER_MODE_STRUCTURED;
- desc.CPUAccessFlags = CPU_ACCESS_WRITE;
- desc.ElementByteStride = static_cast<Uint32>(sizeof(DrawConstantBuffer));
+ desc.Name = "Asteroids data buffer";
+ desc.Usage = USAGE_DYNAMIC;
+ desc.BindFlags = BIND_SHADER_RESOURCE;
+ desc.Mode = BUFFER_MODE_STRUCTURED;
+ desc.CPUAccessFlags = CPU_ACCESS_WRITE;
+ desc.ElementByteStride = static_cast<Uint32>(sizeof(AsteroidData));
desc.uiSizeInBytes = desc.ElementByteStride * MaxAsteroidsInSubset;
mAsteroidsDataBuffers.resize(mNumSubsets);
for(Uint32 i=0; i < mNumSubsets; ++i)
@@ -270,17 +297,6 @@ Asteroids::Asteroids(const Settings &settings, AsteroidsSimulation* asteroids, G
}
}
}
- else
- {
- BufferDesc desc;
- desc.Name = "Asteroids constant buffer";
- desc.Usage = USAGE_DYNAMIC;
- desc.CPUAccessFlags = CPU_ACCESS_WRITE;
- desc.BindFlags = BIND_UNIFORM_BUFFER;
- desc.uiSizeInBytes = (Uint32) sizeof(DrawConstantBuffer);
- mDevice->CreateBuffer(desc, nullptr, &mDrawConstantBuffer);
- Barriers.emplace_back(mDrawConstantBuffer, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_CONSTANT_BUFFER, true);
- }
// create pipeline state
{
@@ -293,6 +309,7 @@ Asteroids::Asteroids(const Settings &settings, AsteroidsSimulation* asteroids, G
};
PSODesc.GraphicsPipeline.InputLayout.LayoutElements = inputDesc;
+ // In bindless mode we will use instance ID buffer as the third input
PSODesc.GraphicsPipeline.InputLayout.NumElements = (m_BindingMode == BindingMode::Bindless) ? 3 : 2;
PSODesc.GraphicsPipeline.DepthStencilDesc.DepthFunc = COMPARISON_FUNC_GREATER_EQUAL;
@@ -302,8 +319,8 @@ Asteroids::Asteroids(const Settings &settings, AsteroidsSimulation* asteroids, G
ShaderCreateInfo attribs;
attribs.Desc.ShaderType = SHADER_TYPE_VERTEX;
attribs.Desc.Name = "Asteroids VS";
- attribs.EntryPoint = "asteroid_vs";
- attribs.FilePath = "asteroid_vs.hlsl";
+ attribs.EntryPoint = "asteroid_vs_diligent";
+ attribs.FilePath = "asteroid_vs_diligent.hlsl";
attribs.SourceLanguage = SHADER_SOURCE_LANGUAGE_HLSL;
attribs.pShaderSourceStreamFactory = pShaderSourceFactory;
attribs.UseCombinedTextureSamplers = true;
@@ -369,29 +386,32 @@ Asteroids::Asteroids(const Settings &settings, AsteroidsSimulation* asteroids, G
PSODesc.GraphicsPipeline.pVS = vs;
PSODesc.GraphicsPipeline.pPS = ps;
+ mDevice->CreatePipelineState(PSODesc, &mAsteroidsPSO);
+ mAsteroidsPSO->GetStaticVariableByName(SHADER_TYPE_VERTEX, "DrawConstantBuffer")->Set(mDrawConstantBuffer);
+
Uint32 NumSRBs = 0;
if(m_BindingMode == BindingMode::Dynamic)
{
+ // Create one SRB per subset for dynamic binding mode
NumSRBs = mNumSubsets;
}
else if(m_BindingMode == BindingMode::Mutable)
{
+ // Create one SRB per asteroid in mutable binding mode
PSODesc.SRBAllocationGranularity = 1024;
NumSRBs = NUM_ASTEROIDS;
}
else if(m_BindingMode == BindingMode::TextureMutable)
{
+ // Create one SRB per texture in texture-mutable binding mode
PSODesc.SRBAllocationGranularity = NUM_UNIQUE_TEXTURES;
NumSRBs = NUM_UNIQUE_TEXTURES;
}
else if(m_BindingMode == BindingMode::Bindless)
{
+ // Create one SRB per subset for bindless mode
NumSRBs = mNumSubsets;
}
- mDevice->CreatePipelineState(PSODesc, &mAsteroidsPSO);
- if (m_BindingMode != BindingMode::Bindless)
- mAsteroidsPSO->GetStaticVariableByName(SHADER_TYPE_VERTEX, "DrawConstantBuffer")->Set(mDrawConstantBuffer);
-
mAsteroidsSRBs.resize(NumSRBs);
for(size_t srb = 0; srb < mAsteroidsSRBs.size(); ++srb)
{
@@ -583,6 +603,7 @@ Asteroids::Asteroids(const Settings &settings, AsteroidsSimulation* asteroids, G
InitializeTextureData();
if( m_BindingMode == BindingMode::Mutable )
{
+ // Bind the corresponding texture to the asteroids's SRB
for(size_t srb = 0; srb < NUM_ASTEROIDS; ++srb)
{
auto staticData = &mAsteroids->StaticData()[srb];
@@ -591,6 +612,7 @@ Asteroids::Asteroids(const Settings &settings, AsteroidsSimulation* asteroids, G
}
else if( m_BindingMode == BindingMode::TextureMutable )
{
+ // Bind the corresponding texture to the textures's SRB
for(size_t srb = 0; srb < NUM_UNIQUE_TEXTURES; ++srb)
{
mAsteroidsSRBs[srb]->GetVariableByName(SHADER_TYPE_PIXEL, "Tex")->Set(mTextureSRVs[srb]);
@@ -598,6 +620,7 @@ Asteroids::Asteroids(const Settings &settings, AsteroidsSimulation* asteroids, G
}
else if( m_BindingMode == BindingMode::Bindless )
{
+ // Bind all textures to every subset's SRB. The textures will be dynamically indexed in the shader.
IDeviceObject* SRVArray[NUM_UNIQUE_TEXTURES];
for(Uint32 t = 0; t < NUM_UNIQUE_TEXTURES; ++t)
SRVArray[t] = mTextureSRVs[t];
@@ -624,7 +647,6 @@ Asteroids::~Asteroids()
}
-
void Asteroids::ResizeSwapChain(HWND outputWindow, unsigned int width, unsigned int height)
{
mSwapChain->Resize(width, height);
@@ -833,32 +855,37 @@ void Asteroids::RenderSubset(Diligent::Uint32 SubsetNum,
{
IBuffer* ia_buffers[] = { mVertexBuffer, mInstanceIDBuffer };
Uint32 ia_offsets[_countof(ia_buffers)] = {};
+ // Bind instance data buffer in bindless mode
pCtx->SetVertexBuffers(0, (m_BindingMode == BindingMode::Bindless) ? 2 : 1, ia_buffers, ia_offsets, RESOURCE_STATE_TRANSITION_MODE_VERIFY, SET_VERTEX_BUFFERS_FLAG_NONE);
pCtx->SetIndexBuffer(mIndexBuffer, 0, RESOURCE_STATE_TRANSITION_MODE_VERIFY);
}
- auto viewProjection = camera.ViewProjection();
-
if (m_BindingMode == BindingMode::Bindless)
{
{
- MapHelper<DrawConstantBuffer> drawConstants(pCtx, mAsteroidsDataBuffers[SubsetNum], MAP_WRITE, MAP_FLAG_DISCARD);
+ // Update asteroid data buffer
+ MapHelper<AsteroidData> asteroidData(pCtx, mAsteroidsDataBuffers[SubsetNum], MAP_WRITE, MAP_FLAG_DISCARD);
UINT i=0;
for (UINT drawIdx = startIdx; drawIdx < startIdx+numAsteroids; ++drawIdx, ++i)
{
const auto staticData = &staticAsteroidData[drawIdx];
const auto dynamicData = &dynamicAsteroidData[drawIdx];
- XMStoreFloat4x4(&drawConstants[i].mWorld, dynamicData->world);
- XMStoreFloat4x4(&drawConstants[i].mViewProjection, viewProjection);
- drawConstants[i].mSurfaceColor = staticData->surfaceColor;
- drawConstants[i].mDeepColor = staticData->deepColor;
- drawConstants[i].mTextureIndex = staticData->textureIndex;
+ XMStoreFloat4x4(&asteroidData[i].mWorld, dynamicData->world);
+ asteroidData[i].mSurfaceColor = staticData->surfaceColor;
+ asteroidData[i].mDeepColor = staticData->deepColor;
+ asteroidData[i].mTextureIndex = staticData->textureIndex;
}
}
- pCtx->CommitShaderResources(mAsteroidsSRBs[SubsetNum], RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
+
+ StateTransitionDesc Barrier{mAsteroidsDataBuffers[SubsetNum], RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_SHADER_RESOURCE, true};
+ pCtx->TransitionResourceStates(1, &Barrier);
+
+ // Commit and verify resources
+ pCtx->CommitShaderResources(mAsteroidsSRBs[SubsetNum], RESOURCE_STATE_TRANSITION_MODE_VERIFY);
}
+ const auto& viewProjection = camera.ViewProjection();
auto pVar = m_BindingMode == BindingMode::Dynamic ? mAsteroidsSRBs[SubsetNum]->GetVariableByName(SHADER_TYPE_PIXEL, "Tex") : nullptr;
for (UINT drawIdx = startIdx; drawIdx < startIdx+numAsteroids; ++drawIdx)
{
@@ -872,8 +899,8 @@ void Asteroids::RenderSubset(Diligent::Uint32 SubsetNum,
XMStoreFloat4x4(&drawConstants->mViewProjection, viewProjection);
drawConstants->mSurfaceColor = staticData->surfaceColor;
drawConstants->mDeepColor = staticData->deepColor;
- drawConstants->mTextureIndex = staticData->textureIndex;
}
+ // No need to update the buffer in bindless mode
if( m_BindingMode == BindingMode::Dynamic )
{
@@ -891,8 +918,16 @@ void Asteroids::RenderSubset(Diligent::Uint32 SubsetNum,
DrawIndexedAttribs attribs(dynamicData->indexCount, VT_UINT16, DRAW_FLAG_VERIFY_ALL);
attribs.FirstIndexLocation = dynamicData->indexStart;
- attribs.BaseVertex = staticData->vertexStart;
- attribs.FirstInstanceLocation = drawIdx - startIdx;
+ attribs.BaseVertex = staticData->vertexStart;
+
+ if( m_BindingMode == BindingMode::Bindless )
+ {
+ // It is very important to speciy this flag to make sure the engine does not do extra
+ // work processing buffers that stay intact.
+ attribs.Flags |= DRAW_FLAG_RESOURCE_BUFFERS_INTACT;
+ attribs.FirstInstanceLocation = drawIdx - startIdx;
+ }
+
pCtx->DrawIndexed(attribs);
}
}
@@ -915,13 +950,23 @@ void Asteroids::Render(float frameTime, const OrbitCamera& camera, const Setting
auto SubsetSize = NUM_ASTEROIDS / mNumSubsets;
+ if (m_BindingMode == BindingMode::Bindless)
+ {
+ // Write view-projection matrix into the buffer
+ const auto& viewProjection = camera.ViewProjection();
+ mDeviceCtxt->UpdateBuffer(mDrawConstantBuffer, 0, sizeof(DirectX::XMFLOAT4X4), (void*)&viewProjection, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
+ // Explicitly transition the buffer to CONSTANT_BUFFER state
+ StateTransitionDesc Barrier{mDrawConstantBuffer, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_CONSTANT_BUFFER, true};
+ mDeviceCtxt->TransitionResourceStates(1, &Barrier);
+ }
+
if (settings.multithreadedRendering)
{
m_NumThreadsCompleted = 0;
mUpdateSubsetsSignal.Trigger(true);
}
-
+ // Update all subsets in this thread when multithreadedRendering is false
for(Uint32 i=0; i < (!settings.multithreadedRendering ? mNumSubsets : 1); ++i)
mAsteroids->Update(frameTime, camera.Eye(), settings, SubsetSize * i, SubsetSize);
@@ -933,7 +978,6 @@ void Asteroids::Render(float frameTime, const OrbitCamera& camera, const Setting
// Reset mUpdateSubsetsSignal while all threads are waiting for mRenderSubsetsSignal
mUpdateSubsetsSignal.Reset();
}
-
QueryPerformanceCounter((LARGE_INTEGER*)&currCounter);
mUpdateTicks = currCounter-mUpdateTicks;
@@ -947,6 +991,7 @@ void Asteroids::Render(float frameTime, const OrbitCamera& camera, const Setting
mRenderSubsetsSignal.Trigger(true);
}
+ // Render all subsets in this thread when multithreadedRendering is false
for(Uint32 i=0; i < (!settings.multithreadedRendering ? mNumSubsets : 1); ++i)
RenderSubset(i, mDeviceCtxt, camera, SubsetSize * i, SubsetSize);