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)
|
if (g_debug_context)
|
||||||
g_debug_context->OnEvent(DebugContext::Event::IncomingPrimitiveBatch, nullptr);
|
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
|
// Processes information about internal vertex attributes to figure out how a vertex is
|
||||||
// loaded.
|
// loaded.
|
||||||
// Later, these can be compiled and cached.
|
// 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);
|
Shader::OutputVertex::ValidateSemantics(regs.rasterizer);
|
||||||
|
|
||||||
// Load vertices
|
// Load vertices
|
||||||
bool is_indexed = (id == PICA_REG_INDEX(pipeline.trigger_draw_indexed));
|
|
||||||
|
|
||||||
const auto& index_info = regs.pipeline.index_array;
|
const auto& index_info = regs.pipeline.index_array;
|
||||||
const u8* index_address_8 = Memory::GetPhysicalPointer(base_address + index_info.offset);
|
const u8* index_address_8 = Memory::GetPhysicalPointer(base_address + index_info.offset);
|
||||||
const u16* index_address_16 = reinterpret_cast<const u16*>(index_address_8);
|
const u16* index_address_16 = reinterpret_cast<const u16*>(index_address_8);
|
||||||
bool index_u16 = index_info.format != 0;
|
bool index_u16 = index_info.format != 0;
|
||||||
|
|
||||||
PrimitiveAssembler<Shader::OutputVertex>& primitive_assembler = g_state.primitive_assembler;
|
|
||||||
|
|
||||||
if (g_debug_context && g_debug_context->recorder) {
|
if (g_debug_context && g_debug_context->recorder) {
|
||||||
for (int i = 0; i < 3; ++i) {
|
for (int i = 0; i < 3; ++i) {
|
||||||
const auto texture = regs.texturing.GetTextures()[i];
|
const auto texture = regs.texturing.GetTextures()[i];
|
||||||
|
|
|
@ -46,12 +46,12 @@ struct PrimitiveAssembler {
|
||||||
void Reconfigure(PipelineRegs::TriangleTopology topology);
|
void Reconfigure(PipelineRegs::TriangleTopology topology);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is our internal state empty?
|
* Returns whether the PrimitiveAssembler has an empty internal buffer.
|
||||||
*/
|
*/
|
||||||
bool IsEmpty() const;
|
bool IsEmpty() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* What is our triangle topology?
|
* Returns the current topology.
|
||||||
*/
|
*/
|
||||||
PipelineRegs::TriangleTopology GetTopology() const;
|
PipelineRegs::TriangleTopology GetTopology() const;
|
||||||
|
|
||||||
|
|
Reference in New Issue