static void update_fragment_shader(struct softpipe_context *softpipe, unsigned prim) { struct sp_fragment_shader_variant_key key; memset(&key, 0, sizeof(key)); if (prim == PIPE_PRIM_TRIANGLES) key.polygon_stipple = softpipe->rasterizer->poly_stipple_enable; if (softpipe->fs) { softpipe->fs_variant = softpipe_find_fs_variant(softpipe, softpipe->fs, &key); /* prepare the TGSI interpreter for FS execution */ softpipe->fs_variant->prepare(softpipe->fs_variant, softpipe->fs_machine, (struct tgsi_sampler *) softpipe-> tgsi.sampler[PIPE_SHADER_FRAGMENT], (struct tgsi_image *)softpipe->tgsi.image[PIPE_SHADER_FRAGMENT], (struct tgsi_buffer *)softpipe->tgsi.buffer[PIPE_SHADER_FRAGMENT]); } else { softpipe->fs_variant = NULL; } /* This would be the logical place to pass the fragment shader * to the draw module. However, doing this here, during state * validation, causes problems with the 'draw' module helpers for * wide/AA/stippled lines. * In principle, the draw's fragment shader should be per-variant * but that doesn't work. So we use a single draw fragment shader * per fragment shader, not per variant. */ #if 0 if (softpipe->fs_variant) { draw_bind_fragment_shader(softpipe->draw, softpipe->fs_variant->draw_shader); } else { draw_bind_fragment_shader(softpipe->draw, NULL); } #endif }
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; draw_bind_fragment_shader(i915->draw, (i915->fs ? i915->fs->draw_data : NULL)); i915->dirty |= I915_NEW_FS; }
static enum pipe_error update_swtnl_draw( struct svga_context *svga, unsigned dirty ) { draw_flush( svga->swtnl.draw ); if (dirty & SVGA_NEW_VS) draw_bind_vertex_shader(svga->swtnl.draw, svga->curr.vs->draw_shader); if (dirty & SVGA_NEW_FS) draw_bind_fragment_shader(svga->swtnl.draw, svga->curr.fs->draw_shader); if (dirty & SVGA_NEW_VBUFFER) draw_set_vertex_buffers(svga->swtnl.draw, 0, svga->curr.num_vertex_buffers, svga->curr.vb); if (dirty & SVGA_NEW_VELEMENT) draw_set_vertex_elements(svga->swtnl.draw, svga->curr.velems->count, svga->curr.velems->velem ); if (dirty & SVGA_NEW_CLIP) draw_set_clip_state(svga->swtnl.draw, &svga->curr.clip); if (dirty & (SVGA_NEW_VIEWPORT | SVGA_NEW_REDUCED_PRIMITIVE | SVGA_NEW_RAST)) set_draw_viewport( svga ); if (dirty & SVGA_NEW_RAST) draw_set_rasterizer_state(svga->swtnl.draw, &svga->curr.rast->templ, (void *) svga->curr.rast); /* Tell the draw module how deep the Z/depth buffer is. * * If no depth buffer is bound, send the utility function the * format for no bound depth (PIPE_FORMAT_NONE). */ if (dirty & SVGA_NEW_FRAME_BUFFER) draw_set_zs_format(svga->swtnl.draw, (svga->curr.framebuffer.zsbuf) ? svga->curr.framebuffer.zsbuf->format : PIPE_FORMAT_NONE); return PIPE_OK; }
static enum pipe_error update_swtnl_draw( struct svga_context *svga, unsigned dirty ) { draw_flush( svga->swtnl.draw ); if (dirty & SVGA_NEW_VS) draw_bind_vertex_shader(svga->swtnl.draw, svga->curr.vs->draw_shader); if (dirty & SVGA_NEW_FS) draw_bind_fragment_shader(svga->swtnl.draw, svga->curr.fs->draw_shader); if (dirty & SVGA_NEW_VBUFFER) draw_set_vertex_buffers(svga->swtnl.draw, 0, svga->curr.num_vertex_buffers, svga->curr.vb); if (dirty & SVGA_NEW_VELEMENT) draw_set_vertex_elements(svga->swtnl.draw, svga->curr.velems->count, svga->curr.velems->velem ); if (dirty & SVGA_NEW_CLIP) draw_set_clip_state(svga->swtnl.draw, &svga->curr.clip); if (dirty & (SVGA_NEW_VIEWPORT | SVGA_NEW_REDUCED_PRIMITIVE | SVGA_NEW_RAST)) set_draw_viewport( svga ); if (dirty & SVGA_NEW_RAST) draw_set_rasterizer_state(svga->swtnl.draw, &svga->curr.rast->templ, (void *) svga->curr.rast); if (dirty & SVGA_NEW_FRAME_BUFFER) draw_set_mrd(svga->swtnl.draw, svga->curr.depthscale); return 0; }
void nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) { struct nv30_context *nv30 = nv30_context(pipe); struct draw_context *draw = nv30->draw; struct pipe_transfer *transfer[PIPE_MAX_ATTRIBS] = {NULL}; struct pipe_transfer *transferi = NULL; int i; nv30_render_validate(nv30); if (nv30->draw_dirty & NV30_NEW_VIEWPORT) draw_set_viewport_states(draw, 0, 1, &nv30->viewport); if (nv30->draw_dirty & NV30_NEW_RASTERIZER) draw_set_rasterizer_state(draw, &nv30->rast->pipe, NULL); if (nv30->draw_dirty & NV30_NEW_CLIP) draw_set_clip_state(draw, &nv30->clip); if (nv30->draw_dirty & NV30_NEW_ARRAYS) { draw_set_vertex_buffers(draw, 0, nv30->num_vtxbufs, nv30->vtxbuf); draw_set_vertex_elements(draw, nv30->vertex->num_elements, nv30->vertex->pipe); } if (nv30->draw_dirty & NV30_NEW_FRAGPROG) { struct nv30_fragprog *fp = nv30->fragprog.program; if (!fp->draw) fp->draw = draw_create_fragment_shader(draw, &fp->pipe); draw_bind_fragment_shader(draw, fp->draw); } if (nv30->draw_dirty & NV30_NEW_VERTPROG) { struct nv30_vertprog *vp = nv30->vertprog.program; if (!vp->draw) vp->draw = draw_create_vertex_shader(draw, &vp->pipe); draw_bind_vertex_shader(draw, vp->draw); } if (nv30->draw_dirty & NV30_NEW_VERTCONST) { if (nv30->vertprog.constbuf) { void *map = nv04_resource(nv30->vertprog.constbuf)->data; draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0, map, nv30->vertprog.constbuf_nr * 16); } else { draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0, NULL, 0); } } for (i = 0; i < nv30->num_vtxbufs; i++) { const void *map = nv30->vtxbuf[i].user_buffer; if (!map) { if (nv30->vtxbuf[i].buffer) map = pipe_buffer_map(pipe, nv30->vtxbuf[i].buffer, PIPE_TRANSFER_UNSYNCHRONIZED | PIPE_TRANSFER_READ, &transfer[i]); } draw_set_mapped_vertex_buffer(draw, i, map, ~0); } if (info->indexed) { const void *map = nv30->idxbuf.user_buffer; if (!map) map = pipe_buffer_map(pipe, nv30->idxbuf.buffer, PIPE_TRANSFER_UNSYNCHRONIZED | PIPE_TRANSFER_READ, &transferi); draw_set_indexes(draw, (ubyte *) map + nv30->idxbuf.offset, nv30->idxbuf.index_size, ~0); } else { draw_set_indexes(draw, NULL, 0, 0); } draw_vbo(draw, info); draw_flush(draw); if (info->indexed && transferi) pipe_buffer_unmap(pipe, transferi); for (i = 0; i < nv30->num_vtxbufs; i++) if (transfer[i]) pipe_buffer_unmap(pipe, transfer[i]); nv30->draw_dirty = 0; nv30_state_release(nv30); }