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