1de2362d3Smrg/* 2de2362d3Smrg * Copyright 2008 Advanced Micro Devices, Inc. 3de2362d3Smrg * 4de2362d3Smrg * Permission is hereby granted, free of charge, to any person obtaining a 5de2362d3Smrg * copy of this software and associated documentation files (the "Software"), 6de2362d3Smrg * to deal in the Software without restriction, including without limitation 7de2362d3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8de2362d3Smrg * and/or sell copies of the Software, and to permit persons to whom the 9de2362d3Smrg * Software is furnished to do so, subject to the following conditions: 10de2362d3Smrg * 11de2362d3Smrg * The above copyright notice and this permission notice (including the next 12de2362d3Smrg * paragraph) shall be included in all copies or substantial portions of the 13de2362d3Smrg * Software. 14de2362d3Smrg * 15de2362d3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16de2362d3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17de2362d3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18de2362d3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19de2362d3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20de2362d3Smrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21de2362d3Smrg * SOFTWARE. 22de2362d3Smrg * 23de2362d3Smrg * Author: Alex Deucher <alexander.deucher@amd.com> 24de2362d3Smrg * 25de2362d3Smrg */ 26de2362d3Smrg 27de2362d3Smrg#ifdef HAVE_CONFIG_H 28de2362d3Smrg#include "config.h" 29de2362d3Smrg#endif 30de2362d3Smrg 31de2362d3Smrg#include "xf86.h" 32de2362d3Smrg 33de2362d3Smrg#include "exa.h" 34de2362d3Smrg 35de2362d3Smrg#include "radeon.h" 36de2362d3Smrg#include "radeon_reg.h" 37de2362d3Smrg#include "r600_shader.h" 38de2362d3Smrg#include "r600_reg.h" 39de2362d3Smrg#include "r600_state.h" 40de2362d3Smrg 41de2362d3Smrg#include "radeon_video.h" 42de2362d3Smrg 43de2362d3Smrg#include <X11/extensions/Xv.h> 44de2362d3Smrg#include "fourcc.h" 45de2362d3Smrg 46de2362d3Smrg#include "damage.h" 47de2362d3Smrg 48de2362d3Smrg#include "radeon_exa_shared.h" 49de2362d3Smrg#include "radeon_vbo.h" 50de2362d3Smrg 51de2362d3Smrg/* Parameters for ITU-R BT.601 and ITU-R BT.709 colour spaces 52de2362d3Smrg note the difference to the parameters used in overlay are due 53de2362d3Smrg to 10bit vs. float calcs */ 54de2362d3Smrgstatic REF_TRANSFORM trans[2] = 55de2362d3Smrg{ 56de2362d3Smrg {1.1643, 0.0, 1.5960, -0.3918, -0.8129, 2.0172, 0.0}, /* BT.601 */ 57de2362d3Smrg {1.1643, 0.0, 1.7927, -0.2132, -0.5329, 2.1124, 0.0} /* BT.709 */ 58de2362d3Smrg}; 59de2362d3Smrg 60de2362d3Smrgvoid 61de2362d3SmrgR600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) 62de2362d3Smrg{ 63de2362d3Smrg RADEONInfoPtr info = RADEONPTR(pScrn); 64de2362d3Smrg struct radeon_accel_state *accel_state = info->accel_state; 65de2362d3Smrg PixmapPtr pPixmap = pPriv->pPixmap; 66de2362d3Smrg BoxPtr pBox = REGION_RECTS(&pPriv->clip); 67de2362d3Smrg int nBox = REGION_NUM_RECTS(&pPriv->clip); 68de2362d3Smrg int dstxoff, dstyoff; 69de2362d3Smrg struct r600_accel_object src_obj, dst_obj; 70de2362d3Smrg cb_config_t cb_conf; 71de2362d3Smrg tex_resource_t tex_res; 72de2362d3Smrg tex_sampler_t tex_samp; 73de2362d3Smrg shader_config_t vs_conf, ps_conf; 74de2362d3Smrg /* 75de2362d3Smrg * y' = y - .0625 76de2362d3Smrg * u' = u - .5 77de2362d3Smrg * v' = v - .5; 78de2362d3Smrg * 79de2362d3Smrg * r = 1.1643 * y' + 0.0 * u' + 1.5958 * v' 80de2362d3Smrg * g = 1.1643 * y' - 0.39173 * u' - 0.81290 * v' 81de2362d3Smrg * b = 1.1643 * y' + 2.017 * u' + 0.0 * v' 82de2362d3Smrg * 83de2362d3Smrg * DP3 might look like the straightforward solution 84de2362d3Smrg * but we'd need to move the texture yuv values in 85de2362d3Smrg * the same reg for this to work. Therefore use MADs. 86de2362d3Smrg * Brightness just adds to the off constant. 87de2362d3Smrg * Contrast is multiplication of luminance. 88de2362d3Smrg * Saturation and hue change the u and v coeffs. 89de2362d3Smrg * Default values (before adjustments - depend on colorspace): 90de2362d3Smrg * yco = 1.1643 91de2362d3Smrg * uco = 0, -0.39173, 2.017 92de2362d3Smrg * vco = 1.5958, -0.8129, 0 93de2362d3Smrg * off = -0.0625 * yco + -0.5 * uco[r] + -0.5 * vco[r], 94de2362d3Smrg * -0.0625 * yco + -0.5 * uco[g] + -0.5 * vco[g], 95de2362d3Smrg * -0.0625 * yco + -0.5 * uco[b] + -0.5 * vco[b], 96de2362d3Smrg * 97de2362d3Smrg * temp = MAD(yco, yuv.yyyy, off) 98de2362d3Smrg * temp = MAD(uco, yuv.uuuu, temp) 99de2362d3Smrg * result = MAD(vco, yuv.vvvv, temp) 100de2362d3Smrg */ 101de2362d3Smrg /* TODO: calc consts in the shader */ 102de2362d3Smrg const float Loff = -0.0627; 103de2362d3Smrg const float Coff = -0.502; 104de2362d3Smrg float uvcosf, uvsinf; 105de2362d3Smrg float yco; 106de2362d3Smrg float uco[3], vco[3], off[3]; 107de2362d3Smrg float bright, cont, gamma; 108de2362d3Smrg int ref = pPriv->transform_index; 109de2362d3Smrg float ps_alu_consts[12]; 110de2362d3Smrg float vs_alu_consts[4]; 111de2362d3Smrg 112de2362d3Smrg cont = RTFContrast(pPriv->contrast); 113de2362d3Smrg bright = RTFBrightness(pPriv->brightness); 114de2362d3Smrg gamma = (float)pPriv->gamma / 1000.0; 115de2362d3Smrg uvcosf = RTFSaturation(pPriv->saturation) * cos(RTFHue(pPriv->hue)); 116de2362d3Smrg uvsinf = RTFSaturation(pPriv->saturation) * sin(RTFHue(pPriv->hue)); 117de2362d3Smrg /* overlay video also does pre-gamma contrast/sat adjust, should we? */ 118de2362d3Smrg 119de2362d3Smrg yco = trans[ref].RefLuma * cont; 120de2362d3Smrg uco[0] = -trans[ref].RefRCr * uvsinf; 121de2362d3Smrg uco[1] = trans[ref].RefGCb * uvcosf - trans[ref].RefGCr * uvsinf; 122de2362d3Smrg uco[2] = trans[ref].RefBCb * uvcosf; 123de2362d3Smrg vco[0] = trans[ref].RefRCr * uvcosf; 124de2362d3Smrg vco[1] = trans[ref].RefGCb * uvsinf + trans[ref].RefGCr * uvcosf; 125de2362d3Smrg vco[2] = trans[ref].RefBCb * uvsinf; 126de2362d3Smrg off[0] = Loff * yco + Coff * (uco[0] + vco[0]) + bright; 127de2362d3Smrg off[1] = Loff * yco + Coff * (uco[1] + vco[1]) + bright; 128de2362d3Smrg off[2] = Loff * yco + Coff * (uco[2] + vco[2]) + bright; 129de2362d3Smrg 130de2362d3Smrg // XXX 131de2362d3Smrg gamma = 1.0; 132de2362d3Smrg 133de2362d3Smrg /* setup the ps consts */ 134de2362d3Smrg ps_alu_consts[0] = off[0]; 135de2362d3Smrg ps_alu_consts[1] = off[1]; 136de2362d3Smrg ps_alu_consts[2] = off[2]; 137de2362d3Smrg ps_alu_consts[3] = yco; 138de2362d3Smrg 139de2362d3Smrg ps_alu_consts[4] = uco[0]; 140de2362d3Smrg ps_alu_consts[5] = uco[1]; 141de2362d3Smrg ps_alu_consts[6] = uco[2]; 142de2362d3Smrg ps_alu_consts[7] = gamma; 143de2362d3Smrg 144de2362d3Smrg ps_alu_consts[8] = vco[0]; 145de2362d3Smrg ps_alu_consts[9] = vco[1]; 146de2362d3Smrg ps_alu_consts[10] = vco[2]; 147de2362d3Smrg ps_alu_consts[11] = 0.0; 148de2362d3Smrg 149de2362d3Smrg CLEAR (cb_conf); 150de2362d3Smrg CLEAR (tex_res); 151de2362d3Smrg CLEAR (tex_samp); 152de2362d3Smrg CLEAR (vs_conf); 153de2362d3Smrg CLEAR (ps_conf); 154de2362d3Smrg 15539413783Smrg dst_obj.bo = radeon_get_pixmap_bo(pPixmap)->bo.radeon; 15618781e08Smrg dst_obj.tiling_flags = radeon_get_pixmap_tiling(pPixmap); 15718781e08Smrg dst_obj.surface = radeon_get_pixmap_surface(pPixmap); 15818781e08Smrg 159de2362d3Smrg dst_obj.pitch = exaGetPixmapPitch(pPixmap) / (pPixmap->drawable.bitsPerPixel / 8); 160de2362d3Smrg 161de2362d3Smrg src_obj.pitch = pPriv->src_pitch; 162de2362d3Smrg src_obj.width = pPriv->w; 163de2362d3Smrg src_obj.height = pPriv->h; 164de2362d3Smrg src_obj.bpp = 16; 165de2362d3Smrg src_obj.domain = RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT; 166de2362d3Smrg src_obj.bo = pPriv->src_bo[pPriv->currentBuffer]; 167de2362d3Smrg src_obj.tiling_flags = 0; 168de2362d3Smrg src_obj.surface = NULL; 169de2362d3Smrg 170de2362d3Smrg dst_obj.width = pPixmap->drawable.width; 171de2362d3Smrg dst_obj.height = pPixmap->drawable.height; 172de2362d3Smrg dst_obj.bpp = pPixmap->drawable.bitsPerPixel; 173de2362d3Smrg dst_obj.domain = RADEON_GEM_DOMAIN_VRAM; 174de2362d3Smrg 175de2362d3Smrg if (!R600SetAccelState(pScrn, 176de2362d3Smrg &src_obj, 177de2362d3Smrg NULL, 178de2362d3Smrg &dst_obj, 179de2362d3Smrg accel_state->xv_vs_offset, accel_state->xv_ps_offset, 180de2362d3Smrg 3, 0xffffffff)) 181de2362d3Smrg return; 182de2362d3Smrg 183de2362d3Smrg#ifdef COMPOSITE 184de2362d3Smrg dstxoff = -pPixmap->screen_x + pPixmap->drawable.x; 185de2362d3Smrg dstyoff = -pPixmap->screen_y + pPixmap->drawable.y; 186de2362d3Smrg#else 187de2362d3Smrg dstxoff = 0; 188de2362d3Smrg dstyoff = 0; 189de2362d3Smrg#endif 190de2362d3Smrg 191de2362d3Smrg radeon_vbo_check(pScrn, &accel_state->vbo, 16); 192de2362d3Smrg radeon_cp_start(pScrn); 193de2362d3Smrg 19418781e08Smrg r600_set_default_state(pScrn); 195de2362d3Smrg 19618781e08Smrg r600_set_generic_scissor(pScrn, 0, 0, accel_state->dst_obj.width, accel_state->dst_obj.height); 19718781e08Smrg r600_set_screen_scissor(pScrn, 0, 0, accel_state->dst_obj.width, accel_state->dst_obj.height); 19818781e08Smrg r600_set_window_scissor(pScrn, 0, 0, accel_state->dst_obj.width, accel_state->dst_obj.height); 199de2362d3Smrg 200de2362d3Smrg /* PS bool constant */ 201de2362d3Smrg switch(pPriv->id) { 202de2362d3Smrg case FOURCC_YV12: 203de2362d3Smrg case FOURCC_I420: 20418781e08Smrg r600_set_bool_consts(pScrn, SQ_BOOL_CONST_ps, (1 << 0)); 205de2362d3Smrg break; 206de2362d3Smrg case FOURCC_UYVY: 207de2362d3Smrg case FOURCC_YUY2: 208de2362d3Smrg default: 20918781e08Smrg r600_set_bool_consts(pScrn, SQ_BOOL_CONST_ps, (0 << 0)); 210de2362d3Smrg break; 211de2362d3Smrg } 212de2362d3Smrg 213de2362d3Smrg /* Shader */ 214de2362d3Smrg vs_conf.shader_addr = accel_state->vs_mc_addr; 215de2362d3Smrg vs_conf.shader_size = accel_state->vs_size; 216de2362d3Smrg vs_conf.num_gprs = 2; 217de2362d3Smrg vs_conf.stack_size = 0; 218de2362d3Smrg vs_conf.bo = accel_state->shaders_bo; 21918781e08Smrg r600_vs_setup(pScrn, &vs_conf, RADEON_GEM_DOMAIN_VRAM); 220de2362d3Smrg 221de2362d3Smrg ps_conf.shader_addr = accel_state->ps_mc_addr; 222de2362d3Smrg ps_conf.shader_size = accel_state->ps_size; 223de2362d3Smrg ps_conf.num_gprs = 3; 224de2362d3Smrg ps_conf.stack_size = 1; 225de2362d3Smrg ps_conf.uncached_first_inst = 1; 226de2362d3Smrg ps_conf.clamp_consts = 0; 227de2362d3Smrg ps_conf.export_mode = 2; 228de2362d3Smrg ps_conf.bo = accel_state->shaders_bo; 22918781e08Smrg r600_ps_setup(pScrn, &ps_conf, RADEON_GEM_DOMAIN_VRAM); 230de2362d3Smrg 231de2362d3Smrg /* PS alu constants */ 23218781e08Smrg r600_set_alu_consts(pScrn, SQ_ALU_CONSTANT_ps, 233de2362d3Smrg sizeof(ps_alu_consts) / SQ_ALU_CONSTANT_offset, ps_alu_consts); 234de2362d3Smrg 235de2362d3Smrg /* Texture */ 236de2362d3Smrg switch(pPriv->id) { 237de2362d3Smrg case FOURCC_YV12: 238de2362d3Smrg case FOURCC_I420: 239de2362d3Smrg accel_state->src_size[0] = accel_state->src_obj[0].pitch * pPriv->h; 240de2362d3Smrg 241de2362d3Smrg /* Y texture */ 242de2362d3Smrg tex_res.id = 0; 243de2362d3Smrg tex_res.w = accel_state->src_obj[0].width; 244de2362d3Smrg tex_res.h = accel_state->src_obj[0].height; 245de2362d3Smrg tex_res.pitch = accel_state->src_obj[0].pitch; 246de2362d3Smrg tex_res.depth = 0; 247de2362d3Smrg tex_res.dim = SQ_TEX_DIM_2D; 24818781e08Smrg tex_res.base = 0; 24918781e08Smrg tex_res.mip_base = 0; 250de2362d3Smrg tex_res.size = accel_state->src_size[0]; 251de2362d3Smrg tex_res.bo = accel_state->src_obj[0].bo; 252de2362d3Smrg tex_res.mip_bo = accel_state->src_obj[0].bo; 253de2362d3Smrg tex_res.surface = NULL; 254de2362d3Smrg 255de2362d3Smrg tex_res.format = FMT_8; 256de2362d3Smrg tex_res.dst_sel_x = SQ_SEL_X; /* Y */ 257de2362d3Smrg tex_res.dst_sel_y = SQ_SEL_1; 258de2362d3Smrg tex_res.dst_sel_z = SQ_SEL_1; 259de2362d3Smrg tex_res.dst_sel_w = SQ_SEL_1; 260de2362d3Smrg 261de2362d3Smrg tex_res.request_size = 1; 262de2362d3Smrg tex_res.base_level = 0; 263de2362d3Smrg tex_res.last_level = 0; 264de2362d3Smrg tex_res.perf_modulation = 0; 265de2362d3Smrg tex_res.interlaced = 0; 266de2362d3Smrg if (accel_state->src_obj[0].tiling_flags == 0) 267de2362d3Smrg tex_res.tile_mode = 1; 26818781e08Smrg r600_set_tex_resource(pScrn, &tex_res, accel_state->src_obj[0].domain); 269de2362d3Smrg 270de2362d3Smrg /* Y sampler */ 271de2362d3Smrg tex_samp.id = 0; 272de2362d3Smrg tex_samp.clamp_x = SQ_TEX_CLAMP_LAST_TEXEL; 273de2362d3Smrg tex_samp.clamp_y = SQ_TEX_CLAMP_LAST_TEXEL; 274de2362d3Smrg tex_samp.clamp_z = SQ_TEX_WRAP; 275de2362d3Smrg 276de2362d3Smrg /* xxx: switch to bicubic */ 277de2362d3Smrg tex_samp.xy_mag_filter = SQ_TEX_XY_FILTER_BILINEAR; 278de2362d3Smrg tex_samp.xy_min_filter = SQ_TEX_XY_FILTER_BILINEAR; 279de2362d3Smrg 280de2362d3Smrg tex_samp.z_filter = SQ_TEX_Z_FILTER_NONE; 281de2362d3Smrg tex_samp.mip_filter = 0; /* no mipmap */ 28218781e08Smrg r600_set_tex_sampler(pScrn, &tex_samp); 283de2362d3Smrg 284de2362d3Smrg /* U or V texture */ 285de2362d3Smrg tex_res.id = 1; 286de2362d3Smrg tex_res.format = FMT_8; 287de2362d3Smrg tex_res.w = accel_state->src_obj[0].width >> 1; 288de2362d3Smrg tex_res.h = accel_state->src_obj[0].height >> 1; 289de2362d3Smrg tex_res.pitch = RADEON_ALIGN(accel_state->src_obj[0].pitch >> 1, pPriv->hw_align); 290de2362d3Smrg tex_res.dst_sel_x = SQ_SEL_X; /* V or U */ 291de2362d3Smrg tex_res.dst_sel_y = SQ_SEL_1; 292de2362d3Smrg tex_res.dst_sel_z = SQ_SEL_1; 293de2362d3Smrg tex_res.dst_sel_w = SQ_SEL_1; 294de2362d3Smrg tex_res.interlaced = 0; 295de2362d3Smrg 29618781e08Smrg tex_res.base = pPriv->planev_offset; 29718781e08Smrg tex_res.mip_base = pPriv->planev_offset; 298de2362d3Smrg tex_res.size = tex_res.pitch * (pPriv->h >> 1); 299de2362d3Smrg if (accel_state->src_obj[0].tiling_flags == 0) 300de2362d3Smrg tex_res.tile_mode = 1; 30118781e08Smrg r600_set_tex_resource(pScrn, &tex_res, accel_state->src_obj[0].domain); 302de2362d3Smrg 303de2362d3Smrg /* U or V sampler */ 304de2362d3Smrg tex_samp.id = 1; 30518781e08Smrg r600_set_tex_sampler(pScrn, &tex_samp); 306de2362d3Smrg 307de2362d3Smrg /* U or V texture */ 308de2362d3Smrg tex_res.id = 2; 309de2362d3Smrg tex_res.format = FMT_8; 310de2362d3Smrg tex_res.w = accel_state->src_obj[0].width >> 1; 311de2362d3Smrg tex_res.h = accel_state->src_obj[0].height >> 1; 312de2362d3Smrg tex_res.pitch = RADEON_ALIGN(accel_state->src_obj[0].pitch >> 1, pPriv->hw_align); 313de2362d3Smrg tex_res.dst_sel_x = SQ_SEL_X; /* V or U */ 314de2362d3Smrg tex_res.dst_sel_y = SQ_SEL_1; 315de2362d3Smrg tex_res.dst_sel_z = SQ_SEL_1; 316de2362d3Smrg tex_res.dst_sel_w = SQ_SEL_1; 317de2362d3Smrg tex_res.interlaced = 0; 318de2362d3Smrg 31918781e08Smrg tex_res.base = pPriv->planeu_offset; 32018781e08Smrg tex_res.mip_base = pPriv->planeu_offset; 321de2362d3Smrg tex_res.size = tex_res.pitch * (pPriv->h >> 1); 322de2362d3Smrg if (accel_state->src_obj[0].tiling_flags == 0) 323de2362d3Smrg tex_res.tile_mode = 1; 32418781e08Smrg r600_set_tex_resource(pScrn, &tex_res, accel_state->src_obj[0].domain); 325de2362d3Smrg 326de2362d3Smrg /* UV sampler */ 327de2362d3Smrg tex_samp.id = 2; 32818781e08Smrg r600_set_tex_sampler(pScrn, &tex_samp); 329de2362d3Smrg break; 330de2362d3Smrg case FOURCC_UYVY: 331de2362d3Smrg case FOURCC_YUY2: 332de2362d3Smrg default: 333de2362d3Smrg accel_state->src_size[0] = accel_state->src_obj[0].pitch * pPriv->h; 334de2362d3Smrg 335de2362d3Smrg /* YUV texture */ 336de2362d3Smrg tex_res.id = 0; 337de2362d3Smrg tex_res.w = accel_state->src_obj[0].width; 338de2362d3Smrg tex_res.h = accel_state->src_obj[0].height; 339de2362d3Smrg tex_res.pitch = accel_state->src_obj[0].pitch >> 1; 340de2362d3Smrg tex_res.depth = 0; 341de2362d3Smrg tex_res.dim = SQ_TEX_DIM_2D; 34218781e08Smrg tex_res.base = 0; 34318781e08Smrg tex_res.mip_base = 0; 344de2362d3Smrg tex_res.size = accel_state->src_size[0]; 345de2362d3Smrg tex_res.bo = accel_state->src_obj[0].bo; 346de2362d3Smrg tex_res.mip_bo = accel_state->src_obj[0].bo; 347de2362d3Smrg 348de2362d3Smrg if (pPriv->id == FOURCC_UYVY) 349de2362d3Smrg tex_res.format = FMT_GB_GR; 350de2362d3Smrg else 351de2362d3Smrg tex_res.format = FMT_BG_RG; 352de2362d3Smrg tex_res.dst_sel_x = SQ_SEL_Y; 353de2362d3Smrg tex_res.dst_sel_y = SQ_SEL_X; 354de2362d3Smrg tex_res.dst_sel_z = SQ_SEL_Z; 355de2362d3Smrg tex_res.dst_sel_w = SQ_SEL_1; 356de2362d3Smrg 357de2362d3Smrg tex_res.request_size = 1; 358de2362d3Smrg tex_res.base_level = 0; 359de2362d3Smrg tex_res.last_level = 0; 360de2362d3Smrg tex_res.perf_modulation = 0; 361de2362d3Smrg tex_res.interlaced = 0; 362de2362d3Smrg if (accel_state->src_obj[0].tiling_flags == 0) 363de2362d3Smrg tex_res.tile_mode = 1; 36418781e08Smrg r600_set_tex_resource(pScrn, &tex_res, accel_state->src_obj[0].domain); 365de2362d3Smrg 366de2362d3Smrg /* YUV sampler */ 367de2362d3Smrg tex_samp.id = 0; 368de2362d3Smrg tex_samp.clamp_x = SQ_TEX_CLAMP_LAST_TEXEL; 369de2362d3Smrg tex_samp.clamp_y = SQ_TEX_CLAMP_LAST_TEXEL; 370de2362d3Smrg tex_samp.clamp_z = SQ_TEX_WRAP; 371de2362d3Smrg 372de2362d3Smrg /* xxx: switch to bicubic */ 373de2362d3Smrg tex_samp.xy_mag_filter = SQ_TEX_XY_FILTER_BILINEAR; 374de2362d3Smrg tex_samp.xy_min_filter = SQ_TEX_XY_FILTER_BILINEAR; 375de2362d3Smrg 376de2362d3Smrg tex_samp.z_filter = SQ_TEX_Z_FILTER_NONE; 377de2362d3Smrg tex_samp.mip_filter = 0; /* no mipmap */ 37818781e08Smrg r600_set_tex_sampler(pScrn, &tex_samp); 379de2362d3Smrg 380de2362d3Smrg break; 381de2362d3Smrg } 382de2362d3Smrg 383de2362d3Smrg cb_conf.id = 0; 384de2362d3Smrg cb_conf.w = accel_state->dst_obj.pitch; 385de2362d3Smrg cb_conf.h = accel_state->dst_obj.height; 38618781e08Smrg cb_conf.base = 0; 387de2362d3Smrg cb_conf.bo = accel_state->dst_obj.bo; 388de2362d3Smrg cb_conf.surface = accel_state->dst_obj.surface; 389de2362d3Smrg 390de2362d3Smrg switch (accel_state->dst_obj.bpp) { 391de2362d3Smrg case 16: 392de2362d3Smrg if (pPixmap->drawable.depth == 15) { 393de2362d3Smrg cb_conf.format = COLOR_1_5_5_5; 394de2362d3Smrg cb_conf.comp_swap = 1; /* ARGB */ 395de2362d3Smrg } else { 396de2362d3Smrg cb_conf.format = COLOR_5_6_5; 397de2362d3Smrg cb_conf.comp_swap = 2; /* RGB */ 398de2362d3Smrg } 399de2362d3Smrg#if X_BYTE_ORDER == X_BIG_ENDIAN 400de2362d3Smrg cb_conf.endian = ENDIAN_8IN16; 401de2362d3Smrg#endif 402de2362d3Smrg break; 403de2362d3Smrg case 32: 404de2362d3Smrg cb_conf.format = COLOR_8_8_8_8; 405de2362d3Smrg cb_conf.comp_swap = 1; /* ARGB */ 406de2362d3Smrg#if X_BYTE_ORDER == X_BIG_ENDIAN 407de2362d3Smrg cb_conf.endian = ENDIAN_8IN32; 408de2362d3Smrg#endif 409de2362d3Smrg break; 410de2362d3Smrg default: 411de2362d3Smrg return; 412de2362d3Smrg } 413de2362d3Smrg 414de2362d3Smrg cb_conf.source_format = 1; 415de2362d3Smrg cb_conf.blend_clamp = 1; 416de2362d3Smrg cb_conf.pmask = 0xf; 417de2362d3Smrg cb_conf.rop = 3; 418de2362d3Smrg if (accel_state->dst_obj.tiling_flags == 0) 419de2362d3Smrg cb_conf.array_mode = 1; 42018781e08Smrg r600_set_render_target(pScrn, &cb_conf, accel_state->dst_obj.domain); 421de2362d3Smrg 42218781e08Smrg r600_set_spi(pScrn, (1 - 1), 1); 423de2362d3Smrg 424de2362d3Smrg vs_alu_consts[0] = 1.0 / pPriv->w; 425de2362d3Smrg vs_alu_consts[1] = 1.0 / pPriv->h; 426de2362d3Smrg vs_alu_consts[2] = 0.0; 427de2362d3Smrg vs_alu_consts[3] = 0.0; 428de2362d3Smrg 429de2362d3Smrg /* VS alu constants */ 43018781e08Smrg r600_set_alu_consts(pScrn, SQ_ALU_CONSTANT_vs, 431de2362d3Smrg sizeof(vs_alu_consts) / SQ_ALU_CONSTANT_offset, vs_alu_consts); 432de2362d3Smrg 433de2362d3Smrg if (pPriv->vsync) { 434de2362d3Smrg xf86CrtcPtr crtc; 435de2362d3Smrg if (pPriv->desired_crtc) 436de2362d3Smrg crtc = pPriv->desired_crtc; 437de2362d3Smrg else 43818781e08Smrg crtc = radeon_pick_best_crtc(pScrn, FALSE, 439de2362d3Smrg pPriv->drw_x, 440de2362d3Smrg pPriv->drw_x + pPriv->dst_w, 441de2362d3Smrg pPriv->drw_y, 442de2362d3Smrg pPriv->drw_y + pPriv->dst_h); 443de2362d3Smrg if (crtc) 44418781e08Smrg r600_cp_wait_vline_sync(pScrn, pPixmap, 445de2362d3Smrg crtc, 446de2362d3Smrg pPriv->drw_y - crtc->y, 447de2362d3Smrg (pPriv->drw_y - crtc->y) + pPriv->dst_h); 448de2362d3Smrg } 449de2362d3Smrg 450de2362d3Smrg while (nBox--) { 451de2362d3Smrg float srcX, srcY, srcw, srch; 452de2362d3Smrg int dstX, dstY, dstw, dsth; 453de2362d3Smrg float *vb; 454de2362d3Smrg 455de2362d3Smrg 456de2362d3Smrg dstX = pBox->x1 + dstxoff; 457de2362d3Smrg dstY = pBox->y1 + dstyoff; 458de2362d3Smrg dstw = pBox->x2 - pBox->x1; 459de2362d3Smrg dsth = pBox->y2 - pBox->y1; 460de2362d3Smrg 461de2362d3Smrg srcX = pPriv->src_x; 462de2362d3Smrg srcX += ((pBox->x1 - pPriv->drw_x) * 463de2362d3Smrg pPriv->src_w) / (float)pPriv->dst_w; 464de2362d3Smrg srcY = pPriv->src_y; 465de2362d3Smrg srcY += ((pBox->y1 - pPriv->drw_y) * 466de2362d3Smrg pPriv->src_h) / (float)pPriv->dst_h; 467de2362d3Smrg 468de2362d3Smrg srcw = (pPriv->src_w * dstw) / (float)pPriv->dst_w; 469de2362d3Smrg srch = (pPriv->src_h * dsth) / (float)pPriv->dst_h; 470de2362d3Smrg 471de2362d3Smrg vb = radeon_vbo_space(pScrn, &accel_state->vbo, 16); 472de2362d3Smrg 473de2362d3Smrg vb[0] = (float)dstX; 474de2362d3Smrg vb[1] = (float)dstY; 475de2362d3Smrg vb[2] = (float)srcX; 476de2362d3Smrg vb[3] = (float)srcY; 477de2362d3Smrg 478de2362d3Smrg vb[4] = (float)dstX; 479de2362d3Smrg vb[5] = (float)(dstY + dsth); 480de2362d3Smrg vb[6] = (float)srcX; 481de2362d3Smrg vb[7] = (float)(srcY + srch); 482de2362d3Smrg 483de2362d3Smrg vb[8] = (float)(dstX + dstw); 484de2362d3Smrg vb[9] = (float)(dstY + dsth); 485de2362d3Smrg vb[10] = (float)(srcX + srcw); 486de2362d3Smrg vb[11] = (float)(srcY + srch); 487de2362d3Smrg 488de2362d3Smrg radeon_vbo_commit(pScrn, &accel_state->vbo); 489de2362d3Smrg 490de2362d3Smrg pBox++; 491de2362d3Smrg } 492de2362d3Smrg 493de2362d3Smrg r600_finish_op(pScrn, 16); 494de2362d3Smrg 495de2362d3Smrg DamageDamageRegion(pPriv->pDraw, &pPriv->clip); 496de2362d3Smrg} 497