HomogeneousPoint3fAccumulator HomogeneousPoint3fIntegralImage::getRegion(int xmin, int xmax, int ymin, int ymax) const {
  HomogeneousPoint3fAccumulator pa;
  if (! rows() || !cols())
    return pa;
  xmin = _clamp(xmin-1, 0, rows()-1);
  xmax = _clamp(xmax-1, 0, rows()-1);
  ymin = _clamp(ymin-1, 0, cols()-1);
  ymax = _clamp(ymax-1, 0, cols()-1);
  pa = coeffRef(xmax,ymax); //total
  pa += coeffRef(xmin,ymin);  //upper right
  pa -= coeffRef(xmin, ymax);  //upper rectangle
  pa -= coeffRef(xmax, ymin);  //rightmost rectangle
  return pa;
}
	static void _apply_gradient(
		Combine combine,
		const std::vector<Vector<T, N>>& grad0,
		const std::vector<Vector<T, N>>& grad1,
		const std::vector<Vector<T, N>>& grad2,
		GLubyte* dp,
		GLubyte* de
	)
	{
		auto gb0 = grad0.begin(), ge0 = grad0.end();
		auto gb1 = grad1.begin(), ge1 = grad1.end();
		auto gb2 = grad2.begin(), ge2 = grad2.end();

		for(auto gp0=gb0; gp0!=ge0; ++gp0)
		for(auto gp1=gb1; gp1!=ge1; ++gp1)
		for(auto gp2=gb2; gp2!=ge2; ++gp2)
		{
			Vector<T, N> color = combine(*gp0, *gp1, *gp2);
			for(std::size_t c=0; c!=N; ++c)
			{
				assert(dp != de);
				*dp++ = GLubyte(_clamp(color.At(c))*_cc_max());
			}
		}
		OGLPLUS_FAKE_USE(de);
		assert(dp == de);
	}
fixed control_yaw(fixed psi, fixed gyr_z, fixed set_point)
{
	setPoint_y = set_point;

	_yaw_observer(psi, gyr_z);

	integrator_y = _clamp(integrator_y + kyi*(setPoint_y - x1hat_y_k));
    return ky1*setPoint_y + ky2*integrator_y + ky3*x1hat_y_k + ky4*x2hat_y_k + ky5*x3hat_y_k;	      
}
fixed control_roll(fixed phi, fixed gyr_y, fixed set_point, fixed pwm)
{
	setPoint_r = set_point;

	_roll_observer(phi, gyr_y, pwm);

	integrator_r = _clamp(integrator_r + kri*(setPoint_r - x1hat_r_k));
      return kr1*setPoint_r + kr2*integrator_r + kr3*x1hat_r_k + kr4*x2hat_r_k + kr5*x3hat_r_k;
      //return setPoint_r - g1*x1hat_r_k - g2*x2hat_r_k - g3*x3hat_r_k;
}
fixed control_pitch(fixed theta, fixed gyr_x, fixed set_point, fixed pwm)
{
	setPoint_p = set_point;

	_pitch_observer(theta, gyr_x, pwm);

	integrator_p = _clamp(integrator_p + kpi*(setPoint_p - x1hat_p_k));
    return kp1*setPoint_p + kp2*integrator_p + kp3*x1hat_p_k + kp4*x2hat_p_k + kp5*x3hat_p_k;
     //return setPoint_p - g1*x1hat_p_k - g2*x2hat_p_k - g3*x3hat_p_k;
    
}
fixed control_height(fixed height, fixed set_point)
{
	setPoint_h = set_point;

	_height_observer(height);

    integrator_h = _clamp(integrator_h + khi*(setPoint_h - x1hat_h_k));
    
    return kh1*setPoint_h + kh2*integrator_h + kh3*x1hat_h_k + kh4*x2hat_h_k + kh5*x3hat_h_k;

}
Exemple #7
0
const float Himmel::setAltitude(const float altitude)
{
    osg::Vec4f temp; 
    u_common->get(temp);

    // Clamp altitude into non uniform atmosphere. (min alt is 1m)
    temp[0] = _clamp(0.001f, Earth::atmosphereThicknessNonUniform(), altitude);
    u_common->set(temp);

    return getAltitude();
}
Exemple #8
0
void game::validate(ghost_move & move) const
{
	move.fix();

	_clamp(move.index.x, 0, (int)_board.width());
	_clamp(move.index.y, 0, (int)_board.height());

	move.possible = false;
	if (_board.is_valid(move.index.x, move.index.y))
	{
		if (_board.is_valid_tight(move.index.x, move.index.y))
		{
			move.possible = move.border == top ? !_board.at(move.index).top : !_board.at(move.index).left;
		}
		else
		{
			if (move.index.y == _board.height() - 1 && move.index.x != _board.width() - 1)
				move.possible = move.border == top && !_board.at(move.index).top;

			if (move.index.x == _board.width() - 1 && move.index.y != _board.height() - 1)
				move.possible = move.border == left && !_board.at(move.index).left;
		}
	}
}
	static void _apply_gradient(
		const std::vector<Vector<T, N>>& grad0,
		GLubyte* dp,
		GLubyte* de
	)
	{
		auto gb0 = grad0.begin(), ge0 = grad0.end();

		for(auto gp0=gb0; gp0!=ge0; ++gp0)
		{
			Vector<T, N> color = *gp0;
			for(std::size_t c=0; c!=N; ++c)
			{
				assert(dp != de);
				*dp++ = GLubyte(_clamp(color.At(c))*_cc_max());
			}
		}
		OGLPLUS_FAKE_USE(de);
		assert(dp == de);
	}
Exemple #10
0
/**
 * 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);
}
Exemple #11
0
/**
 * 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);
   }
}
/**
 * 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);
}
Exemple #13
0
/**
 * 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;
    }
}