Full Code of jobeid/TrayPwrD3 for AI

master 277a329c8640 cached
22 files
118.2 KB
32.5k tokens
73 symbols
1 requests
Download .txt
Repository: jobeid/TrayPwrD3
Branch: master
Commit: 277a329c8640
Files: 22
Total size: 118.2 KB

Directory structure:
gitextract_f_fcv1s_/

├── LICENSE
├── README.md
└── src/
    ├── AboutDlg.cpp
    ├── AboutDlg.h
    ├── D3dx12jo.cpp
    ├── D3dx12jo.h
    ├── LICENSE.txt
    ├── Mainfrm.cpp
    ├── TrayIcon.CPP
    ├── TrayPwr.cpp
    ├── TrayPwr.h
    ├── TrayPwr.rc
    ├── TrayPwr.sln
    ├── TrayPwr.vcxproj
    ├── TrayPwr.vcxproj.user
    ├── d3dx12.h
    ├── mainfrm.h
    ├── res/
    │   └── APP.RC2
    ├── resource.h
    ├── stdafx.cpp
    ├── stdafx.h
    └── trayicon.h

================================================
FILE CONTENTS
================================================

================================================
FILE: LICENSE
================================================
MIT License

Copyright© 2017 J.S. Obeid

Permission is hereby granted, free of charge, to any person 
obtaining a copy of this software and associated documentation 
files(the \Software\), to deal in the Software without 
restriction, including without limitation the rights to use, 
copy, modify, merge, publish, distribute, sublicense, and / or 
sell copies of the Software, and to permit persons to whom the 
Software is furnished to do so, subject to the following 
conditions:

The above copyright notice and this permission notice shall be 
included in all copies or substantial portions of the Software. 

THE SOFTWARE IS PROVIDED \AS IS\, WITHOUT WARRANTY OF ANY KIND, 
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND  
NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
OTHER DEALINGS IN THE SOFTWARE. 		


================================================
FILE: README.md
================================================
# TrayPwrD3
**Keeps dGPU on but idle** until needed. This addresses the Windows 10 (64bit) stutter/mouse freeze on dual GPU laptops (intel or AMD CPU with built in GPU in combination with NVIDIA). TrayPwrD3 runs in the background and stays in a tray icon.   ![Tray icon](screenshots/traypwr_icon1.png?raw=true "Tray icon")

**Other functionality**: single click turns monitor off to save power until you wake it up by moving the mouse or using the keyboard; provides several menu options on right click; more details in Help menu.

This is to address the [Windows 10 and Optimus problem of stutters and mouse hangs](https://forums.geforce.com/default/topic/860554/geforce-mobile-gpus/windows-10-and-optimus/15/). For more about this issue see description on answers.microsoft [Intel + NVIDIA Laptop Freeze Problem](https://answers.microsoft.com/en-us/windows/forum/windows_10-hardware/mobile-gtx-1060-freeze-problem/93e7004a-62b1-4211-8e37-4c136608865e). Note: it is not for stutters in games. It only addresses the desktop stutters in Windows 10 (right click -> display settings, battery icon, chrome and firefox tabs, PowerPoint slideshow etc).  If you don't have any of these, then you don't need it. 

**Windows 10 May 2020 Update:** With this latest update Microsoft fixed the latency issue. However, you will need NVIDIA driver version 451.48 or later. For more information see this Windows Latest post: [Nvidia GeForce 451.48 adds Windows 10 GPU scheduling feature](https://www.windowslatest.com/2020/06/24/nvidia-geforce-451-48-windows-10-hardware-accelerated-gpu-scheduling/).
  
**Update 7/14/2020:** Still noticing some brief hanging during some activities with explorer. So latency issue not totally fixed.

**Update 11/12/2020:** Still noticing some major hanging during some activities with explorer and when running certain apps e.g. Media Player Classic on AMD Ryzen systems. So NVIDIA GPU activation latency remains a problem. The updated version of TrayPwrD3 (v2020-11) now supports AMD Ryzen systems and prevents the GPU stutter or latency on both Intel and AMD Ryzen systems.

**Update 12/25/2025:** Starting the app now checks if there is a running instance and gives the option to kill it.

# Installation
Simply download the latest version of the [executable](https://github.com/jobeid/TrayPwrD3/tree/master/executable), uncompress it in any folder and run it. 
Notes:
- The executable was compliled for 64bit windows. 
- Direct3D version 12 is required.
- If you don't already have [Visual C++ Redistributable for Visual Studio](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads) installed, then you could download the 64bit version [directly from Microsoft](https://aka.ms/vs/16/release/vc_redist.x64.exe) and install it.
- Optional: If you would like to start TrayPwrD3 when windows starts, you can place a shortcut of the executable in the startup folder (located at %USERPROFILE%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\STARTUP). You can quickly open the startup folder by tapping the Windows key+R to bring up the "Run" dialog, and type `shell:startup` then enter.

# Using the App
When you start the app it simply runs in the background in a tray icon, keeping the dGPU on but idle. This addresses the well known Windows 10 stutter/mouse freeze on some dual GPU laptops.

**To stop the app** simpley right-click the icon and click exit. **There is _no_ need to reboot the system**.

# Screenshots

Tray icon:   ![Tray icon](screenshots/traypwr_icon1.png?raw=true "Tray icon")


Right click menu:  ![Menu](screenshots/traypwr_rightclick1.png?raw=true "Menu")


================================================
FILE: src/AboutDlg.cpp
================================================
// AboutDlg.cpp : implementation file
//

#include "stdafx.h"
#include "traypwr.h"
#include "AboutDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog


BOOL CAboutDlg::m_bVisible = FALSE;
HWND CAboutDlg::m_MyhWnd = NULL;

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	m_hChildProcess = NULL;
	m_dwChildProcessId = 0;
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
    //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
	ON_WM_DESTROY()
	ON_WM_SHOWWINDOW()
	ON_BN_CLICKED(IDSYSINFO, OnSysinfo)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

BOOL CAboutDlg::OnInitDialog() 
{
	const char *mylic =
		"MIT License\r\n\r\n"
		"Copyright 2020 J.S. Obeid\r\n\r\n"
		"Permission is hereby granted, free of charge, to any person obtaining a copy\r\n"
		"of this software and associated documentation files(the \"Software\"), to deal\r\n"
		"in the Software without restriction, including without limitation the rights\r\n"
		"to use, copy, modify, merge, publish, distribute, sublicense, and / or sell\r\n"
		"copies of the Software, and to permit persons to whom the Software is\r\n"
		"furnished to do so, subject to the following conditions : \r\n\r\n"
		"The above copyright notice and this permission notice shall be included in\r\n"
		"all copies or substantial portions of the Software.\r\n\r\n"
		"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\r\n"
		"EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\r\n"
		"OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND \r\n"
		"NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\r\n"
		"HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\r\n"
		"WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n"
		"OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\r\n"
		"DEALINGS IN THE SOFTWARE.";
	CDialog::OnInitDialog();

	GetDlgItem(IDC_EDITLIC)->SetWindowTextA(mylic);
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

void CAboutDlg::OnSize(UINT nType, int cx, int cy)
{
	CDialog::OnSize(nType, cx, cy);
}

void CAboutDlg::OnDestroy() 
{
	CDialog::OnDestroy();
	m_MyhWnd=NULL;
    //CSystemTray::MinimiseToTray(this);
    m_bVisible = FALSE;
}

void CAboutDlg::OnShowWindow(BOOL bShow, UINT nStatus) 
{
	CDialog::OnShowWindow(bShow, nStatus);
    m_MyhWnd=m_hWnd;
    //if (bShow) CSystemTray::MaximiseFromTray(this);
}

INT_PTR CAboutDlg::DoModal()
{
    if (m_bVisible)
	{	
		BringToTop();
        return IDCANCEL;
	}
    m_bVisible = TRUE;
	return CDialog::DoModal();
}


/////////////////////////////////////////////////////////////////////////////
// CAboutDlg message handlers

void CAboutDlg::OnSysinfo() 
{
	StartSysInfo();
}

void CAboutDlg::BringToTop()
{
	if (m_MyhWnd!=0) 
	{
		::SetWindowPos(m_MyhWnd,HWND_TOP,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE);
	}
}

BOOL CAboutDlg::OnCommand(WPARAM wParam, LPARAM lParam) 
{
	// TODO: Add your specialized code here and/or call the base class
	
	return CDialog::OnCommand(wParam, lParam);
}

//-----------------------------------------------------------
//
// StartSysInfo()
// Calls MSINFO32.EXE
//
BOOL CAboutDlg::StartSysInfo()
{
	OnInvokeMSInfo("msinfo32.exe");
	return TRUE;
}
//-----------start external exe functions:
void CAboutDlg::OnInvokeMSInfo(LPSTR SomeExeNm)
{
	PROCESS_INFORMATION pi;
	STARTUPINFO si;
	ZeroMemory(&si, sizeof(STARTUPINFO));
	si.cb = sizeof(STARTUPINFO);

	if (WaitForSingleObject(m_hChildProcess, 0) != WAIT_TIMEOUT &&
		CreateProcess(NULL, SomeExeNm,
			NULL, NULL,
			FALSE, 0,
			NULL, NULL,
			&si, &pi))
	{
		// Close the old process handle
		CloseHandle(m_hChildProcess);

		// Close the thread handle (process handle will be closed in ExitInstance)
		CloseHandle(pi.hThread);

		// store child process information
		m_hChildProcess = pi.hProcess;
		m_dwChildProcessId = pi.dwProcessId;
	}
	else
	{
		// ActivateChildProcess() activates all top-level windows whose PID matches m_dwChildProcessId.
		EnumWindows((WNDENUMPROC)CAboutDlg::ActivateChildProcess,
			(LPARAM)m_dwChildProcessId);
	}
	WaitForInputIdle(m_hChildProcess, 1000);
}

BOOL CALLBACK CAboutDlg::CloseChildProcess(HWND hWnd, LPARAM lParam)
{
	DWORD dwID;
	GetWindowThreadProcessId(hWnd, &dwID);
	if (dwID == (DWORD)lParam)
	{
		::PostMessage(hWnd, WM_CLOSE, 0, 0);
	}
	return TRUE;
}

BOOL CALLBACK CAboutDlg::ActivateChildProcess(HWND hWnd, LPARAM lParam)
{
	DWORD dwID;
	GetWindowThreadProcessId(hWnd, &dwID);
	if (dwID == (DWORD)lParam)
	{
		// Note: This block is adapted from CFrameWnd::ActivateFrame
		// and from CFrameWnd::BringToTop.
		int nCmdShow = -1;
		HWND hWndLastPop;

		// translate default nCmdShow (-1)
		if (nCmdShow == -1)
		{
			if (::IsIconic(hWnd))
				nCmdShow = SW_RESTORE;
		}
		ASSERT(nCmdShow != SW_HIDE &&
			nCmdShow != SW_MINIMIZE && nCmdShow != SW_SHOWMINNOACTIVE &&
			nCmdShow != SW_SHOWNA && nCmdShow != SW_SHOWNOACTIVATE);

		// bring to top before showing
		// if no last active popup, it will return hWnd
		hWndLastPop = ::GetLastActivePopup(hWnd);
		::BringWindowToTop(hWndLastPop);

		if (nCmdShow != -1)
		{
			// show the window as specified
			::ShowWindow(hWnd, nCmdShow);

			// and finally, bring to top after showing
			// if no last active popup, it will return hWnd
			hWndLastPop = ::GetLastActivePopup(hWnd);
			::BringWindowToTop(hWndLastPop);
		}

		::PostMessage(hWnd, WM_SETFOCUS, 0, 0);
	}
	return TRUE;
}


================================================
FILE: src/AboutDlg.h
================================================
// AboutDlg.h : header file
//

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

	void BringToTop();
// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
    //}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	public:
	virtual INT_PTR DoModal();
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);
	virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
	//}}AFX_VIRTUAL

// Implementation
protected:
    static BOOL m_bVisible;
	static HWND m_MyhWnd;
	//stuff for calling external exe's:
	HANDLE m_hChildProcess;
	DWORD m_dwChildProcessId;
	void OnInvokeMSInfo(LPSTR SomeExeNm);
	static BOOL CALLBACK CloseChildProcess(HWND hWnd, LPARAM lParam);
	static BOOL CALLBACK ActivateChildProcess(HWND hWnd, LPARAM lParam);
	BOOL StartSysInfo();

	//{{AFX_MSG(CAboutDlg)
	virtual BOOL OnInitDialog();
	afx_msg void OnDestroy();
	afx_msg void OnSize(UINT nType, int cx, int cy);
	afx_msg void OnShowWindow(BOOL bShow, UINT nStatus);
	afx_msg void OnSysinfo();
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};


================================================
FILE: src/D3dx12jo.cpp
================================================
#include "stdafx.h"
#include "D3dx12jo.h"

using namespace DirectX; // we will be using the directxmath library

D3dx12jo::D3dx12jo()
{
	hwnd_jo = NULL;
	FullScreen_jo = false;
	Running = true;
}

bool D3dx12jo::InitD3D(HWND hwnd_tmp)
{
	HRESULT hr;

	// -- Create the Device -- //

	IDXGIFactory4* dxgiFactory;

	hwnd_jo = hwnd_tmp;
	hr = CreateDXGIFactory1(IID_PPV_ARGS(&dxgiFactory));
	if (FAILED(hr))
	{
		return false;
	}

	IDXGIAdapter1* adapter; // adapters are the graphics card (this includes the embedded graphics on the motherboard)

	int adapterIndex = 0; // we'll start looking for directx 12  compatible graphics devices starting at index 0

	bool adapterFound = false; // set this to true when a good one was found

							   // find first hardware gpu that supports d3d 12
							   //while (dxgiFactory->EnumAdapters1(adapterIndex, &adapter) != DXGI_ERROR_NOT_FOUND)
	while (adapterIndex<3)
	{
		DXGI_ADAPTER_DESC1 desc;

		if (dxgiFactory->EnumAdapters1(adapterIndex, &adapter) == DXGI_ERROR_NOT_FOUND)
		{
			break;
		}
		adapter->GetDesc1(&desc);

		if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)
		{
			// we dont want a software device
			adapterIndex++;
			continue;
		}
		if (desc.VendorId == 32902)
		{
			// we dont want INTEL device (id=0x8086) look up vendor id in device manager
			adapterIndex++;
			continue;
		}
		if (desc.VendorId == 4098)
		{
			// we dont want AMD device (id=0x1002) look up vendor id in device manager
			adapterIndex++;
			continue;
		}
		// we want a device that is compatible with direct3d 12 (feature level 11 or higher)
		hr = D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr);
		if (SUCCEEDED(hr))
		{
			adapterFound = true;
			break;
		}
		adapterIndex++;
	}

	if (!adapterFound)
	{
		return false;
	}

	// Create the device
	hr = D3D12CreateDevice(
		adapter,
		D3D_FEATURE_LEVEL_11_0,
		IID_PPV_ARGS(&device)
	);
	if (FAILED(hr))
	{
		return false;
	}

	// -- Create a direct command queue -- //

	D3D12_COMMAND_QUEUE_DESC cqDesc = {};
	cqDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
	cqDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; // direct means the gpu can directly execute this command queue

	hr = device->CreateCommandQueue(&cqDesc, IID_PPV_ARGS(&commandQueue)); // create the command queue
	if (FAILED(hr))
	{
		return false;
	}

	// -- Create the Swap Chain (double/tripple buffering) -- //

	DXGI_MODE_DESC backBufferDesc = {}; // this is to describe our display mode
	backBufferDesc.Width = 300; //Width; // buffer width
	backBufferDesc.Height = 240; //Height; // buffer height
	backBufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // format of the buffer (rgba 32 bits, 8 bits for each chanel)

														// describe our multi-sampling. We are not multi-sampling, so we set the count to 1 (we need at least one sample of course)
	DXGI_SAMPLE_DESC sampleDesc = {};
	sampleDesc.Count = 1; // multisample count (no multisampling, so we just put 1, since we still need 1 sample)

						  // Describe and create the swap chain.
	DXGI_SWAP_CHAIN_DESC swapChainDesc = {};
	swapChainDesc.BufferCount = FRAME_BUFFER_COUNT_X; // number of buffers we have
	swapChainDesc.BufferDesc = backBufferDesc; // our back buffer description
	swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // this says the pipeline will render to this swap chain
	swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; // dxgi will discard the buffer (data) after we call present
	swapChainDesc.OutputWindow = hwnd_jo; // handle to our window
	swapChainDesc.SampleDesc = sampleDesc; // our multi-sampling description
	swapChainDesc.Windowed = !FullScreen_jo; // set to true, then if in fullscreen must call SetFullScreenState with true for full screen to get uncapped fps

	IDXGISwapChain* tempSwapChain;

	dxgiFactory->CreateSwapChain(
		commandQueue, // the queue will be flushed once the swap chain is created
		&swapChainDesc, // give it the swap chain description we created above
		&tempSwapChain // store the created swap chain in a temp IDXGISwapChain interface
	);

	swapChain = static_cast<IDXGISwapChain3*>(tempSwapChain);

	frameIndex = swapChain->GetCurrentBackBufferIndex();

	// -- Create the Back Buffers (render target views) Descriptor Heap -- //

	// describe an rtv descriptor heap and create
	D3D12_DESCRIPTOR_HEAP_DESC rtvHeapDesc = {};
	rtvHeapDesc.NumDescriptors = FRAME_BUFFER_COUNT_X; // number of descriptors for this heap.
	rtvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; // this heap is a render target view heap

													   // This heap will not be directly referenced by the shaders (not shader visible), as this will store the output from the pipeline
													   // otherwise we would set the heap's flag to D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE
	rtvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
	hr = device->CreateDescriptorHeap(&rtvHeapDesc, IID_PPV_ARGS(&rtvDescriptorHeap));
	if (FAILED(hr))
	{
		return false;
	}

	// get the size of a descriptor in this heap (this is a rtv heap, so only rtv descriptors should be stored in it.
	// descriptor sizes may vary from device to device, which is why there is no set size and we must ask the 
	// device to give us the size. we will use this size to increment a descriptor handle offset
	rtvDescriptorSize = device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);

	// get a handle to the first descriptor in the descriptor heap. a handle is basically a pointer,
	// but we cannot literally use it like a c++ pointer.
	CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(rtvDescriptorHeap->GetCPUDescriptorHandleForHeapStart());

	// Create a RTV for each buffer (double buffering is two buffers, tripple buffering is 3).
	for (int i = 0; i < FRAME_BUFFER_COUNT_X; i++)
	{
		// first we get the n'th buffer in the swap chain and store it in the n'th
		// position of our ID3D12Resource array
		hr = swapChain->GetBuffer(i, IID_PPV_ARGS(&renderTargets[i]));
		if (FAILED(hr))
		{
			return false;
		}

		// the we "create" a render target view which binds the swap chain buffer (ID3D12Resource[n]) to the rtv handle
		device->CreateRenderTargetView(renderTargets[i], nullptr, rtvHandle);

		// we increment the rtv handle by the rtv descriptor size we got above
		rtvHandle.Offset(1, rtvDescriptorSize);
	}

	// -- Create the Command Allocators -- //

	for (int i = 0; i < FRAME_BUFFER_COUNT_X; i++)
	{
		hr = device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&commandAllocator[i]));
		if (FAILED(hr))
		{
			return false;
		}
	}

	// -- Create a Command List -- //

	// create the command list with the first allocator
	hr = device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, commandAllocator[0], NULL, IID_PPV_ARGS(&commandList));
	if (FAILED(hr))
	{
		return false;
	}

	// command lists are created in the recording state. our main loop will set it up for recording again so close it now
	commandList->Close();

	// -- Create a Fence & Fence Event -- //

	// create the fences
	for (int i = 0; i < FRAME_BUFFER_COUNT_X; i++)
	{
		hr = device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence[i]));
		if (FAILED(hr))
		{
			return false;
		}
		fenceValue[i] = 0; // set the initial fence value to 0
	}

	// create a handle to a fence event
	fenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
	if (fenceEvent == nullptr)
	{
		return false;
	}

	return true;
}

