v3dv: port dynamic state tracking to use Mesa Vulkan

Specifically to use the common vk_dynamic_graphics_state.

The advantage of using the common struct is not only reducing the size
of our custom one, but also using common helpers (like all those cmd
buffer setters), and a lot of the logic that in the future will be
used for other extensions.

Some notes:

 * We still keep dirty flags, for things like PIPELINE,
   DESCRIPTOR_SETS, etc. Other driver do the same. FWIW, this is also
   an improvement, as before we were mixing those with the per-spec
   Vulkan dynamic info.

 * For the port viewport/scissor we still keep some data on a custom
   structure, as we cache the translate/scale info that is derived
   from scissor/viewport, but used in three different places.

   For that we also maintain a custom implementation of
   CmdSetViewport, that computes translate/scale, and call the common
   implementation.

 * We make the same for color_write_enables. The vulkan runtime saves
   it as a 8-bit bitset, with a bit per attachment. But when combining
   with color_write_mask you need a 32bit with 4 bits set per
   attachment. To avoid recompute it during emission, we also cache
   the color_write_enables, using the runtime just to track the dirty
   status.

Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27609>
This commit is contained in:
Alejandro Piñeiro
2024-02-01 12:39:12 +01:00
committed by Marge Bot
parent 858154b84e
commit f2236065b7
8 changed files with 342 additions and 613 deletions

View File

