/** * Draw vertex arrays, with optional indexing, optional instancing. * All the other drawing functions are implemented in terms of this function. * Basically, map the vertex buffers (and drawing surfaces), then hand off * the drawing to the 'draw' module. */ static void llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) { struct llvmpipe_context *lp = llvmpipe_context(pipe); struct draw_context *draw = lp->draw; const void *mapped_indices = NULL; unsigned i; if (!llvmpipe_check_render_cond(lp)) return; if (lp->dirty) llvmpipe_update_derived( lp ); /* * Map vertex buffers */ for (i = 0; i < lp->num_vertex_buffers; i++) { const void *buf = lp->vertex_buffer[i].user_buffer; if (!buf) buf = llvmpipe_resource_data(lp->vertex_buffer[i].buffer); draw_set_mapped_vertex_buffer(draw, i, buf); } /* Map index buffer, if present */ if (info->indexed) { mapped_indices = lp->index_buffer.user_buffer; if (!mapped_indices) mapped_indices = llvmpipe_resource_data(lp->index_buffer.buffer); draw_set_indexes(draw, (ubyte *) mapped_indices + lp->index_buffer.offset, lp->index_buffer.index_size); } llvmpipe_prepare_vertex_sampling(lp, lp->num_sampler_views[PIPE_SHADER_VERTEX], lp->sampler_views[PIPE_SHADER_VERTEX]); /* draw! */ draw_vbo(draw, info); /* * unmap vertex/index buffers */ for (i = 0; i < lp->num_vertex_buffers; i++) { draw_set_mapped_vertex_buffer(draw, i, NULL); } if (mapped_indices) { draw_set_indexes(draw, NULL, 0); } llvmpipe_cleanup_vertex_sampling(lp); /* * TODO: Flush only when a user vertex/index buffer is present * (or even better, modify draw module to do this * internally when this condition is seen?) */ draw_flush(draw); }
void nvfx_draw_vbo_swtnl(struct pipe_context *pipe, const struct pipe_draw_info* info) { struct nvfx_context *nvfx = nvfx_context(pipe); unsigned i; void *map; if (!nvfx_state_validate_swtnl(nvfx)) return; nvfx_state_emit(nvfx); /* these must be passed without adding the offsets */ for (i = 0; i < nvfx->vtxbuf_nr; i++) { map = nvfx_buffer(nvfx->vtxbuf[i].buffer)->data; draw_set_mapped_vertex_buffer(nvfx->draw, i, map); } map = NULL; if (info->indexed && nvfx->idxbuf.buffer) map = nvfx_buffer(nvfx->idxbuf.buffer)->data; draw_set_mapped_index_buffer(nvfx->draw, map); if (nvfx->constbuf[PIPE_SHADER_VERTEX]) { const unsigned nr = nvfx->constbuf_nr[PIPE_SHADER_VERTEX]; map = nvfx_buffer(nvfx->constbuf[PIPE_SHADER_VERTEX])->data; draw_set_mapped_constant_buffer(nvfx->draw, PIPE_SHADER_VERTEX, 0, map, nr); } draw_vbo(nvfx->draw, info); draw_flush(nvfx->draw); }
static void llvmpipe_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, struct pipe_resource *constants) { struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); unsigned size = constants ? constants->width0 : 0; const void *data = constants ? llvmpipe_resource_data(constants) : NULL; assert(shader < PIPE_SHADER_TYPES); assert(index < PIPE_MAX_CONSTANT_BUFFERS); if(llvmpipe->constants[shader][index] == constants) return; draw_flush(llvmpipe->draw); /* note: reference counting */ pipe_resource_reference(&llvmpipe->constants[shader][index], constants); if(shader == PIPE_SHADER_VERTEX || shader == PIPE_SHADER_GEOMETRY) { draw_set_mapped_constant_buffer(llvmpipe->draw, shader, index, data, size); } llvmpipe->dirty |= LP_NEW_CONSTANTS; }
static void i915_set_sampler_textures(struct pipe_context *pipe, unsigned num, struct pipe_texture **texture) { struct i915_context *i915 = i915_context(pipe); uint i; assert(num <= PIPE_MAX_SAMPLERS); /* Check for no-op */ if (num == i915->num_textures && !memcmp(i915->texture, texture, num * sizeof(struct pipe_texture *))) return; /* Fixes wrong texture in texobj with VBUF */ draw_flush(i915->draw); for (i = 0; i < num; i++) pipe_texture_reference((struct pipe_texture **) &i915->texture[i], texture[i]); for (i = num; i < i915->num_textures; i++) pipe_texture_reference((struct pipe_texture **) &i915->texture[i], NULL); i915->num_textures = num; i915->dirty |= I915_NEW_TEXTURE; }
static void i915_set_fragment_sampler_views(struct pipe_context *pipe, unsigned num, struct pipe_sampler_view **views) { struct i915_context *i915 = i915_context(pipe); uint i; assert(num <= PIPE_MAX_SAMPLERS); /* Check for no-op */ if (num == i915->num_fragment_sampler_views && !memcmp(i915->fragment_sampler_views, views, num * sizeof(struct pipe_sampler_view *))) return; /* Fixes wrong texture in texobj with VBUF */ draw_flush(i915->draw); for (i = 0; i < num; i++) pipe_sampler_view_reference(&i915->fragment_sampler_views[i], views[i]); for (i = num; i < i915->num_fragment_sampler_views; i++) pipe_sampler_view_reference(&i915->fragment_sampler_views[i], NULL); i915->num_fragment_sampler_views = num; i915->dirty |= I915_NEW_SAMPLER_VIEW; }
void llvmpipe_set_vertex_sampler_textures(struct pipe_context *pipe, unsigned num_textures, struct pipe_texture **textures) { struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); uint i; assert(num_textures <= PIPE_MAX_VERTEX_SAMPLERS); /* Check for no-op */ if (num_textures == llvmpipe->num_vertex_textures && !memcmp(llvmpipe->vertex_textures, textures, num_textures * sizeof(struct pipe_texture *))) { return; } draw_flush(llvmpipe->draw); for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { struct pipe_texture *tex = i < num_textures ? textures[i] : NULL; pipe_texture_reference(&llvmpipe->vertex_textures[i], tex); } llvmpipe->num_vertex_textures = num_textures; llvmpipe->dirty |= LP_NEW_TEXTURE; }
void llvmpipe_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, struct pipe_buffer *constants) { struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); unsigned size = constants ? constants->size : 0; const void *data = constants ? llvmpipe_buffer(constants)->data : NULL; assert(shader < PIPE_SHADER_TYPES); assert(index == 0); if(llvmpipe->constants[shader] == constants) return; draw_flush(llvmpipe->draw); /* note: reference counting */ pipe_buffer_reference(&llvmpipe->constants[shader], constants); if(shader == PIPE_SHADER_VERTEX) { draw_set_mapped_constant_buffer(llvmpipe->draw, PIPE_SHADER_VERTEX, 0, data, size); } llvmpipe->dirty |= LP_NEW_CONSTANTS; }
void softpipe_set_sampler_textures(struct pipe_context *pipe, unsigned num, struct pipe_texture **texture) { struct softpipe_context *softpipe = softpipe_context(pipe); uint i; assert(num <= PIPE_MAX_SAMPLERS); /* Check for no-op */ if (num == softpipe->num_textures && !memcmp(softpipe->texture, texture, num * sizeof(struct pipe_texture *))) return; draw_flush(softpipe->draw); for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { struct pipe_texture *tex = i < num ? texture[i] : NULL; pipe_texture_reference(&softpipe->texture[i], tex); sp_tex_tile_cache_set_texture(softpipe->tex_cache[i], tex); } softpipe->num_textures = num; softpipe->dirty |= SP_NEW_TEXTURE; }
void softpipe_bind_sampler_states(struct pipe_context *pipe, unsigned num, void **sampler) { struct softpipe_context *softpipe = softpipe_context(pipe); unsigned i; assert(num <= PIPE_MAX_SAMPLERS); /* Check for no-op */ if (num == softpipe->num_samplers && !memcmp(softpipe->sampler, sampler, num * sizeof(void *))) return; draw_flush(softpipe->draw); for (i = 0; i < num; ++i) softpipe->sampler[i] = sampler[i]; for (i = num; i < PIPE_MAX_SAMPLERS; ++i) softpipe->sampler[i] = NULL; softpipe->num_samplers = num; softpipe->dirty |= SP_NEW_SAMPLER; }
static void llvmpipe_set_vertex_sampler_views(struct pipe_context *pipe, unsigned num, struct pipe_sampler_view **views) { struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); uint i; assert(num <= PIPE_MAX_VERTEX_SAMPLERS); /* Check for no-op */ if (num == llvmpipe->num_vertex_sampler_views && !memcmp(llvmpipe->vertex_sampler_views, views, num * sizeof(struct pipe_sampler_view *))) { return; } draw_flush(llvmpipe->draw); for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { struct pipe_sampler_view *view = i < num ? views[i] : NULL; pipe_sampler_view_reference(&llvmpipe->vertex_sampler_views[i], view); } llvmpipe->num_vertex_sampler_views = num; draw_set_sampler_views(llvmpipe->draw, llvmpipe->vertex_sampler_views, llvmpipe->num_vertex_sampler_views); llvmpipe->dirty |= LP_NEW_SAMPLER_VIEW; }
void llvmpipe_bind_vertex_sampler_states(struct pipe_context *pipe, unsigned num_samplers, void **samplers) { struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); unsigned i; assert(num_samplers <= PIPE_MAX_VERTEX_SAMPLERS); /* Check for no-op */ if (num_samplers == llvmpipe->num_vertex_samplers && !memcmp(llvmpipe->vertex_samplers, samplers, num_samplers * sizeof(void *))) return; draw_flush(llvmpipe->draw); for (i = 0; i < num_samplers; ++i) llvmpipe->vertex_samplers[i] = samplers[i]; for (i = num_samplers; i < PIPE_MAX_VERTEX_SAMPLERS; ++i) llvmpipe->vertex_samplers[i] = NULL; llvmpipe->num_vertex_samplers = num_samplers; llvmpipe->dirty |= LP_NEW_SAMPLER; }
/** * \param fence if non-null, returns pointer to a fence which can be waited on */ void llvmpipe_flush( struct pipe_context *pipe, struct pipe_fence_handle **fence, const char *reason) { struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); draw_flush(llvmpipe->draw); /* ask the setup module to flush */ lp_setup_flush(llvmpipe->setup, fence, reason); /* Enable to dump BMPs of the color/depth buffers each frame */ if (0) { static unsigned frame_no = 1; char filename[256]; unsigned i; for (i = 0; i < llvmpipe->framebuffer.nr_cbufs; i++) { util_snprintf(filename, sizeof(filename), "cbuf%u_%u", i, frame_no); debug_dump_surface_bmp(&llvmpipe->pipe, filename, llvmpipe->framebuffer.cbufs[i]); } if (0) { util_snprintf(filename, sizeof(filename), "zsbuf_%u", frame_no); debug_dump_surface_bmp(&llvmpipe->pipe, filename, llvmpipe->framebuffer.zsbuf); } ++frame_no; } }
void llvmpipe_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, const struct pipe_constant_buffer *constants) { struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); struct pipe_buffer *buffer = constants ? constants->buffer : NULL; unsigned size = buffer ? buffer->size : 0; const void *data = buffer ? llvmpipe_buffer(buffer)->data : NULL; assert(shader < PIPE_SHADER_TYPES); assert(index == 0); if(shader == PIPE_SHADER_VERTEX) draw_flush(llvmpipe->draw); /* note: reference counting */ pipe_buffer_reference(&llvmpipe->constants[shader].buffer, buffer); if(shader == PIPE_SHADER_FRAGMENT) { llvmpipe->jit_context.constants = data; } if(shader == PIPE_SHADER_VERTEX) { draw_set_mapped_constant_buffer(llvmpipe->draw, data, size); } llvmpipe->dirty |= LP_NEW_CONSTANTS; }
/* SW TCL elements, using Draw. */ static void r300_swtcl_draw_vbo(struct pipe_context* pipe, const struct pipe_draw_info *info) { struct r300_context* r300 = r300_context(pipe); struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS]; struct pipe_transfer *ib_transfer = NULL; int i; void *indices = NULL; boolean indexed = info->indexed && r300->vbuf_mgr->index_buffer.buffer; if (r300->skip_rendering) { return; } r300_update_derived_state(r300); r300_reserve_cs_dwords(r300, PREP_EMIT_STATES | PREP_EMIT_VARRAYS_SWTCL | (indexed ? PREP_INDEXED : 0), indexed ? 256 : 6); for (i = 0; i < r300->vbuf_mgr->nr_vertex_buffers; i++) { if (r300->vbuf_mgr->vertex_buffer[i].buffer) { void *buf = pipe_buffer_map(pipe, r300->vbuf_mgr->vertex_buffer[i].buffer, PIPE_TRANSFER_READ | PIPE_TRANSFER_UNSYNCHRONIZED, &vb_transfer[i]); draw_set_mapped_vertex_buffer(r300->draw, i, buf); } } if (indexed) { indices = pipe_buffer_map(pipe, r300->vbuf_mgr->index_buffer.buffer, PIPE_TRANSFER_READ | PIPE_TRANSFER_UNSYNCHRONIZED, &ib_transfer); } draw_set_mapped_index_buffer(r300->draw, indices); r300->draw_vbo_locked = TRUE; r300->draw_first_emitted = FALSE; draw_vbo(r300->draw, info); draw_flush(r300->draw); r300->draw_vbo_locked = FALSE; for (i = 0; i < r300->vbuf_mgr->nr_vertex_buffers; i++) { if (r300->vbuf_mgr->vertex_buffer[i].buffer) { pipe_buffer_unmap(pipe, vb_transfer[i]); draw_set_mapped_vertex_buffer(r300->draw, i, NULL); } } if (indexed) { pipe_buffer_unmap(pipe, ib_transfer); draw_set_mapped_index_buffer(r300->draw, NULL); } }
void softpipe_set_sampler_views(struct pipe_context *pipe, unsigned shader, unsigned start, unsigned num, struct pipe_sampler_view **views) { struct softpipe_context *softpipe = softpipe_context(pipe); uint i; assert(shader < PIPE_SHADER_TYPES); assert(start + num <= ARRAY_SIZE(softpipe->sampler_views[shader])); draw_flush(softpipe->draw); /* set the new sampler views */ for (i = 0; i < num; i++) { struct sp_sampler_view *sp_sviewsrc; struct sp_sampler_view *sp_sviewdst = &softpipe->tgsi.sampler[shader]->sp_sview[start + i]; struct pipe_sampler_view **pview = &softpipe->sampler_views[shader][start + i]; pipe_sampler_view_reference(pview, views[i]); sp_tex_tile_cache_set_sampler_view(softpipe->tex_cache[shader][start + i], views[i]); /* * We don't really have variants, however some bits are different per shader, * so just copy? */ sp_sviewsrc = (struct sp_sampler_view *)*pview; if (sp_sviewsrc) { memcpy(sp_sviewdst, sp_sviewsrc, sizeof(*sp_sviewsrc)); sp_sviewdst->compute_lambda = softpipe_get_lambda_func(&sp_sviewdst->base, shader); sp_sviewdst->cache = softpipe->tex_cache[shader][start + i]; } else { memset(sp_sviewdst, 0, sizeof(*sp_sviewsrc)); } } /* find highest non-null sampler_views[] entry */ { unsigned j = MAX2(softpipe->num_sampler_views[shader], start + num); while (j > 0 && softpipe->sampler_views[shader][j - 1] == NULL) j--; softpipe->num_sampler_views[shader] = j; } if (shader == PIPE_SHADER_VERTEX || shader == PIPE_SHADER_GEOMETRY) { draw_set_sampler_views(softpipe->draw, shader, softpipe->sampler_views[shader], softpipe->num_sampler_views[shader]); } softpipe->dirty |= SP_NEW_TEXTURE; }
static void i915_set_scissor_state( struct pipe_context *pipe, const struct pipe_scissor_state *scissor ) { struct i915_context *i915 = i915_context(pipe); draw_flush(i915->draw); memcpy( &i915->scissor, scissor, sizeof(*scissor) ); i915->dirty |= I915_NEW_SCISSOR; }
static void i915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) { struct i915_context *i915 = i915_context(pipe); struct draw_context *draw = i915->draw; const void *mapped_indices = NULL; /* * Ack vs contants here, helps ipers a lot. */ i915->dirty &= ~I915_NEW_VS_CONSTANTS; if (i915->dirty) i915_update_derived(i915); /* * Map index buffer, if present */ if (info->indexed) { mapped_indices = i915->index_buffer.user_buffer; if (!mapped_indices) mapped_indices = i915_buffer(i915->index_buffer.buffer)->data; draw_set_indexes(draw, (ubyte *) mapped_indices + i915->index_buffer.offset, i915->index_buffer.index_size); } if (i915->constants[PIPE_SHADER_VERTEX]) draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0, i915_buffer(i915->constants[PIPE_SHADER_VERTEX])->data, (i915->current.num_user_constants[PIPE_SHADER_VERTEX] * 4 * sizeof(float))); else draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0, NULL, 0); if (i915->num_vertex_sampler_views > 0) i915_prepare_vertex_sampling(i915); /* * Do the drawing */ draw_vbo(i915->draw, info); if (mapped_indices) draw_set_indexes(draw, NULL, 0); if (i915->num_vertex_sampler_views > 0) i915_cleanup_vertex_sampling(i915); /* * Instead of flushing on every state change, we flush once here * when we fire the vbo. */ draw_flush(i915->draw); }
static void llvmpipe_set_sampler_views(struct pipe_context *pipe, unsigned shader, unsigned start, unsigned num, struct pipe_sampler_view **views) { struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); uint i; assert(num <= PIPE_MAX_SHADER_SAMPLER_VIEWS); assert(shader < PIPE_SHADER_TYPES); assert(start + num <= Elements(llvmpipe->sampler_views[shader])); draw_flush(llvmpipe->draw); /* set the new sampler views */ for (i = 0; i < num; i++) { /* Note: we're using pipe_sampler_view_release() here to work around * a possible crash when the old view belongs to another context that * was already destroyed. */ pipe_sampler_view_release(pipe, &llvmpipe->sampler_views[shader][start + i]); /* * Warn if someone tries to set a view created in a different context * (which is why we need the hack above in the first place). * An assert would be better but st/mesa relies on it... */ if (views[i] && views[i]->context != pipe) { debug_printf("Illegal setting of sampler_view %d created in another " "context\n", i); } pipe_sampler_view_reference(&llvmpipe->sampler_views[shader][start + i], views[i]); } /* find highest non-null sampler_views[] entry */ { unsigned j = MAX2(llvmpipe->num_sampler_views[shader], start + num); while (j > 0 && llvmpipe->sampler_views[shader][j - 1] == NULL) j--; llvmpipe->num_sampler_views[shader] = j; } if (shader == PIPE_SHADER_VERTEX || shader == PIPE_SHADER_GEOMETRY) { draw_set_sampler_views(llvmpipe->draw, shader, llvmpipe->sampler_views[shader], llvmpipe->num_sampler_views[shader]); } else { llvmpipe->dirty |= LP_NEW_SAMPLER_VIEW; } }
static void i915_set_blend_color( struct pipe_context *pipe, const struct pipe_blend_color *blend_color ) { struct i915_context *i915 = i915_context(pipe); draw_flush(i915->draw); i915->blend_color = *blend_color; i915->dirty |= I915_NEW_BLEND; }
static void nv20_flush(struct pipe_context *pipe, unsigned flags, struct pipe_fence_handle **fence) { struct nv20_context *nv20 = nv20_context(pipe); draw_flush(nv20->draw); FIRE_RING(fence); }
static void cell_bind_blend_state(struct pipe_context *pipe, void *blend) { struct cell_context *cell = cell_context(pipe); draw_flush(cell->draw); cell->blend = (struct pipe_blend_state *) blend; cell->dirty |= CELL_NEW_BLEND; }
static void i915_fixup_bind_fs_state(struct pipe_context *pipe, void *shader) { struct i915_context *i915 = i915_context(pipe); draw_flush(i915->draw); i915->saved_fs = shader; i915->saved_bind_fs_state(pipe, shader); }
static void i915_set_stencil_ref( struct pipe_context *pipe, const struct pipe_stencil_ref *stencil_ref ) { struct i915_context *i915 = i915_context(pipe); draw_flush(i915->draw); i915->stencil_ref = *stencil_ref; i915->dirty |= I915_NEW_DEPTH_STENCIL; }
static void i915_set_clip_state( struct pipe_context *pipe, const struct pipe_clip_state *clip ) { struct i915_context *i915 = i915_context(pipe); draw_flush(i915->draw); draw_set_clip_state(i915->draw, clip); i915->dirty |= I915_NEW_CLIP; }
static void i915_set_framebuffer_state(struct pipe_context *pipe, const struct pipe_framebuffer_state *fb) { struct i915_context *i915 = i915_context(pipe); draw_flush(i915->draw); i915->framebuffer = *fb; /* struct copy */ i915->dirty |= I915_NEW_FRAMEBUFFER; }
void softpipe_set_polygon_stipple( struct pipe_context *pipe, const struct pipe_poly_stipple *stipple ) { struct softpipe_context *softpipe = softpipe_context(pipe); draw_flush(softpipe->draw); softpipe->poly_stipple = *stipple; /* struct copy */ softpipe->dirty |= SP_NEW_STIPPLE; }
static void i915_bind_fs_state(struct pipe_context *pipe, void *shader) { struct i915_context *i915 = i915_context(pipe); draw_flush(i915->draw); i915->fs = (struct i915_fragment_shader*) shader; i915->dirty |= I915_NEW_FS; }
static void i915_bind_depth_stencil_state(struct pipe_context *pipe, void *depth_stencil) { struct i915_context *i915 = i915_context(pipe); draw_flush(i915->draw); i915->depth_stencil = (const struct i915_depth_stencil_state *)depth_stencil; i915->dirty |= I915_NEW_DEPTH_STENCIL; }
static void i915_bind_blend_state(struct pipe_context *pipe, void *blend) { struct i915_context *i915 = i915_context(pipe); draw_flush(i915->draw); i915->blend = (struct i915_blend_state*)blend; i915->dirty |= I915_NEW_BLEND; }
void softpipe_set_scissor_state( struct pipe_context *pipe, const struct pipe_scissor_state *scissor ) { struct softpipe_context *softpipe = softpipe_context(pipe); draw_flush(softpipe->draw); softpipe->scissor = *scissor; /* struct copy */ softpipe->dirty |= SP_NEW_SCISSOR; }