From 8831bd09188735f2204a0040c7b7017b79d132f9 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 5 Mar 2016 16:55:17 +0100 Subject: [PATCH 1/2] gl: Factorize code in rsx_gl_texture.cpp --- rpcs3/Emu/RSX/GL/rsx_gl_texture.cpp | 355 ++++++++++++---------------- 1 file changed, 145 insertions(+), 210 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/rsx_gl_texture.cpp b/rpcs3/Emu/RSX/GL/rsx_gl_texture.cpp index c5e8b22ac2..7534fb259b 100644 --- a/rpcs3/Emu/RSX/GL/rsx_gl_texture.cpp +++ b/rpcs3/Emu/RSX/GL/rsx_gl_texture.cpp @@ -7,6 +7,120 @@ #include "../rsx_utils.h" #include "../Common/TextureUtils.h" +namespace +{ + std::tuple get_internal_format_format_type(u32 texture_format) + { + switch (texture_format) + { + case CELL_GCM_TEXTURE_B8: return std::make_tuple(GL_RGBA, GL_BLUE, GL_UNSIGNED_BYTE); + case CELL_GCM_TEXTURE_A1R5G5B5: return std::make_tuple(GL_RGBA, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV); + case CELL_GCM_TEXTURE_A4R4G4B4: return std::make_tuple(GL_RGBA, GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4); + case CELL_GCM_TEXTURE_R5G6B5: return std::make_tuple(GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5); + case CELL_GCM_TEXTURE_A8R8G8B8: return std::make_tuple(GL_RGBA, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8); + case CELL_GCM_TEXTURE_G8B8: return std::make_tuple(GL_RGBA, GL_RG, GL_UNSIGNED_BYTE); + case CELL_GCM_TEXTURE_R6G5B5: return std::make_tuple(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE); + case CELL_GCM_TEXTURE_DEPTH24_D8: return std::make_tuple(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE); + case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT: return std::make_tuple(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_FLOAT); + case CELL_GCM_TEXTURE_DEPTH16: return std::make_tuple(GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_SHORT); + case CELL_GCM_TEXTURE_DEPTH16_FLOAT: return std::make_tuple(GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_FLOAT); + case CELL_GCM_TEXTURE_X16: return std::make_tuple(GL_RGBA, GL_RED, GL_UNSIGNED_SHORT); + case CELL_GCM_TEXTURE_Y16_X16: return std::make_tuple(GL_RGBA, GL_RG, GL_UNSIGNED_SHORT); + case CELL_GCM_TEXTURE_R5G5B5A1: return std::make_tuple(GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1); + case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: return std::make_tuple(GL_RGBA, GL_RGBA, GL_HALF_FLOAT); + case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT: return std::make_tuple(GL_RGBA, GL_RGBA, GL_FLOAT); + case CELL_GCM_TEXTURE_X32_FLOAT: return std::make_tuple(GL_RGBA, GL_RED, GL_FLOAT); + case CELL_GCM_TEXTURE_D1R5G5B5: return std::make_tuple(GL_RGBA, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV); + case CELL_GCM_TEXTURE_D8R8G8B8: return std::make_tuple(GL_RGBA, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8); + case CELL_GCM_TEXTURE_Y16_X16_FLOAT: return std::make_tuple(GL_RGBA, GL_RG, GL_HALF_FLOAT); + } + throw EXCEPTION("Compressed or unknown texture format %x", texture_format); + } + + bool is_compressed_format(u32 texture_format) + { + switch (texture_format) + { + case CELL_GCM_TEXTURE_B8: + case CELL_GCM_TEXTURE_A1R5G5B5: + case CELL_GCM_TEXTURE_A4R4G4B4: + case CELL_GCM_TEXTURE_R5G6B5: + case CELL_GCM_TEXTURE_A8R8G8B8: + case CELL_GCM_TEXTURE_G8B8: + case CELL_GCM_TEXTURE_R6G5B5: + case CELL_GCM_TEXTURE_DEPTH24_D8: + case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT: + case CELL_GCM_TEXTURE_DEPTH16: + case CELL_GCM_TEXTURE_DEPTH16_FLOAT: + case CELL_GCM_TEXTURE_X16: + case CELL_GCM_TEXTURE_Y16_X16: + case CELL_GCM_TEXTURE_R5G5B5A1: + case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: + case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT: + case CELL_GCM_TEXTURE_X32_FLOAT: + case CELL_GCM_TEXTURE_D1R5G5B5: + case CELL_GCM_TEXTURE_D8R8G8B8: + case CELL_GCM_TEXTURE_Y16_X16_FLOAT: + return false; + case CELL_GCM_TEXTURE_COMPRESSED_DXT1: + case CELL_GCM_TEXTURE_COMPRESSED_DXT23: + case CELL_GCM_TEXTURE_COMPRESSED_DXT45: + return true; + } + throw EXCEPTION("Unknown format %x", texture_format); + } + + bool requires_unpack_byte(u32 texture_format) + { + switch (texture_format) + { + case CELL_GCM_TEXTURE_R5G6B5: + case CELL_GCM_TEXTURE_X16: + case CELL_GCM_TEXTURE_R5G5B5A1: + case CELL_GCM_TEXTURE_Y16_X16_FLOAT: + case CELL_GCM_TEXTURE_Y16_X16: + case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT: + case CELL_GCM_TEXTURE_D1R5G5B5: + case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: + return true; + } + return false; + } + + std::array get_swizzle_remap(u32 texture_format) + { + // NOTE: This must be in ARGB order in all forms below. + switch (texture_format) + { + case CELL_GCM_TEXTURE_B8: return{ GL_BLUE, GL_BLUE, GL_BLUE, GL_BLUE }; + case CELL_GCM_TEXTURE_A4R4G4B4: return { GL_BLUE, GL_ALPHA, GL_RED, GL_GREEN }; + case CELL_GCM_TEXTURE_G8B8: return { GL_RED, GL_GREEN, GL_RED, GL_GREEN }; + case CELL_GCM_TEXTURE_X16: return { GL_RED, GL_ONE, GL_RED, GL_ONE }; + case CELL_GCM_TEXTURE_Y16_X16: return { GL_GREEN, GL_RED, GL_GREEN, GL_RED }; + case CELL_GCM_TEXTURE_X32_FLOAT: return { GL_RED, GL_ONE, GL_ONE, GL_ONE }; + case CELL_GCM_TEXTURE_D1R5G5B5: return { GL_ONE, GL_RED, GL_GREEN, GL_BLUE }; + case CELL_GCM_TEXTURE_D8R8G8B8: return { GL_ONE, GL_RED, GL_GREEN, GL_BLUE }; + case CELL_GCM_TEXTURE_Y16_X16_FLOAT: return { GL_RED, GL_GREEN, GL_RED, GL_GREEN }; + case CELL_GCM_TEXTURE_A1R5G5B5: + case CELL_GCM_TEXTURE_R5G6B5: + case CELL_GCM_TEXTURE_A8R8G8B8: + case CELL_GCM_TEXTURE_R6G5B5: + case CELL_GCM_TEXTURE_DEPTH24_D8: + case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT: + case CELL_GCM_TEXTURE_DEPTH16: + case CELL_GCM_TEXTURE_DEPTH16_FLOAT: + case CELL_GCM_TEXTURE_R5G5B5A1: + case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: + case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT: + case CELL_GCM_TEXTURE_COMPRESSED_DXT1: + case CELL_GCM_TEXTURE_COMPRESSED_DXT23: + case CELL_GCM_TEXTURE_COMPRESSED_DXT45: + return{ GL_ALPHA, GL_RED, GL_GREEN, GL_BLUE }; + } + throw EXCEPTION("Unknown format %x", texture_format); + } +} + namespace rsx { namespace gl @@ -165,10 +279,6 @@ namespace rsx u32 format = full_format & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN); bool is_swizzled = !!(~full_format & CELL_GCM_TEXTURE_LN); - static const GLint glRemapStandard[4] = { GL_ALPHA, GL_RED, GL_GREEN, GL_BLUE }; - // NOTE: This must be in ARGB order in all forms below. - const GLint *glRemap = glRemapStandard; - ::gl::pixel_pack_settings().apply(); ::gl::pixel_unpack_settings().apply(); @@ -197,218 +307,43 @@ namespace rsx glPixelStorei(GL_UNPACK_ROW_LENGTH, aligned_pitch); - switch (format) + if (!is_compressed_format(format)) { - case CELL_GCM_TEXTURE_B8: // One 8-bit fixed-point number + if (requires_unpack_byte(format)) + glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); + const auto &internal_format_format_type = get_internal_format_format_type(format); + glTexImage2D(m_target, 0, std::get<0>(internal_format_format_type), tex.width(), tex.height(), 0, std::get<1>(internal_format_format_type), std::get<2>(internal_format_format_type), texture_data); + if (requires_unpack_byte(format)) + glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); + } + else { - glTexImage2D(m_target, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BLUE, GL_UNSIGNED_BYTE, texture_data); + switch (format) + { + case CELL_GCM_TEXTURE_COMPRESSED_DXT1: // Compressed 4x4 pixels into 8 bytes + { + u32 size = ((tex.width() + 3) / 4) * ((tex.height() + 3) / 4) * 8; + glCompressedTexImage2D(m_target, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, tex.width(), tex.height(), 0, size, texture_data); + break; + } - static const GLint swizzleMaskB8[] = { GL_BLUE, GL_BLUE, GL_BLUE, GL_BLUE }; - glRemap = swizzleMaskB8; + case CELL_GCM_TEXTURE_COMPRESSED_DXT23: // Compressed 4x4 pixels into 16 bytes + { + u32 size = ((tex.width() + 3) / 4) * ((tex.height() + 3) / 4) * 16; + glCompressedTexImage2D(m_target, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, tex.width(), tex.height(), 0, size, texture_data); + } break; + + case CELL_GCM_TEXTURE_COMPRESSED_DXT45: // Compressed 4x4 pixels into 16 bytes + { + u32 size = ((tex.width() + 3) / 4) * ((tex.height() + 3) / 4) * 16; + glCompressedTexImage2D(m_target, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, tex.width(), tex.height(), 0, size, texture_data); + break; + } + } } - case CELL_GCM_TEXTURE_A1R5G5B5: - { - glTexImage2D(m_target, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, texture_data); - break; - } - - case CELL_GCM_TEXTURE_A4R4G4B4: - { - glTexImage2D(m_target, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4, texture_data); - - // We read it in as R4G4B4A4, so we need to remap each component. - static const GLint swizzleMaskA4R4G4B4[] = { GL_BLUE, GL_ALPHA, GL_RED, GL_GREEN }; - glRemap = swizzleMaskA4R4G4B4; - break; - } - - case CELL_GCM_TEXTURE_R5G6B5: - { - LOG_WARNING(RSX, "CELL_GCM_R5G6B5 texture. Watch out for corruption due to swapped color channels!"); - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); - glTexImage2D(m_target, 0, GL_RGB, tex.width(), tex.height(), 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, texture_data); - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); - break; - } - - case CELL_GCM_TEXTURE_A8R8G8B8: - { - glTexImage2D(m_target, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, texture_data); - break; - } - - case CELL_GCM_TEXTURE_COMPRESSED_DXT1: // Compressed 4x4 pixels into 8 bytes - { - u32 size = ((tex.width() + 3) / 4) * ((tex.height() + 3) / 4) * 8; - glCompressedTexImage2D(m_target, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, tex.width(), tex.height(), 0, size, texture_data); - break; - } - - case CELL_GCM_TEXTURE_COMPRESSED_DXT23: // Compressed 4x4 pixels into 16 bytes - { - u32 size = ((tex.width() + 3) / 4) * ((tex.height() + 3) / 4) * 16; - glCompressedTexImage2D(m_target, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, tex.width(), tex.height(), 0, size, texture_data); - } - break; - - case CELL_GCM_TEXTURE_COMPRESSED_DXT45: // Compressed 4x4 pixels into 16 bytes - { - u32 size = ((tex.width() + 3) / 4) * ((tex.height() + 3) / 4) * 16; - glCompressedTexImage2D(m_target, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, tex.width(), tex.height(), 0, size, texture_data); - break; - } - - case CELL_GCM_TEXTURE_G8B8: - { - glTexImage2D(m_target, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RG, GL_UNSIGNED_BYTE, texture_data); - - static const GLint swizzleMaskG8B8[] = { GL_RED, GL_GREEN, GL_RED, GL_GREEN }; - glRemap = swizzleMaskG8B8; - break; - } - - case CELL_GCM_TEXTURE_R6G5B5: - { - glTexImage2D(m_target, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, texture_data); - break; - } - - case CELL_GCM_TEXTURE_DEPTH24_D8: // 24-bit unsigned fixed-point number and 8 bits of garbage - { - glTexImage2D(m_target, 0, GL_DEPTH_COMPONENT24, tex.width(), tex.height(), 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, texture_data); - break; - } - - case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT: // 24-bit unsigned float and 8 bits of garbage - { - glTexImage2D(m_target, 0, GL_DEPTH_COMPONENT24, tex.width(), tex.height(), 0, GL_DEPTH_COMPONENT, GL_FLOAT, texture_data); - break; - } - - case CELL_GCM_TEXTURE_DEPTH16: // 16-bit unsigned fixed-point number - { - glTexImage2D(m_target, 0, GL_DEPTH_COMPONENT16, tex.width(), tex.height(), 0, GL_DEPTH_COMPONENT, GL_SHORT, texture_data); - break; - } - - case CELL_GCM_TEXTURE_DEPTH16_FLOAT: // 16-bit unsigned float - { - glTexImage2D(m_target, 0, GL_DEPTH_COMPONENT16, tex.width(), tex.height(), 0, GL_DEPTH_COMPONENT, GL_FLOAT, texture_data); - break; - } - - case CELL_GCM_TEXTURE_X16: // A 16-bit fixed-point number - { - LOG_WARNING(RSX, "CELL_GCM_X16 texture. Watch out for corruption due to swapped color channels!"); - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); - glTexImage2D(m_target, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RED, GL_UNSIGNED_SHORT, texture_data); - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); - - static const GLint swizzleMaskX16[] = { GL_RED, GL_ONE, GL_RED, GL_ONE }; - glRemap = swizzleMaskX16; - break; - } - - case CELL_GCM_TEXTURE_Y16_X16: // Two 16-bit fixed-point numbers - { - LOG_WARNING(RSX, "CELL_GCM_Y16_X16 texture. Watch out for corruption due to swapped color channels!"); - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); - glTexImage2D(m_target, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RG, GL_UNSIGNED_SHORT, texture_data); - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); - - static const GLint swizzleMaskX32_Y16_X16[] = { GL_GREEN, GL_RED, GL_GREEN, GL_RED }; - glRemap = swizzleMaskX32_Y16_X16; - break; - } - - case CELL_GCM_TEXTURE_R5G5B5A1: - { - LOG_WARNING(RSX, "CELL_GCM_R5G6B5A1 texture. Watch out for corruption due to swapped color channels!"); - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); - glTexImage2D(m_target, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, texture_data); - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); - break; - } - - case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: // Four fp16 values - { - LOG_WARNING(RSX, "CELL_GCM_W16_Z16_Y16_X16_FLOAT texture. Watch out for corruption due to swapped color channels!"); - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); - glTexImage2D(m_target, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_HALF_FLOAT, texture_data); - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); - break; - } - - case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT: // Four fp32 values - { - LOG_WARNING(RSX, "CELL_GCM_W32_Z32_Y32_X32_FLOAT texture. Watch out for corruption due to swapped color channels!"); - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); - glTexImage2D(m_target, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_FLOAT, texture_data); - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); - break; - } - - case CELL_GCM_TEXTURE_X32_FLOAT: // One 32-bit floating-point number - { - glTexImage2D(m_target, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RED, GL_FLOAT, texture_data); - - static const GLint swizzleMaskX32_FLOAT[] = { GL_RED, GL_ONE, GL_ONE, GL_ONE }; - glRemap = swizzleMaskX32_FLOAT; - break; - } - - case CELL_GCM_TEXTURE_D1R5G5B5: - { - LOG_WARNING(RSX, "CELL_GCM_D1R5G5B5 texture. Watch out for corruption due to swapped color channels!"); - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); - - // TODO: Texture swizzling - glTexImage2D(m_target, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, texture_data); - - static const GLint swizzleMaskX32_D1R5G5B5[] = { GL_ONE, GL_RED, GL_GREEN, GL_BLUE }; - glRemap = swizzleMaskX32_D1R5G5B5; - - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); - break; - } - - case CELL_GCM_TEXTURE_D8R8G8B8: // 8 bits of garbage and three unsigned 8-bit fixed-point numbers - { - glTexImage2D(m_target, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, texture_data); - - static const GLint swizzleMaskX32_D8R8G8B8[] = { GL_ONE, GL_RED, GL_GREEN, GL_BLUE }; - glRemap = swizzleMaskX32_D8R8G8B8; - break; - } - - - case CELL_GCM_TEXTURE_Y16_X16_FLOAT: // Two fp16 values - { - LOG_WARNING(RSX, "CELL_GCM_Y16_X16_FLOAT texture. Watch out for corruption due to swapped color channels!"); - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); - glTexImage2D(m_target, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RG, GL_HALF_FLOAT, texture_data); - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); - - static const GLint swizzleMaskX32_Y16_X16_FLOAT[] = { GL_RED, GL_GREEN, GL_RED, GL_GREEN }; - glRemap = swizzleMaskX32_Y16_X16_FLOAT; - break; - } - - case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: - case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: - { - glTexImage2D(m_target, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, texture_data); - break; - } - - default: - { - LOG_ERROR(RSX, "Init tex error: Bad tex format (0x%x | %s | 0x%x)", format, (is_swizzled ? "swizzled" : "linear"), tex.format() & 0x40); - break; - } - } + const std::array& glRemap = get_swizzle_remap(format); glTexParameteri(m_target, GL_TEXTURE_MAX_LEVEL, tex.mipmap() - 1); From 9e01f2817fad5f6608da7978db09621f58e736b4 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 5 Mar 2016 18:46:22 +0100 Subject: [PATCH 2/2] gl: Use less costly glTexStorage2D instead of glTexImage2D. --- rpcs3/Emu/RSX/GL/GLProcTable.h | 2 ++ rpcs3/Emu/RSX/GL/rsx_gl_texture.cpp | 41 +++++++++++++++-------------- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/GLProcTable.h b/rpcs3/Emu/RSX/GL/GLProcTable.h index 54c06d4a4b..5b7838dce0 100644 --- a/rpcs3/Emu/RSX/GL/GLProcTable.h +++ b/rpcs3/Emu/RSX/GL/GLProcTable.h @@ -177,6 +177,8 @@ OPENGL_PROC(PFNGLCOPYIMAGESUBDATAPROC, CopyImageSubData); OPENGL_PROC(PFNGLDEBUGMESSAGECONTROLARBPROC, DebugMessageControlARB); OPENGL_PROC(PFNGLDEBUGMESSAGEINSERTARBPROC, DebugMessageInsertARB); OPENGL_PROC(PFNGLDEBUGMESSAGECALLBACKARBPROC, DebugMessageCallbackARB); + +OPENGL_PROC(PFNGLTEXSTORAGE2DPROC, TexStorage2D); //... #if !defined(__GNUG__) || defined(__MINGW32__) diff --git a/rpcs3/Emu/RSX/GL/rsx_gl_texture.cpp b/rpcs3/Emu/RSX/GL/rsx_gl_texture.cpp index 7534fb259b..7f2f599562 100644 --- a/rpcs3/Emu/RSX/GL/rsx_gl_texture.cpp +++ b/rpcs3/Emu/RSX/GL/rsx_gl_texture.cpp @@ -9,30 +9,30 @@ namespace { - std::tuple get_internal_format_format_type(u32 texture_format) + std::tuple get_sized_internal_format_format_type(u32 texture_format) { switch (texture_format) { - case CELL_GCM_TEXTURE_B8: return std::make_tuple(GL_RGBA, GL_BLUE, GL_UNSIGNED_BYTE); - case CELL_GCM_TEXTURE_A1R5G5B5: return std::make_tuple(GL_RGBA, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV); - case CELL_GCM_TEXTURE_A4R4G4B4: return std::make_tuple(GL_RGBA, GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4); - case CELL_GCM_TEXTURE_R5G6B5: return std::make_tuple(GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5); - case CELL_GCM_TEXTURE_A8R8G8B8: return std::make_tuple(GL_RGBA, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8); - case CELL_GCM_TEXTURE_G8B8: return std::make_tuple(GL_RGBA, GL_RG, GL_UNSIGNED_BYTE); - case CELL_GCM_TEXTURE_R6G5B5: return std::make_tuple(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE); + case CELL_GCM_TEXTURE_B8: return std::make_tuple(GL_R8, GL_RED, GL_UNSIGNED_BYTE); + case CELL_GCM_TEXTURE_A1R5G5B5: return std::make_tuple(GL_RGB5_A1, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV); + case CELL_GCM_TEXTURE_A4R4G4B4: return std::make_tuple(GL_RGBA4, GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4); + case CELL_GCM_TEXTURE_R5G6B5: return std::make_tuple(GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5); + case CELL_GCM_TEXTURE_A8R8G8B8: return std::make_tuple(GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8); + case CELL_GCM_TEXTURE_G8B8: return std::make_tuple(GL_RG8, GL_RG, GL_UNSIGNED_BYTE); + case CELL_GCM_TEXTURE_R6G5B5: return std::make_tuple(GL_RGB565, GL_RGBA, GL_UNSIGNED_BYTE); case CELL_GCM_TEXTURE_DEPTH24_D8: return std::make_tuple(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE); case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT: return std::make_tuple(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_FLOAT); case CELL_GCM_TEXTURE_DEPTH16: return std::make_tuple(GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_SHORT); case CELL_GCM_TEXTURE_DEPTH16_FLOAT: return std::make_tuple(GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_FLOAT); - case CELL_GCM_TEXTURE_X16: return std::make_tuple(GL_RGBA, GL_RED, GL_UNSIGNED_SHORT); - case CELL_GCM_TEXTURE_Y16_X16: return std::make_tuple(GL_RGBA, GL_RG, GL_UNSIGNED_SHORT); - case CELL_GCM_TEXTURE_R5G5B5A1: return std::make_tuple(GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1); - case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: return std::make_tuple(GL_RGBA, GL_RGBA, GL_HALF_FLOAT); - case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT: return std::make_tuple(GL_RGBA, GL_RGBA, GL_FLOAT); - case CELL_GCM_TEXTURE_X32_FLOAT: return std::make_tuple(GL_RGBA, GL_RED, GL_FLOAT); - case CELL_GCM_TEXTURE_D1R5G5B5: return std::make_tuple(GL_RGBA, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV); - case CELL_GCM_TEXTURE_D8R8G8B8: return std::make_tuple(GL_RGBA, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8); - case CELL_GCM_TEXTURE_Y16_X16_FLOAT: return std::make_tuple(GL_RGBA, GL_RG, GL_HALF_FLOAT); + case CELL_GCM_TEXTURE_X16: return std::make_tuple(GL_R16, GL_RED, GL_UNSIGNED_SHORT); + case CELL_GCM_TEXTURE_Y16_X16: return std::make_tuple(GL_RG16, GL_RG, GL_UNSIGNED_SHORT); + case CELL_GCM_TEXTURE_R5G5B5A1: return std::make_tuple(GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1); + case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: return std::make_tuple(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT); + case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT: return std::make_tuple(GL_RGBA32F, GL_RGBA, GL_FLOAT); + case CELL_GCM_TEXTURE_X32_FLOAT: return std::make_tuple(GL_R32F, GL_RED, GL_FLOAT); + case CELL_GCM_TEXTURE_D1R5G5B5: return std::make_tuple(GL_RGB5_A1, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV); + case CELL_GCM_TEXTURE_D8R8G8B8: return std::make_tuple(GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8); + case CELL_GCM_TEXTURE_Y16_X16_FLOAT: return std::make_tuple(GL_RG16F, GL_RG, GL_HALF_FLOAT); } throw EXCEPTION("Compressed or unknown texture format %x", texture_format); } @@ -92,7 +92,7 @@ namespace // NOTE: This must be in ARGB order in all forms below. switch (texture_format) { - case CELL_GCM_TEXTURE_B8: return{ GL_BLUE, GL_BLUE, GL_BLUE, GL_BLUE }; + case CELL_GCM_TEXTURE_B8: return{ GL_RED, GL_RED, GL_RED, GL_RED }; case CELL_GCM_TEXTURE_A4R4G4B4: return { GL_BLUE, GL_ALPHA, GL_RED, GL_GREEN }; case CELL_GCM_TEXTURE_G8B8: return { GL_RED, GL_GREEN, GL_RED, GL_GREEN }; case CELL_GCM_TEXTURE_X16: return { GL_RED, GL_ONE, GL_RED, GL_ONE }; @@ -309,10 +309,11 @@ namespace rsx if (!is_compressed_format(format)) { + const auto &sized_internal_format_format_type = get_sized_internal_format_format_type(format); + glTexStorage2D(m_target, tex.mipmap(), std::get<0>(sized_internal_format_format_type), tex.width(), tex.height()); if (requires_unpack_byte(format)) glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); - const auto &internal_format_format_type = get_internal_format_format_type(format); - glTexImage2D(m_target, 0, std::get<0>(internal_format_format_type), tex.width(), tex.height(), 0, std::get<1>(internal_format_format_type), std::get<2>(internal_format_format_type), texture_data); + glTexSubImage2D(m_target, 0, 0, 0, tex.width(), tex.height(), std::get<1>(sized_internal_format_format_type), std::get<2>(sized_internal_format_format_type), texture_data); if (requires_unpack_byte(format)) glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); }