static INLINE void
nv50_stage_set_sampler_views(struct nv50_context *nv50, int s,
                             unsigned nr,
                             struct pipe_sampler_view **views)
{
   unsigned i;

   assert(nr <= PIPE_MAX_SAMPLERS);
   for (i = 0; i < nr; ++i) {
      struct nv50_tic_entry *old = nv50_tic_entry(nv50->textures[s][i]);
      if (old)
         nv50_screen_tic_unlock(nv50->screen, old);

      pipe_sampler_view_reference(&nv50->textures[s][i], views[i]);
   }

   assert(nv50->num_textures[s] <= PIPE_MAX_SAMPLERS);
   for (i = nr; i < nv50->num_textures[s]; ++i) {
      struct nv50_tic_entry *old = nv50_tic_entry(nv50->textures[s][i]);
      if (!old)
         continue;
      nv50_screen_tic_unlock(nv50->screen, old);

      pipe_sampler_view_reference(&nv50->textures[s][i], NULL);
   }

   nv50->num_textures[s] = nr;

   nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_TEXTURES);

   nv50->dirty |= NV50_NEW_TEXTURES;
}
예제 #2
0
파일: nvc0_state.c 프로젝트: Unr34ler/mesa
static void
nvc0_stage_set_sampler_views_range(struct nvc0_context *nvc0, const unsigned s,
                                   unsigned start, unsigned nr,
                                   struct pipe_sampler_view **views)
{
   struct nouveau_bufctx *bctx = (s == 5) ? nvc0->bufctx_cp : nvc0->bufctx_3d;
   const unsigned end = start + nr;
   const unsigned bin = (s == 5) ? NVC0_BIND_CP_TEX(0) : NVC0_BIND_3D_TEX(s, 0);
   int last_valid = -1;
   unsigned i;

   if (views) {
      for (i = start; i < end; ++i) {
         const unsigned p = i - start;
         if (views[p])
            last_valid = i;
         if (views[p] == nvc0->textures[s][i])
            continue;
         nvc0->textures_dirty[s] |= 1 << i;

         if (views[p] && views[p]->texture) {
            struct pipe_resource *res = views[p]->texture;
            if (res->target == PIPE_BUFFER &&
                (res->flags & PIPE_RESOURCE_FLAG_MAP_COHERENT))
               nvc0->textures_coherent[s] |= 1 << i;
            else
               nvc0->textures_coherent[s] &= ~(1 << i);
         } else {
            nvc0->textures_coherent[s] &= ~(1 << i);
         }

         if (nvc0->textures[s][i]) {
            struct nv50_tic_entry *old = nv50_tic_entry(nvc0->textures[s][i]);
            nouveau_bufctx_reset(bctx, bin + i);
            nvc0_screen_tic_unlock(nvc0->screen, old);
         }
         pipe_sampler_view_reference(&nvc0->textures[s][i], views[p]);
      }
   } else {
      for (i = start; i < end; ++i) {
         struct nv50_tic_entry *old = nv50_tic_entry(nvc0->textures[s][i]);
         if (!old)
            continue;
         nvc0->textures_dirty[s] |= 1 << i;

         nvc0_screen_tic_unlock(nvc0->screen, old);
         pipe_sampler_view_reference(&nvc0->textures[s][i], NULL);
         nouveau_bufctx_reset(bctx, bin + i);
      }
   }

   if (nvc0->num_textures[s] <= end) {
      if (last_valid < 0) {
         for (i = start; i && !nvc0->textures[s][i - 1]; --i);
         nvc0->num_textures[s] = i;
      } else {
         nvc0->num_textures[s] = last_valid + 1;
      }
   }
}
예제 #3
0
static inline void
nvc0_stage_set_sampler_views(struct nvc0_context *nvc0, int s,
                             unsigned nr,
                             struct pipe_sampler_view **views)
{
   unsigned i;

   for (i = 0; i < nr; ++i) {
      struct nv50_tic_entry *old = nv50_tic_entry(nvc0->textures[s][i]);

      if (views[i] == nvc0->textures[s][i])
         continue;
      nvc0->textures_dirty[s] |= 1 << i;

      if (old) {
         nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_TEX(s, i));
         nvc0_screen_tic_unlock(nvc0->screen, old);
      }

      pipe_sampler_view_reference(&nvc0->textures[s][i], views[i]);
   }

   for (i = nr; i < nvc0->num_textures[s]; ++i) {
      struct nv50_tic_entry *old = nv50_tic_entry(nvc0->textures[s][i]);
      if (old) {
         nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_TEX(s, i));
         nvc0_screen_tic_unlock(nvc0->screen, old);
         pipe_sampler_view_reference(&nvc0->textures[s][i], NULL);
      }
   }

   nvc0->num_textures[s] = nr;

   nvc0->dirty |= NVC0_NEW_TEXTURES;
}
예제 #4
0
파일: nvc0_state.c 프로젝트: nikai3d/mesa
static INLINE void
nvc0_stage_set_sampler_views(struct nvc0_context *nvc0, int s,
                             unsigned nr,
                             struct pipe_sampler_view **views)
{
   unsigned i;

   for (i = 0; i < nr; ++i) {
      struct nv50_tic_entry *old = nv50_tic_entry(nvc0->textures[s][i]);
      if (old)
         nvc0_screen_tic_unlock(nvc0->screen, old);

      pipe_sampler_view_reference(&nvc0->textures[s][i], views[i]);
   }

   for (i = nr; i < nvc0->num_textures[s]; ++i) {
      struct nv50_tic_entry *old = nv50_tic_entry(nvc0->textures[s][i]);
      if (!old)
         continue;
      nvc0_screen_tic_unlock(nvc0->screen, old);

      pipe_sampler_view_reference(&nvc0->textures[s][i], NULL);
   }

   nvc0->num_textures[s] = nr;

   nvc0_bufctx_reset(nvc0, NVC0_BUFCTX_TEXTURES);

   nvc0->dirty |= NVC0_NEW_TEXTURES;
}
/* NOTE: only called when not referenced anywhere, won't be bound */
static void
nv50_sampler_view_destroy(struct pipe_context *pipe,
                          struct pipe_sampler_view *view)
{
   pipe_resource_reference(&view->texture, NULL);

   nv50_screen_tic_free(nv50_context(pipe)->screen, nv50_tic_entry(view));

   FREE(nv50_tic_entry(view));
}
예제 #6
0
파일: nvc0_state.c 프로젝트: chemecse/mesa
static inline void
nvc0_stage_set_sampler_views(struct nvc0_context *nvc0, int s,
                             unsigned nr,
                             struct pipe_sampler_view **views)
{
   unsigned i;

   for (i = 0; i < nr; ++i) {
      struct nv50_tic_entry *old = nv50_tic_entry(nvc0->textures[s][i]);

      if (views[i] == nvc0->textures[s][i])
         continue;
      nvc0->textures_dirty[s] |= 1 << i;

      if (views[i] && views[i]->texture) {
         struct pipe_resource *res = views[i]->texture;
         if (res->target == PIPE_BUFFER &&
             (res->flags & PIPE_RESOURCE_FLAG_MAP_COHERENT))
            nvc0->textures_coherent[s] |= 1 << i;
         else
            nvc0->textures_coherent[s] &= ~(1 << i);
      } else {
         nvc0->textures_coherent[s] &= ~(1 << i);
      }

      if (old) {
         if (s == 5)
            nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_TEX(i));
         else
            nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_TEX(s, i));
         nvc0_screen_tic_unlock(nvc0->screen, old);
      }

      pipe_sampler_view_reference(&nvc0->textures[s][i], views[i]);
   }

   for (i = nr; i < nvc0->num_textures[s]; ++i) {
      struct nv50_tic_entry *old = nv50_tic_entry(nvc0->textures[s][i]);
      if (old) {
         if (s == 5)
            nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_TEX(i));
         else
            nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_TEX(s, i));
         nvc0_screen_tic_unlock(nvc0->screen, old);
         pipe_sampler_view_reference(&nvc0->textures[s][i], NULL);
      }
   }

   nvc0->num_textures[s] = nr;
}
예제 #7
0
static boolean
nve4_validate_tic(struct nvc0_context *nvc0, unsigned s)
{
   struct nouveau_bo *txc = nvc0->screen->txc;
   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
   unsigned i;
   boolean need_flush = FALSE;

   for (i = 0; i < nvc0->num_textures[s]; ++i) {
      struct nv50_tic_entry *tic = nv50_tic_entry(nvc0->textures[s][i]);
      struct nv04_resource *res;
      const boolean dirty = !!(nvc0->textures_dirty[s] & (1 << i));

      if (!tic) {
         nvc0->tex_handles[s][i] |= NVE4_TIC_ENTRY_INVALID;
         continue;
      }
      res = nv04_resource(tic->pipe.texture);

      if (tic->id < 0) {
         tic->id = nvc0_screen_tic_alloc(nvc0->screen, tic);

         PUSH_SPACE(push, 16);
         BEGIN_NVC0(push, NVE4_P2MF(DST_ADDRESS_HIGH), 2);
         PUSH_DATAh(push, txc->offset + (tic->id * 32));
         PUSH_DATA (push, txc->offset + (tic->id * 32));
         BEGIN_NVC0(push, NVE4_P2MF(LINE_LENGTH_IN), 2);
         PUSH_DATA (push, 32);
         PUSH_DATA (push, 1);
         BEGIN_1IC0(push, NVE4_P2MF(EXEC), 9);
         PUSH_DATA (push, 0x1001);
         PUSH_DATAp(push, &tic->tic[0], 8);

         need_flush = TRUE;
      } else
      if (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) {
         BEGIN_NVC0(push, NVC0_3D(TEX_CACHE_CTL), 1);
         PUSH_DATA (push, (tic->id << 4) | 1);
      }
      nvc0->screen->tic.lock[tic->id / 32] |= 1 << (tic->id % 32);

      res->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING;
      res->status |=  NOUVEAU_BUFFER_STATUS_GPU_READING;

      nvc0->tex_handles[s][i] &= ~NVE4_TIC_ENTRY_INVALID;
      nvc0->tex_handles[s][i] |= tic->id;
      if (dirty)
         BCTX_REFN(nvc0->bufctx_3d, TEX(s, i), res, RD);
   }
   for (; i < nvc0->state.num_textures[s]; ++i) {
      nvc0->tex_handles[s][i] |= NVE4_TIC_ENTRY_INVALID;
      nvc0->textures_dirty[s] |= 1 << i;
   }

   nvc0->state.num_textures[s] = nvc0->num_textures[s];

   return need_flush;
}
예제 #8
0
파일: nv50_state.c 프로젝트: Kalamatee/mesa
static inline void
nv50_stage_set_sampler_views(struct nv50_context *nv50, int s,
                             unsigned nr,
                             struct pipe_sampler_view **views)
{
   unsigned i;

