st/mesa: add support for ARB_sample_locations
authorRhys Perry <pendingchaos02@gmail.com>
Fri, 15 Jun 2018 01:56:28 +0000 (19:56 -0600)
committerBrian Paul <brianp@vmware.com>
Fri, 15 Jun 2018 02:09:45 +0000 (20:09 -0600)
Signed-off-by: Rhys Perry <pendingchaos02@gmail.com>
Reviewed-by: Brian Paul <brianp@vmware.com> (v2)
Reviewed-by: Marek Olšák <marek.olsak@amd.com> (v2)
src/mesa/state_tracker/st_atom.h
src/mesa/state_tracker/st_atom_list.h
src/mesa/state_tracker/st_atom_msaa.c
src/mesa/state_tracker/st_cb_fbo.c
src/mesa/state_tracker/st_cb_msaa.c
src/mesa/state_tracker/st_context.c
src/mesa/state_tracker/st_context.h
src/mesa/state_tracker/st_extensions.c

index 2567ad30df12676ae4099d706b61eeaf276399d0..96e128d38cfcdd335c6a2d315e03d3447583cda6 100644 (file)
@@ -86,7 +86,7 @@ enum {
                                  ST_NEW_CS_SAMPLERS)
 
 #define ST_NEW_FRAMEBUFFER      (ST_NEW_FB_STATE | \
-                                 ST_NEW_SAMPLE_MASK | \
+                                 ST_NEW_SAMPLE_STATE | \
                                  ST_NEW_SAMPLE_SHADING)
 
 #define ST_NEW_VERTEX_PROGRAM(st, p) (p->affected_states | \
index 5391d4710c16a22b1b16fcbdfefeb7d258ad93bb..e1aebc91e78ea30383e9cee84588e892bd42629d 100644 (file)
@@ -34,7 +34,7 @@ ST_STATE(ST_NEW_FS_IMAGES, st_bind_fs_images)
 ST_STATE(ST_NEW_FB_STATE, st_update_framebuffer_state) /* depends on update_*_texture and bind_*_images */
 ST_STATE(ST_NEW_BLEND, st_update_blend) /* depends on update_framebuffer_state */
 ST_STATE(ST_NEW_RASTERIZER, st_update_rasterizer) /* depends on update_framebuffer_state */
-ST_STATE(ST_NEW_SAMPLE_MASK, st_update_sample_mask) /* depends on update_framebuffer_state */
+ST_STATE(ST_NEW_SAMPLE_STATE, st_update_sample_state) /* depends on update_framebuffer_state */
 ST_STATE(ST_NEW_SAMPLE_SHADING, st_update_sample_shading)
 ST_STATE(ST_NEW_SCISSOR, st_update_scissor) /* depends on update_framebuffer_state */
 ST_STATE(ST_NEW_VIEWPORT, st_update_viewport) /* depends on update_framebuffer_state */
index 556c7c5889e02225b281185452a6590d659f4012..c6affec5525150568525820db90d19138f84b467 100644 (file)
 #include "st_program.h"
 
 #include "cso_cache/cso_context.h"
+#include "util/u_framebuffer.h"
 #include "main/framebuffer.h"
 
 
