rsx: More fixes

- Workaround for AMD glMultiDrawArrays bug
- Disable disjoint command submission when multidraw support is disabled
This commit is contained in:
kd-11 2017-10-17 13:34:44 +03:00
parent 89dcafbe41
commit 5db45c3699
4 changed files with 38 additions and 15 deletions

View File

@ -497,7 +497,7 @@ void GLGSRender::end()
} }
const GLenum draw_mode = gl::draw_mode(rsx::method_registers.current_draw_clause.primitive); const GLenum draw_mode = gl::draw_mode(rsx::method_registers.current_draw_clause.primitive);
bool single_draw = rsx::method_registers.current_draw_clause.first_count_commands.size() <= 1 || rsx::method_registers.current_draw_clause.is_disjoint_primitive; bool single_draw = !supports_multidraw || (rsx::method_registers.current_draw_clause.first_count_commands.size() <= 1 || rsx::method_registers.current_draw_clause.is_disjoint_primitive);
if (indexed_draw_info) if (indexed_draw_info)
{ {
@ -546,21 +546,32 @@ void GLGSRender::end()
} }
else else
{ {
std::vector<GLint> firsts;
std::vector<GLsizei> counts;
const auto draw_count = rsx::method_registers.current_draw_clause.first_count_commands.size();
firsts.reserve(draw_count);
counts.reserve(draw_count);
u32 base_index = rsx::method_registers.current_draw_clause.first_count_commands.front().first; u32 base_index = rsx::method_registers.current_draw_clause.first_count_commands.front().first;
for (const auto &range : rsx::method_registers.current_draw_clause.first_count_commands) if (gl::get_driver_caps().vendor_AMD == false)
{ {
firsts.push_back(range.first - base_index); std::vector<GLint> firsts;
counts.push_back(range.second); std::vector<GLsizei> counts;
} const auto draw_count = rsx::method_registers.current_draw_clause.first_count_commands.size();
glMultiDrawArrays(draw_mode, firsts.data(), counts.data(), (GLsizei)draw_count); firsts.reserve(draw_count);
counts.reserve(draw_count);
for (const auto &range : rsx::method_registers.current_draw_clause.first_count_commands)
{
firsts.push_back(range.first - base_index);
counts.push_back(range.second);
}
glMultiDrawArrays(draw_mode, firsts.data(), counts.data(), (GLsizei)draw_count);
}
else
{
//MultiDrawArrays is broken on some primitive types using AMD. One known type is GL_TRIANGLE_STRIP but there could be more
for (const auto &range : rsx::method_registers.current_draw_clause.first_count_commands)
{
glDrawArrays(draw_mode, range.first - base_index, range.second);
}
}
} }
} }

View File

@ -84,6 +84,7 @@ namespace gl
bool NV_texture_barrier_supported = false; bool NV_texture_barrier_supported = false;
bool initialized = false; bool initialized = false;
bool vendor_INTEL = false; bool vendor_INTEL = false;
bool vendor_AMD = false;
void initialize() void initialize()
{ {
@ -192,6 +193,12 @@ namespace gl
if (!EXT_dsa_supported && glGetTextureImageEXT && glTextureBufferRangeEXT) if (!EXT_dsa_supported && glGetTextureImageEXT && glTextureBufferRangeEXT)
EXT_dsa_supported = true; EXT_dsa_supported = true;
} }
#ifdef _WIN32
else if (vendor_string.find("amd") != std::string::npos)
{
vendor_AMD = true;
}
#endif
initialized = true; initialized = true;
} }

View File

@ -595,6 +595,7 @@ namespace rsx
bool execute_method_call = true; bool execute_method_call = true;
//TODO: Flatten draw calls when multidraw is not supported to simplify checking in the end() methods
if (supports_multidraw) if (supports_multidraw)
{ {
//TODO: Make this cleaner //TODO: Make this cleaner

View File

@ -1211,8 +1211,12 @@ void VKGSRender::end()
} }
std::optional<std::tuple<VkDeviceSize, VkIndexType> > index_info = std::get<4>(upload_info); std::optional<std::tuple<VkDeviceSize, VkIndexType> > index_info = std::get<4>(upload_info);
const bool is_emulated_restart = (index_info && rsx::method_registers.restart_index_enabled() && vk::emulate_primitive_restart() && rsx::method_registers.current_draw_clause.command == rsx::draw_command::indexed);
const bool single_draw = !is_emulated_restart && (rsx::method_registers.current_draw_clause.first_count_commands.size() <= 1 || rsx::method_registers.current_draw_clause.is_disjoint_primitive); bool primitive_emulated = false;
vk::get_appropriate_topology(rsx::method_registers.current_draw_clause.primitive, primitive_emulated);
const bool is_emulated_restart = (!primitive_emulated && rsx::method_registers.restart_index_enabled() && vk::emulate_primitive_restart() && rsx::method_registers.current_draw_clause.command == rsx::draw_command::indexed);
const bool single_draw = !supports_multidraw || (!is_emulated_restart && (rsx::method_registers.current_draw_clause.first_count_commands.size() <= 1 || rsx::method_registers.current_draw_clause.is_disjoint_primitive));
if (!index_info) if (!index_info)
{ {