patch to import Jon Smirl's work from Bitkeeper
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_subset_bitmap.c
1 /**
2 * \file radeon_subset_bitmap.c
3 * \brief Bitmap drawing.
4 *
5 * \author Keith Whitwell <keith@tungstengraphics.com>
6 */
7
8 /*
9 * Copyright 2003 ATI Technologies Inc., Ontario, Canada, and
10 * Tungsten Graphics Inc., Cedar Park, Texas.
11 *
12 * All Rights Reserved.
13 *
14 * Permission is hereby granted, free of charge, to any person obtaining a
15 * copy of this software and associated documentation files (the "Software"),
16 * to deal in the Software without restriction, including without limitation
17 * on the rights to use, copy, modify, merge, publish, distribute, sub
18 * license, and/or sell copies of the Software, and to permit persons to whom
19 * the Software is furnished to do so, subject to the following conditions:
20 *
21 * The above copyright notice and this permission notice (including the next
22 * paragraph) shall be included in all copies or substantial portions of the
23 * Software.
24 *
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
28 * ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
29 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
30 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
31 * USE OR OTHER DEALINGS IN THE SOFTWARE.
32 *
33 */
34
35 /* $XFree86$ */
36
37 #include "glheader.h"
38 #include "mtypes.h"
39 #include "colormac.h"
40 #include "context.h"
41 #include "enums.h"
42 #include "imports.h"
43 #include "image.h"
44 /*#include "mmath.h"*/
45 #include "macros.h"
46 #include "state.h"
47
48 #include "radeon_context.h"
49 #include "radeon_ioctl.h"
50 #include "radeon_state.h"
51 #include "radeon_subset.h"
52
53 /**
54 * \brief Cope with depth operations by drawing individual pixels as points
55 *
56 * \param xorig x coordinate of the bitmap corner.
57 * \param yorig y coordinate of the bitmap corner.
58 * \param xmove increment to the final x coordinate.
59 * \param ymove increment to the final y coordinate.
60 * \param width bitmap width.
61 * \param height bitmap height.
62 * \param bitmap bitmap pointer.
63 *
64 * Clips the bitmap coordinates and adjusts for windows coordinates. Draws the
65 * bitmap with glPoints(), turning off TCL and hardware viewport transformation
66 * to emit raw pixel coordinates. Finally fires any outstanding vertices and
67 * restores TCL, viewport, texture and color states.
68 */
69 void
70 radeonPointsBitmap( GLsizei width, GLsizei height,
71 GLfloat xorig, GLfloat yorig,
72 GLfloat xmove, GLfloat ymove,
73 const GLubyte *bitmap )
74 {
75 GET_CURRENT_CONTEXT(ctx);
76 GLsizei bmwidth = width, bmheight = height;
77 GLint px, py;
78 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
79 GLfloat saved_color[4], saved_tex0[2];
80 GLint row, col;
81 GLuint orig_se_cntl;
82 GLuint w, h;
83 const struct gl_pixelstore_attrib *unpack = &ctx->Unpack;
84
85 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
86
87 if (width < 0 || height < 0) {
88 _mesa_error( ctx, GL_INVALID_VALUE, "glBitmap(width or height < 0)" );
89 return;
90 }
91
92 if (!ctx->Current.RasterPosValid)
93 return;
94
95 if (ctx->NewState)
96 _mesa_update_state(ctx);
97
98
99 if (ctx->_RotateMode) {
100 width = bmheight; height = bmwidth;
101
102 px = IFLOOR(ctx->Current.RasterPos[0] + yorig);
103 py = IFLOOR(ctx->Current.RasterPos[1] + xorig);
104
105 ctx->Current.RasterPos[0] += ymove;
106 ctx->Current.RasterPos[1] += xmove;
107 }
108 else {
109 px = IFLOOR(ctx->Current.RasterPos[0] - xorig);
110 py = IFLOOR(ctx->Current.RasterPos[1] - yorig);
111
112 ctx->Current.RasterPos[0] += xmove;
113 ctx->Current.RasterPos[1] += ymove;
114 }
115
116
117
118 /* Turn off tcl and the hw viewport transformation so that we can
119 * emit raw pixel coordinates:
120 */
121 radeonSubsetVtxEnableTCL( rmesa, GL_FALSE );
122 RADEON_STATECHANGE( rmesa, set );
123 orig_se_cntl = rmesa->hw.set.cmd[SET_SE_CNTL];
124 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~(RADEON_VPORT_XY_XFORM_ENABLE |
125 RADEON_VPORT_Z_XFORM_ENABLE);
126
127
128 /* Adjust for window coordinates, flip y values:
129 */
130 h = rmesa->dri.drawable->h + rmesa->dri.drawable->y - 1;
131 w = rmesa->dri.drawable->w;
132 px += rmesa->dri.drawable->x;
133
134 /* Save current color, texcoord to restore later:
135 */
136 COPY_4V( saved_color, ctx->Current.Attrib[VERT_ATTRIB_COLOR0] );
137 COPY_2V( saved_tex0, ctx->Current.Attrib[VERT_ATTRIB_TEX0] );
138
139 /* Just use the GL entrypoints to talk to radeon_subset_vtx.c:
140 */
141 glBegin( GL_POINTS );
142 glColor4fv( ctx->Current.RasterColor );
143 glTexCoord2fv( ctx->Current.RasterTexCoords[0] );
144
145
146 if (ctx->_RotateMode) {
147 for (col=0; col<width; col++) {
148 const GLubyte *src = (const GLubyte *)
149 _mesa_image_address( unpack, bitmap, height, width,
150 GL_COLOR_INDEX, GL_BITMAP, 0, col, 0 );
151
152 /* Msb first */
153 GLubyte mask = 128U >> (unpack->SkipPixels & 0x7);
154 for (row=0; row<height; row++) {
155 if (*src & mask) {
156 glVertex2f( px-col, h - (py + row) );
157 }
158 src += mask & 1;
159 mask = ((mask << 7) & 0xff) | (mask >> 1);
160 }
161 /* get ready for next row */
162 if (mask != 128)
163 src++;
164 }
165 }
166 else {
167 for (row=0; row<height; row++) {
168 const GLubyte *src = (const GLubyte *)
169 _mesa_image_address( unpack, bitmap, width, height,
170 GL_COLOR_INDEX, GL_BITMAP, 0, row, 0 );
171
172 /* Msb first */
173 GLubyte mask = 128U >> (unpack->SkipPixels & 0x7);
174 for (col=0; col<width; col++) {
175 if (*src & mask) {
176 glVertex2f( px+col, h - (py + row) );
177 }
178 src += mask & 1;
179 mask = ((mask << 7) & 0xff) | (mask >> 1);
180 }
181 /* get ready for next row */
182 if (mask != 128)
183 src++;
184 }
185 }
186
187 glEnd();
188 glColor4fv( saved_color );
189 glTexCoord2fv( saved_tex0 );
190
191 /* Fire outstanding vertices, restore state
192 */
193 RADEON_STATECHANGE( rmesa, set );
194 rmesa->hw.set.cmd[SET_SE_CNTL] = orig_se_cntl;
195 radeonSubsetVtxEnableTCL( rmesa, GL_TRUE );
196 }
197