public void ResourceFromTexture3D(Device device, Type bufferType)
    {
        using Texture3D <float> buffer = device.Get().AllocateTexture3D <float>(bufferType, 16, 16, 4);

        using ComPtr <ID3D12Resource> d3D12Resource = default;

        InteropServices.GetID3D12Resource(buffer, Windows.__uuidof <ID3D12Resource>(), (void **)d3D12Resource.GetAddressOf());

        Assert.IsTrue(d3D12Resource.Get() != null);
        Assert.AreEqual(d3D12Resource.Get()->GetDesc().Dimension, D3D12_RESOURCE_DIMENSION_TEXTURE3D);

        d3D12Resource.Dispose();

        int hResult = InteropServices.TryGetID3D12Resource(buffer, Windows.__uuidof <ID3D12Resource>(), (void **)d3D12Resource.GetAddressOf());

        Assert.AreEqual(hResult, S.S_OK);
        Assert.IsTrue(d3D12Resource.Get() != null);
        Assert.AreEqual(d3D12Resource.Get()->GetDesc().Dimension, D3D12_RESOURCE_DIMENSION_TEXTURE3D);
    }
Exemple #2
0
        public void ResourceFromBuffer(Device device, Type bufferType)
        {
            using Buffer <float> buffer = device.Get().AllocateBuffer <float>(bufferType, 128);

            using ComPtr <ID3D12Resource> d3D12Resource = default;

            InteropServices.GetID3D12Resource(buffer, FX.__uuidof <ID3D12Resource>(), (void **)d3D12Resource.GetAddressOf());

            Assert.IsTrue(d3D12Resource.Get() != null);
            Assert.AreEqual(d3D12Resource.Get()->GetDesc().Dimension, D3D12_RESOURCE_DIMENSION_BUFFER);

            d3D12Resource.Dispose();

            int hResult = InteropServices.TryGetID3D12Resource(buffer, FX.__uuidof <ID3D12Resource>(), (void **)d3D12Resource.GetAddressOf());

            Assert.AreEqual(hResult, FX.S_OK);
            Assert.IsTrue(d3D12Resource.Get() != null);
            Assert.AreEqual(d3D12Resource.Get()->GetDesc().Dimension, D3D12_RESOURCE_DIMENSION_BUFFER);
        }
    public void GetDevice(Device device)
    {
        using ComPtr <ID3D12Device> d3D12Device = default;

        InteropServices.GetID3D12Device(device.Get(), Windows.__uuidof <ID3D12Device>(), (void **)d3D12Device.GetAddressOf());

        Assert.IsTrue(d3D12Device.Get() != null);

        LUID luid = d3D12Device.Get()->GetAdapterLuid();

        Assert.IsTrue(*(ulong *)&luid != 0);

        d3D12Device.Dispose();

        int hResult = InteropServices.TryGetID3D12Device(device.Get(), Windows.__uuidof <ID3D12Device>(), (void **)d3D12Device.GetAddressOf());

        Assert.AreEqual(hResult, S.S_OK);
        Assert.IsTrue(d3D12Device.Get() != null);

        luid = d3D12Device.Get()->GetAdapterLuid();

        Assert.IsTrue(*(ulong *)&luid != 0);
    }
    /// <inheritdoc/>
    public override unsafe void OnInitialize(HWND hwnd)
    {
        // Get the underlying ID3D12Device in use
        fixed(ID3D12Device **d3D12Device = this.d3D12Device)
        {
            _ = InteropServices.TryGetID3D12Device(GraphicsDevice.Default, Windows.__uuidof <ID3D12Device>(), (void **)d3D12Device);
        }

        // Create the direct command queue to use
        fixed(ID3D12CommandQueue **d3D12CommandQueue = this.d3D12CommandQueue)
        {
            D3D12_COMMAND_QUEUE_DESC d3D12CommandQueueDesc;

            d3D12CommandQueueDesc.Type     = D3D12_COMMAND_LIST_TYPE.D3D12_COMMAND_LIST_TYPE_DIRECT;
            d3D12CommandQueueDesc.Priority = (int)D3D12_COMMAND_QUEUE_PRIORITY.D3D12_COMMAND_QUEUE_PRIORITY_NORMAL;
            d3D12CommandQueueDesc.Flags    = D3D12_COMMAND_QUEUE_FLAGS.D3D12_COMMAND_QUEUE_FLAG_NONE;
            d3D12CommandQueueDesc.NodeMask = 0;

            _ = d3D12Device.Get()->CreateCommandQueue(
                &d3D12CommandQueueDesc,
                Windows.__uuidof <ID3D12CommandQueue>(),
                (void **)d3D12CommandQueue);
        }

        // Create the direct fence
        fixed(ID3D12Fence **d3D12Fence = this.d3D12Fence)
        {
            _ = this.d3D12Device.Get()->CreateFence(
                0,
                D3D12_FENCE_FLAGS.D3D12_FENCE_FLAG_NONE,
                Windows.__uuidof <ID3D12Fence>(),
                (void **)d3D12Fence);
        }

        // Create the swap chain to display frames
        fixed(IDXGISwapChain1 **dxgiSwapChain1 = this.dxgiSwapChain1)
        {
            using ComPtr <IDXGIFactory2> dxgiFactory2 = default;

            _ = DirectX.CreateDXGIFactory2(DXGI.DXGI_CREATE_FACTORY_DEBUG, Windows.__uuidof <IDXGIFactory2>(), (void **)dxgiFactory2.GetAddressOf());

            DXGI_SWAP_CHAIN_DESC1 dxgiSwapChainDesc1 = default;

            dxgiSwapChainDesc1.AlphaMode   = DXGI_ALPHA_MODE.DXGI_ALPHA_MODE_IGNORE;
            dxgiSwapChainDesc1.BufferCount = 2;
            dxgiSwapChainDesc1.Flags       = 0;
            dxgiSwapChainDesc1.Format      = DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM;
            dxgiSwapChainDesc1.Width       = 0;
            dxgiSwapChainDesc1.Height      = 0;
            dxgiSwapChainDesc1.SampleDesc  = new DXGI_SAMPLE_DESC(count: 1, quality: 0);
            dxgiSwapChainDesc1.Scaling     = DXGI_SCALING.DXGI_SCALING_STRETCH;
            dxgiSwapChainDesc1.Stereo      = 0;
            dxgiSwapChainDesc1.SwapEffect  = DXGI_SWAP_EFFECT.DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;

            _ = dxgiFactory2.Get()->CreateSwapChainForHwnd(
                (IUnknown *)d3D12CommandQueue.Get(),
                hwnd,
                &dxgiSwapChainDesc1,
                null,
                null,
                dxgiSwapChain1);
        }

        // Create the command allocator to use
        fixed(ID3D12CommandAllocator **d3D12CommandAllocator = this.d3D12CommandAllocator)
        {
            this.d3D12Device.Get()->CreateCommandAllocator(
                D3D12_COMMAND_LIST_TYPE.D3D12_COMMAND_LIST_TYPE_DIRECT,
                Windows.__uuidof <ID3D12CommandAllocator>(),
                (void **)d3D12CommandAllocator);
        }

        // Create the reusable command list to copy data to the back buffers
        fixed(ID3D12GraphicsCommandList **d3D12GraphicsCommandList = this.d3D12GraphicsCommandList)
        {
            this.d3D12Device.Get()->CreateCommandList(
                0,
                D3D12_COMMAND_LIST_TYPE.D3D12_COMMAND_LIST_TYPE_DIRECT,
                d3D12CommandAllocator,
                null,
                Windows.__uuidof <ID3D12GraphicsCommandList>(),
                (void **)d3D12GraphicsCommandList);
        }

        // Close the command list to prepare it for future use
        this.d3D12GraphicsCommandList.Get()->Close();
    }
        /// <inheritdoc/>
        public override unsafe void OnUpdate(TimeSpan time)
        {
            if (this.isResizePending)
            {
                ApplyResize();

                this.isResizePending = false;
            }

            // Generate the new frame
            Gpu.Default.For(this.texture !.Width, this.texture.Height, this.shaderFactory(this.texture, time));

            using ComPtr <ID3D12Resource> d3D12Resource = default;

            // Get the underlying ID3D12Resource pointer for the texture
            _ = InteropServices.TryGetID3D12Resource(this.texture, FX.__uuidof <ID3D12Resource>(), (void **)d3D12Resource.GetAddressOf());

            // Get the target back buffer to update
            ID3D12Resource *d3D12ResourceBackBuffer = this.currentBufferIndex switch
            {
                0 => this.d3D12Resource0.Get(),
                1 => this.d3D12Resource1.Get(),
                _ => null
            };

            this.currentBufferIndex ^= 1;

            // Reset the command list and command allocator
            this.d3D12CommandAllocator.Get()->Reset();
            this.d3D12GraphicsCommandList.Get()->Reset(this.d3D12CommandAllocator.Get(), null);

            D3D12_RESOURCE_BARRIER *d3D12ResourceBarriers = stackalloc D3D12_RESOURCE_BARRIER[]
            {
                D3D12_RESOURCE_BARRIER.InitTransition(
                    d3D12Resource.Get(),
                    D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
                    D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_COPY_SOURCE),
                D3D12_RESOURCE_BARRIER.InitTransition(
                    d3D12ResourceBackBuffer,
                    D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_COMMON,
                    D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_COPY_DEST)
            };

            // Transition the resources to COPY_DEST and COPY_SOURCE respectively
            d3D12GraphicsCommandList.Get()->ResourceBarrier(2, d3D12ResourceBarriers);

            // Copy the generated frame to the target back buffer
            d3D12GraphicsCommandList.Get()->CopyResource(d3D12ResourceBackBuffer, d3D12Resource.Get());

            d3D12ResourceBarriers[0] = D3D12_RESOURCE_BARRIER.InitTransition(
                d3D12Resource.Get(),
                D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_COPY_SOURCE,
                D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_UNORDERED_ACCESS);

            d3D12ResourceBarriers[1] = D3D12_RESOURCE_BARRIER.InitTransition(
                d3D12ResourceBackBuffer,
                D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_COPY_DEST,
                D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_COMMON);

            // Transition the resources back to COMMON and UNORDERED_ACCESS respectively
            d3D12GraphicsCommandList.Get()->ResourceBarrier(2, d3D12ResourceBarriers);

            d3D12GraphicsCommandList.Get()->Close();

            // Execute the command list to perform the copy
            this.d3D12CommandQueue.Get()->ExecuteCommandLists(1, (ID3D12CommandList **)d3D12GraphicsCommandList.GetAddressOf());
            this.d3D12CommandQueue.Get()->Signal(this.d3D12Fence.Get(), this.nextD3D12FenceValue);

            // Present the new frame
            this.dxgiSwapChain1.Get()->Present(0, 0);

            if (this.nextD3D12FenceValue > this.d3D12Fence.Get()->GetCompletedValue())
            {
                this.d3D12Fence.Get()->SetEventOnCompletion(this.nextD3D12FenceValue, default);
            }

            this.nextD3D12FenceValue++;
        }
    }
}