   assert(nr <= PIPE_MAX_SAMPLERS);
   for (i = 0; i < nr; ++i) {
      struct nv50_tic_entry *old = nv50_tic_entry(nv50->textures[s][i]);
      if (old)
         nv50_screen_tic_unlock(nv50->screen, old);

      if (views[i] && views[i]->texture) {
         struct pipe_resource *res = views[i]->texture;
         if (res->target == PIPE_BUFFER &&
             (res->flags & PIPE_RESOURCE_FLAG_MAP_COHERENT))
            nv50->textures_coherent[s] |= 1 << i;
         else
            nv50->textures_coherent[s] &= ~(1 << i);
      } else {
         nv50->textures_coherent[s] &= ~(1 << i);
      }

      pipe_sampler_view_reference(&nv50->textures[s][i], views[i]);
   }

   assert(nv50->num_textures[s] <= PIPE_MAX_SAMPLERS);
   for (i = nr; i < nv50->num_textures[s]; ++i) {
      struct nv50_tic_entry *old = nv50_tic_entry(nv50->textures[s][i]);
      if (!old)
         continue;
      nv50_screen_tic_unlock(nv50->screen, old);

      pipe_sampler_view_reference(&nv50->textures[s][i], NULL);
   }

   nv50->num_textures[s] = nr;

   nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_3D_TEXTURES);

   nv50->dirty_3d |= NV50_NEW_3D_TEXTURES;
}
예제 #9
0
파일: nv50_surface.c 프로젝트: nikai3d/mesa
static INLINE void
nv50_blit_fixup_tic_entry(struct pipe_sampler_view *view)
{
   struct nv50_tic_entry *ent = nv50_tic_entry(view);

   ent->tic[2] &= ~(1 << 31); /* scaled coordinates, ok with 3d textures ? */

   /* magic: */

   ent->tic[3] = 0x20000000; /* affects quality of near vertical edges in MS8 */
}
예제 #10
0
파일: nvc0_state.c 프로젝트: chemecse/mesa
static bool
nvc0_bind_images_range(struct nvc0_context *nvc0, const unsigned s,
                       unsigned start, unsigned nr,
                       const struct pipe_image_view *pimages)
{
   const unsigned end = start + nr;
   unsigned mask = 0;
   unsigned i;

   assert(s < 6);

   if (pimages) {
      for (i = start; i < end; ++i) {
         struct pipe_image_view *img = &nvc0->images[s][i];
         const unsigned p = i - start;

         if (img->resource == pimages[p].resource &&
             img->format == pimages[p].format &&
             img->access == pimages[p].access) {
            if (img->resource == NULL)
               continue;
            if (img->resource->target == PIPE_BUFFER &&
                img->u.buf.offset == pimages[p].u.buf.offset &&
                img->u.buf.size == pimages[p].u.buf.size)
               continue;
            if (img->resource->target != PIPE_BUFFER &&
                img->u.tex.first_layer == pimages[p].u.tex.first_layer &&
                img->u.tex.last_layer == pimages[p].u.tex.last_layer &&
                img->u.tex.level == pimages[p].u.tex.level)
               continue;
         }

         mask |= (1 << i);
         if (pimages[p].resource)
            nvc0->images_valid[s] |= (1 << i);
         else
            nvc0->images_valid[s] &= ~(1 << i);

         img->format = pimages[p].format;
         img->access = pimages[p].access;
         if (pimages[p].resource && pimages[p].resource->target == PIPE_BUFFER)
            img->u.buf = pimages[p].u.buf;
         else
            img->u.tex = pimages[p].u.tex;

         pipe_resource_reference(
               &img->resource, pimages[p].resource);

         if (nvc0->screen->base.class_3d >= GM107_3D_CLASS) {
            if (nvc0->images_tic[s][i]) {
               struct nv50_tic_entry *old =
                  nv50_tic_entry(nvc0->images_tic[s][i]);
               nvc0_screen_tic_unlock(nvc0->screen, old);
               pipe_sampler_view_reference(&nvc0->images_tic[s][i], NULL);
            }

            nvc0->images_tic[s][i] =
               gm107_create_texture_view_from_image(&nvc0->base.pipe,
                                                    &pimages[p]);
         }
      }
      if (!mask)
         return false;
   } else {
      mask = ((1 << nr) - 1) << start;
      if (!(nvc0->images_valid[s] & mask))
         return false;
      for (i = start; i < end; ++i) {
         pipe_resource_reference(&nvc0->images[s][i].resource, NULL);
         if (nvc0->screen->base.class_3d >= GM107_3D_CLASS) {
            struct nv50_tic_entry *old = nv50_tic_entry(nvc0->images_tic[s][i]);
            if (old) {
               nvc0_screen_tic_unlock(nvc0->screen, old);
               pipe_sampler_view_reference(&nvc0->images_tic[s][i], NULL);
            }
         }
      }
      nvc0->images_valid[s] &= ~mask;
   }
   nvc0->images_dirty[s] |= mask;

   if (s == 5)
      nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_SUF);
   else
      nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_SUF);

   return true;
}
예제 #11
0
static boolean
nvc0_validate_tic(struct nvc0_context *nvc0, int s)
{
   uint32_t commands[32];
   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
   struct nouveau_bo *txc = nvc0->screen->txc;
   unsigned i;
   unsigned n = 0;
   boolean need_flush = FALSE;

   for (i = 0; i < nvc0->num_textures[s]; ++i) {
      struct nv50_tic_entry *tic = nv50_tic_entry(nvc0->textures[s][i]);
      struct nv04_resource *res;
      const boolean dirty = !!(nvc0->textures_dirty[s] & (1 << i));

      if (!tic) {
         if (dirty)
            commands[n++] = (i << 1) | 0;
         continue;
      }
      res = nv04_resource(tic->pipe.texture);

      if (tic->id < 0) {
         tic->id = nvc0_screen_tic_alloc(nvc0->screen, tic);

         PUSH_SPACE(push, 17);
         BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2);
         PUSH_DATAh(push, txc->offset + (tic->id * 32));
         PUSH_DATA (push, txc->offset + (tic->id * 32));
         BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2);
         PUSH_DATA (push, 32);
         PUSH_DATA (push, 1);
         BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1);
         PUSH_DATA (push, 0x100111);
         BEGIN_NIC0(push, NVC0_M2MF(DATA), 8);
         PUSH_DATAp(push, &tic->tic[0], 8);

         need_flush = TRUE;
      } else
      if (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) {
         BEGIN_NVC0(push, NVC0_3D(TEX_CACHE_CTL), 1);
         PUSH_DATA (push, (tic->id << 4) | 1);
      }
      nvc0->screen->tic.lock[tic->id / 32] |= 1 << (tic->id % 32);

      res->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING;
      res->status |=  NOUVEAU_BUFFER_STATUS_GPU_READING;

      if (!dirty)
         continue;
      commands[n++] = (tic->id << 9) | (i << 1) | 1;

      BCTX_REFN(nvc0->bufctx_3d, TEX(s, i), res, RD);
   }
   for (; i < nvc0->state.num_textures[s]; ++i)
      commands[n++] = (i << 1) | 0;

   nvc0->state.num_textures[s] = nvc0->num_textures[s];

   if (n) {
      BEGIN_NIC0(push, NVC0_3D(BIND_TIC(s)), n);
      PUSH_DATAp(push, commands, n);
   }
   nvc0->textures_dirty[s] = 0;

   return need_flush;
}
예제 #12
0
파일: nv50_tex.c 프로젝트: DirectFB/mesa
static boolean
nv50_validate_tic(struct nv50_context *nv50, int s)
{
   struct nouveau_pushbuf *push = nv50->base.pushbuf;
   struct nouveau_bo *txc = nv50->screen->txc;
   unsigned i;
   boolean need_flush = FALSE;

   assert(nv50->num_textures[s] <= PIPE_MAX_SAMPLERS);
   for (i = 0; i < nv50->num_textures[s]; ++i) {
      struct nv50_tic_entry *tic = nv50_tic_entry(nv50->textures[s][i]);
      struct nv04_resource *res;

      if (!tic) {
         BEGIN_NV04(push, NV50_3D(BIND_TIC(s)), 1);
         PUSH_DATA (push, (i << 1) | 0);
         continue;
      }
      res = &nv50_miptree(tic->pipe.texture)->base;

      if (tic->id < 0) {
         tic->id = nv50_screen_tic_alloc(nv50->screen, tic);

         BEGIN_NV04(push, NV50_2D(DST_FORMAT), 2);
         PUSH_DATA (push, NV50_SURFACE_FORMAT_R8_UNORM);
         PUSH_DATA (push, 1);
         BEGIN_NV04(push, NV50_2D(DST_PITCH), 5);
         PUSH_DATA (push, 262144);
         PUSH_DATA (push, 65536);
         PUSH_DATA (push, 1);
         PUSH_DATAh(push, txc->offset);
         PUSH_DATA (push, txc->offset);
         BEGIN_NV04(push, NV50_2D(SIFC_BITMAP_ENABLE), 2);
         PUSH_DATA (push, 0);
         PUSH_DATA (push, NV50_SURFACE_FORMAT_R8_UNORM);
         BEGIN_NV04(push, NV50_2D(SIFC_WIDTH), 10);
         PUSH_DATA (push, 32);
         PUSH_DATA (push, 1);
         PUSH_DATA (push, 0);
         PUSH_DATA (push, 1);
         PUSH_DATA (push, 0);
         PUSH_DATA (push, 1);
         PUSH_DATA (push, 0);
         PUSH_DATA (push, tic->id * 32);
         PUSH_DATA (push, 0);
         PUSH_DATA (push, 0);
         BEGIN_NI04(push, NV50_2D(SIFC_DATA), 8);
         PUSH_DATAp(push, &tic->tic[0], 8);

         need_flush = TRUE;
      } else
      if (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) {
         BEGIN_NV04(push, NV50_3D(TEX_CACHE_CTL), 1);
         PUSH_DATA (push, 0x20);
      }

      nv50->screen->tic.lock[tic->id / 32] |= 1 << (tic->id % 32);

      res->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING;
      res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING;

      BCTX_REFN(nv50->bufctx_3d, TEXTURES, res, RD);

      BEGIN_NV04(push, NV50_3D(BIND_TIC(s)), 1);
      PUSH_DATA (push, (tic->id << 9) | (i << 1) | 1);
   }
   for (; i < nv50->state.num_textures[s]; ++i) {
      BEGIN_NV04(push, NV50_3D(BIND_TIC(s)), 1);
      PUSH_DATA (push, (i << 1) | 0);
   }
   if (nv50->num_textures[s]) {
      BEGIN_NV04(push, NV50_3D(CB_ADDR), 1);
      PUSH_DATA (push, (NV50_CB_AUX_TEX_MS_OFFSET << (8 - 2)) | NV50_CB_AUX);
      BEGIN_NI04(push, NV50_3D(CB_DATA(0)), nv50->num_textures[s] * 2);
      for (i = 0; i < nv50->num_textures[s]; i++) {
         struct nv50_tic_entry *tic = nv50_tic_entry(nv50->textures[s][i]);
         struct nv50_miptree *res;

         if (!tic) {
            PUSH_DATA (push, 0);
            PUSH_DATA (push, 0);
            continue;
         }
         res = nv50_miptree(tic->pipe.texture);
         PUSH_DATA (push, res->ms_x);
         PUSH_DATA (push, res->ms_y);
      }
   }
   nv50->state.num_textures[s] = nv50->num_textures[s];

   return need_flush;
}