mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-13 07:57:58 +00:00
- store the Vulkan descriptor sets in the material - where they belong!
Having them in the base texture object was a major maintenance issue.
This commit is contained in:
parent
46e75e8107
commit
5a2a72fc95
18 changed files with 160 additions and 116 deletions
|
@ -50,7 +50,7 @@ void AnimTexture::SetFrame(const uint8_t *palette, const void *data_)
|
||||||
{
|
{
|
||||||
memcpy(Palette, palette, 768);
|
memcpy(Palette, palette, 768);
|
||||||
memcpy(Image.Data(), data_, Width * Height);
|
memcpy(Image.Data(), data_, Width * Height);
|
||||||
CleanHardwareTextures(true);
|
CleanHardwareTextures();
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
|
@ -17,8 +17,6 @@ public:
|
||||||
IHardwareTexture() = default;
|
IHardwareTexture() = default;
|
||||||
virtual ~IHardwareTexture() = default;
|
virtual ~IHardwareTexture() = default;
|
||||||
|
|
||||||
virtual void DeleteDescriptors() { }
|
|
||||||
|
|
||||||
virtual void AllocateBuffer(int w, int h, int texelsize) = 0;
|
virtual void AllocateBuffer(int w, int h, int texelsize) = 0;
|
||||||
virtual uint8_t *MapBuffer() = 0;
|
virtual uint8_t *MapBuffer() = 0;
|
||||||
virtual unsigned int CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, const char *name) = 0;
|
virtual unsigned int CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, const char *name) = 0;
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "hw_material.h"
|
#include "hw_material.h"
|
||||||
#include "texturemanager.h"
|
#include "texturemanager.h"
|
||||||
#include "c_cvars.h"
|
#include "c_cvars.h"
|
||||||
|
#include "v_video.h"
|
||||||
|
|
||||||
IHardwareTexture* CreateHardwareTexture();
|
IHardwareTexture* CreateHardwareTexture();
|
||||||
|
|
||||||
|
@ -173,7 +174,7 @@ FMaterial * FMaterial::ValidateTexture(FGameTexture * gtex, int scaleflags, bool
|
||||||
FMaterial *hwtex = gtex->Material[scaleflags];
|
FMaterial *hwtex = gtex->Material[scaleflags];
|
||||||
if (hwtex == NULL && create)
|
if (hwtex == NULL && create)
|
||||||
{
|
{
|
||||||
hwtex = new FMaterial(gtex, scaleflags);
|
hwtex = screen->CreateMaterial(gtex, scaleflags);
|
||||||
}
|
}
|
||||||
return hwtex;
|
return hwtex;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,10 +27,11 @@ public:
|
||||||
FTexture* imgtex; // the first layer's texture image - should be moved into the array
|
FTexture* imgtex; // the first layer's texture image - should be moved into the array
|
||||||
|
|
||||||
FMaterial(FGameTexture *tex, int scaleflags);
|
FMaterial(FGameTexture *tex, int scaleflags);
|
||||||
~FMaterial();
|
virtual ~FMaterial();
|
||||||
int GetLayerFlags() const { return mLayerFlags; }
|
int GetLayerFlags() const { return mLayerFlags; }
|
||||||
int GetShaderIndex() const { return mShaderIndex; }
|
int GetShaderIndex() const { return mShaderIndex; }
|
||||||
int GetScaleFlags() const { return mScaleFlags; }
|
int GetScaleFlags() const { return mScaleFlags; }
|
||||||
|
virtual void DeleteDescriptors() { }
|
||||||
|
|
||||||
FGameTexture* Source() const
|
FGameTexture* Source() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -36,11 +36,6 @@ private:
|
||||||
hwTexture = nullptr;
|
hwTexture = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeleteDescriptors()
|
|
||||||
{
|
|
||||||
if (hwTexture) hwTexture->DeleteDescriptors();
|
|
||||||
}
|
|
||||||
|
|
||||||
~TranslatedTexture()
|
~TranslatedTexture()
|
||||||
{
|
{
|
||||||
Delete();
|
Delete();
|
||||||
|
@ -81,15 +76,8 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
void Clean()
|
||||||
void Clean(bool reallyclean)
|
|
||||||
{
|
{
|
||||||
hwDefTex[0].DeleteDescriptors();
|
|
||||||
hwDefTex[1].DeleteDescriptors();
|
|
||||||
for (unsigned int j = 0; j < hwTex_Translated.Size(); j++)
|
|
||||||
hwTex_Translated[j].DeleteDescriptors();
|
|
||||||
|
|
||||||
if (!reallyclean) return;
|
|
||||||
hwDefTex[0].Delete();
|
hwDefTex[0].Delete();
|
||||||
hwDefTex[1].Delete();
|
hwDefTex[1].Delete();
|
||||||
hwTex_Translated.Clear();
|
hwTex_Translated.Clear();
|
||||||
|
|
|
@ -558,9 +558,9 @@ bool FTexture::DetermineTranslucency()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void FTexture::CleanHardwareTextures(bool reallyclean)
|
void FTexture::CleanHardwareTextures()
|
||||||
{
|
{
|
||||||
SystemTextures.Clean(reallyclean);
|
SystemTextures.Clean();
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
@ -787,6 +787,11 @@ void FGameTexture::SetSpriteRect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FGameTexture::CleanHardwareData(bool full)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
// Create a hardware texture for this texture image.
|
// Create a hardware texture for this texture image.
|
||||||
|
|
|
@ -118,7 +118,7 @@ void FTextureManager::FlushAll()
|
||||||
{
|
{
|
||||||
for (int j = 0; j < 2; j++)
|
for (int j = 0; j < 2; j++)
|
||||||
{
|
{
|
||||||
Textures[i].Texture->GetTexture()->CleanHardwareTextures(true);
|
Textures[i].Texture->CleanHardwareData();
|
||||||
delete Textures[i].Texture->GetSoftwareTexture();
|
delete Textures[i].Texture->GetSoftwareTexture();
|
||||||
Textures[i].Texture->SetSoftwareTexture(nullptr);
|
Textures[i].Texture->SetSoftwareTexture(nullptr);
|
||||||
calcShouldUpscale(Textures[i].Texture);
|
calcShouldUpscale(Textures[i].Texture);
|
||||||
|
|
|
@ -259,7 +259,7 @@ public:
|
||||||
static FTexture *CreateTexture(int lumpnum, bool allowflats = false);
|
static FTexture *CreateTexture(int lumpnum, bool allowflats = false);
|
||||||
virtual FImageSource *GetImage() const { return nullptr; }
|
virtual FImageSource *GetImage() const { return nullptr; }
|
||||||
void CreateUpsampledTextureBuffer(FTextureBuffer &texbuffer, bool hasAlpha, bool checkonly);
|
void CreateUpsampledTextureBuffer(FTextureBuffer &texbuffer, bool hasAlpha, bool checkonly);
|
||||||
void CleanHardwareTextures(bool reallyclean);
|
void CleanHardwareTextures();
|
||||||
|
|
||||||
int GetWidth() { return Width; }
|
int GetWidth() { return Width; }
|
||||||
int GetHeight() { return Height; }
|
int GetHeight() { return Height; }
|
||||||
|
@ -648,6 +648,9 @@ public:
|
||||||
else if ((isWarped() || shaderindex >= FIRST_USER_SHADER) && clampmode <= CLAMP_XY) clampmode = CLAMP_NONE;
|
else if ((isWarped() || shaderindex >= FIRST_USER_SHADER) && clampmode <= CLAMP_XY) clampmode = CLAMP_NONE;
|
||||||
return clampmode;
|
return clampmode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CleanHardwareData(bool full = true);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline FGameTexture* MakeGameTexture(FTexture* tex, const char *name, ETextureType useType)
|
inline FGameTexture* MakeGameTexture(FTexture* tex, const char *name, ETextureType useType)
|
||||||
|
|
|
@ -3401,6 +3401,7 @@ void D_Cleanup()
|
||||||
DeinitMenus();
|
DeinitMenus();
|
||||||
LightDefaults.DeleteAndClear(); // this can leak heap memory if it isn't cleared.
|
LightDefaults.DeleteAndClear(); // this can leak heap memory if it isn't cleared.
|
||||||
TexAnim.DeleteAll();
|
TexAnim.DeleteAll();
|
||||||
|
TexMan.DeleteAll();
|
||||||
|
|
||||||
// delete DoomStartupInfo data
|
// delete DoomStartupInfo data
|
||||||
DoomStartupInfo.Name = "";
|
DoomStartupInfo.Name = "";
|
||||||
|
|
|
@ -373,8 +373,8 @@ bool Wiper_Burn::Run(int ticks)
|
||||||
done = (Density < 0);
|
done = (Density < 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
BurnTexture->CleanHardwareTextures(true);
|
BurnTexture->CleanHardwareTextures();
|
||||||
endScreen->GetTexture()->CleanHardwareTextures(false); // this only cleans the descriptor sets for the Vulkan backend. Needs to be done better.
|
endScreen->CleanHardwareData(false); // this only cleans the descriptor sets for the Vulkan backend. We do not want to delete the wipe screen's hardware texture here.
|
||||||
|
|
||||||
const uint8_t *src = BurnArray;
|
const uint8_t *src = BurnArray;
|
||||||
uint32_t *dest = (uint32_t *)BurnTexture->GetBuffer();
|
uint32_t *dest = (uint32_t *)BurnTexture->GetBuffer();
|
||||||
|
|
|
@ -230,7 +230,7 @@ void hw_PrecacheTexture(uint8_t *texhitlist, TMap<PClassActor*, bool> &actorhitl
|
||||||
// For now, only delete what's in neither list. The logic being used here does not really work that well for selective deletion.
|
// For now, only delete what's in neither list. The logic being used here does not really work that well for selective deletion.
|
||||||
if (usedTextures.CheckKey(tex->GetTexture()) == nullptr && usedSprites.CheckKey(tex->GetTexture()) == nullptr)
|
if (usedTextures.CheckKey(tex->GetTexture()) == nullptr && usedSprites.CheckKey(tex->GetTexture()) == nullptr)
|
||||||
{
|
{
|
||||||
tex->GetTexture()->CleanHardwareTextures(true);
|
tex->CleanHardwareData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -455,6 +455,11 @@ void DFrameBuffer::FPSLimit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FMaterial* DFrameBuffer::CreateMaterial(FGameTexture* tex, int scaleflags)
|
||||||
|
{
|
||||||
|
return new FMaterial(tex, scaleflags);
|
||||||
|
}
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION(_Screen, GetViewWindow)
|
DEFINE_ACTION_FUNCTION(_Screen, GetViewWindow)
|
||||||
{
|
{
|
||||||
PARAM_PROLOGUE;
|
PARAM_PROLOGUE;
|
||||||
|
|
|
@ -65,6 +65,8 @@ class FFlatVertexBuffer;
|
||||||
class HWViewpointBuffer;
|
class HWViewpointBuffer;
|
||||||
class FLightBuffer;
|
class FLightBuffer;
|
||||||
struct HWDrawInfo;
|
struct HWDrawInfo;
|
||||||
|
class FMaterial;
|
||||||
|
class FGameTexture;
|
||||||
|
|
||||||
enum EHWCaps
|
enum EHWCaps
|
||||||
{
|
{
|
||||||
|
@ -266,6 +268,7 @@ public:
|
||||||
virtual IHardwareTexture *CreateHardwareTexture() { return nullptr; }
|
virtual IHardwareTexture *CreateHardwareTexture() { return nullptr; }
|
||||||
virtual void PrecacheMaterial(FMaterial *mat, int translation) {}
|
virtual void PrecacheMaterial(FMaterial *mat, int translation) {}
|
||||||
virtual FModelRenderer *CreateModelRenderer(int mli) { return nullptr; }
|
virtual FModelRenderer *CreateModelRenderer(int mli) { return nullptr; }
|
||||||
|
virtual FMaterial* CreateMaterial(FGameTexture* tex, int scaleflags);
|
||||||
virtual void TextureFilterChanged() {}
|
virtual void TextureFilterChanged() {}
|
||||||
virtual void BeginFrame() {}
|
virtual void BeginFrame() {}
|
||||||
virtual void SetWindowSize(int w, int h) {}
|
virtual void SetWindowSize(int w, int h) {}
|
||||||
|
|
|
@ -434,8 +434,7 @@ void VkRenderState::ApplyMaterial()
|
||||||
auto fb = GetVulkanFrameBuffer();
|
auto fb = GetVulkanFrameBuffer();
|
||||||
auto passManager = fb->GetRenderPassManager();
|
auto passManager = fb->GetRenderPassManager();
|
||||||
|
|
||||||
VkHardwareTexture* base = mMaterial.mMaterial ? static_cast<VkHardwareTexture*>(mMaterial.mMaterial->GetLayer(0, mMaterial.mTranslation)) : nullptr;
|
VulkanDescriptorSet* descriptorset = mMaterial.mMaterial ? static_cast<VkMaterial*>(mMaterial.mMaterial)->GetDescriptorSet(mMaterial) : passManager->GetNullTextureDescriptorSet();
|
||||||
VulkanDescriptorSet* descriptorset = base ? base->GetDescriptorSet(mMaterial) : passManager->GetNullTextureDescriptorSet();
|
|
||||||
|
|
||||||
mCommandBuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, passManager->GetPipelineLayout(mPipelineKey.NumTextureLayers), 1, descriptorset);
|
mCommandBuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, passManager->GetPipelineLayout(mPipelineKey.NumTextureLayers), 1, descriptorset);
|
||||||
mMaterial.mChanged = false;
|
mMaterial.mChanged = false;
|
||||||
|
|
|
@ -667,6 +667,11 @@ IHardwareTexture *VulkanFrameBuffer::CreateHardwareTexture()
|
||||||
return new VkHardwareTexture();
|
return new VkHardwareTexture();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FMaterial* VulkanFrameBuffer::CreateMaterial(FGameTexture* tex, int scaleflags)
|
||||||
|
{
|
||||||
|
return new VkMaterial(tex, scaleflags);
|
||||||
|
}
|
||||||
|
|
||||||
FModelRenderer *VulkanFrameBuffer::CreateModelRenderer(int mli)
|
FModelRenderer *VulkanFrameBuffer::CreateModelRenderer(int mli)
|
||||||
{
|
{
|
||||||
return new FHWModelRenderer(nullptr, *GetRenderState(), mli);
|
return new FHWModelRenderer(nullptr, *GetRenderState(), mli);
|
||||||
|
@ -711,7 +716,7 @@ void VulkanFrameBuffer::TextureFilterChanged()
|
||||||
if (mSamplerManager)
|
if (mSamplerManager)
|
||||||
{
|
{
|
||||||
// Destroy the texture descriptors as they used the old samplers
|
// Destroy the texture descriptors as they used the old samplers
|
||||||
VkHardwareTexture::ResetAllDescriptors();
|
VkMaterial::ResetAllDescriptors();
|
||||||
|
|
||||||
mSamplerManager->SetTextureFilterMode();
|
mSamplerManager->SetTextureFilterMode();
|
||||||
}
|
}
|
||||||
|
@ -720,7 +725,7 @@ void VulkanFrameBuffer::TextureFilterChanged()
|
||||||
void VulkanFrameBuffer::StartPrecaching()
|
void VulkanFrameBuffer::StartPrecaching()
|
||||||
{
|
{
|
||||||
// Destroy the texture descriptors to avoid problems with potentially stale textures.
|
// Destroy the texture descriptors to avoid problems with potentially stale textures.
|
||||||
VkHardwareTexture::ResetAllDescriptors();
|
VkMaterial::ResetAllDescriptors();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanFrameBuffer::BlurScene(float amount)
|
void VulkanFrameBuffer::BlurScene(float amount)
|
||||||
|
|
|
@ -89,6 +89,7 @@ public:
|
||||||
void PostProcessScene(int fixedcm, const std::function<void()> &afterBloomDrawEndScene2D) override;
|
void PostProcessScene(int fixedcm, const std::function<void()> &afterBloomDrawEndScene2D) override;
|
||||||
|
|
||||||
IHardwareTexture *CreateHardwareTexture() override;
|
IHardwareTexture *CreateHardwareTexture() override;
|
||||||
|
FMaterial* CreateMaterial(FGameTexture* tex, int scaleflags) override;
|
||||||
FModelRenderer *CreateModelRenderer(int mli) override;
|
FModelRenderer *CreateModelRenderer(int mli) override;
|
||||||
IVertexBuffer *CreateVertexBuffer() override;
|
IVertexBuffer *CreateVertexBuffer() override;
|
||||||
IIndexBuffer *CreateIndexBuffer() override;
|
IIndexBuffer *CreateIndexBuffer() override;
|
||||||
|
|
|
@ -64,8 +64,6 @@ void VkHardwareTexture::Reset()
|
||||||
{
|
{
|
||||||
if (auto fb = GetVulkanFrameBuffer())
|
if (auto fb = GetVulkanFrameBuffer())
|
||||||
{
|
{
|
||||||
ResetDescriptors();
|
|
||||||
|
|
||||||
if (mappedSWFB)
|
if (mappedSWFB)
|
||||||
{
|
{
|
||||||
mImage.Image->Unmap();
|
mImage.Image->Unmap();
|
||||||
|
@ -84,78 +82,6 @@ void VkHardwareTexture::Reset()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VkHardwareTexture::ResetDescriptors()
|
|
||||||
{
|
|
||||||
if (auto fb = GetVulkanFrameBuffer())
|
|
||||||
{
|
|
||||||
auto &deleteList = fb->FrameDeleteList;
|
|
||||||
|
|
||||||
for (auto &it : mDescriptorSets)
|
|
||||||
{
|
|
||||||
deleteList.Descriptors.push_back(std::move(it.descriptor));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mDescriptorSets.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void VkHardwareTexture::ResetAllDescriptors()
|
|
||||||
{
|
|
||||||
for (VkHardwareTexture *cur = First; cur; cur = cur->Next)
|
|
||||||
cur->ResetDescriptors();
|
|
||||||
|
|
||||||
auto fb = GetVulkanFrameBuffer();
|
|
||||||
if (fb)
|
|
||||||
fb->GetRenderPassManager()->TextureSetPoolReset();
|
|
||||||
}
|
|
||||||
|
|
||||||
VulkanDescriptorSet *VkHardwareTexture::GetDescriptorSet(const FMaterialState &state)
|
|
||||||
{
|
|
||||||
FMaterial *mat = state.mMaterial;
|
|
||||||
auto base = state.mMaterial->Source();
|
|
||||||
int clampmode = state.mClampMode;
|
|
||||||
int translation = state.mTranslation;
|
|
||||||
|
|
||||||
clampmode = base->GetClampMode(clampmode);
|
|
||||||
|
|
||||||
// Textures that are already scaled in the texture lump will not get replaced by hires textures.
|
|
||||||
int flags = mat->GetScaleFlags();
|
|
||||||
|
|
||||||
for (auto &set : mDescriptorSets)
|
|
||||||
{
|
|
||||||
if (set.descriptor && set.clampmode == clampmode && set.flags == flags) return set.descriptor.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
int numLayers = mat->GetLayers();
|
|
||||||
|
|
||||||
auto fb = GetVulkanFrameBuffer();
|
|
||||||
auto descriptor = fb->GetRenderPassManager()->AllocateTextureDescriptorSet(std::max(numLayers, SHADER_MIN_REQUIRED_TEXTURE_LAYERS));
|
|
||||||
|
|
||||||
descriptor->SetDebugName("VkHardwareTexture.mDescriptorSets");
|
|
||||||
|
|
||||||
VulkanSampler *sampler = fb->GetSamplerManager()->Get(clampmode);
|
|
||||||
|
|
||||||
WriteDescriptors update;
|
|
||||||
update.addCombinedImageSampler(descriptor.get(), 0, GetImage(mat->BaseLayer(), translation, flags)->View.get(), sampler, mImage.Layout);
|
|
||||||
for (int i = 1; i < numLayers; i++)
|
|
||||||
{
|
|
||||||
FTexture *layer;
|
|
||||||
auto systex = static_cast<VkHardwareTexture*>(mat->GetLayer(i, 0, &layer));
|
|
||||||
// fixme: Upscale flags must be disabled for certain layers.
|
|
||||||
update.addCombinedImageSampler(descriptor.get(), i, systex->GetImage(layer, 0, flags)->View.get(), sampler, systex->mImage.Layout);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto dummyImage = fb->GetRenderPassManager()->GetNullTextureView();
|
|
||||||
for (int i = numLayers; i < SHADER_MIN_REQUIRED_TEXTURE_LAYERS; i++)
|
|
||||||
{
|
|
||||||
update.addCombinedImageSampler(descriptor.get(), i, dummyImage, sampler, mImage.Layout);
|
|
||||||
}
|
|
||||||
|
|
||||||
update.updateSets(fb->device);
|
|
||||||
mDescriptorSets.emplace_back(clampmode, flags, std::move(descriptor));
|
|
||||||
return mDescriptorSets.back().descriptor.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
VkTextureImage *VkHardwareTexture::GetImage(FTexture *tex, int translation, int flags)
|
VkTextureImage *VkHardwareTexture::GetImage(FTexture *tex, int translation, int flags)
|
||||||
{
|
{
|
||||||
if (!mImage.Image)
|
if (!mImage.Image)
|
||||||
|
@ -392,3 +318,98 @@ void VkHardwareTexture::CreateWipeTexture(int w, int h, const char *name)
|
||||||
transition1.execute(fb->GetTransferCommands());
|
transition1.execute(fb->GetTransferCommands());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VkMaterial* VkMaterial::First = nullptr;
|
||||||
|
|
||||||
|
VkMaterial::VkMaterial(FGameTexture* tex, int scaleflags) : FMaterial(tex, scaleflags)
|
||||||
|
{
|
||||||
|
Next = First;
|
||||||
|
First = this;
|
||||||
|
if (Next) Next->Prev = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkMaterial::~VkMaterial()
|
||||||
|
{
|
||||||
|
if (Next) Next->Prev = Prev;
|
||||||
|
if (Prev) Prev->Next = Next;
|
||||||
|
else First = Next;
|
||||||
|
|
||||||
|
DeleteDescriptors();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VkMaterial::DeleteDescriptors()
|
||||||
|
{
|
||||||
|
if (auto fb = GetVulkanFrameBuffer())
|
||||||
|
{
|
||||||
|
auto& deleteList = fb->FrameDeleteList;
|
||||||
|
|
||||||
|
for (auto& it : mDescriptorSets)
|
||||||
|
{
|
||||||
|
deleteList.Descriptors.push_back(std::move(it.descriptor));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mDescriptorSets.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VkMaterial::ResetAllDescriptors()
|
||||||
|
{
|
||||||
|
for (VkMaterial* cur = First; cur; cur = cur->Next)
|
||||||
|
cur->DeleteDescriptors();
|
||||||
|
|
||||||
|
auto fb = GetVulkanFrameBuffer();
|
||||||
|
if (fb)
|
||||||
|
fb->GetRenderPassManager()->TextureSetPoolReset();
|
||||||
|
}
|
||||||
|
|
||||||
|
VulkanDescriptorSet* VkMaterial::GetDescriptorSet(const FMaterialState& state)
|
||||||
|
{
|
||||||
|
auto base = Source();
|
||||||
|
int clampmode = state.mClampMode;
|
||||||
|
int translation = state.mTranslation;
|
||||||
|
|
||||||
|
auto remap = translation <= 0 ? nullptr : GPalette.TranslationToTable(translation);
|
||||||
|
if (remap) translation = remap->Index;
|
||||||
|
|
||||||
|
clampmode = base->GetClampMode(clampmode);
|
||||||
|
|
||||||
|
// Textures that are already scaled in the texture lump will not get replaced by hires textures.
|
||||||
|
int flags = GetScaleFlags();
|
||||||
|
|
||||||
|
for (auto& set : mDescriptorSets)
|
||||||
|
{
|
||||||
|
if (set.descriptor && set.clampmode == clampmode && set.flags == translation) return set.descriptor.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
int numLayers = GetLayers();
|
||||||
|
|
||||||
|
auto fb = GetVulkanFrameBuffer();
|
||||||
|
auto descriptor = fb->GetRenderPassManager()->AllocateTextureDescriptorSet(std::max(numLayers, SHADER_MIN_REQUIRED_TEXTURE_LAYERS));
|
||||||
|
|
||||||
|
descriptor->SetDebugName("VkHardwareTexture.mDescriptorSets");
|
||||||
|
|
||||||
|
VulkanSampler* sampler = fb->GetSamplerManager()->Get(clampmode);
|
||||||
|
|
||||||
|
WriteDescriptors update;
|
||||||
|
FTexture* layer;
|
||||||
|
auto systex = static_cast<VkHardwareTexture*>(GetLayer(0, translation, &layer));
|
||||||
|
update.addCombinedImageSampler(descriptor.get(), 0, systex->GetImage(layer, translation, flags)->View.get(), sampler, systex->mImage.Layout);
|
||||||
|
for (int i = 1; i < numLayers; i++)
|
||||||
|
{
|
||||||
|
auto systex = static_cast<VkHardwareTexture*>(GetLayer(i, 0, &layer));
|
||||||
|
// fixme: Upscale flags must be disabled for certain layers.
|
||||||
|
update.addCombinedImageSampler(descriptor.get(), i, systex->GetImage(layer, 0, flags)->View.get(), sampler, systex->mImage.Layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto dummyImage = fb->GetRenderPassManager()->GetNullTextureView();
|
||||||
|
for (int i = numLayers; i < SHADER_MIN_REQUIRED_TEXTURE_LAYERS; i++)
|
||||||
|
{
|
||||||
|
update.addCombinedImageSampler(descriptor.get(), i, dummyImage, sampler, systex->mImage.Layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
update.updateSets(fb->device);
|
||||||
|
mDescriptorSets.emplace_back(clampmode, translation, std::move(descriptor));
|
||||||
|
return mDescriptorSets.back().descriptor.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,15 +11,18 @@
|
||||||
#include "hw_ihwtexture.h"
|
#include "hw_ihwtexture.h"
|
||||||
#include "volk/volk.h"
|
#include "volk/volk.h"
|
||||||
#include "vk_imagetransition.h"
|
#include "vk_imagetransition.h"
|
||||||
|
#include "hw_material.h"
|
||||||
|
|
||||||
struct FMaterialState;
|
struct FMaterialState;
|
||||||
class VulkanDescriptorSet;
|
class VulkanDescriptorSet;
|
||||||
class VulkanImage;
|
class VulkanImage;
|
||||||
class VulkanImageView;
|
class VulkanImageView;
|
||||||
class VulkanBuffer;
|
class VulkanBuffer;
|
||||||
|
class FGameTexture;
|
||||||
|
|
||||||
class VkHardwareTexture : public IHardwareTexture
|
class VkHardwareTexture : public IHardwareTexture
|
||||||
{
|
{
|
||||||
|
friend class VkMaterial;
|
||||||
public:
|
public:
|
||||||
VkHardwareTexture();
|
VkHardwareTexture();
|
||||||
~VkHardwareTexture();
|
~VkHardwareTexture();
|
||||||
|
@ -27,8 +30,6 @@ public:
|
||||||
static void ResetAll();
|
static void ResetAll();
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
VulkanDescriptorSet *GetDescriptorSet(const FMaterialState &state);
|
|
||||||
|
|
||||||
// Software renderer stuff
|
// Software renderer stuff
|
||||||
void AllocateBuffer(int w, int h, int texelsize) override;
|
void AllocateBuffer(int w, int h, int texelsize) override;
|
||||||
uint8_t *MapBuffer() override;
|
uint8_t *MapBuffer() override;
|
||||||
|
@ -37,12 +38,9 @@ public:
|
||||||
// Wipe screen
|
// Wipe screen
|
||||||
void CreateWipeTexture(int w, int h, const char *name);
|
void CreateWipeTexture(int w, int h, const char *name);
|
||||||
|
|
||||||
void DeleteDescriptors() override { ResetDescriptors(); }
|
|
||||||
|
|
||||||
VkTextureImage *GetImage(FTexture *tex, int translation, int flags);
|
VkTextureImage *GetImage(FTexture *tex, int translation, int flags);
|
||||||
VkTextureImage *GetDepthStencil(FTexture *tex);
|
VkTextureImage *GetDepthStencil(FTexture *tex);
|
||||||
|
|
||||||
static void ResetAllDescriptors();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void CreateImage(FTexture *tex, int translation, int flags);
|
void CreateImage(FTexture *tex, int translation, int flags);
|
||||||
|
@ -50,19 +48,32 @@ private:
|
||||||
void CreateTexture(int w, int h, int pixelsize, VkFormat format, const void *pixels);
|
void CreateTexture(int w, int h, int pixelsize, VkFormat format, const void *pixels);
|
||||||
static int GetMipLevels(int w, int h);
|
static int GetMipLevels(int w, int h);
|
||||||
|
|
||||||
void ResetDescriptors();
|
|
||||||
|
|
||||||
static VkHardwareTexture *First;
|
static VkHardwareTexture *First;
|
||||||
VkHardwareTexture *Prev = nullptr;
|
VkHardwareTexture *Prev = nullptr;
|
||||||
VkHardwareTexture *Next = nullptr;
|
VkHardwareTexture *Next = nullptr;
|
||||||
|
|
||||||
|
VkTextureImage mImage;
|
||||||
|
int mTexelsize = 4;
|
||||||
|
|
||||||
|
VkTextureImage mDepthStencil;
|
||||||
|
|
||||||
|
uint8_t* mappedSWFB = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class VkMaterial : public FMaterial
|
||||||
|
{
|
||||||
|
static VkMaterial* First;
|
||||||
|
VkMaterial* Prev = nullptr;
|
||||||
|
VkMaterial* Next = nullptr;
|
||||||
|
|
||||||
struct DescriptorEntry
|
struct DescriptorEntry
|
||||||
{
|
{
|
||||||
int clampmode;
|
int clampmode;
|
||||||
int flags;
|
int flags;
|
||||||
std::unique_ptr<VulkanDescriptorSet> descriptor;
|
std::unique_ptr<VulkanDescriptorSet> descriptor;
|
||||||
|
|
||||||
DescriptorEntry(int cm, int f, std::unique_ptr<VulkanDescriptorSet> &&d)
|
DescriptorEntry(int cm, int f, std::unique_ptr<VulkanDescriptorSet>&& d)
|
||||||
{
|
{
|
||||||
clampmode = cm;
|
clampmode = cm;
|
||||||
flags = f;
|
flags = f;
|
||||||
|
@ -71,10 +82,12 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<DescriptorEntry> mDescriptorSets;
|
std::vector<DescriptorEntry> mDescriptorSets;
|
||||||
VkTextureImage mImage;
|
|
||||||
int mTexelsize = 4;
|
|
||||||
|
|
||||||
VkTextureImage mDepthStencil;
|
public:
|
||||||
|
VkMaterial(FGameTexture *tex, int scaleflags);
|
||||||
|
~VkMaterial();
|
||||||
|
VulkanDescriptorSet* GetDescriptorSet(const FMaterialState& state);
|
||||||
|
void DeleteDescriptors() override;
|
||||||
|
static void ResetAllDescriptors();
|
||||||
|
|
||||||
uint8_t* mappedSWFB = nullptr;
|
};
|
||||||
};
|
|
Loading…
Reference in a new issue