|
|
|
@ -286,6 +286,38 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
|
|
|
|
|
if (g_debug_context)
|
|
|
|
|
g_debug_context->OnEvent(DebugContext::Event::IncomingPrimitiveBatch, nullptr);
|
|
|
|
|
|
|
|
|
|
PrimitiveAssembler<Shader::OutputVertex>& primitive_assembler = g_state.primitive_assembler;
|
|
|
|
|
|
|
|
|
|
bool accelerate_draw = VideoCore::g_hw_shader_enabled && primitive_assembler.IsEmpty();
|
|
|
|
|
|
|
|
|
|
if (regs.pipeline.use_gs == PipelineRegs::UseGS::No) {
|
|
|
|
|
auto topology = primitive_assembler.GetTopology();
|
|
|
|
|
if (topology == PipelineRegs::TriangleTopology::Shader ||
|
|
|
|
|
topology == PipelineRegs::TriangleTopology::List) {
|
|
|
|
|
accelerate_draw = accelerate_draw && (regs.pipeline.num_vertices % 3) == 0;
|
|
|
|
|
}
|
|
|
|
|
// TODO (wwylele): for Strip/Fan topology, if the primitive assember is not restarted
|
|
|
|
|
// after this draw call, the buffered vertex from this draw should "leak" to the next
|
|
|
|
|
// draw, in which case we should buffer the vertex into the software primitive assember,
|
|
|
|
|
// or disable accelerate draw completely. However, there is not game found yet that does
|
|
|
|
|
// this, so this is left unimplemented for now. Revisit this when an issue is found in
|
|
|
|
|
// games.
|
|
|
|
|
} else {
|
|
|
|
|
if (VideoCore::g_hw_shader_accurate_gs) {
|
|
|
|
|
accelerate_draw = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool is_indexed = (id == PICA_REG_INDEX(pipeline.trigger_draw_indexed));
|
|
|
|
|
|
|
|
|
|
if (accelerate_draw &&
|
|
|
|
|
VideoCore::g_renderer->Rasterizer()->AccelerateDrawBatch(is_indexed)) {
|
|
|
|
|
if (g_debug_context) {
|
|
|
|
|
g_debug_context->OnEvent(DebugContext::Event::FinishedPrimitiveBatch, nullptr);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Processes information about internal vertex attributes to figure out how a vertex is
|
|
|
|
|
// loaded.
|
|
|
|
|
// Later, these can be compiled and cached.
|
|
|
|
@ -294,15 +326,11 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
|
|
|
|
|
Shader::OutputVertex::ValidateSemantics(regs.rasterizer);
|
|
|
|
|
|
|
|
|
|
// Load vertices
|
|
|
|
|
bool is_indexed = (id == PICA_REG_INDEX(pipeline.trigger_draw_indexed));
|
|
|
|
|
|
|
|
|
|
const auto& index_info = regs.pipeline.index_array;
|
|
|
|
|
const u8* index_address_8 = Memory::GetPhysicalPointer(base_address + index_info.offset);
|
|
|
|
|
const u16* index_address_16 = reinterpret_cast<const u16*>(index_address_8);
|
|
|
|
|
bool index_u16 = index_info.format != 0;
|
|
|
|
|
|
|
|
|
|
PrimitiveAssembler<Shader::OutputVertex>& primitive_assembler = g_state.primitive_assembler;
|
|
|
|
|
|
|
|
|
|
if (g_debug_context && g_debug_context->recorder) {
|
|
|
|
|
for (int i = 0; i < 3; ++i) {
|
|
|
|
|
const auto texture = regs.texturing.GetTextures()[i];
|
|
|
|
|