[Mesa-dev] [PATCH 2/2] mesa/st: add support for hw atomics

Dave Airlie airlied at gmail.com
Tue Aug 1 23:00:23 UTC 2017


From: Dave Airlie <airlied at redhat.com>

This adds support for hw atomics to the state tracker,
it just sets the limits using the new CAPs, and sets
the maximums etc for it.

Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 src/mesa/state_tracker/st_extensions.c | 50 +++++++++++++++++++++++++++-------
 1 file changed, 40 insertions(+), 10 deletions(-)

diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c
index 74193cc..49c3f82 100644
--- a/src/mesa/state_tracker/st_extensions.c
+++ b/src/mesa/state_tracker/st_extensions.c
@@ -78,6 +78,8 @@ void st_init_limits(struct pipe_screen *screen,
    int supported_irs;
    unsigned sh;
    boolean can_ubo = TRUE;
+   uint32_t atomic_counter_mode = screen->get_param(screen, PIPE_CAP_ATOMIC_COUNTER_MODE);
+   uint32_t temp;
 
    c->MaxTextureLevels
       = _min(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS),
@@ -242,11 +244,19 @@ void st_init_limits(struct pipe_screen *screen,
                                           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;
-
+      if (atomic_counter_mode == PIPE_ATOMIC_COUNTER_MODE_HW_COUNTERS) {
+         /*
+          * for separate atomic counters get the actual hw limits
+          * per stage on atomic counters and buffers
+          */
+         pc->MaxAtomicCounters = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS);
+         pc->MaxAtomicBuffers = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS);
+         pc->MaxShaderStorageBlocks = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_SHADER_BUFFERS);
+      } else {
+         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);
 
@@ -406,14 +416,26 @@ void st_init_limits(struct pipe_screen *screen,
       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_FRAGMENT].MaxAtomicBuffers;
+
+   if (atomic_counter_mode == PIPE_ATOMIC_COUNTER_MODE_HW_COUNTERS) {
+      /* for separate atomic buffers - there atomic buffer size will be
+         limitied */
+      c->MaxAtomicBufferSize = c->Program[MESA_SHADER_FRAGMENT].MaxAtomicCounters * ATOMIC_COUNTER_SIZE;
+      /* on all HW with separate atomic (evergreen) the following
+         lines are true. not sure it's worth adding CAPs for this at this
+         stage. */
+      c->MaxCombinedAtomicCounters = c->Program[MESA_SHADER_FRAGMENT].MaxAtomicCounters;
+      c->MaxCombinedAtomicBuffers = c->Program[MESA_SHADER_FRAGMENT].MaxAtomicBuffers;
+   } else {
+      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);
+      assert(c->MaxCombinedAtomicBuffers <= MAX_COMBINED_ATOMIC_BUFFERS);
+   }
 
    if (c->MaxCombinedAtomicBuffers > 0) {
       extensions->ARB_shader_atomic_counters = GL_TRUE;
@@ -424,8 +446,11 @@ void st_init_limits(struct pipe_screen *screen,
    c->ShaderStorageBufferOffsetAlignment =
       screen->get_param(screen, PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT);
    if (c->ShaderStorageBufferOffsetAlignment) {
-      c->MaxCombinedShaderStorageBlocks = c->MaxShaderStorageBufferBindings =
-         c->MaxCombinedAtomicBuffers;
+
+      /* for hw atomic counters leaves these at default for now */
+      if (atomic_counter_mode == PIPE_ATOMIC_COUNTER_MODE_USE_BUFFERS)
+         c->MaxCombinedShaderStorageBlocks = c->MaxShaderStorageBufferBindings =
+            c->MaxCombinedAtomicBuffers;
       c->MaxCombinedShaderOutputResources +=
          c->MaxCombinedShaderStorageBlocks;
       c->MaxShaderStorageBlockSize = 1 << 27;
@@ -466,6 +491,11 @@ void st_init_limits(struct pipe_screen *screen,
 
    c->AllowMappedBuffersDuringExecution =
       screen->get_param(screen, PIPE_CAP_ALLOW_MAPPED_BUFFERS_DURING_EXECUTION);
+
+   /* limit the max combined shader output resources to a driver limit */
+   temp = screen->get_param(screen, PIPE_CAP_MAX_COMBINED_SHADER_OUTPUT_RESOURCES);
+   if (temp > 0 && c->MaxCombinedShaderOutputResources > temp)
+      c->MaxCombinedShaderOutputResources = temp;
 }
 
 
-- 
2.9.4



More information about the mesa-dev mailing list