intel_pixel_bitmap.c revision ecadb51bbcb972a79f3ed79e65a7986b9396e757
19e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt/**************************************************************************
29e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt *
39e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
49e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * All Rights Reserved.
59e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt *
69e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * Permission is hereby granted, free of charge, to any person obtaining a
79e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * copy of this software and associated documentation files (the
89e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * "Software"), to deal in the Software without restriction, including
99e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * without limitation the rights to use, copy, modify, merge, publish,
109e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * distribute, sub license, and/or sell copies of the Software, and to
119e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * permit persons to whom the Software is furnished to do so, subject to
129e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * the following conditions:
139e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt *
149e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * The above copyright notice and this permission notice (including the
159e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * next paragraph) shall be included in all copies or substantial portionsalloc
169e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * of the Software.
179e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt *
189e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
199e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
209e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
219e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
229e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
239e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
249e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
259e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt *
269e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt **************************************************************************/
279e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
28ecadb51bbcb972a79f3ed79e65a7986b9396e757Brian Paul#include "main/glheader.h"
29ecadb51bbcb972a79f3ed79e65a7986b9396e757Brian Paul#include "main/enums.h"
30ecadb51bbcb972a79f3ed79e65a7986b9396e757Brian Paul#include "main/image.h"
31ecadb51bbcb972a79f3ed79e65a7986b9396e757Brian Paul#include "main/colormac.h"
32ecadb51bbcb972a79f3ed79e65a7986b9396e757Brian Paul#include "main/mtypes.h"
33ecadb51bbcb972a79f3ed79e65a7986b9396e757Brian Paul#include "main/macros.h"
34ecadb51bbcb972a79f3ed79e65a7986b9396e757Brian Paul#include "main/bufferobj.h"
359e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt#include "swrast/swrast.h"
369e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
379e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt#include "intel_screen.h"
389e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt#include "intel_context.h"
399e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt#include "intel_batchbuffer.h"
409e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt#include "intel_blit.h"
419e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt#include "intel_regions.h"
429e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt#include "intel_buffer_objects.h"
43c99fa92ff84e927c82e1231d96921fda9a2b0852Kristian Høgsberg#include "intel_buffers.h"
44c99fa92ff84e927c82e1231d96921fda9a2b0852Kristian Høgsberg#include "intel_pixel.h"
45f75843a517bd188639e6866db2a7b04de3524e16Dave Airlie#include "intel_reg.h"
469e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
479e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
489e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt#define FILE_DEBUG_FLAG DEBUG_PIXEL
499e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
509e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
519e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt/* Unlike the other intel_pixel_* functions, the expectation here is
529e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * that the incoming data is not in a PBO.  With the XY_TEXT blit
539e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * method, there's no benefit haveing it in a PBO, but we could
549e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * implement a path based on XY_MONO_SRC_COPY_BLIT which might benefit
559e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * PBO bitmaps.  I think they are probably pretty rare though - I
569e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * wonder if Xgl uses them?
579e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt */
589e68e191ac9d32f2f93e840a66127e724b442756Eric Anholtstatic const GLubyte *map_pbo( GLcontext *ctx,
599e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt			       GLsizei width, GLsizei height,
609e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt			       const struct gl_pixelstore_attrib *unpack,
619e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt			       const GLubyte *bitmap )
629e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt{
639e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   GLubyte *buf;
649e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
659e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   if (!_mesa_validate_pbo_access(2, unpack, width, height, 1,
669e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt				  GL_COLOR_INDEX, GL_BITMAP,
679e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt				  (GLvoid *) bitmap)) {
689e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      _mesa_error(ctx, GL_INVALID_OPERATION,"glBitmap(invalid PBO access)");
699e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      return NULL;
709e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   }
719e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
729e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
739e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt					   GL_READ_ONLY_ARB,
749e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt					   unpack->BufferObj);
759e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   if (!buf) {
769e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      _mesa_error(ctx, GL_INVALID_OPERATION, "glBitmap(PBO is mapped)");
779e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      return NULL;
789e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   }
799e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
809e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   return ADD_POINTERS(buf, bitmap);
819e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt}
829e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
839e68e191ac9d32f2f93e840a66127e724b442756Eric Anholtstatic GLboolean test_bit( const GLubyte *src,
849e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt			    GLuint bit )
859e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt{
869e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   return (src[bit/8] & (1<<(bit % 8))) ? 1 : 0;
879e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt}
889e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
899e68e191ac9d32f2f93e840a66127e724b442756Eric Anholtstatic void set_bit( GLubyte *dest,
909e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt			  GLuint bit )
919e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt{
929e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   dest[bit/8] |= 1 << (bit % 8);
939e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt}
949e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
959e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt/* Extract a rectangle's worth of data from the bitmap.  Called
969e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * per-cliprect.
979e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt */
989e68e191ac9d32f2f93e840a66127e724b442756Eric Anholtstatic GLuint get_bitmap_rect(GLsizei width, GLsizei height,
999e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt			      const struct gl_pixelstore_attrib *unpack,
1009e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt			      const GLubyte *bitmap,
1019e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt			      GLuint x, GLuint y,
1029e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt			      GLuint w, GLuint h,
1039e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt			      GLubyte *dest,
1049e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt			      GLuint row_align,
1059e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt			      GLboolean invert)
1069e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt{
1079e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   GLuint src_offset = (x + unpack->SkipPixels) & 0x7;
1089e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   GLuint mask = unpack->LsbFirst ? 0 : 7;
1099e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   GLuint bit = 0;
1109e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   GLint row, col;
1119e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   GLint first, last;
1129e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   GLint incr;
1139e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   GLuint count = 0;
1149e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
1159e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   if (INTEL_DEBUG & DEBUG_PIXEL)
1169e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      _mesa_printf("%s %d,%d %dx%d bitmap %dx%d skip %d src_offset %d mask %d\n",
1179e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt		   __FUNCTION__, x,y,w,h,width,height,unpack->SkipPixels, src_offset, mask);
1189e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
1199e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   if (invert) {
1209e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      first = h-1;
1219e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      last = 0;
1229e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      incr = -1;
1239e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   }
1249e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   else {
1259e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      first = 0;
1269e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      last = h-1;
1279e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      incr = 1;
1289e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   }
1299e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
1309e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   /* Require that dest be pre-zero'd.
1319e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt    */
1329e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   for (row = first; row != (last+incr); row += incr) {
1339e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      const GLubyte *rowsrc = _mesa_image_address2d(unpack, bitmap,
1349e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt						    width, height,
1359e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt						    GL_COLOR_INDEX, GL_BITMAP,
1369e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt						    y + row, x);
1379e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
1389e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      for (col = 0; col < w; col++, bit++) {
1399e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	 if (test_bit(rowsrc, (col + src_offset) ^ mask)) {
1409e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	    set_bit(dest, bit ^ 7);
1419e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	    count++;
1429e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	 }
1439e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      }
1449e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
1459e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      if (row_align)
1469e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	 bit = ALIGN(bit, row_align);
1479e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   }
1489e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
1499e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   return count;
1509e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt}
1519e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
1529e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
1539e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
1549e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
1559e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt/*
1569e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * Render a bitmap.
1579e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt */
1589e68e191ac9d32f2f93e840a66127e724b442756Eric Anholtstatic GLboolean
1599e68e191ac9d32f2f93e840a66127e724b442756Eric Anholtdo_blit_bitmap( GLcontext *ctx,
1609e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt		GLint dstx, GLint dsty,
1619e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt		GLsizei width, GLsizei height,
1629e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt		const struct gl_pixelstore_attrib *unpack,
1639e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt		const GLubyte *bitmap )
1649e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt{
1659e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   struct intel_context *intel = intel_context(ctx);
1669e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   struct intel_region *dst = intel_drawbuf_region(intel);
1679e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   GLfloat tmpColor[4];
1685982d397990fd2ae4c729977cf8d22da5ef29987Xiang, Haihao   GLubyte ubcolor[4];
1695982d397990fd2ae4c729977cf8d22da5ef29987Xiang, Haihao   GLuint color8888, color565;
1709e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
1719e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   if (!dst)
1729e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt       return GL_FALSE;
1739e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
1749e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   if (unpack->BufferObj->Name) {
1759e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      bitmap = map_pbo(ctx, width, height, unpack, bitmap);
1769e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      if (bitmap == NULL)
1779e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	 return GL_TRUE;	/* even though this is an error, we're done */
1789e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   }
1799e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
1809e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   COPY_4V(tmpColor, ctx->Current.RasterColor);
1819e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
1829e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   if (NEED_SECONDARY_COLOR(ctx)) {
1839e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt       ADD_3V(tmpColor, tmpColor, ctx->Current.RasterSecondaryColor);
1849e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   }
1859e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
1865982d397990fd2ae4c729977cf8d22da5ef29987Xiang, Haihao   UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[0], tmpColor[0]);
1875982d397990fd2ae4c729977cf8d22da5ef29987Xiang, Haihao   UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[1], tmpColor[1]);
1885982d397990fd2ae4c729977cf8d22da5ef29987Xiang, Haihao   UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[2], tmpColor[2]);
1895982d397990fd2ae4c729977cf8d22da5ef29987Xiang, Haihao   UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[3], tmpColor[3]);
1905982d397990fd2ae4c729977cf8d22da5ef29987Xiang, Haihao
1915982d397990fd2ae4c729977cf8d22da5ef29987Xiang, Haihao   color8888 = INTEL_PACKCOLOR8888(ubcolor[0], ubcolor[1], ubcolor[2], ubcolor[3]);
1925982d397990fd2ae4c729977cf8d22da5ef29987Xiang, Haihao   color565 = INTEL_PACKCOLOR565(ubcolor[0], ubcolor[1], ubcolor[2]);
1939e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
1949e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   /* Does zoom apply to bitmaps?
1959e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt    */
196f5eb62a1161f050925c5c0b4839c437b29bdbc6bEric Anholt   if (!intel_check_blit_fragment_ops(ctx, tmpColor[3] == 1.0F) ||
1979e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt       ctx->Pixel.ZoomX != 1.0F ||
1989e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt       ctx->Pixel.ZoomY != 1.0F)
1999e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      return GL_FALSE;
2009e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
2019e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   LOCK_HARDWARE(intel);
2029e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
2039e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   if (intel->driDrawable->numClipRects) {
2049e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      __DRIdrawablePrivate *dPriv = intel->driDrawable;
2059e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      drm_clip_rect_t *box = dPriv->pClipRects;
2069e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      drm_clip_rect_t dest_rect;
2079e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      GLint nbox = dPriv->numClipRects;
2089e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      GLint srcx = 0, srcy = 0;
2099e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      GLint orig_screen_x1, orig_screen_y2;
2109e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      GLuint i;
2119e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
2129e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
2139e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      orig_screen_x1 = dPriv->x + dstx;
2149e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      orig_screen_y2 = dPriv->y + (dPriv->h - dsty);
2159e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
2169e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      /* Do scissoring in GL coordinates:
2179e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt       */
2189e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      if (ctx->Scissor.Enabled)
2199e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      {
2209e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	 GLint x = ctx->Scissor.X;
2219e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	 GLint y = ctx->Scissor.Y;
2229e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	 GLuint w = ctx->Scissor.Width;
2239e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	 GLuint h = ctx->Scissor.Height;
2249e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
2259e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt         if (!_mesa_clip_to_region(x, y, x+w-1, y+h-1, &dstx, &dsty, &width, &height))
2269e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt            goto out;
2279e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      }
2289e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
2299e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      /* Convert from GL to hardware coordinates:
2309e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt       */
2319e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      dsty = dPriv->y + (dPriv->h - dsty - height);
2329e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      dstx = dPriv->x + dstx;
2339e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
2349e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      dest_rect.x1 = dstx < 0 ? 0 : dstx;
2359e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      dest_rect.y1 = dsty < 0 ? 0 : dsty;
2369e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      dest_rect.x2 = dstx + width < 0 ? 0 : dstx + width;
2379e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      dest_rect.y2 = dsty + height < 0 ? 0 : dsty + height;
2389e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
2399e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      for (i = 0; i < nbox; i++) {
2409e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt         drm_clip_rect_t rect;
2419e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	 int box_w, box_h;
2429e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	 GLint px, py;
2439e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	 GLuint stipple[32];
2449e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
2459e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt         if (!intel_intersect_cliprects(&rect, &dest_rect, &box[i]))
2469e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt            continue;
2479e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
2489e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	 /* Now go back to GL coordinates to figure out what subset of
2499e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	  * the bitmap we are uploading for this cliprect:
2509e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	  */
2519e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	 box_w = rect.x2 - rect.x1;
2529e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	 box_h = rect.y2 - rect.y1;
2539e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	 srcx = rect.x1 - orig_screen_x1;
2549e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	 srcy = orig_screen_y2 - rect.y2;
2559e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
2569e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
2579e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt#define DY 32
2589e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt#define DX 32
2599e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
2609e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	 /* Then, finally, chop it all into chunks that can be
2619e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	  * digested by hardware:
2629e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	  */
2639e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	 for (py = 0; py < box_h; py += DY) {
2649e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	    for (px = 0; px < box_w; px += DX) {
2659e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	       int h = MIN2(DY, box_h - py);
2669e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	       int w = MIN2(DX, box_w - px);
2679e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	       GLuint sz = ALIGN(ALIGN(w,8) * h, 64)/8;
2689e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	       GLenum logic_op = ctx->Color.ColorLogicOpEnabled ?
2699e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt		  ctx->Color.LogicOp : GL_COPY;
2709e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
2719e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	       assert(sz <= sizeof(stipple));
2729e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	       memset(stipple, 0, sz);
2739e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
2749e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	       /* May need to adjust this when padding has been introduced in
2759e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt		* sz above:
2769e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt		*/
2779e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	       if (get_bitmap_rect(width, height, unpack,
2789e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt				   bitmap,
2799e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt				   srcx + px, srcy + py, w, h,
2809e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt				   (GLubyte *)stipple,
2819e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt				   8,
2829e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt				   GL_TRUE) == 0)
2839e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt		  continue;
2849e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
2859e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	       /*
2869e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt		*/
2879e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	       intelEmitImmediateColorExpandBlit( intel,
2889e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt						  dst->cpp,
2899e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt						  (GLubyte *)stipple,
2909e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt						  sz,
2915982d397990fd2ae4c729977cf8d22da5ef29987Xiang, Haihao						  (dst->cpp == 2) ? color565 : color8888,
2929e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt						  dst->pitch,
2939e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt						  dst->buffer,
2949e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt						  0,
295f75843a517bd188639e6866db2a7b04de3524e16Dave Airlie						  dst->tiling,
2969e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt						  rect.x1 + px,
2979e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt						  rect.y2 - (py + h),
2989e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt						  w, h,
2999e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt						  logic_op);
3009e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	    }
3019e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	 }
3029e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      }
3039e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   }
304f75843a517bd188639e6866db2a7b04de3524e16Dave Airlieout:
3059e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   UNLOCK_HARDWARE(intel);
3069e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
3079e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
3089e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   if (unpack->BufferObj->Name) {
3099e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      /* done with PBO so unmap it now */
3109e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
3119e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt                              unpack->BufferObj);
3129e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   }
3139e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
3149e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   return GL_TRUE;
3159e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt}
3169e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
3179e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
3189e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
3199e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
3209e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
3219e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt/* There are a large number of possible ways to implement bitmap on
3229e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * this hardware, most of them have some sort of drawback.  Here are a
3239e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * few that spring to mind:
3249e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt *
3259e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * Blit:
3269e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt *    - XY_MONO_SRC_BLT_CMD
3279e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt *         - use XY_SETUP_CLIP_BLT for cliprect clipping.
3289e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt *    - XY_TEXT_BLT
3299e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt *    - XY_TEXT_IMMEDIATE_BLT
3309e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt *         - blit per cliprect, subject to maximum immediate data size.
3319e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt *    - XY_COLOR_BLT
3329e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt *         - per pixel or run of pixels
3339e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt *    - XY_PIXEL_BLT
3349e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt *         - good for sparse bitmaps
3359e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt *
3369e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * 3D engine:
3379e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt *    - Point per pixel
3389e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt *    - Translate bitmap to an alpha texture and render as a quad
3399e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt *    - Chop bitmap up into 32x32 squares and render w/polygon stipple.
3409e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt */
3419e68e191ac9d32f2f93e840a66127e724b442756Eric Anholtvoid
3429e68e191ac9d32f2f93e840a66127e724b442756Eric AnholtintelBitmap(GLcontext * ctx,
3439e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	    GLint x, GLint y,
3449e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	    GLsizei width, GLsizei height,
3459e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	    const struct gl_pixelstore_attrib *unpack,
3469e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	    const GLubyte * pixels)
3479e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt{
3489e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   if (do_blit_bitmap(ctx, x, y, width, height,
3499e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt                          unpack, pixels))
3509e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      return;
3519e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
3529e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   if (INTEL_DEBUG & DEBUG_PIXEL)
3539e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      _mesa_printf("%s: fallback to swrast\n", __FUNCTION__);
3549e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
3559e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   _swrast_Bitmap(ctx, x, y, width, height, unpack, pixels);
3569e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt}
357