r600_textured_videofuncs.c revision 0974d292
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 209ad43ddacSmrg radeon_vbo_check(pScrn, 16); 2100974d292Smrg radeon_cp_start(pScrn); 211b7e1c893Smrg 212b7e1c893Smrg set_default_state(pScrn, accel_state->ib); 213b7e1c893Smrg 214ad43ddacSmrg set_generic_scissor(pScrn, accel_state->ib, 0, 0, accel_state->dst_obj.width, accel_state->dst_obj.height); 215ad43ddacSmrg set_screen_scissor(pScrn, accel_state->ib, 0, 0, accel_state->dst_obj.width, accel_state->dst_obj.height); 216ad43ddacSmrg 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: 222b7e1c893Smrg 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: 227b7e1c893Smrg 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; 237ad43ddacSmrg 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; 247ad43ddacSmrg ps_setup (pScrn, accel_state->ib, &ps_conf, RADEON_GEM_DOMAIN_VRAM); 248b7e1c893Smrg 249b7e1c893Smrg /* PS alu constants */ 250b7e1c893Smrg set_alu_consts(pScrn, accel_state->ib, SQ_ALU_CONSTANT_ps, 251b7e1c893Smrg 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; 283ad43ddacSmrg set_tex_resource (pScrn, accel_state->ib, &tex_res, accel_state->src_obj[0].domain); 284b7e1c893Smrg 285b7e1c893Smrg /* Y sampler */ 286b7e1c893Smrg tex_samp.id = 0; 287b7e1c893Smrg tex_samp.clamp_x = SQ_TEX_CLAMP_LAST_TEXEL; 288b7e1c893Smrg tex_samp.clamp_y = SQ_TEX_CLAMP_LAST_TEXEL; 289b7e1c893Smrg tex_samp.clamp_z = SQ_TEX_WRAP; 290b7e1c893Smrg 291b7e1c893Smrg /* xxx: switch to bicubic */ 292b7e1c893Smrg tex_samp.xy_mag_filter = SQ_TEX_XY_FILTER_BILINEAR; 293b7e1c893Smrg tex_samp.xy_min_filter = SQ_TEX_XY_FILTER_BILINEAR; 294b7e1c893Smrg 295b7e1c893Smrg tex_samp.z_filter = SQ_TEX_Z_FILTER_NONE; 296b7e1c893Smrg tex_samp.mip_filter = 0; /* no mipmap */ 297b7e1c893Smrg set_tex_sampler (pScrn, accel_state->ib, &tex_samp); 298b7e1c893Smrg 299b7e1c893Smrg /* U or V texture */ 300b7e1c893Smrg tex_res.id = 1; 301b7e1c893Smrg tex_res.format = FMT_8; 302ad43ddacSmrg tex_res.w = accel_state->src_obj[0].width >> 1; 303ad43ddacSmrg tex_res.h = accel_state->src_obj[0].height >> 1; 304ad43ddacSmrg tex_res.pitch = RADEON_ALIGN(accel_state->src_obj[0].pitch >> 1, 256); 305b7e1c893Smrg tex_res.dst_sel_x = SQ_SEL_X; /* V or U */ 306b7e1c893Smrg tex_res.dst_sel_y = SQ_SEL_1; 307b7e1c893Smrg tex_res.dst_sel_z = SQ_SEL_1; 308b7e1c893Smrg tex_res.dst_sel_w = SQ_SEL_1; 309b7e1c893Smrg tex_res.interlaced = 0; 310b7e1c893Smrg 311ad43ddacSmrg tex_res.base = accel_state->src_obj[0].offset + pPriv->planev_offset; 312ad43ddacSmrg tex_res.mip_base = accel_state->src_obj[0].offset + pPriv->planev_offset; 3130974d292Smrg tex_res.size = accel_state->src_size[0] / 4; 314ad43ddacSmrg set_tex_resource (pScrn, accel_state->ib, &tex_res, accel_state->src_obj[0].domain); 315b7e1c893Smrg 316b7e1c893Smrg /* U or V sampler */ 317b7e1c893Smrg tex_samp.id = 1; 318b7e1c893Smrg set_tex_sampler (pScrn, accel_state->ib, &tex_samp); 319b7e1c893Smrg 320b7e1c893Smrg /* U or V texture */ 321b7e1c893Smrg tex_res.id = 2; 322b7e1c893Smrg tex_res.format = FMT_8; 323ad43ddacSmrg tex_res.w = accel_state->src_obj[0].width >> 1; 324ad43ddacSmrg tex_res.h = accel_state->src_obj[0].height >> 1; 325ad43ddacSmrg tex_res.pitch = RADEON_ALIGN(accel_state->src_obj[0].pitch >> 1, 256); 326b7e1c893Smrg tex_res.dst_sel_x = SQ_SEL_X; /* V or U */ 327b7e1c893Smrg tex_res.dst_sel_y = SQ_SEL_1; 328b7e1c893Smrg tex_res.dst_sel_z = SQ_SEL_1; 329b7e1c893Smrg tex_res.dst_sel_w = SQ_SEL_1; 330b7e1c893Smrg tex_res.interlaced = 0; 331b7e1c893Smrg 332ad43ddacSmrg tex_res.base = accel_state->src_obj[0].offset + pPriv->planeu_offset; 333ad43ddacSmrg tex_res.mip_base = accel_state->src_obj[0].offset + pPriv->planeu_offset; 3340974d292Smrg tex_res.size = accel_state->src_size[0] / 4; 335ad43ddacSmrg set_tex_resource (pScrn, accel_state->ib, &tex_res, accel_state->src_obj[0].domain); 336b7e1c893Smrg 337b7e1c893Smrg /* UV sampler */ 338b7e1c893Smrg tex_samp.id = 2; 339b7e1c893Smrg set_tex_sampler (pScrn, accel_state->ib, &tex_samp); 340b7e1c893Smrg break; 341b7e1c893Smrg case FOURCC_UYVY: 342b7e1c893Smrg case FOURCC_YUY2: 343b7e1c893Smrg default: 344ad43ddacSmrg accel_state->src_size[0] = accel_state->src_obj[0].pitch * pPriv->h; 345b7e1c893Smrg 346b7e1c893Smrg /* Y texture */ 347b7e1c893Smrg tex_res.id = 0; 348ad43ddacSmrg tex_res.w = accel_state->src_obj[0].width; 349ad43ddacSmrg tex_res.h = accel_state->src_obj[0].height; 350ad43ddacSmrg tex_res.pitch = accel_state->src_obj[0].pitch >> 1; 351b7e1c893Smrg tex_res.depth = 0; 352b7e1c893Smrg tex_res.dim = SQ_TEX_DIM_2D; 353ad43ddacSmrg tex_res.base = accel_state->src_obj[0].offset; 354ad43ddacSmrg tex_res.mip_base = accel_state->src_obj[0].offset; 3550974d292Smrg tex_res.size = accel_state->src_size[0]; 356ad43ddacSmrg tex_res.bo = accel_state->src_obj[0].bo; 357ad43ddacSmrg tex_res.mip_bo = accel_state->src_obj[0].bo; 358b7e1c893Smrg 359b7e1c893Smrg tex_res.format = FMT_8_8; 360b7e1c893Smrg if (pPriv->id == FOURCC_UYVY) 361b7e1c893Smrg tex_res.dst_sel_x = SQ_SEL_Y; /* Y */ 362b7e1c893Smrg else 363b7e1c893Smrg tex_res.dst_sel_x = SQ_SEL_X; /* Y */ 364b7e1c893Smrg tex_res.dst_sel_y = SQ_SEL_1; 365b7e1c893Smrg tex_res.dst_sel_z = SQ_SEL_1; 366b7e1c893Smrg tex_res.dst_sel_w = SQ_SEL_1; 367b7e1c893Smrg 368b7e1c893Smrg tex_res.request_size = 1; 369b7e1c893Smrg tex_res.base_level = 0; 370b7e1c893Smrg tex_res.last_level = 0; 371b7e1c893Smrg tex_res.perf_modulation = 0; 372b7e1c893Smrg tex_res.interlaced = 0; 373ad43ddacSmrg set_tex_resource (pScrn, accel_state->ib, &tex_res, accel_state->src_obj[0].domain); 374b7e1c893Smrg 375b7e1c893Smrg /* Y sampler */ 376b7e1c893Smrg tex_samp.id = 0; 377b7e1c893Smrg tex_samp.clamp_x = SQ_TEX_CLAMP_LAST_TEXEL; 378b7e1c893Smrg tex_samp.clamp_y = SQ_TEX_CLAMP_LAST_TEXEL; 379b7e1c893Smrg tex_samp.clamp_z = SQ_TEX_WRAP; 380b7e1c893Smrg 381b7e1c893Smrg /* xxx: switch to bicubic */ 382b7e1c893Smrg tex_samp.xy_mag_filter = SQ_TEX_XY_FILTER_BILINEAR; 383b7e1c893Smrg tex_samp.xy_min_filter = SQ_TEX_XY_FILTER_BILINEAR; 384b7e1c893Smrg 385b7e1c893Smrg tex_samp.z_filter = SQ_TEX_Z_FILTER_NONE; 386b7e1c893Smrg tex_samp.mip_filter = 0; /* no mipmap */ 387b7e1c893Smrg set_tex_sampler (pScrn, accel_state->ib, &tex_samp); 388b7e1c893Smrg 389b7e1c893Smrg /* UV texture */ 390b7e1c893Smrg tex_res.id = 1; 391b7e1c893Smrg tex_res.format = FMT_8_8_8_8; 392ad43ddacSmrg tex_res.w = accel_state->src_obj[0].width >> 1; 393ad43ddacSmrg tex_res.h = accel_state->src_obj[0].height; 394ad43ddacSmrg tex_res.pitch = accel_state->src_obj[0].pitch >> 2; 395b7e1c893Smrg if (pPriv->id == FOURCC_UYVY) { 396b7e1c893Smrg tex_res.dst_sel_x = SQ_SEL_X; /* V */ 397b7e1c893Smrg tex_res.dst_sel_y = SQ_SEL_Z; /* U */ 398b7e1c893Smrg } else { 399b7e1c893Smrg tex_res.dst_sel_x = SQ_SEL_Y; /* V */ 400b7e1c893Smrg tex_res.dst_sel_y = SQ_SEL_W; /* U */ 401b7e1c893Smrg } 402b7e1c893Smrg tex_res.dst_sel_z = SQ_SEL_1; 403b7e1c893Smrg tex_res.dst_sel_w = SQ_SEL_1; 404b7e1c893Smrg tex_res.interlaced = 0; 405b7e1c893Smrg 406ad43ddacSmrg tex_res.base = accel_state->src_obj[0].offset; 407ad43ddacSmrg tex_res.mip_base = accel_state->src_obj[0].offset; 4080974d292Smrg tex_res.size = accel_state->src_size[0]; 409ad43ddacSmrg set_tex_resource (pScrn, accel_state->ib, &tex_res, accel_state->src_obj[0].domain); 410b7e1c893Smrg 411b7e1c893Smrg /* UV sampler */ 412b7e1c893Smrg tex_samp.id = 1; 413b7e1c893Smrg set_tex_sampler (pScrn, accel_state->ib, &tex_samp); 414b7e1c893Smrg break; 415b7e1c893Smrg } 416b7e1c893Smrg 417b7e1c893Smrg cb_conf.id = 0; 418ad43ddacSmrg cb_conf.w = accel_state->dst_obj.pitch; 419ad43ddacSmrg cb_conf.h = accel_state->dst_obj.height; 420ad43ddacSmrg cb_conf.base = accel_state->dst_obj.offset; 421ad43ddacSmrg cb_conf.bo = accel_state->dst_obj.bo; 422b7e1c893Smrg 423ad43ddacSmrg switch (accel_state->dst_obj.bpp) { 424b7e1c893Smrg case 16: 425b7e1c893Smrg if (pPixmap->drawable.depth == 15) { 426b7e1c893Smrg cb_conf.format = COLOR_1_5_5_5; 427b7e1c893Smrg cb_conf.comp_swap = 1; /* ARGB */ 428b7e1c893Smrg } else { 429b7e1c893Smrg cb_conf.format = COLOR_5_6_5; 430b7e1c893Smrg cb_conf.comp_swap = 2; /* RGB */ 431b7e1c893Smrg } 432b7e1c893Smrg break; 433b7e1c893Smrg case 32: 434b7e1c893Smrg cb_conf.format = COLOR_8_8_8_8; 435b7e1c893Smrg cb_conf.comp_swap = 1; /* ARGB */ 436b7e1c893Smrg break; 437b7e1c893Smrg default: 438b7e1c893Smrg return; 439b7e1c893Smrg } 440b7e1c893Smrg 441b7e1c893Smrg cb_conf.source_format = 1; 442b7e1c893Smrg cb_conf.blend_clamp = 1; 443ad43ddacSmrg set_render_target(pScrn, accel_state->ib, &cb_conf, accel_state->dst_obj.domain); 444b7e1c893Smrg 4450974d292Smrg /* Render setup */ 4460974d292Smrg BEGIN_BATCH(20); 4470974d292Smrg EREG(accel_state->ib, CB_TARGET_MASK, (0x0f << TARGET0_ENABLE_shift)); 4480974d292Smrg EREG(accel_state->ib, CB_COLOR_CONTROL, (0xcc << ROP3_shift)); /* copy */ 4490974d292Smrg 450b7e1c893Smrg /* Interpolator setup */ 451b7e1c893Smrg /* export tex coords from VS */ 452b7e1c893Smrg EREG(accel_state->ib, SPI_VS_OUT_CONFIG, ((1 - 1) << VS_EXPORT_COUNT_shift)); 453b7e1c893Smrg EREG(accel_state->ib, SPI_VS_OUT_ID_0, (0 << SEMANTIC_0_shift)); 4540974d292Smrg EREG(accel_state->ib, SPI_PS_INPUT_CNTL_0 + (0 << 2), ((0 << SEMANTIC_shift) | 4550974d292Smrg (0x03 << DEFAULT_VAL_shift) | 4560974d292Smrg SEL_CENTROID_bit)); 457b7e1c893Smrg 458b7e1c893Smrg /* Enabling flat shading needs both FLAT_SHADE_bit in SPI_PS_INPUT_CNTL_x 459b7e1c893Smrg * *and* FLAT_SHADE_ENA_bit in SPI_INTERP_CONTROL_0 */ 4600974d292Smrg PACK0(accel_state->ib, SPI_PS_IN_CONTROL_0, 3); 4610974d292Smrg E32(accel_state->ib, ((1 << NUM_INTERP_shift))); 4620974d292Smrg E32(accel_state->ib, 0); 4630974d292Smrg E32(accel_state->ib, 0); 464ad43ddacSmrg END_BATCH(); 465b7e1c893Smrg 466ad43ddacSmrg vs_alu_consts[0] = 1.0 / pPriv->w; 467ad43ddacSmrg vs_alu_consts[1] = 1.0 / pPriv->h; 468ad43ddacSmrg vs_alu_consts[2] = 0.0; 469ad43ddacSmrg vs_alu_consts[3] = 0.0; 470b7e1c893Smrg 471ad43ddacSmrg /* VS alu constants */ 472ad43ddacSmrg set_alu_consts(pScrn, accel_state->ib, SQ_ALU_CONSTANT_vs, 473ad43ddacSmrg sizeof(vs_alu_consts) / SQ_ALU_CONSTANT_offset, vs_alu_consts); 474b7e1c893Smrg 475ad43ddacSmrg if (pPriv->vsync) { 476ad43ddacSmrg xf86CrtcPtr crtc; 477ad43ddacSmrg if (pPriv->desired_crtc) 478ad43ddacSmrg crtc = pPriv->desired_crtc; 479ad43ddacSmrg else 480ad43ddacSmrg crtc = radeon_pick_best_crtc(pScrn, 481ad43ddacSmrg pPriv->drw_x, 482ad43ddacSmrg pPriv->drw_x + pPriv->dst_w, 483ad43ddacSmrg pPriv->drw_y, 484ad43ddacSmrg pPriv->drw_y + pPriv->dst_h); 485ad43ddacSmrg if (crtc) 486b7e1c893Smrg cp_wait_vline_sync(pScrn, accel_state->ib, pPixmap, 487ad43ddacSmrg crtc, 488b7e1c893Smrg pPriv->drw_y - crtc->y, 489b7e1c893Smrg (pPriv->drw_y - crtc->y) + pPriv->dst_h); 490b7e1c893Smrg } 491b7e1c893Smrg 492b7e1c893Smrg while (nBox--) { 493b7e1c893Smrg int srcX, srcY, srcw, srch; 494b7e1c893Smrg int dstX, dstY, dstw, dsth; 495b7e1c893Smrg float *vb; 496b7e1c893Smrg 497b7e1c893Smrg 498b7e1c893Smrg dstX = pBox->x1 + dstxoff; 499b7e1c893Smrg dstY = pBox->y1 + dstyoff; 500b7e1c893Smrg dstw = pBox->x2 - pBox->x1; 501b7e1c893Smrg dsth = pBox->y2 - pBox->y1; 502b7e1c893Smrg 503ad43ddacSmrg srcX = pPriv->src_x; 504ad43ddacSmrg srcX += ((pBox->x1 - pPriv->drw_x) * 505ad43ddacSmrg pPriv->src_w) / pPriv->dst_w; 506ad43ddacSmrg srcY = pPriv->src_y; 507ad43ddacSmrg srcY += ((pBox->y1 - pPriv->drw_y) * 508ad43ddacSmrg pPriv->src_h) / pPriv->dst_h; 509b7e1c893Smrg 510b7e1c893Smrg srcw = (pPriv->src_w * dstw) / pPriv->dst_w; 511b7e1c893Smrg srch = (pPriv->src_h * dsth) / pPriv->dst_h; 512b7e1c893Smrg 513ad43ddacSmrg vb = radeon_vbo_space(pScrn, 16); 514ad43ddacSmrg 515b7e1c893Smrg vb[0] = (float)dstX; 516b7e1c893Smrg vb[1] = (float)dstY; 517ad43ddacSmrg vb[2] = (float)srcX; 518ad43ddacSmrg vb[3] = (float)srcY; 519b7e1c893Smrg 520b7e1c893Smrg vb[4] = (float)dstX; 521b7e1c893Smrg vb[5] = (float)(dstY + dsth); 522ad43ddacSmrg vb[6] = (float)srcX; 523ad43ddacSmrg vb[7] = (float)(srcY + srch); 524b7e1c893Smrg 525b7e1c893Smrg vb[8] = (float)(dstX + dstw); 526b7e1c893Smrg vb[9] = (float)(dstY + dsth); 527ad43ddacSmrg vb[10] = (float)(srcX + srcw); 528ad43ddacSmrg vb[11] = (float)(srcY + srch); 529b7e1c893Smrg 530ad43ddacSmrg radeon_vbo_commit(pScrn); 531b7e1c893Smrg 532b7e1c893Smrg pBox++; 533b7e1c893Smrg } 534b7e1c893Smrg 535ad43ddacSmrg r600_finish_op(pScrn, 16); 536b7e1c893Smrg 537b7e1c893Smrg DamageDamageRegion(pPriv->pDraw, &pPriv->clip); 538b7e1c893Smrg} 539