101e04c3fSmrg/* 201e04c3fSmrg * Mesa 3-D graphics library 301e04c3fSmrg * 401e04c3fSmrg * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 501e04c3fSmrg * 601e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 701e04c3fSmrg * copy of this software and associated documentation files (the "Software"), 801e04c3fSmrg * to deal in the Software without restriction, including without limitation 901e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 1001e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the 1101e04c3fSmrg * Software is furnished to do so, subject to the following conditions: 1201e04c3fSmrg * 1301e04c3fSmrg * The above copyright notice and this permission notice shall be included 1401e04c3fSmrg * in all copies or substantial portions of the Software. 1501e04c3fSmrg * 1601e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 1701e04c3fSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1801e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1901e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 2001e04c3fSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 2101e04c3fSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 2201e04c3fSmrg * OTHER DEALINGS IN THE SOFTWARE. 2301e04c3fSmrg */ 2401e04c3fSmrg 2501e04c3fSmrg#include <stdbool.h> 2601e04c3fSmrg#include "glheader.h" 2701e04c3fSmrg#include "draw_validate.h" 2801e04c3fSmrg#include "arrayobj.h" 2901e04c3fSmrg#include "bufferobj.h" 3001e04c3fSmrg#include "context.h" 317ec681f3Smrg 3201e04c3fSmrg#include "mtypes.h" 3301e04c3fSmrg#include "pipelineobj.h" 3401e04c3fSmrg#include "enums.h" 3501e04c3fSmrg#include "state.h" 3601e04c3fSmrg#include "transformfeedback.h" 3701e04c3fSmrg#include "uniforms.h" 3801e04c3fSmrg#include "program/prog_print.h" 3901e04c3fSmrg 4001e04c3fSmrg 417ec681f3Smrg/** 427ec681f3Smrg * Compute the bitmask of allowed primitive types (ValidPrimMask) depending 437ec681f3Smrg * on shaders and current states. This is used by draw validation. 447ec681f3Smrg * 457ec681f3Smrg * If some combinations of shaders and states are invalid, ValidPrimMask is 467ec681f3Smrg * set to 0, which will always set GL_INVALID_OPERATION in draw calls 477ec681f3Smrg * except for invalid enums, which will set GL_INVALID_ENUM, minimizing 487ec681f3Smrg * the number of gl_context variables that have to be read by draw calls. 497ec681f3Smrg */ 507ec681f3Smrgvoid 517ec681f3Smrg_mesa_update_valid_to_render_state(struct gl_context *ctx) 5201e04c3fSmrg{ 537ec681f3Smrg struct gl_pipeline_object *shader = ctx->_Shader; 547ec681f3Smrg unsigned mask = ctx->SupportedPrimMask; 557ec681f3Smrg bool drawpix_valid = true; 567ec681f3Smrg 577ec681f3Smrg if (_mesa_is_no_error_enabled(ctx)) { 587ec681f3Smrg ctx->ValidPrimMask = mask; 597ec681f3Smrg ctx->ValidPrimMaskIndexed = mask; 607ec681f3Smrg ctx->DrawPixValid = drawpix_valid; 617ec681f3Smrg return; 627ec681f3Smrg } 637ec681f3Smrg 647ec681f3Smrg /* Start with an empty mask and set this to the trimmed mask at the end. */ 657ec681f3Smrg ctx->ValidPrimMask = 0; 667ec681f3Smrg ctx->ValidPrimMaskIndexed = 0; 677ec681f3Smrg ctx->DrawPixValid = false; 687ec681f3Smrg 697ec681f3Smrg /* The default error is GL_INVALID_OPERATION if mode is a valid enum. 707ec681f3Smrg * It can be overriden by following code if we should return a different 717ec681f3Smrg * error. 727ec681f3Smrg */ 737ec681f3Smrg ctx->DrawGLError = GL_INVALID_OPERATION; 747ec681f3Smrg 757ec681f3Smrg if (!ctx->DrawBuffer || 767ec681f3Smrg ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { 777ec681f3Smrg ctx->DrawGLError = GL_INVALID_FRAMEBUFFER_OPERATION; 787ec681f3Smrg return; 797ec681f3Smrg } 807ec681f3Smrg 817ec681f3Smrg /* A pipeline object is bound */ 827ec681f3Smrg if (shader->Name && !shader->Validated && 837ec681f3Smrg !_mesa_validate_program_pipeline(ctx, shader)) 847ec681f3Smrg return; 857ec681f3Smrg 867ec681f3Smrg /* If a program is active and SSO not in use, check if validation of 877ec681f3Smrg * samplers succeeded for the active program. */ 887ec681f3Smrg if (shader->ActiveProgram && shader != ctx->Pipeline.Current && 897ec681f3Smrg !_mesa_sampler_uniforms_are_valid(shader->ActiveProgram, NULL, 0)) 907ec681f3Smrg return; 917ec681f3Smrg 9201e04c3fSmrg /* The ARB_blend_func_extended spec's ERRORS section says: 9301e04c3fSmrg * 9401e04c3fSmrg * "The error INVALID_OPERATION is generated by Begin or any procedure 9501e04c3fSmrg * that implicitly calls Begin if any draw buffer has a blend function 9601e04c3fSmrg * requiring the second color input (SRC1_COLOR, ONE_MINUS_SRC1_COLOR, 9701e04c3fSmrg * SRC1_ALPHA or ONE_MINUS_SRC1_ALPHA), and a framebuffer is bound that 9801e04c3fSmrg * has more than the value of MAX_DUAL_SOURCE_DRAW_BUFFERS-1 active 9901e04c3fSmrg * color attachements." 10001e04c3fSmrg */ 1017ec681f3Smrg unsigned max_dual_source_buffers = ctx->Const.MaxDualSourceDrawBuffers; 1027ec681f3Smrg unsigned num_color_buffers = ctx->DrawBuffer->_NumColorDrawBuffers; 1037ec681f3Smrg 1047ec681f3Smrg if (num_color_buffers > max_dual_source_buffers && 1057ec681f3Smrg ctx->Color._BlendUsesDualSrc & 1067ec681f3Smrg BITFIELD_RANGE(max_dual_source_buffers, 1077ec681f3Smrg num_color_buffers - max_dual_source_buffers)) 1087ec681f3Smrg return; 10901e04c3fSmrg 1107ec681f3Smrg if (ctx->Color.BlendEnabled && 1117ec681f3Smrg ctx->Color._AdvancedBlendMode != BLEND_NONE) { 11201e04c3fSmrg /* The KHR_blend_equation_advanced spec says: 11301e04c3fSmrg * 11401e04c3fSmrg * "If any non-NONE draw buffer uses a blend equation found in table 11501e04c3fSmrg * X.1 or X.2, the error INVALID_OPERATION is generated by Begin or 11601e04c3fSmrg * any operation that implicitly calls Begin (such as DrawElements) 11701e04c3fSmrg * if: 11801e04c3fSmrg * 11901e04c3fSmrg * * the draw buffer for color output zero selects multiple color 12001e04c3fSmrg * buffers (e.g., FRONT_AND_BACK in the default framebuffer); or 12101e04c3fSmrg * 12201e04c3fSmrg * * the draw buffer for any other color output is not NONE." 12301e04c3fSmrg */ 1247ec681f3Smrg if (ctx->DrawBuffer->ColorDrawBuffer[0] == GL_FRONT_AND_BACK) 1257ec681f3Smrg return; 12601e04c3fSmrg 1277ec681f3Smrg for (unsigned i = 1; i < num_color_buffers; i++) { 1287ec681f3Smrg if (ctx->DrawBuffer->ColorDrawBuffer[i] != GL_NONE) 1297ec681f3Smrg return; 13001e04c3fSmrg } 13101e04c3fSmrg 13201e04c3fSmrg /* The KHR_blend_equation_advanced spec says: 13301e04c3fSmrg * 13401e04c3fSmrg * "Advanced blending equations require the use of a fragment shader 13501e04c3fSmrg * with a matching "blend_support" layout qualifier. If the current 13601e04c3fSmrg * blend equation is found in table X.1 or X.2, and the active 13701e04c3fSmrg * fragment shader does not include the layout qualifier matching 13801e04c3fSmrg * the blend equation or "blend_support_all_equations", the error 13901e04c3fSmrg * INVALID_OPERATION is generated [...]" 14001e04c3fSmrg */ 1417ec681f3Smrg const struct gl_program *prog = 1427ec681f3Smrg ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT]; 1437ec681f3Smrg const GLbitfield blend_support = !prog ? 0 : prog->info.fs.advanced_blend_modes; 14401e04c3fSmrg 1457ec681f3Smrg if ((blend_support & BITFIELD_BIT(ctx->Color._AdvancedBlendMode)) == 0) 1467ec681f3Smrg return; 14701e04c3fSmrg } 14801e04c3fSmrg 14901e04c3fSmrg if (ctx->API == API_OPENGL_COMPAT) { 1507ec681f3Smrg if (!shader->CurrentProgram[MESA_SHADER_FRAGMENT]) { 15101e04c3fSmrg if (ctx->FragmentProgram.Enabled && 1527ec681f3Smrg !_mesa_arb_fragment_program_enabled(ctx)) 1537ec681f3Smrg return; 15401e04c3fSmrg 15501e04c3fSmrg /* If drawing to integer-valued color buffers, there must be an 15601e04c3fSmrg * active fragment shader (GL_EXT_texture_integer). 15701e04c3fSmrg */ 1587ec681f3Smrg if (ctx->DrawBuffer->_IntegerBuffers) 1597ec681f3Smrg return; 16001e04c3fSmrg } 16101e04c3fSmrg } 16201e04c3fSmrg 1637ec681f3Smrg /* DrawPixels/CopyPixels/Bitmap is valid after this point. */ 1647ec681f3Smrg ctx->DrawPixValid = true; 16501e04c3fSmrg 16601e04c3fSmrg /* Section 11.2 (Tessellation) of the ES 3.2 spec says: 16701e04c3fSmrg * 16801e04c3fSmrg * "An INVALID_OPERATION error is generated by any command that 16901e04c3fSmrg * transfers vertices to the GL if the current program state has 17001e04c3fSmrg * one but not both of a tessellation control shader and tessellation 17101e04c3fSmrg * evaluation shader." 17201e04c3fSmrg * 17301e04c3fSmrg * The OpenGL spec argues that this is allowed because a tess ctrl shader 17401e04c3fSmrg * without a tess eval shader can be used with transform feedback. 17501e04c3fSmrg * However, glBeginTransformFeedback doesn't allow GL_PATCHES and 17601e04c3fSmrg * therefore doesn't allow tessellation. 17701e04c3fSmrg * 17801e04c3fSmrg * Further investigation showed that this is indeed a spec bug and 17901e04c3fSmrg * a tess ctrl shader without a tess eval shader shouldn't have been 18001e04c3fSmrg * allowed, because there is no API in GL 4.0 that can make use this 18101e04c3fSmrg * to produce something useful. 18201e04c3fSmrg * 18301e04c3fSmrg * Also, all vendors except one don't support a tess ctrl shader without 18401e04c3fSmrg * a tess eval shader anyway. 18501e04c3fSmrg */ 1867ec681f3Smrg if (shader->CurrentProgram[MESA_SHADER_TESS_CTRL] && 1877ec681f3Smrg !shader->CurrentProgram[MESA_SHADER_TESS_EVAL]) 1887ec681f3Smrg return; 18901e04c3fSmrg 19001e04c3fSmrg switch (ctx->API) { 19101e04c3fSmrg case API_OPENGLES2: 19201e04c3fSmrg /* Section 11.2 (Tessellation) of the ES 3.2 spec says: 19301e04c3fSmrg * 19401e04c3fSmrg * "An INVALID_OPERATION error is generated by any command that 19501e04c3fSmrg * transfers vertices to the GL if the current program state has 19601e04c3fSmrg * one but not both of a tessellation control shader and tessellation 19701e04c3fSmrg * evaluation shader." 19801e04c3fSmrg */ 19901e04c3fSmrg if (_mesa_is_gles3(ctx) && 2007ec681f3Smrg shader->CurrentProgram[MESA_SHADER_TESS_EVAL] && 2017ec681f3Smrg !shader->CurrentProgram[MESA_SHADER_TESS_CTRL]) 2027ec681f3Smrg return; 203a8bb7a65Smaya 204a8bb7a65Smaya /* From GL_EXT_color_buffer_float: 205a8bb7a65Smaya * 206a8bb7a65Smaya * "Blending applies only if the color buffer has a fixed-point or 207a8bb7a65Smaya * or floating-point format. If the color buffer has an integer 208a8bb7a65Smaya * format, proceed to the next operation. Furthermore, an 209a8bb7a65Smaya * INVALID_OPERATION error is generated by DrawArrays and the other 210a8bb7a65Smaya * drawing commands defined in section 2.8.3 (10.5 in ES 3.1) if 211a8bb7a65Smaya * blending is enabled (see below) and any draw buffer has 32-bit 212a8bb7a65Smaya * floating-point format components." 213a8bb7a65Smaya * 214a8bb7a65Smaya * However GL_EXT_float_blend removes this text. 215a8bb7a65Smaya */ 216a8bb7a65Smaya if (!ctx->Extensions.EXT_float_blend && 2177ec681f3Smrg (ctx->DrawBuffer->_FP32Buffers & ctx->Color.BlendEnabled)) 2187ec681f3Smrg return; 21901e04c3fSmrg break; 22001e04c3fSmrg 22101e04c3fSmrg case API_OPENGL_CORE: 22201e04c3fSmrg /* Section 10.4 (Drawing Commands Using Vertex Arrays) of the OpenGL 4.5 22301e04c3fSmrg * Core Profile spec says: 22401e04c3fSmrg * 22501e04c3fSmrg * "An INVALID_OPERATION error is generated if no vertex array 22601e04c3fSmrg * object is bound (see section 10.3.1)." 22701e04c3fSmrg */ 2287ec681f3Smrg if (ctx->Array.VAO == ctx->Array.DefaultVAO) 2297ec681f3Smrg return; 23001e04c3fSmrg break; 23101e04c3fSmrg 23201e04c3fSmrg case API_OPENGLES: 2337ec681f3Smrg break; 2347ec681f3Smrg 23501e04c3fSmrg case API_OPENGL_COMPAT: 2367ec681f3Smrg /* Check invalid ARB vertex programs. */ 2377ec681f3Smrg if (!shader->CurrentProgram[MESA_SHADER_VERTEX] && 2387ec681f3Smrg ctx->VertexProgram.Enabled && 2397ec681f3Smrg !_mesa_arb_vertex_program_enabled(ctx)) 2407ec681f3Smrg return; 24101e04c3fSmrg break; 24201e04c3fSmrg 24301e04c3fSmrg default: 2447ec681f3Smrg unreachable("Invalid API value in _mesa_update_valid_to_render_state"); 24501e04c3fSmrg } 24601e04c3fSmrg 2477ec681f3Smrg /* From the GL_NV_fill_rectangle spec: 2487ec681f3Smrg * 2497ec681f3Smrg * "An INVALID_OPERATION error is generated by Begin or any Draw command if 2507ec681f3Smrg * only one of the front and back polygon mode is FILL_RECTANGLE_NV." 25101e04c3fSmrg */ 2527ec681f3Smrg if ((ctx->Polygon.FrontMode == GL_FILL_RECTANGLE_NV) != 2537ec681f3Smrg (ctx->Polygon.BackMode == GL_FILL_RECTANGLE_NV)) 2547ec681f3Smrg return; 25501e04c3fSmrg 2567ec681f3Smrg /* From GL_INTEL_conservative_rasterization spec: 2577ec681f3Smrg * 2587ec681f3Smrg * The conservative rasterization option applies only to polygons with 2597ec681f3Smrg * PolygonMode state set to FILL. Draw requests for polygons with different 2607ec681f3Smrg * PolygonMode setting or for other primitive types (points/lines) generate 2617ec681f3Smrg * INVALID_OPERATION error. 2627ec681f3Smrg */ 2637ec681f3Smrg if (ctx->IntelConservativeRasterization) { 2647ec681f3Smrg if (ctx->Polygon.FrontMode != GL_FILL || 2657ec681f3Smrg ctx->Polygon.BackMode != GL_FILL) { 2667ec681f3Smrg return; 2677ec681f3Smrg } else { 2687ec681f3Smrg mask &= (1 << GL_TRIANGLES) | 2697ec681f3Smrg (1 << GL_TRIANGLE_STRIP) | 2707ec681f3Smrg (1 << GL_TRIANGLE_FAN) | 2717ec681f3Smrg (1 << GL_QUADS) | 2727ec681f3Smrg (1 << GL_QUAD_STRIP) | 2737ec681f3Smrg (1 << GL_POLYGON) | 2747ec681f3Smrg (1 << GL_TRIANGLES_ADJACENCY) | 2757ec681f3Smrg (1 << GL_TRIANGLE_STRIP_ADJACENCY); 2767ec681f3Smrg } 2777ec681f3Smrg } 27801e04c3fSmrg 2797ec681f3Smrg /* From the GL_EXT_transform_feedback spec: 2807ec681f3Smrg * 2817ec681f3Smrg * "The error INVALID_OPERATION is generated if Begin, or any command 2827ec681f3Smrg * that performs an explicit Begin, is called when: 2837ec681f3Smrg * 2847ec681f3Smrg * * a geometry shader is not active and <mode> does not match the 2857ec681f3Smrg * allowed begin modes for the current transform feedback state as 2867ec681f3Smrg * given by table X.1. 2877ec681f3Smrg * 2887ec681f3Smrg * * a geometry shader is active and the output primitive type of the 2897ec681f3Smrg * geometry shader does not match the allowed begin modes for the 2907ec681f3Smrg * current transform feedback state as given by table X.1. 2917ec681f3Smrg * 2927ec681f3Smrg */ 2937ec681f3Smrg if (_mesa_is_xfb_active_and_unpaused(ctx)) { 2947ec681f3Smrg if(shader->CurrentProgram[MESA_SHADER_GEOMETRY]) { 2957ec681f3Smrg switch (shader->CurrentProgram[MESA_SHADER_GEOMETRY]-> 2967ec681f3Smrg info.gs.output_primitive) { 2977ec681f3Smrg case GL_POINTS: 2987ec681f3Smrg if (ctx->TransformFeedback.Mode != GL_POINTS) 2997ec681f3Smrg mask = 0; 3007ec681f3Smrg break; 3017ec681f3Smrg case GL_LINE_STRIP: 3027ec681f3Smrg if (ctx->TransformFeedback.Mode != GL_LINES) 3037ec681f3Smrg mask = 0; 3047ec681f3Smrg break; 3057ec681f3Smrg case GL_TRIANGLE_STRIP: 3067ec681f3Smrg if (ctx->TransformFeedback.Mode != GL_TRIANGLES) 3077ec681f3Smrg mask = 0; 3087ec681f3Smrg break; 3097ec681f3Smrg default: 3107ec681f3Smrg mask = 0; 3117ec681f3Smrg } 3127ec681f3Smrg } 3137ec681f3Smrg else if (shader->CurrentProgram[MESA_SHADER_TESS_EVAL]) { 3147ec681f3Smrg struct gl_program *tes = 3157ec681f3Smrg shader->CurrentProgram[MESA_SHADER_TESS_EVAL]; 3167ec681f3Smrg if (tes->info.tess.point_mode) { 3177ec681f3Smrg if (ctx->TransformFeedback.Mode != GL_POINTS) 3187ec681f3Smrg mask = 0; 3197ec681f3Smrg } else if (tes->info.tess.primitive_mode == GL_ISOLINES) { 3207ec681f3Smrg if (ctx->TransformFeedback.Mode != GL_LINES) 3217ec681f3Smrg mask = 0; 3227ec681f3Smrg } else { 3237ec681f3Smrg if (ctx->TransformFeedback.Mode != GL_TRIANGLES) 3247ec681f3Smrg mask = 0; 3257ec681f3Smrg } 3267ec681f3Smrg } 3277ec681f3Smrg else { 3287ec681f3Smrg switch (ctx->TransformFeedback.Mode) { 3297ec681f3Smrg case GL_POINTS: 3307ec681f3Smrg mask &= 1 << GL_POINTS; 3317ec681f3Smrg break; 3327ec681f3Smrg case GL_LINES: 3337ec681f3Smrg mask &= (1 << GL_LINES) | 3347ec681f3Smrg (1 << GL_LINE_LOOP) | 3357ec681f3Smrg (1 << GL_LINE_STRIP); 3367ec681f3Smrg break; 3377ec681f3Smrg case GL_TRIANGLES: 3387ec681f3Smrg /* TODO: This doesn't look right, but it matches the original code. */ 3397ec681f3Smrg mask &= ~((1 << GL_POINTS) | 3407ec681f3Smrg (1 << GL_LINES) | 3417ec681f3Smrg (1 << GL_LINE_LOOP) | 3427ec681f3Smrg (1 << GL_LINE_STRIP)); 3437ec681f3Smrg break; 3447ec681f3Smrg } 3457ec681f3Smrg } 34601e04c3fSmrg 3477ec681f3Smrg if (!mask) 3487ec681f3Smrg return; 34901e04c3fSmrg } 35001e04c3fSmrg 35101e04c3fSmrg /* From the OpenGL 4.5 specification, section 11.3.1: 35201e04c3fSmrg * 35301e04c3fSmrg * The error INVALID_OPERATION is generated if Begin, or any command that 35401e04c3fSmrg * implicitly calls Begin, is called when a geometry shader is active and: 35501e04c3fSmrg * 35601e04c3fSmrg * * the input primitive type of the current geometry shader is 35701e04c3fSmrg * POINTS and <mode> is not POINTS, 35801e04c3fSmrg * 35901e04c3fSmrg * * the input primitive type of the current geometry shader is 36001e04c3fSmrg * LINES and <mode> is not LINES, LINE_STRIP, or LINE_LOOP, 36101e04c3fSmrg * 36201e04c3fSmrg * * the input primitive type of the current geometry shader is 36301e04c3fSmrg * TRIANGLES and <mode> is not TRIANGLES, TRIANGLE_STRIP or 36401e04c3fSmrg * TRIANGLE_FAN, 36501e04c3fSmrg * 36601e04c3fSmrg * * the input primitive type of the current geometry shader is 36701e04c3fSmrg * LINES_ADJACENCY_ARB and <mode> is not LINES_ADJACENCY_ARB or 36801e04c3fSmrg * LINE_STRIP_ADJACENCY_ARB, or 36901e04c3fSmrg * 37001e04c3fSmrg * * the input primitive type of the current geometry shader is 37101e04c3fSmrg * TRIANGLES_ADJACENCY_ARB and <mode> is not 37201e04c3fSmrg * TRIANGLES_ADJACENCY_ARB or TRIANGLE_STRIP_ADJACENCY_ARB. 37301e04c3fSmrg * 37401e04c3fSmrg * The GL spec doesn't mention any interaction with tessellation, which 37501e04c3fSmrg * is clearly a spec bug. The same rule should apply, but instead of 37601e04c3fSmrg * the draw primitive mode, the tessellation evaluation shader primitive 37701e04c3fSmrg * mode should be used for the checking. 37801e04c3fSmrg */ 3797ec681f3Smrg if (shader->CurrentProgram[MESA_SHADER_GEOMETRY]) { 38001e04c3fSmrg const GLenum geom_mode = 3817ec681f3Smrg shader->CurrentProgram[MESA_SHADER_GEOMETRY]-> 38201e04c3fSmrg info.gs.input_primitive; 38301e04c3fSmrg struct gl_program *tes = 3847ec681f3Smrg shader->CurrentProgram[MESA_SHADER_TESS_EVAL]; 38501e04c3fSmrg 38601e04c3fSmrg if (tes) { 3877ec681f3Smrg bool valid; 3887ec681f3Smrg 38901e04c3fSmrg if (tes->info.tess.point_mode) 3907ec681f3Smrg valid = geom_mode == GL_POINTS; 39101e04c3fSmrg else if (tes->info.tess.primitive_mode == GL_ISOLINES) 3927ec681f3Smrg valid = geom_mode == GL_LINES; 39301e04c3fSmrg else 39401e04c3fSmrg /* the GL_QUADS mode generates triangles too */ 3957ec681f3Smrg valid = geom_mode == GL_TRIANGLES; 39601e04c3fSmrg 3977ec681f3Smrg /* TES and GS use incompatible primitive types. Discard all draws. */ 3987ec681f3Smrg if (!valid) 3997ec681f3Smrg return; 4007ec681f3Smrg } else { 4017ec681f3Smrg switch (geom_mode) { 4027ec681f3Smrg case GL_POINTS: 4037ec681f3Smrg mask &= 1 << GL_POINTS; 4047ec681f3Smrg break; 4057ec681f3Smrg case GL_LINES: 4067ec681f3Smrg mask &= (1 << GL_LINES) | 4077ec681f3Smrg (1 << GL_LINE_LOOP) | 4087ec681f3Smrg (1 << GL_LINE_STRIP); 4097ec681f3Smrg break; 4107ec681f3Smrg case GL_TRIANGLES: 4117ec681f3Smrg mask &= (1 << GL_TRIANGLES) | 4127ec681f3Smrg (1 << GL_TRIANGLE_STRIP) | 4137ec681f3Smrg (1 << GL_TRIANGLE_FAN); 4147ec681f3Smrg break; 4157ec681f3Smrg case GL_LINES_ADJACENCY: 4167ec681f3Smrg mask &= (1 << GL_LINES_ADJACENCY) | 4177ec681f3Smrg (1 << GL_LINE_STRIP_ADJACENCY); 4187ec681f3Smrg break; 4197ec681f3Smrg case GL_TRIANGLES_ADJACENCY: 4207ec681f3Smrg mask &= (1 << GL_TRIANGLES_ADJACENCY) | 4217ec681f3Smrg (1 << GL_TRIANGLE_STRIP_ADJACENCY); 4227ec681f3Smrg break; 4237ec681f3Smrg } 42401e04c3fSmrg } 42501e04c3fSmrg } 42601e04c3fSmrg 42701e04c3fSmrg /* From the OpenGL 4.0 (Core Profile) spec (section 2.12): 42801e04c3fSmrg * 42901e04c3fSmrg * "Tessellation operates only on patch primitives. If tessellation is 43001e04c3fSmrg * active, any command that transfers vertices to the GL will 43101e04c3fSmrg * generate an INVALID_OPERATION error if the primitive mode is not 43201e04c3fSmrg * PATCHES. 43301e04c3fSmrg * Patch primitives are not supported by pipeline stages below the 43401e04c3fSmrg * tessellation evaluation shader. If there is no active program 43501e04c3fSmrg * object or the active program object does not contain a tessellation 43601e04c3fSmrg * evaluation shader, the error INVALID_OPERATION is generated by any 43701e04c3fSmrg * command that transfers vertices to the GL if the primitive mode is 43801e04c3fSmrg * PATCHES." 43901e04c3fSmrg * 44001e04c3fSmrg */ 4417ec681f3Smrg if (shader->CurrentProgram[MESA_SHADER_TESS_EVAL] || 4427ec681f3Smrg shader->CurrentProgram[MESA_SHADER_TESS_CTRL]) { 4437ec681f3Smrg mask &= 1 << GL_PATCHES; 44401e04c3fSmrg } 44501e04c3fSmrg else { 4467ec681f3Smrg mask &= ~(1 << GL_PATCHES); 44701e04c3fSmrg } 44801e04c3fSmrg 4497ec681f3Smrg#ifdef DEBUG 4507ec681f3Smrg if (shader->Flags & GLSL_LOG) { 4517ec681f3Smrg struct gl_program **prog = shader->CurrentProgram; 45201e04c3fSmrg 4537ec681f3Smrg for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 4547ec681f3Smrg if (prog[i] == NULL || prog[i]->_Used) 4557ec681f3Smrg continue; 45601e04c3fSmrg 4577ec681f3Smrg /* This is the first time this shader is being used. 4587ec681f3Smrg * Append shader's constants/uniforms to log file. 4597ec681f3Smrg * 4607ec681f3Smrg * Only log data for the program target that matches the shader 4617ec681f3Smrg * target. It's possible to have a program bound to the vertex 4627ec681f3Smrg * shader target that also supplied a fragment shader. If that 4637ec681f3Smrg * program isn't also bound to the fragment shader target we don't 4647ec681f3Smrg * want to log its fragment data. 4657ec681f3Smrg */ 4667ec681f3Smrg _mesa_append_uniforms_to_file(prog[i]); 46701e04c3fSmrg } 4687ec681f3Smrg 4697ec681f3Smrg for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 4707ec681f3Smrg if (prog[i] != NULL) 4717ec681f3Smrg prog[i]->_Used = GL_TRUE; 47201e04c3fSmrg } 47301e04c3fSmrg } 4747ec681f3Smrg#endif 47501e04c3fSmrg 4767ec681f3Smrg /* Non-indexed draws are valid after this point. */ 4777ec681f3Smrg ctx->ValidPrimMask = mask; 47801e04c3fSmrg 47901e04c3fSmrg /* Section 2.14.2 (Transform Feedback Primitive Capture) of the OpenGL ES 48001e04c3fSmrg * 3.1 spec says: 48101e04c3fSmrg * 48201e04c3fSmrg * The error INVALID_OPERATION is also generated by DrawElements, 48301e04c3fSmrg * DrawElementsInstanced, and DrawRangeElements while transform feedback 48401e04c3fSmrg * is active and not paused, regardless of mode. 48501e04c3fSmrg * 48601e04c3fSmrg * The OES_geometry_shader_spec says: 48701e04c3fSmrg * 48801e04c3fSmrg * Issues: 48901e04c3fSmrg * 49001e04c3fSmrg * ... 49101e04c3fSmrg * 49201e04c3fSmrg * (13) Does this extension change how transform feedback operates 49301e04c3fSmrg * compared to unextended OpenGL ES 3.0 or 3.1? 49401e04c3fSmrg * 49501e04c3fSmrg * RESOLVED: Yes... Since we no longer require being able to predict how 49601e04c3fSmrg * much geometry will be generated, we also lift the restriction that 49701e04c3fSmrg * only DrawArray* commands are supported and also support the 49801e04c3fSmrg * DrawElements* commands for transform feedback. 49901e04c3fSmrg * 50001e04c3fSmrg * This should also be reflected in the body of the spec, but that appears 50101e04c3fSmrg * to have been overlooked. The body of the spec only explicitly allows 50201e04c3fSmrg * the indirect versions. 50301e04c3fSmrg */ 50401e04c3fSmrg if (_mesa_is_gles3(ctx) && 50501e04c3fSmrg !_mesa_has_OES_geometry_shader(ctx) && 5067ec681f3Smrg _mesa_is_xfb_active_and_unpaused(ctx)) 5077ec681f3Smrg return; 50801e04c3fSmrg 5097ec681f3Smrg ctx->ValidPrimMaskIndexed = mask; 51001e04c3fSmrg} 511