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