Esempio n. 1
0
static void
update_tgsi_samplers( struct softpipe_context *softpipe )
{
   unsigned i, sh;

   set_shader_sampler(softpipe, PIPE_SHADER_VERTEX,
                      softpipe->vs->max_sampler);
   set_shader_sampler(softpipe, PIPE_SHADER_FRAGMENT,
                      softpipe->fs_variant->info.file_max[TGSI_FILE_SAMPLER]);
   if (softpipe->gs) {
      set_shader_sampler(softpipe, PIPE_SHADER_GEOMETRY,
                         softpipe->gs->max_sampler);
   }

   /* XXX is this really necessary here??? */
   for (sh = 0; sh < ARRAY_SIZE(softpipe->tex_cache); sh++) {
      for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
         struct softpipe_tex_tile_cache *tc = softpipe->tex_cache[sh][i];
         if (tc && tc->texture) {
            struct softpipe_resource *spt = softpipe_resource(tc->texture);
            if (spt->timestamp != tc->timestamp) {
               sp_tex_tile_cache_validate_texture( tc );
               /*
                 _debug_printf("INV %d %d\n", tc->timestamp, spt->timestamp);
               */
               tc->timestamp = spt->timestamp;
            }
         }
      }
   }
}
Esempio n. 2
0
static void
gdi_present(struct pipe_screen *screen,
            struct pipe_resource *res,
            HDC hDC)
{
   /* This will fail if any interposing layer (trace, debug, etc) has
    * been introduced between the state-trackers and the pipe driver.
    *
    * Ideally this would get replaced with a call to
    * pipe_screen::flush_frontbuffer().
    *
    * Failing that, it may be necessary for intervening layers to wrap
    * other structs such as this stw_winsys as well...
    */

   struct sw_winsys *winsys = NULL;
   struct sw_displaytarget *dt = NULL;

#ifdef HAVE_LLVMPIPE
   if (use_llvmpipe) {
      winsys = llvmpipe_screen(screen)->winsys;
      dt = llvmpipe_resource(res)->dt;
      gdi_sw_display(winsys, dt, hDC);
      return;
   }
#endif

   winsys = softpipe_screen(screen)->winsys,
   dt = softpipe_resource(res)->dt,
   gdi_sw_display(winsys, dt, hDC);
}
Esempio n. 3
0
static void
update_tgsi_samplers( struct softpipe_context *softpipe )
{
   unsigned i;

   softpipe_reset_sampler_variants( softpipe );

   for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
      struct softpipe_tex_tile_cache *tc = softpipe->fragment_tex_cache[i];
      if (tc && tc->texture) {
         struct softpipe_resource *spt = softpipe_resource(tc->texture);
         if (spt->timestamp != tc->timestamp) {
	    sp_tex_tile_cache_validate_texture( tc );
            /*
            _debug_printf("INV %d %d\n", tc->timestamp, spt->timestamp);
            */
            tc->timestamp = spt->timestamp;
         }
      }
   }

   for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
      struct softpipe_tex_tile_cache *tc = softpipe->vertex_tex_cache[i];

      if (tc && tc->texture) {
         struct softpipe_resource *spt = softpipe_resource(tc->texture);

         if (spt->timestamp != tc->timestamp) {
	    sp_tex_tile_cache_validate_texture(tc);
            tc->timestamp = spt->timestamp;
         }
      }
   }

   for (i = 0; i < PIPE_MAX_GEOMETRY_SAMPLERS; i++) {
      struct softpipe_tex_tile_cache *tc = softpipe->geometry_tex_cache[i];

      if (tc && tc->texture) {
         struct softpipe_resource *spt = softpipe_resource(tc->texture);

         if (spt->timestamp != tc->timestamp) {
	    sp_tex_tile_cache_validate_texture(tc);
            tc->timestamp = spt->timestamp;
         }
      }
   }
}
Esempio n. 4
0
/* This is often overriden by the co-state tracker.
 */
static void
softpipe_flush_frontbuffer(struct pipe_screen *_screen,
                           struct pipe_resource *resource,
                           unsigned level, unsigned layer,
                           void *context_private)
{
   struct softpipe_screen *screen = softpipe_screen(_screen);
   struct sw_winsys *winsys = screen->winsys;
   struct softpipe_resource *texture = softpipe_resource(resource);

   assert(texture->dt);
   if (texture->dt)
      winsys->displaytarget_display(winsys, texture->dt, context_private);
}
Esempio n. 5
0
static boolean
softpipe_resource_get_handle(struct pipe_screen *screen,
                             struct pipe_resource *pt,
                             struct winsys_handle *whandle)
{
   struct sw_winsys *winsys = softpipe_screen(screen)->winsys;
   struct softpipe_resource *spr = softpipe_resource(pt);