void D3dx12jo::UpdatePipeline()
{
	HRESULT hr;

	// We have to wait for the gpu to finish with the command allocator before we reset it
	WaitForPreviousFrame();

	// we can only reset an allocator once the gpu is done with it
	// resetting an allocator frees the memory that the command list was stored in
	hr = commandAllocator[frameIndex]->Reset();
	if (FAILED(hr))
	{
		Running = false;
	}

	// reset the command list. by resetting the command list we are putting it into
	// a recording state so we can start recording commands into the command allocator.
	// the command allocator that we reference here may have multiple command lists
	// associated with it, but only one can be recording at any time. Make sure
	// that any other command lists associated to this command allocator are in
	// the closed state (not recording).
	// Here you will pass an initial pipeline state object as the second parameter,
	// but in this tutorial we are only clearing the rtv, and do not actually need
	// anything but an initial default pipeline, which is what we get by setting
	// the second parameter to NULL
	hr = commandList->Reset(commandAllocator[frameIndex], NULL);
	if (FAILED(hr))
	{
		Running = false;
	}

	// here we start recording commands into the commandList (which all the commands will be stored in the commandAllocator)

	// transition the "frameIndex" render target from the present state to the render target state so the command list draws to it starting from here
	commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(renderTargets[frameIndex], D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET));

	// here we again get the handle to our current render target view so we can set it as the render target in the output merger stage of the pipeline
	CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(rtvDescriptorHeap->GetCPUDescriptorHandleForHeapStart(), frameIndex, rtvDescriptorSize);

	// set the render target for the output merger stage (the output of the pipeline)
	commandList->OMSetRenderTargets(1, &rtvHandle, FALSE, nullptr);

	// Clear the render target by using the ClearRenderTargetView command
	const float clearColor[] = { 0.0f, 0.2f, 0.4f, 1.0f };	//DARK BLUE
	commandList->ClearRenderTargetView(rtvHandle, clearColor, 0, nullptr);

	// transition the "frameIndex" render target from the render target state to the present state. If the debug layer is enabled, you will receive a
	// warning if present is called on the render target when it's not in the present state
	commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(renderTargets[frameIndex], D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT));

	hr = commandList->Close();
	if (FAILED(hr))
	{
		Running = false;
	}
}

void D3dx12jo::Render()
{
	HRESULT hr;

	UpdatePipeline(); // update the pipeline by sending commands to the commandqueue

					  // create an array of command lists (only one command list here)
	ID3D12CommandList* ppCommandLists[] = { commandList };

	// execute the array of command lists
	commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists);

	// this command goes in at the end of our command queue. we will know when our command queue 
	// has finished because the fence value will be set to "fenceValue" from the GPU since the command
	// queue is being executed on the GPU
	hr = commandQueue->Signal(fence[frameIndex], fenceValue[frameIndex]);
	if (FAILED(hr))
	{
		Running = false;
	}

	// present the current backbuffer
	hr = swapChain->Present(0, 0);
	if (FAILED(hr))
	{
		Running = false;
	}
}

void D3dx12jo::Cleanup()
{
	// wait for the gpu to finish all frames
	for (int i = 0; i < FRAME_BUFFER_COUNT_X; ++i)
	{
		frameIndex = i;
		WaitForPreviousFrame();
	}

	// get swapchain out of full screen before exiting
	BOOL fs = false;
	if (swapChain->GetFullscreenState(&fs, NULL))
		swapChain->SetFullscreenState(false, NULL);

	SAFE_RELEASE(device);
	SAFE_RELEASE(swapChain);
	SAFE_RELEASE(commandQueue);
	SAFE_RELEASE(rtvDescriptorHeap);
	SAFE_RELEASE(commandList);

	for (int i = 0; i < FRAME_BUFFER_COUNT_X; ++i)
	{
		SAFE_RELEASE(renderTargets[i]);
		SAFE_RELEASE(commandAllocator[i]);
		SAFE_RELEASE(fence[i]);
	};
}

void D3dx12jo::WaitForPreviousFrame()
{
	HRESULT hr;

	// if the current fence value is still less than "fenceValue", then we know the GPU has not finished executing
	// the command queue since it has not reached the "commandQueue->Signal(fence, fenceValue)" command
	if (fence[frameIndex]->GetCompletedValue() < fenceValue[frameIndex])
	{
		// we have the fence create an event which is signaled once the fence's current value is "fenceValue"
		hr = fence[frameIndex]->SetEventOnCompletion(fenceValue[frameIndex], fenceEvent);
		if (FAILED(hr))
		{
			Running = false;
		}

		// We will wait until the fence has triggered the event that it's current value has reached "fenceValue". once it's value
		// has reached "fenceValue", we know the command queue has finished executing
		WaitForSingleObject(fenceEvent, INFINITE);
	}

	// increment fenceValue for next frame
	fenceValue[frameIndex]++;

	// swap the current rtv buffer index so we draw on the correct buffer
	frameIndex = swapChain->GetCurrentBackBufferIndex();
}

void D3dx12jo::CloseFenceHandle()
{
	WaitForPreviousFrame();
	CloseHandle(fenceEvent);
}

================================================
FILE: src/D3dx12jo.h
================================================
#pragma once

#include <d3d12.h>
#include <dxgi1_4.h>
#include <D3Dcompiler.h>
#include <DirectXMath.h>
#include "d3dx12.h"

// this will only call release if an object exists (prevents exceptions calling release on non existant objects)
#define SAFE_RELEASE(p) { if ( (p) ) { (p)->Release(); (p) = 0; } }
#define FRAME_BUFFER_COUNT_X  2 // number of buffers we want, 2 for double buffering, 3 for tripple buffering

class D3dx12jo 
{
public:
	D3dx12jo();

	// function declarations
	bool InitD3D(HWND hwnd); // initializes direct3d 12
	void Render(); // execute the command list
	void Cleanup(); // release com ojects and clean up memory
	void CloseFenceHandle(); //CloseHandle(fenceEvent);

protected:
	void UpdatePipeline(); // update the direct3d pipeline (update command lists)
	void WaitForPreviousFrame(); // wait until gpu is finished with command list
								 // Handle to the window
	HWND hwnd_jo;
	// is window full screen?
	bool FullScreen_jo;

	// we will exit the program when this becomes false
	bool Running;
	// direct3d stuff

	ID3D12Device* device; // direct3d device

	IDXGISwapChain3* swapChain; // swapchain used to switch between render targets

	ID3D12CommandQueue* commandQueue; // container for command lists

	ID3D12DescriptorHeap* rtvDescriptorHeap; // a descriptor heap to hold resources like the render targets

	ID3D12Resource* renderTargets[FRAME_BUFFER_COUNT_X]; // number of render targets equal to buffer count

	ID3D12CommandAllocator* commandAllocator[FRAME_BUFFER_COUNT_X]; // we want enough allocators for each buffer * number of threads (we only have one thread)

	ID3D12GraphicsCommandList* commandList; // a command list we can record commands into, then execute them to render the frame

	ID3D12Fence* fence[FRAME_BUFFER_COUNT_X];    // an object that is locked while our command list is being executed by the gpu. We need as many 
											 //as we have allocators (more if we want to know when the gpu is finished with an asset)

	HANDLE fenceEvent; // a handle to an event when our fence is unlocked by the gpu

	UINT64 fenceValue[FRAME_BUFFER_COUNT_X]; // this value is incremented each frame. each fence will have its own value

	int frameIndex; // current rtv we are on

	int rtvDescriptorSize; // size of the rtv descriptor on the device (all front and back buffers will be the same size)
};



================================================
FILE: src/LICENSE.txt
================================================
MIT License

Copyright 2020 J.S. Obeid

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the \Software\), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 

THE SOFTWARE IS PROVIDED \AS IS\, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND  NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 		

================================================
FILE: src/Mainfrm.cpp
================================================
////////////////////////////////////////////////////////////////
// Main frame window implementation
//

#include "stdafx.h"
#include "TrayPwr.h"
#include "mainfrm.h"
#include <VersionHelpers.h>

// Message ID used for tray notifications
#define WM_MY_TRAY_NOTIFICATION WM_USER+0
#define EWX_FORCEIFHUNG      0x00000010

IMPLEMENT_DYNAMIC(CMainFrame, CFrameWnd)

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
	//{{AFX_MSG_MAP(CMainFrame)
	ON_MESSAGE(WM_MY_TRAY_NOTIFICATION, OnTrayNotification)
	ON_WM_CREATE()
	ON_WM_CLOSE()
	ON_COMMAND(ID_APPTP_EXIT, OnAppTpExit)
	ON_COMMAND(ID_TPLOGOFF, OnTpLogOff)
	ON_COMMAND(ID_TPSHUTDOWN, OnTpShutDown)
	ON_COMMAND(ID_TPRESTART, OnTpRestart)
	ON_COMMAND(ID_TPSTANDBY, OnTpStandBy)
	ON_WM_TIMER()
	ON_COMMAND(ID_TPSCREENSAVE, OnTpScreenSave)
	ON_WM_ENDSESSION()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

static UINT BASED_CODE indicators[] = {
	ID_SEPARATOR,				// status line indicator
};

CMainFrame::CMainFrame() : m_trayIcon(IDR_TRAYICON)
{
	m_bShutdown = FALSE;
	m_DblClicked = FALSE;
	m_BtnClicked = 0;
	m_nTicks = 0;
	m_nTimer = 0;
}

CMainFrame::~CMainFrame()
{
}

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
		return -1;

	if (!m_wndStatusBar.Create(this) ||
		!m_wndStatusBar.SetIndicators(indicators, 
		sizeof(indicators)/sizeof(UINT))) 
		return -1;		 // fail to create

	//assign global hwnd for d3dx12
	//JJJ SET hwnd_jo IN DXjo class = m_hWnd;
	D3dx12jo* pD3jo = new D3dx12jo();
	m_pD3jo = pD3jo;
	if (!m_pD3jo->InitD3D(m_hWnd))
	{
		//MessageBox(0, L"Failed to initialize direct3d 12", L"Error", MB_OK);
		m_pD3jo->Cleanup();
		return -1;
	}

	// Set up tray icon
	m_trayIcon.SetNotificationWnd(this, WM_MY_TRAY_NOTIFICATION);
	m_iWhichIcon = 1;
	m_trayIcon.SetIcon(IDI_MYICON);

	// start timer for dx rendering and managing messages
	OnStartTimer();

	return 0;
}

//////////////////
// Close window. Unless we are shutting down, just hide it.
//
void CMainFrame::OnClose() 
{
	if (m_bShutdown)
		CFrameWnd::OnClose();
	else
		ShowWindow(SW_HIDE);
}

//////////////////
// Handle notification from tray icon: display a message.
//
LRESULT CMainFrame::OnTrayNotification(WPARAM uID, LPARAM lEvent)
{

	switch (lEvent)
	{
	case WM_LBUTTONUP: 
		//if one click then turn monitor off:
		m_BtnClicked=WM_LBUTTONUP;
		ResetTimerTicks();
		break;
	case WM_LBUTTONDBLCLK: 
		if (m_nTimer!=0) 
		{
			m_DblClicked=TRUE;
			m_BtnClicked = 0;
			if (IsShiftKeyDown())
			{
				OnTpStandBy();
			}else{ 
				//OnTpShutDown();
			}
		}
		break;
	case WM_RBUTTONUP: 
		m_BtnClicked=WM_RBUTTONUP;
		ResetTimerTicks();
		break;
	case WM_RBUTTONDBLCLK: 
		if (m_nTimer!=0) 
		{
			m_DblClicked=TRUE;
			if (IsShiftKeyDown())
			{
				OnTpLogOff();
			}else{ 
				OnTpRestart();
			}
		}
		break;
	}
	// let tray icon do default stuff
	return 0;
}

////////////////////////////////////////////////////////////////
// Command handlers below.
//

void CMainFrame::OnAppTpExit() 
{
	m_bShutdown = TRUE;		// really exit
	//clean up dx12:
	OnStopTimer();
	m_pD3jo->CloseFenceHandle();
	m_pD3jo->Cleanup();
	//close and exit:
	SendMessage(WM_CLOSE);	
}


void CMainFrame::OnTpLogOff()
{
	TpExitWindows(FALSE,ID_TPLOGOFF);
}
void CMainFrame::OnTpShutDown()
{
	TpExitWindows(FALSE,ID_TPSHUTDOWN);
}
void CMainFrame::OnTpRestart()
{
	TpExitWindows(FALSE,ID_TPRESTART);
}
void CMainFrame::OnTpStandBy()
{
	TpExitWindows(FALSE,ID_TPSTANDBY);
}
void CMainFrame::OnTpScreenSave() 
{
	// TODO: Add your command handler code here
	m_BtnClicked=WM_TPSCREENSAVER;
	ResetTimerTicks();
}

