brw_urb.c

Go to the documentation of this file.
00001 /*
00002  Copyright (C) Intel Corp.  2006.  All Rights Reserved.
00003  Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
00004  develop this 3D driver.
00005 
00006  Permission is hereby granted, free of charge, to any person obtaining
00007  a copy of this software and associated documentation files (the
00008  "Software"), to deal in the Software without restriction, including
00009  without limitation the rights to use, copy, modify, merge, publish,
00010  distribute, sublicense, and/or sell copies of the Software, and to
00011  permit persons to whom the Software is furnished to do so, subject to
00012  the following conditions:
00013 
00014  The above copyright notice and this permission notice (including the
00015  next paragraph) shall be included in all copies or substantial
00016  portions of the Software.
00017 
00018  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00019  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00020  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00021  IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
00022  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00023  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00024  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00025 
00026  **********************************************************************/
00027  /*
00028   * Authors:
00029   *   Keith Whitwell <keith@tungstengraphics.com>
00030   */
00031 
00032 
00033 #include "brw_context.h"
00034 //#include "brw_state.h"
00035 #include "brw_batch.h"
00036 #include "brw_defines.h"
00037 
00038 #define VS 0
00039 #define GS 1
00040 #define CLP 2
00041 #define SF 3
00042 #define CS 4
00043 
00044 /* XXX: Are the min_entry_size numbers useful?
00045  * XXX: Verify min_nr_entries, esp for VS.
00046  * XXX: Verify SF min_entry_size.
00047  */
00048 static const struct {
00049    unsigned min_nr_entries;
00050    unsigned preferred_nr_entries;
00051    unsigned min_entry_size;
00052    unsigned max_entry_size;
00053 } limits[CS+1] = {
00054    { 8, 32, 1, 5 },                     /* vs */
00055    { 4, 8,  1, 5 },                     /* gs */
00056    { 6, 8,  1, 5 },                     /* clp */
00057    { 1, 8,  1, 12 },                    /* sf */
00058    { 1, 4,  1, 32 }                     /* cs */
00059 };
00060 
00061 
00062 static boolean check_urb_layout( struct brw_context *brw )
00063 {
00064    brw->urb.vs_start = 0;
00065    brw->urb.gs_start = brw->urb.nr_vs_entries * brw->urb.vsize;
00066    brw->urb.clip_start = brw->urb.gs_start + brw->urb.nr_gs_entries * brw->urb.vsize;
00067    brw->urb.sf_start = brw->urb.clip_start + brw->urb.nr_clip_entries * brw->urb.vsize;
00068    brw->urb.cs_start = brw->urb.sf_start + brw->urb.nr_sf_entries * brw->urb.sfsize;
00069 
00070    return brw->urb.cs_start + brw->urb.nr_cs_entries * brw->urb.csize <= 256;
00071 }
00072 
00073 /* Most minimal update, forces re-emit of URB fence packet after GS
00074  * unit turned on/off.
00075  */
00076 static void recalculate_urb_fence( struct brw_context *brw )
00077 {
00078    unsigned csize = brw->curbe.total_size;
00079    unsigned vsize = brw->vs.prog_data->urb_entry_size;
00080    unsigned sfsize = brw->sf.prog_data->urb_entry_size;
00081 
00082    if (csize < limits[CS].min_entry_size)
00083       csize = limits[CS].min_entry_size;
00084 
00085    if (vsize < limits[VS].min_entry_size)
00086       vsize = limits[VS].min_entry_size;
00087 
00088    if (sfsize < limits[SF].min_entry_size)
00089       sfsize = limits[SF].min_entry_size;
00090 
00091    if (brw->urb.vsize < vsize ||
00092        brw->urb.sfsize < sfsize ||
00093        brw->urb.csize < csize ||
00094        (brw->urb.constrained && (brw->urb.vsize > brw->urb.vsize ||
00095                                  brw->urb.sfsize > brw->urb.sfsize ||
00096                                  brw->urb.csize > brw->urb.csize))) {
00097 
00098 
00099       brw->urb.csize = csize;
00100       brw->urb.sfsize = sfsize;
00101       brw->urb.vsize = vsize;
00102 
00103       brw->urb.nr_vs_entries = limits[VS].preferred_nr_entries;
00104       brw->urb.nr_gs_entries = limits[GS].preferred_nr_entries;
00105       brw->urb.nr_clip_entries = limits[CLP].preferred_nr_entries;
00106       brw->urb.nr_sf_entries = limits[SF].preferred_nr_entries;
00107       brw->urb.nr_cs_entries = limits[CS].preferred_nr_entries;
00108 
00109       if (!check_urb_layout(brw)) {
00110          brw->urb.nr_vs_entries = limits[VS].min_nr_entries;
00111          brw->urb.nr_gs_entries = limits[GS].min_nr_entries;
00112          brw->urb.nr_clip_entries = limits[CLP].min_nr_entries;
00113          brw->urb.nr_sf_entries = limits[SF].min_nr_entries;
00114          brw->urb.nr_cs_entries = limits[CS].min_nr_entries;
00115 
00116          brw->urb.constrained = 1;
00117 
00118          if (!check_urb_layout(brw)) {
00119             /* This is impossible, given the maximal sizes of urb
00120              * entries and the values for minimum nr of entries
00121              * provided above.
00122              */
00123             debug_printf("couldn't calculate URB layout!\n");
00124             exit(1);
00125          }
00126 
00127          if (BRW_DEBUG & (DEBUG_URB|DEBUG_FALLBACKS))
00128             debug_printf("URB CONSTRAINED\n");
00129       }
00130       else
00131          brw->urb.constrained = 0;
00132 
00133       if (BRW_DEBUG & DEBUG_URB)
00134          debug_printf("URB fence: %d ..VS.. %d ..GS.. %d ..CLP.. %d ..SF.. %d ..CS.. %d\n",
00135                       brw->urb.vs_start,
00136                       brw->urb.gs_start,
00137                       brw->urb.clip_start,
00138                       brw->urb.sf_start,
00139                       brw->urb.cs_start,
00140                       256);
00141 
00142       brw->state.dirty.brw |= BRW_NEW_URB_FENCE;
00143    }
00144 }
00145 
00146 
00147 const struct brw_tracked_state brw_recalculate_urb_fence = {
00148    .dirty = {
00149       .brw = BRW_NEW_CURBE_OFFSETS,
00150       .cache = (CACHE_NEW_VS_PROG |
00151                 CACHE_NEW_SF_PROG)
00152    },
00153    .update = recalculate_urb_fence
00154 };
00155 
00156 
00157 
00158 
00159 
00160 void brw_upload_urb_fence(struct brw_context *brw)
00161 {
00162    struct brw_urb_fence uf;
00163    memset(&uf, 0, sizeof(uf));
00164 
00165    uf.header.opcode = CMD_URB_FENCE;
00166    uf.header.length = sizeof(uf)/4-2;
00167    uf.header.vs_realloc = 1;
00168    uf.header.gs_realloc = 1;
00169    uf.header.clp_realloc = 1;
00170    uf.header.sf_realloc = 1;
00171    uf.header.vfe_realloc = 1;
00172    uf.header.cs_realloc = 1;
00173 
00174    /* The ordering below is correct, not the layout in the
00175     * instruction.
00176     *
00177     * There are 256 urb reg pairs in total.
00178     */
00179    uf.bits0.vs_fence  = brw->urb.gs_start;
00180    uf.bits0.gs_fence  = brw->urb.clip_start;
00181    uf.bits0.clp_fence = brw->urb.sf_start;
00182    uf.bits1.sf_fence  = brw->urb.cs_start;
00183    uf.bits1.cs_fence  = 256;
00184 
00185    BRW_BATCH_STRUCT(brw, &uf);
00186 }

Generated on Tue Sep 29 06:25:17 2009 for Gallium3D by  doxygen 1.5.4