Merge branch '7.8'
[mesa.git] / src / mesa / drivers / dri / r300 / r300_blit.c
1 /*
2 * Copyright (C) 2009 Maciej Cencora <m.cencora@gmail.com>
3 *
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial
16 * portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 */
27
28 #include "radeon_common.h"
29 #include "r300_context.h"
30
31 #include "r300_blit.h"
32 #include "r300_cmdbuf.h"
33 #include "r300_emit.h"
34 #include "r300_tex.h"
35 #include "compiler/radeon_compiler.h"
36 #include "compiler/radeon_opcodes.h"
37
38 static void vp_ins_outs(struct r300_vertex_program_compiler *c)
39 {
40 c->code->inputs[VERT_ATTRIB_POS] = 0;
41 c->code->inputs[VERT_ATTRIB_TEX0] = 1;
42 c->code->outputs[VERT_RESULT_HPOS] = 0;
43 c->code->outputs[VERT_RESULT_TEX0] = 1;
44 }
45
46 static void fp_allocate_hw_inputs(
47 struct r300_fragment_program_compiler * c,
48 void (*allocate)(void * data, unsigned input, unsigned hwreg),
49 void * mydata)
50 {
51 allocate(mydata, FRAG_ATTRIB_TEX0, 0);
52 }
53
54 static void create_vertex_program(struct r300_context *r300)
55 {
56 struct r300_vertex_program_compiler compiler;
57 struct rc_instruction *inst;
58
59 rc_init(&compiler.Base);
60
61 inst = rc_insert_new_instruction(&compiler.Base, compiler.Base.Program.Instructions.Prev);
62 inst->U.I.Opcode = RC_OPCODE_MOV;
63 inst->U.I.DstReg.File = RC_FILE_OUTPUT;
64 inst->U.I.DstReg.Index = VERT_RESULT_HPOS;
65 inst->U.I.DstReg.RelAddr = 0;
66 inst->U.I.DstReg.WriteMask = RC_MASK_XYZW;
67 inst->U.I.SrcReg[0].Abs = 0;
68 inst->U.I.SrcReg[0].File = RC_FILE_INPUT;
69 inst->U.I.SrcReg[0].Index = VERT_ATTRIB_POS;
70 inst->U.I.SrcReg[0].Negate = 0;
71 inst->U.I.SrcReg[0].RelAddr = 0;
72 inst->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_XYZW;
73
74 inst = rc_insert_new_instruction(&compiler.Base, compiler.Base.Program.Instructions.Prev);
75 inst->U.I.Opcode = RC_OPCODE_MOV;
76 inst->U.I.DstReg.File = RC_FILE_OUTPUT;
77 inst->U.I.DstReg.Index = VERT_RESULT_TEX0;
78 inst->U.I.DstReg.RelAddr = 0;
79 inst->U.I.DstReg.WriteMask = RC_MASK_XYZW;
80 inst->U.I.SrcReg[0].Abs = 0;
81 inst->U.I.SrcReg[0].File = RC_FILE_INPUT;
82 inst->U.I.SrcReg[0].Index = VERT_ATTRIB_TEX0;
83 inst->U.I.SrcReg[0].Negate = 0;
84 inst->U.I.SrcReg[0].RelAddr = 0;
85 inst->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_XYZW;
86
87 compiler.Base.Program.InputsRead = (1 << VERT_ATTRIB_POS) | (1 << VERT_ATTRIB_TEX0);
88 compiler.RequiredOutputs = compiler.Base.Program.OutputsWritten = (1 << VERT_RESULT_HPOS) | (1 << VERT_RESULT_TEX0);
89 compiler.SetHwInputOutput = vp_ins_outs;
90 compiler.code = &r300->blit.vp_code;
91
92 r3xx_compile_vertex_program(&compiler);
93 }
94
95 static void create_fragment_program(struct r300_context *r300)
96 {
97 struct r300_fragment_program_compiler compiler;
98 struct rc_instruction *inst;
99
100 memset(&compiler, 0, sizeof(struct r300_fragment_program_compiler));
101 rc_init(&compiler.Base);
102
103 inst = rc_insert_new_instruction(&compiler.Base, compiler.Base.Program.Instructions.Prev);
104 inst->U.I.Opcode = RC_OPCODE_TEX;
105 inst->U.I.TexSrcTarget = RC_TEXTURE_2D;
106 inst->U.I.TexSrcUnit = 0;
107 inst->U.I.DstReg.File = RC_FILE_OUTPUT;
108 inst->U.I.DstReg.Index = FRAG_RESULT_COLOR;
109 inst->U.I.DstReg.WriteMask = RC_MASK_XYZW;
110 inst->U.I.SrcReg[0].Abs = 0;
111 inst->U.I.SrcReg[0].File = RC_FILE_INPUT;
112 inst->U.I.SrcReg[0].Index = FRAG_ATTRIB_TEX0;
113 inst->U.I.SrcReg[0].Negate = 0;
114 inst->U.I.SrcReg[0].RelAddr = 0;
115 inst->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_XYZW;
116
117 compiler.Base.Program.InputsRead = (1 << FRAG_ATTRIB_TEX0);
118 compiler.OutputColor[0] = FRAG_RESULT_COLOR;
119 compiler.OutputDepth = FRAG_RESULT_DEPTH;
120 compiler.enable_shadow_ambient = GL_TRUE;
121 compiler.is_r500 = (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515);
122 compiler.max_temp_regs = (compiler.is_r500) ? 128 : 32;
123 compiler.code = &r300->blit.fp_code;
124 compiler.AllocateHwInputs = fp_allocate_hw_inputs;
125
126 r3xx_compile_fragment_program(&compiler);
127 }
128
129 void r300_blit_init(struct r300_context *r300)
130 {
131 if (r300->options.hw_tcl_enabled)
132 create_vertex_program(r300);
133 create_fragment_program(r300);
134 }
135
136 static void r300_emit_tx_setup(struct r300_context *r300,
137 gl_format mesa_format,
138 struct radeon_bo *bo,
139 intptr_t offset,
140 unsigned width,
141 unsigned height,
142 unsigned pitch)
143 {
144 BATCH_LOCALS(&r300->radeon);
145
146 assert(width <= 2048);
147 assert(height <= 2048);
148 assert(r300TranslateTexFormat(mesa_format) >= 0);
149 assert(offset % 32 == 0);
150
151 BEGIN_BATCH(17);
152 OUT_BATCH_REGVAL(R300_TX_FILTER0_0,
153 (R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_S_SHIFT) |
154 (R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_T_SHIFT) |
155 (R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_R_SHIFT) |
156 R300_TX_MIN_FILTER_MIP_NONE |
157 R300_TX_MIN_FILTER_NEAREST |
158 R300_TX_MAG_FILTER_NEAREST |
159 (0 << 28));
160 OUT_BATCH_REGVAL(R300_TX_FILTER1_0, 0);
161 OUT_BATCH_REGVAL(R300_TX_SIZE_0,
162 ((width-1) << R300_TX_WIDTHMASK_SHIFT) |
163 ((height-1) << R300_TX_HEIGHTMASK_SHIFT) |
164 (0 << R300_TX_DEPTHMASK_SHIFT) |
165 (0 << R300_TX_MAX_MIP_LEVEL_SHIFT) |
166 R300_TX_SIZE_TXPITCH_EN);
167
168 OUT_BATCH_REGVAL(R300_TX_FORMAT_0, r300TranslateTexFormat(mesa_format));
169 OUT_BATCH_REGVAL(R300_TX_FORMAT2_0, pitch - 1);
170 OUT_BATCH_REGSEQ(R300_TX_OFFSET_0, 1);
171 OUT_BATCH_RELOC(0, bo, offset, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
172
173 OUT_BATCH_REGSEQ(R300_TX_INVALTAGS, 2);
174 OUT_BATCH(0);
175 OUT_BATCH(1);
176
177 END_BATCH();
178 }
179
180 #define EASY_US_FORMAT(FMT, C0, C1, C2, C3, SIGN) \
181 (FMT | R500_C0_SEL_##C0 | R500_C1_SEL_##C1 | \
182 R500_C2_SEL_##C2 | R500_C3_SEL_##C3 | R500_OUT_SIGN(SIGN))
183
184 static uint32_t mesa_format_to_us_format(gl_format mesa_format)
185 {
186 switch(mesa_format)
187 {
188 case MESA_FORMAT_RGBA8888: // x
189 return EASY_US_FORMAT(R500_OUT_FMT_C4_8, A, B, G, R, 0);
190 case MESA_FORMAT_RGB565: // x
191 case MESA_FORMAT_ARGB1555: // x
192 case MESA_FORMAT_RGBA8888_REV: // x
193 return EASY_US_FORMAT(R500_OUT_FMT_C4_8, R, G, B, A, 0);
194 case MESA_FORMAT_ARGB8888: // x
195 return EASY_US_FORMAT(R500_OUT_FMT_C4_8, B, G, R, A, 0);
196 case MESA_FORMAT_ARGB8888_REV:
197 return EASY_US_FORMAT(R500_OUT_FMT_C4_8, A, R, G, B, 0);
198 case MESA_FORMAT_XRGB8888:
199 return EASY_US_FORMAT(R500_OUT_FMT_C4_8, A, R, G, B, 0);
200
201 case MESA_FORMAT_RGB332:
202 return EASY_US_FORMAT(R500_OUT_FMT_C_3_3_2, A, R, G, B, 0);
203
204 case MESA_FORMAT_RGBA_FLOAT32:
205 return EASY_US_FORMAT(R500_OUT_FMT_C4_32_FP, R, G, B, A, 0);
206 case MESA_FORMAT_RGBA_FLOAT16:
207 return EASY_US_FORMAT(R500_OUT_FMT_C4_16_FP, R, G, B, A, 0);
208 case MESA_FORMAT_ALPHA_FLOAT32:
209 return EASY_US_FORMAT(R500_OUT_FMT_C_32_FP, A, A, A, A, 0);
210 case MESA_FORMAT_ALPHA_FLOAT16:
211 return EASY_US_FORMAT(R500_OUT_FMT_C_16_FP, A, A, A, A, 0);
212
213 case MESA_FORMAT_SIGNED_RGBA8888:
214 return EASY_US_FORMAT(R500_OUT_FMT_C4_8, R, G, B, A, 0xf);
215 case MESA_FORMAT_SIGNED_RGBA8888_REV:
216 return EASY_US_FORMAT(R500_OUT_FMT_C4_8, A, B, G, R, 0xf);
217 case MESA_FORMAT_SIGNED_RGBA_16:
218 return EASY_US_FORMAT(R500_OUT_FMT_C4_16, R, G, B, A, 0xf);
219
220 default:
221 fprintf(stderr, "Unsupported format %s for US output\n", _mesa_get_format_name(mesa_format));
222 assert(0);
223 return 0;
224 }
225 }
226 #undef EASY_US_FORMAT
227
228 static void r500_emit_fp_setup(struct r300_context *r300,
229 struct r500_fragment_program_code *fp,
230 gl_format dst_format)
231 {
232 r500_emit_fp(r300, (uint32_t *)fp->inst, (fp->inst_end + 1) * 6, 0, 0, 0);
233 BATCH_LOCALS(&r300->radeon);
234
235 BEGIN_BATCH(10);
236 OUT_BATCH_REGSEQ(R500_US_CODE_ADDR, 3);
237 OUT_BATCH(R500_US_CODE_START_ADDR(0) | R500_US_CODE_END_ADDR(fp->inst_end));
238 OUT_BATCH(R500_US_CODE_RANGE_ADDR(0) | R500_US_CODE_RANGE_SIZE(fp->inst_end));
239 OUT_BATCH(0);
240 OUT_BATCH_REGVAL(R500_US_CONFIG, 0);
241 OUT_BATCH_REGVAL(R500_US_OUT_FMT_0, mesa_format_to_us_format(dst_format));
242 OUT_BATCH_REGVAL(R500_US_PIXSIZE, fp->max_temp_idx);
243 END_BATCH();
244 }
245
246 static void r500_emit_rs_setup(struct r300_context *r300)
247 {
248 BATCH_LOCALS(&r300->radeon);
249
250 BEGIN_BATCH(7);
251 OUT_BATCH_REGSEQ(R300_RS_COUNT, 2);
252 OUT_BATCH((4 << R300_IT_COUNT_SHIFT) | R300_HIRES_EN);
253 OUT_BATCH(0);
254 OUT_BATCH_REGVAL(R500_RS_INST_0,
255 (0 << R500_RS_INST_TEX_ID_SHIFT) |
256 (0 << R500_RS_INST_TEX_ADDR_SHIFT) |
257 R500_RS_INST_TEX_CN_WRITE |
258 R500_RS_INST_COL_CN_NO_WRITE);
259 OUT_BATCH_REGVAL(R500_RS_IP_0,
260 (0 << R500_RS_IP_TEX_PTR_S_SHIFT) |
261 (1 << R500_RS_IP_TEX_PTR_T_SHIFT) |
262 (2 << R500_RS_IP_TEX_PTR_R_SHIFT) |
263 (3 << R500_RS_IP_TEX_PTR_Q_SHIFT));
264 END_BATCH();
265 }
266
267 static void r300_emit_fp_setup(struct r300_context *r300,
268 struct r300_fragment_program_code *code,
269 gl_format dst_format)
270 {
271 unsigned i;
272 BATCH_LOCALS(&r300->radeon);
273
274 BEGIN_BATCH((code->alu.length + 1) * 4 + code->tex.length + 1 + 11);
275
276 OUT_BATCH_REGSEQ(R300_US_ALU_RGB_INST_0, code->alu.length);
277 for (i = 0; i < code->alu.length; i++) {
278 OUT_BATCH(code->alu.inst[i].rgb_inst);
279 }
280 OUT_BATCH_REGSEQ(R300_US_ALU_RGB_ADDR_0, code->alu.length);
281 for (i = 0; i < code->alu.length; i++) {
282 OUT_BATCH(code->alu.inst[i].rgb_addr);
283 }
284 OUT_BATCH_REGSEQ(R300_US_ALU_ALPHA_INST_0, code->alu.length);
285 for (i = 0; i < code->alu.length; i++) {
286 OUT_BATCH(code->alu.inst[i].alpha_inst);
287 }
288 OUT_BATCH_REGSEQ(R300_US_ALU_ALPHA_ADDR_0, code->alu.length);
289 for (i = 0; i < code->alu.length; i++) {
290 OUT_BATCH(code->alu.inst[i].alpha_addr);
291 }
292
293 OUT_BATCH_REGSEQ(R300_US_TEX_INST_0, code->tex.length);
294 OUT_BATCH_TABLE(code->tex.inst, code->tex.length);
295
296 OUT_BATCH_REGSEQ(R300_US_CONFIG, 3);
297 OUT_BATCH(R300_PFS_CNTL_FIRST_NODE_HAS_TEX);
298 OUT_BATCH(code->pixsize);
299 OUT_BATCH(code->code_offset);
300 OUT_BATCH_REGSEQ(R300_US_CODE_ADDR_0, 4);
301 OUT_BATCH_TABLE(code->code_addr, 4);
302 OUT_BATCH_REGVAL(R500_US_OUT_FMT_0, mesa_format_to_us_format(dst_format));
303 END_BATCH();
304 }
305
306 static void r300_emit_rs_setup(struct r300_context *r300)
307 {
308 BATCH_LOCALS(&r300->radeon);
309
310 BEGIN_BATCH(7);
311 OUT_BATCH_REGSEQ(R300_RS_COUNT, 2);
312 OUT_BATCH((4 << R300_IT_COUNT_SHIFT) | R300_HIRES_EN);
313 OUT_BATCH(0);
314 OUT_BATCH_REGVAL(R300_RS_INST_0,
315 R300_RS_INST_TEX_ID(0) |
316 R300_RS_INST_TEX_ADDR(0) |
317 R300_RS_INST_TEX_CN_WRITE);
318 OUT_BATCH_REGVAL(R300_RS_IP_0,
319 R300_RS_TEX_PTR(0) |
320 R300_RS_SEL_S(R300_RS_SEL_C0) |
321 R300_RS_SEL_T(R300_RS_SEL_C1) |
322 R300_RS_SEL_R(R300_RS_SEL_K0) |
323 R300_RS_SEL_Q(R300_RS_SEL_K1));
324 END_BATCH();
325 }
326
327 static void emit_pvs_setup(struct r300_context *r300,
328 uint32_t *vp_code,
329 unsigned vp_len)
330 {
331 BATCH_LOCALS(&r300->radeon);
332
333 r300_emit_vpu(r300, vp_code, vp_len * 4, R300_PVS_CODE_START);
334
335 BEGIN_BATCH(4);
336 OUT_BATCH_REGSEQ(R300_VAP_PVS_CODE_CNTL_0, 3);
337 OUT_BATCH((0 << R300_PVS_FIRST_INST_SHIFT) |
338 ((vp_len - 1) << R300_PVS_XYZW_VALID_INST_SHIFT) |
339 ((vp_len - 1)<< R300_PVS_LAST_INST_SHIFT));
340 OUT_BATCH(0);
341 OUT_BATCH((vp_len - 1) << R300_PVS_LAST_VTX_SRC_INST_SHIFT);
342 END_BATCH();
343 }
344
345 static void emit_vap_setup(struct r300_context *r300)
346 {
347 int tex_offset;
348 BATCH_LOCALS(&r300->radeon);
349
350 if (r300->options.hw_tcl_enabled)
351 tex_offset = 1;
352 else
353 tex_offset = 6;
354
355 BEGIN_BATCH(12);
356 OUT_BATCH_REGSEQ(R300_SE_VTE_CNTL, 2);
357 OUT_BATCH(R300_VTX_XY_FMT | R300_VTX_Z_FMT);
358 OUT_BATCH(4);
359
360 OUT_BATCH_REGVAL(R300_VAP_PSC_SGN_NORM_CNTL, 0xaaaaaaaa);
361 OUT_BATCH_REGVAL(R300_VAP_PROG_STREAM_CNTL_0,
362 ((R300_DATA_TYPE_FLOAT_2 | (0 << R300_DST_VEC_LOC_SHIFT)) << 0) |
363 (((tex_offset << R300_DST_VEC_LOC_SHIFT) | R300_DATA_TYPE_FLOAT_2 | R300_LAST_VEC) << 16));
364 OUT_BATCH_REGVAL(R300_VAP_PROG_STREAM_CNTL_EXT_0,
365 ((((R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_SHIFT) |
366 (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_SHIFT) |
367 (R300_SWIZZLE_SELECT_FP_ZERO << R300_SWIZZLE_SELECT_Z_SHIFT) |
368 (R300_SWIZZLE_SELECT_FP_ONE << R300_SWIZZLE_SELECT_W_SHIFT) |
369 (0xf << R300_WRITE_ENA_SHIFT) ) << 0) |
370 (((R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_SHIFT) |
371 (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_SHIFT) |
372 (R300_SWIZZLE_SELECT_FP_ZERO << R300_SWIZZLE_SELECT_Z_SHIFT) |
373 (R300_SWIZZLE_SELECT_FP_ONE << R300_SWIZZLE_SELECT_W_SHIFT) |
374 (0xf << R300_WRITE_ENA_SHIFT) ) << 16) ) );
375 OUT_BATCH_REGSEQ(R300_VAP_OUTPUT_VTX_FMT_0, 2);
376 OUT_BATCH(R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT);
377 OUT_BATCH(R300_VAP_OUTPUT_VTX_FMT_1__4_COMPONENTS);
378 END_BATCH();
379 }
380
381 static GLboolean validate_buffers(struct r300_context *r300,
382 struct radeon_bo *src_bo,
383 struct radeon_bo *dst_bo)
384 {
385 int ret;
386
387 radeon_cs_space_reset_bos(r300->radeon.cmdbuf.cs);
388
389 ret = radeon_cs_space_check_with_bo(r300->radeon.cmdbuf.cs,
390 src_bo, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0);
391 if (ret)
392 return GL_FALSE;
393
394 ret = radeon_cs_space_check_with_bo(r300->radeon.cmdbuf.cs,
395 dst_bo, 0, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT);
396 if (ret)
397 return GL_FALSE;
398
399 return GL_TRUE;
400 }
401
402 /**
403 * Calculate texcoords for given image region.
404 * Output values are [minx, maxx, miny, maxy]
405 */
406 static void calc_tex_coords(float img_width, float img_height,
407 float x, float y,
408 float reg_width, float reg_height,
409 unsigned flip_y, float *buf)
410 {
411 buf[0] = x / img_width;
412 buf[1] = buf[0] + reg_width / img_width;
413 buf[2] = y / img_height;
414 buf[3] = buf[2] + reg_height / img_height;
415 if (flip_y)
416 {
417 buf[2] = 1.0 - buf[2];
418 buf[3] = 1.0 - buf[3];
419 }
420 }
421
422 static void emit_draw_packet(struct r300_context *r300,
423 unsigned src_width, unsigned src_height,
424 unsigned src_x_offset, unsigned src_y_offset,
425 unsigned dst_x_offset, unsigned dst_y_offset,
426 unsigned reg_width, unsigned reg_height,
427 unsigned flip_y)
428 {
429 float texcoords[4];
430
431 calc_tex_coords(src_width, src_height,
432 src_x_offset, src_y_offset,
433 reg_width, reg_height,
434 flip_y, texcoords);
435
436 float verts[] = { dst_x_offset, dst_y_offset,
437 texcoords[0], texcoords[2],
438 dst_x_offset, dst_y_offset + reg_height,
439 texcoords[0], texcoords[3],
440 dst_x_offset + reg_width, dst_y_offset + reg_height,
441 texcoords[1], texcoords[3],
442 dst_x_offset + reg_width, dst_y_offset,
443 texcoords[1], texcoords[2] };
444
445 BATCH_LOCALS(&r300->radeon);
446
447 BEGIN_BATCH(19);
448 OUT_BATCH_PACKET3(R300_PACKET3_3D_DRAW_IMMD_2, 16);
449 OUT_BATCH(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED |
450 (4 << 16) | R300_VAP_VF_CNTL__PRIM_QUADS);
451 OUT_BATCH_TABLE(verts, 16);
452 END_BATCH();
453 }
454
455 static void other_stuff(struct r300_context *r300)
456 {
457 BATCH_LOCALS(&r300->radeon);
458
459 BEGIN_BATCH(13);
460 OUT_BATCH_REGVAL(R300_GA_POLY_MODE,
461 R300_GA_POLY_MODE_FRONT_PTYPE_TRI | R300_GA_POLY_MODE_BACK_PTYPE_TRI);
462 OUT_BATCH_REGVAL(R300_SU_CULL_MODE, R300_FRONT_FACE_CCW);
463 OUT_BATCH_REGVAL(R300_FG_FOG_BLEND, 0);
464 OUT_BATCH_REGVAL(R300_FG_ALPHA_FUNC, 0);
465 OUT_BATCH_REGSEQ(R300_RB3D_CBLEND, 2);
466 OUT_BATCH(0x0);
467 OUT_BATCH(0x0);
468 OUT_BATCH_REGVAL(R300_ZB_CNTL, 0);
469 END_BATCH();
470 if (r300->options.hw_tcl_enabled) {
471 BEGIN_BATCH(2);
472 OUT_BATCH_REGVAL(R300_VAP_CLIP_CNTL, R300_CLIP_DISABLE);
473 END_BATCH();
474 }
475 }
476
477 static void emit_cb_setup(struct r300_context *r300,
478 struct radeon_bo *bo,
479 intptr_t offset,
480 gl_format mesa_format,
481 unsigned pitch,
482 unsigned width,
483 unsigned height)
484 {
485 BATCH_LOCALS(&r300->radeon);
486
487 unsigned x1, y1, x2, y2;
488 x1 = 0;
489 y1 = 0;
490 x2 = width - 1;
491 y2 = height - 1;
492
493 if (r300->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV515) {
494 x1 += R300_SCISSORS_OFFSET;
495 y1 += R300_SCISSORS_OFFSET;
496 x2 += R300_SCISSORS_OFFSET;
497 y2 += R300_SCISSORS_OFFSET;
498 }
499
500 r300_emit_cb_setup(r300, bo, offset, mesa_format,
501 _mesa_get_format_bytes(mesa_format),
502 _mesa_format_row_stride(mesa_format, pitch));
503
504 BEGIN_BATCH_NO_AUTOSTATE(5);
505 OUT_BATCH_REGSEQ(R300_SC_SCISSORS_TL, 2);
506 OUT_BATCH((x1 << R300_SCISSORS_X_SHIFT)|(y1 << R300_SCISSORS_Y_SHIFT));
507 OUT_BATCH((x2 << R300_SCISSORS_X_SHIFT)|(y2 << R300_SCISSORS_Y_SHIFT));
508 OUT_BATCH_REGVAL(R300_RB3D_CCTL, 0);
509 END_BATCH();
510 }
511
512 unsigned r300_check_blit(gl_format dst_format)
513 {
514 switch (dst_format) {
515 case MESA_FORMAT_RGB565:
516 case MESA_FORMAT_ARGB1555:
517 case MESA_FORMAT_RGBA8888:
518 case MESA_FORMAT_RGBA8888_REV:
519 case MESA_FORMAT_ARGB8888:
520 case MESA_FORMAT_ARGB8888_REV:
521 case MESA_FORMAT_XRGB8888:
522 break;
523 default:
524 return 0;
525 }
526
527 if (_mesa_get_format_bits(dst_format, GL_DEPTH_BITS) > 0)
528 return 0;
529
530 return 1;
531 }
532
533 /**
534 * Copy a region of [@a width x @a height] pixels from source buffer
535 * to destination buffer.
536 * @param[in] r300 r300 context
537 * @param[in] src_bo source radeon buffer object
538 * @param[in] src_offset offset of the source image in the @a src_bo
539 * @param[in] src_mesaformat source image format
540 * @param[in] src_pitch aligned source image width
541 * @param[in] src_width source image width
542 * @param[in] src_height source image height
543 * @param[in] src_x_offset x offset in the source image
544 * @param[in] src_y_offset y offset in the source image
545 * @param[in] dst_bo destination radeon buffer object
546 * @param[in] dst_offset offset of the destination image in the @a dst_bo
547 * @param[in] dst_mesaformat destination image format
548 * @param[in] dst_pitch aligned destination image width
549 * @param[in] dst_width destination image width
550 * @param[in] dst_height destination image height
551 * @param[in] dst_x_offset x offset in the destination image
552 * @param[in] dst_y_offset y offset in the destination image
553 * @param[in] width region width
554 * @param[in] height region height
555 * @param[in] flip_y set if y coords of the source image need to be flipped
556 */
557 unsigned r300_blit(GLcontext *ctx,
558 struct radeon_bo *src_bo,
559 intptr_t src_offset,
560 gl_format src_mesaformat,
561 unsigned src_pitch,
562 unsigned src_width,
563 unsigned src_height,
564 unsigned src_x_offset,
565 unsigned src_y_offset,
566 struct radeon_bo *dst_bo,
567 intptr_t dst_offset,
568 gl_format dst_mesaformat,
569 unsigned dst_pitch,
570 unsigned dst_width,
571 unsigned dst_height,
572 unsigned dst_x_offset,
573 unsigned dst_y_offset,
574 unsigned reg_width,
575 unsigned reg_height,
576 unsigned flip_y)
577 {
578 r300ContextPtr r300 = R300_CONTEXT(ctx);
579
580 if (!r300_check_blit(dst_mesaformat))
581 return 0;
582
583 /* Make sure that colorbuffer has even width - hw limitation */
584 if (dst_pitch % 2 > 0)
585 ++dst_pitch;
586
587 /* Need to clamp the region size to make sure
588 * we don't read outside of the source buffer
589 * or write outside of the destination buffer.
590 */
591 if (reg_width + src_x_offset > src_width)
592 reg_width = src_width - src_x_offset;
593 if (reg_height + src_y_offset > src_height)
594 reg_height = src_height - src_y_offset;
595 if (reg_width + dst_x_offset > dst_width)
596 reg_width = dst_width - dst_x_offset;
597 if (reg_height + dst_y_offset > dst_height)
598 reg_height = dst_height - dst_y_offset;
599
600 if (src_bo == dst_bo) {
601 return 0;
602 }
603
604 if (src_offset % 32 || dst_offset % 32) {
605 return GL_FALSE;
606 }
607
608 if (0) {
609 fprintf(stderr, "src: size [%d x %d], pitch %d, "
610 "offset [%d x %d], format %s, bo %p\n",
611 src_width, src_height, src_pitch,
612 src_x_offset, src_y_offset,
613 _mesa_get_format_name(src_mesaformat),
614 src_bo);
615 fprintf(stderr, "dst: pitch %d, offset[%d x %d], format %s, bo %p\n",
616 dst_pitch, dst_x_offset, dst_y_offset,
617 _mesa_get_format_name(dst_mesaformat), dst_bo);
618 fprintf(stderr, "region: %d x %d\n", reg_width, reg_height);
619 }
620
621 /* Flush is needed to make sure that source buffer has correct data */
622 radeonFlush(r300->radeon.glCtx);
623
624 if (!validate_buffers(r300, src_bo, dst_bo))
625 return 0;
626
627 rcommonEnsureCmdBufSpace(&r300->radeon, 200, __FUNCTION__);
628
629 other_stuff(r300);
630
631 r300_emit_tx_setup(r300, src_mesaformat, src_bo, src_offset, src_width, src_height, src_pitch);
632
633 if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
634 r500_emit_fp_setup(r300, &r300->blit.fp_code.code.r500, dst_mesaformat);
635 r500_emit_rs_setup(r300);
636 } else {
637 r300_emit_fp_setup(r300, &r300->blit.fp_code.code.r300, dst_mesaformat);
638 r300_emit_rs_setup(r300);
639 }
640
641 if (r300->options.hw_tcl_enabled)
642 emit_pvs_setup(r300, r300->blit.vp_code.body.d, 2);
643
644 emit_vap_setup(r300);
645
646 emit_cb_setup(r300, dst_bo, dst_offset, dst_mesaformat, dst_pitch, dst_width, dst_height);
647
648 emit_draw_packet(r300, src_width, src_height,
649 src_x_offset, src_y_offset,
650 dst_x_offset, dst_y_offset,
651 reg_width, reg_height,
652 flip_y);
653
654 r300EmitCacheFlush(r300);
655
656 radeonFlush(r300->radeon.glCtx);
657
658 return 1;
659 }