2
* Copyright (C) 2009 Maciej Cencora <m.cencora@gmail.com>
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:
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.
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.
28
#include "radeon_common.h"
29
#include "r300_context.h"
31
#include "r300_blit.h"
32
#include "r300_cmdbuf.h"
33
#include "r300_emit.h"
35
#include "compiler/radeon_compiler.h"
36
#include "compiler/radeon_opcodes.h"
38
static void vp_ins_outs(struct r300_vertex_program_compiler *c)
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;
46
static void fp_allocate_hw_inputs(
47
struct r300_fragment_program_compiler * c,
48
void (*allocate)(void * data, unsigned input, unsigned hwreg),
51
allocate(mydata, FRAG_ATTRIB_TEX0, 0);
54
static void create_vertex_program(struct r300_context *r300)
56
struct r300_vertex_program_compiler compiler;
57
struct rc_instruction *inst;
59
memset(&compiler, 0, sizeof(compiler));
60
rc_init(&compiler.Base);
62
inst = rc_insert_new_instruction(&compiler.Base, compiler.Base.Program.Instructions.Prev);
63
inst->U.I.Opcode = RC_OPCODE_MOV;
64
inst->U.I.DstReg.File = RC_FILE_OUTPUT;
65
inst->U.I.DstReg.Index = VERT_RESULT_HPOS;
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;
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.WriteMask = RC_MASK_XYZW;
79
inst->U.I.SrcReg[0].Abs = 0;
80
inst->U.I.SrcReg[0].File = RC_FILE_INPUT;
81
inst->U.I.SrcReg[0].Index = VERT_ATTRIB_TEX0;
82
inst->U.I.SrcReg[0].Negate = 0;
83
inst->U.I.SrcReg[0].RelAddr = 0;
84
inst->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_XYZW;
86
compiler.Base.Program.InputsRead = (1 << VERT_ATTRIB_POS) | (1 << VERT_ATTRIB_TEX0);
87
compiler.RequiredOutputs = compiler.Base.Program.OutputsWritten = (1 << VERT_RESULT_HPOS) | (1 << VERT_RESULT_TEX0);
88
compiler.SetHwInputOutput = vp_ins_outs;
89
compiler.code = &r300->blit.vp_code;
90
compiler.Base.is_r500 = r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515;
91
compiler.Base.disable_optimizations = 0;
92
compiler.Base.has_half_swizzles = 0;
93
compiler.Base.max_temp_regs = 32;
94
compiler.Base.max_constants = 256;
95
compiler.Base.max_alu_insts = compiler.Base.is_r500 ? 1024 : 256;
97
r3xx_compile_vertex_program(&compiler);
100
static void create_fragment_program(struct r300_context *r300)
102
struct r300_fragment_program_compiler compiler;
103
struct rc_instruction *inst;
105
memset(&compiler, 0, sizeof(struct r300_fragment_program_compiler));
106
rc_init(&compiler.Base);
108
inst = rc_insert_new_instruction(&compiler.Base, compiler.Base.Program.Instructions.Prev);
109
inst->U.I.Opcode = RC_OPCODE_TEX;
110
inst->U.I.TexSrcTarget = RC_TEXTURE_2D;
111
inst->U.I.TexSrcUnit = 0;
112
inst->U.I.DstReg.File = RC_FILE_OUTPUT;
113
inst->U.I.DstReg.Index = FRAG_RESULT_COLOR;
114
inst->U.I.DstReg.WriteMask = RC_MASK_XYZW;
115
inst->U.I.SrcReg[0].Abs = 0;
116
inst->U.I.SrcReg[0].File = RC_FILE_INPUT;
117
inst->U.I.SrcReg[0].Index = FRAG_ATTRIB_TEX0;
118
inst->U.I.SrcReg[0].Negate = 0;
119
inst->U.I.SrcReg[0].RelAddr = 0;
120
inst->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_XYZW;
121
inst->U.I.TexSwizzle = RC_SWIZZLE_XYZW;
123
compiler.Base.Program.InputsRead = (1 << FRAG_ATTRIB_TEX0);
124
compiler.OutputColor[0] = FRAG_RESULT_COLOR;
125
compiler.OutputDepth = FRAG_RESULT_DEPTH;
126
compiler.enable_shadow_ambient = GL_TRUE;
127
compiler.Base.is_r500 = (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515);
128
compiler.Base.disable_optimizations = 0;
129
compiler.Base.has_half_swizzles = 1;
130
compiler.Base.max_temp_regs = (compiler.Base.is_r500) ? 128 : 32;
131
compiler.Base.max_constants = compiler.Base.is_r500 ? 256 : 32;
132
compiler.Base.max_alu_insts = compiler.Base.is_r500 ? 512 : 64;
133
compiler.Base.max_tex_insts = compiler.Base.is_r500 ? 512 : 32;
134
compiler.code = &r300->blit.fp_code;
135
compiler.AllocateHwInputs = fp_allocate_hw_inputs;
137
r3xx_compile_fragment_program(&compiler);
140
void r300_blit_init(struct r300_context *r300)
142
if (r300->options.hw_tcl_enabled)
143
create_vertex_program(r300);
144
create_fragment_program(r300);
147
static void r300_emit_tx_setup(struct r300_context *r300,
148
gl_format mesa_format,
149
struct radeon_bo *bo,
155
int is_r500 = r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515;
156
BATCH_LOCALS(&r300->radeon);
158
assert(is_r500 ? width <= 4096 : width <= 2048);
159
assert(is_r500 ? height <= 4096 : height <= 2048);
160
assert(r300TranslateTexFormat(mesa_format) >= 0);
161
assert(offset % 32 == 0);
164
OUT_BATCH_REGVAL(R300_TX_FILTER0_0,
165
(R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_S_SHIFT) |
166
(R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_T_SHIFT) |
167
(R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_R_SHIFT) |
168
R300_TX_MIN_FILTER_MIP_NONE |
169
R300_TX_MIN_FILTER_NEAREST |
170
R300_TX_MAG_FILTER_NEAREST |
172
OUT_BATCH_REGVAL(R300_TX_FILTER1_0, 0);
173
OUT_BATCH_REGVAL(R300_TX_SIZE_0,
174
(((width - 1) & 0x7ff) << R300_TX_WIDTHMASK_SHIFT) |
175
(((height - 1) & 0x7ff) << R300_TX_HEIGHTMASK_SHIFT) |
176
(0 << R300_TX_DEPTHMASK_SHIFT) |
177
(0 << R300_TX_MAX_MIP_LEVEL_SHIFT) |
178
R300_TX_SIZE_TXPITCH_EN);
180
OUT_BATCH_REGVAL(R300_TX_FORMAT_0, r300TranslateTexFormat(mesa_format));
181
OUT_BATCH_REGVAL(R300_TX_FORMAT2_0,
183
(is_r500 && width > 2048 ? R500_TXWIDTH_BIT11 : 0) |
184
(is_r500 && height > 2048 ? R500_TXHEIGHT_BIT11 : 0));
185
OUT_BATCH_REGSEQ(R300_TX_OFFSET_0, 1);
186
OUT_BATCH_RELOC(0, bo, offset, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
188
OUT_BATCH_REGSEQ(R300_TX_INVALTAGS, 2);
195
#define EASY_US_FORMAT(FMT, C0, C1, C2, C3, SIGN) \
196
(FMT | R500_C0_SEL_##C0 | R500_C1_SEL_##C1 | \
197
R500_C2_SEL_##C2 | R500_C3_SEL_##C3 | R500_OUT_SIGN(SIGN))
199
static uint32_t mesa_format_to_us_format(gl_format mesa_format)
203
case MESA_FORMAT_RGBA8888: // x
204
return EASY_US_FORMAT(R500_OUT_FMT_C4_8, A, B, G, R, 0);
205
case MESA_FORMAT_RGB565: // x
206
case MESA_FORMAT_ARGB1555: // x
207
case MESA_FORMAT_RGBA8888_REV: // x
208
return EASY_US_FORMAT(R500_OUT_FMT_C4_8, R, G, B, A, 0);
209
case MESA_FORMAT_ARGB8888: // x
210
return EASY_US_FORMAT(R500_OUT_FMT_C4_8, B, G, R, A, 0);
211
case MESA_FORMAT_ARGB8888_REV:
212
return EASY_US_FORMAT(R500_OUT_FMT_C4_8, A, R, G, B, 0);
213
case MESA_FORMAT_XRGB8888:
214
return EASY_US_FORMAT(R500_OUT_FMT_C4_8, A, R, G, B, 0);
216
case MESA_FORMAT_RGB332:
217
return EASY_US_FORMAT(R500_OUT_FMT_C_3_3_2, A, R, G, B, 0);
219
case MESA_FORMAT_RGBA_FLOAT32:
220
return EASY_US_FORMAT(R500_OUT_FMT_C4_32_FP, R, G, B, A, 0);
221
case MESA_FORMAT_RGBA_FLOAT16:
222
return EASY_US_FORMAT(R500_OUT_FMT_C4_16_FP, R, G, B, A, 0);
223
case MESA_FORMAT_ALPHA_FLOAT32:
224
return EASY_US_FORMAT(R500_OUT_FMT_C_32_FP, A, A, A, A, 0);
225
case MESA_FORMAT_ALPHA_FLOAT16:
226
return EASY_US_FORMAT(R500_OUT_FMT_C_16_FP, A, A, A, A, 0);
228
case MESA_FORMAT_SIGNED_RGBA8888:
229
return EASY_US_FORMAT(R500_OUT_FMT_C4_8, R, G, B, A, 0xf);
230
case MESA_FORMAT_SIGNED_RGBA8888_REV:
231
return EASY_US_FORMAT(R500_OUT_FMT_C4_8, A, B, G, R, 0xf);
232
case MESA_FORMAT_SIGNED_RGBA_16:
233
return EASY_US_FORMAT(R500_OUT_FMT_C4_16, R, G, B, A, 0xf);
236
fprintf(stderr, "Unsupported format %s for US output\n", _mesa_get_format_name(mesa_format));
241
#undef EASY_US_FORMAT
243
static void r500_emit_fp_setup(struct r300_context *r300,
244
struct r500_fragment_program_code *fp,
245
gl_format dst_format)
247
r500_emit_fp(r300, (uint32_t *)fp->inst, (fp->inst_end + 1) * 6, 0, 0, 0);
248
BATCH_LOCALS(&r300->radeon);
251
OUT_BATCH_REGSEQ(R500_US_CODE_ADDR, 3);
252
OUT_BATCH(R500_US_CODE_START_ADDR(0) | R500_US_CODE_END_ADDR(fp->inst_end));
253
OUT_BATCH(R500_US_CODE_RANGE_ADDR(0) | R500_US_CODE_RANGE_SIZE(fp->inst_end));
255
OUT_BATCH_REGVAL(R500_US_CONFIG, 0);
256
OUT_BATCH_REGVAL(R500_US_OUT_FMT_0, mesa_format_to_us_format(dst_format));
257
OUT_BATCH_REGVAL(R500_US_PIXSIZE, fp->max_temp_idx);
261
static void r500_emit_rs_setup(struct r300_context *r300)
263
BATCH_LOCALS(&r300->radeon);
266
OUT_BATCH_REGSEQ(R300_RS_COUNT, 2);
267
OUT_BATCH((4 << R300_IT_COUNT_SHIFT) | R300_HIRES_EN);
269
OUT_BATCH_REGVAL(R500_RS_INST_0,
270
(0 << R500_RS_INST_TEX_ID_SHIFT) |
271
(0 << R500_RS_INST_TEX_ADDR_SHIFT) |
272
R500_RS_INST_TEX_CN_WRITE |
273
R500_RS_INST_COL_CN_NO_WRITE);
274
OUT_BATCH_REGVAL(R500_RS_IP_0,
275
(0 << R500_RS_IP_TEX_PTR_S_SHIFT) |
276
(1 << R500_RS_IP_TEX_PTR_T_SHIFT) |
277
(2 << R500_RS_IP_TEX_PTR_R_SHIFT) |
278
(3 << R500_RS_IP_TEX_PTR_Q_SHIFT));
282
static void r300_emit_fp_setup(struct r300_context *r300,
283
struct r300_fragment_program_code *code,
284
gl_format dst_format)
287
BATCH_LOCALS(&r300->radeon);
289
BEGIN_BATCH((code->alu.length + 1) * 4 + code->tex.length + 1 + 11);
291
OUT_BATCH_REGSEQ(R300_US_ALU_RGB_INST_0, code->alu.length);
292
for (i = 0; i < code->alu.length; i++) {
293
OUT_BATCH(code->alu.inst[i].rgb_inst);
295
OUT_BATCH_REGSEQ(R300_US_ALU_RGB_ADDR_0, code->alu.length);
296
for (i = 0; i < code->alu.length; i++) {
297
OUT_BATCH(code->alu.inst[i].rgb_addr);
299
OUT_BATCH_REGSEQ(R300_US_ALU_ALPHA_INST_0, code->alu.length);
300
for (i = 0; i < code->alu.length; i++) {
301
OUT_BATCH(code->alu.inst[i].alpha_inst);
303
OUT_BATCH_REGSEQ(R300_US_ALU_ALPHA_ADDR_0, code->alu.length);
304
for (i = 0; i < code->alu.length; i++) {
305
OUT_BATCH(code->alu.inst[i].alpha_addr);
308
OUT_BATCH_REGSEQ(R300_US_TEX_INST_0, code->tex.length);
309
OUT_BATCH_TABLE(code->tex.inst, code->tex.length);
311
OUT_BATCH_REGSEQ(R300_US_CONFIG, 3);
312
OUT_BATCH(R300_PFS_CNTL_FIRST_NODE_HAS_TEX);
313
OUT_BATCH(code->pixsize);
314
OUT_BATCH(code->code_offset);
315
OUT_BATCH_REGSEQ(R300_US_CODE_ADDR_0, 4);
316
OUT_BATCH_TABLE(code->code_addr, 4);
317
OUT_BATCH_REGVAL(R500_US_OUT_FMT_0, mesa_format_to_us_format(dst_format));
321
static void r300_emit_rs_setup(struct r300_context *r300)
323
BATCH_LOCALS(&r300->radeon);
326
OUT_BATCH_REGSEQ(R300_RS_COUNT, 2);
327
OUT_BATCH((4 << R300_IT_COUNT_SHIFT) | R300_HIRES_EN);
329
OUT_BATCH_REGVAL(R300_RS_INST_0,
330
R300_RS_INST_TEX_ID(0) |
331
R300_RS_INST_TEX_ADDR(0) |
332
R300_RS_INST_TEX_CN_WRITE);
333
OUT_BATCH_REGVAL(R300_RS_IP_0,
335
R300_RS_SEL_S(R300_RS_SEL_C0) |
336
R300_RS_SEL_T(R300_RS_SEL_C1) |
337
R300_RS_SEL_R(R300_RS_SEL_K0) |
338
R300_RS_SEL_Q(R300_RS_SEL_K1));
342
static void emit_pvs_setup(struct r300_context *r300,
346
BATCH_LOCALS(&r300->radeon);
348
r300_emit_vpu(r300, vp_code, vp_len * 4, R300_PVS_CODE_START);
351
OUT_BATCH_REGSEQ(R300_VAP_PVS_CODE_CNTL_0, 3);
352
OUT_BATCH((0 << R300_PVS_FIRST_INST_SHIFT) |
353
((vp_len - 1) << R300_PVS_XYZW_VALID_INST_SHIFT) |
354
((vp_len - 1)<< R300_PVS_LAST_INST_SHIFT));
356
OUT_BATCH((vp_len - 1) << R300_PVS_LAST_VTX_SRC_INST_SHIFT);
360
static void emit_vap_setup(struct r300_context *r300)
363
BATCH_LOCALS(&r300->radeon);
365
if (r300->options.hw_tcl_enabled)
371
OUT_BATCH_REGSEQ(R300_SE_VTE_CNTL, 2);
372
OUT_BATCH(R300_VTX_XY_FMT | R300_VTX_Z_FMT);
375
OUT_BATCH_REGVAL(R300_VAP_PSC_SGN_NORM_CNTL, 0xaaaaaaaa);
376
OUT_BATCH_REGVAL(R300_VAP_PROG_STREAM_CNTL_0,
377
((R300_DATA_TYPE_FLOAT_2 | (0 << R300_DST_VEC_LOC_SHIFT)) << 0) |
378
(((tex_offset << R300_DST_VEC_LOC_SHIFT) | R300_DATA_TYPE_FLOAT_2 | R300_LAST_VEC) << 16));
379
OUT_BATCH_REGVAL(R300_VAP_PROG_STREAM_CNTL_EXT_0,
380
((((R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_SHIFT) |
381
(R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_SHIFT) |
382
(R300_SWIZZLE_SELECT_FP_ZERO << R300_SWIZZLE_SELECT_Z_SHIFT) |
383
(R300_SWIZZLE_SELECT_FP_ONE << R300_SWIZZLE_SELECT_W_SHIFT) |
384
(0xf << R300_WRITE_ENA_SHIFT) ) << 0) |
385
(((R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_SHIFT) |
386
(R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_SHIFT) |
387
(R300_SWIZZLE_SELECT_FP_ZERO << R300_SWIZZLE_SELECT_Z_SHIFT) |
388
(R300_SWIZZLE_SELECT_FP_ONE << R300_SWIZZLE_SELECT_W_SHIFT) |
389
(0xf << R300_WRITE_ENA_SHIFT) ) << 16) ) );
390
OUT_BATCH_REGSEQ(R300_VAP_OUTPUT_VTX_FMT_0, 2);
391
OUT_BATCH(R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT);
392
OUT_BATCH(R300_VAP_OUTPUT_VTX_FMT_1__4_COMPONENTS);
396
static GLboolean validate_buffers(struct r300_context *r300,
397
struct radeon_bo *src_bo,
398
struct radeon_bo *dst_bo)
402
radeon_cs_space_reset_bos(r300->radeon.cmdbuf.cs);
404
ret = radeon_cs_space_check_with_bo(r300->radeon.cmdbuf.cs,
405
src_bo, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0);
409
ret = radeon_cs_space_check_with_bo(r300->radeon.cmdbuf.cs,
410
dst_bo, 0, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT);
418
* Calculate texcoords for given image region.
419
* Output values are [minx, maxx, miny, maxy]
421
static void calc_tex_coords(float img_width, float img_height,
423
float reg_width, float reg_height,
424
unsigned flip_y, float *buf)
426
buf[0] = x / img_width;
427
buf[1] = buf[0] + reg_width / img_width;
428
buf[2] = y / img_height;
429
buf[3] = buf[2] + reg_height / img_height;
432
buf[2] = 1.0 - buf[2];
433
buf[3] = 1.0 - buf[3];
437
static void emit_draw_packet(struct r300_context *r300,
438
unsigned src_width, unsigned src_height,
439
unsigned src_x_offset, unsigned src_y_offset,
440
unsigned dst_x_offset, unsigned dst_y_offset,
441
unsigned reg_width, unsigned reg_height,
446
calc_tex_coords(src_width, src_height,
447
src_x_offset, src_y_offset,
448
reg_width, reg_height,
451
float verts[] = { dst_x_offset, dst_y_offset,
452
texcoords[0], texcoords[2],
453
dst_x_offset, dst_y_offset + reg_height,
454
texcoords[0], texcoords[3],
455
dst_x_offset + reg_width, dst_y_offset + reg_height,
456
texcoords[1], texcoords[3],
457
dst_x_offset + reg_width, dst_y_offset,
458
texcoords[1], texcoords[2] };
460
BATCH_LOCALS(&r300->radeon);
463
OUT_BATCH_PACKET3(R300_PACKET3_3D_DRAW_IMMD_2, 16);
464
OUT_BATCH(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED |
465
(4 << 16) | R300_VAP_VF_CNTL__PRIM_QUADS);
466
OUT_BATCH_TABLE(verts, 16);
470
static void other_stuff(struct r300_context *r300)
472
BATCH_LOCALS(&r300->radeon);
475
OUT_BATCH_REGVAL(R300_GA_POLY_MODE,
476
R300_GA_POLY_MODE_FRONT_PTYPE_TRI | R300_GA_POLY_MODE_BACK_PTYPE_TRI);
477
OUT_BATCH_REGVAL(R300_SU_CULL_MODE, R300_FRONT_FACE_CCW);
478
OUT_BATCH_REGVAL(R300_FG_FOG_BLEND, 0);
479
OUT_BATCH_REGVAL(R300_FG_ALPHA_FUNC, 0);
480
OUT_BATCH_REGSEQ(R300_RB3D_CBLEND, 2);
483
OUT_BATCH_REGVAL(R300_ZB_CNTL, 0);
485
if (r300->options.hw_tcl_enabled) {
487
OUT_BATCH_REGVAL(R300_VAP_CLIP_CNTL, R300_CLIP_DISABLE);
492
static void emit_cb_setup(struct r300_context *r300,
493
struct radeon_bo *bo,
495
gl_format mesa_format,
500
BATCH_LOCALS(&r300->radeon);
502
unsigned x1, y1, x2, y2;
508
if (r300->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV515) {
509
x1 += R300_SCISSORS_OFFSET;
510
y1 += R300_SCISSORS_OFFSET;
511
x2 += R300_SCISSORS_OFFSET;
512
y2 += R300_SCISSORS_OFFSET;
515
r300_emit_cb_setup(r300, bo, offset, mesa_format,
516
_mesa_get_format_bytes(mesa_format),
517
_mesa_format_row_stride(mesa_format, pitch));
519
BEGIN_BATCH_NO_AUTOSTATE(5);
520
OUT_BATCH_REGSEQ(R300_SC_SCISSORS_TL, 2);
521
OUT_BATCH((x1 << R300_SCISSORS_X_SHIFT)|(y1 << R300_SCISSORS_Y_SHIFT));
522
OUT_BATCH((x2 << R300_SCISSORS_X_SHIFT)|(y2 << R300_SCISSORS_Y_SHIFT));
523
OUT_BATCH_REGVAL(R300_RB3D_CCTL, 0);
527
unsigned r300_check_blit(gl_format dst_format)
529
switch (dst_format) {
530
case MESA_FORMAT_RGB565:
531
case MESA_FORMAT_ARGB1555:
532
case MESA_FORMAT_RGBA8888:
533
case MESA_FORMAT_RGBA8888_REV:
534
case MESA_FORMAT_ARGB8888:
535
case MESA_FORMAT_ARGB8888_REV:
536
case MESA_FORMAT_XRGB8888:
542
if (_mesa_get_format_bits(dst_format, GL_DEPTH_BITS) > 0)
549
* Copy a region of [@a width x @a height] pixels from source buffer
550
* to destination buffer.
551
* @param[in] r300 r300 context
552
* @param[in] src_bo source radeon buffer object
553
* @param[in] src_offset offset of the source image in the @a src_bo
554
* @param[in] src_mesaformat source image format
555
* @param[in] src_pitch aligned source image width
556
* @param[in] src_width source image width
557
* @param[in] src_height source image height
558
* @param[in] src_x_offset x offset in the source image
559
* @param[in] src_y_offset y offset in the source image
560
* @param[in] dst_bo destination radeon buffer object
561
* @param[in] dst_offset offset of the destination image in the @a dst_bo
562
* @param[in] dst_mesaformat destination image format
563
* @param[in] dst_pitch aligned destination image width
564
* @param[in] dst_width destination image width
565
* @param[in] dst_height destination image height
566
* @param[in] dst_x_offset x offset in the destination image
567
* @param[in] dst_y_offset y offset in the destination image
568
* @param[in] width region width
569
* @param[in] height region height
570
* @param[in] flip_y set if y coords of the source image need to be flipped
572
unsigned r300_blit(struct gl_context *ctx,
573
struct radeon_bo *src_bo,
575
gl_format src_mesaformat,
579
unsigned src_x_offset,
580
unsigned src_y_offset,
581
struct radeon_bo *dst_bo,
583
gl_format dst_mesaformat,
587
unsigned dst_x_offset,
588
unsigned dst_y_offset,
593
r300ContextPtr r300 = R300_CONTEXT(ctx);
595
if (!r300_check_blit(dst_mesaformat))
598
/* Make sure that colorbuffer has even width - hw limitation */
599
if (dst_pitch % 2 > 0)
602
/* Need to clamp the region size to make sure
603
* we don't read outside of the source buffer
604
* or write outside of the destination buffer.
606
if (reg_width + src_x_offset > src_width)
607
reg_width = src_width - src_x_offset;
608
if (reg_height + src_y_offset > src_height)
609
reg_height = src_height - src_y_offset;
610
if (reg_width + dst_x_offset > dst_width)
611
reg_width = dst_width - dst_x_offset;
612
if (reg_height + dst_y_offset > dst_height)
613
reg_height = dst_height - dst_y_offset;
615
if (src_bo == dst_bo) {
619
if (src_offset % 32 || dst_offset % 32) {
624
fprintf(stderr, "src: size [%d x %d], pitch %d, "
625
"offset [%d x %d], format %s, bo %p\n",
626
src_width, src_height, src_pitch,
627
src_x_offset, src_y_offset,
628
_mesa_get_format_name(src_mesaformat),
630
fprintf(stderr, "dst: pitch %d, offset[%d x %d], format %s, bo %p\n",
631
dst_pitch, dst_x_offset, dst_y_offset,
632
_mesa_get_format_name(dst_mesaformat), dst_bo);
633
fprintf(stderr, "region: %d x %d\n", reg_width, reg_height);
636
/* Flush is needed to make sure that source buffer has correct data */
637
radeonFlush(r300->radeon.glCtx);
639
if (!validate_buffers(r300, src_bo, dst_bo))
642
rcommonEnsureCmdBufSpace(&r300->radeon, 200, __FUNCTION__);
646
r300_emit_tx_setup(r300, src_mesaformat, src_bo, src_offset, src_width, src_height, src_pitch);
648
if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
649
r500_emit_fp_setup(r300, &r300->blit.fp_code.code.r500, dst_mesaformat);
650
r500_emit_rs_setup(r300);
652
r300_emit_fp_setup(r300, &r300->blit.fp_code.code.r300, dst_mesaformat);
653
r300_emit_rs_setup(r300);
656
if (r300->options.hw_tcl_enabled)
657
emit_pvs_setup(r300, r300->blit.vp_code.body.d, 2);
659
emit_vap_setup(r300);
661
emit_cb_setup(r300, dst_bo, dst_offset, dst_mesaformat, dst_pitch, dst_width, dst_height);
663
emit_draw_packet(r300, src_width, src_height,
664
src_x_offset, src_y_offset,
665
dst_x_offset, dst_y_offset,
666
reg_width, reg_height,
669
r300EmitCacheFlush(r300);
671
radeonFlush(r300->radeon.glCtx);