summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/sis/sis6326_clear.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri/sis/sis6326_clear.c')
-rw-r--r--src/mesa/drivers/dri/sis/sis6326_clear.c236
1 files changed, 236 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/sis/sis6326_clear.c b/src/mesa/drivers/dri/sis/sis6326_clear.c
new file mode 100644
index 00000000000..be5addb7cf2
--- /dev/null
+++ b/src/mesa/drivers/dri/sis/sis6326_clear.c
@@ -0,0 +1,236 @@
+/*
+ * Copyright 2005 Eric Anholt
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <anholt@FreeBSD.org>
+ *
+ */
+
+#include "sis_context.h"
+#include "sis_state.h"
+#include "sis_lock.h"
+#include "sis_reg.h"
+
+#include "swrast/swrast.h"
+#include "macros.h"
+
+static void sis_clear_front_buffer(GLcontext *ctx, GLenum mask, GLint x,
+ GLint y, GLint width, GLint height);
+static void sis_clear_back_buffer(GLcontext *ctx, GLenum mask, GLint x,
+ GLint y, GLint width, GLint height);
+static void sis_clear_z_buffer(GLcontext * ctx, GLbitfield mask, GLint x,
+ GLint y, GLint width, GLint height );
+
+static void
+set_color_pattern( sisContextPtr smesa, GLubyte red, GLubyte green,
+ GLubyte blue, GLubyte alpha )
+{
+ /* XXX only RGB565 and ARGB8888 */
+ switch (smesa->colorFormat)
+ {
+ case DST_FORMAT_ARGB_8888:
+ smesa->clearColorPattern = (alpha << 24) +
+ (red << 16) + (green << 8) + (blue);
+ break;
+ case DST_FORMAT_RGB_565:
+ smesa->clearColorPattern = ((red >> 3) << 11) +
+ ((green >> 2) << 5) + (blue >> 3);
+ smesa->clearColorPattern |= smesa->clearColorPattern << 16;
+ break;
+ default:
+ sis_fatal_error("Bad dst color format\n");
+ }
+}
+
+void
+sis6326UpdateZPattern(sisContextPtr smesa, GLclampd z)
+{
+ CLAMPED_FLOAT_TO_USHORT(smesa->clearZStencilPattern, z * 65535.0);
+}
+
+void
+sis6326DDClear(GLcontext *ctx, GLbitfield mask, GLboolean all,
+ GLint x, GLint y, GLint width, GLint height)
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ GLint x1, y1, width1, height1;
+
+ if (all) {
+ GLframebuffer *buffer = ctx->DrawBuffer;
+
+ x1 = 0;
+ y1 = 0;
+ width1 = buffer->Width;
+ height1 = buffer->Height;
+ } else {
+ x1 = x;
+ y1 = Y_FLIP(y+height-1);
+ width1 = width;
+ height1 = height;
+ }
+ /* XXX: Scissoring */
+
+ fprintf(stderr, "Clear\n");
+
+ /* Mask out any non-existent buffers */
+ if (smesa->depth.offset == 0 || !ctx->Depth.Mask)
+ mask &= ~BUFFER_BIT_DEPTH;
+
+ LOCK_HARDWARE();
+
+ if (mask & BUFFER_BIT_FRONT_LEFT) {
+ sis_clear_front_buffer(ctx, mask, x1, y1, width1, height1);
+ mask &= ~BUFFER_BIT_FRONT_LEFT;
+ }
+
+ if (mask & BUFFER_BIT_BACK_LEFT) {
+ sis_clear_back_buffer(ctx, mask, x1, y1, width1, height1);
+ mask &= ~BUFFER_BIT_BACK_LEFT;
+ }
+
+ if (mask & BUFFER_BIT_DEPTH) {
+ sis_clear_z_buffer(ctx, mask, x1, y1, width1, height1);
+ mask &= ~BUFFER_BIT_DEPTH;
+ }
+
+ UNLOCK_HARDWARE();
+
+ if (mask != 0)
+ _swrast_Clear(ctx, mask, all, x1, y1, width, height);
+}
+
+
+void
+sis6326DDClearColor(GLcontext *ctx, const GLfloat color[4])
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ GLubyte c[4];
+
+ CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]);
+ CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]);
+ CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]);
+ CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]);
+
+ set_color_pattern( smesa, c[0], c[1], c[2], c[3] );
+}
+
+void
+sis6326DDClearDepth(GLcontext *ctx, GLclampd d)
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+
+ sis6326UpdateZPattern(smesa, d);
+}
+
+static void
+sis_clear_back_buffer(GLcontext *ctx, GLenum mask, GLint x, GLint y,
+ GLint width, GLint height)
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+
+ /* XXX: The order of writing these registers seems to matter, while
+ * it actually shouldn't.
+ */
+ mWait3DCmdQueue(6);
+ MMIO(REG_6326_BitBlt_DstSrcPitch, smesa->back.pitch << 16);
+ MMIO(REG_6326_BitBlt_fgColor, SiS_ROP_PATCOPY |
+ smesa->clearColorPattern);
+ MMIO(REG_6326_BitBlt_bgColor, SiS_ROP_PATCOPY |
+ smesa->clearColorPattern);
+ MMIO(REG_6326_BitBlt_DstAddr, smesa->back.offset +
+ (y+height) * smesa->back.pitch +
+ (x+width) * smesa->bytesPerPixel);
+ MMIO(REG_6326_BitBlt_HeightWidth, ((height-1) << 16) |
+ (width * smesa->bytesPerPixel));
+ MMIO_WMB();
+ MMIO(REG_6326_BitBlt_Cmd, BLT_PAT_BG);
+}
+
+static void
+sis_clear_front_buffer(GLcontext *ctx, GLenum mask, GLint x, GLint y,
+ GLint width, GLint height)
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+ int count;
+ drm_clip_rect_t *pExtents = NULL;
+
+ pExtents = smesa->driDrawable->pClipRects;
+ count = smesa->driDrawable->numClipRects;
+
+ mWait3DCmdQueue(3);
+ MMIO(REG_6326_BitBlt_DstSrcPitch, smesa->front.pitch << 16);
+ MMIO(REG_6326_BitBlt_fgColor, SiS_ROP_PATCOPY |
+ smesa->clearColorPattern);
+ MMIO(REG_6326_BitBlt_bgColor, SiS_ROP_PATCOPY |
+ smesa->clearColorPattern);
+
+ while (count--) {
+ GLint x1 = pExtents->x1 - smesa->driDrawable->x;
+ GLint y1 = pExtents->y1 - smesa->driDrawable->y;
+ GLint x2 = pExtents->x2 - smesa->driDrawable->x;
+ GLint y2 = pExtents->y2 - smesa->driDrawable->y;
+
+ if (x > x1)
+ x1 = x;
+ if (y > y1)
+ y1 = y;
+
+ if (x + width < x2)
+ x2 = x + width;
+ if (y + height < y2)
+ y2 = y + height;
+ width = x2 - x1;
+ height = y2 - y1;
+
+ pExtents++;
+
+ if (width <= 0 || height <= 0)
+ continue;
+
+ mWait3DCmdQueue(3);
+ MMIO(REG_6326_BitBlt_DstAddr, smesa->front.offset +
+ (y2-1) * smesa->front.pitch + x2 * smesa->bytesPerPixel);
+ MMIO(REG_6326_BitBlt_HeightWidth, ((height-1) << 16) |
+ (width * smesa->bytesPerPixel));
+ MMIO_WMB();
+ MMIO(REG_6326_BitBlt_Cmd, BLT_PAT_BG);
+ }
+}
+
+static void
+sis_clear_z_buffer(GLcontext * ctx, GLbitfield mask, GLint x, GLint y,
+ GLint width, GLint height)
+{
+ sisContextPtr smesa = SIS_CONTEXT(ctx);
+
+ mWait3DCmdQueue(6);
+ MMIO(REG_6326_BitBlt_DstAddr,
+ smesa->depth.offset + y * smesa->depth.pitch + x * 2);
+ MMIO(REG_6326_BitBlt_DstSrcPitch, smesa->depth.pitch << 16);
+ MMIO(REG_6326_BitBlt_HeightWidth, ((height-1) << 16) | (width * 2));
+ MMIO(REG_6326_BitBlt_fgColor, SiS_ROP_PATCOPY | smesa->clearZStencilPattern);
+ MMIO(REG_6326_BitBlt_bgColor, SiS_ROP_PATCOPY | smesa->clearZStencilPattern);
+ MMIO_WMB();
+ MMIO(REG_6326_BitBlt_Cmd, BLT_PAT_BG | BLT_XINC | BLT_YINC);
+}
+