forked from suyu/suyu
VideoCore: Corrections to the MME Inliner and removal of hacky instance management.
This commit is contained in:
parent
ba02d564f8
commit
7606da5611
6 changed files with 81 additions and 31 deletions
|
@ -260,6 +260,9 @@ void Maxwell3D::CallMacroMethod(u32 method, std::size_t num_parameters, const u3
|
||||||
|
|
||||||
// Execute the current macro.
|
// Execute the current macro.
|
||||||
macro_interpreter.Execute(macro_positions[entry], num_parameters, parameters);
|
macro_interpreter.Execute(macro_positions[entry], num_parameters, parameters);
|
||||||
|
if (mme_draw.current_mode != MMMEDrawMode::Undefined) {
|
||||||
|
FlushMMEInlineDraw();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Maxwell3D::CallMethod(const GPU::MethodCall& method_call) {
|
void Maxwell3D::CallMethod(const GPU::MethodCall& method_call) {
|
||||||
|
@ -426,25 +429,37 @@ void Maxwell3D::CallMethodFromMME(const GPU::MethodCall& method_call) {
|
||||||
regs.reg_array[method] = method_call.argument;
|
regs.reg_array[method] = method_call.argument;
|
||||||
if (method == MAXWELL3D_REG_INDEX(vertex_buffer.count) ||
|
if (method == MAXWELL3D_REG_INDEX(vertex_buffer.count) ||
|
||||||
method == MAXWELL3D_REG_INDEX(index_array.count)) {
|
method == MAXWELL3D_REG_INDEX(index_array.count)) {
|
||||||
MMMEDrawMode expected_mode = method == MAXWELL3D_REG_INDEX(vertex_buffer.count)
|
const MMMEDrawMode expected_mode = method == MAXWELL3D_REG_INDEX(vertex_buffer.count)
|
||||||
? MMMEDrawMode::Array
|
? MMMEDrawMode::Array
|
||||||
: MMMEDrawMode::Indexed;
|
: MMMEDrawMode::Indexed;
|
||||||
u32 count = method_call.argument;
|
const u32 count = method_call.argument;
|
||||||
while (true) {
|
while (true) {
|
||||||
if (mme_draw.current_mode == MMMEDrawMode::Undefined) {
|
if (mme_draw.current_mode == MMMEDrawMode::Undefined) {
|
||||||
mme_draw.current_mode = expected_mode;
|
if (mme_draw.gl_begin_consume) {
|
||||||
mme_draw.current_count = count;
|
mme_draw.current_mode = expected_mode;
|
||||||
mme_draw.instance_count = 1;
|
mme_draw.current_count = count;
|
||||||
|
mme_draw.instance_count = 1;
|
||||||
|
mme_draw.gl_begin_consume = false;
|
||||||
|
mme_draw.gl_end_count = 0;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
if (mme_draw.current_mode == expected_mode && count == mme_draw.current_count) {
|
if (mme_draw.current_mode == expected_mode && count == mme_draw.current_count &&
|
||||||
|
mme_draw.instance_mode && mme_draw.gl_begin_consume) {
|
||||||
mme_draw.instance_count++;
|
mme_draw.instance_count++;
|
||||||
|
mme_draw.gl_begin_consume = false;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
FlushMMEInlineDraw();
|
FlushMMEInlineDraw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (method == MAXWELL3D_REG_INDEX(draw.vertex_begin_gl)) {
|
||||||
|
mme_draw.instance_mode =
|
||||||
|
(regs.draw.instance_next != 0) || (regs.draw.instance_cont != 0);
|
||||||
|
mme_draw.gl_begin_consume = true;
|
||||||
|
} else {
|
||||||
|
mme_draw.gl_end_count++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (mme_draw.current_mode != MMMEDrawMode::Undefined) {
|
if (mme_draw.current_mode != MMMEDrawMode::Undefined) {
|
||||||
|
@ -458,6 +473,7 @@ void Maxwell3D::FlushMMEInlineDraw() {
|
||||||
LOG_DEBUG(HW_GPU, "called, topology={}, count={}", static_cast<u32>(regs.draw.topology.Value()),
|
LOG_DEBUG(HW_GPU, "called, topology={}, count={}", static_cast<u32>(regs.draw.topology.Value()),
|
||||||
regs.vertex_buffer.count);
|
regs.vertex_buffer.count);
|
||||||
ASSERT_MSG(!(regs.index_array.count && regs.vertex_buffer.count), "Both indexed and direct?");
|
ASSERT_MSG(!(regs.index_array.count && regs.vertex_buffer.count), "Both indexed and direct?");
|
||||||
|
ASSERT(mme_draw.instance_count == mme_draw.gl_end_count);
|
||||||
|
|
||||||
auto debug_context = system.GetGPUDebugContext();
|
auto debug_context = system.GetGPUDebugContext();
|
||||||
|
|
||||||
|
@ -488,6 +504,9 @@ void Maxwell3D::FlushMMEInlineDraw() {
|
||||||
mme_draw.current_mode = MMMEDrawMode::Undefined;
|
mme_draw.current_mode = MMMEDrawMode::Undefined;
|
||||||
mme_draw.current_count = 0;
|
mme_draw.current_count = 0;
|
||||||
mme_draw.instance_count = 0;
|
mme_draw.instance_count = 0;
|
||||||
|
mme_draw.instance_mode = false;
|
||||||
|
mme_draw.gl_begin_consume = false;
|
||||||
|
mme_draw.gl_end_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Maxwell3D::ProcessMacroUpload(u32 data) {
|
void Maxwell3D::ProcessMacroUpload(u32 data) {
|
||||||
|
|
|
@ -1277,8 +1277,11 @@ public:
|
||||||
|
|
||||||
struct MMEDrawState {
|
struct MMEDrawState {
|
||||||
MMMEDrawMode current_mode{MMMEDrawMode::Undefined};
|
MMMEDrawMode current_mode{MMMEDrawMode::Undefined};
|
||||||
u32 current_count;
|
u32 current_count{};
|
||||||
u32 instance_count;
|
u32 instance_count{};
|
||||||
|
bool instance_mode{};
|
||||||
|
bool gl_begin_consume{};
|
||||||
|
u32 gl_end_count{};
|
||||||
} mme_draw;
|
} mme_draw;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -788,13 +788,13 @@ void RasterizerOpenGL::DrawArrays() {
|
||||||
DrawPrelude();
|
DrawPrelude();
|
||||||
|
|
||||||
auto& maxwell3d = system.GPU().Maxwell3D();
|
auto& maxwell3d = system.GPU().Maxwell3D();
|
||||||
auto& regs = maxwell3d.regs;
|
const auto& regs = maxwell3d.regs;
|
||||||
auto current_instance = maxwell3d.state.current_instance;
|
const auto current_instance = maxwell3d.state.current_instance;
|
||||||
auto primitive_mode = MaxwellToGL::PrimitiveTopology(regs.draw.topology);
|
const auto primitive_mode = MaxwellToGL::PrimitiveTopology(regs.draw.topology);
|
||||||
if (accelerate_draw == AccelDraw::Indexed) {
|
if (accelerate_draw == AccelDraw::Indexed) {
|
||||||
auto index_format = MaxwellToGL::IndexFormat(regs.index_array.format);
|
const auto index_format = MaxwellToGL::IndexFormat(regs.index_array.format);
|
||||||
auto count = regs.index_array.count;
|
const auto count = regs.index_array.count;
|
||||||
auto base_vertex = static_cast<GLint>(regs.vb_element_base);
|
const auto base_vertex = static_cast<GLint>(regs.vb_element_base);
|
||||||
const auto index_buffer_ptr = reinterpret_cast<const void*>(index_buffer_offset);
|
const auto index_buffer_ptr = reinterpret_cast<const void*>(index_buffer_offset);
|
||||||
if (current_instance > 0) {
|
if (current_instance > 0) {
|
||||||
glDrawElementsInstancedBaseVertexBaseInstance(primitive_mode, count, index_format,
|
glDrawElementsInstancedBaseVertexBaseInstance(primitive_mode, count, index_format,
|
||||||
|
@ -805,8 +805,8 @@ void RasterizerOpenGL::DrawArrays() {
|
||||||
base_vertex);
|
base_vertex);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto count = regs.vertex_buffer.count;
|
const auto count = regs.vertex_buffer.count;
|
||||||
auto vertex_first = regs.vertex_buffer.first;
|
const auto vertex_first = regs.vertex_buffer.first;
|
||||||
if (current_instance > 0) {
|
if (current_instance > 0) {
|
||||||
glDrawArraysInstancedBaseInstance(primitive_mode, vertex_first, count, 1,
|
glDrawArraysInstancedBaseInstance(primitive_mode, vertex_first, count, 1,
|
||||||
current_instance);
|
current_instance);
|
||||||
|
@ -819,21 +819,19 @@ void RasterizerOpenGL::DrawArrays() {
|
||||||
maxwell3d.dirty.memory_general = false;
|
maxwell3d.dirty.memory_general = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma optimize("", off)
|
|
||||||
|
|
||||||
void RasterizerOpenGL::DrawMultiArrays() {
|
void RasterizerOpenGL::DrawMultiArrays() {
|
||||||
DrawPrelude();
|
DrawPrelude();
|
||||||
|
|
||||||
auto& maxwell3d = system.GPU().Maxwell3D();
|
auto& maxwell3d = system.GPU().Maxwell3D();
|
||||||
auto& regs = maxwell3d.regs;
|
const auto& regs = maxwell3d.regs;
|
||||||
auto& draw_setup = maxwell3d.mme_draw;
|
const auto& draw_setup = maxwell3d.mme_draw;
|
||||||
auto num_instances = draw_setup.instance_count;
|
const auto num_instances = draw_setup.instance_count;
|
||||||
auto base_instance = static_cast<GLint>(regs.vb_base_instance);
|
const auto base_instance = static_cast<GLint>(regs.vb_base_instance);
|
||||||
auto primitive_mode = MaxwellToGL::PrimitiveTopology(regs.draw.topology);
|
const auto primitive_mode = MaxwellToGL::PrimitiveTopology(regs.draw.topology);
|
||||||
if (draw_setup.current_mode == Tegra::Engines::Maxwell3D::MMMEDrawMode::Indexed) {
|
if (draw_setup.current_mode == Tegra::Engines::Maxwell3D::MMMEDrawMode::Indexed) {
|
||||||
auto index_format = MaxwellToGL::IndexFormat(regs.index_array.format);
|
const auto index_format = MaxwellToGL::IndexFormat(regs.index_array.format);
|
||||||
auto count = regs.index_array.count;
|
const auto count = regs.index_array.count;
|
||||||
auto base_vertex = static_cast<GLint>(regs.vb_element_base);
|
const auto base_vertex = static_cast<GLint>(regs.vb_element_base);
|
||||||
const auto index_buffer_ptr = reinterpret_cast<const void*>(index_buffer_offset);
|
const auto index_buffer_ptr = reinterpret_cast<const void*>(index_buffer_offset);
|
||||||
if (num_instances > 1) {
|
if (num_instances > 1) {
|
||||||
glDrawElementsInstancedBaseVertexBaseInstance(primitive_mode, count, index_format,
|
glDrawElementsInstancedBaseVertexBaseInstance(primitive_mode, count, index_format,
|
||||||
|
@ -844,8 +842,8 @@ void RasterizerOpenGL::DrawMultiArrays() {
|
||||||
base_vertex);
|
base_vertex);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto count = regs.vertex_buffer.count;
|
const auto count = regs.vertex_buffer.count;
|
||||||
auto vertex_first = regs.vertex_buffer.first;
|
const auto vertex_first = regs.vertex_buffer.first;
|
||||||
if (num_instances > 1) {
|
if (num_instances > 1) {
|
||||||
glDrawArraysInstancedBaseInstance(primitive_mode, vertex_first, count, num_instances,
|
glDrawArraysInstancedBaseInstance(primitive_mode, vertex_first, count, num_instances,
|
||||||
base_instance);
|
base_instance);
|
||||||
|
|
|
@ -462,6 +462,14 @@ private:
|
||||||
code.AddLine("float gl_PointSize;");
|
code.AddLine("float gl_PointSize;");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ir.UsesInstanceId()) {
|
||||||
|
code.AddLine("int gl_InstanceID;");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ir.UsesVertexId()) {
|
||||||
|
code.AddLine("int gl_VertexID;");
|
||||||
|
}
|
||||||
|
|
||||||
--code.scope;
|
--code.scope;
|
||||||
code.AddLine("}};");
|
code.AddLine("}};");
|
||||||
code.AddNewLine();
|
code.AddNewLine();
|
||||||
|
@ -964,7 +972,7 @@ private:
|
||||||
switch (element) {
|
switch (element) {
|
||||||
case 2:
|
case 2:
|
||||||
// Config pack's first value is instance_id.
|
// Config pack's first value is instance_id.
|
||||||
return {"gl_InstanceID", Type::Uint};
|
return {"gl_InstanceID", Type::Int};
|
||||||
case 3:
|
case 3:
|
||||||
return {"gl_VertexID", Type::Int};
|
return {"gl_VertexID", Type::Int};
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,6 +114,18 @@ Node ShaderIR::GetOutputAttribute(Attribute::Index index, u64 element, Node buff
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (index == Attribute::Index::TessCoordInstanceIDVertexID) {
|
||||||
|
switch (element) {
|
||||||
|
case 2:
|
||||||
|
uses_instance_id = true;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
uses_vertex_id = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (index == Attribute::Index::ClipDistances0123 ||
|
if (index == Attribute::Index::ClipDistances0123 ||
|
||||||
index == Attribute::Index::ClipDistances4567) {
|
index == Attribute::Index::ClipDistances4567) {
|
||||||
const auto clip_index =
|
const auto clip_index =
|
||||||
|
|
|
@ -124,6 +124,14 @@ public:
|
||||||
return uses_point_size;
|
return uses_point_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool UsesInstanceId() const {
|
||||||
|
return uses_instance_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UsesVertexId() const {
|
||||||
|
return uses_vertex_id;
|
||||||
|
}
|
||||||
|
|
||||||
bool HasPhysicalAttributes() const {
|
bool HasPhysicalAttributes() const {
|
||||||
return uses_physical_attributes;
|
return uses_physical_attributes;
|
||||||
}
|
}
|
||||||
|
@ -373,6 +381,8 @@ private:
|
||||||
bool uses_viewport_index{};
|
bool uses_viewport_index{};
|
||||||
bool uses_point_size{};
|
bool uses_point_size{};
|
||||||
bool uses_physical_attributes{}; // Shader uses AL2P or physical attribute read/writes
|
bool uses_physical_attributes{}; // Shader uses AL2P or physical attribute read/writes
|
||||||
|
bool uses_instance_id{};
|
||||||
|
bool uses_vertex_id{};
|
||||||
|
|
||||||
Tegra::Shader::Header header;
|
Tegra::Shader::Header header;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue