Fix smoothed depal on GLES. Don't enable filtering if not using.

This commit is contained in:
Henrik Rydgård 2022-08-24 09:31:47 +02:00
parent 586da08820
commit b529d26f3a
14 changed files with 37 additions and 27 deletions

View File

@ -181,6 +181,7 @@ std::string FragmentShaderDesc(const FShaderID &id) {
if (id.Bit(FS_BIT_FLATSHADE)) desc << "Flat ";
if (id.Bit(FS_BIT_BGRA_TEXTURE)) desc << "BGRA ";
if (id.Bit(FS_BIT_SHADER_DEPAL)) desc << "Depal ";
if (id.Bit(FS_BIT_SHADER_SMOOTHED_DEPAL)) desc << "SmoothDepal ";
if (id.Bit(FS_BIT_COLOR_WRITEMASK)) desc << "WriteMask ";
if (id.Bit(FS_BIT_SHADER_TEX_CLAMP)) {
desc << "TClamp";

View File

@ -1866,7 +1866,7 @@ bool CanDepalettize(GETextureFormat texFormat, GEBufferFormat bufferFormat) {
// Great enhancement for Test Drive.
static bool CanUseSmoothDepal(const GPUgstate &gstate, GEBufferFormat framebufferFormat, int rampLength) {
if (gstate.getClutIndexStartPos() == 0 &&
gstate.getClutIndexMask() <= rampLength) {
gstate.getClutIndexMask() < rampLength) {
switch (framebufferFormat) {
case GE_FORMAT_565:
if (gstate.getClutIndexShift() == 0 || gstate.getClutIndexShift() == 11) {
@ -1918,7 +1918,7 @@ void TextureCacheCommon::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer
if (useShaderDepal) {
// Very icky conflation here of native and thin3d rendering. This will need careful work per backend in BindAsClutTexture.
BindAsClutTexture(clutTexture.texture);
BindAsClutTexture(clutTexture.texture, smoothedDepal);
framebufferManager_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_MAY_COPY_WITH_UV | BINDFBCOLOR_APPLY_TEX_OFFSET);
// Vulkan needs to do some extra work here to pick out the native handle from Draw.

View File

@ -334,7 +334,7 @@ protected:
virtual void UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBase, bool clutIndexIsSimple) = 0;
bool CheckFullHash(TexCacheEntry *entry, bool &doDelete);
virtual void BindAsClutTexture(Draw::Texture *tex) {}
virtual void BindAsClutTexture(Draw::Texture *tex, bool smooth) {}
CheckAlphaResult DecodeTextureLevel(u8 *out, int outPitch, GETextureFormat format, GEPaletteFormat clutformat, uint32_t texaddr, int level, int bufw, bool reverseColors, bool expandTo32Bit);
void UnswizzleFromMem(u32 *dest, u32 destPitch, const u8 *texptr, u32 bufw, u32 height, u32 bytesPerPixel);

View File

@ -105,7 +105,7 @@ ClutTexture TextureShaderCache::GetClutTexture(GEPaletteFormat clutFormat, const
// Quick check for how many continouosly growing entries we have at the start.
// Bilinearly filtering CLUTs only really makes sense for this kind of ramp.
for (int i = 0; i < maxClutEntries; i++) {
rampLength = i + 1;
rampLength = i;
int r = desc.initData[0][i * 4];
int g = desc.initData[0][i * 4 + 1];
int b = desc.initData[0][i * 4 + 2];

View File

@ -263,10 +263,10 @@ void TextureCacheD3D11::Unbind() {
InvalidateLastTexture();
}
void TextureCacheD3D11::BindAsClutTexture(Draw::Texture *tex) {
void TextureCacheD3D11::BindAsClutTexture(Draw::Texture *tex, bool smooth) {
ID3D11ShaderResourceView *clutTexture = (ID3D11ShaderResourceView *)draw_->GetNativeObject(Draw::NativeObject::TEXTURE_VIEW, tex);
context_->PSSetShaderResources(TEX_SLOT_CLUT, 1, &clutTexture);
context_->PSSetSamplers(3, 1, &stockD3D11.samplerPoint2DWrap);
context_->PSSetSamplers(3, 1, smooth ? &stockD3D11.samplerLinear2DClamp : &stockD3D11.samplerPoint2DClamp);
}
void TextureCacheD3D11::BuildTexture(TexCacheEntry *const entry) {

View File

@ -59,7 +59,7 @@ protected:
void BindTexture(TexCacheEntry *entry) override;
void Unbind() override;
void ReleaseTexture(TexCacheEntry *entry, bool delete_them) override;
void BindAsClutTexture(Draw::Texture *tex) override;
void BindAsClutTexture(Draw::Texture *tex, bool smooth) override;
void ApplySamplingParams(const SamplerCacheKey &key) override;
private:

View File

@ -223,11 +223,11 @@ void TextureCacheDX9::Unbind() {
InvalidateLastTexture();
}
void TextureCacheDX9::BindAsClutTexture(Draw::Texture *tex) {
void TextureCacheDX9::BindAsClutTexture(Draw::Texture *tex, bool smooth) {
LPDIRECT3DBASETEXTURE9 clutTexture = (LPDIRECT3DBASETEXTURE9)draw_->GetNativeObject(Draw::NativeObject::TEXTURE_VIEW, tex);
device_->SetTexture(1, clutTexture);
device_->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_POINT);
device_->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
device_->SetSamplerState(1, D3DSAMP_MINFILTER, smooth ? D3DTEXF_LINEAR : D3DTEXF_POINT);
device_->SetSamplerState(1, D3DSAMP_MAGFILTER, smooth ? D3DTEXF_LINEAR : D3DTEXF_POINT);
device_->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
}

View File

@ -49,7 +49,7 @@ protected:
void BindTexture(TexCacheEntry *entry) override;
void Unbind() override;
void ReleaseTexture(TexCacheEntry *entry, bool delete_them) override;
void BindAsClutTexture(Draw::Texture *tex) override;
void BindAsClutTexture(Draw::Texture *tex, bool smooth) override;
private:
void ApplySamplingParams(const SamplerCacheKey &key) override;

View File

@ -238,10 +238,10 @@ void TextureCacheGLES::Unbind() {
InvalidateLastTexture();
}
void TextureCacheGLES::BindAsClutTexture(Draw::Texture *tex) {
void TextureCacheGLES::BindAsClutTexture(Draw::Texture *tex, bool smooth) {
GLRTexture *glrTex = (GLRTexture *)draw_->GetNativeObject(Draw::NativeObject::TEXTURE_VIEW, tex);
render_->BindTexture(TEX_SLOT_CLUT, glrTex);
render_->SetTextureSampler(TEX_SLOT_CLUT, GL_REPEAT, GL_CLAMP_TO_EDGE, GL_NEAREST, GL_NEAREST, 0.0f);
render_->SetTextureSampler(TEX_SLOT_CLUT, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, smooth ? GL_LINEAR : GL_NEAREST, smooth ? GL_LINEAR : GL_NEAREST, 0.0f);
}
void TextureCacheGLES::BuildTexture(TexCacheEntry *const entry) {

View File

@ -65,7 +65,7 @@ protected:
void Unbind() override;
void ReleaseTexture(TexCacheEntry *entry, bool delete_them) override;
void BindAsClutTexture(Draw::Texture *tex) override;
void BindAsClutTexture(Draw::Texture *tex, bool smooth) override;
private:
void ApplySamplingParams(const SamplerCacheKey &key) override;

View File

@ -183,11 +183,13 @@ void DrawEngineVulkan::InitDeviceObjects() {
samp.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
samp.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
samp.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
samp.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
samp.flags = 0;
samp.magFilter = VK_FILTER_LINEAR;
samp.minFilter = VK_FILTER_LINEAR;
res = vkCreateSampler(device, &samp, nullptr, &samplerSecondary_);
samp.maxLod = VK_LOD_CLAMP_NONE; // recommended by best practices, has no effect since we don't use mipmaps.
res = vkCreateSampler(device, &samp, nullptr, &samplerSecondaryLinear_);
samp.magFilter = VK_FILTER_NEAREST;
samp.minFilter = VK_FILTER_NEAREST;
res = vkCreateSampler(device, &samp, nullptr, &samplerSecondaryNearest_);
_dbg_assert_(VK_SUCCESS == res);
res = vkCreateSampler(device, &samp, nullptr, &nullSampler_);
_dbg_assert_(VK_SUCCESS == res);
@ -235,8 +237,10 @@ void DrawEngineVulkan::DestroyDeviceObjects() {
for (int i = 0; i < VulkanContext::MAX_INFLIGHT_FRAMES; i++) {
frame_[i].Destroy(vulkan);
}
if (samplerSecondary_ != VK_NULL_HANDLE)
vulkan->Delete().QueueDeleteSampler(samplerSecondary_);
if (samplerSecondaryNearest_ != VK_NULL_HANDLE)
vulkan->Delete().QueueDeleteSampler(samplerSecondaryNearest_);
if (samplerSecondaryLinear_ != VK_NULL_HANDLE)
vulkan->Delete().QueueDeleteSampler(samplerSecondaryLinear_);
if (nullSampler_ != VK_NULL_HANDLE)
vulkan->Delete().QueueDeleteSampler(nullSampler_);
if (pipelineLayout_ != VK_NULL_HANDLE)
@ -248,6 +252,7 @@ void DrawEngineVulkan::DestroyDeviceObjects() {
delete vertexCache_;
vertexCache_ = nullptr;
}
// Need to clear this to get rid of all remaining references to the dead buffers.
vai_.Iterate([](uint32_t hash, VertexArrayInfoVulkan *vai) {
delete vai;
@ -411,7 +416,7 @@ VkDescriptorSet DrawEngineVulkan::GetOrCreateDescriptorSet(VkImageView imageView
if (boundSecondary_) {
tex[1].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
tex[1].imageView = boundSecondary_;
tex[1].sampler = samplerSecondary_;
tex[1].sampler = samplerSecondaryNearest_;
writes[n].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writes[n].pNext = nullptr;
writes[n].dstBinding = DRAW_BINDING_2ND_TEXTURE;
@ -425,7 +430,7 @@ VkDescriptorSet DrawEngineVulkan::GetOrCreateDescriptorSet(VkImageView imageView
if (boundDepal_) {
tex[2].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
tex[2].imageView = boundDepal_;
tex[2].sampler = samplerSecondary_; // doesn't matter, we use load
tex[2].sampler = boundDepalSmoothed_ ? samplerSecondaryLinear_ : samplerSecondaryNearest_;
writes[n].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writes[n].pNext = nullptr;
writes[n].dstBinding = DRAW_BINDING_DEPAL_TEXTURE;

View File

@ -182,9 +182,10 @@ public:
return stats_;
}
void SetDepalTexture(VkImageView depal) {
void SetDepalTexture(VkImageView depal, bool smooth) {
if (boundDepal_ != depal) {
boundDepal_ = depal;
boundDepalSmoothed_ = smooth;
gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE);
}
}
@ -217,8 +218,11 @@ private:
// Secondary texture for shader blending
VkImageView boundSecondary_ = VK_NULL_HANDLE;
// CLUT texture for shader depal
VkImageView boundDepal_ = VK_NULL_HANDLE;
VkSampler samplerSecondary_ = VK_NULL_HANDLE; // This one is actually never used since we use fetch (except in SmoothedDepal mode for Test Drive).
bool boundDepalSmoothed_ = false;
VkSampler samplerSecondaryLinear_ = VK_NULL_HANDLE;
VkSampler samplerSecondaryNearest_ = VK_NULL_HANDLE;
PrehashMap<VertexArrayInfoVulkan *, nullptr> vai_;
VulkanPushBuffer *vertexCache_;

View File

@ -402,7 +402,7 @@ void TextureCacheVulkan::BindTexture(TexCacheEntry *entry) {
SamplerCacheKey samplerKey = GetSamplingParams(maxLevel, entry);
curSampler_ = samplerCache_.GetOrCreateSampler(samplerKey);
imageView_ = entry->vkTex->GetImageView();
drawEngine_->SetDepalTexture(VK_NULL_HANDLE);
drawEngine_->SetDepalTexture(VK_NULL_HANDLE, false);
gstate_c.SetUseShaderDepal(false, false);
}
@ -416,9 +416,9 @@ void TextureCacheVulkan::Unbind() {
InvalidateLastTexture();
}
void TextureCacheVulkan::BindAsClutTexture(Draw::Texture *tex) {
void TextureCacheVulkan::BindAsClutTexture(Draw::Texture *tex, bool smooth) {
VkImageView clutTexture = (VkImageView)draw_->GetNativeObject(Draw::NativeObject::TEXTURE_VIEW, tex);
drawEngine_->SetDepalTexture(clutTexture);
drawEngine_->SetDepalTexture(clutTexture, smooth);
}
static Draw::DataFormat FromVulkanFormat(VkFormat fmt) {

View File

@ -94,7 +94,7 @@ protected:
void BindTexture(TexCacheEntry *entry) override;
void Unbind() override;
void ReleaseTexture(TexCacheEntry *entry, bool delete_them) override;
void BindAsClutTexture(Draw::Texture *tex) override;
void BindAsClutTexture(Draw::Texture *tex, bool smooth) override;
void ApplySamplingParams(const SamplerCacheKey &key) override;
void BoundFramebufferTexture() override;