Mesa (master): zink: implement ARB_instanced_arrays

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Sep 24 20:47:57 UTC 2020


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

Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date:   Fri Jul 10 09:48:23 2020 -0400

zink: implement ARB_instanced_arrays

this is just a simple case of connecting up the vertex state to the pipeline
state

Reviewed-by: Erik Faye-Lund <erik.faye-lund at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6270>

---

 docs/features.txt                        |  2 +-
 src/gallium/drivers/zink/zink_pipeline.c |  8 ++++++++
 src/gallium/drivers/zink/zink_pipeline.h |  2 ++
 src/gallium/drivers/zink/zink_screen.c   |  3 +++
 src/gallium/drivers/zink/zink_state.c    | 13 +++++++++++--
 src/gallium/drivers/zink/zink_state.h    |  1 +
 6 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/docs/features.txt b/docs/features.txt
index 7028870c62f..610241d8b96 100644
--- a/docs/features.txt
+++ b/docs/features.txt
@@ -107,7 +107,7 @@ GL 3.3, GLSL 3.30 --- all DONE: i965, nv50, nvc0, r600, radeonsi, llvmpipe, soft
   GL_ARB_texture_rgb10_a2ui                             DONE (freedreno, swr, zink, panfrost)
   GL_ARB_texture_swizzle                                DONE (freedreno, swr, v3d, zink, panfrost)
   GL_ARB_timer_query                                    DONE (freedreno, swr)
-  GL_ARB_instanced_arrays                               DONE (freedreno, swr, v3d, panfrost)
+  GL_ARB_instanced_arrays                               DONE (freedreno, swr, v3d, panfrost, zink)
   GL_ARB_vertex_type_2_10_10_10_rev                     DONE (freedreno, swr, v3d, panfrost)
 
 
diff --git a/src/gallium/drivers/zink/zink_pipeline.c b/src/gallium/drivers/zink/zink_pipeline.c
index 976c3afc857..f36943a3347 100644
--- a/src/gallium/drivers/zink/zink_pipeline.c
+++ b/src/gallium/drivers/zink/zink_pipeline.c
@@ -46,6 +46,14 @@ zink_create_gfx_pipeline(struct zink_screen *screen,
    vertex_input_state.pVertexAttributeDescriptions = state->element_state->attribs;
    vertex_input_state.vertexAttributeDescriptionCount = state->element_state->num_attribs;
 
+   VkPipelineVertexInputDivisorStateCreateInfoEXT vdiv_state = {};
+   if (state->divisors_present) {
+       vertex_input_state.pNext = &vdiv_state;
+       vdiv_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT;
+       vdiv_state.vertexBindingDivisorCount = state->divisors_present;
+       vdiv_state.pVertexBindingDivisors = state->divisors;
+   }
+
    VkPipelineInputAssemblyStateCreateInfo primitive_state = {};
    primitive_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
    primitive_state.topology = primitive_topology;
diff --git a/src/gallium/drivers/zink/zink_pipeline.h b/src/gallium/drivers/zink/zink_pipeline.h
index 116ce656405..25c9db3ed66 100644
--- a/src/gallium/drivers/zink/zink_pipeline.h
+++ b/src/gallium/drivers/zink/zink_pipeline.h
@@ -41,6 +41,8 @@ struct zink_gfx_pipeline_state {
 
    struct zink_vertex_elements_hw_state *element_state;
    VkVertexInputBindingDescription bindings[PIPE_MAX_ATTRIBS]; // combination of element_state and stride
+   VkVertexInputBindingDivisorDescriptionEXT divisors[PIPE_MAX_ATTRIBS];
+   uint8_t divisors_present;
 
    uint32_t num_attachments;
    struct zink_blend_state *blend_state;
diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c
index 6cec34ac7f1..2c0d59f9b2f 100644
--- a/src/gallium/drivers/zink/zink_screen.c
+++ b/src/gallium/drivers/zink/zink_screen.c
@@ -98,6 +98,9 @@ zink_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_TGSI_TEXCOORD:
       return 1;
 
+   case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
+      return screen->have_EXT_vertex_attribute_divisor;
+
    case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
       if (!screen->feats.dualSrcBlend)
          return 0;
diff --git a/src/gallium/drivers/zink/zink_state.c b/src/gallium/drivers/zink/zink_state.c
index 95f23c273ba..fbb3bd1272f 100644
--- a/src/gallium/drivers/zink/zink_state.c
+++ b/src/gallium/drivers/zink/zink_state.c
@@ -48,7 +48,6 @@ zink_create_vertex_elements_state(struct pipe_context *pctx,
    int num_bindings = 0;
    for (i = 0; i < num_elements; ++i) {
       const struct pipe_vertex_element *elem = elements + i;
-      assert(!elem->instance_divisor);
 
       int binding = elem->vertex_buffer_index;
       if (buffer_map[binding] < 0) {
@@ -59,7 +58,11 @@ zink_create_vertex_elements_state(struct pipe_context *pctx,
 
 
       ves->bindings[binding].binding = binding;
-      ves->bindings[binding].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
+      ves->bindings[binding].inputRate = elem->instance_divisor ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX;
+
+      assert(!elem->instance_divisor || zink_screen(pctx->screen)->have_EXT_vertex_attribute_divisor);
+      ves->divisor[binding] = elem->instance_divisor;
+      assert(elem->instance_divisor <= screen->max_vertex_attrib_divisor);
 
       ves->hw_state.attribs[i].binding = binding;
       ves->hw_state.attribs[i].location = i; // TODO: unsure
@@ -82,12 +85,18 @@ zink_bind_vertex_elements_state(struct pipe_context *pctx,
    struct zink_gfx_pipeline_state *state = &ctx->gfx_pipeline_state;
    ctx->element_state = cso;
    state->hash = 0;
+   state->divisors_present = 0;
    if (cso) {
       state->element_state = &ctx->element_state->hw_state;
       struct zink_vertex_elements_state *ves = cso;
       for (int i = 0; i < state->element_state->num_bindings; ++i) {
          state->bindings[i].binding = ves->bindings[i].binding;
          state->bindings[i].inputRate = ves->bindings[i].inputRate;
+         if (ves->divisor[i]) {
+            state->divisors[state->divisors_present].divisor = ves->divisor[i];
+            state->divisors[state->divisors_present].binding = state->bindings[i].binding;
+            state->divisors_present++;
+         }
       }
    } else
      state->element_state = NULL;
diff --git a/src/gallium/drivers/zink/zink_state.h b/src/gallium/drivers/zink/zink_state.h
index ef5e18176d4..5f0bc304da9 100644
--- a/src/gallium/drivers/zink/zink_state.h
+++ b/src/gallium/drivers/zink/zink_state.h
@@ -38,6 +38,7 @@ struct zink_vertex_elements_state {
       uint32_t binding;
       VkVertexInputRate inputRate;
    } bindings[PIPE_MAX_ATTRIBS];
+   uint32_t divisor[PIPE_MAX_ATTRIBS];
    uint8_t binding_map[PIPE_MAX_ATTRIBS];
    struct zink_vertex_elements_hw_state hw_state;
 };



More information about the mesa-commit mailing list