DXTexture::DXTexture(const TextureConfig& tex_config) : AbstractTexture(tex_config) { DXGI_FORMAT dxgi_format = GetDXGIFormatForHostFormat(m_config.format); if (m_config.rendertarget) { m_texture = D3DTexture2D::Create( m_config.width, m_config.height, (D3D11_BIND_FLAG)((int)D3D11_BIND_RENDER_TARGET | (int)D3D11_BIND_SHADER_RESOURCE), D3D11_USAGE_DEFAULT, dxgi_format, 1, m_config.layers); } else { const D3D11_TEXTURE2D_DESC texdesc = CD3D11_TEXTURE2D_DESC(dxgi_format, m_config.width, m_config.height, 1, m_config.levels, D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_DEFAULT, 0); ID3D11Texture2D* pTexture; const HRESULT hr = D3D::device->CreateTexture2D(&texdesc, nullptr, &pTexture); CHECK(SUCCEEDED(hr), "Create texture of the TextureCache"); m_texture = new D3DTexture2D(pTexture, D3D11_BIND_SHADER_RESOURCE); // TODO: better debug names D3D::SetDebugObjectName(m_texture->GetTex(), "a texture of the TextureCache"); D3D::SetDebugObjectName(m_texture->GetSRV(), "shader resource view of a texture of the TextureCache"); SAFE_RELEASE(pTexture); } }
std::unique_ptr<DXStagingTexture> DXStagingTexture::Create(StagingTextureType type, const TextureConfig& config) { D3D11_USAGE usage; UINT cpu_flags; if (type == StagingTextureType::Readback) { usage = D3D11_USAGE_STAGING; cpu_flags = D3D11_CPU_ACCESS_READ; } else if (type == StagingTextureType::Upload) { usage = D3D11_USAGE_DYNAMIC; cpu_flags = D3D11_CPU_ACCESS_WRITE; } else { usage = D3D11_USAGE_STAGING; cpu_flags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; } CD3D11_TEXTURE2D_DESC desc(GetDXGIFormatForHostFormat(config.format), config.width, config.height, 1, 1, 0, usage, cpu_flags); ID3D11Texture2D* texture; HRESULT hr = D3D::device->CreateTexture2D(&desc, nullptr, &texture); CHECK(SUCCEEDED(hr), "Create staging texture"); if (FAILED(hr)) return nullptr; return std::unique_ptr<DXStagingTexture>(new DXStagingTexture(type, config, texture)); }
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); }
void DXTexture::ResolveFromTexture(const AbstractTexture* src, const MathUtil::Rectangle<int>& rect, u32 layer, u32 level) { const DXTexture* srcentry = static_cast<const DXTexture*>(src); DEBUG_ASSERT(m_config.samples > 1 && m_config.width == srcentry->m_config.width && m_config.height == srcentry->m_config.height && m_config.samples == 1); DEBUG_ASSERT(rect.left + rect.GetWidth() <= static_cast<int>(srcentry->m_config.width) && rect.top + rect.GetHeight() <= static_cast<int>(srcentry->m_config.height)); D3D::context->ResolveSubresource( m_d3d_texture, D3D11CalcSubresource(level, layer, m_config.levels), srcentry->m_d3d_texture, D3D11CalcSubresource(level, layer, srcentry->m_config.levels), GetDXGIFormatForHostFormat(m_config.format, false)); }