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,
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];
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);
}
* 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
#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 {
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 */
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;