Add initial support for texture views
This commit is contained in:
parent
902dee6121
commit
42f8cdb151
|
|
@ -12,25 +12,31 @@
|
||||||
#include <Nazara/OpenGLRenderer/Wrapper/Context.hpp>
|
#include <Nazara/OpenGLRenderer/Wrapper/Context.hpp>
|
||||||
#include <Nazara/OpenGLRenderer/Wrapper/Texture.hpp>
|
#include <Nazara/OpenGLRenderer/Wrapper/Texture.hpp>
|
||||||
#include <Nazara/Renderer/Texture.hpp>
|
#include <Nazara/Renderer/Texture.hpp>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
class NAZARA_OPENGLRENDERER_API OpenGLTexture : public Texture
|
class NAZARA_OPENGLRENDERER_API OpenGLTexture : public Texture
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
OpenGLTexture(OpenGLDevice& device, const TextureInfo& params);
|
OpenGLTexture(OpenGLDevice& device, const TextureInfo& textureInfo);
|
||||||
|
OpenGLTexture(std::shared_ptr<OpenGLTexture> parentTexture, const TextureViewInfo& viewInfo);
|
||||||
OpenGLTexture(const OpenGLTexture&) = delete;
|
OpenGLTexture(const OpenGLTexture&) = delete;
|
||||||
OpenGLTexture(OpenGLTexture&&) = delete;
|
OpenGLTexture(OpenGLTexture&&) = delete;
|
||||||
~OpenGLTexture() = default;
|
~OpenGLTexture() = default;
|
||||||
|
|
||||||
bool Copy(const Texture& source, const Boxui& srcBox, const Vector3ui& dstPos) override;
|
bool Copy(const Texture& source, const Boxui& srcBox, const Vector3ui& dstPos) override;
|
||||||
|
std::shared_ptr<Texture> CreateView(const TextureViewInfo& viewInfo) override;
|
||||||
|
|
||||||
PixelFormat GetFormat() const override;
|
PixelFormat GetFormat() const override;
|
||||||
UInt8 GetLevelCount() const override;
|
UInt8 GetLevelCount() const override;
|
||||||
|
OpenGLTexture* GetParentTexture() const override;
|
||||||
Vector3ui GetSize(UInt8 level = 0) const override;
|
Vector3ui GetSize(UInt8 level = 0) const override;
|
||||||
inline const GL::Texture& GetTexture() const;
|
inline const GL::Texture& GetTexture() const;
|
||||||
ImageType GetType() const override;
|
ImageType GetType() const override;
|
||||||
|
|
||||||
|
inline bool RequireTextureViewEmulation() const;
|
||||||
|
|
||||||
using Texture::Update;
|
using Texture::Update;
|
||||||
bool Update(const void* ptr, const Boxui& box, unsigned int srcWidth = 0, unsigned int srcHeight = 0, UInt8 level = 0) override;
|
bool Update(const void* ptr, const Boxui& box, unsigned int srcWidth = 0, unsigned int srcHeight = 0, UInt8 level = 0) override;
|
||||||
|
|
||||||
|
|
@ -42,8 +48,10 @@ namespace Nz
|
||||||
static inline GL::TextureTarget ToTextureTarget(ImageType imageType);
|
static inline GL::TextureTarget ToTextureTarget(ImageType imageType);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::optional<TextureViewInfo> m_viewInfo;
|
||||||
|
std::shared_ptr<OpenGLTexture> m_parentTexture;
|
||||||
GL::Texture m_texture;
|
GL::Texture m_texture;
|
||||||
TextureInfo m_params;
|
TextureInfo m_textureInfo;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,11 @@ namespace Nz
|
||||||
return m_texture;
|
return m_texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool OpenGLTexture::RequireTextureViewEmulation() const
|
||||||
|
{
|
||||||
|
return m_viewInfo.has_value() && !m_texture.IsValid();
|
||||||
|
}
|
||||||
|
|
||||||
inline GL::TextureTarget OpenGLTexture::ToTextureTarget(ImageType imageType)
|
inline GL::TextureTarget OpenGLTexture::ToTextureTarget(ImageType imageType)
|
||||||
{
|
{
|
||||||
switch (imageType)
|
switch (imageType)
|
||||||
|
|
|
||||||
|
|
@ -60,8 +60,9 @@ namespace Nz::GL
|
||||||
StorageBuffers,
|
StorageBuffers,
|
||||||
TextureCompressionS3tc,
|
TextureCompressionS3tc,
|
||||||
TextureFilterAnisotropic,
|
TextureFilterAnisotropic,
|
||||||
|
TextureView,
|
||||||
|
|
||||||
Max = TextureFilterAnisotropic
|
Max = TextureView
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class ExtensionStatus
|
enum class ExtensionStatus
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,9 @@ typedef void (GL_APIENTRYP PFNGLPOLYGONMODEPROC) (GLenum face, GLenum mode);
|
||||||
// Depth clamp (OpenGL 3.2)
|
// Depth clamp (OpenGL 3.2)
|
||||||
#define GL_DEPTH_CLAMP 0x864F
|
#define GL_DEPTH_CLAMP 0x864F
|
||||||
|
|
||||||
|
// Texture views (OpenGL 4.3)
|
||||||
|
typedef void (GL_APIENTRYP PFNGLTEXTUREVIEWPROC) (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers);
|
||||||
|
|
||||||
// Clip control (OpenGL 4.5)
|
// Clip control (OpenGL 4.5)
|
||||||
#define GL_LOWER_LEFT 0x8CA1
|
#define GL_LOWER_LEFT 0x8CA1
|
||||||
#define GL_UPPER_LEFT 0x8CA2
|
#define GL_UPPER_LEFT 0x8CA2
|
||||||
|
|
@ -200,6 +203,8 @@ typedef void (GL_APIENTRYP PFNGLSPECIALIZESHADERPROC) (GLuint shader, const GLch
|
||||||
extCb(glObjectLabel, PFNGLOBJECTLABELPROC) \
|
extCb(glObjectLabel, PFNGLOBJECTLABELPROC) \
|
||||||
extCb(glPopDebugGroup, PFNGLPOPDEBUGGROUPPROC) \
|
extCb(glPopDebugGroup, PFNGLPOPDEBUGGROUPPROC) \
|
||||||
extCb(glPushDebugGroup, PFNGLPUSHDEBUGGROUPPROC) \
|
extCb(glPushDebugGroup, PFNGLPUSHDEBUGGROUPPROC) \
|
||||||
|
/* OpenGL 4.3 - GL_ARB_texture_view */ \
|
||||||
|
extCb(glTextureView, PFNGLTEXTUREVIEWPROC) \
|
||||||
/* OpenGL 4.5 - GL_ARB_clip_control/GL_EXT_clip_control */ \
|
/* OpenGL 4.5 - GL_ARB_clip_control/GL_EXT_clip_control */ \
|
||||||
extCb(glClipControl, PFNGLCLIPCONTROLPROC) \
|
extCb(glClipControl, PFNGLCLIPCONTROLPROC) \
|
||||||
/* OpenGL 4.6 - GL_ARB_spirv_extensions */\
|
/* OpenGL 4.6 - GL_ARB_spirv_extensions */\
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ namespace Nz::GL
|
||||||
inline void TexStorage3D(TextureTarget target, GLint levels, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth);
|
inline void TexStorage3D(TextureTarget target, GLint levels, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth);
|
||||||
inline void TexSubImage2D(TextureTarget target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* data);
|
inline void TexSubImage2D(TextureTarget target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* data);
|
||||||
inline void TexSubImage3D(TextureTarget target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* data);
|
inline void TexSubImage3D(TextureTarget target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* data);
|
||||||
|
inline void TextureView(GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers);
|
||||||
|
|
||||||
Texture& operator=(const Texture&) = delete;
|
Texture& operator=(const Texture&) = delete;
|
||||||
Texture& operator=(Texture&&) noexcept = default;
|
Texture& operator=(Texture&&) noexcept = default;
|
||||||
|
|
|
||||||
|
|
@ -111,6 +111,12 @@ namespace Nz::GL
|
||||||
//< TODO: Handle errors
|
//< TODO: Handle errors
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void Texture::TextureView(GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers)
|
||||||
|
{
|
||||||
|
const Context& context = EnsureDeviceContext();
|
||||||
|
context.glTextureView(m_objectId, target, origtexture, internalformat, minlevel, numlevels, minlayer, numlayers);
|
||||||
|
}
|
||||||
|
|
||||||
inline GLuint Texture::CreateHelper(OpenGLDevice& /*device*/, const Context& context)
|
inline GLuint Texture::CreateHelper(OpenGLDevice& /*device*/, const Context& context)
|
||||||
{
|
{
|
||||||
GLuint texture = 0;
|
GLuint texture = 0;
|
||||||
|
|
|
||||||
|
|
@ -26,13 +26,23 @@ namespace Nz
|
||||||
PixelFormat pixelFormat;
|
PixelFormat pixelFormat;
|
||||||
ImageType type;
|
ImageType type;
|
||||||
TextureUsageFlags usageFlags = TextureUsage::ShaderSampling | TextureUsage::TransferDestination;
|
TextureUsageFlags usageFlags = TextureUsage::ShaderSampling | TextureUsage::TransferDestination;
|
||||||
UInt8 mipmapLevel = 1;
|
UInt8 levelCount = 1;
|
||||||
unsigned int layerCount = 1;
|
unsigned int layerCount = 1;
|
||||||
unsigned int depth = 1;
|
unsigned int depth = 1;
|
||||||
unsigned int height;
|
unsigned int height;
|
||||||
unsigned int width;
|
unsigned int width;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TextureViewInfo
|
||||||
|
{
|
||||||
|
ImageType viewType;
|
||||||
|
PixelFormat reinterpretFormat;
|
||||||
|
UInt8 baseMipLevel = 0;
|
||||||
|
UInt8 levelCount = 1;
|
||||||
|
unsigned int baseArrayLayer = 0;
|
||||||
|
unsigned int layerCount = 1;
|
||||||
|
};
|
||||||
|
|
||||||
struct NAZARA_RENDERER_API TextureParams : ImageParams
|
struct NAZARA_RENDERER_API TextureParams : ImageParams
|
||||||
{
|
{
|
||||||
std::shared_ptr<RenderDevice> renderDevice;
|
std::shared_ptr<RenderDevice> renderDevice;
|
||||||
|
|
@ -56,9 +66,11 @@ namespace Nz
|
||||||
virtual ~Texture();
|
virtual ~Texture();
|
||||||
|
|
||||||
virtual bool Copy(const Texture& source, const Boxui& srcBox, const Vector3ui& dstPos = Vector3ui::Zero()) = 0;
|
virtual bool Copy(const Texture& source, const Boxui& srcBox, const Vector3ui& dstPos = Vector3ui::Zero()) = 0;
|
||||||
|
virtual std::shared_ptr<Texture> CreateView(const TextureViewInfo& viewInfo) = 0;
|
||||||
|
|
||||||
virtual PixelFormat GetFormat() const = 0;
|
virtual PixelFormat GetFormat() const = 0;
|
||||||
virtual UInt8 GetLevelCount() const = 0;
|
virtual UInt8 GetLevelCount() const = 0;
|
||||||
|
virtual Texture* GetParentTexture() const = 0;
|
||||||
virtual Vector3ui GetSize(UInt8 level = 0) const = 0;
|
virtual Vector3ui GetSize(UInt8 level = 0) const = 0;
|
||||||
virtual ImageType GetType() const = 0;
|
virtual ImageType GetType() const = 0;
|
||||||
|
|
||||||
|
|
@ -67,6 +79,7 @@ namespace Nz
|
||||||
Texture& operator=(const Texture&) = delete;
|
Texture& operator=(const Texture&) = delete;
|
||||||
Texture& operator=(Texture&&) = delete;
|
Texture& operator=(Texture&&) = delete;
|
||||||
|
|
||||||
|
static inline TextureInfo ApplyView(TextureInfo textureInfo, const TextureViewInfo& viewInfo);
|
||||||
static inline unsigned int GetLevelSize(unsigned int size, unsigned int level);
|
static inline unsigned int GetLevelSize(unsigned int size, unsigned int level);
|
||||||
|
|
||||||
static std::shared_ptr<Texture> CreateFromImage(const Image& image, const TextureParams& params);
|
static std::shared_ptr<Texture> CreateFromImage(const Image& image, const TextureParams& params);
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,19 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
inline TextureInfo Texture::ApplyView(TextureInfo textureInfo, const TextureViewInfo& viewInfo)
|
||||||
|
{
|
||||||
|
textureInfo.type = viewInfo.viewType;
|
||||||
|
textureInfo.pixelFormat = viewInfo.reinterpretFormat;
|
||||||
|
textureInfo.width = GetLevelSize(textureInfo.width, viewInfo.baseMipLevel);
|
||||||
|
textureInfo.height = GetLevelSize(textureInfo.height, viewInfo.baseMipLevel);
|
||||||
|
textureInfo.depth = GetLevelSize(textureInfo.depth, viewInfo.baseMipLevel);
|
||||||
|
textureInfo.levelCount = (textureInfo.levelCount > viewInfo.baseMipLevel) ? (textureInfo.levelCount - viewInfo.baseMipLevel) : 1;
|
||||||
|
textureInfo.layerCount = (textureInfo.layerCount > viewInfo.baseArrayLayer) ? (textureInfo.layerCount - viewInfo.baseArrayLayer) : 1;
|
||||||
|
|
||||||
|
return textureInfo;
|
||||||
|
}
|
||||||
|
|
||||||
inline unsigned int Texture::GetLevelSize(unsigned int size, unsigned int level)
|
inline unsigned int Texture::GetLevelSize(unsigned int size, unsigned int level)
|
||||||
{
|
{
|
||||||
if (size == 0) // Possible dans le cas d'une image invalide
|
if (size == 0) // Possible dans le cas d'une image invalide
|
||||||
|
|
|
||||||
|
|
@ -18,17 +18,20 @@ namespace Nz
|
||||||
class NAZARA_VULKANRENDERER_API VulkanTexture : public Texture
|
class NAZARA_VULKANRENDERER_API VulkanTexture : public Texture
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
VulkanTexture(Vk::Device& device, const TextureInfo& params);
|
VulkanTexture(Vk::Device& device, const TextureInfo& textureInfo);
|
||||||
|
VulkanTexture(std::shared_ptr<VulkanTexture> parentTexture, const TextureViewInfo& viewInfo);
|
||||||
VulkanTexture(const VulkanTexture&) = delete;
|
VulkanTexture(const VulkanTexture&) = delete;
|
||||||
VulkanTexture(VulkanTexture&&) = delete;
|
VulkanTexture(VulkanTexture&&) = delete;
|
||||||
~VulkanTexture();
|
~VulkanTexture();
|
||||||
|
|
||||||
bool Copy(const Texture& source, const Boxui& srcBox, const Vector3ui& dstPos) override;
|
bool Copy(const Texture& source, const Boxui& srcBox, const Vector3ui& dstPos) override;
|
||||||
|
std::shared_ptr<Texture> CreateView(const TextureViewInfo& viewInfo) override;
|
||||||
|
|
||||||
PixelFormat GetFormat() const override;
|
PixelFormat GetFormat() const override;
|
||||||
inline VkImage GetImage() const;
|
inline VkImage GetImage() const;
|
||||||
inline VkImageView GetImageView() const;
|
inline VkImageView GetImageView() const;
|
||||||
UInt8 GetLevelCount() const override;
|
UInt8 GetLevelCount() const override;
|
||||||
|
VulkanTexture* GetParentTexture() const override;
|
||||||
Vector3ui GetSize(UInt8 level = 0) const override;
|
Vector3ui GetSize(UInt8 level = 0) const override;
|
||||||
ImageType GetType() const override;
|
ImageType GetType() const override;
|
||||||
|
|
||||||
|
|
@ -43,11 +46,12 @@ namespace Nz
|
||||||
private:
|
private:
|
||||||
static void InitViewForFormat(PixelFormat pixelFormat, VkImageViewCreateInfo& createImageView);
|
static void InitViewForFormat(PixelFormat pixelFormat, VkImageViewCreateInfo& createImageView);
|
||||||
|
|
||||||
|
std::shared_ptr<VulkanTexture> m_parentTexture;
|
||||||
VkImage m_image;
|
VkImage m_image;
|
||||||
VmaAllocation m_allocation;
|
VmaAllocation m_allocation;
|
||||||
Vk::Device& m_device;
|
Vk::Device& m_device;
|
||||||
Vk::ImageView m_imageView;
|
Vk::ImageView m_imageView;
|
||||||
TextureInfo m_params;
|
TextureInfo m_textureInfo;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -329,7 +329,7 @@ namespace Nz
|
||||||
throw std::runtime_error("couldn't find a sampling-compatible depth pixel format");
|
throw std::runtime_error("couldn't find a sampling-compatible depth pixel format");
|
||||||
|
|
||||||
TextureInfo texInfo;
|
TextureInfo texInfo;
|
||||||
texInfo.width = texInfo.height = texInfo.depth = texInfo.mipmapLevel = 1;
|
texInfo.width = texInfo.height = texInfo.depth = texInfo.levelCount = 1;
|
||||||
texInfo.pixelFormat = depthFormat;
|
texInfo.pixelFormat = depthFormat;
|
||||||
|
|
||||||
std::array<UInt8, 6> whitePixels = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
std::array<UInt8, 6> whitePixels = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||||
|
|
@ -350,7 +350,7 @@ namespace Nz
|
||||||
// White texture 2D
|
// White texture 2D
|
||||||
{
|
{
|
||||||
TextureInfo texInfo;
|
TextureInfo texInfo;
|
||||||
texInfo.width = texInfo.height = texInfo.depth = texInfo.mipmapLevel = 1;
|
texInfo.width = texInfo.height = texInfo.depth = texInfo.levelCount = 1;
|
||||||
texInfo.pixelFormat = PixelFormat::L8;
|
texInfo.pixelFormat = PixelFormat::L8;
|
||||||
|
|
||||||
std::array<UInt8, 6> whitePixels = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
std::array<UInt8, 6> whitePixels = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||||
|
|
|
||||||
|
|
@ -10,57 +10,87 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
OpenGLTexture::OpenGLTexture(OpenGLDevice& device, const TextureInfo& params) :
|
OpenGLTexture::OpenGLTexture(OpenGLDevice& device, const TextureInfo& textureInfo) :
|
||||||
m_params(params)
|
m_textureInfo(textureInfo)
|
||||||
{
|
{
|
||||||
if (!m_texture.Create(device))
|
if (!m_texture.Create(device))
|
||||||
throw std::runtime_error("failed to create texture object");
|
throw std::runtime_error("failed to create texture object");
|
||||||
|
|
||||||
auto format = DescribeTextureFormat(params.pixelFormat);
|
auto format = DescribeTextureFormat(textureInfo.pixelFormat);
|
||||||
if (!format)
|
if (!format)
|
||||||
throw std::runtime_error("unsupported texture format");
|
throw std::runtime_error("unsupported texture format");
|
||||||
|
|
||||||
const GL::Context& context = m_texture.EnsureDeviceContext();
|
const GL::Context& context = m_texture.EnsureDeviceContext();
|
||||||
context.ClearErrorStack();
|
context.ClearErrorStack();
|
||||||
|
|
||||||
switch (params.type)
|
switch (textureInfo.type)
|
||||||
{
|
{
|
||||||
case ImageType::E2D:
|
case ImageType::E2D:
|
||||||
m_texture.TexStorage2D(GL::TextureTarget::Target2D, params.mipmapLevel, format->internalFormat, params.width, params.height);
|
m_texture.TexStorage2D(GL::TextureTarget::Target2D, textureInfo.levelCount, format->internalFormat, textureInfo.width, textureInfo.height);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ImageType::E2D_Array:
|
case ImageType::E2D_Array:
|
||||||
m_texture.TexStorage3D(GL::TextureTarget::Target2D_Array, params.mipmapLevel, format->internalFormat, params.width, params.height, params.layerCount);
|
m_texture.TexStorage3D(GL::TextureTarget::Target2D_Array, textureInfo.levelCount, format->internalFormat, textureInfo.width, textureInfo.height, textureInfo.layerCount);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ImageType::E3D:
|
case ImageType::E3D:
|
||||||
m_texture.TexStorage3D(GL::TextureTarget::Target3D, params.mipmapLevel, format->internalFormat, params.width, params.height, params.depth);
|
m_texture.TexStorage3D(GL::TextureTarget::Target3D, textureInfo.levelCount, format->internalFormat, textureInfo.width, textureInfo.height, textureInfo.depth);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ImageType::Cubemap:
|
case ImageType::Cubemap:
|
||||||
m_texture.TexStorage2D(GL::TextureTarget::Cubemap, params.mipmapLevel, format->internalFormat, params.width, params.height);
|
m_texture.TexStorage2D(GL::TextureTarget::Cubemap, textureInfo.levelCount, format->internalFormat, textureInfo.width, textureInfo.height);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// OpenGL ES doesn't support 1D textures, use 2D textures with a height of 1 instead
|
// OpenGL ES doesn't support 1D textures, use 2D textures with a height of 1 instead
|
||||||
case ImageType::E1D:
|
case ImageType::E1D:
|
||||||
m_texture.TexStorage2D(GL::TextureTarget::Target2D, params.mipmapLevel, format->internalFormat, params.width, 1);
|
m_texture.TexStorage2D(GL::TextureTarget::Target2D, textureInfo.levelCount, format->internalFormat, textureInfo.width, 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ImageType::E1D_Array:
|
case ImageType::E1D_Array:
|
||||||
m_texture.TexStorage2D(GL::TextureTarget::Target2D, params.mipmapLevel, format->internalFormat, params.width, params.layerCount);
|
m_texture.TexStorage2D(GL::TextureTarget::Target2D, textureInfo.levelCount, format->internalFormat, textureInfo.width, textureInfo.layerCount);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!context.DidLastCallSucceed())
|
if (!context.DidLastCallSucceed())
|
||||||
throw std::runtime_error("failed to create texture");
|
throw std::runtime_error("failed to create texture");
|
||||||
|
|
||||||
m_texture.SetParameteri(GL_TEXTURE_MAX_LEVEL, m_params.mipmapLevel);
|
m_texture.SetParameteri(GL_TEXTURE_MAX_LEVEL, m_textureInfo.levelCount);
|
||||||
m_texture.SetParameteri(GL_TEXTURE_SWIZZLE_R, format->swizzleR);
|
m_texture.SetParameteri(GL_TEXTURE_SWIZZLE_R, format->swizzleR);
|
||||||
m_texture.SetParameteri(GL_TEXTURE_SWIZZLE_G, format->swizzleG);
|
m_texture.SetParameteri(GL_TEXTURE_SWIZZLE_G, format->swizzleG);
|
||||||
m_texture.SetParameteri(GL_TEXTURE_SWIZZLE_B, format->swizzleB);
|
m_texture.SetParameteri(GL_TEXTURE_SWIZZLE_B, format->swizzleB);
|
||||||
m_texture.SetParameteri(GL_TEXTURE_SWIZZLE_A, format->swizzleA);
|
m_texture.SetParameteri(GL_TEXTURE_SWIZZLE_A, format->swizzleA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OpenGLTexture::OpenGLTexture(std::shared_ptr<OpenGLTexture> parentTexture, const TextureViewInfo& viewInfo) :
|
||||||
|
m_parentTexture(std::move(parentTexture))
|
||||||
|
{
|
||||||
|
const GL::Context& context = m_parentTexture->m_texture.EnsureDeviceContext();
|
||||||
|
|
||||||
|
NazaraAssert(viewInfo.layerCount <= m_parentTexture->m_textureInfo.layerCount - viewInfo.baseArrayLayer, "layer count exceeds number of layers");
|
||||||
|
NazaraAssert(viewInfo.levelCount <= m_parentTexture->m_textureInfo.levelCount - viewInfo.baseMipLevel, "level count exceeds number of levels");
|
||||||
|
|
||||||
|
m_viewInfo = viewInfo;
|
||||||
|
|
||||||
|
// Try to use texture views if supported (core in GL 4.3 or extension)
|
||||||
|
if (context.IsExtensionSupported(GL::Extension::TextureView))
|
||||||
|
{
|
||||||
|
if (m_texture.Create(*m_parentTexture->m_texture.GetDevice()))
|
||||||
|
{
|
||||||
|
auto format = DescribeTextureFormat(viewInfo.reinterpretFormat);
|
||||||
|
GLenum target = ToOpenGL(ToTextureTarget(viewInfo.viewType));
|
||||||
|
|
||||||
|
context.ClearErrorStack();
|
||||||
|
|
||||||
|
m_texture.TextureView(target, m_parentTexture->m_texture.GetObjectId(), format->internalFormat, viewInfo.baseMipLevel, viewInfo.levelCount, viewInfo.baseArrayLayer, viewInfo.layerCount);
|
||||||
|
|
||||||
|
if (!context.DidLastCallSucceed())
|
||||||
|
m_texture.Destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If texture views are not supported, they will be emulated when using them as attachments
|
||||||
|
}
|
||||||
|
|
||||||
bool OpenGLTexture::Copy(const Texture& source, const Boxui& srcBox, const Vector3ui& dstPos)
|
bool OpenGLTexture::Copy(const Texture& source, const Boxui& srcBox, const Vector3ui& dstPos)
|
||||||
{
|
{
|
||||||
const OpenGLTexture& glTexture = static_cast<const OpenGLTexture&>(source);
|
const OpenGLTexture& glTexture = static_cast<const OpenGLTexture&>(source);
|
||||||
|
|
@ -69,34 +99,57 @@ namespace Nz
|
||||||
return context.CopyTexture(glTexture.GetTexture(), m_texture, srcBox, dstPos);
|
return context.CopyTexture(glTexture.GetTexture(), m_texture, srcBox, dstPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Texture> OpenGLTexture::CreateView(const TextureViewInfo& viewInfo)
|
||||||
|
{
|
||||||
|
if (m_parentTexture)
|
||||||
|
{
|
||||||
|
assert(m_viewInfo);
|
||||||
|
NazaraAssert(viewInfo.layerCount <= m_viewInfo->layerCount - viewInfo.baseArrayLayer, "layer count exceeds number of layers");
|
||||||
|
NazaraAssert(viewInfo.levelCount <= m_viewInfo->levelCount - viewInfo.baseMipLevel, "level count exceeds number of levels");
|
||||||
|
|
||||||
|
TextureViewInfo ajustedView = viewInfo;
|
||||||
|
ajustedView.baseArrayLayer += m_viewInfo->baseArrayLayer;
|
||||||
|
ajustedView.baseMipLevel += m_viewInfo->baseMipLevel;
|
||||||
|
|
||||||
|
return m_parentTexture->CreateView(ajustedView);
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_shared<OpenGLTexture>(std::static_pointer_cast<OpenGLTexture>(shared_from_this()), viewInfo);
|
||||||
|
}
|
||||||
|
|
||||||
PixelFormat OpenGLTexture::GetFormat() const
|
PixelFormat OpenGLTexture::GetFormat() const
|
||||||
{
|
{
|
||||||
return m_params.pixelFormat;
|
return m_textureInfo.pixelFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt8 OpenGLTexture::GetLevelCount() const
|
UInt8 OpenGLTexture::GetLevelCount() const
|
||||||
{
|
{
|
||||||
return m_params.mipmapLevel;
|
return m_textureInfo.levelCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenGLTexture* OpenGLTexture::GetParentTexture() const
|
||||||
|
{
|
||||||
|
return m_parentTexture.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3ui OpenGLTexture::GetSize(UInt8 level) const
|
Vector3ui OpenGLTexture::GetSize(UInt8 level) const
|
||||||
{
|
{
|
||||||
return Vector3ui(GetLevelSize(m_params.width, level), GetLevelSize(m_params.height, level), GetLevelSize(m_params.depth, level));
|
return Vector3ui(GetLevelSize(m_textureInfo.width, level), GetLevelSize(m_textureInfo.height, level), GetLevelSize(m_textureInfo.depth, level));
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageType OpenGLTexture::GetType() const
|
ImageType OpenGLTexture::GetType() const
|
||||||
{
|
{
|
||||||
return m_params.type;
|
return m_textureInfo.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenGLTexture::Update(const void* ptr, const Boxui& box, unsigned int srcWidth, unsigned int srcHeight, UInt8 level)
|
bool OpenGLTexture::Update(const void* ptr, const Boxui& box, unsigned int srcWidth, unsigned int srcHeight, UInt8 level)
|
||||||
{
|
{
|
||||||
auto format = DescribeTextureFormat(m_params.pixelFormat);
|
auto format = DescribeTextureFormat(m_textureInfo.pixelFormat);
|
||||||
assert(format);
|
assert(format);
|
||||||
|
|
||||||
const GL::Context& context = m_texture.EnsureDeviceContext();
|
const GL::Context& context = m_texture.EnsureDeviceContext();
|
||||||
|
|
||||||
UInt8 bpp = PixelFormatInfo::GetBytesPerPixel(m_params.pixelFormat);
|
UInt8 bpp = PixelFormatInfo::GetBytesPerPixel(m_textureInfo.pixelFormat);
|
||||||
if (bpp % 8 == 0)
|
if (bpp % 8 == 0)
|
||||||
context.glPixelStorei(GL_UNPACK_ALIGNMENT, 8);
|
context.glPixelStorei(GL_UNPACK_ALIGNMENT, 8);
|
||||||
else if (bpp % 4 == 0)
|
else if (bpp % 4 == 0)
|
||||||
|
|
@ -109,7 +162,7 @@ namespace Nz
|
||||||
context.glPixelStorei(GL_UNPACK_ROW_LENGTH, srcWidth);
|
context.glPixelStorei(GL_UNPACK_ROW_LENGTH, srcWidth);
|
||||||
context.glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, srcHeight);
|
context.glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, srcHeight);
|
||||||
|
|
||||||
switch (m_params.type)
|
switch (m_textureInfo.type)
|
||||||
{
|
{
|
||||||
case ImageType::E1D:
|
case ImageType::E1D:
|
||||||
break;
|
break;
|
||||||
|
|
@ -129,7 +182,7 @@ namespace Nz
|
||||||
|
|
||||||
case ImageType::Cubemap:
|
case ImageType::Cubemap:
|
||||||
{
|
{
|
||||||
std::size_t faceSize = PixelFormatInfo::ComputeSize(m_params.pixelFormat, m_params.width, m_params.height, 1);
|
std::size_t faceSize = PixelFormatInfo::ComputeSize(m_textureInfo.pixelFormat, m_textureInfo.width, m_textureInfo.height, 1);
|
||||||
const UInt8* facePtr = static_cast<const UInt8*>(ptr);
|
const UInt8* facePtr = static_cast<const UInt8*>(ptr);
|
||||||
|
|
||||||
for (GL::TextureTarget face : { GL::TextureTarget::CubemapPositiveX, GL::TextureTarget::CubemapNegativeX, GL::TextureTarget::CubemapPositiveY, GL::TextureTarget::CubemapNegativeY, GL::TextureTarget::CubemapPositiveZ, GL::TextureTarget::CubemapNegativeZ })
|
for (GL::TextureTarget face : { GL::TextureTarget::CubemapPositiveX, GL::TextureTarget::CubemapNegativeX, GL::TextureTarget::CubemapPositiveY, GL::TextureTarget::CubemapNegativeY, GL::TextureTarget::CubemapPositiveZ, GL::TextureTarget::CubemapNegativeZ })
|
||||||
|
|
|
||||||
|
|
@ -446,6 +446,16 @@ namespace Nz::GL
|
||||||
else if (m_supportedExtensions.count("GL_EXT_texture_filter_anisotropic"))
|
else if (m_supportedExtensions.count("GL_EXT_texture_filter_anisotropic"))
|
||||||
m_extensionStatus[UnderlyingCast(Extension::TextureFilterAnisotropic)] = ExtensionStatus::EXT;
|
m_extensionStatus[UnderlyingCast(Extension::TextureFilterAnisotropic)] = ExtensionStatus::EXT;
|
||||||
|
|
||||||
|
// Texture view
|
||||||
|
if (m_params.type == ContextType::OpenGL && glVersion >= 430)
|
||||||
|
m_extensionStatus[UnderlyingCast(Extension::TextureView)] = ExtensionStatus::Core;
|
||||||
|
else if (m_supportedExtensions.count("GL_ARB_texture_view"))
|
||||||
|
m_extensionStatus[UnderlyingCast(Extension::TextureView)] = ExtensionStatus::ARB;
|
||||||
|
else if (m_supportedExtensions.count("GL_OES_texture_view"))
|
||||||
|
m_extensionStatus[UnderlyingCast(Extension::TextureView)] = ExtensionStatus::KHR; //< not sure about the OES => KHR mapping
|
||||||
|
else if (m_supportedExtensions.count("GL_EXT_texture_view"))
|
||||||
|
m_extensionStatus[UnderlyingCast(Extension::TextureView)] = ExtensionStatus::EXT; //< not sure about the OES => KHR mapping
|
||||||
|
|
||||||
#define NAZARA_OPENGLRENDERER_FUNC(name, sig)
|
#define NAZARA_OPENGLRENDERER_FUNC(name, sig)
|
||||||
#define NAZARA_OPENGLRENDERER_EXT_FUNC(name, sig) loader.Load<sig, UnderlyingCast(FunctionIndex:: name)>(name, #name, false);
|
#define NAZARA_OPENGLRENDERER_EXT_FUNC(name, sig) loader.Load<sig, UnderlyingCast(FunctionIndex:: name)>(name, #name, false);
|
||||||
NAZARA_OPENGLRENDERER_FOREACH_GLES_FUNC(NAZARA_OPENGLRENDERER_FUNC, NAZARA_OPENGLRENDERER_EXT_FUNC)
|
NAZARA_OPENGLRENDERER_FOREACH_GLES_FUNC(NAZARA_OPENGLRENDERER_FUNC, NAZARA_OPENGLRENDERER_EXT_FUNC)
|
||||||
|
|
@ -959,6 +969,12 @@ namespace Nz::GL
|
||||||
constexpr std::size_t functionIndex = UnderlyingCast(FunctionIndex::glSpecializeShader);
|
constexpr std::size_t functionIndex = UnderlyingCast(FunctionIndex::glSpecializeShader);
|
||||||
return loader.Load<PFNGLSPECIALIZESHADERPROC, functionIndex>(glSpecializeShader, "glSpecializeShaderARB", false); //< from GL_ARB_spirv_extensions
|
return loader.Load<PFNGLSPECIALIZESHADERPROC, functionIndex>(glSpecializeShader, "glSpecializeShaderARB", false); //< from GL_ARB_spirv_extensions
|
||||||
}
|
}
|
||||||
|
else if (function == "glTextureView")
|
||||||
|
{
|
||||||
|
constexpr std::size_t functionIndex = UnderlyingCast(FunctionIndex::glTextureView);
|
||||||
|
return loader.Load<PFNGLTEXTUREVIEWPROC, functionIndex>(glTextureView, "glTextureViewOES", false) ||
|
||||||
|
loader.Load<PFNGLTEXTUREVIEWPROC, functionIndex>(glTextureView, "glTextureViewEXT", false); //< from GL_EXT_texture_view
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,15 +13,15 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
VulkanTexture::VulkanTexture(Vk::Device& device, const TextureInfo& params) :
|
VulkanTexture::VulkanTexture(Vk::Device& device, const TextureInfo& textureInfo) :
|
||||||
m_image(VK_NULL_HANDLE),
|
m_image(VK_NULL_HANDLE),
|
||||||
m_allocation(nullptr),
|
m_allocation(nullptr),
|
||||||
m_device(device),
|
m_device(device),
|
||||||
m_params(params)
|
m_textureInfo(textureInfo)
|
||||||
{
|
{
|
||||||
VkImageViewCreateInfo createInfoView = {};
|
VkImageViewCreateInfo createInfoView = {};
|
||||||
createInfoView.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
createInfoView.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||||
InitViewForFormat(params.pixelFormat, createInfoView);
|
InitViewForFormat(textureInfo.pixelFormat, createInfoView);
|
||||||
|
|
||||||
VkImageCreateInfo createInfo = {};
|
VkImageCreateInfo createInfo = {};
|
||||||
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||||
|
|
@ -29,66 +29,66 @@ namespace Nz
|
||||||
createInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
createInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
createInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
createInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
createInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
createInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||||
createInfo.usage = ToVulkan(params.usageFlags);
|
createInfo.usage = ToVulkan(textureInfo.usageFlags);
|
||||||
|
|
||||||
switch (params.type)
|
switch (textureInfo.type)
|
||||||
{
|
{
|
||||||
case ImageType::E1D:
|
case ImageType::E1D:
|
||||||
NazaraAssert(params.width > 0, "Width must be over zero");
|
NazaraAssert(textureInfo.width > 0, "Width must be over zero");
|
||||||
NazaraAssert(params.height == 1, "Height must be one");
|
NazaraAssert(textureInfo.height == 1, "Height must be one");
|
||||||
NazaraAssert(params.depth == 1, "Depth must be one");
|
NazaraAssert(textureInfo.depth == 1, "Depth must be one");
|
||||||
NazaraAssert(params.layerCount == 1, "Array count must be one");
|
NazaraAssert(textureInfo.layerCount == 1, "Array count must be one");
|
||||||
|
|
||||||
createInfo.imageType = VK_IMAGE_TYPE_1D;
|
createInfo.imageType = VK_IMAGE_TYPE_1D;
|
||||||
createInfoView.viewType = VK_IMAGE_VIEW_TYPE_1D;
|
createInfoView.viewType = VK_IMAGE_VIEW_TYPE_1D;
|
||||||
createInfo.extent.width = params.width;
|
createInfo.extent.width = textureInfo.width;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ImageType::E1D_Array:
|
case ImageType::E1D_Array:
|
||||||
NazaraAssert(params.width > 0, "Width must be over zero");
|
NazaraAssert(textureInfo.width > 0, "Width must be over zero");
|
||||||
NazaraAssert(params.height == 1, "Height must be one");
|
NazaraAssert(textureInfo.height == 1, "Height must be one");
|
||||||
NazaraAssert(params.depth == 1, "Depth must be one");
|
NazaraAssert(textureInfo.depth == 1, "Depth must be one");
|
||||||
NazaraAssert(params.layerCount > 0, "Array count must be over zero");
|
NazaraAssert(textureInfo.layerCount > 0, "Array count must be over zero");
|
||||||
|
|
||||||
createInfo.imageType = VK_IMAGE_TYPE_1D;
|
createInfo.imageType = VK_IMAGE_TYPE_1D;
|
||||||
createInfoView.viewType = VK_IMAGE_VIEW_TYPE_1D_ARRAY;
|
createInfoView.viewType = VK_IMAGE_VIEW_TYPE_1D_ARRAY;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ImageType::E2D:
|
case ImageType::E2D:
|
||||||
NazaraAssert(params.width > 0, "Width must be over zero");
|
NazaraAssert(textureInfo.width > 0, "Width must be over zero");
|
||||||
NazaraAssert(params.height > 0, "Height must be over zero");
|
NazaraAssert(textureInfo.height > 0, "Height must be over zero");
|
||||||
NazaraAssert(params.depth == 1, "Depth must be one");
|
NazaraAssert(textureInfo.depth == 1, "Depth must be one");
|
||||||
NazaraAssert(params.layerCount == 1, "Array count must be one");
|
NazaraAssert(textureInfo.layerCount == 1, "Array count must be one");
|
||||||
|
|
||||||
createInfo.imageType = VK_IMAGE_TYPE_2D;
|
createInfo.imageType = VK_IMAGE_TYPE_2D;
|
||||||
createInfoView.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
createInfoView.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ImageType::E2D_Array:
|
case ImageType::E2D_Array:
|
||||||
NazaraAssert(params.width > 0, "Width must be over zero");
|
NazaraAssert(textureInfo.width > 0, "Width must be over zero");
|
||||||
NazaraAssert(params.height > 0, "Height must be over zero");
|
NazaraAssert(textureInfo.height > 0, "Height must be over zero");
|
||||||
NazaraAssert(params.depth == 1, "Depth must be one");
|
NazaraAssert(textureInfo.depth == 1, "Depth must be one");
|
||||||
NazaraAssert(params.layerCount > 0, "Array count must be over zero");
|
NazaraAssert(textureInfo.layerCount > 0, "Array count must be over zero");
|
||||||
|
|
||||||
createInfo.imageType = VK_IMAGE_TYPE_2D;
|
createInfo.imageType = VK_IMAGE_TYPE_2D;
|
||||||
createInfoView.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
|
createInfoView.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ImageType::E3D:
|
case ImageType::E3D:
|
||||||
NazaraAssert(params.width > 0, "Width must be over zero");
|
NazaraAssert(textureInfo.width > 0, "Width must be over zero");
|
||||||
NazaraAssert(params.height > 0, "Height must be over zero");
|
NazaraAssert(textureInfo.height > 0, "Height must be over zero");
|
||||||
NazaraAssert(params.depth > 0, "Depth must be over zero");
|
NazaraAssert(textureInfo.depth > 0, "Depth must be over zero");
|
||||||
NazaraAssert(params.layerCount == 1, "Array count must be one");
|
NazaraAssert(textureInfo.layerCount == 1, "Array count must be one");
|
||||||
|
|
||||||
createInfo.imageType = VK_IMAGE_TYPE_3D;
|
createInfo.imageType = VK_IMAGE_TYPE_3D;
|
||||||
createInfoView.viewType = VK_IMAGE_VIEW_TYPE_3D;
|
createInfoView.viewType = VK_IMAGE_VIEW_TYPE_3D;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ImageType::Cubemap:
|
case ImageType::Cubemap:
|
||||||
NazaraAssert(params.width > 0, "Width must be over zero");
|
NazaraAssert(textureInfo.width > 0, "Width must be over zero");
|
||||||
NazaraAssert(params.height > 0, "Height must be over zero");
|
NazaraAssert(textureInfo.height > 0, "Height must be over zero");
|
||||||
NazaraAssert(params.depth == 1, "Depth must be one");
|
NazaraAssert(textureInfo.depth == 1, "Depth must be one");
|
||||||
NazaraAssert(params.layerCount % 6 == 0, "Array count must be a multiple of 6");
|
NazaraAssert(textureInfo.layerCount % 6 == 0, "Array count must be a multiple of 6");
|
||||||
|
|
||||||
createInfo.imageType = VK_IMAGE_TYPE_2D;
|
createInfo.imageType = VK_IMAGE_TYPE_2D;
|
||||||
createInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
|
createInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
|
||||||
|
|
@ -99,11 +99,11 @@ namespace Nz
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
createInfo.extent.width = params.width;
|
createInfo.extent.width = textureInfo.width;
|
||||||
createInfo.extent.height = params.height;
|
createInfo.extent.height = textureInfo.height;
|
||||||
createInfo.extent.depth = params.depth;
|
createInfo.extent.depth = textureInfo.depth;
|
||||||
createInfo.arrayLayers = params.layerCount;
|
createInfo.arrayLayers = textureInfo.layerCount;
|
||||||
createInfo.mipLevels = params.mipmapLevel;
|
createInfo.mipLevels = textureInfo.levelCount;
|
||||||
|
|
||||||
VmaAllocationCreateInfo allocInfo = {};
|
VmaAllocationCreateInfo allocInfo = {};
|
||||||
allocInfo.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
|
allocInfo.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
|
||||||
|
|
@ -115,7 +115,7 @@ namespace Nz
|
||||||
CallOnExit releaseImage([&]{ vmaDestroyImage(m_device.GetMemoryAllocator(), m_image, m_allocation); });
|
CallOnExit releaseImage([&]{ vmaDestroyImage(m_device.GetMemoryAllocator(), m_image, m_allocation); });
|
||||||
|
|
||||||
createInfoView.subresourceRange = {
|
createInfoView.subresourceRange = {
|
||||||
ToVulkan(PixelFormatInfo::GetContent(params.pixelFormat)),
|
ToVulkan(PixelFormatInfo::GetContent(textureInfo.pixelFormat)),
|
||||||
0, //< baseMipLevel
|
0, //< baseMipLevel
|
||||||
createInfo.mipLevels, //< levelCount
|
createInfo.mipLevels, //< levelCount
|
||||||
0, //< baseArrayLayer
|
0, //< baseArrayLayer
|
||||||
|
|
@ -128,17 +128,40 @@ namespace Nz
|
||||||
throw std::runtime_error("Failed to create default image view: " + TranslateVulkanError(m_imageView.GetLastErrorCode()));
|
throw std::runtime_error("Failed to create default image view: " + TranslateVulkanError(m_imageView.GetLastErrorCode()));
|
||||||
|
|
||||||
releaseImage.Reset();
|
releaseImage.Reset();
|
||||||
createInfoView.image = m_image;
|
}
|
||||||
|
|
||||||
{
|
VulkanTexture::VulkanTexture(std::shared_ptr<VulkanTexture> parentTexture, const TextureViewInfo& viewInfo) :
|
||||||
// FIXME
|
m_parentTexture(std::move(parentTexture)),
|
||||||
vmaDestroyImage(m_device.GetMemoryAllocator(), m_image, m_allocation);
|
m_image(m_parentTexture->m_image),
|
||||||
}
|
m_allocation(nullptr),
|
||||||
|
m_device(m_parentTexture->m_device)
|
||||||
|
{
|
||||||
|
m_textureInfo = ApplyView(m_parentTexture->m_textureInfo, viewInfo);
|
||||||
|
|
||||||
|
NazaraAssert(viewInfo.layerCount <= m_parentTexture->m_textureInfo.layerCount - viewInfo.baseArrayLayer, "layer count exceeds number of layers");
|
||||||
|
NazaraAssert(viewInfo.levelCount <= m_parentTexture->m_textureInfo.levelCount - viewInfo.baseMipLevel, "level count exceeds number of levels");
|
||||||
|
|
||||||
|
VkImageViewCreateInfo createInfoView = {};
|
||||||
|
createInfoView.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||||
|
createInfoView.image = m_image;
|
||||||
|
createInfoView.subresourceRange = {
|
||||||
|
ToVulkan(PixelFormatInfo::GetContent(m_textureInfo.pixelFormat)),
|
||||||
|
0, //< baseMipLevel
|
||||||
|
m_textureInfo.levelCount, //< levelCount
|
||||||
|
0, //< baseArrayLayer
|
||||||
|
m_textureInfo.layerCount //< layerCount, will be set if the type is an array/cubemap
|
||||||
|
};
|
||||||
|
|
||||||
|
InitViewForFormat(viewInfo.reinterpretFormat, createInfoView);
|
||||||
|
|
||||||
|
if (!m_imageView.Create(m_device, createInfoView))
|
||||||
|
throw std::runtime_error("Failed to create image view: " + TranslateVulkanError(m_imageView.GetLastErrorCode()));
|
||||||
}
|
}
|
||||||
|
|
||||||
VulkanTexture::~VulkanTexture()
|
VulkanTexture::~VulkanTexture()
|
||||||
{
|
{
|
||||||
vmaDestroyImage(m_device.GetMemoryAllocator(), m_image, m_allocation);
|
if (m_allocation)
|
||||||
|
vmaDestroyImage(m_device.GetMemoryAllocator(), m_image, m_allocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VulkanTexture::Copy(const Texture& source, const Boxui& srcBox, const Vector3ui& dstPos)
|
bool VulkanTexture::Copy(const Texture& source, const Boxui& srcBox, const Vector3ui& dstPos)
|
||||||
|
|
@ -192,30 +215,43 @@ namespace Nz
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Texture> VulkanTexture::CreateView(const TextureViewInfo& viewInfo)
|
||||||
|
{
|
||||||
|
if (m_parentTexture)
|
||||||
|
return m_parentTexture->CreateView(viewInfo);
|
||||||
|
|
||||||
|
return std::make_shared<VulkanTexture>(std::static_pointer_cast<VulkanTexture>(shared_from_this()), viewInfo);
|
||||||
|
}
|
||||||
|
|
||||||
PixelFormat VulkanTexture::GetFormat() const
|
PixelFormat VulkanTexture::GetFormat() const
|
||||||
{
|
{
|
||||||
return m_params.pixelFormat;
|
return m_textureInfo.pixelFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt8 VulkanTexture::GetLevelCount() const
|
UInt8 VulkanTexture::GetLevelCount() const
|
||||||
{
|
{
|
||||||
return m_params.mipmapLevel;
|
return m_textureInfo.levelCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
VulkanTexture* VulkanTexture::GetParentTexture() const
|
||||||
|
{
|
||||||
|
return m_parentTexture.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3ui VulkanTexture::GetSize(UInt8 level) const
|
Vector3ui VulkanTexture::GetSize(UInt8 level) const
|
||||||
{
|
{
|
||||||
return Vector3ui(GetLevelSize(m_params.width, level), GetLevelSize(m_params.height, level), GetLevelSize(m_params.depth, level));
|
return Vector3ui(GetLevelSize(m_textureInfo.width, level), GetLevelSize(m_textureInfo.height, level), GetLevelSize(m_textureInfo.depth, level));
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageType VulkanTexture::GetType() const
|
ImageType VulkanTexture::GetType() const
|
||||||
{
|
{
|
||||||
return m_params.type;
|
return m_textureInfo.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VulkanTexture::Update(const void* ptr, const Boxui& box, unsigned int srcWidth, unsigned int srcHeight, UInt8 level)
|
bool VulkanTexture::Update(const void* ptr, const Boxui& box, unsigned int srcWidth, unsigned int srcHeight, UInt8 level)
|
||||||
{
|
{
|
||||||
std::size_t textureSize = box.width * box.height * box.depth * PixelFormatInfo::GetBytesPerPixel(m_params.pixelFormat);
|
std::size_t textureSize = box.width * box.height * box.depth * PixelFormatInfo::GetBytesPerPixel(m_textureInfo.pixelFormat);
|
||||||
if (m_params.type == ImageType::Cubemap)
|
if (m_textureInfo.type == ImageType::Cubemap)
|
||||||
textureSize *= 6;
|
textureSize *= 6;
|
||||||
|
|
||||||
VkBufferCreateInfo createInfo = {};
|
VkBufferCreateInfo createInfo = {};
|
||||||
|
|
@ -256,7 +292,7 @@ namespace Nz
|
||||||
unsigned int dstWidth = box.width;
|
unsigned int dstWidth = box.width;
|
||||||
unsigned int dstHeight = box.height;
|
unsigned int dstHeight = box.height;
|
||||||
|
|
||||||
unsigned int bpp = PixelFormatInfo::GetBytesPerPixel(m_params.pixelFormat);
|
unsigned int bpp = PixelFormatInfo::GetBytesPerPixel(m_textureInfo.pixelFormat);
|
||||||
unsigned int lineStride = box.width * bpp;
|
unsigned int lineStride = box.width * bpp;
|
||||||
unsigned int dstLineStride = dstWidth * bpp;
|
unsigned int dstLineStride = dstWidth * bpp;
|
||||||
unsigned int dstFaceStride = dstLineStride * dstHeight;
|
unsigned int dstFaceStride = dstLineStride * dstHeight;
|
||||||
|
|
@ -287,14 +323,14 @@ namespace Nz
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
VkImageAspectFlags aspect = VK_IMAGE_ASPECT_COLOR_BIT;
|
VkImageAspectFlags aspect = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
if (PixelFormatInfo::GetContent(m_params.pixelFormat) == PixelFormatContent::Depth)
|
if (PixelFormatInfo::GetContent(m_textureInfo.pixelFormat) == PixelFormatContent::Depth)
|
||||||
aspect = VK_IMAGE_ASPECT_DEPTH_BIT;
|
aspect = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||||
|
|
||||||
VkImageSubresourceLayers subresourceLayers = { //< FIXME
|
VkImageSubresourceLayers subresourceLayers = { //< FIXME
|
||||||
aspect,
|
aspect,
|
||||||
level, //< mipLevel
|
level, //< mipLevel
|
||||||
0, //< baseArrayLayer
|
0, //< baseArrayLayer
|
||||||
UInt32((m_params.type == ImageType::Cubemap) ? 6 : 1) //< layerCount
|
UInt32((m_textureInfo.type == ImageType::Cubemap) ? 6 : 1) //< layerCount
|
||||||
};
|
};
|
||||||
|
|
||||||
VkImageSubresourceRange subresourceRange = { //< FIXME
|
VkImageSubresourceRange subresourceRange = { //< FIXME
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue