r300: setup render target format for r300/r400 cards too
[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 rc_init(&compiler.Base);
101
102 inst = rc_insert_new_instruction(&compiler.Base, compiler.Base.Program.Instructions.Prev);
103 inst->U.I.Opcode = RC_OPCODE_TEX;
104 inst->U.I.TexSrcTarget = RC_TEXTURE_2D;
105 inst->U.I.TexSrcUnit = 0;
106 inst->U.I.DstReg.File = RC_FILE_OUTPUT;
107 inst->U.I.DstReg.Index = FRAG_RESULT_COLOR;
108 inst->U.I.DstReg.WriteMask = RC_MASK_XYZW;
109 inst->U.I.SrcReg[0].Abs = 0;
110 inst->U.I.SrcReg[0].File = RC_FILE_INPUT;
111 inst->U.I.SrcReg[0].Index = FRAG_ATTRIB_TEX0;
112 inst->U.I.SrcReg[0].Negate = 0;
113 inst->U.I.SrcReg[0].RelAddr = 0;
114 inst->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_XYZW;
115
116 compiler.Base.Program.InputsRead = (1 << FRAG_ATTRIB_TEX0);
117 compiler.OutputColor = FRAG_RESULT_COLOR;
118 compiler.OutputDepth = FRAG_RESULT_DEPTH;
119 compiler.is_r500 = (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515);
120 compiler.code = &r300->blit.fp_code;
121 compiler.AllocateHwInputs = fp_allocate_hw_inputs;
122
123 r3xx_compile_fragment_program(&compiler);
124 }
125
126 void r300_blit_init(struct r300_context *r300)
127 {
128 create_vertex_program(r300);
129 create_fragment_program(r300);
130 }
131
132 static void r300_emit_tx_setup(struct r300_context *r300,
133 gl_format mesa_format,
134 struct radeon_bo *bo,
135 intptr_t offset,
136 unsigned width,
137 unsigned height,
138 unsigned pitch)
139 {
140 BATCH_LOCALS(&r300->radeon);
141
142 assert(width <= 2048);
143 assert(height <= 2048);
144 assert(r300TranslateTexFormat(mesa_format) != 0);
145 assert(offset % 32 == 0);
146
147 BEGIN_BATCH(17);
148 OUT_BATCH_REGVAL(R300_TX_FILTER0_0,
149 (R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_S_SHIFT) |
150 (R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_T_SHIFT) |
151 (R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_R_SHIFT) |
152 R300_TX_MIN_FILTER_MIP_NONE |
153 R300_TX_MIN_FILTER_LINEAR |
154 R300_TX_MAG_FILTER_LINEAR |
155 (0 << 28));
156 OUT_BATCH_REGVAL(R300_TX_FILTER1_0, 0);
157 OUT_BATCH_REGVAL(R300_TX_SIZE_0,
158 ((width-1) << R300_TX_WIDTHMASK_SHIFT) |
159 ((height-1) << R300_TX_HEIGHTMASK_SHIFT) |
160 (0 << R300_TX_DEPTHMASK_SHIFT) |
161 (0 << R300_TX_MAX_MIP_LEVEL_SHIFT) |
162 R300_TX_SIZE_TXPITCH_EN);
163
164 OUT_BATCH_REGVAL(R300_TX_FORMAT_0, r300TranslateTexFormat(mesa_format));
165 OUT_BATCH_REGVAL(R300_TX_FORMAT2_0, pitch/_mesa_get_format_bytes(mesa_format) - 1);
166 OUT_BATCH_REGSEQ(R300_TX_OFFSET_0, 1);
167 OUT_BATCH_RELOC(0, bo, offset, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
168
169 OUT_BATCH_REGSEQ(R300_TX_INVALTAGS, 2);
170 OUT_BATCH(0);
171 OUT_BATCH(1);
172
173 END_BATCH();
174 }
175
176 #define EASY_US_FORMAT(FMT, C0, C1, C2, C3, SIGN) \
177 (FMT | R500_C0_SEL_##C0 | R500_C1_SEL_##C1 | \
178 R500_C2_SEL_##C2 | R500_C3_SEL_##C3 | R500_OUT_SIGN(SIGN))
179
180 static uint32_t mesa_format_to_us_format(gl_format mesa_format)
181 {
182 switch(mesa_format)
183 {
184 case MESA_FORMAT_S8_Z24:
185 case MESA_FORMAT_X8_Z24:
186 case MESA_FORMAT_RGBA8888: // x
187 return EASY_US_FORMAT(R500_OUT_FMT_C4_8, A, B, G, R, 0);
188 case MESA_FORMAT_RGB565: // x
189 case MESA_FORMAT_ARGB1555: // x
190 case MESA_FORMAT_RGBA8888_REV: // x
191 return EASY_US_FORMAT(R500_OUT_FMT_C4_8, R, G, B, A, 0);
192 case MESA_FORMAT_ARGB8888: // x
193 return EASY_US_FORMAT(R500_OUT_FMT_C4_8, B, G, R, A, 0);
194 case MESA_FORMAT_ARGB8888_REV:
195 return EASY_US_FORMAT(R500_OUT_FMT_C4_8, A, R, G, B, 0);
196 case MESA_FORMAT_XRGB8888:
197 return EASY_US_FORMAT(R500_OUT_FMT_C4_8, A, R, G, B, 0);
198
199 case MESA_FORMAT_RGB332:
200 return EASY_US_FORMAT(R500_OUT_FMT_C_3_3_2, A, R, G, B, 0);
201
202 case MESA_FORMAT_RGBA_FLOAT32:
203 return EASY_US_FORMAT(R500_OUT_FMT_C4_32_FP, R, G, B, A, 0);
204 case MESA_FORMAT_RGBA_FLOAT16:
205 return EASY_US_FORMAT(R500_OUT_FMT_C4_16_FP, R, G, B, A, 0);
206 case MESA_FORMAT_ALPHA_FLOAT32:
207 return EASY_US_FORMAT(R500_OUT_FMT_C_32_FP, A, A, A, A, 0);
208 case MESA_FORMAT_ALPHA_FLOAT16:
209 return EASY_US_FORMAT(R500_OUT_FMT_C_16_FP, A, A, A, A, 0);
210
211 case MESA_FORMAT_SIGNED_RGBA8888:
212 return EASY_US_FORMAT(R500_OUT_FMT_C4_8, R, G, B, A, 0xf);
213 case MESA_FORMAT_SIGNED_RGBA8888_REV:
214 return EASY_US_FORMAT(R500_OUT_FMT_C4_8, A, B, G, R, 0xf);
215 case MESA_FORMAT_SIGNED_RGBA_16:
216 return EASY_US_FORMAT(R500_OUT_FMT_C4_16, R, G, B, A, 0xf);
217
218 default:
219 assert(!"Invalid format for US output\n");
220 return 0;
221 }
222 }
223 #undef EASY_US_FORMAT
224
225 static void r500_emit_fp_setup(struct r300_context *r300,
226 struct r500_fragment_program_code *fp,
227 gl_format dst_format)
228 {
229 r500_emit_fp(r300, (uint32_t *)fp->inst, (fp->inst_end + 1) * 6, 0, 0, 0);
230 BATCH_LOCALS(&r300->radeon);
231
232 BEGIN_BATCH(10);
233 OUT_BATCH_REGSEQ(R500_US_CODE_ADDR, 3);
234 OUT_BATCH(R500_US_CODE_START_ADDR(0) | R500_US_CODE_END_ADDR(fp->inst_end));
235 OUT_BATCH(R500_US_CODE_RANGE_ADDR(0) | R500_US_CODE_RANGE_SIZE(fp->inst_end));
236 OUT_BATCH(0);
237 OUT_BATCH_REGVAL(R500_US_CONFIG, 0);
238 OUT_BATCH_REGVAL(R500_US_OUT_FMT_0, mesa_format_to_us_format(dst_format));
239 OUT_BATCH_REGVAL(R500_US_PIXSIZE, fp->max_temp_idx);
240 END_BATCH();
241 }
242
243 static void r500_emit_rs_setup(struct r300_context *r300)
244 {
245 BATCH_LOCALS(&r300->radeon);
246
247 BEGIN_BATCH(7);
248 OUT_BATCH_REGSEQ(R300_RS_COUNT, 2);
249 OUT_BATCH((4 << R300_IT_COUNT_SHIFT) | R300_HIRES_EN);
250 OUT_BATCH(0);
251 OUT_BATCH_REGVAL(R500_RS_INST_0,
252 (0 << R500_RS_INST_TEX_ID_SHIFT) |
253 (0 << R500_RS_INST_TEX_ADDR_SHIFT) |
254 R500_RS_INST_TEX_CN_WRITE |
255 R500_RS_INST_COL_CN_NO_WRITE);
256 OUT_BATCH_REGVAL(R500_RS_IP_0,
257 (0 << R500_RS_IP_TEX_PTR_S_SHIFT) |
258 (1 << R500_RS_IP_TEX_PTR_T_SHIFT) |
259 (2 << R500_RS_IP_TEX_PTR_R_SHIFT) |
260 (3 << R500_RS_IP_TEX_PTR_Q_SHIFT));
261 END_BATCH();
262 }
263
264 static void r300_emit_fp_setup(struct r300_context *r300,
265 struct r300_fragment_program_code *code,
266 gl_format dst_format)
267 {
268 unsigned i;
269 BATCH_LOCALS(&r300->radeon);
270
271 BEGIN_BATCH((code->alu.length + 1) * 4 + code->tex.length + 1 + 11);
272
273 OUT_BATCH_REGSEQ(R300_US_ALU_RGB_INST_0, code->alu.length);
274 for (i = 0; i < code->alu.length; i++) {
275 OUT_BATCH(code->alu.inst[i].rgb_inst);
276 }
277 OUT_BATCH_REGSEQ(R300_US_ALU_RGB_ADDR_0, code->alu.length);
278 for (i = 0; i < code->alu.length; i++) {
279 OUT_BATCH(code->alu.inst[i].rgb_addr);
280 }
281 OUT_BATCH_REGSEQ(R300_US_ALU_ALPHA_INST_0, code->alu.length);
282 for (i = 0; i < code->alu.length; i++) {
283 OUT_BATCH(code->alu.inst[i].alpha_inst);
284 }
285 OUT_BATCH_REGSEQ(R300_US_ALU_ALPHA_ADDR_0, code->alu.length);
286 for (i = 0; i < code->alu.length; i++) {
287 OUT_BATCH(code->alu.inst[i].alpha_addr);
288 }
289
290 OUT_BATCH_REGSEQ(R300_US_TEX_INST_0, code->tex.length);
291 OUT_BATCH_TABLE(code->tex.inst, code->tex.length);
292
293 OUT_BATCH_REGSEQ(R300_US_CONFIG, 3);
294 OUT_BATCH(R300_PFS_CNTL_FIRST_NODE_HAS_TEX);
295 OUT_BATCH(code->pixsize);
296 OUT_BATCH(code->code_offset);
297 OUT_BATCH_REGSEQ(R300_US_CODE_ADDR_0, 4);
298 OUT_BATCH_TABLE(code->code_addr, 4);
299 OUT_BATCH_REGVAL(R500_US_OUT_FMT_0, mesa_format_to_us_format(dst_format));
300 END_BATCH();
301 }
302
303 static void r300_emit_rs_setup(struct r300_context *r300)
304 {
305 BATCH_LOCALS(&r300->radeon);
306
307 BEGIN_BATCH(7);
308 OUT_BATCH_REGSEQ(R300_RS_COUNT, 2);
309 OUT_BATCH((4 << R300_IT_COUNT_SHIFT) | R300_HIRES_EN);
310 OUT_BATCH(0);
311 OUT_BATCH_REGVAL(R300_RS_INST_0,
312 R300_RS_INST_TEX_ID(0) |
313 R300_RS_INST_TEX_ADDR(0) |
314 R300_RS_INST_TEX_CN_WRITE);
315 OUT_BATCH_REGVAL(R300_RS_IP_0,
316 R300_RS_TEX_PTR(0) |
317 R300_RS_SEL_S(R300_RS_SEL_C0) |
318 R300_RS_SEL_R(R300_RS_SEL_C1) |
319 R300_RS_SEL_T(R300_RS_SEL_K0) |
320 R300_RS_SEL_Q(R300_RS_SEL_K1));
321 END_BATCH();
322 }
323
324 static void emit_pvs_setup(struct r300_context *r300,
325 uint32_t *vp_code,
326 unsigned vp_len)
327 {
328 BATCH_LOCALS(&r300->radeon);
329
330 r300_emit_vpu(r300, vp_code, vp_len * 4, R300_PVS_CODE_START);
331
332 BEGIN_BATCH(4);
333 OUT_BATCH_REGSEQ(R300_VAP_PVS_CODE_CNTL_0, 3);
334 OUT_BATCH((0 << R300_PVS_FIRST_INST_SHIFT) |
335 ((vp_len - 1) << R300_PVS_XYZW_VALID_INST_SHIFT) |
336 ((vp_len - 1)<< R300_PVS_LAST_INST_SHIFT));
337 OUT_BATCH(0);
338 OUT_BATCH((vp_len - 1) << R300_PVS_LAST_VTX_SRC_INST_SHIFT);
339 END_BATCH();
340 }
341
342 static void emit_vap_setup(struct r300_context *r300, unsigned width, unsigned height)
343 {
344 BATCH_LOCALS(&r300->radeon);
345
346 BEGIN_BATCH(12);
347 OUT_BATCH_REGSEQ(R300_SE_VTE_CNTL, 2);
348 OUT_BATCH(R300_VTX_XY_FMT | R300_VTX_Z_FMT);
349 OUT_BATCH(4);
350
351 OUT_BATCH_REGVAL(R300_VAP_PSC_SGN_NORM_CNTL, 0xaaaaaaaa);
352 OUT_BATCH_REGVAL(R300_VAP_PROG_STREAM_CNTL_0,
353 ((R300_DATA_TYPE_FLOAT_2 | (0 << R300_DST_VEC_LOC_SHIFT)) << 0) |
354 (((1 << R300_DST_VEC_LOC_SHIFT) | R300_DATA_TYPE_FLOAT_2 | R300_LAST_VEC) << 16));
355 OUT_BATCH_REGVAL(R300_VAP_PROG_STREAM_CNTL_EXT_0,
356 ((((R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_SHIFT) |
357 (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_SHIFT) |
358 (R300_SWIZZLE_SELECT_FP_ZERO << R300_SWIZZLE_SELECT_Z_SHIFT) |
359 (R300_SWIZZLE_SELECT_FP_ONE << R300_SWIZZLE_SELECT_W_SHIFT) |
360 (0xf << R300_WRITE_ENA_SHIFT) ) << 0) |
361 (((R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_SHIFT) |
362 (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_SHIFT) |
363 (R300_SWIZZLE_SELECT_FP_ZERO << R300_SWIZZLE_SELECT_Z_SHIFT) |
364 (R300_SWIZZLE_SELECT_FP_ONE << R300_SWIZZLE_SELECT_W_SHIFT) |
365 (0xf << R300_WRITE_ENA_SHIFT) ) << 16) ) );
366 OUT_BATCH_REGSEQ(R300_VAP_OUTPUT_VTX_FMT_0, 2);
367 OUT_BATCH(R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT);
368 OUT_BATCH(R300_VAP_OUTPUT_VTX_FMT_1__4_COMPONENTS);
369 END_BATCH();
370 }
371
372 static GLboolean validate_buffers(struct r300_context *r300,
373 struct radeon_bo *src_bo,
374 struct radeon_bo *dst_bo)
375 {
376 int ret;
377 radeon_cs_space_add_persistent_bo(r300->radeon.cmdbuf.cs,
378 src_bo, RADEON_GEM_DOMAIN_VRAM, 0);
379
380 radeon_cs_space_add_persistent_bo(r300->radeon.cmdbuf.cs,
381 dst_bo, 0, RADEON_GEM_DOMAIN_VRAM);
382
383 ret = radeon_cs_space_check_with_bo(r300->radeon.cmdbuf.cs,
384 first_elem(&r300->radeon.dma.reserved)->bo,
385 RADEON_GEM_DOMAIN_GTT, 0);
386 if (ret)
387 return GL_FALSE;
388
389 return GL_TRUE;
390 }
391
392 static void emit_draw_packet(struct r300_context *r300, float width, float height)
393 {
394 float verts[] = { 0.0, 0.0, 0.0, 1.0,
395 0.0, height, 0.0, 0.0,
396 width, height, 1.0, 0.0,
397 width, 0.0, 1.0, 1.0 };
398
399 BATCH_LOCALS(&r300->radeon);
400
401 BEGIN_BATCH(19);
402 OUT_BATCH_PACKET3(R300_PACKET3_3D_DRAW_IMMD_2, 16);
403 OUT_BATCH(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED |
404 (4 << 16) | R300_VAP_VF_CNTL__PRIM_QUADS);
405 OUT_BATCH_TABLE(verts, 16);
406 END_BATCH();
407 }
408
409 static void other_stuff(struct r300_context *r300)
410 {
411 BATCH_LOCALS(&r300->radeon);
412
413 BEGIN_BATCH(15);
414 OUT_BATCH_REGVAL(R300_GA_POLY_MODE,
415 R300_GA_POLY_MODE_FRONT_PTYPE_TRI | R300_GA_POLY_MODE_BACK_PTYPE_TRI);
416 OUT_BATCH_REGVAL(R300_SU_CULL_MODE, R300_FRONT_FACE_CCW);
417 OUT_BATCH_REGVAL(R300_FG_FOG_BLEND, 0);
418 OUT_BATCH_REGVAL(R300_FG_ALPHA_FUNC, 0);
419 OUT_BATCH_REGSEQ(R300_RB3D_CBLEND, 2);
420 OUT_BATCH(0x0);
421 OUT_BATCH(0x0);
422 OUT_BATCH_REGVAL(R300_VAP_CLIP_CNTL, R300_CLIP_DISABLE);
423 OUT_BATCH_REGVAL(R300_ZB_CNTL, 0);
424 END_BATCH();
425 }
426
427 static void emit_cb_setup(struct r300_context *r300,
428 struct radeon_bo *bo,
429 intptr_t offset,
430 gl_format mesa_format,
431 unsigned width,
432 unsigned height)
433 {
434 BATCH_LOCALS(&r300->radeon);
435
436 unsigned x1, y1, x2, y2;
437 x1 = 0;
438 y1 = 0;
439 x2 = width - 1;
440 y2 = height - 1;
441
442 if (r300->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV515) {
443 x1 += R300_SCISSORS_OFFSET;
444 y1 += R300_SCISSORS_OFFSET;
445 x2 += R300_SCISSORS_OFFSET;
446 y2 += R300_SCISSORS_OFFSET;
447 }
448
449 r300_emit_cb_setup(r300, bo, offset, mesa_format,
450 _mesa_get_format_bytes(mesa_format),
451 _mesa_format_row_stride(mesa_format, width));
452
453 BEGIN_BATCH_NO_AUTOSTATE(3);
454 OUT_BATCH_REGSEQ(R300_SC_SCISSORS_TL, 2);
455 OUT_BATCH((x1 << R300_SCISSORS_X_SHIFT)|(y1 << R300_SCISSORS_Y_SHIFT));
456 OUT_BATCH((x2 << R300_SCISSORS_X_SHIFT)|(y2 << R300_SCISSORS_Y_SHIFT));
457 END_BATCH();
458 }
459
460 GLboolean r300_blit(struct r300_context *r300,
461 struct radeon_bo *src_bo,
462 intptr_t src_offset,
463 gl_format src_mesaformat,
464 unsigned src_pitch,
465 unsigned src_width,
466 unsigned src_height,
467 struct radeon_bo *dst_bo,
468 intptr_t dst_offset,
469 gl_format dst_mesaformat,
470 unsigned dst_width,
471 unsigned dst_height)
472 {
473 //assert(src_width == dst_width);
474 //assert(src_height == dst_height);
475
476 if (src_bo == dst_bo) {
477 return GL_FALSE;
478 }
479
480 //return GL_FALSE;
481
482 if (1) {
483 fprintf(stderr, "src: width %d, height %d, pitch %d vs %d, format %s\n",
484 src_width, src_height, src_pitch,
485 _mesa_format_row_stride(src_mesaformat, src_width),
486 _mesa_get_format_name(src_mesaformat));
487 fprintf(stderr, "dst: width %d, height %d, pitch %d, format %s\n",
488 dst_width, dst_height,
489 _mesa_format_row_stride(dst_mesaformat, dst_width),
490 _mesa_get_format_name(dst_mesaformat));
491 }
492
493 if (!validate_buffers(r300, src_bo, dst_bo))
494 return GL_FALSE;
495
496 rcommonEnsureCmdBufSpace(&r300->radeon, 200, __FUNCTION__);
497
498 other_stuff(r300);
499
500 r300_emit_tx_setup(r300, src_mesaformat, src_bo, src_offset, src_width, src_height, src_pitch);
501
502 if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
503 r500_emit_fp_setup(r300, &r300->blit.fp_code.code.r500, dst_mesaformat);
504 r500_emit_rs_setup(r300);
505 } else {
506 r300_emit_fp_setup(r300, &r300->blit.fp_code.code.r300, dst_mesaformat);
507 r300_emit_rs_setup(r300);
508 }
509
510 emit_pvs_setup(r300, r300->blit.vp_code.body.d, 2);
511 emit_vap_setup(r300, dst_width, dst_height);
512
513 emit_cb_setup(r300, dst_bo, dst_offset, dst_mesaformat, dst_width, dst_height);
514
515 emit_draw_packet(r300, dst_width, dst_height);
516
517 r300EmitCacheFlush(r300);
518
519 radeonFlush(r300->radeon.glCtx);
520 //r300ResetHwState(r300);
521
522 return GL_TRUE;
523 }