zink: use more dynamic state3 when available

this is an all-or-nothing type of thing, where either all the blend/ms
states are available or they aren't

Reviewed-by: Adam Jackson <ajax@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18890>
This commit is contained in:
Mike Blumenkrantz 2022-06-14 16:13:23 -04:00 committed by Marge Bot
parent c7f46d2ad6
commit a5b8466e4a
7 changed files with 116 additions and 36 deletions

View file

@ -2879,6 +2879,7 @@ zink_set_framebuffer_state(struct pipe_context *pctx,
const struct pipe_framebuffer_state *state)
{
struct zink_context *ctx = zink_context(pctx);
struct zink_screen *screen = zink_screen(pctx->screen);
unsigned samples = state->nr_cbufs || state->zsbuf ? 0 : state->samples;
unsigned w = ctx->fb_state.width;
unsigned h = ctx->fb_state.height;
@ -2932,6 +2933,8 @@ zink_set_framebuffer_state(struct pipe_context *pctx,
/* renderpass changes if the number or types of attachments change */
ctx->rp_changed |= ctx->fb_state.nr_cbufs != state->nr_cbufs;
ctx->rp_changed |= !!ctx->fb_state.zsbuf != !!state->zsbuf;
if (ctx->fb_state.nr_cbufs != state->nr_cbufs)
ctx->blend_state_changed |= screen->have_full_ds3;
util_copy_framebuffer_state(&ctx->fb_state, state);
zink_update_fbfetch(ctx);
@ -3030,7 +3033,10 @@ zink_set_framebuffer_state(struct pipe_context *pctx,
zink_update_fs_key_samples(ctx);
if (ctx->gfx_pipeline_state.rast_samples != rast_samples) {
ctx->sample_locations_changed |= ctx->gfx_pipeline_state.sample_locations_enabled;
ctx->gfx_pipeline_state.dirty = true;
if (screen->have_full_ds3)
ctx->sample_mask_changed = true;
else
ctx->gfx_pipeline_state.dirty = true;
}
ctx->gfx_pipeline_state.rast_samples = rast_samples;
@ -3054,7 +3060,10 @@ zink_set_sample_mask(struct pipe_context *pctx, unsigned sample_mask)
{
struct zink_context *ctx = zink_context(pctx);
ctx->gfx_pipeline_state.sample_mask = sample_mask;
ctx->gfx_pipeline_state.dirty = true;
if (zink_screen(pctx->screen)->have_full_ds3)
ctx->sample_mask_changed = true;
else
ctx->gfx_pipeline_state.dirty = true;
}
static void
@ -4631,6 +4640,7 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
screen->info.have_EXT_vertex_input_dynamic_state;
ctx->compute_pipeline_state.dirty = true;
ctx->fb_changed = ctx->rp_changed = true;
ctx->sample_mask_changed = true;
ctx->gfx_pipeline_state.gfx_prim_mode = PIPE_PRIM_MAX;
zink_init_draw_functions(ctx, screen);

View file

@ -647,6 +647,23 @@ zink_draw(struct pipe_context *pctx,
VKCTX(CmdSetLineRasterizationModeEXT)(batch->state->cmdbuf, (VkLineRasterizationModeEXT)rast_state->hw_state.line_mode);
VKCTX(CmdSetLineStippleEnableEXT)(batch->state->cmdbuf, rast_state->hw_state.line_stipple_enable);
}
if ((BATCH_CHANGED || ctx->sample_mask_changed) && screen->have_full_ds3) {
VKCTX(CmdSetRasterizationSamplesEXT)(batch->state->cmdbuf, (VkSampleCountFlagBits)(ctx->gfx_pipeline_state.rast_samples + 1));
VKCTX(CmdSetSampleMaskEXT)(batch->state->cmdbuf, (VkSampleCountFlagBits)(ctx->gfx_pipeline_state.rast_samples + 1), &ctx->gfx_pipeline_state.sample_mask);
ctx->sample_mask_changed = false;
}
if ((BATCH_CHANGED || ctx->blend_state_changed) && screen->have_full_ds3) {
if (ctx->gfx_pipeline_state.blend_state) {
VKCTX(CmdSetAlphaToCoverageEnableEXT)(batch->state->cmdbuf, ctx->gfx_pipeline_state.blend_state->alpha_to_coverage);
if (screen->info.feats.features.alphaToOne)
VKCTX(CmdSetAlphaToOneEnableEXT)(batch->state->cmdbuf, ctx->gfx_pipeline_state.blend_state->alpha_to_one);
VKCTX(CmdSetColorBlendEnableEXT)(batch->state->cmdbuf, 0, ctx->fb_state.nr_cbufs, ctx->gfx_pipeline_state.blend_state->ds3.enables);
VKCTX(CmdSetColorWriteMaskEXT)(batch->state->cmdbuf, 0, ctx->fb_state.nr_cbufs, ctx->gfx_pipeline_state.blend_state->ds3.wrmask);
VKCTX(CmdSetColorBlendEquationEXT)(batch->state->cmdbuf, 0, ctx->fb_state.nr_cbufs, ctx->gfx_pipeline_state.blend_state->ds3.eq);
VKCTX(CmdSetLogicOpEnableEXT)(batch->state->cmdbuf, ctx->gfx_pipeline_state.blend_state->logicop_enable);
VKCTX(CmdSetLogicOpEXT)(batch->state->cmdbuf, ctx->gfx_pipeline_state.blend_state->logicop_func);
}
}
if (BATCH_CHANGED || rast_state_changed) {
enum pipe_prim_type reduced_prim = ctx->last_vertex_stage->reduced_prim;

View file

@ -35,16 +35,6 @@
#include "util/u_debug.h"
#include "util/u_prim.h"
static VkBlendFactor
clamp_void_blend_factor(VkBlendFactor f)
{
if (f == VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA)
return VK_BLEND_FACTOR_ZERO;
if (f == VK_BLEND_FACTOR_DST_ALPHA)
return VK_BLEND_FACTOR_ONE;
return f;
}
VkPipeline
zink_create_gfx_pipeline(struct zink_screen *screen,
struct zink_gfx_program *prog,
@ -210,7 +200,7 @@ zink_create_gfx_pipeline(struct zink_screen *screen,
depth_stencil_state.back = state->dyn_state1.depth_stencil_alpha_state->stencil_back;
depth_stencil_state.depthWriteEnable = state->dyn_state1.depth_stencil_alpha_state->depth_write;
VkDynamicState dynamicStateEnables[64] = {
VkDynamicState dynamicStateEnables[80] = {
VK_DYNAMIC_STATE_LINE_WIDTH,
VK_DYNAMIC_STATE_DEPTH_BIAS,
VK_DYNAMIC_STATE_BLEND_CONSTANTS,
@ -257,6 +247,20 @@ zink_create_gfx_pipeline(struct zink_screen *screen,
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT;
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT;
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LINE_STIPPLE_EXT;
if (screen->have_full_ds3) {
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SAMPLE_MASK_EXT;
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT;
if (state->blend_state) {
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LOGIC_OP_EXT;
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT;
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT;
if (screen->info.feats.features.alphaToOne)
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT;
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT;
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT;
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT;
}
}
}
if (screen->info.have_EXT_color_write_enable)
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT;
@ -454,32 +458,12 @@ zink_create_gfx_pipeline_output(struct zink_screen *screen, struct zink_gfx_pipe
VkPipelineColorBlendStateCreateInfo blend_state = {0};
blend_state.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
if (state->blend_state) {
unsigned num_attachments = state->rendering_info.colorAttachmentCount;
blend_state.pAttachments = state->blend_state->attachments;
blend_state.attachmentCount = num_attachments;
blend_state.logicOpEnable = state->blend_state->logicop_enable;
blend_state.attachmentCount = state->rendering_info.colorAttachmentCount;
if (state->blend_state)
blend_state.logicOp = state->blend_state->logicop_func;
}
VkPipelineMultisampleStateCreateInfo ms_state = {0};
ms_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
ms_state.rasterizationSamples = state->rast_samples + 1;
if (state->blend_state) {
ms_state.alphaToCoverageEnable = state->blend_state->alpha_to_coverage;
if (state->blend_state->alpha_to_one && !screen->info.feats.features.alphaToOne) {
static bool warned = false;
warn_missing_feature(warned, "alphaToOne");
}
ms_state.alphaToOneEnable = state->blend_state->alpha_to_one;
}
/* "If pSampleMask is NULL, it is treated as if the mask has all bits set to 1."
* - Chapter 27. Rasterization
*
* thus it never makes sense to leave this as NULL since gallium will provide correct
* data here as long as sample_mask is initialized on context creation
*/
ms_state.pSampleMask = &state->sample_mask;
if (state->force_persample_interp) {
ms_state.sampleShadingEnable = VK_TRUE;
ms_state.minSampleShading = 1.0;
@ -498,6 +482,48 @@ zink_create_gfx_pipeline_output(struct zink_screen *screen, struct zink_gfx_pipe
}
if (screen->info.have_EXT_color_write_enable)
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT;
if (screen->have_full_ds3) {
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SAMPLE_MASK_EXT;
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT;
if (state->blend_state) {
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LOGIC_OP_EXT;
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT;
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT;
if (screen->info.feats.features.alphaToOne)
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT;
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT;
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT;
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT;
}
} else {
if (state->blend_state) {
unsigned num_attachments = state->render_pass ?
state->render_pass->state.num_rts :
state->rendering_info.colorAttachmentCount;
if (state->render_pass && state->render_pass->state.have_zsbuf)
num_attachments--;
blend_state.pAttachments = state->blend_state->attachments;
blend_state.attachmentCount = num_attachments;
blend_state.logicOpEnable = state->blend_state->logicop_enable;
blend_state.logicOp = state->blend_state->logicop_func;
ms_state.alphaToCoverageEnable = state->blend_state->alpha_to_coverage;
if (state->blend_state->alpha_to_one && !screen->info.feats.features.alphaToOne) {
static bool warned = false;
warn_missing_feature(warned, "alphaToOne");
}
ms_state.alphaToOneEnable = state->blend_state->alpha_to_one;
}
ms_state.rasterizationSamples = state->rast_samples + 1;
/* "If pSampleMask is NULL, it is treated as if the mask has all bits set to 1."
* - Chapter 27. Rasterization
*
* thus it never makes sense to leave this as NULL since gallium will provide correct
* data here as long as sample_mask is initialized on context creation
*/
ms_state.pSampleMask = &state->sample_mask;
}
assert(state_count < ARRAY_SIZE(dynamicStateEnables));
VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo = {0};

View file

@ -2250,6 +2250,15 @@ init_driver_workarounds(struct zink_screen *screen)
!screen->info.dynamic_state3_feats.extendedDynamicState3ProvokingVertexMode ||
!screen->info.dynamic_state3_feats.extendedDynamicState3LineRasterizationMode)
screen->info.have_EXT_extended_dynamic_state3 = false;
else if (screen->info.dynamic_state3_feats.extendedDynamicState3SampleMask &&
screen->info.dynamic_state3_feats.extendedDynamicState3AlphaToCoverageEnable &&
(!screen->info.feats.features.alphaToOne || screen->info.dynamic_state3_feats.extendedDynamicState3AlphaToOneEnable) &&
screen->info.dynamic_state3_feats.extendedDynamicState3ColorBlendEnable &&
screen->info.dynamic_state3_feats.extendedDynamicState3RasterizationSamples &&
screen->info.dynamic_state3_feats.extendedDynamicState3ColorWriteMask &&
screen->info.dynamic_state3_feats.extendedDynamicState3LogicOpEnable &&
screen->info.dynamic_state2_feats.extendedDynamicState2LogicOp)
screen->have_full_ds3 = true;
if (screen->info.have_EXT_graphics_pipeline_library)
screen->info.have_EXT_graphics_pipeline_library = screen->info.have_EXT_extended_dynamic_state &&
screen->info.have_EXT_extended_dynamic_state2 &&

View file

@ -406,6 +406,15 @@ zink_create_blend_state(struct pipe_context *pctx,
att.colorWriteMask |= VK_COLOR_COMPONENT_A_BIT;
cso->attachments[i] = att;
cso->ds3.enables[i] = att.blendEnable;
cso->ds3.eq[i].alphaBlendOp = att.alphaBlendOp;
cso->ds3.eq[i].dstAlphaBlendFactor = att.dstAlphaBlendFactor;
cso->ds3.eq[i].srcAlphaBlendFactor = att.srcAlphaBlendFactor;
cso->ds3.eq[i].colorBlendOp = att.colorBlendOp;
cso->ds3.eq[i].dstColorBlendFactor = att.dstColorBlendFactor;
cso->ds3.eq[i].srcColorBlendFactor = att.srcColorBlendFactor;
cso->ds3.wrmask[i] = att.colorWriteMask;
}
cso->dual_src_blend = util_blend_state_is_dual(blend_state, 0);
@ -422,7 +431,7 @@ zink_bind_blend_state(struct pipe_context *pctx, void *cso)
if (state->blend_state != cso) {
state->blend_state = cso;
state->blend_id = blend ? blend->hash : 0;
state->dirty = true;
state->dirty |= !zink_screen(pctx->screen)->have_full_ds3;
bool force_dual_color_blend = zink_screen(pctx->screen)->driconf.dual_color_blend_by_location &&
blend && blend->dual_src_blend && state->blend_state->attachments[0].blendEnable;
if (force_dual_color_blend != zink_get_fs_key(ctx)->force_dual_color_blend)

View file

@ -56,6 +56,7 @@ zink_cache_vertex_state_destroy(struct pipe_screen *pscreen, struct pipe_vertex_
const struct zink_vertex_elements_hw_state *
zink_vertex_state_mask(struct pipe_vertex_state *vstate, uint32_t partial_velem_mask, bool have_EXT_vertex_input_dynamic_state);
#ifdef __cplusplus
}
#endif

View file

@ -274,6 +274,12 @@ struct zink_blend_state {
uint32_t hash;
VkPipelineColorBlendAttachmentState attachments[PIPE_MAX_COLOR_BUFS];
struct {
VkBool32 enables[PIPE_MAX_COLOR_BUFS];
VkColorBlendEquationEXT eq[PIPE_MAX_COLOR_BUFS];
VkColorComponentFlags wrmask[PIPE_MAX_COLOR_BUFS];
} ds3;
VkBool32 logicop_enable;
VkLogicOp logicop_func;
@ -1134,6 +1140,7 @@ struct zink_screen {
struct nir_shader_compiler_options nir_options;
bool optimal_keys;
bool have_full_ds3;
bool have_X8_D24_UNORM_PACK32;
bool have_D24_UNORM_S8_UINT;
bool have_D32_SFLOAT_S8_UINT;
@ -1573,6 +1580,7 @@ struct zink_context {
bool primitive_restart;
bool vertex_state_changed : 1;
bool blend_state_changed : 1;
bool sample_mask_changed : 1;
bool rast_state_changed : 1;
bool dsa_state_changed : 1;
bool stencil_ref_changed : 1;