Improved GS Renderer.

This commit is contained in:
DH 2013-11-09 23:29:49 +02:00
parent 6ea2c7d6a8
commit 521244b0e0
28 changed files with 2568 additions and 2702 deletions

View File

@ -1,4 +1,5 @@
#pragma once #pragma once
#include "rpcs3.h"
enum enum
{ {
@ -39,6 +40,104 @@ struct gcmInfo
u32 control_addr; u32 control_addr;
}; };
struct CellGcmSurface
{
u8 type;
u8 antialias;
u8 color_format;
u8 color_target;
u8 color_location[4];
u32 color_offset[4];
u32 color_pitch[4];
u8 depth_format;
u8 depth_location;
u16 pad;
u32 depth_offset;
u32 depth_pitch;
u16 width;
u16 height;
u16 x;
u16 y;
};
struct CellGcmReportData
{
u64 timer;
u32 value;
u32 pad;
};
struct CellGcmZcullInfo
{
u32 region;
u32 size;
u32 start;
u32 offset;
u32 status0;
u32 status1;
};
struct CellGcmTileInfo
{
u32 tile;
u32 limit;
u32 pitch;
u32 format;
};
struct GcmZcullInfo
{
u32 m_offset;
u32 m_width;
u32 m_height;
u32 m_cullStart;
u32 m_zFormat;
u32 m_aaFormat;
u32 m_zCullDir;
u32 m_zCullFormat;
u32 m_sFunc;
u32 m_sRef;
u32 m_sMask;
bool m_binded;
GcmZcullInfo()
{
memset(this, 0, sizeof(*this));
}
};
struct GcmTileInfo
{
u8 m_location;
u32 m_offset;
u32 m_size;
u32 m_pitch;
u8 m_comp;
u16 m_base;
u8 m_bank;
bool m_binded;
GcmTileInfo()
{
memset(this, 0, sizeof(*this));
}
CellGcmTileInfo Pack()
{
CellGcmTileInfo ret;
re(ret.tile, (m_location + 1) | (m_bank << 4) | ((m_offset / 0x10000) << 16) | (m_location << 31));
re(ret.limit, ((m_offset + m_size - 1) / 0x10000) << 16 | (m_location << 31));
re(ret.pitch, (m_pitch / 0x100) << 8);
re(ret.format, m_base | ((m_base + ((m_size - 1) / 0x10000)) << 13) | (m_comp << 26) | (1 << 30));
return ret;
}
};
enum enum
{ {
CELL_GCM_LOCATION_LOCAL, CELL_GCM_LOCATION_LOCAL,

View File

@ -1,7 +1,7 @@
#include "stdafx.h" #include "stdafx.h"
#include "FragmentProgram.h" #include "GLFragmentProgram.h"
void FragmentDecompilerThread::AddCode(wxString code, bool append_mask) void GLFragmentDecompilerThread::AddCode(wxString code, bool append_mask)
{ {
if(!src0.exec_if_eq && !src0.exec_if_gr && !src0.exec_if_lt) return; if(!src0.exec_if_eq && !src0.exec_if_gr && !src0.exec_if_lt) return;
@ -79,7 +79,7 @@ void FragmentDecompilerThread::AddCode(wxString code, bool append_mask)
main += "\t" + code + ";\n"; main += "\t" + code + ";\n";
} }
wxString FragmentDecompilerThread::GetMask() wxString GLFragmentDecompilerThread::GetMask()
{ {
wxString ret = wxEmptyString; wxString ret = wxEmptyString;
@ -96,7 +96,7 @@ wxString FragmentDecompilerThread::GetMask()
return ret.IsEmpty() || strncmp(ret, dst_mask, 4) == 0 ? wxEmptyString : ("." + ret); return ret.IsEmpty() || strncmp(ret, dst_mask, 4) == 0 ? wxEmptyString : ("." + ret);
} }
wxString FragmentDecompilerThread::AddReg(u32 index, int fp16) wxString GLFragmentDecompilerThread::AddReg(u32 index, int fp16)
{ {
/* /*
if(HasReg(index, fp16)) if(HasReg(index, fp16))
@ -110,18 +110,18 @@ wxString FragmentDecompilerThread::AddReg(u32 index, int fp16)
wxString::Format((fp16 ? "h%u" : "r%u"), index), fp16 ? -1 : index); wxString::Format((fp16 ? "h%u" : "r%u"), index), fp16 ? -1 : index);
} }
bool FragmentDecompilerThread::HasReg(u32 index, int fp16) bool GLFragmentDecompilerThread::HasReg(u32 index, int fp16)
{ {
return m_parr.HasParam(PARAM_OUT, "vec4", return m_parr.HasParam(PARAM_OUT, "vec4",
wxString::Format((fp16 ? "h%u" : "r%u"), index)); wxString::Format((fp16 ? "h%u" : "r%u"), index));
} }
wxString FragmentDecompilerThread::AddCond(int fp16) wxString GLFragmentDecompilerThread::AddCond(int fp16)
{ {
return m_parr.AddParam(PARAM_NONE , "vec4", wxString::Format(fp16 ? "hc%d" : "rc%d", src0.cond_mod_reg_index)); return m_parr.AddParam(PARAM_NONE , "vec4", wxString::Format(fp16 ? "hc%d" : "rc%d", src0.cond_mod_reg_index));
} }
wxString FragmentDecompilerThread::AddConst() wxString GLFragmentDecompilerThread::AddConst()
{ {
mem32_ptr_t data(m_addr + m_size + m_offset); mem32_ptr_t data(m_addr + m_size + m_offset);
@ -134,12 +134,12 @@ wxString FragmentDecompilerThread::AddConst()
wxString::Format("vec4(%f, %f, %f, %f)", (float&)x, (float&)y, (float&)z, (float&)w)); wxString::Format("vec4(%f, %f, %f, %f)", (float&)x, (float&)y, (float&)z, (float&)w));
} }
wxString FragmentDecompilerThread::AddTex() wxString GLFragmentDecompilerThread::AddTex()
{ {
return m_parr.AddParam(PARAM_UNIFORM, "sampler2D", wxString::Format("tex%d", dst.tex_num)); return m_parr.AddParam(PARAM_UNIFORM, "sampler2D", wxString::Format("tex%d", dst.tex_num));
} }
template<typename T> wxString FragmentDecompilerThread::GetSRC(T src) template<typename T> wxString GLFragmentDecompilerThread::GetSRC(T src)
{ {
wxString ret = wxEmptyString; wxString ret = wxEmptyString;
@ -204,7 +204,7 @@ template<typename T> wxString FragmentDecompilerThread::GetSRC(T src)
return ret; return ret;
} }
wxString FragmentDecompilerThread::BuildCode() wxString GLFragmentDecompilerThread::BuildCode()
{ {
wxString p = wxEmptyString; wxString p = wxEmptyString;
@ -222,7 +222,7 @@ wxString FragmentDecompilerThread::BuildCode()
return wxString::Format(prot, p, main); return wxString::Format(prot, p, main);
} }
void FragmentDecompilerThread::Task() void GLFragmentDecompilerThread::Task()
{ {
mem32_ptr_t data(m_addr); mem32_ptr_t data(m_addr);
m_size = 0; m_size = 0;
@ -322,13 +322,13 @@ void FragmentDecompilerThread::Task()
main.Clear(); main.Clear();
} }
ShaderProgram::ShaderProgram() GLShaderProgram::GLShaderProgram()
: m_decompiler_thread(nullptr) : m_decompiler_thread(nullptr)
, id(0) , id(0)
{ {
} }
ShaderProgram::~ShaderProgram() GLShaderProgram::~GLShaderProgram()
{ {
if(m_decompiler_thread) if(m_decompiler_thread)
{ {
@ -345,7 +345,7 @@ ShaderProgram::~ShaderProgram()
Delete(); Delete();
} }
void ShaderProgram::Decompile() void GLShaderProgram::Decompile(RSXShaderProgram& prog)
{ {
#if 0 #if 0
FragmentDecompilerThread(shader, parr, addr).Entry(); FragmentDecompilerThread(shader, parr, addr).Entry();
@ -362,12 +362,12 @@ void ShaderProgram::Decompile()
m_decompiler_thread = nullptr; m_decompiler_thread = nullptr;
} }
m_decompiler_thread = new FragmentDecompilerThread(shader, parr, addr, size); m_decompiler_thread = new GLFragmentDecompilerThread(shader, parr, prog.addr, prog.size);
m_decompiler_thread->Start(); m_decompiler_thread->Start();
#endif #endif
} }
void ShaderProgram::Compile() void GLShaderProgram::Compile()
{ {
if(id) glDeleteShader(id); if(id) glDeleteShader(id);
@ -401,7 +401,7 @@ void ShaderProgram::Compile()
//else ConLog.Write("Shader compiled successfully!"); //else ConLog.Write("Shader compiled successfully!");
} }
void ShaderProgram::Delete() void GLShaderProgram::Delete()
{ {
for(u32 i=0; i<parr.params.GetCount(); ++i) for(u32 i=0; i<parr.params.GetCount(); ++i)
{ {

View File

@ -1,7 +1,8 @@
#pragma once #pragma once
#include "ShaderParam.h" #include "GLShaderParam.h"
#include "Emu/GS/RSXFragmentProgram.h"
struct FragmentDecompilerThread : public ThreadBase struct GLFragmentDecompilerThread : public ThreadBase
{ {
union OPDEST union OPDEST
{ {
@ -99,14 +100,14 @@ struct FragmentDecompilerThread : public ThreadBase
wxString main; wxString main;
wxString& m_shader; wxString& m_shader;
ParamArray& m_parr; GLParamArray& m_parr;
u32 m_addr; u32 m_addr;
u32& m_size; u32& m_size;
u32 m_const_index; u32 m_const_index;
u32 m_offset; u32 m_offset;
u32 m_location; u32 m_location;
FragmentDecompilerThread(wxString& shader, ParamArray& parr, u32 addr, u32& size) GLFragmentDecompilerThread(wxString& shader, GLParamArray& parr, u32 addr, u32& size)
: ThreadBase(false, "Fragment Shader Decompiler Thread") : ThreadBase(false, "Fragment Shader Decompiler Thread")
, m_shader(shader) , m_shader(shader)
, m_parr(parr) , m_parr(parr)
@ -135,18 +136,15 @@ struct FragmentDecompilerThread : public ThreadBase
u32 GetData(const u32 d) const { return d << 16 | d >> 16; } u32 GetData(const u32 d) const { return d << 16 | d >> 16; }
}; };
struct ShaderProgram struct GLShaderProgram
{ {
ShaderProgram(); GLShaderProgram();
~ShaderProgram(); ~GLShaderProgram();
FragmentDecompilerThread* m_decompiler_thread; GLFragmentDecompilerThread* m_decompiler_thread;
ParamArray parr; GLParamArray parr;
u32 size;
u32 addr;
u32 offset;
wxString shader; wxString shader;
u32 id; u32 id;
@ -158,7 +156,7 @@ struct ShaderProgram
m_decompiler_thread->Wait(); m_decompiler_thread->Wait();
} }
} }
void Decompile(); void Decompile(RSXShaderProgram& prog);
void Compile(); void Compile();
void Delete(); void Delete();

File diff suppressed because it is too large Load Diff

View File

@ -3,9 +3,9 @@
#include "Emu/GS/RSXThread.h" #include "Emu/GS/RSXThread.h"
#include "wx/glcanvas.h" #include "wx/glcanvas.h"
#include "GLBuffers.h" #include "GLBuffers.h"
#include "Program.h" #include "GLProgram.h"
#include "OpenGL.h" #include "OpenGL.h"
#include "ProgramBuffer.h" #include "GLProgramBuffer.h"
#pragma comment(lib, "opengl32.lib") #pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "gl.lib") #pragma comment(lib, "gl.lib")
@ -15,57 +15,10 @@ void checkForGlError(const char* situation);
class GLTexture class GLTexture
{ {
u32 m_width, m_height;
u32 m_id; u32 m_id;
u32 m_offset;
bool m_enabled;
bool m_cubemap;
u8 m_dimension;
u32 m_format;
u16 m_mipmap;
u32 m_pitch;
u16 m_depth;
u16 m_minlod;
u16 m_maxlod;
u8 m_maxaniso;
u8 m_wraps;
u8 m_wrapt;
u8 m_wrapr;
u8 m_unsigned_remap;
u8 m_zfunc;
u8 m_gamma;
u8 m_aniso_bias;
u8 m_signed_remap;
u16 m_bias;
u8 m_min_filter;
u8 m_mag_filter;
u8 m_conv;
u8 m_a_signed;
u8 m_r_signed;
u8 m_g_signed;
u8 m_b_signed;
u32 m_remap;
public: public:
GLTexture() GLTexture() : m_id(0)
: m_width(0), m_height(0)
, m_id(0)
, m_offset(0)
, m_enabled(false)
, m_cubemap(false)
, m_dimension(0)
, m_format(0)
, m_mipmap(0)
, m_minlod(0)
, m_maxlod(1000)
, m_maxaniso(0)
{ {
} }
@ -81,85 +34,9 @@ public:
glGenTextures(1, &m_id); glGenTextures(1, &m_id);
checkForGlError("GLTexture::Init() -> glGenTextures"); checkForGlError("GLTexture::Init() -> glGenTextures");
Bind(); Bind();
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
} }
} }
void SetRect(const u32 width, const u32 height)
{
m_width = width;
m_height = height;
}
u32 GetOffset() const { return m_offset; }
void SetFormat(const bool cubemap, const u8 dimension, const u32 format, const u16 mipmap)
{
m_cubemap = cubemap;
m_dimension = dimension;
m_format = format;
m_mipmap = mipmap;
}
void SetAddress(u8 wraps, u8 wrapt, u8 wrapr, u8 unsigned_remap, u8 zfunc, u8 gamma, u8 aniso_bias, u8 signed_remap)
{
m_wraps = wraps;
m_wrapt = wrapt;
m_wrapr = wrapr;
m_unsigned_remap = unsigned_remap;
m_zfunc = zfunc;
m_gamma = gamma;
m_aniso_bias = aniso_bias;
m_signed_remap = signed_remap;
}
void SetControl0(const bool enable, const u16 minlod, const u16 maxlod, const u8 maxaniso)
{
m_enabled = enable;
m_minlod = minlod;
m_maxlod = maxlod;
m_maxaniso = maxaniso;
}
void SetControl1(u32 remap)
{
m_remap = remap;
}
void SetControl3(u16 depth, u32 pitch)
{
m_depth = depth;
m_pitch = pitch;
}
void SetFilter(u16 bias, u8 min, u8 mag, u8 conv, u8 a_signed, u8 r_signed, u8 g_signed, u8 b_signed)
{
m_bias = bias;
m_min_filter = min;
m_mag_filter = mag;
m_conv = conv;
m_a_signed = a_signed;
m_r_signed = r_signed;
m_g_signed = g_signed;
m_b_signed = b_signed;
}
u32 GetFormat() const { return m_format; }
void SetOffset(const u32 offset)
{
m_offset = offset;
}
wxSize GetRect() const
{
return wxSize(m_width, m_height);
}
int GetGlWrap(int wrap) int GetGlWrap(int wrap)
{ {
switch(wrap) switch(wrap)
@ -176,12 +53,12 @@ public:
return GL_REPEAT; return GL_REPEAT;
} }
void Init() void Init(RSXTexture& tex)
{ {
Bind(); Bind();
if(!Memory.IsGoodAddr(m_offset)) if(!Memory.IsGoodAddr(tex.GetOffset()))
{ {
ConLog.Error("Bad texture address=0x%x", m_offset); ConLog.Error("Bad texture address=0x%x", tex.GetOffset());
return; return;
} }
//ConLog.Warning("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", //ConLog.Warning("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",
@ -189,16 +66,16 @@ public:
//TODO: safe init //TODO: safe init
checkForGlError("GLTexture::Init() -> glBindTexture"); checkForGlError("GLTexture::Init() -> glBindTexture");
int format = m_format & ~(0x20 | 0x40); int format = tex.GetFormat() & ~(0x20 | 0x40);
bool is_swizzled = (m_format & 0x20) == 0; bool is_swizzled = (tex.GetFormat() & 0x20) == 0;
glPixelStorei(GL_PACK_ALIGNMENT, m_pitch); glPixelStorei(GL_PACK_ALIGNMENT, tex.m_pitch);
char* pixels = (char*)Memory.GetMemFromAddr(m_offset); char* pixels = (char*)Memory.GetMemFromAddr(tex.GetOffset());
switch(format) switch(format)
{ {
case 0x81: case 0x81:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_BLUE, GL_UNSIGNED_BYTE, pixels); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.m_width, tex.m_height, 0, GL_BLUE, GL_UNSIGNED_BYTE, pixels);
checkForGlError("GLTexture::Init() -> glTexImage2D"); checkForGlError("GLTexture::Init() -> glTexImage2D");
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE);
@ -210,39 +87,39 @@ public:
break; break;
case 0x85: case 0x85:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, pixels); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.m_width, tex.m_height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, pixels);
checkForGlError("GLTexture::Init() -> glTexImage2D"); checkForGlError("GLTexture::Init() -> glTexImage2D");
break; break;
case 0x86: case 0x86:
{ {
u32 size = ((m_width + 3) / 4) * ((m_height + 3) / 4) * 8; u32 size = ((tex.m_width + 3) / 4) * ((tex.m_height + 3) / 4) * 8;
glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, m_width, m_height, 0, size, pixels); glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, tex.m_width, tex.m_height, 0, size, pixels);
checkForGlError("GLTexture::Init() -> glCompressedTexImage2D"); checkForGlError("GLTexture::Init() -> glCompressedTexImage2D");
} }
break; break;
case 0x87: case 0x87:
{ {
u32 size = ((m_width + 3) / 4) * ((m_height + 3) / 4) * 16; u32 size = ((tex.m_width + 3) / 4) * ((tex.m_height + 3) / 4) * 16;
glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, m_width, m_height, 0, size, pixels); glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, tex.m_width, tex.m_height, 0, size, pixels);
checkForGlError("GLTexture::Init() -> glCompressedTexImage2D"); checkForGlError("GLTexture::Init() -> glCompressedTexImage2D");
} }
break; break;
case 0x88: case 0x88:
{ {
u32 size = ((m_width + 3) / 4) * ((m_height + 3) / 4) * 16; u32 size = ((tex.m_width + 3) / 4) * ((tex.m_height + 3) / 4) * 16;
glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, m_width, m_height, 0, size, pixels); glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, tex.m_width, tex.m_height, 0, size, pixels);
checkForGlError("GLTexture::Init() -> glCompressedTexImage2D"); checkForGlError("GLTexture::Init() -> glCompressedTexImage2D");
} }
break; break;
case 0x94: case 0x94:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RED, GL_SHORT, pixels); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.m_width, tex.m_height, 0, GL_RED, GL_SHORT, pixels);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_ONE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_ONE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_ONE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_ONE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_ONE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_ONE);
@ -251,30 +128,30 @@ public:
break; break;
case 0x9a: case 0x9a:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_BGRA, GL_HALF_FLOAT, pixels); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.m_width, tex.m_height, 0, GL_BGRA, GL_HALF_FLOAT, pixels);
checkForGlError("GLTexture::Init() -> glTexImage2D"); checkForGlError("GLTexture::Init() -> glTexImage2D");
break; break;
case 0x9e: case 0x9e:
{ {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, pixels); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.m_width, tex.m_height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, pixels);
checkForGlError("GLTexture::Init() -> glTexImage2D"); checkForGlError("GLTexture::Init() -> glTexImage2D");
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ONE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ONE);
} }
break; break;
default: ConLog.Error("Init tex error: Bad tex format (0x%x | 0x%x | 0x%x)", format, m_format & 0x20, m_format & 0x40); break; default: ConLog.Error("Init tex error: Bad tex format (0x%x | 0x%x | 0x%x)", format, tex.GetFormat() & 0x20, tex.GetFormat() & 0x40); break;
} }
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, m_mipmap - 1); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, tex.m_mipmap - 1);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, m_mipmap > 1); glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, tex.m_mipmap > 1);
if(format != 0x81 && format != 0x94) if(format != 0x81 && format != 0x94)
{ {
u8 remap_a = m_remap & 0x3; u8 remap_a = tex.m_remap & 0x3;
u8 remap_r = (m_remap >> 2) & 0x3; u8 remap_r = (tex.m_remap >> 2) & 0x3;
u8 remap_g = (m_remap >> 4) & 0x3; u8 remap_g = (tex.m_remap >> 4) & 0x3;
u8 remap_b = (m_remap >> 6) & 0x3; u8 remap_b = (tex.m_remap >> 6) & 0x3;
static const int gl_remap[] = static const int gl_remap[] =
{ {
@ -302,14 +179,14 @@ public:
GL_ALWAYS, GL_ALWAYS,
}; };
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GetGlWrap(m_wraps)); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GetGlWrap(tex.m_wraps));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GetGlWrap(m_wrapt)); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GetGlWrap(tex.m_wrapt));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GetGlWrap(m_wrapr)); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GetGlWrap(tex.m_wrapr));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, gl_tex_zfunc[m_zfunc]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, gl_tex_zfunc[tex.m_zfunc]);
glTexEnvi(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, m_bias); glTexEnvi(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, tex.m_bias);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, m_minlod); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, tex.m_minlod);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, m_maxlod); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, tex.m_maxlod);
static const int gl_tex_filter[] = static const int gl_tex_filter[] =
{ {
@ -323,20 +200,20 @@ public:
GL_NEAREST, GL_NEAREST,
}; };
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_tex_filter[m_min_filter]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_tex_filter[tex.m_min_filter]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_tex_filter[m_mag_filter]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_tex_filter[tex.m_mag_filter]);
//Unbind(); //Unbind();
} }
void Save(const wxString& name) void Save(RSXTexture& tex, const wxString& name)
{ {
if(!m_id || !m_offset || !m_width || !m_height) return; if(!m_id || !tex.m_offset || !tex.m_width || !tex.m_height) return;
u32* alldata = new u32[m_width * m_height]; u32* alldata = new u32[tex.m_width * tex.m_height];
Bind(); Bind();
switch(m_format & ~(0x20 | 0x40)) switch(tex.m_format & ~(0x20 | 0x40))
{ {
case 0x81: case 0x81:
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, alldata); glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, alldata);
@ -353,15 +230,15 @@ public:
{ {
wxFile f(name + ".raw", wxFile::write); wxFile f(name + ".raw", wxFile::write);
f.Write(alldata, m_width * m_height * 4); f.Write(alldata, tex.m_width * tex.m_height * 4);
} }
u8* data = new u8[m_width * m_height * 3]; u8* data = new u8[tex.m_width * tex.m_height * 3];
u8* alpha = new u8[m_width * m_height]; u8* alpha = new u8[tex.m_width * tex.m_height];
u8* src = (u8*)alldata; u8* src = (u8*)alldata;
u8* dst_d = data; u8* dst_d = data;
u8* dst_a = alpha; u8* dst_a = alpha;
for(u32 i=0; i<m_width*m_height;i++) for(u32 i=0; i<tex.m_width*tex.m_height;i++)
{ {
*dst_d++ = *src++; *dst_d++ = *src++;
*dst_d++ = *src++; *dst_d++ = *src++;
@ -370,7 +247,7 @@ public:
} }
wxImage out; wxImage out;
out.Create(m_width, m_height, data, alpha); out.Create(tex.m_width, tex.m_height, data, alpha);
out.SaveFile(name, wxBITMAP_TYPE_PNG); out.SaveFile(name, wxBITMAP_TYPE_PNG);
free(alldata); free(alldata);
@ -378,7 +255,7 @@ public:
//free(alpha); //free(alpha);
} }
void Save() void Save(RSXTexture& tex)
{ {
static const wxString& dir_path = "textures"; static const wxString& dir_path = "textures";
static const wxString& file_fmt = dir_path + "\\" + "tex[%d].png"; static const wxString& file_fmt = dir_path + "\\" + "tex[%d].png";
@ -387,7 +264,7 @@ public:
u32 count = 0; u32 count = 0;
while(wxFileExists(wxString::Format(file_fmt, count))) count++; while(wxFileExists(wxString::Format(file_fmt, count))) count++;
Save(wxString::Format(file_fmt, count)); Save(tex, wxString::Format(file_fmt, count));
} }
void Bind() void Bind()
@ -408,64 +285,11 @@ public:
m_id = 0; m_id = 0;
} }
} }
bool IsEnabled() const { return m_enabled; }
};
struct TransformConstant
{
u32 id;
float x, y, z, w;
TransformConstant()
: x(0.0f)
, y(0.0f)
, z(0.0f)
, w(0.0f)
{
}
TransformConstant(u32 id, float x, float y, float z, float w)
: id(id)
, x(x)
, y(y)
, z(z)
, w(w)
{
}
};
struct IndexArrayData
{
Array<u8> m_data;
int m_type;
u32 m_first;
u32 m_count;
u32 m_addr;
u32 index_max;
u32 index_min;
IndexArrayData()
{
Reset();
}
void Reset()
{
m_type = 0;
m_first = ~0;
m_count = 0;
m_addr = 0;
index_min = ~0;
index_max = 0;
m_data.Clear();
}
}; };
struct GLGSFrame : public GSFrame struct GLGSFrame : public GSFrame
{ {
wxGLCanvas* canvas; wxGLCanvas* canvas;
GLTexture m_textures[16];
u32 m_frames; u32 m_frames;
GLGSFrame(); GLGSFrame();
@ -474,7 +298,6 @@ struct GLGSFrame : public GSFrame
void Flip(); void Flip();
wxGLCanvas* GetCanvas() const { return canvas; } wxGLCanvas* GetCanvas() const { return canvas; }
GLTexture& GetTexture(const u32 index) { return m_textures[index]; }
virtual void SetViewport(int x, int y, u32 w, u32 h); virtual void SetViewport(int x, int y, u32 w, u32 h);
@ -482,22 +305,12 @@ private:
virtual void OnSize(wxSizeEvent& event); virtual void OnSize(wxSizeEvent& event);
}; };
struct GLRSXThread : public ThreadBase
{
wxWindow* m_parent;
Stack<u32> call_stack;
GLRSXThread(wxWindow* parent);
virtual void Task();
};
class PostDrawObj class PostDrawObj
{ {
protected: protected:
ShaderProgram m_fp; GLShaderProgram m_fp;
VertexProgram m_vp; GLVertexProgram m_vp;
Program m_program; GLProgram m_program;
GLfbo m_fbo; GLfbo m_fbo;
GLrbo m_rbo; GLrbo m_rbo;
@ -594,51 +407,35 @@ public:
class GLGSRender class GLGSRender
: public wxWindow : public wxWindow
, public GSRender , public GSRender
, public ExecRSXCMDdata
{ {
public:
static const uint m_vertex_count = 16;
static const uint m_fragment_count = 16;
static const uint m_textures_count = 16;
private: private:
GLRSXThread* m_rsx_thread;
IndexArrayData m_indexed_array;
ShaderProgram m_shader_progs[m_fragment_count];
ShaderProgram* m_cur_shader_prog;
int m_cur_shader_prog_num;
VertexData m_vertex_data[m_vertex_count];
Array<u8> m_vdata; Array<u8> m_vdata;
VertexProgram m_vertex_progs[m_vertex_count];
VertexProgram* m_cur_vertex_prog;
Array<TransformConstant> m_transform_constants;
Array<TransformConstant> m_fragment_constants;
ArrayF<PostDrawObj> m_post_draw_objs; ArrayF<PostDrawObj> m_post_draw_objs;
Program m_program; GLProgram m_program;
int m_fp_buf_num; int m_fp_buf_num;
int m_vp_buf_num; int m_vp_buf_num;
int m_draw_array_count; GLProgramBuffer m_prog_buffer;
int m_draw_mode;
ProgramBuffer m_prog_buffer;
u32 m_width; GLShaderProgram m_shader_prog;
u32 m_height; GLVertexProgram m_vertex_prog;
GLTexture m_gl_textures[m_textures_count];
GLvao m_vao; GLvao m_vao;
GLvbo m_vbo; GLvbo m_vbo;
GLrbo m_rbo; GLrbo m_rbo;
GLfbo m_fbo; GLfbo m_fbo;
wxGLContext* m_context;
public: public:
GLGSFrame* m_frame; GLGSFrame* m_frame;
u32 m_draw_frames; u32 m_draw_frames;
u32 m_skip_frames; u32 m_skip_frames;
GLGSRender(); GLGSRender();
~GLGSRender(); virtual ~GLGSRender();
private: private:
void EnableVertexData(bool indexed_draw=false); void EnableVertexData(bool indexed_draw=false);
@ -648,8 +445,6 @@ private:
void InitFragmentData(); void InitFragmentData();
void Enable(bool enable, const u32 cap); void Enable(bool enable, const u32 cap);
virtual void Init(const u32 ioAddress, const u32 ioSize, const u32 ctrlAddress, const u32 localAddress);
virtual void Draw();
virtual void Close(); virtual void Close();
bool LoadProgram(); bool LoadProgram();
void WriteDepthBuffer(); void WriteDepthBuffer();
@ -661,11 +456,11 @@ private:
void DrawObjects(); void DrawObjects();
public: protected:
void DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u32 count); virtual void OnInit();
void CloseOpenGL(); virtual void OnInitThread();
virtual void OnExitThread();
virtual void OnReset();
virtual void ExecCMD(); virtual void ExecCMD();
virtual void Reset(); virtual void Flip();
void Init();
}; };

View File

@ -1,12 +1,12 @@
#include "stdafx.h" #include "stdafx.h"
#include "Program.h" #include "GLProgram.h"
#include "GLGSRender.h" #include "GLGSRender.h"
Program::Program() : id(0) GLProgram::GLProgram() : id(0)
{ {
} }
int Program::GetLocation(const wxString& name) int GLProgram::GetLocation(const wxString& name)
{ {
for(u32 i=0; i<m_locations.GetCount(); ++i) for(u32 i=0; i<m_locations.GetCount(); ++i)
{ {
@ -24,12 +24,12 @@ int Program::GetLocation(const wxString& name)
return m_locations[pos].loc; return m_locations[pos].loc;
} }
bool Program::IsCreated() const bool GLProgram::IsCreated() const
{ {
return id > 0; return id > 0;
} }
void Program::Create(const u32 vp, const u32 fp) void GLProgram::Create(const u32 vp, const u32 fp)
{ {
if(IsCreated()) Delete(); if(IsCreated()) Delete();
id = glCreateProgram(); id = glCreateProgram();
@ -74,19 +74,19 @@ void Program::Create(const u32 vp, const u32 fp)
} }
} }
void Program::UnUse() void GLProgram::UnUse()
{ {
id = 0; id = 0;
m_locations.Clear(); m_locations.Clear();
} }
void Program::Use() void GLProgram::Use()
{ {
glUseProgram(id); glUseProgram(id);
checkForGlError("glUseProgram"); checkForGlError("glUseProgram");
} }
void Program::SetTex(u32 index) void GLProgram::SetTex(u32 index)
{ {
int loc = GetLocation(wxString::Format("tex%u", index)); int loc = GetLocation(wxString::Format("tex%u", index));
checkForGlError(wxString::Format("GetLocation(tex%u)", index)); checkForGlError(wxString::Format("GetLocation(tex%u)", index));
@ -94,7 +94,7 @@ void Program::SetTex(u32 index)
checkForGlError(wxString::Format("SetTex(%u - %d - %d)", id, index, loc)); checkForGlError(wxString::Format("SetTex(%u - %d - %d)", id, index, loc));
} }
void Program::Delete() void GLProgram::Delete()
{ {
if(!IsCreated()) return; if(!IsCreated()) return;
glDeleteProgram(id); glDeleteProgram(id);

View File

@ -1,8 +1,8 @@
#pragma once #pragma once
#include "VertexProgram.h" #include "GLVertexProgram.h"
#include "FragmentProgram.h" #include "GLFragmentProgram.h"
struct Program struct GLProgram
{ {
private: private:
struct Location struct Location
@ -16,7 +16,7 @@ private:
public: public:
u32 id; u32 id;
Program(); GLProgram();
int GetLocation(const wxString& name); int GetLocation(const wxString& name);
bool IsCreated() const; bool IsCreated() const;

View File

@ -1,14 +1,14 @@
#include "stdafx.h" #include "stdafx.h"
#include "ProgramBuffer.h" #include "GLProgramBuffer.h"
int ProgramBuffer::SearchFp(ShaderProgram& fp) int GLProgramBuffer::SearchFp(const RSXShaderProgram& rsx_fp, GLShaderProgram& gl_fp)
{ {
for(u32 i=0; i<m_buf.GetCount(); ++i) for(u32 i=0; i<m_buf.GetCount(); ++i)
{ {
if(memcmp(&m_buf[i].fp_data[0], &Memory[fp.addr], m_buf[i].fp_data.GetCount()) != 0) continue; if(memcmp(&m_buf[i].fp_data[0], &Memory[rsx_fp.addr], m_buf[i].fp_data.GetCount()) != 0) continue;
fp.id = m_buf[i].fp_id; gl_fp.id = m_buf[i].fp_id;
fp.shader = m_buf[i].fp_shader.GetPtr(); gl_fp.shader = m_buf[i].fp_shader.GetPtr();
return i; return i;
} }
@ -16,15 +16,15 @@ int ProgramBuffer::SearchFp(ShaderProgram& fp)
return -1; return -1;
} }
int ProgramBuffer::SearchVp(VertexProgram& vp) int GLProgramBuffer::SearchVp(const RSXVertexProgram& rsx_vp, GLVertexProgram& gl_vp)
{ {
for(u32 i=0; i<m_buf.GetCount(); ++i) for(u32 i=0; i<m_buf.GetCount(); ++i)
{ {
if(m_buf[i].vp_data.GetCount() != vp.data.GetCount()) continue; if(m_buf[i].vp_data.GetCount() != rsx_vp.data.GetCount()) continue;
if(memcmp(m_buf[i].vp_data.GetPtr(), vp.data.GetPtr(), vp.data.GetCount() * 4) != 0) continue; if(memcmp(m_buf[i].vp_data.GetPtr(), rsx_vp.data.GetPtr(), rsx_vp.data.GetCount() * 4) != 0) continue;
vp.id = m_buf[i].vp_id; gl_vp.id = m_buf[i].vp_id;
vp.shader = m_buf[i].vp_shader.GetPtr(); gl_vp.shader = m_buf[i].vp_shader.GetPtr();
return i; return i;
} }
@ -32,19 +32,19 @@ int ProgramBuffer::SearchVp(VertexProgram& vp)
return -1; return -1;
} }
bool ProgramBuffer::CmpVP(const u32 a, const u32 b) const bool GLProgramBuffer::CmpVP(const u32 a, const u32 b) const
{ {
if(m_buf[a].vp_data.GetCount() != m_buf[b].vp_data.GetCount()) return false; if(m_buf[a].vp_data.GetCount() != m_buf[b].vp_data.GetCount()) return false;
return memcmp(m_buf[a].vp_data.GetPtr(), m_buf[b].vp_data.GetPtr(), m_buf[a].vp_data.GetCount() * 4) == 0; return memcmp(m_buf[a].vp_data.GetPtr(), m_buf[b].vp_data.GetPtr(), m_buf[a].vp_data.GetCount() * 4) == 0;
} }
bool ProgramBuffer::CmpFP(const u32 a, const u32 b) const bool GLProgramBuffer::CmpFP(const u32 a, const u32 b) const
{ {
if(m_buf[a].fp_data.GetCount() != m_buf[b].fp_data.GetCount()) return false; if(m_buf[a].fp_data.GetCount() != m_buf[b].fp_data.GetCount()) return false;
return memcmp(m_buf[a].fp_data.GetPtr(), m_buf[b].fp_data.GetPtr(), m_buf[a].fp_data.GetCount()) == 0; return memcmp(m_buf[a].fp_data.GetPtr(), m_buf[b].fp_data.GetPtr(), m_buf[a].fp_data.GetCount()) == 0;
} }
u32 ProgramBuffer::GetProg(u32 fp, u32 vp) const u32 GLProgramBuffer::GetProg(u32 fp, u32 vp) const
{ {
if(fp == vp) if(fp == vp)
{ {
@ -82,34 +82,34 @@ u32 ProgramBuffer::GetProg(u32 fp, u32 vp) const
return 0; return 0;
} }
void ProgramBuffer::Add(Program& prog, ShaderProgram& fp, VertexProgram& vp) void GLProgramBuffer::Add(GLProgram& prog, GLShaderProgram& gl_fp, RSXShaderProgram& rsx_fp, GLVertexProgram& gl_vp, RSXVertexProgram& rsx_vp)
{ {
BufferInfo& new_buf = *new BufferInfo(); GLBufferInfo& new_buf = *new GLBufferInfo();
ConLog.Write("Add program (%d):", m_buf.GetCount()); ConLog.Write("Add program (%d):", m_buf.GetCount());
ConLog.Write("*** prog id = %d", prog.id); ConLog.Write("*** prog id = %d", prog.id);
ConLog.Write("*** vp id = %d", vp.id); ConLog.Write("*** vp id = %d", gl_vp.id);
ConLog.Write("*** fp id = %d", fp.id); ConLog.Write("*** fp id = %d", gl_fp.id);
ConLog.Write("*** vp data size = %d", vp.data.GetCount() * 4); ConLog.Write("*** vp data size = %d", rsx_vp.data.GetCount() * 4);
ConLog.Write("*** fp data size = %d", fp.size); ConLog.Write("*** fp data size = %d", rsx_fp.size);
ConLog.Write("*** vp shader = \n%s", vp.shader); ConLog.Write("*** vp shader = \n%s", gl_vp.shader);
ConLog.Write("*** fp shader = \n%s", fp.shader); ConLog.Write("*** fp shader = \n%s", gl_fp.shader);
new_buf.prog_id = prog.id; new_buf.prog_id = prog.id;
new_buf.vp_id = vp.id; new_buf.vp_id = gl_vp.id;
new_buf.fp_id = fp.id; new_buf.fp_id = gl_fp.id;
new_buf.fp_data.AddCpy(&Memory[fp.addr], fp.size); new_buf.fp_data.AddCpy(&Memory[rsx_fp.addr], rsx_fp.size);
new_buf.vp_data.CopyFrom(vp.data); new_buf.vp_data.CopyFrom(rsx_vp.data);
new_buf.vp_shader = vp.shader; new_buf.vp_shader = gl_vp.shader;
new_buf.fp_shader = fp.shader; new_buf.fp_shader = gl_fp.shader;
m_buf.Move(&new_buf); m_buf.Move(&new_buf);
} }
void ProgramBuffer::Clear() void GLProgramBuffer::Clear()
{ {
for(u32 i=0; i<m_buf.GetCount(); ++i) for(u32 i=0; i<m_buf.GetCount(); ++i)
{ {

View File

@ -0,0 +1,29 @@
#pragma once
#include "GLProgram.h"
struct GLBufferInfo
{
u32 prog_id;
u32 fp_id;
u32 vp_id;
Array<u8> fp_data;
Array<u32> vp_data;
ArrayString fp_shader;
ArrayString vp_shader;
};
struct GLProgramBuffer
{
Array<GLBufferInfo> m_buf;
int SearchFp(const RSXShaderProgram& rsx_fp, GLShaderProgram& gl_fp);
int SearchVp(const RSXVertexProgram& rsx_vp, GLVertexProgram& gl_vp);
bool CmpVP(const u32 a, const u32 b) const;
bool CmpFP(const u32 a, const u32 b) const;
u32 GetProg(u32 fp, u32 vp) const;
void Add(GLProgram& prog, GLShaderProgram& gl_fp, RSXShaderProgram& rsx_fp, GLVertexProgram& gl_vp, RSXVertexProgram& rsx_vp);
void Clear();
};

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#include "OpenGL.h" #include "OpenGL.h"
enum ParamFlag enum GLParamFlag
{ {
PARAM_IN, PARAM_IN,
PARAM_OUT, PARAM_OUT,
@ -10,13 +10,13 @@ enum ParamFlag
PARAM_NONE, PARAM_NONE,
}; };
struct ParamItem struct GLParamItem
{ {
ArrayString name; ArrayString name;
ArrayString location; ArrayString location;
ArrayString value; ArrayString value;
ParamItem(const wxString& _name, int _location, const wxString& _value = wxEmptyString) GLParamItem(const wxString& _name, int _location, const wxString& _value = wxEmptyString)
: name(_name) : name(_name)
, location(_location > -1 ? wxString::Format("layout (location = %d) ", _location) : "") , location(_location > -1 ? wxString::Format("layout (location = %d) ", _location) : "")
, value(_value) , value(_value)
@ -24,13 +24,13 @@ struct ParamItem
} }
}; };
struct ParamType struct GLParamType
{ {
const ParamFlag flag; const GLParamFlag flag;
ArrayString type; ArrayString type;
Array<ParamItem> items; Array<GLParamItem> items;
ParamType(const ParamFlag _flag, const wxString& _type) GLParamType(const GLParamFlag _flag, const wxString& _type)
: type(_type) : type(_type)
, flag(_flag) , flag(_flag)
{ {
@ -68,11 +68,11 @@ struct ParamType
} }
}; };
struct ParamArray struct GLParamArray
{ {
Array<ParamType> params; Array<GLParamType> params;
ParamType* SearchParam(const wxString& type) GLParamType* SearchParam(const wxString& type)
{ {
for(u32 i=0; i<params.GetCount(); ++i) for(u32 i=0; i<params.GetCount(); ++i)
{ {
@ -82,7 +82,7 @@ struct ParamArray
return nullptr; return nullptr;
} }
wxString GetParamFlag(const ParamFlag flag) wxString GetParamFlag(const GLParamFlag flag)
{ {
switch(flag) switch(flag)
{ {
@ -95,46 +95,46 @@ struct ParamArray
return wxEmptyString; return wxEmptyString;
} }
bool HasParam(const ParamFlag flag, wxString type, const wxString& name) bool HasParam(const GLParamFlag flag, wxString type, const wxString& name)
{ {
type = GetParamFlag(flag) + type; type = GetParamFlag(flag) + type;
ParamType* t = SearchParam(type); GLParamType* t = SearchParam(type);
return t && t->SearchName(name); return t && t->SearchName(name);
} }
wxString AddParam(const ParamFlag flag, wxString type, const wxString& name, const wxString& value) wxString AddParam(const GLParamFlag flag, wxString type, const wxString& name, const wxString& value)
{ {
type = GetParamFlag(flag) + type; type = GetParamFlag(flag) + type;
ParamType* t = SearchParam(type); GLParamType* t = SearchParam(type);
if(t) if(t)
{ {
if(!t->SearchName(name)) t->items.Move(new ParamItem(name, -1, value)); if(!t->SearchName(name)) t->items.Move(new GLParamItem(name, -1, value));
} }
else else
{ {
const u32 num = params.GetCount(); const u32 num = params.GetCount();
params.Move(new ParamType(flag, type)); params.Move(new GLParamType(flag, type));
params[num].items.Move(new ParamItem(name, -1, value)); params[num].items.Move(new GLParamItem(name, -1, value));
} }
return name; return name;
} }
wxString AddParam(const ParamFlag flag, wxString type, const wxString& name, int location = -1) wxString AddParam(const GLParamFlag flag, wxString type, const wxString& name, int location = -1)
{ {
type = GetParamFlag(flag) + type; type = GetParamFlag(flag) + type;
ParamType* t = SearchParam(type); GLParamType* t = SearchParam(type);
if(t) if(t)
{ {
if(!t->SearchName(name)) t->items.Move(new ParamItem(name, location)); if(!t->SearchName(name)) t->items.Move(new GLParamItem(name, location));
} }
else else
{ {
const u32 num = params.GetCount(); const u32 num = params.GetCount();
params.Move(new ParamType(flag, type)); params.Move(new GLParamType(flag, type));
params[num].items.Move(new ParamItem(name, location)); params[num].items.Move(new GLParamItem(name, location));
} }
return name; return name;

View File

@ -1,7 +1,7 @@
#include "stdafx.h" #include "stdafx.h"
#include "VertexProgram.h" #include "GLVertexProgram.h"
wxString VertexDecompilerThread::GetMask(bool is_sca) wxString GLVertexDecompilerThread::GetMask(bool is_sca)
{ {
wxString ret = wxEmptyString; wxString ret = wxEmptyString;
@ -23,17 +23,17 @@ wxString VertexDecompilerThread::GetMask(bool is_sca)
return ret.IsEmpty() || ret == "xyzw" ? wxEmptyString : ("." + ret); return ret.IsEmpty() || ret == "xyzw" ? wxEmptyString : ("." + ret);
} }
wxString VertexDecompilerThread::GetVecMask() wxString GLVertexDecompilerThread::GetVecMask()
{ {
return GetMask(false); return GetMask(false);
} }
wxString VertexDecompilerThread::GetScaMask() wxString GLVertexDecompilerThread::GetScaMask()
{ {
return GetMask(true); return GetMask(true);
} }
wxString VertexDecompilerThread::GetDST(bool isSca) wxString GLVertexDecompilerThread::GetDST(bool isSca)
{ {
static const wxString reg_table[] = static const wxString reg_table[] =
{ {
@ -73,7 +73,7 @@ wxString VertexDecompilerThread::GetDST(bool isSca)
return ret; return ret;
} }
wxString VertexDecompilerThread::GetSRC(const u32 n, bool isSca) wxString GLVertexDecompilerThread::GetSRC(const u32 n, bool isSca)
{ {
static const wxString reg_table[] = static const wxString reg_table[] =
{ {
@ -151,7 +151,7 @@ wxString VertexDecompilerThread::GetSRC(const u32 n, bool isSca)
return ret; return ret;
} }
void VertexDecompilerThread::AddCode(bool is_sca, wxString code, bool src_mask) void GLVertexDecompilerThread::AddCode(bool is_sca, wxString code, bool src_mask)
{ {
if(d0.cond == 0) return; if(d0.cond == 0) return;
enum enum
@ -215,17 +215,17 @@ void VertexDecompilerThread::AddCode(bool is_sca, wxString code, bool src_mask)
main += "\t" + code + ";\n"; main += "\t" + code + ";\n";
} }
void VertexDecompilerThread::AddVecCode(const wxString& code, bool src_mask) void GLVertexDecompilerThread::AddVecCode(const wxString& code, bool src_mask)
{ {
AddCode(false, code, src_mask); AddCode(false, code, src_mask);
} }
void VertexDecompilerThread::AddScaCode(const wxString& code) void GLVertexDecompilerThread::AddScaCode(const wxString& code)
{ {
AddCode(true, code, false); AddCode(true, code, false);
} }
wxString VertexDecompilerThread::BuildCode() wxString GLVertexDecompilerThread::BuildCode()
{ {
wxString p = wxEmptyString; wxString p = wxEmptyString;
@ -243,7 +243,7 @@ wxString VertexDecompilerThread::BuildCode()
return wxString::Format(prot, p, main); return wxString::Format(prot, p, main);
} }
void VertexDecompilerThread::Task() void GLVertexDecompilerThread::Task()
{ {
for(u32 i=0;;) for(u32 i=0;;)
{ {
@ -327,13 +327,13 @@ void VertexDecompilerThread::Task()
main = wxEmptyString; main = wxEmptyString;
} }
VertexProgram::VertexProgram() GLVertexProgram::GLVertexProgram()
: m_decompiler_thread(nullptr) : m_decompiler_thread(nullptr)
, id(0) , id(0)
{ {
} }
VertexProgram::~VertexProgram() GLVertexProgram::~GLVertexProgram()
{ {
if(m_decompiler_thread) if(m_decompiler_thread)
{ {
@ -350,10 +350,10 @@ VertexProgram::~VertexProgram()
Delete(); Delete();
} }
void VertexProgram::Decompile() void GLVertexProgram::Decompile(RSXVertexProgram& prog)
{ {
#if 0 #if 0
VertexDecompilerThread(data, shader, parr).Entry(); GLVertexDecompilerThread(data, shader, parr).Entry();
#else #else
if(m_decompiler_thread) if(m_decompiler_thread)
{ {
@ -367,12 +367,12 @@ void VertexProgram::Decompile()
m_decompiler_thread = nullptr; m_decompiler_thread = nullptr;
} }
m_decompiler_thread = new VertexDecompilerThread(data, shader, parr); m_decompiler_thread = new GLVertexDecompilerThread(prog.data, shader, parr);
m_decompiler_thread->Start(); m_decompiler_thread->Start();
#endif #endif
} }
void VertexProgram::Compile() void GLVertexProgram::Compile()
{ {
if(id) glDeleteShader(id); if(id) glDeleteShader(id);
@ -407,9 +407,8 @@ void VertexProgram::Compile()
} }
void VertexProgram::Delete() void GLVertexProgram::Delete()
{ {
data.Clear();
parr.params.Clear(); parr.params.Clear();
shader.Clear(); shader.Clear();
@ -419,79 +418,3 @@ void VertexProgram::Delete()
id = 0; id = 0;
} }
} }
VertexData::VertexData()
: frequency(0)
, stride(0)
, size(0)
, type(0)
, addr(0)
, data()
{
}
void VertexData::Reset()
{
frequency = 0;
stride = 0;
size = 0;
type = 0;
addr = 0;
data.ClearF();
}
void VertexData::Load(u32 start, u32 count)
{
if(!addr) return;
const u32 tsize = GetTypeSize();
data.SetCount((start + count) * tsize * size);
for(u32 i=start; i<start + count; ++i)
{
const u8* src = Memory.GetMemFromAddr(addr) + stride * i;
u8* dst = &data[i * tsize * size];
switch(tsize)
{
case 1:
{
memcpy(dst, src, size);
}
break;
case 2:
{
const u16* c_src = (const u16*)src;
u16* c_dst = (u16*)dst;
for(u32 j=0; j<size; ++j) *c_dst++ = re(*c_src++);
}
break;
case 4:
{
const u32* c_src = (const u32*)src;
u32* c_dst = (u32*)dst;
for(u32 j=0; j<size; ++j) *c_dst++ = re(*c_src++);
}
break;
}
}
}
u32 VertexData::GetTypeSize()
{
switch (type)
{
case 1: return 2;
case 2: return 4;
case 3: return 2;
case 4: return 1;
case 5: return 2;
case 7: return 1;
}
ConLog.Error("Bad vertex data type! %d", type);
return 1;
}

View File

@ -1,7 +1,8 @@
#pragma once #pragma once
#include "ShaderParam.h" #include "GLShaderParam.h"
#include "Emu/GS/RSXVertexProgram.h"
struct VertexDecompilerThread : public ThreadBase struct GLVertexDecompilerThread : public ThreadBase
{ {
union D0 union D0
{ {
@ -129,9 +130,9 @@ struct VertexDecompilerThread : public ThreadBase
wxString main; wxString main;
wxString& m_shader; wxString& m_shader;
Array<u32>& m_data; Array<u32>& m_data;
ParamArray& m_parr; GLParamArray& m_parr;
VertexDecompilerThread(Array<u32>& data, wxString& shader, ParamArray& parr) GLVertexDecompilerThread(Array<u32>& data, wxString& shader, GLParamArray& parr)
: ThreadBase(false, "Vertex Shader Decompiler Thread") : ThreadBase(false, "Vertex Shader Decompiler Thread")
, m_data(data) , m_data(data)
, m_shader(shader) , m_shader(shader)
@ -152,17 +153,16 @@ struct VertexDecompilerThread : public ThreadBase
virtual void Task(); virtual void Task();
}; };
struct VertexProgram struct GLVertexProgram
{ {
wxString shader; GLVertexDecompilerThread* m_decompiler_thread;
GLVertexProgram();
~GLVertexProgram();
GLParamArray parr;
u32 id; u32 id;
VertexDecompilerThread* m_decompiler_thread; wxString shader;
VertexProgram();
~VertexProgram();
Array<u32> data;
ParamArray parr;
void Wait() void Wait()
{ {
@ -171,27 +171,8 @@ struct VertexProgram
m_decompiler_thread->Wait(); m_decompiler_thread->Wait();
} }
} }
void Decompile();
void Decompile(RSXVertexProgram& prog);
void Compile(); void Compile();
void Delete(); void Delete();
}; };
struct VertexData
{
u32 frequency;
u32 stride;
u32 size;
u32 type;
u32 addr;
u32 constant_count;
Array<u8> data;
VertexData();
void Reset();
bool IsEnabled() { return size > 0; }
void Load(u32 start, u32 count);
u32 GetTypeSize();
};

View File

@ -1,29 +0,0 @@
#pragma once
#include "Program.h"
struct BufferInfo
{
u32 prog_id;
u32 fp_id;
u32 vp_id;
Array<u8> fp_data;
Array<u32> vp_data;
ArrayString fp_shader;
ArrayString vp_shader;
};
struct ProgramBuffer
{
Array<BufferInfo> m_buf;
int SearchFp(ShaderProgram& fp);
int SearchVp(VertexProgram& vp);
bool CmpVP(const u32 a, const u32 b) const;
bool CmpFP(const u32 a, const u32 b) const;
u32 GetProg(u32 fp, u32 vp) const;
void Add(Program& prog, ShaderProgram& fp, VertexProgram& vp);
void Clear();
};

View File

@ -32,6 +32,7 @@ void GSManager::Close()
if(m_render) if(m_render)
{ {
m_render->Close(); m_render->Close();
delete m_render;
m_render = nullptr; m_render = nullptr;
} }
} }

View File

@ -76,28 +76,6 @@ void GSFrame::SetSize(int width, int height)
} }
*/ */
GSRender::GSRender()
: m_ctrl(nullptr)
, m_flip_status(0)
, m_flip_mode(CELL_GCM_DISPLAY_VSYNC)
, m_main_mem_addr(0)
{
}
u32 GSRender::GetAddress(u32 offset, u8 location)
{
switch(location)
{
case CELL_GCM_LOCATION_LOCAL: return m_local_mem_addr + offset;
case CELL_GCM_LOCATION_MAIN: return m_main_mem_addr + offset;
}
ConLog.Error("GetAddress(offset=0x%x, location=0x%x", location);
assert(0);
return 0;
}
GSLockCurrent::GSLockCurrent(GSLockType type) : GSLock(Emu.GetGSManager().GetRender(), type) GSLockCurrent::GSLockCurrent(GSLockType type) : GSLock(Emu.GetGSManager().GetRender(), type)
{ {
} }

View File

@ -1,16 +1,6 @@
#pragma once #pragma once
#include "Emu/GS/GCM.h" #include "Emu/GS/GCM.h"
#include "Emu/SysCalls/Callback.h" #include "Emu/GS/RSXThread.h"
#include "rpcs3.h"
enum Method
{
CELL_GCM_METHOD_FLAG_NON_INCREMENT = 0x40000000,
CELL_GCM_METHOD_FLAG_JUMP = 0x20000000,
CELL_GCM_METHOD_FLAG_CALL = 0x00000002,
CELL_GCM_METHOD_FLAG_RETURN = 0x00020000,
};
wxSize AspectRatio(wxSize rs, const wxSize as); wxSize AspectRatio(wxSize rs, const wxSize as);
@ -40,138 +30,13 @@ private:
DECLARE_EVENT_TABLE(); DECLARE_EVENT_TABLE();
}; };
struct CellGcmSurface struct GSRender : public RSXThread
{ {
u8 type; virtual ~GSRender()
u8 antialias;
u8 color_format;
u8 color_target;
u8 color_location[4];
u32 color_offset[4];
u32 color_pitch[4];
u8 depth_format;
u8 depth_location;
u16 pad;
u32 depth_offset;
u32 depth_pitch;
u16 width;
u16 height;
u16 x;
u16 y;
};
struct CellGcmReportData
{
u64 timer;
u32 value;
u32 pad;
};
struct CellGcmZcullInfo
{
u32 region;
u32 size;
u32 start;
u32 offset;
u32 status0;
u32 status1;
};
struct CellGcmTileInfo
{
u32 tile;
u32 limit;
u32 pitch;
u32 format;
};
struct GcmZcullInfo
{
u32 m_offset;
u32 m_width;
u32 m_height;
u32 m_cullStart;
u32 m_zFormat;
u32 m_aaFormat;
u32 m_zCullDir;
u32 m_zCullFormat;
u32 m_sFunc;
u32 m_sRef;
u32 m_sMask;
bool m_binded;
GcmZcullInfo()
{ {
memset(this, 0, sizeof(*this));
}
};
struct GcmTileInfo
{
u8 m_location;
u32 m_offset;
u32 m_size;
u32 m_pitch;
u8 m_comp;
u16 m_base;
u8 m_bank;
bool m_binded;
GcmTileInfo()
{
memset(this, 0, sizeof(*this));
} }
CellGcmTileInfo Pack()
{
CellGcmTileInfo ret;
re(ret.tile, (m_location + 1) | (m_bank << 4) | ((m_offset / 0x10000) << 16) | (m_location << 31));
re(ret.limit, ((m_offset + m_size - 1) / 0x10000) << 16 | (m_location << 31));
re(ret.pitch, (m_pitch / 0x100) << 8);
re(ret.format, m_base | ((m_base + ((m_size - 1) / 0x10000)) << 13) | (m_comp << 26) | (1 << 30));
return ret;
}
};
static const int g_tiles_count = 15;
struct GSRender
{
u32 m_ioAddress, m_ioSize, m_ctrlAddress;
CellGcmControl* m_ctrl;
wxCriticalSection m_cs_main;
wxSemaphore m_sem_flush;
wxSemaphore m_sem_flip;
int m_flip_status;
int m_flip_mode;
volatile bool m_draw;
Callback m_flip_handler;
GcmTileInfo m_tiles[g_tiles_count];
u32 m_tiles_addr;
u32 m_zculls_addr;
u32 m_gcm_buffers_addr;
u32 m_gcm_buffers_count;
u32 m_gcm_current_buffer;
u32 m_ctxt_addr;
u32 m_report_main_addr;
u32 m_local_mem_addr, m_main_mem_addr;
Array<MemInfo> m_main_mem_info;
GSRender();
virtual void Init(const u32 ioAddress, const u32 ioSize, const u32 ctrlAddress, const u32 localAddress)=0;
virtual void Draw()=0;
virtual void Close()=0; virtual void Close()=0;
u32 GetAddress(u32 offset, u8 location);
}; };
enum GSLockType enum GSLockType

View File

@ -24,168 +24,53 @@ private:
} }
}; };
struct NullRSXThread : public wxThread
{
wxWindow* m_parent;
Stack<u32> call_stack;
NullRSXThread(wxWindow* parent);
virtual void OnExit();
void Start();
ExitCode Entry();
};
class NullGSRender class NullGSRender
: public wxWindow : public wxWindow
, public GSRender , public GSRender
{ {
private:
NullRSXThread* m_rsx_thread;
public: public:
NullGSFrame* m_frame; NullGSFrame* m_frame;
NullGSRender() NullGSRender() : m_frame(nullptr)
: m_frame(nullptr)
, m_rsx_thread(nullptr)
{ {
m_draw = false;
m_frame = new NullGSFrame(); m_frame = new NullGSFrame();
} }
~NullGSRender() virtual ~NullGSRender()
{ {
Close();
m_frame->Close(); m_frame->Close();
} }
private: private:
virtual void Init(const u32 ioAddress, const u32 ioSize, const u32 ctrlAddress, const u32 localAddress) virtual void OnInit()
{ {
if(m_frame->IsShown()) return;
m_frame->SetSize(740, 480);
m_frame->Show(); m_frame->Show();
m_ioAddress = ioAddress;
m_ctrlAddress = ctrlAddress;
m_ioSize = ioSize;
m_local_mem_addr = localAddress;
m_ctrl = (CellGcmControl*)Memory.GetMemFromAddr(m_ctrlAddress);
(m_rsx_thread = new NullRSXThread(this))->Start();
} }
public: virtual void OnInitThread()
void DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u32 count)
{ {
switch(cmd)
{
case NV406E_SET_REFERENCE:
m_ctrl->ref = re32(args[0]);
break;
}
} }
virtual void Draw() virtual void OnExitThread()
{
}
virtual void OnReset()
{
}
virtual void ExecCMD()
{
}
virtual void Flip()
{ {
//if(m_frame && !m_frame->IsBeingDeleted()) m_frame->Draw();
m_draw = true;
} }
virtual void Close() virtual void Close()
{ {
if(m_rsx_thread) m_rsx_thread->Delete(); if(IsAlive()) Stop();
if(m_frame->IsShown()) m_frame->Hide(); if(m_frame->IsShown()) m_frame->Hide();
m_ctrl = NULL;
} }
}; };
NullRSXThread::NullRSXThread(wxWindow* parent)
: wxThread(wxTHREAD_DETACHED)
, m_parent(parent)
{
}
void NullRSXThread::OnExit()
{
call_stack.Clear();
}
void NullRSXThread::Start()
{
Create();
Run();
}
wxThread::ExitCode NullRSXThread::Entry()
{
ConLog.Write("Null RSX thread entry");
NullGSRender& p = *(NullGSRender*)m_parent;
while(!TestDestroy() && p.m_frame && !p.m_frame->IsBeingDeleted())
{
wxCriticalSectionLocker lock(p.m_cs_main);
if(p.m_ctrl->get == p.m_ctrl->put || !Emu.IsRunning())
{
SemaphorePostAndWait(p.m_sem_flush);
if(p.m_draw)
{
p.m_draw = false;
p.m_flip_status = 0;
if(SemaphorePostAndWait(p.m_sem_flip)) continue;
}
Sleep(1);
continue;
}
const u32 get = re(p.m_ctrl->get);
const u32 cmd = Memory.Read32(p.m_ioAddress + get);
const u32 count = (cmd >> 18) & 0x7ff;
if(cmd & CELL_GCM_METHOD_FLAG_JUMP)
{
p.m_ctrl->get = re32(cmd & ~(CELL_GCM_METHOD_FLAG_JUMP | CELL_GCM_METHOD_FLAG_NON_INCREMENT));
ConLog.Warning("rsx jump!");
continue;
}
if(cmd & CELL_GCM_METHOD_FLAG_CALL)
{
call_stack.Push(get + 4);
p.m_ctrl->get = re32(cmd & ~CELL_GCM_METHOD_FLAG_CALL);
ConLog.Warning("rsx call!");
continue;
}
if(cmd & CELL_GCM_METHOD_FLAG_RETURN)
{
p.m_ctrl->get = re32(call_stack.Pop());
ConLog.Warning("rsx return!");
continue;
}
if(cmd & CELL_GCM_METHOD_FLAG_NON_INCREMENT)
{
//ConLog.Warning("non increment cmd! 0x%x", cmd);
}
if(cmd == 0)
{
ConLog.Warning("null cmd: addr=0x%x, put=0x%x, get=0x%x", p.m_ioAddress + get, re(p.m_ctrl->put), get);
Emu.Pause();
continue;
}
p.DoCmd(cmd, cmd & 0x3ffff, mem32_ptr_t(p.m_ioAddress + get + 4), count);
re(p.m_ctrl->get, get + (count + 1) * 4);
}
ConLog.Write("Null RSX thread exit...");
call_stack.Clear();
return (ExitCode)0;
}

