Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mesa / drivers / dri / sis / sis6326_clear.c
1 /*
2  * Copyright 2005 Eric Anholt
3  * All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  *
24  * Authors:
25  *    Eric Anholt <anholt@FreeBSD.org>
26  *
27  */
28
29 #include "sis_context.h"
30 #include "sis_state.h"
31 #include "sis_lock.h"
32 #include "sis_reg.h"
33
34 #include "swrast/swrast.h"
35 #include "main/macros.h"
36
37 static void sis_clear_front_buffer(struct gl_context *ctx, GLenum mask, GLint x,
38                                    GLint y, GLint width, GLint height);
39 static void sis_clear_back_buffer(struct gl_context *ctx, GLenum mask, GLint x,
40                                   GLint y, GLint width, GLint height);
41 static void sis_clear_z_buffer(struct gl_context * ctx, GLbitfield mask, GLint x,
42                                GLint y, GLint width, GLint height );
43
44 static void
45 set_color_pattern( sisContextPtr smesa, GLubyte red, GLubyte green,
46                    GLubyte blue, GLubyte alpha )
47 {
48    /* XXX only RGB565 and ARGB8888 */
49    switch (smesa->colorFormat)
50    {
51    case DST_FORMAT_ARGB_8888:
52       smesa->clearColorPattern = (alpha << 24) +
53          (red << 16) + (green << 8) + (blue);
54       break;
55    case DST_FORMAT_RGB_565:
56       smesa->clearColorPattern = ((red >> 3) << 11) +
57          ((green >> 2) << 5) + (blue >> 3);
58       smesa->clearColorPattern |= smesa->clearColorPattern << 16;
59       break;
60    default:
61       sis_fatal_error("Bad dst color format\n");
62    }
63 }
64
65 void
66 sis6326UpdateZPattern(sisContextPtr smesa, GLclampd z)
67 {
68    CLAMPED_FLOAT_TO_USHORT(smesa->clearZStencilPattern, z * 65535.0);
69 }
70
71 void
72 sis6326DDClear(struct gl_context *ctx, GLbitfield mask)
73 {
74    sisContextPtr smesa = SIS_CONTEXT(ctx);
75    GLint x1, y1, width1, height1;
76
77    /* get region after locking: */
78    x1 = ctx->DrawBuffer->_Xmin;
79    y1 = ctx->DrawBuffer->_Ymin;
80    width1 = ctx->DrawBuffer->_Xmax - x1;
81    height1 = ctx->DrawBuffer->_Ymax - y1;
82    y1 = Y_FLIP(y1 + height1 - 1);
83
84    /* XXX: Scissoring */
85    
86    fprintf(stderr, "Clear\n");
87
88    /* Mask out any non-existent buffers */
89    if (smesa->depth.offset == 0 || !ctx->Depth.Mask)
90       mask &= ~BUFFER_BIT_DEPTH;
91
92    LOCK_HARDWARE();
93
94    if (mask & BUFFER_BIT_FRONT_LEFT) {
95       sis_clear_front_buffer(ctx, mask, x1, y1, width1, height1);
96       mask &= ~BUFFER_BIT_FRONT_LEFT;
97    }
98
99    if (mask & BUFFER_BIT_BACK_LEFT) {
100       sis_clear_back_buffer(ctx, mask, x1, y1, width1, height1);
101       mask &= ~BUFFER_BIT_BACK_LEFT;
102    }
103
104    if (mask & BUFFER_BIT_DEPTH) {
105       sis_clear_z_buffer(ctx, mask, x1, y1, width1, height1);
106       mask &= ~BUFFER_BIT_DEPTH;
107    }
108
109    UNLOCK_HARDWARE();
110
111    if (mask != 0)
112       _swrast_Clear(ctx, mask);
113 }
114
115
116 void
117 sis6326DDClearColor(struct gl_context *ctx, const GLfloat color[4])
118 {
119    sisContextPtr smesa = SIS_CONTEXT(ctx);
120    GLubyte c[4];
121
122    CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]);
123    CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]);
124    CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]);
125    CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]);
126
127    set_color_pattern( smesa, c[0], c[1], c[2], c[3] );
128 }
129
130 void
131 sis6326DDClearDepth(struct gl_context *ctx, GLclampd d)
132 {
133    sisContextPtr smesa = SIS_CONTEXT(ctx);
134
135    sis6326UpdateZPattern(smesa, d);
136 }
137
138 static void
139 sis_clear_back_buffer(struct gl_context *ctx, GLenum mask, GLint x, GLint y,
140                       GLint width, GLint height)
141 {
142    sisContextPtr smesa = SIS_CONTEXT(ctx);
143    
144    /* XXX: The order of writing these registers seems to matter, while
145     * it actually shouldn't.
146     */
147    mWait3DCmdQueue(6);
148    MMIO(REG_6326_BitBlt_DstSrcPitch, smesa->back.pitch << 16);
149    MMIO(REG_6326_BitBlt_fgColor, SiS_ROP_PATCOPY |
150         smesa->clearColorPattern);
151    MMIO(REG_6326_BitBlt_bgColor, SiS_ROP_PATCOPY |
152         smesa->clearColorPattern);
153    MMIO(REG_6326_BitBlt_DstAddr, smesa->back.offset +
154         (y+height) * smesa->back.pitch +
155         (x+width) * smesa->bytesPerPixel);
156    MMIO(REG_6326_BitBlt_HeightWidth, ((height-1) << 16) |
157         (width * smesa->bytesPerPixel));
158    MMIO_WMB();
159    MMIO(REG_6326_BitBlt_Cmd, BLT_PAT_BG);
160 }
161
162 static void
163 sis_clear_front_buffer(struct gl_context *ctx, GLenum mask, GLint x, GLint y,
164                        GLint width, GLint height)
165 {
166    sisContextPtr smesa = SIS_CONTEXT(ctx);
167    int count;
168    drm_clip_rect_t *pExtents = NULL;
169    
170    pExtents = smesa->driDrawable->pClipRects;
171    count = smesa->driDrawable->numClipRects;
172
173    mWait3DCmdQueue(3);
174    MMIO(REG_6326_BitBlt_DstSrcPitch, smesa->front.pitch << 16);
175    MMIO(REG_6326_BitBlt_fgColor, SiS_ROP_PATCOPY |
176        smesa->clearColorPattern);
177    MMIO(REG_6326_BitBlt_bgColor, SiS_ROP_PATCOPY |
178        smesa->clearColorPattern);
179
180    while (count--) {
181       GLint x1 = pExtents->x1 - smesa->driDrawable->x;
182       GLint y1 = pExtents->y1 - smesa->driDrawable->y;
183       GLint x2 = pExtents->x2 - smesa->driDrawable->x;
184       GLint y2 = pExtents->y2 - smesa->driDrawable->y;
185
186       if (x > x1)
187          x1 = x;
188       if (y > y1)
189          y1 = y;
190
191       if (x + width < x2)
192          x2 = x + width;
193       if (y + height < y2)
194          y2 = y + height;
195       width = x2 - x1;
196       height = y2 - y1;
197
198       pExtents++;
199
200       if (width <= 0 || height <= 0)
201          continue;
202
203       mWait3DCmdQueue(3);
204       MMIO(REG_6326_BitBlt_DstAddr, smesa->front.offset +
205            (y2-1) * smesa->front.pitch + x2 * smesa->bytesPerPixel);
206       MMIO(REG_6326_BitBlt_HeightWidth, ((height-1) << 16) |
207            (width * smesa->bytesPerPixel));
208       MMIO_WMB();
209       MMIO(REG_6326_BitBlt_Cmd, BLT_PAT_BG);
210    }
211 }
212
213 static void
214 sis_clear_z_buffer(struct gl_context * ctx, GLbitfield mask, GLint x, GLint y,
215                    GLint width, GLint height)
216 {
217    sisContextPtr smesa = SIS_CONTEXT(ctx);
218
219    mWait3DCmdQueue(6);
220    MMIO(REG_6326_BitBlt_DstAddr,
221         smesa->depth.offset + y * smesa->depth.pitch + x * 2);
222    MMIO(REG_6326_BitBlt_DstSrcPitch, smesa->depth.pitch << 16);
223    MMIO(REG_6326_BitBlt_HeightWidth, ((height-1) << 16) | (width * 2));
224    MMIO(REG_6326_BitBlt_fgColor, SiS_ROP_PATCOPY | smesa->clearZStencilPattern);
225    MMIO(REG_6326_BitBlt_bgColor, SiS_ROP_PATCOPY | smesa->clearZStencilPattern);
226    MMIO_WMB();
227    MMIO(REG_6326_BitBlt_Cmd, BLT_PAT_BG | BLT_XINC | BLT_YINC);
228 }
229