17ec681f3Smrg/*
27ec681f3Smrg * Copyright © 2019 Red Hat.
37ec681f3Smrg *
47ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a
57ec681f3Smrg * copy of this software and associated documentation files (the "Software"),
67ec681f3Smrg * to deal in the Software without restriction, including without limitation
77ec681f3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
87ec681f3Smrg * and/or sell copies of the Software, and to permit persons to whom the
97ec681f3Smrg * Software is furnished to do so, subject to the following conditions:
107ec681f3Smrg *
117ec681f3Smrg * The above copyright notice and this permission notice (including the next
127ec681f3Smrg * paragraph) shall be included in all copies or substantial portions of the
137ec681f3Smrg * Software.
147ec681f3Smrg *
157ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
167ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
177ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
187ec681f3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
197ec681f3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
207ec681f3Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
217ec681f3Smrg * IN THE SOFTWARE.
227ec681f3Smrg */
237ec681f3Smrg
247ec681f3Smrg/* use a gallium context to execute a command buffer */
257ec681f3Smrg
267ec681f3Smrg#include "lvp_private.h"
277ec681f3Smrg
287ec681f3Smrg#include "pipe/p_context.h"
297ec681f3Smrg#include "pipe/p_state.h"
307ec681f3Smrg#include "lvp_conv.h"
317ec681f3Smrg
327ec681f3Smrg#include "pipe/p_shader_tokens.h"
337ec681f3Smrg#include "tgsi/tgsi_text.h"
347ec681f3Smrg#include "tgsi/tgsi_parse.h"
357ec681f3Smrg
367ec681f3Smrg#include "util/format/u_format.h"
377ec681f3Smrg#include "util/u_surface.h"
387ec681f3Smrg#include "util/u_sampler.h"
397ec681f3Smrg#include "util/u_box.h"
407ec681f3Smrg#include "util/u_inlines.h"
417ec681f3Smrg#include "util/u_prim.h"
427ec681f3Smrg#include "util/u_prim_restart.h"
437ec681f3Smrg#include "util/format/u_format_zs.h"
447ec681f3Smrg
457ec681f3Smrg#include "vk_util.h"
467ec681f3Smrg
477ec681f3Smrg#define VK_PROTOTYPES
487ec681f3Smrg#include <vulkan/vulkan.h>
497ec681f3Smrg
507ec681f3Smrg#define DOUBLE_EQ(a, b) (fabs((a) - (b)) < DBL_EPSILON)
517ec681f3Smrg
527ec681f3Smrgenum gs_output {
537ec681f3Smrg  GS_OUTPUT_NONE,
547ec681f3Smrg  GS_OUTPUT_NOT_LINES,
557ec681f3Smrg  GS_OUTPUT_LINES,
567ec681f3Smrg};
577ec681f3Smrg
587ec681f3Smrgstruct rendering_state {
597ec681f3Smrg   struct pipe_context *pctx;
607ec681f3Smrg   struct cso_context *cso;
617ec681f3Smrg
627ec681f3Smrg   bool blend_dirty;
637ec681f3Smrg   bool rs_dirty;
647ec681f3Smrg   bool dsa_dirty;
657ec681f3Smrg   bool stencil_ref_dirty;
667ec681f3Smrg   bool clip_state_dirty;
677ec681f3Smrg   bool blend_color_dirty;
687ec681f3Smrg   bool ve_dirty;
697ec681f3Smrg   bool vb_dirty;
707ec681f3Smrg   bool constbuf_dirty[PIPE_SHADER_TYPES];
717ec681f3Smrg   bool pcbuf_dirty[PIPE_SHADER_TYPES];
727ec681f3Smrg   bool vp_dirty;
737ec681f3Smrg   bool scissor_dirty;
747ec681f3Smrg   bool ib_dirty;
757ec681f3Smrg   bool sample_mask_dirty;
767ec681f3Smrg   bool min_samples_dirty;
777ec681f3Smrg   struct pipe_draw_indirect_info indirect_info;
787ec681f3Smrg   struct pipe_draw_info info;
797ec681f3Smrg
807ec681f3Smrg   struct pipe_grid_info dispatch_info;
817ec681f3Smrg   struct pipe_framebuffer_state framebuffer;
827ec681f3Smrg
837ec681f3Smrg   struct pipe_blend_state blend_state;
847ec681f3Smrg   struct {
857ec681f3Smrg      float offset_units;
867ec681f3Smrg      float offset_scale;
877ec681f3Smrg      float offset_clamp;
887ec681f3Smrg      bool enabled;
897ec681f3Smrg   } depth_bias;
907ec681f3Smrg   struct pipe_rasterizer_state rs_state;
917ec681f3Smrg   struct pipe_depth_stencil_alpha_state dsa_state;
927ec681f3Smrg
937ec681f3Smrg   struct pipe_blend_color blend_color;
947ec681f3Smrg   struct pipe_stencil_ref stencil_ref;
957ec681f3Smrg   struct pipe_clip_state clip_state;
967ec681f3Smrg
977ec681f3Smrg   int num_scissors;
987ec681f3Smrg   struct pipe_scissor_state scissors[16];
997ec681f3Smrg
1007ec681f3Smrg   int num_viewports;
1017ec681f3Smrg   struct pipe_viewport_state viewports[16];
1027ec681f3Smrg
1037ec681f3Smrg   uint8_t patch_vertices;
1047ec681f3Smrg   ubyte index_size;
1057ec681f3Smrg   unsigned index_offset;
1067ec681f3Smrg   struct pipe_resource *index_buffer;
1077ec681f3Smrg   struct pipe_constant_buffer pc_buffer[PIPE_SHADER_TYPES];
1087ec681f3Smrg   struct pipe_constant_buffer const_buffer[PIPE_SHADER_TYPES][16];
1097ec681f3Smrg   int num_const_bufs[PIPE_SHADER_TYPES];
1107ec681f3Smrg   int num_vb;
1117ec681f3Smrg   unsigned start_vb;
1127ec681f3Smrg   struct pipe_vertex_buffer vb[PIPE_MAX_ATTRIBS];
1137ec681f3Smrg   struct cso_velems_state velem;
1147ec681f3Smrg
1157ec681f3Smrg   struct pipe_sampler_view *sv[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
1167ec681f3Smrg   int num_sampler_views[PIPE_SHADER_TYPES];
1177ec681f3Smrg   struct pipe_sampler_state ss[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
1187ec681f3Smrg   /* cso_context api is stupid */
1197ec681f3Smrg   const struct pipe_sampler_state *cso_ss_ptr[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
1207ec681f3Smrg   int num_sampler_states[PIPE_SHADER_TYPES];
1217ec681f3Smrg   bool sv_dirty[PIPE_SHADER_TYPES];
1227ec681f3Smrg   bool ss_dirty[PIPE_SHADER_TYPES];
1237ec681f3Smrg
1247ec681f3Smrg   struct pipe_image_view iv[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_IMAGES];
1257ec681f3Smrg   int num_shader_images[PIPE_SHADER_TYPES];
1267ec681f3Smrg   struct pipe_shader_buffer sb[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_BUFFERS];
1277ec681f3Smrg   int num_shader_buffers[PIPE_SHADER_TYPES];
1287ec681f3Smrg   bool iv_dirty[PIPE_SHADER_TYPES];
1297ec681f3Smrg   bool sb_dirty[PIPE_SHADER_TYPES];
1307ec681f3Smrg   bool disable_multisample;
1317ec681f3Smrg   enum gs_output gs_output_lines : 2;
1327ec681f3Smrg
1337ec681f3Smrg   uint32_t color_write_disables:8;
1347ec681f3Smrg   bool has_color_write_disables:1;
1357ec681f3Smrg   uint32_t pad:13;
1367ec681f3Smrg
1377ec681f3Smrg   void *ss_cso[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
1387ec681f3Smrg   void *velems_cso;
1397ec681f3Smrg
1407ec681f3Smrg   uint8_t push_constants[128 * 4];
1417ec681f3Smrg
1427ec681f3Smrg   const struct lvp_render_pass *pass;
1437ec681f3Smrg   uint32_t subpass;
1447ec681f3Smrg   const struct lvp_framebuffer *vk_framebuffer;
1457ec681f3Smrg   VkRect2D render_area;
1467ec681f3Smrg
1477ec681f3Smrg   uint32_t sample_mask;
1487ec681f3Smrg   unsigned min_samples;
1497ec681f3Smrg
1507ec681f3Smrg   struct lvp_image_view **imageless_views;
1517ec681f3Smrg   struct lvp_attachment_state *attachments;
1527ec681f3Smrg   VkImageAspectFlags *pending_clear_aspects;
1537ec681f3Smrg   uint32_t *cleared_views;
1547ec681f3Smrg   int num_pending_aspects;
1557ec681f3Smrg
1567ec681f3Smrg   uint32_t num_so_targets;
1577ec681f3Smrg   struct pipe_stream_output_target *so_targets[PIPE_MAX_SO_BUFFERS];
1587ec681f3Smrg   uint32_t so_offsets[PIPE_MAX_SO_BUFFERS];
1597ec681f3Smrg};
1607ec681f3Smrg
1617ec681f3SmrgALWAYS_INLINE static void
1627ec681f3Smrgassert_subresource_layers(const struct pipe_resource *pres, const VkImageSubresourceLayers *layers, const VkOffset3D *offsets)
1637ec681f3Smrg{
1647ec681f3Smrg#ifndef NDEBUG
1657ec681f3Smrg   if (pres->target == PIPE_TEXTURE_3D) {
1667ec681f3Smrg      assert(layers->baseArrayLayer == 0);
1677ec681f3Smrg      assert(layers->layerCount == 1);
1687ec681f3Smrg      assert(offsets[0].z <= pres->depth0);
1697ec681f3Smrg      assert(offsets[1].z <= pres->depth0);
1707ec681f3Smrg   } else {
1717ec681f3Smrg      assert(layers->baseArrayLayer < pres->array_size);
1727ec681f3Smrg      assert(layers->baseArrayLayer + layers->layerCount <= pres->array_size);
1737ec681f3Smrg      assert(offsets[0].z == 0);
1747ec681f3Smrg      assert(offsets[1].z == 1);
1757ec681f3Smrg   }
1767ec681f3Smrg#endif
1777ec681f3Smrg}
1787ec681f3Smrg
1797ec681f3Smrgstatic void emit_compute_state(struct rendering_state *state)
1807ec681f3Smrg{
1817ec681f3Smrg   if (state->iv_dirty[PIPE_SHADER_COMPUTE]) {
1827ec681f3Smrg      state->pctx->set_shader_images(state->pctx, PIPE_SHADER_COMPUTE,
1837ec681f3Smrg                                     0, state->num_shader_images[PIPE_SHADER_COMPUTE],
1847ec681f3Smrg                                     0, state->iv[PIPE_SHADER_COMPUTE]);
1857ec681f3Smrg      state->iv_dirty[PIPE_SHADER_COMPUTE] = false;
1867ec681f3Smrg   }
1877ec681f3Smrg
1887ec681f3Smrg   if (state->pcbuf_dirty[PIPE_SHADER_COMPUTE]) {
1897ec681f3Smrg      state->pctx->set_constant_buffer(state->pctx, PIPE_SHADER_COMPUTE,
1907ec681f3Smrg                                       0, false, &state->pc_buffer[PIPE_SHADER_COMPUTE]);
1917ec681f3Smrg      state->pcbuf_dirty[PIPE_SHADER_COMPUTE] = false;
1927ec681f3Smrg   }
1937ec681f3Smrg
1947ec681f3Smrg   if (state->constbuf_dirty[PIPE_SHADER_COMPUTE]) {
1957ec681f3Smrg      for (unsigned i = 0; i < state->num_const_bufs[PIPE_SHADER_COMPUTE]; i++)
1967ec681f3Smrg         state->pctx->set_constant_buffer(state->pctx, PIPE_SHADER_COMPUTE,
1977ec681f3Smrg                                          i + 1, false, &state->const_buffer[PIPE_SHADER_COMPUTE][i]);
1987ec681f3Smrg      state->constbuf_dirty[PIPE_SHADER_COMPUTE] = false;
1997ec681f3Smrg   }
2007ec681f3Smrg
2017ec681f3Smrg   if (state->sb_dirty[PIPE_SHADER_COMPUTE]) {
2027ec681f3Smrg      state->pctx->set_shader_buffers(state->pctx, PIPE_SHADER_COMPUTE,
2037ec681f3Smrg                                      0, state->num_shader_buffers[PIPE_SHADER_COMPUTE],
2047ec681f3Smrg                                      state->sb[PIPE_SHADER_COMPUTE], 0);
2057ec681f3Smrg      state->sb_dirty[PIPE_SHADER_COMPUTE] = false;
2067ec681f3Smrg   }
2077ec681f3Smrg
2087ec681f3Smrg   if (state->sv_dirty[PIPE_SHADER_COMPUTE]) {
2097ec681f3Smrg      state->pctx->set_sampler_views(state->pctx, PIPE_SHADER_COMPUTE, 0, state->num_sampler_views[PIPE_SHADER_COMPUTE],
2107ec681f3Smrg                                     0, false, state->sv[PIPE_SHADER_COMPUTE]);
2117ec681f3Smrg      state->sv_dirty[PIPE_SHADER_COMPUTE] = false;
2127ec681f3Smrg   }
2137ec681f3Smrg
2147ec681f3Smrg   if (state->ss_dirty[PIPE_SHADER_COMPUTE]) {
2157ec681f3Smrg      for (unsigned i = 0; i < state->num_sampler_states[PIPE_SHADER_COMPUTE]; i++) {
2167ec681f3Smrg         if (state->ss_cso[PIPE_SHADER_COMPUTE][i])
2177ec681f3Smrg            state->pctx->delete_sampler_state(state->pctx, state->ss_cso[PIPE_SHADER_COMPUTE][i]);
2187ec681f3Smrg         state->ss_cso[PIPE_SHADER_COMPUTE][i] = state->pctx->create_sampler_state(state->pctx, &state->ss[PIPE_SHADER_COMPUTE][i]);
2197ec681f3Smrg      }
2207ec681f3Smrg      state->pctx->bind_sampler_states(state->pctx, PIPE_SHADER_COMPUTE, 0, state->num_sampler_states[PIPE_SHADER_COMPUTE], state->ss_cso[PIPE_SHADER_COMPUTE]);
2217ec681f3Smrg      state->ss_dirty[PIPE_SHADER_COMPUTE] = false;
2227ec681f3Smrg   }
2237ec681f3Smrg}
2247ec681f3Smrg
2257ec681f3Smrgstatic void emit_state(struct rendering_state *state)
2267ec681f3Smrg{
2277ec681f3Smrg   int sh;
2287ec681f3Smrg   if (state->blend_dirty) {
2297ec681f3Smrg      uint32_t mask = 0;
2307ec681f3Smrg      /* zero out the colormask values for disabled attachments */
2317ec681f3Smrg      if (state->has_color_write_disables && state->color_write_disables) {
2327ec681f3Smrg         u_foreach_bit(att, state->color_write_disables) {
2337ec681f3Smrg            mask |= state->blend_state.rt[att].colormask << (att * 4);
2347ec681f3Smrg            state->blend_state.rt[att].colormask = 0;
2357ec681f3Smrg         }
2367ec681f3Smrg      }
2377ec681f3Smrg      cso_set_blend(state->cso, &state->blend_state);
2387ec681f3Smrg      /* reset colormasks using saved bitmask */
2397ec681f3Smrg      if (state->has_color_write_disables && state->color_write_disables) {
2407ec681f3Smrg         const uint32_t att_mask = BITFIELD_MASK(4);
2417ec681f3Smrg         u_foreach_bit(att, state->color_write_disables) {
2427ec681f3Smrg            state->blend_state.rt[att].colormask = (mask >> (att * 4)) & att_mask;
2437ec681f3Smrg         }
2447ec681f3Smrg      }
2457ec681f3Smrg      state->blend_dirty = false;
2467ec681f3Smrg   }
2477ec681f3Smrg
2487ec681f3Smrg   if (state->rs_dirty) {
2497ec681f3Smrg      bool ms = state->rs_state.multisample;
2507ec681f3Smrg      if (state->disable_multisample &&
2517ec681f3Smrg          (state->gs_output_lines == GS_OUTPUT_LINES ||
2527ec681f3Smrg           (state->gs_output_lines == GS_OUTPUT_NONE && u_reduced_prim(state->info.mode) == PIPE_PRIM_LINES)))
2537ec681f3Smrg         state->rs_state.multisample = false;
2547ec681f3Smrg      assert(offsetof(struct pipe_rasterizer_state, offset_clamp) - offsetof(struct pipe_rasterizer_state, offset_units) == sizeof(float) * 2);
2557ec681f3Smrg      if (state->depth_bias.enabled) {
2567ec681f3Smrg         memcpy(&state->rs_state.offset_units, &state->depth_bias, sizeof(float) * 3);
2577ec681f3Smrg      } else {
2587ec681f3Smrg         memset(&state->rs_state.offset_units, 0, sizeof(float) * 3);
2597ec681f3Smrg      }
2607ec681f3Smrg      cso_set_rasterizer(state->cso, &state->rs_state);
2617ec681f3Smrg      state->rs_dirty = false;
2627ec681f3Smrg      state->rs_state.multisample = ms;
2637ec681f3Smrg   }
2647ec681f3Smrg
2657ec681f3Smrg   if (state->dsa_dirty) {
2667ec681f3Smrg      cso_set_depth_stencil_alpha(state->cso, &state->dsa_state);
2677ec681f3Smrg      state->dsa_dirty = false;
2687ec681f3Smrg   }
2697ec681f3Smrg
2707ec681f3Smrg   if (state->sample_mask_dirty) {
2717ec681f3Smrg      cso_set_sample_mask(state->cso, state->sample_mask);
2727ec681f3Smrg      state->sample_mask_dirty = false;
2737ec681f3Smrg   }
2747ec681f3Smrg
2757ec681f3Smrg   if (state->min_samples_dirty) {
2767ec681f3Smrg      cso_set_min_samples(state->cso, state->min_samples);
2777ec681f3Smrg      state->min_samples_dirty = false;
2787ec681f3Smrg   }
2797ec681f3Smrg
2807ec681f3Smrg   if (state->blend_color_dirty) {
2817ec681f3Smrg      state->pctx->set_blend_color(state->pctx, &state->blend_color);
2827ec681f3Smrg      state->blend_color_dirty = false;
2837ec681f3Smrg   }
2847ec681f3Smrg
2857ec681f3Smrg   if (state->stencil_ref_dirty) {
2867ec681f3Smrg      cso_set_stencil_ref(state->cso, state->stencil_ref);
2877ec681f3Smrg      state->stencil_ref_dirty = false;
2887ec681f3Smrg   }
2897ec681f3Smrg
2907ec681f3Smrg   if (state->vb_dirty) {
2917ec681f3Smrg      cso_set_vertex_buffers(state->cso, state->start_vb, state->num_vb, state->vb);
2927ec681f3Smrg      state->vb_dirty = false;
2937ec681f3Smrg   }
2947ec681f3Smrg
2957ec681f3Smrg   if (state->ve_dirty) {
2967ec681f3Smrg      cso_set_vertex_elements(state->cso, &state->velem);
2977ec681f3Smrg      state->ve_dirty = false;
2987ec681f3Smrg   }
2997ec681f3Smrg
3007ec681f3Smrg
3017ec681f3Smrg   for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
3027ec681f3Smrg      if (state->constbuf_dirty[sh]) {
3037ec681f3Smrg         for (unsigned idx = 0; idx < state->num_const_bufs[sh]; idx++)
3047ec681f3Smrg            state->pctx->set_constant_buffer(state->pctx, sh,
3057ec681f3Smrg                                             idx + 1, false, &state->const_buffer[sh][idx]);
3067ec681f3Smrg      }
3077ec681f3Smrg      state->constbuf_dirty[sh] = false;
3087ec681f3Smrg   }
3097ec681f3Smrg
3107ec681f3Smrg   for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
3117ec681f3Smrg      if (state->pcbuf_dirty[sh]) {
3127ec681f3Smrg         state->pctx->set_constant_buffer(state->pctx, sh,
3137ec681f3Smrg                                          0, false, &state->pc_buffer[sh]);
3147ec681f3Smrg      }
3157ec681f3Smrg   }
3167ec681f3Smrg
3177ec681f3Smrg   for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
3187ec681f3Smrg      if (state->sb_dirty[sh]) {
3197ec681f3Smrg         state->pctx->set_shader_buffers(state->pctx, sh,
3207ec681f3Smrg                                         0, state->num_shader_buffers[sh],
3217ec681f3Smrg                                         state->sb[sh], 0);
3227ec681f3Smrg      }
3237ec681f3Smrg   }
3247ec681f3Smrg
3257ec681f3Smrg   for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
3267ec681f3Smrg      if (state->iv_dirty[sh]) {
3277ec681f3Smrg         state->pctx->set_shader_images(state->pctx, sh,
3287ec681f3Smrg                                        0, state->num_shader_images[sh], 0,
3297ec681f3Smrg                                        state->iv[sh]);
3307ec681f3Smrg      }
3317ec681f3Smrg   }
3327ec681f3Smrg
3337ec681f3Smrg   for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
3347ec681f3Smrg
3357ec681f3Smrg      if (!state->sv_dirty[sh])
3367ec681f3Smrg         continue;
3377ec681f3Smrg
3387ec681f3Smrg      state->pctx->set_sampler_views(state->pctx, sh, 0, state->num_sampler_views[sh],
3397ec681f3Smrg                                     0, false, state->sv[sh]);
3407ec681f3Smrg      state->sv_dirty[sh] = false;
3417ec681f3Smrg   }
3427ec681f3Smrg
3437ec681f3Smrg   for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
3447ec681f3Smrg      if (!state->ss_dirty[sh])
3457ec681f3Smrg         continue;
3467ec681f3Smrg
3477ec681f3Smrg      cso_set_samplers(state->cso, sh, state->num_sampler_states[sh], state->cso_ss_ptr[sh]);
3487ec681f3Smrg   }
3497ec681f3Smrg
3507ec681f3Smrg   if (state->vp_dirty) {
3517ec681f3Smrg      state->pctx->set_viewport_states(state->pctx, 0, state->num_viewports, state->viewports);
3527ec681f3Smrg      state->vp_dirty = false;
3537ec681f3Smrg   }
3547ec681f3Smrg
3557ec681f3Smrg   if (state->scissor_dirty) {
3567ec681f3Smrg      state->pctx->set_scissor_states(state->pctx, 0, state->num_scissors, state->scissors);
3577ec681f3Smrg      state->scissor_dirty = false;
3587ec681f3Smrg   }
3597ec681f3Smrg}
3607ec681f3Smrg
3617ec681f3Smrgstatic void handle_compute_pipeline(struct vk_cmd_queue_entry *cmd,
3627ec681f3Smrg                                    struct rendering_state *state)
3637ec681f3Smrg{
3647ec681f3Smrg   LVP_FROM_HANDLE(lvp_pipeline, pipeline, cmd->u.bind_pipeline.pipeline);
3657ec681f3Smrg
3667ec681f3Smrg   state->dispatch_info.block[0] = pipeline->pipeline_nir[MESA_SHADER_COMPUTE]->info.workgroup_size[0];
3677ec681f3Smrg   state->dispatch_info.block[1] = pipeline->pipeline_nir[MESA_SHADER_COMPUTE]->info.workgroup_size[1];
3687ec681f3Smrg   state->dispatch_info.block[2] = pipeline->pipeline_nir[MESA_SHADER_COMPUTE]->info.workgroup_size[2];
3697ec681f3Smrg   state->pctx->bind_compute_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_COMPUTE]);
3707ec681f3Smrg}
3717ec681f3Smrg
3727ec681f3Smrgstatic void
3737ec681f3Smrgget_viewport_xform(const VkViewport *viewport,
3747ec681f3Smrg                   float scale[3], float translate[3])
3757ec681f3Smrg{
3767ec681f3Smrg   float x = viewport->x;
3777ec681f3Smrg   float y = viewport->y;
3787ec681f3Smrg   float half_width = 0.5f * viewport->width;
3797ec681f3Smrg   float half_height = 0.5f * viewport->height;
3807ec681f3Smrg   double n = viewport->minDepth;
3817ec681f3Smrg   double f = viewport->maxDepth;
3827ec681f3Smrg
3837ec681f3Smrg   scale[0] = half_width;
3847ec681f3Smrg   translate[0] = half_width + x;
3857ec681f3Smrg   scale[1] = half_height;
3867ec681f3Smrg   translate[1] = half_height + y;
3877ec681f3Smrg
3887ec681f3Smrg   scale[2] = (f - n);
3897ec681f3Smrg   translate[2] = n;
3907ec681f3Smrg}
3917ec681f3Smrg
3927ec681f3Smrg/* enum re-indexing:
3937ec681f3Smrg
3947ec681f3Smrg    VK_DYNAMIC_STATE_VIEWPORT
3957ec681f3Smrg    VK_DYNAMIC_STATE_SCISSOR
3967ec681f3Smrg    VK_DYNAMIC_STATE_LINE_WIDTH
3977ec681f3Smrg    VK_DYNAMIC_STATE_DEPTH_BIAS
3987ec681f3Smrg    VK_DYNAMIC_STATE_BLEND_CONSTANTS
3997ec681f3Smrg    VK_DYNAMIC_STATE_DEPTH_BOUNDS
4007ec681f3Smrg    VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK
4017ec681f3Smrg    VK_DYNAMIC_STATE_STENCIL_WRITE_MASK
4027ec681f3Smrg    VK_DYNAMIC_STATE_STENCIL_REFERENCE
4037ec681f3Smrg
4047ec681f3Smrg    VK_DYNAMIC_STATE_LINE_STIPPLE_EXT
4057ec681f3Smrg
4067ec681f3Smrg    VK_DYNAMIC_STATE_CULL_MODE_EXT
4077ec681f3Smrg    VK_DYNAMIC_STATE_FRONT_FACE_EXT
4087ec681f3Smrg    VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT
4097ec681f3Smrg    VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT
4107ec681f3Smrg    VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT
4117ec681f3Smrg    VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT
4127ec681f3Smrg    VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT
4137ec681f3Smrg    VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT
4147ec681f3Smrg    VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT
4157ec681f3Smrg    VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT
4167ec681f3Smrg    VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT
4177ec681f3Smrg    VK_DYNAMIC_STATE_STENCIL_OP_EXT
4187ec681f3Smrg
4197ec681f3Smrg    VK_DYNAMIC_STATE_VERTEX_INPUT_EXT
4207ec681f3Smrg
4217ec681f3Smrg    VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT
4227ec681f3Smrg    VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT
4237ec681f3Smrg    VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT
4247ec681f3Smrg    VK_DYNAMIC_STATE_LOGIC_OP_EXT
4257ec681f3Smrg    VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT
4267ec681f3Smrg
4277ec681f3Smrg    VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT
4287ec681f3Smrg*/
4297ec681f3Smrgstatic int conv_dynamic_state_idx(VkDynamicState dyn_state)
4307ec681f3Smrg{
4317ec681f3Smrg   if (dyn_state <= VK_DYNAMIC_STATE_STENCIL_REFERENCE)
4327ec681f3Smrg      return dyn_state;
4337ec681f3Smrg   if (dyn_state == VK_DYNAMIC_STATE_LINE_STIPPLE_EXT)
4347ec681f3Smrg      /* this one has a weird id, map after the normal dynamic state ones */
4357ec681f3Smrg      return VK_DYNAMIC_STATE_STENCIL_REFERENCE + 1;
4367ec681f3Smrg   if (dyn_state >= VK_DYNAMIC_STATE_CULL_MODE_EXT &&
4377ec681f3Smrg       dyn_state <= VK_DYNAMIC_STATE_STENCIL_OP_EXT)
4387ec681f3Smrg      return dyn_state - VK_DYNAMIC_STATE_CULL_MODE_EXT + VK_DYNAMIC_STATE_STENCIL_REFERENCE + 2;
4397ec681f3Smrg   if (dyn_state == VK_DYNAMIC_STATE_VERTEX_INPUT_EXT)
4407ec681f3Smrg      return (VK_DYNAMIC_STATE_STENCIL_OP_EXT - VK_DYNAMIC_STATE_CULL_MODE_EXT) + VK_DYNAMIC_STATE_STENCIL_REFERENCE + 2 + 1;
4417ec681f3Smrg   if (dyn_state >= VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT &&
4427ec681f3Smrg       dyn_state <= VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT)
4437ec681f3Smrg      return dyn_state - VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT +
4447ec681f3Smrg             VK_DYNAMIC_STATE_STENCIL_OP_EXT - VK_DYNAMIC_STATE_CULL_MODE_EXT +
4457ec681f3Smrg             VK_DYNAMIC_STATE_STENCIL_REFERENCE + 2 + 1 + 1;
4467ec681f3Smrg   if (dyn_state == VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT)
4477ec681f3Smrg      return VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT - VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT +
4487ec681f3Smrg             VK_DYNAMIC_STATE_STENCIL_OP_EXT - VK_DYNAMIC_STATE_CULL_MODE_EXT +
4497ec681f3Smrg             VK_DYNAMIC_STATE_STENCIL_REFERENCE + 2 + 1 + 1 + 1;
4507ec681f3Smrg   assert(0);
4517ec681f3Smrg   return -1;
4527ec681f3Smrg}
4537ec681f3Smrg
4547ec681f3Smrgstatic void handle_graphics_pipeline(struct vk_cmd_queue_entry *cmd,
4557ec681f3Smrg                                     struct rendering_state *state)
4567ec681f3Smrg{
4577ec681f3Smrg   LVP_FROM_HANDLE(lvp_pipeline, pipeline, cmd->u.bind_pipeline.pipeline);
4587ec681f3Smrg   bool dynamic_states[VK_DYNAMIC_STATE_STENCIL_REFERENCE+32];
4597ec681f3Smrg   unsigned fb_samples = 0;
4607ec681f3Smrg
4617ec681f3Smrg   memset(dynamic_states, 0, sizeof(dynamic_states));
4627ec681f3Smrg   if (pipeline->graphics_create_info.pDynamicState)
4637ec681f3Smrg   {
4647ec681f3Smrg      const VkPipelineDynamicStateCreateInfo *dyn = pipeline->graphics_create_info.pDynamicState;
4657ec681f3Smrg      int i;
4667ec681f3Smrg      for (i = 0; i < dyn->dynamicStateCount; i++) {
4677ec681f3Smrg         int idx = conv_dynamic_state_idx(dyn->pDynamicStates[i]);
4687ec681f3Smrg         if (idx == -1)
4697ec681f3Smrg            continue;
4707ec681f3Smrg         dynamic_states[idx] = true;
4717ec681f3Smrg      }
4727ec681f3Smrg   }
4737ec681f3Smrg   state->has_color_write_disables = dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT)];
4747ec681f3Smrg
4757ec681f3Smrg   bool has_stage[PIPE_SHADER_TYPES] = { false };
4767ec681f3Smrg
4777ec681f3Smrg   state->pctx->bind_gs_state(state->pctx, NULL);
4787ec681f3Smrg   if (state->pctx->bind_tcs_state)
4797ec681f3Smrg      state->pctx->bind_tcs_state(state->pctx, NULL);
4807ec681f3Smrg   if (state->pctx->bind_tes_state)
4817ec681f3Smrg      state->pctx->bind_tes_state(state->pctx, NULL);
4827ec681f3Smrg   state->gs_output_lines = GS_OUTPUT_NONE;
4837ec681f3Smrg   {
4847ec681f3Smrg      int i;
4857ec681f3Smrg      for (i = 0; i < pipeline->graphics_create_info.stageCount; i++) {
4867ec681f3Smrg         const VkPipelineShaderStageCreateInfo *sh = &pipeline->graphics_create_info.pStages[i];
4877ec681f3Smrg         switch (sh->stage) {
4887ec681f3Smrg         case VK_SHADER_STAGE_FRAGMENT_BIT:
4897ec681f3Smrg            state->pctx->bind_fs_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_FRAGMENT]);
4907ec681f3Smrg            has_stage[PIPE_SHADER_FRAGMENT] = true;
4917ec681f3Smrg            break;
4927ec681f3Smrg         case VK_SHADER_STAGE_VERTEX_BIT:
4937ec681f3Smrg            state->pctx->bind_vs_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_VERTEX]);
4947ec681f3Smrg            has_stage[PIPE_SHADER_VERTEX] = true;
4957ec681f3Smrg            break;
4967ec681f3Smrg         case VK_SHADER_STAGE_GEOMETRY_BIT:
4977ec681f3Smrg            state->pctx->bind_gs_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_GEOMETRY]);
4987ec681f3Smrg            state->gs_output_lines = pipeline->gs_output_lines ? GS_OUTPUT_LINES : GS_OUTPUT_NOT_LINES;
4997ec681f3Smrg            has_stage[PIPE_SHADER_GEOMETRY] = true;
5007ec681f3Smrg            break;
5017ec681f3Smrg         case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
5027ec681f3Smrg            state->pctx->bind_tcs_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_TESS_CTRL]);
5037ec681f3Smrg            has_stage[PIPE_SHADER_TESS_CTRL] = true;
5047ec681f3Smrg            break;
5057ec681f3Smrg         case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
5067ec681f3Smrg            state->pctx->bind_tes_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_TESS_EVAL]);
5077ec681f3Smrg            has_stage[PIPE_SHADER_TESS_EVAL] = true;
5087ec681f3Smrg            break;
5097ec681f3Smrg         default:
5107ec681f3Smrg            assert(0);
5117ec681f3Smrg            break;
5127ec681f3Smrg         }
5137ec681f3Smrg      }
5147ec681f3Smrg   }
5157ec681f3Smrg
5167ec681f3Smrg   /* there should always be a dummy fs. */
5177ec681f3Smrg   if (!has_stage[PIPE_SHADER_FRAGMENT])
5187ec681f3Smrg      state->pctx->bind_fs_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_FRAGMENT]);
5197ec681f3Smrg   if (state->pctx->bind_gs_state && !has_stage[PIPE_SHADER_GEOMETRY])
5207ec681f3Smrg      state->pctx->bind_gs_state(state->pctx, NULL);
5217ec681f3Smrg   if (state->pctx->bind_tcs_state && !has_stage[PIPE_SHADER_TESS_CTRL])
5227ec681f3Smrg      state->pctx->bind_tcs_state(state->pctx, NULL);
5237ec681f3Smrg   if (state->pctx->bind_tes_state && !has_stage[PIPE_SHADER_TESS_EVAL])
5247ec681f3Smrg      state->pctx->bind_tes_state(state->pctx, NULL);
5257ec681f3Smrg
5267ec681f3Smrg   /* rasterization state */
5277ec681f3Smrg   if (pipeline->graphics_create_info.pRasterizationState) {
5287ec681f3Smrg      const VkPipelineRasterizationStateCreateInfo *rsc = pipeline->graphics_create_info.pRasterizationState;
5297ec681f3Smrg      const VkPipelineRasterizationDepthClipStateCreateInfoEXT *depth_clip_state =
5307ec681f3Smrg         vk_find_struct_const(rsc->pNext, PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT);
5317ec681f3Smrg      state->rs_state.depth_clamp = rsc->depthClampEnable;
5327ec681f3Smrg      if (!depth_clip_state)
5337ec681f3Smrg         state->rs_state.depth_clip_near = state->rs_state.depth_clip_far = !rsc->depthClampEnable;
5347ec681f3Smrg      else
5357ec681f3Smrg         state->rs_state.depth_clip_near = state->rs_state.depth_clip_far = depth_clip_state->depthClipEnable;
5367ec681f3Smrg
5377ec681f3Smrg      if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT)])
5387ec681f3Smrg         state->rs_state.rasterizer_discard = rsc->rasterizerDiscardEnable;
5397ec681f3Smrg
5407ec681f3Smrg      state->rs_state.line_smooth = pipeline->line_smooth;
5417ec681f3Smrg      state->rs_state.line_stipple_enable = pipeline->line_stipple_enable;
5427ec681f3Smrg      state->rs_state.fill_front = vk_polygon_mode_to_pipe(rsc->polygonMode);
5437ec681f3Smrg      state->rs_state.fill_back = vk_polygon_mode_to_pipe(rsc->polygonMode);
5447ec681f3Smrg      state->rs_state.point_size_per_vertex = true;
5457ec681f3Smrg      state->rs_state.flatshade_first = !pipeline->provoking_vertex_last;
5467ec681f3Smrg      state->rs_state.point_quad_rasterization = true;
5477ec681f3Smrg      state->rs_state.clip_halfz = true;
5487ec681f3Smrg      state->rs_state.half_pixel_center = true;
5497ec681f3Smrg      state->rs_state.scissor = true;
5507ec681f3Smrg      state->rs_state.no_ms_sample_mask_out = true;
5517ec681f3Smrg      state->rs_state.line_rectangular = pipeline->line_rectangular;
5527ec681f3Smrg
5537ec681f3Smrg      if (!dynamic_states[VK_DYNAMIC_STATE_LINE_WIDTH])
5547ec681f3Smrg         state->rs_state.line_width = rsc->lineWidth;
5557ec681f3Smrg      if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_LINE_STIPPLE_EXT)]) {
5567ec681f3Smrg         state->rs_state.line_stipple_factor = pipeline->line_stipple_factor;
5577ec681f3Smrg         state->rs_state.line_stipple_pattern = pipeline->line_stipple_pattern;
5587ec681f3Smrg      }
5597ec681f3Smrg
5607ec681f3Smrg      if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT)])
5617ec681f3Smrg         state->depth_bias.enabled = pipeline->graphics_create_info.pRasterizationState->depthBiasEnable;
5627ec681f3Smrg      if (!dynamic_states[VK_DYNAMIC_STATE_DEPTH_BIAS]) {
5637ec681f3Smrg         state->depth_bias.offset_units = rsc->depthBiasConstantFactor;
5647ec681f3Smrg         state->depth_bias.offset_scale = rsc->depthBiasSlopeFactor;
5657ec681f3Smrg         state->depth_bias.offset_clamp = rsc->depthBiasClamp;
5667ec681f3Smrg      }
5677ec681f3Smrg
5687ec681f3Smrg      if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_CULL_MODE_EXT)])
5697ec681f3Smrg         state->rs_state.cull_face = vk_cull_to_pipe(rsc->cullMode);
5707ec681f3Smrg
5717ec681f3Smrg      if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_FRONT_FACE_EXT)])
5727ec681f3Smrg         state->rs_state.front_ccw = (rsc->frontFace == VK_FRONT_FACE_COUNTER_CLOCKWISE);
5737ec681f3Smrg      state->rs_dirty = true;
5747ec681f3Smrg   }
5757ec681f3Smrg
5767ec681f3Smrg   state->disable_multisample = pipeline->disable_multisample;
5777ec681f3Smrg   if (pipeline->graphics_create_info.pMultisampleState) {
5787ec681f3Smrg      const VkPipelineMultisampleStateCreateInfo *ms = pipeline->graphics_create_info.pMultisampleState;
5797ec681f3Smrg      state->rs_state.multisample = ms->rasterizationSamples > 1;
5807ec681f3Smrg      state->sample_mask = ms->pSampleMask ? ms->pSampleMask[0] : 0xffffffff;
5817ec681f3Smrg      state->blend_state.alpha_to_coverage = ms->alphaToCoverageEnable;
5827ec681f3Smrg      state->blend_state.alpha_to_one = ms->alphaToOneEnable;
5837ec681f3Smrg      state->blend_dirty = true;
5847ec681f3Smrg      state->rs_dirty = true;
5857ec681f3Smrg      state->min_samples = 1;
5867ec681f3Smrg      state->sample_mask_dirty = true;
5877ec681f3Smrg      fb_samples = ms->rasterizationSamples;
5887ec681f3Smrg      if (ms->sampleShadingEnable) {
5897ec681f3Smrg         state->min_samples = ceil(ms->rasterizationSamples * ms->minSampleShading);
5907ec681f3Smrg         if (state->min_samples > 1)
5917ec681f3Smrg            state->min_samples = ms->rasterizationSamples;
5927ec681f3Smrg         if (state->min_samples < 1)
5937ec681f3Smrg            state->min_samples = 1;
5947ec681f3Smrg      }
5957ec681f3Smrg      if (pipeline->force_min_sample)
5967ec681f3Smrg         state->min_samples = ms->rasterizationSamples;
5977ec681f3Smrg      state->min_samples_dirty = true;
5987ec681f3Smrg   } else {
5997ec681f3Smrg      state->rs_state.multisample = false;
6007ec681f3Smrg      state->sample_mask_dirty = state->sample_mask != 0xffffffff;
6017ec681f3Smrg      state->sample_mask = 0xffffffff;
6027ec681f3Smrg      state->min_samples_dirty = state->min_samples;
6037ec681f3Smrg      state->min_samples = 0;
6047ec681f3Smrg      state->blend_dirty |= state->blend_state.alpha_to_coverage || state->blend_state.alpha_to_one;
6057ec681f3Smrg      state->blend_state.alpha_to_coverage = false;
6067ec681f3Smrg      state->blend_state.alpha_to_one = false;
6077ec681f3Smrg      state->rs_dirty = true;
6087ec681f3Smrg   }
6097ec681f3Smrg
6107ec681f3Smrg   if (pipeline->graphics_create_info.pDepthStencilState) {
6117ec681f3Smrg      const VkPipelineDepthStencilStateCreateInfo *dsa = pipeline->graphics_create_info.pDepthStencilState;
6127ec681f3Smrg
6137ec681f3Smrg      if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT)])
6147ec681f3Smrg         state->dsa_state.depth_enabled = dsa->depthTestEnable;
6157ec681f3Smrg      if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT)])
6167ec681f3Smrg         state->dsa_state.depth_writemask = dsa->depthWriteEnable;
6177ec681f3Smrg      if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT)])
6187ec681f3Smrg         state->dsa_state.depth_func = dsa->depthCompareOp;
6197ec681f3Smrg      if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT)])
6207ec681f3Smrg         state->dsa_state.depth_bounds_test = dsa->depthBoundsTestEnable;
6217ec681f3Smrg
6227ec681f3Smrg      if (!dynamic_states[VK_DYNAMIC_STATE_DEPTH_BOUNDS]) {
6237ec681f3Smrg         state->dsa_state.depth_bounds_min = dsa->minDepthBounds;
6247ec681f3Smrg         state->dsa_state.depth_bounds_max = dsa->maxDepthBounds;
6257ec681f3Smrg      }
6267ec681f3Smrg
6277ec681f3Smrg      if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT)]) {
6287ec681f3Smrg         state->dsa_state.stencil[0].enabled = dsa->stencilTestEnable;
6297ec681f3Smrg         state->dsa_state.stencil[1].enabled = dsa->stencilTestEnable;
6307ec681f3Smrg      }
6317ec681f3Smrg
6327ec681f3Smrg      if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_STENCIL_OP_EXT)]) {
6337ec681f3Smrg         state->dsa_state.stencil[0].func = dsa->front.compareOp;
6347ec681f3Smrg         state->dsa_state.stencil[0].fail_op = vk_conv_stencil_op(dsa->front.failOp);
6357ec681f3Smrg         state->dsa_state.stencil[0].zpass_op = vk_conv_stencil_op(dsa->front.passOp);
6367ec681f3Smrg         state->dsa_state.stencil[0].zfail_op = vk_conv_stencil_op(dsa->front.depthFailOp);
6377ec681f3Smrg
6387ec681f3Smrg         state->dsa_state.stencil[1].func = dsa->back.compareOp;
6397ec681f3Smrg         state->dsa_state.stencil[1].fail_op = vk_conv_stencil_op(dsa->back.failOp);
6407ec681f3Smrg         state->dsa_state.stencil[1].zpass_op = vk_conv_stencil_op(dsa->back.passOp);
6417ec681f3Smrg         state->dsa_state.stencil[1].zfail_op = vk_conv_stencil_op(dsa->back.depthFailOp);
6427ec681f3Smrg      }
6437ec681f3Smrg
6447ec681f3Smrg      if (!dynamic_states[VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK]) {
6457ec681f3Smrg         state->dsa_state.stencil[0].valuemask = dsa->front.compareMask;
6467ec681f3Smrg         state->dsa_state.stencil[1].valuemask = dsa->back.compareMask;
6477ec681f3Smrg      }
6487ec681f3Smrg
6497ec681f3Smrg      if (!dynamic_states[VK_DYNAMIC_STATE_STENCIL_WRITE_MASK]) {
6507ec681f3Smrg         state->dsa_state.stencil[0].writemask = dsa->front.writeMask;
6517ec681f3Smrg         state->dsa_state.stencil[1].writemask = dsa->back.writeMask;
6527ec681f3Smrg      }
6537ec681f3Smrg
6547ec681f3Smrg      if (dsa->stencilTestEnable) {
6557ec681f3Smrg         if (!dynamic_states[VK_DYNAMIC_STATE_STENCIL_REFERENCE]) {
6567ec681f3Smrg            state->stencil_ref.ref_value[0] = dsa->front.reference;
6577ec681f3Smrg            state->stencil_ref.ref_value[1] = dsa->back.reference;
6587ec681f3Smrg            state->stencil_ref_dirty = true;
6597ec681f3Smrg         }
6607ec681f3Smrg      }
6617ec681f3Smrg   } else
6627ec681f3Smrg      memset(&state->dsa_state, 0, sizeof(state->dsa_state));
6637ec681f3Smrg   state->dsa_dirty = true;
6647ec681f3Smrg
6657ec681f3Smrg   if (pipeline->graphics_create_info.pColorBlendState) {
6667ec681f3Smrg      const VkPipelineColorBlendStateCreateInfo *cb = pipeline->graphics_create_info.pColorBlendState;
6677ec681f3Smrg      int i;
6687ec681f3Smrg
6697ec681f3Smrg      if (cb->logicOpEnable) {
6707ec681f3Smrg         state->blend_state.logicop_enable = VK_TRUE;
6717ec681f3Smrg         if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_LOGIC_OP_EXT)])
6727ec681f3Smrg            state->blend_state.logicop_func = vk_conv_logic_op(cb->logicOp);
6737ec681f3Smrg      }
6747ec681f3Smrg
6757ec681f3Smrg      if (cb->attachmentCount > 1)
6767ec681f3Smrg         state->blend_state.independent_blend_enable = true;
6777ec681f3Smrg      for (i = 0; i < cb->attachmentCount; i++) {
6787ec681f3Smrg         state->blend_state.rt[i].colormask = cb->pAttachments[i].colorWriteMask;
6797ec681f3Smrg         state->blend_state.rt[i].blend_enable = cb->pAttachments[i].blendEnable;
6807ec681f3Smrg         state->blend_state.rt[i].rgb_func = vk_conv_blend_func(cb->pAttachments[i].colorBlendOp);
6817ec681f3Smrg         state->blend_state.rt[i].rgb_src_factor = vk_conv_blend_factor(cb->pAttachments[i].srcColorBlendFactor);
6827ec681f3Smrg         state->blend_state.rt[i].rgb_dst_factor = vk_conv_blend_factor(cb->pAttachments[i].dstColorBlendFactor);
6837ec681f3Smrg         state->blend_state.rt[i].alpha_func = vk_conv_blend_func(cb->pAttachments[i].alphaBlendOp);
6847ec681f3Smrg         state->blend_state.rt[i].alpha_src_factor = vk_conv_blend_factor(cb->pAttachments[i].srcAlphaBlendFactor);
6857ec681f3Smrg         state->blend_state.rt[i].alpha_dst_factor = vk_conv_blend_factor(cb->pAttachments[i].dstAlphaBlendFactor);
6867ec681f3Smrg
6877ec681f3Smrg         /* At least llvmpipe applies the blend factor prior to the blend function,
6887ec681f3Smrg          * regardless of what function is used. (like i965 hardware).
6897ec681f3Smrg          * It means for MIN/MAX the blend factor has to be stomped to ONE.
6907ec681f3Smrg          */
6917ec681f3Smrg         if (cb->pAttachments[i].colorBlendOp == VK_BLEND_OP_MIN ||
6927ec681f3Smrg             cb->pAttachments[i].colorBlendOp == VK_BLEND_OP_MAX) {
6937ec681f3Smrg            state->blend_state.rt[i].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
6947ec681f3Smrg            state->blend_state.rt[i].rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
6957ec681f3Smrg         }
6967ec681f3Smrg
6977ec681f3Smrg         if (cb->pAttachments[i].alphaBlendOp == VK_BLEND_OP_MIN ||
6987ec681f3Smrg             cb->pAttachments[i].alphaBlendOp == VK_BLEND_OP_MAX) {
6997ec681f3Smrg            state->blend_state.rt[i].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
7007ec681f3Smrg            state->blend_state.rt[i].alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
7017ec681f3Smrg         }
7027ec681f3Smrg      }
7037ec681f3Smrg      state->blend_dirty = true;
7047ec681f3Smrg      if (!dynamic_states[VK_DYNAMIC_STATE_BLEND_CONSTANTS]) {
7057ec681f3Smrg         memcpy(state->blend_color.color, cb->blendConstants, 4 * sizeof(float));
7067ec681f3Smrg         state->blend_color_dirty = true;
7077ec681f3Smrg      }
7087ec681f3Smrg   } else {
7097ec681f3Smrg      memset(&state->blend_state, 0, sizeof(state->blend_state));
7107ec681f3Smrg      state->blend_dirty = true;
7117ec681f3Smrg   }
7127ec681f3Smrg
7137ec681f3Smrg   if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_VERTEX_INPUT_EXT)]) {
7147ec681f3Smrg      const VkPipelineVertexInputStateCreateInfo *vi = pipeline->graphics_create_info.pVertexInputState;
7157ec681f3Smrg      int i;
7167ec681f3Smrg      const VkPipelineVertexInputDivisorStateCreateInfoEXT *div_state =
7177ec681f3Smrg         vk_find_struct_const(vi->pNext,
7187ec681f3Smrg                              PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT);
7197ec681f3Smrg
7207ec681f3Smrg      if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT)]) {
7217ec681f3Smrg         for (i = 0; i < vi->vertexBindingDescriptionCount; i++) {
7227ec681f3Smrg            state->vb[vi->pVertexBindingDescriptions[i].binding].stride = vi->pVertexBindingDescriptions[i].stride;
7237ec681f3Smrg         }
7247ec681f3Smrg      }
7257ec681f3Smrg
7267ec681f3Smrg      int max_location = -1;
7277ec681f3Smrg      for (i = 0; i < vi->vertexAttributeDescriptionCount; i++) {
7287ec681f3Smrg         unsigned location = vi->pVertexAttributeDescriptions[i].location;
7297ec681f3Smrg         unsigned binding = vi->pVertexAttributeDescriptions[i].binding;
7307ec681f3Smrg         const struct VkVertexInputBindingDescription *desc_binding = NULL;
7317ec681f3Smrg         for (unsigned j = 0; j < vi->vertexBindingDescriptionCount; j++) {
7327ec681f3Smrg            const struct VkVertexInputBindingDescription *b = &vi->pVertexBindingDescriptions[j];
7337ec681f3Smrg            if (b->binding == binding) {
7347ec681f3Smrg               desc_binding = b;
7357ec681f3Smrg               break;
7367ec681f3Smrg            }
7377ec681f3Smrg         }
7387ec681f3Smrg         assert(desc_binding);
7397ec681f3Smrg         state->velem.velems[location].src_offset = vi->pVertexAttributeDescriptions[i].offset;
7407ec681f3Smrg         state->velem.velems[location].vertex_buffer_index = binding;
7417ec681f3Smrg         state->velem.velems[location].src_format = lvp_vk_format_to_pipe_format(vi->pVertexAttributeDescriptions[i].format);
7427ec681f3Smrg         state->velem.velems[location].dual_slot = false;
7437ec681f3Smrg
7447ec681f3Smrg         switch (desc_binding->inputRate) {
7457ec681f3Smrg         case VK_VERTEX_INPUT_RATE_VERTEX:
7467ec681f3Smrg            state->velem.velems[location].instance_divisor = 0;
7477ec681f3Smrg            break;
7487ec681f3Smrg         case VK_VERTEX_INPUT_RATE_INSTANCE:
7497ec681f3Smrg            if (div_state) {
7507ec681f3Smrg               for (unsigned j = 0; j < div_state->vertexBindingDivisorCount; j++) {
7517ec681f3Smrg                  const VkVertexInputBindingDivisorDescriptionEXT *desc =
7527ec681f3Smrg                     &div_state->pVertexBindingDivisors[j];
7537ec681f3Smrg                  if (desc->binding == state->velem.velems[location].vertex_buffer_index) {
7547ec681f3Smrg                     state->velem.velems[location].instance_divisor = desc->divisor;
7557ec681f3Smrg                     break;
7567ec681f3Smrg                  }
7577ec681f3Smrg               }
7587ec681f3Smrg            } else
7597ec681f3Smrg               state->velem.velems[location].instance_divisor = 1;
7607ec681f3Smrg            break;
7617ec681f3Smrg         default:
7627ec681f3Smrg            assert(0);
7637ec681f3Smrg            break;
7647ec681f3Smrg         }
7657ec681f3Smrg
7667ec681f3Smrg         if ((int)location > max_location)
7677ec681f3Smrg            max_location = location;
7687ec681f3Smrg      }
7697ec681f3Smrg      state->velem.count = max_location + 1;
7707ec681f3Smrg      state->vb_dirty = true;
7717ec681f3Smrg      state->ve_dirty = true;
7727ec681f3Smrg   }
7737ec681f3Smrg
7747ec681f3Smrg   {
7757ec681f3Smrg      const VkPipelineInputAssemblyStateCreateInfo *ia = pipeline->graphics_create_info.pInputAssemblyState;
7767ec681f3Smrg
7777ec681f3Smrg      if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT)]) {
7787ec681f3Smrg         state->info.mode = vk_conv_topology(ia->topology);
7797ec681f3Smrg         state->rs_dirty = true;
7807ec681f3Smrg      }
7817ec681f3Smrg      if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT)])
7827ec681f3Smrg         state->info.primitive_restart = ia->primitiveRestartEnable;
7837ec681f3Smrg   }
7847ec681f3Smrg
7857ec681f3Smrg   if (pipeline->graphics_create_info.pTessellationState) {
7867ec681f3Smrg      if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT)]) {
7877ec681f3Smrg         const VkPipelineTessellationStateCreateInfo *ts = pipeline->graphics_create_info.pTessellationState;
7887ec681f3Smrg         state->patch_vertices = ts->patchControlPoints;
7897ec681f3Smrg      }
7907ec681f3Smrg   } else
7917ec681f3Smrg      state->patch_vertices = 0;
7927ec681f3Smrg
7937ec681f3Smrg   if (pipeline->graphics_create_info.pViewportState) {
7947ec681f3Smrg      const VkPipelineViewportStateCreateInfo *vpi= pipeline->graphics_create_info.pViewportState;
7957ec681f3Smrg      int i;
7967ec681f3Smrg
7977ec681f3Smrg      if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT)]) {
7987ec681f3Smrg         state->num_viewports = vpi->viewportCount;
7997ec681f3Smrg         state->vp_dirty = true;
8007ec681f3Smrg      }
8017ec681f3Smrg      if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT)]) {
8027ec681f3Smrg         state->num_scissors = vpi->scissorCount;
8037ec681f3Smrg         state->scissor_dirty = true;
8047ec681f3Smrg      }
8057ec681f3Smrg
8067ec681f3Smrg      if (!dynamic_states[VK_DYNAMIC_STATE_VIEWPORT] &&
8077ec681f3Smrg          !dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT)]) {
8087ec681f3Smrg         for (i = 0; i < vpi->viewportCount; i++)
8097ec681f3Smrg            get_viewport_xform(&vpi->pViewports[i], state->viewports[i].scale, state->viewports[i].translate);
8107ec681f3Smrg         state->vp_dirty = true;
8117ec681f3Smrg      }
8127ec681f3Smrg      if (!dynamic_states[VK_DYNAMIC_STATE_SCISSOR] &&
8137ec681f3Smrg          !dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT)]) {
8147ec681f3Smrg         for (i = 0; i < vpi->scissorCount; i++) {
8157ec681f3Smrg            const VkRect2D *ss = &vpi->pScissors[i];
8167ec681f3Smrg            state->scissors[i].minx = ss->offset.x;
8177ec681f3Smrg            state->scissors[i].miny = ss->offset.y;
8187ec681f3Smrg            state->scissors[i].maxx = ss->offset.x + ss->extent.width;
8197ec681f3Smrg            state->scissors[i].maxy = ss->offset.y + ss->extent.height;
8207ec681f3Smrg            state->scissor_dirty = true;
8217ec681f3Smrg         }
8227ec681f3Smrg
8237ec681f3Smrg      }
8247ec681f3Smrg   }
8257ec681f3Smrg
8267ec681f3Smrg   if (fb_samples != state->framebuffer.samples) {
8277ec681f3Smrg      state->framebuffer.samples = fb_samples;
8287ec681f3Smrg      state->pctx->set_framebuffer_state(state->pctx, &state->framebuffer);
8297ec681f3Smrg   }
8307ec681f3Smrg}
8317ec681f3Smrg
8327ec681f3Smrgstatic void handle_pipeline(struct vk_cmd_queue_entry *cmd,
8337ec681f3Smrg                            struct rendering_state *state)
8347ec681f3Smrg{
8357ec681f3Smrg   LVP_FROM_HANDLE(lvp_pipeline, pipeline, cmd->u.bind_pipeline.pipeline);
8367ec681f3Smrg   if (pipeline->is_compute_pipeline)
8377ec681f3Smrg      handle_compute_pipeline(cmd, state);
8387ec681f3Smrg   else
8397ec681f3Smrg      handle_graphics_pipeline(cmd, state);
8407ec681f3Smrg}
8417ec681f3Smrg
8427ec681f3Smrgstatic void vertex_buffers(uint32_t first_binding,
8437ec681f3Smrg                           uint32_t binding_count,
8447ec681f3Smrg                           const VkBuffer *buffers,
8457ec681f3Smrg                           const VkDeviceSize *offsets,
8467ec681f3Smrg                           const VkDeviceSize *strides,
8477ec681f3Smrg                           struct rendering_state *state)
8487ec681f3Smrg{
8497ec681f3Smrg   int i;
8507ec681f3Smrg   for (i = 0; i < binding_count; i++) {
8517ec681f3Smrg      int idx = i + first_binding;
8527ec681f3Smrg
8537ec681f3Smrg      state->vb[idx].buffer_offset = offsets[i];
8547ec681f3Smrg      state->vb[idx].buffer.resource = buffers[i] ? lvp_buffer_from_handle(buffers[i])->bo : NULL;
8557ec681f3Smrg
8567ec681f3Smrg      if (strides)
8577ec681f3Smrg         state->vb[idx].stride = strides[i];
8587ec681f3Smrg   }
8597ec681f3Smrg   if (first_binding < state->start_vb)
8607ec681f3Smrg      state->start_vb = first_binding;
8617ec681f3Smrg   if (first_binding + binding_count >= state->num_vb)
8627ec681f3Smrg      state->num_vb = first_binding + binding_count;
8637ec681f3Smrg   state->vb_dirty = true;
8647ec681f3Smrg}
8657ec681f3Smrg
8667ec681f3Smrgstatic void handle_vertex_buffers(struct vk_cmd_queue_entry *cmd,
8677ec681f3Smrg                                  struct rendering_state *state)
8687ec681f3Smrg{
8697ec681f3Smrg   struct vk_cmd_bind_vertex_buffers *vcb = &cmd->u.bind_vertex_buffers;
8707ec681f3Smrg
8717ec681f3Smrg   vertex_buffers(vcb->first_binding,
8727ec681f3Smrg                  vcb->binding_count,
8737ec681f3Smrg                  vcb->buffers,
8747ec681f3Smrg                  vcb->offsets,
8757ec681f3Smrg                  NULL,
8767ec681f3Smrg                  state);
8777ec681f3Smrg}
8787ec681f3Smrg
8797ec681f3Smrgstatic void handle_vertex_buffers2(struct vk_cmd_queue_entry *cmd,
8807ec681f3Smrg                                   struct rendering_state *state)
8817ec681f3Smrg{
8827ec681f3Smrg   struct vk_cmd_bind_vertex_buffers2_ext *vcb = &cmd->u.bind_vertex_buffers2_ext;
8837ec681f3Smrg
8847ec681f3Smrg   vertex_buffers(vcb->first_binding,
8857ec681f3Smrg                  vcb->binding_count,
8867ec681f3Smrg                  vcb->buffers,
8877ec681f3Smrg                  vcb->offsets,
8887ec681f3Smrg                  vcb->strides,
8897ec681f3Smrg                  state);
8907ec681f3Smrg}
8917ec681f3Smrg
8927ec681f3Smrgstruct dyn_info {
8937ec681f3Smrg   struct {
8947ec681f3Smrg      uint16_t const_buffer_count;
8957ec681f3Smrg      uint16_t shader_buffer_count;
8967ec681f3Smrg      uint16_t sampler_count;
8977ec681f3Smrg      uint16_t sampler_view_count;
8987ec681f3Smrg      uint16_t image_count;
8997ec681f3Smrg   } stage[MESA_SHADER_STAGES];
9007ec681f3Smrg
9017ec681f3Smrg   uint32_t dyn_index;
9027ec681f3Smrg   const uint32_t *dynamic_offsets;
9037ec681f3Smrg   uint32_t dynamic_offset_count;
9047ec681f3Smrg};
9057ec681f3Smrg
9067ec681f3Smrgstatic void fill_sampler(struct pipe_sampler_state *ss,
9077ec681f3Smrg                         struct lvp_sampler *samp)
9087ec681f3Smrg{
9097ec681f3Smrg   ss->wrap_s = vk_conv_wrap_mode(samp->create_info.addressModeU);
9107ec681f3Smrg   ss->wrap_t = vk_conv_wrap_mode(samp->create_info.addressModeV);
9117ec681f3Smrg   ss->wrap_r = vk_conv_wrap_mode(samp->create_info.addressModeW);
9127ec681f3Smrg   ss->min_img_filter = samp->create_info.minFilter == VK_FILTER_LINEAR ? PIPE_TEX_FILTER_LINEAR : PIPE_TEX_FILTER_NEAREST;
9137ec681f3Smrg   ss->min_mip_filter = samp->create_info.mipmapMode == VK_SAMPLER_MIPMAP_MODE_LINEAR ? PIPE_TEX_MIPFILTER_LINEAR : PIPE_TEX_MIPFILTER_NEAREST;
9147ec681f3Smrg   ss->mag_img_filter = samp->create_info.magFilter == VK_FILTER_LINEAR ? PIPE_TEX_FILTER_LINEAR : PIPE_TEX_FILTER_NEAREST;
9157ec681f3Smrg   ss->min_lod = samp->create_info.minLod;
9167ec681f3Smrg   ss->max_lod = samp->create_info.maxLod;
9177ec681f3Smrg   ss->lod_bias = samp->create_info.mipLodBias;
9187ec681f3Smrg   if (samp->create_info.anisotropyEnable)
9197ec681f3Smrg      ss->max_anisotropy = samp->create_info.maxAnisotropy;
9207ec681f3Smrg   else
9217ec681f3Smrg      ss->max_anisotropy = 1;
9227ec681f3Smrg   ss->normalized_coords = !samp->create_info.unnormalizedCoordinates;
9237ec681f3Smrg   ss->compare_mode = samp->create_info.compareEnable ? PIPE_TEX_COMPARE_R_TO_TEXTURE : PIPE_TEX_COMPARE_NONE;
9247ec681f3Smrg   ss->compare_func = samp->create_info.compareOp;
9257ec681f3Smrg   ss->seamless_cube_map = true;
9267ec681f3Smrg   ss->reduction_mode = samp->reduction_mode;
9277ec681f3Smrg   memcpy(&ss->border_color, &samp->border_color,
9287ec681f3Smrg          sizeof(union pipe_color_union));
9297ec681f3Smrg}
9307ec681f3Smrg
9317ec681f3Smrgstatic void fill_sampler_stage(struct rendering_state *state,
9327ec681f3Smrg                               struct dyn_info *dyn_info,
9337ec681f3Smrg                               gl_shader_stage stage,
9347ec681f3Smrg                               enum pipe_shader_type p_stage,
9357ec681f3Smrg                               int array_idx,
9367ec681f3Smrg                               const union lvp_descriptor_info *descriptor,
9377ec681f3Smrg                               const struct lvp_descriptor_set_binding_layout *binding)
9387ec681f3Smrg{
9397ec681f3Smrg   int ss_idx = binding->stage[stage].sampler_index;
9407ec681f3Smrg   if (ss_idx == -1)
9417ec681f3Smrg      return;
9427ec681f3Smrg   ss_idx += array_idx;
9437ec681f3Smrg   ss_idx += dyn_info->stage[stage].sampler_count;
9447ec681f3Smrg   fill_sampler(&state->ss[p_stage][ss_idx], binding->immutable_samplers ? binding->immutable_samplers[array_idx] : descriptor->sampler);
9457ec681f3Smrg   if (state->num_sampler_states[p_stage] <= ss_idx)
9467ec681f3Smrg      state->num_sampler_states[p_stage] = ss_idx + 1;
9477ec681f3Smrg   state->ss_dirty[p_stage] = true;
9487ec681f3Smrg}
9497ec681f3Smrg
9507ec681f3Smrg#define fix_depth_swizzle(x) do { \
9517ec681f3Smrg  if (x > PIPE_SWIZZLE_X && x < PIPE_SWIZZLE_0) \
9527ec681f3Smrg    x = PIPE_SWIZZLE_0;				\
9537ec681f3Smrg  } while (0)
9547ec681f3Smrg#define fix_depth_swizzle_a(x) do { \
9557ec681f3Smrg  if (x > PIPE_SWIZZLE_X && x < PIPE_SWIZZLE_0) \
9567ec681f3Smrg    x = PIPE_SWIZZLE_1;				\
9577ec681f3Smrg  } while (0)
9587ec681f3Smrg
9597ec681f3Smrgstatic void fill_sampler_view_stage(struct rendering_state *state,
9607ec681f3Smrg                                    struct dyn_info *dyn_info,
9617ec681f3Smrg                                    gl_shader_stage stage,
9627ec681f3Smrg                                    enum pipe_shader_type p_stage,
9637ec681f3Smrg                                    int array_idx,
9647ec681f3Smrg                                    const union lvp_descriptor_info *descriptor,
9657ec681f3Smrg                                    const struct lvp_descriptor_set_binding_layout *binding)
9667ec681f3Smrg{
9677ec681f3Smrg   int sv_idx = binding->stage[stage].sampler_view_index;
9687ec681f3Smrg   if (sv_idx == -1)
9697ec681f3Smrg      return;
9707ec681f3Smrg   sv_idx += array_idx;
9717ec681f3Smrg   sv_idx += dyn_info->stage[stage].sampler_view_count;
9727ec681f3Smrg   struct lvp_image_view *iv = descriptor->iview;
9737ec681f3Smrg   struct pipe_sampler_view templ;
9747ec681f3Smrg
9757ec681f3Smrg   enum pipe_format pformat;
9767ec681f3Smrg   if (iv->subresourceRange.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT)
9777ec681f3Smrg      pformat = lvp_vk_format_to_pipe_format(iv->format);
9787ec681f3Smrg   else if (iv->subresourceRange.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
9797ec681f3Smrg      pformat = util_format_stencil_only(lvp_vk_format_to_pipe_format(iv->format));
9807ec681f3Smrg   else
9817ec681f3Smrg      pformat = lvp_vk_format_to_pipe_format(iv->format);
9827ec681f3Smrg   u_sampler_view_default_template(&templ,
9837ec681f3Smrg                                   iv->image->bo,
9847ec681f3Smrg                                   pformat);
9857ec681f3Smrg   if (iv->view_type == VK_IMAGE_VIEW_TYPE_1D)
9867ec681f3Smrg      templ.target = PIPE_TEXTURE_1D;
9877ec681f3Smrg   if (iv->view_type == VK_IMAGE_VIEW_TYPE_2D)
9887ec681f3Smrg      templ.target = PIPE_TEXTURE_2D;
9897ec681f3Smrg   if (iv->view_type == VK_IMAGE_VIEW_TYPE_CUBE)
9907ec681f3Smrg      templ.target = PIPE_TEXTURE_CUBE;
9917ec681f3Smrg   if (iv->view_type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
9927ec681f3Smrg      templ.target = PIPE_TEXTURE_CUBE_ARRAY;
9937ec681f3Smrg   templ.u.tex.first_layer = iv->subresourceRange.baseArrayLayer;
9947ec681f3Smrg   templ.u.tex.last_layer = iv->subresourceRange.baseArrayLayer + lvp_get_layerCount(iv->image, &iv->subresourceRange) - 1;
9957ec681f3Smrg   templ.u.tex.first_level = iv->subresourceRange.baseMipLevel;
9967ec681f3Smrg   templ.u.tex.last_level = iv->subresourceRange.baseMipLevel + lvp_get_levelCount(iv->image, &iv->subresourceRange) - 1;
9977ec681f3Smrg   if (iv->components.r != VK_COMPONENT_SWIZZLE_IDENTITY)
9987ec681f3Smrg      templ.swizzle_r = vk_conv_swizzle(iv->components.r);
9997ec681f3Smrg   if (iv->components.g != VK_COMPONENT_SWIZZLE_IDENTITY)
10007ec681f3Smrg      templ.swizzle_g = vk_conv_swizzle(iv->components.g);
10017ec681f3Smrg   if (iv->components.b != VK_COMPONENT_SWIZZLE_IDENTITY)
10027ec681f3Smrg      templ.swizzle_b = vk_conv_swizzle(iv->components.b);
10037ec681f3Smrg   if (iv->components.a != VK_COMPONENT_SWIZZLE_IDENTITY)
10047ec681f3Smrg      templ.swizzle_a = vk_conv_swizzle(iv->components.a);
10057ec681f3Smrg
10067ec681f3Smrg   /* depth stencil swizzles need special handling to pass VK CTS
10077ec681f3Smrg    * but also for zink GL tests.
10087ec681f3Smrg    * piping A swizzle into R fixes GL_ALPHA depth texture mode
10097ec681f3Smrg    * only swizzling from R/0/1 (for alpha) fixes VK CTS tests
10107ec681f3Smrg    * and a bunch of zink tests.
10117ec681f3Smrg   */
10127ec681f3Smrg   if (iv->subresourceRange.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT ||
10137ec681f3Smrg       iv->subresourceRange.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) {
10147ec681f3Smrg      if (templ.swizzle_a == PIPE_SWIZZLE_X)
10157ec681f3Smrg         templ.swizzle_r = PIPE_SWIZZLE_X;
10167ec681f3Smrg      fix_depth_swizzle(templ.swizzle_r);
10177ec681f3Smrg      fix_depth_swizzle(templ.swizzle_g);
10187ec681f3Smrg      fix_depth_swizzle(templ.swizzle_b);
10197ec681f3Smrg      fix_depth_swizzle_a(templ.swizzle_a);
10207ec681f3Smrg   }
10217ec681f3Smrg
10227ec681f3Smrg   if (state->sv[p_stage][sv_idx])
10237ec681f3Smrg      pipe_sampler_view_reference(&state->sv[p_stage][sv_idx], NULL);
10247ec681f3Smrg   state->sv[p_stage][sv_idx] = state->pctx->create_sampler_view(state->pctx, iv->image->bo, &templ);
10257ec681f3Smrg   if (state->num_sampler_views[p_stage] <= sv_idx)
10267ec681f3Smrg      state->num_sampler_views[p_stage] = sv_idx + 1;
10277ec681f3Smrg   state->sv_dirty[p_stage] = true;
10287ec681f3Smrg}
10297ec681f3Smrg
10307ec681f3Smrgstatic void fill_sampler_buffer_view_stage(struct rendering_state *state,
10317ec681f3Smrg                                           struct dyn_info *dyn_info,
10327ec681f3Smrg                                           gl_shader_stage stage,
10337ec681f3Smrg                                           enum pipe_shader_type p_stage,
10347ec681f3Smrg                                           int array_idx,
10357ec681f3Smrg                                           const union lvp_descriptor_info *descriptor,
10367ec681f3Smrg                                           const struct lvp_descriptor_set_binding_layout *binding)
10377ec681f3Smrg{
10387ec681f3Smrg   int sv_idx = binding->stage[stage].sampler_view_index;
10397ec681f3Smrg   if (sv_idx == -1)
10407ec681f3Smrg      return;
10417ec681f3Smrg   sv_idx += array_idx;
10427ec681f3Smrg   sv_idx += dyn_info->stage[stage].sampler_view_count;
10437ec681f3Smrg   struct lvp_buffer_view *bv = descriptor->buffer_view;
10447ec681f3Smrg   struct pipe_sampler_view templ;
10457ec681f3Smrg   memset(&templ, 0, sizeof(templ));
10467ec681f3Smrg   templ.target = PIPE_BUFFER;
10477ec681f3Smrg   templ.swizzle_r = PIPE_SWIZZLE_X;
10487ec681f3Smrg   templ.swizzle_g = PIPE_SWIZZLE_Y;
10497ec681f3Smrg   templ.swizzle_b = PIPE_SWIZZLE_Z;
10507ec681f3Smrg   templ.swizzle_a = PIPE_SWIZZLE_W;
10517ec681f3Smrg   templ.format = bv->pformat;
10527ec681f3Smrg   templ.u.buf.offset = bv->offset + bv->buffer->offset;
10537ec681f3Smrg   templ.u.buf.size = bv->range == VK_WHOLE_SIZE ? (bv->buffer->size - bv->offset) : bv->range;
10547ec681f3Smrg   templ.texture = bv->buffer->bo;
10557ec681f3Smrg   templ.context = state->pctx;
10567ec681f3Smrg
10577ec681f3Smrg   if (state->sv[p_stage][sv_idx])
10587ec681f3Smrg      pipe_sampler_view_reference(&state->sv[p_stage][sv_idx], NULL);
10597ec681f3Smrg   state->sv[p_stage][sv_idx] = state->pctx->create_sampler_view(state->pctx, bv->buffer->bo, &templ);
10607ec681f3Smrg   if (state->num_sampler_views[p_stage] <= sv_idx)
10617ec681f3Smrg      state->num_sampler_views[p_stage] = sv_idx + 1;
10627ec681f3Smrg   state->sv_dirty[p_stage] = true;
10637ec681f3Smrg}
10647ec681f3Smrg
10657ec681f3Smrgstatic void fill_image_view_stage(struct rendering_state *state,
10667ec681f3Smrg                                  struct dyn_info *dyn_info,
10677ec681f3Smrg                                  gl_shader_stage stage,
10687ec681f3Smrg                                  enum pipe_shader_type p_stage,
10697ec681f3Smrg                                  int array_idx,
10707ec681f3Smrg                                  const union lvp_descriptor_info *descriptor,
10717ec681f3Smrg                                  const struct lvp_descriptor_set_binding_layout *binding)
10727ec681f3Smrg{
10737ec681f3Smrg   struct lvp_image_view *iv = descriptor->iview;
10747ec681f3Smrg   int idx = binding->stage[stage].image_index;
10757ec681f3Smrg   if (idx == -1)
10767ec681f3Smrg      return;
10777ec681f3Smrg   idx += array_idx;
10787ec681f3Smrg   idx += dyn_info->stage[stage].image_count;
10797ec681f3Smrg   state->iv[p_stage][idx].resource = iv->image->bo;
10807ec681f3Smrg   if (iv->subresourceRange.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT)
10817ec681f3Smrg      state->iv[p_stage][idx].format = lvp_vk_format_to_pipe_format(iv->format);
10827ec681f3Smrg   else if (iv->subresourceRange.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
10837ec681f3Smrg      state->iv[p_stage][idx].format = util_format_stencil_only(lvp_vk_format_to_pipe_format(iv->format));
10847ec681f3Smrg   else
10857ec681f3Smrg      state->iv[p_stage][idx].format = lvp_vk_format_to_pipe_format(iv->format);
10867ec681f3Smrg
10877ec681f3Smrg   if (iv->view_type == VK_IMAGE_VIEW_TYPE_3D) {
10887ec681f3Smrg      state->iv[p_stage][idx].u.tex.first_layer = 0;
10897ec681f3Smrg      state->iv[p_stage][idx].u.tex.last_layer = u_minify(iv->image->bo->depth0, iv->subresourceRange.baseMipLevel) - 1;
10907ec681f3Smrg   } else {
10917ec681f3Smrg      state->iv[p_stage][idx].u.tex.first_layer = iv->subresourceRange.baseArrayLayer;
10927ec681f3Smrg      state->iv[p_stage][idx].u.tex.last_layer = iv->subresourceRange.baseArrayLayer + lvp_get_layerCount(iv->image, &iv->subresourceRange) - 1;
10937ec681f3Smrg   }
10947ec681f3Smrg   state->iv[p_stage][idx].u.tex.level = iv->subresourceRange.baseMipLevel;
10957ec681f3Smrg   if (state->num_shader_images[p_stage] <= idx)
10967ec681f3Smrg      state->num_shader_images[p_stage] = idx + 1;
10977ec681f3Smrg   state->iv_dirty[p_stage] = true;
10987ec681f3Smrg}
10997ec681f3Smrg
11007ec681f3Smrgstatic void fill_image_buffer_view_stage(struct rendering_state *state,
11017ec681f3Smrg                                         struct dyn_info *dyn_info,
11027ec681f3Smrg                                         gl_shader_stage stage,
11037ec681f3Smrg                                         enum pipe_shader_type p_stage,
11047ec681f3Smrg                                         int array_idx,
11057ec681f3Smrg                                         const union lvp_descriptor_info *descriptor,
11067ec681f3Smrg                                         const struct lvp_descriptor_set_binding_layout *binding)
11077ec681f3Smrg{
11087ec681f3Smrg   struct lvp_buffer_view *bv = descriptor->buffer_view;
11097ec681f3Smrg   int idx = binding->stage[stage].image_index;
11107ec681f3Smrg   if (idx == -1)
11117ec681f3Smrg      return;
11127ec681f3Smrg   idx += array_idx;
11137ec681f3Smrg   idx += dyn_info->stage[stage].image_count;
11147ec681f3Smrg   state->iv[p_stage][idx].resource = bv->buffer->bo;
11157ec681f3Smrg   state->iv[p_stage][idx].format = bv->pformat;
11167ec681f3Smrg   state->iv[p_stage][idx].u.buf.offset = bv->offset + bv->buffer->offset;
11177ec681f3Smrg   state->iv[p_stage][idx].u.buf.size = bv->range == VK_WHOLE_SIZE ? (bv->buffer->size - bv->offset): bv->range;
11187ec681f3Smrg   if (state->num_shader_images[p_stage] <= idx)
11197ec681f3Smrg      state->num_shader_images[p_stage] = idx + 1;
11207ec681f3Smrg   state->iv_dirty[p_stage] = true;
11217ec681f3Smrg}
11227ec681f3Smrg
11237ec681f3Smrgstatic void handle_descriptor(struct rendering_state *state,
11247ec681f3Smrg                              struct dyn_info *dyn_info,
11257ec681f3Smrg                              const struct lvp_descriptor_set_binding_layout *binding,
11267ec681f3Smrg                              gl_shader_stage stage,
11277ec681f3Smrg                              enum pipe_shader_type p_stage,
11287ec681f3Smrg                              int array_idx,
11297ec681f3Smrg                              VkDescriptorType type,
11307ec681f3Smrg                              const union lvp_descriptor_info *descriptor)
11317ec681f3Smrg{
11327ec681f3Smrg   bool is_dynamic = type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
11337ec681f3Smrg      type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
11347ec681f3Smrg
11357ec681f3Smrg   switch (type) {
11367ec681f3Smrg   case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
11377ec681f3Smrg   case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: {
11387ec681f3Smrg      fill_image_view_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding);
11397ec681f3Smrg      break;
11407ec681f3Smrg   }
11417ec681f3Smrg   case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
11427ec681f3Smrg   case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: {
11437ec681f3Smrg      int idx = binding->stage[stage].const_buffer_index;
11447ec681f3Smrg      if (idx == -1)
11457ec681f3Smrg         return;
11467ec681f3Smrg      idx += array_idx;
11477ec681f3Smrg      idx += dyn_info->stage[stage].const_buffer_count;
11487ec681f3Smrg      state->const_buffer[p_stage][idx].buffer = descriptor->buffer->bo;
11497ec681f3Smrg      state->const_buffer[p_stage][idx].buffer_offset = descriptor->offset + descriptor->buffer->offset;
11507ec681f3Smrg      if (is_dynamic) {
11517ec681f3Smrg         uint32_t offset = dyn_info->dynamic_offsets[dyn_info->dyn_index + binding->dynamic_index + array_idx];
11527ec681f3Smrg         state->const_buffer[p_stage][idx].buffer_offset += offset;
11537ec681f3Smrg      }
11547ec681f3Smrg      if (descriptor->range == VK_WHOLE_SIZE)
11557ec681f3Smrg         state->const_buffer[p_stage][idx].buffer_size = descriptor->buffer->bo->width0 - state->const_buffer[p_stage][idx].buffer_offset;
11567ec681f3Smrg      else
11577ec681f3Smrg         state->const_buffer[p_stage][idx].buffer_size = descriptor->range;
11587ec681f3Smrg      if (state->num_const_bufs[p_stage] <= idx)
11597ec681f3Smrg         state->num_const_bufs[p_stage] = idx + 1;
11607ec681f3Smrg      state->constbuf_dirty[p_stage] = true;
11617ec681f3Smrg      break;
11627ec681f3Smrg   }
11637ec681f3Smrg   case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
11647ec681f3Smrg   case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: {
11657ec681f3Smrg      int idx = binding->stage[stage].shader_buffer_index;
11667ec681f3Smrg      if (idx == -1)
11677ec681f3Smrg         return;
11687ec681f3Smrg      idx += array_idx;
11697ec681f3Smrg      idx += dyn_info->stage[stage].shader_buffer_count;
11707ec681f3Smrg      state->sb[p_stage][idx].buffer = descriptor->buffer->bo;
11717ec681f3Smrg      state->sb[p_stage][idx].buffer_offset = descriptor->offset + descriptor->buffer->offset;
11727ec681f3Smrg      if (is_dynamic) {
11737ec681f3Smrg         uint32_t offset = dyn_info->dynamic_offsets[dyn_info->dyn_index + binding->dynamic_index + array_idx];
11747ec681f3Smrg         state->sb[p_stage][idx].buffer_offset += offset;
11757ec681f3Smrg      }
11767ec681f3Smrg      if (descriptor->range == VK_WHOLE_SIZE)
11777ec681f3Smrg         state->sb[p_stage][idx].buffer_size = descriptor->buffer->bo->width0 - state->sb[p_stage][idx].buffer_offset;
11787ec681f3Smrg      else
11797ec681f3Smrg         state->sb[p_stage][idx].buffer_size = descriptor->range;
11807ec681f3Smrg      if (state->num_shader_buffers[p_stage] <= idx)
11817ec681f3Smrg         state->num_shader_buffers[p_stage] = idx + 1;
11827ec681f3Smrg      state->sb_dirty[p_stage] = true;
11837ec681f3Smrg      break;
11847ec681f3Smrg   }
11857ec681f3Smrg   case VK_DESCRIPTOR_TYPE_SAMPLER:
11867ec681f3Smrg      if (!descriptor->sampler)
11877ec681f3Smrg         return;
11887ec681f3Smrg      fill_sampler_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding);
11897ec681f3Smrg      break;
11907ec681f3Smrg   case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
11917ec681f3Smrg      fill_sampler_view_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding);
11927ec681f3Smrg      break;
11937ec681f3Smrg   case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
11947ec681f3Smrg      fill_sampler_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding);
11957ec681f3Smrg      fill_sampler_view_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding);
11967ec681f3Smrg      break;
11977ec681f3Smrg   case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
11987ec681f3Smrg      fill_sampler_buffer_view_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding);
11997ec681f3Smrg      break;
12007ec681f3Smrg   case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
12017ec681f3Smrg      fill_image_buffer_view_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding);
12027ec681f3Smrg      break;
12037ec681f3Smrg   default:
12047ec681f3Smrg      fprintf(stderr, "Unhandled descriptor set %d\n", type);
12057ec681f3Smrg      break;
12067ec681f3Smrg   }
12077ec681f3Smrg}
12087ec681f3Smrg
12097ec681f3Smrgstatic void handle_set_stage(struct rendering_state *state,
12107ec681f3Smrg                             struct dyn_info *dyn_info,
12117ec681f3Smrg                             const struct lvp_descriptor_set *set,
12127ec681f3Smrg                             gl_shader_stage stage,
12137ec681f3Smrg                             enum pipe_shader_type p_stage)
12147ec681f3Smrg{
12157ec681f3Smrg   int j;
12167ec681f3Smrg   for (j = 0; j < set->layout->binding_count; j++) {
12177ec681f3Smrg      const struct lvp_descriptor_set_binding_layout *binding;
12187ec681f3Smrg      const struct lvp_descriptor *descriptor;
12197ec681f3Smrg      binding = &set->layout->binding[j];
12207ec681f3Smrg
12217ec681f3Smrg      if (binding->valid) {
12227ec681f3Smrg         for (int i = 0; i < binding->array_size; i++) {
12237ec681f3Smrg            descriptor = &set->descriptors[binding->descriptor_index + i];
12247ec681f3Smrg            handle_descriptor(state, dyn_info, binding, stage, p_stage, i, descriptor->type, &descriptor->info);
12257ec681f3Smrg         }
12267ec681f3Smrg      }
12277ec681f3Smrg   }
12287ec681f3Smrg}
12297ec681f3Smrg
12307ec681f3Smrgstatic void increment_dyn_info(struct dyn_info *dyn_info,
12317ec681f3Smrg                               struct lvp_descriptor_set_layout *layout, bool inc_dyn)
12327ec681f3Smrg{
12337ec681f3Smrg   for (gl_shader_stage stage = MESA_SHADER_VERTEX; stage < MESA_SHADER_STAGES; stage++) {
12347ec681f3Smrg      dyn_info->stage[stage].const_buffer_count += layout->stage[stage].const_buffer_count;
12357ec681f3Smrg      dyn_info->stage[stage].shader_buffer_count += layout->stage[stage].shader_buffer_count;
12367ec681f3Smrg      dyn_info->stage[stage].sampler_count += layout->stage[stage].sampler_count;
12377ec681f3Smrg      dyn_info->stage[stage].sampler_view_count += layout->stage[stage].sampler_view_count;
12387ec681f3Smrg      dyn_info->stage[stage].image_count += layout->stage[stage].image_count;
12397ec681f3Smrg   }
12407ec681f3Smrg   if (inc_dyn)
12417ec681f3Smrg      dyn_info->dyn_index += layout->dynamic_offset_count;
12427ec681f3Smrg}
12437ec681f3Smrg
12447ec681f3Smrgstatic void handle_compute_descriptor_sets(struct vk_cmd_queue_entry *cmd,
12457ec681f3Smrg                                           struct dyn_info *dyn_info,
12467ec681f3Smrg                                           struct rendering_state *state)
12477ec681f3Smrg{
12487ec681f3Smrg   struct vk_cmd_bind_descriptor_sets *bds = &cmd->u.bind_descriptor_sets;
12497ec681f3Smrg   struct lvp_descriptor_set_layout **set_layout = cmd->driver_data;
12507ec681f3Smrg   int i;
12517ec681f3Smrg
12527ec681f3Smrg   for (i = 0; i < bds->first_set; i++) {
12537ec681f3Smrg      increment_dyn_info(dyn_info, set_layout[i], false);
12547ec681f3Smrg   }
12557ec681f3Smrg   for (i = 0; i < bds->descriptor_set_count; i++) {
12567ec681f3Smrg      const struct lvp_descriptor_set *set = lvp_descriptor_set_from_handle(bds->descriptor_sets[i]);
12577ec681f3Smrg
12587ec681f3Smrg      if (set->layout->shader_stages & VK_SHADER_STAGE_COMPUTE_BIT)
12597ec681f3Smrg         handle_set_stage(state, dyn_info, set, MESA_SHADER_COMPUTE, PIPE_SHADER_COMPUTE);
12607ec681f3Smrg      increment_dyn_info(dyn_info, set_layout[bds->first_set + i], true);
12617ec681f3Smrg   }
12627ec681f3Smrg}
12637ec681f3Smrg
12647ec681f3Smrgstatic void handle_descriptor_sets(struct vk_cmd_queue_entry *cmd,
12657ec681f3Smrg                                   struct rendering_state *state)
12667ec681f3Smrg{
12677ec681f3Smrg   struct vk_cmd_bind_descriptor_sets *bds = &cmd->u.bind_descriptor_sets;
12687ec681f3Smrg   struct lvp_descriptor_set_layout **set_layout = cmd->driver_data;
12697ec681f3Smrg   int i;
12707ec681f3Smrg   struct dyn_info dyn_info;
12717ec681f3Smrg
12727ec681f3Smrg   dyn_info.dyn_index = 0;
12737ec681f3Smrg   dyn_info.dynamic_offsets = bds->dynamic_offsets;
12747ec681f3Smrg   dyn_info.dynamic_offset_count = bds->dynamic_offset_count;
12757ec681f3Smrg
12767ec681f3Smrg   memset(dyn_info.stage, 0, sizeof(dyn_info.stage));
12777ec681f3Smrg   if (bds->pipeline_bind_point == VK_PIPELINE_BIND_POINT_COMPUTE) {
12787ec681f3Smrg      handle_compute_descriptor_sets(cmd, &dyn_info, state);
12797ec681f3Smrg      return;
12807ec681f3Smrg   }
12817ec681f3Smrg
12827ec681f3Smrg   for (i = 0; i < bds->first_set; i++) {
12837ec681f3Smrg      increment_dyn_info(&dyn_info, set_layout[i], false);
12847ec681f3Smrg   }
12857ec681f3Smrg
12867ec681f3Smrg   for (i = 0; i < bds->descriptor_set_count; i++) {
12877ec681f3Smrg      const struct lvp_descriptor_set *set = lvp_descriptor_set_from_handle(bds->descriptor_sets[i]);
12887ec681f3Smrg
12897ec681f3Smrg      if (set->layout->shader_stages & VK_SHADER_STAGE_VERTEX_BIT)
12907ec681f3Smrg         handle_set_stage(state, &dyn_info, set, MESA_SHADER_VERTEX, PIPE_SHADER_VERTEX);
12917ec681f3Smrg
12927ec681f3Smrg      if (set->layout->shader_stages & VK_SHADER_STAGE_GEOMETRY_BIT)
12937ec681f3Smrg         handle_set_stage(state, &dyn_info, set, MESA_SHADER_GEOMETRY, PIPE_SHADER_GEOMETRY);
12947ec681f3Smrg
12957ec681f3Smrg      if (set->layout->shader_stages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
12967ec681f3Smrg         handle_set_stage(state, &dyn_info, set, MESA_SHADER_TESS_CTRL, PIPE_SHADER_TESS_CTRL);
12977ec681f3Smrg
12987ec681f3Smrg      if (set->layout->shader_stages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
12997ec681f3Smrg         handle_set_stage(state, &dyn_info, set, MESA_SHADER_TESS_EVAL, PIPE_SHADER_TESS_EVAL);
13007ec681f3Smrg
13017ec681f3Smrg      if (set->layout->shader_stages & VK_SHADER_STAGE_FRAGMENT_BIT)
13027ec681f3Smrg         handle_set_stage(state, &dyn_info, set, MESA_SHADER_FRAGMENT, PIPE_SHADER_FRAGMENT);
13037ec681f3Smrg
13047ec681f3Smrg      increment_dyn_info(&dyn_info, set_layout[bds->first_set + i], true);
13057ec681f3Smrg   }
13067ec681f3Smrg}
13077ec681f3Smrg
13087ec681f3Smrgstatic struct pipe_surface *create_img_surface_bo(struct rendering_state *state,
13097ec681f3Smrg                                                  VkImageSubresourceRange *range,
13107ec681f3Smrg                                                  struct pipe_resource *bo,
13117ec681f3Smrg                                                  enum pipe_format pformat,
13127ec681f3Smrg                                                  int width,
13137ec681f3Smrg                                                  int height,
13147ec681f3Smrg                                                  int base_layer, int layer_count,
13157ec681f3Smrg                                                  int level)
13167ec681f3Smrg{
13177ec681f3Smrg   struct pipe_surface template;
13187ec681f3Smrg
13197ec681f3Smrg   memset(&template, 0, sizeof(struct pipe_surface));
13207ec681f3Smrg
13217ec681f3Smrg   template.format = pformat;
13227ec681f3Smrg   template.width = width;
13237ec681f3Smrg   template.height = height;
13247ec681f3Smrg   template.u.tex.first_layer = range->baseArrayLayer + base_layer;
13257ec681f3Smrg   template.u.tex.last_layer = range->baseArrayLayer + layer_count;
13267ec681f3Smrg   template.u.tex.level = range->baseMipLevel + level;
13277ec681f3Smrg
13287ec681f3Smrg   if (template.format == PIPE_FORMAT_NONE)
13297ec681f3Smrg      return NULL;
13307ec681f3Smrg   return state->pctx->create_surface(state->pctx,
13317ec681f3Smrg                                      bo, &template);
13327ec681f3Smrg
13337ec681f3Smrg}
13347ec681f3Smrgstatic struct pipe_surface *create_img_surface(struct rendering_state *state,
13357ec681f3Smrg                                               struct lvp_image_view *imgv,
13367ec681f3Smrg                                               VkFormat format, int width,
13377ec681f3Smrg                                               int height,
13387ec681f3Smrg                                               int base_layer, int layer_count)
13397ec681f3Smrg{
13407ec681f3Smrg   return create_img_surface_bo(state, &imgv->subresourceRange, imgv->image->bo,
13417ec681f3Smrg                                lvp_vk_format_to_pipe_format(format), width, height, base_layer, layer_count, 0);
13427ec681f3Smrg}
13437ec681f3Smrg
13447ec681f3Smrgstatic void add_img_view_surface(struct rendering_state *state,
13457ec681f3Smrg                                 struct lvp_image_view *imgv, VkFormat format, int width, int height)
13467ec681f3Smrg{
13477ec681f3Smrg   if (!imgv->surface) {
13487ec681f3Smrg      imgv->surface = create_img_surface(state, imgv, format,
13497ec681f3Smrg                                         width, height,
13507ec681f3Smrg                                         0, lvp_get_layerCount(imgv->image, &imgv->subresourceRange) - 1);
13517ec681f3Smrg   }
13527ec681f3Smrg}
13537ec681f3Smrg
13547ec681f3Smrgstatic inline bool
13557ec681f3Smrgattachment_needs_clear(struct rendering_state *state,
13567ec681f3Smrg                       uint32_t a)
13577ec681f3Smrg{
13587ec681f3Smrg   const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
13597ec681f3Smrg   uint32_t view_mask = subpass->view_mask;
13607ec681f3Smrg   return (a != VK_ATTACHMENT_UNUSED &&
13617ec681f3Smrg           state->pending_clear_aspects[a] &&
13627ec681f3Smrg           (!view_mask || (view_mask & ~state->cleared_views[a])));
13637ec681f3Smrg}
13647ec681f3Smrg
13657ec681f3Smrgstatic bool
13667ec681f3Smrgsubpass_needs_clear(struct rendering_state *state)
13677ec681f3Smrg{
13687ec681f3Smrg   uint32_t a;
13697ec681f3Smrg   const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
13707ec681f3Smrg   for (uint32_t i = 0; i < subpass->color_count; i++) {
13717ec681f3Smrg      a = subpass->color_attachments[i].attachment;
13727ec681f3Smrg      if (attachment_needs_clear(state, a))
13737ec681f3Smrg         return true;
13747ec681f3Smrg   }
13757ec681f3Smrg   if (subpass->depth_stencil_attachment) {
13767ec681f3Smrg      a = subpass->depth_stencil_attachment->attachment;
13777ec681f3Smrg      if (attachment_needs_clear(state, a))
13787ec681f3Smrg         return true;
13797ec681f3Smrg   }
13807ec681f3Smrg   return false;
13817ec681f3Smrg}
13827ec681f3Smrg
13837ec681f3Smrgstatic void clear_attachment_layers(struct rendering_state *state,
13847ec681f3Smrg                                    struct lvp_image_view *imgv,
13857ec681f3Smrg                                    VkRect2D *rect,
13867ec681f3Smrg                                    unsigned base_layer, unsigned layer_count,
13877ec681f3Smrg                                    unsigned ds_clear_flags, double dclear_val,
13887ec681f3Smrg                                    uint32_t sclear_val,
13897ec681f3Smrg                                    union pipe_color_union *col_val)
13907ec681f3Smrg{
13917ec681f3Smrg   struct pipe_surface *clear_surf = create_img_surface(state,
13927ec681f3Smrg                                                        imgv,
13937ec681f3Smrg                                                        imgv->format,
13947ec681f3Smrg                                                        state->framebuffer.width,
13957ec681f3Smrg                                                        state->framebuffer.height,
13967ec681f3Smrg                                                        base_layer,
13977ec681f3Smrg                                                        base_layer + layer_count - 1);
13987ec681f3Smrg
13997ec681f3Smrg   if (ds_clear_flags) {
14007ec681f3Smrg      state->pctx->clear_depth_stencil(state->pctx,
14017ec681f3Smrg                                       clear_surf,
14027ec681f3Smrg                                       ds_clear_flags,
14037ec681f3Smrg                                       dclear_val, sclear_val,
14047ec681f3Smrg                                       rect->offset.x, rect->offset.y,
14057ec681f3Smrg                                       rect->extent.width, rect->extent.height,
14067ec681f3Smrg                                       true);
14077ec681f3Smrg   } else {
14087ec681f3Smrg      state->pctx->clear_render_target(state->pctx, clear_surf,
14097ec681f3Smrg                                       col_val,
14107ec681f3Smrg                                       rect->offset.x, rect->offset.y,
14117ec681f3Smrg                                       rect->extent.width, rect->extent.height,
14127ec681f3Smrg                                       true);
14137ec681f3Smrg   }
14147ec681f3Smrg   state->pctx->surface_destroy(state->pctx, clear_surf);
14157ec681f3Smrg}
14167ec681f3Smrg
14177ec681f3Smrgstatic struct lvp_image_view *
14187ec681f3Smrgget_attachment(struct rendering_state *state,
14197ec681f3Smrg               unsigned idx)
14207ec681f3Smrg{
14217ec681f3Smrg   if (state->imageless_views)
14227ec681f3Smrg      return state->imageless_views[idx];
14237ec681f3Smrg   else
14247ec681f3Smrg      return state->vk_framebuffer->attachments[idx];
14257ec681f3Smrg}
14267ec681f3Smrg
14277ec681f3Smrgstatic void render_subpass_clear(struct rendering_state *state)
14287ec681f3Smrg{
14297ec681f3Smrg   const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
14307ec681f3Smrg
14317ec681f3Smrg   for (unsigned i = 0; i < subpass->color_count; i++) {
14327ec681f3Smrg      uint32_t a = subpass->color_attachments[i].attachment;
14337ec681f3Smrg
14347ec681f3Smrg      if (!attachment_needs_clear(state, a))
14357ec681f3Smrg         continue;
14367ec681f3Smrg
14377ec681f3Smrg      union pipe_color_union color_clear_val = { 0 };
14387ec681f3Smrg      const VkClearValue value = state->attachments[a].clear_value;
14397ec681f3Smrg      color_clear_val.ui[0] = value.color.uint32[0];
14407ec681f3Smrg      color_clear_val.ui[1] = value.color.uint32[1];
14417ec681f3Smrg      color_clear_val.ui[2] = value.color.uint32[2];
14427ec681f3Smrg      color_clear_val.ui[3] = value.color.uint32[3];
14437ec681f3Smrg
14447ec681f3Smrg      struct lvp_image_view *imgv = get_attachment(state, a);
14457ec681f3Smrg
14467ec681f3Smrg      assert(imgv->surface);
14477ec681f3Smrg
14487ec681f3Smrg      if (subpass->view_mask) {
14497ec681f3Smrg         u_foreach_bit(i, subpass->view_mask)
14507ec681f3Smrg            clear_attachment_layers(state, imgv, &state->render_area,
14517ec681f3Smrg                                    i, 1, 0, 0, 0, &color_clear_val);
14527ec681f3Smrg         state->cleared_views[a] |= subpass->view_mask;
14537ec681f3Smrg      } else {
14547ec681f3Smrg         state->pctx->clear_render_target(state->pctx,
14557ec681f3Smrg                                          imgv->surface,
14567ec681f3Smrg                                          &color_clear_val,
14577ec681f3Smrg                                          state->render_area.offset.x, state->render_area.offset.y,
14587ec681f3Smrg                                          state->render_area.extent.width, state->render_area.extent.height,
14597ec681f3Smrg                                          false);
14607ec681f3Smrg         state->pending_clear_aspects[a] = 0;
14617ec681f3Smrg      }
14627ec681f3Smrg   }
14637ec681f3Smrg
14647ec681f3Smrg   if (subpass->depth_stencil_attachment) {
14657ec681f3Smrg      uint32_t ds = subpass->depth_stencil_attachment->attachment;
14667ec681f3Smrg
14677ec681f3Smrg      if (!attachment_needs_clear(state, ds))
14687ec681f3Smrg         return;
14697ec681f3Smrg
14707ec681f3Smrg      struct lvp_render_pass_attachment *att = &state->pass->attachments[ds];
14717ec681f3Smrg      struct lvp_image_view *imgv = get_attachment(state, ds);
14727ec681f3Smrg
14737ec681f3Smrg      assert (util_format_is_depth_or_stencil(imgv->surface->format));
14747ec681f3Smrg
14757ec681f3Smrg      const struct util_format_description *desc = util_format_description(imgv->surface->format);
14767ec681f3Smrg      double dclear_val = 0;
14777ec681f3Smrg      uint32_t sclear_val = 0;
14787ec681f3Smrg      uint32_t ds_clear_flags = 0;
14797ec681f3Smrg
14807ec681f3Smrg      if ((util_format_has_stencil(desc) && att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) ||
14817ec681f3Smrg          (util_format_is_depth_and_stencil(imgv->surface->format) && att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_DONT_CARE)) {
14827ec681f3Smrg         ds_clear_flags |= PIPE_CLEAR_STENCIL;
14837ec681f3Smrg         if (att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR)
14847ec681f3Smrg            sclear_val = state->attachments[ds].clear_value.depthStencil.stencil;
14857ec681f3Smrg      }
14867ec681f3Smrg      if ((util_format_has_depth(desc) && att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) ||
14877ec681f3Smrg          (util_format_is_depth_and_stencil(imgv->surface->format) && att->load_op == VK_ATTACHMENT_LOAD_OP_DONT_CARE)) {
14887ec681f3Smrg         ds_clear_flags |= PIPE_CLEAR_DEPTH;
14897ec681f3Smrg         if (att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR)
14907ec681f3Smrg            dclear_val = state->attachments[ds].clear_value.depthStencil.depth;
14917ec681f3Smrg      }
14927ec681f3Smrg
14937ec681f3Smrg      assert(imgv->surface);
14947ec681f3Smrg      if (ds_clear_flags) {
14957ec681f3Smrg         if (subpass->view_mask) {
14967ec681f3Smrg            u_foreach_bit(i, subpass->view_mask)
14977ec681f3Smrg               clear_attachment_layers(state, imgv, &state->render_area,
14987ec681f3Smrg                                       i, 1, ds_clear_flags, dclear_val, sclear_val, NULL);
14997ec681f3Smrg            state->cleared_views[ds] |= subpass->view_mask;
15007ec681f3Smrg         } else {
15017ec681f3Smrg            state->pctx->clear_depth_stencil(state->pctx,
15027ec681f3Smrg                                             imgv->surface,
15037ec681f3Smrg                                             ds_clear_flags,
15047ec681f3Smrg                                             dclear_val, sclear_val,
15057ec681f3Smrg                                             state->render_area.offset.x, state->render_area.offset.y,
15067ec681f3Smrg                                             state->render_area.extent.width, state->render_area.extent.height,
15077ec681f3Smrg                                             false);
15087ec681f3Smrg            state->pending_clear_aspects[ds] = 0;
15097ec681f3Smrg         }
15107ec681f3Smrg      }
15117ec681f3Smrg
15127ec681f3Smrg   }
15137ec681f3Smrg
15147ec681f3Smrg}
15157ec681f3Smrg
15167ec681f3Smrgstatic void render_subpass_clear_fast(struct rendering_state *state)
15177ec681f3Smrg{
15187ec681f3Smrg   /* attempt to use the clear interface first, then fallback to per-attchment clears */
15197ec681f3Smrg   const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
15207ec681f3Smrg   bool has_color_value = false;
15217ec681f3Smrg   uint32_t buffers = 0;
15227ec681f3Smrg   VkClearValue color_value = {0};
15237ec681f3Smrg   double dclear_val = 0;
15247ec681f3Smrg   uint32_t sclear_val = 0;
15257ec681f3Smrg
15267ec681f3Smrg   /*
15277ec681f3Smrg    * the state tracker clear interface only works if all the attachments have the same
15287ec681f3Smrg    * clear color.
15297ec681f3Smrg    */
15307ec681f3Smrg   /* llvmpipe doesn't support scissored clears yet */
15317ec681f3Smrg   if (state->render_area.offset.x || state->render_area.offset.y)
15327ec681f3Smrg      goto slow_clear;
15337ec681f3Smrg
15347ec681f3Smrg   if (state->render_area.extent.width != state->framebuffer.width ||
15357ec681f3Smrg       state->render_area.extent.height != state->framebuffer.height)
15367ec681f3Smrg      goto slow_clear;
15377ec681f3Smrg
15387ec681f3Smrg   if (subpass->view_mask)
15397ec681f3Smrg      goto slow_clear;
15407ec681f3Smrg   for (unsigned i = 0; i < subpass->color_count; i++) {
15417ec681f3Smrg      uint32_t a = subpass->color_attachments[i].attachment;
15427ec681f3Smrg
15437ec681f3Smrg      if (!attachment_needs_clear(state, a))
15447ec681f3Smrg         continue;
15457ec681f3Smrg
15467ec681f3Smrg      if (has_color_value) {
15477ec681f3Smrg         if (memcmp(&color_value, &state->attachments[a].clear_value, sizeof(VkClearValue)))
15487ec681f3Smrg            goto slow_clear;
15497ec681f3Smrg      } else {
15507ec681f3Smrg         memcpy(&color_value, &state->attachments[a].clear_value, sizeof(VkClearValue));
15517ec681f3Smrg         has_color_value = true;
15527ec681f3Smrg      }
15537ec681f3Smrg   }
15547ec681f3Smrg
15557ec681f3Smrg   for (unsigned i = 0; i < subpass->color_count; i++) {
15567ec681f3Smrg      uint32_t a = subpass->color_attachments[i].attachment;
15577ec681f3Smrg
15587ec681f3Smrg      if (!attachment_needs_clear(state, a))
15597ec681f3Smrg         continue;
15607ec681f3Smrg      buffers |= (PIPE_CLEAR_COLOR0 << i);
15617ec681f3Smrg      state->pending_clear_aspects[a] = 0;
15627ec681f3Smrg   }
15637ec681f3Smrg
15647ec681f3Smrg   if (subpass->depth_stencil_attachment &&
15657ec681f3Smrg       attachment_needs_clear(state, subpass->depth_stencil_attachment->attachment)) {
15667ec681f3Smrg      uint32_t ds = subpass->depth_stencil_attachment->attachment;
15677ec681f3Smrg
15687ec681f3Smrg      struct lvp_render_pass_attachment *att = &state->pass->attachments[ds];
15697ec681f3Smrg      struct lvp_image_view *imgv = get_attachment(state, ds);
15707ec681f3Smrg      const struct util_format_description *desc = util_format_description(imgv->surface->format);
15717ec681f3Smrg
15727ec681f3Smrg      /* also clear stencil for don't care to avoid RMW */
15737ec681f3Smrg      if ((util_format_has_stencil(desc) && att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) ||
15747ec681f3Smrg          (util_format_is_depth_and_stencil(imgv->surface->format) && att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_DONT_CARE))
15757ec681f3Smrg         buffers |= PIPE_CLEAR_STENCIL;
15767ec681f3Smrg      if (util_format_has_depth(desc) && att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR)
15777ec681f3Smrg         buffers |= PIPE_CLEAR_DEPTH;
15787ec681f3Smrg
15797ec681f3Smrg      dclear_val = state->attachments[ds].clear_value.depthStencil.depth;
15807ec681f3Smrg      sclear_val = state->attachments[ds].clear_value.depthStencil.stencil;
15817ec681f3Smrg      state->pending_clear_aspects[ds] = 0;
15827ec681f3Smrg   }
15837ec681f3Smrg
15847ec681f3Smrg   union pipe_color_union col_val;
15857ec681f3Smrg   for (unsigned i = 0; i < 4; i++)
15867ec681f3Smrg      col_val.ui[i] = color_value.color.uint32[i];
15877ec681f3Smrg
15887ec681f3Smrg   state->pctx->clear(state->pctx, buffers,
15897ec681f3Smrg                      NULL, &col_val,
15907ec681f3Smrg                      dclear_val, sclear_val);
15917ec681f3Smrg   return;
15927ec681f3Smrgslow_clear:
15937ec681f3Smrg   render_subpass_clear(state);
15947ec681f3Smrg}
15957ec681f3Smrg
15967ec681f3Smrgstatic void render_pass_resolve(struct rendering_state *state)
15977ec681f3Smrg{
15987ec681f3Smrg   const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
15997ec681f3Smrg
16007ec681f3Smrg   if (subpass->depth_stencil_attachment && subpass->ds_resolve_attachment) {
16017ec681f3Smrg      struct lvp_subpass_attachment src_att = *subpass->depth_stencil_attachment;
16027ec681f3Smrg      struct lvp_subpass_attachment dst_att = *subpass->ds_resolve_attachment;
16037ec681f3Smrg      if (dst_att.attachment != VK_ATTACHMENT_UNUSED) {
16047ec681f3Smrg         int num_blits = 1;
16057ec681f3Smrg         if (subpass->depth_resolve_mode != subpass->stencil_resolve_mode)
16067ec681f3Smrg            num_blits = 2;
16077ec681f3Smrg
16087ec681f3Smrg         for (unsigned i = 0; i < num_blits; i++) {
16097ec681f3Smrg
16107ec681f3Smrg            if (i == 0 && subpass->depth_resolve_mode == VK_RESOLVE_MODE_NONE)
16117ec681f3Smrg               continue;
16127ec681f3Smrg
16137ec681f3Smrg            if (i == 1 && subpass->stencil_resolve_mode == VK_RESOLVE_MODE_NONE)
16147ec681f3Smrg               continue;
16157ec681f3Smrg
16167ec681f3Smrg            struct lvp_image_view *src_imgv = get_attachment(state, src_att.attachment);
16177ec681f3Smrg            struct lvp_image_view *dst_imgv = get_attachment(state, dst_att.attachment);
16187ec681f3Smrg
16197ec681f3Smrg            struct pipe_blit_info info;
16207ec681f3Smrg            memset(&info, 0, sizeof(info));
16217ec681f3Smrg
16227ec681f3Smrg            info.src.resource = src_imgv->image->bo;
16237ec681f3Smrg            info.dst.resource = dst_imgv->image->bo;
16247ec681f3Smrg            info.src.format = src_imgv->pformat;
16257ec681f3Smrg            info.dst.format = dst_imgv->pformat;
16267ec681f3Smrg            info.filter = PIPE_TEX_FILTER_NEAREST;
16277ec681f3Smrg
16287ec681f3Smrg            if (num_blits == 1)
16297ec681f3Smrg               info.mask = PIPE_MASK_ZS;
16307ec681f3Smrg            else if (i == 0)
16317ec681f3Smrg               info.mask = PIPE_MASK_Z;
16327ec681f3Smrg            else
16337ec681f3Smrg               info.mask = PIPE_MASK_S;
16347ec681f3Smrg
16357ec681f3Smrg            if (i == 0 && subpass->depth_resolve_mode == VK_RESOLVE_MODE_SAMPLE_ZERO_BIT)
16367ec681f3Smrg               info.sample0_only = true;
16377ec681f3Smrg            if (i == 1 && subpass->stencil_resolve_mode == VK_RESOLVE_MODE_SAMPLE_ZERO_BIT)
16387ec681f3Smrg               info.sample0_only = true;
16397ec681f3Smrg
16407ec681f3Smrg            info.src.box.x = state->render_area.offset.x;
16417ec681f3Smrg            info.src.box.y = state->render_area.offset.y;
16427ec681f3Smrg            info.src.box.width = state->render_area.extent.width;
16437ec681f3Smrg            info.src.box.height = state->render_area.extent.height;
16447ec681f3Smrg            info.src.box.depth = state->vk_framebuffer->layers;
16457ec681f3Smrg
16467ec681f3Smrg            info.dst.box = info.src.box;
16477ec681f3Smrg
16487ec681f3Smrg            state->pctx->blit(state->pctx, &info);
16497ec681f3Smrg         }
16507ec681f3Smrg      }
16517ec681f3Smrg   }
16527ec681f3Smrg
16537ec681f3Smrg   if (!subpass->has_color_resolve)
16547ec681f3Smrg      return;
16557ec681f3Smrg   for (uint32_t i = 0; i < subpass->color_count; i++) {
16567ec681f3Smrg      struct lvp_subpass_attachment src_att = subpass->color_attachments[i];
16577ec681f3Smrg      struct lvp_subpass_attachment dst_att = subpass->resolve_attachments[i];
16587ec681f3Smrg
16597ec681f3Smrg      if (dst_att.attachment == VK_ATTACHMENT_UNUSED)
16607ec681f3Smrg         continue;
16617ec681f3Smrg
16627ec681f3Smrg      struct lvp_image_view *src_imgv = get_attachment(state, src_att.attachment);
16637ec681f3Smrg      struct lvp_image_view *dst_imgv = get_attachment(state, dst_att.attachment);
16647ec681f3Smrg
16657ec681f3Smrg      struct pipe_blit_info info;
16667ec681f3Smrg      memset(&info, 0, sizeof(info));
16677ec681f3Smrg
16687ec681f3Smrg      info.src.resource = src_imgv->image->bo;
16697ec681f3Smrg      info.dst.resource = dst_imgv->image->bo;
16707ec681f3Smrg      info.src.format = src_imgv->pformat;
16717ec681f3Smrg      info.dst.format = dst_imgv->pformat;
16727ec681f3Smrg      info.filter = PIPE_TEX_FILTER_NEAREST;
16737ec681f3Smrg      info.mask = PIPE_MASK_RGBA;
16747ec681f3Smrg      info.src.box.x = state->render_area.offset.x;
16757ec681f3Smrg      info.src.box.y = state->render_area.offset.y;
16767ec681f3Smrg      info.src.box.width = state->render_area.extent.width;
16777ec681f3Smrg      info.src.box.height = state->render_area.extent.height;
16787ec681f3Smrg      info.src.box.depth = state->vk_framebuffer->layers;
16797ec681f3Smrg
16807ec681f3Smrg      info.dst.box = info.src.box;
16817ec681f3Smrg
16827ec681f3Smrg      info.src.level = src_imgv->subresourceRange.baseMipLevel;
16837ec681f3Smrg      info.dst.level = dst_imgv->subresourceRange.baseMipLevel;
16847ec681f3Smrg
16857ec681f3Smrg      state->pctx->blit(state->pctx, &info);
16867ec681f3Smrg   }
16877ec681f3Smrg}
16887ec681f3Smrg
16897ec681f3Smrgstatic void begin_render_subpass(struct rendering_state *state,
16907ec681f3Smrg                                 int subpass_idx)
16917ec681f3Smrg{
16927ec681f3Smrg   state->subpass = subpass_idx;
16937ec681f3Smrg
16947ec681f3Smrg   state->framebuffer.nr_cbufs = 0;
16957ec681f3Smrg
16967ec681f3Smrg   const struct lvp_subpass *subpass = &state->pass->subpasses[subpass_idx];
16977ec681f3Smrg   for (unsigned i = 0; i < subpass->color_count; i++) {
16987ec681f3Smrg      struct lvp_subpass_attachment *color_att = &subpass->color_attachments[i];
16997ec681f3Smrg      if (color_att->attachment != VK_ATTACHMENT_UNUSED) {
17007ec681f3Smrg         struct lvp_image_view *imgv = get_attachment(state, color_att->attachment);
17017ec681f3Smrg         add_img_view_surface(state, imgv, state->pass->attachments[color_att->attachment].format, state->framebuffer.width, state->framebuffer.height);
17027ec681f3Smrg         state->framebuffer.cbufs[state->framebuffer.nr_cbufs] = imgv->surface;
17037ec681f3Smrg      } else
17047ec681f3Smrg         state->framebuffer.cbufs[state->framebuffer.nr_cbufs] = NULL;
17057ec681f3Smrg      state->framebuffer.nr_cbufs++;
17067ec681f3Smrg   }
17077ec681f3Smrg
17087ec681f3Smrg   if (subpass->depth_stencil_attachment) {
17097ec681f3Smrg      struct lvp_subpass_attachment *ds_att = subpass->depth_stencil_attachment;
17107ec681f3Smrg
17117ec681f3Smrg      if (ds_att->attachment != VK_ATTACHMENT_UNUSED) {
17127ec681f3Smrg         struct lvp_image_view *imgv = get_attachment(state, ds_att->attachment);
17137ec681f3Smrg         add_img_view_surface(state, imgv, state->pass->attachments[ds_att->attachment].format, state->framebuffer.width, state->framebuffer.height);
17147ec681f3Smrg         state->framebuffer.zsbuf = imgv->surface;
17157ec681f3Smrg      }
17167ec681f3Smrg   }
17177ec681f3Smrg
17187ec681f3Smrg   state->pctx->set_framebuffer_state(state->pctx,
17197ec681f3Smrg                                      &state->framebuffer);
17207ec681f3Smrg
17217ec681f3Smrg   if (subpass_needs_clear(state))
17227ec681f3Smrg      render_subpass_clear_fast(state);
17237ec681f3Smrg}
17247ec681f3Smrg
17257ec681f3Smrgstatic void begin_render_pass(const VkRenderPassBeginInfo *render_pass_begin,
17267ec681f3Smrg                              struct rendering_state *state)
17277ec681f3Smrg{
17287ec681f3Smrg   LVP_FROM_HANDLE(lvp_render_pass, pass, render_pass_begin->renderPass);
17297ec681f3Smrg   LVP_FROM_HANDLE(lvp_framebuffer, framebuffer, render_pass_begin->framebuffer);
17307ec681f3Smrg   const struct VkRenderPassAttachmentBeginInfo *attachment_info =
17317ec681f3Smrg      vk_find_struct_const(render_pass_begin->pNext,
17327ec681f3Smrg                           RENDER_PASS_ATTACHMENT_BEGIN_INFO);
17337ec681f3Smrg
17347ec681f3Smrg   state->pass = pass;
17357ec681f3Smrg   state->vk_framebuffer = framebuffer;
17367ec681f3Smrg   state->render_area = render_pass_begin->renderArea;
17377ec681f3Smrg
17387ec681f3Smrg   if (attachment_info) {
17397ec681f3Smrg      state->imageless_views = realloc(state->imageless_views, sizeof(*state->imageless_views) * attachment_info->attachmentCount);
17407ec681f3Smrg      for (unsigned i = 0; i < attachment_info->attachmentCount; i++)
17417ec681f3Smrg         state->imageless_views[i] = lvp_image_view_from_handle(attachment_info->pAttachments[i]);
17427ec681f3Smrg   }
17437ec681f3Smrg
17447ec681f3Smrg   state->framebuffer.width = state->vk_framebuffer->width;
17457ec681f3Smrg   state->framebuffer.height = state->vk_framebuffer->height;
17467ec681f3Smrg   state->framebuffer.layers = state->vk_framebuffer->layers;
17477ec681f3Smrg
17487ec681f3Smrg   if (state->num_pending_aspects < state->pass->attachment_count) {
17497ec681f3Smrg      state->pending_clear_aspects = realloc(state->pending_clear_aspects, sizeof(VkImageAspectFlags) * state->pass->attachment_count);
17507ec681f3Smrg      state->cleared_views = realloc(state->cleared_views, sizeof(uint32_t) * state->pass->attachment_count);
17517ec681f3Smrg      state->num_pending_aspects = state->pass->attachment_count;
17527ec681f3Smrg   }
17537ec681f3Smrg
17547ec681f3Smrg   state->attachments = realloc(state->attachments, sizeof(*state->attachments) * pass->attachment_count);
17557ec681f3Smrg   for (unsigned i = 0; i < state->pass->attachment_count; i++) {
17567ec681f3Smrg      struct lvp_render_pass_attachment *att = &pass->attachments[i];
17577ec681f3Smrg      VkImageAspectFlags att_aspects = vk_format_aspects(att->format);
17587ec681f3Smrg      VkImageAspectFlags clear_aspects = 0;
17597ec681f3Smrg      if (att_aspects == VK_IMAGE_ASPECT_COLOR_BIT) {
17607ec681f3Smrg         /* color attachment */
17617ec681f3Smrg         if (att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
17627ec681f3Smrg            clear_aspects |= VK_IMAGE_ASPECT_COLOR_BIT;
17637ec681f3Smrg         }
17647ec681f3Smrg      } else {
17657ec681f3Smrg         /* depthstencil attachment */
17667ec681f3Smrg         if ((att_aspects & VK_IMAGE_ASPECT_DEPTH_BIT) &&
17677ec681f3Smrg             att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
17687ec681f3Smrg            clear_aspects |= VK_IMAGE_ASPECT_DEPTH_BIT;
17697ec681f3Smrg            if ((att_aspects & VK_IMAGE_ASPECT_STENCIL_BIT) &&
17707ec681f3Smrg                att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
17717ec681f3Smrg               clear_aspects |= VK_IMAGE_ASPECT_STENCIL_BIT;
17727ec681f3Smrg         }
17737ec681f3Smrg         if ((att_aspects & VK_IMAGE_ASPECT_STENCIL_BIT) &&
17747ec681f3Smrg             att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
17757ec681f3Smrg            clear_aspects |= VK_IMAGE_ASPECT_STENCIL_BIT;
17767ec681f3Smrg         }
17777ec681f3Smrg      }
17787ec681f3Smrg      state->attachments[i].pending_clear_aspects = clear_aspects;
17797ec681f3Smrg      if (clear_aspects)
17807ec681f3Smrg         state->attachments[i].clear_value = render_pass_begin->pClearValues[i];
17817ec681f3Smrg
17827ec681f3Smrg      state->pending_clear_aspects[i] = state->attachments[i].pending_clear_aspects;
17837ec681f3Smrg      state->cleared_views[i] = 0;
17847ec681f3Smrg   }
17857ec681f3Smrg   begin_render_subpass(state, 0);
17867ec681f3Smrg}
17877ec681f3Smrg
17887ec681f3Smrg
17897ec681f3Smrgstatic void handle_begin_render_pass(struct vk_cmd_queue_entry *cmd,
17907ec681f3Smrg                                     struct rendering_state *state)
17917ec681f3Smrg{
17927ec681f3Smrg   begin_render_pass(cmd->u.begin_render_pass.render_pass_begin, state);
17937ec681f3Smrg}
17947ec681f3Smrg
17957ec681f3Smrgstatic void handle_begin_render_pass2(struct vk_cmd_queue_entry *cmd,
17967ec681f3Smrg                                      struct rendering_state *state)
17977ec681f3Smrg{
17987ec681f3Smrg   begin_render_pass(cmd->u.begin_render_pass2.render_pass_begin, state);
17997ec681f3Smrg}
18007ec681f3Smrg
18017ec681f3Smrgstatic void handle_end_render_pass2(struct vk_cmd_queue_entry *cmd,
18027ec681f3Smrg                                    struct rendering_state *state)
18037ec681f3Smrg{
18047ec681f3Smrg   state->pctx->flush(state->pctx, NULL, 0);
18057ec681f3Smrg
18067ec681f3Smrg   render_pass_resolve(state);
18077ec681f3Smrg
18087ec681f3Smrg   free(state->attachments);
18097ec681f3Smrg   state->attachments = NULL;
18107ec681f3Smrg   state->pass = NULL;
18117ec681f3Smrg   state->subpass = 0;
18127ec681f3Smrg}
18137ec681f3Smrg
18147ec681f3Smrgstatic void handle_next_subpass2(struct vk_cmd_queue_entry *cmd,
18157ec681f3Smrg                                struct rendering_state *state)
18167ec681f3Smrg{
18177ec681f3Smrg   state->pctx->flush(state->pctx, NULL, 0);
18187ec681f3Smrg   render_pass_resolve(state);
18197ec681f3Smrg   state->subpass++;
18207ec681f3Smrg   begin_render_subpass(state, state->subpass);
18217ec681f3Smrg}
18227ec681f3Smrg
18237ec681f3Smrgstatic void handle_draw(struct vk_cmd_queue_entry *cmd,
18247ec681f3Smrg                        struct rendering_state *state)
18257ec681f3Smrg{
18267ec681f3Smrg   const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
18277ec681f3Smrg   struct pipe_draw_start_count_bias draw;
18287ec681f3Smrg
18297ec681f3Smrg   state->info.index_size = 0;
18307ec681f3Smrg   state->info.index.resource = NULL;
18317ec681f3Smrg   state->info.start_instance = cmd->u.draw.first_instance;
18327ec681f3Smrg   state->info.instance_count = cmd->u.draw.instance_count;
18337ec681f3Smrg   state->info.view_mask = subpass->view_mask;
18347ec681f3Smrg
18357ec681f3Smrg   draw.start = cmd->u.draw.first_vertex;
18367ec681f3Smrg   draw.count = cmd->u.draw.vertex_count;
18377ec681f3Smrg
18387ec681f3Smrg   state->pctx->set_patch_vertices(state->pctx, state->patch_vertices);
18397ec681f3Smrg   state->pctx->draw_vbo(state->pctx, &state->info, 0, NULL, &draw, 1);
18407ec681f3Smrg}
18417ec681f3Smrg
18427ec681f3Smrgstatic void handle_draw_multi(struct vk_cmd_queue_entry *cmd,
18437ec681f3Smrg                              struct rendering_state *state)
18447ec681f3Smrg{
18457ec681f3Smrg   const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
18467ec681f3Smrg   struct pipe_draw_start_count_bias *draws = calloc(cmd->u.draw_multi_ext.draw_count,
18477ec681f3Smrg                                                     sizeof(*draws));
18487ec681f3Smrg
18497ec681f3Smrg   state->info.index_size = 0;
18507ec681f3Smrg   state->info.index.resource = NULL;
18517ec681f3Smrg   state->info.start_instance = cmd->u.draw_multi_ext.first_instance;
18527ec681f3Smrg   state->info.instance_count = cmd->u.draw_multi_ext.instance_count;
18537ec681f3Smrg   state->info.view_mask = subpass->view_mask;
18547ec681f3Smrg   if (cmd->u.draw_multi_ext.draw_count > 1)
18557ec681f3Smrg      state->info.increment_draw_id = true;
18567ec681f3Smrg
18577ec681f3Smrg   for(unsigned i = 0; i < cmd->u.draw_multi_ext.draw_count; i++) {
18587ec681f3Smrg      draws[i].start = cmd->u.draw_multi_ext.vertex_info[i].firstVertex;
18597ec681f3Smrg      draws[i].count = cmd->u.draw_multi_ext.vertex_info[i].vertexCount;
18607ec681f3Smrg      draws[i].index_bias = 0;
18617ec681f3Smrg   }
18627ec681f3Smrg
18637ec681f3Smrg   state->pctx->set_patch_vertices(state->pctx, state->patch_vertices);
18647ec681f3Smrg
18657ec681f3Smrg   if (cmd->u.draw_multi_indexed_ext.draw_count)
18667ec681f3Smrg      state->pctx->draw_vbo(state->pctx, &state->info, 0, NULL, draws, cmd->u.draw_multi_ext.draw_count);
18677ec681f3Smrg
18687ec681f3Smrg   free(draws);
18697ec681f3Smrg}
18707ec681f3Smrg
18717ec681f3Smrgstatic void set_viewport(unsigned first_viewport, unsigned viewport_count,
18727ec681f3Smrg                         const VkViewport* viewports,
18737ec681f3Smrg                         struct rendering_state *state)
18747ec681f3Smrg{
18757ec681f3Smrg   int i;
18767ec681f3Smrg   unsigned base = 0;
18777ec681f3Smrg   if (first_viewport == UINT32_MAX)
18787ec681f3Smrg      state->num_viewports = viewport_count;
18797ec681f3Smrg   else
18807ec681f3Smrg      base = first_viewport;
18817ec681f3Smrg
18827ec681f3Smrg   for (i = 0; i < viewport_count; i++) {
18837ec681f3Smrg      int idx = i + base;
18847ec681f3Smrg      const VkViewport *vp = &viewports[i];
18857ec681f3Smrg      get_viewport_xform(vp, state->viewports[idx].scale, state->viewports[idx].translate);
18867ec681f3Smrg   }
18877ec681f3Smrg   state->vp_dirty = true;
18887ec681f3Smrg}
18897ec681f3Smrg
18907ec681f3Smrgstatic void handle_set_viewport(struct vk_cmd_queue_entry *cmd,
18917ec681f3Smrg                                struct rendering_state *state)
18927ec681f3Smrg{
18937ec681f3Smrg   set_viewport(cmd->u.set_viewport.first_viewport,
18947ec681f3Smrg                cmd->u.set_viewport.viewport_count,
18957ec681f3Smrg                cmd->u.set_viewport.viewports,
18967ec681f3Smrg                state);
18977ec681f3Smrg}
18987ec681f3Smrg
18997ec681f3Smrgstatic void handle_set_viewport_with_count(struct vk_cmd_queue_entry *cmd,
19007ec681f3Smrg                                           struct rendering_state *state)
19017ec681f3Smrg{
19027ec681f3Smrg   set_viewport(UINT32_MAX,
19037ec681f3Smrg                cmd->u.set_viewport_with_count_ext.viewport_count,
19047ec681f3Smrg                cmd->u.set_viewport_with_count_ext.viewports,
19057ec681f3Smrg                state);
19067ec681f3Smrg}
19077ec681f3Smrg
19087ec681f3Smrgstatic void set_scissor(unsigned first_scissor,
19097ec681f3Smrg                        unsigned scissor_count,
19107ec681f3Smrg                        const VkRect2D *scissors,
19117ec681f3Smrg                        struct rendering_state *state)
19127ec681f3Smrg{
19137ec681f3Smrg   int i;
19147ec681f3Smrg   unsigned base = 0;
19157ec681f3Smrg   if (first_scissor == UINT32_MAX)
19167ec681f3Smrg      state->num_scissors = scissor_count;
19177ec681f3Smrg   else
19187ec681f3Smrg      base = first_scissor;
19197ec681f3Smrg
19207ec681f3Smrg   for (i = 0; i < scissor_count; i++) {
19217ec681f3Smrg      int idx = i + base;
19227ec681f3Smrg      const VkRect2D *ss = &scissors[i];
19237ec681f3Smrg      state->scissors[idx].minx = ss->offset.x;
19247ec681f3Smrg      state->scissors[idx].miny = ss->offset.y;
19257ec681f3Smrg      state->scissors[idx].maxx = ss->offset.x + ss->extent.width;
19267ec681f3Smrg      state->scissors[idx].maxy = ss->offset.y + ss->extent.height;
19277ec681f3Smrg   }
19287ec681f3Smrg   state->scissor_dirty = true;
19297ec681f3Smrg}
19307ec681f3Smrg
19317ec681f3Smrgstatic void handle_set_scissor(struct vk_cmd_queue_entry *cmd,
19327ec681f3Smrg                               struct rendering_state *state)
19337ec681f3Smrg{
19347ec681f3Smrg   set_scissor(cmd->u.set_scissor.first_scissor,
19357ec681f3Smrg               cmd->u.set_scissor.scissor_count,
19367ec681f3Smrg               cmd->u.set_scissor.scissors,
19377ec681f3Smrg               state);
19387ec681f3Smrg}
19397ec681f3Smrg
19407ec681f3Smrgstatic void handle_set_scissor_with_count(struct vk_cmd_queue_entry *cmd,
19417ec681f3Smrg                                          struct rendering_state *state)
19427ec681f3Smrg{
19437ec681f3Smrg   set_scissor(UINT32_MAX,
19447ec681f3Smrg               cmd->u.set_scissor_with_count_ext.scissor_count,
19457ec681f3Smrg               cmd->u.set_scissor_with_count_ext.scissors,
19467ec681f3Smrg               state);
19477ec681f3Smrg}
19487ec681f3Smrg
19497ec681f3Smrgstatic void handle_set_line_width(struct vk_cmd_queue_entry *cmd,
19507ec681f3Smrg                                  struct rendering_state *state)
19517ec681f3Smrg{
19527ec681f3Smrg   state->rs_state.line_width = cmd->u.set_line_width.line_width;
19537ec681f3Smrg   state->rs_dirty = true;
19547ec681f3Smrg}
19557ec681f3Smrg
19567ec681f3Smrgstatic void handle_set_depth_bias(struct vk_cmd_queue_entry *cmd,
19577ec681f3Smrg                                  struct rendering_state *state)
19587ec681f3Smrg{
19597ec681f3Smrg   state->depth_bias.offset_units = cmd->u.set_depth_bias.depth_bias_constant_factor;
19607ec681f3Smrg   state->depth_bias.offset_scale = cmd->u.set_depth_bias.depth_bias_slope_factor;
19617ec681f3Smrg   state->depth_bias.offset_clamp = cmd->u.set_depth_bias.depth_bias_clamp;
19627ec681f3Smrg   state->rs_dirty = true;
19637ec681f3Smrg}
19647ec681f3Smrg
19657ec681f3Smrgstatic void handle_set_blend_constants(struct vk_cmd_queue_entry *cmd,
19667ec681f3Smrg                                       struct rendering_state *state)
19677ec681f3Smrg{
19687ec681f3Smrg   memcpy(state->blend_color.color, cmd->u.set_blend_constants.blend_constants, 4 * sizeof(float));
19697ec681f3Smrg   state->blend_color_dirty = true;
19707ec681f3Smrg}
19717ec681f3Smrg
19727ec681f3Smrgstatic void handle_set_depth_bounds(struct vk_cmd_queue_entry *cmd,
19737ec681f3Smrg                                    struct rendering_state *state)
19747ec681f3Smrg{
19757ec681f3Smrg   state->dsa_dirty |= !DOUBLE_EQ(state->dsa_state.depth_bounds_min, cmd->u.set_depth_bounds.min_depth_bounds);
19767ec681f3Smrg   state->dsa_dirty |= !DOUBLE_EQ(state->dsa_state.depth_bounds_max, cmd->u.set_depth_bounds.max_depth_bounds);
19777ec681f3Smrg   state->dsa_state.depth_bounds_min = cmd->u.set_depth_bounds.min_depth_bounds;
19787ec681f3Smrg   state->dsa_state.depth_bounds_max = cmd->u.set_depth_bounds.max_depth_bounds;
19797ec681f3Smrg}
19807ec681f3Smrg
19817ec681f3Smrgstatic void handle_set_stencil_compare_mask(struct vk_cmd_queue_entry *cmd,
19827ec681f3Smrg                                            struct rendering_state *state)
19837ec681f3Smrg{
19847ec681f3Smrg   if (cmd->u.set_stencil_compare_mask.face_mask & VK_STENCIL_FACE_FRONT_BIT)
19857ec681f3Smrg      state->dsa_state.stencil[0].valuemask = cmd->u.set_stencil_compare_mask.compare_mask;
19867ec681f3Smrg   if (cmd->u.set_stencil_compare_mask.face_mask & VK_STENCIL_FACE_BACK_BIT)
19877ec681f3Smrg      state->dsa_state.stencil[1].valuemask = cmd->u.set_stencil_compare_mask.compare_mask;
19887ec681f3Smrg   state->dsa_dirty = true;
19897ec681f3Smrg}
19907ec681f3Smrg
19917ec681f3Smrgstatic void handle_set_stencil_write_mask(struct vk_cmd_queue_entry *cmd,
19927ec681f3Smrg                                          struct rendering_state *state)
19937ec681f3Smrg{
19947ec681f3Smrg   if (cmd->u.set_stencil_write_mask.face_mask & VK_STENCIL_FACE_FRONT_BIT)
19957ec681f3Smrg      state->dsa_state.stencil[0].writemask = cmd->u.set_stencil_write_mask.write_mask;
19967ec681f3Smrg   if (cmd->u.set_stencil_write_mask.face_mask & VK_STENCIL_FACE_BACK_BIT)
19977ec681f3Smrg      state->dsa_state.stencil[1].writemask = cmd->u.set_stencil_write_mask.write_mask;
19987ec681f3Smrg   state->dsa_dirty = true;
19997ec681f3Smrg}
20007ec681f3Smrg
20017ec681f3Smrgstatic void handle_set_stencil_reference(struct vk_cmd_queue_entry *cmd,
20027ec681f3Smrg                                         struct rendering_state *state)
20037ec681f3Smrg{
20047ec681f3Smrg   if (cmd->u.set_stencil_reference.face_mask & VK_STENCIL_FACE_FRONT_BIT)
20057ec681f3Smrg      state->stencil_ref.ref_value[0] = cmd->u.set_stencil_reference.reference;
20067ec681f3Smrg   if (cmd->u.set_stencil_reference.face_mask & VK_STENCIL_FACE_BACK_BIT)
20077ec681f3Smrg      state->stencil_ref.ref_value[1] = cmd->u.set_stencil_reference.reference;
20087ec681f3Smrg   state->stencil_ref_dirty = true;
20097ec681f3Smrg}
20107ec681f3Smrg
20117ec681f3Smrgstatic void
20127ec681f3Smrgcopy_depth_rect(ubyte * dst,
20137ec681f3Smrg                enum pipe_format dst_format,
20147ec681f3Smrg                unsigned dst_stride,
20157ec681f3Smrg                unsigned dst_x,
20167ec681f3Smrg                unsigned dst_y,
20177ec681f3Smrg                unsigned width,
20187ec681f3Smrg                unsigned height,
20197ec681f3Smrg                const ubyte * src,
20207ec681f3Smrg                enum pipe_format src_format,
20217ec681f3Smrg                int src_stride,
20227ec681f3Smrg                unsigned src_x,
20237ec681f3Smrg                unsigned src_y)
20247ec681f3Smrg{
20257ec681f3Smrg   int src_stride_pos = src_stride < 0 ? -src_stride : src_stride;
20267ec681f3Smrg   int src_blocksize = util_format_get_blocksize(src_format);
20277ec681f3Smrg   int src_blockwidth = util_format_get_blockwidth(src_format);
20287ec681f3Smrg   int src_blockheight = util_format_get_blockheight(src_format);
20297ec681f3Smrg   int dst_blocksize = util_format_get_blocksize(dst_format);
20307ec681f3Smrg   int dst_blockwidth = util_format_get_blockwidth(dst_format);
20317ec681f3Smrg   int dst_blockheight = util_format_get_blockheight(dst_format);
20327ec681f3Smrg
20337ec681f3Smrg   assert(src_blocksize > 0);
20347ec681f3Smrg   assert(src_blockwidth > 0);
20357ec681f3Smrg   assert(src_blockheight > 0);
20367ec681f3Smrg
20377ec681f3Smrg   dst_x /= dst_blockwidth;
20387ec681f3Smrg   dst_y /= dst_blockheight;
20397ec681f3Smrg   width = (width + src_blockwidth - 1)/src_blockwidth;
20407ec681f3Smrg   height = (height + src_blockheight - 1)/src_blockheight;
20417ec681f3Smrg   src_x /= src_blockwidth;
20427ec681f3Smrg   src_y /= src_blockheight;
20437ec681f3Smrg
20447ec681f3Smrg   dst += dst_x * dst_blocksize;
20457ec681f3Smrg   src += src_x * src_blocksize;
20467ec681f3Smrg   dst += dst_y * dst_stride;
20477ec681f3Smrg   src += src_y * src_stride_pos;
20487ec681f3Smrg
20497ec681f3Smrg   if (dst_format == PIPE_FORMAT_S8_UINT) {
20507ec681f3Smrg      if (src_format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) {
20517ec681f3Smrg         util_format_z32_float_s8x24_uint_unpack_s_8uint(dst, dst_stride,
20527ec681f3Smrg                                                         src, src_stride,
20537ec681f3Smrg                                                         width, height);
20547ec681f3Smrg      } else if (src_format == PIPE_FORMAT_Z24_UNORM_S8_UINT) {
20557ec681f3Smrg         util_format_z24_unorm_s8_uint_unpack_s_8uint(dst, dst_stride,
20567ec681f3Smrg                                                      src, src_stride,
20577ec681f3Smrg                                                      width, height);
20587ec681f3Smrg      } else {
20597ec681f3Smrg      }
20607ec681f3Smrg   } else if (dst_format == PIPE_FORMAT_Z24X8_UNORM) {
20617ec681f3Smrg      util_format_z24_unorm_s8_uint_unpack_z24(dst, dst_stride,
20627ec681f3Smrg                                               src, src_stride,
20637ec681f3Smrg                                               width, height);
20647ec681f3Smrg   } else if (dst_format == PIPE_FORMAT_Z32_FLOAT) {
20657ec681f3Smrg      if (src_format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) {
20667ec681f3Smrg         util_format_z32_float_s8x24_uint_unpack_z_float((float *)dst, dst_stride,
20677ec681f3Smrg                                                         src, src_stride,
20687ec681f3Smrg                                                         width, height);
20697ec681f3Smrg      }
20707ec681f3Smrg   } else if (dst_format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) {
20717ec681f3Smrg      if (src_format == PIPE_FORMAT_Z32_FLOAT)
20727ec681f3Smrg         util_format_z32_float_s8x24_uint_pack_z_float(dst, dst_stride,
20737ec681f3Smrg                                                       (float *)src, src_stride,
20747ec681f3Smrg                                                       width, height);
20757ec681f3Smrg      else if (src_format == PIPE_FORMAT_S8_UINT)
20767ec681f3Smrg         util_format_z32_float_s8x24_uint_pack_s_8uint(dst, dst_stride,
20777ec681f3Smrg                                                       src, src_stride,
20787ec681f3Smrg                                                       width, height);
20797ec681f3Smrg   } else if (dst_format == PIPE_FORMAT_Z24_UNORM_S8_UINT) {
20807ec681f3Smrg      if (src_format == PIPE_FORMAT_S8_UINT)
20817ec681f3Smrg         util_format_z24_unorm_s8_uint_pack_s_8uint(dst, dst_stride,
20827ec681f3Smrg                                                    src, src_stride,
20837ec681f3Smrg                                                    width, height);
20847ec681f3Smrg      if (src_format == PIPE_FORMAT_Z24X8_UNORM)
20857ec681f3Smrg         util_format_z24_unorm_s8_uint_pack_z24(dst, dst_stride,
20867ec681f3Smrg                                                src, src_stride,
20877ec681f3Smrg                                                width, height);
20887ec681f3Smrg   }
20897ec681f3Smrg}
20907ec681f3Smrg
20917ec681f3Smrgstatic void
20927ec681f3Smrgcopy_depth_box(ubyte *dst,
20937ec681f3Smrg               enum pipe_format dst_format,
20947ec681f3Smrg               unsigned dst_stride, unsigned dst_slice_stride,
20957ec681f3Smrg               unsigned dst_x, unsigned dst_y, unsigned dst_z,
20967ec681f3Smrg               unsigned width, unsigned height, unsigned depth,
20977ec681f3Smrg               const ubyte * src,
20987ec681f3Smrg               enum pipe_format src_format,
20997ec681f3Smrg               int src_stride, unsigned src_slice_stride,
21007ec681f3Smrg               unsigned src_x, unsigned src_y, unsigned src_z)
21017ec681f3Smrg{
21027ec681f3Smrg   unsigned z;
21037ec681f3Smrg   dst += dst_z * dst_slice_stride;
21047ec681f3Smrg   src += src_z * src_slice_stride;
21057ec681f3Smrg   for (z = 0; z < depth; ++z) {
21067ec681f3Smrg      copy_depth_rect(dst,
21077ec681f3Smrg                      dst_format,
21087ec681f3Smrg                      dst_stride,
21097ec681f3Smrg                      dst_x, dst_y,
21107ec681f3Smrg                      width, height,
21117ec681f3Smrg                      src,
21127ec681f3Smrg                      src_format,
21137ec681f3Smrg                      src_stride,
21147ec681f3Smrg                      src_x, src_y);
21157ec681f3Smrg
21167ec681f3Smrg      dst += dst_slice_stride;
21177ec681f3Smrg      src += src_slice_stride;
21187ec681f3Smrg   }
21197ec681f3Smrg}
21207ec681f3Smrg
21217ec681f3Smrgstatic void handle_copy_image_to_buffer2_khr(struct vk_cmd_queue_entry *cmd,
21227ec681f3Smrg                                             struct rendering_state *state)
21237ec681f3Smrg{
21247ec681f3Smrg   int i;
21257ec681f3Smrg   struct VkCopyImageToBufferInfo2KHR *copycmd = cmd->u.copy_image_to_buffer2_khr.copy_image_to_buffer_info;
21267ec681f3Smrg   LVP_FROM_HANDLE(lvp_image, src_image, copycmd->srcImage);
21277ec681f3Smrg   struct pipe_box box, dbox;
21287ec681f3Smrg   struct pipe_transfer *src_t, *dst_t;
21297ec681f3Smrg   ubyte *src_data, *dst_data;
21307ec681f3Smrg
21317ec681f3Smrg   state->pctx->flush(state->pctx, NULL, 0);
21327ec681f3Smrg
21337ec681f3Smrg   for (i = 0; i < copycmd->regionCount; i++) {
21347ec681f3Smrg
21357ec681f3Smrg      box.x = copycmd->pRegions[i].imageOffset.x;
21367ec681f3Smrg      box.y = copycmd->pRegions[i].imageOffset.y;
21377ec681f3Smrg      box.z = src_image->vk.image_type == VK_IMAGE_TYPE_3D ? copycmd->pRegions[i].imageOffset.z : copycmd->pRegions[i].imageSubresource.baseArrayLayer;
21387ec681f3Smrg      box.width = copycmd->pRegions[i].imageExtent.width;
21397ec681f3Smrg      box.height = copycmd->pRegions[i].imageExtent.height;
21407ec681f3Smrg      box.depth = src_image->vk.image_type == VK_IMAGE_TYPE_3D ? copycmd->pRegions[i].imageExtent.depth : copycmd->pRegions[i].imageSubresource.layerCount;
21417ec681f3Smrg
21427ec681f3Smrg      src_data = state->pctx->texture_map(state->pctx,
21437ec681f3Smrg                                           src_image->bo,
21447ec681f3Smrg                                           copycmd->pRegions[i].imageSubresource.mipLevel,
21457ec681f3Smrg                                           PIPE_MAP_READ,
21467ec681f3Smrg                                           &box,
21477ec681f3Smrg                                           &src_t);
21487ec681f3Smrg
21497ec681f3Smrg      dbox.x = copycmd->pRegions[i].bufferOffset;
21507ec681f3Smrg      dbox.y = 0;
21517ec681f3Smrg      dbox.z = 0;
21527ec681f3Smrg      dbox.width = lvp_buffer_from_handle(copycmd->dstBuffer)->bo->width0;
21537ec681f3Smrg      dbox.height = 1;
21547ec681f3Smrg      dbox.depth = 1;
21557ec681f3Smrg      dst_data = state->pctx->buffer_map(state->pctx,
21567ec681f3Smrg                                           lvp_buffer_from_handle(copycmd->dstBuffer)->bo,
21577ec681f3Smrg                                           0,
21587ec681f3Smrg                                           PIPE_MAP_WRITE,
21597ec681f3Smrg                                           &dbox,
21607ec681f3Smrg                                           &dst_t);
21617ec681f3Smrg
21627ec681f3Smrg      enum pipe_format src_format = src_image->bo->format;
21637ec681f3Smrg      enum pipe_format dst_format = src_format;
21647ec681f3Smrg      if (util_format_is_depth_or_stencil(src_format)) {
21657ec681f3Smrg         if (copycmd->pRegions[i].imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT) {
21667ec681f3Smrg            dst_format = util_format_get_depth_only(src_format);
21677ec681f3Smrg         } else if (copycmd->pRegions[i].imageSubresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) {
21687ec681f3Smrg            dst_format = PIPE_FORMAT_S8_UINT;
21697ec681f3Smrg         }
21707ec681f3Smrg      }
21717ec681f3Smrg
21727ec681f3Smrg      unsigned buffer_row_len = util_format_get_stride(dst_format, copycmd->pRegions[i].bufferRowLength);
21737ec681f3Smrg      if (buffer_row_len == 0)
21747ec681f3Smrg         buffer_row_len = util_format_get_stride(dst_format, copycmd->pRegions[i].imageExtent.width);
21757ec681f3Smrg      unsigned buffer_image_height = copycmd->pRegions[i].bufferImageHeight;
21767ec681f3Smrg      if (buffer_image_height == 0)
21777ec681f3Smrg         buffer_image_height = copycmd->pRegions[i].imageExtent.height;
21787ec681f3Smrg
21797ec681f3Smrg      unsigned img_stride = util_format_get_2d_size(dst_format, buffer_row_len, buffer_image_height);
21807ec681f3Smrg      if (src_format != dst_format) {
21817ec681f3Smrg         copy_depth_box(dst_data, dst_format,
21827ec681f3Smrg                        buffer_row_len, img_stride,
21837ec681f3Smrg                        0, 0, 0,
21847ec681f3Smrg                        copycmd->pRegions[i].imageExtent.width,
21857ec681f3Smrg                        copycmd->pRegions[i].imageExtent.height,
21867ec681f3Smrg                        box.depth,
21877ec681f3Smrg                        src_data, src_format, src_t->stride, src_t->layer_stride, 0, 0, 0);
21887ec681f3Smrg      } else {
21897ec681f3Smrg         util_copy_box((ubyte *)dst_data, src_format,
21907ec681f3Smrg                       buffer_row_len, img_stride,
21917ec681f3Smrg                       0, 0, 0,
21927ec681f3Smrg                       copycmd->pRegions[i].imageExtent.width,
21937ec681f3Smrg                       copycmd->pRegions[i].imageExtent.height,
21947ec681f3Smrg                       box.depth,
21957ec681f3Smrg                       src_data, src_t->stride, src_t->layer_stride, 0, 0, 0);
21967ec681f3Smrg      }
21977ec681f3Smrg      state->pctx->texture_unmap(state->pctx, src_t);
21987ec681f3Smrg      state->pctx->buffer_unmap(state->pctx, dst_t);
21997ec681f3Smrg   }
22007ec681f3Smrg}
22017ec681f3Smrg
22027ec681f3Smrgstatic void handle_copy_buffer_to_image(struct vk_cmd_queue_entry *cmd,
22037ec681f3Smrg                                        struct rendering_state *state)
22047ec681f3Smrg{
22057ec681f3Smrg   int i;
22067ec681f3Smrg   struct VkCopyBufferToImageInfo2KHR *copycmd = cmd->u.copy_buffer_to_image2_khr.copy_buffer_to_image_info;
22077ec681f3Smrg   LVP_FROM_HANDLE(lvp_image, dst_image, copycmd->dstImage);
22087ec681f3Smrg   struct pipe_box box, sbox;
22097ec681f3Smrg   struct pipe_transfer *src_t, *dst_t;
22107ec681f3Smrg   void *src_data, *dst_data;
22117ec681f3Smrg
22127ec681f3Smrg   state->pctx->flush(state->pctx, NULL, 0);
22137ec681f3Smrg
22147ec681f3Smrg   for (i = 0; i < copycmd->regionCount; i++) {
22157ec681f3Smrg
22167ec681f3Smrg      sbox.x = copycmd->pRegions[i].bufferOffset;
22177ec681f3Smrg      sbox.y = 0;
22187ec681f3Smrg      sbox.z = 0;
22197ec681f3Smrg      sbox.width = lvp_buffer_from_handle(copycmd->srcBuffer)->bo->width0;
22207ec681f3Smrg      sbox.height = 1;
22217ec681f3Smrg      sbox.depth = 1;
22227ec681f3Smrg      src_data = state->pctx->buffer_map(state->pctx,
22237ec681f3Smrg                                           lvp_buffer_from_handle(copycmd->srcBuffer)->bo,
22247ec681f3Smrg                                           0,
22257ec681f3Smrg                                           PIPE_MAP_READ,
22267ec681f3Smrg                                           &sbox,
22277ec681f3Smrg                                           &src_t);
22287ec681f3Smrg
22297ec681f3Smrg
22307ec681f3Smrg      box.x = copycmd->pRegions[i].imageOffset.x;
22317ec681f3Smrg      box.y = copycmd->pRegions[i].imageOffset.y;
22327ec681f3Smrg      box.z = dst_image->vk.image_type == VK_IMAGE_TYPE_3D ? copycmd->pRegions[i].imageOffset.z : copycmd->pRegions[i].imageSubresource.baseArrayLayer;
22337ec681f3Smrg      box.width = copycmd->pRegions[i].imageExtent.width;
22347ec681f3Smrg      box.height = copycmd->pRegions[i].imageExtent.height;
22357ec681f3Smrg      box.depth = dst_image->vk.image_type == VK_IMAGE_TYPE_3D ? copycmd->pRegions[i].imageExtent.depth : copycmd->pRegions[i].imageSubresource.layerCount;
22367ec681f3Smrg
22377ec681f3Smrg      dst_data = state->pctx->texture_map(state->pctx,
22387ec681f3Smrg                                           dst_image->bo,
22397ec681f3Smrg                                           copycmd->pRegions[i].imageSubresource.mipLevel,
22407ec681f3Smrg                                           PIPE_MAP_WRITE,
22417ec681f3Smrg                                           &box,
22427ec681f3Smrg                                           &dst_t);
22437ec681f3Smrg
22447ec681f3Smrg      enum pipe_format dst_format = dst_image->bo->format;
22457ec681f3Smrg      enum pipe_format src_format = dst_format;
22467ec681f3Smrg      if (util_format_is_depth_or_stencil(dst_format)) {
22477ec681f3Smrg         if (copycmd->pRegions[i].imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT) {
22487ec681f3Smrg            src_format = util_format_get_depth_only(dst_image->bo->format);
22497ec681f3Smrg         } else if (copycmd->pRegions[i].imageSubresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) {
22507ec681f3Smrg            src_format = PIPE_FORMAT_S8_UINT;
22517ec681f3Smrg         }
22527ec681f3Smrg      }
22537ec681f3Smrg
22547ec681f3Smrg      unsigned buffer_row_len = util_format_get_stride(src_format, copycmd->pRegions[i].bufferRowLength);
22557ec681f3Smrg      if (buffer_row_len == 0)
22567ec681f3Smrg         buffer_row_len = util_format_get_stride(src_format, copycmd->pRegions[i].imageExtent.width);
22577ec681f3Smrg      unsigned buffer_image_height = copycmd->pRegions[i].bufferImageHeight;
22587ec681f3Smrg      if (buffer_image_height == 0)
22597ec681f3Smrg         buffer_image_height = copycmd->pRegions[i].imageExtent.height;
22607ec681f3Smrg
22617ec681f3Smrg      unsigned img_stride = util_format_get_2d_size(src_format, buffer_row_len, buffer_image_height);
22627ec681f3Smrg      if (src_format != dst_format) {
22637ec681f3Smrg         copy_depth_box(dst_data, dst_format,
22647ec681f3Smrg                        dst_t->stride, dst_t->layer_stride,
22657ec681f3Smrg                        0, 0, 0,
22667ec681f3Smrg                        copycmd->pRegions[i].imageExtent.width,
22677ec681f3Smrg                        copycmd->pRegions[i].imageExtent.height,
22687ec681f3Smrg                        box.depth,
22697ec681f3Smrg                        src_data, src_format,
22707ec681f3Smrg                        buffer_row_len, img_stride, 0, 0, 0);
22717ec681f3Smrg      } else {
22727ec681f3Smrg         util_copy_box(dst_data, dst_format,
22737ec681f3Smrg                       dst_t->stride, dst_t->layer_stride,
22747ec681f3Smrg                       0, 0, 0,
22757ec681f3Smrg                       copycmd->pRegions[i].imageExtent.width,
22767ec681f3Smrg                       copycmd->pRegions[i].imageExtent.height,
22777ec681f3Smrg                       box.depth,
22787ec681f3Smrg                       src_data,
22797ec681f3Smrg                       buffer_row_len, img_stride, 0, 0, 0);
22807ec681f3Smrg      }
22817ec681f3Smrg      state->pctx->buffer_unmap(state->pctx, src_t);
22827ec681f3Smrg      state->pctx->texture_unmap(state->pctx, dst_t);
22837ec681f3Smrg   }
22847ec681f3Smrg}
22857ec681f3Smrg
22867ec681f3Smrgstatic void handle_copy_image(struct vk_cmd_queue_entry *cmd,
22877ec681f3Smrg                              struct rendering_state *state)
22887ec681f3Smrg{
22897ec681f3Smrg   int i;
22907ec681f3Smrg   struct VkCopyImageInfo2KHR *copycmd = cmd->u.copy_image2_khr.copy_image_info;
22917ec681f3Smrg   LVP_FROM_HANDLE(lvp_image, src_image, copycmd->srcImage);
22927ec681f3Smrg   LVP_FROM_HANDLE(lvp_image, dst_image, copycmd->dstImage);
22937ec681f3Smrg
22947ec681f3Smrg   state->pctx->flush(state->pctx, NULL, 0);
22957ec681f3Smrg
22967ec681f3Smrg   for (i = 0; i < copycmd->regionCount; i++) {
22977ec681f3Smrg      struct pipe_box src_box;
22987ec681f3Smrg      src_box.x = copycmd->pRegions[i].srcOffset.x;
22997ec681f3Smrg      src_box.y = copycmd->pRegions[i].srcOffset.y;
23007ec681f3Smrg      src_box.width = copycmd->pRegions[i].extent.width;
23017ec681f3Smrg      src_box.height = copycmd->pRegions[i].extent.height;
23027ec681f3Smrg      if (src_image->bo->target == PIPE_TEXTURE_3D) {
23037ec681f3Smrg         src_box.depth = copycmd->pRegions[i].extent.depth;
23047ec681f3Smrg         src_box.z = copycmd->pRegions[i].srcOffset.z;
23057ec681f3Smrg      } else {
23067ec681f3Smrg         src_box.depth = copycmd->pRegions[i].srcSubresource.layerCount;
23077ec681f3Smrg         src_box.z = copycmd->pRegions[i].srcSubresource.baseArrayLayer;
23087ec681f3Smrg      }
23097ec681f3Smrg
23107ec681f3Smrg      unsigned dstz = dst_image->bo->target == PIPE_TEXTURE_3D ?
23117ec681f3Smrg                      copycmd->pRegions[i].dstOffset.z :
23127ec681f3Smrg                      copycmd->pRegions[i].dstSubresource.baseArrayLayer;
23137ec681f3Smrg      state->pctx->resource_copy_region(state->pctx, dst_image->bo,
23147ec681f3Smrg                                        copycmd->pRegions[i].dstSubresource.mipLevel,
23157ec681f3Smrg                                        copycmd->pRegions[i].dstOffset.x,
23167ec681f3Smrg                                        copycmd->pRegions[i].dstOffset.y,
23177ec681f3Smrg                                        dstz,
23187ec681f3Smrg                                        src_image->bo,
23197ec681f3Smrg                                        copycmd->pRegions[i].srcSubresource.mipLevel,
23207ec681f3Smrg                                        &src_box);
23217ec681f3Smrg   }
23227ec681f3Smrg}
23237ec681f3Smrg
23247ec681f3Smrgstatic void handle_copy_buffer(struct vk_cmd_queue_entry *cmd,
23257ec681f3Smrg                               struct rendering_state *state)
23267ec681f3Smrg{
23277ec681f3Smrg   int i;
23287ec681f3Smrg   struct VkCopyBufferInfo2KHR *copycmd = cmd->u.copy_buffer2_khr.copy_buffer_info;
23297ec681f3Smrg
23307ec681f3Smrg   for (i = 0; i < copycmd->regionCount; i++) {
23317ec681f3Smrg      struct pipe_box box = { 0 };
23327ec681f3Smrg      u_box_1d(copycmd->pRegions[i].srcOffset, copycmd->pRegions[i].size, &box);
23337ec681f3Smrg      state->pctx->resource_copy_region(state->pctx, lvp_buffer_from_handle(copycmd->dstBuffer)->bo, 0,
23347ec681f3Smrg                                        copycmd->pRegions[i].dstOffset, 0, 0,
23357ec681f3Smrg                                        lvp_buffer_from_handle(copycmd->srcBuffer)->bo, 0, &box);
23367ec681f3Smrg   }
23377ec681f3Smrg}
23387ec681f3Smrg
23397ec681f3Smrgstatic void handle_blit_image(struct vk_cmd_queue_entry *cmd,
23407ec681f3Smrg                              struct rendering_state *state)
23417ec681f3Smrg{
23427ec681f3Smrg   int i;
23437ec681f3Smrg   struct VkBlitImageInfo2KHR *blitcmd = cmd->u.blit_image2_khr.blit_image_info;
23447ec681f3Smrg   LVP_FROM_HANDLE(lvp_image, src_image, blitcmd->srcImage);
23457ec681f3Smrg   LVP_FROM_HANDLE(lvp_image, dst_image, blitcmd->dstImage);
23467ec681f3Smrg   struct pipe_blit_info info;
23477ec681f3Smrg
23487ec681f3Smrg   memset(&info, 0, sizeof(info));
23497ec681f3Smrg
23507ec681f3Smrg   state->pctx->flush(state->pctx, NULL, 0);
23517ec681f3Smrg   info.src.resource = src_image->bo;
23527ec681f3Smrg   info.dst.resource = dst_image->bo;
23537ec681f3Smrg   info.src.format = src_image->bo->format;
23547ec681f3Smrg   info.dst.format = dst_image->bo->format;
23557ec681f3Smrg   info.mask = util_format_is_depth_or_stencil(info.src.format) ? PIPE_MASK_ZS : PIPE_MASK_RGBA;
23567ec681f3Smrg   info.filter = blitcmd->filter == VK_FILTER_NEAREST ? PIPE_TEX_FILTER_NEAREST : PIPE_TEX_FILTER_LINEAR;
23577ec681f3Smrg   for (i = 0; i < blitcmd->regionCount; i++) {
23587ec681f3Smrg      int srcX0, srcX1, srcY0, srcY1, srcZ0, srcZ1;
23597ec681f3Smrg      unsigned dstX0, dstX1, dstY0, dstY1, dstZ0, dstZ1;
23607ec681f3Smrg
23617ec681f3Smrg      srcX0 = blitcmd->pRegions[i].srcOffsets[0].x;
23627ec681f3Smrg      srcX1 = blitcmd->pRegions[i].srcOffsets[1].x;
23637ec681f3Smrg      srcY0 = blitcmd->pRegions[i].srcOffsets[0].y;
23647ec681f3Smrg      srcY1 = blitcmd->pRegions[i].srcOffsets[1].y;
23657ec681f3Smrg      srcZ0 = blitcmd->pRegions[i].srcOffsets[0].z;
23667ec681f3Smrg      srcZ1 = blitcmd->pRegions[i].srcOffsets[1].z;
23677ec681f3Smrg
23687ec681f3Smrg      dstX0 = blitcmd->pRegions[i].dstOffsets[0].x;
23697ec681f3Smrg      dstX1 = blitcmd->pRegions[i].dstOffsets[1].x;
23707ec681f3Smrg      dstY0 = blitcmd->pRegions[i].dstOffsets[0].y;
23717ec681f3Smrg      dstY1 = blitcmd->pRegions[i].dstOffsets[1].y;
23727ec681f3Smrg      dstZ0 = blitcmd->pRegions[i].dstOffsets[0].z;
23737ec681f3Smrg      dstZ1 = blitcmd->pRegions[i].dstOffsets[1].z;
23747ec681f3Smrg
23757ec681f3Smrg      if (dstX0 < dstX1) {
23767ec681f3Smrg         info.dst.box.x = dstX0;
23777ec681f3Smrg         info.src.box.x = srcX0;
23787ec681f3Smrg         info.dst.box.width = dstX1 - dstX0;
23797ec681f3Smrg         info.src.box.width = srcX1 - srcX0;
23807ec681f3Smrg      } else {
23817ec681f3Smrg         info.dst.box.x = dstX1;
23827ec681f3Smrg         info.src.box.x = srcX1;
23837ec681f3Smrg         info.dst.box.width = dstX0 - dstX1;
23847ec681f3Smrg         info.src.box.width = srcX0 - srcX1;
23857ec681f3Smrg      }
23867ec681f3Smrg
23877ec681f3Smrg      if (dstY0 < dstY1) {
23887ec681f3Smrg         info.dst.box.y = dstY0;
23897ec681f3Smrg         info.src.box.y = srcY0;
23907ec681f3Smrg         info.dst.box.height = dstY1 - dstY0;
23917ec681f3Smrg         info.src.box.height = srcY1 - srcY0;
23927ec681f3Smrg      } else {
23937ec681f3Smrg         info.dst.box.y = dstY1;
23947ec681f3Smrg         info.src.box.y = srcY1;
23957ec681f3Smrg         info.dst.box.height = dstY0 - dstY1;
23967ec681f3Smrg         info.src.box.height = srcY0 - srcY1;
23977ec681f3Smrg      }
23987ec681f3Smrg
23997ec681f3Smrg      assert_subresource_layers(info.src.resource, &blitcmd->pRegions[i].srcSubresource, blitcmd->pRegions[i].srcOffsets);
24007ec681f3Smrg      assert_subresource_layers(info.dst.resource, &blitcmd->pRegions[i].dstSubresource, blitcmd->pRegions[i].dstOffsets);
24017ec681f3Smrg      if (src_image->bo->target == PIPE_TEXTURE_3D) {
24027ec681f3Smrg         if (dstZ0 < dstZ1) {
24037ec681f3Smrg            info.dst.box.z = dstZ0;
24047ec681f3Smrg            info.src.box.z = srcZ0;
24057ec681f3Smrg            info.dst.box.depth = dstZ1 - dstZ0;
24067ec681f3Smrg            info.src.box.depth = srcZ1 - srcZ0;
24077ec681f3Smrg         } else {
24087ec681f3Smrg            info.dst.box.z = dstZ1;
24097ec681f3Smrg            info.src.box.z = srcZ1;
24107ec681f3Smrg            info.dst.box.depth = dstZ0 - dstZ1;
24117ec681f3Smrg            info.src.box.depth = srcZ0 - srcZ1;
24127ec681f3Smrg         }
24137ec681f3Smrg      } else {
24147ec681f3Smrg         info.src.box.z = blitcmd->pRegions[i].srcSubresource.baseArrayLayer;
24157ec681f3Smrg         info.dst.box.z = blitcmd->pRegions[i].dstSubresource.baseArrayLayer;
24167ec681f3Smrg         info.src.box.depth = blitcmd->pRegions[i].srcSubresource.layerCount;
24177ec681f3Smrg         info.dst.box.depth = blitcmd->pRegions[i].dstSubresource.layerCount;
24187ec681f3Smrg      }
24197ec681f3Smrg
24207ec681f3Smrg      info.src.level = blitcmd->pRegions[i].srcSubresource.mipLevel;
24217ec681f3Smrg      info.dst.level = blitcmd->pRegions[i].dstSubresource.mipLevel;
24227ec681f3Smrg      state->pctx->blit(state->pctx, &info);
24237ec681f3Smrg   }
24247ec681f3Smrg}
24257ec681f3Smrg
24267ec681f3Smrgstatic void handle_fill_buffer(struct vk_cmd_queue_entry *cmd,
24277ec681f3Smrg                               struct rendering_state *state)
24287ec681f3Smrg{
24297ec681f3Smrg   struct vk_cmd_fill_buffer *fillcmd = &cmd->u.fill_buffer;
24307ec681f3Smrg   uint32_t size = fillcmd->size;
24317ec681f3Smrg
24327ec681f3Smrg   if (fillcmd->size == VK_WHOLE_SIZE) {
24337ec681f3Smrg      size = lvp_buffer_from_handle(fillcmd->dst_buffer)->bo->width0 - fillcmd->dst_offset;
24347ec681f3Smrg      size = ROUND_DOWN_TO(size, 4);
24357ec681f3Smrg   }
24367ec681f3Smrg
24377ec681f3Smrg   state->pctx->clear_buffer(state->pctx,
24387ec681f3Smrg                             lvp_buffer_from_handle(fillcmd->dst_buffer)->bo,
24397ec681f3Smrg                             fillcmd->dst_offset,
24407ec681f3Smrg                             size,
24417ec681f3Smrg                             &fillcmd->data,
24427ec681f3Smrg                             4);
24437ec681f3Smrg}
24447ec681f3Smrg
24457ec681f3Smrgstatic void handle_update_buffer(struct vk_cmd_queue_entry *cmd,
24467ec681f3Smrg                                 struct rendering_state *state)
24477ec681f3Smrg{
24487ec681f3Smrg   struct vk_cmd_update_buffer *updcmd = &cmd->u.update_buffer;
24497ec681f3Smrg   uint32_t *dst;
24507ec681f3Smrg   struct pipe_transfer *dst_t;
24517ec681f3Smrg   struct pipe_box box;
24527ec681f3Smrg
24537ec681f3Smrg   u_box_1d(updcmd->dst_offset, updcmd->data_size, &box);
24547ec681f3Smrg   dst = state->pctx->buffer_map(state->pctx,
24557ec681f3Smrg                                   lvp_buffer_from_handle(updcmd->dst_buffer)->bo,
24567ec681f3Smrg                                   0,
24577ec681f3Smrg                                   PIPE_MAP_WRITE,
24587ec681f3Smrg                                   &box,
24597ec681f3Smrg                                   &dst_t);
24607ec681f3Smrg
24617ec681f3Smrg   memcpy(dst, updcmd->data, updcmd->data_size);
24627ec681f3Smrg   state->pctx->buffer_unmap(state->pctx, dst_t);
24637ec681f3Smrg}
24647ec681f3Smrg
24657ec681f3Smrgstatic void handle_draw_indexed(struct vk_cmd_queue_entry *cmd,
24667ec681f3Smrg                                struct rendering_state *state)
24677ec681f3Smrg{
24687ec681f3Smrg   const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
24697ec681f3Smrg   struct pipe_draw_start_count_bias draw = {0};
24707ec681f3Smrg
24717ec681f3Smrg   state->info.index_bounds_valid = false;
24727ec681f3Smrg   state->info.min_index = 0;
24737ec681f3Smrg   state->info.max_index = ~0;
24747ec681f3Smrg   state->info.index_size = state->index_size;
24757ec681f3Smrg   state->info.index.resource = state->index_buffer;
24767ec681f3Smrg   state->info.start_instance = cmd->u.draw_indexed.first_instance;
24777ec681f3Smrg   state->info.instance_count = cmd->u.draw_indexed.instance_count;
24787ec681f3Smrg   state->info.view_mask = subpass->view_mask;
24797ec681f3Smrg
24807ec681f3Smrg   if (state->info.primitive_restart)
24817ec681f3Smrg      state->info.restart_index = util_prim_restart_index_from_size(state->info.index_size);
24827ec681f3Smrg
24837ec681f3Smrg   draw.count = cmd->u.draw_indexed.index_count;
24847ec681f3Smrg   draw.index_bias = cmd->u.draw_indexed.vertex_offset;
24857ec681f3Smrg   /* TODO: avoid calculating multiple times if cmdbuf is submitted again */
24867ec681f3Smrg   draw.start = (state->index_offset / state->index_size) + cmd->u.draw_indexed.first_index;
24877ec681f3Smrg
24887ec681f3Smrg   state->info.index_bias_varies = !cmd->u.draw_indexed.vertex_offset;
24897ec681f3Smrg   state->pctx->set_patch_vertices(state->pctx, state->patch_vertices);
24907ec681f3Smrg   state->pctx->draw_vbo(state->pctx, &state->info, 0, NULL, &draw, 1);
24917ec681f3Smrg}
24927ec681f3Smrg
24937ec681f3Smrgstatic void handle_draw_multi_indexed(struct vk_cmd_queue_entry *cmd,
24947ec681f3Smrg                                      struct rendering_state *state)
24957ec681f3Smrg{
24967ec681f3Smrg   const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
24977ec681f3Smrg   struct pipe_draw_start_count_bias *draws = calloc(cmd->u.draw_multi_indexed_ext.draw_count,
24987ec681f3Smrg                                                     sizeof(*draws));
24997ec681f3Smrg
25007ec681f3Smrg   state->info.index_bounds_valid = false;
25017ec681f3Smrg   state->info.min_index = 0;
25027ec681f3Smrg   state->info.max_index = ~0;
25037ec681f3Smrg   state->info.index_size = state->index_size;
25047ec681f3Smrg   state->info.index.resource = state->index_buffer;
25057ec681f3Smrg   state->info.start_instance = cmd->u.draw_multi_indexed_ext.first_instance;
25067ec681f3Smrg   state->info.instance_count = cmd->u.draw_multi_indexed_ext.instance_count;
25077ec681f3Smrg   state->info.view_mask = subpass->view_mask;
25087ec681f3Smrg   if (cmd->u.draw_multi_indexed_ext.draw_count > 1)
25097ec681f3Smrg      state->info.increment_draw_id = true;
25107ec681f3Smrg
25117ec681f3Smrg   if (state->info.primitive_restart)
25127ec681f3Smrg      state->info.restart_index = util_prim_restart_index_from_size(state->info.index_size);
25137ec681f3Smrg
25147ec681f3Smrg   unsigned size = cmd->u.draw_multi_indexed_ext.draw_count * sizeof(struct pipe_draw_start_count_bias);
25157ec681f3Smrg   memcpy(draws, cmd->u.draw_multi_indexed_ext.index_info, size);
25167ec681f3Smrg
25177ec681f3Smrg   /* only the first member is read if index_bias_varies is true */
25187ec681f3Smrg   if (cmd->u.draw_multi_indexed_ext.draw_count &&
25197ec681f3Smrg       cmd->u.draw_multi_indexed_ext.vertex_offset)
25207ec681f3Smrg      draws[0].index_bias = *cmd->u.draw_multi_indexed_ext.vertex_offset;
25217ec681f3Smrg
25227ec681f3Smrg   /* TODO: avoid calculating multiple times if cmdbuf is submitted again */
25237ec681f3Smrg   for (unsigned i = 0; i < cmd->u.draw_multi_indexed_ext.draw_count; i++)
25247ec681f3Smrg      draws[i].start = (state->index_offset / state->index_size) + draws[i].start;
25257ec681f3Smrg
25267ec681f3Smrg   state->info.index_bias_varies = !cmd->u.draw_multi_indexed_ext.vertex_offset;
25277ec681f3Smrg   state->pctx->set_patch_vertices(state->pctx, state->patch_vertices);
25287ec681f3Smrg
25297ec681f3Smrg   if (cmd->u.draw_multi_indexed_ext.draw_count)
25307ec681f3Smrg      state->pctx->draw_vbo(state->pctx, &state->info, 0, NULL, draws, cmd->u.draw_multi_indexed_ext.draw_count);
25317ec681f3Smrg
25327ec681f3Smrg   free(draws);
25337ec681f3Smrg}
25347ec681f3Smrg
25357ec681f3Smrgstatic void handle_draw_indirect(struct vk_cmd_queue_entry *cmd,
25367ec681f3Smrg                                 struct rendering_state *state, bool indexed)
25377ec681f3Smrg{
25387ec681f3Smrg   const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
25397ec681f3Smrg   struct pipe_draw_start_count_bias draw = {0};
25407ec681f3Smrg   if (indexed) {
25417ec681f3Smrg      state->info.index_bounds_valid = false;
25427ec681f3Smrg      state->info.index_size = state->index_size;
25437ec681f3Smrg      state->info.index.resource = state->index_buffer;
25447ec681f3Smrg      state->info.max_index = ~0;
25457ec681f3Smrg      if (state->info.primitive_restart)
25467ec681f3Smrg         state->info.restart_index = util_prim_restart_index_from_size(state->info.index_size);
25477ec681f3Smrg   } else
25487ec681f3Smrg      state->info.index_size = 0;
25497ec681f3Smrg   state->indirect_info.offset = cmd->u.draw_indirect.offset;
25507ec681f3Smrg   state->indirect_info.stride = cmd->u.draw_indirect.stride;
25517ec681f3Smrg   state->indirect_info.draw_count = cmd->u.draw_indirect.draw_count;
25527ec681f3Smrg   state->indirect_info.buffer = lvp_buffer_from_handle(cmd->u.draw_indirect.buffer)->bo;
25537ec681f3Smrg   state->info.view_mask = subpass->view_mask;
25547ec681f3Smrg
25557ec681f3Smrg   state->pctx->set_patch_vertices(state->pctx, state->patch_vertices);
25567ec681f3Smrg   state->pctx->draw_vbo(state->pctx, &state->info, 0, &state->indirect_info, &draw, 1);
25577ec681f3Smrg}
25587ec681f3Smrg
25597ec681f3Smrgstatic void handle_index_buffer(struct vk_cmd_queue_entry *cmd,
25607ec681f3Smrg                                struct rendering_state *state)
25617ec681f3Smrg{
25627ec681f3Smrg   struct vk_cmd_bind_index_buffer *ib = &cmd->u.bind_index_buffer;
25637ec681f3Smrg   switch (ib->index_type) {
25647ec681f3Smrg   case VK_INDEX_TYPE_UINT8_EXT:
25657ec681f3Smrg      state->index_size = 1;
25667ec681f3Smrg      break;
25677ec681f3Smrg   case VK_INDEX_TYPE_UINT16:
25687ec681f3Smrg      state->index_size = 2;
25697ec681f3Smrg      break;
25707ec681f3Smrg   case VK_INDEX_TYPE_UINT32:
25717ec681f3Smrg      state->index_size = 4;
25727ec681f3Smrg      break;
25737ec681f3Smrg   default:
25747ec681f3Smrg      break;
25757ec681f3Smrg   }
25767ec681f3Smrg   state->index_offset = ib->offset;
25777ec681f3Smrg   if (ib->buffer)
25787ec681f3Smrg      state->index_buffer = lvp_buffer_from_handle(ib->buffer)->bo;
25797ec681f3Smrg   else
25807ec681f3Smrg      state->index_buffer = NULL;
25817ec681f3Smrg
25827ec681f3Smrg   state->ib_dirty = true;
25837ec681f3Smrg}
25847ec681f3Smrg
25857ec681f3Smrgstatic void handle_dispatch(struct vk_cmd_queue_entry *cmd,
25867ec681f3Smrg                            struct rendering_state *state)
25877ec681f3Smrg{
25887ec681f3Smrg   state->dispatch_info.grid[0] = cmd->u.dispatch.group_count_x;
25897ec681f3Smrg   state->dispatch_info.grid[1] = cmd->u.dispatch.group_count_y;
25907ec681f3Smrg   state->dispatch_info.grid[2] = cmd->u.dispatch.group_count_z;
25917ec681f3Smrg   state->dispatch_info.grid_base[0] = 0;
25927ec681f3Smrg   state->dispatch_info.grid_base[1] = 0;
25937ec681f3Smrg   state->dispatch_info.grid_base[2] = 0;
25947ec681f3Smrg   state->dispatch_info.indirect = NULL;
25957ec681f3Smrg   state->pctx->launch_grid(state->pctx, &state->dispatch_info);
25967ec681f3Smrg}
25977ec681f3Smrg
25987ec681f3Smrgstatic void handle_dispatch_base(struct vk_cmd_queue_entry *cmd,
25997ec681f3Smrg                                 struct rendering_state *state)
26007ec681f3Smrg{
26017ec681f3Smrg   state->dispatch_info.grid[0] = cmd->u.dispatch_base.group_count_x;
26027ec681f3Smrg   state->dispatch_info.grid[1] = cmd->u.dispatch_base.group_count_y;
26037ec681f3Smrg   state->dispatch_info.grid[2] = cmd->u.dispatch_base.group_count_z;
26047ec681f3Smrg   state->dispatch_info.grid_base[0] = cmd->u.dispatch_base.base_group_x;
26057ec681f3Smrg   state->dispatch_info.grid_base[1] = cmd->u.dispatch_base.base_group_y;
26067ec681f3Smrg   state->dispatch_info.grid_base[2] = cmd->u.dispatch_base.base_group_z;
26077ec681f3Smrg   state->dispatch_info.indirect = NULL;
26087ec681f3Smrg   state->pctx->launch_grid(state->pctx, &state->dispatch_info);
26097ec681f3Smrg}
26107ec681f3Smrg
26117ec681f3Smrgstatic void handle_dispatch_indirect(struct vk_cmd_queue_entry *cmd,
26127ec681f3Smrg                                     struct rendering_state *state)
26137ec681f3Smrg{
26147ec681f3Smrg   state->dispatch_info.indirect = lvp_buffer_from_handle(cmd->u.dispatch_indirect.buffer)->bo;
26157ec681f3Smrg   state->dispatch_info.indirect_offset = cmd->u.dispatch_indirect.offset;
26167ec681f3Smrg   state->pctx->launch_grid(state->pctx, &state->dispatch_info);
26177ec681f3Smrg}
26187ec681f3Smrg
26197ec681f3Smrgstatic void handle_push_constants(struct vk_cmd_queue_entry *cmd,
26207ec681f3Smrg                                  struct rendering_state *state)
26217ec681f3Smrg{
26227ec681f3Smrg   memcpy(state->push_constants + cmd->u.push_constants.offset, cmd->u.push_constants.values, cmd->u.push_constants.size);
26237ec681f3Smrg
26247ec681f3Smrg   state->pc_buffer[PIPE_SHADER_VERTEX].buffer_size = 128 * 4;
26257ec681f3Smrg   state->pc_buffer[PIPE_SHADER_VERTEX].buffer_offset = 0;
26267ec681f3Smrg   state->pc_buffer[PIPE_SHADER_VERTEX].user_buffer = state->push_constants;
26277ec681f3Smrg   state->pcbuf_dirty[PIPE_SHADER_VERTEX] = true;
26287ec681f3Smrg   state->pc_buffer[PIPE_SHADER_FRAGMENT].buffer_size = 128 * 4;
26297ec681f3Smrg   state->pc_buffer[PIPE_SHADER_FRAGMENT].buffer_offset = 0;
26307ec681f3Smrg   state->pc_buffer[PIPE_SHADER_FRAGMENT].user_buffer = state->push_constants;
26317ec681f3Smrg   state->pcbuf_dirty[PIPE_SHADER_FRAGMENT] = true;
26327ec681f3Smrg   state->pc_buffer[PIPE_SHADER_GEOMETRY].buffer_size = 128 * 4;
26337ec681f3Smrg   state->pc_buffer[PIPE_SHADER_GEOMETRY].buffer_offset = 0;
26347ec681f3Smrg   state->pc_buffer[PIPE_SHADER_GEOMETRY].user_buffer = state->push_constants;
26357ec681f3Smrg   state->pcbuf_dirty[PIPE_SHADER_GEOMETRY] = true;
26367ec681f3Smrg   state->pc_buffer[PIPE_SHADER_TESS_CTRL].buffer_size = 128 * 4;
26377ec681f3Smrg   state->pc_buffer[PIPE_SHADER_TESS_CTRL].buffer_offset = 0;
26387ec681f3Smrg   state->pc_buffer[PIPE_SHADER_TESS_CTRL].user_buffer = state->push_constants;
26397ec681f3Smrg   state->pcbuf_dirty[PIPE_SHADER_TESS_CTRL] = true;
26407ec681f3Smrg   state->pc_buffer[PIPE_SHADER_TESS_EVAL].buffer_size = 128 * 4;
26417ec681f3Smrg   state->pc_buffer[PIPE_SHADER_TESS_EVAL].buffer_offset = 0;
26427ec681f3Smrg   state->pc_buffer[PIPE_SHADER_TESS_EVAL].user_buffer = state->push_constants;
26437ec681f3Smrg   state->pcbuf_dirty[PIPE_SHADER_TESS_EVAL] = true;
26447ec681f3Smrg   state->pc_buffer[PIPE_SHADER_COMPUTE].buffer_size = 128 * 4;
26457ec681f3Smrg   state->pc_buffer[PIPE_SHADER_COMPUTE].buffer_offset = 0;
26467ec681f3Smrg   state->pc_buffer[PIPE_SHADER_COMPUTE].user_buffer = state->push_constants;
26477ec681f3Smrg   state->pcbuf_dirty[PIPE_SHADER_COMPUTE] = true;
26487ec681f3Smrg}
26497ec681f3Smrg
26507ec681f3Smrgstatic void lvp_execute_cmd_buffer(struct lvp_cmd_buffer *cmd_buffer,
26517ec681f3Smrg                                   struct rendering_state *state);
26527ec681f3Smrg
26537ec681f3Smrgstatic void handle_execute_commands(struct vk_cmd_queue_entry *cmd,
26547ec681f3Smrg                                    struct rendering_state *state)
26557ec681f3Smrg{
26567ec681f3Smrg   for (unsigned i = 0; i < cmd->u.execute_commands.command_buffer_count; i++) {
26577ec681f3Smrg      LVP_FROM_HANDLE(lvp_cmd_buffer, secondary_buf, cmd->u.execute_commands.command_buffers[i]);
26587ec681f3Smrg      lvp_execute_cmd_buffer(secondary_buf, state);
26597ec681f3Smrg   }
26607ec681f3Smrg}
26617ec681f3Smrg
26627ec681f3Smrgstatic void handle_event_set(struct vk_cmd_queue_entry *cmd,
26637ec681f3Smrg                             struct rendering_state *state)
26647ec681f3Smrg{
26657ec681f3Smrg   LVP_FROM_HANDLE(lvp_event, event, cmd->u.set_event.event);
26667ec681f3Smrg
26677ec681f3Smrg   if (cmd->u.reset_event.stage_mask == VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT)
26687ec681f3Smrg      state->pctx->flush(state->pctx, NULL, 0);
26697ec681f3Smrg   event->event_storage = 1;
26707ec681f3Smrg}
26717ec681f3Smrg
26727ec681f3Smrgstatic void handle_event_reset(struct vk_cmd_queue_entry *cmd,
26737ec681f3Smrg                               struct rendering_state *state)
26747ec681f3Smrg{
26757ec681f3Smrg   LVP_FROM_HANDLE(lvp_event, event, cmd->u.reset_event.event);
26767ec681f3Smrg
26777ec681f3Smrg   if (cmd->u.reset_event.stage_mask == VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT)
26787ec681f3Smrg      state->pctx->flush(state->pctx, NULL, 0);
26797ec681f3Smrg   event->event_storage = 0;
26807ec681f3Smrg}
26817ec681f3Smrg
26827ec681f3Smrgstatic void handle_wait_events(struct vk_cmd_queue_entry *cmd,
26837ec681f3Smrg                               struct rendering_state *state)
26847ec681f3Smrg{
26857ec681f3Smrg   for (unsigned i = 0; i < cmd->u.wait_events.event_count; i++) {
26867ec681f3Smrg      LVP_FROM_HANDLE(lvp_event, event, cmd->u.wait_events.events[i]);
26877ec681f3Smrg
26887ec681f3Smrg      while (event->event_storage != true);
26897ec681f3Smrg   }
26907ec681f3Smrg}
26917ec681f3Smrg
26927ec681f3Smrgstatic void handle_pipeline_barrier(struct vk_cmd_queue_entry *cmd,
26937ec681f3Smrg                                    struct rendering_state *state)
26947ec681f3Smrg{
26957ec681f3Smrg   /* why hello nail, I'm a hammer. - TODO */
26967ec681f3Smrg   state->pctx->flush(state->pctx, NULL, 0);
26977ec681f3Smrg}
26987ec681f3Smrg
26997ec681f3Smrgstatic void handle_begin_query(struct vk_cmd_queue_entry *cmd,
27007ec681f3Smrg                               struct rendering_state *state)
27017ec681f3Smrg{
27027ec681f3Smrg   struct vk_cmd_begin_query *qcmd = &cmd->u.begin_query;
27037ec681f3Smrg   LVP_FROM_HANDLE(lvp_query_pool, pool, qcmd->query_pool);
27047ec681f3Smrg
27057ec681f3Smrg   if (pool->type == VK_QUERY_TYPE_PIPELINE_STATISTICS &&
27067ec681f3Smrg       pool->pipeline_stats & VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT)
27077ec681f3Smrg      emit_compute_state(state);
27087ec681f3Smrg
27097ec681f3Smrg   emit_state(state);
27107ec681f3Smrg
27117ec681f3Smrg   if (!pool->queries[qcmd->query]) {
27127ec681f3Smrg      enum pipe_query_type qtype = pool->base_type;
27137ec681f3Smrg      pool->queries[qcmd->query] = state->pctx->create_query(state->pctx,
27147ec681f3Smrg                                                             qtype, 0);
27157ec681f3Smrg   }
27167ec681f3Smrg
27177ec681f3Smrg   state->pctx->begin_query(state->pctx, pool->queries[qcmd->query]);
27187ec681f3Smrg}
27197ec681f3Smrg
27207ec681f3Smrgstatic void handle_end_query(struct vk_cmd_queue_entry *cmd,
27217ec681f3Smrg                             struct rendering_state *state)
27227ec681f3Smrg{
27237ec681f3Smrg   struct vk_cmd_end_query *qcmd = &cmd->u.end_query;
27247ec681f3Smrg   LVP_FROM_HANDLE(lvp_query_pool, pool, qcmd->query_pool);
27257ec681f3Smrg   assert(pool->queries[qcmd->query]);
27267ec681f3Smrg
27277ec681f3Smrg   state->pctx->end_query(state->pctx, pool->queries[qcmd->query]);
27287ec681f3Smrg}
27297ec681f3Smrg
27307ec681f3Smrg
27317ec681f3Smrgstatic void handle_begin_query_indexed_ext(struct vk_cmd_queue_entry *cmd,
27327ec681f3Smrg                                           struct rendering_state *state)
27337ec681f3Smrg{
27347ec681f3Smrg   struct vk_cmd_begin_query_indexed_ext *qcmd = &cmd->u.begin_query_indexed_ext;
27357ec681f3Smrg   LVP_FROM_HANDLE(lvp_query_pool, pool, qcmd->query_pool);
27367ec681f3Smrg
27377ec681f3Smrg   if (pool->type == VK_QUERY_TYPE_PIPELINE_STATISTICS &&
27387ec681f3Smrg       pool->pipeline_stats & VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT)
27397ec681f3Smrg      emit_compute_state(state);
27407ec681f3Smrg
27417ec681f3Smrg   emit_state(state);
27427ec681f3Smrg
27437ec681f3Smrg   if (!pool->queries[qcmd->query]) {
27447ec681f3Smrg      enum pipe_query_type qtype = pool->base_type;
27457ec681f3Smrg      pool->queries[qcmd->query] = state->pctx->create_query(state->pctx,
27467ec681f3Smrg                                                             qtype, qcmd->index);
27477ec681f3Smrg   }
27487ec681f3Smrg
27497ec681f3Smrg   state->pctx->begin_query(state->pctx, pool->queries[qcmd->query]);
27507ec681f3Smrg}
27517ec681f3Smrg
27527ec681f3Smrgstatic void handle_end_query_indexed_ext(struct vk_cmd_queue_entry *cmd,
27537ec681f3Smrg                                         struct rendering_state *state)
27547ec681f3Smrg{
27557ec681f3Smrg   struct vk_cmd_end_query_indexed_ext *qcmd = &cmd->u.end_query_indexed_ext;
27567ec681f3Smrg   LVP_FROM_HANDLE(lvp_query_pool, pool, qcmd->query_pool);
27577ec681f3Smrg   assert(pool->queries[qcmd->query]);
27587ec681f3Smrg
27597ec681f3Smrg   state->pctx->end_query(state->pctx, pool->queries[qcmd->query]);
27607ec681f3Smrg}
27617ec681f3Smrg
27627ec681f3Smrgstatic void handle_reset_query_pool(struct vk_cmd_queue_entry *cmd,
27637ec681f3Smrg                                    struct rendering_state *state)
27647ec681f3Smrg{
27657ec681f3Smrg   struct vk_cmd_reset_query_pool *qcmd = &cmd->u.reset_query_pool;
27667ec681f3Smrg   LVP_FROM_HANDLE(lvp_query_pool, pool, qcmd->query_pool);
27677ec681f3Smrg   for (unsigned i = qcmd->first_query; i < qcmd->first_query + qcmd->query_count; i++) {
27687ec681f3Smrg      if (pool->queries[i]) {
27697ec681f3Smrg         state->pctx->destroy_query(state->pctx, pool->queries[i]);
27707ec681f3Smrg         pool->queries[i] = NULL;
27717ec681f3Smrg      }
27727ec681f3Smrg   }
27737ec681f3Smrg}
27747ec681f3Smrg
27757ec681f3Smrgstatic void handle_write_timestamp(struct vk_cmd_queue_entry *cmd,
27767ec681f3Smrg                                   struct rendering_state *state)
27777ec681f3Smrg{
27787ec681f3Smrg   struct vk_cmd_write_timestamp *qcmd = &cmd->u.write_timestamp;
27797ec681f3Smrg   LVP_FROM_HANDLE(lvp_query_pool, pool, qcmd->query_pool);
27807ec681f3Smrg   if (!pool->queries[qcmd->query]) {
27817ec681f3Smrg      pool->queries[qcmd->query] = state->pctx->create_query(state->pctx,
27827ec681f3Smrg                                                             PIPE_QUERY_TIMESTAMP, 0);
27837ec681f3Smrg   }
27847ec681f3Smrg
27857ec681f3Smrg   if (!(qcmd->pipeline_stage == VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT))
27867ec681f3Smrg      state->pctx->flush(state->pctx, NULL, 0);
27877ec681f3Smrg   state->pctx->end_query(state->pctx, pool->queries[qcmd->query]);
27887ec681f3Smrg
27897ec681f3Smrg}
27907ec681f3Smrg
27917ec681f3Smrgstatic void handle_copy_query_pool_results(struct vk_cmd_queue_entry *cmd,
27927ec681f3Smrg                                           struct rendering_state *state)
27937ec681f3Smrg{
27947ec681f3Smrg   struct vk_cmd_copy_query_pool_results *copycmd = &cmd->u.copy_query_pool_results;
27957ec681f3Smrg   LVP_FROM_HANDLE(lvp_query_pool, pool, copycmd->query_pool);
27967ec681f3Smrg
27977ec681f3Smrg   for (unsigned i = copycmd->first_query; i < copycmd->first_query + copycmd->query_count; i++) {
27987ec681f3Smrg      unsigned offset = copycmd->dst_offset + lvp_buffer_from_handle(copycmd->dst_buffer)->offset + (copycmd->stride * (i - copycmd->first_query));
27997ec681f3Smrg      if (pool->queries[i]) {
28007ec681f3Smrg         if (copycmd->flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)
28017ec681f3Smrg            state->pctx->get_query_result_resource(state->pctx,
28027ec681f3Smrg                                                   pool->queries[i],
28037ec681f3Smrg                                                   copycmd->flags & VK_QUERY_RESULT_WAIT_BIT,
28047ec681f3Smrg                                                   copycmd->flags & VK_QUERY_RESULT_64_BIT ? PIPE_QUERY_TYPE_U64 : PIPE_QUERY_TYPE_U32,
28057ec681f3Smrg                                                   -1,
28067ec681f3Smrg                                                   lvp_buffer_from_handle(copycmd->dst_buffer)->bo,
28077ec681f3Smrg                                                   offset + (copycmd->flags & VK_QUERY_RESULT_64_BIT ? 8 : 4));
28087ec681f3Smrg         if (pool->type == VK_QUERY_TYPE_PIPELINE_STATISTICS) {
28097ec681f3Smrg            unsigned num_results = 0;
28107ec681f3Smrg            unsigned result_size = copycmd->flags & VK_QUERY_RESULT_64_BIT ? 8 : 4;
28117ec681f3Smrg            u_foreach_bit(bit, pool->pipeline_stats)
28127ec681f3Smrg               state->pctx->get_query_result_resource(state->pctx,
28137ec681f3Smrg                                                      pool->queries[i],
28147ec681f3Smrg                                                      copycmd->flags & VK_QUERY_RESULT_WAIT_BIT,
28157ec681f3Smrg                                                      copycmd->flags & VK_QUERY_RESULT_64_BIT ? PIPE_QUERY_TYPE_U64 : PIPE_QUERY_TYPE_U32,
28167ec681f3Smrg                                                      bit,
28177ec681f3Smrg                                                      lvp_buffer_from_handle(copycmd->dst_buffer)->bo,
28187ec681f3Smrg                                                      offset + num_results++ * result_size);
28197ec681f3Smrg         } else {
28207ec681f3Smrg            state->pctx->get_query_result_resource(state->pctx,
28217ec681f3Smrg                                                   pool->queries[i],
28227ec681f3Smrg                                                   copycmd->flags & VK_QUERY_RESULT_WAIT_BIT,
28237ec681f3Smrg                                                   copycmd->flags & VK_QUERY_RESULT_64_BIT ? PIPE_QUERY_TYPE_U64 : PIPE_QUERY_TYPE_U32,
28247ec681f3Smrg                                                   0,
28257ec681f3Smrg                                                   lvp_buffer_from_handle(copycmd->dst_buffer)->bo,
28267ec681f3Smrg                                                   offset);
28277ec681f3Smrg         }
28287ec681f3Smrg      } else {
28297ec681f3Smrg         /* if no queries emitted yet, just reset the buffer to 0 so avail is reported correctly */
28307ec681f3Smrg         if (copycmd->flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT) {
28317ec681f3Smrg            struct pipe_transfer *src_t;
28327ec681f3Smrg            uint32_t *map;
28337ec681f3Smrg
28347ec681f3Smrg            struct pipe_box box = {0};
28357ec681f3Smrg            box.x = offset;
28367ec681f3Smrg            box.width = copycmd->stride;
28377ec681f3Smrg            box.height = 1;
28387ec681f3Smrg            box.depth = 1;
28397ec681f3Smrg            map = state->pctx->buffer_map(state->pctx,
28407ec681f3Smrg                                            lvp_buffer_from_handle(copycmd->dst_buffer)->bo, 0, PIPE_MAP_READ, &box,
28417ec681f3Smrg                                            &src_t);
28427ec681f3Smrg
28437ec681f3Smrg            memset(map, 0, box.width);
28447ec681f3Smrg            state->pctx->buffer_unmap(state->pctx, src_t);
28457ec681f3Smrg         }
28467ec681f3Smrg      }
28477ec681f3Smrg   }
28487ec681f3Smrg}
28497ec681f3Smrg
28507ec681f3Smrgstatic void handle_clear_color_image(struct vk_cmd_queue_entry *cmd,
28517ec681f3Smrg                                     struct rendering_state *state)
28527ec681f3Smrg{
28537ec681f3Smrg   LVP_FROM_HANDLE(lvp_image, image, cmd->u.clear_color_image.image);
28547ec681f3Smrg   union util_color uc;
28557ec681f3Smrg   uint32_t *col_val = uc.ui;
28567ec681f3Smrg   util_pack_color_union(image->bo->format, &uc, (void*)cmd->u.clear_color_image.color);
28577ec681f3Smrg   for (unsigned i = 0; i < cmd->u.clear_color_image.range_count; i++) {
28587ec681f3Smrg      VkImageSubresourceRange *range = &cmd->u.clear_color_image.ranges[i];
28597ec681f3Smrg      struct pipe_box box;
28607ec681f3Smrg      box.x = 0;
28617ec681f3Smrg      box.y = 0;
28627ec681f3Smrg      box.z = 0;
28637ec681f3Smrg
28647ec681f3Smrg      uint32_t level_count = lvp_get_levelCount(image, range);
28657ec681f3Smrg      for (unsigned j = range->baseMipLevel; j < range->baseMipLevel + level_count; j++) {
28667ec681f3Smrg         box.width = u_minify(image->bo->width0, j);
28677ec681f3Smrg         box.height = u_minify(image->bo->height0, j);
28687ec681f3Smrg         box.depth = 1;
28697ec681f3Smrg         if (image->bo->target == PIPE_TEXTURE_3D)
28707ec681f3Smrg            box.depth = u_minify(image->bo->depth0, j);
28717ec681f3Smrg         else if (image->bo->target == PIPE_TEXTURE_1D_ARRAY) {
28727ec681f3Smrg            box.y = range->baseArrayLayer;
28737ec681f3Smrg            box.height = lvp_get_layerCount(image, range);
28747ec681f3Smrg            box.depth = 1;
28757ec681f3Smrg         } else {
28767ec681f3Smrg            box.z = range->baseArrayLayer;
28777ec681f3Smrg            box.depth = lvp_get_layerCount(image, range);
28787ec681f3Smrg         }
28797ec681f3Smrg
28807ec681f3Smrg         state->pctx->clear_texture(state->pctx, image->bo,
28817ec681f3Smrg                                    j, &box, (void *)col_val);
28827ec681f3Smrg      }
28837ec681f3Smrg   }
28847ec681f3Smrg}
28857ec681f3Smrg
28867ec681f3Smrgstatic void handle_clear_ds_image(struct vk_cmd_queue_entry *cmd,
28877ec681f3Smrg                                  struct rendering_state *state)
28887ec681f3Smrg{
28897ec681f3Smrg   LVP_FROM_HANDLE(lvp_image, image, cmd->u.clear_depth_stencil_image.image);
28907ec681f3Smrg   for (unsigned i = 0; i < cmd->u.clear_depth_stencil_image.range_count; i++) {
28917ec681f3Smrg      VkImageSubresourceRange *range = &cmd->u.clear_depth_stencil_image.ranges[i];
28927ec681f3Smrg      uint32_t ds_clear_flags = 0;
28937ec681f3Smrg      if (range->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT)
28947ec681f3Smrg         ds_clear_flags |= PIPE_CLEAR_DEPTH;
28957ec681f3Smrg      if (range->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT)
28967ec681f3Smrg         ds_clear_flags |= PIPE_CLEAR_STENCIL;
28977ec681f3Smrg
28987ec681f3Smrg      uint32_t level_count = lvp_get_levelCount(image, range);
28997ec681f3Smrg      for (unsigned j = 0; j < level_count; j++) {
29007ec681f3Smrg         struct pipe_surface *surf;
29017ec681f3Smrg         unsigned width, height;
29027ec681f3Smrg
29037ec681f3Smrg         width = u_minify(image->bo->width0, range->baseMipLevel + j);
29047ec681f3Smrg         height = u_minify(image->bo->height0, range->baseMipLevel + j);
29057ec681f3Smrg
29067ec681f3Smrg         surf = create_img_surface_bo(state, range,
29077ec681f3Smrg                                      image->bo, image->bo->format,
29087ec681f3Smrg                                      width, height,
29097ec681f3Smrg                                      0, lvp_get_layerCount(image, range) - 1, j);
29107ec681f3Smrg
29117ec681f3Smrg         state->pctx->clear_depth_stencil(state->pctx,
29127ec681f3Smrg                                          surf,
29137ec681f3Smrg                                          ds_clear_flags,
29147ec681f3Smrg                                          cmd->u.clear_depth_stencil_image.depth_stencil->depth,
29157ec681f3Smrg                                          cmd->u.clear_depth_stencil_image.depth_stencil->stencil,
29167ec681f3Smrg                                          0, 0,
29177ec681f3Smrg                                          width, height, true);
29187ec681f3Smrg         state->pctx->surface_destroy(state->pctx, surf);
29197ec681f3Smrg      }
29207ec681f3Smrg   }
29217ec681f3Smrg}
29227ec681f3Smrg
29237ec681f3Smrgstatic void handle_clear_attachments(struct vk_cmd_queue_entry *cmd,
29247ec681f3Smrg                                     struct rendering_state *state)
29257ec681f3Smrg{
29267ec681f3Smrg   for (uint32_t a = 0; a < cmd->u.clear_attachments.attachment_count; a++) {
29277ec681f3Smrg      VkClearAttachment *att = &cmd->u.clear_attachments.attachments[a];
29287ec681f3Smrg      const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
29297ec681f3Smrg      struct lvp_image_view *imgv;
29307ec681f3Smrg
29317ec681f3Smrg      if (att->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) {
29327ec681f3Smrg         struct lvp_subpass_attachment *color_att = &subpass->color_attachments[att->colorAttachment];
29337ec681f3Smrg         if (!color_att || color_att->attachment == VK_ATTACHMENT_UNUSED)
29347ec681f3Smrg            continue;
29357ec681f3Smrg         imgv = get_attachment(state, color_att->attachment);
29367ec681f3Smrg      } else {
29377ec681f3Smrg         struct lvp_subpass_attachment *ds_att = subpass->depth_stencil_attachment;
29387ec681f3Smrg         if (!ds_att || ds_att->attachment == VK_ATTACHMENT_UNUSED)
29397ec681f3Smrg            continue;
29407ec681f3Smrg         imgv = get_attachment(state, ds_att->attachment);
29417ec681f3Smrg      }
29427ec681f3Smrg      union pipe_color_union col_val;
29437ec681f3Smrg      double dclear_val = 0;
29447ec681f3Smrg      uint32_t sclear_val = 0;
29457ec681f3Smrg      uint32_t ds_clear_flags = 0;
29467ec681f3Smrg      if (att->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) {
29477ec681f3Smrg         ds_clear_flags |= PIPE_CLEAR_DEPTH;
29487ec681f3Smrg         dclear_val = att->clearValue.depthStencil.depth;
29497ec681f3Smrg      }
29507ec681f3Smrg      if (att->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) {
29517ec681f3Smrg         ds_clear_flags |= PIPE_CLEAR_STENCIL;
29527ec681f3Smrg         sclear_val = att->clearValue.depthStencil.stencil;
29537ec681f3Smrg      }
29547ec681f3Smrg      if (att->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
29557ec681f3Smrg         for (unsigned i = 0; i < 4; i++)
29567ec681f3Smrg            col_val.ui[i] = att->clearValue.color.uint32[i];
29577ec681f3Smrg      }
29587ec681f3Smrg
29597ec681f3Smrg      for (uint32_t r = 0; r < cmd->u.clear_attachments.rect_count; r++) {
29607ec681f3Smrg
29617ec681f3Smrg         VkClearRect *rect = &cmd->u.clear_attachments.rects[r];
29627ec681f3Smrg         if (subpass->view_mask) {
29637ec681f3Smrg            u_foreach_bit(i, subpass->view_mask)
29647ec681f3Smrg               clear_attachment_layers(state, imgv, &rect->rect,
29657ec681f3Smrg                                       i, 1,
29667ec681f3Smrg                                       ds_clear_flags, dclear_val, sclear_val,
29677ec681f3Smrg                                       &col_val);
29687ec681f3Smrg         } else
29697ec681f3Smrg            clear_attachment_layers(state, imgv, &rect->rect,
29707ec681f3Smrg                                    rect->baseArrayLayer, rect->layerCount,
29717ec681f3Smrg                                    ds_clear_flags, dclear_val, sclear_val,
29727ec681f3Smrg                                    &col_val);
29737ec681f3Smrg      }
29747ec681f3Smrg   }
29757ec681f3Smrg}
29767ec681f3Smrg
29777ec681f3Smrgstatic void handle_resolve_image(struct vk_cmd_queue_entry *cmd,
29787ec681f3Smrg                                 struct rendering_state *state)
29797ec681f3Smrg{
29807ec681f3Smrg   int i;
29817ec681f3Smrg   struct VkResolveImageInfo2KHR *resolvecmd = cmd->u.resolve_image2_khr.resolve_image_info;
29827ec681f3Smrg   LVP_FROM_HANDLE(lvp_image, src_image, resolvecmd->srcImage);
29837ec681f3Smrg   LVP_FROM_HANDLE(lvp_image, dst_image, resolvecmd->dstImage);
29847ec681f3Smrg   struct pipe_blit_info info;
29857ec681f3Smrg
29867ec681f3Smrg   memset(&info, 0, sizeof(info));
29877ec681f3Smrg
29887ec681f3Smrg   state->pctx->flush(state->pctx, NULL, 0);
29897ec681f3Smrg   info.src.resource = src_image->bo;
29907ec681f3Smrg   info.dst.resource = dst_image->bo;
29917ec681f3Smrg   info.src.format = src_image->bo->format;
29927ec681f3Smrg   info.dst.format = dst_image->bo->format;
29937ec681f3Smrg   info.mask = util_format_is_depth_or_stencil(info.src.format) ? PIPE_MASK_ZS : PIPE_MASK_RGBA;
29947ec681f3Smrg   info.filter = PIPE_TEX_FILTER_NEAREST;
29957ec681f3Smrg   for (i = 0; i < resolvecmd->regionCount; i++) {
29967ec681f3Smrg      int srcX0, srcY0;
29977ec681f3Smrg      unsigned dstX0, dstY0;
29987ec681f3Smrg
29997ec681f3Smrg      srcX0 = resolvecmd->pRegions[i].srcOffset.x;
30007ec681f3Smrg      srcY0 = resolvecmd->pRegions[i].srcOffset.y;
30017ec681f3Smrg
30027ec681f3Smrg      dstX0 = resolvecmd->pRegions[i].dstOffset.x;
30037ec681f3Smrg      dstY0 = resolvecmd->pRegions[i].dstOffset.y;
30047ec681f3Smrg
30057ec681f3Smrg      info.dst.box.x = dstX0;
30067ec681f3Smrg      info.dst.box.y = dstY0;
30077ec681f3Smrg      info.src.box.x = srcX0;
30087ec681f3Smrg      info.src.box.y = srcY0;
30097ec681f3Smrg
30107ec681f3Smrg      info.dst.box.width = resolvecmd->pRegions[i].extent.width;
30117ec681f3Smrg      info.src.box.width = resolvecmd->pRegions[i].extent.width;
30127ec681f3Smrg      info.dst.box.height = resolvecmd->pRegions[i].extent.height;
30137ec681f3Smrg      info.src.box.height = resolvecmd->pRegions[i].extent.height;
30147ec681f3Smrg
30157ec681f3Smrg      info.dst.box.depth = resolvecmd->pRegions[i].dstSubresource.layerCount;
30167ec681f3Smrg      info.src.box.depth = resolvecmd->pRegions[i].srcSubresource.layerCount;
30177ec681f3Smrg
30187ec681f3Smrg      info.src.level = resolvecmd->pRegions[i].srcSubresource.mipLevel;
30197ec681f3Smrg      info.src.box.z = resolvecmd->pRegions[i].srcOffset.z + resolvecmd->pRegions[i].srcSubresource.baseArrayLayer;
30207ec681f3Smrg
30217ec681f3Smrg      info.dst.level = resolvecmd->pRegions[i].dstSubresource.mipLevel;
30227ec681f3Smrg      info.dst.box.z = resolvecmd->pRegions[i].dstOffset.z + resolvecmd->pRegions[i].dstSubresource.baseArrayLayer;
30237ec681f3Smrg
30247ec681f3Smrg      state->pctx->blit(state->pctx, &info);
30257ec681f3Smrg   }
30267ec681f3Smrg}
30277ec681f3Smrg
30287ec681f3Smrgstatic void handle_draw_indirect_count(struct vk_cmd_queue_entry *cmd,
30297ec681f3Smrg                                       struct rendering_state *state, bool indexed)
30307ec681f3Smrg{
30317ec681f3Smrg   const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
30327ec681f3Smrg   struct pipe_draw_start_count_bias draw = {0};
30337ec681f3Smrg   if (indexed) {
30347ec681f3Smrg      state->info.index_bounds_valid = false;
30357ec681f3Smrg      state->info.index_size = state->index_size;
30367ec681f3Smrg      state->info.index.resource = state->index_buffer;
30377ec681f3Smrg      state->info.max_index = ~0;
30387ec681f3Smrg   } else
30397ec681f3Smrg      state->info.index_size = 0;
30407ec681f3Smrg   state->indirect_info.offset = cmd->u.draw_indirect_count.offset;
30417ec681f3Smrg   state->indirect_info.stride = cmd->u.draw_indirect_count.stride;
30427ec681f3Smrg   state->indirect_info.draw_count = cmd->u.draw_indirect_count.max_draw_count;
30437ec681f3Smrg   state->indirect_info.buffer = lvp_buffer_from_handle(cmd->u.draw_indirect_count.buffer)->bo;
30447ec681f3Smrg   state->indirect_info.indirect_draw_count_offset = cmd->u.draw_indirect_count.count_buffer_offset;
30457ec681f3Smrg   state->indirect_info.indirect_draw_count = lvp_buffer_from_handle(cmd->u.draw_indirect_count.count_buffer)->bo;
30467ec681f3Smrg   state->info.view_mask = subpass->view_mask;
30477ec681f3Smrg
30487ec681f3Smrg   state->pctx->set_patch_vertices(state->pctx, state->patch_vertices);
30497ec681f3Smrg   state->pctx->draw_vbo(state->pctx, &state->info, 0, &state->indirect_info, &draw, 1);
30507ec681f3Smrg}
30517ec681f3Smrg
30527ec681f3Smrgstatic void handle_compute_push_descriptor_set(struct lvp_cmd_push_descriptor_set *pds,
30537ec681f3Smrg                                               struct dyn_info *dyn_info,
30547ec681f3Smrg                                               struct rendering_state *state)
30557ec681f3Smrg{
30567ec681f3Smrg   struct lvp_descriptor_set_layout *layout = pds->layout->set[pds->set].layout;
30577ec681f3Smrg
30587ec681f3Smrg   if (!(layout->shader_stages & VK_SHADER_STAGE_COMPUTE_BIT))
30597ec681f3Smrg      return;
30607ec681f3Smrg   for (unsigned i = 0; i < pds->set; i++) {
30617ec681f3Smrg      increment_dyn_info(dyn_info, pds->layout->set[i].layout, false);
30627ec681f3Smrg   }
30637ec681f3Smrg   unsigned info_idx = 0;
30647ec681f3Smrg   for (unsigned i = 0; i < pds->descriptor_write_count; i++) {
30657ec681f3Smrg      struct lvp_write_descriptor *desc = &pds->descriptors[i];
30667ec681f3Smrg      struct lvp_descriptor_set_binding_layout *binding = &layout->binding[desc->dst_binding];
30677ec681f3Smrg
30687ec681f3Smrg      if (!binding->valid)
30697ec681f3Smrg         continue;
30707ec681f3Smrg
30717ec681f3Smrg      for (unsigned j = 0; j < desc->descriptor_count; j++) {
30727ec681f3Smrg         union lvp_descriptor_info *info = &pds->infos[info_idx + j];
30737ec681f3Smrg
30747ec681f3Smrg         handle_descriptor(state, dyn_info, binding,
30757ec681f3Smrg                           MESA_SHADER_COMPUTE, PIPE_SHADER_COMPUTE,
30767ec681f3Smrg                           j, desc->descriptor_type,
30777ec681f3Smrg                           info);
30787ec681f3Smrg      }
30797ec681f3Smrg      info_idx += desc->descriptor_count;
30807ec681f3Smrg   }
30817ec681f3Smrg}
30827ec681f3Smrg
30837ec681f3Smrgstatic struct lvp_cmd_push_descriptor_set *create_push_descriptor_set(struct vk_cmd_push_descriptor_set_khr *in_cmd)
30847ec681f3Smrg{
30857ec681f3Smrg   LVP_FROM_HANDLE(lvp_pipeline_layout, layout, in_cmd->layout);
30867ec681f3Smrg   struct lvp_cmd_push_descriptor_set *out_cmd;
30877ec681f3Smrg   int count_descriptors = 0;
30887ec681f3Smrg   int cmd_size = sizeof(*out_cmd);
30897ec681f3Smrg
30907ec681f3Smrg   for (unsigned i = 0; i < in_cmd->descriptor_write_count; i++) {
30917ec681f3Smrg      count_descriptors += in_cmd->descriptor_writes[i].descriptorCount;
30927ec681f3Smrg   }
30937ec681f3Smrg   cmd_size += count_descriptors * sizeof(union lvp_descriptor_info);
30947ec681f3Smrg
30957ec681f3Smrg   cmd_size += in_cmd->descriptor_write_count * sizeof(struct lvp_write_descriptor);
30967ec681f3Smrg
30977ec681f3Smrg   out_cmd = calloc(1, cmd_size);
30987ec681f3Smrg   if (!out_cmd)
30997ec681f3Smrg      return NULL;
31007ec681f3Smrg
31017ec681f3Smrg   out_cmd->bind_point = in_cmd->pipeline_bind_point;
31027ec681f3Smrg   out_cmd->layout = layout;
31037ec681f3Smrg   out_cmd->set = in_cmd->set;
31047ec681f3Smrg   out_cmd->descriptor_write_count = in_cmd->descriptor_write_count;
31057ec681f3Smrg   out_cmd->descriptors = (struct lvp_write_descriptor *)(out_cmd + 1);
31067ec681f3Smrg   out_cmd->infos = (union lvp_descriptor_info *)(out_cmd->descriptors + in_cmd->descriptor_write_count);
31077ec681f3Smrg
31087ec681f3Smrg   unsigned descriptor_index = 0;
31097ec681f3Smrg
31107ec681f3Smrg   for (unsigned i = 0; i < in_cmd->descriptor_write_count; i++) {
31117ec681f3Smrg      struct lvp_write_descriptor *desc = &out_cmd->descriptors[i];
31127ec681f3Smrg
31137ec681f3Smrg      /* dstSet is ignored */
31147ec681f3Smrg      desc->dst_binding = in_cmd->descriptor_writes[i].dstBinding;
31157ec681f3Smrg      desc->dst_array_element = in_cmd->descriptor_writes[i].dstArrayElement;
31167ec681f3Smrg      desc->descriptor_count = in_cmd->descriptor_writes[i].descriptorCount;
31177ec681f3Smrg      desc->descriptor_type = in_cmd->descriptor_writes[i].descriptorType;
31187ec681f3Smrg
31197ec681f3Smrg      for (unsigned j = 0; j < desc->descriptor_count; j++) {
31207ec681f3Smrg         union lvp_descriptor_info *info = &out_cmd->infos[descriptor_index + j];
31217ec681f3Smrg         switch (desc->descriptor_type) {
31227ec681f3Smrg         case VK_DESCRIPTOR_TYPE_SAMPLER:
31237ec681f3Smrg            info->sampler = lvp_sampler_from_handle(in_cmd->descriptor_writes[i].pImageInfo[j].sampler);
31247ec681f3Smrg            break;
31257ec681f3Smrg         case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
31267ec681f3Smrg            info->sampler = lvp_sampler_from_handle(in_cmd->descriptor_writes[i].pImageInfo[j].sampler);
31277ec681f3Smrg            info->iview = lvp_image_view_from_handle(in_cmd->descriptor_writes[i].pImageInfo[j].imageView);
31287ec681f3Smrg            info->image_layout = in_cmd->descriptor_writes[i].pImageInfo[j].imageLayout;
31297ec681f3Smrg            break;
31307ec681f3Smrg         case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
31317ec681f3Smrg         case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
31327ec681f3Smrg         case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
31337ec681f3Smrg            info->iview = lvp_image_view_from_handle(in_cmd->descriptor_writes[i].pImageInfo[j].imageView);
31347ec681f3Smrg            info->image_layout = in_cmd->descriptor_writes[i].pImageInfo[j].imageLayout;
31357ec681f3Smrg            break;
31367ec681f3Smrg         case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
31377ec681f3Smrg         case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
31387ec681f3Smrg            info->buffer_view = lvp_buffer_view_from_handle(in_cmd->descriptor_writes[i].pTexelBufferView[j]);
31397ec681f3Smrg            break;
31407ec681f3Smrg         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
31417ec681f3Smrg         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
31427ec681f3Smrg         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
31437ec681f3Smrg         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
31447ec681f3Smrg         default:
31457ec681f3Smrg            info->buffer = lvp_buffer_from_handle(in_cmd->descriptor_writes[i].pBufferInfo[j].buffer);
31467ec681f3Smrg            info->offset = in_cmd->descriptor_writes[i].pBufferInfo[j].offset;
31477ec681f3Smrg            info->range = in_cmd->descriptor_writes[i].pBufferInfo[j].range;
31487ec681f3Smrg            break;
31497ec681f3Smrg         }
31507ec681f3Smrg      }
31517ec681f3Smrg      descriptor_index += desc->descriptor_count;
31527ec681f3Smrg   }
31537ec681f3Smrg
31547ec681f3Smrg   return out_cmd;
31557ec681f3Smrg}
31567ec681f3Smrg
31577ec681f3Smrgstatic void handle_push_descriptor_set_generic(struct vk_cmd_push_descriptor_set_khr *_pds,
31587ec681f3Smrg                                               struct rendering_state *state)
31597ec681f3Smrg{
31607ec681f3Smrg   struct lvp_cmd_push_descriptor_set *pds;
31617ec681f3Smrg   struct lvp_descriptor_set_layout *layout;
31627ec681f3Smrg   struct dyn_info dyn_info;
31637ec681f3Smrg
31647ec681f3Smrg   pds = create_push_descriptor_set(_pds);
31657ec681f3Smrg   layout = pds->layout->set[pds->set].layout;
31667ec681f3Smrg
31677ec681f3Smrg   memset(&dyn_info.stage, 0, sizeof(dyn_info.stage));
31687ec681f3Smrg   dyn_info.dyn_index = 0;
31697ec681f3Smrg   if (pds->bind_point == VK_PIPELINE_BIND_POINT_COMPUTE) {
31707ec681f3Smrg      handle_compute_push_descriptor_set(pds, &dyn_info, state);
31717ec681f3Smrg   }
31727ec681f3Smrg
31737ec681f3Smrg   for (unsigned i = 0; i < pds->set; i++) {
31747ec681f3Smrg      increment_dyn_info(&dyn_info, pds->layout->set[i].layout, false);
31757ec681f3Smrg   }
31767ec681f3Smrg
31777ec681f3Smrg   unsigned info_idx = 0;
31787ec681f3Smrg   for (unsigned i = 0; i < pds->descriptor_write_count; i++) {
31797ec681f3Smrg      struct lvp_write_descriptor *desc = &pds->descriptors[i];
31807ec681f3Smrg      struct lvp_descriptor_set_binding_layout *binding = &layout->binding[desc->dst_binding];
31817ec681f3Smrg
31827ec681f3Smrg      if (!binding->valid)
31837ec681f3Smrg         continue;
31847ec681f3Smrg
31857ec681f3Smrg      for (unsigned j = 0; j < desc->descriptor_count; j++) {
31867ec681f3Smrg         union lvp_descriptor_info *info = &pds->infos[info_idx + j];
31877ec681f3Smrg
31887ec681f3Smrg         if (layout->shader_stages & VK_SHADER_STAGE_VERTEX_BIT)
31897ec681f3Smrg            handle_descriptor(state, &dyn_info, binding,
31907ec681f3Smrg                              MESA_SHADER_VERTEX, PIPE_SHADER_VERTEX,
31917ec681f3Smrg                              j, desc->descriptor_type,
31927ec681f3Smrg                              info);
31937ec681f3Smrg         if (layout->shader_stages & VK_SHADER_STAGE_FRAGMENT_BIT)
31947ec681f3Smrg            handle_descriptor(state, &dyn_info, binding,
31957ec681f3Smrg                              MESA_SHADER_FRAGMENT, PIPE_SHADER_FRAGMENT,
31967ec681f3Smrg                              j, desc->descriptor_type,
31977ec681f3Smrg                              info);
31987ec681f3Smrg         if (layout->shader_stages & VK_SHADER_STAGE_GEOMETRY_BIT)
31997ec681f3Smrg            handle_descriptor(state, &dyn_info, binding,
32007ec681f3Smrg                              MESA_SHADER_GEOMETRY, PIPE_SHADER_GEOMETRY,
32017ec681f3Smrg                              j, desc->descriptor_type,
32027ec681f3Smrg                              info);
32037ec681f3Smrg         if (layout->shader_stages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
32047ec681f3Smrg            handle_descriptor(state, &dyn_info, binding,
32057ec681f3Smrg                              MESA_SHADER_TESS_CTRL, PIPE_SHADER_TESS_CTRL,
32067ec681f3Smrg                              j, desc->descriptor_type,
32077ec681f3Smrg                              info);
32087ec681f3Smrg         if (layout->shader_stages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
32097ec681f3Smrg            handle_descriptor(state, &dyn_info, binding,
32107ec681f3Smrg                              MESA_SHADER_TESS_EVAL, PIPE_SHADER_TESS_EVAL,
32117ec681f3Smrg                              j, desc->descriptor_type,
32127ec681f3Smrg                              info);
32137ec681f3Smrg      }
32147ec681f3Smrg      info_idx += desc->descriptor_count;
32157ec681f3Smrg   }
32167ec681f3Smrg   free(pds);
32177ec681f3Smrg}
32187ec681f3Smrg
32197ec681f3Smrgstatic void handle_push_descriptor_set(struct vk_cmd_queue_entry *cmd,
32207ec681f3Smrg                                       struct rendering_state *state)
32217ec681f3Smrg{
32227ec681f3Smrg   handle_push_descriptor_set_generic(&cmd->u.push_descriptor_set_khr, state);
32237ec681f3Smrg}
32247ec681f3Smrg
32257ec681f3Smrgstatic void handle_push_descriptor_set_with_template(struct vk_cmd_queue_entry *cmd,
32267ec681f3Smrg                                                     struct rendering_state *state)
32277ec681f3Smrg{
32287ec681f3Smrg   LVP_FROM_HANDLE(lvp_descriptor_update_template, templ, cmd->u.push_descriptor_set_with_template_khr.descriptor_update_template);
32297ec681f3Smrg   struct vk_cmd_push_descriptor_set_khr *pds;
32307ec681f3Smrg   int pds_size = sizeof(*pds);
32317ec681f3Smrg
32327ec681f3Smrg   pds_size += templ->entry_count * sizeof(struct VkWriteDescriptorSet);
32337ec681f3Smrg
32347ec681f3Smrg   for (unsigned i = 0; i < templ->entry_count; i++) {
32357ec681f3Smrg      VkDescriptorUpdateTemplateEntry *entry = &templ->entry[i];
32367ec681f3Smrg      switch (entry->descriptorType) {
32377ec681f3Smrg      case VK_DESCRIPTOR_TYPE_SAMPLER:
32387ec681f3Smrg      case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
32397ec681f3Smrg      case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
32407ec681f3Smrg      case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
32417ec681f3Smrg      case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
32427ec681f3Smrg         pds_size += sizeof(VkDescriptorImageInfo) * entry->descriptorCount;
32437ec681f3Smrg         break;
32447ec681f3Smrg      case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
32457ec681f3Smrg      case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
32467ec681f3Smrg         pds_size += sizeof(VkBufferView) * entry->descriptorCount;
32477ec681f3Smrg         break;
32487ec681f3Smrg      case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
32497ec681f3Smrg      case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
32507ec681f3Smrg      case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
32517ec681f3Smrg      case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
32527ec681f3Smrg      default:
32537ec681f3Smrg         pds_size += sizeof(VkDescriptorBufferInfo) * entry->descriptorCount;
32547ec681f3Smrg         break;
32557ec681f3Smrg      }
32567ec681f3Smrg   }
32577ec681f3Smrg
32587ec681f3Smrg   pds = calloc(1, pds_size);
32597ec681f3Smrg   if (!pds)
32607ec681f3Smrg      return;
32617ec681f3Smrg
32627ec681f3Smrg   pds->pipeline_bind_point = templ->bind_point;
32637ec681f3Smrg   pds->layout = lvp_pipeline_layout_to_handle(templ->pipeline_layout);
32647ec681f3Smrg   pds->set = templ->set;
32657ec681f3Smrg   pds->descriptor_write_count = templ->entry_count;
32667ec681f3Smrg   pds->descriptor_writes = (struct VkWriteDescriptorSet *)(pds + 1);
32677ec681f3Smrg   const uint8_t *next_info = (const uint8_t *) (pds->descriptor_writes + templ->entry_count);
32687ec681f3Smrg
32697ec681f3Smrg   const uint8_t *pSrc = cmd->u.push_descriptor_set_with_template_khr.data;
32707ec681f3Smrg   for (unsigned i = 0; i < templ->entry_count; i++) {
32717ec681f3Smrg      struct VkWriteDescriptorSet *desc = &pds->descriptor_writes[i];
32727ec681f3Smrg      struct VkDescriptorUpdateTemplateEntry *entry = &templ->entry[i];
32737ec681f3Smrg
32747ec681f3Smrg      /* dstSet is ignored */
32757ec681f3Smrg      desc->dstBinding = entry->dstBinding;
32767ec681f3Smrg      desc->dstArrayElement = entry->dstArrayElement;
32777ec681f3Smrg      desc->descriptorCount = entry->descriptorCount;
32787ec681f3Smrg      desc->descriptorType = entry->descriptorType;
32797ec681f3Smrg      desc->pImageInfo = (const VkDescriptorImageInfo *) next_info;
32807ec681f3Smrg      desc->pTexelBufferView = (const VkBufferView *) next_info;
32817ec681f3Smrg      desc->pBufferInfo = (const VkDescriptorBufferInfo *) next_info;
32827ec681f3Smrg
32837ec681f3Smrg      for (unsigned j = 0; j < desc->descriptorCount; j++) {
32847ec681f3Smrg         switch (desc->descriptorType) {
32857ec681f3Smrg         case VK_DESCRIPTOR_TYPE_SAMPLER:
32867ec681f3Smrg         case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
32877ec681f3Smrg         case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
32887ec681f3Smrg         case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
32897ec681f3Smrg         case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
32907ec681f3Smrg            memcpy((VkDescriptorImageInfo*)&desc->pImageInfo[j], pSrc, sizeof(VkDescriptorImageInfo));
32917ec681f3Smrg            next_info += sizeof(VkDescriptorImageInfo);
32927ec681f3Smrg            pSrc += sizeof(VkDescriptorImageInfo);
32937ec681f3Smrg            break;
32947ec681f3Smrg         case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
32957ec681f3Smrg         case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
32967ec681f3Smrg            memcpy((VkBufferView*)&desc->pTexelBufferView[j], pSrc, sizeof(VkBufferView));
32977ec681f3Smrg            next_info += sizeof(VkBufferView);
32987ec681f3Smrg            pSrc += sizeof(VkBufferView);
32997ec681f3Smrg            break;
33007ec681f3Smrg         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
33017ec681f3Smrg         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
33027ec681f3Smrg         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
33037ec681f3Smrg         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
33047ec681f3Smrg         default:
33057ec681f3Smrg            memcpy((VkDescriptorBufferInfo*)&desc->pBufferInfo[j], pSrc, sizeof(VkDescriptorBufferInfo));
33067ec681f3Smrg            next_info += sizeof(VkDescriptorBufferInfo);
33077ec681f3Smrg            pSrc += sizeof(VkDescriptorBufferInfo);
33087ec681f3Smrg            break;
33097ec681f3Smrg         }
33107ec681f3Smrg      }
33117ec681f3Smrg   }
33127ec681f3Smrg   handle_push_descriptor_set_generic(pds, state);
33137ec681f3Smrg   free(pds);
33147ec681f3Smrg}
33157ec681f3Smrg
33167ec681f3Smrgstatic void handle_bind_transform_feedback_buffers(struct vk_cmd_queue_entry *cmd,
33177ec681f3Smrg                                                   struct rendering_state *state)
33187ec681f3Smrg{
33197ec681f3Smrg   struct vk_cmd_bind_transform_feedback_buffers_ext *btfb = &cmd->u.bind_transform_feedback_buffers_ext;
33207ec681f3Smrg
33217ec681f3Smrg   for (unsigned i = 0; i < btfb->binding_count; i++) {
33227ec681f3Smrg      int idx = i + btfb->first_binding;
33237ec681f3Smrg      uint32_t size;
33247ec681f3Smrg      if (btfb->sizes && btfb->sizes[i] != VK_WHOLE_SIZE)
33257ec681f3Smrg         size = btfb->sizes[i];
33267ec681f3Smrg      else
33277ec681f3Smrg         size = lvp_buffer_from_handle(btfb->buffers[i])->size - btfb->offsets[i];
33287ec681f3Smrg
33297ec681f3Smrg      if (state->so_targets[idx])
33307ec681f3Smrg         state->pctx->stream_output_target_destroy(state->pctx, state->so_targets[idx]);
33317ec681f3Smrg
33327ec681f3Smrg      state->so_targets[idx] = state->pctx->create_stream_output_target(state->pctx,
33337ec681f3Smrg                                                                        lvp_buffer_from_handle(btfb->buffers[i])->bo,
33347ec681f3Smrg                                                                        btfb->offsets[i],
33357ec681f3Smrg                                                                        size);
33367ec681f3Smrg   }
33377ec681f3Smrg   state->num_so_targets = btfb->first_binding + btfb->binding_count;
33387ec681f3Smrg}
33397ec681f3Smrg
33407ec681f3Smrgstatic void handle_begin_transform_feedback(struct vk_cmd_queue_entry *cmd,
33417ec681f3Smrg                                            struct rendering_state *state)
33427ec681f3Smrg{
33437ec681f3Smrg   struct vk_cmd_begin_transform_feedback_ext *btf = &cmd->u.begin_transform_feedback_ext;
33447ec681f3Smrg   uint32_t offsets[4];
33457ec681f3Smrg
33467ec681f3Smrg   memset(offsets, 0, sizeof(uint32_t)*4);
33477ec681f3Smrg
33487ec681f3Smrg   for (unsigned i = 0; i < btf->counter_buffer_count; i++) {
33497ec681f3Smrg      if (!btf->counter_buffers[i])
33507ec681f3Smrg         continue;
33517ec681f3Smrg
33527ec681f3Smrg      pipe_buffer_read(state->pctx,
33537ec681f3Smrg                       btf->counter_buffers ? lvp_buffer_from_handle(btf->counter_buffers[i])->bo : NULL,
33547ec681f3Smrg                       btf->counter_buffer_offsets ? btf->counter_buffer_offsets[i] : 0,
33557ec681f3Smrg                       4,
33567ec681f3Smrg                       &offsets[i]);
33577ec681f3Smrg   }
33587ec681f3Smrg   state->pctx->set_stream_output_targets(state->pctx, state->num_so_targets,
33597ec681f3Smrg                                          state->so_targets, offsets);
33607ec681f3Smrg}
33617ec681f3Smrg
33627ec681f3Smrgstatic void handle_end_transform_feedback(struct vk_cmd_queue_entry *cmd,
33637ec681f3Smrg                                          struct rendering_state *state)
33647ec681f3Smrg{
33657ec681f3Smrg   struct vk_cmd_end_transform_feedback_ext *etf = &cmd->u.end_transform_feedback_ext;
33667ec681f3Smrg
33677ec681f3Smrg   if (etf->counter_buffer_count) {
33687ec681f3Smrg      for (unsigned i = 0; i < etf->counter_buffer_count; i++) {
33697ec681f3Smrg         if (!etf->counter_buffers[i])
33707ec681f3Smrg            continue;
33717ec681f3Smrg
33727ec681f3Smrg         uint32_t offset;
33737ec681f3Smrg         offset = state->pctx->stream_output_target_offset(state->so_targets[i]);
33747ec681f3Smrg
33757ec681f3Smrg         pipe_buffer_write(state->pctx,
33767ec681f3Smrg                           etf->counter_buffers ? lvp_buffer_from_handle(etf->counter_buffers[i])->bo : NULL,
33777ec681f3Smrg                           etf->counter_buffer_offsets ? etf->counter_buffer_offsets[i] : 0,
33787ec681f3Smrg                           4,
33797ec681f3Smrg                           &offset);
33807ec681f3Smrg      }
33817ec681f3Smrg   }
33827ec681f3Smrg   state->pctx->set_stream_output_targets(state->pctx, 0, NULL, NULL);
33837ec681f3Smrg}
33847ec681f3Smrg
33857ec681f3Smrgstatic void handle_draw_indirect_byte_count(struct vk_cmd_queue_entry *cmd,
33867ec681f3Smrg                                            struct rendering_state *state)
33877ec681f3Smrg{
33887ec681f3Smrg   struct vk_cmd_draw_indirect_byte_count_ext *dibc = &cmd->u.draw_indirect_byte_count_ext;
33897ec681f3Smrg   const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
33907ec681f3Smrg   struct pipe_draw_start_count_bias draw = {0};
33917ec681f3Smrg
33927ec681f3Smrg   pipe_buffer_read(state->pctx,
33937ec681f3Smrg                    lvp_buffer_from_handle(dibc->counter_buffer)->bo,
33947ec681f3Smrg                    lvp_buffer_from_handle(dibc->counter_buffer)->offset + dibc->counter_buffer_offset,
33957ec681f3Smrg                    4, &draw.count);
33967ec681f3Smrg
33977ec681f3Smrg   state->info.start_instance = cmd->u.draw_indirect_byte_count_ext.first_instance;
33987ec681f3Smrg   state->info.instance_count = cmd->u.draw_indirect_byte_count_ext.instance_count;
33997ec681f3Smrg   state->info.index_size = 0;
34007ec681f3Smrg
34017ec681f3Smrg   draw.count /= cmd->u.draw_indirect_byte_count_ext.vertex_stride;
34027ec681f3Smrg   state->info.view_mask = subpass->view_mask;
34037ec681f3Smrg   state->pctx->set_patch_vertices(state->pctx, state->patch_vertices);
34047ec681f3Smrg   state->pctx->draw_vbo(state->pctx, &state->info, 0, &state->indirect_info, &draw, 1);
34057ec681f3Smrg}
34067ec681f3Smrg
34077ec681f3Smrgstatic void handle_begin_conditional_rendering(struct vk_cmd_queue_entry *cmd,
34087ec681f3Smrg                                               struct rendering_state *state)
34097ec681f3Smrg{
34107ec681f3Smrg   struct VkConditionalRenderingBeginInfoEXT *bcr = cmd->u.begin_conditional_rendering_ext.conditional_rendering_begin;
34117ec681f3Smrg   state->pctx->render_condition_mem(state->pctx,
34127ec681f3Smrg                                     lvp_buffer_from_handle(bcr->buffer)->bo,
34137ec681f3Smrg                                     lvp_buffer_from_handle(bcr->buffer)->offset + bcr->offset,
34147ec681f3Smrg                                     bcr->flags & VK_CONDITIONAL_RENDERING_INVERTED_BIT_EXT);
34157ec681f3Smrg}
34167ec681f3Smrg
34177ec681f3Smrgstatic void handle_end_conditional_rendering(struct rendering_state *state)
34187ec681f3Smrg{
34197ec681f3Smrg   state->pctx->render_condition_mem(state->pctx, NULL, 0, false);
34207ec681f3Smrg}
34217ec681f3Smrg
34227ec681f3Smrgstatic void handle_set_vertex_input(struct vk_cmd_queue_entry *cmd,
34237ec681f3Smrg                                    struct rendering_state *state)
34247ec681f3Smrg{
34257ec681f3Smrg   const struct vk_cmd_set_vertex_input_ext *vertex_input = &cmd->u.set_vertex_input_ext;
34267ec681f3Smrg   const struct VkVertexInputBindingDescription2EXT *bindings = vertex_input->vertex_binding_descriptions;
34277ec681f3Smrg   const struct VkVertexInputAttributeDescription2EXT *attrs = vertex_input->vertex_attribute_descriptions;
34287ec681f3Smrg   int max_location = -1;
34297ec681f3Smrg   for (unsigned i = 0; i < vertex_input->vertex_attribute_description_count; i++) {
34307ec681f3Smrg      const struct VkVertexInputBindingDescription2EXT *binding = NULL;
34317ec681f3Smrg      unsigned location = attrs[i].location;
34327ec681f3Smrg
34337ec681f3Smrg      for (unsigned j = 0; j < vertex_input->vertex_binding_description_count; j++) {
34347ec681f3Smrg         const struct VkVertexInputBindingDescription2EXT *b = &bindings[j];
34357ec681f3Smrg         if (b->binding == attrs[i].binding) {
34367ec681f3Smrg            binding = b;
34377ec681f3Smrg            break;
34387ec681f3Smrg         }
34397ec681f3Smrg      }
34407ec681f3Smrg      assert(binding);
34417ec681f3Smrg      state->velem.velems[location].src_offset = attrs[i].offset;
34427ec681f3Smrg      state->velem.velems[location].vertex_buffer_index = attrs[i].binding;
34437ec681f3Smrg      state->velem.velems[location].src_format = lvp_vk_format_to_pipe_format(attrs[i].format);
34447ec681f3Smrg      state->vb[attrs[i].binding].stride = binding->stride;
34457ec681f3Smrg
34467ec681f3Smrg      switch (binding->inputRate) {
34477ec681f3Smrg      case VK_VERTEX_INPUT_RATE_VERTEX:
34487ec681f3Smrg         state->velem.velems[location].instance_divisor = 0;
34497ec681f3Smrg         break;
34507ec681f3Smrg      case VK_VERTEX_INPUT_RATE_INSTANCE:
34517ec681f3Smrg         state->velem.velems[location].instance_divisor = binding->divisor;
34527ec681f3Smrg         break;
34537ec681f3Smrg      default:
34547ec681f3Smrg         assert(0);
34557ec681f3Smrg         break;
34567ec681f3Smrg      }
34577ec681f3Smrg
34587ec681f3Smrg      if ((int)location > max_location)
34597ec681f3Smrg         max_location = location;
34607ec681f3Smrg   }
34617ec681f3Smrg   state->velem.count = max_location + 1;
34627ec681f3Smrg   state->vb_dirty = true;
34637ec681f3Smrg   state->ve_dirty = true;
34647ec681f3Smrg}
34657ec681f3Smrg
34667ec681f3Smrgstatic void handle_set_cull_mode(struct vk_cmd_queue_entry *cmd,
34677ec681f3Smrg                                 struct rendering_state *state)
34687ec681f3Smrg{
34697ec681f3Smrg   state->rs_state.cull_face = vk_cull_to_pipe(cmd->u.set_cull_mode_ext.cull_mode);
34707ec681f3Smrg   state->rs_dirty = true;
34717ec681f3Smrg}
34727ec681f3Smrg
34737ec681f3Smrgstatic void handle_set_front_face(struct vk_cmd_queue_entry *cmd,
34747ec681f3Smrg                                  struct rendering_state *state)
34757ec681f3Smrg{
34767ec681f3Smrg   state->rs_state.front_ccw = (cmd->u.set_front_face_ext.front_face == VK_FRONT_FACE_COUNTER_CLOCKWISE);
34777ec681f3Smrg   state->rs_dirty = true;
34787ec681f3Smrg}
34797ec681f3Smrg
34807ec681f3Smrgstatic void handle_set_primitive_topology(struct vk_cmd_queue_entry *cmd,
34817ec681f3Smrg                                          struct rendering_state *state)
34827ec681f3Smrg{
34837ec681f3Smrg   state->info.mode = vk_conv_topology(cmd->u.set_primitive_topology_ext.primitive_topology);
34847ec681f3Smrg   state->rs_dirty = true;
34857ec681f3Smrg}
34867ec681f3Smrg
34877ec681f3Smrg
34887ec681f3Smrgstatic void handle_set_depth_test_enable(struct vk_cmd_queue_entry *cmd,
34897ec681f3Smrg                                         struct rendering_state *state)
34907ec681f3Smrg{
34917ec681f3Smrg   state->dsa_dirty |= state->dsa_state.depth_enabled != cmd->u.set_depth_test_enable_ext.depth_test_enable;
34927ec681f3Smrg   state->dsa_state.depth_enabled = cmd->u.set_depth_test_enable_ext.depth_test_enable;
34937ec681f3Smrg}
34947ec681f3Smrg
34957ec681f3Smrgstatic void handle_set_depth_write_enable(struct vk_cmd_queue_entry *cmd,
34967ec681f3Smrg                                          struct rendering_state *state)
34977ec681f3Smrg{
34987ec681f3Smrg   state->dsa_dirty |= state->dsa_state.depth_writemask != cmd->u.set_depth_write_enable_ext.depth_write_enable;
34997ec681f3Smrg   state->dsa_state.depth_writemask = cmd->u.set_depth_write_enable_ext.depth_write_enable;
35007ec681f3Smrg}
35017ec681f3Smrg
35027ec681f3Smrgstatic void handle_set_depth_compare_op(struct vk_cmd_queue_entry *cmd,
35037ec681f3Smrg                                        struct rendering_state *state)
35047ec681f3Smrg{
35057ec681f3Smrg   state->dsa_dirty |= state->dsa_state.depth_func != cmd->u.set_depth_compare_op_ext.depth_compare_op;
35067ec681f3Smrg   state->dsa_state.depth_func = cmd->u.set_depth_compare_op_ext.depth_compare_op;
35077ec681f3Smrg}
35087ec681f3Smrg
35097ec681f3Smrgstatic void handle_set_depth_bounds_test_enable(struct vk_cmd_queue_entry *cmd,
35107ec681f3Smrg                                                struct rendering_state *state)
35117ec681f3Smrg{
35127ec681f3Smrg   state->dsa_dirty |= state->dsa_state.depth_bounds_test != cmd->u.set_depth_bounds_test_enable_ext.depth_bounds_test_enable;
35137ec681f3Smrg   state->dsa_state.depth_bounds_test = cmd->u.set_depth_bounds_test_enable_ext.depth_bounds_test_enable;
35147ec681f3Smrg}
35157ec681f3Smrg
35167ec681f3Smrgstatic void handle_set_stencil_test_enable(struct vk_cmd_queue_entry *cmd,
35177ec681f3Smrg                                           struct rendering_state *state)
35187ec681f3Smrg{
35197ec681f3Smrg   state->dsa_dirty |= state->dsa_state.stencil[0].enabled != cmd->u.set_stencil_test_enable_ext.stencil_test_enable ||
35207ec681f3Smrg                       state->dsa_state.stencil[1].enabled != cmd->u.set_stencil_test_enable_ext.stencil_test_enable;
35217ec681f3Smrg   state->dsa_state.stencil[0].enabled = cmd->u.set_stencil_test_enable_ext.stencil_test_enable;
35227ec681f3Smrg   state->dsa_state.stencil[1].enabled = cmd->u.set_stencil_test_enable_ext.stencil_test_enable;
35237ec681f3Smrg}
35247ec681f3Smrg
35257ec681f3Smrgstatic void handle_set_stencil_op(struct vk_cmd_queue_entry *cmd,
35267ec681f3Smrg                                  struct rendering_state *state)
35277ec681f3Smrg{
35287ec681f3Smrg   if (cmd->u.set_stencil_op_ext.face_mask & VK_STENCIL_FACE_FRONT_BIT) {
35297ec681f3Smrg      state->dsa_state.stencil[0].func = cmd->u.set_stencil_op_ext.compare_op;
35307ec681f3Smrg      state->dsa_state.stencil[0].fail_op = vk_conv_stencil_op(cmd->u.set_stencil_op_ext.fail_op);
35317ec681f3Smrg      state->dsa_state.stencil[0].zpass_op = vk_conv_stencil_op(cmd->u.set_stencil_op_ext.pass_op);
35327ec681f3Smrg      state->dsa_state.stencil[0].zfail_op = vk_conv_stencil_op(cmd->u.set_stencil_op_ext.depth_fail_op);
35337ec681f3Smrg   }
35347ec681f3Smrg
35357ec681f3Smrg   if (cmd->u.set_stencil_op_ext.face_mask & VK_STENCIL_FACE_BACK_BIT) {
35367ec681f3Smrg      state->dsa_state.stencil[1].func = cmd->u.set_stencil_op_ext.compare_op;
35377ec681f3Smrg      state->dsa_state.stencil[1].fail_op = vk_conv_stencil_op(cmd->u.set_stencil_op_ext.fail_op);
35387ec681f3Smrg      state->dsa_state.stencil[1].zpass_op = vk_conv_stencil_op(cmd->u.set_stencil_op_ext.pass_op);
35397ec681f3Smrg      state->dsa_state.stencil[1].zfail_op = vk_conv_stencil_op(cmd->u.set_stencil_op_ext.depth_fail_op);
35407ec681f3Smrg   }
35417ec681f3Smrg   state->dsa_dirty = true;
35427ec681f3Smrg}
35437ec681f3Smrg
35447ec681f3Smrgstatic void handle_set_line_stipple(struct vk_cmd_queue_entry *cmd,
35457ec681f3Smrg                                    struct rendering_state *state)
35467ec681f3Smrg{
35477ec681f3Smrg   state->rs_state.line_stipple_factor = cmd->u.set_line_stipple_ext.line_stipple_factor - 1;
35487ec681f3Smrg   state->rs_state.line_stipple_pattern = cmd->u.set_line_stipple_ext.line_stipple_pattern;
35497ec681f3Smrg   state->rs_dirty = true;
35507ec681f3Smrg}
35517ec681f3Smrg
35527ec681f3Smrgstatic void handle_set_depth_bias_enable(struct vk_cmd_queue_entry *cmd,
35537ec681f3Smrg                                         struct rendering_state *state)
35547ec681f3Smrg{
35557ec681f3Smrg   state->rs_dirty |= state->depth_bias.enabled != cmd->u.set_depth_bias_enable_ext.depth_bias_enable;
35567ec681f3Smrg   state->depth_bias.enabled = cmd->u.set_depth_bias_enable_ext.depth_bias_enable;
35577ec681f3Smrg}
35587ec681f3Smrg
35597ec681f3Smrgstatic void handle_set_logic_op(struct vk_cmd_queue_entry *cmd,
35607ec681f3Smrg                                struct rendering_state *state)
35617ec681f3Smrg{
35627ec681f3Smrg   unsigned op = vk_conv_logic_op(cmd->u.set_logic_op_ext.logic_op);
35637ec681f3Smrg   state->rs_dirty |= state->blend_state.logicop_func != op;
35647ec681f3Smrg   state->blend_state.logicop_func = op;
35657ec681f3Smrg}
35667ec681f3Smrg
35677ec681f3Smrgstatic void handle_set_patch_control_points(struct vk_cmd_queue_entry *cmd,
35687ec681f3Smrg                                            struct rendering_state *state)
35697ec681f3Smrg{
35707ec681f3Smrg   state->patch_vertices = cmd->u.set_patch_control_points_ext.patch_control_points;
35717ec681f3Smrg}
35727ec681f3Smrg
35737ec681f3Smrgstatic void handle_set_primitive_restart_enable(struct vk_cmd_queue_entry *cmd,
35747ec681f3Smrg                                                struct rendering_state *state)
35757ec681f3Smrg{
35767ec681f3Smrg   state->info.primitive_restart = cmd->u.set_primitive_restart_enable_ext.primitive_restart_enable;
35777ec681f3Smrg}
35787ec681f3Smrg
35797ec681f3Smrgstatic void handle_set_rasterizer_discard_enable(struct vk_cmd_queue_entry *cmd,
35807ec681f3Smrg                                                 struct rendering_state *state)
35817ec681f3Smrg{
35827ec681f3Smrg   state->rs_dirty |= state->rs_state.rasterizer_discard != cmd->u.set_rasterizer_discard_enable_ext.rasterizer_discard_enable;
35837ec681f3Smrg   state->rs_state.rasterizer_discard = cmd->u.set_rasterizer_discard_enable_ext.rasterizer_discard_enable;
35847ec681f3Smrg}
35857ec681f3Smrg
35867ec681f3Smrgstatic void handle_set_color_write_enable(struct vk_cmd_queue_entry *cmd,
35877ec681f3Smrg                                          struct rendering_state *state)
35887ec681f3Smrg{
35897ec681f3Smrg   uint8_t disable_mask = 0; //PIPE_MAX_COLOR_BUFS is max attachment count
35907ec681f3Smrg
35917ec681f3Smrg   for (unsigned i = 0; i < cmd->u.set_color_write_enable_ext.attachment_count; i++) {
35927ec681f3Smrg      /* this is inverted because cmdbufs are zero-initialized, meaning only 'true'
35937ec681f3Smrg       * can be detected with a bool, and the default is to enable color writes
35947ec681f3Smrg       */
35957ec681f3Smrg      if (cmd->u.set_color_write_enable_ext.color_write_enables[i] != VK_TRUE)
35967ec681f3Smrg         disable_mask |= BITFIELD_BIT(i);
35977ec681f3Smrg   }
35987ec681f3Smrg
35997ec681f3Smrg   state->blend_dirty |= state->color_write_disables != disable_mask;
36007ec681f3Smrg   state->color_write_disables = disable_mask;
36017ec681f3Smrg}
36027ec681f3Smrg
36037ec681f3Smrgstatic void lvp_execute_cmd_buffer(struct lvp_cmd_buffer *cmd_buffer,
36047ec681f3Smrg                                   struct rendering_state *state)
36057ec681f3Smrg{
36067ec681f3Smrg   struct vk_cmd_queue_entry *cmd;
36077ec681f3Smrg   bool first = true;
36087ec681f3Smrg   bool did_flush = false;
36097ec681f3Smrg
36107ec681f3Smrg   LIST_FOR_EACH_ENTRY(cmd, &cmd_buffer->queue.cmds, cmd_link) {
36117ec681f3Smrg      switch (cmd->type) {
36127ec681f3Smrg      case VK_CMD_BIND_PIPELINE:
36137ec681f3Smrg         handle_pipeline(cmd, state);
36147ec681f3Smrg         break;
36157ec681f3Smrg      case VK_CMD_SET_VIEWPORT:
36167ec681f3Smrg         handle_set_viewport(cmd, state);
36177ec681f3Smrg         break;
36187ec681f3Smrg      case VK_CMD_SET_VIEWPORT_WITH_COUNT_EXT:
36197ec681f3Smrg         handle_set_viewport_with_count(cmd, state);
36207ec681f3Smrg         break;
36217ec681f3Smrg      case VK_CMD_SET_SCISSOR:
36227ec681f3Smrg         handle_set_scissor(cmd, state);
36237ec681f3Smrg         break;
36247ec681f3Smrg      case VK_CMD_SET_SCISSOR_WITH_COUNT_EXT:
36257ec681f3Smrg         handle_set_scissor_with_count(cmd, state);
36267ec681f3Smrg         break;
36277ec681f3Smrg      case VK_CMD_SET_LINE_WIDTH:
36287ec681f3Smrg         handle_set_line_width(cmd, state);
36297ec681f3Smrg         break;
36307ec681f3Smrg      case VK_CMD_SET_DEPTH_BIAS:
36317ec681f3Smrg         handle_set_depth_bias(cmd, state);
36327ec681f3Smrg         break;
36337ec681f3Smrg      case VK_CMD_SET_BLEND_CONSTANTS:
36347ec681f3Smrg         handle_set_blend_constants(cmd, state);
36357ec681f3Smrg         break;
36367ec681f3Smrg      case VK_CMD_SET_DEPTH_BOUNDS:
36377ec681f3Smrg         handle_set_depth_bounds(cmd, state);
36387ec681f3Smrg         break;
36397ec681f3Smrg      case VK_CMD_SET_STENCIL_COMPARE_MASK:
36407ec681f3Smrg         handle_set_stencil_compare_mask(cmd, state);
36417ec681f3Smrg         break;
36427ec681f3Smrg      case VK_CMD_SET_STENCIL_WRITE_MASK:
36437ec681f3Smrg         handle_set_stencil_write_mask(cmd, state);
36447ec681f3Smrg         break;
36457ec681f3Smrg      case VK_CMD_SET_STENCIL_REFERENCE:
36467ec681f3Smrg         handle_set_stencil_reference(cmd, state);
36477ec681f3Smrg         break;
36487ec681f3Smrg      case VK_CMD_BIND_DESCRIPTOR_SETS:
36497ec681f3Smrg         handle_descriptor_sets(cmd, state);
36507ec681f3Smrg         break;
36517ec681f3Smrg      case VK_CMD_BIND_INDEX_BUFFER:
36527ec681f3Smrg         handle_index_buffer(cmd, state);
36537ec681f3Smrg         break;
36547ec681f3Smrg      case VK_CMD_BIND_VERTEX_BUFFERS:
36557ec681f3Smrg         handle_vertex_buffers(cmd, state);
36567ec681f3Smrg         break;
36577ec681f3Smrg      case VK_CMD_BIND_VERTEX_BUFFERS2_EXT:
36587ec681f3Smrg         handle_vertex_buffers2(cmd, state);
36597ec681f3Smrg         break;
36607ec681f3Smrg      case VK_CMD_DRAW:
36617ec681f3Smrg         emit_state(state);
36627ec681f3Smrg         handle_draw(cmd, state);
36637ec681f3Smrg         break;
36647ec681f3Smrg      case VK_CMD_DRAW_MULTI_EXT:
36657ec681f3Smrg         emit_state(state);
36667ec681f3Smrg         handle_draw_multi(cmd, state);
36677ec681f3Smrg         break;
36687ec681f3Smrg      case VK_CMD_DRAW_INDEXED:
36697ec681f3Smrg         emit_state(state);
36707ec681f3Smrg         handle_draw_indexed(cmd, state);
36717ec681f3Smrg         break;
36727ec681f3Smrg      case VK_CMD_DRAW_INDIRECT:
36737ec681f3Smrg         emit_state(state);
36747ec681f3Smrg         handle_draw_indirect(cmd, state, false);
36757ec681f3Smrg         break;
36767ec681f3Smrg      case VK_CMD_DRAW_INDEXED_INDIRECT:
36777ec681f3Smrg         emit_state(state);
36787ec681f3Smrg         handle_draw_indirect(cmd, state, true);
36797ec681f3Smrg         break;
36807ec681f3Smrg      case VK_CMD_DRAW_MULTI_INDEXED_EXT:
36817ec681f3Smrg         emit_state(state);
36827ec681f3Smrg         handle_draw_multi_indexed(cmd, state);
36837ec681f3Smrg         break;
36847ec681f3Smrg      case VK_CMD_DISPATCH:
36857ec681f3Smrg         emit_compute_state(state);
36867ec681f3Smrg         handle_dispatch(cmd, state);
36877ec681f3Smrg         break;
36887ec681f3Smrg      case VK_CMD_DISPATCH_BASE:
36897ec681f3Smrg         emit_compute_state(state);
36907ec681f3Smrg         handle_dispatch_base(cmd, state);
36917ec681f3Smrg         break;
36927ec681f3Smrg      case VK_CMD_DISPATCH_INDIRECT:
36937ec681f3Smrg         emit_compute_state(state);
36947ec681f3Smrg         handle_dispatch_indirect(cmd, state);
36957ec681f3Smrg         break;
36967ec681f3Smrg      case VK_CMD_COPY_BUFFER2_KHR:
36977ec681f3Smrg         handle_copy_buffer(cmd, state);
36987ec681f3Smrg         break;
36997ec681f3Smrg      case VK_CMD_COPY_IMAGE2_KHR:
37007ec681f3Smrg         handle_copy_image(cmd, state);
37017ec681f3Smrg         break;
37027ec681f3Smrg      case VK_CMD_BLIT_IMAGE2_KHR:
37037ec681f3Smrg         handle_blit_image(cmd, state);
37047ec681f3Smrg         break;
37057ec681f3Smrg      case VK_CMD_COPY_BUFFER_TO_IMAGE2_KHR:
37067ec681f3Smrg         handle_copy_buffer_to_image(cmd, state);
37077ec681f3Smrg         break;
37087ec681f3Smrg      case VK_CMD_COPY_IMAGE_TO_BUFFER2_KHR:
37097ec681f3Smrg         handle_copy_image_to_buffer2_khr(cmd, state);
37107ec681f3Smrg         break;
37117ec681f3Smrg      case VK_CMD_UPDATE_BUFFER:
37127ec681f3Smrg         handle_update_buffer(cmd, state);
37137ec681f3Smrg         break;
37147ec681f3Smrg      case VK_CMD_FILL_BUFFER:
37157ec681f3Smrg         handle_fill_buffer(cmd, state);
37167ec681f3Smrg         break;
37177ec681f3Smrg      case VK_CMD_CLEAR_COLOR_IMAGE:
37187ec681f3Smrg         handle_clear_color_image(cmd, state);
37197ec681f3Smrg         break;
37207ec681f3Smrg      case VK_CMD_CLEAR_DEPTH_STENCIL_IMAGE:
37217ec681f3Smrg         handle_clear_ds_image(cmd, state);
37227ec681f3Smrg         break;
37237ec681f3Smrg      case VK_CMD_CLEAR_ATTACHMENTS:
37247ec681f3Smrg         handle_clear_attachments(cmd, state);
37257ec681f3Smrg         break;
37267ec681f3Smrg      case VK_CMD_RESOLVE_IMAGE2_KHR:
37277ec681f3Smrg         handle_resolve_image(cmd, state);
37287ec681f3Smrg         break;
37297ec681f3Smrg      case VK_CMD_SET_EVENT:
37307ec681f3Smrg         handle_event_set(cmd, state);
37317ec681f3Smrg         break;
37327ec681f3Smrg      case VK_CMD_RESET_EVENT:
37337ec681f3Smrg         handle_event_reset(cmd, state);
37347ec681f3Smrg         break;
37357ec681f3Smrg      case VK_CMD_WAIT_EVENTS:
37367ec681f3Smrg         handle_wait_events(cmd, state);
37377ec681f3Smrg         break;
37387ec681f3Smrg      case VK_CMD_PIPELINE_BARRIER:
37397ec681f3Smrg         /* skip flushes since every cmdbuf does a flush
37407ec681f3Smrg            after iterating its cmds and so this is redundant
37417ec681f3Smrg          */
37427ec681f3Smrg         if (first || did_flush || cmd->cmd_link.next == &cmd_buffer->queue.cmds)
37437ec681f3Smrg            continue;
37447ec681f3Smrg         handle_pipeline_barrier(cmd, state);
37457ec681f3Smrg         did_flush = true;
37467ec681f3Smrg         continue;
37477ec681f3Smrg      case VK_CMD_BEGIN_QUERY_INDEXED_EXT:
37487ec681f3Smrg         handle_begin_query_indexed_ext(cmd, state);
37497ec681f3Smrg         break;
37507ec681f3Smrg      case VK_CMD_END_QUERY_INDEXED_EXT:
37517ec681f3Smrg         handle_end_query_indexed_ext(cmd, state);
37527ec681f3Smrg         break;
37537ec681f3Smrg      case VK_CMD_BEGIN_QUERY:
37547ec681f3Smrg         handle_begin_query(cmd, state);
37557ec681f3Smrg         break;
37567ec681f3Smrg      case VK_CMD_END_QUERY:
37577ec681f3Smrg         handle_end_query(cmd, state);
37587ec681f3Smrg         break;
37597ec681f3Smrg      case VK_CMD_RESET_QUERY_POOL:
37607ec681f3Smrg         handle_reset_query_pool(cmd, state);
37617ec681f3Smrg         break;
37627ec681f3Smrg      case VK_CMD_WRITE_TIMESTAMP:
37637ec681f3Smrg         handle_write_timestamp(cmd, state);
37647ec681f3Smrg         break;
37657ec681f3Smrg      case VK_CMD_COPY_QUERY_POOL_RESULTS:
37667ec681f3Smrg         handle_copy_query_pool_results(cmd, state);
37677ec681f3Smrg         break;
37687ec681f3Smrg      case VK_CMD_PUSH_CONSTANTS:
37697ec681f3Smrg         handle_push_constants(cmd, state);
37707ec681f3Smrg         break;
37717ec681f3Smrg      case VK_CMD_BEGIN_RENDER_PASS:
37727ec681f3Smrg         handle_begin_render_pass(cmd, state);
37737ec681f3Smrg         break;
37747ec681f3Smrg      case VK_CMD_BEGIN_RENDER_PASS2:
37757ec681f3Smrg         handle_begin_render_pass2(cmd, state);
37767ec681f3Smrg         break;
37777ec681f3Smrg      case VK_CMD_NEXT_SUBPASS:
37787ec681f3Smrg      case VK_CMD_NEXT_SUBPASS2:
37797ec681f3Smrg         handle_next_subpass2(cmd, state);
37807ec681f3Smrg         break;
37817ec681f3Smrg      case VK_CMD_END_RENDER_PASS:
37827ec681f3Smrg      case VK_CMD_END_RENDER_PASS2:
37837ec681f3Smrg         handle_end_render_pass2(cmd, state);
37847ec681f3Smrg         break;
37857ec681f3Smrg      case VK_CMD_EXECUTE_COMMANDS:
37867ec681f3Smrg         handle_execute_commands(cmd, state);
37877ec681f3Smrg         break;
37887ec681f3Smrg      case VK_CMD_DRAW_INDIRECT_COUNT:
37897ec681f3Smrg         emit_state(state);
37907ec681f3Smrg         handle_draw_indirect_count(cmd, state, false);
37917ec681f3Smrg         break;
37927ec681f3Smrg      case VK_CMD_DRAW_INDEXED_INDIRECT_COUNT:
37937ec681f3Smrg         emit_state(state);
37947ec681f3Smrg         handle_draw_indirect_count(cmd, state, true);
37957ec681f3Smrg         break;
37967ec681f3Smrg      case VK_CMD_PUSH_DESCRIPTOR_SET_KHR:
37977ec681f3Smrg         handle_push_descriptor_set(cmd, state);
37987ec681f3Smrg         break;
37997ec681f3Smrg      case VK_CMD_PUSH_DESCRIPTOR_SET_WITH_TEMPLATE_KHR:
38007ec681f3Smrg         handle_push_descriptor_set_with_template(cmd, state);
38017ec681f3Smrg         break;
38027ec681f3Smrg      case VK_CMD_BIND_TRANSFORM_FEEDBACK_BUFFERS_EXT:
38037ec681f3Smrg         handle_bind_transform_feedback_buffers(cmd, state);
38047ec681f3Smrg         break;
38057ec681f3Smrg      case VK_CMD_BEGIN_TRANSFORM_FEEDBACK_EXT:
38067ec681f3Smrg         handle_begin_transform_feedback(cmd, state);
38077ec681f3Smrg         break;
38087ec681f3Smrg      case VK_CMD_END_TRANSFORM_FEEDBACK_EXT:
38097ec681f3Smrg         handle_end_transform_feedback(cmd, state);
38107ec681f3Smrg         break;
38117ec681f3Smrg      case VK_CMD_DRAW_INDIRECT_BYTE_COUNT_EXT:
38127ec681f3Smrg         emit_state(state);
38137ec681f3Smrg         handle_draw_indirect_byte_count(cmd, state);
38147ec681f3Smrg         break;
38157ec681f3Smrg      case VK_CMD_BEGIN_CONDITIONAL_RENDERING_EXT:
38167ec681f3Smrg         handle_begin_conditional_rendering(cmd, state);
38177ec681f3Smrg         break;
38187ec681f3Smrg      case VK_CMD_END_CONDITIONAL_RENDERING_EXT:
38197ec681f3Smrg         handle_end_conditional_rendering(state);
38207ec681f3Smrg         break;
38217ec681f3Smrg      case VK_CMD_SET_VERTEX_INPUT_EXT:
38227ec681f3Smrg         handle_set_vertex_input(cmd, state);
38237ec681f3Smrg         break;
38247ec681f3Smrg      case VK_CMD_SET_CULL_MODE_EXT:
38257ec681f3Smrg         handle_set_cull_mode(cmd, state);
38267ec681f3Smrg         break;
38277ec681f3Smrg      case VK_CMD_SET_FRONT_FACE_EXT:
38287ec681f3Smrg         handle_set_front_face(cmd, state);
38297ec681f3Smrg         break;
38307ec681f3Smrg      case VK_CMD_SET_PRIMITIVE_TOPOLOGY_EXT:
38317ec681f3Smrg         handle_set_primitive_topology(cmd, state);
38327ec681f3Smrg         break;
38337ec681f3Smrg      case VK_CMD_SET_DEPTH_TEST_ENABLE_EXT:
38347ec681f3Smrg         handle_set_depth_test_enable(cmd, state);
38357ec681f3Smrg         break;
38367ec681f3Smrg      case VK_CMD_SET_DEPTH_WRITE_ENABLE_EXT:
38377ec681f3Smrg         handle_set_depth_write_enable(cmd, state);
38387ec681f3Smrg         break;
38397ec681f3Smrg      case VK_CMD_SET_DEPTH_COMPARE_OP_EXT:
38407ec681f3Smrg         handle_set_depth_compare_op(cmd, state);
38417ec681f3Smrg         break;
38427ec681f3Smrg      case VK_CMD_SET_DEPTH_BOUNDS_TEST_ENABLE_EXT:
38437ec681f3Smrg         handle_set_depth_bounds_test_enable(cmd, state);
38447ec681f3Smrg         break;
38457ec681f3Smrg      case VK_CMD_SET_STENCIL_TEST_ENABLE_EXT:
38467ec681f3Smrg         handle_set_stencil_test_enable(cmd, state);
38477ec681f3Smrg         break;
38487ec681f3Smrg      case VK_CMD_SET_STENCIL_OP_EXT:
38497ec681f3Smrg         handle_set_stencil_op(cmd, state);
38507ec681f3Smrg         break;
38517ec681f3Smrg      case VK_CMD_SET_LINE_STIPPLE_EXT:
38527ec681f3Smrg         handle_set_line_stipple(cmd, state);
38537ec681f3Smrg         break;
38547ec681f3Smrg      case VK_CMD_SET_DEPTH_BIAS_ENABLE_EXT:
38557ec681f3Smrg         handle_set_depth_bias_enable(cmd, state);
38567ec681f3Smrg         break;
38577ec681f3Smrg      case VK_CMD_SET_LOGIC_OP_EXT:
38587ec681f3Smrg         handle_set_logic_op(cmd, state);
38597ec681f3Smrg         break;
38607ec681f3Smrg      case VK_CMD_SET_PATCH_CONTROL_POINTS_EXT:
38617ec681f3Smrg         handle_set_patch_control_points(cmd, state);
38627ec681f3Smrg         break;
38637ec681f3Smrg      case VK_CMD_SET_PRIMITIVE_RESTART_ENABLE_EXT:
38647ec681f3Smrg         handle_set_primitive_restart_enable(cmd, state);
38657ec681f3Smrg         break;
38667ec681f3Smrg      case VK_CMD_SET_RASTERIZER_DISCARD_ENABLE_EXT:
38677ec681f3Smrg         handle_set_rasterizer_discard_enable(cmd, state);
38687ec681f3Smrg         break;
38697ec681f3Smrg      case VK_CMD_SET_COLOR_WRITE_ENABLE_EXT:
38707ec681f3Smrg         handle_set_color_write_enable(cmd, state);
38717ec681f3Smrg         break;
38727ec681f3Smrg      case VK_CMD_SET_DEVICE_MASK:
38737ec681f3Smrg         /* no-op */
38747ec681f3Smrg         break;
38757ec681f3Smrg      default:
38767ec681f3Smrg         fprintf(stderr, "Unsupported command %s\n", vk_cmd_queue_type_names[cmd->type]);
38777ec681f3Smrg         unreachable("Unsupported command");
38787ec681f3Smrg         break;
38797ec681f3Smrg      }
38807ec681f3Smrg      first = false;
38817ec681f3Smrg      did_flush = false;
38827ec681f3Smrg   }
38837ec681f3Smrg}
38847ec681f3Smrg
38857ec681f3SmrgVkResult lvp_execute_cmds(struct lvp_device *device,
38867ec681f3Smrg                          struct lvp_queue *queue,
38877ec681f3Smrg                          struct lvp_cmd_buffer *cmd_buffer)
38887ec681f3Smrg{
38897ec681f3Smrg   struct rendering_state state;
38907ec681f3Smrg   memset(&state, 0, sizeof(state));
38917ec681f3Smrg   state.pctx = queue->ctx;
38927ec681f3Smrg   state.cso = queue->cso;
38937ec681f3Smrg   state.blend_dirty = true;
38947ec681f3Smrg   state.dsa_dirty = true;
38957ec681f3Smrg   state.rs_dirty = true;
38967ec681f3Smrg   state.vp_dirty = true;
38977ec681f3Smrg   for (enum pipe_shader_type s = PIPE_SHADER_VERTEX; s < PIPE_SHADER_TYPES; s++) {
38987ec681f3Smrg      for (unsigned i = 0; i < PIPE_MAX_SAMPLERS; i++)
38997ec681f3Smrg         state.cso_ss_ptr[s][i] = &state.ss[s][i];
39007ec681f3Smrg   }
39017ec681f3Smrg   /* create a gallium context */
39027ec681f3Smrg   lvp_execute_cmd_buffer(cmd_buffer, &state);
39037ec681f3Smrg
39047ec681f3Smrg   state.start_vb = -1;
39057ec681f3Smrg   state.num_vb = 0;
39067ec681f3Smrg   cso_unbind_context(queue->cso);
39077ec681f3Smrg   for (unsigned i = 0; i < PIPE_MAX_SO_BUFFERS; i++) {
39087ec681f3Smrg      if (state.so_targets[i]) {
39097ec681f3Smrg         state.pctx->stream_output_target_destroy(state.pctx, state.so_targets[i]);
39107ec681f3Smrg      }
39117ec681f3Smrg   }
39127ec681f3Smrg
39137ec681f3Smrg   for (enum pipe_shader_type s = PIPE_SHADER_VERTEX; s < PIPE_SHADER_TYPES; s++) {
39147ec681f3Smrg      for (unsigned i = 0; i < PIPE_MAX_SAMPLERS; i++) {
39157ec681f3Smrg         if (state.sv[s][i])
39167ec681f3Smrg            pipe_sampler_view_reference(&state.sv[s][i], NULL);
39177ec681f3Smrg      }
39187ec681f3Smrg   }
39197ec681f3Smrg
39207ec681f3Smrg   for (unsigned i = 0; i < PIPE_MAX_SAMPLERS; i++) {
39217ec681f3Smrg      if (state.cso_ss_ptr[PIPE_SHADER_COMPUTE][i])
39227ec681f3Smrg         state.pctx->delete_sampler_state(state.pctx, state.ss_cso[PIPE_SHADER_COMPUTE][i]);
39237ec681f3Smrg   }
39247ec681f3Smrg
39257ec681f3Smrg   free(state.imageless_views);
39267ec681f3Smrg   free(state.pending_clear_aspects);
39277ec681f3Smrg   free(state.cleared_views);
39287ec681f3Smrg   free(state.attachments);
39297ec681f3Smrg   return VK_SUCCESS;
39307ec681f3Smrg}
3931