radeon_exa_shared.c revision 39413783
1de2362d3Smrg/* 2de2362d3Smrg * Copyright 2005 Eric Anholt 3de2362d3Smrg * Copyright 2005 Benjamin Herrenschmidt 4de2362d3Smrg * Copyright 2008 Advanced Micro Devices, Inc. 5de2362d3Smrg * All Rights Reserved. 6de2362d3Smrg * 7de2362d3Smrg * Permission is hereby granted, free of charge, to any person obtaining a 8de2362d3Smrg * copy of this software and associated documentation files (the "Software"), 9de2362d3Smrg * to deal in the Software without restriction, including without limitation 10de2362d3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11de2362d3Smrg * and/or sell copies of the Software, and to permit persons to whom the 12de2362d3Smrg * Software is furnished to do so, subject to the following conditions: 13de2362d3Smrg * 14de2362d3Smrg * The above copyright notice and this permission notice (including the next 15de2362d3Smrg * paragraph) shall be included in all copies or substantial portions of the 16de2362d3Smrg * Software. 17de2362d3Smrg * 18de2362d3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19de2362d3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20de2362d3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21de2362d3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22de2362d3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23de2362d3Smrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24de2362d3Smrg * SOFTWARE. 25de2362d3Smrg * 26de2362d3Smrg * Authors: 27de2362d3Smrg * Eric Anholt <anholt@FreeBSD.org> 28de2362d3Smrg * Zack Rusin <zrusin@trolltech.com> 29de2362d3Smrg * Benjamin Herrenschmidt <benh@kernel.crashing.org> 30de2362d3Smrg * Alex Deucher <alexander.deucher@amd.com> 31de2362d3Smrg * Matthias Hopf <mhopf@suse.de> 32de2362d3Smrg */ 33de2362d3Smrg#ifdef HAVE_CONFIG_H 34de2362d3Smrg#include "config.h" 35de2362d3Smrg#endif 36de2362d3Smrg 37de2362d3Smrg#include "radeon.h" 38de2362d3Smrg#include "radeon_probe.h" 39de2362d3Smrg#include "radeon_version.h" 40de2362d3Smrg#include "radeon_vbo.h" 41de2362d3Smrg 42de2362d3SmrgPixmapPtr 43de2362d3SmrgRADEONGetDrawablePixmap(DrawablePtr pDrawable) 44de2362d3Smrg{ 45de2362d3Smrg if (pDrawable->type == DRAWABLE_WINDOW) 46de2362d3Smrg return pDrawable->pScreen->GetWindowPixmap((WindowPtr)pDrawable); 47de2362d3Smrg else 48de2362d3Smrg return (PixmapPtr)pDrawable; 49de2362d3Smrg} 50de2362d3Smrg 51de2362d3Smrgvoid RADEONVlineHelperClear(ScrnInfoPtr pScrn) 52de2362d3Smrg{ 53de2362d3Smrg RADEONInfoPtr info = RADEONPTR(pScrn); 54de2362d3Smrg struct radeon_accel_state *accel_state = info->accel_state; 55de2362d3Smrg 56de2362d3Smrg accel_state->vline_crtc = NULL; 57de2362d3Smrg accel_state->vline_y1 = -1; 58de2362d3Smrg accel_state->vline_y2 = 0; 59de2362d3Smrg} 60de2362d3Smrg 61de2362d3Smrgvoid RADEONVlineHelperSet(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2) 62de2362d3Smrg{ 63de2362d3Smrg RADEONInfoPtr info = RADEONPTR(pScrn); 64de2362d3Smrg struct radeon_accel_state *accel_state = info->accel_state; 65de2362d3Smrg 6618781e08Smrg accel_state->vline_crtc = 6718781e08Smrg radeon_pick_best_crtc(pScrn, FALSE, x1, x2, y1, y2); 68de2362d3Smrg if (accel_state->vline_y1 == -1) 69de2362d3Smrg accel_state->vline_y1 = y1; 70de2362d3Smrg if (y1 < accel_state->vline_y1) 71de2362d3Smrg accel_state->vline_y1 = y1; 72de2362d3Smrg if (y2 > accel_state->vline_y2) 73de2362d3Smrg accel_state->vline_y2 = y2; 74de2362d3Smrg} 75de2362d3Smrg 76de2362d3SmrgBool RADEONValidPM(uint32_t pm, int bpp) 77de2362d3Smrg{ 78de2362d3Smrg uint8_t r, g, b, a; 79de2362d3Smrg Bool ret = FALSE; 80de2362d3Smrg 81de2362d3Smrg switch (bpp) { 82de2362d3Smrg case 8: 83de2362d3Smrg a = pm & 0xff; 84de2362d3Smrg if ((a == 0) || (a == 0xff)) 85de2362d3Smrg ret = TRUE; 86de2362d3Smrg break; 87de2362d3Smrg case 16: 88de2362d3Smrg r = (pm >> 11) & 0x1f; 89de2362d3Smrg g = (pm >> 5) & 0x3f; 90de2362d3Smrg b = (pm >> 0) & 0x1f; 91de2362d3Smrg if (((r == 0) || (r == 0x1f)) && 92de2362d3Smrg ((g == 0) || (g == 0x3f)) && 93de2362d3Smrg ((b == 0) || (b == 0x1f))) 94de2362d3Smrg ret = TRUE; 95de2362d3Smrg break; 96de2362d3Smrg case 32: 97de2362d3Smrg a = (pm >> 24) & 0xff; 98de2362d3Smrg r = (pm >> 16) & 0xff; 99de2362d3Smrg g = (pm >> 8) & 0xff; 100de2362d3Smrg b = (pm >> 0) & 0xff; 101de2362d3Smrg if (((a == 0) || (a == 0xff)) && 102de2362d3Smrg ((r == 0) || (r == 0xff)) && 103de2362d3Smrg ((g == 0) || (g == 0xff)) && 104de2362d3Smrg ((b == 0) || (b == 0xff))) 105de2362d3Smrg ret = TRUE; 106de2362d3Smrg break; 107de2362d3Smrg default: 108de2362d3Smrg break; 109de2362d3Smrg } 110de2362d3Smrg return ret; 111de2362d3Smrg} 112de2362d3Smrg 113de2362d3SmrgBool RADEONCheckBPP(int bpp) 114de2362d3Smrg{ 115de2362d3Smrg switch (bpp) { 116de2362d3Smrg case 8: 117de2362d3Smrg case 16: 118de2362d3Smrg case 32: 119de2362d3Smrg return TRUE; 120de2362d3Smrg default: 121de2362d3Smrg break; 122de2362d3Smrg } 123de2362d3Smrg return FALSE; 124de2362d3Smrg} 125de2362d3Smrg 126de2362d3SmrgPixmapPtr RADEONSolidPixmap(ScreenPtr pScreen, uint32_t solid) 127de2362d3Smrg{ 128de2362d3Smrg PixmapPtr pPix = pScreen->CreatePixmap(pScreen, 1, 1, 32, 0); 12918781e08Smrg struct radeon_bo *bo; 130de2362d3Smrg exaMoveInPixmap(pPix); 131de2362d3Smrg 13239413783Smrg bo = radeon_get_pixmap_bo(pPix)->bo.radeon; 133de2362d3Smrg 13418781e08Smrg if (radeon_bo_map(bo, 1)) { 135de2362d3Smrg pScreen->DestroyPixmap(pPix); 136de2362d3Smrg return NULL; 137de2362d3Smrg } 138de2362d3Smrg 13918781e08Smrg memcpy(bo->ptr, &solid, 4); 14018781e08Smrg radeon_bo_unmap(bo); 141de2362d3Smrg 142de2362d3Smrg return pPix; 143de2362d3Smrg} 144de2362d3Smrg 145de2362d3Smrgint radeon_cp_start(ScrnInfoPtr pScrn) 146de2362d3Smrg{ 147de2362d3Smrg RADEONInfoPtr info = RADEONPTR(pScrn); 148de2362d3Smrg struct radeon_accel_state *accel_state = info->accel_state; 149de2362d3Smrg 15018781e08Smrg if (CS_FULL(info->cs)) { 15118781e08Smrg radeon_cs_flush_indirect(pScrn); 152de2362d3Smrg } 15318781e08Smrg accel_state->ib_reset_op = info->cs->cdw; 154de2362d3Smrg accel_state->vbo.vb_start_op = accel_state->vbo.vb_offset; 155de2362d3Smrg accel_state->cbuf.vb_start_op = accel_state->cbuf.vb_offset; 156de2362d3Smrg return 0; 157de2362d3Smrg} 158de2362d3Smrg 159de2362d3Smrgvoid radeon_vb_no_space(ScrnInfoPtr pScrn, 160de2362d3Smrg struct radeon_vbo_object *vbo, 161de2362d3Smrg int vert_size) 162de2362d3Smrg{ 163de2362d3Smrg RADEONInfoPtr info = RADEONPTR(pScrn); 164de2362d3Smrg struct radeon_accel_state *accel_state = info->accel_state; 165de2362d3Smrg 16618781e08Smrg if (vbo->vb_bo) { 16718781e08Smrg if (vbo->vb_start_op != vbo->vb_offset) { 16818781e08Smrg accel_state->finish_op(pScrn, vert_size); 16918781e08Smrg accel_state->ib_reset_op = info->cs->cdw; 1707821949aSmrg } 17118781e08Smrg 17218781e08Smrg /* release the current VBO */ 17318781e08Smrg radeon_vbo_put(pScrn, vbo); 174de2362d3Smrg } 17518781e08Smrg /* get a new one */ 17618781e08Smrg radeon_vbo_get(pScrn, vbo); 177de2362d3Smrg return; 178de2362d3Smrg} 179de2362d3Smrg 180de2362d3Smrgvoid radeon_ib_discard(ScrnInfoPtr pScrn) 181de2362d3Smrg{ 182de2362d3Smrg RADEONInfoPtr info = RADEONPTR(pScrn); 183de2362d3Smrg int ret; 184de2362d3Smrg 185de2362d3Smrg if (info->accel_state->ib_reset_op) { 186de2362d3Smrg /* if we have data just reset the CS and ignore the operation */ 187de2362d3Smrg info->cs->cdw = info->accel_state->ib_reset_op; 188de2362d3Smrg info->accel_state->ib_reset_op = 0; 189de2362d3Smrg goto out; 190de2362d3Smrg } 191de2362d3Smrg 192de2362d3Smrg info->accel_state->vbo.vb_offset = 0; 193de2362d3Smrg info->accel_state->vbo.vb_start_op = -1; 194de2362d3Smrg info->accel_state->cbuf.vb_offset = 0; 195de2362d3Smrg info->accel_state->cbuf.vb_start_op = -1; 196de2362d3Smrg 197de2362d3Smrg if (CS_FULL(info->cs)) { 198de2362d3Smrg radeon_cs_flush_indirect(pScrn); 199de2362d3Smrg return; 200de2362d3Smrg } 201de2362d3Smrg radeon_cs_erase(info->cs); 202de2362d3Smrg ret = radeon_cs_space_check_with_bo(info->cs, 203de2362d3Smrg info->accel_state->vbo.vb_bo, 204de2362d3Smrg RADEON_GEM_DOMAIN_GTT, 0); 205de2362d3Smrg if (ret) 206de2362d3Smrg ErrorF("space check failed in flush\n"); 207de2362d3Smrg 208de2362d3Smrg if (info->accel_state->cbuf.vb_bo) { 209de2362d3Smrg ret = radeon_cs_space_check_with_bo(info->cs, 210de2362d3Smrg info->accel_state->cbuf.vb_bo, 211de2362d3Smrg RADEON_GEM_DOMAIN_GTT, 0); 212de2362d3Smrg if (ret) 213de2362d3Smrg ErrorF("space check failed in flush\n"); 214de2362d3Smrg } 215de2362d3Smrg 216de2362d3Smrg out: 217de2362d3Smrg if (info->dri2.enabled) { 218de2362d3Smrg info->accel_state->XInited3D = FALSE; 219de2362d3Smrg info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN; 220de2362d3Smrg } 221de2362d3Smrg 222de2362d3Smrg} 223