Mesa (master): v3dv: only write new uniforms when needed

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Nov 20 07:09:33 UTC 2020


Module: Mesa
Branch: master
Commit: 94c00be49fba0bbfe39836844c622c02dbe142a2
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=94c00be49fba0bbfe39836844c622c02dbe142a2

Author: Iago Toral Quiroga <itoral at igalia.com>
Date:   Thu Nov 19 09:45:16 2020 +0100

v3dv: only write new uniforms when needed

Writing uniform streams is performance sensitive so we should try our
best to avoid writing new uniforms if they have not changed. Particularly,
if only the vertex buffers have changed, we should not write new uniforms.

This improves performance in vkQuake2 by about 11.15%.

Reviewed-by: Alejandro Piñeiro <apinheiro at igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7683>

---

 src/broadcom/vulkan/v3dv_cmd_buffer.c | 47 +++++++++++++++++++++--------------
 src/broadcom/vulkan/v3dv_private.h    |  7 ++++++
 2 files changed, 35 insertions(+), 19 deletions(-)

diff --git a/src/broadcom/vulkan/v3dv_cmd_buffer.c b/src/broadcom/vulkan/v3dv_cmd_buffer.c
index 9c06dbf87bd..e6343a01cfe 100644
--- a/src/broadcom/vulkan/v3dv_cmd_buffer.c
+++ b/src/broadcom/vulkan/v3dv_cmd_buffer.c
@@ -3506,24 +3506,30 @@ emit_configuration_bits(struct v3dv_cmd_buffer *cmd_buffer)
 }
 
 static void
-emit_gl_shader_state(struct v3dv_cmd_buffer *cmd_buffer)
+update_uniform_state(struct v3dv_cmd_buffer *cmd_buffer)
 {
-   struct v3dv_job *job = cmd_buffer->state.job;
-   assert(job);
-
-   struct v3dv_cmd_buffer_state *state = &cmd_buffer->state;
-   struct v3dv_pipeline *pipeline = state->pipeline;
+   struct v3dv_pipeline *pipeline = cmd_buffer->state.pipeline;
    assert(pipeline);
 
-   /* Upload the uniforms to the indirect CL first */
-   struct v3dv_cl_reloc fs_uniforms =
+   cmd_buffer->state.uniforms.fs =
       v3dv_write_uniforms(cmd_buffer, pipeline->fs);
 
-   struct v3dv_cl_reloc vs_uniforms =
+   cmd_buffer->state.uniforms.vs =
       v3dv_write_uniforms(cmd_buffer, pipeline->vs);
 
-   struct v3dv_cl_reloc vs_bin_uniforms =
+   cmd_buffer->state.uniforms.vs_bin =
       v3dv_write_uniforms(cmd_buffer, pipeline->vs_bin);
+}
+
+static void
+emit_gl_shader_state(struct v3dv_cmd_buffer *cmd_buffer)
+{
+   struct v3dv_job *job = cmd_buffer->state.job;
+   assert(job);
+
+   struct v3dv_cmd_buffer_state *state = &cmd_buffer->state;
+   struct v3dv_pipeline *pipeline = state->pipeline;
+   assert(pipeline);
 
    /* Update the cache dirty flag based on the shader progs data */
    job->tmu_dirty_rcl |= pipeline->vs_bin->current_variant->prog_data.vs->base.tmu_dirty_rcl;
@@ -3561,9 +3567,9 @@ emit_gl_shader_state(struct v3dv_cmd_buffer *cmd_buffer)
       shader.fragment_shader_code_address =
          v3dv_cl_address(pipeline->fs->current_variant->assembly_bo, 0);
 
-      shader.coordinate_shader_uniforms_address = vs_bin_uniforms;
-      shader.vertex_shader_uniforms_address = vs_uniforms;
-      shader.fragment_shader_uniforms_address = fs_uniforms;
+      shader.coordinate_shader_uniforms_address = cmd_buffer->state.uniforms.vs_bin;
+      shader.vertex_shader_uniforms_address = cmd_buffer->state.uniforms.vs;
+      shader.fragment_shader_uniforms_address = cmd_buffer->state.uniforms.fs;
 
       shader.address_of_default_attribute_values =
          v3dv_cl_address(pipeline->default_attribute_values, 0);
@@ -4058,13 +4064,16 @@ cmd_buffer_emit_pre_draw(struct v3dv_cmd_buffer *cmd_buffer)
     * that will require that we new uniform state for QUNIFORM_VIEWPORT_*.
     */
    uint32_t *dirty = &cmd_buffer->state.dirty;
-   if (*dirty & (V3DV_CMD_DIRTY_PIPELINE |
-                 V3DV_CMD_DIRTY_VERTEX_BUFFER |
-                 V3DV_CMD_DIRTY_DESCRIPTOR_SETS |
-                 V3DV_CMD_DIRTY_PUSH_CONSTANTS |
-                 V3DV_CMD_DIRTY_VIEWPORT)) {
+
+   const bool dirty_uniforms = *dirty & (V3DV_CMD_DIRTY_PIPELINE |
+                                         V3DV_CMD_DIRTY_PUSH_CONSTANTS |
+                                         V3DV_CMD_DIRTY_DESCRIPTOR_SETS |
+                                         V3DV_CMD_DIRTY_VIEWPORT);
+   if (dirty_uniforms)
+      update_uniform_state(cmd_buffer);
+
+   if (dirty_uniforms || (*dirty & V3DV_CMD_DIRTY_VERTEX_BUFFER))
       emit_gl_shader_state(cmd_buffer);
-   }
 
    if (*dirty & (V3DV_CMD_DIRTY_PIPELINE)) {
       emit_configuration_bits(cmd_buffer);
diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h
index 6f7730b1682..be63f684567 100644
--- a/src/broadcom/vulkan/v3dv_private.h
+++ b/src/broadcom/vulkan/v3dv_private.h
@@ -1013,6 +1013,13 @@ struct v3dv_cmd_buffer_state {
       uint8_t index_size;
    } index_buffer;
 
+   /* Current uniforms */
+   struct {
+      struct v3dv_cl_reloc vs_bin;
+      struct v3dv_cl_reloc vs;
+      struct v3dv_cl_reloc fs;
+   } uniforms;
+
    /* Used to flag OOM conditions during command buffer recording */
    bool oom;
 



More information about the mesa-commit mailing list