View File

@ -0,0 +1,15 @@
#pragma once
struct RSXShaderProgram
{
u32 size;
u32 addr;
u32 offset;
RSXShaderProgram()
: size(0)
, addr(0)
, offset(0)
{
}
};

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,281 @@
#pragma once #pragma once
#include "GCM.h" #include "GCM.h"
#include "RSXVertexProgram.h"
#include "RSXFragmentProgram.h"
#include "Emu/SysCalls/Callback.h"
class ExecRSXCMDdata enum Method
{ {
CELL_GCM_METHOD_FLAG_NON_INCREMENT = 0x40000000,
CELL_GCM_METHOD_FLAG_JUMP = 0x20000000,
CELL_GCM_METHOD_FLAG_CALL = 0x00000002,
CELL_GCM_METHOD_FLAG_RETURN = 0x00020000,
};
class RSXTexture
{
public:
bool m_enabled;
u32 m_width, m_height;
u32 m_offset;
bool m_cubemap;
u8 m_dimension;
u32 m_format;
u16 m_mipmap;
u32 m_pitch;
u16 m_depth;
u16 m_minlod;
u16 m_maxlod;
u8 m_maxaniso;
u8 m_wraps;
u8 m_wrapt;
u8 m_wrapr;
u8 m_unsigned_remap;
u8 m_zfunc;
u8 m_gamma;
u8 m_aniso_bias;
u8 m_signed_remap;
u16 m_bias;
u8 m_min_filter;
u8 m_mag_filter;
u8 m_conv;
u8 m_a_signed;
u8 m_r_signed;
u8 m_g_signed;
u8 m_b_signed;
u32 m_remap;
public:
RSXTexture()
: m_width(0), m_height(0)
, m_offset(0)
, m_enabled(false)
, m_cubemap(false)
, m_dimension(0)
, m_format(0)
, m_mipmap(0)
, m_minlod(0)
, m_maxlod(1000)
, m_maxaniso(0)
{
}
void SetRect(const u32 width, const u32 height)
{
m_width = width;
m_height = height;
}
void SetFormat(const bool cubemap, const u8 dimension, const u32 format, const u16 mipmap)
{
m_cubemap = cubemap;
m_dimension = dimension;
m_format = format;
m_mipmap = mipmap;
}
void SetAddress(u8 wraps, u8 wrapt, u8 wrapr, u8 unsigned_remap, u8 zfunc, u8 gamma, u8 aniso_bias, u8 signed_remap)
{
m_wraps = wraps;
m_wrapt = wrapt;
m_wrapr = wrapr;
m_unsigned_remap = unsigned_remap;
m_zfunc = zfunc;
m_gamma = gamma;
m_aniso_bias = aniso_bias;
m_signed_remap = signed_remap;
}
void SetControl0(const bool enable, const u16 minlod, const u16 maxlod, const u8 maxaniso)
{
m_enabled = enable;
m_minlod = minlod;
m_maxlod = maxlod;
m_maxaniso = maxaniso;
}
void SetControl1(u32 remap)
{
m_remap = remap;
}
void SetControl3(u16 depth, u32 pitch)
{
m_depth = depth;
m_pitch = pitch;
}
void SetFilter(u16 bias, u8 min, u8 mag, u8 conv, u8 a_signed, u8 r_signed, u8 g_signed, u8 b_signed)
{
m_bias = bias;
m_min_filter = min;
m_mag_filter = mag;
m_conv = conv;
m_a_signed = a_signed;
m_r_signed = r_signed;
m_g_signed = g_signed;
m_b_signed = b_signed;
}
u32 GetFormat() const
{
return m_format;
}
void SetOffset(const u32 offset)
{
m_offset = offset;
}
wxSize GetRect() const
{
return wxSize(m_width, m_height);
}
bool IsEnabled() const
{
return m_enabled;
}
u32 GetOffset() const
{
return m_offset;
}
};
struct RSXVertexData
{
u32 frequency;
u32 stride;
u32 size;
u32 type;
u32 addr;
u32 constant_count;
Array<u8> data;
RSXVertexData();
void Reset();
bool IsEnabled() { return size > 0; }
void Load(u32 start, u32 count);
u32 GetTypeSize();
};
struct RSXIndexArrayData
{
Array<u8> m_data;
int m_type;
u32 m_first;
u32 m_count;
u32 m_addr;
u32 index_max;
u32 index_min;
RSXIndexArrayData()
{
Reset();
}
void Reset()
{
m_type = 0;
m_first = ~0;
m_count = 0;
m_addr = 0;
index_min = ~0;
index_max = 0;
m_data.Clear();
}
};
struct RSXTransformConstant
{
u32 id;
float x, y, z, w;
RSXTransformConstant()
: x(0.0f)
, y(0.0f)
, z(0.0f)
, w(0.0f)
{
}
RSXTransformConstant(u32 id, float x, float y, float z, float w)
: id(id)
, x(x)
, y(y)
, z(z)
, w(w)
{
}
};
class RSXThread : public ThreadBase
{
public:
static const uint m_textures_count = 16;
static const uint m_vertex_count = 16;
static const uint m_fragment_count = 16;
static const uint m_tiles_count = 15;
protected:
Stack<u32> m_call_stack;
CellGcmControl* m_ctrl;
public:
GcmTileInfo m_tiles[m_tiles_count];
RSXTexture m_textures[m_textures_count];
RSXVertexData m_vertex_data[m_vertex_count];
RSXIndexArrayData m_indexed_array;
Array<RSXTransformConstant> m_fragment_constants;
Array<RSXTransformConstant> m_transform_constants;
u32 m_cur_shader_prog_num;
RSXShaderProgram m_shader_progs[m_fragment_count];
RSXShaderProgram* m_cur_shader_prog;
RSXVertexProgram m_vertex_progs[m_vertex_count];
RSXVertexProgram* m_cur_vertex_prog;
public:
u32 m_ioAddress, m_ioSize, m_ctrlAddress;
int m_flip_status;
int m_flip_mode;
u32 m_tiles_addr;
u32 m_zculls_addr;
u32 m_gcm_buffers_addr;
u32 m_gcm_buffers_count;
u32 m_gcm_current_buffer;
u32 m_ctxt_addr;
u32 m_report_main_addr;
u32 m_local_mem_addr, m_main_mem_addr;
Array<MemInfo> m_main_mem_info;
protected:
uint m_draw_mode;
u32 m_width, m_height;
u32 m_draw_array_count;
public:
wxCriticalSection m_cs_main;
wxSemaphore m_sem_flush;
wxSemaphore m_sem_flip;
Callback m_flip_handler;
public: public:
bool m_set_color_mask; bool m_set_color_mask;
bool m_color_mask_r; bool m_color_mask_r;
@ -229,8 +502,16 @@ public:
u8 m_begin_end; u8 m_begin_end;
public: protected:
ExecRSXCMDdata() RSXThread()
: ThreadBase(false, "RSXThread")
, m_ctrl(nullptr)
, m_flip_status(0)
, m_flip_mode(CELL_GCM_DISPLAY_VSYNC)
, m_main_mem_addr(0)
, m_local_mem_addr(0)
, m_draw_mode(0)
, m_draw_array_count(0)
{ {
m_set_alpha_test = false; m_set_alpha_test = false;
m_set_blend = false; m_set_blend = false;
@ -246,15 +527,18 @@ public:
m_set_surface_clip_horizontal = false; m_set_surface_clip_horizontal = false;
m_set_surface_clip_vertical = false; m_set_surface_clip_vertical = false;
m_clear_surface_mask = 0;
m_clear_color_r = 0; m_clear_color_r = 0;
m_clear_color_g = 0; m_clear_color_g = 0;
m_clear_color_b = 0; m_clear_color_b = 0;
m_clear_color_a = 0; m_clear_color_a = 0;
m_clear_z = 0xffffff;
m_clear_s = 0;
Reset(); Reset();
} }
virtual void Reset() void Reset()
{ {
m_set_color_mask = false; m_set_color_mask = false;
m_set_clip = false; m_set_clip = false;
@ -302,19 +586,57 @@ public:
m_begin_end = 0; m_begin_end = 0;
} }
virtual void ExecCMD()=0; void Begin(u32 draw_mode);
}; void End();
class RSXThread : public ThreadBase void DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u32 count);
{
Array<u32> call_stack;
CellGcmControl& m_ctrl;
u32 m_ioAddress;
protected: virtual void OnInit() = 0;
RSXThread(CellGcmControl* ctrl, u32 ioAddress); virtual void OnInitThread() = 0;
virtual void OnExitThread() = 0;
virtual void OnReset() = 0;
virtual void ExecCMD() = 0;
virtual void Flip() = 0;
u32 GetAddress(u32 offset, u8 location)
{
switch(location)
{
case CELL_GCM_LOCATION_LOCAL: return m_local_mem_addr + offset;
case CELL_GCM_LOCATION_MAIN: return m_main_mem_addr + offset;
}
ConLog.Error("GetAddress(offset=0x%x, location=0x%x)", location);
assert(0);
return 0;
}
void LoadVertexData(u32 first, u32 count)
{
for(u32 i=0; i<m_vertex_count; ++i)
{
if(!m_vertex_data[i].IsEnabled()) continue;
m_vertex_data[i].Load(first, count);
}
}
private:
virtual void Task(); virtual void Task();
virtual void OnExit();
}; public:
void Init(const u32 ioAddress, const u32 ioSize, const u32 ctrlAddress, const u32 localAddress)
{
m_ctrl = (CellGcmControl*)&Memory[ctrlAddress];
m_ioAddress = ioAddress;
m_ioSize = ioSize;
m_ctrlAddress = ctrlAddress;
m_local_mem_addr = localAddress;
m_cur_vertex_prog = nullptr;
m_cur_shader_prog = nullptr;
m_cur_shader_prog_num = 0;
OnInit();
ThreadBase::Start();
}
};

