Files
funnygame/materialsystem/vulkan/rendercommandlist.cpp

258 lines
7.2 KiB
C++

#include "vulkan_state.h"
#include "commands.h"
CVkRenderCommandList::~CVkRenderCommandList()
{
ResetRendering();
}
void CVkRenderCommandList::ResetRendering()
{
for ( auto m: m_pCommandBuffers )
{
m_pCommandBufferManager->FreeCommandBufferWithCommands(m);
}
m_pPostRaster = NULL;
m_materials = {};
m_pCommandBuffers = {};
}
void CVkRenderCommandList::SetRenderTarget( uint32_t uIndex, IImage *pImage )
{
SwitchRenderingStage(RENDERING_STAGE_SETUP_RASTER);
VulkanRenderOutput_t *pOutput = FindOrCreateRenderOutput(uIndex);
pOutput->m_stImage.m_eObjectType = FRAME_OBJECT_TYPE_SINGLE;
pOutput->m_stImage.m_pSingle = pImage;
}
void CVkRenderCommandList::SetClearColor( uint32_t uIndex, float r, float g, float b, float a )
{
SwitchRenderingStage(RENDERING_STAGE_SETUP_RASTER);
VulkanRenderOutput_t *pOutput = FindOrCreateRenderOutput(uIndex);
pOutput->m_fClearColor[0] = r;
pOutput->m_fClearColor[1] = g;
pOutput->m_fClearColor[2] = b;
pOutput->m_fClearColor[3] = a;
}
void CVkRenderCommandList::SetDepthTarget( IImage *pDepth )
{
SwitchRenderingStage(RENDERING_STAGE_SETUP_RASTER);
if (pDepth)
{
m_bDepthEnabled = true;
m_depth.m_stImage.m_pSingle = pDepth;
}
else
{
m_bDepthEnabled = false;
}
}
void CVkRenderCommandList::SetClearDepth( float fVal)
{
SwitchRenderingStage(RENDERING_STAGE_SETUP_RASTER);
m_depth.m_fClearDepth = fVal;
}
void CVkRenderCommandList::SetRenderResolution( uint32_t iWidth, uint32_t iHeight )
{
SwitchRenderingStage(RENDERING_STAGE_SETUP_RASTER);
m_uWidth = iWidth;
m_uHeight = iHeight;
}
void CVkRenderCommandList::SetScissors( uint32_t uX, uint32_t uY, uint32_t uWidth, uint32_t uHeight )
{
SwitchRenderingStage(RENDERING_STAGE_RASTER);
}
void CVkRenderCommandList::SetViewport( uint32_t uX, uint32_t uY, uint32_t uWidth, uint32_t uHeight, float fMinDepth, float fMaxDepth )
{
SwitchRenderingStage(RENDERING_STAGE_RASTER);
}
void CVkRenderCommandList::SetMaterial( IMaterial *pMaterial )
{
SwitchRenderingStage(RENDERING_STAGE_SETUP_RASTER);
bool bWasCreated = false;
m_pCurrentMaterialBuffer = FindOrCreateMaterialCommandBuffer(pMaterial, &bWasCreated);
if (bWasCreated)
{
m_pCurrentMaterialBuffer->Reset();
CVkBeginCommand *pBeginCommand = CREATE_COMMAND(m_pCommandBufferManager, Begin);
pBeginCommand->images = m_pOutput;
pBeginCommand->nResolutionX = m_uWidth;
pBeginCommand->nResolutionY = m_uHeight;
for ( auto &i: pBeginCommand->images)
{
pBeginCommand->AddDependency(i.m_stImage.m_pSingle, DEPENDENCY_MODE_DRAWCALL_OUTPUT_IMAGE);
}
if ( m_bDepthEnabled )
{
pBeginCommand->AddDependency(m_depth.m_stImage.m_pSingle, DEPENDENCY_MODE_DRAWCALL_OUTPUT_DEPTH_IMAGE);
pBeginCommand->bDepthEnabled = m_bDepthEnabled;
pBeginCommand->stDepthImage = m_depth;
}
m_pCurrentMaterialBuffer->AddCommand(pBeginCommand);
CVkSetShaderCommand *pSetShader = CREATE_COMMAND(m_pCommandBufferManager, SetShader);
pSetShader->pShader = ((CVkMaterial*)pMaterial)->m_pVkShader;
m_pCurrentMaterialBuffer->AddCommand(pSetShader);
CVkSetShaderDataCommand *pSetShaderData = CREATE_COMMAND(m_pCommandBufferManager, SetShaderData);
pSetShaderData->pShaderData = pMaterial;
m_pCurrentMaterialBuffer->AddCommand(pSetShaderData);
CVkSetScissorsCommand *pScissorsCommand = CREATE_COMMAND(m_pCommandBufferManager, SetScissors);
pScissorsCommand->uWidth = m_uWidth;
pScissorsCommand->uHeight = m_uHeight;
m_pCurrentMaterialBuffer->AddCommand(pScissorsCommand);
CVkSetViewportCommand *pViewportCommand = CREATE_COMMAND(m_pCommandBufferManager, SetViewport);
pViewportCommand->fX = 0;
pViewportCommand->fY = 0;
pViewportCommand->fWidth = m_uWidth;
pViewportCommand->fHeight = m_uHeight;
pViewportCommand->fDepthMin = 0;
pViewportCommand->fDepthMax = 1;
m_pCurrentMaterialBuffer->AddCommand(pViewportCommand);
}
}
void CVkRenderCommandList::SetVertexBuffer( uint32_t uBinding, IVertexBuffer *pBuffer )
{
SwitchRenderingStage(RENDERING_STAGE_RASTER);
CVkSetVertexBufferCommand *pCmd = CREATE_COMMAND(m_pCommandBufferManager, SetVertexBuffer);
pCmd->uBinding = uBinding;
pCmd->pBuffer = pBuffer;
m_pCurrentMaterialBuffer->AddCommand(pCmd);
}
void CVkRenderCommandList::SetIndexBuffer( IVertexBuffer *pBuffer )
{
SwitchRenderingStage(RENDERING_STAGE_RASTER);
}
void CVkRenderCommandList::DrawPrimitives( uint32_t nVertexCount, uint32_t nFirstVertex, uint32_t nInstanceCount, uint32_t nFirstInstance )
{
SwitchRenderingStage(RENDERING_STAGE_RASTER);
CVkDrawPrimitivesCommand *pCmd = CREATE_COMMAND(m_pCommandBufferManager, DrawPrimitives);
pCmd->nVertexCount = nVertexCount;
pCmd->nFirstVertex = nFirstVertex;
pCmd->nInstanceCount = nInstanceCount;
pCmd->nFirstInstance = nFirstInstance;
m_pCurrentMaterialBuffer->AddCommand(pCmd);
}
void CVkRenderCommandList::DrawPrimitivesIndexed( uint32_t nIndexCount, uint32_t nFirstIndex, uint32_t nVertexOffset, uint32_t nInstanceCount, uint32_t nFirstInstance )
{
SwitchRenderingStage(RENDERING_STAGE_RASTER);
}
void CVkRenderCommandList::ResolveImage( IImage *pOriginal, IImage *pResolved )
{
SwitchRenderingStage(RENDERING_STAGE_POST_RASTER);
CVkResolveImageCommand *pCmd = CREATE_COMMAND(m_pCommandBufferManager, ResolveImage);
pCmd->stInputImage.m_eObjectType = FRAME_OBJECT_TYPE_SINGLE;
pCmd->stInputImage.m_pSingle = pOriginal;
pCmd->stOutputImage.m_eObjectType = FRAME_OBJECT_TYPE_SINGLE;
pCmd->stOutputImage.m_pSingle = pResolved;
pCmd->AddDependency(pOriginal, DEPENDENCY_MODE_IMAGE_SOURCE);
pCmd->AddDependency(pResolved, DEPENDENCY_MODE_IMAGE_DESTINATION);
m_pPostRaster->AddCommand(pCmd);
}
void CVkRenderCommandList::StartRecording()
{
ResetRendering();
}
void CVkRenderCommandList::EndRecording()
{
SwitchRenderingStage(RENDERING_STAGE_FINISHED);
}
void CVkRenderCommandList::Submit()
{
for ( auto m: m_pCommandBuffers)
{
m->Submit();
}
}
void CVkRenderCommandList::SwitchRenderingStage( EVulkanRenderingStage eStage )
{
if (eStage != RENDERING_STAGE_RASTER)
{
for ( auto m: m_materials)
{
CVkEndCommand *pEndCommand = CREATE_COMMAND(m_pCommandBufferManager, End);
m.m_pCommandBuffer->AddCommand(pEndCommand);
m.m_pCommandBuffer->Render();
m_pCommandBuffers.AppendTail(m.m_pCommandBuffer);
}
m_materials = {};
};
if (eStage == RENDERING_STAGE_POST_RASTER)
{
m_pPostRaster = m_pCommandBufferManager->CreateCommandBuffer();
m_pPostRaster->Reset();
}
else
{
if (m_pPostRaster)
{
m_pPostRaster->Render();
m_pCommandBuffers.AppendTail(m_pPostRaster);
}
}
}
VulkanRenderOutput_t *CVkRenderCommandList::FindOrCreateRenderOutput( uint32_t uIndex )
{
for ( auto &v: m_pOutput )
{
if (v.m_uIndex == uIndex)
return &v;
}
VulkanRenderOutput_t output = {};
output.m_uIndex = uIndex;
m_pOutput.AppendTail(output);
return &m_pOutput[m_pOutput.GetSize()-1];
}
IVkCommandBuffer *CVkRenderCommandList::FindOrCreateMaterialCommandBuffer( IMaterial *pMaterial, bool *pbWasCreated )
{
for (auto &m: m_materials)
{
if (m.m_pMaterial == pMaterial)
{
if (pbWasCreated)
*pbWasCreated = false;
return m.m_pCommandBuffer;
}
}
VulkanMaterialCommandBuffer_t mat;
mat.m_pCommandBuffer = m_pCommandBufferManager->CreateCommandBuffer();
mat.m_pMaterial = pMaterial;
m_materials.AppendTail(mat);
if (pbWasCreated)
*pbWasCreated = true;
return m_materials[m_materials.GetSize()-1].m_pCommandBuffer;
}