JNIEXPORT void JNICALL Java_org_jetbrains_skiko_graphicapi_InternalDirectXApi_waitForCompletion()

in skiko/src/awtMain/cpp/windows/InternalDirectXApi.cc [315:374]


    JNIEXPORT void JNICALL Java_org_jetbrains_skiko_graphicapi_InternalDirectXApi_waitForCompletion(
            JNIEnv *env, jobject redrawer, jlong devicePtr, jlong texturePtr) {

        DirectXOffscreenDevice *device = fromJavaPointer<DirectXOffscreenDevice *>(devicePtr);

        DirectXOffScreenTexture *texture = fromJavaPointer<DirectXOffScreenTexture *>(texturePtr);

        auto commandAllocator = device->commandAllocator;
        auto commandList = device->commandList;

        commandAllocator->Reset();
        commandList->Reset(commandAllocator, nullptr);

        D3D12_RESOURCE_BARRIER textureResourceBarrier;
        textureResourceBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
        textureResourceBarrier.Transition.pResource = texture->resource;
        textureResourceBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
        textureResourceBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_SOURCE;
        textureResourceBarrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES ;
        textureResourceBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;

        commandList->ResourceBarrier(1, &textureResourceBarrier);

        D3D12_TEXTURE_COPY_LOCATION src = {};
        src.pResource = texture->resource;
        src.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
        src.SubresourceIndex = 0;

        D3D12_TEXTURE_COPY_LOCATION dst = {};
        dst.pResource = texture->readbackBufferResource;
        dst.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
        dst.PlacedFootprint.Offset = 0;
        dst.PlacedFootprint.Footprint.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
        dst.PlacedFootprint.Footprint.Width = texture->width;
        dst.PlacedFootprint.Footprint.Height = texture->height;
        dst.PlacedFootprint.Footprint.Depth = 1;
        dst.PlacedFootprint.Footprint.RowPitch = calculateRowPitch(texture->width);

        D3D12_BOX srcBox = {0, 0, 0, static_cast<UINT>(texture->width), static_cast<UINT>(texture->height), 1};

        commandList->CopyTextureRegion(&dst, 0, 0, 0, &src, &srcBox);

        commandList->Close();

        ID3D12CommandList* commandLists[] = { commandList };
        device->backendContext.fQueue->ExecuteCommandLists(_countof(commandLists), commandLists);

        // Wait for the command list to finish executing; the readback buffer will be ready to read
        auto fence = device->fence;
        auto fenceEvent = device->fenceEvent;
        auto& fenceValue = device->fenceValue;

        fenceValue += 1;
        device->backendContext.fQueue->Signal(fence, fenceValue);

        if (fence->GetCompletedValue() < fenceValue) {
            fence->SetEventOnCompletion(fenceValue, fenceEvent);
            WaitForSingleObject(fenceEvent, INFINITE);
        }
    }