void DX11SpriteBatch::Draw(const POINT& center, float width, float height, XMCOLOR color) { Sprite sprite; sprite.SrcRect = CD3D11_RECT(0, 0, mTexWidth, mTexHeight);; sprite.DestRect = CD3D11_RECT(center.x - (LONG)(0.5*width), center.y - (LONG)(0.5*width), center.x + (LONG)(0.5*width), center.y + (LONG)(0.5*height)); sprite.Color = color; mSpriteList.push_back(sprite); }
void DX11SpriteBatch::Draw(const POINT& position, XMCOLOR color) { Sprite sprite; sprite.SrcRect = CD3D11_RECT(0, 0, mTexWidth, mTexHeight); sprite.DestRect = CD3D11_RECT(position.x, position.y, position.x + mTexWidth, position.y + mTexHeight); sprite.Color = color; mSpriteList.push_back(sprite); }
void DX11SpriteBatch::DrawConsoleCommand(DX11FontSheet& fs, char (&text)[COMMAND_MAX_LENGTH], const POINT& pos) { BeginBatch(fs.GetFontSheetSRV()); int posX = pos.x; int posY = pos.y; XMCOLOR color = 0xffffffff; for(u32 i = 0; i < COMMAND_MAX_LENGTH; ++i) { WCHAR character = text[i]; if(character == ' ') posX += fs.GetSpaceWidth(); else if(character == '\t') posX += (4*fs.GetMaxCharWidth() - posX%(4*fs.GetMaxCharWidth())); else if(character == '\n') { posX = pos.x; posY += fs.GetCharHeight(); } else if(character == nullchar) break; else { if ( character < DX11FontSheet::StartChar || character > DX11FontSheet::EndChar ) character = '?'; const CD3D11_RECT& charRect = fs.GetCharBoundingRect(character); int width = charRect.right - charRect.left; int height = charRect.bottom - charRect.top; Draw(CD3D11_RECT(posX, posY, posX + width, posY + height), charRect, color); // Move to the next character position. posX += width + 1; } } // We Draw the cursor const CD3D11_RECT& charRect = fs.GetCharBoundingRect('_'); int width = charRect.right - charRect.left; int height = charRect.bottom - charRect.top; Draw(CD3D11_RECT(posX, posY, posX + width, posY + height), charRect, color); EndBatch(mContext); }
void DxFont::BuildFontSheetBitmap(Gdiplus::Font & font, Gdiplus::Graphics & charGraphics, Gdiplus::Bitmap & charBitmap, Gdiplus::Graphics & fontSheetGraphics) { WCHAR charString[ 2 ] = { ' ', 0 }; Gdiplus::SolidBrush whiteBrush( Gdiplus::Color( 255, 255, 255, 255 ) ); UINT fontSheetX = 0; UINT fontSheetY = 0; for( UINT i = 0; i < NumChars; ++i ) { charString[ 0 ] = static_cast<WCHAR>(StartChar + i); charGraphics.Clear(Gdiplus::Color(0, 0, 0, 0)); charGraphics.DrawString(charString, 1, &font, Gdiplus::PointF(0.0f, 0.0f), &whiteBrush); int minX = GetCharMinX(charBitmap); int maxX = GetCharMaxX(charBitmap); int charWidth = maxX - minX + 1; if(fontSheetX + charWidth >= TexWidth) { fontSheetX = 0; fontSheetY += static_cast<int>(CharHeight) + 1; } CharRects[i] = CD3D11_RECT(fontSheetX, fontSheetY, fontSheetX + charWidth, fontSheetY + CharHeight); fontSheetGraphics.DrawImage(&charBitmap, fontSheetX, fontSheetY, minX, 0, charWidth, CharHeight, Gdiplus::UnitPixel); fontSheetX += charWidth + 1; } }
void Television::Render() { if (g_ActiveConfig.bUseRealXFB && g_ActiveConfig.bUseXFB) { // Use real XFB mode // TODO: If this is the lower field, render at a vertical offset of 1 // line down. We could even consider implementing a deinterlacing // algorithm. D3D11_RECT sourceRc = CD3D11_RECT(0, 0, int(m_curWidth), int(m_curHeight)); D3D::stateman->SetSampler(0, m_samplerState); D3D::drawShadedTexQuad( m_yuyvTextureSRV, &sourceRc, MAX_XFB_WIDTH, MAX_XFB_HEIGHT, m_pShader, VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout()); } else if (g_ActiveConfig.bUseXFB) { // Use virtual XFB mode // TODO: Eventually, Television should render the Virtual XFB mode // display as well. } }
void TextureCache::TCacheEntry::FromRenderTarget(u8* dst, unsigned int dstFormat, u32 dstStride, PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf, u32 cbufid, const float *colmat) { g_renderer->ResetAPIState(); // stretch picture with increased internal resolution const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)config.width, (float)config.height); D3D::context->RSSetViewports(1, &vp); // set transformation if (nullptr == efbcopycbuf[cbufid].get()) { const D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(28 * sizeof(float), D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DEFAULT); D3D11_SUBRESOURCE_DATA data; data.pSysMem = colmat; HRESULT hr = D3D::device->CreateBuffer(&cbdesc, &data, D3D::ToAddr(efbcopycbuf[cbufid])); CHECK(SUCCEEDED(hr), "Create efb copy constant buffer %d", cbufid); D3D::SetDebugObjectName(efbcopycbuf[cbufid].get(), "a constant buffer used in TextureCache::CopyRenderTargetToTexture"); } D3D::stateman->SetPixelConstants(efbcopycbuf[cbufid].get()); const TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(srcRect); // TODO: try targetSource.asRECT(); const D3D11_RECT sourcerect = CD3D11_RECT(targetSource.left, targetSource.top, targetSource.right, targetSource.bottom); // Use linear filtering if (bScaleByHalf), use point filtering otherwise if (scaleByHalf) D3D::SetLinearCopySampler(); else D3D::SetPointCopySampler(); // if texture is currently in use, it needs to be temporarily unset u32 textureSlotMask = D3D::stateman->UnsetTexture(texture->GetSRV()); D3D::stateman->Apply(); D3D::context->OMSetRenderTargets(1, &texture->GetRTV(), nullptr); // Create texture copy D3D::drawShadedTexQuad( ((srcFormat == PEControl::Z24) ? FramebufferManager::GetEFBDepthTexture() : FramebufferManager::GetEFBColorTexture())->GetSRV(), &sourcerect, Renderer::GetTargetWidth(), Renderer::GetTargetHeight(), (srcFormat == PEControl::Z24) ? PixelShaderCache::GetDepthMatrixProgram(true) : PixelShaderCache::GetColorMatrixProgram(true), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), (g_Config.iStereoMode > 0) ? GeometryShaderCache::GetCopyGeometryShader() : nullptr); D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); g_renderer->RestoreAPIState(); if (g_ActiveConfig.bSkipEFBCopyToRam) { this->Zero(dst); } else { s_encoder->Encode(dst, this, srcFormat, srcRect, isIntensity, scaleByHalf); } }
void DX11SpriteBatch::Draw(const CD3D11_RECT& destinationRect, XMCOLOR color) { Sprite sprite; sprite.SrcRect = CD3D11_RECT(0, 0, mTexWidth, mTexHeight); sprite.DestRect = destinationRect; sprite.Color = color; mSpriteList.push_back(sprite); }
void DX11SpriteBatch::Draw(const POINT& position, const CD3D11_RECT& sourceRect, XMCOLOR color) { int srcWidth = sourceRect.right - sourceRect.left; int srcHeight = sourceRect.bottom - sourceRect.top; Sprite sprite; sprite.SrcRect = sourceRect; sprite.DestRect = CD3D11_RECT(position.x, position.y, position.x + srcWidth, position.y + srcHeight); sprite.Color = color; mSpriteList.push_back(sprite); }
void TextureCache::TCacheEntry::FromRenderTarget(u8* dst, PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect, bool scaleByHalf, unsigned int cbufid, const float *colmat) { g_renderer->ResetAPIState(); // stretch picture with increased internal resolution const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)config.width, (float)config.height); D3D::context->RSSetViewports(1, &vp); // set transformation if (nullptr == efbcopycbuf[cbufid]) { const D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(28 * sizeof(float), D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DEFAULT); D3D11_SUBRESOURCE_DATA data; data.pSysMem = colmat; HRESULT hr = D3D::device->CreateBuffer(&cbdesc, &data, &efbcopycbuf[cbufid]); CHECK(SUCCEEDED(hr), "Create efb copy constant buffer %d", cbufid); D3D::SetDebugObjectName((ID3D11DeviceChild*)efbcopycbuf[cbufid], "a constant buffer used in TextureCache::CopyRenderTargetToTexture"); } D3D::stateman->SetPixelConstants(efbcopycbuf[cbufid]); const TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(srcRect); // TODO: try targetSource.asRECT(); const D3D11_RECT sourcerect = CD3D11_RECT(targetSource.left, targetSource.top, targetSource.right, targetSource.bottom); // Use linear filtering if (bScaleByHalf), use point filtering otherwise if (scaleByHalf) D3D::SetLinearCopySampler(); else D3D::SetPointCopySampler(); // Make sure we don't draw with the texture set as both a source and target. // (This can happen because we don't unbind textures when we free them.) D3D::stateman->UnsetTexture(texture->GetSRV()); D3D::context->OMSetRenderTargets(1, &texture->GetRTV(), nullptr); // Create texture copy D3D::drawShadedTexQuad( (srcFormat == PEControl::Z24 ? FramebufferManager::GetEFBDepthTexture() : FramebufferManager::GetEFBColorTexture())->GetSRV(), &sourcerect, Renderer::GetTargetWidth(), Renderer::GetTargetHeight(), srcFormat == PEControl::Z24 ? PixelShaderCache::GetDepthMatrixProgram(true) : PixelShaderCache::GetColorMatrixProgram(true), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), GeometryShaderCache::GetCopyGeometryShader()); D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); g_renderer->RestoreAPIState(); }
void DxSprite::DrawString(int X, int Y, const std::wstring & text, int R, int G, int B, int A, DxFont & F) { float blendFactor[4] = { 1.0f }; GetDX11Context()->OMSetBlendState(TransparentBS, blendFactor, 0xFFFFFFFF); BeginBatch(F.GetFontSheetSRV()); UINT length = text.length(); int posX = X; int posY = Y; XMCOLOR color; XMVECTOR Vec = XMVectorSet( R ? (float)( R / 255.0f ) : 0.0f, G ? (float)( G / 255.0f ) : 0.0f, B ? (float)( B / 255.0f ) : 0.0f, A ? (float)( A / 255.0f ) : 0.0f ); XMStoreColor(&color, Vec); for(UINT i = 0; i < length; ++i) { WCHAR character = text[i]; if(character == ' ') posX += F.GetSpaceWidth(); else if(character == '\n') { posX = X; posY += F.GetCharHeight(); } else { const CD3D11_RECT & charRect = F.GetCharRect(character); int width = charRect.right - charRect.left; int height = charRect.bottom - charRect.top; Draw(CD3D11_RECT(posX, posY, posX + width, posY + height), charRect, color); posX += width + 1; } } EndBatch(); GetDX11Context()->OMSetBlendState(0, blendFactor, 0xFFFFFFFF); }
void XFBSource::CopyEFB(float Gamma) { g_renderer->ResetAPIState(); // reset any game specific settings // Copy EFB data to XFB and restore render target again const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)texWidth, (float)texHeight); const D3D11_RECT rect = CD3D11_RECT(0, 0, texWidth, texHeight); D3D::context->RSSetViewports(1, &vp); D3D::context->OMSetRenderTargets(1, &tex->GetRTV(), nullptr); D3D::SetPointCopySampler(); D3D::drawShadedTexQuad(FramebufferManager::GetEFBColorTexture()->GetSRV(), &rect, Renderer::GetTargetWidth(), Renderer::GetTargetHeight(), PixelShaderCache::GetColorCopyProgram(true), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), GeometryShaderCache::GetCopyGeometryShader(), Gamma); D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); g_renderer->RestoreAPIState(); }
void TextureCache::TCacheEntry::FromRenderTarget(u8* dst, PEControl::PixelFormat src_format, const EFBRectangle& srcRect, bool scale_by_half, unsigned int cbuf_id, const float* colmat) { // When copying at half size, in multisampled mode, resolve the color/depth buffer first. // This is because multisampled texture reads go through Load, not Sample, and the linear // filter is ignored. bool multisampled = (g_ActiveConfig.iMultisamples > 1); D3DTexture2D* efb_tex = (src_format == PEControl::Z24) ? FramebufferManager::GetEFBDepthTexture() : FramebufferManager::GetEFBColorTexture(); if (multisampled && scale_by_half) { multisampled = false; efb_tex = (src_format == PEControl::Z24) ? FramebufferManager::GetResolvedEFBDepthTexture() : FramebufferManager::GetResolvedEFBColorTexture(); } // stretch picture with increased internal resolution const D3D12_VIEWPORT vp = { 0.f, 0.f, (float)config.width, (float)config.height, D3D12_MIN_DEPTH, D3D12_MAX_DEPTH }; D3D::current_command_list->RSSetViewports(1, &vp); // set transformation if (nullptr == s_efb_copy_buffers[cbuf_id]) { CheckHR( D3D::device12->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(28 * sizeof(float)), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&s_efb_copy_buffers[cbuf_id]) ) ); void* pData = nullptr; CheckHR(s_efb_copy_buffers[cbuf_id]->Map(0, nullptr, &pData)); memcpy(pData, colmat, 28 * sizeof(float)); } D3D::current_command_list->SetGraphicsRootConstantBufferView(DESCRIPTOR_TABLE_PS_CBVONE, s_efb_copy_buffers[cbuf_id]->GetGPUVirtualAddress()); D3D::command_list_mgr->m_dirty_ps_cbv = true; const TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(srcRect); // TODO: try targetSource.asRECT(); const D3D11_RECT sourcerect = CD3D11_RECT(targetSource.left, targetSource.top, targetSource.right, targetSource.bottom); // Use linear filtering if (bScaleByHalf), use point filtering otherwise if (scale_by_half) D3D::SetLinearCopySampler(); else D3D::SetPointCopySampler(); // Make sure we don't draw with the texture set as both a source and target. // (This can happen because we don't unbind textures when we free them.) m_texture->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_RENDER_TARGET); D3D::current_command_list->OMSetRenderTargets(1, &m_texture->GetRTV12(), FALSE, nullptr); // Create texture copy D3D::DrawShadedTexQuad( efb_tex, &sourcerect, Renderer::GetTargetWidth(), Renderer::GetTargetHeight(), (src_format == PEControl::Z24) ? StaticShaderCache::GetDepthMatrixPixelShader(multisampled) : StaticShaderCache::GetColorMatrixPixelShader(multisampled), StaticShaderCache::GetSimpleVertexShader(), StaticShaderCache::GetSimpleVertexShaderInputLayout(), StaticShaderCache::GetCopyGeometryShader(), 1.0f, 0, DXGI_FORMAT_R8G8B8A8_UNORM, false, m_texture->GetMultisampled() ); m_texture->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); FramebufferManager::GetEFBColorTexture()->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_RENDER_TARGET); FramebufferManager::GetEFBDepthTexture()->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_DEPTH_WRITE); D3D::current_command_list->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV12(), FALSE, &FramebufferManager::GetEFBDepthTexture()->GetDSV12()); g_renderer->RestoreAPIState(); }
void DX11SpriteBatch::DrawInfoText(DX11FontSheet& fs, const char* text, const POINT& pos) { BeginBatch(fs.GetFontSheetSRV()); int posX = pos.x; int posY = pos.y; int tabIdx = 0; int maxCharWidth = fs.GetMaxCharWidth(); XMCOLOR color = Color::Black; u32 i = 0; while( true ) { WCHAR character = text[i]; if(character == ' ') { posX += maxCharWidth; tabIdx += maxCharWidth; } else if(character == '\t') { posX += (4*maxCharWidth - tabIdx%(4*maxCharWidth)); tabIdx = 0; } else if(character == '\n') { posX = pos.x; posY += fs.GetCharHeight(); tabIdx = 0; } else if(character == SCREEN_WHITE) color = Color::White; else if(character == SCREEN_RED) color = Color::Red; else if(character == SCREEN_GREEN) color = Color::Lime; else if(character == SCREEN_BLUE) color = Color::Blue; else if(character == SCREEN_YELLOW) color = Color::Yellow; else if(character == SCREEN_ORANGE) color = Color::Orange; else if(character == SCREEN_ROSE) color = Color::Fuchsia; else if(character == SCREEN_GRAY) color = Color::Gray; else if(character == SCREEN_BLACK) color = Color::Black; else if(character == nullchar) break; else { if ( character < DX11FontSheet::StartChar || character > DX11FontSheet::EndChar ) character = '?'; // Get the bounding rect of the character on the fontsheet. const CD3D11_RECT& charRect = fs.GetCharBoundingRect(character); int width = charRect.right - charRect.left; int height = charRect.bottom - charRect.top; int delta = maxCharWidth - width; // Draw the character sprite. Draw(CD3D11_RECT(posX, posY, posX + width, posY + height), charRect, color); // Move to the next character position. posX += width + delta; tabIdx += width + delta; } ++i; } EndBatch(mContext); }
void DX11SpriteBatch::DrawString(DX11FontSheet& fs, const char text[], const POINT& pos, XMCOLOR color, TextAlignment alignment) { BeginBatch(fs.GetFontSheetSRV()); u32 length = (u32)strlen(text); int posX = 0; int posY = pos.y; int totalWidth = 0; int tabIdx = 0; int maxCharWidth = fs.GetMaxCharWidth(); if (alignment == LeftAligned) { posX = pos.x; } else { // Calculate text total width to adjust with the alignment for(u32 i = 0; i < length; ++i) { WCHAR character = text[i]; if(character == ' ') { totalWidth += maxCharWidth; } else { if ( character < DX11FontSheet::StartChar || character > DX11FontSheet::EndChar ) character = '?'; // Get the bounding rect of the character on the fontsheet. const CD3D11_RECT& charRect = fs.GetCharBoundingRect(character); int width = charRect.right - charRect.left; totalWidth += width; } } if (alignment == RightAligned) posX = pos.x - totalWidth; else posX = pos.x - totalWidth/ 2; } for(u32 i = 0; i < length; ++i) { WCHAR character = text[i]; if(character == ' ') { posX += maxCharWidth; tabIdx += maxCharWidth; } else if(character == '\t') { posX += (4*maxCharWidth - posX%(4*maxCharWidth)); tabIdx = 0; } else if(character == '\n') { posX = pos.x; posY += fs.GetCharHeight();; tabIdx = 0; } else { if ( character < DX11FontSheet::StartChar || character > DX11FontSheet::EndChar ) character = '?'; // Get the bounding rect of the character on the fontsheet. const CD3D11_RECT& charRect = fs.GetCharBoundingRect(character); int width = charRect.right - charRect.left; int height = charRect.bottom - charRect.top; int delta = maxCharWidth - width; // Draw the character sprite. Draw(CD3D11_RECT(posX, posY, posX + width, posY + height), charRect, color); // Move to the next character position. posX += width + delta; tabIdx += width + delta; } } EndBatch(mContext); }
void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFormat, PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf, unsigned int cbufid, const float *colmat) { if (type != TCET_EC_DYNAMIC || g_ActiveConfig.bCopyEFBToTexture) { g_renderer->ResetAPIState(); // stretch picture with increased internal resolution const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)virtual_width, (float)virtual_height); D3D::context->RSSetViewports(1, &vp); // set transformation if (nullptr == efbcopycbuf[cbufid]) { const D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(28 * sizeof(float), D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DEFAULT); D3D11_SUBRESOURCE_DATA data; data.pSysMem = colmat; HRESULT hr = D3D::device->CreateBuffer(&cbdesc, &data, &efbcopycbuf[cbufid]); CHECK(SUCCEEDED(hr), "Create efb copy constant buffer %d", cbufid); D3D::SetDebugObjectName((ID3D11DeviceChild*)efbcopycbuf[cbufid], "a constant buffer used in TextureCache::CopyRenderTargetToTexture"); } D3D::stateman->SetPixelConstants(efbcopycbuf[cbufid]); const TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(srcRect); // TODO: try targetSource.asRECT(); const D3D11_RECT sourcerect = CD3D11_RECT(targetSource.left, targetSource.top, targetSource.right, targetSource.bottom); // Use linear filtering if (bScaleByHalf), use point filtering otherwise if (scaleByHalf) D3D::SetLinearCopySampler(); else D3D::SetPointCopySampler(); // if texture is currently in use, it needs to be temporarily unset u32 textureSlotMask = D3D::stateman->UnsetTexture(texture->GetSRV()); D3D::stateman->Apply(); D3D::context->OMSetRenderTargets(1, &texture->GetRTV(), nullptr); // Create texture copy D3D::drawShadedTexQuad( (srcFormat == PEControl::Z24) ? FramebufferManager::GetEFBDepthTexture()->GetSRV() : FramebufferManager::GetEFBColorTexture()->GetSRV(), &sourcerect, Renderer::GetTargetWidth(), Renderer::GetTargetHeight(), (srcFormat == PEControl::Z24) ? PixelShaderCache::GetDepthMatrixProgram(true) : PixelShaderCache::GetColorMatrixProgram(true), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), GeometryShaderCache::GetCopyGeometryShader()); D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); g_renderer->RestoreAPIState(); // Restore old texture in all previously used slots, if any D3D::stateman->SetTextureByMask(textureSlotMask, texture->GetSRV()); } if (!g_ActiveConfig.bCopyEFBToTexture) { u8* dst = Memory::GetPointer(dstAddr); size_t encoded_size = g_encoder->Encode(dst, dstFormat, srcFormat, srcRect, isIntensity, scaleByHalf); u64 hash = GetHash64(dst, (int)encoded_size, g_ActiveConfig.iSafeTextureCache_ColorSamples); // Mark texture entries in destination address range dynamic unless caching is enabled and the texture entry is up to date if (!g_ActiveConfig.bEFBCopyCacheEnable) TextureCache::MakeRangeDynamic(addr, (u32)encoded_size); else if (!TextureCache::Find(addr, hash)) TextureCache::MakeRangeDynamic(addr, (u32)encoded_size); this->hash = hash; } }