std::unique_ptr<DXTexture> DXTexture::Create(const TextureConfig& config) { // Use typeless to create the texture when it's a render target, so we can alias it with an // integer format (for EFB). const DXGI_FORMAT tex_format = D3DCommon::GetDXGIFormatForAbstractFormat(config.format, config.IsRenderTarget()); UINT bindflags = D3D11_BIND_SHADER_RESOURCE; if (config.IsRenderTarget()) bindflags |= IsDepthFormat(config.format) ? D3D11_BIND_DEPTH_STENCIL : D3D11_BIND_RENDER_TARGET; if (config.IsComputeImage()) bindflags |= D3D11_BIND_UNORDERED_ACCESS; CD3D11_TEXTURE2D_DESC desc(tex_format, config.width, config.height, config.layers, config.levels, bindflags, D3D11_USAGE_DEFAULT, 0, config.samples, 0, 0); ComPtr<ID3D11Texture2D> d3d_texture; HRESULT hr = D3D::device->CreateTexture2D(&desc, nullptr, &d3d_texture); if (FAILED(hr)) { PanicAlert("Failed to create %ux%ux%u D3D backing texture", config.width, config.height, config.layers); return nullptr; } std::unique_ptr<DXTexture> tex(new DXTexture(config, d3d_texture.Get())); if (!tex->CreateSRV() || (config.IsComputeImage() && !tex->CreateUAV())) return nullptr; return tex; }
std::unique_ptr<DXTexture> DXTexture::Create(const TextureConfig& config) { // Use typeless to create the texture when it's a render target, so we can alias it with an // integer format (for EFB). const DXGI_FORMAT tex_format = GetDXGIFormatForHostFormat(config.format, config.IsRenderTarget()); const DXGI_FORMAT srv_format = GetSRVFormatForHostFormat(config.format); UINT bindflags = D3D11_BIND_SHADER_RESOURCE; if (config.IsRenderTarget()) bindflags |= IsDepthFormat(config.format) ? D3D11_BIND_DEPTH_STENCIL : D3D11_BIND_RENDER_TARGET; if (config.IsComputeImage()) bindflags |= D3D11_BIND_UNORDERED_ACCESS; CD3D11_TEXTURE2D_DESC desc(tex_format, config.width, config.height, config.layers, config.levels, bindflags, D3D11_USAGE_DEFAULT, 0, config.samples, 0, 0); ID3D11Texture2D* d3d_texture; HRESULT hr = D3D::device->CreateTexture2D(&desc, nullptr, &d3d_texture); if (FAILED(hr)) { PanicAlert("Failed to create %ux%ux%u D3D backing texture", config.width, config.height, config.layers); return nullptr; } ID3D11ShaderResourceView* d3d_srv; const CD3D11_SHADER_RESOURCE_VIEW_DESC srv_desc(d3d_texture, config.IsMultisampled() ? D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY : D3D11_SRV_DIMENSION_TEXTURE2DARRAY, srv_format, 0, config.levels, 0, config.layers); hr = D3D::device->CreateShaderResourceView(d3d_texture, &srv_desc, &d3d_srv); if (FAILED(hr)) { PanicAlert("Failed to create %ux%ux%u D3D SRV", config.width, config.height, config.layers); d3d_texture->Release(); return nullptr; } ID3D11UnorderedAccessView* d3d_uav = nullptr; if (config.IsComputeImage()) { const CD3D11_UNORDERED_ACCESS_VIEW_DESC uav_desc( d3d_texture, D3D11_UAV_DIMENSION_TEXTURE2DARRAY, srv_format, 0, 0, config.layers); hr = D3D::device->CreateUnorderedAccessView(d3d_texture, &uav_desc, &d3d_uav); if (FAILED(hr)) { PanicAlert("Failed to create %ux%ux%u D3D UAV", config.width, config.height, config.layers); d3d_uav->Release(); d3d_texture->Release(); return nullptr; } } return std::make_unique<DXTexture>(config, d3d_texture, d3d_srv, d3d_uav); }