1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Mesa 3-D graphics library
3*61046927SAndroid Build Coastguard Worker *
4*61046927SAndroid Build Coastguard Worker * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
5*61046927SAndroid Build Coastguard Worker *
6*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
7*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
8*61046927SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
9*61046927SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10*61046927SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
11*61046927SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
12*61046927SAndroid Build Coastguard Worker *
13*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice shall be included
14*61046927SAndroid Build Coastguard Worker * in all copies or substantial portions of the Software.
15*61046927SAndroid Build Coastguard Worker *
16*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17*61046927SAndroid Build Coastguard Worker * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19*61046927SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20*61046927SAndroid Build Coastguard Worker * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21*61046927SAndroid Build Coastguard Worker * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22*61046927SAndroid Build Coastguard Worker * OTHER DEALINGS IN THE SOFTWARE.
23*61046927SAndroid Build Coastguard Worker */
24*61046927SAndroid Build Coastguard Worker
25*61046927SAndroid Build Coastguard Worker #include "util/glheader.h"
26*61046927SAndroid Build Coastguard Worker #include "draw_validate.h"
27*61046927SAndroid Build Coastguard Worker #include "bufferobj.h"
28*61046927SAndroid Build Coastguard Worker #include "context.h"
29*61046927SAndroid Build Coastguard Worker #include "enums.h"
30*61046927SAndroid Build Coastguard Worker #include "feedback.h"
31*61046927SAndroid Build Coastguard Worker #include "framebuffer.h"
32*61046927SAndroid Build Coastguard Worker #include "image.h"
33*61046927SAndroid Build Coastguard Worker #include "pbo.h"
34*61046927SAndroid Build Coastguard Worker #include "pixel.h"
35*61046927SAndroid Build Coastguard Worker #include "state.h"
36*61046927SAndroid Build Coastguard Worker #include "glformats.h"
37*61046927SAndroid Build Coastguard Worker #include "fbobject.h"
38*61046927SAndroid Build Coastguard Worker #include "util/u_math.h"
39*61046927SAndroid Build Coastguard Worker #include "util/rounding.h"
40*61046927SAndroid Build Coastguard Worker #include "api_exec_decl.h"
41*61046927SAndroid Build Coastguard Worker
42*61046927SAndroid Build Coastguard Worker #include "state_tracker/st_cb_bitmap.h"
43*61046927SAndroid Build Coastguard Worker #include "state_tracker/st_cb_drawpixels.h"
44*61046927SAndroid Build Coastguard Worker
45*61046927SAndroid Build Coastguard Worker /*
46*61046927SAndroid Build Coastguard Worker * Execute glDrawPixels
47*61046927SAndroid Build Coastguard Worker */
48*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_DrawPixels(GLsizei width,GLsizei height,GLenum format,GLenum type,const GLvoid * pixels)49*61046927SAndroid Build Coastguard Worker _mesa_DrawPixels( GLsizei width, GLsizei height,
50*61046927SAndroid Build Coastguard Worker GLenum format, GLenum type, const GLvoid *pixels )
51*61046927SAndroid Build Coastguard Worker {
52*61046927SAndroid Build Coastguard Worker GLenum err;
53*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
54*61046927SAndroid Build Coastguard Worker
55*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, 0, 0);
56*61046927SAndroid Build Coastguard Worker
57*61046927SAndroid Build Coastguard Worker if (MESA_VERBOSE & VERBOSE_API)
58*61046927SAndroid Build Coastguard Worker _mesa_debug(ctx, "glDrawPixels(%d, %d, %s, %s, %p) // to %s at %ld, %ld\n",
59*61046927SAndroid Build Coastguard Worker width, height,
60*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(format),
61*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(type),
62*61046927SAndroid Build Coastguard Worker pixels,
63*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(ctx->DrawBuffer->ColorDrawBuffer[0]),
64*61046927SAndroid Build Coastguard Worker lroundf(ctx->Current.RasterPos[0]),
65*61046927SAndroid Build Coastguard Worker lroundf(ctx->Current.RasterPos[1]));
66*61046927SAndroid Build Coastguard Worker
67*61046927SAndroid Build Coastguard Worker
68*61046927SAndroid Build Coastguard Worker if (width < 0 || height < 0) {
69*61046927SAndroid Build Coastguard Worker _mesa_error( ctx, GL_INVALID_VALUE, "glDrawPixels(width or height < 0)" );
70*61046927SAndroid Build Coastguard Worker return;
71*61046927SAndroid Build Coastguard Worker }
72*61046927SAndroid Build Coastguard Worker
73*61046927SAndroid Build Coastguard Worker /* We're not using the current vertex program, and the driver may install
74*61046927SAndroid Build Coastguard Worker * its own. Note: this may dirty some state.
75*61046927SAndroid Build Coastguard Worker */
76*61046927SAndroid Build Coastguard Worker _mesa_set_vp_override(ctx, GL_TRUE);
77*61046927SAndroid Build Coastguard Worker
78*61046927SAndroid Build Coastguard Worker _mesa_update_pixel(ctx);
79*61046927SAndroid Build Coastguard Worker
80*61046927SAndroid Build Coastguard Worker if (ctx->NewState)
81*61046927SAndroid Build Coastguard Worker _mesa_update_state(ctx);
82*61046927SAndroid Build Coastguard Worker
83*61046927SAndroid Build Coastguard Worker if (!ctx->DrawPixValid) {
84*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels");
85*61046927SAndroid Build Coastguard Worker goto end;
86*61046927SAndroid Build Coastguard Worker }
87*61046927SAndroid Build Coastguard Worker
88*61046927SAndroid Build Coastguard Worker /* GL 3.0 introduced a new restriction on glDrawPixels() over what was in
89*61046927SAndroid Build Coastguard Worker * GL_EXT_texture_integer. From section 3.7.4 ("Rasterization of Pixel
90*61046927SAndroid Build Coastguard Worker * Rectangles) on page 151 of the GL 3.0 specification:
91*61046927SAndroid Build Coastguard Worker *
92*61046927SAndroid Build Coastguard Worker * "If format contains integer components, as shown in table 3.6, an
93*61046927SAndroid Build Coastguard Worker * INVALID OPERATION error is generated."
94*61046927SAndroid Build Coastguard Worker *
95*61046927SAndroid Build Coastguard Worker * Since DrawPixels rendering would be merely undefined if not an error (due
96*61046927SAndroid Build Coastguard Worker * to a lack of defined mapping from integer data to gl_Color fragment shader
97*61046927SAndroid Build Coastguard Worker * input), NVIDIA's implementation also just returns this error despite
98*61046927SAndroid Build Coastguard Worker * exposing GL_EXT_texture_integer, just return an error regardless.
99*61046927SAndroid Build Coastguard Worker */
100*61046927SAndroid Build Coastguard Worker if (_mesa_is_enum_format_integer(format)) {
101*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels(integer format)");
102*61046927SAndroid Build Coastguard Worker goto end;
103*61046927SAndroid Build Coastguard Worker }
104*61046927SAndroid Build Coastguard Worker
105*61046927SAndroid Build Coastguard Worker err = _mesa_error_check_format_and_type(ctx, format, type);
106*61046927SAndroid Build Coastguard Worker if (err != GL_NO_ERROR) {
107*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, err, "glDrawPixels(invalid format %s and/or type %s)",
108*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(format),
109*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(type));
110*61046927SAndroid Build Coastguard Worker goto end;
111*61046927SAndroid Build Coastguard Worker }
112*61046927SAndroid Build Coastguard Worker
113*61046927SAndroid Build Coastguard Worker /* do special format-related checks */
114*61046927SAndroid Build Coastguard Worker switch (format) {
115*61046927SAndroid Build Coastguard Worker case GL_STENCIL_INDEX:
116*61046927SAndroid Build Coastguard Worker case GL_DEPTH_COMPONENT:
117*61046927SAndroid Build Coastguard Worker case GL_DEPTH_STENCIL_EXT:
118*61046927SAndroid Build Coastguard Worker /* these buffers must exist */
119*61046927SAndroid Build Coastguard Worker if (!_mesa_dest_buffer_exists(ctx, format)) {
120*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
121*61046927SAndroid Build Coastguard Worker "glDrawPixels(missing dest buffer)");
122*61046927SAndroid Build Coastguard Worker goto end;
123*61046927SAndroid Build Coastguard Worker }
124*61046927SAndroid Build Coastguard Worker break;
125*61046927SAndroid Build Coastguard Worker case GL_COLOR_INDEX:
126*61046927SAndroid Build Coastguard Worker if (ctx->PixelMaps.ItoR.Size == 0 ||
127*61046927SAndroid Build Coastguard Worker ctx->PixelMaps.ItoG.Size == 0 ||
128*61046927SAndroid Build Coastguard Worker ctx->PixelMaps.ItoB.Size == 0) {
129*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
130*61046927SAndroid Build Coastguard Worker "glDrawPixels(drawing color index pixels into RGB buffer)");
131*61046927SAndroid Build Coastguard Worker goto end;
132*61046927SAndroid Build Coastguard Worker }
133*61046927SAndroid Build Coastguard Worker break;
134*61046927SAndroid Build Coastguard Worker default:
135*61046927SAndroid Build Coastguard Worker /* for color formats it's not an error if the destination color
136*61046927SAndroid Build Coastguard Worker * buffer doesn't exist.
137*61046927SAndroid Build Coastguard Worker */
138*61046927SAndroid Build Coastguard Worker break;
139*61046927SAndroid Build Coastguard Worker }
140*61046927SAndroid Build Coastguard Worker
141*61046927SAndroid Build Coastguard Worker if (ctx->RasterDiscard) {
142*61046927SAndroid Build Coastguard Worker goto end;
143*61046927SAndroid Build Coastguard Worker }
144*61046927SAndroid Build Coastguard Worker
145*61046927SAndroid Build Coastguard Worker if (!ctx->Current.RasterPosValid) {
146*61046927SAndroid Build Coastguard Worker goto end; /* no-op, not an error */
147*61046927SAndroid Build Coastguard Worker }
148*61046927SAndroid Build Coastguard Worker
149*61046927SAndroid Build Coastguard Worker if (ctx->RenderMode == GL_RENDER) {
150*61046927SAndroid Build Coastguard Worker if (width > 0 && height > 0) {
151*61046927SAndroid Build Coastguard Worker /* Round, to satisfy conformance tests (matches SGI's OpenGL) */
152*61046927SAndroid Build Coastguard Worker GLint x = lroundf(ctx->Current.RasterPos[0]);
153*61046927SAndroid Build Coastguard Worker GLint y = lroundf(ctx->Current.RasterPos[1]);
154*61046927SAndroid Build Coastguard Worker
155*61046927SAndroid Build Coastguard Worker if (ctx->Unpack.BufferObj) {
156*61046927SAndroid Build Coastguard Worker /* unpack from PBO */
157*61046927SAndroid Build Coastguard Worker if (!_mesa_validate_pbo_access(2, &ctx->Unpack, width, height,
158*61046927SAndroid Build Coastguard Worker 1, format, type, INT_MAX, pixels)) {
159*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
160*61046927SAndroid Build Coastguard Worker "glDrawPixels(invalid PBO access)");
161*61046927SAndroid Build Coastguard Worker goto end;
162*61046927SAndroid Build Coastguard Worker }
163*61046927SAndroid Build Coastguard Worker if (_mesa_check_disallowed_mapping(ctx->Unpack.BufferObj)) {
164*61046927SAndroid Build Coastguard Worker /* buffer is mapped - that's an error */
165*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
166*61046927SAndroid Build Coastguard Worker "glDrawPixels(PBO is mapped)");
167*61046927SAndroid Build Coastguard Worker goto end;
168*61046927SAndroid Build Coastguard Worker }
169*61046927SAndroid Build Coastguard Worker }
170*61046927SAndroid Build Coastguard Worker
171*61046927SAndroid Build Coastguard Worker st_DrawPixels(ctx, x, y, width, height, format, type,
172*61046927SAndroid Build Coastguard Worker &ctx->Unpack, pixels);
173*61046927SAndroid Build Coastguard Worker }
174*61046927SAndroid Build Coastguard Worker }
175*61046927SAndroid Build Coastguard Worker else if (ctx->RenderMode == GL_FEEDBACK) {
176*61046927SAndroid Build Coastguard Worker /* Feedback the current raster pos info */
177*61046927SAndroid Build Coastguard Worker FLUSH_CURRENT( ctx, 0 );
178*61046927SAndroid Build Coastguard Worker _mesa_feedback_token( ctx, (GLfloat) (GLint) GL_DRAW_PIXEL_TOKEN );
179*61046927SAndroid Build Coastguard Worker _mesa_feedback_vertex( ctx,
180*61046927SAndroid Build Coastguard Worker ctx->Current.RasterPos,
181*61046927SAndroid Build Coastguard Worker ctx->Current.RasterColor,
182*61046927SAndroid Build Coastguard Worker ctx->Current.RasterTexCoords[0] );
183*61046927SAndroid Build Coastguard Worker }
184*61046927SAndroid Build Coastguard Worker else {
185*61046927SAndroid Build Coastguard Worker assert(ctx->RenderMode == GL_SELECT);
186*61046927SAndroid Build Coastguard Worker /* Do nothing. See OpenGL Spec, Appendix B, Corollary 6. */
187*61046927SAndroid Build Coastguard Worker }
188*61046927SAndroid Build Coastguard Worker
189*61046927SAndroid Build Coastguard Worker end:
190*61046927SAndroid Build Coastguard Worker _mesa_set_vp_override(ctx, GL_FALSE);
191*61046927SAndroid Build Coastguard Worker
192*61046927SAndroid Build Coastguard Worker if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
193*61046927SAndroid Build Coastguard Worker _mesa_flush(ctx);
194*61046927SAndroid Build Coastguard Worker }
195*61046927SAndroid Build Coastguard Worker }
196*61046927SAndroid Build Coastguard Worker
197*61046927SAndroid Build Coastguard Worker
198*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CopyPixels(GLint srcx,GLint srcy,GLsizei width,GLsizei height,GLenum type)199*61046927SAndroid Build Coastguard Worker _mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height,
200*61046927SAndroid Build Coastguard Worker GLenum type )
201*61046927SAndroid Build Coastguard Worker {
202*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
203*61046927SAndroid Build Coastguard Worker
204*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, 0, 0);
205*61046927SAndroid Build Coastguard Worker
206*61046927SAndroid Build Coastguard Worker if (MESA_VERBOSE & VERBOSE_API)
207*61046927SAndroid Build Coastguard Worker _mesa_debug(ctx,
208*61046927SAndroid Build Coastguard Worker "glCopyPixels(%d, %d, %d, %d, %s) // from %s to %s at %ld, %ld\n",
209*61046927SAndroid Build Coastguard Worker srcx, srcy, width, height,
210*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(type),
211*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(ctx->ReadBuffer->ColorReadBuffer),
212*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(ctx->DrawBuffer->ColorDrawBuffer[0]),
213*61046927SAndroid Build Coastguard Worker lroundf(ctx->Current.RasterPos[0]),
214*61046927SAndroid Build Coastguard Worker lroundf(ctx->Current.RasterPos[1]));
215*61046927SAndroid Build Coastguard Worker
216*61046927SAndroid Build Coastguard Worker if (width < 0 || height < 0) {
217*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "glCopyPixels(width or height < 0)");
218*61046927SAndroid Build Coastguard Worker return;
219*61046927SAndroid Build Coastguard Worker }
220*61046927SAndroid Build Coastguard Worker
221*61046927SAndroid Build Coastguard Worker /* Note: more detailed 'type' checking is done by the
222*61046927SAndroid Build Coastguard Worker * _mesa_source/dest_buffer_exists() calls below. That's where we
223*61046927SAndroid Build Coastguard Worker * check if the stencil buffer exists, etc.
224*61046927SAndroid Build Coastguard Worker */
225*61046927SAndroid Build Coastguard Worker if (type != GL_COLOR &&
226*61046927SAndroid Build Coastguard Worker type != GL_DEPTH &&
227*61046927SAndroid Build Coastguard Worker type != GL_STENCIL &&
228*61046927SAndroid Build Coastguard Worker type != GL_DEPTH_STENCIL &&
229*61046927SAndroid Build Coastguard Worker type != GL_DEPTH_STENCIL_TO_RGBA_NV &&
230*61046927SAndroid Build Coastguard Worker type != GL_DEPTH_STENCIL_TO_BGRA_NV) {
231*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "glCopyPixels(type=%s)",
232*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(type));
233*61046927SAndroid Build Coastguard Worker return;
234*61046927SAndroid Build Coastguard Worker }
235*61046927SAndroid Build Coastguard Worker
236*61046927SAndroid Build Coastguard Worker /* Return GL_INVALID_ENUM if the relevant extension is not enabled */
237*61046927SAndroid Build Coastguard Worker if ((type == GL_DEPTH_STENCIL_TO_RGBA_NV || type == GL_DEPTH_STENCIL_TO_BGRA_NV) &&
238*61046927SAndroid Build Coastguard Worker !ctx->Extensions.NV_copy_depth_to_color) {
239*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "glCopyPixels(type=%s)",
240*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(type));
241*61046927SAndroid Build Coastguard Worker return;
242*61046927SAndroid Build Coastguard Worker }
243*61046927SAndroid Build Coastguard Worker
244*61046927SAndroid Build Coastguard Worker /* We're not using the current vertex program, and the driver may install
245*61046927SAndroid Build Coastguard Worker * it's own. Note: this may dirty some state.
246*61046927SAndroid Build Coastguard Worker */
247*61046927SAndroid Build Coastguard Worker _mesa_set_vp_override(ctx, GL_TRUE);
248*61046927SAndroid Build Coastguard Worker
249*61046927SAndroid Build Coastguard Worker _mesa_update_pixel(ctx);
250*61046927SAndroid Build Coastguard Worker
251*61046927SAndroid Build Coastguard Worker if (ctx->NewState)
252*61046927SAndroid Build Coastguard Worker _mesa_update_state(ctx);
253*61046927SAndroid Build Coastguard Worker
254*61046927SAndroid Build Coastguard Worker if (!ctx->DrawPixValid) {
255*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyPixels");
256*61046927SAndroid Build Coastguard Worker goto end;
257*61046927SAndroid Build Coastguard Worker }
258*61046927SAndroid Build Coastguard Worker
259*61046927SAndroid Build Coastguard Worker /* Check read buffer's status (draw buffer was already checked) */
260*61046927SAndroid Build Coastguard Worker if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
261*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
262*61046927SAndroid Build Coastguard Worker "glCopyPixels(incomplete framebuffer)" );
263*61046927SAndroid Build Coastguard Worker goto end;
264*61046927SAndroid Build Coastguard Worker }
265*61046927SAndroid Build Coastguard Worker
266*61046927SAndroid Build Coastguard Worker if (_mesa_is_user_fbo(ctx->ReadBuffer) &&
267*61046927SAndroid Build Coastguard Worker ctx->ReadBuffer->Visual.samples > 0) {
268*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
269*61046927SAndroid Build Coastguard Worker "glCopyPixels(multisample FBO)");
270*61046927SAndroid Build Coastguard Worker goto end;
271*61046927SAndroid Build Coastguard Worker }
272*61046927SAndroid Build Coastguard Worker
273*61046927SAndroid Build Coastguard Worker if (!_mesa_source_buffer_exists(ctx, type) ||
274*61046927SAndroid Build Coastguard Worker !_mesa_dest_buffer_exists(ctx, type)) {
275*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
276*61046927SAndroid Build Coastguard Worker "glCopyPixels(missing source or dest buffer)");
277*61046927SAndroid Build Coastguard Worker goto end;
278*61046927SAndroid Build Coastguard Worker }
279*61046927SAndroid Build Coastguard Worker
280*61046927SAndroid Build Coastguard Worker if (ctx->RasterDiscard) {
281*61046927SAndroid Build Coastguard Worker goto end;
282*61046927SAndroid Build Coastguard Worker }
283*61046927SAndroid Build Coastguard Worker
284*61046927SAndroid Build Coastguard Worker if (!ctx->Current.RasterPosValid || width == 0 || height == 0) {
285*61046927SAndroid Build Coastguard Worker goto end; /* no-op, not an error */
286*61046927SAndroid Build Coastguard Worker }
287*61046927SAndroid Build Coastguard Worker
288*61046927SAndroid Build Coastguard Worker if (ctx->RenderMode == GL_RENDER) {
289*61046927SAndroid Build Coastguard Worker /* Round to satisfy conformance tests (matches SGI's OpenGL) */
290*61046927SAndroid Build Coastguard Worker if (width > 0 && height > 0) {
291*61046927SAndroid Build Coastguard Worker GLint destx = lroundf(ctx->Current.RasterPos[0]);
292*61046927SAndroid Build Coastguard Worker GLint desty = lroundf(ctx->Current.RasterPos[1]);
293*61046927SAndroid Build Coastguard Worker st_CopyPixels( ctx, srcx, srcy, width, height, destx, desty,
294*61046927SAndroid Build Coastguard Worker type );
295*61046927SAndroid Build Coastguard Worker }
296*61046927SAndroid Build Coastguard Worker }
297*61046927SAndroid Build Coastguard Worker else if (ctx->RenderMode == GL_FEEDBACK) {
298*61046927SAndroid Build Coastguard Worker FLUSH_CURRENT( ctx, 0 );
299*61046927SAndroid Build Coastguard Worker _mesa_feedback_token( ctx, (GLfloat) (GLint) GL_COPY_PIXEL_TOKEN );
300*61046927SAndroid Build Coastguard Worker _mesa_feedback_vertex( ctx,
301*61046927SAndroid Build Coastguard Worker ctx->Current.RasterPos,
302*61046927SAndroid Build Coastguard Worker ctx->Current.RasterColor,
303*61046927SAndroid Build Coastguard Worker ctx->Current.RasterTexCoords[0] );
304*61046927SAndroid Build Coastguard Worker }
305*61046927SAndroid Build Coastguard Worker else {
306*61046927SAndroid Build Coastguard Worker assert(ctx->RenderMode == GL_SELECT);
307*61046927SAndroid Build Coastguard Worker /* Do nothing. See OpenGL Spec, Appendix B, Corollary 6. */
308*61046927SAndroid Build Coastguard Worker }
309*61046927SAndroid Build Coastguard Worker
310*61046927SAndroid Build Coastguard Worker end:
311*61046927SAndroid Build Coastguard Worker _mesa_set_vp_override(ctx, GL_FALSE);
312*61046927SAndroid Build Coastguard Worker
313*61046927SAndroid Build Coastguard Worker if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
314*61046927SAndroid Build Coastguard Worker _mesa_flush(ctx);
315*61046927SAndroid Build Coastguard Worker }
316*61046927SAndroid Build Coastguard Worker }
317*61046927SAndroid Build Coastguard Worker
318*61046927SAndroid Build Coastguard Worker
319*61046927SAndroid Build Coastguard Worker void
_mesa_bitmap(struct gl_context * ctx,GLsizei width,GLsizei height,GLfloat xorig,GLfloat yorig,GLfloat xmove,GLfloat ymove,const GLubyte * bitmap,struct pipe_resource * tex)320*61046927SAndroid Build Coastguard Worker _mesa_bitmap(struct gl_context *ctx, GLsizei width, GLsizei height,
321*61046927SAndroid Build Coastguard Worker GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove,
322*61046927SAndroid Build Coastguard Worker const GLubyte *bitmap, struct pipe_resource *tex)
323*61046927SAndroid Build Coastguard Worker {
324*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, 0, 0);
325*61046927SAndroid Build Coastguard Worker
326*61046927SAndroid Build Coastguard Worker if (width < 0 || height < 0) {
327*61046927SAndroid Build Coastguard Worker _mesa_error( ctx, GL_INVALID_VALUE, "glBitmap(width or height < 0)" );
328*61046927SAndroid Build Coastguard Worker return;
329*61046927SAndroid Build Coastguard Worker }
330*61046927SAndroid Build Coastguard Worker
331*61046927SAndroid Build Coastguard Worker if (!ctx->Current.RasterPosValid) {
332*61046927SAndroid Build Coastguard Worker return; /* do nothing */
333*61046927SAndroid Build Coastguard Worker }
334*61046927SAndroid Build Coastguard Worker
335*61046927SAndroid Build Coastguard Worker _mesa_update_pixel(ctx);
336*61046927SAndroid Build Coastguard Worker
337*61046927SAndroid Build Coastguard Worker if (ctx->NewState)
338*61046927SAndroid Build Coastguard Worker _mesa_update_state(ctx);
339*61046927SAndroid Build Coastguard Worker
340*61046927SAndroid Build Coastguard Worker if (!ctx->DrawPixValid) {
341*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION, "glBitmap");
342*61046927SAndroid Build Coastguard Worker return;
343*61046927SAndroid Build Coastguard Worker }
344*61046927SAndroid Build Coastguard Worker
345*61046927SAndroid Build Coastguard Worker if (ctx->RasterDiscard)
346*61046927SAndroid Build Coastguard Worker return;
347*61046927SAndroid Build Coastguard Worker
348*61046927SAndroid Build Coastguard Worker if (ctx->RenderMode == GL_RENDER) {
349*61046927SAndroid Build Coastguard Worker /* Truncate, to satisfy conformance tests (matches SGI's OpenGL). */
350*61046927SAndroid Build Coastguard Worker if (width > 0 && height > 0) {
351*61046927SAndroid Build Coastguard Worker const GLfloat epsilon = 0.0001F;
352*61046927SAndroid Build Coastguard Worker GLint x = util_ifloor(ctx->Current.RasterPos[0] + epsilon - xorig);
353*61046927SAndroid Build Coastguard Worker GLint y = util_ifloor(ctx->Current.RasterPos[1] + epsilon - yorig);
354*61046927SAndroid Build Coastguard Worker
355*61046927SAndroid Build Coastguard Worker if (!tex && ctx->Unpack.BufferObj) {
356*61046927SAndroid Build Coastguard Worker /* unpack from PBO */
357*61046927SAndroid Build Coastguard Worker if (!_mesa_validate_pbo_access(2, &ctx->Unpack, width, height,
358*61046927SAndroid Build Coastguard Worker 1, GL_COLOR_INDEX, GL_BITMAP,
359*61046927SAndroid Build Coastguard Worker INT_MAX, (const GLvoid *) bitmap)) {
360*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
361*61046927SAndroid Build Coastguard Worker "glBitmap(invalid PBO access)");
362*61046927SAndroid Build Coastguard Worker return;
363*61046927SAndroid Build Coastguard Worker }
364*61046927SAndroid Build Coastguard Worker if (_mesa_check_disallowed_mapping(ctx->Unpack.BufferObj)) {
365*61046927SAndroid Build Coastguard Worker /* buffer is mapped - that's an error */
366*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
367*61046927SAndroid Build Coastguard Worker "glBitmap(PBO is mapped)");
368*61046927SAndroid Build Coastguard Worker return;
369*61046927SAndroid Build Coastguard Worker }
370*61046927SAndroid Build Coastguard Worker }
371*61046927SAndroid Build Coastguard Worker
372*61046927SAndroid Build Coastguard Worker st_Bitmap(ctx, x, y, width, height, &ctx->Unpack, bitmap, tex);
373*61046927SAndroid Build Coastguard Worker }
374*61046927SAndroid Build Coastguard Worker }
375*61046927SAndroid Build Coastguard Worker else if (ctx->RenderMode == GL_FEEDBACK) {
376*61046927SAndroid Build Coastguard Worker FLUSH_CURRENT(ctx, 0);
377*61046927SAndroid Build Coastguard Worker _mesa_feedback_token( ctx, (GLfloat) (GLint) GL_BITMAP_TOKEN );
378*61046927SAndroid Build Coastguard Worker _mesa_feedback_vertex( ctx,
379*61046927SAndroid Build Coastguard Worker ctx->Current.RasterPos,
380*61046927SAndroid Build Coastguard Worker ctx->Current.RasterColor,
381*61046927SAndroid Build Coastguard Worker ctx->Current.RasterTexCoords[0] );
382*61046927SAndroid Build Coastguard Worker }
383*61046927SAndroid Build Coastguard Worker else {
384*61046927SAndroid Build Coastguard Worker assert(ctx->RenderMode == GL_SELECT);
385*61046927SAndroid Build Coastguard Worker /* Do nothing. See OpenGL Spec, Appendix B, Corollary 6. */
386*61046927SAndroid Build Coastguard Worker }
387*61046927SAndroid Build Coastguard Worker
388*61046927SAndroid Build Coastguard Worker /* update raster position */
389*61046927SAndroid Build Coastguard Worker ctx->Current.RasterPos[0] += xmove;
390*61046927SAndroid Build Coastguard Worker ctx->Current.RasterPos[1] += ymove;
391*61046927SAndroid Build Coastguard Worker ctx->PopAttribState |= GL_CURRENT_BIT;
392*61046927SAndroid Build Coastguard Worker
393*61046927SAndroid Build Coastguard Worker if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
394*61046927SAndroid Build Coastguard Worker _mesa_flush(ctx);
395*61046927SAndroid Build Coastguard Worker }
396*61046927SAndroid Build Coastguard Worker }
397*61046927SAndroid Build Coastguard Worker
398*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_Bitmap(GLsizei width,GLsizei height,GLfloat xorig,GLfloat yorig,GLfloat xmove,GLfloat ymove,const GLubyte * bitmap)399*61046927SAndroid Build Coastguard Worker _mesa_Bitmap(GLsizei width, GLsizei height,
400*61046927SAndroid Build Coastguard Worker GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove,
401*61046927SAndroid Build Coastguard Worker const GLubyte *bitmap)
402*61046927SAndroid Build Coastguard Worker {
403*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
404*61046927SAndroid Build Coastguard Worker
405*61046927SAndroid Build Coastguard Worker _mesa_bitmap(ctx, width, height, xorig, yorig, xmove, ymove, bitmap, NULL);
406*61046927SAndroid Build Coastguard Worker }
407