Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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/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.                              unsigned 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 <= Elements(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.                            unsigned 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 <= Elements(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->cache = softpipe->tex_cache[shader][start + i];
  131.       }
  132.       else {
  133.          memset(sp_sviewdst, 0,  sizeof(*sp_sviewsrc));
  134.       }
  135.    }
  136.  
  137.  
  138.    /* find highest non-null sampler_views[] entry */
  139.    {
  140.       unsigned j = MAX2(softpipe->num_sampler_views[shader], start + num);
  141.       while (j > 0 && softpipe->sampler_views[shader][j - 1] == NULL)
  142.          j--;
  143.       softpipe->num_sampler_views[shader] = j;
  144.    }
  145.  
  146.    if (shader == PIPE_SHADER_VERTEX || shader == PIPE_SHADER_GEOMETRY) {
  147.       draw_set_sampler_views(softpipe->draw,
  148.                              shader,
  149.                              softpipe->sampler_views[shader],
  150.                              softpipe->num_sampler_views[shader]);
  151.    }
  152.  
  153.    softpipe->dirty |= SP_NEW_TEXTURE;
  154. }
  155.  
  156.  
  157. static void
  158. softpipe_delete_sampler_state(struct pipe_context *pipe,
  159.                               void *sampler)
  160. {
  161.    FREE( sampler );
  162. }
  163.  
  164.  
  165. static void
  166. prepare_shader_sampling(
  167.    struct softpipe_context *sp,
  168.    unsigned num,
  169.    struct pipe_sampler_view **views,
  170.    unsigned shader_type,
  171.    struct pipe_resource *mapped_tex[PIPE_MAX_SHADER_SAMPLER_VIEWS])
  172. {
  173.  
  174.    unsigned i;
  175.    uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS];
  176.    uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS];
  177.    uint32_t mip_offsets[PIPE_MAX_TEXTURE_LEVELS];
  178.    const void *addr;
  179.  
  180.    assert(num <= PIPE_MAX_SHADER_SAMPLER_VIEWS);
  181.    if (!num)
  182.       return;
  183.  
  184.    for (i = 0; i < PIPE_MAX_SHADER_SAMPLER_VIEWS; i++) {
  185.       struct pipe_sampler_view *view = i < num ? views[i] : NULL;
  186.  
  187.       if (view) {
  188.          struct pipe_resource *tex = view->texture;
  189.          struct softpipe_resource *sp_tex = softpipe_resource(tex);
  190.          unsigned width0 = tex->width0;
  191.          unsigned num_layers = tex->depth0;
  192.          unsigned first_level = 0;
  193.          unsigned last_level = 0;
  194.  
  195.          /* We're referencing the texture's internal data, so save a
  196.           * reference to it.
  197.           */
  198.          pipe_resource_reference(&mapped_tex[i], tex);
  199.  
  200.          if (!sp_tex->dt) {
  201.             /* regular texture - setup array of mipmap level offsets */
  202.             struct pipe_resource *res = view->texture;
  203.             int j;
  204.  
  205.             if (view->target != PIPE_BUFFER) {
  206.                first_level = view->u.tex.first_level;
  207.                last_level = view->u.tex.last_level;
  208.                assert(first_level <= last_level);
  209.                assert(last_level <= res->last_level);
  210.                addr = sp_tex->data;
  211.  
  212.                for (j = first_level; j <= last_level; j++) {
  213.                   mip_offsets[j] = sp_tex->level_offset[j];
  214.                   row_stride[j] = sp_tex->stride[j];
  215.                   img_stride[j] = sp_tex->img_stride[j];
  216.                }
  217.                if (view->target == PIPE_TEXTURE_1D_ARRAY ||
  218.                    view->target == PIPE_TEXTURE_2D_ARRAY ||
  219.                    view->target == PIPE_TEXTURE_CUBE ||
  220.                    view->target == PIPE_TEXTURE_CUBE_ARRAY) {
  221.                   num_layers = view->u.tex.last_layer - view->u.tex.first_layer + 1;
  222.                   for (j = first_level; j <= last_level; j++) {
  223.                      mip_offsets[j] += view->u.tex.first_layer *
  224.                                        sp_tex->img_stride[j];
  225.                   }
  226.                   if (view->target == PIPE_TEXTURE_CUBE ||
  227.                       view->target == PIPE_TEXTURE_CUBE_ARRAY) {
  228.                      assert(num_layers % 6 == 0);
  229.                   }
  230.                   assert(view->u.tex.first_layer <= view->u.tex.last_layer);
  231.                   assert(view->u.tex.last_layer < res->array_size);
  232.                }
  233.             }
  234.             else {
  235.                unsigned view_blocksize = util_format_get_blocksize(view->format);
  236.                addr = sp_tex->data;
  237.                /* probably don't really need to fill that out */
  238.                mip_offsets[0] = 0;
  239.                row_stride[0] = 0;
  240.                img_stride[0] = 0;
  241.  
  242.                /* everything specified in number of elements here. */
  243.                width0 = view->u.buf.last_element - view->u.buf.first_element + 1;
  244.                addr = (uint8_t *)addr + view->u.buf.first_element *
  245.                                view_blocksize;
  246.                assert(view->u.buf.first_element <= view->u.buf.last_element);
  247.                assert(view->u.buf.last_element * view_blocksize < res->width0);
  248.             }
  249.          }
  250.          else {
  251.             /* display target texture/surface */
  252.             /*
  253.              * XXX: Where should this be unmapped?
  254.              */
  255.             struct softpipe_screen *screen = softpipe_screen(tex->screen);
  256.             struct sw_winsys *winsys = screen->winsys;
  257.             addr = winsys->displaytarget_map(winsys, sp_tex->dt,
  258.                                              PIPE_TRANSFER_READ);
  259.             row_stride[0] = sp_tex->stride[0];
  260.             img_stride[0] = sp_tex->img_stride[0];
  261.             mip_offsets[0] = 0;
  262.             assert(addr);
  263.          }
  264.          draw_set_mapped_texture(sp->draw,
  265.                                  shader_type,
  266.                                  i,
  267.                                  width0, tex->height0, num_layers,
  268.                                  first_level, last_level,
  269.                                  addr,
  270.                                  row_stride, img_stride, mip_offsets);
  271.       }
  272.    }
  273. }
  274.  
  275.  
  276. /**
  277.  * Called during state validation when SP_NEW_TEXTURE is set.
  278.  */
  279. void
  280. softpipe_prepare_vertex_sampling(struct softpipe_context *sp,
  281.                                  unsigned num,
  282.                                  struct pipe_sampler_view **views)
  283. {
  284.    prepare_shader_sampling(sp, num, views, PIPE_SHADER_VERTEX,
  285.                            sp->mapped_vs_tex);
  286. }
  287.  
  288. void
  289. softpipe_cleanup_vertex_sampling(struct softpipe_context *ctx)
  290. {
  291.    unsigned i;
  292.    for (i = 0; i < Elements(ctx->mapped_vs_tex); i++) {
  293.       pipe_resource_reference(&ctx->mapped_vs_tex[i], NULL);
  294.    }
  295. }
  296.  
  297.  
  298. /**
  299.  * Called during state validation when SP_NEW_TEXTURE is set.
  300.  */
  301. void
  302. softpipe_prepare_geometry_sampling(struct softpipe_context *sp,
  303.                                    unsigned num,
  304.                                    struct pipe_sampler_view **views)
  305. {
  306.    prepare_shader_sampling(sp, num, views, PIPE_SHADER_GEOMETRY,
  307.                            sp->mapped_gs_tex);
  308. }
  309.  
  310. void
  311. softpipe_cleanup_geometry_sampling(struct softpipe_context *ctx)
  312. {
  313.    unsigned i;
  314.    for (i = 0; i < Elements(ctx->mapped_gs_tex); i++) {
  315.       pipe_resource_reference(&ctx->mapped_gs_tex[i], NULL);
  316.    }
  317. }
  318.  
  319.  
  320. void
  321. softpipe_init_sampler_funcs(struct pipe_context *pipe)
  322. {
  323.    pipe->create_sampler_state = softpipe_create_sampler_state;
  324.    pipe->bind_sampler_states = softpipe_bind_sampler_states;
  325.    pipe->delete_sampler_state = softpipe_delete_sampler_state;
  326.  
  327.    pipe->create_sampler_view = softpipe_create_sampler_view;
  328.    pipe->set_sampler_views = softpipe_set_sampler_views;
  329.    pipe->sampler_view_destroy = softpipe_sampler_view_destroy;
  330. }
  331.  
  332.