diff options
author | Jordan Justen <[email protected]> | 2015-12-08 16:56:26 -0800 |
---|---|---|
committer | Jordan Justen <[email protected]> | 2015-12-09 11:02:20 -0800 |
commit | f8d5fb4293ea13d0459dd69c40d3d68003f94015 (patch) | |
tree | 8df8e34a9f0ec555176219a5f6da37ef2224d8e1 /src/vulkan/anv_cmd_buffer.c | |
parent | 974bdfa9ad87bb8282def5e9aab9dfe4849b3bc7 (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.c | 54 |
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, |