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) 2009 VMware, Inc. 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
26*61046927SAndroid Build Coastguard Worker /**
27*61046927SAndroid Build Coastguard Worker * \file viewport.c
28*61046927SAndroid Build Coastguard Worker * glViewport and glDepthRange functions.
29*61046927SAndroid Build Coastguard Worker */
30*61046927SAndroid Build Coastguard Worker
31*61046927SAndroid Build Coastguard Worker
32*61046927SAndroid Build Coastguard Worker #include "context.h"
33*61046927SAndroid Build Coastguard Worker #include "enums.h"
34*61046927SAndroid Build Coastguard Worker #include "macros.h"
35*61046927SAndroid Build Coastguard Worker #include "mtypes.h"
36*61046927SAndroid Build Coastguard Worker #include "viewport.h"
37*61046927SAndroid Build Coastguard Worker #include "api_exec_decl.h"
38*61046927SAndroid Build Coastguard Worker
39*61046927SAndroid Build Coastguard Worker #include "state_tracker/st_manager.h"
40*61046927SAndroid Build Coastguard Worker #include "state_tracker/st_context.h"
41*61046927SAndroid Build Coastguard Worker
42*61046927SAndroid Build Coastguard Worker static void
clamp_viewport(struct gl_context * ctx,GLfloat * x,GLfloat * y,GLfloat * width,GLfloat * height)43*61046927SAndroid Build Coastguard Worker clamp_viewport(struct gl_context *ctx, GLfloat *x, GLfloat *y,
44*61046927SAndroid Build Coastguard Worker GLfloat *width, GLfloat *height)
45*61046927SAndroid Build Coastguard Worker {
46*61046927SAndroid Build Coastguard Worker /* clamp width and height to the implementation dependent range */
47*61046927SAndroid Build Coastguard Worker *width = MIN2(*width, (GLfloat) ctx->Const.MaxViewportWidth);
48*61046927SAndroid Build Coastguard Worker *height = MIN2(*height, (GLfloat) ctx->Const.MaxViewportHeight);
49*61046927SAndroid Build Coastguard Worker
50*61046927SAndroid Build Coastguard Worker /* The GL_ARB_viewport_array spec says:
51*61046927SAndroid Build Coastguard Worker *
52*61046927SAndroid Build Coastguard Worker * "The location of the viewport's bottom-left corner, given by (x,y),
53*61046927SAndroid Build Coastguard Worker * are clamped to be within the implementation-dependent viewport
54*61046927SAndroid Build Coastguard Worker * bounds range. The viewport bounds range [min, max] tuple may be
55*61046927SAndroid Build Coastguard Worker * determined by calling GetFloatv with the symbolic constant
56*61046927SAndroid Build Coastguard Worker * VIEWPORT_BOUNDS_RANGE (see section 6.1)."
57*61046927SAndroid Build Coastguard Worker */
58*61046927SAndroid Build Coastguard Worker if (_mesa_has_ARB_viewport_array(ctx) ||
59*61046927SAndroid Build Coastguard Worker _mesa_has_OES_viewport_array(ctx)) {
60*61046927SAndroid Build Coastguard Worker *x = CLAMP(*x,
61*61046927SAndroid Build Coastguard Worker ctx->Const.ViewportBounds.Min, ctx->Const.ViewportBounds.Max);
62*61046927SAndroid Build Coastguard Worker *y = CLAMP(*y,
63*61046927SAndroid Build Coastguard Worker ctx->Const.ViewportBounds.Min, ctx->Const.ViewportBounds.Max);
64*61046927SAndroid Build Coastguard Worker }
65*61046927SAndroid Build Coastguard Worker }
66*61046927SAndroid Build Coastguard Worker
67*61046927SAndroid Build Coastguard Worker static void
set_viewport_no_notify(struct gl_context * ctx,unsigned idx,GLfloat x,GLfloat y,GLfloat width,GLfloat height)68*61046927SAndroid Build Coastguard Worker set_viewport_no_notify(struct gl_context *ctx, unsigned idx,
69*61046927SAndroid Build Coastguard Worker GLfloat x, GLfloat y,
70*61046927SAndroid Build Coastguard Worker GLfloat width, GLfloat height)
71*61046927SAndroid Build Coastguard Worker {
72*61046927SAndroid Build Coastguard Worker if (ctx->ViewportArray[idx].X == x &&
73*61046927SAndroid Build Coastguard Worker ctx->ViewportArray[idx].Width == width &&
74*61046927SAndroid Build Coastguard Worker ctx->ViewportArray[idx].Y == y &&
75*61046927SAndroid Build Coastguard Worker ctx->ViewportArray[idx].Height == height)
76*61046927SAndroid Build Coastguard Worker return;
77*61046927SAndroid Build Coastguard Worker
78*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, 0, GL_VIEWPORT_BIT);
79*61046927SAndroid Build Coastguard Worker ctx->NewDriverState |= ST_NEW_VIEWPORT;
80*61046927SAndroid Build Coastguard Worker
81*61046927SAndroid Build Coastguard Worker ctx->ViewportArray[idx].X = x;
82*61046927SAndroid Build Coastguard Worker ctx->ViewportArray[idx].Width = width;
83*61046927SAndroid Build Coastguard Worker ctx->ViewportArray[idx].Y = y;
84*61046927SAndroid Build Coastguard Worker ctx->ViewportArray[idx].Height = height;
85*61046927SAndroid Build Coastguard Worker }
86*61046927SAndroid Build Coastguard Worker
87*61046927SAndroid Build Coastguard Worker struct gl_viewport_inputs {
88*61046927SAndroid Build Coastguard Worker GLfloat X, Y; /**< position */
89*61046927SAndroid Build Coastguard Worker GLfloat Width, Height; /**< size */
90*61046927SAndroid Build Coastguard Worker };
91*61046927SAndroid Build Coastguard Worker
92*61046927SAndroid Build Coastguard Worker struct gl_depthrange_inputs {
93*61046927SAndroid Build Coastguard Worker GLdouble Near, Far; /**< Depth buffer range */
94*61046927SAndroid Build Coastguard Worker };
95*61046927SAndroid Build Coastguard Worker
96*61046927SAndroid Build Coastguard Worker static void
viewport(struct gl_context * ctx,GLint x,GLint y,GLsizei width,GLsizei height)97*61046927SAndroid Build Coastguard Worker viewport(struct gl_context *ctx, GLint x, GLint y, GLsizei width,
98*61046927SAndroid Build Coastguard Worker GLsizei height)
99*61046927SAndroid Build Coastguard Worker {
100*61046927SAndroid Build Coastguard Worker struct gl_viewport_inputs input = { x, y, width, height };
101*61046927SAndroid Build Coastguard Worker
102*61046927SAndroid Build Coastguard Worker /* Clamp the viewport to the implementation dependent values. */
103*61046927SAndroid Build Coastguard Worker clamp_viewport(ctx, &input.X, &input.Y, &input.Width, &input.Height);
104*61046927SAndroid Build Coastguard Worker
105*61046927SAndroid Build Coastguard Worker /* The GL_ARB_viewport_array spec says:
106*61046927SAndroid Build Coastguard Worker *
107*61046927SAndroid Build Coastguard Worker * "Viewport sets the parameters for all viewports to the same values
108*61046927SAndroid Build Coastguard Worker * and is equivalent (assuming no errors are generated) to:
109*61046927SAndroid Build Coastguard Worker *
110*61046927SAndroid Build Coastguard Worker * for (uint i = 0; i < MAX_VIEWPORTS; i++)
111*61046927SAndroid Build Coastguard Worker * ViewportIndexedf(i, 1, (float)x, (float)y, (float)w, (float)h);"
112*61046927SAndroid Build Coastguard Worker *
113*61046927SAndroid Build Coastguard Worker * Set all of the viewports supported by the implementation, but only
114*61046927SAndroid Build Coastguard Worker * signal the driver once at the end.
115*61046927SAndroid Build Coastguard Worker */
116*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < ctx->Const.MaxViewports; i++)
117*61046927SAndroid Build Coastguard Worker set_viewport_no_notify(ctx, i, input.X, input.Y, input.Width, input.Height);
118*61046927SAndroid Build Coastguard Worker
119*61046927SAndroid Build Coastguard Worker if (ctx->invalidate_on_gl_viewport)
120*61046927SAndroid Build Coastguard Worker st_manager_invalidate_drawables(ctx);
121*61046927SAndroid Build Coastguard Worker }
122*61046927SAndroid Build Coastguard Worker
123*61046927SAndroid Build Coastguard Worker /**
124*61046927SAndroid Build Coastguard Worker * Set the viewport.
125*61046927SAndroid Build Coastguard Worker * \sa Called via glViewport() or display list execution.
126*61046927SAndroid Build Coastguard Worker *
127*61046927SAndroid Build Coastguard Worker * Flushes the vertices and calls _mesa_set_viewport() with the given
128*61046927SAndroid Build Coastguard Worker * parameters.
129*61046927SAndroid Build Coastguard Worker */
130*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_Viewport_no_error(GLint x,GLint y,GLsizei width,GLsizei height)131*61046927SAndroid Build Coastguard Worker _mesa_Viewport_no_error(GLint x, GLint y, GLsizei width, GLsizei height)
132*61046927SAndroid Build Coastguard Worker {
133*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
134*61046927SAndroid Build Coastguard Worker viewport(ctx, x, y, width, height);
135*61046927SAndroid Build Coastguard Worker }
136*61046927SAndroid Build Coastguard Worker
137*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_Viewport(GLint x,GLint y,GLsizei width,GLsizei height)138*61046927SAndroid Build Coastguard Worker _mesa_Viewport(GLint x, GLint y, GLsizei width, GLsizei height)
139*61046927SAndroid Build Coastguard Worker {
140*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
141*61046927SAndroid Build Coastguard Worker
142*61046927SAndroid Build Coastguard Worker if (MESA_VERBOSE & VERBOSE_API)
143*61046927SAndroid Build Coastguard Worker _mesa_debug(ctx, "glViewport %d %d %d %d\n", x, y, width, height);
144*61046927SAndroid Build Coastguard Worker
145*61046927SAndroid Build Coastguard Worker if (width < 0 || height < 0) {
146*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
147*61046927SAndroid Build Coastguard Worker "glViewport(%d, %d, %d, %d)", x, y, width, height);
148*61046927SAndroid Build Coastguard Worker return;
149*61046927SAndroid Build Coastguard Worker }
150*61046927SAndroid Build Coastguard Worker
151*61046927SAndroid Build Coastguard Worker viewport(ctx, x, y, width, height);
152*61046927SAndroid Build Coastguard Worker }
153*61046927SAndroid Build Coastguard Worker
154*61046927SAndroid Build Coastguard Worker
155*61046927SAndroid Build Coastguard Worker /**
156*61046927SAndroid Build Coastguard Worker * Set new viewport parameters and update derived state.
157*61046927SAndroid Build Coastguard Worker * Usually called from _mesa_Viewport().
158*61046927SAndroid Build Coastguard Worker *
159*61046927SAndroid Build Coastguard Worker * \param ctx GL context.
160*61046927SAndroid Build Coastguard Worker * \param idx Index of the viewport to be updated.
161*61046927SAndroid Build Coastguard Worker * \param x, y coordinates of the lower left corner of the viewport rectangle.
162*61046927SAndroid Build Coastguard Worker * \param width width of the viewport rectangle.
163*61046927SAndroid Build Coastguard Worker * \param height height of the viewport rectangle.
164*61046927SAndroid Build Coastguard Worker */
165*61046927SAndroid Build Coastguard Worker void
_mesa_set_viewport(struct gl_context * ctx,unsigned idx,GLfloat x,GLfloat y,GLfloat width,GLfloat height)166*61046927SAndroid Build Coastguard Worker _mesa_set_viewport(struct gl_context *ctx, unsigned idx, GLfloat x, GLfloat y,
167*61046927SAndroid Build Coastguard Worker GLfloat width, GLfloat height)
168*61046927SAndroid Build Coastguard Worker {
169*61046927SAndroid Build Coastguard Worker clamp_viewport(ctx, &x, &y, &width, &height);
170*61046927SAndroid Build Coastguard Worker set_viewport_no_notify(ctx, idx, x, y, width, height);
171*61046927SAndroid Build Coastguard Worker
172*61046927SAndroid Build Coastguard Worker if (ctx->invalidate_on_gl_viewport)
173*61046927SAndroid Build Coastguard Worker st_manager_invalidate_drawables(ctx);
174*61046927SAndroid Build Coastguard Worker }
175*61046927SAndroid Build Coastguard Worker
176*61046927SAndroid Build Coastguard Worker static void
viewport_array(struct gl_context * ctx,GLuint first,GLsizei count,struct gl_viewport_inputs * inputs)177*61046927SAndroid Build Coastguard Worker viewport_array(struct gl_context *ctx, GLuint first, GLsizei count,
178*61046927SAndroid Build Coastguard Worker struct gl_viewport_inputs *inputs)
179*61046927SAndroid Build Coastguard Worker {
180*61046927SAndroid Build Coastguard Worker for (GLsizei i = 0; i < count; i++) {
181*61046927SAndroid Build Coastguard Worker clamp_viewport(ctx, &inputs[i].X, &inputs[i].Y,
182*61046927SAndroid Build Coastguard Worker &inputs[i].Width, &inputs[i].Height);
183*61046927SAndroid Build Coastguard Worker
184*61046927SAndroid Build Coastguard Worker set_viewport_no_notify(ctx, i + first, inputs[i].X, inputs[i].Y,
185*61046927SAndroid Build Coastguard Worker inputs[i].Width, inputs[i].Height);
186*61046927SAndroid Build Coastguard Worker }
187*61046927SAndroid Build Coastguard Worker
188*61046927SAndroid Build Coastguard Worker if (ctx->invalidate_on_gl_viewport)
189*61046927SAndroid Build Coastguard Worker st_manager_invalidate_drawables(ctx);
190*61046927SAndroid Build Coastguard Worker }
191*61046927SAndroid Build Coastguard Worker
192*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ViewportArrayv_no_error(GLuint first,GLsizei count,const GLfloat * v)193*61046927SAndroid Build Coastguard Worker _mesa_ViewportArrayv_no_error(GLuint first, GLsizei count, const GLfloat *v)
194*61046927SAndroid Build Coastguard Worker {
195*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
196*61046927SAndroid Build Coastguard Worker
197*61046927SAndroid Build Coastguard Worker struct gl_viewport_inputs *p = (struct gl_viewport_inputs *)v;
198*61046927SAndroid Build Coastguard Worker viewport_array(ctx, first, count, p);
199*61046927SAndroid Build Coastguard Worker }
200*61046927SAndroid Build Coastguard Worker
201*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ViewportArrayv(GLuint first,GLsizei count,const GLfloat * v)202*61046927SAndroid Build Coastguard Worker _mesa_ViewportArrayv(GLuint first, GLsizei count, const GLfloat *v)
203*61046927SAndroid Build Coastguard Worker {
204*61046927SAndroid Build Coastguard Worker int i;
205*61046927SAndroid Build Coastguard Worker struct gl_viewport_inputs *p = (struct gl_viewport_inputs *)v;
206*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
207*61046927SAndroid Build Coastguard Worker
208*61046927SAndroid Build Coastguard Worker if (MESA_VERBOSE & VERBOSE_API)
209*61046927SAndroid Build Coastguard Worker _mesa_debug(ctx, "glViewportArrayv %d %d\n", first, count);
210*61046927SAndroid Build Coastguard Worker
211*61046927SAndroid Build Coastguard Worker if ((first + count) > ctx->Const.MaxViewports) {
212*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
213*61046927SAndroid Build Coastguard Worker "glViewportArrayv: first (%d) + count (%d) > MaxViewports "
214*61046927SAndroid Build Coastguard Worker "(%d)",
215*61046927SAndroid Build Coastguard Worker first, count, ctx->Const.MaxViewports);
216*61046927SAndroid Build Coastguard Worker return;
217*61046927SAndroid Build Coastguard Worker }
218*61046927SAndroid Build Coastguard Worker
219*61046927SAndroid Build Coastguard Worker /* Verify width & height */
220*61046927SAndroid Build Coastguard Worker for (i = 0; i < count; i++) {
221*61046927SAndroid Build Coastguard Worker if (p[i].Width < 0 || p[i].Height < 0) {
222*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
223*61046927SAndroid Build Coastguard Worker "glViewportArrayv: index (%d) width or height < 0 "
224*61046927SAndroid Build Coastguard Worker "(%f, %f)",
225*61046927SAndroid Build Coastguard Worker i + first, p[i].Width, p[i].Height);
226*61046927SAndroid Build Coastguard Worker return;
227*61046927SAndroid Build Coastguard Worker }
228*61046927SAndroid Build Coastguard Worker }
229*61046927SAndroid Build Coastguard Worker
230*61046927SAndroid Build Coastguard Worker viewport_array(ctx, first, count, p);
231*61046927SAndroid Build Coastguard Worker }
232*61046927SAndroid Build Coastguard Worker
233*61046927SAndroid Build Coastguard Worker static void
viewport_indexed_err(struct gl_context * ctx,GLuint index,GLfloat x,GLfloat y,GLfloat w,GLfloat h,const char * function)234*61046927SAndroid Build Coastguard Worker viewport_indexed_err(struct gl_context *ctx, GLuint index, GLfloat x, GLfloat y,
235*61046927SAndroid Build Coastguard Worker GLfloat w, GLfloat h, const char *function)
236*61046927SAndroid Build Coastguard Worker {
237*61046927SAndroid Build Coastguard Worker if (MESA_VERBOSE & VERBOSE_API)
238*61046927SAndroid Build Coastguard Worker _mesa_debug(ctx, "%s(%d, %f, %f, %f, %f)\n",
239*61046927SAndroid Build Coastguard Worker function, index, x, y, w, h);
240*61046927SAndroid Build Coastguard Worker
241*61046927SAndroid Build Coastguard Worker if (index >= ctx->Const.MaxViewports) {
242*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
243*61046927SAndroid Build Coastguard Worker "%s: index (%d) >= MaxViewports (%d)",
244*61046927SAndroid Build Coastguard Worker function, index, ctx->Const.MaxViewports);
245*61046927SAndroid Build Coastguard Worker return;
246*61046927SAndroid Build Coastguard Worker }
247*61046927SAndroid Build Coastguard Worker
248*61046927SAndroid Build Coastguard Worker /* Verify width & height */
249*61046927SAndroid Build Coastguard Worker if (w < 0 || h < 0) {
250*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
251*61046927SAndroid Build Coastguard Worker "%s: index (%d) width or height < 0 (%f, %f)",
252*61046927SAndroid Build Coastguard Worker function, index, w, h);
253*61046927SAndroid Build Coastguard Worker return;
254*61046927SAndroid Build Coastguard Worker }
255*61046927SAndroid Build Coastguard Worker
256*61046927SAndroid Build Coastguard Worker _mesa_set_viewport(ctx, index, x, y, w, h);
257*61046927SAndroid Build Coastguard Worker }
258*61046927SAndroid Build Coastguard Worker
259*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ViewportIndexedf_no_error(GLuint index,GLfloat x,GLfloat y,GLfloat w,GLfloat h)260*61046927SAndroid Build Coastguard Worker _mesa_ViewportIndexedf_no_error(GLuint index, GLfloat x, GLfloat y,
261*61046927SAndroid Build Coastguard Worker GLfloat w, GLfloat h)
262*61046927SAndroid Build Coastguard Worker {
263*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
264*61046927SAndroid Build Coastguard Worker _mesa_set_viewport(ctx, index, x, y, w, h);
265*61046927SAndroid Build Coastguard Worker }
266*61046927SAndroid Build Coastguard Worker
267*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ViewportIndexedf(GLuint index,GLfloat x,GLfloat y,GLfloat w,GLfloat h)268*61046927SAndroid Build Coastguard Worker _mesa_ViewportIndexedf(GLuint index, GLfloat x, GLfloat y,
269*61046927SAndroid Build Coastguard Worker GLfloat w, GLfloat h)
270*61046927SAndroid Build Coastguard Worker {
271*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
272*61046927SAndroid Build Coastguard Worker viewport_indexed_err(ctx, index, x, y, w, h, "glViewportIndexedf");
273*61046927SAndroid Build Coastguard Worker }
274*61046927SAndroid Build Coastguard Worker
275*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ViewportIndexedfv_no_error(GLuint index,const GLfloat * v)276*61046927SAndroid Build Coastguard Worker _mesa_ViewportIndexedfv_no_error(GLuint index, const GLfloat *v)
277*61046927SAndroid Build Coastguard Worker {
278*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
279*61046927SAndroid Build Coastguard Worker _mesa_set_viewport(ctx, index, v[0], v[1], v[2], v[3]);
280*61046927SAndroid Build Coastguard Worker }
281*61046927SAndroid Build Coastguard Worker
282*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ViewportIndexedfv(GLuint index,const GLfloat * v)283*61046927SAndroid Build Coastguard Worker _mesa_ViewportIndexedfv(GLuint index, const GLfloat *v)
284*61046927SAndroid Build Coastguard Worker {
285*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
286*61046927SAndroid Build Coastguard Worker viewport_indexed_err(ctx, index, v[0], v[1], v[2], v[3],
287*61046927SAndroid Build Coastguard Worker "glViewportIndexedfv");
288*61046927SAndroid Build Coastguard Worker }
289*61046927SAndroid Build Coastguard Worker
290*61046927SAndroid Build Coastguard Worker static void
set_depth_range_no_notify(struct gl_context * ctx,unsigned idx,GLclampd nearval,GLclampd farval)291*61046927SAndroid Build Coastguard Worker set_depth_range_no_notify(struct gl_context *ctx, unsigned idx,
292*61046927SAndroid Build Coastguard Worker GLclampd nearval, GLclampd farval)
293*61046927SAndroid Build Coastguard Worker {
294*61046927SAndroid Build Coastguard Worker if (ctx->ViewportArray[idx].Near == nearval &&
295*61046927SAndroid Build Coastguard Worker ctx->ViewportArray[idx].Far == farval)
296*61046927SAndroid Build Coastguard Worker return;
297*61046927SAndroid Build Coastguard Worker
298*61046927SAndroid Build Coastguard Worker /* The depth range is needed by program state constants. */
299*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, _NEW_VIEWPORT, GL_VIEWPORT_BIT);
300*61046927SAndroid Build Coastguard Worker ctx->NewDriverState |= ST_NEW_VIEWPORT;
301*61046927SAndroid Build Coastguard Worker
302*61046927SAndroid Build Coastguard Worker ctx->ViewportArray[idx].Near = SATURATE(nearval);
303*61046927SAndroid Build Coastguard Worker ctx->ViewportArray[idx].Far = SATURATE(farval);
304*61046927SAndroid Build Coastguard Worker }
305*61046927SAndroid Build Coastguard Worker
306*61046927SAndroid Build Coastguard Worker void
_mesa_set_depth_range(struct gl_context * ctx,unsigned idx,GLclampd nearval,GLclampd farval)307*61046927SAndroid Build Coastguard Worker _mesa_set_depth_range(struct gl_context *ctx, unsigned idx,
308*61046927SAndroid Build Coastguard Worker GLclampd nearval, GLclampd farval)
309*61046927SAndroid Build Coastguard Worker {
310*61046927SAndroid Build Coastguard Worker set_depth_range_no_notify(ctx, idx, nearval, farval);
311*61046927SAndroid Build Coastguard Worker }
312*61046927SAndroid Build Coastguard Worker
313*61046927SAndroid Build Coastguard Worker /**
314*61046927SAndroid Build Coastguard Worker * Called by glDepthRange
315*61046927SAndroid Build Coastguard Worker *
316*61046927SAndroid Build Coastguard Worker * \param nearval specifies the Z buffer value which should correspond to
317*61046927SAndroid Build Coastguard Worker * the near clip plane
318*61046927SAndroid Build Coastguard Worker * \param farval specifies the Z buffer value which should correspond to
319*61046927SAndroid Build Coastguard Worker * the far clip plane
320*61046927SAndroid Build Coastguard Worker */
321*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_DepthRange(GLclampd nearval,GLclampd farval)322*61046927SAndroid Build Coastguard Worker _mesa_DepthRange(GLclampd nearval, GLclampd farval)
323*61046927SAndroid Build Coastguard Worker {
324*61046927SAndroid Build Coastguard Worker unsigned i;
325*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
326*61046927SAndroid Build Coastguard Worker
327*61046927SAndroid Build Coastguard Worker if (MESA_VERBOSE&VERBOSE_API)
328*61046927SAndroid Build Coastguard Worker _mesa_debug(ctx, "glDepthRange %f %f\n", nearval, farval);
329*61046927SAndroid Build Coastguard Worker
330*61046927SAndroid Build Coastguard Worker /* The GL_ARB_viewport_array spec says:
331*61046927SAndroid Build Coastguard Worker *
332*61046927SAndroid Build Coastguard Worker * "DepthRange sets the depth range for all viewports to the same
333*61046927SAndroid Build Coastguard Worker * values and is equivalent (assuming no errors are generated) to:
334*61046927SAndroid Build Coastguard Worker *
335*61046927SAndroid Build Coastguard Worker * for (uint i = 0; i < MAX_VIEWPORTS; i++)
336*61046927SAndroid Build Coastguard Worker * DepthRangeIndexed(i, n, f);"
337*61046927SAndroid Build Coastguard Worker *
338*61046927SAndroid Build Coastguard Worker * Set the depth range for all of the viewports supported by the
339*61046927SAndroid Build Coastguard Worker * implementation, but only signal the driver once at the end.
340*61046927SAndroid Build Coastguard Worker */
341*61046927SAndroid Build Coastguard Worker for (i = 0; i < ctx->Const.MaxViewports; i++)
342*61046927SAndroid Build Coastguard Worker set_depth_range_no_notify(ctx, i, nearval, farval);
343*61046927SAndroid Build Coastguard Worker }
344*61046927SAndroid Build Coastguard Worker
345*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_DepthRangef(GLclampf nearval,GLclampf farval)346*61046927SAndroid Build Coastguard Worker _mesa_DepthRangef(GLclampf nearval, GLclampf farval)
347*61046927SAndroid Build Coastguard Worker {
348*61046927SAndroid Build Coastguard Worker _mesa_DepthRange(nearval, farval);
349*61046927SAndroid Build Coastguard Worker }
350*61046927SAndroid Build Coastguard Worker
351*61046927SAndroid Build Coastguard Worker /**
352*61046927SAndroid Build Coastguard Worker * Update a range DepthRange values
353*61046927SAndroid Build Coastguard Worker *
354*61046927SAndroid Build Coastguard Worker * \param first starting array index
355*61046927SAndroid Build Coastguard Worker * \param count count of DepthRange items to update
356*61046927SAndroid Build Coastguard Worker * \param v pointer to memory containing
357*61046927SAndroid Build Coastguard Worker * GLclampd near and far clip-plane values
358*61046927SAndroid Build Coastguard Worker */
359*61046927SAndroid Build Coastguard Worker static ALWAYS_INLINE void
depth_range_arrayv(struct gl_context * ctx,GLuint first,GLsizei count,const struct gl_depthrange_inputs * const inputs)360*61046927SAndroid Build Coastguard Worker depth_range_arrayv(struct gl_context *ctx, GLuint first, GLsizei count,
361*61046927SAndroid Build Coastguard Worker const struct gl_depthrange_inputs *const inputs)
362*61046927SAndroid Build Coastguard Worker {
363*61046927SAndroid Build Coastguard Worker for (GLsizei i = 0; i < count; i++)
364*61046927SAndroid Build Coastguard Worker set_depth_range_no_notify(ctx, i + first, inputs[i].Near, inputs[i].Far);
365*61046927SAndroid Build Coastguard Worker }
366*61046927SAndroid Build Coastguard Worker
367*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_DepthRangeArrayv_no_error(GLuint first,GLsizei count,const GLclampd * v)368*61046927SAndroid Build Coastguard Worker _mesa_DepthRangeArrayv_no_error(GLuint first, GLsizei count, const GLclampd *v)
369*61046927SAndroid Build Coastguard Worker {
370*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
371*61046927SAndroid Build Coastguard Worker
372*61046927SAndroid Build Coastguard Worker const struct gl_depthrange_inputs *const p =
373*61046927SAndroid Build Coastguard Worker (struct gl_depthrange_inputs *)v;
374*61046927SAndroid Build Coastguard Worker depth_range_arrayv(ctx, first, count, p);
375*61046927SAndroid Build Coastguard Worker }
376*61046927SAndroid Build Coastguard Worker
377*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_DepthRangeArrayv(GLuint first,GLsizei count,const GLclampd * v)378*61046927SAndroid Build Coastguard Worker _mesa_DepthRangeArrayv(GLuint first, GLsizei count, const GLclampd *v)
379*61046927SAndroid Build Coastguard Worker {
380*61046927SAndroid Build Coastguard Worker const struct gl_depthrange_inputs *const p =
381*61046927SAndroid Build Coastguard Worker (struct gl_depthrange_inputs *) v;
382*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
383*61046927SAndroid Build Coastguard Worker
384*61046927SAndroid Build Coastguard Worker if (MESA_VERBOSE & VERBOSE_API)
385*61046927SAndroid Build Coastguard Worker _mesa_debug(ctx, "glDepthRangeArrayv %d %d\n", first, count);
386*61046927SAndroid Build Coastguard Worker
387*61046927SAndroid Build Coastguard Worker if ((first + count) > ctx->Const.MaxViewports) {
388*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
389*61046927SAndroid Build Coastguard Worker "glDepthRangev: first (%d) + count (%d) >= MaxViewports (%d)",
390*61046927SAndroid Build Coastguard Worker first, count, ctx->Const.MaxViewports);
391*61046927SAndroid Build Coastguard Worker return;
392*61046927SAndroid Build Coastguard Worker }
393*61046927SAndroid Build Coastguard Worker
394*61046927SAndroid Build Coastguard Worker depth_range_arrayv(ctx, first, count, p);
395*61046927SAndroid Build Coastguard Worker }
396*61046927SAndroid Build Coastguard Worker
397*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_DepthRangeArrayfvOES(GLuint first,GLsizei count,const GLfloat * v)398*61046927SAndroid Build Coastguard Worker _mesa_DepthRangeArrayfvOES(GLuint first, GLsizei count, const GLfloat *v)
399*61046927SAndroid Build Coastguard Worker {
400*61046927SAndroid Build Coastguard Worker int i;
401*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
402*61046927SAndroid Build Coastguard Worker
403*61046927SAndroid Build Coastguard Worker if (MESA_VERBOSE & VERBOSE_API)
404*61046927SAndroid Build Coastguard Worker _mesa_debug(ctx, "glDepthRangeArrayfv %d %d\n", first, count);
405*61046927SAndroid Build Coastguard Worker
406*61046927SAndroid Build Coastguard Worker if ((first + count) > ctx->Const.MaxViewports) {
407*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
408*61046927SAndroid Build Coastguard Worker "glDepthRangeArrayfv: first (%d) + count (%d) >= MaxViewports (%d)",
409*61046927SAndroid Build Coastguard Worker first, count, ctx->Const.MaxViewports);
410*61046927SAndroid Build Coastguard Worker return;
411*61046927SAndroid Build Coastguard Worker }
412*61046927SAndroid Build Coastguard Worker
413*61046927SAndroid Build Coastguard Worker for (i = 0; i < count; i++)
414*61046927SAndroid Build Coastguard Worker set_depth_range_no_notify(ctx, i + first, v[i * 2], v[i * 2 + 1]);
415*61046927SAndroid Build Coastguard Worker }
416*61046927SAndroid Build Coastguard Worker
417*61046927SAndroid Build Coastguard Worker /**
418*61046927SAndroid Build Coastguard Worker * Update a single DepthRange
419*61046927SAndroid Build Coastguard Worker *
420*61046927SAndroid Build Coastguard Worker * \param index array index to update
421*61046927SAndroid Build Coastguard Worker * \param nearval specifies the Z buffer value which should correspond to
422*61046927SAndroid Build Coastguard Worker * the near clip plane
423*61046927SAndroid Build Coastguard Worker * \param farval specifies the Z buffer value which should correspond to
424*61046927SAndroid Build Coastguard Worker * the far clip plane
425*61046927SAndroid Build Coastguard Worker */
426*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_DepthRangeIndexed_no_error(GLuint index,GLclampd nearval,GLclampd farval)427*61046927SAndroid Build Coastguard Worker _mesa_DepthRangeIndexed_no_error(GLuint index, GLclampd nearval,
428*61046927SAndroid Build Coastguard Worker GLclampd farval)
429*61046927SAndroid Build Coastguard Worker {
430*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
431*61046927SAndroid Build Coastguard Worker _mesa_set_depth_range(ctx, index, nearval, farval);
432*61046927SAndroid Build Coastguard Worker }
433*61046927SAndroid Build Coastguard Worker
434*61046927SAndroid Build Coastguard Worker
435*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_DepthRangeIndexed(GLuint index,GLclampd nearval,GLclampd farval)436*61046927SAndroid Build Coastguard Worker _mesa_DepthRangeIndexed(GLuint index, GLclampd nearval, GLclampd farval)
437*61046927SAndroid Build Coastguard Worker {
438*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
439*61046927SAndroid Build Coastguard Worker
440*61046927SAndroid Build Coastguard Worker if (MESA_VERBOSE & VERBOSE_API)
441*61046927SAndroid Build Coastguard Worker _mesa_debug(ctx, "glDepthRangeIndexed(%d, %f, %f)\n",
442*61046927SAndroid Build Coastguard Worker index, nearval, farval);
443*61046927SAndroid Build Coastguard Worker
444*61046927SAndroid Build Coastguard Worker if (index >= ctx->Const.MaxViewports) {
445*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
446*61046927SAndroid Build Coastguard Worker "glDepthRangeIndexed: index (%d) >= MaxViewports (%d)",
447*61046927SAndroid Build Coastguard Worker index, ctx->Const.MaxViewports);
448*61046927SAndroid Build Coastguard Worker return;
449*61046927SAndroid Build Coastguard Worker }
450*61046927SAndroid Build Coastguard Worker
451*61046927SAndroid Build Coastguard Worker _mesa_set_depth_range(ctx, index, nearval, farval);
452*61046927SAndroid Build Coastguard Worker }
453*61046927SAndroid Build Coastguard Worker
454*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_DepthRangeIndexedfOES(GLuint index,GLfloat nearval,GLfloat farval)455*61046927SAndroid Build Coastguard Worker _mesa_DepthRangeIndexedfOES(GLuint index, GLfloat nearval, GLfloat farval)
456*61046927SAndroid Build Coastguard Worker {
457*61046927SAndroid Build Coastguard Worker _mesa_DepthRangeIndexed(index, nearval, farval);
458*61046927SAndroid Build Coastguard Worker }
459*61046927SAndroid Build Coastguard Worker
460*61046927SAndroid Build Coastguard Worker /**
461*61046927SAndroid Build Coastguard Worker * Initialize the context viewport attribute group.
462*61046927SAndroid Build Coastguard Worker * \param ctx the GL context.
463*61046927SAndroid Build Coastguard Worker */
_mesa_init_viewport(struct gl_context * ctx)464*61046927SAndroid Build Coastguard Worker void _mesa_init_viewport(struct gl_context *ctx)
465*61046927SAndroid Build Coastguard Worker {
466*61046927SAndroid Build Coastguard Worker unsigned i;
467*61046927SAndroid Build Coastguard Worker
468*61046927SAndroid Build Coastguard Worker ctx->Transform.ClipOrigin = GL_LOWER_LEFT;
469*61046927SAndroid Build Coastguard Worker ctx->Transform.ClipDepthMode = GL_NEGATIVE_ONE_TO_ONE;
470*61046927SAndroid Build Coastguard Worker
471*61046927SAndroid Build Coastguard Worker /* Note: ctx->Const.MaxViewports may not have been set by the driver yet,
472*61046927SAndroid Build Coastguard Worker * so just initialize all of them.
473*61046927SAndroid Build Coastguard Worker */
474*61046927SAndroid Build Coastguard Worker for (i = 0; i < MAX_VIEWPORTS; i++) {
475*61046927SAndroid Build Coastguard Worker /* Viewport group */
476*61046927SAndroid Build Coastguard Worker ctx->ViewportArray[i].X = 0;
477*61046927SAndroid Build Coastguard Worker ctx->ViewportArray[i].Y = 0;
478*61046927SAndroid Build Coastguard Worker ctx->ViewportArray[i].Width = 0;
479*61046927SAndroid Build Coastguard Worker ctx->ViewportArray[i].Height = 0;
480*61046927SAndroid Build Coastguard Worker ctx->ViewportArray[i].Near = 0.0;
481*61046927SAndroid Build Coastguard Worker ctx->ViewportArray[i].Far = 1.0;
482*61046927SAndroid Build Coastguard Worker ctx->ViewportArray[i].SwizzleX = GL_VIEWPORT_SWIZZLE_POSITIVE_X_NV;
483*61046927SAndroid Build Coastguard Worker ctx->ViewportArray[i].SwizzleY = GL_VIEWPORT_SWIZZLE_POSITIVE_Y_NV;
484*61046927SAndroid Build Coastguard Worker ctx->ViewportArray[i].SwizzleZ = GL_VIEWPORT_SWIZZLE_POSITIVE_Z_NV;
485*61046927SAndroid Build Coastguard Worker ctx->ViewportArray[i].SwizzleW = GL_VIEWPORT_SWIZZLE_POSITIVE_W_NV;
486*61046927SAndroid Build Coastguard Worker }
487*61046927SAndroid Build Coastguard Worker
488*61046927SAndroid Build Coastguard Worker ctx->SubpixelPrecisionBias[0] = 0;
489*61046927SAndroid Build Coastguard Worker ctx->SubpixelPrecisionBias[1] = 0;
490*61046927SAndroid Build Coastguard Worker }
491*61046927SAndroid Build Coastguard Worker
492*61046927SAndroid Build Coastguard Worker
493*61046927SAndroid Build Coastguard Worker static ALWAYS_INLINE void
clip_control(struct gl_context * ctx,GLenum origin,GLenum depth,bool no_error)494*61046927SAndroid Build Coastguard Worker clip_control(struct gl_context *ctx, GLenum origin, GLenum depth, bool no_error)
495*61046927SAndroid Build Coastguard Worker {
496*61046927SAndroid Build Coastguard Worker if (ctx->Transform.ClipOrigin == origin &&
497*61046927SAndroid Build Coastguard Worker ctx->Transform.ClipDepthMode == depth)
498*61046927SAndroid Build Coastguard Worker return;
499*61046927SAndroid Build Coastguard Worker
500*61046927SAndroid Build Coastguard Worker if (!no_error &&
501*61046927SAndroid Build Coastguard Worker origin != GL_LOWER_LEFT && origin != GL_UPPER_LEFT) {
502*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "glClipControl");
503*61046927SAndroid Build Coastguard Worker return;
504*61046927SAndroid Build Coastguard Worker }
505*61046927SAndroid Build Coastguard Worker
506*61046927SAndroid Build Coastguard Worker if (!no_error &&
507*61046927SAndroid Build Coastguard Worker depth != GL_NEGATIVE_ONE_TO_ONE && depth != GL_ZERO_TO_ONE) {
508*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "glClipControl");
509*61046927SAndroid Build Coastguard Worker return;
510*61046927SAndroid Build Coastguard Worker }
511*61046927SAndroid Build Coastguard Worker
512*61046927SAndroid Build Coastguard Worker /* Affects transform state and the viewport transform */
513*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, 0, GL_TRANSFORM_BIT);
514*61046927SAndroid Build Coastguard Worker ctx->NewDriverState |= ST_NEW_VIEWPORT | ST_NEW_RASTERIZER;
515*61046927SAndroid Build Coastguard Worker
516*61046927SAndroid Build Coastguard Worker if (ctx->Transform.ClipOrigin != origin) {
517*61046927SAndroid Build Coastguard Worker ctx->Transform.ClipOrigin = origin;
518*61046927SAndroid Build Coastguard Worker
519*61046927SAndroid Build Coastguard Worker /* Affects the winding order of the front face. */
520*61046927SAndroid Build Coastguard Worker ctx->NewDriverState |= ST_NEW_RASTERIZER;
521*61046927SAndroid Build Coastguard Worker }
522*61046927SAndroid Build Coastguard Worker
523*61046927SAndroid Build Coastguard Worker if (ctx->Transform.ClipDepthMode != depth) {
524*61046927SAndroid Build Coastguard Worker ctx->Transform.ClipDepthMode = depth;
525*61046927SAndroid Build Coastguard Worker }
526*61046927SAndroid Build Coastguard Worker }
527*61046927SAndroid Build Coastguard Worker
528*61046927SAndroid Build Coastguard Worker
529*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ClipControl_no_error(GLenum origin,GLenum depth)530*61046927SAndroid Build Coastguard Worker _mesa_ClipControl_no_error(GLenum origin, GLenum depth)
531*61046927SAndroid Build Coastguard Worker {
532*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
533*61046927SAndroid Build Coastguard Worker clip_control(ctx, origin, depth, true);
534*61046927SAndroid Build Coastguard Worker }
535*61046927SAndroid Build Coastguard Worker
536*61046927SAndroid Build Coastguard Worker
537*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ClipControl(GLenum origin,GLenum depth)538*61046927SAndroid Build Coastguard Worker _mesa_ClipControl(GLenum origin, GLenum depth)
539*61046927SAndroid Build Coastguard Worker {
540*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
541*61046927SAndroid Build Coastguard Worker
542*61046927SAndroid Build Coastguard Worker if (MESA_VERBOSE & VERBOSE_API)
543*61046927SAndroid Build Coastguard Worker _mesa_debug(ctx, "glClipControl(%s, %s)\n",
544*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(origin),
545*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(depth));
546*61046927SAndroid Build Coastguard Worker
547*61046927SAndroid Build Coastguard Worker ASSERT_OUTSIDE_BEGIN_END(ctx);
548*61046927SAndroid Build Coastguard Worker
549*61046927SAndroid Build Coastguard Worker if (!ctx->Extensions.ARB_clip_control) {
550*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION, "glClipControl");
551*61046927SAndroid Build Coastguard Worker return;
552*61046927SAndroid Build Coastguard Worker }
553*61046927SAndroid Build Coastguard Worker
554*61046927SAndroid Build Coastguard Worker clip_control(ctx, origin, depth, false);
555*61046927SAndroid Build Coastguard Worker }
556*61046927SAndroid Build Coastguard Worker
557*61046927SAndroid Build Coastguard Worker /**
558*61046927SAndroid Build Coastguard Worker * Computes the scaling and the translation part of the
559*61046927SAndroid Build Coastguard Worker * viewport transform matrix of the \param i-th viewport
560*61046927SAndroid Build Coastguard Worker * and writes that into \param scale and \param translate.
561*61046927SAndroid Build Coastguard Worker */
562*61046927SAndroid Build Coastguard Worker void
_mesa_get_viewport_xform(struct gl_context * ctx,unsigned i,float scale[3],float translate[3])563*61046927SAndroid Build Coastguard Worker _mesa_get_viewport_xform(struct gl_context *ctx, unsigned i,
564*61046927SAndroid Build Coastguard Worker float scale[3], float translate[3])
565*61046927SAndroid Build Coastguard Worker {
566*61046927SAndroid Build Coastguard Worker float x = ctx->ViewportArray[i].X;
567*61046927SAndroid Build Coastguard Worker float y = ctx->ViewportArray[i].Y;
568*61046927SAndroid Build Coastguard Worker float half_width = 0.5f * ctx->ViewportArray[i].Width;
569*61046927SAndroid Build Coastguard Worker float half_height = 0.5f * ctx->ViewportArray[i].Height;
570*61046927SAndroid Build Coastguard Worker double n = ctx->ViewportArray[i].Near;
571*61046927SAndroid Build Coastguard Worker double f = ctx->ViewportArray[i].Far;
572*61046927SAndroid Build Coastguard Worker
573*61046927SAndroid Build Coastguard Worker scale[0] = half_width;
574*61046927SAndroid Build Coastguard Worker translate[0] = half_width + x;
575*61046927SAndroid Build Coastguard Worker if (ctx->Transform.ClipOrigin == GL_UPPER_LEFT) {
576*61046927SAndroid Build Coastguard Worker scale[1] = -half_height;
577*61046927SAndroid Build Coastguard Worker } else {
578*61046927SAndroid Build Coastguard Worker scale[1] = half_height;
579*61046927SAndroid Build Coastguard Worker }
580*61046927SAndroid Build Coastguard Worker translate[1] = half_height + y;
581*61046927SAndroid Build Coastguard Worker
582*61046927SAndroid Build Coastguard Worker if (ctx->Transform.ClipDepthMode == GL_NEGATIVE_ONE_TO_ONE) {
583*61046927SAndroid Build Coastguard Worker scale[2] = 0.5 * (f - n);
584*61046927SAndroid Build Coastguard Worker translate[2] = 0.5 * (n + f);
585*61046927SAndroid Build Coastguard Worker } else {
586*61046927SAndroid Build Coastguard Worker scale[2] = f - n;
587*61046927SAndroid Build Coastguard Worker translate[2] = n;
588*61046927SAndroid Build Coastguard Worker }
589*61046927SAndroid Build Coastguard Worker }
590*61046927SAndroid Build Coastguard Worker
591*61046927SAndroid Build Coastguard Worker
592*61046927SAndroid Build Coastguard Worker static void
subpixel_precision_bias(struct gl_context * ctx,GLuint xbits,GLuint ybits)593*61046927SAndroid Build Coastguard Worker subpixel_precision_bias(struct gl_context *ctx, GLuint xbits, GLuint ybits)
594*61046927SAndroid Build Coastguard Worker {
595*61046927SAndroid Build Coastguard Worker if (MESA_VERBOSE & VERBOSE_API)
596*61046927SAndroid Build Coastguard Worker _mesa_debug(ctx, "glSubpixelPrecisionBiasNV(%u, %u)\n", xbits, ybits);
597*61046927SAndroid Build Coastguard Worker
598*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, 0, GL_VIEWPORT_BIT);
599*61046927SAndroid Build Coastguard Worker
600*61046927SAndroid Build Coastguard Worker ctx->SubpixelPrecisionBias[0] = xbits;
601*61046927SAndroid Build Coastguard Worker ctx->SubpixelPrecisionBias[1] = ybits;
602*61046927SAndroid Build Coastguard Worker
603*61046927SAndroid Build Coastguard Worker ctx->NewDriverState |= ST_NEW_RASTERIZER;
604*61046927SAndroid Build Coastguard Worker }
605*61046927SAndroid Build Coastguard Worker
606*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_SubpixelPrecisionBiasNV_no_error(GLuint xbits,GLuint ybits)607*61046927SAndroid Build Coastguard Worker _mesa_SubpixelPrecisionBiasNV_no_error(GLuint xbits, GLuint ybits)
608*61046927SAndroid Build Coastguard Worker {
609*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
610*61046927SAndroid Build Coastguard Worker
611*61046927SAndroid Build Coastguard Worker if (MESA_VERBOSE & VERBOSE_API)
612*61046927SAndroid Build Coastguard Worker _mesa_debug(ctx, "glSubpixelPrecisionBiasNV(%u, %u)\n", xbits, ybits);
613*61046927SAndroid Build Coastguard Worker
614*61046927SAndroid Build Coastguard Worker subpixel_precision_bias(ctx, xbits, ybits);
615*61046927SAndroid Build Coastguard Worker }
616*61046927SAndroid Build Coastguard Worker
617*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_SubpixelPrecisionBiasNV(GLuint xbits,GLuint ybits)618*61046927SAndroid Build Coastguard Worker _mesa_SubpixelPrecisionBiasNV(GLuint xbits, GLuint ybits)
619*61046927SAndroid Build Coastguard Worker {
620*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
621*61046927SAndroid Build Coastguard Worker
622*61046927SAndroid Build Coastguard Worker if (MESA_VERBOSE & VERBOSE_API)
623*61046927SAndroid Build Coastguard Worker _mesa_debug(ctx, "glSubpixelPrecisionBiasNV(%u, %u)\n", xbits, ybits);
624*61046927SAndroid Build Coastguard Worker
625*61046927SAndroid Build Coastguard Worker ASSERT_OUTSIDE_BEGIN_END(ctx);
626*61046927SAndroid Build Coastguard Worker
627*61046927SAndroid Build Coastguard Worker if (!ctx->Extensions.NV_conservative_raster) {
628*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
629*61046927SAndroid Build Coastguard Worker "glSubpixelPrecisionBiasNV not supported");
630*61046927SAndroid Build Coastguard Worker return;
631*61046927SAndroid Build Coastguard Worker }
632*61046927SAndroid Build Coastguard Worker
633*61046927SAndroid Build Coastguard Worker if (xbits > ctx->Const.MaxSubpixelPrecisionBiasBits) {
634*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "glSubpixelPrecisionBiasNV");
635*61046927SAndroid Build Coastguard Worker return;
636*61046927SAndroid Build Coastguard Worker }
637*61046927SAndroid Build Coastguard Worker
638*61046927SAndroid Build Coastguard Worker if (ybits > ctx->Const.MaxSubpixelPrecisionBiasBits) {
639*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "glSubpixelPrecisionBiasNV");
640*61046927SAndroid Build Coastguard Worker return;
641*61046927SAndroid Build Coastguard Worker }
642*61046927SAndroid Build Coastguard Worker
643*61046927SAndroid Build Coastguard Worker subpixel_precision_bias(ctx, xbits, ybits);
644*61046927SAndroid Build Coastguard Worker }
645*61046927SAndroid Build Coastguard Worker
646*61046927SAndroid Build Coastguard Worker static void
set_viewport_swizzle(struct gl_context * ctx,GLuint index,GLenum swizzlex,GLenum swizzley,GLenum swizzlez,GLenum swizzlew)647*61046927SAndroid Build Coastguard Worker set_viewport_swizzle(struct gl_context *ctx, GLuint index,
648*61046927SAndroid Build Coastguard Worker GLenum swizzlex, GLenum swizzley,
649*61046927SAndroid Build Coastguard Worker GLenum swizzlez, GLenum swizzlew)
650*61046927SAndroid Build Coastguard Worker {
651*61046927SAndroid Build Coastguard Worker struct gl_viewport_attrib *viewport = &ctx->ViewportArray[index];
652*61046927SAndroid Build Coastguard Worker if (viewport->SwizzleX == swizzlex &&
653*61046927SAndroid Build Coastguard Worker viewport->SwizzleY == swizzley &&
654*61046927SAndroid Build Coastguard Worker viewport->SwizzleZ == swizzlez &&
655*61046927SAndroid Build Coastguard Worker viewport->SwizzleW == swizzlew)
656*61046927SAndroid Build Coastguard Worker return;
657*61046927SAndroid Build Coastguard Worker
658*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, _NEW_VIEWPORT, GL_VIEWPORT_BIT);
659*61046927SAndroid Build Coastguard Worker ctx->NewDriverState |= ST_NEW_VIEWPORT;
660*61046927SAndroid Build Coastguard Worker
661*61046927SAndroid Build Coastguard Worker viewport->SwizzleX = swizzlex;
662*61046927SAndroid Build Coastguard Worker viewport->SwizzleY = swizzley;
663*61046927SAndroid Build Coastguard Worker viewport->SwizzleZ = swizzlez;
664*61046927SAndroid Build Coastguard Worker viewport->SwizzleW = swizzlew;
665*61046927SAndroid Build Coastguard Worker }
666*61046927SAndroid Build Coastguard Worker
667*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ViewportSwizzleNV_no_error(GLuint index,GLenum swizzlex,GLenum swizzley,GLenum swizzlez,GLenum swizzlew)668*61046927SAndroid Build Coastguard Worker _mesa_ViewportSwizzleNV_no_error(GLuint index,
669*61046927SAndroid Build Coastguard Worker GLenum swizzlex, GLenum swizzley,
670*61046927SAndroid Build Coastguard Worker GLenum swizzlez, GLenum swizzlew)
671*61046927SAndroid Build Coastguard Worker {
672*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
673*61046927SAndroid Build Coastguard Worker
674*61046927SAndroid Build Coastguard Worker if (MESA_VERBOSE & VERBOSE_API)
675*61046927SAndroid Build Coastguard Worker _mesa_debug(ctx, "glViewportSwizzleNV(%x, %x, %x, %x)\n",
676*61046927SAndroid Build Coastguard Worker swizzlex, swizzley, swizzlez, swizzlew);
677*61046927SAndroid Build Coastguard Worker
678*61046927SAndroid Build Coastguard Worker set_viewport_swizzle(ctx, index, swizzlex, swizzley, swizzlez, swizzlew);
679*61046927SAndroid Build Coastguard Worker }
680*61046927SAndroid Build Coastguard Worker
681*61046927SAndroid Build Coastguard Worker static bool
verify_viewport_swizzle(GLenum swizzle)682*61046927SAndroid Build Coastguard Worker verify_viewport_swizzle(GLenum swizzle)
683*61046927SAndroid Build Coastguard Worker {
684*61046927SAndroid Build Coastguard Worker return swizzle >= GL_VIEWPORT_SWIZZLE_POSITIVE_X_NV &&
685*61046927SAndroid Build Coastguard Worker swizzle <= GL_VIEWPORT_SWIZZLE_NEGATIVE_W_NV;
686*61046927SAndroid Build Coastguard Worker }
687*61046927SAndroid Build Coastguard Worker
688*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ViewportSwizzleNV(GLuint index,GLenum swizzlex,GLenum swizzley,GLenum swizzlez,GLenum swizzlew)689*61046927SAndroid Build Coastguard Worker _mesa_ViewportSwizzleNV(GLuint index,
690*61046927SAndroid Build Coastguard Worker GLenum swizzlex, GLenum swizzley,
691*61046927SAndroid Build Coastguard Worker GLenum swizzlez, GLenum swizzlew)
692*61046927SAndroid Build Coastguard Worker {
693*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
694*61046927SAndroid Build Coastguard Worker
695*61046927SAndroid Build Coastguard Worker if (MESA_VERBOSE & VERBOSE_API)
696*61046927SAndroid Build Coastguard Worker _mesa_debug(ctx, "glViewportSwizzleNV(%x, %x, %x, %x)\n",
697*61046927SAndroid Build Coastguard Worker swizzlex, swizzley, swizzlez, swizzlew);
698*61046927SAndroid Build Coastguard Worker
699*61046927SAndroid Build Coastguard Worker if (!ctx->Extensions.NV_viewport_swizzle) {
700*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
701*61046927SAndroid Build Coastguard Worker "glViewportSwizzleNV not supported");
702*61046927SAndroid Build Coastguard Worker return;
703*61046927SAndroid Build Coastguard Worker }
704*61046927SAndroid Build Coastguard Worker
705*61046927SAndroid Build Coastguard Worker if (index >= ctx->Const.MaxViewports) {
706*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
707*61046927SAndroid Build Coastguard Worker "glViewportSwizzleNV: index (%d) >= MaxViewports (%d)",
708*61046927SAndroid Build Coastguard Worker index, ctx->Const.MaxViewports);
709*61046927SAndroid Build Coastguard Worker return;
710*61046927SAndroid Build Coastguard Worker }
711*61046927SAndroid Build Coastguard Worker
712*61046927SAndroid Build Coastguard Worker if (!verify_viewport_swizzle(swizzlex)) {
713*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM,
714*61046927SAndroid Build Coastguard Worker "glViewportSwizzleNV(swizzlex=%x)", swizzlex);
715*61046927SAndroid Build Coastguard Worker return;
716*61046927SAndroid Build Coastguard Worker }
717*61046927SAndroid Build Coastguard Worker
718*61046927SAndroid Build Coastguard Worker if (!verify_viewport_swizzle(swizzley)) {
719*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM,
720*61046927SAndroid Build Coastguard Worker "glViewportSwizzleNV(swizzley=%x)", swizzley);
721*61046927SAndroid Build Coastguard Worker return;
722*61046927SAndroid Build Coastguard Worker }
723*61046927SAndroid Build Coastguard Worker
724*61046927SAndroid Build Coastguard Worker if (!verify_viewport_swizzle(swizzlez)) {
725*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM,
726*61046927SAndroid Build Coastguard Worker "glViewportSwizzleNV(swizzlez=%x)", swizzlez);
727*61046927SAndroid Build Coastguard Worker return;
728*61046927SAndroid Build Coastguard Worker }
729*61046927SAndroid Build Coastguard Worker
730*61046927SAndroid Build Coastguard Worker if (!verify_viewport_swizzle(swizzlew)) {
731*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM,
732*61046927SAndroid Build Coastguard Worker "glViewportSwizzleNV(swizzlew=%x)", swizzlew);
733*61046927SAndroid Build Coastguard Worker return;
734*61046927SAndroid Build Coastguard Worker }
735*61046927SAndroid Build Coastguard Worker
736*61046927SAndroid Build Coastguard Worker set_viewport_swizzle(ctx, index, swizzlex, swizzley, swizzlez, swizzlew);
737*61046927SAndroid Build Coastguard Worker }
738