r600_textured_videofuncs.c revision b13dfe66
1b7e1c893Smrg/* 2b7e1c893Smrg * Copyright 2008 Advanced Micro Devices, Inc. 3b7e1c893Smrg * 4b7e1c893Smrg * Permission is hereby granted, free of charge, to any person obtaining a 5b7e1c893Smrg * copy of this software and associated documentation files (the "Software"), 6b7e1c893Smrg * to deal in the Software without restriction, including without limitation 7b7e1c893Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8b7e1c893Smrg * and/or sell copies of the Software, and to permit persons to whom the 9b7e1c893Smrg * Software is furnished to do so, subject to the following conditions: 10b7e1c893Smrg * 11b7e1c893Smrg * The above copyright notice and this permission notice (including the next 12b7e1c893Smrg * paragraph) shall be included in all copies or substantial portions of the 13b7e1c893Smrg * Software. 14b7e1c893Smrg * 15b7e1c893Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16b7e1c893Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17b7e1c893Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18b7e1c893Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19b7e1c893Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20b7e1c893Smrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21b7e1c893Smrg * SOFTWARE. 22b7e1c893Smrg * 23b7e1c893Smrg * Author: Alex Deucher <alexander.deucher@amd.com> 24b7e1c893Smrg * 25b7e1c893Smrg */ 26b7e1c893Smrg 27b7e1c893Smrg#ifdef HAVE_CONFIG_H 28b7e1c893Smrg#include "config.h" 29b7e1c893Smrg#endif 30b7e1c893Smrg 31b7e1c893Smrg#include "xf86.h" 32b7e1c893Smrg 33b7e1c893Smrg#include "exa.h" 34b7e1c893Smrg 35b7e1c893Smrg#include "radeon.h" 36b7e1c893Smrg#include "radeon_reg.h" 37b7e1c893Smrg#include "r600_shader.h" 38b7e1c893Smrg#include "r600_reg.h" 39b7e1c893Smrg#include "r600_state.h" 40b7e1c893Smrg 41b7e1c893Smrg#include "radeon_video.h" 42b7e1c893Smrg 43b7e1c893Smrg#include <X11/extensions/Xv.h> 44b7e1c893Smrg#include "fourcc.h" 45b7e1c893Smrg 46b7e1c893Smrg#include "damage.h" 47b7e1c893Smrg 480974d292Smrg#include "radeon_exa_shared.h" 49ad43ddacSmrg#include "radeon_vbo.h" 50b7e1c893Smrg 51ad43ddacSmrg/* Parameters for ITU-R BT.601 and ITU-R BT.709 colour spaces 52ad43ddacSmrg note the difference to the parameters used in overlay are due 53ad43ddacSmrg to 10bit vs. float calcs */ 54ad43ddacSmrgstatic REF_TRANSFORM trans[2] = 55ad43ddacSmrg{ 56ad43ddacSmrg {1.1643, 0.0, 1.5960, -0.3918, -0.8129, 2.0172, 0.0}, /* BT.601 */ 57ad43ddacSmrg {1.1643, 0.0, 1.7927, -0.2132, -0.5329, 2.1124, 0.0} /* BT.709 */ 58ad43ddacSmrg}; 59b7e1c893Smrg 60b7e1c893Smrgvoid 61b7e1c893SmrgR600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) 62b7e1c893Smrg{ 63b7e1c893Smrg RADEONInfoPtr info = RADEONPTR(pScrn); 64b7e1c893Smrg struct radeon_accel_state *accel_state = info->accel_state; 65b7e1c893Smrg PixmapPtr pPixmap = pPriv->pPixmap; 66b7e1c893Smrg BoxPtr pBox = REGION_RECTS(&pPriv->clip); 67b7e1c893Smrg int nBox = REGION_NUM_RECTS(&pPriv->clip); 68b7e1c893Smrg int dstxoff, dstyoff; 69ad43ddacSmrg struct r600_accel_object src_obj, dst_obj; 70b7e1c893Smrg cb_config_t cb_conf; 71b7e1c893Smrg tex_resource_t tex_res; 72b7e1c893Smrg tex_sampler_t tex_samp; 73b7e1c893Smrg shader_config_t vs_conf, ps_conf; 74ad43ddacSmrg /* 75ad43ddacSmrg * y' = y - .0625 76ad43ddacSmrg * u' = u - .5 77ad43ddacSmrg * v' = v - .5; 78ad43ddacSmrg * 79ad43ddacSmrg * r = 1.1643 * y' + 0.0 * u' + 1.5958 * v' 80ad43ddacSmrg * g = 1.1643 * y' - 0.39173 * u' - 0.81290 * v' 81ad43ddacSmrg * b = 1.1643 * y' + 2.017 * u' + 0.0 * v' 82ad43ddacSmrg * 83ad43ddacSmrg * DP3 might look like the straightforward solution 84ad43ddacSmrg * but we'd need to move the texture yuv values in 85ad43ddacSmrg * the same reg for this to work. Therefore use MADs. 86ad43ddacSmrg * Brightness just adds to the off constant. 87ad43ddacSmrg * Contrast is multiplication of luminance. 88ad43ddacSmrg * Saturation and hue change the u and v coeffs. 89ad43ddacSmrg * Default values (before adjustments - depend on colorspace): 90ad43ddacSmrg * yco = 1.1643 91ad43ddacSmrg * uco = 0, -0.39173, 2.017 92ad43ddacSmrg * vco = 1.5958, -0.8129, 0 93ad43ddacSmrg * off = -0.0625 * yco + -0.5 * uco[r] + -0.5 * vco[r], 94ad43ddacSmrg * -0.0625 * yco + -0.5 * uco[g] + -0.5 * vco[g], 95ad43ddacSmrg * -0.0625 * yco + -0.5 * uco[b] + -0.5 * vco[b], 96ad43ddacSmrg * 97ad43ddacSmrg * temp = MAD(yco, yuv.yyyy, off) 98ad43ddacSmrg * temp = MAD(uco, yuv.uuuu, temp) 99ad43ddacSmrg * result = MAD(vco, yuv.vvvv, temp) 100ad43ddacSmrg */ 101ad43ddacSmrg /* TODO: calc consts in the shader */ 102ad43ddacSmrg const float Loff = -0.0627; 103ad43ddacSmrg const float Coff = -0.502; 104ad43ddacSmrg float uvcosf, uvsinf; 105ad43ddacSmrg float yco; 106ad43ddacSmrg float uco[3], vco[3], off[3]; 107ad43ddacSmrg float bright, cont, gamma; 108ad43ddacSmrg int ref = pPriv->transform_index; 109ad43ddacSmrg Bool needgamma = FALSE; 110ad43ddacSmrg float ps_alu_consts[12]; 111ad43ddacSmrg float vs_alu_consts[4]; 112ad43ddacSmrg 113ad43ddacSmrg cont = RTFContrast(pPriv->contrast); 114ad43ddacSmrg bright = RTFBrightness(pPriv->brightness); 115ad43ddacSmrg gamma = (float)pPriv->gamma / 1000.0; 116ad43ddacSmrg uvcosf = RTFSaturation(pPriv->saturation) * cos(RTFHue(pPriv->hue)); 117ad43ddacSmrg uvsinf = RTFSaturation(pPriv->saturation) * sin(RTFHue(pPriv->hue)); 118ad43ddacSmrg /* overlay video also does pre-gamma contrast/sat adjust, should we? */ 119ad43ddacSmrg 120ad43ddacSmrg yco = trans[ref].RefLuma * cont; 121ad43ddacSmrg uco[0] = -trans[ref].RefRCr * uvsinf; 122ad43ddacSmrg uco[1] = trans[ref].RefGCb * uvcosf - trans[ref].RefGCr * uvsinf; 123ad43ddacSmrg uco[2] = trans[ref].RefBCb * uvcosf; 124ad43ddacSmrg vco[0] = trans[ref].RefRCr * uvcosf; 125ad43ddacSmrg vco[1] = trans[ref].RefGCb * uvsinf + trans[ref].RefGCr * uvcosf; 126ad43ddacSmrg vco[2] = trans[ref].RefBCb * uvsinf; 127ad43ddacSmrg off[0] = Loff * yco + Coff * (uco[0] + vco[0]) + bright; 128ad43ddacSmrg off[1] = Loff * yco + Coff * (uco[1] + vco[1]) + bright; 129ad43ddacSmrg off[2] = Loff * yco + Coff * (uco[2] + vco[2]) + bright; 130ad43ddacSmrg 131ad43ddacSmrg // XXX 132ad43ddacSmrg gamma = 1.0; 133ad43ddacSmrg 134ad43ddacSmrg if (gamma != 1.0) { 135ad43ddacSmrg needgamma = TRUE; 136ad43ddacSmrg /* note: gamma correction is out = in ^ gamma; 137ad43ddacSmrg gpu can only do LG2/EX2 therefore we transform into 138ad43ddacSmrg in ^ gamma = 2 ^ (log2(in) * gamma). 139ad43ddacSmrg Lots of scalar ops, unfortunately (better solution?) - 140ad43ddacSmrg without gamma that's 3 inst, with gamma it's 10... 141ad43ddacSmrg could use different gamma factors per channel, 142ad43ddacSmrg if that's of any use. */ 143ad43ddacSmrg } 144ad43ddacSmrg 145ad43ddacSmrg /* setup the ps consts */ 146ad43ddacSmrg ps_alu_consts[0] = off[0]; 147ad43ddacSmrg ps_alu_consts[1] = off[1]; 148ad43ddacSmrg ps_alu_consts[2] = off[2]; 149ad43ddacSmrg ps_alu_consts[3] = yco; 150ad43ddacSmrg 151ad43ddacSmrg ps_alu_consts[4] = uco[0]; 152ad43ddacSmrg ps_alu_consts[5] = uco[1]; 153ad43ddacSmrg ps_alu_consts[6] = uco[2]; 154ad43ddacSmrg ps_alu_consts[7] = gamma; 155ad43ddacSmrg 156ad43ddacSmrg ps_alu_consts[8] = vco[0]; 157ad43ddacSmrg ps_alu_consts[9] = vco[1]; 158ad43ddacSmrg ps_alu_consts[10] = vco[2]; 159ad43ddacSmrg ps_alu_consts[11] = 0.0; 160b7e1c893Smrg 161b7e1c893Smrg CLEAR (cb_conf); 162b7e1c893Smrg CLEAR (tex_res); 163b7e1c893Smrg CLEAR (tex_samp); 164b7e1c893Smrg CLEAR (vs_conf); 165b7e1c893Smrg CLEAR (ps_conf); 166b7e1c893Smrg 167ad43ddacSmrg#if defined(XF86DRM_MODE) 168ad43ddacSmrg if (info->cs) { 169ad43ddacSmrg dst_obj.offset = 0; 170ad43ddacSmrg src_obj.offset = 0; 171ad43ddacSmrg dst_obj.bo = radeon_get_pixmap_bo(pPixmap); 172ad43ddacSmrg } else 173ad43ddacSmrg#endif 174ad43ddacSmrg { 175ad43ddacSmrg dst_obj.offset = exaGetPixmapOffset(pPixmap) + info->fbLocation + pScrn->fbOffset; 176ad43ddacSmrg src_obj.offset = pPriv->src_offset + info->fbLocation + pScrn->fbOffset; 177ad43ddacSmrg dst_obj.bo = src_obj.bo = NULL; 178ad43ddacSmrg } 179ad43ddacSmrg dst_obj.pitch = exaGetPixmapPitch(pPixmap) / (pPixmap->drawable.bitsPerPixel / 8); 180ad43ddacSmrg 181ad43ddacSmrg src_obj.pitch = pPriv->src_pitch; 182ad43ddacSmrg src_obj.width = pPriv->w; 183ad43ddacSmrg src_obj.height = pPriv->h; 184ad43ddacSmrg src_obj.bpp = 16; 185ad43ddacSmrg src_obj.domain = RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT; 186ad43ddacSmrg src_obj.bo = pPriv->src_bo[pPriv->currentBuffer]; 187ad43ddacSmrg 188ad43ddacSmrg dst_obj.width = pPixmap->drawable.width; 189ad43ddacSmrg dst_obj.height = pPixmap->drawable.height; 190ad43ddacSmrg dst_obj.bpp = pPixmap->drawable.bitsPerPixel; 191ad43ddacSmrg dst_obj.domain = RADEON_GEM_DOMAIN_VRAM; 192ad43ddacSmrg 193ad43ddacSmrg if (!R600SetAccelState(pScrn, 194ad43ddacSmrg &src_obj, 195ad43ddacSmrg NULL, 196ad43ddacSmrg &dst_obj, 197ad43ddacSmrg accel_state->xv_vs_offset, accel_state->xv_ps_offset, 198ad43ddacSmrg 3, 0xffffffff)) 199b7e1c893Smrg return; 200b7e1c893Smrg 201b7e1c893Smrg#ifdef COMPOSITE 202b7e1c893Smrg dstxoff = -pPixmap->screen_x + pPixmap->drawable.x; 203b7e1c893Smrg dstyoff = -pPixmap->screen_y + pPixmap->drawable.y; 204b7e1c893Smrg#else 205b7e1c893Smrg dstxoff = 0; 206b7e1c893Smrg dstyoff = 0; 207b7e1c893Smrg#endif 208b7e1c893Smrg 209921a55d8Smrg radeon_vbo_check(pScrn, &accel_state->vbo, 16); 2100974d292Smrg radeon_cp_start(pScrn); 211b7e1c893Smrg 212921a55d8Smrg r600_set_default_state(pScrn, accel_state->ib); 213b7e1c893Smrg 214921a55d8Smrg r600_set_generic_scissor(pScrn, accel_state->ib, 0, 0, accel_state->dst_obj.width, accel_state->dst_obj.height); 215921a55d8Smrg r600_set_screen_scissor(pScrn, accel_state->ib, 0, 0, accel_state->dst_obj.width, accel_state->dst_obj.height); 216921a55d8Smrg r600_set_window_scissor(pScrn, accel_state->ib, 0, 0, accel_state->dst_obj.width, accel_state->dst_obj.height); 217b7e1c893Smrg 218b7e1c893Smrg /* PS bool constant */ 219b7e1c893Smrg switch(pPriv->id) { 220b7e1c893Smrg case FOURCC_YV12: 221b7e1c893Smrg case FOURCC_I420: 222921a55d8Smrg r600_set_bool_consts(pScrn, accel_state->ib, SQ_BOOL_CONST_ps, (1 << 0)); 223b7e1c893Smrg break; 224b7e1c893Smrg case FOURCC_UYVY: 225b7e1c893Smrg case FOURCC_YUY2: 226b7e1c893Smrg default: 227921a55d8Smrg r600_set_bool_consts(pScrn, accel_state->ib, SQ_BOOL_CONST_ps, (0 << 0)); 228b7e1c893Smrg break; 229b7e1c893Smrg } 230b7e1c893Smrg 231b7e1c893Smrg /* Shader */ 232b7e1c893Smrg vs_conf.shader_addr = accel_state->vs_mc_addr; 2330974d292Smrg vs_conf.shader_size = accel_state->vs_size; 234b7e1c893Smrg vs_conf.num_gprs = 2; 235b7e1c893Smrg vs_conf.stack_size = 0; 236ad43ddacSmrg vs_conf.bo = accel_state->shaders_bo; 237921a55d8Smrg r600_vs_setup(pScrn, accel_state->ib, &vs_conf, RADEON_GEM_DOMAIN_VRAM); 238b7e1c893Smrg 239b7e1c893Smrg ps_conf.shader_addr = accel_state->ps_mc_addr; 2400974d292Smrg ps_conf.shader_size = accel_state->ps_size; 241b7e1c893Smrg ps_conf.num_gprs = 3; 242b7e1c893Smrg ps_conf.stack_size = 1; 243b7e1c893Smrg ps_conf.uncached_first_inst = 1; 244b7e1c893Smrg ps_conf.clamp_consts = 0; 245b7e1c893Smrg ps_conf.export_mode = 2; 246ad43ddacSmrg ps_conf.bo = accel_state->shaders_bo; 247921a55d8Smrg r600_ps_setup(pScrn, accel_state->ib, &ps_conf, RADEON_GEM_DOMAIN_VRAM); 248b7e1c893Smrg 249b7e1c893Smrg /* PS alu constants */ 250921a55d8Smrg r600_set_alu_consts(pScrn, accel_state->ib, SQ_ALU_CONSTANT_ps, 251921a55d8Smrg sizeof(ps_alu_consts) / SQ_ALU_CONSTANT_offset, ps_alu_consts); 252b7e1c893Smrg 253b7e1c893Smrg /* Texture */ 254b7e1c893Smrg switch(pPriv->id) { 255b7e1c893Smrg case FOURCC_YV12: 256b7e1c893Smrg case FOURCC_I420: 257ad43ddacSmrg accel_state->src_size[0] = accel_state->src_obj[0].pitch * pPriv->h; 258b7e1c893Smrg 259b7e1c893Smrg /* Y texture */ 260b7e1c893Smrg tex_res.id = 0; 261ad43ddacSmrg tex_res.w = accel_state->src_obj[0].width; 262ad43ddacSmrg tex_res.h = accel_state->src_obj[0].height; 263ad43ddacSmrg tex_res.pitch = accel_state->src_obj[0].pitch; 264b7e1c893Smrg tex_res.depth = 0; 265b7e1c893Smrg tex_res.dim = SQ_TEX_DIM_2D; 266ad43ddacSmrg tex_res.base = accel_state->src_obj[0].offset; 267ad43ddacSmrg tex_res.mip_base = accel_state->src_obj[0].offset; 2680974d292Smrg tex_res.size = accel_state->src_size[0]; 269ad43ddacSmrg tex_res.bo = accel_state->src_obj[0].bo; 270ad43ddacSmrg tex_res.mip_bo = accel_state->src_obj[0].bo; 271b7e1c893Smrg 272b7e1c893Smrg tex_res.format = FMT_8; 273b7e1c893Smrg tex_res.dst_sel_x = SQ_SEL_X; /* Y */ 274b7e1c893Smrg tex_res.dst_sel_y = SQ_SEL_1; 275b7e1c893Smrg tex_res.dst_sel_z = SQ_SEL_1; 276b7e1c893Smrg tex_res.dst_sel_w = SQ_SEL_1; 277b7e1c893Smrg 278b7e1c893Smrg tex_res.request_size = 1; 279b7e1c893Smrg tex_res.base_level = 0; 280b7e1c893Smrg tex_res.last_level = 0; 281b7e1c893Smrg tex_res.perf_modulation = 0; 282b7e1c893Smrg tex_res.interlaced = 0; 283b13dfe66Smrg if (accel_state->src_obj[0].tiling_flags == 0) 284b13dfe66Smrg tex_res.tile_mode = 1; 285921a55d8Smrg r600_set_tex_resource(pScrn, accel_state->ib, &tex_res, accel_state->src_obj[0].domain); 286b7e1c893Smrg 287b7e1c893Smrg /* Y sampler */ 288b7e1c893Smrg tex_samp.id = 0; 289b7e1c893Smrg tex_samp.clamp_x = SQ_TEX_CLAMP_LAST_TEXEL; 290b7e1c893Smrg tex_samp.clamp_y = SQ_TEX_CLAMP_LAST_TEXEL; 291b7e1c893Smrg tex_samp.clamp_z = SQ_TEX_WRAP; 292b7e1c893Smrg 293b7e1c893Smrg /* xxx: switch to bicubic */ 294b7e1c893Smrg tex_samp.xy_mag_filter = SQ_TEX_XY_FILTER_BILINEAR; 295b7e1c893Smrg tex_samp.xy_min_filter = SQ_TEX_XY_FILTER_BILINEAR; 296b7e1c893Smrg 297b7e1c893Smrg tex_samp.z_filter = SQ_TEX_Z_FILTER_NONE; 298b7e1c893Smrg tex_samp.mip_filter = 0; /* no mipmap */ 299921a55d8Smrg r600_set_tex_sampler(pScrn, accel_state->ib, &tex_samp); 300b7e1c893Smrg 301b7e1c893Smrg /* U or V texture */ 302b7e1c893Smrg tex_res.id = 1; 303b7e1c893Smrg tex_res.format = FMT_8; 304ad43ddacSmrg tex_res.w = accel_state->src_obj[0].width >> 1; 305ad43ddacSmrg tex_res.h = accel_state->src_obj[0].height >> 1; 306b13dfe66Smrg tex_res.pitch = RADEON_ALIGN(accel_state->src_obj[0].pitch >> 1, pPriv->hw_align); 307b7e1c893Smrg tex_res.dst_sel_x = SQ_SEL_X; /* V or U */ 308b7e1c893Smrg tex_res.dst_sel_y = SQ_SEL_1; 309b7e1c893Smrg tex_res.dst_sel_z = SQ_SEL_1; 310b7e1c893Smrg tex_res.dst_sel_w = SQ_SEL_1; 311b7e1c893Smrg tex_res.interlaced = 0; 312b7e1c893Smrg 313ad43ddacSmrg tex_res.base = accel_state->src_obj[0].offset + pPriv->planev_offset; 314ad43ddacSmrg tex_res.mip_base = accel_state->src_obj[0].offset + pPriv->planev_offset; 315921a55d8Smrg tex_res.size = tex_res.pitch * (pPriv->h >> 1); 316b13dfe66Smrg if (accel_state->src_obj[0].tiling_flags == 0) 317b13dfe66Smrg tex_res.tile_mode = 1; 318921a55d8Smrg r600_set_tex_resource(pScrn, accel_state->ib, &tex_res, accel_state->src_obj[0].domain); 319b7e1c893Smrg 320b7e1c893Smrg /* U or V sampler */ 321b7e1c893Smrg tex_samp.id = 1; 322921a55d8Smrg r600_set_tex_sampler(pScrn, accel_state->ib, &tex_samp); 323b7e1c893Smrg 324b7e1c893Smrg /* U or V texture */ 325b7e1c893Smrg tex_res.id = 2; 326b7e1c893Smrg tex_res.format = FMT_8; 327ad43ddacSmrg tex_res.w = accel_state->src_obj[0].width >> 1; 328ad43ddacSmrg tex_res.h = accel_state->src_obj[0].height >> 1; 329b13dfe66Smrg tex_res.pitch = RADEON_ALIGN(accel_state->src_obj[0].pitch >> 1, pPriv->hw_align); 330b7e1c893Smrg tex_res.dst_sel_x = SQ_SEL_X; /* V or U */ 331b7e1c893Smrg tex_res.dst_sel_y = SQ_SEL_1; 332b7e1c893Smrg tex_res.dst_sel_z = SQ_SEL_1; 333b7e1c893Smrg tex_res.dst_sel_w = SQ_SEL_1; 334b7e1c893Smrg tex_res.interlaced = 0; 335b7e1c893Smrg 336ad43ddacSmrg tex_res.base = accel_state->src_obj[0].offset + pPriv->planeu_offset; 337ad43ddacSmrg tex_res.mip_base = accel_state->src_obj[0].offset + pPriv->planeu_offset; 338921a55d8Smrg tex_res.size = tex_res.pitch * (pPriv->h >> 1); 339b13dfe66Smrg if (accel_state->src_obj[0].tiling_flags == 0) 340b13dfe66Smrg tex_res.tile_mode = 1; 341921a55d8Smrg r600_set_tex_resource(pScrn, accel_state->ib, &tex_res, accel_state->src_obj[0].domain); 342b7e1c893Smrg 343b7e1c893Smrg /* UV sampler */ 344b7e1c893Smrg tex_samp.id = 2; 345921a55d8Smrg r600_set_tex_sampler(pScrn, accel_state->ib, &tex_samp); 346b7e1c893Smrg break; 347b7e1c893Smrg case FOURCC_UYVY: 348b7e1c893Smrg case FOURCC_YUY2: 349b7e1c893Smrg default: 350ad43ddacSmrg accel_state->src_size[0] = accel_state->src_obj[0].pitch * pPriv->h; 351b7e1c893Smrg 352b7e1c893Smrg /* Y texture */ 353b7e1c893Smrg tex_res.id = 0; 354ad43ddacSmrg tex_res.w = accel_state->src_obj[0].width; 355ad43ddacSmrg tex_res.h = accel_state->src_obj[0].height; 356ad43ddacSmrg tex_res.pitch = accel_state->src_obj[0].pitch >> 1; 357b7e1c893Smrg tex_res.depth = 0; 358b7e1c893Smrg tex_res.dim = SQ_TEX_DIM_2D; 359ad43ddacSmrg tex_res.base = accel_state->src_obj[0].offset; 360ad43ddacSmrg tex_res.mip_base = accel_state->src_obj[0].offset; 3610974d292Smrg tex_res.size = accel_state->src_size[0]; 362ad43ddacSmrg tex_res.bo = accel_state->src_obj[0].bo; 363ad43ddacSmrg tex_res.mip_bo = accel_state->src_obj[0].bo; 364b7e1c893Smrg 365b7e1c893Smrg tex_res.format = FMT_8_8; 366b7e1c893Smrg if (pPriv->id == FOURCC_UYVY) 367b7e1c893Smrg tex_res.dst_sel_x = SQ_SEL_Y; /* Y */ 368b7e1c893Smrg else 369b7e1c893Smrg tex_res.dst_sel_x = SQ_SEL_X; /* Y */ 370b7e1c893Smrg tex_res.dst_sel_y = SQ_SEL_1; 371b7e1c893Smrg tex_res.dst_sel_z = SQ_SEL_1; 372b7e1c893Smrg tex_res.dst_sel_w = SQ_SEL_1; 373b7e1c893Smrg 374b7e1c893Smrg tex_res.request_size = 1; 375b7e1c893Smrg tex_res.base_level = 0; 376b7e1c893Smrg tex_res.last_level = 0; 377b7e1c893Smrg tex_res.perf_modulation = 0; 378b7e1c893Smrg tex_res.interlaced = 0; 379b13dfe66Smrg if (accel_state->src_obj[0].tiling_flags == 0) 380b13dfe66Smrg tex_res.tile_mode = 1; 381921a55d8Smrg r600_set_tex_resource(pScrn, accel_state->ib, &tex_res, accel_state->src_obj[0].domain); 382b7e1c893Smrg 383b7e1c893Smrg /* Y sampler */ 384b7e1c893Smrg tex_samp.id = 0; 385b7e1c893Smrg tex_samp.clamp_x = SQ_TEX_CLAMP_LAST_TEXEL; 386b7e1c893Smrg tex_samp.clamp_y = SQ_TEX_CLAMP_LAST_TEXEL; 387b7e1c893Smrg tex_samp.clamp_z = SQ_TEX_WRAP; 388b7e1c893Smrg 389b7e1c893Smrg /* xxx: switch to bicubic */ 390b7e1c893Smrg tex_samp.xy_mag_filter = SQ_TEX_XY_FILTER_BILINEAR; 391b7e1c893Smrg tex_samp.xy_min_filter = SQ_TEX_XY_FILTER_BILINEAR; 392b7e1c893Smrg 393b7e1c893Smrg tex_samp.z_filter = SQ_TEX_Z_FILTER_NONE; 394b7e1c893Smrg tex_samp.mip_filter = 0; /* no mipmap */ 395921a55d8Smrg r600_set_tex_sampler(pScrn, accel_state->ib, &tex_samp); 396b7e1c893Smrg 397b7e1c893Smrg /* UV texture */ 398b7e1c893Smrg tex_res.id = 1; 399b7e1c893Smrg tex_res.format = FMT_8_8_8_8; 400ad43ddacSmrg tex_res.w = accel_state->src_obj[0].width >> 1; 401ad43ddacSmrg tex_res.h = accel_state->src_obj[0].height; 402ad43ddacSmrg tex_res.pitch = accel_state->src_obj[0].pitch >> 2; 403b7e1c893Smrg if (pPriv->id == FOURCC_UYVY) { 404b7e1c893Smrg tex_res.dst_sel_x = SQ_SEL_X; /* V */ 405b7e1c893Smrg tex_res.dst_sel_y = SQ_SEL_Z; /* U */ 406b7e1c893Smrg } else { 407b7e1c893Smrg tex_res.dst_sel_x = SQ_SEL_Y; /* V */ 408b7e1c893Smrg tex_res.dst_sel_y = SQ_SEL_W; /* U */ 409b7e1c893Smrg } 410b7e1c893Smrg tex_res.dst_sel_z = SQ_SEL_1; 411b7e1c893Smrg tex_res.dst_sel_w = SQ_SEL_1; 412b7e1c893Smrg tex_res.interlaced = 0; 413b7e1c893Smrg 414ad43ddacSmrg tex_res.base = accel_state->src_obj[0].offset; 415ad43ddacSmrg tex_res.mip_base = accel_state->src_obj[0].offset; 4160974d292Smrg tex_res.size = accel_state->src_size[0]; 417b13dfe66Smrg if (accel_state->src_obj[0].tiling_flags == 0) 418b13dfe66Smrg tex_res.tile_mode = 1; 419921a55d8Smrg r600_set_tex_resource(pScrn, accel_state->ib, &tex_res, accel_state->src_obj[0].domain); 420b7e1c893Smrg 421b7e1c893Smrg /* UV sampler */ 422b7e1c893Smrg tex_samp.id = 1; 423921a55d8Smrg r600_set_tex_sampler(pScrn, accel_state->ib, &tex_samp); 424b7e1c893Smrg break; 425b7e1c893Smrg } 426b7e1c893Smrg 427b7e1c893Smrg cb_conf.id = 0; 428ad43ddacSmrg cb_conf.w = accel_state->dst_obj.pitch; 429ad43ddacSmrg cb_conf.h = accel_state->dst_obj.height; 430ad43ddacSmrg cb_conf.base = accel_state->dst_obj.offset; 431ad43ddacSmrg cb_conf.bo = accel_state->dst_obj.bo; 432b7e1c893Smrg 433ad43ddacSmrg switch (accel_state->dst_obj.bpp) { 434b7e1c893Smrg case 16: 435b7e1c893Smrg if (pPixmap->drawable.depth == 15) { 436b7e1c893Smrg cb_conf.format = COLOR_1_5_5_5; 437b7e1c893Smrg cb_conf.comp_swap = 1; /* ARGB */ 438b7e1c893Smrg } else { 439b7e1c893Smrg cb_conf.format = COLOR_5_6_5; 440b7e1c893Smrg cb_conf.comp_swap = 2; /* RGB */ 441b7e1c893Smrg } 442b13dfe66Smrg#if X_BYTE_ORDER == X_BIG_ENDIAN 443b13dfe66Smrg cb_conf.endian = ENDIAN_8IN16; 444b13dfe66Smrg#endif 445b7e1c893Smrg break; 446b7e1c893Smrg case 32: 447b7e1c893Smrg cb_conf.format = COLOR_8_8_8_8; 448b7e1c893Smrg cb_conf.comp_swap = 1; /* ARGB */ 449b13dfe66Smrg#if X_BYTE_ORDER == X_BIG_ENDIAN 450b13dfe66Smrg cb_conf.endian = ENDIAN_8IN32; 451b13dfe66Smrg#endif 452b7e1c893Smrg break; 453b7e1c893Smrg default: 454b7e1c893Smrg return; 455b7e1c893Smrg } 456b7e1c893Smrg 457b7e1c893Smrg cb_conf.source_format = 1; 458b7e1c893Smrg cb_conf.blend_clamp = 1; 459b13dfe66Smrg cb_conf.pmask = 0xf; 460b13dfe66Smrg cb_conf.rop = 3; 461b13dfe66Smrg if (accel_state->dst_obj.tiling_flags == 0) 462b13dfe66Smrg cb_conf.array_mode = 1; 463921a55d8Smrg r600_set_render_target(pScrn, accel_state->ib, &cb_conf, accel_state->dst_obj.domain); 464b7e1c893Smrg 465b13dfe66Smrg r600_set_spi(pScrn, accel_state->ib, (1 - 1), 1); 466b7e1c893Smrg 467ad43ddacSmrg vs_alu_consts[0] = 1.0 / pPriv->w; 468ad43ddacSmrg vs_alu_consts[1] = 1.0 / pPriv->h; 469ad43ddacSmrg vs_alu_consts[2] = 0.0; 470ad43ddacSmrg vs_alu_consts[3] = 0.0; 471b7e1c893Smrg 472ad43ddacSmrg /* VS alu constants */ 473921a55d8Smrg r600_set_alu_consts(pScrn, accel_state->ib, SQ_ALU_CONSTANT_vs, 474921a55d8Smrg sizeof(vs_alu_consts) / SQ_ALU_CONSTANT_offset, vs_alu_consts); 475b7e1c893Smrg 476ad43ddacSmrg if (pPriv->vsync) { 477ad43ddacSmrg xf86CrtcPtr crtc; 478ad43ddacSmrg if (pPriv->desired_crtc) 479ad43ddacSmrg crtc = pPriv->desired_crtc; 480ad43ddacSmrg else 481ad43ddacSmrg crtc = radeon_pick_best_crtc(pScrn, 482ad43ddacSmrg pPriv->drw_x, 483ad43ddacSmrg pPriv->drw_x + pPriv->dst_w, 484ad43ddacSmrg pPriv->drw_y, 485ad43ddacSmrg pPriv->drw_y + pPriv->dst_h); 486ad43ddacSmrg if (crtc) 487921a55d8Smrg r600_cp_wait_vline_sync(pScrn, accel_state->ib, pPixmap, 488921a55d8Smrg crtc, 489921a55d8Smrg pPriv->drw_y - crtc->y, 490921a55d8Smrg (pPriv->drw_y - crtc->y) + pPriv->dst_h); 491b7e1c893Smrg } 492b7e1c893Smrg 493b7e1c893Smrg while (nBox--) { 494b7e1c893Smrg int srcX, srcY, srcw, srch; 495b7e1c893Smrg int dstX, dstY, dstw, dsth; 496b7e1c893Smrg float *vb; 497b7e1c893Smrg 498b7e1c893Smrg 499b7e1c893Smrg dstX = pBox->x1 + dstxoff; 500b7e1c893Smrg dstY = pBox->y1 + dstyoff; 501b7e1c893Smrg dstw = pBox->x2 - pBox->x1; 502b7e1c893Smrg dsth = pBox->y2 - pBox->y1; 503b7e1c893Smrg 504ad43ddacSmrg srcX = pPriv->src_x; 505ad43ddacSmrg srcX += ((pBox->x1 - pPriv->drw_x) * 506ad43ddacSmrg pPriv->src_w) / pPriv->dst_w; 507ad43ddacSmrg srcY = pPriv->src_y; 508ad43ddacSmrg srcY += ((pBox->y1 - pPriv->drw_y) * 509ad43ddacSmrg pPriv->src_h) / pPriv->dst_h; 510b7e1c893Smrg 511b7e1c893Smrg srcw = (pPriv->src_w * dstw) / pPriv->dst_w; 512b7e1c893Smrg srch = (pPriv->src_h * dsth) / pPriv->dst_h; 513b7e1c893Smrg 514921a55d8Smrg vb = radeon_vbo_space(pScrn, &accel_state->vbo, 16); 515ad43ddacSmrg 516b7e1c893Smrg vb[0] = (float)dstX; 517b7e1c893Smrg vb[1] = (float)dstY; 518ad43ddacSmrg vb[2] = (float)srcX; 519ad43ddacSmrg vb[3] = (float)srcY; 520b7e1c893Smrg 521b7e1c893Smrg vb[4] = (float)dstX; 522b7e1c893Smrg vb[5] = (float)(dstY + dsth); 523ad43ddacSmrg vb[6] = (float)srcX; 524ad43ddacSmrg vb[7] = (float)(srcY + srch); 525b7e1c893Smrg 526b7e1c893Smrg vb[8] = (float)(dstX + dstw); 527b7e1c893Smrg vb[9] = (float)(dstY + dsth); 528ad43ddacSmrg vb[10] = (float)(srcX + srcw); 529ad43ddacSmrg vb[11] = (float)(srcY + srch); 530b7e1c893Smrg 531921a55d8Smrg radeon_vbo_commit(pScrn, &accel_state->vbo); 532b7e1c893Smrg 533b7e1c893Smrg pBox++; 534b7e1c893Smrg } 535b7e1c893Smrg 536ad43ddacSmrg r600_finish_op(pScrn, 16); 537b7e1c893Smrg 538b7e1c893Smrg DamageDamageRegion(pPriv->pDraw, &pPriv->clip); 539b7e1c893Smrg} 540