void CMainFrame::TpExitWindows(BOOL Force,int shtdn)
{

	if(IsWindowsVersionOrGreater(4, 0, 0)) {
        // Get the access token of the current process.  Get it
        // with the privileges of querying the access token and
        // adjusting its privileges.
		HANDLE hToken=0;
		LUID tLuid;
		TOKEN_PRIVILEGES tTokenPriv;

		BOOL bRes=OpenProcessToken(GetCurrentProcess(), 
            TOKEN_ADJUST_PRIVILEGES + TOKEN_QUERY, &hToken);
		if (bRes==0L){
			return; //Failed
		}
        // Get the locally unique identifier (LUID) which
        // represents the shutdown privilege.
		if (LookupPrivilegeValue(0L, "SeShutdownPrivilege", &tLuid)==0L)
			return; //Failed

        // Populate the new TOKEN_PRIVILEGES values with the LUID
        // and allow your current process to shutdown the computer.
		tTokenPriv.PrivilegeCount=1;
		tTokenPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
		tTokenPriv.Privileges[0].Luid = tLuid;

		AdjustTokenPrivileges(hToken, FALSE, &tTokenPriv, sizeof(TOKEN_PRIVILEGES),
			(PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL);
	} //Now we have the correct privileges, hopefully.
	
	//Perform desired windows power-down:
	
	UINT FORCE_FLAG=(Force == TRUE ? EWX_FORCEIFHUNG : 0L);

	switch (shtdn)
	{
	case ID_TPLOGOFF:{
		ExitWindowsEx(FORCE_FLAG | EWX_LOGOFF, 0L);
		}
		break;

	case ID_TPSHUTDOWN:{
		ExitWindowsEx(FORCE_FLAG | EWX_SHUTDOWN | EWX_POWEROFF, 0L);
		}
		break;

	case ID_TPRESTART:{
		ExitWindowsEx(FORCE_FLAG | EWX_REBOOT, 0L);
		}
		break;

	case ID_TPSTANDBY:{
		SetSystemPowerState(1L, 1L);
		}
		break;
	}

}

void CMainFrame::OnTimer(UINT_PTR nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	if (m_DblClicked==FALSE) 
	{
		
		m_nTicks++;
		if (m_nTicks>2)
		{
			//Some useful debugging code:
			//CString msg;
			//msg.Format("Hello: m_nTicks=%d", m_nTicks);   
			//MessageBeep(0xFFFFFFFF);   // Beep
			//MessageBox(msg); 
			switch (m_BtnClicked)
			{
			case WM_RBUTTONUP:
				DoMenuDropDown();
				m_BtnClicked = 0;
				break;
			case WM_LBUTTONUP:
				//if one click then turn monitor off:
				if (m_nTicks>18) // but wait longer: 18x50 =900 msec.
				{
					if (MonitorOffSupport()==TRUE)
					{
						SendMessage(WM_SYSCOMMAND, SC_MONITORPOWER, 2L);
					}
					else //no monitor-off support, just kick in screen saver.
					{
						SendMessage(WM_SYSCOMMAND, SC_SCREENSAVE, 0L);
					}
					m_BtnClicked = 0;
				}
				break;
			case WM_TPSCREENSAVER:
				if (m_nTicks>10) // but wait longer
				{
					SendMessage(WM_SYSCOMMAND, SC_SCREENSAVE, 0L);
					m_BtnClicked = 0;
				}
				break;
			default:
				if (m_nTicks > 100)
				{
					//TRACE(_T("OnTimer - default, %d ticks.\n", m_nTicks));
					m_pD3jo->Render();
					ResetTimerTicks();

				}
				break;
			}
		}
	}
	else //m_DblClicked=TRUE;
	{
		m_DblClicked=FALSE;
		m_BtnClicked = 0;
		ResetTimerTicks();
	}
	CFrameWnd::OnTimer(nIDEvent);
}

void CMainFrame::ResetTimerTicks()
{
	m_nTicks = 0;
}

void CMainFrame::OnStartTimer()
{
	m_nTicks = 0;
	m_nTimer = SetTimer(1, 50, 0);
}

void CMainFrame::OnStopTimer()
{
	if (m_nTimer != 0)
	{
		KillTimer(m_nTimer);
		m_nTimer = 0;
	}
}

void CMainFrame::DoMenuDropDown()
{
	CMenu menu;
	if (!menu.LoadMenu(IDR_TRAYICON))
		return;
	CMenu* pSubMenu = menu.GetSubMenu(0);
	if (!pSubMenu) 
		return;

		// Make first menu item the default (bold font)
		//::SetMenuDefaultItem(pSubMenu->m_hMenu, 0, TRUE);

		// Display the menu at the current mouse location. There's a "bug"
		// (Microsoft calls it a feature) in Windows 95 that requires calling
		// SetForegroundWindow. To find out more, search for Q135788 in MSDN.
		//
		CPoint mouse;
		GetCursorPos(&mouse);
		::SetForegroundWindow(m_hWnd);	
		::TrackPopupMenu(pSubMenu->m_hMenu, 0, mouse.x, mouse.y, 0,
			m_hWnd, NULL);
}

BOOL CMainFrame::IsShiftKeyDown()
{
	return ((GetAsyncKeyState(VK_SHIFT) & 0x8000)!=0);
}

// Function MonitorOffSupport()
//This function determines if the operating system supports monitor off
//Returns false for NT4, true for Win95,98,2000
BOOL CMainFrame::MonitorOffSupport()
{
	if(IsWindowsVersionOrGreater(4, 0, 0)) {
		if (IsWindowsVersionOrGreater(5, 0, 0))
		{
			return TRUE; // NT 5 or more
		}
		return FALSE; // NT 4 or less
	}
	return TRUE; //Win95,98 etc...
}

void CMainFrame::OnEndSession(BOOL bEnding) 
{
	CFrameWnd::OnEndSession(bEnding);
	
	// Force app to quit:
	OnAppTpExit();
}


================================================
FILE: src/TrayIcon.CPP
================================================
////////////////////////////////////////////////////////////////
// CTrayIcon adopted from Microsoft Systems Journal's CTrayIcon by Paul DiLascia.
//

#include "stdafx.h"
#include "trayicon.h"
#include <afxpriv.h>		// for AfxLoadString

IMPLEMENT_DYNAMIC(CTrayIcon, CCmdTarget)

CTrayIcon::CTrayIcon(UINT uID)
{
	// Initialize NOTIFYICONDATA
	memset(&m_nid, 0 , sizeof(m_nid));
	m_nid.cbSize = sizeof(m_nid);
	m_nid.uID = uID;	// never changes after construction

	// Use resource string as tip if there is one
	AfxLoadString(uID, m_nid.szTip, sizeof(m_nid.szTip));
}

CTrayIcon::~CTrayIcon()
{
	SetIcon(0); // remove icon from system tray
}

//////////////////
// Set notification window. It must created already.
//
void CTrayIcon::SetNotificationWnd(CWnd* pNotifyWnd, UINT uCbMsg)
{
	// If the following assert fails, you're probably
	// calling me before you created your window. Oops.
	ASSERT(pNotifyWnd==NULL || ::IsWindow(pNotifyWnd->GetSafeHwnd()));
	m_nid.hWnd = pNotifyWnd->GetSafeHwnd();

	ASSERT(uCbMsg==0 || uCbMsg>=WM_USER);
	m_nid.uCallbackMessage = uCbMsg;
}

//////////////////
// This is the main variant for setting the icon.
// Sets both the icon and tooltip from resource ID
// To remove the icon, call SetIcon(0)
//
BOOL CTrayIcon::SetIcon(UINT uID)
{ 
	HICON hicon=NULL;
	if (uID) {
		AfxLoadString(uID, m_nid.szTip, sizeof(m_nid.szTip));
		//hicon = AfxGetApp()->LoadIcon(uID);
		hicon=(HICON) LoadImage(AfxGetInstanceHandle(),MAKEINTRESOURCE(uID),IMAGE_ICON,16,16,LR_DEFAULTCOLOR);
	}
	return SetIcon(hicon, NULL);
}

//////////////////
// Common SetIcon for all overloads. 
//
BOOL CTrayIcon::SetIcon(HICON hicon, LPCSTR lpTip) 
{
	UINT msg;
	m_nid.uFlags = 0;

	// Set the icon
	if (hicon) {
		// Add or replace icon in system tray
		msg = m_nid.hIcon ? NIM_MODIFY : NIM_ADD;
		m_nid.hIcon = hicon;
		//m_nid.uFlags |= NIF_ICON; //NIF_ICON Or NIF_TIP Or NIF_MESSAGE
		m_nid.uFlags = NIF_ICON; //NIF_ICON Or NIF_TIP Or NIF_MESSAGE
	} else { // remove icon from tray
		if (m_nid.hIcon==NULL)
			return TRUE;		// already deleted
		msg = NIM_DELETE;
	}

	// Use the tip, if any
	if (lpTip)
		strcpy_s(m_nid.szTip, sizeof(m_nid.szTip), lpTip);
	if (m_nid.szTip[0])
		m_nid.uFlags |= NIF_TIP;

	// Use callback if any
	if (m_nid.uCallbackMessage && m_nid.hWnd)
		m_nid.uFlags |= NIF_MESSAGE;

	// Do it
	BOOL bRet = Shell_NotifyIcon(msg, &m_nid);
	if (msg==NIM_DELETE || !bRet)
		m_nid.hIcon = NULL;	// failed
	return bRet;
}


================================================
FILE: src/TrayPwr.cpp
================================================
////////////////////////////////////////////////////////////////
// TrayPwr Adopted from Microsoft Systems Journal's CTrayIcon by Paul DiLascia.
//
// All the activity takes place in MainFrm.cpp.

#include "stdafx.h"
#include "TrayPwr.h"
#include "mainfrm.h"
#include "AboutDlg.h"
#include <io.h>
#include <TlHelp32.h>

CMyApp theApp;

BEGIN_MESSAGE_MAP(CMyApp, CWinApp)
	//{{AFX_MSG_MAP(CMyApp)
	ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

namespace {
	// Return PID of first other process that has the same executable name as this process.
	DWORD FindOtherInstancePid()
	{
		DWORD myPid = GetCurrentProcessId();

		TCHAR myPath[MAX_PATH] = { 0 };
		if (!GetModuleFileName(NULL, myPath, _countof(myPath)))
			return 0;
		// Extract executable file name only (e.g. "TrayPwrD3.exe")
		TCHAR *pName = _tcsrchr(myPath, '\\');
		LPCTSTR myExeName = pName ? pName + 1 : myPath;

		HANDLE hsnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
		if (hsnap == INVALID_HANDLE_VALUE)
			return 0;

		PROCESSENTRY32 pe = { 0 };
		pe.dwSize = sizeof(pe);
		if (Process32First(hsnap, &pe))
		{
			do
			{
				// szExeFile holds the base exe name
				if (pe.th32ProcessID != myPid &&
					_tcsicmp(pe.szExeFile, myExeName) == 0)
				{
					CloseHandle(hsnap);
					return pe.th32ProcessID;
				}
			} while (Process32Next(hsnap, &pe));
		}
		CloseHandle(hsnap);
		return 0;
	}

	// Terminates the process with the given PID. Returns TRUE on success.
	BOOL TerminateProcessByPid(DWORD pid, DWORD timeoutMs = 5000)
	{
		HANDLE hProc = OpenProcess(PROCESS_TERMINATE | SYNCHRONIZE, FALSE, pid);
		if (!hProc)
			return FALSE;
		BOOL ok = TerminateProcess(hProc, 0) != FALSE;
		if (ok)
		{
			WaitForSingleObject(hProc, timeoutMs);
		}
		CloseHandle(hProc);
		return ok;
	}
}

CMyApp::CMyApp()
{

}

BOOL CMyApp::InitInstance()
{
	// Check for another running instance of this exe
	DWORD otherPid = FindOtherInstancePid();
	if (otherPid != 0)
	{
		CString msg;
		msg.Format(_T("Another instance of %s is already running (PID %u).\n\n"
			"Do you want to terminate the running instance and continue?"),
			AfxGetAppName(), otherPid);
		int res = AfxMessageBox(msg, MB_YESNO | MB_ICONQUESTION);
		if (res == IDYES)
		{
			if (!TerminateProcessByPid(otherPid))
			{
				AfxMessageBox(_T("Failed to terminate the running instance. Startup will be cancelled."),
					MB_OK | MB_ICONERROR);
				return FALSE;
			}
			// optionally wait a moment to ensure process is gone
			Sleep(200);
		}
		else
		{
			// user chose not to terminate the other instance -> exit
			return FALSE;
		}
	}

	// Create main frame window (don't use doc/view stuff)
	m_bAboutDialogActive=FALSE;
	CMainFrame* pMainFrame = new CMainFrame;
	if (!pMainFrame->LoadFrame(IDR_MAINFRAME))
		return FALSE;
	m_pMainWnd = pMainFrame;
	return TRUE;
}

void CMyApp::OnAppAbout()
{
	CAboutDlg aboutDlg; 
	aboutDlg.DoModal();
}


================================================
FILE: src/TrayPwr.h
================================================
////////////////////////////////////////////////////////////////
// TrayPwr Copyright 1996 Microsoft Systems Journal.
// See TrayPwr.CPP for description of program.
//
#include "resource.h"
#include "D3dx12jo.h"

class CMyApp : public CWinApp {
public:
	CMyApp();

	virtual BOOL InitInstance();
	//{{AFX_MSG(CMyApp)
	afx_msg void OnAppAbout();
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
protected:

private:
	BOOL m_bAboutDialogActive;
};


================================================
FILE: src/TrayPwr.rc
================================================
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"

/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS

/////////////////////////////////////////////////////////////////////////////
// English (United States) resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)

#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//

1 TEXTINCLUDE 
BEGIN
    "resource.h\0"
END

2 TEXTINCLUDE 
BEGIN
    "#include ""afxres.h""\r\n"
    "\0"
END

3 TEXTINCLUDE 
BEGIN
    "#define _AFX_NO_SPLITTER_RESOURCES\r\n"
    "#define _AFX_NO_OLE_RESOURCES\r\n"
    "#define _AFX_NO_TRACKER_RESOURCES\r\n"
    "#define _AFX_NO_PROPERTY_RESOURCES\r\n"
    "\r\n"
    "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
    "#ifdef _WIN32\r\n"
    "LANGUAGE 9, 1\r\n"
    "#pragma code_page(1252)\r\n"
    "#endif\r\n"
    "#include ""res\\app.rc2""  // non-Microsoft Visual C++ edited resources\r\n"
    "#include ""afxres.rc""         // Standard components\r\n"
    "#endif\0"
END

#endif    // APSTUDIO_INVOKED


/////////////////////////////////////////////////////////////////////////////
//
// Icon
//

// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDR_MAINFRAME           ICON                    "res\\app.ico"

IDI_MYICON              ICON                    "res\\myicon.ico"


/////////////////////////////////////////////////////////////////////////////
//
// Menu
//

IDR_MAINFRAME MENU
BEGIN
    POPUP "&File"
    BEGIN
        MENUITEM "&About TrayPwr...",           ID_APP_ABOUT
        MENUITEM "E&xit",                       ID_APP_EXIT
    END
    POPUP "&View"
    BEGIN
        MENUITEM "&Status Bar",                 ID_VIEW_STATUS_BAR
    END
END

IDR_TRAYICON MENU
BEGIN
    POPUP "&Tray"
    BEGIN
        MENUITEM "&Help...",                    ID_APP_ABOUT
        MENUITEM "&Log off",                    ID_TPLOGOFF
        MENUITEM "Shut &down",                  ID_TPSHUTDOWN
        MENUITEM "&Restart",                    ID_TPRESTART
        MENUITEM "Stand &by",                   ID_TPSTANDBY
        MENUITEM "&Screen Saver",               ID_TPSCREENSAVE
        MENUITEM "E&xit",                       ID_APPTP_EXIT
    END
END


/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//

IDD_ABOUTBOX DIALOGEX 0, 0, 268, 188
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "TrayPower D3 Help"
FONT 8, "MS Sans Serif", 0, 0, 0x0
BEGIN
    DEFPUSHBUTTON   "&OK",IDOK,206,64,56,15,WS_GROUP
    LTEXT           "TrayPower D3 (Keeps dGPU on/idle)\nVersion 1.7.0.0",IDC_STATIC,36,7,154,17,NOT WS_GROUP
    LTEXT           "Copyright  2020  J. S. Obeid",IDC_STATIC,36,23,167,9,NOT WS_GROUP
    ICON            IDR_MAINFRAME,IDC_STATIC,9,9,20,20,SS_SUNKEN
    LTEXT           "Keeps dGPU idle + sits in tray icon. Options:",IDC_STATIC,6,34,237,9,NOT WS_GROUP
    LTEXT           "Left click: turns monitor off, and saves battery power without powering down. ",IDC_STATIC,6,42,240,9,NOT WS_GROUP
    PUSHBUTTON      "&System Info...",IDSYSINFO,206,6,56,15,WS_GROUP
    LTEXT           "Right click: power-down menu.\nRight double click : restarts computer.\nShift Left double click: goes into Stand by.\nShift Right double click: logs off. ",IDC_STATIC,6,49,141,35,NOT WS_GROUP
    EDITTEXT        IDC_EDITLIC,6,84,256,100,ES_MULTILINE | ES_AUTOHSCROLL | ES_READONLY | WS_VSCROLL | WS_HSCROLL
END


/////////////////////////////////////////////////////////////////////////////
//
// Version
//

AFX_ID_PREVIEW_ZOOMOUT VERSIONINFO
 FILEVERSION 1,8,0,0
 PRODUCTVERSION 1,8,0,0
 FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
 FILEFLAGS 0x1L
#else
 FILEFLAGS 0x0L
#endif
 FILEOS 0x4L
 FILETYPE 0x1L
 FILESUBTYPE 0x0L
BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "040904b0"
        BEGIN
            VALUE "Comments", "Tray Power D3"
            VALUE "CompanyName", "J Obeid Software"
            VALUE "FileDescription", "TrayPwrD3"
            VALUE "FileVersion", "1.8.0.0"
            VALUE "InternalName", "TrayPwr"
            VALUE "LegalCopyright", "Copyright  2025  J. S. Obeid"
            VALUE "OriginalFilename", "TrayPwr.exe"
            VALUE "ProductName", "Tray Power D3"
            VALUE "ProductVersion", "1.8.0.0"
        END
    END
    BLOCK "VarFileInfo"
    BEGIN
        VALUE "Translation", 0x409, 1200
    END
END


/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//

#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
    IDD_ABOUTBOX, DIALOG
    BEGIN
        LEFTMARGIN, 6
        RIGHTMARGIN, 262
        TOPMARGIN, 6
        BOTTOMMARGIN, 184
    END
END
#endif    // APSTUDIO_INVOKED


/////////////////////////////////////////////////////////////////////////////
//
// AFX_DIALOG_LAYOUT
//

IDD_ABOUTBOX AFX_DIALOG_LAYOUT
BEGIN
    0
END


/////////////////////////////////////////////////////////////////////////////
//
// String Table
//

STRINGTABLE
BEGIN
    IDR_MAINFRAME           "Tray Power"
END

STRINGTABLE
BEGIN
    IDI_MYICON              "TrayPwrD3 - monitor off"
END

STRINGTABLE
BEGIN
    AFX_IDS_APP_TITLE       "TrayPwrD3"
    AFX_IDS_IDLEMESSAGE     "Ready"
END

STRINGTABLE
BEGIN
    ID_APP_ABOUT            "Display program information"
    ID_APP_EXIT             "Hide window"
END

STRINGTABLE
BEGIN
    ID_APPTP_EXIT           "Quit Tray Power and remove from system tray"
END

#endif    // English (United States) resources
/////////////////////////////////////////////////////////////////////////////



#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#define _AFX_NO_SPLITTER_RESOURCES
#define _AFX_NO_OLE_RESOURCES
#define _AFX_NO_TRACKER_RESOURCES
#define _AFX_NO_PROPERTY_RESOURCES

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE 9, 1
#pragma code_page(1252)
#endif
#include "res\app.rc2"  // non-Microsoft Visual C++ edited resources
#include "afxres.rc"         // Standard components
#endif
/////////////////////////////////////////////////////////////////////////////
#endif    // not APSTUDIO_INVOKED



================================================
FILE: src/TrayPwr.sln
================================================

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TrayPwr", "TrayPwr.vcxproj", "{8B5413C2-0C8A-4E4F-A42E-C3AE5A763DA4}"
EndProject
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|x64 = Debug|x64
		Debug|x86 = Debug|x86
		Release|x64 = Release|x64
		Release|x86 = Release|x86
	EndGlobalSection
	GlobalSection(ProjectConfigurationPlatforms) = postSolution
		{8B5413C2-0C8A-4E4F-A42E-C3AE5A763DA4}.Debug|x64.ActiveCfg = Debug|x64
		{8B5413C2-0C8A-4E4F-A42E-C3AE5A763DA4}.Debug|x64.Build.0 = Debug|x64
		{8B5413C2-0C8A-4E4F-A42E-C3AE5A763DA4}.Debug|x86.ActiveCfg = Debug|Win32
		{8B5413C2-0C8A-4E4F-A42E-C3AE5A763DA4}.Debug|x86.Build.0 = Debug|Win32
		{8B5413C2-0C8A-4E4F-A42E-C3AE5A763DA4}.Release|x64.ActiveCfg = Release|x64
		{8B5413C2-0C8A-4E4F-A42E-C3AE5A763DA4}.Release|x64.Build.0 = Release|x64
		{8B5413C2-0C8A-4E4F-A42E-C3AE5A763DA4}.Release|x86.ActiveCfg = Release|Win32
		{8B5413C2-0C8A-4E4F-A42E-C3AE5A763DA4}.Release|x86.Build.0 = Release|Win32
	EndGlobalSection
	GlobalSection(SolutionProperties) = preSolution
		HideSolutionNode = FALSE
	EndGlobalSection
EndGlobal


================================================
FILE: src/TrayPwr.vcxproj
================================================
<?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="Debug|x64">
      <Configuration>Debug</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|Win32">
      <Configuration>Release</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|x64">
      <Configuration>Release</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
  </ItemGroup>
  <PropertyGroup Label="Globals">
    <SccProjectName />
    <SccLocalPath />
    <Keyword>MFCProj</Keyword>
    <ProjectGuid>{8B5413C2-0C8A-4E4F-A42E-C3AE5A763DA4}</ProjectGuid>
    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
    <ProjectName>TrayPwrD3</ProjectName>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
    <PlatformToolset>v143</PlatformToolset>
    <UseOfMfc>Dynamic</UseOfMfc>
    <CharacterSet>MultiByte</CharacterSet>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
    <PlatformToolset>v143</PlatformToolset>
    <UseOfMfc>Dynamic</UseOfMfc>
    <CharacterSet>MultiByte</CharacterSet>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
    <PlatformToolset>v143</PlatformToolset>
    <UseOfMfc>Dynamic</UseOfMfc>
    <CharacterSet>MultiByte</CharacterSet>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
    <PlatformToolset>v143</PlatformToolset>
    <UseOfMfc>Dynamic</UseOfMfc>
    <CLRSupport>true</CLRSupport>
    <CharacterSet>NotSet</CharacterSet>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
  <ImportGroup Label="ExtensionSettings">
  </ImportGroup>
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
    <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
  </ImportGroup>
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
    <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
  </ImportGroup>
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
    <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
  </ImportGroup>
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
    <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
  </ImportGroup>
  <PropertyGroup Label="UserMacros" />
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <OutDir>.\Release\</OutDir>
    <IntDir>.\Release\</IntDir>
    <LinkIncremental>false</LinkIncremental>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <LinkIncremental>false</LinkIncremental>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    <OutDir>.\Debug\</OutDir>
    <IntDir>.\Debug\</IntDir>
    <LinkIncremental>true</LinkIncremental>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <LinkIncremental>true</LinkIncremental>
  </PropertyGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <ClCompile>
      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
      <InlineFunctionExpansion>Default</InlineFunctionExpansion>
      <StringPooling>true</StringPooling>
      <FunctionLevelLinking>true</FunctionLevelLinking>
      <Optimization>MinSpace</Optimization>
      <SuppressStartupBanner>true</SuppressStartupBanner>
      <WarningLevel>Level3</WarningLevel>
      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <AssemblerListingLocation>.\Release\</AssemblerListingLocation>
      <BrowseInformation>true</BrowseInformation>
      <PrecompiledHeaderOutputFile>.\Release\TrayPwr.pch</PrecompiledHeaderOutputFile>
      <PrecompiledHeader>Use</PrecompiledHeader>
      <PrecompiledHeaderFile>STDAFX.H</PrecompiledHeaderFile>
      <ObjectFileName>.\Release\</ObjectFileName>
      <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName>
    </ClCompile>
    <Midl>
      <SuppressStartupBanner>true</SuppressStartupBanner>
      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <TypeLibraryName>.\Release\TrayPwr.tlb</TypeLibraryName>
      <MkTypLibCompatible>true</MkTypLibCompatible>
      <TargetEnvironment>Win32</TargetEnvironment>
    </Midl>
    <ResourceCompile>
      <Culture>0x0409</Culture>
      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ResourceCompile>
    <Bscmake>
      <SuppressStartupBanner>true</SuppressStartupBanner>
      <OutputFile>.\Release\TrayPwr.bsc</OutputFile>
    </Bscmake>
    <Link>
      <SuppressStartupBanner>true</SuppressStartupBanner>
      <OutputFile>.\Release\TrayPwr.exe</OutputFile>
      <AdditionalDependencies>oldnames.lib;%(AdditionalDependencies)</AdditionalDependencies>
      <StackReserveSize>10240</StackReserveSize>
      <SubSystem>Windows</SubSystem>
    </Link>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <ClCompile>
      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
      <InlineFunctionExpansion>Default</InlineFunctionExpansion>
      <StringPooling>true</StringPooling>
      <FunctionLevelLinking>true</FunctionLevelLinking>
      <Optimization>MinSpace</Optimization>
      <SuppressStartupBanner>true</SuppressStartupBanner>
      <WarningLevel>Level3</WarningLevel>
      <BrowseInformation>true</BrowseInformation>
      <PrecompiledHeader>Use</PrecompiledHeader>
      <PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
      <CompileAsManaged>true</CompileAsManaged>
      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;NO_WARN_MBCS_MFC_DEPRECATION;%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ClCompile>
    <Midl>
      <SuppressStartupBanner>true</SuppressStartupBanner>
      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <TypeLibraryName>.\Release\TrayPwr.tlb</TypeLibraryName>
      <MkTypLibCompatible>true</MkTypLibCompatible>
    </Midl>
    <ResourceCompile>
      <Culture>0x0409</Culture>
      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ResourceCompile>
    <Bscmake>
      <SuppressStartupBanner>true</SuppressStartupBanner>
    </Bscmake>
    <Link>
      <SuppressStartupBanner>true</SuppressStartupBanner>
      <AdditionalDependencies>d3d12.lib;dxgi.lib;d3dcompiler.lib;%(AdditionalDependencies)</AdditionalDependencies>
      <StackReserveSize>10240</StackReserveSize>
      <SubSystem>Windows</SubSystem>
    </Link>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    <ClCompile>
      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
      <InlineFunctionExpansion>Default</InlineFunctionExpansion>
      <FunctionLevelLinking>false</FunctionLevelLinking>
      <Optimization>Disabled</Optimization>
      <SuppressStartupBanner>true</SuppressStartupBanner>
      <WarningLevel>Level3</WarningLevel>
      <MinimalRebuild>true</MinimalRebuild>
      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <AssemblerListingLocation>.\Debug\</AssemblerListingLocation>
      <BrowseInformation>true</BrowseInformation>
      <PrecompiledHeaderOutputFile>.\Debug\TrayPwr.pch</PrecompiledHeaderOutputFile>
      <PrecompiledHeader>Use</PrecompiledHeader>
      <PrecompiledHeaderFile>STDAFX.H</PrecompiledHeaderFile>
      <ObjectFileName>.\Debug\</ObjectFileName>
      <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName>
    </ClCompile>
    <Midl>
      <SuppressStartupBanner>true</SuppressStartupBanner>
      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <TypeLibraryName>.\Debug\TrayPwr.tlb</TypeLibraryName>
      <MkTypLibCompatible>true</MkTypLibCompatible>
      <TargetEnvironment>Win32</TargetEnvironment>
    </Midl>
    <ResourceCompile>
      <Culture>0x0409</Culture>
      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ResourceCompile>
    <Bscmake>
      <SuppressStartupBanner>true</SuppressStartupBanner>
      <OutputFile>.\Debug\TrayPwr.bsc</OutputFile>
    </Bscmake>
    <Link>
      <SuppressStartupBanner>true</SuppressStartupBanner>
      <GenerateDebugInformation>true</GenerateDebugInformation>
      <OutputFile>.\Debug\TrayPwr.exe</OutputFile>
      <AdditionalDependencies>oldnames.lib;%(AdditionalDependencies)</AdditionalDependencies>
      <StackReserveSize>10240</StackReserveSize>
      <SubSystem>Windows</SubSystem>
    </Link>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <ClCompile>
      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
      <InlineFunctionExpansion>Default</InlineFunctionExpansion>
      <FunctionLevelLinking>false</FunctionLevelLinking>
      <Optimization>Disabled</Optimization>
      <SuppressStartupBanner>true</SuppressStartupBanner>
      <WarningLevel>Level3</WarningLevel>
      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;NO_WARN_MBCS_MFC_DEPRECATION;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <BrowseInformation>true</BrowseInformation>
      <PrecompiledHeader>Use</PrecompiledHeader>
      <PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
      <ShowIncludes>false</ShowIncludes>
    </ClCompile>
    <Midl>
      <SuppressStartupBanner>true</SuppressStartupBanner>
      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <TypeLibraryName>.\Debug\TrayPwr.tlb</TypeLibraryName>
      <MkTypLibCompatible>true</MkTypLibCompatible>
    </Midl>
    <ResourceCompile>
      <Culture>0x0409</Culture>
      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ResourceCompile>
    <Bscmake>
      <SuppressStartupBanner>true</SuppressStartupBanner>
    </Bscmake>
    <Link>
      <SuppressStartupBanner>true</SuppressStartupBanner>
      <GenerateDebugInformation>true</GenerateDebugInformation>
      <AdditionalDependencies>d3d12.lib;dxgi.lib;d3dcompiler.lib;%(AdditionalDependencies)</AdditionalDependencies>
      <StackReserveSize>10240</StackReserveSize>
      <SubSystem>Windows</SubSystem>
    </Link>
  </ItemDefinitionGroup>
  <ItemGroup>
    <ClCompile Include="AboutDlg.cpp" />
    <ClCompile Include="D3dx12jo.cpp" />
    <ClCompile Include="Mainfrm.cpp" />
    <ClCompile Include="stdafx.cpp">
      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
    </ClCompile>
    <ClCompile Include="TrayIcon.CPP" />
    <ClCompile Include="TrayPwr.cpp">
      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Use</PrecompiledHeader>
    </ClCompile>
  </ItemGroup>
  <ItemGroup>
    <ResourceCompile Include="TrayPwr.rc" />
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="AboutDlg.h" />
    <ClInclude Include="d3dx12.h" />
    <ClInclude Include="D3dx12jo.h" />
    <ClInclude Include="mainfrm.h" />
    <ClInclude Include="RESOURCE.H" />
    <ClInclude Include="stdafx.h" />
    <ClInclude Include="trayicon.h" />
    <ClInclude Include="TrayPwr.h" />
  </ItemGroup>
  <ItemGroup>
    <Image Include="res\APP.ICO" />
    <Image Include="res\MYICON.ICO" />
  </ItemGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
  <ImportGroup Label="ExtensionTargets">
  </ImportGroup>
  <ProjectExtensions>
    <VisualStudio>
      <UserProperties RESOURCE_FILE="TrayPwr.rc" />
    </VisualStudio>
  </ProjectExtensions>
</Project>

================================================
FILE: src/TrayPwr.vcxproj.user
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <RESOURCE_FILE>TrayPwr.rc</RESOURCE_FILE>
    <ShowAllFiles>true</ShowAllFiles>
  </PropertyGroup>
</Project>

================================================
FILE: src/d3dx12.h
================================================
//////////////////////////////////////////////////////////////////////////////
//
//  Copyright (C) Microsoft Corporation.  All Rights Reserved.
//
//  File:       d3dx12.h
//  Content:    D3DX12 utility library
//
//////////////////////////////////////////////////////////////////////////////

#ifndef __D3DX12_H__
#define __D3DX12_H__

#include "d3d12.h"

#if defined( __cplusplus )

struct CD3DX12_DEFAULT {};
extern const DECLSPEC_SELECTANY CD3DX12_DEFAULT D3D12_DEFAULT;

//------------------------------------------------------------------------------------------------
inline bool operator==(const D3D12_VIEWPORT& l, const D3D12_VIEWPORT& r)
{
	return l.TopLeftX == r.TopLeftX && l.TopLeftY == r.TopLeftY && l.Width == r.Width &&
		l.Height == r.Height && l.MinDepth == r.MinDepth && l.MaxDepth == r.MaxDepth;
}

//------------------------------------------------------------------------------------------------
inline bool operator!=(const D3D12_VIEWPORT& l, const D3D12_VIEWPORT& r)
{
	return !(l == r);
}

//------------------------------------------------------------------------------------------------
struct CD3DX12_RECT : public D3D12_RECT
{
	CD3DX12_RECT()
	{}
	explicit CD3DX12_RECT(const D3D12_RECT& o) :
		D3D12_RECT(o)
	{}
	explicit CD3DX12_RECT(
		LONG Left,
		LONG Top,
		LONG Right,
		LONG Bottom)
	{
		left = Left;
		top = Top;
		right = Right;
		bottom = Bottom;
	}
	~CD3DX12_RECT() {}
	operator const D3D12_RECT&() const { return *this; }
};

//------------------------------------------------------------------------------------------------
struct CD3DX12_BOX : public D3D12_BOX
{
	CD3DX12_BOX()
	{}
	explicit CD3DX12_BOX(const D3D12_BOX& o) :
		D3D12_BOX(o)
	{}
	explicit CD3DX12_BOX(
		LONG Left,
		LONG Right)
	{
		left = Left;
		top = 0;
		front = 0;
		right = Right;
		bottom = 1;
		back = 1;
	}
	explicit CD3DX12_BOX(
		LONG Left,
		LONG Top,
		LONG Right,
		LONG Bottom)
	{
		left = Left;
		top = Top;
		front = 0;
		right = Right;
		bottom = Bottom;
		back = 1;
	}
	explicit CD3DX12_BOX(
		LONG Left,
		LONG Top,
		LONG Front,
		LONG Right,
		LONG Bottom,
		LONG Back)
	{
		left = Left;
		top = Top;
		front = Front;
		right = Right;
		bottom = Bottom;
		back = Back;
	}
	~CD3DX12_BOX() {}
	operator const D3D12_BOX&() const { return *this; }
};
inline bool operator==(const D3D12_BOX& l, const D3D12_BOX& r)
{
	return l.left == r.left && l.top == r.top && l.front == r.front &&
		l.right == r.right && l.bottom == r.bottom && l.back == r.back;
}
inline bool operator!=(const D3D12_BOX& l, const D3D12_BOX& r)
{
	return !(l == r);
}

//------------------------------------------------------------------------------------------------
struct CD3DX12_DEPTH_STENCIL_DESC : public D3D12_DEPTH_STENCIL_DESC
{
	CD3DX12_DEPTH_STENCIL_DESC()
	{}
	explicit CD3DX12_DEPTH_STENCIL_DESC(const D3D12_DEPTH_STENCIL_DESC& o) :
		D3D12_DEPTH_STENCIL_DESC(o)
	{}
	explicit CD3DX12_DEPTH_STENCIL_DESC(CD3DX12_DEFAULT)
	{
		DepthEnable = TRUE;
		DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL;
		DepthFunc = D3D12_COMPARISON_FUNC_LESS;
		StencilEnable = FALSE;
		StencilReadMask = D3D12_DEFAULT_STENCIL_READ_MASK;
		StencilWriteMask = D3D12_DEFAULT_STENCIL_WRITE_MASK;
		const D3D12_DEPTH_STENCILOP_DESC defaultStencilOp =
		{ D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_COMPARISON_FUNC_ALWAYS };
		FrontFace = defaultStencilOp;
		BackFace = defaultStencilOp;
	}
	explicit CD3DX12_DEPTH_STENCIL_DESC(
		BOOL depthEnable,
		D3D12_DEPTH_WRITE_MASK depthWriteMask,
		D3D12_COMPARISON_FUNC depthFunc,
		BOOL stencilEnable,
		UINT8 stencilReadMask,
		UINT8 stencilWriteMask,
		D3D12_STENCIL_OP frontStencilFailOp,
		D3D12_STENCIL_OP frontStencilDepthFailOp,
		D3D12_STENCIL_OP frontStencilPassOp,
		D3D12_COMPARISON_FUNC frontStencilFunc,
		D3D12_STENCIL_OP backStencilFailOp,
		D3D12_STENCIL_OP backStencilDepthFailOp,
		D3D12_STENCIL_OP backStencilPassOp,
		D3D12_COMPARISON_FUNC backStencilFunc)
	{
		DepthEnable = depthEnable;
		DepthWriteMask = depthWriteMask;
		DepthFunc = depthFunc;
		StencilEnable = stencilEnable;
		StencilReadMask = stencilReadMask;
		StencilWriteMask = stencilWriteMask;
		FrontFace.StencilFailOp = frontStencilFailOp;
		FrontFace.StencilDepthFailOp = frontStencilDepthFailOp;
		FrontFace.StencilPassOp = frontStencilPassOp;
		FrontFace.StencilFunc = frontStencilFunc;
		BackFace.StencilFailOp = backStencilFailOp;
		BackFace.StencilDepthFailOp = backStencilDepthFailOp;
		BackFace.StencilPassOp = backStencilPassOp;
		BackFace.StencilFunc = backStencilFunc;
	}
	~CD3DX12_DEPTH_STENCIL_DESC() {}
	operator const D3D12_DEPTH_STENCIL_DESC&() const { return *this; }
};

//------------------------------------------------------------------------------------------------
struct CD3DX12_BLEND_DESC : public D3D12_BLEND_DESC
{
	CD3DX12_BLEND_DESC()
	{}
	explicit CD3DX12_BLEND_DESC(const D3D12_BLEND_DESC& o) :
		D3D12_BLEND_DESC(o)
	{}
	explicit CD3DX12_BLEND_DESC(CD3DX12_DEFAULT)
	{
		AlphaToCoverageEnable = FALSE;
		IndependentBlendEnable = FALSE;
		const D3D12_RENDER_TARGET_BLEND_DESC defaultRenderTargetBlendDesc =
		{
			FALSE,FALSE,
			D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD,
			D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD,
			D3D12_LOGIC_OP_NOOP,
			D3D12_COLOR_WRITE_ENABLE_ALL,
		};
		for (UINT i = 0; i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i)
			RenderTarget[i] = defaultRenderTargetBlendDesc;
	}
	~CD3DX12_BLEND_DESC() {}
	operator const D3D12_BLEND_DESC&() const { return *this; }
};

//------------------------------------------------------------------------------------------------
struct CD3DX12_RASTERIZER_DESC : public D3D12_RASTERIZER_DESC
{
	CD3DX12_RASTERIZER_DESC()
	{}
	explicit CD3DX12_RASTERIZER_DESC(const D3D12_RASTERIZER_DESC& o) :
		D3D12_RASTERIZER_DESC(o)
	{}
	explicit CD3DX12_RASTERIZER_DESC(CD3DX12_DEFAULT)
	{
		FillMode = D3D12_FILL_MODE_SOLID;
		CullMode = D3D12_CULL_MODE_BACK;
		FrontCounterClockwise = FALSE;
		DepthBias = D3D12_DEFAULT_DEPTH_BIAS;
		DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP;
		SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS;
		DepthClipEnable = TRUE;
		MultisampleEnable = FALSE;
		AntialiasedLineEnable = FALSE;
		ForcedSampleCount = 0;
		ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;
	}
	explicit CD3DX12_RASTERIZER_DESC(
		D3D12_FILL_MODE fillMode,
		D3D12_CULL_MODE cullMode,
		BOOL frontCounterClockwise,
		INT depthBias,
		FLOAT depthBiasClamp,
		FLOAT slopeScaledDepthBias,
		BOOL depthClipEnable,
		BOOL multisampleEnable,
		BOOL antialiasedLineEnable,
		UINT forcedSampleCount,
		D3D12_CONSERVATIVE_RASTERIZATION_MODE conservativeRaster)
	{
		FillMode = fillMode;
		CullMode = cullMode;
		FrontCounterClockwise = frontCounterClockwise;
		DepthBias = depthBias;
		DepthBiasClamp = depthBiasClamp;
		SlopeScaledDepthBias = slopeScaledDepthBias;
		DepthClipEnable = depthClipEnable;
		MultisampleEnable = multisampleEnable;
		AntialiasedLineEnable = antialiasedLineEnable;
		ForcedSampleCount = forcedSampleCount;
		ConservativeRaster = conservativeRaster;
	}
	~CD3DX12_RASTERIZER_DESC() {}
	operator const D3D12_RASTERIZER_DESC&() const { return *this; }
};

//------------------------------------------------------------------------------------------------
struct CD3DX12_RESOURCE_ALLOCATION_INFO : public D3D12_RESOURCE_ALLOCATION_INFO
{
	CD3DX12_RESOURCE_ALLOCATION_INFO()
	{}
	explicit CD3DX12_RESOURCE_ALLOCATION_INFO(const D3D12_RESOURCE_ALLOCATION_INFO& o) :
		D3D12_RESOURCE_ALLOCATION_INFO(o)
	{}
	CD3DX12_RESOURCE_ALLOCATION_INFO(
		UINT64 size,
		UINT64 alignment)
	{
		SizeInBytes = size;
		Alignment = alignment;
	}
	operator const D3D12_RESOURCE_ALLOCATION_INFO&() const { return *this; }
};

//------------------------------------------------------------------------------------------------
struct CD3DX12_HEAP_PROPERTIES : public D3D12_HEAP_PROPERTIES
{
	CD3DX12_HEAP_PROPERTIES()
	{}
	explicit CD3DX12_HEAP_PROPERTIES(const D3D12_HEAP_PROPERTIES &o) :
		D3D12_HEAP_PROPERTIES(o)
	{}
	CD3DX12_HEAP_PROPERTIES(
		D3D12_CPU_PAGE_PROPERTY cpuPageProperty,
		D3D12_MEMORY_POOL memoryPoolPreference,
		UINT creationNodeMask = 1,
		UINT nodeMask = 1)
	{
		Type = D3D12_HEAP_TYPE_CUSTOM;
		CPUPageProperty = cpuPageProperty;
		MemoryPoolPreference = memoryPoolPreference;
		CreationNodeMask = creationNodeMask;
		VisibleNodeMask = nodeMask;
	}
	explicit CD3DX12_HEAP_PROPERTIES(
		D3D12_HEAP_TYPE type,
		UINT creationNodeMask = 1,
		UINT nodeMask = 1)
	{
		Type = type;
		CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
		MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
		CreationNodeMask = creationNodeMask;
		VisibleNodeMask = nodeMask;
	}
	operator const D3D12_HEAP_PROPERTIES&() const { return *this; }
	bool IsCPUAccessible() const
	{
		return Type == D3D12_HEAP_TYPE_UPLOAD || Type == D3D12_HEAP_TYPE_READBACK || (Type == D3D12_HEAP_TYPE_CUSTOM &&
			(CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE || CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_BACK));
	}
};
inline bool operator==(const D3D12_HEAP_PROPERTIES& l, const D3D12_HEAP_PROPERTIES& r)
{
	return l.Type == r.Type && l.CPUPageProperty == r.CPUPageProperty &&
		l.MemoryPoolPreference == r.MemoryPoolPreference &&
		l.CreationNodeMask == r.CreationNodeMask &&
		l.VisibleNodeMask == r.VisibleNodeMask;
}
inline bool operator!=(const D3D12_HEAP_PROPERTIES& l, const D3D12_HEAP_PROPERTIES& r)
{
	return !(l == r);
}

//------------------------------------------------------------------------------------------------
struct CD3DX12_HEAP_DESC : public D3D12_HEAP_DESC
{
	CD3DX12_HEAP_DESC()
	{}
	explicit CD3DX12_HEAP_DESC(const D3D12_HEAP_DESC &o) :
		D3D12_HEAP_DESC(o)
	{}
	CD3DX12_HEAP_DESC(
		UINT64 size,
		D3D12_HEAP_PROPERTIES properties,
		UINT64 alignment = 0,
		D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE)
	{
		SizeInBytes = size;
		Properties = properties;
		Alignment = alignment;
		Flags = flags;
	}
	CD3DX12_HEAP_DESC(
		UINT64 size,
		D3D12_HEAP_TYPE type,
		UINT64 alignment = 0,
		D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE)
	{
		SizeInBytes = size;
		Properties = CD3DX12_HEAP_PROPERTIES(type);
		Alignment = alignment;
		Flags = flags;
	}
	CD3DX12_HEAP_DESC(
		UINT64 size,
		D3D12_CPU_PAGE_PROPERTY cpuPageProperty,
		D3D12_MEMORY_POOL memoryPoolPreference,
		UINT64 alignment = 0,
		D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE)
	{
		SizeInBytes = size;
		Properties = CD3DX12_HEAP_PROPERTIES(cpuPageProperty, memoryPoolPreference);
		Alignment = alignment;
		Flags = flags;
	}
	CD3DX12_HEAP_DESC(
		const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo,
		D3D12_HEAP_PROPERTIES properties,
		D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE)
	{
		SizeInBytes = resAllocInfo.SizeInBytes;
		Properties = properties;
		Alignment = resAllocInfo.Alignment;
		Flags = flags;
	}
	CD3DX12_HEAP_DESC(
		const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo,
		D3D12_HEAP_TYPE type,
		D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE)
	{
		SizeInBytes = resAllocInfo.SizeInBytes;
		Properties = CD3DX12_HEAP_PROPERTIES(type);
		Alignment = resAllocInfo.Alignment;
		Flags = flags;
	}
	CD3DX12_HEAP_DESC(
		const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo,
		D3D12_CPU_PAGE_PROPERTY cpuPageProperty,
		D3D12_MEMORY_POOL memoryPoolPreference,
		D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE)
	{
		SizeInBytes = resAllocInfo.SizeInBytes;
		Properties = CD3DX12_HEAP_PROPERTIES(cpuPageProperty, memoryPoolPreference);
		Alignment = resAllocInfo.Alignment;
		Flags = flags;
	}
	operator const D3D12_HEAP_DESC&() const { return *this; }
	bool IsCPUAccessible() const
	{
		return static_cast< const CD3DX12_HEAP_PROPERTIES* >(&Properties)->IsCPUAccessible();
	}
};
inline bool operator==(const D3D12_HEAP_DESC& l, const D3D12_HEAP_DESC& r)
{
	return l.SizeInBytes == r.SizeInBytes &&
		l.Properties == r.Properties &&
		l.Alignment == r.Alignment &&
		l.Flags == r.Flags;
}
inline bool operator!=(const D3D12_HEAP_DESC& l, const D3D12_HEAP_DESC& r)
{
	return !(l == r);
}

//------------------------------------------------------------------------------------------------
struct CD3DX12_CLEAR_VALUE : public D3D12_CLEAR_VALUE
{
	CD3DX12_CLEAR_VALUE()
	{}
	explicit CD3DX12_CLEAR_VALUE(const D3D12_CLEAR_VALUE &o) :
		D3D12_CLEAR_VALUE(o)
	{}
	CD3DX12_CLEAR_VALUE(
		DXGI_FORMAT format,
		const FLOAT color[4])
	{
		Format = format;
		memcpy(Color, color, sizeof(Color));
	}
	CD3DX12_CLEAR_VALUE(
		DXGI_FORMAT format,
		FLOAT depth,
		UINT8 stencil)
	{
		Format = format;
		/* Use memcpy to preserve NAN values */
		memcpy(&DepthStencil.Depth, &depth, sizeof(depth));
		DepthStencil.Stencil = stencil;
	}
	operator const D3D12_CLEAR_VALUE&() const { return *this; }
};

//------------------------------------------------------------------------------------------------
struct CD3DX12_RANGE : public D3D12_RANGE
{
	CD3DX12_RANGE()
	{}
	explicit CD3DX12_RANGE(const D3D12_RANGE &o) :
		D3D12_RANGE(o)
	{}
	CD3DX12_RANGE(
		SIZE_T begin,
		SIZE_T end)
	{
		Begin = begin;
		End = end;
	}
	operator const D3D12_RANGE&() const { return *this; }
};

//------------------------------------------------------------------------------------------------
struct CD3DX12_TILED_RESOURCE_COORDINATE : public D3D12_TILED_RESOURCE_COORDINATE
{
	CD3DX12_TILED_RESOURCE_COORDINATE()
	{}
	explicit CD3DX12_TILED_RESOURCE_COORDINATE(const D3D12_TILED_RESOURCE_COORDINATE &o) :
		D3D12_TILED_RESOURCE_COORDINATE(o)
	{}
	CD3DX12_TILED_RESOURCE_COORDINATE(
		UINT x,
		UINT y,
		UINT z,
		UINT subresource)
	{
		X = x;
		Y = y;
		Z = z;
		Subresource = subresource;
	}
	operator const D3D12_TILED_RESOURCE_COORDINATE&() const { return *this; }
};

//------------------------------------------------------------------------------------------------
struct CD3DX12_TILE_REGION_SIZE : public D3D12_TILE_REGION_SIZE
{
	CD3DX12_TILE_REGION_SIZE()
	{}
	explicit CD3DX12_TILE_REGION_SIZE(const D3D12_TILE_REGION_SIZE &o) :
		D3D12_TILE_REGION_SIZE(o)
	{}
	CD3DX12_TILE_REGION_SIZE(
		UINT numTiles,
		BOOL useBox,
		UINT width,
		UINT16 height,
		UINT16 depth)
	{
		NumTiles = numTiles;
		UseBox = useBox;
		Width = width;
		Height = height;
		Depth = depth;
	}
	operator const D3D12_TILE_REGION_SIZE&() const { return *this; }
};

//------------------------------------------------------------------------------------------------
struct CD3DX12_SUBRESOURCE_TILING : public D3D12_SUBRESOURCE_TILING
{
	CD3DX12_SUBRESOURCE_TILING()
	{}
	explicit CD3DX12_SUBRESOURCE_TILING(const D3D12_SUBRESOURCE_TILING &o) :
		D3D12_SUBRESOURCE_TILING(o)
	{}
	CD3DX12_SUBRESOURCE_TILING(
		UINT widthInTiles,
		UINT16 heightInTiles,
		UINT16 depthInTiles,
		UINT startTileIndexInOverallResource)
	{
		WidthInTiles = widthInTiles;
		HeightInTiles = heightInTiles;
		DepthInTiles = depthInTiles;
		StartTileIndexInOverallResource = startTileIndexInOverallResource;
	}
	operator const D3D12_SUBRESOURCE_TILING&() const { return *this; }
};

//------------------------------------------------------------------------------------------------
struct CD3DX12_TILE_SHAPE : public D3D12_TILE_SHAPE
{
	CD3DX12_TILE_SHAPE()
	{}
	explicit CD3DX12_TILE_SHAPE(const D3D12_TILE_SHAPE &o) :
		D3D12_TILE_SHAPE(o)
	{}
	CD3DX12_TILE_SHAPE(
		UINT widthInTexels,
		UINT heightInTexels,
		UINT depthInTexels)
	{
		WidthInTexels = widthInTexels;
		HeightInTexels = heightInTexels;
		DepthInTexels = depthInTexels;
	}
	operator const D3D12_TILE_SHAPE&() const { return *this; }
};

//------------------------------------------------------------------------------------------------
struct CD3DX12_RESOURCE_BARRIER : public D3D12_RESOURCE_BARRIER
{
	CD3DX12_RESOURCE_BARRIER()
	{}
	explicit CD3DX12_RESOURCE_BARRIER(const D3D12_RESOURCE_BARRIER &o) :
		D3D12_RESOURCE_BARRIER(o)
	{}
	static inline CD3DX12_RESOURCE_BARRIER Transition(
		_In_ ID3D12Resource* pResource,
		D3D12_RESOURCE_STATES stateBefore,
		D3D12_RESOURCE_STATES stateAfter,
		UINT subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
		D3D12_RESOURCE_BARRIER_FLAGS flags = D3D12_RESOURCE_BARRIER_FLAG_NONE)
	{
		CD3DX12_RESOURCE_BARRIER result;
		ZeroMemory(&result, sizeof(result));
		D3D12_RESOURCE_BARRIER &barrier = result;
		result.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
		result.Flags = flags;
		barrier.Transition.pResource = pResource;
		barrier.Transition.StateBefore = stateBefore;
		barrier.Transition.StateAfter = stateAfter;
		barrier.Transition.Subresource = subresource;
		return result;
	}
	static inline CD3DX12_RESOURCE_BARRIER Aliasing(
		_In_ ID3D12Resource* pResourceBefore,
		_In_ ID3D12Resource* pResourceAfter)
	{
		CD3DX12_RESOURCE_BARRIER result;
		ZeroMemory(&result, sizeof(result));
		D3D12_RESOURCE_BARRIER &barrier = result;
		result.Type = D3D12_RESOURCE_BARRIER_TYPE_ALIASING;
		barrier.Aliasing.pResourceBefore = pResourceBefore;
		barrier.Aliasing.pResourceAfter = pResourceAfter;
		return result;
	}
	static inline CD3DX12_RESOURCE_BARRIER UAV(
		_In_ ID3D12Resource* pResource)
	{
		CD3DX12_RESOURCE_BARRIER result;
		ZeroMemory(&result, sizeof(result));
		D3D12_RESOURCE_BARRIER &barrier = result;
		result.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV;
		barrier.UAV.pResource = pResource;
		return result;
	}
	operator const D3D12_RESOURCE_BARRIER&() const { return *this; }
};

//------------------------------------------------------------------------------------------------
struct CD3DX12_PACKED_MIP_INFO : public D3D12_PACKED_MIP_INFO
{
	CD3DX12_PACKED_MIP_INFO()
	{}
	explicit CD3DX12_PACKED_MIP_INFO(const D3D12_PACKED_MIP_INFO &o) :
		D3D12_PACKED_MIP_INFO(o)
	{}
	CD3DX12_PACKED_MIP_INFO(
		UINT8 numStandardMips,
		UINT8 numPackedMips,
		UINT numTilesForPackedMips,
		UINT startTileIndexInOverallResource)
	{
		NumStandardMips = numStandardMips;
		NumPackedMips = numPackedMips;
		NumTilesForPackedMips = numTilesForPackedMips;
		StartTileIndexInOverallResource = startTileIndexInOverallResource;
	}
	operator const D3D12_PACKED_MIP_INFO&() const { return *this; }
};

//------------------------------------------------------------------------------------------------
struct CD3DX12_SUBRESOURCE_FOOTPRINT : public D3D12_SUBRESOURCE_FOOTPRINT
{
	CD3DX12_SUBRESOURCE_FOOTPRINT()
	{}
	explicit CD3DX12_SUBRESOURCE_FOOTPRINT(const D3D12_SUBRESOURCE_FOOTPRINT &o) :
		D3D12_SUBRESOURCE_FOOTPRINT(o)
	{}
	CD3DX12_SUBRESOURCE_FOOTPRINT(
		DXGI_FORMAT format,
		UINT width,
		UINT height,
		UINT depth,
		UINT rowPitch)
	{
		Format = format;
		Width = width;
		Height = height;
		Depth = depth;
		RowPitch = rowPitch;
	}
	explicit CD3DX12_SUBRESOURCE_FOOTPRINT(
		const D3D12_RESOURCE_DESC& resDesc,
		UINT rowPitch)
	{
		Format = resDesc.Format;
		Width = UINT(resDesc.Width);
		Height = resDesc.Height;
		Depth = (resDesc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D ? resDesc.DepthOrArraySize : 1);
		RowPitch = rowPitch;
	}
	operator const D3D12_SUBRESOURCE_FOOTPRINT&() const { return *this; }
};

//------------------------------------------------------------------------------------------------
struct CD3DX12_TEXTURE_COPY_LOCATION : public D3D12_TEXTURE_COPY_LOCATION
{
	CD3DX12_TEXTURE_COPY_LOCATION()
	{}
	explicit CD3DX12_TEXTURE_COPY_LOCATION(const D3D12_TEXTURE_COPY_LOCATION &o) :
		D3D12_TEXTURE_COPY_LOCATION(o)
	{}
	CD3DX12_TEXTURE_COPY_LOCATION(ID3D12Resource* pRes) { pResource = pRes; }
	CD3DX12_TEXTURE_COPY_LOCATION(ID3D12Resource* pRes, D3D12_PLACED_SUBRESOURCE_FOOTPRINT const& Footprint)
	{
		pResource = pRes;
		Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
		PlacedFootprint = Footprint;
	}
	CD3DX12_TEXTURE_COPY_LOCATION(ID3D12Resource* pRes, UINT Sub)
	{
		pResource = pRes;
		Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
		SubresourceIndex = Sub;
	}
};

//------------------------------------------------------------------------------------------------
struct CD3DX12_DESCRIPTOR_RANGE : public D3D12_DESCRIPTOR_RANGE
{
	CD3DX12_DESCRIPTOR_RANGE() { }
	explicit CD3DX12_DESCRIPTOR_RANGE(const D3D12_DESCRIPTOR_RANGE &o) :
		D3D12_DESCRIPTOR_RANGE(o)
	{}
	CD3DX12_DESCRIPTOR_RANGE(
		D3D12_DESCRIPTOR_RANGE_TYPE rangeType,
		UINT numDescriptors,
		UINT baseShaderRegister,
		UINT registerSpace = 0,
		UINT offsetInDescriptorsFromTableStart =
		D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND)
	{
		Init(rangeType, numDescriptors, baseShaderRegister, registerSpace, offsetInDescriptorsFromTableStart);
	}

	inline void Init(
		D3D12_DESCRIPTOR_RANGE_TYPE rangeType,
		UINT numDescriptors,
		UINT baseShaderRegister,
		UINT registerSpace = 0,
		UINT offsetInDescriptorsFromTableStart =
		D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND)
	{
		Init(*this, rangeType, numDescriptors, baseShaderRegister, registerSpace, offsetInDescriptorsFromTableStart);
	}

	static inline void Init(
		_Out_ D3D12_DESCRIPTOR_RANGE &range,
		D3D12_DESCRIPTOR_RANGE_TYPE rangeType,
		UINT numDescriptors,
		UINT baseShaderRegister,
		UINT registerSpace = 0,
		UINT offsetInDescriptorsFromTableStart =
		D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND)
	{
		range.RangeType = rangeType;
		range.NumDescriptors = numDescriptors;
		range.BaseShaderRegister = baseShaderRegister;
		range.RegisterSpace = registerSpace;
		range.OffsetInDescriptorsFromTableStart = offsetInDescriptorsFromTableStart;
	}
};

//------------------------------------------------------------------------------------------------
struct CD3DX12_ROOT_DESCRIPTOR_TABLE : public D3D12_ROOT_DESCRIPTOR_TABLE
{
	CD3DX12_ROOT_DESCRIPTOR_TABLE() {}
	explicit CD3DX12_ROOT_DESCRIPTOR_TABLE(const D3D12_ROOT_DESCRIPTOR_TABLE &o) :
		D3D12_ROOT_DESCRIPTOR_TABLE(o)
	{}
	CD3DX12_ROOT_DESCRIPTOR_TABLE(
		UINT numDescriptorRanges,
		_In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* _pDescriptorRanges)
	{
		Init(numDescriptorRanges, _pDescriptorRanges);
	}

	inline void Init(
		UINT numDescriptorRanges,
		_In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* _pDescriptorRanges)
	{
		Init(*this, numDescriptorRanges, _pDescriptorRanges);
	}

	static inline void Init(
		_Out_ D3D12_ROOT_DESCRIPTOR_TABLE &rootDescriptorTable,
		UINT numDescriptorRanges,
		_In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* _pDescriptorRanges)
	{
		rootDescriptorTable.NumDescriptorRanges = numDescriptorRanges;
		rootDescriptorTable.pDescriptorRanges = _pDescriptorRanges;
	}
};

//------------------------------------------------------------------------------------------------
struct CD3DX12_ROOT_CONSTANTS : public D3D12_ROOT_CONSTANTS
{
	CD3DX12_ROOT_CONSTANTS() {}
	explicit CD3DX12_ROOT_CONSTANTS(const D3D12_ROOT_CONSTANTS &o) :
		D3D12_ROOT_CONSTANTS(o)
	{}
	CD3DX12_ROOT_CONSTANTS(
		UINT num32BitValues,
		UINT shaderRegister,
		UINT registerSpace = 0)
	{
		Init(num32BitValues, shaderRegister, registerSpace);
	}

	inline void Init(
		UINT num32BitValues,
		UINT shaderRegister,
		UINT registerSpace = 0)
	{
		Init(*this, num32BitValues, shaderRegister, registerSpace);
	}

	static inline void Init(
		_Out_ D3D12_ROOT_CONSTANTS &rootConstants,
		UINT num32BitValues,
		UINT shaderRegister,
		UINT registerSpace = 0)
	{
		rootConstants.Num32BitValues = num32BitValues;
		rootConstants.ShaderRegister = shaderRegister;
		rootConstants.RegisterSpace = registerSpace;
	}
};

//------------------------------------------------------------------------------------------------
struct CD3DX12_ROOT_DESCRIPTOR : public D3D12_ROOT_DESCRIPTOR
{
	CD3DX12_ROOT_DESCRIPTOR() {}
	explicit CD3DX12_ROOT_DESCRIPTOR(const D3D12_ROOT_DESCRIPTOR &o) :
		D3D12_ROOT_DESCRIPTOR(o)
	{}
	CD3DX12_ROOT_DESCRIPTOR(
		UINT shaderRegister,
		UINT registerSpace = 0)
	{
		Init(shaderRegister, registerSpace);
	}

	inline void Init(
		UINT shaderRegister,
		UINT registerSpace = 0)
	{
		Init(*this, shaderRegister, registerSpace);
	}

	static inline void Init(_Out_ D3D12_ROOT_DESCRIPTOR &table, UINT shaderRegister, UINT registerSpace = 0)
	{
		table.ShaderRegister = shaderRegister;
		table.RegisterSpace = registerSpace;
	}
};

//------------------------------------------------------------------------------------------------
struct CD3DX12_ROOT_PARAMETER : public D3D12_ROOT_PARAMETER
{
	CD3DX12_ROOT_PARAMETER() {}
	explicit CD3DX12_ROOT_PARAMETER(const D3D12_ROOT_PARAMETER &o) :
		D3D12_ROOT_PARAMETER(o)
	{}

	static inline void InitAsDescriptorTable(
		_Out_ D3D12_ROOT_PARAMETER &rootParam,
		UINT numDescriptorRanges,
		_In_reads_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* pDescriptorRanges,
		D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL)
	{
		rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
		rootParam.ShaderVisibility = visibility;
		CD3DX12_ROOT_DESCRIPTOR_TABLE::Init(rootParam.DescriptorTable, numDescriptorRanges, pDescriptorRanges);
	}

	static inline void InitAsConstants(
		_Out_ D3D12_ROOT_PARAMETER &rootParam,
		UINT num32BitValues,
		UINT shaderRegister,
		UINT registerSpace = 0,
		D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL)
	{
		rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
		rootParam.ShaderVisibility = visibility;
		CD3DX12_ROOT_CONSTANTS::Init(rootParam.Constants, num32BitValues, shaderRegister, registerSpace);
	}

	static inline void InitAsConstantBufferView(
		_Out_ D3D12_ROOT_PARAMETER &rootParam,
		UINT shaderRegister,
		UINT registerSpace = 0,
		D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL)
	{
		rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
		rootParam.ShaderVisibility = visibility;
		CD3DX12_ROOT_DESCRIPTOR::Init(rootParam.Descriptor, shaderRegister, registerSpace);
	}

	static inline void InitAsShaderResourceView(
		_Out_ D3D12_ROOT_PARAMETER &rootParam,
		UINT shaderRegister,
		UINT registerSpace = 0,
		D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL)
	{
		rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_SRV;
		rootParam.ShaderVisibility = visibility;
		CD3DX12_ROOT_DESCRIPTOR::Init(rootParam.Descriptor, shaderRegister, registerSpace);
	}

	static inline void InitAsUnorderedAccessView(
		_Out_ D3D12_ROOT_PARAMETER &rootParam,
		UINT shaderRegister,
		UINT registerSpace = 0,
		D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL)
	{
		rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV;
		rootParam.ShaderVisibility = visibility;
		CD3DX12_ROOT_DESCRIPTOR::Init(rootParam.Descriptor, shaderRegister, registerSpace);
	}

	inline void InitAsDescriptorTable(
		UINT numDescriptorRanges,
		_In_reads_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* pDescriptorRanges,
		D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL)
	{
		InitAsDescriptorTable(*this, numDescriptorRanges, pDescriptorRanges, visibility);
	}

	inline void InitAsConstants(
		UINT num32BitValues,
		UINT shaderRegister,
		UINT registerSpace = 0,
		D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL)
	{
		InitAsConstants(*this, num32BitValues, shaderRegister, registerSpace, visibility);
	}

	inline void InitAsConstantBufferView(
		UINT shaderRegister,
		UINT registerSpace = 0,
		D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL)
	{
		InitAsConstantBufferView(*this, shaderRegister, registerSpace, visibility);
	}

	inline void InitAsShaderResourceView(
		UINT shaderRegister,
		UINT registerSpace = 0,
		D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL)
	{
		InitAsShaderResourceView(*this, shaderRegister, registerSpace, visibility);
	}

	inline void InitAsUnorderedAccessView(
		UINT shaderRegister,
		UINT registerSpace = 0,
		D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL)
	{
		InitAsUnorderedAccessView(*this, shaderRegister, registerSpace, visibility);
	}
};

//------------------------------------------------------------------------------------------------
struct CD3DX12_STATIC_SAMPLER_DESC : public D3D12_STATIC_SAMPLER_DESC
{
	CD3DX12_STATIC_SAMPLER_DESC() {}
	explicit CD3DX12_STATIC_SAMPLER_DESC(const D3D12_STATIC_SAMPLER_DESC &o) :
		D3D12_STATIC_SAMPLER_DESC(o)
	{}
	CD3DX12_STATIC_SAMPLER_DESC(
		UINT shaderRegister,
		D3D12_FILTER filter = D3D12_FILTER_ANISOTROPIC,
		D3D12_TEXTURE_ADDRESS_MODE addressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
		D3D12_TEXTURE_ADDRESS_MODE addressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
		D3D12_TEXTURE_ADDRESS_MODE addressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
		FLOAT mipLODBias = 0,
		UINT maxAnisotropy = 16,
		D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL,
		D3D12_STATIC_BORDER_COLOR borderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE,
		FLOAT minLOD = 0.f,
		FLOAT maxLOD = D3D12_FLOAT32_MAX,
		D3D12_SHADER_VISIBILITY shaderVisibility = D3D12_SHADER_VISIBILITY_ALL,
		UINT registerSpace = 0)
	{
		Init(
			shaderRegister,
			filter,
			addressU,
			addressV,
			addressW,
			mipLODBias,
			maxAnisotropy,
			comparisonFunc,
			borderColor,
			minLOD,
			maxLOD,
			shaderVisibility,
			registerSpace);
	}

	static inline void Init(
		_Out_ D3D12_STATIC_SAMPLER_DESC &samplerDesc,
		UINT shaderRegister,
		D3D12_FILTER filter = D3D12_FILTER_ANISOTROPIC,
		D3D12_TEXTURE_ADDRESS_MODE addressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
		D3D12_TEXTURE_ADDRESS_MODE addressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
		D3D12_TEXTURE_ADDRESS_MODE addressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
		FLOAT mipLODBias = 0,
		UINT maxAnisotropy = 16,
		D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL,
		D3D12_STATIC_BORDER_COLOR borderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE,
		FLOAT minLOD = 0.f,
		FLOAT maxLOD = D3D12_FLOAT32_MAX,
		D3D12_SHADER_VISIBILITY shaderVisibility = D3D12_SHADER_VISIBILITY_ALL,
		UINT registerSpace = 0)
	{
		samplerDesc.ShaderRegister = shaderRegister;
		samplerDesc.Filter = filter;
		samplerDesc.AddressU = addressU;
		samplerDesc.AddressV = addressV;
		samplerDesc.AddressW = addressW;
		samplerDesc.MipLODBias = mipLODBias;
		samplerDesc.MaxAnisotropy = maxAnisotropy;
		samplerDesc.ComparisonFunc = comparisonFunc;
		samplerDesc.BorderColor = borderColor;
		samplerDesc.MinLOD = minLOD;
		samplerDesc.MaxLOD = maxLOD;
		samplerDesc.ShaderVisibility = shaderVisibility;
		samplerDesc.RegisterSpace = registerSpace;
	}
	inline void Init(
		UINT shaderRegister,
		D3D12_FILTER filter = D3D12_FILTER_ANISOTROPIC,
		D3D12_TEXTURE_ADDRESS_MODE addressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
		D3D12_TEXTURE_ADDRESS_MODE addressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
		D3D12_TEXTURE_ADDRESS_MODE addressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
		FLOAT mipLODBias = 0,
		UINT maxAnisotropy = 16,
		D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL,
		D3D12_STATIC_BORDER_COLOR borderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE,
		FLOAT minLOD = 0.f,
		FLOAT maxLOD = D3D12_FLOAT32_MAX,
		D3D12_SHADER_VISIBILITY shaderVisibility = D3D12_SHADER_VISIBILITY_ALL,
		UINT registerSpace = 0)
	{
		Init(
			*this,
			shaderRegister,
			filter,
			addressU,
			addressV,
			addressW,
			mipLODBias,
			maxAnisotropy,
			comparisonFunc,
			borderColor,
			minLOD,
			maxLOD,
			shaderVisibility,
			registerSpace);
	}

};

//------------------------------------------------------------------------------------------------
struct CD3DX12_ROOT_SIGNATURE_DESC : public D3D12_ROOT_SIGNATURE_DESC
{
	CD3DX12_ROOT_SIGNATURE_DESC() {}
	explicit CD3DX12_ROOT_SIGNATURE_DESC(const D3D12_ROOT_SIGNATURE_DESC &o) :
		D3D12_ROOT_SIGNATURE_DESC(o)
	{}
	CD3DX12_ROOT_SIGNATURE_DESC(
		UINT numParameters,
		_In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters,
		UINT numStaticSamplers = 0,
		_In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = NULL,
		D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE)
	{
		Init(numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags);
	}
	CD3DX12_ROOT_SIGNATURE_DESC(CD3DX12_DEFAULT)
	{
		Init(0, NULL, 0, NULL, D3D12_ROOT_SIGNATURE_FLAG_NONE);
	}

	inline void Init(
		UINT numParameters,
		_In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters,
		UINT numStaticSamplers = 0,
		_In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = NULL,
		D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE)
	{
		Init(*this, numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags);
	}

	static inline void Init(
		_Out_ D3D12_ROOT_SIGNATURE_DESC &desc,
		UINT numParameters,
		_In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters,
		UINT numStaticSamplers = 0,
		_In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = NULL,
		D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE)
	{
		desc.NumParameters = numParameters;
		desc.pParameters = _pParameters;
		desc.NumStaticSamplers = numStaticSamplers;
		desc.pStaticSamplers = _pStaticSamplers;
		desc.Flags = flags;
	}
};

//------------------------------------------------------------------------------------------------
struct CD3DX12_CPU_DESCRIPTOR_HANDLE : public D3D12_CPU_DESCRIPTOR_HANDLE
{
	CD3DX12_CPU_DESCRIPTOR_HANDLE() {}
	explicit CD3DX12_CPU_DESCRIPTOR_HANDLE(const D3D12_CPU_DESCRIPTOR_HANDLE &o) :
		D3D12_CPU_DESCRIPTOR_HANDLE(o)
	{}
	CD3DX12_CPU_DESCRIPTOR_HANDLE(CD3DX12_DEFAULT) { ptr = 0; }
	CD3DX12_CPU_DESCRIPTOR_HANDLE(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &other, INT offsetScaledByIncrementSize)
	{
		InitOffsetted(other, offsetScaledByIncrementSize);
	}
	CD3DX12_CPU_DESCRIPTOR_HANDLE(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &other, INT offsetInDescriptors, UINT descriptorIncrementSize)
	{
		InitOffsetted(other, offsetInDescriptors, descriptorIncrementSize);
	}
	CD3DX12_CPU_DESCRIPTOR_HANDLE& Offset(INT offsetInDescriptors, UINT descriptorIncrementSize)
	{
		ptr += offsetInDescriptors * descriptorIncrementSize;
		return *this;
	}
	CD3DX12_CPU_DESCRIPTOR_HANDLE& Offset(INT offsetScaledByIncrementSize)
	{
		ptr += offsetScaledByIncrementSize;
		return *this;
	}
	bool operator==(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE& other)
	{
		return (ptr == other.ptr);
	}
	bool operator!=(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE& other)
	{
		return (ptr != other.ptr);
	}
	CD3DX12_CPU_DESCRIPTOR_HANDLE &operator=(const D3D12_CPU_DESCRIPTOR_HANDLE &other)
	{
		ptr = other.ptr;
		return *this;
	}

	inline void InitOffsetted(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize)
	{
		InitOffsetted(*this, base, offsetScaledByIncrementSize);
	}

	inline void InitOffsetted(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize)
	{
		InitOffsetted(*this, base, offsetInDescriptors, descriptorIncrementSize);
	}

	static inline void InitOffsetted(_Out_ D3D12_CPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize)
	{
		handle.ptr = base.ptr + offsetScaledByIncrementSize;
	}

	static inline void InitOffsetted(_Out_ D3D12_CPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize)
	{
		handle.ptr = base.ptr + offsetInDescriptors * descriptorIncrementSize;
	}
};

//------------------------------------------------------------------------------------------------
struct CD3DX12_GPU_DESCRIPTOR_HANDLE : public D3D12_GPU_DESCRIPTOR_HANDLE
{
	CD3DX12_GPU_DESCRIPTOR_HANDLE() {}
	explicit CD3DX12_GPU_DESCRIPTOR_HANDLE(const D3D12_GPU_DESCRIPTOR_HANDLE &o) :
		D3D12_GPU_DESCRIPTOR_HANDLE(o)
	{}
	CD3DX12_GPU_DESCRIPTOR_HANDLE(CD3DX12_DEFAULT) { ptr = 0; }
	CD3DX12_GPU_DESCRIPTOR_HANDLE(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &other, INT offsetScaledByIncrementSize)
	{
		InitOffsetted(other, offsetScaledByIncrementSize);
	}
	CD3DX12_GPU_DESCRIPTOR_HANDLE(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &other, INT offsetInDescriptors, UINT descriptorIncrementSize)
	{
		InitOffsetted(other, offsetInDescriptors, descriptorIncrementSize);
	}
	CD3DX12_GPU_DESCRIPTOR_HANDLE& Offset(INT offsetInDescriptors, UINT descriptorIncrementSize)
	{
		ptr += offsetInDescriptors * descriptorIncrementSize;
		return *this;
	}
	CD3DX12_GPU_DESCRIPTOR_HANDLE& Offset(INT offsetScaledByIncrementSize)
	{
		ptr += offsetScaledByIncrementSize;
		return *this;
	}
	inline bool operator==(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE& other)
	{
		return (ptr == other.ptr);
	}
	inline bool operator!=(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE& other)
	{
		return (ptr != other.ptr);
	}
	CD3DX12_GPU_DESCRIPTOR_HANDLE &operator=(const D3D12_GPU_DESCRIPTOR_HANDLE &other)
	{
		ptr = other.ptr;
		return *this;
	}

	inline void InitOffsetted(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize)
	{
		InitOffsetted(*this, base, offsetScaledByIncrementSize);
	}

	inline void InitOffsetted(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize)
	{
		InitOffsetted(*this, base, offsetInDescriptors, descriptorIncrementSize);
	}

	static inline void InitOffsetted(_Out_ D3D12_GPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize)
	{
		handle.ptr = base.ptr + offsetScaledByIncrementSize;
	}

	static inline void InitOffsetted(_Out_ D3D12_GPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize)
	{
		handle.ptr = base.ptr + offsetInDescriptors * descriptorIncrementSize;
	}
};

//------------------------------------------------------------------------------------------------
inline UINT D3D12CalcSubresource(UINT MipSlice, UINT ArraySlice, UINT PlaneSlice, UINT MipLevels, UINT ArraySize)
{
	return MipSlice + ArraySlice * MipLevels + PlaneSlice * MipLevels * ArraySize;
}

//------------------------------------------------------------------------------------------------
template <typename T, typename U, typename V>
inline void D3D12DecomposeSubresource(UINT Subresource, UINT MipLevels, UINT ArraySize, _Out_ T& MipSlice, _Out_ U& ArraySlice, _Out_ V& PlaneSlice)
{
	MipSlice = static_cast<T>(Subresource % MipLevels);
	ArraySlice = static_cast<U>((Subresource / MipLevels) % ArraySize);
	PlaneSlice = static_cast<V>(Subresource / (MipLevels * ArraySize));
}

//------------------------------------------------------------------------------------------------
inline UINT8 D3D12GetFormatPlaneCount(
	_In_ ID3D12Device* pDevice,
	DXGI_FORMAT Format
	)
{
	D3D12_FEATURE_DATA_FORMAT_INFO formatInfo = { Format };
	if (FAILED(pDevice->CheckFeatureSupport(D3D12_FEATURE_FORMAT_INFO, &formatInfo, sizeof(formatInfo))))
	{
		return 0;
	}
	return formatInfo.PlaneCount;
}

//------------------------------------------------------------------------------------------------
struct CD3DX12_RESOURCE_DESC : public D3D12_RESOURCE_DESC
{
	CD3DX12_RESOURCE_DESC()
	{}
	explicit CD3DX12_RESOURCE_DESC(const D3D12_RESOURCE_DESC& o) :
		D3D12_RESOURCE_DESC(o)
	{}
	CD3DX12_RESOURCE_DESC(
		D3D12_RESOURCE_DIMENSION dimension,
		UINT64 alignment,
		UINT64 width,
		UINT height,
		UINT16 depthOrArraySize,
		UINT16 mipLevels,
		DXGI_FORMAT format,
		UINT sampleCount,
		UINT sampleQuality,
		D3D12_TEXTURE_LAYOUT layout,
		D3D12_RESOURCE_FLAGS flags)
	{
		Dimension = dimension;
		Alignment = alignment;
		Width = width;
		Height = height;
		DepthOrArraySize = depthOrArraySize;
		MipLevels = mipLevels;
		Format = format;
		SampleDesc.Count = sampleCount;
		SampleDesc.Quality = sampleQuality;
		Layout = layout;
		Flags = flags;
	}
	static inline CD3DX12_RESOURCE_DESC Buffer(
		const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo,
		D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE)
	{
		return CD3DX12_RESOURCE_DESC(D3D12_RESOURCE_DIMENSION_BUFFER, resAllocInfo.Alignment, resAllocInfo.SizeInBytes,
			1, 1, 1, DXGI_FORMAT_UNKNOWN, 1, 0, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, flags);
	}
	static inline CD3DX12_RESOURCE_DESC Buffer(
		UINT64 width,
		D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE,
		UINT64 alignment = 0)
	{
		return CD3DX12_RESOURCE_DESC(D3D12_RESOURCE_DIMENSION_BUFFER, alignment, width, 1, 1, 1,
			DXGI_FORMAT_UNKNOWN, 1, 0, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, flags);
	}
	static inline CD3DX12_RESOURCE_DESC Tex1D(
		DXGI_FORMAT format,
		UINT64 width,
		UINT16 arraySize = 1,
		UINT16 mipLevels = 0,
		D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE,
		D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN,
		UINT64 alignment = 0)
	{
		return CD3DX12_RESOURCE_DESC(D3D12_RESOURCE_DIMENSION_TEXTURE1D, alignment, width, 1, arraySize,
			mipLevels, format, 1, 0, layout, flags);
	}
	static inline CD3DX12_RESOURCE_DESC Tex2D(
		DXGI_FORMAT format,
		UINT64 width,
		UINT height,
		UINT16 arraySize = 1,
		UINT16 mipLevels = 0,
		UINT sampleCount = 1,
		UINT sampleQuality = 0,
		D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE,
		D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN,
		UINT64 alignment = 0)
	{
		return CD3DX12_RESOURCE_DESC(D3D12_RESOURCE_DIMENSION_TEXTURE2D, alignment, width, height, arraySize,
			mipLevels, format, sampleCount, sampleQuality, layout, flags);
	}
	static inline CD3DX12_RESOURCE_DESC Tex3D(
		DXGI_FORMAT format,
		UINT64 width,
		UINT height,
		UINT16 depth,
		UINT16 mipLevels = 0,
		D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE,
		D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN,
		UINT64 alignment = 0)
	{
		return CD3DX12_RESOURCE_DESC(D3D12_RESOURCE_DIMENSION_TEXTURE3D, alignment, width, height, depth,
			mipLevels, format, 1, 0, layout, flags);
	}
	inline UINT16 Depth() const
	{
		return (Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D ? DepthOrArraySize : 1);
	}
	inline UINT16 ArraySize() const
	{
		return (Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE3D ? DepthOrArraySize : 1);
	}
	inline UINT8 PlaneCount(_In_ ID3D12Device* pDevice) const
	{
		return D3D12GetFormatPlaneCount(pDevice, Format);
	}
	inline UINT Subresources(_In_ ID3D12Device* pDevice) const
	{
		return MipLevels * ArraySize() * PlaneCount(pDevice);
	}
	inline UINT CalcSubresource(UINT MipSlice, UINT ArraySlice, UINT PlaneSlice)
	{
		return D3D12CalcSubresource(MipSlice, ArraySlice, PlaneSlice, MipLevels, ArraySize());
	}
	operator const D3D12_RESOURCE_DESC&() const { return *this; }
};
inline bool operator==(const D3D12_RESOURCE_DESC& l, const D3D12_RESOURCE_DESC& r)
{
	return l.Dimension == r.Dimension &&
		l.Alignment == r.Alignment &&
		l.Width == r.Width &&
		l.Height == r.Height &&
		l.DepthOrArraySize == r.DepthOrArraySize &&
		l.MipLevels == r.MipLevels &&
		l.Format == r.Format &&
		l.SampleDesc.Count == r.SampleDesc.Count &&
		l.SampleDesc.Quality == r.SampleDesc.Quality &&
		l.Layout == r.Layout &&
		l.Flags == r.Flags;
}
inline bool operator!=(const D3D12_RESOURCE_DESC& l, const D3D12_RESOURCE_DESC& r)
{
	return !(l == r);
}

//------------------------------------------------------------------------------------------------
// Row-by-row memcpy
inline void MemcpySubresource(
	_In_ const D3D12_MEMCPY_DEST* pDest,
	_In_ const D3D12_SUBRESOURCE_DATA* pSrc,
	SIZE_T RowSizeInBytes,
	UINT NumRows,
	UINT NumSlices)
{
	for (UINT z = 0; z < NumSlices; ++z)
	{
		BYTE* pDestSlice = reinterpret_cast<BYTE*>(pDest->pData) + pDest->SlicePitch * z;
		const BYTE* pSrcSlice = reinterpret_cast<const BYTE*>(pSrc->pData) + pSrc->SlicePitch * z;
		for (UINT y = 0; y < NumRows; ++y)
		{
			memcpy(pDestSlice + pDest->RowPitch * y,
				pSrcSlice + pSrc->RowPitch * y,
				RowSizeInBytes);
		}
	}
}

//------------------------------------------------------------------------------------------------
// Returns required size of a buffer to be used for data upload
inline UINT64 GetRequiredIntermediateSize(
	_In_ ID3D12Resource* pDestinationResource,
	_In_range_(0, D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
	_In_range_(0, D3D12_REQ_SUBRESOURCES - FirstSubresource) UINT NumSubresources)
{
	D3D12_RESOURCE_DESC Desc = pDestinationResource->GetDesc();
	UINT64 RequiredSize = 0;

	ID3D12Device* pDevice;
	pDestinationResource->GetDevice(__uuidof(*pDevice), reinterpret_cast<void**>(&pDevice));
	pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, 0, nullptr, nullptr, nullptr, &RequiredSize);
	pDevice->Release();

	return RequiredSize;
}

//------------------------------------------------------------------------------------------------
// All arrays must be populated (e.g. by calling GetCopyableFootprints)
inline UINT64 UpdateSubresources(
	_In_ ID3D12GraphicsCommandList* pCmdList,
	_In_ ID3D12Resource* pDestinationResource,
	_In_ ID3D12Resource* pIntermediate,
	_In_range_(0, D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
	_In_range_(0, D3D12_REQ_SUBRESOURCES - FirstSubresource) UINT NumSubresources,
	UINT64 RequiredSize,
	_In_reads_(NumSubresources) const D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts,
	_In_reads_(NumSubresources) const UINT* pNumRows,
	_In_reads_(NumSubresources) const UINT64* pRowSizesInBytes,
	_In_reads_(NumSubresources) const D3D12_SUBRESOURCE_DATA* pSrcData)
{
	// Minor validation
	D3D12_RESOURCE_DESC IntermediateDesc = pIntermediate->GetDesc();
	D3D12_RESOURCE_DESC DestinationDesc = pDestinationResource->GetDesc();
	if (IntermediateDesc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER ||
		IntermediateDesc.Width < RequiredSize + pLayouts[0].Offset ||
		RequiredSize >(SIZE_T) - 1 ||
		(DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER &&
			(FirstSubresource != 0 || NumSubresources != 1)))
	{
		return 0;
	}

	BYTE* pData;
	HRESULT hr = pIntermediate->Map(0, NULL, reinterpret_cast<void**>(&pData));
	if (FAILED(hr))
	{
		return 0;
	}

	for (UINT i = 0; i < NumSubresources; ++i)
	{
		if (pRowSizesInBytes[i] >(SIZE_T)-1) return 0;
		D3D12_MEMCPY_DEST DestData = { pData + pLayouts[i].Offset, pLayouts[i].Footprint.RowPitch, pLayouts[i].Footprint.RowPitch * pNumRows[i] };
		MemcpySubresource(&DestData, &pSrcData[i], (SIZE_T)pRowSizesInBytes[i], pNumRows[i], pLayouts[i].Footprint.Depth);
	}
	pIntermediate->Unmap(0, NULL);

	if (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
	{
		CD3DX12_BOX SrcBox(UINT(pLayouts[0].Offset), UINT(pLayouts[0].Offset + pLayouts[0].Footprint.Width));
		pCmdList->CopyBufferRegion(
			pDestinationResource, 0, pIntermediate, pLayouts[0].Offset, pLayouts[0].Footprint.Width);
	}
	else
	{
		for (UINT i = 0; i < NumSubresources; ++i)
		{
			CD3DX12_TEXTURE_COPY_LOCATION Dst(pDestinationResource, i + FirstSubresource);
			CD3DX12_TEXTURE_COPY_LOCATION Src(pIntermediate, pLayouts[i]);
			pCmdList->CopyTextureRegion(&Dst, 0, 0, 0, &Src, nullptr);
		}
	}
	return RequiredSize;
}

//------------------------------------------------------------------------------------------------
// Heap-allocating UpdateSubresources implementation
inline UINT64 UpdateSubresources(
	_In_ ID3D12GraphicsCommandList* pCmdList,
	_In_ ID3D12Resource* pDestinationResource,
	_In_ ID3D12Resource* pIntermediate,
	UINT64 IntermediateOffset,
	_In_range_(0, D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
	_In_range_(0, D3D12_REQ_SUBRESOURCES - FirstSubresource) UINT NumSubresources,
	_In_reads_(NumSubresources) D3D12_SUBRESOURCE_DATA* pSrcData)
{
	UINT64 RequiredSize = 0;
	UINT64 MemToAlloc = static_cast<UINT64>(sizeof(D3D12_PLACED_SUBRESOURCE_FOOTPRINT) + sizeof(UINT) + sizeof(UINT64)) * NumSubresources;
	if (MemToAlloc > SIZE_MAX)
	{
		return 0;
	}
	void* pMem = HeapAlloc(GetProcessHeap(), 0, static_cast<SIZE_T>(MemToAlloc));
	if (pMem == NULL)
	{
		return 0;
	}
	D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts = reinterpret_cast<D3D12_PLACED_SUBRESOURCE_FOOTPRINT*>(pMem);
	UINT64* pRowSizesInBytes = reinterpret_cast<UINT64*>(pLayouts + NumSubresources);
	UINT* pNumRows = reinterpret_cast<UINT*>(pRowSizesInBytes + NumSubresources);

	D3D12_RESOURCE_DESC Desc = pDestinationResource->GetDesc();
	ID3D12Device* pDevice;
	pDestinationResource->GetDevice(__uuidof(*pDevice), reinterpret_cast<void**>(&pDevice));
	pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, pLayouts, pNumRows, pRowSizesInBytes, &RequiredSize);
	pDevice->Release();

	UINT64 Result = UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, pLayouts, pNumRows, pRowSizesInBytes, pSrcData);
	HeapFree(GetProcessHeap(), 0, pMem);
	return Result;
}

//------------------------------------------------------------------------------------------------
// Stack-allocating UpdateSubresources implementation
template <UINT MaxSubresources>
inline UINT64 UpdateSubresources(
	_In_ ID3D12GraphicsCommandList* pCmdList,
	_In_ ID3D12Resource* pDestinationResource,
	_In_ ID3D12Resource* pIntermediate,
	UINT64 IntermediateOffset,
	_In_range_(0, MaxSubresources) UINT FirstSubresource,
	_In_range_(1, MaxSubresources - FirstSubresource) UINT NumSubresources,
	_In_reads_(NumSubresources) D3D12_SUBRESOURCE_DATA* pSrcData)
{
	UINT64 RequiredSize = 0;
	D3D12_PLACED_SUBRESOURCE_FOOTPRINT Layouts[MaxSubresources];
	UINT NumRows[MaxSubresources];
	UINT64 RowSizesInBytes[MaxSubresources];

	D3D12_RESOURCE_DESC Desc = pDestinationResource->GetDesc();
	ID3D12Device* pDevice;
	pDestinationResource->GetDevice(__uuidof(*pDevice), reinterpret_cast<void**>(&pDevice));
	pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, Layouts, NumRows, RowSizesInBytes, &RequiredSize);
	pDevice->Release();

	return UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, Layouts, NumRows, RowSizesInBytes, pSrcData);
}

