void submitCommandsAndWait (const DeviceInterface& vk, const VkDevice device, const VkQueue queue, const VkCommandBuffer commandBuffer) { const VkFenceCreateInfo fenceParams = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; 0u, // VkFenceCreateFlags flags; }; const Unique<VkFence> fence(createFence(vk, device, &fenceParams)); const VkSubmitInfo submitInfo = { VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; 0u, // deUint32 waitSemaphoreCount; DE_NULL, // const VkSemaphore* pWaitSemaphores; (const VkPipelineStageFlags*)DE_NULL, 1u, // deUint32 commandBufferCount; &commandBuffer, // const VkCommandBuffer* pCommandBuffers; 0u, // deUint32 signalSemaphoreCount; DE_NULL, // const VkSemaphore* pSignalSemaphores; }; VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence)); VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull)); }
void Window::initializeD3D() { f = createFence(); ID3D12Device *dev = device(); if (FAILED(dev->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, commandAllocator(), Q_NULLPTR, IID_PPV_ARGS(&commandList)))) { qWarning("Failed to create command list"); return; } commandList->Close(); }
vk::Move<vk::VkFence> createAndImportFence (const vk::DeviceInterface& vkd, const vk::VkDevice device, vk::VkExternalFenceHandleTypeFlagBitsKHR externalType, NativeHandle& handle, vk::VkFenceImportFlagsKHR flags) { vk::Move<vk::VkFence> fence (createFence(vkd, device)); importFence(vkd, device, *fence, externalType, handle, flags); return fence; }
QImage QD3D12Window::readbackRGBA8888(ID3D12Resource *rt, D3D12_RESOURCE_STATES rtState, ID3D12GraphicsCommandList *commandList) { ComPtr<ID3D12Resource> readbackBuf; D3D12_RESOURCE_DESC rtDesc = rt->GetDesc(); UINT64 textureByteSize = 0; D3D12_PLACED_SUBRESOURCE_FOOTPRINT textureLayout = {}; device()->GetCopyableFootprints(&rtDesc, 0, 1, 0, &textureLayout, Q_NULLPTR, Q_NULLPTR, &textureByteSize); D3D12_HEAP_PROPERTIES heapProp = {}; heapProp.Type = D3D12_HEAP_TYPE_READBACK; D3D12_RESOURCE_DESC bufDesc = {}; bufDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; bufDesc.Width = textureByteSize; bufDesc.Height = 1; bufDesc.DepthOrArraySize = 1; bufDesc.MipLevels = 1; bufDesc.Format = DXGI_FORMAT_UNKNOWN; bufDesc.SampleDesc.Count = 1; bufDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; if (FAILED(device()->CreateCommittedResource(&heapProp, D3D12_HEAP_FLAG_NONE, &bufDesc, D3D12_RESOURCE_STATE_COPY_DEST, Q_NULLPTR, IID_PPV_ARGS(&readbackBuf)))) { qWarning("Failed to create committed resource (readback buffer)"); return QImage(); } D3D12_TEXTURE_COPY_LOCATION dstLoc; dstLoc.pResource = readbackBuf.Get(); dstLoc.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; dstLoc.PlacedFootprint = textureLayout; D3D12_TEXTURE_COPY_LOCATION srcLoc; srcLoc.pResource = rt; srcLoc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; srcLoc.SubresourceIndex = 0; transitionResource(rt, commandList, rtState, D3D12_RESOURCE_STATE_COPY_SOURCE); commandList->CopyTextureRegion(&dstLoc, 0, 0, 0, &srcLoc, Q_NULLPTR); transitionResource(rt, commandList, D3D12_RESOURCE_STATE_COPY_SOURCE, rtState); commandList->Close(); ID3D12CommandList *commandLists[] = { commandList }; commandQueue()->ExecuteCommandLists(_countof(commandLists), commandLists); QScopedPointer<Fence> f(createFence()); waitForGPU(f.data()); QImage img(rtDesc.Width, rtDesc.Height, QImage::Format_RGBA8888); quint8 *p = Q_NULLPTR; D3D12_RANGE readRange = { 0, 0 }; if (FAILED(readbackBuf->Map(0, &readRange, reinterpret_cast<void **>(&p)))) { qWarning("Mapping the readback buffer failed"); return QImage(); } for (UINT y = 0; y < rtDesc.Height; ++y) { quint8 *dst = img.scanLine(y); memcpy(dst, p, rtDesc.Width * 4); p += textureLayout.Footprint.RowPitch; } readbackBuf->Unmap(0, Q_NULLPTR); return img; }