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.
This commit is contained in:
Jason Ekstrand
2015-09-11 10:25:21 -07:00
parent fd21f0681a
commit b908c67816
3 changed files with 62 additions and 22 deletions

View 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);
}

View 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

View 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;