Merge branch 'master' of ssh://people.freedesktop.org/~jbarnes/mesa
[mesa.git] / src / mesa / drivers / dri / ffb / ffb_bitmap.c
1 /*
2 *
3 * GLX Hardware Device Driver for Sun Creator/Creator3D
4 * Copyright (C) 2001 David S. Miller
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * DAVID MILLER, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
22 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 *
24 *
25 * David S. Miller <davem@redhat.com>
26 */
27
28 #include "ffb_context.h"
29 #include "ffb_state.h"
30 #include "ffb_lock.h"
31 #include "ffb_bitmap.h"
32 #include "swrast/swrast.h"
33 #include "main/image.h"
34 #include "main/macros.h"
35
36 /* Compute ceiling of integer quotient of A divided by B: */
37 #define CEILING( A, B ) ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 )
38
39 #undef FFB_BITMAP_TRACE
40
41 static void
42 ffb_bitmap(GLcontext *ctx, GLint px, GLint py,
43 GLsizei width, GLsizei height,
44 const struct gl_pixelstore_attrib *unpack,
45 const GLubyte *bitmap)
46 {
47 ffbContextPtr fmesa = FFB_CONTEXT(ctx);
48 ffb_fbcPtr ffb = fmesa->regs;
49 __DRIdrawable *dPriv = fmesa->driDrawable;
50 unsigned int ppc, pixel;
51 GLint row, col, row_stride;
52 const GLubyte *src;
53 char *buf;
54
55 if (fmesa->bad_fragment_attrs != 0)
56 _swrast_Bitmap(ctx, px, py, width,
57 height, unpack, bitmap);
58
59 pixel = (((((GLuint)(ctx->Current.RasterColor[0] * 255.0f)) & 0xff) << 0) |
60 ((((GLuint)(ctx->Current.RasterColor[1] * 255.0f)) & 0xff) << 8) |
61 ((((GLuint)(ctx->Current.RasterColor[2] * 255.0f)) & 0xff) << 16) |
62 ((((GLuint)(ctx->Current.RasterColor[3] * 255.0f)) & 0xff) << 24));
63
64 #ifdef FFB_BITMAP_TRACE
65 fprintf(stderr, "ffb_bitmap: ppc(%08x) fbc(%08x) cmp(%08x) pixel(%08x)\n",
66 fmesa->ppc, fmesa->fbc, fmesa->cmp, pixel);
67 #endif
68
69 LOCK_HARDWARE(fmesa);
70 fmesa->hw_locked = 1;
71
72 if (fmesa->state_dirty)
73 ffbSyncHardware(fmesa);
74
75 ppc = fmesa->ppc;
76
77 FFBFifo(fmesa, 4);
78 ffb->ppc = ((ppc &
79 ~(FFB_PPC_TBE_MASK | FFB_PPC_ZS_MASK | FFB_PPC_CS_MASK | FFB_PPC_XS_MASK))
80 | (FFB_PPC_TBE_TRANSPARENT | FFB_PPC_ZS_CONST | FFB_PPC_CS_CONST |
81 (ctx->Color.BlendEnabled ? FFB_PPC_XS_CONST : FFB_PPC_XS_WID)));
82 ffb->constz = ((GLuint) (ctx->Current.RasterPos[2] * 0x0fffffff));
83 ffb->fg = pixel;
84 ffb->fontinc = (0 << 16) | 32;
85
86 buf = (char *)(fmesa->sfb32 + (dPriv->x << 2) + (dPriv->y << 13));
87
88 row_stride = (unpack->Alignment * CEILING(width, 8 * unpack->Alignment));
89 src = (const GLubyte *) (bitmap +
90 (unpack->SkipRows * row_stride) +
91 (unpack->SkipPixels / 8));
92 if (unpack->LsbFirst == GL_TRUE) {
93 for (row = 0; row < height; row++, src += row_stride) {
94 const GLubyte *row_src = src;
95 GLuint base_x, base_y;
96
97 base_x = dPriv->x + px;
98 base_y = dPriv->y + (dPriv->h - (py + row));
99
100 FFBFifo(fmesa, 1);
101 ffb->fontxy = (base_y << 16) | base_x;
102
103 for (col = 0; col < width; col += 32, row_src += 4) {
104 GLint bitnum, font_w = (width - col);
105 GLuint font_data;
106
107 if (font_w > 32)
108 font_w = 32;
109 font_data = 0;
110 for (bitnum = 0; bitnum < 32; bitnum++) {
111 const GLubyte val = row_src[bitnum >> 3];
112
113 if (val & (1 << (bitnum & (8 - 1))))
114 font_data |= (1 << (31 - bitnum));
115 }
116
117 FFBFifo(fmesa, 2);
118 ffb->fontw = font_w;
119 ffb->font = font_data;
120 }
121 }
122 } else {
123 for (row = 0; row < height; row++, src += row_stride) {
124 const GLubyte *row_src = src;
125 GLuint base_x, base_y;
126
127 base_x = dPriv->x + px;
128 base_y = dPriv->y + (dPriv->h - (py + row));
129
130 FFBFifo(fmesa, 1);
131 ffb->fontxy = (base_y << 16) | base_x;
132
133 for (col = 0; col < width; col += 32, row_src += 4) {
134 GLint font_w = (width - col);
135
136 if (font_w > 32)
137 font_w = 32;
138 FFBFifo(fmesa, 2);
139 ffb->fontw = font_w;
140 ffb->font = (((unsigned int)row_src[0]) << 24 |
141 ((unsigned int)row_src[1]) << 16 |
142 ((unsigned int)row_src[2]) << 8 |
143 ((unsigned int)row_src[3]) << 0);
144 }
145 }
146 }
147
148 FFBFifo(fmesa, 1);
149 ffb->ppc = ppc;
150 fmesa->ffbScreen->rp_active = 1;
151
152 UNLOCK_HARDWARE(fmesa);
153 fmesa->hw_locked = 0;
154 }
155
156 void ffbDDInitBitmapFuncs(GLcontext *ctx)
157 {
158 ctx->Driver.Bitmap = ffb_bitmap;
159 }