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