uint32_t DirectXInputLayoutRegistry::create(const Vertices& vertices) { TB::runtimeCheck(vertices.size() > 0); const char* semantics[] = { "POSITION", "NORMAL", "TEXCOORD", "COLOR" }; const DXGI_FORMAT formats[] = { DXGI_FORMAT(0), DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R32G32B32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT }; // Input layout elements std::vector<D3D11_INPUT_ELEMENT_DESC> elements; for (size_t i = 0; i < vertices.size(); i++) { const auto& stream = vertices[i]; elements.push_back({ semantics[(int)stream.semantic], (UINT)stream.usageIndex, formats[stream.elements], (UINT)i, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }); } // Hash the memory bytes of the element uint32_t id = hash(reinterpret_cast<uint8_t*>(&elements[0]), elements.size() * sizeof(D3D11_INPUT_ELEMENT_DESC)); auto item = mRegistry.find(id); if (item == mRegistry.end()) { std::stringstream fakeVSCode; const char* memberTypes[] = { nullptr, "float", "float2", "float3", "float4" }; // Create a fake vertex shader for the input layout fakeVSCode << "struct VSInput"; fakeVSCode << "{"; for (size_t i = 0; i < vertices.size(); i++) { const auto& stream = vertices[i]; fakeVSCode << memberTypes[stream.elements] << " _" << i << " : " << semantics[(int)stream.semantic] << stream.usageIndex << ";"; } fakeVSCode << "};"; fakeVSCode << "float4 MainVS(VSInput input) : SV_POSITION { return float4(0, 0, 0, 1); }"; DirectXShader fakeVS(mRenderer, DataChunk(fakeVSCode.str()), "MainVS", ShaderType::Vertex); ComPtr<ID3D11InputLayout> inputLayout; HRESULT hr = mRenderer->getDevice()->CreateInputLayout(&elements[0], (UINT)elements.size(), fakeVS.getBlob()->GetBufferPointer(), fakeVS.getBlob()->GetBufferSize(), inputLayout.getInitRef()); TB::runtimeCheck(hr == S_OK); mRegistry.emplace(id, inputLayout); } return id; }
//----------------------------------------------- HRESULT CPUTRenderTargetDepth::CreateRenderTarget( std::string textureName, UINT width, UINT height, DXGI_FORMAT depthFormat, UINT multiSampleCount, bool recreate ) { HRESULT result; mName = textureName; mWidth = width; mHeight = height; mDepthFormat = depthFormat; mMultiSampleCount = multiSampleCount; // NOTE: The following doesn't work for DX10.0 devices. // They don't support binding an MSAA depth texture as // If we have a DX 10.1 or no MSAA, then create a shader resource view, and add a CPUTTexture to the AssetLibrary D3D_FEATURE_LEVEL featureLevel = gpSample->GetFeatureLevel(); bool supportsResourceView = ( featureLevel >= D3D_FEATURE_LEVEL_10_1) || (mMultiSampleCount==1); D3D11_TEXTURE2D_DESC depthDesc = { width, height, 1, // MIP Levels 1, // Array Size DXGI_FORMAT(depthFormat - 1), // DXGI_FORMAT_R32_TYPELESS mMultiSampleCount, 0, D3D11_USAGE_DEFAULT, D3D11_BIND_DEPTH_STENCIL | (supportsResourceView ? D3D11_BIND_SHADER_RESOURCE : 0), 0, // CPU Access flags 0 // Misc flags }; // Create either a Texture2D, or Texture2DMS, depending on multisample count. D3D11_DSV_DIMENSION dsvDimension = (mMultiSampleCount>1) ? D3D11_DSV_DIMENSION_TEXTURE2DMS : D3D11_DSV_DIMENSION_TEXTURE2D; ID3D11Device *pD3dDevice = CPUT_DX11::GetDevice(); result = pD3dDevice->CreateTexture2D( &depthDesc, NULL, &mpDepthTextureDX ); ASSERT( SUCCEEDED(result), "Failed creating depth texture.\nAre you using MSAA with a DX10.0 GPU?\nOnly DX10.1 and above can create a shader resource view for an MSAA depth texture." ); D3D11_DEPTH_STENCIL_VIEW_DESC dsvd = { depthFormat, dsvDimension, 0 }; result = pD3dDevice->CreateDepthStencilView( mpDepthTextureDX, &dsvd, &mpDepthStencilView ); ASSERT( SUCCEEDED(result), "Failed creating depth stencil view" ); CPUTSetDebugName( mpDepthStencilView, mName ); if( supportsResourceView ) { D3D11_SRV_DIMENSION srvDimension = (mMultiSampleCount>1) ? D3D11_SRV_DIMENSION_TEXTURE2DMS : D3D11_SRV_DIMENSION_TEXTURE2D; // Create the shader-resource view D3D11_SHADER_RESOURCE_VIEW_DESC depthRsDesc = { DXGI_FORMAT(depthFormat + 1), srvDimension, 0 }; // TODO: Support optionally creating MIP chain. Then, support MIP generation (e.g., GenerateMIPS()). depthRsDesc.Texture2D.MipLevels = 1; result = pD3dDevice->CreateShaderResourceView( mpDepthTextureDX, &depthRsDesc, &mpDepthResourceView ); ASSERT( SUCCEEDED(result), "Failed creating render target shader resource view" ); CPUTSetDebugName( mpDepthResourceView, textureName + " Depth" ); if( !recreate ) { CPUTAssetLibrary *pAssetLibrary = CPUTAssetLibrary::GetAssetLibrary(); mpDepthTexture = CPUTTextureDX11::Create(mName); pAssetLibrary->AddTexture( mName, "", "", mpDepthTexture ); } ((CPUTTextureDX11*)mpDepthTexture)->SetTextureAndShaderResourceView(mpDepthTextureDX, mpDepthResourceView); } return S_OK; }