@@ -31,7 +31,7 @@ float
v3dv_get_aa_line_width(struct v3dv_pipeline *pipeline,
struct v3dv_cmd_buffer *buffer)
{
float width = buffer->state.dynamic.line_width;
float width = buffer->vk.dynamic_graphics_state.rs.line.width;
/* If line smoothing is enabled then we want to add some extra pixels to
* the width in order to have some semi-transparent edges.
@@ -833,6 +833,7 @@ v3dv_job_init(struct v3dv_job *job,
*/
cmd_buffer->state.dirty = ~0;
cmd_buffer->state.dirty_descriptor_stages = ~0;
vk_dynamic_graphics_state_dirty_all(&cmd_buffer->vk.dynamic_graphics_state);
/* Honor inheritance of occlusion queries in secondaries if requested */
if (cmd_buffer->vk.level == VK_COMMAND_BUFFER_LEVEL_SECONDARY &&
@@ -1361,8 +1362,11 @@ cmd_buffer_ensure_render_pass_attachment_state(struct v3dv_cmd_buffer *cmd_buffe
* to emit a new clip window to constraint it to the render area.
*/
static void
constraint_clip_window_to_render_area(struct v3dv_cmd_buffer_state *state)
constraint_clip_window_to_render_area(struct v3dv_cmd_buffer *cmd_buffer)
{
struct v3dv_cmd_buffer_state *state = &cmd_buffer->state;
struct vk_dynamic_graphics_state *dyn = &cmd_buffer->vk.dynamic_graphics_state;
uint32_t min_render_x = state->render_area.offset.x;
uint32_t min_render_y = state->render_area.offset.y;
uint32_t max_render_x = min_render_x + state->render_area.extent.width - 1;
@@ -1373,7 +1377,7 @@ constraint_clip_window_to_render_area(struct v3dv_cmd_buffer_state *state)
uint32_t max_clip_y = min_clip_y + state->clip_window.extent.height - 1;
if (min_render_x > min_clip_x || min_render_y > min_clip_y ||
max_render_x < max_clip_x || max_render_y < max_clip_y) {
state->dirty |= V3DV_CMD_DIRTY_SCISSOR;
BITSET_SET(dyn->dirty, MESA_VK_DYNAMIC_VP_SCISSORS);
}
}
@@ -1396,7 +1400,7 @@ v3dv_CmdBeginRenderPass2(VkCommandBuffer commandBuffer,
cmd_buffer_init_render_pass_attachment_state(cmd_buffer, pRenderPassBegin);
state->render_area = pRenderPassBegin->renderArea;
constraint_clip_window_to_render_area(state);
constraint_clip_window_to_render_area(cmd_buffer);
/* Setup for first subpass */
v3dv_cmd_buffer_subpass_start(cmd_buffer, 0);
@@ -2096,108 +2100,36 @@ v3dv_CmdExecuteCommands(VkCommandBuffer commandBuffer,
}
}
/* This goes though the list of possible dynamic states in the pipeline and,
* for those that are not configured as dynamic, copies relevant state into
* the command buffer.
static void
cmd_buffer_copy_private_dynamic_state(struct v3dv_dynamic_state *dst,
struct v3dv_dynamic_state *src,
struct vk_dynamic_graphics_state *src_dyn)
{
if (BITSET_TEST(src_dyn->set, MESA_VK_DYNAMIC_VP_VIEWPORTS)) {
typed_memcpy(dst->viewport.scale, src->viewport.scale,
MAX_VIEWPORTS);
typed_memcpy(dst->viewport.translate, src->viewport.translate,
MAX_VIEWPORTS);
}
if (BITSET_TEST(src_dyn->set, MESA_VK_DYNAMIC_CB_COLOR_WRITE_ENABLES))
dst->color_write_enable = src->color_write_enable;
}
/* This function copies relevant static state from the pipeline to the command
* buffer state.
*
* Notice the Vulkan runtime uses the term 'dynamic' to refer to all state
* that *could* be dynamic, even if it is not dynamic for a particular
* pipeline, so the terminology used in the runtime may be a bit misleading.
*/
static void
cmd_buffer_bind_pipeline_static_state(struct v3dv_cmd_buffer *cmd_buffer,
const struct v3dv_dynamic_state *src)
struct v3dv_pipeline *pipeline)
{
struct v3dv_dynamic_state *dest = &cmd_buffer->state.dynamic;
uint32_t dynamic_mask = src->mask;
uint32_t dirty = 0;
vk_cmd_set_dynamic_graphics_state(&cmd_buffer->vk, &pipeline->dynamic_graphics_state);
cmd_buffer_copy_private_dynamic_state(&cmd_buffer->state.dynamic, &pipeline->dynamic,
&pipeline->dynamic_graphics_state);
if (!(dynamic_mask & V3DV_DYNAMIC_VIEWPORT)) {
dest->viewport.count = src->viewport.count;
if (memcmp(&dest->viewport.viewports, &src->viewport.viewports,
src->viewport.count * sizeof(VkViewport))) {
typed_memcpy(dest->viewport.viewports,
src->viewport.viewports,
src->viewport.count);
typed_memcpy(dest->viewport.scale, src->viewport.scale,
src->viewport.count);
typed_memcpy(dest->viewport.translate, src->viewport.translate,
src->viewport.count);
dirty |= V3DV_CMD_DIRTY_VIEWPORT;
}
}
if (!(dynamic_mask & V3DV_DYNAMIC_SCISSOR)) {
dest->scissor.count = src->scissor.count;
if (memcmp(&dest->scissor.scissors, &src->scissor.scissors,
src->scissor.count * sizeof(VkRect2D))) {
typed_memcpy(dest->scissor.scissors,
src->scissor.scissors, src->scissor.count);
dirty |= V3DV_CMD_DIRTY_SCISSOR;
}
}
if (!(dynamic_mask & V3DV_DYNAMIC_STENCIL_COMPARE_MASK)) {
if (memcmp(&dest->stencil_compare_mask, &src->stencil_compare_mask,
sizeof(src->stencil_compare_mask))) {
dest->stencil_compare_mask = src->stencil_compare_mask;
dirty |= V3DV_CMD_DIRTY_STENCIL_COMPARE_MASK;
}
}
if (!(dynamic_mask & V3DV_DYNAMIC_STENCIL_WRITE_MASK)) {
if (memcmp(&dest->stencil_write_mask, &src->stencil_write_mask,
sizeof(src->stencil_write_mask))) {
dest->stencil_write_mask = src->stencil_write_mask;
dirty |= V3DV_CMD_DIRTY_STENCIL_WRITE_MASK;
}
}
if (!(dynamic_mask & V3DV_DYNAMIC_STENCIL_REFERENCE)) {
if (memcmp(&dest->stencil_reference, &src->stencil_reference,
sizeof(src->stencil_reference))) {
dest->stencil_reference = src->stencil_reference;
dirty |= V3DV_CMD_DIRTY_STENCIL_REFERENCE;
}
}
if (!(dynamic_mask & V3DV_DYNAMIC_BLEND_CONSTANTS)) {
if (memcmp(dest->blend_constants, src->blend_constants,
sizeof(src->blend_constants))) {
memcpy(dest->blend_constants, src->blend_constants,
sizeof(src->blend_constants));
dirty |= V3DV_CMD_DIRTY_BLEND_CONSTANTS;
}
}
if (!(dynamic_mask & V3DV_DYNAMIC_DEPTH_BIAS)) {
if (memcmp(&dest->depth_bias, &src->depth_bias,
sizeof(src->depth_bias))) {
memcpy(&dest->depth_bias, &src->depth_bias, sizeof(src->depth_bias));
dirty |= V3DV_CMD_DIRTY_DEPTH_BIAS;
}
}
if (!(dynamic_mask & V3DV_DYNAMIC_DEPTH_BOUNDS)) {
if (memcmp(&dest->depth_bounds, &src->depth_bounds,
sizeof(src->depth_bounds))) {
memcpy(&dest->depth_bounds, &src->depth_bounds, sizeof(src->depth_bounds));
dirty |= V3DV_CMD_DIRTY_DEPTH_BOUNDS;
}
}
if (!(dynamic_mask & V3DV_DYNAMIC_LINE_WIDTH)) {
if (dest->line_width != src->line_width) {
dest->line_width = src->line_width;
dirty |= V3DV_CMD_DIRTY_LINE_WIDTH;
}
}
if (!(dynamic_mask & V3DV_DYNAMIC_COLOR_WRITE_ENABLE)) {
if (dest->color_write_enable != src->color_write_enable) {
dest->color_write_enable = src->color_write_enable;
dirty |= V3DV_CMD_DIRTY_COLOR_WRITE_ENABLE;
}
}
cmd_buffer->state.dynamic.mask = dynamic_mask;
cmd_buffer->state.dirty |= dirty;
}
static void
@@ -2210,13 +2142,12 @@ bind_graphics_pipeline(struct v3dv_cmd_buffer *cmd_buffer,
* could have changed (through calls to vkCmdSetXXX) between bindings of
* the same pipeline.
*/
cmd_buffer_bind_pipeline_static_state(cmd_buffer, &pipeline->dynamic_state);
cmd_buffer_bind_pipeline_static_state(cmd_buffer, pipeline);
if (cmd_buffer->state.gfx.pipeline == pipeline)
return;
cmd_buffer->state.gfx.pipeline = pipeline;
cmd_buffer->state.dirty |= V3DV_CMD_DIRTY_PIPELINE;
}
@@ -2261,18 +2192,19 @@ v3dv_CmdBindPipeline(VkCommandBuffer commandBuffer,
* and scale parameters.
*/
void
v3dv_cmd_buffer_state_get_viewport_z_xform(struct v3dv_cmd_buffer_state *state,
v3dv_cmd_buffer_state_get_viewport_z_xform(struct v3dv_cmd_buffer *cmd_buffer,
uint32_t vp_idx,
float *translate_z, float *scale_z)
{
const struct v3dv_viewport_state *vp_state = &state->dynamic.viewport;
const struct v3dv_viewport_state *vp_state = &cmd_buffer->state.dynamic.viewport;
const struct vk_viewport_state *vk_vp_state = &cmd_buffer->vk.dynamic_graphics_state.vp;
float t = vp_state->translate[vp_idx][2];
float s = vp_state->scale[vp_idx][2];
assert(state->gfx.pipeline);
if (state->gfx.pipeline->negative_one_to_one) {
t = (t + vp_state->viewports[vp_idx].maxDepth) * 0.5f;
assert(cmd_buffer->state.gfx.pipeline);
if (cmd_buffer->state.gfx.pipeline->negative_one_to_one) {
t = (t + vk_vp_state->viewports[vp_idx].maxDepth) * 0.5f;
s *= 0.5f;
}
@@ -2283,6 +2215,38 @@ v3dv_cmd_buffer_state_get_viewport_z_xform(struct v3dv_cmd_buffer_state *state,
*scale_z = s;
}
VKAPI_ATTR void VKAPI_CALL
v3dv_CmdSetColorWriteEnableEXT(VkCommandBuffer commandBuffer,
uint32_t attachmentCount,
const VkBool32 *pColorWriteEnables)
{
V3DV_FROM_HANDLE(v3dv_cmd_buffer, cmd_buffer, commandBuffer);
struct v3dv_dynamic_state *v3dv_dyn = &cmd_buffer->state.dynamic;
struct vk_dynamic_graphics_state *dyn = &cmd_buffer->vk.dynamic_graphics_state;
uint32_t color_write_enable = 0;
/* Vulkan runtime computes color_write_enable as an 8-bit bitset, setting a
* bit per attachment. But when emitting, it is combined with the
* color_write_mask, that is stored as a 32-bit mask (one bit per channel,
* per attachment). So we store the color_write_enable as a 32-bit mask
* ourselves.
*/
for (uint32_t i = 0; i < attachmentCount; i++)
color_write_enable |= pColorWriteEnables[i] ? (0xfu << (i * 4)) : 0;
if (v3dv_dyn->color_write_enable == color_write_enable)
return;
v3dv_dyn->color_write_enable = color_write_enable;
BITSET_SET(dyn->set, MESA_VK_DYNAMIC_CB_COLOR_WRITE_ENABLES);
BITSET_SET(dyn->dirty, MESA_VK_DYNAMIC_CB_COLOR_WRITE_ENABLES);
}
/* We keep a custom CmdSetViewport because we want to cache the outcome of
* viewport_compute_xform, and because we need to set the viewport count. This
* is specially relevant to our case because we are pushing/popping the
* dynamic state as part of the meta operations.
*/
VKAPI_ATTR void VKAPI_CALL
v3dv_CmdSetViewport(VkCommandBuffer commandBuffer,
uint32_t firstViewport,
@@ -2290,64 +2254,47 @@ v3dv_CmdSetViewport(VkCommandBuffer commandBuffer,
const VkViewport *pViewports)
{
V3DV_FROM_HANDLE(v3dv_cmd_buffer, cmd_buffer, commandBuffer);
struct v3dv_cmd_buffer_state *state = &cmd_buffer->state;
const uint32_t total_count = firstViewport + viewportCount;
struct v3dv_dynamic_state *v3dv_dyn = &cmd_buffer->state.dynamic;
struct vk_dynamic_graphics_state *dyn = &cmd_buffer->vk.dynamic_graphics_state;
const uint32_t total_count = firstViewport + viewportCount;
assert(firstViewport < MAX_VIEWPORTS);
assert(total_count >= 1 && total_count <= MAX_VIEWPORTS);
if (state->dynamic.viewport.count < total_count)
state->dynamic.viewport.count = total_count;
if (!memcmp(state->dynamic.viewport.viewports + firstViewport,
pViewports, viewportCount * sizeof(*pViewports))) {
return;
}
memcpy(state->dynamic.viewport.viewports + firstViewport, pViewports,
viewportCount * sizeof(*pViewports));
vk_common_CmdSetViewportWithCount(commandBuffer,
total_count,
pViewports);
for (uint32_t i = firstViewport; i < total_count; i++) {
v3dv_X(cmd_buffer->device, viewport_compute_xform)
(&state->dynamic.viewport.viewports[i],
state->dynamic.viewport.scale[i],
state->dynamic.viewport.translate[i]);
(&dyn->vp.viewports[i], v3dv_dyn->viewport.scale[i],
v3dv_dyn->viewport.translate[i]);
}
cmd_buffer->state.dirty |= V3DV_CMD_DIRTY_VIEWPORT;
}
/* We keep a custom CmdSetScissor because we need to set the scissor
* count. This is specially relevant to our case because we are
* pushing/popping the dynamic state as part of the meta operations.
*/
VKAPI_ATTR void VKAPI_CALL
v3dv_CmdSetScissor(VkCommandBuffer commandBuffer,
uint32_t firstScissor,
uint32_t scissorCount,
const VkRect2D *pScissors)
{
V3DV_FROM_HANDLE(v3dv_cmd_buffer, cmd_buffer, commandBuffer);
struct v3dv_cmd_buffer_state *state = &cmd_buffer->state;
assert(firstScissor < MAX_SCISSORS);
assert(firstScissor + scissorCount >= 1 &&
firstScissor + scissorCount <= MAX_SCISSORS);
if (state->dynamic.scissor.count < firstScissor + scissorCount)
state->dynamic.scissor.count = firstScissor + scissorCount;
if (!memcmp(state->dynamic.scissor.scissors + firstScissor,
pScissors, scissorCount * sizeof(*pScissors))) {
return;
}
memcpy(state->dynamic.scissor.scissors + firstScissor, pScissors,
scissorCount * sizeof(*pScissors));
cmd_buffer->state.dirty |= V3DV_CMD_DIRTY_SCISSOR;
vk_common_CmdSetScissorWithCount(commandBuffer,
firstScissor + scissorCount,
pScissors);
}
static void
emit_scissor(struct v3dv_cmd_buffer *cmd_buffer)
{
if (cmd_buffer->state.dynamic.viewport.count == 0)
if (cmd_buffer->vk.dynamic_graphics_state.vp.viewport_count == 0)
return;
struct v3dv_dynamic_state *dynamic = &cmd_buffer->state.dynamic;
@@ -2398,8 +2345,10 @@ emit_scissor(struct v3dv_cmd_buffer *cmd_buffer)
* FIXME: right now we only allow one scissor. Below would need to be
* updated if we support more
*/
if (dynamic->scissor.count > 0) {
VkRect2D *scissor = &dynamic->scissor.scissors[0];
struct vk_dynamic_graphics_state *vk_dyn =
&cmd_buffer->vk.dynamic_graphics_state;
if (vk_dyn->vp.scissor_count > 0) {
VkRect2D *scissor = &vk_dyn->vp.scissors[0];
minx = MAX2(minx, scissor->offset.x);
miny = MAX2(miny, scissor->offset.y);
maxx = MIN2(maxx, scissor->offset.x + scissor->extent.width);
@@ -2422,12 +2371,11 @@ emit_scissor(struct v3dv_cmd_buffer *cmd_buffer)
v3dv_X(cmd_buffer->device, job_emit_clip_window)
(cmd_buffer->state.job, &cmd_buffer->state.clip_window);
cmd_buffer->state.dirty &= ~V3DV_CMD_DIRTY_SCISSOR;
BITSET_CLEAR(vk_dyn->dirty, MESA_VK_DYNAMIC_VP_SCISSORS);
}
static void
update_gfx_uniform_state(struct v3dv_cmd_buffer *cmd_buffer,
uint32_t dirty_uniform_state)
static bool
update_gfx_uniform_state(struct v3dv_cmd_buffer *cmd_buffer)
{
/* We need to update uniform streams if any piece of state that is passed
* to the shader as a uniform may have changed.
@@ -2435,16 +2383,29 @@ update_gfx_uniform_state(struct v3dv_cmd_buffer *cmd_buffer,
* If only descriptor sets are dirty then we can safely ignore updates
* for shader stages that don't access descriptors.
*/
struct v3dv_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
assert(pipeline);
uint32_t dirty = cmd_buffer->state.dirty;
struct vk_dynamic_graphics_state *dyn =
&cmd_buffer->vk.dynamic_graphics_state;
const bool has_new_pipeline = dirty_uniform_state & V3DV_CMD_DIRTY_PIPELINE;
const bool has_new_viewport = dirty_uniform_state & V3DV_CMD_DIRTY_VIEWPORT;
const bool has_new_push_constants = dirty_uniform_state & V3DV_CMD_DIRTY_PUSH_CONSTANTS;
const bool has_new_descriptors = dirty_uniform_state & V3DV_CMD_DIRTY_DESCRIPTOR_SETS;
const bool has_new_view_index = dirty_uniform_state & V3DV_CMD_DIRTY_VIEW_INDEX;
const bool has_new_draw_id = dirty_uniform_state & V3DV_CMD_DIRTY_DRAW_ID;
const bool dirty_uniform_state =
(dirty & (V3DV_CMD_DIRTY_PIPELINE |
V3DV_CMD_DIRTY_PUSH_CONSTANTS |
V3DV_CMD_DIRTY_DESCRIPTOR_SETS |
V3DV_CMD_DIRTY_VIEW_INDEX |
V3DV_CMD_DIRTY_DRAW_ID)) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_VP_VIEWPORTS);
if (!dirty_uniform_state)
return false;
const bool has_new_pipeline = dirty & V3DV_CMD_DIRTY_PIPELINE;
const bool has_new_viewport = BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_VP_VIEWPORTS);
const bool has_new_push_constants = dirty & V3DV_CMD_DIRTY_PUSH_CONSTANTS;
const bool has_new_descriptors = dirty & V3DV_CMD_DIRTY_DESCRIPTOR_SETS;
const bool has_new_view_index = dirty & V3DV_CMD_DIRTY_VIEW_INDEX;
const bool has_new_draw_id = dirty & V3DV_CMD_DIRTY_DRAW_ID;
/* VK_SHADER_STAGE_FRAGMENT_BIT */
const bool has_new_descriptors_fs =
@@ -2533,6 +2494,8 @@ update_gfx_uniform_state(struct v3dv_cmd_buffer *cmd_buffer,
cmd_buffer->state.dirty &= ~V3DV_CMD_DIRTY_VIEW_INDEX;
cmd_buffer->state.dirty &= ~V3DV_CMD_DIRTY_DRAW_ID;
return true;
}
/* This stores command buffer state that we might be about to stomp for
@@ -2589,6 +2552,8 @@ v3dv_cmd_buffer_meta_state_push(struct v3dv_cmd_buffer *cmd_buffer,
* account the graphics pipeline, and the graphics state
*/
state->meta.gfx.pipeline = state->gfx.pipeline;
vk_dynamic_graphics_state_copy(&state->meta.dynamic_graphics_state,
&cmd_buffer->vk.dynamic_graphics_state);
memcpy(&state->meta.dynamic, &state->dynamic, sizeof(state->dynamic));
struct v3dv_descriptor_state *gfx_descriptor_state =
@@ -2659,6 +2624,8 @@ v3dv_cmd_buffer_meta_state_pop(struct v3dv_cmd_buffer *cmd_buffer,
}
/* Restore dynamic state */
vk_dynamic_graphics_state_copy(&cmd_buffer->vk.dynamic_graphics_state,
&state->meta.dynamic_graphics_state);
memcpy(&state->dynamic, &state->meta.dynamic, sizeof(state->dynamic));
state->dirty = ~0;
@@ -3018,17 +2985,10 @@ v3dv_cmd_buffer_emit_pre_draw(struct v3dv_cmd_buffer *cmd_buffer,
* that will require that we new uniform state for QUNIFORM_VIEWPORT_*.
*/
uint32_t *dirty = &cmd_buffer->state.dirty;
struct vk_dynamic_graphics_state *dyn = &cmd_buffer->vk.dynamic_graphics_state;
const uint32_t dirty_uniform_state =
*dirty & (V3DV_CMD_DIRTY_PIPELINE |
V3DV_CMD_DIRTY_PUSH_CONSTANTS |
V3DV_CMD_DIRTY_DESCRIPTOR_SETS |
V3DV_CMD_DIRTY_VIEWPORT |
V3DV_CMD_DIRTY_VIEW_INDEX |
V3DV_CMD_DIRTY_DRAW_ID);
if (dirty_uniform_state)
update_gfx_uniform_state(cmd_buffer, dirty_uniform_state);
const bool dirty_uniform_state =
update_gfx_uniform_state(cmd_buffer);
struct v3dv_device *device = cmd_buffer->device;
@@ -3040,44 +3000,51 @@ v3dv_cmd_buffer_emit_pre_draw(struct v3dv_cmd_buffer *cmd_buffer,
v3dv_X(device, cmd_buffer_emit_varyings_state)(cmd_buffer);
}
if (*dirty & (V3DV_CMD_DIRTY_VIEWPORT | V3DV_CMD_DIRTY_SCISSOR)) {
if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_VP_SCISSORS) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_VP_VIEWPORTS)) {
emit_scissor(cmd_buffer);
}
if (*dirty & V3DV_CMD_DIRTY_VIEWPORT) {
if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_VP_VIEWPORTS))
v3dv_X(device, cmd_buffer_emit_viewport)(cmd_buffer);
}
if (*dirty & V3DV_CMD_DIRTY_INDEX_BUFFER)
v3dv_X(device, cmd_buffer_emit_index_buffer)(cmd_buffer);
const uint32_t dynamic_stencil_dirty_flags =
V3DV_CMD_DIRTY_STENCIL_COMPARE_MASK |
V3DV_CMD_DIRTY_STENCIL_WRITE_MASK |
V3DV_CMD_DIRTY_STENCIL_REFERENCE;
if (*dirty & (V3DV_CMD_DIRTY_PIPELINE | dynamic_stencil_dirty_flags))
bool any_dynamic_stencil_dirty =
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_COMPARE_MASK) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_WRITE_MASK) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE);
if (*dirty & V3DV_CMD_DIRTY_PIPELINE || any_dynamic_stencil_dirty)
v3dv_X(device, cmd_buffer_emit_stencil)(cmd_buffer);
if (*dirty & (V3DV_CMD_DIRTY_PIPELINE | V3DV_CMD_DIRTY_DEPTH_BIAS))
if (*dirty & V3DV_CMD_DIRTY_PIPELINE ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RS_DEPTH_BIAS_FACTORS)) {
v3dv_X(device, cmd_buffer_emit_depth_bias)(cmd_buffer);
}
if (*dirty & V3DV_CMD_DIRTY_DEPTH_BOUNDS)
if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_DEPTH_BOUNDS_TEST_BOUNDS))
v3dv_X(device, cmd_buffer_emit_depth_bounds)(cmd_buffer);
if (*dirty & (V3DV_CMD_DIRTY_PIPELINE | V3DV_CMD_DIRTY_BLEND_CONSTANTS))
if (*dirty & V3DV_CMD_DIRTY_PIPELINE ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_CB_BLEND_CONSTANTS)) {
v3dv_X(device, cmd_buffer_emit_blend)(cmd_buffer);
}
if (*dirty & V3DV_CMD_DIRTY_OCCLUSION_QUERY)
v3dv_X(device, cmd_buffer_emit_occlusion_query)(cmd_buffer);
if (*dirty & V3DV_CMD_DIRTY_LINE_WIDTH)
if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RS_LINE_WIDTH))
v3dv_X(device, cmd_buffer_emit_line_width)(cmd_buffer);
if (*dirty & V3DV_CMD_DIRTY_PIPELINE)
v3dv_X(device, cmd_buffer_emit_sample_state)(cmd_buffer);
if (*dirty & (V3DV_CMD_DIRTY_PIPELINE | V3DV_CMD_DIRTY_COLOR_WRITE_ENABLE))
if (*dirty & V3DV_CMD_DIRTY_PIPELINE ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_CB_COLOR_WRITE_ENABLES)) {
v3dv_X(device, cmd_buffer_emit_color_write_mask)(cmd_buffer);
}
/* We disable double-buffer mode if indirect draws are used because in that
* case we don't know the vertex count.
@@ -3505,77 +3472,6 @@ v3dv_CmdBindIndexBuffer(VkCommandBuffer commandBuffer,
cmd_buffer->state.dirty |= V3DV_CMD_DIRTY_INDEX_BUFFER;
}
VKAPI_ATTR void VKAPI_CALL
v3dv_CmdSetStencilCompareMask(VkCommandBuffer commandBuffer,
VkStencilFaceFlags faceMask,
uint32_t compareMask)
{
V3DV_FROM_HANDLE(v3dv_cmd_buffer, cmd_buffer, commandBuffer);
if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
cmd_buffer->state.dynamic.stencil_compare_mask.front = compareMask & 0xff;
if (faceMask & VK_STENCIL_FACE_BACK_BIT)
cmd_buffer->state.dynamic.stencil_compare_mask.back = compareMask & 0xff;
cmd_buffer->state.dirty |= V3DV_CMD_DIRTY_STENCIL_COMPARE_MASK;
}
VKAPI_ATTR void VKAPI_CALL
v3dv_CmdSetStencilWriteMask(VkCommandBuffer commandBuffer,
VkStencilFaceFlags faceMask,
uint32_t writeMask)
{
V3DV_FROM_HANDLE(v3dv_cmd_buffer, cmd_buffer, commandBuffer);
if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
cmd_buffer->state.dynamic.stencil_write_mask.front = writeMask & 0xff;
if (faceMask & VK_STENCIL_FACE_BACK_BIT)
cmd_buffer->state.dynamic.stencil_write_mask.back = writeMask & 0xff;
cmd_buffer->state.dirty |= V3DV_CMD_DIRTY_STENCIL_WRITE_MASK;
}
VKAPI_ATTR void VKAPI_CALL
v3dv_CmdSetStencilReference(VkCommandBuffer commandBuffer,
VkStencilFaceFlags faceMask,
uint32_t reference)
{
V3DV_FROM_HANDLE(v3dv_cmd_buffer, cmd_buffer, commandBuffer);
if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
cmd_buffer->state.dynamic.stencil_reference.front = reference & 0xff;
if (faceMask & VK_STENCIL_FACE_BACK_BIT)
cmd_buffer->state.dynamic.stencil_reference.back = reference & 0xff;
cmd_buffer->state.dirty |= V3DV_CMD_DIRTY_STENCIL_REFERENCE;
}
VKAPI_ATTR void VKAPI_CALL
v3dv_CmdSetDepthBias(VkCommandBuffer commandBuffer,
float depthBiasConstantFactor,
float depthBiasClamp,
float depthBiasSlopeFactor)
{
V3DV_FROM_HANDLE(v3dv_cmd_buffer, cmd_buffer, commandBuffer);
cmd_buffer->state.dynamic.depth_bias.constant_factor = depthBiasConstantFactor;
cmd_buffer->state.dynamic.depth_bias.depth_bias_clamp = depthBiasClamp;
cmd_buffer->state.dynamic.depth_bias.slope_factor = depthBiasSlopeFactor;
cmd_buffer->state.dirty |= V3DV_CMD_DIRTY_DEPTH_BIAS;
}
VKAPI_ATTR void VKAPI_CALL
v3dv_CmdSetDepthBounds(VkCommandBuffer commandBuffer,
float minDepthBounds,
float maxDepthBounds)
{
V3DV_FROM_HANDLE(v3dv_cmd_buffer, cmd_buffer, commandBuffer);
cmd_buffer->state.dynamic.depth_bounds.min = minDepthBounds;
cmd_buffer->state.dynamic.depth_bounds.max = maxDepthBounds;
cmd_buffer->state.dirty |= V3DV_CMD_DIRTY_DEPTH_BOUNDS;
}
VKAPI_ATTR void VKAPI_CALL
v3dv_CmdSetLineStippleEXT(VkCommandBuffer commandBuffer,
uint32_t lineStippleFactor,
@@ -3584,16 +3480,6 @@ v3dv_CmdSetLineStippleEXT(VkCommandBuffer commandBuffer,
/* We do not support stippled line rasterization so we just ignore this. */
}
VKAPI_ATTR void VKAPI_CALL
v3dv_CmdSetLineWidth(VkCommandBuffer commandBuffer,
float lineWidth)
{
V3DV_FROM_HANDLE(v3dv_cmd_buffer, cmd_buffer, commandBuffer);
cmd_buffer->state.dynamic.line_width = lineWidth;
cmd_buffer->state.dirty |= V3DV_CMD_DIRTY_LINE_WIDTH;
}
/**
* This checks a descriptor set to see if are binding any descriptors that would
* involve sampling from a linear image (the hardware only supports this for
@@ -3983,44 +3869,6 @@ v3dv_CmdPushConstants(VkCommandBuffer commandBuffer,
cmd_buffer->state.dirty_push_constants_stages |= stageFlags;
}
VKAPI_ATTR void VKAPI_CALL
v3dv_CmdSetBlendConstants(VkCommandBuffer commandBuffer,
const float blendConstants[4])
{
V3DV_FROM_HANDLE(v3dv_cmd_buffer, cmd_buffer, commandBuffer);
struct v3dv_cmd_buffer_state *state = &cmd_buffer->state;
if (!memcmp(state->dynamic.blend_constants, blendConstants,
sizeof(state->dynamic.blend_constants))) {
return;
}
memcpy(state->dynamic.blend_constants, blendConstants,
sizeof(state->dynamic.blend_constants));
cmd_buffer->state.dirty |= V3DV_CMD_DIRTY_BLEND_CONSTANTS;
}
VKAPI_ATTR void VKAPI_CALL
v3dv_CmdSetColorWriteEnableEXT(VkCommandBuffer commandBuffer,
uint32_t attachmentCount,
const VkBool32 *pColorWriteEnables)
{
V3DV_FROM_HANDLE(v3dv_cmd_buffer, cmd_buffer, commandBuffer);
struct v3dv_cmd_buffer_state *state = &cmd_buffer->state;
uint32_t color_write_enable = 0;
for (uint32_t i = 0; i < attachmentCount; i++)
color_write_enable |= pColorWriteEnables[i] ? (0xfu << (i * 4)) : 0;
if (state->dynamic.color_write_enable == color_write_enable)
return;
state->dynamic.color_write_enable = color_write_enable;
state->dirty |= V3DV_CMD_DIRTY_COLOR_WRITE_ENABLE;
}
void
v3dv_cmd_buffer_ensure_array_state(struct v3dv_cmd_buffer *cmd_buffer,
uint32_t slot_size,
@@ -4658,8 +4506,7 @@ v3dv_CmdBeginRenderingKHR(VkCommandBuffer commandBuffer,
vk_free(&cmd_buffer->vk.pool->alloc, clear_values);
state->render_area = info->renderArea;
constraint_clip_window_to_render_area(state);
constraint_clip_window_to_render_area(cmd_buffer);
v3dv_cmd_buffer_subpass_start(cmd_buffer, 0);
}

View File

@@ -26,6 +26,7 @@
#include "compiler/nir/nir_builder.h"
#include "util/u_pack_color.h"
#include "vk_common_entrypoints.h"
static void
get_hw_clear_color(struct v3dv_device *device,
@@ -1122,13 +1123,13 @@ emit_subpass_ds_clear_rects(struct v3dv_cmd_buffer *cmd_buffer,
pipeline->pipeline);
if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
v3dv_CmdSetStencilReference(cmd_buffer_handle,
VK_STENCIL_FACE_FRONT_AND_BACK,
clear_ds->stencil);
v3dv_CmdSetStencilWriteMask(cmd_buffer_handle,
VK_STENCIL_FACE_FRONT_AND_BACK, 0xff);
v3dv_CmdSetStencilCompareMask(cmd_buffer_handle,
VK_STENCIL_FACE_FRONT_AND_BACK, 0xff);
vk_common_CmdSetStencilReference(cmd_buffer_handle,
VK_STENCIL_FACE_FRONT_AND_BACK,
clear_ds->stencil);
vk_common_CmdSetStencilWriteMask(cmd_buffer_handle,
VK_STENCIL_FACE_FRONT_AND_BACK, 0xff);
vk_common_CmdSetStencilCompareMask(cmd_buffer_handle,
VK_STENCIL_FACE_FRONT_AND_BACK, 0xff);
}
for (uint32_t i = 0; i < rect_count; i++) {

View File

@@ -2645,145 +2645,6 @@ compute_vpm_config(struct v3dv_pipeline *pipeline)
return VK_SUCCESS;
}
static unsigned
v3dv_dynamic_state_mask(VkDynamicState state)
{
switch(state) {
case VK_DYNAMIC_STATE_VIEWPORT:
return V3DV_DYNAMIC_VIEWPORT;
case VK_DYNAMIC_STATE_SCISSOR:
return V3DV_DYNAMIC_SCISSOR;
case VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK:
return V3DV_DYNAMIC_STENCIL_COMPARE_MASK;
case VK_DYNAMIC_STATE_STENCIL_WRITE_MASK:
return V3DV_DYNAMIC_STENCIL_WRITE_MASK;
case VK_DYNAMIC_STATE_STENCIL_REFERENCE:
return V3DV_DYNAMIC_STENCIL_REFERENCE;
case VK_DYNAMIC_STATE_BLEND_CONSTANTS:
return V3DV_DYNAMIC_BLEND_CONSTANTS;
case VK_DYNAMIC_STATE_DEPTH_BIAS:
return V3DV_DYNAMIC_DEPTH_BIAS;
case VK_DYNAMIC_STATE_LINE_WIDTH:
return V3DV_DYNAMIC_LINE_WIDTH;
case VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT:
return V3DV_DYNAMIC_COLOR_WRITE_ENABLE;
case VK_DYNAMIC_STATE_DEPTH_BOUNDS:
return V3DV_DYNAMIC_DEPTH_BOUNDS;
default:
unreachable("Unhandled dynamic state");
}
}
static void
pipeline_init_dynamic_state(
struct v3dv_pipeline *pipeline,
const VkPipelineDynamicStateCreateInfo *pDynamicState,
const VkPipelineViewportStateCreateInfo *pViewportState,
const VkPipelineDepthStencilStateCreateInfo *pDepthStencilState,
const VkPipelineColorBlendStateCreateInfo *pColorBlendState,
const VkPipelineRasterizationStateCreateInfo *pRasterizationState,
const VkPipelineColorWriteCreateInfoEXT *pColorWriteState)
{
/* Initialize to default values */
const struct v3d_device_info *devinfo = &pipeline->device->devinfo;
struct v3dv_dynamic_state *dynamic = &pipeline->dynamic_state;
memset(dynamic, 0, sizeof(*dynamic));
dynamic->stencil_compare_mask.front = ~0;
dynamic->stencil_compare_mask.back = ~0;
dynamic->stencil_write_mask.front = ~0;
dynamic->stencil_write_mask.back = ~0;
dynamic->line_width = 1.0f;
dynamic->color_write_enable =
(1ull << (4 * V3D_MAX_RENDER_TARGETS(devinfo->ver))) - 1;
dynamic->depth_bounds.max = 1.0f;
/* Create a mask of enabled dynamic states */
uint32_t dynamic_states = 0;
if (pDynamicState) {
uint32_t count = pDynamicState->dynamicStateCount;
for (uint32_t s = 0; s < count; s++) {
dynamic_states |=
v3dv_dynamic_state_mask(pDynamicState->pDynamicStates[s]);
}
}
/* For any pipeline states that are not dynamic, set the dynamic state
* from the static pipeline state.
*/
if (pViewportState) {
if (!(dynamic_states & V3DV_DYNAMIC_VIEWPORT)) {
dynamic->viewport.count = pViewportState->viewportCount;
typed_memcpy(dynamic->viewport.viewports, pViewportState->pViewports,
pViewportState->viewportCount);
for (uint32_t i = 0; i < dynamic->viewport.count; i++) {
v3dv_X(pipeline->device, viewport_compute_xform)
(&dynamic->viewport.viewports[i],
dynamic->viewport.scale[i],
dynamic->viewport.translate[i]);
}
}
if (!(dynamic_states & V3DV_DYNAMIC_SCISSOR)) {
dynamic->scissor.count = pViewportState->scissorCount;
typed_memcpy(dynamic->scissor.scissors, pViewportState->pScissors,
pViewportState->scissorCount);
}
}
if (pDepthStencilState) {
if (!(dynamic_states & V3DV_DYNAMIC_STENCIL_COMPARE_MASK)) {
dynamic->stencil_compare_mask.front =
pDepthStencilState->front.compareMask;
dynamic->stencil_compare_mask.back =
pDepthStencilState->back.compareMask;
}
if (!(dynamic_states & V3DV_DYNAMIC_STENCIL_WRITE_MASK)) {
dynamic->stencil_write_mask.front = pDepthStencilState->front.writeMask;
dynamic->stencil_write_mask.back = pDepthStencilState->back.writeMask;
}
if (!(dynamic_states & V3DV_DYNAMIC_STENCIL_REFERENCE)) {
dynamic->stencil_reference.front = pDepthStencilState->front.reference;
dynamic->stencil_reference.back = pDepthStencilState->back.reference;
}
if (!(dynamic_states & V3DV_DYNAMIC_DEPTH_BOUNDS)) {
dynamic->depth_bounds.min = pDepthStencilState->minDepthBounds;
dynamic->depth_bounds.max = pDepthStencilState->maxDepthBounds;
}
}
if (pColorBlendState && !(dynamic_states & V3DV_DYNAMIC_BLEND_CONSTANTS)) {
memcpy(dynamic->blend_constants, pColorBlendState->blendConstants,
sizeof(dynamic->blend_constants));
}
if (pRasterizationState) {
if (pRasterizationState->depthBiasEnable &&
!(dynamic_states & V3DV_DYNAMIC_DEPTH_BIAS)) {
dynamic->depth_bias.constant_factor =
pRasterizationState->depthBiasConstantFactor;
dynamic->depth_bias.depth_bias_clamp =
pRasterizationState->depthBiasClamp;
dynamic->depth_bias.slope_factor =
pRasterizationState->depthBiasSlopeFactor;
}
if (!(dynamic_states & V3DV_DYNAMIC_LINE_WIDTH))
dynamic->line_width = pRasterizationState->lineWidth;
}
if (pColorWriteState && !(dynamic_states & V3DV_DYNAMIC_COLOR_WRITE_ENABLE)) {
dynamic->color_write_enable = 0;
for (uint32_t i = 0; i < pColorWriteState->attachmentCount; i++)
dynamic->color_write_enable |= pColorWriteState->pColorWriteEnables[i] ? (0xfu << (i * 4)) : 0;
}
pipeline->dynamic_state.mask = dynamic_states;
}
static bool
stencil_op_is_no_op(const VkStencilOpState *stencil)
{
@@ -2965,6 +2826,49 @@ pipeline_setup_rendering_info(struct v3dv_device *device,
};
}
static VkResult
pipeline_init_dynamic_state(struct v3dv_device *device,
struct v3dv_pipeline *pipeline,
struct vk_graphics_pipeline_state *pipeline_state,
const VkGraphicsPipelineCreateInfo *pCreateInfo,
const VkPipelineColorWriteCreateInfoEXT *cw_info)
{
VkResult result = VK_SUCCESS;
struct vk_graphics_pipeline_all_state all;
result = vk_graphics_pipeline_state_fill(&pipeline->device->vk, pipeline_state,
pCreateInfo, &pipeline->rendering_info, 0,
&all, NULL, 0, NULL);
if (result != VK_SUCCESS)
return result;
vk_dynamic_graphics_state_fill(&pipeline->dynamic_graphics_state, pipeline_state);
struct v3dv_dynamic_state *v3dv_dyn = &pipeline->dynamic;
struct vk_dynamic_graphics_state *dyn = &pipeline->dynamic_graphics_state;
if (BITSET_TEST(dyn->set, MESA_VK_DYNAMIC_VP_VIEWPORTS) ||
BITSET_TEST(dyn->set, MESA_VK_DYNAMIC_VP_SCISSORS)) {
/* FIXME: right now we don't support multiViewport so viewporst[0] would
* work now, but would need to change if we allow multiple viewports.
*/
v3dv_X(device, viewport_compute_xform)(&dyn->vp.viewports[0],
v3dv_dyn->viewport.scale[0],
v3dv_dyn->viewport.translate[0]);
}
v3dv_dyn->color_write_enable =
(1ull << (4 * V3D_MAX_RENDER_TARGETS(device->devinfo.ver))) - 1;
if (cw_info && BITSET_TEST(dyn->set, MESA_VK_DYNAMIC_CB_COLOR_WRITE_ENABLES)) {
v3dv_dyn->color_write_enable = 0;
for (uint32_t i = 0; i < cw_info->attachmentCount; i++)
v3dv_dyn->color_write_enable |=
cw_info->pColorWriteEnables[i] ? (0xfu << (i * 4)) : 0;
}
return result;
}
static VkResult
pipeline_init(struct v3dv_pipeline *pipeline,
struct v3dv_device *device,
@@ -3033,6 +2937,17 @@ pipeline_init(struct v3dv_pipeline *pipeline,
PIPELINE_COLOR_WRITE_CREATE_INFO_EXT) :
NULL;
struct vk_graphics_pipeline_state pipeline_state = { };
result = pipeline_init_dynamic_state(device, pipeline, &pipeline_state,
pCreateInfo, cw_info);
if (result != VK_SUCCESS) {
/* Caller would already destroy the pipeline, and we didn't allocate any
* extra info. We don't need to do anything else.
*/
return result;
}
const VkPipelineViewportDepthClipControlCreateInfoEXT *depth_clip_control =
vp_info ? vk_find_struct_const(vp_info->pNext,
PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT) :
@@ -3041,22 +2956,18 @@ pipeline_init(struct v3dv_pipeline *pipeline,
if (depth_clip_control)
pipeline->negative_one_to_one = depth_clip_control->negativeOneToOne;
pipeline_init_dynamic_state(pipeline,
pCreateInfo->pDynamicState,
vp_info, ds_info, cb_info, rs_info, cw_info);
/* V3D 4.2 doesn't support depth bounds testing so we don't advertise that
* feature and it shouldn't be used by any pipeline.
*/
assert(device->devinfo.ver >= 71 ||
!ds_info || !ds_info->depthBoundsTestEnable);
pipeline->depth_bounds_test_enabled = ds_info && ds_info->depthBoundsTestEnable;
enable_depth_bias(pipeline, rs_info);
v3dv_X(device, pipeline_pack_state)(pipeline, cb_info, ds_info,
rs_info, pv_info, ls_info,
ms_info);
ms_info,
&pipeline_state);
pipeline_set_sample_mask(pipeline, ms_info);
pipeline_set_sample_rate_shading(pipeline, ms_info);

View File

@@ -1040,102 +1040,49 @@ struct v3dv_cmd_buffer_attachment_state {
bool use_tlb_resolve;
};
/* Cached values derived from Vulkan viewport/count */
struct v3dv_viewport_state {
uint32_t count;
VkViewport viewports[MAX_VIEWPORTS];
float translate[MAX_VIEWPORTS][3];
float scale[MAX_VIEWPORTS][3];
};
struct v3dv_scissor_state {
uint32_t count;
VkRect2D scissors[MAX_SCISSORS];
};
/* Mostly a v3dv mapping of VkDynamicState, used to track which data as
* defined as dynamic
*/
enum v3dv_dynamic_state_bits {
V3DV_DYNAMIC_VIEWPORT = 1 << 0,
V3DV_DYNAMIC_SCISSOR = 1 << 1,
V3DV_DYNAMIC_STENCIL_COMPARE_MASK = 1 << 2,
V3DV_DYNAMIC_STENCIL_WRITE_MASK = 1 << 3,
V3DV_DYNAMIC_STENCIL_REFERENCE = 1 << 4,
V3DV_DYNAMIC_BLEND_CONSTANTS = 1 << 5,
V3DV_DYNAMIC_DEPTH_BIAS = 1 << 6,
V3DV_DYNAMIC_LINE_WIDTH = 1 << 7,
V3DV_DYNAMIC_COLOR_WRITE_ENABLE = 1 << 8,
V3DV_DYNAMIC_DEPTH_BOUNDS = 1 << 9,
V3DV_DYNAMIC_ALL = (1 << 10) - 1,
};
/* Flags for dirty pipeline state.
/* Flags for custom dirty state, that could lead to packet emission.
*
* Note *custom*, for all the dynamic state tracking coming from the Vulkan
* API, we use the Mesa runtime framework and their predefined flags
* (MESA_VK_DYNAMIC_XXX).
*
* Here we defined additional flags used to track dirty state.
*/
enum v3dv_cmd_dirty_bits {
V3DV_CMD_DIRTY_VIEWPORT = 1 << 0,
V3DV_CMD_DIRTY_SCISSOR = 1 << 1,
V3DV_CMD_DIRTY_STENCIL_COMPARE_MASK = 1 << 2,
V3DV_CMD_DIRTY_STENCIL_WRITE_MASK = 1 << 3,
V3DV_CMD_DIRTY_STENCIL_REFERENCE = 1 << 4,
V3DV_CMD_DIRTY_PIPELINE = 1 << 5,
V3DV_CMD_DIRTY_COMPUTE_PIPELINE = 1 << 6,
V3DV_CMD_DIRTY_VERTEX_BUFFER = 1 << 7,
V3DV_CMD_DIRTY_INDEX_BUFFER = 1 << 8,
V3DV_CMD_DIRTY_DESCRIPTOR_SETS = 1 << 9,
V3DV_CMD_DIRTY_COMPUTE_DESCRIPTOR_SETS = 1 << 10,
V3DV_CMD_DIRTY_PUSH_CONSTANTS = 1 << 11,
V3DV_CMD_DIRTY_PUSH_CONSTANTS_UBO = 1 << 12,
V3DV_CMD_DIRTY_BLEND_CONSTANTS = 1 << 13,
V3DV_CMD_DIRTY_OCCLUSION_QUERY = 1 << 14,
V3DV_CMD_DIRTY_DEPTH_BIAS = 1 << 15,
V3DV_CMD_DIRTY_LINE_WIDTH = 1 << 16,
V3DV_CMD_DIRTY_VIEW_INDEX = 1 << 17,
V3DV_CMD_DIRTY_COLOR_WRITE_ENABLE = 1 << 18,
V3DV_CMD_DIRTY_DEPTH_BOUNDS = 1 << 19,
V3DV_CMD_DIRTY_DRAW_ID = 1 << 20,
V3DV_CMD_DIRTY_PIPELINE = 1 << 0,
V3DV_CMD_DIRTY_COMPUTE_PIPELINE = 1 << 1,
V3DV_CMD_DIRTY_VERTEX_BUFFER = 1 << 2,
V3DV_CMD_DIRTY_INDEX_BUFFER = 1 << 3,
V3DV_CMD_DIRTY_DESCRIPTOR_SETS = 1 << 4,
V3DV_CMD_DIRTY_COMPUTE_DESCRIPTOR_SETS = 1 << 5,
V3DV_CMD_DIRTY_PUSH_CONSTANTS = 1 << 6,
V3DV_CMD_DIRTY_PUSH_CONSTANTS_UBO = 1 << 7,
V3DV_CMD_DIRTY_OCCLUSION_QUERY = 1 << 8,
V3DV_CMD_DIRTY_VIEW_INDEX = 1 << 9,
V3DV_CMD_DIRTY_DRAW_ID = 1 << 10,
V3DV_CMD_DIRTY_ALL = (1 << 10) - 1,
};
struct v3dv_dynamic_state {
/**
* Bitmask of (1 << VK_DYNAMIC_STATE_*).
* Defines the set of saved dynamic state.
/* FIXME: we keep some viewport info cached (translate, scale) because we
* use that on more that one place. But note that translate_z and scale_z
* is also used in several places, and we recompute it based on
* scissor/viewport info all time. So perhaps we could do the same with the
* x and y component.
*/
uint32_t mask;
struct v3dv_viewport_state viewport;
struct v3dv_scissor_state scissor;
struct {
uint32_t front;
uint32_t back;
} stencil_compare_mask;
struct {
uint32_t front;
uint32_t back;
} stencil_write_mask;
struct {
uint32_t front;
uint32_t back;
} stencil_reference;
float blend_constants[4];
struct {
float constant_factor;
float depth_bias_clamp;
float slope_factor;
} depth_bias;
struct {
float min;
float max;
} depth_bounds;
float line_width;
/* We cache the color_write_enable as the vulkan runtime keeps a 8-bit
* bitset with a bit per attachment, but in order to combine with the
* color_write_masks is easier to cache a 32-bit bitset with 4 bits per
* attachment.
*/
uint32_t color_write_enable;
};
@@ -1520,8 +1467,16 @@ struct v3dv_cmd_buffer_state {
struct v3dv_cmd_pipeline_state gfx;
struct v3dv_cmd_pipeline_state compute;
/* For most state tracking we rely on vk_dynamic_graphics_state, but we
* maintain a custom structure for some state-related data that we want to
* cache.
*/
struct v3dv_dynamic_state dynamic;
/* This dirty is for v3dv_cmd_dirty_bits (FIXME: perhaps we should be more
* explicit about it). For dirty flags coming from Vulkan dynamic state,
* use the vk_dynamic_graphics_state handled by the vk_cmd_buffer
*/
uint32_t dirty;
VkShaderStageFlagBits dirty_descriptor_stages;
VkShaderStageFlagBits dirty_push_constants_stages;
@@ -1606,6 +1561,7 @@ struct v3dv_cmd_buffer_state {
bool tile_aligned_render_area;
VkRect2D render_area;
struct vk_dynamic_graphics_state dynamic_graphics_state;
struct v3dv_dynamic_state dynamic;
struct v3dv_cmd_pipeline_state gfx;
@@ -1650,7 +1606,7 @@ struct v3dv_cmd_buffer_state {
};
void
v3dv_cmd_buffer_state_get_viewport_z_xform(struct v3dv_cmd_buffer_state *state,
v3dv_cmd_buffer_state_get_viewport_z_xform(struct v3dv_cmd_buffer *cmd_buffer,
uint32_t vp_idx,
float *translate_z, float *scale_z);
@@ -2299,7 +2255,8 @@ struct v3dv_pipeline {
uint32_t size_per_thread;
} spill;
struct v3dv_dynamic_state dynamic_state;
struct vk_dynamic_graphics_state dynamic_graphics_state;
struct v3dv_dynamic_state dynamic;
struct v3dv_pipeline_layout *layout;
@@ -2386,9 +2343,6 @@ struct v3dv_pipeline {
bool is_z16;
} depth_bias;
/* Depth bounds */
bool depth_bounds_test_enabled;
struct {
void *mem_ctx;
struct util_dynarray data; /* Array of v3dv_pipeline_executable_data */

View File

@@ -521,7 +521,7 @@ v3dv_write_uniforms_wg_offsets(struct v3dv_cmd_buffer *cmd_buffer,
case QUNIFORM_VIEWPORT_Z_OFFSET: {
float translate_z;
v3dv_cmd_buffer_state_get_viewport_z_xform(&cmd_buffer->state, 0,
v3dv_cmd_buffer_state_get_viewport_z_xform(cmd_buffer, 0,
&translate_z, NULL);
cl_aligned_f(&uniforms, translate_z);
break;
@@ -529,7 +529,7 @@ v3dv_write_uniforms_wg_offsets(struct v3dv_cmd_buffer *cmd_buffer,
case QUNIFORM_VIEWPORT_Z_SCALE: {
float scale_z;
v3dv_cmd_buffer_state_get_viewport_z_xform(&cmd_buffer->state, 0,
v3dv_cmd_buffer_state_get_viewport_z_xform(cmd_buffer, 0,
NULL, &scale_z);
cl_aligned_f(&uniforms, scale_z);
break;
@@ -662,7 +662,8 @@ v3dv_write_uniforms_wg_offsets(struct v3dv_cmd_buffer *cmd_buffer,
break;
case QUNIFORM_LINE_WIDTH:
cl_aligned_u32(&uniforms, job->cmd_buffer->state.dynamic.line_width);
cl_aligned_u32(&uniforms,
job->cmd_buffer->vk.dynamic_graphics_state.rs.line.width);
break;
case QUNIFORM_AA_LINE_WIDTH:

View File

@@ -1329,8 +1329,8 @@ v3dX(cmd_buffer_emit_viewport)(struct v3dv_cmd_buffer *cmd_buffer)
struct v3dv_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
assert(pipeline);
/* FIXME: right now we only support one viewport. viewporst[0] would work
* now, would need to change if we allow multiple viewports
/* FIXME: right now we don't support multiViewport so viewports[0] would
* work now, but would need to change if we allow multiple viewports.
*/
float *vptranslate = dynamic->viewport.translate[0];
float *vpscale = dynamic->viewport.scale[0];
@@ -1360,7 +1360,7 @@ v3dX(cmd_buffer_emit_viewport)(struct v3dv_cmd_buffer *cmd_buffer)
#endif
float translate_z, scale_z;
v3dv_cmd_buffer_state_get_viewport_z_xform(&cmd_buffer->state, 0,
v3dv_cmd_buffer_state_get_viewport_z_xform(cmd_buffer, 0,
&translate_z, &scale_z);
#if V3D_VERSION == 42
@@ -1421,7 +1421,8 @@ v3dX(cmd_buffer_emit_viewport)(struct v3dv_cmd_buffer *cmd_buffer)
vp.coarse_y = vp_coarse_y;
}
cmd_buffer->state.dirty &= ~V3DV_CMD_DIRTY_VIEWPORT;
BITSET_CLEAR(cmd_buffer->vk.dynamic_graphics_state.dirty,
MESA_VK_DYNAMIC_VP_VIEWPORTS);
}
void
@@ -1431,52 +1432,50 @@ v3dX(cmd_buffer_emit_stencil)(struct v3dv_cmd_buffer *cmd_buffer)
assert(job);
struct v3dv_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
struct v3dv_dynamic_state *dynamic_state = &cmd_buffer->state.dynamic;
const uint32_t dynamic_stencil_states = V3DV_DYNAMIC_STENCIL_COMPARE_MASK |
V3DV_DYNAMIC_STENCIL_WRITE_MASK |
V3DV_DYNAMIC_STENCIL_REFERENCE;
struct vk_dynamic_graphics_state *dyn =
&cmd_buffer->vk.dynamic_graphics_state;
v3dv_cl_ensure_space_with_branch(&job->bcl,
2 * cl_packet_length(STENCIL_CFG));
v3dv_return_if_oom(cmd_buffer, NULL);
bool any_dynamic_stencil_state =
BITSET_TEST(dyn->set, MESA_VK_DYNAMIC_DS_STENCIL_COMPARE_MASK) ||
BITSET_TEST(dyn->set, MESA_VK_DYNAMIC_DS_STENCIL_WRITE_MASK) ||
BITSET_TEST(dyn->set, MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE);
bool emitted_stencil = false;
const struct vk_stencil_test_face_state *front = &dyn->ds.stencil.front;
const struct vk_stencil_test_face_state *back = &dyn->ds.stencil.back;
for (uint32_t i = 0; i < 2; i++) {
if (pipeline->emit_stencil_cfg[i]) {
if (dynamic_state->mask & dynamic_stencil_states) {
if (any_dynamic_stencil_state) {
cl_emit_with_prepacked(&job->bcl, STENCIL_CFG,
pipeline->stencil_cfg[i], config) {
if (dynamic_state->mask & V3DV_DYNAMIC_STENCIL_COMPARE_MASK) {
if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_COMPARE_MASK)) {
config.stencil_test_mask =
i == 0 ? dynamic_state->stencil_compare_mask.front :
dynamic_state->stencil_compare_mask.back;
i == 0 ? front->compare_mask : back->compare_mask;
}
if (dynamic_state->mask & V3DV_DYNAMIC_STENCIL_WRITE_MASK) {
if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_WRITE_MASK)) {
config.stencil_write_mask =
i == 0 ? dynamic_state->stencil_write_mask.front :
dynamic_state->stencil_write_mask.back;
i == 0 ? front->write_mask : back->write_mask;
}
if (dynamic_state->mask & V3DV_DYNAMIC_STENCIL_REFERENCE) {
if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE)) {
config.stencil_ref_value =
i == 0 ? dynamic_state->stencil_reference.front :
dynamic_state->stencil_reference.back;
i == 0 ? front->reference : back->reference;
}
}
} else {
cl_emit_prepacked(&job->bcl, &pipeline->stencil_cfg[i]);
}
emitted_stencil = true;
}
}
if (emitted_stencil) {
const uint32_t dynamic_stencil_dirty_flags =
V3DV_CMD_DIRTY_STENCIL_COMPARE_MASK |
V3DV_CMD_DIRTY_STENCIL_WRITE_MASK |
V3DV_CMD_DIRTY_STENCIL_REFERENCE;
cmd_buffer->state.dirty &= ~dynamic_stencil_dirty_flags;
BITSET_CLEAR(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_COMPARE_MASK);
BITSET_CLEAR(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE);
BITSET_CLEAR(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_WRITE_MASK);
}
}
@@ -1492,21 +1491,22 @@ v3dX(cmd_buffer_emit_depth_bias)(struct v3dv_cmd_buffer *cmd_buffer)
struct v3dv_job *job = cmd_buffer->state.job;
assert(job);
struct vk_dynamic_graphics_state *dyn = &cmd_buffer->vk.dynamic_graphics_state;
v3dv_cl_ensure_space_with_branch(&job->bcl, cl_packet_length(DEPTH_OFFSET));
v3dv_return_if_oom(cmd_buffer, NULL);
struct v3dv_dynamic_state *dynamic = &cmd_buffer->state.dynamic;
cl_emit(&job->bcl, DEPTH_OFFSET, bias) {
bias.depth_offset_factor = dynamic->depth_bias.slope_factor;
bias.depth_offset_units = dynamic->depth_bias.constant_factor;
bias.depth_offset_factor = dyn->rs.depth_bias.slope;
bias.depth_offset_units = dyn->rs.depth_bias.constant;
#if V3D_VERSION <= 42
if (pipeline->depth_bias.is_z16)
bias.depth_offset_units *= 256.0f;
#endif
bias.limit = dynamic->depth_bias.depth_bias_clamp;
bias.limit = dyn->rs.depth_bias.clamp;
}
cmd_buffer->state.dirty &= ~V3DV_CMD_DIRTY_DEPTH_BIAS;
BITSET_CLEAR(dyn->dirty, MESA_VK_DYNAMIC_RS_DEPTH_BIAS_FACTORS);
}
void
@@ -1517,12 +1517,11 @@ v3dX(cmd_buffer_emit_depth_bounds)(struct v3dv_cmd_buffer *cmd_buffer)
* Note that this method is being called as v3dv_job_init flags all state
* as dirty. See FIXME note in v3dv_job_init.
*/
#if V3D_VERSION >= 71
struct v3dv_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
assert(pipeline);
struct vk_dynamic_graphics_state *dyn =
&cmd_buffer->vk.dynamic_graphics_state;
if (!pipeline->depth_bounds_test_enabled)
if (!dyn->ds.depth.bounds_test.enable)
return;
struct v3dv_job *job = cmd_buffer->state.job;
@@ -1531,13 +1530,11 @@ v3dX(cmd_buffer_emit_depth_bounds)(struct v3dv_cmd_buffer *cmd_buffer)
v3dv_cl_ensure_space_with_branch(&job->bcl, cl_packet_length(DEPTH_BOUNDS_TEST_LIMITS));
v3dv_return_if_oom(cmd_buffer, NULL);
struct v3dv_dynamic_state *dynamic = &cmd_buffer->state.dynamic;
cl_emit(&job->bcl, DEPTH_BOUNDS_TEST_LIMITS, bounds) {
bounds.lower_test_limit = dynamic->depth_bounds.min;
bounds.upper_test_limit = dynamic->depth_bounds.max;
bounds.lower_test_limit = dyn->ds.depth.bounds_test.min;
bounds.upper_test_limit = dyn->ds.depth.bounds_test.max;
}
cmd_buffer->state.dirty &= ~V3DV_CMD_DIRTY_DEPTH_BOUNDS;
BITSET_CLEAR(dyn->dirty, MESA_VK_DYNAMIC_DS_DEPTH_BOUNDS_TEST_BOUNDS);
#endif
}
@@ -1547,6 +1544,8 @@ v3dX(cmd_buffer_emit_line_width)(struct v3dv_cmd_buffer *cmd_buffer)
struct v3dv_job *job = cmd_buffer->state.job;
assert(job);
struct vk_dynamic_graphics_state *dyn = &cmd_buffer->vk.dynamic_graphics_state;
v3dv_cl_ensure_space_with_branch(&job->bcl, cl_packet_length(LINE_WIDTH));
v3dv_return_if_oom(cmd_buffer, NULL);
@@ -1555,7 +1554,7 @@ v3dX(cmd_buffer_emit_line_width)(struct v3dv_cmd_buffer *cmd_buffer)
cmd_buffer);
}
cmd_buffer->state.dirty &= ~V3DV_CMD_DIRTY_LINE_WIDTH;
BITSET_CLEAR(dyn->dirty, MESA_VK_DYNAMIC_RS_LINE_WIDTH);
}
void
@@ -1609,17 +1608,20 @@ v3dX(cmd_buffer_emit_blend)(struct v3dv_cmd_buffer *cmd_buffer)
}
}
if (pipeline->blend.needs_color_constants &&
cmd_buffer->state.dirty & V3DV_CMD_DIRTY_BLEND_CONSTANTS) {
struct v3dv_dynamic_state *dynamic = &cmd_buffer->state.dynamic;
if (pipeline->blend.needs_color_constants) {
const struct vk_dynamic_graphics_state *dyn =
&cmd_buffer->vk.dynamic_graphics_state;
cl_emit(&job->bcl, BLEND_CONSTANT_COLOR, color) {
color.red_f16 = _mesa_float_to_half(dynamic->blend_constants[0]);
color.green_f16 = _mesa_float_to_half(dynamic->blend_constants[1]);
color.blue_f16 = _mesa_float_to_half(dynamic->blend_constants[2]);
color.alpha_f16 = _mesa_float_to_half(dynamic->blend_constants[3]);
color.red_f16 = _mesa_float_to_half(dyn->cb.blend_constants[0]);
color.green_f16 = _mesa_float_to_half(dyn->cb.blend_constants[1]);
color.blue_f16 = _mesa_float_to_half(dyn->cb.blend_constants[2]);
color.alpha_f16 = _mesa_float_to_half(dyn->cb.blend_constants[3]);
}
cmd_buffer->state.dirty &= ~V3DV_CMD_DIRTY_BLEND_CONSTANTS;
}
BITSET_CLEAR(cmd_buffer->vk.dynamic_graphics_state.dirty,
MESA_VK_DYNAMIC_CB_BLEND_CONSTANTS);
}
void
@@ -1629,9 +1631,10 @@ v3dX(cmd_buffer_emit_color_write_mask)(struct v3dv_cmd_buffer *cmd_buffer)
v3dv_cl_ensure_space_with_branch(&job->bcl, cl_packet_length(COLOR_WRITE_MASKS));
struct v3dv_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
struct v3dv_dynamic_state *dynamic = &cmd_buffer->state.dynamic;
uint32_t color_write_mask = ~dynamic->color_write_enable |
struct v3dv_dynamic_state *v3dv_dyn = &cmd_buffer->state.dynamic;
uint32_t color_write_mask = ~v3dv_dyn->color_write_enable |
pipeline->blend.color_write_masks;
#if V3D_VERSION <= 42
/* Only 4 RTs */
color_write_mask &= 0xffff;
@@ -1641,7 +1644,8 @@ v3dX(cmd_buffer_emit_color_write_mask)(struct v3dv_cmd_buffer *cmd_buffer)
mask.mask = color_write_mask;
}
cmd_buffer->state.dirty &= ~V3DV_CMD_DIRTY_COLOR_WRITE_ENABLE;
BITSET_CLEAR(cmd_buffer->vk.dynamic_graphics_state.dirty,
MESA_VK_DYNAMIC_CB_COLOR_WRITE_ENABLES);
}
static void

