00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "brw_defines.h"
00033 #include "brw_context.h"
00034 #include "brw_eu.h"
00035 #include "brw_util.h"
00036 #include "brw_state.h"
00037 #include "brw_gs.h"
00038
00039
00040
00041 static void compile_gs_prog( struct brw_context *brw,
00042 struct brw_gs_prog_key *key )
00043 {
00044 struct brw_gs_compile c;
00045 const unsigned *program;
00046 unsigned program_size;
00047
00048 memset(&c, 0, sizeof(c));
00049
00050 c.key = *key;
00051
00052
00053
00054
00055 c.nr_attrs = brw_count_bits(c.key.attrs);
00056 c.nr_regs = (c.nr_attrs + 1) / 2 + 1;
00057 c.nr_bytes = c.nr_regs * REG_SIZE;
00058
00059
00060
00061
00062 brw_init_compile(&c.func);
00063
00064 c.func.single_program_flow = 1;
00065
00066
00067
00068
00069 brw_set_mask_control(&c.func, BRW_MASK_DISABLE);
00070
00071
00072
00073
00074
00075 switch (key->primitive) {
00076 case PIPE_PRIM_QUADS:
00077 brw_gs_quads( &c );
00078 break;
00079 case PIPE_PRIM_QUAD_STRIP:
00080 brw_gs_quad_strip( &c );
00081 break;
00082 case PIPE_PRIM_LINE_LOOP:
00083 brw_gs_lines( &c );
00084 break;
00085 case PIPE_PRIM_LINES:
00086 if (key->hint_gs_always)
00087 brw_gs_lines( &c );
00088 else {
00089 return;
00090 }
00091 break;
00092 case PIPE_PRIM_TRIANGLES:
00093 if (key->hint_gs_always)
00094 brw_gs_tris( &c );
00095 else {
00096 return;
00097 }
00098 break;
00099 case PIPE_PRIM_POINTS:
00100 if (key->hint_gs_always)
00101 brw_gs_points( &c );
00102 else {
00103 return;
00104 }
00105 break;
00106 default:
00107 return;
00108 }
00109
00110
00111
00112 program = brw_get_program(&c.func, &program_size);
00113
00114
00115
00116 brw->gs.prog_gs_offset = brw_upload_cache( &brw->cache[BRW_GS_PROG],
00117 &c.key,
00118 sizeof(c.key),
00119 program,
00120 program_size,
00121 &c.prog_data,
00122 &brw->gs.prog_data );
00123 }
00124
00125
00126 static boolean search_cache( struct brw_context *brw,
00127 struct brw_gs_prog_key *key )
00128 {
00129 return brw_search_cache(&brw->cache[BRW_GS_PROG],
00130 key, sizeof(*key),
00131 &brw->gs.prog_data,
00132 &brw->gs.prog_gs_offset);
00133 }
00134
00135
00136 static const int gs_prim[PIPE_PRIM_POLYGON+1] = {
00137 PIPE_PRIM_POINTS,
00138 PIPE_PRIM_LINES,
00139 PIPE_PRIM_LINE_LOOP,
00140 PIPE_PRIM_LINES,
00141 PIPE_PRIM_TRIANGLES,
00142 PIPE_PRIM_TRIANGLES,
00143 PIPE_PRIM_TRIANGLES,
00144 PIPE_PRIM_QUADS,
00145 PIPE_PRIM_QUAD_STRIP,
00146 PIPE_PRIM_TRIANGLES
00147 };
00148
00149 static void populate_key( struct brw_context *brw,
00150 struct brw_gs_prog_key *key )
00151 {
00152 memset(key, 0, sizeof(*key));
00153
00154
00155 key->attrs = brw->vs.prog_data->outputs_written;
00156
00157
00158 key->primitive = gs_prim[brw->primitive];
00159
00160 key->hint_gs_always = 0;
00161
00162 key->need_gs_prog = (key->hint_gs_always ||
00163 brw->primitive == PIPE_PRIM_QUADS ||
00164 brw->primitive == PIPE_PRIM_QUAD_STRIP ||
00165 brw->primitive == PIPE_PRIM_LINE_LOOP);
00166 }
00167
00168
00169
00170 static void upload_gs_prog( struct brw_context *brw )
00171 {
00172 struct brw_gs_prog_key key;
00173
00174
00175
00176 populate_key(brw, &key);
00177
00178 if (brw->gs.prog_active != key.need_gs_prog) {
00179 brw->state.dirty.cache |= CACHE_NEW_GS_PROG;
00180 brw->gs.prog_active = key.need_gs_prog;
00181 }
00182
00183 if (brw->gs.prog_active) {
00184 if (!search_cache(brw, &key))
00185 compile_gs_prog( brw, &key );
00186 }
00187 }
00188
00189
00190 const struct brw_tracked_state brw_gs_prog = {
00191 .dirty = {
00192 .brw = BRW_NEW_PRIMITIVE,
00193 .cache = CACHE_NEW_VS_PROG
00194 },
00195 .update = upload_gs_prog
00196 };