mirror of
https://github.com/love2d/love.git
synced 2026-08-12 16:40:57 +02:00
Initial support for integer format textures.
They can't be rendered to and ImageData can't use the formats, for now.
This commit is contained in:
+122
-79
@@ -26,81 +26,99 @@ namespace love
|
||||
|
||||
static PixelFormatInfo formatInfo[] =
|
||||
{
|
||||
// components, blockW, blockH, blockSize, color, depth, stencil, compressed
|
||||
{ 0, 1, 1, 0, false, false, false, false }, // PIXELFORMAT_UNKNOWN
|
||||
// components, blockW, blockH, blockSize, color, depth, stencil, compressed, dataType
|
||||
{ 0, 1, 1, 0, false, false, false, false, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_UNKNOWN
|
||||
|
||||
{ 0, 1, 1, 0, true, false, false, false }, // PIXELFORMAT_NORMAL
|
||||
{ 0, 1, 1, 0, true, false, false, false }, // PIXELFORMAT_HDR
|
||||
{ 0, 1, 1, 0, true, false, false, false, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_NORMAL
|
||||
{ 0, 1, 1, 0, true, false, false, false, PIXELFORMATTYPE_SFLOAT }, // PIXELFORMAT_HDR
|
||||
|
||||
{ 1, 1, 1, 1, true, false, false, false }, // PIXELFORMAT_R8_UNORM
|
||||
{ 1, 1, 1, 2, true, false, false, false }, // PIXELFORMAT_R16_UNORM
|
||||
{ 1, 1, 1, 2, true, false, false, false }, // PIXELFORMAT_R16_FLOAT
|
||||
{ 1, 1, 1, 4, true, false, false, false }, // PIXELFORMAT_R32_FLOAT
|
||||
{ 1, 1, 1, 1, true, false, false, false, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_R8_UNORM
|
||||
{ 1, 1, 1, 1, true, false, false, false, PIXELFORMATTYPE_SINT }, // PIXELFORMAT_R8_INT
|
||||
{ 1, 1, 1, 1, true, false, false, false, PIXELFORMATTYPE_UINT }, // PIXELFORMAT_R8_UINT
|
||||
{ 1, 1, 1, 2, true, false, false, false, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_R16_UNORM
|
||||
{ 1, 1, 1, 2, true, false, false, false, PIXELFORMATTYPE_SFLOAT }, // PIXELFORMAT_R16_FLOAT
|
||||
{ 1, 1, 1, 2, true, false, false, false, PIXELFORMATTYPE_SINT }, // PIXELFORMAT_R16_INT
|
||||
{ 1, 1, 1, 2, true, false, false, false, PIXELFORMATTYPE_UINT }, // PIXELFORMAT_R16_UINT
|
||||
{ 1, 1, 1, 4, true, false, false, false, PIXELFORMATTYPE_SFLOAT }, // PIXELFORMAT_R32_FLOAT
|
||||
{ 1, 1, 1, 4, true, false, false, false, PIXELFORMATTYPE_SINT }, // PIXELFORMAT_R32_INT
|
||||
{ 1, 1, 1, 4, true, false, false, false, PIXELFORMATTYPE_UINT }, // PIXELFORMAT_R32_UINT
|
||||
|
||||
{ 2, 1, 1, 2, true, false, false, false }, // PIXELFORMAT_RG8_UNORM
|
||||
{ 2, 1, 1, 2, true, false, false, false }, // PIXELFORMAT_LA8_UNORM
|
||||
{ 2, 1, 1, 4, true, false, false, false }, // PIXELFORMAT_RG16_UNORM
|
||||
{ 2, 1, 1, 4, true, false, false, false }, // PIXELFORMAT_RG16_FLOAT
|
||||
{ 2, 1, 1, 8, true, false, false, false }, // PIXELFORMAT_RG32_FLOAT
|
||||
{ 2, 1, 1, 2, true, false, false, false, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_RG8_UNORM
|
||||
{ 2, 1, 1, 2, true, false, false, false, PIXELFORMATTYPE_SINT }, // PIXELFORMAT_RG8_INT
|
||||
{ 2, 1, 1, 2, true, false, false, false, PIXELFORMATTYPE_UINT }, // PIXELFORMAT_RG8_UINT
|
||||
{ 2, 1, 1, 2, true, false, false, false, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_LA8_UNORM
|
||||
{ 2, 1, 1, 4, true, false, false, false, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_RG16_UNORM
|
||||
{ 2, 1, 1, 4, true, false, false, false, PIXELFORMATTYPE_SFLOAT }, // PIXELFORMAT_RG16_FLOAT
|
||||
{ 2, 1, 1, 4, true, false, false, false, PIXELFORMATTYPE_SINT }, // PIXELFORMAT_RG16_INT
|
||||
{ 2, 1, 1, 4, true, false, false, false, PIXELFORMATTYPE_UINT }, // PIXELFORMAT_RG16_UINT
|
||||
{ 2, 1, 1, 8, true, false, false, false, PIXELFORMATTYPE_SFLOAT }, // PIXELFORMAT_RG32_FLOAT
|
||||
{ 2, 1, 1, 8, true, false, false, false, PIXELFORMATTYPE_SINT }, // PIXELFORMAT_RG32_INT
|
||||
{ 2, 1, 1, 8, true, false, false, false, PIXELFORMATTYPE_UINT }, // PIXELFORMAT_RG32_UINT
|
||||
|
||||
{ 4, 1, 1, 4, true, false, false, false }, // PIXELFORMAT_RGBA8_UNORM
|
||||
{ 4, 1, 1, 4, true, false, false, false }, // PIXELFORMAT_sRGBA8_UNORM
|
||||
{ 4, 1, 1, 8, true, false, false, false }, // PIXELFORMAT_RGBA16_UNORM
|
||||
{ 4, 1, 1, 8, true, false, false, false }, // PIXELFORMAT_RGBA16_FLOAT
|
||||
{ 4, 1, 1, 16, true, false, false, false }, // PIXELFORMAT_RGBA32_FLOAT
|
||||
{ 4, 1, 1, 4, true, false, false, false, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_RGBA8_UNORM
|
||||
{ 4, 1, 1, 4, true, false, false, false, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_sRGBA8_UNORM
|
||||
{ 4, 1, 1, 4, true, false, false, false, PIXELFORMATTYPE_SINT }, // PIXELFORMAT_RGBA8_INT
|
||||
{ 4, 1, 1, 4, true, false, false, false, PIXELFORMATTYPE_UINT }, // PIXELFORMAT_RGBA8_UINT
|
||||
{ 4, 1, 1, 8, true, false, false, false, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_RGBA16_UNORM
|
||||
{ 4, 1, 1, 8, true, false, false, false, PIXELFORMATTYPE_SFLOAT }, // PIXELFORMAT_RGBA16_FLOAT
|
||||
{ 4, 1, 1, 8, true, false, false, false, PIXELFORMATTYPE_SINT }, // PIXELFORMAT_RGBA16_INT
|
||||
{ 4, 1, 1, 8, true, false, false, false, PIXELFORMATTYPE_UINT }, // PIXELFORMAT_RGBA16_UINT
|
||||
{ 4, 1, 1, 16, true, false, false, false, PIXELFORMATTYPE_SFLOAT }, // PIXELFORMAT_RGBA32_FLOAT
|
||||
{ 4, 1, 1, 16, true, false, false, false, PIXELFORMATTYPE_SINT }, // PIXELFORMAT_RGBA32_INT
|
||||
{ 4, 1, 1, 16, true, false, false, false, PIXELFORMATTYPE_UINT }, // PIXELFORMAT_RGBA32_UINT
|
||||
|
||||
{ 4, 1, 1, 2, true, false, false, false }, // PIXELFORMAT_RGBA4_UNORM
|
||||
{ 4, 1, 1, 2, true, false, false, false }, // PIXELFORMAT_RGB5A1_UNORM
|
||||
{ 3, 1, 1, 2, true, false, false, false }, // PIXELFORMAT_RGB565_UNORM
|
||||
{ 4, 1, 1, 4, true, false, false, false }, // PIXELFORMAT_RGB10A2_UNORM
|
||||
{ 3, 1, 1, 4, true, false, false, false }, // PIXELFORMAT_RG11B10_FLOAT
|
||||
{ 4, 1, 1, 2, true, false, false, false, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_RGBA4_UNORM
|
||||
{ 4, 1, 1, 2, true, false, false, false, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_RGB5A1_UNORM
|
||||
{ 3, 1, 1, 2, true, false, false, false, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_RGB565_UNORM
|
||||
{ 4, 1, 1, 4, true, false, false, false, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_RGB10A2_UNORM
|
||||
{ 3, 1, 1, 4, true, false, false, false, PIXELFORMATTYPE_UFLOAT }, // PIXELFORMAT_RG11B10_FLOAT
|
||||
|
||||
{ 1, 1, 1, 1, false, false, true , false }, // PIXELFORMAT_STENCIL8
|
||||
{ 1, 1, 1, 2, false, true, false, false }, // PIXELFORMAT_DEPTH16_UNORM
|
||||
{ 1, 1, 1, 3, false, true, false, false }, // PIXELFORMAT_DEPTH24_UNORM
|
||||
{ 1, 1, 1, 4, false, true, false, false }, // PIXELFORMAT_DEPTH32_FLOAT
|
||||
{ 2, 1, 1, 4, false, true, true , false }, // PIXELFORMAT_DEPTH24_UNORM_STENCIL8
|
||||
{ 2, 1, 1, 5, false, true, true , false }, // PIXELFORMAT_DEPTH32_FLOAT_STENCIL8
|
||||
{ 1, 1, 1, 1, false, false, true , false, PIXELFORMATTYPE_UINT }, // PIXELFORMAT_STENCIL8
|
||||
{ 1, 1, 1, 2, false, true, false, false, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_DEPTH16_UNORM
|
||||
{ 1, 1, 1, 3, false, true, false, false, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_DEPTH24_UNORM
|
||||
{ 1, 1, 1, 4, false, true, false, false, PIXELFORMATTYPE_SFLOAT }, // PIXELFORMAT_DEPTH32_FLOAT
|
||||
{ 2, 1, 1, 4, false, true, true , false, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_DEPTH24_UNORM_STENCIL8
|
||||
{ 2, 1, 1, 5, false, true, true , false, PIXELFORMATTYPE_SFLOAT }, // PIXELFORMAT_DEPTH32_FLOAT_STENCIL8
|
||||
|
||||
{ 3, 4, 4, 8, true, false, false, true }, // PIXELFORMAT_DXT1_UNORM
|
||||
{ 4, 4, 4, 16, true, false, false, true }, // PIXELFORMAT_DXT3_UNORM
|
||||
{ 4, 4, 4, 16, true, false, false, true }, // PIXELFORMAT_DXT5_UNORM
|
||||
{ 1, 4, 4, 8, true, false, false, true }, // PIXELFORMAT_BC4_UNORM
|
||||
{ 1, 4, 4, 8, true, false, false, true }, // PIXELFORMAT_BC4_SNORM
|
||||
{ 2, 4, 4, 16, true, false, false, true }, // PIXELFORMAT_BC5_UNORM
|
||||
{ 2, 4, 4, 16, true, false, false, true }, // PIXELFORMAT_BC5_SNORM
|
||||
{ 3, 4, 4, 16, true, false, false, true }, // PIXELFORMAT_BC6H_UFLOAT
|
||||
{ 3, 4, 4, 16, true, false, false, true }, // PIXELFORMAT_BC6H_FLOAT
|
||||
{ 4, 4, 4, 16, true, false, false, true }, // PIXELFORMAT_BC7_UNORM
|
||||
{ 3, 4, 4, 8, true, false, false, true, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_DXT1_UNORM
|
||||
{ 4, 4, 4, 16, true, false, false, true, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_DXT3_UNORM
|
||||
{ 4, 4, 4, 16, true, false, false, true, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_DXT5_UNORM
|
||||
{ 1, 4, 4, 8, true, false, false, true, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_BC4_UNORM
|
||||
{ 1, 4, 4, 8, true, false, false, true, PIXELFORMATTYPE_SNORM }, // PIXELFORMAT_BC4_SNORM
|
||||
{ 2, 4, 4, 16, true, false, false, true, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_BC5_UNORM
|
||||
{ 2, 4, 4, 16, true, false, false, true, PIXELFORMATTYPE_SNORM }, // PIXELFORMAT_BC5_SNORM
|
||||
{ 3, 4, 4, 16, true, false, false, true, PIXELFORMATTYPE_UFLOAT }, // PIXELFORMAT_BC6H_UFLOAT
|
||||
{ 3, 4, 4, 16, true, false, false, true, PIXELFORMATTYPE_SFLOAT }, // PIXELFORMAT_BC6H_FLOAT
|
||||
{ 4, 4, 4, 16, true, false, false, true, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_BC7_UNORM
|
||||
|
||||
{ 3, 16, 8, 32, true, false, false, true }, // PIXELFORMAT_PVR1_RGB2_UNORM
|
||||
{ 3, 8, 8, 32, true, false, false, true }, // PIXELFORMAT_PVR1_RGB4_UNORM
|
||||
{ 4, 16, 8, 32, true, false, false, true }, // PIXELFORMAT_PVR1_RGBA2_UNORM
|
||||
{ 4, 8, 8, 32, true, false, false, true }, // PIXELFORMAT_PVR1_RGBA4_UNORM
|
||||
{ 3, 16, 8, 32, true, false, false, true, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_PVR1_RGB2_UNORM
|
||||
{ 3, 8, 8, 32, true, false, false, true, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_PVR1_RGB4_UNORM
|
||||
{ 4, 16, 8, 32, true, false, false, true, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_PVR1_RGBA2_UNORM
|
||||
{ 4, 8, 8, 32, true, false, false, true, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_PVR1_RGBA4_UNORM
|
||||
|
||||
{ 3, 4, 4, 8, true, false, false, true }, // PIXELFORMAT_ETC1_UNORM
|
||||
{ 3, 4, 4, 8, true, false, false, true }, // PIXELFORMAT_ETC2_RGB_UNORM
|
||||
{ 4, 4, 4, 16, true, false, false, true }, // PIXELFORMAT_ETC2_RGBA_UNORM
|
||||
{ 4, 4, 4, 8, true, false, false, true }, // PIXELFORMAT_ETC2_RGBA1_UNORM
|
||||
{ 1, 4, 4, 8, true, false, false, true }, // PIXELFORMAT_EAC_R_UNORM
|
||||
{ 1, 4, 4, 8, true, false, false, true }, // PIXELFORMAT_EAC_R_SNORM
|
||||
{ 2, 4, 4, 16, true, false, false, true }, // PIXELFORMAT_EAC_RG_UNORM
|
||||
{ 2, 4, 4, 16, true, false, false, true }, // PIXELFORMAT_EAC_RG_SNORM
|
||||
{ 3, 4, 4, 8, true, false, false, true, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_ETC1_UNORM
|
||||
{ 3, 4, 4, 8, true, false, false, true, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_ETC2_RGB_UNORM
|
||||
{ 4, 4, 4, 16, true, false, false, true, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_ETC2_RGBA_UNORM
|
||||
{ 4, 4, 4, 8, true, false, false, true, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_ETC2_RGBA1_UNORM
|
||||
{ 1, 4, 4, 8, true, false, false, true, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_EAC_R_UNORM
|
||||
{ 1, 4, 4, 8, true, false, false, true, PIXELFORMATTYPE_SNORM }, // PIXELFORMAT_EAC_R_SNORM
|
||||
{ 2, 4, 4, 16, true, false, false, true, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_EAC_RG_UNORM
|
||||
{ 2, 4, 4, 16, true, false, false, true, PIXELFORMATTYPE_SNORM }, // PIXELFORMAT_EAC_RG_SNORM
|
||||
|
||||
{ 4, 4, 4, 1, true, false, false, true }, // PIXELFORMAT_ASTC_4x4
|
||||
{ 4, 5, 4, 1, true, false, false, true }, // PIXELFORMAT_ASTC_5x4
|
||||
{ 4, 5, 5, 1, true, false, false, true }, // PIXELFORMAT_ASTC_5x5
|
||||
{ 4, 6, 5, 1, true, false, false, true }, // PIXELFORMAT_ASTC_6x5
|
||||
{ 4, 6, 6, 1, true, false, false, true }, // PIXELFORMAT_ASTC_6x6
|
||||
{ 4, 8, 5, 1, true, false, false, true }, // PIXELFORMAT_ASTC_8x5
|
||||
{ 4, 8, 6, 1, true, false, false, true }, // PIXELFORMAT_ASTC_8x6
|
||||
{ 4, 8, 8, 1, true, false, false, true }, // PIXELFORMAT_ASTC_8x8
|
||||
{ 4, 8, 5, 1, true, false, false, true }, // PIXELFORMAT_ASTC_10x5
|
||||
{ 4, 10, 6, 1, true, false, false, true }, // PIXELFORMAT_ASTC_10x6
|
||||
{ 4, 10, 8, 1, true, false, false, true }, // PIXELFORMAT_ASTC_10x8
|
||||
{ 4, 10, 10, 1, true, false, false, true }, // PIXELFORMAT_ASTC_10x10
|
||||
{ 4, 12, 10, 1, true, false, false, true }, // PIXELFORMAT_ASTC_12x10
|
||||
{ 4, 12, 12, 1, true, false, false, true }, // PIXELFORMAT_ASTC_12x12
|
||||
{ 4, 4, 4, 1, true, false, false, true, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_ASTC_4x4
|
||||
{ 4, 5, 4, 1, true, false, false, true, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_ASTC_5x4
|
||||
{ 4, 5, 5, 1, true, false, false, true, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_ASTC_5x5
|
||||
{ 4, 6, 5, 1, true, false, false, true, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_ASTC_6x5
|
||||
{ 4, 6, 6, 1, true, false, false, true, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_ASTC_6x6
|
||||
{ 4, 8, 5, 1, true, false, false, true, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_ASTC_8x5
|
||||
{ 4, 8, 6, 1, true, false, false, true, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_ASTC_8x6
|
||||
{ 4, 8, 8, 1, true, false, false, true, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_ASTC_8x8
|
||||
{ 4, 8, 5, 1, true, false, false, true, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_ASTC_10x5
|
||||
{ 4, 10, 6, 1, true, false, false, true, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_ASTC_10x6
|
||||
{ 4, 10, 8, 1, true, false, false, true, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_ASTC_10x8
|
||||
{ 4, 10, 10, 1, true, false, false, true, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_ASTC_10x10
|
||||
{ 4, 12, 10, 1, true, false, false, true, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_ASTC_12x10
|
||||
{ 4, 12, 12, 1, true, false, false, true, PIXELFORMATTYPE_UNORM }, // PIXELFORMAT_ASTC_12x12
|
||||
};
|
||||
|
||||
static_assert(sizeof(formatInfo) / sizeof(PixelFormatInfo) == PIXELFORMAT_MAX_ENUM, "Update the formatInfo array when adding or removing a PixelFormat");
|
||||
@@ -112,22 +130,40 @@ static StringMap<PixelFormat, PIXELFORMAT_MAX_ENUM>::Entry formatEntries[] =
|
||||
{ "normal", PIXELFORMAT_NORMAL },
|
||||
{ "hdr", PIXELFORMAT_HDR },
|
||||
|
||||
{ "r8", PIXELFORMAT_R8_UNORM },
|
||||
{ "r16", PIXELFORMAT_R16_UNORM },
|
||||
{ "r16f", PIXELFORMAT_R16_FLOAT },
|
||||
{ "r32f", PIXELFORMAT_R32_FLOAT },
|
||||
{ "r8", PIXELFORMAT_R8_UNORM },
|
||||
{ "r8i", PIXELFORMAT_R8_INT },
|
||||
{ "r8ui", PIXELFORMAT_R8_UINT },
|
||||
{ "r16", PIXELFORMAT_R16_UNORM },
|
||||
{ "r16f", PIXELFORMAT_R16_FLOAT },
|
||||
{ "r16i", PIXELFORMAT_R16_INT },
|
||||
{ "r16ui", PIXELFORMAT_R16_UINT },
|
||||
{ "r32f", PIXELFORMAT_R32_FLOAT },
|
||||
{ "r32i", PIXELFORMAT_R32_INT },
|
||||
{ "r32ui", PIXELFORMAT_R32_UINT },
|
||||
|
||||
{ "rg8", PIXELFORMAT_RG8_UNORM },
|
||||
{ "la8", PIXELFORMAT_LA8_UNORM },
|
||||
{ "rg16", PIXELFORMAT_RG16_UNORM },
|
||||
{ "rg16f", PIXELFORMAT_RG16_FLOAT },
|
||||
{ "rg32f", PIXELFORMAT_RG32_FLOAT },
|
||||
{ "rg8", PIXELFORMAT_RG8_UNORM },
|
||||
{ "rg8i", PIXELFORMAT_RG8_INT },
|
||||
{ "rg8ui", PIXELFORMAT_RG8_UINT },
|
||||
{ "la8", PIXELFORMAT_LA8_UNORM },
|
||||
{ "rg16", PIXELFORMAT_RG16_UNORM },
|
||||
{ "rg16f", PIXELFORMAT_RG16_FLOAT },
|
||||
{ "rg16i", PIXELFORMAT_RG16_INT },
|
||||
{ "rg16ui", PIXELFORMAT_RG16_UINT },
|
||||
{ "rg32f", PIXELFORMAT_RG32_FLOAT },
|
||||
{ "rg32i", PIXELFORMAT_RG32_INT },
|
||||
{ "rg32ui", PIXELFORMAT_RG32_UINT },
|
||||
|
||||
{ "rgba8", PIXELFORMAT_RGBA8_UNORM },
|
||||
{ "srgba8", PIXELFORMAT_sRGBA8_UNORM },
|
||||
{ "rgba16", PIXELFORMAT_RGBA16_UNORM },
|
||||
{ "rgba16f", PIXELFORMAT_RGBA16_FLOAT },
|
||||
{ "rgba32f", PIXELFORMAT_RGBA32_FLOAT },
|
||||
{ "rgba8", PIXELFORMAT_RGBA8_UNORM },
|
||||
{ "srgba8", PIXELFORMAT_sRGBA8_UNORM },
|
||||
{ "rgba8i", PIXELFORMAT_RGBA8_INT },
|
||||
{ "rgba8ui", PIXELFORMAT_RGBA8_UINT },
|
||||
{ "rgba16", PIXELFORMAT_RGBA16_UNORM },
|
||||
{ "rgba16f", PIXELFORMAT_RGBA16_FLOAT },
|
||||
{ "rgba16i", PIXELFORMAT_RGBA16_INT },
|
||||
{ "rgba16ui", PIXELFORMAT_RGBA16_UINT },
|
||||
{ "rgba32f", PIXELFORMAT_RGBA32_FLOAT },
|
||||
{ "rgba32i", PIXELFORMAT_RGBA32_INT },
|
||||
{ "rgba32ui", PIXELFORMAT_RGBA32_UINT },
|
||||
|
||||
{ "rgba4", PIXELFORMAT_RGBA4_UNORM },
|
||||
{ "rgb5a1", PIXELFORMAT_RGB5A1_UNORM },
|
||||
@@ -164,6 +200,7 @@ static StringMap<PixelFormat, PIXELFORMAT_MAX_ENUM>::Entry formatEntries[] =
|
||||
{ "EACrs", PIXELFORMAT_EAC_R_SNORM },
|
||||
{ "EACrg", PIXELFORMAT_EAC_RG_UNORM },
|
||||
{ "EACrgs", PIXELFORMAT_EAC_RG_SNORM },
|
||||
|
||||
{ "ASTC4x4", PIXELFORMAT_ASTC_4x4 },
|
||||
{ "ASTC5x4", PIXELFORMAT_ASTC_5x4 },
|
||||
{ "ASTC5x5", PIXELFORMAT_ASTC_5x5 },
|
||||
@@ -220,6 +257,12 @@ bool isPixelFormatStencil(PixelFormat format)
|
||||
return formatInfo[format].stencil;
|
||||
}
|
||||
|
||||
bool isPixelFormatInteger(PixelFormat format)
|
||||
{
|
||||
auto type = formatInfo[format].dataType;
|
||||
return type == PIXELFORMATTYPE_SINT || type == PIXELFORMATTYPE_UINT;
|
||||
}
|
||||
|
||||
PixelFormat getSRGBPixelFormat(PixelFormat format)
|
||||
{
|
||||
if (format == PIXELFORMAT_RGBA8_UNORM)
|
||||
|
||||
@@ -35,23 +35,41 @@ enum PixelFormat
|
||||
|
||||
// 1-channel normal formats
|
||||
PIXELFORMAT_R8_UNORM,
|
||||
PIXELFORMAT_R8_INT,
|
||||
PIXELFORMAT_R8_UINT,
|
||||
PIXELFORMAT_R16_UNORM,
|
||||
PIXELFORMAT_R16_FLOAT,
|
||||
PIXELFORMAT_R16_INT,
|
||||
PIXELFORMAT_R16_UINT,
|
||||
PIXELFORMAT_R32_FLOAT,
|
||||
PIXELFORMAT_R32_INT,
|
||||
PIXELFORMAT_R32_UINT,
|
||||
|
||||
// 2-channel normal formats
|
||||
PIXELFORMAT_RG8_UNORM,
|
||||
PIXELFORMAT_RG8_INT,
|
||||
PIXELFORMAT_RG8_UINT,
|
||||
PIXELFORMAT_LA8_UNORM, // Same as RG8, but accessed as (L, L, L, A)
|
||||
PIXELFORMAT_RG16_UNORM,
|
||||
PIXELFORMAT_RG16_FLOAT,
|
||||
PIXELFORMAT_RG16_INT,
|
||||
PIXELFORMAT_RG16_UINT,
|
||||
PIXELFORMAT_RG32_FLOAT,
|
||||
PIXELFORMAT_RG32_INT,
|
||||
PIXELFORMAT_RG32_UINT,
|
||||
|
||||
// 4-channel normal formats
|
||||
PIXELFORMAT_RGBA8_UNORM,
|
||||
PIXELFORMAT_sRGBA8_UNORM,
|
||||
PIXELFORMAT_RGBA8_INT,
|
||||
PIXELFORMAT_RGBA8_UINT,
|
||||
PIXELFORMAT_RGBA16_UNORM,
|
||||
PIXELFORMAT_RGBA16_FLOAT,
|
||||
PIXELFORMAT_RGBA16_INT,
|
||||
PIXELFORMAT_RGBA16_UINT,
|
||||
PIXELFORMAT_RGBA32_FLOAT,
|
||||
PIXELFORMAT_RGBA32_INT,
|
||||
PIXELFORMAT_RGBA32_UINT,
|
||||
|
||||
// packed formats
|
||||
PIXELFORMAT_RGBA4_UNORM, // LSB->MSB: [a, b, g, r]
|
||||
@@ -109,6 +127,16 @@ enum PixelFormat
|
||||
PIXELFORMAT_MAX_ENUM
|
||||
};
|
||||
|
||||
enum PixelFormatType
|
||||
{
|
||||
PIXELFORMATTYPE_UNORM,
|
||||
PIXELFORMATTYPE_SNORM,
|
||||
PIXELFORMATTYPE_UFLOAT,
|
||||
PIXELFORMATTYPE_SFLOAT,
|
||||
PIXELFORMATTYPE_UINT,
|
||||
PIXELFORMATTYPE_SINT,
|
||||
};
|
||||
|
||||
struct PixelFormatInfo
|
||||
{
|
||||
int components;
|
||||
@@ -119,6 +147,7 @@ struct PixelFormatInfo
|
||||
bool depth;
|
||||
bool stencil;
|
||||
bool compressed;
|
||||
PixelFormatType dataType;
|
||||
};
|
||||
|
||||
bool getConstant(PixelFormat in, const char *&out);
|
||||
@@ -146,6 +175,11 @@ bool isPixelFormatDepth(PixelFormat format);
|
||||
**/
|
||||
bool isPixelFormatStencil(PixelFormat format);
|
||||
|
||||
/**
|
||||
* Gets whether the specified pixel format is a signed or unsigned integer type.
|
||||
**/
|
||||
bool isPixelFormatInteger(PixelFormat format);
|
||||
|
||||
/**
|
||||
* Gets the sRGB version of a linear pixel format, if applicable.
|
||||
**/
|
||||
|
||||
@@ -693,6 +693,9 @@ void Graphics::setRenderTargets(const RenderTargets &rts)
|
||||
if (!firsttex->isValidSlice(firsttarget.slice))
|
||||
throw love::Exception("Invalid slice index: %d.", firsttarget.slice + 1);
|
||||
|
||||
if (isPixelFormatInteger(firstcolorformat))
|
||||
throw love::Exception("Textures with integer pixel formats cannot be rendered to, currently.");
|
||||
|
||||
bool hasSRGBtexture = firstcolorformat == PIXELFORMAT_sRGBA8_UNORM;
|
||||
int pixelw = firsttex->getPixelWidth(firsttarget.mipmap);
|
||||
int pixelh = firsttex->getPixelHeight(firsttarget.mipmap);
|
||||
@@ -726,6 +729,9 @@ void Graphics::setRenderTargets(const RenderTargets &rts)
|
||||
if (isPixelFormatDepthStencil(format))
|
||||
throw love::Exception("Depth/stencil format textures must be used with the 'depthstencil' field of the table passed into setRenderTargets.");
|
||||
|
||||
if (isPixelFormatInteger(format))
|
||||
throw love::Exception("Textures with integer pixel formats cannot be rendered to, currently.");
|
||||
|
||||
if (format == PIXELFORMAT_sRGBA8_UNORM)
|
||||
hasSRGBtexture = true;
|
||||
}
|
||||
|
||||
@@ -635,10 +635,9 @@ bool Shader::isDefaultActive()
|
||||
return false;
|
||||
}
|
||||
|
||||
TextureType Shader::getMainTextureType() const
|
||||
const Shader::UniformInfo *Shader::getMainTextureInfo() const
|
||||
{
|
||||
const UniformInfo *info = getUniformInfo(BUILTIN_TEXTURE_MAIN);
|
||||
return info != nullptr ? info->textureType : TEXTURE_MAX_ENUM;
|
||||
return getUniformInfo(BUILTIN_TEXTURE_MAIN);
|
||||
}
|
||||
|
||||
void Shader::validateDrawState(PrimitiveType primtype, Texture *maintex) const
|
||||
|
||||
@@ -131,9 +131,9 @@ public:
|
||||
};
|
||||
|
||||
UniformType baseType;
|
||||
Access access;
|
||||
DataBaseType dataBaseType;
|
||||
TextureType textureType;
|
||||
DataBaseType texelBufferType;
|
||||
Access access;
|
||||
bool isDepthSampler;
|
||||
size_t bufferStride;
|
||||
size_t bufferMemberCount;
|
||||
@@ -221,7 +221,7 @@ public:
|
||||
**/
|
||||
virtual void setVideoTextures(Texture *ytexture, Texture *cbtexture, Texture *crtexture) = 0;
|
||||
|
||||
TextureType getMainTextureType() const;
|
||||
const UniformInfo *getMainTextureInfo() const;
|
||||
void validateDrawState(PrimitiveType primtype, Texture *maintexture) const;
|
||||
|
||||
void getLocalThreadgroupSize(int *x, int *y, int *z);
|
||||
|
||||
@@ -504,6 +504,9 @@ void Texture::generateMipmaps()
|
||||
if (isPixelFormatDepthStencil(format))
|
||||
throw love::Exception("generateMipmaps cannot be called on a depth/stencil Texture.");
|
||||
|
||||
if (isPixelFormatInteger(format))
|
||||
throw love::Exception("generateMipmaps cannot be called on an integer Texture.");
|
||||
|
||||
generateMipmapsInternal();
|
||||
}
|
||||
|
||||
|
||||
@@ -341,6 +341,7 @@ bool Graphics::setMode(int width, int height, int pixelwidth, int pixelheight, b
|
||||
batchedDrawState.indexBuffer = CreateStreamBuffer(BUFFERUSAGE_INDEX, sizeof(uint16) * LOVE_UINT16_MAX);
|
||||
}
|
||||
|
||||
// TODO: one buffer each for float, int, uint
|
||||
if (capabilities.features[FEATURE_TEXEL_BUFFER] && defaultBuffers[BUFFERUSAGE_TEXEL].get() == nullptr)
|
||||
{
|
||||
Buffer::Settings settings(BUFFERUSAGEFLAG_TEXEL, BUFFERDATAUSAGE_STATIC);
|
||||
@@ -1723,7 +1724,7 @@ bool Graphics::isPixelFormatSupported(PixelFormat format, bool rendertarget, boo
|
||||
// Make sure at least something is bound to a color attachment. I believe
|
||||
// this is required on ES2 but I'm not positive.
|
||||
if (isPixelFormatDepthStencil(format))
|
||||
gl.framebufferTexture(GL_COLOR_ATTACHMENT0, TEXTURE_2D, gl.getDefaultTexture(TEXTURE_2D), 0, 0, 0);
|
||||
gl.framebufferTexture(GL_COLOR_ATTACHMENT0, TEXTURE_2D, gl.getDefaultTexture(TEXTURE_2D, DATA_BASETYPE_FLOAT), 0, 0, 0);
|
||||
|
||||
if (readable)
|
||||
{
|
||||
|
||||
@@ -304,10 +304,13 @@ void OpenGL::deInitContext()
|
||||
|
||||
for (int i = 0; i < TEXTURE_MAX_ENUM; i++)
|
||||
{
|
||||
if (state.defaultTexture[i] != 0)
|
||||
for (int datatype = DATA_BASETYPE_FLOAT; datatype <= DATA_BASETYPE_UINT; datatype++)
|
||||
{
|
||||
gl.deleteTexture(state.defaultTexture[i]);
|
||||
state.defaultTexture[i] = 0;
|
||||
if (state.defaultTexture[i][datatype] != 0)
|
||||
{
|
||||
gl.deleteTexture(state.defaultTexture[i][datatype]);
|
||||
state.defaultTexture[i][datatype] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -569,6 +572,7 @@ void OpenGL::createDefaultTexture()
|
||||
// which would create the need to use different "passthrough" shaders for
|
||||
// untextured primitives vs images.
|
||||
const GLubyte pix[] = {255, 255, 255, 255};
|
||||
const GLubyte intpix[] = {1, 1, 1, 1};
|
||||
|
||||
SamplerState s;
|
||||
s.minFilter = s.magFilter = SamplerState::FILTER_NEAREST;
|
||||
@@ -576,41 +580,55 @@ void OpenGL::createDefaultTexture()
|
||||
|
||||
for (int i = 0; i < TEXTURE_MAX_ENUM; i++)
|
||||
{
|
||||
state.defaultTexture[i] = 0;
|
||||
|
||||
TextureType type = (TextureType) i;
|
||||
|
||||
if (!isTextureTypeSupported(type))
|
||||
continue;
|
||||
|
||||
GLuint curtexture = state.boundTextures[type][0];
|
||||
|
||||
glGenTextures(1, &state.defaultTexture[type]);
|
||||
bindTextureToUnit(type, state.defaultTexture[type], 0, false);
|
||||
|
||||
setSamplerState(type, s);
|
||||
|
||||
bool isSRGB = false;
|
||||
rawTexStorage(type, 1, PIXELFORMAT_RGBA8_UNORM, isSRGB, 1, 1);
|
||||
|
||||
TextureFormat fmt = convertPixelFormat(PIXELFORMAT_RGBA8_UNORM, false, isSRGB);
|
||||
|
||||
int slices = type == TEXTURE_CUBE ? 6 : 1;
|
||||
|
||||
for (int slice = 0; slice < slices; slice++)
|
||||
for (int datatype = (int)DATA_BASETYPE_FLOAT; datatype <= (int)DATA_BASETYPE_UINT; datatype++)
|
||||
{
|
||||
GLenum gltarget = getGLTextureType(type);
|
||||
state.defaultTexture[i][datatype] = 0;
|
||||
|
||||
if (type == TEXTURE_CUBE)
|
||||
gltarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + slice;
|
||||
TextureType type = (TextureType) i;
|
||||
|
||||
if (type == TEXTURE_2D || type == TEXTURE_CUBE)
|
||||
glTexSubImage2D(gltarget, 0, 0, 0, 1, 1, fmt.externalformat, fmt.type, pix);
|
||||
else if (type == TEXTURE_2D_ARRAY || type == TEXTURE_VOLUME)
|
||||
glTexSubImage3D(gltarget, 0, 0, 0, slice, 1, 1, 1, fmt.externalformat, fmt.type, pix);
|
||||
if (!isTextureTypeSupported(type))
|
||||
continue;
|
||||
|
||||
if (datatype != DATA_BASETYPE_FLOAT && !(GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0))
|
||||
continue;
|
||||
|
||||
GLuint curtexture = state.boundTextures[type][0];
|
||||
|
||||
glGenTextures(1, &state.defaultTexture[type][datatype]);
|
||||
bindTextureToUnit(type, state.defaultTexture[type][datatype], 0, false);
|
||||
|
||||
setSamplerState(type, s);
|
||||
|
||||
PixelFormat format = PIXELFORMAT_RGBA8_UNORM;
|
||||
if (datatype == DATA_BASETYPE_INT)
|
||||
format = PIXELFORMAT_RGBA8_INT;
|
||||
else if (datatype == DATA_BASETYPE_UINT)
|
||||
format = PIXELFORMAT_RGBA8_UINT;
|
||||
|
||||
const GLubyte *p = datatype == DATA_BASETYPE_FLOAT ? pix : intpix;
|
||||
|
||||
bool isSRGB = false;
|
||||
rawTexStorage(type, 1, format, isSRGB, 1, 1);
|
||||
|
||||
TextureFormat fmt = convertPixelFormat(format, false, isSRGB);
|
||||
|
||||
int slices = type == TEXTURE_CUBE ? 6 : 1;
|
||||
|
||||
for (int slice = 0; slice < slices; slice++)
|
||||
{
|
||||
GLenum gltarget = getGLTextureType(type);
|
||||
|
||||
if (type == TEXTURE_CUBE)
|
||||
gltarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + slice;
|
||||
|
||||
if (type == TEXTURE_2D || type == TEXTURE_CUBE)
|
||||
glTexSubImage2D(gltarget, 0, 0, 0, 1, 1, fmt.externalformat, fmt.type, p);
|
||||
else if (type == TEXTURE_2D_ARRAY || type == TEXTURE_VOLUME)
|
||||
glTexSubImage3D(gltarget, 0, 0, 0, slice, 1, 1, 1, fmt.externalformat, fmt.type, p);
|
||||
}
|
||||
|
||||
bindTextureToUnit(type, curtexture, 0, false);
|
||||
}
|
||||
|
||||
bindTextureToUnit(type, curtexture, 0, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1113,9 +1131,9 @@ GLuint OpenGL::getDefaultFBO() const
|
||||
#endif
|
||||
}
|
||||
|
||||
GLuint OpenGL::getDefaultTexture(TextureType type) const
|
||||
GLuint OpenGL::getDefaultTexture(TextureType type, DataBaseType datatype) const
|
||||
{
|
||||
return state.defaultTexture[type];
|
||||
return state.defaultTexture[type][datatype];
|
||||
}
|
||||
|
||||
void OpenGL::setTextureUnit(int textureunit)
|
||||
@@ -1166,14 +1184,19 @@ void OpenGL::bindTextureToUnit(Texture *texture, int textureunit, bool restorepr
|
||||
}
|
||||
else
|
||||
{
|
||||
DataBaseType datatype = DATA_BASETYPE_FLOAT;
|
||||
|
||||
if (textureunit == 0 && Shader::current != nullptr)
|
||||
{
|
||||
TextureType shadertex = Shader::current->getMainTextureType();
|
||||
if (shadertex != TEXTURE_MAX_ENUM)
|
||||
textype = shadertex;
|
||||
const Shader::UniformInfo *info = Shader::current->getMainTextureInfo();
|
||||
if (info != nullptr)
|
||||
{
|
||||
textype = info->textureType;
|
||||
datatype = info->dataBaseType;
|
||||
}
|
||||
}
|
||||
|
||||
handle = getDefaultTexture(textype);
|
||||
handle = getDefaultTexture(textype, datatype);
|
||||
}
|
||||
|
||||
bindTextureToUnit(textype, handle, textureunit, restoreprev, bindforedit);
|
||||
@@ -1662,6 +1685,7 @@ OpenGL::TextureFormat OpenGL::convertPixelFormat(PixelFormat pixelformat, bool r
|
||||
f.externalformat = GL_RGBA;
|
||||
f.type = GL_UNSIGNED_SHORT;
|
||||
break;
|
||||
|
||||
case PIXELFORMAT_R16_FLOAT:
|
||||
f.internalformat = GL_R16F;
|
||||
f.externalformat = GL_RED;
|
||||
@@ -1702,6 +1726,97 @@ OpenGL::TextureFormat OpenGL::convertPixelFormat(PixelFormat pixelformat, bool r
|
||||
f.type = GL_FLOAT;
|
||||
break;
|
||||
|
||||
case PIXELFORMAT_R8_INT:
|
||||
f.internalformat = GL_R8I;
|
||||
f.externalformat = GL_RED_INTEGER;
|
||||
f.type = GL_BYTE;
|
||||
break;
|
||||
case PIXELFORMAT_R8_UINT:
|
||||
f.internalformat = GL_R8UI;
|
||||
f.externalformat = GL_RED_INTEGER;
|
||||
f.type = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
case PIXELFORMAT_RG8_INT:
|
||||
f.internalformat = GL_RG8I;
|
||||
f.externalformat = GL_RG_INTEGER;
|
||||
f.type = GL_BYTE;
|
||||
break;
|
||||
case PIXELFORMAT_RG8_UINT:
|
||||
f.internalformat = GL_RG8UI;
|
||||
f.externalformat = GL_RG_INTEGER;
|
||||
f.type = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
case PIXELFORMAT_RGBA8_INT:
|
||||
f.internalformat = GL_RGBA8I;
|
||||
f.externalformat = GL_RGBA_INTEGER;
|
||||
f.type = GL_BYTE;
|
||||
break;
|
||||
case PIXELFORMAT_RGBA8_UINT:
|
||||
f.internalformat = GL_RGBA8UI;
|
||||
f.externalformat = GL_RGBA_INTEGER;
|
||||
f.type = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
case PIXELFORMAT_R16_INT:
|
||||
f.internalformat = GL_R16I;
|
||||
f.externalformat = GL_RED_INTEGER;
|
||||
f.type = GL_SHORT;
|
||||
break;
|
||||
case PIXELFORMAT_R16_UINT:
|
||||
f.internalformat = GL_R16UI;
|
||||
f.externalformat = GL_RED_INTEGER;
|
||||
f.type = GL_UNSIGNED_SHORT;
|
||||
break;
|
||||
case PIXELFORMAT_RG16_INT:
|
||||
f.internalformat = GL_RG16I;
|
||||
f.externalformat = GL_RG_INTEGER;
|
||||
f.type = GL_SHORT;
|
||||
break;
|
||||
case PIXELFORMAT_RG16_UINT:
|
||||
f.internalformat = GL_RG16UI;
|
||||
f.externalformat = GL_RG_INTEGER;
|
||||
f.type = GL_UNSIGNED_SHORT;
|
||||
break;
|
||||
case PIXELFORMAT_RGBA16_INT:
|
||||
f.internalformat = GL_RGBA16I;
|
||||
f.externalformat = GL_RGBA_INTEGER;
|
||||
f.type = GL_SHORT;
|
||||
break;
|
||||
case PIXELFORMAT_RGBA16_UINT:
|
||||
f.internalformat = GL_RGBA16UI;
|
||||
f.externalformat = GL_RGBA_INTEGER;
|
||||
f.type = GL_UNSIGNED_SHORT;
|
||||
break;
|
||||
case PIXELFORMAT_R32_INT:
|
||||
f.internalformat = GL_R32I;
|
||||
f.externalformat = GL_RED_INTEGER;
|
||||
f.type = GL_INT;
|
||||
break;
|
||||
case PIXELFORMAT_R32_UINT:
|
||||
f.internalformat = GL_R32UI;
|
||||
f.externalformat = GL_RED_INTEGER;
|
||||
f.type = GL_UNSIGNED_INT;
|
||||
break;
|
||||
case PIXELFORMAT_RG32_INT:
|
||||
f.internalformat = GL_RG32I;
|
||||
f.externalformat = GL_RG_INTEGER;
|
||||
f.type = GL_INT;
|
||||
break;
|
||||
case PIXELFORMAT_RG32_UINT:
|
||||
f.internalformat = GL_RG32UI;
|
||||
f.externalformat = GL_RG_INTEGER;
|
||||
f.type = GL_UNSIGNED_INT;
|
||||
break;
|
||||
case PIXELFORMAT_RGBA32_INT:
|
||||
f.internalformat = GL_RGBA32I;
|
||||
f.externalformat = GL_RGBA_INTEGER;
|
||||
f.type = GL_INT;
|
||||
break;
|
||||
case PIXELFORMAT_RGBA32_UINT:
|
||||
f.internalformat = GL_RGBA32UI;
|
||||
f.externalformat = GL_RGBA_INTEGER;
|
||||
f.type = GL_UNSIGNED_INT;
|
||||
break;
|
||||
|
||||
case PIXELFORMAT_LA8_UNORM:
|
||||
if (gl.isCoreProfile() || GLAD_ES_VERSION_3_0)
|
||||
{
|
||||
@@ -2046,6 +2161,28 @@ uint32 OpenGL::getPixelFormatUsageFlags(PixelFormat pixelformat)
|
||||
flags &= ~PIXELFORMATUSAGEFLAGS_LINEAR;
|
||||
break;
|
||||
|
||||
case PIXELFORMAT_R8_INT:
|
||||
case PIXELFORMAT_R8_UINT:
|
||||
case PIXELFORMAT_RG8_INT:
|
||||
case PIXELFORMAT_RG8_UINT:
|
||||
case PIXELFORMAT_RGBA8_INT:
|
||||
case PIXELFORMAT_RGBA8_UINT:
|
||||
case PIXELFORMAT_R16_INT:
|
||||
case PIXELFORMAT_R16_UINT:
|
||||
case PIXELFORMAT_RG16_INT:
|
||||
case PIXELFORMAT_RG16_UINT:
|
||||
case PIXELFORMAT_RGBA16_INT:
|
||||
case PIXELFORMAT_RGBA16_UINT:
|
||||
case PIXELFORMAT_R32_INT:
|
||||
case PIXELFORMAT_R32_UINT:
|
||||
case PIXELFORMAT_RG32_INT:
|
||||
case PIXELFORMAT_RG32_UINT:
|
||||
case PIXELFORMAT_RGBA32_INT:
|
||||
case PIXELFORMAT_RGBA32_UINT:
|
||||
if (GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0)
|
||||
flags |= PIXELFORMATUSAGEFLAGS_SAMPLE | PIXELFORMATUSAGEFLAGS_RENDERTARGET;
|
||||
break;
|
||||
|
||||
case PIXELFORMAT_LA8_UNORM:
|
||||
flags |= commonsample;
|
||||
break;
|
||||
|
||||
@@ -312,7 +312,7 @@ public:
|
||||
/**
|
||||
* Gets the ID for love's default texture (used for "untextured" primitives.)
|
||||
**/
|
||||
GLuint getDefaultTexture(TextureType type) const;
|
||||
GLuint getDefaultTexture(TextureType type, DataBaseType datatype) const;
|
||||
|
||||
/**
|
||||
* Gets the texture ID for love's default texel buffer.
|
||||
@@ -523,7 +523,7 @@ private:
|
||||
|
||||
GLuint boundFramebuffers[2];
|
||||
|
||||
GLuint defaultTexture[TEXTURE_MAX_ENUM];
|
||||
GLuint defaultTexture[TEXTURE_MAX_ENUM][DATA_BASETYPE_MAX_ENUM];
|
||||
GLuint defaultTexelBuffer;
|
||||
GLuint defaultStorageBuffer;
|
||||
|
||||
|
||||
@@ -119,16 +119,8 @@ void Shader::mapActiveUniforms()
|
||||
|
||||
u.name = std::string(cname, (size_t) namelen);
|
||||
u.location = glGetUniformLocation(program, u.name.c_str());
|
||||
u.baseType = getUniformBaseType(gltype);
|
||||
u.access = ACCESS_READ;
|
||||
u.textureType = getUniformTextureType(gltype);
|
||||
u.texelBufferType = getUniformTexelBufferType(gltype);
|
||||
u.isDepthSampler = isDepthTextureType(gltype);
|
||||
|
||||
if (u.baseType == UNIFORM_MATRIX)
|
||||
u.matrix = getMatrixSize(gltype);
|
||||
else
|
||||
u.components = getUniformTypeComponents(gltype);
|
||||
computeUniformTypeInfo(gltype, u);
|
||||
|
||||
// glGetActiveUniform appends "[0]" to the end of array uniform names...
|
||||
if (u.name.length() > 3)
|
||||
@@ -160,7 +152,7 @@ void Shader::mapActiveUniforms()
|
||||
else
|
||||
{
|
||||
unit.isTexelBuffer = false;
|
||||
unit.texture = gl.getDefaultTexture(u.textureType);
|
||||
unit.texture = gl.getDefaultTexture(u.textureType, u.dataBaseType);
|
||||
}
|
||||
|
||||
for (int i = 0; i < u.count; i++)
|
||||
@@ -718,6 +710,40 @@ void Shader::updateUniform(const UniformInfo *info, int count, bool internalupda
|
||||
}
|
||||
}
|
||||
|
||||
static bool isResourceBaseTypeCompatible(DataBaseType a, DataBaseType b)
|
||||
{
|
||||
if (a == DATA_BASETYPE_FLOAT || a == DATA_BASETYPE_UNORM || a == DATA_BASETYPE_SNORM)
|
||||
return b == DATA_BASETYPE_FLOAT || b == DATA_BASETYPE_UNORM || b == DATA_BASETYPE_SNORM;
|
||||
|
||||
if (a == DATA_BASETYPE_INT && b == DATA_BASETYPE_INT)
|
||||
return true;
|
||||
|
||||
if (a == DATA_BASETYPE_UINT && b == DATA_BASETYPE_UINT)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static DataBaseType getDataBaseType(PixelFormat format)
|
||||
{
|
||||
switch (getPixelFormatInfo(format).dataType)
|
||||
{
|
||||
case PIXELFORMATTYPE_UNORM:
|
||||
return DATA_BASETYPE_UNORM;
|
||||
case PIXELFORMATTYPE_SNORM:
|
||||
return DATA_BASETYPE_SNORM;
|
||||
case PIXELFORMATTYPE_UFLOAT:
|
||||
case PIXELFORMATTYPE_SFLOAT:
|
||||
return DATA_BASETYPE_FLOAT;
|
||||
case PIXELFORMATTYPE_SINT:
|
||||
return DATA_BASETYPE_INT;
|
||||
case PIXELFORMATTYPE_UINT:
|
||||
return DATA_BASETYPE_UINT;
|
||||
default:
|
||||
return DATA_BASETYPE_FLOAT;
|
||||
}
|
||||
}
|
||||
|
||||
void Shader::sendTextures(const UniformInfo *info, love::graphics::Texture **textures, int count)
|
||||
{
|
||||
Shader::sendTextures(info, textures, count, false);
|
||||
@@ -742,7 +768,6 @@ void Shader::sendTextures(const UniformInfo *info, love::graphics::Texture **tex
|
||||
|
||||
if (tex != nullptr)
|
||||
{
|
||||
const SamplerState &sampler = tex->getSamplerState();
|
||||
if (!tex->isReadable())
|
||||
{
|
||||
if (internalUpdate)
|
||||
@@ -750,7 +775,7 @@ void Shader::sendTextures(const UniformInfo *info, love::graphics::Texture **tex
|
||||
else
|
||||
throw love::Exception("Textures with non-readable formats cannot be sampled from in a shader.");
|
||||
}
|
||||
else if (info->isDepthSampler != sampler.depthSampleMode.hasValue)
|
||||
else if (info->isDepthSampler != tex->getSamplerState().depthSampleMode.hasValue)
|
||||
{
|
||||
if (internalUpdate)
|
||||
continue;
|
||||
@@ -772,6 +797,13 @@ void Shader::sendTextures(const UniformInfo *info, love::graphics::Texture **tex
|
||||
throw love::Exception("Texture's type (%s) must match the type of %s (%s).", textypestr, info->name.c_str(), shadertextypestr);
|
||||
}
|
||||
}
|
||||
else if (!isResourceBaseTypeCompatible(info->dataBaseType, getDataBaseType(tex->getPixelFormat())))
|
||||
{
|
||||
if (internalUpdate)
|
||||
continue;
|
||||
else
|
||||
throw love::Exception("Texture's data format base type must match the uniform variable declared in the shader (float, int, or uint).");
|
||||
}
|
||||
|
||||
tex->retain();
|
||||
}
|
||||
@@ -785,7 +817,7 @@ void Shader::sendTextures(const UniformInfo *info, love::graphics::Texture **tex
|
||||
if (textures[i] != nullptr)
|
||||
gltex = (GLuint) tex->getHandle();
|
||||
else
|
||||
gltex = gl.getDefaultTexture(info->textureType);
|
||||
gltex = gl.getDefaultTexture(info->textureType, info->dataBaseType);
|
||||
|
||||
int texunit = info->ints[i];
|
||||
|
||||
@@ -802,20 +834,6 @@ void Shader::sendBuffers(const UniformInfo *info, love::graphics::Buffer **buffe
|
||||
Shader::sendBuffers(info, buffers, count, false);
|
||||
}
|
||||
|
||||
static bool isTexelBufferTypeCompatible(DataBaseType a, DataBaseType b)
|
||||
{
|
||||
if (a == DATA_BASETYPE_FLOAT || a == DATA_BASETYPE_UNORM || a == DATA_BASETYPE_SNORM)
|
||||
return b == DATA_BASETYPE_FLOAT || b == DATA_BASETYPE_UNORM || b == DATA_BASETYPE_SNORM;
|
||||
|
||||
if (a == DATA_BASETYPE_INT && b == DATA_BASETYPE_INT)
|
||||
return true;
|
||||
|
||||
if (a == DATA_BASETYPE_UINT && b == DATA_BASETYPE_UINT)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Shader::sendBuffers(const UniformInfo *info, love::graphics::Buffer **buffers, int count, bool internalUpdate)
|
||||
{
|
||||
uint32 requiredtypeflags = 0;
|
||||
@@ -860,7 +878,7 @@ void Shader::sendBuffers(const UniformInfo *info, love::graphics::Buffer **buffe
|
||||
if (texelbinding)
|
||||
{
|
||||
DataBaseType basetype = buffer->getDataMember(0).info.baseType;
|
||||
if (!isTexelBufferTypeCompatible(basetype, info->texelBufferType))
|
||||
if (!isResourceBaseTypeCompatible(basetype, info->dataBaseType))
|
||||
{
|
||||
if (internalUpdate)
|
||||
continue;
|
||||
@@ -1043,11 +1061,6 @@ void Shader::updateBuiltinUniforms(love::graphics::Graphics *gfx, int viewportW,
|
||||
|
||||
int Shader::getUniformTypeComponents(GLenum type) const
|
||||
{
|
||||
UniformType basetype = getUniformBaseType(type);
|
||||
|
||||
if (basetype == UNIFORM_SAMPLER || basetype == UNIFORM_TEXELBUFFER)
|
||||
return 1;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case GL_INT:
|
||||
@@ -1122,25 +1135,35 @@ Shader::MatrixSize Shader::getMatrixSize(GLenum type) const
|
||||
return m;
|
||||
}
|
||||
|
||||
Shader::UniformType Shader::getUniformBaseType(GLenum type) const
|
||||
void Shader::computeUniformTypeInfo(GLenum type, UniformInfo &u)
|
||||
{
|
||||
u.isDepthSampler = false;
|
||||
u.components = getUniformTypeComponents(type);
|
||||
u.baseType = UNIFORM_UNKNOWN;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case GL_INT:
|
||||
case GL_INT_VEC2:
|
||||
case GL_INT_VEC3:
|
||||
case GL_INT_VEC4:
|
||||
return UNIFORM_INT;
|
||||
u.baseType = UNIFORM_INT;
|
||||
u.dataBaseType = DATA_BASETYPE_INT;
|
||||
break;
|
||||
case GL_UNSIGNED_INT:
|
||||
case GL_UNSIGNED_INT_VEC2:
|
||||
case GL_UNSIGNED_INT_VEC3:
|
||||
case GL_UNSIGNED_INT_VEC4:
|
||||
return UNIFORM_UINT;
|
||||
u.baseType = UNIFORM_UINT;
|
||||
u.dataBaseType = DATA_BASETYPE_UINT;
|
||||
break;
|
||||
case GL_FLOAT:
|
||||
case GL_FLOAT_VEC2:
|
||||
case GL_FLOAT_VEC3:
|
||||
case GL_FLOAT_VEC4:
|
||||
return UNIFORM_FLOAT;
|
||||
u.baseType = UNIFORM_FLOAT;
|
||||
u.dataBaseType = DATA_BASETYPE_FLOAT;
|
||||
break;
|
||||
case GL_FLOAT_MAT2:
|
||||
case GL_FLOAT_MAT3:
|
||||
case GL_FLOAT_MAT4:
|
||||
@@ -1150,105 +1173,112 @@ Shader::UniformType Shader::getUniformBaseType(GLenum type) const
|
||||
case GL_FLOAT_MAT3x4:
|
||||
case GL_FLOAT_MAT4x2:
|
||||
case GL_FLOAT_MAT4x3:
|
||||
return UNIFORM_MATRIX;
|
||||
u.baseType = UNIFORM_MATRIX;
|
||||
u.dataBaseType = DATA_BASETYPE_FLOAT;
|
||||
u.matrix = getMatrixSize(type);
|
||||
break;
|
||||
case GL_BOOL:
|
||||
case GL_BOOL_VEC2:
|
||||
case GL_BOOL_VEC3:
|
||||
case GL_BOOL_VEC4:
|
||||
return UNIFORM_BOOL;
|
||||
case GL_SAMPLER_1D:
|
||||
case GL_SAMPLER_1D_SHADOW:
|
||||
case GL_SAMPLER_1D_ARRAY:
|
||||
case GL_SAMPLER_1D_ARRAY_SHADOW:
|
||||
u.baseType = UNIFORM_BOOL;
|
||||
u.dataBaseType = DATA_BASETYPE_BOOL;
|
||||
break;
|
||||
|
||||
case GL_SAMPLER_2D:
|
||||
case GL_SAMPLER_2D_MULTISAMPLE:
|
||||
case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
|
||||
case GL_SAMPLER_2D_RECT:
|
||||
case GL_SAMPLER_2D_RECT_SHADOW:
|
||||
u.baseType = UNIFORM_SAMPLER;
|
||||
u.dataBaseType = DATA_BASETYPE_FLOAT;
|
||||
u.textureType = TEXTURE_2D;
|
||||
break;
|
||||
case GL_SAMPLER_2D_SHADOW:
|
||||
u.baseType = UNIFORM_SAMPLER;
|
||||
u.dataBaseType = DATA_BASETYPE_FLOAT;
|
||||
u.textureType = TEXTURE_2D;
|
||||
u.isDepthSampler = true;
|
||||
break;
|
||||
case GL_INT_SAMPLER_2D:
|
||||
u.baseType = UNIFORM_SAMPLER;
|
||||
u.dataBaseType = DATA_BASETYPE_INT;
|
||||
u.textureType = TEXTURE_2D;
|
||||
break;
|
||||
case GL_UNSIGNED_INT_SAMPLER_2D:
|
||||
u.baseType = UNIFORM_SAMPLER;
|
||||
u.dataBaseType = DATA_BASETYPE_UINT;
|
||||
u.textureType = TEXTURE_2D;
|
||||
break;
|
||||
case GL_SAMPLER_2D_ARRAY:
|
||||
u.baseType = UNIFORM_SAMPLER;
|
||||
u.dataBaseType = DATA_BASETYPE_FLOAT;
|
||||
u.textureType = TEXTURE_2D_ARRAY;
|
||||
break;
|
||||
case GL_SAMPLER_2D_ARRAY_SHADOW:
|
||||
u.baseType = UNIFORM_SAMPLER;
|
||||
u.dataBaseType = DATA_BASETYPE_FLOAT;
|
||||
u.textureType = TEXTURE_2D_ARRAY;
|
||||
u.isDepthSampler = true;
|
||||
break;
|
||||
case GL_INT_SAMPLER_2D_ARRAY:
|
||||
u.baseType = UNIFORM_SAMPLER;
|
||||
u.dataBaseType = DATA_BASETYPE_INT;
|
||||
u.textureType = TEXTURE_2D_ARRAY;
|
||||
break;
|
||||
case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
|
||||
u.baseType = UNIFORM_SAMPLER;
|
||||
u.dataBaseType = DATA_BASETYPE_UINT;
|
||||
u.textureType = TEXTURE_2D_ARRAY;
|
||||
break;
|
||||
case GL_SAMPLER_3D:
|
||||
u.baseType = UNIFORM_SAMPLER;
|
||||
u.dataBaseType = DATA_BASETYPE_FLOAT;
|
||||
u.textureType = TEXTURE_VOLUME;
|
||||
break;
|
||||
case GL_INT_SAMPLER_3D:
|
||||
u.baseType = UNIFORM_SAMPLER;
|
||||
u.dataBaseType = DATA_BASETYPE_INT;
|
||||
u.textureType = TEXTURE_VOLUME;
|
||||
break;
|
||||
case GL_UNSIGNED_INT_SAMPLER_3D:
|
||||
u.baseType = UNIFORM_SAMPLER;
|
||||
u.dataBaseType = DATA_BASETYPE_UINT;
|
||||
u.textureType = TEXTURE_VOLUME;
|
||||
break;
|
||||
case GL_SAMPLER_CUBE:
|
||||
u.baseType = UNIFORM_SAMPLER;
|
||||
u.dataBaseType = DATA_BASETYPE_FLOAT;
|
||||
u.textureType = TEXTURE_CUBE;
|
||||
break;
|
||||
case GL_SAMPLER_CUBE_SHADOW:
|
||||
case GL_SAMPLER_CUBE_MAP_ARRAY:
|
||||
case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:
|
||||
return UNIFORM_SAMPLER;
|
||||
u.baseType = UNIFORM_SAMPLER;
|
||||
u.dataBaseType = DATA_BASETYPE_FLOAT;
|
||||
u.textureType = TEXTURE_CUBE;
|
||||
u.isDepthSampler = true;
|
||||
break;
|
||||
case GL_INT_SAMPLER_CUBE:
|
||||
u.baseType = UNIFORM_SAMPLER;
|
||||
u.dataBaseType = DATA_BASETYPE_INT;
|
||||
u.textureType = TEXTURE_CUBE;
|
||||
break;
|
||||
case GL_UNSIGNED_INT_SAMPLER_CUBE:
|
||||
u.baseType = UNIFORM_SAMPLER;
|
||||
u.dataBaseType = DATA_BASETYPE_UINT;
|
||||
u.textureType = TEXTURE_CUBE;
|
||||
break;
|
||||
|
||||
case GL_SAMPLER_BUFFER:
|
||||
u.baseType = UNIFORM_TEXELBUFFER;
|
||||
u.dataBaseType = DATA_BASETYPE_FLOAT;
|
||||
break;
|
||||
case GL_INT_SAMPLER_BUFFER:
|
||||
u.baseType = UNIFORM_TEXELBUFFER;
|
||||
u.dataBaseType = DATA_BASETYPE_INT;
|
||||
break;
|
||||
case GL_UNSIGNED_INT_SAMPLER_BUFFER:
|
||||
return UNIFORM_TEXELBUFFER;
|
||||
default:
|
||||
return UNIFORM_UNKNOWN;
|
||||
}
|
||||
}
|
||||
u.baseType = UNIFORM_TEXELBUFFER;
|
||||
u.dataBaseType = DATA_BASETYPE_UINT;
|
||||
break;
|
||||
|
||||
TextureType Shader::getUniformTextureType(GLenum type) const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case GL_SAMPLER_1D:
|
||||
case GL_SAMPLER_1D_SHADOW:
|
||||
case GL_SAMPLER_1D_ARRAY:
|
||||
case GL_SAMPLER_1D_ARRAY_SHADOW:
|
||||
// 1D-typed textures are not supported.
|
||||
return TEXTURE_MAX_ENUM;
|
||||
case GL_SAMPLER_2D:
|
||||
case GL_SAMPLER_2D_SHADOW:
|
||||
return TEXTURE_2D;
|
||||
case GL_SAMPLER_2D_MULTISAMPLE:
|
||||
case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
|
||||
// Multisample textures are not supported.
|
||||
return TEXTURE_MAX_ENUM;
|
||||
case GL_SAMPLER_2D_RECT:
|
||||
case GL_SAMPLER_2D_RECT_SHADOW:
|
||||
// Rectangle textures are not supported.
|
||||
return TEXTURE_MAX_ENUM;
|
||||
case GL_SAMPLER_2D_ARRAY:
|
||||
case GL_SAMPLER_2D_ARRAY_SHADOW:
|
||||
return TEXTURE_2D_ARRAY;
|
||||
case GL_SAMPLER_3D:
|
||||
return TEXTURE_VOLUME;
|
||||
case GL_SAMPLER_CUBE:
|
||||
case GL_SAMPLER_CUBE_SHADOW:
|
||||
return TEXTURE_CUBE;
|
||||
case GL_SAMPLER_CUBE_MAP_ARRAY:
|
||||
case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:
|
||||
// Cubemap array textures are not supported.
|
||||
return TEXTURE_MAX_ENUM;
|
||||
default:
|
||||
return TEXTURE_MAX_ENUM;
|
||||
}
|
||||
}
|
||||
|
||||
DataBaseType Shader::getUniformTexelBufferType(GLenum type) const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case GL_SAMPLER_BUFFER:
|
||||
return DATA_BASETYPE_FLOAT;
|
||||
case GL_INT_SAMPLER_BUFFER:
|
||||
return DATA_BASETYPE_INT;
|
||||
case GL_UNSIGNED_INT_SAMPLER_BUFFER:
|
||||
return DATA_BASETYPE_UINT;
|
||||
default:
|
||||
return DATA_BASETYPE_MAX_ENUM;
|
||||
}
|
||||
}
|
||||
|
||||
bool Shader::isDepthTextureType(GLenum type) const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case GL_SAMPLER_1D_SHADOW:
|
||||
case GL_SAMPLER_1D_ARRAY_SHADOW:
|
||||
case GL_SAMPLER_2D_SHADOW:
|
||||
case GL_SAMPLER_2D_ARRAY_SHADOW:
|
||||
case GL_SAMPLER_CUBE_SHADOW:
|
||||
case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -92,11 +92,8 @@ private:
|
||||
void sendBuffers(const UniformInfo *info, love::graphics::Buffer **buffers, int count, bool internalupdate);
|
||||
|
||||
int getUniformTypeComponents(GLenum type) const;
|
||||
void computeUniformTypeInfo(GLenum type, UniformInfo &u);
|
||||
MatrixSize getMatrixSize(GLenum type) const;
|
||||
UniformType getUniformBaseType(GLenum type) const;
|
||||
TextureType getUniformTextureType(GLenum type) const;
|
||||
DataBaseType getUniformTexelBufferType(GLenum type) const;
|
||||
bool isDepthTextureType(GLenum type) const;
|
||||
|
||||
void flushBatchedDraws() const;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user