"Fossies" - the Fresh Open Source Software Archive

Member "mesa-20.1.8/src/gallium/drivers/softpipe/sp_state_sampler.c" (16 Sep 2020, 11268 Bytes) of package /linux/misc/mesa-20.1.8.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "sp_state_sampler.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 20.1.5_vs_20.2.0-rc1.

    1 /**************************************************************************
    2  * 
    3  * Copyright 2007 VMware, Inc.
    4  * All Rights Reserved.
    5  *
    6  * Permission is hereby granted, free of charge, to any person obtaining a
    7  * copy of this software and associated documentation files (the
    8  * "Software"), to deal in the Software without restriction, including
    9  * without limitation the rights to use, copy, modify, merge, publish,
   10  * distribute, sub license, and/or sell copies of the Software, and to
   11  * permit persons to whom the Software is furnished to do so, subject to
   12  * the following conditions:
   13  * 
   14  * The above copyright notice and this permission notice (including the
   15  * next paragraph) shall be included in all copies or substantial portions
   16  * of the Software.
   17  * 
   18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
   21  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
   22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   25  * 
   26  **************************************************************************/
   27 
   28 /* Authors:
   29  *  Brian Paul
   30  */
   31 
   32 #include "util/u_memory.h"
   33 #include "util/u_inlines.h"
   34 #include "util/format/u_format.h"
   35 
   36 #include "draw/draw_context.h"
   37 
   38 #include "sp_context.h"
   39 #include "sp_state.h"
   40 #include "sp_texture.h"
   41 #include "sp_tex_sample.h"
   42 #include "sp_tex_tile_cache.h"
   43 #include "sp_screen.h"
   44 #include "state_tracker/sw_winsys.h"
   45 
   46 
   47 /**
   48  * Bind a range [start, start+num-1] of samplers for a shader stage.
   49  */
   50 static void
   51 softpipe_bind_sampler_states(struct pipe_context *pipe,
   52                              enum pipe_shader_type shader,
   53                              unsigned start,
   54                              unsigned num,
   55                              void **samplers)
   56 {
   57    struct softpipe_context *softpipe = softpipe_context(pipe);
   58    unsigned i;
   59 
   60    assert(shader < PIPE_SHADER_TYPES);
   61    assert(start + num <= ARRAY_SIZE(softpipe->samplers[shader]));
   62 
   63    draw_flush(softpipe->draw);
   64 
   65    /* set the new samplers */
   66    for (i = 0; i < num; i++) {
   67       softpipe->samplers[shader][start + i] = samplers[i];
   68    }
   69 
   70    /* find highest non-null samplers[] entry */
   71    {
   72       unsigned j = MAX2(softpipe->num_samplers[shader], start + num);
   73       while (j > 0 && softpipe->samplers[shader][j - 1] == NULL)
   74          j--;
   75       softpipe->num_samplers[shader] = j;
   76    }
   77 
   78    if (shader == PIPE_SHADER_VERTEX || shader == PIPE_SHADER_GEOMETRY) {
   79       draw_set_samplers(softpipe->draw,
   80                         shader,
   81                         softpipe->samplers[shader],
   82                         softpipe->num_samplers[shader]);
   83    }
   84 
   85    softpipe->dirty |= SP_NEW_SAMPLER;
   86 }
   87 
   88 
   89 static void
   90 softpipe_sampler_view_destroy(struct pipe_context *pipe,
   91                               struct pipe_sampler_view *view)
   92 {
   93    pipe_resource_reference(&view->texture, NULL);
   94    FREE(view);
   95 }
   96 
   97 
   98 void
   99 softpipe_set_sampler_views(struct pipe_context *pipe,
  100                            enum pipe_shader_type shader,
  101                            unsigned start,
  102                            unsigned num,
  103                            struct pipe_sampler_view **views)
  104 {
  105    struct softpipe_context *softpipe = softpipe_context(pipe);
  106    uint i;
  107 
  108    assert(shader < PIPE_SHADER_TYPES);
  109    assert(start + num <= ARRAY_SIZE(softpipe->sampler_views[shader]));
  110 
  111    draw_flush(softpipe->draw);
  112 
  113    /* set the new sampler views */
  114    for (i = 0; i < num; i++) {
  115       struct sp_sampler_view *sp_sviewsrc;
  116       struct sp_sampler_view *sp_sviewdst =
  117          &softpipe->tgsi.sampler[shader]->sp_sview[start + i];
  118       struct pipe_sampler_view **pview = &softpipe->sampler_views[shader][start + i];
  119       pipe_sampler_view_reference(pview, views[i]);
  120       sp_tex_tile_cache_set_sampler_view(softpipe->tex_cache[shader][start + i],
  121                                          views[i]);
  122       /*
  123        * We don't really have variants, however some bits are different per shader,
  124        * so just copy?
  125        */
  126       sp_sviewsrc = (struct sp_sampler_view *)*pview;
  127       if (sp_sviewsrc) {
  128          memcpy(sp_sviewdst, sp_sviewsrc, sizeof(*sp_sviewsrc));
  129          sp_sviewdst->compute_lambda = softpipe_get_lambda_func(&sp_sviewdst->base, shader);
  130          sp_sviewdst->compute_lambda_from_grad = softpipe_get_lambda_from_grad_func(&sp_sviewdst->base, shader);
  131          sp_sviewdst->cache = softpipe->tex_cache[shader][start + i];
  132       }
  133       else {
  134          memset(sp_sviewdst, 0,  sizeof(*sp_sviewsrc));
  135       }
  136    }
  137 
  138 
  139    /* find highest non-null sampler_views[] entry */
  140    {
  141       unsigned j = MAX2(softpipe->num_sampler_views[shader], start + num);
  142       while (j > 0 && softpipe->sampler_views[shader][j - 1] == NULL)
  143          j--;
  144       softpipe->num_sampler_views[shader] = j;
  145    }
  146 
  147    if (shader == PIPE_SHADER_VERTEX || shader == PIPE_SHADER_GEOMETRY) {
  148       draw_set_sampler_views(softpipe->draw,
  149                              shader,
  150                              softpipe->sampler_views[shader],
  151                              softpipe->num_sampler_views[shader]);
  152    }
  153 
  154    softpipe->dirty |= SP_NEW_TEXTURE;
  155 }
  156 
  157 
  158 static void
  159 softpipe_delete_sampler_state(struct pipe_context *pipe,
  160                               void *sampler)
  161 {
  162    FREE( sampler );
  163 }
  164 
  165 
  166 static void
  167 prepare_shader_sampling(
  168    struct softpipe_context *sp,
  169    unsigned num,
  170    struct pipe_sampler_view **views,
  171    enum pipe_shader_type shader_type,
  172    struct pipe_resource *mapped_tex[PIPE_MAX_SHADER_SAMPLER_VIEWS])
  173 {
  174 
  175    unsigned i;
  176    uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS];
  177    uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS];
  178    uint32_t mip_offsets[PIPE_MAX_TEXTURE_LEVELS];
  179    const void *addr;
  180 
  181    assert(num <= PIPE_MAX_SHADER_SAMPLER_VIEWS);
  182    if (!num)
  183       return;
  184 
  185    for (i = 0; i < num; i++) {
  186       struct pipe_sampler_view *view = views[i];
  187 
  188       if (view) {
  189          struct pipe_resource *tex = view->texture;
  190          struct softpipe_resource *sp_tex = softpipe_resource(tex);
  191          unsigned width0 = tex->width0;
  192          unsigned num_layers = tex->depth0;
  193          unsigned first_level = 0;
  194          unsigned last_level = 0;
  195 
  196          /* We're referencing the texture's internal data, so save a
  197           * reference to it.
  198           */
  199          pipe_resource_reference(&mapped_tex[i], tex);
  200 
  201          if (!sp_tex->dt) {
  202             /* regular texture - setup array of mipmap level offsets */
  203             ASSERTED struct pipe_resource *res = view->texture;
  204             int j;
  205 
  206             if (view->target != PIPE_BUFFER) {
  207                first_level = view->u.tex.first_level;
  208                last_level = view->u.tex.last_level;
  209                assert(first_level <= last_level);
  210                assert(last_level <= res->last_level);
  211                addr = sp_tex->data;
  212 
  213                for (j = first_level; j <= last_level; j++) {
  214                   mip_offsets[j] = sp_tex->level_offset[j];
  215                   row_stride[j] = sp_tex->stride[j];
  216                   img_stride[j] = sp_tex->img_stride[j];
  217                }
  218                if (tex->target == PIPE_TEXTURE_1D_ARRAY ||
  219                    tex->target == PIPE_TEXTURE_2D_ARRAY ||
  220                    tex->target == PIPE_TEXTURE_CUBE ||
  221                    tex->target == PIPE_TEXTURE_CUBE_ARRAY) {
  222                   num_layers = view->u.tex.last_layer - view->u.tex.first_layer + 1;
  223                   for (j = first_level; j <= last_level; j++) {
  224                      mip_offsets[j] += view->u.tex.first_layer *
  225                                        sp_tex->img_stride[j];
  226                   }
  227                   if (view->target == PIPE_TEXTURE_CUBE ||
  228                       view->target == PIPE_TEXTURE_CUBE_ARRAY) {
  229                      assert(num_layers % 6 == 0);
  230                   }
  231                   assert(view->u.tex.first_layer <= view->u.tex.last_layer);
  232                   assert(view->u.tex.last_layer < res->array_size);
  233                }
  234             }
  235             else {
  236                unsigned view_blocksize = util_format_get_blocksize(view->format);
  237                addr = sp_tex->data;
  238                /* probably don't really need to fill that out */
  239                mip_offsets[0] = 0;
  240                row_stride[0] = 0;
  241                img_stride[0] = 0;
  242 
  243                /* everything specified in number of elements here. */
  244                width0 = view->u.buf.size / view_blocksize;
  245                addr = (uint8_t *)addr + view->u.buf.offset;
  246                assert(view->u.buf.offset + view->u.buf.size <= res->width0);
  247             }
  248          }
  249          else {
  250             /* display target texture/surface */
  251             /*
  252              * XXX: Where should this be unmapped?
  253              */
  254             struct softpipe_screen *screen = softpipe_screen(tex->screen);
  255             struct sw_winsys *winsys = screen->winsys;
  256             addr = winsys->displaytarget_map(winsys, sp_tex->dt,
  257                                              PIPE_TRANSFER_READ);
  258             row_stride[0] = sp_tex->stride[0];
  259             img_stride[0] = sp_tex->img_stride[0];
  260             mip_offsets[0] = 0;
  261             assert(addr);
  262          }
  263          draw_set_mapped_texture(sp->draw,
  264                                  shader_type,
  265                                  i,
  266                                  width0, tex->height0, num_layers,
  267                                  first_level, last_level,
  268                                  addr,
  269                                  row_stride, img_stride, mip_offsets);
  270       }
  271    }
  272 }
  273 
  274 
  275 /**
  276  * Called during state validation when SP_NEW_TEXTURE is set.
  277  */
  278 void
  279 softpipe_prepare_vertex_sampling(struct softpipe_context *sp,
  280                                  unsigned num,
  281                                  struct pipe_sampler_view **views)
  282 {
  283    prepare_shader_sampling(sp, num, views, PIPE_SHADER_VERTEX,
  284                            sp->mapped_vs_tex);
  285 }
  286 
  287 void
  288 softpipe_cleanup_vertex_sampling(struct softpipe_context *ctx)
  289 {
  290    unsigned i;
  291    for (i = 0; i < ARRAY_SIZE(ctx->mapped_vs_tex); i++) {
  292       pipe_resource_reference(&ctx->mapped_vs_tex[i], NULL);
  293    }
  294 }
  295 
  296 
  297 /**
  298  * Called during state validation when SP_NEW_TEXTURE is set.
  299  */
  300 void
  301 softpipe_prepare_geometry_sampling(struct softpipe_context *sp,
  302                                    unsigned num,
  303                                    struct pipe_sampler_view **views)
  304 {
  305    prepare_shader_sampling(sp, num, views, PIPE_SHADER_GEOMETRY,
  306                            sp->mapped_gs_tex);
  307 }
  308 
  309 void
  310 softpipe_cleanup_geometry_sampling(struct softpipe_context *ctx)
  311 {
  312    unsigned i;
  313    for (i = 0; i < ARRAY_SIZE(ctx->mapped_gs_tex); i++) {
  314       pipe_resource_reference(&ctx->mapped_gs_tex[i], NULL);
  315    }
  316 }
  317 
  318 
  319 void
  320 softpipe_init_sampler_funcs(struct pipe_context *pipe)
  321 {
  322    pipe->create_sampler_state = softpipe_create_sampler_state;
  323    pipe->bind_sampler_states = softpipe_bind_sampler_states;
  324    pipe->delete_sampler_state = softpipe_delete_sampler_state;
  325 
  326    pipe->create_sampler_view = softpipe_create_sampler_view;
  327    pipe->set_sampler_views = softpipe_set_sampler_views;
  328    pipe->sampler_view_destroy = softpipe_sampler_view_destroy;
  329 }
  330