i965/gen7: Expose ARB_shader_atomic_counters.
[mesa.git] / src / mesa / drivers / dri / i965 / brw_context.c
index 109f40babe34bc0b65276c93410af55c619d4ec0..776d8b303e5f507e42e5bb02f55a6ec5d975949c 100644 (file)
@@ -37,7 +37,6 @@
 #include "main/imports.h"
 #include "main/macros.h"
 #include "main/points.h"
-#include "main/simple_list.h"
 #include "main/version.h"
 #include "main/vtxfmt.h"
 
@@ -131,8 +130,10 @@ intel_viewport(struct gl_context *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
    struct brw_context *brw = brw_context(ctx);
    __DRIcontext *driContext = brw->driContext;
 
-   if (brw->saved_viewport)
-      brw->saved_viewport(ctx, x, y, w, h);
+   (void) x;
+   (void) y;
+   (void) w;
+   (void) h;
 
    if (_mesa_is_winsys_fbo(ctx->DrawBuffer)) {
       dri2InvalidateDrawable(driContext->driDrawablePriv);
@@ -221,10 +222,8 @@ brw_init_driver_functions(struct brw_context *brw,
     * So EGL still relies on viewport hacks to handle window resizing.
     * This should go away with DRI3000.
     */
-   if (!brw->driContext->driScreenPriv->dri2.useInvalidate) {
-      brw->saved_viewport = functions->Viewport;
+   if (!brw->driContext->driScreenPriv->dri2.useInvalidate)
       functions->Viewport = intel_viewport;
-   }
 
    functions->Flush = intel_glFlush;
    functions->Finish = intelFinish;
@@ -251,9 +250,15 @@ brw_init_driver_functions(struct brw_context *brw,
 
    functions->QuerySamplesForFormat = brw_query_samples_for_format;
 
+   functions->NewTransformFeedback = brw_new_transform_feedback;
+   functions->DeleteTransformFeedback = brw_delete_transform_feedback;
+   functions->GetTransformFeedbackVertexCount =
+      brw_get_transform_feedback_vertex_count;
    if (brw->gen >= 7) {
       functions->BeginTransformFeedback = gen7_begin_transform_feedback;
       functions->EndTransformFeedback = gen7_end_transform_feedback;
+      functions->PauseTransformFeedback = gen7_pause_transform_feedback;
+      functions->ResumeTransformFeedback = gen7_resume_transform_feedback;
    } else {
       functions->BeginTransformFeedback = brw_begin_transform_feedback;
       functions->EndTransformFeedback = brw_end_transform_feedback;
@@ -263,6 +268,56 @@ brw_init_driver_functions(struct brw_context *brw,
       functions->GetSamplePosition = gen6_get_sample_position;
 }
 
+/**
+ * Return array of MSAA modes supported by the hardware. The array is
+ * zero-terminated and sorted in decreasing order.
+ */
+static const int*
+brw_supported_msaa_modes(const struct brw_context *brw)
+{
+   static const int gen7_samples[] = {8, 4, 0};
+   static const int gen6_samples[] = {4, 0};
+   static const int gen4_samples[] = {0};
+   if (brw->gen >= 7) {
+      return gen7_samples;
+   } else if (brw->gen == 6) {
+      return gen6_samples;
+   } else {
+      return gen4_samples;
+   }
+}
+
+/**
+ * Override GL_MAX_SAMPLES and related constants according to value of driconf
+ * option 'clamp_max_samples'.
+ */
+static void
+brw_override_max_samples(struct brw_context *brw)
+{
+   const int clamp_max_samples = driQueryOptioni(&brw->optionCache,
+                                                 "clamp_max_samples");
+   if (clamp_max_samples < 0)
+      return;
+
+   const int *supported_msaa_modes = brw_supported_msaa_modes(brw);
+   int max_samples = 0;
+
+   /* Select the largest supported MSAA mode that does not exceed
+    * clamp_max_samples.
+    */
+   for (int i = 0; supported_msaa_modes[i] != 0; ++i) {
+      if (supported_msaa_modes[i] <= clamp_max_samples) {
+         max_samples = supported_msaa_modes[i];
+         break;
+      }
+   }
+
+   brw->ctx.Const.MaxSamples = max_samples;
+   brw->ctx.Const.MaxColorTextureSamples = max_samples;
+   brw->ctx.Const.MaxDepthTextureSamples = max_samples;
+   brw->ctx.Const.MaxIntegerSamples = max_samples;
+}
+
 static void
 brw_initialize_context_constants(struct brw_context *brw)
 {
@@ -280,9 +335,14 @@ brw_initialize_context_constants(struct brw_context *brw)
       MIN2(ctx->Const.MaxTextureCoordUnits,
            ctx->Const.FragmentProgram.MaxTextureImageUnits);
    ctx->Const.VertexProgram.MaxTextureImageUnits = BRW_MAX_TEX_UNIT;
+   if (brw->gen >= 7)
+      ctx->Const.GeometryProgram.MaxTextureImageUnits = BRW_MAX_TEX_UNIT;
+   else
+      ctx->Const.GeometryProgram.MaxTextureImageUnits = 0;
    ctx->Const.MaxCombinedTextureImageUnits =
       ctx->Const.VertexProgram.MaxTextureImageUnits +
-      ctx->Const.FragmentProgram.MaxTextureImageUnits;
+      ctx->Const.FragmentProgram.MaxTextureImageUnits +
+      ctx->Const.GeometryProgram.MaxTextureImageUnits;
 
    ctx->Const.MaxTextureLevels = 14; /* 8192 */
    if (ctx->Const.MaxTextureLevels > MAX_TEXTURE_LEVELS)
@@ -321,18 +381,16 @@ brw_initialize_context_constants(struct brw_context *brw)
    ctx->Const.MaxTransformFeedbackSeparateComponents =
       BRW_MAX_SOL_BINDINGS / BRW_MAX_SOL_BUFFERS;
 
-   if (brw->gen == 6) {
-      ctx->Const.MaxSamples = 4;
-      ctx->Const.MaxColorTextureSamples = 4;
-      ctx->Const.MaxDepthTextureSamples = 4;
-      ctx->Const.MaxIntegerSamples = 4;
-   } else if (brw->gen >= 7) {
-      ctx->Const.MaxSamples = 8;
-      ctx->Const.MaxColorTextureSamples = 8;
-      ctx->Const.MaxDepthTextureSamples = 8;
-      ctx->Const.MaxIntegerSamples = 8;
+   ctx->Const.AlwaysUseGetTransformFeedbackVertexCount = true;
+
+   const int max_samples = brw_supported_msaa_modes(brw)[0];
+   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;
-   }
 
    ctx->Const.MinLineWidth = 1.0;
    ctx->Const.MinLineWidthAA = 1.0;
@@ -385,6 +443,16 @@ brw_initialize_context_constants(struct brw_context *brw)
    ctx->Const.FragmentProgram.HighInt = ctx->Const.FragmentProgram.LowInt;
    ctx->Const.FragmentProgram.MediumInt = ctx->Const.FragmentProgram.LowInt;
 
+   if (brw->gen >= 7) {
+      ctx->Const.FragmentProgram.MaxAtomicCounters = MAX_ATOMIC_COUNTERS;
+      ctx->Const.VertexProgram.MaxAtomicCounters = MAX_ATOMIC_COUNTERS;
+      ctx->Const.GeometryProgram.MaxAtomicCounters = MAX_ATOMIC_COUNTERS;
+      ctx->Const.FragmentProgram.MaxAtomicBuffers = BRW_MAX_ABO;
+      ctx->Const.VertexProgram.MaxAtomicBuffers = BRW_MAX_ABO;
+      ctx->Const.GeometryProgram.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
@@ -395,12 +463,23 @@ brw_initialize_context_constants(struct brw_context *brw)
 
    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.VertexProgram.MaxOutputComponents = 128;
-      ctx->Const.GeometryProgram.MaxInputComponents = 128;
+      ctx->Const.GeometryProgram.MaxInputComponents = 64;
       ctx->Const.GeometryProgram.MaxOutputComponents = 128;
       ctx->Const.FragmentProgram.MaxInputComponents = 128;
    }
@@ -483,7 +562,7 @@ brw_process_driconf_options(struct brw_context *brw)
       driQueryOptionb(options, "disable_glsl_line_continuations");
 }
 
-bool
+GLboolean
 brwCreateContext(gl_api api,
                 const struct gl_config *mesaVis,
                 __DRIcontext *driContextPriv,
@@ -586,10 +665,12 @@ brwCreateContext(gl_api api,
    /* Reinitialize the context point state.  It depends on ctx->Const values. */
    _mesa_init_point(ctx);
 
-   intelInitExtensions(ctx);
-
    intel_batchbuffer_init(brw);
 
+   brw_init_state(brw);
+
+   intelInitExtensions(ctx);
+
    intel_fbo_init(brw);
 
    if (brw->gen >= 6) {
@@ -648,8 +729,6 @@ brwCreateContext(gl_api api,
    brw->prim_restart.in_progress = false;
    brw->prim_restart.enable_cut_index = false;
 
-   brw_init_state( brw );
-
    if (brw->gen < 6) {
       brw->curbe.last_buf = calloc(1, 4096);
       brw->curbe.next_buf = calloc(1, 4096);
@@ -673,13 +752,15 @@ brwCreateContext(gl_api api,
 
    _mesa_compute_version(ctx);
 
+   /* Here we override context constants. We apply the overrides after
+    * calculation of the context version because we do not want the overridden
+    * constants to change the version.
+    */
+   brw_override_max_samples(brw);
+
    _mesa_initialize_dispatch_tables(ctx);
    _mesa_initialize_vbo_vtxfmt(ctx);
 
-   if (ctx->Extensions.AMD_performance_monitor) {
-      brw_init_performance_monitors(brw);
-   }
-
    return true;
 }