radeon_exa_shared.c revision 43df4709
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 129PixmapPtr RADEONSolidPixmap(ScreenPtr pScreen, uint32_t solid) 130{ 131 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 132 RADEONInfoPtr info = RADEONPTR(pScrn); 133 PixmapPtr pPix = pScreen->CreatePixmap(pScreen, 1, 1, 32, 0); 134 135 exaMoveInPixmap(pPix); 136 137#if defined(XF86DRM_MODE) 138 if (info->cs) { 139 struct radeon_bo *bo; 140 141 bo = radeon_get_pixmap_bo(pPix); 142 143 if (radeon_bo_map(bo, 1)) { 144 pScreen->DestroyPixmap(pPix); 145 return NULL; 146 } 147 148 memcpy(bo->ptr, &solid, 4); 149 radeon_bo_unmap(bo); 150 151 return pPix; 152 } 153#endif 154 155 if (!exaDrawableIsOffscreen(&pPix->drawable)) { 156 pScreen->DestroyPixmap(pPix); 157 return NULL; 158 } 159 160 /* XXX: Big hammer... */ 161 info->accel_state->exa->WaitMarker(pScreen, info->accel_state->exaSyncMarker); 162 memcpy(info->FB + exaGetPixmapOffset(pPix), &solid, 4); 163 164 return pPix; 165} 166 167static Bool radeon_vb_get(ScrnInfoPtr pScrn) 168{ 169 RADEONInfoPtr info = RADEONPTR(pScrn); 170 struct radeon_accel_state *accel_state = info->accel_state; 171 172 accel_state->vbo.vb_mc_addr = info->gartLocation + info->dri->bufStart + 173 (accel_state->ib->idx*accel_state->ib->total)+ 174 (accel_state->ib->total / 2); 175 accel_state->vbo.vb_total = (accel_state->ib->total / 2); 176 accel_state->vbo.vb_ptr = (pointer)((char*)accel_state->ib->address + 177 (accel_state->ib->total / 2)); 178 accel_state->vbo.vb_offset = 0; 179 return TRUE; 180} 181 182int radeon_cp_start(ScrnInfoPtr pScrn) 183{ 184 RADEONInfoPtr info = RADEONPTR(pScrn); 185 struct radeon_accel_state *accel_state = info->accel_state; 186 187#if defined(XF86DRM_MODE) 188 if (info->cs) { 189 if (CS_FULL(info->cs)) { 190 radeon_cs_flush_indirect(pScrn); 191 } 192 accel_state->ib_reset_op = info->cs->cdw; 193 } else 194#endif 195 { 196 accel_state->ib = RADEONCPGetBuffer(pScrn); 197 if (!radeon_vb_get(pScrn)) { 198 return -1; 199 } 200 } 201 accel_state->vbo.vb_start_op = accel_state->vbo.vb_offset; 202 accel_state->cbuf.vb_start_op = accel_state->cbuf.vb_offset; 203 return 0; 204} 205 206void radeon_vb_no_space(ScrnInfoPtr pScrn, 207 struct radeon_vbo_object *vbo, 208 int vert_size) 209{ 210 RADEONInfoPtr info = RADEONPTR(pScrn); 211 struct radeon_accel_state *accel_state = info->accel_state; 212 213#if defined(XF86DRM_MODE) 214 if (info->cs) { 215 if (vbo->vb_bo) { 216 if (vbo->vb_start_op != vbo->vb_offset) { 217 accel_state->finish_op(pScrn, vert_size); 218 accel_state->ib_reset_op = info->cs->cdw; 219 } 220 221 /* release the current VBO */ 222 radeon_vbo_put(pScrn, vbo); 223 } 224 /* get a new one */ 225 radeon_vbo_get(pScrn, vbo); 226 return; 227 } 228#endif 229 if (vbo->vb_start_op != -1) { 230 accel_state->finish_op(pScrn, vert_size); 231 radeon_cp_start(pScrn); 232 } 233 return; 234} 235 236#if defined(XF86DRM_MODE) 237void radeon_ib_discard(ScrnInfoPtr pScrn) 238{ 239 RADEONInfoPtr info = RADEONPTR(pScrn); 240 int ret; 241 242 if (info->accel_state->ib_reset_op) { 243 /* if we have data just reset the CS and ignore the operation */ 244 info->cs->cdw = info->accel_state->ib_reset_op; 245 info->accel_state->ib_reset_op = 0; 246 goto out; 247 } 248 249 info->accel_state->vbo.vb_offset = 0; 250 info->accel_state->vbo.vb_start_op = -1; 251 info->accel_state->cbuf.vb_offset = 0; 252 info->accel_state->cbuf.vb_start_op = -1; 253 254 if (CS_FULL(info->cs)) { 255 radeon_cs_flush_indirect(pScrn); 256 return; 257 } 258 radeon_cs_erase(info->cs); 259 ret = radeon_cs_space_check_with_bo(info->cs, 260 info->accel_state->vbo.vb_bo, 261 RADEON_GEM_DOMAIN_GTT, 0); 262 if (ret) 263 ErrorF("space check failed in flush\n"); 264 265 if (info->accel_state->cbuf.vb_bo) { 266 ret = radeon_cs_space_check_with_bo(info->cs, 267 info->accel_state->cbuf.vb_bo, 268 RADEON_GEM_DOMAIN_GTT, 0); 269 if (ret) 270 ErrorF("space check failed in flush\n"); 271 } 272 273 out: 274 if (info->dri2.enabled) { 275 info->accel_state->XInited3D = FALSE; 276 info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN; 277 } 278 279} 280#endif 281