/**
 * Round up the requested multisample count to the next supported sample size.
 */
unsigned
intel_quantize_num_samples(struct intel_screen *intel, unsigned num_samples)
{
   const int *msaa_modes = intel_supported_msaa_modes(intel);
   int quantized_samples = 0;

   for (int i = 0; msaa_modes[i] != -1; ++i) {
      if (msaa_modes[i] >= num_samples)
         quantized_samples = msaa_modes[i];
      else
         break;
   }

   return quantized_samples;
}
Ejemplo n.º 2
0
static void
brw_initialize_context_constants(struct brw_context *brw)
{
   struct gl_context *ctx = &brw->ctx;

   unsigned max_samplers =
      brw->gen >= 8 || brw->is_haswell ? BRW_MAX_TEX_UNIT : 16;

   ctx->Const.QueryCounterBits.Timestamp = 36;

   ctx->Const.StripTextureBorder = true;

   ctx->Const.MaxDualSourceDrawBuffers = 1;
   ctx->Const.MaxDrawBuffers = BRW_MAX_DRAW_BUFFERS;
   ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = max_samplers;
   ctx->Const.MaxTextureCoordUnits = 8; /* Mesa limit */
   ctx->Const.MaxTextureUnits =
      MIN2(ctx->Const.MaxTextureCoordUnits,
           ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits);
   ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = max_samplers;
   if (brw->gen >= 7)
      ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits = max_samplers;
   else
      ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits = 0;
   if (getenv("INTEL_COMPUTE_SHADER")) {
      ctx->Const.Program[MESA_SHADER_COMPUTE].MaxTextureImageUnits = BRW_MAX_TEX_UNIT;
      ctx->Const.MaxUniformBufferBindings += 12;
   } else {
      ctx->Const.Program[MESA_SHADER_COMPUTE].MaxTextureImageUnits = 0;
   }
   ctx->Const.MaxCombinedTextureImageUnits =
      ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits +
      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits +
      ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits +
      ctx->Const.Program[MESA_SHADER_COMPUTE].MaxTextureImageUnits;

   ctx->Const.MaxTextureLevels = 14; /* 8192 */
   if (ctx->Const.MaxTextureLevels > MAX_TEXTURE_LEVELS)
      ctx->Const.MaxTextureLevels = MAX_TEXTURE_LEVELS;
   ctx->Const.Max3DTextureLevels = 12; /* 2048 */
   ctx->Const.MaxCubeTextureLevels = 14; /* 8192 */
   ctx->Const.MaxTextureMbytes = 1536;

   if (brw->gen >= 7)
      ctx->Const.MaxArrayTextureLayers = 2048;
   else
      ctx->Const.MaxArrayTextureLayers = 512;

   ctx->Const.MaxTextureRectSize = 1 << 12;

   ctx->Const.MaxTextureMaxAnisotropy = 16.0;

   ctx->Const.MaxRenderbufferSize = 8192;

   /* Hardware only supports a limited number of transform feedback buffers.
    * So we need to override the Mesa default (which is based only on software
    * limits).
    */
   ctx->Const.MaxTransformFeedbackBuffers = BRW_MAX_SOL_BUFFERS;

   /* On Gen6, in the worst case, we use up one binding table entry per
    * transform feedback component (see comments above the definition of
    * BRW_MAX_SOL_BINDINGS, in brw_context.h), so we need to advertise a value
    * for MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS equal to
    * BRW_MAX_SOL_BINDINGS.
    *
    * In "separate components" mode, we need to divide this value by
    * BRW_MAX_SOL_BUFFERS, so that the total number of binding table entries
    * used up by all buffers will not exceed BRW_MAX_SOL_BINDINGS.
    */
   ctx->Const.MaxTransformFeedbackInterleavedComponents = BRW_MAX_SOL_BINDINGS;
   ctx->Const.MaxTransformFeedbackSeparateComponents =
      BRW_MAX_SOL_BINDINGS / BRW_MAX_SOL_BUFFERS;

   ctx->Const.AlwaysUseGetTransformFeedbackVertexCount = true;

   int max_samples;
   const int *msaa_modes = intel_supported_msaa_modes(brw->intelScreen);
   const int clamp_max_samples =
      driQueryOptioni(&brw->optionCache, "clamp_max_samples");

   if (clamp_max_samples < 0) {
      max_samples = msaa_modes[0];
   } else {
      /* Select the largest supported MSAA mode that does not exceed
       * clamp_max_samples.
       */
      max_samples = 0;
      for (int i = 0; msaa_modes[i] != 0; ++i) {
         if (msaa_modes[i] <= clamp_max_samples) {
            max_samples = msaa_modes[i];
            break;
         }
      }
   }

   ctx->Const.MaxSamples = max_samples;
   ctx->Const.MaxColorTextureSamples = max_samples;
   ctx->Const.MaxDepthTextureSamples = max_samples;
   ctx->Const.MaxIntegerSamples = max_samples;

   if (brw->gen >= 7)
      ctx->Const.MaxProgramTextureGatherComponents = 4;
   else if (brw->gen == 6)
      ctx->Const.MaxProgramTextureGatherComponents = 1;

   ctx->Const.MinLineWidth = 1.0;
   ctx->Const.MinLineWidthAA = 1.0;
   ctx->Const.MaxLineWidth = 5.0;
   ctx->Const.MaxLineWidthAA = 5.0;
   ctx->Const.LineWidthGranularity = 0.5;

   ctx->Const.MinPointSize = 1.0;
   ctx->Const.MinPointSizeAA = 1.0;
   ctx->Const.MaxPointSize = 255.0;
   ctx->Const.MaxPointSizeAA = 255.0;
   ctx->Const.PointSizeGranularity = 1.0;

   if (brw->gen >= 5 || brw->is_g4x)
      ctx->Const.MaxClipPlanes = 8;

   ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeInstructions = 16 * 1024;
   ctx->Const.Program[MESA_SHADER_VERTEX].MaxAluInstructions = 0;
   ctx->Const.Program[MESA_SHADER_VERTEX].MaxTexInstructions = 0;
   ctx->Const.Program[MESA_SHADER_VERTEX].MaxTexIndirections = 0;
   ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeAluInstructions = 0;
   ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeTexInstructions = 0;
   ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeTexIndirections = 0;
   ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeAttribs = 16;
   ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeTemps = 256;
   ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeAddressRegs = 1;
   ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeParameters = 1024;
   ctx->Const.Program[MESA_SHADER_VERTEX].MaxEnvParams =
      MIN2(ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeParameters,
	   ctx->Const.Program[MESA_SHADER_VERTEX].MaxEnvParams);

   ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxNativeInstructions = 1024;
   ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxNativeAluInstructions = 1024;
   ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxNativeTexInstructions = 1024;
   ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxNativeTexIndirections = 1024;
   ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxNativeAttribs = 12;
   ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxNativeTemps = 256;
   ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxNativeAddressRegs = 0;
   ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxNativeParameters = 1024;
   ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxEnvParams =
      MIN2(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxNativeParameters,
	   ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxEnvParams);

   /* Fragment shaders use real, 32-bit twos-complement integers for all
    * integer types.
    */
   ctx->Const.Program[MESA_SHADER_FRAGMENT].LowInt.RangeMin = 31;
   ctx->Const.Program[MESA_SHADER_FRAGMENT].LowInt.RangeMax = 30;
   ctx->Const.Program[MESA_SHADER_FRAGMENT].LowInt.Precision = 0;
   ctx->Const.Program[MESA_SHADER_FRAGMENT].HighInt = ctx->Const.Program[MESA_SHADER_FRAGMENT].LowInt;
   ctx->Const.Program[MESA_SHADER_FRAGMENT].MediumInt = ctx->Const.Program[MESA_SHADER_FRAGMENT].LowInt;

   if (brw->gen >= 7) {
      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxAtomicCounters = MAX_ATOMIC_COUNTERS;
      ctx->Const.Program[MESA_SHADER_VERTEX].MaxAtomicCounters = MAX_ATOMIC_COUNTERS;
      ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxAtomicCounters = MAX_ATOMIC_COUNTERS;
      ctx->Const.Program[MESA_SHADER_COMPUTE].MaxAtomicCounters = MAX_ATOMIC_COUNTERS;
      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxAtomicBuffers = BRW_MAX_ABO;
      ctx->Const.Program[MESA_SHADER_VERTEX].MaxAtomicBuffers = BRW_MAX_ABO;
      ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxAtomicBuffers = BRW_MAX_ABO;
      ctx->Const.Program[MESA_SHADER_COMPUTE].MaxAtomicBuffers = BRW_MAX_ABO;
      ctx->Const.MaxCombinedAtomicBuffers = 3 * BRW_MAX_ABO;
   }

   /* Gen6 converts quads to polygon in beginning of 3D pipeline,
    * but we're not sure how it's actually done for vertex order,
    * that affect provoking vertex decision. Always use last vertex
    * convention for quad primitive which works as expected for now.
    */
   if (brw->gen >= 6)
      ctx->Const.QuadsFollowProvokingVertexConvention = false;

   ctx->Const.NativeIntegers = true;
   ctx->Const.UniformBooleanTrue = 1;

   /* From the gen4 PRM, volume 4 page 127:
    *
    *     "For SURFTYPE_BUFFER non-rendertarget surfaces, this field specifies
    *      the base address of the first element of the surface, computed in
    *      software by adding the surface base address to the byte offset of
    *      the element in the buffer."
    *
    * However, unaligned accesses are slower, so enforce buffer alignment.
    */
   ctx->Const.UniformBufferOffsetAlignment = 16;
   ctx->Const.TextureBufferOffsetAlignment = 16;

   if (brw->gen >= 6) {
      ctx->Const.MaxVarying = 32;
      ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 128;
      ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxInputComponents = 64;
      ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxOutputComponents = 128;
      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents = 128;
   }

   /* We want the GLSL compiler to emit code that uses condition codes */
   for (int i = 0; i < MESA_SHADER_STAGES; i++) {
      ctx->ShaderCompilerOptions[i].MaxIfDepth = brw->gen < 6 ? 16 : UINT_MAX;
      ctx->ShaderCompilerOptions[i].EmitCondCodes = true;
      ctx->ShaderCompilerOptions[i].EmitNoNoise = true;
      ctx->ShaderCompilerOptions[i].EmitNoMainReturn = true;
      ctx->ShaderCompilerOptions[i].EmitNoIndirectInput = true;
      ctx->ShaderCompilerOptions[i].EmitNoIndirectOutput =
	 (i == MESA_SHADER_FRAGMENT);
      ctx->ShaderCompilerOptions[i].EmitNoIndirectTemp =
	 (i == MESA_SHADER_FRAGMENT);
      ctx->ShaderCompilerOptions[i].EmitNoIndirectUniform = false;
      ctx->ShaderCompilerOptions[i].LowerClipDistance = true;
   }

   ctx->ShaderCompilerOptions[MESA_SHADER_VERTEX].OptimizeForAOS = true;
   ctx->ShaderCompilerOptions[MESA_SHADER_GEOMETRY].OptimizeForAOS = true;

   /* ARB_viewport_array */
   if (brw->gen >= 7 && ctx->API == API_OPENGL_CORE) {
      ctx->Const.MaxViewports = GEN7_NUM_VIEWPORTS;
      ctx->Const.ViewportSubpixelBits = 0;

      /* Cast to float before negating becuase MaxViewportWidth is unsigned.
       */
      ctx->Const.ViewportBounds.Min = -(float)ctx->Const.MaxViewportWidth;
      ctx->Const.ViewportBounds.Max = ctx->Const.MaxViewportWidth;
   }
}