Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * Copyright © 2011 Intel Corporation
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the "Software"),
  6.  * to deal in the Software without restriction, including without limitation
  7.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8.  * and/or sell copies of the Software, and to permit persons to whom the
  9.  * Software is furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice (including the next
  12.  * paragraph) shall be included in all copies or substantial portions of the
  13.  * Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  18.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  21.  * IN THE SOFTWARE.
  22.  */
  23.  
  24. #include "brw_context.h"
  25. #include "brw_state.h"
  26. #include "brw_defines.h"
  27. #include "intel_batchbuffer.h"
  28.  
  29. #include "main/macros.h"
  30. #include "main/samplerobj.h"
  31.  
  32. /**
  33.  * Sets the sampler state for a single unit.
  34.  */
  35. static void
  36. gen7_update_sampler_state(struct brw_context *brw, int unit, int ss_index,
  37.                           struct gen7_sampler_state *sampler)
  38. {
  39.    struct gl_context *ctx = &brw->ctx;
  40.    struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
  41.    struct gl_texture_object *texObj = texUnit->_Current;
  42.    struct gl_sampler_object *gl_sampler = _mesa_get_samplerobj(ctx, unit);
  43.    bool using_nearest = false;
  44.  
  45.    /* These don't use samplers at all. */
  46.    if (texObj->Target == GL_TEXTURE_BUFFER)
  47.       return;
  48.  
  49.    switch (gl_sampler->MinFilter) {
  50.    case GL_NEAREST:
  51.       sampler->ss0.min_filter = BRW_MAPFILTER_NEAREST;
  52.       sampler->ss0.mip_filter = BRW_MIPFILTER_NONE;
  53.       using_nearest = true;
  54.       break;
  55.    case GL_LINEAR:
  56.       sampler->ss0.min_filter = BRW_MAPFILTER_LINEAR;
  57.       sampler->ss0.mip_filter = BRW_MIPFILTER_NONE;
  58.       break;
  59.    case GL_NEAREST_MIPMAP_NEAREST:
  60.       sampler->ss0.min_filter = BRW_MAPFILTER_NEAREST;
  61.       sampler->ss0.mip_filter = BRW_MIPFILTER_NEAREST;
  62.       break;
  63.    case GL_LINEAR_MIPMAP_NEAREST:
  64.       sampler->ss0.min_filter = BRW_MAPFILTER_LINEAR;
  65.       sampler->ss0.mip_filter = BRW_MIPFILTER_NEAREST;
  66.       break;
  67.    case GL_NEAREST_MIPMAP_LINEAR:
  68.       sampler->ss0.min_filter = BRW_MAPFILTER_NEAREST;
  69.       sampler->ss0.mip_filter = BRW_MIPFILTER_LINEAR;
  70.       break;
  71.    case GL_LINEAR_MIPMAP_LINEAR:
  72.       sampler->ss0.min_filter = BRW_MAPFILTER_LINEAR;
  73.       sampler->ss0.mip_filter = BRW_MIPFILTER_LINEAR;
  74.       break;
  75.    default:
  76.       break;
  77.    }
  78.  
  79.    /* Set Anisotropy: */
  80.    if (gl_sampler->MaxAnisotropy > 1.0) {
  81.       sampler->ss0.min_filter = BRW_MAPFILTER_ANISOTROPIC;
  82.       sampler->ss0.mag_filter = BRW_MAPFILTER_ANISOTROPIC;
  83.  
  84.       if (gl_sampler->MaxAnisotropy > 2.0) {
  85.          sampler->ss3.max_aniso = MIN2((gl_sampler->MaxAnisotropy - 2) / 2,
  86.                                        BRW_ANISORATIO_16);
  87.       }
  88.    }
  89.    else {
  90.       switch (gl_sampler->MagFilter) {
  91.       case GL_NEAREST:
  92.          sampler->ss0.mag_filter = BRW_MAPFILTER_NEAREST;
  93.          using_nearest = true;
  94.          break;
  95.       case GL_LINEAR:
  96.          sampler->ss0.mag_filter = BRW_MAPFILTER_LINEAR;
  97.          break;
  98.       default:
  99.          break;
  100.       }
  101.    }
  102.  
  103.    sampler->ss3.r_wrap_mode = translate_wrap_mode(gl_sampler->WrapR,
  104.                                                   using_nearest);
  105.    sampler->ss3.s_wrap_mode = translate_wrap_mode(gl_sampler->WrapS,
  106.                                                   using_nearest);
  107.    sampler->ss3.t_wrap_mode = translate_wrap_mode(gl_sampler->WrapT,
  108.                                                   using_nearest);
  109.  
  110.    /* Cube-maps on 965 and later must use the same wrap mode for all 3
  111.     * coordinate dimensions.  Futher, only CUBE and CLAMP are valid.
  112.     */
  113.    if (texObj->Target == GL_TEXTURE_CUBE_MAP ||
  114.        texObj->Target == GL_TEXTURE_CUBE_MAP_ARRAY) {
  115.       if (ctx->Texture.CubeMapSeamless &&
  116.           (gl_sampler->MinFilter != GL_NEAREST ||
  117.            gl_sampler->MagFilter != GL_NEAREST)) {
  118.          sampler->ss3.r_wrap_mode = BRW_TEXCOORDMODE_CUBE;
  119.          sampler->ss3.s_wrap_mode = BRW_TEXCOORDMODE_CUBE;
  120.          sampler->ss3.t_wrap_mode = BRW_TEXCOORDMODE_CUBE;
  121.       } else {
  122.          sampler->ss3.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
  123.          sampler->ss3.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
  124.          sampler->ss3.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
  125.       }
  126.    } else if (texObj->Target == GL_TEXTURE_1D) {
  127.       /* There's a bug in 1D texture sampling - it actually pays
  128.        * attention to the wrap_t value, though it should not.
  129.        * Override the wrap_t value here to GL_REPEAT to keep
  130.        * any nonexistent border pixels from floating in.
  131.        */
  132.       sampler->ss3.t_wrap_mode = BRW_TEXCOORDMODE_WRAP;
  133.    }
  134.  
  135.    /* Set shadow function: */
  136.    if (gl_sampler->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB) {
  137.       /* Shadowing is "enabled" by emitting a particular sampler
  138.        * message (sample_c).  So need to recompile WM program when
  139.        * shadow comparison is enabled on each/any texture unit.
  140.        */
  141.       sampler->ss1.shadow_function =
  142.          intel_translate_shadow_compare_func(gl_sampler->CompareFunc);
  143.    }
  144.  
  145.    /* Set LOD bias: */
  146.    sampler->ss0.lod_bias = S_FIXED(CLAMP(texUnit->LodBias +
  147.                                          gl_sampler->LodBias, -16, 15), 8);
  148.  
  149.    sampler->ss0.lod_preclamp = 1; /* OpenGL mode */
  150.    sampler->ss0.default_color_mode = 0; /* OpenGL/DX10 mode */
  151.  
  152.    /* Set BaseMipLevel, MaxLOD, MinLOD:
  153.     *
  154.     * XXX: I don't think that using firstLevel, lastLevel works,
  155.     * because we always setup the surface state as if firstLevel ==
  156.     * level zero.  Probably have to subtract firstLevel from each of
  157.     * these:
  158.     */
  159.    sampler->ss0.base_level = U_FIXED(0, 1);
  160.  
  161.    sampler->ss1.max_lod = U_FIXED(CLAMP(gl_sampler->MaxLod, 0, 13), 8);
  162.    sampler->ss1.min_lod = U_FIXED(CLAMP(gl_sampler->MinLod, 0, 13), 8);
  163.  
  164.    /* The sampler can handle non-normalized texture rectangle coordinates
  165.     * natively
  166.     */
  167.    if (texObj->Target == GL_TEXTURE_RECTANGLE) {
  168.       sampler->ss3.non_normalized_coord = 1;
  169.    }
  170.  
  171.    upload_default_color(brw, gl_sampler, unit, ss_index);
  172.  
  173.    sampler->ss2.default_color_pointer = brw->wm.sdc_offset[ss_index] >> 5;
  174.  
  175.    if (sampler->ss0.min_filter != BRW_MAPFILTER_NEAREST)
  176.       sampler->ss3.address_round |= BRW_ADDRESS_ROUNDING_ENABLE_U_MIN |
  177.                                     BRW_ADDRESS_ROUNDING_ENABLE_V_MIN |
  178.                                     BRW_ADDRESS_ROUNDING_ENABLE_R_MIN;
  179.    if (sampler->ss0.mag_filter != BRW_MAPFILTER_NEAREST)
  180.       sampler->ss3.address_round |= BRW_ADDRESS_ROUNDING_ENABLE_U_MAG |
  181.                                     BRW_ADDRESS_ROUNDING_ENABLE_V_MAG |
  182.                                     BRW_ADDRESS_ROUNDING_ENABLE_R_MAG;
  183. }
  184.  
  185.  
  186. static void
  187. gen7_upload_samplers(struct brw_context *brw)
  188. {
  189.    struct gl_context *ctx = &brw->ctx;
  190.    struct gen7_sampler_state *samplers;
  191.  
  192.    /* BRW_NEW_VERTEX_PROGRAM and BRW_NEW_FRAGMENT_PROGRAM */
  193.    struct gl_program *vs = (struct gl_program *) brw->vertex_program;
  194.    struct gl_program *fs = (struct gl_program *) brw->fragment_program;
  195.  
  196.    GLbitfield SamplersUsed = vs->SamplersUsed | fs->SamplersUsed;
  197.  
  198.    brw->sampler.count = _mesa_fls(SamplersUsed);
  199.  
  200.    if (brw->sampler.count == 0)
  201.       return;
  202.  
  203.    samplers = brw_state_batch(brw, AUB_TRACE_SAMPLER_STATE,
  204.                               brw->sampler.count * sizeof(*samplers),
  205.                               32, &brw->sampler.offset);
  206.    memset(samplers, 0, brw->sampler.count * sizeof(*samplers));
  207.  
  208.    for (unsigned s = 0; s < brw->sampler.count; s++) {
  209.       if (SamplersUsed & (1 << s)) {
  210.          const unsigned unit = (fs->SamplersUsed & (1 << s)) ?
  211.             fs->SamplerUnits[s] : vs->SamplerUnits[s];
  212.          if (ctx->Texture.Unit[unit]._ReallyEnabled)
  213.             gen7_update_sampler_state(brw, unit, s, &samplers[s]);
  214.       }
  215.    }
  216.  
  217.    brw->state.dirty.cache |= CACHE_NEW_SAMPLER;
  218. }
  219.  
  220. const struct brw_tracked_state gen7_samplers = {
  221.    .dirty = {
  222.       .mesa = _NEW_TEXTURE,
  223.       .brw = BRW_NEW_BATCH |
  224.              BRW_NEW_VERTEX_PROGRAM |
  225.              BRW_NEW_FRAGMENT_PROGRAM,
  226.       .cache = 0
  227.    },
  228.    .emit = gen7_upload_samplers,
  229. };
  230.