GPUShader/DRW: Add Transform Feedback support.
This is a usefull feature that can be used to do a lot of precomputation on the GPU instead of the CPU. Implementation is simple and only covers the most usefull case. How to use: - Create shader with transform feedback. - Create a pass with DRW_STATE_TRANS_FEEDBACK. - Create a target Gwn_VertBuf (make sure it's big enough). - Create a shading group with DRW_shgroup_transform_feedback_create(). - Add your draw calls to the shading group. - Render your pass normaly. Current limitation: - Only one output buffer. - Cannot pause/resume tfb rendering to interleave with normal drawcalls. - Cannot get the number of verts drawn.
This commit is contained in:
@@ -102,6 +102,21 @@ void drw_state_set(DRWState state)
|
||||
}
|
||||
}
|
||||
|
||||
/* Raster Discard */
|
||||
{
|
||||
if (CHANGED_ANY(DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR |
|
||||
DRW_STATE_WRITE_STENCIL | DRW_STATE_WRITE_STENCIL_SHADOW))
|
||||
{
|
||||
if ((state & (DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR |
|
||||
DRW_STATE_WRITE_STENCIL | DRW_STATE_WRITE_STENCIL_SHADOW)) != 0) {
|
||||
glDisable(GL_RASTERIZER_DISCARD);
|
||||
}
|
||||
else {
|
||||
glEnable(GL_RASTERIZER_DISCARD);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Cull */
|
||||
{
|
||||
DRWState test;
|
||||
@@ -900,6 +915,7 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
|
||||
int val;
|
||||
float fval;
|
||||
const bool shader_changed = (DST.shader != shgroup->shader);
|
||||
bool use_tfeedback = false;
|
||||
|
||||
if (shader_changed) {
|
||||
if (DST.shader) GPU_shader_unbind();
|
||||
@@ -907,6 +923,13 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
|
||||
DST.shader = shgroup->shader;
|
||||
}
|
||||
|
||||
if ((pass_state & DRW_STATE_TRANS_FEEDBACK) != 0 &&
|
||||
(shgroup->type == DRW_SHG_FEEDBACK_TRANSFORM))
|
||||
{
|
||||
use_tfeedback = GPU_shader_transform_feedback_enable(shgroup->shader,
|
||||
shgroup->tfeedback_target->vbo_id);
|
||||
}
|
||||
|
||||
release_ubo_slots(shader_changed);
|
||||
release_texture_slots(shader_changed);
|
||||
|
||||
@@ -1023,7 +1046,7 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
|
||||
#endif
|
||||
|
||||
/* Rendering Calls */
|
||||
if (!ELEM(shgroup->type, DRW_SHG_NORMAL)) {
|
||||
if (!ELEM(shgroup->type, DRW_SHG_NORMAL, DRW_SHG_FEEDBACK_TRANSFORM)) {
|
||||
/* Replacing multiple calls with only one */
|
||||
if (ELEM(shgroup->type, DRW_SHG_INSTANCE, DRW_SHG_INSTANCE_EXTERNAL)) {
|
||||
if (shgroup->type == DRW_SHG_INSTANCE_EXTERNAL) {
|
||||
@@ -1104,6 +1127,10 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
|
||||
glFrontFace(DST.frontface);
|
||||
}
|
||||
|
||||
if (use_tfeedback) {
|
||||
GPU_shader_transform_feedback_disable(shgroup->shader);
|
||||
}
|
||||
|
||||
/* TODO: remove, (currently causes alpha issue with sculpt, need to investigate) */
|
||||
DRW_state_reset();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user