v3dv: try harder to skip emission of redundant state

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6766>
This commit is contained in:
Iago Toral Quiroga 2020-06-11 11:59:24 +02:00 committed by Marge Bot
parent 420d13b324
commit e1c8041cde
2 changed files with 81 additions and 26 deletions

View file

@ -3402,13 +3402,18 @@ emit_gl_shader_state(struct v3dv_cmd_buffer *cmd_buffer)
}
}
if (cmd_buffer->state.dirty & V3DV_CMD_DIRTY_PIPELINE) {
v3dv_cl_ensure_space_with_branch(&job->bcl,
sizeof(pipeline->vcm_cache_size));
v3dv_return_if_oom(cmd_buffer, NULL);
cl_emit_prepacked(&job->bcl, &pipeline->vcm_cache_size);
}
v3dv_cl_ensure_space_with_branch(&job->bcl,
sizeof(pipeline->vcm_cache_size) +
cl_packet_length(GL_SHADER_STATE));
v3dv_return_if_oom(cmd_buffer, NULL);
cl_emit_prepacked(&job->bcl, &pipeline->vcm_cache_size);
cl_emit(&job->bcl, GL_SHADER_STATE, state) {
state.address = v3dv_cl_address(job->indirect.bo,
shader_rec_offset);
@ -3672,13 +3677,21 @@ cmd_buffer_emit_pre_draw(struct v3dv_cmd_buffer *cmd_buffer)
struct v3dv_job *job = cmd_buffer_pre_draw_split_job(cmd_buffer);
job->draw_count++;
/* FIXME: likely to be filtered by really needed states */
/* We may need to compile shader variants based on bound textures */
uint32_t *dirty = &cmd_buffer->state.dirty;
if (*dirty & (V3DV_CMD_DIRTY_PIPELINE |
V3DV_CMD_DIRTY_DESCRIPTOR_SETS)) {
update_pipeline_variants(cmd_buffer);
}
/* GL shader state binds shaders, uniform and vertex attribute state. The
* compiler injects uniforms to handle some descriptor types (such as
* textures), so we need to regen that when descriptor state changes.
*/
if (*dirty & (V3DV_CMD_DIRTY_PIPELINE |
V3DV_CMD_DIRTY_VERTEX_BUFFER |
V3DV_CMD_DIRTY_DESCRIPTOR_SETS |
V3DV_CMD_DIRTY_PUSH_CONSTANTS)) {
update_pipeline_variants(cmd_buffer);
emit_gl_shader_state(cmd_buffer);
}
@ -3761,8 +3774,8 @@ v3dv_CmdDrawIndexed(VkCommandBuffer commandBuffer,
const struct v3dv_pipeline *pipeline = cmd_buffer->state.pipeline;
uint32_t hw_prim_type = v3d_hw_prim_type(pipeline->vs->topology);
uint8_t index_type = ffs(cmd_buffer->state.index_size) - 1;
uint32_t index_offset = firstIndex * cmd_buffer->state.index_size;
uint8_t index_type = ffs(cmd_buffer->state.index_buffer.index_size) - 1;
uint32_t index_offset = firstIndex * cmd_buffer->state.index_buffer.index_size;
if (vertexOffset != 0 || firstInstance != 0) {
v3dv_cl_ensure_space_with_branch(
@ -3859,7 +3872,7 @@ v3dv_CmdDrawIndexedIndirect(VkCommandBuffer commandBuffer,
const struct v3dv_pipeline *pipeline = cmd_buffer->state.pipeline;
uint32_t hw_prim_type = v3d_hw_prim_type(pipeline->vs->topology);
uint8_t index_type = ffs(cmd_buffer->state.index_size) - 1;
uint8_t index_type = ffs(cmd_buffer->state.index_buffer.index_size) - 1;
v3dv_cl_ensure_space_with_branch(
&job->bcl, cl_packet_length(INDIRECT_INDEXED_INSTANCED_PRIM_LIST));
@ -3912,12 +3925,35 @@ v3dv_CmdBindVertexBuffers(VkCommandBuffer commandBuffer,
*/
assert(firstBinding + bindingCount <= MAX_VBS);
bool vb_state_changed = false;
for (uint32_t i = 0; i < bindingCount; i++) {
vb[firstBinding + i].buffer = v3dv_buffer_from_handle(pBuffers[i]);
vb[firstBinding + i].offset = pOffsets[i];
if (vb[firstBinding + i].buffer != v3dv_buffer_from_handle(pBuffers[i])) {
vb[firstBinding + i].buffer = v3dv_buffer_from_handle(pBuffers[i]);
vb_state_changed = true;
}
if (vb[firstBinding + i].offset != pOffsets[i]) {
vb[firstBinding + i].offset = pOffsets[i];
vb_state_changed = true;
}
}
cmd_buffer->state.dirty |= V3DV_CMD_DIRTY_VERTEX_BUFFER;
if (vb_state_changed)
cmd_buffer->state.dirty |= V3DV_CMD_DIRTY_VERTEX_BUFFER;
}
static uint32_t
get_index_size(VkIndexType index_type)
{
switch (index_type) {
case VK_INDEX_TYPE_UINT16:
return 2;
break;
case VK_INDEX_TYPE_UINT32:
return 4;
break;
default:
unreachable("Unsupported index type");
}
}
void
@ -3936,22 +3972,22 @@ v3dv_CmdBindIndexBuffer(VkCommandBuffer commandBuffer,
&job->bcl, cl_packet_length(INDEX_BUFFER_SETUP));
v3dv_return_if_oom(cmd_buffer, NULL);
const uint32_t index_size = get_index_size(indexType);
if (buffer == cmd_buffer->state.index_buffer.buffer &&
offset == cmd_buffer->state.index_buffer.offset &&
index_size == cmd_buffer->state.index_buffer.index_size) {
return;
}
cl_emit(&job->bcl, INDEX_BUFFER_SETUP, ib) {
ib.address = v3dv_cl_address(ibuffer->mem->bo,
ibuffer->mem_offset + offset);
ib.size = ibuffer->mem->bo->size;
}
switch (indexType) {
case VK_INDEX_TYPE_UINT16:
cmd_buffer->state.index_size = 2;
break;
case VK_INDEX_TYPE_UINT32:
cmd_buffer->state.index_size = 4;
break;
default:
unreachable("Unsupported index type");
}
cmd_buffer->state.index_buffer.buffer = buffer;
cmd_buffer->state.index_buffer.offset = offset;
cmd_buffer->state.index_buffer.index_size = index_size;
}
void
@ -4053,21 +4089,33 @@ v3dv_CmdBindDescriptorSets(VkCommandBuffer commandBuffer,
struct v3dv_descriptor_state *descriptor_state =
&cmd_buffer->state.descriptor_state;
bool descriptor_state_changed = false;
for (uint32_t i = 0; i < descriptorSetCount; i++) {
V3DV_FROM_HANDLE(v3dv_descriptor_set, set, pDescriptorSets[i]);
uint32_t index = firstSet + i;
descriptor_state->descriptor_sets[index] = set;
descriptor_state->valid |= (1u << index);
if (descriptor_state->descriptor_sets[index] != set) {
descriptor_state->descriptor_sets[index] = set;
descriptor_state_changed = true;
}
if (!(descriptor_state->valid & (1u << index))) {
descriptor_state->valid |= (1u << index);
descriptor_state_changed = true;
}
for (uint32_t j = 0; j < set->layout->dynamic_offset_count; j++, dyn_index++) {
uint32_t idx = j + layout->set[i + firstSet].dynamic_offset_start;
descriptor_state->dynamic_offsets[idx] = pDynamicOffsets[dyn_index];
if (descriptor_state->dynamic_offsets[idx] != pDynamicOffsets[dyn_index]) {
descriptor_state->dynamic_offsets[idx] = pDynamicOffsets[dyn_index];
descriptor_state_changed = true;
}
}
}
cmd_buffer->state.dirty |= V3DV_CMD_DIRTY_DESCRIPTOR_SETS;
if (descriptor_state_changed)
cmd_buffer->state.dirty |= V3DV_CMD_DIRTY_DESCRIPTOR_SETS;
}
void
@ -4080,6 +4128,9 @@ v3dv_CmdPushConstants(VkCommandBuffer commandBuffer,
{
V3DV_FROM_HANDLE(v3dv_cmd_buffer, cmd_buffer, commandBuffer);
if (!memcmp(cmd_buffer->push_constants_data + offset, pValues, size))
return;
memcpy((void*) cmd_buffer->push_constants_data + offset, pValues, size);
cmd_buffer->state.dirty |= V3DV_CMD_DIRTY_PUSH_CONSTANTS;

View file

@ -835,7 +835,11 @@ struct v3dv_cmd_buffer_state {
struct v3dv_vertex_binding vertex_bindings[MAX_VBS];
uint8_t index_size;
struct {
VkBuffer buffer;
VkDeviceSize offset;
uint8_t index_size;
} index_buffer;
/* Used to flag OOM conditions during command buffer recording */
bool oom;