Graphics: Improve TextureSampler handling
This commit is contained in:
parent
78c3f57333
commit
b9151d8a7a
|
|
@ -89,19 +89,13 @@ int main()
|
|||
return __LINE__;
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::shared_ptr<Nz::TextureSampler> textureSampler = device->InstantiateTextureSampler({});
|
||||
|
||||
std::shared_ptr<Nz::Material> material = std::make_shared<Nz::Material>(Nz::BasicMaterial::GetSettings());
|
||||
material->EnableDepthBuffer(true);
|
||||
|
||||
Nz::BasicMaterial basicMat(*material);
|
||||
basicMat.EnableAlphaTest(false);
|
||||
basicMat.SetAlphaMap(alphaTexture);
|
||||
basicMat.SetAlphaSampler(textureSampler);
|
||||
basicMat.SetDiffuseMap(texture);
|
||||
basicMat.SetDiffuseSampler(textureSampler);
|
||||
|
||||
Nz::Model model(std::move(gfxMesh));
|
||||
for (std::size_t i = 0; i < model.GetSubMeshCount(); ++i)
|
||||
|
|
|
|||
|
|
@ -24,11 +24,11 @@ namespace Nz
|
|||
inline void EnableAlphaTest(bool alphaTest);
|
||||
|
||||
inline const std::shared_ptr<Texture>& GetAlphaMap() const;
|
||||
inline const std::shared_ptr<TextureSampler>& GetAlphaSampler() const;
|
||||
inline const TextureSamplerInfo& GetAlphaSampler() const;
|
||||
float GetAlphaTestThreshold() const;
|
||||
Color GetDiffuseColor() const;
|
||||
inline const std::shared_ptr<Texture>& GetDiffuseMap() const;
|
||||
inline const std::shared_ptr<TextureSampler>& GetDiffuseSampler() const;
|
||||
inline const TextureSamplerInfo& GetDiffuseSampler() const;
|
||||
|
||||
inline bool HasAlphaMap() const;
|
||||
inline bool HasAlphaTest() const;
|
||||
|
|
@ -37,11 +37,11 @@ namespace Nz
|
|||
inline bool HasDiffuseMap() const;
|
||||
|
||||
inline void SetAlphaMap(std::shared_ptr<Texture> alphaMap);
|
||||
inline void SetAlphaSampler(std::shared_ptr<TextureSampler> alphaSampler);
|
||||
inline void SetAlphaSampler(TextureSamplerInfo alphaSampler);
|
||||
void SetAlphaTestThreshold(float alphaThreshold);
|
||||
void SetDiffuseColor(const Color& diffuse);
|
||||
inline void SetDiffuseMap(std::shared_ptr<Texture> diffuseMap);
|
||||
inline void SetDiffuseSampler(std::shared_ptr<TextureSampler> diffuseSampler);
|
||||
inline void SetDiffuseSampler(TextureSamplerInfo diffuseSampler);
|
||||
|
||||
static inline const UniformOffsets& GetOffsets();
|
||||
static inline const std::shared_ptr<MaterialSettings>& GetSettings();
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ namespace Nz
|
|||
return m_material.GetTexture(m_textureIndexes.alpha);
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<TextureSampler>& BasicMaterial::GetAlphaSampler() const
|
||||
inline const TextureSamplerInfo& BasicMaterial::GetAlphaSampler() const
|
||||
{
|
||||
NazaraAssert(HasAlphaMap(), "Material has no alpha texture slot");
|
||||
return m_material.GetTextureSampler(m_textureIndexes.alpha);
|
||||
|
|
@ -47,7 +47,7 @@ namespace Nz
|
|||
return m_material.GetTexture(m_textureIndexes.diffuse);
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<TextureSampler>& BasicMaterial::GetDiffuseSampler() const
|
||||
inline const TextureSamplerInfo& BasicMaterial::GetDiffuseSampler() const
|
||||
{
|
||||
NazaraAssert(HasDiffuseMap(), "Material has no alpha texture slot");
|
||||
return m_material.GetTextureSampler(m_textureIndexes.diffuse);
|
||||
|
|
@ -88,7 +88,7 @@ namespace Nz
|
|||
m_material.EnableCondition(m_conditionIndexes.hasAlphaMap, hasAlphaMap);
|
||||
}
|
||||
|
||||
inline void BasicMaterial::SetAlphaSampler(std::shared_ptr<TextureSampler> alphaSampler)
|
||||
inline void BasicMaterial::SetAlphaSampler(TextureSamplerInfo alphaSampler)
|
||||
{
|
||||
NazaraAssert(HasAlphaMap(), "Material has no alpha map slot");
|
||||
m_material.SetTextureSampler(m_textureIndexes.alpha, std::move(alphaSampler));
|
||||
|
|
@ -104,7 +104,7 @@ namespace Nz
|
|||
m_material.EnableCondition(m_conditionIndexes.hasDiffuseMap, hasDiffuseMap);
|
||||
}
|
||||
|
||||
inline void BasicMaterial::SetDiffuseSampler(std::shared_ptr<TextureSampler> diffuseSampler)
|
||||
inline void BasicMaterial::SetDiffuseSampler(TextureSamplerInfo diffuseSampler)
|
||||
{
|
||||
NazaraAssert(HasDiffuseMap(), "Material has no diffuse map slot");
|
||||
m_material.SetTextureSampler(m_textureIndexes.diffuse, std::move(diffuseSampler));
|
||||
|
|
|
|||
|
|
@ -9,8 +9,10 @@
|
|||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/Config.hpp>
|
||||
#include <Nazara/Graphics/TextureSamplerCache.hpp>
|
||||
#include <Nazara/Renderer/Renderer.hpp>
|
||||
#include <Nazara/Renderer/RenderDevice.hpp>
|
||||
#include <optional>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
|
|
@ -30,6 +32,7 @@ namespace Nz
|
|||
~Graphics();
|
||||
|
||||
inline RenderDevice& GetRenderDevice();
|
||||
inline TextureSamplerCache& GetSamplerCache();
|
||||
inline const std::shared_ptr<AbstractBuffer>& GetViewerDataUBO();
|
||||
|
||||
struct Config
|
||||
|
|
@ -38,6 +41,7 @@ namespace Nz
|
|||
};
|
||||
|
||||
private:
|
||||
std::optional<TextureSamplerCache> m_samplerCache;
|
||||
std::shared_ptr<AbstractBuffer> m_viewerDataUBO;
|
||||
std::shared_ptr<RenderDevice> m_renderDevice;
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,11 @@ namespace Nz
|
|||
return *m_renderDevice;
|
||||
}
|
||||
|
||||
inline TextureSamplerCache& Graphics::GetSamplerCache()
|
||||
{
|
||||
return *m_samplerCache;
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<AbstractBuffer>& Graphics::GetViewerDataUBO()
|
||||
{
|
||||
return m_viewerDataUBO;
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ namespace Nz
|
|||
inline const std::shared_ptr<UberShader>& GetShader(ShaderStageType shaderStage) const;
|
||||
inline BlendFunc GetSrcBlend() const;
|
||||
inline const std::shared_ptr<Texture>& GetTexture(std::size_t textureIndex) const;
|
||||
inline const std::shared_ptr<TextureSampler>& GetTextureSampler(std::size_t textureIndex) const;
|
||||
inline const TextureSamplerInfo& GetTextureSampler(std::size_t textureIndex) const;
|
||||
inline const std::shared_ptr<AbstractBuffer>& GetUniformBuffer(std::size_t bufferIndex) const;
|
||||
inline std::vector<UInt8>& GetUniformBufferData(std::size_t bufferIndex);
|
||||
inline const std::vector<UInt8>& GetUniformBufferConstData(std::size_t bufferIndex);
|
||||
|
|
@ -96,7 +96,7 @@ namespace Nz
|
|||
inline void SetUniformBuffer(std::size_t bufferIndex, std::shared_ptr<AbstractBuffer> uniformBuffer);
|
||||
inline void SetSrcBlend(BlendFunc func);
|
||||
inline void SetTexture(std::size_t textureIndex, std::shared_ptr<Texture> texture);
|
||||
inline void SetTextureSampler(std::size_t textureIndex, std::shared_ptr<TextureSampler> sampler);
|
||||
inline void SetTextureSampler(std::size_t textureIndex, TextureSamplerInfo samplerInfo);
|
||||
|
||||
void UpdateShaderBinding(ShaderBinding& shaderBinding) const;
|
||||
|
||||
|
|
@ -106,12 +106,14 @@ namespace Nz
|
|||
private:
|
||||
inline void InvalidatePipeline();
|
||||
inline void InvalidateShaderBinding();
|
||||
inline void InvalidateTextureSampler(std::size_t textureIndex);
|
||||
inline void UpdatePipeline() const;
|
||||
|
||||
struct MaterialTexture
|
||||
{
|
||||
std::shared_ptr<TextureSampler> sampler;
|
||||
mutable std::shared_ptr<TextureSampler> sampler;
|
||||
std::shared_ptr<Texture> texture;
|
||||
TextureSamplerInfo samplerInfo;
|
||||
};
|
||||
|
||||
struct UniformBuffer
|
||||
|
|
|
|||
|
|
@ -436,10 +436,10 @@ namespace Nz
|
|||
return m_textures[textureIndex].texture;
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<TextureSampler>& Material::GetTextureSampler(std::size_t textureIndex) const
|
||||
inline const TextureSamplerInfo& Material::GetTextureSampler(std::size_t textureIndex) const
|
||||
{
|
||||
NazaraAssert(textureIndex < m_textures.size(), "Invalid texture index");
|
||||
return m_textures[textureIndex].sampler;
|
||||
return m_textures[textureIndex].samplerInfo;
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<AbstractBuffer>& Material::GetUniformBuffer(std::size_t bufferIndex) const
|
||||
|
|
@ -695,13 +695,13 @@ namespace Nz
|
|||
}
|
||||
}
|
||||
|
||||
inline void Material::SetTextureSampler(std::size_t textureIndex, std::shared_ptr<TextureSampler> sampler)
|
||||
inline void Material::SetTextureSampler(std::size_t textureIndex, TextureSamplerInfo samplerInfo)
|
||||
{
|
||||
NazaraAssert(textureIndex < m_textures.size(), "Invalid texture index");
|
||||
if (m_textures[textureIndex].sampler != sampler)
|
||||
if (m_textures[textureIndex].samplerInfo != samplerInfo)
|
||||
{
|
||||
m_textures[textureIndex].sampler = std::move(sampler);
|
||||
InvalidateShaderBinding();
|
||||
m_textures[textureIndex].samplerInfo = std::move(samplerInfo);
|
||||
InvalidateTextureSampler(textureIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -731,6 +731,14 @@ namespace Nz
|
|||
//TODO
|
||||
}
|
||||
|
||||
inline void Material::InvalidateTextureSampler(std::size_t textureIndex)
|
||||
{
|
||||
assert(textureIndex < m_textures.size());
|
||||
m_textures[textureIndex].sampler.reset();
|
||||
|
||||
InvalidateShaderBinding();
|
||||
}
|
||||
|
||||
inline void Material::UpdatePipeline() const
|
||||
{
|
||||
for (auto& shader : m_pipelineInfo.shaders)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
// Copyright (C) 2017 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Graphics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_TEXTURESAMPLERCACHE_HPP
|
||||
#define NAZARA_TEXTURESAMPLERCACHE_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/Config.hpp>
|
||||
#include <Nazara/Renderer/TextureSampler.hpp>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class RenderDevice;
|
||||
|
||||
class NAZARA_GRAPHICS_API TextureSamplerCache
|
||||
{
|
||||
public:
|
||||
inline TextureSamplerCache(std::shared_ptr<RenderDevice> device);
|
||||
TextureSamplerCache(const TextureSamplerCache&) = delete;
|
||||
TextureSamplerCache(TextureSamplerCache&&) = delete;
|
||||
~TextureSamplerCache() = default;
|
||||
|
||||
const std::shared_ptr<TextureSampler>& Get(const TextureSamplerInfo& info);
|
||||
|
||||
TextureSamplerCache& operator=(const TextureSamplerCache&) = delete;
|
||||
TextureSamplerCache& operator=(TextureSamplerCache&&) = delete;
|
||||
|
||||
private:
|
||||
std::shared_ptr<RenderDevice> m_device;
|
||||
std::unordered_map<TextureSamplerInfo, std::shared_ptr<TextureSampler>> m_samplers;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/TextureSamplerCache.inl>
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
// Copyright (C) 2017 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Graphics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Graphics/TextureSamplerCache.hpp>
|
||||
#include <functional>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline TextureSamplerCache::TextureSamplerCache(std::shared_ptr<RenderDevice> device) :
|
||||
m_device(std::move(device))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DebugOff.hpp>
|
||||
|
|
@ -22,6 +22,9 @@ namespace Nz
|
|||
SamplerWrap wrapModeU = SamplerWrap_Clamp;
|
||||
SamplerWrap wrapModeV = SamplerWrap_Clamp;
|
||||
SamplerWrap wrapModeW = SamplerWrap_Clamp;
|
||||
|
||||
inline bool operator==(const TextureSamplerInfo& samplerInfo) const;
|
||||
inline bool operator!=(const TextureSamplerInfo& samplerInfo) const;
|
||||
};
|
||||
|
||||
class NAZARA_RENDERER_API TextureSampler
|
||||
|
|
@ -37,6 +40,9 @@ namespace Nz
|
|||
};
|
||||
}
|
||||
|
||||
template<>
|
||||
struct std::hash<Nz::TextureSamplerInfo>;
|
||||
|
||||
#include <Nazara/Renderer/TextureSampler.inl>
|
||||
|
||||
#endif // NAZARA_TEXTURE_HPP
|
||||
|
|
|
|||
|
|
@ -3,10 +3,60 @@
|
|||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Renderer/TextureSampler.hpp>
|
||||
#include <Nazara/Core/Algorithm.hpp>
|
||||
#include <Nazara/Math/Algorithm.hpp>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline bool TextureSamplerInfo::operator==(const TextureSamplerInfo& samplerInfo) const
|
||||
{
|
||||
if (!NumberEquals(anisotropyLevel, samplerInfo.anisotropyLevel, 0.99f))
|
||||
return false;
|
||||
|
||||
if (magFilter != samplerInfo.magFilter)
|
||||
return false;
|
||||
|
||||
if (minFilter != samplerInfo.minFilter)
|
||||
return false;
|
||||
|
||||
if (mipmapMode != samplerInfo.mipmapMode)
|
||||
return false;
|
||||
|
||||
if (wrapModeU != samplerInfo.wrapModeU)
|
||||
return false;
|
||||
|
||||
if (wrapModeV != samplerInfo.wrapModeV)
|
||||
return false;
|
||||
|
||||
if (wrapModeW != samplerInfo.wrapModeW)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool TextureSamplerInfo::operator!=(const TextureSamplerInfo& samplerInfo) const
|
||||
{
|
||||
return !operator==(samplerInfo);
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
struct std::hash<Nz::TextureSamplerInfo>
|
||||
{
|
||||
std::size_t operator()(const Nz::TextureSamplerInfo& sampler) const
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
Nz::HashCombine(seed, sampler.anisotropyLevel);
|
||||
Nz::HashCombine(seed, sampler.magFilter);
|
||||
Nz::HashCombine(seed, sampler.minFilter);
|
||||
Nz::HashCombine(seed, sampler.mipmapMode);
|
||||
Nz::HashCombine(seed, sampler.wrapModeU);
|
||||
Nz::HashCombine(seed, sampler.wrapModeV);
|
||||
Nz::HashCombine(seed, sampler.wrapModeW);
|
||||
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
|
||||
#include <Nazara/Renderer/DebugOff.hpp>
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@ namespace Nz
|
|||
if (!m_renderDevice)
|
||||
throw std::runtime_error("failed to instantiate render device");
|
||||
|
||||
m_samplerCache.emplace(m_renderDevice);
|
||||
|
||||
MaterialPipeline::Initialize();
|
||||
|
||||
Nz::PredefinedViewerData viewerUboOffsets = Nz::PredefinedViewerData::GetOffsets();
|
||||
|
|
|
|||
|
|
@ -63,7 +63,14 @@ namespace Nz
|
|||
|
||||
for (const auto& textureSlot : m_textures)
|
||||
{
|
||||
if (textureSlot.texture && textureSlot.sampler)
|
||||
if (!textureSlot.sampler)
|
||||
{
|
||||
TextureSamplerCache& samplerCache = Graphics::Instance()->GetSamplerCache();
|
||||
textureSlot.sampler = samplerCache.Get(textureSlot.samplerInfo);
|
||||
}
|
||||
|
||||
//TODO: Use "missing" texture
|
||||
if (textureSlot.texture)
|
||||
{
|
||||
bindings.push_back({
|
||||
bindingIndex,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright (C) 2017 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Graphics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Graphics/TextureSamplerCache.hpp>
|
||||
#include <Nazara/Renderer/RenderDevice.hpp>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
const std::shared_ptr<TextureSampler>& TextureSamplerCache::Get(const TextureSamplerInfo& info)
|
||||
{
|
||||
auto it = m_samplers.find(info);
|
||||
if (it == m_samplers.end())
|
||||
it = m_samplers.emplace(info, m_device->InstantiateTextureSampler(info)).first;
|
||||
|
||||
return it->second;
|
||||
}
|
||||
}
|
||||
|
|
@ -55,13 +55,13 @@ namespace Nz
|
|||
VkMemoryRequirements requirement = newBlock.buffer.GetMemoryRequirements();
|
||||
|
||||
if (!newBlock.blockMemory.Create(m_device, requirement.size, requirement.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT))
|
||||
throw std::runtime_error("Failed to allocate block memory: " + TranslateVulkanError(newBlock.blockMemory.GetLastErrorCode()));
|
||||
throw std::runtime_error("failed to allocate block memory: " + TranslateVulkanError(newBlock.blockMemory.GetLastErrorCode()));
|
||||
|
||||
if (!newBlock.buffer.BindBufferMemory(newBlock.blockMemory))
|
||||
throw std::runtime_error("Failed to bind buffer memory: " + TranslateVulkanError(newBlock.buffer.GetLastErrorCode()));
|
||||
throw std::runtime_error("failed to bind buffer memory: " + TranslateVulkanError(newBlock.buffer.GetLastErrorCode()));
|
||||
|
||||
if (!newBlock.blockMemory.Map())
|
||||
throw std::runtime_error("Failed to map buffer memory: " + TranslateVulkanError(newBlock.buffer.GetLastErrorCode()));
|
||||
throw std::runtime_error("failed to map buffer memory: " + TranslateVulkanError(newBlock.buffer.GetLastErrorCode()));
|
||||
|
||||
bestBlock.block = &m_blocks.emplace_back(std::move(newBlock));
|
||||
bestBlock.alignedOffset = 0;
|
||||
|
|
|
|||
Loading…
Reference in New Issue