Added SimpleCompute samples for UWP
После Ширина: | Высота: | Размер: 39 KiB |
После Ширина: | Высота: | Размер: 23 KiB |
После Ширина: | Высота: | Размер: 26 KiB |
После Ширина: | Высота: | Размер: 24 KiB |
После Ширина: | Высота: | Размер: 45 KiB |
|
@ -0,0 +1,43 @@
|
|||
//--------------------------------------------------------------------------------------
|
||||
// File: fractal.hlsl
|
||||
//
|
||||
// This is a compute shader that draws a Mandelbrot fractal.
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
RWTexture2D<float4> OutputTexture : register(u0);
|
||||
Texture2D ColorMapTexture : register(t0);
|
||||
SamplerState ColorMapSampler : register(s0);
|
||||
|
||||
cbuffer cb0
|
||||
{
|
||||
float4 g_MaxThreadIter : packoffset(c0);
|
||||
float4 g_Window : packoffset(c1);
|
||||
}
|
||||
|
||||
[numthreads(8, 8, 1)]
|
||||
void main(uint3 DTid : SV_DispatchThreadID)
|
||||
{
|
||||
float2 WindowLocal = ((float2)DTid.xy / g_MaxThreadIter.xy) * float2(1, -1) + float2(-0.5f, 0.5f);
|
||||
float2 coord = WindowLocal.xy * g_Window.xy + g_Window.zw;
|
||||
|
||||
uint maxiter = (uint)g_MaxThreadIter.z * 4;
|
||||
uint iter = 0;
|
||||
float2 constant = coord;
|
||||
float2 sq;
|
||||
do
|
||||
{
|
||||
float2 newvalue;
|
||||
sq = coord * coord;
|
||||
newvalue.x = sq.x - sq.y;
|
||||
newvalue.y = 2 * coord.y * coord.x;
|
||||
coord = newvalue + constant;
|
||||
iter++;
|
||||
} while (iter < maxiter && (sq.x + sq.y) < 4.0);
|
||||
|
||||
float colorIndex = frac((float)iter / g_MaxThreadIter.z);
|
||||
float4 SampledColor = ColorMapTexture.SampleLevel(ColorMapSampler, float2(colorIndex, 0), 0);
|
||||
|
||||
OutputTexture[DTid.xy] = SampledColor;
|
||||
}
|
|
@ -0,0 +1,684 @@
|
|||
//
|
||||
// DeviceResources.cpp - A wrapper for the Direct3D 11 device and swapchain
|
||||
// (requires DirectX 11.3 Runtime)
|
||||
//
|
||||
|
||||
|
||||
#include "pch.h"
|
||||
#include "DeviceResources.h"
|
||||
|
||||
using namespace DirectX;
|
||||
using namespace DX;
|
||||
|
||||
using Microsoft::WRL::ComPtr;
|
||||
|
||||
namespace
|
||||
{
|
||||
#if defined(_DEBUG)
|
||||
// Check for SDK Layer support.
|
||||
inline bool SdkLayersAvailable()
|
||||
{
|
||||
HRESULT hr = D3D11CreateDevice(
|
||||
nullptr,
|
||||
D3D_DRIVER_TYPE_NULL, // There is no need to create a real hardware device.
|
||||
0,
|
||||
D3D11_CREATE_DEVICE_DEBUG, // Check for the SDK layers.
|
||||
nullptr, // Any feature level will do.
|
||||
0,
|
||||
D3D11_SDK_VERSION,
|
||||
nullptr, // No need to keep the D3D device reference.
|
||||
nullptr, // No need to know the feature level.
|
||||
nullptr // No need to keep the D3D device context reference.
|
||||
);
|
||||
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
#endif
|
||||
|
||||
inline DXGI_FORMAT NoSRGB(DXGI_FORMAT fmt)
|
||||
{
|
||||
switch (fmt)
|
||||
{
|
||||
case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: return DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: return DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: return DXGI_FORMAT_B8G8R8X8_UNORM;
|
||||
default: return fmt;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Constants used to calculate screen rotations
|
||||
namespace ScreenRotation
|
||||
{
|
||||
// 0-degree Z-rotation
|
||||
static const XMFLOAT4X4 Rotation0(
|
||||
1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
);
|
||||
|
||||
// 90-degree Z-rotation
|
||||
static const XMFLOAT4X4 Rotation90(
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
-1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
);
|
||||
|
||||
// 180-degree Z-rotation
|
||||
static const XMFLOAT4X4 Rotation180(
|
||||
-1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, -1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
);
|
||||
|
||||
// 270-degree Z-rotation
|
||||
static const XMFLOAT4X4 Rotation270(
|
||||
0.0f, -1.0f, 0.0f, 0.0f,
|
||||
1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
);
|
||||
};
|
||||
|
||||
// Constructor for DeviceResources.
|
||||
DeviceResources::DeviceResources(DXGI_FORMAT backBufferFormat, DXGI_FORMAT depthBufferFormat, UINT backBufferCount, D3D_FEATURE_LEVEL minFeatureLevel, unsigned int flags) :
|
||||
m_screenViewport{},
|
||||
m_backBufferFormat(backBufferFormat),
|
||||
m_depthBufferFormat(depthBufferFormat),
|
||||
m_backBufferCount(backBufferCount),
|
||||
m_d3dMinFeatureLevel(minFeatureLevel),
|
||||
m_window(nullptr),
|
||||
m_d3dFeatureLevel(D3D_FEATURE_LEVEL_9_1),
|
||||
m_rotation(DXGI_MODE_ROTATION_IDENTITY),
|
||||
m_dxgiFactoryFlags(0),
|
||||
m_outputSize{0, 0, 1, 1},
|
||||
m_orientationTransform3D(ScreenRotation::Rotation0),
|
||||
m_colorSpace(DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709),
|
||||
m_options(flags),
|
||||
m_deviceNotify(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
// Configures the Direct3D device, and stores handles to it and the device context.
|
||||
void DeviceResources::CreateDeviceResources()
|
||||
{
|
||||
UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
|
||||
|
||||
#if defined(_DEBUG)
|
||||
if (SdkLayersAvailable())
|
||||
{
|
||||
// If the project is in a debug build, enable debugging via SDK Layers with this flag.
|
||||
creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
|
||||
}
|
||||
else
|
||||
{
|
||||
OutputDebugStringA("WARNING: Direct3D Debug Device is not available\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_DEBUG)
|
||||
{
|
||||
ComPtr<IDXGIInfoQueue> dxgiInfoQueue;
|
||||
if (SUCCEEDED(DXGIGetDebugInterface1(0, IID_PPV_ARGS(dxgiInfoQueue.GetAddressOf()))))
|
||||
{
|
||||
m_dxgiFactoryFlags = DXGI_CREATE_FACTORY_DEBUG;
|
||||
|
||||
dxgiInfoQueue->SetBreakOnSeverity(DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_ERROR, true);
|
||||
dxgiInfoQueue->SetBreakOnSeverity(DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_CORRUPTION, true);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ThrowIfFailed(CreateDXGIFactory2(m_dxgiFactoryFlags, IID_PPV_ARGS(m_dxgiFactory.ReleaseAndGetAddressOf())));
|
||||
|
||||
// Determines whether tearing support is available for fullscreen borderless windows.
|
||||
if (m_options & c_AllowTearing)
|
||||
{
|
||||
BOOL allowTearing = FALSE;
|
||||
|
||||
ComPtr<IDXGIFactory5> factory5;
|
||||
HRESULT hr = m_dxgiFactory.As(&factory5);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = factory5->CheckFeatureSupport(DXGI_FEATURE_PRESENT_ALLOW_TEARING, &allowTearing, sizeof(allowTearing));
|
||||
}
|
||||
|
||||
if (FAILED(hr) || !allowTearing)
|
||||
{
|
||||
m_options &= ~c_AllowTearing;
|
||||
#ifdef _DEBUG
|
||||
OutputDebugStringA("WARNING: Variable refresh rate displays not supported");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// Determine DirectX hardware feature levels this app will support.
|
||||
static const D3D_FEATURE_LEVEL s_featureLevels[] =
|
||||
{
|
||||
D3D_FEATURE_LEVEL_12_1,
|
||||
D3D_FEATURE_LEVEL_12_0,
|
||||
D3D_FEATURE_LEVEL_11_1,
|
||||
D3D_FEATURE_LEVEL_11_0,
|
||||
D3D_FEATURE_LEVEL_10_1,
|
||||
D3D_FEATURE_LEVEL_10_0,
|
||||
D3D_FEATURE_LEVEL_9_3,
|
||||
D3D_FEATURE_LEVEL_9_2,
|
||||
D3D_FEATURE_LEVEL_9_1,
|
||||
};
|
||||
|
||||
UINT featLevelCount = 0;
|
||||
for (; featLevelCount < _countof(s_featureLevels); ++featLevelCount)
|
||||
{
|
||||
if (s_featureLevels[featLevelCount] < m_d3dMinFeatureLevel)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!featLevelCount)
|
||||
{
|
||||
throw std::out_of_range("minFeatureLevel too high");
|
||||
}
|
||||
|
||||
ComPtr<IDXGIAdapter1> adapter;
|
||||
GetHardwareAdapter(adapter.GetAddressOf());
|
||||
|
||||
// Create the Direct3D 11 API device object and a corresponding context.
|
||||
ComPtr<ID3D11Device> device;
|
||||
ComPtr<ID3D11DeviceContext> context;
|
||||
|
||||
HRESULT hr = E_FAIL;
|
||||
if (adapter)
|
||||
{
|
||||
hr = D3D11CreateDevice(
|
||||
adapter.Get(),
|
||||
D3D_DRIVER_TYPE_UNKNOWN,
|
||||
0,
|
||||
creationFlags, // Set debug and Direct2D compatibility flags.
|
||||
s_featureLevels,
|
||||
featLevelCount,
|
||||
D3D11_SDK_VERSION,
|
||||
device.GetAddressOf(), // Returns the Direct3D device created.
|
||||
&m_d3dFeatureLevel, // Returns feature level of device created.
|
||||
context.GetAddressOf() // Returns the device immediate context.
|
||||
);
|
||||
}
|
||||
#if defined(NDEBUG)
|
||||
else
|
||||
{
|
||||
throw std::exception("No Direct3D hardware device found");
|
||||
}
|
||||
#else
|
||||
if (FAILED(hr))
|
||||
{
|
||||
// If the initialization fails, fall back to the WARP device.
|
||||
// For more information on WARP, see:
|
||||
// http://go.microsoft.com/fwlink/?LinkId=286690
|
||||
hr = D3D11CreateDevice(
|
||||
nullptr,
|
||||
D3D_DRIVER_TYPE_WARP, // Create a WARP device instead of a hardware device.
|
||||
0,
|
||||
creationFlags,
|
||||
s_featureLevels,
|
||||
featLevelCount,
|
||||
D3D11_SDK_VERSION,
|
||||
device.GetAddressOf(),
|
||||
&m_d3dFeatureLevel,
|
||||
context.GetAddressOf()
|
||||
);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
OutputDebugStringA("Direct3D Adapter - WARP\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ThrowIfFailed(hr);
|
||||
|
||||
#ifndef NDEBUG
|
||||
ComPtr<ID3D11Debug> d3dDebug;
|
||||
if (SUCCEEDED(device.As(&d3dDebug)))
|
||||
{
|
||||
ComPtr<ID3D11InfoQueue> d3dInfoQueue;
|
||||
if (SUCCEEDED(d3dDebug.As(&d3dInfoQueue)))
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
d3dInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, true);
|
||||
d3dInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, true);
|
||||
#endif
|
||||
D3D11_MESSAGE_ID hide[] =
|
||||
{
|
||||
D3D11_MESSAGE_ID_SETPRIVATEDATA_CHANGINGPARAMS,
|
||||
};
|
||||
D3D11_INFO_QUEUE_FILTER filter = {};
|
||||
filter.DenyList.NumIDs = _countof(hide);
|
||||
filter.DenyList.pIDList = hide;
|
||||
d3dInfoQueue->AddStorageFilterEntries(&filter);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ThrowIfFailed(device.As(&m_d3dDevice));
|
||||
ThrowIfFailed(context.As(&m_d3dContext));
|
||||
}
|
||||
|
||||
// These resources need to be recreated every time the window size is changed.
|
||||
void DeviceResources::CreateWindowSizeDependentResources()
|
||||
{
|
||||
if (!m_window)
|
||||
{
|
||||
throw std::exception("Call SetWindow with a valid CoreWindow pointer");
|
||||
}
|
||||
|
||||
// Clear the previous window size specific context.
|
||||
ID3D11RenderTargetView* nullViews[] = {nullptr};
|
||||
m_d3dContext->OMSetRenderTargets(_countof(nullViews), nullViews, nullptr);
|
||||
m_d3dRenderTargetView.Reset();
|
||||
m_d3dDepthStencilView.Reset();
|
||||
m_renderTarget.Reset();
|
||||
m_depthStencil.Reset();
|
||||
m_d3dContext->Flush();
|
||||
|
||||
// Determine the render target size in pixels.
|
||||
UINT backBufferWidth = std::max<UINT>(m_outputSize.right - m_outputSize.left, 1);
|
||||
UINT backBufferHeight = std::max<UINT>(m_outputSize.bottom - m_outputSize.top, 1);
|
||||
DXGI_FORMAT backBufferFormat = NoSRGB(m_backBufferFormat);
|
||||
|
||||
if (m_swapChain)
|
||||
{
|
||||
// If the swap chain already exists, resize it.
|
||||
HRESULT hr = m_swapChain->ResizeBuffers(
|
||||
m_backBufferCount,
|
||||
backBufferWidth,
|
||||
backBufferHeight,
|
||||
backBufferFormat,
|
||||
(m_options & c_AllowTearing) ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0
|
||||
);
|
||||
|
||||
if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
char buff[64] = {};
|
||||
sprintf_s(buff, "Device Lost on ResizeBuffers: Reason code 0x%08X\n", (hr == DXGI_ERROR_DEVICE_REMOVED) ? m_d3dDevice->GetDeviceRemovedReason() : hr);
|
||||
OutputDebugStringA(buff);
|
||||
#endif
|
||||
// If the device was removed for any reason, a new device and swap chain will need to be created.
|
||||
HandleDeviceLost();
|
||||
|
||||
// Everything is set up now. Do not continue execution of this method. HandleDeviceLost will reenter this method
|
||||
// and correctly set up the new device.
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
ThrowIfFailed(hr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create a descriptor for the swap chain.
|
||||
DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
|
||||
swapChainDesc.Width = backBufferWidth;
|
||||
swapChainDesc.Height = backBufferHeight;
|
||||
swapChainDesc.Format = backBufferFormat;
|
||||
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
swapChainDesc.BufferCount = m_backBufferCount;
|
||||
swapChainDesc.SampleDesc.Count = 1;
|
||||
swapChainDesc.SampleDesc.Quality = 0;
|
||||
swapChainDesc.Scaling = DXGI_SCALING_ASPECT_RATIO_STRETCH;
|
||||
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||
swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
|
||||
swapChainDesc.Flags = (m_options & c_AllowTearing) ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0;
|
||||
|
||||
// Create a swap chain for the window.
|
||||
ComPtr<IDXGISwapChain1> swapChain;
|
||||
ThrowIfFailed(m_dxgiFactory->CreateSwapChainForCoreWindow(
|
||||
m_d3dDevice.Get(),
|
||||
m_window,
|
||||
&swapChainDesc,
|
||||
nullptr,
|
||||
swapChain.GetAddressOf()
|
||||
));
|
||||
|
||||
ThrowIfFailed(swapChain.As(&m_swapChain));
|
||||
|
||||
// Ensure that DXGI does not queue more than one frame at a time. This both reduces latency and
|
||||
// ensures that the application will only render after each VSync, minimizing power consumption.
|
||||
ComPtr<IDXGIDevice3> dxgiDevice;
|
||||
ThrowIfFailed(m_d3dDevice.As(&dxgiDevice));
|
||||
ThrowIfFailed(dxgiDevice->SetMaximumFrameLatency(1));
|
||||
}
|
||||
|
||||
// Handle color space settings for HDR
|
||||
UpdateColorSpace();
|
||||
|
||||
// Set the proper orientation for the swap chain, and generate
|
||||
// matrix transformations for rendering to the rotated swap chain.
|
||||
switch (m_rotation)
|
||||
{
|
||||
default:
|
||||
case DXGI_MODE_ROTATION_IDENTITY:
|
||||
m_orientationTransform3D = ScreenRotation::Rotation0;
|
||||
break;
|
||||
|
||||
case DXGI_MODE_ROTATION_ROTATE90:
|
||||
m_orientationTransform3D = ScreenRotation::Rotation270;
|
||||
break;
|
||||
|
||||
case DXGI_MODE_ROTATION_ROTATE180:
|
||||
m_orientationTransform3D = ScreenRotation::Rotation180;
|
||||
break;
|
||||
|
||||
case DXGI_MODE_ROTATION_ROTATE270:
|
||||
m_orientationTransform3D = ScreenRotation::Rotation90;
|
||||
break;
|
||||
}
|
||||
|
||||
ThrowIfFailed(m_swapChain->SetRotation(m_rotation));
|
||||
|
||||
// Create a render target view of the swap chain back buffer.
|
||||
ThrowIfFailed(m_swapChain->GetBuffer(0, IID_PPV_ARGS(m_renderTarget.ReleaseAndGetAddressOf())));
|
||||
|
||||
CD3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc(D3D11_RTV_DIMENSION_TEXTURE2D, m_backBufferFormat);
|
||||
ThrowIfFailed(m_d3dDevice->CreateRenderTargetView(
|
||||
m_renderTarget.Get(),
|
||||
&renderTargetViewDesc,
|
||||
m_d3dRenderTargetView.ReleaseAndGetAddressOf()
|
||||
));
|
||||
|
||||
if (m_depthBufferFormat != DXGI_FORMAT_UNKNOWN)
|
||||
{
|
||||
// Create a depth stencil view for use with 3D rendering if needed.
|
||||
CD3D11_TEXTURE2D_DESC depthStencilDesc(
|
||||
m_depthBufferFormat,
|
||||
backBufferWidth,
|
||||
backBufferHeight,
|
||||
1, // This depth stencil view has only one texture.
|
||||
1, // Use a single mipmap level.
|
||||
D3D11_BIND_DEPTH_STENCIL
|
||||
);
|
||||
|
||||
ThrowIfFailed(m_d3dDevice->CreateTexture2D(
|
||||
&depthStencilDesc,
|
||||
nullptr,
|
||||
m_depthStencil.ReleaseAndGetAddressOf()
|
||||
));
|
||||
|
||||
CD3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc(D3D11_DSV_DIMENSION_TEXTURE2D);
|
||||
ThrowIfFailed(m_d3dDevice->CreateDepthStencilView(
|
||||
m_depthStencil.Get(),
|
||||
&depthStencilViewDesc,
|
||||
m_d3dDepthStencilView.ReleaseAndGetAddressOf()
|
||||
));
|
||||
}
|
||||
|
||||
// Set the 3D rendering viewport to target the entire window.
|
||||
m_screenViewport = CD3D11_VIEWPORT(
|
||||
0.0f,
|
||||
0.0f,
|
||||
static_cast<float>(backBufferWidth),
|
||||
static_cast<float>(backBufferHeight)
|
||||
);
|
||||
}
|
||||
|
||||
// This method is called when the CoreWindow is created (or re-created).
|
||||
void DeviceResources::SetWindow(IUnknown* window, int width, int height, DXGI_MODE_ROTATION rotation)
|
||||
{
|
||||
m_window = window;
|
||||
|
||||
m_outputSize.left = m_outputSize.top = 0;
|
||||
m_outputSize.right = width;
|
||||
m_outputSize.bottom = height;
|
||||
|
||||
m_rotation = rotation;
|
||||
}
|
||||
|
||||
// This method is called when the window changes size
|
||||
bool DeviceResources::WindowSizeChanged(int width, int height, DXGI_MODE_ROTATION rotation)
|
||||
{
|
||||
RECT newRc;
|
||||
newRc.left = newRc.top = 0;
|
||||
newRc.right = width;
|
||||
newRc.bottom = height;
|
||||
if (newRc == m_outputSize && rotation == m_rotation)
|
||||
{
|
||||
// Handle color space settings for HDR
|
||||
UpdateColorSpace();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
m_outputSize = newRc;
|
||||
m_rotation = rotation;
|
||||
CreateWindowSizeDependentResources();
|
||||
return true;
|
||||
}
|
||||
|
||||
// This method is called in the event handler for the DisplayContentsInvalidated event.
|
||||
void DeviceResources::ValidateDevice()
|
||||
{
|
||||
// The D3D Device is no longer valid if the default adapter changed since the device
|
||||
// was created or if the device has been removed.
|
||||
|
||||
DXGI_ADAPTER_DESC previousDesc;
|
||||
{
|
||||
ComPtr<IDXGIAdapter1> previousDefaultAdapter;
|
||||
ThrowIfFailed(m_dxgiFactory->EnumAdapters1(0, previousDefaultAdapter.GetAddressOf()));
|
||||
|
||||
ThrowIfFailed(previousDefaultAdapter->GetDesc(&previousDesc));
|
||||
}
|
||||
|
||||
DXGI_ADAPTER_DESC currentDesc;
|
||||
{
|
||||
ComPtr<IDXGIFactory2> currentFactory;
|
||||
ThrowIfFailed(CreateDXGIFactory2(m_dxgiFactoryFlags, IID_PPV_ARGS(currentFactory.GetAddressOf())));
|
||||
|
||||
ComPtr<IDXGIAdapter1> currentDefaultAdapter;
|
||||
ThrowIfFailed(currentFactory->EnumAdapters1(0, currentDefaultAdapter.GetAddressOf()));
|
||||
|
||||
ThrowIfFailed(currentDefaultAdapter->GetDesc(¤tDesc));
|
||||
}
|
||||
|
||||
// If the adapter LUIDs don't match, or if the device reports that it has been removed,
|
||||
// a new D3D device must be created.
|
||||
|
||||
if (previousDesc.AdapterLuid.LowPart != currentDesc.AdapterLuid.LowPart
|
||||
|| previousDesc.AdapterLuid.HighPart != currentDesc.AdapterLuid.HighPart
|
||||
|| FAILED(m_d3dDevice->GetDeviceRemovedReason()))
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
OutputDebugStringA("Device Lost on ValidateDevice\n");
|
||||
#endif
|
||||
|
||||
// Create a new device and swap chain.
|
||||
HandleDeviceLost();
|
||||
}
|
||||
}
|
||||
|
||||
// Recreate all device resources and set them back to the current state.
|
||||
void DeviceResources::HandleDeviceLost()
|
||||
{
|
||||
if (m_deviceNotify)
|
||||
{
|
||||
m_deviceNotify->OnDeviceLost();
|
||||
}
|
||||
|
||||
m_d3dDepthStencilView.Reset();
|
||||
m_d3dRenderTargetView.Reset();
|
||||
m_renderTarget.Reset();
|
||||
m_depthStencil.Reset();
|
||||
m_swapChain.Reset();
|
||||
m_d3dContext.Reset();
|
||||
m_d3dDevice.Reset();
|
||||
m_dxgiFactory.Reset();
|
||||
|
||||
#ifdef _DEBUG
|
||||
{
|
||||
ComPtr<IDXGIDebug1> dxgiDebug;
|
||||
if (SUCCEEDED(DXGIGetDebugInterface1(0, IID_PPV_ARGS(&dxgiDebug))))
|
||||
{
|
||||
dxgiDebug->ReportLiveObjects(DXGI_DEBUG_ALL, DXGI_DEBUG_RLO_FLAGS(DXGI_DEBUG_RLO_SUMMARY | DXGI_DEBUG_RLO_IGNORE_INTERNAL));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
CreateDeviceResources();
|
||||
CreateWindowSizeDependentResources();
|
||||
|
||||
if (m_deviceNotify)
|
||||
{
|
||||
m_deviceNotify->OnDeviceRestored();
|
||||
}
|
||||
}
|
||||
|
||||
// Call this method when the app suspends. It provides a hint to the driver that the app
|
||||
// is entering an idle state and that temporary buffers can be reclaimed for use by other apps.
|
||||
void DeviceResources::Trim()
|
||||
{
|
||||
ComPtr<IDXGIDevice3> dxgiDevice;
|
||||
if (SUCCEEDED(m_d3dDevice.As(&dxgiDevice)))
|
||||
{
|
||||
dxgiDevice->Trim();
|
||||
}
|
||||
}
|
||||
|
||||
// Present the contents of the swap chain to the screen.
|
||||
void DeviceResources::Present()
|
||||
{
|
||||
HRESULT hr;
|
||||
if (m_options & c_AllowTearing)
|
||||
{
|
||||
// Recommended to always use tearing if supported when using a sync interval of 0.
|
||||
hr = m_swapChain->Present(0, DXGI_PRESENT_ALLOW_TEARING);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The first argument instructs DXGI to block until VSync, putting the application
|
||||
// to sleep until the next VSync. This ensures we don't waste any cycles rendering
|
||||
// frames that will never be displayed to the screen.
|
||||
hr = m_swapChain->Present(1, 0);
|
||||
}
|
||||
|
||||
// Discard the contents of the render target.
|
||||
// This is a valid operation only when the existing contents will be entirely
|
||||
// overwritten. If dirty or scroll rects are used, this call should be removed.
|
||||
m_d3dContext->DiscardView(m_d3dRenderTargetView.Get());
|
||||
|
||||
if (m_d3dDepthStencilView)
|
||||
{
|
||||
// Discard the contents of the depth stencil.
|
||||
m_d3dContext->DiscardView(m_d3dDepthStencilView.Get());
|
||||
}
|
||||
|
||||
// If the device was removed either by a disconnection or a driver upgrade, we
|
||||
// must recreate all device resources.
|
||||
if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
char buff[64] = {};
|
||||
sprintf_s(buff, "Device Lost on Present: Reason code 0x%08X\n", (hr == DXGI_ERROR_DEVICE_REMOVED) ? m_d3dDevice->GetDeviceRemovedReason() : hr);
|
||||
OutputDebugStringA(buff);
|
||||
#endif
|
||||
HandleDeviceLost();
|
||||
}
|
||||
else
|
||||
{
|
||||
ThrowIfFailed(hr);
|
||||
|
||||
if (!m_dxgiFactory->IsCurrent())
|
||||
{
|
||||
// Output information is cached on the DXGI Factory. If it is stale we need to create a new factory.
|
||||
ThrowIfFailed(CreateDXGIFactory2(m_dxgiFactoryFlags, IID_PPV_ARGS(m_dxgiFactory.ReleaseAndGetAddressOf())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This method acquires the first available hardware adapter.
|
||||
// If no such adapter can be found, *ppAdapter will be set to nullptr.
|
||||
void DeviceResources::GetHardwareAdapter(IDXGIAdapter1** ppAdapter)
|
||||
{
|
||||
*ppAdapter = nullptr;
|
||||
|
||||
ComPtr<IDXGIAdapter1> adapter;
|
||||
for (UINT adapterIndex = 0; DXGI_ERROR_NOT_FOUND != m_dxgiFactory->EnumAdapters1(adapterIndex, adapter.ReleaseAndGetAddressOf()); adapterIndex++)
|
||||
{
|
||||
DXGI_ADAPTER_DESC1 desc;
|
||||
adapter->GetDesc1(&desc);
|
||||
|
||||
if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)
|
||||
{
|
||||
// Don't select the Basic Render Driver adapter.
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
wchar_t buff[256] = {};
|
||||
swprintf_s(buff, L"Direct3D Adapter (%u): VID:%04X, PID:%04X - %ls\n", adapterIndex, desc.VendorId, desc.DeviceId, desc.Description);
|
||||
OutputDebugStringW(buff);
|
||||
#endif
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
*ppAdapter = adapter.Detach();
|
||||
}
|
||||
|
||||
// Sets the color space for the swap chain in order to handle HDR output.
|
||||
void DeviceResources::UpdateColorSpace()
|
||||
{
|
||||
DXGI_COLOR_SPACE_TYPE colorSpace = DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
|
||||
|
||||
bool isdisplayhdr10 = false;
|
||||
|
||||
#if defined(NTDDI_WIN10_RS2)
|
||||
if (m_swapChain)
|
||||
{
|
||||
ComPtr<IDXGIOutput> output;
|
||||
if (SUCCEEDED(m_swapChain->GetContainingOutput(output.GetAddressOf())))
|
||||
{
|
||||
ComPtr<IDXGIOutput6> output6;
|
||||
if (SUCCEEDED(output.As(&output6)))
|
||||
{
|
||||
DXGI_OUTPUT_DESC1 desc;
|
||||
ThrowIfFailed(output6->GetDesc1(&desc));
|
||||
|
||||
if (desc.ColorSpace == DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020)
|
||||
{
|
||||
// Display output is HDR10.
|
||||
isdisplayhdr10 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((m_options & c_EnableHDR) && isdisplayhdr10)
|
||||
{
|
||||
switch (m_backBufferFormat)
|
||||
{
|
||||
case DXGI_FORMAT_R10G10B10A2_UNORM:
|
||||
// The application creates the HDR10 signal.
|
||||
colorSpace = DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020;
|
||||
break;
|
||||
|
||||
case DXGI_FORMAT_R16G16B16A16_FLOAT:
|
||||
// The system creates the HDR10 signal; application uses linear values.
|
||||
colorSpace = DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_colorSpace = colorSpace;
|
||||
|
||||
UINT colorSpaceSupport = 0;
|
||||
if (SUCCEEDED(m_swapChain->CheckColorSpaceSupport(colorSpace, &colorSpaceSupport))
|
||||
&& (colorSpaceSupport & DXGI_SWAP_CHAIN_COLOR_SPACE_SUPPORT_FLAG_PRESENT))
|
||||
{
|
||||
ThrowIfFailed(m_swapChain->SetColorSpace1(colorSpace));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
//
|
||||
// DeviceResources.h - A wrapper for the Direct3D 11 device and swapchain
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace DX
|
||||
{
|
||||
// Provides an interface for an application that owns DeviceResources to be notified of the device being lost or created.
|
||||
interface IDeviceNotify
|
||||
{
|
||||
virtual void OnDeviceLost() = 0;
|
||||
virtual void OnDeviceRestored() = 0;
|
||||
};
|
||||
|
||||
// Controls all the DirectX device resources.
|
||||
class DeviceResources
|
||||
{
|
||||
public:
|
||||
static const unsigned int c_AllowTearing = 0x1;
|
||||
static const unsigned int c_EnableHDR = 0x2;
|
||||
|
||||
DeviceResources(DXGI_FORMAT backBufferFormat = DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||
DXGI_FORMAT depthBufferFormat = DXGI_FORMAT_D24_UNORM_S8_UINT,
|
||||
UINT backBufferCount = 2,
|
||||
D3D_FEATURE_LEVEL minFeatureLevel = D3D_FEATURE_LEVEL_9_3,
|
||||
unsigned int flags = 0);
|
||||
|
||||
void CreateDeviceResources();
|
||||
void CreateWindowSizeDependentResources();
|
||||
void SetWindow(IUnknown* window, int width, int height, DXGI_MODE_ROTATION rotation);
|
||||
bool WindowSizeChanged(int width, int height, DXGI_MODE_ROTATION rotation);
|
||||
void ValidateDevice();
|
||||
void HandleDeviceLost();
|
||||
void RegisterDeviceNotify(IDeviceNotify* deviceNotify) { m_deviceNotify = deviceNotify; }
|
||||
void Trim();
|
||||
void Present();
|
||||
|
||||
// Device Accessors.
|
||||
RECT GetOutputSize() const { return m_outputSize; }
|
||||
DXGI_MODE_ROTATION GetRotation() const { return m_rotation; }
|
||||
|
||||
// Direct3D Accessors.
|
||||
ID3D11Device2* GetD3DDevice() const { return m_d3dDevice.Get(); }
|
||||
ID3D11DeviceContext2* GetD3DDeviceContext() const { return m_d3dContext.Get(); }
|
||||
IDXGISwapChain3* GetSwapChain() const { return m_swapChain.Get(); }
|
||||
D3D_FEATURE_LEVEL GetDeviceFeatureLevel() const { return m_d3dFeatureLevel; }
|
||||
ID3D11Texture2D* GetRenderTarget() const { return m_renderTarget.Get(); }
|
||||
ID3D11Texture2D* GetDepthStencil() const { return m_depthStencil.Get(); }
|
||||
ID3D11RenderTargetView* GetRenderTargetView() const { return m_d3dRenderTargetView.Get(); }
|
||||
ID3D11DepthStencilView* GetDepthStencilView() const { return m_d3dDepthStencilView.Get(); }
|
||||
DXGI_FORMAT GetBackBufferFormat() const { return m_backBufferFormat; }
|
||||
DXGI_FORMAT GetDepthBufferFormat() const { return m_depthBufferFormat; }
|
||||
D3D11_VIEWPORT GetScreenViewport() const { return m_screenViewport; }
|
||||
UINT GetBackBufferCount() const { return m_backBufferCount; }
|
||||
DirectX::XMFLOAT4X4 GetOrientationTransform3D() const { return m_orientationTransform3D; }
|
||||
DXGI_COLOR_SPACE_TYPE GetColorSpace() const { return m_colorSpace; }
|
||||
unsigned int GetDeviceOptions() const { return m_options; }
|
||||
|
||||
private:
|
||||
void GetHardwareAdapter(IDXGIAdapter1** ppAdapter);
|
||||
void UpdateColorSpace();
|
||||
|
||||
// Direct3D objects.
|
||||
Microsoft::WRL::ComPtr<IDXGIFactory2> m_dxgiFactory;
|
||||
Microsoft::WRL::ComPtr<ID3D11Device3> m_d3dDevice;
|
||||
Microsoft::WRL::ComPtr<ID3D11DeviceContext2> m_d3dContext;
|
||||
Microsoft::WRL::ComPtr<IDXGISwapChain3> m_swapChain;
|
||||
|
||||
// Direct3D rendering objects. Required for 3D.
|
||||
Microsoft::WRL::ComPtr<ID3D11Texture2D> m_renderTarget;
|
||||
Microsoft::WRL::ComPtr<ID3D11Texture2D> m_depthStencil;
|
||||
Microsoft::WRL::ComPtr<ID3D11RenderTargetView> m_d3dRenderTargetView;
|
||||
Microsoft::WRL::ComPtr<ID3D11DepthStencilView> m_d3dDepthStencilView;
|
||||
D3D11_VIEWPORT m_screenViewport;
|
||||
|
||||
// Direct3D properties.
|
||||
DXGI_FORMAT m_backBufferFormat;
|
||||
DXGI_FORMAT m_depthBufferFormat;
|
||||
UINT m_backBufferCount;
|
||||
D3D_FEATURE_LEVEL m_d3dMinFeatureLevel;
|
||||
|
||||
// Cached device properties.
|
||||
IUnknown* m_window;
|
||||
D3D_FEATURE_LEVEL m_d3dFeatureLevel;
|
||||
DXGI_MODE_ROTATION m_rotation;
|
||||
DWORD m_dxgiFactoryFlags;
|
||||
RECT m_outputSize;
|
||||
|
||||
// Transforms used for display orientation.
|
||||
DirectX::XMFLOAT4X4 m_orientationTransform3D;
|
||||
|
||||
// HDR Support
|
||||
DXGI_COLOR_SPACE_TYPE m_colorSpace;
|
||||
|
||||
// DeviceResources options (see flags above)
|
||||
unsigned int m_options;
|
||||
|
||||
// The IDeviceNotify can be held directly as it owns the DeviceResources.
|
||||
IDeviceNotify* m_deviceNotify;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,431 @@
|
|||
//--------------------------------------------------------------------------------------
|
||||
// Main.cpp
|
||||
//
|
||||
// Entry point for Universal Windows Platform (UWP) app.
|
||||
//
|
||||
// Advanced Technology Group (ATG)
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
#include "pch.h"
|
||||
#include "SimpleComputeUWP.h"
|
||||
|
||||
#include "Telemetry.h"
|
||||
|
||||
#include <ppltasks.h>
|
||||
|
||||
using namespace concurrency;
|
||||
using namespace Windows::ApplicationModel;
|
||||
using namespace Windows::ApplicationModel::Core;
|
||||
using namespace Windows::ApplicationModel::Activation;
|
||||
using namespace Windows::UI::Core;
|
||||
using namespace Windows::UI::Input;
|
||||
using namespace Windows::UI::ViewManagement;
|
||||
using namespace Windows::System;
|
||||
using namespace Windows::Foundation;
|
||||
using namespace Windows::Graphics::Display;
|
||||
using namespace DirectX;
|
||||
|
||||
ref class ViewProvider sealed : public IFrameworkView
|
||||
{
|
||||
public:
|
||||
ViewProvider() :
|
||||
m_exit(false),
|
||||
m_visible(true),
|
||||
m_in_sizemove(false),
|
||||
m_DPI(96.f),
|
||||
m_logicalWidth(800.f),
|
||||
m_logicalHeight(600.f),
|
||||
m_nativeOrientation(DisplayOrientations::None),
|
||||
m_currentOrientation(DisplayOrientations::None)
|
||||
{
|
||||
}
|
||||
|
||||
// IFrameworkView methods
|
||||
virtual void Initialize(CoreApplicationView^ applicationView)
|
||||
{
|
||||
applicationView->Activated +=
|
||||
ref new TypedEventHandler<CoreApplicationView^, IActivatedEventArgs^>(this, &ViewProvider::OnActivated);
|
||||
|
||||
CoreApplication::Suspending +=
|
||||
ref new EventHandler<SuspendingEventArgs^>(this, &ViewProvider::OnSuspending);
|
||||
|
||||
CoreApplication::Resuming +=
|
||||
ref new EventHandler<Platform::Object^>(this, &ViewProvider::OnResuming);
|
||||
|
||||
m_sample = std::make_unique<Sample>();
|
||||
|
||||
// Sample Usage Telemetry
|
||||
//
|
||||
// Disable or remove this code block to opt-out of sample usage telemetry
|
||||
//
|
||||
if (ATG::EventRegisterATGSampleTelemetry() == ERROR_SUCCESS)
|
||||
{
|
||||
wchar_t exeName[MAX_PATH + 1] = {};
|
||||
if (!GetModuleFileNameW(nullptr, exeName, MAX_PATH))
|
||||
{
|
||||
wcscpy_s(exeName, L"Unknown");
|
||||
}
|
||||
wchar_t fname[_MAX_FNAME] = {};
|
||||
wchar_t ext[_MAX_EXT] = {};
|
||||
(void)_wsplitpath_s(exeName, nullptr, 0, nullptr, 0, fname, _MAX_FNAME, ext, _MAX_EXT);
|
||||
(void)_wmakepath_s(exeName, nullptr, nullptr, fname, ext); // keep only the filename + extension
|
||||
|
||||
ATG::EventWriteSampleLoaded(exeName);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void Uninitialize()
|
||||
{
|
||||
m_sample.reset();
|
||||
}
|
||||
|
||||
virtual void SetWindow(CoreWindow^ window)
|
||||
{
|
||||
window->SizeChanged +=
|
||||
ref new TypedEventHandler<CoreWindow^, WindowSizeChangedEventArgs^>(this, &ViewProvider::OnWindowSizeChanged);
|
||||
|
||||
#if defined(NTDDI_WIN10_RS2) && (NTDDI_VERSION >= NTDDI_WIN10_RS2)
|
||||
try
|
||||
{
|
||||
window->ResizeStarted +=
|
||||
ref new TypedEventHandler<CoreWindow^, Object^>(this, &ViewProvider::OnResizeStarted);
|
||||
|
||||
window->ResizeCompleted +=
|
||||
ref new TypedEventHandler<CoreWindow^, Object^>(this, &ViewProvider::OnResizeCompleted);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// Requires Windows 10 Creators Update (10.0.15063) or later
|
||||
}
|
||||
#endif
|
||||
|
||||
window->VisibilityChanged +=
|
||||
ref new TypedEventHandler<CoreWindow^, VisibilityChangedEventArgs^>(this, &ViewProvider::OnVisibilityChanged);
|
||||
|
||||
window->Closed +=
|
||||
ref new TypedEventHandler<CoreWindow^, CoreWindowEventArgs^>(this, &ViewProvider::OnWindowClosed);
|
||||
|
||||
auto dispatcher = CoreWindow::GetForCurrentThread()->Dispatcher;
|
||||
|
||||
dispatcher->AcceleratorKeyActivated +=
|
||||
ref new TypedEventHandler<CoreDispatcher^, AcceleratorKeyEventArgs^>(this, &ViewProvider::OnAcceleratorKeyActivated);
|
||||
|
||||
auto currentDisplayInformation = DisplayInformation::GetForCurrentView();
|
||||
|
||||
currentDisplayInformation->DpiChanged +=
|
||||
ref new TypedEventHandler<DisplayInformation^, Object^>(this, &ViewProvider::OnDpiChanged);
|
||||
|
||||
currentDisplayInformation->OrientationChanged +=
|
||||
ref new TypedEventHandler<DisplayInformation^, Object^>(this, &ViewProvider::OnOrientationChanged);
|
||||
|
||||
DisplayInformation::DisplayContentsInvalidated +=
|
||||
ref new TypedEventHandler<DisplayInformation^, Object^>(this, &ViewProvider::OnDisplayContentsInvalidated);
|
||||
|
||||
m_DPI = currentDisplayInformation->LogicalDpi;
|
||||
|
||||
m_logicalWidth = window->Bounds.Width;
|
||||
m_logicalHeight = window->Bounds.Height;
|
||||
|
||||
m_nativeOrientation = currentDisplayInformation->NativeOrientation;
|
||||
m_currentOrientation = currentDisplayInformation->CurrentOrientation;
|
||||
|
||||
int outputWidth = ConvertDipsToPixels(m_logicalWidth);
|
||||
int outputHeight = ConvertDipsToPixels(m_logicalHeight);
|
||||
|
||||
DXGI_MODE_ROTATION rotation = ComputeDisplayRotation();
|
||||
|
||||
if (rotation == DXGI_MODE_ROTATION_ROTATE90 || rotation == DXGI_MODE_ROTATION_ROTATE270)
|
||||
{
|
||||
std::swap(outputWidth, outputHeight);
|
||||
}
|
||||
|
||||
m_sample->Initialize(reinterpret_cast<IUnknown*>(window),
|
||||
outputWidth, outputHeight, rotation );
|
||||
|
||||
Mouse::SetDpi(m_DPI);
|
||||
}
|
||||
|
||||
virtual void Load(Platform::String^ entryPoint)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void Run()
|
||||
{
|
||||
while (!m_exit)
|
||||
{
|
||||
if (m_visible)
|
||||
{
|
||||
m_sample->Tick();
|
||||
|
||||
CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
|
||||
}
|
||||
else
|
||||
{
|
||||
CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
// Event handlers
|
||||
void OnActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args)
|
||||
{
|
||||
if (args->Kind == ActivationKind::Launch)
|
||||
{
|
||||
auto launchArgs = static_cast<LaunchActivatedEventArgs^>(args);
|
||||
|
||||
if (launchArgs->PrelaunchActivated)
|
||||
{
|
||||
// Opt-out of Prelaunch
|
||||
CoreApplication::Exit();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int w, h;
|
||||
m_sample->GetDefaultSize(w, h);
|
||||
|
||||
m_DPI = DisplayInformation::GetForCurrentView()->LogicalDpi;
|
||||
|
||||
ApplicationView::PreferredLaunchWindowingMode = ApplicationViewWindowingMode::PreferredLaunchViewSize;
|
||||
// Change to ApplicationViewWindowingMode::FullScreen to default to full screen
|
||||
|
||||
auto desiredSize = Size(ConvertPixelsToDips(w), ConvertPixelsToDips(h));
|
||||
|
||||
ApplicationView::PreferredLaunchViewSize = desiredSize;
|
||||
|
||||
auto view = ApplicationView::GetForCurrentView();
|
||||
|
||||
auto minSize = Size(ConvertPixelsToDips(320), ConvertPixelsToDips(200));
|
||||
|
||||
view->SetPreferredMinSize(minSize);
|
||||
|
||||
CoreWindow::GetForCurrentThread()->Activate();
|
||||
|
||||
view->FullScreenSystemOverlayMode = FullScreenSystemOverlayMode::Minimal;
|
||||
|
||||
view->TryResizeView(desiredSize);
|
||||
}
|
||||
|
||||
void OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ args)
|
||||
{
|
||||
auto deferral = args->SuspendingOperation->GetDeferral();
|
||||
|
||||
create_task([this, deferral]()
|
||||
{
|
||||
m_sample->OnSuspending();
|
||||
|
||||
deferral->Complete();
|
||||
});
|
||||
}
|
||||
|
||||
void OnResuming(Platform::Object^ sender, Platform::Object^ args)
|
||||
{
|
||||
m_sample->OnResuming();
|
||||
}
|
||||
|
||||
void OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args)
|
||||
{
|
||||
m_logicalWidth = sender->Bounds.Width;
|
||||
m_logicalHeight = sender->Bounds.Height;
|
||||
|
||||
if (m_in_sizemove)
|
||||
return;
|
||||
|
||||
HandleWindowSizeChanged();
|
||||
}
|
||||
|
||||
#if defined(NTDDI_WIN10_RS2) && (NTDDI_VERSION >= NTDDI_WIN10_RS2)
|
||||
void OnResizeStarted(CoreWindow^ sender, Platform::Object^ args)
|
||||
{
|
||||
m_in_sizemove = true;
|
||||
}
|
||||
|
||||
void OnResizeCompleted(CoreWindow^ sender, Platform::Object^ args)
|
||||
{
|
||||
m_in_sizemove = false;
|
||||
|
||||
HandleWindowSizeChanged();
|
||||
}
|
||||
#endif
|
||||
|
||||
void OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args)
|
||||
{
|
||||
m_visible = args->Visible;
|
||||
if (m_visible)
|
||||
m_sample->OnActivated();
|
||||
else
|
||||
m_sample->OnDeactivated();
|
||||
}
|
||||
|
||||
void OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args)
|
||||
{
|
||||
m_exit = true;
|
||||
}
|
||||
|
||||
void OnAcceleratorKeyActivated(CoreDispatcher^, AcceleratorKeyEventArgs^ args)
|
||||
{
|
||||
if (args->EventType == CoreAcceleratorKeyEventType::SystemKeyDown
|
||||
&& args->VirtualKey == VirtualKey::Enter
|
||||
&& args->KeyStatus.IsMenuKeyDown
|
||||
&& !args->KeyStatus.WasKeyDown)
|
||||
{
|
||||
// Implements the classic ALT+ENTER fullscreen toggle
|
||||
auto view = ApplicationView::GetForCurrentView();
|
||||
|
||||
if (view->IsFullScreenMode)
|
||||
view->ExitFullScreenMode();
|
||||
else
|
||||
view->TryEnterFullScreenMode();
|
||||
|
||||
args->Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
void OnDpiChanged(DisplayInformation^ sender, Object^ args)
|
||||
{
|
||||
m_DPI = sender->LogicalDpi;
|
||||
|
||||
HandleWindowSizeChanged();
|
||||
|
||||
Mouse::SetDpi(m_DPI);
|
||||
}
|
||||
|
||||
void OnOrientationChanged(DisplayInformation^ sender, Object^ args)
|
||||
{
|
||||
auto resizeManager = CoreWindowResizeManager::GetForCurrentView();
|
||||
resizeManager->ShouldWaitForLayoutCompletion = true;
|
||||
|
||||
m_currentOrientation = sender->CurrentOrientation;
|
||||
|
||||
HandleWindowSizeChanged();
|
||||
|
||||
resizeManager->NotifyLayoutCompleted();
|
||||
}
|
||||
|
||||
void OnDisplayContentsInvalidated(DisplayInformation^ sender, Object^ args)
|
||||
{
|
||||
m_sample->ValidateDevice();
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_exit;
|
||||
bool m_visible;
|
||||
bool m_in_sizemove;
|
||||
float m_DPI;
|
||||
float m_logicalWidth;
|
||||
float m_logicalHeight;
|
||||
std::unique_ptr<Sample> m_sample;
|
||||
|
||||
Windows::Graphics::Display::DisplayOrientations m_nativeOrientation;
|
||||
Windows::Graphics::Display::DisplayOrientations m_currentOrientation;
|
||||
|
||||
inline int ConvertDipsToPixels(float dips) const
|
||||
{
|
||||
return int(dips * m_DPI / 96.f + 0.5f);
|
||||
}
|
||||
|
||||
inline float ConvertPixelsToDips(int pixels) const
|
||||
{
|
||||
return (float(pixels) * 96.f / m_DPI);
|
||||
}
|
||||
|
||||
DXGI_MODE_ROTATION ComputeDisplayRotation() const
|
||||
{
|
||||
DXGI_MODE_ROTATION rotation = DXGI_MODE_ROTATION_UNSPECIFIED;
|
||||
|
||||
switch (m_nativeOrientation)
|
||||
{
|
||||
case DisplayOrientations::Landscape:
|
||||
switch (m_currentOrientation)
|
||||
{
|
||||
case DisplayOrientations::Landscape:
|
||||
rotation = DXGI_MODE_ROTATION_IDENTITY;
|
||||
break;
|
||||
|
||||
case DisplayOrientations::Portrait:
|
||||
rotation = DXGI_MODE_ROTATION_ROTATE270;
|
||||
break;
|
||||
|
||||
case DisplayOrientations::LandscapeFlipped:
|
||||
rotation = DXGI_MODE_ROTATION_ROTATE180;
|
||||
break;
|
||||
|
||||
case DisplayOrientations::PortraitFlipped:
|
||||
rotation = DXGI_MODE_ROTATION_ROTATE90;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case DisplayOrientations::Portrait:
|
||||
switch (m_currentOrientation)
|
||||
{
|
||||
case DisplayOrientations::Landscape:
|
||||
rotation = DXGI_MODE_ROTATION_ROTATE90;
|
||||
break;
|
||||
|
||||
case DisplayOrientations::Portrait:
|
||||
rotation = DXGI_MODE_ROTATION_IDENTITY;
|
||||
break;
|
||||
|
||||
case DisplayOrientations::LandscapeFlipped:
|
||||
rotation = DXGI_MODE_ROTATION_ROTATE270;
|
||||
break;
|
||||
|
||||
case DisplayOrientations::PortraitFlipped:
|
||||
rotation = DXGI_MODE_ROTATION_ROTATE180;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return rotation;
|
||||
}
|
||||
|
||||
void HandleWindowSizeChanged()
|
||||
{
|
||||
int outputWidth = ConvertDipsToPixels(m_logicalWidth);
|
||||
int outputHeight = ConvertDipsToPixels(m_logicalHeight);
|
||||
|
||||
DXGI_MODE_ROTATION rotation = ComputeDisplayRotation();
|
||||
|
||||
if (rotation == DXGI_MODE_ROTATION_ROTATE90 || rotation == DXGI_MODE_ROTATION_ROTATE270)
|
||||
{
|
||||
std::swap(outputWidth, outputHeight);
|
||||
}
|
||||
|
||||
m_sample->OnWindowSizeChanged(outputWidth, outputHeight, rotation);
|
||||
}
|
||||
};
|
||||
|
||||
ref class ViewProviderFactory : IFrameworkViewSource
|
||||
{
|
||||
public:
|
||||
virtual IFrameworkView^ CreateView()
|
||||
{
|
||||
return ref new ViewProvider();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Entry point
|
||||
[Platform::MTAThread]
|
||||
int __cdecl main(Platform::Array<Platform::String^>^ /*argv*/)
|
||||
{
|
||||
if (!XMVerifyCPUSupport())
|
||||
{
|
||||
throw std::exception("XMVerifyCPUSupport");
|
||||
}
|
||||
|
||||
auto viewProviderFactory = ref new ViewProviderFactory();
|
||||
CoreApplication::Run(viewProviderFactory);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Exit helper
|
||||
void ExitSample()
|
||||
{
|
||||
Windows::ApplicationModel::Core::CoreApplication::Exit();
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<Package
|
||||
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
|
||||
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
|
||||
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
|
||||
IgnorableNamespaces="uap mp">
|
||||
|
||||
<Identity
|
||||
Name="b7152606-a365-4e23-8a5b-b10091654435"
|
||||
Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US"
|
||||
Version="1.0.0.0" />
|
||||
|
||||
<mp:PhoneIdentity PhoneProductId="b7152606-a365-4e23-8a5b-b10091654435" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
|
||||
|
||||
<Properties>
|
||||
<DisplayName>SimpleComputeUWP</DisplayName>
|
||||
<PublisherDisplayName>Xbox Advanced Technology Group</PublisherDisplayName>
|
||||
<Logo>Assets\StoreLogo.png</Logo>
|
||||
</Properties>
|
||||
|
||||
<Dependencies>
|
||||
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
|
||||
</Dependencies>
|
||||
|
||||
<Resources>
|
||||
<Resource Language="x-generate"/>
|
||||
</Resources>
|
||||
|
||||
<Applications>
|
||||
<Application Id="App"
|
||||
Executable="$targetnametoken$.exe"
|
||||
EntryPoint="SimpleComputeUWP.App">
|
||||
<uap:VisualElements
|
||||
DisplayName="SimpleComputeUWP"
|
||||
Square150x150Logo="Assets\Logo.png"
|
||||
Square44x44Logo="Assets\SmallLogo.png"
|
||||
Description="SimpleComputeUWP"
|
||||
BackgroundColor="transparent">
|
||||
<uap:DefaultTile Wide310x150Logo="Assets\WideLogo.png"/>
|
||||
<uap:SplashScreen Image="Assets\SplashScreen.png" />
|
||||
</uap:VisualElements>
|
||||
</Application>
|
||||
</Applications>
|
||||
|
||||
<Capabilities>
|
||||
<Capability Name="internetClient" />
|
||||
</Capabilities>
|
||||
</Package>
|
|
@ -0,0 +1,458 @@
|
|||
//--------------------------------------------------------------------------------------
|
||||
// SimpleComputeUWP.cpp
|
||||
//
|
||||
// Advanced Technology Group (ATG)
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
#include "pch.h"
|
||||
#include "SimpleComputeUWP.h"
|
||||
|
||||
#include "ATGColors.h"
|
||||
#include "ControllerFont.h"
|
||||
#include "ReadData.h"
|
||||
|
||||
extern void ExitSample();
|
||||
|
||||
using namespace DirectX;
|
||||
|
||||
using Microsoft::WRL::ComPtr;
|
||||
|
||||
namespace
|
||||
{
|
||||
const uint32_t s_numShaderThreads = 8; // make sure to update value in shader if this changes
|
||||
|
||||
const wchar_t* g_SampleTitle = L"SimpleCompute";
|
||||
const wchar_t* g_SampleDescription = L"Demonstrates how to use DirectCompute";
|
||||
const ATG::HelpButtonAssignment g_HelpButtons[] = {
|
||||
{ ATG::HelpID::MENU_BUTTON, L"Show/Hide Help" },
|
||||
{ ATG::HelpID::VIEW_BUTTON, L"Exit" },
|
||||
{ ATG::HelpID::LEFT_STICK, L"Pan Viewport" },
|
||||
{ ATG::HelpID::RIGHT_STICK, L"Zoom Viewport" },
|
||||
{ ATG::HelpID::RIGHT_TRIGGER, L"Increase Zoom Speed" },
|
||||
{ ATG::HelpID::Y_BUTTON, L"Reset Viewport to Default" },
|
||||
};
|
||||
}
|
||||
|
||||
Sample::Sample() :
|
||||
m_showHelp(false),
|
||||
m_gamepadPresent(false)
|
||||
{
|
||||
// Renders only 2D, so no need for a depth buffer.
|
||||
m_deviceResources = std::make_unique<DX::DeviceResources>(DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN, 2, D3D_FEATURE_LEVEL_11_0);
|
||||
m_deviceResources->RegisterDeviceNotify(this);
|
||||
|
||||
m_help = std::make_unique<ATG::Help>(g_SampleTitle, g_SampleDescription, g_HelpButtons, _countof(g_HelpButtons));
|
||||
}
|
||||
|
||||
// Initialize the Direct3D resources required to run.
|
||||
void Sample::Initialize(::IUnknown* window, int width, int height, DXGI_MODE_ROTATION rotation)
|
||||
{
|
||||
ResetWindow();
|
||||
|
||||
m_gamePad = std::make_unique<GamePad>();
|
||||
|
||||
m_keyboard = std::make_unique<Keyboard>();
|
||||
m_keyboard->SetWindow(reinterpret_cast<ABI::Windows::UI::Core::ICoreWindow*>(window));
|
||||
|
||||
m_mouse = std::make_unique<Mouse>();
|
||||
m_mouse->SetWindow(reinterpret_cast<ABI::Windows::UI::Core::ICoreWindow*>(window));
|
||||
|
||||
m_deviceResources->SetWindow(window, width, height, rotation);
|
||||
|
||||
m_deviceResources->CreateDeviceResources();
|
||||
CreateDeviceDependentResources();
|
||||
|
||||
m_deviceResources->CreateWindowSizeDependentResources();
|
||||
CreateWindowSizeDependentResources();
|
||||
}
|
||||
|
||||
#pragma region Frame Update
|
||||
// Executes basic render loop.
|
||||
void Sample::Tick()
|
||||
{
|
||||
m_timer.Tick([&]()
|
||||
{
|
||||
Update(m_timer);
|
||||
});
|
||||
|
||||
Render();
|
||||
}
|
||||
|
||||
// Updates the world.
|
||||
void Sample::Update(DX::StepTimer const& timer)
|
||||
{
|
||||
PIXBeginEvent(PIX_COLOR_DEFAULT, L"Update");
|
||||
|
||||
float elapsedTime = float(timer.GetElapsedSeconds());
|
||||
|
||||
m_renderFPS.Tick(elapsedTime);
|
||||
|
||||
auto pad = m_gamePad->GetState(0);
|
||||
m_gamepadPresent = pad.IsConnected();
|
||||
if (m_gamepadPresent)
|
||||
{
|
||||
m_gamePadButtons.Update(pad);
|
||||
|
||||
if (m_gamePadButtons.menu == GamePad::ButtonStateTracker::PRESSED)
|
||||
{
|
||||
m_showHelp = !m_showHelp;
|
||||
}
|
||||
else if (m_showHelp && m_gamePadButtons.b == GamePad::ButtonStateTracker::PRESSED)
|
||||
{
|
||||
m_showHelp = false;
|
||||
}
|
||||
|
||||
if (!m_showHelp)
|
||||
{
|
||||
if (pad.IsViewPressed())
|
||||
{
|
||||
ExitSample();
|
||||
}
|
||||
|
||||
const float ThumbLeftX = pad.thumbSticks.leftX;
|
||||
const float ThumbLeftY = pad.thumbSticks.leftY;
|
||||
const float ThumbRightY = pad.thumbSticks.rightY;
|
||||
const float RightTrigger = m_gamePadButtons.rightTrigger == DirectX::GamePad::ButtonStateTracker::HELD;
|
||||
|
||||
if (m_gamePadButtons.y == DirectX::GamePad::ButtonStateTracker::PRESSED)
|
||||
{
|
||||
ResetWindow();
|
||||
}
|
||||
|
||||
if (ThumbLeftX != 0.0f || ThumbLeftY != 0.0f || ThumbRightY != 0.0f)
|
||||
{
|
||||
const float ScaleSpeed = 1.0f + RightTrigger * 4.0f;
|
||||
const float WindowScale = 1.0f + ThumbRightY * -0.25f * ScaleSpeed * elapsedTime;
|
||||
m_window.x *= WindowScale;
|
||||
m_window.y *= WindowScale;
|
||||
m_window.z += m_window.x * ThumbLeftX * elapsedTime * 0.5f;
|
||||
m_window.w += m_window.y * ThumbLeftY * elapsedTime * 0.5f;
|
||||
m_windowUpdated = true;
|
||||
}
|
||||
|
||||
m_windowUpdated = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_gamePadButtons.Reset();
|
||||
}
|
||||
|
||||
auto kb = m_keyboard->GetState();
|
||||
m_keyboardButtons.Update(kb);
|
||||
|
||||
if (m_keyboardButtons.IsKeyPressed(Keyboard::F1))
|
||||
{
|
||||
m_showHelp = !m_showHelp;
|
||||
}
|
||||
else if (m_showHelp && kb.Escape)
|
||||
{
|
||||
m_showHelp = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_keyboardButtons.IsKeyPressed(Keyboard::Escape))
|
||||
{
|
||||
ExitSample();
|
||||
}
|
||||
|
||||
if (m_keyboardButtons.IsKeyPressed(Keyboard::Home))
|
||||
{
|
||||
ResetWindow();
|
||||
}
|
||||
|
||||
if (kb.W || kb.S || kb.A || kb.D || kb.PageUp || kb.PageDown)
|
||||
{
|
||||
const float ScaleSpeed = (kb.LeftShift || kb.RightShift) ? 4.f : 1.f;
|
||||
|
||||
float zoom = kb.PageDown ? 1.f : (kb.PageUp ? -1.f : 0.f);
|
||||
float x = kb.D ? 1.f : (kb.A ? -1.f : 0.f);
|
||||
float y = kb.W ? 1.f : (kb.S ? -1.f : 0.f);
|
||||
|
||||
const float WindowScale = 1.0f + zoom * ScaleSpeed * elapsedTime;
|
||||
m_window.x *= WindowScale;
|
||||
m_window.y *= WindowScale;
|
||||
m_window.z += m_window.x * x * elapsedTime * 0.5f;
|
||||
m_window.w += m_window.y * y * elapsedTime * 0.5f;
|
||||
m_windowUpdated = true;
|
||||
}
|
||||
}
|
||||
|
||||
PIXEndEvent();
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Frame Render
|
||||
// Draws the scene.
|
||||
void Sample::Render()
|
||||
{
|
||||
// Don't try to render anything before the first Update.
|
||||
if (m_timer.GetFrameCount() == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Clear();
|
||||
|
||||
auto context = m_deviceResources->GetD3DDeviceContext();
|
||||
|
||||
if (m_showHelp)
|
||||
{
|
||||
m_help->Render();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Flip colors for which async compute buffer is being rendered
|
||||
PIXBeginEvent(context, PIX_COLOR_DEFAULT, L"Render");
|
||||
|
||||
UpdateFractalData();
|
||||
|
||||
context->CSSetConstantBuffers(0, 1, m_cbFractal.GetAddressOf());
|
||||
context->CSSetShaderResources(0, 1, m_fractalColorMapSRV.GetAddressOf());
|
||||
context->CSSetSamplers(0, 1, m_fractalBilinearSampler.GetAddressOf());
|
||||
context->CSSetShader(m_csFractal.Get(), nullptr, 0);
|
||||
context->CSSetUnorderedAccessViews(0, 1, m_fractalUAV.GetAddressOf(), nullptr);
|
||||
|
||||
D3D11_TEXTURE2D_DESC texDesc = {};
|
||||
m_fractalTexture->GetDesc(&texDesc);
|
||||
|
||||
const uint32_t threadGroupX = texDesc.Width / s_numShaderThreads;
|
||||
const uint32_t threadGroupY = texDesc.Height / s_numShaderThreads;
|
||||
context->Dispatch(threadGroupX, threadGroupY, 1);
|
||||
|
||||
ID3D11UnorderedAccessView* nulluav[] = { nullptr };
|
||||
context->CSSetUnorderedAccessViews(0, 1, nulluav, nullptr);
|
||||
|
||||
RECT outputSize = m_deviceResources->GetOutputSize();
|
||||
|
||||
RECT safeRect = SimpleMath::Viewport::ComputeTitleSafeArea(outputSize.right, outputSize.bottom);
|
||||
XMFLOAT2 pos(float(safeRect.left), float(safeRect.top));
|
||||
|
||||
m_spriteBatch->Begin();
|
||||
m_spriteBatch->Draw(m_fractalSRV.Get(), outputSize);
|
||||
|
||||
wchar_t outputString[256] = {};
|
||||
swprintf_s(outputString, 256, L"Simple Compute Context %0.2f fps", m_renderFPS.GetFPS());
|
||||
|
||||
m_font->DrawString(m_spriteBatch.get(), outputString, pos);
|
||||
pos.y += m_font->GetLineSpacing();
|
||||
|
||||
swprintf_s(outputString, 256, L"Synchronous compute %0.2f fps", m_renderFPS.GetFPS());
|
||||
m_font->DrawString(m_spriteBatch.get(), outputString, pos);
|
||||
|
||||
const wchar_t* legend = m_gamepadPresent
|
||||
? L"[View] Exit [Menu] Help"
|
||||
: L"WASD: Pan viewport PageUp/Down: Zoom viewport Esc: Exit";
|
||||
|
||||
DX::DrawControllerString(m_spriteBatch.get(), m_font.get(), m_ctrlFont.get(),
|
||||
legend,
|
||||
XMFLOAT2(float(safeRect.left), float(safeRect.bottom) - m_font->GetLineSpacing()));
|
||||
|
||||
m_spriteBatch->End();
|
||||
|
||||
PIXEndEvent(context);
|
||||
}
|
||||
|
||||
// Show the new frame.
|
||||
PIXBeginEvent(PIX_COLOR_DEFAULT, L"Present");
|
||||
m_deviceResources->Present();
|
||||
PIXEndEvent();
|
||||
}
|
||||
|
||||
// Helper method to clear the back buffers.
|
||||
void Sample::Clear()
|
||||
{
|
||||
auto context = m_deviceResources->GetD3DDeviceContext();
|
||||
PIXBeginEvent(context, PIX_COLOR_DEFAULT, L"Clear");
|
||||
|
||||
// Clear the views.
|
||||
auto renderTarget = m_deviceResources->GetRenderTargetView();
|
||||
|
||||
context->ClearRenderTargetView(renderTarget, ATG::Colors::Background);
|
||||
|
||||
context->OMSetRenderTargets(1, &renderTarget, nullptr);
|
||||
|
||||
// Set the viewport.
|
||||
auto viewport = m_deviceResources->GetScreenViewport();
|
||||
context->RSSetViewports(1, &viewport);
|
||||
|
||||
PIXEndEvent(context);
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Message Handlers
|
||||
// Message handlers
|
||||
void Sample::OnActivated()
|
||||
{
|
||||
}
|
||||
|
||||
void Sample::OnDeactivated()
|
||||
{
|
||||
}
|
||||
|
||||
void Sample::OnSuspending()
|
||||
{
|
||||
auto context = m_deviceResources->GetD3DDeviceContext();
|
||||
context->ClearState();
|
||||
|
||||
m_deviceResources->Trim();
|
||||
}
|
||||
|
||||
void Sample::OnResuming()
|
||||
{
|
||||
m_timer.ResetElapsedTime();
|
||||
m_gamePadButtons.Reset();
|
||||
m_keyboardButtons.Reset();
|
||||
}
|
||||
|
||||
void Sample::OnWindowSizeChanged(int width, int height, DXGI_MODE_ROTATION rotation)
|
||||
{
|
||||
if (!m_deviceResources->WindowSizeChanged(width, height, rotation))
|
||||
return;
|
||||
|
||||
CreateWindowSizeDependentResources();
|
||||
}
|
||||
|
||||
void Sample::ValidateDevice()
|
||||
{
|
||||
m_deviceResources->ValidateDevice();
|
||||
}
|
||||
|
||||
// Properties
|
||||
void Sample::GetDefaultSize(int& width, int& height) const
|
||||
{
|
||||
width = 1280;
|
||||
height = 720;
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Direct3D Resources
|
||||
// These are the resources that depend on the device.
|
||||
void Sample::CreateDeviceDependentResources()
|
||||
{
|
||||
auto device = m_deviceResources->GetD3DDevice();
|
||||
auto context = m_deviceResources->GetD3DDeviceContext();
|
||||
|
||||
auto blob = DX::ReadData(L"Fractal.cso");
|
||||
DX::ThrowIfFailed(
|
||||
device->CreateComputeShader(blob.data(), blob.size(), nullptr, m_csFractal.ReleaseAndGetAddressOf()));
|
||||
|
||||
RECT outputSize = m_deviceResources->GetOutputSize();
|
||||
CD3D11_TEXTURE2D_DESC TexDesc(
|
||||
DXGI_FORMAT_R32G32B32A32_FLOAT,
|
||||
outputSize.right,
|
||||
outputSize.bottom,
|
||||
1,
|
||||
1,
|
||||
D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE
|
||||
);
|
||||
|
||||
DX::ThrowIfFailed(
|
||||
device->CreateTexture2D(&TexDesc, nullptr, m_fractalTexture.ReleaseAndGetAddressOf()));
|
||||
|
||||
DX::ThrowIfFailed(
|
||||
device->CreateShaderResourceView(m_fractalTexture.Get(), nullptr, m_fractalSRV.ReleaseAndGetAddressOf()));
|
||||
|
||||
CD3D11_UNORDERED_ACCESS_VIEW_DESC UAVDesc(D3D11_UAV_DIMENSION_TEXTURE2D, TexDesc.Format);
|
||||
DX::ThrowIfFailed(
|
||||
device->CreateUnorderedAccessView(m_fractalTexture.Get(), &UAVDesc, m_fractalUAV.ReleaseAndGetAddressOf()));
|
||||
|
||||
CD3D11_BUFFER_DESC CBDesc(sizeof(CB_FractalCS), D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
||||
DX::ThrowIfFailed(
|
||||
device->CreateBuffer(&CBDesc, nullptr, m_cbFractal.ReleaseAndGetAddressOf()));
|
||||
|
||||
TexDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
TexDesc.Width = 8;
|
||||
TexDesc.Height = 1;
|
||||
TexDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
|
||||
const uint32_t GradientTexels[8] = { 0xFF000040, 0xFF000080, 0xFF0000C0, 0xFF0000FF, 0xFF0040FF, 0xFF0080FF, 0xFF00C0FF, 0xFF00FFFF };
|
||||
|
||||
D3D11_SUBRESOURCE_DATA InitData = {};
|
||||
InitData.SysMemPitch = sizeof(GradientTexels);
|
||||
InitData.pSysMem = GradientTexels;
|
||||
DX::ThrowIfFailed(
|
||||
device->CreateTexture2D(&TexDesc, &InitData, m_fractalColorMap.ReleaseAndGetAddressOf()));
|
||||
|
||||
DX::ThrowIfFailed(
|
||||
device->CreateShaderResourceView(m_fractalColorMap.Get(), nullptr, m_fractalColorMapSRV.ReleaseAndGetAddressOf()));
|
||||
|
||||
CD3D11_SAMPLER_DESC SamplerDesc(D3D11_DEFAULT);
|
||||
SamplerDesc.Filter = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT;
|
||||
DX::ThrowIfFailed(
|
||||
device->CreateSamplerState(&SamplerDesc, m_fractalBilinearSampler.ReleaseAndGetAddressOf()));
|
||||
|
||||
m_fractalMaxIterations = 300;
|
||||
|
||||
m_spriteBatch = std::make_unique<SpriteBatch>(context);
|
||||
m_font = std::make_unique<SpriteFont>(device, L"SegoeUI_18.spritefont");
|
||||
m_ctrlFont = std::make_unique<SpriteFont>(device, L"XboxOneControllerLegendSmall.spritefont");
|
||||
m_help->RestoreDevice(context);
|
||||
}
|
||||
|
||||
// Allocate all memory resources that change on a window SizeChanged event.
|
||||
void Sample::CreateWindowSizeDependentResources()
|
||||
{
|
||||
auto size = m_deviceResources->GetOutputSize();
|
||||
m_help->SetWindow(size);
|
||||
|
||||
m_spriteBatch->SetViewport(m_deviceResources->GetScreenViewport());
|
||||
}
|
||||
|
||||
void Sample::OnDeviceLost()
|
||||
{
|
||||
m_cbFractal.Reset();
|
||||
m_csFractal.Reset();
|
||||
m_fractalTexture.Reset();
|
||||
m_fractalUAV.Reset();
|
||||
m_fractalSRV.Reset();
|
||||
m_fractalColorMap.Reset();
|
||||
m_fractalColorMapSRV.Reset();
|
||||
m_fractalBilinearSampler.Reset();
|
||||
|
||||
m_spriteBatch.reset();
|
||||
m_font.reset();
|
||||
m_ctrlFont.reset();
|
||||
|
||||
m_help->ReleaseDevice();
|
||||
}
|
||||
|
||||
void Sample::OnDeviceRestored()
|
||||
{
|
||||
CreateDeviceDependentResources();
|
||||
|
||||
CreateWindowSizeDependentResources();
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
void Sample::ResetWindow()
|
||||
{
|
||||
m_window = XMFLOAT4(4.0f, 2.25f, -0.65f, 0.0f);
|
||||
m_windowUpdated = true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Name: UpdateFractalData
|
||||
// Desc: Updates the dynamic constant buffer with fractal data
|
||||
//--------------------------------------------------------------------------------------
|
||||
void Sample::UpdateFractalData()
|
||||
{
|
||||
D3D11_TEXTURE2D_DESC texDesc = {};
|
||||
m_fractalTexture->GetDesc(&texDesc);
|
||||
|
||||
auto context = m_deviceResources->GetD3DDeviceContext();
|
||||
D3D11_MAPPED_SUBRESOURCE mapped;
|
||||
|
||||
DX::ThrowIfFailed(
|
||||
context->Map(m_cbFractal.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped)
|
||||
);
|
||||
|
||||
auto pCBFractalData = reinterpret_cast<CB_FractalCS*> (mapped.pData);
|
||||
|
||||
pCBFractalData->MaxThreadIter = XMFLOAT4(static_cast<float>(texDesc.Width), static_cast<float>(texDesc.Height), static_cast<float>(m_fractalMaxIterations), 0);
|
||||
pCBFractalData->Window = m_window;
|
||||
|
||||
context->Unmap(m_cbFractal.Get(), 0);
|
||||
}
|
||||
|
|
@ -0,0 +1,140 @@
|
|||
//--------------------------------------------------------------------------------------
|
||||
// SimpleComputeUWP.h
|
||||
//
|
||||
// Advanced Technology Group (ATG)
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "DeviceResources.h"
|
||||
#include "StepTimer.h"
|
||||
#include "ControllerHelp.h"
|
||||
|
||||
class SmoothedFPS
|
||||
{
|
||||
public:
|
||||
SmoothedFPS(uint32_t frameInterval = 100)
|
||||
{
|
||||
Initialize(frameInterval);
|
||||
}
|
||||
|
||||
void Initialize(uint32_t frameInterval = 100)
|
||||
{
|
||||
m_frameInterval = frameInterval;
|
||||
m_timeAccumulator = 0.0f;
|
||||
m_frameAccumulator = 0;
|
||||
m_smoothedFPS = 0.0f;
|
||||
}
|
||||
|
||||
void Tick(float DeltaTime)
|
||||
{
|
||||
m_timeAccumulator += DeltaTime;
|
||||
++m_frameAccumulator;
|
||||
|
||||
if (m_frameAccumulator >= m_frameInterval)
|
||||
{
|
||||
m_smoothedFPS = (float)m_frameInterval / m_timeAccumulator;
|
||||
m_timeAccumulator = 0.0f;
|
||||
m_frameAccumulator = 0;
|
||||
}
|
||||
}
|
||||
|
||||
float GetFPS() const { return m_smoothedFPS; }
|
||||
|
||||
private:
|
||||
float m_smoothedFPS;
|
||||
float m_timeAccumulator;
|
||||
uint32_t m_frameAccumulator;
|
||||
uint32_t m_frameInterval;
|
||||
|
||||
};
|
||||
|
||||
|
||||
// A basic sample implementation that creates a D3D11 device and
|
||||
// provides a render loop.
|
||||
class Sample : public DX::IDeviceNotify
|
||||
{
|
||||
public:
|
||||
|
||||
Sample();
|
||||
|
||||
// Initialization and management
|
||||
void Initialize(::IUnknown* window, int width, int height, DXGI_MODE_ROTATION rotation);
|
||||
|
||||
// Basic render loop
|
||||
void Tick();
|
||||
|
||||
// IDeviceNotify
|
||||
virtual void OnDeviceLost() override;
|
||||
virtual void OnDeviceRestored() override;
|
||||
|
||||
// Messages
|
||||
void OnActivated();
|
||||
void OnDeactivated();
|
||||
void OnSuspending();
|
||||
void OnResuming();
|
||||
void OnWindowSizeChanged(int width, int height, DXGI_MODE_ROTATION rotation);
|
||||
void ValidateDevice();
|
||||
|
||||
// Properties
|
||||
void GetDefaultSize( int& width, int& height ) const;
|
||||
|
||||
private:
|
||||
struct CB_FractalCS
|
||||
{
|
||||
DirectX::XMFLOAT4 MaxThreadIter;
|
||||
DirectX::XMFLOAT4 Window;
|
||||
};
|
||||
|
||||
void Update(DX::StepTimer const& timer);
|
||||
void Render();
|
||||
|
||||
void Clear();
|
||||
|
||||
void CreateDeviceDependentResources();
|
||||
void CreateWindowSizeDependentResources();
|
||||
|
||||
void ResetWindow();
|
||||
void UpdateFractalData();
|
||||
|
||||
// Device resources.
|
||||
std::unique_ptr<DX::DeviceResources> m_deviceResources;
|
||||
|
||||
// Rendering loop timer.
|
||||
DX::StepTimer m_timer;
|
||||
|
||||
std::unique_ptr<ATG::Help> m_help;
|
||||
bool m_showHelp;
|
||||
|
||||
// Input devices.
|
||||
std::unique_ptr<DirectX::GamePad> m_gamePad;
|
||||
std::unique_ptr<DirectX::Keyboard> m_keyboard;
|
||||
std::unique_ptr<DirectX::Mouse> m_mouse;
|
||||
|
||||
DirectX::GamePad::ButtonStateTracker m_gamePadButtons;
|
||||
DirectX::Keyboard::KeyboardStateTracker m_keyboardButtons;
|
||||
bool m_gamepadPresent;
|
||||
|
||||
// Compute data
|
||||
SmoothedFPS m_renderFPS;
|
||||
|
||||
uint64_t* m_fractalTimestamps;
|
||||
DirectX::XMFLOAT4 m_window;
|
||||
bool m_windowUpdated;
|
||||
uint32_t m_fractalMaxIterations;
|
||||
|
||||
Microsoft::WRL::ComPtr<ID3D11Buffer> m_cbFractal;
|
||||
Microsoft::WRL::ComPtr<ID3D11ComputeShader> m_csFractal;
|
||||
Microsoft::WRL::ComPtr<ID3D11Texture2D> m_fractalTexture;
|
||||
Microsoft::WRL::ComPtr<ID3D11UnorderedAccessView> m_fractalUAV;
|
||||
Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> m_fractalSRV;
|
||||
Microsoft::WRL::ComPtr<ID3D11Texture2D> m_fractalColorMap;
|
||||
Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> m_fractalColorMapSRV;
|
||||
Microsoft::WRL::ComPtr<ID3D11SamplerState> m_fractalBilinearSampler;
|
||||
|
||||
// DirectXTK objects.
|
||||
std::unique_ptr<DirectX::SpriteBatch> m_spriteBatch;
|
||||
std::unique_ptr<DirectX::SpriteFont> m_font;
|
||||
std::unique_ptr<DirectX::SpriteFont> m_ctrlFont;
|
||||
};
|
|
@ -0,0 +1,57 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26730.3
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SimpleComputeUWP", "SimpleComputeUWP.vcxproj", "{3787F188-97B3-49EA-9243-386C5BDE4D41}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DirectXTK", "..\..\..\Kits\DirectXTK\DirectXTK_Windows10.vcxproj", "{F4776924-619C-42C7-88B2-82C947CCC9E7}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|ARM = Debug|ARM
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|ARM = Release|ARM
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{3787F188-97B3-49EA-9243-386C5BDE4D41}.Debug|ARM.ActiveCfg = Debug|ARM
|
||||
{3787F188-97B3-49EA-9243-386C5BDE4D41}.Debug|ARM.Build.0 = Debug|ARM
|
||||
{3787F188-97B3-49EA-9243-386C5BDE4D41}.Debug|ARM.Deploy.0 = Debug|ARM
|
||||
{3787F188-97B3-49EA-9243-386C5BDE4D41}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{3787F188-97B3-49EA-9243-386C5BDE4D41}.Debug|x64.Build.0 = Debug|x64
|
||||
{3787F188-97B3-49EA-9243-386C5BDE4D41}.Debug|x64.Deploy.0 = Debug|x64
|
||||
{3787F188-97B3-49EA-9243-386C5BDE4D41}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{3787F188-97B3-49EA-9243-386C5BDE4D41}.Debug|x86.Build.0 = Debug|Win32
|
||||
{3787F188-97B3-49EA-9243-386C5BDE4D41}.Debug|x86.Deploy.0 = Debug|Win32
|
||||
{3787F188-97B3-49EA-9243-386C5BDE4D41}.Release|ARM.ActiveCfg = Release|ARM
|
||||
{3787F188-97B3-49EA-9243-386C5BDE4D41}.Release|ARM.Build.0 = Release|ARM
|
||||
{3787F188-97B3-49EA-9243-386C5BDE4D41}.Release|ARM.Deploy.0 = Release|ARM
|
||||
{3787F188-97B3-49EA-9243-386C5BDE4D41}.Release|x64.ActiveCfg = Release|x64
|
||||
{3787F188-97B3-49EA-9243-386C5BDE4D41}.Release|x64.Build.0 = Release|x64
|
||||
{3787F188-97B3-49EA-9243-386C5BDE4D41}.Release|x64.Deploy.0 = Release|x64
|
||||
{3787F188-97B3-49EA-9243-386C5BDE4D41}.Release|x86.ActiveCfg = Release|Win32
|
||||
{3787F188-97B3-49EA-9243-386C5BDE4D41}.Release|x86.Build.0 = Release|Win32
|
||||
{3787F188-97B3-49EA-9243-386C5BDE4D41}.Release|x86.Deploy.0 = Release|Win32
|
||||
{F4776924-619C-42C7-88B2-82C947CCC9E7}.Debug|ARM.ActiveCfg = Debug|ARM
|
||||
{F4776924-619C-42C7-88B2-82C947CCC9E7}.Debug|ARM.Build.0 = Debug|ARM
|
||||
{F4776924-619C-42C7-88B2-82C947CCC9E7}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{F4776924-619C-42C7-88B2-82C947CCC9E7}.Debug|x64.Build.0 = Debug|x64
|
||||
{F4776924-619C-42C7-88B2-82C947CCC9E7}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{F4776924-619C-42C7-88B2-82C947CCC9E7}.Debug|x86.Build.0 = Debug|Win32
|
||||
{F4776924-619C-42C7-88B2-82C947CCC9E7}.Release|ARM.ActiveCfg = Release|ARM
|
||||
{F4776924-619C-42C7-88B2-82C947CCC9E7}.Release|ARM.Build.0 = Release|ARM
|
||||
{F4776924-619C-42C7-88B2-82C947CCC9E7}.Release|x64.ActiveCfg = Release|x64
|
||||
{F4776924-619C-42C7-88B2-82C947CCC9E7}.Release|x64.Build.0 = Release|x64
|
||||
{F4776924-619C-42C7-88B2-82C947CCC9E7}.Release|x86.ActiveCfg = Release|Win32
|
||||
{F4776924-619C-42C7-88B2-82C947CCC9E7}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {59FA58DA-E61A-4C0E-83F5-9C87DDA76612}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,344 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|ARM">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>ARM</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|ARM">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>ARM</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{3787f188-97b3-49ea-9243-386c5bde4d41}</ProjectGuid>
|
||||
<Keyword>DirectXApp</Keyword>
|
||||
<RootNamespace>SimpleComputeUWP</RootNamespace>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
|
||||
<AppContainerApplication>true</AppContainerApplication>
|
||||
<ApplicationType>Windows Store</ApplicationType>
|
||||
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformMinVersion>10.0.14393.0</WindowsTargetPlatformMinVersion>
|
||||
<ApplicationTypeRevision>10.0</ApplicationTypeRevision>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
<Import Project="$(VSINSTALLDIR)\Common7\IDE\Extensions\Microsoft\VsGraphics\ImageContentTask.props" />
|
||||
<Import Project="$(VSINSTALLDIR)\Common7\IDE\Extensions\Microsoft\VsGraphics\MeshContentTask.props" />
|
||||
<Import Project="$(VSINSTALLDIR)\Common7\IDE\Extensions\Microsoft\VsGraphics\ShaderGraphContentTask.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros">
|
||||
<AppxPackageSigningEnabled>false</AppxPackageSigningEnabled>
|
||||
<AppxSymbolPackageEnabled>false</AppxSymbolPackageEnabled>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
|
||||
<Link>
|
||||
<AdditionalDependencies>ATGTelemetryUWP.lib; d2d1.lib; d3d11.lib; dxgi.lib; dxguid.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\..\Kits\Telemetry\$(Platform); %(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\arm; $(VCInstallDir)\lib\arm</AdditionalLibraryDirectories>
|
||||
<GenerateWindowsMetadata>true</GenerateWindowsMetadata>
|
||||
</Link>
|
||||
<ClCompile>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir);$(IntermediateOutputPath);..\..\..\Kits\DirectXTK\Inc;..\..\..\Kits\ATGTK;..\..\..\Kits\Telemetry;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
</ClCompile>
|
||||
<FXCompile>
|
||||
<ShaderModel>4.0_level_9_3</ShaderModel>
|
||||
</FXCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
|
||||
<Link>
|
||||
<AdditionalDependencies>ATGTelemetryUWP.lib; d2d1.lib; d3d11.lib; dxgi.lib; dxguid.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\..\Kits\Telemetry\$(Platform); %(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\arm; $(VCInstallDir)\lib\arm</AdditionalLibraryDirectories>
|
||||
<GenerateWindowsMetadata>true</GenerateWindowsMetadata>
|
||||
</Link>
|
||||
<ClCompile>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir);$(IntermediateOutputPath);..\..\..\Kits\DirectXTK\Inc;..\..\..\Kits\ATGTK;..\..\..\Kits\Telemetry;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
</ClCompile>
|
||||
<FXCompile>
|
||||
<ShaderModel>4.0_level_9_3</ShaderModel>
|
||||
</FXCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Link>
|
||||
<AdditionalDependencies>ATGTelemetryUWP.lib; d2d1.lib; d3d11.lib; dxgi.lib; dxguid.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\..\Kits\Telemetry\$(Platform); %(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store; $(VCInstallDir)\lib</AdditionalLibraryDirectories>
|
||||
<GenerateWindowsMetadata>true</GenerateWindowsMetadata>
|
||||
</Link>
|
||||
<ClCompile>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir);$(IntermediateOutputPath);..\..\..\Kits\DirectXTK\Inc;..\..\..\Kits\ATGTK;..\..\..\Kits\Telemetry;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
|
||||
</ClCompile>
|
||||
<FXCompile>
|
||||
<ShaderModel>4.0_level_9_3</ShaderModel>
|
||||
</FXCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Link>
|
||||
<AdditionalDependencies>ATGTelemetryUWP.lib; d2d1.lib; d3d11.lib; dxgi.lib; dxguid.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\..\Kits\Telemetry\$(Platform); %(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store; $(VCInstallDir)\lib</AdditionalLibraryDirectories>
|
||||
<GenerateWindowsMetadata>true</GenerateWindowsMetadata>
|
||||
</Link>
|
||||
<ClCompile>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir);$(IntermediateOutputPath);..\..\..\Kits\DirectXTK\Inc;..\..\..\Kits\ATGTK;..\..\..\Kits\Telemetry;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
|
||||
</ClCompile>
|
||||
<FXCompile>
|
||||
<ShaderModel>4.0_level_9_3</ShaderModel>
|
||||
</FXCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Link>
|
||||
<AdditionalDependencies>ATGTelemetryUWP.lib; d2d1.lib; d3d11.lib; dxgi.lib; dxguid.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\..\Kits\Telemetry\$(Platform); %(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\amd64; $(VCInstallDir)\lib\amd64</AdditionalLibraryDirectories>
|
||||
<GenerateWindowsMetadata>true</GenerateWindowsMetadata>
|
||||
</Link>
|
||||
<ClCompile>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir);$(IntermediateOutputPath);..\..\..\Kits\DirectXTK\Inc;..\..\..\Kits\ATGTK;..\..\..\Kits\Telemetry;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
</ClCompile>
|
||||
<FXCompile>
|
||||
<ShaderModel>4.0_level_9_3</ShaderModel>
|
||||
</FXCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Link>
|
||||
<AdditionalDependencies>ATGTelemetryUWP.lib; d2d1.lib; d3d11.lib; dxgi.lib; dxguid.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\..\Kits\Telemetry\$(Platform); %(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\amd64; $(VCInstallDir)\lib\amd64</AdditionalLibraryDirectories>
|
||||
<GenerateWindowsMetadata>true</GenerateWindowsMetadata>
|
||||
</Link>
|
||||
<ClCompile>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir);$(IntermediateOutputPath);..\..\..\Kits\DirectXTK\Inc;..\..\..\Kits\ATGTK;..\..\..\Kits\Telemetry;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
</ClCompile>
|
||||
<FXCompile>
|
||||
<ShaderModel>4.0_level_9_3</ShaderModel>
|
||||
</FXCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\Kits\ATGTK\ControllerFont.h" />
|
||||
<ClInclude Include="..\..\..\Kits\ATGTK\ControllerHelp.h" />
|
||||
<ClInclude Include="..\..\..\Kits\ATGTK\ReadData.h" />
|
||||
<ClInclude Include="SimpleComputeUWP.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="StepTimer.h" />
|
||||
<ClInclude Include="DeviceResources.h" />
|
||||
<ClInclude Include="..\..\..\Kits\ATGTK\ATGColors.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\Kits\ATGTK\ControllerHelp.cpp" />
|
||||
<ClCompile Include="SimpleComputeUWP.cpp" />
|
||||
<ClCompile Include="Main.cpp" />
|
||||
<ClCompile Include="DeviceResources.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AppxManifest Include="Package.appxmanifest">
|
||||
<SubType>Designer</SubType>
|
||||
</AppxManifest>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="..\..\..\Media\Textures\ATGSampleBackground.DDS" />
|
||||
<Image Include="..\..\..\Media\Textures\callout_circle.dds" />
|
||||
<Image Include="..\..\..\Media\Textures\gamepad.dds" />
|
||||
<Image Include="Assets\Logo.png" />
|
||||
<Image Include="Assets\SmallLogo.png" />
|
||||
<Image Include="Assets\SplashScreen.png" />
|
||||
<Image Include="Assets\StoreLogo.png" />
|
||||
<Image Include="Assets\WideLogo.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\..\Kits\Telemetry\ARM\ATGTelemetryUWP.dll">
|
||||
<ExcludedFromBuild Condition="'$(Platform)'=='x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Platform)'=='Win32'">true</ExcludedFromBuild>
|
||||
<DeploymentContent Condition="'$(Platform)'=='ARM'">true</DeploymentContent>
|
||||
<Link>ATGTelemetryUWP.dll</Link>
|
||||
</None>
|
||||
<None Include="..\..\..\Kits\Telemetry\Win32\ATGTelemetryUWP.dll">
|
||||
<ExcludedFromBuild Condition="'$(Platform)'=='x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Platform)'=='ARM'">true</ExcludedFromBuild>
|
||||
<DeploymentContent Condition="'$(Platform)'=='Win32'">true</DeploymentContent>
|
||||
<Link>ATGTelemetryUWP.dll</Link>
|
||||
</None>
|
||||
<None Include="..\..\..\Kits\Telemetry\x64\ATGTelemetryUWP.dll">
|
||||
<ExcludedFromBuild Condition="'$(Platform)'=='ARM'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Platform)'=='Win32'">true</ExcludedFromBuild>
|
||||
<DeploymentContent Condition="'$(Platform)'=='x64'">true</DeploymentContent>
|
||||
<Link>ATGTelemetryUWP.dll</Link>
|
||||
</None>
|
||||
<None Include="..\..\..\Media\Fonts\SegoeUI_18.spritefont">
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</DeploymentContent>
|
||||
</None>
|
||||
<None Include="..\..\..\Media\Fonts\SegoeUI_22.spritefont">
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</DeploymentContent>
|
||||
</None>
|
||||
<None Include="..\..\..\Media\Fonts\SegoeUI_36.spritefont">
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</DeploymentContent>
|
||||
</None>
|
||||
<None Include="..\..\..\Media\Fonts\XboxOneControllerLegendSmall.spritefont">
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</DeploymentContent>
|
||||
</None>
|
||||
<None Include="Readme.docx" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Kits\DirectXTK\DirectXTK_Windows10.vcxproj">
|
||||
<Project>{f4776924-619c-42c7-88b2-82c947ccc9e7}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<FxCompile Include="Assets\fractal.hlsl">
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Compute</ShaderType>
|
||||
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">5.0</ShaderModel>
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Compute</ShaderType>
|
||||
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">5.0</ShaderModel>
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">Compute</ShaderType>
|
||||
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">5.0</ShaderModel>
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">Compute</ShaderType>
|
||||
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">5.0</ShaderModel>
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Compute</ShaderType>
|
||||
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">5.0</ShaderModel>
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Compute</ShaderType>
|
||||
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">5.0</ShaderModel>
|
||||
</FxCompile>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="$(VSINSTALLDIR)\Common7\IDE\Extensions\Microsoft\VsGraphics\ImageContentTask.targets" />
|
||||
<Import Project="$(VSINSTALLDIR)\Common7\IDE\Extensions\Microsoft\VsGraphics\MeshContentTask.targets" />
|
||||
<Import Project="$(VSINSTALLDIR)\Common7\IDE\Extensions\Microsoft\VsGraphics\ShaderGraphContentTask.targets" />
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -0,0 +1,118 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Common">
|
||||
<UniqueIdentifier>6fea3680-ba52-4355-86be-176549a3dea7</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Assets">
|
||||
<UniqueIdentifier>172f489e-16be-4ec2-a0ea-a336422c1aa6</UniqueIdentifier>
|
||||
<Extensions>bmp;dds;fbx;gif;jpg;jpeg;tga;tiff;tif;png</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="ATG Tool Kit">
|
||||
<UniqueIdentifier>38e0a3f4-0376-4777-a6ec-10bbd7e8b6fd</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Common\Telemetry">
|
||||
<UniqueIdentifier>0338ee9d-74ba-4824-87ab-e3b7be53e099</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Common\Telemetry\ARM">
|
||||
<UniqueIdentifier>c2dd4733-38fb-42f7-b559-1aec90bbaba4</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Common\Telemetry\Win32">
|
||||
<UniqueIdentifier>3466da97-cd17-49ef-b52e-1b4a7abc7550</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Common\Telemetry\x64">
|
||||
<UniqueIdentifier>b7152606-a365-4e23-8a5b-b10091654435</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="SimpleComputeUWP.h" />
|
||||
<ClInclude Include="StepTimer.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DeviceResources.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\Kits\ATGTK\ATGColors.h">
|
||||
<Filter>ATG Tool Kit</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\Kits\ATGTK\ControllerFont.h">
|
||||
<Filter>ATG Tool Kit</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\Kits\ATGTK\ControllerHelp.h">
|
||||
<Filter>ATG Tool Kit</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\Kits\ATGTK\ReadData.h">
|
||||
<Filter>ATG Tool Kit</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="pch.cpp" />
|
||||
<ClCompile Include="SimpleComputeUWP.cpp" />
|
||||
<ClCompile Include="Main.cpp" />
|
||||
<ClCompile Include="DeviceResources.cpp">
|
||||
<Filter>Common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\Kits\ATGTK\ControllerHelp.cpp">
|
||||
<Filter>ATG Tool Kit</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="Assets\Logo.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\SmallLogo.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\SplashScreen.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\StoreLogo.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\WideLogo.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="..\..\..\Media\Textures\ATGSampleBackground.DDS">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="..\..\..\Media\Textures\callout_circle.dds">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="..\..\..\Media\Textures\gamepad.dds">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\..\Kits\Telemetry\ARM\ATGTelemetryUWP.dll">
|
||||
<Filter>Common\Telemetry\ARM</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\Kits\Telemetry\Win32\ATGTelemetryUWP.dll">
|
||||
<Filter>Common\Telemetry\Win32</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\Kits\Telemetry\x64\ATGTelemetryUWP.dll">
|
||||
<Filter>Common\Telemetry\x64</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\Media\Fonts\SegoeUI_18.spritefont">
|
||||
<Filter>Assets</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\Media\Fonts\SegoeUI_22.spritefont">
|
||||
<Filter>Assets</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\Media\Fonts\SegoeUI_36.spritefont">
|
||||
<Filter>Assets</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\Media\Fonts\XboxOneControllerLegendSmall.spritefont">
|
||||
<Filter>Assets</Filter>
|
||||
</None>
|
||||
<None Include="Readme.docx" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AppxManifest Include="Package.appxmanifest" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<FxCompile Include="Assets\fractal.hlsl">
|
||||
<Filter>Assets</Filter>
|
||||
</FxCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,188 @@
|
|||
//
|
||||
// StepTimer.h - A simple timer that provides elapsed time information
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <exception>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace DX
|
||||
{
|
||||
// Helper class for animation and simulation timing.
|
||||
class StepTimer
|
||||
{
|
||||
public:
|
||||
StepTimer() :
|
||||
m_elapsedTicks(0),
|
||||
m_totalTicks(0),
|
||||
m_leftOverTicks(0),
|
||||
m_frameCount(0),
|
||||
m_framesPerSecond(0),
|
||||
m_framesThisSecond(0),
|
||||
m_qpcSecondCounter(0),
|
||||
m_isFixedTimeStep(false),
|
||||
m_targetElapsedTicks(TicksPerSecond / 60)
|
||||
{
|
||||
if (!QueryPerformanceFrequency(&m_qpcFrequency))
|
||||
{
|
||||
throw std::exception( "QueryPerformanceFrequency" );
|
||||
}
|
||||
|
||||
if (!QueryPerformanceCounter(&m_qpcLastTime))
|
||||
{
|
||||
throw std::exception( "QueryPerformanceCounter" );
|
||||
}
|
||||
|
||||
// Initialize max delta to 1/10 of a second.
|
||||
m_qpcMaxDelta = m_qpcFrequency.QuadPart / 10;
|
||||
}
|
||||
|
||||
// Get elapsed time since the previous Update call.
|
||||
uint64_t GetElapsedTicks() const { return m_elapsedTicks; }
|
||||
double GetElapsedSeconds() const { return TicksToSeconds(m_elapsedTicks); }
|
||||
|
||||
// Get total time since the start of the program.
|
||||
uint64_t GetTotalTicks() const { return m_totalTicks; }
|
||||
double GetTotalSeconds() const { return TicksToSeconds(m_totalTicks); }
|
||||
|
||||
// Get total number of updates since start of the program.
|
||||
uint32_t GetFrameCount() const { return m_frameCount; }
|
||||
|
||||
// Get the current framerate.
|
||||
uint32_t GetFramesPerSecond() const { return m_framesPerSecond; }
|
||||
|
||||
// Set whether to use fixed or variable timestep mode.
|
||||
void SetFixedTimeStep(bool isFixedTimestep) { m_isFixedTimeStep = isFixedTimestep; }
|
||||
|
||||
// Set how often to call Update when in fixed timestep mode.
|
||||
void SetTargetElapsedTicks(uint64_t targetElapsed) { m_targetElapsedTicks = targetElapsed; }
|
||||
void SetTargetElapsedSeconds(double targetElapsed) { m_targetElapsedTicks = SecondsToTicks(targetElapsed); }
|
||||
|
||||
// Integer format represents time using 10,000,000 ticks per second.
|
||||
static const uint64_t TicksPerSecond = 10000000;
|
||||
|
||||
static double TicksToSeconds(uint64_t ticks) { return static_cast<double>(ticks) / TicksPerSecond; }
|
||||
static uint64_t SecondsToTicks(double seconds) { return static_cast<uint64_t>(seconds * TicksPerSecond); }
|
||||
|
||||
// After an intentional timing discontinuity (for instance a blocking IO operation)
|
||||
// call this to avoid having the fixed timestep logic attempt a set of catch-up
|
||||
// Update calls.
|
||||
|
||||
void ResetElapsedTime()
|
||||
{
|
||||
if (!QueryPerformanceCounter(&m_qpcLastTime))
|
||||
{
|
||||
throw std::exception("QueryPerformanceCounter");
|
||||
}
|
||||
|
||||
m_leftOverTicks = 0;
|
||||
m_framesPerSecond = 0;
|
||||
m_framesThisSecond = 0;
|
||||
m_qpcSecondCounter = 0;
|
||||
}
|
||||
|
||||
// Update timer state, calling the specified Update function the appropriate number of times.
|
||||
template<typename TUpdate>
|
||||
void Tick(const TUpdate& update)
|
||||
{
|
||||
// Query the current time.
|
||||
LARGE_INTEGER currentTime;
|
||||
|
||||
if (!QueryPerformanceCounter(¤tTime))
|
||||
{
|
||||
throw std::exception( "QueryPerformanceCounter" );
|
||||
}
|
||||
|
||||
uint64_t timeDelta = currentTime.QuadPart - m_qpcLastTime.QuadPart;
|
||||
|
||||
m_qpcLastTime = currentTime;
|
||||
m_qpcSecondCounter += timeDelta;
|
||||
|
||||
// Clamp excessively large time deltas (e.g. after paused in the debugger).
|
||||
if (timeDelta > m_qpcMaxDelta)
|
||||
{
|
||||
timeDelta = m_qpcMaxDelta;
|
||||
}
|
||||
|
||||
// Convert QPC units into a canonical tick format. This cannot overflow due to the previous clamp.
|
||||
timeDelta *= TicksPerSecond;
|
||||
timeDelta /= m_qpcFrequency.QuadPart;
|
||||
|
||||
uint32_t lastFrameCount = m_frameCount;
|
||||
|
||||
if (m_isFixedTimeStep)
|
||||
{
|
||||
// Fixed timestep update logic
|
||||
|
||||
// If the app is running very close to the target elapsed time (within 1/4 of a millisecond) just clamp
|
||||
// the clock to exactly match the target value. This prevents tiny and irrelevant errors
|
||||
// from accumulating over time. Without this clamping, a game that requested a 60 fps
|
||||
// fixed update, running with vsync enabled on a 59.94 NTSC display, would eventually
|
||||
// accumulate enough tiny errors that it would drop a frame. It is better to just round
|
||||
// small deviations down to zero to leave things running smoothly.
|
||||
|
||||
if (abs(static_cast<int64_t>(timeDelta - m_targetElapsedTicks)) < TicksPerSecond / 4000)
|
||||
{
|
||||
timeDelta = m_targetElapsedTicks;
|
||||
}
|
||||
|
||||
m_leftOverTicks += timeDelta;
|
||||
|
||||
while (m_leftOverTicks >= m_targetElapsedTicks)
|
||||
{
|
||||
m_elapsedTicks = m_targetElapsedTicks;
|
||||
m_totalTicks += m_targetElapsedTicks;
|
||||
m_leftOverTicks -= m_targetElapsedTicks;
|
||||
m_frameCount++;
|
||||
|
||||
update();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Variable timestep update logic.
|
||||
m_elapsedTicks = timeDelta;
|
||||
m_totalTicks += timeDelta;
|
||||
m_leftOverTicks = 0;
|
||||
m_frameCount++;
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
// Track the current framerate.
|
||||
if (m_frameCount != lastFrameCount)
|
||||
{
|
||||
m_framesThisSecond++;
|
||||
}
|
||||
|
||||
if (m_qpcSecondCounter >= static_cast<uint64_t>(m_qpcFrequency.QuadPart))
|
||||
{
|
||||
m_framesPerSecond = m_framesThisSecond;
|
||||
m_framesThisSecond = 0;
|
||||
m_qpcSecondCounter %= m_qpcFrequency.QuadPart;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
// Source timing data uses QPC units.
|
||||
LARGE_INTEGER m_qpcFrequency;
|
||||
LARGE_INTEGER m_qpcLastTime;
|
||||
uint64_t m_qpcMaxDelta;
|
||||
|
||||
// Derived timing data uses a canonical tick format.
|
||||
uint64_t m_elapsedTicks;
|
||||
uint64_t m_totalTicks;
|
||||
uint64_t m_leftOverTicks;
|
||||
|
||||
// Members for tracking the framerate.
|
||||
uint32_t m_frameCount;
|
||||
uint32_t m_framesPerSecond;
|
||||
uint32_t m_framesThisSecond;
|
||||
uint64_t m_qpcSecondCounter;
|
||||
|
||||
// Members for configuring fixed timestep mode.
|
||||
bool m_isFixedTimeStep;
|
||||
uint64_t m_targetElapsedTicks;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
//--------------------------------------------------------------------------------------
|
||||
// pch.cpp
|
||||
//
|
||||
// Include the standard header and generate the precompiled header.
|
||||
//
|
||||
// Advanced Technology Group (ATG)
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
#include "pch.h"
|
|
@ -0,0 +1,77 @@
|
|||
//--------------------------------------------------------------------------------------
|
||||
// pch.h
|
||||
//
|
||||
// Header for standard system include files.
|
||||
//
|
||||
// Advanced Technology Group (ATG)
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
// Use the C++ standard templated min/max
|
||||
#define NOMINMAX
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4467)
|
||||
#include <wrl.h>
|
||||
#pragma warning(pop)
|
||||
|
||||
#include <d3d11_3.h>
|
||||
|
||||
#if defined(NTDDI_WIN10_RS2)
|
||||
#include <dxgi1_6.h>
|
||||
#else
|
||||
#include <dxgi1_5.h>
|
||||
#endif
|
||||
|
||||
#include <DirectXMath.h>
|
||||
#include <DirectXColors.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <exception>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <pix.h>
|
||||
|
||||
#ifdef _DEBUG
|
||||
#include <dxgidebug.h>
|
||||
#endif
|
||||
|
||||
#include "Keyboard.h"
|
||||
#include "GamePad.h"
|
||||
#include "Mouse.h"
|
||||
#include "SimpleMath.h"
|
||||
#include "SpriteBatch.h"
|
||||
#include "SpriteFont.h"
|
||||
|
||||
namespace DX
|
||||
{
|
||||
// Helper class for COM exceptions
|
||||
class com_exception : public std::exception
|
||||
{
|
||||
public:
|
||||
com_exception(HRESULT hr) : result(hr) {}
|
||||
|
||||
virtual const char* what() const override
|
||||
{
|
||||
static char s_str[64] = {};
|
||||
sprintf_s(s_str, "Failure with HRESULT of %08X", static_cast<unsigned int>(result));
|
||||
return s_str;
|
||||
}
|
||||
|
||||
private:
|
||||
HRESULT result;
|
||||
};
|
||||
|
||||
// Helper utility converts D3D API failures into exceptions.
|
||||
inline void ThrowIfFailed(HRESULT hr)
|
||||
{
|
||||
if (FAILED(hr))
|
||||
{
|
||||
throw com_exception(hr);
|
||||
}
|
||||
}
|
||||
}
|
После Ширина: | Высота: | Размер: 39 KiB |
После Ширина: | Высота: | Размер: 23 KiB |
После Ширина: | Высота: | Размер: 26 KiB |
После Ширина: | Высота: | Размер: 24 KiB |
После Ширина: | Высота: | Размер: 45 KiB |
|
@ -0,0 +1,55 @@
|
|||
//--------------------------------------------------------------------------------------
|
||||
// File: fractal.hlsl
|
||||
//
|
||||
// This is a compute shader that draws a Mandelbrot fractal.
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
#define RS\
|
||||
[\
|
||||
RootSignature\
|
||||
(\
|
||||
"CBV(b0, visibility=SHADER_VISIBILITY_ALL),\
|
||||
DescriptorTable(Sampler(s0, numDescriptors=1), visibility=SHADER_VISIBILITY_ALL),\
|
||||
DescriptorTable(SRV(t0, numDescriptors=1), visibility=SHADER_VISIBILITY_ALL),\
|
||||
DescriptorTable(UAV(u0, numDescriptors=1), visibility=SHADER_VISIBILITY_ALL)"\
|
||||
)\
|
||||
]
|
||||
|
||||
RWTexture2D<float4> OutputTexture : register(u0);
|
||||
Texture2D ColorMapTexture : register(t0);
|
||||
SamplerState ColorMapSampler : register(s0);
|
||||
|
||||
cbuffer cb0
|
||||
{
|
||||
float4 g_MaxThreadIter : packoffset(c0);
|
||||
float4 g_Window : packoffset(c1);
|
||||
}
|
||||
|
||||
[numthreads(8, 8, 1)]
|
||||
RS
|
||||
void main(uint3 DTid : SV_DispatchThreadID)
|
||||
{
|
||||
float2 WindowLocal = ((float2)DTid.xy / g_MaxThreadIter.xy) * float2(1, -1) + float2(-0.5f, 0.5f);
|
||||
float2 coord = WindowLocal.xy * g_Window.xy + g_Window.zw;
|
||||
|
||||
uint maxiter = (uint)g_MaxThreadIter.z * 4;
|
||||
uint iter = 0;
|
||||
float2 constant = coord;
|
||||
float2 sq;
|
||||
do
|
||||
{
|
||||
float2 newvalue;
|
||||
sq = coord * coord;
|
||||
newvalue.x = sq.x - sq.y;
|
||||
newvalue.y = 2 * coord.y * coord.x;
|
||||
coord = newvalue + constant;
|
||||
iter++;
|
||||
} while (iter < maxiter && (sq.x + sq.y) < 4.0);
|
||||
|
||||
float colorIndex = frac((float)iter / g_MaxThreadIter.z);
|
||||
float4 SampledColor = ColorMapTexture.SampleLevel(ColorMapSampler, float2(colorIndex, 0), 0);
|
||||
|
||||
OutputTexture[DTid.xy] = SampledColor;
|
||||
}
|
|
@ -0,0 +1,777 @@
|
|||
//
|
||||
// DeviceResources.cpp - A wrapper for the Direct3D 12 device and swapchain
|
||||
//
|
||||
|
||||
#include "pch.h"
|
||||
#include "DeviceResources.h"
|
||||
|
||||
using namespace DirectX;
|
||||
using namespace DX;
|
||||
|
||||
using Microsoft::WRL::ComPtr;
|
||||
|
||||
// Constants used to calculate screen rotations
|
||||
namespace ScreenRotation
|
||||
{
|
||||
// 0-degree Z-rotation
|
||||
static const XMFLOAT4X4 Rotation0(
|
||||
1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
);
|
||||
|
||||
// 90-degree Z-rotation
|
||||
static const XMFLOAT4X4 Rotation90(
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
-1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
);
|
||||
|
||||
// 180-degree Z-rotation
|
||||
static const XMFLOAT4X4 Rotation180(
|
||||
-1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, -1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
);
|
||||
|
||||
// 270-degree Z-rotation
|
||||
static const XMFLOAT4X4 Rotation270(
|
||||
0.0f, -1.0f, 0.0f, 0.0f,
|
||||
1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
);
|
||||
};
|
||||
|
||||
namespace
|
||||
{
|
||||
inline DXGI_FORMAT NoSRGB(DXGI_FORMAT fmt)
|
||||
{
|
||||
switch (fmt)
|
||||
{
|
||||
case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: return DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: return DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: return DXGI_FORMAT_B8G8R8X8_UNORM;
|
||||
default: return fmt;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Constructor for DeviceResources.
|
||||
DeviceResources::DeviceResources(DXGI_FORMAT backBufferFormat, DXGI_FORMAT depthBufferFormat, UINT backBufferCount, D3D_FEATURE_LEVEL minFeatureLevel, unsigned int flags) :
|
||||
m_backBufferIndex(0),
|
||||
m_fenceValues{},
|
||||
m_rtvDescriptorSize(0),
|
||||
m_screenViewport{},
|
||||
m_scissorRect{},
|
||||
m_backBufferFormat(backBufferFormat),
|
||||
m_depthBufferFormat(depthBufferFormat),
|
||||
m_backBufferCount(backBufferCount),
|
||||
m_d3dMinFeatureLevel(minFeatureLevel),
|
||||
m_window(nullptr),
|
||||
m_d3dFeatureLevel(D3D_FEATURE_LEVEL_11_0),
|
||||
m_rotation(DXGI_MODE_ROTATION_IDENTITY),
|
||||
m_dxgiFactoryFlags(0),
|
||||
m_outputSize{0, 0, 1, 1},
|
||||
m_orientationTransform3D(ScreenRotation::Rotation0),
|
||||
m_colorSpace(DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709),
|
||||
m_options(flags),
|
||||
m_deviceNotify(nullptr)
|
||||
{
|
||||
if (backBufferCount > MAX_BACK_BUFFER_COUNT)
|
||||
{
|
||||
throw std::out_of_range("backBufferCount too large");
|
||||
}
|
||||
|
||||
if (minFeatureLevel < D3D_FEATURE_LEVEL_11_0)
|
||||
{
|
||||
throw std::out_of_range("minFeatureLevel too low");
|
||||
}
|
||||
}
|
||||
|
||||
// Destructor for DeviceResources.
|
||||
DeviceResources::~DeviceResources()
|
||||
{
|
||||
// Ensure that the GPU is no longer referencing resources that are about to be destroyed.
|
||||
WaitForGpu();
|
||||
}
|
||||
|
||||
// Configures the Direct3D device, and stores handles to it and the device context.
|
||||
void DeviceResources::CreateDeviceResources()
|
||||
{
|
||||
#if defined(_DEBUG)
|
||||
// Enable the debug layer (requires the Graphics Tools "optional feature").
|
||||
//
|
||||
// NOTE: Enabling the debug layer after device creation will invalidate the active device.
|
||||
{
|
||||
ComPtr<ID3D12Debug> debugController;
|
||||
if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(debugController.GetAddressOf()))))
|
||||
{
|
||||
debugController->EnableDebugLayer();
|
||||
}
|
||||
else
|
||||
{
|
||||
OutputDebugStringA("WARNING: Direct3D Debug Device is not available\n");
|
||||
}
|
||||
|
||||
ComPtr<IDXGIInfoQueue> dxgiInfoQueue;
|
||||
if (SUCCEEDED(DXGIGetDebugInterface1(0, IID_PPV_ARGS(dxgiInfoQueue.GetAddressOf()))))
|
||||
{
|
||||
m_dxgiFactoryFlags = DXGI_CREATE_FACTORY_DEBUG;
|
||||
|
||||
dxgiInfoQueue->SetBreakOnSeverity(DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_ERROR, true);
|
||||
dxgiInfoQueue->SetBreakOnSeverity(DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_CORRUPTION, true);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ThrowIfFailed(CreateDXGIFactory2(m_dxgiFactoryFlags, IID_PPV_ARGS(m_dxgiFactory.ReleaseAndGetAddressOf())));
|
||||
|
||||
// Determines whether tearing support is available for fullscreen borderless windows.
|
||||
if (m_options & c_AllowTearing)
|
||||
{
|
||||
BOOL allowTearing = FALSE;
|
||||
|
||||
ComPtr<IDXGIFactory5> factory5;
|
||||
HRESULT hr = m_dxgiFactory.As(&factory5);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = factory5->CheckFeatureSupport(DXGI_FEATURE_PRESENT_ALLOW_TEARING, &allowTearing, sizeof(allowTearing));
|
||||
}
|
||||
|
||||
if (FAILED(hr) || !allowTearing)
|
||||
{
|
||||
m_options &= ~c_AllowTearing;
|
||||
#ifdef _DEBUG
|
||||
OutputDebugStringA("WARNING: Variable refresh rate displays not supported");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
ComPtr<IDXGIAdapter1> adapter;
|
||||
GetAdapter(adapter.GetAddressOf());
|
||||
|
||||
// Create the DX12 API device object.
|
||||
ThrowIfFailed(D3D12CreateDevice(
|
||||
adapter.Get(),
|
||||
m_d3dMinFeatureLevel,
|
||||
IID_PPV_ARGS(m_d3dDevice.ReleaseAndGetAddressOf())
|
||||
));
|
||||
|
||||
#ifndef NDEBUG
|
||||
// Configure debug device (if active).
|
||||
ComPtr<ID3D12InfoQueue> d3dInfoQueue;
|
||||
if (SUCCEEDED(m_d3dDevice.As(&d3dInfoQueue)))
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
d3dInfoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_CORRUPTION, true);
|
||||
d3dInfoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_ERROR, true);
|
||||
#endif
|
||||
D3D12_MESSAGE_ID hide[] =
|
||||
{
|
||||
D3D12_MESSAGE_ID_MAP_INVALID_NULLRANGE,
|
||||
D3D12_MESSAGE_ID_UNMAP_INVALID_NULLRANGE
|
||||
};
|
||||
D3D12_INFO_QUEUE_FILTER filter = {};
|
||||
filter.DenyList.NumIDs = _countof(hide);
|
||||
filter.DenyList.pIDList = hide;
|
||||
d3dInfoQueue->AddStorageFilterEntries(&filter);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Determine maximum supported feature level for this device
|
||||
static const D3D_FEATURE_LEVEL s_featureLevels[] =
|
||||
{
|
||||
D3D_FEATURE_LEVEL_12_1,
|
||||
D3D_FEATURE_LEVEL_12_0,
|
||||
D3D_FEATURE_LEVEL_11_1,
|
||||
D3D_FEATURE_LEVEL_11_0,
|
||||
};
|
||||
|
||||
D3D12_FEATURE_DATA_FEATURE_LEVELS featLevels =
|
||||
{
|
||||
_countof(s_featureLevels), s_featureLevels, D3D_FEATURE_LEVEL_11_0
|
||||
};
|
||||
|
||||
HRESULT hr = m_d3dDevice->CheckFeatureSupport(D3D12_FEATURE_FEATURE_LEVELS, &featLevels, sizeof(featLevels));
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
m_d3dFeatureLevel = featLevels.MaxSupportedFeatureLevel;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_d3dFeatureLevel = m_d3dMinFeatureLevel;
|
||||
}
|
||||
|
||||
// Create the command queue.
|
||||
D3D12_COMMAND_QUEUE_DESC queueDesc = {};
|
||||
queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
|
||||
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
|
||||
|
||||
ThrowIfFailed(m_d3dDevice->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(m_commandQueue.ReleaseAndGetAddressOf())));
|
||||
|
||||
// Create descriptor heaps for render target views and depth stencil views.
|
||||
D3D12_DESCRIPTOR_HEAP_DESC rtvDescriptorHeapDesc = {};
|
||||
rtvDescriptorHeapDesc.NumDescriptors = m_backBufferCount;
|
||||
rtvDescriptorHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
|
||||
|
||||
ThrowIfFailed(m_d3dDevice->CreateDescriptorHeap(&rtvDescriptorHeapDesc, IID_PPV_ARGS(m_rtvDescriptorHeap.ReleaseAndGetAddressOf())));
|
||||
|
||||
m_rtvDescriptorHeap->SetName(L"DeviceResources");
|
||||
|
||||
m_rtvDescriptorSize = m_d3dDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
|
||||
|
||||
if (m_depthBufferFormat != DXGI_FORMAT_UNKNOWN)
|
||||
{
|
||||
D3D12_DESCRIPTOR_HEAP_DESC dsvDescriptorHeapDesc = {};
|
||||
dsvDescriptorHeapDesc.NumDescriptors = 1;
|
||||
dsvDescriptorHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
|
||||
|
||||
ThrowIfFailed(m_d3dDevice->CreateDescriptorHeap(&dsvDescriptorHeapDesc, IID_PPV_ARGS(m_dsvDescriptorHeap.ReleaseAndGetAddressOf())));
|
||||
|
||||
m_dsvDescriptorHeap->SetName(L"DeviceResources");
|
||||
}
|
||||
|
||||
// Create a command allocator for each back buffer that will be rendered to.
|
||||
for (UINT n = 0; n < m_backBufferCount; n++)
|
||||
{
|
||||
ThrowIfFailed(m_d3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(m_commandAllocators[n].ReleaseAndGetAddressOf())));
|
||||
}
|
||||
|
||||
// Create a command list for recording graphics commands.
|
||||
ThrowIfFailed(m_d3dDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_commandAllocators[0].Get(), nullptr, IID_PPV_ARGS(m_commandList.ReleaseAndGetAddressOf())));
|
||||
ThrowIfFailed(m_commandList->Close());
|
||||
|
||||
// Create a fence for tracking GPU execution progress.
|
||||
ThrowIfFailed(m_d3dDevice->CreateFence(m_fenceValues[m_backBufferIndex], D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(m_fence.ReleaseAndGetAddressOf())));
|
||||
m_fenceValues[m_backBufferIndex]++;
|
||||
|
||||
m_fenceEvent.Attach(CreateEvent(nullptr, FALSE, FALSE, nullptr));
|
||||
if (!m_fenceEvent.IsValid())
|
||||
{
|
||||
throw std::exception("CreateEvent");
|
||||
}
|
||||
}
|
||||
|
||||
// These resources need to be recreated every time the window size is changed.
|
||||
void DeviceResources::CreateWindowSizeDependentResources()
|
||||
{
|
||||
if (!m_window)
|
||||
{
|
||||
throw std::exception("Call SetWindow with a valid CoreWindow pointer");
|
||||
}
|
||||
|
||||
// Wait until all previous GPU work is complete.
|
||||
WaitForGpu();
|
||||
|
||||
// Release resources that are tied to the swap chain and update fence values.
|
||||
for (UINT n = 0; n < m_backBufferCount; n++)
|
||||
{
|
||||
m_renderTargets[n].Reset();
|
||||
m_fenceValues[n] = m_fenceValues[m_backBufferIndex];
|
||||
}
|
||||
|
||||
// Determine the render target size in pixels.
|
||||
UINT backBufferWidth = std::max<UINT>(m_outputSize.right - m_outputSize.left, 1);
|
||||
UINT backBufferHeight = std::max<UINT>(m_outputSize.bottom - m_outputSize.top, 1);
|
||||
DXGI_FORMAT backBufferFormat = NoSRGB(m_backBufferFormat);
|
||||
|
||||
// If the swap chain already exists, resize it, otherwise create one.
|
||||
if (m_swapChain)
|
||||
{
|
||||
// If the swap chain already exists, resize it.
|
||||
HRESULT hr = m_swapChain->ResizeBuffers(
|
||||
m_backBufferCount,
|
||||
backBufferWidth,
|
||||
backBufferHeight,
|
||||
backBufferFormat,
|
||||
(m_options & c_AllowTearing) ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0
|
||||
);
|
||||
|
||||
if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
char buff[64] = {};
|
||||
sprintf_s(buff, "Device Lost on ResizeBuffers: Reason code 0x%08X\n", (hr == DXGI_ERROR_DEVICE_REMOVED) ? m_d3dDevice->GetDeviceRemovedReason() : hr);
|
||||
OutputDebugStringA(buff);
|
||||
#endif
|
||||
// If the device was removed for any reason, a new device and swap chain will need to be created.
|
||||
HandleDeviceLost();
|
||||
|
||||
// Everything is set up now. Do not continue execution of this method. HandleDeviceLost will reenter this method
|
||||
// and correctly set up the new device.
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
ThrowIfFailed(hr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create a descriptor for the swap chain.
|
||||
DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
|
||||
swapChainDesc.Width = backBufferWidth;
|
||||
swapChainDesc.Height = backBufferHeight;
|
||||
swapChainDesc.Format = backBufferFormat;
|
||||
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
swapChainDesc.BufferCount = m_backBufferCount;
|
||||
swapChainDesc.SampleDesc.Count = 1;
|
||||
swapChainDesc.SampleDesc.Quality = 0;
|
||||
swapChainDesc.Scaling = DXGI_SCALING_ASPECT_RATIO_STRETCH;
|
||||
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||
swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
|
||||
swapChainDesc.Flags = (m_options & c_AllowTearing) ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0;
|
||||
|
||||
// Create a swap chain for the window.
|
||||
ComPtr<IDXGISwapChain1> swapChain;
|
||||
ThrowIfFailed(m_dxgiFactory->CreateSwapChainForCoreWindow(
|
||||
m_commandQueue.Get(),
|
||||
m_window,
|
||||
&swapChainDesc,
|
||||
nullptr,
|
||||
swapChain.GetAddressOf()
|
||||
));
|
||||
|
||||
ThrowIfFailed(swapChain.As(&m_swapChain));
|
||||
}
|
||||
|
||||
// Handle color space settings for HDR
|
||||
UpdateColorSpace();
|
||||
|
||||
// Set the proper orientation for the swap chain, and generate
|
||||
// matrix transformations for rendering to the rotated swap chain.
|
||||
switch (m_rotation)
|
||||
{
|
||||
default:
|
||||
case DXGI_MODE_ROTATION_IDENTITY:
|
||||
m_orientationTransform3D = ScreenRotation::Rotation0;
|
||||
break;
|
||||
|
||||
case DXGI_MODE_ROTATION_ROTATE90:
|
||||
m_orientationTransform3D = ScreenRotation::Rotation270;
|
||||
break;
|
||||
|
||||
case DXGI_MODE_ROTATION_ROTATE180:
|
||||
m_orientationTransform3D = ScreenRotation::Rotation180;
|
||||
break;
|
||||
|
||||
case DXGI_MODE_ROTATION_ROTATE270:
|
||||
m_orientationTransform3D = ScreenRotation::Rotation90;
|
||||
break;
|
||||
}
|
||||
|
||||
ThrowIfFailed(m_swapChain->SetRotation(m_rotation));
|
||||
|
||||
// Obtain the back buffers for this window which will be the final render targets
|
||||
// and create render target views for each of them.
|
||||
for (UINT n = 0; n < m_backBufferCount; n++)
|
||||
{
|
||||
ThrowIfFailed(m_swapChain->GetBuffer(n, IID_PPV_ARGS(m_renderTargets[n].GetAddressOf())));
|
||||
|
||||
wchar_t name[25] = {};
|
||||
swprintf_s(name, L"Render target %u", n);
|
||||
m_renderTargets[n]->SetName(name);
|
||||
|
||||
D3D12_RENDER_TARGET_VIEW_DESC rtvDesc = {};
|
||||
rtvDesc.Format = m_backBufferFormat;
|
||||
rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
|
||||
|
||||
CD3DX12_CPU_DESCRIPTOR_HANDLE rtvDescriptor(m_rtvDescriptorHeap->GetCPUDescriptorHandleForHeapStart(), n, m_rtvDescriptorSize);
|
||||
m_d3dDevice->CreateRenderTargetView(m_renderTargets[n].Get(), &rtvDesc, rtvDescriptor);
|
||||
}
|
||||
|
||||
// Reset the index to the current back buffer.
|
||||
m_backBufferIndex = m_swapChain->GetCurrentBackBufferIndex();
|
||||
|
||||
if (m_depthBufferFormat != DXGI_FORMAT_UNKNOWN)
|
||||
{
|
||||
// Allocate a 2-D surface as the depth/stencil buffer and create a depth/stencil view
|
||||
// on this surface.
|
||||
CD3DX12_HEAP_PROPERTIES depthHeapProperties(D3D12_HEAP_TYPE_DEFAULT);
|
||||
|
||||
D3D12_RESOURCE_DESC depthStencilDesc = CD3DX12_RESOURCE_DESC::Tex2D(
|
||||
m_depthBufferFormat,
|
||||
backBufferWidth,
|
||||
backBufferHeight,
|
||||
1, // This depth stencil view has only one texture.
|
||||
1 // Use a single mipmap level.
|
||||
);
|
||||
depthStencilDesc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
|
||||
|
||||
D3D12_CLEAR_VALUE depthOptimizedClearValue = {};
|
||||
depthOptimizedClearValue.Format = m_depthBufferFormat;
|
||||
depthOptimizedClearValue.DepthStencil.Depth = 1.0f;
|
||||
depthOptimizedClearValue.DepthStencil.Stencil = 0;
|
||||
|
||||
ThrowIfFailed(m_d3dDevice->CreateCommittedResource(
|
||||
&depthHeapProperties,
|
||||
D3D12_HEAP_FLAG_NONE,
|
||||
&depthStencilDesc,
|
||||
D3D12_RESOURCE_STATE_DEPTH_WRITE,
|
||||
&depthOptimizedClearValue,
|
||||
IID_PPV_ARGS(m_depthStencil.ReleaseAndGetAddressOf())
|
||||
));
|
||||
|
||||
m_depthStencil->SetName(L"Depth stencil");
|
||||
|
||||
D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc = {};
|
||||
dsvDesc.Format = m_depthBufferFormat;
|
||||
dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
|
||||
|
||||
m_d3dDevice->CreateDepthStencilView(m_depthStencil.Get(), &dsvDesc, m_dsvDescriptorHeap->GetCPUDescriptorHandleForHeapStart());
|
||||
}
|
||||
|
||||
// Set the 3D rendering viewport and scissor rectangle to target the entire window.
|
||||
m_screenViewport.TopLeftX = m_screenViewport.TopLeftY = 0.f;
|
||||
m_screenViewport.Width = static_cast<float>(backBufferWidth);
|
||||
m_screenViewport.Height = static_cast<float>(backBufferHeight);
|
||||
m_screenViewport.MinDepth = D3D12_MIN_DEPTH;
|
||||
m_screenViewport.MaxDepth = D3D12_MAX_DEPTH;
|
||||
|
||||
m_scissorRect.left = m_scissorRect.top = 0;
|
||||
m_scissorRect.right = backBufferWidth;
|
||||
m_scissorRect.bottom = backBufferHeight;
|
||||
}
|
||||
|
||||
// This method is called when the CoreWindow is created (or re-created).
|
||||
void DeviceResources::SetWindow(IUnknown* window, int width, int height, DXGI_MODE_ROTATION rotation)
|
||||
{
|
||||
m_window = window;
|
||||
|
||||
m_outputSize.left = m_outputSize.top = 0;
|
||||
m_outputSize.right = width;
|
||||
m_outputSize.bottom = height;
|
||||
|
||||
m_rotation = rotation;
|
||||
}
|
||||
|
||||
// This method is called when the window changes size.
|
||||
bool DeviceResources::WindowSizeChanged(int width, int height, DXGI_MODE_ROTATION rotation)
|
||||
{
|
||||
RECT newRc;
|
||||
newRc.left = newRc.top = 0;
|
||||
newRc.right = width;
|
||||
newRc.bottom = height;
|
||||
if (newRc.left == m_outputSize.left
|
||||
&& newRc.top == m_outputSize.top
|
||||
&& newRc.right == m_outputSize.right
|
||||
&& newRc.bottom == m_outputSize.bottom
|
||||
&& rotation == m_rotation)
|
||||
{
|
||||
// Handle color space settings for HDR
|
||||
UpdateColorSpace();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
m_outputSize = newRc;
|
||||
m_rotation = rotation;
|
||||
CreateWindowSizeDependentResources();
|
||||
return true;
|
||||
}
|
||||
|
||||
// This method is called in the event handler for the DisplayContentsInvalidated event.
|
||||
void DeviceResources::ValidateDevice()
|
||||
{
|
||||
// The D3D Device is no longer valid if the default adapter changed since the device
|
||||
// was created or if the device has been removed.
|
||||
|
||||
DXGI_ADAPTER_DESC previousDesc;
|
||||
{
|
||||
ComPtr<IDXGIAdapter1> previousDefaultAdapter;
|
||||
ThrowIfFailed(m_dxgiFactory->EnumAdapters1(0, previousDefaultAdapter.GetAddressOf()));
|
||||
|
||||
ThrowIfFailed(previousDefaultAdapter->GetDesc(&previousDesc));
|
||||
}
|
||||
|
||||
DXGI_ADAPTER_DESC currentDesc;
|
||||
{
|
||||
ComPtr<IDXGIFactory4> currentFactory;
|
||||
ThrowIfFailed(CreateDXGIFactory2(m_dxgiFactoryFlags, IID_PPV_ARGS(currentFactory.GetAddressOf())));
|
||||
|
||||
ComPtr<IDXGIAdapter1> currentDefaultAdapter;
|
||||
ThrowIfFailed(currentFactory->EnumAdapters1(0, currentDefaultAdapter.GetAddressOf()));
|
||||
|
||||
ThrowIfFailed(currentDefaultAdapter->GetDesc(¤tDesc));
|
||||
}
|
||||
|
||||
// If the adapter LUIDs don't match, or if the device reports that it has been removed,
|
||||
// a new D3D device must be created.
|
||||
|
||||
if (previousDesc.AdapterLuid.LowPart != currentDesc.AdapterLuid.LowPart
|
||||
|| previousDesc.AdapterLuid.HighPart != currentDesc.AdapterLuid.HighPart
|
||||
|| FAILED(m_d3dDevice->GetDeviceRemovedReason()))
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
OutputDebugStringA("Device Lost on ValidateDevice\n");
|
||||
#endif
|
||||
|
||||
// Create a new device and swap chain.
|
||||
HandleDeviceLost();
|
||||
}
|
||||
}
|
||||
|
||||
// Recreate all device resources and set them back to the current state.
|
||||
void DeviceResources::HandleDeviceLost()
|
||||
{
|
||||
if (m_deviceNotify)
|
||||
{
|
||||
m_deviceNotify->OnDeviceLost();
|
||||
}
|
||||
|
||||
for (UINT n = 0; n < m_backBufferCount; n++)
|
||||
{
|
||||
m_commandAllocators[n].Reset();
|
||||
m_renderTargets[n].Reset();
|
||||
}
|
||||
|
||||
m_depthStencil.Reset();
|
||||
m_commandQueue.Reset();
|
||||
m_commandList.Reset();
|
||||
m_fence.Reset();
|
||||
m_rtvDescriptorHeap.Reset();
|
||||
m_dsvDescriptorHeap.Reset();
|
||||
m_swapChain.Reset();
|
||||
m_d3dDevice.Reset();
|
||||
m_dxgiFactory.Reset();
|
||||
|
||||
#ifdef _DEBUG
|
||||
{
|
||||
ComPtr<IDXGIDebug1> dxgiDebug;
|
||||
if (SUCCEEDED(DXGIGetDebugInterface1(0, IID_PPV_ARGS(&dxgiDebug))))
|
||||
{
|
||||
dxgiDebug->ReportLiveObjects(DXGI_DEBUG_ALL, DXGI_DEBUG_RLO_FLAGS(DXGI_DEBUG_RLO_SUMMARY | DXGI_DEBUG_RLO_IGNORE_INTERNAL));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
CreateDeviceResources();
|
||||
CreateWindowSizeDependentResources();
|
||||
|
||||
if (m_deviceNotify)
|
||||
{
|
||||
m_deviceNotify->OnDeviceRestored();
|
||||
}
|
||||
}
|
||||
|
||||
// Prepare the command list and render target for rendering.
|
||||
void DeviceResources::Prepare(D3D12_RESOURCE_STATES beforeState)
|
||||
{
|
||||
// Reset command list and allocator.
|
||||
ThrowIfFailed(m_commandAllocators[m_backBufferIndex]->Reset());
|
||||
ThrowIfFailed(m_commandList->Reset(m_commandAllocators[m_backBufferIndex].Get(), nullptr));
|
||||
|
||||
if (beforeState != D3D12_RESOURCE_STATE_RENDER_TARGET)
|
||||
{
|
||||
// Transition the render target into the correct state to allow for drawing into it.
|
||||
D3D12_RESOURCE_BARRIER barrier = CD3DX12_RESOURCE_BARRIER::Transition(m_renderTargets[m_backBufferIndex].Get(), beforeState, D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||
m_commandList->ResourceBarrier(1, &barrier);
|
||||
}
|
||||
}
|
||||
|
||||
// Present the contents of the swap chain to the screen.
|
||||
void DeviceResources::Present(D3D12_RESOURCE_STATES beforeState)
|
||||
{
|
||||
if (beforeState != D3D12_RESOURCE_STATE_PRESENT)
|
||||
{
|
||||
// Transition the render target to the state that allows it to be presented to the display.
|
||||
D3D12_RESOURCE_BARRIER barrier = CD3DX12_RESOURCE_BARRIER::Transition(m_renderTargets[m_backBufferIndex].Get(), beforeState, D3D12_RESOURCE_STATE_PRESENT);
|
||||
m_commandList->ResourceBarrier(1, &barrier);
|
||||
}
|
||||
|
||||
// Send the command list off to the GPU for processing.
|
||||
ThrowIfFailed(m_commandList->Close());
|
||||
m_commandQueue->ExecuteCommandLists(1, CommandListCast(m_commandList.GetAddressOf()));
|
||||
|
||||
HRESULT hr;
|
||||
if (m_options & c_AllowTearing)
|
||||
{
|
||||
// Recommended to always use tearing if supported when using a sync interval of 0.
|
||||
hr = m_swapChain->Present(0, DXGI_PRESENT_ALLOW_TEARING);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The first argument instructs DXGI to block until VSync, putting the application
|
||||
// to sleep until the next VSync. This ensures we don't waste any cycles rendering
|
||||
// frames that will never be displayed to the screen.
|
||||
hr = m_swapChain->Present(1, 0);
|
||||
}
|
||||
|
||||
// If the device was reset we must completely reinitialize the renderer.
|
||||
if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
char buff[64] = {};
|
||||
sprintf_s(buff, "Device Lost on Present: Reason code 0x%08X\n", (hr == DXGI_ERROR_DEVICE_REMOVED) ? m_d3dDevice->GetDeviceRemovedReason() : hr);
|
||||
OutputDebugStringA(buff);
|
||||
#endif
|
||||
HandleDeviceLost();
|
||||
}
|
||||
else
|
||||
{
|
||||
ThrowIfFailed(hr);
|
||||
|
||||
MoveToNextFrame();
|
||||
|
||||
if (!m_dxgiFactory->IsCurrent())
|
||||
{
|
||||
// Output information is cached on the DXGI Factory. If it is stale we need to create a new factory.
|
||||
ThrowIfFailed(CreateDXGIFactory2(m_dxgiFactoryFlags, IID_PPV_ARGS(m_dxgiFactory.ReleaseAndGetAddressOf())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for pending GPU work to complete.
|
||||
void DeviceResources::WaitForGpu() noexcept
|
||||
{
|
||||
if (m_commandQueue && m_fence && m_fenceEvent.IsValid())
|
||||
{
|
||||
// Schedule a Signal command in the GPU queue.
|
||||
UINT64 fenceValue = m_fenceValues[m_backBufferIndex];
|
||||
if (SUCCEEDED(m_commandQueue->Signal(m_fence.Get(), fenceValue)))
|
||||
{
|
||||
// Wait until the Signal has been processed.
|
||||
if (SUCCEEDED(m_fence->SetEventOnCompletion(fenceValue, m_fenceEvent.Get())))
|
||||
{
|
||||
WaitForSingleObjectEx(m_fenceEvent.Get(), INFINITE, FALSE);
|
||||
|
||||
// Increment the fence value for the current frame.
|
||||
m_fenceValues[m_backBufferIndex]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Prepare to render the next frame.
|
||||
void DeviceResources::MoveToNextFrame()
|
||||
{
|
||||
// Schedule a Signal command in the queue.
|
||||
const UINT64 currentFenceValue = m_fenceValues[m_backBufferIndex];
|
||||
ThrowIfFailed(m_commandQueue->Signal(m_fence.Get(), currentFenceValue));
|
||||
|
||||
// Update the back buffer index.
|
||||
m_backBufferIndex = m_swapChain->GetCurrentBackBufferIndex();
|
||||
|
||||
// If the next frame is not ready to be rendered yet, wait until it is ready.
|
||||
if (m_fence->GetCompletedValue() < m_fenceValues[m_backBufferIndex])
|
||||
{
|
||||
ThrowIfFailed(m_fence->SetEventOnCompletion(m_fenceValues[m_backBufferIndex], m_fenceEvent.Get()));
|
||||
WaitForSingleObjectEx(m_fenceEvent.Get(), INFINITE, FALSE);
|
||||
}
|
||||
|
||||
// Set the fence value for the next frame.
|
||||
m_fenceValues[m_backBufferIndex] = currentFenceValue + 1;
|
||||
}
|
||||
|
||||
// This method acquires the first available hardware adapter that supports Direct3D 12.
|
||||
// If no such adapter can be found, try WARP. Otherwise throw an exception.
|
||||
void DeviceResources::GetAdapter(IDXGIAdapter1** ppAdapter)
|
||||
{
|
||||
*ppAdapter = nullptr;
|
||||
|
||||
ComPtr<IDXGIAdapter1> adapter;
|
||||
for (UINT adapterIndex = 0; DXGI_ERROR_NOT_FOUND != m_dxgiFactory->EnumAdapters1(adapterIndex, adapter.ReleaseAndGetAddressOf()); ++adapterIndex)
|
||||
{
|
||||
DXGI_ADAPTER_DESC1 desc;
|
||||
ThrowIfFailed(adapter->GetDesc1(&desc));
|
||||
|
||||
if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)
|
||||
{
|
||||
// Don't select the Basic Render Driver adapter.
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check to see if the adapter supports Direct3D 12, but don't create the actual device yet.
|
||||
if (SUCCEEDED(D3D12CreateDevice(adapter.Get(), m_d3dMinFeatureLevel, _uuidof(ID3D12Device), nullptr)))
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
wchar_t buff[256] = {};
|
||||
swprintf_s(buff, L"Direct3D Adapter (%u): VID:%04X, PID:%04X - %ls\n", adapterIndex, desc.VendorId, desc.DeviceId, desc.Description);
|
||||
OutputDebugStringW(buff);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
if (!adapter)
|
||||
{
|
||||
// Try WARP12 instead
|
||||
if (FAILED(m_dxgiFactory->EnumWarpAdapter(IID_PPV_ARGS(adapter.ReleaseAndGetAddressOf()))))
|
||||
{
|
||||
throw std::exception("WARP12 not available. Enable the 'Graphics Tools' optional feature");
|
||||
}
|
||||
|
||||
OutputDebugStringA("Direct3D Adapter - WARP12\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!adapter)
|
||||
{
|
||||
throw std::exception("No Direct3D 12 device found");
|
||||
}
|
||||
|
||||
*ppAdapter = adapter.Detach();
|
||||
}
|
||||
|
||||
// Sets the color space for the swap chain in order to handle HDR output.
|
||||
void DeviceResources::UpdateColorSpace()
|
||||
{
|
||||
DXGI_COLOR_SPACE_TYPE colorSpace = DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
|
||||
|
||||
bool isdisplayhdr10 = false;
|
||||
|
||||
#if defined(NTDDI_WIN10_RS2)
|
||||
if (m_swapChain)
|
||||
{
|
||||
ComPtr<IDXGIOutput> output;
|
||||
if (SUCCEEDED(m_swapChain->GetContainingOutput(output.GetAddressOf())))
|
||||
{
|
||||
ComPtr<IDXGIOutput6> output6;
|
||||
if (SUCCEEDED(output.As(&output6)))
|
||||
{
|
||||
DXGI_OUTPUT_DESC1 desc;
|
||||
ThrowIfFailed(output6->GetDesc1(&desc));
|
||||
|
||||
if (desc.ColorSpace == DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020)
|
||||
{
|
||||
// Display output is HDR10.
|
||||
isdisplayhdr10 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((m_options & c_EnableHDR) && isdisplayhdr10)
|
||||
{
|
||||
switch (m_backBufferFormat)
|
||||
{
|
||||
case DXGI_FORMAT_R10G10B10A2_UNORM:
|
||||
// The application creates the HDR10 signal.
|
||||
colorSpace = DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020;
|
||||
break;
|
||||
|
||||
case DXGI_FORMAT_R16G16B16A16_FLOAT:
|
||||
// The system creates the HDR10 signal; application uses linear values.
|
||||
colorSpace = DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_colorSpace = colorSpace;
|
||||
|
||||
UINT colorSpaceSupport = 0;
|
||||
if (SUCCEEDED(m_swapChain->CheckColorSpaceSupport(colorSpace, &colorSpaceSupport))
|
||||
&& (colorSpaceSupport & DXGI_SWAP_CHAIN_COLOR_SPACE_SUPPORT_FLAG_PRESENT))
|
||||
{
|
||||
ThrowIfFailed(m_swapChain->SetColorSpace1(colorSpace));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
//
|
||||
// DeviceResources.h - A wrapper for the Direct3D 12 device and swapchain
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace DX
|
||||
{
|
||||
// Provides an interface for an application that owns DeviceResources to be notified of the device being lost or created.
|
||||
interface IDeviceNotify
|
||||
{
|
||||
virtual void OnDeviceLost() = 0;
|
||||
virtual void OnDeviceRestored() = 0;
|
||||
};
|
||||
|
||||
// Controls all the DirectX device resources.
|
||||
class DeviceResources
|
||||
{
|
||||
public:
|
||||
static const unsigned int c_AllowTearing = 0x1;
|
||||
static const unsigned int c_EnableHDR = 0x2;
|
||||
|
||||
DeviceResources(DXGI_FORMAT backBufferFormat = DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||
DXGI_FORMAT depthBufferFormat = DXGI_FORMAT_D32_FLOAT,
|
||||
UINT backBufferCount = 2,
|
||||
D3D_FEATURE_LEVEL minFeatureLevel = D3D_FEATURE_LEVEL_11_0,
|
||||
unsigned int flags = 0);
|
||||
~DeviceResources();
|
||||
|
||||
void CreateDeviceResources();
|
||||
void CreateWindowSizeDependentResources();
|
||||
void SetWindow(IUnknown* window, int width, int height, DXGI_MODE_ROTATION rotation);
|
||||
bool WindowSizeChanged(int width, int height, DXGI_MODE_ROTATION rotation);
|
||||
void ValidateDevice();
|
||||
void HandleDeviceLost();
|
||||
void RegisterDeviceNotify(IDeviceNotify* deviceNotify) { m_deviceNotify = deviceNotify; }
|
||||
void Prepare(D3D12_RESOURCE_STATES beforeState = D3D12_RESOURCE_STATE_PRESENT);
|
||||
void Present(D3D12_RESOURCE_STATES beforeState = D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||
void WaitForGpu() noexcept;
|
||||
|
||||
// Device Accessors.
|
||||
RECT GetOutputSize() const { return m_outputSize; }
|
||||
DXGI_MODE_ROTATION GetRotation() const { return m_rotation; }
|
||||
|
||||
// Direct3D Accessors.
|
||||
ID3D12Device* GetD3DDevice() const { return m_d3dDevice.Get(); }
|
||||
IDXGISwapChain3* GetSwapChain() const { return m_swapChain.Get(); }
|
||||
D3D_FEATURE_LEVEL GetDeviceFeatureLevel() const { return m_d3dFeatureLevel; }
|
||||
ID3D12Resource* GetRenderTarget() const { return m_renderTargets[m_backBufferIndex].Get(); }
|
||||
ID3D12Resource* GetDepthStencil() const { return m_depthStencil.Get(); }
|
||||
ID3D12CommandQueue* GetCommandQueue() const { return m_commandQueue.Get(); }
|
||||
ID3D12CommandAllocator* GetCommandAllocator() const { return m_commandAllocators[m_backBufferIndex].Get(); }
|
||||
ID3D12GraphicsCommandList* GetCommandList() const { return m_commandList.Get(); }
|
||||
DXGI_FORMAT GetBackBufferFormat() const { return m_backBufferFormat; }
|
||||
DXGI_FORMAT GetDepthBufferFormat() const { return m_depthBufferFormat; }
|
||||
D3D12_VIEWPORT GetScreenViewport() const { return m_screenViewport; }
|
||||
D3D12_RECT GetScissorRect() const { return m_scissorRect; }
|
||||
UINT GetCurrentFrameIndex() const { return m_backBufferIndex; }
|
||||
UINT GetBackBufferCount() const { return m_backBufferCount; }
|
||||
DirectX::XMFLOAT4X4 GetOrientationTransform3D() const { return m_orientationTransform3D; }
|
||||
DXGI_COLOR_SPACE_TYPE GetColorSpace() const { return m_colorSpace; }
|
||||
unsigned int GetDeviceOptions() const { return m_options; }
|
||||
|
||||
CD3DX12_CPU_DESCRIPTOR_HANDLE GetRenderTargetView() const
|
||||
{
|
||||
return CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtvDescriptorHeap->GetCPUDescriptorHandleForHeapStart(), m_backBufferIndex, m_rtvDescriptorSize);
|
||||
}
|
||||
CD3DX12_CPU_DESCRIPTOR_HANDLE GetDepthStencilView() const
|
||||
{
|
||||
return CD3DX12_CPU_DESCRIPTOR_HANDLE(m_dsvDescriptorHeap->GetCPUDescriptorHandleForHeapStart());
|
||||
}
|
||||
|
||||
private:
|
||||
void MoveToNextFrame();
|
||||
void GetAdapter(IDXGIAdapter1** ppAdapter);
|
||||
void UpdateColorSpace();
|
||||
|
||||
const static size_t MAX_BACK_BUFFER_COUNT = 3;
|
||||
|
||||
UINT m_backBufferIndex;
|
||||
|
||||
// Direct3D objects.
|
||||
Microsoft::WRL::ComPtr<ID3D12Device> m_d3dDevice;
|
||||
Microsoft::WRL::ComPtr<ID3D12CommandQueue> m_commandQueue;
|
||||
Microsoft::WRL::ComPtr<ID3D12GraphicsCommandList> m_commandList;
|
||||
Microsoft::WRL::ComPtr<ID3D12CommandAllocator> m_commandAllocators[MAX_BACK_BUFFER_COUNT];
|
||||
|
||||
// Swap chain objects.
|
||||
Microsoft::WRL::ComPtr<IDXGIFactory4> m_dxgiFactory;
|
||||
Microsoft::WRL::ComPtr<IDXGISwapChain3> m_swapChain;
|
||||
Microsoft::WRL::ComPtr<ID3D12Resource> m_renderTargets[MAX_BACK_BUFFER_COUNT];
|
||||
Microsoft::WRL::ComPtr<ID3D12Resource> m_depthStencil;
|
||||
|
||||
// Presentation fence objects.
|
||||
Microsoft::WRL::ComPtr<ID3D12Fence> m_fence;
|
||||
UINT64 m_fenceValues[MAX_BACK_BUFFER_COUNT];
|
||||
Microsoft::WRL::Wrappers::Event m_fenceEvent;
|
||||
|
||||
// Direct3D rendering objects.
|
||||
Microsoft::WRL::ComPtr<ID3D12DescriptorHeap> m_rtvDescriptorHeap;
|
||||
Microsoft::WRL::ComPtr<ID3D12DescriptorHeap> m_dsvDescriptorHeap;
|
||||
UINT m_rtvDescriptorSize;
|
||||
D3D12_VIEWPORT m_screenViewport;
|
||||
D3D12_RECT m_scissorRect;
|
||||
|
||||
// Direct3D properties.
|
||||
DXGI_FORMAT m_backBufferFormat;
|
||||
DXGI_FORMAT m_depthBufferFormat;
|
||||
UINT m_backBufferCount;
|
||||
D3D_FEATURE_LEVEL m_d3dMinFeatureLevel;
|
||||
|
||||
// Cached device properties.
|
||||
IUnknown* m_window;
|
||||
D3D_FEATURE_LEVEL m_d3dFeatureLevel;
|
||||
DXGI_MODE_ROTATION m_rotation;
|
||||
DWORD m_dxgiFactoryFlags;
|
||||
RECT m_outputSize;
|
||||
|
||||
// HDR Support
|
||||
DXGI_COLOR_SPACE_TYPE m_colorSpace;
|
||||
|
||||
// DeviceResources options (see flags above)
|
||||
unsigned int m_options;
|
||||
|
||||
// Transforms used for display orientation.
|
||||
DirectX::XMFLOAT4X4 m_orientationTransform3D;
|
||||
|
||||
// The IDeviceNotify can be held directly as it owns the DeviceResources.
|
||||
IDeviceNotify* m_deviceNotify;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,431 @@
|
|||
//--------------------------------------------------------------------------------------
|
||||
// Main.cpp
|
||||
//
|
||||
// Entry point for Universal Windows Platform (UWP) app.
|
||||
//
|
||||
// Advanced Technology Group (ATG)
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
#include "pch.h"
|
||||
#include "SimpleComputeUWP12.h"
|
||||
|
||||
#include "Telemetry.h"
|
||||
|
||||
#include <ppltasks.h>
|
||||
|
||||
using namespace concurrency;
|
||||
using namespace Windows::ApplicationModel;
|
||||
using namespace Windows::ApplicationModel::Core;
|
||||
using namespace Windows::ApplicationModel::Activation;
|
||||
using namespace Windows::UI::Core;
|
||||
using namespace Windows::UI::Input;
|
||||
using namespace Windows::UI::ViewManagement;
|
||||
using namespace Windows::System;
|
||||
using namespace Windows::Foundation;
|
||||
using namespace Windows::Graphics::Display;
|
||||
using namespace DirectX;
|
||||
|
||||
ref class ViewProvider sealed : public IFrameworkView
|
||||
{
|
||||
public:
|
||||
ViewProvider() :
|
||||
m_exit(false),
|
||||
m_visible(true),
|
||||
m_in_sizemove(false),
|
||||
m_DPI(96.f),
|
||||
m_logicalWidth(800.f),
|
||||
m_logicalHeight(600.f),
|
||||
m_nativeOrientation(DisplayOrientations::None),
|
||||
m_currentOrientation(DisplayOrientations::None)
|
||||
{
|
||||
}
|
||||
|
||||
// IFrameworkView methods
|
||||
virtual void Initialize(CoreApplicationView^ applicationView)
|
||||
{
|
||||
applicationView->Activated +=
|
||||
ref new TypedEventHandler<CoreApplicationView^, IActivatedEventArgs^>(this, &ViewProvider::OnActivated);
|
||||
|
||||
CoreApplication::Suspending +=
|
||||
ref new EventHandler<SuspendingEventArgs^>(this, &ViewProvider::OnSuspending);
|
||||
|
||||
CoreApplication::Resuming +=
|
||||
ref new EventHandler<Platform::Object^>(this, &ViewProvider::OnResuming);
|
||||
|
||||
m_sample = std::make_unique<Sample>();
|
||||
|
||||
// Sample Usage Telemetry
|
||||
//
|
||||
// Disable or remove this code block to opt-out of sample usage telemetry
|
||||
//
|
||||
if (ATG::EventRegisterATGSampleTelemetry() == ERROR_SUCCESS)
|
||||
{
|
||||
wchar_t exeName[MAX_PATH + 1] = {};
|
||||
if (!GetModuleFileNameW(nullptr, exeName, MAX_PATH))
|
||||
{
|
||||
wcscpy_s(exeName, L"Unknown");
|
||||
}
|
||||
wchar_t fname[_MAX_FNAME] = {};
|
||||
wchar_t ext[_MAX_EXT] = {};
|
||||
(void)_wsplitpath_s(exeName, nullptr, 0, nullptr, 0, fname, _MAX_FNAME, ext, _MAX_EXT);
|
||||
(void)_wmakepath_s(exeName, nullptr, nullptr, fname, ext); // keep only the filename + extension
|
||||
|
||||
ATG::EventWriteSampleLoaded(exeName);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void Uninitialize()
|
||||
{
|
||||
m_sample.reset();
|
||||
}
|
||||
|
||||
virtual void SetWindow(CoreWindow^ window)
|
||||
{
|
||||
window->SizeChanged +=
|
||||
ref new TypedEventHandler<CoreWindow^, WindowSizeChangedEventArgs^>(this, &ViewProvider::OnWindowSizeChanged);
|
||||
|
||||
#if defined(NTDDI_WIN10_RS2) && (NTDDI_VERSION >= NTDDI_WIN10_RS2)
|
||||
try
|
||||
{
|
||||
window->ResizeStarted +=
|
||||
ref new TypedEventHandler<CoreWindow^, Object^>(this, &ViewProvider::OnResizeStarted);
|
||||
|
||||
window->ResizeCompleted +=
|
||||
ref new TypedEventHandler<CoreWindow^, Object^>(this, &ViewProvider::OnResizeCompleted);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// Requires Windows 10 Creators Update (10.0.15063) or later
|
||||
}
|
||||
#endif
|
||||
|
||||
window->VisibilityChanged +=
|
||||
ref new TypedEventHandler<CoreWindow^, VisibilityChangedEventArgs^>(this, &ViewProvider::OnVisibilityChanged);
|
||||
|
||||
window->Closed +=
|
||||
ref new TypedEventHandler<CoreWindow^, CoreWindowEventArgs^>(this, &ViewProvider::OnWindowClosed);
|
||||
|
||||
auto dispatcher = CoreWindow::GetForCurrentThread()->Dispatcher;
|
||||
|
||||
dispatcher->AcceleratorKeyActivated +=
|
||||
ref new TypedEventHandler<CoreDispatcher^, AcceleratorKeyEventArgs^>(this, &ViewProvider::OnAcceleratorKeyActivated);
|
||||
|
||||
auto currentDisplayInformation = DisplayInformation::GetForCurrentView();
|
||||
|
||||
currentDisplayInformation->DpiChanged +=
|
||||
ref new TypedEventHandler<DisplayInformation^, Object^>(this, &ViewProvider::OnDpiChanged);
|
||||
|
||||
currentDisplayInformation->OrientationChanged +=
|
||||
ref new TypedEventHandler<DisplayInformation^, Object^>(this, &ViewProvider::OnOrientationChanged);
|
||||
|
||||
DisplayInformation::DisplayContentsInvalidated +=
|
||||
ref new TypedEventHandler<DisplayInformation^, Object^>(this, &ViewProvider::OnDisplayContentsInvalidated);
|
||||
|
||||
m_DPI = currentDisplayInformation->LogicalDpi;
|
||||
|
||||
m_logicalWidth = window->Bounds.Width;
|
||||
m_logicalHeight = window->Bounds.Height;
|
||||
|
||||
m_nativeOrientation = currentDisplayInformation->NativeOrientation;
|
||||
m_currentOrientation = currentDisplayInformation->CurrentOrientation;
|
||||
|
||||
int outputWidth = ConvertDipsToPixels(m_logicalWidth);
|
||||
int outputHeight = ConvertDipsToPixels(m_logicalHeight);
|
||||
|
||||
DXGI_MODE_ROTATION rotation = ComputeDisplayRotation();
|
||||
|
||||
if (rotation == DXGI_MODE_ROTATION_ROTATE90 || rotation == DXGI_MODE_ROTATION_ROTATE270)
|
||||
{
|
||||
std::swap(outputWidth, outputHeight);
|
||||
}
|
||||
|
||||
m_sample->Initialize(reinterpret_cast<IUnknown*>(window),
|
||||
outputWidth, outputHeight, rotation );
|
||||
|
||||
Mouse::SetDpi(m_DPI);
|
||||
}
|
||||
|
||||
virtual void Load(Platform::String^ entryPoint)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void Run()
|
||||
{
|
||||
while (!m_exit)
|
||||
{
|
||||
if (m_visible)
|
||||
{
|
||||
m_sample->Tick();
|
||||
|
||||
CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
|
||||
}
|
||||
else
|
||||
{
|
||||
CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
// Event handlers
|
||||
void OnActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args)
|
||||
{
|
||||
if (args->Kind == ActivationKind::Launch)
|
||||
{
|
||||
auto launchArgs = static_cast<LaunchActivatedEventArgs^>(args);
|
||||
|
||||
if (launchArgs->PrelaunchActivated)
|
||||
{
|
||||
// Opt-out of Prelaunch
|
||||
CoreApplication::Exit();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int w, h;
|
||||
m_sample->GetDefaultSize(w, h);
|
||||
|
||||
m_DPI = DisplayInformation::GetForCurrentView()->LogicalDpi;
|
||||
|
||||
ApplicationView::PreferredLaunchWindowingMode = ApplicationViewWindowingMode::PreferredLaunchViewSize;
|
||||
// Change to ApplicationViewWindowingMode::FullScreen to default to full screen
|
||||
|
||||
auto desiredSize = Size(ConvertPixelsToDips(w), ConvertPixelsToDips(h));
|
||||
|
||||
ApplicationView::PreferredLaunchViewSize = desiredSize;
|
||||
|
||||
auto view = ApplicationView::GetForCurrentView();
|
||||
|
||||
auto minSize = Size(ConvertPixelsToDips(320), ConvertPixelsToDips(200));
|
||||
|
||||
view->SetPreferredMinSize(minSize);
|
||||
|
||||
CoreWindow::GetForCurrentThread()->Activate();
|
||||
|
||||
view->FullScreenSystemOverlayMode = FullScreenSystemOverlayMode::Minimal;
|
||||
|
||||
view->TryResizeView(desiredSize);
|
||||
}
|
||||
|
||||
void OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ args)
|
||||
{
|
||||
auto deferral = args->SuspendingOperation->GetDeferral();
|
||||
|
||||
create_task([this, deferral]()
|
||||
{
|
||||
m_sample->OnSuspending();
|
||||
|
||||
deferral->Complete();
|
||||
});
|
||||
}
|
||||
|
||||
void OnResuming(Platform::Object^ sender, Platform::Object^ args)
|
||||
{
|
||||
m_sample->OnResuming();
|
||||
}
|
||||
|
||||
void OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args)
|
||||
{
|
||||
m_logicalWidth = sender->Bounds.Width;
|
||||
m_logicalHeight = sender->Bounds.Height;
|
||||
|
||||
if (m_in_sizemove)
|
||||
return;
|
||||
|
||||
HandleWindowSizeChanged();
|
||||
}
|
||||
|
||||
#if defined(NTDDI_WIN10_RS2) && (NTDDI_VERSION >= NTDDI_WIN10_RS2)
|
||||
void OnResizeStarted(CoreWindow^ sender, Platform::Object^ args)
|
||||
{
|
||||
m_in_sizemove = true;
|
||||
}
|
||||
|
||||
void OnResizeCompleted(CoreWindow^ sender, Platform::Object^ args)
|
||||
{
|
||||
m_in_sizemove = false;
|
||||
|
||||
HandleWindowSizeChanged();
|
||||
}
|
||||
#endif
|
||||
|
||||
void OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args)
|
||||
{
|
||||
m_visible = args->Visible;
|
||||
if (m_visible)
|
||||
m_sample->OnActivated();
|
||||
else
|
||||
m_sample->OnDeactivated();
|
||||
}
|
||||
|
||||
void OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args)
|
||||
{
|
||||
m_exit = true;
|
||||
}
|
||||
|
||||
void OnAcceleratorKeyActivated(CoreDispatcher^, AcceleratorKeyEventArgs^ args)
|
||||
{
|
||||
if (args->EventType == CoreAcceleratorKeyEventType::SystemKeyDown
|
||||
&& args->VirtualKey == VirtualKey::Enter
|
||||
&& args->KeyStatus.IsMenuKeyDown
|
||||
&& !args->KeyStatus.WasKeyDown)
|
||||
{
|
||||
// Implements the classic ALT+ENTER fullscreen toggle
|
||||
auto view = ApplicationView::GetForCurrentView();
|
||||
|
||||
if (view->IsFullScreenMode)
|
||||
view->ExitFullScreenMode();
|
||||
else
|
||||
view->TryEnterFullScreenMode();
|
||||
|
||||
args->Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
void OnDpiChanged(DisplayInformation^ sender, Object^ args)
|
||||
{
|
||||
m_DPI = sender->LogicalDpi;
|
||||
|
||||
HandleWindowSizeChanged();
|
||||
|
||||
Mouse::SetDpi(m_DPI);
|
||||
}
|
||||
|
||||
void OnOrientationChanged(DisplayInformation^ sender, Object^ args)
|
||||
{
|
||||
auto resizeManager = CoreWindowResizeManager::GetForCurrentView();
|
||||
resizeManager->ShouldWaitForLayoutCompletion = true;
|
||||
|
||||
m_currentOrientation = sender->CurrentOrientation;
|
||||
|
||||
HandleWindowSizeChanged();
|
||||
|
||||
resizeManager->NotifyLayoutCompleted();
|
||||
}
|
||||
|
||||
void OnDisplayContentsInvalidated(DisplayInformation^ sender, Object^ args)
|
||||
{
|
||||
m_sample->ValidateDevice();
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_exit;
|
||||
bool m_visible;
|
||||
bool m_in_sizemove;
|
||||
float m_DPI;
|
||||
float m_logicalWidth;
|
||||
float m_logicalHeight;
|
||||
std::unique_ptr<Sample> m_sample;
|
||||
|
||||
Windows::Graphics::Display::DisplayOrientations m_nativeOrientation;
|
||||
Windows::Graphics::Display::DisplayOrientations m_currentOrientation;
|
||||
|
||||
inline int ConvertDipsToPixels(float dips) const
|
||||
{
|
||||
return int(dips * m_DPI / 96.f + 0.5f);
|
||||
}
|
||||
|
||||
inline float ConvertPixelsToDips(int pixels) const
|
||||
{
|
||||
return (float(pixels) * 96.f / m_DPI);
|
||||
}
|
||||
|
||||
DXGI_MODE_ROTATION ComputeDisplayRotation() const
|
||||
{
|
||||
DXGI_MODE_ROTATION rotation = DXGI_MODE_ROTATION_UNSPECIFIED;
|
||||
|
||||
switch (m_nativeOrientation)
|
||||
{
|
||||
case DisplayOrientations::Landscape:
|
||||
switch (m_currentOrientation)
|
||||
{
|
||||
case DisplayOrientations::Landscape:
|
||||
rotation = DXGI_MODE_ROTATION_IDENTITY;
|
||||
break;
|
||||
|
||||
case DisplayOrientations::Portrait:
|
||||
rotation = DXGI_MODE_ROTATION_ROTATE270;
|
||||
break;
|
||||
|
||||
case DisplayOrientations::LandscapeFlipped:
|
||||
rotation = DXGI_MODE_ROTATION_ROTATE180;
|
||||
break;
|
||||
|
||||
case DisplayOrientations::PortraitFlipped:
|
||||
rotation = DXGI_MODE_ROTATION_ROTATE90;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case DisplayOrientations::Portrait:
|
||||
switch (m_currentOrientation)
|
||||
{
|
||||
case DisplayOrientations::Landscape:
|
||||
rotation = DXGI_MODE_ROTATION_ROTATE90;
|
||||
break;
|
||||
|
||||
case DisplayOrientations::Portrait:
|
||||
rotation = DXGI_MODE_ROTATION_IDENTITY;
|
||||
break;
|
||||
|
||||
case DisplayOrientations::LandscapeFlipped:
|
||||
rotation = DXGI_MODE_ROTATION_ROTATE270;
|
||||
break;
|
||||
|
||||
case DisplayOrientations::PortraitFlipped:
|
||||
rotation = DXGI_MODE_ROTATION_ROTATE180;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return rotation;
|
||||
}
|
||||
|
||||
void HandleWindowSizeChanged()
|
||||
{
|
||||
int outputWidth = ConvertDipsToPixels(m_logicalWidth);
|
||||
int outputHeight = ConvertDipsToPixels(m_logicalHeight);
|
||||
|
||||
DXGI_MODE_ROTATION rotation = ComputeDisplayRotation();
|
||||
|
||||
if (rotation == DXGI_MODE_ROTATION_ROTATE90 || rotation == DXGI_MODE_ROTATION_ROTATE270)
|
||||
{
|
||||
std::swap(outputWidth, outputHeight);
|
||||
}
|
||||
|
||||
m_sample->OnWindowSizeChanged(outputWidth, outputHeight, rotation);
|
||||
}
|
||||
};
|
||||
|
||||
ref class ViewProviderFactory : IFrameworkViewSource
|
||||
{
|
||||
public:
|
||||
virtual IFrameworkView^ CreateView()
|
||||
{
|
||||
return ref new ViewProvider();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Entry point
|
||||
[Platform::MTAThread]
|
||||
int __cdecl main(Platform::Array<Platform::String^>^ /*argv*/)
|
||||
{
|
||||
if (!XMVerifyCPUSupport())
|
||||
{
|
||||
throw std::exception("XMVerifyCPUSupport");
|
||||
}
|
||||
|
||||
auto viewProviderFactory = ref new ViewProviderFactory();
|
||||
CoreApplication::Run(viewProviderFactory);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Exit helper
|
||||
void ExitSample()
|
||||
{
|
||||
Windows::ApplicationModel::Core::CoreApplication::Exit();
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<Package
|
||||
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
|
||||
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
|
||||
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
|
||||
IgnorableNamespaces="uap mp">
|
||||
|
||||
<Identity
|
||||
Name="a9047f90-ffb3-4392-a926-185c1bc7416d"
|
||||
Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US"
|
||||
Version="1.0.0.0" />
|
||||
|
||||
<mp:PhoneIdentity PhoneProductId="a9047f90-ffb3-4392-a926-185c1bc7416d" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
|
||||
|
||||
<Properties>
|
||||
<DisplayName>SimpleComputeUWP12</DisplayName>
|
||||
<PublisherDisplayName>Xbox Advanced Technology Group</PublisherDisplayName>
|
||||
<Logo>Assets\StoreLogo.png</Logo>
|
||||
</Properties>
|
||||
|
||||
<Dependencies>
|
||||
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
|
||||
</Dependencies>
|
||||
|
||||
<Resources>
|
||||
<Resource Language="x-generate"/>
|
||||
</Resources>
|
||||
|
||||
<Applications>
|
||||
<Application Id="App"
|
||||
Executable="$targetnametoken$.exe"
|
||||
EntryPoint="SimpleComputeUWP12.App">
|
||||
<uap:VisualElements
|
||||
DisplayName="SimpleComputeUWP12"
|
||||
Square150x150Logo="Assets\Logo.png"
|
||||
Square44x44Logo="Assets\SmallLogo.png"
|
||||
Description="SimpleComputeUWP12"
|
||||
BackgroundColor="transparent">
|
||||
<uap:DefaultTile Wide310x150Logo="Assets\WideLogo.png"/>
|
||||
<uap:SplashScreen Image="Assets\SplashScreen.png" />
|
||||
</uap:VisualElements>
|
||||
</Application>
|
||||
</Applications>
|
||||
|
||||
<Capabilities>
|
||||
<Capability Name="internetClient" />
|
||||
</Capabilities>
|
||||
</Package>
|
|
@ -0,0 +1,887 @@
|
|||
//--------------------------------------------------------------------------------------
|
||||
// SimpleComputeUWP12.cpp
|
||||
//
|
||||
// Advanced Technology Group (ATG)
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
#include "pch.h"
|
||||
#include "SimpleComputeUWP12.h"
|
||||
|
||||
#include "ATGColors.h"
|
||||
#include "ControllerFont.h"
|
||||
#include "ReadData.h"
|
||||
|
||||
extern void ExitSample();
|
||||
|
||||
using namespace DirectX;
|
||||
|
||||
using Microsoft::WRL::ComPtr;
|
||||
|
||||
namespace
|
||||
{
|
||||
const uint32_t s_numShaderThreads = 8; // make sure to update value in shader if this changes
|
||||
|
||||
const wchar_t* g_SampleTitle = L"SimpleCompute12";
|
||||
const wchar_t* g_SampleDescription = L"Demonstrates how to use the D3D12_COMMAND_LIST_TYPE_COMPUTE interface to submit asynchronous compute shader workloads";
|
||||
const ATG::HelpButtonAssignment g_HelpButtons[] = {
|
||||
{ ATG::HelpID::MENU_BUTTON, L"Show/Hide Help" },
|
||||
{ ATG::HelpID::VIEW_BUTTON, L"Exit" },
|
||||
{ ATG::HelpID::LEFT_STICK, L"Pan Viewport" },
|
||||
{ ATG::HelpID::RIGHT_STICK, L"Zoom Viewport" },
|
||||
{ ATG::HelpID::RIGHT_TRIGGER, L"Increase Zoom Speed" },
|
||||
{ ATG::HelpID::A_BUTTON, L"Toggle Async Compute" },
|
||||
{ ATG::HelpID::Y_BUTTON, L"Reset Viewport to Default" },
|
||||
};
|
||||
|
||||
const D3D12_SAMPLER_DESC s_samplerType[] =
|
||||
{
|
||||
// MinMagMipPointUVWClamp
|
||||
{
|
||||
D3D12_FILTER_MIN_MAG_MIP_POINT, // Filter mode
|
||||
D3D12_TEXTURE_ADDRESS_MODE_CLAMP, // U address clamping
|
||||
D3D12_TEXTURE_ADDRESS_MODE_CLAMP, // V address clamping
|
||||
D3D12_TEXTURE_ADDRESS_MODE_CLAMP, // W address clamping
|
||||
0.0F, // Mip LOD bias
|
||||
0, // Max Anisotropy - applies if using ANISOTROPIC filtering only
|
||||
D3D12_COMPARISON_FUNC_ALWAYS, // Comparison Func - always pass
|
||||
{ 0.0F, 0.0F, 0.0F, 0.0F }, // BorderColor float values - used if TEXTURE_ADDRESS_BORDER is set.
|
||||
0.0F, // MinLOD
|
||||
D3D12_FLOAT32_MAX // MaxLOD
|
||||
},
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Inserts a resource transition operation in the command list
|
||||
//--------------------------------------------------------------------------------------
|
||||
void ResourceBarrier(_In_ ID3D12GraphicsCommandList* pCmdList, _In_ ID3D12Resource* pResource, D3D12_RESOURCE_STATES Before, D3D12_RESOURCE_STATES After, D3D12_RESOURCE_BARRIER_FLAGS Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE)
|
||||
{
|
||||
D3D12_RESOURCE_BARRIER barrierDesc = {};
|
||||
|
||||
barrierDesc.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||
barrierDesc.Flags = Flags;
|
||||
barrierDesc.Transition.pResource = pResource;
|
||||
barrierDesc.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
|
||||
barrierDesc.Transition.StateBefore = Before;
|
||||
barrierDesc.Transition.StateAfter = After;
|
||||
|
||||
pCmdList->ResourceBarrier(1, &barrierDesc);
|
||||
}
|
||||
}
|
||||
|
||||
Sample::Sample() :
|
||||
m_showHelp(false),
|
||||
m_gamepadPresent(false),
|
||||
m_usingAsyncCompute(false),
|
||||
m_renderIndex(0),
|
||||
m_terminateThread(false),
|
||||
m_fractalMaxIterations(300)
|
||||
{
|
||||
// Renders only 2D, so no need for a depth buffer.
|
||||
m_deviceResources = std::make_unique<DX::DeviceResources>(DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN);
|
||||
m_deviceResources->RegisterDeviceNotify(this);
|
||||
|
||||
m_help = std::make_unique<ATG::Help>(g_SampleTitle, g_SampleDescription, g_HelpButtons, _countof(g_HelpButtons));
|
||||
}
|
||||
|
||||
// Initialize the Direct3D resources required to run.
|
||||
void Sample::Initialize(::IUnknown* window, int width, int height, DXGI_MODE_ROTATION rotation)
|
||||
{
|
||||
ResetWindow();
|
||||
|
||||
m_gamePad = std::make_unique<GamePad>();
|
||||
|
||||
m_keyboard = std::make_unique<Keyboard>();
|
||||
m_keyboard->SetWindow(reinterpret_cast<ABI::Windows::UI::Core::ICoreWindow*>(window));
|
||||
|
||||
m_mouse = std::make_unique<Mouse>();
|
||||
m_mouse->SetWindow(reinterpret_cast<ABI::Windows::UI::Core::ICoreWindow*>(window));
|
||||
|
||||
m_deviceResources->SetWindow(window, width, height, rotation);
|
||||
|
||||
m_deviceResources->CreateDeviceResources();
|
||||
CreateDeviceDependentResources();
|
||||
|
||||
m_deviceResources->CreateWindowSizeDependentResources();
|
||||
CreateWindowSizeDependentResources();
|
||||
|
||||
m_computeThread = new std::thread(&Sample::AsyncComputeThreadProc, this);
|
||||
|
||||
}
|
||||
|
||||
#pragma region Frame Update
|
||||
// Executes basic render loop.
|
||||
void Sample::Tick()
|
||||
{
|
||||
m_timer.Tick([&]()
|
||||
{
|
||||
Update(m_timer);
|
||||
});
|
||||
|
||||
Render();
|
||||
}
|
||||
|
||||
// Updates the world.
|
||||
void Sample::Update(DX::StepTimer const& timer)
|
||||
{
|
||||
PIXBeginEvent(PIX_COLOR_DEFAULT, L"Update");
|
||||
|
||||
float elapsedTime = float(timer.GetElapsedSeconds());
|
||||
|
||||
m_renderFPS.Tick(elapsedTime);
|
||||
|
||||
auto pad = m_gamePad->GetState(0);
|
||||
m_gamepadPresent = pad.IsConnected();
|
||||
if (m_gamepadPresent)
|
||||
{
|
||||
m_gamePadButtons.Update(pad);
|
||||
|
||||
if (m_gamePadButtons.menu == GamePad::ButtonStateTracker::PRESSED)
|
||||
{
|
||||
m_showHelp = !m_showHelp;
|
||||
}
|
||||
else if (m_showHelp && m_gamePadButtons.b == GamePad::ButtonStateTracker::PRESSED)
|
||||
{
|
||||
m_showHelp = false;
|
||||
}
|
||||
|
||||
if (!m_showHelp)
|
||||
{
|
||||
if (pad.IsViewPressed())
|
||||
{
|
||||
ExitSample();
|
||||
}
|
||||
|
||||
if ((m_gamePadButtons.a == DirectX::GamePad::ButtonStateTracker::PRESSED))
|
||||
{
|
||||
m_usingAsyncCompute = !m_usingAsyncCompute;
|
||||
}
|
||||
const float ThumbLeftX = pad.thumbSticks.leftX;
|
||||
const float ThumbLeftY = pad.thumbSticks.leftY;
|
||||
const float ThumbRightY = pad.thumbSticks.rightY;
|
||||
const float RightTrigger = m_gamePadButtons.rightTrigger == DirectX::GamePad::ButtonStateTracker::HELD;
|
||||
|
||||
if (m_gamePadButtons.y == DirectX::GamePad::ButtonStateTracker::PRESSED)
|
||||
{
|
||||
ResetWindow();
|
||||
}
|
||||
|
||||
if (ThumbLeftX != 0.0f || ThumbLeftY != 0.0f || ThumbRightY != 0.0f)
|
||||
{
|
||||
const float ScaleSpeed = 1.0f + RightTrigger * 4.0f;
|
||||
const float WindowScale = 1.0f + ThumbRightY * -0.25f * ScaleSpeed * elapsedTime;
|
||||
m_window.x *= WindowScale;
|
||||
m_window.y *= WindowScale;
|
||||
m_window.z += m_window.x * ThumbLeftX * elapsedTime * 0.5f;
|
||||
m_window.w += m_window.y * ThumbLeftY * elapsedTime * 0.5f;
|
||||
m_windowUpdated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_gamePadButtons.Reset();
|
||||
}
|
||||
|
||||
auto kb = m_keyboard->GetState();
|
||||
m_keyboardButtons.Update(kb);
|
||||
|
||||
if (m_keyboardButtons.IsKeyPressed(Keyboard::F1))
|
||||
{
|
||||
m_showHelp = !m_showHelp;
|
||||
}
|
||||
else if (m_showHelp && kb.Escape)
|
||||
{
|
||||
m_showHelp = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_keyboardButtons.IsKeyPressed(Keyboard::Escape))
|
||||
{
|
||||
ExitSample();
|
||||
}
|
||||
|
||||
if (m_keyboardButtons.IsKeyPressed(Keyboard::Space))
|
||||
{
|
||||
m_usingAsyncCompute = !m_usingAsyncCompute;
|
||||
}
|
||||
|
||||
if (m_keyboardButtons.IsKeyPressed(Keyboard::Home))
|
||||
{
|
||||
ResetWindow();
|
||||
}
|
||||
|
||||
if (kb.W || kb.S || kb.A || kb.D || kb.PageUp || kb.PageDown)
|
||||
{
|
||||
const float ScaleSpeed = (kb.LeftShift || kb.RightShift) ? 4.f : 1.f;
|
||||
|
||||
float zoom = kb.PageDown ? 1.f : (kb.PageUp ? -1.f : 0.f);
|
||||
float x = kb.D ? 1.f : (kb.A ? -1.f : 0.f);
|
||||
float y = kb.W ? 1.f : (kb.S ? -1.f : 0.f);
|
||||
|
||||
const float WindowScale = 1.0f + zoom * ScaleSpeed * elapsedTime;
|
||||
m_window.x *= WindowScale;
|
||||
m_window.y *= WindowScale;
|
||||
m_window.z += m_window.x * x * elapsedTime * 0.5f;
|
||||
m_window.w += m_window.y * y * elapsedTime * 0.5f;
|
||||
m_windowUpdated = true;
|
||||
}
|
||||
}
|
||||
|
||||
PIXEndEvent();
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Frame Render
|
||||
// Draws the scene.
|
||||
void Sample::Render()
|
||||
{
|
||||
// Don't try to render anything before the first Update.
|
||||
if (m_timer.GetFrameCount() == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepare the command list to render a new frame.
|
||||
m_deviceResources->Prepare();
|
||||
Clear();
|
||||
|
||||
auto commandList = m_deviceResources->GetCommandList();
|
||||
|
||||
// Flip colors for which async compute buffer is being rendered
|
||||
PIXBeginEvent(commandList, m_renderIndex ? PIX_COLOR(0, 0, 255) : PIX_COLOR(0, 255, 0), L"Render");
|
||||
|
||||
if (m_showHelp)
|
||||
{
|
||||
m_help->Render(commandList);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!m_usingAsyncCompute) // the user has requested synchronous compute
|
||||
{ // add the compute work to the main command list
|
||||
if (m_windowUpdated)
|
||||
{
|
||||
UpdateFractalData();
|
||||
|
||||
ID3D12DescriptorHeap* pHeaps[] = { m_SRVDescriptorHeap->Heap(), m_samplerDescriptorHeap->Heap() };
|
||||
commandList->SetDescriptorHeaps(_countof(pHeaps), pHeaps);
|
||||
|
||||
EnsureResourceState(ComputeIndex(), D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
|
||||
m_resourceState[ComputeIndex()] = ResourceState_Computing;
|
||||
|
||||
commandList->SetComputeRootSignature(m_computeRootSignature.Get());
|
||||
|
||||
commandList->SetComputeRootConstantBufferView(e_rootParameterCB, m_renderHeap.GpuAddress());
|
||||
commandList->SetComputeRootDescriptorTable(e_rootParameterSampler, m_samplerDescriptorHeap->GetGpuHandle(0));
|
||||
commandList->SetComputeRootDescriptorTable(e_rootParameterSRV, m_SRVDescriptorHeap->GetGpuHandle(e_iSRV + 2)); // sampler texture, gradient
|
||||
commandList->SetComputeRootDescriptorTable(e_rootParameterUAV, m_SRVDescriptorHeap->GetGpuHandle(e_iUAV + ComputeIndex()));
|
||||
|
||||
commandList->SetPipelineState(m_computePSO.Get());
|
||||
commandList->Dispatch(m_ThreadGroupX, m_ThreadGroupY, 1);
|
||||
|
||||
m_resourceState[ComputeIndex()] = ResourceState_Computed;
|
||||
SwapRenderComputeIndex();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_resourceState[ComputeIndex()] == ResourceState_Computed) // async has finished with an update, so swap out the buffers
|
||||
{
|
||||
m_renderResourceFenceValue++;
|
||||
EnsureResourceState(RenderIndex(), D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
|
||||
m_resourceState[RenderIndex()] = ResourceState_Switching;
|
||||
SwapRenderComputeIndex();
|
||||
}
|
||||
else if (m_resourceState[ComputeIndex()] == ResourceState_Switching) // the compute buffer has finished being swapped from a pixel shader view to an unordered access view
|
||||
{ // it's now ready for the async compute thread to use
|
||||
m_resourceState[ComputeIndex()] = ResourceState_ReadyCompute;
|
||||
}
|
||||
else if (m_resourceState[ComputeIndex()] == ResourceState_ReadyCompute) // the async compute thread hasn't kicked off and starting using the compute buffer
|
||||
{
|
||||
// do nothing, still waiting on async compute to actually do work
|
||||
}
|
||||
else if (m_windowUpdated) // need to kick off a new async compute, the user has changed the view area with the controller
|
||||
{
|
||||
assert((m_resourceState[RenderIndex()] == ResourceState_ReadyCompute) || (m_resourceState[RenderIndex()] == ResourceState_Rendered));
|
||||
m_renderResourceFenceValue++;
|
||||
EnsureResourceState(RenderIndex(), D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
|
||||
m_resourceState[RenderIndex()] = ResourceState_Switching;
|
||||
SwapRenderComputeIndex();
|
||||
}
|
||||
}
|
||||
{
|
||||
assert((m_resourceState[RenderIndex()] == ResourceState_Computed) || (m_resourceState[RenderIndex()] == ResourceState_Rendered));
|
||||
RECT outputSize = m_deviceResources->GetOutputSize();
|
||||
|
||||
m_resourceState[RenderIndex()] = ResourceState_Rendering;
|
||||
EnsureResourceState(RenderIndex(), D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
|
||||
|
||||
ID3D12DescriptorHeap* pHeaps[] = { m_SRVDescriptorHeap->Heap(), m_samplerDescriptorHeap->Heap() };
|
||||
commandList->SetDescriptorHeaps(_countof(pHeaps), pHeaps);
|
||||
|
||||
m_spriteBatch->Begin(commandList);
|
||||
XMUINT2 texSize(outputSize.right, outputSize.bottom);
|
||||
XMFLOAT2 texLoc(0, 0);
|
||||
auto textureSRV = m_SRVDescriptorHeap->GetGpuHandle(e_iSRV + RenderIndex());
|
||||
m_spriteBatch->Draw(textureSRV, texSize, texLoc);
|
||||
m_spriteBatch->End();
|
||||
|
||||
pHeaps[0] = m_resourceDescriptors->Heap();
|
||||
commandList->SetDescriptorHeaps(1, pHeaps);
|
||||
|
||||
m_spriteBatch->Begin(commandList);
|
||||
|
||||
{
|
||||
RECT safeRect = SimpleMath::Viewport::ComputeTitleSafeArea(outputSize.right, outputSize.bottom);
|
||||
XMFLOAT2 pos(float(safeRect.left), float(safeRect.top));
|
||||
|
||||
wchar_t outputString[256] = {};
|
||||
swprintf_s(outputString, 256, L"Simple Compute Context %0.2f fps", m_renderFPS.GetFPS());
|
||||
|
||||
m_font->DrawString(m_spriteBatch.get(), outputString, pos);
|
||||
pos.y += m_font->GetLineSpacing();
|
||||
if (m_usingAsyncCompute)
|
||||
{
|
||||
swprintf_s(outputString, 256, L"Asynchronous compute %0.2f fps", m_computeFPS.GetFPS());
|
||||
m_font->DrawString(m_spriteBatch.get(), outputString, pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
swprintf_s(outputString, 256, L"Synchronous compute %0.2f fps", m_renderFPS.GetFPS());
|
||||
m_font->DrawString(m_spriteBatch.get(), outputString, pos);
|
||||
}
|
||||
|
||||
const wchar_t* legend = m_gamepadPresent
|
||||
? L"[A] Toggle asynchronous vs. synchronous [View] Exit [Menu] Help"
|
||||
: L"WASD: Pan viewport PageUp/Down: Zoom viewport Space: Toggle async Esc: Exit";
|
||||
|
||||
DX::DrawControllerString(m_spriteBatch.get(), m_font.get(), m_ctrlFont.get(),
|
||||
legend,
|
||||
XMFLOAT2(float(safeRect.left), float(safeRect.bottom) - m_font->GetLineSpacing()));
|
||||
}
|
||||
m_spriteBatch->End();
|
||||
}
|
||||
}
|
||||
|
||||
PIXEndEvent(commandList);
|
||||
|
||||
// Show the new frame.
|
||||
PIXBeginEvent(m_deviceResources->GetCommandQueue(), PIX_COLOR_DEFAULT, L"Present");
|
||||
m_deviceResources->Present();
|
||||
|
||||
// insert a fence for the frame, this allows the compute thread to grab the compute buffer as soon as the view is changed to unordered access
|
||||
auto commandQueue = m_deviceResources->GetCommandQueue();
|
||||
commandQueue->Signal(m_renderResourceFence.Get(), m_renderResourceFenceValue);
|
||||
|
||||
m_graphicsMemory->Commit(m_deviceResources->GetCommandQueue());
|
||||
m_resourceState[RenderIndex()] = ResourceState_Rendered;
|
||||
|
||||
PIXEndEvent(commandQueue);
|
||||
}
|
||||
|
||||
// Helper method to clear the back buffers.
|
||||
void Sample::Clear()
|
||||
{
|
||||
auto commandList = m_deviceResources->GetCommandList();
|
||||
PIXBeginEvent(commandList, PIX_COLOR_DEFAULT, L"Clear");
|
||||
|
||||
// Clear the views.
|
||||
auto rtvDescriptor = m_deviceResources->GetRenderTargetView();
|
||||
|
||||
commandList->OMSetRenderTargets(1, &rtvDescriptor, FALSE, nullptr);
|
||||
commandList->ClearRenderTargetView(rtvDescriptor, ATG::Colors::Background, 0, nullptr);
|
||||
|
||||
// Set the viewport and scissor rect.
|
||||
auto viewport = m_deviceResources->GetScreenViewport();
|
||||
auto scissorRect = m_deviceResources->GetScissorRect();
|
||||
commandList->RSSetViewports(1, &viewport);
|
||||
commandList->RSSetScissorRects(1, &scissorRect);
|
||||
|
||||
PIXEndEvent(commandList);
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Message Handlers
|
||||
// Message handlers
|
||||
void Sample::OnActivated()
|
||||
{
|
||||
}
|
||||
|
||||
void Sample::OnDeactivated()
|
||||
{
|
||||
}
|
||||
|
||||
void Sample::OnSuspending()
|
||||
{
|
||||
}
|
||||
|
||||
void Sample::OnResuming()
|
||||
{
|
||||
m_timer.ResetElapsedTime();
|
||||
m_gamePadButtons.Reset();
|
||||
m_keyboardButtons.Reset();
|
||||
}
|
||||
|
||||
void Sample::OnWindowSizeChanged(int width, int height, DXGI_MODE_ROTATION rotation)
|
||||
{
|
||||
if (!m_deviceResources->WindowSizeChanged(width, height, rotation))
|
||||
return;
|
||||
|
||||
CreateWindowSizeDependentResources();
|
||||
}
|
||||
|
||||
void Sample::ValidateDevice()
|
||||
{
|
||||
m_deviceResources->ValidateDevice();
|
||||
}
|
||||
|
||||
// Properties
|
||||
void Sample::GetDefaultSize(int& width, int& height) const
|
||||
{
|
||||
width = 1280;
|
||||
height = 720;
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Direct3D Resources
|
||||
// These are the resources that depend on the device.
|
||||
void Sample::CreateDeviceDependentResources()
|
||||
{
|
||||
auto device = m_deviceResources->GetD3DDevice();
|
||||
auto commandList = m_deviceResources->GetCommandList();
|
||||
commandList->Reset(m_deviceResources->GetCommandAllocator(), nullptr);
|
||||
m_graphicsMemory = std::make_unique<GraphicsMemory>(device);
|
||||
|
||||
m_resourceState[0] = m_resourceState[1] = ResourceState_ReadyCompute;
|
||||
|
||||
m_resourceDescriptors = std::make_unique<DescriptorHeap>(device,
|
||||
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
|
||||
D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE,
|
||||
Descriptors::Count);
|
||||
|
||||
// create compute fence and event
|
||||
m_computeFenceEvent.Attach(CreateEventEx(nullptr, FALSE, FALSE, EVENT_ALL_ACCESS));
|
||||
if (!m_computeFenceEvent.IsValid())
|
||||
{
|
||||
throw std::exception("CreateEvent");
|
||||
}
|
||||
|
||||
DX::ThrowIfFailed(
|
||||
device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(m_computeFence.ReleaseAndGetAddressOf())));
|
||||
m_computeFence->SetName(L"Compute");
|
||||
m_computeFenceValue = 1;
|
||||
|
||||
DX::ThrowIfFailed(
|
||||
device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(m_renderResourceFence.ReleaseAndGetAddressOf())));
|
||||
m_renderResourceFence->SetName(L"Resource");
|
||||
m_renderResourceFenceValue = 1;
|
||||
|
||||
// Initialize resource and descriptor heaps
|
||||
m_renderHeap = GraphicsMemory::Get().Allocate((size_t)(4 * 1024));
|
||||
m_computeHeap = GraphicsMemory::Get().Allocate((size_t)(4 * 1024));
|
||||
|
||||
// sampler setup
|
||||
{
|
||||
m_samplerDescriptorHeap = std::make_unique<DescriptorHeap>(device,
|
||||
D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER,
|
||||
D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE,
|
||||
1);
|
||||
device->CreateSampler(s_samplerType, m_samplerDescriptorHeap->GetCpuHandle(0));
|
||||
}
|
||||
|
||||
m_SRVDescriptorHeap = std::make_unique<DescriptorHeap>(device,
|
||||
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
|
||||
D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE,
|
||||
e_iHeapEnd);
|
||||
|
||||
// create fractal texture and views
|
||||
const D3D12_HEAP_PROPERTIES defaultHeapProperties = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT);
|
||||
const D3D12_RESOURCE_DESC texDesc = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8G8B8A8_UNORM, 1920, 1080, 1, 1, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS);
|
||||
m_resourceStateFractalTexture[0] = D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
|
||||
DX::ThrowIfFailed(
|
||||
device->CreateCommittedResource(
|
||||
&defaultHeapProperties,
|
||||
D3D12_HEAP_FLAG_NONE,
|
||||
&texDesc,
|
||||
m_resourceStateFractalTexture[0],
|
||||
nullptr,
|
||||
IID_PPV_ARGS(m_fractalTexture[0].ReleaseAndGetAddressOf())));
|
||||
m_fractalTexture[0]->SetName(L"Fractal Texture 0");
|
||||
|
||||
m_resourceStateFractalTexture[1] = D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
|
||||
DX::ThrowIfFailed(
|
||||
device->CreateCommittedResource(
|
||||
&defaultHeapProperties,
|
||||
D3D12_HEAP_FLAG_NONE,
|
||||
&texDesc,
|
||||
m_resourceStateFractalTexture[1],
|
||||
nullptr,
|
||||
IID_PPV_ARGS(m_fractalTexture[1].ReleaseAndGetAddressOf())));
|
||||
m_fractalTexture[1]->SetName(L"Fractal Texture 1");
|
||||
|
||||
m_ThreadGroupX = static_cast<uint32_t>(texDesc.Width) / s_numShaderThreads;
|
||||
m_ThreadGroupY = texDesc.Height / s_numShaderThreads;
|
||||
|
||||
// create gradient textures
|
||||
const uint32_t GradientTexels[] = { 0xFF000040, 0xFF000080, 0xFF0000C0, 0xFF0000FF, 0xFF0040FF, 0xFF0080FF, 0xFF00C0FF, 0xFF00FFFF };
|
||||
const uint32_t RainbowTexels[] = { 0xFF0000FF, 0xFF0080FF, 0xFF00FFFF, 0xFF00FF00, 0xFFFFFF00, 0xFFFF0000, 0xFF800000, 0xFFFF00FF };
|
||||
static_assert(sizeof(RainbowTexels) == sizeof(GradientTexels), "Mismatched size");
|
||||
|
||||
const D3D12_RESOURCE_DESC gradientTexDesc = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8G8B8A8_UNORM, 8, 1, 1, 1);
|
||||
DX::ThrowIfFailed(
|
||||
device->CreateCommittedResource(
|
||||
&defaultHeapProperties,
|
||||
D3D12_HEAP_FLAG_NONE,
|
||||
&gradientTexDesc,
|
||||
D3D12_RESOURCE_STATE_COMMON,
|
||||
nullptr,
|
||||
IID_PPV_ARGS(m_fractalColorMap[0].ReleaseAndGetAddressOf())));
|
||||
m_fractalColorMap[0]->SetName(L"Fractal Color Map 0");
|
||||
|
||||
DX::ThrowIfFailed(
|
||||
device->CreateCommittedResource(
|
||||
&defaultHeapProperties,
|
||||
D3D12_HEAP_FLAG_NONE,
|
||||
&gradientTexDesc,
|
||||
D3D12_RESOURCE_STATE_COMMON,
|
||||
nullptr,
|
||||
IID_PPV_ARGS(m_fractalColorMap[1].ReleaseAndGetAddressOf())));
|
||||
m_fractalColorMap[1]->SetName(L"Fractal Color Map 1");
|
||||
|
||||
Microsoft::WRL::ComPtr<ID3D12Resource> colorMapIntermediate[2];
|
||||
{
|
||||
CD3DX12_HEAP_PROPERTIES heapProps(D3D12_HEAP_TYPE_UPLOAD);
|
||||
|
||||
D3D12_RESOURCE_ALLOCATION_INFO info = {};
|
||||
info.SizeInBytes = 1024;
|
||||
info.Alignment = 0;
|
||||
const D3D12_RESOURCE_DESC tempBufferDesc = CD3DX12_RESOURCE_DESC::Buffer(info);
|
||||
DX::ThrowIfFailed(
|
||||
device->CreateCommittedResource(
|
||||
&heapProps,
|
||||
D3D12_HEAP_FLAG_NONE,
|
||||
&tempBufferDesc,
|
||||
D3D12_RESOURCE_STATE_GENERIC_READ,
|
||||
nullptr,
|
||||
IID_PPV_ARGS(colorMapIntermediate[0].ReleaseAndGetAddressOf())));
|
||||
|
||||
DX::ThrowIfFailed(
|
||||
device->CreateCommittedResource(
|
||||
&heapProps,
|
||||
D3D12_HEAP_FLAG_NONE,
|
||||
&tempBufferDesc,
|
||||
D3D12_RESOURCE_STATE_GENERIC_READ,
|
||||
nullptr,
|
||||
IID_PPV_ARGS(colorMapIntermediate[1].ReleaseAndGetAddressOf())));
|
||||
|
||||
CD3DX12_SUBRESOURCE_FOOTPRINT descSubresource(gradientTexDesc, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
|
||||
ResourceBarrier(commandList, m_fractalColorMap[0].Get(), D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_COPY_DEST);
|
||||
|
||||
D3D12_SUBRESOURCE_DATA textureData = {};
|
||||
textureData.pData = GradientTexels;
|
||||
textureData.RowPitch = static_cast<LONG_PTR>(gradientTexDesc.Width * sizeof(uint32_t));
|
||||
textureData.SlicePitch = 1;
|
||||
UpdateSubresources(commandList, m_fractalColorMap[0].Get(), colorMapIntermediate[0].Get(), 0, 0, 1, &textureData);
|
||||
|
||||
ResourceBarrier(commandList, m_fractalColorMap[0].Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
|
||||
|
||||
textureData.pData = RainbowTexels;
|
||||
ResourceBarrier(commandList, m_fractalColorMap[1].Get(), D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_COPY_DEST);
|
||||
UpdateSubresources(commandList, m_fractalColorMap[1].Get(), colorMapIntermediate[1].Get(), 0, 0, 1, &textureData);
|
||||
ResourceBarrier(commandList, m_fractalColorMap[1].Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
|
||||
}
|
||||
|
||||
// create uav
|
||||
device->CreateUnorderedAccessView(m_fractalTexture[0].Get(), nullptr, nullptr, m_SRVDescriptorHeap->GetCpuHandle(e_iUAV));
|
||||
device->CreateUnorderedAccessView(m_fractalTexture[1].Get(), nullptr, nullptr, m_SRVDescriptorHeap->GetCpuHandle(e_iUAV + 1));
|
||||
|
||||
// create srv
|
||||
device->CreateShaderResourceView(m_fractalTexture[0].Get(), nullptr, m_SRVDescriptorHeap->GetCpuHandle(e_iSRV));
|
||||
device->CreateShaderResourceView(m_fractalTexture[1].Get(), nullptr, m_SRVDescriptorHeap->GetCpuHandle(e_iSRV + 1));
|
||||
device->CreateShaderResourceView(m_fractalColorMap[0].Get(), nullptr, m_SRVDescriptorHeap->GetCpuHandle(e_iSRV + 2));
|
||||
device->CreateShaderResourceView(m_fractalColorMap[1].Get(), nullptr, m_SRVDescriptorHeap->GetCpuHandle(e_iSRV + 3));
|
||||
|
||||
// load fractal shader
|
||||
auto computeShaderBlob = DX::ReadData(L"Fractal.cso");
|
||||
|
||||
// Define root table layout
|
||||
CD3DX12_DESCRIPTOR_RANGE descRange[e_numRootParameters];
|
||||
descRange[e_rootParameterSampler].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 1, 0); // s0
|
||||
descRange[e_rootParameterSRV].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0); // t0
|
||||
descRange[e_rootParameterUAV].Init(D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 1, 0); // u0
|
||||
|
||||
CD3DX12_ROOT_PARAMETER rootParameters[e_numRootParameters];
|
||||
rootParameters[e_rootParameterCB].InitAsConstantBufferView(0, 0, D3D12_SHADER_VISIBILITY_ALL);
|
||||
rootParameters[e_rootParameterSampler].InitAsDescriptorTable(1, &descRange[e_rootParameterSampler], D3D12_SHADER_VISIBILITY_ALL);
|
||||
rootParameters[e_rootParameterSRV].InitAsDescriptorTable(1, &descRange[e_rootParameterSRV], D3D12_SHADER_VISIBILITY_ALL);
|
||||
rootParameters[e_rootParameterUAV].InitAsDescriptorTable(1, &descRange[e_rootParameterUAV], D3D12_SHADER_VISIBILITY_ALL);
|
||||
|
||||
CD3DX12_ROOT_SIGNATURE_DESC rootSignature(_countof(rootParameters), rootParameters);
|
||||
ID3DBlob *spSerializedSignature;
|
||||
DX::ThrowIfFailed(
|
||||
D3D12SerializeRootSignature(&rootSignature, D3D_ROOT_SIGNATURE_VERSION_1, &spSerializedSignature, nullptr));
|
||||
|
||||
// Create the root signature
|
||||
DX::ThrowIfFailed(
|
||||
device->CreateRootSignature(
|
||||
0,
|
||||
spSerializedSignature->GetBufferPointer(),
|
||||
spSerializedSignature->GetBufferSize(),
|
||||
IID_PPV_ARGS(m_computeRootSignature.ReleaseAndGetAddressOf())));
|
||||
m_computeRootSignature->SetName(L"Compute RS");
|
||||
|
||||
// Create compute pipeline state
|
||||
D3D12_COMPUTE_PIPELINE_STATE_DESC descComputePSO = {};
|
||||
descComputePSO.pRootSignature = m_computeRootSignature.Get();
|
||||
descComputePSO.CS.pShaderBytecode = computeShaderBlob.data();
|
||||
descComputePSO.CS.BytecodeLength = computeShaderBlob.size();
|
||||
|
||||
DX::ThrowIfFailed(
|
||||
device->CreateComputePipelineState(&descComputePSO, IID_PPV_ARGS(m_computePSO.ReleaseAndGetAddressOf())));
|
||||
m_computePSO->SetName(L"Compute PSO");
|
||||
|
||||
// Create compute allocator, command queue and command list
|
||||
D3D12_COMMAND_QUEUE_DESC descCommandQueue = { D3D12_COMMAND_LIST_TYPE_COMPUTE, 0, D3D12_COMMAND_QUEUE_FLAG_NONE };
|
||||
DX::ThrowIfFailed(
|
||||
device->CreateCommandQueue(&descCommandQueue, IID_PPV_ARGS(m_computeCommandQueue.ReleaseAndGetAddressOf())));
|
||||
|
||||
DX::ThrowIfFailed(
|
||||
device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_COMPUTE, IID_PPV_ARGS(m_computeAllocator.ReleaseAndGetAddressOf())));
|
||||
|
||||
DX::ThrowIfFailed(
|
||||
device->CreateCommandList(
|
||||
0,
|
||||
D3D12_COMMAND_LIST_TYPE_COMPUTE,
|
||||
m_computeAllocator.Get(),
|
||||
m_computePSO.Get(),
|
||||
IID_PPV_ARGS(m_computeCommandList.ReleaseAndGetAddressOf())));
|
||||
|
||||
commandList->Close();
|
||||
m_deviceResources->GetCommandQueue()->ExecuteCommandLists(1, CommandListCast(&commandList));
|
||||
|
||||
// Wait until assets have been uploaded to the GPU.
|
||||
m_deviceResources->WaitForGpu();
|
||||
|
||||
ResourceUploadBatch resourceUpload(device);
|
||||
|
||||
resourceUpload.Begin();
|
||||
|
||||
{
|
||||
RenderTargetState rtState(m_deviceResources->GetBackBufferFormat(), m_deviceResources->GetDepthBufferFormat());
|
||||
SpriteBatchPipelineStateDescription pd(rtState);
|
||||
|
||||
m_spriteBatch = std::make_unique<SpriteBatch>(device, resourceUpload, pd);
|
||||
}
|
||||
|
||||
{
|
||||
m_font = std::make_unique<SpriteFont>(device, resourceUpload,
|
||||
L"SegoeUI_18.spritefont",
|
||||
m_resourceDescriptors->GetCpuHandle(Descriptors::TextFont),
|
||||
m_resourceDescriptors->GetGpuHandle(Descriptors::TextFont));
|
||||
m_ctrlFont = std::make_unique<SpriteFont>(device, resourceUpload,
|
||||
L"XboxOneControllerLegendSmall.spritefont",
|
||||
m_resourceDescriptors->GetCpuHandle(Descriptors::ControllerFont),
|
||||
m_resourceDescriptors->GetGpuHandle(Descriptors::ControllerFont));
|
||||
|
||||
auto uploadResourcesFinished = resourceUpload.End(m_deviceResources->GetCommandQueue());
|
||||
uploadResourcesFinished.wait();
|
||||
}
|
||||
|
||||
{
|
||||
RenderTargetState rtState(m_deviceResources->GetBackBufferFormat(), m_deviceResources->GetDepthBufferFormat());
|
||||
ResourceUploadBatch uploadBatch(device);
|
||||
uploadBatch.Begin();
|
||||
|
||||
m_help->RestoreDevice(device, uploadBatch, rtState);
|
||||
|
||||
auto finish = uploadBatch.End(m_deviceResources->GetCommandQueue());
|
||||
finish.wait();
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate all memory resources that change on a window SizeChanged event.
|
||||
void Sample::CreateWindowSizeDependentResources()
|
||||
{
|
||||
auto size = m_deviceResources->GetOutputSize();
|
||||
m_help->SetWindow(size);
|
||||
|
||||
auto viewport = m_deviceResources->GetScreenViewport();
|
||||
m_spriteBatch->SetViewport(viewport);
|
||||
}
|
||||
|
||||
void Sample::OnDeviceLost()
|
||||
{
|
||||
m_spriteBatch.reset();
|
||||
m_font.reset();
|
||||
m_ctrlFont.reset();
|
||||
m_resourceDescriptors.reset();
|
||||
|
||||
m_computePSO.Reset();
|
||||
m_computeRootSignature.Reset();
|
||||
m_computeAllocator.Reset();
|
||||
m_computeCommandQueue.Reset();
|
||||
m_computeCommandList.Reset();
|
||||
|
||||
m_computeFenceEvent.Close();
|
||||
|
||||
m_computeFence.Reset();
|
||||
m_renderResourceFence.Reset();
|
||||
|
||||
m_fractalColorMap[0].Reset();
|
||||
m_fractalColorMap[1].Reset();
|
||||
m_fractalTexture[0].Reset();
|
||||
m_fractalTexture[1].Reset();
|
||||
|
||||
m_renderHeap.Reset();
|
||||
m_computeHeap.Reset();
|
||||
|
||||
m_SRVDescriptorHeap.reset();
|
||||
m_samplerDescriptorHeap.reset();
|
||||
|
||||
m_help->ReleaseDevice();
|
||||
|
||||
m_graphicsMemory.reset();
|
||||
}
|
||||
|
||||
void Sample::OnDeviceRestored()
|
||||
{
|
||||
CreateDeviceDependentResources();
|
||||
|
||||
CreateWindowSizeDependentResources();
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
void Sample::ResetWindow()
|
||||
{
|
||||
m_window = XMFLOAT4(4.0f, 2.25f, -0.65f, 0.0f);
|
||||
m_windowUpdated = true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Name: UpdateFractalData
|
||||
// Desc: Updates the dynamic constant buffer with fractal data
|
||||
//--------------------------------------------------------------------------------------
|
||||
void Sample::UpdateFractalData()
|
||||
{
|
||||
const D3D12_RESOURCE_DESC texDesc = m_fractalTexture[0]->GetDesc();
|
||||
|
||||
SharedGraphicsResource *pUploadHeap = m_usingAsyncCompute ? &m_computeHeap : &m_renderHeap;
|
||||
|
||||
auto pCBFractalData = reinterpret_cast<CB_FractalCS*> (pUploadHeap->Memory());
|
||||
|
||||
pCBFractalData->MaxThreadIter = XMFLOAT4(static_cast<float>(texDesc.Width), static_cast<float>(texDesc.Height), static_cast<float>(m_fractalMaxIterations), 0);
|
||||
pCBFractalData->Window = m_window;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Name: EnsureResourceState
|
||||
// Desc: Ensures the fractal texture is in the desired resource state
|
||||
//--------------------------------------------------------------------------------------
|
||||
_Use_decl_annotations_
|
||||
bool Sample::EnsureResourceState(uint32_t index, D3D12_RESOURCE_STATES afterState)
|
||||
{
|
||||
if (m_resourceStateFractalTexture[index] != afterState)
|
||||
{
|
||||
auto commandList = m_deviceResources->GetCommandList();
|
||||
|
||||
ResourceBarrier(commandList, m_fractalTexture[index].Get(), m_resourceStateFractalTexture[index], afterState);
|
||||
m_resourceStateFractalTexture[index] = afterState;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Sample::AsyncComputeThreadProc()
|
||||
{
|
||||
LARGE_INTEGER PerfFreq;
|
||||
QueryPerformanceFrequency(&PerfFreq);
|
||||
|
||||
LARGE_INTEGER LastFrameTime;
|
||||
QueryPerformanceCounter(&LastFrameTime);
|
||||
|
||||
while (!m_terminateThread)
|
||||
{
|
||||
LARGE_INTEGER CurrentFrameTime;
|
||||
QueryPerformanceCounter(&CurrentFrameTime);
|
||||
double DeltaTime = (double)(CurrentFrameTime.QuadPart - LastFrameTime.QuadPart) / (double)PerfFreq.QuadPart;
|
||||
LastFrameTime = CurrentFrameTime;
|
||||
|
||||
if (m_usingAsyncCompute)
|
||||
{
|
||||
if (m_windowUpdated)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (m_resourceState[ComputeIndex()] == ResourceState_Switching) // render kicked off a resource switch to unordered,
|
||||
{ // check the fence for completed for quickest turn around
|
||||
if (m_renderResourceFence->GetCompletedValue() >= m_renderResourceFenceValue) // render might also check first and switch the state to ready compute
|
||||
{
|
||||
m_resourceState[ComputeIndex()] = ResourceState_ReadyCompute;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (m_resourceState[ComputeIndex()] == ResourceState_ReadyCompute) // render detected compute buffer switched to unordered access first
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (!m_usingAsyncCompute) // user has request synchronous compute
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!m_usingAsyncCompute) // user has request synchronous compute
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
m_computeFPS.Tick(static_cast<FLOAT>(DeltaTime));
|
||||
|
||||
UpdateFractalData();
|
||||
|
||||
// setup the asynchronous compute command list, use a unique command list
|
||||
PIXBeginEvent(m_computeCommandList.Get(), !m_renderIndex ? PIX_COLOR(0, 0, 255) : PIX_COLOR(0, 255, 0), "Compute");
|
||||
|
||||
ID3D12DescriptorHeap* pHeaps[] = { m_SRVDescriptorHeap->Heap(), m_samplerDescriptorHeap->Heap() };
|
||||
m_computeCommandList->SetDescriptorHeaps(_countof(pHeaps), pHeaps);
|
||||
|
||||
m_computeCommandList->SetComputeRootSignature(m_computeRootSignature.Get());
|
||||
|
||||
m_computeCommandList->SetComputeRootConstantBufferView(e_rootParameterCB, m_computeHeap.GpuAddress());
|
||||
m_computeCommandList->SetComputeRootDescriptorTable(e_rootParameterSampler, m_samplerDescriptorHeap->GetGpuHandle(0));
|
||||
m_computeCommandList->SetComputeRootDescriptorTable(e_rootParameterSRV, m_SRVDescriptorHeap->GetGpuHandle(e_iSRV + 3)); // rainbow sampler
|
||||
m_computeCommandList->SetComputeRootDescriptorTable(e_rootParameterUAV, m_SRVDescriptorHeap->GetGpuHandle(e_iUAV + ComputeIndex()));
|
||||
|
||||
m_computeCommandList->SetPipelineState(m_computePSO.Get());
|
||||
m_computeCommandList->Dispatch(m_ThreadGroupX, m_ThreadGroupY, 1);
|
||||
|
||||
PIXEndEvent(m_computeCommandList.Get());
|
||||
|
||||
// close and execute the command list
|
||||
m_computeCommandList->Close();
|
||||
ID3D12CommandList *tempList = m_computeCommandList.Get();
|
||||
m_computeCommandQueue->ExecuteCommandLists(1, &tempList);
|
||||
|
||||
const uint64_t fence = m_computeFenceValue++;
|
||||
m_computeCommandQueue->Signal(m_computeFence.Get(), fence);
|
||||
if (m_computeFence->GetCompletedValue() < fence) // block until async compute has completed using a fence
|
||||
{
|
||||
m_computeFence->SetEventOnCompletion(fence, m_computeFenceEvent.Get());
|
||||
WaitForSingleObject(m_computeFenceEvent.Get(), INFINITE);
|
||||
}
|
||||
m_resourceState[ComputeIndex()] = ResourceState_Computed; // signal the buffer is now ready for render thread to use
|
||||
|
||||
m_computeAllocator->Reset();
|
||||
m_computeCommandList->Reset(m_computeAllocator.Get(), m_computePSO.Get());
|
||||
}
|
||||
else
|
||||
{
|
||||
SwitchToThread();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SwitchToThread();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,226 @@
|
|||
//--------------------------------------------------------------------------------------
|
||||
// SimpleComputeUWP12.h
|
||||
//
|
||||
// Advanced Technology Group (ATG)
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "DeviceResources.h"
|
||||
#include "StepTimer.h"
|
||||
#include "ControllerHelp.h"
|
||||
|
||||
class SmoothedFPS
|
||||
{
|
||||
public:
|
||||
SmoothedFPS(uint32_t frameInterval = 100)
|
||||
{
|
||||
Initialize(frameInterval);
|
||||
}
|
||||
|
||||
void Initialize(uint32_t frameInterval = 100)
|
||||
{
|
||||
m_frameInterval = frameInterval;
|
||||
m_timeAccumulator = 0.0f;
|
||||
m_frameAccumulator = 0;
|
||||
m_smoothedFPS = 0.0f;
|
||||
}
|
||||
|
||||
void Tick(float DeltaTime)
|
||||
{
|
||||
m_timeAccumulator += DeltaTime;
|
||||
++m_frameAccumulator;
|
||||
|
||||
if (m_frameAccumulator >= m_frameInterval)
|
||||
{
|
||||
m_smoothedFPS = (float)m_frameInterval / m_timeAccumulator;
|
||||
m_timeAccumulator = 0.0f;
|
||||
m_frameAccumulator = 0;
|
||||
}
|
||||
}
|
||||
|
||||
float GetFPS() const { return m_smoothedFPS; }
|
||||
|
||||
private:
|
||||
float m_smoothedFPS;
|
||||
float m_timeAccumulator;
|
||||
uint32_t m_frameAccumulator;
|
||||
uint32_t m_frameInterval;
|
||||
};
|
||||
|
||||
// A basic sample implementation that creates a D3D12 device and
|
||||
// provides a render loop.
|
||||
class Sample : public DX::IDeviceNotify
|
||||
{
|
||||
public:
|
||||
|
||||
Sample();
|
||||
|
||||
// Initialization and management
|
||||
void Initialize(::IUnknown* window, int width, int height, DXGI_MODE_ROTATION rotation);
|
||||
|
||||
// Basic render loop
|
||||
void Tick();
|
||||
|
||||
// IDeviceNotify
|
||||
virtual void OnDeviceLost() override;
|
||||
virtual void OnDeviceRestored() override;
|
||||
|
||||
// Messages
|
||||
void OnActivated();
|
||||
void OnDeactivated();
|
||||
void OnSuspending();
|
||||
void OnResuming();
|
||||
void OnWindowSizeChanged(int width, int height, DXGI_MODE_ROTATION rotation);
|
||||
void ValidateDevice();
|
||||
|
||||
// Properties
|
||||
void GetDefaultSize( int& width, int& height ) const;
|
||||
|
||||
private:
|
||||
struct CB_FractalCS
|
||||
{
|
||||
DirectX::XMFLOAT4 MaxThreadIter;
|
||||
DirectX::XMFLOAT4 Window;
|
||||
};
|
||||
struct Vertex
|
||||
{
|
||||
DirectX::XMFLOAT4 position;
|
||||
DirectX::XMFLOAT2 texcoord;
|
||||
};
|
||||
|
||||
void Update(DX::StepTimer const& timer);
|
||||
void Render();
|
||||
|
||||
void Clear();
|
||||
|
||||
void CreateDeviceDependentResources();
|
||||
void CreateWindowSizeDependentResources();
|
||||
|
||||
void ResetWindow();
|
||||
|
||||
void UpdateFractalData();
|
||||
// called by compute side of work, updates the window parameters
|
||||
|
||||
bool EnsureResourceState(_In_range_(0, 1) uint32_t index, D3D12_RESOURCE_STATES afterState);
|
||||
|
||||
void AsyncComputeThreadProc();
|
||||
|
||||
uint32_t ComputeIndex() const { return 1 - m_renderIndex; }
|
||||
uint32_t RenderIndex() const { return m_renderIndex; }
|
||||
void SwapRenderComputeIndex() { m_renderIndex = 1 - m_renderIndex; }
|
||||
|
||||
// Device resources.
|
||||
std::unique_ptr<DX::DeviceResources> m_deviceResources;
|
||||
|
||||
// Rendering loop timer.
|
||||
DX::StepTimer m_timer;
|
||||
|
||||
// on-screen help
|
||||
std::unique_ptr<ATG::Help> m_help;
|
||||
bool m_showHelp;
|
||||
|
||||
// Input devices.
|
||||
std::unique_ptr<DirectX::GamePad> m_gamePad;
|
||||
std::unique_ptr<DirectX::Keyboard> m_keyboard;
|
||||
std::unique_ptr<DirectX::Mouse> m_mouse;
|
||||
|
||||
DirectX::GamePad::ButtonStateTracker m_gamePadButtons;
|
||||
DirectX::Keyboard::KeyboardStateTracker m_keyboardButtons;
|
||||
bool m_gamepadPresent;
|
||||
|
||||
// Compute data
|
||||
uint32_t m_ThreadGroupX;
|
||||
uint32_t m_ThreadGroupY;
|
||||
|
||||
SmoothedFPS m_renderFPS;
|
||||
SmoothedFPS m_computeFPS;
|
||||
|
||||
std::atomic<bool> m_terminateThread;
|
||||
std::thread * m_computeThread;
|
||||
|
||||
std::atomic<uint32_t> m_renderIndex; // which bank of fractal data the renderer is using, the value is either 0 or 1, compute is using the inverse
|
||||
|
||||
CB_FractalCS* m_fractalData; // data for compute shader constant buffer on how many iterations on the Mandelbrot set and the bounds
|
||||
DirectX::XMFLOAT4 m_window; // the bounds for the Mandelbrot set being calculated on the CPU
|
||||
uint32_t m_fractalMaxIterations; // number of iterations when calculating the Mandelbrot set on the CPU
|
||||
std::atomic<bool> m_windowUpdated;
|
||||
|
||||
// shared data
|
||||
std::unique_ptr<DirectX::DescriptorHeap> m_SRVDescriptorHeap; // shader resource views for the fractal texture and data
|
||||
std::unique_ptr<DirectX::DescriptorHeap> m_samplerDescriptorHeap;// shader resource views for the samplers used by the compute shader
|
||||
DirectX::SharedGraphicsResource m_renderHeap; // renderer version of the fractal constant data
|
||||
DirectX::SharedGraphicsResource m_computeHeap; // async compute version of the fractal constant data
|
||||
|
||||
// fractal texture data
|
||||
Microsoft::WRL::ComPtr<ID3D12Resource> m_fractalColorMap[2]; // the textures used by the sampler for coloring the computed fractal, one for sync, one for async
|
||||
Microsoft::WRL::ComPtr<ID3D12Resource> m_fractalTexture[2]; // the actual texture generated by the compute shader, double buffered, async and render operating on opposite textures
|
||||
D3D12_RESOURCE_STATES m_resourceStateFractalTexture[2]; // current state of the fractal texture, unordered or texture view
|
||||
Microsoft::WRL::ComPtr<ID3D12Fence> m_renderResourceFence; // fence used by async compute to start once it's texture has changed to unordered access
|
||||
uint64_t m_renderResourceFenceValue;
|
||||
|
||||
// compute data
|
||||
std::atomic<bool> m_usingAsyncCompute;
|
||||
|
||||
Microsoft::WRL::ComPtr<ID3D12PipelineState> m_computePSO;
|
||||
Microsoft::WRL::ComPtr<ID3D12RootSignature> m_computeRootSignature;
|
||||
Microsoft::WRL::ComPtr<ID3D12CommandAllocator> m_computeAllocator;
|
||||
Microsoft::WRL::ComPtr<ID3D12CommandQueue> m_computeCommandQueue;
|
||||
Microsoft::WRL::ComPtr<ID3D12GraphicsCommandList> m_computeCommandList;
|
||||
|
||||
Microsoft::WRL::ComPtr<ID3D12Fence> m_computeFence; // fence used by the async compute shader to stall waiting for task is complete, so it can signal render when it's done
|
||||
uint64_t m_computeFenceValue;
|
||||
Microsoft::WRL::Wrappers::Event m_computeFenceEvent;
|
||||
|
||||
// DirectXTK objects.
|
||||
std::unique_ptr<DirectX::GraphicsMemory> m_graphicsMemory;
|
||||
std::unique_ptr<DirectX::DescriptorHeap> m_resourceDescriptors;
|
||||
std::unique_ptr<DirectX::SpriteBatch> m_spriteBatch;
|
||||
std::unique_ptr<DirectX::SpriteFont> m_font;
|
||||
std::unique_ptr<DirectX::SpriteFont> m_ctrlFont;
|
||||
|
||||
enum Descriptors
|
||||
{
|
||||
TextFont,
|
||||
ControllerFont,
|
||||
Count
|
||||
};
|
||||
|
||||
enum ResourceBufferState : uint32_t
|
||||
{
|
||||
ResourceState_ReadyCompute,
|
||||
ResourceState_Computing, // async is currently running on this resource buffer
|
||||
ResourceState_Computed, // async buffer has been updated, no one is using it, moved to this state by async thread, only render will access in this state
|
||||
ResourceState_Switching, // switching buffer from texture to unordered, from render to compute access
|
||||
ResourceState_Rendering, // buffer is currently being used by the render system for the frame
|
||||
ResourceState_Rendered // render frame finished for this resource. possible to switch to computing by render thread if needed
|
||||
};
|
||||
|
||||
std::atomic<ResourceBufferState> m_resourceState[2];
|
||||
|
||||
// Indexes for the root parameter table
|
||||
enum RootParameters : uint32_t
|
||||
{
|
||||
e_rootParameterCB = 0,
|
||||
e_rootParameterSampler,
|
||||
e_rootParameterSRV,
|
||||
e_rootParameterUAV,
|
||||
e_numRootParameters
|
||||
};
|
||||
|
||||
// indexes of resources into the descriptor heap
|
||||
enum DescriptorHeapCount : uint32_t
|
||||
{
|
||||
e_cCB = 10,
|
||||
e_cUAV = 2,
|
||||
e_cSRV = 4,
|
||||
};
|
||||
enum DescriptorHeapIndex : uint32_t
|
||||
{
|
||||
e_iCB = 0,
|
||||
e_iUAV = e_iCB + e_cCB,
|
||||
e_iSRV = e_iUAV + e_cUAV,
|
||||
e_iHeapEnd = e_iSRV + e_cSRV
|
||||
};
|
||||
};
|
|
@ -0,0 +1,57 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26730.3
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SimpleComputeUWP12", "SimpleComputeUWP12.vcxproj", "{557759CF-77BD-4774-BFA1-96BA0523A4F6}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DirectXTK12", "..\..\..\Kits\DirectXTK12\DirectXTK_Windows10.vcxproj", "{945B8F0E-AE5F-447C-933A-9D069532D3E4}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|ARM = Debug|ARM
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|ARM = Release|ARM
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{557759CF-77BD-4774-BFA1-96BA0523A4F6}.Debug|ARM.ActiveCfg = Debug|ARM
|
||||
{557759CF-77BD-4774-BFA1-96BA0523A4F6}.Debug|ARM.Build.0 = Debug|ARM
|
||||
{557759CF-77BD-4774-BFA1-96BA0523A4F6}.Debug|ARM.Deploy.0 = Debug|ARM
|
||||
{557759CF-77BD-4774-BFA1-96BA0523A4F6}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{557759CF-77BD-4774-BFA1-96BA0523A4F6}.Debug|x64.Build.0 = Debug|x64
|
||||
{557759CF-77BD-4774-BFA1-96BA0523A4F6}.Debug|x64.Deploy.0 = Debug|x64
|
||||
{557759CF-77BD-4774-BFA1-96BA0523A4F6}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{557759CF-77BD-4774-BFA1-96BA0523A4F6}.Debug|x86.Build.0 = Debug|Win32
|
||||
{557759CF-77BD-4774-BFA1-96BA0523A4F6}.Debug|x86.Deploy.0 = Debug|Win32
|
||||
{557759CF-77BD-4774-BFA1-96BA0523A4F6}.Release|ARM.ActiveCfg = Release|ARM
|
||||
{557759CF-77BD-4774-BFA1-96BA0523A4F6}.Release|ARM.Build.0 = Release|ARM
|
||||
{557759CF-77BD-4774-BFA1-96BA0523A4F6}.Release|ARM.Deploy.0 = Release|ARM
|
||||
{557759CF-77BD-4774-BFA1-96BA0523A4F6}.Release|x64.ActiveCfg = Release|x64
|
||||
{557759CF-77BD-4774-BFA1-96BA0523A4F6}.Release|x64.Build.0 = Release|x64
|
||||
{557759CF-77BD-4774-BFA1-96BA0523A4F6}.Release|x64.Deploy.0 = Release|x64
|
||||
{557759CF-77BD-4774-BFA1-96BA0523A4F6}.Release|x86.ActiveCfg = Release|Win32
|
||||
{557759CF-77BD-4774-BFA1-96BA0523A4F6}.Release|x86.Build.0 = Release|Win32
|
||||
{557759CF-77BD-4774-BFA1-96BA0523A4F6}.Release|x86.Deploy.0 = Release|Win32
|
||||
{945B8F0E-AE5F-447C-933A-9D069532D3E4}.Debug|ARM.ActiveCfg = Debug|ARM
|
||||
{945B8F0E-AE5F-447C-933A-9D069532D3E4}.Debug|ARM.Build.0 = Debug|ARM
|
||||
{945B8F0E-AE5F-447C-933A-9D069532D3E4}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{945B8F0E-AE5F-447C-933A-9D069532D3E4}.Debug|x64.Build.0 = Debug|x64
|
||||
{945B8F0E-AE5F-447C-933A-9D069532D3E4}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{945B8F0E-AE5F-447C-933A-9D069532D3E4}.Debug|x86.Build.0 = Debug|Win32
|
||||
{945B8F0E-AE5F-447C-933A-9D069532D3E4}.Release|ARM.ActiveCfg = Release|ARM
|
||||
{945B8F0E-AE5F-447C-933A-9D069532D3E4}.Release|ARM.Build.0 = Release|ARM
|
||||
{945B8F0E-AE5F-447C-933A-9D069532D3E4}.Release|x64.ActiveCfg = Release|x64
|
||||
{945B8F0E-AE5F-447C-933A-9D069532D3E4}.Release|x64.Build.0 = Release|x64
|
||||
{945B8F0E-AE5F-447C-933A-9D069532D3E4}.Release|x86.ActiveCfg = Release|Win32
|
||||
{945B8F0E-AE5F-447C-933A-9D069532D3E4}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {A23BA710-ACB8-4342-9587-8F1C9AC40D01}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,340 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|ARM">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>ARM</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|ARM">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>ARM</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{557759cf-77bd-4774-bfa1-96ba0523a4f6}</ProjectGuid>
|
||||
<Keyword>DirectXApp</Keyword>
|
||||
<RootNamespace>SimpleComputeUWP12</RootNamespace>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
|
||||
<AppContainerApplication>true</AppContainerApplication>
|
||||
<ApplicationType>Windows Store</ApplicationType>
|
||||
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformMinVersion>10.0.14393.0</WindowsTargetPlatformMinVersion>
|
||||
<ApplicationTypeRevision>10.0</ApplicationTypeRevision>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
<Import Project="$(VSINSTALLDIR)\Common7\IDE\Extensions\Microsoft\VsGraphics\ImageContentTask.props" />
|
||||
<Import Project="$(VSINSTALLDIR)\Common7\IDE\Extensions\Microsoft\VsGraphics\MeshContentTask.props" />
|
||||
<Import Project="$(VSINSTALLDIR)\Common7\IDE\Extensions\Microsoft\VsGraphics\ShaderGraphContentTask.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros">
|
||||
<AppxPackageSigningEnabled>false</AppxPackageSigningEnabled>
|
||||
<AppxSymbolPackageEnabled>false</AppxSymbolPackageEnabled>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
|
||||
<Link>
|
||||
<AdditionalDependencies>ATGTelemetryUWP.lib; d2d1.lib; d3d12.lib; dxgi.lib; dxguid.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\..\Kits\Telemetry\$(Platform); %(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\arm; $(VCInstallDir)\lib\arm</AdditionalLibraryDirectories>
|
||||
<GenerateWindowsMetadata>true</GenerateWindowsMetadata>
|
||||
</Link>
|
||||
<ClCompile>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir);$(IntermediateOutputPath);..\..\..\Kits\DirectXTK12\Inc;..\..\..\Kits\ATGTK;..\..\..\Kits\Telemetry;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
</ClCompile>
|
||||
<FXCompile>
|
||||
<ShaderModel>5.1</ShaderModel>
|
||||
</FXCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
|
||||
<Link>
|
||||
<AdditionalDependencies>ATGTelemetryUWP.lib; d2d1.lib; d3d12.lib; dxgi.lib; dxguid.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\..\Kits\Telemetry\$(Platform); %(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\arm; $(VCInstallDir)\lib\arm</AdditionalLibraryDirectories>
|
||||
<GenerateWindowsMetadata>true</GenerateWindowsMetadata>
|
||||
</Link>
|
||||
<ClCompile>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir);$(IntermediateOutputPath);..\..\..\Kits\DirectXTK12\Inc;..\..\..\Kits\ATGTK;..\..\..\Kits\Telemetry;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
</ClCompile>
|
||||
<FXCompile>
|
||||
<ShaderModel>5.1</ShaderModel>
|
||||
</FXCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Link>
|
||||
<AdditionalDependencies>ATGTelemetryUWP.lib; d2d1.lib; d3d12.lib; dxgi.lib; dxguid.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\..\Kits\Telemetry\$(Platform); %(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store; $(VCInstallDir)\lib</AdditionalLibraryDirectories>
|
||||
<GenerateWindowsMetadata>true</GenerateWindowsMetadata>
|
||||
</Link>
|
||||
<ClCompile>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir);$(IntermediateOutputPath);..\..\..\Kits\DirectXTK12\Inc;..\..\..\Kits\ATGTK;..\..\..\Kits\Telemetry;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
|
||||
</ClCompile>
|
||||
<FXCompile>
|
||||
<ShaderModel>5.1</ShaderModel>
|
||||
</FXCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Link>
|
||||
<AdditionalDependencies>ATGTelemetryUWP.lib; d2d1.lib; d3d12.lib; dxgi.lib; dxguid.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\..\Kits\Telemetry\$(Platform); %(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store; $(VCInstallDir)\lib</AdditionalLibraryDirectories>
|
||||
<GenerateWindowsMetadata>true</GenerateWindowsMetadata>
|
||||
</Link>
|
||||
<ClCompile>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir);$(IntermediateOutputPath);..\..\..\Kits\DirectXTK12\Inc;..\..\..\Kits\ATGTK;..\..\..\Kits\Telemetry;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
|
||||
</ClCompile>
|
||||
<FXCompile>
|
||||
<ShaderModel>5.1</ShaderModel>
|
||||
</FXCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Link>
|
||||
<AdditionalDependencies>ATGTelemetryUWP.lib; d2d1.lib; d3d12.lib; dxgi.lib; dxguid.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\..\Kits\Telemetry\$(Platform); %(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\amd64; $(VCInstallDir)\lib\amd64</AdditionalLibraryDirectories>
|
||||
<GenerateWindowsMetadata>true</GenerateWindowsMetadata>
|
||||
</Link>
|
||||
<ClCompile>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir);$(IntermediateOutputPath);..\..\..\Kits\DirectXTK12\Inc;..\..\..\Kits\ATGTK;..\..\..\Kits\Telemetry;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
</ClCompile>
|
||||
<FXCompile>
|
||||
<ShaderModel>5.1</ShaderModel>
|
||||
</FXCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Link>
|
||||
<AdditionalDependencies>ATGTelemetryUWP.lib; d2d1.lib; d3d12.lib; dxgi.lib; dxguid.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\..\Kits\Telemetry\$(Platform); %(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\amd64; $(VCInstallDir)\lib\amd64</AdditionalLibraryDirectories>
|
||||
<GenerateWindowsMetadata>true</GenerateWindowsMetadata>
|
||||
</Link>
|
||||
<ClCompile>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir);$(IntermediateOutputPath);..\..\..\Kits\DirectXTK12\Inc;..\..\..\Kits\ATGTK;..\..\..\Kits\Telemetry;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
</ClCompile>
|
||||
<FXCompile>
|
||||
<ShaderModel>5.1</ShaderModel>
|
||||
</FXCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\Kits\ATGTK\ControllerFont.h" />
|
||||
<ClInclude Include="..\..\..\Kits\ATGTK\ControllerHelp.h" />
|
||||
<ClInclude Include="..\..\..\Kits\ATGTK\CSVReader.h" />
|
||||
<ClInclude Include="..\..\..\Kits\ATGTK\ReadData.h" />
|
||||
<ClInclude Include="SimpleComputeUWP12.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="StepTimer.h" />
|
||||
<ClInclude Include="DeviceResources.h" />
|
||||
<ClInclude Include="..\..\..\Kits\ATGTK\d3dx12.h" />
|
||||
<ClInclude Include="..\..\..\Kits\ATGTK\ATGColors.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\Kits\ATGTK\ControllerHelp.cpp" />
|
||||
<ClCompile Include="SimpleComputeUWP12.cpp" />
|
||||
<ClCompile Include="Main.cpp" />
|
||||
<ClCompile Include="DeviceResources.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AppxManifest Include="Package.appxmanifest">
|
||||
<SubType>Designer</SubType>
|
||||
</AppxManifest>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="..\..\..\Media\Textures\ATGSampleBackground.DDS" />
|
||||
<Image Include="..\..\..\Media\Textures\callout_circle.dds" />
|
||||
<Image Include="..\..\..\Media\Textures\gamepad.dds" />
|
||||
<Image Include="Assets\Logo.png" />
|
||||
<Image Include="Assets\SmallLogo.png" />
|
||||
<Image Include="Assets\SplashScreen.png" />
|
||||
<Image Include="Assets\StoreLogo.png" />
|
||||
<Image Include="Assets\WideLogo.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\..\Kits\Telemetry\ARM\ATGTelemetryUWP.dll">
|
||||
<ExcludedFromBuild Condition="'$(Platform)'=='x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Platform)'=='Win32'">true</ExcludedFromBuild>
|
||||
<DeploymentContent Condition="'$(Platform)'=='ARM'">true</DeploymentContent>
|
||||
<Link>ATGTelemetryUWP.dll</Link>
|
||||
</None>
|
||||
<None Include="..\..\..\Kits\Telemetry\Win32\ATGTelemetryUWP.dll">
|
||||
<ExcludedFromBuild Condition="'$(Platform)'=='x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Platform)'=='ARM'">true</ExcludedFromBuild>
|
||||
<DeploymentContent Condition="'$(Platform)'=='Win32'">true</DeploymentContent>
|
||||
<Link>ATGTelemetryUWP.dll</Link>
|
||||
</None>
|
||||
<None Include="..\..\..\Kits\Telemetry\x64\ATGTelemetryUWP.dll">
|
||||
<ExcludedFromBuild Condition="'$(Platform)'=='ARM'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Platform)'=='Win32'">true</ExcludedFromBuild>
|
||||
<DeploymentContent Condition="'$(Platform)'=='x64'">true</DeploymentContent>
|
||||
<Link>ATGTelemetryUWP.dll</Link>
|
||||
</None>
|
||||
<None Include="..\..\..\Media\Fonts\SegoeUI_18.spritefont">
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</DeploymentContent>
|
||||
</None>
|
||||
<None Include="..\..\..\Media\Fonts\SegoeUI_22.spritefont">
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</DeploymentContent>
|
||||
</None>
|
||||
<None Include="..\..\..\Media\Fonts\SegoeUI_36.spritefont">
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</DeploymentContent>
|
||||
</None>
|
||||
<None Include="..\..\..\Media\Fonts\XboxOneControllerLegendSmall.spritefont">
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</DeploymentContent>
|
||||
</None>
|
||||
<None Include="Readme.docx" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Kits\DirectXTK12\DirectXTK_Windows10.vcxproj">
|
||||
<Project>{945b8f0e-ae5f-447c-933a-9d069532d3e4}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<FxCompile Include="Assets\fractal.hlsl">
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Compute</ShaderType>
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Compute</ShaderType>
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">Compute</ShaderType>
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">Compute</ShaderType>
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Compute</ShaderType>
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Compute</ShaderType>
|
||||
</FxCompile>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="$(VSINSTALLDIR)\Common7\IDE\Extensions\Microsoft\VsGraphics\ImageContentTask.targets" />
|
||||
<Import Project="$(VSINSTALLDIR)\Common7\IDE\Extensions\Microsoft\VsGraphics\MeshContentTask.targets" />
|
||||
<Import Project="$(VSINSTALLDIR)\Common7\IDE\Extensions\Microsoft\VsGraphics\ShaderGraphContentTask.targets" />
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -0,0 +1,124 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Common">
|
||||
<UniqueIdentifier>caee200e-5ed8-4ca9-9739-1edbf98df0fe</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Assets">
|
||||
<UniqueIdentifier>50316526-f464-47c4-839a-75443c0e42ba</UniqueIdentifier>
|
||||
<Extensions>bmp;dds;fbx;gif;jpg;jpeg;tga;tiff;tif;png</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="ATG Tool Kit">
|
||||
<UniqueIdentifier>4caff1d9-cad0-4514-9011-ec859b630947</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Common\Telemetry">
|
||||
<UniqueIdentifier>7bcab1f2-58a7-41e5-904c-71a28fab3cbd</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Common\Telemetry\ARM">
|
||||
<UniqueIdentifier>a32b937b-1e0b-40f7-b821-8e8067ea6ee2</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Common\Telemetry\Win32">
|
||||
<UniqueIdentifier>0109e811-84f6-4575-a69d-3d5fecf07924</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Common\Telemetry\x64">
|
||||
<UniqueIdentifier>8f41b037-289c-4b49-98ae-d96a6c97be68</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="SimpleComputeUWP12.h" />
|
||||
<ClInclude Include="StepTimer.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DeviceResources.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\Kits\ATGTK\d3dx12.h">
|
||||
<Filter>ATG Tool Kit</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\Kits\ATGTK\ATGColors.h">
|
||||
<Filter>ATG Tool Kit</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\Kits\ATGTK\ControllerFont.h">
|
||||
<Filter>ATG Tool Kit</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\Kits\ATGTK\CSVReader.h">
|
||||
<Filter>ATG Tool Kit</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\Kits\ATGTK\ReadData.h">
|
||||
<Filter>ATG Tool Kit</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\Kits\ATGTK\ControllerHelp.h">
|
||||
<Filter>ATG Tool Kit</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="pch.cpp" />
|
||||
<ClCompile Include="SimpleComputeUWP12.cpp" />
|
||||
<ClCompile Include="Main.cpp" />
|
||||
<ClCompile Include="DeviceResources.cpp">
|
||||
<Filter>Common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\Kits\ATGTK\ControllerHelp.cpp">
|
||||
<Filter>ATG Tool Kit</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="Assets\Logo.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\SmallLogo.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\SplashScreen.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\StoreLogo.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="Assets\WideLogo.png">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="..\..\..\Media\Textures\ATGSampleBackground.DDS">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="..\..\..\Media\Textures\callout_circle.dds">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="..\..\..\Media\Textures\gamepad.dds">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\..\Kits\Telemetry\ARM\ATGTelemetryUWP.dll">
|
||||
<Filter>Common\Telemetry\ARM</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\Kits\Telemetry\Win32\ATGTelemetryUWP.dll">
|
||||
<Filter>Common\Telemetry\Win32</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\Kits\Telemetry\x64\ATGTelemetryUWP.dll">
|
||||
<Filter>Common\Telemetry\x64</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\Media\Fonts\SegoeUI_18.spritefont">
|
||||
<Filter>Assets</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\Media\Fonts\SegoeUI_22.spritefont">
|
||||
<Filter>Assets</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\Media\Fonts\SegoeUI_36.spritefont">
|
||||
<Filter>Assets</Filter>
|
||||
</None>
|
||||
<None Include="..\..\..\Media\Fonts\XboxOneControllerLegendSmall.spritefont">
|
||||
<Filter>Assets</Filter>
|
||||
</None>
|
||||
<None Include="Readme.docx" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AppxManifest Include="Package.appxmanifest" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<FxCompile Include="Assets\fractal.hlsl">
|
||||
<Filter>Assets</Filter>
|
||||
</FxCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,188 @@
|
|||
//
|
||||
// StepTimer.h - A simple timer that provides elapsed time information
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <exception>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace DX
|
||||
{
|
||||
// Helper class for animation and simulation timing.
|
||||
class StepTimer
|
||||
{
|
||||
public:
|
||||
StepTimer() :
|
||||
m_elapsedTicks(0),
|
||||
m_totalTicks(0),
|
||||
m_leftOverTicks(0),
|
||||
m_frameCount(0),
|
||||
m_framesPerSecond(0),
|
||||
m_framesThisSecond(0),
|
||||
m_qpcSecondCounter(0),
|
||||
m_isFixedTimeStep(false),
|
||||
m_targetElapsedTicks(TicksPerSecond / 60)
|
||||
{
|
||||
if (!QueryPerformanceFrequency(&m_qpcFrequency))
|
||||
{
|
||||
throw std::exception( "QueryPerformanceFrequency" );
|
||||
}
|
||||
|
||||
if (!QueryPerformanceCounter(&m_qpcLastTime))
|
||||
{
|
||||
throw std::exception( "QueryPerformanceCounter" );
|
||||
}
|
||||
|
||||
// Initialize max delta to 1/10 of a second.
|
||||
m_qpcMaxDelta = m_qpcFrequency.QuadPart / 10;
|
||||
}
|
||||
|
||||
// Get elapsed time since the previous Update call.
|
||||
uint64_t GetElapsedTicks() const { return m_elapsedTicks; }
|
||||
double GetElapsedSeconds() const { return TicksToSeconds(m_elapsedTicks); }
|
||||
|
||||
// Get total time since the start of the program.
|
||||
uint64_t GetTotalTicks() const { return m_totalTicks; }
|
||||
double GetTotalSeconds() const { return TicksToSeconds(m_totalTicks); }
|
||||
|
||||
// Get total number of updates since start of the program.
|
||||
uint32_t GetFrameCount() const { return m_frameCount; }
|
||||
|
||||
// Get the current framerate.
|
||||
uint32_t GetFramesPerSecond() const { return m_framesPerSecond; }
|
||||
|
||||
// Set whether to use fixed or variable timestep mode.
|
||||
void SetFixedTimeStep(bool isFixedTimestep) { m_isFixedTimeStep = isFixedTimestep; }
|
||||
|
||||
// Set how often to call Update when in fixed timestep mode.
|
||||
void SetTargetElapsedTicks(uint64_t targetElapsed) { m_targetElapsedTicks = targetElapsed; }
|
||||
void SetTargetElapsedSeconds(double targetElapsed) { m_targetElapsedTicks = SecondsToTicks(targetElapsed); }
|
||||
|
||||
// Integer format represents time using 10,000,000 ticks per second.
|
||||
static const uint64_t TicksPerSecond = 10000000;
|
||||
|
||||
static double TicksToSeconds(uint64_t ticks) { return static_cast<double>(ticks) / TicksPerSecond; }
|
||||
static uint64_t SecondsToTicks(double seconds) { return static_cast<uint64_t>(seconds * TicksPerSecond); }
|
||||
|
||||
// After an intentional timing discontinuity (for instance a blocking IO operation)
|
||||
// call this to avoid having the fixed timestep logic attempt a set of catch-up
|
||||
// Update calls.
|
||||
|
||||
void ResetElapsedTime()
|
||||
{
|
||||
if (!QueryPerformanceCounter(&m_qpcLastTime))
|
||||
{
|
||||
throw std::exception("QueryPerformanceCounter");
|
||||
}
|
||||
|
||||
m_leftOverTicks = 0;
|
||||
m_framesPerSecond = 0;
|
||||
m_framesThisSecond = 0;
|
||||
m_qpcSecondCounter = 0;
|
||||
}
|
||||
|
||||
// Update timer state, calling the specified Update function the appropriate number of times.
|
||||
template<typename TUpdate>
|
||||
void Tick(const TUpdate& update)
|
||||
{
|
||||
// Query the current time.
|
||||
LARGE_INTEGER currentTime;
|
||||
|
||||
if (!QueryPerformanceCounter(¤tTime))
|
||||
{
|
||||
throw std::exception( "QueryPerformanceCounter" );
|
||||
}
|
||||
|
||||
uint64_t timeDelta = currentTime.QuadPart - m_qpcLastTime.QuadPart;
|
||||
|
||||
m_qpcLastTime = currentTime;
|
||||
m_qpcSecondCounter += timeDelta;
|
||||
|
||||
// Clamp excessively large time deltas (e.g. after paused in the debugger).
|
||||
if (timeDelta > m_qpcMaxDelta)
|
||||
{
|
||||
timeDelta = m_qpcMaxDelta;
|
||||
}
|
||||
|
||||
// Convert QPC units into a canonical tick format. This cannot overflow due to the previous clamp.
|
||||
timeDelta *= TicksPerSecond;
|
||||
timeDelta /= m_qpcFrequency.QuadPart;
|
||||
|
||||
uint32_t lastFrameCount = m_frameCount;
|
||||
|
||||
if (m_isFixedTimeStep)
|
||||
{
|
||||
// Fixed timestep update logic
|
||||
|
||||
// If the app is running very close to the target elapsed time (within 1/4 of a millisecond) just clamp
|
||||
// the clock to exactly match the target value. This prevents tiny and irrelevant errors
|
||||
// from accumulating over time. Without this clamping, a game that requested a 60 fps
|
||||
// fixed update, running with vsync enabled on a 59.94 NTSC display, would eventually
|
||||
// accumulate enough tiny errors that it would drop a frame. It is better to just round
|
||||
// small deviations down to zero to leave things running smoothly.
|
||||
|
||||
if (abs(static_cast<int64_t>(timeDelta - m_targetElapsedTicks)) < TicksPerSecond / 4000)
|
||||
{
|
||||
timeDelta = m_targetElapsedTicks;
|
||||
}
|
||||
|
||||
m_leftOverTicks += timeDelta;
|
||||
|
||||
while (m_leftOverTicks >= m_targetElapsedTicks)
|
||||
{
|
||||
m_elapsedTicks = m_targetElapsedTicks;
|
||||
m_totalTicks += m_targetElapsedTicks;
|
||||
m_leftOverTicks -= m_targetElapsedTicks;
|
||||
m_frameCount++;
|
||||
|
||||
update();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Variable timestep update logic.
|
||||
m_elapsedTicks = timeDelta;
|
||||
m_totalTicks += timeDelta;
|
||||
m_leftOverTicks = 0;
|
||||
m_frameCount++;
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
// Track the current framerate.
|
||||
if (m_frameCount != lastFrameCount)
|
||||
{
|
||||
m_framesThisSecond++;
|
||||
}
|
||||
|
||||
if (m_qpcSecondCounter >= static_cast<uint64_t>(m_qpcFrequency.QuadPart))
|
||||
{
|
||||
m_framesPerSecond = m_framesThisSecond;
|
||||
m_framesThisSecond = 0;
|
||||
m_qpcSecondCounter %= m_qpcFrequency.QuadPart;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
// Source timing data uses QPC units.
|
||||
LARGE_INTEGER m_qpcFrequency;
|
||||
LARGE_INTEGER m_qpcLastTime;
|
||||
uint64_t m_qpcMaxDelta;
|
||||
|
||||
// Derived timing data uses a canonical tick format.
|
||||
uint64_t m_elapsedTicks;
|
||||
uint64_t m_totalTicks;
|
||||
uint64_t m_leftOverTicks;
|
||||
|
||||
// Members for tracking the framerate.
|
||||
uint32_t m_frameCount;
|
||||
uint32_t m_framesPerSecond;
|
||||
uint32_t m_framesThisSecond;
|
||||
uint64_t m_qpcSecondCounter;
|
||||
|
||||
// Members for configuring fixed timestep mode.
|
||||
bool m_isFixedTimeStep;
|
||||
uint64_t m_targetElapsedTicks;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
//--------------------------------------------------------------------------------------
|
||||
// pch.cpp
|
||||
//
|
||||
// Include the standard header and generate the precompiled header.
|
||||
//
|
||||
// Advanced Technology Group (ATG)
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
#include "pch.h"
|
|
@ -0,0 +1,83 @@
|
|||
//--------------------------------------------------------------------------------------
|
||||
// pch.h
|
||||
//
|
||||
// Header for standard system include files.
|
||||
//
|
||||
// Advanced Technology Group (ATG)
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
// Use the C++ standard templated min/max
|
||||
#define NOMINMAX
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4467)
|
||||
#include <wrl.h>
|
||||
#pragma warning(pop)
|
||||
|
||||
#include <d3d12.h>
|
||||
|
||||
#if defined(NTDDI_WIN10_RS2)
|
||||
#include <dxgi1_6.h>
|
||||
#else
|
||||
#include <dxgi1_5.h>
|
||||
#endif
|
||||
|
||||
#include <DirectXMath.h>
|
||||
#include <DirectXColors.h>
|
||||
|
||||
#include "d3dx12.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <exception>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <thread>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <pix.h>
|
||||
|
||||
#ifdef _DEBUG
|
||||
#include <dxgidebug.h>
|
||||
#endif
|
||||
|
||||
#include "GamePad.h"
|
||||
#include "GraphicsMemory.h"
|
||||
#include "Keyboard.h"
|
||||
#include "Mouse.h"
|
||||
#include "RenderTargetState.h"
|
||||
#include "SimpleMath.h"
|
||||
#include "SpriteBatch.h"
|
||||
#include "SpriteFont.h"
|
||||
|
||||
namespace DX
|
||||
{
|
||||
// Helper class for COM exceptions
|
||||
class com_exception : public std::exception
|
||||
{
|
||||
public:
|
||||
com_exception(HRESULT hr) : result(hr) {}
|
||||
|
||||
virtual const char* what() const override
|
||||
{
|
||||
static char s_str[64] = {};
|
||||
sprintf_s(s_str, "Failure with HRESULT of %08X", static_cast<unsigned int>(result));
|
||||
return s_str;
|
||||
}
|
||||
|
||||
private:
|
||||
HRESULT result;
|
||||
};
|
||||
|
||||
// Helper utility converts D3D API failures into exceptions.
|
||||
inline void ThrowIfFailed(HRESULT hr)
|
||||
{
|
||||
if (FAILED(hr))
|
||||
{
|
||||
throw com_exception(hr);
|
||||
}
|
||||
}
|
||||
}
|