diff --git a/GPU/D3D11/TextureCacheD3D11.cpp b/GPU/D3D11/TextureCacheD3D11.cpp index c669b42d7e..1b280be4cf 100644 --- a/GPU/D3D11/TextureCacheD3D11.cpp +++ b/GPU/D3D11/TextureCacheD3D11.cpp @@ -318,6 +318,10 @@ void TextureCacheD3D11::BindTexture(TexCacheEntry *entry) { context_->PSSetShaderResources(0, 1, &textureView); lastBoundTexture = textureView; } + SamplerCacheKey key; + UpdateSamplingParams(*entry, key); + ID3D11SamplerState *state = samplerCache_.GetOrCreateSampler(device_, key); + context_->PSSetSamplers(0, 1, &state); } void TextureCacheD3D11::Unbind() { @@ -328,6 +332,7 @@ void TextureCacheD3D11::Unbind() { void TextureCacheD3D11::ApplyTexture() { TexCacheEntry *entry = nextTexture_; if (entry == nullptr) { + // Unbind? return; } nextTexture_ = nullptr; @@ -372,10 +377,6 @@ void TextureCacheD3D11::ApplyTexture() { ApplyTextureFramebuffer(entry, entry->framebuffer); } else { BindTexture(entry); - SamplerCacheKey key; - UpdateSamplingParams(*entry, key); - ID3D11SamplerState *state = samplerCache_.GetOrCreateSampler(device_, key); - context_->PSSetSamplers(0, 1, &state); gstate_c.textureFullAlpha = entry->GetAlphaStatus() == TexCacheEntry::STATUS_ALPHA_FULL; gstate_c.textureSimpleAlpha = entry->GetAlphaStatus() != TexCacheEntry::STATUS_ALPHA_UNKNOWN; } diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index 572425f8f7..e145ae5708 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -338,6 +338,7 @@ void TextureCacheDX9::BindTexture(TexCacheEntry *entry) { pD3Ddevice->SetTexture(0, texture); lastBoundTexture = texture; } + UpdateSamplingParams(*entry, false); } void TextureCacheDX9::Unbind() { @@ -391,8 +392,6 @@ void TextureCacheDX9::ApplyTexture() { ApplyTextureFramebuffer(entry, entry->framebuffer); } else { BindTexture(entry); - UpdateSamplingParams(*entry, false); - gstate_c.textureFullAlpha = entry->GetAlphaStatus() == TexCacheEntry::STATUS_ALPHA_FULL; gstate_c.textureSimpleAlpha = entry->GetAlphaStatus() != TexCacheEntry::STATUS_ALPHA_UNKNOWN; } diff --git a/GPU/GLES/TextureCacheGLES.cpp b/GPU/GLES/TextureCacheGLES.cpp index c79401742c..6c3684b9a6 100644 --- a/GPU/GLES/TextureCacheGLES.cpp +++ b/GPU/GLES/TextureCacheGLES.cpp @@ -390,6 +390,7 @@ void TextureCacheGLES::BindTexture(TexCacheEntry *entry) { glBindTexture(GL_TEXTURE_2D, entry->textureName); lastBoundTexture = entry->textureName; } + UpdateSamplingParams(*entry, false); } void TextureCacheGLES::Unbind() { @@ -442,8 +443,6 @@ void TextureCacheGLES::ApplyTexture() { ApplyTextureFramebuffer(entry, entry->framebuffer); } else { BindTexture(entry); - UpdateSamplingParams(*entry, false); - gstate_c.textureFullAlpha = entry->GetAlphaStatus() == TexCacheEntry::STATUS_ALPHA_FULL; gstate_c.textureSimpleAlpha = entry->GetAlphaStatus() != TexCacheEntry::STATUS_ALPHA_UNKNOWN; } diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index 4db14a367c..868bacb592 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -668,7 +668,8 @@ void DrawEngineVulkan::DoFlush(VkCommandBuffer cmd) { } if (textureNeedsApply) { - textureCache_->ApplyTexture(imageView, sampler); + textureCache_->ApplyTexture(); + textureCache_->GetVulkanHandles(imageView, sampler); if (imageView == VK_NULL_HANDLE) imageView = nullTexture_->GetImageView(); if (sampler == VK_NULL_HANDLE) @@ -768,7 +769,8 @@ void DrawEngineVulkan::DoFlush(VkCommandBuffer cmd) { // to use a "pre-clear" render pass, for high efficiency on tilers. if (result.action == SW_DRAW_PRIMITIVES) { if (textureNeedsApply) { - textureCache_->ApplyTexture(imageView, sampler); + textureCache_->ApplyTexture(); + textureCache_->GetVulkanHandles(imageView, sampler); if (imageView == VK_NULL_HANDLE) imageView = nullTexture_->GetImageView(); if (sampler == VK_NULL_HANDLE) diff --git a/GPU/Vulkan/DrawEngineVulkan.h b/GPU/Vulkan/DrawEngineVulkan.h index f94d61f93f..cd77564093 100644 --- a/GPU/Vulkan/DrawEngineVulkan.h +++ b/GPU/Vulkan/DrawEngineVulkan.h @@ -123,7 +123,7 @@ public: void DirtyAllUBOs(); VulkanPushBuffer *GetPushBufferForTextureData() { - return frame_[curFrame_].pushUBO; + return frame_[curFrame_ & 1].pushUBO; } const DrawEngineVulkanStats &GetStats() const { diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index 4c6e0138fe..0de9df3e0c 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -398,17 +398,27 @@ void TextureCacheVulkan::UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutB } void TextureCacheVulkan::BindTexture(TexCacheEntry *entry) { + if (!entry || !entry->vkTex) { + imageView_ = VK_NULL_HANDLE; + sampler_ = VK_NULL_HANDLE; + return; + } + imageView_ = entry->vkTex->texture_->GetImageView(); + SamplerCacheKey key; + UpdateSamplingParams(*entry, key); + sampler_ = samplerCache_.GetOrCreateSampler(key); } void TextureCacheVulkan::Unbind() { + imageView_ = VK_NULL_HANDLE; + sampler_ = VK_NULL_HANDLE; } -void TextureCacheVulkan::ApplyTexture(VkImageView &imageView, VkSampler &sampler) { +void TextureCacheVulkan::ApplyTexture() { TexCacheEntry *entry = nextTexture_; if (entry == nullptr) { - imageView = VK_NULL_HANDLE; - sampler = VK_NULL_HANDLE; + // Unbind(); return; } nextTexture_ = nullptr; @@ -448,27 +458,18 @@ void TextureCacheVulkan::ApplyTexture(VkImageView &imageView, VkSampler &sampler } entry->lastFrame = gpuStats.numFlips; - VkCommandBuffer cmd = nullptr; if (entry->framebuffer) { - ApplyTextureFramebuffer(cmd, entry, entry->framebuffer, imageView, sampler); - } else if (entry->vkTex) { - imageView = entry->vkTex->texture_->GetImageView(); - - SamplerCacheKey key; - UpdateSamplingParams(*entry, key); - sampler = samplerCache_.GetOrCreateSampler(key); - + ApplyTextureFramebuffer(entry, entry->framebuffer); + } else { + BindTexture(entry); gstate_c.textureFullAlpha = entry->GetAlphaStatus() == TexCacheEntry::STATUS_ALPHA_FULL; gstate_c.textureSimpleAlpha = entry->GetAlphaStatus() != TexCacheEntry::STATUS_ALPHA_UNKNOWN; lastBoundTexture = entry->vkTex; - } else { - imageView = VK_NULL_HANDLE; - sampler = VK_NULL_HANDLE; } } -void TextureCacheVulkan::ApplyTextureFramebuffer(VkCommandBuffer cmd, TexCacheEntry *entry, VirtualFramebuffer *framebuffer, VkImageView &imageView, VkSampler &sampler) { +void TextureCacheVulkan::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer) { DepalShaderVulkan *depal = nullptr; const GEPaletteFormat clutFormat = gstate.getClutPaletteFormat(); if ((entry->status & TexCacheEntry::STATUS_DEPALETTIZE) && !g_Config.bDisableSlowFramebufEffects) { @@ -574,7 +575,7 @@ void TextureCacheVulkan::ApplyTextureFramebuffer(VkCommandBuffer cmd, TexCacheEn SamplerCacheKey key; UpdateSamplingParams(*entry, key); key.mipEnable = false; - sampler = samplerCache_.GetOrCreateSampler(key); + sampler_ = samplerCache_.GetOrCreateSampler(key); lastBoundTexture = nullptr; } diff --git a/GPU/Vulkan/TextureCacheVulkan.h b/GPU/Vulkan/TextureCacheVulkan.h index c7163516f2..4014a04498 100644 --- a/GPU/Vulkan/TextureCacheVulkan.h +++ b/GPU/Vulkan/TextureCacheVulkan.h @@ -90,7 +90,11 @@ public: gstate_c.Dirty(DIRTY_TEXTURE_PARAMS); } - void ApplyTexture(VkImageView &imageView, VkSampler &sampler); + void ApplyTexture(); + void GetVulkanHandles(VkImageView &imageView, VkSampler &sampler) { + imageView = imageView_; + sampler = sampler_; + } protected: void BindTexture(TexCacheEntry *entry) override; @@ -105,7 +109,7 @@ private: VkFormat GetDestFormat(GETextureFormat format, GEPaletteFormat clutFormat) const; TexCacheEntry::Status CheckAlpha(const u32 *pixelData, VkFormat dstFmt, int stride, int w, int h); void UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBase, bool clutIndexIsSimple); - void ApplyTextureFramebuffer(VkCommandBuffer cmd, TexCacheEntry *entry, VirtualFramebuffer *framebuffer, VkImageView &image, VkSampler &sampler); + void ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer); void SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, SamplerCacheKey &key); bool CheckFullHash(TexCacheEntry *const entry, bool &doDelete); @@ -129,6 +133,10 @@ private: DepalShaderCacheVulkan *depalShaderCache_; ShaderManagerVulkan *shaderManagerVulkan_; DrawEngineVulkan *drawEngine_; + + // Bound state to emulate an API similar to the others + VkImageView imageView_ = VK_NULL_HANDLE; + VkSampler sampler_ = VK_NULL_HANDLE; }; VkFormat getClutDestFormatVulkan(GEPaletteFormat format);