LLE : Expanded NV2A formats and added conversions (using libyuv row-conversions) for some that cannot map directly to an OpenGL format.

This commit is contained in:
PatrickvL 2018-06-25 14:42:53 +02:00
parent a7f658ed8d
commit d394d2e48c
1 changed files with 195 additions and 160 deletions

View File

@ -125,35 +125,41 @@ static const GLenum pgraph_stencil_op_map[] = {
GL_DECR_WRAP, GL_DECR_WRAP,
}; };
enum FormatEncoding {
linear = 0,
swizzled, // for all NV097_SET_TEXTURE_FORMAT_*_SZ_*
compressed // for all NV097_SET_TEXTURE_FORMAT_*_DXT*
};
typedef struct ColorFormatInfo { typedef struct ColorFormatInfo {
unsigned int bytes_per_pixel; // Derived from the total number of channel bits unsigned int bytes_per_pixel; // Derived from the total number of channel bits
bool linear; // True for all NV097_SET_TEXTURE_FORMAT_COLOR_LU_* (and _LC_*?) FormatEncoding encoding;
GLint gl_internal_format; GLint gl_internal_format;
GLenum gl_format; GLenum gl_format; // == 0 for compressed formats
GLenum gl_type; GLenum gl_type;
GLenum gl_swizzle_mask[4]; GLint gl_swizzle_mask[4];
} ColorFormatInfo; } ColorFormatInfo;
// Note : Avoid designated initializers to facilitate C++ builds // Note : Avoid designated initializers to facilitate C++ builds
static const ColorFormatInfo kelvin_color_format_map[256] = { static const ColorFormatInfo kelvin_color_format_map[256] = {
//0x00 [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_Y8] = //0x00 [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_Y8] =
{1, false, GL_R8, GL_RED, GL_UNSIGNED_BYTE, {1, swizzled, GL_R8, GL_RED, GL_UNSIGNED_BYTE,
{GL_RED, GL_RED, GL_RED, GL_ONE}}, {GL_RED, GL_RED, GL_RED, GL_ONE}},
//0x01 [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_AY8] = //0x01 [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_AY8] =
{1, false, GL_R8, GL_RED, GL_UNSIGNED_BYTE, {1, swizzled, GL_R8, GL_RED, GL_UNSIGNED_BYTE,
{GL_RED, GL_RED, GL_RED, GL_RED}}, {GL_RED, GL_RED, GL_RED, GL_RED}},
//0x02 [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_A1R5G5B5] = //0x02 [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_A1R5G5B5] =
{2, false, GL_RGB5_A1, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV}, {2, swizzled, GL_RGB5_A1, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV},
//0x03 [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_X1R5G5B5] = //0x03 [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_X1R5G5B5] =
{2, false, GL_RGB5, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV}, {2, swizzled, GL_RGB5, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV},
//0x04 [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_A4R4G4B4] = //0x04 [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_A4R4G4B4] =
{2, false, GL_RGBA4, GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV}, {2, swizzled, GL_RGBA4, GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV},
//0x05 [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_R5G6B5] = //0x05 [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_R5G6B5] =
{2, false, GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5}, {2, swizzled, GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5},
//0x06 [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_A8R8G8B8] = //0x06 [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_A8R8G8B8] =
{4, false, GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV}, {4, swizzled, GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV},
//0x07 [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_X8R8G8B8] = //0x07 [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_X8R8G8B8] =
{4, false, GL_RGB8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV}, {4, swizzled, GL_RGB8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV},
//0x08 [?] = //0x08 [?] =
{}, {},
//0x09 [?] = //0x09 [?] =
@ -162,58 +168,61 @@ static const ColorFormatInfo kelvin_color_format_map[256] = {
{}, {},
/* paletted texture */ /* paletted texture */
//0x0B [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_I8_A8R8G8B8] = //0x0B [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_I8_A8R8G8B8] = // See convert_texture_data
{1, false, GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV}, // See convert_texture_data {1, swizzled, GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV},
//0x0C [NV097_SET_TEXTURE_FORMAT_COLOR_L_DXT1_A1R5G5B5] = //0x0C [NV097_SET_TEXTURE_FORMAT_COLOR_L_DXT1_A1R5G5B5] =
{4, false, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 0, GL_RGBA}, {4, compressed, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 0, GL_RGBA},
//0x0D [?] = //0x0D [?] =
{}, {},
//0x0E [NV097_SET_TEXTURE_FORMAT_COLOR_L_DXT23_A8R8G8B8] = //0x0E [NV097_SET_TEXTURE_FORMAT_COLOR_L_DXT23_A8R8G8B8] =
{4, false, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 0, GL_RGBA}, {4, compressed, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 0, GL_RGBA},
//0x0F [NV097_SET_TEXTURE_FORMAT_COLOR_L_DXT45_A8R8G8B8] = //0x0F [NV097_SET_TEXTURE_FORMAT_COLOR_L_DXT45_A8R8G8B8] =
{4, false, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, 0, GL_RGBA}, {4, compressed, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, 0, GL_RGBA},
//0x10 [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_A1R5G5B5] = //0x10 [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_A1R5G5B5] =
{2, true, GL_RGB5_A1, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV}, {2, linear, GL_RGB5_A1, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV},
//0x11 [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_R5G6B5] = //0x11 [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_R5G6B5] =
{2, true, GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5}, {2, linear, GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5},
//0x12 [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_A8R8G8B8] = //0x12 [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_A8R8G8B8] =
{4, true, GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV}, {4, linear, GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV},
//0x13 [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_Y8] = //0x13 [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_Y8] =
{1, true, GL_R8, GL_RED, GL_UNSIGNED_BYTE, {1, linear, GL_R8, GL_RED, GL_UNSIGNED_BYTE,
{GL_RED, GL_RED, GL_RED, GL_ONE}}, {GL_RED, GL_RED, GL_RED, GL_ONE}},
//0x14 [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_SY8] = //0x14 [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_SY8] =
{1, true, GL_R8, GL_RED, GL_BYTE, /* FIXME: This might be signed */ {1, linear, GL_R8, GL_RED, GL_BYTE,
{GL_RED, GL_RED, GL_RED, GL_ONE}}, // TODO : Verify {GL_RED, GL_RED, GL_RED, GL_ONE}}, // TODO : Verify
//0x15 [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_X7SY9] = //0x15 [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_X7SY9] = // See convert_texture_data
{2, true}, // TODO : Complete {2, linear, GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV}, // TODO : Verify
//0x16 [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_R8B8] = //0x16 [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_R8B8] =
{2, true}, // TODO : Complete {2, linear, GL_RG8_SNORM, GL_RG, GL_UNSIGNED_BYTE,
{GL_RED, GL_ZERO, GL_GREEN, GL_ONE}}, // TODO : Verify
//0x17 [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_G8B8] = //0x17 [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_G8B8] =
{2, true}, // TODO : Complete {2, linear, GL_RG8_SNORM, GL_RG, GL_UNSIGNED_BYTE,
{GL_ZERO, GL_RED, GL_GREEN, GL_ONE}}, // TODO : Verify
//0x18 [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_SG8SB8] = //0x18 [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_SG8SB8] =
{2, true}, // TODO : Complete {2, linear, GL_RG8_SNORM, GL_RG, GL_BYTE,
{GL_ZERO, GL_RED, GL_GREEN, GL_ONE}}, // TODO : Verify
//0x19 [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_A8] = //0x19 [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_A8] =
{1, false, GL_R8, GL_RED, GL_UNSIGNED_BYTE, {1, swizzled, GL_R8, GL_RED, GL_UNSIGNED_BYTE,
{GL_ONE, GL_ONE, GL_ONE, GL_RED}}, {GL_ONE, GL_ONE, GL_ONE, GL_RED}},
//0x1A [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_A8Y8] = //0x1A [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_A8Y8] =
{2, false, GL_RG8, GL_RG, GL_UNSIGNED_BYTE, {2, swizzled, GL_RG8, GL_RG, GL_UNSIGNED_BYTE,
{GL_GREEN, GL_GREEN, GL_GREEN, GL_RED}}, {GL_GREEN, GL_GREEN, GL_GREEN, GL_RED}},
//0x1B [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_AY8] = //0x1B [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_AY8] =
{1, true, GL_R8, GL_RED, GL_UNSIGNED_BYTE, {1, linear, GL_R8, GL_RED, GL_UNSIGNED_BYTE,
{GL_RED, GL_RED, GL_RED, GL_RED}}, {GL_RED, GL_RED, GL_RED, GL_RED}},
//0x1C [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_X1R5G5B5] = //0x1C [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_X1R5G5B5] =
{2, true, GL_RGB5, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV}, {2, linear, GL_RGB5, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV},
//0x1D [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_A4R4G4B4] = //0x1D [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_A4R4G4B4] =
{2, true, GL_RGBA4, GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV}, // TODO : Verify this is truely linear {2, linear, GL_RGBA4, GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV}, // TODO : Verify this is truely linear
//0x1E [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_X8R8G8B8] = //0x1E [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_X8R8G8B8] =
{4, true, GL_RGB8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV}, {4, linear, GL_RGB8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV},
//0x1F [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_A8] = //0x1F [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_A8] =
{1, true, GL_R8, GL_RED, GL_UNSIGNED_BYTE, {1, linear, GL_R8, GL_RED, GL_UNSIGNED_BYTE,
{GL_ONE, GL_ONE, GL_ONE, GL_RED}}, {GL_ONE, GL_ONE, GL_ONE, GL_RED}},
//0x20 [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_A8Y8] = //0x20 [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_A8Y8] =
{2, true, GL_RG8, GL_RG, GL_UNSIGNED_BYTE, {2, linear, GL_RG8, GL_RG, GL_UNSIGNED_BYTE,
{GL_GREEN, GL_GREEN, GL_GREEN, GL_RED}}, {GL_GREEN, GL_GREEN, GL_GREEN, GL_RED}},
//0x21 [?] = //0x21 [?] =
{}, {},
@ -221,81 +230,78 @@ static const ColorFormatInfo kelvin_color_format_map[256] = {
{}, {},
//0x23 [?] = //0x23 [?] =
{}, {},
//0x24 [NV097_SET_TEXTURE_FORMAT_COLOR_LC_IMAGE_CR8YB8CB8YA8] = //0x24 [NV097_SET_TEXTURE_FORMAT_COLOR_LC_IMAGE_CR8YB8CB8YA8] = // See convert_texture_data calling ____UYVYToARGBRow_C
{ 2, true, GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, // See convert_texture_data and convert_yuy2_to_rgb {2, linear, GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8}, // TODO : Verify
{GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA}}, // TODO : Verify //0x25 [NV097_SET_TEXTURE_FORMAT_COLOR_LC_IMAGE_YB8CR8YA8CB8] = // See convert_texture_data calling ____YUY2ToARGBRow_C
//0x25 [NV097_SET_TEXTURE_FORMAT_COLOR_LC_IMAGE_YB8CR8YA8CB8] = {2, linear, GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8}, // TODO : Verify
{ 2, true, GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, // See convert_texture_data and convert_yuy2_to_rgb //0x26 [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_A8CR8CB8Y8] = // See convert_texture_data
{GL_GREEN, GL_RED, GL_ALPHA, GL_BLUE}}, // TODO : Verify {2, linear, GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8}, // TODO : Verify
//0x26 [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_A8CR8CB8Y8] =
{ 2, true, GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, // See convert_texture_data and convert_yuy2_to_rgb
{GL_ALPHA, GL_RED, GL_BLUE, GL_GREEN}}, // TODO : Verify
//0x27 [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_R6G5B5] = //0x27 [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_R6G5B5] = // See convert_texture_data
{2, false, GL_RGB8_SNORM, GL_RGB, GL_BYTE}, /* FIXME: This might be signed */ // See convert_texture_data {2, swizzled, GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV},
//0x28 [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_G8B8] = //0x28 [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_G8B8] =
{2, false, GL_RG8_SNORM, GL_RG, GL_BYTE, /* FIXME: This might be signed */ {2, swizzled, GL_RG8_SNORM, GL_RG, GL_UNSIGNED_BYTE,
{GL_ZERO, GL_RED, GL_GREEN, GL_ONE}}, {GL_ZERO, GL_RED, GL_GREEN, GL_ONE}},
//0x29 [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_R8B8] = //0x29 [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_R8B8] =
{2, false, GL_RG8_SNORM, GL_RG, GL_BYTE, /* FIXME: This might be signed */ {2, swizzled, GL_RG8_SNORM, GL_RG, GL_UNSIGNED_BYTE,
{GL_RED, GL_ZERO, GL_GREEN, GL_ONE}}, {GL_RED, GL_ZERO, GL_GREEN, GL_ONE}},
//0x2A [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_DEPTH_X8_Y24_FIXED] = //0x2A [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_DEPTH_X8_Y24_FIXED] =
{4, false, GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8}, // TODO : Verify {4, swizzled, GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8}, // TODO : Verify
//0x2B [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_DEPTH_X8_Y24_FLOAT] = //0x2B [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_DEPTH_X8_Y24_FLOAT] =
{4, false, GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV}, // TODO : Verify {4, swizzled, GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV}, // TODO : Verify
//0x2C [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_DEPTH_Y16_FIXED] = //0x2C [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_DEPTH_Y16_FIXED] =
{2, false, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}, // TODO : Verify {2, swizzled, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}, // TODO : Verify
//0x2D [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_DEPTH_Y16_FLOAT] = //0x2D [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_DEPTH_Y16_FLOAT] =
{2, false, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_FLOAT}, // TODO : Verify {2, swizzled, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_FLOAT}, // TODO : Verify
/* TODO: format conversion */ /* TODO: format conversion */
//0x2E [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_DEPTH_X8_Y24_FIXED] = //0x2E [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_DEPTH_X8_Y24_FIXED] =
{4, true, GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8}, {4, linear, GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8},
//0x2F [?] = //0x2F [?] =
{}, {},
//0x30 [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_DEPTH_Y16_FIXED] = //0x30 [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_DEPTH_Y16_FIXED] =
{2, true, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}, {2, linear, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT},
//0x31 [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_DEPTH_Y16_FLOAT] = //0x31 [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_DEPTH_Y16_FLOAT] =
{2, true, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_FLOAT}, // TODO : Verify {2, linear, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_FLOAT}, // TODO : Verify
//0x32 [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_Y16] = //0x32 [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_Y16] =
{2, false, GL_R16, GL_RED, GL_UNSIGNED_SHORT, // TODO : Verify {2, swizzled, GL_R16, GL_RED, GL_UNSIGNED_SHORT, // TODO : Verify
{GL_RED, GL_RED, GL_RED, GL_ONE}}, {GL_RED, GL_RED, GL_RED, GL_ONE}},
//0x33 [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_YB_16_YA_16] = //0x33 [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_YB_16_YA_16] =
{4, false, GL_R16, GL_RED, GL_UNSIGNED_SHORT, // TODO : Verify {4, swizzled, GL_R16, GL_RED, GL_UNSIGNED_SHORT, // TODO : Verify
{GL_RED, GL_RED, GL_RED, GL_GREEN}}, {GL_RED, GL_RED, GL_RED, GL_GREEN}},
//0x34 [NV097_SET_TEXTURE_FORMAT_COLOR_LC_IMAGE_A4V6YB6A4U6YA6] = //0x34 [NV097_SET_TEXTURE_FORMAT_COLOR_LC_IMAGE_A4V6YB6A4U6YA6] =
{4, true}, // TODO : Complete {4, linear}, // TODO : Complete this declaration
//0x35 [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_Y16] = //0x35 [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_Y16] =
{2, true, GL_R16, GL_RED, GL_UNSIGNED_SHORT, {2, linear, GL_R16, GL_RED, GL_UNSIGNED_SHORT,
{GL_RED, GL_RED, GL_RED, GL_ONE}}, {GL_RED, GL_RED, GL_RED, GL_ONE}},
//0x36 [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_YB16YA16] = //0x36 [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_YB16YA16] =
{4, true, GL_R16, GL_RED, GL_UNSIGNED_SHORT, // TODO : Verify {4, linear, GL_R16, GL_RED, GL_UNSIGNED_SHORT, // TODO : Verify
{GL_RED, GL_RED, GL_GREEN, GL_GREEN}}, {GL_RED, GL_RED, GL_GREEN, GL_GREEN}},
//0x37 [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_R6G5B5] = //0x37 [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_R6G5B5] = // See convert_texture_data
{2, false, GL_RGB8_SNORM, GL_RGB, GL_BYTE}, /* FIXME: This might be signed */ // TODO : Verify {2, linear, GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV},
//0x38 [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_R5G5B5A1] = //0x38 [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_R5G5B5A1] = // See convert_texture_data
{2, false}, // TODO : Complete {2, swizzled, GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV}, // TODO : Verify
//0x39 [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_R4G4B4A4] = //0x39 [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_R4G4B4A4] = // See convert_texture_data
{2, false}, // TODO : Complete {2, swizzled, GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV}, // TODO : Verify
//0x3A [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_A8B8G8R8] = //0x3A [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_A8B8G8R8] =
{4, false, GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV}, {4, swizzled, GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV}, // TODO : Verify
//0x3B [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_B8G8R8A8] = //0x3B [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_B8G8R8A8] =
{4, false, GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8}, // TODO : Verify {4, swizzled, GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8}, // TODO : Verify
//0x3C [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_R8G8B8A8] = //0x3C [NV097_SET_TEXTURE_FORMAT_COLOR_SZ_R8G8B8A8] =
{4, false, GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8}, {4, swizzled, GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8},
//0x3D [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_R5G5B5A1] = //0x3D [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_R5G5B5A1] = // See convert_texture_data
{2, true}, // TODO : Complete {2, linear, GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV}, // TODO : Verify
//0x3E [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_R4G4B4A4] = //0x3E [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_R4G4B4A4] = // See convert_texture_data
{2, true}, // TODO : Complete {2, linear, GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV}, // TODO : Verify
//0x3F [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_A8B8G8R8] = //0x3F [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_A8B8G8R8] =
{4, true, GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV}, {4, linear, GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV}, // TODO : Verify
//0x40 [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_B8G8R8A8] = //0x40 [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_B8G8R8A8] =
{4, true, GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8}, {4, linear, GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8}, // TODO : Verify
//0x41 [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_R8G8B8A8] = //0x41 [NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_R8G8B8A8] =
{4, true, GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8}, {4, linear, GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8}, // TODO : Verify
}; };
typedef struct SurfaceColorFormatInfo { typedef struct SurfaceColorFormatInfo {
@ -366,9 +372,7 @@ static void load_graphics_object(NV2AState *d, hwaddr instance_address, Graphics
static GraphicsObject* lookup_graphics_object(PGRAPHState *s, hwaddr instance_address); static GraphicsObject* lookup_graphics_object(PGRAPHState *s, hwaddr instance_address);
static float convert_f16_to_float(uint16_t f16); static float convert_f16_to_float(uint16_t f16);
static float convert_f24_to_float(uint32_t f24); static float convert_f24_to_float(uint32_t f24);
static uint8_t cliptobyte(int x); static uint8_t* convert_texture_data(const unsigned int color_format, const uint8_t *data, const uint8_t *palette_data, const unsigned int width, const unsigned int height, const unsigned int depth, const unsigned int row_pitch, const unsigned int slice_pitch);
static void convert_yuy2_to_rgb(const uint8_t *line, unsigned int ix, uint8_t *r, uint8_t *g, uint8_t* b);
static uint8_t* convert_texture_data(const TextureShape s, const uint8_t *data, const uint8_t *palette_data, unsigned int width, unsigned int height, unsigned int depth, unsigned int row_pitch, unsigned int slice_pitch);
static void upload_gl_texture(GLenum gl_target, const TextureShape s, const uint8_t *texture_data, const uint8_t *palette_data); static void upload_gl_texture(GLenum gl_target, const TextureShape s, const uint8_t *texture_data, const uint8_t *palette_data);
static TextureBinding* generate_texture(const TextureShape s, const uint8_t *texture_data, const uint8_t *palette_data); static TextureBinding* generate_texture(const TextureShape s, const uint8_t *texture_data, const uint8_t *palette_data);
static guint texture_key_hash(gconstpointer key); static guint texture_key_hash(gconstpointer key);
@ -3164,7 +3168,7 @@ static void pgraph_bind_shaders(PGRAPHState *pg)
GET_MASK(pg->regs[NV_PGRAPH_TEXFMT0 + i*4], GET_MASK(pg->regs[NV_PGRAPH_TEXFMT0 + i*4],
NV_PGRAPH_TEXFMT0_COLOR); NV_PGRAPH_TEXFMT0_COLOR);
if (enabled && kelvin_color_format_map[color_format].linear) { if (enabled && kelvin_color_format_map[color_format].encoding == linear) {
state.psh.rect_tex[i] = true; state.psh.rect_tex[i] = true;
} }
@ -3679,7 +3683,7 @@ static void pgraph_bind_textures(NV2AState *d)
} }
unsigned int width, height, depth; unsigned int width, height, depth;
if (f.linear) { if (f.encoding == linear) {
assert(dimensionality == 2); assert(dimensionality == 2);
width = rect_width; width = rect_width;
height = rect_height; height = rect_height;
@ -3691,7 +3695,7 @@ static void pgraph_bind_textures(NV2AState *d)
/* FIXME: What about 3D mipmaps? */ /* FIXME: What about 3D mipmaps? */
levels = MIN(levels, max_mipmap_level + 1); levels = MIN(levels, max_mipmap_level + 1);
if (f.gl_format != 0) { if (f.encoding == swizzled) {
/* Discard mipmap levels that would be smaller than 1x1. /* Discard mipmap levels that would be smaller than 1x1.
* FIXME: Is this actually needed? * FIXME: Is this actually needed?
* *
@ -3757,7 +3761,7 @@ static void pgraph_bind_textures(NV2AState *d)
NV2A_DPRINTF(" - 0x%tx\n", texture_data - d->vram_ptr); NV2A_DPRINTF(" - 0x%tx\n", texture_data - d->vram_ptr);
size_t length = 0; size_t length = 0;
if (f.linear) { if (f.encoding == linear) {
assert(cubemap == false); assert(cubemap == false);
assert(dimensionality == 2); assert(dimensionality == 2);
length = height * pitch; length = height * pitch;
@ -3765,7 +3769,7 @@ static void pgraph_bind_textures(NV2AState *d)
if (dimensionality >= 2) { if (dimensionality >= 2) {
unsigned int w = width, h = height; unsigned int w = width, h = height;
unsigned int level; unsigned int level;
if (f.gl_format != 0) { if (f.encoding == swizzled) {
for (level = 0; level < levels; level++) { for (level = 0; level < levels; level++) {
w = MAX(w, 1); h = MAX(h, 1); w = MAX(w, 1); h = MAX(h, 1);
length += w * h * f.bytes_per_pixel; length += w * h * f.bytes_per_pixel;
@ -3833,8 +3837,8 @@ static void pgraph_bind_textures(NV2AState *d)
glBindTexture(binding->gl_target, binding->gl_texture); glBindTexture(binding->gl_target, binding->gl_texture);
if (f.linear) { if (f.encoding == linear) {
/* somtimes games try to set mipmap min filters on linear textures. /* sometimes games try to set mipmap min filters on linear textures.
* this could indicate a bug... */ * this could indicate a bug... */
switch (min_filter) { switch (min_filter) {
case NV_PGRAPH_TEXFILTER0_MIN_BOX_NEARESTLOD: case NV_PGRAPH_TEXFILTER0_MIN_BOX_NEARESTLOD:
@ -4157,37 +4161,23 @@ static float convert_f24_to_float(uint32_t f24) {
return *(float*)&i; return *(float*)&i;
} }
static uint8_t cliptobyte(int x) extern void __R6G5B5ToARGBRow_C(const uint8* src_r6g5b5, uint8* dst_argb, int width);
{ extern void ____YUY2ToARGBRow_C(const uint8* src_yuy2, uint8* rgb_buf, int width);
return (uint8_t)((x < 0) ? 0 : ((x > 255) ? 255 : x)); extern void ____UYVYToARGBRow_C(const uint8* src_uyvy, uint8* rgb_buf, int width);
} extern void R5G5B5A1ToARGBRow_C(const uint8* src_r5g5b5a1, uint8* dst_argb, int width);
extern void R4G4B4A4ToARGBRow_C(const uint8* src_argb4444, uint8* dst_argb, int width);
static void convert_yuy2_to_rgb(const uint8_t *line, unsigned int ix, static uint8_t* convert_texture_data(const unsigned int color_format,
uint8_t *r, uint8_t *g, uint8_t* b) {
int c, d, e;
c = (int)line[ix * 2] - 16;
if (ix % 2) {
d = (int)line[ix * 2 - 1] - 128;
e = (int)line[ix * 2 + 1] - 128;
} else {
d = (int)line[ix * 2 + 1] - 128;
e = (int)line[ix * 2 + 3] - 128;
}
*r = cliptobyte((298 * c + 409 * e + 128) >> 8);
*g = cliptobyte((298 * c - 100 * d - 208 * e + 128) >> 8);
*b = cliptobyte((298 * c + 516 * d + 128) >> 8);
}
static uint8_t* convert_texture_data(const TextureShape s,
const uint8_t *data, const uint8_t *data,
const uint8_t *palette_data, const uint8_t *palette_data,
unsigned int width, const unsigned int width,
unsigned int height, const unsigned int height,
unsigned int depth, const unsigned int depth,
unsigned int row_pitch, const unsigned int row_pitch,
unsigned int slice_pitch) const unsigned int slice_pitch)
{ {
switch (s.color_format) { // Note : Unswizzle is already done when entering here
switch (color_format) {
case NV097_SET_TEXTURE_FORMAT_COLOR_SZ_I8_A8R8G8B8: { case NV097_SET_TEXTURE_FORMAT_COLOR_SZ_I8_A8R8G8B8: {
assert(depth == 1); /* FIXME */ assert(depth == 1); /* FIXME */
uint8_t* converted_data = (uint8_t*)g_malloc(width * height * 4); uint8_t* converted_data = (uint8_t*)g_malloc(width * height * 4);
@ -4201,42 +4191,72 @@ static uint8_t* convert_texture_data(const TextureShape s,
} }
return converted_data; return converted_data;
} }
case NV097_SET_TEXTURE_FORMAT_COLOR_LC_IMAGE_CR8YB8CB8YA8: case NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_X7SY9: {
case NV097_SET_TEXTURE_FORMAT_COLOR_LC_IMAGE_YB8CR8YA8CB8: assert(false); /* FIXME */
case NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_A8CR8CB8Y8: { return NULL;
}
case NV097_SET_TEXTURE_FORMAT_COLOR_LC_IMAGE_CR8YB8CB8YA8: {
assert(depth == 1); /* FIXME */ assert(depth == 1); /* FIXME */
uint8_t* converted_data = (uint8_t*)g_malloc(width * height * 4); uint8_t* converted_data = (uint8_t*)g_malloc(width * height * 4);
unsigned int x, y; unsigned int y;
for (y = 0; y < height; y++) { for (y = 0; y < height; y++) {
const uint8_t* line = &data[y * s.width * 2]; const uint8_t* line = &data[y * width * 2];
for (x = 0; x < width; x++) { uint8_t* pixel = &converted_data[(y * width) * 4];
uint8_t* pixel = &converted_data[(y * s.width + x) * 4]; ____UYVYToARGBRow_C(line, pixel, width);
/* FIXME: Actually needs uyvy? */
convert_yuy2_to_rgb(line, x, &pixel[0], &pixel[1], &pixel[2]);
pixel[3] = 255;
}
} }
return converted_data; return converted_data;
} }
case NV097_SET_TEXTURE_FORMAT_COLOR_SZ_R6G5B5: { case NV097_SET_TEXTURE_FORMAT_COLOR_LC_IMAGE_YB8CR8YA8CB8: {
assert(depth == 1); /* FIXME */ assert(depth == 1); /* FIXME */
uint8_t *converted_data = (uint8_t*)g_malloc(width * height * 3); uint8_t* converted_data = (uint8_t*)g_malloc(width * height * 4);
unsigned int x, y; unsigned int y;
for (y = 0; y < height; y++) { for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) { const uint8_t* line = &data[y * width * 2];
uint16_t rgb655 = *(uint16_t*)(data + y * row_pitch + x * 2); uint8_t* pixel = &converted_data[(y * width) * 4];
int8_t *pixel = (int8_t*)&converted_data[(y * width + x) * 3]; ____YUY2ToARGBRow_C(line, pixel, width);
/* Maps 5 bit G and B signed value range to 8 bit }
* signed values. R is probably unsigned. return converted_data;
*/ }
rgb655 ^= (1 << 9) | (1 << 4); case NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_A8CR8CB8Y8: {
pixel[0] = ((rgb655 & 0xFC00) >> 10) * 0x7F / 0x3F; assert(false); /* FIXME */
pixel[1] = ((rgb655 & 0x03E0) >> 5) * 0xFF / 0x1F - 0x80; return NULL;
pixel[2] = (rgb655 & 0x001F) * 0xFF / 0x1F - 0x80; }
} case NV097_SET_TEXTURE_FORMAT_COLOR_SZ_R6G5B5:
case NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_R6G5B5: {
assert(depth == 1); /* FIXME */
uint8_t *converted_data = (uint8_t*)g_malloc(width * height * 4);
unsigned int y;
for (y = 0; y < height; y++) {
uint16_t rgb655 = *(uint16_t*)(data + y * row_pitch);
int8_t *pixel = (int8_t*)&converted_data[(y * width) * 4];
__R6G5B5ToARGBRow_C((const uint8*)rgb655, (uint8*)pixel, width);
} }
return converted_data; return converted_data;
} }
case NV097_SET_TEXTURE_FORMAT_COLOR_SZ_R5G5B5A1:
case NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_R5G5B5A1: {
assert(depth == 1); /* FIXME */
uint8_t *converted_data = (uint8_t*)g_malloc(width * height * 4);
unsigned int y;
for (y = 0; y < height; y++) {
uint16_t r5g5b5a1 = *(uint16_t*)(data + y * row_pitch);
int8_t *pixel = (int8_t*)&converted_data[(y * width) * 4];
R5G5B5A1ToARGBRow_C((uint8_t *)r5g5b5a1, (uint8_t *)pixel, width);
}
return converted_data;
}
case NV097_SET_TEXTURE_FORMAT_COLOR_SZ_R4G4B4A4:
case NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_R4G4B4A4: {
assert(depth == 1); /* FIXME */
uint8_t *converted_data = (uint8_t*)g_malloc(width * height * 4);
unsigned int y;
for (y = 0; y < height; y++) {
uint16_t r4g4b4a4 = *(uint16_t*)(data + y * row_pitch);
int8_t *pixel = (int8_t*)&converted_data[(y * width) * 4];
R4G4B4A4ToARGBRow_C((uint8_t *)r4g4b4a4, (uint8_t *)pixel, width);
}
return converted_data;
}
default: default:
return NULL; return NULL;
} }
@ -4261,7 +4281,13 @@ static void upload_gl_texture(GLenum gl_target,
glPixelStorei(GL_UNPACK_ROW_LENGTH, glPixelStorei(GL_UNPACK_ROW_LENGTH,
s.pitch / f.bytes_per_pixel); s.pitch / f.bytes_per_pixel);
uint8_t *converted = convert_texture_data(s, texture_data, uint8_t *unswizzled = NULL;
if (f.encoding == swizzled) { // TODO : Verify this works correctly
unswizzled = (uint8_t*)g_malloc(s.height * s.pitch);
unswizzle_rect(texture_data, s.width, s.height,
unswizzled, s.pitch, f.bytes_per_pixel);
}
uint8_t *converted = convert_texture_data(s.color_format, unswizzled ? unswizzled : texture_data,
palette_data, palette_data,
s.width, s.height, 1, s.width, s.height, 1,
s.pitch, 0); s.pitch, 0);
@ -4269,11 +4295,14 @@ static void upload_gl_texture(GLenum gl_target,
glTexImage2D(gl_target, 0, f.gl_internal_format, glTexImage2D(gl_target, 0, f.gl_internal_format,
s.width, s.height, 0, s.width, s.height, 0,
f.gl_format, f.gl_type, f.gl_format, f.gl_type,
converted ? converted : texture_data); converted ? converted : unswizzled ? unswizzled : texture_data);
if (converted) { if (converted) {
g_free(converted); g_free(converted);
} }
if (unswizzled) {
g_free(unswizzled);
}
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
break; break;
@ -4290,7 +4319,7 @@ static void upload_gl_texture(GLenum gl_target,
unsigned int level; unsigned int level;
for (level = 0; level < s.levels; level++) { for (level = 0; level < s.levels; level++) {
if (f.gl_format == 0) { /* compressed */ if (f.encoding == compressed) {
width = MAX(width, 4); height = MAX(height, 4); width = MAX(width, 4); height = MAX(height, 4);
@ -4312,11 +4341,14 @@ static void upload_gl_texture(GLenum gl_target,
width = MAX(width, 1); height = MAX(height, 1); width = MAX(width, 1); height = MAX(height, 1);
unsigned int pitch = width * f.bytes_per_pixel; unsigned int pitch = width * f.bytes_per_pixel;
uint8_t *unswizzled = (uint8_t*)g_malloc(height * pitch); uint8_t *unswizzled = NULL;
unswizzle_rect(texture_data, width, height, if (f.encoding == swizzled) {
unswizzled, pitch, f.bytes_per_pixel); unswizzled = (uint8_t*)g_malloc(height * pitch);
unswizzle_rect(texture_data, width, height,
unswizzled, pitch, f.bytes_per_pixel);
}
uint8_t *converted = convert_texture_data(s, unswizzled, uint8_t *converted = convert_texture_data(s.color_format, unswizzled ? unswizzled : texture_data,
palette_data, palette_data,
width, height, 1, width, height, 1,
pitch, 0); pitch, 0);
@ -4324,12 +4356,14 @@ static void upload_gl_texture(GLenum gl_target,
glTexImage2D(gl_target, level, f.gl_internal_format, glTexImage2D(gl_target, level, f.gl_internal_format,
width, height, 0, width, height, 0,
f.gl_format, f.gl_type, f.gl_format, f.gl_type,
converted ? converted : unswizzled); converted ? converted : unswizzled ? unswizzled : texture_data);
if (converted) { if (converted) {
g_free(converted); g_free(converted);
} }
g_free(unswizzled); if (unswizzled) {
g_free(unswizzled);
}
texture_data += width * height * f.bytes_per_pixel; texture_data += width * height * f.bytes_per_pixel;
} }
@ -4344,19 +4378,18 @@ static void upload_gl_texture(GLenum gl_target,
unsigned int width = s.width, height = s.height, depth = s.depth; unsigned int width = s.width, height = s.height, depth = s.depth;
assert(f.gl_format != 0); /* FIXME: compressed not supported yet */
assert(f.linear == false);
unsigned int level; unsigned int level;
for (level = 0; level < s.levels; level++) { for (level = 0; level < s.levels; level++) {
unsigned int row_pitch = width * f.bytes_per_pixel; unsigned int row_pitch = width * f.bytes_per_pixel;
unsigned int slice_pitch = row_pitch * height; unsigned int slice_pitch = row_pitch * height;
uint8_t *unswizzled = (uint8_t*)g_malloc(slice_pitch * depth); uint8_t *unswizzled = NULL;
unswizzle_box(texture_data, width, height, depth, unswizzled, if (f.encoding == swizzled) {
row_pitch, slice_pitch, f.bytes_per_pixel); unswizzled = (uint8_t*)g_malloc(slice_pitch * depth);
unswizzle_box(texture_data, width, height, depth, unswizzled,
uint8_t *converted = convert_texture_data(s, unswizzled, row_pitch, slice_pitch, f.bytes_per_pixel);
}
uint8_t *converted = convert_texture_data(s.color_format, unswizzled ? unswizzled : texture_data,
palette_data, palette_data,
width, height, depth, width, height, depth,
row_pitch, slice_pitch); row_pitch, slice_pitch);
@ -4364,12 +4397,14 @@ static void upload_gl_texture(GLenum gl_target,
glTexImage3D(gl_target, level, f.gl_internal_format, glTexImage3D(gl_target, level, f.gl_internal_format,
width, height, depth, 0, width, height, depth, 0,
f.gl_format, f.gl_type, f.gl_format, f.gl_type,
converted ? converted : unswizzled); converted ? converted : unswizzled ? unswizzled : texture_data);
if (converted) { if (converted) {
g_free(converted); g_free(converted);
} }
g_free(unswizzled); if (unswizzled) {
g_free(unswizzled);
}
texture_data += width * height * depth * f.bytes_per_pixel; texture_data += width * height * depth * f.bytes_per_pixel;
@ -4399,11 +4434,11 @@ static TextureBinding* generate_texture(const TextureShape s,
GLenum gl_target; GLenum gl_target;
if (s.cubemap) { if (s.cubemap) {
assert(f.linear == false); assert(f.encoding != linear);
assert(s.dimensionality == 2); assert(s.dimensionality == 2);
gl_target = GL_TEXTURE_CUBE_MAP; gl_target = GL_TEXTURE_CUBE_MAP;
} else { } else {
if (f.linear) { if (f.encoding == linear) { /* FIXME : Include compressed too? (!= swizzled) */
/* linear textures use unnormalised texcoords. /* linear textures use unnormalised texcoords.
* GL_TEXTURE_RECTANGLE_ARB conveniently also does, but * GL_TEXTURE_RECTANGLE_ARB conveniently also does, but
* does not allow repeat and mirror wrap modes. * does not allow repeat and mirror wrap modes.
@ -4430,7 +4465,7 @@ static TextureBinding* generate_texture(const TextureShape s,
NV2A_GL_DLABEL(GL_TEXTURE, gl_texture, NV2A_GL_DLABEL(GL_TEXTURE, gl_texture,
"format: 0x%02X%s, %d dimensions%s, width: %d, height: %d, depth: %d", "format: 0x%02X%s, %d dimensions%s, width: %d, height: %d, depth: %d",
s.color_format, f.linear ? "" : " (SZ)", s.color_format, {"", " (SZ)", " (DXT)"}[f.encoding],
s.dimensionality, s.cubemap ? " (Cubemap)" : "", s.dimensionality, s.cubemap ? " (Cubemap)" : "",
s.width, s.height, s.depth); s.width, s.height, s.depth);
@ -4463,7 +4498,7 @@ static TextureBinding* generate_texture(const TextureShape s,
} }
/* Linear textures don't support mipmapping */ /* Linear textures don't support mipmapping */
if (!f.linear) { if (f.encoding != linear) {
glTexParameteri(gl_target, GL_TEXTURE_BASE_LEVEL, glTexParameteri(gl_target, GL_TEXTURE_BASE_LEVEL,
s.min_mipmap_level); s.min_mipmap_level);
glTexParameteri(gl_target, GL_TEXTURE_MAX_LEVEL, glTexParameteri(gl_target, GL_TEXTURE_MAX_LEVEL,