bool in_rp = ctx->batch.in_rp;
uint64_t tc_data = ctx->dynamic_fb.tc_info.data;
bool queries_disabled = ctx->queries_disabled;
+ unsigned ds3_states = ctx->ds3_states;
if (ctx->unordered_blitting) {
/* for unordered blit, swap the unordered cmdbuf for the main one for the whole op to avoid conditional hell */
ctx->batch.state->cmdbuf = ctx->batch.state->barrier_cmdbuf;
ctx->queries_disabled = true;
ctx->batch.state->has_barriers = true;
ctx->pipeline_changed[0] = true;
+ struct zink_screen *screen = zink_screen(pctx->screen);
+ if (screen->info.have_EXT_extended_dynamic_state3) {
+ if (screen->have_full_ds3)
+ ctx->ds3_states = UINT32_MAX;
+ else
+ ctx->ds3_states = BITFIELD_MASK(ZINK_DS3_BLEND_A2C);
+ if (!screen->info.dynamic_state3_feats.extendedDynamicState3AlphaToOneEnable)
+ ctx->ds3_states &= ~BITFIELD_BIT(ZINK_DS3_BLEND_A21);
+ }
zink_select_draw_vbo(ctx);
}
zink_blit_begin(ctx, ZINK_BLIT_SAVE_FB | ZINK_BLIT_SAVE_FS | ZINK_BLIT_SAVE_TEXTURES);
ctx->batch.state->cmdbuf = cmdbuf;
ctx->gfx_pipeline_state.pipeline = pipeline;
ctx->pipeline_changed[0] = true;
+ ctx->ds3_states = ds3_states;
zink_select_draw_vbo(ctx);
}
ctx->unordered_blitting = false;
if (ctx->batch.state->is_device_lost) {
check_device_lost(ctx);
} else {
+ struct zink_screen *screen = zink_screen(ctx->base.screen);
zink_start_batch(ctx, batch);
- if (zink_screen(ctx->base.screen)->info.have_EXT_transform_feedback && ctx->num_so_targets)
+ if (screen->info.have_EXT_transform_feedback && ctx->num_so_targets)
ctx->dirty_so_targets = true;
ctx->pipeline_changed[0] = ctx->pipeline_changed[1] = true;
zink_select_draw_vbo(ctx);
if (ctx->oom_stall)
stall(ctx);
+ if (screen->info.have_EXT_extended_dynamic_state3) {
+ if (screen->have_full_ds3)
+ ctx->ds3_states = UINT32_MAX;
+ else
+ ctx->ds3_states = BITFIELD_MASK(ZINK_DS3_BLEND_A2C);
+ if (!screen->info.dynamic_state3_feats.extendedDynamicState3AlphaToOneEnable)
+ ctx->ds3_states &= ~BITFIELD_BIT(ZINK_DS3_BLEND_A21);
+ }
ctx->oom_flush = false;
ctx->oom_stall = false;
ctx->dd.bindless_bound = false;
/* 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)
+ if (ctx->fb_state.nr_cbufs != state->nr_cbufs) {
ctx->blend_state_changed |= screen->have_full_ds3;
+ if (state->nr_cbufs && screen->have_full_ds3)
+ ctx->ds3_states |= BITFIELD_BIT(ZINK_DS3_BLEND_ON) | BITFIELD_BIT(ZINK_DS3_BLEND_WRITE) | BITFIELD_BIT(ZINK_DS3_BLEND_EQ);
+ }
util_copy_framebuffer_state(&ctx->fb_state, state);
zink_update_fbfetch(ctx);
VKCTX(CmdSetFrontFaceEXT)(batch->state->cmdbuf, (VkFrontFace)ctx->gfx_pipeline_state.dyn_state1.front_face);
VKCTX(CmdSetCullModeEXT)(batch->state->cmdbuf, ctx->gfx_pipeline_state.dyn_state1.cull_mode);
}
- if (!screen->driver_workarounds.no_linestipple && (DYNAMIC_STATE >= ZINK_DYNAMIC_STATE3 || rast_state->base.line_stipple_enable))
- VKCTX(CmdSetLineStippleEXT)(batch->state->cmdbuf, rast_state->base.line_stipple_factor, rast_state->base.line_stipple_pattern);
if (DYNAMIC_STATE >= ZINK_DYNAMIC_STATE3) {
- VKCTX(CmdSetDepthClipEnableEXT)(batch->state->cmdbuf, rast_state->hw_state.depth_clip);
- VKCTX(CmdSetDepthClampEnableEXT)(batch->state->cmdbuf, rast_state->hw_state.depth_clamp);
- VKCTX(CmdSetPolygonModeEXT)(batch->state->cmdbuf, (VkPolygonMode)rast_state->hw_state.polygon_mode);
- VKCTX(CmdSetDepthClipNegativeOneToOneEXT)(batch->state->cmdbuf, !rast_state->hw_state.clip_halfz);
- VKCTX(CmdSetProvokingVertexModeEXT)(batch->state->cmdbuf, rast_state->hw_state.pv_last ?
- VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT :
- VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT);
- VKCTX(CmdSetLineRasterizationModeEXT)(batch->state->cmdbuf, rast_state->dynamic_line_mode);
- if (screen->info.dynamic_state3_feats.extendedDynamicState3LineStippleEnable)
+ if (ctx->ds3_states & BITFIELD_BIT(ZINK_DS3_RAST_STIPPLE))
+ VKCTX(CmdSetLineStippleEXT)(batch->state->cmdbuf, rast_state->base.line_stipple_factor, rast_state->base.line_stipple_pattern);
+ if (ctx->ds3_states & BITFIELD_BIT(ZINK_DS3_RAST_CLIP))
+ VKCTX(CmdSetDepthClipEnableEXT)(batch->state->cmdbuf, rast_state->hw_state.depth_clip);
+ if (ctx->ds3_states & BITFIELD_BIT(ZINK_DS3_RAST_CLAMP))
+ VKCTX(CmdSetDepthClampEnableEXT)(batch->state->cmdbuf, rast_state->hw_state.depth_clamp);
+ if (ctx->ds3_states & BITFIELD_BIT(ZINK_DS3_RAST_POLYGON))
+ VKCTX(CmdSetPolygonModeEXT)(batch->state->cmdbuf, (VkPolygonMode)rast_state->hw_state.polygon_mode);
+ if (ctx->ds3_states & BITFIELD_BIT(ZINK_DS3_RAST_HALFZ))
+ VKCTX(CmdSetDepthClipNegativeOneToOneEXT)(batch->state->cmdbuf, !rast_state->hw_state.clip_halfz);
+ if (ctx->ds3_states & BITFIELD_BIT(ZINK_DS3_RAST_PV))
+ VKCTX(CmdSetProvokingVertexModeEXT)(batch->state->cmdbuf,
+ rast_state->hw_state.pv_last ?
+ VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT :
+ VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT);
+ if (ctx->ds3_states & BITFIELD_BIT(ZINK_DS3_RAST_CLIP))
+ VKCTX(CmdSetLineRasterizationModeEXT)(batch->state->cmdbuf, rast_state->dynamic_line_mode);
+ if (ctx->ds3_states & BITFIELD_BIT(ZINK_DS3_RAST_STIPPLE_ON))
VKCTX(CmdSetLineStippleEnableEXT)(batch->state->cmdbuf, rast_state->hw_state.line_stipple_enable);
}
}
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 ((BATCH_CHANGED || ctx->blend_state_changed)) {
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)
+ if (ctx->ds3_states & BITFIELD_BIT(ZINK_DS3_BLEND_A2C))
+ VKCTX(CmdSetAlphaToCoverageEnableEXT)(batch->state->cmdbuf, ctx->gfx_pipeline_state.blend_state->alpha_to_coverage);
+ if (ctx->ds3_states & BITFIELD_BIT(ZINK_DS3_BLEND_A21))
VKCTX(CmdSetAlphaToOneEnableEXT)(batch->state->cmdbuf, ctx->gfx_pipeline_state.blend_state->alpha_to_one);
if (ctx->fb_state.nr_cbufs) {
- 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);
+ if (ctx->ds3_states & BITFIELD_BIT(ZINK_DS3_BLEND_ON))
+ VKCTX(CmdSetColorBlendEnableEXT)(batch->state->cmdbuf, 0, ctx->fb_state.nr_cbufs, ctx->gfx_pipeline_state.blend_state->ds3.enables);
+ if (ctx->ds3_states & BITFIELD_BIT(ZINK_DS3_BLEND_WRITE))
+ VKCTX(CmdSetColorWriteMaskEXT)(batch->state->cmdbuf, 0, ctx->fb_state.nr_cbufs, ctx->gfx_pipeline_state.blend_state->ds3.wrmask);
+ if (ctx->ds3_states & BITFIELD_BIT(ZINK_DS3_BLEND_EQ))
+ 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 (ctx->ds3_states & BITFIELD_BIT(ZINK_DS3_BLEND_LOGIC_ON))
+ VKCTX(CmdSetLogicOpEnableEXT)(batch->state->cmdbuf, ctx->gfx_pipeline_state.blend_state->logicop_enable);
+ if (ctx->ds3_states & BITFIELD_BIT(ZINK_DS3_BLEND_LOGIC))
+ VKCTX(CmdSetLogicOpEXT)(batch->state->cmdbuf, ctx->gfx_pipeline_state.blend_state->logicop_func);
}
}
+ ctx->ds3_states = 0;
if (BATCH_CHANGED ||
/* only re-emit on non-batch change when actually drawing lines */
*/
cso->alpha_to_coverage = blend_state->alpha_to_coverage;
cso->alpha_to_one = blend_state->alpha_to_one;
+ cso->num_rts = blend_state->max_rt + 1;
for (int i = 0; i < blend_state->max_rt + 1; ++i) {
const struct pipe_rt_blend_state *rt = blend_state->rt;
if (rt->colormask & PIPE_MASK_A)
att.colorWriteMask |= VK_COLOR_COMPONENT_A_BIT;
+ cso->wrmask |= (rt->colormask << i);
+ if (rt->blend_enable)
+ cso->enables |= BITFIELD_BIT(i);
+
cso->attachments[i] = att;
cso->ds3.enables[i] = att.blendEnable;
struct zink_gfx_pipeline_state* state = &zink_context(pctx)->gfx_pipeline_state;
zink_flush_dgc_if_enabled(ctx);
struct zink_blend_state *blend = cso;
+ struct zink_blend_state *old_blend = state->blend_state;
if (state->blend_state != cso) {
state->blend_state = cso;
if (force_dual_color_blend != zink_get_fs_base_key(ctx)->force_dual_color_blend)
zink_set_fs_base_key(ctx)->force_dual_color_blend = force_dual_color_blend;
ctx->blend_state_changed = true;
+
+ if (cso && screen->have_full_ds3) {
+#define STATE_CHECK(NAME, FLAG) \
+ if ((!old_blend || old_blend->NAME != blend->NAME)) \
+ ctx->ds3_states |= BITFIELD_BIT(ZINK_DS3_BLEND_##FLAG)
+
+ STATE_CHECK(alpha_to_coverage, A2C);
+ if (screen->info.dynamic_state3_feats.extendedDynamicState3AlphaToOneEnable) {
+ STATE_CHECK(alpha_to_one, A21);
+ }
+ STATE_CHECK(enables, ON);
+ STATE_CHECK(wrmask, WRITE);
+ if (old_blend && blend->num_rts == old_blend->num_rts) {
+ if (memcmp(blend->ds3.eq, old_blend->ds3.eq, blend->num_rts * sizeof(blend->ds3.eq[0])))
+ ctx->ds3_states |= BITFIELD_BIT(ZINK_DS3_BLEND_EQ);
+ } else {
+ ctx->ds3_states |= BITFIELD_BIT(ZINK_DS3_BLEND_EQ);
+ }
+ STATE_CHECK(logicop_enable, LOGIC_ON);
+ STATE_CHECK(logicop_func, LOGIC);
+
+#undef STATE_CHECK
+ }
+
}
}
{
struct zink_context *ctx = zink_context(pctx);
struct zink_screen *screen = zink_screen(pctx->screen);
+ struct zink_rasterizer_state *prev_state = ctx->rast_state;
bool point_quad_rasterization = ctx->rast_state ? ctx->rast_state->base.point_quad_rasterization : false;
bool scissor = ctx->rast_state ? ctx->rast_state->base.scissor : false;
bool pv_last = ctx->rast_state ? ctx->rast_state->hw_state.pv_last : false;
ctx->vp_state_changed = true;
}
+ if (screen->info.have_EXT_extended_dynamic_state3) {
+#define STATE_CHECK(NAME, FLAG) \
+ if (cso && (!prev_state || prev_state->NAME != ctx->rast_state->NAME)) \
+ ctx->ds3_states |= BITFIELD_BIT(ZINK_DS3_RAST_##FLAG)
+
+ if (!screen->driver_workarounds.no_linestipple) {
+ if (ctx->rast_state->base.line_stipple_enable) {
+ STATE_CHECK(base.line_stipple_factor, STIPPLE);
+ STATE_CHECK(base.line_stipple_pattern, STIPPLE);
+ } else {
+ ctx->ds3_states &= ~BITFIELD_BIT(ZINK_DS3_RAST_STIPPLE);
+ }
+ if (screen->info.dynamic_state3_feats.extendedDynamicState3LineStippleEnable) {
+ STATE_CHECK(hw_state.line_stipple_enable, STIPPLE_ON);
+ }
+ }
+ STATE_CHECK(hw_state.depth_clip, CLIP);
+ STATE_CHECK(hw_state.depth_clamp, CLAMP);
+ STATE_CHECK(hw_state.polygon_mode, POLYGON);
+ STATE_CHECK(hw_state.clip_halfz, HALFZ);
+ STATE_CHECK(hw_state.pv_last, PV);
+ STATE_CHECK(dynamic_line_mode, LINE);
+
+#undef STATE_CHECK
+ }
+
if (fabs(ctx->rast_state->base.line_width - line_width) > FLT_EPSILON)
ctx->line_width_changed = true;
struct zink_blend_state {
uint32_t hash;
+ unsigned num_rts;
VkPipelineColorBlendAttachmentState attachments[PIPE_MAX_COLOR_BUFS];
struct {
VkBool32 alpha_to_coverage;
VkBool32 alpha_to_one;
+ uint32_t wrmask;
+ uint8_t enables;
+
bool dual_src_blend;
};
unsigned num_draws);
typedef void (*pipe_launch_grid_func)(struct pipe_context *pipe, const struct pipe_grid_info *info);
+
+enum zink_ds3_state {
+ ZINK_DS3_RAST_STIPPLE,
+ ZINK_DS3_RAST_CLIP,
+ ZINK_DS3_RAST_CLAMP,
+ ZINK_DS3_RAST_POLYGON,
+ ZINK_DS3_RAST_HALFZ,
+ ZINK_DS3_RAST_PV,
+ ZINK_DS3_RAST_LINE,
+ ZINK_DS3_RAST_STIPPLE_ON,
+ ZINK_DS3_BLEND_A2C,
+ ZINK_DS3_BLEND_A21,
+ ZINK_DS3_BLEND_ON,
+ ZINK_DS3_BLEND_WRITE,
+ ZINK_DS3_BLEND_EQ,
+ ZINK_DS3_BLEND_LOGIC_ON,
+ ZINK_DS3_BLEND_LOGIC,
+};
+
struct zink_context {
struct pipe_context base;
struct threaded_context *tc;
uint8_t barrier_set_idx[2];
unsigned memory_barrier;
+ uint32_t ds3_states;
+
uint32_t num_so_targets;
struct pipe_stream_output_target *so_targets[PIPE_MAX_SO_OUTPUTS];
bool dirty_so_targets;