Subversion Repositories Kolibri OS

Rev

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