Showing posts with label Desktop. Show all posts
Showing posts with label Desktop. Show all posts

Tuesday, January 1, 2019

Modifying D3D12HelloFrameBuffering desktop to support fullscreen

DirectX-Graphics-Samples-master\Samples\Desktop\D3D12HelloWorld\src\HelloFrameBuffers

There is D3D12Fullscreen desktop project but it is little bit complicated so I modified D3D12FrameBuffering desktop project to enable Fullscreen capability.

D3D12FrameBuffering Project setting

Right click D3D12FrameBuffering Project top open D3D12HelloFrameBuffering property pages.
Select configuration to "All configurations"
On Configuration Options > Manifest Tool > All options, set DPI Awareness to Per Monitor High DPI Aware.

Win32Application class


Copy  WM_SIZE handler from D3D12Fullscreen Win32Application to WindowProc()

DXSample class


Add OnSizeChanged() pure virtual function declaration to DXSample class
 virtual void OnSizeChanged(UINT width, UINT height, bool minimized) = 0;

Copy SetWindowBounds() from D3D12Fullscreen DXSample.
Add     RECT m_windowBounds; member.


D3D12HelloFrameBuffering class


Comment out following line to enable ALT+Enter

factory->MakeWindowAssociation(Win32Application::GetHwnd(), DXGI_MWA_NO_ALT_ENTER)


Add bool m_windowedMode variable to D3D12HelloFrameBuffering class.


Copy those functions from D3D12Fullscreen to D3D12HelloFrameBuffer
 void LoadSizeDependentResources();
 void UpdatePostViewAndScissor();
 void LoadSceneResolutionDependentResources();

 virtual void OnSizeChanged(UINT width, UINT height, bool minimized);


 PopulateCommandList() is unchanged.

This is my UpdatePostViewAndScissor() implementation:

void D3D12HelloFrameBuffering::UpdatePostViewAndScissor()
{
    float x = 1.0f;
    float y = 1.0f;

    m_viewport.TopLeftX = m_width * (1.0f - x) / 2.0f;
    m_viewport.TopLeftY = m_height * (1.0f - y) / 2.0f;
    m_viewport.Width = x * m_width;
    m_viewport.Height = y * m_height;

    m_scissorRect.left = static_cast<LONG>(m_viewport.TopLeftX);
    m_scissorRect.right = static_cast<LONG>(m_viewport.TopLeftX + m_viewport.Width);
    m_scissorRect.top = static_cast<LONG>(m_viewport.TopLeftY);
    m_scissorRect.bottom = static_cast<LONG>(m_viewport.TopLeftY + m_viewport.Height);
}


m_resolutionOptions[], m_postViewport, m_postScissorRect, m_postCommandList and LoadSceneResolutionDependentResources() is not absolute necessary

 Call LoadSizeDependentResources() on the last portion of LoadAssets()

Run and press ALT+Enter to switch fullscreen

Screen shot of D3D12HelloFrameBuffering, 3840x2160 fullscreen mode


Studying D3D12HelloConstBuffers desktop sample


DirectX-Graphics-Samples-master\Samples\Desktop\D3D12HelloWorld\src\HelloConstBuffers

•Describe how to pass constant buffer to shaders.

Diff from D3DXHelloTriangle.h


struct SceneConstantBuffer
    {
        XMFLOAT4 offset;
    };
SceneConstantBuffer m_constantBufferData;
// constant buffer view (CBV) descriptor heap.
ComPtr<ID3D12DescriptorHeap> m_cbvHeap;
ComPtr<ID3D12Resource> m_constantBuffer;
UINT8* m_pCbvDataBegin;

D3D12HelloConstBuffers objects and their relations






























m_constantBuffer->Map() is called to get mapped pointer m_cbvDataBegin on OnInit() and m_constantBuffer is never Unmap() ed. Keep constant buffer mapped is OK

OnUpdate(), constant buffer data is updated and memcpy() ed to m_cbvDataBegin.

m_commandList->SetDescriptorHeaps() and m_commandList->SetGraphicsRootDesrptorTable() to set m_cbvHeap.

on Shaders.hlsl, constant buffer is exposed at register(b0):

cbuffer SceneConstantBuffer : register(b0)

{

    float4 offset;

};




Saturday, December 29, 2018

Studying D3D12HelloTriangle and D3D12HelloBundles desktop project

D3D12HelloTriangle






Difference from D3D12HelloWorld

Took diff with WinMerge to find difference.

