Subversion Repositories Kolibri OS

Rev

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