DRW: Refactor: Make use of the new Gawain long attrib support.
This commit is contained in:
@@ -87,10 +87,7 @@ void GWN_batch_draw(Gwn_Batch*);
|
||||
|
||||
// clement : temp stuff
|
||||
void GWN_batch_draw_stupid(Gwn_Batch*, int v_first, int v_count);
|
||||
void GWN_batch_draw_stupid_instanced(Gwn_Batch*, unsigned int instance_vbo, int instance_first, int instance_count,
|
||||
int attrib_nbr, int attrib_stride, int attrib_loc[16], int attrib_size[16]);
|
||||
void GWN_batch_draw_stupid_instanced_with_batch(Gwn_Batch*, Gwn_Batch*);
|
||||
|
||||
void GWN_batch_draw_stupid_instanced(Gwn_Batch*, Gwn_Batch*, int instance_first, int instance_count);
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -194,15 +194,15 @@ static void Batch_update_program_bindings(Gwn_Batch* batch, unsigned int v_first
|
||||
batch->program_dirty = false;
|
||||
}
|
||||
|
||||
static void Batch_update_program_bindings_instancing(Gwn_Batch* batch, Gwn_Batch* batch_instancing, unsigned int v_first)
|
||||
static void Batch_update_program_bindings_instancing(Gwn_Batch* batch, Gwn_Batch* batch_instancing, unsigned int instance_first)
|
||||
{
|
||||
// disable all as a precaution
|
||||
// why are we not using prev_attrib_enabled_bits?? see immediate.c
|
||||
for (unsigned a_idx = 0; a_idx < GWN_VERT_ATTR_MAX_LEN; ++a_idx)
|
||||
glDisableVertexAttribArray(a_idx);
|
||||
|
||||
create_bindings(batch, batch->interface, v_first, false);
|
||||
create_bindings(batch_instancing, batch->interface, v_first, true);
|
||||
create_bindings(batch, batch->interface, 0, false);
|
||||
create_bindings(batch_instancing, batch->interface, instance_first, true);
|
||||
|
||||
batch->program_dirty = false;
|
||||
}
|
||||
@@ -346,9 +346,6 @@ void GWN_batch_draw(Gwn_Batch* batch)
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// clement : temp stuff
|
||||
void GWN_batch_draw_stupid(Gwn_Batch* batch, int v_first, int v_count)
|
||||
{
|
||||
if (batch->vao_id)
|
||||
@@ -364,9 +361,8 @@ void GWN_batch_draw_stupid(Gwn_Batch* batch, int v_first, int v_count)
|
||||
//gpuBindMatrices(batch->program);
|
||||
|
||||
// Infer lenght if vertex count is not given
|
||||
if (v_count == 0) {
|
||||
if (v_count == 0)
|
||||
v_count = (batch->elem) ? batch->elem->index_ct : batch->verts[0]->vertex_ct;
|
||||
}
|
||||
|
||||
if (batch->elem)
|
||||
{
|
||||
@@ -388,64 +384,7 @@ void GWN_batch_draw_stupid(Gwn_Batch* batch, int v_first, int v_count)
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
// clement : temp stuff
|
||||
void GWN_batch_draw_stupid_instanced(Gwn_Batch* batch, unsigned int instance_vbo, int instance_first, int instance_count,
|
||||
int attrib_nbr, int attrib_stride, int attrib_size[16], int attrib_loc[16])
|
||||
{
|
||||
if (batch->vao_id)
|
||||
glBindVertexArray(batch->vao_id);
|
||||
else
|
||||
Batch_prime(batch);
|
||||
|
||||
if (batch->program_dirty)
|
||||
Batch_update_program_bindings(batch, 0);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo);
|
||||
int ptr_ofs = instance_first * attrib_stride;
|
||||
for (int i = 0; i < attrib_nbr; ++i)
|
||||
{
|
||||
int size = attrib_size[i];
|
||||
int loc = attrib_loc[i];
|
||||
int atr_ofs = 0;
|
||||
|
||||
while (size > 0)
|
||||
{
|
||||
glEnableVertexAttribArray(loc + atr_ofs);
|
||||
glVertexAttribPointer(loc + atr_ofs, (size > 4) ? 4 : size, GL_FLOAT, GL_FALSE,
|
||||
sizeof(float) * attrib_stride, (GLvoid*)(sizeof(float) * ptr_ofs));
|
||||
glVertexAttribDivisor(loc + atr_ofs, 1);
|
||||
atr_ofs++;
|
||||
ptr_ofs += (size > 4) ? 4 : size;
|
||||
size -= 4;
|
||||
}
|
||||
}
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
// GWN_batch_program_use_begin(batch);
|
||||
|
||||
//gpuBindMatrices(batch->program);
|
||||
|
||||
if (batch->elem)
|
||||
{
|
||||
const Gwn_IndexBuf* el = batch->elem;
|
||||
#if GWN_TRACK_INDEX_RANGE
|
||||
glDrawElementsInstancedBaseVertex(batch->gl_prim_type, el->index_ct, el->gl_index_type, 0, instance_count, el->base_index);
|
||||
#else
|
||||
glDrawElementsInstanced(batch->gl_prim_type, el->index_ct, GL_UNSIGNED_INT, 0, instance_count);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
glDrawArraysInstanced(batch->gl_prim_type, 0, batch->verts[0]->vertex_ct, instance_count);
|
||||
|
||||
// Reset divisor to prevent messing the next draw
|
||||
for (unsigned a_idx = 0; a_idx < GWN_VERT_ATTR_MAX_LEN; ++a_idx)
|
||||
glVertexAttribDivisor(a_idx, 0);
|
||||
|
||||
// GWN_batch_program_use_end(batch);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
void GWN_batch_draw_stupid_instanced_with_batch(Gwn_Batch* batch_instanced, Gwn_Batch* batch_instancing)
|
||||
void GWN_batch_draw_stupid_instanced(Gwn_Batch* batch_instanced, Gwn_Batch* batch_instancing, int instance_first, int instance_count)
|
||||
{
|
||||
if (batch_instanced->vao_id)
|
||||
glBindVertexArray(batch_instanced->vao_id);
|
||||
@@ -453,22 +392,25 @@ void GWN_batch_draw_stupid_instanced_with_batch(Gwn_Batch* batch_instanced, Gwn_
|
||||
Batch_prime(batch_instanced);
|
||||
|
||||
if (batch_instanced->program_dirty)
|
||||
Batch_update_program_bindings_instancing(batch_instanced, batch_instancing, 0);
|
||||
Batch_update_program_bindings_instancing(batch_instanced, batch_instancing, instance_first);
|
||||
|
||||
Gwn_VertBuf* verts = batch_instancing->verts[0];
|
||||
|
||||
if (instance_count == 0)
|
||||
instance_count = verts->vertex_ct;
|
||||
|
||||
if (batch_instanced->elem)
|
||||
{
|
||||
const Gwn_IndexBuf* el = batch_instanced->elem;
|
||||
|
||||
#if GWN_TRACK_INDEX_RANGE
|
||||
glDrawElementsInstancedBaseVertex(batch_instanced->gl_prim_type, el->index_ct, el->gl_index_type, 0, verts->vertex_ct, el->base_index);
|
||||
glDrawElementsInstancedBaseVertex(batch_instanced->gl_prim_type, el->index_ct, el->gl_index_type, 0, instance_count, el->base_index);
|
||||
#else
|
||||
glDrawElementsInstanced(batch_instanced->gl_prim_type, el->index_ct, GL_UNSIGNED_INT, 0, verts->vertex_ct);
|
||||
glDrawElementsInstanced(batch_instanced->gl_prim_type, el->index_ct, GL_UNSIGNED_INT, 0, instance_count);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
glDrawArraysInstanced(batch_instanced->gl_prim_type, 0, batch_instanced->verts[0]->vertex_ct, verts->vertex_ct);
|
||||
glDrawArraysInstanced(batch_instanced->gl_prim_type, 0, batch_instanced->verts[0]->vertex_ct, instance_count);
|
||||
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
@@ -190,10 +190,6 @@ struct DRWUniform {
|
||||
|
||||
struct DRWInterface {
|
||||
DRWUniform *uniforms; /* DRWUniform, single-linked list */
|
||||
int attribs_count;
|
||||
int attribs_stride;
|
||||
int attribs_size[16];
|
||||
int attribs_loc[16];
|
||||
/* matrices locations */
|
||||
int model;
|
||||
int modelinverse;
|
||||
@@ -213,15 +209,16 @@ struct DRWInterface {
|
||||
int eye;
|
||||
int clipplanes;
|
||||
/* Dynamic batch */
|
||||
Gwn_Batch *instance_batch; /* contains instances attributes */
|
||||
GLuint instance_vbo; /* same as instance_batch but generated from DRWCalls */
|
||||
struct DRWInstanceData *inst_data;
|
||||
#ifdef USE_GPU_SELECT
|
||||
struct DRWInstanceData *inst_selectid;
|
||||
/* Override for single object instances. */
|
||||
int override_selectid;
|
||||
#endif
|
||||
int instance_count;
|
||||
unsigned int instance_count;
|
||||
unsigned char attribs_count;
|
||||
unsigned char attribs_stride;
|
||||
unsigned char attribs_size[MAX_ATTRIB_COUNT];
|
||||
Gwn_VertFormat vbo_format;
|
||||
};
|
||||
|
||||
@@ -279,6 +276,7 @@ struct DRWShadingGroup {
|
||||
|
||||
ID *instance_data; /* Object->data to instance */
|
||||
Gwn_Batch *instance_geom; /* Geometry to instance */
|
||||
Gwn_Batch *instancing_geom;/* Instances attributes */
|
||||
Gwn_Batch *batch_geom; /* Result of call batching */
|
||||
|
||||
#ifdef USE_GPU_SELECT
|
||||
@@ -294,6 +292,7 @@ enum {
|
||||
DRW_SHG_LINE_BATCH,
|
||||
DRW_SHG_TRIANGLE_BATCH,
|
||||
DRW_SHG_INSTANCE,
|
||||
DRW_SHG_INSTANCE_EXTERNAL,
|
||||
};
|
||||
|
||||
/* Used by DRWCall.type */
|
||||
@@ -661,8 +660,6 @@ static void drw_interface_create(DRWInterface *interface, GPUShader *shader)
|
||||
interface->instance_count = 0;
|
||||
interface->attribs_count = 0;
|
||||
interface->attribs_stride = 0;
|
||||
interface->instance_vbo = 0;
|
||||
interface->instance_batch = NULL;
|
||||
interface->inst_data = NULL;
|
||||
interface->uniforms = NULL;
|
||||
#ifdef USE_GPU_SELECT
|
||||
@@ -712,33 +709,16 @@ static void drw_interface_uniform(DRWShadingGroup *shgroup, const char *name,
|
||||
static void drw_interface_attrib(DRWShadingGroup *shgroup, const char *name, DRWAttribType UNUSED(type), int size, bool dummy)
|
||||
{
|
||||
unsigned int attrib_id = shgroup->interface.attribs_count;
|
||||
GLuint program = GPU_shader_get_program(shgroup->shader);
|
||||
|
||||
shgroup->interface.attribs_loc[attrib_id] = glGetAttribLocation(program, name);
|
||||
shgroup->interface.attribs_size[attrib_id] = size;
|
||||
shgroup->interface.attribs_stride += size;
|
||||
shgroup->interface.attribs_count += 1;
|
||||
|
||||
if (shgroup->type != DRW_SHG_INSTANCE) {
|
||||
BLI_assert(size <= 4); /* Matrices are not supported by Gawain. */
|
||||
GWN_vertformat_attr_add(&shgroup->interface.vbo_format, name, GWN_COMP_F32, size, GWN_FETCH_FLOAT);
|
||||
}
|
||||
|
||||
BLI_assert(ELEM(shgroup->type, DRW_SHG_INSTANCE, DRW_SHG_POINT_BATCH, DRW_SHG_LINE_BATCH, DRW_SHG_TRIANGLE_BATCH));
|
||||
BLI_assert(shgroup->interface.attribs_count < MAX_ATTRIB_COUNT);
|
||||
|
||||
/* Adding attribute even if not found for now (to keep memory alignment).
|
||||
* Should ideally take vertex format automatically from batch eventually */
|
||||
#if 0
|
||||
if (attrib->location == -1 && !dummy) {
|
||||
if (G.debug & G_DEBUG)
|
||||
fprintf(stderr, "Attribute '%s' not found!\n", name);
|
||||
BLI_assert(0);
|
||||
MEM_freeN(attrib);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
GWN_vertformat_attr_add(&shgroup->interface.vbo_format, name, GWN_COMP_F32, size, GWN_FETCH_FLOAT);
|
||||
|
||||
UNUSED_VARS(dummy);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -771,6 +751,7 @@ DRWShadingGroup *DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass)
|
||||
shgroup->state_extra_disable = ~0x0;
|
||||
shgroup->stencil_mask = 0;
|
||||
shgroup->batch_geom = NULL;
|
||||
shgroup->instancing_geom = NULL;
|
||||
shgroup->instance_geom = NULL;
|
||||
shgroup->instance_data = NULL;
|
||||
|
||||
@@ -921,12 +902,9 @@ DRWShadingGroup *DRW_shgroup_empty_tri_batch_create(struct GPUShader *shader, DR
|
||||
|
||||
void DRW_shgroup_free(struct DRWShadingGroup *shgroup)
|
||||
{
|
||||
if (shgroup->interface.instance_vbo &&
|
||||
(shgroup->interface.instance_batch == 0))
|
||||
{
|
||||
glDeleteBuffers(1, &shgroup->interface.instance_vbo);
|
||||
if (shgroup->type != DRW_SHG_INSTANCE_EXTERNAL) {
|
||||
GWN_BATCH_DISCARD_SAFE(shgroup->instancing_geom);
|
||||
}
|
||||
|
||||
GWN_BATCH_DISCARD_SAFE(shgroup->batch_geom);
|
||||
}
|
||||
|
||||
@@ -942,12 +920,14 @@ void DRW_shgroup_free(struct DRWShadingGroup *shgroup)
|
||||
call->head.prev = NULL; \
|
||||
} ((void)0)
|
||||
|
||||
/* Specify an external batch instead of adding each attrib one by one. */
|
||||
void DRW_shgroup_instance_batch(DRWShadingGroup *shgroup, struct Gwn_Batch *instances)
|
||||
{
|
||||
BLI_assert(shgroup->type == DRW_SHG_INSTANCE);
|
||||
BLI_assert(shgroup->interface.instance_batch == NULL);
|
||||
BLI_assert(shgroup->instancing_geom == NULL);
|
||||
|
||||
shgroup->interface.instance_batch = instances;
|
||||
shgroup->type = DRW_SHG_INSTANCE_EXTERNAL;
|
||||
shgroup->instancing_geom = instances;
|
||||
|
||||
#ifdef USE_GPU_SELECT
|
||||
DRWCall *call = BLI_mempool_alloc(DST.vmempool->calls);
|
||||
@@ -1226,48 +1206,35 @@ static void shgroup_dynamic_batch(DRWShadingGroup *shgroup)
|
||||
static void shgroup_dynamic_instance(DRWShadingGroup *shgroup)
|
||||
{
|
||||
DRWInterface *interface = &shgroup->interface;
|
||||
int buffer_size = 0;
|
||||
void *data = NULL;
|
||||
int nbr = interface->instance_count;
|
||||
|
||||
if (interface->instance_batch != NULL) {
|
||||
if (nbr == 0)
|
||||
return;
|
||||
|
||||
/* XXX Add a dummy attr for simple instancing. */
|
||||
if (interface->attribs_count == 0) {
|
||||
drw_interface_attrib(shgroup, "dummy", DRW_ATTRIB_FLOAT, 1, true);
|
||||
}
|
||||
|
||||
/* TODO We still need this because gawain does not support Matrix attribs. */
|
||||
if (interface->instance_count == 0) {
|
||||
if (interface->instance_vbo) {
|
||||
glDeleteBuffers(1, &interface->instance_vbo);
|
||||
interface->instance_vbo = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Gather Data */
|
||||
buffer_size = sizeof(float) * interface->attribs_stride * interface->instance_count;
|
||||
|
||||
/* TODO poke mike to add this to gawain */
|
||||
if (interface->instance_vbo) {
|
||||
glDeleteBuffers(1, &interface->instance_vbo);
|
||||
interface->instance_vbo = 0;
|
||||
}
|
||||
|
||||
/* Upload Data */
|
||||
Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&interface->vbo_format);
|
||||
if (interface->inst_data) {
|
||||
data = DRW_instance_data_get(interface->inst_data);
|
||||
GWN_vertbuf_data_set(vbo, nbr, DRW_instance_data_get(interface->inst_data), false);
|
||||
} else {
|
||||
/* Use unitialized memory. This is for dummy vertex buffers. */
|
||||
/* XXX TODO do not alloc at all. */
|
||||
GWN_vertbuf_data_alloc(vbo, nbr);
|
||||
}
|
||||
|
||||
glGenBuffers(1, &interface->instance_vbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, interface->instance_vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, buffer_size, data, GL_STATIC_DRAW);
|
||||
/* TODO make the batch dynamic instead of freeing it every times */
|
||||
if (shgroup->instancing_geom)
|
||||
GWN_batch_discard(shgroup->instancing_geom);
|
||||
|
||||
shgroup->instancing_geom = GWN_batch_create_ex(GWN_PRIM_POINTS, vbo, NULL, GWN_BATCH_OWNS_VBO);
|
||||
}
|
||||
|
||||
static void shgroup_dynamic_batch_from_calls(DRWShadingGroup *shgroup)
|
||||
{
|
||||
if ((shgroup->interface.instance_vbo || shgroup->batch_geom) &&
|
||||
(G.debug_value == 667))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (shgroup->type == DRW_SHG_INSTANCE) {
|
||||
shgroup_dynamic_instance(shgroup);
|
||||
}
|
||||
@@ -1797,17 +1764,10 @@ static void draw_geometry_prepare(
|
||||
static void draw_geometry_execute_ex(
|
||||
DRWShadingGroup *shgroup, Gwn_Batch *geom, unsigned int start, unsigned int count)
|
||||
{
|
||||
DRWInterface *interface = &shgroup->interface;
|
||||
/* step 2 : bind vertex array & draw */
|
||||
GWN_batch_program_set(geom, GPU_shader_get_program(shgroup->shader), GPU_shader_get_interface(shgroup->shader));
|
||||
if (interface->instance_batch) {
|
||||
/* Used for Particles. Cannot do partial drawing. */
|
||||
GWN_batch_draw_stupid_instanced_with_batch(geom, interface->instance_batch);
|
||||
}
|
||||
else if (interface->instance_vbo) {
|
||||
GWN_batch_draw_stupid_instanced(
|
||||
geom, interface->instance_vbo, start, count, interface->attribs_count,
|
||||
interface->attribs_stride, interface->attribs_size, interface->attribs_loc);
|
||||
if (shgroup->instancing_geom) {
|
||||
GWN_batch_draw_stupid_instanced(geom, shgroup->instancing_geom, start, count);
|
||||
}
|
||||
else {
|
||||
GWN_batch_draw_stupid(geom, start, count);
|
||||
@@ -2033,10 +1993,10 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
|
||||
float obmat[4][4];
|
||||
unit_m4(obmat);
|
||||
|
||||
if (shgroup->type == DRW_SHG_INSTANCE &&
|
||||
(interface->instance_count > 0 || interface->instance_batch != NULL))
|
||||
if (ELEM(shgroup->type, DRW_SHG_INSTANCE, DRW_SHG_INSTANCE_EXTERNAL) &&
|
||||
(shgroup->instancing_geom != NULL))
|
||||
{
|
||||
if (interface->instance_batch != NULL) {
|
||||
if (shgroup->type == DRW_SHG_INSTANCE_EXTERNAL) {
|
||||
GPU_SELECT_LOAD_IF_PICKSEL((DRWCall *)shgroup->calls_first);
|
||||
draw_geometry(shgroup, shgroup->instance_geom, obmat, shgroup->instance_data, 0, 0);
|
||||
}
|
||||
|
||||
@@ -1007,7 +1007,7 @@ bool GPU_fx_do_composite_pass(
|
||||
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
/* the draw call we all waited for, draw a point per pixel, scaled per circle of confusion */
|
||||
GWN_batch_draw_stupid_instanced(fx->point_batch, 0, fx->dof_downsampled_w * fx->dof_downsampled_h, 0, 0, 0, NULL, NULL);
|
||||
// GWN_batch_draw_stupid_instanced(fx->point_batch, 0, fx->dof_downsampled_w * fx->dof_downsampled_h, 0, 0, 0, NULL, NULL);
|
||||
|
||||
GPU_texture_unbind(fx->dof_half_downsampled_far);
|
||||
GPU_framebuffer_texture_detach(fx->dof_far_blur);
|
||||
@@ -1023,7 +1023,7 @@ bool GPU_fx_do_composite_pass(
|
||||
/* have to clear the buffer unfortunately */
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
/* the draw call we all waited for, draw a point per pixel, scaled per circle of confusion */
|
||||
GWN_batch_draw_stupid_instanced(fx->point_batch, 0, fx->dof_downsampled_w * fx->dof_downsampled_h, 0, 0, 0, NULL, NULL);
|
||||
// GWN_batch_draw_stupid_instanced(fx->point_batch, 0, fx->dof_downsampled_w * fx->dof_downsampled_h, 0, 0, 0, NULL, NULL);
|
||||
GWN_batch_program_use_end(fx->point_batch);
|
||||
|
||||
/* disable bindings */
|
||||
|
||||
Reference in New Issue
Block a user