From d68c1e2ac28bbf0ac6259e9619fb73958fc598b8 Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Thu, 9 Jun 2016 22:50:43 -0400 Subject: [PATCH] mesa: add GL_EXT_window_rectangles state storage/retrieval functionality Signed-off-by: Ilia Mirkin Reviewed-by: Brian Paul --- src/mesa/main/attrib.c | 7 +++++ src/mesa/main/config.h | 7 +++-- src/mesa/main/dlist.c | 38 ++++++++++++++++++++++++- src/mesa/main/extensions_table.h | 1 + src/mesa/main/get.c | 12 ++++++++ src/mesa/main/get_hash_params.py | 5 ++++ src/mesa/main/mtypes.h | 5 ++++ src/mesa/main/scissor.c | 48 ++++++++++++++++++++++++++++++++ 8 files changed, 120 insertions(+), 3 deletions(-) diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c index 52a8ba63363..f859191f69c 100644 --- a/src/mesa/main/attrib.c +++ b/src/mesa/main/attrib.c @@ -1305,6 +1305,13 @@ _mesa_PopAttrib(void) _mesa_set_enablei(ctx, GL_SCISSOR_TEST, i, (scissor->EnableFlags >> i) & 1); } + if (ctx->Extensions.EXT_window_rectangles) { + STATIC_ASSERT(sizeof(struct gl_scissor_rect) == + 4 * sizeof(GLint)); + _mesa_WindowRectanglesEXT( + scissor->WindowRectMode, scissor->NumWindowRects, + (const GLint *)scissor->WindowRects); + } } break; case GL_STENCIL_BUFFER_BIT: diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h index bc5e56923b8..0d0ee90e678 100644 --- a/src/mesa/main/config.h +++ b/src/mesa/main/config.h @@ -132,10 +132,13 @@ */ #define MAX_TEXTURE_UNITS ((MAX_TEXTURE_COORD_UNITS > MAX_TEXTURE_IMAGE_UNITS) ? MAX_TEXTURE_COORD_UNITS : MAX_TEXTURE_IMAGE_UNITS) -/** Maximun number of viewports supported with ARB_viewport_array */ +/** Maximum number of viewports supported with ARB_viewport_array */ #define MAX_VIEWPORTS 16 -/** Maxmimum size for CVA. May be overridden by the drivers. */ +/** Maximum number of window rectangles supported with EXT_window_rectangles */ +#define MAX_WINDOW_RECTANGLES 8 + +/** Maximum size for CVA. May be overridden by the drivers. */ #define MAX_ARRAY_LOCK_SIZE 3000 /** Subpixel precision for antialiasing, window coordinate snapping */ diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c index 43e2ffb3a78..4e4b1385c0b 100644 --- a/src/mesa/main/dlist.c +++ b/src/mesa/main/dlist.c @@ -485,6 +485,9 @@ typedef enum /* EXT_polygon_offset_clamp */ OPCODE_POLYGON_OFFSET_CLAMP, + /* EXT_window_rectangles */ + OPCODE_WINDOW_RECTANGLES, + /* The following three are meta instructions */ OPCODE_ERROR, /* raise compiled-in error */ OPCODE_CONTINUE, @@ -1090,7 +1093,10 @@ _mesa_delete_list(struct gl_context *ctx, struct gl_display_list *dlist) free(get_pointer(&n[3])); n += InstSize[n[0].opcode]; break; - + case OPCODE_WINDOW_RECTANGLES: + free(get_pointer(&n[3])); + n += InstSize[n[0].opcode]; + break; case OPCODE_CONTINUE: n = (Node *) get_pointer(&n[1]); free(block); @@ -7922,6 +7928,27 @@ save_UniformBlockBinding(GLuint prog, GLuint index, GLuint binding) } } +/** GL_EXT_window_rectangles */ +static void GLAPIENTRY +save_WindowRectanglesEXT(GLenum mode, GLsizei count, const GLint *box) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = alloc_instruction(ctx, OPCODE_WINDOW_RECTANGLES, 2 + POINTER_DWORDS); + if (n) { + GLint *box_copy = NULL; + + if (count > 0) + box_copy = memdup(box, sizeof(GLint) * 4 * count); + n[1].e = mode; + n[2].si = count; + save_pointer(&n[3], box_copy); + } + if (ctx->ExecuteFlag) { + CALL_WindowRectanglesEXT(ctx->Exec, (mode, count, box)); + } +} /** * Save an error-generating command into display list. @@ -9122,6 +9149,12 @@ execute_list(struct gl_context *ctx, GLuint list) CALL_UniformBlockBinding(ctx->Exec, (n[1].ui, n[2].ui, n[3].ui)); break; + /* GL_EXT_window_rectangles */ + case OPCODE_WINDOW_RECTANGLES: + CALL_WindowRectanglesEXT( + ctx->Exec, (n[1].e, n[2].si, get_pointer(&n[3]))); + break; + case OPCODE_CONTINUE: n = (Node *) get_pointer(&n[1]); break; @@ -10018,6 +10051,9 @@ _mesa_initialize_save_table(const struct gl_context *ctx) /* GL_EXT_polygon_offset_clamp */ SET_PolygonOffsetClampEXT(table, save_PolygonOffsetClampEXT); + + /* GL_EXT_window_rectangles */ + SET_WindowRectanglesEXT(table, save_WindowRectanglesEXT); } diff --git a/src/mesa/main/extensions_table.h b/src/mesa/main/extensions_table.h index ea8eb306f59..ad3bffc068a 100644 --- a/src/mesa/main/extensions_table.h +++ b/src/mesa/main/extensions_table.h @@ -267,6 +267,7 @@ EXT(EXT_transform_feedback , EXT_transform_feedback EXT(EXT_unpack_subimage , dummy_true , x , x , x , ES2, 2011) EXT(EXT_vertex_array , dummy_true , GLL, x , x , x , 1995) EXT(EXT_vertex_array_bgra , EXT_vertex_array_bgra , GLL, GLC, x , x , 2008) +EXT(EXT_window_rectangles , EXT_window_rectangles , GLL, GLC, x , 30, 2016) EXT(GREMEDY_string_marker , GREMEDY_string_marker , GLL, GLC, x , x , 2007) diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c index 6ffa99ca01e..8cb0cc713e3 100644 --- a/src/mesa/main/get.c +++ b/src/mesa/main/get.c @@ -464,6 +464,7 @@ EXTRA_EXT(ARB_indirect_parameters); EXTRA_EXT(ATI_meminfo); EXTRA_EXT(NVX_gpu_memory_info); EXTRA_EXT(ARB_cull_distance); +EXTRA_EXT(EXT_window_rectangles); static const int extra_ARB_color_buffer_float_or_glcore[] = { @@ -1944,6 +1945,17 @@ find_value_indexed(const char *func, GLenum pname, GLuint index, union value *v) v->value_int_4[3] = ctx->Scissor.ScissorArray[index].Height; return TYPE_INT_4; + case GL_WINDOW_RECTANGLE_EXT: + if (!ctx->Extensions.EXT_window_rectangles) + goto invalid_enum; + if (index >= ctx->Const.MaxWindowRectangles) + goto invalid_value; + v->value_int_4[0] = ctx->Scissor.WindowRects[index].X; + v->value_int_4[1] = ctx->Scissor.WindowRects[index].Y; + v->value_int_4[2] = ctx->Scissor.WindowRects[index].Width; + v->value_int_4[3] = ctx->Scissor.WindowRects[index].Height; + return TYPE_INT_4; + case GL_VIEWPORT: if (index >= ctx->Const.MaxViewports) goto invalid_value; diff --git a/src/mesa/main/get_hash_params.py b/src/mesa/main/get_hash_params.py index bfcbfd687db..0672b0718e6 100644 --- a/src/mesa/main/get_hash_params.py +++ b/src/mesa/main/get_hash_params.py @@ -416,6 +416,11 @@ descriptor=[ [ "MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS", "CONTEXT_INT(Const.MaxTransformFeedbackInterleavedComponents), extra_EXT_transform_feedback" ], [ "MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS", "CONTEXT_INT(Const.MaxTransformFeedbackBuffers), extra_EXT_transform_feedback" ], [ "MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS", "CONTEXT_INT(Const.MaxTransformFeedbackSeparateComponents), extra_EXT_transform_feedback" ], + +# GL_EXT_window_rectangles + [ "MAX_WINDOW_RECTANGLES_EXT", "CONTEXT_INT(Const.MaxWindowRectangles), extra_EXT_window_rectangles" ], + [ "NUM_WINDOW_RECTANGLES_EXT", "CONTEXT_INT(Scissor.NumWindowRects), extra_EXT_window_rectangles" ], + [ "WINDOW_RECTANGLE_MODE_EXT", "CONTEXT_ENUM(Scissor.WindowRectMode), extra_EXT_window_rectangles" ], ]}, { "apis": ["GLES", "GLES2"], "params": [ diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 87e3c0cbf36..7f03c040c40 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -794,6 +794,9 @@ struct gl_scissor_attrib { GLbitfield EnableFlags; /**< Scissor test enabled? */ struct gl_scissor_rect ScissorArray[MAX_VIEWPORTS]; + GLint NumWindowRects; /**< Count of enabled window rectangles */ + GLenum WindowRectMode; /**< Whether to include or exclude the rects */ + struct gl_scissor_rect WindowRects[MAX_WINDOW_RECTANGLES]; }; @@ -3447,6 +3450,7 @@ struct gl_constants GLfloat Min; GLfloat Max; } ViewportBounds; /**< GL_ARB_viewport_array */ + GLuint MaxWindowRectangles; /**< GL_EXT_window_rectangles */ struct gl_program_constants Program[MESA_SHADER_STAGES]; GLuint MaxProgramMatrices; @@ -3916,6 +3920,7 @@ struct gl_extensions GLboolean EXT_transform_feedback; GLboolean EXT_timer_query; GLboolean EXT_vertex_array_bgra; + GLboolean EXT_window_rectangles; GLboolean OES_copy_image; GLboolean OES_sample_variables; GLboolean OES_shader_io_blocks; diff --git a/src/mesa/main/scissor.c b/src/mesa/main/scissor.c index 2b568e4926b..631ea4d3205 100644 --- a/src/mesa/main/scissor.c +++ b/src/mesa/main/scissor.c @@ -25,6 +25,7 @@ #include "main/glheader.h" #include "main/context.h" +#include "main/enums.h" #include "main/mtypes.h" #include "main/scissor.h" @@ -213,7 +214,53 @@ _mesa_ScissorIndexedv(GLuint index, const GLint *v) void GLAPIENTRY _mesa_WindowRectanglesEXT(GLenum mode, GLsizei count, const GLint *box) { + int i; + struct gl_scissor_rect newval[MAX_WINDOW_RECTANGLES]; + GET_CURRENT_CONTEXT(ctx); + + if (MESA_VERBOSE & VERBOSE_API) + _mesa_debug(ctx, "glWindowRectanglesEXT(%s, %d, %p)\n", + _mesa_enum_to_string(mode), count, box); + + if (mode != GL_INCLUSIVE_EXT && mode != GL_EXCLUSIVE_EXT) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glWindowRectanglesEXT(invalid mode 0x%x)", mode); + return; + } + + if (count < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glWindowRectanglesEXT(count < 0)"); + return; + } + + if (count > ctx->Const.MaxWindowRectangles) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glWindowRectanglesEXT(count >= MaxWindowRectangles (%d)", + ctx->Const.MaxWindowRectangles); + return; + } + + for (i = 0; i < count; i++) { + if (box[2] < 0 || box[3] < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glWindowRectanglesEXT(box %d: w < 0 || h < 0)", i); + return; + } + newval[i].X = box[0]; + newval[i].Y = box[1]; + newval[i].Width = box[2]; + newval[i].Height = box[3]; + box += 4; + } + + FLUSH_VERTICES(ctx, _NEW_SCISSOR); + memcpy(ctx->Scissor.WindowRects, newval, + sizeof(struct gl_scissor_rect) * count); + ctx->Scissor.NumWindowRects = count; + ctx->Scissor.WindowRectMode = mode; + if (ctx->Driver.Scissor) + ctx->Driver.Scissor(ctx); } @@ -228,6 +275,7 @@ _mesa_init_scissor(struct gl_context *ctx) /* Scissor group */ ctx->Scissor.EnableFlags = 0; + ctx->Scissor.WindowRectMode = GL_EXCLUSIVE_EXT; /* Note: ctx->Const.MaxViewports may not have been set by the driver yet, * so just initialize all of them. -- 2.30.2