|
|
@ -202,7 +202,8 @@ void RasterizerOpenGL::Clear(u32 layer_count) { |
|
|
++num_queued_commands; |
|
|
++num_queued_commands; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void RasterizerOpenGL::Draw(bool is_indexed, u32 instance_count) { |
|
|
|
|
|
|
|
|
template <typename Func> |
|
|
|
|
|
void RasterizerOpenGL::PrepareDraw(bool is_indexed, Func&& draw_func) { |
|
|
MICROPROFILE_SCOPE(OpenGL_Drawing); |
|
|
MICROPROFILE_SCOPE(OpenGL_Drawing); |
|
|
|
|
|
|
|
|
SCOPE_EXIT({ gpu.TickWork(); }); |
|
|
SCOPE_EXIT({ gpu.TickWork(); }); |
|
|
@ -226,6 +227,17 @@ void RasterizerOpenGL::Draw(bool is_indexed, u32 instance_count) { |
|
|
const GLenum primitive_mode = MaxwellToGL::PrimitiveTopology(draw_state.topology); |
|
|
const GLenum primitive_mode = MaxwellToGL::PrimitiveTopology(draw_state.topology); |
|
|
BeginTransformFeedback(pipeline, primitive_mode); |
|
|
BeginTransformFeedback(pipeline, primitive_mode); |
|
|
|
|
|
|
|
|
|
|
|
draw_func(primitive_mode); |
|
|
|
|
|
|
|
|
|
|
|
EndTransformFeedback(); |
|
|
|
|
|
|
|
|
|
|
|
++num_queued_commands; |
|
|
|
|
|
has_written_global_memory |= pipeline->WritesGlobalMemory(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void RasterizerOpenGL::Draw(bool is_indexed, u32 instance_count) { |
|
|
|
|
|
PrepareDraw(is_indexed, [this, is_indexed, instance_count](GLenum primitive_mode) { |
|
|
|
|
|
const auto& draw_state = maxwell3d->draw_manager->GetDrawState(); |
|
|
const GLuint base_instance = static_cast<GLuint>(draw_state.base_instance); |
|
|
const GLuint base_instance = static_cast<GLuint>(draw_state.base_instance); |
|
|
const GLsizei num_instances = static_cast<GLsizei>(instance_count); |
|
|
const GLsizei num_instances = static_cast<GLsizei>(instance_count); |
|
|
if (is_indexed) { |
|
|
if (is_indexed) { |
|
|
@ -238,7 +250,8 @@ void RasterizerOpenGL::Draw(bool is_indexed, u32 instance_count) { |
|
|
} else if (num_instances == 1 && base_instance == 0) { |
|
|
} else if (num_instances == 1 && base_instance == 0) { |
|
|
glDrawElementsBaseVertex(primitive_mode, num_vertices, format, offset, base_vertex); |
|
|
glDrawElementsBaseVertex(primitive_mode, num_vertices, format, offset, base_vertex); |
|
|
} else if (base_vertex == 0 && base_instance == 0) { |
|
|
} else if (base_vertex == 0 && base_instance == 0) { |
|
|
glDrawElementsInstanced(primitive_mode, num_vertices, format, offset, num_instances); |
|
|
|
|
|
|
|
|
glDrawElementsInstanced(primitive_mode, num_vertices, format, offset, |
|
|
|
|
|
num_instances); |
|
|
} else if (base_vertex == 0) { |
|
|
} else if (base_vertex == 0) { |
|
|
glDrawElementsInstancedBaseInstance(primitive_mode, num_vertices, format, offset, |
|
|
glDrawElementsInstancedBaseInstance(primitive_mode, num_vertices, format, offset, |
|
|
num_instances, base_instance); |
|
|
num_instances, base_instance); |
|
|
@ -262,10 +275,47 @@ void RasterizerOpenGL::Draw(bool is_indexed, u32 instance_count) { |
|
|
num_instances, base_instance); |
|
|
num_instances, base_instance); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
EndTransformFeedback(); |
|
|
|
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
++num_queued_commands; |
|
|
|
|
|
has_written_global_memory |= pipeline->WritesGlobalMemory(); |
|
|
|
|
|
|
|
|
void RasterizerOpenGL::DrawIndirect() { |
|
|
|
|
|
const auto& params = maxwell3d->draw_manager->GetIndirectParams(); |
|
|
|
|
|
buffer_cache.SetDrawIndirect(¶ms); |
|
|
|
|
|
PrepareDraw(params.is_indexed, [this, ¶ms](GLenum primitive_mode) { |
|
|
|
|
|
const auto [buffer, offset] = buffer_cache.GetDrawIndirectBuffer(); |
|
|
|
|
|
const GLvoid* const gl_offset = |
|
|
|
|
|
reinterpret_cast<const GLvoid*>(static_cast<uintptr_t>(offset)); |
|
|
|
|
|
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer->Handle()); |
|
|
|
|
|
if (params.include_count) { |
|
|
|
|
|
const auto [draw_buffer, offset_base] = buffer_cache.GetDrawIndirectCount(); |
|
|
|
|
|
glBindBuffer(GL_PARAMETER_BUFFER, draw_buffer->Handle()); |
|
|
|
|
|
|
|
|
|
|
|
if (params.is_indexed) { |
|
|
|
|
|
const GLenum format = MaxwellToGL::IndexFormat(maxwell3d->regs.index_buffer.format); |
|
|
|
|
|
glMultiDrawElementsIndirectCount(primitive_mode, format, gl_offset, |
|
|
|
|
|
static_cast<GLintptr>(offset_base), |
|
|
|
|
|
static_cast<GLsizei>(params.max_draw_counts), |
|
|
|
|
|
static_cast<GLsizei>(params.stride)); |
|
|
|
|
|
} else { |
|
|
|
|
|
glMultiDrawArraysIndirectCount(primitive_mode, gl_offset, |
|
|
|
|
|
static_cast<GLintptr>(offset_base), |
|
|
|
|
|
static_cast<GLsizei>(params.max_draw_counts), |
|
|
|
|
|
static_cast<GLsizei>(params.stride)); |
|
|
|
|
|
} |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
if (params.is_indexed) { |
|
|
|
|
|
const GLenum format = MaxwellToGL::IndexFormat(maxwell3d->regs.index_buffer.format); |
|
|
|
|
|
glMultiDrawElementsIndirect(primitive_mode, format, gl_offset, |
|
|
|
|
|
static_cast<GLsizei>(params.max_draw_counts), |
|
|
|
|
|
static_cast<GLsizei>(params.stride)); |
|
|
|
|
|
} else { |
|
|
|
|
|
glMultiDrawArraysIndirect(primitive_mode, gl_offset, |
|
|
|
|
|
static_cast<GLsizei>(params.max_draw_counts), |
|
|
|
|
|
static_cast<GLsizei>(params.stride)); |
|
|
|
|
|
} |
|
|
|
|
|
}); |
|
|
|
|
|
buffer_cache.SetDrawIndirect(nullptr); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void RasterizerOpenGL::DispatchCompute() { |
|
|
void RasterizerOpenGL::DispatchCompute() { |
|
|
|