   assert(spr->dt);
   if (!spr->dt)
      return FALSE;

   return winsys->displaytarget_get_handle(winsys, spr->dt, whandle);
}
static void
gdi_softpipe_present(struct pipe_screen *screen,
                     struct pipe_surface *surface,
                     HDC hDC)
{
   /* This will fail if any interposing layer (trace, debug, etc) has
    * been introduced between the state-trackers and softpipe.
    *
    * Ideally this would get replaced with a call to
    * pipe_screen::flush_frontbuffer().
    *
    * Failing that, it may be necessary for intervening layers to wrap
    * other structs such as this stw_winsys as well...
    */
   gdi_sw_display(softpipe_screen(screen)->winsys,
                  softpipe_resource(surface->texture)->dt,
                  hDC);
}
Esempio n. 7
0
static void
softpipe_resource_destroy(struct pipe_screen *pscreen,
			  struct pipe_resource *pt)
{
   struct softpipe_screen *screen = softpipe_screen(pscreen);
   struct softpipe_resource *spr = softpipe_resource(pt);

   if (spr->dt) {
      /* display target */
      struct sw_winsys *winsys = screen->winsys;
      winsys->displaytarget_destroy(winsys, spr->dt);
   }
   else if (!spr->userBuffer) {
      /* regular texture */
      align_free(spr->data);
   }

   FREE(spr);
}
Esempio n. 8
0
/**
 * Find/create an sp_sampler_variant object for sampling the given texture,
 * sampler and tex unit.
 *
 * Note that the tex unit is significant.  We can't re-use a sampler
 * variant for multiple texture units because the sampler variant contains
 * the texture object pointer.  If the texture object pointer were stored
 * somewhere outside the sampler variant, we could re-use samplers for
 * multiple texture units.
 */
static struct sp_sampler_variant *
get_sampler_variant( unsigned unit,
                     struct sp_sampler *sampler,
                     struct pipe_sampler_view *view,
                     unsigned processor )
{
    struct softpipe_resource *sp_texture = softpipe_resource(view->texture);
    struct sp_sampler_variant *v = NULL;
    union sp_sampler_key key;

    /* if this fails, widen the key.unit field and update this assertion */
    assert(PIPE_MAX_SAMPLERS <= 16);

    key.bits.target = sp_texture->base.target;
    key.bits.is_pot = sp_texture->pot;
    key.bits.processor = processor;
    key.bits.unit = unit;
    key.bits.swizzle_r = view->swizzle_r;
    key.bits.swizzle_g = view->swizzle_g;
    key.bits.swizzle_b = view->swizzle_b;
    key.bits.swizzle_a = view->swizzle_a;
    key.bits.pad = 0;

    if (sampler->current &&
            key.value == sampler->current->key.value) {
        v = sampler->current;
    }

    if (v == NULL) {
        for (v = sampler->variants; v; v = v->next)
            if (v->key.value == key.value)
                break;

        if (v == NULL) {
            v = sp_create_sampler_variant( &sampler->base, key );
            v->next = sampler->variants;
            sampler->variants = v;
        }
    }

    sampler->current = v;
    return v;
}
Esempio n. 9
0
/**
 * Unmap memory mapping for given pipe_transfer object.
 */
static void
softpipe_transfer_unmap(struct pipe_context *pipe,
                        struct pipe_transfer *transfer)
{
   struct softpipe_resource *spr;

   assert(transfer->resource);
   spr = softpipe_resource(transfer->resource);

   if (spr->dt) {
      /* display target */
      struct sw_winsys *winsys = softpipe_screen(pipe->screen)->winsys;
      winsys->displaytarget_unmap(winsys, spr->dt);
   }

   if (transfer->usage & PIPE_TRANSFER_WRITE) {
      /* Mark the texture as dirty to expire the tile caches. */
      spr->timestamp++;
   }
}
Esempio n. 10
0
/**
 * Create memory mapping for given pipe_transfer object.
 */
static void *
softpipe_transfer_map(struct pipe_context *pipe,
                      struct pipe_transfer *transfer)
{
   struct softpipe_transfer *spt = softpipe_transfer(transfer);
   struct softpipe_resource *spr = softpipe_resource(transfer->resource);
   struct sw_winsys *winsys = softpipe_screen(pipe->screen)->winsys;
   uint8_t *map;
   
   /* resources backed by display target treated specially:
    */
   if (spr->dt) {
      map = winsys->displaytarget_map(winsys, spr->dt, transfer->usage);
   }
   else {
      map = spr->data;
   }

