mirror of
https://github.com/cemu-project/Cemu.git
synced 2026-07-10 01:24:41 -06:00
Vulkan: Separate function for continued drawcalls
This commit is contained in:
parent
87f522102b
commit
5cf665f281
@ -70,6 +70,15 @@ struct LatteGPUState_t
|
||||
|
||||
extern LatteGPUState_t LatteGPUState;
|
||||
|
||||
// drawcall context
|
||||
|
||||
struct LatteDrawcallContext
|
||||
{
|
||||
bool isFirst{}; // first _execute() in current sequence
|
||||
// these are only valid if isFirst is false:
|
||||
// todo
|
||||
};
|
||||
|
||||
// texture
|
||||
|
||||
#include "Cafe/HW/Latte/Core/LatteTexture.h"
|
||||
|
||||
@ -1,10 +1,8 @@
|
||||
#include "Cafe/HW/Latte/ISA/RegDefines.h"
|
||||
#include "Cafe/OS/libs/gx2/GX2.h" // for write gatherer and special state. Get rid of dependency
|
||||
#include "Cafe/OS/libs/gx2/GX2_Misc.h" // for GX2::sGX2MainCoreIndex. Legacy dependency
|
||||
#include "Cafe/OS/libs/gx2/GX2_Event.h" // for notification callbacks
|
||||
#include "Cafe/HW/Latte/Renderer/Renderer.h"
|
||||
#include "Cafe/HW/Latte/Core/Latte.h"
|
||||
#include "Cafe/HW/Latte/Core/LatteDraw.h"
|
||||
#include "Cafe/HW/Latte/Core/LatteShader.h"
|
||||
#include "Cafe/HW/Latte/Core/LatteAsyncCommands.h"
|
||||
#include "Cafe/HW/Latte/Core/LattePerformanceMonitor.h"
|
||||
@ -53,7 +51,7 @@ public:
|
||||
void beginDrawPass()
|
||||
{
|
||||
m_drawPassActive = true;
|
||||
m_isFirstDraw = true;
|
||||
m_drawcallContext.isFirst = true;
|
||||
m_vertexBufferChanged = true;
|
||||
m_uniformBufferChanged = true;
|
||||
g_renderer->draw_beginSequence();
|
||||
@ -71,16 +69,16 @@ public:
|
||||
if (physIndices == MPTR_NULL)
|
||||
return;
|
||||
auto indexType = LatteGPUState.contextNew.VGT_DMA_INDEX_TYPE.get_INDEX_TYPE();
|
||||
g_renderer->draw_execute(baseVertex, baseInstance, numInstances, count, physIndices, indexType, m_isFirstDraw);
|
||||
g_renderer->draw_execute(baseVertex, baseInstance, numInstances, count, physIndices, indexType, m_drawcallContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_renderer->draw_execute(baseVertex, baseInstance, numInstances, count, MPTR_NULL, Latte::LATTE_VGT_DMA_INDEX_TYPE::E_INDEX_TYPE::AUTO, m_isFirstDraw);
|
||||
g_renderer->draw_execute(baseVertex, baseInstance, numInstances, count, MPTR_NULL, Latte::LATTE_VGT_DMA_INDEX_TYPE::E_INDEX_TYPE::AUTO, m_drawcallContext);
|
||||
}
|
||||
performanceMonitor.cycle[performanceMonitor.cycleIndex].drawCallCounter++;
|
||||
if (!m_isFirstDraw)
|
||||
if (!m_drawcallContext.isFirst)
|
||||
performanceMonitor.cycle[performanceMonitor.cycleIndex].fastDrawCallCounter++;
|
||||
m_isFirstDraw = false;
|
||||
m_drawcallContext.isFirst = false;
|
||||
m_vertexBufferChanged = false;
|
||||
m_uniformBufferChanged = false;
|
||||
}
|
||||
@ -121,7 +119,7 @@ public:
|
||||
|
||||
private:
|
||||
bool m_drawPassActive{ false };
|
||||
bool m_isFirstDraw{false};
|
||||
LatteDrawcallContext m_drawcallContext{};
|
||||
bool m_vertexBufferChanged{ false };
|
||||
bool m_uniformBufferChanged{ false };
|
||||
boost::container::static_vector<CmdQueuePos, 4> m_queuePosStack;
|
||||
|
||||
@ -1067,7 +1067,7 @@ void MetalRenderer::draw_beginSequence()
|
||||
m_state.m_skipDrawSequence = true;
|
||||
}
|
||||
|
||||
void MetalRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32 instanceCount, uint32 count, MPTR indexDataMPTR, Latte::LATTE_VGT_DMA_INDEX_TYPE::E_INDEX_TYPE indexType, bool isFirst)
|
||||
void MetalRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32 instanceCount, uint32 count, MPTR indexDataMPTR, Latte::LATTE_VGT_DMA_INDEX_TYPE::E_INDEX_TYPE indexType, const LatteDrawcallContext& drawcallContext)
|
||||
{
|
||||
if (m_state.m_skipDrawSequence)
|
||||
{
|
||||
|
||||
@ -250,7 +250,7 @@ public:
|
||||
|
||||
// core drawing logic
|
||||
void draw_beginSequence() override;
|
||||
void draw_execute(uint32 baseVertex, uint32 baseInstance, uint32 instanceCount, uint32 count, MPTR indexDataMPTR, Latte::LATTE_VGT_DMA_INDEX_TYPE::E_INDEX_TYPE indexType, bool isFirst) override;
|
||||
void draw_execute(uint32 baseVertex, uint32 baseInstance, uint32 instanceCount, uint32 count, MPTR indexDataMPTR, Latte::LATTE_VGT_DMA_INDEX_TYPE::E_INDEX_TYPE indexType, const LatteDrawcallContext& drawcallContext) override;
|
||||
void draw_endSequence() override;
|
||||
|
||||
void draw_updateVertexBuffersDirectAccess();
|
||||
|
||||
@ -159,7 +159,7 @@ public:
|
||||
void draw_init();
|
||||
|
||||
void draw_beginSequence() override;
|
||||
void draw_execute(uint32 baseVertex, uint32 baseInstance, uint32 instanceCount, uint32 count, MPTR indexDataMPTR, Latte::LATTE_VGT_DMA_INDEX_TYPE::E_INDEX_TYPE indexType, bool isFirst) override;
|
||||
void draw_execute(uint32 baseVertex, uint32 baseInstance, uint32 instanceCount, uint32 count, MPTR indexDataMPTR, Latte::LATTE_VGT_DMA_INDEX_TYPE::E_INDEX_TYPE indexType, const LatteDrawcallContext& drawcallContext) override;
|
||||
void draw_endSequence() override;
|
||||
|
||||
template<bool TIsMinimal, bool THasProfiling>
|
||||
|
||||
@ -1148,9 +1148,9 @@ void OpenGLRenderer::draw_beginSequence()
|
||||
// no-op
|
||||
}
|
||||
|
||||
void OpenGLRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32 instanceCount, uint32 count, MPTR indexDataMPTR, Latte::LATTE_VGT_DMA_INDEX_TYPE::E_INDEX_TYPE indexType, bool isFirst)
|
||||
void OpenGLRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32 instanceCount, uint32 count, MPTR indexDataMPTR, Latte::LATTE_VGT_DMA_INDEX_TYPE::E_INDEX_TYPE indexType, const LatteDrawcallContext& drawcallContext)
|
||||
{
|
||||
bool isMinimal = !isFirst;
|
||||
bool isMinimal = !drawcallContext.isFirst;
|
||||
if (isMinimal)
|
||||
draw_genericDrawHandler<true, false>(baseVertex, baseInstance, instanceCount, count, indexDataMPTR, indexType);
|
||||
else
|
||||
|
||||
@ -140,7 +140,7 @@ public:
|
||||
|
||||
// core drawing logic
|
||||
virtual void draw_beginSequence() = 0;
|
||||
virtual void draw_execute(uint32 baseVertex, uint32 baseInstance, uint32 instanceCount, uint32 count, MPTR indexDataMPTR, Latte::LATTE_VGT_DMA_INDEX_TYPE::E_INDEX_TYPE indexType, bool isFirst) = 0;
|
||||
virtual void draw_execute(uint32 baseVertex, uint32 baseInstance, uint32 instanceCount, uint32 count, MPTR indexDataMPTR, Latte::LATTE_VGT_DMA_INDEX_TYPE::E_INDEX_TYPE indexType, const LatteDrawcallContext& drawcallContext) = 0;
|
||||
virtual void draw_endSequence() = 0;
|
||||
|
||||
// index
|
||||
|
||||
@ -530,7 +530,7 @@ private:
|
||||
void draw_endRenderPass();
|
||||
|
||||
void draw_beginSequence() override;
|
||||
void draw_execute(uint32 baseVertex, uint32 baseInstance, uint32 instanceCount, uint32 count, MPTR indexDataMPTR, Latte::LATTE_VGT_DMA_INDEX_TYPE::E_INDEX_TYPE indexType, bool isFirst) override;
|
||||
void draw_execute(uint32 baseVertex, uint32 baseInstance, uint32 instanceCount, uint32 count, MPTR indexDataMPTR, Latte::LATTE_VGT_DMA_INDEX_TYPE::E_INDEX_TYPE indexType, const LatteDrawcallContext& drawcallContext) override;
|
||||
void draw_endSequence() override;
|
||||
|
||||
void draw_updateVertexBuffersDirectAccess();
|
||||
@ -663,6 +663,10 @@ private:
|
||||
uint32 m_submitThreshold{}; // submit current buffer if recordedDrawcalls exceeds this number
|
||||
bool m_submitOnIdle{}; // submit current buffer if Latte command processor goes into idle state (no more commands or waiting for externally signaled condition)
|
||||
|
||||
// drawcall handling
|
||||
void draw_execute_first(uint32 baseVertex, uint32 baseInstance, uint32 instanceCount, uint32 count, MPTR indexDataMPTR, Latte::LATTE_VGT_DMA_INDEX_TYPE::E_INDEX_TYPE indexType, const LatteDrawcallContext& drawcallContext);
|
||||
void draw_execute_continued(uint32 baseVertex, uint32 baseInstance, uint32 instanceCount, uint32 count, MPTR indexDataMPTR, Latte::LATTE_VGT_DMA_INDEX_TYPE::E_INDEX_TYPE indexType, const LatteDrawcallContext& drawcallContext);
|
||||
|
||||
// tracking for dynamic offsets
|
||||
struct
|
||||
{
|
||||
|
||||
@ -1302,11 +1302,177 @@ void VulkanRenderer::draw_beginSequence()
|
||||
m_state.drawSequenceSkip = true;
|
||||
}
|
||||
|
||||
void VulkanRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32 instanceCount, uint32 count, MPTR indexDataMPTR, Latte::LATTE_VGT_DMA_INDEX_TYPE::E_INDEX_TYPE indexType, bool isFirst)
|
||||
void VulkanRenderer::draw_execute_first(uint32 baseVertex, uint32 baseInstance, uint32 instanceCount, uint32 count, MPTR indexDataMPTR, Latte::LATTE_VGT_DMA_INDEX_TYPE::E_INDEX_TYPE indexType, const LatteDrawcallContext& drawcallContext)
|
||||
{
|
||||
if (m_state.drawSequenceSkip)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// fast clear color as depth
|
||||
if (LatteGPUState.contextNew.GetSpecialStateValues()[8] != 0)
|
||||
{
|
||||
LatteDraw_handleSpecialState8_clearAsDepth();
|
||||
return;
|
||||
}
|
||||
else if (LatteGPUState.contextNew.GetSpecialStateValues()[5] != 0)
|
||||
{
|
||||
draw_handleSpecialState5();
|
||||
return;
|
||||
}
|
||||
|
||||
// prepare streamout
|
||||
m_streamoutState.verticesPerInstance = count;
|
||||
LatteStreamout_PrepareDrawcall(count, instanceCount);
|
||||
|
||||
// update uniform vars
|
||||
LatteDecompilerShader* vertexShader = LatteSHRC_GetActiveVertexShader();
|
||||
LatteDecompilerShader* pixelShader = LatteSHRC_GetActivePixelShader();
|
||||
LatteDecompilerShader* geometryShader = LatteSHRC_GetActiveGeometryShader();
|
||||
|
||||
if (vertexShader)
|
||||
uniformData_updateUniformVars(VulkanRendererConst::SHADER_STAGE_INDEX_VERTEX, vertexShader);
|
||||
if (pixelShader)
|
||||
uniformData_updateUniformVars(VulkanRendererConst::SHADER_STAGE_INDEX_FRAGMENT, pixelShader);
|
||||
if (geometryShader)
|
||||
uniformData_updateUniformVars(VulkanRendererConst::SHADER_STAGE_INDEX_GEOMETRY, geometryShader);
|
||||
// store where the read pointer should go after command buffer execution
|
||||
m_cmdBufferUniformRingbufIndices[m_commandBufferIndex] = m_uniformVarBufferWriteIndex;
|
||||
|
||||
// process index data
|
||||
const LattePrimitiveMode primitiveMode = static_cast<LattePrimitiveMode>(LatteGPUState.contextRegister[mmVGT_PRIMITIVE_TYPE]);
|
||||
|
||||
Renderer::INDEX_TYPE hostIndexType;
|
||||
uint32 hostIndexCount;
|
||||
uint32 indexMin = 0;
|
||||
uint32 indexMax = 0;
|
||||
Renderer::IndexAllocation indexAllocation;
|
||||
LatteIndices_decode(memory_getPointerFromVirtualOffset(indexDataMPTR), indexType, count, primitiveMode, indexMin, indexMax, hostIndexType, hostIndexCount, indexAllocation);
|
||||
VKRSynchronizedHeapAllocator::AllocatorReservation* indexReservation = (VKRSynchronizedHeapAllocator::AllocatorReservation*)indexAllocation.rendererInternal;
|
||||
// update index binding
|
||||
if (hostIndexType != INDEX_TYPE::NONE)
|
||||
{
|
||||
uint32 indexBufferIndex = indexReservation->bufferIndex;
|
||||
uint32 indexBufferOffset = indexReservation->bufferOffset;
|
||||
if (m_state.activeIndexBufferOffset != indexBufferOffset || m_state.activeIndexBufferIndex != indexBufferIndex || m_state.activeIndexType != hostIndexType)
|
||||
{
|
||||
m_state.activeIndexType = hostIndexType;
|
||||
m_state.activeIndexBufferOffset = indexBufferOffset;
|
||||
m_state.activeIndexBufferIndex = indexBufferIndex;
|
||||
VkIndexType vkType;
|
||||
if (hostIndexType == INDEX_TYPE::U16)
|
||||
vkType = VK_INDEX_TYPE_UINT16;
|
||||
else if (hostIndexType == INDEX_TYPE::U32)
|
||||
vkType = VK_INDEX_TYPE_UINT32;
|
||||
else
|
||||
cemu_assert(false);
|
||||
vkCmdBindIndexBuffer(m_state.currentCommandBuffer, indexReservation->vkBuffer, indexBufferOffset, vkType);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_useHostMemoryForCache)
|
||||
{
|
||||
// direct memory access (Wii U memory space imported as a Vulkan buffer), update buffer bindings
|
||||
draw_updateVertexBuffersDirectAccess();
|
||||
LatteDecompilerShader* vertexShader = LatteSHRC_GetActiveVertexShader();
|
||||
if (vertexShader)
|
||||
draw_updateUniformBuffersDirectAccess(vertexShader, mmSQ_VTX_UNIFORM_BLOCK_START, LatteConst::ShaderType::Vertex);
|
||||
LatteDecompilerShader* geometryShader = LatteSHRC_GetActiveGeometryShader();
|
||||
if (geometryShader)
|
||||
draw_updateUniformBuffersDirectAccess(geometryShader, mmSQ_GS_UNIFORM_BLOCK_START, LatteConst::ShaderType::Geometry);
|
||||
LatteDecompilerShader* pixelShader = LatteSHRC_GetActivePixelShader();
|
||||
if (pixelShader)
|
||||
draw_updateUniformBuffersDirectAccess(pixelShader, mmSQ_PS_UNIFORM_BLOCK_START, LatteConst::ShaderType::Pixel);
|
||||
}
|
||||
else
|
||||
{
|
||||
// synchronize vertex and uniform cache and update buffer bindings
|
||||
LatteBufferCache_Sync(indexMin + baseVertex, indexMax + baseVertex, baseInstance, instanceCount);
|
||||
}
|
||||
|
||||
PipelineInfo* pipeline_info = draw_getOrCreateGraphicsPipeline(count);
|
||||
m_state.activePipelineInfo = pipeline_info;
|
||||
|
||||
auto vkObjPipeline = pipeline_info->m_vkrObjPipeline;
|
||||
if (vkObjPipeline->GetPipeline() == VK_NULL_HANDLE)
|
||||
{
|
||||
// invalid/uninitialized pipeline
|
||||
m_state.activeVertexDS = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
VkDescriptorSetInfo *vertexDS = nullptr, *pixelDS = nullptr, *geometryDS = nullptr;
|
||||
draw_prepareDescriptorSets(pipeline_info, vertexDS, pixelDS, geometryDS);
|
||||
m_state.activeVertexDS = vertexDS;
|
||||
m_state.activePixelDS = pixelDS;
|
||||
m_state.activeGeometryDS = geometryDS;
|
||||
m_state.descriptorSetsChanged = true;
|
||||
|
||||
draw_setRenderPass();
|
||||
|
||||
if (m_state.currentPipeline != vkObjPipeline->GetPipeline())
|
||||
{
|
||||
vkCmdBindPipeline(m_state.currentCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, vkObjPipeline->GetPipeline());
|
||||
vkObjPipeline->flagForCurrentCommandBuffer();
|
||||
m_state.currentPipeline = vkObjPipeline->GetPipeline();
|
||||
// depth bias
|
||||
if (pipeline_info->usesDepthBias)
|
||||
draw_updateDepthBias(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pipeline_info->usesDepthBias)
|
||||
draw_updateDepthBias(false);
|
||||
}
|
||||
// update blend constants
|
||||
if (pipeline_info->usesBlendConstants)
|
||||
draw_updateVkBlendConstants();
|
||||
// update descriptor sets
|
||||
uint32_t dynamicOffsets[17 * 2];
|
||||
if (vertexDS && pixelDS)
|
||||
{
|
||||
// update vertex and pixel descriptor set in a single call to vkCmdBindDescriptorSets
|
||||
sint32 numDynOffsetsVS;
|
||||
sint32 numDynOffsetsPS;
|
||||
draw_prepareDynamicOffsetsForDescriptorSet(VulkanRendererConst::SHADER_STAGE_INDEX_VERTEX, dynamicOffsets, numDynOffsetsVS, pipeline_info);
|
||||
draw_prepareDynamicOffsetsForDescriptorSet(VulkanRendererConst::SHADER_STAGE_INDEX_FRAGMENT, dynamicOffsets + numDynOffsetsVS, numDynOffsetsPS, pipeline_info);
|
||||
|
||||
VkDescriptorSet dsArray[2];
|
||||
dsArray[0] = vertexDS->m_vkObjDescriptorSet->descriptorSet;
|
||||
dsArray[1] = pixelDS->m_vkObjDescriptorSet->descriptorSet;
|
||||
|
||||
vkCmdBindDescriptorSets(m_state.currentCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, vkObjPipeline->m_pipelineLayout, 0, 2, dsArray, numDynOffsetsVS + numDynOffsetsPS, dynamicOffsets);
|
||||
}
|
||||
else if (vertexDS)
|
||||
{
|
||||
sint32 numDynOffsets;
|
||||
draw_prepareDynamicOffsetsForDescriptorSet(VulkanRendererConst::SHADER_STAGE_INDEX_VERTEX, dynamicOffsets, numDynOffsets, pipeline_info);
|
||||
vkCmdBindDescriptorSets(m_state.currentCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, vkObjPipeline->m_pipelineLayout, 0, 1, &vertexDS->m_vkObjDescriptorSet->descriptorSet, numDynOffsets, dynamicOffsets);
|
||||
}
|
||||
else if (pixelDS)
|
||||
{
|
||||
sint32 numDynOffsets;
|
||||
draw_prepareDynamicOffsetsForDescriptorSet(VulkanRendererConst::SHADER_STAGE_INDEX_FRAGMENT, dynamicOffsets, numDynOffsets, pipeline_info);
|
||||
vkCmdBindDescriptorSets(m_state.currentCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, vkObjPipeline->m_pipelineLayout, 1, 1, &pixelDS->m_vkObjDescriptorSet->descriptorSet, numDynOffsets, dynamicOffsets);
|
||||
}
|
||||
if (geometryDS)
|
||||
{
|
||||
sint32 numDynOffsets;
|
||||
draw_prepareDynamicOffsetsForDescriptorSet(VulkanRendererConst::SHADER_STAGE_INDEX_GEOMETRY, dynamicOffsets, numDynOffsets, pipeline_info);
|
||||
vkCmdBindDescriptorSets(m_state.currentCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, vkObjPipeline->m_pipelineLayout, 2, 1, &geometryDS->m_vkObjDescriptorSet->descriptorSet, numDynOffsets, dynamicOffsets);
|
||||
}
|
||||
// draw
|
||||
if (hostIndexType != INDEX_TYPE::NONE)
|
||||
vkCmdDrawIndexed(m_state.currentCommandBuffer, hostIndexCount, instanceCount, 0, baseVertex, baseInstance);
|
||||
else
|
||||
vkCmdDraw(m_state.currentCommandBuffer, count, instanceCount, baseVertex, baseInstance);
|
||||
LatteStreamout_FinishDrawcall(m_useHostMemoryForCache);
|
||||
}
|
||||
|
||||
void VulkanRenderer::draw_execute_continued(uint32 baseVertex, uint32 baseInstance, uint32 instanceCount, uint32 count, MPTR indexDataMPTR, Latte::LATTE_VGT_DMA_INDEX_TYPE::E_INDEX_TYPE indexType, const LatteDrawcallContext& drawcallContext)
|
||||
{
|
||||
if (m_state.drawSequenceSkip)
|
||||
{
|
||||
LatteGPUState.drawCallCounter++;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1314,13 +1480,11 @@ void VulkanRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32
|
||||
if (LatteGPUState.contextNew.GetSpecialStateValues()[8] != 0)
|
||||
{
|
||||
LatteDraw_handleSpecialState8_clearAsDepth();
|
||||
LatteGPUState.drawCallCounter++;
|
||||
return;
|
||||
}
|
||||
else if (LatteGPUState.contextNew.GetSpecialStateValues()[5] != 0)
|
||||
{
|
||||
draw_handleSpecialState5();
|
||||
LatteGPUState.drawCallCounter++;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1394,31 +1558,23 @@ void VulkanRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32
|
||||
}
|
||||
|
||||
PipelineInfo* pipeline_info;
|
||||
|
||||
if (!isFirst)
|
||||
// recalculate the part of the pipeline hash that can change during fast draws
|
||||
if (m_state.activePipelineInfo->minimalStateHash != draw_calculateMinimalGraphicsPipelineHash(vertexShader->compatibleFetchShader, LatteGPUState.contextNew))
|
||||
{
|
||||
if (m_state.activePipelineInfo->minimalStateHash != draw_calculateMinimalGraphicsPipelineHash(vertexShader->compatibleFetchShader, LatteGPUState.contextNew))
|
||||
{
|
||||
// pipeline changed
|
||||
pipeline_info = draw_getOrCreateGraphicsPipeline(count);
|
||||
m_state.activePipelineInfo = pipeline_info;
|
||||
}
|
||||
else
|
||||
{
|
||||
pipeline_info = m_state.activePipelineInfo;
|
||||
#ifdef CEMU_DEBUG_ASSERT
|
||||
auto pipeline_info2 = draw_getOrCreateGraphicsPipeline(count);
|
||||
if (pipeline_info != pipeline_info2)
|
||||
{
|
||||
cemu_assert_debug(false);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
// pipeline changed
|
||||
pipeline_info = draw_getOrCreateGraphicsPipeline(count);
|
||||
m_state.activePipelineInfo = pipeline_info;
|
||||
}
|
||||
else
|
||||
{
|
||||
pipeline_info = draw_getOrCreateGraphicsPipeline(count);
|
||||
m_state.activePipelineInfo = pipeline_info;
|
||||
pipeline_info = m_state.activePipelineInfo;
|
||||
#ifdef CEMU_DEBUG_ASSERT
|
||||
auto pipeline_info2 = draw_getOrCreateGraphicsPipeline(count);
|
||||
if (pipeline_info != pipeline_info2)
|
||||
{
|
||||
cemu_assert_debug(false);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
auto vkObjPipeline = pipeline_info->m_vkrObjPipeline;
|
||||
@ -1429,9 +1585,8 @@ void VulkanRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
VkDescriptorSetInfo *vertexDS = nullptr, *pixelDS = nullptr, *geometryDS = nullptr;
|
||||
if (!isFirst && m_state.activeVertexDS)
|
||||
if (m_state.activeVertexDS)
|
||||
{
|
||||
vertexDS = m_state.activeVertexDS;
|
||||
pixelDS = m_state.activePixelDS;
|
||||
@ -1510,7 +1665,14 @@ void VulkanRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32
|
||||
vkCmdDraw(m_state.currentCommandBuffer, count, instanceCount, baseVertex, baseInstance);
|
||||
|
||||
LatteStreamout_FinishDrawcall(m_useHostMemoryForCache);
|
||||
}
|
||||
|
||||
void VulkanRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32 instanceCount, uint32 count, MPTR indexDataMPTR, Latte::LATTE_VGT_DMA_INDEX_TYPE::E_INDEX_TYPE indexType, const LatteDrawcallContext& drawcallContext)
|
||||
{
|
||||
if (drawcallContext.isFirst)
|
||||
draw_execute_first(baseVertex, baseInstance, instanceCount, count, indexDataMPTR, indexType, drawcallContext);
|
||||
else
|
||||
draw_execute_continued(baseVertex, baseInstance, instanceCount, count, indexDataMPTR, indexType, drawcallContext);
|
||||
LatteGPUState.drawCallCounter++;
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user