[Mesa-dev] [PATCH v3 3/5] st/mesa: add support for ARB_sample_locations

Rhys Perry pendingchaos02 at gmail.com
Fri Jun 1 15:08:20 UTC 2018


Signed-off-by: Rhys Perry <pendingchaos02 at gmail.com>
Reviewed-by: Brian Paul <brianp at vmware.com> (v2)
Reviewed-by: Marek Olšák <marek.olsak at amd.com> (v2)
---
 src/mesa/state_tracker/st_atom.h       |  2 +-
 src/mesa/state_tracker/st_atom_list.h  |  2 +-
 src/mesa/state_tracker/st_atom_msaa.c  | 77 +++++++++++++++++++++++++++++++++-
 src/mesa/state_tracker/st_cb_fbo.c     | 14 +++++++
 src/mesa/state_tracker/st_cb_msaa.c    | 27 ++++++++++++
 src/mesa/state_tracker/st_context.c    |  7 ++--
 src/mesa/state_tracker/st_context.h    |  6 +++
 src/mesa/state_tracker/st_extensions.c |  1 +
 8 files changed, 129 insertions(+), 7 deletions(-)

diff --git a/src/mesa/state_tracker/st_atom.h b/src/mesa/state_tracker/st_atom.h
index 2567ad30df..96e128d38c 100644
--- a/src/mesa/state_tracker/st_atom.h
+++ b/src/mesa/state_tracker/st_atom.h
@@ -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 | \
diff --git a/src/mesa/state_tracker/st_atom_list.h b/src/mesa/state_tracker/st_atom_list.h
index 5391d4710c..e1aebc91e7 100644
--- a/src/mesa/state_tracker/st_atom_list.h
+++ b/src/mesa/state_tracker/st_atom_list.h
@@ -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 */
diff --git a/src/mesa/state_tracker/st_atom_msaa.c b/src/mesa/state_tracker/st_atom_msaa.c
index 556c7c5889..c6affec552 100644
--- a/src/mesa/state_tracker/st_atom_msaa.c
+++ b/src/mesa/state_tracker/st_atom_msaa.c
@@ -33,13 +33,84 @@
 #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);
 }
 
 
diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c
index 5eeec08655..b851db6488 100644
--- a/src/mesa/state_tracker/st_cb_fbo.c
+++ b/src/mesa/state_tracker/st_cb_fbo.c
@@ -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;
 }
diff --git a/src/mesa/state_tracker/st_cb_msaa.c b/src/mesa/state_tracker/st_cb_msaa.c
index 7f1b4fde91..6c5dc1fd43 100644
--- a/src/mesa/state_tracker/st_cb_msaa.c
+++ b/src/mesa/state_tracker/st_cb_msaa.c
@@ -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;
 }
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
index 50c8b2e654..6c1be76afc 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -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. */
diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
index 9f5bfba3fd..a4d52b40ae 100644
--- a/src/mesa/state_tracker/st_context.h
+++ b/src/mesa/state_tracker/st_context.h
@@ -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 */
diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c
index 2d56a88027..3f529a878d 100644
--- a/src/mesa/state_tracker/st_extensions.c
+++ b/src/mesa/state_tracker/st_extensions.c
@@ -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                       },
-- 
2.14.3



More information about the mesa-dev mailing list