<html>
    <head>
      <base href="https://bugs.freedesktop.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - [anv] vkCmdCopyBuffer() and vkCmdCopyQueryPoolResults() write-after-write hazard"
   href="https://bugs.freedesktop.org/show_bug.cgi?id=108894">108894</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>[anv] vkCmdCopyBuffer() and vkCmdCopyQueryPoolResults() write-after-write hazard
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>Mesa
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>git
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>Other
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>medium
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>Drivers/Vulkan/intel
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>intel-3d-bugs@lists.freedesktop.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>joseph.kucia@gmail.com
          </td>
        </tr>

        <tr>
          <th>QA Contact</th>
          <td>intel-3d-bugs@lists.freedesktop.org
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>jason@jlekstrand.net
          </td>
        </tr></table>
      <p>
        <div>
        <pre>It seems to be impossible to synchronize vkCmdCopyBuffer() and
vkCmdCopyQueryPoolResults() commands. I think it should be enough to issue a
pipeline barrier with VK_PIPELINE_STAGE_TRANSFER_BIT and
VK_ACCESS_TRANSFER_WRITE_BIT between vkCmdCopyBuffer() and
vkCmdCopyQueryPoolResults() to avoid write-after-write hazards. However, in my
test case, I consistently get the value written by vkCmdCopyBuffer().
vkCmdCopyBuffer() is issued before vkCmdCopyQueryPoolResults().

--- api dump ---
vkCmdResetQueryPool(commandBuffer, queryPool, firstQuery, queryCount) returns
void:
    commandBuffer:                  VkCommandBuffer = 0x55c2b2e7d430
    queryPool:                      VkQueryPool = 0x55c2b2dbd050
    firstQuery:                     uint32_t = 0
    queryCount:                     uint32_t = 1

vkCmdWriteTimestamp(commandBuffer, pipelineStage, queryPool, query) returns
void:
    commandBuffer:                  VkCommandBuffer = 0x55c2b2e7d430
    pipelineStage:                  VkPipelineStageFlagBits = 8192
(VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT)
    queryPool:                      VkQueryPool = 0x55c2b2dbd050
    query:                          uint32_t = 0

vkCmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, regionCount, pRegions)
returns void:
    commandBuffer:                  VkCommandBuffer = 0x55c2b2e7d430
    srcBuffer:                      VkBuffer = 0x55c2b2e80150
    dstBuffer:                      VkBuffer = 0x55c2b2dbcfc0
    regionCount:                    uint32_t = 1
    pRegions:                       const VkBufferCopy* = 0x7ffc0d802d20
        pRegions[0]:                    const VkBufferCopy = 0x7ffc0d802d20:
            srcOffset:                      VkDeviceSize = 0
            dstOffset:                      VkDeviceSize = 0
            size:                           VkDeviceSize = 32

// we should issue a pipeline barrier here

vkCmdCopyQueryPoolResults(commandBuffer, queryPool, firstQuery, queryCount,
dstBuffer, dstOffset, stride, flags) returns void:
    commandBuffer:                  VkCommandBuffer = 0x55c2b2e7d430
    queryPool:                      VkQueryPool = 0x55c2b2dbd050
    firstQuery:                     uint32_t = 0
    queryCount:                     uint32_t = 1
    dstBuffer:                      VkBuffer = 0x55c2b2dbcfc0
    dstOffset:                      VkDeviceSize = 0
    stride:                         VkDeviceSize = 8
    flags:                          VkQueryResultFlags = 3
(VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT)
--- api dump ---

The expected result is to get the value written by vkCmdCopyQueryPoolResults().
On Anvil, the result is the value written by vkCmdCopyBuffer().

I have a test case in the form of a vkd3d test:
<a href="https://source.winehq.org/git/vkd3d.git/blob/HEAD:/tests/d3d12.c#l18279">https://source.winehq.org/git/vkd3d.git/blob/HEAD:/tests/d3d12.c#l18279</a>
The test passes on RADV and Nvidia. Note that the current version of vkd3d
doesn't issue a required pipeline barrier between vkCmdCopyBuffer() and
vkCmdCopyQueryPoolResults().</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are the assignee for the bug.</li>
          <li>You are the QA Contact for the bug.</li>
      </ul>
    </body>
</html>