本文整理汇总了C++中TCacheEntryBase::SetHashes方法的典型用法代码示例。如果您正苦于以下问题:C++ TCacheEntryBase::SetHashes方法的具体用法?C++ TCacheEntryBase::SetHashes怎么用?C++ TCacheEntryBase::SetHashes使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类TCacheEntryBase
的用法示例。
在下文中一共展示了TCacheEntryBase::SetHashes方法的6个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: DoPartialTextureUpdates
TextureCache::TCacheEntryBase* TextureCache::DoPartialTextureUpdates(TexCache::iterator iter_t)
{
TCacheEntryBase* entry_to_update = iter_t->second;
const bool isPaletteTexture = (entry_to_update->format == GX_TF_C4
|| entry_to_update->format == GX_TF_C8
|| entry_to_update->format == GX_TF_C14X2
|| entry_to_update->format >= 0x10000);
// Efb copies and paletted textures are excluded from these updates, until there's an example where a game would
// benefit from this. Both would require more work to be done.
// TODO: Implement upscaling support for normal textures, and then remove the efb to ram and the scaled efb restrictions
if (entry_to_update->IsEfbCopy()
|| isPaletteTexture)
return entry_to_update;
u32 block_width = TexDecoder_GetBlockWidthInTexels(entry_to_update->format);
u32 block_height = TexDecoder_GetBlockHeightInTexels(entry_to_update->format);
u32 block_size = block_width * block_height * TexDecoder_GetTexelSizeInNibbles(entry_to_update->format) / 2;
u32 numBlocksX = (entry_to_update->native_width + block_width - 1) / block_width;
TexCache::iterator iter = textures_by_address.lower_bound(entry_to_update->addr);
TexCache::iterator iterend = textures_by_address.upper_bound(entry_to_update->addr + entry_to_update->size_in_bytes);
bool entry_need_scaling = true;
while (iter != iterend)
{
TCacheEntryBase* entry = iter->second;
if (entry != entry_to_update
&& entry->IsEfbCopy()
&& entry_to_update->addr <= entry->addr
&& entry->addr + entry->size_in_bytes <= entry_to_update->addr + entry_to_update->size_in_bytes
&& entry->frameCount == FRAMECOUNT_INVALID
&& entry->memory_stride == numBlocksX * block_size)
{
u32 block_offset = (entry->addr - entry_to_update->addr) / block_size;
u32 block_x = block_offset % numBlocksX;
u32 block_y = block_offset / numBlocksX;
u32 x = block_x * block_width;
u32 y = block_y * block_height;
MathUtil::Rectangle<int> srcrect, dstrect;
srcrect.left = 0;
srcrect.top = 0;
dstrect.left = 0;
dstrect.top = 0;
if (entry_need_scaling)
{
entry_need_scaling = false;
u32 w = entry_to_update->native_width * entry->config.width / entry->native_width;
u32 h = entry_to_update->native_height * entry->config.height / entry->native_height;
u32 max = g_renderer->GetMaxTextureSize();
if (max < w || max < h)
{
iter++;
continue;
}
if (entry_to_update->config.width != w || entry_to_update->config.height != h)
{
TextureCache::TCacheEntryConfig newconfig;
newconfig.width = w;
newconfig.height = h;
newconfig.rendertarget = true;
TCacheEntryBase* newentry = AllocateTexture(newconfig);
newentry->SetGeneralParameters(entry_to_update->addr, entry_to_update->size_in_bytes, entry_to_update->format);
newentry->SetDimensions(entry_to_update->native_width, entry_to_update->native_height, 1);
newentry->SetHashes(entry_to_update->base_hash, entry_to_update->hash);
newentry->frameCount = frameCount;
newentry->is_efb_copy = false;
srcrect.right = entry_to_update->config.width;
srcrect.bottom = entry_to_update->config.height;
dstrect.right = w;
dstrect.bottom = h;
newentry->CopyRectangleFromTexture(entry_to_update, srcrect, dstrect);
entry_to_update = newentry;
u64 key = iter_t->first;
iter_t = FreeTexture(iter_t);
textures_by_address.emplace(key, entry_to_update);
}
}
srcrect.right = entry->config.width;
srcrect.bottom = entry->config.height;
dstrect.left = x * entry_to_update->config.width / entry_to_update->native_width;
dstrect.top = y * entry_to_update->config.height / entry_to_update->native_height;
dstrect.right = (x + entry->native_width) * entry_to_update->config.width / entry_to_update->native_width;
dstrect.bottom = (y + entry->native_height) * entry_to_update->config.height / entry_to_update->native_height;
entry_to_update->CopyRectangleFromTexture(entry, srcrect, dstrect);
// Mark the texture update as used, so it isn't applied more than once
entry->frameCount = frameCount;
}
++iter;
}
return entry_to_update;
}
示例2: CopyRenderTargetToTexture
//.........这里部分代码省略.........
bytes_per_row,
num_blocks_y,
dstStride,
srcFormat,
srcRect,
isIntensity,
scaleByHalf);
}
else
{
// Hack: Most games don't actually need the correct texture data in RAM
// and we can just keep a copy in VRAM. We zero the memory so we
// can check it hasn't changed before using our copy in VRAM.
u8* ptr = dst;
for (u32 i = 0; i < num_blocks_y; i++)
{
memset(ptr, 0, bytes_per_row);
ptr += dstStride;
}
}
if (g_bRecordFifoData)
{
// Mark the memory behind this efb copy as dynamicly generated for the Fifo log
u32 address = dstAddr;
for (u32 i = 0; i < num_blocks_y; i++)
{
FifoRecorder::GetInstance().UseMemory(address, bytes_per_row, MemoryUpdate::TEXTURE_MAP, true);
address += dstStride;
}
}
if (dstStride < bytes_per_row)
{
// This kind of efb copy results in a scrambled image.
// I'm pretty sure no game actually wants to do this, it might be caused by a
// programming bug in the game, or a CPU/Bounding box emulation issue with dolphin.
// The copy_to_ram code path above handles this "correctly" and scrambles the image
// but the copy_to_vram code path just saves and uses unscrambled texture instead.
// To avoid a "incorrect" result, we simply skip doing the copy_to_vram code path
// so if the game does try to use the scrambled texture, dolphin will grab the scrambled
// texture (or black if copy_to_ram is also disabled) out of ram.
ERROR_LOG(VIDEO, "Memory stride too small (%i < %i)", dstStride, bytes_per_row);
copy_to_vram = false;
}
// Invalidate all textures that overlap the range of our efb copy.
// Unless our efb copy has a weird stride, then we want avoid invalidating textures which
// we might be able to do a partial texture update on.
// TODO: This also invalidates partial overlaps, which we currently don't have a better way
// of dealing with.
if (dstStride == bytes_per_row || !copy_to_vram)
{
TexCache::iterator iter = textures_by_address.begin();
while (iter != textures_by_address.end())
{
if (iter->second->addr + iter->second->size_in_bytes <= dstAddr || iter->second->addr >= dstAddr + num_blocks_y * dstStride)
++iter;
else
iter = InvalidateTexture(iter);
}
}
if (copy_to_vram)
{
// create the texture
TCacheEntryConfig config;
config.rendertarget = true;
config.width = scaled_tex_w;
config.height = scaled_tex_h;
config.layers = FramebufferManagerBase::GetEFBLayers();
TCacheEntryBase* entry = AllocateTexture(config);
if (entry)
{
entry->SetGeneralParameters(dstAddr, 0, baseFormat);
entry->SetDimensions(tex_w, tex_h, 1);
entry->frameCount = FRAMECOUNT_INVALID;
entry->SetEfbCopy(dstStride);
entry->is_custom_tex = false;
entry->FromRenderTarget(dst, srcFormat, srcRect, scaleByHalf, cbufid, colmat);
u64 hash = entry->CalculateHash();
entry->SetHashes(hash, hash);
if (g_ActiveConfig.bDumpEFBTarget)
{
static int count = 0;
entry->Save(StringFromFormat("%sefb_frame_%i.png", File::GetUserPath(D_DUMPTEXTURES_IDX).c_str(),
count++), 0);
}
textures_by_address.emplace((u64)dstAddr, entry);
}
}
}
示例3: Load
//.........这里部分代码省略.........
config.width = width;
config.height = height;
config.levels = texLevels;
TCacheEntryBase* entry = AllocateTexture(config);
GFX_DEBUGGER_PAUSE_AT(NEXT_NEW_TEXTURE, true);
if (!entry)
return nullptr;
if (!hires_tex)
{
if (!(texformat == GX_TF_RGBA8 && from_tmem))
{
const u8* tlut = &texMem[tlutaddr];
TexDecoder_Decode(temp, src_data, expandedWidth, expandedHeight, texformat, tlut, (TlutFormat)tlutfmt);
}
else
{
u8* src_data_gb = &texMem[bpmem.tex[stage / 4].texImage2[stage % 4].tmem_odd * TMEM_LINE_SIZE];
TexDecoder_DecodeRGBA8FromTmem(temp, src_data, src_data_gb, expandedWidth, expandedHeight);
}
}
iter = textures_by_address.emplace((u64)address, entry);
if (g_ActiveConfig.iSafeTextureCache_ColorSamples == 0 ||
std::max(texture_size, palette_size) <= (u32)g_ActiveConfig.iSafeTextureCache_ColorSamples * 8)
{
entry->textures_by_hash_iter = textures_by_hash.emplace(full_hash, entry);
}
entry->SetGeneralParameters(address, texture_size, full_format);
entry->SetDimensions(nativeW, nativeH, tex_levels);
entry->SetHashes(base_hash, full_hash);
entry->is_efb_copy = false;
entry->is_custom_tex = hires_tex != nullptr;
// load texture
entry->Load(width, height, expandedWidth, 0);
std::string basename = "";
if (g_ActiveConfig.bDumpTextures && !hires_tex)
{
basename = HiresTexture::GenBaseName(
src_data, texture_size,
&texMem[tlutaddr], palette_size,
width, height,
texformat, use_mipmaps,
true
);
DumpTexture(entry, basename, 0);
}
if (hires_tex)
{
for (u32 level_index = 1; level_index != texLevels; ++level_index)
{
const auto& level = hires_tex->m_levels[level_index];
CheckTempSize(level.data_size);
memcpy(temp, level.data.get(), level.data_size);
entry->Load(level.width, level.height, level.width, level_index);
}
}
else
{
// load mips - TODO: Loading mipmaps from tmem is untested!
示例4: ScaleTextureCacheEntryTo
void TextureCacheBase::ScaleTextureCacheEntryTo(TextureCacheBase::TCacheEntryBase** entry, u32 new_width, u32 new_height)
{
if ((*entry)->config.width == new_width && (*entry)->config.height == new_height)
{
return;
}
u32 max = g_renderer->GetMaxTextureSize();
if (max < new_width || max < new_height)
{
ERROR_LOG(VIDEO, "Texture too big, width = %d, height = %d", new_width, new_height);
return;
}
TextureCacheBase::TCacheEntryConfig newconfig;
newconfig.width = new_width;
newconfig.height = new_height;
newconfig.layers = (*entry)->config.layers;
newconfig.rendertarget = true;
TCacheEntryBase* newentry = AllocateTexture(newconfig);
if (newentry)
{
newentry->SetGeneralParameters((*entry)->addr, (*entry)->size_in_bytes, (*entry)->format);
newentry->SetDimensions((*entry)->native_width, (*entry)->native_height, 1);
newentry->SetHashes((*entry)->base_hash, (*entry)->hash);
newentry->frameCount = frameCount;
newentry->is_efb_copy = (*entry)->is_efb_copy;
MathUtil::Rectangle<int> srcrect, dstrect;
srcrect.left = 0;
srcrect.top = 0;
srcrect.right = (*entry)->config.width;
srcrect.bottom = (*entry)->config.height;
dstrect.left = 0;
dstrect.top = 0;
dstrect.right = new_width;
dstrect.bottom = new_height;
newentry->CopyRectangleFromTexture(*entry, srcrect, dstrect);
// Keep track of the pointer for textures_by_hash
if ((*entry)->textures_by_hash_iter != textures_by_hash.end())
{
newentry->textures_by_hash_iter = textures_by_hash.emplace((*entry)->hash, newentry);
}
// Remove the old texture
std::pair<TexCache::iterator, TexCache::iterator>iter_range = textures_by_address.equal_range((*entry)->addr);
TexCache::iterator iter = iter_range.first;
while (iter != iter_range.second)
{
if (iter->second == *entry)
{
FreeTexture(iter);
iter = iter_range.second;
}
else
{
iter++;
}
}
*entry = newentry;
textures_by_address.emplace((*entry)->addr, *entry);
}
else
{
ERROR_LOG(VIDEO, "Scaling failed");
}
}
示例5: CopyRenderTargetToTexture
//.........这里部分代码省略.........
break;
case 7: // A8
colmat[3] = colmat[7] = colmat[11] = colmat[15] = 1.0f;
cbufid = 16;
break;
case 9: // G8
colmat[1] = colmat[5] = colmat[9] = colmat[13] = 1.0f;
cbufid = 17;
break;
case 10: // B8
colmat[2] = colmat[6] = colmat[10] = colmat[14] = 1.0f;
cbufid = 18;
break;
case 11: // RG8
colmat[0] = colmat[4] = colmat[8] = colmat[13] = 1.0f;
cbufid = 19;
break;
case 12: // GB8
colmat[1] = colmat[5] = colmat[9] = colmat[14] = 1.0f;
cbufid = 20;
break;
case 4: // RGB565
colmat[0] = colmat[5] = colmat[10] = 1.0f;
ColorMask[0] = ColorMask[2] = 31.0f;
ColorMask[4] = ColorMask[6] = 1.0f / 31.0f;
ColorMask[1] = 63.0f;
ColorMask[5] = 1.0f / 63.0f;
fConstAdd[3] = 1.0f; // set alpha to 1
cbufid = 21;
break;
case 5: // RGB5A3
colmat[0] = colmat[5] = colmat[10] = colmat[15] = 1.0f;
ColorMask[0] = ColorMask[1] = ColorMask[2] = 31.0f;
ColorMask[4] = ColorMask[5] = ColorMask[6] = 1.0f / 31.0f;
ColorMask[3] = 7.0f;
ColorMask[7] = 1.0f / 7.0f;
cbufid = 22;
break;
case 6: // RGBA8
colmat[0] = colmat[5] = colmat[10] = colmat[15] = 1.0f;
cbufid = 23;
break;
default:
ERROR_LOG(VIDEO, "Unknown copy color format: 0x%x", dstFormat);
colmat[0] = colmat[5] = colmat[10] = colmat[15] = 1.0f;
cbufid = 23;
break;
}
}
const unsigned int tex_w = scaleByHalf ? srcRect.GetWidth()/2 : srcRect.GetWidth();
const unsigned int tex_h = scaleByHalf ? srcRect.GetHeight()/2 : srcRect.GetHeight();
unsigned int scaled_tex_w = g_ActiveConfig.bCopyEFBScaled ? Renderer::EFBToScaledX(tex_w) : tex_w;
unsigned int scaled_tex_h = g_ActiveConfig.bCopyEFBScaled ? Renderer::EFBToScaledY(tex_h) : tex_h;
TCacheEntryBase *entry = textures[dstAddr];
if (entry)
{
if (entry->type == TCET_EC_DYNAMIC && entry->native_width == tex_w && entry->native_height == tex_h)
{
scaled_tex_w = tex_w;
scaled_tex_h = tex_h;
}
else if (!(entry->type == TCET_EC_VRAM && entry->virtual_width == scaled_tex_w && entry->virtual_height == scaled_tex_h))
{
// remove it and recreate it as a render target
delete entry;
entry = NULL;
}
}
if (NULL == entry)
{
// create the texture
textures[dstAddr] = entry = g_texture_cache->CreateRenderTargetTexture(scaled_tex_w, scaled_tex_h);
// TODO: Using the wrong dstFormat, dumb...
entry->SetGeneralParameters(dstAddr, 0, dstFormat, 1);
entry->SetDimensions(tex_w, tex_h, scaled_tex_w, scaled_tex_h);
entry->SetHashes(TEXHASH_INVALID);
entry->type = TCET_EC_VRAM;
}
entry->frameCount = frameCount;
g_renderer->ResetAPIState(); // reset any game specific settings
entry->FromRenderTarget(dstAddr, dstFormat, srcFormat, srcRect, isIntensity, scaleByHalf, cbufid, colmat);
g_renderer->RestoreAPIState();
}
示例6: CopyRenderTargetToTexture
//.........这里部分代码省略.........
break;
case 6: // RGBA8
colmat[0] = colmat[5] = colmat[10] = colmat[15] = 1.0f;
cbufid = 29;
if (!efbHasAlpha)
{
ColorMask[3] = 0.0f;
fConstAdd[3] = 1.0f;
cbufid = 30;
}
break;
default:
ERROR_LOG(VIDEO, "Unknown copy color format: 0x%x", dstFormat);
colmat[0] = colmat[5] = colmat[10] = colmat[15] = 1.0f;
cbufid = 31;
break;
}
}
u8* dst = Memory::GetPointer(dstAddr);
if (dst == nullptr)
{
ERROR_LOG(VIDEO, "Trying to copy from EFB to invalid address 0x%8x", dstAddr);
return;
}
const unsigned int tex_w = scaleByHalf ? srcRect.GetWidth() / 2 : srcRect.GetWidth();
const unsigned int tex_h = scaleByHalf ? srcRect.GetHeight() / 2 : srcRect.GetHeight();
unsigned int scaled_tex_w = g_ActiveConfig.bCopyEFBScaled ? Renderer::EFBToScaledX(tex_w) : tex_w;
unsigned int scaled_tex_h = g_ActiveConfig.bCopyEFBScaled ? Renderer::EFBToScaledY(tex_h) : tex_h;
// remove all texture cache entries at dstAddr
{
std::pair<TexCache::iterator, TexCache::iterator> iter_range = textures_by_address.equal_range((u64)dstAddr);
TexCache::iterator iter = iter_range.first;
while (iter != iter_range.second)
{
iter = FreeTexture(iter);
}
}
// create the texture
TCacheEntryConfig config;
config.rendertarget = true;
config.width = scaled_tex_w;
config.height = scaled_tex_h;
config.layers = FramebufferManagerBase::GetEFBLayers();
TCacheEntryBase* entry = AllocateTexture(config);
entry->SetGeneralParameters(dstAddr, 0, dstFormat);
entry->SetDimensions(tex_w, tex_h, 1);
entry->frameCount = FRAMECOUNT_INVALID;
entry->SetEfbCopy(dstStride);
entry->is_custom_tex = false;
entry->FromRenderTarget(dst, dstFormat, dstStride, srcFormat, srcRect, isIntensity, scaleByHalf, cbufid, colmat);
u64 hash = entry->CalculateHash();
entry->SetHashes(hash, hash);
// Invalidate all textures that overlap the range of our efb copy.
// Unless our efb copy has a weird stride, then we want avoid invalidating textures which
// we might be able to do a partial texture update on.
if (entry->memory_stride == entry->CacheLinesPerRow() * 32)
{
TexCache::iterator iter = textures_by_address.begin();
while (iter != textures_by_address.end())
{
if (iter->second->OverlapsMemoryRange(dstAddr, entry->size_in_bytes))
iter = FreeTexture(iter);
else
++iter;
}
}
if (g_ActiveConfig.bDumpEFBTarget)
{
static int count = 0;
entry->Save(StringFromFormat("%sefb_frame_%i.png", File::GetUserPath(D_DUMPTEXTURES_IDX).c_str(),
count++), 0);
}
if (g_bRecordFifoData)
{
// Mark the memory behind this efb copy as dynamicly generated for the Fifo log
u32 address = dstAddr;
for (u32 i = 0; i < entry->NumBlocksY(); i++)
{
FifoRecorder::GetInstance().UseMemory(address, entry->CacheLinesPerRow() * 32, MemoryUpdate::TEXTURE_MAP, true);
address += entry->memory_stride;
}
}
textures_by_address.emplace((u64)dstAddr, entry);
}