1733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt/**************************************************************************
2733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt *
3877128505431adaf817dc8069172ebe4a1cdf5d8José Fonseca * Copyright 2006 VMware, Inc.
4733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt * All Rights Reserved.
5733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt *
6733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt * Permission is hereby granted, free of charge, to any person obtaining a
7733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt * copy of this software and associated documentation files (the
8733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt * "Software"), to deal in the Software without restriction, including
9733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt * without limitation the rights to use, copy, modify, merge, publish,
10733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt * distribute, sub license, and/or sell copies of the Software, and to
11733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt * permit persons to whom the Software is furnished to do so, subject to
12733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt * the following conditions:
13733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt *
14733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt * The above copyright notice and this permission notice (including the
15733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt * next paragraph) shall be included in all copies or substantial portionsalloc
16733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt * of the Software.
17733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt *
18733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21877128505431adaf817dc8069172ebe4a1cdf5d8José Fonseca * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt *
26733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt **************************************************************************/
27733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
28733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt#include "main/glheader.h"
29733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt#include "main/enums.h"
30733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt#include "main/image.h"
31733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt#include "main/colormac.h"
32733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt#include "main/condrender.h"
33733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt#include "main/mtypes.h"
34733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt#include "main/macros.h"
35733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt#include "main/pbo.h"
36733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt#include "main/bufferobj.h"
37733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt#include "main/state.h"
38733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt#include "main/texobj.h"
39733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt#include "main/context.h"
40733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt#include "main/fbobject.h"
41733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt#include "swrast/swrast.h"
42733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt#include "drivers/common/meta.h"
43733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
44733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt#include "intel_screen.h"
45733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt#include "intel_context.h"
46733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt#include "intel_batchbuffer.h"
47733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt#include "intel_blit.h"
48733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt#include "intel_fbo.h"
49733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt#include "intel_regions.h"
50733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt#include "intel_buffers.h"
51733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt#include "intel_pixel.h"
52733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt#include "intel_reg.h"
53733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
54733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
55733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt#define FILE_DEBUG_FLAG DEBUG_PIXEL
56733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
57733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
58733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt/* Unlike the other intel_pixel_* functions, the expectation here is
59733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt * that the incoming data is not in a PBO.  With the XY_TEXT blit
60733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt * method, there's no benefit haveing it in a PBO, but we could
61733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt * implement a path based on XY_MONO_SRC_COPY_BLIT which might benefit
62733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt * PBO bitmaps.  I think they are probably pretty rare though - I
63733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt * wonder if Xgl uses them?
64733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt */
65733d32f3765be84a7e908df7e99a278cadcee853Eric Anholtstatic const GLubyte *map_pbo( struct gl_context *ctx,
66733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt			       GLsizei width, GLsizei height,
67733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt			       const struct gl_pixelstore_attrib *unpack,
68733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt			       const GLubyte *bitmap )
69733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt{
70733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   GLubyte *buf;
71733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
72733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   if (!_mesa_validate_pbo_access(2, unpack, width, height, 1,
73733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt				  GL_COLOR_INDEX, GL_BITMAP,
74733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt				  INT_MAX, (const GLvoid *) bitmap)) {
75733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt      _mesa_error(ctx, GL_INVALID_OPERATION,"glBitmap(invalid PBO access)");
76733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt      return NULL;
77733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   }
78733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
79733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   buf = (GLubyte *) ctx->Driver.MapBufferRange(ctx, 0, unpack->BufferObj->Size,
80733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt						GL_MAP_READ_BIT,
81dca350201e00c7cf1cfb009158f4abf27fbc96d2Marek Olšák						unpack->BufferObj,
82dca350201e00c7cf1cfb009158f4abf27fbc96d2Marek Olšák                                                MAP_INTERNAL);
83733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   if (!buf) {
84733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt      _mesa_error(ctx, GL_INVALID_OPERATION, "glBitmap(PBO is mapped)");
85733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt      return NULL;
86733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   }
87733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
88733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   return ADD_POINTERS(buf, bitmap);
89733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt}
90733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
91733d32f3765be84a7e908df7e99a278cadcee853Eric Anholtstatic bool test_bit( const GLubyte *src, GLuint bit )
92733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt{
93733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   return (src[bit/8] & (1<<(bit % 8))) ? 1 : 0;
94733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt}
95733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
96733d32f3765be84a7e908df7e99a278cadcee853Eric Anholtstatic void set_bit( GLubyte *dest, GLuint bit )
97733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt{
98733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   dest[bit/8] |= 1 << (bit % 8);
99733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt}
100733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
101733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt/* Extract a rectangle's worth of data from the bitmap.  Called
102733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt * per chunk of HW-sized bitmap.
103733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt */
104733d32f3765be84a7e908df7e99a278cadcee853Eric Anholtstatic GLuint get_bitmap_rect(GLsizei width, GLsizei height,
105733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt			      const struct gl_pixelstore_attrib *unpack,
106733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt			      const GLubyte *bitmap,
107733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt			      GLuint x, GLuint y,
108733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt			      GLuint w, GLuint h,
109733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt			      GLubyte *dest,
110733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt			      GLuint row_align,
111733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt			      bool invert)
112733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt{
113733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   GLuint src_offset = (x + unpack->SkipPixels) & 0x7;
114733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   GLuint mask = unpack->LsbFirst ? 0 : 7;
115733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   GLuint bit = 0;
116733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   GLint row, col;
117733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   GLint first, last;
118733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   GLint incr;
119733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   GLuint count = 0;
120733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
121733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   DBG("%s %d,%d %dx%d bitmap %dx%d skip %d src_offset %d mask %d\n",
122139e6c7c4a9c59be5f4b3f431ac393cc097326acMarius Predut       __func__, x,y,w,h,width,height,unpack->SkipPixels, src_offset, mask);
123733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
124733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   if (invert) {
125733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt      first = h-1;
126733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt      last = 0;
127733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt      incr = -1;
128733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   }
129733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   else {
130733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt      first = 0;
131733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt      last = h-1;
132733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt      incr = 1;
133733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   }
134733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
135733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   /* Require that dest be pre-zero'd.
136733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt    */
137733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   for (row = first; row != (last+incr); row += incr) {
138733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt      const GLubyte *rowsrc = _mesa_image_address2d(unpack, bitmap,
139733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt						    width, height,
140733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt						    GL_COLOR_INDEX, GL_BITMAP,
141733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt						    y + row, x);
142733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
143733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt      for (col = 0; col < w; col++, bit++) {
144733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt	 if (test_bit(rowsrc, (col + src_offset) ^ mask)) {
145733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt	    set_bit(dest, bit ^ 7);
146733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt	    count++;
147733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt	 }
148733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt      }
149733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
150733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt      if (row_align)
151733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt	 bit = ALIGN(bit, row_align);
152733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   }
153733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
154733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   return count;
155733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt}
156733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
157733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt/**
158733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt * Returns the low Y value of the vertical range given, flipped according to
159733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt * whether the framebuffer is or not.
160733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt */
1618e9fe53ce9f8b01ae66b19dc273594fa413e9ad5Brian Paulstatic inline int
162733d32f3765be84a7e908df7e99a278cadcee853Eric Anholty_flip(struct gl_framebuffer *fb, int y, int height)
163733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt{
164733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   if (_mesa_is_user_fbo(fb))
165733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt      return y;
166733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   else
167733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt      return fb->Height - y - height;
168733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt}
169733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
170733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt/*
171733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt * Render a bitmap.
172733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt */
173733d32f3765be84a7e908df7e99a278cadcee853Eric Anholtstatic bool
174733d32f3765be84a7e908df7e99a278cadcee853Eric Anholtdo_blit_bitmap( struct gl_context *ctx,
175733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt		GLint dstx, GLint dsty,
176733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt		GLsizei width, GLsizei height,
177733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt		const struct gl_pixelstore_attrib *unpack,
178733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt		const GLubyte *bitmap )
179733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt{
180733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   struct intel_context *intel = intel_context(ctx);
181733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   struct gl_framebuffer *fb = ctx->DrawBuffer;
182733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   struct intel_renderbuffer *irb;
183733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   GLfloat tmpColor[4];
184733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   GLubyte ubcolor[4];
185733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   GLuint color;
186733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   GLsizei bitmap_width = width;
187733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   GLsizei bitmap_height = height;
188733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   GLint px, py;
189733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   GLuint stipple[32];
190733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   GLint orig_dstx = dstx;
191733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   GLint orig_dsty = dsty;
192733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
193733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   /* Update draw buffer bounds */
194733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   _mesa_update_state(ctx);
195733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
196733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   if (ctx->Depth.Test) {
197733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt      /* The blit path produces incorrect results when depth testing is on.
198733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt       * It seems the blit Z coord is always 1.0 (the far plane) so fragments
199733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt       * will likely be obscured by other, closer geometry.
200733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt       */
201733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt      return false;
202733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   }
203733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
204733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   intel_prepare_render(intel);
205733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
206733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   if (fb->_NumColorDrawBuffers != 1) {
207733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt      perf_debug("accelerated glBitmap() only supports rendering to a "
208733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt                 "single color buffer\n");
209733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt      return false;
210733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   }
211733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
212733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   irb = intel_renderbuffer(fb->_ColorDrawBuffers[0]);
213733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
214733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   if (_mesa_is_bufferobj(unpack->BufferObj)) {
215733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt      bitmap = map_pbo(ctx, width, height, unpack, bitmap);
216733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt      if (bitmap == NULL)
217733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt	 return true;	/* even though this is an error, we're done */
218733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   }
219733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
220733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   COPY_4V(tmpColor, ctx->Current.RasterColor);
221733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
222733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   if (_mesa_need_secondary_color(ctx)) {
223733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt       ADD_3V(tmpColor, tmpColor, ctx->Current.RasterSecondaryColor);
224733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   }
225733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
226733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[0], tmpColor[0]);
227733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[1], tmpColor[1]);
228733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[2], tmpColor[2]);
229733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[3], tmpColor[3]);
230733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
231733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   switch (irb->mt->format) {
232ef145ba4ded6aafb28e3bda02fb348e6b8bff12aMark Mueller   case MESA_FORMAT_B8G8R8A8_UNORM:
233ef145ba4ded6aafb28e3bda02fb348e6b8bff12aMark Mueller   case MESA_FORMAT_B8G8R8X8_UNORM:
234733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt      color = PACK_COLOR_8888(ubcolor[3], ubcolor[0], ubcolor[1], ubcolor[2]);
235733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt      break;
236eeed49f5f290793870c60b5b635b977a732a1eb4Mark Mueller   case MESA_FORMAT_B5G6R5_UNORM:
237733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt      color = PACK_COLOR_565(ubcolor[0], ubcolor[1], ubcolor[2]);
238733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt      break;
239733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   default:
240733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt      perf_debug("Unsupported format %s in accelerated glBitmap()\n",
241733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt                 _mesa_get_format_name(irb->mt->format));
242733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt      return false;
243733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   }
244733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
245733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   if (!intel_check_blit_fragment_ops(ctx, tmpColor[3] == 1.0F))
246733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt      return false;
247733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
248733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   /* Clip to buffer bounds and scissor. */
249733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   if (!_mesa_clip_to_region(fb->_Xmin, fb->_Ymin,
250733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt			     fb->_Xmax, fb->_Ymax,
251733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt			     &dstx, &dsty, &width, &height))
252733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt      goto out;
253733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
254733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   dsty = y_flip(fb, dsty, height);
255733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
256733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt#define DY 32
257733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt#define DX 32
258733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
259733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   /* Chop it all into chunks that can be digested by hardware: */
260733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   for (py = 0; py < height; py += DY) {
261733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt      for (px = 0; px < width; px += DX) {
262733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt	 int h = MIN2(DY, height - py);
263733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt	 int w = MIN2(DX, width - px);
264733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt	 GLuint sz = ALIGN(ALIGN(w,8) * h, 64)/8;
265733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt	 GLenum logic_op = ctx->Color.ColorLogicOpEnabled ?
266733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt	    ctx->Color.LogicOp : GL_COPY;
267733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
268733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt	 assert(sz <= sizeof(stipple));
269733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt	 memset(stipple, 0, sz);
270733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
271733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt	 /* May need to adjust this when padding has been introduced in
272733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt	  * sz above:
273733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt	  *
274733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt	  * Have to translate destination coordinates back into source
275733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt	  * coordinates.
276733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt	  */
277733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt         int count = get_bitmap_rect(bitmap_width, bitmap_height, unpack,
278733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt                                     bitmap,
279733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt                                     -orig_dstx + (dstx + px),
280733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt                                     -orig_dsty + y_flip(fb, dsty + py, h),
281733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt                                     w, h,
282733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt                                     (GLubyte *)stipple,
283733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt                                     8,
284733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt                                     _mesa_is_winsys_fbo(fb));
285733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt         if (count == 0)
286733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt	    continue;
287733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
288733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt	 if (!intelEmitImmediateColorExpandBlit(intel,
289733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt						irb->mt->cpp,
290733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt						(GLubyte *)stipple,
291733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt						sz,
292733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt						color,
293733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt						irb->mt->region->pitch,
294733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt						irb->mt->region->bo,
295733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt						0,
296733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt						irb->mt->region->tiling,
297733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt						dstx + px,
298733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt						dsty + py,
299733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt						w, h,
300733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt						logic_op)) {
301733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt	    return false;
302733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt	 }
303733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
304733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt         if (ctx->Query.CurrentOcclusionObject)
305733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt            ctx->Query.CurrentOcclusionObject->Result += count;
306733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt      }
307733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   }
308733d32f3765be84a7e908df7e99a278cadcee853Eric Anholtout:
309733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
310733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   if (unlikely(INTEL_DEBUG & DEBUG_SYNC))
311733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt      intel_batchbuffer_flush(intel);
312733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
313733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   if (_mesa_is_bufferobj(unpack->BufferObj)) {
314733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt      /* done with PBO so unmap it now */
315dca350201e00c7cf1cfb009158f4abf27fbc96d2Marek Olšák      ctx->Driver.UnmapBuffer(ctx, unpack->BufferObj, MAP_INTERNAL);
316733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   }
317733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
318733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   intel_check_front_buffer_rendering(intel);
319733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
320733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   return true;
321733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt}
322733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
323733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
324733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt/* There are a large number of possible ways to implement bitmap on
325733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt * this hardware, most of them have some sort of drawback.  Here are a
326733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt * few that spring to mind:
327733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt *
328733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt * Blit:
329733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt *    - XY_MONO_SRC_BLT_CMD
330733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt *         - use XY_SETUP_CLIP_BLT for cliprect clipping.
331733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt *    - XY_TEXT_BLT
332733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt *    - XY_TEXT_IMMEDIATE_BLT
333733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt *         - blit per cliprect, subject to maximum immediate data size.
334733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt *    - XY_COLOR_BLT
335733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt *         - per pixel or run of pixels
336733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt *    - XY_PIXEL_BLT
337733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt *         - good for sparse bitmaps
338733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt *
339733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt * 3D engine:
340733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt *    - Point per pixel
341733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt *    - Translate bitmap to an alpha texture and render as a quad
342733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt *    - Chop bitmap up into 32x32 squares and render w/polygon stipple.
343733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt */
344733d32f3765be84a7e908df7e99a278cadcee853Eric Anholtvoid
345733d32f3765be84a7e908df7e99a278cadcee853Eric AnholtintelBitmap(struct gl_context * ctx,
346733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt	    GLint x, GLint y,
347733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt	    GLsizei width, GLsizei height,
348733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt	    const struct gl_pixelstore_attrib *unpack,
349733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt	    const GLubyte * pixels)
350733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt{
351733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   if (!_mesa_check_conditional_render(ctx))
352733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt      return;
353733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
354733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   if (do_blit_bitmap(ctx, x, y, width, height,
355733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt                          unpack, pixels))
356733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt      return;
357733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt
358733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt   _mesa_meta_Bitmap(ctx, x, y, width, height, unpack, pixels);
359733d32f3765be84a7e908df7e99a278cadcee853Eric Anholt}
360