• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
3  * Copyright 2009 Marek Olšák <maraeo@gmail.com>
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * on the rights to use, copy, modify, merge, publish, distribute, sub
9  * license, and/or sell copies of the Software, and to permit persons to whom
10  * the Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22  * USE OR OTHER DEALINGS IN THE SOFTWARE. */
23 
24 #include "draw/draw_context.h"
25 
26 #include "util/u_math.h"
27 #include "util/u_memory.h"
28 #include "util/u_pack_color.h"
29 
30 #include "r300_context.h"
31 #include "r300_fs.h"
32 #include "r300_screen.h"
33 #include "r300_shader_semantics.h"
34 #include "r300_state_inlines.h"
35 #include "r300_texture.h"
36 #include "r300_vs.h"
37 
38 /* r300_state_derived: Various bits of state which are dependent upon
39  * currently bound CSO data. */
40 
41 enum r300_rs_swizzle {
42     SWIZ_XYZW = 0,
43     SWIZ_X001,
44     SWIZ_XY01,
45     SWIZ_0001,
46 };
47 
48 enum r300_rs_col_write_type {
49     WRITE_COLOR = 0,
50     WRITE_FACE
51 };
52 
r300_draw_emit_attrib(struct r300_context * r300,enum attrib_emit emit,int index)53 static void r300_draw_emit_attrib(struct r300_context* r300,
54                                   enum attrib_emit emit,
55                                   int index)
56 {
57     struct r300_vertex_shader* vs = r300->vs_state.state;
58     struct tgsi_shader_info* info = &vs->info;
59     int output;
60 
61     output = draw_find_shader_output(r300->draw,
62                                      info->output_semantic_name[index],
63                                      info->output_semantic_index[index]);
64     draw_emit_vertex_attr(&r300->vertex_info, emit, output);
65 }
66 
r300_draw_emit_all_attribs(struct r300_context * r300)67 static void r300_draw_emit_all_attribs(struct r300_context* r300)
68 {
69     struct r300_vertex_shader* vs = r300->vs_state.state;
70     struct r300_shader_semantics* vs_outputs = &vs->outputs;
71     int i, gen_count;
72 
73     /* Position. */
74     if (vs_outputs->pos != ATTR_UNUSED) {
75         r300_draw_emit_attrib(r300, EMIT_4F, vs_outputs->pos);
76     } else {
77         assert(0);
78     }
79 
80     /* Point size. */
81     if (vs_outputs->psize != ATTR_UNUSED) {
82         r300_draw_emit_attrib(r300, EMIT_1F_PSIZE, vs_outputs->psize);
83     }
84 
85     /* Colors. */
86     for (i = 0; i < ATTR_COLOR_COUNT; i++) {
87         if (vs_outputs->color[i] != ATTR_UNUSED) {
88             r300_draw_emit_attrib(r300, EMIT_4F, vs_outputs->color[i]);
89         }
90     }
91 
92     /* Back-face colors. */
93     for (i = 0; i < ATTR_COLOR_COUNT; i++) {
94         if (vs_outputs->bcolor[i] != ATTR_UNUSED) {
95             r300_draw_emit_attrib(r300, EMIT_4F, vs_outputs->bcolor[i]);
96         }
97     }
98 
99     /* Texture coordinates. */
100     /* Only 8 generic vertex attributes can be used. If there are more,
101      * they won't be rasterized. */
102     gen_count = 0;
103     for (i = 0; i < ATTR_GENERIC_COUNT && gen_count < 8; i++) {
104         if (vs_outputs->generic[i] != ATTR_UNUSED &&
105             !(r300->sprite_coord_enable & (1 << i))) {
106             r300_draw_emit_attrib(r300, EMIT_4F, vs_outputs->generic[i]);
107             gen_count++;
108         }
109     }
110 
111     /* Fog coordinates. */
112     if (gen_count < 8 && vs_outputs->fog != ATTR_UNUSED) {
113         r300_draw_emit_attrib(r300, EMIT_4F, vs_outputs->fog);
114         gen_count++;
115     }
116 
117     /* WPOS. */
118     if (r300_fs(r300)->shader->inputs.wpos != ATTR_UNUSED && gen_count < 8) {
119         DBG(r300, DBG_SWTCL, "draw_emit_attrib: WPOS, index: %i\n",
120             vs_outputs->wpos);
121         r300_draw_emit_attrib(r300, EMIT_4F, vs_outputs->wpos);
122     }
123 }
124 
125 /* Update the PSC tables for SW TCL, using Draw. */
r300_swtcl_vertex_psc(struct r300_context * r300)126 static void r300_swtcl_vertex_psc(struct r300_context *r300)
127 {
128     struct r300_vertex_stream_state *vstream = r300->vertex_stream_state.state;
129     struct vertex_info *vinfo = &r300->vertex_info;
130     uint16_t type, swizzle;
131     enum pipe_format format;
132     unsigned i, attrib_count;
133     int* vs_output_tab = r300->stream_loc_notcl;
134 
135     memset(vstream, 0, sizeof(struct r300_vertex_stream_state));
136 
137     /* For each Draw attribute, route it to the fragment shader according
138      * to the vs_output_tab. */
139     attrib_count = vinfo->num_attribs;
140     DBG(r300, DBG_SWTCL, "r300: attrib count: %d\n", attrib_count);
141     for (i = 0; i < attrib_count; i++) {
142         if (vs_output_tab[i] == -1) {
143             assert(0);
144             abort();
145         }
146 
147         format = draw_translate_vinfo_format(vinfo->attrib[i].emit);
148 
149         DBG(r300, DBG_SWTCL,
150             "r300: swtcl_vertex_psc [%i] <- %s\n",
151             vs_output_tab[i], util_format_short_name(format));
152 
153         /* Obtain the type of data in this attribute. */
154         type = r300_translate_vertex_data_type(format);
155         if (type == R300_INVALID_FORMAT) {
156             fprintf(stderr, "r300: Bad vertex format %s.\n",
157                     util_format_short_name(format));
158             assert(0);
159             abort();
160         }
161 
162         type |= vs_output_tab[i] << R300_DST_VEC_LOC_SHIFT;
163 
164         /* Obtain the swizzle for this attribute. Note that the default
165          * swizzle in the hardware is not XYZW! */
166         swizzle = r300_translate_vertex_data_swizzle(format);
167 
168         /* Add the attribute to the PSC table. */
169         if (i & 1) {
170             vstream->vap_prog_stream_cntl[i >> 1] |= type << 16;
171             vstream->vap_prog_stream_cntl_ext[i >> 1] |= swizzle << 16;
172         } else {
173             vstream->vap_prog_stream_cntl[i >> 1] |= type;
174             vstream->vap_prog_stream_cntl_ext[i >> 1] |= swizzle;
175         }
176     }
177 
178     /* Set the last vector in the PSC. */
179     if (i) {
180         i -= 1;
181     }
182     vstream->vap_prog_stream_cntl[i >> 1] |=
183         (R300_LAST_VEC << (i & 1 ? 16 : 0));
184 
185     vstream->count = (i >> 1) + 1;
186     r300_mark_atom_dirty(r300, &r300->vertex_stream_state);
187     r300->vertex_stream_state.size = (1 + vstream->count) * 2;
188 }
189 
r300_rs_col(struct r300_rs_block * rs,int id,int ptr,enum r300_rs_swizzle swiz)190 static void r300_rs_col(struct r300_rs_block* rs, int id, int ptr,
191                         enum r300_rs_swizzle swiz)
192 {
193     rs->ip[id] |= R300_RS_COL_PTR(ptr);
194     if (swiz == SWIZ_0001) {
195         rs->ip[id] |= R300_RS_COL_FMT(R300_RS_COL_FMT_0001);
196     } else {
197         rs->ip[id] |= R300_RS_COL_FMT(R300_RS_COL_FMT_RGBA);
198     }
199     rs->inst[id] |= R300_RS_INST_COL_ID(id);
200 }
201 
r300_rs_col_write(struct r300_rs_block * rs,int id,int fp_offset,enum r300_rs_col_write_type type)202 static void r300_rs_col_write(struct r300_rs_block* rs, int id, int fp_offset,
203                               enum r300_rs_col_write_type type)
204 {
205     assert(type == WRITE_COLOR);
206     rs->inst[id] |= R300_RS_INST_COL_CN_WRITE |
207                     R300_RS_INST_COL_ADDR(fp_offset);
208 }
209 
r300_rs_tex(struct r300_rs_block * rs,int id,int ptr,enum r300_rs_swizzle swiz)210 static void r300_rs_tex(struct r300_rs_block* rs, int id, int ptr,
211                         enum r300_rs_swizzle swiz)
212 {
213     if (swiz == SWIZ_X001) {
214         rs->ip[id] |= R300_RS_TEX_PTR(ptr) |
215                       R300_RS_SEL_S(R300_RS_SEL_C0) |
216                       R300_RS_SEL_T(R300_RS_SEL_K0) |
217                       R300_RS_SEL_R(R300_RS_SEL_K0) |
218                       R300_RS_SEL_Q(R300_RS_SEL_K1);
219     } else if (swiz == SWIZ_XY01) {
220         rs->ip[id] |= R300_RS_TEX_PTR(ptr) |
221                       R300_RS_SEL_S(R300_RS_SEL_C0) |
222                       R300_RS_SEL_T(R300_RS_SEL_C1) |
223                       R300_RS_SEL_R(R300_RS_SEL_K0) |
224                       R300_RS_SEL_Q(R300_RS_SEL_K1);
225     } else {
226         rs->ip[id] |= R300_RS_TEX_PTR(ptr) |
227                       R300_RS_SEL_S(R300_RS_SEL_C0) |
228                       R300_RS_SEL_T(R300_RS_SEL_C1) |
229                       R300_RS_SEL_R(R300_RS_SEL_C2) |
230                       R300_RS_SEL_Q(R300_RS_SEL_C3);
231     }
232     rs->inst[id] |= R300_RS_INST_TEX_ID(id);
233 }
234 
r300_rs_tex_write(struct r300_rs_block * rs,int id,int fp_offset)235 static void r300_rs_tex_write(struct r300_rs_block* rs, int id, int fp_offset)
236 {
237     rs->inst[id] |= R300_RS_INST_TEX_CN_WRITE |
238                     R300_RS_INST_TEX_ADDR(fp_offset);
239 }
240 
r500_rs_col(struct r300_rs_block * rs,int id,int ptr,enum r300_rs_swizzle swiz)241 static void r500_rs_col(struct r300_rs_block* rs, int id, int ptr,
242                         enum r300_rs_swizzle swiz)
243 {
244     rs->ip[id] |= R500_RS_COL_PTR(ptr);
245     if (swiz == SWIZ_0001) {
246         rs->ip[id] |= R500_RS_COL_FMT(R300_RS_COL_FMT_0001);
247     } else {
248         rs->ip[id] |= R500_RS_COL_FMT(R300_RS_COL_FMT_RGBA);
249     }
250     rs->inst[id] |= R500_RS_INST_COL_ID(id);
251 }
252 
r500_rs_col_write(struct r300_rs_block * rs,int id,int fp_offset,enum r300_rs_col_write_type type)253 static void r500_rs_col_write(struct r300_rs_block* rs, int id, int fp_offset,
254                               enum r300_rs_col_write_type type)
255 {
256     if (type == WRITE_FACE)
257         rs->inst[id] |= R500_RS_INST_COL_CN_WRITE_BACKFACE |
258                         R500_RS_INST_COL_ADDR(fp_offset);
259     else
260         rs->inst[id] |= R500_RS_INST_COL_CN_WRITE |
261                         R500_RS_INST_COL_ADDR(fp_offset);
262 
263 }
264 
r500_rs_tex(struct r300_rs_block * rs,int id,int ptr,enum r300_rs_swizzle swiz)265 static void r500_rs_tex(struct r300_rs_block* rs, int id, int ptr,
266 			enum r300_rs_swizzle swiz)
267 {
268     if (swiz == SWIZ_X001) {
269         rs->ip[id] |= R500_RS_SEL_S(ptr) |
270                       R500_RS_SEL_T(R500_RS_IP_PTR_K0) |
271                       R500_RS_SEL_R(R500_RS_IP_PTR_K0) |
272                       R500_RS_SEL_Q(R500_RS_IP_PTR_K1);
273     } else if (swiz == SWIZ_XY01) {
274         rs->ip[id] |= R500_RS_SEL_S(ptr) |
275                       R500_RS_SEL_T(ptr + 1) |
276                       R500_RS_SEL_R(R500_RS_IP_PTR_K0) |
277                       R500_RS_SEL_Q(R500_RS_IP_PTR_K1);
278     } else {
279         rs->ip[id] |= R500_RS_SEL_S(ptr) |
280                       R500_RS_SEL_T(ptr + 1) |
281                       R500_RS_SEL_R(ptr + 2) |
282                       R500_RS_SEL_Q(ptr + 3);
283     }
284     rs->inst[id] |= R500_RS_INST_TEX_ID(id);
285 }
286 
r500_rs_tex_write(struct r300_rs_block * rs,int id,int fp_offset)287 static void r500_rs_tex_write(struct r300_rs_block* rs, int id, int fp_offset)
288 {
289     rs->inst[id] |= R500_RS_INST_TEX_CN_WRITE |
290                     R500_RS_INST_TEX_ADDR(fp_offset);
291 }
292 
293 /* Set up the RS block.
294  *
295  * This is the part of the chipset that is responsible for linking vertex
296  * and fragment shaders and stuffed texture coordinates.
297  *
298  * The rasterizer reads data from VAP, which produces vertex shader outputs,
299  * and GA, which produces stuffed texture coordinates. VAP outputs have
300  * precedence over GA. All outputs must be rasterized otherwise it locks up.
301  * If there are more outputs rasterized than is set in VAP/GA, it locks up
302  * too. The funky part is that this info has been pretty much obtained by trial
303  * and error. */
r300_update_rs_block(struct r300_context * r300)304 static void r300_update_rs_block(struct r300_context *r300)
305 {
306     struct r300_vertex_shader *vs = r300->vs_state.state;
307     struct r300_shader_semantics *vs_outputs = &vs->outputs;
308     struct r300_shader_semantics *fs_inputs = &r300_fs(r300)->shader->inputs;
309     struct r300_rs_block rs = {0};
310     int i, col_count = 0, tex_count = 0, fp_offset = 0, count, loc = 0, tex_ptr = 0;
311     int gen_offset = 0;
312     void (*rX00_rs_col)(struct r300_rs_block*, int, int, enum r300_rs_swizzle);
313     void (*rX00_rs_col_write)(struct r300_rs_block*, int, int, enum r300_rs_col_write_type);
314     void (*rX00_rs_tex)(struct r300_rs_block*, int, int, enum r300_rs_swizzle);
315     void (*rX00_rs_tex_write)(struct r300_rs_block*, int, int);
316     boolean any_bcolor_used = vs_outputs->bcolor[0] != ATTR_UNUSED ||
317                               vs_outputs->bcolor[1] != ATTR_UNUSED;
318     int *stream_loc_notcl = r300->stream_loc_notcl;
319     uint32_t stuffing_enable = 0;
320 
321     if (r300->screen->caps.is_r500) {
322         rX00_rs_col       = r500_rs_col;
323         rX00_rs_col_write = r500_rs_col_write;
324         rX00_rs_tex       = r500_rs_tex;
325         rX00_rs_tex_write = r500_rs_tex_write;
326     } else {
327         rX00_rs_col       = r300_rs_col;
328         rX00_rs_col_write = r300_rs_col_write;
329         rX00_rs_tex       = r300_rs_tex;
330         rX00_rs_tex_write = r300_rs_tex_write;
331     }
332 
333     /* 0x5555 copied from classic, which means:
334      * Select user color 0 for COLOR0 up to COLOR7.
335      * What the hell does that mean? */
336     rs.vap_vtx_state_cntl = 0x5555;
337 
338     /* The position is always present in VAP. */
339     rs.vap_vsm_vtx_assm |= R300_INPUT_CNTL_POS;
340     rs.vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT;
341     stream_loc_notcl[loc++] = 0;
342 
343     /* Set up the point size in VAP. */
344     if (vs_outputs->psize != ATTR_UNUSED) {
345         rs.vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT;
346         stream_loc_notcl[loc++] = 1;
347     }
348 
349     /* Set up and rasterize colors. */
350     for (i = 0; i < ATTR_COLOR_COUNT; i++) {
351         if (vs_outputs->color[i] != ATTR_UNUSED || any_bcolor_used ||
352             vs_outputs->color[1] != ATTR_UNUSED) {
353             /* Set up the color in VAP. */
354             rs.vap_vsm_vtx_assm |= R300_INPUT_CNTL_COLOR;
355             rs.vap_out_vtx_fmt[0] |=
356                     R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << i;
357             stream_loc_notcl[loc++] = 2 + i;
358 
359             /* Rasterize it. */
360             rX00_rs_col(&rs, col_count, col_count, SWIZ_XYZW);
361 
362             /* Write it to the FS input register if it's needed by the FS. */
363             if (fs_inputs->color[i] != ATTR_UNUSED) {
364                 rX00_rs_col_write(&rs, col_count, fp_offset, WRITE_COLOR);
365                 fp_offset++;
366 
367                 DBG(r300, DBG_RS,
368                     "r300: Rasterized color %i written to FS.\n", i);
369             } else {
370                 DBG(r300, DBG_RS, "r300: Rasterized color %i unused.\n", i);
371             }
372             col_count++;
373         } else {
374             /* Skip the FS input register, leave it uninitialized. */
375             /* If we try to set it to (0,0,0,1), it will lock up. */
376             if (fs_inputs->color[i] != ATTR_UNUSED) {
377                 fp_offset++;
378 
379                 DBG(r300, DBG_RS, "r300: FS input color %i unassigned.\n",
380                     i);
381             }
382         }
383     }
384 
385     /* Set up back-face colors. The rasterizer will do the color selection
386      * automatically. */
387     if (any_bcolor_used) {
388         if (r300->two_sided_color) {
389             /* Rasterize as back-face colors. */
390             for (i = 0; i < ATTR_COLOR_COUNT; i++) {
391                 rs.vap_vsm_vtx_assm |= R300_INPUT_CNTL_COLOR;
392                 rs.vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << (2+i);
393                 stream_loc_notcl[loc++] = 4 + i;
394             }
395         } else {
396             /* Rasterize two fake texcoords to prevent from the two-sided color
397              * selection. */
398             /* XXX Consider recompiling the vertex shader to save 2 RS units. */
399             for (i = 0; i < 2; i++) {
400                 rs.vap_vsm_vtx_assm |= (R300_INPUT_CNTL_TC0 << tex_count);
401                 rs.vap_out_vtx_fmt[1] |= (4 << (3 * tex_count));
402                 stream_loc_notcl[loc++] = 6 + tex_count;
403 
404                 /* Rasterize it. */
405                 rX00_rs_tex(&rs, tex_count, tex_ptr, SWIZ_XYZW);
406                 tex_count++;
407                 tex_ptr += 4;
408             }
409         }
410     }
411 
412     /* gl_FrontFacing.
413      * Note that we can use either the two-sided color selection based on
414      * the front and back vertex shader colors, or gl_FrontFacing,
415      * but not both! It locks up otherwise.
416      *
417      * In Direct3D 9, the two-sided color selection can be used
418      * with shaders 2.0 only, while gl_FrontFacing can be used
419      * with shaders 3.0 only. The hardware apparently hasn't been designed
420      * to support both at the same time. */
421     if (r300->screen->caps.is_r500 && fs_inputs->face != ATTR_UNUSED &&
422         !(any_bcolor_used && r300->two_sided_color)) {
423         rX00_rs_col(&rs, col_count, col_count, SWIZ_XYZW);
424         rX00_rs_col_write(&rs, col_count, fp_offset, WRITE_FACE);
425         fp_offset++;
426         col_count++;
427         DBG(r300, DBG_RS, "r300: Rasterized FACE written to FS.\n");
428     } else if (fs_inputs->face != ATTR_UNUSED) {
429         fprintf(stderr, "r300: ERROR: FS input FACE unassigned.\n");
430     }
431 
432     /* Re-use color varyings for texcoords if possible.
433      *
434      * The colors are interpolated as 20-bit floats (reduced precision),
435      * Use this hack only if there are too many generic varyings.
436      * (number of generic varyings + fog + wpos > 8) */
437     if (r300->screen->caps.is_r500 && !any_bcolor_used && !r300->flatshade &&
438 	fs_inputs->face == ATTR_UNUSED &&
439         vs_outputs->num_generic + (vs_outputs->fog != ATTR_UNUSED) +
440         (fs_inputs->wpos != ATTR_UNUSED) > 8) {
441 	for (i = 0; i < ATTR_GENERIC_COUNT && col_count < 2; i++) {
442 	    /* Cannot use color varyings for sprite coords. */
443 	    if (fs_inputs->generic[i] != ATTR_UNUSED &&
444 		(r300->sprite_coord_enable & (1 << i))) {
445 		break;
446 	    }
447 
448 	    if (vs_outputs->generic[i] != ATTR_UNUSED) {
449 		/* Set up the color in VAP. */
450 		rs.vap_vsm_vtx_assm |= R300_INPUT_CNTL_COLOR;
451 		rs.vap_out_vtx_fmt[0] |=
452 			R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << col_count;
453 		stream_loc_notcl[loc++] = 2 + col_count;
454 
455 		/* Rasterize it. */
456 		rX00_rs_col(&rs, col_count, col_count, SWIZ_XYZW);
457 
458 		/* Write it to the FS input register if it's needed by the FS. */
459 		if (fs_inputs->generic[i] != ATTR_UNUSED) {
460 		    rX00_rs_col_write(&rs, col_count, fp_offset, WRITE_COLOR);
461 		    fp_offset++;
462 
463 		    DBG(r300, DBG_RS,
464 			"r300: Rasterized generic %i redirected to color %i and written to FS.\n",
465 		        i, col_count);
466 		} else {
467 		    DBG(r300, DBG_RS, "r300: Rasterized generic %i redirected to color %i unused.\n",
468 		        i, col_count);
469 		}
470 		col_count++;
471 	    } else {
472 		/* Skip the FS input register, leave it uninitialized. */
473 		/* If we try to set it to (0,0,0,1), it will lock up. */
474 		if (fs_inputs->generic[i] != ATTR_UNUSED) {
475 		    fp_offset++;
476 
477 		    DBG(r300, DBG_RS, "r300: FS input generic %i unassigned.\n", i);
478 		}
479 	    }
480 	}
481 	gen_offset = i;
482     }
483 
484     /* Rasterize texture coordinates. */
485     for (i = gen_offset; i < ATTR_GENERIC_COUNT && tex_count < 8; i++) {
486 	boolean sprite_coord = false;
487 
488 	if (fs_inputs->generic[i] != ATTR_UNUSED) {
489 	    sprite_coord = !!(r300->sprite_coord_enable & (1 << i));
490 	}
491 
492         if (vs_outputs->generic[i] != ATTR_UNUSED || sprite_coord) {
493             if (!sprite_coord) {
494                 /* Set up the texture coordinates in VAP. */
495                 rs.vap_vsm_vtx_assm |= (R300_INPUT_CNTL_TC0 << tex_count);
496                 rs.vap_out_vtx_fmt[1] |= (4 << (3 * tex_count));
497                 stream_loc_notcl[loc++] = 6 + tex_count;
498             } else
499                 stuffing_enable |=
500                     R300_GB_TEX_ST << (R300_GB_TEX0_SOURCE_SHIFT + (tex_count*2));
501 
502             /* Rasterize it. */
503             rX00_rs_tex(&rs, tex_count, tex_ptr,
504 			sprite_coord ? SWIZ_XY01 : SWIZ_XYZW);
505 
506             /* Write it to the FS input register if it's needed by the FS. */
507             if (fs_inputs->generic[i] != ATTR_UNUSED) {
508                 rX00_rs_tex_write(&rs, tex_count, fp_offset);
509                 fp_offset++;
510 
511                 DBG(r300, DBG_RS,
512                     "r300: Rasterized generic %i written to FS%s in texcoord %d.\n",
513                     i, sprite_coord ? " (sprite coord)" : "", tex_count);
514             } else {
515                 DBG(r300, DBG_RS,
516                     "r300: Rasterized generic %i unused%s.\n",
517                     i, sprite_coord ? " (sprite coord)" : "");
518             }
519             tex_count++;
520             tex_ptr += sprite_coord ? 2 : 4;
521         } else {
522             /* Skip the FS input register, leave it uninitialized. */
523             /* If we try to set it to (0,0,0,1), it will lock up. */
524             if (fs_inputs->generic[i] != ATTR_UNUSED) {
525                 fp_offset++;
526 
527                 DBG(r300, DBG_RS, "r300: FS input generic %i unassigned%s.\n",
528                     i, sprite_coord ? " (sprite coord)" : "");
529             }
530         }
531     }
532 
533     for (; i < ATTR_GENERIC_COUNT; i++) {
534         if (fs_inputs->generic[i] != ATTR_UNUSED) {
535             fprintf(stderr, "r300: ERROR: FS input generic %i unassigned, "
536                     "not enough hardware slots (it's not a bug, do not "
537                     "report it).\n", i);
538         }
539     }
540 
541     /* Rasterize fog coordinates. */
542     if (vs_outputs->fog != ATTR_UNUSED && tex_count < 8) {
543         /* Set up the fog coordinates in VAP. */
544         rs.vap_vsm_vtx_assm |= (R300_INPUT_CNTL_TC0 << tex_count);
545         rs.vap_out_vtx_fmt[1] |= (4 << (3 * tex_count));
546         stream_loc_notcl[loc++] = 6 + tex_count;
547 
548         /* Rasterize it. */
549         rX00_rs_tex(&rs, tex_count, tex_ptr, SWIZ_X001);
550 
551         /* Write it to the FS input register if it's needed by the FS. */
552         if (fs_inputs->fog != ATTR_UNUSED) {
553             rX00_rs_tex_write(&rs, tex_count, fp_offset);
554             fp_offset++;
555 
556             DBG(r300, DBG_RS, "r300: Rasterized fog written to FS.\n");
557         } else {
558             DBG(r300, DBG_RS, "r300: Rasterized fog unused.\n");
559         }
560         tex_count++;
561         tex_ptr += 4;
562     } else {
563         /* Skip the FS input register, leave it uninitialized. */
564         /* If we try to set it to (0,0,0,1), it will lock up. */
565         if (fs_inputs->fog != ATTR_UNUSED) {
566             fp_offset++;
567 
568             if (tex_count < 8) {
569                 DBG(r300, DBG_RS, "r300: FS input fog unassigned.\n");
570             } else {
571                 fprintf(stderr, "r300: ERROR: FS input fog unassigned, "
572                         "not enough hardware slots. (it's not a bug, "
573                         "do not report it)\n");
574             }
575         }
576     }
577 
578     /* Rasterize WPOS. */
579     /* Don't set it in VAP if the FS doesn't need it. */
580     if (fs_inputs->wpos != ATTR_UNUSED && tex_count < 8) {
581         /* Set up the WPOS coordinates in VAP. */
582         rs.vap_vsm_vtx_assm |= (R300_INPUT_CNTL_TC0 << tex_count);
583         rs.vap_out_vtx_fmt[1] |= (4 << (3 * tex_count));
584         stream_loc_notcl[loc++] = 6 + tex_count;
585 
586         /* Rasterize it. */
587         rX00_rs_tex(&rs, tex_count, tex_ptr, SWIZ_XYZW);
588 
589         /* Write it to the FS input register. */
590         rX00_rs_tex_write(&rs, tex_count, fp_offset);
591 
592         DBG(r300, DBG_RS, "r300: Rasterized WPOS written to FS.\n");
593 
594         fp_offset++;
595         tex_count++;
596         tex_ptr += 4;
597     } else {
598         if (fs_inputs->wpos != ATTR_UNUSED && tex_count >= 8) {
599             fprintf(stderr, "r300: ERROR: FS input WPOS unassigned, "
600                     "not enough hardware slots. (it's not a bug, do not "
601                     "report it)\n");
602         }
603     }
604 
605     /* Invalidate the rest of the no-TCL (GA) stream locations. */
606     for (; loc < 16;) {
607         stream_loc_notcl[loc++] = -1;
608     }
609 
610     /* Rasterize at least one color, or bad things happen. */
611     if (col_count == 0 && tex_count == 0) {
612         rX00_rs_col(&rs, 0, 0, SWIZ_0001);
613         col_count++;
614 
615         DBG(r300, DBG_RS, "r300: Rasterized color 0 to prevent lockups.\n");
616     }
617 
618     DBG(r300, DBG_RS, "r300: --- Rasterizer status ---: colors: %i, "
619         "generics: %i.\n", col_count, tex_count);
620 
621     rs.count = MIN2(tex_ptr, 32) | (col_count << R300_IC_COUNT_SHIFT) |
622         R300_HIRES_EN;
623 
624     count = MAX3(col_count, tex_count, 1);
625     rs.inst_count = count - 1;
626 
627     /* set the GB enable flags */
628     if (r300->sprite_coord_enable)
629 	stuffing_enable |= R300_GB_POINT_STUFF_ENABLE;
630 
631     rs.gb_enable = stuffing_enable;
632 
633     /* Now, after all that, see if we actually need to update the state. */
634     if (memcmp(r300->rs_block_state.state, &rs, sizeof(struct r300_rs_block))) {
635         memcpy(r300->rs_block_state.state, &rs, sizeof(struct r300_rs_block));
636         r300->rs_block_state.size = 13 + count*2;
637     }
638 }
639 
rgba_to_bgra(float color[4])640 static void rgba_to_bgra(float color[4])
641 {
642     float x = color[0];
643     color[0] = color[2];
644     color[2] = x;
645 }
646 
r300_get_border_color(enum pipe_format format,const float border[4],boolean is_r500)647 static uint32_t r300_get_border_color(enum pipe_format format,
648                                       const float border[4],
649                                       boolean is_r500)
650 {
651     const struct util_format_description *desc;
652     float border_swizzled[4] = {0};
653     union util_color uc = {0};
654 
655     desc = util_format_description(format);
656 
657     /* Do depth formats first. */
658     if (util_format_is_depth_or_stencil(format)) {
659         switch (format) {
660         case PIPE_FORMAT_Z16_UNORM:
661             return util_pack_z(PIPE_FORMAT_Z16_UNORM, border[0]);
662         case PIPE_FORMAT_X8Z24_UNORM:
663         case PIPE_FORMAT_S8_UINT_Z24_UNORM:
664             if (is_r500) {
665                 return util_pack_z(PIPE_FORMAT_X8Z24_UNORM, border[0]);
666             } else {
667                 return util_pack_z(PIPE_FORMAT_Z16_UNORM, border[0]) << 16;
668             }
669         default:
670             assert(0);
671             return 0;
672         }
673     }
674 
675     /* Apply inverse swizzle of the format. */
676     util_format_unswizzle_4f(border_swizzled, border, desc->swizzle);
677 
678     /* Compressed formats. */
679     if (util_format_is_compressed(format)) {
680         switch (format) {
681         case PIPE_FORMAT_RGTC1_SNORM:
682         case PIPE_FORMAT_LATC1_SNORM:
683             border_swizzled[0] = border_swizzled[0] < 0 ?
684                                  border_swizzled[0]*0.5+1 :
685                                  border_swizzled[0]*0.5;
686             /* fallthrough. */
687 
688         case PIPE_FORMAT_RGTC1_UNORM:
689         case PIPE_FORMAT_LATC1_UNORM:
690             /* Add 1/32 to round the border color instead of truncating. */
691             /* The Y component is used for the border color. */
692             border_swizzled[1] = border_swizzled[0] + 1.0f/32;
693             util_pack_color(border_swizzled, PIPE_FORMAT_B4G4R4A4_UNORM, &uc);
694             return uc.ui[0];
695         case PIPE_FORMAT_RGTC2_SNORM:
696         case PIPE_FORMAT_LATC2_SNORM:
697             util_pack_color(border_swizzled, PIPE_FORMAT_R8G8B8A8_SNORM, &uc);
698             return uc.ui[0];
699         case PIPE_FORMAT_RGTC2_UNORM:
700         case PIPE_FORMAT_LATC2_UNORM:
701             util_pack_color(border_swizzled, PIPE_FORMAT_R8G8B8A8_UNORM, &uc);
702             return uc.ui[0];
703         case PIPE_FORMAT_DXT1_SRGB:
704         case PIPE_FORMAT_DXT1_SRGBA:
705         case PIPE_FORMAT_DXT3_SRGBA:
706         case PIPE_FORMAT_DXT5_SRGBA:
707             util_pack_color(border_swizzled, PIPE_FORMAT_B8G8R8A8_SRGB, &uc);
708             return uc.ui[0];
709         default:
710             util_pack_color(border_swizzled, PIPE_FORMAT_B8G8R8A8_UNORM, &uc);
711             return uc.ui[0];
712         }
713     }
714 
715     switch (desc->channel[0].size) {
716         case 2:
717             rgba_to_bgra(border_swizzled);
718             util_pack_color(border_swizzled, PIPE_FORMAT_B2G3R3_UNORM, &uc);
719             break;
720 
721         case 4:
722             rgba_to_bgra(border_swizzled);
723             util_pack_color(border_swizzled, PIPE_FORMAT_B4G4R4A4_UNORM, &uc);
724             break;
725 
726         case 5:
727             rgba_to_bgra(border_swizzled);
728             if (desc->channel[1].size == 5) {
729                 util_pack_color(border_swizzled, PIPE_FORMAT_B5G5R5A1_UNORM, &uc);
730             } else if (desc->channel[1].size == 6) {
731                 util_pack_color(border_swizzled, PIPE_FORMAT_B5G6R5_UNORM, &uc);
732             } else {
733                 assert(0);
734             }
735             break;
736 
737         default:
738         case 8:
739             if (desc->channel[0].type == UTIL_FORMAT_TYPE_SIGNED) {
740                 util_pack_color(border_swizzled, PIPE_FORMAT_R8G8B8A8_SNORM, &uc);
741             } else if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
742                 if (desc->nr_channels == 2) {
743                     border_swizzled[3] = border_swizzled[1];
744                     util_pack_color(border_swizzled, PIPE_FORMAT_L8A8_SRGB, &uc);
745                 } else {
746                     util_pack_color(border_swizzled, PIPE_FORMAT_R8G8B8A8_SRGB, &uc);
747                 }
748             } else {
749                 util_pack_color(border_swizzled, PIPE_FORMAT_R8G8B8A8_UNORM, &uc);
750             }
751             break;
752 
753         case 10:
754             util_pack_color(border_swizzled, PIPE_FORMAT_R10G10B10A2_UNORM, &uc);
755             break;
756 
757         case 16:
758             if (desc->nr_channels <= 2) {
759                 if (desc->channel[0].type == UTIL_FORMAT_TYPE_FLOAT) {
760                     util_pack_color(border_swizzled, PIPE_FORMAT_R16G16_FLOAT, &uc);
761                 } else if (desc->channel[0].type == UTIL_FORMAT_TYPE_SIGNED) {
762                     util_pack_color(border_swizzled, PIPE_FORMAT_R16G16_SNORM, &uc);
763                 } else {
764                     util_pack_color(border_swizzled, PIPE_FORMAT_R16G16_UNORM, &uc);
765                 }
766             } else {
767                 if (desc->channel[0].type == UTIL_FORMAT_TYPE_SIGNED) {
768                     util_pack_color(border_swizzled, PIPE_FORMAT_R8G8B8A8_SNORM, &uc);
769                 } else {
770                     util_pack_color(border_swizzled, PIPE_FORMAT_R8G8B8A8_UNORM, &uc);
771                 }
772             }
773             break;
774 
775         case 32:
776             if (desc->nr_channels == 1) {
777                 util_pack_color(border_swizzled, PIPE_FORMAT_R32_FLOAT, &uc);
778             } else {
779                 util_pack_color(border_swizzled, PIPE_FORMAT_R8G8B8A8_UNORM, &uc);
780             }
781             break;
782     }
783 
784     return uc.ui[0];
785 }
786 
r300_merge_textures_and_samplers(struct r300_context * r300)787 static void r300_merge_textures_and_samplers(struct r300_context* r300)
788 {
789     struct r300_textures_state *state =
790         (struct r300_textures_state*)r300->textures_state.state;
791     struct r300_texture_sampler_state *texstate;
792     struct r300_sampler_state *sampler;
793     struct r300_sampler_view *view;
794     struct r300_resource *tex;
795     unsigned base_level, min_level, level_count, i, j, size;
796     unsigned count = MIN2(state->sampler_view_count,
797                           state->sampler_state_count);
798     boolean has_us_format = r300->screen->caps.has_us_format;
799 
800     /* The KIL opcode fix, see below. */
801     if (!count && !r300->screen->caps.is_r500)
802         count = 1;
803 
804     state->tx_enable = 0;
805     state->count = 0;
806     size = 2;
807 
808     for (i = 0; i < count; i++) {
809         if (state->sampler_views[i] && state->sampler_states[i]) {
810             state->tx_enable |= 1 << i;
811 
812             view = state->sampler_views[i];
813             tex = r300_resource(view->base.texture);
814             sampler = state->sampler_states[i];
815 
816             texstate = &state->regs[i];
817             texstate->format = view->format;
818             texstate->filter0 = sampler->filter0;
819             texstate->filter1 = sampler->filter1;
820 
821             /* Set the border color. */
822             texstate->border_color =
823                 r300_get_border_color(view->base.format,
824                                       sampler->state.border_color.f,
825                                       r300->screen->caps.is_r500);
826 
827             /* determine min/max levels */
828             base_level = view->base.u.tex.first_level;
829             min_level = sampler->min_lod;
830             level_count = MIN3(sampler->max_lod,
831                                tex->b.b.last_level - base_level,
832                                view->base.u.tex.last_level - base_level);
833 
834             if (base_level + min_level) {
835                 unsigned offset;
836 
837                 if (tex->tex.is_npot) {
838                     /* Even though we do not implement mipmapping for NPOT
839                      * textures, we should at least honor the minimum level
840                      * which is allowed to be displayed. We do this by setting up
841                      * an i-th mipmap level as the zero level. */
842                     base_level += min_level;
843                 }
844                 offset = tex->tex.offset_in_bytes[base_level];
845 
846                 r300_texture_setup_format_state(r300->screen, tex,
847                                                 view->base.format,
848                                                 base_level,
849                                                 view->width0_override,
850 		                                view->height0_override,
851                                                 &texstate->format);
852                 texstate->format.tile_config |= offset & 0xffffffe0;
853                 assert((offset & 0x1f) == 0);
854             }
855 
856             /* Assign a texture cache region. */
857             texstate->format.format1 |= view->texcache_region;
858 
859             /* Depth textures are kinda special. */
860             if (util_format_is_depth_or_stencil(view->base.format)) {
861                 unsigned char depth_swizzle[4];
862 
863                 if (!r300->screen->caps.is_r500 &&
864                     util_format_get_blocksizebits(view->base.format) == 32) {
865                     /* X24x8 is sampled as Y16X16 on r3xx-r4xx.
866                      * The depth here is at the Y component. */
867                     for (j = 0; j < 4; j++)
868                         depth_swizzle[j] = PIPE_SWIZZLE_Y;
869                 } else {
870                     for (j = 0; j < 4; j++)
871                         depth_swizzle[j] = PIPE_SWIZZLE_X;
872                 }
873 
874                 /* If compare mode is disabled, sampler view swizzles
875                  * are stored in the format.
876                  * Otherwise, the swizzles must be applied after the compare
877                  * mode in the fragment shader. */
878                 if (sampler->state.compare_mode == PIPE_TEX_COMPARE_NONE) {
879                     texstate->format.format1 |=
880                         r300_get_swizzle_combined(depth_swizzle,
881                                                   view->swizzle, FALSE);
882                 } else {
883                     texstate->format.format1 |=
884                         r300_get_swizzle_combined(depth_swizzle, 0, FALSE);
885                 }
886             }
887 
888             if (r300->screen->caps.dxtc_swizzle &&
889                 util_format_is_compressed(view->base.format)) {
890                 texstate->filter1 |= R400_DXTC_SWIZZLE_ENABLE;
891             }
892 
893             /* to emulate 1D textures through 2D ones correctly */
894             if (tex->b.b.target == PIPE_TEXTURE_1D) {
895                 texstate->filter0 &= ~R300_TX_WRAP_T_MASK;
896                 texstate->filter0 |= R300_TX_WRAP_T(R300_TX_CLAMP_TO_EDGE);
897             }
898 
899             /* The hardware doesn't like CLAMP and CLAMP_TO_BORDER
900              * for the 3rd coordinate if the texture isn't 3D. */
901             if (tex->b.b.target != PIPE_TEXTURE_3D) {
902                 texstate->filter0 &= ~R300_TX_WRAP_R_MASK;
903             }
904 
905             if (tex->tex.is_npot) {
906                 /* NPOT textures don't support mip filter, unfortunately.
907                  * This prevents incorrect rendering. */
908                 texstate->filter0 &= ~R300_TX_MIN_FILTER_MIP_MASK;
909 
910                 /* Mask out the mirrored flag. */
911                 if (texstate->filter0 & R300_TX_WRAP_S(R300_TX_MIRRORED)) {
912                     texstate->filter0 &= ~R300_TX_WRAP_S(R300_TX_MIRRORED);
913                 }
914                 if (texstate->filter0 & R300_TX_WRAP_T(R300_TX_MIRRORED)) {
915                     texstate->filter0 &= ~R300_TX_WRAP_T(R300_TX_MIRRORED);
916                 }
917 
918                 /* Change repeat to clamp-to-edge.
919                  * (the repeat bit has a value of 0, no masking needed). */
920                 if ((texstate->filter0 & R300_TX_WRAP_S_MASK) ==
921                     R300_TX_WRAP_S(R300_TX_REPEAT)) {
922                     texstate->filter0 |= R300_TX_WRAP_S(R300_TX_CLAMP_TO_EDGE);
923                 }
924                 if ((texstate->filter0 & R300_TX_WRAP_T_MASK) ==
925                     R300_TX_WRAP_T(R300_TX_REPEAT)) {
926                     texstate->filter0 |= R300_TX_WRAP_T(R300_TX_CLAMP_TO_EDGE);
927                 }
928             } else {
929                 /* the MAX_MIP level is the largest (finest) one */
930                 texstate->format.format0 |= R300_TX_NUM_LEVELS(level_count);
931                 texstate->filter0 |= R300_TX_MAX_MIP_LEVEL(min_level);
932             }
933 
934             /* Float textures only support nearest and mip-nearest filtering. */
935             if (util_format_is_float(view->base.format)) {
936                 /* No MAG linear filtering. */
937                 if ((texstate->filter0 & R300_TX_MAG_FILTER_MASK) ==
938                     R300_TX_MAG_FILTER_LINEAR) {
939                     texstate->filter0 &= ~R300_TX_MAG_FILTER_MASK;
940                     texstate->filter0 |= R300_TX_MAG_FILTER_NEAREST;
941                 }
942                 /* No MIN linear filtering. */
943                 if ((texstate->filter0 & R300_TX_MIN_FILTER_MASK) ==
944                     R300_TX_MIN_FILTER_LINEAR) {
945                     texstate->filter0 &= ~R300_TX_MIN_FILTER_MASK;
946                     texstate->filter0 |= R300_TX_MIN_FILTER_NEAREST;
947                 }
948                 /* No mipmap linear filtering. */
949                 if ((texstate->filter0 & R300_TX_MIN_FILTER_MIP_MASK) ==
950                     R300_TX_MIN_FILTER_MIP_LINEAR) {
951                     texstate->filter0 &= ~R300_TX_MIN_FILTER_MIP_MASK;
952                     texstate->filter0 |= R300_TX_MIN_FILTER_MIP_NEAREST;
953                 }
954                 /* No anisotropic filtering. */
955                 texstate->filter0 &= ~R300_TX_MAX_ANISO_MASK;
956                 texstate->filter1 &= ~R500_TX_MAX_ANISO_MASK;
957                 texstate->filter1 &= ~R500_TX_ANISO_HIGH_QUALITY;
958             }
959 
960             texstate->filter0 |= i << 28;
961 
962             size += 16 + (has_us_format ? 2 : 0);
963             state->count = i+1;
964         } else {
965             /* For the KIL opcode to work on r3xx-r4xx, the texture unit
966              * assigned to this opcode (it's always the first one) must be
967              * enabled. Otherwise the opcode doesn't work.
968              *
969              * In order to not depend on the fragment shader, we just make
970              * the first unit enabled all the time. */
971             if (i == 0 && !r300->screen->caps.is_r500) {
972                 pipe_sampler_view_reference(
973                         (struct pipe_sampler_view**)&state->sampler_views[i],
974                         &r300->texkill_sampler->base);
975 
976                 state->tx_enable |= 1 << i;
977 
978                 texstate = &state->regs[i];
979 
980                 /* Just set some valid state. */
981                 texstate->format = r300->texkill_sampler->format;
982                 texstate->filter0 =
983                         r300_translate_tex_filters(PIPE_TEX_FILTER_NEAREST,
984                                                    PIPE_TEX_FILTER_NEAREST,
985                                                    PIPE_TEX_FILTER_NEAREST,
986                                                    FALSE);
987                 texstate->filter1 = 0;
988                 texstate->border_color = 0;
989 
990                 texstate->filter0 |= i << 28;
991                 size += 16 + (has_us_format ? 2 : 0);
992                 state->count = i+1;
993             }
994         }
995     }
996 
997     r300->textures_state.size = size;
998 
999     /* Pick a fragment shader based on either the texture compare state
1000      * or the uses_pitch flag or some other external state. */
1001     if (count &&
1002         r300->fs_status == FRAGMENT_SHADER_VALID) {
1003         r300->fs_status = FRAGMENT_SHADER_MAYBE_DIRTY;
1004     }
1005 }
1006 
r300_decompress_depth_textures(struct r300_context * r300)1007 static void r300_decompress_depth_textures(struct r300_context *r300)
1008 {
1009     struct r300_textures_state *state =
1010         (struct r300_textures_state*)r300->textures_state.state;
1011     struct pipe_resource *tex;
1012     unsigned count = MIN2(state->sampler_view_count,
1013                           state->sampler_state_count);
1014     unsigned i;
1015 
1016     if (!r300->locked_zbuffer) {
1017         return;
1018     }
1019 
1020     for (i = 0; i < count; i++) {
1021         if (state->sampler_views[i] && state->sampler_states[i]) {
1022             tex = state->sampler_views[i]->base.texture;
1023 
1024             if (tex == r300->locked_zbuffer->texture) {
1025                 r300_decompress_zmask_locked(r300);
1026                 return;
1027             }
1028         }
1029     }
1030 }
1031 
r300_validate_fragment_shader(struct r300_context * r300)1032 static void r300_validate_fragment_shader(struct r300_context *r300)
1033 {
1034     struct pipe_framebuffer_state *fb = r300->fb_state.state;
1035 
1036     if (r300->fs.state && r300->fs_status != FRAGMENT_SHADER_VALID) {
1037         /* Pick the fragment shader based on external states.
1038          * Then mark the state dirty if the fragment shader is either dirty
1039          * or the function r300_pick_fragment_shader changed the shader. */
1040         if (r300_pick_fragment_shader(r300) ||
1041             r300->fs_status == FRAGMENT_SHADER_DIRTY) {
1042             /* Mark the state atom as dirty. */
1043             r300_mark_fs_code_dirty(r300);
1044 
1045             /* Does Multiwrite need to be changed? */
1046             if (fb->nr_cbufs > 1) {
1047                 boolean new_multiwrite =
1048                     r300_fragment_shader_writes_all(r300_fs(r300));
1049 
1050                 if (r300->fb_multiwrite != new_multiwrite) {
1051                     r300->fb_multiwrite = new_multiwrite;
1052                     r300_mark_fb_state_dirty(r300, R300_CHANGED_MULTIWRITE);
1053                 }
1054             }
1055         }
1056         r300->fs_status = FRAGMENT_SHADER_VALID;
1057     }
1058 }
1059 
r300_update_derived_state(struct r300_context * r300)1060 void r300_update_derived_state(struct r300_context* r300)
1061 {
1062     if (r300->textures_state.dirty) {
1063         r300_decompress_depth_textures(r300);
1064         r300_merge_textures_and_samplers(r300);
1065     }
1066 
1067     r300_validate_fragment_shader(r300);
1068 
1069     if (r300->rs_block_state.dirty) {
1070         r300_update_rs_block(r300);
1071 
1072         if (r300->draw) {
1073             memset(&r300->vertex_info, 0, sizeof(struct vertex_info));
1074             r300_draw_emit_all_attribs(r300);
1075             draw_compute_vertex_size(&r300->vertex_info);
1076             r300_swtcl_vertex_psc(r300);
1077         }
1078     }
1079 
1080     r300_update_hyperz_state(r300);
1081 }
1082