RSX : inline fragment naming as vertex shader

This commit is contained in:
raven02 2015-01-02 06:55:02 +08:00
parent ac75b62f4d
commit fffadb975b
9 changed files with 85 additions and 108 deletions

View File

@ -613,13 +613,13 @@ void GLFragmentDecompilerThread::Task()
m_parr.params.clear(); m_parr.params.clear();
} }
GLShaderProgram::GLShaderProgram() GLFragmentProgram::GLFragmentProgram()
: m_decompiler_thread(nullptr) : m_decompiler_thread(nullptr)
, m_id(0) , id(0)
{ {
} }
GLShaderProgram::~GLShaderProgram() GLFragmentProgram::~GLFragmentProgram()
{ {
if (m_decompiler_thread) if (m_decompiler_thread)
{ {
@ -636,7 +636,7 @@ GLShaderProgram::~GLShaderProgram()
Delete(); Delete();
} }
void GLShaderProgram::Wait() void GLFragmentProgram::Wait()
{ {
if (m_decompiler_thread && m_decompiler_thread->IsAlive()) if (m_decompiler_thread && m_decompiler_thread->IsAlive())
{ {
@ -644,13 +644,13 @@ void GLShaderProgram::Wait()
} }
} }
void GLShaderProgram::Decompile(RSXShaderProgram& prog) void GLFragmentProgram::Decompile(RSXFragmentProgram& prog)
{ {
GLFragmentDecompilerThread decompiler(m_shader, m_parr, prog.addr, prog.size, prog.ctrl); GLFragmentDecompilerThread decompiler(shader, parr, prog.addr, prog.size, prog.ctrl);
decompiler.Task(); decompiler.Task();
} }
void GLShaderProgram::DecompileAsync(RSXShaderProgram& prog) void GLFragmentProgram::DecompileAsync(RSXFragmentProgram& prog)
{ {
if (m_decompiler_thread) if (m_decompiler_thread)
{ {
@ -664,68 +664,68 @@ void GLShaderProgram::DecompileAsync(RSXShaderProgram& prog)
m_decompiler_thread = nullptr; m_decompiler_thread = nullptr;
} }
m_decompiler_thread = new GLFragmentDecompilerThread(m_shader, m_parr, prog.addr, prog.size, prog.ctrl); m_decompiler_thread = new GLFragmentDecompilerThread(shader, parr, prog.addr, prog.size, prog.ctrl);
m_decompiler_thread->Start(); m_decompiler_thread->Start();
} }
void GLShaderProgram::Compile() void GLFragmentProgram::Compile()
{ {
if (m_id) if (id)
{ {
glDeleteShader(m_id); glDeleteShader(id);
} }
m_id = glCreateShader(GL_FRAGMENT_SHADER); id = glCreateShader(GL_FRAGMENT_SHADER);
const char* str = m_shader.c_str(); const char* str = shader.c_str();
const int strlen = m_shader.length(); const int strlen = shader.length();
glShaderSource(m_id, 1, &str, &strlen); glShaderSource(id, 1, &str, &strlen);
glCompileShader(m_id); glCompileShader(id);
GLint compileStatus = GL_FALSE; GLint compileStatus = GL_FALSE;
glGetShaderiv(m_id, GL_COMPILE_STATUS, &compileStatus); // Determine the result of the glCompileShader call glGetShaderiv(id, GL_COMPILE_STATUS, &compileStatus); // Determine the result of the glCompileShader call
if (compileStatus != GL_TRUE) // If the shader failed to compile... if (compileStatus != GL_TRUE) // If the shader failed to compile...
{ {
GLint infoLength; GLint infoLength;
glGetShaderiv(m_id, GL_INFO_LOG_LENGTH, &infoLength); // Retrieve the length in bytes (including trailing NULL) of the shader info log glGetShaderiv(id, GL_INFO_LOG_LENGTH, &infoLength); // Retrieve the length in bytes (including trailing NULL) of the shader info log
if (infoLength > 0) if (infoLength > 0)
{ {
GLsizei len; GLsizei len;
char* buf = new char[infoLength]; // Buffer to store infoLog char* buf = new char[infoLength]; // Buffer to store infoLog
glGetShaderInfoLog(m_id, infoLength, &len, buf); // Retrieve the shader info log into our buffer glGetShaderInfoLog(id, infoLength, &len, buf); // Retrieve the shader info log into our buffer
LOG_ERROR(RSX, "Failed to compile shader: %s", buf); // Write log to the console LOG_ERROR(RSX, "Failed to compile shader: %s", buf); // Write log to the console
delete[] buf; delete[] buf;
} }
LOG_NOTICE(RSX, m_shader.c_str()); // Log the text of the shader that failed to compile LOG_NOTICE(RSX, shader.c_str()); // Log the text of the shader that failed to compile
Emu.Pause(); // Pause the emulator, we can't really continue from here Emu.Pause(); // Pause the emulator, we can't really continue from here
} }
} }
void GLShaderProgram::Delete() void GLFragmentProgram::Delete()
{ {
for (auto& param : m_parr.params) { for (auto& param : parr.params) {
param.items.clear(); param.items.clear();
param.type.clear(); param.type.clear();
} }
m_parr.params.clear(); parr.params.clear();
m_shader.clear(); shader.clear();
if (m_id) if (id)
{ {
if (Emu.IsStopped()) if (Emu.IsStopped())
{ {
LOG_WARNING(RSX, "GLShaderProgram::Delete(): glDeleteShader(%d) avoided", m_id); LOG_WARNING(RSX, "GLFragmentProgram::Delete(): glDeleteShader(%d) avoided", id);
} }
else else
{ {
glDeleteShader(m_id); glDeleteShader(id);
} }
m_id = 0; id = 0;
} }
} }

View File

@ -168,24 +168,28 @@ struct GLFragmentDecompilerThread : public ThreadBase
/** Storage for an Fragment Program in the process of of recompilation. /** Storage for an Fragment Program in the process of of recompilation.
* This class calls OpenGL functions and should only be used from the RSX/Graphics thread. * This class calls OpenGL functions and should only be used from the RSX/Graphics thread.
*/ */
class GLShaderProgram class GLFragmentProgram
{ {
public: public:
GLShaderProgram(); GLFragmentProgram();
~GLShaderProgram(); ~GLFragmentProgram();
GLParamArray parr;
u32 id;
std::string shader;
/** /**
* Decompile a fragment shader located in the PS3's Memory. This function operates synchronously. * Decompile a fragment shader located in the PS3's Memory. This function operates synchronously.
* @param prog RSXShaderProgram specifying the location and size of the shader in memory * @param prog RSXShaderProgram specifying the location and size of the shader in memory
*/ */
void Decompile(RSXShaderProgram& prog); void Decompile(RSXFragmentProgram& prog);
/** /**
* Asynchronously decompile a fragment shader located in the PS3's Memory. * Asynchronously decompile a fragment shader located in the PS3's Memory.
* When this function is called you must call Wait() before GetShaderText() will return valid data. * When this function is called you must call Wait() before GetShaderText() will return valid data.
* @param prog RSXShaderProgram specifying the location and size of the shader in memory * @param prog RSXShaderProgram specifying the location and size of the shader in memory
*/ */
void DecompileAsync(RSXShaderProgram& prog); void DecompileAsync(RSXFragmentProgram& prog);
/** Wait for the decompiler task to complete decompilation. */ /** Wait for the decompiler task to complete decompilation. */
void Wait(); void Wait();
@ -193,37 +197,10 @@ public:
/** Compile the decompiled fragment shader into a format we can use with OpenGL. */ /** Compile the decompiled fragment shader into a format we can use with OpenGL. */
void Compile(); void Compile();
/** Get the source text for this shader */
inline const std::string& GetShaderText() const { return m_shader; }
/**
* Set the source text for this shader
* @param shaderText supplied shader text
*/
inline void SetShaderText(const std::string& shaderText) { m_shader = shaderText; }
/** Get the OpenGL id this shader is bound to */
inline u32 GetId() const { return m_id; }
/**
* Set the OpenGL id this shader is bound to
* @param id supplied id
*/
inline void SetId(const u32 id) { m_id = id; }
private: private:
/** Threaded fragment shader decompiler responsible for decompiling this program */ /** Threaded fragment shader decompiler responsible for decompiling this program */
GLFragmentDecompilerThread* m_decompiler_thread; GLFragmentDecompilerThread* m_decompiler_thread;
/** Shader parameter storage */
GLParamArray m_parr;
/** Text of our decompiler shader */
std::string m_shader;
/** OpenGL id this shader is bound to */
u32 m_id;
/** Deletes the shader and any stored information */ /** Deletes the shader and any stored information */
void Delete(); void Delete();
}; };

View File

@ -655,7 +655,7 @@ void PostDrawObj::Initialize()
InitializeShaders(); InitializeShaders();
m_fp.Compile(); m_fp.Compile();
m_vp.Compile(); m_vp.Compile();
m_program.Create(m_vp.id, m_fp.GetId()); m_program.Create(m_vp.id, m_fp.id);
m_program.Use(); m_program.Use();
InitializeLocations(); InitializeLocations();
} }
@ -746,7 +746,7 @@ void DrawCursorObj::InitializeShaders()
" gl_Position = in_pos;\n" " gl_Position = in_pos;\n"
"}\n"; "}\n";
m_fp.SetShaderText( m_fp.shader =
"#version 330\n" "#version 330\n"
"\n" "\n"
"in vec2 tc;\n" "in vec2 tc;\n"
@ -756,7 +756,7 @@ void DrawCursorObj::InitializeShaders()
"void main()\n" "void main()\n"
"{\n" "{\n"
" res = texture(tex0, tc);\n" " res = texture(tex0, tc);\n"
"}\n"); "}\n";
} }
void DrawCursorObj::SetTexture(void* pixels, int width, int height) void DrawCursorObj::SetTexture(void* pixels, int width, int height)
@ -1070,7 +1070,7 @@ void GLGSRender::InitVertexData()
void GLGSRender::InitFragmentData() void GLGSRender::InitFragmentData()
{ {
if (!m_cur_shader_prog) if (!m_cur_fragment_prog)
{ {
LOG_ERROR(RSX, "InitFragmentData: m_cur_shader_prog == NULL"); LOG_ERROR(RSX, "InitFragmentData: m_cur_shader_prog == NULL");
return; return;
@ -1078,7 +1078,7 @@ void GLGSRender::InitFragmentData()
for (const RSXTransformConstant& c : m_fragment_constants) for (const RSXTransformConstant& c : m_fragment_constants)
{ {
u32 id = c.id - m_cur_shader_prog->offset; u32 id = c.id - m_cur_fragment_prog->offset;
//LOG_WARNING(RSX,"fc%u[0x%x - 0x%x] = (%f, %f, %f, %f)", id, c.id, m_cur_shader_prog->offset, c.x, c.y, c.z, c.w); //LOG_WARNING(RSX,"fc%u[0x%x - 0x%x] = (%f, %f, %f, %f)", id, c.id, m_cur_shader_prog->offset, c.x, c.y, c.z, c.w);
@ -1096,13 +1096,13 @@ void GLGSRender::InitFragmentData()
bool GLGSRender::LoadProgram() bool GLGSRender::LoadProgram()
{ {
if (!m_cur_shader_prog) if (!m_cur_fragment_prog)
{ {
LOG_WARNING(RSX, "LoadProgram: m_cur_shader_prog == NULL"); LOG_WARNING(RSX, "LoadProgram: m_cur_shader_prog == NULL");
return false; return false;
} }
m_cur_shader_prog->ctrl = m_shader_ctrl; m_cur_fragment_prog->ctrl = m_shader_ctrl;
if (!m_cur_vertex_prog) if (!m_cur_vertex_prog)
{ {
@ -1110,19 +1110,19 @@ bool GLGSRender::LoadProgram()
return false; return false;
} }
m_fp_buf_num = m_prog_buffer.SearchFp(*m_cur_shader_prog, m_shader_prog); m_fp_buf_num = m_prog_buffer.SearchFp(*m_cur_fragment_prog, m_fragment_prog);
m_vp_buf_num = m_prog_buffer.SearchVp(*m_cur_vertex_prog, m_vertex_prog); m_vp_buf_num = m_prog_buffer.SearchVp(*m_cur_vertex_prog, m_vertex_prog);
if (m_fp_buf_num == -1) if (m_fp_buf_num == -1)
{ {
LOG_WARNING(RSX, "FP not found in buffer!"); LOG_WARNING(RSX, "FP not found in buffer!");
m_shader_prog.Decompile(*m_cur_shader_prog); m_fragment_prog.Decompile(*m_cur_fragment_prog);
m_shader_prog.Compile(); m_fragment_prog.Compile();
checkForGlError("m_shader_prog.Compile"); checkForGlError("m_fragment_prog.Compile");
// TODO: This shouldn't use current dir // TODO: This shouldn't use current dir
rFile f("./FragmentProgram.txt", rFile::write); rFile f("./FragmentProgram.txt", rFile::write);
f.Write(m_shader_prog.GetShaderText()); f.Write(m_fragment_prog.shader);
} }
if (m_vp_buf_num == -1) if (m_vp_buf_num == -1)
@ -1153,21 +1153,21 @@ bool GLGSRender::LoadProgram()
{ {
// TODO: This isn't working perfectly. Is there any better/shorter way to update the program // TODO: This isn't working perfectly. Is there any better/shorter way to update the program
m_vertex_prog.shader = program.vp_shader; m_vertex_prog.shader = program.vp_shader;
m_shader_prog.SetShaderText(program.fp_shader); m_fragment_prog.shader = program.fp_shader;
m_vertex_prog.Wait(); m_vertex_prog.Wait();
m_vertex_prog.Compile(); m_vertex_prog.Compile();
checkForGlError("m_vertex_prog.Compile"); checkForGlError("m_vertex_prog.Compile");
m_shader_prog.Wait(); m_fragment_prog.Wait();
m_shader_prog.Compile(); m_fragment_prog.Compile();
checkForGlError("m_shader_prog.Compile"); checkForGlError("m_fragment_prog.Compile");
glAttachShader(m_program.id, m_vertex_prog.id); glAttachShader(m_program.id, m_vertex_prog.id);
glAttachShader(m_program.id, m_shader_prog.GetId()); glAttachShader(m_program.id, m_fragment_prog.id);
glLinkProgram(m_program.id); glLinkProgram(m_program.id);
checkForGlError("glLinkProgram"); checkForGlError("glLinkProgram");
glDetachShader(m_program.id, m_vertex_prog.id); glDetachShader(m_program.id, m_vertex_prog.id);
glDetachShader(m_program.id, m_shader_prog.GetId()); glDetachShader(m_program.id, m_fragment_prog.id);
program.vp_id = m_vertex_prog.id; program.vp_id = m_vertex_prog.id;
program.fp_id = m_shader_prog.GetId(); program.fp_id = m_fragment_prog.id;
program.modified = false; program.modified = false;
} }
} }
@ -1176,9 +1176,9 @@ bool GLGSRender::LoadProgram()
} }
else else
{ {
m_program.Create(m_vertex_prog.id, m_shader_prog.GetId()); m_program.Create(m_vertex_prog.id, m_fragment_prog.id);
checkForGlError("m_program.Create"); checkForGlError("m_program.Create");
m_prog_buffer.Add(m_program, m_shader_prog, *m_cur_shader_prog, m_vertex_prog, *m_cur_vertex_prog); m_prog_buffer.Add(m_program, m_fragment_prog, *m_cur_fragment_prog, m_vertex_prog, *m_cur_vertex_prog);
checkForGlError("m_prog_buffer.Add"); checkForGlError("m_prog_buffer.Add");
m_program.Use(); m_program.Use();
@ -1188,9 +1188,9 @@ bool GLGSRender::LoadProgram()
RSXDebuggerProgram program; RSXDebuggerProgram program;
program.id = m_program.id; program.id = m_program.id;
program.vp_id = m_vertex_prog.id; program.vp_id = m_vertex_prog.id;
program.fp_id = m_shader_prog.GetId(); program.fp_id = m_fragment_prog.id;
program.vp_shader = m_vertex_prog.shader; program.vp_shader = m_vertex_prog.shader;
program.fp_shader = m_shader_prog.GetShaderText(); program.fp_shader = m_fragment_prog.shader;
m_debug_programs.push_back(program); m_debug_programs.push_back(program);
} }
} }

View File

@ -67,7 +67,7 @@ public:
class PostDrawObj class PostDrawObj
{ {
protected: protected:
GLShaderProgram m_fp; GLFragmentProgram m_fp;
GLVertexProgram m_vp; GLVertexProgram m_vp;
GLProgram m_program; GLProgram m_program;
GLfbo m_fbo; GLfbo m_fbo;
@ -144,7 +144,7 @@ private:
int m_vp_buf_num; int m_vp_buf_num;
GLProgramBuffer m_prog_buffer; GLProgramBuffer m_prog_buffer;
GLShaderProgram m_shader_prog; GLFragmentProgram m_fragment_prog;
GLVertexProgram m_vertex_prog; GLVertexProgram m_vertex_prog;
GLTexture m_gl_textures[m_textures_count]; GLTexture m_gl_textures[m_textures_count];

View File

@ -4,14 +4,14 @@
#include "GLProgramBuffer.h" #include "GLProgramBuffer.h"
int GLProgramBuffer::SearchFp(const RSXShaderProgram& rsx_fp, GLShaderProgram& gl_fp) int GLProgramBuffer::SearchFp(const RSXFragmentProgram& rsx_fp, GLFragmentProgram& gl_fp)
{ {
for(u32 i=0; i<m_buf.size(); ++i) for(u32 i=0; i<m_buf.size(); ++i)
{ {
if(memcmp(&m_buf[i].fp_data[0], vm::get_ptr<void>(rsx_fp.addr), m_buf[i].fp_data.size()) != 0) continue; if(memcmp(&m_buf[i].fp_data[0], vm::get_ptr<void>(rsx_fp.addr), m_buf[i].fp_data.size()) != 0) continue;
gl_fp.SetId(m_buf[i].fp_id); gl_fp.id = m_buf[i].fp_id;
gl_fp.SetShaderText(m_buf[i].fp_shader); gl_fp.shader = m_buf[i].fp_shader.c_str();
return i; return i;
} }
@ -85,30 +85,30 @@ u32 GLProgramBuffer::GetProg(u32 fp, u32 vp) const
return 0; return 0;
} }
void GLProgramBuffer::Add(GLProgram& prog, GLShaderProgram& gl_fp, RSXShaderProgram& rsx_fp, GLVertexProgram& gl_vp, RSXVertexProgram& rsx_vp) void GLProgramBuffer::Add(GLProgram& prog, GLFragmentProgram& gl_fp, RSXFragmentProgram& rsx_fp, GLVertexProgram& gl_vp, RSXVertexProgram& rsx_vp)
{ {
GLBufferInfo new_buf; GLBufferInfo new_buf;
LOG_NOTICE(RSX, "Add program (%d):", m_buf.size()); LOG_NOTICE(RSX, "Add program (%d):", m_buf.size());
LOG_NOTICE(RSX, "*** prog id = %d", prog.id); LOG_NOTICE(RSX, "*** prog id = %d", prog.id);
LOG_NOTICE(RSX, "*** vp id = %d", gl_vp.id); LOG_NOTICE(RSX, "*** vp id = %d", gl_vp.id);
LOG_NOTICE(RSX, "*** fp id = %d", gl_fp.GetId()); LOG_NOTICE(RSX, "*** fp id = %d", gl_fp.id);
LOG_NOTICE(RSX, "*** vp data size = %d", rsx_vp.data.size() * 4); LOG_NOTICE(RSX, "*** vp data size = %d", rsx_vp.data.size() * 4);
LOG_NOTICE(RSX, "*** fp data size = %d", rsx_fp.size); LOG_NOTICE(RSX, "*** fp data size = %d", rsx_fp.size);
LOG_NOTICE(RSX, "*** vp shader = \n%s", gl_vp.shader.c_str()); LOG_NOTICE(RSX, "*** vp shader = \n%s", gl_vp.shader.c_str());
LOG_NOTICE(RSX, "*** fp shader = \n%s", gl_fp.GetShaderText().c_str()); LOG_NOTICE(RSX, "*** fp shader = \n%s", gl_fp.shader.c_str());
new_buf.prog_id = prog.id; new_buf.prog_id = prog.id;
new_buf.vp_id = gl_vp.id; new_buf.vp_id = gl_vp.id;
new_buf.fp_id = gl_fp.GetId(); new_buf.fp_id = gl_fp.id;
new_buf.fp_data.insert(new_buf.fp_data.end(), vm::get_ptr<u8>(rsx_fp.addr), vm::get_ptr<u8>(rsx_fp.addr + rsx_fp.size)); new_buf.fp_data.insert(new_buf.fp_data.end(), vm::get_ptr<u8>(rsx_fp.addr), vm::get_ptr<u8>(rsx_fp.addr + rsx_fp.size));
new_buf.vp_data = rsx_vp.data; new_buf.vp_data = rsx_vp.data;
new_buf.vp_shader = gl_vp.shader; new_buf.vp_shader = gl_vp.shader;
new_buf.fp_shader = gl_fp.GetShaderText(); new_buf.fp_shader = gl_fp.shader;
m_buf.push_back(new_buf); m_buf.push_back(new_buf);
} }

View File

@ -16,7 +16,7 @@ struct GLProgramBuffer
{ {
std::vector<GLBufferInfo> m_buf; std::vector<GLBufferInfo> m_buf;
int SearchFp(const RSXShaderProgram& rsx_fp, GLShaderProgram& gl_fp); int SearchFp(const RSXFragmentProgram& rsx_fp, GLFragmentProgram& gl_fp);
int SearchVp(const RSXVertexProgram& rsx_vp, GLVertexProgram& gl_vp); int SearchVp(const RSXVertexProgram& rsx_vp, GLVertexProgram& gl_vp);
bool CmpVP(const u32 a, const u32 b) const; bool CmpVP(const u32 a, const u32 b) const;
@ -24,6 +24,6 @@ struct GLProgramBuffer
u32 GetProg(u32 fp, u32 vp) 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 Add(GLProgram& prog, GLFragmentProgram& gl_fp, RSXFragmentProgram& rsx_fp, GLVertexProgram& gl_vp, RSXVertexProgram& rsx_vp);
void Clear(); void Clear();
}; };

View File

@ -71,14 +71,14 @@ enum
RSX_FP_OPCODE_RET = 0x45, // Return RSX_FP_OPCODE_RET = 0x45, // Return
}; };
struct RSXShaderProgram struct RSXFragmentProgram
{ {
u32 size; u32 size;
u32 addr; u32 addr;
u32 offset; u32 offset;
u32 ctrl; u32 ctrl;
RSXShaderProgram() RSXFragmentProgram()
: size(0) : size(0)
, addr(0) , addr(0)
, offset(0) , offset(0)

View File

@ -1068,12 +1068,12 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
// Shader // Shader
case NV4097_SET_SHADER_PROGRAM: case NV4097_SET_SHADER_PROGRAM:
{ {
m_cur_shader_prog = &m_shader_progs[m_cur_shader_prog_num]; m_cur_fragment_prog = &m_fragment_progs[m_cur_fragment_prog_num];
const u32 a0 = ARGS(0); const u32 a0 = ARGS(0);
m_cur_shader_prog->offset = a0 & ~0x3; m_cur_fragment_prog->offset = a0 & ~0x3;
m_cur_shader_prog->addr = GetAddress(m_cur_shader_prog->offset, (a0 & 0x3) - 1); m_cur_fragment_prog->addr = GetAddress(m_cur_fragment_prog->offset, (a0 & 0x3) - 1);
m_cur_shader_prog->ctrl = 0x40; m_cur_fragment_prog->ctrl = 0x40;
} }
break; break;
@ -2300,7 +2300,7 @@ void RSXThread::End()
m_indexed_array.Reset(); m_indexed_array.Reset();
m_fragment_constants.clear(); m_fragment_constants.clear();
m_transform_constants.clear(); m_transform_constants.clear();
m_cur_shader_prog_num = 0; m_cur_fragment_prog_num = 0;
m_clear_surface_mask = 0; m_clear_surface_mask = 0;
m_begin_end = 0; m_begin_end = 0;
@ -2476,8 +2476,8 @@ void RSXThread::Init(const u32 ioAddress, const u32 ioSize, const u32 ctrlAddres
m_local_mem_addr = localAddress; m_local_mem_addr = localAddress;
m_cur_vertex_prog = nullptr; m_cur_vertex_prog = nullptr;
m_cur_shader_prog = nullptr; m_cur_fragment_prog = nullptr;
m_cur_shader_prog_num = 0; m_cur_fragment_prog_num = 0;
m_used_gcm_commands.clear(); m_used_gcm_commands.clear();

View File

@ -115,9 +115,9 @@ public:
std::vector<RSXTransformConstant> m_fragment_constants; std::vector<RSXTransformConstant> m_fragment_constants;
std::vector<RSXTransformConstant> m_transform_constants; std::vector<RSXTransformConstant> m_transform_constants;
u32 m_shader_ctrl, m_cur_shader_prog_num; u32 m_shader_ctrl, m_cur_fragment_prog_num;
RSXShaderProgram m_shader_progs[m_fragment_count]; RSXFragmentProgram m_fragment_progs[m_fragment_count];
RSXShaderProgram* m_cur_shader_prog; RSXFragmentProgram* m_cur_fragment_prog;
RSXVertexProgram m_vertex_progs[m_vertex_count]; RSXVertexProgram m_vertex_progs[m_vertex_count];
RSXVertexProgram* m_cur_vertex_prog; RSXVertexProgram* m_cur_vertex_prog;