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