//------------------------------------------------------------------------------------------------
inline bool D3D12IsLayoutOpaque(D3D12_TEXTURE_LAYOUT Layout)
{
	return Layout == D3D12_TEXTURE_LAYOUT_UNKNOWN || Layout == D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE;
}

//------------------------------------------------------------------------------------------------
inline ID3D12CommandList * const * CommandListCast(ID3D12GraphicsCommandList * const * pp)
{
	// This cast is useful for passing strongly typed command list pointers into
	// ExecuteCommandLists.
	// This cast is valid as long as the const-ness is respected. D3D12 APIs do
	// respect the const-ness of their arguments.
	return reinterpret_cast<ID3D12CommandList * const *>(pp);
}


#endif // defined( __cplusplus )

#endif //__D3DX12_H__




================================================
FILE: src/mainfrm.h
================================================
#include "trayicon.h"
#include "D3dx12jo.h"

// User defined Constants:

#define WM_TPSCREENSAVER  WM_USER + 0x05

//////////////////
// Main frame for TRAYTEST.
//
class CMainFrame : public CFrameWnd {
public:
	BOOL MonitorOffSupport();
	CMainFrame();
	BOOL IsShiftKeyDown();
	D3dx12jo* m_pD3jo;

	virtual ~CMainFrame();
protected:
	DECLARE_DYNAMIC(CMainFrame)
	CStatusBar	m_wndStatusBar;

