Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4358 Serge 1
/*
2
 * Copyright (C) 2009 Maciej Cencora 
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 "r200_context.h"
30
#include "r200_blit.h"
31
 
32
static inline uint32_t cmdpacket0(struct radeon_screen *rscrn,
33
                                  int reg, int count)
34
{
35
    if (count)
36
	    return CP_PACKET0(reg, count - 1);
37
    return CP_PACKET2;
38
}
39
 
40
/* common formats supported as both textures and render targets */
41
unsigned r200_check_blit(gl_format mesa_format, uint32_t dst_pitch)
42
{
43
    /* XXX others?  BE/LE? */
44
    switch (mesa_format) {
45
    case MESA_FORMAT_ARGB8888:
46
    case MESA_FORMAT_XRGB8888:
47
    case MESA_FORMAT_RGB565:
48
    case MESA_FORMAT_ARGB4444:
49
    case MESA_FORMAT_ARGB1555:
50
    case MESA_FORMAT_A8:
51
    case MESA_FORMAT_L8:
52
    case MESA_FORMAT_I8:
53
    /* swizzled */
54
    case MESA_FORMAT_RGBA8888:
55
    case MESA_FORMAT_RGBA8888_REV:
56
	    break;
57
    default:
58
	    return 0;
59
    }
60
 
61
    /* Rendering to small buffer doesn't work.
62
     * Looks like a hw limitation.
63
     */
64
    if (dst_pitch < 32)
65
            return 0;
66
 
67
    /* ??? */
68
    if (_mesa_get_format_bits(mesa_format, GL_DEPTH_BITS) > 0)
69
	    return 0;
70
 
71
    return 1;
72
}
73
 
74
static inline void emit_vtx_state(struct r200_context *r200)
75
{
76
    BATCH_LOCALS(&r200->radeon);
77
 
78
    BEGIN_BATCH(14);
79
    if (r200->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL) {
80
	    OUT_BATCH_REGVAL(R200_SE_VAP_CNTL_STATUS, 0);
81
    } else {
82
	    OUT_BATCH_REGVAL(R200_SE_VAP_CNTL_STATUS, RADEON_TCL_BYPASS);
83
    }
84
    OUT_BATCH_REGVAL(R200_SE_VAP_CNTL, (R200_VAP_FORCE_W_TO_ONE |
85
					(9 << R200_VAP_VF_MAX_VTX_NUM__SHIFT)));
86
    OUT_BATCH_REGVAL(R200_SE_VTX_STATE_CNTL, 0);
87
    OUT_BATCH_REGVAL(R200_SE_VTE_CNTL, 0);
88
    OUT_BATCH_REGVAL(R200_SE_VTX_FMT_0, R200_VTX_XY);
89
    OUT_BATCH_REGVAL(R200_SE_VTX_FMT_1, (2 << R200_VTX_TEX0_COMP_CNT_SHIFT));
90
    OUT_BATCH_REGVAL(RADEON_SE_CNTL, (RADEON_DIFFUSE_SHADE_GOURAUD |
91
				      RADEON_BFACE_SOLID |
92
				      RADEON_FFACE_SOLID |
93
				      RADEON_VTX_PIX_CENTER_OGL |
94
				      RADEON_ROUND_MODE_ROUND |
95
				      RADEON_ROUND_PREC_4TH_PIX));
96
    END_BATCH();
97
}
98
 
99
static void inline emit_tx_setup(struct r200_context *r200,
100
				 gl_format src_mesa_format,
101
				 gl_format dst_mesa_format,
102
				 struct radeon_bo *bo,
103
				 intptr_t offset,
104
				 unsigned width,
105
				 unsigned height,
106
				 unsigned pitch)
