From f745e9489974e64d458765300f82749782ca1ff9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 14 Sep 2022 00:13:29 +0200 Subject: [PATCH] Allow binding "native" texture objects to thin3d --- Common/GPU/D3D11/thin3d_d3d11.cpp | 7 +++++++ Common/GPU/D3D9/thin3d_d3d9.cpp | 7 +++++++ Common/GPU/OpenGL/thin3d_gl.cpp | 6 ++++++ Common/GPU/Vulkan/thin3d_vulkan.cpp | 6 ++++++ Common/GPU/thin3d.h | 7 +++++++ GPU/Common/TextureCacheCommon.cpp | 2 +- 6 files changed, 34 insertions(+), 1 deletion(-) diff --git a/Common/GPU/D3D11/thin3d_d3d11.cpp b/Common/GPU/D3D11/thin3d_d3d11.cpp index 99e2eb2577..c17bb39919 100644 --- a/Common/GPU/D3D11/thin3d_d3d11.cpp +++ b/Common/GPU/D3D11/thin3d_d3d11.cpp @@ -105,6 +105,7 @@ public: void InvalidateCachedState() override; void BindTextures(int start, int count, Texture **textures) override; + void BindNativeTexture(int index, void *nativeTexture) override; void BindSamplerStates(int start, int count, SamplerState **states) override; void BindVertexBuffers(int start, int count, Buffer **buffers, const int *offsets) override; void BindIndexBuffer(Buffer *indexBuffer, int offset) override; @@ -1389,6 +1390,12 @@ void D3D11DrawContext::BindTextures(int start, int count, Texture **textures) { context_->PSSetShaderResources(start, count, views); } +void D3D11DrawContext::BindNativeTexture(int index, void *nativeTexture) { + // Collect the resource views from the textures. + ID3D11ShaderResourceView *view = (ID3D11ShaderResourceView *)nativeTexture; + context_->PSSetShaderResources(index, 1, &view); +} + void D3D11DrawContext::BindSamplerStates(int start, int count, SamplerState **states) { ID3D11SamplerState *samplers[MAX_BOUND_TEXTURES]; _assert_(start + count <= ARRAY_SIZE(samplers)); diff --git a/Common/GPU/D3D9/thin3d_d3d9.cpp b/Common/GPU/D3D9/thin3d_d3d9.cpp index 9bfe824c09..c47d8235a1 100644 --- a/Common/GPU/D3D9/thin3d_d3d9.cpp +++ b/Common/GPU/D3D9/thin3d_d3d9.cpp @@ -521,6 +521,8 @@ public: void GetFramebufferDimensions(Framebuffer *fbo, int *w, int *h) override; void BindTextures(int start, int count, Texture **textures) override; + void BindNativeTexture(int index, void *nativeTexture) override; + void BindSamplerStates(int start, int count, SamplerState **states) override { _assert_(start + count <= MAX_BOUND_TEXTURES); for (int i = 0; i < count; ++i) { @@ -814,6 +816,11 @@ void D3D9Context::BindTextures(int start, int count, Texture **textures) { } } +void D3D9Context::BindNativeTexture(int index, void *nativeTexture) { + LPDIRECT3DTEXTURE9 texture = (LPDIRECT3DTEXTURE9)nativeTexture; + device_->SetTexture(index, texture); +} + void D3D9Context::EndFrame() { curPipeline_ = nullptr; } diff --git a/Common/GPU/OpenGL/thin3d_gl.cpp b/Common/GPU/OpenGL/thin3d_gl.cpp index 2e93fc8791..908a764ecc 100644 --- a/Common/GPU/OpenGL/thin3d_gl.cpp +++ b/Common/GPU/OpenGL/thin3d_gl.cpp @@ -401,6 +401,8 @@ public: } void BindTextures(int start, int count, Texture **textures) override; + void BindNativeTexture(int sampler, void *nativeTexture) override; + void BindPipeline(Pipeline *pipeline) override; void BindVertexBuffers(int start, int count, Buffer **buffers, const int *offsets) override { _assert_(start + count <= ARRAY_SIZE(curVBuffers_)); @@ -1138,6 +1140,10 @@ void OpenGLContext::BindTextures(int start, int count, Texture **textures) { } } +void OpenGLContext::BindNativeTexture(int index, void *nativeTexture) { + boundTextures_[index] = (GLRTexture *)nativeTexture; +} + void OpenGLContext::ApplySamplers() { for (int i = 0; i < MAX_TEXTURE_SLOTS; i++) { const OpenGLSamplerState *samp = boundSamplers_[i]; diff --git a/Common/GPU/Vulkan/thin3d_vulkan.cpp b/Common/GPU/Vulkan/thin3d_vulkan.cpp index c836b41499..8420c01450 100644 --- a/Common/GPU/Vulkan/thin3d_vulkan.cpp +++ b/Common/GPU/Vulkan/thin3d_vulkan.cpp @@ -414,6 +414,7 @@ public: void BindSamplerStates(int start, int count, SamplerState **state) override; void BindTextures(int start, int count, Texture **textures) override; + void BindNativeTexture(int sampler, void *nativeTexture) override; void BindPipeline(Pipeline *pipeline) override { curPipeline_ = (VKPipeline *)pipeline; @@ -1292,6 +1293,11 @@ void VKContext::BindTextures(int start, int count, Texture **textures) { } } +void VKContext::BindNativeTexture(int sampler, void *nativeTexture) { + boundTextures_[sampler] = nullptr; + boundImageView_[sampler] = (VkImageView)nativeTexture; +} + ShaderModule *VKContext::CreateShaderModule(ShaderStage stage, ShaderLanguage language, const uint8_t *data, size_t size, const char *tag) { VKShaderModule *shader = new VKShaderModule(stage, tag); if (shader->Compile(vulkan_, language, data, size)) { diff --git a/Common/GPU/thin3d.h b/Common/GPU/thin3d.h index 46b6305fd9..843e6e8813 100644 --- a/Common/GPU/thin3d.h +++ b/Common/GPU/thin3d.h @@ -675,6 +675,13 @@ public: virtual void BindVertexBuffers(int start, int count, Buffer **buffers, const int *offsets) = 0; virtual void BindIndexBuffer(Buffer *indexBuffer, int offset) = 0; + // Sometimes it's necessary to bind a texture not created by thin3d, and use with a thin3d pipeline. + // Not pretty, and one way in the future could be to create all textures through thin3d. + // Data types: + // * Vulkan: VkImageView + // * D3D11: ID3D11ShaderResourceView* + virtual void BindNativeTexture(int sampler, void *nativeTexture) = 0; + // Only supports a single dynamic uniform buffer, for maximum compatibility with the old APIs and ease of emulation. // More modern methods will be added later. virtual void UpdateDynamicUniformBuffer(const void *ub, size_t size) = 0; diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 22fcedca98..ca83804954 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -2163,7 +2163,7 @@ void TextureCacheCommon::ApplyTextureDepal(TexCacheEntry *entry) { Draw::Viewport vp{ 0.0f, 0.0f, (float)texWidth, (float)texHeight, 0.0f, 1.0f }; draw_->SetViewports(1, &vp); - draw_->BindTexture(0, framebuffer->fbo); + draw_->BindNativeTexture(0, framebuffer->fbo); draw_->BindFramebufferAsTexture(clutFbo, 1, Draw::FB_COLOR_BIT, 0); Draw::SamplerState *nearest = textureShaderCache_->GetSampler(false); Draw::SamplerState *clutSampler = textureShaderCache_->GetSampler(false);