rsx/gl: Minor cleanup and optimization

- Track register change status
- Remove unused gl classes
This commit is contained in:
kd-11 2018-07-22 16:03:14 +03:00 committed by kd-11
parent 8695f95267
commit 19d808d378
8 changed files with 64 additions and 137 deletions

View file

@ -334,8 +334,11 @@ public:
fmt::throw_exception("Trying to get unknown shader program" HERE); fmt::throw_exception("Trying to get unknown shader program" HERE);
} }
// Returns 2 booleans.
// First flag hints that there is more work to do (busy hint)
// Second flag is true if at least one program has been linked successfully (sync hint)
template<typename... Args> template<typename... Args>
bool async_update(u32 max_decompile_count, Args&& ...args) std::pair<bool, bool> async_update(u32 max_decompile_count, Args&& ...args)
{ {
// Decompile shaders and link one pipeline object per 'run' // Decompile shaders and link one pipeline object per 'run'
// NOTE: Linking is much slower than decompilation step, so always decompile at least 1 unit // NOTE: Linking is much slower than decompilation step, so always decompile at least 1 unit
@ -381,7 +384,7 @@ public:
} }
else else
{ {
return busy; return { busy, false };
} }
} }
@ -392,7 +395,7 @@ public:
m_storage[key] = std::move(pipeline); m_storage[key] = std::move(pipeline);
m_link_queue.erase(key); m_link_queue.erase(key);
return (busy || !m_link_queue.empty()); return { (busy || !m_link_queue.empty()), true };
} }
template<typename... Args> template<typename... Args>

View file