-/* Update the sample mask for MSAA.
+/**
+ * Update the sample locations
+ */
+static void
+update_sample_locations(struct st_context *st)
+{
+   struct gl_framebuffer *fb = st->ctx->DrawBuffer;
+
+   if (!st->ctx->Extensions.ARB_sample_locations)
+      return;
+
+   if (fb->ProgrammableSampleLocations) {
+      unsigned grid_width, grid_height, size, pixel, sample_index;
+      unsigned samples = st->state.fb_num_samples;
+      bool sample_location_pixel_grid = fb->SampleLocationPixelGrid;
+      uint8_t locations[
+         PIPE_MAX_SAMPLE_LOCATION_GRID_SIZE *
+         PIPE_MAX_SAMPLE_LOCATION_GRID_SIZE * 32];
+
+      st->pipe->screen->get_sample_pixel_grid(
+         st->pipe->screen, samples, &grid_width, &grid_height);
+      size = grid_width * grid_height * samples;
+
+      /**
+       * when a dimension is greater than MAX_SAMPLE_LOCATION_GRID_SIZE,
+       * st->ctx->Driver.GetSamplePixelGrid() returns 1 for both dimensions.
+       */
+      if (grid_width > MAX_SAMPLE_LOCATION_GRID_SIZE ||
+          grid_height > MAX_SAMPLE_LOCATION_GRID_SIZE)
+         sample_location_pixel_grid = false;
+
+      for (pixel = 0; pixel < grid_width * grid_height; pixel++) {
+         for (sample_index = 0; sample_index < samples; sample_index++) {
+            int table_index = sample_index;
+            float x = 0.5f, y = 0.5f;
+            uint8_t loc;
+            if (sample_location_pixel_grid)
+               table_index = pixel * samples + sample_index;
+            if (fb->SampleLocationTable) {
+               x = fb->SampleLocationTable[table_index*2];
+               y = fb->SampleLocationTable[table_index*2+1];
+            }
+            if (st->state.fb_orientation == Y_0_BOTTOM)
+               y = 1.0 - y;
+
+            loc = roundf(CLAMP(x * 16.0f, 0.0f, 15.0f));
+            loc |= (int)roundf(CLAMP(y * 16.0f, 0.0f, 15.0f)) << 4;
+            locations[pixel * samples + sample_index] = loc;
+         }
+      }
+
+      util_sample_locations_flip_y(
+         st->pipe->screen, st->state.fb_height, samples, locations);
+
+      if (!st->state.enable_sample_locations ||
+          st->state.sample_locations_samples != samples ||
+          memcmp(locations, st->state.sample_locations, size) != 0) {
+         st->pipe->set_sample_locations( st->pipe, size, locations);
+         
+         st->state.sample_locations_samples = samples;
+         memcpy(st->state.sample_locations, locations, size);
+      }
+   } else if (st->state.enable_sample_locations) {
+      st->pipe->set_sample_locations(st->pipe, 0, NULL);
+   }
+
+   st->state.enable_sample_locations = fb->ProgrammableSampleLocations;
+}
+
+
+/* Update the sample mask and locations for MSAA.
  */
 void
-st_update_sample_mask(struct st_context *st)
+st_update_sample_state(struct st_context *st)
 {
    unsigned sample_mask = 0xffffffff;
    unsigned sample_count = st->state.fb_num_samples;
@@ -64,6 +135,8 @@ st_update_sample_mask(struct st_context *st)
    }
 
    cso_set_sample_mask(st->cso_context, sample_mask);
+
+   update_sample_locations(st);
 }
 
 
index 5eeec08655d749d544e41f085c4a7e956e90efd6..b851db64886dacc84cb69ea3a819258c3cd49f71 100644 (file)
@@ -855,6 +855,19 @@ st_UnmapRenderbuffer(struct gl_context *ctx,
 }
 
 
+/**
+ * Called via ctx->Driver.EvaluateDepthValues.
+ */
+static void
+st_EvaluateDepthValues(struct gl_context *ctx)
+{
+   struct st_context *st = st_context(ctx);
+
+   st_validate_state(st, ST_PIPELINE_UPDATE_FRAMEBUFFER);
+
+   st->pipe->evaluate_depth_buffer(st->pipe);
+}
+
 
 void
 st_init_fbo_functions(struct dd_function_table *functions)
@@ -871,4 +884,5 @@ st_init_fbo_functions(struct dd_function_table *functions)
 
    functions->MapRenderbuffer = st_MapRenderbuffer;
    functions->UnmapRenderbuffer = st_UnmapRenderbuffer;
+   functions->EvaluateDepthValues = st_EvaluateDepthValues;
 }
index 7f1b4fde91d433cf86f123a5e838ff3fa3866a92..6c5dc1fd43e2e9a4ed03999bdba427c03966dcd8 100644 (file)
@@ -56,8 +56,35 @@ st_GetSamplePosition(struct gl_context *ctx,
 }
 
 
