IUnknown* DX11Engine::createTexture2D_SRV(IUnknown* pDeviceIn, const Texture& info, const char* buffer, size_t size, const char* name) const { auto pDevice = reinterpret_cast<ID3D11Device*>(pDeviceIn); HRESULT hr; D3D11_TEXTURE2D_DESC tex = { uint32_t(info.mWidth), uint32_t(info.mHeight), uint32_t(info.mMipCount), uint32_t(info.mArraySize), info.mFormat, { 1, 0 }, D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0 }; if(info.eMiscGenerateMipMaps) { tex.MipLevels = 0; tex.MiscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS; tex.BindFlags |= D3D11_BIND_RENDER_TARGET; } uint32_t bpp = getBitsPerPixel(info.mFormat); int level = 1; if (info.eMiscGenerateMipMaps) level = log2i(std::max(info.mWidth, info.mHeight)) + 1; boost::container::small_vector<D3D11_SUBRESOURCE_DATA, 12> subres(level); int w = info.mWidth; int h = info.mHeight; for (int i = 0; i != level; ++i) { subres[i] = D3D11_SUBRESOURCE_DATA{ buffer, w * bpp / 8, 0 }; buffer += mipmap_size<1>(w, h, bpp); w = next_mip_size(w); h = next_mip_size(h); } std::unique_ptr<ID3D11Texture2D, COMDeleter> pTex; std::unique_ptr<ID3D11ShaderResourceView, COMDeleter> pSRV; CD3D11_SHADER_RESOURCE_VIEW_DESC srvDesc(D3D11_SRV_DIMENSION_TEXTURE2D); V(pDevice->CreateTexture2D(&tex, subres.data(), ref(pTex))); V(pDevice->CreateShaderResourceView(pTex.get(), &srvDesc, ref(pSRV))); STAR_SET_DEBUG_NAME(pSRV, size, name); return pSRV.release(); }
bool DirectX11Texture2DHelper::InternalConstruct(ID3D11Device* d3dDevice, int width, int height, DXGI_FORMAT format, UINT bindFlags, int mipLevels, int arraySize, int sampleCount, int sampleQuality, D3D11_RTV_DIMENSION rtvDimension, D3D11_UAV_DIMENSION uavDimension, D3D11_SRV_DIMENSION srvDimension) { CD3D11_TEXTURE2D_DESC textureDesc(format, width, height, arraySize, mipLevels, bindFlags, D3D11_USAGE_DEFAULT, 0, sampleCount, sampleQuality, mipLevels != 1 ? D3D11_RESOURCE_MISC_GENERATE_MIPS : 0); if(FAILED(d3dDevice->CreateTexture2D(&textureDesc, 0, mTexture.getModifiablePointer()))) return true; mTexture->GetDesc(&textureDesc); if(bindFlags & D3D11_BIND_RENDER_TARGET) { mRenderTargetElements.resize(arraySize); for(int i = 0; i < arraySize; ++i) { CD3D11_RENDER_TARGET_VIEW_DESC textureRTVDesc(rtvDimension, format, 0, i, 1); if(FAILED(d3dDevice->CreateRenderTargetView(mTexture, &textureRTVDesc, mRenderTargetElements[i].getModifiablePointer()))) return true; } } if(bindFlags & D3D11_BIND_UNORDERED_ACCESS) { mUnorderedAccessElements.resize(arraySize); for(int i = 0; i < arraySize; ++i) { CD3D11_UNORDERED_ACCESS_VIEW_DESC textureUAVDesc(uavDimension, format, 0, i, 1); if(FAILED(d3dDevice->CreateUnorderedAccessView(mTexture, &textureUAVDesc, mUnorderedAccessElements[i].getModifiablePointer()))) return true; } } if(bindFlags & D3D11_BIND_SHADER_RESOURCE) { CD3D11_SHADER_RESOURCE_VIEW_DESC srvDesc(srvDimension, format, 0, textureDesc.MipLevels, 0, textureDesc.ArraySize); d3dDevice->CreateShaderResourceView(mTexture, &srvDesc, mShaderResource.getModifiablePointer()); mShaderResourceElements.resize(arraySize); for(int i = 0; i < arraySize; ++i) { CD3D11_SHADER_RESOURCE_VIEW_DESC srvElementDesc(srvDimension, format, 0, 1, i, 1); if(FAILED(d3dDevice->CreateShaderResourceView(mTexture, &srvElementDesc, mShaderResourceElements[i].getModifiablePointer()))) return true; } } return false; }
void Texture2D::InternalConstruct(ID3D11Device* d3dDevice, int width, int height, DXGI_FORMAT format, UINT bindFlags, int mipLevels, int arraySize, int sampleCount, int sampleQuality, D3D11_RTV_DIMENSION rtvDimension, D3D11_UAV_DIMENSION uavDimension, D3D11_SRV_DIMENSION srvDimension) { // Initalize mShaderResource = 0; CD3D11_TEXTURE2D_DESC desc( format, width, height, arraySize, mipLevels, bindFlags, D3D11_USAGE_DEFAULT, 0, sampleCount, sampleQuality, // If they request mipmap levels, it's nice to be able to autogenerate them. (mipLevels != 1 ? D3D11_RESOURCE_MISC_GENERATE_MIPS : 0)); d3dDevice->CreateTexture2D(&desc, 0, &mTexture); // Update with actual mip levels, etc. mTexture->GetDesc(&desc); if (bindFlags & D3D11_BIND_RENDER_TARGET) { for (int i = 0; i < arraySize; ++i) { CD3D11_RENDER_TARGET_VIEW_DESC rtvDesc( rtvDimension, format, 0, // Mips i, 1 // Array ); ID3D11RenderTargetView* renderTargetView; d3dDevice->CreateRenderTargetView(mTexture, &rtvDesc, &renderTargetView); mRenderTargetElements.push_back(renderTargetView); } } if (bindFlags & D3D11_BIND_UNORDERED_ACCESS) { // UAV's can't point to multisampled resources! assert(uavDimension != D3D11_UAV_DIMENSION_UNKNOWN); for (int i = 0; i < arraySize; ++i) { CD3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc( uavDimension, format, 0, // Mips i, 1 // Array ); ID3D11UnorderedAccessView* unorderedAccessView; d3dDevice->CreateUnorderedAccessView(mTexture, &uavDesc, &unorderedAccessView); mUnorderedAccessElements.push_back(unorderedAccessView); } } if (bindFlags & D3D11_BIND_SHADER_RESOURCE) { // Whole resource CD3D11_SHADER_RESOURCE_VIEW_DESC srvDesc( srvDimension, format, 0, desc.MipLevels, // Mips 0, desc.ArraySize // Array ); d3dDevice->CreateShaderResourceView(mTexture, &srvDesc, &mShaderResource); // Single elements for (int i = 0; i < arraySize; ++i) { CD3D11_SHADER_RESOURCE_VIEW_DESC srvElementDesc( srvDimension, format, 0, 1, // Mips i, 1 // Array ); ID3D11ShaderResourceView* shaderResourceView; d3dDevice->CreateShaderResourceView(mTexture, &srvElementDesc, &shaderResourceView); mShaderResourceElements.push_back(shaderResourceView); } } }