mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-03 07:48:07 +02:00
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:
parent
858154b84e
commit
f2236065b7
8 changed files with 342 additions and 613 deletions
|
|
@ -31,7 +31,7 @@ float
|
||||||
v3dv_get_aa_line_width(struct v3dv_pipeline *pipeline,
|
v3dv_get_aa_line_width(struct v3dv_pipeline *pipeline,
|
||||||
struct v3dv_cmd_buffer *buffer)
|
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
|
/* If line smoothing is enabled then we want to add some extra pixels to
|
||||||
* the width in order to have some semi-transparent edges.
|
* 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 = ~0;
|
||||||
cmd_buffer->state.dirty_descriptor_stages = ~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 */
|
/* Honor inheritance of occlusion queries in secondaries if requested */
|
||||||
if (cmd_buffer->vk.level == VK_COMMAND_BUFFER_LEVEL_SECONDARY &&
|
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.
|
* to emit a new clip window to constraint it to the render area.
|
||||||
*/
|
*/
|
||||||
static void
|
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_x = state->render_area.offset.x;
|
||||||
uint32_t min_render_y = state->render_area.offset.y;
|
uint32_t min_render_y = state->render_area.offset.y;
|
||||||
uint32_t max_render_x = min_render_x + state->render_area.extent.width - 1;
|
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;
|
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 ||
|
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) {
|
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);
|
cmd_buffer_init_render_pass_attachment_state(cmd_buffer, pRenderPassBegin);
|
||||||
|
|
||||||
state->render_area = pRenderPassBegin->renderArea;
|
state->render_area = pRenderPassBegin->renderArea;
|
||||||
constraint_clip_window_to_render_area(state);
|
constraint_clip_window_to_render_area(cmd_buffer);
|
||||||
|
|
||||||
/* Setup for first subpass */
|
/* Setup for first subpass */
|
||||||
v3dv_cmd_buffer_subpass_start(cmd_buffer, 0);
|
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,
|
static void
|
||||||
* for those that are not configured as dynamic, copies relevant state into
|
cmd_buffer_copy_private_dynamic_state(struct v3dv_dynamic_state *dst,
|
||||||
* the command buffer.
|
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
|
static void
|
||||||
cmd_buffer_bind_pipeline_static_state(struct v3dv_cmd_buffer *cmd_buffer,
|
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;
|
vk_cmd_set_dynamic_graphics_state(&cmd_buffer->vk, &pipeline->dynamic_graphics_state);
|
||||||
uint32_t dynamic_mask = src->mask;
|
cmd_buffer_copy_private_dynamic_state(&cmd_buffer->state.dynamic, &pipeline->dynamic,
|
||||||
uint32_t dirty = 0;
|
&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
|
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
|
* could have changed (through calls to vkCmdSetXXX) between bindings of
|
||||||
* the same pipeline.
|
* 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)
|
if (cmd_buffer->state.gfx.pipeline == pipeline)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cmd_buffer->state.gfx.pipeline = pipeline;
|
cmd_buffer->state.gfx.pipeline = pipeline;
|
||||||
|
|
||||||
cmd_buffer->state.dirty |= V3DV_CMD_DIRTY_PIPELINE;
|
cmd_buffer->state.dirty |= V3DV_CMD_DIRTY_PIPELINE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2261,18 +2192,19 @@ v3dv_CmdBindPipeline(VkCommandBuffer commandBuffer,
|
||||||
* and scale parameters.
|
* and scale parameters.
|
||||||
*/
|
*/
|
||||||
void
|
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,
|
uint32_t vp_idx,
|
||||||
float *translate_z, float *scale_z)
|
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 t = vp_state->translate[vp_idx][2];
|
||||||
float s = vp_state->scale[vp_idx][2];
|
float s = vp_state->scale[vp_idx][2];
|
||||||
|
|
||||||
assert(state->gfx.pipeline);
|
assert(cmd_buffer->state.gfx.pipeline);
|
||||||
if (state->gfx.pipeline->negative_one_to_one) {
|
if (cmd_buffer->state.gfx.pipeline->negative_one_to_one) {
|
||||||
t = (t + vp_state->viewports[vp_idx].maxDepth) * 0.5f;
|
t = (t + vk_vp_state->viewports[vp_idx].maxDepth) * 0.5f;
|
||||||
s *= 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;
|
*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
|
VKAPI_ATTR void VKAPI_CALL
|
||||||
v3dv_CmdSetViewport(VkCommandBuffer commandBuffer,
|
v3dv_CmdSetViewport(VkCommandBuffer commandBuffer,
|
||||||
uint32_t firstViewport,
|
uint32_t firstViewport,
|
||||||
|
|
@ -2290,64 +2254,47 @@ v3dv_CmdSetViewport(VkCommandBuffer commandBuffer,
|
||||||
const VkViewport *pViewports)
|
const VkViewport *pViewports)
|
||||||
{
|
{
|
||||||
V3DV_FROM_HANDLE(v3dv_cmd_buffer, cmd_buffer, commandBuffer);
|
V3DV_FROM_HANDLE(v3dv_cmd_buffer, cmd_buffer, commandBuffer);
|
||||||
struct v3dv_cmd_buffer_state *state = &cmd_buffer->state;
|
struct v3dv_dynamic_state *v3dv_dyn = &cmd_buffer->state.dynamic;
|
||||||
const uint32_t total_count = firstViewport + viewportCount;
|
struct vk_dynamic_graphics_state *dyn = &cmd_buffer->vk.dynamic_graphics_state;
|
||||||
|
|
||||||
|
const uint32_t total_count = firstViewport + viewportCount;
|
||||||
assert(firstViewport < MAX_VIEWPORTS);
|
assert(firstViewport < MAX_VIEWPORTS);
|
||||||
assert(total_count >= 1 && total_count <= MAX_VIEWPORTS);
|
assert(total_count >= 1 && total_count <= MAX_VIEWPORTS);
|
||||||
|
|
||||||
if (state->dynamic.viewport.count < total_count)
|
vk_common_CmdSetViewportWithCount(commandBuffer,
|
||||||
state->dynamic.viewport.count = total_count;
|
total_count,
|
||||||
|
pViewports);
|
||||||
if (!memcmp(state->dynamic.viewport.viewports + firstViewport,
|
|
||||||
pViewports, viewportCount * sizeof(*pViewports))) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(state->dynamic.viewport.viewports + firstViewport, pViewports,
|
|
||||||
viewportCount * sizeof(*pViewports));
|
|
||||||
|
|
||||||
for (uint32_t i = firstViewport; i < total_count; i++) {
|
for (uint32_t i = firstViewport; i < total_count; i++) {
|
||||||
v3dv_X(cmd_buffer->device, viewport_compute_xform)
|
v3dv_X(cmd_buffer->device, viewport_compute_xform)
|
||||||
(&state->dynamic.viewport.viewports[i],
|
(&dyn->vp.viewports[i], v3dv_dyn->viewport.scale[i],
|
||||||
state->dynamic.viewport.scale[i],
|
v3dv_dyn->viewport.translate[i]);
|
||||||
state->dynamic.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
|
VKAPI_ATTR void VKAPI_CALL
|
||||||
v3dv_CmdSetScissor(VkCommandBuffer commandBuffer,
|
v3dv_CmdSetScissor(VkCommandBuffer commandBuffer,
|
||||||
uint32_t firstScissor,
|
uint32_t firstScissor,
|
||||||
uint32_t scissorCount,
|
uint32_t scissorCount,
|
||||||
const VkRect2D *pScissors)
|
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 < MAX_SCISSORS);
|
||||||
assert(firstScissor + scissorCount >= 1 &&
|
assert(firstScissor + scissorCount >= 1 &&
|
||||||
firstScissor + scissorCount <= MAX_SCISSORS);
|
firstScissor + scissorCount <= MAX_SCISSORS);
|
||||||
|
|
||||||
if (state->dynamic.scissor.count < firstScissor + scissorCount)
|
vk_common_CmdSetScissorWithCount(commandBuffer,
|
||||||
state->dynamic.scissor.count = firstScissor + scissorCount;
|
firstScissor + scissorCount,
|
||||||
|
pScissors);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
emit_scissor(struct v3dv_cmd_buffer *cmd_buffer)
|
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;
|
return;
|
||||||
|
|
||||||
struct v3dv_dynamic_state *dynamic = &cmd_buffer->state.dynamic;
|
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
|
* FIXME: right now we only allow one scissor. Below would need to be
|
||||||
* updated if we support more
|
* updated if we support more
|
||||||
*/
|
*/
|
||||||
if (dynamic->scissor.count > 0) {
|
struct vk_dynamic_graphics_state *vk_dyn =
|
||||||
VkRect2D *scissor = &dynamic->scissor.scissors[0];
|
&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);
|
minx = MAX2(minx, scissor->offset.x);
|
||||||
miny = MAX2(miny, scissor->offset.y);
|
miny = MAX2(miny, scissor->offset.y);
|
||||||
maxx = MIN2(maxx, scissor->offset.x + scissor->extent.width);
|
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)
|
v3dv_X(cmd_buffer->device, job_emit_clip_window)
|
||||||
(cmd_buffer->state.job, &cmd_buffer->state.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
|
static bool
|
||||||
update_gfx_uniform_state(struct v3dv_cmd_buffer *cmd_buffer,
|
update_gfx_uniform_state(struct v3dv_cmd_buffer *cmd_buffer)
|
||||||
uint32_t dirty_uniform_state)
|
|
||||||
{
|
{
|
||||||
/* We need to update uniform streams if any piece of state that is passed
|
/* We need to update uniform streams if any piece of state that is passed
|
||||||
* to the shader as a uniform may have changed.
|
* 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
|
* If only descriptor sets are dirty then we can safely ignore updates
|
||||||
* for shader stages that don't access descriptors.
|
* for shader stages that don't access descriptors.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct v3dv_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
|
struct v3dv_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
|
||||||
assert(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 dirty_uniform_state =
|
||||||
const bool has_new_viewport = dirty_uniform_state & V3DV_CMD_DIRTY_VIEWPORT;
|
(dirty & (V3DV_CMD_DIRTY_PIPELINE |
|
||||||
const bool has_new_push_constants = dirty_uniform_state & V3DV_CMD_DIRTY_PUSH_CONSTANTS;
|
V3DV_CMD_DIRTY_PUSH_CONSTANTS |
|
||||||
const bool has_new_descriptors = dirty_uniform_state & V3DV_CMD_DIRTY_DESCRIPTOR_SETS;
|
V3DV_CMD_DIRTY_DESCRIPTOR_SETS |
|
||||||
const bool has_new_view_index = dirty_uniform_state & V3DV_CMD_DIRTY_VIEW_INDEX;
|
V3DV_CMD_DIRTY_VIEW_INDEX |
|
||||||
const bool has_new_draw_id = dirty_uniform_state & V3DV_CMD_DIRTY_DRAW_ID;
|
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 */
|
/* VK_SHADER_STAGE_FRAGMENT_BIT */
|
||||||
const bool has_new_descriptors_fs =
|
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_VIEW_INDEX;
|
||||||
cmd_buffer->state.dirty &= ~V3DV_CMD_DIRTY_DRAW_ID;
|
cmd_buffer->state.dirty &= ~V3DV_CMD_DIRTY_DRAW_ID;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This stores command buffer state that we might be about to stomp for
|
/* 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
|
* account the graphics pipeline, and the graphics state
|
||||||
*/
|
*/
|
||||||
state->meta.gfx.pipeline = state->gfx.pipeline;
|
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));
|
memcpy(&state->meta.dynamic, &state->dynamic, sizeof(state->dynamic));
|
||||||
|
|
||||||
struct v3dv_descriptor_state *gfx_descriptor_state =
|
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 */
|
/* 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));
|
memcpy(&state->dynamic, &state->meta.dynamic, sizeof(state->dynamic));
|
||||||
state->dirty = ~0;
|
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_*.
|
* that will require that we new uniform state for QUNIFORM_VIEWPORT_*.
|
||||||
*/
|
*/
|
||||||
uint32_t *dirty = &cmd_buffer->state.dirty;
|
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 =
|
const bool dirty_uniform_state =
|
||||||
*dirty & (V3DV_CMD_DIRTY_PIPELINE |
|
update_gfx_uniform_state(cmd_buffer);
|
||||||
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);
|
|
||||||
|
|
||||||
struct v3dv_device *device = cmd_buffer->device;
|
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);
|
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);
|
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);
|
v3dv_X(device, cmd_buffer_emit_viewport)(cmd_buffer);
|
||||||
}
|
|
||||||
|
|
||||||
if (*dirty & V3DV_CMD_DIRTY_INDEX_BUFFER)
|
if (*dirty & V3DV_CMD_DIRTY_INDEX_BUFFER)
|
||||||
v3dv_X(device, cmd_buffer_emit_index_buffer)(cmd_buffer);
|
v3dv_X(device, cmd_buffer_emit_index_buffer)(cmd_buffer);
|
||||||
|
|
||||||
const uint32_t dynamic_stencil_dirty_flags =
|
bool any_dynamic_stencil_dirty =
|
||||||
V3DV_CMD_DIRTY_STENCIL_COMPARE_MASK |
|
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_COMPARE_MASK) ||
|
||||||
V3DV_CMD_DIRTY_STENCIL_WRITE_MASK |
|
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_WRITE_MASK) ||
|
||||||
V3DV_CMD_DIRTY_STENCIL_REFERENCE;
|
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE);
|
||||||
if (*dirty & (V3DV_CMD_DIRTY_PIPELINE | dynamic_stencil_dirty_flags))
|
|
||||||
|
if (*dirty & V3DV_CMD_DIRTY_PIPELINE || any_dynamic_stencil_dirty)
|
||||||
v3dv_X(device, cmd_buffer_emit_stencil)(cmd_buffer);
|
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);
|
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);
|
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);
|
v3dv_X(device, cmd_buffer_emit_blend)(cmd_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
if (*dirty & V3DV_CMD_DIRTY_OCCLUSION_QUERY)
|
if (*dirty & V3DV_CMD_DIRTY_OCCLUSION_QUERY)
|
||||||
v3dv_X(device, cmd_buffer_emit_occlusion_query)(cmd_buffer);
|
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);
|
v3dv_X(device, cmd_buffer_emit_line_width)(cmd_buffer);
|
||||||
|
|
||||||
if (*dirty & V3DV_CMD_DIRTY_PIPELINE)
|
if (*dirty & V3DV_CMD_DIRTY_PIPELINE)
|
||||||
v3dv_X(device, cmd_buffer_emit_sample_state)(cmd_buffer);
|
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);
|
v3dv_X(device, cmd_buffer_emit_color_write_mask)(cmd_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
/* We disable double-buffer mode if indirect draws are used because in that
|
/* We disable double-buffer mode if indirect draws are used because in that
|
||||||
* case we don't know the vertex count.
|
* 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;
|
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
|
VKAPI_ATTR void VKAPI_CALL
|
||||||
v3dv_CmdSetLineStippleEXT(VkCommandBuffer commandBuffer,
|
v3dv_CmdSetLineStippleEXT(VkCommandBuffer commandBuffer,
|
||||||
uint32_t lineStippleFactor,
|
uint32_t lineStippleFactor,
|
||||||
|
|
@ -3584,16 +3480,6 @@ v3dv_CmdSetLineStippleEXT(VkCommandBuffer commandBuffer,
|
||||||
/* We do not support stippled line rasterization so we just ignore this. */
|
/* 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
|
* 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
|
* 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;
|
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
|
void
|
||||||
v3dv_cmd_buffer_ensure_array_state(struct v3dv_cmd_buffer *cmd_buffer,
|
v3dv_cmd_buffer_ensure_array_state(struct v3dv_cmd_buffer *cmd_buffer,
|
||||||
uint32_t slot_size,
|
uint32_t slot_size,
|
||||||
|
|
@ -4658,8 +4506,7 @@ v3dv_CmdBeginRenderingKHR(VkCommandBuffer commandBuffer,
|
||||||
vk_free(&cmd_buffer->vk.pool->alloc, clear_values);
|
vk_free(&cmd_buffer->vk.pool->alloc, clear_values);
|
||||||
|
|
||||||
state->render_area = info->renderArea;
|
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);
|
v3dv_cmd_buffer_subpass_start(cmd_buffer, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
#include "compiler/nir/nir_builder.h"
|
#include "compiler/nir/nir_builder.h"
|
||||||
#include "util/u_pack_color.h"
|
#include "util/u_pack_color.h"
|
||||||
|
#include "vk_common_entrypoints.h"
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_hw_clear_color(struct v3dv_device *device,
|
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);
|
pipeline->pipeline);
|
||||||
|
|
||||||
if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
|
if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
|
||||||
v3dv_CmdSetStencilReference(cmd_buffer_handle,
|
vk_common_CmdSetStencilReference(cmd_buffer_handle,
|
||||||
VK_STENCIL_FACE_FRONT_AND_BACK,
|
VK_STENCIL_FACE_FRONT_AND_BACK,
|
||||||
clear_ds->stencil);
|
clear_ds->stencil);
|
||||||
v3dv_CmdSetStencilWriteMask(cmd_buffer_handle,
|
vk_common_CmdSetStencilWriteMask(cmd_buffer_handle,
|
||||||
VK_STENCIL_FACE_FRONT_AND_BACK, 0xff);
|
VK_STENCIL_FACE_FRONT_AND_BACK, 0xff);
|
||||||
v3dv_CmdSetStencilCompareMask(cmd_buffer_handle,
|
vk_common_CmdSetStencilCompareMask(cmd_buffer_handle,
|
||||||
VK_STENCIL_FACE_FRONT_AND_BACK, 0xff);
|
VK_STENCIL_FACE_FRONT_AND_BACK, 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < rect_count; i++) {
|
for (uint32_t i = 0; i < rect_count; i++) {
|
||||||
|
|
|
||||||
|
|
@ -2645,145 +2645,6 @@ compute_vpm_config(struct v3dv_pipeline *pipeline)
|
||||||
return VK_SUCCESS;
|
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
|
static bool
|
||||||
stencil_op_is_no_op(const VkStencilOpState *stencil)
|
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
|
static VkResult
|
||||||
pipeline_init(struct v3dv_pipeline *pipeline,
|
pipeline_init(struct v3dv_pipeline *pipeline,
|
||||||
struct v3dv_device *device,
|
struct v3dv_device *device,
|
||||||
|
|
@ -3033,6 +2937,17 @@ pipeline_init(struct v3dv_pipeline *pipeline,
|
||||||
PIPELINE_COLOR_WRITE_CREATE_INFO_EXT) :
|
PIPELINE_COLOR_WRITE_CREATE_INFO_EXT) :
|
||||||
NULL;
|
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 =
|
const VkPipelineViewportDepthClipControlCreateInfoEXT *depth_clip_control =
|
||||||
vp_info ? vk_find_struct_const(vp_info->pNext,
|
vp_info ? vk_find_struct_const(vp_info->pNext,
|
||||||
PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT) :
|
PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT) :
|
||||||
|
|
@ -3041,22 +2956,18 @@ pipeline_init(struct v3dv_pipeline *pipeline,
|
||||||
if (depth_clip_control)
|
if (depth_clip_control)
|
||||||
pipeline->negative_one_to_one = depth_clip_control->negativeOneToOne;
|
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
|
/* 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.
|
* feature and it shouldn't be used by any pipeline.
|
||||||
*/
|
*/
|
||||||
assert(device->devinfo.ver >= 71 ||
|
assert(device->devinfo.ver >= 71 ||
|
||||||
!ds_info || !ds_info->depthBoundsTestEnable);
|
!ds_info || !ds_info->depthBoundsTestEnable);
|
||||||
pipeline->depth_bounds_test_enabled = ds_info && ds_info->depthBoundsTestEnable;
|
|
||||||
|
|
||||||
enable_depth_bias(pipeline, rs_info);
|
enable_depth_bias(pipeline, rs_info);
|
||||||
|
|
||||||
v3dv_X(device, pipeline_pack_state)(pipeline, cb_info, ds_info,
|
v3dv_X(device, pipeline_pack_state)(pipeline, cb_info, ds_info,
|
||||||
rs_info, pv_info, ls_info,
|
rs_info, pv_info, ls_info,
|
||||||
ms_info);
|
ms_info,
|
||||||
|
&pipeline_state);
|
||||||
|
|
||||||
pipeline_set_sample_mask(pipeline, ms_info);
|
pipeline_set_sample_mask(pipeline, ms_info);
|
||||||
pipeline_set_sample_rate_shading(pipeline, ms_info);
|
pipeline_set_sample_rate_shading(pipeline, ms_info);
|
||||||
|
|
|
||||||
|
|
@ -1040,102 +1040,49 @@ struct v3dv_cmd_buffer_attachment_state {
|
||||||
bool use_tlb_resolve;
|
bool use_tlb_resolve;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Cached values derived from Vulkan viewport/count */
|
||||||
struct v3dv_viewport_state {
|
struct v3dv_viewport_state {
|
||||||
uint32_t count;
|
|
||||||
VkViewport viewports[MAX_VIEWPORTS];
|
|
||||||
float translate[MAX_VIEWPORTS][3];
|
float translate[MAX_VIEWPORTS][3];
|
||||||
float scale[MAX_VIEWPORTS][3];
|
float scale[MAX_VIEWPORTS][3];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct v3dv_scissor_state {
|
/* Flags for custom dirty state, that could lead to packet emission.
|
||||||
uint32_t count;
|
*
|
||||||
VkRect2D scissors[MAX_SCISSORS];
|
* 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).
|
||||||
/* Mostly a v3dv mapping of VkDynamicState, used to track which data as
|
*
|
||||||
* defined as dynamic
|
* Here we defined additional flags used to track dirty state.
|
||||||
*/
|
|
||||||
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.
|
|
||||||
*/
|
*/
|
||||||
enum v3dv_cmd_dirty_bits {
|
enum v3dv_cmd_dirty_bits {
|
||||||
V3DV_CMD_DIRTY_VIEWPORT = 1 << 0,
|
V3DV_CMD_DIRTY_PIPELINE = 1 << 0,
|
||||||
V3DV_CMD_DIRTY_SCISSOR = 1 << 1,
|
V3DV_CMD_DIRTY_COMPUTE_PIPELINE = 1 << 1,
|
||||||
V3DV_CMD_DIRTY_STENCIL_COMPARE_MASK = 1 << 2,
|
V3DV_CMD_DIRTY_VERTEX_BUFFER = 1 << 2,
|
||||||
V3DV_CMD_DIRTY_STENCIL_WRITE_MASK = 1 << 3,
|
V3DV_CMD_DIRTY_INDEX_BUFFER = 1 << 3,
|
||||||
V3DV_CMD_DIRTY_STENCIL_REFERENCE = 1 << 4,
|
V3DV_CMD_DIRTY_DESCRIPTOR_SETS = 1 << 4,
|
||||||
V3DV_CMD_DIRTY_PIPELINE = 1 << 5,
|
V3DV_CMD_DIRTY_COMPUTE_DESCRIPTOR_SETS = 1 << 5,
|
||||||
V3DV_CMD_DIRTY_COMPUTE_PIPELINE = 1 << 6,
|
V3DV_CMD_DIRTY_PUSH_CONSTANTS = 1 << 6,
|
||||||
V3DV_CMD_DIRTY_VERTEX_BUFFER = 1 << 7,
|
V3DV_CMD_DIRTY_PUSH_CONSTANTS_UBO = 1 << 7,
|
||||||
V3DV_CMD_DIRTY_INDEX_BUFFER = 1 << 8,
|
V3DV_CMD_DIRTY_OCCLUSION_QUERY = 1 << 8,
|
||||||
V3DV_CMD_DIRTY_DESCRIPTOR_SETS = 1 << 9,
|
V3DV_CMD_DIRTY_VIEW_INDEX = 1 << 9,
|
||||||
V3DV_CMD_DIRTY_COMPUTE_DESCRIPTOR_SETS = 1 << 10,
|
V3DV_CMD_DIRTY_DRAW_ID = 1 << 10,
|
||||||
V3DV_CMD_DIRTY_PUSH_CONSTANTS = 1 << 11,
|
V3DV_CMD_DIRTY_ALL = (1 << 10) - 1,
|
||||||
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,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct v3dv_dynamic_state {
|
struct v3dv_dynamic_state {
|
||||||
/**
|
/* FIXME: we keep some viewport info cached (translate, scale) because we
|
||||||
* Bitmask of (1 << VK_DYNAMIC_STATE_*).
|
* use that on more that one place. But note that translate_z and scale_z
|
||||||
* Defines the set of saved dynamic state.
|
* 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_viewport_state viewport;
|
||||||
|
|
||||||
struct v3dv_scissor_state scissor;
|
/* 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
|
||||||
struct {
|
* color_write_masks is easier to cache a 32-bit bitset with 4 bits per
|
||||||
uint32_t front;
|
* attachment.
|
||||||
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;
|
|
||||||
|
|
||||||
uint32_t color_write_enable;
|
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 gfx;
|
||||||
struct v3dv_cmd_pipeline_state compute;
|
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;
|
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;
|
uint32_t dirty;
|
||||||
VkShaderStageFlagBits dirty_descriptor_stages;
|
VkShaderStageFlagBits dirty_descriptor_stages;
|
||||||
VkShaderStageFlagBits dirty_push_constants_stages;
|
VkShaderStageFlagBits dirty_push_constants_stages;
|
||||||
|
|
@ -1606,6 +1561,7 @@ struct v3dv_cmd_buffer_state {
|
||||||
bool tile_aligned_render_area;
|
bool tile_aligned_render_area;
|
||||||
VkRect2D render_area;
|
VkRect2D render_area;
|
||||||
|
|
||||||
|
struct vk_dynamic_graphics_state dynamic_graphics_state;
|
||||||
struct v3dv_dynamic_state dynamic;
|
struct v3dv_dynamic_state dynamic;
|
||||||
|
|
||||||
struct v3dv_cmd_pipeline_state gfx;
|
struct v3dv_cmd_pipeline_state gfx;
|
||||||
|
|
@ -1650,7 +1606,7 @@ struct v3dv_cmd_buffer_state {
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
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,
|
uint32_t vp_idx,
|
||||||
float *translate_z, float *scale_z);
|
float *translate_z, float *scale_z);
|
||||||
|
|
||||||
|
|
@ -2299,7 +2255,8 @@ struct v3dv_pipeline {
|
||||||
uint32_t size_per_thread;
|
uint32_t size_per_thread;
|
||||||
} spill;
|
} 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;
|
struct v3dv_pipeline_layout *layout;
|
||||||
|
|
||||||
|
|
@ -2386,9 +2343,6 @@ struct v3dv_pipeline {
|
||||||
bool is_z16;
|
bool is_z16;
|
||||||
} depth_bias;
|
} depth_bias;
|
||||||
|
|
||||||
/* Depth bounds */
|
|
||||||
bool depth_bounds_test_enabled;
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
void *mem_ctx;
|
void *mem_ctx;
|
||||||
struct util_dynarray data; /* Array of v3dv_pipeline_executable_data */
|
struct util_dynarray data; /* Array of v3dv_pipeline_executable_data */
|
||||||
|
|
|
||||||
|
|
@ -521,7 +521,7 @@ v3dv_write_uniforms_wg_offsets(struct v3dv_cmd_buffer *cmd_buffer,
|
||||||
|
|
||||||
case QUNIFORM_VIEWPORT_Z_OFFSET: {
|
case QUNIFORM_VIEWPORT_Z_OFFSET: {
|
||||||
float translate_z;
|
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);
|
&translate_z, NULL);
|
||||||
cl_aligned_f(&uniforms, translate_z);
|
cl_aligned_f(&uniforms, translate_z);
|
||||||
break;
|
break;
|
||||||
|
|
@ -529,7 +529,7 @@ v3dv_write_uniforms_wg_offsets(struct v3dv_cmd_buffer *cmd_buffer,
|
||||||
|
|
||||||
case QUNIFORM_VIEWPORT_Z_SCALE: {
|
case QUNIFORM_VIEWPORT_Z_SCALE: {
|
||||||
float scale_z;
|
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);
|
NULL, &scale_z);
|
||||||
cl_aligned_f(&uniforms, scale_z);
|
cl_aligned_f(&uniforms, scale_z);
|
||||||
break;
|
break;
|
||||||
|
|
@ -662,7 +662,8 @@ v3dv_write_uniforms_wg_offsets(struct v3dv_cmd_buffer *cmd_buffer,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QUNIFORM_LINE_WIDTH:
|
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;
|
break;
|
||||||
|
|
||||||
case QUNIFORM_AA_LINE_WIDTH:
|
case QUNIFORM_AA_LINE_WIDTH:
|
||||||
|
|
|
||||||
|
|
@ -1329,8 +1329,8 @@ v3dX(cmd_buffer_emit_viewport)(struct v3dv_cmd_buffer *cmd_buffer)
|
||||||
struct v3dv_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
|
struct v3dv_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
|
||||||
assert(pipeline);
|
assert(pipeline);
|
||||||
|
|
||||||
/* FIXME: right now we only support one viewport. viewporst[0] would work
|
/* FIXME: right now we don't support multiViewport so viewports[0] would
|
||||||
* now, would need to change if we allow multiple viewports
|
* work now, but would need to change if we allow multiple viewports.
|
||||||
*/
|
*/
|
||||||
float *vptranslate = dynamic->viewport.translate[0];
|
float *vptranslate = dynamic->viewport.translate[0];
|
||||||
float *vpscale = dynamic->viewport.scale[0];
|
float *vpscale = dynamic->viewport.scale[0];
|
||||||
|
|
@ -1360,7 +1360,7 @@ v3dX(cmd_buffer_emit_viewport)(struct v3dv_cmd_buffer *cmd_buffer)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
float translate_z, scale_z;
|
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);
|
&translate_z, &scale_z);
|
||||||
|
|
||||||
#if V3D_VERSION == 42
|
#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;
|
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
|
void
|
||||||
|
|
@ -1431,52 +1432,50 @@ v3dX(cmd_buffer_emit_stencil)(struct v3dv_cmd_buffer *cmd_buffer)
|
||||||
assert(job);
|
assert(job);
|
||||||
|
|
||||||
struct v3dv_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
|
struct v3dv_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
|
||||||
struct v3dv_dynamic_state *dynamic_state = &cmd_buffer->state.dynamic;
|
struct vk_dynamic_graphics_state *dyn =
|
||||||
|
&cmd_buffer->vk.dynamic_graphics_state;
|
||||||
const uint32_t dynamic_stencil_states = V3DV_DYNAMIC_STENCIL_COMPARE_MASK |
|
|
||||||
V3DV_DYNAMIC_STENCIL_WRITE_MASK |
|
|
||||||
V3DV_DYNAMIC_STENCIL_REFERENCE;
|
|
||||||
|
|
||||||
v3dv_cl_ensure_space_with_branch(&job->bcl,
|
v3dv_cl_ensure_space_with_branch(&job->bcl,
|
||||||
2 * cl_packet_length(STENCIL_CFG));
|
2 * cl_packet_length(STENCIL_CFG));
|
||||||
v3dv_return_if_oom(cmd_buffer, NULL);
|
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;
|
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++) {
|
for (uint32_t i = 0; i < 2; i++) {
|
||||||
if (pipeline->emit_stencil_cfg[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,
|
cl_emit_with_prepacked(&job->bcl, STENCIL_CFG,
|
||||||
pipeline->stencil_cfg[i], config) {
|
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 =
|
config.stencil_test_mask =
|
||||||
i == 0 ? dynamic_state->stencil_compare_mask.front :
|
i == 0 ? front->compare_mask : back->compare_mask;
|
||||||
dynamic_state->stencil_compare_mask.back;
|
|
||||||
}
|
}
|
||||||
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 =
|
config.stencil_write_mask =
|
||||||
i == 0 ? dynamic_state->stencil_write_mask.front :
|
i == 0 ? front->write_mask : back->write_mask;
|
||||||
dynamic_state->stencil_write_mask.back;
|
|
||||||
}
|
}
|
||||||
if (dynamic_state->mask & V3DV_DYNAMIC_STENCIL_REFERENCE) {
|
if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE)) {
|
||||||
config.stencil_ref_value =
|
config.stencil_ref_value =
|
||||||
i == 0 ? dynamic_state->stencil_reference.front :
|
i == 0 ? front->reference : back->reference;
|
||||||
dynamic_state->stencil_reference.back;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cl_emit_prepacked(&job->bcl, &pipeline->stencil_cfg[i]);
|
cl_emit_prepacked(&job->bcl, &pipeline->stencil_cfg[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
emitted_stencil = true;
|
emitted_stencil = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (emitted_stencil) {
|
if (emitted_stencil) {
|
||||||
const uint32_t dynamic_stencil_dirty_flags =
|
BITSET_CLEAR(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_COMPARE_MASK);
|
||||||
V3DV_CMD_DIRTY_STENCIL_COMPARE_MASK |
|
BITSET_CLEAR(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE);
|
||||||
V3DV_CMD_DIRTY_STENCIL_WRITE_MASK |
|
BITSET_CLEAR(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_WRITE_MASK);
|
||||||
V3DV_CMD_DIRTY_STENCIL_REFERENCE;
|
|
||||||
cmd_buffer->state.dirty &= ~dynamic_stencil_dirty_flags;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1492,21 +1491,22 @@ v3dX(cmd_buffer_emit_depth_bias)(struct v3dv_cmd_buffer *cmd_buffer)
|
||||||
struct v3dv_job *job = cmd_buffer->state.job;
|
struct v3dv_job *job = cmd_buffer->state.job;
|
||||||
assert(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_cl_ensure_space_with_branch(&job->bcl, cl_packet_length(DEPTH_OFFSET));
|
||||||
v3dv_return_if_oom(cmd_buffer, NULL);
|
v3dv_return_if_oom(cmd_buffer, NULL);
|
||||||
|
|
||||||
struct v3dv_dynamic_state *dynamic = &cmd_buffer->state.dynamic;
|
|
||||||
cl_emit(&job->bcl, DEPTH_OFFSET, bias) {
|
cl_emit(&job->bcl, DEPTH_OFFSET, bias) {
|
||||||
bias.depth_offset_factor = dynamic->depth_bias.slope_factor;
|
bias.depth_offset_factor = dyn->rs.depth_bias.slope;
|
||||||
bias.depth_offset_units = dynamic->depth_bias.constant_factor;
|
bias.depth_offset_units = dyn->rs.depth_bias.constant;
|
||||||
#if V3D_VERSION <= 42
|
#if V3D_VERSION <= 42
|
||||||
if (pipeline->depth_bias.is_z16)
|
if (pipeline->depth_bias.is_z16)
|
||||||
bias.depth_offset_units *= 256.0f;
|
bias.depth_offset_units *= 256.0f;
|
||||||
#endif
|
#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
|
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
|
* Note that this method is being called as v3dv_job_init flags all state
|
||||||
* as dirty. See FIXME note in v3dv_job_init.
|
* as dirty. See FIXME note in v3dv_job_init.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if V3D_VERSION >= 71
|
#if V3D_VERSION >= 71
|
||||||
struct v3dv_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
|
struct vk_dynamic_graphics_state *dyn =
|
||||||
assert(pipeline);
|
&cmd_buffer->vk.dynamic_graphics_state;
|
||||||
|
|
||||||
if (!pipeline->depth_bounds_test_enabled)
|
if (!dyn->ds.depth.bounds_test.enable)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
struct v3dv_job *job = cmd_buffer->state.job;
|
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_cl_ensure_space_with_branch(&job->bcl, cl_packet_length(DEPTH_BOUNDS_TEST_LIMITS));
|
||||||
v3dv_return_if_oom(cmd_buffer, NULL);
|
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) {
|
cl_emit(&job->bcl, DEPTH_BOUNDS_TEST_LIMITS, bounds) {
|
||||||
bounds.lower_test_limit = dynamic->depth_bounds.min;
|
bounds.lower_test_limit = dyn->ds.depth.bounds_test.min;
|
||||||
bounds.upper_test_limit = dynamic->depth_bounds.max;
|
bounds.upper_test_limit = dyn->ds.depth.bounds_test.max;
|
||||||
}
|
}
|
||||||
|
BITSET_CLEAR(dyn->dirty, MESA_VK_DYNAMIC_DS_DEPTH_BOUNDS_TEST_BOUNDS);
|
||||||
cmd_buffer->state.dirty &= ~V3DV_CMD_DIRTY_DEPTH_BOUNDS;
|
|
||||||
#endif
|
#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;
|
struct v3dv_job *job = cmd_buffer->state.job;
|
||||||
assert(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_cl_ensure_space_with_branch(&job->bcl, cl_packet_length(LINE_WIDTH));
|
||||||
v3dv_return_if_oom(cmd_buffer, NULL);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_buffer->state.dirty &= ~V3DV_CMD_DIRTY_LINE_WIDTH;
|
BITSET_CLEAR(dyn->dirty, MESA_VK_DYNAMIC_RS_LINE_WIDTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -1609,17 +1608,20 @@ v3dX(cmd_buffer_emit_blend)(struct v3dv_cmd_buffer *cmd_buffer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pipeline->blend.needs_color_constants &&
|
if (pipeline->blend.needs_color_constants) {
|
||||||
cmd_buffer->state.dirty & V3DV_CMD_DIRTY_BLEND_CONSTANTS) {
|
const struct vk_dynamic_graphics_state *dyn =
|
||||||
struct v3dv_dynamic_state *dynamic = &cmd_buffer->state.dynamic;
|
&cmd_buffer->vk.dynamic_graphics_state;
|
||||||
|
|
||||||
cl_emit(&job->bcl, BLEND_CONSTANT_COLOR, color) {
|
cl_emit(&job->bcl, BLEND_CONSTANT_COLOR, color) {
|
||||||
color.red_f16 = _mesa_float_to_half(dynamic->blend_constants[0]);
|
color.red_f16 = _mesa_float_to_half(dyn->cb.blend_constants[0]);
|
||||||
color.green_f16 = _mesa_float_to_half(dynamic->blend_constants[1]);
|
color.green_f16 = _mesa_float_to_half(dyn->cb.blend_constants[1]);
|
||||||
color.blue_f16 = _mesa_float_to_half(dynamic->blend_constants[2]);
|
color.blue_f16 = _mesa_float_to_half(dyn->cb.blend_constants[2]);
|
||||||
color.alpha_f16 = _mesa_float_to_half(dynamic->blend_constants[3]);
|
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
|
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));
|
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_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
|
||||||
struct v3dv_dynamic_state *dynamic = &cmd_buffer->state.dynamic;
|
struct v3dv_dynamic_state *v3dv_dyn = &cmd_buffer->state.dynamic;
|
||||||
uint32_t color_write_mask = ~dynamic->color_write_enable |
|
uint32_t color_write_mask = ~v3dv_dyn->color_write_enable |
|
||||||
pipeline->blend.color_write_masks;
|
pipeline->blend.color_write_masks;
|
||||||
|
|
||||||
#if V3D_VERSION <= 42
|
#if V3D_VERSION <= 42
|
||||||
/* Only 4 RTs */
|
/* Only 4 RTs */
|
||||||
color_write_mask &= 0xffff;
|
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;
|
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
|
static void
|
||||||
|
|
|
||||||
|
|
@ -293,7 +293,8 @@ pack_single_stencil_cfg(struct v3dv_pipeline *pipeline,
|
||||||
uint8_t *stencil_cfg,
|
uint8_t *stencil_cfg,
|
||||||
bool is_front,
|
bool is_front,
|
||||||
bool is_back,
|
bool is_back,
|
||||||
const VkStencilOpState *stencil_state)
|
const VkStencilOpState *stencil_state,
|
||||||
|
const struct vk_graphics_pipeline_state *state)
|
||||||
{
|
{
|
||||||
/* From the Vulkan spec:
|
/* From the Vulkan spec:
|
||||||
*
|
*
|
||||||
|
|
@ -311,16 +312,16 @@ pack_single_stencil_cfg(struct v3dv_pipeline *pipeline,
|
||||||
* the old.
|
* the old.
|
||||||
*/
|
*/
|
||||||
const uint8_t write_mask =
|
const uint8_t write_mask =
|
||||||
pipeline->dynamic_state.mask & V3DV_DYNAMIC_STENCIL_WRITE_MASK ?
|
BITSET_TEST(state->dynamic, MESA_VK_DYNAMIC_DS_STENCIL_WRITE_MASK) ?
|
||||||
0 : stencil_state->writeMask & 0xff;
|
0 : stencil_state->writeMask & 0xff;
|
||||||
|
|
||||||
const uint8_t compare_mask =
|
const uint8_t compare_mask =
|
||||||
pipeline->dynamic_state.mask & V3DV_DYNAMIC_STENCIL_COMPARE_MASK ?
|
BITSET_TEST(state->dynamic, MESA_VK_DYNAMIC_DS_STENCIL_COMPARE_MASK) ?
|
||||||
0 : stencil_state->compareMask & 0xff;
|
0 : stencil_state->compareMask & 0xff;
|
||||||
|
|
||||||
const uint8_t reference =
|
const uint8_t reference =
|
||||||
pipeline->dynamic_state.mask & V3DV_DYNAMIC_STENCIL_COMPARE_MASK ?
|
BITSET_TEST(state->dynamic, MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE) ?
|
||||||
0 : stencil_state->reference & 0xff;
|
0 : stencil_state->reference & 0xff;
|
||||||
|
|
||||||
v3dvx_pack(stencil_cfg, STENCIL_CFG, config) {
|
v3dvx_pack(stencil_cfg, STENCIL_CFG, config) {
|
||||||
config.front_config = is_front;
|
config.front_config = is_front;
|
||||||
|
|
@ -337,7 +338,8 @@ pack_single_stencil_cfg(struct v3dv_pipeline *pipeline,
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pack_stencil_cfg(struct v3dv_pipeline *pipeline,
|
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));
|
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)
|
if (ri->stencil_attachment_format == VK_FORMAT_UNDEFINED)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const uint32_t dynamic_stencil_states = V3DV_DYNAMIC_STENCIL_COMPARE_MASK |
|
const bool any_dynamic_stencil_states =
|
||||||
V3DV_DYNAMIC_STENCIL_WRITE_MASK |
|
BITSET_TEST(state->dynamic, MESA_VK_DYNAMIC_DS_STENCIL_WRITE_MASK) ||
|
||||||
V3DV_DYNAMIC_STENCIL_REFERENCE;
|
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
|
/* If front != back or we have dynamic stencil state we can't emit a single
|
||||||
* packet for both faces.
|
* packet for both faces.
|
||||||
*/
|
*/
|
||||||
bool needs_front_and_back = false;
|
bool needs_front_and_back = false;
|
||||||
if ((pipeline->dynamic_state.mask & dynamic_stencil_states) ||
|
if ((any_dynamic_stencil_states) ||
|
||||||
memcmp(&ds_info->front, &ds_info->back, sizeof(ds_info->front)))
|
memcmp(&ds_info->front, &ds_info->back, sizeof(ds_info->front))) {
|
||||||
needs_front_and_back = true;
|
needs_front_and_back = true;
|
||||||
|
}
|
||||||
|
|
||||||
/* If the front and back configurations are the same we can emit both with
|
/* If the front and back configurations are the same we can emit both with
|
||||||
* a single packet.
|
* a single packet.
|
||||||
|
|
@ -367,16 +370,22 @@ pack_stencil_cfg(struct v3dv_pipeline *pipeline,
|
||||||
pipeline->emit_stencil_cfg[0] = true;
|
pipeline->emit_stencil_cfg[0] = true;
|
||||||
if (!needs_front_and_back) {
|
if (!needs_front_and_back) {
|
||||||
pack_single_stencil_cfg(pipeline, pipeline->stencil_cfg[0],
|
pack_single_stencil_cfg(pipeline, pipeline->stencil_cfg[0],
|
||||||
true, true, &ds_info->front);
|
true, true, &ds_info->front, state);
|
||||||
} else {
|
} else {
|
||||||
pipeline->emit_stencil_cfg[1] = true;
|
pipeline->emit_stencil_cfg[1] = true;
|
||||||
pack_single_stencil_cfg(pipeline, pipeline->stencil_cfg[0],
|
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],
|
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
|
void
|
||||||
v3dX(pipeline_pack_state)(struct v3dv_pipeline *pipeline,
|
v3dX(pipeline_pack_state)(struct v3dv_pipeline *pipeline,
|
||||||
const VkPipelineColorBlendStateCreateInfo *cb_info,
|
const VkPipelineColorBlendStateCreateInfo *cb_info,
|
||||||
|
|
@ -384,11 +393,12 @@ v3dX(pipeline_pack_state)(struct v3dv_pipeline *pipeline,
|
||||||
const VkPipelineRasterizationStateCreateInfo *rs_info,
|
const VkPipelineRasterizationStateCreateInfo *rs_info,
|
||||||
const VkPipelineRasterizationProvokingVertexStateCreateInfoEXT *pv_info,
|
const VkPipelineRasterizationProvokingVertexStateCreateInfoEXT *pv_info,
|
||||||
const VkPipelineRasterizationLineStateCreateInfoEXT *ls_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_blend(pipeline, cb_info);
|
||||||
pack_cfg_bits(pipeline, ds_info, rs_info, pv_info, ls_info, ms_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
|
static void
|
||||||
|
|
|
||||||
|
|
@ -318,7 +318,8 @@ v3dX(pipeline_pack_state)(struct v3dv_pipeline *pipeline,
|
||||||
const VkPipelineRasterizationStateCreateInfo *rs_info,
|
const VkPipelineRasterizationStateCreateInfo *rs_info,
|
||||||
const VkPipelineRasterizationProvokingVertexStateCreateInfoEXT *pv_info,
|
const VkPipelineRasterizationProvokingVertexStateCreateInfoEXT *pv_info,
|
||||||
const VkPipelineRasterizationLineStateCreateInfoEXT *ls_info,
|
const VkPipelineRasterizationLineStateCreateInfoEXT *ls_info,
|
||||||
const VkPipelineMultisampleStateCreateInfo *ms_info);
|
const VkPipelineMultisampleStateCreateInfo *ms_info,
|
||||||
|
const struct vk_graphics_pipeline_state *state);
|
||||||
void
|
void
|
||||||
v3dX(pipeline_pack_compile_state)(struct v3dv_pipeline *pipeline,
|
v3dX(pipeline_pack_compile_state)(struct v3dv_pipeline *pipeline,
|
||||||
const VkPipelineVertexInputStateCreateInfo *vi_info,
|
const VkPipelineVertexInputStateCreateInfo *vi_info,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue