Exemplo n.º 1
0
bool WrappedVulkan::Serialise_vkCmdSetDepthBounds(Serialiser *localSerialiser,
                                                  VkCommandBuffer cmdBuffer, float minDepthBounds,
                                                  float maxDepthBounds)
{
  SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer));
  SERIALISE_ELEMENT(float, mind, minDepthBounds);
  SERIALISE_ELEMENT(float, maxd, maxDepthBounds);

  Serialise_DebugMessages(localSerialiser, false);

  if(m_State < WRITING)
    m_LastCmdBufferID = cmdid;

  if(m_State == EXECUTING)
  {
    if(ShouldRerecordCmd(cmdid) && InRerecordRange(cmdid))
    {
      cmdBuffer = RerecordCmdBuf(cmdid);
      ObjDisp(cmdBuffer)->CmdSetDepthBounds(Unwrap(cmdBuffer), mind, maxd);
      m_RenderState.mindepth = mind;
      m_RenderState.maxdepth = maxd;
    }
  }
  else if(m_State == READING)
  {
    cmdBuffer = GetResourceManager()->GetLiveHandle<VkCommandBuffer>(cmdid);

    ObjDisp(cmdBuffer)->CmdSetDepthBounds(Unwrap(cmdBuffer), mind, maxd);
  }

  return true;
}
Exemplo n.º 2
0
bool WrappedVulkan::Serialise_vkCmdSetDepthBias(Serialiser *localSerialiser,
                                                VkCommandBuffer cmdBuffer, float depthBias,
                                                float depthBiasClamp, float slopeScaledDepthBias)
{
  SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer));
  SERIALISE_ELEMENT(float, bias, depthBias);
  SERIALISE_ELEMENT(float, biasclamp, depthBiasClamp);
  SERIALISE_ELEMENT(float, slope, slopeScaledDepthBias);

  Serialise_DebugMessages(localSerialiser, false);

  if(m_State < WRITING)
    m_LastCmdBufferID = cmdid;

  if(m_State == EXECUTING)
  {
    if(ShouldRerecordCmd(cmdid) && InRerecordRange(cmdid))
    {
      cmdBuffer = RerecordCmdBuf(cmdid);
      ObjDisp(cmdBuffer)->CmdSetDepthBias(Unwrap(cmdBuffer), bias, biasclamp, slope);
      m_RenderState.bias.depth = bias;
      m_RenderState.bias.biasclamp = biasclamp;
      m_RenderState.bias.slope = slope;
    }
  }
  else if(m_State == READING)
  {
    cmdBuffer = GetResourceManager()->GetLiveHandle<VkCommandBuffer>(cmdid);

    ObjDisp(cmdBuffer)->CmdSetDepthBias(Unwrap(cmdBuffer), bias, biasclamp, slope);
  }

  return true;
}
Exemplo n.º 3
0
bool WrappedVulkan::Serialise_vkCmdSetScissor(Serialiser *localSerialiser,
                                              VkCommandBuffer cmdBuffer, uint32_t firstScissor,
                                              uint32_t scissorCount, const VkRect2D *pScissors)
{
  SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer));
  SERIALISE_ELEMENT(uint32_t, first, firstScissor);
  SERIALISE_ELEMENT(uint32_t, count, scissorCount);
  SERIALISE_ELEMENT_ARR(VkRect2D, scissors, pScissors, count);

  Serialise_DebugMessages(localSerialiser, false);

  if(m_State < WRITING)
    m_LastCmdBufferID = cmdid;

  if(m_State == EXECUTING)
  {
    if(ShouldRerecordCmd(cmdid) && InRerecordRange(cmdid))
    {
      cmdBuffer = RerecordCmdBuf(cmdid);
      ObjDisp(cmdBuffer)->CmdSetScissor(Unwrap(cmdBuffer), first, count, scissors);

      if(m_RenderState.scissors.size() < first + count)
        m_RenderState.scissors.resize(first + count);

      for(uint32_t i = 0; i < count; i++)
        m_RenderState.scissors[first + i] = scissors[i];
    }
  }
  else if(m_State == READING)
  {
    cmdBuffer = GetResourceManager()->GetLiveHandle<VkCommandBuffer>(cmdid);

    ObjDisp(cmdBuffer)->CmdSetScissor(Unwrap(cmdBuffer), first, count, scissors);
  }

  SAFE_DELETE_ARRAY(scissors);

  return true;
}
Exemplo n.º 4
0
bool WrappedVulkan::Serialise_vkCmdSetBlendConstants(Serialiser *localSerialiser,
                                                     VkCommandBuffer cmdBuffer,
                                                     const float *blendConst)
{
  SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer));

  float blendFactor[4];
  if(m_State >= WRITING)
  {
    blendFactor[0] = blendConst[0];
    blendFactor[1] = blendConst[1];
    blendFactor[2] = blendConst[2];
    blendFactor[3] = blendConst[3];
  }
  localSerialiser->SerialisePODArray<4>("blendConst", blendFactor);

  Serialise_DebugMessages(localSerialiser, false);

  if(m_State < WRITING)
    m_LastCmdBufferID = cmdid;

  if(m_State == EXECUTING)
  {
    if(ShouldRerecordCmd(cmdid) && InRerecordRange(cmdid))
    {
      cmdBuffer = RerecordCmdBuf(cmdid);
      ObjDisp(cmdBuffer)->CmdSetBlendConstants(Unwrap(cmdBuffer), blendFactor);
      memcpy(m_RenderState.blendConst, blendFactor, sizeof(blendFactor));
    }
  }
  else if(m_State == READING)
  {
    cmdBuffer = GetResourceManager()->GetLiveHandle<VkCommandBuffer>(cmdid);

    ObjDisp(cmdBuffer)->CmdSetBlendConstants(Unwrap(cmdBuffer), blendFactor);
  }

  return true;
}
Exemplo n.º 5
0
bool WrappedVulkan::Serialise_vkCmdResetEvent(
		Serialiser*                                 localSerialiser,
		VkCommandBuffer                                 cmdBuffer,
    VkEvent                                     event,
		VkPipelineStageFlags                        stageMask)
{
	SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer));
	SERIALISE_ELEMENT(ResourceId, eid, GetResID(event));
	SERIALISE_ELEMENT(VkPipelineStageFlagBits, mask, (VkPipelineStageFlagBits)stageMask);
	
	Serialise_DebugMessages(localSerialiser, false);

	if(m_State < WRITING)
		m_LastCmdBufferID = cmdid;
	
	// see top of this file for current event/fence handling

	if(m_State == EXECUTING)
	{
		event = GetResourceManager()->GetLiveHandle<VkEvent>(eid);

		if(ShouldRerecordCmd(cmdid) && InRerecordRange())
		{
			cmdBuffer = RerecordCmdBuf(cmdid);
			//ObjDisp(cmdBuffer)->CmdResetEvent(Unwrap(cmdBuffer), Unwrap(event), mask);
		}
	}
	else if(m_State == READING)
	{
		cmdBuffer = GetResourceManager()->GetLiveHandle<VkCommandBuffer>(cmdid);
		event = GetResourceManager()->GetLiveHandle<VkEvent>(eid);
		
		//ObjDisp(cmdBuffer)->CmdResetEvent(Unwrap(cmdBuffer), Unwrap(event), mask);
	}

	return true;
}
Exemplo n.º 6
0
bool WrappedVulkan::Serialise_vkCmdSetStencilReference(Serialiser *localSerialiser,
                                                       VkCommandBuffer cmdBuffer,
                                                       VkStencilFaceFlags faceMask,
                                                       uint32_t reference)
{
  SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer));
  SERIALISE_ELEMENT(VkStencilFaceFlagBits, face, (VkStencilFaceFlagBits)faceMask);
  SERIALISE_ELEMENT(uint32_t, mask, reference);

  Serialise_DebugMessages(localSerialiser, false);

  if(m_State < WRITING)
    m_LastCmdBufferID = cmdid;

  if(m_State == EXECUTING)
  {
    if(ShouldRerecordCmd(cmdid) && InRerecordRange(cmdid))
    {
      cmdBuffer = RerecordCmdBuf(cmdid);
      ObjDisp(cmdBuffer)->CmdSetStencilReference(Unwrap(cmdBuffer), face, mask);

      if(face & VK_STENCIL_FACE_FRONT_BIT)
        m_RenderState.front.ref = mask;
      if(face & VK_STENCIL_FACE_BACK_BIT)
        m_RenderState.back.ref = mask;
    }
  }
  else if(m_State == READING)
  {
    cmdBuffer = GetResourceManager()->GetLiveHandle<VkCommandBuffer>(cmdid);

    ObjDisp(cmdBuffer)->CmdSetStencilReference(Unwrap(cmdBuffer), face, mask);
  }

  return true;
}
Exemplo n.º 7
0
bool WrappedVulkan::Serialise_vkCmdWaitEvents(
			Serialiser*                                 localSerialiser,
			VkCommandBuffer                             cmdBuffer,
			uint32_t                                    eventCount,
			const VkEvent*                              pEvents,
			VkPipelineStageFlags                        srcStageMask,
			VkPipelineStageFlags                        dstStageMask,
			uint32_t                                    memoryBarrierCount,
			const VkMemoryBarrier*                      pMemoryBarriers,
			uint32_t                                    bufferMemoryBarrierCount,
			const VkBufferMemoryBarrier*                pBufferMemoryBarriers,
			uint32_t                                    imageMemoryBarrierCount,
			const VkImageMemoryBarrier*                 pImageMemoryBarriers)
{
	SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer));
	SERIALISE_ELEMENT(VkPipelineStageFlagBits, srcStages, (VkPipelineStageFlagBits)srcStageMask);
	SERIALISE_ELEMENT(VkPipelineStageFlagBits, destStages, (VkPipelineStageFlagBits)dstStageMask);
	
	// we don't serialise the original events as we are going to replace this
	// with our own
	
	SERIALISE_ELEMENT(uint32_t, memCount, memoryBarrierCount);
	SERIALISE_ELEMENT(uint32_t, bufCount, bufferMemoryBarrierCount);
	SERIALISE_ELEMENT(uint32_t, imgCount, imageMemoryBarrierCount);

	// we keep the original memory barriers
	SERIALISE_ELEMENT_ARR(VkMemoryBarrier, memBarriers, pMemoryBarriers, memCount);
	SERIALISE_ELEMENT_ARR(VkBufferMemoryBarrier, bufMemBarriers, pBufferMemoryBarriers, bufCount);
	SERIALISE_ELEMENT_ARR(VkImageMemoryBarrier, imgMemBarriers, pImageMemoryBarriers, imgCount);

	vector<VkImageMemoryBarrier> imgBarriers;
	vector<VkBufferMemoryBarrier> bufBarriers;

	// it's possible for buffer or image to be NULL if it refers to a resource that is otherwise
	// not in the log (barriers do not mark resources referenced). If the resource in question does
	// not exist, then it's safe to skip this barrier.
	
	if(m_State < WRITING)
	{
		for(uint32_t i=0; i < bufCount; i++)
			if(bufMemBarriers[i].buffer != VK_NULL_HANDLE)
				bufBarriers.push_back(bufMemBarriers[i]);
		
		for(uint32_t i=0; i < imgCount; i++)
		{
			if(imgMemBarriers[i].image != VK_NULL_HANDLE)
			{
				imgBarriers.push_back(imgMemBarriers[i]);
				ReplacePresentableImageLayout(imgBarriers.back().oldLayout);
				ReplacePresentableImageLayout(imgBarriers.back().newLayout);
			}
		}
	}

	SAFE_DELETE_ARRAY(bufMemBarriers);
	SAFE_DELETE_ARRAY(imgMemBarriers);

	// see top of this file for current event/fence handling

	if(m_State == EXECUTING)
	{
		if(ShouldRerecordCmd(cmdid) && InRerecordRange())
		{
			cmdBuffer = RerecordCmdBuf(cmdid);

			VkEventCreateInfo evInfo = {
				VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, NULL, 0,
			};

			VkEvent ev = VK_NULL_HANDLE;
			ObjDisp(cmdBuffer)->CreateEvent(Unwrap(GetDev()), &evInfo, NULL, &ev);
			// don't wrap this event

			ObjDisp(cmdBuffer)->ResetEvent(Unwrap(GetDev()), ev);
			ObjDisp(cmdBuffer)->CmdSetEvent(Unwrap(cmdBuffer), ev, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);

			ObjDisp(cmdBuffer)->CmdWaitEvents(Unwrap(cmdBuffer), 1, &ev, (VkPipelineStageFlags)srcStages, (VkPipelineStageFlags)destStages,
				memCount, memBarriers,
				(uint32_t)bufBarriers.size(), &bufBarriers[0],
				(uint32_t)imgBarriers.size(), &imgBarriers[0]);

			// register to clean this event up once we're done replaying this section of the log
			m_CleanupEvents.push_back(ev);

			ResourceId cmd = GetResID(RerecordCmdBuf(cmdid));
			GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts, (uint32_t)imgBarriers.size(), &imgBarriers[0]);
		}
	}
	else if(m_State == READING)
	{
		cmdBuffer = GetResourceManager()->GetLiveHandle<VkCommandBuffer>(cmdid);

		VkEventCreateInfo evInfo = {
			VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, NULL, 0,
		};

		VkEvent ev = VK_NULL_HANDLE;
		ObjDisp(cmdBuffer)->CreateEvent(Unwrap(GetDev()), &evInfo, NULL, &ev);
		// don't wrap this event

		ObjDisp(cmdBuffer)->ResetEvent(Unwrap(GetDev()), ev);
		ObjDisp(cmdBuffer)->CmdSetEvent(Unwrap(cmdBuffer), ev, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);

		ObjDisp(cmdBuffer)->CmdWaitEvents(Unwrap(cmdBuffer), 1, &ev, (VkPipelineStageFlags)srcStages, (VkPipelineStageFlags)destStages,
				memCount, memBarriers,
				(uint32_t)bufBarriers.size(), &bufBarriers[0],
				(uint32_t)imgBarriers.size(), &imgBarriers[0]);

		// register to clean this event up once we're done replaying this section of the log
		m_CleanupEvents.push_back(ev);
		
		ResourceId cmd = GetResID(cmdBuffer);
		GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts, (uint32_t)imgBarriers.size(), &imgBarriers[0]);
	}

	SAFE_DELETE_ARRAY(memBarriers);

	return true;
}
Exemplo n.º 8
0
bool WrappedVulkan::Serialise_vkQueueSubmit(Serialiser *localSerialiser, VkQueue queue,
                                            uint32_t submitCount, const VkSubmitInfo *pSubmits,
                                            VkFence fence)
{
  SERIALISE_ELEMENT(ResourceId, queueId, GetResID(queue));
  SERIALISE_ELEMENT(ResourceId, fenceId, fence != VK_NULL_HANDLE ? GetResID(fence) : ResourceId());

  SERIALISE_ELEMENT(uint32_t, numCmds, pSubmits->commandBufferCount);

  vector<ResourceId> cmdIds;
  VkCommandBuffer *cmds = m_State >= WRITING ? NULL : new VkCommandBuffer[numCmds];
  for(uint32_t i = 0; i < numCmds; i++)
  {
    ResourceId bakedId;

    if(m_State >= WRITING)
    {
      VkResourceRecord *record = GetRecord(pSubmits->pCommandBuffers[i]);
      RDCASSERT(record->bakedCommands);
      if(record->bakedCommands)
        bakedId = record->bakedCommands->GetResourceID();
    }

    SERIALISE_ELEMENT(ResourceId, id, bakedId);

    if(m_State < WRITING)
    {
      cmdIds.push_back(id);

      cmds[i] = id != ResourceId() ? Unwrap(GetResourceManager()->GetLiveHandle<VkCommandBuffer>(id))
                                   : NULL;
    }
  }

  if(m_State < WRITING)
  {
    queue = GetResourceManager()->GetLiveHandle<VkQueue>(queueId);
    if(fenceId != ResourceId())
      fence = GetResourceManager()->GetLiveHandle<VkFence>(fenceId);
    else
      fence = VK_NULL_HANDLE;
  }

  // we don't serialise semaphores at all, just whether we waited on any.
  // For waiting semaphores, since we don't track state we have to just conservatively
  // wait for queue idle. Since we do that, there's equally no point in signalling semaphores
  SERIALISE_ELEMENT(uint32_t, numWaitSems, pSubmits->waitSemaphoreCount);

  if(m_State < WRITING && numWaitSems > 0)
    ObjDisp(queue)->QueueWaitIdle(Unwrap(queue));

  VkSubmitInfo submitInfo = {
      VK_STRUCTURE_TYPE_SUBMIT_INFO,
      NULL,
      0,
      NULL,
      NULL,    // wait semaphores
      numCmds,
      cmds,    // command buffers
      0,
      NULL,    // signal semaphores
  };

  const string desc = localSerialiser->GetDebugStr();

  Serialise_DebugMessages(localSerialiser, true);

  if(m_State == READING)
  {
    // don't submit the fence, since we have nothing to wait on it being signalled, and we might
    // not have it correctly in the unsignalled state.
    ObjDisp(queue)->QueueSubmit(Unwrap(queue), 1, &submitInfo, VK_NULL_HANDLE);

    for(uint32_t i = 0; i < numCmds; i++)
    {
      ResourceId cmd = GetResourceManager()->GetLiveID(cmdIds[i]);
      GetResourceManager()->ApplyBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts);
    }

    AddEvent(QUEUE_SUBMIT, desc);

    // we're adding multiple events, need to increment ourselves
    m_RootEventID++;

    string basename = "vkQueueSubmit(" + ToStr::Get(numCmds) + ")";

    for(uint32_t c = 0; c < numCmds; c++)
    {
      string name = StringFormat::Fmt("=> %s[%u]: vkBeginCommandBuffer(%s)", basename.c_str(), c,
                                      ToStr::Get(cmdIds[c]).c_str());

      // add a fake marker
      FetchDrawcall draw;
      draw.name = name;
      draw.flags |= eDraw_SetMarker;
      AddEvent(SET_MARKER, name);
      AddDrawcall(draw, true);
      m_RootEventID++;

      BakedCmdBufferInfo &cmdBufInfo = m_BakedCmdBufferInfo[cmdIds[c]];

      // insert the baked command buffer in-line into this list of notes, assigning new event and
      // drawIDs
      InsertDrawsAndRefreshIDs(cmdBufInfo.draw->children);

      for(size_t e = 0; e < cmdBufInfo.draw->executedCmds.size(); e++)
      {
        vector<uint32_t> &submits =
            m_Partial[Secondary].cmdBufferSubmits[cmdBufInfo.draw->executedCmds[e]];

        for(size_t s = 0; s < submits.size(); s++)
          submits[s] += m_RootEventID;
      }

      for(size_t i = 0; i < cmdBufInfo.debugMessages.size(); i++)
      {
        m_DebugMessages.push_back(cmdBufInfo.debugMessages[i]);
        m_DebugMessages.back().eventID += m_RootEventID;
      }

      // only primary command buffers can be submitted
      m_Partial[Primary].cmdBufferSubmits[cmdIds[c]].push_back(m_RootEventID);

      m_RootEventID += cmdBufInfo.eventCount;
      m_RootDrawcallID += cmdBufInfo.drawCount;

      name = StringFormat::Fmt("=> %s[%u]: vkEndCommandBuffer(%s)", basename.c_str(), c,
                               ToStr::Get(cmdIds[c]).c_str());
      draw.name = name;
      AddEvent(SET_MARKER, name);
      AddDrawcall(draw, true);
      m_RootEventID++;
    }

    // account for the outer loop thinking we've added one event and incrementing,
    // since we've done all the handling ourselves this will be off by one.
    m_RootEventID--;
  }
  else if(m_State == EXECUTING)
  {
    // account for the queue submit event
    m_RootEventID++;

    uint32_t startEID = m_RootEventID;

    // advance m_CurEventID to match the events added when reading
    for(uint32_t c = 0; c < numCmds; c++)
    {
      // 2 extra for the virtual labels around the command buffer
      m_RootEventID += 2 + m_BakedCmdBufferInfo[cmdIds[c]].eventCount;
      m_RootDrawcallID += 2 + m_BakedCmdBufferInfo[cmdIds[c]].drawCount;
    }

    // same accounting for the outer loop as above
    m_RootEventID--;

    if(numCmds == 0)
    {
      // do nothing, don't bother with the logic below
    }
    else if(m_LastEventID <= startEID)
    {
#ifdef VERBOSE_PARTIAL_REPLAY
      RDCDEBUG("Queue Submit no replay %u == %u", m_LastEventID, startEID);
#endif
    }
    else if(m_DrawcallCallback && m_DrawcallCallback->RecordAllCmds())
    {
#ifdef VERBOSE_PARTIAL_REPLAY
      RDCDEBUG("Queue Submit re-recording from %u", m_RootEventID);
#endif

      vector<VkCommandBuffer> rerecordedCmds;

      for(uint32_t c = 0; c < numCmds; c++)
      {
        VkCommandBuffer cmd = RerecordCmdBuf(cmdIds[c]);
        ResourceId rerecord = GetResID(cmd);
#ifdef VERBOSE_PARTIAL_REPLAY
        RDCDEBUG("Queue Submit fully re-recorded replay of %llu, using %llu", cmdIds[c], rerecord);
#endif
        rerecordedCmds.push_back(Unwrap(cmd));

        GetResourceManager()->ApplyBarriers(m_BakedCmdBufferInfo[rerecord].imgbarriers,
                                            m_ImageLayouts);
      }

      submitInfo.commandBufferCount = (uint32_t)rerecordedCmds.size();
      submitInfo.pCommandBuffers = &rerecordedCmds[0];
      // don't submit the fence, since we have nothing to wait on it being signalled, and we might
      // not have it correctly in the unsignalled state.
      ObjDisp(queue)->QueueSubmit(Unwrap(queue), 1, &submitInfo, VK_NULL_HANDLE);
    }
    else if(m_LastEventID > startEID && m_LastEventID < m_RootEventID)
    {
#ifdef VERBOSE_PARTIAL_REPLAY
      RDCDEBUG("Queue Submit partial replay %u < %u", m_LastEventID, m_RootEventID);
#endif

      uint32_t eid = startEID;

      vector<ResourceId> trimmedCmdIds;
      vector<VkCommandBuffer> trimmedCmds;

      for(uint32_t c = 0; c < numCmds; c++)
      {
        // account for the virtual vkBeginCommandBuffer label at the start of the events here
        // so it matches up to baseEvent
        eid++;

        uint32_t end = eid + m_BakedCmdBufferInfo[cmdIds[c]].eventCount;

        if(eid == m_Partial[Primary].baseEvent)
        {
          ResourceId partial = GetResID(RerecordCmdBuf(cmdIds[c], Primary));
#ifdef VERBOSE_PARTIAL_REPLAY
          RDCDEBUG("Queue Submit partial replay of %llu at %u, using %llu", cmdIds[c], eid, partial);
#endif
          trimmedCmdIds.push_back(partial);
          trimmedCmds.push_back(Unwrap(RerecordCmdBuf(cmdIds[c], Primary)));
        }
        else if(m_LastEventID >= end)
        {
#ifdef VERBOSE_PARTIAL_REPLAY
          RDCDEBUG("Queue Submit full replay %llu", cmdIds[c]);
#endif
          trimmedCmdIds.push_back(cmdIds[c]);
          trimmedCmds.push_back(
              Unwrap(GetResourceManager()->GetLiveHandle<VkCommandBuffer>(cmdIds[c])));
        }
        else
        {
#ifdef VERBOSE_PARTIAL_REPLAY
          RDCDEBUG("Queue not submitting %llu", cmdIds[c]);
#endif
        }

        // 1 extra to account for the virtual end command buffer label (begin is accounted for
        // above)
        eid += 1 + m_BakedCmdBufferInfo[cmdIds[c]].eventCount;
      }

      RDCASSERT(trimmedCmds.size() > 0);

      submitInfo.commandBufferCount = (uint32_t)trimmedCmds.size();
      submitInfo.pCommandBuffers = &trimmedCmds[0];
      // don't submit the fence, since we have nothing to wait on it being signalled, and we might
      // not have it correctly in the unsignalled state.
      ObjDisp(queue)->QueueSubmit(Unwrap(queue), 1, &submitInfo, VK_NULL_HANDLE);

      for(uint32_t i = 0; i < trimmedCmdIds.size(); i++)
      {
        ResourceId cmd = trimmedCmdIds[i];
        GetResourceManager()->ApplyBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts);
      }
    }
    else
    {
#ifdef VERBOSE_PARTIAL_REPLAY
      RDCDEBUG("Queue Submit full replay %u >= %u", m_LastEventID, m_RootEventID);
#endif

      // don't submit the fence, since we have nothing to wait on it being signalled, and we might
      // not have it correctly in the unsignalled state.
      ObjDisp(queue)->QueueSubmit(Unwrap(queue), 1, &submitInfo, VK_NULL_HANDLE);

      for(uint32_t i = 0; i < numCmds; i++)
      {
        ResourceId cmd = GetResourceManager()->GetLiveID(cmdIds[i]);
        GetResourceManager()->ApplyBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts);
      }
    }
  }

  SAFE_DELETE_ARRAY(cmds);

  return true;
}