reimplement drawIndexAuto

This commit is contained in:
Asuka 2022-07-07 23:51:29 +08:00
parent 429c766299
commit 9ce4e48278
3 changed files with 65 additions and 51 deletions

View file

@ -64,7 +64,9 @@ namespace sce::Gnm
void GnmCommandBufferDraw::setPrimitiveSetup(PrimitiveSetup reg)
{
VkFrontFace frontFace = reg.getFrontFace() == kPrimitiveSetupFrontFaceCcw ? VK_FRONT_FACE_COUNTER_CLOCKWISE : VK_FRONT_FACE_CLOCKWISE;
VkFrontFace frontFace = reg.getFrontFace() == kPrimitiveSetupFrontFaceCcw
? VK_FRONT_FACE_COUNTER_CLOCKWISE
: VK_FRONT_FACE_CLOCKWISE;
VkPolygonMode polyMode = cvt::convertPolygonMode(reg.getPolygonModeFront());
VkCullModeFlags cullMode = cvt::convertCullMode(reg.getCullFace());
@ -75,7 +77,8 @@ namespace sce::Gnm
m_flags.set(GnmContextFlag::DirtyRasterizerState);
}
void GnmCommandBufferDraw::setScreenScissor(int32_t left, int32_t top, int32_t right, int32_t bottom)
void GnmCommandBufferDraw::setScreenScissor(
int32_t left, int32_t top, int32_t right, int32_t bottom)
{
VkRect2D scissor;
scissor.offset.x = left;
@ -93,7 +96,8 @@ namespace sce::Gnm
}
}
void GnmCommandBufferDraw::setViewport(uint32_t viewportId, float dmin, float dmax, const float scale[3], const float offset[3])
void GnmCommandBufferDraw::setViewport(
uint32_t viewportId, float dmin, float dmax, const float scale[3], const float offset[3])
{
// The viewport's origin in Gnm is in the lower left of the screen,
// with Y pointing up.
@ -145,7 +149,8 @@ namespace sce::Gnm
// TODO:
}
void GnmCommandBufferDraw::setGuardBands(float horzClip, float vertClip, float horzDiscard, float vertDiscard)
void GnmCommandBufferDraw::setGuardBands(
float horzClip, float vertClip, float horzDiscard, float vertDiscard)
{
// TODO:
}
@ -172,8 +177,9 @@ namespace sce::Gnm
auto& ctx = m_state.gp.sc[kShaderStagePs];
ctx.code = psRegs->getCodeAddress();
const SPI_SHADER_PGM_RSRC2_PS* rsrc2 = reinterpret_cast<const SPI_SHADER_PGM_RSRC2_PS*>(&psRegs->spiShaderPgmRsrc2Ps);
ctx.meta.ps.userSgprCount = rsrc2->user_sgpr;
const SPI_SHADER_PGM_RSRC2_PS* rsrc2 =
reinterpret_cast<const SPI_SHADER_PGM_RSRC2_PS*>(&psRegs->spiShaderPgmRsrc2Ps);
ctx.meta.ps.userSgprCount = rsrc2->user_sgpr;
const SPI_PS_INPUT_ENA* addr = reinterpret_cast<const SPI_PS_INPUT_ENA*>(&psRegs->spiPsInputAddr);
ctx.meta.ps.perspSampleEn = addr->persp_sample_ena;
@ -199,8 +205,9 @@ namespace sce::Gnm
auto& ctx = m_state.gp.sc[kShaderStageVs];
ctx.code = vsRegs->getCodeAddress();
const SPI_SHADER_PGM_RSRC2_VS* rsrc2 = reinterpret_cast<const SPI_SHADER_PGM_RSRC2_VS*>(&vsRegs->spiShaderPgmRsrc2Vs);
ctx.meta.vs.userSgprCount = rsrc2->user_sgpr;
const SPI_SHADER_PGM_RSRC2_VS* rsrc2 =
reinterpret_cast<const SPI_SHADER_PGM_RSRC2_VS*>(&vsRegs->spiShaderPgmRsrc2Vs);
ctx.meta.vs.userSgprCount = rsrc2->user_sgpr;
}
void GnmCommandBufferDraw::setEmbeddedVsShader(EmbeddedVsShader shaderId, uint32_t shaderModifier)
@ -301,7 +308,8 @@ namespace sce::Gnm
std::memcpy(&m_state.gp.sc[stage].userData[startUserDataSlot], gpuAddr, sizeof(void*));
}
void GnmCommandBufferDraw::setUserDataRegion(ShaderStage stage, uint32_t startUserDataSlot, const uint32_t* userData, uint32_t numDwords)
void GnmCommandBufferDraw::setUserDataRegion(
ShaderStage stage, uint32_t startUserDataSlot, const uint32_t* userData, uint32_t numDwords)
{
std::memcpy(&m_state.gp.sc[stage].userData[startUserDataSlot], userData, numDwords * sizeof(uint32_t));
}
@ -591,13 +599,9 @@ namespace sce::Gnm
void GnmCommandBufferDraw::drawIndexAuto(uint32_t indexCount, DrawModifier modifier)
{
// If the index size is currently 32 bits, this command will partially set it to 16 bits
m_state.gp.ia.indexType = VK_INDEX_TYPE_UINT16;
m_state.gp.ia.indexBuffer = generateIndexBufferAuto(indexCount);
commitGraphicsState<false>();
commitGraphicsState();
m_context->drawIndexed(indexCount, 1, 0, 0, 0);
m_context->draw(indexCount, 1, 0, 0);
}
void GnmCommandBufferDraw::drawIndexAuto(uint32_t indexCount)
@ -609,14 +613,9 @@ namespace sce::Gnm
void GnmCommandBufferDraw::drawIndex(uint32_t indexCount, const void* indexAddr, DrawModifier modifier)
{
uint32_t indexBufferSize =
m_state.gp.ia.indexType == VK_INDEX_TYPE_UINT16
? sizeof(uint16_t) * indexCount
: sizeof(uint32_t) * indexCount;
updateIndexBuffer(indexAddr, indexCount);
m_state.gp.ia.indexBuffer = generateIndexBuffer(indexAddr, indexBufferSize);
commitGraphicsState();
commitGraphicsState<true>();
m_context->drawIndexed(indexCount, 1, 0, 0, 0);
}
@ -954,6 +953,19 @@ namespace sce::Gnm
bindings.data());
}
void GnmCommandBufferDraw::updateIndexBuffer(
const void* indexAddr,
uint32_t indexCount)
{
uint32_t indexBufferSize =
m_state.gp.ia.indexType == VK_INDEX_TYPE_UINT16
? sizeof(uint16_t) * indexCount
: sizeof(uint32_t) * indexCount;
m_state.gp.ia.indexBuffer =
generateIndexBuffer(indexAddr, indexBufferSize);
}
void GnmCommandBufferDraw::bindVertexBuffers(
gcn::VertexInputSemanticTable& semantic,
const uint32_t* vertexTable,
@ -1003,6 +1015,7 @@ namespace sce::Gnm
m_state.gp.ia.indexType);
}
template <bool Indexed>
void GnmCommandBufferDraw::updateVertexShaderStage()
{
// Update vertex input
@ -1018,7 +1031,10 @@ namespace sce::Gnm
auto shader = getShader(ctx.code);
auto& resTable = shader.getResources();
bindIndexBuffer();
if constexpr (Indexed)
{
bindIndexBuffer();
}
// Update input layout and bind vertex buffer
updateVertexBinding(shader);
@ -1057,20 +1073,15 @@ namespace sce::Gnm
} while (false);
}
template <bool Indexed>
void GnmCommandBufferDraw::commitGraphicsState()
{
updateVertexShaderStage();
updateVertexShaderStage<Indexed>();
updatePixelShaderStage();
applyRenderState();
// Set default ms state
VltMultisampleState msState;
msState.enableAlphaToCoverage = VK_FALSE;
msState.sampleMask = 0xFFFFFFFF;
m_context->setMultisampleState(msState);
// Flush memory to buffer and texture resources.
m_initializer->flush();
// Process pending upload/download
@ -1461,4 +1472,5 @@ namespace sce::Gnm
}
} // namespace sce::Gnm

