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"
321df72402d99145425531297eef6772b88ce5225dEric Anholt#include "main/condrender.h"
33ecadb51bbcb972a79f3ed79e65a7986b9396e757Brian Paul#include "main/mtypes.h"
34ecadb51bbcb972a79f3ed79e65a7986b9396e757Brian Paul#include "main/macros.h"
35b70610b9823fc7dc3672735c11be1a75fbb1a2a4Brian Paul#include "main/pbo.h"
36ecadb51bbcb972a79f3ed79e65a7986b9396e757Brian Paul#include "main/bufferobj.h"
37b9752a2bd615d136369af63ed3d45cc10adf21e7Eric Anholt#include "main/state.h"
38e1a92175542c6645c23cc78f2a4fcd36dd0235e6Eric Anholt#include "main/texobj.h"
39dfc7b7212f57080d18c4d1122435c4c4575694c7Vinson Lee#include "main/context.h"
40c738ea1191cd1b5a0dc60b0e6d05fd918083e961Paul Berry#include "main/fbobject.h"
419e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt#include "swrast/swrast.h"
42ef1e1261df02203da4c7ebf708b0edf1b9cd16c2Vinson Lee#include "drivers/common/meta.h"
439e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
449e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt#include "intel_screen.h"
459e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt#include "intel_context.h"
469e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt#include "intel_batchbuffer.h"
479e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt#include "intel_blit.h"
489e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt#include "intel_regions.h"
49c99fa92ff84e927c82e1231d96921fda9a2b0852Kristian Høgsberg#include "intel_buffers.h"
50c99fa92ff84e927c82e1231d96921fda9a2b0852Kristian Høgsberg#include "intel_pixel.h"
51f75843a517bd188639e6866db2a7b04de3524e16Dave Airlie#include "intel_reg.h"
529e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
539e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
549e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt#define FILE_DEBUG_FLAG DEBUG_PIXEL
559e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
569e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
579e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt/* Unlike the other intel_pixel_* functions, the expectation here is
589e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * that the incoming data is not in a PBO.  With the XY_TEXT blit
599e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * method, there's no benefit haveing it in a PBO, but we could
609e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * implement a path based on XY_MONO_SRC_COPY_BLIT which might benefit
619e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * PBO bitmaps.  I think they are probably pretty rare though - I
629e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * wonder if Xgl uses them?
639e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt */
64f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic const GLubyte *map_pbo( struct gl_context *ctx,
659e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt			       GLsizei width, GLsizei height,
669e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt			       const struct gl_pixelstore_attrib *unpack,
679e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt			       const GLubyte *bitmap )
689e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt{
699e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   GLubyte *buf;
709e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
719e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   if (!_mesa_validate_pbo_access(2, unpack, width, height, 1,
729e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt				  GL_COLOR_INDEX, GL_BITMAP,
736b329b9274b18c50f4177eef7ee087d50ebc1525Brian Paul				  INT_MAX, (const GLvoid *) bitmap)) {
749e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      _mesa_error(ctx, GL_INVALID_OPERATION,"glBitmap(invalid PBO access)");
759e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      return NULL;
769e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   }
779e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
7828249bd260f4c52badf3eb61ade2744604b21bcaIan Romanick   buf = (GLubyte *) ctx->Driver.MapBufferRange(ctx, 0, unpack->BufferObj->Size,
7928249bd260f4c52badf3eb61ade2744604b21bcaIan Romanick						GL_MAP_READ_BIT,
8028249bd260f4c52badf3eb61ade2744604b21bcaIan Romanick						unpack->BufferObj);
819e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   if (!buf) {
829e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      _mesa_error(ctx, GL_INVALID_OPERATION, "glBitmap(PBO is mapped)");
839e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      return NULL;
849e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   }
859e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
869e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   return ADD_POINTERS(buf, bitmap);
879e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt}
889e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
892e5a1a254ed81b1d3efa6064f48183eefac784d0Kenneth Graunkestatic bool test_bit( const GLubyte *src, GLuint bit )
909e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt{
919e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   return (src[bit/8] & (1<<(bit % 8))) ? 1 : 0;
929e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt}
939e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
9429e22059a927a6279d035cdb149b053f8a3e0bf4Brian Paulstatic void set_bit( GLubyte *dest, GLuint bit )
959e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt{
969e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   dest[bit/8] |= 1 << (bit % 8);
979e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt}
989e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
999e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt/* Extract a rectangle's worth of data from the bitmap.  Called
10041f4d82ba8e2497d9fe27f55cb1b8707862fed46Eric Anholt * per chunk of HW-sized bitmap.
1019e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt */
1029e68e191ac9d32f2f93e840a66127e724b442756Eric Anholtstatic GLuint get_bitmap_rect(GLsizei width, GLsizei height,
1039e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt			      const struct gl_pixelstore_attrib *unpack,
1049e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt			      const GLubyte *bitmap,
1059e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt			      GLuint x, GLuint y,
1069e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt			      GLuint w, GLuint h,
1079e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt			      GLubyte *dest,
1089e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt			      GLuint row_align,
1092e5a1a254ed81b1d3efa6064f48183eefac784d0Kenneth Graunke			      bool invert)
1109e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt{
1119e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   GLuint src_offset = (x + unpack->SkipPixels) & 0x7;
1129e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   GLuint mask = unpack->LsbFirst ? 0 : 7;
1139e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   GLuint bit = 0;
1149e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   GLint row, col;
1159e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   GLint first, last;
1169e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   GLint incr;
1179e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   GLuint count = 0;
1189e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
119bb1540835056cdea5db6f55b19c0c87358f14cd1Eric Anholt   DBG("%s %d,%d %dx%d bitmap %dx%d skip %d src_offset %d mask %d\n",
120bb1540835056cdea5db6f55b19c0c87358f14cd1Eric Anholt       __FUNCTION__, x,y,w,h,width,height,unpack->SkipPixels, src_offset, mask);
1219e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
1229e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   if (invert) {
1239e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      first = h-1;
1249e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      last = 0;
1259e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      incr = -1;
1269e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   }
1279e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   else {
1289e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      first = 0;
1299e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      last = h-1;
1309e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      incr = 1;
1319e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   }
1329e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
1339e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   /* Require that dest be pre-zero'd.
1349e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt    */
1359e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   for (row = first; row != (last+incr); row += incr) {
1369e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      const GLubyte *rowsrc = _mesa_image_address2d(unpack, bitmap,
1379e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt						    width, height,
1389e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt						    GL_COLOR_INDEX, GL_BITMAP,
1399e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt						    y + row, x);
1409e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
1419e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      for (col = 0; col < w; col++, bit++) {
1429e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	 if (test_bit(rowsrc, (col + src_offset) ^ mask)) {
1439e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	    set_bit(dest, bit ^ 7);
1449e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	    count++;
1459e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	 }
1469e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      }
1479e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
1489e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      if (row_align)
1499e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	 bit = ALIGN(bit, row_align);
1509e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   }
1519e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
1529e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   return count;
1539e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt}
1549e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
1551db63713046efd49071aae448105df8a80e1e83dEric Anholt/**
1561db63713046efd49071aae448105df8a80e1e83dEric Anholt * Returns the low Y value of the vertical range given, flipped according to
1571db63713046efd49071aae448105df8a80e1e83dEric Anholt * whether the framebuffer is or not.
1581db63713046efd49071aae448105df8a80e1e83dEric Anholt */
159c67bb15d4e3da430d511444bd7d159ccb0c84b73Vinson Leestatic INLINE int
1601db63713046efd49071aae448105df8a80e1e83dEric Anholty_flip(struct gl_framebuffer *fb, int y, int height)
1611db63713046efd49071aae448105df8a80e1e83dEric Anholt{
162c738ea1191cd1b5a0dc60b0e6d05fd918083e961Paul Berry   if (_mesa_is_user_fbo(fb))
1631db63713046efd49071aae448105df8a80e1e83dEric Anholt      return y;
1641db63713046efd49071aae448105df8a80e1e83dEric Anholt   else
1651db63713046efd49071aae448105df8a80e1e83dEric Anholt      return fb->Height - y - height;
1661db63713046efd49071aae448105df8a80e1e83dEric Anholt}
1679e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
1689e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt/*
1699e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * Render a bitmap.
1709e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt */
1712e5a1a254ed81b1d3efa6064f48183eefac784d0Kenneth Graunkestatic bool
172f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergdo_blit_bitmap( struct gl_context *ctx,
1739e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt		GLint dstx, GLint dsty,
1749e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt		GLsizei width, GLsizei height,
1759e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt		const struct gl_pixelstore_attrib *unpack,
1769e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt		const GLubyte *bitmap )
1779e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt{
1789e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   struct intel_context *intel = intel_context(ctx);
179066bee64e1611093c7e641ba77bbd43f70d08cecEric Anholt   struct intel_region *dst;
180cb433d91c6e198b7c77f747f1a38803532bc9be9Eric Anholt   struct gl_framebuffer *fb = ctx->DrawBuffer;
1819e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   GLfloat tmpColor[4];
1825982d397990fd2ae4c729977cf8d22da5ef29987Xiang, Haihao   GLubyte ubcolor[4];
1838f81a6468fdbc7320800ea497791e3e1b8f782caEric Anholt   GLuint color;
184e67350da34c6009edff50c160df27493cb363e1bEric Anholt   GLsizei bitmap_width = width;
185e67350da34c6009edff50c160df27493cb363e1bEric Anholt   GLsizei bitmap_height = height;
186348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt   GLint px, py;
187348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt   GLuint stipple[32];
188348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt   GLint orig_dstx = dstx;
189348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt   GLint orig_dsty = dsty;
1909e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
191b9752a2bd615d136369af63ed3d45cc10adf21e7Eric Anholt   /* Update draw buffer bounds */
192b9752a2bd615d136369af63ed3d45cc10adf21e7Eric Anholt   _mesa_update_state(ctx);
193b9752a2bd615d136369af63ed3d45cc10adf21e7Eric Anholt
1943a5463d158eff483a992c9792d771fb80db9aed0Brian Paul   if (ctx->Depth.Test) {
1953a5463d158eff483a992c9792d771fb80db9aed0Brian Paul      /* The blit path produces incorrect results when depth testing is on.
1963a5463d158eff483a992c9792d771fb80db9aed0Brian Paul       * It seems the blit Z coord is always 1.0 (the far plane) so fragments
1973a5463d158eff483a992c9792d771fb80db9aed0Brian Paul       * will likely be obscured by other, closer geometry.
1983a5463d158eff483a992c9792d771fb80db9aed0Brian Paul       */
1992e5a1a254ed81b1d3efa6064f48183eefac784d0Kenneth Graunke      return false;
2003a5463d158eff483a992c9792d771fb80db9aed0Brian Paul   }
2013a5463d158eff483a992c9792d771fb80db9aed0Brian Paul
202066bee64e1611093c7e641ba77bbd43f70d08cecEric Anholt   intel_prepare_render(intel);
203066bee64e1611093c7e641ba77bbd43f70d08cecEric Anholt   dst = intel_drawbuf_region(intel);
204066bee64e1611093c7e641ba77bbd43f70d08cecEric Anholt
2059e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   if (!dst)
2062e5a1a254ed81b1d3efa6064f48183eefac784d0Kenneth Graunke       return false;
2079e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
208abdf2e14bc174ecd510b580756efa42f43ca4419Brian Paul   if (_mesa_is_bufferobj(unpack->BufferObj)) {
2099e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      bitmap = map_pbo(ctx, width, height, unpack, bitmap);
2109e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      if (bitmap == NULL)
2112e5a1a254ed81b1d3efa6064f48183eefac784d0Kenneth Graunke	 return true;	/* even though this is an error, we're done */
2129e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   }
2139e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
2149e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   COPY_4V(tmpColor, ctx->Current.RasterColor);
2159e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
216decc6e2a32ef49e673c081f30e19b8970155d887Brian Paul   if (_mesa_need_secondary_color(ctx)) {
2179e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt       ADD_3V(tmpColor, tmpColor, ctx->Current.RasterSecondaryColor);
2189e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   }
2199e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
2205982d397990fd2ae4c729977cf8d22da5ef29987Xiang, Haihao   UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[0], tmpColor[0]);
2215982d397990fd2ae4c729977cf8d22da5ef29987Xiang, Haihao   UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[1], tmpColor[1]);
2225982d397990fd2ae4c729977cf8d22da5ef29987Xiang, Haihao   UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[2], tmpColor[2]);
2235982d397990fd2ae4c729977cf8d22da5ef29987Xiang, Haihao   UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[3], tmpColor[3]);
2245982d397990fd2ae4c729977cf8d22da5ef29987Xiang, Haihao
2258f81a6468fdbc7320800ea497791e3e1b8f782caEric Anholt   if (dst->cpp == 2)
226ee64347979b4e22976910cb97869887f7de4241cEric Anholt      color = PACK_COLOR_565(ubcolor[0], ubcolor[1], ubcolor[2]);
2278f81a6468fdbc7320800ea497791e3e1b8f782caEric Anholt   else
228ee64347979b4e22976910cb97869887f7de4241cEric Anholt      color = PACK_COLOR_8888(ubcolor[3], ubcolor[0], ubcolor[1], ubcolor[2]);
2299e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
23069e10084cd3ac9b814b311913138882a32f9f2eaEric Anholt   if (!intel_check_blit_fragment_ops(ctx, tmpColor[3] == 1.0F))
2312e5a1a254ed81b1d3efa6064f48183eefac784d0Kenneth Graunke      return false;
2329e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
233348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt   /* Clip to buffer bounds and scissor. */
234348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt   if (!_mesa_clip_to_region(fb->_Xmin, fb->_Ymin,
235348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt			     fb->_Xmax, fb->_Ymax,
236348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt			     &dstx, &dsty, &width, &height))
237348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt      goto out;
238348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt
239348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt   dsty = y_flip(fb, dsty, height);
2409e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
2419e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt#define DY 32
2429e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt#define DX 32
2439e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
244348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt   /* Chop it all into chunks that can be digested by hardware: */
245348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt   for (py = 0; py < height; py += DY) {
246348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt      for (px = 0; px < width; px += DX) {
247348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt	 int h = MIN2(DY, height - py);
248348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt	 int w = MIN2(DX, width - px);
249348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt	 GLuint sz = ALIGN(ALIGN(w,8) * h, 64)/8;
250348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt	 GLenum logic_op = ctx->Color.ColorLogicOpEnabled ?
251348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt	    ctx->Color.LogicOp : GL_COPY;
252348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt
253348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt	 assert(sz <= sizeof(stipple));
254348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt	 memset(stipple, 0, sz);
255348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt
256348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt	 /* May need to adjust this when padding has been introduced in
257348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt	  * sz above:
258348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt	  *
259348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt	  * Have to translate destination coordinates back into source
260348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt	  * coordinates.
2619e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	  */
262348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt	 if (get_bitmap_rect(bitmap_width, bitmap_height, unpack,
263348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt			     bitmap,
264348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt			     -orig_dstx + (dstx + px),
265348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt			     -orig_dsty + y_flip(fb, dsty + py, h),
266348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt			     w, h,
267348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt			     (GLubyte *)stipple,
268348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt			     8,
269c738ea1191cd1b5a0dc60b0e6d05fd918083e961Paul Berry			     _mesa_is_winsys_fbo(fb)) == 0)
270348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt	    continue;
271348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt
272348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt	 if (!intelEmitImmediateColorExpandBlit(intel,
273348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt						dst->cpp,
274348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt						(GLubyte *)stipple,
275348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt						sz,
276348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt						color,
277348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt						dst->pitch,
2788004a1cb95b8a195f3f4bbaa8d39d2f3297167deEric Anholt						dst->bo,
279348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt						0,
280348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt						dst->tiling,
281348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt						dstx + px,
282348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt						dsty + py,
283348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt						w, h,
284348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt						logic_op)) {
2852e5a1a254ed81b1d3efa6064f48183eefac784d0Kenneth Graunke	    return false;
286348fadc5df83c22b237c59f1aed26573ab9f7506Eric Anholt	 }
2879e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      }
2889e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   }
289f75843a517bd188639e6866db2a7b04de3524e16Dave Airlieout:
2909e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
291bb1540835056cdea5db6f55b19c0c87358f14cd1Eric Anholt   if (unlikely(INTEL_DEBUG & DEBUG_SYNC))
2928d68a90e225d831a395ba788e425cb717eec1f9aChris Wilson      intel_batchbuffer_flush(intel);
2939e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
294abdf2e14bc174ecd510b580756efa42f43ca4419Brian Paul   if (_mesa_is_bufferobj(unpack->BufferObj)) {
2959e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      /* done with PBO so unmap it now */
29656f0c00f125ee75caeadc1c9e8cab8a488635e5eIan Romanick      ctx->Driver.UnmapBuffer(ctx, unpack->BufferObj);
2979e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   }
2989e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
299a7e4a311e971005f7b23572ff3ca93f6d3c17edfEric Anholt   intel_check_front_buffer_rendering(intel);
300a7e4a311e971005f7b23572ff3ca93f6d3c17edfEric Anholt
3012e5a1a254ed81b1d3efa6064f48183eefac784d0Kenneth Graunke   return true;
3029e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt}
3039e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
304bb1540835056cdea5db6f55b19c0c87358f14cd1Eric Anholt
3059e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt/* There are a large number of possible ways to implement bitmap on
3069e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * this hardware, most of them have some sort of drawback.  Here are a
3079e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * few that spring to mind:
3089e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt *
3099e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * Blit:
3109e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt *    - XY_MONO_SRC_BLT_CMD
3119e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt *         - use XY_SETUP_CLIP_BLT for cliprect clipping.
3129e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt *    - XY_TEXT_BLT
3139e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt *    - XY_TEXT_IMMEDIATE_BLT
3149e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt *         - blit per cliprect, subject to maximum immediate data size.
3159e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt *    - XY_COLOR_BLT
3169e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt *         - per pixel or run of pixels
3179e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt *    - XY_PIXEL_BLT
3189e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt *         - good for sparse bitmaps
3199e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt *
3209e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt * 3D engine:
3219e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt *    - Point per pixel
3229e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt *    - Translate bitmap to an alpha texture and render as a quad
3239e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt *    - Chop bitmap up into 32x32 squares and render w/polygon stipple.
3249e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt */
3259e68e191ac9d32f2f93e840a66127e724b442756Eric Anholtvoid
326f9995b30756140724f41daf963fa06167912be7fKristian HøgsbergintelBitmap(struct gl_context * ctx,
3279e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	    GLint x, GLint y,
3289e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	    GLsizei width, GLsizei height,
3299e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	    const struct gl_pixelstore_attrib *unpack,
3309e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt	    const GLubyte * pixels)
3319e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt{
3321df72402d99145425531297eef6772b88ce5225dEric Anholt   if (!_mesa_check_conditional_render(ctx))
3331df72402d99145425531297eef6772b88ce5225dEric Anholt      return;
3341df72402d99145425531297eef6772b88ce5225dEric Anholt
3359e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt   if (do_blit_bitmap(ctx, x, y, width, height,
3369e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt                          unpack, pixels))
3379e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt      return;
3389e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt
339fae18559461e62af623be77787ecba4c7013a8b4Eric Anholt   _mesa_meta_Bitmap(ctx, x, y, width, height, unpack, pixels);
3409e68e191ac9d32f2f93e840a66127e724b442756Eric Anholt}
341