@ -402,13 +402,12 @@ void GLGSRender::end()
//Bind textures and resolve external copy operations //Bind textures and resolve external copy operations
std::chrono::time_point<steady_clock> textures_start = steady_clock::now(); std::chrono::time_point<steady_clock> textures_start = steady_clock::now();
int unused_location;
void *unused = nullptr; void *unused = nullptr;
gl::texture_view* tmp_view; gl::texture_view* tmp_view;
for (int i = 0; i < rsx::limits::fragment_textures_count; ++i) for (int i = 0; i < rsx::limits::fragment_textures_count; ++i)
{ {
if (m_program->uniforms.has_location(rsx::constants::fragment_texture_names[i], &unused_location)) if (m_program->uniforms.has_location(rsx::constants::fragment_texture_names[i]))
{ {
auto sampler_state = static_cast<gl::texture_cache::sampled_image_descriptor*>(fs_sampler_state[i].get()); auto sampler_state = static_cast<gl::texture_cache::sampled_image_descriptor*>(fs_sampler_state[i].get());
auto &tex = rsx::method_registers.fragment_textures[i]; auto &tex = rsx::method_registers.fragment_textures[i];
@ -444,7 +443,7 @@ void GLGSRender::end()
for (int i = 0; i < rsx::limits::vertex_textures_count; ++i) for (int i = 0; i < rsx::limits::vertex_textures_count; ++i)
{ {
if (m_program->uniforms.has_location(rsx::constants::vertex_texture_names[i], &unused_location)) if (m_program->uniforms.has_location(rsx::constants::vertex_texture_names[i]))
{ {
auto sampler_state = static_cast<gl::texture_cache::sampled_image_descriptor*>(vs_sampler_state[i].get()); auto sampler_state = static_cast<gl::texture_cache::sampled_image_descriptor*>(vs_sampler_state[i].get());
glActiveTexture(GL_TEXTURE0 + rsx::limits::fragment_textures_count + i); glActiveTexture(GL_TEXTURE0 + rsx::limits::fragment_textures_count + i);
@ -1786,11 +1785,13 @@ void GLGSRender::on_decompiler_exit()
bool GLGSRender::on_decompiler_task() bool GLGSRender::on_decompiler_task()
{ {
bool ret = m_prog_buffer.async_update(8); const auto result = m_prog_buffer.async_update(8);
if (result.second)
{
// TODO: Proper synchronization with renderer
// Finish works well enough for now but it is not a proper soulution
glFinish();
}
// TODO: Proper synchronization with renderer return result.first;
// Finish works well enough for now but it is not a proper soulution
glFinish();
return ret;
} }

View file

@ -2435,35 +2435,51 @@ public:
bool has_location(const std::string &name, int *location = nullptr) bool has_location(const std::string &name, int *location = nullptr)
{ {
int result = glGetUniformLocation(m_program.id(), name.c_str()); auto found = locations.find(name);
if (found != locations.end())
{
if (location)
{
*location = found->second;
}
if (result < 0) return (found->second >= 0);
return false; }
auto result = glGetUniformLocation(m_program.id(), name.c_str());
locations[name] = result; locations[name] = result;
if (location) if (location)
{
*location = result; *location = result;
}
return true; return (result >= 0);
} }
GLint location(const std::string &name) GLint location(const std::string &name)
{ {
auto finded = locations.find(name); auto found = locations.find(name);
if (found != locations.end())
if (finded != locations.end())
{ {
return finded->second; if (found->second >= 0)
{
return found->second;
}
else
{
throw not_found_exception(name);
}
} }
int result = glGetUniformLocation(m_program.id(), name.c_str()); auto result = glGetUniformLocation(m_program.id(), name.c_str());
if (result < 0) if (result < 0)
{
throw not_found_exception(name); throw not_found_exception(name);
}
locations[name] = result; locations[name] = result;
return result; return result;
} }
@ -2476,28 +2492,6 @@ public:
return active_texture; return active_texture;
} }
int texture(const std::string &name, int active_texture, const gl::texture_view& texture_)
{
return texture(location(name), active_texture, texture_);
}
int texture(const std::string &name, const gl::texture_view& texture_)
{
int atex;
auto finded = locations.find(name);
if (finded != locations.end())
{
atex = finded->second;
}
else
{
atex = active_texture++;
}
return texture(name, atex, texture_);
}
uniform_t operator[](GLint location) uniform_t operator[](GLint location)
{ {
return{ m_program, location }; return{ m_program, location };
@ -2515,83 +2509,6 @@ public:
} }
} uniforms{ this }; } uniforms{ this };
class attribs_t
{
program& m_program;
std::unordered_map<std::string, GLint> m_locations;
public:
attribs_t(program* program) : m_program(*program)
{
}
void clear()
{
m_locations.clear();
}
GLint location(const std::string &name)
{
auto finded = m_locations.find(name);
if (finded != m_locations.end())
{
if (finded->second < 0)
throw not_found_exception(name);
return finded->second;
}
int result = glGetAttribLocation(m_program.id(), name.c_str());
if (result < 0)
throw not_found_exception(name);
m_locations[name] = result;
return result;
}
bool has_location(const std::string &name, int *location_ = nullptr)
{
auto finded = m_locations.find(name);
if (finded != m_locations.end())
{
if (finded->second < 0)
return false;
*location_ = finded->second;
return true;
}
int loc = glGetAttribLocation(m_program.id(), name.c_str());
m_locations[name] = loc;
if (loc < 0)
return false;
*location_ = loc;
return true;
}
attrib_t operator[](GLint location)
{
return{ location };
}
attrib_t operator[](const std::string &name)
{
return{ location(name) };
}
void swap(attribs_t& attribs)
{
m_locations.swap(attribs.m_locations);
}
} attribs{ this };
program& recreate() program& recreate()
{ {
if (created()) if (created())
@ -2686,7 +2603,6 @@ public:
void set_id(uint id) void set_id(uint id)
{ {
uniforms.clear(); uniforms.clear();
attribs.clear();
m_id = id; m_id = id;
} }
@ -2764,7 +2680,6 @@ public:
set_id(program_.id()); set_id(program_.id());
program_.set_id(my_old_id); program_.set_id(my_old_id);
uniforms.swap(program_.uniforms); uniforms.swap(program_.uniforms);
attribs.swap(program_.attribs);
} }
program& operator = (const program& rhs) = delete; program& operator = (const program& rhs) = delete;

View file

@ -437,10 +437,6 @@ namespace rsx
thread_ctrl::set_thread_affinity_mask(thread_ctrl::get_affinity_mask(thread_class::rsx)); thread_ctrl::set_thread_affinity_mask(thread_ctrl::get_affinity_mask(thread_class::rsx));
} }
// Weak cpus need all the help they can get, sleep instead of yield loop
// Lowers decompiler responsiveness but improves emulator performance
const bool prefer_sleep = (std::thread::hardware_concurrency() < 6);
while (!Emu.IsStopped() && !m_rsx_thread_exiting) while (!Emu.IsStopped() && !m_rsx_thread_exiting)
{ {
if (!on_decompiler_task()) if (!on_decompiler_task())
@ -449,13 +445,9 @@ namespace rsx
{ {
std::this_thread::sleep_for(1ms); std::this_thread::sleep_for(1ms);
} }
else if (prefer_sleep)
{
std::this_thread::sleep_for(500us);
}
else else
{ {
std::this_thread::yield(); std::this_thread::sleep_for(500us);
} }
} }
} }

