radeon_span.c revision d0dc75c000d5af92648c7de901756400672b8447
1/************************************************************************** 2 3Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. 4Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and 5 VA Linux Systems Inc., Fremont, California. 6 7The Weather Channel (TM) funded Tungsten Graphics to develop the 8initial release of the Radeon 8500 driver under the XFree86 license. 9This notice must be preserved. 10 11All Rights Reserved. 12 13Permission is hereby granted, free of charge, to any person obtaining 14a copy of this software and associated documentation files (the 15"Software"), to deal in the Software without restriction, including 16without limitation the rights to use, copy, modify, merge, publish, 17distribute, sublicense, and/or sell copies of the Software, and to 18permit persons to whom the Software is furnished to do so, subject to 19the following conditions: 20 21The above copyright notice and this permission notice (including the 22next paragraph) shall be included in all copies or substantial 23portions of the Software. 24 25THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 28IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 29LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 30OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 31WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 32 33**************************************************************************/ 34 35/* 36 * Authors: 37 * Kevin E. Martin <martin@valinux.com> 38 * Gareth Hughes <gareth@valinux.com> 39 * Keith Whitwell <keith@tungstengraphics.com> 40 * 41 */ 42 43#include "main/glheader.h" 44#include "main/texformat.h" 45#include "main/renderbuffer.h" 46#include "swrast/swrast.h" 47#include "swrast/s_renderbuffer.h" 48 49#include "radeon_common.h" 50#include "radeon_span.h" 51 52#define DBG 0 53 54#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN 55#if defined(__linux__) 56#include <byteswap.h> 57#define CPU_TO_LE16( x ) bswap_16( x ) 58#define LE16_TO_CPU( x ) bswap_16( x ) 59#endif /* __linux__ */ 60#else 61#define CPU_TO_LE16( x ) ( x ) 62#define LE16_TO_CPU( x ) ( x ) 63#endif 64 65static void radeonSetSpanFunctions(struct radeon_renderbuffer *rrb); 66 67/* 68 * Note that all information needed to access pixels in a renderbuffer 69 * should be obtained through the gl_renderbuffer parameter, not per-context 70 * information. 71 */ 72#define LOCAL_VARS \ 73 struct radeon_renderbuffer *rrb = (void *) rb; \ 74 int minx = 0, miny = 0; \ 75 int maxx = rb->Width; \ 76 int maxy = rb->Height; \ 77 void *buf = rb->Data; \ 78 int pitch = rb->RowStride * rrb->cpp; \ 79 GLuint p; \ 80 (void)p; 81 82#define Y_FLIP(_y) (_y) 83 84#define HW_LOCK() 85#define HW_UNLOCK() 86#define HW_CLIPLOOP() 87#define HW_ENDCLIPLOOP() 88 89/* ================================================================ 90 * Color buffer 91 */ 92 93/* 16 bit, RGB565 color spanline and pixel functions 94 */ 95#define SPANTMP_PIXEL_FMT GL_RGB 96#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5 97#define TAG(x) radeon##x##_RGB565 98#define TAG2(x,y) radeon##x##_RGB565##y 99#include "spantmp2.h" 100 101#define SPANTMP_PIXEL_FMT GL_RGB 102#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5_REV 103#define TAG(x) radeon##x##_RGB565_REV 104#define TAG2(x,y) radeon##x##_RGB565_REV##y 105#include "spantmp2.h" 106 107/* 16 bit, ARGB1555 color spanline and pixel functions 108 */ 109#define SPANTMP_PIXEL_FMT GL_BGRA 110#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_1_5_5_5_REV 111#define TAG(x) radeon##x##_ARGB1555 112#define TAG2(x,y) radeon##x##_ARGB1555##y 113#include "spantmp2.h" 114 115#define SPANTMP_PIXEL_FMT GL_BGRA 116#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_1_5_5_5 117#define TAG(x) radeon##x##_ARGB1555_REV 118#define TAG2(x,y) radeon##x##_ARGB1555_REV##y 119#include "spantmp2.h" 120 121/* 16 bit, RGBA4 color spanline and pixel functions 122 */ 123#define SPANTMP_PIXEL_FMT GL_BGRA 124#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_4_4_4_4_REV 125#define TAG(x) radeon##x##_ARGB4444 126#define TAG2(x,y) radeon##x##_ARGB4444##y 127#include "spantmp2.h" 128 129#define SPANTMP_PIXEL_FMT GL_BGRA 130#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_4_4_4_4 131#define TAG(x) radeon##x##_ARGB4444_REV 132#define TAG2(x,y) radeon##x##_ARGB4444_REV##y 133#include "spantmp2.h" 134 135/* 32 bit, xRGB8888 color spanline and pixel functions 136 */ 137#define SPANTMP_PIXEL_FMT GL_BGRA 138#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV 139#define TAG(x) radeon##x##_xRGB8888 140#define TAG2(x,y) radeon##x##_xRGB8888##y 141#include "spantmp2.h" 142 143/* 32 bit, ARGB8888 color spanline and pixel functions 144 */ 145#define SPANTMP_PIXEL_FMT GL_BGRA 146#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV 147#define TAG(x) radeon##x##_ARGB8888 148#define TAG2(x,y) radeon##x##_ARGB8888##y 149#include "spantmp2.h" 150 151/* 32 bit, BGRx8888 color spanline and pixel functions 152 */ 153#define SPANTMP_PIXEL_FMT GL_BGRA 154#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8 155#define TAG(x) radeon##x##_BGRx8888 156#define TAG2(x,y) radeon##x##_BGRx8888##y 157#include "spantmp2.h" 158 159/* 32 bit, BGRA8888 color spanline and pixel functions 160 */ 161#define SPANTMP_PIXEL_FMT GL_BGRA 162#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8 163#define TAG(x) radeon##x##_BGRA8888 164#define TAG2(x,y) radeon##x##_BGRA8888##y 165#include "spantmp2.h" 166 167static void 168radeon_renderbuffer_map(struct gl_context *ctx, struct gl_renderbuffer *rb) 169{ 170 struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); 171 GLubyte *map; 172 int stride; 173 174 if (!rb || !rrb) 175 return; 176 177 ctx->Driver.MapRenderbuffer(ctx, rb, 0, 0, rb->Width, rb->Height, 178 GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, 179 &map, &stride); 180 181 rb->Data = map; 182 rb->RowStride = stride / _mesa_get_format_bytes(rb->Format); 183 184 radeonSetSpanFunctions(rrb); 185} 186 187static void 188radeon_renderbuffer_unmap(struct gl_context *ctx, struct gl_renderbuffer *rb) 189{ 190 struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); 191 if (!rb || !rrb) 192 return; 193 194 ctx->Driver.UnmapRenderbuffer(ctx, rb); 195 196 rb->GetRow = NULL; 197 rb->PutRow = NULL; 198 rb->Data = NULL; 199 rb->RowStride = 0; 200} 201 202static void 203radeon_map_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb) 204{ 205 GLuint i; 206 207 radeon_print(RADEON_MEMORY, RADEON_TRACE, 208 "%s( %p , fb %p )\n", 209 __func__, ctx, fb); 210 211 /* check for render to textures */ 212 for (i = 0; i < BUFFER_COUNT; i++) 213 radeon_renderbuffer_map(ctx, fb->Attachment[i].Renderbuffer); 214 215 radeon_check_front_buffer_rendering(ctx); 216} 217 218static void 219radeon_unmap_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb) 220{ 221 GLuint i; 222 223 radeon_print(RADEON_MEMORY, RADEON_TRACE, 224 "%s( %p , fb %p)\n", 225 __func__, ctx, fb); 226 227 /* check for render to textures */ 228 for (i = 0; i < BUFFER_COUNT; i++) 229 radeon_renderbuffer_unmap(ctx, fb->Attachment[i].Renderbuffer); 230 231 radeon_check_front_buffer_rendering(ctx); 232} 233 234static void radeonSpanRenderStart(struct gl_context * ctx) 235{ 236 radeonContextPtr rmesa = RADEON_CONTEXT(ctx); 237 int i; 238 239 radeon_firevertices(rmesa); 240 241 for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) { 242 if (ctx->Texture.Unit[i]._ReallyEnabled) { 243 radeon_validate_texture_miptree(ctx, ctx->Texture.Unit[i]._Current); 244 radeon_swrast_map_texture_images(ctx, ctx->Texture.Unit[i]._Current); 245 } 246 } 247 248 radeon_map_framebuffer(ctx, ctx->DrawBuffer); 249 if (ctx->ReadBuffer != ctx->DrawBuffer) 250 radeon_map_framebuffer(ctx, ctx->ReadBuffer); 251} 252 253static void radeonSpanRenderFinish(struct gl_context * ctx) 254{ 255 int i; 256 257 _swrast_flush(ctx); 258 259 for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) 260 if (ctx->Texture.Unit[i]._ReallyEnabled) 261 radeon_swrast_unmap_texture_images(ctx, ctx->Texture.Unit[i]._Current); 262 263 radeon_unmap_framebuffer(ctx, ctx->DrawBuffer); 264 if (ctx->ReadBuffer != ctx->DrawBuffer) 265 radeon_unmap_framebuffer(ctx, ctx->ReadBuffer); 266} 267 268void radeonInitSpanFuncs(struct gl_context * ctx) 269{ 270 struct swrast_device_driver *swdd = 271 _swrast_GetDeviceDriverReference(ctx); 272 swdd->SpanRenderStart = radeonSpanRenderStart; 273 swdd->SpanRenderFinish = radeonSpanRenderFinish; 274} 275 276/** 277 * Plug in the Get/Put routines for the given driRenderbuffer. 278 */ 279static void radeonSetSpanFunctions(struct radeon_renderbuffer *rrb) 280{ 281 if (rrb->base.Format == MESA_FORMAT_RGB565) { 282 radeonInitPointers_RGB565(&rrb->base); 283 } else if (rrb->base.Format == MESA_FORMAT_RGB565_REV) { 284 radeonInitPointers_RGB565_REV(&rrb->base); 285 } else if (rrb->base.Format == MESA_FORMAT_XRGB8888) { 286 radeonInitPointers_xRGB8888(&rrb->base); 287 } else if (rrb->base.Format == MESA_FORMAT_XRGB8888_REV) { 288 radeonInitPointers_BGRx8888(&rrb->base); 289 } else if (rrb->base.Format == MESA_FORMAT_ARGB8888) { 290 radeonInitPointers_ARGB8888(&rrb->base); 291 } else if (rrb->base.Format == MESA_FORMAT_ARGB8888_REV) { 292 radeonInitPointers_BGRA8888(&rrb->base); 293 } else if (rrb->base.Format == MESA_FORMAT_ARGB4444) { 294 radeonInitPointers_ARGB4444(&rrb->base); 295 } else if (rrb->base.Format == MESA_FORMAT_ARGB4444_REV) { 296 radeonInitPointers_ARGB4444_REV(&rrb->base); 297 } else if (rrb->base.Format == MESA_FORMAT_ARGB1555) { 298 radeonInitPointers_ARGB1555(&rrb->base); 299 } else if (rrb->base.Format == MESA_FORMAT_ARGB1555_REV) { 300 radeonInitPointers_ARGB1555_REV(&rrb->base); 301 } else if (rrb->base.Format == MESA_FORMAT_Z16) { 302 _swrast_set_renderbuffer_accessors(&rrb->base); 303 } else if (rrb->base.Format == MESA_FORMAT_X8_Z24) { 304 _swrast_set_renderbuffer_accessors(&rrb->base); 305 } else if (rrb->base.Format == MESA_FORMAT_S8_Z24) { 306 _swrast_set_renderbuffer_accessors(&rrb->base); 307 } else if (rrb->base.Format == MESA_FORMAT_S8) { 308 _swrast_set_renderbuffer_accessors(&rrb->base); 309 } else { 310 fprintf(stderr, "radeonSetSpanFunctions: bad format: 0x%04X\n", rrb->base.Format); 311 } 312} 313