	CTrayIcon	m_trayIcon;		// my tray icon
	//CEdit			m_wndEdit;		// to display tray notifications
	int			m_iWhichIcon;	// 0/1 which HICON to use
	BOOL			m_bShutdown;	// OK to terminate TRAYTEST
	//BOOL			m_bShowTrayNotifications;	// display info in main window

	//{{AFX_MSG(CMainFrame)
	afx_msg LRESULT OnTrayNotification(WPARAM wp, LPARAM lp);
	afx_msg int	 OnCreate(LPCREATESTRUCT lpCreateStruct);
	afx_msg void OnClose();
	afx_msg void OnAppTpExit();
	afx_msg void OnTpLogOff();
	afx_msg void OnTpShutDown();
	afx_msg void OnTpRestart();
	afx_msg void OnTpStandBy();
	afx_msg void OnTimer(UINT_PTR nIDEvent);
	afx_msg void OnTpScreenSave();
	afx_msg void OnEndSession(BOOL bEnding);
	void ResetTimerTicks();
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
private:
	void DoMenuDropDown();
	UINT_PTR m_nTimer;
	UINT m_BtnClicked;
	UINT m_nTicks;
	UINT m_DblClicked;
	void OnStopTimer();
	void OnStartTimer();
	void TpExitWindows(BOOL Force,int shtdn);
};