+static void
+st_GetProgrammableSampleCaps(struct gl_context *ctx, const struct gl_framebuffer *fb,
+                             GLuint *outBits, GLuint *outWidth, GLuint *outHeight)
+{
+   struct st_context *st = st_context(ctx);
+   struct pipe_screen *screen = st->pipe->screen;
+
+   st_validate_state(st, ST_PIPELINE_UPDATE_FRAMEBUFFER);
+
+   *outBits = 4;
+   *outWidth = 1;
+   *outHeight = 1;
+
+   if (ctx->Extensions.ARB_sample_locations)
+      screen->get_sample_pixel_grid(screen, st->state.fb_num_samples,
+                                    outWidth, outHeight);
+
+   /* We could handle this better in some circumstances,
+    * but it's not really an issue */
+   if (*outWidth > MAX_SAMPLE_LOCATION_GRID_SIZE ||
+       *outHeight > MAX_SAMPLE_LOCATION_GRID_SIZE) {
+      *outWidth = 1;
+      *outHeight = 1;
+   }
+}
+
 void
 st_init_msaa_functions(struct dd_function_table *functions)
 {
    functions->GetSamplePosition = st_GetSamplePosition;
+   functions->GetProgrammableSampleCaps = st_GetProgrammableSampleCaps;
 }
index 50c8b2e6549fd407577703f3026e65416096ccf2..6c1be76afc6dbf0dc27ec3cd3d9480706974c2f8 100644 (file)
@@ -172,7 +172,7 @@ st_invalidate_buffers(struct st_context *st)
    st->dirty |= ST_NEW_BLEND |
                 ST_NEW_DSA |
                 ST_NEW_FB_STATE |
-                ST_NEW_SAMPLE_MASK |
+                ST_NEW_SAMPLE_STATE |
                 ST_NEW_SAMPLE_SHADING |
                 ST_NEW_FS_STATE |
                 ST_NEW_POLY_STIPPLE |
@@ -323,9 +323,10 @@ st_init_driver_flags(struct st_context *st)
    f->NewLogicOp = ST_NEW_BLEND;
    f->NewStencil = ST_NEW_DSA;
    f->NewMultisampleEnable = ST_NEW_BLEND | ST_NEW_RASTERIZER |
-                             ST_NEW_SAMPLE_MASK | ST_NEW_SAMPLE_SHADING;
+                             ST_NEW_SAMPLE_STATE | ST_NEW_SAMPLE_SHADING;
    f->NewSampleAlphaToXEnable = ST_NEW_BLEND;
-   f->NewSampleMask = ST_NEW_SAMPLE_MASK;
+   f->NewSampleMask = ST_NEW_SAMPLE_STATE;
+   f->NewSampleLocations = ST_NEW_SAMPLE_STATE;
    f->NewSampleShading = ST_NEW_SAMPLE_SHADING;
 
    /* This depends on what the gallium driver wants. */
index 9f5bfba3fd960510da1aa5c605d23dd21a1ba1c3..a4d52b40ae42c2c828db9deb6333194c853026da 100644 (file)
@@ -178,6 +178,12 @@ struct st_context
       GLuint poly_stipple[32];  /**< In OpenGL's bottom-to-top order */
 
       GLuint fb_orientation;
+
+      bool enable_sample_locations;
+      unsigned sample_locations_samples;
+      uint8_t sample_locations[
+         PIPE_MAX_SAMPLE_LOCATION_GRID_SIZE *
+         PIPE_MAX_SAMPLE_LOCATION_GRID_SIZE * 32];
    } state;
 
    uint64_t dirty; /**< dirty states */
index 467d9b075965680bf508d8ff170fce91c8d62cf1..c540cee3974a95e79c98f78b3950ccc0022415a3 100644 (file)
@@ -646,6 +646,7 @@ void st_init_extensions(struct pipe_screen *screen,
       { o(ARB_query_buffer_object),          PIPE_CAP_QUERY_BUFFER_OBJECT              },
       { o(ARB_robust_buffer_access_behavior), PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR   },
       { o(ARB_sample_shading),               PIPE_CAP_SAMPLE_SHADING                   },
+      { o(ARB_sample_locations),             PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS    },
       { o(ARB_seamless_cube_map),            PIPE_CAP_SEAMLESS_CUBE_MAP                },
       { o(ARB_shader_ballot),                PIPE_CAP_TGSI_BALLOT                      },
       { o(ARB_shader_clock),                 PIPE_CAP_TGSI_CLOCK                       },