video_core/command_processor: attempt accelerate draw in draw trigger

This commit is contained in:
wwylele 2018-05-11 16:42:29 +03:00
parent 9b448a0739
commit ede0d15fec
2 changed files with 34 additions and 6 deletions

View File

@ -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];

View File

@ -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;