Merge branch 'mesa_7_7_branch'
[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/macros.h"
34
35 /* Compute ceiling of integer quotient of A divided by B: */
36 #define CEILING( A, B ) ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 )
37
38 #undef FFB_BITMAP_TRACE
39
40 static void
41 ffb_bitmap(GLcontext *ctx, GLint px, GLint py,
42 GLsizei width, GLsizei height,
43 const struct gl_pixelstore_attrib *unpack,
44 const GLubyte *bitmap)
45 {
46 ffbContextPtr fmesa = FFB_CONTEXT(ctx);
47 ffb_fbcPtr ffb = fmesa->regs;
48 __DRIdrawable *dPriv = fmesa->driDrawable;
49 unsigned int ppc, pixel;
50 GLint row, col, row_stride;
51 const GLubyte *src;
52 char *buf;
53
54 if (fmesa->bad_fragment_attrs != 0)
55 _swrast_Bitmap(ctx, px, py, width,
56 height, unpack, bitmap);
57
58 pixel = (((((GLuint)(ctx->Current.RasterColor[0] * 255.0f)) & 0xff) << 0) |
59 ((((GLuint)(ctx->Current.RasterColor[1] * 255.0f)) & 0xff) << 8) |
60 ((((GLuint)(ctx->Current.RasterColor[2] * 255.0f)) & 0xff) << 16) |
61 ((((GLuint)(ctx->Current.RasterColor[3] * 255.0f)) & 0xff) << 24));
62
63 #ifdef FFB_BITMAP_TRACE
64 fprintf(stderr, "ffb_bitmap: ppc(%08x) fbc(%08x) cmp(%08x) pixel(%08x)\n",
65 fmesa->ppc, fmesa->fbc, fmesa->cmp, pixel);
66 #endif
67
68 LOCK_HARDWARE(fmesa);
69 fmesa->hw_locked = 1;
70
71 if (fmesa->state_dirty)
72 ffbSyncHardware(fmesa);
73
74 ppc = fmesa->ppc;
75
76 FFBFifo(fmesa, 4);
77 ffb->ppc = ((ppc &
78 ~(FFB_PPC_TBE_MASK | FFB_PPC_ZS_MASK | FFB_PPC_CS_MASK | FFB_PPC_XS_MASK))
79 | (FFB_PPC_TBE_TRANSPARENT | FFB_PPC_ZS_CONST | FFB_PPC_CS_CONST |
80 (ctx->Color.BlendEnabled ? FFB_PPC_XS_CONST : FFB_PPC_XS_WID)));
81 ffb->constz = ((GLuint) (ctx->Current.RasterPos[2] * 0x0fffffff));
82 ffb->fg = pixel;
83 ffb->fontinc = (0 << 16) | 32;
84
85 buf = (char *)(fmesa->sfb32 + (dPriv->x << 2) + (dPriv->y << 13));
86
87 row_stride = (unpack->Alignment * CEILING(width, 8 * unpack->Alignment));
88 src = (const GLubyte *) (bitmap +
89 (unpack->SkipRows * row_stride) +
90 (unpack->SkipPixels / 8));
91 if (unpack->LsbFirst == GL_TRUE) {
92 for (row = 0; row < height; row++, src += row_stride) {
93 const GLubyte *row_src = src;
94 GLuint base_x, base_y;
95
96 base_x = dPriv->x + px;
97 base_y = dPriv->y + (dPriv->h - (py + row));
98
99 FFBFifo(fmesa, 1);
100 ffb->fontxy = (base_y << 16) | base_x;
101
102 for (col = 0; col < width; col += 32, row_src += 4) {
103 GLint bitnum, font_w = (width - col);
104 GLuint font_data;
105
106 if (font_w > 32)
107 font_w = 32;
108 font_data = 0;
109 for (bitnum = 0; bitnum < 32; bitnum++) {
110 const GLubyte val = row_src[bitnum >> 3];
111
112 if (val & (1 << (bitnum & (8 - 1))))
113 font_data |= (1 << (31 - bitnum));
114 }
115
116 FFBFifo(fmesa, 2);
117 ffb->fontw = font_w;
118 ffb->font = font_data;
119 }
120 }
121 } else {
122 for (row = 0; row < height; row++, src += row_stride) {
123 const GLubyte *row_src = src;
124 GLuint base_x, base_y;
125
126 base_x = dPriv->x + px;
127 base_y = dPriv->y + (dPriv->h - (py + row));
128
129 FFBFifo(fmesa, 1);
130 ffb->fontxy = (base_y << 16) | base_x;
131
132 for (col = 0; col < width; col += 32, row_src += 4) {
133 GLint font_w = (width - col);
134
135 if (font_w > 32)
136 font_w = 32;
137 FFBFifo(fmesa, 2);
138 ffb->fontw = font_w;
139 ffb->font = (((unsigned int)row_src[0]) << 24 |
140 ((unsigned int)row_src[1]) << 16 |
141 ((unsigned int)row_src[2]) << 8 |
142 ((unsigned int)row_src[3]) << 0);
143 }
144 }
145 }
146
147 FFBFifo(fmesa, 1);
148 ffb->ppc = ppc;
149 fmesa->ffbScreen->rp_active = 1;
150
151 UNLOCK_HARDWARE(fmesa);
152 fmesa->hw_locked = 0;
153 }
154
155 void ffbDDInitBitmapFuncs(GLcontext *ctx)
156 {
157 ctx->Driver.Bitmap = ffb_bitmap;
158 }