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);
}
// 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>
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'
// NOTE: Linking is much slower than decompilation step, so always decompile at least 1 unit
@ -381,7 +384,7 @@ public:
}
else
{
return busy;
return { busy, false };
}
}
@ -392,7 +395,7 @@ public:
m_storage[key] = std::move(pipeline);
m_link_queue.erase(key);
return (busy || !m_link_queue.empty());
return { (busy || !m_link_queue.empty()), true };
}
template<typename... Args>

View file

@ -402,13 +402,12 @@ void GLGSRender::end()
//Bind textures and resolve external copy operations
std::chrono::time_point<steady_clock> textures_start = steady_clock::now();
int unused_location;
void *unused = nullptr;
gl::texture_view* tmp_view;
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 &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)
{
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());
glActiveTexture(GL_TEXTURE0 + rsx::limits::fragment_textures_count + i);
@ -1786,11 +1785,13 @@ void GLGSRender::on_decompiler_exit()
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
// Finish works well enough for now but it is not a proper soulution
glFinish();
return ret;
return result.first;
}

View file

@ -2435,35 +2435,51 @@ public:
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 false;
return (found->second >= 0);
}
auto result = glGetUniformLocation(m_program.id(), name.c_str());
locations[name] = result;
if (location)
{
*location = result;
}
return true;
return (result >= 0);
}
GLint location(const std::string &name)
{
auto finded = locations.find(name);
if (finded != locations.end())
auto found = locations.find(name);
if (found != 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)
{
throw not_found_exception(name);
}
locations[name] = result;
return result;
}
@ -2476,28 +2492,6 @@ public:
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)
{
return{ m_program, location };
@ -2515,83 +2509,6 @@ public:
}
} 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()
{
if (created())
@ -2686,7 +2603,6 @@ public:
void set_id(uint id)
{
uniforms.clear();
attribs.clear();
m_id = id;
}
@ -2764,7 +2680,6 @@ public:
set_id(program_.id());
program_.set_id(my_old_id);
uniforms.swap(program_.uniforms);
attribs.swap(program_.attribs);
}
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));
}
// 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)
{
if (!on_decompiler_task())
@ -449,13 +445,9 @@ namespace rsx
{
std::this_thread::sleep_for(1ms);
}
else if (prefer_sleep)
{
std::this_thread::sleep_for(500us);
}
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()
{
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 bool is_cubemap = type == rsx::texture_dimension_extended::texture_dimension_cubemap;
VkFormat vk_format;
VkComponentMapping mapping;
VkImageAspectFlags aspect_flags;
VkImageType image_type;
VkImageViewType image_view_type;

View file

@ -371,12 +371,18 @@ namespace rsx
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)
{
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)
@ -1310,7 +1316,16 @@ namespace rsx
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

View file

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