View File

@ -0,0 +1,6 @@
#pragma once
struct RSXVertexProgram
{
Array<u32> data;
};

View File

@ -219,7 +219,7 @@ public:
MemoryBlocks[i].Delete(); MemoryBlocks[i].Delete();
} }
MemoryBlocks.Clear(); MemoryBlocks.ClearF();
} }
void Write8(const u64 addr, const u8 data); void Write8(const u64 addr, const u8 data);

View File

@ -433,7 +433,7 @@ int cellGcmSetTileInfo(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u
cellGcmSys.Warning("cellGcmSetTileInfo(index=%d, location=%d, offset=%d, size=%d, pitch=%d, comp=%d, base=%d, bank=%d)", cellGcmSys.Warning("cellGcmSetTileInfo(index=%d, location=%d, offset=%d, size=%d, pitch=%d, comp=%d, base=%d, bank=%d)",
index, location, offset, size, pitch, comp, base, bank); index, location, offset, size, pitch, comp, base, bank);
if(index >= g_tiles_count || base >= 800 || bank >= 4) if(index >= RSXThread::m_tiles_count || base >= 800 || bank >= 4)
{ {
return CELL_GCM_ERROR_INVALID_VALUE; return CELL_GCM_ERROR_INVALID_VALUE;
} }
@ -470,7 +470,7 @@ int cellGcmBindTile(u8 index)
{ {
cellGcmSys.Warning("cellGcmBindTile(index=%d)", index); cellGcmSys.Warning("cellGcmBindTile(index=%d)", index);
if(index >= g_tiles_count) if(index >= RSXThread::m_tiles_count)
{ {
return CELL_GCM_ERROR_INVALID_VALUE; return CELL_GCM_ERROR_INVALID_VALUE;
} }
@ -485,7 +485,7 @@ int cellGcmUnbindTile(u8 index)
{ {
cellGcmSys.Warning("cellGcmUnbindTile(index=%d)", index); cellGcmSys.Warning("cellGcmUnbindTile(index=%d)", index);
if(index >= g_tiles_count) if(index >= RSXThread::m_tiles_count)
{ {
return CELL_GCM_ERROR_INVALID_VALUE; return CELL_GCM_ERROR_INVALID_VALUE;
} }

View File

@ -9,7 +9,6 @@ Module cellRecs(0x001f, cellRecs_init);
int cellRescSetConvertAndFlip(s32 indx) int cellRescSetConvertAndFlip(s32 indx)
{ {
cellRecs.Log("cellRescSetConvertAndFlip(indx=0x%x)", indx); cellRecs.Log("cellRescSetConvertAndFlip(indx=0x%x)", indx);
Emu.GetGSManager().GetRender().Draw();
return CELL_OK; return CELL_OK;
} }

View File

@ -312,13 +312,6 @@ void default_syscall()
case 23: RESULT(lv2ProcessWaitForChild2(CPU)); return; case 23: RESULT(lv2ProcessWaitForChild2(CPU)); return;
case 25: RESULT(lv2ProcessGetSdkVersion(CPU)); return; case 25: RESULT(lv2ProcessGetSdkVersion(CPU)); return;
*/ */
//timer
case 141:
case 142:
std::this_thread::sleep_for(std::chrono::nanoseconds(SC_ARGS_1));
RESULT(0);
return;
//tty //tty
case 988: case 988:
ConLog.Warning("SysCall 988! r3: 0x%llx, r4: 0x%llx, pc: 0x%llx", ConLog.Warning("SysCall 988! r3: 0x%llx, r4: 0x%llx, pc: 0x%llx",

View File

@ -219,13 +219,13 @@
<ClCompile Include="Emu\FS\vfsLocalFile.cpp" /> <ClCompile Include="Emu\FS\vfsLocalFile.cpp" />
<ClCompile Include="Emu\FS\vfsStream.cpp" /> <ClCompile Include="Emu\FS\vfsStream.cpp" />
<ClCompile Include="Emu\FS\vfsStreamMemory.cpp" /> <ClCompile Include="Emu\FS\vfsStreamMemory.cpp" />
<ClCompile Include="Emu\GS\GL\FragmentProgram.cpp" />
<ClCompile Include="Emu\GS\GL\GLBuffers.cpp" /> <ClCompile Include="Emu\GS\GL\GLBuffers.cpp" />
<ClCompile Include="Emu\GS\GL\GLFragmentProgram.cpp" />
<ClCompile Include="Emu\GS\GL\GLGSRender.cpp" /> <ClCompile Include="Emu\GS\GL\GLGSRender.cpp" />
<ClCompile Include="Emu\GS\GL\GLProgram.cpp" />
<ClCompile Include="Emu\GS\GL\GLProgramBuffer.cpp" />
<ClCompile Include="Emu\GS\GL\GLVertexProgram.cpp" />
<ClCompile Include="Emu\GS\GL\OpenGL.cpp" /> <ClCompile Include="Emu\GS\GL\OpenGL.cpp" />
<ClCompile Include="Emu\GS\GL\Program.cpp" />
<ClCompile Include="Emu\GS\GL\ProgramBuffer.cpp" />
<ClCompile Include="Emu\GS\GL\VertexProgram.cpp" />
<ClCompile Include="Emu\GS\GSManager.cpp" /> <ClCompile Include="Emu\GS\GSManager.cpp" />
<ClCompile Include="Emu\GS\GSRender.cpp" /> <ClCompile Include="Emu\GS\GSRender.cpp" />
<ClCompile Include="Emu\GS\RSXThread.cpp" /> <ClCompile Include="Emu\GS\RSXThread.cpp" />

View File

@ -160,30 +160,18 @@
<ClCompile Include="Emu\SysCalls\lv2\SC_Heap.cpp"> <ClCompile Include="Emu\SysCalls\lv2\SC_Heap.cpp">
<Filter>Emu\SysCalls\lv2</Filter> <Filter>Emu\SysCalls\lv2</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Emu\GS\GL\FragmentProgram.cpp">
<Filter>Emu\GS\GL</Filter>
</ClCompile>
<ClCompile Include="Emu\GS\GL\GLBuffers.cpp"> <ClCompile Include="Emu\GS\GL\GLBuffers.cpp">
<Filter>Emu\GS\GL</Filter> <Filter>Emu\GS\GL</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Emu\GS\GL\GLGSRender.cpp"> <ClCompile Include="Emu\GS\GL\GLGSRender.cpp">
<Filter>Emu\GS\GL</Filter> <Filter>Emu\GS\GL</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Emu\GS\GL\Program.cpp">
<Filter>Emu\GS\GL</Filter>
</ClCompile>
<ClCompile Include="Emu\GS\GL\VertexProgram.cpp">
<Filter>Emu\GS\GL</Filter>
</ClCompile>
<ClCompile Include="Emu\GS\GL\OpenGL.cpp"> <ClCompile Include="Emu\GS\GL\OpenGL.cpp">
<Filter>Emu\GS\GL</Filter> <Filter>Emu\GS\GL</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Emu\GS\GSRender.cpp"> <ClCompile Include="Emu\GS\GSRender.cpp">
<Filter>Emu\GS</Filter> <Filter>Emu\GS</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Emu\GS\GL\ProgramBuffer.cpp">
<Filter>Emu\GS\GL</Filter>
</ClCompile>
<ClCompile Include="Emu\SysCalls\lv2\SC_SPU_Thread.cpp"> <ClCompile Include="Emu\SysCalls\lv2\SC_SPU_Thread.cpp">
<Filter>Emu\SysCalls\lv2</Filter> <Filter>Emu\SysCalls\lv2</Filter>
</ClCompile> </ClCompile>
@ -343,6 +331,18 @@
<ClCompile Include="Emu\SysCalls\Modules\cellRtc.cpp"> <ClCompile Include="Emu\SysCalls\Modules\cellRtc.cpp">
<Filter>Emu\SysCalls\Modules</Filter> <Filter>Emu\SysCalls\Modules</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Emu\GS\GL\GLFragmentProgram.cpp">
<Filter>Emu\GS\GL</Filter>
</ClCompile>
<ClCompile Include="Emu\GS\GL\GLProgram.cpp">
<Filter>Emu\GS\GL</Filter>
</ClCompile>
<ClCompile Include="Emu\GS\GL\GLProgramBuffer.cpp">
<Filter>Emu\GS\GL</Filter>
</ClCompile>
<ClCompile Include="Emu\GS\GL\GLVertexProgram.cpp">
<Filter>Emu\GS\GL</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="rpcs3.rc" /> <ResourceCompile Include="rpcs3.rc" />

View File

@ -198,8 +198,8 @@ enum Status
#include "Ini.h" #include "Ini.h"
#include "Gui/FrameBase.h" #include "Gui/FrameBase.h"
#include "Gui/ConLog.h" #include "Gui/ConLog.h"
#include "Emu/System.h"
#include "Emu/Memory/Memory.h" #include "Emu/Memory/Memory.h"
#include "Emu/System.h"
#include "Emu/Cell/PPUThread.h" #include "Emu/Cell/PPUThread.h"
#include "Emu/FS/vfsFileBase.h" #include "Emu/FS/vfsFileBase.h"