radeon_exa_shared.c revision 0974d292
10974d292Smrg/* 20974d292Smrg * Copyright 2005 Eric Anholt 30974d292Smrg * Copyright 2005 Benjamin Herrenschmidt 40974d292Smrg * Copyright 2008 Advanced Micro Devices, Inc. 50974d292Smrg * All Rights Reserved. 60974d292Smrg * 70974d292Smrg * Permission is hereby granted, free of charge, to any person obtaining a 80974d292Smrg * copy of this software and associated documentation files (the "Software"), 90974d292Smrg * to deal in the Software without restriction, including without limitation 100974d292Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 110974d292Smrg * and/or sell copies of the Software, and to permit persons to whom the 120974d292Smrg * Software is furnished to do so, subject to the following conditions: 130974d292Smrg * 140974d292Smrg * The above copyright notice and this permission notice (including the next 150974d292Smrg * paragraph) shall be included in all copies or substantial portions of the 160974d292Smrg * Software. 170974d292Smrg * 180974d292Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 190974d292Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 200974d292Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 210974d292Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 220974d292Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 230974d292Smrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 240974d292Smrg * SOFTWARE. 250974d292Smrg * 260974d292Smrg * Authors: 270974d292Smrg * Eric Anholt <anholt@FreeBSD.org> 280974d292Smrg * Zack Rusin <zrusin@trolltech.com> 290974d292Smrg * Benjamin Herrenschmidt <benh@kernel.crashing.org> 300974d292Smrg * Alex Deucher <alexander.deucher@amd.com> 310974d292Smrg * Matthias Hopf <mhopf@suse.de> 320974d292Smrg */ 330974d292Smrg#ifdef HAVE_CONFIG_H 340974d292Smrg#include "config.h" 350974d292Smrg#endif 360974d292Smrg 370974d292Smrg#include "radeon.h" 380974d292Smrg#ifdef XF86DRI 390974d292Smrg#include "radeon_drm.h" 400974d292Smrg#endif 410974d292Smrg#include "radeon_macros.h" 420974d292Smrg#include "radeon_probe.h" 430974d292Smrg#include "radeon_version.h" 440974d292Smrg#include "radeon_vbo.h" 450974d292Smrg 460974d292SmrgPixmapPtr 470974d292SmrgRADEONGetDrawablePixmap(DrawablePtr pDrawable) 480974d292Smrg{ 490974d292Smrg if (pDrawable->type == DRAWABLE_WINDOW) 500974d292Smrg return pDrawable->pScreen->GetWindowPixmap((WindowPtr)pDrawable); 510974d292Smrg else 520974d292Smrg return (PixmapPtr)pDrawable; 530974d292Smrg} 540974d292Smrg 550974d292Smrgvoid RADEONVlineHelperClear(ScrnInfoPtr pScrn) 560974d292Smrg{ 570974d292Smrg RADEONInfoPtr info = RADEONPTR(pScrn); 580974d292Smrg struct radeon_accel_state *accel_state = info->accel_state; 590974d292Smrg 600974d292Smrg accel_state->vline_crtc = NULL; 610974d292Smrg accel_state->vline_y1 = -1; 620974d292Smrg accel_state->vline_y2 = 0; 630974d292Smrg} 640974d292Smrg 650974d292Smrgvoid RADEONVlineHelperSet(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2) 660974d292Smrg{ 670974d292Smrg RADEONInfoPtr info = RADEONPTR(pScrn); 680974d292Smrg struct radeon_accel_state *accel_state = info->accel_state; 690974d292Smrg 700974d292Smrg accel_state->vline_crtc = radeon_pick_best_crtc(pScrn, x1, x2, y1, y2); 710974d292Smrg if (accel_state->vline_y1 == -1) 720974d292Smrg accel_state->vline_y1 = y1; 730974d292Smrg if (y1 < accel_state->vline_y1) 740974d292Smrg accel_state->vline_y1 = y1; 750974d292Smrg if (y2 > accel_state->vline_y2) 760974d292Smrg accel_state->vline_y2 = y2; 770974d292Smrg} 780974d292Smrg 790974d292SmrgBool RADEONValidPM(uint32_t pm, int bpp) 800974d292Smrg{ 810974d292Smrg uint8_t r, g, b, a; 820974d292Smrg Bool ret = FALSE; 830974d292Smrg 840974d292Smrg switch (bpp) { 850974d292Smrg case 8: 860974d292Smrg a = pm & 0xff; 870974d292Smrg if ((a == 0) || (a == 0xff)) 880974d292Smrg ret = TRUE; 890974d292Smrg break; 900974d292Smrg case 16: 910974d292Smrg r = (pm >> 11) & 0x1f; 920974d292Smrg g = (pm >> 5) & 0x3f; 930974d292Smrg b = (pm >> 0) & 0x1f; 940974d292Smrg if (((r == 0) || (r == 0x1f)) && 950974d292Smrg ((g == 0) || (g == 0x3f)) && 960974d292Smrg ((b == 0) || (b == 0x1f))) 970974d292Smrg ret = TRUE; 980974d292Smrg break; 990974d292Smrg case 32: 1000974d292Smrg a = (pm >> 24) & 0xff; 1010974d292Smrg r = (pm >> 16) & 0xff; 1020974d292Smrg g = (pm >> 8) & 0xff; 1030974d292Smrg b = (pm >> 0) & 0xff; 1040974d292Smrg if (((a == 0) || (a == 0xff)) && 1050974d292Smrg ((r == 0) || (r == 0xff)) && 1060974d292Smrg ((g == 0) || (g == 0xff)) && 1070974d292Smrg ((b == 0) || (b == 0xff))) 1080974d292Smrg ret = TRUE; 1090974d292Smrg break; 1100974d292Smrg default: 1110974d292Smrg break; 1120974d292Smrg } 1130974d292Smrg return ret; 1140974d292Smrg} 1150974d292Smrg 1160974d292SmrgBool RADEONCheckBPP(int bpp) 1170974d292Smrg{ 1180974d292Smrg switch (bpp) { 1190974d292Smrg case 8: 1200974d292Smrg case 16: 1210974d292Smrg case 32: 1220974d292Smrg return TRUE; 1230974d292Smrg default: 1240974d292Smrg break; 1250974d292Smrg } 1260974d292Smrg return FALSE; 1270974d292Smrg} 1280974d292Smrg 1290974d292Smrgstatic Bool radeon_vb_get(ScrnInfoPtr pScrn) 1300974d292Smrg{ 1310974d292Smrg RADEONInfoPtr info = RADEONPTR(pScrn); 1320974d292Smrg struct radeon_accel_state *accel_state = info->accel_state; 1330974d292Smrg 1340974d292Smrg accel_state->vb_mc_addr = info->gartLocation + info->dri->bufStart + 1350974d292Smrg (accel_state->ib->idx*accel_state->ib->total)+ 1360974d292Smrg (accel_state->ib->total / 2); 1370974d292Smrg accel_state->vb_total = (accel_state->ib->total / 2); 1380974d292Smrg accel_state->vb_ptr = (pointer)((char*)accel_state->ib->address + 1390974d292Smrg (accel_state->ib->total / 2)); 1400974d292Smrg accel_state->vb_offset = 0; 1410974d292Smrg return TRUE; 1420974d292Smrg} 1430974d292Smrg 1440974d292Smrgvoid radeon_vb_discard(ScrnInfoPtr pScrn) 1450974d292Smrg{ 1460974d292Smrg RADEONInfoPtr info = RADEONPTR(pScrn); 1470974d292Smrg 1480974d292Smrg info->accel_state->vb_start_op = -1; 1490974d292Smrg} 1500974d292Smrg 1510974d292Smrgint radeon_cp_start(ScrnInfoPtr pScrn) 1520974d292Smrg{ 1530974d292Smrg RADEONInfoPtr info = RADEONPTR(pScrn); 1540974d292Smrg struct radeon_accel_state *accel_state = info->accel_state; 1550974d292Smrg 1560974d292Smrg#if defined(XF86DRM_MODE) 1570974d292Smrg if (info->cs) { 1580974d292Smrg if (CS_FULL(info->cs)) { 1590974d292Smrg radeon_cs_flush_indirect(pScrn); 1600974d292Smrg } 1610974d292Smrg accel_state->ib_reset_op = info->cs->cdw; 1620974d292Smrg accel_state->vb_start_op = accel_state->vb_offset; 1630974d292Smrg } else 1640974d292Smrg#endif 1650974d292Smrg { 1660974d292Smrg accel_state->ib = RADEONCPGetBuffer(pScrn); 1670974d292Smrg if (!radeon_vb_get(pScrn)) { 1680974d292Smrg return -1; 1690974d292Smrg } 1700974d292Smrg accel_state->vb_start_op = accel_state->vb_offset; 1710974d292Smrg } 1720974d292Smrg return 0; 1730974d292Smrg} 1740974d292Smrg 1750974d292Smrgvoid radeon_vb_no_space(ScrnInfoPtr pScrn, int vert_size) 1760974d292Smrg{ 1770974d292Smrg RADEONInfoPtr info = RADEONPTR(pScrn); 1780974d292Smrg struct radeon_accel_state *accel_state = info->accel_state; 1790974d292Smrg 1800974d292Smrg#if defined(XF86DRM_MODE) 1810974d292Smrg if (info->cs) { 1820974d292Smrg if (accel_state->vb_bo) { 1830974d292Smrg if (accel_state->vb_start_op != accel_state->vb_offset) { 1840974d292Smrg accel_state->finish_op(pScrn, vert_size); 1850974d292Smrg accel_state->ib_reset_op = info->cs->cdw; 1860974d292Smrg } 1870974d292Smrg 1880974d292Smrg /* release the current VBO */ 1890974d292Smrg radeon_vbo_put(pScrn); 1900974d292Smrg } 1910974d292Smrg /* get a new one */ 1920974d292Smrg radeon_vbo_get(pScrn); 1930974d292Smrg return; 1940974d292Smrg } 1950974d292Smrg#endif 1960974d292Smrg if (accel_state->vb_start_op != -1) { 1970974d292Smrg accel_state->finish_op(pScrn, vert_size); 1980974d292Smrg radeon_cp_start(pScrn); 1990974d292Smrg } 2000974d292Smrg return; 2010974d292Smrg} 2020974d292Smrg 2030974d292Smrg#if defined(XF86DRM_MODE) 2040974d292Smrgvoid radeon_ib_discard(ScrnInfoPtr pScrn) 2050974d292Smrg{ 2060974d292Smrg RADEONInfoPtr info = RADEONPTR(pScrn); 2070974d292Smrg int ret; 2080974d292Smrg 2090974d292Smrg if (info->accel_state->ib_reset_op) { 2100974d292Smrg /* if we have data just reset the CS and ignore the operation */ 2110974d292Smrg info->cs->cdw = info->accel_state->ib_reset_op; 2120974d292Smrg info->accel_state->ib_reset_op = 0; 2130974d292Smrg goto out; 2140974d292Smrg } 2150974d292Smrg 2160974d292Smrg info->accel_state->vb_offset = 0; 2170974d292Smrg info->accel_state->vb_start_op = -1; 2180974d292Smrg 2190974d292Smrg if (CS_FULL(info->cs)) { 2200974d292Smrg radeon_cs_flush_indirect(pScrn); 2210974d292Smrg return; 2220974d292Smrg } 2230974d292Smrg radeon_cs_erase(info->cs); 2240974d292Smrg ret = radeon_cs_space_check_with_bo(info->cs, 2250974d292Smrg info->accel_state->vb_bo, 2260974d292Smrg RADEON_GEM_DOMAIN_GTT, 0); 2270974d292Smrg if (ret) 2280974d292Smrg ErrorF("space check failed in flush\n"); 2290974d292Smrg 2300974d292Smrg out: 2310974d292Smrg if (info->dri2.enabled) { 2320974d292Smrg info->accel_state->XInited3D = FALSE; 2330974d292Smrg info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN; 2340974d292Smrg } 2350974d292Smrg 2360974d292Smrg} 2370974d292Smrg#endif 238