vk: Rework the push constants data structure
authorJason Ekstrand <jason.ekstrand@intel.com>
Fri, 11 Sep 2015 17:25:21 +0000 (10:25 -0700)
committerJason Ekstrand <jason.ekstrand@intel.com>
Fri, 11 Sep 2015 17:25:23 +0000 (10:25 -0700)
Previously, we simply had a big blob of stuff for "driver constants".  Now,
we have a very specific data structure that contains the driver constants
that we care about.

src/vulkan/anv_cmd_buffer.c
src/vulkan/anv_compiler.cpp
src/vulkan/anv_private.h

index f8a630bece5c1d7d2f561d5561fb948f68c29b03..17857d9759afb4285b59557489151b200d825c75 100644 (file)
@@ -61,6 +61,39 @@ anv_cmd_state_init(struct anv_cmd_state *state)
    state->gen7.index_buffer = NULL;
 }
 
+static VkResult
+anv_cmd_buffer_ensure_push_constants_size(struct anv_cmd_buffer *cmd_buffer,
+                                          VkShaderStage stage, uint32_t size)
+{
+   struct anv_push_constants **ptr = &cmd_buffer->state.push_constants[stage];
+
+   if (*ptr == NULL) {
+      *ptr = anv_device_alloc(cmd_buffer->device, size, 8,
+                              VK_SYSTEM_ALLOC_TYPE_INTERNAL);
+      if (*ptr == NULL)
+         return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+      (*ptr)->size = size;
+   } else if ((*ptr)->size < size) {
+      void *new_data = anv_device_alloc(cmd_buffer->device, size, 8,
+                                        VK_SYSTEM_ALLOC_TYPE_INTERNAL);
+      if (new_data == NULL)
+         return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+      memcpy(new_data, *ptr, (*ptr)->size);
+      anv_device_free(cmd_buffer->device, *ptr);
+
+      *ptr = new_data;
+      (*ptr)->size = size;
+   }
+
+   return VK_SUCCESS;
+}
+
+#define anv_cmd_buffer_ensure_push_constant_field(cmd_buffer, stage, field) \
+   anv_cmd_buffer_ensure_push_constants_size(cmd_buffer, stage, \
+      (offsetof(struct anv_push_constants, field) + \
+       sizeof(cmd_buffer->state.push_constants[0]->field)))
+
 VkResult anv_CreateCommandBuffer(
     VkDevice                                    _device,
     const VkCmdBufferCreateInfo*                pCreateInfo,
@@ -665,8 +698,8 @@ struct anv_state
 anv_cmd_buffer_push_constants(struct anv_cmd_buffer *cmd_buffer,
                               VkShaderStage stage)
 {
-   struct anv_push_constant_data *data =
-      cmd_buffer->state.push_constants[stage].data;
+   struct anv_push_constants *data =
+      cmd_buffer->state.push_constants[stage];
    struct brw_stage_prog_data *prog_data =
       cmd_buffer->state.pipeline->prog_data[stage];
 
@@ -701,14 +734,9 @@ void anv_CmdPushConstants(
    uint32_t stage;
 
    for_each_bit(stage, stageFlags) {
-      if (cmd_buffer->state.push_constants[stage].data == NULL) {
-         cmd_buffer->state.push_constants[stage].data =
-            anv_device_alloc(cmd_buffer->device,
-                             sizeof(struct anv_push_constant_data), 8,
-                             VK_SYSTEM_ALLOC_TYPE_INTERNAL);
-      }
+      anv_cmd_buffer_ensure_push_constant_field(cmd_buffer, stage, client_data);
 
-      memcpy(cmd_buffer->state.push_constants[stage].data->client_data + start,
+      memcpy(cmd_buffer->state.push_constants[stage]->client_data + start,
              values, length);
    }
 
index 5f189c7ce8e4f1a99c69966cffdf9e5478772060..06ae61aea5c83a4f9bcc12b92c82180fdcc429d6 100644 (file)
@@ -149,14 +149,10 @@ create_params_array(struct anv_device *device,
     * actually dereference any of the gl_constant_value pointers in the
     * params array, it doesn't really matter what we put here.
     */
-   struct anv_push_constant_data *null_data = NULL;
+   struct anv_push_constants *null_data = NULL;
    for (unsigned i = 0; i < num_client_params; i++)
       prog_data->param[i] =
          (const gl_constant_value *)&null_data->client_data[i * sizeof(float)];
-
-   for (unsigned i = 0; i < num_driver_params; i++)
-      prog_data->param[num_client_params + i] =
-         (const gl_constant_value *)&null_data->driver_data[i * sizeof(float)];
 }
 
 static void
index 0c7d5e8a536ebdb6cbc830adf2225f892396c434..53eb0b3052621fea5a734c657be485d6ae670039 100644 (file)
@@ -658,6 +658,8 @@ anv_descriptor_set_destroy(struct anv_device *device,
 #define MAX_SETS   8
 #define MAX_RTS    8
 #define MAX_PUSH_CONSTANTS_SIZE 128
+#define MAX_DYNAMIC_BUFFERS 16
+#define MAX_IMAGES 8
 
 struct anv_pipeline_layout {
    struct {
@@ -700,14 +702,28 @@ struct anv_descriptor_set_binding {
    uint32_t                                     dynamic_offsets[128];
 };
 
-struct anv_push_constant_data {
-    uint8_t client_data[MAX_PUSH_CONSTANTS_SIZE];
-    uint8_t driver_data[0];
-};
-
 struct anv_push_constants {
-    uint32_t driver_data_size;
-    struct anv_push_constant_data *data;
+   /* Current allocated size of this push constants data structure.
+    * Because a decent chunk of it may not be used (images on SKL, for
+    * instance), we won't actually allocate the entire structure up-front.
+    */
+   uint32_t size;
+
+   /* Push constant data provided by the client through vkPushConstants */
+   uint8_t client_data[MAX_PUSH_CONSTANTS_SIZE];
+
+   /* Our hardware only provides zero-based vertex and instance id so, in
+    * order to satisfy the vulkan requirements, we may have to push one or
+    * both of these into the shader.
+    */
+   uint32_t base_vertex;
+   uint32_t base_instance;
+
+   /* Offsets for dynamically bound buffers */
+   uint32_t dynamic_offsets[MAX_DYNAMIC_BUFFERS];
+
+   /* Image data for image_load_store on pre-SKL */
+   struct brw_image_param images[MAX_IMAGES];
 };
 
 /** State required while building cmd buffer */
@@ -731,7 +747,7 @@ struct anv_cmd_state {
    uint32_t                                     state_vf[GEN8_3DSTATE_VF_length];
    struct anv_vertex_binding                    vertex_bindings[MAX_VBS];
    struct anv_descriptor_set_binding            descriptors[MAX_SETS];
-   struct anv_push_constants                    push_constants[VK_SHADER_STAGE_NUM];
+   struct anv_push_constants *                  push_constants[VK_SHADER_STAGE_NUM];
 
    struct {
       struct anv_buffer *                       index_buffer;