1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-22 18:53:28 +01:00

Merge pull request #947 from raven02/rsx

RSX : inline fragment naming & structure as vertex shader one
This commit is contained in:
Raul Tambre 2015-01-03 10:28:55 +02:00
commit 3181c566c0
9 changed files with 85 additions and 108 deletions

View File

@ -613,13 +613,13 @@ void GLFragmentDecompilerThread::Task()
m_parr.params.clear();
}
GLShaderProgram::GLShaderProgram()
GLFragmentProgram::GLFragmentProgram()
: m_decompiler_thread(nullptr)
, m_id(0)
, id(0)
{
}
GLShaderProgram::~GLShaderProgram()
GLFragmentProgram::~GLFragmentProgram()
{
if (m_decompiler_thread)
{
@ -636,7 +636,7 @@ GLShaderProgram::~GLShaderProgram()
Delete();
}
void GLShaderProgram::Wait()
void GLFragmentProgram::Wait()
{
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();
}
void GLShaderProgram::DecompileAsync(RSXShaderProgram& prog)
void GLFragmentProgram::DecompileAsync(RSXFragmentProgram& prog)
{
if (m_decompiler_thread)
{
@ -664,68 +664,68 @@ void GLShaderProgram::DecompileAsync(RSXShaderProgram& prog)
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();
}
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 int strlen = m_shader.length();
const char* str = shader.c_str();
const int strlen = shader.length();
glShaderSource(m_id, 1, &str, &strlen);
glCompileShader(m_id);
glShaderSource(id, 1, &str, &strlen);
glCompileShader(id);
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...
{
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)
{
GLsizei len;
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
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
}
}
void GLShaderProgram::Delete()
void GLFragmentProgram::Delete()
{
for (auto& param : m_parr.params) {
for (auto& param : parr.params) {
param.items.clear();
param.type.clear();
}
m_parr.params.clear();
m_shader.clear();
parr.params.clear();
shader.clear();
if (m_id)
if (id)
{
if (Emu.IsStopped())
{
LOG_WARNING(RSX, "GLShaderProgram::Delete(): glDeleteShader(%d) avoided", m_id);
LOG_WARNING(RSX, "GLFragmentProgram::Delete(): glDeleteShader(%d) avoided", id);
}
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.
* This class calls OpenGL functions and should only be used from the RSX/Graphics thread.
*/
class GLShaderProgram
class GLFragmentProgram
{
public:
GLShaderProgram();
~GLShaderProgram();
GLFragmentProgram();
~GLFragmentProgram();
GLParamArray parr;
u32 id;
std::string shader;
/**
* 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
*/
void Decompile(RSXShaderProgram& prog);
void Decompile(RSXFragmentProgram& prog);
/**
* 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.
* @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. */
void Wait();
@ -193,37 +197,10 @@ public:
/** Compile the decompiled fragment shader into a format we can use with OpenGL. */
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:
/** Threaded fragment shader decompiler responsible for decompiling this program */
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 */
void Delete();
};

View File

@ -655,7 +655,7 @@ void PostDrawObj::Initialize()
InitializeShaders();
m_fp.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();
InitializeLocations();
}
@ -746,7 +746,7 @@ void DrawCursorObj::InitializeShaders()
" gl_Position = in_pos;\n"
"}\n";
m_fp.SetShaderText(
m_fp.shader =
"#version 330\n"
"\n"
"in vec2 tc;\n"
@ -756,7 +756,7 @@ void DrawCursorObj::InitializeShaders()
"void main()\n"
"{\n"
" res = texture(tex0, tc);\n"
"}\n");
"}\n";
}
void DrawCursorObj::SetTexture(void* pixels, int width, int height)
@ -1070,7 +1070,7 @@ void GLGSRender::InitVertexData()
void GLGSRender::InitFragmentData()
{
if (!m_cur_shader_prog)
if (!m_cur_fragment_prog)
{
LOG_ERROR(RSX, "InitFragmentData: m_cur_shader_prog == NULL");
return;
@ -1078,7 +1078,7 @@ void GLGSRender::InitFragmentData()
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);
@ -1096,13 +1096,13 @@ void GLGSRender::InitFragmentData()
bool GLGSRender::LoadProgram()
{
if (!m_cur_shader_prog)
if (!m_cur_fragment_prog)
{
LOG_WARNING(RSX, "LoadProgram: m_cur_shader_prog == NULL");
return false;
}
m_cur_shader_prog->ctrl = m_shader_ctrl;
m_cur_fragment_prog->ctrl = m_shader_ctrl;
if (!m_cur_vertex_prog)
{
@ -1110,19 +1110,19 @@ bool GLGSRender::LoadProgram()
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);
if (m_fp_buf_num == -1)
{
LOG_WARNING(RSX, "FP not found in buffer!");
m_shader_prog.Decompile(*m_cur_shader_prog);
m_shader_prog.Compile();
checkForGlError("m_shader_prog.Compile");
m_fragment_prog.Decompile(*m_cur_fragment_prog);
m_fragment_prog.Compile();
checkForGlError("m_fragment_prog.Compile");
// TODO: This shouldn't use current dir
rFile f("./FragmentProgram.txt", rFile::write);
f.Write(m_shader_prog.GetShaderText());
f.Write(m_fragment_prog.shader);
}
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
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.Compile();
checkForGlError("m_vertex_prog.Compile");
m_shader_prog.Wait();
m_shader_prog.Compile();
checkForGlError("m_shader_prog.Compile");
m_fragment_prog.Wait();
m_fragment_prog.Compile();
checkForGlError("m_fragment_prog.Compile");
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);
checkForGlError("glLinkProgram");
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.fp_id = m_shader_prog.GetId();
program.fp_id = m_fragment_prog.id;
program.modified = false;
}
}
@ -1176,9 +1176,9 @@ bool GLGSRender::LoadProgram()
}
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");
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");
m_program.Use();
@ -1188,9 +1188,9 @@ bool GLGSRender::LoadProgram()
RSXDebuggerProgram program;
program.id = m_program.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.fp_shader = m_shader_prog.GetShaderText();
program.fp_shader = m_fragment_prog.shader;
m_debug_programs.push_back(program);
}
}

