diff --git a/1-D3D12Triangle/1-D3D12Trigger.cpp b/1-D3D12Triangle/1-D3D12Trigger.cpp index e6fe59a8ef5199b2229a406c6833891f2489a729..5d943c3a3ba6ba742316c4103851eaf8402a7e2c 100644 --- a/1-D3D12Triangle/1-D3D12Trigger.cpp +++ b/1-D3D12Triangle/1-D3D12Trigger.cpp @@ -74,10 +74,8 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l UINT64 n64FenceValue = 0ui64; HANDLE hEventFence = nullptr; - D3D12_VIEWPORT stViewPort = { 0.0f, 0.0f - , static_cast(iWidth), static_cast(iHeight), D3D12_MIN_DEPTH, D3D12_MAX_DEPTH }; - D3D12_RECT stScissorRect = { 0, 0 - , static_cast(iWidth), static_cast(iHeight) }; + D3D12_VIEWPORT stViewPort = { 0.0f, 0.0f, static_cast(iWidth), static_cast(iHeight), D3D12_MIN_DEPTH, D3D12_MAX_DEPTH }; + D3D12_RECT stScissorRect = { 0, 0, static_cast(iWidth), static_cast(iHeight) }; D3D_FEATURE_LEVEL emFeatureLevel = D3D_FEATURE_LEVEL_12_1; diff --git a/10-PixelShaderTips/10-PixelShaderTips.cpp b/10-PixelShaderTips/10-PixelShaderTips.cpp index 9f3df7c8527ff1c76c29ae63574d1fab8eb049e9..48174d7a770501a6b24a6581010b3e65fd083557 100644 --- a/10-PixelShaderTips/10-PixelShaderTips.cpp +++ b/10-PixelShaderTips/10-PixelShaderTips.cpp @@ -14,7 +14,7 @@ #include #endif #include -#include "..\WindowsCommons\d3dx12.h" + #include "..\WindowsCommons\DDSTextureLoader12.h" using namespace std; @@ -28,7 +28,7 @@ using namespace DirectX; #pragma comment(lib, "d3dcompiler.lib") #define GRS_WND_CLASS_NAME _T("GRS Game Window Class") -#define GRS_WND_TITLE _T("GRS DirectX12 MultiThread Sample") +#define GRS_WND_TITLE _T("GRS DirectX12 Pixel Shader Tips Sample (With MultiThread Render)") #define GRS_THROW_IF_FAILED(hr) {HRESULT _hr = (hr);if (FAILED(_hr)){ throw CGRSCOMException(_hr); }} @@ -37,6 +37,12 @@ using namespace DirectX; //更简洁的向上边界对齐算法 内存管理中常用 请记住 #define GRS_UPPER(A,B) ((UINT)(((A)+((B)-1))&~(B - 1))) +// 内存分配的宏定义 +#define GRS_ALLOC(sz) ::HeapAlloc(GetProcessHeap(),0,(sz)) +#define GRS_CALLOC(sz) ::HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(sz)) +#define GRS_CREALLOC(p,sz) ::HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(p),(sz)) +#define GRS_SAFE_FREE(p) if( nullptr != (p) ){ ::HeapFree( ::GetProcessHeap(),0,(p) ); (p) = nullptr; } + #define GRS_SAFE_RELEASE(p) if(nullptr != (p)){(p)->Release();(p)=nullptr;} //------------------------------------------------------------------------------------------------------------ // 为了调试加入下面的内联函数和宏定义,为每个接口对象设置名称,方便查看调试输出 @@ -172,14 +178,8 @@ struct ST_GRS_THREAD_PARAMS int g_iWndWidth = 1024; int g_iWndHeight = 768; -CD3DX12_VIEWPORT g_stViewPort(0.0f - , 0.0f - , static_cast(g_iWndWidth) - , static_cast(g_iWndHeight)); -CD3DX12_RECT g_stScissorRect(0 - , 0 - , static_cast(g_iWndWidth) - , static_cast(g_iWndHeight)); +D3D12_VIEWPORT g_stViewPort = { 0.0f, 0.0f, static_cast(g_iWndWidth), static_cast(g_iWndHeight), D3D12_MIN_DEPTH, D3D12_MAX_DEPTH }; +D3D12_RECT g_stScissorRect = { 0, 0, static_cast(g_iWndWidth), static_cast(g_iWndHeight) }; //初始的默认摄像机的位置 XMFLOAT3 g_f3EyePos = XMFLOAT3(0.0f, 5.0f, -10.0f); //眼睛位置 @@ -232,6 +232,7 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l const float faClearColor[] = { 0.2f, 0.5f, 1.0f, 1.0f }; ComPtr pIDXGIFactory5; + ComPtr pIDXGIFactory6; ComPtr pIAdapter1; ComPtr pID3D12Device4; ComPtr pIMainCmdQueue; @@ -239,6 +240,7 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l ComPtr pISwapChain3; ComPtr pIDepthStencilBuffer; //深度蜡板缓冲区 + UINT nCurrentFrameIndex = 0; DXGI_FORMAT emRTFormat = DXGI_FORMAT_R8G8B8A8_UNORM; @@ -265,9 +267,40 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l ComPtr pINoiseTexture; ComPtr pINoiseTextureUpload; + D3D12_HEAP_PROPERTIES stDefautHeapProps = {}; + stDefautHeapProps.Type = D3D12_HEAP_TYPE_DEFAULT; + stDefautHeapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + stDefautHeapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + stDefautHeapProps.CreationNodeMask = 0; + stDefautHeapProps.VisibleNodeMask = 0; + + D3D12_HEAP_PROPERTIES stUploadHeapProps = {}; + stUploadHeapProps.Type = D3D12_HEAP_TYPE_UPLOAD; + stUploadHeapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + stUploadHeapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + stUploadHeapProps.CreationNodeMask = 0; + stUploadHeapProps.VisibleNodeMask = 0; + + D3D12_RESOURCE_DESC stBufferResSesc = {}; + stBufferResSesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + stBufferResSesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + stBufferResSesc.Flags = D3D12_RESOURCE_FLAG_NONE; + stBufferResSesc.Format = DXGI_FORMAT_UNKNOWN; + stBufferResSesc.Width = 0; + stBufferResSesc.Height = 1; + stBufferResSesc.DepthOrArraySize = 1; + stBufferResSesc.MipLevels = 1; + stBufferResSesc.SampleDesc.Count = 1; + stBufferResSesc.SampleDesc.Quality = 0; + + D3D12_RESOURCE_BARRIER stResStateTransBarrier = {}; + stResStateTransBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + stResStateTransBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + stResStateTransBarrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + try { - // 得到当前的工作目录,方便我们使用相对路径来访问各种资源文件 + // 0、得到当前的工作目录,方便我们使用相对路径来访问各种资源文件 { if (0 == ::GetModuleFileName(nullptr, g_pszAppPath, MAX_PATH)) { @@ -293,7 +326,7 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l } } - //1、创建窗口 + // 1、创建窗口 { //--------------------------------------------------------------------------------------------- WNDCLASSEX wcex = {}; @@ -326,8 +359,9 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l } } - //2、打开显示子系统的调试支持 + // 2、创建DXGI Factory对象 { + //打开显示子系统的调试支持 #if defined(_DEBUG) ComPtr debugController; if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController)))) @@ -336,62 +370,31 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l // 打开附加的调试支持 nDXGIFactoryFlags |= DXGI_CREATE_FACTORY_DEBUG; } -#endif - } - - //3、创建DXGI Factory对象 - { +#endif GRS_THROW_IF_FAILED(CreateDXGIFactory2(nDXGIFactoryFlags, IID_PPV_ARGS(&pIDXGIFactory5))); GRS_SET_DXGI_DEBUGNAME_COMPTR(pIDXGIFactory5); - // 关闭ALT+ENTER键切换全屏的功能,因为我们没有实现OnSize处理,所以先关闭 - GRS_THROW_IF_FAILED(pIDXGIFactory5->MakeWindowAssociation(hWnd, DXGI_MWA_NO_ALT_ENTER)); + //获取IDXGIFactory6接口 + GRS_THROW_IF_FAILED(pIDXGIFactory5.As(&pIDXGIFactory6)); + GRS_SET_DXGI_DEBUGNAME_COMPTR(pIDXGIFactory6); } - //4、枚举适配器创建设备 - {//选择NUMA架构的独显来创建3D设备对象,暂时先不支持集显了,当然你可以修改这些行为 - D3D12_FEATURE_DATA_ARCHITECTURE stArchitecture = {}; - DXGI_ADAPTER_DESC1 stAdapterDesc = {}; - D3D_FEATURE_LEVEL emFeatureLevel = D3D_FEATURE_LEVEL_11_0; - HRESULT hr = S_OK; - for (UINT nAdapterIndex = 0; - DXGI_ERROR_NOT_FOUND != pIDXGIFactory5->EnumAdapters1(nAdapterIndex, &pIAdapter1); - ++nAdapterIndex) - { - ZeroMemory(&stAdapterDesc, sizeof(DXGI_ADAPTER_DESC1)); - pIAdapter1->GetDesc1(&stAdapterDesc); - - if (stAdapterDesc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) - {//跳过软件虚拟适配器设备 - continue; - } - - GRS_THROW_IF_FAILED(D3D12CreateDevice(pIAdapter1.Get() - , emFeatureLevel - , IID_PPV_ARGS(&pID3D12Device4))); - - GRS_THROW_IF_FAILED(pID3D12Device4->CheckFeatureSupport( - D3D12_FEATURE_ARCHITECTURE - , &stArchitecture - , sizeof(D3D12_FEATURE_DATA_ARCHITECTURE))); - - if (!stArchitecture.UMA) - { - break; - } - - pID3D12Device4.Reset(); - } + // 3、枚举高性能适配器来创建D3D设备对象 + { + GRS_THROW_IF_FAILED(pIDXGIFactory6->EnumAdapterByGpuPreference( + 0 + , DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE + , IID_PPV_ARGS(&pIAdapter1))); - if (nullptr == pID3D12Device4.Get()) - {// 可怜的机器上居然没有独显 还是先退出了事 - OutputDebugString(_T("\n未发现可供示例运行的独立显卡,示例程序退出!\n")); - throw CGRSCOMException(E_FAIL); - } + GRS_THROW_IF_FAILED(D3D12CreateDevice( + pIAdapter1.Get() + , D3D_FEATURE_LEVEL_12_1 + , IID_PPV_ARGS(&pID3D12Device4))); GRS_SET_D3D12_DEBUGNAME_COMPTR(pID3D12Device4); //将被使用的设备名称显示到窗口标题里 TCHAR pszWndTitle[MAX_PATH] = {}; + DXGI_ADAPTER_DESC1 stAdapterDesc = {}; GRS_THROW_IF_FAILED(pIAdapter1->GetDesc1(&stAdapterDesc)); ::GetWindowText(hWnd, pszWndTitle, MAX_PATH); StringCchPrintf(pszWndTitle @@ -400,9 +403,13 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l , pszWndTitle , stAdapterDesc.Description); ::SetWindowText(hWnd, pszWndTitle); + + //得到每个描述符元素的大小 + g_nRTVDescriptorSize = pID3D12Device4->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); + g_nSRVDescriptorSize = pID3D12Device4->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); } - //5、创建直接命令队列 + // 4、创建直接命令队列 { D3D12_COMMAND_QUEUE_DESC stQueueDesc = {}; stQueueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; @@ -410,7 +417,7 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l GRS_SET_D3D12_DEBUGNAME_COMPTR(pIMainCmdQueue); } - //6、创建交换链 + // 5、创建交换链 { DXGI_SWAP_CHAIN_DESC1 stSwapChainDesc = {}; stSwapChainDesc.BufferCount = g_nFrameBackBufCount; @@ -449,24 +456,21 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l , IID_PPV_ARGS(&g_pIRTVHeap))); GRS_SET_D3D12_DEBUGNAME_COMPTR(g_pIRTVHeap); - //得到每个描述符元素的大小 - g_nRTVDescriptorSize = pID3D12Device4->GetDescriptorHandleIncrementSize( - D3D12_DESCRIPTOR_HEAP_TYPE_RTV); - - g_nSRVDescriptorSize = pID3D12Device4->GetDescriptorHandleIncrementSize( - D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - - CD3DX12_CPU_DESCRIPTOR_HANDLE stRTVHandle(g_pIRTVHeap->GetCPUDescriptorHandleForHeapStart()); + D3D12_CPU_DESCRIPTOR_HANDLE stRTVHandle = g_pIRTVHeap->GetCPUDescriptorHandleForHeapStart(); for (UINT i = 0; i < g_nFrameBackBufCount; i++) {//这个循环暴漏了描述符堆实际上是个数组的本质 GRS_THROW_IF_FAILED(pISwapChain3->GetBuffer(i, IID_PPV_ARGS(&g_pIARenderTargets[i]))); GRS_SET_D3D12_DEBUGNAME_INDEXED_COMPTR(g_pIARenderTargets, i); pID3D12Device4->CreateRenderTargetView(g_pIARenderTargets[i].Get(), nullptr, stRTVHandle); - stRTVHandle.Offset(1, g_nRTVDescriptorSize); + stRTVHandle.ptr += g_nRTVDescriptorSize; } + + // 关闭ALT+ENTER键切换全屏的功能,因为我们没有实现OnSize处理,所以先关闭 + GRS_THROW_IF_FAILED(pIDXGIFactory5->MakeWindowAssociation(hWnd, DXGI_MWA_NO_ALT_ENTER)); + } - //7、创建深度缓冲及深度缓冲描述符堆 + // 6、创建深度缓冲及深度缓冲描述符堆 { D3D12_CLEAR_VALUE stDepthOptimizedClearValue = {}; stDepthOptimizedClearValue.Format = emDSFormat; @@ -475,17 +479,23 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l //使用隐式默认堆创建一个深度蜡板缓冲区, //因为基本上深度缓冲区会一直被使用,重用的意义不大,所以直接使用隐式堆,图方便 + D3D12_RESOURCE_DESC stDSResDesc = {}; + stDSResDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + stDSResDesc.Alignment = 0; + stDSResDesc.Format = emDSFormat; + stDSResDesc.Width = g_iWndWidth; + stDSResDesc.Height = g_iWndHeight; + stDSResDesc.DepthOrArraySize = 1; + stDSResDesc.MipLevels = 0; + stDSResDesc.SampleDesc.Count = 1; + stDSResDesc.SampleDesc.Quality = 0; + stDSResDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + stDSResDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL; + GRS_THROW_IF_FAILED(pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT) + &stDefautHeapProps , D3D12_HEAP_FLAG_NONE - , &CD3DX12_RESOURCE_DESC::Tex2D(emDSFormat - , g_iWndWidth - , g_iWndHeight - , 1 - , 0 - , 1 - , 0 - , D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) + , &stDSResDesc , D3D12_RESOURCE_STATE_DEPTH_WRITE , &stDepthOptimizedClearValue , IID_PPV_ARGS(&pIDepthStencilBuffer) @@ -511,7 +521,7 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l , g_pIDSVHeap->GetCPUDescriptorHandleForHeapStart()); } - //8、创建直接命令列表 + // 7、创建直接命令列表 { // 预处理命令列表 GRS_THROW_IF_FAILED(pID3D12Device4->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT @@ -530,7 +540,7 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l GRS_SET_D3D12_DEBUGNAME_COMPTR(pICmdListPost); } - //9、创建根签名 + // 8、创建根签名 {//这个例子中,所有物体使用相同的根签名,因为渲染过程中需要的参数是一样的 D3D12_FEATURE_DATA_ROOT_SIGNATURE stFeatureData = {}; // 检测是否支持V1.1版本的根签名 @@ -540,38 +550,60 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l D3D12_FEATURE_ROOT_SIGNATURE , &stFeatureData , sizeof(stFeatureData)))) - { - stFeatureData.HighestVersion = D3D_ROOT_SIGNATURE_VERSION_1_0; + {// 1.0版 直接丢异常退出了 + GRS_THROW_IF_FAILED(E_NOTIMPL); } - CD3DX12_DESCRIPTOR_RANGE1 stDSPRanges[3]; - stDSPRanges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 2, 0); //2 Const Buffer View - stDSPRanges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 2, 0); //2 Texture View 1 Texture + 1 Noise Texture - stDSPRanges[2].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 1, 0); - - CD3DX12_ROOT_PARAMETER1 stRootParameters[3]; - stRootParameters[0].InitAsDescriptorTable(1 - , &stDSPRanges[0] - , D3D12_SHADER_VISIBILITY_ALL); //CBV是所有Shader可见 - stRootParameters[1].InitAsDescriptorTable(1 - , &stDSPRanges[1] - , D3D12_SHADER_VISIBILITY_PIXEL);//SRV仅PS可见 - stRootParameters[2].InitAsDescriptorTable(1 - , &stDSPRanges[2] - , D3D12_SHADER_VISIBILITY_PIXEL);//SAMPLE仅PS可见 - - CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC stRootSignatureDesc; - stRootSignatureDesc.Init_1_1(_countof(stRootParameters) - , stRootParameters - , 0 - , nullptr - , D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT); + D3D12_DESCRIPTOR_RANGE1 stDSPRanges[3] = {}; + stDSPRanges[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_CBV; + stDSPRanges[0].NumDescriptors = 2; + stDSPRanges[0].BaseShaderRegister = 0; + stDSPRanges[0].RegisterSpace = 0; + stDSPRanges[0].Flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE; + stDSPRanges[0].OffsetInDescriptorsFromTableStart = 0; + + stDSPRanges[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + stDSPRanges[1].NumDescriptors = 2; + stDSPRanges[1].BaseShaderRegister = 0; + stDSPRanges[1].RegisterSpace = 0; + stDSPRanges[1].Flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE; + stDSPRanges[1].OffsetInDescriptorsFromTableStart = 0; + + stDSPRanges[2].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER; + stDSPRanges[2].NumDescriptors = 1; + stDSPRanges[2].BaseShaderRegister = 0; + stDSPRanges[2].RegisterSpace = 0; + stDSPRanges[2].Flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE; + stDSPRanges[2].OffsetInDescriptorsFromTableStart = 0; + + D3D12_ROOT_PARAMETER1 stRootParameters[3] = {}; + stRootParameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + stRootParameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; //CBV是所有Shader可见 + stRootParameters[0].DescriptorTable.NumDescriptorRanges = 1; + stRootParameters[0].DescriptorTable.pDescriptorRanges = &stDSPRanges[0]; + + stRootParameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + stRootParameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; //SRV仅PS可见 + stRootParameters[1].DescriptorTable.NumDescriptorRanges = 1; + stRootParameters[1].DescriptorTable.pDescriptorRanges = &stDSPRanges[1]; + + stRootParameters[2].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + stRootParameters[2].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; //SAMPLE仅PS可见 + stRootParameters[2].DescriptorTable.NumDescriptorRanges = 1; + stRootParameters[2].DescriptorTable.pDescriptorRanges = &stDSPRanges[2]; + + D3D12_VERSIONED_ROOT_SIGNATURE_DESC stRootSignatureDesc = {}; + stRootSignatureDesc.Version = D3D_ROOT_SIGNATURE_VERSION_1_1; + stRootSignatureDesc.Desc_1_1.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT; + stRootSignatureDesc.Desc_1_1.NumParameters = _countof(stRootParameters); + stRootSignatureDesc.Desc_1_1.pParameters = stRootParameters; + stRootSignatureDesc.Desc_1_1.NumStaticSamplers = 0; + stRootSignatureDesc.Desc_1_1.pStaticSamplers = nullptr; ComPtr pISignatureBlob; ComPtr pIErrorBlob; - GRS_THROW_IF_FAILED(D3DX12SerializeVersionedRootSignature(&stRootSignatureDesc - , stFeatureData.HighestVersion + GRS_THROW_IF_FAILED(D3D12SerializeVersionedRootSignature(&stRootSignatureDesc , &pISignatureBlob , &pIErrorBlob)); @@ -583,13 +615,12 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l GRS_SET_D3D12_DEBUGNAME_COMPTR(pIRootSignature); } - //10、编译Shader创建渲染管线状态对象 + // 9、编译Shader创建渲染管线状态对象 { + UINT compileFlags = 0; #if defined(_DEBUG) // Enable better shader debugging with the graphics debugging tools. - UINT compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; -#else - UINT compileFlags = 0; + compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; #endif //编译为行矩阵形式 compileFlags |= D3DCOMPILE_PACK_MATRIX_ROW_MAJOR; @@ -642,10 +673,18 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l D3D12_GRAPHICS_PIPELINE_STATE_DESC stPSODesc = {}; stPSODesc.InputLayout = { stIALayoutSphere, _countof(stIALayoutSphere) }; stPSODesc.pRootSignature = pIRootSignature.Get(); - stPSODesc.VS = CD3DX12_SHADER_BYTECODE(pIVSSphere.Get()); - stPSODesc.PS = CD3DX12_SHADER_BYTECODE(pIPSSphere.Get()); - stPSODesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT); - stPSODesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT); + stPSODesc.VS.BytecodeLength = pIVSSphere->GetBufferSize(); + stPSODesc.VS.pShaderBytecode = pIVSSphere->GetBufferPointer(); + stPSODesc.PS.BytecodeLength = pIPSSphere->GetBufferSize(); + stPSODesc.PS.pShaderBytecode = pIPSSphere->GetBufferPointer(); + + stPSODesc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID; + stPSODesc.RasterizerState.CullMode = D3D12_CULL_MODE_BACK; + + stPSODesc.BlendState.AlphaToCoverageEnable = FALSE; + stPSODesc.BlendState.IndependentBlendEnable = FALSE; + stPSODesc.BlendState.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL; + stPSODesc.SampleMask = UINT_MAX; stPSODesc.SampleDesc.Count = 1; stPSODesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; @@ -663,7 +702,7 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l GRS_SET_D3D12_DEBUGNAME_COMPTR(pIPSOSphere); } - //11、加载DDS噪声纹理 + // 10、加载DDS噪声纹理 { TCHAR pszNoiseTexture[MAX_PATH] = {}; StringCchPrintf(pszNoiseTexture, MAX_PATH, _T("%sAssets\\Noise1.dds"), g_pszAppPath); @@ -683,39 +722,111 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l , &bIsCube)); GRS_SET_D3D12_DEBUGNAME_COMPTR(pINoiseTexture); - UINT64 n64szUpSphere = GetRequiredIntermediateSize( - pINoiseTexture.Get() - , 0 - , static_cast(stArSubResources.size())); D3D12_RESOURCE_DESC stTXDesc = pINoiseTexture->GetDesc(); + UINT64 n64szUpSphere = 0; + pID3D12Device4->GetCopyableFootprints(&stTXDesc, 0, static_cast(stArSubResources.size()) + , 0, nullptr, nullptr, nullptr, &n64szUpSphere); + stBufferResSesc.Width = n64szUpSphere; GRS_THROW_IF_FAILED(pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD) + &stUploadHeapProps , D3D12_HEAP_FLAG_NONE - , &CD3DX12_RESOURCE_DESC::Buffer(n64szUpSphere) + , &stBufferResSesc , D3D12_RESOURCE_STATE_GENERIC_READ , nullptr , IID_PPV_ARGS(&pINoiseTextureUpload))); GRS_SET_D3D12_DEBUGNAME_COMPTR(pINoiseTextureUpload); //执行两个Copy动作将纹理上传到默认堆中 - UpdateSubresources(pICmdListPre.Get() - , pINoiseTexture.Get() - , pINoiseTextureUpload.Get() - , 0 - , 0 - , static_cast(stArSubResources.size()) - , stArSubResources.data()); + UINT nFirstSubresource = 0; + UINT nNumSubresources = static_cast(stArSubResources.size()); + D3D12_RESOURCE_DESC stUploadResDesc = pINoiseTextureUpload->GetDesc(); + D3D12_RESOURCE_DESC stDefaultResDesc = pINoiseTexture->GetDesc(); + + UINT64 n64RequiredSize = 0; + SIZE_T szMemToAlloc = static_cast(sizeof(D3D12_PLACED_SUBRESOURCE_FOOTPRINT) + + sizeof(UINT) + + sizeof(UINT64)) + * nNumSubresources; + + void* pMem = GRS_CALLOC(static_cast(szMemToAlloc)); + + if (nullptr == pMem) + { + throw CGRSCOMException(HRESULT_FROM_WIN32(GetLastError())); + } + + D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts = reinterpret_cast(pMem); + UINT64* pRowSizesInBytes = reinterpret_cast(pLayouts + nNumSubresources); + UINT* pNumRows = reinterpret_cast(pRowSizesInBytes + nNumSubresources); + + // 这里是第二次调用GetCopyableFootprints,就得到了所有子资源的详细信息 + pID3D12Device4->GetCopyableFootprints(&stDefaultResDesc, nFirstSubresource, nNumSubresources, 0, pLayouts, pNumRows, pRowSizesInBytes, &n64RequiredSize); + + BYTE* pData = nullptr; + GRS_THROW_IF_FAILED(pINoiseTextureUpload->Map(0, nullptr, reinterpret_cast(&pData))); + + // 第一遍Copy!注意3重循环每重的意思 + for (UINT nSubRes = 0; nSubRes < nNumSubresources; ++nSubRes) + {// SubResources + if ( pRowSizesInBytes[nSubRes] > (SIZE_T)-1 ) + { + throw CGRSCOMException(E_FAIL); + } + + D3D12_MEMCPY_DEST stCopyDestData = { pData + pLayouts[nSubRes].Offset + , pLayouts[nSubRes].Footprint.RowPitch + , pLayouts[nSubRes].Footprint.RowPitch * pNumRows[nSubRes] + }; + + for (UINT z = 0; z < pLayouts[nSubRes].Footprint.Depth; ++z) + {// Mipmap + BYTE* pDestSlice = reinterpret_cast(stCopyDestData.pData) + stCopyDestData.SlicePitch * z; + const BYTE* pSrcSlice = reinterpret_cast(stArSubResources[nSubRes].pData) + stArSubResources[nSubRes].SlicePitch * z; + for (UINT y = 0; y < pNumRows[nSubRes]; ++y) + {// Rows + memcpy(pDestSlice + stCopyDestData.RowPitch * y, + pSrcSlice + stArSubResources[nSubRes].RowPitch * y, + (SIZE_T)pRowSizesInBytes[nSubRes]); + } + } + } + pINoiseTextureUpload->Unmap(0, nullptr); + + // 第二次Copy! + if (stDefaultResDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) + {// Buffer 一次性复制就可以了,因为没有行对齐和行大小不一致的问题,Buffer中行数就是1 + pICmdListPre->CopyBufferRegion( pINoiseTexture.Get(), 0, pINoiseTextureUpload.Get(), pLayouts[0].Offset, pLayouts[0].Footprint.Width); + } + else + { + for (UINT nSubRes = 0; nSubRes < nNumSubresources; ++nSubRes) + { + D3D12_TEXTURE_COPY_LOCATION stDstCopyLocation = {}; + stDstCopyLocation.pResource = pINoiseTexture.Get(); + stDstCopyLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + stDstCopyLocation.SubresourceIndex = nSubRes; + + D3D12_TEXTURE_COPY_LOCATION stSrcCopyLocation = {}; + stSrcCopyLocation.pResource = pINoiseTextureUpload.Get(); + stSrcCopyLocation.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + stSrcCopyLocation.PlacedFootprint = pLayouts[nSubRes]; + + pICmdListPre->CopyTextureRegion(&stDstCopyLocation, 0, 0, 0, &stSrcCopyLocation, nullptr); + } + } + + GRS_SAFE_FREE(pMem); //同步 - pICmdListPre->ResourceBarrier(1 - , &CD3DX12_RESOURCE_BARRIER::Transition(pINoiseTexture.Get() - , D3D12_RESOURCE_STATE_COPY_DEST - , D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)); + stResStateTransBarrier.Transition.pResource = pINoiseTexture.Get(); + stResStateTransBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST; + stResStateTransBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + pICmdListPre->ResourceBarrier(1, &stResStateTransBarrier); } - //12、准备参数并启动多个渲染线程 + // 11、准备参数并启动多个渲染线程 { USES_CONVERSION; // 球体个性参数 @@ -733,7 +844,6 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l StringCchPrintfA(g_stThreadParams[g_nThdPlane].pszMeshFile, MAX_PATH, "%sAssets\\Plane.txt", T2A(g_pszAppPath)); g_stThreadParams[g_nThdPlane].v4ModelPos = XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f); - // 物体的共性参数,也就是各线程的共性参数 for (int i = 0; i < g_nMaxThread; i++) { @@ -781,7 +891,7 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l } } - //13、创建围栏对象 + // 12、创建围栏对象 { GRS_THROW_IF_FAILED(pID3D12Device4->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&pIFence))); GRS_SET_D3D12_DEBUGNAME_COMPTR(pIFence); @@ -831,7 +941,6 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l { case 0://状态0,表示等到各子线程加载资源完毕,此时执行一次命令列表完成各子线程要求的资源上传的第二个Copy命令 { - arCmdList.RemoveAll(); //执行命令列表 arCmdList.Add(pICmdListPre.Get()); //主线程负责加载Noise纹理 @@ -894,26 +1003,24 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l //渲染前处理 { - pICmdListPre->ResourceBarrier(1 - , &CD3DX12_RESOURCE_BARRIER::Transition( - g_pIARenderTargets[nCurrentFrameIndex].Get() - , D3D12_RESOURCE_STATE_PRESENT - , D3D12_RESOURCE_STATE_RENDER_TARGET) - ); + stResStateTransBarrier.Transition.pResource = g_pIARenderTargets[nCurrentFrameIndex].Get(); + stResStateTransBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT; + stResStateTransBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET; + pICmdListPre->ResourceBarrier(1, &stResStateTransBarrier); //偏移描述符指针到指定帧缓冲视图位置 - CD3DX12_CPU_DESCRIPTOR_HANDLE stRTVHandle(g_pIRTVHeap->GetCPUDescriptorHandleForHeapStart() - , nCurrentFrameIndex, g_nRTVDescriptorSize); - CD3DX12_CPU_DESCRIPTOR_HANDLE dsvHandle(g_pIDSVHeap->GetCPUDescriptorHandleForHeapStart()); + D3D12_CPU_DESCRIPTOR_HANDLE stRTVHandle = g_pIRTVHeap->GetCPUDescriptorHandleForHeapStart(); + stRTVHandle.ptr += (nCurrentFrameIndex * g_nRTVDescriptorSize); + D3D12_CPU_DESCRIPTOR_HANDLE stDSVHandle = g_pIDSVHeap->GetCPUDescriptorHandleForHeapStart(); //设置渲染目标 - pICmdListPre->OMSetRenderTargets(1, &stRTVHandle, FALSE, &dsvHandle); + pICmdListPre->OMSetRenderTargets(1, &stRTVHandle, FALSE, &stDSVHandle); pICmdListPre->RSSetViewports(1, &g_stViewPort); pICmdListPre->RSSetScissorRects(1, &g_stScissorRect); pICmdListPre->ClearRenderTargetView(stRTVHandle, faClearColor, 0, nullptr); - pICmdListPre->ClearDepthStencilView(dsvHandle, D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, nullptr); + pICmdListPre->ClearDepthStencilView(stDSVHandle, D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, nullptr); } nStates = 2; @@ -937,11 +1044,11 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l break; case 2:// 状态2 表示所有的渲染命令列表都记录完成了,开始后处理和执行命令列表 { - pICmdListPost->ResourceBarrier(1 - , &CD3DX12_RESOURCE_BARRIER::Transition( - g_pIARenderTargets[nCurrentFrameIndex].Get() - , D3D12_RESOURCE_STATE_RENDER_TARGET - , D3D12_RESOURCE_STATE_PRESENT)); + stResStateTransBarrier.Transition.pResource = g_pIARenderTargets[nCurrentFrameIndex].Get(); + stResStateTransBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET; + stResStateTransBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT; + + pICmdListPost->ResourceBarrier(1, &stResStateTransBarrier); //关闭命令列表,可以去执行了 GRS_THROW_IF_FAILED(pICmdListPre->Close()); @@ -1097,6 +1204,38 @@ UINT __stdcall RenderThread(void* pParam) std::vector stArSubResources; DDS_ALPHA_MODE emAlphaMode = DDS_ALPHA_MODE_UNKNOWN; bool bIsCube = false; + + D3D12_HEAP_PROPERTIES stDefautHeapProps = {}; + stDefautHeapProps.Type = D3D12_HEAP_TYPE_DEFAULT; + stDefautHeapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + stDefautHeapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + stDefautHeapProps.CreationNodeMask = 0; + stDefautHeapProps.VisibleNodeMask = 0; + + D3D12_HEAP_PROPERTIES stUploadHeapProps = {}; + stUploadHeapProps.Type = D3D12_HEAP_TYPE_UPLOAD; + stUploadHeapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + stUploadHeapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + stUploadHeapProps.CreationNodeMask = 0; + stUploadHeapProps.VisibleNodeMask = 0; + + D3D12_RESOURCE_DESC stBufferResSesc = {}; + stBufferResSesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + stBufferResSesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + stBufferResSesc.Flags = D3D12_RESOURCE_FLAG_NONE; + stBufferResSesc.Format = DXGI_FORMAT_UNKNOWN; + stBufferResSesc.Width = 0; + stBufferResSesc.Height = 1; + stBufferResSesc.DepthOrArraySize = 1; + stBufferResSesc.MipLevels = 1; + stBufferResSesc.SampleDesc.Count = 1; + stBufferResSesc.SampleDesc.Quality = 0; + + D3D12_RESOURCE_BARRIER stResStateTransBarrier = {}; + stResStateTransBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + stResStateTransBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + stResStateTransBarrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + //1、加载DDS纹理 { GRS_THROW_IF_FAILED(LoadDDSTextureFromFile( @@ -1110,12 +1249,10 @@ UINT __stdcall RenderThread(void* pParam) , &bIsCube)); GRS_SET_D3D12_DEBUGNAME_COMPTR(pITexture); - UINT64 n64szUpSphere = GetRequiredIntermediateSize( - pITexture.Get() - , 0 - , static_cast(stArSubResources.size())); - + UINT64 n64szUpSphere = 0; D3D12_RESOURCE_DESC stTXDesc = pITexture->GetDesc(); + pThdPms->pID3D12Device4->GetCopyableFootprints(&stTXDesc, 0, static_cast(stArSubResources.size()) + , 0, nullptr, nullptr, nullptr, &n64szUpSphere); //记录纹理大小 pThdPms->v2TexSize = XMFLOAT2( @@ -1123,29 +1260,102 @@ UINT __stdcall RenderThread(void* pParam) , static_cast(stTXDesc.Height) ); + stBufferResSesc.Width = n64szUpSphere; GRS_THROW_IF_FAILED(pThdPms->pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD) + &stUploadHeapProps , D3D12_HEAP_FLAG_NONE - , &CD3DX12_RESOURCE_DESC::Buffer(n64szUpSphere) + , &stBufferResSesc , D3D12_RESOURCE_STATE_GENERIC_READ , nullptr , IID_PPV_ARGS(&pITextureUpload))); GRS_SET_D3D12_DEBUGNAME_COMPTR(pITextureUpload); //执行两个Copy动作将纹理上传到默认堆中 - UpdateSubresources(pThdPms->pICmdList - , pITexture.Get() - , pITextureUpload.Get() - , 0 - , 0 - , static_cast(stArSubResources.size()) - , stArSubResources.data()); + UINT nFirstSubresource = 0; + UINT nNumSubresources = static_cast(stArSubResources.size()); + D3D12_RESOURCE_DESC stUploadResDesc = pITextureUpload->GetDesc(); + D3D12_RESOURCE_DESC stDefaultResDesc = pITexture->GetDesc(); + + UINT64 n64RequiredSize = 0; + SIZE_T szMemToAlloc = static_cast(sizeof(D3D12_PLACED_SUBRESOURCE_FOOTPRINT) + + sizeof(UINT) + + sizeof(UINT64)) + * nNumSubresources; + + void* pMem = GRS_CALLOC(static_cast(szMemToAlloc)); + + if (nullptr == pMem) + { + throw CGRSCOMException(HRESULT_FROM_WIN32(GetLastError())); + } + + D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts = reinterpret_cast(pMem); + UINT64* pRowSizesInBytes = reinterpret_cast(pLayouts + nNumSubresources); + UINT* pNumRows = reinterpret_cast(pRowSizesInBytes + nNumSubresources); + + // 这里是第二次调用GetCopyableFootprints,就得到了所有子资源的详细信息 + pThdPms->pID3D12Device4->GetCopyableFootprints(&stDefaultResDesc, nFirstSubresource, nNumSubresources, 0, pLayouts, pNumRows, pRowSizesInBytes, &n64RequiredSize); + + BYTE* pData = nullptr; + GRS_THROW_IF_FAILED(pITextureUpload->Map(0, nullptr, reinterpret_cast(&pData))); + + // 第一遍Copy!注意3重循环每重的意思 + for (UINT nSubRes = 0; nSubRes < nNumSubresources; ++nSubRes) + {// SubResources + if (pRowSizesInBytes[nSubRes] > (SIZE_T)-1) + { + throw CGRSCOMException(E_FAIL); + } + + D3D12_MEMCPY_DEST stCopyDestData = { pData + pLayouts[nSubRes].Offset + , pLayouts[nSubRes].Footprint.RowPitch + , pLayouts[nSubRes].Footprint.RowPitch * pNumRows[nSubRes] + }; + + for (UINT z = 0; z < pLayouts[nSubRes].Footprint.Depth; ++z) + {// Mipmap + BYTE* pDestSlice = reinterpret_cast(stCopyDestData.pData) + stCopyDestData.SlicePitch * z; + const BYTE* pSrcSlice = reinterpret_cast(stArSubResources[nSubRes].pData) + stArSubResources[nSubRes].SlicePitch * z; + for (UINT y = 0; y < pNumRows[nSubRes]; ++y) + {// Rows + memcpy(pDestSlice + stCopyDestData.RowPitch * y, + pSrcSlice + stArSubResources[nSubRes].RowPitch * y, + (SIZE_T)pRowSizesInBytes[nSubRes]); + } + } + } + pITextureUpload->Unmap(0, nullptr); + + // 第二次Copy! + if (stDefaultResDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) + {// Buffer 一次性复制就可以了,因为没有行对齐和行大小不一致的问题,Buffer中行数就是1 + pThdPms->pICmdList->CopyBufferRegion(pITexture.Get(), 0, pITextureUpload.Get(), pLayouts[0].Offset, pLayouts[0].Footprint.Width); + } + else + { + for (UINT nSubRes = 0; nSubRes < nNumSubresources; ++nSubRes) + { + D3D12_TEXTURE_COPY_LOCATION stDstCopyLocation = {}; + stDstCopyLocation.pResource = pITexture.Get(); + stDstCopyLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + stDstCopyLocation.SubresourceIndex = nSubRes; + + D3D12_TEXTURE_COPY_LOCATION stSrcCopyLocation = {}; + stSrcCopyLocation.pResource = pITextureUpload.Get(); + stSrcCopyLocation.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + stSrcCopyLocation.PlacedFootprint = pLayouts[nSubRes]; + + pThdPms->pICmdList->CopyTextureRegion(&stDstCopyLocation, 0, 0, 0, &stSrcCopyLocation, nullptr); + } + } + + GRS_SAFE_FREE(pMem); //同步 - pThdPms->pICmdList->ResourceBarrier(1 - , &CD3DX12_RESOURCE_BARRIER::Transition(pITexture.Get() - , D3D12_RESOURCE_STATE_COPY_DEST - , D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)); + stResStateTransBarrier.Transition.pResource = pITexture.Get(); + stResStateTransBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST; + stResStateTransBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + pThdPms->pICmdList->ResourceBarrier(1, &stResStateTransBarrier); } //2、创建描述符堆 @@ -1169,10 +1379,8 @@ UINT __stdcall RenderThread(void* pParam) stSRVDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; stSRVDesc.Texture2D.MipLevels = 1; - CD3DX12_CPU_DESCRIPTOR_HANDLE stCbvSrvHandle( - pISRVCBVHp->GetCPUDescriptorHandleForHeapStart() - , 2 - , g_nSRVDescriptorSize); + D3D12_CPU_DESCRIPTOR_HANDLE stCbvSrvHandle = pISRVCBVHp->GetCPUDescriptorHandleForHeapStart(); + stCbvSrvHandle.ptr += (2 * g_nSRVDescriptorSize); pThdPms->pID3D12Device4->CreateShaderResourceView( pITexture.Get() @@ -1182,7 +1390,7 @@ UINT __stdcall RenderThread(void* pParam) //创建噪声纹理的描述符 stTXDesc = pThdPms->pINoiseTexture->GetDesc(); stSRVDesc.Format = stTXDesc.Format; - stCbvSrvHandle.Offset(1, g_nSRVDescriptorSize); + stCbvSrvHandle.ptr += g_nSRVDescriptorSize; pThdPms->pID3D12Device4->CreateShaderResourceView( pThdPms->pINoiseTexture , &stSRVDesc @@ -1191,10 +1399,11 @@ UINT __stdcall RenderThread(void* pParam) //3、创建常量缓冲 { + stBufferResSesc.Width = szMVPBuf; GRS_THROW_IF_FAILED(pThdPms->pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD) + &stUploadHeapProps , D3D12_HEAP_FLAG_NONE - , &CD3DX12_RESOURCE_DESC::Buffer(szMVPBuf) //注意缓冲尺寸设置为256边界对齐大小 + , &stBufferResSesc //注意缓冲尺寸设置为256边界对齐大小 , D3D12_RESOURCE_STATE_GENERIC_READ , nullptr , IID_PPV_ARGS(&pICBWVP))); @@ -1208,13 +1417,14 @@ UINT __stdcall RenderThread(void* pParam) cbvDesc.BufferLocation = pICBWVP->GetGPUVirtualAddress(); cbvDesc.SizeInBytes = static_cast(szMVPBuf); - CD3DX12_CPU_DESCRIPTOR_HANDLE stCbvSrvHandle(pISRVCBVHp->GetCPUDescriptorHandleForHeapStart()); + D3D12_CPU_DESCRIPTOR_HANDLE stCbvSrvHandle = pISRVCBVHp->GetCPUDescriptorHandleForHeapStart(); pThdPms->pID3D12Device4->CreateConstantBufferView(&cbvDesc, stCbvSrvHandle); + stBufferResSesc.Width = szPerObjDataBuf;//注意缓冲尺寸设置为256边界对齐大小 GRS_THROW_IF_FAILED(pThdPms->pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD) + &stUploadHeapProps , D3D12_HEAP_FLAG_NONE - , &CD3DX12_RESOURCE_DESC::Buffer(szPerObjDataBuf) //注意缓冲尺寸设置为256边界对齐大小 + , &stBufferResSesc , D3D12_RESOURCE_STATE_GENERIC_READ , nullptr , IID_PPV_ARGS(&pICBPerObjData))); @@ -1226,7 +1436,7 @@ UINT __stdcall RenderThread(void* pParam) cbvDesc.BufferLocation = pICBPerObjData->GetGPUVirtualAddress(); cbvDesc.SizeInBytes = static_cast(szPerObjDataBuf); - stCbvSrvHandle.Offset(1, g_nSRVDescriptorSize); + stCbvSrvHandle.ptr += g_nSRVDescriptorSize; pThdPms->pID3D12Device4->CreateConstantBufferView(&cbvDesc, stCbvSrvHandle); } @@ -1266,10 +1476,11 @@ UINT __stdcall RenderThread(void* pParam) nIndexCnt = nVertexCnt; //创建 Vertex Buffer 仅使用Upload隐式堆 + stBufferResSesc.Width = nVertexCnt * sizeof(ST_GRS_VERTEX); GRS_THROW_IF_FAILED(pThdPms->pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD) + &stUploadHeapProps , D3D12_HEAP_FLAG_NONE - , &CD3DX12_RESOURCE_DESC::Buffer(nVertexCnt * sizeof(ST_GRS_VERTEX)) + , &stBufferResSesc , D3D12_RESOURCE_STATE_GENERIC_READ , nullptr , IID_PPV_ARGS(&pIVB))); @@ -1277,7 +1488,7 @@ UINT __stdcall RenderThread(void* pParam) UINT8* pVertexDataBegin = nullptr; - CD3DX12_RANGE stReadRange(0, 0); + D3D12_RANGE stReadRange = { 0, 0 }; //使用map-memcpy-unmap大法将数据传至顶点缓冲对象 GRS_THROW_IF_FAILED(pIVB->Map(0 @@ -1287,10 +1498,11 @@ UINT __stdcall RenderThread(void* pParam) pIVB->Unmap(0, nullptr); //创建 Index Buffer 仅使用Upload隐式堆 + stBufferResSesc.Width = nIndexCnt * sizeof(UINT); GRS_THROW_IF_FAILED(pThdPms->pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD) + &stUploadHeapProps , D3D12_HEAP_FLAG_NONE - , &CD3DX12_RESOURCE_DESC::Buffer(nIndexCnt * sizeof(UINT)) + , &stBufferResSesc , D3D12_RESOURCE_STATE_GENERIC_READ , nullptr , IID_PPV_ARGS(&pIIB))); @@ -1313,8 +1525,8 @@ UINT __stdcall RenderThread(void* pParam) stIBV.Format = DXGI_FORMAT_R32_UINT; stIBV.SizeInBytes = nIndexCnt * sizeof(UINT); - ::HeapFree(::GetProcessHeap(), 0, pstVertices); - ::HeapFree(::GetProcessHeap(), 0, pnIndices); + GRS_SAFE_FREE(pstVertices); + GRS_SAFE_FREE(pnIndices); } //6、设置事件对象 通知并切回主线程 完成资源的第二个Copy命令 @@ -1389,12 +1601,11 @@ UINT __stdcall RenderThread(void* pParam) //--------------------------------------------------------------------------------------------- //设置对应的渲染目标和视裁剪框(这是渲染子线程必须要做的步骤,基本也就是所谓多线程渲染的核心秘密所在了) { - CD3DX12_CPU_DESCRIPTOR_HANDLE stRTVHandle(g_pIRTVHeap->GetCPUDescriptorHandleForHeapStart() - , pThdPms->nCurrentFrameIndex - , g_nRTVDescriptorSize); - CD3DX12_CPU_DESCRIPTOR_HANDLE dsvHandle(g_pIDSVHeap->GetCPUDescriptorHandleForHeapStart()); + D3D12_CPU_DESCRIPTOR_HANDLE stRTVHandle = g_pIRTVHeap->GetCPUDescriptorHandleForHeapStart(); + stRTVHandle.ptr += (pThdPms->nCurrentFrameIndex * g_nRTVDescriptorSize); + D3D12_CPU_DESCRIPTOR_HANDLE stDSVHandle = g_pIDSVHeap->GetCPUDescriptorHandleForHeapStart(); //设置渲染目标 - pThdPms->pICmdList->OMSetRenderTargets(1, &stRTVHandle, FALSE, &dsvHandle); + pThdPms->pICmdList->OMSetRenderTargets(1, &stRTVHandle, FALSE, &stDSVHandle); pThdPms->pICmdList->RSSetViewports(1, &g_stViewPort); pThdPms->pICmdList->RSSetScissorRects(1, &g_stScissorRect); } @@ -1407,12 +1618,12 @@ UINT __stdcall RenderThread(void* pParam) ID3D12DescriptorHeap* ppHeapsSphere[] = { pISRVCBVHp.Get(),pISampleHp.Get() }; pThdPms->pICmdList->SetDescriptorHeaps(_countof(ppHeapsSphere), ppHeapsSphere); - CD3DX12_GPU_DESCRIPTOR_HANDLE stSRVHandle(pISRVCBVHp->GetGPUDescriptorHandleForHeapStart()); + D3D12_GPU_DESCRIPTOR_HANDLE stSRVHandle = pISRVCBVHp->GetGPUDescriptorHandleForHeapStart(); //设置CBV 注意有两个Const Buffer pThdPms->pICmdList->SetGraphicsRootDescriptorTable(0, stSRVHandle); //偏移至Texture的View - stSRVHandle.Offset(2, g_nSRVDescriptorSize); + stSRVHandle.ptr += (2 * g_nSRVDescriptorSize); //设置SRV pThdPms->pICmdList->SetGraphicsRootDescriptorTable(1, stSRVHandle); @@ -1642,12 +1853,8 @@ BOOL LoadMeshVertex(const CHAR* pszMeshFileName,UINT& nVertexCnt, ST_GRS_VERTEX* fin.get(input); fin.get(input); - ppVertex = (ST_GRS_VERTEX*)HeapAlloc(::GetProcessHeap() - , HEAP_ZERO_MEMORY - , nVertexCnt * sizeof(ST_GRS_VERTEX)); - ppIndices = (UINT*)HeapAlloc(::GetProcessHeap() - , HEAP_ZERO_MEMORY - , nVertexCnt * sizeof(UINT)); + ppVertex = (ST_GRS_VERTEX*)GRS_CALLOC( nVertexCnt * sizeof(ST_GRS_VERTEX) ); + ppIndices = (UINT*)GRS_CALLOC( nVertexCnt * sizeof(UINT) ); for (UINT i = 0; i < nVertexCnt; i++) { diff --git a/11-MultiThreadAndAdapter/11-MultiThreadAndAdapter.cpp b/11-MultiThreadAndAdapter/11-MultiThreadAndAdapter.cpp index 2b3572f00a3fe305699b8cdc796784a18e884bbc..8458f2b7324cd40b46178c6422fe201f94880cd9 100644 --- a/11-MultiThreadAndAdapter/11-MultiThreadAndAdapter.cpp +++ b/11-MultiThreadAndAdapter/11-MultiThreadAndAdapter.cpp @@ -14,7 +14,6 @@ #include #endif #include -#include "..\WindowsCommons\d3dx12.h" #include "..\WindowsCommons\DDSTextureLoader12.h" using namespace std; @@ -30,7 +29,7 @@ using namespace DirectX; #ifndef GRS_BLOCK #define GRS_WND_CLASS_NAME _T("GRS Game Window Class") -#define GRS_WND_TITLE _T("GRS DirectX12 MultiThread&Adapter Sample") +#define GRS_WND_TITLE _T("GRS DirectX12 MultiThread & MultiAdapter Sample") #define GRS_THROW_IF_FAILED(hr) { HRESULT _hr = (hr);if (FAILED(_hr)){ throw CGRSCOMException(_hr); } } #define GRS_SAFE_RELEASE(p) if(nullptr != (p)){(p)->Release();(p)=nullptr;} @@ -40,6 +39,12 @@ using namespace DirectX; //更简洁的向上边界对齐算法 内存管理中常用 请记住 #define GRS_UPPER(A,B) ((UINT)(((A)+((B)-1))&~(B - 1))) +// 内存分配的宏定义 +#define GRS_ALLOC(sz) ::HeapAlloc(GetProcessHeap(),0,(sz)) +#define GRS_CALLOC(sz) ::HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(sz)) +#define GRS_CREALLOC(p,sz) ::HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(p),(sz)) +#define GRS_SAFE_FREE(p) if( nullptr != (p) ){ ::HeapFree( ::GetProcessHeap(),0,(p) ); (p) = nullptr; } + // 为了调试加入下面的内联函数和宏定义,为每个接口对象设置名称,方便查看调试输出 #if defined(_DEBUG) inline void GRS_SetD3D12DebugName(ID3D12Object* pObject, LPCWSTR name) @@ -225,14 +230,8 @@ struct ST_GRS_PEROBJECT_CB int g_iWndWidth = 1024; int g_iWndHeight = 768; -CD3DX12_VIEWPORT g_stViewPort(0.0f - , 0.0f - , static_cast(g_iWndWidth) - , static_cast(g_iWndHeight)); -CD3DX12_RECT g_stScissorRect(0 - , 0 - , static_cast(g_iWndWidth) - , static_cast(g_iWndHeight)); +D3D12_VIEWPORT g_stViewPort = { 0.0f, 0.0f, static_cast(g_iWndWidth), static_cast(g_iWndHeight) , D3D12_MIN_DEPTH, D3D12_MAX_DEPTH }; +D3D12_RECT g_stScissorRect = { 0, 0, static_cast(g_iWndWidth), static_cast(g_iWndHeight) }; //初始的默认摄像机的位置 XMFLOAT3 g_f3EyePos = XMFLOAT3(0.0f, 5.0f, -10.0f); //眼睛位置 @@ -277,7 +276,7 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l HWND hWnd = nullptr; MSG msg = {}; - UINT nDXGIFactoryFlags = 0U; + const float faClearColor[] = { 0.2f, 0.5f, 1.0f, 1.0f }; ComPtr pIDXGIFactory5; @@ -299,7 +298,7 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l //当不能直接共享资源时,就在辅助显卡上创建独立的资源,用于复制主显卡渲染结果过来 ComPtr pISecondaryAdapterTexutrePerFrame[g_nFrameBackBufCount]; BOOL bCrossAdapterTextureSupport = FALSE; - CD3DX12_RESOURCE_DESC stRenderTargetDesc = {}; + D3D12_RESOURCE_DESC stRenderTargetDesc = {}; const float v4ClearColor[4] = { 0.2f, 0.5f, 1.0f, 1.0f }; UINT nCurrentFrameIndex = 0; @@ -331,7 +330,7 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l ComPtr pIVBQuadUpload; D3D12_VERTEX_BUFFER_VIEW pstVBVQuad; SIZE_T szSecondPassCB = GRS_UPPER(sizeof(ST_GRS_PEROBJECT_CB), 256); - ST_GRS_PEROBJECT_CB* pstCBSecondPass = nullptr; + ST_GRS_PEROBJECT_CB* pstCBSecondPass = nullptr; ComPtr pICBResSecondPass; ComPtr pINoiseTexture; ComPtr pINoiseTextureUpload; @@ -344,11 +343,42 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l ComPtr pISRVHeapPostPass[c_nPostPassCnt]; ComPtr pISampleHeapPostPass; + D3D12_HEAP_PROPERTIES stDefautHeapProps = {}; + stDefautHeapProps.Type = D3D12_HEAP_TYPE_DEFAULT; + stDefautHeapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + stDefautHeapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + stDefautHeapProps.CreationNodeMask = 0; + stDefautHeapProps.VisibleNodeMask = 0; + + D3D12_HEAP_PROPERTIES stUploadHeapProps = {}; + stUploadHeapProps.Type = D3D12_HEAP_TYPE_UPLOAD; + stUploadHeapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + stUploadHeapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + stUploadHeapProps.CreationNodeMask = 0; + stUploadHeapProps.VisibleNodeMask = 0; + + D3D12_RESOURCE_DESC stBufferResSesc = {}; + stBufferResSesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + stBufferResSesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + stBufferResSesc.Flags = D3D12_RESOURCE_FLAG_NONE; + stBufferResSesc.Format = DXGI_FORMAT_UNKNOWN; + stBufferResSesc.Width = 0; + stBufferResSesc.Height = 1; + stBufferResSesc.DepthOrArraySize = 1; + stBufferResSesc.MipLevels = 1; + stBufferResSesc.SampleDesc.Count = 1; + stBufferResSesc.SampleDesc.Quality = 0; + + D3D12_RESOURCE_BARRIER stResStateTransBarrier = {}; + stResStateTransBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + stResStateTransBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + stResStateTransBarrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + try { GRS_THROW_IF_FAILED(::CoInitialize(nullptr)); - // 得到当前的工作目录,方便我们使用相对路径来访问各种资源文件 + // 0、得到当前的工作目录,方便我们使用相对路径来访问各种资源文件 { if (0 == ::GetModuleFileName(nullptr, g_pszAppPath, MAX_PATH)) { @@ -374,7 +404,7 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l } } - //1、创建窗口 + // 1、创建窗口 { //--------------------------------------------------------------------------------------------- WNDCLASSEX wcex = {}; @@ -407,9 +437,11 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l } } - //2、打开显示子系统的调试支持 + // 2、创建DXGI Factory对象 { + UINT nDXGIFactoryFlags = 0U; #if defined(_DEBUG) + // 打开显示子系统的调试支持 ComPtr debugController; if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController)))) { @@ -418,27 +450,19 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l nDXGIFactoryFlags |= DXGI_CREATE_FACTORY_DEBUG; } #endif - } - - //3、创建DXGI Factory对象 - { GRS_THROW_IF_FAILED(CreateDXGIFactory2(nDXGIFactoryFlags, IID_PPV_ARGS(&pIDXGIFactory5))); GRS_SET_DXGI_DEBUGNAME_COMPTR(pIDXGIFactory5); - // 关闭ALT+ENTER键切换全屏的功能,因为我们没有实现OnSize处理,所以先关闭 - GRS_THROW_IF_FAILED(pIDXGIFactory5->MakeWindowAssociation(hWnd, DXGI_MWA_NO_ALT_ENTER)); //获取IDXGIFactory6接口 GRS_THROW_IF_FAILED(pIDXGIFactory5.As(&pIDXGIFactory6)); GRS_SET_DXGI_DEBUGNAME_COMPTR(pIDXGIFactory6); } - //4、枚举适配器创建设备 - {//选择NUMA架构的独显来创建3D设备对象,暂时先不支持集显了,当然你可以修改这些行为 - D3D12_FEATURE_DATA_ARCHITECTURE stArchitecture = {}; + // 3、依据性能从高到低枚举适配器创建设备 + { DXGI_ADAPTER_DESC1 stAdapterDesc[c_nMaxGPUCnt] = {}; D3D_FEATURE_LEVEL emFeatureLevel = D3D_FEATURE_LEVEL_12_1; D3D12_COMMAND_QUEUE_DESC stQueueDesc = {}; stQueueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; - HRESULT hr = S_OK; UINT i = 0; @@ -517,7 +541,7 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l ::SetWindowText(hWnd, pszWndTitle); } - //5、创建命令列表 + // 4、创建命令列表 { WCHAR pszDebugName[MAX_PATH] = {}; @@ -585,7 +609,7 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l GRS_SET_D3D12_DEBUGNAME_COMPTR(pICMDListPostPass); } - //6、创建围栏对象,以及多GPU同步围栏对象 + // 5、创建围栏对象,以及多GPU同步围栏对象 { for (int i = 0; i < c_nMaxGPUCnt; i++) { @@ -627,7 +651,7 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l GRS_THROW_IF_FAILED(hrOpenSharedHandleResult); } - //7、创建交换链,创建共享堆 + // 6、创建交换链,创建共享堆 { DXGI_SWAP_CHAIN_DESC1 stSwapChainDesc = {}; stSwapChainDesc.BufferCount = g_nFrameBackBufCount; @@ -678,39 +702,47 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l } //创建渲染目标描述符,以及主显卡的渲染目标资源 - CD3DX12_CLEAR_VALUE stClearValue(stSwapChainDesc.Format, v4ClearColor); - stRenderTargetDesc = CD3DX12_RESOURCE_DESC::Tex2D( - stSwapChainDesc.Format, - stSwapChainDesc.Width, - stSwapChainDesc.Height, - 1u, 1u, - stSwapChainDesc.SampleDesc.Count, - stSwapChainDesc.SampleDesc.Quality, - D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET, - D3D12_TEXTURE_LAYOUT_UNKNOWN, 0u); + D3D12_CLEAR_VALUE stClearValue = {}; + stClearValue.Format = stSwapChainDesc.Format; + stClearValue.Color[0] = v4ClearColor[0]; + stClearValue.Color[1] = v4ClearColor[1]; + stClearValue.Color[2] = v4ClearColor[2]; + stClearValue.Color[3] = v4ClearColor[3]; + + stRenderTargetDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + stRenderTargetDesc.Alignment = 0; + stRenderTargetDesc.Format = stSwapChainDesc.Format; + stRenderTargetDesc.Width = stSwapChainDesc.Width; + stRenderTargetDesc.Height = stSwapChainDesc.Height; + stRenderTargetDesc.DepthOrArraySize = 1; + stRenderTargetDesc.MipLevels = 1; + stRenderTargetDesc.SampleDesc.Count = stSwapChainDesc.SampleDesc.Count; + stRenderTargetDesc.SampleDesc.Quality = stSwapChainDesc.SampleDesc.Quality; + stRenderTargetDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + stRenderTargetDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; WCHAR pszDebugName[MAX_PATH] = {}; - CD3DX12_CPU_DESCRIPTOR_HANDLE stRTVHandleMainGPU(stGPU[c_nMainGPU].m_pIRTVHeap->GetCPUDescriptorHandleForHeapStart()); - CD3DX12_CPU_DESCRIPTOR_HANDLE stRTVHandleSecondGPU(stGPU[c_nSecondGPU].m_pIRTVHeap->GetCPUDescriptorHandleForHeapStart()); + D3D12_CPU_DESCRIPTOR_HANDLE stRTVHandleMainGPU = stGPU[c_nMainGPU].m_pIRTVHeap->GetCPUDescriptorHandleForHeapStart(); + D3D12_CPU_DESCRIPTOR_HANDLE stRTVHandleSecondGPU = stGPU[c_nSecondGPU].m_pIRTVHeap->GetCPUDescriptorHandleForHeapStart(); for (UINT j = 0; j < g_nFrameBackBufCount; j++) { //在辅助显卡上输出 GRS_THROW_IF_FAILED(pISwapChain3->GetBuffer(j, IID_PPV_ARGS(&stGPU[c_nSecondGPU].m_pIRTRes[j]))); //在主显卡上创建渲染目标纹理资源 GRS_THROW_IF_FAILED(stGPU[c_nMainGPU].m_pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), - D3D12_HEAP_FLAG_NONE, - &stRenderTargetDesc, - D3D12_RESOURCE_STATE_COMMON, - &stClearValue, - IID_PPV_ARGS(&stGPU[c_nMainGPU].m_pIRTRes[j]))); + &stDefautHeapProps + , D3D12_HEAP_FLAG_NONE + , &stRenderTargetDesc + , D3D12_RESOURCE_STATE_COMMON + , &stClearValue + , IID_PPV_ARGS(&stGPU[c_nMainGPU].m_pIRTRes[j]))); stGPU[c_nMainGPU].m_pID3D12Device4->CreateRenderTargetView(stGPU[c_nMainGPU].m_pIRTRes[j].Get(), nullptr, stRTVHandleMainGPU); - stRTVHandleMainGPU.Offset(1, stGPU[c_nMainGPU].m_nRTVDescriptorSize); + stRTVHandleMainGPU.ptr += stGPU[c_nMainGPU].m_nRTVDescriptorSize; stGPU[c_nSecondGPU].m_pID3D12Device4->CreateRenderTargetView(stGPU[c_nSecondGPU].m_pIRTRes[j].Get(), nullptr, stRTVHandleSecondGPU); - stRTVHandleSecondGPU.Offset(1, stGPU[c_nSecondGPU].m_nRTVDescriptorSize); + stRTVHandleSecondGPU.ptr += stGPU[c_nSecondGPU].m_nRTVDescriptorSize; } for (int i = 0; i < c_nMaxGPUCnt; i++) @@ -724,18 +756,23 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l //使用隐式默认堆创建一个深度蜡板缓冲区, //因为基本上深度缓冲区会一直被使用,重用的意义不大 //所以直接使用隐式堆,图方便 + D3D12_RESOURCE_DESC stDSResDesc = {}; + stDSResDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + stDSResDesc.Alignment = 0; + stDSResDesc.Format = emDSFormat; + stDSResDesc.Width = g_iWndWidth; + stDSResDesc.Height = g_iWndHeight; + stDSResDesc.DepthOrArraySize = 1; + stDSResDesc.MipLevels = 0; + stDSResDesc.SampleDesc.Count = 1; + stDSResDesc.SampleDesc.Quality = 0; + stDSResDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + stDSResDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL; + GRS_THROW_IF_FAILED(stGPU[i].m_pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT) + &stDefautHeapProps , D3D12_HEAP_FLAG_NONE - , &CD3DX12_RESOURCE_DESC::Tex2D( - emDSFormat - , g_iWndWidth - , g_iWndHeight - , 1 - , 0 - , 1 - , 0 - , D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) + , &stDSResDesc , D3D12_RESOURCE_STATE_DEPTH_WRITE , &stDepthOptimizedClearValue , IID_PPV_ARGS(&stGPU[i].m_pIDSRes) @@ -763,22 +800,22 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l for (UINT k = 0; k < c_nPostPassCnt; k++) { - CD3DX12_CPU_DESCRIPTOR_HANDLE stHRTVOffLine(pIRTVOffLine[k]->GetCPUDescriptorHandleForHeapStart()); + D3D12_CPU_DESCRIPTOR_HANDLE stHRTVOffLine = pIRTVOffLine[k]->GetCPUDescriptorHandleForHeapStart(); for (int i = 0; i < g_nFrameBackBufCount; i++) { // Create Second Adapter Off-Line Render Target GRS_THROW_IF_FAILED(stGPU[c_nSecondGPU].m_pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), - D3D12_HEAP_FLAG_NONE, - &stRenderTargetDesc, - D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE, - &stClearValue, - IID_PPV_ARGS(&pIOffLineRTRes[k][i]))); + &stDefautHeapProps + , D3D12_HEAP_FLAG_NONE + , &stRenderTargetDesc + , D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE + , &stClearValue + , IID_PPV_ARGS(&pIOffLineRTRes[k][i]))); GRS_SET_D3D12_DEBUGNAME_INDEXED_COMPTR(pIOffLineRTRes[k], i); // Off-Line Render Target View stGPU[c_nSecondGPU].m_pID3D12Device4->CreateRenderTargetView(pIOffLineRTRes[k][i].Get(), nullptr, stHRTVOffLine); - stHRTVOffLine.Offset(1, stGPU[c_nSecondGPU].m_nRTVDescriptorSize); + stHRTVOffLine.ptr += stGPU[c_nSecondGPU].m_nRTVDescriptorSize; } } @@ -822,19 +859,33 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l //普通资源字节尺寸大小要64k边界对齐 n64szTexture = GRS_UPPER(stResLayout.Footprint.RowPitch * stResLayout.Footprint.Height , D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT); - stCrossAdapterResDesc - = CD3DX12_RESOURCE_DESC::Buffer(n64szTexture, D3D12_RESOURCE_FLAG_ALLOW_CROSS_ADAPTER); + + stCrossAdapterResDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + stCrossAdapterResDesc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; + stCrossAdapterResDesc.Width = n64szTexture; + stCrossAdapterResDesc.Height = 1; + stCrossAdapterResDesc.DepthOrArraySize = 1; + stCrossAdapterResDesc.MipLevels = 1; + stCrossAdapterResDesc.Format = DXGI_FORMAT_UNKNOWN; + stCrossAdapterResDesc.SampleDesc.Count = 1; + stCrossAdapterResDesc.SampleDesc.Quality = 0; + stCrossAdapterResDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + stCrossAdapterResDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_CROSS_ADAPTER; } // 创建跨显卡共享的资源堆 // 这里需要注意的就是,不管怎样,最差情况下两个显卡间至少都支持Buffer类型的资源共享 // 这里可以理解为共享内存总是可以在任意显卡间共享 // 只是最普通的方式是以Buffer形式共享,GPU不能当做纹理来访问 - CD3DX12_HEAP_DESC stCrossHeapDesc( - n64szTexture * g_nFrameBackBufCount, - D3D12_HEAP_TYPE_DEFAULT, - 0, - D3D12_HEAP_FLAG_SHARED | D3D12_HEAP_FLAG_SHARED_CROSS_ADAPTER); + D3D12_HEAP_DESC stCrossHeapDesc = {}; + stCrossHeapDesc.SizeInBytes = n64szTexture * g_nFrameBackBufCount; + stCrossHeapDesc.Alignment = 0; + stCrossHeapDesc.Flags = D3D12_HEAP_FLAG_SHARED | D3D12_HEAP_FLAG_SHARED_CROSS_ADAPTER; + stCrossHeapDesc.Properties.Type = D3D12_HEAP_TYPE_DEFAULT; + stCrossHeapDesc.Properties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + stCrossHeapDesc.Properties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + stCrossHeapDesc.Properties.CreationNodeMask = 0; + stCrossHeapDesc.Properties.VisibleNodeMask = 0; GRS_THROW_IF_FAILED(stGPU[c_nMainGPU].m_pID3D12Device4->CreateHeap(&stCrossHeapDesc , IID_PPV_ARGS(&stGPU[c_nMainGPU].m_pICrossAdapterHeap))); @@ -880,19 +931,22 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l // 如果共享资源仅能共享Buffer形式的资源,那么就在第二个显卡上创建对应的纹理形式的资源 // 并且将主显卡共享过来的Buffer里的渲染结果纹理,复制到第二个显卡的纹理形式的资源上 GRS_THROW_IF_FAILED(stGPU[c_nSecondGPU].m_pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), - D3D12_HEAP_FLAG_NONE, - &stRenderTargetDesc, - D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, - nullptr, - IID_PPV_ARGS(&pISecondaryAdapterTexutrePerFrame[i]))); + &stDefautHeapProps + , D3D12_HEAP_FLAG_NONE + , &stRenderTargetDesc + , D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE + , nullptr + , IID_PPV_ARGS(&pISecondaryAdapterTexutrePerFrame[i]))); } } } + + // 关闭ALT+ENTER键切换全屏的功能,因为我们没有实现OnSize处理,所以先关闭 + GRS_THROW_IF_FAILED(pIDXGIFactory5->MakeWindowAssociation(hWnd, DXGI_MWA_NO_ALT_ENTER)); } - //8、创建根签名 + // 7、创建根签名 { { //First Pass Root Signature //这个例子中,第一遍渲染由主显卡完成,所有物体使用相同的根签名,因为渲染过程中需要的参数是一样的 @@ -908,28 +962,57 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l stFeatureData.HighestVersion = D3D_ROOT_SIGNATURE_VERSION_1_0; } - CD3DX12_DESCRIPTOR_RANGE1 stDSPRanges[3]; - stDSPRanges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0); //1 Const Buffer View - stDSPRanges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0); //1 Texture View - stDSPRanges[2].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 1, 0);// 1 Sampler - - CD3DX12_ROOT_PARAMETER1 stRootParameters[3]; - stRootParameters[0].InitAsDescriptorTable(1, &stDSPRanges[0], D3D12_SHADER_VISIBILITY_ALL); //CBV是所有Shader可见 - stRootParameters[1].InitAsDescriptorTable(1, &stDSPRanges[1], D3D12_SHADER_VISIBILITY_PIXEL);//SRV仅PS可见 - stRootParameters[2].InitAsDescriptorTable(1, &stDSPRanges[2], D3D12_SHADER_VISIBILITY_PIXEL);//SAMPLE仅PS可见 - - CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC stRootSignatureDesc; - stRootSignatureDesc.Init_1_1(_countof(stRootParameters) - , stRootParameters - , 0 - , nullptr - , D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT); + D3D12_DESCRIPTOR_RANGE1 stDSPRanges[3] = {}; + stDSPRanges[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_CBV; + stDSPRanges[0].NumDescriptors = 1; //1 Const Buffer View + stDSPRanges[0].BaseShaderRegister = 0; + stDSPRanges[0].RegisterSpace = 0; + stDSPRanges[0].Flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE; + stDSPRanges[0].OffsetInDescriptorsFromTableStart = 0; + + stDSPRanges[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + stDSPRanges[1].NumDescriptors = 1; //1 Texture View + stDSPRanges[1].BaseShaderRegister = 0; + stDSPRanges[1].RegisterSpace = 0; + stDSPRanges[1].Flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE; + stDSPRanges[1].OffsetInDescriptorsFromTableStart = 0; + + stDSPRanges[2].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER; + stDSPRanges[2].NumDescriptors = 1; // 1 Sampler + stDSPRanges[2].BaseShaderRegister = 0; + stDSPRanges[2].RegisterSpace = 0; + stDSPRanges[2].Flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE; + stDSPRanges[2].OffsetInDescriptorsFromTableStart = 0; + + D3D12_ROOT_PARAMETER1 stRootParameters[3] = {}; + + stRootParameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + stRootParameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;//CBV是所有Shader可见 + stRootParameters[0].DescriptorTable.NumDescriptorRanges = 1; + stRootParameters[0].DescriptorTable.pDescriptorRanges = &stDSPRanges[0]; + + stRootParameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + stRootParameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;//SRV仅PS可见 + stRootParameters[1].DescriptorTable.NumDescriptorRanges = 1; + stRootParameters[1].DescriptorTable.pDescriptorRanges = &stDSPRanges[1]; + + stRootParameters[2].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + stRootParameters[2].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;//SAMPLE仅PS可见 + stRootParameters[2].DescriptorTable.NumDescriptorRanges = 1; + stRootParameters[2].DescriptorTable.pDescriptorRanges = &stDSPRanges[2]; + + D3D12_VERSIONED_ROOT_SIGNATURE_DESC stRootSignatureDesc = {}; + stRootSignatureDesc.Version = D3D_ROOT_SIGNATURE_VERSION_1_1; + stRootSignatureDesc.Desc_1_1.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT; + stRootSignatureDesc.Desc_1_1.NumParameters = _countof(stRootParameters); + stRootSignatureDesc.Desc_1_1.pParameters = stRootParameters; + stRootSignatureDesc.Desc_1_1.NumStaticSamplers = 0; + stRootSignatureDesc.Desc_1_1.pStaticSamplers = nullptr; ComPtr pISignatureBlob; ComPtr pIErrorBlob; - GRS_THROW_IF_FAILED(D3DX12SerializeVersionedRootSignature(&stRootSignatureDesc - , stFeatureData.HighestVersion + GRS_THROW_IF_FAILED(D3D12SerializeVersionedRootSignature(&stRootSignatureDesc , &pISignatureBlob , &pIErrorBlob)); @@ -944,31 +1027,71 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l //Second Pass Root Signature //创建渲染Quad的根签名对象,注意这个根签名在辅助显卡上用 // 因为我们把所有的渲染目标纹理的SRV都创建在了一个SRV堆的连续位置上,实际只使用一个,所以要和Noise Texture分离一下 - CD3DX12_DESCRIPTOR_RANGE1 stDRQuad[4]; - stDRQuad[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0); // 1 Const Buffer - stDRQuad[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0); // 1 Texture - stDRQuad[2].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 1); // 1 Noise Texture - stDRQuad[3].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 1, 0);// 1 Sampler + D3D12_DESCRIPTOR_RANGE1 stDRQuad[4] = {}; + + stDRQuad[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_CBV; + stDRQuad[0].NumDescriptors = 1; //1 Const Buffer View + stDRQuad[0].BaseShaderRegister = 0; + stDRQuad[0].RegisterSpace = 0; + stDRQuad[0].Flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE; + stDRQuad[0].OffsetInDescriptorsFromTableStart = 0; + + stDRQuad[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + stDRQuad[1].NumDescriptors = 1; //1 Texture View + stDRQuad[1].BaseShaderRegister = 0; + stDRQuad[1].RegisterSpace = 0; + stDRQuad[1].Flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE; + stDRQuad[1].OffsetInDescriptorsFromTableStart = 0; + + stDRQuad[2].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + stDRQuad[2].NumDescriptors = 1; // 1 Noise Texture + stDRQuad[2].BaseShaderRegister = 1; + stDRQuad[2].RegisterSpace = 0; + stDRQuad[2].Flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE; + stDRQuad[2].OffsetInDescriptorsFromTableStart = 0; + + stDRQuad[3].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER; + stDRQuad[3].NumDescriptors = 1; // 1 Sampler + stDRQuad[3].BaseShaderRegister = 0; + stDRQuad[3].RegisterSpace = 0; + stDRQuad[3].Flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE; + stDRQuad[3].OffsetInDescriptorsFromTableStart = 0; //后处理其实就是图像处理,所以资源仅设定Pixel Shader可见 - CD3DX12_ROOT_PARAMETER1 stRPQuad[4]; - stRPQuad[0].InitAsDescriptorTable(1, &stDRQuad[0], D3D12_SHADER_VISIBILITY_PIXEL);//CBV仅PS可见 - stRPQuad[1].InitAsDescriptorTable(1, &stDRQuad[1], D3D12_SHADER_VISIBILITY_PIXEL);//SRV仅PS可见 - stRPQuad[2].InitAsDescriptorTable(1, &stDRQuad[2], D3D12_SHADER_VISIBILITY_PIXEL);//SAMPLE仅PS可见 - stRPQuad[3].InitAsDescriptorTable(1, &stDRQuad[3], D3D12_SHADER_VISIBILITY_PIXEL);//SAMPLE仅PS可见 - - CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC stRSQuadDesc; - stRSQuadDesc.Init_1_1(_countof(stRPQuad) - , stRPQuad - , 0 - , nullptr - , D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT); + D3D12_ROOT_PARAMETER1 stRPQuad[4] = {}; + stRPQuad[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + stRPQuad[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;//CBV仅PS可见 + stRPQuad[0].DescriptorTable.NumDescriptorRanges = 1; + stRPQuad[0].DescriptorTable.pDescriptorRanges = &stDRQuad[0]; + + stRPQuad[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + stRPQuad[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;//SRV仅PS可见 + stRPQuad[1].DescriptorTable.NumDescriptorRanges = 1; + stRPQuad[1].DescriptorTable.pDescriptorRanges = &stDRQuad[1]; + + stRPQuad[2].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + stRPQuad[2].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;//SRV仅PS可见 + stRPQuad[2].DescriptorTable.NumDescriptorRanges = 1; + stRPQuad[2].DescriptorTable.pDescriptorRanges = &stDRQuad[2]; + + + stRPQuad[3].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + stRPQuad[3].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;//SAMPLE仅PS可见 + stRPQuad[3].DescriptorTable.NumDescriptorRanges = 1; + stRPQuad[3].DescriptorTable.pDescriptorRanges = &stDRQuad[3]; + + D3D12_VERSIONED_ROOT_SIGNATURE_DESC stRSQuadDesc = {}; + stRSQuadDesc.Version = D3D_ROOT_SIGNATURE_VERSION_1_1; + stRSQuadDesc.Desc_1_1.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT; + stRSQuadDesc.Desc_1_1.NumParameters = _countof(stRPQuad); + stRSQuadDesc.Desc_1_1.pParameters = stRPQuad; + stRSQuadDesc.Desc_1_1.NumStaticSamplers = 0; + stRSQuadDesc.Desc_1_1.pStaticSamplers = nullptr; pISignatureBlob.Reset(); pIErrorBlob.Reset(); - GRS_THROW_IF_FAILED(D3DX12SerializeVersionedRootSignature(&stRSQuadDesc - , stFeatureData.HighestVersion + GRS_THROW_IF_FAILED(D3D12SerializeVersionedRootSignature(&stRSQuadDesc , &pISignatureBlob , &pIErrorBlob)); @@ -982,26 +1105,44 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l //----------------------------------------------------------------------------------------------------- // Create Third Pass Root Signature - CD3DX12_DESCRIPTOR_RANGE1 stDRThridPass[2]; - stDRThridPass[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0); - stDRThridPass[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 1, 0); - - CD3DX12_ROOT_PARAMETER1 stRPThirdPass[2]; - stRPThirdPass[0].InitAsDescriptorTable(1, &stDRThridPass[0], D3D12_SHADER_VISIBILITY_PIXEL); //CBV所有Shader可见 - stRPThirdPass[1].InitAsDescriptorTable(1, &stDRThridPass[1], D3D12_SHADER_VISIBILITY_PIXEL); //SRV仅PS可见 - - CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC stRSThirdPass; - stRSThirdPass.Init_1_1(_countof(stRPThirdPass) - , stRPThirdPass - , 0 - , nullptr - , D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT); + D3D12_DESCRIPTOR_RANGE1 stDRThridPass[2] = {}; + stDRThridPass[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + stDRThridPass[0].NumDescriptors = 1; // 1 Noise Texture + stDRThridPass[0].BaseShaderRegister = 0; + stDRThridPass[0].RegisterSpace = 0; + stDRThridPass[0].Flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE; + stDRThridPass[0].OffsetInDescriptorsFromTableStart = 0; + + stDRThridPass[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER; + stDRThridPass[1].NumDescriptors = 1; // 1 Sampler + stDRThridPass[1].BaseShaderRegister = 0; + stDRThridPass[1].RegisterSpace = 0; + stDRThridPass[1].Flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE; + stDRThridPass[1].OffsetInDescriptorsFromTableStart = 0; + + D3D12_ROOT_PARAMETER1 stRPThirdPass[2] = {}; + stRPThirdPass[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + stRPThirdPass[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;//SRV仅PS可见 + stRPThirdPass[0].DescriptorTable.NumDescriptorRanges = 1; + stRPThirdPass[0].DescriptorTable.pDescriptorRanges = &stDRThridPass[0]; + + stRPThirdPass[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + stRPThirdPass[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;//Sample仅PS可见 + stRPThirdPass[1].DescriptorTable.NumDescriptorRanges = 1; + stRPThirdPass[1].DescriptorTable.pDescriptorRanges = &stDRThridPass[1]; + + D3D12_VERSIONED_ROOT_SIGNATURE_DESC stRSThirdPass = {}; + stRSThirdPass.Version = D3D_ROOT_SIGNATURE_VERSION_1_1; + stRSThirdPass.Desc_1_1.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT; + stRSThirdPass.Desc_1_1.NumParameters = _countof(stRPThirdPass); + stRSThirdPass.Desc_1_1.pParameters = stRPThirdPass; + stRSThirdPass.Desc_1_1.NumStaticSamplers = 0; + stRSThirdPass.Desc_1_1.pStaticSamplers = nullptr; pISignatureBlob.Reset(); pIErrorBlob.Reset(); - GRS_THROW_IF_FAILED(D3DX12SerializeVersionedRootSignature(&stRSThirdPass - , stFeatureData.HighestVersion + GRS_THROW_IF_FAILED(D3D12SerializeVersionedRootSignature(&stRSThirdPass , &pISignatureBlob , &pIErrorBlob)); @@ -1014,352 +1155,448 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l }} //9、编译Shader创建渲染管线状态对象 - {{ + { { #if defined(_DEBUG) - // Enable better shader debugging with the graphics debugging tools. - UINT nShaderCompileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; + // Enable better shader debugging with the graphics debugging tools. + UINT nShaderCompileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; #else - UINT nShaderCompileFlags = 0; + UINT nShaderCompileFlags = 0; #endif - //编译为行矩阵形式 - nShaderCompileFlags |= D3DCOMPILE_PACK_MATRIX_ROW_MAJOR; - - TCHAR pszShaderFileName[MAX_PATH] = {}; + //编译为行矩阵形式 + nShaderCompileFlags |= D3DCOMPILE_PACK_MATRIX_ROW_MAJOR; - ComPtr pIVSCode; - ComPtr pIPSCode; - ComPtr pIErrMsg; - CHAR pszErrMsg[MAX_PATH] = {}; - HRESULT hr = S_OK; + TCHAR pszShaderFileName[MAX_PATH] = {}; - StringCchPrintf(pszShaderFileName - , MAX_PATH - , _T("%s11-MultiThreadAndAdapter\\Shader\\11-MultiThreadAndAdapter.hlsl") - , g_pszAppPath); + ComPtr pIVSCode; + ComPtr pIPSCode; + ComPtr pIErrMsg; + CHAR pszErrMsg[MAX_PATH] = {}; + HRESULT hr = S_OK; - hr = D3DCompileFromFile(pszShaderFileName, nullptr, nullptr - , "VSMain", "vs_5_0", nShaderCompileFlags, 0, &pIVSCode, &pIErrMsg); - if (FAILED(hr)) - { - StringCchPrintfA(pszErrMsg + StringCchPrintf(pszShaderFileName , MAX_PATH - , "\n%s\n" - , (CHAR*)pIErrMsg->GetBufferPointer()); - ::OutputDebugStringA(pszErrMsg); - throw CGRSCOMException(hr); - } + , _T("%s11-MultiThreadAndAdapter\\Shader\\11-MultiThreadAndAdapter.hlsl") + , g_pszAppPath); - pIErrMsg.Reset(); + hr = D3DCompileFromFile(pszShaderFileName, nullptr, nullptr + , "VSMain", "vs_5_0", nShaderCompileFlags, 0, &pIVSCode, &pIErrMsg); + if (FAILED(hr)) + { + StringCchPrintfA(pszErrMsg + , MAX_PATH + , "\n%s\n" + , (CHAR*)pIErrMsg->GetBufferPointer()); + ::OutputDebugStringA(pszErrMsg); + throw CGRSCOMException(hr); + } - hr = D3DCompileFromFile(pszShaderFileName, nullptr, nullptr - , "PSMain", "ps_5_0", nShaderCompileFlags, 0, &pIPSCode, &pIErrMsg); - if (FAILED(hr)) - { - StringCchPrintfA(pszErrMsg - , MAX_PATH - , "\n%s\n" - , (CHAR*)pIErrMsg->GetBufferPointer()); - ::OutputDebugStringA(pszErrMsg); - throw CGRSCOMException(hr); - } + pIErrMsg.Reset(); - // 我们多添加了一个法线的定义,但目前Shader中我们并没有使用 - D3D12_INPUT_ELEMENT_DESC stIALayoutSphere[] = - { - { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, - { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 16, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, - { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 24, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 } - }; + hr = D3DCompileFromFile(pszShaderFileName, nullptr, nullptr + , "PSMain", "ps_5_0", nShaderCompileFlags, 0, &pIPSCode, &pIErrMsg); + if (FAILED(hr)) + { + StringCchPrintfA(pszErrMsg + , MAX_PATH + , "\n%s\n" + , (CHAR*)pIErrMsg->GetBufferPointer()); + ::OutputDebugStringA(pszErrMsg); + throw CGRSCOMException(hr); + } - // 创建 graphics pipeline state object (PSO)对象 - D3D12_GRAPHICS_PIPELINE_STATE_DESC stPSODesc = {}; - stPSODesc.InputLayout = { stIALayoutSphere, _countof(stIALayoutSphere) }; - stPSODesc.pRootSignature = stGPU[c_nMainGPU].m_pIRS.Get(); - stPSODesc.VS = CD3DX12_SHADER_BYTECODE(pIVSCode.Get()); - stPSODesc.PS = CD3DX12_SHADER_BYTECODE(pIPSCode.Get()); - stPSODesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT); - stPSODesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT); - stPSODesc.SampleMask = UINT_MAX; - stPSODesc.SampleDesc.Count = 1; - stPSODesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; - stPSODesc.NumRenderTargets = 1; - stPSODesc.RTVFormats[0] = emRTFormat; - stPSODesc.DSVFormat = emDSFormat; - stPSODesc.DepthStencilState.StencilEnable = FALSE; - stPSODesc.DepthStencilState.DepthEnable = TRUE; //打开深度缓冲 - stPSODesc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL;//启用深度缓存写入功能 - stPSODesc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_LESS; //深度测试函数(该值为普通的深度测试,即较小值写入) + // 我们多添加了一个法线的定义,但目前Shader中我们并没有使用 + D3D12_INPUT_ELEMENT_DESC stIALayoutSphere[] = + { + { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 16, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 24, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 } + }; + + // 创建 graphics pipeline state object (PSO)对象 + D3D12_GRAPHICS_PIPELINE_STATE_DESC stPSODesc = {}; + stPSODesc.InputLayout = { stIALayoutSphere, _countof(stIALayoutSphere) }; + stPSODesc.pRootSignature = stGPU[c_nMainGPU].m_pIRS.Get(); + stPSODesc.VS.BytecodeLength = pIVSCode->GetBufferSize(); + stPSODesc.VS.pShaderBytecode = pIVSCode->GetBufferPointer(); + stPSODesc.PS.BytecodeLength = pIPSCode->GetBufferSize(); + stPSODesc.PS.pShaderBytecode = pIPSCode->GetBufferPointer(); + + stPSODesc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID; + stPSODesc.RasterizerState.CullMode = D3D12_CULL_MODE_BACK; + + stPSODesc.BlendState.AlphaToCoverageEnable = FALSE; + stPSODesc.BlendState.IndependentBlendEnable = FALSE; + stPSODesc.BlendState.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL; + + stPSODesc.SampleMask = UINT_MAX; + stPSODesc.SampleDesc.Count = 1; + stPSODesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + stPSODesc.NumRenderTargets = 1; + stPSODesc.RTVFormats[0] = emRTFormat; + stPSODesc.DSVFormat = emDSFormat; + stPSODesc.DepthStencilState.StencilEnable = FALSE; + stPSODesc.DepthStencilState.DepthEnable = TRUE; //打开深度缓冲 + stPSODesc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL;//启用深度缓存写入功能 + stPSODesc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_LESS; //深度测试函数(该值为普通的深度测试,即较小值写入) - GRS_THROW_IF_FAILED( - stGPU[c_nMainGPU].m_pID3D12Device4->CreateGraphicsPipelineState( - &stPSODesc - , IID_PPV_ARGS(&stGPU[c_nMainGPU].m_pIPSO))); + GRS_THROW_IF_FAILED( + stGPU[c_nMainGPU].m_pID3D12Device4->CreateGraphicsPipelineState( + &stPSODesc + , IID_PPV_ARGS(&stGPU[c_nMainGPU].m_pIPSO))); - GRS_SET_D3D12_DEBUGNAME_COMPTR(stGPU[c_nMainGPU].m_pIPSO); + GRS_SET_D3D12_DEBUGNAME_COMPTR(stGPU[c_nMainGPU].m_pIPSO); - // Second Pass Pipeline State Object - // 用于渲染单位矩形的管道状态对象,在本例中是后处理 - StringCchPrintf(pszShaderFileName, MAX_PATH, _T("%s11-MultiThreadAndAdapter\\Shader\\11-QuadVS.hlsl"), g_pszAppPath); + // Second Pass Pipeline State Object + // 用于渲染单位矩形的管道状态对象,在本例中是后处理 + StringCchPrintf(pszShaderFileName, MAX_PATH, _T("%s11-MultiThreadAndAdapter\\Shader\\11-QuadVS.hlsl"), g_pszAppPath); - pIVSCode.Reset(); - pIPSCode.Reset(); - pIErrMsg.Reset(); + pIVSCode.Reset(); + pIPSCode.Reset(); + pIErrMsg.Reset(); - hr = D3DCompileFromFile(pszShaderFileName, nullptr, nullptr - , "VSMain", "vs_5_0", nShaderCompileFlags, 0, &pIVSCode, &pIErrMsg); - if (FAILED(hr)) - { - if (nullptr != pIErrMsg) + hr = D3DCompileFromFile(pszShaderFileName, nullptr, nullptr + , "VSMain", "vs_5_0", nShaderCompileFlags, 0, &pIVSCode, &pIErrMsg); + if (FAILED(hr)) { - StringCchPrintfA(pszErrMsg, MAX_PATH, "\n%s\n", (CHAR*)pIErrMsg->GetBufferPointer()); - ::OutputDebugStringA(pszErrMsg); + if (nullptr != pIErrMsg) + { + StringCchPrintfA(pszErrMsg, MAX_PATH, "\n%s\n", (CHAR*)pIErrMsg->GetBufferPointer()); + ::OutputDebugStringA(pszErrMsg); + } + throw CGRSCOMException(hr); } - throw CGRSCOMException(hr); - } - pIErrMsg.Reset(); - StringCchPrintf(pszShaderFileName, MAX_PATH - , _T("%s11-MultiThreadAndAdapter\\Shader\\11-WaterColourPS.hlsl") - , g_pszAppPath); + pIErrMsg.Reset(); + StringCchPrintf(pszShaderFileName, MAX_PATH + , _T("%s11-MultiThreadAndAdapter\\Shader\\11-WaterColourPS.hlsl") + , g_pszAppPath); - hr = D3DCompileFromFile(pszShaderFileName, nullptr, nullptr - , "PSMain", "ps_5_0", nShaderCompileFlags, 0, &pIPSCode, &pIErrMsg); - if (FAILED(hr)) - { - if (nullptr != pIErrMsg) + hr = D3DCompileFromFile(pszShaderFileName, nullptr, nullptr + , "PSMain", "ps_5_0", nShaderCompileFlags, 0, &pIPSCode, &pIErrMsg); + if (FAILED(hr)) { - StringCchPrintfA(pszErrMsg, MAX_PATH, "\n%s\n", (CHAR*)pIErrMsg->GetBufferPointer()); - ::OutputDebugStringA(pszErrMsg); + if (nullptr != pIErrMsg) + { + StringCchPrintfA(pszErrMsg, MAX_PATH, "\n%s\n", (CHAR*)pIErrMsg->GetBufferPointer()); + ::OutputDebugStringA(pszErrMsg); + } + throw CGRSCOMException(hr); } - throw CGRSCOMException(hr); - } - // 我们多添加了一个法线的定义,但目前Shader中我们并没有使用 - D3D12_INPUT_ELEMENT_DESC stIALayoutQuad[] = - { - { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, - { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 16, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 } - }; + // 我们多添加了一个法线的定义,但目前Shader中我们并没有使用 + D3D12_INPUT_ELEMENT_DESC stIALayoutQuad[] = + { + { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 16, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 } + }; + + // 创建 graphics pipeline state object (PSO)对象 + D3D12_GRAPHICS_PIPELINE_STATE_DESC stPSOQuadDesc = {}; + stPSOQuadDesc.InputLayout = { stIALayoutQuad, _countof(stIALayoutQuad) }; + stPSOQuadDesc.pRootSignature = stGPU[c_nSecondGPU].m_pIRS.Get(); + stPSOQuadDesc.VS.BytecodeLength = pIVSCode->GetBufferSize(); + stPSOQuadDesc.VS.pShaderBytecode = pIVSCode->GetBufferPointer(); + stPSOQuadDesc.PS.BytecodeLength = pIPSCode->GetBufferSize(); + stPSOQuadDesc.PS.pShaderBytecode = pIPSCode->GetBufferPointer(); + + stPSOQuadDesc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID; + stPSOQuadDesc.RasterizerState.CullMode = D3D12_CULL_MODE_BACK; + + stPSOQuadDesc.BlendState.AlphaToCoverageEnable = FALSE; + stPSOQuadDesc.BlendState.IndependentBlendEnable = FALSE; + stPSOQuadDesc.BlendState.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL; + + stPSOQuadDesc.SampleMask = UINT_MAX; + stPSOQuadDesc.SampleDesc.Count = 1; + stPSOQuadDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + stPSOQuadDesc.NumRenderTargets = 1; + stPSOQuadDesc.RTVFormats[0] = emRTFormat; + stPSOQuadDesc.DepthStencilState.StencilEnable = FALSE; + stPSOQuadDesc.DepthStencilState.DepthEnable = FALSE; - // 创建 graphics pipeline state object (PSO)对象 - D3D12_GRAPHICS_PIPELINE_STATE_DESC stPSOQuadDesc = {}; - stPSOQuadDesc.InputLayout = { stIALayoutQuad, _countof(stIALayoutQuad) }; - stPSOQuadDesc.pRootSignature = stGPU[c_nSecondGPU].m_pIRS.Get(); - stPSOQuadDesc.VS = CD3DX12_SHADER_BYTECODE(pIVSCode.Get()); - stPSOQuadDesc.PS = CD3DX12_SHADER_BYTECODE(pIPSCode.Get()); - stPSOQuadDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT); - stPSOQuadDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT); - stPSOQuadDesc.SampleMask = UINT_MAX; - stPSOQuadDesc.SampleDesc.Count = 1; - stPSOQuadDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; - stPSOQuadDesc.NumRenderTargets = 1; - stPSOQuadDesc.RTVFormats[0] = emRTFormat; - stPSOQuadDesc.DepthStencilState.StencilEnable = FALSE; - stPSOQuadDesc.DepthStencilState.DepthEnable = FALSE; + GRS_THROW_IF_FAILED( + stGPU[c_nSecondGPU].m_pID3D12Device4->CreateGraphicsPipelineState( + &stPSOQuadDesc + , IID_PPV_ARGS(&stGPU[c_nSecondGPU].m_pIPSO))); + GRS_SET_D3D12_DEBUGNAME_COMPTR(stGPU[c_nSecondGPU].m_pIPSO); - GRS_THROW_IF_FAILED( - stGPU[c_nSecondGPU].m_pID3D12Device4->CreateGraphicsPipelineState( - &stPSOQuadDesc - , IID_PPV_ARGS(&stGPU[c_nSecondGPU].m_pIPSO))); - GRS_SET_D3D12_DEBUGNAME_COMPTR(stGPU[c_nSecondGPU].m_pIPSO); + //--------------------------------------------------------------------------------------------------- + // Create Gaussian blur in the vertical direction PSO + pIPSCode.Reset(); + pIErrMsg.Reset(); + + StringCchPrintf(pszShaderFileName + , MAX_PATH + , _T("%s11-MultiThreadAndAdapter\\Shader\\11-GaussianBlurPS.hlsl") + , g_pszAppPath); - //--------------------------------------------------------------------------------------------------- - // Create Gaussian blur in the vertical direction PSO - pIPSCode.Reset(); - pIErrMsg.Reset(); + //后处理渲染,只编译PS就可以了,VS就用之前的QuadVS即可,都是后处理主要玩PS + hr = D3DCompileFromFile(pszShaderFileName, nullptr, nullptr + , "PSSimpleBlurV", "ps_5_0", nShaderCompileFlags, 0, &pIPSCode, &pIErrMsg); + if (FAILED(hr)) + { + if (nullptr != pIErrMsg) + { + StringCchPrintfA(pszErrMsg, MAX_PATH, "\n%s\n", (CHAR*)pIErrMsg->GetBufferPointer()); + ::OutputDebugStringA(pszErrMsg); + } + throw CGRSCOMException(hr); + } - StringCchPrintf(pszShaderFileName - , MAX_PATH - , _T("%s11-MultiThreadAndAdapter\\Shader\\11-GaussianBlurPS.hlsl") - , g_pszAppPath); + // 创建 graphics pipeline state object (PSO)对象 + D3D12_GRAPHICS_PIPELINE_STATE_DESC stPSOThirdPassDesc = {}; + stPSOThirdPassDesc.InputLayout = { stIALayoutQuad, _countof(stIALayoutQuad) }; + stPSOThirdPassDesc.pRootSignature = pIRSPostPass.Get(); + stPSOThirdPassDesc.VS.BytecodeLength = pIVSCode->GetBufferSize(); + stPSOThirdPassDesc.VS.pShaderBytecode = pIVSCode->GetBufferPointer(); + stPSOThirdPassDesc.PS.BytecodeLength = pIPSCode->GetBufferSize(); + stPSOThirdPassDesc.PS.pShaderBytecode = pIPSCode->GetBufferPointer(); + + stPSOThirdPassDesc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID; + stPSOThirdPassDesc.RasterizerState.CullMode = D3D12_CULL_MODE_BACK; + + stPSOThirdPassDesc.BlendState.AlphaToCoverageEnable = FALSE; + stPSOThirdPassDesc.BlendState.IndependentBlendEnable = FALSE; + stPSOThirdPassDesc.BlendState.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL; + + stPSOThirdPassDesc.SampleMask = UINT_MAX; + stPSOThirdPassDesc.SampleDesc.Count = 1; + stPSOThirdPassDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + stPSOThirdPassDesc.NumRenderTargets = 1; + stPSOThirdPassDesc.RTVFormats[0] = emRTFormat; + stPSOThirdPassDesc.DepthStencilState.StencilEnable = FALSE; + stPSOThirdPassDesc.DepthStencilState.DepthEnable = FALSE; - //后处理渲染,只编译PS就可以了,VS就用之前的QuadVS即可,都是后处理主要玩PS - hr = D3DCompileFromFile(pszShaderFileName, nullptr, nullptr - , "PSSimpleBlurV", "ps_5_0", nShaderCompileFlags, 0, &pIPSCode, &pIErrMsg); - if (FAILED(hr)) - { - if (nullptr != pIErrMsg) + GRS_THROW_IF_FAILED( + stGPU[c_nSecondGPU].m_pID3D12Device4->CreateGraphicsPipelineState( + &stPSOThirdPassDesc + , IID_PPV_ARGS(&pIPSOPostPass[c_nPostPass0]))); + GRS_SET_D3D12_DEBUGNAME_COMPTR(pIPSOPostPass[c_nPostPass0]); + + // Create Gaussian blur in the horizontal direction PSO + pIPSCode.Reset(); + pIErrMsg.Reset(); + + //后处理渲染,只编译PS就可以了,VS就用之前的QuadVS即可,都是后处理主要玩PS + hr = D3DCompileFromFile(pszShaderFileName, nullptr, nullptr + , "PSSimpleBlurU", "ps_5_0", nShaderCompileFlags, 0, &pIPSCode, &pIErrMsg); + if (FAILED(hr)) { - StringCchPrintfA(pszErrMsg, MAX_PATH, "\n%s\n", (CHAR*)pIErrMsg->GetBufferPointer()); - ::OutputDebugStringA(pszErrMsg); + if (nullptr != pIErrMsg) + { + StringCchPrintfA(pszErrMsg, MAX_PATH, "\n%s\n", (CHAR*)pIErrMsg->GetBufferPointer()); + ::OutputDebugStringA(pszErrMsg); + } + throw CGRSCOMException(hr); } - throw CGRSCOMException(hr); - } - // 创建 graphics pipeline state object (PSO)对象 - D3D12_GRAPHICS_PIPELINE_STATE_DESC stPSOThirdPassDesc = {}; - stPSOThirdPassDesc.InputLayout = { stIALayoutQuad, _countof(stIALayoutQuad) }; - stPSOThirdPassDesc.pRootSignature = pIRSPostPass.Get(); - stPSOThirdPassDesc.VS = CD3DX12_SHADER_BYTECODE(pIVSCode.Get()); - stPSOThirdPassDesc.PS = CD3DX12_SHADER_BYTECODE(pIPSCode.Get()); - stPSOThirdPassDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT); - stPSOThirdPassDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT); - stPSOThirdPassDesc.SampleMask = UINT_MAX; - stPSOThirdPassDesc.SampleDesc.Count = 1; - stPSOThirdPassDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; - stPSOThirdPassDesc.NumRenderTargets = 1; - stPSOThirdPassDesc.RTVFormats[0] = emRTFormat; - stPSOThirdPassDesc.DepthStencilState.StencilEnable = FALSE; - stPSOThirdPassDesc.DepthStencilState.DepthEnable = FALSE; + stPSOThirdPassDesc.PS.BytecodeLength = pIPSCode->GetBufferSize(); + stPSOThirdPassDesc.PS.pShaderBytecode = pIPSCode->GetBufferPointer(); - GRS_THROW_IF_FAILED( - stGPU[c_nSecondGPU].m_pID3D12Device4->CreateGraphicsPipelineState( - &stPSOThirdPassDesc - , IID_PPV_ARGS(&pIPSOPostPass[c_nPostPass0]))); - GRS_SET_D3D12_DEBUGNAME_COMPTR(pIPSOPostPass[c_nPostPass0]); - - // Create Gaussian blur in the horizontal direction PSO - pIPSCode.Reset(); - pIErrMsg.Reset(); - - //后处理渲染,只编译PS就可以了,VS就用之前的QuadVS即可,都是后处理主要玩PS - hr = D3DCompileFromFile(pszShaderFileName, nullptr, nullptr - , "PSSimpleBlurU", "ps_5_0", nShaderCompileFlags, 0, &pIPSCode, &pIErrMsg); - if (FAILED(hr)) - { - if (nullptr != pIErrMsg) + GRS_THROW_IF_FAILED( + stGPU[c_nSecondGPU].m_pID3D12Device4->CreateGraphicsPipelineState( + &stPSOThirdPassDesc + , IID_PPV_ARGS(&pIPSOPostPass[c_nPostPass1]))); + GRS_SET_D3D12_DEBUGNAME_COMPTR(pIPSOPostPass[c_nPostPass1]); + //--------------------------------------------------------------------------------------------------- + }} + + //10、准备参数并启动多个渲染线程 + { { + USES_CONVERSION; + // 球体个性参数 + StringCchPrintf(g_stThread[g_nThdSphere].m_pszDDSFile, MAX_PATH, _T("%sAssets\\Earth_512.dds"), g_pszAppPath); + StringCchPrintfA(g_stThread[g_nThdSphere].m_pszMeshFile, MAX_PATH, "%sAssets\\sphere.txt", T2A(g_pszAppPath)); + g_stThread[g_nThdSphere].m_v4ModelPos = XMFLOAT4(2.0f, 2.0f, 0.0f, 1.0f); + + // 立方体个性参数 + StringCchPrintf(g_stThread[g_nThdCube].m_pszDDSFile, MAX_PATH, _T("%sAssets\\Cube.dds"), g_pszAppPath); + StringCchPrintfA(g_stThread[g_nThdCube].m_pszMeshFile, MAX_PATH, "%sAssets\\Cube.txt", T2A(g_pszAppPath)); + g_stThread[g_nThdCube].m_v4ModelPos = XMFLOAT4(-2.0f, 2.0f, 0.0f, 1.0f); + + // 平板个性参数 + StringCchPrintf(g_stThread[g_nThdPlane].m_pszDDSFile, MAX_PATH, _T("%sAssets\\Plane.dds"), g_pszAppPath); + StringCchPrintfA(g_stThread[g_nThdPlane].m_pszMeshFile, MAX_PATH, "%sAssets\\Plane.txt", T2A(g_pszAppPath)); + g_stThread[g_nThdPlane].m_v4ModelPos = XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f); + + // 多线程渲染时,第一遍渲染主要在主显卡上完成,所以为每个线程创建主显卡关联的命令列表 + // 物体的共性参数,也就是各线程的共性参数 + for (int i = 0; i < g_nMaxThread; i++) { - StringCchPrintfA(pszErrMsg, MAX_PATH, "\n%s\n", (CHAR*)pIErrMsg->GetBufferPointer()); - ::OutputDebugStringA(pszErrMsg); + g_stThread[i].m_nThreadIndex = i; //记录序号 + + //创建每个线程需要的命令列表和复制命令队列 + GRS_THROW_IF_FAILED( + stGPU[c_nMainGPU].m_pID3D12Device4->CreateCommandAllocator( + D3D12_COMMAND_LIST_TYPE_DIRECT + , IID_PPV_ARGS(&g_stThread[i].m_pICMDAlloc))); + GRS_SetD3D12DebugNameIndexed(g_stThread[i].m_pICMDAlloc, _T("pIThreadCmdAlloc"), i); + + GRS_THROW_IF_FAILED( + stGPU[c_nMainGPU].m_pID3D12Device4->CreateCommandList( + 0, D3D12_COMMAND_LIST_TYPE_DIRECT + , g_stThread[i].m_pICMDAlloc + , nullptr + , IID_PPV_ARGS(&g_stThread[i].m_pICMDList))); + GRS_SetD3D12DebugNameIndexed(g_stThread[i].m_pICMDList, _T("pIThreadCmdList"), i); + + g_stThread[i].m_dwMainThreadID = ::GetCurrentThreadId(); + g_stThread[i].m_hMainThread = ::GetCurrentThread(); + g_stThread[i].m_hEventRun = ::CreateEvent(nullptr, FALSE, FALSE, nullptr); + g_stThread[i].m_hEventRenderOver = ::CreateEvent(nullptr, FALSE, FALSE, nullptr); + g_stThread[i].m_pID3D12Device4 = stGPU[c_nMainGPU].m_pID3D12Device4.Get(); + g_stThread[i].m_pIRTVHeap = stGPU[c_nMainGPU].m_pIRTVHeap.Get(); + g_stThread[i].m_pIDSVHeap = stGPU[c_nMainGPU].m_pIDSVHeap.Get(); + g_stThread[i].m_pIRS = stGPU[c_nMainGPU].m_pIRS.Get(); + g_stThread[i].m_pIPSO = stGPU[c_nMainGPU].m_pIPSO.Get(); + + arHWaited.Add(g_stThread[i].m_hEventRenderOver); //添加到被等待队列里 + + //以暂停方式创建线程 + g_stThread[i].m_hThisThread = (HANDLE)_beginthreadex(nullptr, + 0, RenderThread, (void*)&g_stThread[i], + CREATE_SUSPENDED, (UINT*)&g_stThread[i].m_dwThisThreadID); + + //然后判断线程创建是否成功 + if (nullptr == g_stThread[i].m_hThisThread + || reinterpret_cast(-1) == g_stThread[i].m_hThisThread) + { + throw CGRSCOMException(HRESULT_FROM_WIN32(GetLastError())); + } + + arHSubThread.Add(g_stThread[i].m_hThisThread); } - throw CGRSCOMException(hr); - } - stPSOThirdPassDesc.PS = CD3DX12_SHADER_BYTECODE(pIPSCode.Get()); + //逐一启动线程 + for (int i = 0; i < g_nMaxThread; i++) + { + ::ResumeThread(g_stThread[i].m_hThisThread); + } + }} + + //11、加载DDS噪声纹理,注意用于后处理,所以加载到第二个显卡上 + { + TCHAR pszNoiseTexture[MAX_PATH] = {}; + StringCchPrintf(pszNoiseTexture, MAX_PATH, _T("%sAssets\\GaussianNoise256.dds"), g_pszAppPath); + std::unique_ptr pbDDSData; + std::vector stArSubResources; + DDS_ALPHA_MODE emAlphaMode = DDS_ALPHA_MODE_UNKNOWN; + bool bIsCube = false; + + GRS_THROW_IF_FAILED(LoadDDSTextureFromFile( + stGPU[c_nSecondGPU].m_pID3D12Device4.Get() + , pszNoiseTexture + , pINoiseTexture.GetAddressOf() + , pbDDSData + , stArSubResources + , SIZE_MAX + , &emAlphaMode + , &bIsCube)); + GRS_SET_D3D12_DEBUGNAME_COMPTR(pINoiseTexture); + + D3D12_RESOURCE_DESC stTXDesc = pINoiseTexture->GetDesc(); + UINT64 n64szUpSphere = 0; + stGPU[c_nSecondGPU].m_pID3D12Device4->GetCopyableFootprints(&stTXDesc, 0, static_cast(stArSubResources.size()) + , 0, nullptr, nullptr, nullptr, &n64szUpSphere); + stBufferResSesc.Width = n64szUpSphere; GRS_THROW_IF_FAILED( - stGPU[c_nSecondGPU].m_pID3D12Device4->CreateGraphicsPipelineState( - &stPSOThirdPassDesc - , IID_PPV_ARGS(&pIPSOPostPass[c_nPostPass1]))); - GRS_SET_D3D12_DEBUGNAME_COMPTR(pIPSOPostPass[c_nPostPass1]); - //--------------------------------------------------------------------------------------------------- - }} + stGPU[c_nSecondGPU].m_pID3D12Device4->CreateCommittedResource( + &stUploadHeapProps + , D3D12_HEAP_FLAG_NONE + , &stBufferResSesc + , D3D12_RESOURCE_STATE_GENERIC_READ + , nullptr + , IID_PPV_ARGS(&pINoiseTextureUpload))); + GRS_SET_D3D12_DEBUGNAME_COMPTR(pINoiseTextureUpload); - //10、准备参数并启动多个渲染线程 - {{ - USES_CONVERSION; - // 球体个性参数 - StringCchPrintf(g_stThread[g_nThdSphere].m_pszDDSFile, MAX_PATH, _T("%sAssets\\Earth_512.dds"), g_pszAppPath); - StringCchPrintfA(g_stThread[g_nThdSphere].m_pszMeshFile, MAX_PATH, "%sAssets\\sphere.txt", T2A(g_pszAppPath)); - g_stThread[g_nThdSphere].m_v4ModelPos = XMFLOAT4(2.0f, 2.0f, 0.0f, 1.0f); - - // 立方体个性参数 - StringCchPrintf(g_stThread[g_nThdCube].m_pszDDSFile, MAX_PATH, _T("%sAssets\\Cube.dds"), g_pszAppPath); - StringCchPrintfA(g_stThread[g_nThdCube].m_pszMeshFile, MAX_PATH, "%sAssets\\Cube.txt", T2A(g_pszAppPath)); - g_stThread[g_nThdCube].m_v4ModelPos = XMFLOAT4(-2.0f, 2.0f, 0.0f, 1.0f); - - // 平板个性参数 - StringCchPrintf(g_stThread[g_nThdPlane].m_pszDDSFile, MAX_PATH, _T("%sAssets\\Plane.dds"), g_pszAppPath); - StringCchPrintfA(g_stThread[g_nThdPlane].m_pszMeshFile, MAX_PATH, "%sAssets\\Plane.txt", T2A(g_pszAppPath)); - g_stThread[g_nThdPlane].m_v4ModelPos = XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f); - - // 多线程渲染时,第一遍渲染主要在主显卡上完成,所以为每个线程创建主显卡关联的命令列表 - // 物体的共性参数,也就是各线程的共性参数 - for (int i = 0; i < g_nMaxThread; i++) + //执行两个Copy动作将纹理上传到默认堆中 + UINT nFirstSubresource = 0; + UINT nNumSubresources = static_cast(stArSubResources.size()); + D3D12_RESOURCE_DESC stUploadResDesc = pINoiseTextureUpload->GetDesc(); + D3D12_RESOURCE_DESC stDefaultResDesc = pINoiseTexture->GetDesc(); + + UINT64 n64RequiredSize = 0; + SIZE_T szMemToAlloc = static_cast(sizeof(D3D12_PLACED_SUBRESOURCE_FOOTPRINT) + + sizeof(UINT) + + sizeof(UINT64)) + * nNumSubresources; + + void* pMem = GRS_CALLOC(static_cast(szMemToAlloc)); + + if (nullptr == pMem) { - g_stThread[i].m_nThreadIndex = i; //记录序号 + throw CGRSCOMException(HRESULT_FROM_WIN32(GetLastError())); + } - //创建每个线程需要的命令列表和复制命令队列 - GRS_THROW_IF_FAILED( - stGPU[c_nMainGPU].m_pID3D12Device4->CreateCommandAllocator( - D3D12_COMMAND_LIST_TYPE_DIRECT - , IID_PPV_ARGS(&g_stThread[i].m_pICMDAlloc))); - GRS_SetD3D12DebugNameIndexed(g_stThread[i].m_pICMDAlloc, _T("pIThreadCmdAlloc"), i); + D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts = reinterpret_cast(pMem); + UINT64* pRowSizesInBytes = reinterpret_cast(pLayouts + nNumSubresources); + UINT* pNumRows = reinterpret_cast(pRowSizesInBytes + nNumSubresources); - GRS_THROW_IF_FAILED( - stGPU[c_nMainGPU].m_pID3D12Device4->CreateCommandList( - 0, D3D12_COMMAND_LIST_TYPE_DIRECT - , g_stThread[i].m_pICMDAlloc - , nullptr - , IID_PPV_ARGS(&g_stThread[i].m_pICMDList))); - GRS_SetD3D12DebugNameIndexed(g_stThread[i].m_pICMDList, _T("pIThreadCmdList"), i); - - g_stThread[i].m_dwMainThreadID = ::GetCurrentThreadId(); - g_stThread[i].m_hMainThread = ::GetCurrentThread(); - g_stThread[i].m_hEventRun = ::CreateEvent(nullptr, FALSE, FALSE, nullptr); - g_stThread[i].m_hEventRenderOver = ::CreateEvent(nullptr, FALSE, FALSE, nullptr); - g_stThread[i].m_pID3D12Device4 = stGPU[c_nMainGPU].m_pID3D12Device4.Get(); - g_stThread[i].m_pIRTVHeap = stGPU[c_nMainGPU].m_pIRTVHeap.Get(); - g_stThread[i].m_pIDSVHeap = stGPU[c_nMainGPU].m_pIDSVHeap.Get(); - g_stThread[i].m_pIRS = stGPU[c_nMainGPU].m_pIRS.Get(); - g_stThread[i].m_pIPSO = stGPU[c_nMainGPU].m_pIPSO.Get(); - - arHWaited.Add(g_stThread[i].m_hEventRenderOver); //添加到被等待队列里 - - //以暂停方式创建线程 - g_stThread[i].m_hThisThread = (HANDLE)_beginthreadex(nullptr, - 0, RenderThread, (void*)&g_stThread[i], - CREATE_SUSPENDED, (UINT*)&g_stThread[i].m_dwThisThreadID); - - //然后判断线程创建是否成功 - if (nullptr == g_stThread[i].m_hThisThread - || reinterpret_cast(-1) == g_stThread[i].m_hThisThread) + // 这里是第二次调用GetCopyableFootprints,就得到了所有子资源的详细信息 + stGPU[c_nSecondGPU].m_pID3D12Device4->GetCopyableFootprints(&stDefaultResDesc, nFirstSubresource, nNumSubresources, 0, pLayouts, pNumRows, pRowSizesInBytes, &n64RequiredSize); + + BYTE* pData = nullptr; + GRS_THROW_IF_FAILED(pINoiseTextureUpload->Map(0, nullptr, reinterpret_cast(&pData))); + // 第一遍Copy!注意3重循环每重的意思 + for (UINT nSubRes = 0; nSubRes < nNumSubresources; ++nSubRes) + {// SubResources + if (pRowSizesInBytes[nSubRes] > (SIZE_T)-1) { - throw CGRSCOMException(HRESULT_FROM_WIN32(GetLastError())); + throw CGRSCOMException(E_FAIL); } - arHSubThread.Add(g_stThread[i].m_hThisThread); + D3D12_MEMCPY_DEST stCopyDestData = { pData + pLayouts[nSubRes].Offset + , pLayouts[nSubRes].Footprint.RowPitch + , pLayouts[nSubRes].Footprint.RowPitch * pNumRows[nSubRes] + }; + + for (UINT z = 0; z < pLayouts[nSubRes].Footprint.Depth; ++z) + {// Mipmap + BYTE* pDestSlice = reinterpret_cast(stCopyDestData.pData) + stCopyDestData.SlicePitch * z; + const BYTE* pSrcSlice = reinterpret_cast(stArSubResources[nSubRes].pData) + stArSubResources[nSubRes].SlicePitch * z; + for (UINT y = 0; y < pNumRows[nSubRes]; ++y) + {// Rows + memcpy(pDestSlice + stCopyDestData.RowPitch * y, + pSrcSlice + stArSubResources[nSubRes].RowPitch * y, + (SIZE_T)pRowSizesInBytes[nSubRes]); + } + } } + pINoiseTextureUpload->Unmap(0, nullptr); - //逐一启动线程 - for (int i = 0; i < g_nMaxThread; i++) + // 第二次Copy! + if (stDefaultResDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) + {// Buffer 一次性复制就可以了,因为没有行对齐和行大小不一致的问题,Buffer中行数就是1 + stGPU[c_nSecondGPU].m_pICMDList->CopyBufferRegion( + pINoiseTexture.Get(), 0, pINoiseTextureUpload.Get(), pLayouts[0].Offset, pLayouts[0].Footprint.Width); + } + else { - ::ResumeThread(g_stThread[i].m_hThisThread); + for (UINT nSubRes = 0; nSubRes < nNumSubresources; ++nSubRes) + { + D3D12_TEXTURE_COPY_LOCATION stDstCopyLocation = {}; + stDstCopyLocation.pResource = pINoiseTexture.Get(); + stDstCopyLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + stDstCopyLocation.SubresourceIndex = nSubRes; + + D3D12_TEXTURE_COPY_LOCATION stSrcCopyLocation = {}; + stSrcCopyLocation.pResource = pINoiseTextureUpload.Get(); + stSrcCopyLocation.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + stSrcCopyLocation.PlacedFootprint = pLayouts[nSubRes]; + + stGPU[c_nSecondGPU].m_pICMDList->CopyTextureRegion(&stDstCopyLocation, 0, 0, 0, &stSrcCopyLocation, nullptr); + } } - }} - //11、加载DDS噪声纹理,注意用于后处理,所以加载到第二个显卡上 - {{ - TCHAR pszNoiseTexture[MAX_PATH] = {}; - StringCchPrintf(pszNoiseTexture, MAX_PATH, _T("%sAssets\\GaussianNoise256.dds"), g_pszAppPath); - std::unique_ptr pbDDSData; - std::vector stArSubResources; - DDS_ALPHA_MODE emAlphaMode = DDS_ALPHA_MODE_UNKNOWN; - bool bIsCube = false; - - GRS_THROW_IF_FAILED(LoadDDSTextureFromFile( - stGPU[c_nSecondGPU].m_pID3D12Device4.Get() - , pszNoiseTexture - , pINoiseTexture.GetAddressOf() - , pbDDSData - , stArSubResources - , SIZE_MAX - , &emAlphaMode - , &bIsCube)); - GRS_SET_D3D12_DEBUGNAME_COMPTR(pINoiseTexture); - - UINT64 n64szUpSphere = GetRequiredIntermediateSize( - pINoiseTexture.Get() - , 0 - , static_cast(stArSubResources.size())); - - D3D12_RESOURCE_DESC stTXDesc = pINoiseTexture->GetDesc(); + GRS_SAFE_FREE(pMem); - GRS_THROW_IF_FAILED( - stGPU[c_nSecondGPU].m_pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD) - , D3D12_HEAP_FLAG_NONE - , &CD3DX12_RESOURCE_DESC::Buffer(n64szUpSphere) - , D3D12_RESOURCE_STATE_GENERIC_READ - , nullptr - , IID_PPV_ARGS(&pINoiseTextureUpload))); - GRS_SET_D3D12_DEBUGNAME_COMPTR(pINoiseTextureUpload); - - //执行两个Copy动作将纹理上传到默认堆中 - UpdateSubresources(stGPU[c_nSecondGPU].m_pICMDList.Get() - , pINoiseTexture.Get() - , pINoiseTextureUpload.Get() - , 0 - , 0 - , static_cast(stArSubResources.size()) - , stArSubResources.data()); - - //同步 - stGPU[c_nSecondGPU].m_pICMDList->ResourceBarrier(1 - , &CD3DX12_RESOURCE_BARRIER::Transition(pINoiseTexture.Get() - , D3D12_RESOURCE_STATE_COPY_DEST - , D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)); - - }} + //同步 + stResStateTransBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST; + stResStateTransBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + stResStateTransBarrier.Transition.pResource = pINoiseTexture.Get(); + + stGPU[c_nSecondGPU].m_pICMDList->ResourceBarrier(1, &stResStateTransBarrier); + } //12、建辅助显卡用来渲染或后处理用的矩形框 { ST_GRS_VERTEX_QUAD stVertexQuad[] = @@ -1371,45 +1608,45 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l }; const UINT nszVBQuad = sizeof(stVertexQuad); - + stBufferResSesc.Width = nszVBQuad; GRS_THROW_IF_FAILED( stGPU[c_nSecondGPU].m_pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), - D3D12_HEAP_FLAG_NONE, - &CD3DX12_RESOURCE_DESC::Buffer(nszVBQuad), - D3D12_RESOURCE_STATE_COPY_DEST, - nullptr, - IID_PPV_ARGS(&pIVBQuad))); + &stDefautHeapProps + , D3D12_HEAP_FLAG_NONE + , &stBufferResSesc + , D3D12_RESOURCE_STATE_COPY_DEST + , nullptr + , IID_PPV_ARGS(&pIVBQuad))); // 这次我们特意演示了如何将顶点缓冲上传到默认堆上的方式,与纹理上传默认堆实际是一样的 + stBufferResSesc.Width = nszVBQuad; GRS_THROW_IF_FAILED( stGPU[c_nSecondGPU].m_pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), - D3D12_HEAP_FLAG_NONE, - &CD3DX12_RESOURCE_DESC::Buffer(nszVBQuad), - D3D12_RESOURCE_STATE_GENERIC_READ, - nullptr, - IID_PPV_ARGS(&pIVBQuadUpload))); + &stUploadHeapProps + , D3D12_HEAP_FLAG_NONE + , &stBufferResSesc + , D3D12_RESOURCE_STATE_GENERIC_READ + , nullptr + , IID_PPV_ARGS(&pIVBQuadUpload))); D3D12_SUBRESOURCE_DATA stVBDataQuad = {}; stVBDataQuad.pData = reinterpret_cast(stVertexQuad); stVBDataQuad.RowPitch = nszVBQuad; stVBDataQuad.SlicePitch = stVBDataQuad.RowPitch; - UpdateSubresources<1>( - stGPU[c_nSecondGPU].m_pICMDList.Get() - , pIVBQuad.Get() - , pIVBQuadUpload.Get() - , 0 - , 0 - , 1 - , &stVBDataQuad); - - stGPU[c_nSecondGPU].m_pICMDList->ResourceBarrier( - 1 - , &CD3DX12_RESOURCE_BARRIER::Transition(pIVBQuad.Get() - , D3D12_RESOURCE_STATE_COPY_DEST - , D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER)); + // 第一遍Copy + BYTE* pData = nullptr; + GRS_THROW_IF_FAILED(pIVBQuadUpload->Map(0, nullptr, reinterpret_cast(&pData))); + memcpy(pData, stVertexQuad, nszVBQuad); + pIVBQuadUpload->Unmap(0, nullptr); + // 第二遍Copy + stGPU[c_nSecondGPU].m_pICMDList->CopyResource(pIVBQuad.Get(), pIVBQuadUpload.Get()); + + // 资源屏障同步 + stResStateTransBarrier.Transition.pResource = pIVBQuad.Get(); + stResStateTransBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST; + stResStateTransBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER; + stGPU[c_nSecondGPU].m_pICMDList->ResourceBarrier(1, &stResStateTransBarrier); pstVBVQuad.BufferLocation = pIVBQuad->GetGPUVirtualAddress(); pstVBVQuad.StrideInBytes = sizeof(ST_GRS_VERTEX_QUAD); @@ -1435,10 +1672,11 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l //-----------------------------------华丽丽的割一下---------------------------------------------------------- // 创建辅助显卡上的常量缓冲区 + stBufferResSesc.Width = szSecondPassCB; //注意缓冲尺寸设置为256边界对齐大小 GRS_THROW_IF_FAILED(stGPU[c_nSecondGPU].m_pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD) + &stUploadHeapProps , D3D12_HEAP_FLAG_NONE - , &CD3DX12_RESOURCE_DESC::Buffer(szSecondPassCB) //注意缓冲尺寸设置为256边界对齐大小 + , &stBufferResSesc , D3D12_RESOURCE_STATE_GENERIC_READ , nullptr , IID_PPV_ARGS(&pICBResSecondPass))); @@ -1457,12 +1695,10 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l , IID_PPV_ARGS(&stGPU[c_nSecondGPU].m_pISRVHeap))); GRS_SET_D3D12_DEBUGNAME_COMPTR(stGPU[c_nSecondGPU].m_pISRVHeap); - CD3DX12_CPU_DESCRIPTOR_HANDLE stSrvHandle( - stGPU[c_nSecondGPU].m_pISRVHeap->GetCPUDescriptorHandleForHeapStart() - ); + D3D12_CPU_DESCRIPTOR_HANDLE stSrvHandle = stGPU[c_nSecondGPU].m_pISRVHeap->GetCPUDescriptorHandleForHeapStart(); // Create Third Pass SRV Heap - stDescriptorHeapDesc.NumDescriptors = g_nFrameBackBufCount; + stDescriptorHeapDesc.NumDescriptors = g_nFrameBackBufCount; //为每一个渲染目标纹理创建一个SRV,这样只需要设置时便宜到对应SRV即可 for (int i = 0; i < c_nPostPassCnt; i++) { @@ -1499,7 +1735,7 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l , stSrvHandle); } - stSrvHandle.Offset(1, stGPU[c_nSecondGPU].m_nSRVDescriptorSize); + stSrvHandle.ptr += stGPU[c_nSecondGPU].m_nSRVDescriptorSize; } //Create CBV @@ -1509,7 +1745,7 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l stGPU[c_nSecondGPU].m_pID3D12Device4->CreateConstantBufferView(&stCBVDesc, stSrvHandle); - stSrvHandle.Offset(1, stGPU[c_nSecondGPU].m_nSRVDescriptorSize); + stSrvHandle.ptr += stGPU[c_nSecondGPU].m_nSRVDescriptorSize; // Create Noise SRV D3D12_RESOURCE_DESC stTXDesc = pINoiseTexture->GetDesc(); @@ -1522,14 +1758,14 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l stSRVDesc.Format = emRTFormat; for (int k = 0; k < c_nPostPassCnt; k++) { - CD3DX12_CPU_DESCRIPTOR_HANDLE stThirdPassSrvHandle(pISRVHeapPostPass[k]->GetCPUDescriptorHandleForHeapStart()); + D3D12_CPU_DESCRIPTOR_HANDLE stThirdPassSrvHandle = pISRVHeapPostPass[k]->GetCPUDescriptorHandleForHeapStart(); for (int i = 0; i < g_nFrameBackBufCount; i++) { stGPU[c_nSecondGPU].m_pID3D12Device4->CreateShaderResourceView( pIOffLineRTRes[k][i].Get() , &stSRVDesc , stThirdPassSrvHandle); - stThirdPassSrvHandle.Offset(1, stGPU[c_nSecondGPU].m_nSRVDescriptorSize); + stThirdPassSrvHandle.ptr += stGPU[c_nSecondGPU].m_nSRVDescriptorSize; } } //------------------------------------------------------------------------------------------------------- @@ -1569,8 +1805,6 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l stGPU[c_nSecondGPU].m_pID3D12Device4->CreateSampler( &stSamplerDesc , pISampleHeapPostPass->GetCPUDescriptorHandleForHeapStart()); - - } //显示窗口,准备开始消息循环渲染 @@ -1680,20 +1914,16 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l //渲染前处理 { - pICMDListBefore->ResourceBarrier(1 - , &CD3DX12_RESOURCE_BARRIER::Transition( - stGPU[c_nMainGPU].m_pIRTRes[nCurrentFrameIndex].Get() - , D3D12_RESOURCE_STATE_COMMON - , D3D12_RESOURCE_STATE_RENDER_TARGET) - ); + stResStateTransBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COMMON; + stResStateTransBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET; + stResStateTransBarrier.Transition.pResource = stGPU[c_nMainGPU].m_pIRTRes[nCurrentFrameIndex].Get(); + + pICMDListBefore->ResourceBarrier(1, &stResStateTransBarrier); //偏移描述符指针到指定帧缓冲视图位置 - CD3DX12_CPU_DESCRIPTOR_HANDLE stRTVHandle( - stGPU[c_nMainGPU].m_pIRTVHeap->GetCPUDescriptorHandleForHeapStart() - , nCurrentFrameIndex - , stGPU[c_nMainGPU].m_nRTVDescriptorSize); - CD3DX12_CPU_DESCRIPTOR_HANDLE stDSVHandle( - stGPU[c_nMainGPU].m_pIDSVHeap->GetCPUDescriptorHandleForHeapStart()); + D3D12_CPU_DESCRIPTOR_HANDLE stRTVHandle = stGPU[c_nMainGPU].m_pIRTVHeap->GetCPUDescriptorHandleForHeapStart(); + stRTVHandle.ptr += (nCurrentFrameIndex * stGPU[c_nMainGPU].m_nRTVDescriptorSize); + D3D12_CPU_DESCRIPTOR_HANDLE stDSVHandle = stGPU[c_nMainGPU].m_pIDSVHeap->GetCPUDescriptorHandleForHeapStart(); //设置渲染目标 pICMDListBefore->OMSetRenderTargets(1, &stRTVHandle, FALSE, &stDSVHandle); @@ -1730,11 +1960,11 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l { // 1 First Pass { - pICMDListLater->ResourceBarrier(1 - , &CD3DX12_RESOURCE_BARRIER::Transition( - stGPU[c_nMainGPU].m_pIRTRes[nCurrentFrameIndex].Get() - , D3D12_RESOURCE_STATE_RENDER_TARGET - , D3D12_RESOURCE_STATE_COMMON)); + stResStateTransBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET; + stResStateTransBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COMMON; + stResStateTransBarrier.Transition.pResource = stGPU[c_nMainGPU].m_pIRTRes[nCurrentFrameIndex].Get(); + + pICMDListLater->ResourceBarrier(1, &stResStateTransBarrier); //关闭命令列表,可以去执行了 GRS_THROW_IF_FAILED(pICMDListBefore->Close()); @@ -1764,7 +1994,7 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l pICMDAllocCopy->Reset(); pICMDListCopy->Reset(pICMDAllocCopy.Get(), nullptr); - if ( bCrossAdapterTextureSupport ) + if (bCrossAdapterTextureSupport) { // 如果适配器支持跨适配器行主纹理,只需将该纹理复制到跨适配器纹理中。 pICMDListCopy->CopyResource( @@ -1782,15 +2012,19 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l stGPU[c_nMainGPU].m_pID3D12Device4->GetCopyableFootprints( &stRenderTargetDesc, 0, 1, 0, &stRenderTargetLayout, nullptr, nullptr, nullptr); - CD3DX12_TEXTURE_COPY_LOCATION dest( - stGPU[c_nMainGPU].m_pICrossAdapterResPerFrame[nCurrentFrameIndex].Get() - , stRenderTargetLayout); - CD3DX12_TEXTURE_COPY_LOCATION src( - stGPU[c_nMainGPU].m_pIRTRes[nCurrentFrameIndex].Get() - , 0); - CD3DX12_BOX box(0, 0, g_iWndWidth, g_iWndHeight); + D3D12_TEXTURE_COPY_LOCATION stDstCopyLocation = {}; + stDstCopyLocation.pResource = stGPU[c_nMainGPU].m_pICrossAdapterResPerFrame[nCurrentFrameIndex].Get(); + stDstCopyLocation.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + stDstCopyLocation.PlacedFootprint = stRenderTargetLayout; - pICMDListCopy->CopyTextureRegion(&dest, 0, 0, 0, &src, &box); + D3D12_TEXTURE_COPY_LOCATION stSrcCopyLocation = {}; + stSrcCopyLocation.pResource = stGPU[c_nMainGPU].m_pIRTRes[nCurrentFrameIndex].Get(); + stSrcCopyLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + stSrcCopyLocation.SubresourceIndex = 0; + + D3D12_BOX stCopyBox = { 0, 0, (UINT)g_iWndWidth, (UINT)g_iWndHeight }; + + pICMDListCopy->CopyTextureRegion(&stDstCopyLocation, 0, 0, 0, &stSrcCopyLocation, &stCopyBox); } GRS_THROW_IF_FAILED(pICMDListCopy->Close()); @@ -1801,7 +2035,7 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l arCmdList.RemoveAll(); arCmdList.Add(pICMDListCopy.Get()); - pICmdQueueCopy->ExecuteCommandLists(static_cast(arCmdList.GetCount()),arCmdList.GetData()); + pICmdQueueCopy->ExecuteCommandLists(static_cast(arCmdList.GetCount()), arCmdList.GetData()); n64CurrentFenceValue = n64FenceValue; // 复制命令的信号设置在共享的围栏对象上这样使得第二个显卡的命令队列可以在这个围栏上等待 @@ -1823,12 +2057,11 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l if (!bCrossAdapterTextureSupport) {//当不能跨显卡共享纹理时,要执行多一遍COPY,相当于经典的两遍COPY中的第二遍COPY // 将共享堆中的缓冲区复制到辅助适配器可以从中取样的纹理中。 - D3D12_RESOURCE_BARRIER stResBarrier = CD3DX12_RESOURCE_BARRIER::Transition( - pISecondaryAdapterTexutrePerFrame[nCurrentFrameIndex].Get(), - D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, - D3D12_RESOURCE_STATE_COPY_DEST); + stResStateTransBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + stResStateTransBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_DEST; + stResStateTransBarrier.Transition.pResource = pISecondaryAdapterTexutrePerFrame[nCurrentFrameIndex].Get(); - stGPU[c_nSecondGPU].m_pICMDList->ResourceBarrier(1, &stResBarrier); + stGPU[c_nSecondGPU].m_pICMDList->ResourceBarrier(1, &stResStateTransBarrier); D3D12_RESOURCE_DESC stSecondaryAdapterTexture = pISecondaryAdapterTexutrePerFrame[nCurrentFrameIndex]->GetDesc(); @@ -1837,22 +2070,29 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l stGPU[c_nSecondGPU].m_pID3D12Device4->GetCopyableFootprints( &stSecondaryAdapterTexture, 0, 1, 0, &stTextureLayout, nullptr, nullptr, nullptr); - CD3DX12_TEXTURE_COPY_LOCATION dest( - pISecondaryAdapterTexutrePerFrame[nCurrentFrameIndex].Get(), 0); - CD3DX12_TEXTURE_COPY_LOCATION src( - stGPU[c_nSecondGPU].m_pICrossAdapterResPerFrame[nCurrentFrameIndex].Get() - , stTextureLayout); - CD3DX12_BOX box(0, 0, g_iWndWidth, g_iWndHeight); + D3D12_TEXTURE_COPY_LOCATION stDstCopyLocation = {}; + stDstCopyLocation.pResource = pISecondaryAdapterTexutrePerFrame[nCurrentFrameIndex].Get(); + stDstCopyLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + stDstCopyLocation.SubresourceIndex = 0; + + D3D12_TEXTURE_COPY_LOCATION stSrcCopyLocation = {}; + stSrcCopyLocation.pResource = stGPU[c_nMainGPU].m_pIRTRes[nCurrentFrameIndex].Get(); + stSrcCopyLocation.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + stSrcCopyLocation.PlacedFootprint = stTextureLayout; + + D3D12_BOX stCopyBox = { 0, 0, (UINT)g_iWndWidth, (UINT)g_iWndHeight }; //这个Copy动作可以理解为一个纹理从Upload堆上传到Default堆 //当显卡都支持跨显卡共享纹理时,这个复制动作就可以省却了,这样提高了效率 //目前越新越高级的显卡基本都支持跨显卡共享纹理,所以就越高效 //比如我现在的辅助显卡是Intel UHD G630就支持跨显卡共享纹理,就不会有这个多余的复制动作 - stGPU[c_nSecondGPU].m_pICMDList->CopyTextureRegion(&dest, 0, 0, 0, &src, &box); + stGPU[c_nSecondGPU].m_pICMDList->CopyTextureRegion(&stDstCopyLocation, 0, 0, 0, &stSrcCopyLocation, &stCopyBox); + + stResStateTransBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST; + stResStateTransBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + stResStateTransBarrier.Transition.pResource = pISecondaryAdapterTexutrePerFrame[nCurrentFrameIndex].Get(); - stResBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST; - stResBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; - stGPU[c_nSecondGPU].m_pICMDList->ResourceBarrier(1, &stResBarrier); + stGPU[c_nSecondGPU].m_pICMDList->ResourceBarrier(1, &stResStateTransBarrier); } //------------------------------------------------------------------------------------------------------ @@ -1868,18 +2108,16 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l stGPU[c_nSecondGPU].m_pICMDList->RSSetViewports(1, &g_stViewPort); stGPU[c_nSecondGPU].m_pICMDList->RSSetScissorRects(1, &g_stScissorRect); - if ( 0 == g_nUsePSID) + if (0 == g_nUsePSID) {//没有高斯模糊的情况,直接输出 - D3D12_RESOURCE_BARRIER stRTBarriersFourthPass = CD3DX12_RESOURCE_BARRIER::Transition( - stGPU[c_nSecondGPU].m_pIRTRes[nCurrentFrameIndex].Get() - , D3D12_RESOURCE_STATE_PRESENT - , D3D12_RESOURCE_STATE_RENDER_TARGET); - stGPU[c_nSecondGPU].m_pICMDList->ResourceBarrier(1, &stRTBarriersFourthPass); + stResStateTransBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT; + stResStateTransBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET; + stResStateTransBarrier.Transition.pResource = stGPU[c_nSecondGPU].m_pIRTRes[nCurrentFrameIndex].Get(); - CD3DX12_CPU_DESCRIPTOR_HANDLE stRTV4Handle( - stGPU[c_nSecondGPU].m_pIRTVHeap->GetCPUDescriptorHandleForHeapStart() - , nCurrentFrameIndex - , stGPU[c_nSecondGPU].m_nRTVDescriptorSize); + stGPU[c_nSecondGPU].m_pICMDList->ResourceBarrier(1, &stResStateTransBarrier); + + D3D12_CPU_DESCRIPTOR_HANDLE stRTV4Handle = stGPU[c_nSecondGPU].m_pIRTVHeap->GetCPUDescriptorHandleForHeapStart(); + stRTV4Handle.ptr += (nCurrentFrameIndex * stGPU[c_nSecondGPU].m_nRTVDescriptorSize); stGPU[c_nSecondGPU].m_pICMDList->OMSetRenderTargets(1, &stRTV4Handle, false, nullptr); float f4ClearColor[] = { 1.0f,0.0f,1.0f,1.0f }; //故意使用不同的清除色,查看是否有“露底”的问题 @@ -1887,43 +2125,34 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l } else { - D3D12_RESOURCE_BARRIER stRTBarriersSecondPass = CD3DX12_RESOURCE_BARRIER::Transition( - pIOffLineRTRes[c_nPostPass0][nCurrentFrameIndex].Get() - , D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE - , D3D12_RESOURCE_STATE_RENDER_TARGET); + stResStateTransBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + stResStateTransBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET; + stResStateTransBarrier.Transition.pResource = pIOffLineRTRes[c_nPostPass0][nCurrentFrameIndex].Get(); + stGPU[c_nSecondGPU].m_pICMDList->ResourceBarrier(1, &stResStateTransBarrier); - stGPU[c_nSecondGPU].m_pICMDList->ResourceBarrier(1, &stRTBarriersSecondPass); + D3D12_CPU_DESCRIPTOR_HANDLE stRTVHadnleSecondPass = pIRTVOffLine[c_nPostPass0]->GetCPUDescriptorHandleForHeapStart(); + stRTVHadnleSecondPass.ptr += ( nCurrentFrameIndex * stGPU[c_nSecondGPU].m_nRTVDescriptorSize); - CD3DX12_CPU_DESCRIPTOR_HANDLE stRTVHadnleSecondPass( - pIRTVOffLine[c_nPostPass0]->GetCPUDescriptorHandleForHeapStart() - , nCurrentFrameIndex - , stGPU[c_nSecondGPU].m_nRTVDescriptorSize); stGPU[c_nSecondGPU].m_pICMDList->OMSetRenderTargets(1, &stRTVHadnleSecondPass, false, nullptr); stGPU[c_nSecondGPU].m_pICMDList->ClearRenderTargetView(stRTVHadnleSecondPass, v4ClearColor, 0, nullptr); } // CBV - CD3DX12_GPU_DESCRIPTOR_HANDLE stCBVGPUHandle( - stGPU[c_nSecondGPU].m_pISRVHeap->GetGPUDescriptorHandleForHeapStart() - , g_nFrameBackBufCount - , stGPU[c_nSecondGPU].m_nSRVDescriptorSize); + D3D12_GPU_DESCRIPTOR_HANDLE stCBVGPUHandle = stGPU[c_nSecondGPU].m_pISRVHeap->GetGPUDescriptorHandleForHeapStart(); + stCBVGPUHandle.ptr += (g_nFrameBackBufCount * stGPU[c_nSecondGPU].m_nSRVDescriptorSize); stGPU[c_nSecondGPU].m_pICMDList->SetGraphicsRootDescriptorTable(0, stCBVGPUHandle); // Render Target to Texture SRV - CD3DX12_GPU_DESCRIPTOR_HANDLE stSRVGPUHandle( - stGPU[c_nSecondGPU].m_pISRVHeap->GetGPUDescriptorHandleForHeapStart() - , nCurrentFrameIndex - , stGPU[c_nSecondGPU].m_nSRVDescriptorSize); + D3D12_GPU_DESCRIPTOR_HANDLE stSRVGPUHandle = stGPU[c_nSecondGPU].m_pISRVHeap->GetGPUDescriptorHandleForHeapStart(); + stSRVGPUHandle.ptr += ( nCurrentFrameIndex * stGPU[c_nSecondGPU].m_nSRVDescriptorSize); stGPU[c_nSecondGPU].m_pICMDList->SetGraphicsRootDescriptorTable(1, stSRVGPUHandle); // Noise Texture SRV - CD3DX12_GPU_DESCRIPTOR_HANDLE stNoiseSRVGPUHandle( - stGPU[c_nSecondGPU].m_pISRVHeap->GetGPUDescriptorHandleForHeapStart() - , g_nFrameBackBufCount + 1 - , stGPU[c_nSecondGPU].m_nSRVDescriptorSize); + D3D12_GPU_DESCRIPTOR_HANDLE stNoiseSRVGPUHandle = stGPU[c_nSecondGPU].m_pISRVHeap->GetGPUDescriptorHandleForHeapStart(); + stNoiseSRVGPUHandle.ptr += ( (g_nFrameBackBufCount + 1) * stGPU[c_nSecondGPU].m_nSRVDescriptorSize ); stGPU[c_nSecondGPU].m_pICMDList->SetGraphicsRootDescriptorTable(2, stNoiseSRVGPUHandle); @@ -1938,27 +2167,27 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l if (0 == g_nUsePSID) {// 没有高斯模糊的情况,直接输出 - stGPU[c_nSecondGPU].m_pICMDList->ResourceBarrier(1 - , &CD3DX12_RESOURCE_BARRIER::Transition( - stGPU[c_nSecondGPU].m_pIRTRes[nCurrentFrameIndex].Get() - , D3D12_RESOURCE_STATE_RENDER_TARGET - , D3D12_RESOURCE_STATE_PRESENT)); + stResStateTransBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET; + stResStateTransBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT; + stResStateTransBarrier.Transition.pResource = stGPU[c_nSecondGPU].m_pIRTRes[nCurrentFrameIndex].Get(); + + stGPU[c_nSecondGPU].m_pICMDList->ResourceBarrier(1, &stResStateTransBarrier); } else { // 第二个显卡上的第一遍渲染目标纹理做状态切换 - stGPU[c_nSecondGPU].m_pICMDList->ResourceBarrier(1 - , &CD3DX12_RESOURCE_BARRIER::Transition( - pIOffLineRTRes[c_nPostPass0][nCurrentFrameIndex].Get() - , D3D12_RESOURCE_STATE_RENDER_TARGET - , D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)); + stResStateTransBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET; + stResStateTransBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + stResStateTransBarrier.Transition.pResource = pIOffLineRTRes[c_nPostPass0][nCurrentFrameIndex].Get(); + + stGPU[c_nSecondGPU].m_pICMDList->ResourceBarrier(1, &stResStateTransBarrier); } GRS_THROW_IF_FAILED(stGPU[c_nSecondGPU].m_pICMDList->Close()); } // 调用高斯模糊效果(两遍 Post Pass) - if( 1 == g_nUsePSID ) - { + if (1 == g_nUsePSID) + { pICMDAllocPostPass->Reset(); pICMDListPostPass->Reset(pICMDAllocPostPass.Get(), pIPSOPostPass[c_nPostPass0].Get()); @@ -1973,32 +2202,27 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l // 3 Thrid Pass //使用高斯模糊 pICMDListPostPass->SetPipelineState(pIPSOPostPass[c_nPostPass0].Get()); - + arDesHeaps.RemoveAll(); arDesHeaps.Add(pISRVHeapPostPass[c_nPostPass0].Get()); arDesHeaps.Add(pISampleHeapPostPass.Get()); - pICMDListPostPass->SetDescriptorHeaps(static_cast(arDesHeaps.GetCount()),arDesHeaps.GetData()); + pICMDListPostPass->SetDescriptorHeaps(static_cast(arDesHeaps.GetCount()), arDesHeaps.GetData()); - D3D12_RESOURCE_BARRIER stRTBarriersThirdPass = CD3DX12_RESOURCE_BARRIER::Transition( - pIOffLineRTRes[c_nPostPass1][nCurrentFrameIndex].Get() - , D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE - , D3D12_RESOURCE_STATE_RENDER_TARGET); + stResStateTransBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + stResStateTransBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET; + stResStateTransBarrier.Transition.pResource = pIOffLineRTRes[c_nPostPass1][nCurrentFrameIndex].Get(); - pICMDListPostPass->ResourceBarrier(1, &stRTBarriersThirdPass); + pICMDListPostPass->ResourceBarrier(1, &stResStateTransBarrier); - CD3DX12_CPU_DESCRIPTOR_HANDLE stRTVHandleThirdPass( - pIRTVOffLine[c_nPostPass1]->GetCPUDescriptorHandleForHeapStart() - , nCurrentFrameIndex - , stGPU[c_nSecondGPU].m_nRTVDescriptorSize); + D3D12_CPU_DESCRIPTOR_HANDLE stRTVHandleThirdPass = pIRTVOffLine[c_nPostPass1]->GetCPUDescriptorHandleForHeapStart(); + stRTVHandleThirdPass.ptr += ( nCurrentFrameIndex * stGPU[c_nSecondGPU].m_nRTVDescriptorSize); pICMDListPostPass->OMSetRenderTargets(1, &stRTVHandleThirdPass, false, nullptr); pICMDListPostPass->ClearRenderTargetView(stRTVHandleThirdPass, v4ClearColor, 0, nullptr); //将第二遍渲染的结果作为纹理 - CD3DX12_GPU_DESCRIPTOR_HANDLE stSRV3Handle( - pISRVHeapPostPass[c_nPostPass0]->GetGPUDescriptorHandleForHeapStart() - , nCurrentFrameIndex - , stGPU[c_nSecondGPU].m_nSRVDescriptorSize); + D3D12_GPU_DESCRIPTOR_HANDLE stSRV3Handle = pISRVHeapPostPass[c_nPostPass0]->GetGPUDescriptorHandleForHeapStart(); + stSRV3Handle.ptr += ( nCurrentFrameIndex * stGPU[c_nSecondGPU].m_nSRVDescriptorSize); pICMDListPostPass->SetGraphicsRootDescriptorTable(0, stSRV3Handle); pICMDListPostPass->SetGraphicsRootDescriptorTable(1, pISampleHeapPostPass->GetGPUDescriptorHandleForHeapStart()); @@ -2007,42 +2231,38 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l pICMDListPostPass->DrawInstanced(4, 1, 0, 0); // 设置好同步围栏 - pICMDListPostPass->ResourceBarrier(1 - , &CD3DX12_RESOURCE_BARRIER::Transition( - pIOffLineRTRes[c_nPostPass1][nCurrentFrameIndex].Get() - , D3D12_RESOURCE_STATE_RENDER_TARGET - , D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)); + stResStateTransBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET; + stResStateTransBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + stResStateTransBarrier.Transition.pResource = pIOffLineRTRes[c_nPostPass1][nCurrentFrameIndex].Get(); + pICMDListPostPass->ResourceBarrier(1, &stResStateTransBarrier); //------------------------------------------------------------------------------------------------------- // 4 Fourth Pass //高斯模糊 pICMDListPostPass->SetPipelineState(pIPSOPostPass[c_nPostPass1].Get()); - + arDesHeaps.RemoveAll(); arDesHeaps.Add(pISRVHeapPostPass[c_nPostPass1].Get()); arDesHeaps.Add(pISampleHeapPostPass.Get()); - pICMDListPostPass->SetDescriptorHeaps(static_cast(arDesHeaps.GetCount()),arDesHeaps.GetData()); + pICMDListPostPass->SetDescriptorHeaps(static_cast(arDesHeaps.GetCount()), arDesHeaps.GetData()); - D3D12_RESOURCE_BARRIER stRTBarriersFourthPass = CD3DX12_RESOURCE_BARRIER::Transition( - stGPU[c_nSecondGPU].m_pIRTRes[nCurrentFrameIndex].Get() - , D3D12_RESOURCE_STATE_PRESENT - , D3D12_RESOURCE_STATE_RENDER_TARGET); - pICMDListPostPass->ResourceBarrier(1, &stRTBarriersFourthPass); + stResStateTransBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT; + stResStateTransBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET; + stResStateTransBarrier.Transition.pResource = stGPU[c_nSecondGPU].m_pIRTRes[nCurrentFrameIndex].Get(); + + pICMDListPostPass->ResourceBarrier(1, &stResStateTransBarrier); + + D3D12_CPU_DESCRIPTOR_HANDLE stRTVHandle = stGPU[c_nSecondGPU].m_pIRTVHeap->GetCPUDescriptorHandleForHeapStart(); + stRTVHandle.ptr += (nCurrentFrameIndex * stGPU[c_nSecondGPU].m_nRTVDescriptorSize); + pICMDListPostPass->OMSetRenderTargets(1, &stRTVHandle, false, nullptr); - CD3DX12_CPU_DESCRIPTOR_HANDLE stRTV4Handle( - stGPU[c_nSecondGPU].m_pIRTVHeap->GetCPUDescriptorHandleForHeapStart() - , nCurrentFrameIndex - , stGPU[c_nSecondGPU].m_nRTVDescriptorSize); - pICMDListPostPass->OMSetRenderTargets(1, &stRTV4Handle, false, nullptr); float f4ClearColor[] = { 1.0f,0.0f,1.0f,1.0f }; //故意使用不同的清除色,查看是否有“露底”的问题 - pICMDListPostPass->ClearRenderTargetView(stRTV4Handle, f4ClearColor, 0, nullptr); + pICMDListPostPass->ClearRenderTargetView(stRTVHandle, f4ClearColor, 0, nullptr); //将第三遍渲染的结果作为纹理 - CD3DX12_GPU_DESCRIPTOR_HANDLE stSRV4Handle( - pISRVHeapPostPass[c_nPostPass1]->GetGPUDescriptorHandleForHeapStart() - , nCurrentFrameIndex - , stGPU[c_nSecondGPU].m_nSRVDescriptorSize); + D3D12_GPU_DESCRIPTOR_HANDLE stSRV4Handle = pISRVHeapPostPass[c_nPostPass1]->GetGPUDescriptorHandleForHeapStart(); + stSRV4Handle.ptr += (nCurrentFrameIndex * stGPU[c_nSecondGPU].m_nSRVDescriptorSize); pICMDListPostPass->SetGraphicsRootDescriptorTable(0, stSRV4Handle); pICMDListPostPass->SetGraphicsRootDescriptorTable(1, pISampleHeapPostPass->GetGPUDescriptorHandleForHeapStart()); @@ -2050,23 +2270,23 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l pICMDListPostPass->DrawInstanced(4, 1, 0, 0); // 设置好同步围栏 - pICMDListPostPass->ResourceBarrier(1 - , &CD3DX12_RESOURCE_BARRIER::Transition( - stGPU[c_nSecondGPU].m_pIRTRes[nCurrentFrameIndex].Get() - , D3D12_RESOURCE_STATE_RENDER_TARGET - , D3D12_RESOURCE_STATE_PRESENT)); + stResStateTransBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET; + stResStateTransBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT; + stResStateTransBarrier.Transition.pResource = stGPU[c_nSecondGPU].m_pIRTRes[nCurrentFrameIndex].Get(); + + pICMDListPostPass->ResourceBarrier(1, &stResStateTransBarrier); GRS_THROW_IF_FAILED(pICMDListPostPass->Close()); } - + arCmdList.RemoveAll(); arCmdList.Add(stGPU[c_nSecondGPU].m_pICMDList.Get()); - if ( 1 == g_nUsePSID) + if (1 == g_nUsePSID) { arCmdList.Add(pICMDListPostPass.Get()); - } - + } + stGPU[c_nSecondGPU].m_pICMDQueue->ExecuteCommandLists(static_cast(arCmdList.GetCount()), arCmdList.GetData()); // 执行Present命令最终呈现画面 @@ -2128,7 +2348,7 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l ::KillTimer(hWnd, WM_USER + 100); } - catch (CGRSCOMException & e) + catch (CGRSCOMException& e) {//发生了COM异常 e; } @@ -2152,7 +2372,7 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l GRS_SAFE_RELEASE(g_stThread[i].m_pICMDAlloc); } } - catch (CGRSCOMException & e) + catch (CGRSCOMException& e) {//发生了异常 e; } @@ -2200,6 +2420,38 @@ UINT __stdcall RenderThread(void* pParam) UINT nSRVDescriptorSize = 0; UINT nRTVDescriptorSize = 0; + + D3D12_HEAP_PROPERTIES stDefautHeapProps = {}; + stDefautHeapProps.Type = D3D12_HEAP_TYPE_DEFAULT; + stDefautHeapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + stDefautHeapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + stDefautHeapProps.CreationNodeMask = 0; + stDefautHeapProps.VisibleNodeMask = 0; + + D3D12_HEAP_PROPERTIES stUploadHeapProps = {}; + stUploadHeapProps.Type = D3D12_HEAP_TYPE_UPLOAD; + stUploadHeapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + stUploadHeapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + stUploadHeapProps.CreationNodeMask = 0; + stUploadHeapProps.VisibleNodeMask = 0; + + D3D12_RESOURCE_DESC stBufferResSesc = {}; + stBufferResSesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + stBufferResSesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + stBufferResSesc.Flags = D3D12_RESOURCE_FLAG_NONE; + stBufferResSesc.Format = DXGI_FORMAT_UNKNOWN; + stBufferResSesc.Width = 0; + stBufferResSesc.Height = 1; + stBufferResSesc.DepthOrArraySize = 1; + stBufferResSesc.MipLevels = 1; + stBufferResSesc.SampleDesc.Count = 1; + stBufferResSesc.SampleDesc.Quality = 0; + + D3D12_RESOURCE_BARRIER stResStateTransBarrier = {}; + stResStateTransBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + stResStateTransBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + stResStateTransBarrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + //1、加载DDS纹理 { nRTVDescriptorSize = pThdPms->m_pID3D12Device4->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); @@ -2216,36 +2468,117 @@ UINT __stdcall RenderThread(void* pParam) , &bIsCube)); GRS_SET_D3D12_DEBUGNAME_COMPTR(pITexture); - UINT64 n64szUpSphere = GetRequiredIntermediateSize( - pITexture.Get() - , 0 - , static_cast(stArSubResources.size())); - D3D12_RESOURCE_DESC stTXDesc = pITexture->GetDesc(); + UINT64 n64szUpSphere = 0; + pThdPms->m_pID3D12Device4->GetCopyableFootprints(&stTXDesc, 0, static_cast(stArSubResources.size()) + , 0, nullptr, nullptr, nullptr, &n64szUpSphere); + stBufferResSesc.Width = n64szUpSphere; GRS_THROW_IF_FAILED(pThdPms->m_pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD) + &stUploadHeapProps , D3D12_HEAP_FLAG_NONE - , &CD3DX12_RESOURCE_DESC::Buffer(n64szUpSphere) + , &stBufferResSesc , D3D12_RESOURCE_STATE_GENERIC_READ , nullptr , IID_PPV_ARGS(&pITextureUpload))); GRS_SET_D3D12_DEBUGNAME_COMPTR(pITextureUpload); + //UpdateSubresources(pThdPms->m_pICMDList + // , pITexture.Get() + // , pITextureUpload.Get() + // , 0 + // , 0 + // , static_cast(stArSubResources.size()) + // , stArSubResources.data()); + //执行两个Copy动作将纹理上传到默认堆中 - UpdateSubresources(pThdPms->m_pICMDList - , pITexture.Get() - , pITextureUpload.Get() - , 0 - , 0 - , static_cast(stArSubResources.size()) - , stArSubResources.data()); + + UINT nFirstSubresource = 0; + UINT nNumSubresources = static_cast(stArSubResources.size()); + D3D12_RESOURCE_DESC stUploadResDesc = pITextureUpload->GetDesc(); + D3D12_RESOURCE_DESC stDefaultResDesc = pITexture->GetDesc(); + + UINT64 n64RequiredSize = 0; + SIZE_T szMemToAlloc = static_cast(sizeof(D3D12_PLACED_SUBRESOURCE_FOOTPRINT) + + sizeof(UINT) + + sizeof(UINT64)) + * nNumSubresources; + + void* pMem = GRS_CALLOC(static_cast(szMemToAlloc)); + + if (nullptr == pMem) + { + throw CGRSCOMException(HRESULT_FROM_WIN32(GetLastError())); + } + + D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts = reinterpret_cast(pMem); + UINT64* pRowSizesInBytes = reinterpret_cast(pLayouts + nNumSubresources); + UINT* pNumRows = reinterpret_cast(pRowSizesInBytes + nNumSubresources); + + // 这里是第二次调用GetCopyableFootprints,就得到了所有子资源的详细信息 + pThdPms->m_pID3D12Device4->GetCopyableFootprints(&stDefaultResDesc, nFirstSubresource, nNumSubresources, 0, pLayouts, pNumRows, pRowSizesInBytes, &n64RequiredSize); + + BYTE* pData = nullptr; + GRS_THROW_IF_FAILED(pITextureUpload->Map(0, nullptr, reinterpret_cast(&pData))); + + // 第一遍Copy!注意3重循环每重的意思 + for (UINT nSubRes = 0; nSubRes < nNumSubresources; ++nSubRes) + {// SubResources + if (pRowSizesInBytes[nSubRes] > (SIZE_T)-1) + { + throw CGRSCOMException(E_FAIL); + } + + D3D12_MEMCPY_DEST stCopyDestData = { pData + pLayouts[nSubRes].Offset + , pLayouts[nSubRes].Footprint.RowPitch + , pLayouts[nSubRes].Footprint.RowPitch * pNumRows[nSubRes] + }; + + for (UINT z = 0; z < pLayouts[nSubRes].Footprint.Depth; ++z) + {// Mipmap + BYTE* pDestSlice = reinterpret_cast(stCopyDestData.pData) + stCopyDestData.SlicePitch * z; + const BYTE* pSrcSlice = reinterpret_cast(stArSubResources[nSubRes].pData) + stArSubResources[nSubRes].SlicePitch * z; + for (UINT y = 0; y < pNumRows[nSubRes]; ++y) + {// Rows + memcpy(pDestSlice + stCopyDestData.RowPitch * y, + pSrcSlice + stArSubResources[nSubRes].RowPitch * y, + (SIZE_T)pRowSizesInBytes[nSubRes]); + } + } + } + pITextureUpload->Unmap(0, nullptr); + + // 第二次Copy! + if (stDefaultResDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) + {// Buffer 一次性复制就可以了,因为没有行对齐和行大小不一致的问题,Buffer中行数就是1 + pThdPms->m_pICMDList->CopyBufferRegion( + pITexture.Get(), 0, pITextureUpload.Get(), pLayouts[0].Offset, pLayouts[0].Footprint.Width); + } + else + { + for (UINT nSubRes = 0; nSubRes < nNumSubresources; ++nSubRes) + { + D3D12_TEXTURE_COPY_LOCATION stDstCopyLocation = {}; + stDstCopyLocation.pResource = pITexture.Get(); + stDstCopyLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + stDstCopyLocation.SubresourceIndex = nSubRes; + + D3D12_TEXTURE_COPY_LOCATION stSrcCopyLocation = {}; + stSrcCopyLocation.pResource = pITextureUpload.Get(); + stSrcCopyLocation.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + stSrcCopyLocation.PlacedFootprint = pLayouts[nSubRes]; + + pThdPms->m_pICMDList->CopyTextureRegion(&stDstCopyLocation, 0, 0, 0, &stSrcCopyLocation, nullptr); + } + } + GRS_SAFE_FREE(pMem); //同步 - pThdPms->m_pICMDList->ResourceBarrier(1 - , &CD3DX12_RESOURCE_BARRIER::Transition(pITexture.Get() - , D3D12_RESOURCE_STATE_COPY_DEST - , D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)); + stResStateTransBarrier.Transition.pResource = pITexture.Get(); + stResStateTransBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST; + stResStateTransBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE; + + pThdPms->m_pICMDList->ResourceBarrier(1, &stResStateTransBarrier); } //2、创建描述符堆 @@ -2269,10 +2602,8 @@ UINT __stdcall RenderThread(void* pParam) stSRVDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; stSRVDesc.Texture2D.MipLevels = 1; - CD3DX12_CPU_DESCRIPTOR_HANDLE stCbvSrvHandle( - pISRVHeap->GetCPUDescriptorHandleForHeapStart() - , 1 - , nSRVDescriptorSize); + D3D12_CPU_DESCRIPTOR_HANDLE stCbvSrvHandle = pISRVHeap->GetCPUDescriptorHandleForHeapStart(); + stCbvSrvHandle.ptr += nSRVDescriptorSize; pThdPms->m_pID3D12Device4->CreateShaderResourceView( pITexture.Get() @@ -2282,10 +2613,11 @@ UINT __stdcall RenderThread(void* pParam) //3、创建常量缓冲 { + stBufferResSesc.Width = szMVPBuf; //注意缓冲尺寸设置为256边界对齐大小 GRS_THROW_IF_FAILED(pThdPms->m_pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD) + &stUploadHeapProps , D3D12_HEAP_FLAG_NONE - , &CD3DX12_RESOURCE_DESC::Buffer(szMVPBuf) //注意缓冲尺寸设置为256边界对齐大小 + , &stBufferResSesc , D3D12_RESOURCE_STATE_GENERIC_READ , nullptr , IID_PPV_ARGS(&pICBWVP))); @@ -2299,7 +2631,7 @@ UINT __stdcall RenderThread(void* pParam) stCBVDesc.BufferLocation = pICBWVP->GetGPUVirtualAddress(); stCBVDesc.SizeInBytes = static_cast(szMVPBuf); - CD3DX12_CPU_DESCRIPTOR_HANDLE stCbvSrvHandle(pISRVHeap->GetCPUDescriptorHandleForHeapStart()); + D3D12_CPU_DESCRIPTOR_HANDLE stCbvSrvHandle = pISRVHeap->GetCPUDescriptorHandleForHeapStart(); pThdPms->m_pID3D12Device4->CreateConstantBufferView(&stCBVDesc, stCbvSrvHandle); } @@ -2339,10 +2671,11 @@ UINT __stdcall RenderThread(void* pParam) nIndexCnt = nVertexCnt; //创建 Vertex Buffer 仅使用Upload隐式堆 + stBufferResSesc.Width = nVertexCnt * sizeof(ST_GRS_VERTEX); GRS_THROW_IF_FAILED(pThdPms->m_pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD) + &stUploadHeapProps , D3D12_HEAP_FLAG_NONE - , &CD3DX12_RESOURCE_DESC::Buffer(nVertexCnt * sizeof(ST_GRS_VERTEX)) + , &stBufferResSesc , D3D12_RESOURCE_STATE_GENERIC_READ , nullptr , IID_PPV_ARGS(&pIVB))); @@ -2350,7 +2683,7 @@ UINT __stdcall RenderThread(void* pParam) UINT8* pVertexDataBegin = nullptr; - CD3DX12_RANGE stReadRange(0, 0); + D3D12_RANGE stReadRange = { 0, 0 }; //使用map-memcpy-unmap大法将数据传至顶点缓冲对象 GRS_THROW_IF_FAILED(pIVB->Map(0 @@ -2360,10 +2693,11 @@ UINT __stdcall RenderThread(void* pParam) pIVB->Unmap(0, nullptr); //创建 Index Buffer 仅使用Upload隐式堆 + stBufferResSesc.Width = nIndexCnt * sizeof(UINT); GRS_THROW_IF_FAILED(pThdPms->m_pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD) + &stUploadHeapProps , D3D12_HEAP_FLAG_NONE - , &CD3DX12_RESOURCE_DESC::Buffer(nIndexCnt * sizeof(UINT)) + , &stBufferResSesc , D3D12_RESOURCE_STATE_GENERIC_READ , nullptr , IID_PPV_ARGS(&pIIB))); @@ -2386,8 +2720,8 @@ UINT __stdcall RenderThread(void* pParam) stIBV.Format = DXGI_FORMAT_R32_UINT; stIBV.SizeInBytes = nIndexCnt * sizeof(UINT); - ::HeapFree(::GetProcessHeap(), 0, pstVertices); - ::HeapFree(::GetProcessHeap(), 0, pnIndices); + GRS_SAFE_FREE(pstVertices); + GRS_SAFE_FREE(pnIndices); } //6、设置事件对象 通知并切回主线程 完成资源的第二个Copy命令 @@ -2461,12 +2795,9 @@ UINT __stdcall RenderThread(void* pParam) //--------------------------------------------------------------------------------------------- //设置对应的渲染目标和视裁剪框(这是渲染子线程必须要做的步骤,基本也就是所谓多线程渲染的核心秘密所在了) { - CD3DX12_CPU_DESCRIPTOR_HANDLE stRTVHandle( - pThdPms->m_pIRTVHeap->GetCPUDescriptorHandleForHeapStart() - , pThdPms->m_nCurrentFrameIndex - , nRTVDescriptorSize); - CD3DX12_CPU_DESCRIPTOR_HANDLE stDSVHandle( - pThdPms->m_pIDSVHeap->GetCPUDescriptorHandleForHeapStart()); + D3D12_CPU_DESCRIPTOR_HANDLE stRTVHandle = pThdPms->m_pIRTVHeap->GetCPUDescriptorHandleForHeapStart(); + stRTVHandle.ptr += (pThdPms->m_nCurrentFrameIndex * nRTVDescriptorSize); + D3D12_CPU_DESCRIPTOR_HANDLE stDSVHandle = pThdPms->m_pIDSVHeap->GetCPUDescriptorHandleForHeapStart(); //设置渲染目标 pThdPms->m_pICMDList->OMSetRenderTargets(1, &stRTVHandle, FALSE, &stDSVHandle); pThdPms->m_pICMDList->RSSetViewports(1, &g_stViewPort); @@ -2483,14 +2814,14 @@ UINT __stdcall RenderThread(void* pParam) arDesHeaps.Add(pISRVHeap.Get()); arDesHeaps.Add(pISampleHeap.Get()); - pThdPms->m_pICMDList->SetDescriptorHeaps(static_cast(arDesHeaps.GetCount()),arDesHeaps.GetData()); + pThdPms->m_pICMDList->SetDescriptorHeaps(static_cast(arDesHeaps.GetCount()), arDesHeaps.GetData()); - CD3DX12_GPU_DESCRIPTOR_HANDLE stSRVHandle(pISRVHeap->GetGPUDescriptorHandleForHeapStart()); + D3D12_GPU_DESCRIPTOR_HANDLE stSRVHandle = pISRVHeap->GetGPUDescriptorHandleForHeapStart(); //设置CBV pThdPms->m_pICMDList->SetGraphicsRootDescriptorTable(0, stSRVHandle); //偏移至Texture的View - stSRVHandle.Offset(1, nSRVDescriptorSize); + stSRVHandle.ptr += nSRVDescriptorSize; //设置SRV pThdPms->m_pICMDList->SetGraphicsRootDescriptorTable(1, stSRVHandle); @@ -2536,7 +2867,7 @@ UINT __stdcall RenderThread(void* pParam) } } } - catch (CGRSCOMException & e) + catch (CGRSCOMException& e) { e; } @@ -2727,12 +3058,8 @@ BOOL LoadMeshVertex(const CHAR* pszMeshFileName, UINT& nVertexCnt, ST_GRS_VERTEX fin.get(input); fin.get(input); - ppVertex = (ST_GRS_VERTEX*)HeapAlloc(::GetProcessHeap() - , HEAP_ZERO_MEMORY - , nVertexCnt * sizeof(ST_GRS_VERTEX)); - ppIndices = (UINT*)HeapAlloc(::GetProcessHeap() - , HEAP_ZERO_MEMORY - , nVertexCnt * sizeof(UINT)); + ppVertex = (ST_GRS_VERTEX*)GRS_ALLOC(nVertexCnt * sizeof(ST_GRS_VERTEX)); + ppIndices = (UINT*)GRS_ALLOC(nVertexCnt * sizeof(UINT)); for (UINT i = 0; i < nVertexCnt; i++) { @@ -2744,7 +3071,7 @@ BOOL LoadMeshVertex(const CHAR* pszMeshFileName, UINT& nVertexCnt, ST_GRS_VERTEX ppIndices[i] = i; } } - catch (CGRSCOMException & e) + catch (CGRSCOMException& e) { e; bRet = FALSE; diff --git a/11-MultiThreadAndAdapter/11-MultiThreadAndAdapter.vcxproj b/11-MultiThreadAndAdapter/11-MultiThreadAndAdapter.vcxproj index 5749940bd831f611acc0c96d7aec726c3c194015..131ed476f3dbfcd455b943aa8bad1b11a3ea367c 100644 --- a/11-MultiThreadAndAdapter/11-MultiThreadAndAdapter.vcxproj +++ b/11-MultiThreadAndAdapter/11-MultiThreadAndAdapter.vcxproj @@ -148,12 +148,6 @@ - - true - true - true - true - false false diff --git a/11-MultiThreadAndAdapter/11-MultiThreadAndAdapter.vcxproj.filters b/11-MultiThreadAndAdapter/11-MultiThreadAndAdapter.vcxproj.filters index 481ba079bc43d06fbaa71d7d28111ebffe0560df..999e8aa8b9ec4d809c5cf99fdb543e2e1d46b1c0 100644 --- a/11-MultiThreadAndAdapter/11-MultiThreadAndAdapter.vcxproj.filters +++ b/11-MultiThreadAndAdapter/11-MultiThreadAndAdapter.vcxproj.filters @@ -21,9 +21,6 @@ 婧愭枃浠 - - 婧愭枃浠 - 婧愭枃浠 diff --git a/11-MultiThreadAndAdapter/11-MultiThreadAndAdapter_NoMultiThread.cpp b/11-MultiThreadAndAdapter/11-MultiThreadAndAdapter_NoMultiThread.cpp deleted file mode 100644 index 307cc9d9e50cc9fe9bb77c79ecbca0d0557f99ee..0000000000000000000000000000000000000000 --- a/11-MultiThreadAndAdapter/11-MultiThreadAndAdapter_NoMultiThread.cpp +++ /dev/null @@ -1,2339 +0,0 @@ -#include -#define WIN32_LEAN_AND_MEAN // 从 Windows 头中排除极少使用的资料 -#include -#include -#include //for ifstream -#include //添加WTL支持 方便使用COM -#include //for T2A -#include //for atl array -#include //for StringCchxxxxx function -#include -#include //for d3d12 -#include -#if defined(_DEBUG) -#include -#endif -#include -#include "..\WindowsCommons\d3dx12.h" -#include "..\WindowsCommons\DDSTextureLoader12.h" - -using namespace std; -using namespace Microsoft; -using namespace Microsoft::WRL; -using namespace DirectX; - -#pragma comment(lib, "dxguid.lib") -#pragma comment(lib, "dxgi.lib") -#pragma comment(lib, "d3d12.lib") -#pragma comment(lib, "d3dcompiler.lib") - -#define GRS_WND_CLASS_NAME _T("GRS Game Window Class") -#define GRS_WND_TITLE _T("GRS D3D12 MultiThread & MultiAdapter Sample") - -#define GRS_SAFE_RELEASE(p) if(p){(p)->Release();(p)=nullptr;} -#define GRS_THROW_IF_FAILED(hr) {HRESULT _hr = (hr);if (FAILED(_hr)){ throw CGRSCOMException(_hr); }} - -//新定义的宏用于上取整除法 -#define GRS_UPPER_DIV(A,B) ((UINT)(((A)+((B)-1))/(B))) -//更简洁的向上边界对齐算法 内存管理中常用 请记住 -#define GRS_UPPER(A,B) ((UINT)(((A)+((B)-1))&~(B - 1))) - -//------------------------------------------------------------------------------------------------------------ -// 为了调试加入下面的内联函数和宏定义,为每个接口对象设置名称,方便查看调试输出 -#if defined(_DEBUG) -inline void GRS_SetD3D12DebugName(ID3D12Object* pObject, LPCWSTR name) -{ - pObject->SetName(name); -} - -inline void GRS_SetD3D12DebugNameIndexed(ID3D12Object* pObject, LPCWSTR name, UINT index) -{ - WCHAR _DebugName[MAX_PATH] = {}; - if (SUCCEEDED(StringCchPrintfW(_DebugName, _countof(_DebugName), L"%s[%u]", name, index))) - { - pObject->SetName(_DebugName); - } -} -#else - -inline void GRS_SetD3D12DebugName(ID3D12Object*, LPCWSTR) -{ -} -inline void GRS_SetD3D12DebugNameIndexed(ID3D12Object*, LPCWSTR, UINT) -{ -} - -#endif - -#define GRS_SET_D3D12_DEBUGNAME(x) GRS_SetD3D12DebugName(x, L#x) -#define GRS_SET_D3D12_DEBUGNAME_INDEXED(x, n) GRS_SetD3D12DebugNameIndexed(x[n], L#x, n) - -#define GRS_SET_D3D12_DEBUGNAME_COMPTR(x) GRS_SetD3D12DebugName(x.Get(), L#x) -#define GRS_SET_D3D12_DEBUGNAME_INDEXED_COMPTR(x, n) GRS_SetD3D12DebugNameIndexed(x[n].Get(), L#x, n) - -#if defined(_DEBUG) -inline void GRS_SetDXGIDebugName(IDXGIObject* pObject, LPCWSTR name) -{ - size_t szLen = 0; - StringCchLengthW(name, 50, &szLen); - pObject->SetPrivateData(WKPDID_D3DDebugObjectName, static_cast(szLen - 1), name); -} - -inline void GRS_SetDXGIDebugNameIndexed(IDXGIObject* pObject, LPCWSTR name, UINT index) -{ - size_t szLen = 0; - WCHAR _DebugName[MAX_PATH] = {}; - if (SUCCEEDED(StringCchPrintfW(_DebugName, _countof(_DebugName), L"%s[%u]", name, index))) - { - StringCchLengthW(_DebugName, _countof(_DebugName), &szLen); - pObject->SetPrivateData(WKPDID_D3DDebugObjectName, static_cast(szLen), _DebugName); - } -} -#else - -inline void GRS_SetDXGIDebugName(IDXGIObject*, LPCWSTR) -{ -} -inline void GRS_SetDXGIDebugNameIndexed(IDXGIObject*, LPCWSTR, UINT) -{ -} - -#endif - -#define GRS_SET_DXGI_DEBUGNAME(x) GRS_SetDXGIDebugName(x, L#x) -#define GRS_SET_DXGI_DEBUGNAME_INDEXED(x, n) GRS_SetDXGIDebugNameIndexed(x[n], L#x, n) - -#define GRS_SET_DXGI_DEBUGNAME_COMPTR(x) GRS_SetDXGIDebugName(x.Get(), L#x) -#define GRS_SET_DXGI_DEBUGNAME_INDEXED_COMPTR(x, n) GRS_SetDXGIDebugNameIndexed(x[n].Get(), L#x, n) -//------------------------------------------------------------------------------------------------------------ - -class CGRSCOMException -{ -public: - CGRSCOMException(HRESULT hr) : m_hrError(hr) - { - } - HRESULT Error() const - { - return m_hrError; - } -private: - const HRESULT m_hrError; -}; - -const UINT g_nFrameBackBufCount = 3u; -// 显卡参数集合 -struct ST_GRS_GPU_PARAMS -{ - UINT m_nIndex; - UINT m_nRTVDescriptorSize; - UINT m_nSRVDescriptorSize; - HANDLE m_hEventFence; - - ComPtr m_pID3D12Device4; - ComPtr m_pICMDQueue; - - ComPtr m_pIRTRes[g_nFrameBackBufCount]; - ComPtr m_pIRTVHeap; - ComPtr m_pIDSRes; - ComPtr m_pIDSVHeap; - - ComPtr m_pISRVHeap; - ComPtr m_pISampleHeap; - - ComPtr m_pIRS; - ComPtr m_pIPSO; - - ComPtr m_pICrossAdapterHeap; - ComPtr m_pICrossAdapterResPerFrame[g_nFrameBackBufCount]; - - ComPtr m_pICMDAlloc; - ComPtr m_pICMDList; - - ComPtr m_pIFence; - ComPtr m_pISharedFence; -}; - -// 常量缓冲区 -struct ST_GRS_MVP -{ - XMFLOAT4X4 m_MVP; //经典的Model-view-projection(MVP)矩阵. -}; - -// 场景物体参数 -struct ST_GRS_MODULE_PARAMS -{ - UINT m_nModuleIndex; - - XMFLOAT4 m_v4ModelPos; - TCHAR m_pszDDSFile[MAX_PATH]; - CHAR m_pszMeshFile[MAX_PATH]; - UINT m_nVertexCnt; - UINT m_nIndexCnt; - - ComPtr m_pIVertexBuffer; - ComPtr m_pIIndexsBuffer; - ComPtr m_pITexture; - ComPtr m_pITextureUpload; - ComPtr m_pICBRes; - - ComPtr m_pSRVHeap; - ComPtr m_pISampleHeap; - - ComPtr m_pIBundleAlloc; - ComPtr m_pIBundle; - - ST_GRS_MVP* m_pMVPBuf; - D3D12_VERTEX_BUFFER_VIEW m_stVertexBufferView; - D3D12_INDEX_BUFFER_VIEW m_stIndexsBufferView; -}; - -struct ST_GRS_PEROBJECT_CB -{ - UINT m_nFun; - float m_fQuatLevel; //量化bit数,取值2-6 - float m_fWaterPower; //表示水彩扩展力度,单位为像素 -}; - -// 顶点结构 -struct ST_GRS_VERTEX_MODULE -{ - XMFLOAT4 m_v4Position; //Position - XMFLOAT2 m_vTex; //Texcoord - XMFLOAT3 m_vNor; //Normal -}; - -// 辅助显卡上渲染单位矩形的顶点结构 -struct ST_GRS_VERTEX_QUAD -{ - XMFLOAT4 m_v4Position; //Position - XMFLOAT2 m_vTex; //Texcoord -}; - -//初始的默认摄像机的位置 -XMFLOAT3 g_f3EyePos = XMFLOAT3(0.0f, 5.0f, -10.0f); //眼睛位置 -XMFLOAT3 g_f3LockAt = XMFLOAT3(0.0f, 0.0f, 0.0f); //眼睛所盯的位置 -XMFLOAT3 g_f3HeapUp = XMFLOAT3(0.0f, 1.0f, 0.0f); //头部正上方位置 - -float g_fYaw = 0.0f; // 绕正Z轴的旋转量. -float g_fPitch = 0.0f; // 绕XZ平面的旋转量 -double g_fPalstance = 10.0f * XM_PI / 180.0f; //物体旋转的角速度,单位:弧度/秒 - -//后处理需要的参数,设置为全局变量方便在窗口过程中根据按键输入调整 -UINT g_nFunNO = 0; //当前使用效果函数的序号(按空格键循环切换) -UINT g_nMaxFunNO = 2; //总的效果函数个数 -float g_fQuatLevel = 2.0f; //量化bit数,取值2-6 -float g_fWaterPower = 40.0f; //表示水彩扩展力度,单位为像素 - -//使用哪个版本PS做最后的模糊处理:0 原样输出 1 矩阵形式高斯模糊PS 2 双向分离优化后的高斯模糊PS(来自微软官方示例) -UINT g_nUsePSID = 1; - -LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); -BOOL LoadMeshVertex(const CHAR* pszMeshFileName, UINT& m_nVertexCnt, ST_GRS_VERTEX_MODULE*& ppVertex, UINT*& ppIndices); - -int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) -{ - try - { - TCHAR pszAppPath[MAX_PATH] = {}; - HWND hWnd = nullptr; - MSG msg = {}; - - int iWndWidth = 1024; - int iWndHeight = 768; - - UINT nDXGIFactoryFlags = 0U; - UINT nCurrentFrameIndex = 0u; - DXGI_FORMAT emRTFmt = DXGI_FORMAT_R8G8B8A8_UNORM; - DXGI_FORMAT emDSFmt = DXGI_FORMAT_D24_UNORM_S8_UINT; - - CD3DX12_VIEWPORT stViewPort(0.0f, 0.0f, static_cast(iWndWidth), static_cast(iWndHeight)); - CD3DX12_RECT stScissorRect(0, 0, static_cast(iWndWidth), static_cast(iWndHeight)); - - const UINT c_nMaxGPUCnt = 2; //演示仅支持两个GPU进行渲染 - const UINT c_nMainGPU = 0; - const UINT c_nSecondGPU = 1; - ST_GRS_GPU_PARAMS stGPU[c_nMaxGPUCnt] = {}; - - // 场景物体参数 - const UINT c_nMaxObjects = 3; - const UINT c_nSphere = 0; - const UINT c_nCube = 1; - const UINT c_nPlane = 2; - ST_GRS_MODULE_PARAMS stObject[c_nMaxObjects] = {}; - - // 常量缓冲区大小上对齐到256Bytes边界 - SIZE_T szMVPBuf = GRS_UPPER(sizeof(ST_GRS_MVP), 256); - - // 用于复制渲染结果的复制命令队列、命令分配器、命令列表对象 - ComPtr pICmdQueueCopy; - ComPtr pICmdAllocCopy; - ComPtr pICmdListCopy; - - //当不能直接共享资源时,就在辅助显卡上创建独立的资源,用于复制主显卡渲染结果过来 - ComPtr pISecondAdapterTexutrePerFrame[g_nFrameBackBufCount]; - BOOL bCrossAdapterTextureSupport = FALSE; - CD3DX12_RESOURCE_DESC stRenderTargetDesc = {}; - const float v4ClearColor[4] = { 0.2f, 0.5f, 1.0f, 1.0f }; - - ComPtr pIDXGIFactory5; - ComPtr pIDXGIFactory6; - ComPtr pISwapChain1; - ComPtr pISwapChain3; - - //辅助显卡上后处理需要的资源变量(Second Pass) - ComPtr pIOffLineRTRes[g_nFrameBackBufCount]; //离线渲染的渲染目标资源 - ComPtr pIRTVOffLine; //离线渲染RTV - - SIZE_T szSecondPassCB = GRS_UPPER(sizeof(ST_GRS_PEROBJECT_CB), 256); - ST_GRS_PEROBJECT_CB* pstCBSecondPass = nullptr; - ComPtr pICBResSecondPass; - ComPtr pIVBQuad; - ComPtr pIVBQuadUpload; - D3D12_VERTEX_BUFFER_VIEW pstVBVQuad; - ComPtr pINoiseTexture; - ComPtr pINoiseTextureUpload; - - //辅助显卡上用于高斯模糊后处理的资源变量(Third Pass) - ComPtr pICMDAllocThirdPass; - ComPtr pICMDListThirdPass; - ComPtr pIRSThirdPass; - ComPtr pIPSOThirdPass; - ComPtr pISRVHeapThirdPass; - ComPtr pISampleHeapThirdPass; - - ComPtr pIPSODoNothing; //简单的显示颜色的PS的管线状态对象 - ComPtr pIPSOBothwayBlur; //双向高斯模糊的合并版 - - CAtlArray arHWaited; - UINT64 n64CurrentFenceValue = 0; - UINT64 n64FenceValue = 1ui64; - - GRS_THROW_IF_FAILED(::CoInitialize(nullptr)); - // 得到当前的工作目录,方便我们使用相对路径来访问各种资源文件 - { - UINT nBytes = GetCurrentDirectory(MAX_PATH, pszAppPath); - if (MAX_PATH == nBytes) - { - GRS_THROW_IF_FAILED(HRESULT_FROM_WIN32(GetLastError())); - } - - WCHAR* lastSlash = _tcsrchr(pszAppPath, _T('\\')); - if (lastSlash) - { - *(lastSlash + 1) = _T('\0'); - } - } - - // 创建窗口 - { - //--------------------------------------------------------------------------------------------- - WNDCLASSEX wcex = {}; - wcex.cbSize = sizeof(WNDCLASSEX); - wcex.style = CS_GLOBALCLASS; - wcex.lpfnWndProc = WndProc; - wcex.cbClsExtra = 0; - wcex.cbWndExtra = 0; - wcex.hInstance = hInstance; - wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); - wcex.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH); //防止无聊的背景重绘 - wcex.lpszClassName = GRS_WND_CLASS_NAME; - RegisterClassEx(&wcex); - - DWORD dwWndStyle = WS_OVERLAPPED | WS_SYSMENU; - RECT rtWnd = { 0, 0, iWndWidth, iWndHeight }; - AdjustWindowRect(&rtWnd, dwWndStyle, FALSE); - - // 计算窗口居中的屏幕坐标 - INT posX = (GetSystemMetrics(SM_CXSCREEN) - rtWnd.right - rtWnd.left) / 2; - INT posY = (GetSystemMetrics(SM_CYSCREEN) - rtWnd.bottom - rtWnd.top) / 2; - - hWnd = CreateWindowW(GRS_WND_CLASS_NAME, GRS_WND_TITLE, dwWndStyle - , posX, posY, rtWnd.right - rtWnd.left, rtWnd.bottom - rtWnd.top - , nullptr, nullptr, hInstance, nullptr); - - if (!hWnd) - { - throw CGRSCOMException(HRESULT_FROM_WIN32(GetLastError())); - } - } - - // 打开显示子系统的调试支持 - { -#if defined(_DEBUG) - ComPtr pIDebugController; - if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&pIDebugController)))) - { - pIDebugController->EnableDebugLayer(); - // 打开附加的调试支持 - nDXGIFactoryFlags |= DXGI_CREATE_FACTORY_DEBUG; - } -#endif - } - - // 创建DXGI Factory对象 - { - GRS_THROW_IF_FAILED(CreateDXGIFactory2(nDXGIFactoryFlags, IID_PPV_ARGS(&pIDXGIFactory5))); - GRS_SET_DXGI_DEBUGNAME_COMPTR(pIDXGIFactory5); - // 关闭ALT+ENTER键切换全屏的功能,因为我们没有实现OnSize处理,所以先关闭 - GRS_THROW_IF_FAILED(pIDXGIFactory5->MakeWindowAssociation(hWnd, DXGI_MWA_NO_ALT_ENTER)); - //获取IDXGIFactory6接口 - GRS_THROW_IF_FAILED(pIDXGIFactory5.As(&pIDXGIFactory6)); - GRS_SET_DXGI_DEBUGNAME_COMPTR(pIDXGIFactory6); - } - - // 枚举适配器创建设备 - { - D3D12_COMMAND_QUEUE_DESC stQueueDesc = {}; - stQueueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; - - D3D12_FEATURE_DATA_ARCHITECTURE stArchitecture = {}; - DXGI_ADAPTER_DESC1 stAdapterDesc[c_nMaxGPUCnt] = {}; - - IDXGIAdapter1* pIAdapterTmp = nullptr; - ID3D12Device4* pID3DDeviceTmp = nullptr; - IDXGIOutput* pIOutput = nullptr; - - HRESULT hrEnumOutput = S_OK; - UINT i = 0; - for (i = 0; - (i < c_nMaxGPUCnt) && - SUCCEEDED(pIDXGIFactory6->EnumAdapterByGpuPreference( - i - , DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE - , IID_PPV_ARGS(&pIAdapterTmp))); - ++i) - { - GRS_THROW_IF_FAILED(pIAdapterTmp->GetDesc1(&stAdapterDesc[i])); - - if (stAdapterDesc[i].Flags & DXGI_ADAPTER_FLAG_SOFTWARE) - {//跳过软件虚拟适配器设备, - //注释这个if判断,可以使用一个真实GPU和一个虚拟软适配器来看双GPU的示例 - continue; - } - - GRS_THROW_IF_FAILED(D3D12CreateDevice(pIAdapterTmp - , D3D_FEATURE_LEVEL_12_1 - , IID_PPV_ARGS(&stGPU[i].m_pID3D12Device4))); - - GRS_SET_D3D12_DEBUGNAME_COMPTR(stGPU[i].m_pID3D12Device4); - - GRS_THROW_IF_FAILED( - stGPU[i].m_pID3D12Device4->CreateCommandQueue( - &stQueueDesc, IID_PPV_ARGS(&stGPU[i].m_pICMDQueue))); - GRS_SetD3D12DebugNameIndexed(stGPU[i].m_pICMDQueue.Get(), _T("m_pICMDQueue"), i); - - stGPU[i].m_nIndex = i; - stGPU[i].m_nRTVDescriptorSize - = stGPU[i].m_pID3D12Device4->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); - stGPU[i].m_nSRVDescriptorSize - = stGPU[i].m_pID3D12Device4->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - - GRS_SAFE_RELEASE(pIAdapterTmp); - } - - //--------------------------------------------------------------------------------------------- - if (nullptr == stGPU[c_nMainGPU].m_pID3D12Device4.Get() - || nullptr == stGPU[c_nSecondGPU].m_pID3D12Device4.Get()) - {// 可怜的机器上居然没有两个以上的显卡 还是先退出了事 当然你可以使用软适配器凑活看下例子 - OutputDebugString(_T("\n机器中显卡数量不足两个,示例程序退出!\n")); - throw CGRSCOMException(E_FAIL); - } - - //复制命令队列创建在独显上,因为独显的性能强悍一些 - stQueueDesc.Type = D3D12_COMMAND_LIST_TYPE_COPY; - GRS_THROW_IF_FAILED( - stGPU[c_nMainGPU].m_pID3D12Device4->CreateCommandQueue( - &stQueueDesc, IID_PPV_ARGS(&pICmdQueueCopy))); - GRS_SET_D3D12_DEBUGNAME_COMPTR(pICmdQueueCopy); - - //将被使用的设备名称显示到窗口标题里 - TCHAR pszWndTitle[MAX_PATH] = {}; - ::GetWindowText(hWnd, pszWndTitle, MAX_PATH); - StringCchPrintf(pszWndTitle - , MAX_PATH - , _T("%s(GPU[0]:%s & GPU[1]:%s)") - , pszWndTitle - , stAdapterDesc[c_nMainGPU].Description - , stAdapterDesc[c_nSecondGPU].Description); - ::SetWindowText(hWnd, pszWndTitle); - } - - // 创建围栏对象,以及多GPU同步围栏对象 - { - for (int i = 0; i < c_nMaxGPUCnt; i++) - { - GRS_THROW_IF_FAILED( - stGPU[i].m_pID3D12Device4->CreateFence( - 0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&stGPU[i].m_pIFence))); - GRS_SET_D3D12_DEBUGNAME_COMPTR(stGPU[i].m_pIFence); - - stGPU[i].m_hEventFence = CreateEvent(nullptr, FALSE, FALSE, nullptr); - if (stGPU[i].m_hEventFence == nullptr) - { - GRS_THROW_IF_FAILED(HRESULT_FROM_WIN32(GetLastError())); - } - } - - // 在主显卡上创建一个可共享的围栏对象 - GRS_THROW_IF_FAILED(stGPU[c_nMainGPU].m_pID3D12Device4->CreateFence(0 - , D3D12_FENCE_FLAG_SHARED | D3D12_FENCE_FLAG_SHARED_CROSS_ADAPTER - , IID_PPV_ARGS(&stGPU[c_nMainGPU].m_pISharedFence))); - GRS_SET_D3D12_DEBUGNAME_COMPTR(stGPU[c_nMainGPU].m_pISharedFence); - - // 共享这个围栏,通过句柄方式 - HANDLE hFenceShared = nullptr; - GRS_THROW_IF_FAILED(stGPU[c_nMainGPU].m_pID3D12Device4->CreateSharedHandle( - stGPU[c_nMainGPU].m_pISharedFence.Get(), - nullptr, - GENERIC_ALL, - nullptr, - &hFenceShared)); - - // 在辅助显卡上打开这个围栏对象完成共享 - HRESULT hrOpenSharedHandleResult - = stGPU[c_nSecondGPU].m_pID3D12Device4->OpenSharedHandle(hFenceShared - , IID_PPV_ARGS(&stGPU[c_nSecondGPU].m_pISharedFence)); - GRS_SET_D3D12_DEBUGNAME_COMPTR(stGPU[c_nSecondGPU].m_pISharedFence); - // 先关闭句柄,再判定是否共享成功 - ::CloseHandle(hFenceShared); - GRS_THROW_IF_FAILED(hrOpenSharedHandleResult); - } - - // 创建命令列表 - { - WCHAR pszDebugName[MAX_PATH] = {}; - for (int i = 0; i < c_nMaxGPUCnt; i++) - { - GRS_THROW_IF_FAILED( - stGPU[i].m_pID3D12Device4->CreateCommandAllocator( - D3D12_COMMAND_LIST_TYPE_DIRECT - , IID_PPV_ARGS(&stGPU[i].m_pICMDAlloc))); - - if (SUCCEEDED(StringCchPrintfW(pszDebugName, MAX_PATH, L"stGPU[%u].m_pICMDAlloc", i))) - { - stGPU[i].m_pICMDAlloc->SetName(pszDebugName); - } - - // 创建每个GPU的命令列表对象 - GRS_THROW_IF_FAILED(stGPU[i].m_pID3D12Device4->CreateCommandList(0 - , D3D12_COMMAND_LIST_TYPE_DIRECT - , stGPU[i].m_pICMDAlloc.Get() - , nullptr - , IID_PPV_ARGS(&stGPU[i].m_pICMDList))); - - if (SUCCEEDED(StringCchPrintfW(pszDebugName, MAX_PATH, L"stGPU[%u].m_pICMDList", i))) - { - stGPU[i].m_pICMDList->SetName(pszDebugName); - } - } - - // 在主显卡上创建复制命令列表(所谓能力越强,责任也就越大!) - GRS_THROW_IF_FAILED( - stGPU[c_nMainGPU].m_pID3D12Device4->CreateCommandAllocator( - D3D12_COMMAND_LIST_TYPE_COPY - , IID_PPV_ARGS(&pICmdAllocCopy))); - GRS_SET_D3D12_DEBUGNAME_COMPTR(pICmdAllocCopy); - - GRS_THROW_IF_FAILED(stGPU[c_nMainGPU].m_pID3D12Device4->CreateCommandList(0 - , D3D12_COMMAND_LIST_TYPE_COPY - , pICmdAllocCopy.Get() - , nullptr - , IID_PPV_ARGS(&pICmdListCopy))); - GRS_SET_D3D12_DEBUGNAME_COMPTR(pICmdListCopy); - - // 在辅助显卡上创建Third Pass 渲染需要的命令分配器和命令列表 - GRS_THROW_IF_FAILED( - stGPU[c_nSecondGPU].m_pID3D12Device4->CreateCommandAllocator( - D3D12_COMMAND_LIST_TYPE_DIRECT - , IID_PPV_ARGS(&pICMDAllocThirdPass))); - GRS_SET_D3D12_DEBUGNAME_COMPTR(pICMDAllocThirdPass); - - GRS_THROW_IF_FAILED( - stGPU[c_nSecondGPU].m_pID3D12Device4->CreateCommandList(0 - , D3D12_COMMAND_LIST_TYPE_DIRECT - , pICMDAllocThirdPass.Get() - , nullptr - , IID_PPV_ARGS(&pICMDListThirdPass))); - GRS_SET_D3D12_DEBUGNAME_COMPTR(pICMDListThirdPass); - } - - // 创建交换链 - { - DXGI_SWAP_CHAIN_DESC1 stSwapChainDesc = {}; - stSwapChainDesc.BufferCount = g_nFrameBackBufCount; - stSwapChainDesc.Width = iWndWidth; - stSwapChainDesc.Height = iWndHeight; - stSwapChainDesc.Format = emRTFmt; - stSwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - stSwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; - stSwapChainDesc.SampleDesc.Count = 1; - - GRS_THROW_IF_FAILED(pIDXGIFactory5->CreateSwapChainForHwnd( - stGPU[c_nSecondGPU].m_pICMDQueue.Get(), // 使用接驳了显示器的显卡的命令队列做为交换链的命令队列 - hWnd, - &stSwapChainDesc, - nullptr, - nullptr, - &pISwapChain1 - )); - GRS_SET_DXGI_DEBUGNAME_COMPTR(pISwapChain1); - - //注意此处使用了高版本的SwapChain接口的函数 - GRS_THROW_IF_FAILED(pISwapChain1.As(&pISwapChain3)); - GRS_SET_DXGI_DEBUGNAME_COMPTR(pISwapChain3); - - // 获取当前第一个供绘制的后缓冲序号 - nCurrentFrameIndex = pISwapChain3->GetCurrentBackBufferIndex(); - - //创建RTV(渲染目标视图)描述符堆(这里堆的含义应当理解为数组或者固定大小元素的固定大小显存池) - D3D12_DESCRIPTOR_HEAP_DESC stRTVHeapDesc = {}; - stRTVHeapDesc.NumDescriptors = g_nFrameBackBufCount; - stRTVHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; - stRTVHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; - - for (int i = 0; i < c_nMaxGPUCnt; i++) - { - GRS_THROW_IF_FAILED(stGPU[i].m_pID3D12Device4->CreateDescriptorHeap( - &stRTVHeapDesc, IID_PPV_ARGS(&stGPU[i].m_pIRTVHeap))); - GRS_SetD3D12DebugNameIndexed(stGPU[i].m_pIRTVHeap.Get(), _T("m_pIRTVHeap"), i); - } - - //Off-Line Render Target View - GRS_THROW_IF_FAILED(stGPU[c_nSecondGPU].m_pID3D12Device4->CreateDescriptorHeap( - &stRTVHeapDesc, IID_PPV_ARGS(&pIRTVOffLine))); - GRS_SET_D3D12_DEBUGNAME_COMPTR(pIRTVOffLine); - - CD3DX12_CLEAR_VALUE stClearValue(stSwapChainDesc.Format, v4ClearColor); - stRenderTargetDesc = CD3DX12_RESOURCE_DESC::Tex2D( - stSwapChainDesc.Format, - stSwapChainDesc.Width, - stSwapChainDesc.Height, - 1u, 1u, - stSwapChainDesc.SampleDesc.Count, - stSwapChainDesc.SampleDesc.Quality, - D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET, - D3D12_TEXTURE_LAYOUT_UNKNOWN, 0u); - - WCHAR pszDebugName[MAX_PATH] = {}; - CD3DX12_CPU_DESCRIPTOR_HANDLE stHRTVOffLine(pIRTVOffLine->GetCPUDescriptorHandleForHeapStart()); - for (UINT i = 0; i < c_nMaxGPUCnt; i++) - { - CD3DX12_CPU_DESCRIPTOR_HANDLE stRTVHandle(stGPU[i].m_pIRTVHeap->GetCPUDescriptorHandleForHeapStart()); - - for (UINT j = 0; j < g_nFrameBackBufCount; j++) - { - if (i == c_nSecondGPU) - { - GRS_THROW_IF_FAILED(pISwapChain3->GetBuffer(j, IID_PPV_ARGS(&stGPU[i].m_pIRTRes[j]))); - - // Create Second Adapter Off-Line Render Target - GRS_THROW_IF_FAILED(stGPU[i].m_pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), - D3D12_HEAP_FLAG_NONE, - &stRenderTargetDesc, - D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE, - &stClearValue, - IID_PPV_ARGS(&pIOffLineRTRes[j]))); - - GRS_SET_D3D12_DEBUGNAME_INDEXED_COMPTR(pIOffLineRTRes, j); - // Off-Line Render Target View - stGPU[i].m_pID3D12Device4->CreateRenderTargetView(pIOffLineRTRes[j].Get(), nullptr, stHRTVOffLine); - stHRTVOffLine.Offset(1, stGPU[i].m_nRTVDescriptorSize); - } - else - { - GRS_THROW_IF_FAILED(stGPU[i].m_pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), - D3D12_HEAP_FLAG_NONE, - &stRenderTargetDesc, - D3D12_RESOURCE_STATE_COMMON, - &stClearValue, - IID_PPV_ARGS(&stGPU[i].m_pIRTRes[j]))); - } - - StringCchPrintfW(pszDebugName, MAX_PATH, L"stGPU[%u].m_pIRTRes[%u]", i, j); - stGPU[i].m_pIRTRes[j]->SetName(pszDebugName); - - stGPU[i].m_pID3D12Device4->CreateRenderTargetView(stGPU[i].m_pIRTRes[j].Get(), nullptr, stRTVHandle); - stRTVHandle.Offset(1, stGPU[i].m_nRTVDescriptorSize); - } - - // 创建每个显卡上的深度蜡板缓冲区 - D3D12_CLEAR_VALUE stDepthOptimizedClearValue = {}; - stDepthOptimizedClearValue.Format = emDSFmt; - stDepthOptimizedClearValue.DepthStencil.Depth = 1.0f; - stDepthOptimizedClearValue.DepthStencil.Stencil = 0; - - //使用隐式默认堆创建一个深度蜡板缓冲区, - //因为基本上深度缓冲区会一直被使用,重用的意义不大,所以直接使用隐式堆,图方便 - GRS_THROW_IF_FAILED(stGPU[i].m_pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT) - , D3D12_HEAP_FLAG_NONE - , &CD3DX12_RESOURCE_DESC::Tex2D( - emDSFmt - , iWndWidth - , iWndHeight - , 1 - , 0 - , 1 - , 0 - , D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) - , D3D12_RESOURCE_STATE_DEPTH_WRITE - , &stDepthOptimizedClearValue - , IID_PPV_ARGS(&stGPU[i].m_pIDSRes) - )); - - StringCchPrintfW(pszDebugName, MAX_PATH, L"stGPU[%u].m_pIDSRes", i); - stGPU[i].m_pIDSRes->SetName(pszDebugName); - - - // Create DSV Heap - D3D12_DESCRIPTOR_HEAP_DESC stDSVHeapDesc = {}; - stDSVHeapDesc.NumDescriptors = 1; - stDSVHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV; - stDSVHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; - - GRS_THROW_IF_FAILED(stGPU[i].m_pID3D12Device4->CreateDescriptorHeap( - &stDSVHeapDesc, IID_PPV_ARGS(&stGPU[i].m_pIDSVHeap))); - GRS_SetD3D12DebugNameIndexed(stGPU[i].m_pIDSVHeap.Get(), _T("m_pIDSVHeap"), i); - - // Create DSV - D3D12_DEPTH_STENCIL_VIEW_DESC stDepthStencilDesc = {}; - stDepthStencilDesc.Format = emDSFmt; - stDepthStencilDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D; - stDepthStencilDesc.Flags = D3D12_DSV_FLAG_NONE; - - stGPU[i].m_pID3D12Device4->CreateDepthStencilView(stGPU[i].m_pIDSRes.Get() - , &stDepthStencilDesc - , stGPU[i].m_pIDSVHeap->GetCPUDescriptorHandleForHeapStart()); - } - } - - // 创建跨适配器的共享资源堆 - { - { - D3D12_FEATURE_DATA_D3D12_OPTIONS stOptions = {}; - // 通过检测带有显示输出的显卡是否支持跨显卡资源来决定跨显卡的资源如何创建 - GRS_THROW_IF_FAILED(stGPU[c_nSecondGPU].m_pID3D12Device4->CheckFeatureSupport( - D3D12_FEATURE_D3D12_OPTIONS, reinterpret_cast(&stOptions), sizeof(stOptions))); - - bCrossAdapterTextureSupport = stOptions.CrossAdapterRowMajorTextureSupported; - - UINT64 n64szTexture = 0; - D3D12_RESOURCE_DESC stCrossAdapterResDesc = {}; - - if (bCrossAdapterTextureSupport) - { - // 如果支持那么直接创建跨显卡资源堆 - stCrossAdapterResDesc = stRenderTargetDesc; - stCrossAdapterResDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_CROSS_ADAPTER; - stCrossAdapterResDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; - - D3D12_RESOURCE_ALLOCATION_INFO stTextureInfo - = stGPU[c_nMainGPU].m_pID3D12Device4->GetResourceAllocationInfo(0, 1, &stCrossAdapterResDesc); - n64szTexture = stTextureInfo.SizeInBytes; - } - else - { - // 如果不支持,那么我们就需要先在主显卡上创建用于复制渲染结果的资源堆,然后再共享堆到辅助显卡上 - D3D12_PLACED_SUBRESOURCE_FOOTPRINT stResLayout = {}; - stGPU[c_nMainGPU].m_pID3D12Device4->GetCopyableFootprints(&stRenderTargetDesc, 0, 1, 0, &stResLayout, nullptr, nullptr, nullptr); - n64szTexture = GRS_UPPER(stResLayout.Footprint.RowPitch * stResLayout.Footprint.Height, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT); - stCrossAdapterResDesc = CD3DX12_RESOURCE_DESC::Buffer(n64szTexture, D3D12_RESOURCE_FLAG_ALLOW_CROSS_ADAPTER); - } - - // 创建跨显卡共享的资源堆 - CD3DX12_HEAP_DESC stCrossHeapDesc( - n64szTexture * g_nFrameBackBufCount, - D3D12_HEAP_TYPE_DEFAULT, - 0, - D3D12_HEAP_FLAG_SHARED | D3D12_HEAP_FLAG_SHARED_CROSS_ADAPTER); - - GRS_THROW_IF_FAILED(stGPU[c_nMainGPU].m_pID3D12Device4->CreateHeap(&stCrossHeapDesc - , IID_PPV_ARGS(&stGPU[c_nMainGPU].m_pICrossAdapterHeap))); - - HANDLE hHeap = nullptr; - GRS_THROW_IF_FAILED(stGPU[c_nMainGPU].m_pID3D12Device4->CreateSharedHandle( - stGPU[c_nMainGPU].m_pICrossAdapterHeap.Get(), - nullptr, - GENERIC_ALL, - nullptr, - &hHeap)); - - HRESULT hrOpenSharedHandle = stGPU[c_nSecondGPU].m_pID3D12Device4->OpenSharedHandle(hHeap - , IID_PPV_ARGS(&stGPU[c_nSecondGPU].m_pICrossAdapterHeap)); - - // 先关闭句柄,再判定是否共享成功 - ::CloseHandle(hHeap); - - GRS_THROW_IF_FAILED(hrOpenSharedHandle); - - // 以定位方式在共享堆上创建每个显卡上的资源 - for (UINT i = 0; i < g_nFrameBackBufCount; i++) - { - GRS_THROW_IF_FAILED(stGPU[c_nMainGPU].m_pID3D12Device4->CreatePlacedResource( - stGPU[c_nMainGPU].m_pICrossAdapterHeap.Get(), - n64szTexture * i, - &stCrossAdapterResDesc, - D3D12_RESOURCE_STATE_COPY_DEST, - nullptr, - IID_PPV_ARGS(&stGPU[c_nMainGPU].m_pICrossAdapterResPerFrame[i]))); - - GRS_THROW_IF_FAILED(stGPU[c_nSecondGPU].m_pID3D12Device4->CreatePlacedResource( - stGPU[c_nSecondGPU].m_pICrossAdapterHeap.Get(), - n64szTexture * i, - &stCrossAdapterResDesc, - bCrossAdapterTextureSupport ? D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE : D3D12_RESOURCE_STATE_COPY_SOURCE, - nullptr, - IID_PPV_ARGS(&stGPU[c_nSecondGPU].m_pICrossAdapterResPerFrame[i]))); - - if (!bCrossAdapterTextureSupport) - { - // If the primary adapter's render target must be shared as a buffer, - // create a texture resource to copy it into on the secondary adapter. - GRS_THROW_IF_FAILED(stGPU[c_nSecondGPU].m_pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), - D3D12_HEAP_FLAG_NONE, - &stRenderTargetDesc, - D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, - nullptr, - IID_PPV_ARGS(&pISecondAdapterTexutrePerFrame[i]))); - } - } - - } - } - // 创建根签名 - {//这个例子中,所有物体使用相同的根签名,因为渲染过程中需要的参数是一样的 - D3D12_FEATURE_DATA_ROOT_SIGNATURE stFeatureData = {}; - - // 检测是否支持V1.1版本的根签名 - stFeatureData.HighestVersion = D3D_ROOT_SIGNATURE_VERSION_1_1; - if (FAILED(stGPU[c_nMainGPU].m_pID3D12Device4->CheckFeatureSupport(D3D12_FEATURE_ROOT_SIGNATURE - , &stFeatureData, sizeof(stFeatureData)))) - { - stFeatureData.HighestVersion = D3D_ROOT_SIGNATURE_VERSION_1_0; - } - - CD3DX12_DESCRIPTOR_RANGE1 stDSPRanges[3]; - stDSPRanges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0); - stDSPRanges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0); - stDSPRanges[2].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 1, 0); - - CD3DX12_ROOT_PARAMETER1 stRootParameters[3]; - stRootParameters[0].InitAsDescriptorTable(1, &stDSPRanges[0], D3D12_SHADER_VISIBILITY_ALL); //CBV是所有Shader可见 - stRootParameters[1].InitAsDescriptorTable(1, &stDSPRanges[1], D3D12_SHADER_VISIBILITY_PIXEL);//SRV仅PS可见 - stRootParameters[2].InitAsDescriptorTable(1, &stDSPRanges[2], D3D12_SHADER_VISIBILITY_PIXEL);//SAMPLE仅PS可见 - - CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC stRootSignatureDesc; - stRootSignatureDesc.Init_1_1(_countof(stRootParameters) - , stRootParameters - , 0 - , nullptr - , D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT); - - ComPtr pISignatureBlob; - ComPtr pIErrorBlob; - GRS_THROW_IF_FAILED(D3DX12SerializeVersionedRootSignature(&stRootSignatureDesc - , stFeatureData.HighestVersion - , &pISignatureBlob - , &pIErrorBlob)); - - GRS_THROW_IF_FAILED(stGPU[c_nMainGPU].m_pID3D12Device4->CreateRootSignature(0 - , pISignatureBlob->GetBufferPointer() - , pISignatureBlob->GetBufferSize() - , IID_PPV_ARGS(&stGPU[c_nMainGPU].m_pIRS))); - - GRS_SET_D3D12_DEBUGNAME_COMPTR(stGPU[c_nMainGPU].m_pIRS); - - //------------------------------------------------------------------------------------------------ - // Second Pass - // 创建渲染Quad的根签名对象,注意这个根签名在辅助显卡上用 - CD3DX12_DESCRIPTOR_RANGE1 stDRQuad[3]; - stDRQuad[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0); - stDRQuad[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 2, 0); - stDRQuad[2].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 1, 0); - - CD3DX12_ROOT_PARAMETER1 stRPQuad[3]; - stRPQuad[0].InitAsDescriptorTable(1, &stDRQuad[0], D3D12_SHADER_VISIBILITY_PIXEL); //CBV所有Shader可见 - stRPQuad[1].InitAsDescriptorTable(1, &stDRQuad[1], D3D12_SHADER_VISIBILITY_PIXEL); //SRV仅PS可见 - stRPQuad[2].InitAsDescriptorTable(1, &stDRQuad[2], D3D12_SHADER_VISIBILITY_PIXEL); //SAMPLE仅PS可见 - - CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC stRSQuadDesc; - stRSQuadDesc.Init_1_1(_countof(stRPQuad) - , stRPQuad - , 0 - , nullptr - , D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT); - - pISignatureBlob.Reset(); - pIErrorBlob.Reset(); - GRS_THROW_IF_FAILED(D3DX12SerializeVersionedRootSignature(&stRSQuadDesc - , stFeatureData.HighestVersion - , &pISignatureBlob - , &pIErrorBlob)); - - GRS_THROW_IF_FAILED(stGPU[c_nSecondGPU].m_pID3D12Device4->CreateRootSignature(0 - , pISignatureBlob->GetBufferPointer() - , pISignatureBlob->GetBufferSize() - , IID_PPV_ARGS(&stGPU[c_nSecondGPU].m_pIRS))); - - GRS_SET_D3D12_DEBUGNAME_COMPTR(stGPU[c_nSecondGPU].m_pIRS); - - //----------------------------------------------------------------------------------------------------- - // Third Pass - CD3DX12_DESCRIPTOR_RANGE1 stDRThridPass[2]; - stDRThridPass[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0); - stDRThridPass[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 1, 0); - - CD3DX12_ROOT_PARAMETER1 stRPThirdPass[2]; - stRPThirdPass[0].InitAsDescriptorTable(1, &stDRThridPass[0], D3D12_SHADER_VISIBILITY_PIXEL); //CBV所有Shader可见 - stRPThirdPass[1].InitAsDescriptorTable(1, &stDRThridPass[1], D3D12_SHADER_VISIBILITY_PIXEL); //SRV仅PS可见 - - CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC stRSThirdPass; - stRSThirdPass.Init_1_1(_countof(stRPThirdPass) - , stRPThirdPass - , 0 - , nullptr - , D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT); - - pISignatureBlob.Reset(); - pIErrorBlob.Reset(); - - GRS_THROW_IF_FAILED(D3DX12SerializeVersionedRootSignature(&stRSThirdPass - , stFeatureData.HighestVersion - , &pISignatureBlob - , &pIErrorBlob)); - - GRS_THROW_IF_FAILED(stGPU[c_nSecondGPU].m_pID3D12Device4->CreateRootSignature(0 - , pISignatureBlob->GetBufferPointer() - , pISignatureBlob->GetBufferSize() - , IID_PPV_ARGS(&pIRSThirdPass))); - - GRS_SET_D3D12_DEBUGNAME_COMPTR(pIRSThirdPass); - } - - // 编译Shader创建渲染管线状态对象 - { { -#if defined(_DEBUG) - // Enable better shader debugging with the graphics debugging tools. - UINT nShaderCompileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; -#else - UINT nShaderCompileFlags = 0; -#endif - //编译为行矩阵形式 - nShaderCompileFlags |= D3DCOMPILE_PACK_MATRIX_ROW_MAJOR; - - TCHAR pszShaderFileName[MAX_PATH] = {}; - - StringCchPrintf(pszShaderFileName - , MAX_PATH - , _T("%s11-MultiThreadAndAdapter\\Shader\\11-MultiThreadAndAdapter.hlsl") - , pszAppPath); - - ComPtr pVSCode; - ComPtr pPSCode; - ComPtr pErrMsg; - CHAR pszErrMsg[MAX_PATH] = {}; - HRESULT hr = S_OK; - - hr = D3DCompileFromFile(pszShaderFileName, nullptr, nullptr - , "VSMain", "vs_5_0", nShaderCompileFlags, 0, &pVSCode, &pErrMsg); - if (FAILED(hr)) - { - if (nullptr != pErrMsg) - { - StringCchPrintfA(pszErrMsg - , MAX_PATH - , "\n%s\n" - , (CHAR*)pErrMsg->GetBufferPointer()); - ::OutputDebugStringA(pszErrMsg); - } - throw CGRSCOMException(hr); - } - - pErrMsg.Reset(); - - hr = D3DCompileFromFile(pszShaderFileName, nullptr, nullptr - , "PSMain", "ps_5_0", nShaderCompileFlags, 0, &pPSCode, &pErrMsg); - if (FAILED(hr)) - { - if (nullptr != pErrMsg) - { - StringCchPrintfA(pszErrMsg - , MAX_PATH - , "\n%s\n" - , (CHAR*)pErrMsg->GetBufferPointer()); - ::OutputDebugStringA(pszErrMsg); - } - throw CGRSCOMException(hr); - } - - - // 我们多添加了一个法线的定义,但目前Shader中我们并没有使用 - D3D12_INPUT_ELEMENT_DESC stIALayoutSphere[] = - { - { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, - { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 16, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, - { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 24, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 } - }; - - // 创建 graphics pipeline state object (PSO)对象 - D3D12_GRAPHICS_PIPELINE_STATE_DESC stPSODesc = {}; - stPSODesc.InputLayout = { stIALayoutSphere, _countof(stIALayoutSphere) }; - stPSODesc.pRootSignature = stGPU[c_nMainGPU].m_pIRS.Get(); - stPSODesc.VS = CD3DX12_SHADER_BYTECODE(pVSCode.Get()); - stPSODesc.PS = CD3DX12_SHADER_BYTECODE(pPSCode.Get()); - stPSODesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT); - stPSODesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT); - stPSODesc.SampleMask = UINT_MAX; - stPSODesc.SampleDesc.Count = 1; - stPSODesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; - stPSODesc.NumRenderTargets = 1; - stPSODesc.RTVFormats[0] = emRTFmt; - stPSODesc.DepthStencilState.StencilEnable = FALSE; - stPSODesc.DepthStencilState.DepthEnable = TRUE; //打开深度缓冲 - stPSODesc.DSVFormat = emDSFmt; - stPSODesc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL;//启用深度缓存写入功能 - stPSODesc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_LESS; //深度测试函数(该值为普通的深度测试,即较小值写入) - - GRS_THROW_IF_FAILED( - stGPU[c_nMainGPU].m_pID3D12Device4->CreateGraphicsPipelineState(&stPSODesc - , IID_PPV_ARGS(&stGPU[c_nMainGPU].m_pIPSO))); - - GRS_SET_D3D12_DEBUGNAME_COMPTR(stGPU[c_nMainGPU].m_pIPSO); - - //--------------------------------------------------------------------------------------------------- - //用于渲染单位矩形的管道状态对象(Second Pass) - - StringCchPrintf(pszShaderFileName, MAX_PATH - , _T("%s11-MultiThreadAndAdapter\\Shader\\11-QuadVS.hlsl") - , pszAppPath); - - pVSCode.Reset(); - pPSCode.Reset(); - pErrMsg.Reset(); - - hr = D3DCompileFromFile(pszShaderFileName, nullptr, nullptr - , "VSMain", "vs_5_0", nShaderCompileFlags, 0, &pVSCode, &pErrMsg); - if (FAILED(hr)) - { - if (nullptr != pErrMsg) - { - StringCchPrintfA(pszErrMsg, MAX_PATH, "\n%s\n", (CHAR*)pErrMsg->GetBufferPointer()); - ::OutputDebugStringA(pszErrMsg); - } - throw CGRSCOMException(hr); - } - - pErrMsg.Reset(); - - StringCchPrintf(pszShaderFileName, MAX_PATH - , _T("%s11-MultiThreadAndAdapter\\Shader\\11-WaterColourPS.hlsl") - , pszAppPath); - - hr = D3DCompileFromFile(pszShaderFileName, nullptr, nullptr - , "PSMain", "ps_5_0", nShaderCompileFlags, 0, &pPSCode, &pErrMsg); - if (FAILED(hr)) - { - if (nullptr != pErrMsg) - { - StringCchPrintfA(pszErrMsg, MAX_PATH, "\n%s\n", (CHAR*)pErrMsg->GetBufferPointer()); - ::OutputDebugStringA(pszErrMsg); - } - throw CGRSCOMException(hr); - } - - D3D12_INPUT_ELEMENT_DESC stIALayoutQuad[] = - { - { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, - { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 16, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 } - }; - - // 创建 graphics pipeline state object (PSO)对象 - D3D12_GRAPHICS_PIPELINE_STATE_DESC stPSOQuadDesc = {}; - stPSOQuadDesc.InputLayout = { stIALayoutQuad, _countof(stIALayoutQuad) }; - stPSOQuadDesc.pRootSignature = stGPU[c_nSecondGPU].m_pIRS.Get(); - stPSOQuadDesc.VS = CD3DX12_SHADER_BYTECODE(pVSCode.Get()); - stPSOQuadDesc.PS = CD3DX12_SHADER_BYTECODE(pPSCode.Get()); - stPSOQuadDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT); - stPSOQuadDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT); - stPSOQuadDesc.SampleMask = UINT_MAX; - stPSOQuadDesc.SampleDesc.Count = 1; - stPSOQuadDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; - stPSOQuadDesc.NumRenderTargets = 1; - stPSOQuadDesc.RTVFormats[0] = emRTFmt; - stPSOQuadDesc.DepthStencilState.StencilEnable = FALSE; - stPSOQuadDesc.DepthStencilState.DepthEnable = FALSE; - - GRS_THROW_IF_FAILED( - stGPU[c_nSecondGPU].m_pID3D12Device4->CreateGraphicsPipelineState( - &stPSOQuadDesc - , IID_PPV_ARGS(&stGPU[c_nSecondGPU].m_pIPSO))); - GRS_SET_D3D12_DEBUGNAME_COMPTR(stGPU[c_nSecondGPU].m_pIPSO); - - //--------------------------------------------------------------------------------------------------- - // Third Pass - - pPSCode.Reset(); - pErrMsg.Reset(); - - StringCchPrintf(pszShaderFileName, MAX_PATH - , _T("%s11-MultiThreadAndAdapter\\Shader\\11-GaussianBlurPS.hlsl") - , pszAppPath); - - //第三趟渲染,只编译PS就可以了,VS就用之前的QuadVS即可,都是后处理主要玩PS - hr = D3DCompileFromFile(pszShaderFileName, nullptr, nullptr - , "PSMain", "ps_5_0", nShaderCompileFlags, 0, &pPSCode, &pErrMsg); - if (FAILED(hr)) - { - if (nullptr != pErrMsg) - { - StringCchPrintfA(pszErrMsg, MAX_PATH, "\n%s\n", (CHAR*)pErrMsg->GetBufferPointer()); - ::OutputDebugStringA(pszErrMsg); - } - throw CGRSCOMException(hr); - } - - // 创建 graphics pipeline state object (PSO)对象 - D3D12_GRAPHICS_PIPELINE_STATE_DESC stPSOThirdPassDesc = {}; - stPSOThirdPassDesc.InputLayout = { stIALayoutQuad, _countof(stIALayoutQuad) }; - stPSOThirdPassDesc.pRootSignature = pIRSThirdPass.Get(); - stPSOThirdPassDesc.VS = CD3DX12_SHADER_BYTECODE(pVSCode.Get()); - stPSOThirdPassDesc.PS = CD3DX12_SHADER_BYTECODE(pPSCode.Get()); - stPSOThirdPassDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT); - stPSOThirdPassDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT); - stPSOThirdPassDesc.SampleMask = UINT_MAX; - stPSOThirdPassDesc.SampleDesc.Count = 1; - stPSOThirdPassDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; - stPSOThirdPassDesc.NumRenderTargets = 1; - stPSOThirdPassDesc.RTVFormats[0] = emRTFmt; - stPSOThirdPassDesc.DepthStencilState.StencilEnable = FALSE; - stPSOThirdPassDesc.DepthStencilState.DepthEnable = FALSE; - - GRS_THROW_IF_FAILED( - stGPU[c_nSecondGPU].m_pID3D12Device4->CreateGraphicsPipelineState( - &stPSOThirdPassDesc - , IID_PPV_ARGS(&pIPSOThirdPass))); - GRS_SET_D3D12_DEBUGNAME_COMPTR(pIPSOThirdPass); - - // DoNothing PS PSO - pPSCode.Reset(); - pErrMsg.Reset(); - - StringCchPrintf(pszShaderFileName, MAX_PATH - , _T("%s11-MultiThreadAndAdapter\\Shader\\11-DoNothingPS.hlsl") - , pszAppPath); - - //第三趟渲染,只编译PS就可以了,VS就用之前的QuadVS即可,都是后处理主要玩PS - hr = D3DCompileFromFile(pszShaderFileName, nullptr, nullptr - , "PSMain", "ps_5_0", nShaderCompileFlags, 0, &pPSCode, &pErrMsg); - if (FAILED(hr)) - { - if (nullptr != pErrMsg) - { - StringCchPrintfA(pszErrMsg, MAX_PATH, "\n%s\n", (CHAR*)pErrMsg->GetBufferPointer()); - ::OutputDebugStringA(pszErrMsg); - } - throw CGRSCOMException(hr); - } - - stPSOThirdPassDesc.PS = CD3DX12_SHADER_BYTECODE(pPSCode.Get()); - GRS_THROW_IF_FAILED( - stGPU[c_nSecondGPU].m_pID3D12Device4->CreateGraphicsPipelineState( - &stPSOThirdPassDesc - , IID_PPV_ARGS(&pIPSODoNothing))); - GRS_SET_D3D12_DEBUGNAME_COMPTR(pIPSODoNothing); - - // DoNothing PS PSO - pPSCode.Reset(); - pErrMsg.Reset(); - - StringCchPrintf(pszShaderFileName, MAX_PATH - , _T("%s11-MultiThreadAndAdapter\\Shader\\blurShaders_MS.hlsl") - , pszAppPath); - - //第三趟渲染,只编译PS就可以了,VS就用之前的QuadVS即可,都是后处理主要玩PS - hr = D3DCompileFromFile(pszShaderFileName, nullptr, nullptr - , "PSSimpleBlur", "ps_5_0", nShaderCompileFlags, 0, &pPSCode, &pErrMsg); - if (FAILED(hr)) - { - if (nullptr != pErrMsg) - { - StringCchPrintfA(pszErrMsg, MAX_PATH, "\n%s\n", (CHAR*)pErrMsg->GetBufferPointer()); - ::OutputDebugStringA(pszErrMsg); - } - throw CGRSCOMException(hr); - } - - stPSOThirdPassDesc.PS = CD3DX12_SHADER_BYTECODE(pPSCode.Get()); - - GRS_THROW_IF_FAILED( - stGPU[c_nSecondGPU].m_pID3D12Device4->CreateGraphicsPipelineState( - &stPSOThirdPassDesc - , IID_PPV_ARGS(&pIPSOBothwayBlur))); - GRS_SET_D3D12_DEBUGNAME_COMPTR(pIPSOBothwayBlur); - - }} - - // 加载DDS噪声纹理,注意用于后处理,所以加载到第二个显卡上 - { { - TCHAR pszNoiseTexture[MAX_PATH] = {}; - StringCchPrintf(pszNoiseTexture, MAX_PATH, _T("%sAssets\\Noise1.dds"), pszAppPath); - std::unique_ptr pbDDSData; - std::vector stArSubResources; - DDS_ALPHA_MODE emAlphaMode = DDS_ALPHA_MODE_UNKNOWN; - bool bIsCube = false; - - GRS_THROW_IF_FAILED(LoadDDSTextureFromFile( - stGPU[c_nSecondGPU].m_pID3D12Device4.Get() - , pszNoiseTexture - , pINoiseTexture.GetAddressOf() - , pbDDSData - , stArSubResources - , SIZE_MAX - , &emAlphaMode - , &bIsCube)); - GRS_SET_D3D12_DEBUGNAME_COMPTR(pINoiseTexture); - - UINT64 n64szUpSphere = GetRequiredIntermediateSize( - pINoiseTexture.Get() - , 0 - , static_cast(stArSubResources.size())); - - D3D12_RESOURCE_DESC stTXDesc = pINoiseTexture->GetDesc(); - - GRS_THROW_IF_FAILED( - stGPU[c_nSecondGPU].m_pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD) - , D3D12_HEAP_FLAG_NONE - , &CD3DX12_RESOURCE_DESC::Buffer(n64szUpSphere) - , D3D12_RESOURCE_STATE_GENERIC_READ - , nullptr - , IID_PPV_ARGS(&pINoiseTextureUpload))); - GRS_SET_D3D12_DEBUGNAME_COMPTR(pINoiseTextureUpload); - - //执行两个Copy动作将纹理上传到默认堆中 - UpdateSubresources(stGPU[c_nSecondGPU].m_pICMDList.Get() - , pINoiseTexture.Get() - , pINoiseTextureUpload.Get() - , 0 - , 0 - , static_cast(stArSubResources.size()) - , stArSubResources.data()); - - //同步 - stGPU[c_nSecondGPU].m_pICMDList->ResourceBarrier(1 - , &CD3DX12_RESOURCE_BARRIER::Transition(pINoiseTexture.Get() - , D3D12_RESOURCE_STATE_COPY_DEST - , D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)); - - }} - - // 准备多个物体参数 - { - // 物体个性参数 - USES_CONVERSION; - - StringCchPrintf(stObject[c_nSphere].m_pszDDSFile, MAX_PATH, _T("%s\\Mesh\\sphere.dds"), pszAppPath); - StringCchPrintfA(stObject[c_nSphere].m_pszMeshFile, MAX_PATH, "%s\\Mesh\\sphere.txt", T2A(pszAppPath)); - stObject[c_nSphere].m_v4ModelPos = XMFLOAT4(2.0f, 2.0f, 0.0f, 1.0f); - - // 立方体个性参数 - StringCchPrintf(stObject[c_nCube].m_pszDDSFile, MAX_PATH, _T("%s\\Mesh\\Cube.dds"), pszAppPath); - StringCchPrintfA(stObject[c_nCube].m_pszMeshFile, MAX_PATH, "%s\\Mesh\\Cube.txt", T2A(pszAppPath)); - stObject[c_nCube].m_v4ModelPos = XMFLOAT4(-2.0f, 2.0f, 0.0f, 1.0f); - - // 平板个性参数 - StringCchPrintf(stObject[c_nPlane].m_pszDDSFile, MAX_PATH, _T("%s\\Mesh\\Plane.dds"), pszAppPath); - StringCchPrintfA(stObject[c_nPlane].m_pszMeshFile, MAX_PATH, "%s\\Mesh\\Plane.txt", T2A(pszAppPath)); - stObject[c_nPlane].m_v4ModelPos = XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f); - - // Mesh Value - ST_GRS_VERTEX_MODULE* pstVertices = nullptr; - UINT* pnIndices = nullptr; - // DDS Value - std::unique_ptr pbDDSData; - std::vector stArSubResources; - DDS_ALPHA_MODE emAlphaMode = DDS_ALPHA_MODE_UNKNOWN; - bool bIsCube = false; - - // 场景物体的共性参数,也就是各线程的共性参数 - for (int i = 0; i < c_nMaxObjects; i++) - { - stObject[i].m_nModuleIndex = i; - - //创建每个Module的捆绑包 - GRS_THROW_IF_FAILED(stGPU[c_nMainGPU].m_pID3D12Device4->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_BUNDLE - , IID_PPV_ARGS(&stObject[i].m_pIBundleAlloc))); - GRS_SetD3D12DebugNameIndexed(stObject[i].m_pIBundleAlloc.Get(), _T("m_pIBundleAlloc"), i); - - GRS_THROW_IF_FAILED(stGPU[c_nMainGPU].m_pID3D12Device4->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_BUNDLE - , stObject[i].m_pIBundleAlloc.Get(), nullptr, IID_PPV_ARGS(&stObject[i].m_pIBundle))); - GRS_SetD3D12DebugNameIndexed(stObject[i].m_pIBundle.Get(), _T("m_pIBundle"), i); - - //加载DDS - pbDDSData.release(); - stArSubResources.clear(); - GRS_THROW_IF_FAILED(LoadDDSTextureFromFile(stGPU[c_nMainGPU].m_pID3D12Device4.Get() - , stObject[i].m_pszDDSFile - , stObject[i].m_pITexture.GetAddressOf() - , pbDDSData - , stArSubResources - , SIZE_MAX - , &emAlphaMode - , &bIsCube)); - - GRS_SetD3D12DebugNameIndexed(stObject[i].m_pITexture.Get(), _T("m_pITexture"), i); - - UINT64 n64szUpSphere = GetRequiredIntermediateSize( - stObject[i].m_pITexture.Get() - , 0 - , static_cast(stArSubResources.size())); - D3D12_RESOURCE_DESC stTXDesc = stObject[i].m_pITexture->GetDesc(); - - //创建上传堆 - GRS_THROW_IF_FAILED(stGPU[c_nMainGPU].m_pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD) - , D3D12_HEAP_FLAG_NONE - , &CD3DX12_RESOURCE_DESC::Buffer(n64szUpSphere) - , D3D12_RESOURCE_STATE_GENERIC_READ - , nullptr - , IID_PPV_ARGS(&stObject[i].m_pITextureUpload))); - GRS_SetD3D12DebugNameIndexed(stObject[i].m_pITextureUpload.Get(), _T("m_pITextureUpload"), i); - - //上传DDS - UpdateSubresources(stGPU[c_nMainGPU].m_pICMDList.Get() - , stObject[i].m_pITexture.Get() - , stObject[i].m_pITextureUpload.Get() - , 0 - , 0 - , static_cast(stArSubResources.size()) - , stArSubResources.data()); - - //同步 - stGPU[c_nMainGPU].m_pICMDList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition( - stObject[i].m_pITexture.Get() - , D3D12_RESOURCE_STATE_COPY_DEST - , D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE)); - - - //创建SRV CBV堆 - D3D12_DESCRIPTOR_HEAP_DESC stSRVHeapDesc = {}; - stSRVHeapDesc.NumDescriptors = 2; //1 SRV + 1 CBV - stSRVHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; - stSRVHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; - - GRS_THROW_IF_FAILED(stGPU[c_nMainGPU].m_pID3D12Device4->CreateDescriptorHeap(&stSRVHeapDesc - , IID_PPV_ARGS(&stObject[i].m_pSRVHeap))); - GRS_SetD3D12DebugNameIndexed(stObject[i].m_pSRVHeap.Get(), _T("m_pSRVHeap"), i); - - //创建SRV - D3D12_SHADER_RESOURCE_VIEW_DESC stSRVDesc = {}; - stSRVDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; - stSRVDesc.Format = stTXDesc.Format; - stSRVDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; - stSRVDesc.Texture2D.MipLevels = 1; - - CD3DX12_CPU_DESCRIPTOR_HANDLE stCBVSRVHandle( - stObject[i].m_pSRVHeap->GetCPUDescriptorHandleForHeapStart() - , 1 - , stGPU[c_nMainGPU].m_pID3D12Device4->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV)); - - stGPU[c_nMainGPU].m_pID3D12Device4->CreateShaderResourceView(stObject[i].m_pITexture.Get() - , &stSRVDesc - , stCBVSRVHandle); - - // 创建Sample - D3D12_DESCRIPTOR_HEAP_DESC stSamplerHeapDesc = {}; - stSamplerHeapDesc.NumDescriptors = 1; - stSamplerHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER; - stSamplerHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; - - GRS_THROW_IF_FAILED(stGPU[c_nMainGPU].m_pID3D12Device4->CreateDescriptorHeap(&stSamplerHeapDesc - , IID_PPV_ARGS(&stObject[i].m_pISampleHeap))); - GRS_SetD3D12DebugNameIndexed(stObject[i].m_pISampleHeap.Get(), _T("m_pISampleHeap"), i); - - D3D12_SAMPLER_DESC stSamplerDesc = {}; - stSamplerDesc.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR; - stSamplerDesc.MinLOD = 0; - stSamplerDesc.MaxLOD = D3D12_FLOAT32_MAX; - stSamplerDesc.MipLODBias = 0.0f; - stSamplerDesc.MaxAnisotropy = 1; - stSamplerDesc.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS; - stSamplerDesc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP; - stSamplerDesc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP; - stSamplerDesc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP; - - stGPU[c_nMainGPU].m_pID3D12Device4->CreateSampler(&stSamplerDesc - , stObject[i].m_pISampleHeap->GetCPUDescriptorHandleForHeapStart()); - - //加载网格数据 - LoadMeshVertex(stObject[i].m_pszMeshFile, stObject[i].m_nVertexCnt, pstVertices, pnIndices); - stObject[i].m_nIndexCnt = stObject[i].m_nVertexCnt; - - //创建 Vertex Buffer 仅使用Upload隐式堆 - GRS_THROW_IF_FAILED(stGPU[c_nMainGPU].m_pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD) - , D3D12_HEAP_FLAG_NONE - , &CD3DX12_RESOURCE_DESC::Buffer(stObject[i].m_nVertexCnt * sizeof(ST_GRS_VERTEX_MODULE)) - , D3D12_RESOURCE_STATE_GENERIC_READ - , nullptr - , IID_PPV_ARGS(&stObject[i].m_pIVertexBuffer))); - GRS_SetD3D12DebugNameIndexed(stObject[i].m_pIVertexBuffer.Get(), _T("m_pIVertexBuffer"), i); - - //使用map-memcpy-unmap大法将数据传至顶点缓冲对象 - UINT8* pVertexDataBegin = nullptr; - CD3DX12_RANGE stReadRange(0, 0); // We do not intend to read from this resource on the CPU. - - GRS_THROW_IF_FAILED(stObject[i].m_pIVertexBuffer->Map(0, &stReadRange, reinterpret_cast(&pVertexDataBegin))); - memcpy(pVertexDataBegin, pstVertices, stObject[i].m_nVertexCnt * sizeof(ST_GRS_VERTEX_MODULE)); - stObject[i].m_pIVertexBuffer->Unmap(0, nullptr); - - //创建 Index Buffer 仅使用Upload隐式堆 - GRS_THROW_IF_FAILED(stGPU[c_nMainGPU].m_pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD) - , D3D12_HEAP_FLAG_NONE - , &CD3DX12_RESOURCE_DESC::Buffer(stObject[i].m_nIndexCnt * sizeof(UINT)) - , D3D12_RESOURCE_STATE_GENERIC_READ - , nullptr - , IID_PPV_ARGS(&stObject[i].m_pIIndexsBuffer))); - GRS_SetD3D12DebugNameIndexed(stObject[i].m_pIIndexsBuffer.Get(), _T("m_pIIndexsBuffer"), i); - - UINT8* pIndexDataBegin = nullptr; - GRS_THROW_IF_FAILED(stObject[i].m_pIIndexsBuffer->Map(0, &stReadRange, reinterpret_cast(&pIndexDataBegin))); - memcpy(pIndexDataBegin, pnIndices, stObject[i].m_nIndexCnt * sizeof(UINT)); - stObject[i].m_pIIndexsBuffer->Unmap(0, nullptr); - - //创建Vertex Buffer View - stObject[i].m_stVertexBufferView.BufferLocation = stObject[i].m_pIVertexBuffer->GetGPUVirtualAddress(); - stObject[i].m_stVertexBufferView.StrideInBytes = sizeof(ST_GRS_VERTEX_MODULE); - stObject[i].m_stVertexBufferView.SizeInBytes = stObject[i].m_nVertexCnt * sizeof(ST_GRS_VERTEX_MODULE); - - //创建Index Buffer View - stObject[i].m_stIndexsBufferView.BufferLocation = stObject[i].m_pIIndexsBuffer->GetGPUVirtualAddress(); - stObject[i].m_stIndexsBufferView.Format = DXGI_FORMAT_R32_UINT; - stObject[i].m_stIndexsBufferView.SizeInBytes = stObject[i].m_nIndexCnt * sizeof(UINT); - - ::HeapFree(::GetProcessHeap(), 0, pstVertices); - ::HeapFree(::GetProcessHeap(), 0, pnIndices); - - // 创建常量缓冲 注意缓冲尺寸设置为256边界对齐大小 - GRS_THROW_IF_FAILED(stGPU[c_nMainGPU].m_pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD) - , D3D12_HEAP_FLAG_NONE - , &CD3DX12_RESOURCE_DESC::Buffer(szMVPBuf) - , D3D12_RESOURCE_STATE_GENERIC_READ - , nullptr - , IID_PPV_ARGS(&stObject[i].m_pICBRes))); - GRS_SetD3D12DebugNameIndexed(stObject[i].m_pICBRes.Get(), _T("m_pICBRes"), i); - // Map 之后就不再Unmap了 直接复制数据进去 这样每帧都不用map-copy-unmap浪费时间了 - GRS_THROW_IF_FAILED(stObject[i].m_pICBRes->Map(0, nullptr, reinterpret_cast(&stObject[i].m_pMVPBuf))); - //--------------------------------------------------------------------------------------------- - - // 创建CBV - D3D12_CONSTANT_BUFFER_VIEW_DESC cbvDesc = {}; - cbvDesc.BufferLocation = stObject[i].m_pICBRes->GetGPUVirtualAddress(); - cbvDesc.SizeInBytes = static_cast(szMVPBuf); - stGPU[c_nMainGPU].m_pID3D12Device4->CreateConstantBufferView(&cbvDesc, stObject[i].m_pSRVHeap->GetCPUDescriptorHandleForHeapStart()); - } - } - - // 记录场景物体渲染的捆绑包 - {{ - //在主显卡上创建渲染物体的捆绑包 - for (int i = 0; i < c_nMaxObjects; i++) - { - stObject[i].m_pIBundle->SetGraphicsRootSignature(stGPU[c_nMainGPU].m_pIRS.Get()); - stObject[i].m_pIBundle->SetPipelineState(stGPU[c_nMainGPU].m_pIPSO.Get()); - - ID3D12DescriptorHeap* ppHeapsSphere[] = { stObject[i].m_pSRVHeap.Get(),stObject[i].m_pISampleHeap.Get() }; - stObject[i].m_pIBundle->SetDescriptorHeaps(_countof(ppHeapsSphere), ppHeapsSphere); - - //设置SRV - CD3DX12_GPU_DESCRIPTOR_HANDLE stGPUCBVHandleSphere(stObject[i].m_pSRVHeap->GetGPUDescriptorHandleForHeapStart()); - stObject[i].m_pIBundle->SetGraphicsRootDescriptorTable(0, stGPUCBVHandleSphere); - - stGPUCBVHandleSphere.Offset(1, stGPU[c_nMainGPU].m_pID3D12Device4->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV)); - //设置CBV - stObject[i].m_pIBundle->SetGraphicsRootDescriptorTable(1, stGPUCBVHandleSphere); - - //设置Sample - stObject[i].m_pIBundle->SetGraphicsRootDescriptorTable(2, stObject[i].m_pISampleHeap->GetGPUDescriptorHandleForHeapStart()); - - //注意我们使用的渲染手法是三角形列表,也就是通常的Mesh网格 - stObject[i].m_pIBundle->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - stObject[i].m_pIBundle->IASetVertexBuffers(0, 1, &stObject[i].m_stVertexBufferView); - stObject[i].m_pIBundle->IASetIndexBuffer(&stObject[i].m_stIndexsBufferView); - - //Draw Call!!! - stObject[i].m_pIBundle->DrawIndexedInstanced(stObject[i].m_nIndexCnt, 1, 0, 0, 0); - stObject[i].m_pIBundle->Close(); - }//End for - }} - - // 建辅助显卡用来渲染或后处理用的矩形框 - { - ST_GRS_VERTEX_QUAD stVertexQuad[] = - { //( x, y, z, w ) ( u, v ) - { { -1.0f, 1.0f, 0.0f, 1.0f }, { 0.0f, 0.0f } }, // Top left. - { { 1.0f, 1.0f, 0.0f, 1.0f }, { 1.0f, 0.0f } }, // Top right. - { { -1.0f, -1.0f, 0.0f, 1.0f }, { 0.0f, 1.0f } }, // Bottom left. - { { 1.0f, -1.0f, 0.0f, 1.0f }, { 1.0f, 1.0f } }, // Bottom right. - }; - - const UINT nszVBQuad = sizeof(stVertexQuad); - - GRS_THROW_IF_FAILED(stGPU[c_nSecondGPU].m_pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), - D3D12_HEAP_FLAG_NONE, - &CD3DX12_RESOURCE_DESC::Buffer(nszVBQuad), - D3D12_RESOURCE_STATE_COPY_DEST, - nullptr, - IID_PPV_ARGS(&pIVBQuad))); - - // 这次我们特意演示了如何将顶点缓冲上传到默认堆上的方式,与纹理上传默认堆实际是一样的 - GRS_THROW_IF_FAILED(stGPU[c_nSecondGPU].m_pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), - D3D12_HEAP_FLAG_NONE, - &CD3DX12_RESOURCE_DESC::Buffer(nszVBQuad), - D3D12_RESOURCE_STATE_GENERIC_READ, - nullptr, - IID_PPV_ARGS(&pIVBQuadUpload))); - - D3D12_SUBRESOURCE_DATA stVBDataQuad = {}; - stVBDataQuad.pData = reinterpret_cast(stVertexQuad); - stVBDataQuad.RowPitch = nszVBQuad; - stVBDataQuad.SlicePitch = stVBDataQuad.RowPitch; - - UpdateSubresources<1>(stGPU[c_nSecondGPU].m_pICMDList.Get(), pIVBQuad.Get(), pIVBQuadUpload.Get(), 0, 0, 1, &stVBDataQuad); - stGPU[c_nSecondGPU].m_pICMDList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(pIVBQuad.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER)); - - pstVBVQuad.BufferLocation = pIVBQuad->GetGPUVirtualAddress(); - pstVBVQuad.StrideInBytes = sizeof(ST_GRS_VERTEX_QUAD); - pstVBVQuad.SizeInBytes = sizeof(stVertexQuad); - - // 执行命令,将矩形顶点缓冲上传到第二个显卡的默认堆上 - GRS_THROW_IF_FAILED(stGPU[c_nSecondGPU].m_pICMDList->Close()); - ID3D12CommandList* ppRenderCommandLists[] = { stGPU[c_nSecondGPU].m_pICMDList.Get() }; - stGPU[c_nSecondGPU].m_pICMDQueue->ExecuteCommandLists(_countof(ppRenderCommandLists), ppRenderCommandLists); - - n64CurrentFenceValue = n64FenceValue; - GRS_THROW_IF_FAILED( - stGPU[c_nSecondGPU].m_pICMDQueue->Signal(stGPU[c_nSecondGPU].m_pIFence.Get(), n64CurrentFenceValue)); - n64FenceValue++; - - if (stGPU[c_nSecondGPU].m_pIFence->GetCompletedValue() < n64CurrentFenceValue) - { - GRS_THROW_IF_FAILED( - stGPU[c_nSecondGPU].m_pIFence->SetEventOnCompletion( - n64CurrentFenceValue - , stGPU[c_nSecondGPU].m_hEventFence)); - WaitForSingleObject(stGPU[c_nSecondGPU].m_hEventFence, INFINITE); - } - } - - // 创建在辅助显卡上渲染单位矩形用的常量缓冲,CBV、SRV、Sample - { - // 创建辅助显卡上的常量缓冲区 - GRS_THROW_IF_FAILED(stGPU[c_nSecondGPU].m_pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD) - , D3D12_HEAP_FLAG_NONE - , &CD3DX12_RESOURCE_DESC::Buffer(szSecondPassCB) //注意缓冲尺寸设置为256边界对齐大小 - , D3D12_RESOURCE_STATE_GENERIC_READ - , nullptr - , IID_PPV_ARGS(&pICBResSecondPass))); - GRS_SET_D3D12_DEBUGNAME_COMPTR(pICBResSecondPass); - - GRS_THROW_IF_FAILED(pICBResSecondPass->Map(0, nullptr, reinterpret_cast(&pstCBSecondPass))); - - D3D12_DESCRIPTOR_HEAP_DESC stHeapDesc = {}; - stHeapDesc.NumDescriptors = g_nFrameBackBufCount + 2; //1 Const Bufer + 1 Texture + g_nFrameBackBufCount * Texture - stHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; - stHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; - - //SRV堆 - GRS_THROW_IF_FAILED( - stGPU[c_nSecondGPU].m_pID3D12Device4->CreateDescriptorHeap( - &stHeapDesc, IID_PPV_ARGS(&stGPU[c_nSecondGPU].m_pISRVHeap))); - GRS_SET_D3D12_DEBUGNAME_COMPTR(stGPU[c_nSecondGPU].m_pISRVHeap); - - // Third Pass SRV Heap - stHeapDesc.NumDescriptors = g_nFrameBackBufCount; - GRS_THROW_IF_FAILED( - stGPU[c_nSecondGPU].m_pID3D12Device4->CreateDescriptorHeap( - &stHeapDesc, IID_PPV_ARGS(&pISRVHeapThirdPass))); - GRS_SET_D3D12_DEBUGNAME_COMPTR(pISRVHeapThirdPass); - - // CBV - D3D12_CONSTANT_BUFFER_VIEW_DESC cbvDesc = {}; - cbvDesc.BufferLocation = pICBResSecondPass->GetGPUVirtualAddress(); - cbvDesc.SizeInBytes = static_cast(szSecondPassCB); - - stGPU[c_nSecondGPU].m_pID3D12Device4->CreateConstantBufferView(&cbvDesc - , stGPU[c_nSecondGPU].m_pISRVHeap->GetCPUDescriptorHandleForHeapStart()); - - // SRV - D3D12_SHADER_RESOURCE_VIEW_DESC stSRVDesc = {}; - stSRVDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; - stSRVDesc.Format = emRTFmt; - stSRVDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; - stSRVDesc.Texture2D.MipLevels = 1; - - CD3DX12_CPU_DESCRIPTOR_HANDLE stSrvHandle( - stGPU[c_nSecondGPU].m_pISRVHeap->GetCPUDescriptorHandleForHeapStart() - , 1 - , stGPU[c_nSecondGPU].m_nSRVDescriptorSize); - - if (!bCrossAdapterTextureSupport) - { - // 使用复制的渲染目标纹理作为Shader的纹理资源 - stGPU[c_nSecondGPU].m_pID3D12Device4->CreateShaderResourceView( - pISecondAdapterTexutrePerFrame[nCurrentFrameIndex].Get() - , &stSRVDesc - , stSrvHandle); - } - else - { - // 直接使用共享的渲染目标复制的纹理作为纹理资源 - stGPU[c_nSecondGPU].m_pID3D12Device4->CreateShaderResourceView( - stGPU[c_nSecondGPU].m_pICrossAdapterResPerFrame[nCurrentFrameIndex].Get() - , &stSRVDesc - , stSrvHandle); - } - - stSrvHandle.Offset(1, stGPU[c_nSecondGPU].m_nSRVDescriptorSize); - // Noise Texture SRV - D3D12_RESOURCE_DESC stTXDesc = pINoiseTexture->GetDesc(); - stSRVDesc.Format = stTXDesc.Format; - //创建噪声纹理描述符 - stGPU[c_nSecondGPU].m_pID3D12Device4->CreateShaderResourceView( - pINoiseTexture.Get(), &stSRVDesc, stSrvHandle); - - //---------------------------------------------------------------------------------------- - // Third Pass SRV - stSRVDesc.Format = emRTFmt; - CD3DX12_CPU_DESCRIPTOR_HANDLE stThirdPassSrvHandle( - pISRVHeapThirdPass->GetCPUDescriptorHandleForHeapStart()); - for (int i = 0; i < g_nFrameBackBufCount; i++) - { - stGPU[c_nSecondGPU].m_pID3D12Device4->CreateShaderResourceView( - pIOffLineRTRes[i].Get() - , &stSRVDesc - , stThirdPassSrvHandle); - stThirdPassSrvHandle.Offset(1, stGPU[c_nSecondGPU].m_nSRVDescriptorSize); - } - - //---------------------------------------------------------------------------------------- - - // 创建Sample Descriptor Heap 采样器描述符堆 - stHeapDesc.NumDescriptors = 1; //只有一个Sample - stHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER; - GRS_THROW_IF_FAILED( - stGPU[c_nSecondGPU].m_pID3D12Device4->CreateDescriptorHeap( - &stHeapDesc, IID_PPV_ARGS(&stGPU[c_nSecondGPU].m_pISampleHeap))); - GRS_SET_D3D12_DEBUGNAME_COMPTR(stGPU[c_nSecondGPU].m_pISampleHeap); - - // Third Pass Sample Heap - GRS_THROW_IF_FAILED( - stGPU[c_nSecondGPU].m_pID3D12Device4->CreateDescriptorHeap( - &stHeapDesc, IID_PPV_ARGS(&pISampleHeapThirdPass))); - GRS_SET_D3D12_DEBUGNAME_COMPTR(pISampleHeapThirdPass); - - // 创建Sample View 实际就是采样器 - D3D12_SAMPLER_DESC stSamplerDesc = {}; - stSamplerDesc.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR; - stSamplerDesc.MinLOD = 0; - stSamplerDesc.MaxLOD = D3D12_FLOAT32_MAX; - stSamplerDesc.MipLODBias = 0.0f; - stSamplerDesc.MaxAnisotropy = 1; - stSamplerDesc.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS; - stSamplerDesc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; - stSamplerDesc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; - stSamplerDesc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; - - stGPU[c_nSecondGPU].m_pID3D12Device4->CreateSampler( - &stSamplerDesc - , stGPU[c_nSecondGPU].m_pISampleHeap->GetCPUDescriptorHandleForHeapStart()); - - // Third Pass Sample - stGPU[c_nSecondGPU].m_pID3D12Device4->CreateSampler( - &stSamplerDesc - , pISampleHeapThirdPass->GetCPUDescriptorHandleForHeapStart()); - } - - // 执行主显卡上第二个Copy命令并等待所有的纹理都上传到了默认堆中 - { { - GRS_THROW_IF_FAILED(stGPU[c_nMainGPU].m_pICMDList->Close()); - ID3D12CommandList* ppRenderCommandLists[] = { stGPU[c_nMainGPU].m_pICMDList.Get() }; - stGPU[c_nMainGPU].m_pICMDQueue->ExecuteCommandLists(_countof(ppRenderCommandLists), ppRenderCommandLists); - - n64CurrentFenceValue = n64FenceValue; - GRS_THROW_IF_FAILED(stGPU[c_nMainGPU].m_pICMDQueue->Signal(stGPU[c_nMainGPU].m_pIFence.Get(), n64CurrentFenceValue)); - - GRS_THROW_IF_FAILED(stGPU[c_nMainGPU].m_pIFence->SetEventOnCompletion(n64CurrentFenceValue, stGPU[c_nMainGPU].m_hEventFence)); - arHWaited.Add(stGPU[c_nMainGPU].m_hEventFence); - n64FenceValue++; - }} - - GRS_THROW_IF_FAILED(pICmdListCopy->Close()); - GRS_THROW_IF_FAILED(pICMDListThirdPass->Close()); - - // Time Value 时间轴变量 - ULONGLONG n64tmFrameStart = ::GetTickCount64(); - ULONGLONG n64tmCurrent = n64tmFrameStart; - // 计算旋转角度需要的变量 - double dModelRotationYAngle = 0.0f; - - XMMATRIX mxRotY; - // 计算投影矩阵 - XMMATRIX mxProjection = XMMatrixPerspectiveFovLH(XM_PIDIV4, (FLOAT)iWndWidth / (FLOAT)iWndHeight, 0.1f, 1000.0f); - - //初始化都结束以后,再显示窗口 - ShowWindow(hWnd, nCmdShow); - UpdateWindow(hWnd); - - DWORD dwRet = 0; - BOOL bExit = FALSE; - //17、开始消息循环,并在其中不断渲染 - while (!bExit) - {//消息循环 - dwRet = ::MsgWaitForMultipleObjects( - static_cast(arHWaited.GetCount()), arHWaited.GetData(), FALSE, INFINITE, QS_ALLINPUT); - switch (dwRet - WAIT_OBJECT_0) - { - case 0: - {//开始新的一帧渲染 - //OnUpdate() - {//计算 Module 模型矩阵 * 视矩阵 view * 裁剪矩阵 projection - n64tmCurrent = ::GetTickCount(); - //计算旋转的角度:旋转角度(弧度) = 时间(秒) * 角速度(弧度/秒) - dModelRotationYAngle += ((n64tmCurrent - n64tmFrameStart) / 1000.0f) * g_fPalstance; - - n64tmFrameStart = n64tmCurrent; - - //旋转角度是2PI周期的倍数,去掉周期数,只留下相对0弧度开始的小于2PI的弧度即可 - if (dModelRotationYAngle > XM_2PI) - { - dModelRotationYAngle = fmod(dModelRotationYAngle, XM_2PI); - } - mxRotY = XMMatrixRotationY(static_cast(dModelRotationYAngle)); - - //注意实际的变换应当是 Module * World * View * Projection - //此处实际World是一个单位矩阵,故省略了 - //而Module矩阵是先位移再旋转,也可以将旋转矩阵理解为就是World矩阵 - XMMATRIX xmMVP = XMMatrixMultiply(XMMatrixLookAtLH(XMLoadFloat3(&g_f3EyePos) - , XMLoadFloat3(&g_f3LockAt) - , XMLoadFloat3(&g_f3HeapUp)) - , mxProjection); - - //计算物体的MVP - xmMVP = XMMatrixMultiply(mxRotY, xmMVP); - - for (int i = 0; i < c_nMaxObjects; i++) - { - XMMATRIX xmModulePos = XMMatrixTranslation(stObject[i].m_v4ModelPos.x - , stObject[i].m_v4ModelPos.y - , stObject[i].m_v4ModelPos.z); - - xmModulePos = XMMatrixMultiply(xmModulePos, xmMVP); - - XMStoreFloat4x4(&stObject[i].m_pMVPBuf->m_MVP, xmModulePos); - } - } - - //更新第二遍渲染的常量缓冲区,可以放在OnUpdate里 - { - pstCBSecondPass->m_nFun = g_nFunNO; - pstCBSecondPass->m_fQuatLevel = g_fQuatLevel; - pstCBSecondPass->m_fWaterPower = g_fWaterPower; - } - - //OnRender() - { - // 获取帧号 - nCurrentFrameIndex = pISwapChain3->GetCurrentBackBufferIndex(); - - // 主显卡渲染(First Pass) - { - stGPU[c_nMainGPU].m_pICMDAlloc->Reset(); - stGPU[c_nMainGPU].m_pICMDList->Reset(stGPU[c_nMainGPU].m_pICMDAlloc.Get(), stGPU[c_nMainGPU].m_pIPSO.Get()); - - stGPU[c_nMainGPU].m_pICMDList->SetGraphicsRootSignature(stGPU[c_nMainGPU].m_pIRS.Get()); - stGPU[c_nMainGPU].m_pICMDList->SetPipelineState(stGPU[c_nMainGPU].m_pIPSO.Get()); - stGPU[c_nMainGPU].m_pICMDList->RSSetViewports(1, &stViewPort); - stGPU[c_nMainGPU].m_pICMDList->RSSetScissorRects(1, &stScissorRect); - - stGPU[c_nMainGPU].m_pICMDList->ResourceBarrier(1 - , &CD3DX12_RESOURCE_BARRIER::Transition( - stGPU[c_nMainGPU].m_pIRTRes[nCurrentFrameIndex].Get() - , D3D12_RESOURCE_STATE_COMMON - , D3D12_RESOURCE_STATE_RENDER_TARGET)); - - CD3DX12_CPU_DESCRIPTOR_HANDLE stRTVHandle( - stGPU[c_nMainGPU].m_pIRTVHeap->GetCPUDescriptorHandleForHeapStart() - , nCurrentFrameIndex - , stGPU[c_nMainGPU].m_nRTVDescriptorSize); - CD3DX12_CPU_DESCRIPTOR_HANDLE dsvHandle( - stGPU[c_nMainGPU].m_pIDSVHeap->GetCPUDescriptorHandleForHeapStart()); - - stGPU[c_nMainGPU].m_pICMDList->OMSetRenderTargets( - 1, &stRTVHandle, false, &dsvHandle); - stGPU[c_nMainGPU].m_pICMDList->ClearRenderTargetView( - stRTVHandle, v4ClearColor, 0, nullptr); - stGPU[c_nMainGPU].m_pICMDList->ClearDepthStencilView( - dsvHandle, D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, nullptr); - - //执行实际的物体绘制渲染,Draw Call! - for (int i = 0; i < c_nMaxObjects; i++) - { - ID3D12DescriptorHeap* ppHeapsSkybox[] - = { stObject[i].m_pSRVHeap.Get(),stObject[i].m_pISampleHeap.Get() }; - stGPU[c_nMainGPU].m_pICMDList->SetDescriptorHeaps(_countof(ppHeapsSkybox), ppHeapsSkybox); - stGPU[c_nMainGPU].m_pICMDList->ExecuteBundle(stObject[i].m_pIBundle.Get()); - } - - stGPU[c_nMainGPU].m_pICMDList->ResourceBarrier(1 - , &CD3DX12_RESOURCE_BARRIER::Transition( - stGPU[c_nMainGPU].m_pIRTRes[nCurrentFrameIndex].Get() - , D3D12_RESOURCE_STATE_RENDER_TARGET - , D3D12_RESOURCE_STATE_COMMON)); - - GRS_THROW_IF_FAILED(stGPU[c_nMainGPU].m_pICMDList->Close()); - - // 主命令队列上执行主命令列表 - ID3D12CommandList* ppRenderCommandLists[] - = { stGPU[c_nMainGPU].m_pICMDList.Get() }; - stGPU[c_nMainGPU].m_pICMDQueue->ExecuteCommandLists( - _countof(ppRenderCommandLists), ppRenderCommandLists); - - n64CurrentFenceValue = n64FenceValue; - GRS_THROW_IF_FAILED(stGPU[c_nMainGPU].m_pICMDQueue->Signal( - stGPU[c_nMainGPU].m_pIFence.Get(), n64CurrentFenceValue)); - n64FenceValue++; - } - - // 将主显卡的渲染结果复制到共享纹理资源中(Copy Main Render Target become Shader Resource) - { - pICmdAllocCopy->Reset(); - pICmdListCopy->Reset(pICmdAllocCopy.Get(), nullptr); - - if (bCrossAdapterTextureSupport) - { - // 如果适配器支持跨适配器行主纹理,只需将该纹理复制到跨适配器纹理中。 - pICmdListCopy->CopyResource( - stGPU[c_nMainGPU].m_pICrossAdapterResPerFrame[nCurrentFrameIndex].Get() - , stGPU[c_nMainGPU].m_pIRTRes[nCurrentFrameIndex].Get()); - } - else - { - // 如果适配器不支持跨适配器行主纹理,则将纹理复制为缓冲区, - // 以便可以显式地管理纹理行间距。使用呈现目标指定的内存布局将中间呈现目标复制到共享缓冲区中。 - D3D12_RESOURCE_DESC stRenderTargetDesc - = stGPU[c_nMainGPU].m_pIRTRes[nCurrentFrameIndex]->GetDesc(); - D3D12_PLACED_SUBRESOURCE_FOOTPRINT stRenderTargetLayout = {}; - - stGPU[c_nMainGPU].m_pID3D12Device4->GetCopyableFootprints( - &stRenderTargetDesc, 0, 1, 0, &stRenderTargetLayout, nullptr, nullptr, nullptr); - - CD3DX12_TEXTURE_COPY_LOCATION dest( - stGPU[c_nMainGPU].m_pICrossAdapterResPerFrame[nCurrentFrameIndex].Get() - , stRenderTargetLayout); - CD3DX12_TEXTURE_COPY_LOCATION src( - stGPU[c_nMainGPU].m_pIRTRes[nCurrentFrameIndex].Get() - , 0); - CD3DX12_BOX box(0, 0, iWndWidth, iWndHeight); - - pICmdListCopy->CopyTextureRegion(&dest, 0, 0, 0, &src, &box); - } - - GRS_THROW_IF_FAILED(pICmdListCopy->Close()); - - // 使用主显卡上的复制命令队列完成渲染目标资源到共享资源间的复制 - // 通过调用命令队列的Wait命令实现同一个GPU上的各命令队列之间的等待同步 - GRS_THROW_IF_FAILED(pICmdQueueCopy->Wait(stGPU[c_nMainGPU].m_pIFence.Get(), n64CurrentFenceValue)); - - ID3D12CommandList* ppCopyCommandLists[] = { pICmdListCopy.Get() }; - pICmdQueueCopy->ExecuteCommandLists(_countof(ppCopyCommandLists), ppCopyCommandLists); - - n64CurrentFenceValue = n64FenceValue; - // 复制命令的信号设置在共享的围栏对象上这样使得第二个显卡的命令队列可以在这个围栏上等待 - // 从而完成不同GPU命令队列间的同步等待 - GRS_THROW_IF_FAILED(pICmdQueueCopy->Signal( - stGPU[c_nMainGPU].m_pISharedFence.Get(), n64CurrentFenceValue)); - n64FenceValue++; - } - - // 开始辅助显卡的渲染,首先调用水彩画效果(Second Pass) - { - stGPU[c_nSecondGPU].m_pICMDAlloc->Reset(); - stGPU[c_nSecondGPU].m_pICMDList->Reset( - stGPU[c_nSecondGPU].m_pICMDAlloc.Get(), stGPU[c_nSecondGPU].m_pIPSO.Get()); - - // 如果不支持跨显卡纹理共享,那么就从共享堆复制资源过来,相当于从Upload堆复制数据到Default堆上 - if (!bCrossAdapterTextureSupport) - { - // 将共享堆中的缓冲区复制到辅助适配器可以从中取样的纹理中。 - D3D12_RESOURCE_BARRIER stResBarrier = CD3DX12_RESOURCE_BARRIER::Transition( - pISecondAdapterTexutrePerFrame[nCurrentFrameIndex].Get(), - D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, - D3D12_RESOURCE_STATE_COPY_DEST); - - stGPU[c_nSecondGPU].m_pICMDList->ResourceBarrier(1, &stResBarrier); - - D3D12_RESOURCE_DESC stSecondaryAdapterTexture - = pISecondAdapterTexutrePerFrame[nCurrentFrameIndex]->GetDesc(); - D3D12_PLACED_SUBRESOURCE_FOOTPRINT stTextureLayout = {}; - - stGPU[c_nSecondGPU].m_pID3D12Device4->GetCopyableFootprints( - &stSecondaryAdapterTexture, 0, 1, 0, &stTextureLayout, nullptr, nullptr, nullptr); - - CD3DX12_TEXTURE_COPY_LOCATION dest( - pISecondAdapterTexutrePerFrame[nCurrentFrameIndex].Get(), 0); - CD3DX12_TEXTURE_COPY_LOCATION src( - stGPU[c_nSecondGPU].m_pICrossAdapterResPerFrame[nCurrentFrameIndex].Get() - , stTextureLayout); - CD3DX12_BOX box(0, 0, iWndWidth, iWndHeight); - - stGPU[c_nSecondGPU].m_pICMDList->CopyTextureRegion(&dest, 0, 0, 0, &src, &box); - - stResBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST; - stResBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; - stGPU[c_nSecondGPU].m_pICMDList->ResourceBarrier(1, &stResBarrier); - } - - //将第一遍渲染的结果作为纹理 - { - CD3DX12_CPU_DESCRIPTOR_HANDLE stSrvHandle( - stGPU[c_nSecondGPU].m_pISRVHeap->GetCPUDescriptorHandleForHeapStart() - , 1 - , stGPU[c_nSecondGPU].m_nSRVDescriptorSize); - - D3D12_SHADER_RESOURCE_VIEW_DESC stSRVDesc = {}; - stSRVDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; - stSRVDesc.Format = emRTFmt; - stSRVDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; - stSRVDesc.Texture2D.MipLevels = 1; - - if (!bCrossAdapterTextureSupport) - { - // 使用复制的渲染目标纹理作为Shader的纹理资源 - stGPU[c_nSecondGPU].m_pID3D12Device4->CreateShaderResourceView( - pISecondAdapterTexutrePerFrame[nCurrentFrameIndex].Get() - , &stSRVDesc - , stSrvHandle); - } - else - { - // 直接使用共享的渲染目标复制的纹理作为纹理资源 - stGPU[c_nSecondGPU].m_pID3D12Device4->CreateShaderResourceView( - stGPU[c_nSecondGPU].m_pICrossAdapterResPerFrame[nCurrentFrameIndex].Get() - , &stSRVDesc - , stSrvHandle); - } - } - - stGPU[c_nSecondGPU].m_pICMDList->SetGraphicsRootSignature(stGPU[c_nSecondGPU].m_pIRS.Get()); - stGPU[c_nSecondGPU].m_pICMDList->SetPipelineState(stGPU[c_nSecondGPU].m_pIPSO.Get()); - ID3D12DescriptorHeap* ppHeaps[] - = { stGPU[c_nSecondGPU].m_pISRVHeap.Get() - ,stGPU[c_nSecondGPU].m_pISampleHeap.Get() }; - stGPU[c_nSecondGPU].m_pICMDList->SetDescriptorHeaps(_countof(ppHeaps), ppHeaps); - - stGPU[c_nSecondGPU].m_pICMDList->RSSetViewports(1, &stViewPort); - stGPU[c_nSecondGPU].m_pICMDList->RSSetScissorRects(1, &stScissorRect); - - D3D12_RESOURCE_BARRIER stRTSecondaryBarriers = CD3DX12_RESOURCE_BARRIER::Transition( - pIOffLineRTRes[nCurrentFrameIndex].Get() - , D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE - , D3D12_RESOURCE_STATE_RENDER_TARGET); - - stGPU[c_nSecondGPU].m_pICMDList->ResourceBarrier(1, &stRTSecondaryBarriers); - - CD3DX12_CPU_DESCRIPTOR_HANDLE stRTVSecondaryHandle( - pIRTVOffLine->GetCPUDescriptorHandleForHeapStart() - , nCurrentFrameIndex - , stGPU[c_nSecondGPU].m_nRTVDescriptorSize); - stGPU[c_nSecondGPU].m_pICMDList->OMSetRenderTargets(1, &stRTVSecondaryHandle, false, nullptr); - stGPU[c_nSecondGPU].m_pICMDList->ClearRenderTargetView(stRTVSecondaryHandle, v4ClearColor, 0, nullptr); - - // 开始绘制矩形 - CD3DX12_GPU_DESCRIPTOR_HANDLE stSRVHandle( - stGPU[c_nSecondGPU].m_pISRVHeap->GetGPUDescriptorHandleForHeapStart() - , 0 - , stGPU[c_nSecondGPU].m_nSRVDescriptorSize); - - stGPU[c_nSecondGPU].m_pICMDList->SetGraphicsRootDescriptorTable(0, stSRVHandle); - stSRVHandle.Offset(1, stGPU[c_nSecondGPU].m_nSRVDescriptorSize); - stGPU[c_nSecondGPU].m_pICMDList->SetGraphicsRootDescriptorTable(1, stSRVHandle); - stGPU[c_nSecondGPU].m_pICMDList->SetGraphicsRootDescriptorTable(2 - , stGPU[c_nSecondGPU].m_pISampleHeap->GetGPUDescriptorHandleForHeapStart()); - - stGPU[c_nSecondGPU].m_pICMDList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - stGPU[c_nSecondGPU].m_pICMDList->IASetVertexBuffers(0, 1, &pstVBVQuad); - // Draw Call! - stGPU[c_nSecondGPU].m_pICMDList->DrawInstanced(4, 1, 0, 0); - - // 设置好同步围栏 - stGPU[c_nSecondGPU].m_pICMDList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition( - pIOffLineRTRes[nCurrentFrameIndex].Get() - , D3D12_RESOURCE_STATE_RENDER_TARGET - , D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)); - - GRS_THROW_IF_FAILED(stGPU[c_nSecondGPU].m_pICMDList->Close()); - - // 使用辅助显卡上的主命令队列执行命令列表 - // 辅助显卡上的主命令队列通过等待共享的围栏对象最终完成了与主显卡之间的同步 - // 注意Wait在ExecuteCommandLists之前,这样就保证了主显卡渲染完毕并且复制完毕后辅助显卡才会开始执行第二遍渲染 - GRS_THROW_IF_FAILED(stGPU[c_nSecondGPU].m_pICMDQueue->Wait(stGPU[c_nSecondGPU].m_pISharedFence.Get(), n64CurrentFenceValue)); - } - - // 调用高斯模糊效果(Third Pass) - {{ - pICMDAllocThirdPass->Reset(); - pICMDListThirdPass->Reset(pICMDAllocThirdPass.Get(), pIPSOThirdPass.Get()); - - //将第二遍渲染的结果作为纹理 - CD3DX12_CPU_DESCRIPTOR_HANDLE stSrvHandle( - pISRVHeapThirdPass->GetCPUDescriptorHandleForHeapStart() - , nCurrentFrameIndex - , stGPU[c_nSecondGPU].m_nSRVDescriptorSize); - - pICMDListThirdPass->SetGraphicsRootSignature(pIRSThirdPass.Get()); - - if( 0 == g_nUsePSID ) - { - pICMDListThirdPass->SetPipelineState(pIPSODoNothing.Get()); - } - else if( 1 == g_nUsePSID ) - { - pICMDListThirdPass->SetPipelineState(pIPSOThirdPass.Get()); - } - else - { - pICMDListThirdPass->SetPipelineState(pIPSOBothwayBlur.Get()); - } - - ID3D12DescriptorHeap* ppHeaps[] - = { pISRVHeapThirdPass.Get() - ,pISampleHeapThirdPass.Get() }; - pICMDListThirdPass->SetDescriptorHeaps(_countof(ppHeaps), ppHeaps); - - pICMDListThirdPass->RSSetViewports(1, &stViewPort); - pICMDListThirdPass->RSSetScissorRects(1, &stScissorRect); - - D3D12_RESOURCE_BARRIER stRTSecondaryBarriers = CD3DX12_RESOURCE_BARRIER::Transition( - stGPU[c_nSecondGPU].m_pIRTRes[nCurrentFrameIndex].Get() - , D3D12_RESOURCE_STATE_PRESENT - , D3D12_RESOURCE_STATE_RENDER_TARGET); - - pICMDListThirdPass->ResourceBarrier(1, &stRTSecondaryBarriers); - - CD3DX12_CPU_DESCRIPTOR_HANDLE stRTVHandle( - stGPU[c_nSecondGPU].m_pIRTVHeap->GetCPUDescriptorHandleForHeapStart() - , nCurrentFrameIndex - , stGPU[c_nSecondGPU].m_nRTVDescriptorSize); - pICMDListThirdPass->OMSetRenderTargets(1, &stRTVHandle, false, nullptr); - float f4ClearColor[] = { 1.0f,0.0f,1.0f,1.0f }; //故意使用与主显卡渲染目标不同的清除色,查看是否有“露底”的问题 - pICMDListThirdPass->ClearRenderTargetView(stRTVHandle, f4ClearColor, 0, nullptr); - - // 开始绘制矩形 - CD3DX12_GPU_DESCRIPTOR_HANDLE stSRVHandle( - pISRVHeapThirdPass->GetGPUDescriptorHandleForHeapStart() - , nCurrentFrameIndex - , stGPU[c_nSecondGPU].m_nSRVDescriptorSize); - - pICMDListThirdPass->SetGraphicsRootDescriptorTable(0, stSRVHandle); - pICMDListThirdPass->SetGraphicsRootDescriptorTable(1 - , pISampleHeapThirdPass->GetGPUDescriptorHandleForHeapStart()); - - pICMDListThirdPass->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - pICMDListThirdPass->IASetVertexBuffers(0, 1, &pstVBVQuad); - // Draw Call! - pICMDListThirdPass->DrawInstanced(4, 1, 0, 0); - - // 设置好同步围栏 - pICMDListThirdPass->ResourceBarrier(1 - , &CD3DX12_RESOURCE_BARRIER::Transition( - stGPU[c_nSecondGPU].m_pIRTRes[nCurrentFrameIndex].Get() - , D3D12_RESOURCE_STATE_RENDER_TARGET - , D3D12_RESOURCE_STATE_PRESENT)); - - GRS_THROW_IF_FAILED(pICMDListThirdPass->Close()); - }} - - ID3D12CommandList* ppBlurCommandLists[] - = { stGPU[c_nSecondGPU].m_pICMDList.Get(), pICMDListThirdPass.Get() }; - stGPU[c_nSecondGPU].m_pICMDQueue->ExecuteCommandLists(_countof(ppBlurCommandLists), ppBlurCommandLists); - - // 执行Present命令最终呈现画面 - GRS_THROW_IF_FAILED(pISwapChain3->Present(1, 0)); - - n64CurrentFenceValue = n64FenceValue; - GRS_THROW_IF_FAILED( - stGPU[c_nSecondGPU].m_pICMDQueue->Signal( - stGPU[c_nSecondGPU].m_pIFence.Get(), n64CurrentFenceValue)); - GRS_THROW_IF_FAILED( - stGPU[c_nSecondGPU].m_pIFence->SetEventOnCompletion( - n64CurrentFenceValue, stGPU[c_nSecondGPU].m_hEventFence)); - n64FenceValue++; - - //开始渲染后只需要在辅助显卡的事件句柄上等待即可 - //因为辅助显卡已经在GPU侧与主显卡通过Wait命令进行了同步 - arHWaited.RemoveAll(); - arHWaited.Add(stGPU[c_nSecondGPU].m_hEventFence); - } - } - break; - case 1: - {//处理消息 - while (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) - { - if (WM_QUIT != msg.message) - { - ::TranslateMessage(&msg); - ::DispatchMessage(&msg); - } - else - { - bExit = TRUE; - } - } - } - break; - case WAIT_TIMEOUT: - { - - } - break; - - default: - break; - } - } - } - catch (CGRSCOMException & e) - {//发生了COM异常 - e; - } -#if defined(_DEBUG) - { - ComPtr dxgiDebug; - if (SUCCEEDED(DXGIGetDebugInterface1(0, IID_PPV_ARGS(&dxgiDebug)))) - { - dxgiDebug->ReportLiveObjects(DXGI_DEBUG_ALL, DXGI_DEBUG_RLO_FLAGS(DXGI_DEBUG_RLO_SUMMARY | DXGI_DEBUG_RLO_IGNORE_INTERNAL)); - } - } -#endif - ::CoUninitialize(); - return 0; -} - - -LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - switch (message) - { - case WM_DESTROY: - PostQuitMessage(0); - break; - case WM_KEYDOWN: - { - USHORT n16KeyCode = (wParam & 0xFF); - if (VK_SPACE == n16KeyCode) - {// - g_nFunNO += 1; - if (g_nFunNO >= g_nMaxFunNO) - { - g_nFunNO = 0; - } - } - - if ( VK_TAB == n16KeyCode ) - { - ++ g_nUsePSID; - if ( g_nUsePSID > 2 ) - { - g_nUsePSID = 0; - } - } - - if (1 == g_nFunNO) - {//当进行水彩画效果渲染时控制生效 - if ('Q' == n16KeyCode || 'q' == n16KeyCode) - {//q 增加水彩取色半径 - g_fWaterPower += 1.0f; - if (g_fWaterPower >= 64.0f) - { - g_fWaterPower = 8.0f; - } - } - - if ('E' == n16KeyCode || 'e' == n16KeyCode) - {//e 控制量化参数,范围 2 - 6 - g_fQuatLevel += 1.0f; - if (g_fQuatLevel > 6.0f) - { - g_fQuatLevel = 2.0f; - } - } - } - - if (VK_ADD == n16KeyCode || VK_OEM_PLUS == n16KeyCode) - { - //double g_fPalstance = 10.0f * XM_PI / 180.0f; //物体旋转的角速度,单位:弧度/秒 - g_fPalstance += 10 * XM_PI / 180.0f; - if (g_fPalstance > XM_PI) - { - g_fPalstance = XM_PI; - } - //XMMatrixOrthographicOffCenterLH() - } - - if (VK_SUBTRACT == n16KeyCode || VK_OEM_MINUS == n16KeyCode) - { - g_fPalstance -= 10 * XM_PI / 180.0f; - if (g_fPalstance < 0.0f) - { - g_fPalstance = XM_PI / 180.0f; - } - } - - //根据用户输入变换 - //XMVECTOR g_f3EyePos = XMVectorSet(0.0f, 5.0f, -10.0f, 0.0f); //眼睛位置 - //XMVECTOR g_f3LockAt = XMVectorSet(0.0f, 0.0f, 1.0f, 0.0f); //眼睛所盯的位置 - //XMVECTOR g_f3HeapUp = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f); //头部正上方位置 - XMFLOAT3 move(0, 0, 0); - float fMoveSpeed = 2.0f; - float fTurnSpeed = XM_PIDIV2 * 0.005f; - - if ('w' == n16KeyCode || 'W' == n16KeyCode) - { - move.z -= 1.0f; - } - - if ('s' == n16KeyCode || 'S' == n16KeyCode) - { - move.z += 1.0f; - } - - if ('d' == n16KeyCode || 'D' == n16KeyCode) - { - move.x += 1.0f; - } - - if ('a' == n16KeyCode || 'A' == n16KeyCode) - { - move.x -= 1.0f; - } - - if (fabs(move.x) > 0.1f && fabs(move.z) > 0.1f) - { - XMVECTOR vector = XMVector3Normalize(XMLoadFloat3(&move)); - move.x = XMVectorGetX(vector); - move.z = XMVectorGetZ(vector); - } - - if (VK_UP == n16KeyCode) - { - g_fPitch += fTurnSpeed; - } - - if (VK_DOWN == n16KeyCode) - { - g_fPitch -= fTurnSpeed; - } - - if (VK_RIGHT == n16KeyCode) - { - g_fYaw -= fTurnSpeed; - } - - if (VK_LEFT == n16KeyCode) - { - g_fYaw += fTurnSpeed; - } - - // Prevent looking too far up or down. - g_fPitch = min(g_fPitch, XM_PIDIV4); - g_fPitch = max(-XM_PIDIV4, g_fPitch); - - // Move the camera in model space. - float x = move.x * -cosf(g_fYaw) - move.z * sinf(g_fYaw); - float z = move.x * sinf(g_fYaw) - move.z * cosf(g_fYaw); - g_f3EyePos.x += x * fMoveSpeed; - g_f3EyePos.z += z * fMoveSpeed; - - // Determine the look direction. - float r = cosf(g_fPitch); - g_f3LockAt.x = r * sinf(g_fYaw); - g_f3LockAt.y = sinf(g_fPitch); - g_f3LockAt.z = r * cosf(g_fYaw); - - if ( VK_ESCAPE == n16KeyCode ) - {//按Tab键还原摄像机位置 - g_f3EyePos = XMFLOAT3(0.0f, 0.0f, -10.0f); //眼睛位置 - g_f3LockAt = XMFLOAT3(0.0f, 0.0f, 0.0f); //眼睛所盯的位置 - g_f3HeapUp = XMFLOAT3(0.0f, 1.0f, 0.0f); //头部正上方位置 - } - } - - break; - default: - return DefWindowProc(hWnd, message, wParam, lParam); - } - return 0; -} - -BOOL LoadMeshVertex(const CHAR* pszMeshFileName, UINT& m_nVertexCnt, ST_GRS_VERTEX_MODULE*& ppVertex, UINT*& ppIndices) -{ - ifstream fin; - char input; - BOOL bRet = TRUE; - try - { - fin.open(pszMeshFileName); - if (fin.fail()) - { - throw CGRSCOMException(E_FAIL); - } - fin.get(input); - while (input != ':') - { - fin.get(input); - } - fin >> m_nVertexCnt; - - fin.get(input); - while (input != ':') - { - fin.get(input); - } - fin.get(input); - fin.get(input); - - ppVertex = (ST_GRS_VERTEX_MODULE*)HeapAlloc(::GetProcessHeap() - , HEAP_ZERO_MEMORY - , m_nVertexCnt * sizeof(ST_GRS_VERTEX_MODULE)); - ppIndices = (UINT*)HeapAlloc(::GetProcessHeap() - , HEAP_ZERO_MEMORY - , m_nVertexCnt * sizeof(UINT)); - - for (UINT i = 0; i < m_nVertexCnt; i++) - { - fin >> ppVertex[i].m_v4Position.x >> ppVertex[i].m_v4Position.y >> ppVertex[i].m_v4Position.z; - ppVertex[i].m_v4Position.w = 1.0f; - fin >> ppVertex[i].m_vTex.x >> ppVertex[i].m_vTex.y; - fin >> ppVertex[i].m_vNor.x >> ppVertex[i].m_vNor.y >> ppVertex[i].m_vNor.z; - - ppIndices[i] = i; - } - } - catch (CGRSCOMException & e) - { - e; - bRet = FALSE; - } - return bRet; -} \ No newline at end of file diff --git a/14-MultiThreadShadow/14-MultiThreadShadow-noshadow.cpp b/14-MultiThreadShadow/14-MultiThreadShadow-noshadow.cpp index 59fca0ef0abd3891557b1222dcc5071683620a2a..e3f6a32488165060230b0c0bbb7b728f91b4e491 100644 --- a/14-MultiThreadShadow/14-MultiThreadShadow-noshadow.cpp +++ b/14-MultiThreadShadow/14-MultiThreadShadow-noshadow.cpp @@ -1051,17 +1051,17 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l //偏移描述符指针到指定帧缓冲视图位置 CD3DX12_CPU_DESCRIPTOR_HANDLE stRTVHandle(g_pIRTVHeap->GetCPUDescriptorHandleForHeapStart() , m_nCurrentFrameIndex, g_nRTVDescriptorSize); - CD3DX12_CPU_DESCRIPTOR_HANDLE dsvHandle(g_pIDSVHeap->GetCPUDescriptorHandleForHeapStart() + CD3DX12_CPU_DESCRIPTOR_HANDLE stDSVHandle(g_pIDSVHeap->GetCPUDescriptorHandleForHeapStart() ,1 , pID3D12Device4->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_DSV)); //设置渲染目标 - pICmdListPre->OMSetRenderTargets(1, &stRTVHandle, FALSE, &dsvHandle); + pICmdListPre->OMSetRenderTargets(1, &stRTVHandle, FALSE, &stDSVHandle); pICmdListPre->RSSetViewports(1, &g_stViewPort); pICmdListPre->RSSetScissorRects(1, &g_stScissorRect); pICmdListPre->ClearRenderTargetView(stRTVHandle, faClearColor, 0, nullptr); - pICmdListPre->ClearDepthStencilView(dsvHandle, D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, nullptr); + pICmdListPre->ClearDepthStencilView(stDSVHandle, D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, nullptr); } @@ -1543,11 +1543,11 @@ UINT __stdcall RenderThread(void* pParam) CD3DX12_CPU_DESCRIPTOR_HANDLE stRTVHandle(g_pIRTVHeap->GetCPUDescriptorHandleForHeapStart() , pThdPms->m_nCurrentFrameIndex , g_nRTVDescriptorSize); - CD3DX12_CPU_DESCRIPTOR_HANDLE dsvHandle(g_pIDSVHeap->GetCPUDescriptorHandleForHeapStart() + CD3DX12_CPU_DESCRIPTOR_HANDLE stDSVHandle(g_pIDSVHeap->GetCPUDescriptorHandleForHeapStart() , 1 , pThdPms->m_pID3D12Device4->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_DSV)); //设置渲染目标 - pThdPms->m_pICmdList->OMSetRenderTargets(1, &stRTVHandle, FALSE, &dsvHandle); + pThdPms->m_pICmdList->OMSetRenderTargets(1, &stRTVHandle, FALSE, &stDSVHandle); pThdPms->m_pICmdList->RSSetViewports(1, &g_stViewPort); pThdPms->m_pICmdList->RSSetScissorRects(1, &g_stScissorRect); } diff --git a/2-D3D12WICTexture/2-D3D12WICTexture.cpp b/2-D3D12WICTexture/2-D3D12WICTexture.cpp index 2089420b7697b0fa306dab3d9644c7ce73a6ccda..f1351c79234eac68ad3efa8d6064cc4113ff4e80 100644 --- a/2-D3D12WICTexture/2-D3D12WICTexture.cpp +++ b/2-D3D12WICTexture/2-D3D12WICTexture.cpp @@ -201,10 +201,8 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l UINT nBPP = 0u; DXGI_FORMAT stTextureFormat = DXGI_FORMAT_UNKNOWN; - D3D12_VIEWPORT stViewPort = { 0.0f, 0.0f - , static_cast(iWidth), static_cast(iHeight), D3D12_MIN_DEPTH, D3D12_MAX_DEPTH }; - D3D12_RECT stScissorRect = { 0, 0 - , static_cast(iWidth), static_cast(iHeight) }; + D3D12_VIEWPORT stViewPort = { 0.0f, 0.0f, static_cast(iWidth), static_cast(iHeight), D3D12_MIN_DEPTH, D3D12_MAX_DEPTH }; + D3D12_RECT stScissorRect = { 0, 0, static_cast(iWidth), static_cast(iHeight) }; ComPtr pIDXGIFactory5; ComPtr pIAdapter1; @@ -324,8 +322,6 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l // 创建DXGI Factory对象 { GRS_THROW_IF_FAILED(CreateDXGIFactory2(nDXGIFactoryFlags, IID_PPV_ARGS(&pIDXGIFactory5))); - // 关闭ALT+ENTER键切换全屏的功能,因为我们没有实现OnSize处理,所以先关闭 - GRS_THROW_IF_FAILED(pIDXGIFactory5->MakeWindowAssociation(hWnd, DXGI_MWA_NO_ALT_ENTER)); } // 枚举适配器,并选择合适的适配器来创建3D设备对象 @@ -410,6 +406,8 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l pID3D12Device4->CreateRenderTargetView(pIARenderTargets[i].Get(), nullptr, stRTVHandle); stRTVHandle.ptr += nRTVDescriptorSize; } + // 关闭ALT+ENTER键切换全屏的功能,因为我们没有实现OnSize处理,所以先关闭 + GRS_THROW_IF_FAILED(pIDXGIFactory5->MakeWindowAssociation(hWnd, DXGI_MWA_NO_ALT_ENTER)); } // 创建SRV堆 (Shader Resource View Heap) diff --git a/3-PlacedTexture/3-D3D12PlacedTexture.cpp b/3-PlacedTexture/3-D3D12PlacedTexture.cpp index 7a1144c2f3226a04293b7c74848b0c34d33b72ae..f6f646c58f3df504d777dfe82c6899a03d4c61b3 100644 --- a/3-PlacedTexture/3-D3D12PlacedTexture.cpp +++ b/3-PlacedTexture/3-D3D12PlacedTexture.cpp @@ -216,7 +216,7 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l UINT nSamplerDescriptorSize = 0; //采样器大小 - D3D12_VIEWPORT stViewPort = { 0.0f, 0.0f, static_cast(iWidth), static_cast(iHeight) }; + D3D12_VIEWPORT stViewPort = { 0.0f, 0.0f, static_cast(iWidth), static_cast(iHeight), D3D12_MIN_DEPTH, D3D12_MAX_DEPTH }; D3D12_RECT stScissorRect = { 0, 0, static_cast(iWidth), static_cast(iHeight) }; ComPtr pIDXGIFactory5; diff --git a/4-D3D12TextureCube/4-D3D12TextureCube.cpp b/4-D3D12TextureCube/4-D3D12TextureCube.cpp index 28e47321986e0dc15ff54d769091a88def8d6fc8..6c4f48ffd9fabb94b77686fadd6d4e756ba23cb7 100644 --- a/4-D3D12TextureCube/4-D3D12TextureCube.cpp +++ b/4-D3D12TextureCube/4-D3D12TextureCube.cpp @@ -234,7 +234,7 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l UINT nSamplerDescriptorSize = 0; //采样器大小 - D3D12_VIEWPORT stViewPort = { 0.0f, 0.0f, static_cast(iWidth), static_cast(iHeight) }; + D3D12_VIEWPORT stViewPort = { 0.0f, 0.0f, static_cast(iWidth), static_cast(iHeight), D3D12_MIN_DEPTH, D3D12_MAX_DEPTH }; D3D12_RECT stScissorRect = { 0, 0, static_cast(iWidth), static_cast(iHeight) }; ComPtr pIDXGIFactory5; diff --git a/5-SkyBox/5-SkyBox.cpp b/5-SkyBox/5-SkyBox.cpp index 678795e4f61368b354bf6ea5794f133a8ecb9247..80037dff70b1b294df9c604870a28118f7cf3d6d 100644 --- a/5-SkyBox/5-SkyBox.cpp +++ b/5-SkyBox/5-SkyBox.cpp @@ -272,6 +272,8 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l UINT64 n64szUploadBufEarth = 0; UINT64 n64szUploadBufSkybox = 0; + DXGI_FORMAT emRTFormat = DXGI_FORMAT_R8G8B8A8_UNORM; + DXGI_FORMAT emDSFormat = DXGI_FORMAT_D32_FLOAT; DXGI_FORMAT emTxtFmtEarth = DXGI_FORMAT_UNKNOWN; const float faClearColor[] = { 0.0f, 0.2f, 0.4f, 1.0f }; @@ -285,7 +287,7 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l UINT nSamplerDescriptorSize = 0; //采样器大小 - D3D12_VIEWPORT stViewPort = { 0.0f, 0.0f, static_cast(iWndWidth), static_cast(iWndHeight) }; + D3D12_VIEWPORT stViewPort = { 0.0f, 0.0f, static_cast(iWndWidth), static_cast(iWndHeight), D3D12_MIN_DEPTH, D3D12_MAX_DEPTH }; D3D12_RECT stScissorRect = { 0, 0, static_cast(iWndWidth), static_cast(iWndHeight) }; //球体的网格数据 @@ -604,7 +606,7 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l stSwapChainDesc.BufferCount = nFrameBackBufCount; stSwapChainDesc.Width = iWndWidth; stSwapChainDesc.Height = iWndHeight; - stSwapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + stSwapChainDesc.Format = emRTFormat; stSwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; stSwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; stSwapChainDesc.SampleDesc.Count = 1; @@ -654,12 +656,12 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l stDSBufHeapDesc.VisibleNodeMask = 0; D3D12_DEPTH_STENCIL_VIEW_DESC stDepthStencilDesc = {}; - stDepthStencilDesc.Format = DXGI_FORMAT_D32_FLOAT; + stDepthStencilDesc.Format = emDSFormat; stDepthStencilDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D; stDepthStencilDesc.Flags = D3D12_DSV_FLAG_NONE; D3D12_CLEAR_VALUE depthOptimizedClearValue = {}; - depthOptimizedClearValue.Format = DXGI_FORMAT_D32_FLOAT; + depthOptimizedClearValue.Format = emDSFormat; depthOptimizedClearValue.DepthStencil.Depth = 1.0f; depthOptimizedClearValue.DepthStencil.Stencil = 0; @@ -670,7 +672,7 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l stDSResDesc.Height = iWndHeight; stDSResDesc.DepthOrArraySize = 1; stDSResDesc.MipLevels = 0; - stDSResDesc.Format = DXGI_FORMAT_D32_FLOAT; + stDSResDesc.Format = emDSFormat; stDSResDesc.SampleDesc.Count = 1; stDSResDesc.SampleDesc.Quality = 0; stDSResDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; @@ -849,8 +851,8 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l stPSODesc.SampleMask = UINT_MAX; stPSODesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; stPSODesc.NumRenderTargets = 1; - stPSODesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; - stPSODesc.DSVFormat = DXGI_FORMAT_D32_FLOAT; + stPSODesc.RTVFormats[0] = emRTFormat; + stPSODesc.DSVFormat = emDSFormat; stPSODesc.DepthStencilState.DepthEnable = TRUE; stPSODesc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL;//启用深度缓存写入功能 stPSODesc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_LESS; //深度测试函数(该值为普通的深度测试) @@ -1495,10 +1497,10 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l cbvDesc.BufferLocation = pICBUploadEarth->GetGPUVirtualAddress(); cbvDesc.SizeInBytes = static_cast(szMVPBuf); - D3D12_CPU_DESCRIPTOR_HANDLE cbvSrvHandle = pISRVHpEarth->GetCPUDescriptorHandleForHeapStart(); - cbvSrvHandle.ptr += nSRVDescriptorSize; + D3D12_CPU_DESCRIPTOR_HANDLE stSRVCBVHandle = pISRVHpEarth->GetCPUDescriptorHandleForHeapStart(); + stSRVCBVHandle.ptr += nSRVDescriptorSize; - pID3D12Device4->CreateConstantBufferView(&cbvDesc, cbvSrvHandle); + pID3D12Device4->CreateConstantBufferView(&cbvDesc, stSRVCBVHandle); //--------------------------------------------------------------------------------------------- cbvDesc.BufferLocation = pICBUploadSkybox->GetGPUVirtualAddress(); @@ -1739,9 +1741,9 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l //偏移描述符指针到指定帧缓冲视图位置 D3D12_CPU_DESCRIPTOR_HANDLE stRTVHandle = pIRTVHeap->GetCPUDescriptorHandleForHeapStart(); stRTVHandle.ptr += (nCurrentFrameIndex * nRTVDescriptorSize); - D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = pIDSVHeap->GetCPUDescriptorHandleForHeapStart(); + D3D12_CPU_DESCRIPTOR_HANDLE stDSVHandle = pIDSVHeap->GetCPUDescriptorHandleForHeapStart(); //设置渲染目标 - pICmdListDirect->OMSetRenderTargets(1, &stRTVHandle, FALSE, &dsvHandle); + pICmdListDirect->OMSetRenderTargets(1, &stRTVHandle, FALSE, &stDSVHandle); pICmdListDirect->RSSetViewports(1, &stViewPort); pICmdListDirect->RSSetScissorRects(1, &stScissorRect); diff --git a/6-MultiThread/6-MultiThreadWithMsgWait.cpp b/6-MultiThread/6-MultiThreadWithMsgWait.cpp index 8b6c310a4abdb73cd99796c7b35ba544a3c7621b..335d1c5fe7c09f1e8c6a5788eb42afcbcca12633 100644 --- a/6-MultiThread/6-MultiThreadWithMsgWait.cpp +++ b/6-MultiThread/6-MultiThreadWithMsgWait.cpp @@ -167,7 +167,7 @@ struct ST_GRS_THREAD_PARAMS int g_iWndWidth = 1024; int g_iWndHeight = 768; -D3D12_VIEWPORT g_stViewPort = { 0.0f, 0.0f, static_cast(g_iWndWidth), static_cast(g_iWndHeight) }; +D3D12_VIEWPORT g_stViewPort = { 0.0f, 0.0f, static_cast(g_iWndWidth), static_cast(g_iWndHeight), D3D12_MIN_DEPTH, D3D12_MAX_DEPTH }; D3D12_RECT g_stScissorRect = { 0, 0, static_cast(g_iWndWidth), static_cast(g_iWndHeight) }; //初始的默认摄像机的位置 @@ -837,15 +837,15 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l //偏移描述符指针到指定帧缓冲视图位置 D3D12_CPU_DESCRIPTOR_HANDLE stRTVHandle = g_pIRTVHeap->GetCPUDescriptorHandleForHeapStart(); stRTVHandle.ptr += ( nCurrentFrameIndex * g_nRTVDescriptorSize); - D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = g_pIDSVHeap->GetCPUDescriptorHandleForHeapStart(); + D3D12_CPU_DESCRIPTOR_HANDLE stDSVHandle = g_pIDSVHeap->GetCPUDescriptorHandleForHeapStart(); //设置渲染目标 - pICmdListPre->OMSetRenderTargets(1, &stRTVHandle, FALSE, &dsvHandle); + pICmdListPre->OMSetRenderTargets(1, &stRTVHandle, FALSE, &stDSVHandle); pICmdListPre->RSSetViewports(1, &g_stViewPort); pICmdListPre->RSSetScissorRects(1, &g_stScissorRect); pICmdListPre->ClearRenderTargetView(stRTVHandle, faClearColor, 0, nullptr); - pICmdListPre->ClearDepthStencilView(dsvHandle, D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, nullptr); + pICmdListPre->ClearDepthStencilView(stDSVHandle, D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, nullptr); } nStates = 2; @@ -1390,9 +1390,9 @@ UINT __stdcall RenderThread(void* pParam) { D3D12_CPU_DESCRIPTOR_HANDLE stRTVHandle = g_pIRTVHeap->GetCPUDescriptorHandleForHeapStart(); stRTVHandle.ptr += ( pThdPms->nCurrentFrameIndex * g_nRTVDescriptorSize); - D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = g_pIDSVHeap->GetCPUDescriptorHandleForHeapStart(); + D3D12_CPU_DESCRIPTOR_HANDLE stDSVHandle = g_pIDSVHeap->GetCPUDescriptorHandleForHeapStart(); //设置渲染目标 - pThdPms->pICmdList->OMSetRenderTargets(1, &stRTVHandle, FALSE, &dsvHandle); + pThdPms->pICmdList->OMSetRenderTargets(1, &stRTVHandle, FALSE, &stDSVHandle); pThdPms->pICmdList->RSSetViewports(1, &g_stViewPort); pThdPms->pICmdList->RSSetScissorRects(1, &g_stScissorRect); } diff --git a/7-D3D12MultiAdapter/7-D3D12MultiAdapter.cpp b/7-D3D12MultiAdapter/7-D3D12MultiAdapter.cpp index 12586bc2de5f9b5e3238bb303736f69daffee59b..ee62e27317563409ec94a6ab3dae3cd7856c8bd2 100644 --- a/7-D3D12MultiAdapter/7-D3D12MultiAdapter.cpp +++ b/7-D3D12MultiAdapter/7-D3D12MultiAdapter.cpp @@ -42,7 +42,7 @@ using namespace DirectX; #define GRS_ALLOC(sz) ::HeapAlloc(GetProcessHeap(),0,(sz)) #define GRS_CALLOC(sz) ::HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(sz)) #define GRS_CREALLOC(p,sz) ::HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(p),(sz)) -#define GRS_SAFE_FREE(p) if( nullptr != (p) ){ ::HeapFree( ::GetProcessHeap(),0,(p) ); (p) = nullptr; } +#define GRS_SAFE_FREE(p) if( nullptr != (p) ){ ::HeapFree( ::GetProcessHeap(),0,(p) ); (p) = nullptr; } //------------------------------------------------------------------------------------------------------------ // 为了调试加入下面的内联函数和宏定义,为每个接口对象设置名称,方便查看调试输出 @@ -223,7 +223,7 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l DXGI_FORMAT emRTFmt = DXGI_FORMAT_R8G8B8A8_UNORM; DXGI_FORMAT emDSFmt = DXGI_FORMAT_D24_UNORM_S8_UINT; - D3D12_VIEWPORT stViewPort = { 0.0f, 0.0f, static_cast(nWndWidth), static_cast(nWndHeight) }; + D3D12_VIEWPORT stViewPort = { 0.0f, 0.0f, static_cast(nWndWidth), static_cast(nWndHeight), D3D12_MIN_DEPTH, D3D12_MAX_DEPTH }; D3D12_RECT stScissorRect = { 0, 0, static_cast(nWndWidth), static_cast(nWndHeight) }; const UINT nMaxGPUParams = 2; //演示仅支持两个GPU进行渲染 @@ -375,12 +375,6 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l // 枚举适配器创建设备 {// 使用DXGI的新函数EnumAdapterByGpuPreference来从高到低枚举系统中的显卡 - - //D3D12_FEATURE_DATA_ARCHITECTURE stArchitecture = {}; - //ID3D12Device4* pID3DDeviceTmp = nullptr; - //IDXGIOutput* pIOutput = nullptr; - //HRESULT hrEnumOutput = S_OK; - DXGI_ADAPTER_DESC1 stAdapterDesc[nMaxGPUParams] = {}; IDXGIAdapter1* pIAdapterTmp = nullptr; UINT i = 0; @@ -1133,11 +1127,7 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l stGPUParams[nIDGPUMain].m_pID3D12Device4->GetCopyableFootprints(&stDefaultResDesc, nFirstSubresource, nNumSubresources, 0, pLayouts, pNumRows, pRowSizesInBytes, &n64RequiredSize); BYTE* pData = nullptr; - HRESULT hr = stModuleParams[i].pITextureUpload->Map(0, nullptr, reinterpret_cast(&pData)); - if (FAILED(hr)) - { - return 0; - } + GRS_THROW_IF_FAILED(stModuleParams[i].pITextureUpload->Map(0, nullptr, reinterpret_cast(&pData))); // 第一遍Copy!注意3重循环每重的意思 for (UINT nSubRes = 0; nSubRes < nNumSubresources; ++nSubRes) @@ -1194,7 +1184,6 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l //同步 D3D12_RESOURCE_BARRIER stUploadTransResBarrier = {}; - stUploadTransResBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; stUploadTransResBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; stUploadTransResBarrier.Transition.pResource = stModuleParams[i].pITexture.Get(); @@ -1657,14 +1646,14 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = stGPUParams[nIDGPUMain].m_pIDHRTV->GetCPUDescriptorHandleForHeapStart(); rtvHandle.ptr += (nCurrentFrameIndex * stGPUParams[nIDGPUMain].m_nszRTV); - D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = stGPUParams[nIDGPUMain].m_pIDHDSVTex->GetCPUDescriptorHandleForHeapStart(); + D3D12_CPU_DESCRIPTOR_HANDLE stDSVHandle = stGPUParams[nIDGPUMain].m_pIDHDSVTex->GetCPUDescriptorHandleForHeapStart(); stGPUParams[nIDGPUMain].m_pICmdList->OMSetRenderTargets( - 1, &rtvHandle, false, &dsvHandle); + 1, &rtvHandle, false, &stDSVHandle); stGPUParams[nIDGPUMain].m_pICmdList->ClearRenderTargetView( rtvHandle, arf4ClearColor, 0, nullptr); stGPUParams[nIDGPUMain].m_pICmdList->ClearDepthStencilView( - dsvHandle, D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, nullptr); + stDSVHandle, D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, nullptr); //执行实际的物体绘制渲染,Draw Call! for (int i = 0; i < nMaxObject; i++) diff --git a/8-UIRenderBase/8-UIRenderBase.cpp b/8-UIRenderBase/8-UIRenderBase.cpp index 43527033c2a5dc30ad1861fb9c98ff38b4cb5c1b..63130c7446ba30c17edaa443bb3386cd4ff0a23f 100644 --- a/8-UIRenderBase/8-UIRenderBase.cpp +++ b/8-UIRenderBase/8-UIRenderBase.cpp @@ -202,6 +202,8 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l UINT nFrame = 0; UINT nRTVDescriptorSize = 0U; + UINT nSRVDescriptorSize = 0U; + UINT nSampleDescriptorSize = 0U; HWND hWnd = nullptr; MSG msg = {}; @@ -224,7 +226,7 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l D3D12_PLACED_SUBRESOURCE_FOOTPRINT stTxtLayouts = {}; D3D12_RESOURCE_DESC stTextureDesc = {}; - D3D12_VIEWPORT stViewPort = { 0.0f, 0.0f, static_cast(iWndWidth), static_cast(iWndHeight), 0.0f, 1.0f }; + D3D12_VIEWPORT stViewPort = { 0.0f, 0.0f, static_cast(iWndWidth), static_cast(iWndHeight), D3D12_MIN_DEPTH, D3D12_MAX_DEPTH }; D3D12_RECT stScissorRect = { 0, 0, static_cast(iWndWidth), static_cast(iWndHeight) }; ComPtr pIDXGIFactory5; @@ -491,6 +493,11 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l , stAdapterDesc.Description); ::SetWindowText(hWnd, pszWndTitle); + + //得到每个描述符元素的大小 + nRTVDescriptorSize = pID3D12Device4->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); + nSRVDescriptorSize = pID3D12Device4->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + nSampleDescriptorSize = pID3D12Device4->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); } // 创建直接命令队列 @@ -552,8 +559,8 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l stRTVHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; GRS_THROW_IF_FAILED(pID3D12Device4->CreateDescriptorHeap(&stRTVHeapDesc, IID_PPV_ARGS(&pIRTVHeap))); - //得到每个描述符元素的大小 - nRTVDescriptorSize = pID3D12Device4->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); + + //--------------------------------------------------------------------------------------------- //9、创建RTV的描述符 @@ -1035,10 +1042,10 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l cbvDesc.BufferLocation = pICBMVO->GetGPUVirtualAddress(); cbvDesc.SizeInBytes = static_cast(szCBBuf); - D3D12_CPU_DESCRIPTOR_HANDLE cbvSrvHandle = pISRVHeap->GetCPUDescriptorHandleForHeapStart(); - cbvSrvHandle.ptr += pID3D12Device4->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + D3D12_CPU_DESCRIPTOR_HANDLE stSRVCBVHandle = pISRVHeap->GetCPUDescriptorHandleForHeapStart(); + stSRVCBVHandle.ptr += nSRVDescriptorSize; - pID3D12Device4->CreateConstantBufferView(&cbvDesc, cbvSrvHandle); + pID3D12Device4->CreateConstantBufferView(&cbvDesc, stSRVCBVHandle); // Sample View D3D12_SAMPLER_DESC stSamplerDesc = {}; @@ -1065,7 +1072,7 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l pICmdBundlesQuad->SetGraphicsRootDescriptorTable(0, pISRVHeap->GetGPUDescriptorHandleForHeapStart()); D3D12_GPU_DESCRIPTOR_HANDLE stGPUCBVHandle = pISRVHeap->GetGPUDescriptorHandleForHeapStart(); - stGPUCBVHandle.ptr += pID3D12Device4->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + stGPUCBVHandle.ptr += nSRVDescriptorSize; pICmdBundlesQuad->SetGraphicsRootDescriptorTable(1, stGPUCBVHandle); pICmdBundlesQuad->SetGraphicsRootDescriptorTable(2, pISampleHeap->GetGPUDescriptorHandleForHeapStart()); diff --git a/9-D3D12RenderToTexture/9-RenderToTexture.cpp b/9-D3D12RenderToTexture/9-RenderToTexture.cpp index 674d585aebc72a0fc9b4cff00c2e50ee6a0d3327..ec0b1a80e4ec39846deb1876c416131cba090202 100644 --- a/9-D3D12RenderToTexture/9-RenderToTexture.cpp +++ b/9-D3D12RenderToTexture/9-RenderToTexture.cpp @@ -13,7 +13,6 @@ #include #endif #include -#include "..\WindowsCommons\d3dx12.h" #include "..\WindowsCommons\DDSTextureLoader12.h" using namespace std; using namespace Microsoft; @@ -35,6 +34,12 @@ using namespace DirectX; //更简洁的向上边界对齐算法 内存管理中常用 请记住 #define GRS_UPPER(A,B) ((UINT)(((A)+((B)-1))&~(B - 1))) +// 内存分配的宏定义 +#define GRS_ALLOC(sz) ::HeapAlloc(GetProcessHeap(),0,(sz)) +#define GRS_CALLOC(sz) ::HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(sz)) +#define GRS_CREALLOC(p,sz) ::HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(p),(sz)) +#define GRS_SAFE_FREE(p) if( nullptr != (p) ){ ::HeapFree( ::GetProcessHeap(),0,(p) ); (p) = nullptr; } + //------------------------------------------------------------------------------------------------------------ // 为了调试加入下面的内联函数和宏定义,为每个接口对象设置名称,方便查看调试输出 #if defined(_DEBUG) @@ -200,28 +205,30 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l MSG msg = {}; TCHAR pszAppPath[MAX_PATH] = {}; - CD3DX12_VIEWPORT stViewPort(0.0f, 0.0f, static_cast(iWndWidth), static_cast(iWndHeight)); - CD3DX12_RECT stScissorRect(0, 0, static_cast(iWndWidth), static_cast(iWndHeight)); + D3D12_VIEWPORT stViewPort = { 0.0f, 0.0f, static_cast(iWndWidth), static_cast(iWndHeight), D3D12_MIN_DEPTH, D3D12_MAX_DEPTH }; + D3D12_RECT stScissorRect = { 0, 0, static_cast(iWndWidth), static_cast(iWndHeight) }; //被渲染纹理的清除颜色,创建时清除色和渲染前清除色保持一致,否则会出现一个未得到优化的警告 const float f4RTTexClearColor[] = { 0.8f, 0.8f, 0.8f, 0.0f }; - UINT nDXGIFactoryFlags = 0U; - const UINT nFrameBackBufCount = 3u; UINT nCurrentFrameIndex = 0; UINT nRTVDescriptorSize = 0U; + UINT nSRVDescriptorSize = 0U; + UINT nSampleDescriptorSize = 0U; ComPtr pIDXGIFactory5; + ComPtr pIDXGIFactory6; ComPtr pIAdapter1; ComPtr pID3D12Device4; ComPtr pIMainCmdQueue; ComPtr pISwapChain1; ComPtr pISwapChain3; ComPtr pIARenderTargets[nFrameBackBufCount]; + ComPtr pIDepthStencilBuffer; //深度蜡板缓冲区 ComPtr pIRTVHeap; ComPtr pIDSVHeap; //深度缓冲描述符堆 - ComPtr pIDepthStencilBuffer; //深度蜡板缓冲区 + DXGI_FORMAT emRTFormat = DXGI_FORMAT_R8G8B8A8_UNORM; DXGI_FORMAT emDSFormat = DXGI_FORMAT_D24_UNORM_S8_UINT; @@ -268,8 +275,34 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l // 常量缓冲区大小上对齐到256Bytes边界 // D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT SIZE_T szMVPBuf = GRS_UPPER(sizeof(ST_GRS_MVP), 256); - UINT nQuadVertexCnt = 0; + + D3D12_HEAP_PROPERTIES stDefautHeapProps = {}; + stDefautHeapProps.Type = D3D12_HEAP_TYPE_DEFAULT; + stDefautHeapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + stDefautHeapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + stDefautHeapProps.CreationNodeMask = 0; + stDefautHeapProps.VisibleNodeMask = 0; + + D3D12_HEAP_PROPERTIES stUploadHeapProps = {}; + stUploadHeapProps.Type = D3D12_HEAP_TYPE_UPLOAD; + stUploadHeapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + stUploadHeapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + stUploadHeapProps.CreationNodeMask = 0; + stUploadHeapProps.VisibleNodeMask = 0; + + D3D12_RESOURCE_DESC stBufferResSesc = {}; + stBufferResSesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + stBufferResSesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + stBufferResSesc.Flags = D3D12_RESOURCE_FLAG_NONE; + stBufferResSesc.Format = DXGI_FORMAT_UNKNOWN; + stBufferResSesc.Width = 0; + stBufferResSesc.Height = 1; + stBufferResSesc.DepthOrArraySize = 1; + stBufferResSesc.MipLevels = 1; + stBufferResSesc.SampleDesc.Count = 1; + stBufferResSesc.SampleDesc.Quality = 0; + try { // 得到当前的工作目录,方便我们使用相对路径来访问各种资源文件 @@ -331,8 +364,10 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l } } - // 打开显示子系统的调试支持 + // 创建DXGI Factory对象 { + UINT nDXGIFactoryFlags = 0U; + // 打开显示子系统的调试支持 #if defined(_DEBUG) ComPtr debugController; if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController)))) @@ -341,51 +376,30 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l // 打开附加的调试支持 nDXGIFactoryFlags |= DXGI_CREATE_FACTORY_DEBUG; } -#endif - } - - // 创建DXGI Factory对象 - { +#endif GRS_THROW_IF_FAILED(CreateDXGIFactory2(nDXGIFactoryFlags, IID_PPV_ARGS(&pIDXGIFactory5))); GRS_SET_DXGI_DEBUGNAME_COMPTR(pIDXGIFactory5); - // 关闭ALT+ENTER键切换全屏的功能,因为我们没有实现OnSize处理,所以先关闭 - GRS_THROW_IF_FAILED(pIDXGIFactory5->MakeWindowAssociation(hWnd, DXGI_MWA_NO_ALT_ENTER)); + //获取IDXGIFactory6接口 + GRS_THROW_IF_FAILED(pIDXGIFactory5.As(&pIDXGIFactory6)); + GRS_SET_DXGI_DEBUGNAME_COMPTR(pIDXGIFactory6); } - // 枚举适配器创建设备 - {//选择NUMA架构的独显来创建3D设备对象,暂时先不支持集显了,当然你可以修改这些行为 - D3D12_FEATURE_DATA_ARCHITECTURE stArchitecture = {}; - DXGI_ADAPTER_DESC1 stAdapterDesc = {}; - for (UINT nAdapterIndex = 0; DXGI_ERROR_NOT_FOUND != pIDXGIFactory5->EnumAdapters1(nAdapterIndex, &pIAdapter1); ++nAdapterIndex) - { - pIAdapter1->GetDesc1(&stAdapterDesc); - - if (stAdapterDesc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) - {//跳过软件虚拟适配器设备 - continue; - } - - GRS_THROW_IF_FAILED(D3D12CreateDevice(pIAdapter1.Get(), D3D_FEATURE_LEVEL_12_1, IID_PPV_ARGS(&pID3D12Device4))); - GRS_THROW_IF_FAILED(pID3D12Device4->CheckFeatureSupport(D3D12_FEATURE_ARCHITECTURE - , &stArchitecture, sizeof(D3D12_FEATURE_DATA_ARCHITECTURE))); - - if (!stArchitecture.UMA) - { - break; - } - - pID3D12Device4.Reset(); - } + // 枚举高性能适配器来创建D3D设备对象 + { + GRS_THROW_IF_FAILED(pIDXGIFactory6->EnumAdapterByGpuPreference( + 0 + , DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE + , IID_PPV_ARGS(&pIAdapter1))); - //--------------------------------------------------------------------------------------------- - if (nullptr == pID3D12Device4.Get()) - {// 可怜的机器上居然没有独显 还是先退出了事 - throw CGRSCOMException(E_FAIL); - } + GRS_THROW_IF_FAILED(D3D12CreateDevice( + pIAdapter1.Get() + , D3D_FEATURE_LEVEL_12_1 + , IID_PPV_ARGS(&pID3D12Device4))); GRS_SET_D3D12_DEBUGNAME_COMPTR(pID3D12Device4); TCHAR pszWndTitle[MAX_PATH] = {}; + DXGI_ADAPTER_DESC1 stAdapterDesc = {}; GRS_THROW_IF_FAILED(pIAdapter1->GetDesc1(&stAdapterDesc)); ::GetWindowText(hWnd, pszWndTitle, MAX_PATH); StringCchPrintf(pszWndTitle @@ -394,19 +408,21 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l , pszWndTitle , stAdapterDesc.Description); ::SetWindowText(hWnd, pszWndTitle); + + //得到每个描述符元素的大小 + nRTVDescriptorSize = pID3D12Device4->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); + nSRVDescriptorSize = pID3D12Device4->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + nSampleDescriptorSize = pID3D12Device4->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); } - // 创建直接命令队列 + // 创建直接命令队列直接命令列表 { D3D12_COMMAND_QUEUE_DESC stQueueDesc = {}; stQueueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; GRS_THROW_IF_FAILED(pID3D12Device4->CreateCommandQueue(&stQueueDesc, IID_PPV_ARGS(&pIMainCmdQueue))); GRS_SET_D3D12_DEBUGNAME_COMPTR(pIMainCmdQueue); - } - // 创建直接命令列表 - { - // 预处理命令列表 + // 创建直接命令列表 GRS_THROW_IF_FAILED(pID3D12Device4->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT , IID_PPV_ARGS(&pICmdAlloc))); GRS_SET_D3D12_DEBUGNAME_COMPTR(pICmdAlloc); @@ -452,18 +468,20 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l GRS_THROW_IF_FAILED(pID3D12Device4->CreateDescriptorHeap(&stRTVHeapDesc, IID_PPV_ARGS(&pIRTVHeap))); GRS_SET_D3D12_DEBUGNAME_COMPTR(pIRTVHeap); - //得到每个描述符元素的大小 - nRTVDescriptorSize = pID3D12Device4->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); - + //--------------------------------------------------------------------------------------------- - CD3DX12_CPU_DESCRIPTOR_HANDLE stRTVHandle(pIRTVHeap->GetCPUDescriptorHandleForHeapStart()); + D3D12_CPU_DESCRIPTOR_HANDLE stRTVHandle = pIRTVHeap->GetCPUDescriptorHandleForHeapStart(); for (UINT i = 0; i < nFrameBackBufCount; i++) {//这个循环暴漏了描述符堆实际上是个数组的本质 GRS_THROW_IF_FAILED(pISwapChain3->GetBuffer(i, IID_PPV_ARGS(&pIARenderTargets[i]))); GRS_SET_D3D12_DEBUGNAME_INDEXED_COMPTR(pIARenderTargets, i); pID3D12Device4->CreateRenderTargetView(pIARenderTargets[i].Get(), nullptr, stRTVHandle); - stRTVHandle.Offset(1, nRTVDescriptorSize); + stRTVHandle.ptr += nRTVDescriptorSize; } + + // 关闭ALT+ENTER键切换全屏的功能,因为我们没有实现OnSize处理,所以先关闭 + GRS_THROW_IF_FAILED(pIDXGIFactory5->MakeWindowAssociation(hWnd, DXGI_MWA_NO_ALT_ENTER)); + } // 创建深度缓冲及深度缓冲描述符堆 @@ -475,17 +493,23 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l //使用隐式默认堆创建一个深度蜡板缓冲区, //因为基本上深度缓冲区会一直被使用,重用的意义不大,所以直接使用隐式堆,图方便 + D3D12_RESOURCE_DESC stDSResDesc = {}; + stDSResDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + stDSResDesc.Alignment = 0; + stDSResDesc.Format = emDSFormat; + stDSResDesc.Width = iWndWidth; + stDSResDesc.Height = iWndHeight; + stDSResDesc.DepthOrArraySize = 1; + stDSResDesc.MipLevels = 0; + stDSResDesc.SampleDesc.Count = 1; + stDSResDesc.SampleDesc.Quality = 0; + stDSResDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + stDSResDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL; + GRS_THROW_IF_FAILED(pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT) + &stDefautHeapProps , D3D12_HEAP_FLAG_NONE - , &CD3DX12_RESOURCE_DESC::Tex2D(emDSFormat - , iWndWidth - , iWndHeight - , 1 - , 0 - , 1 - , 0 - , D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) + , &stDSResDesc , D3D12_RESOURCE_STATE_DEPTH_WRITE , &stDepthOptimizedClearValue , IID_PPV_ARGS(&pIDepthStencilBuffer) @@ -515,31 +539,59 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l // 检测是否支持V1.1版本的根签名 stFeatureData.HighestVersion = D3D_ROOT_SIGNATURE_VERSION_1_1; if (FAILED(pID3D12Device4->CheckFeatureSupport(D3D12_FEATURE_ROOT_SIGNATURE, &stFeatureData, sizeof(stFeatureData)))) - { - stFeatureData.HighestVersion = D3D_ROOT_SIGNATURE_VERSION_1_0; + {// 1.0版 直接丢异常退出了 + GRS_THROW_IF_FAILED(E_NOTIMPL); } - CD3DX12_DESCRIPTOR_RANGE1 stDSPRanges[3]; - stDSPRanges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0); - stDSPRanges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0); - stDSPRanges[2].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 1, 0); - - CD3DX12_ROOT_PARAMETER1 stRootParameters[3]; - stRootParameters[0].InitAsDescriptorTable(1, &stDSPRanges[0], D3D12_SHADER_VISIBILITY_ALL); //CBV是所有Shader可见 - stRootParameters[1].InitAsDescriptorTable(1, &stDSPRanges[1], D3D12_SHADER_VISIBILITY_PIXEL);//SRV仅PS可见 - stRootParameters[2].InitAsDescriptorTable(1, &stDSPRanges[2], D3D12_SHADER_VISIBILITY_PIXEL);//SAMPLE仅PS可见 - - CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC stRootSignatureDesc; - stRootSignatureDesc.Init_1_1(_countof(stRootParameters) - , stRootParameters - , 0 - , nullptr - , D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT); + D3D12_DESCRIPTOR_RANGE1 stDSPRanges[3] = {}; + stDSPRanges[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_CBV; + stDSPRanges[0].NumDescriptors = 1; + stDSPRanges[0].BaseShaderRegister = 0; + stDSPRanges[0].RegisterSpace = 0; + stDSPRanges[0].Flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE; + stDSPRanges[0].OffsetInDescriptorsFromTableStart = 0; + + stDSPRanges[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + stDSPRanges[1].NumDescriptors = 1; + stDSPRanges[1].BaseShaderRegister = 0; + stDSPRanges[1].RegisterSpace = 0; + stDSPRanges[1].Flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE; + stDSPRanges[1].OffsetInDescriptorsFromTableStart = 0; + + stDSPRanges[2].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER; + stDSPRanges[2].NumDescriptors = 1; + stDSPRanges[2].BaseShaderRegister = 0; + stDSPRanges[2].RegisterSpace = 0; + stDSPRanges[2].Flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE; + stDSPRanges[2].OffsetInDescriptorsFromTableStart = 0; + + D3D12_ROOT_PARAMETER1 stRootParameters[3] = {}; + stRootParameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + stRootParameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;//CBV是所有Shader可见 + stRootParameters[0].DescriptorTable.NumDescriptorRanges = 1; + stRootParameters[0].DescriptorTable.pDescriptorRanges = &stDSPRanges[0]; + + stRootParameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + stRootParameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;//SRV仅PS可见 + stRootParameters[1].DescriptorTable.NumDescriptorRanges = 1; + stRootParameters[1].DescriptorTable.pDescriptorRanges = &stDSPRanges[1]; + + stRootParameters[2].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + stRootParameters[2].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;//SAMPLE仅PS可见 + stRootParameters[2].DescriptorTable.NumDescriptorRanges = 1; + stRootParameters[2].DescriptorTable.pDescriptorRanges = &stDSPRanges[2]; + + D3D12_VERSIONED_ROOT_SIGNATURE_DESC stRootSignatureDesc = {}; + stRootSignatureDesc.Version = D3D_ROOT_SIGNATURE_VERSION_1_1; + stRootSignatureDesc.Desc_1_1.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT; + stRootSignatureDesc.Desc_1_1.NumParameters = _countof(stRootParameters); + stRootSignatureDesc.Desc_1_1.pParameters = stRootParameters; + stRootSignatureDesc.Desc_1_1.NumStaticSamplers = 0; + stRootSignatureDesc.Desc_1_1.pStaticSamplers = nullptr; ComPtr pISignatureBlob; ComPtr pIErrorBlob; - GRS_THROW_IF_FAILED(D3DX12SerializeVersionedRootSignature(&stRootSignatureDesc - , stFeatureData.HighestVersion + GRS_THROW_IF_FAILED(D3D12SerializeVersionedRootSignature(&stRootSignatureDesc , &pISignatureBlob , &pIErrorBlob)); @@ -550,11 +602,10 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l GRS_SET_D3D12_DEBUGNAME_COMPTR(pIRSPass1); + UINT compileFlags = 0; #if defined(_DEBUG) // Enable better shader debugging with the graphics debugging tools. - UINT compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; -#else - UINT compileFlags = 0; + compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; #endif //编译为行矩阵形式 compileFlags |= D3DCOMPILE_PACK_MATRIX_ROW_MAJOR; @@ -579,10 +630,18 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l D3D12_GRAPHICS_PIPELINE_STATE_DESC stPSODesc = {}; stPSODesc.InputLayout = { stIALayoutSphere, _countof(stIALayoutSphere) }; stPSODesc.pRootSignature = pIRSPass1.Get(); - stPSODesc.VS = CD3DX12_SHADER_BYTECODE(pIVSShader.Get()); - stPSODesc.PS = CD3DX12_SHADER_BYTECODE(pIPSShader.Get()); - stPSODesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT); - stPSODesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT); + stPSODesc.VS.BytecodeLength = pIVSShader->GetBufferSize(); + stPSODesc.VS.pShaderBytecode = pIVSShader->GetBufferPointer(); + stPSODesc.PS.BytecodeLength = pIPSShader->GetBufferSize(); + stPSODesc.PS.pShaderBytecode = pIPSShader->GetBufferPointer(); + + stPSODesc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID; + stPSODesc.RasterizerState.CullMode = D3D12_CULL_MODE_BACK; + + stPSODesc.BlendState.AlphaToCoverageEnable = FALSE; + stPSODesc.BlendState.IndependentBlendEnable = FALSE; + stPSODesc.BlendState.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL; + stPSODesc.SampleMask = UINT_MAX; stPSODesc.SampleDesc.Count = 1; stPSODesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; @@ -605,31 +664,61 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l // 检测是否支持V1.1版本的根签名 stFeatureData.HighestVersion = D3D_ROOT_SIGNATURE_VERSION_1_1; if (FAILED(pID3D12Device4->CheckFeatureSupport(D3D12_FEATURE_ROOT_SIGNATURE, &stFeatureData, sizeof(stFeatureData)))) - { - stFeatureData.HighestVersion = D3D_ROOT_SIGNATURE_VERSION_1_0; + {// 1.0版 直接丢异常退出了 + GRS_THROW_IF_FAILED(E_NOTIMPL); } //创建渲染矩形的根签名对象 - CD3DX12_DESCRIPTOR_RANGE1 stDSPRanges[3]; - stDSPRanges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0); - stDSPRanges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0); - stDSPRanges[2].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 1, 0); - - CD3DX12_ROOT_PARAMETER1 stRootParameters[3]; - stRootParameters[0].InitAsDescriptorTable(1, &stDSPRanges[0], D3D12_SHADER_VISIBILITY_PIXEL); - stRootParameters[1].InitAsDescriptorTable(1, &stDSPRanges[1], D3D12_SHADER_VISIBILITY_VERTEX); - stRootParameters[2].InitAsDescriptorTable(1, &stDSPRanges[2], D3D12_SHADER_VISIBILITY_PIXEL); - - CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC stRootSignatureDesc; - stRootSignatureDesc.Init_1_1(_countof(stRootParameters), stRootParameters - , 0, nullptr - , D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT); + D3D12_DESCRIPTOR_RANGE1 stDSPRanges[3] = {}; + stDSPRanges[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + stDSPRanges[0].NumDescriptors = 1; + stDSPRanges[0].BaseShaderRegister = 0; + stDSPRanges[0].RegisterSpace = 0; + stDSPRanges[0].Flags = D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC_WHILE_SET_AT_EXECUTE; + stDSPRanges[0].OffsetInDescriptorsFromTableStart = 0; + + stDSPRanges[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_CBV; + stDSPRanges[1].NumDescriptors = 1; + stDSPRanges[1].BaseShaderRegister = 0; + stDSPRanges[1].RegisterSpace = 0; + stDSPRanges[1].Flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE; + stDSPRanges[1].OffsetInDescriptorsFromTableStart = 0; + + stDSPRanges[2].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER; + stDSPRanges[2].NumDescriptors = 1; + stDSPRanges[2].BaseShaderRegister = 0; + stDSPRanges[2].RegisterSpace = 0; + stDSPRanges[2].Flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE; + stDSPRanges[2].OffsetInDescriptorsFromTableStart = 0; + + D3D12_ROOT_PARAMETER1 stRootParameters[3] = {}; + stRootParameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + stRootParameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; + stRootParameters[0].DescriptorTable.NumDescriptorRanges = 1; + stRootParameters[0].DescriptorTable.pDescriptorRanges = &stDSPRanges[0]; + + stRootParameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + stRootParameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + stRootParameters[1].DescriptorTable.NumDescriptorRanges = 1; + stRootParameters[1].DescriptorTable.pDescriptorRanges = &stDSPRanges[1]; + + stRootParameters[2].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + stRootParameters[2].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; + stRootParameters[2].DescriptorTable.NumDescriptorRanges = 1; + stRootParameters[2].DescriptorTable.pDescriptorRanges = &stDSPRanges[2]; + + D3D12_VERSIONED_ROOT_SIGNATURE_DESC stRootSignatureDesc = {}; + stRootSignatureDesc.Version = D3D_ROOT_SIGNATURE_VERSION_1_1; + stRootSignatureDesc.Desc_1_1.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT; + stRootSignatureDesc.Desc_1_1.NumParameters = _countof(stRootParameters); + stRootSignatureDesc.Desc_1_1.pParameters = stRootParameters; + stRootSignatureDesc.Desc_1_1.NumStaticSamplers = 0; + stRootSignatureDesc.Desc_1_1.pStaticSamplers = nullptr; ComPtr pISignatureBlob; ComPtr pIErrorBlob; - GRS_THROW_IF_FAILED(D3DX12SerializeVersionedRootSignature(&stRootSignatureDesc - , stFeatureData.HighestVersion + GRS_THROW_IF_FAILED(D3D12SerializeVersionedRootSignature(&stRootSignatureDesc , &pISignatureBlob , &pIErrorBlob)); @@ -668,10 +757,18 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l D3D12_GRAPHICS_PIPELINE_STATE_DESC stPSODesc = {}; stPSODesc.InputLayout = { stInputElementDescs, _countof(stInputElementDescs) }; stPSODesc.pRootSignature = pIRSQuad.Get(); - stPSODesc.VS = CD3DX12_SHADER_BYTECODE(pIBlobVertexShader.Get()); - stPSODesc.PS = CD3DX12_SHADER_BYTECODE(pIBlobPixelShader.Get()); - stPSODesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT); - stPSODesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT); + stPSODesc.VS.BytecodeLength = pIBlobVertexShader->GetBufferSize(); + stPSODesc.VS.pShaderBytecode = pIBlobVertexShader->GetBufferPointer(); + stPSODesc.PS.BytecodeLength = pIBlobPixelShader->GetBufferSize(); + stPSODesc.PS.pShaderBytecode = pIBlobPixelShader->GetBufferPointer(); + + stPSODesc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID; + stPSODesc.RasterizerState.CullMode = D3D12_CULL_MODE_BACK; + + stPSODesc.BlendState.AlphaToCoverageEnable = FALSE; + stPSODesc.BlendState.IndependentBlendEnable = FALSE; + stPSODesc.BlendState.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL; + stPSODesc.DepthStencilState.DepthEnable = FALSE; stPSODesc.DepthStencilState.StencilEnable = FALSE; stPSODesc.SampleMask = UINT_MAX; @@ -687,24 +784,27 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l // 创建渲染目标纹理 { - D3D12_RESOURCE_DESC stTexDepthsDesc = CD3DX12_RESOURCE_DESC::Tex2D( - emRTFormat - , iWndWidth - , iWndHeight - , 1 - , 1 - , 1 - , 0 - , D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET //注意这个标志是纹理可以作为渲染目标使用的关键 - ); + D3D12_RESOURCE_DESC stRenderTargetResDesc = {}; + stRenderTargetResDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + stRenderTargetResDesc.Alignment = 0; + stRenderTargetResDesc.Width = iWndWidth; + stRenderTargetResDesc.Height = iWndHeight; + stRenderTargetResDesc.DepthOrArraySize = 1; + stRenderTargetResDesc.MipLevels = 1; + stRenderTargetResDesc.Format = emRTFormat; + stRenderTargetResDesc.SampleDesc.Count = 1; + stRenderTargetResDesc.SampleDesc.Quality = 0; + stRenderTargetResDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + stRenderTargetResDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; + D3D12_CLEAR_VALUE stClear = {}; stClear.Format = emRTFormat; memcpy(&stClear.Color, &f4RTTexClearColor, 4 * sizeof(float)); GRS_THROW_IF_FAILED(pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT) + &stDefautHeapProps , D3D12_HEAP_FLAG_NONE - , &stTexDepthsDesc + , &stRenderTargetResDesc , D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE , &stClear , IID_PPV_ARGS(&pIResRenderTarget))); @@ -726,20 +826,25 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l stDepthOptimizedClearValue.DepthStencil.Depth = 1.0f; stDepthOptimizedClearValue.DepthStencil.Stencil = 0; + D3D12_RESOURCE_DESC stDSResDesc = {}; + stDSResDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + stDSResDesc.Alignment = 0; + stDSResDesc.Width = iWndWidth; + stDSResDesc.Height = iWndHeight; + stDSResDesc.DepthOrArraySize = 1; + stDSResDesc.MipLevels = 0; + stDSResDesc.Format = emDSFormat; + stDSResDesc.SampleDesc.Count = 1; + stDSResDesc.SampleDesc.Quality = 0; + stDSResDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + stDSResDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL; + //使用隐式默认堆创建一个深度蜡板缓冲区, //因为基本上深度缓冲区会一直被使用,重用的意义不大,所以直接使用隐式堆,图方便 GRS_THROW_IF_FAILED(pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT) + &stDefautHeapProps , D3D12_HEAP_FLAG_NONE - , &CD3DX12_RESOURCE_DESC::Tex2D( - emDSFormat - , iWndWidth - , iWndHeight - , 1 - , 0 - , 1 - , 0 - , D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) + , &stDSResDesc , D3D12_RESOURCE_STATE_DEPTH_WRITE , &stDepthOptimizedClearValue , IID_PPV_ARGS(&pIDSTex) @@ -779,17 +884,18 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l nQuadVertexCnt = _countof(stTriangleVertices); + stBufferResSesc.Width = nQuadVBSize; GRS_THROW_IF_FAILED(pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), - D3D12_HEAP_FLAG_NONE, - &CD3DX12_RESOURCE_DESC::Buffer(nQuadVBSize), - D3D12_RESOURCE_STATE_GENERIC_READ, - nullptr, - IID_PPV_ARGS(&pIVBQuad))); + &stUploadHeapProps + , D3D12_HEAP_FLAG_NONE + , &stBufferResSesc + , D3D12_RESOURCE_STATE_GENERIC_READ + , nullptr + , IID_PPV_ARGS(&pIVBQuad))); GRS_SET_D3D12_DEBUGNAME_COMPTR(pIVBQuad); UINT8* pVertexDataBegin = nullptr; - CD3DX12_RANGE stReadRange(0, 0); // We do not intend to read from this resource on the CPU. + D3D12_RANGE stReadRange = { 0, 0 }; // We do not intend to read from this resource on the CPU. GRS_THROW_IF_FAILED(pIVBQuad->Map(0, &stReadRange, reinterpret_cast(&pVertexDataBegin))); memcpy(pVertexDataBegin, stTriangleVertices, sizeof(stTriangleVertices)); pIVBQuad->Unmap(0, nullptr); @@ -801,13 +907,14 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l // 创建矩形框渲染需要的SRV CBV Sample等 { + stBufferResSesc.Width = szCBMOVBuf; GRS_THROW_IF_FAILED(pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), - D3D12_HEAP_FLAG_NONE, - &CD3DX12_RESOURCE_DESC::Buffer(szCBMOVBuf), - D3D12_RESOURCE_STATE_GENERIC_READ, - nullptr, - IID_PPV_ARGS(&pICBMVO))); + &stUploadHeapProps + , D3D12_HEAP_FLAG_NONE + , &stBufferResSesc + , D3D12_RESOURCE_STATE_GENERIC_READ + , nullptr + , IID_PPV_ARGS(&pICBMVO))); GRS_THROW_IF_FAILED(pICBMVO->Map(0, nullptr, reinterpret_cast(&pMOV))); @@ -835,11 +942,10 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l cbvDesc.BufferLocation = pICBMVO->GetGPUVirtualAddress(); cbvDesc.SizeInBytes = static_cast(szCBMOVBuf); - CD3DX12_CPU_DESCRIPTOR_HANDLE cbvSrvHandle(pIDHQuad->GetCPUDescriptorHandleForHeapStart() - , 1 - , pID3D12Device4->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV)); + D3D12_CPU_DESCRIPTOR_HANDLE stSRVCBVHandle = pIDHQuad->GetCPUDescriptorHandleForHeapStart(); + stSRVCBVHandle.ptr += nSRVDescriptorSize; - pID3D12Device4->CreateConstantBufferView(&cbvDesc, cbvSrvHandle); + pID3D12Device4->CreateConstantBufferView(&cbvDesc, stSRVCBVHandle); //Sample stHeapDesc.NumDescriptors = 1; //只有一个Sample @@ -918,37 +1024,119 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l GRS_SetD3D12DebugNameIndexed(stModuleParams[i].pITexture.Get(), _T("pITexture"), i); - UINT64 n64szUpSphere = GetRequiredIntermediateSize( - stModuleParams[i].pITexture.Get() - , 0 - , static_cast(stArSubResources.size())); D3D12_RESOURCE_DESC stTXDesc = stModuleParams[i].pITexture->GetDesc(); + UINT64 n64szUpSphere = 0; + pID3D12Device4->GetCopyableFootprints(&stTXDesc, 0, static_cast(stArSubResources.size()) + , 0, nullptr, nullptr, nullptr, &n64szUpSphere); + - //创建上传堆 + // 在隐式堆上创建上传资源 + stBufferResSesc.Width = n64szUpSphere; GRS_THROW_IF_FAILED(pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD) + &stUploadHeapProps , D3D12_HEAP_FLAG_NONE - , &CD3DX12_RESOURCE_DESC::Buffer(n64szUpSphere) + , &stBufferResSesc , D3D12_RESOURCE_STATE_GENERIC_READ , nullptr , IID_PPV_ARGS(&stModuleParams[i].pITextureUpload))); GRS_SetD3D12DebugNameIndexed(stModuleParams[i].pITextureUpload.Get(), _T("pITextureUpload"), i); //上传DDS - UpdateSubresources(pICmdList.Get() - , stModuleParams[i].pITexture.Get() - , stModuleParams[i].pITextureUpload.Get() - , 0 - , 0 - , static_cast(stArSubResources.size()) - , stArSubResources.data()); + UINT nFirstSubresource = 0; + UINT nNumSubresources = static_cast(stArSubResources.size()); + D3D12_RESOURCE_DESC stUploadResDesc = stModuleParams[i].pITextureUpload->GetDesc(); + D3D12_RESOURCE_DESC stDefaultResDesc = stModuleParams[i].pITexture->GetDesc(); + + UINT64 n64RequiredSize = 0; + SIZE_T szMemToAlloc = static_cast(sizeof(D3D12_PLACED_SUBRESOURCE_FOOTPRINT) + + sizeof(UINT) + + sizeof(UINT64)) + * nNumSubresources; + + void* pMem = GRS_CALLOC(static_cast(szMemToAlloc)); + + if (nullptr == pMem) + { + throw CGRSCOMException(HRESULT_FROM_WIN32(GetLastError())); + } + + D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts = reinterpret_cast(pMem); + UINT64* pRowSizesInBytes = reinterpret_cast(pLayouts + nNumSubresources); + UINT* pNumRows = reinterpret_cast(pRowSizesInBytes + nNumSubresources); + + // 这里是第二次调用GetCopyableFootprints,就得到了所有子资源的详细信息 + pID3D12Device4->GetCopyableFootprints(&stDefaultResDesc, nFirstSubresource, nNumSubresources, 0, pLayouts, pNumRows, pRowSizesInBytes, &n64RequiredSize); + + BYTE* pData = nullptr; + HRESULT hr = stModuleParams[i].pITextureUpload->Map(0, nullptr, reinterpret_cast(&pData)); + if (FAILED(hr)) + { + return 0; + } + + // 第一遍Copy!注意3重循环每重的意思 + for (UINT nSubRes = 0; nSubRes < nNumSubresources; ++nSubRes) + {// SubResources + if (pRowSizesInBytes[nSubRes] > (SIZE_T)-1) + { + throw CGRSCOMException(E_FAIL); + } + + D3D12_MEMCPY_DEST stCopyDestData = { pData + pLayouts[nSubRes].Offset + , pLayouts[nSubRes].Footprint.RowPitch + , pLayouts[nSubRes].Footprint.RowPitch * pNumRows[nSubRes] + }; + + for (UINT z = 0; z < pLayouts[nSubRes].Footprint.Depth; ++z) + {// Mipmap + BYTE* pDestSlice = reinterpret_cast(stCopyDestData.pData) + stCopyDestData.SlicePitch * z; + const BYTE* pSrcSlice = reinterpret_cast(stArSubResources[nSubRes].pData) + stArSubResources[nSubRes].SlicePitch * z; + for (UINT y = 0; y < pNumRows[nSubRes]; ++y) + {// Rows + memcpy(pDestSlice + stCopyDestData.RowPitch * y, + pSrcSlice + stArSubResources[nSubRes].RowPitch * y, + (SIZE_T)pRowSizesInBytes[nSubRes]); + } + } + } + stModuleParams[i].pITextureUpload->Unmap(0, nullptr); + + // 第二次Copy! + if (stDefaultResDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) + {// Buffer 一次性复制就可以了,因为没有行对齐和行大小不一致的问题,Buffer中行数就是1 + pICmdList->CopyBufferRegion( + stModuleParams[i].pITexture.Get(), 0, stModuleParams[i].pITextureUpload.Get(), pLayouts[0].Offset, pLayouts[0].Footprint.Width); + } + else + { + for (UINT nSubRes = 0; nSubRes < nNumSubresources; ++nSubRes) + { + D3D12_TEXTURE_COPY_LOCATION stDstCopyLocation = {}; + stDstCopyLocation.pResource = stModuleParams[i].pITexture.Get(); + stDstCopyLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + stDstCopyLocation.SubresourceIndex = nSubRes; + + D3D12_TEXTURE_COPY_LOCATION stSrcCopyLocation = {}; + stSrcCopyLocation.pResource = stModuleParams[i].pITextureUpload.Get(); + stSrcCopyLocation.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + stSrcCopyLocation.PlacedFootprint = pLayouts[nSubRes]; + + pICmdList->CopyTextureRegion(&stDstCopyLocation, 0, 0, 0, &stSrcCopyLocation, nullptr); + } + } + + GRS_SAFE_FREE(pMem); //同步 - pICmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition( - stModuleParams[i].pITexture.Get() - , D3D12_RESOURCE_STATE_COPY_DEST - , D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE)); + D3D12_RESOURCE_BARRIER stUploadTransResBarrier = {}; + stUploadTransResBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + stUploadTransResBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + stUploadTransResBarrier.Transition.pResource = stModuleParams[i].pITexture.Get(); + stUploadTransResBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST; + stUploadTransResBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE; + stUploadTransResBarrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + pICmdList->ResourceBarrier(1, &stUploadTransResBarrier); //创建SRV CBV堆 D3D12_DESCRIPTOR_HEAP_DESC stSRVHeapDesc = {}; @@ -967,10 +1155,8 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l stSRVDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; stSRVDesc.Texture2D.MipLevels = 1; - CD3DX12_CPU_DESCRIPTOR_HANDLE stCBVSRVHandle( - stModuleParams[i].pISRVCBVHp->GetCPUDescriptorHandleForHeapStart() - , 1 - , pID3D12Device4->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV)); + D3D12_CPU_DESCRIPTOR_HANDLE stCBVSRVHandle = stModuleParams[i].pISRVCBVHp->GetCPUDescriptorHandleForHeapStart(); + stCBVSRVHandle.ptr += nSRVDescriptorSize; pID3D12Device4->CreateShaderResourceView(stModuleParams[i].pITexture.Get() , &stSRVDesc @@ -1005,10 +1191,11 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l stModuleParams[i].nIndexCnt = stModuleParams[i].nVertexCnt; //创建 Vertex Buffer 仅使用Upload隐式堆 + stBufferResSesc.Width = stModuleParams[i].nVertexCnt * sizeof(ST_GRS_VERTEX); GRS_THROW_IF_FAILED(pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD) + &stUploadHeapProps , D3D12_HEAP_FLAG_NONE - , &CD3DX12_RESOURCE_DESC::Buffer(stModuleParams[i].nVertexCnt * sizeof(ST_GRS_VERTEX)) + , &stBufferResSesc , D3D12_RESOURCE_STATE_GENERIC_READ , nullptr , IID_PPV_ARGS(&stModuleParams[i].pIVertexBuffer))); @@ -1016,17 +1203,18 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l //使用map-memcpy-unmap大法将数据传至顶点缓冲对象 UINT8* pVertexDataBegin = nullptr; - CD3DX12_RANGE stReadRange(0, 0); // We do not intend to read from this resource on the CPU. + D3D12_RANGE stReadRange = { 0, 0 }; // We do not intend to read from this resource on the CPU. GRS_THROW_IF_FAILED(stModuleParams[i].pIVertexBuffer->Map(0, &stReadRange, reinterpret_cast(&pVertexDataBegin))); memcpy(pVertexDataBegin, pstVertices, stModuleParams[i].nVertexCnt * sizeof(ST_GRS_VERTEX)); stModuleParams[i].pIVertexBuffer->Unmap(0, nullptr); //创建 Index Buffer 仅使用Upload隐式堆 + stBufferResSesc.Width = stModuleParams[i].nIndexCnt * sizeof(UINT); GRS_THROW_IF_FAILED(pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD) + &stUploadHeapProps , D3D12_HEAP_FLAG_NONE - , &CD3DX12_RESOURCE_DESC::Buffer(stModuleParams[i].nIndexCnt * sizeof(UINT)) + , &stBufferResSesc , D3D12_RESOURCE_STATE_GENERIC_READ , nullptr , IID_PPV_ARGS(&stModuleParams[i].pIIndexsBuffer))); @@ -1047,14 +1235,15 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l stModuleParams[i].stIndexsBufferView.Format = DXGI_FORMAT_R32_UINT; stModuleParams[i].stIndexsBufferView.SizeInBytes = stModuleParams[i].nIndexCnt * sizeof(UINT); - ::HeapFree(::GetProcessHeap(), 0, pstVertices); - ::HeapFree(::GetProcessHeap(), 0, pnIndices); + GRS_SAFE_FREE(pstVertices); + GRS_SAFE_FREE(pnIndices); // 创建常量缓冲 注意缓冲尺寸设置为256边界对齐大小 + stBufferResSesc.Width = szMVPBuf; GRS_THROW_IF_FAILED(pID3D12Device4->CreateCommittedResource( - &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD) + &stUploadHeapProps , D3D12_HEAP_FLAG_NONE - , &CD3DX12_RESOURCE_DESC::Buffer(szMVPBuf) + , &stBufferResSesc , D3D12_RESOURCE_STATE_GENERIC_READ , nullptr , IID_PPV_ARGS(&stModuleParams[i].pIConstBuffer))); @@ -1084,10 +1273,10 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l stModuleParams[i].pIBundle->SetDescriptorHeaps(_countof(ppHeapsSphere), ppHeapsSphere); //设置SRV - CD3DX12_GPU_DESCRIPTOR_HANDLE stGPUCBVHandleSphere(stModuleParams[i].pISRVCBVHp->GetGPUDescriptorHandleForHeapStart()); + D3D12_GPU_DESCRIPTOR_HANDLE stGPUCBVHandleSphere = stModuleParams[i].pISRVCBVHp->GetGPUDescriptorHandleForHeapStart(); stModuleParams[i].pIBundle->SetGraphicsRootDescriptorTable(0, stGPUCBVHandleSphere); - stGPUCBVHandleSphere.Offset(1, pID3D12Device4->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV)); + stGPUCBVHandleSphere.ptr += nSRVDescriptorSize; //设置CBV stModuleParams[i].pIBundle->SetGraphicsRootDescriptorTable(1, stGPUCBVHandleSphere); @@ -1136,6 +1325,12 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l GRS_THROW_IF_FAILED(pIFence->SetEventOnCompletion(fence, hEventFence)); } + D3D12_RESOURCE_BARRIER stRTVStateTransBarrier = {}; + + stRTVStateTransBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + stRTVStateTransBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + stRTVStateTransBarrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + ULONGLONG n64tmFrameStart = ::GetTickCount64(); ULONGLONG n64tmCurrent = n64tmFrameStart; @@ -1227,23 +1422,22 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l GRS_THROW_IF_FAILED(pICmdList->Reset(pICmdAlloc.Get(), pIPSOPass1.Get())); //设置屏障将渲染目标纹理从资源转换为渲染目标状态 - pICmdList->ResourceBarrier(1 - , &CD3DX12_RESOURCE_BARRIER::Transition( - pIResRenderTarget.Get() - , D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE - , D3D12_RESOURCE_STATE_RENDER_TARGET) - ); - CD3DX12_CPU_DESCRIPTOR_HANDLE stRTVHandle(pIDHRTVTex->GetCPUDescriptorHandleForHeapStart()); - CD3DX12_CPU_DESCRIPTOR_HANDLE dsvHandle(pIDHDSVTex->GetCPUDescriptorHandleForHeapStart()); + stRTVStateTransBarrier.Transition.pResource = pIResRenderTarget.Get(); + stRTVStateTransBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE; + stRTVStateTransBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET; + pICmdList->ResourceBarrier(1, &stRTVStateTransBarrier); + + D3D12_CPU_DESCRIPTOR_HANDLE stRTVHandle = pIDHRTVTex->GetCPUDescriptorHandleForHeapStart(); + D3D12_CPU_DESCRIPTOR_HANDLE stDSVHandle = pIDHDSVTex->GetCPUDescriptorHandleForHeapStart(); //设置渲染目标 - pICmdList->OMSetRenderTargets(1, &stRTVHandle, FALSE, &dsvHandle); + pICmdList->OMSetRenderTargets(1, &stRTVHandle, FALSE, &stDSVHandle); pICmdList->RSSetViewports(1, &stViewPort); pICmdList->RSSetScissorRects(1, &stScissorRect); pICmdList->ClearRenderTargetView(stRTVHandle, f4RTTexClearColor, 0, nullptr); - pICmdList->ClearDepthStencilView(dsvHandle, D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, nullptr); + pICmdList->ClearDepthStencilView(stDSVHandle, D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, nullptr); //第一次执行每个场景物体的的捆绑包,渲染到纹理 for (int i = 0; i < nMaxObject; i++) @@ -1254,11 +1448,10 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l } //渲染完毕将渲染目标纹理由渲染目标状态转换回纹理状态,并准备显示 - pICmdList->ResourceBarrier(1 - , &CD3DX12_RESOURCE_BARRIER::Transition( - pIResRenderTarget.Get() - , D3D12_RESOURCE_STATE_RENDER_TARGET - , D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE)); + stRTVStateTransBarrier.Transition.pResource = pIResRenderTarget.Get(); + stRTVStateTransBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET; + stRTVStateTransBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE; + pICmdList->ResourceBarrier(1, &stRTVStateTransBarrier); //关闭命令列表,去执行 GRS_THROW_IF_FAILED(pICmdList->Close()); @@ -1304,25 +1497,23 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l //第二遍渲染,渲染到屏幕,并显示纹理渲染的结果 { - pICmdList->ResourceBarrier(1 - , &CD3DX12_RESOURCE_BARRIER::Transition( - pIARenderTargets[nCurrentFrameIndex].Get() - , D3D12_RESOURCE_STATE_PRESENT - , D3D12_RESOURCE_STATE_RENDER_TARGET) - ); + stRTVStateTransBarrier.Transition.pResource = pIARenderTargets[nCurrentFrameIndex].Get(); + stRTVStateTransBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT; + stRTVStateTransBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET; + pICmdList->ResourceBarrier(1, &stRTVStateTransBarrier); //偏移描述符指针到指定帧缓冲视图位置 - CD3DX12_CPU_DESCRIPTOR_HANDLE stRTVHandle(pIRTVHeap->GetCPUDescriptorHandleForHeapStart() - , nCurrentFrameIndex, nRTVDescriptorSize); - CD3DX12_CPU_DESCRIPTOR_HANDLE dsvHandle(pIDSVHeap->GetCPUDescriptorHandleForHeapStart()); + D3D12_CPU_DESCRIPTOR_HANDLE stRTVHandle = pIRTVHeap->GetCPUDescriptorHandleForHeapStart(); + stRTVHandle.ptr += ( nCurrentFrameIndex * nRTVDescriptorSize ); + D3D12_CPU_DESCRIPTOR_HANDLE stDSVHandle = pIDSVHeap->GetCPUDescriptorHandleForHeapStart(); //设置渲染目标 - pICmdList->OMSetRenderTargets(1, &stRTVHandle, FALSE, &dsvHandle); + pICmdList->OMSetRenderTargets(1, &stRTVHandle, FALSE, &stDSVHandle); pICmdList->RSSetViewports(1, &stViewPort); pICmdList->RSSetScissorRects(1, &stScissorRect); const float arClearColor[] = { 0.0f, 0.0f, 0.5f, 1.0f }; pICmdList->ClearRenderTargetView(stRTVHandle, arClearColor, 0, nullptr); - pICmdList->ClearDepthStencilView(dsvHandle, D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, nullptr); + pICmdList->ClearDepthStencilView(stDSVHandle, D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, nullptr); //再一次执行每个场景物体的的捆绑包,渲染到屏幕 for (int i = 0; i < nMaxObject; i++) @@ -1352,9 +1543,9 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l ID3D12DescriptorHeap* ppHeapsQuad[] = { pIDHQuad.Get(),pIDHSampleQuad.Get() }; pICmdList->SetDescriptorHeaps(_countof(ppHeapsQuad), ppHeapsQuad); - CD3DX12_GPU_DESCRIPTOR_HANDLE stGPUCBVHandle(pIDHQuad->GetGPUDescriptorHandleForHeapStart()); + D3D12_GPU_DESCRIPTOR_HANDLE stGPUCBVHandle(pIDHQuad->GetGPUDescriptorHandleForHeapStart()); pICmdList->SetGraphicsRootDescriptorTable(0, stGPUCBVHandle); - stGPUCBVHandle.Offset(1, pID3D12Device4->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV)); + stGPUCBVHandle.ptr += nSRVDescriptorSize; pICmdList->SetGraphicsRootDescriptorTable(1, stGPUCBVHandle); pICmdList->SetGraphicsRootDescriptorTable(2, pIDHSampleQuad->GetGPUDescriptorHandleForHeapStart()); @@ -1363,11 +1554,10 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR l //Draw Call!!! pICmdList->DrawInstanced(nQuadVertexCnt, 1, 0, 0); - pICmdList->ResourceBarrier(1 - , &CD3DX12_RESOURCE_BARRIER::Transition( - pIARenderTargets[nCurrentFrameIndex].Get() - , D3D12_RESOURCE_STATE_RENDER_TARGET - , D3D12_RESOURCE_STATE_PRESENT)); + stRTVStateTransBarrier.Transition.pResource = pIARenderTargets[nCurrentFrameIndex].Get(); + stRTVStateTransBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET; + stRTVStateTransBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT; + pICmdList->ResourceBarrier(1, &stRTVStateTransBarrier); //关闭命令列表,去执行 GRS_THROW_IF_FAILED(pICmdList->Close()); @@ -1601,12 +1791,8 @@ BOOL LoadMeshVertex(const CHAR*pszMeshFileName, UINT&nVertexCnt, ST_GRS_VERTEX*& fin.get(input); fin.get(input); - ppVertex = (ST_GRS_VERTEX*)HeapAlloc(::GetProcessHeap() - , HEAP_ZERO_MEMORY - , nVertexCnt * sizeof(ST_GRS_VERTEX)); - ppIndices = (UINT*)HeapAlloc(::GetProcessHeap() - , HEAP_ZERO_MEMORY - , nVertexCnt * sizeof(UINT)); + ppVertex = (ST_GRS_VERTEX*)GRS_CALLOC(nVertexCnt * sizeof(ST_GRS_VERTEX)); + ppIndices = (UINT*)GRS_CALLOC(nVertexCnt * sizeof(UINT)); for (UINT i = 0; i < nVertexCnt; i++) { diff --git a/Revision.md b/Revision.md index 4007bf2baf85f9c7dea596b0603c2ad2dc3cca28..706110ff8e9f9a4edf8327dd2834592403b34f4f 100644 --- a/Revision.md +++ b/Revision.md @@ -44,3 +44,15 @@ D3D12 ERROR: ID3D12CommandQueue::Present: Resource state (0x800: D3D12_RESOURCE_ 2021-6-5 1銆佸幓闄や簡绀轰緥7澶氭樉鍗℃覆鏌撲腑鐨刣3dx12.h鐨勬墍鏈夊紩鐢紱 + +2銆佸幓闄や簡绀轰緥8 UI娓叉煋涓殑d3dx12.h鐨勬墍鏈夊紩鐢紱 + +2021-6-6 + +1銆佸幓闄や簡绀轰緥9娓叉煋鍒扮汗鐞嗙ず渚嬩腑鎵鏈塪3dx12.h鐨勫紩鐢紱 + +2銆佸幓闄や簡绀轰緥10鍑犱釜鍚庡鐞嗙壒鏁堢ず渚嬩腑鎵鏈塪3dx12.h鐨勫紩鐢紱 + +2021-6-7 + +1銆佸幓闄や簡绀轰緥11澶氱嚎绋+澶氭樉鍗℃覆鏌撶ず渚嬩腑鎵鏈塪3dx12.h鐨勫紩鐢紱