mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-07-11 01:25:07 +02:00
Disable anisotropic filtering for all flat draws.
May improve performance slightly, and should fix the last instances of #19555
This commit is contained in:
@@ -182,7 +182,7 @@ static int TexLog2(float delta) {
|
||||
return useful - 127 * 256;
|
||||
}
|
||||
|
||||
SamplerCacheKey TextureCacheCommon::GetSamplingParams(int maxLevel, const TexCacheEntry *entry) {
|
||||
SamplerCacheKey TextureCacheCommon::GetSamplingParams(int maxLevel, const TexCacheEntry *entry, bool flatZ) {
|
||||
SamplerCacheKey key{};
|
||||
|
||||
int minFilt = gstate.texfilter & 0x7;
|
||||
@@ -224,7 +224,7 @@ SamplerCacheKey TextureCacheCommon::GetSamplingParams(int maxLevel, const TexCac
|
||||
key.maxLevel = maxLevel * 256;
|
||||
key.minLevel = 0;
|
||||
key.lodBias = (int)(lodBias * 256.0f);
|
||||
if (gstate_c.Use(GPU_USE_ANISOTROPY) && g_Config.iAnisotropyLevel > 0) {
|
||||
if (gstate_c.Use(GPU_USE_ANISOTROPY) && !flatZ) {
|
||||
key.aniso = true;
|
||||
}
|
||||
break;
|
||||
@@ -260,7 +260,7 @@ SamplerCacheKey TextureCacheCommon::GetSamplingParams(int maxLevel, const TexCac
|
||||
key.mipEnable = true;
|
||||
key.mipFilt = 1;
|
||||
key.maxLevel = 9 * 256;
|
||||
if (gstate_c.Use(GPU_USE_ANISOTROPY) && g_Config.iAnisotropyLevel > 0) {
|
||||
if (gstate_c.Use(GPU_USE_ANISOTROPY) && !flatZ) {
|
||||
key.aniso = true;
|
||||
}
|
||||
}
|
||||
@@ -294,7 +294,7 @@ SamplerCacheKey TextureCacheCommon::GetSamplingParams(int maxLevel, const TexCac
|
||||
case TEX_FILTER_AUTO_MAX_QUALITY:
|
||||
default:
|
||||
forceFiltering = TEX_FILTER_AUTO_MAX_QUALITY;
|
||||
if (gstate_c.Use(GPU_USE_ANISOTROPY) && g_Config.iAnisotropyLevel > 0) {
|
||||
if (gstate_c.Use(GPU_USE_ANISOTROPY) && !flatZ) {
|
||||
key.aniso = true;
|
||||
}
|
||||
if (gstate.isModeThrough() && g_Config.iInternalResolution != 1) {
|
||||
@@ -339,7 +339,7 @@ SamplerCacheKey TextureCacheCommon::GetSamplingParams(int maxLevel, const TexCac
|
||||
}
|
||||
|
||||
SamplerCacheKey TextureCacheCommon::GetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight) {
|
||||
SamplerCacheKey key = GetSamplingParams(0, nullptr);
|
||||
SamplerCacheKey key = GetSamplingParams(0, nullptr, true);
|
||||
|
||||
// In case auto max quality was on, restore min filt. Another fix for water in Outrun.
|
||||
if (g_Config.iTexFiltering == TEX_FILTER_AUTO_MAX_QUALITY) {
|
||||
@@ -2129,14 +2129,14 @@ CheckAlphaResult TextureCacheCommon::ReadIndexedTex(u8 *out, int outPitch, int l
|
||||
}
|
||||
}
|
||||
|
||||
void TextureCacheCommon::ApplyTexture(bool doBind) {
|
||||
void TextureCacheCommon::ApplyTexture(bool doBind, bool flatZ) {
|
||||
TexCacheEntry *entry = nextTexture_;
|
||||
if (!entry) {
|
||||
// Maybe we bound a framebuffer?
|
||||
ForgetLastTexture();
|
||||
if (failedTexture_) {
|
||||
// Backends should handle this by binding a black texture with 0 alpha.
|
||||
BindTexture(nullptr);
|
||||
BindTexture(nullptr, flatZ);
|
||||
} else if (nextFramebufferTexture_) {
|
||||
// ApplyTextureFrameBuffer is responsible for setting SetTextureFullAlpha.
|
||||
ApplyTextureFramebuffer(nextFramebufferTexture_, gstate.getTextureFormat(), nextFramebufferTextureChannel_);
|
||||
@@ -2211,7 +2211,7 @@ void TextureCacheCommon::ApplyTexture(bool doBind) {
|
||||
} else {
|
||||
entry->lastFrame = gpuStats.totals.numFlips;
|
||||
if (doBind) {
|
||||
BindTexture(entry);
|
||||
BindTexture(entry, flatZ);
|
||||
}
|
||||
gstate_c.SetTextureFullAlpha(entry->GetAlphaStatus() == TexCacheEntry::STATUS_ALPHA_FULL);
|
||||
gstate_c.SetTextureIs3D((entry->status & TexCacheEntry::STATUS_3D) != 0);
|
||||
|
||||
@@ -351,7 +351,7 @@ public:
|
||||
shaderManager_ = sm;
|
||||
}
|
||||
|
||||
void ApplyTexture(bool doBind = true);
|
||||
void ApplyTexture(bool doBind, bool flatZ);
|
||||
bool SetOffsetTexture(u32 yOffset);
|
||||
void Invalidate(u32 addr, int size, GPUInvalidationType type);
|
||||
void InvalidateAll(GPUInvalidationType type);
|
||||
@@ -408,7 +408,7 @@ public:
|
||||
protected:
|
||||
bool PrepareBuildTexture(BuildTexturePlan &plan, TexCacheEntry *entry);
|
||||
|
||||
virtual void BindTexture(TexCacheEntry *entry) = 0;
|
||||
virtual void BindTexture(TexCacheEntry *entry, bool flatZ) = 0;
|
||||
virtual void Unbind() = 0;
|
||||
virtual void ReleaseTexture(TexCacheEntry *entry, bool delete_them) = 0;
|
||||
void DeleteTexture(TexCache::iterator it);
|
||||
@@ -445,7 +445,7 @@ protected:
|
||||
|
||||
static u32 EstimateTexMemoryUsage(const TexCacheEntry *entry);
|
||||
|
||||
SamplerCacheKey GetSamplingParams(int maxLevel, const TexCacheEntry *entry);
|
||||
SamplerCacheKey GetSamplingParams(int maxLevel, const TexCacheEntry *entry, bool flatZ);
|
||||
SamplerCacheKey GetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight);
|
||||
void UpdateMaxSeenV(TexCacheEntry *entry, bool throughMode);
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ public:
|
||||
void ReadColor0(float color[4]) const {
|
||||
switch (decFmt_.c0fmt) {
|
||||
case DEC_U8_4:
|
||||
Uint8x4ToFloat4(color, *(const u32 *)(data_ + decFmt_.c0off));
|
||||
Vec4F32::LoadU8Norm(data_ + decFmt_.c0off).Store(color);
|
||||
break;
|
||||
case DEC_FLOAT_4:
|
||||
memcpy(color, data_ + decFmt_.c0off, 16);
|
||||
@@ -119,7 +119,7 @@ public:
|
||||
Vec4F32 ReadColorF32() const {
|
||||
switch (decFmt_.c0fmt) {
|
||||
case DEC_U8_4:
|
||||
return Vec4F32::LoadU8Norm((const u8 *)(data_ + decFmt_.c0off));
|
||||
return Vec4F32::LoadU8Norm(data_ + decFmt_.c0off);
|
||||
case DEC_FLOAT_4:
|
||||
return Vec4F32::Load((const float *)(data_ + decFmt_.c0off));
|
||||
default:
|
||||
|
||||
@@ -304,6 +304,9 @@ void DrawEngineD3D11::Flush() {
|
||||
if (changed & (ClipInfoFlags::DepthClampFragment | ClipInfoFlags::MinMaxZDiscard)) {
|
||||
gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE | DIRTY_FRAGMENTSHADER_STATE | DIRTY_RASTER_STATE);
|
||||
}
|
||||
if (changed & ClipInfoFlags::FlatZ) {
|
||||
gstate_c.Dirty(DIRTY_TEXTURE_PARAMS);
|
||||
}
|
||||
lastClipInfoFlags_ = clipInfoFlags_;
|
||||
}
|
||||
|
||||
@@ -332,7 +335,7 @@ void DrawEngineD3D11::Flush() {
|
||||
|
||||
if (textureNeedsApply) {
|
||||
gstate_c.dstSquared = false;
|
||||
textureCache_->ApplyTexture();
|
||||
textureCache_->ApplyTexture(true, clipInfoFlags_ & ClipInfoFlags::FlatZ);
|
||||
if (gstate_c.dstSquared) {
|
||||
gstate_c.Dirty(DIRTY_BLEND_STATE);
|
||||
}
|
||||
@@ -446,7 +449,7 @@ void DrawEngineD3D11::Flush() {
|
||||
// TODO: This should be after BuildDrawingParams!
|
||||
if (textureNeedsApply) {
|
||||
gstate_c.pixelMapped = result.pixelMapped;
|
||||
textureCache_->ApplyTexture();
|
||||
textureCache_->ApplyTexture(true, clipInfoFlags_ & ClipInfoFlags::FlatZ);
|
||||
gstate_c.pixelMapped = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -245,7 +245,7 @@ void TextureCacheD3D11::UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBa
|
||||
clutLastFormat_ = gstate.clutformat;
|
||||
}
|
||||
|
||||
void TextureCacheD3D11::BindTexture(TexCacheEntry *entry) {
|
||||
void TextureCacheD3D11::BindTexture(TexCacheEntry *entry, bool flatZ) {
|
||||
if (!entry) {
|
||||
ID3D11ShaderResourceView *textureView = nullptr;
|
||||
context_->PSSetShaderResources(0, 1, &textureView);
|
||||
@@ -257,7 +257,7 @@ void TextureCacheD3D11::BindTexture(TexCacheEntry *entry) {
|
||||
lastBoundTexture_ = textureView;
|
||||
}
|
||||
int maxLevel = (entry->status & TexCacheEntry::STATUS_NO_MIPS) ? 0 : entry->maxLevel;
|
||||
SamplerCacheKey samplerKey = GetSamplingParams(maxLevel, entry);
|
||||
SamplerCacheKey samplerKey = GetSamplingParams(maxLevel, entry, flatZ);
|
||||
ComPtr<ID3D11SamplerState> state;
|
||||
samplerCache_.GetOrCreateSampler(device_, samplerKey, &state);
|
||||
context_->PSSetSamplers(0, 1, state.GetAddressOf());
|
||||
@@ -499,7 +499,7 @@ bool TextureCacheD3D11::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level
|
||||
|
||||
// Apply texture may need to rebuild the texture if we're about to render, or bind a framebuffer.
|
||||
TexCacheEntry *entry = nextTexture_;
|
||||
ApplyTexture();
|
||||
ApplyTexture(true, false);
|
||||
|
||||
ID3D11Texture2D *texture = (ID3D11Texture2D *)entry->texturePtr;
|
||||
if (!texture)
|
||||
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
void DestroyDeviceObjects();
|
||||
|
||||
protected:
|
||||
void BindTexture(TexCacheEntry *entry) override;
|
||||
void BindTexture(TexCacheEntry *entry, bool flatZ) override;
|
||||
void Unbind() override;
|
||||
void ReleaseTexture(TexCacheEntry *entry, bool delete_them) override;
|
||||
void BindAsClutTexture(Draw::Texture *tex, bool smooth) override;
|
||||
|
||||
@@ -264,6 +264,9 @@ void DrawEngineGLES::Flush() {
|
||||
if (changed & (ClipInfoFlags::DepthClampFragment | ClipInfoFlags::MinMaxZDiscard)) {
|
||||
gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE | DIRTY_FRAGMENTSHADER_STATE | DIRTY_RASTER_STATE);
|
||||
}
|
||||
if (changed & ClipInfoFlags::FlatZ) {
|
||||
gstate_c.Dirty(DIRTY_TEXTURE_PARAMS);
|
||||
}
|
||||
lastClipInfoFlags_ = clipInfoFlags_;
|
||||
}
|
||||
|
||||
@@ -317,7 +320,7 @@ void DrawEngineGLES::Flush() {
|
||||
}
|
||||
|
||||
if (textureNeedsApply) {
|
||||
textureCache_->ApplyTexture();
|
||||
textureCache_->ApplyTexture(true, clipInfoFlags_ & ClipInfoFlags::FlatZ);
|
||||
}
|
||||
|
||||
// Need to ApplyDrawState after ApplyTexture because depal can launch a render pass and that wrecks the state.
|
||||
@@ -398,7 +401,7 @@ void DrawEngineGLES::Flush() {
|
||||
if (textureNeedsApply) {
|
||||
gstate_c.pixelMapped = result.pixelMapped;
|
||||
gstate_c.dstSquared = false;
|
||||
textureCache_->ApplyTexture();
|
||||
textureCache_->ApplyTexture(true, clipInfoFlags_ & ClipInfoFlags::FlatZ);
|
||||
if (gstate_c.dstSquared) {
|
||||
gstate_c.Dirty(DIRTY_BLEND_STATE);
|
||||
}
|
||||
|
||||
@@ -191,7 +191,7 @@ void TextureCacheGLES::UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBas
|
||||
clutLastFormat_ = gstate.clutformat;
|
||||
}
|
||||
|
||||
void TextureCacheGLES::BindTexture(TexCacheEntry *entry) {
|
||||
void TextureCacheGLES::BindTexture(TexCacheEntry *entry, bool flatZ) {
|
||||
if (!entry) {
|
||||
render_->BindTexture(0, nullptr);
|
||||
lastBoundTexture = nullptr;
|
||||
@@ -202,7 +202,7 @@ void TextureCacheGLES::BindTexture(TexCacheEntry *entry) {
|
||||
lastBoundTexture = entry->textureName;
|
||||
}
|
||||
int maxLevel = (entry->status & TexCacheEntry::STATUS_NO_MIPS) ? 0 : entry->maxLevel;
|
||||
SamplerCacheKey samplerKey = GetSamplingParams(maxLevel, entry);
|
||||
SamplerCacheKey samplerKey = GetSamplingParams(maxLevel, entry, flatZ);
|
||||
ApplySamplingParams(samplerKey);
|
||||
gstate_c.SetUseShaderDepal(ShaderDepalMode::OFF);
|
||||
}
|
||||
@@ -388,7 +388,7 @@ bool TextureCacheGLES::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level,
|
||||
TexCacheEntry *entry = nextTexture_;
|
||||
// We might need a render pass to set the sampling params, unfortunately. Otherwise BuildTexture may crash.
|
||||
framebufferManagerGL_->RebindFramebuffer("RebindFramebuffer - GetCurrentTextureDebug");
|
||||
ApplyTexture(false);
|
||||
ApplyTexture(false, false);
|
||||
|
||||
GLRenderManager *renderManager = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ public:
|
||||
void DeviceRestore(Draw::DrawContext *draw) override;
|
||||
|
||||
protected:
|
||||
void BindTexture(TexCacheEntry *entry) override;
|
||||
void BindTexture(TexCacheEntry *entry, bool flatZ) override;
|
||||
void Unbind() override;
|
||||
void ReleaseTexture(TexCacheEntry *entry, bool delete_them) override;
|
||||
|
||||
|
||||
+1
-1
@@ -573,7 +573,7 @@ u32 GPUCommonHW::CheckGPUFeatures() const {
|
||||
if (draw_->GetDeviceCaps().logicOpSupported) {
|
||||
features |= GPU_USE_LOGIC_OP;
|
||||
}
|
||||
if (draw_->GetDeviceCaps().anisoSupported) {
|
||||
if (draw_->GetDeviceCaps().anisoSupported && g_Config.iAnisotropyLevel > 0) {
|
||||
features |= GPU_USE_ANISOTROPY;
|
||||
}
|
||||
if (draw_->GetDeviceCaps().dualSourceBlend) {
|
||||
|
||||
@@ -196,6 +196,7 @@ enum {
|
||||
};
|
||||
|
||||
enum class ClipInfoFlags {
|
||||
Empty = 0,
|
||||
Valid = 1,
|
||||
SoftClipCull = 2,
|
||||
FlatZ = 4,
|
||||
|
||||
+3
-9
@@ -176,15 +176,9 @@ void GPUgstate::FastLoadBoneMatrix(u32 addr) {
|
||||
__m128i row1 = _mm_slli_epi32(_mm_loadu_si128((const __m128i *)src), 8);
|
||||
__m128i row2 = _mm_slli_epi32(_mm_loadu_si128((const __m128i *)(src + 4)), 8);
|
||||
__m128i row3 = _mm_slli_epi32(_mm_loadu_si128((const __m128i *)(src + 8)), 8);
|
||||
if ((num & 0x3) == 0) {
|
||||
_mm_store_si128((__m128i *)dst, row1);
|
||||
_mm_store_si128((__m128i *)(dst + 4), row2);
|
||||
_mm_store_si128((__m128i *)(dst + 8), row3);
|
||||
} else {
|
||||
_mm_storeu_si128((__m128i *)dst, row1);
|
||||
_mm_storeu_si128((__m128i *)(dst + 4), row2);
|
||||
_mm_storeu_si128((__m128i *)(dst + 8), row3);
|
||||
}
|
||||
_mm_storeu_si128((__m128i *)dst, row1);
|
||||
_mm_storeu_si128((__m128i *)(dst + 4), row2);
|
||||
_mm_storeu_si128((__m128i *)(dst + 8), row3);
|
||||
#elif PPSSPP_ARCH(ARM_NEON)
|
||||
const uint32x4_t row1 = vshlq_n_u32(vld1q_u32(src), 8);
|
||||
const uint32x4_t row2 = vshlq_n_u32(vld1q_u32(src + 4), 8);
|
||||
|
||||
@@ -251,6 +251,9 @@ void DrawEngineVulkan::Flush() {
|
||||
if (changed & (ClipInfoFlags::DepthClampFragment | ClipInfoFlags::MinMaxZDiscard)) {
|
||||
gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE | DIRTY_FRAGMENTSHADER_STATE | DIRTY_RASTER_STATE);
|
||||
}
|
||||
if (changed & ClipInfoFlags::FlatZ) {
|
||||
gstate_c.Dirty(DIRTY_TEXTURE_PARAMS);
|
||||
}
|
||||
lastClipInfoFlags_ = clipInfoFlags_;
|
||||
}
|
||||
|
||||
@@ -297,8 +300,8 @@ void DrawEngineVulkan::Flush() {
|
||||
gstate_c.vertexFullAlpha = gstate_c.vertexFullAlpha && ((hasColor && (gstate.materialupdate & 1)) || gstate.getMaterialAmbientA() == 255) && (!gstate.isLightingEnabled() || gstate.getAmbientA() == 255);
|
||||
}
|
||||
|
||||
if (textureNeedsApply || true) {
|
||||
textureCache_->ApplyTexture();
|
||||
if (textureNeedsApply) {
|
||||
textureCache_->ApplyTexture(true, clipInfoFlags_ & ClipInfoFlags::FlatZ);
|
||||
textureCache_->GetVulkanHandles(imageView, sampler);
|
||||
if (imageView == VK_NULL_HANDLE)
|
||||
imageView = (VkImageView)draw_->GetNativeObject(gstate_c.textureIsArray ? Draw::NativeObject::NULL_IMAGEVIEW_ARRAY : Draw::NativeObject::NULL_IMAGEVIEW);
|
||||
@@ -462,7 +465,7 @@ void DrawEngineVulkan::Flush() {
|
||||
if (textureNeedsApply) {
|
||||
gstate_c.pixelMapped = result.pixelMapped;
|
||||
gstate_c.dstSquared = false;
|
||||
textureCache_->ApplyTexture();
|
||||
textureCache_->ApplyTexture(true, clipInfoFlags_ & ClipInfoFlags::FlatZ);
|
||||
gstate_c.pixelMapped = false;
|
||||
textureCache_->GetVulkanHandles(imageView, sampler);
|
||||
if (imageView == VK_NULL_HANDLE)
|
||||
|
||||
@@ -632,14 +632,14 @@ void TextureCacheVulkan::UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutB
|
||||
clutLastFormat_ = gstate.clutformat;
|
||||
}
|
||||
|
||||
void TextureCacheVulkan::BindTexture(TexCacheEntry *entry) {
|
||||
void TextureCacheVulkan::BindTexture(TexCacheEntry *entry, bool flatZ) {
|
||||
if (!entry || !entry->vkTex) {
|
||||
Unbind();
|
||||
return;
|
||||
}
|
||||
|
||||
int maxLevel = (entry->status & TexCacheEntry::STATUS_NO_MIPS) ? 0 : entry->maxLevel;
|
||||
SamplerCacheKey samplerKey = GetSamplingParams(maxLevel, entry);
|
||||
SamplerCacheKey samplerKey = GetSamplingParams(maxLevel, entry, flatZ);
|
||||
curSampler_ = samplerCache_.GetOrCreateSampler(samplerKey);
|
||||
imageView_ = entry->vkTex->GetImageView();
|
||||
drawEngine_->SetDepalTexture(VK_NULL_HANDLE, false);
|
||||
@@ -1060,7 +1060,7 @@ bool TextureCacheVulkan::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int leve
|
||||
|
||||
// Apply texture may need to rebuild the texture if we're about to render, or bind a framebuffer.
|
||||
TexCacheEntry *entry = nextTexture_;
|
||||
ApplyTexture();
|
||||
ApplyTexture(true, false);
|
||||
|
||||
if (!entry->vkTex)
|
||||
return false;
|
||||
|
||||
@@ -85,7 +85,7 @@ public:
|
||||
void *GetNativeTextureView(const TexCacheEntry *entry, bool flat) const override;
|
||||
|
||||
protected:
|
||||
void BindTexture(TexCacheEntry *entry) override;
|
||||
void BindTexture(TexCacheEntry *entry, bool flatZ) override;
|
||||
void Unbind() override;
|
||||
void ReleaseTexture(TexCacheEntry *entry, bool delete_them) override;
|
||||
void BindAsClutTexture(Draw::Texture *tex, bool smooth) override;
|
||||
|
||||
@@ -619,9 +619,13 @@ void GameSettingsScreen::CreateGraphicsSettings(UI::ViewGroup *graphicsSettings)
|
||||
graphicsSettings->Add(new SettingHint(gr->T("Deposterize Tip", "Fixes visual banding glitches in upscaled textures"), deposterize));
|
||||
|
||||
graphicsSettings->Add(new ItemHeader(gr->T("Texture Filtering")));
|
||||
|
||||
static const char *anisoLevels[] = { "Off", "2x", "4x", "8x", "16x" };
|
||||
PopupMultiChoice *anisoFiltering = graphicsSettings->Add(new PopupMultiChoice(&g_Config.iAnisotropyLevel, gr->T("Anisotropic Filtering"), anisoLevels, 0, ARRAY_SIZE(anisoLevels), I18NCat::GRAPHICS, screenManager()));
|
||||
anisoFiltering->SetDisabledPtr(&g_Config.bSoftwareRendering);
|
||||
anisoFiltering->OnChoice.Add([](UI::EventParams &e) {
|
||||
System_PostUIMessage(UIMessage::GPU_CONFIG_CHANGED);
|
||||
});
|
||||
|
||||
static const char *texFilters[] = { "Auto", "Nearest", "Linear", "Auto Max Quality"};
|
||||
PopupMultiChoice *filters = graphicsSettings->Add(new PopupMultiChoice(&g_Config.iTexFiltering, gr->T("Texture Filter"), texFilters, 1, ARRAY_SIZE(texFilters), I18NCat::GRAPHICS, screenManager()));
|
||||
|
||||
@@ -1344,7 +1344,7 @@ void ImGeDebuggerWindow::Draw(ImConfig &cfg, ImControl &control, GPUCommon *gpuD
|
||||
TexCacheEntry *tex = texcache ? texcache->SetTexture() : nullptr;
|
||||
if (tex) {
|
||||
ImGui::Text("Texture: %08x", tex->addr);
|
||||
texcache->ApplyTexture(false);
|
||||
texcache->ApplyTexture(false, false);
|
||||
|
||||
void *nativeView = texcache->GetNativeTextureView(tex, true);
|
||||
ImTextureID texId = ImGui_ImplThin3d_AddNativeTextureTemp(nativeView);
|
||||
|
||||
Reference in New Issue
Block a user