/** * Instanced drawing. * \sa draw_vbo */ void draw_arrays_instanced(struct draw_context *draw, unsigned mode, unsigned start, unsigned count, unsigned startInstance, unsigned instanceCount) { struct pipe_draw_info info; util_draw_init_info(&info); info.mode = mode; info.start = start; info.count = count; info.start_instance = startInstance; info.instance_count = instanceCount; info.indexed = (draw->pt.user.elts != NULL); if (!info.indexed) { info.min_index = start; info.max_index = start + count - 1; } draw_vbo(draw, &info); }
static void draw( void ) { float clear_color[4] = {1,0,1,1}; struct pipe_draw_info info; ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0); util_draw_init_info(&info); info.indexed = (draw_elements != 0); info.mode = PIPE_PRIM_TRIANGLES; info.start = 0; info.count = 3; /* draw NUM_INST triangles */ info.instance_count = NUM_INST; ctx->draw_vbo(ctx, &info); ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); #if 0 /* At the moment, libgraw leaks out/makes available some of the * symbols from gallium/auxiliary, including these debug helpers. * Will eventually want to bless some of these paths, and lock the * others down so they aren't accessible from test programs. * * This currently just happens to work on debug builds - a release * build will probably fail to link here: */ debug_dump_surface_bmp(ctx, "result.bmp", surf); #endif screen->flush_frontbuffer(screen, surf, window); }
void cso_draw_arrays(struct cso_context *cso, uint mode, uint start, uint count) { struct pipe_draw_info info; util_draw_init_info(&info); info.mode = mode; info.start = start; info.count = count; info.min_index = start; info.max_index = start + count - 1; cso_draw_vbo(cso, &info); }
/** * Set the states that are invariant between all ops. */ static bool ilo_blitter_set_invariants(struct ilo_blitter *blitter) { struct pipe_vertex_element velem; struct pipe_viewport_state vp; if (blitter->initialized) return true; /* only vertex X and Y */ memset(&velem, 0, sizeof(velem)); velem.src_format = PIPE_FORMAT_R32G32_FLOAT; ilo_gpe_init_ve(blitter->ilo->dev, 1, &velem, &blitter->ve); /* generate VUE header */ ilo_gpe_init_ve_nosrc(blitter->ilo->dev, GEN6_VFCOMP_STORE_0, /* Reserved */ GEN6_VFCOMP_STORE_0, /* Render Target Array Index */ GEN6_VFCOMP_STORE_0, /* Viewport Index */ GEN6_VFCOMP_STORE_0, /* Point Width */ &blitter->ve.nosrc_cso); blitter->ve.prepend_nosrc_cso = true; /* a rectangle has 3 vertices in a RECTLIST */ util_draw_init_info(&blitter->draw); blitter->draw.mode = ILO_PRIM_RECTANGLES; blitter->draw.count = 3; /** * From the Haswell PRM, volume 7, page 615: * * "The clear value must be between the min and max depth values * (inclusive) defined in the CC_VIEWPORT." * * Even though clipping and viewport transformation will be disabled, we * still need to set up the viewport states. */ memset(&vp, 0, sizeof(vp)); vp.scale[0] = 1.0f; vp.scale[1] = 1.0f; vp.scale[2] = 1.0f; ilo_gpe_set_viewport_cso(blitter->ilo->dev, &vp, &blitter->viewport); blitter->initialized = true; return true; }
static void draw( void ) { union pipe_color_union clear_color = { {1,0,1,1} }; struct pipe_draw_info info; ctx->clear(ctx, PIPE_CLEAR_COLOR, &clear_color, 0, 0); util_draw_init_info(&info); info.indexed = (draw_elements != 0); info.mode = PIPE_PRIM_TRIANGLES; info.start = 0; info.count = 3; /* draw NUM_INST triangles */ info.instance_count = NUM_INST; ctx->draw_vbo(ctx, &info); ctx->flush(ctx, NULL, 0); graw_save_surface_to_file(ctx, surf, NULL); screen->flush_frontbuffer(screen, tex, 0, 0, window); }
/** * This function gets plugged into the VBO module and is called when * we have something to render. * Basically, translate the information into the format expected by gallium. */ void st_draw_vbo(struct gl_context *ctx, const struct _mesa_prim *prims, GLuint nr_prims, const struct _mesa_index_buffer *ib, GLboolean index_bounds_valid, GLuint min_index, GLuint max_index, struct gl_transform_feedback_object *tfb_vertcount, struct gl_buffer_object *indirect) { struct st_context *st = st_context(ctx); struct pipe_index_buffer ibuffer = {0}; struct pipe_draw_info info; const struct gl_client_array **arrays = ctx->Array._DrawArrays; unsigned i; /* Mesa core state should have been validated already */ assert(ctx->NewState == 0x0); /* Validate state. */ if (st->dirty.st || ctx->NewDriverState) { st_validate_state(st); #if 0 if (MESA_VERBOSE & VERBOSE_GLSL) { check_uniforms(ctx); } #else (void) check_uniforms; #endif } if (st->vertex_array_out_of_memory) { return; } util_draw_init_info(&info); if (ib) { /* Get index bounds for user buffers. */ if (!index_bounds_valid) if (!all_varyings_in_vbos(arrays)) vbo_get_minmax_indices(ctx, prims, ib, &min_index, &max_index, nr_prims); if (!setup_index_buffer(st, ib, &ibuffer)) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBegin/DrawElements/DrawArray"); return; } info.indexed = TRUE; if (min_index != ~0 && max_index != ~0) { info.min_index = min_index; info.max_index = max_index; } /* The VBO module handles restart for the non-indexed GLDrawArrays * so we only set these fields for indexed drawing: */ info.primitive_restart = ctx->Array._PrimitiveRestart; info.restart_index = ctx->Array.RestartIndex; } else { /* Transform feedback drawing is always non-indexed. */ /* Set info.count_from_stream_output. */ if (tfb_vertcount) { st_transform_feedback_draw_init(tfb_vertcount, &info); } } /* do actual drawing */ for (i = 0; i < nr_prims; i++) { info.mode = translate_prim(ctx, prims[i].mode); info.start = prims[i].start; info.count = prims[i].count; info.start_instance = prims[i].base_instance; info.instance_count = prims[i].num_instances; info.index_bias = prims[i].basevertex; if (!ib) { info.min_index = info.start; info.max_index = info.start + info.count - 1; } if (ST_DEBUG & DEBUG_DRAW) { debug_printf("st/draw: mode %s start %u count %u indexed %d\n", u_prim_name(info.mode), info.start, info.count, info.indexed); } if (info.count_from_stream_output) { cso_draw_vbo(st->cso_context, &info); } else if (info.primitive_restart) { /* don't trim, restarts might be inside index list */ cso_draw_vbo(st->cso_context, &info); } else if (u_trim_pipe_prim(prims[i].mode, &info.count)) { cso_draw_vbo(st->cso_context, &info); } } if (ib && st->indexbuf_uploader && !_mesa_is_bufferobj(ib->obj)) { pipe_resource_reference(&ibuffer.buffer, NULL); } }
static void st_indirect_draw_vbo(struct gl_context *ctx, GLuint mode, struct gl_buffer_object *indirect_data, GLsizeiptr indirect_offset, unsigned draw_count, unsigned stride, struct gl_buffer_object *indirect_params, GLsizeiptr indirect_params_offset, const struct _mesa_index_buffer *ib) { struct st_context *st = st_context(ctx); struct pipe_index_buffer ibuffer = {0}; struct pipe_draw_info info; /* Mesa core state should have been validated already */ assert(ctx->NewState == 0x0); assert(stride); /* Validate state. */ if ((st->dirty | ctx->NewDriverState) & ST_PIPELINE_RENDER_STATE_MASK || st->gfx_shaders_may_be_dirty) { st_validate_state(st, ST_PIPELINE_RENDER); } if (st->vertex_array_out_of_memory) { return; } util_draw_init_info(&info); if (ib) { if (!setup_index_buffer(st, ib, &ibuffer)) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "gl%sDrawElementsIndirect%s", (draw_count > 1) ? "Multi" : "", indirect_params ? "CountARB" : ""); return; } info.indexed = TRUE; /* Primitive restart is not handled by the VBO module in this case. */ setup_primitive_restart(ctx, ib, &info); } info.mode = translate_prim(ctx, mode); info.vertices_per_patch = ctx->TessCtrlProgram.patch_vertices; info.indirect = st_buffer_object(indirect_data)->buffer; info.indirect_offset = indirect_offset; if (ST_DEBUG & DEBUG_DRAW) { debug_printf("st/draw indirect: mode %s drawcount %d indexed %d\n", u_prim_name(info.mode), draw_count, info.indexed); } if (!st->has_multi_draw_indirect) { int i; assert(!indirect_params); info.indirect_count = 1; for (i = 0; i < draw_count; i++) { info.drawid = i; cso_draw_vbo(st->cso_context, &info); info.indirect_offset += stride; } } else { info.indirect_count = draw_count; info.indirect_stride = stride; if (indirect_params) { info.indirect_params = st_buffer_object(indirect_params)->buffer; info.indirect_params_offset = indirect_params_offset; } cso_draw_vbo(st->cso_context, &info); } }
/** * This function gets plugged into the VBO module and is called when * we have something to render. * Basically, translate the information into the format expected by gallium. */ void st_draw_vbo(struct gl_context *ctx, const struct _mesa_prim *prims, GLuint nr_prims, const struct _mesa_index_buffer *ib, GLboolean index_bounds_valid, GLuint min_index, GLuint max_index, struct gl_transform_feedback_object *tfb_vertcount) { struct st_context *st = st_context(ctx); struct pipe_index_buffer ibuffer = {0}; struct pipe_draw_info info; const struct gl_client_array **arrays = ctx->Array._DrawArrays; unsigned i; GLboolean new_array; /* Mesa core state should have been validated already */ assert(ctx->NewState == 0x0); /* Get Mesa driver state. */ st->dirty.st |= ctx->NewDriverState; ctx->NewDriverState = 0; new_array = (st->dirty.st & (ST_NEW_VERTEX_ARRAYS | ST_NEW_VERTEX_PROGRAM)) || (st->dirty.mesa & (_NEW_PROGRAM | _NEW_BUFFER_OBJECT)) != 0; /* Validate state. */ if (st->dirty.st) { GLboolean vertDataEdgeFlags; vertDataEdgeFlags = arrays[VERT_ATTRIB_EDGEFLAG]->BufferObj && arrays[VERT_ATTRIB_EDGEFLAG]->BufferObj->Name; if (vertDataEdgeFlags != st->vertdata_edgeflags) { st->vertdata_edgeflags = vertDataEdgeFlags; st->dirty.st |= ST_NEW_EDGEFLAGS_DATA; } st_validate_state(st); if (new_array) { if (!st_validate_varrays(ctx, arrays)) { /* probably out of memory, no-op the draw call */ return; } } #if 0 if (MESA_VERBOSE & VERBOSE_GLSL) { check_uniforms(ctx); } #else (void) check_uniforms; #endif } util_draw_init_info(&info); if (ib) { /* Get index bounds for user buffers. */ if (!index_bounds_valid) if (!all_varyings_in_vbos(arrays)) vbo_get_minmax_indices(ctx, prims, ib, &min_index, &max_index, nr_prims); setup_index_buffer(st, ib, &ibuffer); info.indexed = TRUE; if (min_index != ~0 && max_index != ~0) { info.min_index = min_index; info.max_index = max_index; } /* The VBO module handles restart for the non-indexed GLDrawArrays * so we only set these fields for indexed drawing: */ info.primitive_restart = ctx->Array.PrimitiveRestart; info.restart_index = ctx->Array.RestartIndex; } else { /* Transform feedback drawing is always non-indexed. */ /* Set info.count_from_stream_output. */ if (tfb_vertcount) { st_transform_feedback_draw_init(tfb_vertcount, &info); } } /* do actual drawing */ for (i = 0; i < nr_prims; i++) { info.mode = translate_prim( ctx, prims[i].mode ); info.start = prims[i].start; info.count = prims[i].count; info.instance_count = prims[i].num_instances; info.index_bias = prims[i].basevertex; if (!ib) { info.min_index = info.start; info.max_index = info.start + info.count - 1; } if (info.count_from_stream_output) { cso_draw_vbo(st->cso_context, &info); } else if (info.primitive_restart) { /* don't trim, restarts might be inside index list */ cso_draw_vbo(st->cso_context, &info); } else if (u_trim_pipe_prim(info.mode, &info.count)) cso_draw_vbo(st->cso_context, &info); } if (ib && st->indexbuf_uploader && !_mesa_is_bufferobj(ib->obj)) { pipe_resource_reference(&ibuffer.buffer, NULL); } }