+void GLAPIENTRY
+_mesa_ViewportArrayv(GLuint first, GLsizei count, const GLfloat *v)
+{
+ int i;
+ const struct gl_viewport_inputs *const p = (struct gl_viewport_inputs *) v;
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx, "glViewportArrayv %d %d\n", first, count);
+
+ if ((first + count) > ctx->Const.MaxViewports) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glViewportArrayv: first (%d) + count (%d) > MaxViewports "
+ "(%d)",
+ first, count, ctx->Const.MaxViewports);
+ return;
+ }
+
+ /* Verify width & height */
+ for (i = 0; i < count; i++) {
+ if (p[i].Width < 0 || p[i].Height < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glViewportArrayv: index (%d) width or height < 0 "
+ "(%f, %f)",
+ i + first, p[i].Width, p[i].Height);
+ return;
+ }
+ }
+
+ for (i = 0; i < count; i++)
+ set_viewport_no_notify(ctx, i + first,
+ p[i].X, p[i].Y,
+ p[i].Width, p[i].Height);
+
+ if (ctx->Driver.Viewport)
+ ctx->Driver.Viewport(ctx);
+}
+
+static void
+ViewportIndexedf(GLuint index, GLfloat x, GLfloat y,
+ GLfloat w, GLfloat h, const char *function)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx, "%s(%d, %f, %f, %f, %f)\n",
+ function, index, x, y, w, h);
+
+ if (index >= ctx->Const.MaxViewports) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "%s: index (%d) >= MaxViewports (%d)",
+ function, index, ctx->Const.MaxViewports);
+ return;
+ }
+
+ /* Verify width & height */
+ if (w < 0 || h < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "%s: index (%d) width or height < 0 (%f, %f)",
+ function, index, w, h);
+ return;
+ }
+
+ _mesa_set_viewport(ctx, index, x, y, w, h);
+}
+
+void GLAPIENTRY
+_mesa_ViewportIndexedf(GLuint index, GLfloat x, GLfloat y,
+ GLfloat w, GLfloat h)
+{
+ ViewportIndexedf(index, x, y, w, h, "glViewportIndexedf");
+}
+
+void GLAPIENTRY
+_mesa_ViewportIndexedfv(GLuint index, const GLfloat *v)
+{
+ ViewportIndexedf(index, v[0], v[1], v[2], v[3], "glViewportIndexedfv");
+}
+
+static void
+set_depth_range_no_notify(struct gl_context *ctx, unsigned idx,
+ GLclampd nearval, GLclampd farval)
+{
+ if (ctx->ViewportArray[idx].Near == nearval &&
+ ctx->ViewportArray[idx].Far == farval)
+ return;
+
+ ctx->ViewportArray[idx].Near = CLAMP(nearval, 0.0, 1.0);
+ ctx->ViewportArray[idx].Far = CLAMP(farval, 0.0, 1.0);
+ ctx->NewState |= _NEW_VIEWPORT;
+}
+
+void
+_mesa_set_depth_range(struct gl_context *ctx, unsigned idx,
+ GLclampd nearval, GLclampd farval)
+{
+ set_depth_range_no_notify(ctx, idx, nearval, farval);
+
+ if (ctx->Driver.DepthRange)
+ ctx->Driver.DepthRange(ctx);
+}