================================================
FILE: src/res/APP.RC2
================================================
//
// APP.RC2 - resources Microsoft Visual C++ does not edit directly
//

#ifdef APSTUDIO_INVOKED
	#error this file is not editable by Microsoft Visual C++
#endif //APSTUDIO_INVOKED


/////////////////////////////////////////////////////////////////////////////
// Add manually edited resources here...

/////////////////////////////////////////////////////////////////////////////


================================================
FILE: src/resource.h
================================================
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by TrayPwr.rc
//
#define IDR_MAINFRAME                   2
#define IDR_TRAYICON                    3
#define IDSYSINFO                       81
#define IDD_ABOUTBOX                    100
#define IDI_MYICON                      101
#define IDI_MYICON2                     102
#define IDC_EDIT1                       1002
#define IDC_EDITLIC                     1002
#define ID_APPTP_EXIT                   32776
#define ID_TPLOGOFF                     32777
#define ID_TPSHUTDOWN                   32778
#define ID_TPRESTART                    32779
#define ID_TPSTANDBY                    32780
#define ID_TPSCREENSAVE                 32781

// Next default values for new objects
// 
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE        105
#define _APS_NEXT_COMMAND_VALUE         32781
#define _APS_NEXT_CONTROL_VALUE         1003
#define _APS_NEXT_SYMED_VALUE           103
#endif
#endif