View File

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

View File

@ -4,14 +4,14 @@
#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)
{
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.SetShaderText(m_buf[i].fp_shader);
gl_fp.id = m_buf[i].fp_id;
gl_fp.shader = m_buf[i].fp_shader.c_str();
return i;
}
@ -85,37 +85,37 @@ u32 GLProgramBuffer::GetProg(u32 fp, u32 vp) const
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;
LOG_NOTICE(RSX, "Add program (%d):", m_buf.size());
LOG_NOTICE(RSX, "*** prog id = %d", prog.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, "*** fp data size = %d", rsx_fp.size);
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.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.vp_data = rsx_vp.data;
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);
}
void GLProgramBuffer::Clear()
{
for(u32 i=0; i<m_buf.size(); ++i)
for (u32 i = 0; i < m_buf.size(); ++i)
{
glDetachShader(m_buf[i].prog_id, m_buf[i].fp_id);
glDetachShader(m_buf[i].prog_id, m_buf[i].vp_id);

View File

@ -16,7 +16,7 @@ struct GLProgramBuffer
{
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);
bool CmpVP(const u32 a, const u32 b) const;
@ -24,6 +24,6 @@ struct GLProgramBuffer
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();
};

View File

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

View File

@ -1068,12 +1068,12 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
// Shader
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);
m_cur_shader_prog->offset = a0 & ~0x3;
m_cur_shader_prog->addr = GetAddress(m_cur_shader_prog->offset, (a0 & 0x3) - 1);
m_cur_shader_prog->ctrl = 0x40;
m_cur_fragment_prog->offset = a0 & ~0x3;
m_cur_fragment_prog->addr = GetAddress(m_cur_fragment_prog->offset, (a0 & 0x3) - 1);
m_cur_fragment_prog->ctrl = 0x40;
}
break;
@ -2300,7 +2300,7 @@ void RSXThread::End()
m_indexed_array.Reset();
m_fragment_constants.clear();
m_transform_constants.clear();
m_cur_shader_prog_num = 0;
m_cur_fragment_prog_num = 0;
m_clear_surface_mask = 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_cur_vertex_prog = nullptr;
m_cur_shader_prog = nullptr;
m_cur_shader_prog_num = 0;
m_cur_fragment_prog = nullptr;
m_cur_fragment_prog_num = 0;
m_used_gcm_commands.clear();

View File

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