D3D12HelloTriangle class has several new members
CD3DX12_VIEWPORT m_viewport;
CD3DX12_RECT m_scissorRect;
ComPtr<ID3D12RootSignature> m_rootSignature;
ComPtr<ID3D12PipelineState> m_pipelineState;
ComPtr<ID3D12Resource> m_vertexBuffer;
D3D12_VERTEX_BUFFER_VIEW m_vertexBufferView;
New struct declaration of triangle vertex
struct Vertex {
    XMFLOAT3 position;
    XMFLOAT4 color;
};


D3D12HelloTriangle.cpp objects and their relations

m_rootSignature

rootSignature specifies shader input parameters such as vertex buffer location or shader constants.

But vertex buffer is specified by m_commandList->IASetVertexBuffers() and shader does not use shader constants.

m_rootSignature is referenced by pipeline state object and pso uses it internally.

m_commandList also referenced m_rootSignature but it seems it is not absolute necessary on this sample.

m_viewPort

specifies viewport size (used to scale images to fit client area)

m_scissorRect

this parameter is used for “scissoring” : scissors triangles which crosses window edge to prevent corruption of geometry shape.

m_pipelineState

contains rendering pipeline parameters such as vertex shader, pixel shader, alpha blending, render target format and m_rootSignature

m_vertexBuffer

contains triangle vertices position and vertex colors data.

data is placed on GPU memory.

m_vertexBufferView

struct to store GPU memory address of vertex buffer and its size info.

used by m_commandList

Shader code
 
Shader is a program that runs on GPU.

D3D12HelloTriangle sample contains shaders.hlsl

shaders.hlsl contains vertex shader VSMain() and pixel shader PSMain().

VSMain() processes one vertex, input vertex position and color from arg, and send it to subsequent stage. VSMain() is called 3 times.

PSMain() is called on every pixel of triangle with VSMain() return value and calculate pixel color.

Shader program is compiled to the executable code on D3D12HelloTriangle::OnInit() by calling D3DCompileFromFile() and those shader binaries is passed to pipeline state object.




D3D12HelloBundles sample



DirectX-Graphics-Samples-master\Samples\Desktop\D3D12HelloWorld\src\HelloBundles

Shows efficient triangle drawing using bundles.


Difference from HelloTriangle sample

 
D3D12HelloBundles.h

ComPtr<ID3D12CommandAllocator> m_bundleAllocator;

ComPtr<ID3D12GraphicsCommandList> m_bundle;

D3D12HelloBundles.cpp

m_bundleAllocator created as COMMAND_LIST_TYPE_BUNDLE

m_bundle command list is created as COMMAND_LIST_TYPE_BUNDLE and  record pipeline setup and draw commands

m_commandList->ExecuteBundle() to execute recorded pipeline setup and draw command


Studying D3D12HelloWorld desktop project

Studying D3D12HelloWindow desktop project



D3D12HelloWorld

Main.cpp
  • There is WinMain() function, the entry point of the program.
  • Instanciate D3D12HelloWindow and pass it to Win32Application::Run() function.
Win32Application.cpp
  • Handles Windows API calls such as CreateWindow() and WindowProc() callback.
DXSample.cpp
  • DXSample::GetHardwareAdapter() calls D3D12CreateDevice to get ID3D12Device ptr.
  • ParseCommandLineArgs() reads argc and argv and decide to use Warp(reference rasterizer) or not.
D3D12HelloWindow.cpp
  • Contains interesting DirectX12 code.
  • D3D12HelloWindow::OnInit() prepares DirectX 12 resources.
  • D3D12HelloWindow::OnRender() redraws image of render buffer and swap foreground render buffer with background render buffer.

D3D12HelloWindow members


m_swapChain
  • Has two Output Render Targets, its size is window size and pixel format is RGBA8888
  • m_swapChain->Present() is called to swap front buffer and back buffer on the next display vbrank event. this mechanism exists to prevent 都creen tearing・ it happens when displaying render target is overwritten by graphics redraw.
m_commandQueue
  • prepared on D3D12HelloWindow::OnInit()
  • associated to m_swapChain for force flush. (?)
  • on OnRender() m_commandQueue->ExecuteCommandLists() is called.
  • m_commandQueue->Signal() is used to wait frame redraw update.
m_commandList
  • contains draw call to run on GPU.
  • ClearRenderTargetView() with blue color specified.


Render target state management

 It is necessary to change render target state to RENDER_TARGET before drawing and revert to PRESENT state when drawing finished.

m_commandList->ResourceBarrier() do this task.



Double Buffering




VBlank event waiting


D3D12HelloWindow.cpp implementation is not optimal. D3DHelloFrameBuffering is more efficient. So VBlank event waiting code review will be performed with D3DHelloFrameBuffering



Next: Draw a triangle!


https://yamamoto2002.blogspot.com/2018/12/studying-d3d12hellotriangle-project.html