107
{
108
    uint32_t txformat = R200_TXFORMAT_NON_POWER2;
109
    BATCH_LOCALS(&r200->radeon);
110
 
111
    assert(width <= 2048);
112
    assert(height <= 2048);
113
    assert(offset % 32 == 0);
114
 
115
    /* XXX others?  BE/LE? */
116
    switch (src_mesa_format) {
117
    case MESA_FORMAT_ARGB8888:
118
	    txformat |= R200_TXFORMAT_ARGB8888 | R200_TXFORMAT_ALPHA_IN_MAP;
119
	    break;
120
    case MESA_FORMAT_RGBA8888:
121
	    txformat |= R200_TXFORMAT_RGBA8888 | R200_TXFORMAT_ALPHA_IN_MAP;
122
	    break;
123
    case MESA_FORMAT_RGBA8888_REV:
124
	    txformat |= R200_TXFORMAT_ABGR8888 | R200_TXFORMAT_ALPHA_IN_MAP;
125
	    break;
126
    case MESA_FORMAT_XRGB8888:
127
	    txformat |= R200_TXFORMAT_ARGB8888;
128
	    break;
129
    case MESA_FORMAT_RGB565:
130
	    txformat |= R200_TXFORMAT_RGB565;
131
	    break;
132
    case MESA_FORMAT_ARGB4444:
133
	    txformat |= R200_TXFORMAT_ARGB4444 | R200_TXFORMAT_ALPHA_IN_MAP;
134
	    break;
135
    case MESA_FORMAT_ARGB1555:
136
	    txformat |= R200_TXFORMAT_ARGB1555 | R200_TXFORMAT_ALPHA_IN_MAP;
137
	    break;
138
    case MESA_FORMAT_A8:
139
    case MESA_FORMAT_I8:
140
	    txformat |= R200_TXFORMAT_I8 | R200_TXFORMAT_ALPHA_IN_MAP;
141
	    break;
142
    case MESA_FORMAT_L8:
143
	    txformat |= R200_TXFORMAT_I8;
144
	    break;
145
    case MESA_FORMAT_AL88:
146
	    txformat |= R200_TXFORMAT_AI88 | R200_TXFORMAT_ALPHA_IN_MAP;
147
	    break;
148
    default:
149
	    break;
150
    }
151
 
152
    if (bo->flags & RADEON_BO_FLAGS_MACRO_TILE)
153
	offset |= R200_TXO_MACRO_TILE;
154
    if (bo->flags & RADEON_BO_FLAGS_MICRO_TILE)
155
	offset |= R200_TXO_MICRO_TILE;
156
 
157
    switch (dst_mesa_format) {
158
    case MESA_FORMAT_ARGB8888:
159
    case MESA_FORMAT_XRGB8888:
160
    case MESA_FORMAT_RGB565:
161
    case MESA_FORMAT_ARGB4444:
162
    case MESA_FORMAT_ARGB1555:
163
    case MESA_FORMAT_A8:
164
    case MESA_FORMAT_L8:
165
    case MESA_FORMAT_I8:
166
    default:
167
	    /* no swizzle required */
168
	    BEGIN_BATCH(10);
169
	    OUT_BATCH_REGVAL(RADEON_PP_CNTL, (RADEON_TEX_0_ENABLE |
170
					      RADEON_TEX_BLEND_0_ENABLE));
171
	    OUT_BATCH_REGVAL(R200_PP_TXCBLEND_0, (R200_TXC_ARG_A_ZERO |
172
						  R200_TXC_ARG_B_ZERO |
173
						  R200_TXC_ARG_C_R0_COLOR |
174
						  R200_TXC_OP_MADD));
175
	    OUT_BATCH_REGVAL(R200_PP_TXCBLEND2_0, (R200_TXC_CLAMP_0_1 |
176
						   R200_TXC_OUTPUT_REG_R0));
177
	    OUT_BATCH_REGVAL(R200_PP_TXABLEND_0, (R200_TXA_ARG_A_ZERO |
178
						  R200_TXA_ARG_B_ZERO |
179
						  R200_TXA_ARG_C_R0_ALPHA |
180
						  R200_TXA_OP_MADD));
181
	    OUT_BATCH_REGVAL(R200_PP_TXABLEND2_0, (R200_TXA_CLAMP_0_1 |
182
						   R200_TXA_OUTPUT_REG_R0));
183
	    END_BATCH();
184
	    break;
185
    case MESA_FORMAT_RGBA8888:
186
	    BEGIN_BATCH(10);
187
	    OUT_BATCH_REGVAL(RADEON_PP_CNTL, (RADEON_TEX_0_ENABLE |
188
					      RADEON_TEX_BLEND_0_ENABLE));
189
	    OUT_BATCH_REGVAL(R200_PP_TXCBLEND_0, (R200_TXC_ARG_A_ZERO |
190
						  R200_TXC_ARG_B_ZERO |
191
						  R200_TXC_ARG_C_R0_COLOR |
192
						  R200_TXC_OP_MADD));
193
	    OUT_BATCH_REGVAL(R200_PP_TXCBLEND2_0, (R200_TXC_CLAMP_0_1 |
194
						   R200_TXC_OUTPUT_ROTATE_GBA |
195
						   R200_TXC_OUTPUT_REG_R0));
196
	    OUT_BATCH_REGVAL(R200_PP_TXABLEND_0, (R200_TXA_ARG_A_ZERO |
197
						  R200_TXA_ARG_B_ZERO |
198
						  R200_TXA_ARG_C_R0_ALPHA |
199
						  R200_TXA_OP_MADD));
200
	    OUT_BATCH_REGVAL(R200_PP_TXABLEND2_0, (R200_TXA_CLAMP_0_1 |
201
						   (R200_TXA_REPL_RED << R200_TXA_REPL_ARG_C_SHIFT) |
202
						   R200_TXA_OUTPUT_REG_R0));
203
	    END_BATCH();
204
	    break;
205
    case MESA_FORMAT_RGBA8888_REV:
206
	    BEGIN_BATCH(34);
207
	    OUT_BATCH_REGVAL(RADEON_PP_CNTL, (RADEON_TEX_0_ENABLE |
208
					      RADEON_TEX_BLEND_0_ENABLE |
209
					      RADEON_TEX_BLEND_1_ENABLE |
210
					      RADEON_TEX_BLEND_2_ENABLE |
211
					      RADEON_TEX_BLEND_3_ENABLE));
212
	    /* r1.r = r0.b */
213
	    OUT_BATCH_REGVAL(R200_PP_TXCBLEND_0, (R200_TXC_ARG_A_ZERO |
214
						  R200_TXC_ARG_B_ZERO |
215
						  R200_TXC_ARG_C_R0_COLOR |
216
						  R200_TXC_OP_MADD));
217
	    OUT_BATCH_REGVAL(R200_PP_TXCBLEND2_0, (R200_TXC_CLAMP_0_1 |
218
						   R200_TXC_OUTPUT_MASK_R |
219
						   (R200_TXC_REPL_BLUE << R200_TXC_REPL_ARG_C_SHIFT) |
220
						   R200_TXC_OUTPUT_REG_R1));
221
	    /* r1.a = r0.a */
222
	    OUT_BATCH_REGVAL(R200_PP_TXABLEND_0, (R200_TXA_ARG_A_ZERO |
223
						  R200_TXA_ARG_B_ZERO |
224
						  R200_TXA_ARG_C_R0_ALPHA |
225
						  R200_TXA_OP_MADD));
226
	    OUT_BATCH_REGVAL(R200_PP_TXABLEND2_0, (R200_TXA_CLAMP_0_1 |
227
						   R200_TXA_OUTPUT_REG_R1));
228
	    /* r1.g = r0.g */
229
	    OUT_BATCH_REGVAL(R200_PP_TXCBLEND_1, (R200_TXC_ARG_A_ZERO |
230
						  R200_TXC_ARG_B_ZERO |
231
						  R200_TXC_ARG_C_R0_COLOR |
232
						  R200_TXC_OP_MADD));
233
	    OUT_BATCH_REGVAL(R200_PP_TXCBLEND2_1, (R200_TXC_CLAMP_0_1 |
234
						   R200_TXC_OUTPUT_MASK_G |
235
						   (R200_TXC_REPL_GREEN << R200_TXC_REPL_ARG_C_SHIFT) |
236
						   R200_TXC_OUTPUT_REG_R1));
237
	    /* r1.a = r0.a */
238
	    OUT_BATCH_REGVAL(R200_PP_TXABLEND_1, (R200_TXA_ARG_A_ZERO |
239
						  R200_TXA_ARG_B_ZERO |
240
						  R200_TXA_ARG_C_R0_ALPHA |
241
						  R200_TXA_OP_MADD));
242
	    OUT_BATCH_REGVAL(R200_PP_TXABLEND2_1, (R200_TXA_CLAMP_0_1 |
243
						   R200_TXA_OUTPUT_REG_R1));
244
	    /* r1.b = r0.r */
245
	    OUT_BATCH_REGVAL(R200_PP_TXCBLEND_2, (R200_TXC_ARG_A_ZERO |
246
						  R200_TXC_ARG_B_ZERO |
247
						  R200_TXC_ARG_C_R0_COLOR |
248
						  R200_TXC_OP_MADD));
249
	    OUT_BATCH_REGVAL(R200_PP_TXCBLEND2_2, (R200_TXC_CLAMP_0_1 |
250
						   R200_TXC_OUTPUT_MASK_B |
251
						   (R200_TXC_REPL_RED << R200_TXC_REPL_ARG_C_SHIFT) |
252
						   R200_TXC_OUTPUT_REG_R1));
253
	    /* r1.a = r0.a */
254
	    OUT_BATCH_REGVAL(R200_PP_TXABLEND_2, (R200_TXA_ARG_A_ZERO |
255
						  R200_TXA_ARG_B_ZERO |
256
						  R200_TXA_ARG_C_R0_ALPHA |
257
						  R200_TXA_OP_MADD));
258
	    OUT_BATCH_REGVAL(R200_PP_TXABLEND2_2, (R200_TXA_CLAMP_0_1 |
259
						   R200_TXA_OUTPUT_REG_R1));
260
	    /* r0.rgb = r1.rgb */
261
	    OUT_BATCH_REGVAL(R200_PP_TXCBLEND_3, (R200_TXC_ARG_A_ZERO |
262
						  R200_TXC_ARG_B_ZERO |
263
						  R200_TXC_ARG_C_R1_COLOR |
264
						  R200_TXC_OP_MADD));
265
	    OUT_BATCH_REGVAL(R200_PP_TXCBLEND2_3, (R200_TXC_CLAMP_0_1 |
266
						   R200_TXC_OUTPUT_REG_R0));
267
	    /* r0.a = r1.a */
268
	    OUT_BATCH_REGVAL(R200_PP_TXABLEND_3, (R200_TXA_ARG_A_ZERO |
269
						  R200_TXA_ARG_B_ZERO |
270
						  R200_TXA_ARG_C_R1_ALPHA |
271
						  R200_TXA_OP_MADD));
272
	    OUT_BATCH_REGVAL(R200_PP_TXABLEND2_3, (R200_TXA_CLAMP_0_1 |
273
						   R200_TXA_OUTPUT_REG_R0));
274
	    END_BATCH();
275
	    break;
276
    }
277
 
278
    BEGIN_BATCH(18);
279
    OUT_BATCH_REGVAL(R200_PP_CNTL_X, 0);
280
    OUT_BATCH_REGVAL(R200_PP_TXMULTI_CTL_0, 0);
281
    OUT_BATCH_REGVAL(R200_PP_TXFILTER_0, (R200_CLAMP_S_CLAMP_LAST |
282
					  R200_CLAMP_T_CLAMP_LAST |
283
					  R200_MAG_FILTER_NEAREST |
284
					  R200_MIN_FILTER_NEAREST));
285
    OUT_BATCH_REGVAL(R200_PP_TXFORMAT_0, txformat);
286
    OUT_BATCH_REGVAL(R200_PP_TXFORMAT_X_0, 0);
287
    OUT_BATCH_REGVAL(R200_PP_TXSIZE_0, ((width - 1) |
288
					((height - 1) << RADEON_TEX_VSIZE_SHIFT)));
289
    OUT_BATCH_REGVAL(R200_PP_TXPITCH_0, pitch * _mesa_get_format_bytes(src_mesa_format) - 32);
290
 
291
    OUT_BATCH_REGSEQ(R200_PP_TXOFFSET_0, 1);
292
    OUT_BATCH_RELOC(offset, bo, offset, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
293
 
294
    END_BATCH();
295
}
296
 
297
static inline void emit_cb_setup(struct r200_context *r200,
298
				 struct radeon_bo *bo,
299
				 intptr_t offset,
300
				 gl_format mesa_format,
301
				 unsigned pitch,
302
				 unsigned width,
303
				 unsigned height)
304
{
305
    uint32_t dst_pitch = pitch;
306
    uint32_t dst_format = 0;
307
    BATCH_LOCALS(&r200->radeon);
308
 
309
    /* XXX others?  BE/LE? */
310
    switch (mesa_format) {
311
    case MESA_FORMAT_ARGB8888:
312
    case MESA_FORMAT_XRGB8888:
313
    case MESA_FORMAT_RGBA8888:
314
    case MESA_FORMAT_RGBA8888_REV:
315
	    dst_format = RADEON_COLOR_FORMAT_ARGB8888;
316
	    break;
317
    case MESA_FORMAT_RGB565:
318
	    dst_format = RADEON_COLOR_FORMAT_RGB565;
319
	    break;
320
    case MESA_FORMAT_ARGB4444:
321
	    dst_format = RADEON_COLOR_FORMAT_ARGB4444;
322
	    break;
323
    case MESA_FORMAT_ARGB1555:
324
	    dst_format = RADEON_COLOR_FORMAT_ARGB1555;
325
	    break;
326
    case MESA_FORMAT_A8:
327
    case MESA_FORMAT_L8:
328
    case MESA_FORMAT_I8:
329
	    dst_format = RADEON_COLOR_FORMAT_RGB8;
330
	    break;
331
    default:
332
	    break;
333
    }
334
 
335
    if (bo->flags & RADEON_BO_FLAGS_MACRO_TILE)
336
	dst_pitch |= R200_COLOR_TILE_ENABLE;
337
    if (bo->flags & RADEON_BO_FLAGS_MICRO_TILE)
338
	dst_pitch |= R200_COLOR_MICROTILE_ENABLE;
339
 
340
    BEGIN_BATCH_NO_AUTOSTATE(22);
341
    OUT_BATCH_REGVAL(R200_RE_AUX_SCISSOR_CNTL, 0);
342
    OUT_BATCH_REGVAL(R200_RE_CNTL, 0);
343
    OUT_BATCH_REGVAL(RADEON_RE_TOP_LEFT, 0);
344
    OUT_BATCH_REGVAL(RADEON_RE_WIDTH_HEIGHT, (((width - 1) << RADEON_RE_WIDTH_SHIFT) |
345
					      ((height - 1) << RADEON_RE_HEIGHT_SHIFT)));
346
    OUT_BATCH_REGVAL(RADEON_RB3D_PLANEMASK, 0xffffffff);
347
    OUT_BATCH_REGVAL(RADEON_RB3D_BLENDCNTL, RADEON_SRC_BLEND_GL_ONE | RADEON_DST_BLEND_GL_ZERO);
348
    OUT_BATCH_REGVAL(RADEON_RB3D_CNTL, dst_format);
349
 
350
    OUT_BATCH_REGSEQ(RADEON_RB3D_COLOROFFSET, 1);
351
    OUT_BATCH_RELOC(offset, bo, offset, 0, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0);
352
    OUT_BATCH_REGSEQ(RADEON_RB3D_COLORPITCH, 1);
353
    OUT_BATCH_RELOC(dst_pitch, bo, dst_pitch, 0, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0);
354
 
355
    END_BATCH();
356
}
357
 
358
static GLboolean validate_buffers(struct r200_context *r200,
359
                                  struct radeon_bo *src_bo,
360
                                  struct radeon_bo *dst_bo)
361
{
362
    int ret;
363
 
364
    radeon_cs_space_reset_bos(r200->radeon.cmdbuf.cs);
365
 
366
    ret = radeon_cs_space_check_with_bo(r200->radeon.cmdbuf.cs,
367
                                        src_bo, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0);
368
    if (ret)
369
        return GL_FALSE;
370
 
371
    ret = radeon_cs_space_check_with_bo(r200->radeon.cmdbuf.cs,
372
                                        dst_bo, 0, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT);
373
    if (ret)
374
        return GL_FALSE;
375
 
376
    return GL_TRUE;
377
}
378
 
379
/**
380
 * Calculate texcoords for given image region.
381
 * Output values are [minx, maxx, miny, maxy]
382
 */
383
static inline void calc_tex_coords(float img_width, float img_height,
384
				   float x, float y,
385
				   float reg_width, float reg_height,
386
				   unsigned flip_y, float *buf)
387
{
388
    buf[0] = x / img_width;
389
    buf[1] = buf[0] + reg_width / img_width;
390
    buf[2] = y / img_height;
391
    buf[3] = buf[2] + reg_height / img_height;
392
    if (flip_y)
393
    {
394
        buf[2] = 1.0 - buf[2];
395
        buf[3] = 1.0 - buf[3];
396
    }
397
}
398
 
399
static inline void emit_draw_packet(struct r200_context *r200,
400
				    unsigned src_width, unsigned src_height,
401
				    unsigned src_x_offset, unsigned src_y_offset,
402
				    unsigned dst_x_offset, unsigned dst_y_offset,
403
				    unsigned reg_width, unsigned reg_height,
404
				    unsigned flip_y)
405
{
406
    float texcoords[4];
407
    float verts[12];
408
    BATCH_LOCALS(&r200->radeon);
409
 
410
    calc_tex_coords(src_width, src_height,
411
                    src_x_offset, src_y_offset,
412
                    reg_width, reg_height,
413
                    flip_y, texcoords);
414
 
415
    verts[0] = dst_x_offset;
416
    verts[1] = dst_y_offset + reg_height;
417
    verts[2] = texcoords[0];
418
    verts[3] = texcoords[3];
419
 
420
    verts[4] = dst_x_offset + reg_width;
421
    verts[5] = dst_y_offset + reg_height;
422
    verts[6] = texcoords[1];
423
    verts[7] = texcoords[3];
424
 
425
    verts[8] = dst_x_offset + reg_width;
426
    verts[9] = dst_y_offset;
427
    verts[10] = texcoords[1];
428
    verts[11] = texcoords[2];
429
 
430
    BEGIN_BATCH(14);
431
    OUT_BATCH(R200_CP_CMD_3D_DRAW_IMMD_2 | (12 << 16));
432
    OUT_BATCH(RADEON_CP_VC_CNTL_PRIM_WALK_RING |
433
	      RADEON_CP_VC_CNTL_PRIM_TYPE_RECT_LIST |
434
              (3 << 16));
435
    OUT_BATCH_TABLE(verts, 12);
436
    END_BATCH();
437
}
438
 
439
/**
440
 * Copy a region of [@a width x @a height] pixels from source buffer
441
 * to destination buffer.
442
 * @param[in] r200 r200 context
443
 * @param[in] src_bo source radeon buffer object
444
 * @param[in] src_offset offset of the source image in the @a src_bo
445
 * @param[in] src_mesaformat source image format
446
 * @param[in] src_pitch aligned source image width
447
 * @param[in] src_width source image width
448
 * @param[in] src_height source image height
449
 * @param[in] src_x_offset x offset in the source image
450
 * @param[in] src_y_offset y offset in the source image
451
 * @param[in] dst_bo destination radeon buffer object
452
 * @param[in] dst_offset offset of the destination image in the @a dst_bo
453
 * @param[in] dst_mesaformat destination image format
454
 * @param[in] dst_pitch aligned destination image width
455
 * @param[in] dst_width destination image width
456
 * @param[in] dst_height destination image height
457
 * @param[in] dst_x_offset x offset in the destination image
458
 * @param[in] dst_y_offset y offset in the destination image
459
 * @param[in] width region width
460
 * @param[in] height region height
461
 * @param[in] flip_y set if y coords of the source image need to be flipped
462
 */
463
unsigned r200_blit(struct gl_context *ctx,
464
                   struct radeon_bo *src_bo,
465
                   intptr_t src_offset,
466
                   gl_format src_mesaformat,
467
                   unsigned src_pitch,
468
                   unsigned src_width,
469
                   unsigned src_height,
470
                   unsigned src_x_offset,
471
                   unsigned src_y_offset,
472
                   struct radeon_bo *dst_bo,
473
                   intptr_t dst_offset,
474
                   gl_format dst_mesaformat,
475
                   unsigned dst_pitch,
476
                   unsigned dst_width,
477
                   unsigned dst_height,
478
                   unsigned dst_x_offset,
479
                   unsigned dst_y_offset,
480
                   unsigned reg_width,
481
                   unsigned reg_height,
482
                   unsigned flip_y)
483
{
484
    struct r200_context *r200 = R200_CONTEXT(ctx);
485
 
486
    if (!r200_check_blit(dst_mesaformat, dst_pitch))
487
        return GL_FALSE;
488
 
489
    /* Make sure that colorbuffer has even width - hw limitation */
490
    if (dst_pitch % 2 > 0)
491
        ++dst_pitch;
492
 
493
    /* Need to clamp the region size to make sure
494
     * we don't read outside of the source buffer
495
     * or write outside of the destination buffer.
496
     */
497
    if (reg_width + src_x_offset > src_width)
498
        reg_width = src_width - src_x_offset;
499
    if (reg_height + src_y_offset > src_height)
500
        reg_height = src_height - src_y_offset;
501
    if (reg_width + dst_x_offset > dst_width)
502
        reg_width = dst_width - dst_x_offset;
503
    if (reg_height + dst_y_offset > dst_height)
504
        reg_height = dst_height - dst_y_offset;
505
 
506
    if (src_bo == dst_bo) {
507
        return GL_FALSE;
508
    }
509
 
510
    if (src_offset % 32 || dst_offset % 32) {
511
        return GL_FALSE;
512
    }
513
 
514
    if (0) {
515
        fprintf(stderr, "src: size [%d x %d], pitch %d, "
516
                "offset [%d x %d], format %s, bo %p\n",
517
                src_width, src_height, src_pitch,
518
                src_x_offset, src_y_offset,
519
                _mesa_get_format_name(src_mesaformat),
520
                src_bo);
521
        fprintf(stderr, "dst: pitch %d, offset[%d x %d], format %s, bo %p\n",
522
                dst_pitch, dst_x_offset, dst_y_offset,
523
                _mesa_get_format_name(dst_mesaformat), dst_bo);
524
        fprintf(stderr, "region: %d x %d\n", reg_width, reg_height);
525
    }
526
 
527
    /* Flush is needed to make sure that source buffer has correct data */
528
    radeonFlush(&r200->radeon.glCtx);
529
 
530
    rcommonEnsureCmdBufSpace(&r200->radeon, 102, __FUNCTION__);
531
 
532
    if (!validate_buffers(r200, src_bo, dst_bo))
533
        return GL_FALSE;
534
 
535
    /* 14 */
536
    emit_vtx_state(r200);
537
    /* 52 */
538
    emit_tx_setup(r200, src_mesaformat, dst_mesaformat, src_bo, src_offset, src_width, src_height, src_pitch);
539
    /* 22 */
540
    emit_cb_setup(r200, dst_bo, dst_offset, dst_mesaformat, dst_pitch, dst_width, dst_height);
541
    /* 14 */
542
    emit_draw_packet(r200, src_width, src_height,
543
                     src_x_offset, src_y_offset,
544
                     dst_x_offset, dst_y_offset,
545
                     reg_width, reg_height,
546
                     flip_y);
547
 
548
    radeonFlush(ctx);
549
 
550
    return GL_TRUE;
551
}