Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
  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 TUNGSTEN GRAPHICS 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 <keith@tungstengraphics.com>
  31.   *   Brian Paul
  32.   */
  33.  
  34.  
  35. #include "main/macros.h"
  36.  
  37. #include "st_context.h"
  38. #include "st_cb_texture.h"
  39. #include "st_format.h"
  40. #include "st_atom.h"
  41. #include "pipe/p_context.h"
  42. #include "pipe/p_defines.h"
  43.  
  44. #include "cso_cache/cso_context.h"
  45.  
  46.  
  47. /**
  48.  * Convert GLenum texcoord wrap tokens to pipe tokens.
  49.  */
  50. static GLuint
  51. gl_wrap_xlate(GLenum wrap)
  52. {
  53.    switch (wrap) {
  54.    case GL_REPEAT:
  55.       return PIPE_TEX_WRAP_REPEAT;
  56.    case GL_CLAMP:
  57.       return PIPE_TEX_WRAP_CLAMP;
  58.    case GL_CLAMP_TO_EDGE:
  59.       return PIPE_TEX_WRAP_CLAMP_TO_EDGE;
  60.    case GL_CLAMP_TO_BORDER:
  61.       return PIPE_TEX_WRAP_CLAMP_TO_BORDER;
  62.    case GL_MIRRORED_REPEAT:
  63.       return PIPE_TEX_WRAP_MIRROR_REPEAT;
  64.    case GL_MIRROR_CLAMP_EXT:
  65.       return PIPE_TEX_WRAP_MIRROR_CLAMP;
  66.    case GL_MIRROR_CLAMP_TO_EDGE_EXT:
  67.       return PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE;
  68.    case GL_MIRROR_CLAMP_TO_BORDER_EXT:
  69.       return PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER;
  70.    default:
  71.       assert(0);
  72.       return 0;
  73.    }
  74. }
  75.  
  76.  
  77. static GLuint
  78. gl_filter_to_mip_filter(GLenum filter)
  79. {
  80.    switch (filter) {
  81.    case GL_NEAREST:
  82.    case GL_LINEAR:
  83.       return PIPE_TEX_MIPFILTER_NONE;
  84.  
  85.    case GL_NEAREST_MIPMAP_NEAREST:
  86.    case GL_LINEAR_MIPMAP_NEAREST:
  87.       return PIPE_TEX_MIPFILTER_NEAREST;
  88.  
  89.    case GL_NEAREST_MIPMAP_LINEAR:
  90.    case GL_LINEAR_MIPMAP_LINEAR:
  91.       return PIPE_TEX_MIPFILTER_LINEAR;
  92.  
  93.    default:
  94.       assert(0);
  95.       return PIPE_TEX_MIPFILTER_NONE;
  96.    }
  97. }
  98.  
  99.  
  100. static GLuint
  101. gl_filter_to_img_filter(GLenum filter)
  102. {
  103.    switch (filter) {
  104.    case GL_NEAREST:
  105.    case GL_NEAREST_MIPMAP_NEAREST:
  106.    case GL_NEAREST_MIPMAP_LINEAR:
  107.       return PIPE_TEX_FILTER_NEAREST;
  108.  
  109.    case GL_LINEAR:
  110.    case GL_LINEAR_MIPMAP_NEAREST:
  111.    case GL_LINEAR_MIPMAP_LINEAR:
  112.       return PIPE_TEX_FILTER_LINEAR;
  113.  
  114.    default:
  115.       assert(0);
  116.       return PIPE_TEX_FILTER_NEAREST;
  117.    }
  118. }
  119.  
  120.  
  121. static void
  122. update_samplers(struct st_context *st)
  123. {
  124.    struct gl_vertex_program *vprog = st->ctx->VertexProgram._Current;
  125.    struct gl_fragment_program *fprog = st->ctx->FragmentProgram._Current;
  126.    const GLbitfield samplersUsed = (vprog->Base.SamplersUsed |
  127.                                     fprog->Base.SamplersUsed);
  128.    GLuint su;
  129.  
  130.    st->state.num_samplers = 0;
  131.  
  132.    /* loop over sampler units (aka tex image units) */
  133.    for (su = 0; su < st->ctx->Const.MaxTextureImageUnits; su++) {
  134.       struct pipe_sampler_state *sampler = st->state.samplers + su;
  135.  
  136.       memset(sampler, 0, sizeof(*sampler));
  137.  
  138.       if (samplersUsed & (1 << su)) {
  139.          struct gl_texture_object *texobj;
  140.          struct gl_texture_image *teximg;
  141.          GLuint texUnit;
  142.  
  143.          if (fprog->Base.SamplersUsed & (1 << su))
  144.             texUnit = fprog->Base.SamplerUnits[su];
  145.          else
  146.             texUnit = vprog->Base.SamplerUnits[su];
  147.  
  148.          texobj = st->ctx->Texture.Unit[texUnit]._Current;
  149.          if (!texobj) {
  150.             texobj = st_get_default_texture(st);
  151.          }
  152.  
  153.          teximg = texobj->Image[0][texobj->BaseLevel];
  154.  
  155.          sampler->wrap_s = gl_wrap_xlate(texobj->WrapS);
  156.          sampler->wrap_t = gl_wrap_xlate(texobj->WrapT);
  157.          sampler->wrap_r = gl_wrap_xlate(texobj->WrapR);
  158.  
  159.          sampler->min_img_filter = gl_filter_to_img_filter(texobj->MinFilter);
  160.          sampler->min_mip_filter = gl_filter_to_mip_filter(texobj->MinFilter);
  161.          sampler->mag_img_filter = gl_filter_to_img_filter(texobj->MagFilter);
  162.  
  163.          if (texobj->Target != GL_TEXTURE_RECTANGLE_ARB)
  164.             sampler->normalized_coords = 1;
  165.  
  166.          sampler->lod_bias = st->ctx->Texture.Unit[su].LodBias;
  167.  
  168.          sampler->min_lod = texobj->BaseLevel + texobj->MinLod;
  169.          if (sampler->min_lod < texobj->BaseLevel)
  170.             sampler->min_lod = texobj->BaseLevel;
  171.  
  172.          sampler->max_lod = MIN2((GLfloat) texobj->MaxLevel,
  173.                                  (texobj->MaxLod + texobj->BaseLevel));
  174.          if (sampler->max_lod < sampler->min_lod) {
  175.             /* The GL spec doesn't seem to specify what to do in this case.
  176.              * Swap the values.
  177.              */
  178.             float tmp = sampler->max_lod;
  179.             sampler->max_lod = sampler->min_lod;
  180.             sampler->min_lod = tmp;
  181.             assert(sampler->min_lod <= sampler->max_lod);
  182.          }
  183.  
  184.          st_translate_color(texobj->BorderColor.f,
  185.                             teximg ? teximg->_BaseFormat : GL_RGBA,
  186.                             sampler->border_color);
  187.  
  188.          sampler->max_anisotropy = (texobj->MaxAnisotropy == 1.0 ? 0 : (GLuint)texobj->MaxAnisotropy);
  189.  
  190.          /* only care about ARB_shadow, not SGI shadow */
  191.          if (texobj->CompareMode == GL_COMPARE_R_TO_TEXTURE) {
  192.             sampler->compare_mode = PIPE_TEX_COMPARE_R_TO_TEXTURE;
  193.             sampler->compare_func
  194.                = st_compare_func_to_pipe(texobj->CompareFunc);
  195.          }
  196.  
  197.          st->state.num_samplers = su + 1;
  198.  
  199.          /*printf("%s su=%u non-null\n", __FUNCTION__, su);*/
  200.          cso_single_sampler(st->cso_context, su, sampler);
  201.          if (su < st->ctx->Const.MaxVertexTextureImageUnits) {
  202.             cso_single_vertex_sampler(st->cso_context, su, sampler);
  203.          }
  204.       }
  205.       else {
  206.          /*printf("%s su=%u null\n", __FUNCTION__, su);*/
  207.          cso_single_sampler(st->cso_context, su, NULL);
  208.          if (su < st->ctx->Const.MaxVertexTextureImageUnits) {
  209.             cso_single_vertex_sampler(st->cso_context, su, NULL);
  210.          }
  211.       }
  212.    }
  213.  
  214.    cso_single_sampler_done(st->cso_context);
  215.    if (st->ctx->Const.MaxVertexTextureImageUnits > 0) {
  216.       cso_single_vertex_sampler_done(st->cso_context);
  217.    }
  218. }
  219.  
  220.  
  221. const struct st_tracked_state st_update_sampler = {
  222.    "st_update_sampler",                                 /* name */
  223.    {                                                    /* dirty */
  224.       _NEW_TEXTURE,                                     /* mesa */
  225.       0,                                                /* st */
  226.    },
  227.    update_samplers                                      /* update */
  228. };
  229.