1 /*
2 * Copyright 2010 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 *
23 * Author: Alex Deucher <alexander.deucher@amd.com>
24 *
25 */
26
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #include "xf86.h"
32
33 #include "exa.h"
34
35 #include "radeon.h"
36 #include "radeon_reg.h"
37 #include "evergreen_shader.h"
38 #include "evergreen_reg.h"
39 #include "evergreen_state.h"
40 #include "radeon_exa_shared.h"
41 #include "radeon_vbo.h"
42
43 extern int cayman_solid_vs(RADEONChipFamily ChipSet, uint32_t* vs);
44 extern int cayman_solid_ps(RADEONChipFamily ChipSet, uint32_t* ps);
45
46 extern int cayman_copy_vs(RADEONChipFamily ChipSet, uint32_t* vs);
47 extern int cayman_copy_ps(RADEONChipFamily ChipSet, uint32_t* ps);
48
49 extern int cayman_xv_vs(RADEONChipFamily ChipSet, uint32_t* shader);
50 extern int cayman_xv_ps(RADEONChipFamily ChipSet, uint32_t* shader);
51
52 extern int cayman_comp_vs(RADEONChipFamily ChipSet, uint32_t* vs);
53 extern int cayman_comp_ps(RADEONChipFamily ChipSet, uint32_t* ps);
54
55 static Bool
EVERGREENPrepareSolid(PixmapPtr pPix,int alu,Pixel pm,Pixel fg)56 EVERGREENPrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg)
57 {
58 ScrnInfoPtr pScrn = xf86ScreenToScrn(pPix->drawable.pScreen);
59 RADEONInfoPtr info = RADEONPTR(pScrn);
60 struct radeon_accel_state *accel_state = info->accel_state;
61 cb_config_t cb_conf;
62 shader_config_t vs_conf, ps_conf;
63 uint32_t a, r, g, b;
64 float *ps_alu_consts;
65 const_config_t ps_const_conf;
66 struct r600_accel_object dst;
67
68
69 if (!RADEONCheckBPP(pPix->drawable.bitsPerPixel))
70 RADEON_FALLBACK(("EVERGREENCheckDatatype failed\n"));
71 if (!RADEONValidPM(pm, pPix->drawable.bitsPerPixel))
72 RADEON_FALLBACK(("invalid planemask\n"));
73
74 dst.bo = radeon_get_pixmap_bo(pPix)->bo.radeon;
75 dst.tiling_flags = radeon_get_pixmap_tiling(pPix);
76 dst.surface = radeon_get_pixmap_surface(pPix);
77
78 dst.pitch = exaGetPixmapPitch(pPix) / (pPix->drawable.bitsPerPixel / 8);
79 dst.width = pPix->drawable.width;
80 dst.height = pPix->drawable.height;
81 dst.bpp = pPix->drawable.bitsPerPixel;
82 dst.domain = RADEON_GEM_DOMAIN_VRAM;
83
84 if (!R600SetAccelState(pScrn,
85 NULL,
86 NULL,
87 &dst,
88 accel_state->solid_vs_offset, accel_state->solid_ps_offset,
89 alu, pm))
90 return FALSE;
91
92 CLEAR (cb_conf);
93 CLEAR (vs_conf);
94 CLEAR (ps_conf);
95 CLEAR (ps_const_conf);
96
97 radeon_vbo_check(pScrn, &accel_state->vbo, 16);
98 radeon_vbo_check(pScrn, &accel_state->cbuf, 256);
99 radeon_cp_start(pScrn);
100
101 evergreen_set_default_state(pScrn);
102
103 evergreen_set_generic_scissor(pScrn, 0, 0, accel_state->dst_obj.width, accel_state->dst_obj.height);
104 evergreen_set_screen_scissor(pScrn, 0, 0, accel_state->dst_obj.width, accel_state->dst_obj.height);
105 evergreen_set_window_scissor(pScrn, 0, 0, accel_state->dst_obj.width, accel_state->dst_obj.height);
106
107 /* Shader */
108 vs_conf.shader_addr = accel_state->vs_mc_addr;
109 vs_conf.shader_size = accel_state->vs_size;
110 vs_conf.num_gprs = 2;
111 vs_conf.stack_size = 0;
112 vs_conf.bo = accel_state->shaders_bo;
113 evergreen_vs_setup(pScrn, &vs_conf, RADEON_GEM_DOMAIN_VRAM);
114
115 ps_conf.shader_addr = accel_state->ps_mc_addr;
116 ps_conf.shader_size = accel_state->ps_size;
117 ps_conf.num_gprs = 1;
118 ps_conf.stack_size = 0;
119 ps_conf.clamp_consts = 0;
120 ps_conf.export_mode = 2;
121 ps_conf.bo = accel_state->shaders_bo;
122 evergreen_ps_setup(pScrn, &ps_conf, RADEON_GEM_DOMAIN_VRAM);
123
124 cb_conf.id = 0;
125 cb_conf.w = accel_state->dst_obj.pitch;
126 cb_conf.h = accel_state->dst_obj.height;
127 cb_conf.base = 0;
128 cb_conf.bo = accel_state->dst_obj.bo;
129 cb_conf.surface = accel_state->dst_obj.surface;
130
131 if (accel_state->dst_obj.bpp == 8) {
132 cb_conf.format = COLOR_8;
133 cb_conf.comp_swap = 3; /* A */
134 } else if (accel_state->dst_obj.bpp == 16) {
135 cb_conf.format = COLOR_5_6_5;
136 cb_conf.comp_swap = 2; /* RGB */
137 #if X_BYTE_ORDER == X_BIG_ENDIAN
138 cb_conf.endian = ENDIAN_8IN16;
139 #endif
140 } else {
141 cb_conf.format = COLOR_8_8_8_8;
142 cb_conf.comp_swap = 1; /* ARGB */
143 #if X_BYTE_ORDER == X_BIG_ENDIAN
144 cb_conf.endian = ENDIAN_8IN32;
145 #endif
146 }
147 cb_conf.source_format = EXPORT_4C_16BPC;
148 cb_conf.blend_clamp = 1;
149 /* Render setup */
150 if (accel_state->planemask & 0x000000ff)
151 cb_conf.pmask |= 4; /* B */
152 if (accel_state->planemask & 0x0000ff00)
153 cb_conf.pmask |= 2; /* G */
154 if (accel_state->planemask & 0x00ff0000)
155 cb_conf.pmask |= 1; /* R */
156 if (accel_state->planemask & 0xff000000)
157 cb_conf.pmask |= 8; /* A */
158 cb_conf.rop = accel_state->rop;
159 if ((accel_state->dst_obj.tiling_flags & RADEON_TILING_MASK) ==
160 RADEON_TILING_LINEAR) {
161 cb_conf.array_mode = 0;
162 cb_conf.non_disp_tiling = 1;
163 }
164 evergreen_set_render_target(pScrn, &cb_conf, accel_state->dst_obj.domain);
165
166 evergreen_set_spi(pScrn, 0, 0);
167
168 /* PS alu constants */
169 ps_const_conf.size_bytes = 256;
170 ps_const_conf.type = SHADER_TYPE_PS;
171 ps_alu_consts = radeon_vbo_space(pScrn, &accel_state->cbuf, 256);
172 ps_const_conf.bo = accel_state->cbuf.vb_bo;
173 ps_const_conf.const_addr = accel_state->cbuf.vb_offset;
174 ps_const_conf.cpu_ptr = (uint32_t *)(char *)ps_alu_consts;
175 if (accel_state->dst_obj.bpp == 16) {
176 r = (fg >> 11) & 0x1f;
177 g = (fg >> 5) & 0x3f;
178 b = (fg >> 0) & 0x1f;
179 ps_alu_consts[0] = (float)r / 31; /* R */
180 ps_alu_consts[1] = (float)g / 63; /* G */
181 ps_alu_consts[2] = (float)b / 31; /* B */
182 ps_alu_consts[3] = 1.0; /* A */
183 } else if (accel_state->dst_obj.bpp == 8) {
184 a = (fg >> 0) & 0xff;
185 ps_alu_consts[0] = 0.0; /* R */
186 ps_alu_consts[1] = 0.0; /* G */
187 ps_alu_consts[2] = 0.0; /* B */
188 ps_alu_consts[3] = (float)a / 255; /* A */
189 } else {
190 a = (fg >> 24) & 0xff;
191 r = (fg >> 16) & 0xff;
192 g = (fg >> 8) & 0xff;
193 b = (fg >> 0) & 0xff;
194 ps_alu_consts[0] = (float)r / 255; /* R */
195 ps_alu_consts[1] = (float)g / 255; /* G */
196 ps_alu_consts[2] = (float)b / 255; /* B */
197 ps_alu_consts[3] = (float)a / 255; /* A */
198 }
199 radeon_vbo_commit(pScrn, &accel_state->cbuf);
200 evergreen_set_alu_consts(pScrn, &ps_const_conf, RADEON_GEM_DOMAIN_GTT);
201
202 if (accel_state->vsync)
203 RADEONVlineHelperClear(pScrn);
204
205 accel_state->dst_pix = pPix;
206 accel_state->fg = fg;
207
208 return TRUE;
209 }
210
211 static void
EVERGREENDoneSolid(PixmapPtr pPix)212 EVERGREENDoneSolid(PixmapPtr pPix)
213 {
214 ScrnInfoPtr pScrn = xf86ScreenToScrn(pPix->drawable.pScreen);
215 RADEONInfoPtr info = RADEONPTR(pScrn);
216 struct radeon_accel_state *accel_state = info->accel_state;
217
218 if (accel_state->vsync)
219 evergreen_cp_wait_vline_sync(pScrn, pPix,
220 accel_state->vline_crtc,
221 accel_state->vline_y1,
222 accel_state->vline_y2);
223
224 evergreen_finish_op(pScrn, 8);
225 }
226
227 static void
EVERGREENSolid(PixmapPtr pPix,int x1,int y1,int x2,int y2)228 EVERGREENSolid(PixmapPtr pPix, int x1, int y1, int x2, int y2)
229 {
230 ScrnInfoPtr pScrn = xf86ScreenToScrn(pPix->drawable.pScreen);
231 RADEONInfoPtr info = RADEONPTR(pScrn);
232 struct radeon_accel_state *accel_state = info->accel_state;
233 float *vb;
234
235 if (CS_FULL(info->cs)) {
236 EVERGREENDoneSolid(info->accel_state->dst_pix);
237 radeon_cs_flush_indirect(pScrn);
238 EVERGREENPrepareSolid(accel_state->dst_pix,
239 accel_state->rop,
240 accel_state->planemask,
241 accel_state->fg);
242 }
243
244 if (accel_state->vsync)
245 RADEONVlineHelperSet(pScrn, x1, y1, x2, y2);
246
247 vb = radeon_vbo_space(pScrn, &accel_state->vbo, 8);
248
249 vb[0] = (float)x1;
250 vb[1] = (float)y1;
251
252 vb[2] = (float)x1;
253 vb[3] = (float)y2;
254
255 vb[4] = (float)x2;
256 vb[5] = (float)y2;
257
258 radeon_vbo_commit(pScrn, &accel_state->vbo);
259 }
260
261 static void
EVERGREENDoPrepareCopy(ScrnInfoPtr pScrn)262 EVERGREENDoPrepareCopy(ScrnInfoPtr pScrn)
263 {
264 RADEONInfoPtr info = RADEONPTR(pScrn);
265 struct radeon_accel_state *accel_state = info->accel_state;
266 cb_config_t cb_conf;
267 tex_resource_t tex_res;
268 tex_sampler_t tex_samp;
269 shader_config_t vs_conf, ps_conf;
270
271 CLEAR (cb_conf);
272 CLEAR (tex_res);
273 CLEAR (tex_samp);
274 CLEAR (vs_conf);
275 CLEAR (ps_conf);
276
277 radeon_vbo_check(pScrn, &accel_state->vbo, 16);
278 radeon_cp_start(pScrn);
279
280 evergreen_set_default_state(pScrn);
281
282 evergreen_set_generic_scissor(pScrn, 0, 0, accel_state->dst_obj.width, accel_state->dst_obj.height);
283 evergreen_set_screen_scissor(pScrn, 0, 0, accel_state->dst_obj.width, accel_state->dst_obj.height);
284 evergreen_set_window_scissor(pScrn, 0, 0, accel_state->dst_obj.width, accel_state->dst_obj.height);
285
286 /* Shader */
287 vs_conf.shader_addr = accel_state->vs_mc_addr;
288 vs_conf.shader_size = accel_state->vs_size;
289 vs_conf.num_gprs = 2;
290 vs_conf.stack_size = 0;
291 vs_conf.bo = accel_state->shaders_bo;
292 evergreen_vs_setup(pScrn, &vs_conf, RADEON_GEM_DOMAIN_VRAM);
293
294 ps_conf.shader_addr = accel_state->ps_mc_addr;
295 ps_conf.shader_size = accel_state->ps_size;
296 ps_conf.num_gprs = 1;
297 ps_conf.stack_size = 0;
298 ps_conf.clamp_consts = 0;
299 ps_conf.export_mode = 2;
300 ps_conf.bo = accel_state->shaders_bo;
301 evergreen_ps_setup(pScrn, &ps_conf, RADEON_GEM_DOMAIN_VRAM);
302
303 /* Texture */
304 tex_res.id = 0;
305 tex_res.w = accel_state->src_obj[0].width;
306 tex_res.h = accel_state->src_obj[0].height;
307 tex_res.pitch = accel_state->src_obj[0].pitch;
308 tex_res.depth = 0;
309 tex_res.dim = SQ_TEX_DIM_2D;
310 tex_res.base = 0;
311 tex_res.mip_base = 0;
312 tex_res.size = accel_state->src_size[0];
313 tex_res.bo = accel_state->src_obj[0].bo;
314 tex_res.mip_bo = accel_state->src_obj[0].bo;
315 tex_res.surface = accel_state->src_obj[0].surface;
316 if (accel_state->src_obj[0].bpp == 8) {
317 tex_res.format = FMT_8;
318 tex_res.dst_sel_x = SQ_SEL_1; /* R */
319 tex_res.dst_sel_y = SQ_SEL_1; /* G */
320 tex_res.dst_sel_z = SQ_SEL_1; /* B */
321 tex_res.dst_sel_w = SQ_SEL_X; /* A */
322 } else if (accel_state->src_obj[0].bpp == 16) {
323 tex_res.format = FMT_5_6_5;
324 tex_res.dst_sel_x = SQ_SEL_Z; /* R */
325 tex_res.dst_sel_y = SQ_SEL_Y; /* G */
326 tex_res.dst_sel_z = SQ_SEL_X; /* B */
327 tex_res.dst_sel_w = SQ_SEL_1; /* A */
328 } else {
329 tex_res.format = FMT_8_8_8_8;
330 tex_res.dst_sel_x = SQ_SEL_Z; /* R */
331 tex_res.dst_sel_y = SQ_SEL_Y; /* G */
332 tex_res.dst_sel_z = SQ_SEL_X; /* B */
333 tex_res.dst_sel_w = SQ_SEL_W; /* A */
334 }
335
336 tex_res.base_level = 0;
337 tex_res.last_level = 0;
338 tex_res.perf_modulation = 0;
339 if ((accel_state->src_obj[0].tiling_flags & RADEON_TILING_MASK) ==
340 RADEON_TILING_LINEAR)
341 tex_res.array_mode = 0;
342 evergreen_set_tex_resource(pScrn, &tex_res, accel_state->src_obj[0].domain);
343
344 tex_samp.id = 0;
345 tex_samp.clamp_x = SQ_TEX_CLAMP_LAST_TEXEL;
346 tex_samp.clamp_y = SQ_TEX_CLAMP_LAST_TEXEL;
347 tex_samp.clamp_z = SQ_TEX_WRAP;
348 tex_samp.xy_mag_filter = SQ_TEX_XY_FILTER_POINT;
349 tex_samp.xy_min_filter = SQ_TEX_XY_FILTER_POINT;
350 tex_samp.mc_coord_truncate = 1;
351 tex_samp.z_filter = SQ_TEX_Z_FILTER_NONE;
352 tex_samp.mip_filter = 0; /* no mipmap */
353 evergreen_set_tex_sampler (pScrn, &tex_samp);
354
355 cb_conf.id = 0;
356 cb_conf.w = accel_state->dst_obj.pitch;
357 cb_conf.h = accel_state->dst_obj.height;
358 cb_conf.base = 0;
359 cb_conf.bo = accel_state->dst_obj.bo;
360 cb_conf.surface = accel_state->dst_obj.surface;
361 if (accel_state->dst_obj.bpp == 8) {
362 cb_conf.format = COLOR_8;
363 cb_conf.comp_swap = 3; /* A */
364 } else if (accel_state->dst_obj.bpp == 16) {
365 cb_conf.format = COLOR_5_6_5;
366 cb_conf.comp_swap = 2; /* RGB */
367 } else {
368 cb_conf.format = COLOR_8_8_8_8;
369 cb_conf.comp_swap = 1; /* ARGB */
370 }
371 cb_conf.source_format = EXPORT_4C_16BPC;
372 cb_conf.blend_clamp = 1;
373 /* Render setup */
374 if (accel_state->planemask & 0x000000ff)
375 cb_conf.pmask |= 4; /* B */
376 if (accel_state->planemask & 0x0000ff00)
377 cb_conf.pmask |= 2; /* G */
378 if (accel_state->planemask & 0x00ff0000)
379 cb_conf.pmask |= 1; /* R */
380 if (accel_state->planemask & 0xff000000)
381 cb_conf.pmask |= 8; /* A */
382 cb_conf.rop = accel_state->rop;
383 if ((accel_state->dst_obj.tiling_flags & RADEON_TILING_MASK) ==
384 RADEON_TILING_LINEAR) {
385 cb_conf.array_mode = 0;
386 cb_conf.non_disp_tiling = 1;
387 }
388 evergreen_set_render_target(pScrn, &cb_conf, accel_state->dst_obj.domain);
389
390 evergreen_set_spi(pScrn, (1 - 1), 1);
391
392 }
393
394 static void
EVERGREENDoCopy(ScrnInfoPtr pScrn)395 EVERGREENDoCopy(ScrnInfoPtr pScrn)
396 {
397 evergreen_finish_op(pScrn, 16);
398 }
399
400 static void
EVERGREENDoCopyVline(PixmapPtr pPix)401 EVERGREENDoCopyVline(PixmapPtr pPix)
402 {
403 ScrnInfoPtr pScrn = xf86ScreenToScrn(pPix->drawable.pScreen);
404 RADEONInfoPtr info = RADEONPTR(pScrn);
405 struct radeon_accel_state *accel_state = info->accel_state;
406
407 if (accel_state->vsync)
408 evergreen_cp_wait_vline_sync(pScrn, pPix,
409 accel_state->vline_crtc,
410 accel_state->vline_y1,
411 accel_state->vline_y2);
412
413 evergreen_finish_op(pScrn, 16);
414 }
415
416 static void
EVERGREENAppendCopyVertex(ScrnInfoPtr pScrn,int srcX,int srcY,int dstX,int dstY,int w,int h)417 EVERGREENAppendCopyVertex(ScrnInfoPtr pScrn,
418 int srcX, int srcY,
419 int dstX, int dstY,
420 int w, int h)
421 {
422 RADEONInfoPtr info = RADEONPTR(pScrn);
423 struct radeon_accel_state *accel_state = info->accel_state;
424 float *vb;
425
426 vb = radeon_vbo_space(pScrn, &accel_state->vbo, 16);
427
428 vb[0] = (float)dstX;
429 vb[1] = (float)dstY;
430 vb[2] = (float)srcX;
431 vb[3] = (float)srcY;
432
433 vb[4] = (float)dstX;
434 vb[5] = (float)(dstY + h);
435 vb[6] = (float)srcX;
436 vb[7] = (float)(srcY + h);
437
438 vb[8] = (float)(dstX + w);
439 vb[9] = (float)(dstY + h);
440 vb[10] = (float)(srcX + w);
441 vb[11] = (float)(srcY + h);
442
443 radeon_vbo_commit(pScrn, &accel_state->vbo);
444 }
445
446 static Bool
EVERGREENPrepareCopy(PixmapPtr pSrc,PixmapPtr pDst,int xdir,int ydir,int rop,Pixel planemask)447 EVERGREENPrepareCopy(PixmapPtr pSrc, PixmapPtr pDst,
448 int xdir, int ydir,
449 int rop,
450 Pixel planemask)
451 {
452 ScrnInfoPtr pScrn = xf86ScreenToScrn(pDst->drawable.pScreen);
453 RADEONInfoPtr info = RADEONPTR(pScrn);
454 struct radeon_accel_state *accel_state = info->accel_state;
455 struct r600_accel_object src_obj, dst_obj;
456
457 if (!RADEONCheckBPP(pSrc->drawable.bitsPerPixel))
458 RADEON_FALLBACK(("EVERGREENCheckDatatype src failed\n"));
459 if (!RADEONCheckBPP(pDst->drawable.bitsPerPixel))
460 RADEON_FALLBACK(("EVERGREENCheckDatatype dst failed\n"));
461 if (!RADEONValidPM(planemask, pDst->drawable.bitsPerPixel))
462 RADEON_FALLBACK(("Invalid planemask\n"));
463
464 dst_obj.pitch = exaGetPixmapPitch(pDst) / (pDst->drawable.bitsPerPixel / 8);
465 src_obj.pitch = exaGetPixmapPitch(pSrc) / (pSrc->drawable.bitsPerPixel / 8);
466
467 accel_state->same_surface = FALSE;
468
469 src_obj.bo = radeon_get_pixmap_bo(pSrc)->bo.radeon;
470 dst_obj.bo = radeon_get_pixmap_bo(pDst)->bo.radeon;
471 dst_obj.surface = radeon_get_pixmap_surface(pDst);
472 src_obj.surface = radeon_get_pixmap_surface(pSrc);
473 dst_obj.tiling_flags = radeon_get_pixmap_tiling(pDst);
474 src_obj.tiling_flags = radeon_get_pixmap_tiling(pSrc);
475 if (src_obj.bo == dst_obj.bo)
476 accel_state->same_surface = TRUE;
477
478 src_obj.width = pSrc->drawable.width;
479 src_obj.height = pSrc->drawable.height;
480 src_obj.bpp = pSrc->drawable.bitsPerPixel;
481 src_obj.domain = RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT;
482
483 dst_obj.width = pDst->drawable.width;
484 dst_obj.height = pDst->drawable.height;
485 dst_obj.bpp = pDst->drawable.bitsPerPixel;
486 if (radeon_get_pixmap_shared(pDst) == TRUE)
487 dst_obj.domain = RADEON_GEM_DOMAIN_GTT;
488 else
489 dst_obj.domain = RADEON_GEM_DOMAIN_VRAM;
490
491 if (!R600SetAccelState(pScrn,
492 &src_obj,
493 NULL,
494 &dst_obj,
495 accel_state->copy_vs_offset, accel_state->copy_ps_offset,
496 rop, planemask))
497 return FALSE;
498
499 if (accel_state->same_surface == TRUE) {
500 unsigned height = RADEON_ALIGN(pDst->drawable.height,
501 drmmode_get_height_align(pScrn, accel_state->dst_obj.tiling_flags));
502 unsigned long size = height * accel_state->dst_obj.pitch * pDst->drawable.bitsPerPixel/8;
503
504 if (accel_state->dst_obj.surface)
505 size = accel_state->dst_obj.surface->bo_size;
506
507 if (accel_state->copy_area_bo) {
508 radeon_bo_unref(accel_state->copy_area_bo);
509 accel_state->copy_area_bo = NULL;
510 }
511 accel_state->copy_area_bo = radeon_bo_open(info->bufmgr, 0, size, 0,
512 RADEON_GEM_DOMAIN_VRAM,
513 0);
514 if (!accel_state->copy_area_bo)
515 RADEON_FALLBACK(("temp copy surface alloc failed\n"));
516
517 radeon_cs_space_add_persistent_bo(info->cs, accel_state->copy_area_bo,
518 0, RADEON_GEM_DOMAIN_VRAM);
519 if (radeon_cs_space_check(info->cs)) {
520 radeon_bo_unref(accel_state->copy_area_bo);
521 accel_state->copy_area_bo = NULL;
522 return FALSE;
523 }
524 accel_state->copy_area = (void*)accel_state->copy_area_bo;
525 } else
526 EVERGREENDoPrepareCopy(pScrn);
527
528 if (accel_state->vsync)
529 RADEONVlineHelperClear(pScrn);
530
531 accel_state->dst_pix = pDst;
532 accel_state->src_pix = pSrc;
533 accel_state->xdir = xdir;
534 accel_state->ydir = ydir;
535
536 return TRUE;
537 }
538
539 static void
EVERGREENDoneCopy(PixmapPtr pDst)540 EVERGREENDoneCopy(PixmapPtr pDst)
541 {
542 ScrnInfoPtr pScrn = xf86ScreenToScrn(pDst->drawable.pScreen);
543 RADEONInfoPtr info = RADEONPTR(pScrn);
544 struct radeon_accel_state *accel_state = info->accel_state;
545
546 if (!accel_state->same_surface)
547 EVERGREENDoCopyVline(pDst);
548
549 if (accel_state->copy_area)
550 accel_state->copy_area = NULL;
551
552 }
553
554 static void
EVERGREENCopy(PixmapPtr pDst,int srcX,int srcY,int dstX,int dstY,int w,int h)555 EVERGREENCopy(PixmapPtr pDst,
556 int srcX, int srcY,
557 int dstX, int dstY,
558 int w, int h)
559 {
560 ScrnInfoPtr pScrn = xf86ScreenToScrn(pDst->drawable.pScreen);
561 RADEONInfoPtr info = RADEONPTR(pScrn);
562 struct radeon_accel_state *accel_state = info->accel_state;
563
564 if (accel_state->same_surface && (srcX == dstX) && (srcY == dstY))
565 return;
566
567 if (CS_FULL(info->cs)) {
568 EVERGREENDoneCopy(info->accel_state->dst_pix);
569 radeon_cs_flush_indirect(pScrn);
570 EVERGREENPrepareCopy(accel_state->src_pix,
571 accel_state->dst_pix,
572 accel_state->xdir,
573 accel_state->ydir,
574 accel_state->rop,
575 accel_state->planemask);
576 }
577
578 if (accel_state->vsync)
579 RADEONVlineHelperSet(pScrn, dstX, dstY, dstX + w, dstY + h);
580
581 if (accel_state->same_surface &&
582 (srcX + w <= dstX || dstX + w <= srcX || srcY + h <= dstY || dstY + h <= srcY)) {
583 EVERGREENDoPrepareCopy(pScrn);
584 EVERGREENAppendCopyVertex(pScrn, srcX, srcY, dstX, dstY, w, h);
585 EVERGREENDoCopyVline(pDst);
586 } else if (accel_state->same_surface && accel_state->copy_area) {
587 uint32_t orig_dst_domain = accel_state->dst_obj.domain;
588 uint32_t orig_src_domain = accel_state->src_obj[0].domain;
589 uint32_t orig_src_tiling_flags = accel_state->src_obj[0].tiling_flags;
590 uint32_t orig_dst_tiling_flags = accel_state->dst_obj.tiling_flags;
591 struct radeon_bo *orig_bo = accel_state->dst_obj.bo;
592 int orig_rop = accel_state->rop;
593 struct radeon_surface *orig_dst_surface = accel_state->dst_obj.surface;
594 struct radeon_surface *orig_src_surface = accel_state->src_obj[0].surface;
595
596 /* src to tmp */
597 accel_state->dst_obj.domain = RADEON_GEM_DOMAIN_VRAM;
598 accel_state->dst_obj.bo = accel_state->copy_area_bo;
599 accel_state->dst_obj.tiling_flags = 0;
600 accel_state->rop = 3;
601 accel_state->dst_obj.surface = NULL;
602 EVERGREENDoPrepareCopy(pScrn);
603 EVERGREENAppendCopyVertex(pScrn, srcX, srcY, dstX, dstY, w, h);
604 EVERGREENDoCopy(pScrn);
605
606 /* tmp to dst */
607 accel_state->src_obj[0].domain = RADEON_GEM_DOMAIN_VRAM;
608 accel_state->src_obj[0].bo = accel_state->copy_area_bo;
609 accel_state->src_obj[0].tiling_flags = 0;
610 accel_state->src_obj[0].surface = NULL;
611 accel_state->dst_obj.domain = orig_dst_domain;
612 accel_state->dst_obj.bo = orig_bo;
613 accel_state->dst_obj.tiling_flags = orig_dst_tiling_flags;
614 accel_state->rop = orig_rop;
615 accel_state->dst_obj.surface = orig_dst_surface;
616 EVERGREENDoPrepareCopy(pScrn);
617 EVERGREENAppendCopyVertex(pScrn, dstX, dstY, dstX, dstY, w, h);
618 EVERGREENDoCopyVline(pDst);
619
620 /* restore state */
621 accel_state->src_obj[0].domain = orig_src_domain;
622 accel_state->src_obj[0].bo = orig_bo;
623 accel_state->src_obj[0].tiling_flags = orig_src_tiling_flags;
624 accel_state->src_obj[0].surface = orig_src_surface;
625 } else
626 EVERGREENAppendCopyVertex(pScrn, srcX, srcY, dstX, dstY, w, h);
627
628 }
629
630 struct blendinfo {
631 Bool dst_alpha;
632 Bool src_alpha;
633 uint32_t blend_cntl;
634 };
635
636 static struct blendinfo EVERGREENBlendOp[] = {
637 /* Clear */
638 {0, 0, (BLEND_ZERO << COLOR_SRCBLEND_shift) | (BLEND_ZERO << COLOR_DESTBLEND_shift)},
639 /* Src */
640 {0, 0, (BLEND_ONE << COLOR_SRCBLEND_shift) | (BLEND_ZERO << COLOR_DESTBLEND_shift)},
641 /* Dst */
642 {0, 0, (BLEND_ZERO << COLOR_SRCBLEND_shift) | (BLEND_ONE << COLOR_DESTBLEND_shift)},
643 /* Over */
644 {0, 1, (BLEND_ONE << COLOR_SRCBLEND_shift) | (BLEND_ONE_MINUS_SRC_ALPHA << COLOR_DESTBLEND_shift)},
645 /* OverReverse */
646 {1, 0, (BLEND_ONE_MINUS_DST_ALPHA << COLOR_SRCBLEND_shift) | (BLEND_ONE << COLOR_DESTBLEND_shift)},
647 /* In */
648 {1, 0, (BLEND_DST_ALPHA << COLOR_SRCBLEND_shift) | (BLEND_ZERO << COLOR_DESTBLEND_shift)},
649 /* InReverse */
650 {0, 1, (BLEND_ZERO << COLOR_SRCBLEND_shift) | (BLEND_SRC_ALPHA << COLOR_DESTBLEND_shift)},
651 /* Out */
652 {1, 0, (BLEND_ONE_MINUS_DST_ALPHA << COLOR_SRCBLEND_shift) | (BLEND_ZERO << COLOR_DESTBLEND_shift)},
653 /* OutReverse */
654 {0, 1, (BLEND_ZERO << COLOR_SRCBLEND_shift) | (BLEND_ONE_MINUS_SRC_ALPHA << COLOR_DESTBLEND_shift)},
655 /* Atop */
656 {1, 1, (BLEND_DST_ALPHA << COLOR_SRCBLEND_shift) | (BLEND_ONE_MINUS_SRC_ALPHA << COLOR_DESTBLEND_shift)},
657 /* AtopReverse */
658 {1, 1, (BLEND_ONE_MINUS_DST_ALPHA << COLOR_SRCBLEND_shift) | (BLEND_SRC_ALPHA << COLOR_DESTBLEND_shift)},
659 /* Xor */
660 {1, 1, (BLEND_ONE_MINUS_DST_ALPHA << COLOR_SRCBLEND_shift) | (BLEND_ONE_MINUS_SRC_ALPHA << COLOR_DESTBLEND_shift)},
661 /* Add */
662 {0, 0, (BLEND_ONE << COLOR_SRCBLEND_shift) | (BLEND_ONE << COLOR_DESTBLEND_shift)},
663 };
664
665 struct formatinfo {
666 unsigned int fmt;
667 uint32_t card_fmt;
668 };
669
670 static struct formatinfo EVERGREENTexFormats[] = {
671 {PICT_a2r10g10b10, FMT_2_10_10_10},
672 {PICT_x2r10g10b10, FMT_2_10_10_10},
673 {PICT_a2b10g10r10, FMT_2_10_10_10},
674 {PICT_x2b10g10r10, FMT_2_10_10_10},
675 {PICT_a8r8g8b8, FMT_8_8_8_8},
676 {PICT_x8r8g8b8, FMT_8_8_8_8},
677 {PICT_a8b8g8r8, FMT_8_8_8_8},
678 {PICT_x8b8g8r8, FMT_8_8_8_8},
679 {PICT_b8g8r8a8, FMT_8_8_8_8},
680 {PICT_b8g8r8x8, FMT_8_8_8_8},
681 {PICT_r5g6b5, FMT_5_6_5},
682 {PICT_a1r5g5b5, FMT_1_5_5_5},
683 {PICT_x1r5g5b5, FMT_1_5_5_5},
684 {PICT_a8, FMT_8},
685 };
686
EVERGREENGetBlendCntl(int op,PicturePtr pMask,uint32_t dst_format)687 static uint32_t EVERGREENGetBlendCntl(int op, PicturePtr pMask, uint32_t dst_format)
688 {
689 uint32_t sblend, dblend;
690
691 sblend = EVERGREENBlendOp[op].blend_cntl & COLOR_SRCBLEND_mask;
692 dblend = EVERGREENBlendOp[op].blend_cntl & COLOR_DESTBLEND_mask;
693
694 /* If there's no dst alpha channel, adjust the blend op so that we'll treat
695 * it as always 1.
696 */
697 if (PICT_FORMAT_A(dst_format) == 0 && EVERGREENBlendOp[op].dst_alpha) {
698 if (sblend == (BLEND_DST_ALPHA << COLOR_SRCBLEND_shift))
699 sblend = (BLEND_ONE << COLOR_SRCBLEND_shift);
700 else if (sblend == (BLEND_ONE_MINUS_DST_ALPHA << COLOR_SRCBLEND_shift))
701 sblend = (BLEND_ZERO << COLOR_SRCBLEND_shift);
702 }
703
704 /* If the source alpha is being used, then we should only be in a case where
705 * the source blend factor is 0, and the source blend value is the mask
706 * channels multiplied by the source picture's alpha.
707 */
708 if (pMask && pMask->componentAlpha && EVERGREENBlendOp[op].src_alpha) {
709 if (dblend == (BLEND_SRC_ALPHA << COLOR_DESTBLEND_shift)) {
710 dblend = (BLEND_SRC_COLOR << COLOR_DESTBLEND_shift);
711 } else if (dblend == (BLEND_ONE_MINUS_SRC_ALPHA << COLOR_DESTBLEND_shift)) {
712 dblend = (BLEND_ONE_MINUS_SRC_COLOR << COLOR_DESTBLEND_shift);
713 }
714
715 /* With some tricks, we can still accelerate PictOpOver with solid src.
716 * This is commonly used for text rendering, so it's worth the extra
717 * effort.
718 */
719 if (sblend == (BLEND_ONE << COLOR_SRCBLEND_shift)) {
720 sblend = (BLEND_CONSTANT_COLOR << COLOR_SRCBLEND_shift);
721 }
722 }
723
724 return sblend | dblend;
725 }
726
EVERGREENGetDestFormat(PicturePtr pDstPicture,uint32_t * dst_format)727 static Bool EVERGREENGetDestFormat(PicturePtr pDstPicture, uint32_t *dst_format)
728 {
729 switch (pDstPicture->format) {
730 case PICT_a2r10g10b10:
731 case PICT_x2r10g10b10:
732 case PICT_a2b10g10r10:
733 case PICT_x2b10g10r10:
734 *dst_format = COLOR_2_10_10_10;
735 break;
736 case PICT_a8r8g8b8:
737 case PICT_x8r8g8b8:
738 case PICT_a8b8g8r8:
739 case PICT_x8b8g8r8:
740 case PICT_b8g8r8a8:
741 case PICT_b8g8r8x8:
742 *dst_format = COLOR_8_8_8_8;
743 break;
744 case PICT_r5g6b5:
745 *dst_format = COLOR_5_6_5;
746 break;
747 case PICT_a1r5g5b5:
748 case PICT_x1r5g5b5:
749 *dst_format = COLOR_1_5_5_5;
750 break;
751 case PICT_a8:
752 *dst_format = COLOR_8;
753 break;
754 default:
755 RADEON_FALLBACK(("Unsupported dest format 0x%x\n",
756 (int)pDstPicture->format));
757 }
758 return TRUE;
759 }
760
EVERGREENCheckCompositeTexture(PicturePtr pPict,PicturePtr pDstPict,int op,int unit)761 static Bool EVERGREENCheckCompositeTexture(PicturePtr pPict,
762 PicturePtr pDstPict,
763 int op,
764 int unit)
765 {
766 unsigned int repeatType = pPict->repeat ? pPict->repeatType : RepeatNone;
767 unsigned int i;
768
769 for (i = 0; i < sizeof(EVERGREENTexFormats) / sizeof(EVERGREENTexFormats[0]); i++) {
770 if (EVERGREENTexFormats[i].fmt == pPict->format)
771 break;
772 }
773 if (i == sizeof(EVERGREENTexFormats) / sizeof(EVERGREENTexFormats[0]))
774 RADEON_FALLBACK(("Unsupported picture format 0x%x\n",
775 (int)pPict->format));
776
777 if (pPict->filter != PictFilterNearest &&
778 pPict->filter != PictFilterBilinear)
779 RADEON_FALLBACK(("Unsupported filter 0x%x\n", pPict->filter));
780
781 /* for REPEAT_NONE, Render semantics are that sampling outside the source
782 * picture results in alpha=0 pixels. We can implement this with a border color
783 * *if* our source texture has an alpha channel, otherwise we need to fall
784 * back. If we're not transformed then we hope that upper layers have clipped
785 * rendering to the bounds of the source drawable, in which case it doesn't
786 * matter. I have not, however, verified that the X server always does such
787 * clipping.
788 */
789 /* FIXME evergreen */
790 if (pPict->transform != 0 && repeatType == RepeatNone && PICT_FORMAT_A(pPict->format) == 0) {
791 if (!(((op == PictOpSrc) || (op == PictOpClear)) && (PICT_FORMAT_A(pDstPict->format) == 0)))
792 RADEON_FALLBACK(("REPEAT_NONE unsupported for transformed xRGB source\n"));
793 }
794
795 if (!radeon_transform_is_affine_or_scaled(pPict->transform))
796 RADEON_FALLBACK(("non-affine transforms not supported\n"));
797
798 return TRUE;
799 }
800
EVERGREENXFormSetup(PicturePtr pPict,ScrnInfoPtr pScrn,int unit,float * vs_alu_consts)801 static void EVERGREENXFormSetup(PicturePtr pPict, ScrnInfoPtr pScrn,
802 int unit, float *vs_alu_consts)
803 {
804 RADEONInfoPtr info = RADEONPTR(pScrn);
805 struct radeon_accel_state *accel_state = info->accel_state;
806 int const_offset = unit * 8;
807 int w, h;
808
809 if (pPict->pDrawable) {
810 w = pPict->pDrawable->width;
811 h = pPict->pDrawable->height;
812 } else {
813 w = 1;
814 h = 1;
815 }
816
817 if (pPict->transform != 0) {
818 accel_state->is_transform[unit] = TRUE;
819 accel_state->transform[unit] = pPict->transform;
820
821 vs_alu_consts[0 + const_offset] = xFixedToFloat(pPict->transform->matrix[0][0]);
822 vs_alu_consts[1 + const_offset] = xFixedToFloat(pPict->transform->matrix[0][1]);
823 vs_alu_consts[2 + const_offset] = xFixedToFloat(pPict->transform->matrix[0][2]);
824 vs_alu_consts[3 + const_offset] = 1.0 / w;
825
826 vs_alu_consts[4 + const_offset] = xFixedToFloat(pPict->transform->matrix[1][0]);
827 vs_alu_consts[5 + const_offset] = xFixedToFloat(pPict->transform->matrix[1][1]);
828 vs_alu_consts[6 + const_offset] = xFixedToFloat(pPict->transform->matrix[1][2]);
829 vs_alu_consts[7 + const_offset] = 1.0 / h;
830 } else {
831 accel_state->is_transform[unit] = FALSE;
832
833 vs_alu_consts[0 + const_offset] = 1.0;
834 vs_alu_consts[1 + const_offset] = 0.0;
835 vs_alu_consts[2 + const_offset] = 0.0;
836 vs_alu_consts[3 + const_offset] = 1.0 / w;
837
838 vs_alu_consts[4 + const_offset] = 0.0;
839 vs_alu_consts[5 + const_offset] = 1.0;
840 vs_alu_consts[6 + const_offset] = 0.0;
841 vs_alu_consts[7 + const_offset] = 1.0 / h;
842 }
843
844 }
845
EVERGREENTextureSetup(PicturePtr pPict,PixmapPtr pPix,int unit)846 static Bool EVERGREENTextureSetup(PicturePtr pPict, PixmapPtr pPix,
847 int unit)
848 {
849 ScrnInfoPtr pScrn = xf86ScreenToScrn(pPix->drawable.pScreen);
850 RADEONInfoPtr info = RADEONPTR(pScrn);
851 struct radeon_accel_state *accel_state = info->accel_state;
852 unsigned int repeatType;
853 unsigned int i;
854 tex_resource_t tex_res;
855 tex_sampler_t tex_samp;
856 int pix_r, pix_g, pix_b, pix_a;
857
858 CLEAR (tex_res);
859 CLEAR (tex_samp);
860
861 for (i = 0; i < sizeof(EVERGREENTexFormats) / sizeof(EVERGREENTexFormats[0]); i++) {
862 if (EVERGREENTexFormats[i].fmt == pPict->format)
863 break;
864 }
865
866 /* Texture */
867 if (pPict->pDrawable) {
868 tex_res.w = pPict->pDrawable->width;
869 tex_res.h = pPict->pDrawable->height;
870 repeatType = pPict->repeat ? pPict->repeatType : RepeatNone;
871 } else {
872 tex_res.w = 1;
873 tex_res.h = 1;
874 repeatType = RepeatNormal;
875 }
876
877 tex_res.id = unit;
878 tex_res.pitch = accel_state->src_obj[unit].pitch;
879 tex_res.depth = 0;
880 tex_res.dim = SQ_TEX_DIM_2D;
881 tex_res.base = 0;
882 tex_res.mip_base = 0;
883 tex_res.size = accel_state->src_size[unit];
884 tex_res.format = EVERGREENTexFormats[i].card_fmt;
885 tex_res.bo = accel_state->src_obj[unit].bo;
886 tex_res.mip_bo = accel_state->src_obj[unit].bo;
887 tex_res.surface = accel_state->src_obj[unit].surface;
888
889 #if X_BYTE_ORDER == X_BIG_ENDIAN
890 switch (accel_state->src_obj[unit].bpp) {
891 case 16:
892 tex_res.endian = SQ_ENDIAN_8IN16;
893 break;
894 case 32:
895 tex_res.endian = SQ_ENDIAN_8IN32;
896 break;
897 default :
898 break;
899 }
900 #endif
901
902 /* component swizzles */
903 switch (pPict->format) {
904 case PICT_a2r10g10b10:
905 case PICT_a1r5g5b5:
906 case PICT_a8r8g8b8:
907 pix_r = SQ_SEL_Z; /* R */
908 pix_g = SQ_SEL_Y; /* G */
909 pix_b = SQ_SEL_X; /* B */
910 pix_a = SQ_SEL_W; /* A */
911 break;
912 case PICT_a2b10g10r10:
913 case PICT_a8b8g8r8:
914 pix_r = SQ_SEL_X; /* R */
915 pix_g = SQ_SEL_Y; /* G */
916 pix_b = SQ_SEL_Z; /* B */
917 pix_a = SQ_SEL_W; /* A */
918 break;
919 case PICT_x2b10g10r10:
920 case PICT_x8b8g8r8:
921 pix_r = SQ_SEL_X; /* R */
922 pix_g = SQ_SEL_Y; /* G */
923 pix_b = SQ_SEL_Z; /* B */
924 pix_a = SQ_SEL_1; /* A */
925 break;
926 case PICT_b8g8r8a8:
927 pix_r = SQ_SEL_Y; /* R */
928 pix_g = SQ_SEL_Z; /* G */
929 pix_b = SQ_SEL_W; /* B */
930 pix_a = SQ_SEL_X; /* A */
931 break;
932 case PICT_b8g8r8x8:
933 pix_r = SQ_SEL_Y; /* R */
934 pix_g = SQ_SEL_Z; /* G */
935 pix_b = SQ_SEL_W; /* B */
936 pix_a = SQ_SEL_1; /* A */
937 break;
938 case PICT_x2r10g10b10:
939 case PICT_x1r5g5b5:
940 case PICT_x8r8g8b8:
941 case PICT_r5g6b5:
942 pix_r = SQ_SEL_Z; /* R */
943 pix_g = SQ_SEL_Y; /* G */
944 pix_b = SQ_SEL_X; /* B */
945 pix_a = SQ_SEL_1; /* A */
946 break;
947 case PICT_a8:
948 pix_r = SQ_SEL_0; /* R */
949 pix_g = SQ_SEL_0; /* G */
950 pix_b = SQ_SEL_0; /* B */
951 pix_a = SQ_SEL_X; /* A */
952 break;
953 default:
954 RADEON_FALLBACK(("Bad format 0x%x\n", pPict->format));
955 }
956
957 if (unit == 0) {
958 if (!accel_state->msk_pic) {
959 if (PICT_FORMAT_RGB(pPict->format) == 0) {
960 pix_r = SQ_SEL_0;
961 pix_g = SQ_SEL_0;
962 pix_b = SQ_SEL_0;
963 }
964
965 if (PICT_FORMAT_A(pPict->format) == 0)
966 pix_a = SQ_SEL_1;
967 } else {
968 if (accel_state->component_alpha) {
969 if (accel_state->src_alpha) {
970 if (PICT_FORMAT_A(pPict->format) == 0) {
971 pix_r = SQ_SEL_1;
972 pix_g = SQ_SEL_1;
973 pix_b = SQ_SEL_1;
974 pix_a = SQ_SEL_1;
975 } else {
976 pix_r = pix_a;
977 pix_g = pix_a;
978 pix_b = pix_a;
979 }
980 } else {
981 if (PICT_FORMAT_A(pPict->format) == 0)
982 pix_a = SQ_SEL_1;
983 }
984 } else {
985 if (PICT_FORMAT_RGB(pPict->format) == 0) {
986 pix_r = SQ_SEL_0;
987 pix_g = SQ_SEL_0;
988 pix_b = SQ_SEL_0;
989 }
990
991 if (PICT_FORMAT_A(pPict->format) == 0)
992 pix_a = SQ_SEL_1;
993 }
994 }
995 } else {
996 if (accel_state->component_alpha) {
997 if (PICT_FORMAT_A(pPict->format) == 0)
998 pix_a = SQ_SEL_1;
999 } else {
1000 if (PICT_FORMAT_A(pPict->format) == 0) {
1001 pix_r = SQ_SEL_1;
1002 pix_g = SQ_SEL_1;
1003 pix_b = SQ_SEL_1;
1004 pix_a = SQ_SEL_1;
1005 } else {
1006 pix_r = pix_a;
1007 pix_g = pix_a;
1008 pix_b = pix_a;
1009 }
1010 }
1011 }
1012
1013 tex_res.dst_sel_x = pix_r; /* R */
1014 tex_res.dst_sel_y = pix_g; /* G */
1015 tex_res.dst_sel_z = pix_b; /* B */
1016 tex_res.dst_sel_w = pix_a; /* A */
1017
1018 tex_res.base_level = 0;
1019 tex_res.last_level = 0;
1020 tex_res.perf_modulation = 0;
1021 if ((accel_state->src_obj[unit].tiling_flags & RADEON_TILING_MASK) ==
1022 RADEON_TILING_LINEAR)
1023 tex_res.array_mode = 0;
1024 evergreen_set_tex_resource (pScrn, &tex_res, accel_state->src_obj[unit].domain);
1025
1026 tex_samp.id = unit;
1027 tex_samp.border_color = SQ_TEX_BORDER_COLOR_TRANS_BLACK;
1028
1029 switch (repeatType) {
1030 case RepeatNormal:
1031 tex_samp.clamp_x = SQ_TEX_WRAP;
1032 tex_samp.clamp_y = SQ_TEX_WRAP;
1033 break;
1034 case RepeatPad:
1035 tex_samp.clamp_x = SQ_TEX_CLAMP_LAST_TEXEL;
1036 tex_samp.clamp_y = SQ_TEX_CLAMP_LAST_TEXEL;
1037 break;
1038 case RepeatReflect:
1039 tex_samp.clamp_x = SQ_TEX_MIRROR;
1040 tex_samp.clamp_y = SQ_TEX_MIRROR;
1041 break;
1042 case RepeatNone:
1043 tex_samp.clamp_x = SQ_TEX_CLAMP_BORDER;
1044 tex_samp.clamp_y = SQ_TEX_CLAMP_BORDER;
1045 break;
1046 default:
1047 RADEON_FALLBACK(("Bad repeat 0x%x\n", repeatType));
1048 }
1049
1050 switch (pPict->filter) {
1051 case PictFilterNearest:
1052 tex_samp.xy_mag_filter = SQ_TEX_XY_FILTER_POINT;
1053 tex_samp.xy_min_filter = SQ_TEX_XY_FILTER_POINT;
1054 tex_samp.mc_coord_truncate = 1;
1055 break;
1056 case PictFilterBilinear:
1057 tex_samp.xy_mag_filter = SQ_TEX_XY_FILTER_BILINEAR;
1058 tex_samp.xy_min_filter = SQ_TEX_XY_FILTER_BILINEAR;
1059 break;
1060 default:
1061 RADEON_FALLBACK(("Bad filter 0x%x\n", pPict->filter));
1062 }
1063
1064 tex_samp.clamp_z = SQ_TEX_WRAP;
1065 tex_samp.z_filter = SQ_TEX_Z_FILTER_NONE;
1066 tex_samp.mip_filter = 0; /* no mipmap */
1067 evergreen_set_tex_sampler (pScrn, &tex_samp);
1068
1069 return TRUE;
1070 }
1071
EVERGREENCheckComposite(int op,PicturePtr pSrcPicture,PicturePtr pMaskPicture,PicturePtr pDstPicture)1072 static Bool EVERGREENCheckComposite(int op, PicturePtr pSrcPicture,
1073 PicturePtr pMaskPicture,
1074 PicturePtr pDstPicture)
1075 {
1076 uint32_t tmp1;
1077 PixmapPtr pSrcPixmap, pDstPixmap;
1078
1079 /* Check for unsupported compositing operations. */
1080 if (op >= (int) (sizeof(EVERGREENBlendOp) / sizeof(EVERGREENBlendOp[0])))
1081 RADEON_FALLBACK(("Unsupported Composite op 0x%x\n", op));
1082
1083 if (pSrcPicture->pDrawable) {
1084 pSrcPixmap = RADEONGetDrawablePixmap(pSrcPicture->pDrawable);
1085
1086 if (pSrcPixmap->drawable.width >= 16384 ||
1087 pSrcPixmap->drawable.height >= 16384) {
1088 RADEON_FALLBACK(("Source w/h too large (%d,%d).\n",
1089 pSrcPixmap->drawable.width,
1090 pSrcPixmap->drawable.height));
1091 }
1092
1093 if (!EVERGREENCheckCompositeTexture(pSrcPicture, pDstPicture, op, 0))
1094 return FALSE;
1095 } else if (pSrcPicture->pSourcePict->type != SourcePictTypeSolidFill)
1096 RADEON_FALLBACK(("Gradient pictures not supported yet\n"));
1097
1098 pDstPixmap = RADEONGetDrawablePixmap(pDstPicture->pDrawable);
1099
1100 if (pDstPixmap->drawable.width >= 16384 ||
1101 pDstPixmap->drawable.height >= 16384) {
1102 RADEON_FALLBACK(("Dest w/h too large (%d,%d).\n",
1103 pDstPixmap->drawable.width,
1104 pDstPixmap->drawable.height));
1105 }
1106
1107 if (pMaskPicture) {
1108 PixmapPtr pMaskPixmap;
1109
1110 if (pMaskPicture->pDrawable) {
1111 pMaskPixmap = RADEONGetDrawablePixmap(pMaskPicture->pDrawable);
1112
1113 if (pMaskPixmap->drawable.width >= 16384 ||
1114 pMaskPixmap->drawable.height >= 16384) {
1115 RADEON_FALLBACK(("Mask w/h too large (%d,%d).\n",
1116 pMaskPixmap->drawable.width,
1117 pMaskPixmap->drawable.height));
1118 }
1119
1120 if (pMaskPicture->componentAlpha) {
1121 /* Check if it's component alpha that relies on a source alpha and
1122 * on the source value. We can only get one of those into the
1123 * single source value that we get to blend with.
1124 *
1125 * We can cheat a bit if the src is solid, though. PictOpOver
1126 * can use the constant blend color to sneak a second blend
1127 * source in.
1128 */
1129 if (EVERGREENBlendOp[op].src_alpha &&
1130 (EVERGREENBlendOp[op].blend_cntl & COLOR_SRCBLEND_mask) !=
1131 (BLEND_ZERO << COLOR_SRCBLEND_shift)) {
1132 if (pSrcPicture->pDrawable || op != PictOpOver)
1133 RADEON_FALLBACK(("Component alpha not supported with source "
1134 "alpha and source value blending.\n"));
1135 }
1136 }
1137
1138 if (!EVERGREENCheckCompositeTexture(pMaskPicture, pDstPicture, op, 1))
1139 return FALSE;
1140 } else if (pMaskPicture->pSourcePict->type != SourcePictTypeSolidFill)
1141 RADEON_FALLBACK(("Gradient pictures not supported yet\n"));
1142 }
1143
1144 if (!EVERGREENGetDestFormat(pDstPicture, &tmp1))
1145 return FALSE;
1146
1147 return TRUE;
1148
1149 }
1150
EVERGREENSetSolidConsts(ScrnInfoPtr pScrn,float * buf,int format,uint32_t fg,int unit)1151 static void EVERGREENSetSolidConsts(ScrnInfoPtr pScrn, float *buf, int format, uint32_t fg, int unit)
1152 {
1153 RADEONInfoPtr info = RADEONPTR(pScrn);
1154 struct radeon_accel_state *accel_state = info->accel_state;
1155 float pix_r = 0, pix_g = 0, pix_b = 0, pix_a = 0;
1156
1157 uint32_t w = (fg >> 24) & 0xff;
1158 uint32_t z = (fg >> 16) & 0xff;
1159 uint32_t y = (fg >> 8) & 0xff;
1160 uint32_t x = (fg >> 0) & 0xff;
1161 float xf = (float)x / 255; /* R */
1162 float yf = (float)y / 255; /* G */
1163 float zf = (float)z / 255; /* B */
1164 float wf = (float)w / 255; /* A */
1165
1166 /* component swizzles */
1167 switch (format) {
1168 case PICT_a1r5g5b5:
1169 case PICT_a8r8g8b8:
1170 pix_r = zf; /* R */
1171 pix_g = yf; /* G */
1172 pix_b = xf; /* B */
1173 pix_a = wf; /* A */
1174 break;
1175 case PICT_a8b8g8r8:
1176 pix_r = xf; /* R */
1177 pix_g = yf; /* G */
1178 pix_b = zf; /* B */
1179 pix_a = wf; /* A */
1180 break;
1181 case PICT_x8b8g8r8:
1182 pix_r = xf; /* R */
1183 pix_g = yf; /* G */
1184 pix_b = zf; /* B */
1185 pix_a = 1.0; /* A */
1186 break;
1187 case PICT_b8g8r8a8:
1188 pix_r = yf; /* R */
1189 pix_g = zf; /* G */
1190 pix_b = wf; /* B */
1191 pix_a = xf; /* A */
1192 break;
1193 case PICT_b8g8r8x8:
1194 pix_r = yf; /* R */
1195 pix_g = zf; /* G */
1196 pix_b = wf; /* B */
1197 pix_a = 1.0; /* A */
1198 break;
1199 case PICT_x1r5g5b5:
1200 case PICT_x8r8g8b8:
1201 case PICT_r5g6b5:
1202 pix_r = zf; /* R */
1203 pix_g = yf; /* G */
1204 pix_b = xf; /* B */
1205 pix_a = 1.0; /* A */
1206 break;
1207 case PICT_a8:
1208 pix_r = 0.0; /* R */
1209 pix_g = 0.0; /* G */
1210 pix_b = 0.0; /* B */
1211 pix_a = xf; /* A */
1212 break;
1213 default:
1214 ErrorF("Bad format 0x%x\n", format);
1215 }
1216
1217 if (unit == 0) {
1218 if (!accel_state->msk_pic) {
1219 if (PICT_FORMAT_RGB(format) == 0) {
1220 pix_r = 0.0;
1221 pix_g = 0.0;
1222 pix_b = 0.0;
1223 }
1224
1225 if (PICT_FORMAT_A(format) == 0)
1226 pix_a = 1.0;
1227 } else {
1228 if (accel_state->component_alpha) {
1229 if (accel_state->src_alpha) {
1230 /* required for PictOpOver */
1231 float cblend[4] = { pix_r / pix_a, pix_g / pix_a,
1232 pix_b / pix_a, pix_a / pix_a };
1233 evergreen_set_blend_color(pScrn, cblend);
1234
1235 if (PICT_FORMAT_A(format) == 0) {
1236 pix_r = 1.0;
1237 pix_g = 1.0;
1238 pix_b = 1.0;
1239 pix_a = 1.0;
1240 } else {
1241 pix_r = pix_a;
1242 pix_g = pix_a;
1243 pix_b = pix_a;
1244 }
1245 } else {
1246 if (PICT_FORMAT_A(format) == 0)
1247 pix_a = 1.0;
1248 }
1249 } else {
1250 if (PICT_FORMAT_RGB(format) == 0) {
1251 pix_r = 0;
1252 pix_g = 0;
1253 pix_b = 0;
1254 }
1255
1256 if (PICT_FORMAT_A(format) == 0)
1257 pix_a = 1.0;
1258 }
1259 }
1260 } else {
1261 if (accel_state->component_alpha) {
1262 if (PICT_FORMAT_A(format) == 0)
1263 pix_a = 1.0;
1264 } else {
1265 if (PICT_FORMAT_A(format) == 0) {
1266 pix_r = 1.0;
1267 pix_g = 1.0;
1268 pix_b = 1.0;
1269 pix_a = 1.0;
1270 } else {
1271 pix_r = pix_a;
1272 pix_g = pix_a;
1273 pix_b = pix_a;
1274 }
1275 }
1276 }
1277
1278 buf[0] = pix_r;
1279 buf[1] = pix_g;
1280 buf[2] = pix_b;
1281 buf[3] = pix_a;
1282 }
1283
EVERGREENPrepareComposite(int op,PicturePtr pSrcPicture,PicturePtr pMaskPicture,PicturePtr pDstPicture,PixmapPtr pSrc,PixmapPtr pMask,PixmapPtr pDst)1284 static Bool EVERGREENPrepareComposite(int op, PicturePtr pSrcPicture,
1285 PicturePtr pMaskPicture, PicturePtr pDstPicture,
1286 PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
1287 {
1288 ScreenPtr pScreen = pDst->drawable.pScreen;
1289 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
1290 RADEONInfoPtr info = RADEONPTR(pScrn);
1291 struct radeon_accel_state *accel_state = info->accel_state;
1292 uint32_t dst_format;
1293 cb_config_t cb_conf;
1294 shader_config_t vs_conf, ps_conf;
1295 const_config_t vs_const_conf;
1296 struct r600_accel_object src_obj, mask_obj, dst_obj;
1297 float *cbuf;
1298 uint32_t ps_bool_consts = 0;
1299
1300 if (pDst->drawable.bitsPerPixel < 8 || (pSrc && pSrc->drawable.bitsPerPixel < 8))
1301 return FALSE;
1302
1303 if (pSrc) {
1304 src_obj.bo = radeon_get_pixmap_bo(pSrc)->bo.radeon;
1305 src_obj.surface = radeon_get_pixmap_surface(pSrc);
1306 src_obj.tiling_flags = radeon_get_pixmap_tiling(pSrc);
1307 src_obj.pitch = exaGetPixmapPitch(pSrc) / (pSrc->drawable.bitsPerPixel / 8);
1308 src_obj.width = pSrc->drawable.width;
1309 src_obj.height = pSrc->drawable.height;
1310 src_obj.bpp = pSrc->drawable.bitsPerPixel;
1311 src_obj.domain = RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT;
1312 }
1313
1314 dst_obj.bo = radeon_get_pixmap_bo(pDst)->bo.radeon;
1315 dst_obj.surface = radeon_get_pixmap_surface(pDst);
1316 dst_obj.tiling_flags = radeon_get_pixmap_tiling(pDst);
1317 dst_obj.pitch = exaGetPixmapPitch(pDst) / (pDst->drawable.bitsPerPixel / 8);
1318 dst_obj.width = pDst->drawable.width;
1319 dst_obj.height = pDst->drawable.height;
1320 dst_obj.bpp = pDst->drawable.bitsPerPixel;
1321 if (radeon_get_pixmap_shared(pDst) == TRUE)
1322 dst_obj.domain = RADEON_GEM_DOMAIN_GTT;
1323 else
1324 dst_obj.domain = RADEON_GEM_DOMAIN_VRAM;
1325
1326 if (pMaskPicture) {
1327 if (pMask) {
1328 mask_obj.bo = radeon_get_pixmap_bo(pMask)->bo.radeon;
1329 mask_obj.tiling_flags = radeon_get_pixmap_tiling(pMask);
1330 mask_obj.pitch = exaGetPixmapPitch(pMask) / (pMask->drawable.bitsPerPixel / 8);
1331 mask_obj.surface = radeon_get_pixmap_surface(pMask);
1332 mask_obj.width = pMask->drawable.width;
1333 mask_obj.height = pMask->drawable.height;
1334 mask_obj.bpp = pMask->drawable.bitsPerPixel;
1335 mask_obj.domain = RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT;
1336 }
1337
1338 accel_state->msk_pic = pMaskPicture;
1339 if (pMaskPicture->componentAlpha) {
1340 accel_state->component_alpha = TRUE;
1341 if (EVERGREENBlendOp[op].src_alpha)
1342 accel_state->src_alpha = TRUE;
1343 else
1344 accel_state->src_alpha = FALSE;
1345 } else {
1346 accel_state->component_alpha = FALSE;
1347 accel_state->src_alpha = FALSE;
1348 }
1349 } else {
1350 accel_state->msk_pic = NULL;
1351 accel_state->component_alpha = FALSE;
1352 accel_state->src_alpha = FALSE;
1353 }
1354
1355 if (!R600SetAccelState(pScrn,
1356 pSrc ? &src_obj : NULL,
1357 (pMaskPicture && pMask) ? &mask_obj : NULL,
1358 &dst_obj,
1359 accel_state->comp_vs_offset, accel_state->comp_ps_offset,
1360 3, 0xffffffff))
1361 return FALSE;
1362
1363 if (!EVERGREENGetDestFormat(pDstPicture, &dst_format))
1364 return FALSE;
1365
1366 CLEAR (cb_conf);
1367 CLEAR (vs_conf);
1368 CLEAR (ps_conf);
1369 CLEAR (vs_const_conf);
1370
1371 if (pMask)
1372 radeon_vbo_check(pScrn, &accel_state->vbo, 24);
1373 else
1374 radeon_vbo_check(pScrn, &accel_state->vbo, 16);
1375
1376 radeon_vbo_check(pScrn, &accel_state->cbuf, 256);
1377
1378 radeon_cp_start(pScrn);
1379
1380 evergreen_set_default_state(pScrn);
1381
1382 evergreen_set_generic_scissor(pScrn, 0, 0, accel_state->dst_obj.width, accel_state->dst_obj.height);
1383 evergreen_set_screen_scissor(pScrn, 0, 0, accel_state->dst_obj.width, accel_state->dst_obj.height);
1384 evergreen_set_window_scissor(pScrn, 0, 0, accel_state->dst_obj.width, accel_state->dst_obj.height);
1385
1386 if (pSrc) {
1387 if (!EVERGREENTextureSetup(pSrcPicture, pSrc, 0)) {
1388 radeon_ib_discard(pScrn);
1389 radeon_cs_flush_indirect(pScrn);
1390 return FALSE;
1391 }
1392 } else
1393 accel_state->is_transform[0] = FALSE;
1394
1395 if (pMask) {
1396 if (!EVERGREENTextureSetup(pMaskPicture, pMask, 1)) {
1397 radeon_ib_discard(pScrn);
1398 radeon_cs_flush_indirect(pScrn);
1399 return FALSE;
1400 }
1401 } else
1402 accel_state->is_transform[1] = FALSE;
1403
1404 if (pSrc)
1405 ps_bool_consts |= (1 << 0);
1406 if (pMask)
1407 ps_bool_consts |= (1 << 1);
1408 evergreen_set_bool_consts(pScrn, SQ_BOOL_CONST_ps, ps_bool_consts);
1409
1410 if (pMask) {
1411 evergreen_set_bool_consts(pScrn, SQ_BOOL_CONST_vs, (1 << 0));
1412 } else {
1413 evergreen_set_bool_consts(pScrn, SQ_BOOL_CONST_vs, (0 << 0));
1414 }
1415
1416 /* Shader */
1417 vs_conf.shader_addr = accel_state->vs_mc_addr;
1418 vs_conf.shader_size = accel_state->vs_size;
1419 vs_conf.num_gprs = 5;
1420 vs_conf.stack_size = 1;
1421 vs_conf.bo = accel_state->shaders_bo;
1422 evergreen_vs_setup(pScrn, &vs_conf, RADEON_GEM_DOMAIN_VRAM);
1423
1424 ps_conf.shader_addr = accel_state->ps_mc_addr;
1425 ps_conf.shader_size = accel_state->ps_size;
1426 ps_conf.num_gprs = 2;
1427 ps_conf.stack_size = 1;
1428 ps_conf.clamp_consts = 0;
1429 ps_conf.export_mode = 2;
1430 ps_conf.bo = accel_state->shaders_bo;
1431 evergreen_ps_setup(pScrn, &ps_conf, RADEON_GEM_DOMAIN_VRAM);
1432
1433 cb_conf.id = 0;
1434 cb_conf.w = accel_state->dst_obj.pitch;
1435 cb_conf.h = accel_state->dst_obj.height;
1436 cb_conf.base = 0;
1437 cb_conf.format = dst_format;
1438 cb_conf.bo = accel_state->dst_obj.bo;
1439 cb_conf.surface = accel_state->dst_obj.surface;
1440
1441 switch (pDstPicture->format) {
1442 case PICT_a2r10g10b10:
1443 case PICT_x2r10g10b10:
1444 case PICT_a8r8g8b8:
1445 case PICT_x8r8g8b8:
1446 case PICT_a1r5g5b5:
1447 case PICT_x1r5g5b5:
1448 default:
1449 cb_conf.comp_swap = 1; /* ARGB */
1450 break;
1451 case PICT_a2b10g10r10:
1452 case PICT_x2b10g10r10:
1453 case PICT_a8b8g8r8:
1454 case PICT_x8b8g8r8:
1455 cb_conf.comp_swap = 0; /* ABGR */
1456 break;
1457 case PICT_b8g8r8a8:
1458 case PICT_b8g8r8x8:
1459 cb_conf.comp_swap = 3; /* BGRA */
1460 break;
1461 case PICT_r5g6b5:
1462 cb_conf.comp_swap = 2; /* RGB */
1463 break;
1464 case PICT_a8:
1465 cb_conf.comp_swap = 3; /* A */
1466 break;
1467 }
1468 cb_conf.source_format = EXPORT_4C_16BPC;
1469 cb_conf.blend_clamp = 1;
1470 cb_conf.blendcntl = EVERGREENGetBlendCntl(op, pMaskPicture, pDstPicture->format);
1471 cb_conf.blendcntl |= CB_BLEND0_CONTROL__ENABLE_bit;
1472 cb_conf.rop = 3;
1473 cb_conf.pmask = 0xf;
1474 if ((accel_state->dst_obj.tiling_flags & RADEON_TILING_MASK) ==
1475 RADEON_TILING_LINEAR) {
1476 cb_conf.array_mode = 0;
1477 cb_conf.non_disp_tiling = 1;
1478 }
1479 #if X_BYTE_ORDER == X_BIG_ENDIAN
1480 switch (dst_obj.bpp) {
1481 case 16:
1482 cb_conf.endian = ENDIAN_8IN16;
1483 break;
1484 case 32:
1485 cb_conf.endian = ENDIAN_8IN32;
1486 break;
1487 default:
1488 break;
1489 }
1490 #endif
1491 evergreen_set_render_target(pScrn, &cb_conf, accel_state->dst_obj.domain);
1492
1493 if (pMask)
1494 evergreen_set_spi(pScrn, (2 - 1), 2);
1495 else
1496 evergreen_set_spi(pScrn, (1 - 1), 1);
1497
1498 /* VS alu constants */
1499 vs_const_conf.size_bytes = 256;
1500 vs_const_conf.type = SHADER_TYPE_VS;
1501 cbuf = radeon_vbo_space(pScrn, &accel_state->cbuf, 256);
1502 vs_const_conf.bo = accel_state->cbuf.vb_bo;
1503 vs_const_conf.const_addr = accel_state->cbuf.vb_offset;
1504
1505 vs_const_conf.cpu_ptr = (uint32_t *)(char *)cbuf;
1506 EVERGREENXFormSetup(pSrcPicture, pScrn, 0, cbuf);
1507 if (pMask)
1508 EVERGREENXFormSetup(pMaskPicture, pScrn, 1, cbuf);
1509
1510 if (!pSrc) {
1511 /* solid src color */
1512 EVERGREENSetSolidConsts(pScrn, &cbuf[16], pSrcPicture->format,
1513 pSrcPicture->pSourcePict->solidFill.color, 0);
1514 }
1515
1516 if (!pMaskPicture) {
1517 /* use identity constant if there is no mask */
1518 cbuf[20] = 1.0;
1519 cbuf[21] = 1.0;
1520 cbuf[22] = 1.0;
1521 cbuf[23] = 1.0;
1522 } else if (!pMask) {
1523 /* solid mask color */
1524 EVERGREENSetSolidConsts(pScrn, &cbuf[20], pMaskPicture->format,
1525 pMaskPicture->pSourcePict->solidFill.color, 1);
1526 }
1527
1528 radeon_vbo_commit(pScrn, &accel_state->cbuf);
1529 evergreen_set_alu_consts(pScrn, &vs_const_conf, RADEON_GEM_DOMAIN_GTT);
1530
1531 if (accel_state->vsync)
1532 RADEONVlineHelperClear(pScrn);
1533
1534 accel_state->composite_op = op;
1535 accel_state->dst_pic = pDstPicture;
1536 accel_state->src_pic = pSrcPicture;
1537 accel_state->dst_pix = pDst;
1538 accel_state->msk_pix = pMask;
1539 accel_state->src_pix = pSrc;
1540
1541 return TRUE;
1542 }
1543
EVERGREENFinishComposite(ScrnInfoPtr pScrn,PixmapPtr pDst,struct radeon_accel_state * accel_state)1544 static void EVERGREENFinishComposite(ScrnInfoPtr pScrn, PixmapPtr pDst,
1545 struct radeon_accel_state *accel_state)
1546 {
1547 int vtx_size;
1548
1549 if (accel_state->vsync)
1550 evergreen_cp_wait_vline_sync(pScrn, pDst,
1551 accel_state->vline_crtc,
1552 accel_state->vline_y1,
1553 accel_state->vline_y2);
1554
1555 vtx_size = accel_state->msk_pix ? 24 : 16;
1556
1557 evergreen_finish_op(pScrn, vtx_size);
1558 }
1559
EVERGREENDoneComposite(PixmapPtr pDst)1560 static void EVERGREENDoneComposite(PixmapPtr pDst)
1561 {
1562 ScreenPtr pScreen = pDst->drawable.pScreen;
1563 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
1564 RADEONInfoPtr info = RADEONPTR(pScrn);
1565 struct radeon_accel_state *accel_state = info->accel_state;
1566
1567 EVERGREENFinishComposite(pScrn, pDst, accel_state);
1568 }
1569
EVERGREENComposite(PixmapPtr pDst,int srcX,int srcY,int maskX,int maskY,int dstX,int dstY,int w,int h)1570 static void EVERGREENComposite(PixmapPtr pDst,
1571 int srcX, int srcY,
1572 int maskX, int maskY,
1573 int dstX, int dstY,
1574 int w, int h)
1575 {
1576 ScrnInfoPtr pScrn = xf86ScreenToScrn(pDst->drawable.pScreen);
1577 RADEONInfoPtr info = RADEONPTR(pScrn);
1578 struct radeon_accel_state *accel_state = info->accel_state;
1579 float *vb;
1580
1581 if (CS_FULL(info->cs)) {
1582 EVERGREENFinishComposite(pScrn, pDst, info->accel_state);
1583 radeon_cs_flush_indirect(pScrn);
1584 EVERGREENPrepareComposite(info->accel_state->composite_op,
1585 info->accel_state->src_pic,
1586 info->accel_state->msk_pic,
1587 info->accel_state->dst_pic,
1588 info->accel_state->src_pix,
1589 info->accel_state->msk_pix,
1590 info->accel_state->dst_pix);
1591 }
1592
1593 if (accel_state->vsync)
1594 RADEONVlineHelperSet(pScrn, dstX, dstY, dstX + w, dstY + h);
1595
1596 if (accel_state->msk_pix) {
1597
1598 vb = radeon_vbo_space(pScrn, &accel_state->vbo, 24);
1599
1600 vb[0] = (float)dstX;
1601 vb[1] = (float)dstY;
1602 vb[2] = (float)srcX;
1603 vb[3] = (float)srcY;
1604 vb[4] = (float)maskX;
1605 vb[5] = (float)maskY;
1606
1607 vb[6] = (float)dstX;
1608 vb[7] = (float)(dstY + h);
1609 vb[8] = (float)srcX;
1610 vb[9] = (float)(srcY + h);
1611 vb[10] = (float)maskX;
1612 vb[11] = (float)(maskY + h);
1613
1614 vb[12] = (float)(dstX + w);
1615 vb[13] = (float)(dstY + h);
1616 vb[14] = (float)(srcX + w);
1617 vb[15] = (float)(srcY + h);
1618 vb[16] = (float)(maskX + w);
1619 vb[17] = (float)(maskY + h);
1620
1621 radeon_vbo_commit(pScrn, &accel_state->vbo);
1622
1623 } else {
1624
1625 vb = radeon_vbo_space(pScrn, &accel_state->vbo, 16);
1626
1627 vb[0] = (float)dstX;
1628 vb[1] = (float)dstY;
1629 vb[2] = (float)srcX;
1630 vb[3] = (float)srcY;
1631
1632 vb[4] = (float)dstX;
1633 vb[5] = (float)(dstY + h);
1634 vb[6] = (float)srcX;
1635 vb[7] = (float)(srcY + h);
1636
1637 vb[8] = (float)(dstX + w);
1638 vb[9] = (float)(dstY + h);
1639 vb[10] = (float)(srcX + w);
1640 vb[11] = (float)(srcY + h);
1641
1642 radeon_vbo_commit(pScrn, &accel_state->vbo);
1643 }
1644
1645
1646 }
1647
1648 static Bool
EVERGREENUploadToScreen(PixmapPtr pDst,int x,int y,int w,int h,char * src,int src_pitch)1649 EVERGREENUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h,
1650 char *src, int src_pitch)
1651 {
1652 ScrnInfoPtr pScrn = xf86ScreenToScrn(pDst->drawable.pScreen);
1653 RADEONInfoPtr info = RADEONPTR(pScrn);
1654 struct radeon_accel_state *accel_state = info->accel_state;
1655 struct radeon_exa_pixmap_priv *driver_priv;
1656 struct radeon_bo *scratch = NULL;
1657 struct radeon_bo *copy_dst;
1658 unsigned char *dst;
1659 unsigned size;
1660 uint32_t dst_domain;
1661 int bpp = pDst->drawable.bitsPerPixel;
1662 uint32_t scratch_pitch;
1663 uint32_t copy_pitch;
1664 uint32_t dst_pitch_hw = exaGetPixmapPitch(pDst) / (bpp / 8);
1665 int ret;
1666 Bool flush = TRUE;
1667 Bool r;
1668 int i;
1669 struct r600_accel_object src_obj, dst_obj;
1670 uint32_t height, base_align;
1671
1672 if (bpp < 8)
1673 return FALSE;
1674
1675 driver_priv = exaGetPixmapDriverPrivate(pDst);
1676 if (!driver_priv || !driver_priv->bo->bo.radeon)
1677 return FALSE;
1678
1679 /* If we know the BO won't be busy / in VRAM, don't bother with a scratch */
1680 copy_dst = driver_priv->bo->bo.radeon;
1681 copy_pitch = pDst->devKind;
1682 if (!(driver_priv->tiling_flags & (RADEON_TILING_MACRO | RADEON_TILING_MICRO))) {
1683 if (!radeon_bo_is_referenced_by_cs(driver_priv->bo->bo.radeon, info->cs)) {
1684 flush = FALSE;
1685 if (!radeon_bo_is_busy(driver_priv->bo->bo.radeon, &dst_domain) &&
1686 !(dst_domain & RADEON_GEM_DOMAIN_VRAM))
1687 goto copy;
1688 }
1689 }
1690
1691 scratch_pitch = RADEON_ALIGN(w, drmmode_get_pitch_align(pScrn, (bpp / 8), 0));
1692 height = RADEON_ALIGN(h, drmmode_get_height_align(pScrn, 0));
1693 base_align = drmmode_get_base_align(pScrn, (bpp / 8), 0);
1694 size = scratch_pitch * height * (bpp / 8);
1695 scratch = radeon_bo_open(info->bufmgr, 0, size, base_align, RADEON_GEM_DOMAIN_GTT, 0);
1696 if (!scratch) {
1697 goto copy;
1698 }
1699
1700 src_obj.pitch = scratch_pitch;
1701 src_obj.width = w;
1702 src_obj.height = h;
1703 src_obj.bpp = bpp;
1704 src_obj.domain = RADEON_GEM_DOMAIN_GTT;
1705 src_obj.bo = scratch;
1706 src_obj.tiling_flags = 0;
1707 src_obj.surface = NULL;
1708
1709 dst_obj.pitch = dst_pitch_hw;
1710 dst_obj.width = pDst->drawable.width;
1711 dst_obj.height = pDst->drawable.height;
1712 dst_obj.bpp = bpp;
1713 dst_obj.domain = RADEON_GEM_DOMAIN_VRAM;
1714 dst_obj.bo = radeon_get_pixmap_bo(pDst)->bo.radeon;
1715 dst_obj.tiling_flags = radeon_get_pixmap_tiling(pDst);
1716 dst_obj.surface = radeon_get_pixmap_surface(pDst);
1717
1718 if (!R600SetAccelState(pScrn,
1719 &src_obj,
1720 NULL,
1721 &dst_obj,
1722 accel_state->copy_vs_offset, accel_state->copy_ps_offset,
1723 3, 0xffffffff)) {
1724 goto copy;
1725 }
1726 copy_dst = scratch;
1727 copy_pitch = scratch_pitch * (bpp / 8);
1728 flush = FALSE;
1729
1730 copy:
1731 if (flush)
1732 radeon_cs_flush_indirect(pScrn);
1733
1734 ret = radeon_bo_map(copy_dst, 0);
1735 if (ret) {
1736 r = FALSE;
1737 goto out;
1738 }
1739 r = TRUE;
1740 size = w * bpp / 8;
1741 dst = copy_dst->ptr;
1742 if (copy_dst == driver_priv->bo->bo.radeon)
1743 dst += y * copy_pitch + x * bpp / 8;
1744 for (i = 0; i < h; i++) {
1745 memcpy(dst + i * copy_pitch, src, size);
1746 src += src_pitch;
1747 }
1748 radeon_bo_unmap(copy_dst);
1749
1750 if (copy_dst == scratch) {
1751 if (info->accel_state->vsync)
1752 RADEONVlineHelperSet(pScrn, x, y, x + w, y + h);
1753
1754 /* blit from gart to vram */
1755 EVERGREENDoPrepareCopy(pScrn);
1756 EVERGREENAppendCopyVertex(pScrn, 0, 0, x, y, w, h);
1757 EVERGREENDoCopyVline(pDst);
1758 }
1759
1760 out:
1761 if (scratch)
1762 radeon_bo_unref(scratch);
1763 return r;
1764 }
1765
1766 static Bool
EVERGREENDownloadFromScreen(PixmapPtr pSrc,int x,int y,int w,int h,char * dst,int dst_pitch)1767 EVERGREENDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w,
1768 int h, char *dst, int dst_pitch)
1769 {
1770 ScrnInfoPtr pScrn = xf86ScreenToScrn(pSrc->drawable.pScreen);
1771 RADEONInfoPtr info = RADEONPTR(pScrn);
1772 struct radeon_accel_state *accel_state = info->accel_state;
1773 struct radeon_exa_pixmap_priv *driver_priv;
1774 struct radeon_bo *scratch = NULL;
1775 struct radeon_bo *copy_src;
1776 unsigned size;
1777 uint32_t src_domain = 0;
1778 int bpp = pSrc->drawable.bitsPerPixel;
1779 uint32_t scratch_pitch;
1780 uint32_t copy_pitch;
1781 uint32_t src_pitch_hw = exaGetPixmapPitch(pSrc) / (bpp / 8);
1782 int ret;
1783 Bool flush = FALSE;
1784 Bool r;
1785 struct r600_accel_object src_obj, dst_obj;
1786 uint32_t height, base_align;
1787
1788 if (bpp < 8)
1789 return FALSE;
1790
1791 driver_priv = exaGetPixmapDriverPrivate(pSrc);
1792 if (!driver_priv || !driver_priv->bo->bo.radeon)
1793 return FALSE;
1794
1795 /* If we know the BO won't end up in VRAM anyway, don't bother with a scratch */
1796 copy_src = driver_priv->bo->bo.radeon;
1797 copy_pitch = pSrc->devKind;
1798 if (!(driver_priv->tiling_flags & (RADEON_TILING_MACRO | RADEON_TILING_MICRO))) {
1799 if (radeon_bo_is_referenced_by_cs(driver_priv->bo->bo.radeon, info->cs)) {
1800 src_domain = radeon_bo_get_src_domain(driver_priv->bo->bo.radeon);
1801 if ((src_domain & (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM)) ==
1802 (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM))
1803 src_domain = 0;
1804 else /* A write may be scheduled */
1805 flush = TRUE;
1806 }
1807
1808 if (!src_domain)
1809 radeon_bo_is_busy(driver_priv->bo->bo.radeon, &src_domain);
1810
1811 if (src_domain & ~(uint32_t)RADEON_GEM_DOMAIN_VRAM)
1812 goto copy;
1813
1814 }
1815
1816 if (!accel_state->allowHWDFS)
1817 goto copy;
1818
1819 scratch_pitch = RADEON_ALIGN(w, drmmode_get_pitch_align(pScrn, (bpp / 8), 0));
1820 height = RADEON_ALIGN(h, drmmode_get_height_align(pScrn, 0));
1821 base_align = drmmode_get_base_align(pScrn, (bpp / 8), 0);
1822 size = scratch_pitch * height * (bpp / 8);
1823 scratch = radeon_bo_open(info->bufmgr, 0, size, base_align, RADEON_GEM_DOMAIN_GTT, 0);
1824 if (!scratch) {
1825 goto copy;
1826 }
1827 radeon_cs_space_reset_bos(info->cs);
1828 radeon_cs_space_add_persistent_bo(info->cs, info->accel_state->shaders_bo,
1829 RADEON_GEM_DOMAIN_VRAM, 0);
1830 accel_state->src_obj[0].domain = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM;
1831 radeon_add_pixmap(info->cs, pSrc, info->accel_state->src_obj[0].domain, 0);
1832 accel_state->dst_obj.domain = RADEON_GEM_DOMAIN_GTT;
1833 radeon_cs_space_add_persistent_bo(info->cs, scratch, 0, accel_state->dst_obj.domain);
1834 ret = radeon_cs_space_check(info->cs);
1835 if (ret) {
1836 goto copy;
1837 }
1838
1839 src_obj.pitch = src_pitch_hw;
1840 src_obj.width = pSrc->drawable.width;
1841 src_obj.height = pSrc->drawable.height;
1842 src_obj.bpp = bpp;
1843 src_obj.domain = RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT;
1844 src_obj.bo = radeon_get_pixmap_bo(pSrc)->bo.radeon;
1845 src_obj.tiling_flags = radeon_get_pixmap_tiling(pSrc);
1846 src_obj.surface = radeon_get_pixmap_surface(pSrc);
1847
1848 dst_obj.pitch = scratch_pitch;
1849 dst_obj.width = w;
1850 dst_obj.height = h;
1851 dst_obj.bo = scratch;
1852 dst_obj.bpp = bpp;
1853 dst_obj.domain = RADEON_GEM_DOMAIN_GTT;
1854 dst_obj.tiling_flags = 0;
1855 dst_obj.surface = NULL;
1856
1857 if (!R600SetAccelState(pScrn,
1858 &src_obj,
1859 NULL,
1860 &dst_obj,
1861 accel_state->copy_vs_offset, accel_state->copy_ps_offset,
1862 3, 0xffffffff)) {
1863 goto copy;
1864 }
1865
1866 /* blit from vram to gart */
1867 EVERGREENDoPrepareCopy(pScrn);
1868 EVERGREENAppendCopyVertex(pScrn, x, y, 0, 0, w, h);
1869 EVERGREENDoCopy(pScrn);
1870 copy_src = scratch;
1871 copy_pitch = scratch_pitch * (bpp / 8);
1872 flush = TRUE;
1873
1874 copy:
1875 if (flush)
1876 radeon_cs_flush_indirect(pScrn);
1877
1878 ret = radeon_bo_map(copy_src, 0);
1879 if (ret) {
1880 ErrorF("failed to map pixmap: %d\n", ret);
1881 r = FALSE;
1882 goto out;
1883 }
1884 r = TRUE;
1885 w *= bpp / 8;
1886 if (copy_src == driver_priv->bo->bo.radeon)
1887 size = y * copy_pitch + x * bpp / 8;
1888 else
1889 size = 0;
1890 while (h--) {
1891 memcpy(dst, copy_src->ptr + size, w);
1892 size += copy_pitch;
1893 dst += dst_pitch;
1894 }
1895 radeon_bo_unmap(copy_src);
1896 out:
1897 if (scratch)
1898 radeon_bo_unref(scratch);
1899 return r;
1900 }
1901
1902 static int
EVERGREENMarkSync(ScreenPtr pScreen)1903 EVERGREENMarkSync(ScreenPtr pScreen)
1904 {
1905 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
1906 RADEONInfoPtr info = RADEONPTR(pScrn);
1907 struct radeon_accel_state *accel_state = info->accel_state;
1908
1909 return ++accel_state->exaSyncMarker;
1910
1911 }
1912
1913 static void
EVERGREENSync(ScreenPtr pScreen,int marker)1914 EVERGREENSync(ScreenPtr pScreen, int marker)
1915 {
1916 return;
1917 }
1918
1919 static Bool
EVERGREENAllocShaders(ScrnInfoPtr pScrn,ScreenPtr pScreen)1920 EVERGREENAllocShaders(ScrnInfoPtr pScrn, ScreenPtr pScreen)
1921 {
1922 RADEONInfoPtr info = RADEONPTR(pScrn);
1923 struct radeon_accel_state *accel_state = info->accel_state;
1924
1925 /* 512 bytes per shader for now */
1926 int size = 512 * 9;
1927
1928 accel_state->shaders_bo = radeon_bo_open(info->bufmgr, 0, size, 0,
1929 RADEON_GEM_DOMAIN_VRAM, 0);
1930 if (!accel_state->shaders_bo) {
1931 ErrorF("Allocating shader failed\n");
1932 return FALSE;
1933 }
1934 return TRUE;
1935 }
1936
1937 static Bool
EVERGREENLoadShaders(ScrnInfoPtr pScrn)1938 EVERGREENLoadShaders(ScrnInfoPtr pScrn)
1939 {
1940 RADEONInfoPtr info = RADEONPTR(pScrn);
1941 struct radeon_accel_state *accel_state = info->accel_state;
1942 RADEONChipFamily ChipSet = info->ChipFamily;
1943 uint32_t *shader;
1944 int ret;
1945
1946 ret = radeon_bo_map(accel_state->shaders_bo, 1);
1947 if (ret) {
1948 FatalError("failed to map shader %d\n", ret);
1949 return FALSE;
1950 }
1951 shader = accel_state->shaders_bo->ptr;
1952
1953 /* solid vs --------------------------------------- */
1954 accel_state->solid_vs_offset = 0;
1955 evergreen_solid_vs(ChipSet, shader + accel_state->solid_vs_offset / 4);
1956
1957 /* solid ps --------------------------------------- */
1958 accel_state->solid_ps_offset = 512;
1959 evergreen_solid_ps(ChipSet, shader + accel_state->solid_ps_offset / 4);
1960
1961 /* copy vs --------------------------------------- */
1962 accel_state->copy_vs_offset = 1024;
1963 evergreen_copy_vs(ChipSet, shader + accel_state->copy_vs_offset / 4);
1964
1965 /* copy ps --------------------------------------- */
1966 accel_state->copy_ps_offset = 1536;
1967 evergreen_copy_ps(ChipSet, shader + accel_state->copy_ps_offset / 4);
1968
1969 /* comp vs --------------------------------------- */
1970 accel_state->comp_vs_offset = 2048;
1971 evergreen_comp_vs(ChipSet, shader + accel_state->comp_vs_offset / 4);
1972
1973 /* comp ps --------------------------------------- */
1974 accel_state->comp_ps_offset = 2560;
1975 evergreen_comp_ps(ChipSet, shader + accel_state->comp_ps_offset / 4);
1976
1977 /* xv vs --------------------------------------- */
1978 accel_state->xv_vs_offset = 3072;
1979 evergreen_xv_vs(ChipSet, shader + accel_state->xv_vs_offset / 4);
1980
1981 /* xv ps --------------------------------------- */
1982 accel_state->xv_ps_offset = 3584;
1983 evergreen_xv_ps(ChipSet, shader + accel_state->xv_ps_offset / 4);
1984
1985 radeon_bo_unmap(accel_state->shaders_bo);
1986
1987 return TRUE;
1988 }
1989
1990 static Bool
CAYMANLoadShaders(ScrnInfoPtr pScrn)1991 CAYMANLoadShaders(ScrnInfoPtr pScrn)
1992 {
1993 RADEONInfoPtr info = RADEONPTR(pScrn);
1994 struct radeon_accel_state *accel_state = info->accel_state;
1995 RADEONChipFamily ChipSet = info->ChipFamily;
1996 uint32_t *shader;
1997 int ret;
1998
1999 ret = radeon_bo_map(accel_state->shaders_bo, 1);
2000 if (ret) {
2001 FatalError("failed to map shader %d\n", ret);
2002 return FALSE;
2003 }
2004 shader = accel_state->shaders_bo->ptr;
2005
2006 /* solid vs --------------------------------------- */
2007 accel_state->solid_vs_offset = 0;
2008 cayman_solid_vs(ChipSet, shader + accel_state->solid_vs_offset / 4);
2009
2010 /* solid ps --------------------------------------- */
2011 accel_state->solid_ps_offset = 512;
2012 cayman_solid_ps(ChipSet, shader + accel_state->solid_ps_offset / 4);
2013
2014 /* copy vs --------------------------------------- */
2015 accel_state->copy_vs_offset = 1024;
2016 cayman_copy_vs(ChipSet, shader + accel_state->copy_vs_offset / 4);
2017
2018 /* copy ps --------------------------------------- */
2019 accel_state->copy_ps_offset = 1536;
2020 cayman_copy_ps(ChipSet, shader + accel_state->copy_ps_offset / 4);
2021
2022 /* comp vs --------------------------------------- */
2023 accel_state->comp_vs_offset = 2048;
2024 cayman_comp_vs(ChipSet, shader + accel_state->comp_vs_offset / 4);
2025
2026 /* comp ps --------------------------------------- */
2027 accel_state->comp_ps_offset = 2560;
2028 cayman_comp_ps(ChipSet, shader + accel_state->comp_ps_offset / 4);
2029
2030 /* xv vs --------------------------------------- */
2031 accel_state->xv_vs_offset = 3072;
2032 cayman_xv_vs(ChipSet, shader + accel_state->xv_vs_offset / 4);
2033
2034 /* xv ps --------------------------------------- */
2035 accel_state->xv_ps_offset = 3584;
2036 cayman_xv_ps(ChipSet, shader + accel_state->xv_ps_offset / 4);
2037
2038 radeon_bo_unmap(accel_state->shaders_bo);
2039
2040 return TRUE;
2041 }
2042
2043 Bool
EVERGREENDrawInit(ScreenPtr pScreen)2044 EVERGREENDrawInit(ScreenPtr pScreen)
2045 {
2046 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
2047 RADEONInfoPtr info = RADEONPTR(pScrn);
2048
2049 if (!info->accel_state->exa) {
2050 xf86DrvMsg(pScreen->myNum, X_ERROR, "Memory map not set up\n");
2051 return FALSE;
2052 }
2053
2054 info->accel_state->exa->exa_major = EXA_VERSION_MAJOR;
2055 info->accel_state->exa->exa_minor = EXA_VERSION_MINOR;
2056
2057 info->accel_state->exa->PrepareSolid = EVERGREENPrepareSolid;
2058 info->accel_state->exa->Solid = EVERGREENSolid;
2059 info->accel_state->exa->DoneSolid = EVERGREENDoneSolid;
2060
2061 info->accel_state->exa->PrepareCopy = EVERGREENPrepareCopy;
2062 info->accel_state->exa->Copy = EVERGREENCopy;
2063 info->accel_state->exa->DoneCopy = EVERGREENDoneCopy;
2064
2065 info->accel_state->exa->MarkSync = EVERGREENMarkSync;
2066 info->accel_state->exa->WaitMarker = EVERGREENSync;
2067
2068 info->accel_state->exa->DestroyPixmap = RADEONEXADestroyPixmap;
2069 info->accel_state->exa->PixmapIsOffscreen = RADEONEXAPixmapIsOffscreen;
2070 info->accel_state->exa->PrepareAccess = RADEONPrepareAccess_CS;
2071 info->accel_state->exa->FinishAccess = RADEONFinishAccess_CS;
2072 info->accel_state->exa->UploadToScreen = EVERGREENUploadToScreen;
2073 info->accel_state->exa->DownloadFromScreen = EVERGREENDownloadFromScreen;
2074 info->accel_state->exa->CreatePixmap2 = RADEONEXACreatePixmap2;
2075 info->accel_state->exa->SharePixmapBacking = RADEONEXASharePixmapBacking;
2076 info->accel_state->exa->SetSharedPixmapBacking = RADEONEXASetSharedPixmapBacking;
2077 info->accel_state->exa->flags = EXA_OFFSCREEN_PIXMAPS | EXA_SUPPORTS_PREPARE_AUX |
2078 EXA_HANDLES_PIXMAPS | EXA_MIXED_PIXMAPS;
2079 info->accel_state->exa->pixmapOffsetAlign = 256;
2080 info->accel_state->exa->pixmapPitchAlign = 256;
2081
2082 info->accel_state->exa->CheckComposite = EVERGREENCheckComposite;
2083 info->accel_state->exa->PrepareComposite = EVERGREENPrepareComposite;
2084 info->accel_state->exa->Composite = EVERGREENComposite;
2085 info->accel_state->exa->DoneComposite = EVERGREENDoneComposite;
2086
2087 info->accel_state->exa->maxPitchBytes = 32768;
2088 info->accel_state->exa->maxX = 8192;
2089 info->accel_state->exa->maxY = 8192;
2090
2091 /* not supported yet */
2092 if (xf86ReturnOptValBool(info->Options, OPTION_EXA_VSYNC, FALSE)) {
2093 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EXA VSync enabled\n");
2094 info->accel_state->vsync = TRUE;
2095 } else
2096 info->accel_state->vsync = FALSE;
2097
2098 if (!exaDriverInit(pScreen, info->accel_state->exa)) {
2099 free(info->accel_state->exa);
2100 return FALSE;
2101 }
2102
2103 info->accel_state->XInited3D = FALSE;
2104 info->accel_state->copy_area = NULL;
2105 info->accel_state->src_obj[0].bo = NULL;
2106 info->accel_state->src_obj[1].bo = NULL;
2107 info->accel_state->dst_obj.bo = NULL;
2108 info->accel_state->copy_area_bo = NULL;
2109 info->accel_state->vbo.vb_start_op = -1;
2110 info->accel_state->cbuf.vb_start_op = -1;
2111 info->accel_state->finish_op = evergreen_finish_op;
2112 info->accel_state->vbo.verts_per_op = 3;
2113 info->accel_state->cbuf.verts_per_op = 1;
2114 RADEONVlineHelperClear(pScrn);
2115
2116 radeon_vbo_init_lists(pScrn);
2117
2118 if (!EVERGREENAllocShaders(pScrn, pScreen))
2119 return FALSE;
2120
2121 if (info->ChipFamily >= CHIP_FAMILY_CAYMAN) {
2122 if (!CAYMANLoadShaders(pScrn))
2123 return FALSE;
2124 } else {
2125 if (!EVERGREENLoadShaders(pScrn))
2126 return FALSE;
2127 }
2128
2129 exaMarkSync(pScreen);
2130
2131 return TRUE;
2132
2133 }
2134