/**
 * 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);
      }
   }
}
示例#2
0
/**
 * 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);
      }
   }
}