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#include "radeon_probe.h" 39#include "radeon_version.h" 40#include "radeon_vbo.h" 41 42PixmapPtr 43RADEONGetDrawablePixmap(DrawablePtr pDrawable) 44{ 45 if (pDrawable->type == DRAWABLE_WINDOW) 46 return pDrawable->pScreen->GetWindowPixmap((WindowPtr)pDrawable); 47 else 48 return (PixmapPtr)pDrawable; 49} 50 51void RADEONVlineHelperClear(ScrnInfoPtr pScrn) 52{ 53 RADEONInfoPtr info = RADEONPTR(pScrn); 54 struct radeon_accel_state *accel_state = info->accel_state; 55 56 accel_state->vline_crtc = NULL; 57 accel_state->vline_y1 = -1; 58 accel_state->vline_y2 = 0; 59} 60 61void RADEONVlineHelperSet(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2) 62{ 63 RADEONInfoPtr info = RADEONPTR(pScrn); 64 struct radeon_accel_state *accel_state = info->accel_state; 65 66 accel_state->vline_crtc = 67 radeon_pick_best_crtc(pScrn, FALSE, x1, x2, y1, y2); 68 if (accel_state->vline_y1 == -1) 69 accel_state->vline_y1 = y1; 70 if (y1 < accel_state->vline_y1) 71 accel_state->vline_y1 = y1; 72 if (y2 > accel_state->vline_y2) 73 accel_state->vline_y2 = y2; 74} 75 76Bool RADEONValidPM(uint32_t pm, int bpp) 77{ 78 uint8_t r, g, b, a; 79 Bool ret = FALSE; 80 81 switch (bpp) { 82 case 8: 83 a = pm & 0xff; 84 if ((a == 0) || (a == 0xff)) 85 ret = TRUE; 86 break; 87 case 16: 88 r = (pm >> 11) & 0x1f; 89 g = (pm >> 5) & 0x3f; 90 b = (pm >> 0) & 0x1f; 91 if (((r == 0) || (r == 0x1f)) && 92 ((g == 0) || (g == 0x3f)) && 93 ((b == 0) || (b == 0x1f))) 94 ret = TRUE; 95 break; 96 case 32: 97 a = (pm >> 24) & 0xff; 98 r = (pm >> 16) & 0xff; 99 g = (pm >> 8) & 0xff; 100 b = (pm >> 0) & 0xff; 101 if (((a == 0) || (a == 0xff)) && 102 ((r == 0) || (r == 0xff)) && 103 ((g == 0) || (g == 0xff)) && 104 ((b == 0) || (b == 0xff))) 105 ret = TRUE; 106 break; 107 default: 108 break; 109 } 110 return ret; 111} 112 113Bool RADEONCheckBPP(int bpp) 114{ 115 switch (bpp) { 116 case 8: 117 case 16: 118 case 32: 119 return TRUE; 120 default: 121 break; 122 } 123 return FALSE; 124} 125 126PixmapPtr RADEONSolidPixmap(ScreenPtr pScreen, uint32_t solid) 127{ 128 PixmapPtr pPix = pScreen->CreatePixmap(pScreen, 1, 1, 32, 0); 129 struct radeon_bo *bo; 130 exaMoveInPixmap(pPix); 131 132 bo = radeon_get_pixmap_bo(pPix)->bo.radeon; 133 134 if (radeon_bo_map(bo, 1)) { 135 pScreen->DestroyPixmap(pPix); 136 return NULL; 137 } 138 139 memcpy(bo->ptr, &solid, 4); 140 radeon_bo_unmap(bo); 141 142 return pPix; 143} 144 145int radeon_cp_start(ScrnInfoPtr pScrn) 146{ 147 RADEONInfoPtr info = RADEONPTR(pScrn); 148 struct radeon_accel_state *accel_state = info->accel_state; 149 150 if (CS_FULL(info->cs)) { 151 radeon_cs_flush_indirect(pScrn); 152 } 153 accel_state->ib_reset_op = info->cs->cdw; 154 accel_state->vbo.vb_start_op = accel_state->vbo.vb_offset; 155 accel_state->cbuf.vb_start_op = accel_state->cbuf.vb_offset; 156 return 0; 157} 158 159void radeon_vb_no_space(ScrnInfoPtr pScrn, 160 struct radeon_vbo_object *vbo, 161 int vert_size) 162{ 163 RADEONInfoPtr info = RADEONPTR(pScrn); 164 struct radeon_accel_state *accel_state = info->accel_state; 165 166 if (vbo->vb_bo) { 167 if (vbo->vb_start_op != vbo->vb_offset) { 168 accel_state->finish_op(pScrn, vert_size); 169 accel_state->ib_reset_op = info->cs->cdw; 170 } 171 172 /* release the current VBO */ 173 radeon_vbo_put(pScrn, vbo); 174 } 175 /* get a new one */ 176 radeon_vbo_get(pScrn, vbo); 177 return; 178} 179 180void radeon_ib_discard(ScrnInfoPtr pScrn) 181{ 182 RADEONInfoPtr info = RADEONPTR(pScrn); 183 int ret; 184 185 if (info->accel_state->ib_reset_op) { 186 /* if we have data just reset the CS and ignore the operation */ 187 info->cs->cdw = info->accel_state->ib_reset_op; 188 info->accel_state->ib_reset_op = 0; 189 goto out; 190 } 191 192 info->accel_state->vbo.vb_offset = 0; 193 info->accel_state->vbo.vb_start_op = -1; 194 info->accel_state->cbuf.vb_offset = 0; 195 info->accel_state->cbuf.vb_start_op = -1; 196 197 if (CS_FULL(info->cs)) { 198 radeon_cs_flush_indirect(pScrn); 199 return; 200 } 201 radeon_cs_erase(info->cs); 202 ret = radeon_cs_space_check_with_bo(info->cs, 203 info->accel_state->vbo.vb_bo, 204 RADEON_GEM_DOMAIN_GTT, 0); 205 if (ret) 206 ErrorF("space check failed in flush\n"); 207 208 if (info->accel_state->cbuf.vb_bo) { 209 ret = radeon_cs_space_check_with_bo(info->cs, 210 info->accel_state->cbuf.vb_bo, 211 RADEON_GEM_DOMAIN_GTT, 0); 212 if (ret) 213 ErrorF("space check failed in flush\n"); 214 } 215 216 out: 217 if (info->dri2.enabled) { 218 info->accel_state->XInited3D = FALSE; 219 info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN; 220 } 221 222} 223