bool WrappedOpenGL::Serialise_glUseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program)
{
  if(GetLogVersion() >= 0x000011)
  {
    // this marker value is used below to identify where the serialised data sits.
    SERIALISE_ELEMENT(uint64_t, marker, marker_glUseProgramStages_hack);
  }
  SERIALISE_ELEMENT(ResourceId, pipe,
                    GetResourceManager()->GetID(ProgramPipeRes(GetCtx(), pipeline)));
  SERIALISE_ELEMENT(uint32_t, Stages, stages);
  SERIALISE_ELEMENT(
      ResourceId, prog,
      (program ? GetResourceManager()->GetID(ProgramRes(GetCtx(), program)) : ResourceId()));

  if(m_State < WRITING)
  {
    if(prog != ResourceId())
    {
      ResourceId livePipeId = GetResourceManager()->GetLiveID(pipe);
      ResourceId liveProgId = GetResourceManager()->GetLiveID(prog);

      PipelineData &pipeDetails = m_Pipelines[livePipeId];
      ProgramData &progDetails = m_Programs[liveProgId];

      for(size_t s = 0; s < 6; s++)
      {
        if(Stages & ShaderBit(s))
        {
          for(size_t sh = 0; sh < progDetails.shaders.size(); sh++)
          {
            if(m_Shaders[progDetails.shaders[sh]].type == ShaderEnum(s))
            {
              pipeDetails.stagePrograms[s] = liveProgId;
              pipeDetails.stageShaders[s] = progDetails.shaders[sh];
              break;
            }
          }
        }
      }

      m_Real.glUseProgramStages(GetResourceManager()->GetLiveResource(pipe).name, Stages,
                                GetResourceManager()->GetLiveResource(prog).name);
    }
    else
    {
      ResourceId livePipeId = GetResourceManager()->GetLiveID(pipe);
      PipelineData &pipeDetails = m_Pipelines[livePipeId];

      for(size_t s = 0; s < 6; s++)
      {
        if(Stages & ShaderBit(s))
        {
          pipeDetails.stagePrograms[s] = ResourceId();
          pipeDetails.stageShaders[s] = ResourceId();
        }
      }

      m_Real.glUseProgramStages(GetResourceManager()->GetLiveResource(pipe).name, Stages, 0);
    }
  }

  return true;
}
Beispiel #2
0
bool WrappedVulkan::Serialise_vkCreateSwapchainKHR(Serialiser *localSerialiser, VkDevice device,
                                                   const VkSwapchainCreateInfoKHR *pCreateInfo,
                                                   const VkAllocationCallbacks *pAllocator,
                                                   VkSwapchainKHR *pSwapChain)
{
  SERIALISE_ELEMENT(ResourceId, devId, GetResID(device));
  SERIALISE_ELEMENT(VkSwapchainCreateInfoKHR, info, *pCreateInfo);
  SERIALISE_ELEMENT(ResourceId, id, GetResID(*pSwapChain));

  uint32_t numIms = 0;

  if(m_State >= WRITING)
  {
    VkResult vkr = VK_SUCCESS;

    vkr = ObjDisp(device)->GetSwapchainImagesKHR(Unwrap(device), Unwrap(*pSwapChain), &numIms, NULL);
    RDCASSERTEQUAL(vkr, VK_SUCCESS);
  }

  SERIALISE_ELEMENT(uint32_t, numSwapImages, numIms);
  SERIALISE_ELEMENT(VkSharingMode, sharingMode, pCreateInfo->imageSharingMode);

  // default to 0 for old logs, in most cases this doesn't change anything
  VkImageUsageFlags usage = pCreateInfo ? pCreateInfo->imageUsage : 0;
  if(m_State >= WRITING || GetLogVersion() >= 0x0000006)
  {
    localSerialiser->Serialise("usage", usage);
  }

  if(m_State == READING)
  {
    // use original ID because we don't create a live version of the swapchain
    SwapchainInfo &swapinfo = m_CreationInfo.m_SwapChain[id];

    swapinfo.format = info.imageFormat;
    swapinfo.extent = info.imageExtent;
    swapinfo.arraySize = info.imageArrayLayers;

    swapinfo.images.resize(numSwapImages);

    device = GetResourceManager()->GetLiveHandle<VkDevice>(devId);

    const VkImageCreateInfo imInfo = {
        VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
        NULL,
        0,
        VK_IMAGE_TYPE_2D,
        info.imageFormat,
        {info.imageExtent.width, info.imageExtent.height, 1},
        1,
        info.imageArrayLayers,
        VK_SAMPLE_COUNT_1_BIT,
        VK_IMAGE_TILING_OPTIMAL,
        VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
            VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | usage,
        sharingMode,
        0,
        NULL,
        VK_IMAGE_LAYOUT_UNDEFINED,
    };

    for(uint32_t i = 0; i < numSwapImages; i++)
    {
      VkDeviceMemory mem = VK_NULL_HANDLE;
      VkImage im = VK_NULL_HANDLE;

      VkResult vkr = ObjDisp(device)->CreateImage(Unwrap(device), &imInfo, NULL, &im);
      RDCASSERTEQUAL(vkr, VK_SUCCESS);

      ResourceId liveId = GetResourceManager()->WrapResource(Unwrap(device), im);

      VkMemoryRequirements mrq = {0};

      ObjDisp(device)->GetImageMemoryRequirements(Unwrap(device), Unwrap(im), &mrq);

      VkMemoryAllocateInfo allocInfo = {
          VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, mrq.size,
          GetGPULocalMemoryIndex(mrq.memoryTypeBits),
      };

      vkr = ObjDisp(device)->AllocateMemory(Unwrap(device), &allocInfo, NULL, &mem);
      RDCASSERTEQUAL(vkr, VK_SUCCESS);

      ResourceId memid = GetResourceManager()->WrapResource(Unwrap(device), mem);
      // register as a live-only resource, so it is cleaned up properly
      GetResourceManager()->AddLiveResource(memid, mem);

      vkr = ObjDisp(device)->BindImageMemory(Unwrap(device), Unwrap(im), Unwrap(mem), 0);
      RDCASSERTEQUAL(vkr, VK_SUCCESS);

      // image live ID will be assigned separately in Serialise_vkGetSwapChainInfoWSI
      // memory doesn't have a live ID

      swapinfo.images[i].im = im;

      // fill out image info so we track resource state barriers
      // sneaky-cheeky use of the swapchain's ID here (it's not a live ID because
      // we don't create a live swapchain). This will be picked up in
      // Serialise_vkGetSwapchainImagesKHR to set the data for the live IDs on the
      // swapchain images.
      VulkanCreationInfo::Image &iminfo = m_CreationInfo.m_Image[id];
      iminfo.type = VK_IMAGE_TYPE_2D;
      iminfo.format = info.imageFormat;
      iminfo.extent.width = info.imageExtent.width;
      iminfo.extent.height = info.imageExtent.height;
      iminfo.extent.depth = 1;
      iminfo.mipLevels = 1;
      iminfo.arrayLayers = info.imageArrayLayers;
      iminfo.creationFlags =
          TextureCategory::ShaderRead | TextureCategory::ColorTarget | TextureCategory::SwapBuffer;
      iminfo.cube = false;
      iminfo.samples = VK_SAMPLE_COUNT_1_BIT;

      m_CreationInfo.m_Names[liveId] = StringFormat::Fmt("Presentable Image %u", i);

      VkImageSubresourceRange range;
      range.baseMipLevel = range.baseArrayLayer = 0;
      range.levelCount = 1;
      range.layerCount = info.imageArrayLayers;
      range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;

      m_ImageLayouts[liveId].extent = iminfo.extent;
      m_ImageLayouts[liveId].format = iminfo.format;

      m_ImageLayouts[liveId].subresourceStates.clear();
      m_ImageLayouts[liveId].subresourceStates.push_back(
          ImageRegionState(range, UNKNOWN_PREV_IMG_LAYOUT, VK_IMAGE_LAYOUT_UNDEFINED));
    }
  }

  return true;
}