diff options
author | Dave Airlie <[email protected]> | 2017-03-02 21:39:10 +0000 |
---|---|---|
committer | Dave Airlie <[email protected]> | 2017-07-17 01:44:43 +0100 |
commit | 9ee67467c9ea592340aee10a55ba54d7266ff0a9 (patch) | |
tree | 4588211428eb7a5f369bd0ac3629f32d34863d8a /src/amd/vulkan/radv_meta_clear.c | |
parent | 8eed291c2c4bfaddf256dcdb10bfa95bfe2b7c58 (diff) |
radv: predicate cmask eliminate when using DCC.
When using DCC some clear values don't require a cmask eliminate
step. This patch adds support for black and black with alpha 1,
there are other values, but I don't have access to a comprehensive list.
This works by setting the cmask eliminate predicate when doing the
fast clear, and later when doing the cmask elimination making sure
the draws are predicated.
This increases the fps on Sascha Willems deferred.
Tonga: 580fps->670fps on a Tonga PRO card.
Polaris 730->850fps
Reviewed-by: Bas Nieuwenhuizen <[email protected]>
Signed-off-by: Dave Airlie <[email protected]>
Diffstat (limited to 'src/amd/vulkan/radv_meta_clear.c')
-rw-r--r-- | src/amd/vulkan/radv_meta_clear.c | 87 |
1 files changed, 86 insertions, 1 deletions
diff --git a/src/amd/vulkan/radv_meta_clear.c b/src/amd/vulkan/radv_meta_clear.c index bf583452453..353e8382ca1 100644 --- a/src/amd/vulkan/radv_meta_clear.c +++ b/src/amd/vulkan/radv_meta_clear.c @@ -856,6 +856,83 @@ fail: return res; } +static void vi_get_fast_clear_parameters(VkFormat format, + const VkClearColorValue *clear_value, + uint32_t* reset_value, + bool *can_avoid_fast_clear_elim) +{ + bool values[4] = {}; + int extra_channel; + bool main_value = false; + bool extra_value = false; + int i; + *can_avoid_fast_clear_elim = false; + + *reset_value = 0x20202020U; + + const struct vk_format_description *desc = vk_format_description(format); + if (format == VK_FORMAT_B10G11R11_UFLOAT_PACK32 || + format == VK_FORMAT_R5G6B5_UNORM_PACK16 || + format == VK_FORMAT_B5G6R5_UNORM_PACK16) + extra_channel = -1; + else if (desc->layout == VK_FORMAT_LAYOUT_PLAIN) { + if (radv_translate_colorswap(format, false) <= 1) + extra_channel = desc->nr_channels - 1; + else + extra_channel = 0; + } else + return; + + for (i = 0; i < 4; i++) { + int index = desc->swizzle[i] - VK_SWIZZLE_X; + if (desc->swizzle[i] < VK_SWIZZLE_X || + desc->swizzle[i] > VK_SWIZZLE_W) + continue; + + if (desc->channel[i].pure_integer && + desc->channel[i].type == VK_FORMAT_TYPE_SIGNED) { + /* Use the maximum value for clamping the clear color. */ + int max = u_bit_consecutive(0, desc->channel[i].size - 1); + + values[i] = clear_value->int32[i] != 0; + if (clear_value->int32[i] != 0 && MIN2(clear_value->int32[i], max) != max) + return; + } else if (desc->channel[i].pure_integer && + desc->channel[i].type == VK_FORMAT_TYPE_UNSIGNED) { + /* Use the maximum value for clamping the clear color. */ + unsigned max = u_bit_consecutive(0, desc->channel[i].size); + + values[i] = clear_value->uint32[i] != 0U; + if (clear_value->uint32[i] != 0U && MIN2(clear_value->uint32[i], max) != max) + return; + } else { + values[i] = clear_value->float32[i] != 0.0F; + if (clear_value->float32[i] != 0.0F && clear_value->float32[i] != 1.0F) + return; + } + + if (index == extra_channel) + extra_value = values[i]; + else + main_value = values[i]; + } + + for (int i = 0; i < 4; ++i) + if (values[i] != main_value && + desc->swizzle[i] - VK_SWIZZLE_X != extra_channel && + desc->swizzle[i] >= VK_SWIZZLE_X && + desc->swizzle[i] <= VK_SWIZZLE_W) + return; + + *can_avoid_fast_clear_elim = true; + if (main_value) + *reset_value |= 0x80808080U; + + if (extra_value) + *reset_value |= 0x40404040U; + return; +} + static bool emit_fast_color_clear(struct radv_cmd_buffer *cmd_buffer, const VkClearAttachment *clear_att, @@ -930,9 +1007,17 @@ emit_fast_color_clear(struct radv_cmd_buffer *cmd_buffer, RADV_CMD_FLAG_FLUSH_AND_INV_CB_META; /* clear cmask buffer */ if (iview->image->surface.dcc_size) { + uint32_t reset_value; + bool can_avoid_fast_clear_elim; + vi_get_fast_clear_parameters(iview->image->vk_format, + &clear_value, &reset_value, + &can_avoid_fast_clear_elim); + radv_fill_buffer(cmd_buffer, iview->image->bo, iview->image->offset + iview->image->dcc_offset, - iview->image->surface.dcc_size, 0x20202020); + iview->image->surface.dcc_size, reset_value); + radv_set_dcc_need_cmask_elim_pred(cmd_buffer, iview->image, + !can_avoid_fast_clear_elim); } else { if (iview->image->surface.bpe > 8) { |