Skip to content

Commit

Permalink
* Implemented renderer dependencies for OGL (not well-tested)
Browse files Browse the repository at this point in the history
  • Loading branch information
harrand committed May 19, 2023
1 parent 25972b0 commit 13b8c34
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 6 deletions.
63 changes: 61 additions & 2 deletions src/tz/gl/impl/opengl/device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,75 @@

namespace tz::gl
{
device_render_scheduler_ogl::device_render_scheduler_ogl(const tz::gl::schedule& sched):
sched(sched){}

device_ogl::device_ogl()
void device_render_scheduler_ogl::ogl_fingerprint(unsigned int fingerprint, std::size_t renderer_id)
{
this->fingerprint_to_renderer_id.emplace(fingerprint, renderer_id);
}

void device_render_scheduler_ogl::ogl_new_sync()
{
this->renderer_syncs.push_back(0);
}

void device_render_scheduler_ogl::ogl_gpu_do_waits(unsigned int fingerprint)
{
tz::assert(this->fingerprint_to_renderer_id.find(fingerprint) != this->fingerprint_to_renderer_id.end(), "fingerprint %u does not exist", fingerprint);
std::size_t renderer_id = this->fingerprint_to_renderer_id[fingerprint];
for(tz::gl::eid_t evt : this->sched.get_dependencies(renderer_id))
{
ogl_gpu_wait_on(static_cast<tz::hanval>(evt));
}
}

void device_render_scheduler_ogl::ogl_gpu_wait_on(tz::gl::renderer_handle dep)
{
auto hval = static_cast<std::size_t>(static_cast<tz::hanval>(dep));
tz::assert(this->renderer_syncs[hval] != 0, "trying to wait on a sync object belonging to a renderer, but the sync object was never registered, or hasnt been recognised as a renderer with dependencies.");
glWaitSync(this->renderer_syncs[hval], 0, GL_TIMEOUT_IGNORED);
}

void device_render_scheduler_ogl::ogl_register_sync(unsigned int fingerprint)
{
tz::assert(this->fingerprint_to_renderer_id.find(fingerprint) != this->fingerprint_to_renderer_id.end(), "fingerprint %u does not exist", fingerprint);
std::size_t hval = this->fingerprint_to_renderer_id.at(fingerprint);
bool anyone_depends_on_me = false;
for(tz::gl::eid_t evt : this->sched.timeline)
{
std::span<const tz::gl::eid_t> deps = this->sched.get_dependencies(evt);
if(std::any_of(deps.begin(), deps.end(), [hval](tz::gl::eid_t dep){return dep == hval;}))
{
anyone_depends_on_me = true;
}
}
if(!anyone_depends_on_me)
{
// if nobody depends on this renderer, its a waste of time to register a sync, so dont bother.
return;
}
if(this->renderer_syncs[hval] != 0)
{
// kill the old sync.
glDeleteSync(this->renderer_syncs[hval]);
}
this->renderer_syncs[hval] = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
}

device_ogl::device_ogl():
device_render_scheduler_ogl(device_common<renderer_ogl>::render_graph())
{
glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE);
}

tz::gl::renderer_handle device_ogl::create_renderer(const renderer_info& info)
{
TZ_PROFZONE("OpenGL Frontend - renderer Create (via device)", 0xFFAA0000);
return device_common<renderer_ogl>::emplace_renderer(info);
device_render_scheduler_ogl::ogl_new_sync();
tz::gl::renderer_handle ret = device_common<renderer_ogl>::emplace_renderer(info);
device_render_scheduler_ogl::ogl_fingerprint(device_common<renderer_ogl>::get_renderer(ret).ogl_get_uid(), device_common<renderer_ogl>::renderer_count() - 1);
return ret;
}

image_format device_ogl::get_window_format() const
Expand Down
20 changes: 17 additions & 3 deletions src/tz/gl/impl/opengl/device.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,26 @@
#include "tz/gl/api/device.hpp"
#include "tz/gl/declare/image_format.hpp"
#include "tz/gl/impl/opengl/renderer.hpp"
#include <unordered_map>

namespace tz::gl
{
class device_ogl : public device_common<renderer_ogl>
class device_render_scheduler_ogl
{
public:
device_render_scheduler_ogl(const tz::gl::schedule& sched);
void ogl_fingerprint(unsigned int fingerprint, std::size_t renderer_id);
void ogl_gpu_do_waits(unsigned int fingerprint);
void ogl_gpu_wait_on(tz::gl::renderer_handle dep);
void ogl_register_sync(unsigned int fingerprint);
void ogl_new_sync();
private:
std::vector<GLsync> renderer_syncs = {};
std::unordered_map<unsigned int, std::size_t> fingerprint_to_renderer_id = {};
const tz::gl::schedule& sched;
};

class device_ogl : public device_render_scheduler_ogl, public device_common<renderer_ogl>
{
public:
device_ogl();
Expand All @@ -20,8 +36,6 @@ namespace tz::gl
void dbgui();
void begin_frame();
void end_frame();
private:
std::vector<renderer_ogl> renderers;
};
static_assert(device_type<device_ogl, renderer_info>);
}
Expand Down
4 changes: 4 additions & 0 deletions src/tz/gl/impl/opengl/renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

namespace tz::gl
{
unsigned int renderer_ogl_base::uid_counter = 0;
namespace detail
{
void initialise_buffer(buffer_component_ogl& bufcomp)
Expand Down Expand Up @@ -546,6 +547,8 @@ namespace tz::gl
}
#endif

tz::gl::get_device().ogl_gpu_do_waits(renderer_ogl_base::ogl_get_uid());

if(this->shader.is_compute())
{
this->resources.write_dynamic_images();
Expand Down Expand Up @@ -657,6 +660,7 @@ namespace tz::gl
glClientWaitSync(fence, GL_SYNC_FLUSH_COMMANDS_BIT, std::numeric_limits<GLuint64>::max());
glDeleteSync(fence);
}
tz::gl::get_device().ogl_register_sync(renderer_ogl_base::ogl_get_uid());
}

void renderer_ogl::edit(const renderer_edit_request& edit_request)
Expand Down
13 changes: 12 additions & 1 deletion src/tz/gl/impl/opengl/renderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,11 +125,22 @@ namespace tz::gl
tz::gl::renderer_options options;
};

struct renderer_ogl_base
{
protected:
// devices have this concept of renderer handles, but they are not guaranteed to be unique (e.g if renderer handle 2 is deleted and a new renderer is created, that will also have handle 2.)
// this is a uid which will uniquely identify ths current renderer. renderers need to have their own identity because other manager classes (mainly device_vulkan2) does bookkeeping for renderers and needs to know who is who.
static unsigned int uid_counter;
unsigned int uid = uid_counter++;
public:
unsigned int ogl_get_uid() const{return this->uid;}
};

/**
* @ingroup tz_gl2_graphicsapi_ogl_frontend_renderer
* renderer implementation which heavily calls into the backend at @ref tz_gl_ogl2.
*/
class renderer_ogl
class renderer_ogl : public renderer_ogl_base
{
public:
/**
Expand Down

0 comments on commit 13b8c34

Please sign in to comment.