/** * Called during state validation when LP_NEW_SAMPLER_VIEW is set. */ void llvmpipe_prepare_vertex_sampling(struct llvmpipe_context *lp, unsigned num, struct pipe_sampler_view **views) { unsigned i; uint32_t row_stride[DRAW_MAX_TEXTURE_LEVELS]; uint32_t img_stride[DRAW_MAX_TEXTURE_LEVELS]; const void *data[DRAW_MAX_TEXTURE_LEVELS]; assert(num <= PIPE_MAX_VERTEX_SAMPLERS); if (!num) return; for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { struct pipe_sampler_view *view = i < num ? views[i] : NULL; if (view) { struct pipe_resource *tex = view->texture; struct llvmpipe_resource *lp_tex = llvmpipe_resource(tex); /* We're referencing the texture's internal data, so save a * reference to it. */ pipe_resource_reference(&lp->mapped_vs_tex[i], tex); if (!lp_tex->dt) { /* regular texture - setup array of mipmap level pointers */ int j; for (j = 0; j <= tex->last_level; j++) { data[j] = llvmpipe_get_texture_image_all(lp_tex, j, LP_TEX_USAGE_READ, LP_TEX_LAYOUT_LINEAR); row_stride[j] = lp_tex->row_stride[j]; img_stride[j] = lp_tex->img_stride[j]; } } else { /* display target texture/surface */ /* * XXX: Where should this be unmapped? */ struct llvmpipe_screen *screen = llvmpipe_screen(tex->screen); struct sw_winsys *winsys = screen->winsys; data[0] = winsys->displaytarget_map(winsys, lp_tex->dt, PIPE_TRANSFER_READ); row_stride[0] = lp_tex->row_stride[0]; img_stride[0] = lp_tex->img_stride[0]; assert(data[0]); } draw_set_mapped_texture(lp->draw, i, tex->width0, tex->height0, tex->depth0, tex->last_level, row_stride, img_stride, data); } } }
/** * Called before drawing VBO to map vertex samplers and hand them to draw */ void i915_prepare_vertex_sampling(struct i915_context *i915) { struct i915_winsys *iws = i915->iws; unsigned i,j; uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS]; uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS]; uint32_t mip_offsets[PIPE_MAX_TEXTURE_LEVELS]; unsigned num = i915->num_vertex_sampler_views; struct pipe_sampler_view **views = i915->vertex_sampler_views; assert(num <= PIPE_MAX_SAMPLERS); if (!num) return; for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { struct pipe_sampler_view *view = i < num ? views[i] : NULL; if (view) { struct pipe_resource *tex = view->texture; struct i915_texture *i915_tex = i915_texture(tex); ubyte *addr; /* We're referencing the texture's internal data, so save a * reference to it. */ pipe_resource_reference(&i915->mapped_vs_tex[i], tex); i915->mapped_vs_tex_buffer[i] = i915_tex->buffer; addr = iws->buffer_map(iws, i915_tex->buffer, FALSE /* read only */); /* Setup array of mipmap level pointers */ /* FIXME: handle 3D textures? */ for (j = view->u.tex.first_level; j <= tex->last_level; j++) { mip_offsets[j] = i915_texture_offset(i915_tex, j , 0 /* FIXME depth */); row_stride[j] = i915_tex->stride; img_stride[j] = 0; /* FIXME */; } draw_set_mapped_texture(i915->draw, PIPE_SHADER_VERTEX, i, tex->width0, tex->height0, tex->depth0, view->u.tex.first_level, tex->last_level, addr, row_stride, img_stride, mip_offsets); } else i915->mapped_vs_tex[i] = NULL; } }
static void prepare_shader_sampling( struct llvmpipe_context *lp, unsigned num, struct pipe_sampler_view **views, unsigned shader_type) { unsigned i; uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS]; uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS]; uint32_t mip_offsets[PIPE_MAX_TEXTURE_LEVELS]; const void *addr; assert(num <= PIPE_MAX_SHADER_SAMPLER_VIEWS); if (!num) return; for (i = 0; i < num; i++) { struct pipe_sampler_view *view = i < num ? views[i] : NULL; if (view) { struct pipe_resource *tex = view->texture; struct llvmpipe_resource *lp_tex = llvmpipe_resource(tex); unsigned width0 = tex->width0; unsigned num_layers = tex->depth0; unsigned first_level = 0; unsigned last_level = 0; if (!lp_tex->dt) { /* regular texture - setup array of mipmap level offsets */ struct pipe_resource *res = view->texture; int j; if (llvmpipe_resource_is_texture(res)) { first_level = view->u.tex.first_level; last_level = view->u.tex.last_level; assert(first_level <= last_level); assert(last_level <= res->last_level); addr = lp_tex->tex_data; for (j = first_level; j <= last_level; j++) { mip_offsets[j] = lp_tex->mip_offsets[j]; row_stride[j] = lp_tex->row_stride[j]; img_stride[j] = lp_tex->img_stride[j]; } if (tex->target == PIPE_TEXTURE_1D_ARRAY || tex->target == PIPE_TEXTURE_2D_ARRAY || tex->target == PIPE_TEXTURE_CUBE || tex->target == PIPE_TEXTURE_CUBE_ARRAY) { num_layers = view->u.tex.last_layer - view->u.tex.first_layer + 1; for (j = first_level; j <= last_level; j++) { mip_offsets[j] += view->u.tex.first_layer * lp_tex->img_stride[j]; } if (view->target == PIPE_TEXTURE_CUBE || view->target == PIPE_TEXTURE_CUBE_ARRAY) { assert(num_layers % 6 == 0); } assert(view->u.tex.first_layer <= view->u.tex.last_layer); assert(view->u.tex.last_layer < res->array_size); } } else { unsigned view_blocksize = util_format_get_blocksize(view->format); addr = lp_tex->data; /* probably don't really need to fill that out */ mip_offsets[0] = 0; row_stride[0] = 0; img_stride[0] = 0; /* everything specified in number of elements here. */ width0 = view->u.buf.last_element - view->u.buf.first_element + 1; addr = (uint8_t *)addr + view->u.buf.first_element * view_blocksize; assert(view->u.buf.first_element <= view->u.buf.last_element); assert(view->u.buf.last_element * view_blocksize < res->width0); } } else { /* display target texture/surface */ /* * XXX: Where should this be unmapped? */ struct llvmpipe_screen *screen = llvmpipe_screen(tex->screen); struct sw_winsys *winsys = screen->winsys; addr = winsys->displaytarget_map(winsys, lp_tex->dt, PIPE_TRANSFER_READ); row_stride[0] = lp_tex->row_stride[0]; img_stride[0] = lp_tex->img_stride[0]; mip_offsets[0] = 0; assert(addr); } draw_set_mapped_texture(lp->draw, shader_type, i, width0, tex->height0, num_layers, first_level, last_level, addr, row_stride, img_stride, mip_offsets); } } }