1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright © 2021 Collabora Ltd.
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Derived from tu_cmd_buffer.c which is:
5bf215546Sopenharmony_ci * Copyright © 2016 Red Hat.
6bf215546Sopenharmony_ci * Copyright © 2016 Bas Nieuwenhuizen
7bf215546Sopenharmony_ci * Copyright © 2015 Intel Corporation
8bf215546Sopenharmony_ci *
9bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
10bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
11bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
12bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
14bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
15bf215546Sopenharmony_ci *
16bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
17bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
18bf215546Sopenharmony_ci * Software.
19bf215546Sopenharmony_ci *
20bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
23bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE.
27bf215546Sopenharmony_ci */
28bf215546Sopenharmony_ci
29bf215546Sopenharmony_ci#include "panvk_private.h"
30bf215546Sopenharmony_ci
31bf215546Sopenharmony_ci#include "pan_encoder.h"
32bf215546Sopenharmony_ci
33bf215546Sopenharmony_ci#include "util/rounding.h"
34bf215546Sopenharmony_ci#include "vk_format.h"
35bf215546Sopenharmony_ci
36bf215546Sopenharmony_civoid
37bf215546Sopenharmony_cipanvk_CmdBindVertexBuffers(VkCommandBuffer commandBuffer,
38bf215546Sopenharmony_ci                           uint32_t firstBinding,
39bf215546Sopenharmony_ci                           uint32_t bindingCount,
40bf215546Sopenharmony_ci                           const VkBuffer *pBuffers,
41bf215546Sopenharmony_ci                           const VkDeviceSize *pOffsets)
42bf215546Sopenharmony_ci{
43bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
44bf215546Sopenharmony_ci   struct panvk_descriptor_state *desc_state =
45bf215546Sopenharmony_ci      panvk_cmd_get_desc_state(cmdbuf, GRAPHICS);
46bf215546Sopenharmony_ci
47bf215546Sopenharmony_ci   assert(firstBinding + bindingCount <= MAX_VBS);
48bf215546Sopenharmony_ci
49bf215546Sopenharmony_ci   for (uint32_t i = 0; i < bindingCount; i++) {
50bf215546Sopenharmony_ci      VK_FROM_HANDLE(panvk_buffer, buffer, pBuffers[i]);
51bf215546Sopenharmony_ci
52bf215546Sopenharmony_ci      cmdbuf->state.vb.bufs[firstBinding + i].address =
53bf215546Sopenharmony_ci         panvk_buffer_gpu_ptr(buffer, pOffsets[i]);
54bf215546Sopenharmony_ci      cmdbuf->state.vb.bufs[firstBinding + i].size =
55bf215546Sopenharmony_ci         panvk_buffer_range(buffer, pOffsets[i], VK_WHOLE_SIZE);
56bf215546Sopenharmony_ci   }
57bf215546Sopenharmony_ci
58bf215546Sopenharmony_ci   cmdbuf->state.vb.count = MAX2(cmdbuf->state.vb.count, firstBinding + bindingCount);
59bf215546Sopenharmony_ci   desc_state->vs_attrib_bufs = desc_state->vs_attribs = 0;
60bf215546Sopenharmony_ci}
61bf215546Sopenharmony_ci
62bf215546Sopenharmony_civoid
63bf215546Sopenharmony_cipanvk_CmdBindIndexBuffer(VkCommandBuffer commandBuffer,
64bf215546Sopenharmony_ci                         VkBuffer buffer,
65bf215546Sopenharmony_ci                         VkDeviceSize offset,
66bf215546Sopenharmony_ci                         VkIndexType indexType)
67bf215546Sopenharmony_ci{
68bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
69bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_buffer, buf, buffer);
70bf215546Sopenharmony_ci
71bf215546Sopenharmony_ci   cmdbuf->state.ib.buffer = buf;
72bf215546Sopenharmony_ci   cmdbuf->state.ib.offset = offset;
73bf215546Sopenharmony_ci   switch (indexType) {
74bf215546Sopenharmony_ci   case VK_INDEX_TYPE_UINT16:
75bf215546Sopenharmony_ci      cmdbuf->state.ib.index_size = 16;
76bf215546Sopenharmony_ci      break;
77bf215546Sopenharmony_ci   case VK_INDEX_TYPE_UINT32:
78bf215546Sopenharmony_ci      cmdbuf->state.ib.index_size = 32;
79bf215546Sopenharmony_ci      break;
80bf215546Sopenharmony_ci   case VK_INDEX_TYPE_NONE_KHR:
81bf215546Sopenharmony_ci      cmdbuf->state.ib.index_size = 0;
82bf215546Sopenharmony_ci      break;
83bf215546Sopenharmony_ci   case VK_INDEX_TYPE_UINT8_EXT:
84bf215546Sopenharmony_ci      cmdbuf->state.ib.index_size = 8;
85bf215546Sopenharmony_ci      break;
86bf215546Sopenharmony_ci   default:
87bf215546Sopenharmony_ci      unreachable("Invalid index type\n");
88bf215546Sopenharmony_ci   }
89bf215546Sopenharmony_ci}
90bf215546Sopenharmony_ci
91bf215546Sopenharmony_cistatic void
92bf215546Sopenharmony_cipanvk_set_dyn_ssbo_pointers(struct panvk_descriptor_state *desc_state,
93bf215546Sopenharmony_ci                            unsigned dyn_ssbo_offset,
94bf215546Sopenharmony_ci                            struct panvk_descriptor_set *set)
95bf215546Sopenharmony_ci{
96bf215546Sopenharmony_ci   struct panvk_sysvals *sysvals = &desc_state->sysvals;
97bf215546Sopenharmony_ci
98bf215546Sopenharmony_ci   for (unsigned i = 0; i < set->layout->num_dyn_ssbos; i++) {
99bf215546Sopenharmony_ci      const struct panvk_buffer_desc *ssbo =
100bf215546Sopenharmony_ci         &desc_state->dyn.ssbos[dyn_ssbo_offset + i];
101bf215546Sopenharmony_ci
102bf215546Sopenharmony_ci      sysvals->dyn_ssbos[dyn_ssbo_offset + i] = (struct panvk_ssbo_addr) {
103bf215546Sopenharmony_ci         .base_addr = panvk_buffer_gpu_ptr(ssbo->buffer, ssbo->offset),
104bf215546Sopenharmony_ci         .size = panvk_buffer_range(ssbo->buffer, ssbo->offset, ssbo->size),
105bf215546Sopenharmony_ci      };
106bf215546Sopenharmony_ci   }
107bf215546Sopenharmony_ci
108bf215546Sopenharmony_ci   desc_state->sysvals_ptr = 0;
109bf215546Sopenharmony_ci}
110bf215546Sopenharmony_ci
111bf215546Sopenharmony_civoid
112bf215546Sopenharmony_cipanvk_CmdBindDescriptorSets(VkCommandBuffer commandBuffer,
113bf215546Sopenharmony_ci                            VkPipelineBindPoint pipelineBindPoint,
114bf215546Sopenharmony_ci                            VkPipelineLayout layout,
115bf215546Sopenharmony_ci                            uint32_t firstSet,
116bf215546Sopenharmony_ci                            uint32_t descriptorSetCount,
117bf215546Sopenharmony_ci                            const VkDescriptorSet *pDescriptorSets,
118bf215546Sopenharmony_ci                            uint32_t dynamicOffsetCount,
119bf215546Sopenharmony_ci                            const uint32_t *pDynamicOffsets)
120bf215546Sopenharmony_ci{
121bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
122bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_pipeline_layout, playout, layout);
123bf215546Sopenharmony_ci
124bf215546Sopenharmony_ci   struct panvk_descriptor_state *descriptors_state =
125bf215546Sopenharmony_ci      &cmdbuf->bind_points[pipelineBindPoint].desc_state;
126bf215546Sopenharmony_ci
127bf215546Sopenharmony_ci   unsigned dynoffset_idx = 0;
128bf215546Sopenharmony_ci   for (unsigned i = 0; i < descriptorSetCount; ++i) {
129bf215546Sopenharmony_ci      unsigned idx = i + firstSet;
130bf215546Sopenharmony_ci      VK_FROM_HANDLE(panvk_descriptor_set, set, pDescriptorSets[i]);
131bf215546Sopenharmony_ci
132bf215546Sopenharmony_ci      descriptors_state->sets[idx] = set;
133bf215546Sopenharmony_ci
134bf215546Sopenharmony_ci      if (set->layout->num_dyn_ssbos || set->layout->num_dyn_ubos) {
135bf215546Sopenharmony_ci         unsigned dyn_ubo_offset = playout->sets[idx].dyn_ubo_offset;
136bf215546Sopenharmony_ci         unsigned dyn_ssbo_offset = playout->sets[idx].dyn_ssbo_offset;
137bf215546Sopenharmony_ci
138bf215546Sopenharmony_ci         for (unsigned b = 0; b < set->layout->binding_count; b++) {
139bf215546Sopenharmony_ci            for (unsigned e = 0; e < set->layout->bindings[b].array_size; e++) {
140bf215546Sopenharmony_ci               struct panvk_buffer_desc *bdesc = NULL;
141bf215546Sopenharmony_ci
142bf215546Sopenharmony_ci               if (set->layout->bindings[b].type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) {
143bf215546Sopenharmony_ci                  bdesc = &descriptors_state->dyn.ubos[dyn_ubo_offset++];
144bf215546Sopenharmony_ci                  *bdesc = set->dyn_ubos[set->layout->bindings[b].dyn_ubo_idx + e];
145bf215546Sopenharmony_ci               } else if (set->layout->bindings[b].type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) {
146bf215546Sopenharmony_ci                  bdesc = &descriptors_state->dyn.ssbos[dyn_ssbo_offset++];
147bf215546Sopenharmony_ci                  *bdesc = set->dyn_ssbos[set->layout->bindings[b].dyn_ssbo_idx + e];
148bf215546Sopenharmony_ci               }
149bf215546Sopenharmony_ci
150bf215546Sopenharmony_ci               if (bdesc) {
151bf215546Sopenharmony_ci                  bdesc->offset += pDynamicOffsets[dynoffset_idx++];
152bf215546Sopenharmony_ci               }
153bf215546Sopenharmony_ci            }
154bf215546Sopenharmony_ci         }
155bf215546Sopenharmony_ci      }
156bf215546Sopenharmony_ci
157bf215546Sopenharmony_ci      if (set->layout->num_dyn_ssbos) {
158bf215546Sopenharmony_ci         panvk_set_dyn_ssbo_pointers(descriptors_state,
159bf215546Sopenharmony_ci                                     playout->sets[idx].dyn_ssbo_offset,
160bf215546Sopenharmony_ci                                     set);
161bf215546Sopenharmony_ci      }
162bf215546Sopenharmony_ci
163bf215546Sopenharmony_ci      if (set->layout->num_dyn_ssbos)
164bf215546Sopenharmony_ci         descriptors_state->dirty |= PANVK_DYNAMIC_SSBO;
165bf215546Sopenharmony_ci
166bf215546Sopenharmony_ci      if (set->layout->num_ubos || set->layout->num_dyn_ubos ||
167bf215546Sopenharmony_ci          set->layout->num_dyn_ssbos || set->layout->desc_ubo_size)
168bf215546Sopenharmony_ci         descriptors_state->ubos = 0;
169bf215546Sopenharmony_ci
170bf215546Sopenharmony_ci      if (set->layout->num_textures)
171bf215546Sopenharmony_ci         descriptors_state->textures = 0;
172bf215546Sopenharmony_ci
173bf215546Sopenharmony_ci      if (set->layout->num_samplers)
174bf215546Sopenharmony_ci         descriptors_state->samplers = 0;
175bf215546Sopenharmony_ci
176bf215546Sopenharmony_ci      if (set->layout->num_imgs) {
177bf215546Sopenharmony_ci         descriptors_state->vs_attrib_bufs = descriptors_state->non_vs_attrib_bufs = 0;
178bf215546Sopenharmony_ci         descriptors_state->vs_attribs = descriptors_state->non_vs_attribs = 0;
179bf215546Sopenharmony_ci      }
180bf215546Sopenharmony_ci   }
181bf215546Sopenharmony_ci
182bf215546Sopenharmony_ci   assert(dynoffset_idx == dynamicOffsetCount);
183bf215546Sopenharmony_ci}
184bf215546Sopenharmony_ci
185bf215546Sopenharmony_civoid
186bf215546Sopenharmony_cipanvk_CmdPushConstants(VkCommandBuffer commandBuffer,
187bf215546Sopenharmony_ci                       VkPipelineLayout layout,
188bf215546Sopenharmony_ci                       VkShaderStageFlags stageFlags,
189bf215546Sopenharmony_ci                       uint32_t offset,
190bf215546Sopenharmony_ci                       uint32_t size,
191bf215546Sopenharmony_ci                       const void *pValues)
192bf215546Sopenharmony_ci{
193bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
194bf215546Sopenharmony_ci
195bf215546Sopenharmony_ci   memcpy(cmdbuf->push_constants + offset, pValues, size);
196bf215546Sopenharmony_ci
197bf215546Sopenharmony_ci   if (stageFlags & VK_SHADER_STAGE_ALL_GRAPHICS) {
198bf215546Sopenharmony_ci      struct panvk_descriptor_state *desc_state =
199bf215546Sopenharmony_ci         panvk_cmd_get_desc_state(cmdbuf, GRAPHICS);
200bf215546Sopenharmony_ci
201bf215546Sopenharmony_ci      desc_state->ubos = 0;
202bf215546Sopenharmony_ci      desc_state->push_constants = 0;
203bf215546Sopenharmony_ci   }
204bf215546Sopenharmony_ci
205bf215546Sopenharmony_ci   if (stageFlags & VK_SHADER_STAGE_COMPUTE_BIT) {
206bf215546Sopenharmony_ci      struct panvk_descriptor_state *desc_state =
207bf215546Sopenharmony_ci         panvk_cmd_get_desc_state(cmdbuf, COMPUTE);
208bf215546Sopenharmony_ci
209bf215546Sopenharmony_ci      desc_state->ubos = 0;
210bf215546Sopenharmony_ci      desc_state->push_constants = 0;
211bf215546Sopenharmony_ci   }
212bf215546Sopenharmony_ci}
213bf215546Sopenharmony_ci
214bf215546Sopenharmony_civoid
215bf215546Sopenharmony_cipanvk_CmdBindPipeline(VkCommandBuffer commandBuffer,
216bf215546Sopenharmony_ci                      VkPipelineBindPoint pipelineBindPoint,
217bf215546Sopenharmony_ci                      VkPipeline _pipeline)
218bf215546Sopenharmony_ci{
219bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
220bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_pipeline, pipeline, _pipeline);
221bf215546Sopenharmony_ci
222bf215546Sopenharmony_ci   cmdbuf->bind_points[pipelineBindPoint].pipeline = pipeline;
223bf215546Sopenharmony_ci   cmdbuf->state.fs_rsd = 0;
224bf215546Sopenharmony_ci
225bf215546Sopenharmony_ci   if (pipelineBindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS) {
226bf215546Sopenharmony_ci      cmdbuf->state.varyings = pipeline->varyings;
227bf215546Sopenharmony_ci
228bf215546Sopenharmony_ci      if (!(pipeline->dynamic_state_mask & BITFIELD_BIT(VK_DYNAMIC_STATE_VIEWPORT))) {
229bf215546Sopenharmony_ci         cmdbuf->state.viewport = pipeline->viewport;
230bf215546Sopenharmony_ci         cmdbuf->state.dirty |= PANVK_DYNAMIC_VIEWPORT;
231bf215546Sopenharmony_ci      }
232bf215546Sopenharmony_ci      if (!(pipeline->dynamic_state_mask & BITFIELD_BIT(VK_DYNAMIC_STATE_SCISSOR))) {
233bf215546Sopenharmony_ci         cmdbuf->state.scissor = pipeline->scissor;
234bf215546Sopenharmony_ci         cmdbuf->state.dirty |= PANVK_DYNAMIC_SCISSOR;
235bf215546Sopenharmony_ci      }
236bf215546Sopenharmony_ci   }
237bf215546Sopenharmony_ci
238bf215546Sopenharmony_ci   /* Sysvals are passed through UBOs, we need dirty the UBO array if the
239bf215546Sopenharmony_ci    * pipeline contain shaders using sysvals.
240bf215546Sopenharmony_ci    */
241bf215546Sopenharmony_ci   cmdbuf->bind_points[pipelineBindPoint].desc_state.ubos = 0;
242bf215546Sopenharmony_ci}
243bf215546Sopenharmony_ci
244bf215546Sopenharmony_civoid
245bf215546Sopenharmony_cipanvk_CmdSetViewport(VkCommandBuffer commandBuffer,
246bf215546Sopenharmony_ci                     uint32_t firstViewport,
247bf215546Sopenharmony_ci                     uint32_t viewportCount,
248bf215546Sopenharmony_ci                     const VkViewport *pViewports)
249bf215546Sopenharmony_ci{
250bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
251bf215546Sopenharmony_ci   assert(viewportCount == 1);
252bf215546Sopenharmony_ci   assert(!firstViewport);
253bf215546Sopenharmony_ci
254bf215546Sopenharmony_ci   cmdbuf->state.viewport = pViewports[0];
255bf215546Sopenharmony_ci   cmdbuf->state.vpd = 0;
256bf215546Sopenharmony_ci   cmdbuf->state.dirty |= PANVK_DYNAMIC_VIEWPORT;
257bf215546Sopenharmony_ci}
258bf215546Sopenharmony_ci
259bf215546Sopenharmony_civoid
260bf215546Sopenharmony_cipanvk_CmdSetScissor(VkCommandBuffer commandBuffer,
261bf215546Sopenharmony_ci                    uint32_t firstScissor,
262bf215546Sopenharmony_ci                    uint32_t scissorCount,
263bf215546Sopenharmony_ci                    const VkRect2D *pScissors)
264bf215546Sopenharmony_ci{
265bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
266bf215546Sopenharmony_ci   assert(scissorCount == 1);
267bf215546Sopenharmony_ci   assert(!firstScissor);
268bf215546Sopenharmony_ci
269bf215546Sopenharmony_ci   cmdbuf->state.scissor = pScissors[0];
270bf215546Sopenharmony_ci   cmdbuf->state.vpd = 0;
271bf215546Sopenharmony_ci   cmdbuf->state.dirty |= PANVK_DYNAMIC_SCISSOR;
272bf215546Sopenharmony_ci}
273bf215546Sopenharmony_ci
274bf215546Sopenharmony_civoid
275bf215546Sopenharmony_cipanvk_CmdSetLineWidth(VkCommandBuffer commandBuffer, float lineWidth)
276bf215546Sopenharmony_ci{
277bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
278bf215546Sopenharmony_ci
279bf215546Sopenharmony_ci   cmdbuf->state.rast.line_width = lineWidth;
280bf215546Sopenharmony_ci   cmdbuf->state.dirty |= PANVK_DYNAMIC_LINE_WIDTH;
281bf215546Sopenharmony_ci}
282bf215546Sopenharmony_ci
283bf215546Sopenharmony_civoid
284bf215546Sopenharmony_cipanvk_CmdSetDepthBias(VkCommandBuffer commandBuffer,
285bf215546Sopenharmony_ci                      float depthBiasConstantFactor,
286bf215546Sopenharmony_ci                      float depthBiasClamp,
287bf215546Sopenharmony_ci                      float depthBiasSlopeFactor)
288bf215546Sopenharmony_ci{
289bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
290bf215546Sopenharmony_ci
291bf215546Sopenharmony_ci   cmdbuf->state.rast.depth_bias.constant_factor = depthBiasConstantFactor;
292bf215546Sopenharmony_ci   cmdbuf->state.rast.depth_bias.clamp = depthBiasClamp;
293bf215546Sopenharmony_ci   cmdbuf->state.rast.depth_bias.slope_factor = depthBiasSlopeFactor;
294bf215546Sopenharmony_ci   cmdbuf->state.dirty |= PANVK_DYNAMIC_DEPTH_BIAS;
295bf215546Sopenharmony_ci   cmdbuf->state.fs_rsd = 0;
296bf215546Sopenharmony_ci}
297bf215546Sopenharmony_ci
298bf215546Sopenharmony_civoid
299bf215546Sopenharmony_cipanvk_CmdSetBlendConstants(VkCommandBuffer commandBuffer,
300bf215546Sopenharmony_ci                           const float blendConstants[4])
301bf215546Sopenharmony_ci{
302bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
303bf215546Sopenharmony_ci
304bf215546Sopenharmony_ci   for (unsigned i = 0; i < 4; i++)
305bf215546Sopenharmony_ci      cmdbuf->state.blend.constants[i] = CLAMP(blendConstants[i], 0.0f, 1.0f);
306bf215546Sopenharmony_ci
307bf215546Sopenharmony_ci   cmdbuf->state.dirty |= PANVK_DYNAMIC_BLEND_CONSTANTS;
308bf215546Sopenharmony_ci   cmdbuf->state.fs_rsd = 0;
309bf215546Sopenharmony_ci}
310bf215546Sopenharmony_ci
311bf215546Sopenharmony_civoid
312bf215546Sopenharmony_cipanvk_CmdSetDepthBounds(VkCommandBuffer commandBuffer,
313bf215546Sopenharmony_ci                        float minDepthBounds,
314bf215546Sopenharmony_ci                        float maxDepthBounds)
315bf215546Sopenharmony_ci{
316bf215546Sopenharmony_ci   panvk_stub();
317bf215546Sopenharmony_ci}
318bf215546Sopenharmony_ci
319bf215546Sopenharmony_civoid
320bf215546Sopenharmony_cipanvk_CmdSetStencilCompareMask(VkCommandBuffer commandBuffer,
321bf215546Sopenharmony_ci                               VkStencilFaceFlags faceMask,
322bf215546Sopenharmony_ci                               uint32_t compareMask)
323bf215546Sopenharmony_ci{
324bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
325bf215546Sopenharmony_ci
326bf215546Sopenharmony_ci   if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
327bf215546Sopenharmony_ci      cmdbuf->state.zs.s_front.compare_mask = compareMask;
328bf215546Sopenharmony_ci
329bf215546Sopenharmony_ci   if (faceMask & VK_STENCIL_FACE_BACK_BIT)
330bf215546Sopenharmony_ci      cmdbuf->state.zs.s_back.compare_mask = compareMask;
331bf215546Sopenharmony_ci
332bf215546Sopenharmony_ci   cmdbuf->state.dirty |= PANVK_DYNAMIC_STENCIL_COMPARE_MASK;
333bf215546Sopenharmony_ci   cmdbuf->state.fs_rsd = 0;
334bf215546Sopenharmony_ci}
335bf215546Sopenharmony_ci
336bf215546Sopenharmony_civoid
337bf215546Sopenharmony_cipanvk_CmdSetStencilWriteMask(VkCommandBuffer commandBuffer,
338bf215546Sopenharmony_ci                             VkStencilFaceFlags faceMask,
339bf215546Sopenharmony_ci                             uint32_t writeMask)
340bf215546Sopenharmony_ci{
341bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
342bf215546Sopenharmony_ci
343bf215546Sopenharmony_ci   if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
344bf215546Sopenharmony_ci      cmdbuf->state.zs.s_front.write_mask = writeMask;
345bf215546Sopenharmony_ci
346bf215546Sopenharmony_ci   if (faceMask & VK_STENCIL_FACE_BACK_BIT)
347bf215546Sopenharmony_ci      cmdbuf->state.zs.s_back.write_mask = writeMask;
348bf215546Sopenharmony_ci
349bf215546Sopenharmony_ci   cmdbuf->state.dirty |= PANVK_DYNAMIC_STENCIL_WRITE_MASK;
350bf215546Sopenharmony_ci   cmdbuf->state.fs_rsd = 0;
351bf215546Sopenharmony_ci}
352bf215546Sopenharmony_ci
353bf215546Sopenharmony_civoid
354bf215546Sopenharmony_cipanvk_CmdSetStencilReference(VkCommandBuffer commandBuffer,
355bf215546Sopenharmony_ci                             VkStencilFaceFlags faceMask,
356bf215546Sopenharmony_ci                             uint32_t reference)
357bf215546Sopenharmony_ci{
358bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
359bf215546Sopenharmony_ci
360bf215546Sopenharmony_ci   if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
361bf215546Sopenharmony_ci      cmdbuf->state.zs.s_front.ref = reference;
362bf215546Sopenharmony_ci
363bf215546Sopenharmony_ci   if (faceMask & VK_STENCIL_FACE_BACK_BIT)
364bf215546Sopenharmony_ci      cmdbuf->state.zs.s_back.ref = reference;
365bf215546Sopenharmony_ci
366bf215546Sopenharmony_ci   cmdbuf->state.dirty |= PANVK_DYNAMIC_STENCIL_REFERENCE;
367bf215546Sopenharmony_ci   cmdbuf->state.fs_rsd = 0;
368bf215546Sopenharmony_ci}
369bf215546Sopenharmony_ci
370bf215546Sopenharmony_ciVkResult
371bf215546Sopenharmony_cipanvk_CreateCommandPool(VkDevice _device,
372bf215546Sopenharmony_ci                        const VkCommandPoolCreateInfo *pCreateInfo,
373bf215546Sopenharmony_ci                        const VkAllocationCallbacks *pAllocator,
374bf215546Sopenharmony_ci                        VkCommandPool *pCmdPool)
375bf215546Sopenharmony_ci{
376bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_device, device, _device);
377bf215546Sopenharmony_ci   struct panvk_cmd_pool *pool;
378bf215546Sopenharmony_ci
379bf215546Sopenharmony_ci   pool = vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*pool), 8,
380bf215546Sopenharmony_ci                    VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
381bf215546Sopenharmony_ci   if (pool == NULL)
382bf215546Sopenharmony_ci      return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
383bf215546Sopenharmony_ci
384bf215546Sopenharmony_ci   VkResult result = vk_command_pool_init(&pool->vk, &device->vk,
385bf215546Sopenharmony_ci                                          pCreateInfo, pAllocator);
386bf215546Sopenharmony_ci   if (result != VK_SUCCESS) {
387bf215546Sopenharmony_ci      vk_free2(&device->vk.alloc, pAllocator, pool);
388bf215546Sopenharmony_ci      return result;
389bf215546Sopenharmony_ci   }
390bf215546Sopenharmony_ci
391bf215546Sopenharmony_ci   list_inithead(&pool->active_cmd_buffers);
392bf215546Sopenharmony_ci   list_inithead(&pool->free_cmd_buffers);
393bf215546Sopenharmony_ci
394bf215546Sopenharmony_ci   panvk_bo_pool_init(&pool->desc_bo_pool);
395bf215546Sopenharmony_ci   panvk_bo_pool_init(&pool->varying_bo_pool);
396bf215546Sopenharmony_ci   panvk_bo_pool_init(&pool->tls_bo_pool);
397bf215546Sopenharmony_ci   *pCmdPool = panvk_cmd_pool_to_handle(pool);
398bf215546Sopenharmony_ci   return VK_SUCCESS;
399bf215546Sopenharmony_ci}
400bf215546Sopenharmony_ci
401bf215546Sopenharmony_cistatic void
402bf215546Sopenharmony_cipanvk_cmd_prepare_clear_values(struct panvk_cmd_buffer *cmdbuf,
403bf215546Sopenharmony_ci                               const VkClearValue *in)
404bf215546Sopenharmony_ci{
405bf215546Sopenharmony_ci   for (unsigned i = 0; i < cmdbuf->state.pass->attachment_count; i++) {
406bf215546Sopenharmony_ci       const struct panvk_render_pass_attachment *attachment =
407bf215546Sopenharmony_ci          &cmdbuf->state.pass->attachments[i];
408bf215546Sopenharmony_ci       enum pipe_format fmt = attachment->format;
409bf215546Sopenharmony_ci
410bf215546Sopenharmony_ci       if (util_format_is_depth_or_stencil(fmt)) {
411bf215546Sopenharmony_ci          if (attachment->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR ||
412bf215546Sopenharmony_ci              attachment->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
413bf215546Sopenharmony_ci             cmdbuf->state.clear[i].depth = in[i].depthStencil.depth;
414bf215546Sopenharmony_ci             cmdbuf->state.clear[i].stencil = in[i].depthStencil.stencil;
415bf215546Sopenharmony_ci          } else {
416bf215546Sopenharmony_ci             cmdbuf->state.clear[i].depth = 0;
417bf215546Sopenharmony_ci             cmdbuf->state.clear[i].stencil = 0;
418bf215546Sopenharmony_ci          }
419bf215546Sopenharmony_ci       } else {
420bf215546Sopenharmony_ci          if (attachment->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
421bf215546Sopenharmony_ci             union pipe_color_union *col = (union pipe_color_union *) &in[i].color;
422bf215546Sopenharmony_ci             pan_pack_color(cmdbuf->state.clear[i].color, col, fmt, false);
423bf215546Sopenharmony_ci          } else {
424bf215546Sopenharmony_ci             memset(cmdbuf->state.clear[i].color, 0, sizeof(cmdbuf->state.clear[0].color));
425bf215546Sopenharmony_ci          }
426bf215546Sopenharmony_ci       }
427bf215546Sopenharmony_ci   }
428bf215546Sopenharmony_ci}
429bf215546Sopenharmony_ci
430bf215546Sopenharmony_civoid
431bf215546Sopenharmony_cipanvk_cmd_fb_info_set_subpass(struct panvk_cmd_buffer *cmdbuf)
432bf215546Sopenharmony_ci{
433bf215546Sopenharmony_ci   const struct panvk_subpass *subpass = cmdbuf->state.subpass;
434bf215546Sopenharmony_ci   struct pan_fb_info *fbinfo = &cmdbuf->state.fb.info;
435bf215546Sopenharmony_ci   const struct panvk_framebuffer *fb = cmdbuf->state.framebuffer;
436bf215546Sopenharmony_ci   const struct panvk_clear_value *clears = cmdbuf->state.clear;
437bf215546Sopenharmony_ci   struct panvk_image_view *view;
438bf215546Sopenharmony_ci
439bf215546Sopenharmony_ci   fbinfo->nr_samples = 1;
440bf215546Sopenharmony_ci   fbinfo->rt_count = subpass->color_count;
441bf215546Sopenharmony_ci   memset(&fbinfo->bifrost.pre_post.dcds, 0, sizeof(fbinfo->bifrost.pre_post.dcds));
442bf215546Sopenharmony_ci
443bf215546Sopenharmony_ci   for (unsigned cb = 0; cb < subpass->color_count; cb++) {
444bf215546Sopenharmony_ci      int idx = subpass->color_attachments[cb].idx;
445bf215546Sopenharmony_ci      view = idx != VK_ATTACHMENT_UNUSED ?
446bf215546Sopenharmony_ci             fb->attachments[idx].iview : NULL;
447bf215546Sopenharmony_ci      if (!view)
448bf215546Sopenharmony_ci         continue;
449bf215546Sopenharmony_ci      fbinfo->rts[cb].view = &view->pview;
450bf215546Sopenharmony_ci      fbinfo->rts[cb].clear = subpass->color_attachments[cb].clear;
451bf215546Sopenharmony_ci      fbinfo->rts[cb].preload = subpass->color_attachments[cb].preload;
452bf215546Sopenharmony_ci      fbinfo->rts[cb].crc_valid = &cmdbuf->state.fb.crc_valid[cb];
453bf215546Sopenharmony_ci
454bf215546Sopenharmony_ci      memcpy(fbinfo->rts[cb].clear_value, clears[idx].color,
455bf215546Sopenharmony_ci             sizeof(fbinfo->rts[cb].clear_value));
456bf215546Sopenharmony_ci      fbinfo->nr_samples =
457bf215546Sopenharmony_ci         MAX2(fbinfo->nr_samples, view->pview.image->layout.nr_samples);
458bf215546Sopenharmony_ci   }
459bf215546Sopenharmony_ci
460bf215546Sopenharmony_ci   if (subpass->zs_attachment.idx != VK_ATTACHMENT_UNUSED) {
461bf215546Sopenharmony_ci      view = fb->attachments[subpass->zs_attachment.idx].iview;
462bf215546Sopenharmony_ci      const struct util_format_description *fdesc =
463bf215546Sopenharmony_ci         util_format_description(view->pview.format);
464bf215546Sopenharmony_ci
465bf215546Sopenharmony_ci      fbinfo->nr_samples =
466bf215546Sopenharmony_ci         MAX2(fbinfo->nr_samples, view->pview.image->layout.nr_samples);
467bf215546Sopenharmony_ci
468bf215546Sopenharmony_ci      if (util_format_has_depth(fdesc)) {
469bf215546Sopenharmony_ci         fbinfo->zs.clear.z = subpass->zs_attachment.clear;
470bf215546Sopenharmony_ci         fbinfo->zs.clear_value.depth = clears[subpass->zs_attachment.idx].depth;
471bf215546Sopenharmony_ci         fbinfo->zs.view.zs = &view->pview;
472bf215546Sopenharmony_ci      }
473bf215546Sopenharmony_ci
474bf215546Sopenharmony_ci      if (util_format_has_stencil(fdesc)) {
475bf215546Sopenharmony_ci         fbinfo->zs.clear.s = subpass->zs_attachment.clear;
476bf215546Sopenharmony_ci         fbinfo->zs.clear_value.stencil = clears[subpass->zs_attachment.idx].stencil;
477bf215546Sopenharmony_ci         if (!fbinfo->zs.view.zs)
478bf215546Sopenharmony_ci            fbinfo->zs.view.s = &view->pview;
479bf215546Sopenharmony_ci      }
480bf215546Sopenharmony_ci   }
481bf215546Sopenharmony_ci}
482bf215546Sopenharmony_ci
483bf215546Sopenharmony_civoid
484bf215546Sopenharmony_cipanvk_cmd_fb_info_init(struct panvk_cmd_buffer *cmdbuf)
485bf215546Sopenharmony_ci{
486bf215546Sopenharmony_ci   struct pan_fb_info *fbinfo = &cmdbuf->state.fb.info;
487bf215546Sopenharmony_ci   const struct panvk_framebuffer *fb = cmdbuf->state.framebuffer;
488bf215546Sopenharmony_ci
489bf215546Sopenharmony_ci   memset(cmdbuf->state.fb.crc_valid, 0, sizeof(cmdbuf->state.fb.crc_valid));
490bf215546Sopenharmony_ci
491bf215546Sopenharmony_ci   *fbinfo = (struct pan_fb_info) {
492bf215546Sopenharmony_ci      .width = fb->width,
493bf215546Sopenharmony_ci      .height = fb->height,
494bf215546Sopenharmony_ci      .extent.maxx = fb->width - 1,
495bf215546Sopenharmony_ci      .extent.maxy = fb->height - 1,
496bf215546Sopenharmony_ci   };
497bf215546Sopenharmony_ci}
498bf215546Sopenharmony_ci
499bf215546Sopenharmony_civoid
500bf215546Sopenharmony_cipanvk_CmdBeginRenderPass2(VkCommandBuffer commandBuffer,
501bf215546Sopenharmony_ci                          const VkRenderPassBeginInfo *pRenderPassBegin,
502bf215546Sopenharmony_ci                          const VkSubpassBeginInfo *pSubpassBeginInfo)
503bf215546Sopenharmony_ci{
504bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
505bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_render_pass, pass, pRenderPassBegin->renderPass);
506bf215546Sopenharmony_ci   VK_FROM_HANDLE(panvk_framebuffer, fb, pRenderPassBegin->framebuffer);
507bf215546Sopenharmony_ci
508bf215546Sopenharmony_ci   cmdbuf->state.pass = pass;
509bf215546Sopenharmony_ci   cmdbuf->state.subpass = pass->subpasses;
510bf215546Sopenharmony_ci   cmdbuf->state.framebuffer = fb;
511bf215546Sopenharmony_ci   cmdbuf->state.render_area = pRenderPassBegin->renderArea;
512bf215546Sopenharmony_ci   cmdbuf->state.batch = vk_zalloc(&cmdbuf->pool->vk.alloc,
513bf215546Sopenharmony_ci                                   sizeof(*cmdbuf->state.batch), 8,
514bf215546Sopenharmony_ci                                   VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
515bf215546Sopenharmony_ci   util_dynarray_init(&cmdbuf->state.batch->jobs, NULL);
516bf215546Sopenharmony_ci   util_dynarray_init(&cmdbuf->state.batch->event_ops, NULL);
517bf215546Sopenharmony_ci   assert(pRenderPassBegin->clearValueCount <= pass->attachment_count);
518bf215546Sopenharmony_ci   cmdbuf->state.clear =
519bf215546Sopenharmony_ci      vk_zalloc(&cmdbuf->pool->vk.alloc,
520bf215546Sopenharmony_ci                sizeof(*cmdbuf->state.clear) * pass->attachment_count,
521bf215546Sopenharmony_ci                8, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
522bf215546Sopenharmony_ci   panvk_cmd_prepare_clear_values(cmdbuf, pRenderPassBegin->pClearValues);
523bf215546Sopenharmony_ci   panvk_cmd_fb_info_init(cmdbuf);
524bf215546Sopenharmony_ci   panvk_cmd_fb_info_set_subpass(cmdbuf);
525bf215546Sopenharmony_ci}
526bf215546Sopenharmony_ci
527bf215546Sopenharmony_civoid
528bf215546Sopenharmony_cipanvk_cmd_preload_fb_after_batch_split(struct panvk_cmd_buffer *cmdbuf)
529bf215546Sopenharmony_ci{
530bf215546Sopenharmony_ci   for (unsigned i = 0; i < cmdbuf->state.fb.info.rt_count; i++) {
531bf215546Sopenharmony_ci      if (cmdbuf->state.fb.info.rts[i].view) {
532bf215546Sopenharmony_ci         cmdbuf->state.fb.info.rts[i].clear = false;
533bf215546Sopenharmony_ci         cmdbuf->state.fb.info.rts[i].preload = true;
534bf215546Sopenharmony_ci      }
535bf215546Sopenharmony_ci   }
536bf215546Sopenharmony_ci
537bf215546Sopenharmony_ci   if (cmdbuf->state.fb.info.zs.view.zs) {
538bf215546Sopenharmony_ci      cmdbuf->state.fb.info.zs.clear.z = false;
539bf215546Sopenharmony_ci      cmdbuf->state.fb.info.zs.preload.z = true;
540bf215546Sopenharmony_ci   }
541bf215546Sopenharmony_ci
542bf215546Sopenharmony_ci   if (cmdbuf->state.fb.info.zs.view.s ||
543bf215546Sopenharmony_ci       (cmdbuf->state.fb.info.zs.view.zs &&
544bf215546Sopenharmony_ci        util_format_is_depth_and_stencil(cmdbuf->state.fb.info.zs.view.zs->format))) {
545bf215546Sopenharmony_ci      cmdbuf->state.fb.info.zs.clear.s = false;
546bf215546Sopenharmony_ci      cmdbuf->state.fb.info.zs.preload.s = true;
547bf215546Sopenharmony_ci   }
548bf215546Sopenharmony_ci}
549bf215546Sopenharmony_ci
550bf215546Sopenharmony_cistruct panvk_batch *
551bf215546Sopenharmony_cipanvk_cmd_open_batch(struct panvk_cmd_buffer *cmdbuf)
552bf215546Sopenharmony_ci{
553bf215546Sopenharmony_ci   assert(!cmdbuf->state.batch);
554bf215546Sopenharmony_ci   cmdbuf->state.batch = vk_zalloc(&cmdbuf->pool->vk.alloc,
555bf215546Sopenharmony_ci                                   sizeof(*cmdbuf->state.batch), 8,
556bf215546Sopenharmony_ci                                   VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
557bf215546Sopenharmony_ci   assert(cmdbuf->state.batch);
558bf215546Sopenharmony_ci   return cmdbuf->state.batch;
559bf215546Sopenharmony_ci}
560bf215546Sopenharmony_ci
561bf215546Sopenharmony_civoid
562bf215546Sopenharmony_cipanvk_CmdDrawIndirect(VkCommandBuffer commandBuffer,
563bf215546Sopenharmony_ci                      VkBuffer _buffer,
564bf215546Sopenharmony_ci                      VkDeviceSize offset,
565bf215546Sopenharmony_ci                      uint32_t drawCount,
566bf215546Sopenharmony_ci                      uint32_t stride)
567bf215546Sopenharmony_ci{
568bf215546Sopenharmony_ci   panvk_stub();
569bf215546Sopenharmony_ci}
570bf215546Sopenharmony_ci
571bf215546Sopenharmony_civoid
572bf215546Sopenharmony_cipanvk_CmdDrawIndexedIndirect(VkCommandBuffer commandBuffer,
573bf215546Sopenharmony_ci                             VkBuffer _buffer,
574bf215546Sopenharmony_ci                             VkDeviceSize offset,
575bf215546Sopenharmony_ci                             uint32_t drawCount,
576bf215546Sopenharmony_ci                             uint32_t stride)
577bf215546Sopenharmony_ci{
578bf215546Sopenharmony_ci   panvk_stub();
579bf215546Sopenharmony_ci}
580bf215546Sopenharmony_ci
581bf215546Sopenharmony_civoid
582bf215546Sopenharmony_cipanvk_CmdDispatchBase(VkCommandBuffer commandBuffer,
583bf215546Sopenharmony_ci                      uint32_t base_x,
584bf215546Sopenharmony_ci                      uint32_t base_y,
585bf215546Sopenharmony_ci                      uint32_t base_z,
586bf215546Sopenharmony_ci                      uint32_t x,
587bf215546Sopenharmony_ci                      uint32_t y,
588bf215546Sopenharmony_ci                      uint32_t z)
589bf215546Sopenharmony_ci{
590bf215546Sopenharmony_ci   panvk_stub();
591bf215546Sopenharmony_ci}
592bf215546Sopenharmony_ci
593bf215546Sopenharmony_civoid
594bf215546Sopenharmony_cipanvk_CmdDispatchIndirect(VkCommandBuffer commandBuffer,
595bf215546Sopenharmony_ci                          VkBuffer _buffer,
596bf215546Sopenharmony_ci                          VkDeviceSize offset)
597bf215546Sopenharmony_ci{
598bf215546Sopenharmony_ci   panvk_stub();
599bf215546Sopenharmony_ci}
600bf215546Sopenharmony_ci
601bf215546Sopenharmony_civoid
602bf215546Sopenharmony_cipanvk_CmdSetDeviceMask(VkCommandBuffer commandBuffer, uint32_t deviceMask)
603bf215546Sopenharmony_ci{
604bf215546Sopenharmony_ci   panvk_stub();
605bf215546Sopenharmony_ci}
606