summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2015-09-11 10:25:21 -0700
committerJason Ekstrand <[email protected]>2015-09-11 10:25:23 -0700
commitb908c67816709d0bdcdec02b7926c80531508405 (patch)
tree040203e8fd059a85674df1d095f78605fc085ffd
parentfd21f0681a36d5f9fe7d2180eae1f83dae799d99 (diff)
vk: Rework the push constants data structure
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.
-rw-r--r--src/vulkan/anv_cmd_buffer.c46
-rw-r--r--src/vulkan/anv_compiler.cpp6
-rw-r--r--src/vulkan/anv_private.h32
3 files changed, 62 insertions, 22 deletions
diff --git a/src/vulkan/anv_cmd_buffer.c b/src/vulkan/anv_cmd_buffer.c
index f8a630bece5..17857d9759a 100644
--- a/src/vulkan/anv_cmd_buffer.c
+++ b/src/vulkan/anv_cmd_buffer.c
@@ -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);
}
diff --git a/src/vulkan/anv_compiler.cpp b/src/vulkan/anv_compiler.cpp
index 5f189c7ce8e..06ae61aea5c 100644
--- a/src/vulkan/anv_compiler.cpp
+++ b/src/vulkan/anv_compiler.cpp
@@ -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
diff --git a/src/vulkan/anv_private.h b/src/vulkan/anv_private.h
index 0c7d5e8a536..53eb0b30526 100644
--- a/src/vulkan/anv_private.h
+++ b/src/vulkan/anv_private.h
@@ -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;