================================================
FILE: src/stdafx.cpp
================================================
#include "stdafx.h"

================================================
FILE: src/stdafx.h
================================================
#pragma once

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN    // Exclude rarely-used stuff from Windows headers.
#endif

#include <afxwin.h>			 // MFC core and standard components
#include <afxext.h>			 // MFC extensions (including VB)
#include <string>


================================================
FILE: src/trayicon.h
================================================
////////////////////////////////////////////////////////////////
// CTrayIcon Copyright 1996 Microsoft Systems Journal.
//
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.

#ifndef _TRAYICON_H
#define _TRAYICON_H

////////////////
// CTrayIcon manages an icon in the Windows 95 system tray. 
// 
class CTrayIcon : public CCmdTarget {
protected:
	DECLARE_DYNAMIC(CTrayIcon)
	NOTIFYICONDATA m_nid;			// struct for Shell_NotifyIcon args

public:
	CTrayIcon(UINT uID);
	~CTrayIcon();

	// Call this to receive tray notifications
	void SetNotificationWnd(CWnd* pNotifyWnd, UINT uCbMsg);

	// SetIcon functions. To remove icon, call SetIcon(0)
	//
	BOOL SetIcon(UINT uID); // main variant you want to use
	BOOL SetIcon(HICON hicon, LPCSTR lpTip);
	BOOL SetIcon(LPCTSTR lpResName, LPCSTR lpTip)
		{ return SetIcon(lpResName ? 
			AfxGetApp()->LoadIcon(lpResName) : NULL, lpTip); }
	BOOL SetStandardIcon(LPCTSTR lpszIconName, LPCSTR lpTip)
		{ return SetIcon(::LoadIcon(NULL, lpszIconName), lpTip); }

};