View file

@ -172,11 +172,15 @@ namespace sce::Gnm
const uint32_t* vertexTable,
uint32_t bufferCount);
void updateIndexBuffer(
const void* indexAddr,
uint32_t indexCount);
void updateVertexBinding(GnmShader& shader);
template<bool Indexed>
void updateVertexShaderStage();
void updatePixelShaderStage();
template <bool Indexed>
void commitGraphicsState();
void commitComputeState();

View file

@ -354,29 +354,27 @@ namespace sce::Gnm::cvt
VkPrimitiveTopology convertPrimitiveType(PrimitiveType primType)
{
VkPrimitiveTopology topology;
switch (primType)
{
case kPrimitiveTypeNone: topology = VK_PRIMITIVE_TOPOLOGY_MAX_ENUM; break;
case kPrimitiveTypePointList: topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST; break;
case kPrimitiveTypeLineList: topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST; break;
case kPrimitiveTypeLineStrip: topology = VK_PRIMITIVE_TOPOLOGY_LINE_STRIP; break;
case kPrimitiveTypeTriList: topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; break;
case kPrimitiveTypeTriFan: topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN; break;
case kPrimitiveTypeTriStrip: topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; break;
case kPrimitiveTypePatch: topology = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST; break;
case kPrimitiveTypeLineListAdjacency: topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY; break;
case kPrimitiveTypeLineStripAdjacency: topology = VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY; break;
case kPrimitiveTypeTriListAdjacency: topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY; break;
case kPrimitiveTypeTriStripAdjacency: topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY; break;
// Not supported by vulkan
//case kPrimitiveTypeRectList: topology = ; break;
//case kPrimitiveTypeLineLoop: topology = ; break;
//case kPrimitiveTypeQuadList: topology = ; break;
//case kPrimitiveTypeQuadStrip: topology = ; break;
//case kPrimitiveTypePolygon: topology = ; break;
case kPrimitiveTypeNone: topology = VK_PRIMITIVE_TOPOLOGY_MAX_ENUM; break;
case kPrimitiveTypePointList: topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST; break;
case kPrimitiveTypeLineList: topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST; break;
case kPrimitiveTypeLineStrip: topology = VK_PRIMITIVE_TOPOLOGY_LINE_STRIP; break;
case kPrimitiveTypeTriList: topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; break;
case kPrimitiveTypeTriFan: topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN; break;
case kPrimitiveTypeTriStrip: topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; break;
case kPrimitiveTypePatch: topology = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST; break;
case kPrimitiveTypeLineListAdjacency: topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY; break;
case kPrimitiveTypeLineStripAdjacency: topology = VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY; break;
case kPrimitiveTypeTriListAdjacency: topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY; break;
case kPrimitiveTypeTriStripAdjacency: topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY; break;
// Not supported by vulkan
//case kPrimitiveTypeRectList: topology = ; break;
//case kPrimitiveTypeLineLoop: topology = ; break;
//case kPrimitiveTypeQuadList: topology = ; break;
//case kPrimitiveTypeQuadStrip: topology = ; break;
//case kPrimitiveTypePolygon: topology = ; break;
default:
topology = VK_PRIMITIVE_TOPOLOGY_MAX_ENUM;
LOG_ERR("unsupported PrimitiveType %d", primType);