diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2018-05-16 13:47:15 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2018-05-16 17:58:32 +0300 |
commit | a25856f2a802dae4e2c4c01e9b74d8c8a1769933 (patch) | |
tree | 1ae725b9d04c36f4847c5bc08fb55f4a0f7a8aab /source/blender/draw/intern/draw_manager_exec.c | |
parent | a3f4c72ec9d431f65bf9f50b7849e22e2f213ad0 (diff) |
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.
Diffstat (limited to 'source/blender/draw/intern/draw_manager_exec.c')
-rw-r--r-- | source/blender/draw/intern/draw_manager_exec.c | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c index 033168680b8..78ac96e41b2 100644 --- a/source/blender/draw/intern/draw_manager_exec.c +++ b/source/blender/draw/intern/draw_manager_exec.c @@ -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(); } |