1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**************************************************************************
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All Rights Reserved.
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish,
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sub license, and/or sell copies of the Software, and to
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions:
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial portionsalloc
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the Software.
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **************************************************************************/
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/glheader.h"
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/enums.h"
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/image.h"
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/colormac.h"
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/condrender.h"
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/mtypes.h"
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/macros.h"
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/pbo.h"
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/bufferobj.h"
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/state.h"
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/texobj.h"
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/context.h"
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/fbobject.h"
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "swrast/swrast.h"
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "drivers/common/meta.h"
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "intel_screen.h"
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "intel_context.h"
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "intel_batchbuffer.h"
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "intel_blit.h"
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "intel_regions.h"
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "intel_buffers.h"
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "intel_pixel.h"
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "intel_reg.h"
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define FILE_DEBUG_FLAG DEBUG_PIXEL
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Unlike the other intel_pixel_* functions, the expectation here is
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * that the incoming data is not in a PBO.  With the XY_TEXT blit
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * method, there's no benefit haveing it in a PBO, but we could
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * implement a path based on XY_MONO_SRC_COPY_BLIT which might benefit
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * PBO bitmaps.  I think they are probably pretty rare though - I
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * wonder if Xgl uses them?
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const GLubyte *map_pbo( struct gl_context *ctx,
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			       GLsizei width, GLsizei height,
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			       const struct gl_pixelstore_attrib *unpack,
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			       const GLubyte *bitmap )
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLubyte *buf;
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!_mesa_validate_pbo_access(2, unpack, width, height, 1,
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				  GL_COLOR_INDEX, GL_BITMAP,
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				  INT_MAX, (const GLvoid *) bitmap)) {
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_error(ctx, GL_INVALID_OPERATION,"glBitmap(invalid PBO access)");
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   buf = (GLubyte *) ctx->Driver.MapBufferRange(ctx, 0, unpack->BufferObj->Size,
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						GL_MAP_READ_BIT,
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						unpack->BufferObj);
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!buf) {
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_error(ctx, GL_INVALID_OPERATION, "glBitmap(PBO is mapped)");
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return ADD_POINTERS(buf, bitmap);
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic bool test_bit( const GLubyte *src, GLuint bit )
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (src[bit/8] & (1<<(bit % 8))) ? 1 : 0;
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void set_bit( GLubyte *dest, GLuint bit )
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dest[bit/8] |= 1 << (bit % 8);
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Extract a rectangle's worth of data from the bitmap.  Called
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * per chunk of HW-sized bitmap.
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLuint get_bitmap_rect(GLsizei width, GLsizei height,
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			      const struct gl_pixelstore_attrib *unpack,
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			      const GLubyte *bitmap,
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			      GLuint x, GLuint y,
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			      GLuint w, GLuint h,
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			      GLubyte *dest,
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			      GLuint row_align,
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			      bool invert)
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint src_offset = (x + unpack->SkipPixels) & 0x7;
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint mask = unpack->LsbFirst ? 0 : 7;
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint bit = 0;
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint row, col;
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint first, last;
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint incr;
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint count = 0;
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   DBG("%s %d,%d %dx%d bitmap %dx%d skip %d src_offset %d mask %d\n",
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       __FUNCTION__, x,y,w,h,width,height,unpack->SkipPixels, src_offset, mask);
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (invert) {
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      first = h-1;
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      last = 0;
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      incr = -1;
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      first = 0;
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      last = h-1;
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      incr = 1;
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Require that dest be pre-zero'd.
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (row = first; row != (last+incr); row += incr) {
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const GLubyte *rowsrc = _mesa_image_address2d(unpack, bitmap,
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						    width, height,
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						    GL_COLOR_INDEX, GL_BITMAP,
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						    y + row, x);
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (col = 0; col < w; col++, bit++) {
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (test_bit(rowsrc, (col + src_offset) ^ mask)) {
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    set_bit(dest, bit ^ 7);
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    count++;
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (row_align)
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 bit = ALIGN(bit, row_align);
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return count;
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Returns the low Y value of the vertical range given, flipped according to
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * whether the framebuffer is or not.
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE int
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgy_flip(struct gl_framebuffer *fb, int y, int height)
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (_mesa_is_user_fbo(fb))
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return y;
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return fb->Height - y - height;
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Render a bitmap.
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic bool
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdo_blit_bitmap( struct gl_context *ctx,
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GLint dstx, GLint dsty,
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		GLsizei width, GLsizei height,
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const struct gl_pixelstore_attrib *unpack,
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const GLubyte *bitmap )
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct intel_context *intel = intel_context(ctx);
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct intel_region *dst;
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_framebuffer *fb = ctx->DrawBuffer;
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat tmpColor[4];
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLubyte ubcolor[4];
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint color;
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLsizei bitmap_width = width;
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLsizei bitmap_height = height;
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint px, py;
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint stipple[32];
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint orig_dstx = dstx;
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint orig_dsty = dsty;
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Update draw buffer bounds */
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _mesa_update_state(ctx);
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ctx->Depth.Test) {
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* The blit path produces incorrect results when depth testing is on.
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * It seems the blit Z coord is always 1.0 (the far plane) so fragments
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * will likely be obscured by other, closer geometry.
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return false;
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   intel_prepare_render(intel);
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dst = intel_drawbuf_region(intel);
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!dst)
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       return false;
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (_mesa_is_bufferobj(unpack->BufferObj)) {
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      bitmap = map_pbo(ctx, width, height, unpack, bitmap);
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (bitmap == NULL)
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 return true;	/* even though this is an error, we're done */
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   COPY_4V(tmpColor, ctx->Current.RasterColor);
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (_mesa_need_secondary_color(ctx)) {
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       ADD_3V(tmpColor, tmpColor, ctx->Current.RasterSecondaryColor);
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[0], tmpColor[0]);
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[1], tmpColor[1]);
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[2], tmpColor[2]);
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[3], tmpColor[3]);
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dst->cpp == 2)
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      color = PACK_COLOR_565(ubcolor[0], ubcolor[1], ubcolor[2]);
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      color = PACK_COLOR_8888(ubcolor[3], ubcolor[0], ubcolor[1], ubcolor[2]);
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!intel_check_blit_fragment_ops(ctx, tmpColor[3] == 1.0F))
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return false;
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Clip to buffer bounds and scissor. */
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!_mesa_clip_to_region(fb->_Xmin, fb->_Ymin,
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     fb->_Xmax, fb->_Ymax,
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     &dstx, &dsty, &width, &height))
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto out;
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dsty = y_flip(fb, dsty, height);
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define DY 32
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define DX 32
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Chop it all into chunks that can be digested by hardware: */
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (py = 0; py < height; py += DY) {
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (px = 0; px < width; px += DX) {
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 int h = MIN2(DY, height - py);
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 int w = MIN2(DX, width - px);
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 GLuint sz = ALIGN(ALIGN(w,8) * h, 64)/8;
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 GLenum logic_op = ctx->Color.ColorLogicOpEnabled ?
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    ctx->Color.LogicOp : GL_COPY;
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(sz <= sizeof(stipple));
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 memset(stipple, 0, sz);
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* May need to adjust this when padding has been introduced in
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * sz above:
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  *
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * Have to translate destination coordinates back into source
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * coordinates.
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  */
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (get_bitmap_rect(bitmap_width, bitmap_height, unpack,
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     bitmap,
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     -orig_dstx + (dstx + px),
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     -orig_dsty + y_flip(fb, dsty + py, h),
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     w, h,
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     (GLubyte *)stipple,
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     8,
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     _mesa_is_winsys_fbo(fb)) == 0)
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    continue;
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (!intelEmitImmediateColorExpandBlit(intel,
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						dst->cpp,
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						(GLubyte *)stipple,
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						sz,
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						color,
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						dst->pitch,
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						dst->bo,
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						0,
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						dst->tiling,
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						dstx + px,
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						dsty + py,
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						w, h,
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						logic_op)) {
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    return false;
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgout:
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (unlikely(INTEL_DEBUG & DEBUG_SYNC))
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      intel_batchbuffer_flush(intel);
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (_mesa_is_bufferobj(unpack->BufferObj)) {
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* done with PBO so unmap it now */
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ctx->Driver.UnmapBuffer(ctx, unpack->BufferObj);
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   intel_check_front_buffer_rendering(intel);
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return true;
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* There are a large number of possible ways to implement bitmap on
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * this hardware, most of them have some sort of drawback.  Here are a
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * few that spring to mind:
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Blit:
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    - XY_MONO_SRC_BLT_CMD
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *         - use XY_SETUP_CLIP_BLT for cliprect clipping.
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    - XY_TEXT_BLT
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    - XY_TEXT_IMMEDIATE_BLT
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *         - blit per cliprect, subject to maximum immediate data size.
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    - XY_COLOR_BLT
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *         - per pixel or run of pixels
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    - XY_PIXEL_BLT
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *         - good for sparse bitmaps
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3D engine:
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    - Point per pixel
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    - Translate bitmap to an alpha texture and render as a quad
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    - Chop bitmap up into 32x32 squares and render w/polygon stipple.
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgintelBitmap(struct gl_context * ctx,
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    GLint x, GLint y,
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    GLsizei width, GLsizei height,
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    const struct gl_pixelstore_attrib *unpack,
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    const GLubyte * pixels)
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!_mesa_check_conditional_render(ctx))
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (do_blit_bitmap(ctx, x, y, width, height,
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          unpack, pixels))
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _mesa_meta_Bitmap(ctx, x, y, width, height, unpack, pixels);
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
341