#endif
Download .txt
gitextract_f_fcv1s_/

├── LICENSE
├── README.md
└── src/
    ├── AboutDlg.cpp
    ├── AboutDlg.h
    ├── D3dx12jo.cpp
    ├── D3dx12jo.h
    ├── LICENSE.txt
    ├── Mainfrm.cpp
    ├── TrayIcon.CPP
    ├── TrayPwr.cpp
    ├── TrayPwr.h
    ├── TrayPwr.rc
    ├── TrayPwr.sln
    ├── TrayPwr.vcxproj
    ├── TrayPwr.vcxproj.user
    ├── d3dx12.h
    ├── mainfrm.h
    ├── res/
    │   └── APP.RC2
    ├── resource.h
    ├── stdafx.cpp
    ├── stdafx.h
    └── trayicon.h
Download .txt
SYMBOL INDEX (73 symbols across 10 files)

FILE: src/AboutDlg.cpp
  function BOOL (line 44) | BOOL CAboutDlg::OnInitDialog()
  function INT_PTR (line 92) | INT_PTR CAboutDlg::DoModal()
  function BOOL (line 120) | BOOL CAboutDlg::OnCommand(WPARAM wParam, LPARAM lParam)
  function BOOL (line 132) | BOOL CAboutDlg::StartSysInfo()
  function BOOL (line 171) | BOOL CALLBACK CAboutDlg::CloseChildProcess(HWND hWnd, LPARAM lParam)
  function BOOL (line 182) | BOOL CALLBACK CAboutDlg::ActivateChildProcess(HWND hWnd, LPARAM lParam)

FILE: src/AboutDlg.h
  function class (line 7) | class CAboutDlg : public CDialog

FILE: src/D3dx12jo.h
  function class (line 13) | class D3dx12jo

FILE: src/Mainfrm.cpp
  function LRESULT (line 95) | LRESULT CMainFrame::OnTrayNotification(WPARAM uID, LPARAM lEvent)
  function BOOL (line 344) | BOOL CMainFrame::IsShiftKeyDown()
  function BOOL (line 352) | BOOL CMainFrame::MonitorOffSupport()

FILE: src/TrayIcon.CPP
  function BOOL (line 46) | BOOL CTrayIcon::SetIcon(UINT uID)
  function BOOL (line 60) | BOOL CTrayIcon::SetIcon(HICON hicon, LPCSTR lpTip)

FILE: src/TrayPwr.cpp
  function DWORD (line 23) | DWORD FindOtherInstancePid()
  function BOOL (line 58) | BOOL TerminateProcessByPid(DWORD pid, DWORD timeoutMs = 5000)
  function BOOL (line 78) | BOOL CMyApp::InitInstance()

FILE: src/TrayPwr.h
  function class (line 8) | class CMyApp : public CWinApp {

FILE: src/d3dx12.h
  type CD3DX12_DEFAULT (line 17) | struct CD3DX12_DEFAULT {}
  function D3D12_RECT (line 34) | struct CD3DX12_RECT : public D3D12_RECT
  function D3D12_BOX (line 57) | struct CD3DX12_BOX : public D3D12_BOX
  function D3D12_DEPTH_STENCIL_DESC (line 117) | struct CD3DX12_DEPTH_STENCIL_DESC : public D3D12_DEPTH_STENCIL_DESC
  function D3D12_BLEND_DESC (line 173) | struct CD3DX12_BLEND_DESC : public D3D12_BLEND_DESC
  function D3D12_RASTERIZER_DESC (line 200) | struct CD3DX12_RASTERIZER_DESC : public D3D12_RASTERIZER_DESC
  function D3D12_RESOURCE_ALLOCATION_INFO (line 251) | struct CD3DX12_RESOURCE_ALLOCATION_INFO : public D3D12_RESOURCE_ALLOCATI...
  type CD3DX12_HEAP_PROPERTIES (line 269) | struct CD3DX12_HEAP_PROPERTIES
  function explicit (line 273) | explicit CD3DX12_HEAP_PROPERTIES(const D3D12_HEAP_PROPERTIES &o) :
  type CD3DX12_HEAP_DESC (line 319) | struct CD3DX12_HEAP_DESC
  function explicit (line 323) | explicit CD3DX12_HEAP_DESC(const D3D12_HEAP_DESC &o) :
  type CD3DX12_CLEAR_VALUE (line 410) | struct CD3DX12_CLEAR_VALUE
  function explicit (line 414) | explicit CD3DX12_CLEAR_VALUE(const D3D12_CLEAR_VALUE &o) :
  type CD3DX12_RANGE (line 438) | struct CD3DX12_RANGE
  function explicit (line 442) | explicit CD3DX12_RANGE(const D3D12_RANGE &o) :
  type CD3DX12_TILED_RESOURCE_COORDINATE (line 456) | struct CD3DX12_TILED_RESOURCE_COORDINATE
  function explicit (line 460) | explicit CD3DX12_TILED_RESOURCE_COORDINATE(const D3D12_TILED_RESOURCE_CO...
  type CD3DX12_SUBRESOURCE_TILING (line 502) | struct CD3DX12_SUBRESOURCE_TILING
  function explicit (line 506) | explicit CD3DX12_SUBRESOURCE_TILING(const D3D12_SUBRESOURCE_TILING &o) :
  function D3D12_TILE_SHAPE (line 524) | struct CD3DX12_TILE_SHAPE : public D3D12_TILE_SHAPE
  type CD3DX12_RESOURCE_BARRIER (line 544) | struct CD3DX12_RESOURCE_BARRIER
  function explicit (line 548) | explicit CD3DX12_RESOURCE_BARRIER(const D3D12_RESOURCE_BARRIER &o) :
  function CD3DX12_RESOURCE_BARRIER (line 551) | static inline CD3DX12_RESOURCE_BARRIER Transition(
  function CD3DX12_RESOURCE_BARRIER (line 569) | static inline CD3DX12_RESOURCE_BARRIER Aliasing(
  function CD3DX12_RESOURCE_BARRIER (line 581) | static inline CD3DX12_RESOURCE_BARRIER UAV(
  type CD3DX12_PACKED_MIP_INFO (line 595) | struct CD3DX12_PACKED_MIP_INFO
  function explicit (line 599) | explicit CD3DX12_PACKED_MIP_INFO(const D3D12_PACKED_MIP_INFO &o) :
  function explicit (line 621) | explicit CD3DX12_SUBRESOURCE_FOOTPRINT(const D3D12_SUBRESOURCE_FOOTPRINT...
  function explicit (line 637) | explicit CD3DX12_SUBRESOURCE_FOOTPRINT(
  type CD3DX12_TEXTURE_COPY_LOCATION (line 651) | struct CD3DX12_TEXTURE_COPY_LOCATION
  function explicit (line 655) | explicit CD3DX12_TEXTURE_COPY_LOCATION(const D3D12_TEXTURE_COPY_LOCATION...
  function D3D12_DESCRIPTOR_RANGE (line 674) | struct CD3DX12_DESCRIPTOR_RANGE : public D3D12_DESCRIPTOR_RANGE
  function D3D12_ROOT_DESCRIPTOR_TABLE (line 720) | struct CD3DX12_ROOT_DESCRIPTOR_TABLE : public D3D12_ROOT_DESCRIPTOR_TABLE
  function Init (line 733) | inline void Init(
  function Init (line 740) | static inline void Init(
  function D3D12_ROOT_CONSTANTS (line 751) | struct CD3DX12_ROOT_CONSTANTS : public D3D12_ROOT_CONSTANTS
  function D3D12_ROOT_DESCRIPTOR (line 786) | struct CD3DX12_ROOT_DESCRIPTOR : public D3D12_ROOT_DESCRIPTOR
  function D3D12_ROOT_PARAMETER (line 814) | struct CD3DX12_ROOT_PARAMETER : public D3D12_ROOT_PARAMETER
  function InitAsDescriptorTable (line 877) | inline void InitAsDescriptorTable(
  function D3D12_STATIC_SAMPLER_DESC (line 920) | struct CD3DX12_STATIC_SAMPLER_DESC : public D3D12_STATIC_SAMPLER_DESC
  function D3D12_ROOT_SIGNATURE_DESC (line 1022) | struct CD3DX12_ROOT_SIGNATURE_DESC : public D3D12_ROOT_SIGNATURE_DESC
  function CD3DX12_ROOT_SIGNATURE_DESC (line 1037) | CD3DX12_ROOT_SIGNATURE_DESC(CD3DX12_DEFAULT)
  function D3D12_CPU_DESCRIPTOR_HANDLE (line 1069) | struct CD3DX12_CPU_DESCRIPTOR_HANDLE : public D3D12_CPU_DESCRIPTOR_HANDLE
  function D3D12_GPU_DESCRIPTOR_HANDLE (line 1130) | struct CD3DX12_GPU_DESCRIPTOR_HANDLE : public D3D12_GPU_DESCRIPTOR_HANDLE
  function UINT (line 1191) | inline UINT D3D12CalcSubresource(UINT MipSlice, UINT ArraySlice, UINT Pl...
  function D3D12DecomposeSubresource (line 1198) | void D3D12DecomposeSubresource(UINT Subresource, UINT MipLevels, UINT Ar...
  function UINT8 (line 1206) | inline UINT8 D3D12GetFormatPlaneCount(
  function D3D12_RESOURCE_DESC (line 1220) | struct CD3DX12_RESOURCE_DESC : public D3D12_RESOURCE_DESC
  function CD3DX12_RESOURCE_DESC (line 1252) | static inline CD3DX12_RESOURCE_DESC Buffer(
  function UINT8 (line 1315) | inline UINT8 PlaneCount(_In_ ID3D12Device* pDevice) const
  function UINT (line 1319) | inline UINT Subresources(_In_ ID3D12Device* pDevice) const
  function UINT (line 1323) | inline UINT CalcSubresource(UINT MipSlice, UINT ArraySlice, UINT PlaneSl...
  function D3D12IsLayoutOpaque (line 1511) | inline bool D3D12IsLayoutOpaque(D3D12_TEXTURE_LAYOUT Layout)
  function ID3D12CommandList (line 1517) | inline ID3D12CommandList * const * CommandListCast(ID3D12GraphicsCommand...

FILE: src/mainfrm.h
  function class (line 11) | class CMainFrame : public CFrameWnd {

FILE: src/trayicon.h
  function class (line 13) | class CTrayIcon : public CCmdTarget {
Condensed preview — 22 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (133K chars).
[
  {
    "path": "LICENSE",
    "chars": 1084,
    "preview": "MIT License\n\nCopyright© 2017 J.S. Obeid\n\nPermission is hereby granted, free of charge, to any person \nobtaining a copy o"
  },
  {
    "path": "README.md",
    "chars": 3641,
    "preview": "# TrayPwrD3\n**Keeps dGPU on but idle** until needed. This addresses the Windows 10 (64bit) stutter/mouse freeze on dual "
  },
  {
    "path": "src/AboutDlg.cpp",
    "chars": 5950,
    "preview": "// AboutDlg.cpp : implementation file\r\n//\r\n\r\n#include \"stdafx.h\"\r\n#include \"traypwr.h\"\r\n#include \"AboutDlg.h\"\r\n\r\n#ifdef "
  },
  {
    "path": "src/AboutDlg.h",
    "chars": 1216,
    "preview": "// AboutDlg.h : header file\r\n//\r\n\r\n/////////////////////////////////////////////////////////////////////////////\r\n// CAb"
  },
  {
    "path": "src/D3dx12jo.cpp",
    "chars": 13109,
    "preview": "#include \"stdafx.h\"\r\n#include \"D3dx12jo.h\"\r\n\r\nusing namespace DirectX; // we will be using the directxmath library\r\n\r\nD3"
  },
  {
    "path": "src/D3dx12jo.h",
    "chars": 2407,
    "preview": "#pragma once\r\n\r\n#include <d3d12.h>\r\n#include <dxgi1_4.h>\r\n#include <D3Dcompiler.h>\r\n#include <DirectXMath.h>\r\n#include \""
  },
  {
    "path": "src/LICENSE.txt",
    "chars": 1075,
    "preview": "MIT License\r\n\r\nCopyright 2020 J.S. Obeid\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy"
  },
  {
    "path": "src/Mainfrm.cpp",
    "chars": 8316,
    "preview": "////////////////////////////////////////////////////////////////\r\n// Main frame window implementation\r\n//\r\n\r\n#include \"s"
  },
  {
    "path": "src/TrayIcon.CPP",
    "chars": 2540,
    "preview": "////////////////////////////////////////////////////////////////\r\n// CTrayIcon adopted from Microsoft Systems Journal's "
  },
  {
    "path": "src/TrayPwr.cpp",
    "chars": 3017,
    "preview": "////////////////////////////////////////////////////////////////\r\n// TrayPwr Adopted from Microsoft Systems Journal's CT"
  },
  {
    "path": "src/TrayPwr.h",
    "chars": 453,
    "preview": "////////////////////////////////////////////////////////////////\r\n// TrayPwr Copyright 1996 Microsoft Systems Journal.\r\n"
  },
  {
    "path": "src/TrayPwr.rc",
    "chars": 6877,
    "preview": "// Microsoft Visual C++ generated resource script.\r\n//\r\n#include \"resource.h\"\r\n\r\n#define APSTUDIO_READONLY_SYMBOLS\r\n////"
  },
  {
    "path": "src/TrayPwr.sln",
    "chars": 1293,
    "preview": "\r\nMicrosoft Visual Studio Solution File, Format Version 12.00\r\n# Visual Studio 14\r\nVisualStudioVersion = 14.0.25420.1\r\n"
  },
  {
    "path": "src/TrayPwr.vcxproj",
    "chars": 13983,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" ToolsVersion=\"14.0\" xmlns=\"http://schemas.micro"
  },
  {
    "path": "src/TrayPwr.vcxproj.user",
    "chars": 267,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"14.0\" xmlns=\"http://schemas.microsoft.com/developer/msbu"
  },
  {
    "path": "src/d3dx12.h",
    "chars": 51638,
    "preview": "//////////////////////////////////////////////////////////////////////////////\r\n//\r\n//  Copyright (C) Microsoft Corporat"
  },
  {
    "path": "src/mainfrm.h",
    "chars": 1388,
    "preview": "#include \"trayicon.h\"\r\n#include \"D3dx12jo.h\"\r\n\r\n// User defined Constants:\r\n\r\n#define WM_TPSCREENSAVER  WM_USER + 0x05\r\n"
  },
  {
    "path": "src/res/APP.RC2",
    "chars": 395,
    "preview": "//\r\n// APP.RC2 - resources Microsoft Visual C++ does not edit directly\r\n//\r\n\r\n#ifdef APSTUDIO_INVOKED\r\n\t#error this file"
  },
  {
    "path": "src/resource.h",
    "chars": 1044,
    "preview": "//{{NO_DEPENDENCIES}}\r\n// Microsoft Visual C++ generated include file.\r\n// Used by TrayPwr.rc\r\n//\r\n#define IDR_MAINFRAME"
  },
  {
    "path": "src/stdafx.cpp",
    "chars": 19,
    "preview": "#include \"stdafx.h\""
  },
  {
    "path": "src/stdafx.h",
    "chars": 274,
    "preview": "#pragma once\r\n\r\n#ifndef WIN32_LEAN_AND_MEAN\r\n#define WIN32_LEAN_AND_MEAN    // Exclude rarely-used stuff from Windows he"
  },
  {
    "path": "src/trayicon.h",
    "chars": 1087,
    "preview": "////////////////////////////////////////////////////////////////\r\n// CTrayIcon Copyright 1996 Microsoft Systems Journal."
  }
]

About this extraction

This page contains the full source code of the jobeid/TrayPwrD3 GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 22 files (118.2 KB), approximately 32.5k tokens, and a symbol index with 73 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!