   if (map == NULL)
      return NULL;
   else
      return map + spt->offset;
}
Esempio n. 11
0
static void
update_tgsi_samplers( struct softpipe_context *softpipe )
{
    unsigned i, sh;

    softpipe_reset_sampler_variants( softpipe );

    for (sh = 0; sh < Elements(softpipe->tex_cache); sh++) {
        for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
            struct softpipe_tex_tile_cache *tc = softpipe->tex_cache[sh][i];
            if (tc && tc->texture) {
                struct softpipe_resource *spt = softpipe_resource(tc->texture);
                if (spt->timestamp != tc->timestamp) {
                    sp_tex_tile_cache_validate_texture( tc );
                    /*
                      _debug_printf("INV %d %d\n", tc->timestamp, spt->timestamp);
                    */
                    tc->timestamp = spt->timestamp;
                }
            }
        }
    }
}
Esempio n. 12
0
/**
 * Geta pipe_transfer object which is used for moving data in/out of
 * a resource object.
 * \param pipe  rendering context
 * \param resource  the resource to transfer in/out of
 * \param level  which mipmap level
 * \param usage  bitmask of PIPE_TRANSFER_x flags
 * \param box  the 1D/2D/3D region of interest
 */
static struct pipe_transfer *
softpipe_get_transfer(struct pipe_context *pipe,
                      struct pipe_resource *resource,
                      unsigned level,
                      unsigned usage,
                      const struct pipe_box *box)
{
   struct softpipe_resource *spr = softpipe_resource(resource);
   struct softpipe_transfer *spt;

   assert(resource);
   assert(level <= resource->last_level);

   /* make sure the requested region is in the image bounds */
   assert(box->x + box->width <= u_minify(resource->width0, level));
   if (resource->target == PIPE_TEXTURE_1D_ARRAY) {
      assert(box->y + box->height <= resource->array_size);
   }
   else {
      assert(box->y + box->height <= u_minify(resource->height0, level));
      if (resource->target == PIPE_TEXTURE_2D_ARRAY) {
         assert(box->z + box->depth <= resource->array_size);
      }
      else if (resource->target == PIPE_TEXTURE_CUBE) {
         assert(box->z < 6);
      }
      else {
         assert(box->z + box->depth <= (u_minify(resource->depth0, level)));
      }
   }

   /*
    * Transfers, like other pipe operations, must happen in order, so flush the
    * context if necessary.
    */
   if (!(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) {
      boolean read_only = !(usage & PIPE_TRANSFER_WRITE);
      boolean do_not_block = !!(usage & PIPE_TRANSFER_DONTBLOCK);
      if (!softpipe_flush_resource(pipe, resource,
                                   level, box->depth > 1 ? -1 : box->z,
                                   0, /* flush_flags */
                                   read_only,
                                   TRUE, /* cpu_access */
                                   do_not_block)) {
         /*
          * It would have blocked, but state tracker requested no to.
          */
         assert(do_not_block);
         return NULL;
      }
   }

   spt = CALLOC_STRUCT(softpipe_transfer);
   if (spt) {
      struct pipe_transfer *pt = &spt->base;
      enum pipe_format format = resource->format;
      const unsigned hgt = u_minify(spr->base.height0, level);
      const unsigned nblocksy = util_format_get_nblocksy(format, hgt);

      pipe_resource_reference(&pt->resource, resource);
      pt->level = level;
      pt->usage = usage;
      pt->box = *box;
      pt->stride = spr->stride[level];
      pt->layer_stride = pt->stride * nblocksy;

      spt->offset = sp_get_tex_image_offset(spr, level, box->z);
 
      spt->offset += 
         box->y / util_format_get_blockheight(format) * spt->base.stride +
         box->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);

      return pt;
   }
   return NULL;
}
Esempio n. 13
0
/**
 * Geta pipe_transfer object which is used for moving data in/out of
 * a resource object.
 * \param pipe  rendering context
 * \param resource  the resource to transfer in/out of
 * \param level  which mipmap level
 * \param usage  bitmask of PIPE_TRANSFER_x flags
 * \param box  the 1D/2D/3D region of interest
 */
static void *
softpipe_transfer_map(struct pipe_context *pipe,
                      struct pipe_resource *resource,
                      unsigned level,
                      unsigned usage,
                      const struct pipe_box *box,
                      struct pipe_transfer **transfer)
{
   struct sw_winsys *winsys = softpipe_screen(pipe->screen)->winsys;
   struct softpipe_resource *spr = softpipe_resource(resource);
   struct softpipe_transfer *spt;
   struct pipe_transfer *pt;
   enum pipe_format format = resource->format;
   uint8_t *map;

