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.  
  29. #include "util/u_memory.h"
  30. #include "pipe/p_shader_tokens.h"
  31. #include "draw/draw_context.h"
  32. #include "draw/draw_vertex.h"
  33. #include "i915_context.h"
  34. #include "i915_state.h"
  35. #include "i915_debug.h"
  36. #include "i915_fpc.h"
  37. #include "i915_reg.h"
  38.  
  39. static uint find_mapping(const struct i915_fragment_shader* fs, int unit)
  40. {
  41.    int i;
  42.    for (i = 0; i < I915_TEX_UNITS ; i++)
  43.    {
  44.       if (fs->generic_mapping[i] == unit)
  45.          return i;
  46.    }
  47.    debug_printf("Mapping not found\n");
  48.    return 0;
  49. }
  50.  
  51.  
  52.  
  53. /***********************************************************************
  54.  * Determine the hardware vertex layout.
  55.  * Depends on vertex/fragment shader state.
  56.  */
  57. static void calculate_vertex_layout(struct i915_context *i915)
  58. {
  59.    const struct i915_fragment_shader *fs = i915->fs;
  60.    const enum interp_mode colorInterp = i915->rasterizer->color_interp;
  61.    struct vertex_info vinfo;
  62.    boolean texCoords[I915_TEX_UNITS], colors[2], fog, needW, face;
  63.    uint i;
  64.    int src;
  65.  
  66.    memset(texCoords, 0, sizeof(texCoords));
  67.    colors[0] = colors[1] = fog = needW = face = FALSE;
  68.    memset(&vinfo, 0, sizeof(vinfo));
  69.  
  70.    /* Determine which fragment program inputs are needed.  Setup HW vertex
  71.     * layout below, in the HW-specific attribute order.
  72.     */
  73.    for (i = 0; i < fs->info.num_inputs; i++) {
  74.       switch (fs->info.input_semantic_name[i]) {
  75.       case TGSI_SEMANTIC_POSITION:
  76.          {
  77.             uint unit = I915_SEMANTIC_POS;
  78.             texCoords[find_mapping(fs, unit)] = TRUE;
  79.          }
  80.          break;
  81.       case TGSI_SEMANTIC_COLOR:
  82.          assert(fs->info.input_semantic_index[i] < 2);
  83.          colors[fs->info.input_semantic_index[i]] = TRUE;
  84.          break;
  85.       case TGSI_SEMANTIC_GENERIC:
  86.          {
  87.             /* texcoords/varyings/other generic */
  88.             uint unit = fs->info.input_semantic_index[i];
  89.  
  90.             texCoords[find_mapping(fs, unit)] = TRUE;
  91.             needW = TRUE;
  92.          }
  93.          break;
  94.       case TGSI_SEMANTIC_FOG:
  95.          fog = TRUE;
  96.          break;
  97.       case TGSI_SEMANTIC_FACE:
  98.          face = TRUE;
  99.          break;
  100.       default:
  101.          debug_printf("Unknown input type %d\n", fs->info.input_semantic_name[i]);
  102.          assert(0);
  103.       }
  104.    }
  105.  
  106.  
  107.    /* pos */
  108.    src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_POSITION, 0);
  109.    if (needW) {
  110.       draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src);
  111.       vinfo.hwfmt[0] |= S4_VFMT_XYZW;
  112.       vinfo.attrib[0].emit = EMIT_4F;
  113.    }
  114.    else {
  115.       draw_emit_vertex_attr(&vinfo, EMIT_3F, INTERP_LINEAR, src);
  116.       vinfo.hwfmt[0] |= S4_VFMT_XYZ;
  117.       vinfo.attrib[0].emit = EMIT_3F;
  118.    }
  119.  
  120.    /* hardware point size */
  121.    /* XXX todo */
  122.  
  123.    /* primary color */
  124.    if (colors[0]) {
  125.       src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_COLOR, 0);
  126.       draw_emit_vertex_attr(&vinfo, EMIT_4UB_BGRA, colorInterp, src);
  127.       vinfo.hwfmt[0] |= S4_VFMT_COLOR;
  128.    }
  129.  
  130.    /* secondary color */
  131.    if (colors[1]) {
  132.       src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_COLOR, 1);
  133.       draw_emit_vertex_attr(&vinfo, EMIT_4UB_BGRA, colorInterp, src);
  134.       vinfo.hwfmt[0] |= S4_VFMT_SPEC_FOG;
  135.    }
  136.  
  137.    /* fog coord, not fog blend factor */
  138.    if (fog) {
  139.       src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_FOG, 0);
  140.       draw_emit_vertex_attr(&vinfo, EMIT_1F, INTERP_PERSPECTIVE, src);
  141.       vinfo.hwfmt[0] |= S4_VFMT_FOG_PARAM;
  142.    }
  143.  
  144.    /* texcoords/varyings */
  145.    for (i = 0; i < I915_TEX_UNITS; i++) {
  146.       uint hwtc;
  147.       if (texCoords[i]) {
  148.          hwtc = TEXCOORDFMT_4D;
  149.          src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_GENERIC, fs->generic_mapping[i]);
  150.          draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
  151.       }
  152.       else {
  153.          hwtc = TEXCOORDFMT_NOT_PRESENT;
  154.       }
  155.       vinfo.hwfmt[1] |= hwtc << (i * 4);
  156.    }
  157.  
  158.    /* front/back face */
  159.    if (face) {
  160.       uint slot = find_mapping(fs, I915_SEMANTIC_FACE);
  161.       debug_printf("Front/back face is broken\n");
  162.       /* XXX Because of limitations in the draw module, currently src will be 0
  163.        * for SEMANTIC_FACE, so this aliases to POS. We need to fix in the draw
  164.        * module by adding an extra shader output.
  165.        */
  166.       src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_FACE, 0);
  167.       draw_emit_vertex_attr(&vinfo, EMIT_1F, INTERP_CONSTANT, src);
  168.       vinfo.hwfmt[1] &= ~(TEXCOORDFMT_NOT_PRESENT << (slot * 4));
  169.       vinfo.hwfmt[1] |= TEXCOORDFMT_1D << (slot * 4);
  170.    }
  171.  
  172.    draw_compute_vertex_size(&vinfo);
  173.  
  174.    if (memcmp(&i915->current.vertex_info, &vinfo, sizeof(vinfo))) {
  175.       /* Need to set this flag so that the LIS2/4 registers get set.
  176.        * It also means the i915_update_immediate() function must be called
  177.        * after this one, in i915_update_derived().
  178.        */
  179.       i915->dirty |= I915_NEW_VERTEX_FORMAT;
  180.  
  181.       memcpy(&i915->current.vertex_info, &vinfo, sizeof(vinfo));
  182.    }
  183. }
  184.  
  185. struct i915_tracked_state i915_update_vertex_layout = {
  186.    "vertex_layout",
  187.    calculate_vertex_layout,
  188.    I915_NEW_RASTERIZER | I915_NEW_FS | I915_NEW_VS
  189. };
  190.  
  191.  
  192.  
  193. /***********************************************************************
  194.  */
  195. static struct i915_tracked_state *atoms[] = {
  196.    &i915_update_vertex_layout,
  197.    &i915_hw_samplers,
  198.    &i915_hw_sampler_views,
  199.    &i915_hw_immediate,
  200.    &i915_hw_dynamic,
  201.    &i915_hw_fs,
  202.    &i915_hw_framebuffer,
  203.    &i915_hw_dst_buf_vars,
  204.    &i915_hw_constants,
  205.    NULL,
  206. };
  207.  
  208. void i915_update_derived(struct i915_context *i915)
  209. {
  210.    int i;
  211.  
  212.    if (I915_DBG_ON(DBG_ATOMS))
  213.       i915_dump_dirty(i915, __FUNCTION__);
  214.  
  215.    for (i = 0; atoms[i]; i++)
  216.       if (atoms[i]->dirty & i915->dirty)
  217.          atoms[i]->update(i915);
  218.  
  219.    i915->dirty = 0;
  220. }
  221.