r600: add initial blit support
[mesa.git] / src / mesa / drivers / dri / r600 / r600_blit.c
1 /*
2 * Copyright (C) 2009 Advanced Micro Devices, Inc.
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 "r600_context.h"
30
31 #include "r600_blit.h"
32 #include "r600_blit_shaders.h"
33 #include "r600_cmdbuf.h"
34
35 static uint32_t mesa_format_to_cb_format(gl_format mesa_format)
36 {
37 uint32_t comp_swap, format, color_info = 0;
38 //fprintf(stderr,"format for copy %s\n",_mesa_get_format_name(mesa_format));
39 switch(mesa_format) {
40 /* XXX check and add these */
41 case MESA_FORMAT_RGBA8888:
42 comp_swap = SWAP_STD_REV;
43 format = FMT_8_8_8_8;
44 break;
45 case MESA_FORMAT_RGBA8888_REV:
46 comp_swap = SWAP_STD;
47 format = FMT_8_8_8_8;
48 break;
49 case MESA_FORMAT_ARGB8888:
50 case MESA_FORMAT_XRGB8888:
51 comp_swap = SWAP_ALT;
52 format = FMT_8_8_8_8;
53 break;
54 case MESA_FORMAT_ARGB8888_REV:
55 comp_swap = SWAP_ALT_REV;
56 format = FMT_8_8_8_8;
57 break;
58 case MESA_FORMAT_RGB565:
59 comp_swap = SWAP_ALT_REV;
60 format = FMT_5_6_5;
61 break;
62 case MESA_FORMAT_ARGB1555:
63 comp_swap = SWAP_ALT_REV;
64 format = FMT_1_5_5_5;
65 break;
66 case MESA_FORMAT_ARGB4444:
67 comp_swap = SWAP_ALT;
68 format = FMT_4_4_4_4;
69 break;
70 case MESA_FORMAT_S8_Z24:
71 format = FMT_8_24;
72 comp_swap = SWAP_STD;
73 break;
74 default:
75 fprintf(stderr,"Invalid format for copy %s\n",_mesa_get_format_name(mesa_format));
76 assert("Invalid format for US output\n");
77 return 0;
78 }
79
80 SETfield(color_info, format, CB_COLOR0_INFO__FORMAT_shift,
81 CB_COLOR0_INFO__FORMAT_mask);
82 SETfield(color_info, comp_swap, COMP_SWAP_shift, COMP_SWAP_mask);
83
84 return color_info;
85
86 }
87
88 static inline void
89 set_render_target(context_t *context, struct radeon_bo *bo, gl_format format,
90 int pitch, int bpp, int w, int h, intptr_t dst_offset)
91 {
92 uint32_t cb_color0_base, cb_color0_size = 0, cb_color0_info = 0, cb_color0_view;
93 int nPitchInPixel, id = 0;
94 BATCH_LOCALS(&context->radeon);
95
96 cb_color0_base = dst_offset / 256;
97 cb_color0_view = 0;
98
99 cb_color0_info = mesa_format_to_cb_format(format);
100
101 nPitchInPixel = pitch/bpp;
102 SETfield(cb_color0_size, (nPitchInPixel / 8) - 1,
103 PITCH_TILE_MAX_shift, PITCH_TILE_MAX_mask);
104 SETfield(cb_color0_size, ((nPitchInPixel * h) / 64) - 1,
105 SLICE_TILE_MAX_shift, SLICE_TILE_MAX_mask);
106 SETfield(cb_color0_info, ENDIAN_NONE, ENDIAN_shift, ENDIAN_mask);
107 SETfield(cb_color0_info, ARRAY_LINEAR_GENERAL,
108 CB_COLOR0_INFO__ARRAY_MODE_shift, CB_COLOR0_INFO__ARRAY_MODE_mask);
109 /*
110 if(4 == bpp)
111 {
112 SETfield(cb_color0_info, COLOR_8_8_8_8,
113 CB_COLOR0_INFO__FORMAT_shift, CB_COLOR0_INFO__FORMAT_mask);
114 SETfield(cb_color0_info, SWAP_ALT, COMP_SWAP_shift, COMP_SWAP_mask);
115 }
116 else
117 {
118 SETfield(cb_color0_info, COLOR_5_6_5,
119 CB_COLOR0_INFO__FORMAT_shift, CB_COLOR0_INFO__FORMAT_mask);
120 SETfield(cb_color0_info, SWAP_ALT_REV,
121 COMP_SWAP_shift, COMP_SWAP_mask);
122 }
123 */
124 SETbit(cb_color0_info, SOURCE_FORMAT_bit);
125 //SETbit(cb_color0_info, BLEND_CLAMP_bit);
126 SETbit(cb_color0_info, BLEND_BYPASS_bit);
127 SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask);
128
129 BEGIN_BATCH_NO_AUTOSTATE(3 + 2);
130 R600_OUT_BATCH_REGSEQ(CB_COLOR0_BASE + (4 * id), 1);
131 R600_OUT_BATCH(cb_color0_base);
132 R600_OUT_BATCH_RELOC(0,
133 bo,
134 0,
135 0, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0);
136 END_BATCH();
137
138 if ((context->radeon.radeonScreen->chip_family > CHIP_FAMILY_R600) &&
139 (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770)) {
140 BEGIN_BATCH_NO_AUTOSTATE(2);
141 R600_OUT_BATCH(CP_PACKET3(R600_IT_SURFACE_BASE_UPDATE, 0));
142 R600_OUT_BATCH((2 << id));
143 END_BATCH();
144 }
145
146 BEGIN_BATCH_NO_AUTOSTATE(18);
147 R600_OUT_BATCH_REGVAL(CB_COLOR0_SIZE + (4 * id), cb_color0_size);
148 R600_OUT_BATCH_REGVAL(CB_COLOR0_VIEW + (4 * id), cb_color0_view);
149 R600_OUT_BATCH_REGVAL(CB_COLOR0_INFO + (4 * id), cb_color0_info);
150 R600_OUT_BATCH_REGVAL(CB_COLOR0_TILE + (4 * id), 0);
151 R600_OUT_BATCH_REGVAL(CB_COLOR0_FRAG + (4 * id), 0);
152 R600_OUT_BATCH_REGVAL(CB_COLOR0_MASK + (4 * id), 0);
153 END_BATCH();
154
155 COMMIT_BATCH();
156
157 }
158
159 static inline void load_shaders(GLcontext * ctx)
160 {
161
162 radeonContextPtr radeonctx = RADEON_CONTEXT(ctx);
163 context_t *context = R700_CONTEXT(ctx);
164 int i, size;
165 uint32_t *shader;
166
167 if (context->blit_bo_loaded == 1)
168 return;
169
170 size = 4096;
171 context->blit_bo = radeon_bo_open(radeonctx->radeonScreen->bom, 0,
172 size, 256, RADEON_GEM_DOMAIN_GTT, 0);
173 radeon_bo_map(context->blit_bo, 1);
174 shader = context->blit_bo->ptr;
175
176 for(i=0; i<sizeof(r6xx_vs)/4; i++) {
177 shader[128+i] = r6xx_vs[i];
178 }
179 for(i=0; i<sizeof(r6xx_ps)/4; i++) {
180 shader[256+i] = r6xx_ps[i];
181 }
182
183 radeon_bo_unmap(context->blit_bo);
184 context->blit_bo_loaded = 1;
185
186 }
187
188 static inline void
189 set_shaders(context_t *context)
190 {
191 struct radeon_bo * pbo = context->blit_bo;
192 BATCH_LOCALS(&context->radeon);
193
194 uint32_t sq_pgm_start_fs = (512 >> 8);
195 uint32_t sq_pgm_resources_fs = 0;
196 uint32_t sq_pgm_cf_offset_fs = 0;
197
198 uint32_t sq_pgm_start_vs = (512 >> 8);
199 uint32_t sq_pgm_resources_vs = (1 << NUM_GPRS_shift);
200 uint32_t sq_pgm_cf_offset_vs = 0;
201
202 uint32_t sq_pgm_start_ps = (1024 >> 8);
203 uint32_t sq_pgm_resources_ps = (1 << NUM_GPRS_shift);
204 uint32_t sq_pgm_cf_offset_ps = 0;
205 uint32_t sq_pgm_exports_ps = (1 << 1);
206
207 radeon_cs_space_check_with_bo(context->radeon.cmdbuf.cs,
208 pbo,
209 RADEON_GEM_DOMAIN_GTT, 0);
210
211 r700SyncSurf(context, pbo, RADEON_GEM_DOMAIN_GTT, 0, SH_ACTION_ENA_bit);
212
213 /* FS */
214
215 BEGIN_BATCH_NO_AUTOSTATE(3 + 2);
216 R600_OUT_BATCH_REGSEQ(SQ_PGM_START_FS, 1);
217 R600_OUT_BATCH(sq_pgm_start_fs);
218 R600_OUT_BATCH_RELOC(sq_pgm_start_fs,
219 pbo,
220 sq_pgm_start_fs,
221 RADEON_GEM_DOMAIN_GTT, 0, 0);
222 END_BATCH();
223
224 BEGIN_BATCH_NO_AUTOSTATE(6);
225 R600_OUT_BATCH_REGVAL(SQ_PGM_RESOURCES_FS, sq_pgm_resources_fs);
226 R600_OUT_BATCH_REGVAL(SQ_PGM_CF_OFFSET_FS, sq_pgm_cf_offset_fs);
227 END_BATCH();
228
229 /* VS */
230
231 BEGIN_BATCH_NO_AUTOSTATE(3 + 2);
232 R600_OUT_BATCH_REGSEQ(SQ_PGM_START_VS, 1);
233 R600_OUT_BATCH(sq_pgm_start_vs);
234 R600_OUT_BATCH_RELOC(sq_pgm_start_vs,
235 pbo,
236 sq_pgm_start_vs,
237 RADEON_GEM_DOMAIN_GTT, 0, 0);
238 END_BATCH();
239
240 BEGIN_BATCH_NO_AUTOSTATE(6);
241 R600_OUT_BATCH_REGVAL(SQ_PGM_RESOURCES_VS, sq_pgm_resources_vs);
242 R600_OUT_BATCH_REGVAL(SQ_PGM_CF_OFFSET_VS, sq_pgm_cf_offset_vs);
243 END_BATCH();
244
245 /* PS */
246
247 BEGIN_BATCH_NO_AUTOSTATE(3 + 2);
248 R600_OUT_BATCH_REGSEQ(SQ_PGM_START_PS, 1);
249 R600_OUT_BATCH(sq_pgm_start_ps);
250 R600_OUT_BATCH_RELOC(sq_pgm_start_ps,
251 pbo,
252 sq_pgm_start_ps,
253 RADEON_GEM_DOMAIN_GTT, 0, 0);
254 END_BATCH();
255
256 BEGIN_BATCH_NO_AUTOSTATE(9);
257 R600_OUT_BATCH_REGVAL(SQ_PGM_RESOURCES_PS, sq_pgm_resources_ps);
258 R600_OUT_BATCH_REGVAL(SQ_PGM_EXPORTS_PS, sq_pgm_exports_ps);
259 R600_OUT_BATCH_REGVAL(SQ_PGM_CF_OFFSET_PS, sq_pgm_cf_offset_ps);
260 END_BATCH();
261
262 BEGIN_BATCH_NO_AUTOSTATE(18);
263 R600_OUT_BATCH_REGVAL(SPI_VS_OUT_CONFIG, 0); //EXPORT_COUNT is - 1
264 R600_OUT_BATCH_REGVAL(SPI_VS_OUT_ID_0, 0);
265 R600_OUT_BATCH_REGVAL(SPI_PS_INPUT_CNTL_0, SEL_CENTROID_bit);
266 R600_OUT_BATCH_REGVAL(SPI_PS_IN_CONTROL_0, (1 << NUM_INTERP_shift));
267 R600_OUT_BATCH_REGVAL(SPI_PS_IN_CONTROL_1, 0);
268 R600_OUT_BATCH_REGVAL(SPI_INTERP_CONTROL_0, 0);
269 END_BATCH();
270
271 COMMIT_BATCH();
272
273 }
274
275 static inline void
276 set_vtx_resource(context_t *context)
277 {
278 struct radeon_bo *bo = context->blit_bo;
279 BATCH_LOCALS(&context->radeon);
280
281 BEGIN_BATCH_NO_AUTOSTATE(6);
282 R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CTL_CONST, 1));
283 R600_OUT_BATCH(mmSQ_VTX_BASE_VTX_LOC - ASIC_CTL_CONST_BASE_INDEX);
284 R600_OUT_BATCH(0);
285
286 R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CTL_CONST, 1));
287 R600_OUT_BATCH(mmSQ_VTX_START_INST_LOC - ASIC_CTL_CONST_BASE_INDEX);
288 R600_OUT_BATCH(0);
289 END_BATCH();
290 COMMIT_BATCH();
291
292 if ((context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV610) ||
293 (context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV620) ||
294 (context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RS780) ||
295 (context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RS880) ||
296 (context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV710))
297 r700SyncSurf(context, bo, RADEON_GEM_DOMAIN_GTT, 0, TC_ACTION_ENA_bit);
298 else
299 r700SyncSurf(context, bo, RADEON_GEM_DOMAIN_GTT, 0, VC_ACTION_ENA_bit);
300
301 BEGIN_BATCH_NO_AUTOSTATE(9 + 2);
302
303 R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_RESOURCE, 7));
304 R600_OUT_BATCH(SQ_FETCH_RESOURCE_VS_OFFSET * FETCH_RESOURCE_STRIDE);
305 R600_OUT_BATCH(0);
306 R600_OUT_BATCH(48 - 1);
307 R600_OUT_BATCH(16 << SQ_VTX_CONSTANT_WORD2_0__STRIDE_shift);
308 R600_OUT_BATCH(1 << MEM_REQUEST_SIZE_shift);
309 R600_OUT_BATCH(0);
310 R600_OUT_BATCH(0);
311 R600_OUT_BATCH(SQ_TEX_VTX_VALID_BUFFER << SQ_TEX_RESOURCE_WORD6_0__TYPE_shift);
312 R600_OUT_BATCH_RELOC(SQ_VTX_CONSTANT_WORD0_0,
313 bo,
314 SQ_VTX_CONSTANT_WORD0_0,
315 RADEON_GEM_DOMAIN_GTT, 0, 0);
316 END_BATCH();
317 COMMIT_BATCH();
318
319 radeon_cs_space_check_with_bo(context->radeon.cmdbuf.cs,
320 bo,
321 RADEON_GEM_DOMAIN_GTT, 0);
322
323 }
324
325 static void
326 set_tex_resource(context_t * context,
327 gl_format format, struct radeon_bo *bo, int w, int h,
328 int pitch, intptr_t src_offset)
329 {
330 uint32_t sq_tex_resource0, sq_tex_resource1, sq_tex_resource2, sq_tex_resource4, sq_tex_resource6;
331 int bpp = _mesa_get_format_bytes(format);
332 int TexelPitch = pitch/bpp;
333 // int tex_format = mesa_format_to_us_format(format);
334
335 sq_tex_resource0 = sq_tex_resource1 = sq_tex_resource2 = sq_tex_resource4 = sq_tex_resource6 = 0;
336 BATCH_LOCALS(&context->radeon);
337
338 SETfield(sq_tex_resource0, SQ_TEX_DIM_2D, DIM_shift, DIM_mask);
339 SETfield(sq_tex_resource0, ARRAY_LINEAR_GENERAL,
340 SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_shift,
341 SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_mask);
342
343 if (bpp == 4) {
344 SETfield(sq_tex_resource1, FMT_8_8_8_8,
345 SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift,
346 SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
347
348 SETfield(sq_tex_resource4, SQ_SEL_Z,
349 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift,
350 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
351 SETfield(sq_tex_resource4, SQ_SEL_Y,
352 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift,
353 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
354 SETfield(sq_tex_resource4, SQ_SEL_X,
355 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift,
356 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
357 SETfield(sq_tex_resource4, SQ_SEL_W,
358 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift,
359 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
360 } else {
361 SETfield(sq_tex_resource1, FMT_5_6_5,
362 SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift,
363 SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
364 SETfield(sq_tex_resource4, SQ_SEL_Z,
365 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift,
366 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
367 SETfield(sq_tex_resource4, SQ_SEL_Y,
368 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift,
369 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
370 SETfield(sq_tex_resource4, SQ_SEL_X,
371 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift,
372 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
373 SETfield(sq_tex_resource4, SQ_SEL_1,
374 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift,
375 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
376
377 }
378
379 SETfield(sq_tex_resource0, (TexelPitch/8)-1, PITCH_shift, PITCH_mask);
380 SETfield(sq_tex_resource0, w - 1, TEX_WIDTH_shift, TEX_WIDTH_mask);
381 SETfield(sq_tex_resource1, h - 1, TEX_HEIGHT_shift, TEX_HEIGHT_mask);
382
383 sq_tex_resource2 = src_offset / 256;
384
385 SETfield(sq_tex_resource6, SQ_TEX_VTX_VALID_TEXTURE,
386 SQ_TEX_RESOURCE_WORD6_0__TYPE_shift,
387 SQ_TEX_RESOURCE_WORD6_0__TYPE_mask);
388
389 r700SyncSurf(context, bo,
390 RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM,
391 0, TC_ACTION_ENA_bit);
392
393 BEGIN_BATCH_NO_AUTOSTATE(9 + 4);
394 R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_RESOURCE, 7));
395 R600_OUT_BATCH(0 * 7);
396
397 R600_OUT_BATCH(sq_tex_resource0);
398 R600_OUT_BATCH(sq_tex_resource1);
399 R600_OUT_BATCH(sq_tex_resource2);
400 R600_OUT_BATCH(0); //SQ_TEX_RESOURCE3
401 R600_OUT_BATCH(sq_tex_resource4);
402 R600_OUT_BATCH(0); //SQ_TEX_RESOURCE5
403 R600_OUT_BATCH(sq_tex_resource6);
404 R600_OUT_BATCH_RELOC(0,
405 bo,
406 0,
407 RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
408 R600_OUT_BATCH_RELOC(0,
409 bo,
410 0,
411 RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
412 END_BATCH();
413 COMMIT_BATCH();
414 /*
415 if (h < 1)
416 h = 1;
417
418 sq_tex_resource_word0 = (1 << 0);
419 sq_tex_resource_word0 |= ((((pitch >> 3) - 1) << 8) |
420 ((w - 1) << 19));
421
422 sq_tex_resource_word1 = (format << 26);
423 sq_tex_resource_word1 |= ((h - 1) << 0);
424
425 sq_tex_resource_word4 = ((1 << 14) |
426 (0 << 16) |
427 (1 << 19) |
428 (2 << 22) |
429 (3 << 25));
430
431 */
432 }
433
434 static void
435 set_tex_sampler(context_t * context)
436 {
437 uint32_t sq_tex_sampler_word0 = 0, sq_tex_sampler_word1 = 0, sq_tex_sampler_word2 = 0;
438 int i = 0;
439
440 SETbit(sq_tex_sampler_word2, SQ_TEX_SAMPLER_WORD2_0__TYPE_bit);
441
442 BATCH_LOCALS(&context->radeon);
443
444 BEGIN_BATCH_NO_AUTOSTATE(5);
445 R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_SAMPLER, 3));
446 R600_OUT_BATCH(i * 3);
447 R600_OUT_BATCH(sq_tex_sampler_word0);
448 R600_OUT_BATCH(sq_tex_sampler_word1);
449 R600_OUT_BATCH(sq_tex_sampler_word2);
450 END_BATCH();
451
452 }
453
454 static inline void
455 set_scissors(context_t *context, int x1, int y1, int x2, int y2)
456 {
457
458 int i;
459 uint32_t clip_tl = 0, clip_br = 0;
460
461 SETfield(clip_tl, 0, PA_SC_CLIPRECT_0_TL__TL_X_shift,
462 PA_SC_CLIPRECT_0_TL__TL_X_mask);
463 SETfield(clip_tl, 0, PA_SC_CLIPRECT_0_TL__TL_Y_shift,
464 PA_SC_CLIPRECT_0_TL__TL_Y_mask);
465 SETfield(clip_br, 8191, PA_SC_CLIPRECT_0_BR__BR_X_shift,
466 PA_SC_CLIPRECT_0_BR__BR_X_mask);
467 SETfield(clip_br, 8191, PA_SC_CLIPRECT_0_BR__BR_Y_shift,
468 PA_SC_CLIPRECT_0_BR__BR_Y_mask);
469
470 BATCH_LOCALS(&context->radeon);
471
472 BEGIN_BATCH_NO_AUTOSTATE(13);
473 R600_OUT_BATCH_REGSEQ(PA_SC_SCREEN_SCISSOR_TL, 2);
474 R600_OUT_BATCH((x1 << 0) | (y1 << 16));
475 R600_OUT_BATCH((x2 << 0) | (y2 << 16));
476
477 R600_OUT_BATCH_REGSEQ(PA_SC_WINDOW_OFFSET, 3);
478 R600_OUT_BATCH(0); //PA_SC_WINDOW_OFFSET
479 R600_OUT_BATCH((x1 << 0) | (y1 << 16) | (WINDOW_OFFSET_DISABLE_bit)); //PA_SC_WINDOW_SCISSOR_TL
480 R600_OUT_BATCH((x2 << 0) | (y2 << 16));
481
482 /* clip disabled ?
483 R600_OUT_BATCH(CLIP_RULE_mask); //PA_SC_CLIPRECT_RULE);
484 R600_OUT_BATCH(clip_tl); //PA_SC_CLIPRECT_0_TL
485 R600_OUT_BATCH(clip_br); //PA_SC_CLIPRECT_0_BR
486 R600_OUT_BATCH(clip_tl); // 1
487 R600_OUT_BATCH(clip_br);
488 R600_OUT_BATCH(clip_tl); // 2
489 R600_OUT_BATCH(clip_br);
490 R600_OUT_BATCH(clip_tl); // 3
491 R600_OUT_BATCH(clip_br);
492 */
493
494 R600_OUT_BATCH_REGSEQ(PA_SC_GENERIC_SCISSOR_TL, 2);
495 R600_OUT_BATCH((x1 << 0) | (y1 << 16) | (WINDOW_OFFSET_DISABLE_bit));
496 R600_OUT_BATCH((x2 << 0) | (y2 << 16));
497 END_BATCH();
498
499 /* XXX 16 of these PA_SC_VPORT_SCISSOR_0_TL_num ... */
500 BEGIN_BATCH_NO_AUTOSTATE(4);
501 R600_OUT_BATCH_REGSEQ(PA_SC_VPORT_SCISSOR_0_TL, 2 );
502 R600_OUT_BATCH((x1 << 0) | (y1 << 16) | (WINDOW_OFFSET_DISABLE_bit));
503 R600_OUT_BATCH((x2 << 0) | (y2 << 16));
504 END_BATCH();
505
506 /*
507 BEGIN_BATCH_NO_AUTOSTATE(2 + 2 * PA_SC_VPORT_ZMIN_0_num);
508 R600_OUT_BATCH_REGSEQ(PA_SC_VPORT_ZMIN_0, 2 * PA_SC_VPORT_ZMIN_0_num);
509 for(i = 0 i < PA_SC_VPORT_ZMIN_0_num; i++)
510 R600_OUT_BATCH(radeonPackFloat32(0.0F));
511 R600_OUT_BATCH(radeonPackFloat32(1.0F));
512 }
513 END_BATCH();
514 */
515 COMMIT_BATCH();
516
517 }
518
519 static void
520 set_vb_data(context_t * context, int src_x, int src_y, int dst_x, int dst_y,
521 int w, int h, int src_h, unsigned flip_y)
522 {
523 float *vb;
524 radeon_bo_map(context->blit_bo, 1);
525 vb = context->blit_bo->ptr;
526
527 vb[0] = (float)(dst_x);
528 vb[1] = (float)(dst_y);
529 vb[2] = (float)(src_x);
530 vb[3] = (flip_y) ? (float)(src_h - src_y) : (float)src_y;
531
532 vb[4] = (float)(dst_x);
533 vb[5] = (float)(dst_y + h);
534 vb[6] = (float)(src_x);
535 vb[7] = (flip_y) ? (float)(src_h - (src_y + h)) : (float)(src_y + h);
536
537 vb[8] = (float)(dst_x + w);
538 vb[9] = (float)(dst_y + h);
539 vb[10] = (float)(src_x + w);
540 vb[11] = (flip_y) ? (float)(src_h - (src_y + h)) : (float)(src_y + h);
541
542 radeon_bo_unmap(context->blit_bo);
543
544 }
545
546 static inline void
547 draw_auto(context_t *context)
548 {
549 BATCH_LOCALS(&context->radeon);
550 uint32_t vgt_primitive_type = 0, vgt_index_type = 0, vgt_draw_initiator = 0, vgt_num_indices;
551
552 SETfield(vgt_primitive_type, DI_PT_RECTLIST,
553 VGT_PRIMITIVE_TYPE__PRIM_TYPE_shift,
554 VGT_PRIMITIVE_TYPE__PRIM_TYPE_mask);
555 SETfield(vgt_index_type, DI_INDEX_SIZE_16_BIT, INDEX_TYPE_shift,
556 INDEX_TYPE_mask);
557 SETfield(vgt_draw_initiator, DI_MAJOR_MODE_0, MAJOR_MODE_shift,
558 MAJOR_MODE_mask);
559 SETfield(vgt_draw_initiator, DI_SRC_SEL_AUTO_INDEX, SOURCE_SELECT_shift,
560 SOURCE_SELECT_mask);
561
562 vgt_num_indices = 3;
563
564 BEGIN_BATCH_NO_AUTOSTATE(10);
565 // prim
566 R600_OUT_BATCH_REGSEQ(VGT_PRIMITIVE_TYPE, 1);
567 R600_OUT_BATCH(vgt_primitive_type);
568 // index type
569 R600_OUT_BATCH(CP_PACKET3(R600_IT_INDEX_TYPE, 0));
570 R600_OUT_BATCH(vgt_index_type);
571 // num instances
572 R600_OUT_BATCH(CP_PACKET3(R600_IT_NUM_INSTANCES, 0));
573 R600_OUT_BATCH(1);
574 //
575 R600_OUT_BATCH(CP_PACKET3(R600_IT_DRAW_INDEX_AUTO, 1));
576 R600_OUT_BATCH(vgt_num_indices);
577 R600_OUT_BATCH(vgt_draw_initiator);
578
579 END_BATCH();
580 COMMIT_BATCH();
581 }
582
583 static inline void
584 set_default_state(context_t *context)
585 {
586 int i;
587 BATCH_LOCALS(&context->radeon);
588 /*
589 BEGIN_BATCH_NO_AUTOSTATE(sizeof(r7xx_default_state)/4);
590 for(i=0; i< sizeof(r7xx_default_state)/4; i++)
591 R600_OUT_BATCH(r7xx_default_state[i]);
592 END_BATCH();
593 */
594 BEGIN_BATCH_NO_AUTOSTATE(45);
595 R600_OUT_BATCH_REGVAL(CB_CLRCMP_CONTROL,
596 (CLRCMP_SEL_SRC << CLRCMP_FCN_SEL_shift));
597 R600_OUT_BATCH_REGVAL(SQ_VTX_BASE_VTX_LOC, 0);
598 R600_OUT_BATCH_REGVAL(SQ_VTX_START_INST_LOC, 0);
599 R600_OUT_BATCH_REGVAL(DB_DEPTH_INFO, 0);
600 R600_OUT_BATCH_REGVAL(DB_DEPTH_CONTROL, 0);
601 R600_OUT_BATCH_REGVAL(CB_SHADER_MASK, (OUTPUT0_ENABLE_mask));
602 R600_OUT_BATCH_REGVAL(CB_TARGET_MASK, (TARGET0_ENABLE_mask));
603 R600_OUT_BATCH_REGVAL(R7xx_CB_SHADER_CONTROL, (RT0_ENABLE_bit));
604 R600_OUT_BATCH_REGVAL(CB_COLOR_CONTROL, (0xcc << ROP3_shift));
605
606 /*
607 R600_OUT_BATCH_REGSEQ(PA_CL_VPORT_XSCALE_0, 6);
608 R600_OUT_BATCH(0.0f); // PA_CL_VPORT_XSCALE
609 R600_OUT_BATCH(0.0f); // PA_CL_VPORT_XOFFSET
610 R600_OUT_BATCH(0.0f); // PA_CL_VPORT_YSCALE
611 R600_OUT_BATCH(0.0f); // PA_CL_VPORT_YOFFSET
612 R600_OUT_BATCH(0.0f); // PA_CL_VPORT_ZSCALE
613 R600_OUT_BATCH(0.0f); // PA_CL_VPORT_ZOFFSET
614 */
615 R600_OUT_BATCH_REGVAL(PA_CL_VTE_CNTL, VTX_XY_FMT_bit);
616 R600_OUT_BATCH_REGVAL(PA_CL_VS_OUT_CNTL, 0 );
617 R600_OUT_BATCH_REGVAL(PA_CL_CLIP_CNTL, CLIP_DISABLE_bit);
618 R600_OUT_BATCH_REGVAL(PA_SU_SC_MODE_CNTL, (FACE_bit) |
619 (POLYMODE_PTYPE__TRIANGLES << POLYMODE_FRONT_PTYPE_shift) |
620 (POLYMODE_PTYPE__TRIANGLES << POLYMODE_BACK_PTYPE_shift));
621 R600_OUT_BATCH_REGVAL(PA_SU_VTX_CNTL, (PIX_CENTER_bit) |
622 (X_ROUND_TO_EVEN << PA_SU_VTX_CNTL__ROUND_MODE_shift) |
623 (X_1_256TH << QUANT_MODE_shift));
624 R600_OUT_BATCH_REGVAL(VGT_MAX_VTX_INDX, 2048);
625 END_BATCH();
626 /*
627 if (dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) {
628 BEGIN_RING(r7xx_default_size + 10);
629 for (i = 0; i < r7xx_default_size; i++)
630 OUT_RING(r7xx_default_state[i]);
631 } else {
632 BEGIN_RING(r6xx_default_size + 10);
633 for (i = 0; i < r6xx_default_size; i++)
634 OUT_RING(r6xx_default_state[i]);
635 }
636 OUT_RING(CP_PACKET3(R600_IT_EVENT_WRITE, 0));
637 OUT_RING(R600_CACHE_FLUSH_AND_INV_EVENT);
638
639 //OR :
640 r700WaitForIdleClean(context_t *context);
641 */
642 /* SQ config */
643 /*XXX*/
644 /*
645 r700SendSQConfig(GLcontext *ctx, struct radeon_state_atom *atom);
646 // OR:
647 OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 6));
648 OUT_RING((R600_SQ_CONFIG - R600_SET_CONFIG_REG_OFFSET) >> 2);
649 OUT_RING(sq_config);
650 OUT_RING(sq_gpr_resource_mgmt_1);
651 OUT_RING(sq_gpr_resource_mgmt_2);
652 OUT_RING(sq_thread_resource_mgmt);
653 OUT_RING(sq_stack_resource_mgmt_1);
654 OUT_RING(sq_stack_resource_mgmt_2);
655 ADVANCE_RING();
656 */
657 }
658
659 static GLboolean validate_buffers(context_t *rmesa,
660 struct radeon_bo *src_bo,
661 struct radeon_bo *dst_bo)
662 {
663 int ret;
664 radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs,
665 src_bo, RADEON_GEM_DOMAIN_VRAM, 0);
666
667 radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs,
668 dst_bo, 0, RADEON_GEM_DOMAIN_VRAM);
669
670 ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs,
671 first_elem(&rmesa->radeon.dma.reserved)->bo,
672 RADEON_GEM_DOMAIN_GTT, 0);
673 if (ret)
674 return GL_FALSE;
675
676 return GL_TRUE;
677 }
678
679 GLboolean r600_blit(context_t *context,
680 struct radeon_bo *src_bo,
681 intptr_t src_offset,
682 gl_format src_mesaformat,
683 unsigned src_pitch,
684 unsigned src_width,
685 unsigned src_height,
686 unsigned src_x,
687 unsigned src_y,
688 struct radeon_bo *dst_bo,
689 intptr_t dst_offset,
690 gl_format dst_mesaformat,
691 unsigned dst_pitch,
692 unsigned dst_width,
693 unsigned dst_height,
694 unsigned dst_x,
695 unsigned dst_y,
696 unsigned w,
697 unsigned h,
698 unsigned flip_y)
699 {
700 int id = 0;
701 uint32_t cb_bpp;
702
703 if (src_bo == dst_bo) {
704 return GL_FALSE;
705 }
706
707 if (0) {
708 fprintf(stderr, "src: width %d, height %d, pitch %d vs %d, format %s\n",
709 src_width, src_height, src_pitch,
710 _mesa_format_row_stride(src_mesaformat, src_width),
711 _mesa_get_format_name(src_mesaformat));
712 fprintf(stderr, "dst: width %d, height %d, pitch %d, format %s\n",
713 dst_width, dst_height,
714 _mesa_format_row_stride(dst_mesaformat, dst_width),
715 _mesa_get_format_name(dst_mesaformat));
716 }
717
718 /* Flush is needed to make sure that source buffer has correct data */
719 radeonFlush(context->radeon.glCtx);
720
721 if (!validate_buffers(context, src_bo, dst_bo))
722 return GL_FALSE;
723
724 rcommonEnsureCmdBufSpace(&context->radeon, 200, __FUNCTION__);
725
726 /* set clear state */
727 set_default_state(context);
728 /* src */
729 set_tex_resource(context, src_mesaformat, src_bo,
730 src_width, src_height, src_pitch, src_offset);
731
732 set_tex_sampler(context);
733
734 /* dst */
735 cb_bpp = _mesa_get_format_bytes(dst_mesaformat);
736 set_render_target(context, dst_bo, dst_mesaformat,
737 dst_pitch, cb_bpp, dst_width, dst_height, dst_offset);
738 /* shaders */
739 load_shaders(context->radeon.glCtx);
740
741 set_shaders(context);
742
743 /* scissors */
744 set_scissors(context, 0, 0, 8191, 8191);
745
746 set_vb_data(context, src_x, src_y, dst_x, dst_y, w, h, src_height, flip_y);
747 /* Vertex buffer setup */
748 set_vtx_resource(context);
749
750 /* draw */
751 draw_auto(context);
752
753 r700SyncSurf(context, dst_bo, 0,
754 RADEON_GEM_DOMAIN_VRAM|RADEON_GEM_DOMAIN_GTT,
755 CB_ACTION_ENA_bit | (1 << (id + 6)));
756
757 radeonFlush(context->radeon.glCtx);
758
759 return GL_TRUE;
760 }