Пример #1
0
void onRender()
{
	//
	// record all the commands we need to render the scene into the command list
	//

	populateCommandLists();

	//
	// execute the command list
	//

	ID3D12CommandList* ppCommandLists[] = { mCommandList.Get() };
	mCommandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists);

	//
	// swap the back and front buffers
	//

	mSwapChain->Present(1, 0);
	mIndexLastSwapBuf = (1 + mIndexLastSwapBuf) % cNumSwapBufs;
	mSwapChain->GetBuffer(mIndexLastSwapBuf, IID_PPV_ARGS(mRenderTarget.ReleaseAndGetAddressOf()));
	mDevice->CreateRenderTargetView(mRenderTarget.Get(), nullptr, mDescriptorHeap->GetCPUDescriptorHandleForHeapStart());

	//
	// wait and reset everything
	//

	waitForGPU();
}
Пример #2
0
void onDestroy()
{
	//
	// wait for the GPU to be done with all resources
	//

	waitForGPU();

	mSwapChain->SetFullscreenState(FALSE, nullptr);

	CloseHandle(mHandleEvent);
}
Пример #3
0
void loadAssets()
{
	//
	// handles to vert and pixel shaders
	//

	ComPtr<ID3DBlob> blobShaderVert, blobShaderPixel;

	//
	// compile shaders
	//

	D3DCompileFromFile(L"shaders.hlsl", nullptr, nullptr, "VShader", "vs_5_0", 0, 0, blobShaderVert.GetAddressOf(), nullptr);
	D3DCompileFromFile(L"shaders.hlsl", nullptr, nullptr, "PShader", "ps_5_0", 0, 0, blobShaderPixel.GetAddressOf(), nullptr);

	//
	// create input layout
	//

	D3D12_INPUT_ELEMENT_DESC layout[] =
	{
		{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_PER_VERTEX_DATA, 0 },
		{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D12_INPUT_PER_VERTEX_DATA, 0 }
	};
	UINT numElements = sizeof(layout) / sizeof(layout[0]);

	//
	// create an empty root signature
	//

	ComPtr<ID3DBlob> pOutBlob, pErrorBlob;
	D3D12_ROOT_SIGNATURE_DESC descRootSignature;
	descRootSignature.Init(0, nullptr, 0, nullptr, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);
	D3D12SerializeRootSignature(&descRootSignature, D3D_ROOT_SIGNATURE_VERSION_1, pOutBlob.GetAddressOf(), pErrorBlob.GetAddressOf());
	mDevice->CreateRootSignature(0, pOutBlob->GetBufferPointer(), pOutBlob->GetBufferSize(), IID_PPV_ARGS(mRootSignature.GetAddressOf()));

	//
	// create a PSO description
	//

	D3D12_GRAPHICS_PIPELINE_STATE_DESC descPso;
	ZeroMemory(&descPso, sizeof(descPso));
	descPso.InputLayout = { layout, numElements };
	descPso.pRootSignature = mRootSignature.Get();
	descPso.VS = { reinterpret_cast<BYTE*>(blobShaderVert->GetBufferPointer()), blobShaderVert->GetBufferSize() };
	descPso.PS = { reinterpret_cast<BYTE*>(blobShaderPixel->GetBufferPointer()), blobShaderPixel->GetBufferSize() };
	descPso.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT);
	descPso.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT);
	descPso.DepthStencilState.DepthEnable = FALSE;
	descPso.DepthStencilState.StencilEnable = FALSE;
	descPso.SampleMask = UINT_MAX;
	descPso.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
	descPso.NumRenderTargets = 1;
	descPso.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
	descPso.SampleDesc.Count = 1;

	//
	// create the actual PSO
	//

	mDevice->CreateGraphicsPipelineState(&descPso, IID_PPV_ARGS(mPSO.GetAddressOf()));

	//
	// create descriptor heap
	//

	D3D12_DESCRIPTOR_HEAP_DESC descHeap = {};
	descHeap.NumDescriptors = 1;
	descHeap.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
	descHeap.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
	mDevice->CreateDescriptorHeap(&descHeap, IID_PPV_ARGS(mDescriptorHeap.GetAddressOf()));

	//
	// create command list
	//

	mDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, mCommandAllocator.Get(), mPSO.Get(), IID_PPV_ARGS(mCommandList.GetAddressOf()));

	//
	// create backbuffer/rendertarget
	//

	mSwapChain->GetBuffer(0, IID_PPV_ARGS(mRenderTarget.GetAddressOf()));
	mDevice->CreateRenderTargetView(mRenderTarget.Get(), nullptr, mDescriptorHeap->GetCPUDescriptorHandleForHeapStart());

	//
	// set the viewport
	//

	mViewPort =
	{
		0.0f,
		0.0f,
		static_cast<float>(mWidth),
		static_cast<float>(mHeight),
		0.0f,
		1.0f
	};

	//
	// create scissor rectangle
	//

	mRectScissor = { 0, 0, mWidth, mHeight };

	//
	// create geometry for a triangle
	//

	VERTEX triangleVerts[] =
	{
		{ 0.0f, 0.5f, 0.0f,{ 1.0f, 0.0f, 0.0f, 1.0f } },
		{ 0.45f, -0.5, 0.0f,{ 0.0f, 1.0f, 0.0f, 1.0f } },
		{ -0.45f, -0.5f, 0.0f,{ 0.0f, 0.0f, 1.0f, 1.0f } }
	};

	//
	// actually create the vert buffer
	// Note: using upload heaps to transfer static data like vert buffers is not recommended.
	// Every time the GPU needs it, the upload heap will be marshalled over.  Please read up on Default Heap usage.
	// An upload heap is used here for code simplicity and because there are very few verts to actually transfer
	//

	mDevice->CreateCommittedResource(
		&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
		D3D12_HEAP_FLAG_NONE,
		&CD3DX12_RESOURCE_DESC::Buffer(3 * sizeof(VERTEX)),
		D3D12_RESOURCE_STATE_GENERIC_READ,
		nullptr,    // Clear value
		IID_PPV_ARGS(mBufVerts.GetAddressOf()));

	//
	// copy the triangle data to the vertex buffer
	//

	UINT8* dataBegin;
	mBufVerts->Map(0, nullptr, reinterpret_cast<void**>(&dataBegin));
	memcpy(dataBegin, triangleVerts, sizeof(triangleVerts));
	mBufVerts->Unmap(0, nullptr);

	//
	// create vertex buffer view
	//

	mDescViewBufVert.BufferLocation = mBufVerts->GetGPUVirtualAddress();
	mDescViewBufVert.StrideInBytes = sizeof(VERTEX);
	mDescViewBufVert.SizeInBytes = sizeof(triangleVerts);

	//
	// create fencing object
	//

	mDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(mFence.GetAddressOf()));
	mCurrentFence = 1;

	//
	// close the command list and use it to execute the initial GPU setup
	//

	mCommandList->Close();
	ID3D12CommandList* ppCommandLists[] = { mCommandList.Get() };
	mCommandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists);

	//
	// create event handle
	//

	mHandleEvent = CreateEventEx(nullptr, FALSE, FALSE, EVENT_ALL_ACCESS);

	//
	// wait for the command list to execute; we are reusing the same command list in our main loop but for now, 
	// we just want to wait for setup to complete before continuing
	//

	waitForGPU();
}
Пример #4
0
void Window::afterPresent()
{
    waitForGPU(f);
}
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;
}