mirror of
https://github.com/love2d/love.git
synced 2026-08-17 19:23:38 +02:00
Change the 'viewformats' texture setting field to be a list of pixel formats.
Replace Texture:hasViewFormats with Texture:getViewFormats.
This commit is contained in:
@@ -287,6 +287,28 @@ Texture::Texture(Graphics *gfx, const Settings &settings, const Slices *slices)
|
|||||||
if (isCompressed() && renderTarget)
|
if (isCompressed() && renderTarget)
|
||||||
throw love::Exception("Compressed textures cannot be render targets.");
|
throw love::Exception("Compressed textures cannot be render targets.");
|
||||||
|
|
||||||
|
for (PixelFormat viewformat : viewFormats)
|
||||||
|
{
|
||||||
|
if (getLinearPixelFormat(viewformat) == getLinearPixelFormat(format))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (isPixelFormatCompressed(format) || isPixelFormatCompressed(viewformat))
|
||||||
|
throw love::Exception("Compressed textures cannot use different pixel formats for texture views, aside from sRGB versus linear variants of the same pixel format.");
|
||||||
|
|
||||||
|
if (isPixelFormatColor(viewformat) != isPixelFormatColor(format))
|
||||||
|
throw love::Exception("Color-format textures cannot use depth/stencil pixel formats and vice versa, in texture views.");
|
||||||
|
|
||||||
|
// TODO: depth[24|32f]_stencil8 -> stencil8 can work.
|
||||||
|
if (isPixelFormatDepthStencil(viewformat))
|
||||||
|
throw love::Exception("Using different pixel formats for texture views is not currently supported for depth or stencil formats.");
|
||||||
|
|
||||||
|
size_t viewbytes = getPixelFormatBlockSize(viewformat);
|
||||||
|
size_t basebytes = getPixelFormatBlockSize(format);
|
||||||
|
|
||||||
|
if (viewbytes != basebytes)
|
||||||
|
throw love::Exception("Texture view pixel formats must have the same bits per pixel as the base texture's pixel format.");
|
||||||
|
}
|
||||||
|
|
||||||
validatePixelFormat(gfx);
|
validatePixelFormat(gfx);
|
||||||
|
|
||||||
if (!caps.textureTypes[texType])
|
if (!caps.textureTypes[texType])
|
||||||
@@ -409,28 +431,10 @@ Texture::Texture(Graphics *gfx, Texture *base, const ViewSettings &viewsettings)
|
|||||||
throw love::Exception("Unknown texture type.");
|
throw love::Exception("Unknown texture type.");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto baseformat = base->getPixelFormat();
|
if (format != base->getPixelFormat())
|
||||||
|
|
||||||
if (format != baseformat)
|
|
||||||
{
|
{
|
||||||
if (isPixelFormatCompressed(baseformat) || isPixelFormatCompressed(format))
|
if (std::find(viewFormats.begin(), viewFormats.end(), format) == viewFormats.end())
|
||||||
throw love::Exception("Compressed textures cannot use a different pixel format in a texture view.");
|
throw love::Exception("Using a different pixel format in a texture view requires the original texture to be created with a 'viewformats' setting that includes the given format in its list.");
|
||||||
|
|
||||||
if (isPixelFormatColor(baseformat) != isPixelFormatColor(format))
|
|
||||||
throw love::Exception("Color-format textures cannot use a depth/stencil pixel format and vice versa, in a texture view.");
|
|
||||||
|
|
||||||
// TODO: depth[24|32f]_stencil8 -> stencil8 can work.
|
|
||||||
if (isPixelFormatDepthStencil(baseformat))
|
|
||||||
throw love::Exception("Using a different pixel format in a texture view is not currently supported for depth or stencil formats.");
|
|
||||||
|
|
||||||
if (!viewFormats)
|
|
||||||
throw love::Exception("Using a different pixel format in a texture view requires the original texture to be created with the 'viewformats' setting set to true.");
|
|
||||||
|
|
||||||
size_t bytes = getPixelFormatBlockSize(format);
|
|
||||||
size_t basebytes = getPixelFormatBlockSize(baseformat);
|
|
||||||
|
|
||||||
if (bytes != basebytes)
|
|
||||||
throw love::Exception("Texture views must have the same bits per pixel as the original texture.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *miperr = nullptr;
|
const char *miperr = nullptr;
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
|
|
||||||
// C
|
// C
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace love
|
namespace love
|
||||||
{
|
{
|
||||||
@@ -195,7 +196,7 @@ public:
|
|||||||
int msaa = 1;
|
int msaa = 1;
|
||||||
bool renderTarget = false;
|
bool renderTarget = false;
|
||||||
bool computeWrite = false;
|
bool computeWrite = false;
|
||||||
bool viewFormats = false;
|
std::vector<PixelFormat> viewFormats;
|
||||||
OptionalBool readable;
|
OptionalBool readable;
|
||||||
std::string debugName;
|
std::string debugName;
|
||||||
};
|
};
|
||||||
@@ -279,7 +280,8 @@ public:
|
|||||||
bool isRenderTarget() const { return renderTarget; }
|
bool isRenderTarget() const { return renderTarget; }
|
||||||
bool isComputeWritable() const { return computeWrite; }
|
bool isComputeWritable() const { return computeWrite; }
|
||||||
bool isReadable() const { return readable; }
|
bool isReadable() const { return readable; }
|
||||||
bool hasViewFormats() const { return viewFormats; }
|
|
||||||
|
const std::vector<PixelFormat> &getViewFormats() const { return viewFormats; }
|
||||||
|
|
||||||
bool isCompressed() const;
|
bool isCompressed() const;
|
||||||
bool isFormatLinear() const;
|
bool isFormatLinear() const;
|
||||||
@@ -353,9 +355,10 @@ protected:
|
|||||||
PixelFormat format;
|
PixelFormat format;
|
||||||
bool renderTarget;
|
bool renderTarget;
|
||||||
bool computeWrite;
|
bool computeWrite;
|
||||||
bool viewFormats;
|
|
||||||
bool readable;
|
bool readable;
|
||||||
|
|
||||||
|
std::vector<PixelFormat> viewFormats;
|
||||||
|
|
||||||
MipmapsMode mipmapsMode;
|
MipmapsMode mipmapsMode;
|
||||||
|
|
||||||
int width;
|
int width;
|
||||||
|
|||||||
@@ -76,8 +76,15 @@ Texture::Texture(love::graphics::Graphics *gfxbase, id<MTLDevice> device, const
|
|||||||
desc.usage |= MTLTextureUsageRenderTarget;
|
desc.usage |= MTLTextureUsageRenderTarget;
|
||||||
if (computeWrite)
|
if (computeWrite)
|
||||||
desc.usage |= MTLTextureUsageShaderWrite;
|
desc.usage |= MTLTextureUsageShaderWrite;
|
||||||
if (viewFormats)
|
|
||||||
desc.usage |= MTLTextureUsagePixelFormatView;
|
for (PixelFormat viewformat : viewFormats)
|
||||||
|
{
|
||||||
|
if (getLinearPixelFormat(viewformat) != getLinearPixelFormat(format))
|
||||||
|
{
|
||||||
|
desc.usage |= MTLTextureUsagePixelFormatView;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
texture = [device newTextureWithDescriptor:desc];
|
texture = [device newTextureWithDescriptor:desc];
|
||||||
|
|
||||||
|
|||||||
@@ -326,6 +326,8 @@ public:
|
|||||||
void setVsync(int vsync);
|
void setVsync(int vsync);
|
||||||
int getVsync() const;
|
int getVsync() const;
|
||||||
|
|
||||||
|
uint32 getDeviceApiVersion() const { return deviceApiVersion; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
graphics::ShaderStage *newShaderStageInternal(ShaderStageType stage, const std::string &cachekey, const std::string &source, bool gles) override;
|
graphics::ShaderStage *newShaderStageInternal(ShaderStageType stage, const std::string &cachekey, const std::string &source, bool gles) override;
|
||||||
graphics::Shader *newShaderInternal(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM], const Shader::CompileOptions &options) override;
|
graphics::Shader *newShaderInternal(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM], const Shader::CompileOptions &options) override;
|
||||||
|
|||||||
@@ -100,9 +100,17 @@ bool Texture::loadVolatile()
|
|||||||
if (root)
|
if (root)
|
||||||
{
|
{
|
||||||
VkImageCreateFlags createFlags = 0;
|
VkImageCreateFlags createFlags = 0;
|
||||||
|
std::vector<VkFormat> vkviewformats;
|
||||||
|
|
||||||
if (viewFormats)
|
for (PixelFormat viewformat : viewFormats)
|
||||||
createFlags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
|
{
|
||||||
|
if (viewformat != format)
|
||||||
|
{
|
||||||
|
createFlags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
|
||||||
|
TextureFormat f = Vulkan::getTextureFormat(viewformat);
|
||||||
|
vkviewformats.push_back(f.internalFormat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (texType == TEXTURE_CUBE || texType == TEXTURE_2D_ARRAY)
|
if (texType == TEXTURE_CUBE || texType == TEXTURE_2D_ARRAY)
|
||||||
createFlags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
|
createFlags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
|
||||||
@@ -125,6 +133,17 @@ bool Texture::loadVolatile()
|
|||||||
imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
imageInfo.samples = msaaSamples;
|
imageInfo.samples = msaaSamples;
|
||||||
|
|
||||||
|
VkImageFormatListCreateInfo viewFormatsInfo{};
|
||||||
|
viewFormatsInfo.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO;
|
||||||
|
|
||||||
|
if (!vkviewformats.empty() && vgfx->getDeviceApiVersion() >= VK_API_VERSION_1_2)
|
||||||
|
{
|
||||||
|
viewFormatsInfo.viewFormatCount = (uint32)vkviewformats.size();
|
||||||
|
viewFormatsInfo.pViewFormats = vkviewformats.data();
|
||||||
|
|
||||||
|
imageInfo.pNext = &viewFormatsInfo;
|
||||||
|
}
|
||||||
|
|
||||||
VmaAllocationCreateInfo imageAllocationCreateInfo{};
|
VmaAllocationCreateInfo imageAllocationCreateInfo{};
|
||||||
|
|
||||||
if (vmaCreateImage(allocator, &imageInfo, &imageAllocationCreateInfo, &textureImage, &textureImageAllocation, nullptr) != VK_SUCCESS)
|
if (vmaCreateImage(allocator, &imageInfo, &imageAllocationCreateInfo, &textureImage, &textureImageAllocation, nullptr) != VK_SUCCESS)
|
||||||
|
|||||||
@@ -830,7 +830,25 @@ static void luax_checktexturesettings(lua_State *L, int idx, bool opt, bool chec
|
|||||||
s.msaa = luax_intflag(L, idx, Texture::getConstant(Texture::SETTING_MSAA), s.msaa);
|
s.msaa = luax_intflag(L, idx, Texture::getConstant(Texture::SETTING_MSAA), s.msaa);
|
||||||
|
|
||||||
s.computeWrite = luax_boolflag(L, idx, Texture::getConstant(Texture::SETTING_COMPUTE_WRITE), s.computeWrite);
|
s.computeWrite = luax_boolflag(L, idx, Texture::getConstant(Texture::SETTING_COMPUTE_WRITE), s.computeWrite);
|
||||||
s.viewFormats = luax_boolflag(L, idx, Texture::getConstant(Texture::SETTING_VIEW_FORMATS), s.viewFormats);
|
|
||||||
|
lua_getfield(L, idx, Texture::getConstant(Texture::SETTING_VIEW_FORMATS));
|
||||||
|
if (!lua_isnoneornil(L, -1))
|
||||||
|
{
|
||||||
|
if (lua_type(L, -1) != LUA_TTABLE)
|
||||||
|
luaL_argerror(L, idx, "expected field 'viewformats' to be a table type");
|
||||||
|
|
||||||
|
for (int i = 1; i <= luax_objlen(L, -1); i++)
|
||||||
|
{
|
||||||
|
lua_rawgeti(L, -1, i);
|
||||||
|
const char *str = luaL_checkstring(L, -1);
|
||||||
|
PixelFormat viewformat = PIXELFORMAT_UNKNOWN;
|
||||||
|
if (!getConstant(str, viewformat))
|
||||||
|
luax_enumerror(L, "pixel format", str);
|
||||||
|
s.viewFormats.push_back(viewformat);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
lua_getfield(L, idx, Texture::getConstant(Texture::SETTING_READABLE));
|
lua_getfield(L, idx, Texture::getConstant(Texture::SETTING_READABLE));
|
||||||
if (!lua_isnoneornil(L, -1))
|
if (!lua_isnoneornil(L, -1))
|
||||||
|
|||||||
@@ -300,10 +300,21 @@ int w_Texture_isReadable(lua_State *L)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int w_Texture_hasViewFormats(lua_State *L)
|
int w_Texture_getViewFormats(lua_State *L)
|
||||||
{
|
{
|
||||||
Texture *t = luax_checktexture(L, 1);
|
Texture *t = luax_checktexture(L, 1);
|
||||||
luax_pushboolean(L, t->hasViewFormats());
|
const std::vector<PixelFormat> &viewformats = t->getViewFormats();
|
||||||
|
|
||||||
|
lua_createtable(L, (int) viewformats.size(), 0);
|
||||||
|
for (int i = 0; i < (int) viewformats.size(); i++)
|
||||||
|
{
|
||||||
|
const char *str = nullptr;
|
||||||
|
if (!getConstant(viewformats[i], str))
|
||||||
|
return luaL_error(L, "Unknown pixel format.");
|
||||||
|
lua_pushstring(L, str);
|
||||||
|
lua_rawseti(L, -2, i + 1);
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -518,7 +529,7 @@ const luaL_Reg w_Texture_functions[] =
|
|||||||
{ "isCanvas", w_Texture_isCanvas },
|
{ "isCanvas", w_Texture_isCanvas },
|
||||||
{ "isComputeWritable", w_Texture_isComputeWritable },
|
{ "isComputeWritable", w_Texture_isComputeWritable },
|
||||||
{ "isReadable", w_Texture_isReadable },
|
{ "isReadable", w_Texture_isReadable },
|
||||||
{ "hasViewFormats", w_Texture_hasViewFormats },
|
{ "getViewFormats", w_Texture_getViewFormats },
|
||||||
{ "getMipmapMode", w_Texture_getMipmapMode },
|
{ "getMipmapMode", w_Texture_getMipmapMode },
|
||||||
{ "getDepthSampleMode", w_Texture_getDepthSampleMode },
|
{ "getDepthSampleMode", w_Texture_getDepthSampleMode },
|
||||||
{ "setDepthSampleMode", w_Texture_setDepthSampleMode },
|
{ "setDepthSampleMode", w_Texture_setDepthSampleMode },
|
||||||
|
|||||||
Reference in New Issue
Block a user