View file

@ -3442,5 +3442,5 @@ void VKGSRender::discard_occlusion_query(rsx::reports::occlusion_query_info* que
bool VKGSRender::on_decompiler_task() bool VKGSRender::on_decompiler_task()
{ {
return m_prog_buffer->async_update(8, *m_device, pipeline_layout); return m_prog_buffer->async_update(8, *m_device, pipeline_layout).first;
} }

View file

@ -780,7 +780,6 @@ namespace vk
const u16 section_depth = depth; const u16 section_depth = depth;
const bool is_cubemap = type == rsx::texture_dimension_extended::texture_dimension_cubemap; const bool is_cubemap = type == rsx::texture_dimension_extended::texture_dimension_cubemap;
VkFormat vk_format; VkFormat vk_format;
VkComponentMapping mapping;
VkImageAspectFlags aspect_flags; VkImageAspectFlags aspect_flags;
VkImageType image_type; VkImageType image_type;
VkImageViewType image_view_type; VkImageViewType image_view_type;

View file

@ -371,12 +371,18 @@ namespace rsx
void set_transform_program_start(thread* rsx, u32, u32) void set_transform_program_start(thread* rsx, u32, u32)
{ {
rsx->m_graphics_state |= rsx::pipeline_state::vertex_program_dirty; if (method_registers.register_change_flag)
{
rsx->m_graphics_state |= rsx::pipeline_state::vertex_program_dirty;
}
} }
void set_vertex_attribute_output_mask(thread* rsx, u32, u32) void set_vertex_attribute_output_mask(thread* rsx, u32, u32)
{ {
rsx->m_graphics_state |= rsx::pipeline_state::vertex_program_dirty | rsx::pipeline_state::fragment_program_dirty; if (method_registers.register_change_flag)
{
rsx->m_graphics_state |= rsx::pipeline_state::vertex_program_dirty | rsx::pipeline_state::fragment_program_dirty;
}
} }
void set_begin_end(thread* rsxthr, u32 _reg, u32 arg) void set_begin_end(thread* rsxthr, u32 _reg, u32 arg)
@ -1310,7 +1316,16 @@ namespace rsx
void rsx_state::decode(u32 reg, u32 value) void rsx_state::decode(u32 reg, u32 value)
{ {
registers[reg] = value; auto& old_value = registers[reg];
if (old_value != value)
{
register_change_flag = true;
old_value = value;
}
else
{
register_change_flag = false;
}
} }
bool rsx_state::test(u32 reg, u32 value) const bool rsx_state::test(u32 reg, u32 value) const

View file

@ -159,6 +159,8 @@ namespace rsx
draw_clause current_draw_clause; draw_clause current_draw_clause;
bool register_change_flag;
/** /**
* RSX can sources vertex attributes from 2 places: * RSX can sources vertex attributes from 2 places:
* 1. Immediate values passed by NV4097_SET_VERTEX_DATA*_M + ARRAY_ID write. * 1. Immediate values passed by NV4097_SET_VERTEX_DATA*_M + ARRAY_ID write.