Home | History | Annotate | Download | only in i915
      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