Allow calling dispatch_compute directly to GraphicsEngine

This commit is contained in:
rdb 2014-07-03 21:57:33 +00:00
parent 44aea55a66
commit f8675fcd7b
2 changed files with 55 additions and 1 deletions

View File

@ -1093,7 +1093,58 @@ extract_texture_data(Texture *tex, GraphicsStateGuardian *gsg) {
return gsg->extract_texture_data(tex);
}
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsEngine::dispatch_compute
// Access: Published
// Description: Asks the indicated GraphicsStateGuardian to dispatch
// the compute shader in the given ShaderAttrib using
// the given work group counts. This can act as an
// interface for running a one-off compute shader,
// without having to store it in the scene graph using
// a ComputeNode.
//
// Since this requires a round-trip to the draw thread,
// it may require waiting for the current thread to
// finish rendering if it is called in a multithreaded
// environment. However, you can call this several
// consecutive times on different textures for little
// additional cost.
//
// The return value is true if the operation is
// successful, false otherwise.
////////////////////////////////////////////////////////////////////
void GraphicsEngine::
dispatch_compute(const LVecBase3i &work_groups, const ShaderAttrib *sattr, GraphicsStateGuardian *gsg) {
ReMutexHolder holder(_lock);
CPT(RenderState) state = RenderState::make(sattr);
string draw_name = gsg->get_threading_model().get_draw_name();
if (draw_name.empty()) {
// A single-threaded environment. No problem.
} else {
// A multi-threaded environment. We have to wait until the draw
// thread has finished its current task.
WindowRenderer *wr = get_window_renderer(draw_name, 0);
RenderThread *thread = (RenderThread *)wr;
MutexHolder holder2(thread->_cv_mutex);
while (thread->_thread_state != TS_wait) {
thread->_cv_done.wait();
}
// OK, now the draw thread is idle. That's really good enough for
// our purposes; we don't *actually* need to make the draw thread
// do the work--it's sufficient that it's not doing anything else
// while we access the GSG.
}
gsg->set_state_and_transform(state, TransformState::make_identity());
gsg->dispatch_compute(work_groups[0], work_groups[1], work_groups[2]);
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsEngine::get_global_ptr
// Access: Published, Static

View File

@ -108,6 +108,9 @@ PUBLISHED:
BLOCKING void flip_frame();
bool extract_texture_data(Texture *tex, GraphicsStateGuardian *gsg);
void dispatch_compute(const LVecBase3i &work_groups,
const ShaderAttrib *sattr,
GraphicsStateGuardian *gsg);
static GraphicsEngine *get_global_ptr();