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