Add texture views. Fixes #2022.

Add love.graphics.newTextureView(basetexture, viewsettings). Requires GLSL4 support.
Add 'viewformats' boolean setting to texture setting tables.
Add Texture:hasViewFormats.

The viewsettings table has the following fields:
  format = nil, -- set this to a pixel format to override the base format. It must have the same number of bytes per pixel as the original, and the 'viewformats' setting on the original texture must be true for this to work. Cannot be used for compressed or depth/stencil textures.
  type = nil, -- set this to a texture type to override the base texture type. 2d base textures can make [2d, array] views. [array, cube] base textures can make [2d, array, cube] views.
  mipmapstart = nil, -- set to a number to use a less detailed mipmap level as a base.
  mipmapcount = nil, -- set to a number to override the number of mipmaps in the texture view.
  layerstart = nil, -- set to a number to use a specific layer or cube face as a base.
  layers = nil, -- set to a number to override the number of layers in an array texture view.
This commit is contained in:
Sasha Szpakowski
2024-02-24 15:45:43 -04:00
parent 1e97e09b28
commit 42812ad521
20 changed files with 588 additions and 216 deletions
+69
View File
@@ -799,6 +799,13 @@ static void luax_checktexturesettings(lua_State *L, int idx, bool opt, bool chec
if (s.type == TEXTURE_2D_ARRAY || s.type == TEXTURE_VOLUME)
s.layers = luax_checkintflag(L, idx, Texture::getConstant(Texture::SETTING_LAYERS));
}
else
{
s.width = luax_intflag(L, idx, Texture::getConstant(Texture::SETTING_WIDTH), s.width);
s.height = luax_intflag(L, idx, Texture::getConstant(Texture::SETTING_HEIGHT), s.height);
if (s.type == TEXTURE_2D_ARRAY || s.type == TEXTURE_VOLUME)
s.layers = luax_intflag(L, idx, Texture::getConstant(Texture::SETTING_LAYERS), s.layers);
}
lua_getfield(L, idx, Texture::getConstant(Texture::SETTING_MIPMAPS));
if (!lua_isnoneornil(L, -1))
@@ -823,6 +830,7 @@ 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.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_READABLE));
if (!lua_isnoneornil(L, -1))
@@ -1240,6 +1248,66 @@ int w_newVolumeImage(lua_State *L)
return w_newVolumeTexture(L);
}
int w_newTextureView(lua_State *L)
{
Texture *base = luax_checktexture(L, 1);
luaL_checktype(L, 2, LUA_TTABLE);
Texture::ViewSettings settings;
lua_getfield(L, 2, "format");
if (!lua_isnoneornil(L, -1))
{
const char *str = luaL_checkstring(L, -1);
if (!getConstant(str, settings.format.value))
luax_enumerror(L, "pixel format", str);
settings.format.hasValue = true;
}
lua_pop(L, 1);
lua_getfield(L, 2, "type");
if (!lua_isnoneornil(L, -1))
{
const char *str = luaL_checkstring(L, -1);
if (!Texture::getConstant(str, settings.type.value))
luax_enumerror(L, "texture type", Texture::getConstants(settings.type.value), str);
settings.type.hasValue = true;
}
lua_pop(L, 1);
lua_getfield(L, 2, "mipmapstart");
if (!lua_isnoneornil(L, -1))
settings.mipmapStart.set(luaL_checkint(L, -1) - 1);
lua_pop(L, 1);
lua_getfield(L, 2, "mipmapcount");
if (!lua_isnoneornil(L, -1))
settings.mipmapCount.set(luaL_checkint(L, -1));
lua_pop(L, 1);
lua_getfield(L, 2, "layerstart");
if (!lua_isnoneornil(L, -1))
settings.layerStart.set(luaL_checkint(L, -1) - 1);
lua_pop(L, 1);
lua_getfield(L, 2, "layers");
if (!lua_isnoneornil(L, -1))
settings.layerCount.set(luaL_checkint(L, -1));
lua_pop(L, 1);
lua_getfield(L, 2, "debugname");
if (!lua_isnoneornil(L, -1))
settings.debugName = luaL_checkstring(L, -1);
lua_pop(L, 1);
Texture *t = nullptr;
luax_catchexcept(L, [&]() { t = instance()->newTextureView(base, settings); });
luax_pushtype(L, t);
t->release();
return 1;
}
int w_newQuad(lua_State *L)
{
luax_checkgraphicscreated(L);
@@ -3857,6 +3925,7 @@ static const luaL_Reg functions[] =
{ "newCubeTexture", w_newCubeTexture },
{ "newArrayTexture", w_newArrayTexture },
{ "newVolumeTexture", w_newVolumeTexture },
{ "newTextureView", w_newTextureView },
{ "newQuad", w_newQuad },
{ "newFont", w_newFont },
{ "newImageFont", w_newImageFont },