summaryrefslogtreecommitdiffstats
path: root/src/vulkan/anv_cmd_buffer.c
diff options
context:
space:
mode:
authorJordan Justen <[email protected]>2015-12-08 16:56:26 -0800
committerJordan Justen <[email protected]>2015-12-09 11:02:20 -0800
commitf8d5fb4293ea13d0459dd69c40d3d68003f94015 (patch)
tree8df8e34a9f0ec555176219a5f6da37ef2224d8e1 /src/vulkan/anv_cmd_buffer.c
parent974bdfa9ad87bb8282def5e9aab9dfe4849b3bc7 (diff)
anv: Add anv_cmd_buffer_cs_push_constants
Similar to anv_cmd_buffer_push_constants, but handles the compute pipeline, which requires different setup from the other stages. This also handles initializing the compute shader local IDs. Signed-off-by: Jordan Justen <[email protected]>
Diffstat (limited to 'src/vulkan/anv_cmd_buffer.c')
-rw-r--r--src/vulkan/anv_cmd_buffer.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/src/vulkan/anv_cmd_buffer.c b/src/vulkan/anv_cmd_buffer.c
index aacd2ab60e3..d34d53dcbb3 100644
--- a/src/vulkan/anv_cmd_buffer.c
+++ b/src/vulkan/anv_cmd_buffer.c
@@ -927,6 +927,60 @@ anv_cmd_buffer_push_constants(struct anv_cmd_buffer *cmd_buffer,
return state;
}
+struct anv_state
+anv_cmd_buffer_cs_push_constants(struct anv_cmd_buffer *cmd_buffer)
+{
+ struct anv_push_constants *data =
+ cmd_buffer->state.push_constants[MESA_SHADER_COMPUTE];
+ struct anv_pipeline *pipeline = cmd_buffer->state.compute_pipeline;
+ const struct brw_cs_prog_data *cs_prog_data = &pipeline->cs_prog_data;
+ const struct brw_stage_prog_data *prog_data = &cs_prog_data->base;
+
+ const unsigned local_id_dwords = cs_prog_data->local_invocation_id_regs * 8;
+ const unsigned push_constant_data_size =
+ (local_id_dwords + prog_data->nr_params) * sizeof(gl_constant_value);
+ const unsigned reg_aligned_constant_size = ALIGN(push_constant_data_size, 32);
+ const unsigned param_aligned_count =
+ reg_aligned_constant_size / sizeof(uint32_t);
+
+ /* If we don't actually have any push constants, bail. */
+ if (reg_aligned_constant_size == 0)
+ return (struct anv_state) { .offset = 0 };
+
+ const unsigned threads = pipeline->cs_thread_width_max;
+ const unsigned total_push_constants_size =
+ reg_aligned_constant_size * threads;
+ struct anv_state state =
+ anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
+ total_push_constants_size,
+ 32 /* bottom 5 bits MBZ */);
+
+ /* Walk through the param array and fill the buffer with data */
+ uint32_t *u32_map = state.map;
+
+ brw_cs_fill_local_id_payload(cs_prog_data, u32_map, threads,
+ reg_aligned_constant_size);
+
+ /* Setup uniform data for the first thread */
+ for (unsigned i = 0; i < prog_data->nr_params; i++) {
+ uint32_t offset = (uintptr_t)prog_data->param[i];
+ u32_map[local_id_dwords + i] = *(uint32_t *)((uint8_t *)data + offset);
+ }
+
+ /* Copy uniform data from the first thread to every other thread */
+ const size_t uniform_data_size = prog_data->nr_params * sizeof(uint32_t);
+ for (unsigned t = 1; t < threads; t++) {
+ memcpy(&u32_map[t * param_aligned_count + local_id_dwords],
+ &u32_map[local_id_dwords],
+ uniform_data_size);
+ }
+
+ if (!cmd_buffer->device->info.has_llc)
+ anv_state_clflush(state);
+
+ return state;
+}
+
void anv_CmdPushConstants(
VkCommandBuffer commandBuffer,
VkPipelineLayout layout,