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;
/* 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);
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;
{
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
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);
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;
#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,
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,
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;
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;
}
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};
!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 &&
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);
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)
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
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;
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;
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;