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.  /*
  29.   * Authors:
  30.   *   Keith Whitwell <keithw@vmware.com>
  31.   *   Brian Paul
  32.   */
  33.  
  34.  
  35. #include "main/macros.h"
  36. #include "main/mtypes.h"
  37. #include "main/glformats.h"
  38. #include "main/samplerobj.h"
  39. #include "main/teximage.h"
  40. #include "main/texobj.h"
  41.  
  42. #include "st_context.h"
  43. #include "st_cb_texture.h"
  44. #include "st_format.h"
  45. #include "st_atom.h"
  46. #include "st_texture.h"
  47. #include "pipe/p_context.h"
  48. #include "pipe/p_defines.h"
  49.  
  50. #include "cso_cache/cso_context.h"
  51.  
  52. #include "util/u_format.h"
  53.  
  54.  
  55. /**
  56.  * Convert GLenum texcoord wrap tokens to pipe tokens.
  57.  */
  58. static GLuint
  59. gl_wrap_xlate(GLenum wrap)
  60. {
  61.    switch (wrap) {
  62.    case GL_REPEAT:
  63.       return PIPE_TEX_WRAP_REPEAT;
  64.    case GL_CLAMP:
  65.       return PIPE_TEX_WRAP_CLAMP;
  66.    case GL_CLAMP_TO_EDGE:
  67.       return PIPE_TEX_WRAP_CLAMP_TO_EDGE;
  68.    case GL_CLAMP_TO_BORDER:
  69.       return PIPE_TEX_WRAP_CLAMP_TO_BORDER;
  70.    case GL_MIRRORED_REPEAT:
  71.       return PIPE_TEX_WRAP_MIRROR_REPEAT;
  72.    case GL_MIRROR_CLAMP_EXT:
  73.       return PIPE_TEX_WRAP_MIRROR_CLAMP;
  74.    case GL_MIRROR_CLAMP_TO_EDGE_EXT:
  75.       return PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE;
  76.    case GL_MIRROR_CLAMP_TO_BORDER_EXT:
  77.       return PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER;
  78.    default:
  79.       assert(0);
  80.       return 0;
  81.    }
  82. }
  83.  
  84.  
  85. static GLuint
  86. gl_filter_to_mip_filter(GLenum filter)
  87. {
  88.    switch (filter) {
  89.    case GL_NEAREST:
  90.    case GL_LINEAR:
  91.       return PIPE_TEX_MIPFILTER_NONE;
  92.  
  93.    case GL_NEAREST_MIPMAP_NEAREST:
  94.    case GL_LINEAR_MIPMAP_NEAREST:
  95.       return PIPE_TEX_MIPFILTER_NEAREST;
  96.  
  97.    case GL_NEAREST_MIPMAP_LINEAR:
  98.    case GL_LINEAR_MIPMAP_LINEAR:
  99.       return PIPE_TEX_MIPFILTER_LINEAR;
  100.  
  101.    default:
  102.       assert(0);
  103.       return PIPE_TEX_MIPFILTER_NONE;
  104.    }
  105. }
  106.  
  107.  
  108. static GLuint
  109. gl_filter_to_img_filter(GLenum filter)
  110. {
  111.    switch (filter) {
  112.    case GL_NEAREST:
  113.    case GL_NEAREST_MIPMAP_NEAREST:
  114.    case GL_NEAREST_MIPMAP_LINEAR:
  115.       return PIPE_TEX_FILTER_NEAREST;
  116.  
  117.    case GL_LINEAR:
  118.    case GL_LINEAR_MIPMAP_NEAREST:
  119.    case GL_LINEAR_MIPMAP_LINEAR:
  120.       return PIPE_TEX_FILTER_LINEAR;
  121.  
  122.    default:
  123.       assert(0);
  124.       return PIPE_TEX_FILTER_NEAREST;
  125.    }
  126. }
  127.  
  128.  
  129. static void
  130. convert_sampler(struct st_context *st,
  131.                 struct pipe_sampler_state *sampler,
  132.                 GLuint texUnit)
  133. {
  134.    const struct gl_texture_object *texobj;
  135.    struct gl_context *ctx = st->ctx;
  136.    struct gl_sampler_object *msamp;
  137.    GLenum texBaseFormat;
  138.  
  139.    texobj = ctx->Texture.Unit[texUnit]._Current;
  140.    if (!texobj) {
  141.       texobj = _mesa_get_fallback_texture(ctx, TEXTURE_2D_INDEX);
  142.    }
  143.  
  144.    texBaseFormat = _mesa_texture_base_format(texobj);
  145.  
  146.    msamp = _mesa_get_samplerobj(ctx, texUnit);
  147.  
  148.    memset(sampler, 0, sizeof(*sampler));
  149.    sampler->wrap_s = gl_wrap_xlate(msamp->WrapS);
  150.    sampler->wrap_t = gl_wrap_xlate(msamp->WrapT);
  151.    sampler->wrap_r = gl_wrap_xlate(msamp->WrapR);
  152.  
  153.    sampler->min_img_filter = gl_filter_to_img_filter(msamp->MinFilter);
  154.    sampler->min_mip_filter = gl_filter_to_mip_filter(msamp->MinFilter);
  155.    sampler->mag_img_filter = gl_filter_to_img_filter(msamp->MagFilter);
  156.  
  157.    if (texobj->Target != GL_TEXTURE_RECTANGLE_ARB)
  158.       sampler->normalized_coords = 1;
  159.  
  160.    sampler->lod_bias = ctx->Texture.Unit[texUnit].LodBias + msamp->LodBias;
  161.  
  162.    sampler->min_lod = MAX2(msamp->MinLod, 0.0f);
  163.    sampler->max_lod = msamp->MaxLod;
  164.    if (sampler->max_lod < sampler->min_lod) {
  165.       /* The GL spec doesn't seem to specify what to do in this case.
  166.        * Swap the values.
  167.        */
  168.       float tmp = sampler->max_lod;
  169.       sampler->max_lod = sampler->min_lod;
  170.       sampler->min_lod = tmp;
  171.       assert(sampler->min_lod <= sampler->max_lod);
  172.    }
  173.  
  174.    /* For non-black borders... */
  175.    if (msamp->BorderColor.ui[0] ||
  176.        msamp->BorderColor.ui[1] ||
  177.        msamp->BorderColor.ui[2] ||
  178.        msamp->BorderColor.ui[3]) {
  179.       const struct st_texture_object *stobj = st_texture_object_const(texobj);
  180.       const GLboolean is_integer = texobj->_IsIntegerFormat;
  181.       const struct pipe_sampler_view *sv = NULL;
  182.       union pipe_color_union border_color;
  183.       GLuint i;
  184.  
  185.       /* Just search for the first used view. We can do this because the
  186.          swizzle is per-texture, not per context. */
  187.       /* XXX: clean that up to not use the sampler view at all */
  188.       for (i = 0; i < stobj->num_sampler_views; ++i) {
  189.          if (stobj->sampler_views[i]) {
  190.             sv = stobj->sampler_views[i];
  191.             break;
  192.          }
  193.       }
  194.  
  195.       if (st->apply_texture_swizzle_to_border_color && sv) {
  196.          const unsigned char swz[4] =
  197.          {
  198.             sv->swizzle_r,
  199.             sv->swizzle_g,
  200.             sv->swizzle_b,
  201.             sv->swizzle_a,
  202.          };
  203.  
  204.          st_translate_color(&msamp->BorderColor,
  205.                             &border_color,
  206.                             texBaseFormat, is_integer);
  207.  
  208.          util_format_apply_color_swizzle(&sampler->border_color,
  209.                                          &border_color, swz, is_integer);
  210.       } else {
  211.          st_translate_color(&msamp->BorderColor,
  212.                             &sampler->border_color,
  213.                             texBaseFormat, is_integer);
  214.       }
  215.    }
  216.  
  217.    sampler->max_anisotropy = (msamp->MaxAnisotropy == 1.0 ?
  218.                               0 : (GLuint) msamp->MaxAnisotropy);
  219.  
  220.    /* If sampling a depth texture and using shadow comparison */
  221.    if ((texBaseFormat == GL_DEPTH_COMPONENT ||
  222.         texBaseFormat == GL_DEPTH_STENCIL) &&
  223.        msamp->CompareMode == GL_COMPARE_R_TO_TEXTURE) {
  224.       sampler->compare_mode = PIPE_TEX_COMPARE_R_TO_TEXTURE;
  225.       sampler->compare_func = st_compare_func_to_pipe(msamp->CompareFunc);
  226.    }
  227.  
  228.    sampler->seamless_cube_map =
  229.       ctx->Texture.CubeMapSeamless || msamp->CubeMapSeamless;
  230. }
  231.  
  232.  
  233. /**
  234.  * Update the gallium driver's sampler state for fragment, vertex or
  235.  * geometry shader stage.
  236.  */
  237. static void
  238. update_shader_samplers(struct st_context *st,
  239.                        unsigned shader_stage,
  240.                        const struct gl_program *prog,
  241.                        unsigned max_units,
  242.                        struct pipe_sampler_state *samplers,
  243.                        unsigned *num_samplers)
  244. {
  245.    GLuint unit;
  246.    GLbitfield samplers_used;
  247.    const GLuint old_max = *num_samplers;
  248.  
  249.    samplers_used = prog->SamplersUsed;
  250.  
  251.    if (*num_samplers == 0 && samplers_used == 0x0)
  252.        return;
  253.  
  254.    *num_samplers = 0;
  255.  
  256.    /* loop over sampler units (aka tex image units) */
  257.    for (unit = 0; unit < max_units; unit++, samplers_used >>= 1) {
  258.       struct pipe_sampler_state *sampler = samplers + unit;
  259.  
  260.       if (samplers_used & 1) {
  261.          const GLuint texUnit = prog->SamplerUnits[unit];
  262.  
  263.          convert_sampler(st, sampler, texUnit);
  264.  
  265.          *num_samplers = unit + 1;
  266.  
  267.          cso_single_sampler(st->cso_context, shader_stage, unit, sampler);
  268.       }
  269.       else if (samplers_used != 0 || unit < old_max) {
  270.          cso_single_sampler(st->cso_context, shader_stage, unit, NULL);
  271.       }
  272.       else {
  273.          /* if we've reset all the old samplers and we have no more new ones */
  274.          break;
  275.       }
  276.    }
  277.  
  278.    cso_single_sampler_done(st->cso_context, shader_stage);
  279. }
  280.  
  281.  
  282. static void
  283. update_samplers(struct st_context *st)
  284. {
  285.    const struct gl_context *ctx = st->ctx;
  286.  
  287.    update_shader_samplers(st,
  288.                           PIPE_SHADER_FRAGMENT,
  289.                           &ctx->FragmentProgram._Current->Base,
  290.                           ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits,
  291.                           st->state.samplers[PIPE_SHADER_FRAGMENT],
  292.                           &st->state.num_samplers[PIPE_SHADER_FRAGMENT]);
  293.  
  294.    update_shader_samplers(st,
  295.                           PIPE_SHADER_VERTEX,
  296.                           &ctx->VertexProgram._Current->Base,
  297.                           ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits,
  298.                           st->state.samplers[PIPE_SHADER_VERTEX],
  299.                           &st->state.num_samplers[PIPE_SHADER_VERTEX]);
  300.  
  301.    if (ctx->GeometryProgram._Current) {
  302.       update_shader_samplers(st,
  303.                              PIPE_SHADER_GEOMETRY,
  304.                              &ctx->GeometryProgram._Current->Base,
  305.                              ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits,
  306.                              st->state.samplers[PIPE_SHADER_GEOMETRY],
  307.                              &st->state.num_samplers[PIPE_SHADER_GEOMETRY]);
  308.    }
  309. }
  310.  
  311.  
  312. const struct st_tracked_state st_update_sampler = {
  313.    "st_update_sampler",                                 /* name */
  314.    {                                                    /* dirty */
  315.       _NEW_TEXTURE,                                     /* mesa */
  316.       0,                                                /* st */
  317.    },
  318.    update_samplers                                      /* update */
  319. };
  320.