   assert(resource);
   assert(level <= resource->last_level);

   /* make sure the requested region is in the image bounds */
   assert(box->x + box->width <= (int) u_minify(resource->width0, level));
   if (resource->target == PIPE_TEXTURE_1D_ARRAY) {
      assert(box->y + box->height <= (int) resource->array_size);
   }
   else {
      assert(box->y + box->height <= (int) u_minify(resource->height0, level));
      if (resource->target == PIPE_TEXTURE_2D_ARRAY) {
         assert(box->z + box->depth <= (int) resource->array_size);
      }
      else if (resource->target == PIPE_TEXTURE_CUBE) {
         assert(box->z < 6);
      }
      else if (resource->target == PIPE_TEXTURE_CUBE_ARRAY) {
         assert(box->z <= (int) resource->array_size);
      }
      else {
         assert(box->z + box->depth <= (int) u_minify(resource->depth0, level));
      }
   }

   /*
    * Transfers, like other pipe operations, must happen in order, so flush the
    * context if necessary.
    */
   if (!(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) {
      boolean read_only = !(usage & PIPE_TRANSFER_WRITE);
      boolean do_not_block = !!(usage & PIPE_TRANSFER_DONTBLOCK);
      if (!softpipe_flush_resource(pipe, resource,
                                   level, box->depth > 1 ? -1 : box->z,
                                   0, /* flush_flags */
                                   read_only,
                                   TRUE, /* cpu_access */
                                   do_not_block)) {
         /*
          * It would have blocked, but state tracker requested no to.
          */
         assert(do_not_block);
         return NULL;
      }
   }

   spt = CALLOC_STRUCT(softpipe_transfer);
   if (!spt)
      return NULL;

   pt = &spt->base;

   pipe_resource_reference(&pt->resource, resource);
   pt->level = level;
   pt->usage = usage;
   pt->box = *box;
   pt->stride = spr->stride[level];
   pt->layer_stride = spr->img_stride[level];

   spt->offset = softpipe_get_tex_image_offset(spr, level, box->z);

   spt->offset +=
         box->y / util_format_get_blockheight(format) * spt->base.stride +
         box->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);

   /* resources backed by display target treated specially:
    */
   if (spr->dt) {
      map = winsys->displaytarget_map(winsys, spr->dt, usage);
   }
   else {
      map = spr->data;
   }

   if (!map) {
      pipe_resource_reference(&pt->resource, NULL);
      FREE(spt);
      return NULL;
   }

   *transfer = pt;
   return map + spt->offset;
}
Esempio n. 14
0
static void
prepare_shader_sampling(
   struct softpipe_context *sp,
   unsigned num,
   struct pipe_sampler_view **views,
   unsigned shader_type,
   struct pipe_resource *mapped_tex[PIPE_MAX_SHADER_SAMPLER_VIEWS])
{

   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 < PIPE_MAX_SHADER_SAMPLER_VIEWS; i++) {
      struct pipe_sampler_view *view = i < num ? views[i] : NULL;

      if (view) {
         struct pipe_resource *tex = view->texture;
         struct softpipe_resource *sp_tex = softpipe_resource(tex);
         unsigned width0 = tex->width0;
         unsigned num_layers = tex->depth0;
         unsigned first_level = 0;
         unsigned last_level = 0;

         /* We're referencing the texture's internal data, so save a
          * reference to it.
          */
         pipe_resource_reference(&mapped_tex[i], tex);

         if (!sp_tex->dt) {
            /* regular texture - setup array of mipmap level offsets */
            MAYBE_UNUSED struct pipe_resource *res = view->texture;
            int j;

            if (view->target != PIPE_BUFFER) {
               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 = sp_tex->data;

               for (j = first_level; j <= last_level; j++) {
                  mip_offsets[j] = sp_tex->level_offset[j];
                  row_stride[j] = sp_tex->stride[j];
                  img_stride[j] = sp_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 *
                                       sp_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 = sp_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 softpipe_screen *screen = softpipe_screen(tex->screen);
            struct sw_winsys *winsys = screen->winsys;
            addr = winsys->displaytarget_map(winsys, sp_tex->dt,
                                             PIPE_TRANSFER_READ);
            row_stride[0] = sp_tex->stride[0];
            img_stride[0] = sp_tex->img_stride[0];
            mip_offsets[0] = 0;
            assert(addr);
         }
         draw_set_mapped_texture(sp->draw,
                                 shader_type,
                                 i,
                                 width0, tex->height0, num_layers,
                                 first_level, last_level,
                                 addr,
                                 row_stride, img_stride, mip_offsets);
      }
   }
}