Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2003 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. #include "main/mtypes.h"
  29. #include "main/enums.h"
  30. #include "main/macros.h"
  31. #include "main/colormac.h"
  32. #include "main/samplerobj.h"
  33.  
  34. #include "intel_mipmap_tree.h"
  35. #include "intel_tex.h"
  36.  
  37. #include "i915_context.h"
  38. #include "i915_reg.h"
  39.  
  40.  
  41. static GLuint
  42. translate_texture_format(gl_format mesa_format, GLenum DepthMode)
  43. {
  44.    switch (mesa_format) {
  45.    case MESA_FORMAT_L8:
  46.       return MAPSURF_8BIT | MT_8BIT_L8;
  47.    case MESA_FORMAT_I8:
  48.       return MAPSURF_8BIT | MT_8BIT_I8;
  49.    case MESA_FORMAT_A8:
  50.    case MESA_FORMAT_R8:
  51.       return MAPSURF_8BIT | MT_8BIT_A8;
  52.    case MESA_FORMAT_AL88:
  53.       return MAPSURF_16BIT | MT_16BIT_AY88;
  54.    case MESA_FORMAT_RGB565:
  55.       return MAPSURF_16BIT | MT_16BIT_RGB565;
  56.    case MESA_FORMAT_ARGB1555:
  57.       return MAPSURF_16BIT | MT_16BIT_ARGB1555;
  58.    case MESA_FORMAT_ARGB4444:
  59.       return MAPSURF_16BIT | MT_16BIT_ARGB4444;
  60.    case MESA_FORMAT_SARGB8:
  61.    case MESA_FORMAT_ARGB8888:
  62.       return MAPSURF_32BIT | MT_32BIT_ARGB8888;
  63.    case MESA_FORMAT_XRGB8888:
  64.       return MAPSURF_32BIT | MT_32BIT_XRGB8888;
  65.    case MESA_FORMAT_RGBA8888_REV:
  66.       return MAPSURF_32BIT | MT_32BIT_ABGR8888;
  67.    case MESA_FORMAT_YCBCR_REV:
  68.       return (MAPSURF_422 | MT_422_YCRCB_NORMAL);
  69.    case MESA_FORMAT_YCBCR:
  70.       return (MAPSURF_422 | MT_422_YCRCB_SWAPY);
  71.    case MESA_FORMAT_RGB_FXT1:
  72.    case MESA_FORMAT_RGBA_FXT1:
  73.       return (MAPSURF_COMPRESSED | MT_COMPRESS_FXT1);
  74.    case MESA_FORMAT_Z16:
  75.       if (DepthMode == GL_ALPHA)
  76.           return (MAPSURF_16BIT | MT_16BIT_A16);
  77.       else if (DepthMode == GL_INTENSITY)
  78.           return (MAPSURF_16BIT | MT_16BIT_I16);
  79.       else
  80.           return (MAPSURF_16BIT | MT_16BIT_L16);
  81.    case MESA_FORMAT_RGBA_DXT1:
  82.    case MESA_FORMAT_RGB_DXT1:
  83.    case MESA_FORMAT_SRGB_DXT1:
  84.    case MESA_FORMAT_SRGBA_DXT1:
  85.       return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT1);
  86.    case MESA_FORMAT_RGBA_DXT3:
  87.    case MESA_FORMAT_SRGBA_DXT3:
  88.       return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT2_3);
  89.    case MESA_FORMAT_RGBA_DXT5:
  90.    case MESA_FORMAT_SRGBA_DXT5:
  91.       return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5);
  92.    case MESA_FORMAT_S8_Z24:
  93.    case MESA_FORMAT_X8_Z24:
  94.       if (DepthMode == GL_ALPHA)
  95.          return (MAPSURF_32BIT | MT_32BIT_x8A24);
  96.       else if (DepthMode == GL_INTENSITY)
  97.          return (MAPSURF_32BIT | MT_32BIT_x8I24);
  98.       else
  99.          return (MAPSURF_32BIT | MT_32BIT_x8L24);
  100.    default:
  101.       fprintf(stderr, "%s: bad image format %s\n", __FUNCTION__,
  102.               _mesa_get_format_name(mesa_format));
  103.       abort();
  104.       return 0;
  105.    }
  106. }
  107.  
  108.  
  109.  
  110.  
  111. /* The i915 (and related graphics cores) do not support GL_CLAMP.  The
  112.  * Intel drivers for "other operating systems" implement GL_CLAMP as
  113.  * GL_CLAMP_TO_EDGE, so the same is done here.
  114.  */
  115. static GLuint
  116. translate_wrap_mode(GLenum wrap)
  117. {
  118.    switch (wrap) {
  119.    case GL_REPEAT:
  120.       return TEXCOORDMODE_WRAP;
  121.    case GL_CLAMP:
  122.       return TEXCOORDMODE_CLAMP_EDGE;   /* not quite correct */
  123.    case GL_CLAMP_TO_EDGE:
  124.       return TEXCOORDMODE_CLAMP_EDGE;
  125.    case GL_CLAMP_TO_BORDER:
  126.       return TEXCOORDMODE_CLAMP_BORDER;
  127.    case GL_MIRRORED_REPEAT:
  128.       return TEXCOORDMODE_MIRROR;
  129.    default:
  130.       return TEXCOORDMODE_WRAP;
  131.    }
  132. }
  133.  
  134.  
  135.  
  136. /* Recalculate all state from scratch.  Perhaps not the most
  137.  * efficient, but this has gotten complex enough that we need
  138.  * something which is understandable and reliable.
  139.  */
  140. static bool
  141. i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
  142. {
  143.    struct gl_context *ctx = &intel->ctx;
  144.    struct i915_context *i915 = i915_context(ctx);
  145.    struct gl_texture_unit *tUnit = &ctx->Texture.Unit[unit];
  146.    struct gl_texture_object *tObj = tUnit->_Current;
  147.    struct intel_texture_object *intelObj = intel_texture_object(tObj);
  148.    struct gl_texture_image *firstImage;
  149.    struct gl_sampler_object *sampler = _mesa_get_samplerobj(ctx, unit);
  150.    GLuint *state = i915->state.Tex[unit], format;
  151.    GLint lodbias, aniso = 0;
  152.    GLubyte border[4];
  153.    GLfloat maxlod;
  154.  
  155.    memset(state, 0, sizeof(*state));
  156.  
  157.    /*We need to refcount these. */
  158.  
  159.    if (i915->state.tex_buffer[unit] != NULL) {
  160.        drm_intel_bo_unreference(i915->state.tex_buffer[unit]);
  161.        i915->state.tex_buffer[unit] = NULL;
  162.    }
  163.  
  164.    if (!intel_finalize_mipmap_tree(intel, unit))
  165.       return false;
  166.  
  167.    /* Get first image here, since intelObj->firstLevel will get set in
  168.     * the intel_finalize_mipmap_tree() call above.
  169.     */
  170.    firstImage = tObj->Image[0][tObj->BaseLevel];
  171.  
  172.    drm_intel_bo_reference(intelObj->mt->region->bo);
  173.    i915->state.tex_buffer[unit] = intelObj->mt->region->bo;
  174.    i915->state.tex_offset[unit] = intelObj->mt->offset;
  175.  
  176.    format = translate_texture_format(firstImage->TexFormat,
  177.                                      tObj->DepthMode);
  178.  
  179.    state[I915_TEXREG_MS3] =
  180.       (((firstImage->Height - 1) << MS3_HEIGHT_SHIFT) |
  181.        ((firstImage->Width - 1) << MS3_WIDTH_SHIFT) | format);
  182.  
  183.    if (intelObj->mt->region->tiling != I915_TILING_NONE) {
  184.       state[I915_TEXREG_MS3] |= MS3_TILED_SURFACE;
  185.       if (intelObj->mt->region->tiling == I915_TILING_Y)
  186.          state[I915_TEXREG_MS3] |= MS3_TILE_WALK;
  187.    }
  188.  
  189.    /* We get one field with fraction bits for the maximum addressable
  190.     * (lowest resolution) LOD.  Use it to cover both MAX_LEVEL and
  191.     * MAX_LOD.
  192.     */
  193.    maxlod = MIN2(sampler->MaxLod, tObj->_MaxLevel - tObj->BaseLevel);
  194.    state[I915_TEXREG_MS4] =
  195.       ((((intelObj->mt->region->pitch / 4) - 1) << MS4_PITCH_SHIFT) |
  196.        MS4_CUBE_FACE_ENA_MASK |
  197.        (U_FIXED(CLAMP(maxlod, 0.0, 11.0), 2) << MS4_MAX_LOD_SHIFT) |
  198.        ((firstImage->Depth - 1) << MS4_VOLUME_DEPTH_SHIFT));
  199.  
  200.  
  201.    {
  202.       GLuint minFilt, mipFilt, magFilt;
  203.  
  204.       switch (sampler->MinFilter) {
  205.       case GL_NEAREST:
  206.          minFilt = FILTER_NEAREST;
  207.          mipFilt = MIPFILTER_NONE;
  208.          break;
  209.       case GL_LINEAR:
  210.          minFilt = FILTER_LINEAR;
  211.          mipFilt = MIPFILTER_NONE;
  212.          break;
  213.       case GL_NEAREST_MIPMAP_NEAREST:
  214.          minFilt = FILTER_NEAREST;
  215.          mipFilt = MIPFILTER_NEAREST;
  216.          break;
  217.       case GL_LINEAR_MIPMAP_NEAREST:
  218.          minFilt = FILTER_LINEAR;
  219.          mipFilt = MIPFILTER_NEAREST;
  220.          break;
  221.       case GL_NEAREST_MIPMAP_LINEAR:
  222.          minFilt = FILTER_NEAREST;
  223.          mipFilt = MIPFILTER_LINEAR;
  224.          break;
  225.       case GL_LINEAR_MIPMAP_LINEAR:
  226.          minFilt = FILTER_LINEAR;
  227.          mipFilt = MIPFILTER_LINEAR;
  228.          break;
  229.       default:
  230.          return false;
  231.       }
  232.  
  233.       if (sampler->MaxAnisotropy > 1.0) {
  234.          minFilt = FILTER_ANISOTROPIC;
  235.          magFilt = FILTER_ANISOTROPIC;
  236.          if (sampler->MaxAnisotropy > 2.0)
  237.             aniso = SS2_MAX_ANISO_4;
  238.          else
  239.             aniso = SS2_MAX_ANISO_2;
  240.       }
  241.       else {
  242.          switch (sampler->MagFilter) {
  243.          case GL_NEAREST:
  244.             magFilt = FILTER_NEAREST;
  245.             break;
  246.          case GL_LINEAR:
  247.             magFilt = FILTER_LINEAR;
  248.             break;
  249.          default:
  250.             return false;
  251.          }
  252.       }
  253.  
  254.       lodbias = (int) ((tUnit->LodBias + sampler->LodBias) * 16.0);
  255.       if (lodbias < -256)
  256.           lodbias = -256;
  257.       if (lodbias > 255)
  258.           lodbias = 255;
  259.       state[I915_TEXREG_SS2] = ((lodbias << SS2_LOD_BIAS_SHIFT) &
  260.                                 SS2_LOD_BIAS_MASK);
  261.  
  262.       /* YUV conversion:
  263.        */
  264.       if (firstImage->TexFormat == MESA_FORMAT_YCBCR ||
  265.           firstImage->TexFormat == MESA_FORMAT_YCBCR_REV)
  266.          state[I915_TEXREG_SS2] |= SS2_COLORSPACE_CONVERSION;
  267.  
  268.       /* Shadow:
  269.        */
  270.       if (sampler->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB &&
  271.           tObj->Target != GL_TEXTURE_3D) {
  272.          if (tObj->Target == GL_TEXTURE_1D)
  273.             return false;
  274.  
  275.          state[I915_TEXREG_SS2] |=
  276.             (SS2_SHADOW_ENABLE |
  277.              intel_translate_shadow_compare_func(sampler->CompareFunc));
  278.  
  279.          minFilt = FILTER_4X4_FLAT;
  280.          magFilt = FILTER_4X4_FLAT;
  281.       }
  282.  
  283.       state[I915_TEXREG_SS2] |= ((minFilt << SS2_MIN_FILTER_SHIFT) |
  284.                                  (mipFilt << SS2_MIP_FILTER_SHIFT) |
  285.                                  (magFilt << SS2_MAG_FILTER_SHIFT) |
  286.                                  aniso);
  287.    }
  288.  
  289.    {
  290.       GLenum ws = sampler->WrapS;
  291.       GLenum wt = sampler->WrapT;
  292.       GLenum wr = sampler->WrapR;
  293.       float minlod;
  294.  
  295.       /* We program 1D textures as 2D textures, so the 2D texcoord could
  296.        * result in sampling border values if we don't set the T wrap to
  297.        * repeat.
  298.        */
  299.       if (tObj->Target == GL_TEXTURE_1D)
  300.          wt = GL_REPEAT;
  301.  
  302.       /* 3D textures don't seem to respect the border color.
  303.        * Fallback if there's ever a danger that they might refer to
  304.        * it.  
  305.        *
  306.        * Effectively this means fallback on 3D clamp or
  307.        * clamp_to_border.
  308.        */
  309.       if (tObj->Target == GL_TEXTURE_3D &&
  310.           (sampler->MinFilter != GL_NEAREST ||
  311.            sampler->MagFilter != GL_NEAREST) &&
  312.           (ws == GL_CLAMP ||
  313.            wt == GL_CLAMP ||
  314.            wr == GL_CLAMP ||
  315.            ws == GL_CLAMP_TO_BORDER ||
  316.            wt == GL_CLAMP_TO_BORDER || wr == GL_CLAMP_TO_BORDER))
  317.          return false;
  318.  
  319.       /* Only support TEXCOORDMODE_CLAMP_EDGE and TEXCOORDMODE_CUBE (not
  320.        * used) when using cube map texture coordinates
  321.        */
  322.       if (tObj->Target == GL_TEXTURE_CUBE_MAP_ARB &&
  323.           (((ws != GL_CLAMP) && (ws != GL_CLAMP_TO_EDGE)) ||
  324.            ((wt != GL_CLAMP) && (wt != GL_CLAMP_TO_EDGE))))
  325.           return false;
  326.  
  327.       /*
  328.        * According to 3DSTATE_MAP_STATE at page of 104 in Bspec
  329.        * Vol3d 3D Instructions:
  330.        *   [DevGDG and DevAlv]: Must be a power of 2 for cube maps.
  331.        *   [DevLPT, DevCST and DevBLB]: If not a power of 2, cube maps
  332.        *      must have all faces enabled.
  333.        *
  334.        * But, as I tested on pineview(DevBLB derived), the rendering is
  335.        * bad(you will find the color isn't samplered right in some
  336.        * fragments). After checking, it seems that the texture layout is
  337.        * wrong: making the width and height align of 4(although this
  338.        * doesn't make much sense) will fix this issue and also broke some
  339.        * others. Well, Bspec mentioned nothing about the layout alignment
  340.        * and layout for NPOT cube map.  I guess the Bspec just assume it's
  341.        * a POT cube map.
  342.        *
  343.        * Thus, I guess we need do this for other platforms as well.
  344.        */
  345.       if (tObj->Target == GL_TEXTURE_CUBE_MAP_ARB &&
  346.           !is_power_of_two(firstImage->Height))
  347.          return false;
  348.  
  349.       state[I915_TEXREG_SS3] = ss3;     /* SS3_NORMALIZED_COORDS */
  350.  
  351.       state[I915_TEXREG_SS3] |=
  352.          ((translate_wrap_mode(ws) << SS3_TCX_ADDR_MODE_SHIFT) |
  353.           (translate_wrap_mode(wt) << SS3_TCY_ADDR_MODE_SHIFT) |
  354.           (translate_wrap_mode(wr) << SS3_TCZ_ADDR_MODE_SHIFT));
  355.  
  356.       minlod = MIN2(sampler->MinLod, tObj->_MaxLevel - tObj->BaseLevel);
  357.       state[I915_TEXREG_SS3] |= (unit << SS3_TEXTUREMAP_INDEX_SHIFT);
  358.       state[I915_TEXREG_SS3] |= (U_FIXED(CLAMP(minlod, 0.0, 11.0), 4) <<
  359.                                  SS3_MIN_LOD_SHIFT);
  360.  
  361.    }
  362.  
  363.    if (sampler->sRGBDecode == GL_DECODE_EXT &&
  364.        (_mesa_get_srgb_format_linear(firstImage->TexFormat) !=
  365.         firstImage->TexFormat)) {
  366.       state[I915_TEXREG_SS2] |= SS2_REVERSE_GAMMA_ENABLE;
  367.    }
  368.  
  369.    /* convert border color from float to ubyte */
  370.    CLAMPED_FLOAT_TO_UBYTE(border[0], sampler->BorderColor.f[0]);
  371.    CLAMPED_FLOAT_TO_UBYTE(border[1], sampler->BorderColor.f[1]);
  372.    CLAMPED_FLOAT_TO_UBYTE(border[2], sampler->BorderColor.f[2]);
  373.    CLAMPED_FLOAT_TO_UBYTE(border[3], sampler->BorderColor.f[3]);
  374.  
  375.    if (firstImage->_BaseFormat == GL_DEPTH_COMPONENT) {
  376.       /* GL specs that border color for depth textures is taken from the
  377.        * R channel, while the hardware uses A.  Spam R into all the channels
  378.        * for safety.
  379.        */
  380.       state[I915_TEXREG_SS4] = PACK_COLOR_8888(border[0],
  381.                                                border[0],
  382.                                                border[0],
  383.                                                border[0]);
  384.    } else {
  385.       state[I915_TEXREG_SS4] = PACK_COLOR_8888(border[3],
  386.                                                border[0],
  387.                                                border[1],
  388.                                                border[2]);
  389.    }
  390.  
  391.  
  392.    I915_ACTIVESTATE(i915, I915_UPLOAD_TEX(unit), true);
  393.    /* memcmp was already disabled, but definitely won't work as the
  394.     * region might now change and that wouldn't be detected:
  395.     */
  396.    I915_STATECHANGE(i915, I915_UPLOAD_TEX(unit));
  397.  
  398.  
  399. #if 0
  400.    DBG(TEXTURE, "state[I915_TEXREG_SS2] = 0x%x\n", state[I915_TEXREG_SS2]);
  401.    DBG(TEXTURE, "state[I915_TEXREG_SS3] = 0x%x\n", state[I915_TEXREG_SS3]);
  402.    DBG(TEXTURE, "state[I915_TEXREG_SS4] = 0x%x\n", state[I915_TEXREG_SS4]);
  403.    DBG(TEXTURE, "state[I915_TEXREG_MS2] = 0x%x\n", state[I915_TEXREG_MS2]);
  404.    DBG(TEXTURE, "state[I915_TEXREG_MS3] = 0x%x\n", state[I915_TEXREG_MS3]);
  405.    DBG(TEXTURE, "state[I915_TEXREG_MS4] = 0x%x\n", state[I915_TEXREG_MS4]);
  406. #endif
  407.  
  408.    return true;
  409. }
  410.  
  411.  
  412.  
  413.  
  414. void
  415. i915UpdateTextureState(struct intel_context *intel)
  416. {
  417.    bool ok = true;
  418.    GLuint i;
  419.  
  420.    for (i = 0; i < I915_TEX_UNITS && ok; i++) {
  421.       switch (intel->ctx.Texture.Unit[i]._ReallyEnabled) {
  422.       case TEXTURE_1D_BIT:
  423.       case TEXTURE_2D_BIT:
  424.       case TEXTURE_CUBE_BIT:
  425.       case TEXTURE_3D_BIT:
  426.          ok = i915_update_tex_unit(intel, i, SS3_NORMALIZED_COORDS);
  427.          break;
  428.       case TEXTURE_RECT_BIT:
  429.          ok = i915_update_tex_unit(intel, i, 0);
  430.          break;
  431.       case 0:{
  432.             struct i915_context *i915 = i915_context(&intel->ctx);
  433.             if (i915->state.active & I915_UPLOAD_TEX(i))
  434.                I915_ACTIVESTATE(i915, I915_UPLOAD_TEX(i), false);
  435.  
  436.             if (i915->state.tex_buffer[i] != NULL) {
  437.                drm_intel_bo_unreference(i915->state.tex_buffer[i]);
  438.                i915->state.tex_buffer[i] = NULL;
  439.             }
  440.  
  441.             break;
  442.          }
  443.       default:
  444.          ok = false;
  445.          break;
  446.       }
  447.    }
  448.  
  449.    FALLBACK(intel, I915_FALLBACK_TEXTURE, !ok);
  450. }
  451.