void vg_tess_clerp_approx(float *x, float *y, float x0, float y0, float x1, float y1, float t) { float c = (x0 * x1) + (y0 * y1), s; t = t * t; /* because cos looks like a quadratic around x = 0 (ie this approximation is better when the angle is smaller) */ c = (1.0f - t) + (t * c); s = sqrt_(_maxf(1.0f - (c * c), 0.0f)); /* 1 - c^2 should be >= 0, but we might end up slightly less than 0 due to fp lameness... */ if ((x0 * y1) < (y0 * x1)) { s = -s; } *x = (x0 * c) - (y0 * s); *y = (y0 * c) + (x0 * s); }
/** * Query driver to get implementation limits. * Note that we have to limit/clamp against Mesa's internal limits too. */ void st_init_limits(struct st_context *st) { struct pipe_screen *screen = st->pipe->screen; struct gl_constants *c = &st->ctx->Const; c->MaxTextureLevels = _min(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS), MAX_TEXTURE_LEVELS); c->Max3DTextureLevels = _min(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_3D_LEVELS), MAX_3D_TEXTURE_LEVELS); c->MaxCubeTextureLevels = _min(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS), MAX_CUBE_TEXTURE_LEVELS); c->MaxTextureRectSize = _min(1 << (c->MaxTextureLevels - 1), MAX_TEXTURE_RECT_SIZE); c->MaxTextureImageUnits = _min(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS), MAX_TEXTURE_IMAGE_UNITS); c->MaxVertexTextureImageUnits = _min(screen->get_param(screen, PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS), MAX_VERTEX_TEXTURE_IMAGE_UNITS); c->MaxTextureCoordUnits = _min(c->MaxTextureImageUnits, MAX_TEXTURE_COORD_UNITS); c->MaxTextureUnits = _min(c->MaxTextureImageUnits, c->MaxTextureCoordUnits); c->MaxDrawBuffers = _clamp(screen->get_param(screen, PIPE_CAP_MAX_RENDER_TARGETS), 1, MAX_DRAW_BUFFERS); c->MaxLineWidth = _maxf(1.0f, screen->get_paramf(screen, PIPE_CAP_MAX_LINE_WIDTH)); c->MaxLineWidthAA = _maxf(1.0f, screen->get_paramf(screen, PIPE_CAP_MAX_LINE_WIDTH_AA)); c->MaxPointSize = _maxf(1.0f, screen->get_paramf(screen, PIPE_CAP_MAX_POINT_WIDTH)); c->MaxPointSizeAA = _maxf(1.0f, screen->get_paramf(screen, PIPE_CAP_MAX_POINT_WIDTH_AA)); c->MaxTextureMaxAnisotropy = _maxf(2.0f, screen->get_paramf(screen, PIPE_CAP_MAX_TEXTURE_ANISOTROPY)); c->MaxTextureLodBias = screen->get_paramf(screen, PIPE_CAP_MAX_TEXTURE_LOD_BIAS); c->MaxDrawBuffers = CLAMP(screen->get_param(screen, PIPE_CAP_MAX_RENDER_TARGETS), 1, MAX_DRAW_BUFFERS); /* Is TGSI_OPCODE_CONT supported? */ /* XXX separate query for early function return? */ st->ctx->Shader.EmitContReturn = screen->get_param(screen, PIPE_CAP_TGSI_CONT_SUPPORTED); }
/** * Query driver to get implementation limits. * Note that we have to limit/clamp against Mesa's internal limits too. */ void st_init_limits(struct st_context *st) { struct pipe_screen *screen = st->pipe->screen; struct gl_constants *c = &st->ctx->Const; unsigned sh; boolean can_ubo = TRUE; c->MaxTextureLevels = _min(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS), MAX_TEXTURE_LEVELS); c->Max3DTextureLevels = _min(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_3D_LEVELS), MAX_3D_TEXTURE_LEVELS); c->MaxCubeTextureLevels = _min(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS), MAX_CUBE_TEXTURE_LEVELS); c->MaxTextureRectSize = _min(1 << (c->MaxTextureLevels - 1), MAX_TEXTURE_RECT_SIZE); c->MaxArrayTextureLayers = screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS); /* Define max viewport size and max renderbuffer size in terms of * max texture size (note: max tex RECT size = max tex 2D size). * If this isn't true for some hardware we'll need new PIPE_CAP_ queries. */ c->MaxViewportWidth = c->MaxViewportHeight = c->MaxRenderbufferSize = c->MaxTextureRectSize; c->MaxDrawBuffers = c->MaxColorAttachments = _clamp(screen->get_param(screen, PIPE_CAP_MAX_RENDER_TARGETS), 1, MAX_DRAW_BUFFERS); c->MaxDualSourceDrawBuffers = _clamp(screen->get_param(screen, PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS), 0, MAX_DRAW_BUFFERS); c->MaxLineWidth = _maxf(1.0f, screen->get_paramf(screen, PIPE_CAPF_MAX_LINE_WIDTH)); c->MaxLineWidthAA = _maxf(1.0f, screen->get_paramf(screen, PIPE_CAPF_MAX_LINE_WIDTH_AA)); c->MaxPointSize = _maxf(1.0f, screen->get_paramf(screen, PIPE_CAPF_MAX_POINT_WIDTH)); c->MaxPointSizeAA = _maxf(1.0f, screen->get_paramf(screen, PIPE_CAPF_MAX_POINT_WIDTH_AA)); /* called after _mesa_create_context/_mesa_init_point, fix default user * settable max point size up */ st->ctx->Point.MaxSize = MAX2(c->MaxPointSize, c->MaxPointSizeAA); /* these are not queryable. Note that GL basically mandates a 1.0 minimum * for non-aa sizes, but we can go down to 0.0 for aa points. */ c->MinPointSize = 1.0f; c->MinPointSizeAA = 0.0f; c->MaxTextureMaxAnisotropy = _maxf(2.0f, screen->get_paramf(screen, PIPE_CAPF_MAX_TEXTURE_ANISOTROPY)); c->MaxTextureLodBias = screen->get_paramf(screen, PIPE_CAPF_MAX_TEXTURE_LOD_BIAS); c->QuadsFollowProvokingVertexConvention = screen->get_param( screen, PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION); c->MaxUniformBlockSize = screen->get_shader_param(screen, PIPE_SHADER_FRAGMENT, PIPE_SHADER_CAP_MAX_CONSTS) * 16; if (c->MaxUniformBlockSize < 16384) { can_ubo = FALSE; } for (sh = 0; sh < PIPE_SHADER_TYPES; ++sh) { struct gl_shader_compiler_options *options; struct gl_program_constants *pc; switch (sh) { case PIPE_SHADER_FRAGMENT: pc = &c->Program[MESA_SHADER_FRAGMENT]; options = &st->ctx->ShaderCompilerOptions[MESA_SHADER_FRAGMENT]; break; case PIPE_SHADER_VERTEX: pc = &c->Program[MESA_SHADER_VERTEX]; options = &st->ctx->ShaderCompilerOptions[MESA_SHADER_VERTEX]; break; case PIPE_SHADER_GEOMETRY: pc = &c->Program[MESA_SHADER_GEOMETRY]; options = &st->ctx->ShaderCompilerOptions[MESA_SHADER_GEOMETRY]; break; default: /* compute shader, etc. */ continue; } pc->MaxTextureImageUnits = _min(screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS), MAX_TEXTURE_IMAGE_UNITS); pc->MaxInstructions = pc->MaxNativeInstructions = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_INSTRUCTIONS); pc->MaxAluInstructions = pc->MaxNativeAluInstructions = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS); pc->MaxTexInstructions = pc->MaxNativeTexInstructions = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS); pc->MaxTexIndirections = pc->MaxNativeTexIndirections = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS); pc->MaxAttribs = pc->MaxNativeAttribs = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_INPUTS); pc->MaxTemps = pc->MaxNativeTemps = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_TEMPS); pc->MaxAddressRegs = pc->MaxNativeAddressRegs = _min(screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_ADDRS), MAX_PROGRAM_ADDRESS_REGS); pc->MaxParameters = pc->MaxNativeParameters = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_CONSTS); pc->MaxUniformComponents = 4 * MIN2(pc->MaxNativeParameters, MAX_UNIFORMS); pc->MaxUniformBlocks = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_CONST_BUFFERS); if (pc->MaxUniformBlocks) pc->MaxUniformBlocks -= 1; /* The first one is for ordinary uniforms. */ pc->MaxUniformBlocks = _min(pc->MaxUniformBlocks, MAX_UNIFORM_BUFFERS); pc->MaxCombinedUniformComponents = (pc->MaxUniformComponents + c->MaxUniformBlockSize / 4 * pc->MaxUniformBlocks); /* Gallium doesn't really care about local vs. env parameters so use the * same limits. */ pc->MaxLocalParams = MIN2(pc->MaxParameters, MAX_PROGRAM_LOCAL_PARAMS); pc->MaxEnvParams = MIN2(pc->MaxParameters, MAX_PROGRAM_ENV_PARAMS); options->EmitNoNoise = TRUE; /* TODO: make these more fine-grained if anyone needs it */ options->MaxIfDepth = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH); options->EmitNoLoops = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH); options->EmitNoFunctions = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_SUBROUTINES); options->EmitNoMainReturn = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_SUBROUTINES); options->EmitNoCont = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED); options->EmitNoIndirectInput = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR); options->EmitNoIndirectOutput = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR); options->EmitNoIndirectTemp = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR); options->EmitNoIndirectUniform = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_INDIRECT_CONST_ADDR); if (pc->MaxNativeInstructions && (options->EmitNoIndirectUniform || pc->MaxUniformBlocks < 12)) { can_ubo = FALSE; } if (options->EmitNoLoops) options->MaxUnrollIterations = MIN2(screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_INSTRUCTIONS), 65536); else options->MaxUnrollIterations = 255; /* SM3 limit */ options->LowerClipDistance = true; } c->MaxCombinedTextureImageUnits = _min(c->Program[MESA_SHADER_VERTEX].MaxTextureImageUnits + c->Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits + c->Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits, MAX_COMBINED_TEXTURE_IMAGE_UNITS); /* This depends on program constants. */ c->MaxTextureCoordUnits = _min(c->Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits, MAX_TEXTURE_COORD_UNITS); c->MaxTextureUnits = _min(c->Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits, c->MaxTextureCoordUnits); c->Program[MESA_SHADER_VERTEX].MaxAttribs = MIN2(c->Program[MESA_SHADER_VERTEX].MaxAttribs, 16); /* PIPE_SHADER_CAP_MAX_INPUTS for the FS specifies the maximum number * of inputs. It's always 2 colors + N generic inputs. */ c->MaxVarying = screen->get_shader_param(screen, PIPE_SHADER_FRAGMENT, PIPE_SHADER_CAP_MAX_INPUTS); c->MaxVarying = MIN2(c->MaxVarying, MAX_VARYING); c->Program[MESA_SHADER_FRAGMENT].MaxInputComponents = c->MaxVarying * 4; c->Program[MESA_SHADER_VERTEX].MaxOutputComponents = c->MaxVarying * 4; c->Program[MESA_SHADER_GEOMETRY].MaxInputComponents = c->MaxVarying * 4; c->Program[MESA_SHADER_GEOMETRY].MaxOutputComponents = c->MaxVarying * 4; c->MaxGeometryOutputVertices = screen->get_param(screen, PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES); c->MaxGeometryTotalOutputComponents = screen->get_param(screen, PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS); c->MinProgramTexelOffset = screen->get_param(screen, PIPE_CAP_MIN_TEXEL_OFFSET); c->MaxProgramTexelOffset = screen->get_param(screen, PIPE_CAP_MAX_TEXEL_OFFSET); c->MaxProgramTextureGatherComponents = screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS); c->UniformBooleanTrue = ~0; c->MaxTransformFeedbackBuffers = screen->get_param(screen, PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS); c->MaxTransformFeedbackBuffers = MIN2(c->MaxTransformFeedbackBuffers, MAX_FEEDBACK_BUFFERS); c->MaxTransformFeedbackSeparateComponents = screen->get_param(screen, PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS); c->MaxTransformFeedbackInterleavedComponents = screen->get_param(screen, PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS); c->StripTextureBorder = GL_TRUE; c->GLSLSkipStrictMaxUniformLimitCheck = screen->get_param(screen, PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS); if (can_ubo) { st->ctx->Extensions.ARB_uniform_buffer_object = GL_TRUE; c->UniformBufferOffsetAlignment = screen->get_param(screen, PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT); c->MaxCombinedUniformBlocks = c->MaxUniformBufferBindings = c->Program[MESA_SHADER_VERTEX].MaxUniformBlocks + c->Program[MESA_SHADER_GEOMETRY].MaxUniformBlocks + c->Program[MESA_SHADER_FRAGMENT].MaxUniformBlocks; assert(c->MaxCombinedUniformBlocks <= MAX_COMBINED_UNIFORM_BUFFERS); } }
// update L1 control for waypoint navigation // this function costs about 3.5 milliseconds on a AVR2560 void AP_L1_Control::update_waypoint(const struct Location &prev_WP, const struct Location &next_WP) { struct Location _current_loc; float Nu; float xtrackVel; float ltrackVel; // Calculate L1 gain required for specified damping float K_L1 = 4.0f * _L1_damping * _L1_damping; // Get current position and velocity _ahrs->get_position(&_current_loc); // update _target_bearing_cd _target_bearing_cd = get_bearing_cd(&_current_loc, &next_WP); Vector2f _groundspeed_vector = _ahrs->groundspeed_vector(); //Calculate groundspeed float groundSpeed = _groundspeed_vector.length(); // Calculate time varying control parameters // Calculate the L1 length required for specified period // 0.3183099 = 1/1/pipi _L1_dist = 0.3183099f * _L1_damping * _L1_period * groundSpeed; //Convert current location and WP positions to 2D vectors in lat and long Vector2f A_air((_current_loc.lat*1.0e-7f), (_current_loc.lng*1.0e-7f)); Vector2f A_v((prev_WP.lat*1.0e-7f), (prev_WP.lng*1.0e-7f)); Vector2f B_v((next_WP.lat*1.0e-7f), (next_WP.lng*1.0e-7f)); //Calculate the NE position of the aircraft and WP B relative to WP A A_air = _geo2planar(A_v, A_air)*RADIUS_OF_EARTH; Vector2f AB = _geo2planar(A_v, B_v)*RADIUS_OF_EARTH; //Calculate the unit vector from WP A to WP B Vector2f AB_unit = (AB).normalized(); // calculate distance to target track, for reporting _crosstrack_error = AB_unit % A_air; //Determine if the aircraft is behind a +-135 degree degree arc centred on WP A //and further than L1 distance from WP A. Then use WP A as the L1 reference point //Otherwise do normal L1 guidance float WP_A_dist = A_air.length(); float alongTrackDist = A_air * AB_unit; if (WP_A_dist > _L1_dist && alongTrackDist/(WP_A_dist + 1.0f) < -0.7071f) { //Calc Nu to fly To WP A Vector2f A_air_unit = (A_air).normalized(); // Unit vector from WP A to aircraft xtrackVel = _groundspeed_vector % (-A_air_unit); // Velocity across line ltrackVel = _groundspeed_vector * (-A_air_unit); // Velocity along line Nu = atan2f(xtrackVel,ltrackVel); _nav_bearing = atan2f(-A_air_unit.y , -A_air_unit.x); // bearing (radians) from AC to L1 point } else { //Calc Nu to fly along AB line //Calculate Nu2 angle (angle of velocity vector relative to line connecting waypoints) xtrackVel = _groundspeed_vector % AB_unit; // Velocity cross track ltrackVel = _groundspeed_vector * AB_unit; // Velocity along track float Nu2 = atan2f(xtrackVel,ltrackVel); //Calculate Nu1 angle (Angle to L1 reference point) float xtrackErr = A_air % AB_unit; float sine_Nu1 = xtrackErr/_maxf(_L1_dist , 0.1f); //Limit sine of Nu1 to provide a controlled track capture angle of 45 deg sine_Nu1 = constrain_float(sine_Nu1, -0.7854f, 0.7854f); float Nu1 = asinf(sine_Nu1); Nu = Nu1 + Nu2; _nav_bearing = atan2f(AB_unit.y, AB_unit.x) + Nu1; // bearing (radians) from AC to L1 point } //Limit Nu to +-pi Nu = constrain_float(Nu, -1.5708f, +1.5708f); _latAccDem = K_L1 * groundSpeed * groundSpeed / _L1_dist * sinf(Nu); // Waypoint capture status is always false during waypoint following _WPcircle = false; _bearing_error = Nu; // bearing error angle (radians), +ve to left of track }
// update L1 control for loitering void AP_L1_Control::update_loiter(const struct Location ¢er_WP, float radius, int8_t loiter_direction) { struct Location _current_loc; // Calculate guidance gains used by PD loop (used during circle tracking) float omega = (6.2832f / _L1_period); float Kx = omega * omega; float Kv = 2.0f * _L1_damping * omega; // Calculate L1 gain required for specified damping (used during waypoint capture) float K_L1 = 4.0f * _L1_damping * _L1_damping; //Get current position and velocity _ahrs->get_position(&_current_loc); // update _target_bearing_cd _target_bearing_cd = get_bearing_cd(&_current_loc, ¢er_WP); Vector2f _groundspeed_vector = _ahrs->groundspeed_vector(); //Calculate groundspeed float groundSpeed = _groundspeed_vector.length(); // Calculate time varying control parameters // Calculate the L1 length required for specified period // 0.3183099 = 1/pi _L1_dist = 0.3183099f * _L1_damping * _L1_period * groundSpeed; //Convert current location and WP positionsto 2D vectors in lat and long Vector2f A_air((_current_loc.lat*1.0e-7f), (_current_loc.lng*1.0e-7f)); Vector2f A_v((center_WP.lat*1.0e-7f), (center_WP.lng*1.0e-7f)); //Calculate the NE position of the aircraft relative to WP A A_air = _geo2planar(A_v, A_air)*RADIUS_OF_EARTH; //Calculate the unit vector from WP A to aircraft Vector2f A_air_unit = (A_air).normalized(); //Calculate Nu to capture center_WP float xtrackVelCap = A_air_unit % _groundspeed_vector; // Velocity across line - perpendicular to radial inbound to WP float ltrackVelCap = - (_groundspeed_vector * A_air_unit); // Velocity along line - radial inbound to WP float Nu = atan2f(xtrackVelCap,ltrackVelCap); Nu = constrain_float(Nu, -1.5708f, +1.5708f); //Limit Nu to +- Pi/2 //Calculate lat accln demand to capture center_WP (use L1 guidance law) float latAccDemCap = K_L1 * groundSpeed * groundSpeed / _L1_dist * sinf(Nu); //Calculate radial position and velocity errors float xtrackVelCirc = -ltrackVelCap; // Radial outbound velocity - reuse previous radial inbound velocity float xtrackErrCirc = A_air.length() - radius; // Radial distance from the loiter circle // keep crosstrack error for reporting _crosstrack_error = xtrackErrCirc; //Calculate PD control correction to circle waypoint float latAccDemCircPD = (xtrackErrCirc * Kx + xtrackVelCirc * Kv); //Calculate tangential velocity float velTangent = xtrackVelCap * float(loiter_direction); //Prevent PD demand from turning the wrong way by limiting the command when flying the wrong way if ( velTangent < 0.0f ) { latAccDemCircPD = _maxf(latAccDemCircPD , 0.0f); } // Calculate centripetal acceleration demand float latAccDemCircCtr = velTangent * velTangent / _maxf((0.5f * radius) , (radius + xtrackErrCirc)); //Sum PD control and centripetal acceleration to calculate lateral manoeuvre demand float latAccDemCirc = loiter_direction * (latAccDemCircPD + latAccDemCircCtr); // Perform switchover between 'capture' and 'circle' modes at the point where the commands cross over to achieve a seamless transfer // Only fly 'capture' mode if outside the circle if ((latAccDemCap < latAccDemCirc && loiter_direction > 0 && xtrackErrCirc > 0.0f) | (latAccDemCap > latAccDemCirc && loiter_direction < 0 && xtrackErrCirc > 0.0f)) { _latAccDem = latAccDemCap; _WPcircle = false; _bearing_error = Nu; // angle between demanded and achieved velocity vector, +ve to left of track _nav_bearing = atan2f(-A_air_unit.y , -A_air_unit.x); // bearing (radians) from AC to L1 point } else { _latAccDem = latAccDemCirc; _WPcircle = true; _bearing_error = 0.0f; // bearing error (radians), +ve to left of track _nav_bearing = atan2f(-A_air_unit.y , -A_air_unit.x); // bearing (radians)from AC to L1 point } }
/** * Query driver to get implementation limits. * Note that we have to limit/clamp against Mesa's internal limits too. */ void st_init_limits(struct pipe_screen *screen, struct gl_constants *c, struct gl_extensions *extensions) { int supported_irs; unsigned sh; boolean can_ubo = TRUE; c->MaxTextureLevels = _min(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS), MAX_TEXTURE_LEVELS); c->Max3DTextureLevels = _min(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_3D_LEVELS), MAX_3D_TEXTURE_LEVELS); c->MaxCubeTextureLevels = _min(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS), MAX_CUBE_TEXTURE_LEVELS); c->MaxTextureRectSize = _min(1 << (c->MaxTextureLevels - 1), MAX_TEXTURE_RECT_SIZE); c->MaxArrayTextureLayers = screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS); /* Define max viewport size and max renderbuffer size in terms of * max texture size (note: max tex RECT size = max tex 2D size). * If this isn't true for some hardware we'll need new PIPE_CAP_ queries. */ c->MaxViewportWidth = c->MaxViewportHeight = c->MaxRenderbufferSize = c->MaxTextureRectSize; c->MaxDrawBuffers = c->MaxColorAttachments = _clamp(screen->get_param(screen, PIPE_CAP_MAX_RENDER_TARGETS), 1, MAX_DRAW_BUFFERS); c->MaxDualSourceDrawBuffers = _clamp(screen->get_param(screen, PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS), 0, MAX_DRAW_BUFFERS); c->MaxLineWidth = _maxf(1.0f, screen->get_paramf(screen, PIPE_CAPF_MAX_LINE_WIDTH)); c->MaxLineWidthAA = _maxf(1.0f, screen->get_paramf(screen, PIPE_CAPF_MAX_LINE_WIDTH_AA)); c->MaxPointSize = _maxf(1.0f, screen->get_paramf(screen, PIPE_CAPF_MAX_POINT_WIDTH)); c->MaxPointSizeAA = _maxf(1.0f, screen->get_paramf(screen, PIPE_CAPF_MAX_POINT_WIDTH_AA)); /* these are not queryable. Note that GL basically mandates a 1.0 minimum * for non-aa sizes, but we can go down to 0.0 for aa points. */ c->MinPointSize = 1.0f; c->MinPointSizeAA = 0.0f; c->MaxTextureMaxAnisotropy = _maxf(2.0f, screen->get_paramf(screen, PIPE_CAPF_MAX_TEXTURE_ANISOTROPY)); c->MaxTextureLodBias = screen->get_paramf(screen, PIPE_CAPF_MAX_TEXTURE_LOD_BIAS); c->QuadsFollowProvokingVertexConvention = screen->get_param(screen, PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION); c->MaxUniformBlockSize = screen->get_shader_param(screen, PIPE_SHADER_FRAGMENT, PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE); if (c->MaxUniformBlockSize < 16384) { can_ubo = FALSE; } for (sh = 0; sh < PIPE_SHADER_TYPES; ++sh) { struct gl_shader_compiler_options *options; struct gl_program_constants *pc; switch (sh) { case PIPE_SHADER_FRAGMENT: pc = &c->Program[MESA_SHADER_FRAGMENT]; options = &c->ShaderCompilerOptions[MESA_SHADER_FRAGMENT]; break; case PIPE_SHADER_VERTEX: pc = &c->Program[MESA_SHADER_VERTEX]; options = &c->ShaderCompilerOptions[MESA_SHADER_VERTEX]; break; case PIPE_SHADER_GEOMETRY: pc = &c->Program[MESA_SHADER_GEOMETRY]; options = &c->ShaderCompilerOptions[MESA_SHADER_GEOMETRY]; break; case PIPE_SHADER_TESS_CTRL: pc = &c->Program[MESA_SHADER_TESS_CTRL]; options = &c->ShaderCompilerOptions[MESA_SHADER_TESS_CTRL]; break; case PIPE_SHADER_TESS_EVAL: pc = &c->Program[MESA_SHADER_TESS_EVAL]; options = &c->ShaderCompilerOptions[MESA_SHADER_TESS_EVAL]; break; case PIPE_SHADER_COMPUTE: pc = &c->Program[MESA_SHADER_COMPUTE]; options = &c->ShaderCompilerOptions[MESA_SHADER_COMPUTE]; if (!screen->get_param(screen, PIPE_CAP_COMPUTE)) continue; supported_irs = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_SUPPORTED_IRS); if (!(supported_irs & (1 << PIPE_SHADER_IR_TGSI))) continue; break; default: assert(0); } pc->MaxTextureImageUnits = _min(screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS), MAX_TEXTURE_IMAGE_UNITS); pc->MaxInstructions = pc->MaxNativeInstructions = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_INSTRUCTIONS); pc->MaxAluInstructions = pc->MaxNativeAluInstructions = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS); pc->MaxTexInstructions = pc->MaxNativeTexInstructions = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS); pc->MaxTexIndirections = pc->MaxNativeTexIndirections = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS); pc->MaxAttribs = pc->MaxNativeAttribs = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_INPUTS); pc->MaxTemps = pc->MaxNativeTemps = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_TEMPS); pc->MaxAddressRegs = pc->MaxNativeAddressRegs = sh == PIPE_SHADER_VERTEX ? 1 : 0; pc->MaxParameters = pc->MaxNativeParameters = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE) / sizeof(float[4]); pc->MaxInputComponents = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_INPUTS) * 4; pc->MaxOutputComponents = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_OUTPUTS) * 4; pc->MaxUniformComponents = 4 * MIN2(pc->MaxNativeParameters, MAX_UNIFORMS); pc->MaxUniformBlocks = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_CONST_BUFFERS); if (pc->MaxUniformBlocks) pc->MaxUniformBlocks -= 1; /* The first one is for ordinary uniforms. */ pc->MaxUniformBlocks = _min(pc->MaxUniformBlocks, MAX_UNIFORM_BUFFERS); pc->MaxCombinedUniformComponents = (pc->MaxUniformComponents + c->MaxUniformBlockSize / 4 * pc->MaxUniformBlocks); pc->MaxAtomicCounters = MAX_ATOMIC_COUNTERS; pc->MaxAtomicBuffers = screen->get_shader_param( screen, sh, PIPE_SHADER_CAP_MAX_SHADER_BUFFERS) / 2; pc->MaxShaderStorageBlocks = pc->MaxAtomicBuffers; pc->MaxImageUniforms = screen->get_shader_param( screen, sh, PIPE_SHADER_CAP_MAX_SHADER_IMAGES); /* Gallium doesn't really care about local vs. env parameters so use the * same limits. */ pc->MaxLocalParams = MIN2(pc->MaxParameters, MAX_PROGRAM_LOCAL_PARAMS); pc->MaxEnvParams = MIN2(pc->MaxParameters, MAX_PROGRAM_ENV_PARAMS); if (screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_INTEGERS)) { pc->LowInt.RangeMin = 31; pc->LowInt.RangeMax = 30; pc->LowInt.Precision = 0; pc->MediumInt = pc->HighInt = pc->LowInt; } options->EmitNoNoise = TRUE; /* TODO: make these more fine-grained if anyone needs it */ options->MaxIfDepth = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH); options->EmitNoLoops = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH); options->EmitNoFunctions = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_SUBROUTINES); options->EmitNoMainReturn = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_SUBROUTINES); options->EmitNoCont = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED); options->EmitNoIndirectInput = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR); options->EmitNoIndirectOutput = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR); options->EmitNoIndirectTemp = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR); options->EmitNoIndirectUniform = !screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_INDIRECT_CONST_ADDR); if (pc->MaxNativeInstructions && (options->EmitNoIndirectUniform || pc->MaxUniformBlocks < 12)) { can_ubo = FALSE; } if (options->EmitNoLoops) options->MaxUnrollIterations = MIN2(screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_INSTRUCTIONS), 65536); else options->MaxUnrollIterations = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT); options->LowerCombinedClipCullDistance = true; options->LowerBufferInterfaceBlocks = true; if (sh == PIPE_SHADER_COMPUTE) options->LowerShaderSharedVariables = true; } c->LowerTessLevel = true; c->LowerCsDerivedVariables = true; c->PrimitiveRestartForPatches = screen->get_param(screen, PIPE_CAP_PRIMITIVE_RESTART_FOR_PATCHES); c->MaxCombinedTextureImageUnits = _min(c->Program[MESA_SHADER_VERTEX].MaxTextureImageUnits + c->Program[MESA_SHADER_TESS_CTRL].MaxTextureImageUnits + c->Program[MESA_SHADER_TESS_EVAL].MaxTextureImageUnits + c->Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits + c->Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits + c->Program[MESA_SHADER_COMPUTE].MaxTextureImageUnits, MAX_COMBINED_TEXTURE_IMAGE_UNITS); /* This depends on program constants. */ c->MaxTextureCoordUnits = _min(c->Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits, MAX_TEXTURE_COORD_UNITS); c->MaxTextureUnits = _min(c->Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits, c->MaxTextureCoordUnits); c->Program[MESA_SHADER_VERTEX].MaxAttribs = MIN2(c->Program[MESA_SHADER_VERTEX].MaxAttribs, 16); /* PIPE_SHADER_CAP_MAX_INPUTS for the FS specifies the maximum number * of inputs. It's always 2 colors + N generic inputs. */ c->MaxVarying = screen->get_shader_param(screen, PIPE_SHADER_FRAGMENT, PIPE_SHADER_CAP_MAX_INPUTS); c->MaxVarying = MIN2(c->MaxVarying, MAX_VARYING); c->MaxGeometryOutputVertices = screen->get_param(screen, PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES); c->MaxGeometryTotalOutputComponents = screen->get_param(screen, PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS); c->MaxTessPatchComponents = MAX2(screen->get_param(screen, PIPE_CAP_MAX_SHADER_PATCH_VARYINGS), MAX_VARYING) * 4; c->MinProgramTexelOffset = screen->get_param(screen, PIPE_CAP_MIN_TEXEL_OFFSET); c->MaxProgramTexelOffset = screen->get_param(screen, PIPE_CAP_MAX_TEXEL_OFFSET); c->MaxProgramTextureGatherComponents = screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS); c->MinProgramTextureGatherOffset = screen->get_param(screen, PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET); c->MaxProgramTextureGatherOffset = screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET); c->MaxTransformFeedbackBuffers = screen->get_param(screen, PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS); c->MaxTransformFeedbackBuffers = MIN2(c->MaxTransformFeedbackBuffers, MAX_FEEDBACK_BUFFERS); c->MaxTransformFeedbackSeparateComponents = screen->get_param(screen, PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS); c->MaxTransformFeedbackInterleavedComponents = screen->get_param(screen, PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS); c->MaxVertexStreams = MAX2(1, screen->get_param(screen, PIPE_CAP_MAX_VERTEX_STREAMS)); /* The vertex stream must fit into pipe_stream_output_info::stream */ assert(c->MaxVertexStreams <= 4); c->MaxVertexAttribStride = screen->get_param(screen, PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE); c->StripTextureBorder = GL_TRUE; c->GLSLSkipStrictMaxUniformLimitCheck = screen->get_param(screen, PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS); c->UniformBufferOffsetAlignment = screen->get_param(screen, PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT); if (can_ubo) { extensions->ARB_uniform_buffer_object = GL_TRUE; c->MaxCombinedUniformBlocks = c->MaxUniformBufferBindings = c->Program[MESA_SHADER_VERTEX].MaxUniformBlocks + c->Program[MESA_SHADER_TESS_CTRL].MaxUniformBlocks + c->Program[MESA_SHADER_TESS_EVAL].MaxUniformBlocks + c->Program[MESA_SHADER_GEOMETRY].MaxUniformBlocks + c->Program[MESA_SHADER_FRAGMENT].MaxUniformBlocks + c->Program[MESA_SHADER_COMPUTE].MaxUniformBlocks; assert(c->MaxCombinedUniformBlocks <= MAX_COMBINED_UNIFORM_BUFFERS); } c->GLSLFragCoordIsSysVal = screen->get_param(screen, PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL); c->GLSLFrontFacingIsSysVal = screen->get_param(screen, PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL); c->MaxAtomicBufferBindings = c->Program[MESA_SHADER_FRAGMENT].MaxAtomicBuffers; c->MaxCombinedAtomicBuffers = c->Program[MESA_SHADER_VERTEX].MaxAtomicBuffers + c->Program[MESA_SHADER_TESS_CTRL].MaxAtomicBuffers + c->Program[MESA_SHADER_TESS_EVAL].MaxAtomicBuffers + c->Program[MESA_SHADER_GEOMETRY].MaxAtomicBuffers + c->Program[MESA_SHADER_FRAGMENT].MaxAtomicBuffers; assert(c->MaxCombinedAtomicBuffers <= MAX_COMBINED_ATOMIC_BUFFERS); if (c->MaxCombinedAtomicBuffers > 0) { extensions->ARB_shader_atomic_counters = GL_TRUE; extensions->ARB_shader_atomic_counter_ops = GL_TRUE; } c->MaxCombinedShaderOutputResources = c->MaxDrawBuffers; c->ShaderStorageBufferOffsetAlignment = screen->get_param(screen, PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT); if (c->ShaderStorageBufferOffsetAlignment) { c->MaxCombinedShaderStorageBlocks = c->MaxShaderStorageBufferBindings = c->MaxCombinedAtomicBuffers; c->MaxCombinedShaderOutputResources += c->MaxCombinedShaderStorageBlocks; c->MaxShaderStorageBlockSize = 1 << 27; extensions->ARB_shader_storage_buffer_object = GL_TRUE; } c->MaxCombinedImageUniforms = c->Program[MESA_SHADER_VERTEX].MaxImageUniforms + c->Program[MESA_SHADER_TESS_CTRL].MaxImageUniforms + c->Program[MESA_SHADER_TESS_EVAL].MaxImageUniforms + c->Program[MESA_SHADER_GEOMETRY].MaxImageUniforms + c->Program[MESA_SHADER_FRAGMENT].MaxImageUniforms + c->Program[MESA_SHADER_COMPUTE].MaxImageUniforms; c->MaxCombinedShaderOutputResources += c->MaxCombinedImageUniforms; c->MaxImageUnits = MAX_IMAGE_UNITS; c->MaxImageSamples = 0; /* XXX */ if (c->MaxCombinedImageUniforms) { extensions->ARB_shader_image_load_store = GL_TRUE; extensions->ARB_shader_image_size = GL_TRUE; } /* ARB_framebuffer_no_attachments */ c->MaxFramebufferWidth = c->MaxViewportWidth; c->MaxFramebufferHeight = c->MaxViewportHeight; /* NOTE: we cheat here a little by assuming that * PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS has the same * number of layers as we need, although we technically * could have more the generality is not really useful * in practicality. */ c->MaxFramebufferLayers = screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS); c->MaxWindowRectangles = screen->get_param(screen, PIPE_CAP_MAX_WINDOW_RECTANGLES); }
void vg_mat3x3_rsq(const VG_MAT3X3_T *a, /* only top-left 2x2 matrix used */ float *r, float *s0, float *s1) /* don't need q for anything atm, so not calculated */ { /* a = r * s * q (svd, r is rotation, s is scale, q is rotation/flip) a^T = q^T * s * r^T a * a^T = r * s * q * q^T * s * r^T = r * s^2 * r^T eigenvalues of a * a^T will give s^2 eigenvectors of a * a^T will give r */ /* ( b c ) = a * a^T ( d e ) */ float b = (a->m[0][0] * a->m[0][0]) + (a->m[0][1] * a->m[0][1]); float c = (a->m[0][0] * a->m[1][0]) + (a->m[0][1] * a->m[1][1]); /* d = c */ float e = (a->m[1][0] * a->m[1][0]) + (a->m[1][1] * a->m[1][1]); float bpe = b + e; float bme = b - e; /* solve: bx + cy = sx dx + ey = sy cy * dx = (s - b)x * (s - e)y c^2 = (s - b) * (s - e) s^2 - (b + e)s + (be - c^2) = 0 s = (b + e +/- sqrt((b + e)^2 - 4(be - c^2))) / 2 s = (b + e +/- sqrt(b^2 + e^2 - 2be + 4c^2)) / 2 s = (b + e +/- sqrt((b - e)^2 + 4c^2)) / 2 */ float t = sqrt_((bme * bme) + (4.0f * c * c)); float v = (bpe + t) * 0.5f; /* first eigenvalue */ if (s0) { *s0 = sqrt_(v); } if (s1) { *s1 = sqrt_( /* second eigenvalue */ _maxf(bpe - t, 0.0f) * 0.5f); } /* angle of eigenvector corresponds to r */ if (r) { /* first eigenvector is (c, v - b) / (v - e, c) */ float x = (v - e) + c; float y = (v - b) + c; *r = ((absf_(x) < EPS) && (absf_(y) < EPS)) ? 0.0f : atan2_(y, x); } }
/** * Query driver to get implementation limits. * Note that we have to limit/clamp against Mesa's internal limits too. */ void st_init_limits(struct st_context *st) { struct pipe_screen *screen = st->pipe->screen; struct gl_constants *c = &st->ctx->Const; struct gl_program_constants *pc; unsigned i; c->MaxTextureLevels = _min(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS), MAX_TEXTURE_LEVELS); c->Max3DTextureLevels = _min(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_3D_LEVELS), MAX_3D_TEXTURE_LEVELS); c->MaxCubeTextureLevels = _min(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS), MAX_CUBE_TEXTURE_LEVELS); c->MaxTextureRectSize = _min(1 << (c->MaxTextureLevels - 1), MAX_TEXTURE_RECT_SIZE); c->MaxTextureImageUnits = _min(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS), MAX_TEXTURE_IMAGE_UNITS); c->MaxVertexTextureImageUnits = _min(screen->get_param(screen, PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS), MAX_VERTEX_TEXTURE_IMAGE_UNITS); c->MaxCombinedTextureImageUnits = _min(screen->get_param(screen, PIPE_CAP_MAX_COMBINED_SAMPLERS), MAX_COMBINED_TEXTURE_IMAGE_UNITS); c->MaxTextureCoordUnits = _min(c->MaxTextureImageUnits, MAX_TEXTURE_COORD_UNITS); c->MaxTextureUnits = _min(c->MaxTextureImageUnits, c->MaxTextureCoordUnits); c->MaxDrawBuffers = _clamp(screen->get_param(screen, PIPE_CAP_MAX_RENDER_TARGETS), 1, MAX_DRAW_BUFFERS); c->MaxLineWidth = _maxf(1.0f, screen->get_paramf(screen, PIPE_CAP_MAX_LINE_WIDTH)); c->MaxLineWidthAA = _maxf(1.0f, screen->get_paramf(screen, PIPE_CAP_MAX_LINE_WIDTH_AA)); c->MaxPointSize = _maxf(1.0f, screen->get_paramf(screen, PIPE_CAP_MAX_POINT_WIDTH)); c->MaxPointSizeAA = _maxf(1.0f, screen->get_paramf(screen, PIPE_CAP_MAX_POINT_WIDTH_AA)); /* called after _mesa_create_context/_mesa_init_point, fix default user * settable max point size up */ st->ctx->Point.MaxSize = MAX2(c->MaxPointSize, c->MaxPointSizeAA); /* these are not queryable. Note that GL basically mandates a 1.0 minimum * for non-aa sizes, but we can go down to 0.0 for aa points. */ c->MinPointSize = 1.0f; c->MinPointSizeAA = 0.0f; c->MaxTextureMaxAnisotropy = _maxf(2.0f, screen->get_paramf(screen, PIPE_CAP_MAX_TEXTURE_ANISOTROPY)); c->MaxTextureLodBias = screen->get_paramf(screen, PIPE_CAP_MAX_TEXTURE_LOD_BIAS); c->MaxDrawBuffers = CLAMP(screen->get_param(screen, PIPE_CAP_MAX_RENDER_TARGETS), 1, MAX_DRAW_BUFFERS); /* Quads always follow GL provoking rules. */ c->QuadsFollowProvokingVertexConvention = GL_FALSE; for(i = 0; i < MESA_SHADER_TYPES; ++i) { struct gl_shader_compiler_options *options = &st->ctx->ShaderCompilerOptions[i]; switch(i) { case PIPE_SHADER_FRAGMENT: pc = &c->FragmentProgram; break; case PIPE_SHADER_VERTEX: pc = &c->VertexProgram; break; case PIPE_SHADER_GEOMETRY: pc = &c->GeometryProgram; break; } pc->MaxNativeInstructions = screen->get_shader_param(screen, i, PIPE_SHADER_CAP_MAX_INSTRUCTIONS); pc->MaxNativeAluInstructions = screen->get_shader_param(screen, i, PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS); pc->MaxNativeTexInstructions = screen->get_shader_param(screen, i, PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS); pc->MaxNativeTexIndirections = screen->get_shader_param(screen, i, PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS); pc->MaxNativeAttribs = screen->get_shader_param(screen, i, PIPE_SHADER_CAP_MAX_INPUTS); pc->MaxNativeTemps = screen->get_shader_param(screen, i, PIPE_SHADER_CAP_MAX_TEMPS); pc->MaxNativeAddressRegs = screen->get_shader_param(screen, i, PIPE_SHADER_CAP_MAX_ADDRS); pc->MaxNativeParameters = screen->get_shader_param(screen, i, PIPE_SHADER_CAP_MAX_CONSTS); options->EmitNoNoise = TRUE; /* TODO: make these more fine-grained if anyone needs it */ options->EmitNoIfs = !screen->get_shader_param(screen, i, PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH); options->EmitNoFunctions = !screen->get_shader_param(screen, i, PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH); options->EmitNoLoops = !screen->get_shader_param(screen, i, PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH); options->EmitNoMainReturn = !screen->get_shader_param(screen, i, PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH); options->EmitNoCont = !screen->get_shader_param(screen, i, PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED); if(options->EmitNoLoops) options->MaxUnrollIterations = MIN2(screen->get_shader_param(screen, i, PIPE_SHADER_CAP_MAX_INSTRUCTIONS), 65536); } /* PIPE_CAP_MAX_FS_INPUTS specifies the number of COLORn + GENERICn inputs * and is set in MaxNativeAttribs. It's always 2 colors + N generic * attributes. The GLSL compiler never uses COLORn for varyings, so we * subtract the 2 colors to get the maximum number of varyings (generic * attributes) supported by a driver. */ c->MaxVarying = screen->get_shader_param(screen, PIPE_SHADER_FRAGMENT, PIPE_SHADER_CAP_MAX_INPUTS) - 2; c->MaxVarying = MIN2(c->MaxVarying, MAX_VARYING); /* XXX we'll need a better query here someday */ if (screen->get_param(screen, PIPE_CAP_GLSL)) { c->GLSLVersion = 120; } }