View File

@@ -293,7 +293,8 @@ pack_single_stencil_cfg(struct v3dv_pipeline *pipeline,
uint8_t *stencil_cfg,
bool is_front,
bool is_back,
const VkStencilOpState *stencil_state)
const VkStencilOpState *stencil_state,
const struct vk_graphics_pipeline_state *state)
{
/* From the Vulkan spec:
*
@@ -311,16 +312,16 @@ pack_single_stencil_cfg(struct v3dv_pipeline *pipeline,
* the old.
*/
const uint8_t write_mask =
pipeline->dynamic_state.mask & V3DV_DYNAMIC_STENCIL_WRITE_MASK ?
0 : stencil_state->writeMask & 0xff;
BITSET_TEST(state->dynamic, MESA_VK_DYNAMIC_DS_STENCIL_WRITE_MASK) ?
0 : stencil_state->writeMask & 0xff;
const uint8_t compare_mask =
pipeline->dynamic_state.mask & V3DV_DYNAMIC_STENCIL_COMPARE_MASK ?
0 : stencil_state->compareMask & 0xff;
BITSET_TEST(state->dynamic, MESA_VK_DYNAMIC_DS_STENCIL_COMPARE_MASK) ?
0 : stencil_state->compareMask & 0xff;
const uint8_t reference =
pipeline->dynamic_state.mask & V3DV_DYNAMIC_STENCIL_COMPARE_MASK ?
0 : stencil_state->reference & 0xff;
BITSET_TEST(state->dynamic, MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE) ?
0 : stencil_state->reference & 0xff;
v3dvx_pack(stencil_cfg, STENCIL_CFG, config) {
config.front_config = is_front;
@@ -337,7 +338,8 @@ pack_single_stencil_cfg(struct v3dv_pipeline *pipeline,
static void
pack_stencil_cfg(struct v3dv_pipeline *pipeline,
const VkPipelineDepthStencilStateCreateInfo *ds_info)
const VkPipelineDepthStencilStateCreateInfo *ds_info,
const struct vk_graphics_pipeline_state *state)
{
assert(sizeof(pipeline->stencil_cfg) == 2 * cl_packet_length(STENCIL_CFG));
@@ -348,18 +350,19 @@ pack_stencil_cfg(struct v3dv_pipeline *pipeline,
if (ri->stencil_attachment_format == VK_FORMAT_UNDEFINED)
return;
const uint32_t dynamic_stencil_states = V3DV_DYNAMIC_STENCIL_COMPARE_MASK |
V3DV_DYNAMIC_STENCIL_WRITE_MASK |
V3DV_DYNAMIC_STENCIL_REFERENCE;
const bool any_dynamic_stencil_states =
BITSET_TEST(state->dynamic, MESA_VK_DYNAMIC_DS_STENCIL_WRITE_MASK) ||
BITSET_TEST(state->dynamic, MESA_VK_DYNAMIC_DS_STENCIL_COMPARE_MASK) ||
BITSET_TEST(state->dynamic, MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE);
/* If front != back or we have dynamic stencil state we can't emit a single
* packet for both faces.
*/
bool needs_front_and_back = false;
if ((pipeline->dynamic_state.mask & dynamic_stencil_states) ||
memcmp(&ds_info->front, &ds_info->back, sizeof(ds_info->front)))
if ((any_dynamic_stencil_states) ||
memcmp(&ds_info->front, &ds_info->back, sizeof(ds_info->front))) {
needs_front_and_back = true;
}
/* If the front and back configurations are the same we can emit both with
* a single packet.
@@ -367,16 +370,22 @@ pack_stencil_cfg(struct v3dv_pipeline *pipeline,
pipeline->emit_stencil_cfg[0] = true;
if (!needs_front_and_back) {
pack_single_stencil_cfg(pipeline, pipeline->stencil_cfg[0],
true, true, &ds_info->front);
true, true, &ds_info->front, state);
} else {
pipeline->emit_stencil_cfg[1] = true;
pack_single_stencil_cfg(pipeline, pipeline->stencil_cfg[0],
true, false, &ds_info->front);
true, false, &ds_info->front, state);
pack_single_stencil_cfg(pipeline, pipeline->stencil_cfg[1],
false, true, &ds_info->back);
false, true, &ds_info->back, state);
}
}
/* FIXME: Now that we are passing the vk_graphics_pipeline_state we could
* avoid passing all those parameters. But doing that we would need to change
* all the code that uses the VkXXX structures, and use instead the equivalent
* vk_xxx
*/
void
v3dX(pipeline_pack_state)(struct v3dv_pipeline *pipeline,
const VkPipelineColorBlendStateCreateInfo *cb_info,
@@ -384,11 +393,12 @@ v3dX(pipeline_pack_state)(struct v3dv_pipeline *pipeline,
const VkPipelineRasterizationStateCreateInfo *rs_info,
const VkPipelineRasterizationProvokingVertexStateCreateInfoEXT *pv_info,
const VkPipelineRasterizationLineStateCreateInfoEXT *ls_info,
const VkPipelineMultisampleStateCreateInfo *ms_info)
const VkPipelineMultisampleStateCreateInfo *ms_info,
const struct vk_graphics_pipeline_state *state)
{
pack_blend(pipeline, cb_info);
pack_cfg_bits(pipeline, ds_info, rs_info, pv_info, ls_info, ms_info);
pack_stencil_cfg(pipeline, ds_info);
pack_stencil_cfg(pipeline, ds_info, state);
}
static void

View File

@@ -318,7 +318,8 @@ v3dX(pipeline_pack_state)(struct v3dv_pipeline *pipeline,
const VkPipelineRasterizationStateCreateInfo *rs_info,
const VkPipelineRasterizationProvokingVertexStateCreateInfoEXT *pv_info,
const VkPipelineRasterizationLineStateCreateInfoEXT *ls_info,
const VkPipelineMultisampleStateCreateInfo *ms_info);
const VkPipelineMultisampleStateCreateInfo *ms_info,
const struct vk_graphics_pipeline_state *state);
void
v3dX(pipeline_pack_compile_state)(struct v3dv_pipeline *pipeline,
const VkPipelineVertexInputStateCreateInfo *vi_info,