anv/pipeline: More aggressively optimize away color attachments
Instead of just looking at the number of color attachments, look at which ones are actually used by the subpass. This lets us potentially throw away chunks of the fragment shader. In DXVK, for example, all subpasses have 8 attachments and most are VK_ATTACHMENT_UNUSED so this is very helpful in that case. Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com>
This commit is contained in:
@@ -403,6 +403,7 @@ struct brw_wm_prog_key {
|
|||||||
bool force_dual_color_blend:1;
|
bool force_dual_color_blend:1;
|
||||||
bool coherent_fb_fetch:1;
|
bool coherent_fb_fetch:1;
|
||||||
|
|
||||||
|
uint8_t color_outputs_valid;
|
||||||
uint64_t input_slots_valid;
|
uint64_t input_slots_valid;
|
||||||
unsigned program_string_id;
|
unsigned program_string_id;
|
||||||
GLenum alpha_test_func; /* < For Gen4/5 MRT alpha test */
|
GLenum alpha_test_func; /* < For Gen4/5 MRT alpha test */
|
||||||
|
@@ -339,7 +339,14 @@ populate_wm_prog_key(const struct anv_pipeline *pipeline,
|
|||||||
/* XXX Vulkan doesn't appear to specify */
|
/* XXX Vulkan doesn't appear to specify */
|
||||||
key->clamp_fragment_color = false;
|
key->clamp_fragment_color = false;
|
||||||
|
|
||||||
key->nr_color_regions = pipeline->subpass->color_count;
|
assert(pipeline->subpass->color_count <= MAX_RTS);
|
||||||
|
for (uint32_t i = 0; i < pipeline->subpass->color_count; i++) {
|
||||||
|
if (pipeline->subpass->color_attachments[i].attachment !=
|
||||||
|
VK_ATTACHMENT_UNUSED)
|
||||||
|
key->color_outputs_valid |= (1 << i);
|
||||||
|
}
|
||||||
|
|
||||||
|
key->nr_color_regions = _mesa_bitcount(key->color_outputs_valid);
|
||||||
|
|
||||||
key->replicate_alpha = key->nr_color_regions > 1 &&
|
key->replicate_alpha = key->nr_color_regions > 1 &&
|
||||||
info->pMultisampleState &&
|
info->pMultisampleState &&
|
||||||
@@ -904,8 +911,8 @@ anv_pipeline_compile_fs(struct anv_pipeline *pipeline,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
const unsigned rt = var->data.location - FRAG_RESULT_DATA0;
|
const unsigned rt = var->data.location - FRAG_RESULT_DATA0;
|
||||||
/* Out-of-bounds */
|
/* Unused or out-of-bounds */
|
||||||
if (rt >= key.nr_color_regions)
|
if (rt >= MAX_RTS || !(key.color_outputs_valid & (1 << rt)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const unsigned array_len =
|
const unsigned array_len =
|
||||||
@@ -936,8 +943,8 @@ anv_pipeline_compile_fs(struct anv_pipeline *pipeline,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
const unsigned rt = var->data.location - FRAG_RESULT_DATA0;
|
const unsigned rt = var->data.location - FRAG_RESULT_DATA0;
|
||||||
if (rt >= key.nr_color_regions) {
|
if (rt >= MAX_RTS || !(key.color_outputs_valid & (1 << rt))) {
|
||||||
/* Out-of-bounds, throw it away */
|
/* Unused or out-of-bounds, throw it away */
|
||||||
deleted_output = true;
|
deleted_output = true;
|
||||||
var->data.mode = nir_var_local;
|
var->data.mode = nir_var_local;
|
||||||
exec_node_remove(&var->node);
|
exec_node_remove(&var->node);
|
||||||
@@ -967,6 +974,7 @@ anv_pipeline_compile_fs(struct anv_pipeline *pipeline,
|
|||||||
* the key accordingly.
|
* the key accordingly.
|
||||||
*/
|
*/
|
||||||
key.nr_color_regions = num_rts;
|
key.nr_color_regions = num_rts;
|
||||||
|
key.color_outputs_valid = (1 << num_rts) - 1;
|
||||||
|
|
||||||
assert(num_rts <= max_rt);
|
assert(num_rts <= max_rt);
|
||||||
map.surface_to_descriptor -= num_rts;
|
map.surface_to_descriptor -= num_rts;
|
||||||
|
Reference in New Issue
Block a user