From d0b1bb3032da070a74c81cbcfc8fde380ad26e87 Mon Sep 17 00:00:00 2001 From: Iago Toral Quiroga Date: Thu, 18 Jun 2020 12:14:58 +0200 Subject: [PATCH] v3dv: handle separate binding points for compute and graphics Part-of: --- src/broadcom/vulkan/v3dv_cmd_buffer.c | 54 ++++++++++++++++++--------- src/broadcom/vulkan/v3dv_private.h | 22 ++++++++--- src/broadcom/vulkan/v3dv_uniforms.c | 8 ++-- 3 files changed, 57 insertions(+), 27 deletions(-) diff --git a/src/broadcom/vulkan/v3dv_cmd_buffer.c b/src/broadcom/vulkan/v3dv_cmd_buffer.c index ea0eb5631ac..2255ab33529 100644 --- a/src/broadcom/vulkan/v3dv_cmd_buffer.c +++ b/src/broadcom/vulkan/v3dv_cmd_buffer.c @@ -2547,13 +2547,14 @@ job_update_ez_state(struct v3dv_job *job, */ static void cmd_buffer_populate_v3d_key(struct v3d_key *key, - struct v3dv_cmd_buffer *cmd_buffer) + struct v3dv_cmd_buffer *cmd_buffer, + VkPipelineBindPoint pipeline_binding) { if (cmd_buffer->state.pipeline->combined_index_map != NULL) { struct v3dv_descriptor_map *texture_map = &cmd_buffer->state.pipeline->texture_map; struct v3dv_descriptor_map *sampler_map = &cmd_buffer->state.pipeline->sampler_map; struct v3dv_descriptor_state *descriptor_state = - &cmd_buffer->state.descriptor_state; + &cmd_buffer->state.descriptor_state[pipeline_binding]; hash_table_foreach(cmd_buffer->state.pipeline->combined_index_map, entry) { uint32_t combined_idx = (uint32_t)(uintptr_t) (entry->data); @@ -2612,7 +2613,8 @@ update_fs_variant(struct v3dv_cmd_buffer *cmd_buffer) /* We start with a copy of the original pipeline key */ memcpy(&local_key, &p_stage->key.fs, sizeof(struct v3d_fs_key)); - cmd_buffer_populate_v3d_key(&local_key.base, cmd_buffer); + cmd_buffer_populate_v3d_key(&local_key.base, cmd_buffer, + VK_PIPELINE_BIND_POINT_GRAPHICS); VkResult vk_result; variant = v3dv_get_shader_variant(p_stage, &local_key.base, @@ -2640,7 +2642,8 @@ update_vs_variant(struct v3dv_cmd_buffer *cmd_buffer) p_stage = cmd_buffer->state.pipeline->vs; memcpy(&local_key, &p_stage->key.vs, sizeof(struct v3d_vs_key)); - cmd_buffer_populate_v3d_key(&local_key.base, cmd_buffer); + cmd_buffer_populate_v3d_key(&local_key.base, cmd_buffer, + VK_PIPELINE_BIND_POINT_GRAPHICS); variant = v3dv_get_shader_variant(p_stage, &local_key.base, sizeof(struct v3d_vs_key), @@ -2658,7 +2661,8 @@ update_vs_variant(struct v3dv_cmd_buffer *cmd_buffer) p_stage = cmd_buffer->state.pipeline->vs_bin; memcpy(&local_key, &p_stage->key.vs, sizeof(struct v3d_vs_key)); - cmd_buffer_populate_v3d_key(&local_key.base, cmd_buffer); + cmd_buffer_populate_v3d_key(&local_key.base, cmd_buffer, + VK_PIPELINE_BIND_POINT_GRAPHICS); variant = v3dv_get_shader_variant(p_stage, &local_key.base, sizeof(struct v3d_vs_key), &cmd_buffer->device->alloc, @@ -3499,11 +3503,17 @@ v3dv_cmd_buffer_meta_state_push(struct v3dv_cmd_buffer *cmd_buffer, } state->meta.pipeline = v3dv_pipeline_to_handle(state->pipeline); - if (state->meta.pipeline) + if (state->meta.pipeline) { memcpy(&state->meta.dynamic, &state->dynamic, sizeof(state->dynamic)); + } - if (push_descriptor_state && state->descriptor_state.valid != 0) { - memcpy(&state->meta.descriptor_state, &state->descriptor_state, + /* We expect that meta operations are graphics-only and won't alter + * compute state. + */ + struct v3dv_descriptor_state *gfx_descriptor_state = + &state->descriptor_state[VK_PIPELINE_BIND_POINT_GRAPHICS]; + if (push_descriptor_state && gfx_descriptor_state->valid != 0) { + memcpy(&state->meta.descriptor_state, gfx_descriptor_state, sizeof(state->descriptor_state)); } @@ -3544,20 +3554,27 @@ v3dv_cmd_buffer_meta_state_pop(struct v3dv_cmd_buffer *cmd_buffer, } if (state->meta.pipeline != VK_NULL_HANDLE) { + struct v3dv_pipeline *pipeline = + v3dv_pipeline_from_handle(state->meta.pipeline); + VkPipelineBindPoint pipeline_binding = + v3dv_pipeline_get_binding_point(pipeline); v3dv_CmdBindPipeline(v3dv_cmd_buffer_to_handle(cmd_buffer), - VK_PIPELINE_BIND_POINT_GRAPHICS, + pipeline_binding, state->meta.pipeline); - memcpy(&state->dynamic, &state->meta.dynamic, sizeof(state->dynamic)); - state->dirty |= dirty_dynamic_state; + if (pipeline_binding == VK_PIPELINE_BIND_POINT_GRAPHICS) { + memcpy(&state->dynamic, &state->meta.dynamic, sizeof(state->dynamic)); + state->dirty |= dirty_dynamic_state; + } } else { state->pipeline = VK_NULL_HANDLE; } if (state->meta.descriptor_state.valid != 0) { - memcpy(&state->descriptor_state, &state->meta.descriptor_state, + memcpy(&state->descriptor_state[VK_PIPELINE_BIND_POINT_GRAPHICS], + &state->meta.descriptor_state, sizeof(state->descriptor_state)); } else { - state->descriptor_state.valid = 0; + state->descriptor_state[VK_PIPELINE_BIND_POINT_GRAPHICS].valid = 0; } memcpy(cmd_buffer->push_constants_data, state->meta.push_constants, @@ -4100,11 +4117,10 @@ v3dv_CmdBindDescriptorSets(VkCommandBuffer commandBuffer, uint32_t dyn_index = 0; - assert(pipelineBindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS); assert(firstSet + descriptorSetCount <= MAX_SETS); struct v3dv_descriptor_state *descriptor_state = - &cmd_buffer->state.descriptor_state; + &cmd_buffer->state.descriptor_state[pipelineBindPoint]; bool descriptor_state_changed = false; for (uint32_t i = 0; i < descriptorSetCount; i++) { @@ -4131,8 +4147,12 @@ v3dv_CmdBindDescriptorSets(VkCommandBuffer commandBuffer, } } - if (descriptor_state_changed) - cmd_buffer->state.dirty |= V3DV_CMD_DIRTY_DESCRIPTOR_SETS; + if (descriptor_state_changed) { + if (pipelineBindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS) + cmd_buffer->state.dirty |= V3DV_CMD_DIRTY_DESCRIPTOR_SETS; + else + cmd_buffer->state.dirty |= V3DV_CMD_DIRTY_COMPUTE_DESCRIPTOR_SETS; + } } void diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h index 13ba963456a..8164b7d7d19 100644 --- a/src/broadcom/vulkan/v3dv_private.h +++ b/src/broadcom/vulkan/v3dv_private.h @@ -606,11 +606,12 @@ enum v3dv_cmd_dirty_bits { V3DV_CMD_DIRTY_PIPELINE = 1 << 5, V3DV_CMD_DIRTY_VERTEX_BUFFER = 1 << 6, V3DV_CMD_DIRTY_DESCRIPTOR_SETS = 1 << 7, - V3DV_CMD_DIRTY_PUSH_CONSTANTS = 1 << 8, - V3DV_CMD_DIRTY_BLEND_CONSTANTS = 1 << 9, - V3DV_CMD_DIRTY_OCCLUSION_QUERY = 1 << 10, - V3DV_CMD_DIRTY_DEPTH_BIAS = 1 << 11, - V3DV_CMD_DIRTY_LINE_WIDTH = 1 << 12, + V3DV_CMD_DIRTY_COMPUTE_DESCRIPTOR_SETS = 1 << 8, + V3DV_CMD_DIRTY_PUSH_CONSTANTS = 1 << 9, + V3DV_CMD_DIRTY_BLEND_CONSTANTS = 1 << 10, + V3DV_CMD_DIRTY_OCCLUSION_QUERY = 1 << 11, + V3DV_CMD_DIRTY_DEPTH_BIAS = 1 << 12, + V3DV_CMD_DIRTY_LINE_WIDTH = 1 << 13, }; struct v3dv_dynamic_state { @@ -842,7 +843,7 @@ struct v3dv_cmd_buffer_state { uint32_t subpass_idx; struct v3dv_pipeline *pipeline; - struct v3dv_descriptor_state descriptor_state; + struct v3dv_descriptor_state descriptor_state[2]; struct v3dv_dynamic_state dynamic; uint32_t dirty; @@ -1500,6 +1501,15 @@ struct v3dv_pipeline { uint8_t stencil_cfg[2][cl_packet_length(STENCIL_CFG)]; }; +static inline VkPipelineBindPoint +v3dv_pipeline_get_binding_point(struct v3dv_pipeline *pipeline) +{ + assert(pipeline->active_stages == VK_SHADER_STAGE_COMPUTE_BIT || + !(pipeline->active_stages & VK_SHADER_STAGE_COMPUTE_BIT)); + return pipeline->active_stages == VK_SHADER_STAGE_COMPUTE_BIT ? + VK_PIPELINE_BIND_POINT_COMPUTE : VK_PIPELINE_BIND_POINT_GRAPHICS; +} + const nir_shader_compiler_options *v3dv_pipeline_get_nir_options(void); static inline uint32_t diff --git a/src/broadcom/vulkan/v3dv_uniforms.c b/src/broadcom/vulkan/v3dv_uniforms.c index af28c6f1af3..475281d1132 100644 --- a/src/broadcom/vulkan/v3dv_uniforms.c +++ b/src/broadcom/vulkan/v3dv_uniforms.c @@ -93,7 +93,7 @@ write_tmu_p0(struct v3dv_cmd_buffer *cmd_buffer, uint32_t texture_idx; struct v3dv_job *job = cmd_buffer->state.job; struct v3dv_descriptor_state *descriptor_state = - &cmd_buffer->state.descriptor_state; + &cmd_buffer->state.descriptor_state[v3dv_pipeline_get_binding_point(pipeline)]; v3dv_pipeline_combined_index_key_unpack(pipeline->combined_index_to_key_map[unit], &texture_idx, @@ -130,7 +130,7 @@ write_tmu_p1(struct v3dv_cmd_buffer *cmd_buffer, uint32_t sampler_idx; struct v3dv_job *job = cmd_buffer->state.job; struct v3dv_descriptor_state *descriptor_state = - &cmd_buffer->state.descriptor_state; + &cmd_buffer->state.descriptor_state[v3dv_pipeline_get_binding_point(pipeline)]; v3dv_pipeline_combined_index_key_unpack(pipeline->combined_index_to_key_map[unit], NULL, &sampler_idx); @@ -155,7 +155,7 @@ write_ubo_ssbo_uniforms(struct v3dv_cmd_buffer *cmd_buffer, { struct v3dv_job *job = cmd_buffer->state.job; struct v3dv_descriptor_state *descriptor_state = - &cmd_buffer->state.descriptor_state; + &cmd_buffer->state.descriptor_state[v3dv_pipeline_get_binding_point(pipeline)]; struct v3dv_descriptor_map *map = content == QUNIFORM_UBO_ADDR ? @@ -215,7 +215,7 @@ get_texture_size(struct v3dv_cmd_buffer *cmd_buffer, int unit = v3d_unit_data_get_unit(data); uint32_t texture_idx; struct v3dv_descriptor_state *descriptor_state = - &cmd_buffer->state.descriptor_state; + &cmd_buffer->state.descriptor_state[v3dv_pipeline_get_binding_point(pipeline)]; v3dv_pipeline_combined_index_key_unpack(pipeline->combined_index_to_key_map[unit], &texture_idx,