diff --git a/.gitignore b/.gitignore
index c680e78a72..769c3bd59e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,7 +32,8 @@
/build
/bin
-/libs
+/lib
+/tmp
/ipch
/rpcs3/Debug
/rpcs3/Release
diff --git a/asmjitsrc/asmjit.vcxproj b/asmjitsrc/asmjit.vcxproj
index 4b73e029f5..9290793a44 100644
--- a/asmjitsrc/asmjit.vcxproj
+++ b/asmjitsrc/asmjit.vcxproj
@@ -94,12 +94,12 @@
- $(SolutionDir)libs\$(Configuration)\
+ $(SolutionDir)lib\$(Configuration)-$(Platform)\
- $(SolutionDir)libs\$(Configuration)\
+ $(SolutionDir)lib\$(Configuration)-$(Platform)\
diff --git a/rpcs3/D3D12GSRender.vcxproj b/rpcs3/D3D12GSRender.vcxproj
index d1c7dcd40f..bc883df5cb 100644
--- a/rpcs3/D3D12GSRender.vcxproj
+++ b/rpcs3/D3D12GSRender.vcxproj
@@ -61,6 +61,55 @@
+
+ $(SolutionDir)lib\$(Configuration)-$(Platform)\
+ $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\
+
+
+ $(SolutionDir)lib\$(Configuration)-$(Platform)\
+ $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\
+
+
+ $(SolutionDir)lib\$(Configuration)-$(Platform)\
+ $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\
+
+
+ $(SolutionDir)lib\$(Configuration)-$(Platform)\
+ $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\
+
+
+ $(SolutionDir)lib\$(Configuration)-$(Platform)\
+ $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\
+
+
+
+ true
+
+
+
+
+ true
+
+
+
+
+
+
+ true
+
+
+
+
+ true
+
+
+
+
+ true
+
+
+
+
diff --git a/rpcs3/Emu/RSX/CgBinaryProgram.h b/rpcs3/Emu/RSX/CgBinaryProgram.h
index 5d357e47dd..4029c5d273 100644
--- a/rpcs3/Emu/RSX/CgBinaryProgram.h
+++ b/rpcs3/Emu/RSX/CgBinaryProgram.h
@@ -110,7 +110,17 @@ struct CgBinaryProgram
class CgBinaryDisasm
{
-private:
+ OPDEST dst;
+ SRC0 src0;
+ SRC1 src1;
+ SRC2 src2;
+
+ D0 d0;
+ D1 d1;
+ D2 d2;
+ D3 d3;
+ SRC src[3];
+
std::string m_path; // used for FP decompiler thread, delete this later
u8* m_buffer;
diff --git a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.h b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.h
index 6294db0e5f..edaec9ae2d 100644
--- a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.h
+++ b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.h
@@ -19,6 +19,11 @@
*/
class FragmentProgramDecompiler
{
+ OPDEST dst;
+ SRC0 src0;
+ SRC1 src1;
+ SRC2 src2;
+
std::string main;
u32 m_addr;
u32& m_size;
diff --git a/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.h b/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.h
index 24daff2979..ab4aac0d01 100644
--- a/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.h
+++ b/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.h
@@ -19,6 +19,12 @@
*/
struct VertexProgramDecompiler
{
+ D0 d0;
+ D1 d1;
+ D2 d2;
+ D3 d3;
+ SRC src[3];
+
struct FuncInfo
{
u32 offset;
diff --git a/rpcs3/Emu/RSX/GL/GLBuffers.cpp b/rpcs3/Emu/RSX/GL/GLBuffers.cpp
deleted file mode 100644
index c2fbd354b2..0000000000
--- a/rpcs3/Emu/RSX/GL/GLBuffers.cpp
+++ /dev/null
@@ -1,267 +0,0 @@
-#include "stdafx.h"
-#include "GLBuffers.h"
-
-GLBufferObject::GLBufferObject()
-{
-}
-
-GLBufferObject::GLBufferObject(u32 type)
-{
- Create(type);
-}
-
-GLBufferObject::~GLBufferObject()
-{
- Delete();
-}
-
-void GLBufferObject::Create(GLuint type, u32 count)
-{
- if(IsCreated()) return;
-
- m_id.resize(count);
- glGenBuffers(count, &m_id[0]);
- m_type = type;
-}
-
-void GLBufferObject::Delete()
-{
- if(!IsCreated()) return;
-
- glDeleteBuffers(m_id.size(), &m_id[0]);
- m_id.clear();
- m_type = 0;
-}
-
-void GLBufferObject::Bind(u32 type, u32 num)
-{
- assert(num < m_id.size());
- glBindBuffer(type, m_id[num]);
-}
-
-void GLBufferObject::UnBind(u32 type)
-{
- glBindBuffer(type, 0);
-}
-
-void GLBufferObject::Bind(u32 num)
-{
- Bind(m_type, num);
-}
-
-void GLBufferObject::UnBind()
-{
- UnBind(m_type);
-}
-
-void GLBufferObject::SetData(u32 type, const void* data, u32 size, u32 usage)
-{
- glBufferData(type, size, data, usage);
-}
-
-void GLBufferObject::SetData(const void* data, u32 size, u32 usage)
-{
- SetData(m_type, data, size, usage);
-}
-
-void GLBufferObject::SetAttribPointer(int location, int size, int type, GLvoid* pointer, int stride, bool normalized)
-{
- if(location < 0) return;
-
- glVertexAttribPointer(location, size, type, normalized ? GL_TRUE : GL_FALSE, stride, pointer);
- glEnableVertexAttribArray(location);
-}
-
-bool GLBufferObject::IsCreated() const
-{
- return m_id.size() != 0;
-}
-
-GLvbo::GLvbo()
-{
-}
-
-void GLvbo::Create(u32 count)
-{
- GLBufferObject::Create(GL_ARRAY_BUFFER, count);
-}
-
-GLvao::GLvao() : m_id(0)
-{
-}
-
-GLvao::~GLvao()
-{
- Delete();
-}
-
-void GLvao::Create()
-{
- if(!IsCreated()) glGenVertexArrays(1, &m_id);
-}
-
-void GLvao::Bind() const
-{
- glBindVertexArray(m_id);
-}
-
-void GLvao::Unbind()
-{
- glBindVertexArray(0);
-}
-
-void GLvao::Delete()
-{
- if(!IsCreated()) return;
-
- Unbind();
- glDeleteVertexArrays(1, &m_id);
- m_id = 0;
-}
-
-bool GLvao::IsCreated() const
-{
- return m_id != 0;
-}
-
-GLrbo::GLrbo()
-{
-}
-
-GLrbo::~GLrbo()
-{
-}
-
-void GLrbo::Create(u32 count)
-{
- if(m_id.size() == count)
- {
- return;
- }
-
- Delete();
-
- m_id.resize(count);
- glGenRenderbuffers(count, m_id.data());
-}
-
-void GLrbo::Bind(u32 num) const
-{
- assert(num < m_id.size());
-
- glBindRenderbuffer(GL_RENDERBUFFER, m_id[num]);
-}
-
-void GLrbo::Storage(u32 format, u32 width, u32 height)
-{
- glRenderbufferStorage(GL_RENDERBUFFER, format, width, height);
-}
-
-void GLrbo::Unbind()
-{
- glBindRenderbuffer(GL_RENDERBUFFER, 0);
-}
-
-void GLrbo::Delete()
-{
- if(!IsCreated())
- {
- return;
- }
-
- glDeleteRenderbuffers(m_id.size(), m_id.data());
- m_id.clear();
-}
-
-bool GLrbo::IsCreated() const
-{
- return m_id.size();
-}
-
-u32 GLrbo::GetId(u32 num) const
-{
- assert(num < m_id.size());
- return m_id[num];
-}
-
-GLfbo::GLfbo() : m_id(0)
-{
-}
-
-GLfbo::~GLfbo()
-{
-}
-
-void GLfbo::Create()
-{
- if(IsCreated())
- {
- return;
- }
-
- glGenFramebuffers(1, &m_id);
-}
-
-void GLfbo::Bind(u32 type, int id)
-{
- glBindFramebuffer(type, id);
-}
-
-void GLfbo::Bind(u32 type)
-{
- assert(IsCreated());
-
- m_type = type;
- Bind(type, m_id);
-}
-
-void GLfbo::Texture1D(u32 attachment, u32 texture, int level)
-{
- glFramebufferTexture1D(m_type, attachment, GL_TEXTURE_1D, texture, level);
-}
-
-void GLfbo::Texture2D(u32 attachment, u32 texture, int level)
-{
- glFramebufferTexture2D(m_type, attachment, GL_TEXTURE_2D, texture, level);
-}
-
-void GLfbo::Texture3D(u32 attachment, u32 texture, int zoffset, int level)
-{
- glFramebufferTexture3D(m_type, attachment, GL_TEXTURE_3D, texture, level, zoffset);
-}
-
-void GLfbo::Renderbuffer(u32 attachment, u32 renderbuffer)
-{
- glFramebufferRenderbuffer(m_type, attachment, GL_RENDERBUFFER, renderbuffer);
-}
-
-void GLfbo::Blit(int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, u32 mask, u32 filter)
-{
- glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
-}
-
-void GLfbo::Unbind()
-{
- Unbind(m_type);
-}
-
-void GLfbo::Unbind(u32 type)
-{
- glBindFramebuffer(type, 0);
-}
-
-void GLfbo::Delete()
-{
- if(!IsCreated())
- {
- return;
- }
-
- glDeleteFramebuffers(1, &m_id);
- m_id = 0;
-}
-
-bool GLfbo::IsCreated() const
-{
- return m_id != 0;
-}
diff --git a/rpcs3/Emu/RSX/GL/GLBuffers.h b/rpcs3/Emu/RSX/GL/GLBuffers.h
deleted file mode 100644
index 659365d29b..0000000000
--- a/rpcs3/Emu/RSX/GL/GLBuffers.h
+++ /dev/null
@@ -1,91 +0,0 @@
-#pragma once
-#include "OpenGL.h"
-
-struct GLBufferObject
-{
-protected:
- std::vector m_id;
- GLuint m_type;
-
-public:
- GLBufferObject();
- GLBufferObject(u32 type);
-
- ~GLBufferObject();
-
- void Create(GLuint type, u32 count = 1);
- void Delete();
- void Bind(u32 type, u32 num);
- void UnBind(u32 type);
- void Bind(u32 num = 0);
- void UnBind();
- void SetData(u32 type, const void* data, u32 size, u32 usage = GL_DYNAMIC_DRAW);
- void SetData(const void* data, u32 size, u32 usage = GL_DYNAMIC_DRAW);
- void SetAttribPointer(int location, int size, int type, GLvoid* pointer, int stride, bool normalized = false);
- bool IsCreated() const;
-};
-
-struct GLvbo : public GLBufferObject
-{
- GLvbo();
-
- void Create(u32 count = 1);
-};
-
-class GLvao
-{
-protected:
- GLuint m_id;
-
-public:
- GLvao();
- ~GLvao();
-
- void Create();
- void Bind() const;
- static void Unbind();
- void Delete();
- bool IsCreated() const;
-};
-
-class GLrbo
-{
-protected:
- std::vector m_id;
-
-public:
- GLrbo();
- ~GLrbo();
-
- void Create(u32 count = 1);
- void Bind(u32 num = 0) const;
- void Storage(u32 format, u32 width, u32 height);
- static void Unbind();
- void Delete();
- bool IsCreated() const;
- u32 GetId(u32 num = 0) const;
-};
-
-class GLfbo
-{
-protected:
- GLuint m_id;
- GLuint m_type;
-
-public:
- GLfbo();
- ~GLfbo();
-
- void Create();
- static void Bind(u32 type, int id);
- void Bind(u32 type = GL_FRAMEBUFFER);
- void Texture1D(u32 attachment, u32 texture, int level = 0);
- void Texture2D(u32 attachment, u32 texture, int level = 0);
- void Texture3D(u32 attachment, u32 texture, int zoffset = 0, int level = 0);
- void Renderbuffer(u32 attachment, u32 renderbuffer);
- static void Blit(int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, u32 mask, u32 filter);
- void Unbind();
- static void Unbind(u32 type);
- void Delete();
- bool IsCreated() const;
-};
diff --git a/rpcs3/Emu/RSX/GL/GLCommonDecompiler.cpp b/rpcs3/Emu/RSX/GL/GLCommonDecompiler.cpp
index afa7be3b7c..24a6167c0f 100644
--- a/rpcs3/Emu/RSX/GL/GLCommonDecompiler.cpp
+++ b/rpcs3/Emu/RSX/GL/GLCommonDecompiler.cpp
@@ -72,4 +72,4 @@ std::string compareFunctionImpl(COMPARE f, const std::string &Op0, const std::st
case COMPARE::FUNCTION_SNE:
return "notEqual(" + Op0 + ", " + Op1 + ")";
}
-}
\ No newline at end of file
+}
diff --git a/rpcs3/Emu/RSX/GL/GLCommonDecompiler.h b/rpcs3/Emu/RSX/GL/GLCommonDecompiler.h
index 6ae1d5065a..cee0d9b11c 100644
--- a/rpcs3/Emu/RSX/GL/GLCommonDecompiler.h
+++ b/rpcs3/Emu/RSX/GL/GLCommonDecompiler.h
@@ -3,4 +3,4 @@
std::string getFloatTypeNameImpl(size_t elementCount);
std::string getFunctionImpl(FUNCTION f);
-std::string compareFunctionImpl(COMPARE f, const std::string &Op0, const std::string &Op1);
\ No newline at end of file
+std::string compareFunctionImpl(COMPARE f, const std::string &Op0, const std::string &Op1);
diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp
index ba10d04aa0..9b0c5d0146 100644
--- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp
+++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp
@@ -9,524 +9,6 @@
#define DUMP_VERTEX_DATA 0
-void GLTexture::create()
-{
- if (m_id)
- {
- remove();
- }
-
- glGenTextures(1, &m_id);
- bind();
-}
-
-int GLTexture::gl_wrap(int wrap)
-{
- switch (wrap)
- {
- case CELL_GCM_TEXTURE_WRAP: return GL_REPEAT;
- case CELL_GCM_TEXTURE_MIRROR: return GL_MIRRORED_REPEAT;
- case CELL_GCM_TEXTURE_CLAMP_TO_EDGE: return GL_CLAMP_TO_EDGE;
- case CELL_GCM_TEXTURE_BORDER: return GL_CLAMP_TO_BORDER;
- case CELL_GCM_TEXTURE_CLAMP: return GL_CLAMP;
- case CELL_GCM_TEXTURE_MIRROR_ONCE_CLAMP_TO_EDGE: return GL_MIRROR_CLAMP_TO_EDGE_EXT;
- case CELL_GCM_TEXTURE_MIRROR_ONCE_BORDER: return GL_MIRROR_CLAMP_TO_BORDER_EXT;
- case CELL_GCM_TEXTURE_MIRROR_ONCE_CLAMP: return GL_MIRROR_CLAMP_EXT;
- }
-
- LOG_ERROR(RSX, "Texture wrap error: bad wrap (%d).", wrap);
- return GL_REPEAT;
-}
-
-float GLTexture::max_aniso(int aniso)
-{
- switch (aniso)
- {
- case CELL_GCM_TEXTURE_MAX_ANISO_1: return 1.0f;
- case CELL_GCM_TEXTURE_MAX_ANISO_2: return 2.0f;
- case CELL_GCM_TEXTURE_MAX_ANISO_4: return 4.0f;
- case CELL_GCM_TEXTURE_MAX_ANISO_6: return 6.0f;
- case CELL_GCM_TEXTURE_MAX_ANISO_8: return 8.0f;
- case CELL_GCM_TEXTURE_MAX_ANISO_10: return 10.0f;
- case CELL_GCM_TEXTURE_MAX_ANISO_12: return 12.0f;
- case CELL_GCM_TEXTURE_MAX_ANISO_16: return 16.0f;
- }
-
- LOG_ERROR(RSX, "Texture anisotropy error: bad max aniso (%d).", aniso);
- return 1.0f;
-}
-
-void GLTexture::init(rsx::texture& tex)
-{
- if (!m_id)
- create();
-
- bind();
-
- const u32 texaddr = rsx::get_address(tex.offset(), tex.location());
- //LOG_WARNING(RSX, "texture addr = 0x%x, width = %d, height = %d, max_aniso=%d, mipmap=%d, remap=0x%x, zfunc=0x%x, wraps=0x%x, wrapt=0x%x, wrapr=0x%x, minlod=0x%x, maxlod=0x%x",
- // m_offset, m_width, m_height, m_maxaniso, m_mipmap, m_remap, m_zfunc, m_wraps, m_wrapt, m_wrapr, m_minlod, m_maxlod);
-
- //TODO: safe init
-
- int format = tex.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
- bool is_swizzled = !(tex.format() & CELL_GCM_TEXTURE_LN);
-
- const u8* pixels = vm::ps3::_ptr(texaddr);
- u8 *unswizzledPixels;
- 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;
-
- switch (format)
- {
- case CELL_GCM_TEXTURE_B8: // One 8-bit fixed-point number
- {
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BLUE, GL_UNSIGNED_BYTE, pixels);
-
- static const GLint swizzleMaskB8[] = { GL_BLUE, GL_BLUE, GL_BLUE, GL_BLUE };
- glRemap = swizzleMaskB8;
- break;
- }
-
- case CELL_GCM_TEXTURE_A1R5G5B5:
- {
- glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE);
-
- // TODO: texture swizzling
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, pixels);
- glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
- break;
- }
-
- case CELL_GCM_TEXTURE_A4R4G4B4:
- {
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, pixels);
-
- // 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:
- {
- glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tex.width(), tex.height(), 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixels);
- glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
- break;
- }
-
- case CELL_GCM_TEXTURE_A8R8G8B8:
- {
- if (is_swizzled)
- {
- u32 *src, *dst;
- u16 height = tex.height();
- u16 width = tex.width();
-
- unswizzledPixels = (u8*)malloc(width * height * 4);
- src = (u32*)pixels;
- dst = (u32*)unswizzledPixels;
-
- if ((height & (height - 1)) || (width & (width - 1)))
- {
- LOG_ERROR(RSX, "Swizzle Texture: Width or height not power of 2! (h=%d,w=%d).", height, width);
- }
-
- rsx::convert_linear_swizzle(src, dst, width, height, true);
- }
-
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, is_swizzled ? unswizzledPixels : pixels);
- 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(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, tex.width(), tex.height(), 0, size, pixels);
- 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(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, tex.width(), tex.height(), 0, size, pixels);
- }
- 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(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, tex.width(), tex.height(), 0, size, pixels);
- break;
- }
-
- case CELL_GCM_TEXTURE_G8B8:
- {
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RG, GL_UNSIGNED_BYTE, pixels);
-
- static const GLint swizzleMaskG8B8[] = { GL_RED, GL_GREEN, GL_RED, GL_GREEN };
- glRemap = swizzleMaskG8B8;
- break;
- }
-
- case CELL_GCM_TEXTURE_R6G5B5:
- {
- // TODO: Probably need to actually unswizzle if is_swizzled.
- const u32 numPixels = tex.width() * tex.height();
- unswizzledPixels = (u8 *)malloc(numPixels * 4);
- // TODO: Speed.
- for (u32 i = 0; i < numPixels; ++i) {
- u16 c = reinterpret_cast *>(pixels)[i];
- unswizzledPixels[i * 4 + 0] = convert_6_to_8((c >> 10) & 0x3F);
- unswizzledPixels[i * 4 + 1] = convert_5_to_8((c >> 5) & 0x1F);
- unswizzledPixels[i * 4 + 2] = convert_5_to_8((c >> 0) & 0x1F);
- unswizzledPixels[i * 4 + 3] = 255;
- }
-
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, unswizzledPixels);
-
- free(unswizzledPixels);
- break;
- }
-
- case CELL_GCM_TEXTURE_DEPTH24_D8: // 24-bit unsigned fixed-point number and 8 bits of garbage
- {
- glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, tex.width(), tex.height(), 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, pixels);
- break;
- }
-
- case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT: // 24-bit unsigned float and 8 bits of garbage
- {
- glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, tex.width(), tex.height(), 0, GL_DEPTH_COMPONENT, GL_FLOAT, pixels);
- break;
- }
-
- case CELL_GCM_TEXTURE_DEPTH16: // 16-bit unsigned fixed-point number
- {
- glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, tex.width(), tex.height(), 0, GL_DEPTH_COMPONENT, GL_SHORT, pixels);
- break;
- }
-
- case CELL_GCM_TEXTURE_DEPTH16_FLOAT: // 16-bit unsigned float
- {
- glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, tex.width(), tex.height(), 0, GL_DEPTH_COMPONENT, GL_FLOAT, pixels);
- break;
- }
-
- case CELL_GCM_TEXTURE_X16: // A 16-bit fixed-point number
- {
- glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RED, GL_UNSIGNED_SHORT, pixels);
- 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
- {
- glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RG, GL_UNSIGNED_SHORT, pixels);
- 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:
- {
- glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, pixels);
- glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
- break;
- }
-
- case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: // Four fp16 values
- {
- glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_HALF_FLOAT, pixels);
- glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
- break;
- }
-
- case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT: // Four fp32 values
- {
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BGRA, GL_FLOAT, pixels);
- break;
- }
-
- case CELL_GCM_TEXTURE_X32_FLOAT: // One 32-bit floating-point number
- {
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RED, GL_FLOAT, pixels);
-
- static const GLint swizzleMaskX32_FLOAT[] = { GL_RED, GL_ONE, GL_ONE, GL_ONE };
- glRemap = swizzleMaskX32_FLOAT;
- break;
- }
-
- case CELL_GCM_TEXTURE_D1R5G5B5:
- {
- glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE);
-
-
- // TODO: Texture swizzling
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, pixels);
-
- 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(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, pixels);
-
- 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
- {
- glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RG, GL_HALF_FLOAT, pixels);
- 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:
- {
- const u32 numPixels = tex.width() * tex.height();
- unswizzledPixels = (u8 *)malloc(numPixels * 4);
- // TODO: Speed.
- for (u32 i = 0; i < numPixels; i += 2)
- {
- unswizzledPixels[i * 4 + 0 + 0] = pixels[i * 2 + 3];
- unswizzledPixels[i * 4 + 0 + 1] = pixels[i * 2 + 2];
- unswizzledPixels[i * 4 + 0 + 2] = pixels[i * 2 + 0];
- unswizzledPixels[i * 4 + 0 + 3] = 255;
-
- // The second pixel is the same, except for red.
- unswizzledPixels[i * 4 + 4 + 0] = pixels[i * 2 + 1];
- unswizzledPixels[i * 4 + 4 + 1] = pixels[i * 2 + 2];
- unswizzledPixels[i * 4 + 4 + 2] = pixels[i * 2 + 0];
- unswizzledPixels[i * 4 + 4 + 3] = 255;
- }
-
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, unswizzledPixels);
- free(unswizzledPixels);
- break;
- }
-
- case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8:
- {
- const u32 numPixels = tex.width() * tex.height();
- unswizzledPixels = (u8 *)malloc(numPixels * 4);
- // TODO: Speed.
- for (u32 i = 0; i < numPixels; i += 2)
- {
- unswizzledPixels[i * 4 + 0 + 0] = pixels[i * 2 + 2];
- unswizzledPixels[i * 4 + 0 + 1] = pixels[i * 2 + 3];
- unswizzledPixels[i * 4 + 0 + 2] = pixels[i * 2 + 1];
- unswizzledPixels[i * 4 + 0 + 3] = 255;
-
- // The second pixel is the same, except for red.
- unswizzledPixels[i * 4 + 4 + 0] = pixels[i * 2 + 0];
- unswizzledPixels[i * 4 + 4 + 1] = pixels[i * 2 + 3];
- unswizzledPixels[i * 4 + 4 + 2] = pixels[i * 2 + 1];
- unswizzledPixels[i * 4 + 4 + 3] = 255;
- }
-
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, unswizzledPixels);
- free(unswizzledPixels);
- 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;
- }
- }
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, tex.mipmap() - 1);
- glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, tex.mipmap() > 1);
-
- if (format != CELL_GCM_TEXTURE_B8 && format != CELL_GCM_TEXTURE_X16 && format != CELL_GCM_TEXTURE_X32_FLOAT)
- {
- u8 remap_a = tex.remap() & 0x3;
- u8 remap_r = (tex.remap() >> 2) & 0x3;
- u8 remap_g = (tex.remap() >> 4) & 0x3;
- u8 remap_b = (tex.remap() >> 6) & 0x3;
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, glRemap[remap_a]);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, glRemap[remap_r]);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, glRemap[remap_g]);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, glRemap[remap_b]);
- }
- else
- {
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, glRemap[0]);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, glRemap[1]);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, glRemap[2]);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, glRemap[3]);
- }
-
- static const int gl_tex_zfunc[] =
- {
- GL_NEVER,
- GL_LESS,
- GL_EQUAL,
- GL_LEQUAL,
- GL_GREATER,
- GL_NOTEQUAL,
- GL_GEQUAL,
- GL_ALWAYS,
- };
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, gl_wrap(tex.wrap_s()));
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, gl_wrap(tex.wrap_t()));
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, gl_wrap(tex.wrap_r()));
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, gl_tex_zfunc[tex.zfunc()]);
-
- glTexEnvi(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, tex.bias());
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, (tex.min_lod() >> 8));
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, (tex.max_lod() >> 8));
-
-
-
- static const int gl_tex_min_filter[] =
- {
- GL_NEAREST, // unused
- GL_NEAREST,
- GL_LINEAR,
- GL_NEAREST_MIPMAP_NEAREST,
- GL_LINEAR_MIPMAP_NEAREST,
- GL_NEAREST_MIPMAP_LINEAR,
- GL_LINEAR_MIPMAP_LINEAR,
- GL_NEAREST, // CELL_GCM_TEXTURE_CONVOLUTION_MIN
- };
-
- static const int gl_tex_mag_filter[] = {
- GL_NEAREST, // unused
- GL_NEAREST,
- GL_LINEAR,
- GL_NEAREST, // unused
- GL_LINEAR // CELL_GCM_TEXTURE_CONVOLUTION_MAG
- };
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_tex_min_filter[tex.min_filter()]);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_tex_mag_filter[tex.mag_filter()]);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, max_aniso(tex.max_aniso()));
-
- //Unbind();
-
- if (is_swizzled && format == CELL_GCM_TEXTURE_A8R8G8B8)
- {
- free(unswizzledPixels);
- }
-}
-
-void GLTexture::save(rsx::texture& tex, const std::string& name)
-{
- if (!m_id || !tex.offset() || !tex.width() || !tex.height()) return;
-
- const u32 texPixelCount = tex.width() * tex.height();
-
- u32* alldata = new u32[texPixelCount];
-
- bind();
-
- switch (tex.format() & ~(0x20 | 0x40))
- {
- case CELL_GCM_TEXTURE_B8:
- glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, alldata);
- break;
-
- case CELL_GCM_TEXTURE_A8R8G8B8:
- glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, alldata);
- break;
-
- default:
- delete[] alldata;
- return;
- }
-
- fs::file(fs::get_config_dir() + name + ".raw", fom::rewrite).write(alldata, texPixelCount * 4);
-
- u8* data = new u8[texPixelCount * 3];
- u8* alpha = new u8[texPixelCount];
-
- u8* src = (u8*)alldata;
- u8* dst_d = data;
- u8* dst_a = alpha;
- for (u32 i = 0; i < texPixelCount; i++)
- {
- *dst_d++ = *src++;
- *dst_d++ = *src++;
- *dst_d++ = *src++;
- *dst_a++ = *src++;
- }
-
- rImage out;
- out.Create(tex.width(), tex.height(), data, alpha);
- out.SaveFile(name, rBITMAP_TYPE_PNG);
-
- delete[] alldata;
- //free(data);
- //free(alpha);
-}
-
-void GLTexture::save(rsx::texture& tex)
-{
- static const std::string& dir_path = "textures";
- static const std::string& file_fmt = dir_path + "/" + "tex[%d].png";
-
- if (!fs::is_dir(dir_path)) fs::create_dir(dir_path);
-
- u32 count = 0;
- while (fs::is_file(fmt::format(file_fmt.c_str(), count))) count++;
- save(tex, fmt::format(file_fmt.c_str(), count));
-}
-
-void GLTexture::bind()
-{
- glBindTexture(GL_TEXTURE_2D, m_id);
-}
-
-void GLTexture::unbind()
-{
- glBindTexture(GL_TEXTURE_2D, 0);
-}
-
-void GLTexture::remove()
-{
- if (m_id)
- {
- glDeleteTextures(1, &m_id);
- m_id = 0;
- }
-}
-
-u32 GLTexture::id() const
-{
- return m_id;
-}
-
GLGSRender::GLGSRender() : GSRender(frame_type::OpenGL)
{
}
diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.h b/rpcs3/Emu/RSX/GL/GLGSRender.h
index 06ffd034c6..b49d52a569 100644
--- a/rpcs3/Emu/RSX/GL/GLGSRender.h
+++ b/rpcs3/Emu/RSX/GL/GLGSRender.h
@@ -1,7 +1,7 @@
#pragma once
#include "Emu/RSX/GSRender.h"
-#include "GLBuffers.h"
#include "gl_helpers.h"
+#include "rsx_gl_texture.h"
#define RSX_DEBUG 1
@@ -9,53 +9,14 @@
#pragma comment(lib, "opengl32.lib")
-class GLTexture
-{
- u32 m_id = 0;
-
-public:
- void create();
-
- int gl_wrap(int wrap);
-
- float max_aniso(int aniso);
-
- inline static u8 convert_4_to_8(u8 v)
- {
- // Swizzle bits: 00001234 -> 12341234
- return (v << 4) | (v);
- }
-
- inline static u8 convert_5_to_8(u8 v)
- {
- // Swizzle bits: 00012345 -> 12345123
- return (v << 3) | (v >> 2);
- }
-
- inline static u8 convert_6_to_8(u8 v)
- {
- // Swizzle bits: 00123456 -> 12345612
- return (v << 2) | (v >> 4);
- }
-
- void init(rsx::texture& tex);
- void save(rsx::texture& tex, const std::string& name);
- void save(rsx::texture& tex);
- void bind();
- void unbind();
- void remove();
-
- u32 id() const;
-};
-
class GLGSRender : public GSRender
{
private:
GLFragmentProgram m_fragment_prog;
GLVertexProgram m_vertex_prog;
- GLTexture m_gl_textures[rsx::limits::textures_count];
- GLTexture m_gl_vertex_textures[rsx::limits::vertex_textures_count];
+ rsx::gl::texture m_gl_textures[rsx::limits::textures_count];
+ rsx::gl::texture m_gl_vertex_textures[rsx::limits::vertex_textures_count];
gl::glsl::program *m_program;
diff --git a/rpcs3/Emu/RSX/GL/GLProgram.cpp b/rpcs3/Emu/RSX/GL/GLProgram.cpp
deleted file mode 100644
index 033d1608b5..0000000000
--- a/rpcs3/Emu/RSX/GL/GLProgram.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-#include "stdafx.h"
-#include "Utilities/Log.h"
-#include "Emu/Memory/Memory.h"
-#include "GLProgram.h"
-#include "GLGSRender.h"
-/*
-GLProgram::GLProgram() : id(0)
-{
-}
-
-int GLProgram::GetLocation(const std::string& name)
-{
- for (u32 i=0; i < m_locations.size(); ++i)
- {
- if (!m_locations[i].name.compare(name))
- {
- return m_locations[i].loc;
- }
- }
-
- m_locations.emplace_back();
- u32 pos = m_locations.size()-1;
- m_locations[pos].name = name;
-
- m_locations[pos].loc = glGetUniformLocation(id, name.c_str());
- checkForGlError(fmt::format("glGetUniformLocation(0x%x, %s)", id, name.c_str()));
- return m_locations[pos].loc;
-}
-
-bool GLProgram::IsCreated() const
-{
- return id > 0;
-}
-
-void GLProgram::Create(const u32 vp, const u32 fp)
-{
- if (IsCreated())
- Delete();
-
- id = glCreateProgram();
- glAttachShader(id, vp);
- glAttachShader(id, fp);
-
- glLinkProgram(id);
-
- GLint linkStatus = GL_FALSE;
- glGetProgramiv(id, GL_LINK_STATUS, &linkStatus);
- if (linkStatus != GL_TRUE)
- {
- GLint bufLength = 0;
- glGetProgramiv(id, GL_INFO_LOG_LENGTH, &bufLength);
-
- if (bufLength)
- {
- char* buf = new char[bufLength + 1]();
- glGetProgramInfoLog(id, bufLength, NULL, buf);
- LOG_ERROR(RSX, "Could not link program: %s", buf);
- delete[] buf;
-
- return;
- }
- }
- //else LOG_NOTICE(HLE, "Program linked!");
-
- glGetProgramiv(id, GL_VALIDATE_STATUS, &linkStatus);
- if (linkStatus != GL_TRUE)
- {
- GLint bufLength = 0;
- glGetProgramiv(id, GL_INFO_LOG_LENGTH, &bufLength);
-
- if (bufLength)
- {
- char* buf = new char[bufLength]();
- glGetProgramInfoLog(id, bufLength, NULL, buf);
- LOG_ERROR(RSX, "Could not link program: %s", buf);
- delete[] buf;
-
- return;
- }
- }
-}
-
-void GLProgram::UnUse()
-{
- id = 0;
- m_locations.clear();
-}
-
-void GLProgram::Use()
-{
- if (id != 0)
- glUseProgram(id);
- checkForGlError("glUseProgram");
-}
-
-void GLProgram::SetTex(u32 index)
-{
- int loc = GetLocation(fmt::format("tex%u", index));
- glProgramUniform1i(id, loc, index);
- checkForGlError(fmt::format("SetTex(%u - %d - %d)", id, index, loc));
-}
-
-void GLProgram::SetVTex(u32 index)
-{
- int loc = GetLocation(fmt::format("vtex%u", index));
- glProgramUniform1i(id, loc, index);
- checkForGlError(fmt::format("SetVTex(%u - %d - %d)", id, index, loc));
-}
-
-void GLProgram::Delete()
-{
- if (!IsCreated())
- return;
-
- glDeleteProgram(id);
- id = 0;
- m_locations.clear();
-}
-*/
\ No newline at end of file
diff --git a/rpcs3/Emu/RSX/GL/GLProgram.h b/rpcs3/Emu/RSX/GL/GLProgram.h
deleted file mode 100644
index 024c05b8a1..0000000000
--- a/rpcs3/Emu/RSX/GL/GLProgram.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#pragma once
-
-#include "GLVertexProgram.h"
-#include "GLFragmentProgram.h"
-/*
-struct GLProgram
-{
-private:
- struct Location
- {
- int loc;
- std::string name;
- };
-
- std::vector m_locations;
-
-public:
- u32 id;
-
- GLProgram();
-
- int GetLocation(const std::string& name);
- bool IsCreated() const;
- void Create(const u32 vp, const u32 fp);
- void Use();
- void UnUse();
- void SetTex(u32 index);
- void SetVTex(u32 index);
- void Delete();
-};
-*/
diff --git a/rpcs3/Emu/RSX/GL/GLProgramBuffer.cpp b/rpcs3/Emu/RSX/GL/GLProgramBuffer.cpp
deleted file mode 100644
index 3df737bd0c..0000000000
--- a/rpcs3/Emu/RSX/GL/GLProgramBuffer.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-#include "stdafx.h"
-#include "Utilities/Log.h"
-#include "Emu/Memory/Memory.h"
-
-//#include "GLProgramBuffer.h"
\ No newline at end of file
diff --git a/rpcs3/Emu/RSX/GL/GLProgramBuffer.h b/rpcs3/Emu/RSX/GL/GLProgramBuffer.h
index 5ee69f5e9a..fad18c583d 100644
--- a/rpcs3/Emu/RSX/GL/GLProgramBuffer.h
+++ b/rpcs3/Emu/RSX/GL/GLProgramBuffer.h
@@ -1,5 +1,6 @@
#pragma once
-#include "GLProgram.h"
+#include "GLVertexProgram.h"
+#include "GLFragmentProgram.h"
#include "../Common/ProgramStateCache.h"
#include "Utilities/File.h"
diff --git a/rpcs3/Emu/RSX/GL/rsx_gl_texture.cpp b/rpcs3/Emu/RSX/GL/rsx_gl_texture.cpp
new file mode 100644
index 0000000000..4326be3438
--- /dev/null
+++ b/rpcs3/Emu/RSX/GL/rsx_gl_texture.cpp
@@ -0,0 +1,469 @@
+#include "stdafx.h"
+#include "Utilities/Log.h"
+#include "rsx_gl_texture.h"
+#include "gl_helpers.h"
+#include "../GCM.h"
+#include "../RSXThread.h"
+#include "../RSXTexture.h"
+
+namespace rsx
+{
+ namespace gl
+ {
+ void texture::create()
+ {
+ if (m_id)
+ {
+ remove();
+ }
+
+ glGenTextures(1, &m_id);
+ bind();
+ }
+
+ int texture::gl_wrap(int wrap)
+ {
+ switch (wrap)
+ {
+ case CELL_GCM_TEXTURE_WRAP: return GL_REPEAT;
+ case CELL_GCM_TEXTURE_MIRROR: return GL_MIRRORED_REPEAT;
+ case CELL_GCM_TEXTURE_CLAMP_TO_EDGE: return GL_CLAMP_TO_EDGE;
+ case CELL_GCM_TEXTURE_BORDER: return GL_CLAMP_TO_BORDER;
+ case CELL_GCM_TEXTURE_CLAMP: return GL_CLAMP;
+ case CELL_GCM_TEXTURE_MIRROR_ONCE_CLAMP_TO_EDGE: return GL_MIRROR_CLAMP_TO_EDGE_EXT;
+ case CELL_GCM_TEXTURE_MIRROR_ONCE_BORDER: return GL_MIRROR_CLAMP_TO_BORDER_EXT;
+ case CELL_GCM_TEXTURE_MIRROR_ONCE_CLAMP: return GL_MIRROR_CLAMP_EXT;
+ }
+
+ LOG_ERROR(RSX, "Texture wrap error: bad wrap (%d).", wrap);
+ return GL_REPEAT;
+ }
+
+ float texture::max_aniso(int aniso)
+ {
+ switch (aniso)
+ {
+ case CELL_GCM_TEXTURE_MAX_ANISO_1: return 1.0f;
+ case CELL_GCM_TEXTURE_MAX_ANISO_2: return 2.0f;
+ case CELL_GCM_TEXTURE_MAX_ANISO_4: return 4.0f;
+ case CELL_GCM_TEXTURE_MAX_ANISO_6: return 6.0f;
+ case CELL_GCM_TEXTURE_MAX_ANISO_8: return 8.0f;
+ case CELL_GCM_TEXTURE_MAX_ANISO_10: return 10.0f;
+ case CELL_GCM_TEXTURE_MAX_ANISO_12: return 12.0f;
+ case CELL_GCM_TEXTURE_MAX_ANISO_16: return 16.0f;
+ }
+
+ LOG_ERROR(RSX, "Texture anisotropy error: bad max aniso (%d).", aniso);
+ return 1.0f;
+ }
+
+ void texture::init(rsx::texture& tex)
+ {
+ if (!m_id)
+ create();
+
+ bind();
+
+ const u32 texaddr = rsx::get_address(tex.offset(), tex.location());
+ //LOG_WARNING(RSX, "texture addr = 0x%x, width = %d, height = %d, max_aniso=%d, mipmap=%d, remap=0x%x, zfunc=0x%x, wraps=0x%x, wrapt=0x%x, wrapr=0x%x, minlod=0x%x, maxlod=0x%x",
+ // m_offset, m_width, m_height, m_maxaniso, m_mipmap, m_remap, m_zfunc, m_wraps, m_wrapt, m_wrapr, m_minlod, m_maxlod);
+
+ //TODO: safe init
+
+ int format = tex.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
+ bool is_swizzled = !(tex.format() & CELL_GCM_TEXTURE_LN);
+
+ const u8* pixels = vm::ps3::_ptr(texaddr);
+ u8 *unswizzledPixels;
+ 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;
+
+ switch (format)
+ {
+ case CELL_GCM_TEXTURE_B8: // One 8-bit fixed-point number
+ {
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BLUE, GL_UNSIGNED_BYTE, pixels);
+
+ static const GLint swizzleMaskB8[] = { GL_BLUE, GL_BLUE, GL_BLUE, GL_BLUE };
+ glRemap = swizzleMaskB8;
+ break;
+ }
+
+ case CELL_GCM_TEXTURE_A1R5G5B5:
+ {
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE);
+
+ // TODO: texture swizzling
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, pixels);
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
+ break;
+ }
+
+ case CELL_GCM_TEXTURE_A4R4G4B4:
+ {
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, pixels);
+
+ // 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:
+ {
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tex.width(), tex.height(), 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixels);
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
+ break;
+ }
+
+ case CELL_GCM_TEXTURE_A8R8G8B8:
+ {
+ if (is_swizzled)
+ {
+ u32 *src, *dst;
+ u16 height = tex.height();
+ u16 width = tex.width();
+
+ unswizzledPixels = (u8*)malloc(width * height * 4);
+ src = (u32*)pixels;
+ dst = (u32*)unswizzledPixels;
+
+ if ((height & (height - 1)) || (width & (width - 1)))
+ {
+ LOG_ERROR(RSX, "Swizzle Texture: Width or height not power of 2! (h=%d,w=%d).", height, width);
+ }
+
+ rsx::convert_linear_swizzle(src, dst, width, height, true);
+ }
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, is_swizzled ? unswizzledPixels : pixels);
+ 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(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, tex.width(), tex.height(), 0, size, pixels);
+ 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(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, tex.width(), tex.height(), 0, size, pixels);
+ }
+ 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(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, tex.width(), tex.height(), 0, size, pixels);
+ break;
+ }
+
+ case CELL_GCM_TEXTURE_G8B8:
+ {
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RG, GL_UNSIGNED_BYTE, pixels);
+
+ static const GLint swizzleMaskG8B8[] = { GL_RED, GL_GREEN, GL_RED, GL_GREEN };
+ glRemap = swizzleMaskG8B8;
+ break;
+ }
+
+ case CELL_GCM_TEXTURE_R6G5B5:
+ {
+ // TODO: Probably need to actually unswizzle if is_swizzled.
+ const u32 numPixels = tex.width() * tex.height();
+ unswizzledPixels = (u8 *)malloc(numPixels * 4);
+ // TODO: Speed.
+ for (u32 i = 0; i < numPixels; ++i) {
+ u16 c = reinterpret_cast *>(pixels)[i];
+ unswizzledPixels[i * 4 + 0] = convert_6_to_8((c >> 10) & 0x3F);
+ unswizzledPixels[i * 4 + 1] = convert_5_to_8((c >> 5) & 0x1F);
+ unswizzledPixels[i * 4 + 2] = convert_5_to_8((c >> 0) & 0x1F);
+ unswizzledPixels[i * 4 + 3] = 255;
+ }
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, unswizzledPixels);
+
+ free(unswizzledPixels);
+ break;
+ }
+
+ case CELL_GCM_TEXTURE_DEPTH24_D8: // 24-bit unsigned fixed-point number and 8 bits of garbage
+ {
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, tex.width(), tex.height(), 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, pixels);
+ break;
+ }
+
+ case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT: // 24-bit unsigned float and 8 bits of garbage
+ {
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, tex.width(), tex.height(), 0, GL_DEPTH_COMPONENT, GL_FLOAT, pixels);
+ break;
+ }
+
+ case CELL_GCM_TEXTURE_DEPTH16: // 16-bit unsigned fixed-point number
+ {
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, tex.width(), tex.height(), 0, GL_DEPTH_COMPONENT, GL_SHORT, pixels);
+ break;
+ }
+
+ case CELL_GCM_TEXTURE_DEPTH16_FLOAT: // 16-bit unsigned float
+ {
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, tex.width(), tex.height(), 0, GL_DEPTH_COMPONENT, GL_FLOAT, pixels);
+ break;
+ }
+
+ case CELL_GCM_TEXTURE_X16: // A 16-bit fixed-point number
+ {
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RED, GL_UNSIGNED_SHORT, pixels);
+ 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
+ {
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RG, GL_UNSIGNED_SHORT, pixels);
+ 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:
+ {
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, pixels);
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
+ break;
+ }
+
+ case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: // Four fp16 values
+ {
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_HALF_FLOAT, pixels);
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
+ break;
+ }
+
+ case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT: // Four fp32 values
+ {
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BGRA, GL_FLOAT, pixels);
+ break;
+ }
+
+ case CELL_GCM_TEXTURE_X32_FLOAT: // One 32-bit floating-point number
+ {
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RED, GL_FLOAT, pixels);
+
+ static const GLint swizzleMaskX32_FLOAT[] = { GL_RED, GL_ONE, GL_ONE, GL_ONE };
+ glRemap = swizzleMaskX32_FLOAT;
+ break;
+ }
+
+ case CELL_GCM_TEXTURE_D1R5G5B5:
+ {
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE);
+
+
+ // TODO: Texture swizzling
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, pixels);
+
+ 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(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, pixels);
+
+ 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
+ {
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RG, GL_HALF_FLOAT, pixels);
+ 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:
+ {
+ const u32 numPixels = tex.width() * tex.height();
+ unswizzledPixels = (u8 *)malloc(numPixels * 4);
+ // TODO: Speed.
+ for (u32 i = 0; i < numPixels; i += 2)
+ {
+ unswizzledPixels[i * 4 + 0 + 0] = pixels[i * 2 + 3];
+ unswizzledPixels[i * 4 + 0 + 1] = pixels[i * 2 + 2];
+ unswizzledPixels[i * 4 + 0 + 2] = pixels[i * 2 + 0];
+ unswizzledPixels[i * 4 + 0 + 3] = 255;
+
+ // The second pixel is the same, except for red.
+ unswizzledPixels[i * 4 + 4 + 0] = pixels[i * 2 + 1];
+ unswizzledPixels[i * 4 + 4 + 1] = pixels[i * 2 + 2];
+ unswizzledPixels[i * 4 + 4 + 2] = pixels[i * 2 + 0];
+ unswizzledPixels[i * 4 + 4 + 3] = 255;
+ }
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, unswizzledPixels);
+ free(unswizzledPixels);
+ break;
+ }
+
+ case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8:
+ {
+ const u32 numPixels = tex.width() * tex.height();
+ unswizzledPixels = (u8 *)malloc(numPixels * 4);
+ // TODO: Speed.
+ for (u32 i = 0; i < numPixels; i += 2)
+ {
+ unswizzledPixels[i * 4 + 0 + 0] = pixels[i * 2 + 2];
+ unswizzledPixels[i * 4 + 0 + 1] = pixels[i * 2 + 3];
+ unswizzledPixels[i * 4 + 0 + 2] = pixels[i * 2 + 1];
+ unswizzledPixels[i * 4 + 0 + 3] = 255;
+
+ // The second pixel is the same, except for red.
+ unswizzledPixels[i * 4 + 4 + 0] = pixels[i * 2 + 0];
+ unswizzledPixels[i * 4 + 4 + 1] = pixels[i * 2 + 3];
+ unswizzledPixels[i * 4 + 4 + 2] = pixels[i * 2 + 1];
+ unswizzledPixels[i * 4 + 4 + 3] = 255;
+ }
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, unswizzledPixels);
+ free(unswizzledPixels);
+ 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;
+ }
+ }
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, tex.mipmap() - 1);
+ glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, tex.mipmap() > 1);
+
+ if (format != CELL_GCM_TEXTURE_B8 && format != CELL_GCM_TEXTURE_X16 && format != CELL_GCM_TEXTURE_X32_FLOAT)
+ {
+ u8 remap_a = tex.remap() & 0x3;
+ u8 remap_r = (tex.remap() >> 2) & 0x3;
+ u8 remap_g = (tex.remap() >> 4) & 0x3;
+ u8 remap_b = (tex.remap() >> 6) & 0x3;
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, glRemap[remap_a]);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, glRemap[remap_r]);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, glRemap[remap_g]);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, glRemap[remap_b]);
+ }
+ else
+ {
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, glRemap[0]);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, glRemap[1]);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, glRemap[2]);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, glRemap[3]);
+ }
+
+ static const int gl_tex_zfunc[] =
+ {
+ GL_NEVER,
+ GL_LESS,
+ GL_EQUAL,
+ GL_LEQUAL,
+ GL_GREATER,
+ GL_NOTEQUAL,
+ GL_GEQUAL,
+ GL_ALWAYS,
+ };
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, gl_wrap(tex.wrap_s()));
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, gl_wrap(tex.wrap_t()));
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, gl_wrap(tex.wrap_r()));
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, gl_tex_zfunc[tex.zfunc()]);
+
+ glTexEnvi(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, tex.bias());
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, (tex.min_lod() >> 8));
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, (tex.max_lod() >> 8));
+
+
+
+ static const int gl_tex_min_filter[] =
+ {
+ GL_NEAREST, // unused
+ GL_NEAREST,
+ GL_LINEAR,
+ GL_NEAREST_MIPMAP_NEAREST,
+ GL_LINEAR_MIPMAP_NEAREST,
+ GL_NEAREST_MIPMAP_LINEAR,
+ GL_LINEAR_MIPMAP_LINEAR,
+ GL_NEAREST, // CELL_GCM_TEXTURE_CONVOLUTION_MIN
+ };
+
+ static const int gl_tex_mag_filter[] = {
+ GL_NEAREST, // unused
+ GL_NEAREST,
+ GL_LINEAR,
+ GL_NEAREST, // unused
+ GL_LINEAR // CELL_GCM_TEXTURE_CONVOLUTION_MAG
+ };
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_tex_min_filter[tex.min_filter()]);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_tex_mag_filter[tex.mag_filter()]);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, max_aniso(tex.max_aniso()));
+
+ //Unbind();
+
+ if (is_swizzled && format == CELL_GCM_TEXTURE_A8R8G8B8)
+ {
+ free(unswizzledPixels);
+ }
+ }
+
+ void texture::bind()
+ {
+ glBindTexture(GL_TEXTURE_2D, m_id);
+ }
+
+ void texture::unbind()
+ {
+ glBindTexture(GL_TEXTURE_2D, 0);
+ }
+
+ void texture::remove()
+ {
+ if (m_id)
+ {
+ glDeleteTextures(1, &m_id);
+ m_id = 0;
+ }
+ }
+
+ u32 texture::id() const
+ {
+ return m_id;
+ }
+ }
+}
diff --git a/rpcs3/Emu/RSX/GL/rsx_gl_texture.h b/rpcs3/Emu/RSX/GL/rsx_gl_texture.h
new file mode 100644
index 0000000000..ace0b86c2e
--- /dev/null
+++ b/rpcs3/Emu/RSX/GL/rsx_gl_texture.h
@@ -0,0 +1,45 @@
+
+namespace rsx
+{
+ class texture;
+
+ namespace gl
+ {
+ class texture
+ {
+ u32 m_id = 0;
+
+ public:
+ void create();
+
+ int gl_wrap(int wrap);
+
+ float max_aniso(int aniso);
+
+ inline static u8 convert_4_to_8(u8 v)
+ {
+ // Swizzle bits: 00001234 -> 12341234
+ return (v << 4) | (v);
+ }
+
+ inline static u8 convert_5_to_8(u8 v)
+ {
+ // Swizzle bits: 00012345 -> 12345123
+ return (v << 3) | (v >> 2);
+ }
+
+ inline static u8 convert_6_to_8(u8 v)
+ {
+ // Swizzle bits: 00123456 -> 12345612
+ return (v << 2) | (v >> 4);
+ }
+
+ void init(rsx::texture& tex);
+ void bind();
+ void unbind();
+ void remove();
+
+ u32 id() const;
+ };
+ }
+}
diff --git a/rpcs3/Emu/RSX/RSXFragmentProgram.h b/rpcs3/Emu/RSX/RSXFragmentProgram.h
index 1bde687d92..6ef842d959 100644
--- a/rpcs3/Emu/RSX/RSXFragmentProgram.h
+++ b/rpcs3/Emu/RSX/RSXFragmentProgram.h
@@ -71,7 +71,7 @@ enum
RSX_FP_OPCODE_RET = 0x45 // Return
};
-static union OPDEST
+union OPDEST
{
u32 HEX;
@@ -93,9 +93,9 @@ static union OPDEST
u32 no_dest : 1;
u32 saturate : 1; // _sat
};
-} dst;
+};
-static union SRC0
+union SRC0
{
u32 HEX;
@@ -120,9 +120,9 @@ static union SRC0
u32 cond_mod_reg_index : 1;
u32 cond_reg_index : 1;
};
-} src0;
+};
-static union SRC1
+union SRC1
{
u32 HEX;
@@ -158,9 +158,9 @@ static union SRC1
u32 : 1;
u32 increment : 8; // Increment value for LOOP
};
-} src1;
+};
-static union SRC2
+union SRC2
{
u32 HEX;
@@ -181,7 +181,7 @@ static union SRC2
u32 use_index_reg : 1;
u32 perspective_corr : 1;
};
-} src2;
+};
static const char* rsx_fp_input_attr_regs[] =
{
diff --git a/rpcs3/Emu/RSX/RSXVertexProgram.h b/rpcs3/Emu/RSX/RSXVertexProgram.h
index f05a05749f..f16d811011 100644
--- a/rpcs3/Emu/RSX/RSXVertexProgram.h
+++ b/rpcs3/Emu/RSX/RSXVertexProgram.h
@@ -53,7 +53,7 @@ enum vec_opcode
RSX_VEC_OPCODE_TXL = 0x19
};
-static union D0
+union D0
{
u32 HEX;
@@ -80,9 +80,9 @@ static union D0
u32 vec_result : 1;
u32 : 1;
};
-} d0;
+};
-static union D1
+union D1
{
u32 HEX;
@@ -94,9 +94,9 @@ static union D1
u32 vec_opcode : 5;
u32 sca_opcode : 5;
};
-} d1;
+};
-static union D2
+union D2
{
u32 HEX;
@@ -111,9 +111,9 @@ static union D2
u32 iaddrh : 6;
u32 : 26;
};
-} d2;
+};
-static union D3
+union D3
{
u32 HEX;
@@ -138,9 +138,9 @@ static union D3
u32 : 29;
u32 iaddrl : 3;
};
-} d3;
+};
-static union SRC
+union SRC
{
union
{
@@ -174,7 +174,7 @@ static union SRC
u32 swz_x : 2;
u32 neg : 1;
};
-} src[3];
+};
static const std::string rsx_vp_sca_op_names[] =
{
diff --git a/rpcs3/GLGSRender.vcxproj b/rpcs3/GLGSRender.vcxproj
index bc4738bede..e47df409ab 100644
--- a/rpcs3/GLGSRender.vcxproj
+++ b/rpcs3/GLGSRender.vcxproj
@@ -61,33 +61,79 @@
+
+ $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\
+ $(SolutionDir)lib\$(Configuration)-$(Platform)\
+
+
+ $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\
+ $(SolutionDir)lib\$(Configuration)-$(Platform)\
+
+
+ $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\
+ $(SolutionDir)lib\$(Configuration)-$(Platform)\
+
+
+ $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\
+ $(SolutionDir)lib\$(Configuration)-$(Platform)\
+
+
+ $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\
+ $(SolutionDir)lib\$(Configuration)-$(Platform)\
+
+
+
+ true
+
+
+
+
+ true
+
+
+
+
+
+
+ true
+
+
+
+
+ true
+
+
+
+
+ true
+
+
+
+
{c4a10229-4712-4bd2-b63e-50d93c67a038}
-
-
+
-
-
-
+
diff --git a/rpcs3/GLGSRender.vcxproj.filters b/rpcs3/GLGSRender.vcxproj.filters
index f3ee493441..6d782a3eae 100644
--- a/rpcs3/GLGSRender.vcxproj.filters
+++ b/rpcs3/GLGSRender.vcxproj.filters
@@ -1,69 +1,23 @@
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
+
+
+
+
+
+
+
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
-
-
- {f2f80d8a-5c1d-461d-963f-5de8c8fdf860}
-
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/rpcs3/config.cpp b/rpcs3/config.cpp
index 62488558eb..14424d228b 100644
--- a/rpcs3/config.cpp
+++ b/rpcs3/config.cpp
@@ -33,7 +33,10 @@ namespace rpcs3
void config_t::load()
{
- from_string(fs::file(m_path));
+ fs::file file(m_path);
+
+ if (file)
+ from_string((const std::string)file);
}
void config_t::save() const
diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj
index 0a1ae395e5..1d2f5f1d6d 100644
--- a/rpcs3/emucore.vcxproj
+++ b/rpcs3/emucore.vcxproj
@@ -58,6 +58,46 @@
+
+
+ true
+
+
+ false
+
+
+
+
+ true
+
+
+ true
+
+
+
+
+ true
+
+
+ false
+
+
+
+
+ true
+
+
+ true
+
+
+
+
+ true
+
+
+ false
+
+
@@ -645,6 +685,26 @@
+
+ $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\
+ $(SolutionDir)lib\$(Configuration)-$(Platform)\
+
+
+ $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\
+ $(SolutionDir)lib\$(Configuration)-$(Platform)\
+
+
+ $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\
+ $(SolutionDir)lib\$(Configuration)-$(Platform)\
+
+
+ $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\
+ $(SolutionDir)lib\$(Configuration)-$(Platform)\
+
+
+ $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\
+ $(SolutionDir)lib\$(Configuration)-$(Platform)\
+
diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj
index c2db39580c..9e3439594a 100644
--- a/rpcs3/rpcs3.vcxproj
+++ b/rpcs3/rpcs3.vcxproj
@@ -63,36 +63,41 @@
.\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;.\OpenAL\include;$(IncludePath);..\asmjit\src\asmjit;$(UniversalCRT_IncludePath);..\minidx12\Include
$(SolutionDir)bin\
- ..\libs\$(Configuration)\;$(UniversalCRT_LibraryPath_x64);$(LibraryPath)
+ $(SolutionDir)lib\$(Configuration)-$(Platform)\;$(UniversalCRT_LibraryPath_x64);$(LibraryPath)
$(ProjectName)-dbg
+ $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\
.\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;.\OpenAL\include;$(IncludePath);..\asmjit\src\asmjit;$(UniversalCRT_IncludePath);..\minidx12\Include
$(SolutionDir)bin\
- ..\libs\Debug\;$(UniversalCRT_LibraryPath_x64);$(LibraryPath)
+ $(SolutionDir)lib\$(Configuration)-$(Platform)\;$(SolutionDir)lib\Debug-$(Platform)\;$(UniversalCRT_LibraryPath_x64);$(LibraryPath);$(SolutionDir)lib\$(Configuration)-$(Platform)\
$(ProjectName)-dbg
+ $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\
.\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;.\OpenAL\include;$(UniversalCRT_IncludePath);$(IncludePath);..\minidx12\Include
$(SolutionDir)bin\
- ..\libs\Debug\;$(UniversalCRT_LibraryPath_x64);$(LibraryPath)
+ $(SolutionDir)lib\$(Configuration)-$(Platform)\;$(SolutionDir)lib\Debug-$(Platform)\;$(UniversalCRT_LibraryPath_x64);$(LibraryPath);$(SolutionDir)lib\$(Configuration)-$(Platform)\
$(ProjectName)-dbg
+ $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\
false
.\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;.\OpenAL\include;$(IncludePath);..\asmjit\src\asmjit;$(UniversalCRT_IncludePath);..\minidx12\Include
$(SolutionDir)bin\
- ..\libs\$(Configuration)\;$(UniversalCRT_LibraryPath_x64);$(LibraryPath)
+ $(SolutionDir)lib\$(Configuration)-$(Platform)\;$(UniversalCRT_LibraryPath_x64);$(LibraryPath)
false
false
+ $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\
false
.\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;.\OpenAL\include;$(IncludePath);..\asmjit\src\asmjit;$(UniversalCRT_IncludePath);..\minidx12\Include
$(SolutionDir)bin\
- ..\libs\Release\;$(UniversalCRT_LibraryPath_x64);$(LibraryPath)
+ $(SolutionDir)lib\$(Configuration)-$(Platform)\;$(SolutionDir)lib\Release-$(Platform)\;$(UniversalCRT_LibraryPath_x64);$(LibraryPath)
false
false
+ $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\