#include #include #include #include #include "Bild.h" #include "d3dx12.h" #include "DLLRegister.h" #include "DX12Buffer.h" #include "DX12CommandQueue.h" #include "DX12PixelShader.h" #include "DX12Shader.h" #include "DX12Textur.h" #include "DX12VertexShader.h" #include "Fenster.h" #include "Globals.h" #include "GraphicsApi.h" #include "Kam3D.h" #include "Model3D.h" #include "Model3DList.h" #include "Shader.h" #include "TexturList.h" #include "TexturModel.h" #include "Welt3D.h" using namespace Framework; DirectX12::DirectX12() : GraphicsApi(DIRECTX12), debug(0), device(0), infoQueue(0), directCommandQueue(0), copyCommandQueue(0), computeCommandQueue(0), swapChain(0), rtvHeap(0), dsvHeap(0), shaderBufferHeap(0), depthBuffer(0), backBufferIndex(0), tearing(0), viewPort(0), allowedRenderArea(0), vertexBufferView(0), indexBufferView(0), signature(0), pipeline(0), texturModel(0), uiTextur(0), texturRegister(new TexturList()), vertexShader(0), pixelShader(0) { for (int i = 0; i < 2; i++) backBuffer[i] = 0; } DirectX12::~DirectX12() { if (directCommandQueue) { directCommandQueue->flush(); directCommandQueue->release(); } if (copyCommandQueue) { copyCommandQueue->flush(); copyCommandQueue->release(); } if (computeCommandQueue) { computeCommandQueue->flush(); computeCommandQueue->release(); } if (depthBuffer) depthBuffer->Release(); if (dsvHeap) dsvHeap->Release(); if (shaderBufferHeap) shaderBufferHeap->Release(); if (vertexShader) vertexShader->release(); if (pixelShader) pixelShader->release(); texturRegister->release(); if (uiTextur) uiTextur->release(); if (texturModel) texturModel->release(); if (pipeline) pipeline->Release(); if (signature) signature->Release(); delete indexBufferView; delete vertexBufferView; delete allowedRenderArea; delete viewPort; for (int i = 0; i < 2; i++) { if (backBuffer[i]) backBuffer[i]->Release(); } if (rtvHeap) rtvHeap->Release(); if (swapChain) swapChain->Release(); if (infoQueue) infoQueue->Release(); if (device) { device->Release(); getDLLRegister()->releaseDLL("dxgi.dll"); getDLLRegister()->releaseDLL("d3d12.dll"); } if (debug) debug->Release(); } typedef HRESULT(__stdcall* CreateDXGIFactory2Function)(UINT, REFIID, void**); typedef HRESULT(__stdcall* D3D12CreateDeviceFunction)( IDXGIAdapter*, D3D_FEATURE_LEVEL, REFIID, void**); typedef HRESULT(__stdcall* D3D12GetDebugInterfaceFunction)(REFIID, void**); typedef HRESULT(__stdcall* DXGIGetDebugInterface1Function)( UINT Flags, REFIID riid, _COM_Outptr_ void** pDebug); void DirectX12::initialize( WFenster* fenster, Vec2 backBufferSize, bool fullScreen) { if (device) return GraphicsApi::initialize(fenster, backBufferSize, fullScreen); GraphicsApi::initialize(fenster, backBufferSize, fullScreen); HINSTANCE dxgiDLL = getDLLRegister()->ladeDLL("dxgi.dll", "dxgi.dll"); if (!dxgiDLL) { WMessageBox(fenster->getFensterHandle(), new Text("Fehler"), new Text("dxgi.dll konnte nicht gefunden werden."), MB_ICONERROR); return; } HINSTANCE d3d12DLL = getDLLRegister()->ladeDLL("d3d12.dll", "d3d12.dll"); if (!d3d12DLL) { getDLLRegister()->releaseDLL("dxgi.dll"); WMessageBox(fenster->getFensterHandle(), new Text("Fehler"), new Text("DirectX 12 konnte nicht gefunden werden."), MB_ICONERROR); return; } CreateDXGIFactory2Function createFactory = (CreateDXGIFactory2Function)GetProcAddress( dxgiDLL, "CreateDXGIFactory2"); if (!createFactory) { getDLLRegister()->releaseDLL("dxgi.dll"); getDLLRegister()->releaseDLL("d3d12.dll"); WMessageBox(fenster->getFensterHandle(), new Text("Fehler"), new Text("Der Einstiegspunkt CreateDXGIFactory2 fon DXGI konnte " "nicht gefunden werden."), MB_ICONERROR); return; } D3D12CreateDeviceFunction createDevice = (D3D12CreateDeviceFunction)GetProcAddress( d3d12DLL, "D3D12CreateDevice"); if (!createDevice) { getDLLRegister()->releaseDLL("dxgi.dll"); getDLLRegister()->releaseDLL("d3d12.dll"); WMessageBox(fenster->getFensterHandle(), new Text("Fehler"), new Text("Der Einstiegspunkt D3D12CreateDevice fon DirectX 12 " "konnte nicht gefunden werden."), MB_ICONERROR); return; } PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE d3d12svrsf = (PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE)GetProcAddress( d3d12DLL, "D3D12SerializeVersionedRootSignature"); PFN_D3D12_SERIALIZE_ROOT_SIGNATURE d3d12srsf = (PFN_D3D12_SERIALIZE_ROOT_SIGNATURE)GetProcAddress( d3d12DLL, "D3D12SerializeRootSignature"); bool debugDXGI = 0; #ifdef _DEBUG IDXGIInfoQueue* dxgiInfoQueue; if (debugDX) { D3D12GetDebugInterfaceFunction getDebugInterface = (D3D12GetDebugInterfaceFunction)GetProcAddress( d3d12DLL, "D3D12GetDebugInterface"); if (SUCCEEDED(getDebugInterface(__uuidof(ID3D12Debug), (void**)&debug))) debug->EnableDebugLayer(); DXGIGetDebugInterface1Function dxgiDebugInterface = (DXGIGetDebugInterface1Function)GetProcAddress( dxgiDLL, "DXGIGetDebugInterface1"); if (SUCCEEDED(dxgiDebugInterface( 0, __uuidof(IDXGIInfoQueue), (void**)&dxgiInfoQueue))) debugDXGI = 1; } #endif IDXGIFactory6* factory; UINT createFactoryFlags = 0; #if defined(_DEBUG) if (debugDX && debugDXGI) createFactoryFlags = DXGI_CREATE_FACTORY_DEBUG; #endif HRESULT res = createFactory( createFactoryFlags, __uuidof(IDXGIFactory6), (void**)&factory); if (FAILED(res)) { getDLLRegister()->releaseDLL("dxgi.dll"); getDLLRegister()->releaseDLL("d3d12.dll"); std::cout << "ERROR: createFactory returned " << res << "\n"; WMessageBox(fenster->getFensterHandle(), new Text("Fehler"), new Text("createFactory ist Fehlgeschlagen."), MB_ICONERROR); return; } IDXGIAdapter1* adapter = 0; for (UINT adapterID = 0; DXGI_ERROR_NOT_FOUND != factory->EnumAdapterByGpuPreference(adapterID, DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE, __uuidof(IDXGIAdapter1), (void**)&adapter); ++adapterID) { DXGI_ADAPTER_DESC1 desc; adapter->GetDesc1(&desc); if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) { // Don't select the Basic Render Driver adapter. continue; } // Check to see if the adapter supports Direct3D 12, but don't create // the actual device yet. if (SUCCEEDED(createDevice(adapter, D3D_FEATURE_LEVEL_12_1, _uuidof(ID3D12Device), nullptr))) { char buff[256] = {}; printf_s(buff, L"Direct3D Adapter (%u): VID:%04X, PID:%04X - %ls\n", adapterID, desc.VendorId, desc.DeviceId, desc.Description); std::cout << buff; break; } } if (!adapter) { if (FAILED(factory->EnumWarpAdapter( _uuidof(IDXGIAdapter1), (void**)&adapter))) std::cout << "ERROR: WARP12 not available. Enable the 'Graphics " "Tools' optional feature"; } if (!adapter) { factory->Release(); getDLLRegister()->releaseDLL("dxgi.dll"); getDLLRegister()->releaseDLL("d3d12.dll"); WMessageBox(fenster->getFensterHandle(), new Text("Fehler"), new Text("Es wurde keine passende Grafigkarte gefunden."), MB_ICONERROR); return; } res = createDevice(adapter, D3D_FEATURE_LEVEL_12_1, __uuidof(ID3D12Device5), (void**)&device); adapter->Release(); if (FAILED(res)) { factory->Release(); getDLLRegister()->releaseDLL("dxgi.dll"); getDLLRegister()->releaseDLL("d3d12.dll"); std::cout << "ERROR: createDevice returned " << res << "\n"; WMessageBox(fenster->getFensterHandle(), new Text("Fehler"), new Text("createDevice ist Fehlgeschlagen."), MB_ICONERROR); return; } D3D12_FEATURE_DATA_D3D12_OPTIONS5 featureSupportData = {}; device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS5, &featureSupportData, sizeof(featureSupportData)); if (featureSupportData.RaytracingTier < D3D12_RAYTRACING_TIER_1_0) { device->Release(); factory->Release(); getDLLRegister()->releaseDLL("dxgi.dll"); getDLLRegister()->releaseDLL("d3d12.dll"); std::cout << "ERROR: Raytracing is not available\n"; WMessageBox(fenster->getFensterHandle(), new Text("Fehler"), new Text("Raytracing ist nicht verfügbar. DirectX12 kann nicht " "verwendet werden."), MB_ICONERROR); return; } res = device->QueryInterface(__uuidof(ID3D12InfoQueue), (void**)&infoQueue); if (SUCCEEDED(res)) { if (debugDX) { infoQueue->SetBreakOnSeverity( D3D12_MESSAGE_SEVERITY_CORRUPTION, TRUE); infoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_ERROR, TRUE); infoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_WARNING, TRUE); } // Suppress individual messages by their ID D3D12_MESSAGE_ID DenyIds[] = { // D3D12_MESSAGE_ID_CLEARRENDERTARGETVIEW_MISMATCHINGCLEARVALUE, // // I'm really not sure how to avoid this message. D3D12_MESSAGE_ID_MAP_INVALID_NULLRANGE, // This warning occurs when // using capture frame while // graphics debugging. D3D12_MESSAGE_ID_UNMAP_INVALID_NULLRANGE, // This warning occurs // when using capture // frame while graphics // debugging. }; D3D12_INFO_QUEUE_FILTER NewFilter = {}; NewFilter.DenyList.NumSeverities = 0; //_countof( Severities ); NewFilter.DenyList.pSeverityList = 0; // Severities; NewFilter.DenyList.NumIDs = _countof(DenyIds); NewFilter.DenyList.pIDList = DenyIds; infoQueue->PushStorageFilter(&NewFilter); } directCommandQueue = new DX12DirectCommandQueue(device); copyCommandQueue = new DX12CopyCommandQueue(device); computeCommandQueue = new DX12ComputeCommandQueue(device); IDXGIFactory5* fac5 = 0; factory->QueryInterface(__uuidof(IDXGIFactory5), (void**)&fac5); if (fac5) { res = fac5->CheckFeatureSupport( DXGI_FEATURE_PRESENT_ALLOW_TEARING, &tearing, sizeof(tearing)); if (FAILED(res)) tearing = 0; fac5->Release(); } DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {}; swapChainDesc.Width = backBufferSize.x; swapChainDesc.Height = backBufferSize.y; swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swapChainDesc.Stereo = FALSE; swapChainDesc.SampleDesc = {1, 0}; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.BufferCount = 2; swapChainDesc.Scaling = DXGI_SCALING_STRETCH; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_IGNORE; swapChainDesc.Flags = tearing ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0; IDXGISwapChain1* tmpSwapChain; res = factory->CreateSwapChainForHwnd(directCommandQueue->getQueue(), fenster->getFensterHandle(), &swapChainDesc, 0, 0, &tmpSwapChain); if (FAILED(res)) { factory->Release(); std::cout << "ERROR: CreateSwapChainForHwnd returned " << res << "\n"; WMessageBox(fenster->getFensterHandle(), new Text("Fehler"), new Text("CreateSwapChainForHwnd ist Fehlgeschlagen."), MB_ICONERROR); return; } res = tmpSwapChain->QueryInterface( __uuidof(IDXGISwapChain4), (void**)&swapChain); tmpSwapChain->Release(); if (FAILED(res)) { factory->Release(); std::cout << "ERROR: QueryInterface returned " << res << "\n"; WMessageBox(fenster->getFensterHandle(), new Text("Fehler"), new Text("QueryInterface ist Fehlgeschlagen."), MB_ICONERROR); return; } factory->MakeWindowAssociation( fenster->getFensterHandle(), DXGI_MWA_NO_ALT_ENTER); D3D12_DESCRIPTOR_HEAP_DESC rtvhdesc = {}; rtvhdesc.NumDescriptors = 2; // back buffer count rtvhdesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; res = device->CreateDescriptorHeap( &rtvhdesc, __uuidof(ID3D12DescriptorHeap), (void**)&rtvHeap); if (FAILED(res)) { factory->Release(); std::cout << "ERROR: CreateDescriptorHeap returned " << res << "\n"; WMessageBox(fenster->getFensterHandle(), new Text("Fehler"), new Text("CreateDescriptorHeap ist Fehlgeschlagen."), MB_ICONERROR); return; } auto rtvDescriptorSize = device->GetDescriptorHandleIncrementSize( D3D12_DESCRIPTOR_HEAP_TYPE_RTV); D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle( rtvHeap->GetCPUDescriptorHandleForHeapStart()); for (int i = 0; i < 2; i++) { ID3D12Resource* backBuffer; res = swapChain->GetBuffer( i, __uuidof(ID3D12Resource), (void**)&backBuffer); if (FAILED(res)) { factory->Release(); std::cout << "ERROR: GetBuffer returned " << res << "\n"; WMessageBox(fenster->getFensterHandle(), new Text("Fehler"), new Text("GetBuffer ist Fehlgeschlagen."), MB_ICONERROR); return; } device->CreateRenderTargetView(backBuffer, nullptr, rtvHandle); this->backBuffer[i] = backBuffer; rtvHandle.ptr += rtvDescriptorSize; } viewPort = new D3D12_VIEWPORT(); viewPort->Width = (float)this->backBufferSize.x; viewPort->Height = (float)this->backBufferSize.y; viewPort->MinDepth = 0.0f; viewPort->MaxDepth = 1.0f; viewPort->TopLeftX = 0.0f; viewPort->TopLeftY = 0.0f; allowedRenderArea = new D3D12_RECT(); allowedRenderArea->left = 0; allowedRenderArea->top = 0; allowedRenderArea->right = LONG_MAX; allowedRenderArea->bottom = LONG_MAX; texturModel = new TexturModel(this); Bild* renderB = new Bild(1); renderB->setAlpha3D(1); renderB->neuBild(this->backBufferSize.x, this->backBufferSize.y, 0); uiTextur = createOrGetTextur("_f_Render_Bild", renderB); texturModel->setSize(Vec2(2.f, 2.f)); texturModel->setTextur(dynamic_cast(uiTextur->getThis())); vertexBufferView = new D3D12_VERTEX_BUFFER_VIEW(); vertexBufferView->StrideInBytes = sizeof(Vertex3D); indexBufferView = new D3D12_INDEX_BUFFER_VIEW(); indexBufferView->Format = DXGI_FORMAT_R32_UINT; D3D12_CLEAR_VALUE optimizedClearValue = {}; optimizedClearValue.Format = DXGI_FORMAT_D32_FLOAT; optimizedClearValue.DepthStencil = {1.0f, 0}; CD3DX12_HEAP_PROPERTIES heapProp = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT); CD3DX12_RESOURCE_DESC heapDesc = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_D32_FLOAT, this->backBufferSize.x, this->backBufferSize.y, 1, 0, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL); res = device->CreateCommittedResource(&heapProp, D3D12_HEAP_FLAG_NONE, &heapDesc, D3D12_RESOURCE_STATE_DEPTH_WRITE, &optimizedClearValue, __uuidof(ID3D12Resource), (void**)&depthBuffer); if (FAILED(res)) { factory->Release(); std::cout << "ERROR: CreateCommittedResource returned " << res << "\n"; WMessageBox(fenster->getFensterHandle(), new Text("Fehler"), new Text("CreateCommittedResource ist Fehlgeschlagen."), MB_ICONERROR); return; } D3D12_DESCRIPTOR_HEAP_DESC dsvHeapDesc = {}; dsvHeapDesc.NumDescriptors = 1; dsvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV; dsvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; res = device->CreateDescriptorHeap( &dsvHeapDesc, __uuidof(ID3D12DescriptorHeap), (void**)&dsvHeap); if (FAILED(res)) { factory->Release(); std::cout << "ERROR: CreateDescriptorHeap returned " << res << "\n"; WMessageBox(fenster->getFensterHandle(), new Text("Fehler"), new Text("CreateDescriptorHeap ist Fehlgeschlagen."), MB_ICONERROR); return; } D3D12_DEPTH_STENCIL_VIEW_DESC dsv = {}; dsv.Format = DXGI_FORMAT_D32_FLOAT; dsv.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D; dsv.Texture2D.MipSlice = 0; dsv.Flags = D3D12_DSV_FLAG_NONE; device->CreateDepthStencilView( depthBuffer, &dsv, dsvHeap->GetCPUDescriptorHandleForHeapStart()); D3D12_DESCRIPTOR_HEAP_DESC sbheapDesc = {}; sbheapDesc.NumDescriptors = 6; sbheapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; sbheapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; res = device->CreateDescriptorHeap( &sbheapDesc, __uuidof(ID3D12DescriptorHeap), (void**)&shaderBufferHeap); if (FAILED(res)) { factory->Release(); std::cout << "ERROR: CreateDescriptorHeap returned " << res << "\n"; WMessageBox(fenster->getFensterHandle(), new Text("Fehler"), new Text("CreateDescriptorHeap ist Fehlgeschlagen."), MB_ICONERROR); return; } vertexShader = new DX12VertexShader(device, copyCommandQueue, directCommandQueue); vertexShader->setCompiledByteArray( (unsigned char*)DX12VertexShaderBytes, sizeof(DX12VertexShaderBytes)); vertexShader->erstelleConstBuffer(sizeof(Mat4) * 2, 0); vertexShader->erstelleConstBuffer(sizeof(Mat4) * 128, 1); pixelShader = new DX12PixelShader(device, copyCommandQueue, directCommandQueue); pixelShader->setCompiledByteArray( (unsigned char*)DX12PixelShaderBytes, sizeof(DX12PixelShaderBytes)); pixelShader->erstelleConstBuffer(sizeof(float) * 4, 2); pixelShader->erstelleConstBuffer(sizeof(float) * 3, 3); pixelShader->erstelleConstBuffer(sizeof(int) * 2, 4); D3D12_INPUT_ELEMENT_DESC inputLayout[] = { {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, {"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, {"KNOCHEN_ID", 0, DXGI_FORMAT_R32_UINT, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, {"KNOCHEN_ID", 0, DXGI_FORMAT_R32_UINT, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0} }; vertexShader->erstelleInputLayout(inputLayout, 5); D3D12_FEATURE_DATA_ROOT_SIGNATURE featureData = {}; featureData.HighestVersion = D3D_ROOT_SIGNATURE_VERSION_1_1; if (FAILED(device->CheckFeatureSupport( D3D12_FEATURE_ROOT_SIGNATURE, &featureData, sizeof(featureData)))) featureData.HighestVersion = D3D_ROOT_SIGNATURE_VERSION_1_0; D3D12_ROOT_SIGNATURE_FLAGS rootSignatureFlags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT | D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS | D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS | D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS; D3D12_DESCRIPTOR_RANGE1 range[2]; range[0].NumDescriptors = 5; range[0].BaseShaderRegister = 0; range[0].RegisterSpace = 0; range[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_CBV; range[0].OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND; range[0].Flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE; range[1].NumDescriptors = 1; range[1].BaseShaderRegister = 0; range[1].RegisterSpace = 0; range[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; range[1].OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND; range[1].Flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE; D3D12_ROOT_PARAMETER1 rootParameters[1]; rootParameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; rootParameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; rootParameters[0].DescriptorTable.NumDescriptorRanges = 2; rootParameters[0].DescriptorTable.pDescriptorRanges = range; D3D12_STATIC_SAMPLER_DESC sampler = {}; sampler.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT; sampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_BORDER; sampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_BORDER; sampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_BORDER; sampler.MipLODBias = 0; sampler.MaxAnisotropy = 0; sampler.ComparisonFunc = D3D12_COMPARISON_FUNC_NEVER; sampler.BorderColor = D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK; sampler.MinLOD = 0.0f; sampler.MaxLOD = D3D12_FLOAT32_MAX; sampler.ShaderRegister = 0; sampler.RegisterSpace = 0; sampler.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; D3D12_VERSIONED_ROOT_SIGNATURE_DESC rootSignatureDescription; rootSignatureDescription.Version = D3D_ROOT_SIGNATURE_VERSION_1_1; rootSignatureDescription.Desc_1_1.NumParameters = 1; rootSignatureDescription.Desc_1_1.pParameters = rootParameters; rootSignatureDescription.Desc_1_1.NumStaticSamplers = 1; rootSignatureDescription.Desc_1_1.pStaticSamplers = &sampler; rootSignatureDescription.Desc_1_1.Flags = rootSignatureFlags; ID3DBlob* rootSignature; ID3DBlob* error; res = D3DX12SerializeVersionedRootSignature(&rootSignatureDescription, featureData.HighestVersion, &rootSignature, &error, d3d12svrsf, d3d12srsf); if (FAILED(res)) { factory->Release(); std::cout << "ERROR: D3DX12SerializeVersionedRootSignature returned " << res << "\n"; WMessageBox(fenster->getFensterHandle(), new Text("Fehler"), new Text( "D3DX12SerializeVersionedRootSignature ist Fehlgeschlagen."), MB_ICONERROR); if (error) error->Release(); return; } res = device->CreateRootSignature(0, rootSignature->GetBufferPointer(), rootSignature->GetBufferSize(), __uuidof(ID3D12RootSignature), (void**)&signature); if (FAILED(res)) { factory->Release(); std::cout << "ERROR: CreateRootSignature returned " << res << "\n"; WMessageBox(fenster->getFensterHandle(), new Text("Fehler"), new Text("CreateRootSignature ist Fehlgeschlagen."), MB_ICONERROR); return; } rootSignature->Release(); D3D12_RASTERIZER_DESC rdesc; rdesc.FillMode = D3D12_FILL_MODE_SOLID; rdesc.CullMode = D3D12_CULL_MODE_BACK; rdesc.FrontCounterClockwise = 0; rdesc.DepthBias = 0; rdesc.DepthBiasClamp = 0.f; rdesc.SlopeScaledDepthBias = 0.f; rdesc.DepthClipEnable = 1; rdesc.MultisampleEnable = 0; rdesc.AntialiasedLineEnable = 0; rdesc.ForcedSampleCount = 0; rdesc.ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF; D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {}; psoDesc.InputLayout = {vertexShader->zInputLayout(), (unsigned)vertexShader->getInputLayoutSize()}; psoDesc.pRootSignature = signature; psoDesc.VS = {vertexShader->getCompiledShader(), (unsigned __int64)vertexShader->getCompiledLength()}; psoDesc.PS = {pixelShader->getCompiledShader(), (unsigned __int64)pixelShader->getCompiledLength()}; psoDesc.RasterizerState = rdesc; psoDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT); psoDesc.DepthStencilState.DepthEnable = FALSE; psoDesc.DepthStencilState.StencilEnable = FALSE; psoDesc.SampleMask = UINT_MAX; psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; psoDesc.NumRenderTargets = 1; psoDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; psoDesc.SampleDesc.Count = 1; D3D12_CPU_DESCRIPTOR_HANDLE sbHeapHandle = shaderBufferHeap->GetCPUDescriptorHandleForHeapStart(); unsigned int incr = device->GetDescriptorHandleIncrementSize( D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); D3D12_CONSTANT_BUFFER_VIEW_DESC desc; vertexShader->getViewDesc(0, desc); device->CreateConstantBufferView(&desc, sbHeapHandle); res = device->GetDeviceRemovedReason(); sbHeapHandle.ptr += incr; vertexShader->getViewDesc(1, desc); device->CreateConstantBufferView(&desc, sbHeapHandle); sbHeapHandle.ptr += incr; pixelShader->getViewDesc(2, desc); device->CreateConstantBufferView(&desc, sbHeapHandle); sbHeapHandle.ptr += incr; pixelShader->getViewDesc(3, desc); device->CreateConstantBufferView(&desc, sbHeapHandle); sbHeapHandle.ptr += incr; pixelShader->getViewDesc(4, desc); device->CreateConstantBufferView(&desc, sbHeapHandle); sbHeapHandle.ptr += incr; uiTextur->updateTextur(); D3D12_SHADER_RESOURCE_VIEW_DESC vd; vd.Format = DXGI_FORMAT_B8G8R8A8_UNORM; vd.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; vd.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; vd.Texture2D.MipLevels = 1; vd.Texture2D.MostDetailedMip = 0; vd.Texture2D.PlaneSlice = 0; vd.Texture2D.ResourceMinLODClamp = 0; device->CreateShaderResourceView( ((DX12Textur*)uiTextur)->getResource(), &vd, sbHeapHandle); directCommandQueue->execute(); res = device->CreateGraphicsPipelineState( &psoDesc, __uuidof(ID3D12PipelineState), (void**)&pipeline); if (FAILED(res)) { factory->Release(); std::cout << "ERROR: CreatePipelineState returned " << res << "\n"; WMessageBox(fenster->getFensterHandle(), new Text("Fehler"), new Text("CreatePipelineState ist Fehlgeschlagen."), MB_ICONERROR); return; } factory->Release(); } void DirectX12::update() { if (!device || !swapChain || !directCommandQueue) return; directCommandQueue->flush(); copyCommandQueue->flush(); computeCommandQueue->flush(); modelList->removeAll(); HINSTANCE dxgiDLL = getDLLRegister()->ladeDLL("dxgi.dll", "dxgi.dll"); if (!dxgiDLL) { WMessageBox(fenster->getFensterHandle(), new Text("Fehler"), new Text("dxgi.dll konnte nicht gefunden werden."), MB_ICONERROR); return; } CreateDXGIFactory2Function createFactory = (CreateDXGIFactory2Function)GetProcAddress( dxgiDLL, "CreateDXGIFactory2"); if (!createFactory) { getDLLRegister()->releaseDLL("dxgi.dll"); WMessageBox(fenster->getFensterHandle(), new Text("Fehler"), new Text("Der Einstiegspunkt CreateDXGIFactory2 fon DXGI konnte " "nicht gefunden werden."), MB_ICONERROR); return; } DXGI_SWAP_CHAIN_DESC swapChainDesc = {}; HRESULT res = swapChain->GetDesc(&swapChainDesc); if (FAILED(res)) { getDLLRegister()->releaseDLL("dxgi.dll"); std::cout << "ERROR: GetDesc returned " << res << "\n"; WMessageBox(fenster->getFensterHandle(), new Text("Fehler"), new Text("GetDesc ist Fehlgeschlagen."), MB_ICONERROR); return; } IDXGIFactory4* factory; UINT createFactoryFlags = 0; #if defined(_DEBUG) createFactoryFlags = DXGI_CREATE_FACTORY_DEBUG; #endif res = createFactory( createFactoryFlags, __uuidof(IDXGIFactory4), (void**)&factory); if (FAILED(res)) { getDLLRegister()->releaseDLL("dxgi.dll"); std::cout << "ERROR: createFactory returned " << res << "\n"; WMessageBox(fenster->getFensterHandle(), new Text("Fehler"), new Text("createFactory ist Fehlgeschlagen."), MB_ICONERROR); return; } for (int i = 0; i < 2; ++i) { backBuffer[i]->Release(); backBuffer[i] = 0; } res = swapChain->ResizeBuffers(2, backBufferSize.x, backBufferSize.y, swapChainDesc.BufferDesc.Format, swapChainDesc.Flags); backBufferIndex = swapChain->GetCurrentBackBufferIndex(); auto rtvDescriptorSize = device->GetDescriptorHandleIncrementSize( D3D12_DESCRIPTOR_HEAP_TYPE_RTV); D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle( rtvHeap->GetCPUDescriptorHandleForHeapStart()); for (int i = 0; i < 2; i++) { ID3D12Resource* backBuffer; res = swapChain->GetBuffer( i, __uuidof(ID3D12Resource), (void**)&backBuffer); if (FAILED(res)) { getDLLRegister()->releaseDLL("dxgi.dll"); factory->Release(); std::cout << "ERROR: GetBuffer returned " << res << "\n"; WMessageBox(fenster->getFensterHandle(), new Text("Fehler"), new Text("GetBuffer ist Fehlgeschlagen."), MB_ICONERROR); return; } device->CreateRenderTargetView(backBuffer, nullptr, rtvHandle); this->backBuffer[i] = backBuffer; rtvHandle.ptr += rtvDescriptorSize; } getDLLRegister()->releaseDLL("dxgi.dll"); delete viewPort; viewPort = new D3D12_VIEWPORT(); viewPort->Width = (float)this->backBufferSize.x; viewPort->Height = (float)this->backBufferSize.y; viewPort->MinDepth = 0.0f; viewPort->MaxDepth = 1.0f; viewPort->TopLeftX = 0.0f; viewPort->TopLeftY = 0.0f; depthBuffer->Release(); D3D12_CLEAR_VALUE optimizedClearValue = {}; optimizedClearValue.Format = DXGI_FORMAT_D32_FLOAT; optimizedClearValue.DepthStencil = {1.0f, 0}; CD3DX12_HEAP_PROPERTIES heapProps = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT); CD3DX12_RESOURCE_DESC heapDesc = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_D32_FLOAT, this->backBufferSize.x, this->backBufferSize.y, 1, 0, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL); res = device->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &heapDesc, D3D12_RESOURCE_STATE_DEPTH_WRITE, 0, __uuidof(ID3D12Resource), (void**)&depthBuffer); if (FAILED(res)) { factory->Release(); std::cout << "ERROR: CreateCommittedResource returned " << res << "\n"; WMessageBox(fenster->getFensterHandle(), new Text("Fehler"), new Text("CreateCommittedResource ist Fehlgeschlagen."), MB_ICONERROR); return; } D3D12_DEPTH_STENCIL_VIEW_DESC dsv = {}; dsv.Format = DXGI_FORMAT_D32_FLOAT; dsv.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D; dsv.Texture2D.MipSlice = 0; dsv.Flags = D3D12_DSV_FLAG_NONE; device->CreateDepthStencilView( depthBuffer, &dsv, dsvHeap->GetCPUDescriptorHandleForHeapStart()); if (uiTextur) uiTextur->release(); Bild* renderB = new Bild(1); renderB->setAlpha3D(1); renderB->neuBild(this->backBufferSize.x, this->backBufferSize.y, 0); uiTextur = createOrGetTextur("_f_Render_Bild", renderB); texturModel->setTextur(dynamic_cast(uiTextur->getThis())); factory->Release(); } void DirectX12::beginFrame(bool fill2D, bool fill3D, int fillColor) { D3D12_RESOURCE_BARRIER barrier; ZeroMemory(&barrier, sizeof(barrier)); barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; barrier.Transition.pResource = this->backBuffer[backBufferIndex]; barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT; barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET; barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; directCommandQueue->getCommandList()->ResourceBarrier(1, &barrier); if (fill2D) uiTextur->zBild()->setFarbe(fillColor); if (fill3D) { float color[4]; // Setup the color to clear the buffer. color[0] = ((fillColor >> 16) & 0xFF) / 255.f; // R color[1] = ((fillColor >> 8) & 0xFF) / 255.f; // G color[2] = (fillColor & 0xFF) / 255.f; // B color[3] = ((fillColor >> 24) & 0xFF) / 255.f; // A auto rtvDescriptorSize = device->GetDescriptorHandleIncrementSize( D3D12_DESCRIPTOR_HEAP_TYPE_RTV); D3D12_CPU_DESCRIPTOR_HANDLE rtv = rtvHeap->GetCPUDescriptorHandleForHeapStart(); rtv.ptr += rtvDescriptorSize * backBufferIndex; directCommandQueue->getCommandList()->OMSetRenderTargets(1, &rtv, 0, 0); directCommandQueue->getCommandList()->ClearRenderTargetView( rtv, color, 0, 0); } int lc[] = {0, 0}; pixelShader->füllConstBuffer((char*)lc, 4, sizeof(int) * 2); } void DirectX12::renderObject(Model3D* zObj) { Mat4 trans = Mat4::identity(); zObj->zModelData()->zDXVertexBuffer()->copieren(); zObj->zModelData()->zDXIndexBuffer()->copieren(); int anz = zObj->errechneMatrizen(trans, matrixBuffer); if (vertexShader) vertexShader->füllConstBuffer( (char*)matrixBuffer, 1, sizeof(Mat4) * anz); float matirialBuffer[3]; // light factors (phong model) matirialBuffer[0] = zObj->getAmbientFactor(); matirialBuffer[1] = zObj->getDiffusFactor(); matirialBuffer[2] = zObj->getSpecularFactor(); if (pixelShader) pixelShader->füllConstBuffer( (char*)matirialBuffer, 3, sizeof(float) * 3); unsigned int offset = 0; unsigned int es = (unsigned)zObj->zModelData()->zDXVertexBuffer()->getElementLength(); Model3DTextur* zTextur = zObj->zTextur(); int ind = 0; zObj->beforeRender(this, vertexShader, pixelShader); for (auto i = zObj->zModelData()->getPolygons(); i; i++) { if (zObj->needRenderPolygon(ind)) { Textur* t = zTextur->zPolygonTextur(ind); // if( t &&t->brauchtUpdate() ) // t->updateTextur(); DXGI_FORMAT f = DXGI_FORMAT_R32_UINT; if (zObj->zModelData()->zDXIndexBuffer()->getElementLength() == 2) f = DXGI_FORMAT_R16_UINT; if (zObj->zModelData()->zDXIndexBuffer()->getElementLength() == 1) f = DXGI_FORMAT_R8_UINT; indexBufferView->Format = f; if (t) { /*ID3D11ShaderResourceView *v[ 3 ]; v[ 0 ] = *(DX11Textur *)t; v[ 1 ] = *diffuseLights; v[ 2 ] = *pointLights; d3d11Context->PSSetShaderResources( 0, 3, v ); d3d11Context->DrawIndexed( indexBuffer->getElementAnzahl(), 0, 0 );*/ directCommandQueue->getCommandList()->SetPipelineState( pipeline); directCommandQueue->getCommandList()->SetGraphicsRootSignature( signature); directCommandQueue->getCommandList()->SetDescriptorHeaps( 1, &shaderBufferHeap); directCommandQueue->getCommandList() ->SetGraphicsRootDescriptorTable(0, shaderBufferHeap->GetGPUDescriptorHandleForHeapStart()); directCommandQueue->getCommandList()->RSSetViewports( 1, viewPort); directCommandQueue->getCommandList()->RSSetScissorRects( 1, allowedRenderArea); auto rtvDescriptorSize = device->GetDescriptorHandleIncrementSize( D3D12_DESCRIPTOR_HEAP_TYPE_RTV); D3D12_CPU_DESCRIPTOR_HANDLE rtv = rtvHeap->GetCPUDescriptorHandleForHeapStart(); rtv.ptr += rtvDescriptorSize * backBufferIndex; directCommandQueue->getCommandList()->OMSetRenderTargets( 1, &rtv, 0, 0); indexBufferView->SizeInBytes = zObj->zModelData()->zDXIndexBuffer()->getElementAnzahl() * zObj->zModelData()->zDXIndexBuffer()->getElementLength(); indexBufferView->BufferLocation = ((DX12Buffer*)zObj->zModelData()->zDXIndexBuffer()) ->zBuffer() ->GetGPUVirtualAddress(); directCommandQueue->getCommandList()->IASetIndexBuffer( indexBufferView); vertexBufferView->SizeInBytes = zObj->zModelData()->zDXVertexBuffer()->getElementAnzahl() * zObj->zModelData()->zDXVertexBuffer()->getElementLength(); vertexBufferView->BufferLocation = ((DX12Buffer*)zObj->zModelData()->zDXVertexBuffer()) ->zBuffer() ->GetGPUVirtualAddress(); directCommandQueue->getCommandList()->IASetVertexBuffers( 0, 1, vertexBufferView); directCommandQueue->getCommandList()->IASetPrimitiveTopology( D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); directCommandQueue->getCommandList()->DrawIndexedInstanced( zObj->zModelData()->zDXIndexBuffer()->getElementAnzahl(), 1, 0, 0, 0); } else { /*d3d11Context->RSSetState( meshRS ); ID3D11ShaderResourceView *v[ 3 ]; v[ 0 ] = *(DX11Textur *)defaultTextur; v[ 1 ] = *diffuseLights; v[ 2 ] = *pointLights; d3d11Context->PSSetShaderResources( 0, 3, v ); d3d11Context->DrawIndexed( indexBuffer->getElementAnzahl(), 0, 0 ); d3d11Context->RSSetState( texturRS );*/ // directCommandQueue->getCommandList()->DrawIndexedInstanced( // indexBuffer->getElementAnzahl(), 1, 0, 0, 0 ); } } ind++; } zObj->afterRender(this, pixelShader, vertexShader); } // Überprüft, ob eine Kugel in dem Sichtbaren Raum der Welt liegt und gezeichnet // werden muss // pos: Der Mittelpunkt der Kugel // radius: Der Radius der Kugel // dist: Einen Zeiger auf einen float, in dem das quadrat des Abstands zur // Kammeraposition gespeichert wird, falls diese Funktion true zurückgiebt und // der Zeiger nicht 0 ist bool DirectX12::isInFrustrum( const Vec3& pos, float radius, float* dist) const { for (int i = 0; i < 6; i++) { if (frustrum[i] * pos + radius < 0) return 0; } if (dist) *dist = kamPos.abstand(pos); return 1; } void DirectX12::renderKamera(Kam3D* zKamera) { directCommandQueue->getCommandList()->RSSetViewports( 1, (D3D12_VIEWPORT*)zKamera->zViewPort()); Mat4 tmp = zKamera->getProjectionMatrix() * zKamera->getViewMatrix(); frustrum[0].x = tmp.elements[3][0] + tmp.elements[0][0]; frustrum[0].y = tmp.elements[3][1] + tmp.elements[0][1]; frustrum[0].z = tmp.elements[3][2] + tmp.elements[0][2]; frustrum[0].w = tmp.elements[3][3] + tmp.elements[0][3]; frustrum[1].x = tmp.elements[3][0] - tmp.elements[0][0]; frustrum[1].y = tmp.elements[3][1] - tmp.elements[0][1]; frustrum[1].z = tmp.elements[3][2] - tmp.elements[0][2]; frustrum[1].w = tmp.elements[3][3] - tmp.elements[0][3]; frustrum[2].x = tmp.elements[3][0] - tmp.elements[1][0]; frustrum[2].y = tmp.elements[3][1] - tmp.elements[1][1]; frustrum[2].z = tmp.elements[3][2] - tmp.elements[1][2]; frustrum[2].w = tmp.elements[3][3] - tmp.elements[1][3]; frustrum[3].x = tmp.elements[3][0] + tmp.elements[1][0]; frustrum[3].y = tmp.elements[3][1] + tmp.elements[1][1]; frustrum[3].z = tmp.elements[3][2] + tmp.elements[1][2]; frustrum[3].w = tmp.elements[3][3] + tmp.elements[1][3]; frustrum[4].x = tmp.elements[2][0]; frustrum[4].y = tmp.elements[2][1]; frustrum[4].z = tmp.elements[2][2]; frustrum[4].w = tmp.elements[2][3]; frustrum[5].x = tmp.elements[3][0] - tmp.elements[2][0]; frustrum[5].y = tmp.elements[3][1] - tmp.elements[2][1]; frustrum[5].z = tmp.elements[3][2] - tmp.elements[2][2]; frustrum[5].w = tmp.elements[3][3] - tmp.elements[2][3]; for (int i = 0; i < 6; i++) frustrum[i].normalize(); viewAndProj[0] = zKamera->getViewMatrix(); viewAndProj[1] = zKamera->getProjectionMatrix(); kamPos = zKamera->getWorldPosition(); if (vertexShader) vertexShader->füllConstBuffer( (char*)viewAndProj, 0, sizeof(Mat4) * 2); if (pixelShader) pixelShader->füllConstBuffer((char*)&kamPos, 2, sizeof(float) * 3); Welt3D* w = zKamera->zWelt(); w->render([this](Model3D* obj) { if (isInFrustrum(obj->getPos(), obj->getRadius())) renderObject(obj); }); } void DirectX12::presentFrame() { directCommandQueue->getCommandList()->RSSetViewports(1, viewPort); viewAndProj[0] = Mat4::identity(); viewAndProj[1] = Mat4::identity(); if (vertexShader) vertexShader->füllConstBuffer( (char*)viewAndProj, 0, sizeof(Mat4) * 2); uiTextur->updateTextur(); if (fenster && !IsIconic(fenster->getFensterHandle())) renderObject(texturModel); D3D12_RESOURCE_BARRIER barrier; ZeroMemory(&barrier, sizeof(barrier)); barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; barrier.Transition.pResource = this->backBuffer[backBufferIndex]; barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET; barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT; barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; directCommandQueue->getCommandList()->ResourceBarrier(1, &barrier); copyCommandQueue->execute(); directCommandQueue->execute(); swapChain->Present(0, 0); backBufferIndex = swapChain->GetCurrentBackBufferIndex(); } Textur* DirectX12::createOrGetTextur(const char* name, Bild* b) { if (!device) { if (b) b->release(); return 0; } if (texturRegister->hatTextur(name)) { Textur* ret = texturRegister->getTextur(name); if (b) ret->setBildZ(b); return ret; } Textur* ret = new DX12Textur(device, copyCommandQueue, directCommandQueue); if (b) ret->setBildZ(b); texturRegister->addTextur(dynamic_cast(ret->getThis()), name); ret->updateTextur(); copyCommandQueue->execute(); directCommandQueue->execute(); return ret; } Bild* DirectX12::zUIRenderBild() const { return uiTextur ? uiTextur->zBild() : 0; } bool DirectX12::isAvailable() { HINSTANCE dxgiDLL = getDLLRegister()->ladeDLL("dxgi.dll", "dxgi.dll"); if (!dxgiDLL) return 0; HINSTANCE d3d12DLL = getDLLRegister()->ladeDLL("d3d12.dll", "d3d12.dll"); if (!d3d12DLL) { getDLLRegister()->releaseDLL("dxgi.dll"); return 0; } CreateDXGIFactory2Function createFactory = (CreateDXGIFactory2Function)GetProcAddress( dxgiDLL, "CreateDXGIFactory2"); if (!createFactory) { getDLLRegister()->releaseDLL("dxgi.dll"); getDLLRegister()->releaseDLL("d3d12.dll"); return 0; } D3D12CreateDeviceFunction createDevice = (D3D12CreateDeviceFunction)GetProcAddress( d3d12DLL, "D3D12CreateDevice"); if (!createDevice) { getDLLRegister()->releaseDLL("dxgi.dll"); getDLLRegister()->releaseDLL("d3d12.dll"); return 0; } #ifdef _DEBUG D3D12GetDebugInterfaceFunction getDebugInterface = (D3D12GetDebugInterfaceFunction)GetProcAddress( d3d12DLL, "D3D12GetDebugInterface"); ID3D12Debug* debug = 0; getDebugInterface(__uuidof(ID3D12Debug), (void**)&debug); debug->EnableDebugLayer(); #endif IDXGIFactory4* factory; UINT createFactoryFlags = 0; #ifdef _DEBUG createFactoryFlags = DXGI_CREATE_FACTORY_DEBUG; #endif HRESULT res = createFactory( createFactoryFlags, __uuidof(IDXGIFactory4), (void**)&factory); if (FAILED(res)) { getDLLRegister()->releaseDLL("dxgi.dll"); getDLLRegister()->releaseDLL("d3d12.dll"); return 0; } int index = 0; do { IDXGIAdapter1* current; res = factory->EnumAdapters1(index++, ¤t); if (res == S_OK) { DXGI_ADAPTER_DESC1 dxgiAdapterDesc1; current->GetDesc1(&dxgiAdapterDesc1); ID3D12Device5* device = 0; if ((dxgiAdapterDesc1.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) == 0 && SUCCEEDED(createDevice(current, D3D_FEATURE_LEVEL_12_1, __uuidof(ID3D12Device5), (void**)&device))) { device->Release(); current->Release(); factory->Release(); #ifdef _DEBUG debug->Release(); #endif getDLLRegister()->releaseDLL("dxgi.dll"); getDLLRegister()->releaseDLL("d3d12.dll"); return 1; } current->Release(); } } while (res != DXGI_ERROR_NOT_FOUND); factory->Release(); getDLLRegister()->releaseDLL("dxgi.dll"); getDLLRegister()->releaseDLL("d3d12.dll"); return 0; } DXBuffer* DirectX12::createIndexBuffer() { return new DX12IndexBuffer( sizeof(int), device, copyCommandQueue, directCommandQueue); } DXBuffer* DirectX12::createVertexBuffer() { return new DX12VertexBuffer( sizeof(Vertex3D), device, copyCommandQueue, directCommandQueue); } DXBuffer* DirectX12::createStructuredBuffer(int eSize) { throw "Sorry, support for structured buffers will come eventualy"; // TODO: support structured buffers }