video_core/command_processor: attempt accelerate draw in draw trigger
This commit is contained in:
parent
9b448a0739
commit
ede0d15fec
|
@ -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];
|
||||
|
|
|
@ -46,12 +46,12 @@ struct PrimitiveAssembler {
|
|||
void Reconfigure(PipelineRegs::TriangleTopology topology);
|
||||
|
||||
/**
|
||||
* Is our internal state empty?
|
||||
* Returns whether the PrimitiveAssembler has an empty internal buffer.
|
||||
*/
|
||||
bool IsEmpty() const;
|
||||
|
||||
/**
|
||||
* What is our triangle topology?
|
||||
* Returns the current topology.
|
||||
*/
|
||||
PipelineRegs::TriangleTopology GetTopology() const;
|
||||
|
||||
|
|
Reference in New Issue