IDXGISwapChain3Ptr createDxgiSwapChain(IDXGIFactory4* pFactory, const Window* pWindow, ID3D12CommandQueue* pCommandQueue, ResourceFormat colorFormat) { DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {}; swapChainDesc.BufferCount = kSwapChainBuffers; swapChainDesc.Width = pWindow->getClientAreaWidth(); swapChainDesc.Height = pWindow->getClientAreaHeight(); // Flip mode doesn't support SRGB formats, so we strip them down when creating the resource. We will create the RTV as SRGB instead. // More details at the end of https://msdn.microsoft.com/en-us/library/windows/desktop/bb173064.aspx swapChainDesc.Format = getDxgiFormat(srgbToLinearFormat(colorFormat)); swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; swapChainDesc.SampleDesc.Count = 1; // CreateSwapChainForHwnd() doesn't accept IDXGISwapChain3 (Why MS? Why?) MAKE_SMART_COM_PTR(IDXGISwapChain1); IDXGISwapChain1Ptr pSwapChain; HRESULT hr = pFactory->CreateSwapChainForHwnd(pCommandQueue, pWindow->getApiHandle(), &swapChainDesc, nullptr, nullptr, &pSwapChain); if (FAILED(hr)) { d3dTraceHR("Failed to create the swap-chain", hr); return false; } IDXGISwapChain3Ptr pSwapChain3; d3d_call(pSwapChain->QueryInterface(IID_PPV_ARGS(&pSwapChain3))); return pSwapChain3; }
DXGI_FORMAT getDxgiDSVFormat(E_GI_FORMAT format) { if (format == EGF_D16) return DXGI_FORMAT_D16_UNORM; if (format == EGF_D24S8) return DXGI_FORMAT_D24_UNORM_S8_UINT; if (format == EGF_D32) return DXGI_FORMAT_D32_FLOAT; return getDxgiFormat(format); }
DXGI_FORMAT getDxgiSRVFormat(E_GI_FORMAT format) { if (format == EGF_D16) return DXGI_FORMAT_R16_FLOAT; if (format == EGF_D24S8) return DXGI_FORMAT_R24_UNORM_X8_TYPELESS; if (format == EGF_D32) return DXGI_FORMAT_R32_FLOAT; return getDxgiFormat(format); }
CD3D11InputLayout::CD3D11InputLayout(u32 sortCode, ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dDeviceContext, ID3D10Blob* vertexShaderBuffer, const std::vector<SInputLayoutElement>& elements, u32 hashcode) :IInputLayout(sortCode, elements, hashcode) , md3dDeviceContext(pd3dDeviceContext) , m_pd3dInputLayout(nullptr) { HRESULT hr; u32 elementCount = elements.size(); std::vector<D3D11_INPUT_ELEMENT_DESC> elementsDescs(elementCount); elementsDescs.resize(elementCount); for (u32 i = 0; i < elementCount; i++) { const SInputLayoutElement& element = elements[i]; elementsDescs[i].SemanticName = element.SemanticName.c_str(); elementsDescs[i].SemanticIndex = element.SemanticIndex; elementsDescs[i].Format = getDxgiFormat(element.Format); elementsDescs[i].InputSlot = element.Slot; elementsDescs[i].AlignedByteOffset = element.Offset; if (element.InstanceData) { elementsDescs[i].InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA; elementsDescs[i].InstanceDataStepRate = element.InstanceDataStepRate; } else { elementsDescs[i].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; elementsDescs[i].InstanceDataStepRate = 0; } } hr = pd3dDevice->CreateInputLayout(&elementsDescs[0], elementCount, vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(), &m_pd3dInputLayout); if (FAILED(hr)) { throw std::runtime_error("Create InputLayout Failed!"); } }
bool CD3D11Texture2D::create(u32 width, u32 height, u32 bindFlags, void* rawData, u32 miplevel, E_GI_FORMAT format, u32 pitch, E_MEMORY_USAGE memoryUsage) { HRESULT hr; ID3D11Texture2D* pd3dTexture = NULL; ID3D11ShaderResourceView* pd3dSRV = NULL; ID3D11UnorderedAccessView* pd3dUAV = NULL; CD3D11RenderTarget* pRenderTarget = nullptr; D3D11_TEXTURE2D_DESC texDesc; texDesc.Width = width; texDesc.Height = height; texDesc.MipLevels = miplevel; texDesc.ArraySize = 1; texDesc.Format = getDxgiFormat(format); texDesc.SampleDesc.Count = 1; texDesc.SampleDesc.Quality = 0; texDesc.BindFlags = getD3dx11BindFlags(bindFlags); texDesc.CPUAccessFlags = getD3dx11CpuAccessFlag(bindFlags); texDesc.MiscFlags = 0; texDesc.Usage = getD3d11Usage(memoryUsage); if (memoryUsage == EMU_UNKNOWN) { if ((bindFlags & ETBT_CPU_ACCESS_READ)) { texDesc.Usage = D3D11_USAGE_STAGING; memoryUsage = EMU_STAGING; } else if (bindFlags & ETBT_CPU_ACCESS_WRITE) { texDesc.Usage = D3D11_USAGE_DYNAMIC; memoryUsage = EMU_DEFAULT; } else if (rawData) { texDesc.Usage = D3D11_USAGE_IMMUTABLE; memoryUsage = EMU_STATIC; } else if (!rawData) { texDesc.Usage = D3D11_USAGE_DEFAULT; memoryUsage = EMU_DEFAULT; } } else { if (memoryUsage == EMU_DEFAULT || memoryUsage == EMU_STATIC) { if ((bindFlags & ETBT_CPU_ACCESS_READ) || (bindFlags & ETBT_CPU_ACCESS_WRITE)) { GF_PRINT_CONSOLE_INFO("Static or Default Buffer cannot be accessed by CPU.\n"); return false; } } else if (memoryUsage == EMU_DYNAMIC) { if (bindFlags & ETBT_CPU_ACCESS_READ) { GF_PRINT_CONSOLE_INFO("Dynamic Buffer cannot be read by CPU.\n"); return false; } } } if (memoryUsage == D3D11_USAGE_STAGING) { if ((bindFlags & ETBT_SHADER_RESOURCE) || (bindFlags & ETBT_UNORDERED_ACCESS)){ GF_PRINT_CONSOLE_INFO("Buffer with the memory usage 'STARING' cannot have SHADER_RESOURCE or UNORDERED_ACCESS."); return false; } } if (rawData) { D3D11_SUBRESOURCE_DATA texData; texData.pSysMem = rawData; if (pitch == 0) pitch = getFormatOffset(format) * width; texData.SysMemPitch = pitch; texData.SysMemSlicePitch = 0; hr = md3dDevice->CreateTexture2D(&texDesc, &texData, &pd3dTexture); } else { hr = md3dDevice->CreateTexture2D(&texDesc, NULL, &pd3dTexture); } if (FAILED(hr)) { return false; } if (bindFlags & ETBT_SHADER_RESOURCE) { D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; srvDesc.Format = texDesc.Format; srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; srvDesc.Texture2D.MostDetailedMip = 0; srvDesc.Texture2D.MipLevels = -1; hr = md3dDevice->CreateShaderResourceView(pd3dTexture, &srvDesc, &pd3dSRV); if (FAILED(hr)) { ReleaseCOM(pd3dTexture); return false; } } if (bindFlags & ETBT_UNORDERED_ACCESS) { D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc; uavDesc.Format = texDesc.Format; uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D; uavDesc.Texture2D.MipSlice = 0; hr = md3dDevice->CreateUnorderedAccessView(pd3dTexture, &uavDesc, &pd3dUAV); if (FAILED(hr)) { ReleaseCOM(pd3dTexture); return false; } } if (bindFlags & ETBT_RENDER_TARGET) { pRenderTarget = new CD3D11RenderTarget(md3dDevice, md3dDeviceContext); if (!pRenderTarget->create(this, pd3dTexture, pd3dSRV, width, height, format)) { ReleaseReferenceCounted(pRenderTarget); ReleaseCOM(pd3dSRV); ReleaseCOM(pd3dTexture); return false; } } ReleaseReferenceCounted(mRenderTarget); ReleaseReferenceCounted(mDepthStencilSurface); ReleaseCOM(md3dSRV); ReleaseCOM(md3dUAV); ReleaseCOM(md3dTexture); md3dTexture = pd3dTexture; md3dSRV = pd3dSRV; md3dUAV = pd3dUAV; mRenderTarget = pRenderTarget; mTextureWidth = width; mTextureHeight = height; mFormat = format; return true; }
bool CD3D11Texture3D::create(u32 width, u32 height, u32 depth, u32 bindFlags, void* rawData, u32 miplevel, E_GI_FORMAT format, u32 pitch /*= 0*/, u32 slicePitch /*= 0*/, E_MEMORY_USAGE memoryUsage) { HRESULT hr; ID3D11Texture3D* pd3dTexture3D = NULL; ID3D11ShaderResourceView* pd3dSRV = NULL; ID3D11UnorderedAccessView* pd3dUAV = NULL; D3D11_TEXTURE3D_DESC texDesc; texDesc.Width = width; texDesc.Height = height; texDesc.Depth = depth; texDesc.MipLevels = miplevel; texDesc.Format = getDxgiFormat(format); texDesc.Usage = D3D11_USAGE_IMMUTABLE; texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; texDesc.CPUAccessFlags = 0; texDesc.MiscFlags = 0; texDesc.Usage = getD3d11Usage(memoryUsage); if (pitch == 0) pitch = getFormatOffset(format) * width; if (slicePitch == 0) slicePitch = getFormatOffset(format) * width * height; if (rawData) { if (memoryUsage == EMU_UNKNOWN) texDesc.Usage = D3D11_USAGE_IMMUTABLE; D3D11_SUBRESOURCE_DATA texData; texData.pSysMem = rawData; texData.SysMemPitch = pitch; texData.SysMemSlicePitch = slicePitch; hr = md3dDevice->CreateTexture3D(&texDesc, &texData, &pd3dTexture3D); } else { if (memoryUsage == EMU_UNKNOWN) texDesc.Usage = D3D11_USAGE_DEFAULT; md3dDevice->CreateTexture3D(&texDesc, NULL, &pd3dTexture3D); } if (FAILED(hr)) { return false; } if (bindFlags & ETBT_SHADER_RESOURCE) { D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; srvDesc.Format = texDesc.Format; srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; srvDesc.Texture3D.MostDetailedMip = 0; srvDesc.Texture3D.MipLevels = texDesc.MipLevels; hr = md3dDevice->CreateShaderResourceView(pd3dTexture3D, &srvDesc, &pd3dSRV); if (FAILED(hr)) { ReleaseCOM(pd3dTexture3D); return false; } } if (bindFlags & ETBT_UNORDERED_ACCESS) { D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc; uavDesc.Format = texDesc.Format; uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE3D; uavDesc.Texture3D.MipSlice = 0; uavDesc.Texture3D.FirstWSlice = 0; uavDesc.Texture3D.WSize = texDesc.Depth; hr = md3dDevice->CreateUnorderedAccessView(pd3dTexture3D, &uavDesc, &pd3dUAV); if (FAILED(hr)) { ReleaseCOM(pd3dTexture3D); return false; } } ReleaseCOM(md3dShaderResourceView); ReleaseCOM(md3dUAV); ReleaseCOM(md3dTexture); md3dTexture = pd3dTexture3D; md3dShaderResourceView = pd3dSRV; md3dUAV = pd3dUAV; mTextureWidth = width; mTextureHeight = height; mTextureDepth = depth; mFormat = format; return true; }
bool CD3D11Texture2DArray::create(u32 width, u32 height, u32 arraySize, u32 bindFlags, void* rawData, u32 miplevel, E_GI_FORMAT format, u32 pitch /*= 0*/, E_MEMORY_USAGE memoryUsage) { HRESULT hr; ID3D11Texture2D* pd3dTexture = NULL; ID3D11ShaderResourceView* pd3dSRV = NULL; ID3D11UnorderedAccessView* pd3dUAV = NULL; CD3D11RenderTarget* pRenderTarget = nullptr; std::vector<CD3D11RenderTarget*> renderTargets; std::vector<CD3D11DepthStencilSurface*> depthStencilSurfaces; D3D11_TEXTURE2D_DESC texDesc; texDesc.Width = width; texDesc.Height = height; texDesc.MipLevels = miplevel; texDesc.ArraySize = arraySize; texDesc.Format = getDxgiFormat(format); texDesc.SampleDesc.Count = 1; texDesc.SampleDesc.Quality = 0; texDesc.BindFlags = getD3dx11BindFlags(bindFlags); texDesc.CPUAccessFlags = 0; texDesc.MiscFlags = 0; texDesc.Usage = getD3d11Usage(memoryUsage); if (rawData) { if (memoryUsage == EMU_UNKNOWN) texDesc.Usage = D3D11_USAGE_IMMUTABLE; D3D11_SUBRESOURCE_DATA texData; texData.pSysMem = rawData; if (pitch == 0) pitch = getFormatOffset(format) * width; texData.SysMemPitch = pitch; texData.SysMemSlicePitch = 0; hr = md3dDevice->CreateTexture2D(&texDesc, &texData, &pd3dTexture); } else { if (memoryUsage == EMU_UNKNOWN) texDesc.Usage = D3D11_USAGE_DEFAULT; hr = md3dDevice->CreateTexture2D(&texDesc, NULL, &pd3dTexture); } if (FAILED(hr)) return false; if (bindFlags & ETBT_SHADER_RESOURCE) { D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; srvDesc.Format = getDxgiSRVFormat(format); srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; srvDesc.Texture2DArray.MostDetailedMip = 0; srvDesc.Texture2DArray.MipLevels = miplevel; srvDesc.Texture2DArray.FirstArraySlice = 0; srvDesc.Texture2DArray.ArraySize = arraySize; hr = md3dDevice->CreateShaderResourceView(pd3dTexture, &srvDesc, &pd3dSRV); if (FAILED(hr)) { ReleaseCOM(pd3dTexture); return false; } } if (bindFlags & ETBT_UNORDERED_ACCESS) { D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc; uavDesc.Format = texDesc.Format; uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY; uavDesc.Texture2DArray.MipSlice = 0; uavDesc.Texture2DArray.ArraySize = arraySize; uavDesc.Texture2DArray.FirstArraySlice = 0; hr = md3dDevice->CreateUnorderedAccessView(pd3dTexture, &uavDesc, &pd3dUAV); if (FAILED(hr)) { ReleaseCOM(pd3dTexture); return false; } } if (bindFlags & ETBT_RENDER_TARGET) { for (u32 i = 0; i < arraySize; i++) { CD3D11RenderTarget* pRenderTarget = new CD3D11RenderTarget(md3dDevice, md3dDeviceContext); renderTargets.push_back(pRenderTarget); if (!pRenderTarget->createOneInArray(this, pd3dTexture, pd3dSRV, i, width, height, format)) { clearRenderTargets(renderTargets); ReleaseCOM(pd3dSRV); ReleaseCOM(pd3dTexture); return false; } } } if (bindFlags & ETBT_DEPTH_STENCIL) { for (u32 i = 0; i < arraySize; i++) { CD3D11DepthStencilSurface* pDS = new CD3D11DepthStencilSurface(md3dDevice, md3dDeviceContext); depthStencilSurfaces.push_back(pDS); if (!pDS->createOneInArray(this, pd3dTexture, pd3dSRV, i, width, height, format)) { clearDepthStencilSurfaces(depthStencilSurfaces); clearRenderTargets(renderTargets); ReleaseCOM(pd3dSRV); ReleaseCOM(pd3dTexture); return false; } } } clearRenderTargets(mRenderTargets); clearDepthStencilSurfaces(mDepthStencilSurfaces); ReleaseCOM(md3dSRV); ReleaseCOM(md3dUAV); ReleaseCOM(md3dTexture); md3dTexture = pd3dTexture; md3dSRV = pd3dSRV; md3dUAV = pd3dUAV; mRenderTargets = renderTargets; mDepthStencilSurfaces = depthStencilSurfaces; mTextureWidth = width; mTextureHeight = height; mFormat = format; return true; }