diff options
author | Rafael Antognolli <[email protected]> | 2019-08-19 17:01:10 -0700 |
---|---|---|
committer | Dylan Baker <[email protected]> | 2019-09-04 11:54:49 -0700 |
commit | 1ec895b4a797678c494e5b4b71e5bc3ccd6019c1 (patch) | |
tree | c1d6945546577adb04660cdae891e8ea0a50e07b /src | |
parent | 7ff682a12cab5fc814fa142a8daf625ac00ed2e9 (diff) |
anv: Only re-emit non-dynamic state that has changed.
On commit f6e7de41d7b, we started emitting 3DSTATE_LINE_STIPPLE as part
of the non-dynamic state. That gets re-emitted every time we bind a new
VkPipeline. But that instruction is non-pipelined, and it caused a perf
regression of about 9-10% on Dota2.
This commit makes anv_dynamic_state_copy() return a mask with only the
state that has changed when copying it. 3DSTATE_LINE_STIPPLE won't be
emitted anymore unless it has changed, fixing the problem above.
v2: Improve commit message and add documentation about skipped checks
(Jason)
Fixes: f6e7de41d7b ("anv: Implement VK_EXT_line_rasterization")
Reviewed-by: Jason Ekstrand <[email protected]>
Reviewed-by: Lionel Landwerlin <[email protected]>
(cherry picked from commit 2b7ba9f239c09049408d86eb71be18887691dc58)
Diffstat (limited to 'src')
-rw-r--r-- | src/intel/vulkan/anv_cmd_buffer.c | 68 | ||||
-rw-r--r-- | src/intel/vulkan/anv_private.h | 6 |
2 files changed, 50 insertions, 24 deletions
diff --git a/src/intel/vulkan/anv_cmd_buffer.c b/src/intel/vulkan/anv_cmd_buffer.c index 96c75e06ae8..59a281d6053 100644 --- a/src/intel/vulkan/anv_cmd_buffer.c +++ b/src/intel/vulkan/anv_cmd_buffer.c @@ -78,46 +78,72 @@ const struct anv_dynamic_state default_dynamic_state = { }, }; -void +/** + * Copy the dynamic state from src to dest based on the copy_mask. + * + * Avoid copying states that have not changed, except for VIEWPORT, SCISSOR and + * BLEND_CONSTANTS (always copy them if they are in the copy_mask). + * + * Returns a mask of the states which changed. + */ +anv_cmd_dirty_mask_t anv_dynamic_state_copy(struct anv_dynamic_state *dest, const struct anv_dynamic_state *src, anv_cmd_dirty_mask_t copy_mask) { + anv_cmd_dirty_mask_t changed = 0; + if (copy_mask & ANV_CMD_DIRTY_DYNAMIC_VIEWPORT) { dest->viewport.count = src->viewport.count; typed_memcpy(dest->viewport.viewports, src->viewport.viewports, src->viewport.count); + changed |= ANV_CMD_DIRTY_DYNAMIC_VIEWPORT; } if (copy_mask & ANV_CMD_DIRTY_DYNAMIC_SCISSOR) { dest->scissor.count = src->scissor.count; typed_memcpy(dest->scissor.scissors, src->scissor.scissors, src->scissor.count); + changed |= ANV_CMD_DIRTY_DYNAMIC_SCISSOR; } - if (copy_mask & ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH) - dest->line_width = src->line_width; + if (copy_mask & ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS) { + typed_memcpy(dest->blend_constants, src->blend_constants, 4); + changed |= ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS; + } - if (copy_mask & ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS) - dest->depth_bias = src->depth_bias; +#define ANV_CMP_COPY(field, flag) \ + if (copy_mask & flag) { \ + if (dest->field != src->field) { \ + dest->field = src->field; \ + changed |= flag; \ + } \ + } - if (copy_mask & ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS) - typed_memcpy(dest->blend_constants, src->blend_constants, 4); + ANV_CMP_COPY(line_width, ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH); + + ANV_CMP_COPY(depth_bias.bias, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS); + ANV_CMP_COPY(depth_bias.clamp, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS); + ANV_CMP_COPY(depth_bias.slope, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS); + + ANV_CMP_COPY(depth_bounds.min, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS); + ANV_CMP_COPY(depth_bounds.max, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS); + + ANV_CMP_COPY(stencil_compare_mask.front, ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK); + ANV_CMP_COPY(stencil_compare_mask.back, ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK); - if (copy_mask & ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS) - dest->depth_bounds = src->depth_bounds; + ANV_CMP_COPY(stencil_write_mask.front, ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK); + ANV_CMP_COPY(stencil_write_mask.back, ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK); - if (copy_mask & ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK) - dest->stencil_compare_mask = src->stencil_compare_mask; + ANV_CMP_COPY(stencil_reference.front, ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE); + ANV_CMP_COPY(stencil_reference.back, ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE); - if (copy_mask & ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK) - dest->stencil_write_mask = src->stencil_write_mask; + ANV_CMP_COPY(line_stipple.factor, ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE); + ANV_CMP_COPY(line_stipple.pattern, ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE); - if (copy_mask & ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE) - dest->stencil_reference = src->stencil_reference; +#undef ANV_CMP_COPY - if (copy_mask & ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE) - dest->line_stipple = src->line_stipple; + return changed; } static void @@ -378,10 +404,10 @@ void anv_CmdBindPipeline( cmd_buffer->state.descriptors_dirty |= pipeline->active_stages; /* Apply the dynamic state from the pipeline */ - cmd_buffer->state.gfx.dirty |= pipeline->dynamic_state_mask; - anv_dynamic_state_copy(&cmd_buffer->state.gfx.dynamic, - &pipeline->dynamic_state, - pipeline->dynamic_state_mask); + cmd_buffer->state.gfx.dirty |= + anv_dynamic_state_copy(&cmd_buffer->state.gfx.dynamic, + &pipeline->dynamic_state, + pipeline->dynamic_state_mask); break; default: diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index 78b5b0793e5..b6bb2019bb3 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -2275,9 +2275,9 @@ struct anv_dynamic_state { extern const struct anv_dynamic_state default_dynamic_state; -void anv_dynamic_state_copy(struct anv_dynamic_state *dest, - const struct anv_dynamic_state *src, - uint32_t copy_mask); +uint32_t anv_dynamic_state_copy(struct anv_dynamic_state *dest, + const struct anv_dynamic_state *src, + uint32_t copy_mask); struct anv_surface_state { struct anv_state state; |