r600_textured_videofuncs.c revision 921a55d8
1/* 2 * Copyright 2008 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 "r600_shader.h" 38#include "r600_reg.h" 39#include "r600_state.h" 40 41#include "radeon_video.h" 42 43#include <X11/extensions/Xv.h> 44#include "fourcc.h" 45 46#include "damage.h" 47 48#include "radeon_exa_shared.h" 49#include "radeon_vbo.h" 50 51/* Parameters for ITU-R BT.601 and ITU-R BT.709 colour spaces 52 note the difference to the parameters used in overlay are due 53 to 10bit vs. float calcs */ 54static REF_TRANSFORM trans[2] = 55{ 56 {1.1643, 0.0, 1.5960, -0.3918, -0.8129, 2.0172, 0.0}, /* BT.601 */ 57 {1.1643, 0.0, 1.7927, -0.2132, -0.5329, 2.1124, 0.0} /* BT.709 */ 58}; 59 60void 61R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) 62{ 63 RADEONInfoPtr info = RADEONPTR(pScrn); 64 struct radeon_accel_state *accel_state = info->accel_state; 65 PixmapPtr pPixmap = pPriv->pPixmap; 66 BoxPtr pBox = REGION_RECTS(&pPriv->clip); 67 int nBox = REGION_NUM_RECTS(&pPriv->clip); 68 int dstxoff, dstyoff; 69 struct r600_accel_object src_obj, dst_obj; 70 cb_config_t cb_conf; 71 tex_resource_t tex_res; 72 tex_sampler_t tex_samp; 73 shader_config_t vs_conf, ps_conf; 74 /* 75 * y' = y - .0625 76 * u' = u - .5 77 * v' = v - .5; 78 * 79 * r = 1.1643 * y' + 0.0 * u' + 1.5958 * v' 80 * g = 1.1643 * y' - 0.39173 * u' - 0.81290 * v' 81 * b = 1.1643 * y' + 2.017 * u' + 0.0 * v' 82 * 83 * DP3 might look like the straightforward solution 84 * but we'd need to move the texture yuv values in 85 * the same reg for this to work. Therefore use MADs. 86 * Brightness just adds to the off constant. 87 * Contrast is multiplication of luminance. 88 * Saturation and hue change the u and v coeffs. 89 * Default values (before adjustments - depend on colorspace): 90 * yco = 1.1643 91 * uco = 0, -0.39173, 2.017 92 * vco = 1.5958, -0.8129, 0 93 * off = -0.0625 * yco + -0.5 * uco[r] + -0.5 * vco[r], 94 * -0.0625 * yco + -0.5 * uco[g] + -0.5 * vco[g], 95 * -0.0625 * yco + -0.5 * uco[b] + -0.5 * vco[b], 96 * 97 * temp = MAD(yco, yuv.yyyy, off) 98 * temp = MAD(uco, yuv.uuuu, temp) 99 * result = MAD(vco, yuv.vvvv, temp) 100 */ 101 /* TODO: calc consts in the shader */ 102 const float Loff = -0.0627; 103 const float Coff = -0.502; 104 float uvcosf, uvsinf; 105 float yco; 106 float uco[3], vco[3], off[3]; 107 float bright, cont, gamma; 108 int ref = pPriv->transform_index; 109 Bool needgamma = FALSE; 110 float ps_alu_consts[12]; 111 float vs_alu_consts[4]; 112 113 cont = RTFContrast(pPriv->contrast); 114 bright = RTFBrightness(pPriv->brightness); 115 gamma = (float)pPriv->gamma / 1000.0; 116 uvcosf = RTFSaturation(pPriv->saturation) * cos(RTFHue(pPriv->hue)); 117 uvsinf = RTFSaturation(pPriv->saturation) * sin(RTFHue(pPriv->hue)); 118 /* overlay video also does pre-gamma contrast/sat adjust, should we? */ 119 120 yco = trans[ref].RefLuma * cont; 121 uco[0] = -trans[ref].RefRCr * uvsinf; 122 uco[1] = trans[ref].RefGCb * uvcosf - trans[ref].RefGCr * uvsinf; 123 uco[2] = trans[ref].RefBCb * uvcosf; 124 vco[0] = trans[ref].RefRCr * uvcosf; 125 vco[1] = trans[ref].RefGCb * uvsinf + trans[ref].RefGCr * uvcosf; 126 vco[2] = trans[ref].RefBCb * uvsinf; 127 off[0] = Loff * yco + Coff * (uco[0] + vco[0]) + bright; 128 off[1] = Loff * yco + Coff * (uco[1] + vco[1]) + bright; 129 off[2] = Loff * yco + Coff * (uco[2] + vco[2]) + bright; 130 131 // XXX 132 gamma = 1.0; 133 134 if (gamma != 1.0) { 135 needgamma = TRUE; 136 /* note: gamma correction is out = in ^ gamma; 137 gpu can only do LG2/EX2 therefore we transform into 138 in ^ gamma = 2 ^ (log2(in) * gamma). 139 Lots of scalar ops, unfortunately (better solution?) - 140 without gamma that's 3 inst, with gamma it's 10... 141 could use different gamma factors per channel, 142 if that's of any use. */ 143 } 144 145 /* setup the ps consts */ 146 ps_alu_consts[0] = off[0]; 147 ps_alu_consts[1] = off[1]; 148 ps_alu_consts[2] = off[2]; 149 ps_alu_consts[3] = yco; 150 151 ps_alu_consts[4] = uco[0]; 152 ps_alu_consts[5] = uco[1]; 153 ps_alu_consts[6] = uco[2]; 154 ps_alu_consts[7] = gamma; 155 156 ps_alu_consts[8] = vco[0]; 157 ps_alu_consts[9] = vco[1]; 158 ps_alu_consts[10] = vco[2]; 159 ps_alu_consts[11] = 0.0; 160 161 CLEAR (cb_conf); 162 CLEAR (tex_res); 163 CLEAR (tex_samp); 164 CLEAR (vs_conf); 165 CLEAR (ps_conf); 166 167#if defined(XF86DRM_MODE) 168 if (info->cs) { 169 dst_obj.offset = 0; 170 src_obj.offset = 0; 171 dst_obj.bo = radeon_get_pixmap_bo(pPixmap); 172 } else 173#endif 174 { 175 dst_obj.offset = exaGetPixmapOffset(pPixmap) + info->fbLocation + pScrn->fbOffset; 176 src_obj.offset = pPriv->src_offset + info->fbLocation + pScrn->fbOffset; 177 dst_obj.bo = src_obj.bo = NULL; 178 } 179 dst_obj.pitch = exaGetPixmapPitch(pPixmap) / (pPixmap->drawable.bitsPerPixel / 8); 180 181 src_obj.pitch = pPriv->src_pitch; 182 src_obj.width = pPriv->w; 183 src_obj.height = pPriv->h; 184 src_obj.bpp = 16; 185 src_obj.domain = RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT; 186 src_obj.bo = pPriv->src_bo[pPriv->currentBuffer]; 187 188 dst_obj.width = pPixmap->drawable.width; 189 dst_obj.height = pPixmap->drawable.height; 190 dst_obj.bpp = pPixmap->drawable.bitsPerPixel; 191 dst_obj.domain = RADEON_GEM_DOMAIN_VRAM; 192 193 if (!R600SetAccelState(pScrn, 194 &src_obj, 195 NULL, 196 &dst_obj, 197 accel_state->xv_vs_offset, accel_state->xv_ps_offset, 198 3, 0xffffffff)) 199 return; 200 201#ifdef COMPOSITE 202 dstxoff = -pPixmap->screen_x + pPixmap->drawable.x; 203 dstyoff = -pPixmap->screen_y + pPixmap->drawable.y; 204#else 205 dstxoff = 0; 206 dstyoff = 0; 207#endif 208 209 radeon_vbo_check(pScrn, &accel_state->vbo, 16); 210 radeon_cp_start(pScrn); 211 212 r600_set_default_state(pScrn, accel_state->ib); 213 214 r600_set_generic_scissor(pScrn, accel_state->ib, 0, 0, accel_state->dst_obj.width, accel_state->dst_obj.height); 215 r600_set_screen_scissor(pScrn, accel_state->ib, 0, 0, accel_state->dst_obj.width, accel_state->dst_obj.height); 216 r600_set_window_scissor(pScrn, accel_state->ib, 0, 0, accel_state->dst_obj.width, accel_state->dst_obj.height); 217 218 /* PS bool constant */ 219 switch(pPriv->id) { 220 case FOURCC_YV12: 221 case FOURCC_I420: 222 r600_set_bool_consts(pScrn, accel_state->ib, SQ_BOOL_CONST_ps, (1 << 0)); 223 break; 224 case FOURCC_UYVY: 225 case FOURCC_YUY2: 226 default: 227 r600_set_bool_consts(pScrn, accel_state->ib, SQ_BOOL_CONST_ps, (0 << 0)); 228 break; 229 } 230 231 /* Shader */ 232 vs_conf.shader_addr = accel_state->vs_mc_addr; 233 vs_conf.shader_size = accel_state->vs_size; 234 vs_conf.num_gprs = 2; 235 vs_conf.stack_size = 0; 236 vs_conf.bo = accel_state->shaders_bo; 237 r600_vs_setup(pScrn, accel_state->ib, &vs_conf, RADEON_GEM_DOMAIN_VRAM); 238 239 ps_conf.shader_addr = accel_state->ps_mc_addr; 240 ps_conf.shader_size = accel_state->ps_size; 241 ps_conf.num_gprs = 3; 242 ps_conf.stack_size = 1; 243 ps_conf.uncached_first_inst = 1; 244 ps_conf.clamp_consts = 0; 245 ps_conf.export_mode = 2; 246 ps_conf.bo = accel_state->shaders_bo; 247 r600_ps_setup(pScrn, accel_state->ib, &ps_conf, RADEON_GEM_DOMAIN_VRAM); 248 249 /* PS alu constants */ 250 r600_set_alu_consts(pScrn, accel_state->ib, SQ_ALU_CONSTANT_ps, 251 sizeof(ps_alu_consts) / SQ_ALU_CONSTANT_offset, ps_alu_consts); 252 253 /* Texture */ 254 switch(pPriv->id) { 255 case FOURCC_YV12: 256 case FOURCC_I420: 257 accel_state->src_size[0] = accel_state->src_obj[0].pitch * pPriv->h; 258 259 /* Y texture */ 260 tex_res.id = 0; 261 tex_res.w = accel_state->src_obj[0].width; 262 tex_res.h = accel_state->src_obj[0].height; 263 tex_res.pitch = accel_state->src_obj[0].pitch; 264 tex_res.depth = 0; 265 tex_res.dim = SQ_TEX_DIM_2D; 266 tex_res.base = accel_state->src_obj[0].offset; 267 tex_res.mip_base = accel_state->src_obj[0].offset; 268 tex_res.size = accel_state->src_size[0]; 269 tex_res.bo = accel_state->src_obj[0].bo; 270 tex_res.mip_bo = accel_state->src_obj[0].bo; 271 272 tex_res.format = FMT_8; 273 tex_res.dst_sel_x = SQ_SEL_X; /* Y */ 274 tex_res.dst_sel_y = SQ_SEL_1; 275 tex_res.dst_sel_z = SQ_SEL_1; 276 tex_res.dst_sel_w = SQ_SEL_1; 277 278 tex_res.request_size = 1; 279 tex_res.base_level = 0; 280 tex_res.last_level = 0; 281 tex_res.perf_modulation = 0; 282 tex_res.interlaced = 0; 283 r600_set_tex_resource(pScrn, accel_state->ib, &tex_res, accel_state->src_obj[0].domain); 284 285 /* Y sampler */ 286 tex_samp.id = 0; 287 tex_samp.clamp_x = SQ_TEX_CLAMP_LAST_TEXEL; 288 tex_samp.clamp_y = SQ_TEX_CLAMP_LAST_TEXEL; 289 tex_samp.clamp_z = SQ_TEX_WRAP; 290 291 /* xxx: switch to bicubic */ 292 tex_samp.xy_mag_filter = SQ_TEX_XY_FILTER_BILINEAR; 293 tex_samp.xy_min_filter = SQ_TEX_XY_FILTER_BILINEAR; 294 295 tex_samp.z_filter = SQ_TEX_Z_FILTER_NONE; 296 tex_samp.mip_filter = 0; /* no mipmap */ 297 r600_set_tex_sampler(pScrn, accel_state->ib, &tex_samp); 298 299 /* U or V texture */ 300 tex_res.id = 1; 301 tex_res.format = FMT_8; 302 tex_res.w = accel_state->src_obj[0].width >> 1; 303 tex_res.h = accel_state->src_obj[0].height >> 1; 304 tex_res.pitch = RADEON_ALIGN(accel_state->src_obj[0].pitch >> 1, 256); 305 tex_res.dst_sel_x = SQ_SEL_X; /* V or U */ 306 tex_res.dst_sel_y = SQ_SEL_1; 307 tex_res.dst_sel_z = SQ_SEL_1; 308 tex_res.dst_sel_w = SQ_SEL_1; 309 tex_res.interlaced = 0; 310 311 tex_res.base = accel_state->src_obj[0].offset + pPriv->planev_offset; 312 tex_res.mip_base = accel_state->src_obj[0].offset + pPriv->planev_offset; 313 tex_res.size = tex_res.pitch * (pPriv->h >> 1); 314 r600_set_tex_resource(pScrn, accel_state->ib, &tex_res, accel_state->src_obj[0].domain); 315 316 /* U or V sampler */ 317 tex_samp.id = 1; 318 r600_set_tex_sampler(pScrn, accel_state->ib, &tex_samp); 319 320 /* U or V texture */ 321 tex_res.id = 2; 322 tex_res.format = FMT_8; 323 tex_res.w = accel_state->src_obj[0].width >> 1; 324 tex_res.h = accel_state->src_obj[0].height >> 1; 325 tex_res.pitch = RADEON_ALIGN(accel_state->src_obj[0].pitch >> 1, 256); 326 tex_res.dst_sel_x = SQ_SEL_X; /* V or U */ 327 tex_res.dst_sel_y = SQ_SEL_1; 328 tex_res.dst_sel_z = SQ_SEL_1; 329 tex_res.dst_sel_w = SQ_SEL_1; 330 tex_res.interlaced = 0; 331 332 tex_res.base = accel_state->src_obj[0].offset + pPriv->planeu_offset; 333 tex_res.mip_base = accel_state->src_obj[0].offset + pPriv->planeu_offset; 334 tex_res.size = tex_res.pitch * (pPriv->h >> 1); 335 r600_set_tex_resource(pScrn, accel_state->ib, &tex_res, accel_state->src_obj[0].domain); 336 337 /* UV sampler */ 338 tex_samp.id = 2; 339 r600_set_tex_sampler(pScrn, accel_state->ib, &tex_samp); 340 break; 341 case FOURCC_UYVY: 342 case FOURCC_YUY2: 343 default: 344 accel_state->src_size[0] = accel_state->src_obj[0].pitch * pPriv->h; 345 346 /* Y texture */ 347 tex_res.id = 0; 348 tex_res.w = accel_state->src_obj[0].width; 349 tex_res.h = accel_state->src_obj[0].height; 350 tex_res.pitch = accel_state->src_obj[0].pitch >> 1; 351 tex_res.depth = 0; 352 tex_res.dim = SQ_TEX_DIM_2D; 353 tex_res.base = accel_state->src_obj[0].offset; 354 tex_res.mip_base = accel_state->src_obj[0].offset; 355 tex_res.size = accel_state->src_size[0]; 356 tex_res.bo = accel_state->src_obj[0].bo; 357 tex_res.mip_bo = accel_state->src_obj[0].bo; 358 359 tex_res.format = FMT_8_8; 360 if (pPriv->id == FOURCC_UYVY) 361 tex_res.dst_sel_x = SQ_SEL_Y; /* Y */ 362 else 363 tex_res.dst_sel_x = SQ_SEL_X; /* Y */ 364 tex_res.dst_sel_y = SQ_SEL_1; 365 tex_res.dst_sel_z = SQ_SEL_1; 366 tex_res.dst_sel_w = SQ_SEL_1; 367 368 tex_res.request_size = 1; 369 tex_res.base_level = 0; 370 tex_res.last_level = 0; 371 tex_res.perf_modulation = 0; 372 tex_res.interlaced = 0; 373 r600_set_tex_resource(pScrn, accel_state->ib, &tex_res, accel_state->src_obj[0].domain); 374 375 /* Y sampler */ 376 tex_samp.id = 0; 377 tex_samp.clamp_x = SQ_TEX_CLAMP_LAST_TEXEL; 378 tex_samp.clamp_y = SQ_TEX_CLAMP_LAST_TEXEL; 379 tex_samp.clamp_z = SQ_TEX_WRAP; 380 381 /* xxx: switch to bicubic */ 382 tex_samp.xy_mag_filter = SQ_TEX_XY_FILTER_BILINEAR; 383 tex_samp.xy_min_filter = SQ_TEX_XY_FILTER_BILINEAR; 384 385 tex_samp.z_filter = SQ_TEX_Z_FILTER_NONE; 386 tex_samp.mip_filter = 0; /* no mipmap */ 387 r600_set_tex_sampler(pScrn, accel_state->ib, &tex_samp); 388 389 /* UV texture */ 390 tex_res.id = 1; 391 tex_res.format = FMT_8_8_8_8; 392 tex_res.w = accel_state->src_obj[0].width >> 1; 393 tex_res.h = accel_state->src_obj[0].height; 394 tex_res.pitch = accel_state->src_obj[0].pitch >> 2; 395 if (pPriv->id == FOURCC_UYVY) { 396 tex_res.dst_sel_x = SQ_SEL_X; /* V */ 397 tex_res.dst_sel_y = SQ_SEL_Z; /* U */ 398 } else { 399 tex_res.dst_sel_x = SQ_SEL_Y; /* V */ 400 tex_res.dst_sel_y = SQ_SEL_W; /* U */ 401 } 402 tex_res.dst_sel_z = SQ_SEL_1; 403 tex_res.dst_sel_w = SQ_SEL_1; 404 tex_res.interlaced = 0; 405 406 tex_res.base = accel_state->src_obj[0].offset; 407 tex_res.mip_base = accel_state->src_obj[0].offset; 408 tex_res.size = accel_state->src_size[0]; 409 r600_set_tex_resource(pScrn, accel_state->ib, &tex_res, accel_state->src_obj[0].domain); 410 411 /* UV sampler */ 412 tex_samp.id = 1; 413 r600_set_tex_sampler(pScrn, accel_state->ib, &tex_samp); 414 break; 415 } 416 417 cb_conf.id = 0; 418 cb_conf.w = accel_state->dst_obj.pitch; 419 cb_conf.h = accel_state->dst_obj.height; 420 cb_conf.base = accel_state->dst_obj.offset; 421 cb_conf.bo = accel_state->dst_obj.bo; 422 423 switch (accel_state->dst_obj.bpp) { 424 case 16: 425 if (pPixmap->drawable.depth == 15) { 426 cb_conf.format = COLOR_1_5_5_5; 427 cb_conf.comp_swap = 1; /* ARGB */ 428 } else { 429 cb_conf.format = COLOR_5_6_5; 430 cb_conf.comp_swap = 2; /* RGB */ 431 } 432 break; 433 case 32: 434 cb_conf.format = COLOR_8_8_8_8; 435 cb_conf.comp_swap = 1; /* ARGB */ 436 break; 437 default: 438 return; 439 } 440 441 cb_conf.source_format = 1; 442 cb_conf.blend_clamp = 1; 443 r600_set_render_target(pScrn, accel_state->ib, &cb_conf, accel_state->dst_obj.domain); 444 445 /* Render setup */ 446 BEGIN_BATCH(20); 447 EREG(accel_state->ib, CB_TARGET_MASK, (0x0f << TARGET0_ENABLE_shift)); 448 EREG(accel_state->ib, CB_COLOR_CONTROL, (0xcc << ROP3_shift)); /* copy */ 449 450 /* Interpolator setup */ 451 /* export tex coords from VS */ 452 EREG(accel_state->ib, SPI_VS_OUT_CONFIG, ((1 - 1) << VS_EXPORT_COUNT_shift)); 453 EREG(accel_state->ib, SPI_VS_OUT_ID_0, (0 << SEMANTIC_0_shift)); 454 EREG(accel_state->ib, SPI_PS_INPUT_CNTL_0 + (0 << 2), ((0 << SEMANTIC_shift) | 455 (0x03 << DEFAULT_VAL_shift) | 456 SEL_CENTROID_bit)); 457 458 /* Enabling flat shading needs both FLAT_SHADE_bit in SPI_PS_INPUT_CNTL_x 459 * *and* FLAT_SHADE_ENA_bit in SPI_INTERP_CONTROL_0 */ 460 PACK0(accel_state->ib, SPI_PS_IN_CONTROL_0, 3); 461 E32(accel_state->ib, ((1 << NUM_INTERP_shift))); 462 E32(accel_state->ib, 0); 463 E32(accel_state->ib, 0); 464 END_BATCH(); 465 466 vs_alu_consts[0] = 1.0 / pPriv->w; 467 vs_alu_consts[1] = 1.0 / pPriv->h; 468 vs_alu_consts[2] = 0.0; 469 vs_alu_consts[3] = 0.0; 470 471 /* VS alu constants */ 472 r600_set_alu_consts(pScrn, accel_state->ib, SQ_ALU_CONSTANT_vs, 473 sizeof(vs_alu_consts) / SQ_ALU_CONSTANT_offset, vs_alu_consts); 474 475 if (pPriv->vsync) { 476 xf86CrtcPtr crtc; 477 if (pPriv->desired_crtc) 478 crtc = pPriv->desired_crtc; 479 else 480 crtc = radeon_pick_best_crtc(pScrn, 481 pPriv->drw_x, 482 pPriv->drw_x + pPriv->dst_w, 483 pPriv->drw_y, 484 pPriv->drw_y + pPriv->dst_h); 485 if (crtc) 486 r600_cp_wait_vline_sync(pScrn, accel_state->ib, pPixmap, 487 crtc, 488 pPriv->drw_y - crtc->y, 489 (pPriv->drw_y - crtc->y) + pPriv->dst_h); 490 } 491 492 while (nBox--) { 493 int srcX, srcY, srcw, srch; 494 int dstX, dstY, dstw, dsth; 495 float *vb; 496 497 498 dstX = pBox->x1 + dstxoff; 499 dstY = pBox->y1 + dstyoff; 500 dstw = pBox->x2 - pBox->x1; 501 dsth = pBox->y2 - pBox->y1; 502 503 srcX = pPriv->src_x; 504 srcX += ((pBox->x1 - pPriv->drw_x) * 505 pPriv->src_w) / pPriv->dst_w; 506 srcY = pPriv->src_y; 507 srcY += ((pBox->y1 - pPriv->drw_y) * 508 pPriv->src_h) / pPriv->dst_h; 509 510 srcw = (pPriv->src_w * dstw) / pPriv->dst_w; 511 srch = (pPriv->src_h * dsth) / pPriv->dst_h; 512 513 vb = radeon_vbo_space(pScrn, &accel_state->vbo, 16); 514 515 vb[0] = (float)dstX; 516 vb[1] = (float)dstY; 517 vb[2] = (float)srcX; 518 vb[3] = (float)srcY; 519 520 vb[4] = (float)dstX; 521 vb[5] = (float)(dstY + dsth); 522 vb[6] = (float)srcX; 523 vb[7] = (float)(srcY + srch); 524 525 vb[8] = (float)(dstX + dstw); 526 vb[9] = (float)(dstY + dsth); 527 vb[10] = (float)(srcX + srcw); 528 vb[11] = (float)(srcY + srch); 529 530 radeon_vbo_commit(pScrn, &accel_state->vbo); 531 532 pBox++; 533 } 534 535 r600_finish_op(pScrn, 16); 536 537 DamageDamageRegion(pPriv->pDraw, &pPriv->clip); 538} 539