genX_cmd_buffer.c revision 2314c9ed2e39bcf4ac6b206344acb05fec876a41
16f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand/*
26f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand * Copyright © 2015 Intel Corporation
36f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand *
46f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand * Permission is hereby granted, free of charge, to any person obtaining a
56f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand * copy of this software and associated documentation files (the "Software"),
66f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand * to deal in the Software without restriction, including without limitation
76f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand * the rights to use, copy, modify, merge, publish, distribute, sublicense,
86f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand * and/or sell copies of the Software, and to permit persons to whom the
96f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand * Software is furnished to do so, subject to the following conditions:
106f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand *
116f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand * The above copyright notice and this permission notice (including the next
126f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand * paragraph) shall be included in all copies or substantial portions of the
136f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand * Software.
146f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand *
156f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
166f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
176f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
186f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
196f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
206f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
216f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand * IN THE SOFTWARE.
226f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand */
236f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand
246f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand#include <assert.h>
256f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand#include <stdbool.h>
266f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand
276f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand#include "anv_private.h"
286f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand
297e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand#include "common/gen_l3_config.h"
30371b4a5b33a13f35fa7783510d2d90685a9a2e8aJason Ekstrand#include "genxml/gen_macros.h"
31371b4a5b33a13f35fa7783510d2d90685a9a2e8aJason Ekstrand#include "genxml/genX_pack.h"
326f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand
3317968e2dfd8bd362404e9bdd34188d473edd471fJason Ekstrandstatic void
3417968e2dfd8bd362404e9bdd34188d473edd471fJason Ekstrandemit_lrm(struct anv_batch *batch,
3517968e2dfd8bd362404e9bdd34188d473edd471fJason Ekstrand         uint32_t reg, struct anv_bo *bo, uint32_t offset)
3617968e2dfd8bd362404e9bdd34188d473edd471fJason Ekstrand{
3717968e2dfd8bd362404e9bdd34188d473edd471fJason Ekstrand   anv_batch_emit(batch, GENX(MI_LOAD_REGISTER_MEM), lrm) {
3817968e2dfd8bd362404e9bdd34188d473edd471fJason Ekstrand      lrm.RegisterAddress  = reg;
3917968e2dfd8bd362404e9bdd34188d473edd471fJason Ekstrand      lrm.MemoryAddress    = (struct anv_address) { bo, offset };
4017968e2dfd8bd362404e9bdd34188d473edd471fJason Ekstrand   }
4117968e2dfd8bd362404e9bdd34188d473edd471fJason Ekstrand}
4217968e2dfd8bd362404e9bdd34188d473edd471fJason Ekstrand
4317968e2dfd8bd362404e9bdd34188d473edd471fJason Ekstrandstatic void
4417968e2dfd8bd362404e9bdd34188d473edd471fJason Ekstrandemit_lri(struct anv_batch *batch, uint32_t reg, uint32_t imm)
4517968e2dfd8bd362404e9bdd34188d473edd471fJason Ekstrand{
4617968e2dfd8bd362404e9bdd34188d473edd471fJason Ekstrand   anv_batch_emit(batch, GENX(MI_LOAD_REGISTER_IMM), lri) {
4717968e2dfd8bd362404e9bdd34188d473edd471fJason Ekstrand      lri.RegisterOffset   = reg;
4817968e2dfd8bd362404e9bdd34188d473edd471fJason Ekstrand      lri.DataDWord        = imm;
4917968e2dfd8bd362404e9bdd34188d473edd471fJason Ekstrand   }
5017968e2dfd8bd362404e9bdd34188d473edd471fJason Ekstrand}
5117968e2dfd8bd362404e9bdd34188d473edd471fJason Ekstrand
526f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrandvoid
536f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason EkstrandgenX(cmd_buffer_emit_state_base_address)(struct anv_cmd_buffer *cmd_buffer)
546f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand{
556f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand   struct anv_device *device = cmd_buffer->device;
566f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand
576f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand/* XXX: Do we need this on more than just BDW? */
58371b4a5b33a13f35fa7783510d2d90685a9a2e8aJason Ekstrand#if (GEN_GEN >= 8)
596f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand   /* Emit a render target cache flush.
606f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    *
616f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    * This isn't documented anywhere in the PRM.  However, it seems to be
626f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    * necessary prior to changing the surface state base adress.  Without
636f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    * this, we get GPU hangs when using multi-level command buffers which
646f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    * clear depth, reset state base address, and then go render stuff.
656f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    */
6650018522d2f2e1deb91710d63e0985c0b3dc8818Jason Ekstrand   anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pc) {
6756453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand      pc.RenderTargetCacheFlushEnable = true;
6856453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand   }
696f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand#endif
706f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand
7150018522d2f2e1deb91710d63e0985c0b3dc8818Jason Ekstrand   anv_batch_emit(&cmd_buffer->batch, GENX(STATE_BASE_ADDRESS), sba) {
72c2f2c8e407207c31c29aab5570d23cd6e98d287aJason Ekstrand      sba.GeneralStateBaseAddress = (struct anv_address) { NULL, 0 };
7356453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand      sba.GeneralStateMemoryObjectControlState = GENX(MOCS);
7456453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand      sba.GeneralStateBaseAddressModifyEnable = true;
756f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand
7656453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand      sba.SurfaceStateBaseAddress =
7756453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand         anv_cmd_buffer_surface_base_address(cmd_buffer);
7856453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand      sba.SurfaceStateMemoryObjectControlState = GENX(MOCS);
7956453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand      sba.SurfaceStateBaseAddressModifyEnable = true;
806f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand
8156453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand      sba.DynamicStateBaseAddress =
8256453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand         (struct anv_address) { &device->dynamic_state_block_pool.bo, 0 };
83696f5c1853df39359b9dbd733f4c2a1177481556Lionel Landwerlin      sba.DynamicStateMemoryObjectControlState = GENX(MOCS);
84696f5c1853df39359b9dbd733f4c2a1177481556Lionel Landwerlin      sba.DynamicStateBaseAddressModifyEnable = true;
856f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand
8656453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand      sba.IndirectObjectBaseAddress = (struct anv_address) { NULL, 0 };
8756453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand      sba.IndirectObjectMemoryObjectControlState = GENX(MOCS);
8856453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand      sba.IndirectObjectBaseAddressModifyEnable = true;
896f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand
9056453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand      sba.InstructionBaseAddress =
9156453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand         (struct anv_address) { &device->instruction_block_pool.bo, 0 };
9256453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand      sba.InstructionMemoryObjectControlState = GENX(MOCS);
9356453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand      sba.InstructionBaseAddressModifyEnable = true;
946f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand
95371b4a5b33a13f35fa7783510d2d90685a9a2e8aJason Ekstrand#  if (GEN_GEN >= 8)
966f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand      /* Broadwell requires that we specify a buffer size for a bunch of
976f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand       * these fields.  However, since we will be growing the BO's live, we
986f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand       * just set them all to the maximum.
996f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand       */
10056453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand      sba.GeneralStateBufferSize                = 0xfffff;
10156453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand      sba.GeneralStateBufferSizeModifyEnable    = true;
10256453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand      sba.DynamicStateBufferSize                = 0xfffff;
10356453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand      sba.DynamicStateBufferSizeModifyEnable    = true;
10456453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand      sba.IndirectObjectBufferSize              = 0xfffff;
10556453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand      sba.IndirectObjectBufferSizeModifyEnable  = true;
10656453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand      sba.InstructionBufferSize                 = 0xfffff;
10756453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand      sba.InstructionBuffersizeModifyEnable     = true;
1086f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand#  endif
10956453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand   }
1106f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand
1116f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand   /* After re-setting the surface state base address, we have to do some
1126f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    * cache flusing so that the sampler engine will pick up the new
1136f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    * SURFACE_STATE objects and binding tables. From the Broadwell PRM,
1146f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    * Shared Function > 3D Sampler > State > State Caching (page 96):
1156f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    *
1166f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    *    Coherency with system memory in the state cache, like the texture
1176f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    *    cache is handled partially by software. It is expected that the
1186f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    *    command stream or shader will issue Cache Flush operation or
1196f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    *    Cache_Flush sampler message to ensure that the L1 cache remains
1206f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    *    coherent with system memory.
1216f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    *
1226f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    *    [...]
1236f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    *
1246f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    *    Whenever the value of the Dynamic_State_Base_Addr,
1256f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    *    Surface_State_Base_Addr are altered, the L1 state cache must be
1266f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    *    invalidated to ensure the new surface or sampler state is fetched
1276f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    *    from system memory.
1286f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    *
1296f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    * The PIPE_CONTROL command has a "State Cache Invalidation Enable" bit
1306f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    * which, according the PIPE_CONTROL instruction documentation in the
1316f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    * Broadwell PRM:
1326f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    *
1336f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    *    Setting this bit is independent of any other bit in this packet.
1346f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    *    This bit controls the invalidation of the L1 and L2 state caches
1356f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    *    at the top of the pipe i.e. at the parsing time.
1366f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    *
1376f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    * Unfortunately, experimentation seems to indicate that state cache
1386f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    * invalidation through a PIPE_CONTROL does nothing whatsoever in
1396f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    * regards to surface state and binding tables.  In stead, it seems that
1406f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    * invalidating the texture cache is what is actually needed.
1416f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    *
1426f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    * XXX:  As far as we have been able to determine through
1436f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    * experimentation, shows that flush the texture cache appears to be
1446f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    * sufficient.  The theory here is that all of the sampling/rendering
1456f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    * units cache the binding table in the texture cache.  However, we have
1466f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    * yet to be able to actually confirm this.
1476f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    */
14850018522d2f2e1deb91710d63e0985c0b3dc8818Jason Ekstrand   anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pc) {
14956453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand      pc.TextureCacheInvalidationEnable = true;
15056453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand   }
1516f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand}
1526f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand
1532314c9ed2e39bcf4ac6b206344acb05fec876a41Jason EkstrandVkResult
1542314c9ed2e39bcf4ac6b206344acb05fec876a41Jason EkstrandgenX(BeginCommandBuffer)(
1552314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand    VkCommandBuffer                             commandBuffer,
1562314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand    const VkCommandBufferBeginInfo*             pBeginInfo)
1572314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand{
1582314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
1592314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand
1602314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand   /* If this is the first vkBeginCommandBuffer, we must *initialize* the
1612314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand    * command buffer's state. Otherwise, we must *reset* its state. In both
1622314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand    * cases we reset it.
1632314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand    *
1642314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand    * From the Vulkan 1.0 spec:
1652314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand    *
1662314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand    *    If a command buffer is in the executable state and the command buffer
1672314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand    *    was allocated from a command pool with the
1682314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand    *    VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT flag set, then
1692314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand    *    vkBeginCommandBuffer implicitly resets the command buffer, behaving
1702314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand    *    as if vkResetCommandBuffer had been called with
1712314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand    *    VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT not set. It then puts
1722314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand    *    the command buffer in the recording state.
1732314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand    */
1742314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand   anv_cmd_buffer_reset(cmd_buffer);
1752314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand
1762314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand   cmd_buffer->usage_flags = pBeginInfo->flags;
1772314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand
1782314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand   assert(cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_SECONDARY ||
1792314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand          !(cmd_buffer->usage_flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT));
1802314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand
1812314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand   genX(cmd_buffer_emit_state_base_address)(cmd_buffer);
1822314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand
1832314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand   if (cmd_buffer->usage_flags &
1842314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand       VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT) {
1852314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand      cmd_buffer->state.framebuffer =
1862314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand         anv_framebuffer_from_handle(pBeginInfo->pInheritanceInfo->framebuffer);
1872314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand      cmd_buffer->state.pass =
1882314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand         anv_render_pass_from_handle(pBeginInfo->pInheritanceInfo->renderPass);
1892314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand      cmd_buffer->state.subpass =
1902314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand         &cmd_buffer->state.pass->subpasses[pBeginInfo->pInheritanceInfo->subpass];
1912314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand
1922314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand      cmd_buffer->state.dirty |= ANV_CMD_DIRTY_RENDER_TARGETS;
1932314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand   }
1942314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand
1952314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand   return VK_SUCCESS;
1962314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand}
1972314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand
1982314c9ed2e39bcf4ac6b206344acb05fec876a41Jason EkstrandVkResult
1992314c9ed2e39bcf4ac6b206344acb05fec876a41Jason EkstrandgenX(EndCommandBuffer)(
2002314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand    VkCommandBuffer                             commandBuffer)
2012314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand{
2022314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
2032314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand   struct anv_device *device = cmd_buffer->device;
2042314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand
2052314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand   anv_cmd_buffer_end_batch_buffer(cmd_buffer);
2062314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand
2072314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand   if (cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_PRIMARY) {
2082314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand      /* The algorithm used to compute the validate list is not threadsafe as
2092314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand       * it uses the bo->index field.  We have to lock the device around it.
2102314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand       * Fortunately, the chances for contention here are probably very low.
2112314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand       */
2122314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand      pthread_mutex_lock(&device->mutex);
2132314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand      anv_cmd_buffer_prepare_execbuf(cmd_buffer);
2142314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand      pthread_mutex_unlock(&device->mutex);
2152314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand   }
2162314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand
2172314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand   return VK_SUCCESS;
2182314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand}
2192314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand
2202314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrandvoid
2212314c9ed2e39bcf4ac6b206344acb05fec876a41Jason EkstrandgenX(CmdExecuteCommands)(
2222314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand    VkCommandBuffer                             commandBuffer,
2232314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand    uint32_t                                    commandBufferCount,
2242314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand    const VkCommandBuffer*                      pCmdBuffers)
2252314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand{
2262314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand   ANV_FROM_HANDLE(anv_cmd_buffer, primary, commandBuffer);
2272314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand
2282314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand   assert(primary->level == VK_COMMAND_BUFFER_LEVEL_PRIMARY);
2292314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand
2302314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand   for (uint32_t i = 0; i < commandBufferCount; i++) {
2312314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand      ANV_FROM_HANDLE(anv_cmd_buffer, secondary, pCmdBuffers[i]);
2322314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand
2332314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand      assert(secondary->level == VK_COMMAND_BUFFER_LEVEL_SECONDARY);
2342314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand
2352314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand      anv_cmd_buffer_add_secondary(primary, secondary);
2362314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand   }
2372314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand
2382314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand   /* Each of the secondary command buffers will use its own state base
2392314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand    * address.  We need to re-emit state base address for the primary after
2402314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand    * all of the secondaries are done.
2412314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand    *
2422314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand    * TODO: Maybe we want to make this a dirty bit to avoid extra state base
2432314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand    * address calls?
2442314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand    */
2452314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand   genX(cmd_buffer_emit_state_base_address)(primary);
2462314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand}
2472314c9ed2e39bcf4ac6b206344acb05fec876a41Jason Ekstrand
2487e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand#define IVB_L3SQCREG1_SQGHPCI_DEFAULT     0x00730000
2497e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand#define VLV_L3SQCREG1_SQGHPCI_DEFAULT     0x00d30000
2507e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand#define HSW_L3SQCREG1_SQGHPCI_DEFAULT     0x00610000
2517e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand
2527e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand/**
2537e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand * Program the hardware to use the specified L3 configuration.
2547e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand */
2557e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrandvoid
2567e891f90c701aa1c851f1846857daa75bbb65876Jason EkstrandgenX(cmd_buffer_config_l3)(struct anv_cmd_buffer *cmd_buffer,
2577e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand                           const struct gen_l3_config *cfg)
2587e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand{
2597e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   assert(cfg);
2607e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   if (cfg == cmd_buffer->state.current_l3_config)
2617e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand      return;
2627e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand
2637e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   if (unlikely(INTEL_DEBUG & DEBUG_L3)) {
2647e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand      fprintf(stderr, "L3 config transition: ");
2657e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand      gen_dump_l3_config(cfg, stderr);
2667e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   }
2677e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand
2687e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   const bool has_slm = cfg->n[GEN_L3P_SLM];
2697e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand
2707e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   /* According to the hardware docs, the L3 partitioning can only be changed
2717e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand    * while the pipeline is completely drained and the caches are flushed,
2727e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand    * which involves a first PIPE_CONTROL flush which stalls the pipeline...
2737e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand    */
2747e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pc) {
2757e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand      pc.DCFlushEnable = true;
2767e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand      pc.PostSyncOperation = NoWrite;
2777e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand      pc.CommandStreamerStallEnable = true;
2787e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   }
2797e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand
2807e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   /* ...followed by a second pipelined PIPE_CONTROL that initiates
2817e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand    * invalidation of the relevant caches.  Note that because RO invalidation
2827e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand    * happens at the top of the pipeline (i.e. right away as the PIPE_CONTROL
2837e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand    * command is processed by the CS) we cannot combine it with the previous
2847e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand    * stalling flush as the hardware documentation suggests, because that
2857e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand    * would cause the CS to stall on previous rendering *after* RO
2867e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand    * invalidation and wouldn't prevent the RO caches from being polluted by
2877e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand    * concurrent rendering before the stall completes.  This intentionally
2887e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand    * doesn't implement the SKL+ hardware workaround suggesting to enable CS
2897e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand    * stall on PIPE_CONTROLs with the texture cache invalidation bit set for
2907e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand    * GPGPU workloads because the previous and subsequent PIPE_CONTROLs
2917e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand    * already guarantee that there is no concurrent GPGPU kernel execution
2927e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand    * (see SKL HSD 2132585).
2937e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand    */
2947e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pc) {
2957e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand      pc.TextureCacheInvalidationEnable = true;
2967e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand      pc.ConstantCacheInvalidationEnable = true;
2977e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand      pc.InstructionCacheInvalidateEnable = true;
2987e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand      pc.StateCacheInvalidationEnable = true;
2997e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand      pc.PostSyncOperation = NoWrite;
3007e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   }
3017e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand
3027e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   /* Now send a third stalling flush to make sure that invalidation is
3037e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand    * complete when the L3 configuration registers are modified.
3047e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand    */
3057e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pc) {
3067e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand      pc.DCFlushEnable = true;
3077e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand      pc.PostSyncOperation = NoWrite;
3087e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand      pc.CommandStreamerStallEnable = true;
3097e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   }
3107e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand
3117e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand#if GEN_GEN >= 8
3127e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand
3137e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   assert(!cfg->n[GEN_L3P_IS] && !cfg->n[GEN_L3P_C] && !cfg->n[GEN_L3P_T]);
3147e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand
3157e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   uint32_t l3cr;
3167e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   anv_pack_struct(&l3cr, GENX(L3CNTLREG),
3177e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand                   .SLMEnable = has_slm,
3187e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand                   .URBAllocation = cfg->n[GEN_L3P_URB],
3197e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand                   .ROAllocation = cfg->n[GEN_L3P_RO],
3207e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand                   .DCAllocation = cfg->n[GEN_L3P_DC],
3217e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand                   .AllAllocation = cfg->n[GEN_L3P_ALL]);
3227e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand
3237e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   /* Set up the L3 partitioning. */
3247e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   emit_lri(&cmd_buffer->batch, GENX(L3CNTLREG_num), l3cr);
3257e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand
3267e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand#else
3277e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand
3287e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   const bool has_dc = cfg->n[GEN_L3P_DC] || cfg->n[GEN_L3P_ALL];
3297e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   const bool has_is = cfg->n[GEN_L3P_IS] || cfg->n[GEN_L3P_RO] ||
3307e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand                       cfg->n[GEN_L3P_ALL];
3317e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   const bool has_c = cfg->n[GEN_L3P_C] || cfg->n[GEN_L3P_RO] ||
3327e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand                      cfg->n[GEN_L3P_ALL];
3337e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   const bool has_t = cfg->n[GEN_L3P_T] || cfg->n[GEN_L3P_RO] ||
3347e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand                      cfg->n[GEN_L3P_ALL];
3357e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand
3367e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   assert(!cfg->n[GEN_L3P_ALL]);
3377e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand
3387e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   /* When enabled SLM only uses a portion of the L3 on half of the banks,
3397e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand    * the matching space on the remaining banks has to be allocated to a
3407e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand    * client (URB for all validated configurations) set to the
3417e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand    * lower-bandwidth 2-bank address hashing mode.
3427e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand    */
3437e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   const struct gen_device_info *devinfo = &cmd_buffer->device->info;
3447e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   const bool urb_low_bw = has_slm && !devinfo->is_baytrail;
3457e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   assert(!urb_low_bw || cfg->n[GEN_L3P_URB] == cfg->n[GEN_L3P_SLM]);
3467e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand
3477e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   /* Minimum number of ways that can be allocated to the URB. */
3487e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   const unsigned n0_urb = (devinfo->is_baytrail ? 32 : 0);
3497e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   assert(cfg->n[GEN_L3P_URB] >= n0_urb);
3507e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand
3517e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   uint32_t l3sqcr1, l3cr2, l3cr3;
3527e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   anv_pack_struct(&l3sqcr1, GENX(L3SQCREG1),
3537e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand                   .ConvertDC_UC = !has_dc,
3547e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand                   .ConvertIS_UC = !has_is,
3557e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand                   .ConvertC_UC = !has_c,
3567e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand                   .ConvertT_UC = !has_t);
3577e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   l3sqcr1 |=
3587e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand      GEN_IS_HASWELL ? HSW_L3SQCREG1_SQGHPCI_DEFAULT :
3597e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand      devinfo->is_baytrail ? VLV_L3SQCREG1_SQGHPCI_DEFAULT :
3607e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand      IVB_L3SQCREG1_SQGHPCI_DEFAULT;
3617e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand
3627e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   anv_pack_struct(&l3cr2, GENX(L3CNTLREG2),
3637e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand                   .SLMEnable = has_slm,
3647e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand                   .URBLowBandwidth = urb_low_bw,
3657e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand                   .URBAllocation = cfg->n[GEN_L3P_URB],
3667e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand#if !GEN_IS_HASWELL
3677e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand                   .ALLAllocation = cfg->n[GEN_L3P_ALL],
3687e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand#endif
3697e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand                   .ROAllocation = cfg->n[GEN_L3P_RO],
3707e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand                   .DCAllocation = cfg->n[GEN_L3P_DC]);
3717e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand
3727e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   anv_pack_struct(&l3cr3, GENX(L3CNTLREG3),
3737e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand                   .ISAllocation = cfg->n[GEN_L3P_IS],
3747e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand                   .ISLowBandwidth = 0,
3757e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand                   .CAllocation = cfg->n[GEN_L3P_C],
3767e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand                   .CLowBandwidth = 0,
3777e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand                   .TAllocation = cfg->n[GEN_L3P_T],
3787e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand                   .TLowBandwidth = 0);
3797e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand
3807e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   /* Set up the L3 partitioning. */
3817e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   emit_lri(&cmd_buffer->batch, GENX(L3SQCREG1_num), l3sqcr1);
3827e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   emit_lri(&cmd_buffer->batch, GENX(L3CNTLREG2_num), l3cr2);
3837e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   emit_lri(&cmd_buffer->batch, GENX(L3CNTLREG3_num), l3cr3);
3847e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand
3857e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand#if GEN_IS_HASWELL
3867e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   if (cmd_buffer->device->instance->physicalDevice.cmd_parser_version >= 4) {
3877e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand      /* Enable L3 atomics on HSW if we have a DC partition, otherwise keep
3887e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand       * them disabled to avoid crashing the system hard.
3897e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand       */
3907e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand      uint32_t scratch1, chicken3;
3917e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand      anv_pack_struct(&scratch1, GENX(SCRATCH1),
3927e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand                      .L3AtomicDisable = !has_dc);
3937e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand      anv_pack_struct(&chicken3, GENX(CHICKEN3),
39489a96c8f43370cc84adf92ab32e3de302a1fa1d0Jason Ekstrand                      .L3AtomicDisableMask = true,
3957e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand                      .L3AtomicDisable = !has_dc);
3967e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand      emit_lri(&cmd_buffer->batch, GENX(SCRATCH1_num), scratch1);
3977e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand      emit_lri(&cmd_buffer->batch, GENX(CHICKEN3_num), chicken3);
3987e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   }
3997e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand#endif
4007e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand
4017e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand#endif
4027e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand
4037e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   cmd_buffer->state.current_l3_config = cfg;
4047e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand}
4057e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand
4063a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrandvoid
4073a83c176eab8c513eb723554a240af1a7308d701Jason EkstrandgenX(cmd_buffer_apply_pipe_flushes)(struct anv_cmd_buffer *cmd_buffer)
4083a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand{
4093a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand   enum anv_pipe_bits bits = cmd_buffer->state.pending_pipe_bits;
4103a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand
4113a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand   /* Flushes are pipelined while invalidations are handled immediately.
4123a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand    * Therefore, if we're flushing anything then we need to schedule a stall
4133a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand    * before any invalidations can happen.
4143a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand    */
4153a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand   if (bits & ANV_PIPE_FLUSH_BITS)
4163a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand      bits |= ANV_PIPE_NEEDS_CS_STALL_BIT;
4173a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand
4183a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand   /* If we're going to do an invalidate and we have a pending CS stall that
4193a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand    * has yet to be resolved, we do the CS stall now.
4203a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand    */
4213a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand   if ((bits & ANV_PIPE_INVALIDATE_BITS) &&
4223a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand       (bits & ANV_PIPE_NEEDS_CS_STALL_BIT)) {
4233a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand      bits |= ANV_PIPE_CS_STALL_BIT;
4243a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand      bits &= ~ANV_PIPE_NEEDS_CS_STALL_BIT;
4253a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand   }
4263a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand
4273a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand   if (bits & (ANV_PIPE_FLUSH_BITS | ANV_PIPE_CS_STALL_BIT)) {
4283a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand      anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pipe) {
4293a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand         pipe.DepthCacheFlushEnable = bits & ANV_PIPE_DEPTH_CACHE_FLUSH_BIT;
4303a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand         pipe.DCFlushEnable = bits & ANV_PIPE_DATA_CACHE_FLUSH_BIT;
4313a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand         pipe.RenderTargetCacheFlushEnable =
4323a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand            bits & ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT;
4333a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand
4343a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand         pipe.DepthStallEnable = bits & ANV_PIPE_DEPTH_STALL_BIT;
4353a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand         pipe.CommandStreamerStallEnable = bits & ANV_PIPE_CS_STALL_BIT;
4363a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand         pipe.StallAtPixelScoreboard = bits & ANV_PIPE_STALL_AT_SCOREBOARD_BIT;
4373a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand
4383a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand         /*
4393a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand          * According to the Broadwell documentation, any PIPE_CONTROL with the
4403a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand          * "Command Streamer Stall" bit set must also have another bit set,
4413a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand          * with five different options:
4423a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand          *
4433a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand          *  - Render Target Cache Flush
4443a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand          *  - Depth Cache Flush
4453a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand          *  - Stall at Pixel Scoreboard
4463a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand          *  - Post-Sync Operation
4473a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand          *  - Depth Stall
4483a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand          *  - DC Flush Enable
4493a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand          *
4503a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand          * I chose "Stall at Pixel Scoreboard" since that's what we use in
4513a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand          * mesa and it seems to work fine. The choice is fairly arbitrary.
4523a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand          */
4533a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand         if ((bits & ANV_PIPE_CS_STALL_BIT) &&
4543a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand             !(bits & (ANV_PIPE_FLUSH_BITS | ANV_PIPE_DEPTH_STALL_BIT |
4553a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand                       ANV_PIPE_STALL_AT_SCOREBOARD_BIT)))
4563a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand            pipe.StallAtPixelScoreboard = true;
4573a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand      }
4583a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand
4593a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand      bits &= ~(ANV_PIPE_FLUSH_BITS | ANV_PIPE_CS_STALL_BIT);
4603a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand   }
4613a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand
4623a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand   if (bits & ANV_PIPE_INVALIDATE_BITS) {
4633a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand      anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pipe) {
4643a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand         pipe.StateCacheInvalidationEnable =
4653a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand            bits & ANV_PIPE_STATE_CACHE_INVALIDATE_BIT;
4663a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand         pipe.ConstantCacheInvalidationEnable =
4673a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand            bits & ANV_PIPE_CONSTANT_CACHE_INVALIDATE_BIT;
4683a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand         pipe.VFCacheInvalidationEnable =
4693a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand            bits & ANV_PIPE_VF_CACHE_INVALIDATE_BIT;
4703a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand         pipe.TextureCacheInvalidationEnable =
4713a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand            bits & ANV_PIPE_TEXTURE_CACHE_INVALIDATE_BIT;
4723a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand         pipe.InstructionCacheInvalidateEnable =
4733a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand            bits & ANV_PIPE_INSTRUCTION_CACHE_INVALIDATE_BIT;
4743a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand      }
4753a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand
4763a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand      bits &= ~ANV_PIPE_INVALIDATE_BITS;
4773a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand   }
4783a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand
4793a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand   cmd_buffer->state.pending_pipe_bits = bits;
4803a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand}
4813a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand
4826f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrandvoid genX(CmdPipelineBarrier)(
483a89a485e79ad40793a85979d86d45760362be21aJason Ekstrand    VkCommandBuffer                             commandBuffer,
4846f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    VkPipelineStageFlags                        srcStageMask,
4856f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    VkPipelineStageFlags                        destStageMask,
4866f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    VkBool32                                    byRegion,
487c310fb032d406984e72895b6c94e2f96bff8e70dJason Ekstrand    uint32_t                                    memoryBarrierCount,
488c310fb032d406984e72895b6c94e2f96bff8e70dJason Ekstrand    const VkMemoryBarrier*                      pMemoryBarriers,
489c310fb032d406984e72895b6c94e2f96bff8e70dJason Ekstrand    uint32_t                                    bufferMemoryBarrierCount,
490c310fb032d406984e72895b6c94e2f96bff8e70dJason Ekstrand    const VkBufferMemoryBarrier*                pBufferMemoryBarriers,
491c310fb032d406984e72895b6c94e2f96bff8e70dJason Ekstrand    uint32_t                                    imageMemoryBarrierCount,
492c310fb032d406984e72895b6c94e2f96bff8e70dJason Ekstrand    const VkImageMemoryBarrier*                 pImageMemoryBarriers)
4936f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand{
494a89a485e79ad40793a85979d86d45760362be21aJason Ekstrand   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
4953a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand   uint32_t b;
4966f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand
4976f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand   /* XXX: Right now, we're really dumb and just flush whatever categories
4986f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    * the app asks for.  One of these days we may make this a bit better
4996f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    * but right now that's all the hardware allows for in most areas.
5006f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand    */
501b1cd025b88e3651fac8dd2f7861516f653422ee4Jason Ekstrand   VkAccessFlags src_flags = 0;
502b1cd025b88e3651fac8dd2f7861516f653422ee4Jason Ekstrand   VkAccessFlags dst_flags = 0;
5036f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand
504c310fb032d406984e72895b6c94e2f96bff8e70dJason Ekstrand   for (uint32_t i = 0; i < memoryBarrierCount; i++) {
505c310fb032d406984e72895b6c94e2f96bff8e70dJason Ekstrand      src_flags |= pMemoryBarriers[i].srcAccessMask;
506c310fb032d406984e72895b6c94e2f96bff8e70dJason Ekstrand      dst_flags |= pMemoryBarriers[i].dstAccessMask;
507c310fb032d406984e72895b6c94e2f96bff8e70dJason Ekstrand   }
508c310fb032d406984e72895b6c94e2f96bff8e70dJason Ekstrand
509c310fb032d406984e72895b6c94e2f96bff8e70dJason Ekstrand   for (uint32_t i = 0; i < bufferMemoryBarrierCount; i++) {
510c310fb032d406984e72895b6c94e2f96bff8e70dJason Ekstrand      src_flags |= pBufferMemoryBarriers[i].srcAccessMask;
511c310fb032d406984e72895b6c94e2f96bff8e70dJason Ekstrand      dst_flags |= pBufferMemoryBarriers[i].dstAccessMask;
512c310fb032d406984e72895b6c94e2f96bff8e70dJason Ekstrand   }
513c310fb032d406984e72895b6c94e2f96bff8e70dJason Ekstrand
514c310fb032d406984e72895b6c94e2f96bff8e70dJason Ekstrand   for (uint32_t i = 0; i < imageMemoryBarrierCount; i++) {
515c310fb032d406984e72895b6c94e2f96bff8e70dJason Ekstrand      src_flags |= pImageMemoryBarriers[i].srcAccessMask;
516c310fb032d406984e72895b6c94e2f96bff8e70dJason Ekstrand      dst_flags |= pImageMemoryBarriers[i].dstAccessMask;
5176f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand   }
5186f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand
5193a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand   enum anv_pipe_bits pipe_bits = 0;
5205e92e91c6177bfe31214b8a0ebd0d4c47969b61dKristian Høgsberg
521924fbfc9a1fc46a3698fa23649e6dccc3e3e6782Jason Ekstrand   for_each_bit(b, src_flags) {
522b1cd025b88e3651fac8dd2f7861516f653422ee4Jason Ekstrand      switch ((VkAccessFlagBits)(1 << b)) {
523b1cd025b88e3651fac8dd2f7861516f653422ee4Jason Ekstrand      case VK_ACCESS_SHADER_WRITE_BIT:
5243a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand         pipe_bits |= ANV_PIPE_DATA_CACHE_FLUSH_BIT;
5256f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand         break;
526b1cd025b88e3651fac8dd2f7861516f653422ee4Jason Ekstrand      case VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT:
5273a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand         pipe_bits |= ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT;
5286f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand         break;
529b1cd025b88e3651fac8dd2f7861516f653422ee4Jason Ekstrand      case VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT:
5303a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand         pipe_bits |= ANV_PIPE_DEPTH_CACHE_FLUSH_BIT;
5316f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand         break;
532b1cd025b88e3651fac8dd2f7861516f653422ee4Jason Ekstrand      case VK_ACCESS_TRANSFER_WRITE_BIT:
5333a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand         pipe_bits |= ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT;
5343a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand         pipe_bits |= ANV_PIPE_DEPTH_CACHE_FLUSH_BIT;
5356f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand         break;
5366f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand      default:
5373a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand         break; /* Nothing to do */
5386f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand      }
5396f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand   }
5406f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand
541924fbfc9a1fc46a3698fa23649e6dccc3e3e6782Jason Ekstrand   for_each_bit(b, dst_flags) {
542b1cd025b88e3651fac8dd2f7861516f653422ee4Jason Ekstrand      switch ((VkAccessFlagBits)(1 << b)) {
543b1cd025b88e3651fac8dd2f7861516f653422ee4Jason Ekstrand      case VK_ACCESS_INDIRECT_COMMAND_READ_BIT:
544b1cd025b88e3651fac8dd2f7861516f653422ee4Jason Ekstrand      case VK_ACCESS_INDEX_READ_BIT:
545b1cd025b88e3651fac8dd2f7861516f653422ee4Jason Ekstrand      case VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT:
5463a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand         pipe_bits |= ANV_PIPE_VF_CACHE_INVALIDATE_BIT;
5476f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand         break;
548b1cd025b88e3651fac8dd2f7861516f653422ee4Jason Ekstrand      case VK_ACCESS_UNIFORM_READ_BIT:
5493a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand         pipe_bits |= ANV_PIPE_CONSTANT_CACHE_INVALIDATE_BIT;
5503a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand         pipe_bits |= ANV_PIPE_TEXTURE_CACHE_INVALIDATE_BIT;
5516f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand         break;
5523a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand      case VK_ACCESS_SHADER_READ_BIT:
553b1cd025b88e3651fac8dd2f7861516f653422ee4Jason Ekstrand      case VK_ACCESS_COLOR_ATTACHMENT_READ_BIT:
554b1cd025b88e3651fac8dd2f7861516f653422ee4Jason Ekstrand      case VK_ACCESS_TRANSFER_READ_BIT:
5553a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand         pipe_bits |= ANV_PIPE_TEXTURE_CACHE_INVALIDATE_BIT;
556b1cd025b88e3651fac8dd2f7861516f653422ee4Jason Ekstrand         break;
557b1cd025b88e3651fac8dd2f7861516f653422ee4Jason Ekstrand      default:
5583a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand         break; /* Nothing to do */
5596f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand      }
5606f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand   }
5616f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand
5623a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand   cmd_buffer->state.pending_pipe_bits |= pipe_bits;
5636f613abc2bf8fc3cf70c51a1d569bc4eb9dd18afJason Ekstrand}
564bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg
56554324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrandstatic void
56654324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrandcmd_buffer_alloc_push_constants(struct anv_cmd_buffer *cmd_buffer)
56754324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand{
56854324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand   VkShaderStageFlags stages = cmd_buffer->state.pipeline->active_stages;
56954324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand
57054324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand   /* In order to avoid thrash, we assume that vertex and fragment stages
57154324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand    * always exist.  In the rare case where one is missing *and* the other
57254324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand    * uses push concstants, this may be suboptimal.  However, avoiding stalls
57354324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand    * seems more important.
57454324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand    */
57554324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand   stages |= VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_VERTEX_BIT;
57654324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand
57754324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand   if (stages == cmd_buffer->state.push_constant_stages)
57854324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand      return;
57954324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand
58054324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand#if GEN_GEN >= 8
58154324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand   const unsigned push_constant_kb = 32;
58254324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand#elif GEN_IS_HASWELL
58354324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand   const unsigned push_constant_kb = cmd_buffer->device->info.gt == 3 ? 32 : 16;
58454324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand#else
58554324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand   const unsigned push_constant_kb = 16;
58654324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand#endif
58754324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand
58854324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand   const unsigned num_stages =
58954324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand      _mesa_bitcount(stages & VK_SHADER_STAGE_ALL_GRAPHICS);
59054324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand   unsigned size_per_stage = push_constant_kb / num_stages;
59154324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand
59254324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand   /* Broadwell+ and Haswell gt3 require that the push constant sizes be in
59354324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand    * units of 2KB.  Incidentally, these are the same platforms that have
59454324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand    * 32KB worth of push constant space.
59554324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand    */
59654324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand   if (push_constant_kb == 32)
59754324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand      size_per_stage &= ~1u;
59854324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand
59954324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand   uint32_t kb_used = 0;
60054324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand   for (int i = MESA_SHADER_VERTEX; i < MESA_SHADER_FRAGMENT; i++) {
60154324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand      unsigned push_size = (stages & (1 << i)) ? size_per_stage : 0;
60254324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand      anv_batch_emit(&cmd_buffer->batch,
60354324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand                     GENX(3DSTATE_PUSH_CONSTANT_ALLOC_VS), alloc) {
60454324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand         alloc._3DCommandSubOpcode  = 18 + i;
60554324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand         alloc.ConstantBufferOffset = (push_size > 0) ? kb_used : 0;
60654324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand         alloc.ConstantBufferSize   = push_size;
60754324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand      }
60854324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand      kb_used += push_size;
60954324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand   }
61054324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand
61154324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand   anv_batch_emit(&cmd_buffer->batch,
61254324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand                  GENX(3DSTATE_PUSH_CONSTANT_ALLOC_PS), alloc) {
61354324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand      alloc.ConstantBufferOffset = kb_used;
61454324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand      alloc.ConstantBufferSize = push_constant_kb - kb_used;
61554324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand   }
61654324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand
61754324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand   cmd_buffer->state.push_constant_stages = stages;
61854324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand
61954324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand   /* From the BDW PRM for 3DSTATE_PUSH_CONSTANT_ALLOC_VS:
62054324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand    *
62154324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand    *    "The 3DSTATE_CONSTANT_VS must be reprogrammed prior to
62254324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand    *    the next 3DPRIMITIVE command after programming the
62354324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand    *    3DSTATE_PUSH_CONSTANT_ALLOC_VS"
62454324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand    *
62554324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand    * Since 3DSTATE_PUSH_CONSTANT_ALLOC_VS is programmed as part of
62654324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand    * pipeline setup, we need to dirty push constants.
62754324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand    */
62854324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand   cmd_buffer->state.push_constants_dirty |= VK_SHADER_STAGE_ALL_GRAPHICS;
62954324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand}
63054324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand
6312bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrandstatic void
6322bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrandcmd_buffer_emit_descriptor_pointers(struct anv_cmd_buffer *cmd_buffer,
6332bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand                                    uint32_t stages)
6342bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand{
6352bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand   static const uint32_t sampler_state_opcodes[] = {
6362bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand      [MESA_SHADER_VERTEX]                      = 43,
6372bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand      [MESA_SHADER_TESS_CTRL]                   = 44, /* HS */
6382bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand      [MESA_SHADER_TESS_EVAL]                   = 45, /* DS */
6392bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand      [MESA_SHADER_GEOMETRY]                    = 46,
6402bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand      [MESA_SHADER_FRAGMENT]                    = 47,
6412bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand      [MESA_SHADER_COMPUTE]                     = 0,
6422bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand   };
6432bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand
6442bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand   static const uint32_t binding_table_opcodes[] = {
6452bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand      [MESA_SHADER_VERTEX]                      = 38,
6462bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand      [MESA_SHADER_TESS_CTRL]                   = 39,
6472bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand      [MESA_SHADER_TESS_EVAL]                   = 40,
6482bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand      [MESA_SHADER_GEOMETRY]                    = 41,
6492bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand      [MESA_SHADER_FRAGMENT]                    = 42,
6502bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand      [MESA_SHADER_COMPUTE]                     = 0,
6512bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand   };
6522bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand
6532bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand   anv_foreach_stage(s, stages) {
6542bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand      if (cmd_buffer->state.samplers[s].alloc_size > 0) {
6552bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand         anv_batch_emit(&cmd_buffer->batch,
6562bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand                        GENX(3DSTATE_SAMPLER_STATE_POINTERS_VS), ssp) {
6572bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand            ssp._3DCommandSubOpcode = sampler_state_opcodes[s];
6582bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand            ssp.PointertoVSSamplerState = cmd_buffer->state.samplers[s].offset;
6592bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand         }
6602bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand      }
6612bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand
6622bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand      /* Always emit binding table pointers if we're asked to, since on SKL
6632bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand       * this is what flushes push constants. */
6642bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand      anv_batch_emit(&cmd_buffer->batch,
6652bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand                     GENX(3DSTATE_BINDING_TABLE_POINTERS_VS), btp) {
6662bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand         btp._3DCommandSubOpcode = binding_table_opcodes[s];
6672bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand         btp.PointertoVSBindingTable = cmd_buffer->state.binding_tables[s].offset;
6682bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand      }
6692bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand   }
6702bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand}
6712bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand
672248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrandstatic uint32_t
673248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrandcmd_buffer_flush_push_constants(struct anv_cmd_buffer *cmd_buffer)
674248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand{
675248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand   static const uint32_t push_constant_opcodes[] = {
676248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand      [MESA_SHADER_VERTEX]                      = 21,
677248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand      [MESA_SHADER_TESS_CTRL]                   = 25, /* HS */
678248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand      [MESA_SHADER_TESS_EVAL]                   = 26, /* DS */
679248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand      [MESA_SHADER_GEOMETRY]                    = 22,
680248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand      [MESA_SHADER_FRAGMENT]                    = 23,
681248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand      [MESA_SHADER_COMPUTE]                     = 0,
682248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand   };
683248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand
684248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand   VkShaderStageFlags flushed = 0;
685248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand
686248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand   anv_foreach_stage(stage, cmd_buffer->state.push_constants_dirty) {
687248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand      if (stage == MESA_SHADER_COMPUTE)
688248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand         continue;
689248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand
690248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand      struct anv_state state = anv_cmd_buffer_push_constants(cmd_buffer, stage);
691248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand
692248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand      if (state.offset == 0) {
69350018522d2f2e1deb91710d63e0985c0b3dc8818Jason Ekstrand         anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_CONSTANT_VS), c)
69406fc7fa6842a5b36ed2a16d5a7ca72e516d5b245Jason Ekstrand            c._3DCommandSubOpcode = push_constant_opcodes[stage];
695248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand      } else {
69650018522d2f2e1deb91710d63e0985c0b3dc8818Jason Ekstrand         anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_CONSTANT_VS), c) {
69706fc7fa6842a5b36ed2a16d5a7ca72e516d5b245Jason Ekstrand            c._3DCommandSubOpcode = push_constant_opcodes[stage],
69806fc7fa6842a5b36ed2a16d5a7ca72e516d5b245Jason Ekstrand            c.ConstantBody = (struct GENX(3DSTATE_CONSTANT_BODY)) {
699248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand#if GEN_GEN >= 9
70006fc7fa6842a5b36ed2a16d5a7ca72e516d5b245Jason Ekstrand               .PointerToConstantBuffer2 = { &cmd_buffer->device->dynamic_state_block_pool.bo, state.offset },
70106fc7fa6842a5b36ed2a16d5a7ca72e516d5b245Jason Ekstrand               .ConstantBuffer2ReadLength = DIV_ROUND_UP(state.alloc_size, 32),
702248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand#else
70306fc7fa6842a5b36ed2a16d5a7ca72e516d5b245Jason Ekstrand               .PointerToConstantBuffer0 = { .offset = state.offset },
70406fc7fa6842a5b36ed2a16d5a7ca72e516d5b245Jason Ekstrand               .ConstantBuffer0ReadLength = DIV_ROUND_UP(state.alloc_size, 32),
705248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand#endif
70606fc7fa6842a5b36ed2a16d5a7ca72e516d5b245Jason Ekstrand            };
70706fc7fa6842a5b36ed2a16d5a7ca72e516d5b245Jason Ekstrand         }
708248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand      }
709248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand
710248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand      flushed |= mesa_to_vk_shader_stage(stage);
711248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand   }
712248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand
713248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand   cmd_buffer->state.push_constants_dirty &= ~VK_SHADER_STAGE_ALL_GRAPHICS;
714248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand
715248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand   return flushed;
716248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand}
717248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand
718248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrandvoid
719248ab61740c4082517424f5aa94b2f4e7b210d76Jason EkstrandgenX(cmd_buffer_flush_state)(struct anv_cmd_buffer *cmd_buffer)
720248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand{
721248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand   struct anv_pipeline *pipeline = cmd_buffer->state.pipeline;
722248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand   uint32_t *p;
723248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand
724248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand   uint32_t vb_emit = cmd_buffer->state.vb_dirty & pipeline->vb_used;
725248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand
726248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand   assert((pipeline->active_stages & VK_SHADER_STAGE_COMPUTE_BIT) == 0);
727248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand
7287e891f90c701aa1c851f1846857daa75bbb65876Jason Ekstrand   genX(cmd_buffer_config_l3)(cmd_buffer, pipeline->urb.l3_config);
729248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand
730248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand   genX(flush_pipeline_select_3d)(cmd_buffer);
731248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand
732248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand   if (vb_emit) {
733248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand      const uint32_t num_buffers = __builtin_popcount(vb_emit);
734248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand      const uint32_t num_dwords = 1 + num_buffers * 4;
735248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand
736248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand      p = anv_batch_emitn(&cmd_buffer->batch, num_dwords,
737248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand                          GENX(3DSTATE_VERTEX_BUFFERS));
738248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand      uint32_t vb, i = 0;
739248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand      for_each_bit(vb, vb_emit) {
740248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand         struct anv_buffer *buffer = cmd_buffer->state.vertex_bindings[vb].buffer;
741248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand         uint32_t offset = cmd_buffer->state.vertex_bindings[vb].offset;
742248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand
743248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand         struct GENX(VERTEX_BUFFER_STATE) state = {
744248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand            .VertexBufferIndex = vb,
745248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand
746248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand#if GEN_GEN >= 8
747248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand            .MemoryObjectControlState = GENX(MOCS),
748248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand#else
749248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand            .BufferAccessType = pipeline->instancing_enable[vb] ? INSTANCEDATA : VERTEXDATA,
750248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand            .InstanceDataStepRate = 1,
751248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand            .VertexBufferMemoryObjectControlState = GENX(MOCS),
752248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand#endif
753248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand
754248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand            .AddressModifyEnable = true,
755248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand            .BufferPitch = pipeline->binding_stride[vb],
756248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand            .BufferStartingAddress = { buffer->bo, buffer->offset + offset },
757248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand
758248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand#if GEN_GEN >= 8
759248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand            .BufferSize = buffer->size - offset
760248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand#else
761248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand            .EndAddress = { buffer->bo, buffer->offset + buffer->size - 1},
762248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand#endif
763248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand         };
764248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand
765248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand         GENX(VERTEX_BUFFER_STATE_pack)(&cmd_buffer->batch, &p[1 + i * 4], &state);
766248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand         i++;
767248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand      }
768248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand   }
769248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand
770248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand   cmd_buffer->state.vb_dirty &= ~vb_emit;
771248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand
772248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand   if (cmd_buffer->state.dirty & ANV_CMD_DIRTY_PIPELINE) {
773248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand      anv_batch_emit_batch(&cmd_buffer->batch, &pipeline->batch);
774248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand
77535b53c8d47d3a0b53ee2549d73296d5db8e3cca0Jason Ekstrand      /* The exact descriptor layout is pulled from the pipeline, so we need
77635b53c8d47d3a0b53ee2549d73296d5db8e3cca0Jason Ekstrand       * to re-emit binding tables on every pipeline change.
77735b53c8d47d3a0b53ee2549d73296d5db8e3cca0Jason Ekstrand       */
77835b53c8d47d3a0b53ee2549d73296d5db8e3cca0Jason Ekstrand      cmd_buffer->state.descriptors_dirty |=
77935b53c8d47d3a0b53ee2549d73296d5db8e3cca0Jason Ekstrand         cmd_buffer->state.pipeline->active_stages;
78035b53c8d47d3a0b53ee2549d73296d5db8e3cca0Jason Ekstrand
78154324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand      /* If the pipeline changed, we may need to re-allocate push constant
78254324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand       * space in the URB.
783248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand       */
78454324877926caa28b8ebd89d95b4e7c2447d17b8Jason Ekstrand      cmd_buffer_alloc_push_constants(cmd_buffer);
785248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand   }
786248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand
787248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand#if GEN_GEN <= 7
788248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand   if (cmd_buffer->state.descriptors_dirty & VK_SHADER_STAGE_VERTEX_BIT ||
789248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand       cmd_buffer->state.push_constants_dirty & VK_SHADER_STAGE_VERTEX_BIT) {
790248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand      /* From the IVB PRM Vol. 2, Part 1, Section 3.2.1:
791248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand       *
792248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand       *    "A PIPE_CONTROL with Post-Sync Operation set to 1h and a depth
793248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand       *    stall needs to be sent just prior to any 3DSTATE_VS,
794248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand       *    3DSTATE_URB_VS, 3DSTATE_CONSTANT_VS,
795248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand       *    3DSTATE_BINDING_TABLE_POINTER_VS,
796248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand       *    3DSTATE_SAMPLER_STATE_POINTER_VS command.  Only one
797248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand       *    PIPE_CONTROL needs to be sent before any combination of VS
798248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand       *    associated 3DSTATE."
799248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand       */
80050018522d2f2e1deb91710d63e0985c0b3dc8818Jason Ekstrand      anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pc) {
80156453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand         pc.DepthStallEnable  = true;
80256453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand         pc.PostSyncOperation = WriteImmediateData;
80356453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand         pc.Address           =
80456453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand            (struct anv_address) { &cmd_buffer->device->workaround_bo, 0 };
80556453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand      }
806248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand   }
807248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand#endif
808248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand
809fe4e276b02615b5db8acbf4c65fcfa68982e2e0fJason Ekstrand   /* Render targets live in the same binding table as fragment descriptors */
810fe4e276b02615b5db8acbf4c65fcfa68982e2e0fJason Ekstrand   if (cmd_buffer->state.dirty & ANV_CMD_DIRTY_RENDER_TARGETS)
811fe4e276b02615b5db8acbf4c65fcfa68982e2e0fJason Ekstrand      cmd_buffer->state.descriptors_dirty |= VK_SHADER_STAGE_FRAGMENT_BIT;
812fe4e276b02615b5db8acbf4c65fcfa68982e2e0fJason Ekstrand
813248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand   /* We emit the binding tables and sampler tables first, then emit push
814248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand    * constants and then finally emit binding table and sampler table
815248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand    * pointers.  It has to happen in this order, since emitting the binding
816248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand    * tables may change the push constants (in case of storage images). After
817248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand    * emitting push constants, on SKL+ we have to emit the corresponding
818248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand    * 3DSTATE_BINDING_TABLE_POINTER_* for the push constants to take effect.
819248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand    */
820248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand   uint32_t dirty = 0;
821248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand   if (cmd_buffer->state.descriptors_dirty)
8229df4d6bb36268d5dd248b872611e3787de9608beJason Ekstrand      dirty = anv_cmd_buffer_flush_descriptor_sets(cmd_buffer);
823248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand
824248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand   if (cmd_buffer->state.push_constants_dirty) {
825248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand#if GEN_GEN >= 9
826248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand      /* On Sky Lake and later, the binding table pointers commands are
827248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand       * what actually flush the changes to push constant state so we need
828248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand       * to dirty them so they get re-emitted below.
829248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand       */
830248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand      dirty |= cmd_buffer_flush_push_constants(cmd_buffer);
831248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand#else
832248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand      cmd_buffer_flush_push_constants(cmd_buffer);
833248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand#endif
834248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand   }
835248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand
836248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand   if (dirty)
8372bfe0c33748b9fd96d48cb93656b6dc643bf024eJason Ekstrand      cmd_buffer_emit_descriptor_pointers(cmd_buffer, dirty);
838248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand
839eb6764c4a73006eee32e19e3afc6eab100a2ce16Jason Ekstrand   if (cmd_buffer->state.dirty & ANV_CMD_DIRTY_DYNAMIC_VIEWPORT)
840248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand      gen8_cmd_buffer_emit_viewport(cmd_buffer);
841eb6764c4a73006eee32e19e3afc6eab100a2ce16Jason Ekstrand
842eb6764c4a73006eee32e19e3afc6eab100a2ce16Jason Ekstrand   if (cmd_buffer->state.dirty & (ANV_CMD_DIRTY_DYNAMIC_VIEWPORT |
843eb6764c4a73006eee32e19e3afc6eab100a2ce16Jason Ekstrand                                  ANV_CMD_DIRTY_PIPELINE)) {
844eb6764c4a73006eee32e19e3afc6eab100a2ce16Jason Ekstrand      gen8_cmd_buffer_emit_depth_viewport(cmd_buffer,
845eb6764c4a73006eee32e19e3afc6eab100a2ce16Jason Ekstrand                                          pipeline->depth_clamp_enable);
8468a46b505cb2c7255ad430b56c1ce0dfa9c13c559Jason Ekstrand   }
847248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand
848248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand   if (cmd_buffer->state.dirty & ANV_CMD_DIRTY_DYNAMIC_SCISSOR)
849248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand      gen7_cmd_buffer_emit_scissor(cmd_buffer);
850248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand
851248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand   genX(cmd_buffer_flush_dynamic_state)(cmd_buffer);
8523a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand
8533a83c176eab8c513eb723554a240af1a7308d701Jason Ekstrand   genX(cmd_buffer_apply_pipe_flushes)(cmd_buffer);
854248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand}
855248ab61740c4082517424f5aa94b2f4e7b210d76Jason Ekstrand
856bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsbergstatic void
857bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsbergemit_base_vertex_instance_bo(struct anv_cmd_buffer *cmd_buffer,
858bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg                             struct anv_bo *bo, uint32_t offset)
859bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg{
860bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg   uint32_t *p = anv_batch_emitn(&cmd_buffer->batch, 5,
861bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg                                 GENX(3DSTATE_VERTEX_BUFFERS));
862bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg
863bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg   GENX(VERTEX_BUFFER_STATE_pack)(&cmd_buffer->batch, p + 1,
864bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg      &(struct GENX(VERTEX_BUFFER_STATE)) {
865bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg         .VertexBufferIndex = 32, /* Reserved for this */
866bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg         .AddressModifyEnable = true,
867bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg         .BufferPitch = 0,
868371b4a5b33a13f35fa7783510d2d90685a9a2e8aJason Ekstrand#if (GEN_GEN >= 8)
869bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg         .MemoryObjectControlState = GENX(MOCS),
870bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg         .BufferStartingAddress = { bo, offset },
871bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg         .BufferSize = 8
872bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg#else
873bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg         .VertexBufferMemoryObjectControlState = GENX(MOCS),
874bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg         .BufferStartingAddress = { bo, offset },
875bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg         .EndAddress = { bo, offset + 8 },
876bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg#endif
877bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg      });
878bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg}
879bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg
880bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsbergstatic void
881bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsbergemit_base_vertex_instance(struct anv_cmd_buffer *cmd_buffer,
882bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg                          uint32_t base_vertex, uint32_t base_instance)
883bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg{
884bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg   struct anv_state id_state =
885bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg      anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, 8, 4);
886bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg
887bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg   ((uint32_t *)id_state.map)[0] = base_vertex;
888bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg   ((uint32_t *)id_state.map)[1] = base_instance;
889bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg
890bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg   if (!cmd_buffer->device->info.has_llc)
891bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg      anv_state_clflush(id_state);
892bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg
893bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg   emit_base_vertex_instance_bo(cmd_buffer,
894bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg      &cmd_buffer->device->dynamic_state_block_pool.bo, id_state.offset);
895bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg}
896bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg
897bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsbergvoid genX(CmdDraw)(
898bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg    VkCommandBuffer                             commandBuffer,
899bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg    uint32_t                                    vertexCount,
900bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg    uint32_t                                    instanceCount,
901bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg    uint32_t                                    firstVertex,
902bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg    uint32_t                                    firstInstance)
903bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg{
904bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
905bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg   struct anv_pipeline *pipeline = cmd_buffer->state.pipeline;
9062b29342fae14d8626ca58f8a7ec358b70886ced3Kristian Høgsberg   const struct brw_vs_prog_data *vs_prog_data = get_vs_prog_data(pipeline);
907bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg
908bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg   genX(cmd_buffer_flush_state)(cmd_buffer);
909bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg
9102b29342fae14d8626ca58f8a7ec358b70886ced3Kristian Høgsberg   if (vs_prog_data->uses_basevertex || vs_prog_data->uses_baseinstance)
911bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg      emit_base_vertex_instance(cmd_buffer, firstVertex, firstInstance);
912bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg
91350018522d2f2e1deb91710d63e0985c0b3dc8818Jason Ekstrand   anv_batch_emit(&cmd_buffer->batch, GENX(3DPRIMITIVE), prim) {
9141d4d6852b469c5e726137953ce47d2ee6ed60bdaJason Ekstrand      prim.VertexAccessType         = SEQUENTIAL;
9151d4d6852b469c5e726137953ce47d2ee6ed60bdaJason Ekstrand      prim.PrimitiveTopologyType    = pipeline->topology;
9161d4d6852b469c5e726137953ce47d2ee6ed60bdaJason Ekstrand      prim.VertexCountPerInstance   = vertexCount;
9171d4d6852b469c5e726137953ce47d2ee6ed60bdaJason Ekstrand      prim.StartVertexLocation      = firstVertex;
9181d4d6852b469c5e726137953ce47d2ee6ed60bdaJason Ekstrand      prim.InstanceCount            = instanceCount;
9191d4d6852b469c5e726137953ce47d2ee6ed60bdaJason Ekstrand      prim.StartInstanceLocation    = firstInstance;
9201d4d6852b469c5e726137953ce47d2ee6ed60bdaJason Ekstrand      prim.BaseVertexLocation       = 0;
9211d4d6852b469c5e726137953ce47d2ee6ed60bdaJason Ekstrand   }
922bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg}
923bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg
924bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsbergvoid genX(CmdDrawIndexed)(
925bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg    VkCommandBuffer                             commandBuffer,
926bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg    uint32_t                                    indexCount,
927bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg    uint32_t                                    instanceCount,
928bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg    uint32_t                                    firstIndex,
929bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg    int32_t                                     vertexOffset,
930bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg    uint32_t                                    firstInstance)
931bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg{
932bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
933bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg   struct anv_pipeline *pipeline = cmd_buffer->state.pipeline;
9342b29342fae14d8626ca58f8a7ec358b70886ced3Kristian Høgsberg   const struct brw_vs_prog_data *vs_prog_data = get_vs_prog_data(pipeline);
935bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg
936bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg   genX(cmd_buffer_flush_state)(cmd_buffer);
937bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg
9382b29342fae14d8626ca58f8a7ec358b70886ced3Kristian Høgsberg   if (vs_prog_data->uses_basevertex || vs_prog_data->uses_baseinstance)
939bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg      emit_base_vertex_instance(cmd_buffer, vertexOffset, firstInstance);
940bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg
94150018522d2f2e1deb91710d63e0985c0b3dc8818Jason Ekstrand   anv_batch_emit(&cmd_buffer->batch, GENX(3DPRIMITIVE), prim) {
9421d4d6852b469c5e726137953ce47d2ee6ed60bdaJason Ekstrand      prim.VertexAccessType         = RANDOM;
9431d4d6852b469c5e726137953ce47d2ee6ed60bdaJason Ekstrand      prim.PrimitiveTopologyType    = pipeline->topology;
9441d4d6852b469c5e726137953ce47d2ee6ed60bdaJason Ekstrand      prim.VertexCountPerInstance   = indexCount;
9451d4d6852b469c5e726137953ce47d2ee6ed60bdaJason Ekstrand      prim.StartVertexLocation      = firstIndex;
9461d4d6852b469c5e726137953ce47d2ee6ed60bdaJason Ekstrand      prim.InstanceCount            = instanceCount;
9471d4d6852b469c5e726137953ce47d2ee6ed60bdaJason Ekstrand      prim.StartInstanceLocation    = firstInstance;
9481d4d6852b469c5e726137953ce47d2ee6ed60bdaJason Ekstrand      prim.BaseVertexLocation       = vertexOffset;
9491d4d6852b469c5e726137953ce47d2ee6ed60bdaJason Ekstrand   }
950bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg}
951bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg
952bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg/* Auto-Draw / Indirect Registers */
953bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg#define GEN7_3DPRIM_END_OFFSET          0x2420
954bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg#define GEN7_3DPRIM_START_VERTEX        0x2430
955bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg#define GEN7_3DPRIM_VERTEX_COUNT        0x2434
956bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg#define GEN7_3DPRIM_INSTANCE_COUNT      0x2438
957bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg#define GEN7_3DPRIM_START_INSTANCE      0x243C
958bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg#define GEN7_3DPRIM_BASE_VERTEX         0x2440
959bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg
960bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsbergvoid genX(CmdDrawIndirect)(
961bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg    VkCommandBuffer                             commandBuffer,
962bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg    VkBuffer                                    _buffer,
963bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg    VkDeviceSize                                offset,
964bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg    uint32_t                                    drawCount,
965bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg    uint32_t                                    stride)
966bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg{
967bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
968bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg   ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
969bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg   struct anv_pipeline *pipeline = cmd_buffer->state.pipeline;
9702b29342fae14d8626ca58f8a7ec358b70886ced3Kristian Høgsberg   const struct brw_vs_prog_data *vs_prog_data = get_vs_prog_data(pipeline);
971bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg   struct anv_bo *bo = buffer->bo;
972bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg   uint32_t bo_offset = buffer->offset + offset;
973bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg
974bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg   genX(cmd_buffer_flush_state)(cmd_buffer);
975bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg
9762b29342fae14d8626ca58f8a7ec358b70886ced3Kristian Høgsberg   if (vs_prog_data->uses_basevertex || vs_prog_data->uses_baseinstance)
977bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg      emit_base_vertex_instance_bo(cmd_buffer, bo, bo_offset + 8);
978bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg
979bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_VERTEX_COUNT, bo, bo_offset);
980bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_INSTANCE_COUNT, bo, bo_offset + 4);
981bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_VERTEX, bo, bo_offset + 8);
982bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_INSTANCE, bo, bo_offset + 12);
983bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg   emit_lri(&cmd_buffer->batch, GEN7_3DPRIM_BASE_VERTEX, 0);
984bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg
98550018522d2f2e1deb91710d63e0985c0b3dc8818Jason Ekstrand   anv_batch_emit(&cmd_buffer->batch, GENX(3DPRIMITIVE), prim) {
9861d4d6852b469c5e726137953ce47d2ee6ed60bdaJason Ekstrand      prim.IndirectParameterEnable  = true;
9871d4d6852b469c5e726137953ce47d2ee6ed60bdaJason Ekstrand      prim.VertexAccessType         = SEQUENTIAL;
9881d4d6852b469c5e726137953ce47d2ee6ed60bdaJason Ekstrand      prim.PrimitiveTopologyType    = pipeline->topology;
9891d4d6852b469c5e726137953ce47d2ee6ed60bdaJason Ekstrand   }
990bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg}
991bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg
992bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsbergvoid genX(CmdDrawIndexedIndirect)(
993bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg    VkCommandBuffer                             commandBuffer,
994bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg    VkBuffer                                    _buffer,
995bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg    VkDeviceSize                                offset,
996bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg    uint32_t                                    drawCount,
997bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg    uint32_t                                    stride)
998bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg{
999bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
1000bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg   ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
1001bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg   struct anv_pipeline *pipeline = cmd_buffer->state.pipeline;
10022b29342fae14d8626ca58f8a7ec358b70886ced3Kristian Høgsberg   const struct brw_vs_prog_data *vs_prog_data = get_vs_prog_data(pipeline);
1003bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg   struct anv_bo *bo = buffer->bo;
1004bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg   uint32_t bo_offset = buffer->offset + offset;
1005bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg
1006bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg   genX(cmd_buffer_flush_state)(cmd_buffer);
1007bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg
1008bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg   /* TODO: We need to stomp base vertex to 0 somehow */
10092b29342fae14d8626ca58f8a7ec358b70886ced3Kristian Høgsberg   if (vs_prog_data->uses_basevertex || vs_prog_data->uses_baseinstance)
1010bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg      emit_base_vertex_instance_bo(cmd_buffer, bo, bo_offset + 12);
1011bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg
1012bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_VERTEX_COUNT, bo, bo_offset);
1013bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_INSTANCE_COUNT, bo, bo_offset + 4);
1014bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_VERTEX, bo, bo_offset + 8);
1015bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_BASE_VERTEX, bo, bo_offset + 12);
1016bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_INSTANCE, bo, bo_offset + 16);
1017bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg
101850018522d2f2e1deb91710d63e0985c0b3dc8818Jason Ekstrand   anv_batch_emit(&cmd_buffer->batch, GENX(3DPRIMITIVE), prim) {
10191d4d6852b469c5e726137953ce47d2ee6ed60bdaJason Ekstrand      prim.IndirectParameterEnable  = true;
10201d4d6852b469c5e726137953ce47d2ee6ed60bdaJason Ekstrand      prim.VertexAccessType         = RANDOM;
10211d4d6852b469c5e726137953ce47d2ee6ed60bdaJason Ekstrand      prim.PrimitiveTopologyType    = pipeline->topology;
10221d4d6852b469c5e726137953ce47d2ee6ed60bdaJason Ekstrand   }
1023bdefaae2b92c15af4f2bff41b0e689325e762dc7Kristian Høgsberg}
10246c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg
10258dbfa265a439904628c2d875885e80bc45a90a05Jordan Justen#if GEN_GEN == 7
10268dbfa265a439904628c2d875885e80bc45a90a05Jordan Justen
10278dbfa265a439904628c2d875885e80bc45a90a05Jordan Justenstatic bool
10288dbfa265a439904628c2d875885e80bc45a90a05Jordan Justenverify_cmd_parser(const struct anv_device *device,
10298dbfa265a439904628c2d875885e80bc45a90a05Jordan Justen                  int required_version,
10308dbfa265a439904628c2d875885e80bc45a90a05Jordan Justen                  const char *function)
10318dbfa265a439904628c2d875885e80bc45a90a05Jordan Justen{
10328dbfa265a439904628c2d875885e80bc45a90a05Jordan Justen   if (device->instance->physicalDevice.cmd_parser_version < required_version) {
10338dbfa265a439904628c2d875885e80bc45a90a05Jordan Justen      vk_errorf(VK_ERROR_FEATURE_NOT_PRESENT,
10348dbfa265a439904628c2d875885e80bc45a90a05Jordan Justen                "cmd parser version %d is required for %s",
10358dbfa265a439904628c2d875885e80bc45a90a05Jordan Justen                required_version, function);
10368dbfa265a439904628c2d875885e80bc45a90a05Jordan Justen      return false;
10378dbfa265a439904628c2d875885e80bc45a90a05Jordan Justen   } else {
10388dbfa265a439904628c2d875885e80bc45a90a05Jordan Justen      return true;
10398dbfa265a439904628c2d875885e80bc45a90a05Jordan Justen   }
10408dbfa265a439904628c2d875885e80bc45a90a05Jordan Justen}
10418dbfa265a439904628c2d875885e80bc45a90a05Jordan Justen
10428dbfa265a439904628c2d875885e80bc45a90a05Jordan Justen#endif
10436c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg
10446c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsbergvoid genX(CmdDispatch)(
10456c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg    VkCommandBuffer                             commandBuffer,
10466c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg    uint32_t                                    x,
10476c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg    uint32_t                                    y,
10486c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg    uint32_t                                    z)
10496c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg{
10506c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
10516c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg   struct anv_pipeline *pipeline = cmd_buffer->state.compute_pipeline;
10522b29342fae14d8626ca58f8a7ec358b70886ced3Kristian Høgsberg   const struct brw_cs_prog_data *prog_data = get_cs_prog_data(pipeline);
10536c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg
10546c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg   if (prog_data->uses_num_work_groups) {
10556c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg      struct anv_state state =
10566c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg         anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, 12, 4);
10576c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg      uint32_t *sizes = state.map;
10586c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg      sizes[0] = x;
10596c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg      sizes[1] = y;
10606c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg      sizes[2] = z;
10616c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg      if (!cmd_buffer->device->info.has_llc)
10626c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg         anv_state_clflush(state);
10636c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg      cmd_buffer->state.num_workgroups_offset = state.offset;
10646c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg      cmd_buffer->state.num_workgroups_bo =
10656c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg         &cmd_buffer->device->dynamic_state_block_pool.bo;
10666c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg   }
10676c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg
10686c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg   genX(cmd_buffer_flush_compute_state)(cmd_buffer);
10696c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg
107050018522d2f2e1deb91710d63e0985c0b3dc8818Jason Ekstrand   anv_batch_emit(&cmd_buffer->batch, GENX(GPGPU_WALKER), ggw) {
1071deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand      ggw.SIMDSize                     = prog_data->simd_size / 16;
1072deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand      ggw.ThreadDepthCounterMaximum    = 0;
1073deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand      ggw.ThreadHeightCounterMaximum   = 0;
10741b79e7ebbd77a7e714fafadd91459059aacf2407Jordan Justen      ggw.ThreadWidthCounterMaximum    = prog_data->threads - 1;
1075deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand      ggw.ThreadGroupIDXDimension      = x;
1076deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand      ggw.ThreadGroupIDYDimension      = y;
1077deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand      ggw.ThreadGroupIDZDimension      = z;
1078deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand      ggw.RightExecutionMask           = pipeline->cs_right_mask;
1079deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand      ggw.BottomExecutionMask          = 0xffffffff;
1080deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand   }
1081deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand
108250018522d2f2e1deb91710d63e0985c0b3dc8818Jason Ekstrand   anv_batch_emit(&cmd_buffer->batch, GENX(MEDIA_STATE_FLUSH), msf);
10836c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg}
10846c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg
10856c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg#define GPGPU_DISPATCHDIMX 0x2500
10866c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg#define GPGPU_DISPATCHDIMY 0x2504
10876c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg#define GPGPU_DISPATCHDIMZ 0x2508
10886c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg
108998cdce1ce4737cf09c5d9613a85bb118f0f1757bJordan Justen#define MI_PREDICATE_SRC0  0x2400
109098cdce1ce4737cf09c5d9613a85bb118f0f1757bJordan Justen#define MI_PREDICATE_SRC1  0x2408
109198cdce1ce4737cf09c5d9613a85bb118f0f1757bJordan Justen
10926c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsbergvoid genX(CmdDispatchIndirect)(
10936c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg    VkCommandBuffer                             commandBuffer,
10946c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg    VkBuffer                                    _buffer,
10956c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg    VkDeviceSize                                offset)
10966c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg{
10976c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
10986c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg   ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
10996c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg   struct anv_pipeline *pipeline = cmd_buffer->state.compute_pipeline;
11002b29342fae14d8626ca58f8a7ec358b70886ced3Kristian Høgsberg   const struct brw_cs_prog_data *prog_data = get_cs_prog_data(pipeline);
11016c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg   struct anv_bo *bo = buffer->bo;
11026c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg   uint32_t bo_offset = buffer->offset + offset;
1103da4745104cc02fc0052a2e05e37c69a4dce76eefJordan Justen   struct anv_batch *batch = &cmd_buffer->batch;
11046c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg
11058dbfa265a439904628c2d875885e80bc45a90a05Jordan Justen#if GEN_GEN == 7
11068dbfa265a439904628c2d875885e80bc45a90a05Jordan Justen   /* Linux 4.4 added command parser version 5 which allows the GPGPU
11078dbfa265a439904628c2d875885e80bc45a90a05Jordan Justen    * indirect dispatch registers to be written.
11088dbfa265a439904628c2d875885e80bc45a90a05Jordan Justen    */
1109f56f538ce4753a6fdd969b610f35433fd657e4eeJordan Justen   if (!verify_cmd_parser(cmd_buffer->device, 5, "vkCmdDispatchIndirect"))
11108dbfa265a439904628c2d875885e80bc45a90a05Jordan Justen      return;
11118dbfa265a439904628c2d875885e80bc45a90a05Jordan Justen#endif
11128dbfa265a439904628c2d875885e80bc45a90a05Jordan Justen
11136c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg   if (prog_data->uses_num_work_groups) {
11146c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg      cmd_buffer->state.num_workgroups_offset = bo_offset;
11156c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg      cmd_buffer->state.num_workgroups_bo = bo;
11166c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg   }
11176c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg
11186c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg   genX(cmd_buffer_flush_compute_state)(cmd_buffer);
11196c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg
1120da4745104cc02fc0052a2e05e37c69a4dce76eefJordan Justen   emit_lrm(batch, GPGPU_DISPATCHDIMX, bo, bo_offset);
1121da4745104cc02fc0052a2e05e37c69a4dce76eefJordan Justen   emit_lrm(batch, GPGPU_DISPATCHDIMY, bo, bo_offset + 4);
1122da4745104cc02fc0052a2e05e37c69a4dce76eefJordan Justen   emit_lrm(batch, GPGPU_DISPATCHDIMZ, bo, bo_offset + 8);
11236c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg
112498cdce1ce4737cf09c5d9613a85bb118f0f1757bJordan Justen#if GEN_GEN <= 7
112598cdce1ce4737cf09c5d9613a85bb118f0f1757bJordan Justen   /* Clear upper 32-bits of SRC0 and all 64-bits of SRC1 */
112698cdce1ce4737cf09c5d9613a85bb118f0f1757bJordan Justen   emit_lri(batch, MI_PREDICATE_SRC0 + 4, 0);
112798cdce1ce4737cf09c5d9613a85bb118f0f1757bJordan Justen   emit_lri(batch, MI_PREDICATE_SRC1 + 0, 0);
112898cdce1ce4737cf09c5d9613a85bb118f0f1757bJordan Justen   emit_lri(batch, MI_PREDICATE_SRC1 + 4, 0);
112998cdce1ce4737cf09c5d9613a85bb118f0f1757bJordan Justen
113098cdce1ce4737cf09c5d9613a85bb118f0f1757bJordan Justen   /* Load compute_dispatch_indirect_x_size into SRC0 */
113198cdce1ce4737cf09c5d9613a85bb118f0f1757bJordan Justen   emit_lrm(batch, MI_PREDICATE_SRC0, bo, bo_offset + 0);
113298cdce1ce4737cf09c5d9613a85bb118f0f1757bJordan Justen
113398cdce1ce4737cf09c5d9613a85bb118f0f1757bJordan Justen   /* predicate = (compute_dispatch_indirect_x_size == 0); */
113450018522d2f2e1deb91710d63e0985c0b3dc8818Jason Ekstrand   anv_batch_emit(batch, GENX(MI_PREDICATE), mip) {
1135deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand      mip.LoadOperation    = LOAD_LOAD;
1136deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand      mip.CombineOperation = COMBINE_SET;
1137deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand      mip.CompareOperation = COMPARE_SRCS_EQUAL;
1138deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand   }
113998cdce1ce4737cf09c5d9613a85bb118f0f1757bJordan Justen
114098cdce1ce4737cf09c5d9613a85bb118f0f1757bJordan Justen   /* Load compute_dispatch_indirect_y_size into SRC0 */
114198cdce1ce4737cf09c5d9613a85bb118f0f1757bJordan Justen   emit_lrm(batch, MI_PREDICATE_SRC0, bo, bo_offset + 4);
114298cdce1ce4737cf09c5d9613a85bb118f0f1757bJordan Justen
114398cdce1ce4737cf09c5d9613a85bb118f0f1757bJordan Justen   /* predicate |= (compute_dispatch_indirect_y_size == 0); */
114450018522d2f2e1deb91710d63e0985c0b3dc8818Jason Ekstrand   anv_batch_emit(batch, GENX(MI_PREDICATE), mip) {
1145deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand      mip.LoadOperation    = LOAD_LOAD;
1146deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand      mip.CombineOperation = COMBINE_OR;
1147deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand      mip.CompareOperation = COMPARE_SRCS_EQUAL;
1148deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand   }
114998cdce1ce4737cf09c5d9613a85bb118f0f1757bJordan Justen
115098cdce1ce4737cf09c5d9613a85bb118f0f1757bJordan Justen   /* Load compute_dispatch_indirect_z_size into SRC0 */
115198cdce1ce4737cf09c5d9613a85bb118f0f1757bJordan Justen   emit_lrm(batch, MI_PREDICATE_SRC0, bo, bo_offset + 8);
115298cdce1ce4737cf09c5d9613a85bb118f0f1757bJordan Justen
115398cdce1ce4737cf09c5d9613a85bb118f0f1757bJordan Justen   /* predicate |= (compute_dispatch_indirect_z_size == 0); */
115450018522d2f2e1deb91710d63e0985c0b3dc8818Jason Ekstrand   anv_batch_emit(batch, GENX(MI_PREDICATE), mip) {
1155deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand      mip.LoadOperation    = LOAD_LOAD;
1156deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand      mip.CombineOperation = COMBINE_OR;
1157deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand      mip.CompareOperation = COMPARE_SRCS_EQUAL;
1158deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand   }
115998cdce1ce4737cf09c5d9613a85bb118f0f1757bJordan Justen
116098cdce1ce4737cf09c5d9613a85bb118f0f1757bJordan Justen   /* predicate = !predicate; */
116198cdce1ce4737cf09c5d9613a85bb118f0f1757bJordan Justen#define COMPARE_FALSE                           1
116250018522d2f2e1deb91710d63e0985c0b3dc8818Jason Ekstrand   anv_batch_emit(batch, GENX(MI_PREDICATE), mip) {
1163deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand      mip.LoadOperation    = LOAD_LOADINV;
1164deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand      mip.CombineOperation = COMBINE_OR;
1165deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand      mip.CompareOperation = COMPARE_FALSE;
1166deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand   }
116798cdce1ce4737cf09c5d9613a85bb118f0f1757bJordan Justen#endif
116898cdce1ce4737cf09c5d9613a85bb118f0f1757bJordan Justen
116950018522d2f2e1deb91710d63e0985c0b3dc8818Jason Ekstrand   anv_batch_emit(batch, GENX(GPGPU_WALKER), ggw) {
1170deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand      ggw.IndirectParameterEnable      = true;
1171deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand      ggw.PredicateEnable              = GEN_GEN <= 7;
1172deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand      ggw.SIMDSize                     = prog_data->simd_size / 16;
1173deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand      ggw.ThreadDepthCounterMaximum    = 0;
1174deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand      ggw.ThreadHeightCounterMaximum   = 0;
11751b79e7ebbd77a7e714fafadd91459059aacf2407Jordan Justen      ggw.ThreadWidthCounterMaximum    = prog_data->threads - 1;
1176deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand      ggw.RightExecutionMask           = pipeline->cs_right_mask;
1177deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand      ggw.BottomExecutionMask          = 0xffffffff;
1178deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand   }
1179deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand
118050018522d2f2e1deb91710d63e0985c0b3dc8818Jason Ekstrand   anv_batch_emit(batch, GENX(MEDIA_STATE_FLUSH), msf);
11816c4c04690f30af655ad675b590836d3a84440c3aKristian Høgsberg}
1182832f73f512e9e6c21d495d7b07e229482371ef2fKristian Høgsberg
1183c8ec65a1f5a85dbef3210dc49684fcfed49b7ea2Jordan Justenstatic void
1184c8ec65a1f5a85dbef3210dc49684fcfed49b7ea2Jordan Justenflush_pipeline_before_pipeline_select(struct anv_cmd_buffer *cmd_buffer,
1185c8ec65a1f5a85dbef3210dc49684fcfed49b7ea2Jordan Justen                                      uint32_t pipeline)
1186c8ec65a1f5a85dbef3210dc49684fcfed49b7ea2Jordan Justen{
1187c8ec65a1f5a85dbef3210dc49684fcfed49b7ea2Jordan Justen#if GEN_GEN >= 8 && GEN_GEN < 10
1188c8ec65a1f5a85dbef3210dc49684fcfed49b7ea2Jordan Justen   /* From the Broadwell PRM, Volume 2a: Instructions, PIPELINE_SELECT:
1189c8ec65a1f5a85dbef3210dc49684fcfed49b7ea2Jordan Justen    *
1190c8ec65a1f5a85dbef3210dc49684fcfed49b7ea2Jordan Justen    *   Software must clear the COLOR_CALC_STATE Valid field in
1191c8ec65a1f5a85dbef3210dc49684fcfed49b7ea2Jordan Justen    *   3DSTATE_CC_STATE_POINTERS command prior to send a PIPELINE_SELECT
1192c8ec65a1f5a85dbef3210dc49684fcfed49b7ea2Jordan Justen    *   with Pipeline Select set to GPGPU.
1193c8ec65a1f5a85dbef3210dc49684fcfed49b7ea2Jordan Justen    *
1194c8ec65a1f5a85dbef3210dc49684fcfed49b7ea2Jordan Justen    * The internal hardware docs recommend the same workaround for Gen9
1195c8ec65a1f5a85dbef3210dc49684fcfed49b7ea2Jordan Justen    * hardware too.
1196c8ec65a1f5a85dbef3210dc49684fcfed49b7ea2Jordan Justen    */
1197c8ec65a1f5a85dbef3210dc49684fcfed49b7ea2Jordan Justen   if (pipeline == GPGPU)
119850018522d2f2e1deb91710d63e0985c0b3dc8818Jason Ekstrand      anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_CC_STATE_POINTERS), t);
1199b83785d86d2c7f07323920615c72a9f09695a9a7Jordan Justen#elif GEN_GEN <= 7
1200b83785d86d2c7f07323920615c72a9f09695a9a7Jordan Justen      /* From "BXML » GT » MI » vol1a GPU Overview » [Instruction]
1201b83785d86d2c7f07323920615c72a9f09695a9a7Jordan Justen       * PIPELINE_SELECT [DevBWR+]":
1202b83785d86d2c7f07323920615c72a9f09695a9a7Jordan Justen       *
1203b83785d86d2c7f07323920615c72a9f09695a9a7Jordan Justen       *   Project: DEVSNB+
1204b83785d86d2c7f07323920615c72a9f09695a9a7Jordan Justen       *
1205b83785d86d2c7f07323920615c72a9f09695a9a7Jordan Justen       *   Software must ensure all the write caches are flushed through a
1206b83785d86d2c7f07323920615c72a9f09695a9a7Jordan Justen       *   stalling PIPE_CONTROL command followed by another PIPE_CONTROL
1207b83785d86d2c7f07323920615c72a9f09695a9a7Jordan Justen       *   command to invalidate read only caches prior to programming
1208b83785d86d2c7f07323920615c72a9f09695a9a7Jordan Justen       *   MI_PIPELINE_SELECT command to change the Pipeline Select Mode.
1209b83785d86d2c7f07323920615c72a9f09695a9a7Jordan Justen       */
121050018522d2f2e1deb91710d63e0985c0b3dc8818Jason Ekstrand      anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pc) {
121156453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand         pc.RenderTargetCacheFlushEnable  = true;
121256453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand         pc.DepthCacheFlushEnable         = true;
121356453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand         pc.DCFlushEnable                 = true;
121456453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand         pc.PostSyncOperation             = NoWrite;
121556453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand         pc.CommandStreamerStallEnable    = true;
121656453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand      }
1217b83785d86d2c7f07323920615c72a9f09695a9a7Jordan Justen
121850018522d2f2e1deb91710d63e0985c0b3dc8818Jason Ekstrand      anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pc) {
121956453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand         pc.TextureCacheInvalidationEnable   = true;
122056453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand         pc.ConstantCacheInvalidationEnable  = true;
122156453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand         pc.StateCacheInvalidationEnable     = true;
122256453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand         pc.InstructionCacheInvalidateEnable = true;
122356453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand         pc.PostSyncOperation                = NoWrite;
122456453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand      }
1225c8ec65a1f5a85dbef3210dc49684fcfed49b7ea2Jordan Justen#endif
1226c8ec65a1f5a85dbef3210dc49684fcfed49b7ea2Jordan Justen}
1227c8ec65a1f5a85dbef3210dc49684fcfed49b7ea2Jordan Justen
1228832f73f512e9e6c21d495d7b07e229482371ef2fKristian Høgsbergvoid
1229832f73f512e9e6c21d495d7b07e229482371ef2fKristian HøgsberggenX(flush_pipeline_select_3d)(struct anv_cmd_buffer *cmd_buffer)
1230832f73f512e9e6c21d495d7b07e229482371ef2fKristian Høgsberg{
1231832f73f512e9e6c21d495d7b07e229482371ef2fKristian Høgsberg   if (cmd_buffer->state.current_pipeline != _3D) {
1232c8ec65a1f5a85dbef3210dc49684fcfed49b7ea2Jordan Justen      flush_pipeline_before_pipeline_select(cmd_buffer, _3D);
1233c8ec65a1f5a85dbef3210dc49684fcfed49b7ea2Jordan Justen
123450018522d2f2e1deb91710d63e0985c0b3dc8818Jason Ekstrand      anv_batch_emit(&cmd_buffer->batch, GENX(PIPELINE_SELECT), ps) {
1235371b4a5b33a13f35fa7783510d2d90685a9a2e8aJason Ekstrand#if GEN_GEN >= 9
1236deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand         ps.MaskBits = 3;
1237832f73f512e9e6c21d495d7b07e229482371ef2fKristian Høgsberg#endif
1238deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand         ps.PipelineSelection = _3D;
1239deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand      }
1240deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand
1241832f73f512e9e6c21d495d7b07e229482371ef2fKristian Høgsberg      cmd_buffer->state.current_pipeline = _3D;
1242832f73f512e9e6c21d495d7b07e229482371ef2fKristian Høgsberg   }
1243832f73f512e9e6c21d495d7b07e229482371ef2fKristian Høgsberg}
124485f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg
12451b126305ded36f6b416ada08e29ff84faeafef99Jordan Justenvoid
12461b126305ded36f6b416ada08e29ff84faeafef99Jordan JustengenX(flush_pipeline_select_gpgpu)(struct anv_cmd_buffer *cmd_buffer)
12471b126305ded36f6b416ada08e29ff84faeafef99Jordan Justen{
12481b126305ded36f6b416ada08e29ff84faeafef99Jordan Justen   if (cmd_buffer->state.current_pipeline != GPGPU) {
1249c8ec65a1f5a85dbef3210dc49684fcfed49b7ea2Jordan Justen      flush_pipeline_before_pipeline_select(cmd_buffer, GPGPU);
12501b126305ded36f6b416ada08e29ff84faeafef99Jordan Justen
125150018522d2f2e1deb91710d63e0985c0b3dc8818Jason Ekstrand      anv_batch_emit(&cmd_buffer->batch, GENX(PIPELINE_SELECT), ps) {
12521b126305ded36f6b416ada08e29ff84faeafef99Jordan Justen#if GEN_GEN >= 9
1253deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand         ps.MaskBits = 3;
12541b126305ded36f6b416ada08e29ff84faeafef99Jordan Justen#endif
1255deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand         ps.PipelineSelection = GPGPU;
1256deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand      }
1257deb13870d8a8e107efb636618ccb94edff0f60bfJason Ekstrand
12581b126305ded36f6b416ada08e29ff84faeafef99Jordan Justen      cmd_buffer->state.current_pipeline = GPGPU;
12591b126305ded36f6b416ada08e29ff84faeafef99Jordan Justen   }
12601b126305ded36f6b416ada08e29ff84faeafef99Jordan Justen}
12611b126305ded36f6b416ada08e29ff84faeafef99Jordan Justen
126221ee5fd3263e034a54d7a37d9e5b6e6f9ef49f54Jason Ekstrandstruct anv_state
126321ee5fd3263e034a54d7a37d9e5b6e6f9ef49f54Jason EkstrandgenX(cmd_buffer_alloc_null_surface_state)(struct anv_cmd_buffer *cmd_buffer,
126421ee5fd3263e034a54d7a37d9e5b6e6f9ef49f54Jason Ekstrand                                          struct anv_framebuffer *fb)
126521ee5fd3263e034a54d7a37d9e5b6e6f9ef49f54Jason Ekstrand{
126621ee5fd3263e034a54d7a37d9e5b6e6f9ef49f54Jason Ekstrand   struct anv_state state =
126721ee5fd3263e034a54d7a37d9e5b6e6f9ef49f54Jason Ekstrand      anv_state_stream_alloc(&cmd_buffer->surface_state_stream, 64, 64);
126821ee5fd3263e034a54d7a37d9e5b6e6f9ef49f54Jason Ekstrand
126921ee5fd3263e034a54d7a37d9e5b6e6f9ef49f54Jason Ekstrand   struct GENX(RENDER_SURFACE_STATE) null_ss = {
127021ee5fd3263e034a54d7a37d9e5b6e6f9ef49f54Jason Ekstrand      .SurfaceType = SURFTYPE_NULL,
127121ee5fd3263e034a54d7a37d9e5b6e6f9ef49f54Jason Ekstrand      .SurfaceArray = fb->layers > 0,
127221ee5fd3263e034a54d7a37d9e5b6e6f9ef49f54Jason Ekstrand      .SurfaceFormat = ISL_FORMAT_R8G8B8A8_UNORM,
127321ee5fd3263e034a54d7a37d9e5b6e6f9ef49f54Jason Ekstrand#if GEN_GEN >= 8
127421ee5fd3263e034a54d7a37d9e5b6e6f9ef49f54Jason Ekstrand      .TileMode = YMAJOR,
127521ee5fd3263e034a54d7a37d9e5b6e6f9ef49f54Jason Ekstrand#else
127621ee5fd3263e034a54d7a37d9e5b6e6f9ef49f54Jason Ekstrand      .TiledSurface = true,
127721ee5fd3263e034a54d7a37d9e5b6e6f9ef49f54Jason Ekstrand#endif
127821ee5fd3263e034a54d7a37d9e5b6e6f9ef49f54Jason Ekstrand      .Width = fb->width - 1,
127921ee5fd3263e034a54d7a37d9e5b6e6f9ef49f54Jason Ekstrand      .Height = fb->height - 1,
128021ee5fd3263e034a54d7a37d9e5b6e6f9ef49f54Jason Ekstrand      .Depth = fb->layers - 1,
128121ee5fd3263e034a54d7a37d9e5b6e6f9ef49f54Jason Ekstrand      .RenderTargetViewExtent = fb->layers - 1,
128221ee5fd3263e034a54d7a37d9e5b6e6f9ef49f54Jason Ekstrand   };
128321ee5fd3263e034a54d7a37d9e5b6e6f9ef49f54Jason Ekstrand
128421ee5fd3263e034a54d7a37d9e5b6e6f9ef49f54Jason Ekstrand   GENX(RENDER_SURFACE_STATE_pack)(NULL, state.map, &null_ss);
128521ee5fd3263e034a54d7a37d9e5b6e6f9ef49f54Jason Ekstrand
128621ee5fd3263e034a54d7a37d9e5b6e6f9ef49f54Jason Ekstrand   if (!cmd_buffer->device->info.has_llc)
128721ee5fd3263e034a54d7a37d9e5b6e6f9ef49f54Jason Ekstrand      anv_state_clflush(state);
128821ee5fd3263e034a54d7a37d9e5b6e6f9ef49f54Jason Ekstrand
128921ee5fd3263e034a54d7a37d9e5b6e6f9ef49f54Jason Ekstrand   return state;
129021ee5fd3263e034a54d7a37d9e5b6e6f9ef49f54Jason Ekstrand}
129121ee5fd3263e034a54d7a37d9e5b6e6f9ef49f54Jason Ekstrand
129285f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsbergstatic void
129385f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsbergcmd_buffer_emit_depth_stencil(struct anv_cmd_buffer *cmd_buffer)
129485f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg{
129585f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg   struct anv_device *device = cmd_buffer->device;
129685f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg   const struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
129785f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg   const struct anv_image_view *iview =
129885f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg      anv_cmd_buffer_get_depth_stencil_view(cmd_buffer);
129985f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg   const struct anv_image *image = iview ? iview->image : NULL;
1300234ecf26c65a8909e91313a8b35e2a8a8bbfc0efJason Ekstrand   const bool has_depth = image && (image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT);
130178d074b87a75d599e65ef34f5b866da577b80de3Chad Versace   const bool has_hiz = image != NULL && anv_image_has_hiz(image);
1302234ecf26c65a8909e91313a8b35e2a8a8bbfc0efJason Ekstrand   const bool has_stencil =
1303234ecf26c65a8909e91313a8b35e2a8a8bbfc0efJason Ekstrand      image && (image->aspects & VK_IMAGE_ASPECT_STENCIL_BIT);
130485f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg
130585f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg   /* FIXME: Implement the PMA stall W/A */
130685f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg   /* FIXME: Width and Height are wrong */
130785f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg
130885f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg   /* Emit 3DSTATE_DEPTH_BUFFER */
130985f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg   if (has_depth) {
131050018522d2f2e1deb91710d63e0985c0b3dc8818Jason Ekstrand      anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_DEPTH_BUFFER), db) {
1311a71ded0e1847d9d20c11de2fbaea271724170dc8Jason Ekstrand         db.SurfaceType                   = SURFTYPE_2D;
1312a71ded0e1847d9d20c11de2fbaea271724170dc8Jason Ekstrand         db.DepthWriteEnable              = true;
1313a71ded0e1847d9d20c11de2fbaea271724170dc8Jason Ekstrand         db.StencilWriteEnable            = has_stencil;
131478d074b87a75d599e65ef34f5b866da577b80de3Chad Versace
131578d074b87a75d599e65ef34f5b866da577b80de3Chad Versace         if (cmd_buffer->state.pass->subpass_count == 1) {
131678d074b87a75d599e65ef34f5b866da577b80de3Chad Versace            db.HierarchicalDepthBufferEnable = has_hiz;
131778d074b87a75d599e65ef34f5b866da577b80de3Chad Versace         } else {
131878d074b87a75d599e65ef34f5b866da577b80de3Chad Versace            anv_finishme("Multiple-subpass HiZ not implemented");
131978d074b87a75d599e65ef34f5b866da577b80de3Chad Versace         }
1320a71ded0e1847d9d20c11de2fbaea271724170dc8Jason Ekstrand
1321a71ded0e1847d9d20c11de2fbaea271724170dc8Jason Ekstrand         db.SurfaceFormat = isl_surf_get_depth_format(&device->isl_dev,
1322a71ded0e1847d9d20c11de2fbaea271724170dc8Jason Ekstrand                                                      &image->depth_surface.isl);
1323a71ded0e1847d9d20c11de2fbaea271724170dc8Jason Ekstrand
1324a71ded0e1847d9d20c11de2fbaea271724170dc8Jason Ekstrand         db.SurfaceBaseAddress = (struct anv_address) {
132585f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg            .bo = image->bo,
132622d8666d74f6fa6de53366f76a56277976eced21Kristian Høgsberg            .offset = image->offset + image->depth_surface.offset,
1327a71ded0e1847d9d20c11de2fbaea271724170dc8Jason Ekstrand         };
1328696f5c1853df39359b9dbd733f4c2a1177481556Lionel Landwerlin         db.DepthBufferObjectControlState = GENX(MOCS);
1329a71ded0e1847d9d20c11de2fbaea271724170dc8Jason Ekstrand
1330a71ded0e1847d9d20c11de2fbaea271724170dc8Jason Ekstrand         db.SurfacePitch         = image->depth_surface.isl.row_pitch - 1;
133120e95a746df34923eb4aac5e7f1ab6d722432d89Jason Ekstrand         db.Height               = image->extent.height - 1;
133220e95a746df34923eb4aac5e7f1ab6d722432d89Jason Ekstrand         db.Width                = image->extent.width - 1;
133329e289fa655938f7814bdbb3de7996a8a0f04b60Jason Ekstrand         db.LOD                  = iview->isl.base_level;
133420e95a746df34923eb4aac5e7f1ab6d722432d89Jason Ekstrand         db.Depth                = image->array_size - 1; /* FIXME: 3-D */
133529e289fa655938f7814bdbb3de7996a8a0f04b60Jason Ekstrand         db.MinimumArrayElement  = iview->isl.base_array_layer;
1336a71ded0e1847d9d20c11de2fbaea271724170dc8Jason Ekstrand
1337371b4a5b33a13f35fa7783510d2d90685a9a2e8aJason Ekstrand#if GEN_GEN >= 8
1338a71ded0e1847d9d20c11de2fbaea271724170dc8Jason Ekstrand         db.SurfaceQPitch =
1339696f5c1853df39359b9dbd733f4c2a1177481556Lionel Landwerlin            isl_surf_get_array_pitch_el_rows(&image->depth_surface.isl) >> 2;
134085f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg#endif
1341a71ded0e1847d9d20c11de2fbaea271724170dc8Jason Ekstrand         db.RenderTargetViewExtent = 1 - 1;
1342a71ded0e1847d9d20c11de2fbaea271724170dc8Jason Ekstrand      }
134385f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg   } else {
134485f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg      /* Even when no depth buffer is present, the hardware requires that
134585f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg       * 3DSTATE_DEPTH_BUFFER be programmed correctly. The Broadwell PRM says:
134685f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg       *
134785f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg       *    If a null depth buffer is bound, the driver must instead bind depth as:
134885f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg       *       3DSTATE_DEPTH.SurfaceType = SURFTYPE_2D
134985f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg       *       3DSTATE_DEPTH.Width = 1
135085f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg       *       3DSTATE_DEPTH.Height = 1
135185f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg       *       3DSTATE_DEPTH.SuraceFormat = D16_UNORM
135285f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg       *       3DSTATE_DEPTH.SurfaceBaseAddress = 0
135385f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg       *       3DSTATE_DEPTH.HierarchicalDepthBufferEnable = 0
135485f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg       *       3DSTATE_WM_DEPTH_STENCIL.DepthTestEnable = 0
135585f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg       *       3DSTATE_WM_DEPTH_STENCIL.DepthBufferWriteEnable = 0
135685f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg       *
135785f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg       * The PRM is wrong, though. The width and height must be programmed to
135885f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg       * actual framebuffer's width and height, even when neither depth buffer
13597c1660aa14094e40fba9f39ce194cb6238311b65Jason Ekstrand       * nor stencil buffer is present.  Also, D16_UNORM is not allowed to
13607c1660aa14094e40fba9f39ce194cb6238311b65Jason Ekstrand       * be combined with a stencil buffer so we use D32_FLOAT instead.
136185f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg       */
136250018522d2f2e1deb91710d63e0985c0b3dc8818Jason Ekstrand      anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_DEPTH_BUFFER), db) {
1363a71ded0e1847d9d20c11de2fbaea271724170dc8Jason Ekstrand         db.SurfaceType          = SURFTYPE_2D;
1364a71ded0e1847d9d20c11de2fbaea271724170dc8Jason Ekstrand         db.SurfaceFormat        = D32_FLOAT;
1365a71ded0e1847d9d20c11de2fbaea271724170dc8Jason Ekstrand         db.Width                = fb->width - 1;
1366a71ded0e1847d9d20c11de2fbaea271724170dc8Jason Ekstrand         db.Height               = fb->height - 1;
1367a71ded0e1847d9d20c11de2fbaea271724170dc8Jason Ekstrand         db.StencilWriteEnable   = has_stencil;
1368a71ded0e1847d9d20c11de2fbaea271724170dc8Jason Ekstrand      }
136985f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg   }
137085f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg
137178d074b87a75d599e65ef34f5b866da577b80de3Chad Versace   if (has_hiz) {
137278d074b87a75d599e65ef34f5b866da577b80de3Chad Versace      anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_HIER_DEPTH_BUFFER), hdb) {
137378d074b87a75d599e65ef34f5b866da577b80de3Chad Versace         hdb.HierarchicalDepthBufferObjectControlState = GENX(MOCS);
137478d074b87a75d599e65ef34f5b866da577b80de3Chad Versace         hdb.SurfacePitch = image->hiz_surface.isl.row_pitch - 1;
137578d074b87a75d599e65ef34f5b866da577b80de3Chad Versace         hdb.SurfaceBaseAddress = (struct anv_address) {
137678d074b87a75d599e65ef34f5b866da577b80de3Chad Versace            .bo = image->bo,
137778d074b87a75d599e65ef34f5b866da577b80de3Chad Versace            .offset = image->offset + image->hiz_surface.offset,
137878d074b87a75d599e65ef34f5b866da577b80de3Chad Versace         };
137978d074b87a75d599e65ef34f5b866da577b80de3Chad Versace#if GEN_GEN >= 8
138078d074b87a75d599e65ef34f5b866da577b80de3Chad Versace         /* From the SKL PRM Vol2a:
138178d074b87a75d599e65ef34f5b866da577b80de3Chad Versace          *
138278d074b87a75d599e65ef34f5b866da577b80de3Chad Versace          *    The interpretation of this field is dependent on Surface Type
138378d074b87a75d599e65ef34f5b866da577b80de3Chad Versace          *    as follows:
138478d074b87a75d599e65ef34f5b866da577b80de3Chad Versace          *    - SURFTYPE_1D: distance in pixels between array slices
138578d074b87a75d599e65ef34f5b866da577b80de3Chad Versace          *    - SURFTYPE_2D/CUBE: distance in rows between array slices
138678d074b87a75d599e65ef34f5b866da577b80de3Chad Versace          *    - SURFTYPE_3D: distance in rows between R - slices
138778d074b87a75d599e65ef34f5b866da577b80de3Chad Versace          */
138878d074b87a75d599e65ef34f5b866da577b80de3Chad Versace         hdb.SurfaceQPitch =
138978d074b87a75d599e65ef34f5b866da577b80de3Chad Versace            image->hiz_surface.isl.dim == ISL_SURF_DIM_1D ?
139078d074b87a75d599e65ef34f5b866da577b80de3Chad Versace               isl_surf_get_array_pitch_el(&image->hiz_surface.isl) >> 2 :
139178d074b87a75d599e65ef34f5b866da577b80de3Chad Versace               isl_surf_get_array_pitch_el_rows(&image->hiz_surface.isl) >> 2;
139278d074b87a75d599e65ef34f5b866da577b80de3Chad Versace#endif
139378d074b87a75d599e65ef34f5b866da577b80de3Chad Versace      }
139478d074b87a75d599e65ef34f5b866da577b80de3Chad Versace   } else {
139578d074b87a75d599e65ef34f5b866da577b80de3Chad Versace      anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_HIER_DEPTH_BUFFER), hdb);
139678d074b87a75d599e65ef34f5b866da577b80de3Chad Versace   }
139778d074b87a75d599e65ef34f5b866da577b80de3Chad Versace
139885f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg   /* Emit 3DSTATE_STENCIL_BUFFER */
139985f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg   if (has_stencil) {
140050018522d2f2e1deb91710d63e0985c0b3dc8818Jason Ekstrand      anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_STENCIL_BUFFER), sb) {
1401371b4a5b33a13f35fa7783510d2d90685a9a2e8aJason Ekstrand#if GEN_GEN >= 8 || GEN_IS_HASWELL
1402696f5c1853df39359b9dbd733f4c2a1177481556Lionel Landwerlin         sb.StencilBufferEnable = true;
140385f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg#endif
1404696f5c1853df39359b9dbd733f4c2a1177481556Lionel Landwerlin         sb.StencilBufferObjectControlState = GENX(MOCS);
140585f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg
1406696f5c1853df39359b9dbd733f4c2a1177481556Lionel Landwerlin         sb.SurfacePitch = image->stencil_surface.isl.row_pitch - 1;
140785f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg
1408371b4a5b33a13f35fa7783510d2d90685a9a2e8aJason Ekstrand#if GEN_GEN >= 8
1409696f5c1853df39359b9dbd733f4c2a1177481556Lionel Landwerlin         sb.SurfaceQPitch = isl_surf_get_array_pitch_el_rows(&image->stencil_surface.isl) >> 2;
141085f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg#endif
1411a71ded0e1847d9d20c11de2fbaea271724170dc8Jason Ekstrand         sb.SurfaceBaseAddress = (struct anv_address) {
141285f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg            .bo = image->bo,
141385f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg            .offset = image->offset + image->stencil_surface.offset,
1414a71ded0e1847d9d20c11de2fbaea271724170dc8Jason Ekstrand         };
1415a71ded0e1847d9d20c11de2fbaea271724170dc8Jason Ekstrand      }
141685f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg   } else {
141750018522d2f2e1deb91710d63e0985c0b3dc8818Jason Ekstrand      anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_STENCIL_BUFFER), sb);
141885f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg   }
141985f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg
1420d8aacc24cc37dc435e250668aba0817c36996ad1Nanley Chery   /* From the IVB PRM Vol2P1, 11.5.5.4 3DSTATE_CLEAR_PARAMS:
1421d8aacc24cc37dc435e250668aba0817c36996ad1Nanley Chery    *
1422d8aacc24cc37dc435e250668aba0817c36996ad1Nanley Chery    *    3DSTATE_CLEAR_PARAMS must always be programmed in the along with
1423d8aacc24cc37dc435e250668aba0817c36996ad1Nanley Chery    *    the other Depth/Stencil state commands(i.e. 3DSTATE_DEPTH_BUFFER,
1424d8aacc24cc37dc435e250668aba0817c36996ad1Nanley Chery    *    3DSTATE_STENCIL_BUFFER, or 3DSTATE_HIER_DEPTH_BUFFER)
1425d8aacc24cc37dc435e250668aba0817c36996ad1Nanley Chery    *
1426d8aacc24cc37dc435e250668aba0817c36996ad1Nanley Chery    * Testing also shows that some variant of this restriction may exist HSW+.
1427d8aacc24cc37dc435e250668aba0817c36996ad1Nanley Chery    * On BDW+, it is not possible to emit 2 of these packets consecutively when
1428d8aacc24cc37dc435e250668aba0817c36996ad1Nanley Chery    * both have DepthClearValueValid set. An analysis of such state programming
1429d8aacc24cc37dc435e250668aba0817c36996ad1Nanley Chery    * on SKL showed that the GPU doesn't register the latter packet's clear
1430d8aacc24cc37dc435e250668aba0817c36996ad1Nanley Chery    * value.
1431d8aacc24cc37dc435e250668aba0817c36996ad1Nanley Chery    */
1432d8aacc24cc37dc435e250668aba0817c36996ad1Nanley Chery   anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_CLEAR_PARAMS), cp) {
1433d8aacc24cc37dc435e250668aba0817c36996ad1Nanley Chery      if (has_hiz) {
1434d8aacc24cc37dc435e250668aba0817c36996ad1Nanley Chery         cp.DepthClearValueValid = true;
1435d8aacc24cc37dc435e250668aba0817c36996ad1Nanley Chery         const uint32_t ds =
1436d8aacc24cc37dc435e250668aba0817c36996ad1Nanley Chery            cmd_buffer->state.subpass->depth_stencil_attachment;
1437d8aacc24cc37dc435e250668aba0817c36996ad1Nanley Chery         cp.DepthClearValue =
1438d8aacc24cc37dc435e250668aba0817c36996ad1Nanley Chery            cmd_buffer->state.attachments[ds].clear_value.depthStencil.depth;
1439d8aacc24cc37dc435e250668aba0817c36996ad1Nanley Chery      }
1440d8aacc24cc37dc435e250668aba0817c36996ad1Nanley Chery   }
144185f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg}
144285f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg
1443b548fdbed5c16f5c0dfc26f65b0037a85c567735Jason Ekstrandstatic void
144485f67cf16e9823c858215e8a7359d18762c2653cKristian HøgsberggenX(cmd_buffer_set_subpass)(struct anv_cmd_buffer *cmd_buffer,
144585f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg                             struct anv_subpass *subpass)
144685f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg{
144785f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg   cmd_buffer->state.subpass = subpass;
144885f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg
1449fe4e276b02615b5db8acbf4c65fcfa68982e2e0fJason Ekstrand   cmd_buffer->state.dirty |= ANV_CMD_DIRTY_RENDER_TARGETS;
145085f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg
145185f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg   cmd_buffer_emit_depth_stencil(cmd_buffer);
145278d074b87a75d599e65ef34f5b866da577b80de3Chad Versace   genX(cmd_buffer_emit_hz_op)(cmd_buffer, BLORP_HIZ_OP_HIZ_RESOLVE);
1453d8aacc24cc37dc435e250668aba0817c36996ad1Nanley Chery   genX(cmd_buffer_emit_hz_op)(cmd_buffer, BLORP_HIZ_OP_DEPTH_CLEAR);
1454c81ec84c1ec24f11f86b2fb725956437c721fe18Jason Ekstrand
1455c81ec84c1ec24f11f86b2fb725956437c721fe18Jason Ekstrand   anv_cmd_buffer_clear_subpass(cmd_buffer);
145685f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg}
145785f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg
145885f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsbergvoid genX(CmdBeginRenderPass)(
145985f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg    VkCommandBuffer                             commandBuffer,
146085f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg    const VkRenderPassBeginInfo*                pRenderPassBegin,
146185f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg    VkSubpassContents                           contents)
146285f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg{
146385f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
146485f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg   ANV_FROM_HANDLE(anv_render_pass, pass, pRenderPassBegin->renderPass);
146585f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg   ANV_FROM_HANDLE(anv_framebuffer, framebuffer, pRenderPassBegin->framebuffer);
146685f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg
146785f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg   cmd_buffer->state.framebuffer = framebuffer;
146885f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg   cmd_buffer->state.pass = pass;
1469b26bd6790dd1b09e377bd926e9145ec20ce6ac3fJason Ekstrand   cmd_buffer->state.render_area = pRenderPassBegin->renderArea;
147085f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg   anv_cmd_state_setup_attachments(cmd_buffer, pRenderPassBegin);
147185f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg
147285f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg   genX(flush_pipeline_select_3d)(cmd_buffer);
147385f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg
147485f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg   genX(cmd_buffer_set_subpass)(cmd_buffer, pass->subpasses);
147585f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg}
147685f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg
147785f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsbergvoid genX(CmdNextSubpass)(
147885f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg    VkCommandBuffer                             commandBuffer,
147985f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg    VkSubpassContents                           contents)
148085f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg{
148185f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
148285f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg
148385f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg   assert(cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_PRIMARY);
148485f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg
148585f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg   anv_cmd_buffer_resolve_subpass(cmd_buffer);
148685f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg   genX(cmd_buffer_set_subpass)(cmd_buffer, cmd_buffer->state.subpass + 1);
148785f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg}
148885f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg
148985f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsbergvoid genX(CmdEndRenderPass)(
149085f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg    VkCommandBuffer                             commandBuffer)
149185f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg{
149285f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
149385f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg
149478d074b87a75d599e65ef34f5b866da577b80de3Chad Versace   genX(cmd_buffer_emit_hz_op)(cmd_buffer, BLORP_HIZ_OP_DEPTH_RESOLVE);
149585f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg   anv_cmd_buffer_resolve_subpass(cmd_buffer);
1496ac7eeebce4ae9107863623321b74b1c08389f180Jason Ekstrand
1497ac7eeebce4ae9107863623321b74b1c08389f180Jason Ekstrand#ifndef NDEBUG
1498ac7eeebce4ae9107863623321b74b1c08389f180Jason Ekstrand   anv_dump_add_framebuffer(cmd_buffer, cmd_buffer->state.framebuffer);
1499ac7eeebce4ae9107863623321b74b1c08389f180Jason Ekstrand#endif
150085f67cf16e9823c858215e8a7359d18762c2653cKristian Høgsberg}
150181f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen
150281f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justenstatic void
150381f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justenemit_ps_depth_count(struct anv_batch *batch,
150481f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen                    struct anv_bo *bo, uint32_t offset)
150581f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen{
150650018522d2f2e1deb91710d63e0985c0b3dc8818Jason Ekstrand   anv_batch_emit(batch, GENX(PIPE_CONTROL), pc) {
150756453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand      pc.DestinationAddressType  = DAT_PPGTT;
150856453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand      pc.PostSyncOperation       = WritePSDepthCount;
150956453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand      pc.DepthStallEnable        = true;
151056453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand      pc.Address                 = (struct anv_address) { bo, offset };
151156453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand   }
151281f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen}
151381f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen
151481f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justenstatic void
151581f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justenemit_query_availability(struct anv_batch *batch,
151681f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen                        struct anv_bo *bo, uint32_t offset)
151781f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen{
151850018522d2f2e1deb91710d63e0985c0b3dc8818Jason Ekstrand   anv_batch_emit(batch, GENX(PIPE_CONTROL), pc) {
151956453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand      pc.DestinationAddressType  = DAT_PPGTT;
152056453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand      pc.PostSyncOperation       = WriteImmediateData;
152156453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand      pc.Address                 = (struct anv_address) { bo, offset };
152256453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand      pc.ImmediateData           = 1;
152356453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand   }
152481f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen}
152581f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen
152681f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justenvoid genX(CmdBeginQuery)(
152781f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen    VkCommandBuffer                             commandBuffer,
152881f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen    VkQueryPool                                 queryPool,
152981f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen    uint32_t                                    query,
153081f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen    VkQueryControlFlags                         flags)
153181f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen{
153281f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
153381f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen   ANV_FROM_HANDLE(anv_query_pool, pool, queryPool);
153481f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen
153581f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen   /* Workaround: When meta uses the pipeline with the VS disabled, it seems
153681f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen    * that the pipelining of the depth write breaks. What we see is that
153781f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen    * samples from the render pass clear leaks into the first query
153881f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen    * immediately after the clear. Doing a pipecontrol with a post-sync
153981f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen    * operation and DepthStallEnable seems to work around the issue.
154081f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen    */
154181f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen   if (cmd_buffer->state.need_query_wa) {
154281f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen      cmd_buffer->state.need_query_wa = false;
154350018522d2f2e1deb91710d63e0985c0b3dc8818Jason Ekstrand      anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pc) {
154456453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand         pc.DepthCacheFlushEnable   = true;
154556453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand         pc.DepthStallEnable        = true;
154656453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand      }
154781f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen   }
154881f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen
154981f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen   switch (pool->type) {
155081f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen   case VK_QUERY_TYPE_OCCLUSION:
155181f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen      emit_ps_depth_count(&cmd_buffer->batch, &pool->bo,
155281f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen                          query * sizeof(struct anv_query_pool_slot));
155381f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen      break;
155481f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen
155581f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen   case VK_QUERY_TYPE_PIPELINE_STATISTICS:
155681f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen   default:
155781f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen      unreachable("");
155881f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen   }
155981f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen}
156081f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen
156181f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justenvoid genX(CmdEndQuery)(
156281f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen    VkCommandBuffer                             commandBuffer,
156381f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen    VkQueryPool                                 queryPool,
156481f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen    uint32_t                                    query)
156581f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen{
156681f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
156781f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen   ANV_FROM_HANDLE(anv_query_pool, pool, queryPool);
156881f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen
156981f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen   switch (pool->type) {
157081f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen   case VK_QUERY_TYPE_OCCLUSION:
157181f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen      emit_ps_depth_count(&cmd_buffer->batch, &pool->bo,
157281f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen                          query * sizeof(struct anv_query_pool_slot) + 8);
157381f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen
157481f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen      emit_query_availability(&cmd_buffer->batch, &pool->bo,
157581f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen                              query * sizeof(struct anv_query_pool_slot) + 16);
157681f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen      break;
157781f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen
157881f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen   case VK_QUERY_TYPE_PIPELINE_STATISTICS:
157981f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen   default:
158081f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen      unreachable("");
158181f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen   }
158281f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen}
158381f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen
158481f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen#define TIMESTAMP 0x2358
158581f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen
158681f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justenvoid genX(CmdWriteTimestamp)(
158781f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen    VkCommandBuffer                             commandBuffer,
158881f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen    VkPipelineStageFlagBits                     pipelineStage,
158981f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen    VkQueryPool                                 queryPool,
159081f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen    uint32_t                                    query)
159181f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen{
159281f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
159381f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen   ANV_FROM_HANDLE(anv_query_pool, pool, queryPool);
159481f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen   uint32_t offset = query * sizeof(struct anv_query_pool_slot);
159581f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen
159681f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen   assert(pool->type == VK_QUERY_TYPE_TIMESTAMP);
159781f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen
159881f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen   switch (pipelineStage) {
159981f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen   case VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT:
160050018522d2f2e1deb91710d63e0985c0b3dc8818Jason Ekstrand      anv_batch_emit(&cmd_buffer->batch, GENX(MI_STORE_REGISTER_MEM), srm) {
16018a6ced83e9e936c4c29854148940025c20cd831eJason Ekstrand         srm.RegisterAddress  = TIMESTAMP;
16028a6ced83e9e936c4c29854148940025c20cd831eJason Ekstrand         srm.MemoryAddress    = (struct anv_address) { &pool->bo, offset };
16038a6ced83e9e936c4c29854148940025c20cd831eJason Ekstrand      }
160450018522d2f2e1deb91710d63e0985c0b3dc8818Jason Ekstrand      anv_batch_emit(&cmd_buffer->batch, GENX(MI_STORE_REGISTER_MEM), srm) {
16058a6ced83e9e936c4c29854148940025c20cd831eJason Ekstrand         srm.RegisterAddress  = TIMESTAMP + 4;
16068a6ced83e9e936c4c29854148940025c20cd831eJason Ekstrand         srm.MemoryAddress    = (struct anv_address) { &pool->bo, offset + 4 };
16078a6ced83e9e936c4c29854148940025c20cd831eJason Ekstrand      }
160881f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen      break;
160981f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen
161081f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen   default:
161181f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen      /* Everything else is bottom-of-pipe */
161250018522d2f2e1deb91710d63e0985c0b3dc8818Jason Ekstrand      anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pc) {
1613696f5c1853df39359b9dbd733f4c2a1177481556Lionel Landwerlin         pc.DestinationAddressType  = DAT_PPGTT;
1614696f5c1853df39359b9dbd733f4c2a1177481556Lionel Landwerlin         pc.PostSyncOperation       = WriteTimestamp;
16158a6ced83e9e936c4c29854148940025c20cd831eJason Ekstrand         pc.Address = (struct anv_address) { &pool->bo, offset };
16168a6ced83e9e936c4c29854148940025c20cd831eJason Ekstrand      }
161781f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen      break;
161881f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen   }
161981f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen
162081f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen   emit_query_availability(&cmd_buffer->batch, &pool->bo, query + 16);
162181f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen}
162281f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen
162381f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen#if GEN_GEN > 7 || GEN_IS_HASWELL
162481f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen
162581f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen#define alu_opcode(v)   __gen_uint((v),  20, 31)
162681f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen#define alu_operand1(v) __gen_uint((v),  10, 19)
162781f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen#define alu_operand2(v) __gen_uint((v),   0,  9)
162881f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen#define alu(opcode, operand1, operand2) \
162981f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen   alu_opcode(opcode) | alu_operand1(operand1) | alu_operand2(operand2)
163081f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen
163181f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen#define OPCODE_NOOP      0x000
163281f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen#define OPCODE_LOAD      0x080
163381f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen#define OPCODE_LOADINV   0x480
163481f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen#define OPCODE_LOAD0     0x081
163581f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen#define OPCODE_LOAD1     0x481
163681f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen#define OPCODE_ADD       0x100
163781f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen#define OPCODE_SUB       0x101
163881f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen#define OPCODE_AND       0x102
163981f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen#define OPCODE_OR        0x103
164081f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen#define OPCODE_XOR       0x104
164181f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen#define OPCODE_STORE     0x180
164281f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen#define OPCODE_STOREINV  0x580
164381f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen
164481f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen#define OPERAND_R0   0x00
164581f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen#define OPERAND_R1   0x01
164681f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen#define OPERAND_R2   0x02
164781f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen#define OPERAND_R3   0x03
164881f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen#define OPERAND_R4   0x04
164981f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen#define OPERAND_SRCA 0x20
165081f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen#define OPERAND_SRCB 0x21
165181f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen#define OPERAND_ACCU 0x31
165281f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen#define OPERAND_ZF   0x32
165381f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen#define OPERAND_CF   0x33
165481f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen
165581f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen#define CS_GPR(n) (0x2600 + (n) * 8)
165681f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen
165781f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justenstatic void
165881f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justenemit_load_alu_reg_u64(struct anv_batch *batch, uint32_t reg,
165981f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen                      struct anv_bo *bo, uint32_t offset)
166081f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen{
166150018522d2f2e1deb91710d63e0985c0b3dc8818Jason Ekstrand   anv_batch_emit(batch, GENX(MI_LOAD_REGISTER_MEM), lrm) {
16628a6ced83e9e936c4c29854148940025c20cd831eJason Ekstrand      lrm.RegisterAddress  = reg,
16638a6ced83e9e936c4c29854148940025c20cd831eJason Ekstrand      lrm.MemoryAddress    = (struct anv_address) { bo, offset };
16648a6ced83e9e936c4c29854148940025c20cd831eJason Ekstrand   }
166550018522d2f2e1deb91710d63e0985c0b3dc8818Jason Ekstrand   anv_batch_emit(batch, GENX(MI_LOAD_REGISTER_MEM), lrm) {
16668a6ced83e9e936c4c29854148940025c20cd831eJason Ekstrand      lrm.RegisterAddress  = reg + 4;
16678a6ced83e9e936c4c29854148940025c20cd831eJason Ekstrand      lrm.MemoryAddress    = (struct anv_address) { bo, offset + 4 };
16688a6ced83e9e936c4c29854148940025c20cd831eJason Ekstrand   }
166981f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen}
167081f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen
167181f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justenstatic void
167281f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justenstore_query_result(struct anv_batch *batch, uint32_t reg,
167381f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen                   struct anv_bo *bo, uint32_t offset, VkQueryResultFlags flags)
167481f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen{
167550018522d2f2e1deb91710d63e0985c0b3dc8818Jason Ekstrand   anv_batch_emit(batch, GENX(MI_STORE_REGISTER_MEM), srm) {
16768a6ced83e9e936c4c29854148940025c20cd831eJason Ekstrand      srm.RegisterAddress  = reg;
16778a6ced83e9e936c4c29854148940025c20cd831eJason Ekstrand      srm.MemoryAddress    = (struct anv_address) { bo, offset };
16788a6ced83e9e936c4c29854148940025c20cd831eJason Ekstrand   }
16798a6ced83e9e936c4c29854148940025c20cd831eJason Ekstrand
16808a6ced83e9e936c4c29854148940025c20cd831eJason Ekstrand   if (flags & VK_QUERY_RESULT_64_BIT) {
168150018522d2f2e1deb91710d63e0985c0b3dc8818Jason Ekstrand      anv_batch_emit(batch, GENX(MI_STORE_REGISTER_MEM), srm) {
16828a6ced83e9e936c4c29854148940025c20cd831eJason Ekstrand         srm.RegisterAddress  = reg + 4;
16838a6ced83e9e936c4c29854148940025c20cd831eJason Ekstrand         srm.MemoryAddress    = (struct anv_address) { bo, offset + 4 };
16848a6ced83e9e936c4c29854148940025c20cd831eJason Ekstrand      }
16858a6ced83e9e936c4c29854148940025c20cd831eJason Ekstrand   }
168681f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen}
168781f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen
168881f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justenvoid genX(CmdCopyQueryPoolResults)(
168981f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen    VkCommandBuffer                             commandBuffer,
169081f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen    VkQueryPool                                 queryPool,
169181f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen    uint32_t                                    firstQuery,
169281f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen    uint32_t                                    queryCount,
169381f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen    VkBuffer                                    destBuffer,
169481f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen    VkDeviceSize                                destOffset,
169581f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen    VkDeviceSize                                destStride,
169681f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen    VkQueryResultFlags                          flags)
169781f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen{
169881f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
169981f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen   ANV_FROM_HANDLE(anv_query_pool, pool, queryPool);
170081f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen   ANV_FROM_HANDLE(anv_buffer, buffer, destBuffer);
170181f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen   uint32_t slot_offset, dst_offset;
170281f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen
170356453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand   if (flags & VK_QUERY_RESULT_WAIT_BIT) {
170450018522d2f2e1deb91710d63e0985c0b3dc8818Jason Ekstrand      anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pc) {
170556453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand         pc.CommandStreamerStallEnable = true;
170656453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand         pc.StallAtPixelScoreboard     = true;
170756453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand      }
170856453eeaff92fdd39cc0818afd96a373899d58f8Jason Ekstrand   }
170981f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen
171081f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen   dst_offset = buffer->offset + destOffset;
171181f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen   for (uint32_t i = 0; i < queryCount; i++) {
171281f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen
171381f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen      slot_offset = (firstQuery + i) * sizeof(struct anv_query_pool_slot);
171481f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen      switch (pool->type) {
171581f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen      case VK_QUERY_TYPE_OCCLUSION:
171681f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen         emit_load_alu_reg_u64(&cmd_buffer->batch,
171781f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen                               CS_GPR(0), &pool->bo, slot_offset);
171881f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen         emit_load_alu_reg_u64(&cmd_buffer->batch,
171981f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen                               CS_GPR(1), &pool->bo, slot_offset + 8);
172081f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen
172181f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen         /* FIXME: We need to clamp the result for 32 bit. */
172281f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen
172381f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen         uint32_t *dw = anv_batch_emitn(&cmd_buffer->batch, 5, GENX(MI_MATH));
172481f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen         dw[1] = alu(OPCODE_LOAD, OPERAND_SRCA, OPERAND_R1);
172581f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen         dw[2] = alu(OPCODE_LOAD, OPERAND_SRCB, OPERAND_R0);
172681f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen         dw[3] = alu(OPCODE_SUB, 0, 0);
172781f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen         dw[4] = alu(OPCODE_STORE, OPERAND_R2, OPERAND_ACCU);
172881f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen         break;
172981f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen
173081f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen      case VK_QUERY_TYPE_TIMESTAMP:
173181f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen         emit_load_alu_reg_u64(&cmd_buffer->batch,
173281f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen                               CS_GPR(2), &pool->bo, slot_offset);
173381f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen         break;
173481f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen
173581f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen      default:
173681f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen         unreachable("unhandled query type");
173781f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen      }
173881f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen
173981f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen      store_query_result(&cmd_buffer->batch,
174081f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen                         CS_GPR(2), buffer->bo, dst_offset, flags);
174181f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen
174281f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen      if (flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT) {
174381f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen         emit_load_alu_reg_u64(&cmd_buffer->batch, CS_GPR(0),
174481f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen                               &pool->bo, slot_offset + 16);
174581f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen         if (flags & VK_QUERY_RESULT_64_BIT)
174681f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen            store_query_result(&cmd_buffer->batch,
174781f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen                               CS_GPR(0), buffer->bo, dst_offset + 8, flags);
174881f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen         else
174981f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen            store_query_result(&cmd_buffer->batch,
175081f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen                               CS_GPR(0), buffer->bo, dst_offset + 4, flags);
175181f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen      }
175281f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen
175381f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen      dst_offset += destStride;
175481f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen   }
175581f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen}
175681f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen
1757b9e99282a6e1b3b2b01645e37bf4b735aace677bJason Ekstrand#else
1758b9e99282a6e1b3b2b01645e37bf4b735aace677bJason Ekstrandvoid genX(CmdCopyQueryPoolResults)(
1759b9e99282a6e1b3b2b01645e37bf4b735aace677bJason Ekstrand    VkCommandBuffer                             commandBuffer,
1760b9e99282a6e1b3b2b01645e37bf4b735aace677bJason Ekstrand    VkQueryPool                                 queryPool,
1761b9e99282a6e1b3b2b01645e37bf4b735aace677bJason Ekstrand    uint32_t                                    firstQuery,
1762b9e99282a6e1b3b2b01645e37bf4b735aace677bJason Ekstrand    uint32_t                                    queryCount,
1763b9e99282a6e1b3b2b01645e37bf4b735aace677bJason Ekstrand    VkBuffer                                    destBuffer,
1764b9e99282a6e1b3b2b01645e37bf4b735aace677bJason Ekstrand    VkDeviceSize                                destOffset,
1765b9e99282a6e1b3b2b01645e37bf4b735aace677bJason Ekstrand    VkDeviceSize                                destStride,
1766b9e99282a6e1b3b2b01645e37bf4b735aace677bJason Ekstrand    VkQueryResultFlags                          flags)
1767b9e99282a6e1b3b2b01645e37bf4b735aace677bJason Ekstrand{
1768b9e99282a6e1b3b2b01645e37bf4b735aace677bJason Ekstrand   anv_finishme("Queries not yet supported on Ivy Bridge");
1769b9e99282a6e1b3b2b01645e37bf4b735aace677bJason Ekstrand}
177081f30e2f509b4fcd79376ff02363aba831918ac6Jordan Justen#endif
1771