mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-06 00:59:18 +00:00
RSX : add ClearColor() / ClearStencil() / ClearDepth() / ClearSurface()
This commit is contained in:
parent
325dd0308b
commit
1b87f9312b
@ -29,7 +29,7 @@ int last_width = 0, last_height = 0, last_depth_format = 0;
|
||||
GLenum g_last_gl_error = GL_NO_ERROR;
|
||||
void printGlError(GLenum err, const char* situation)
|
||||
{
|
||||
if(err != GL_NO_ERROR)
|
||||
if (err != GL_NO_ERROR)
|
||||
{
|
||||
LOG_ERROR(RSX, "%s: opengl error 0x%04x", situation, err);
|
||||
Emu.Pause();
|
||||
@ -98,7 +98,9 @@ float GLTexture::GetMaxAniso(int aniso)
|
||||
void GLTexture::Init(RSXTexture& tex)
|
||||
{
|
||||
if (tex.GetLocation() > 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Bind();
|
||||
|
||||
@ -108,8 +110,9 @@ void GLTexture::Init(RSXTexture& tex)
|
||||
LOG_ERROR(RSX, "Bad texture address=0x%x", texaddr);
|
||||
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",
|
||||
//lOG_WARNING(RSX, "texture addr = 0x%x, width = %d, height = %d, max_aniso=%d, mipmap=%d, remap=0x%x, zfunc=0x%x, wraps=0x%x, wrapt=0x%x, wrapr=0x%x, minlod=0x%x, maxlod=0x%x",
|
||||
// m_offset, m_width, m_height, m_maxaniso, m_mipmap, m_remap, m_zfunc, m_wraps, m_wrapt, m_wrapr, m_minlod, m_maxlod);
|
||||
|
||||
//TODO: safe init
|
||||
checkForGlError("GLTexture::Init() -> glBindTexture");
|
||||
|
||||
@ -184,9 +187,9 @@ void GLTexture::Init(RSXTexture& tex)
|
||||
log2width = log(tex.GetWidth()) / log(2);
|
||||
log2height = log(tex.GetHeight()) / log(2);
|
||||
|
||||
for (int i = 0; i<tex.GetHeight(); i++)
|
||||
for (int i = 0; i < tex.GetHeight(); i++)
|
||||
{
|
||||
for (int j = 0; j<tex.GetWidth(); j++)
|
||||
for (int j = 0; j < tex.GetWidth(); j++)
|
||||
{
|
||||
dst[(i*tex.GetHeight()) + j] = src[LinearToSwizzleAddress(j, i, 0, log2width, log2height, 0)];
|
||||
}
|
||||
@ -452,8 +455,7 @@ void GLTexture::Init(RSXTexture& tex)
|
||||
}
|
||||
break;
|
||||
|
||||
default: LOG_ERROR(RSX, "Init tex error: Bad tex format (0x%x | %s | 0x%x)", format,
|
||||
(is_swizzled ? "swizzled" : "linear"), tex.GetFormat() & 0x40);
|
||||
default: LOG_ERROR(RSX, "Init tex error: Bad tex format (0x%x | %s | 0x%x)", format, (is_swizzled ? "swizzled" : "linear"), tex.GetFormat() & 0x40);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -693,8 +695,6 @@ void DrawCursorObj::Draw()
|
||||
|
||||
if (m_update_texture)
|
||||
{
|
||||
//m_update_texture = false;
|
||||
|
||||
glUniform2f(m_program.GetLocation("in_tc"), m_width, m_height);
|
||||
checkForGlError("DrawCursorObj : glUniform2f");
|
||||
if (!m_tex_id)
|
||||
@ -714,8 +714,6 @@ void DrawCursorObj::Draw()
|
||||
|
||||
if (m_update_pos)
|
||||
{
|
||||
//m_update_pos = false;
|
||||
|
||||
glUniform4f(m_program.GetLocation("in_pos"), m_pos_x, m_pos_y, m_pos_z, 1.0f);
|
||||
checkForGlError("DrawCursorObj : glUniform4f");
|
||||
}
|
||||
@ -727,10 +725,7 @@ void DrawCursorObj::Draw()
|
||||
checkForGlError("DrawCursorObj : m_fbo.Bind(GL_READ_FRAMEBUFFER)");
|
||||
GLfbo::Bind(GL_DRAW_FRAMEBUFFER, 0);
|
||||
checkForGlError("DrawCursorObj : GLfbo::Bind(GL_DRAW_FRAMEBUFFER, 0)");
|
||||
GLfbo::Blit(
|
||||
0, 0, m_width, m_height,
|
||||
0, 0, m_width, m_height,
|
||||
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
GLfbo::Blit(0, 0, m_width, m_height, 0, 0, m_width, m_height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
checkForGlError("DrawCursorObj : GLfbo::Blit");
|
||||
m_fbo.Bind();
|
||||
checkForGlError("DrawCursorObj : m_fbo.Bind");
|
||||
@ -783,7 +778,7 @@ void DrawCursorObj::SetPosition(float x, float y, float z)
|
||||
|
||||
void DrawCursorObj::InitializeLocations()
|
||||
{
|
||||
//ConLog.Warning("tex0 location = 0x%x", m_program.GetLocation("tex0"));
|
||||
//LOG_WARNING(RSX, "tex0 location = 0x%x", m_program.GetLocation("tex0"));
|
||||
}
|
||||
|
||||
GLGSRender::GLGSRender()
|
||||
@ -804,7 +799,7 @@ GLGSRender::~GLGSRender()
|
||||
|
||||
void GLGSRender::Enable(bool enable, const u32 cap)
|
||||
{
|
||||
if(enable)
|
||||
if (enable)
|
||||
{
|
||||
glEnable(cap);
|
||||
}
|
||||
@ -820,7 +815,10 @@ void GLGSRender::Close()
|
||||
{
|
||||
Stop();
|
||||
|
||||
if(m_frame->IsShown()) m_frame->Hide();
|
||||
if (m_frame->IsShown())
|
||||
{
|
||||
m_frame->Hide();
|
||||
}
|
||||
m_ctrl = nullptr;
|
||||
}
|
||||
|
||||
@ -831,7 +829,7 @@ void GLGSRender::EnableVertexData(bool indexed_draw)
|
||||
|
||||
const u32 data_offset = indexed_draw ? 0 : m_draw_array_first;
|
||||
|
||||
for(u32 i=0; i<m_vertex_count; ++i)
|
||||
for (u32 i = 0; i < m_vertex_count; ++i)
|
||||
{
|
||||
if (0)
|
||||
{
|
||||
@ -880,7 +878,7 @@ void GLGSRender::EnableVertexData(bool indexed_draw)
|
||||
m_vbo.Bind(0);
|
||||
m_vbo.SetData(m_vdata.data(), m_vdata.size());
|
||||
|
||||
if(indexed_draw)
|
||||
if (indexed_draw)
|
||||
{
|
||||
m_vbo.Bind(GL_ELEMENT_ARRAY_BUFFER, 1);
|
||||
m_vbo.SetData(GL_ELEMENT_ARRAY_BUFFER, m_indexed_array.m_data.data(), m_indexed_array.m_data.size());
|
||||
@ -892,61 +890,61 @@ void GLGSRender::EnableVertexData(bool indexed_draw)
|
||||
rFile dump("VertexDataArray.dump", rFile::write);
|
||||
#endif
|
||||
|
||||
for(u32 i=0; i<m_vertex_count; ++i)
|
||||
for (u32 i = 0; i < m_vertex_count; ++i)
|
||||
{
|
||||
if(!m_vertex_data[i].IsEnabled()) continue;
|
||||
if (!m_vertex_data[i].IsEnabled()) continue;
|
||||
|
||||
#if DUMP_VERTEX_DATA
|
||||
dump.Write(wxString::Format("VertexData[%d]:\n", i));
|
||||
switch(m_vertex_data[i].type)
|
||||
switch (m_vertex_data[i].type)
|
||||
{
|
||||
case CELL_GCM_VERTEX_S1:
|
||||
for(u32 j = 0; j<m_vertex_data[i].data.size(); j+=2)
|
||||
for (u32 j = 0; j < m_vertex_data[i].data.size(); j+=2)
|
||||
{
|
||||
dump.Write(wxString::Format("%d\n", *(u16*)&m_vertex_data[i].data[j]));
|
||||
if(!(((j+2) / 2) % m_vertex_data[i].size)) dump.Write("\n");
|
||||
if (!(((j+2) / 2) % m_vertex_data[i].size)) dump.Write("\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case CELL_GCM_VERTEX_F:
|
||||
for(u32 j = 0; j<m_vertex_data[i].data.size(); j+=4)
|
||||
for (u32 j = 0; j < m_vertex_data[i].data.size(); j+=4)
|
||||
{
|
||||
dump.Write(wxString::Format("%.01f\n", *(float*)&m_vertex_data[i].data[j]));
|
||||
if(!(((j+4) / 4) % m_vertex_data[i].size)) dump.Write("\n");
|
||||
if (!(((j+4) / 4) % m_vertex_data[i].size)) dump.Write("\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case CELL_GCM_VERTEX_SF:
|
||||
for(u32 j = 0; j<m_vertex_data[i].data.size(); j+=2)
|
||||
for (u32 j = 0; j < m_vertex_data[i].data.size(); j+=2)
|
||||
{
|
||||
dump.Write(wxString::Format("%.01f\n", *(float*)&m_vertex_data[i].data[j]));
|
||||
if(!(((j+2) / 2) % m_vertex_data[i].size)) dump.Write("\n");
|
||||
if (!(((j+2) / 2) % m_vertex_data[i].size)) dump.Write("\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case CELL_GCM_VERTEX_UB:
|
||||
for(u32 j = 0; j<m_vertex_data[i].data.size(); ++j)
|
||||
for (u32 j = 0; j < m_vertex_data[i].data.size(); ++j)
|
||||
{
|
||||
dump.Write(wxString::Format("%d\n", m_vertex_data[i].data[j]));
|
||||
if(!((j+1) % m_vertex_data[i].size)) dump.Write("\n");
|
||||
if (!((j+1) % m_vertex_data[i].size)) dump.Write("\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case CELL_GCM_VERTEX_S32K:
|
||||
for(u32 j = 0; j<m_vertex_data[i].data.size(); j+=2)
|
||||
for (u32 j = 0; j < m_vertex_data[i].data.size(); j+=2)
|
||||
{
|
||||
dump.Write(wxString::Format("%d\n", *(u16*)&m_vertex_data[i].data[j]));
|
||||
if(!(((j+2) / 2) % m_vertex_data[i].size)) dump.Write("\n");
|
||||
if (!(((j+2) / 2) % m_vertex_data[i].size)) dump.Write("\n");
|
||||
}
|
||||
break;
|
||||
|
||||
// case CELL_GCM_VERTEX_CMP:
|
||||
|
||||
case CELL_GCM_VERTEX_UB256:
|
||||
for(u32 j = 0; j<m_vertex_data[i].data.size(); ++j)
|
||||
for (u32 j = 0; j < m_vertex_data[i].data.size(); ++j)
|
||||
{
|
||||
dump.Write(wxString::Format("%d\n", m_vertex_data[i].data[j]));
|
||||
if(!((j+1) % m_vertex_data[i].size)) dump.Write("\n");
|
||||
if (!((j+1) % m_vertex_data[i].size)) dump.Write("\n");
|
||||
}
|
||||
break;
|
||||
|
||||
@ -980,13 +978,14 @@ void GLGSRender::EnableVertexData(bool indexed_draw)
|
||||
GL_FALSE,
|
||||
};
|
||||
|
||||
if (m_vertex_data[i].type < 1 || m_vertex_data[i].type > 7) {
|
||||
if (m_vertex_data[i].type < 1 || m_vertex_data[i].type > 7)
|
||||
{
|
||||
LOG_ERROR(RSX, "GLGSRender::EnableVertexData: Bad vertex data type (%d)!", m_vertex_data[i].type);
|
||||
}
|
||||
|
||||
if(!m_vertex_data[i].addr)
|
||||
if (!m_vertex_data[i].addr)
|
||||
{
|
||||
switch(m_vertex_data[i].type)
|
||||
switch (m_vertex_data[i].type)
|
||||
{
|
||||
case CELL_GCM_VERTEX_S32K:
|
||||
case CELL_GCM_VERTEX_S1:
|
||||
@ -1000,7 +999,7 @@ void GLGSRender::EnableVertexData(bool indexed_draw)
|
||||
break;
|
||||
|
||||
case CELL_GCM_VERTEX_F:
|
||||
switch(m_vertex_data[i].size)
|
||||
switch (m_vertex_data[i].size)
|
||||
{
|
||||
case 1: glVertexAttrib1f(i, (GLfloat&)m_vertex_data[i].data[0]); break;
|
||||
case 2: glVertexAttrib2fv(i, (GLfloat*)&m_vertex_data[i].data[0]); break;
|
||||
@ -1033,9 +1032,9 @@ void GLGSRender::EnableVertexData(bool indexed_draw)
|
||||
void GLGSRender::DisableVertexData()
|
||||
{
|
||||
m_vdata.clear();
|
||||
for(u32 i=0; i<m_vertex_count; ++i)
|
||||
for (u32 i = 0; i < m_vertex_count; ++i)
|
||||
{
|
||||
if(!m_vertex_data[i].IsEnabled()) continue;
|
||||
if (!m_vertex_data[i].IsEnabled()) continue;
|
||||
glDisableVertexAttribArray(i);
|
||||
checkForGlError("glDisableVertexAttribArray");
|
||||
}
|
||||
@ -1059,7 +1058,6 @@ void GLGSRender::InitVertexData()
|
||||
l = m_program.GetLocation(name);
|
||||
checkForGlError("glGetUniformLocation " + name);
|
||||
|
||||
//ConLog.Write(name + " x: %.02f y: %.02f z: %.02f w: %.02f", c.x, c.y, c.z, c.w);
|
||||
glUniform4f(l, c.x, c.y, c.z, c.w);
|
||||
checkForGlError("glUniform4f " + name + fmt::Format(" %d [%f %f %f %f]", l, c.x, c.y, c.z, c.w));
|
||||
}
|
||||
@ -1084,13 +1082,14 @@ void GLGSRender::InitVertexData()
|
||||
|
||||
void GLGSRender::InitFragmentData()
|
||||
{
|
||||
if(!m_cur_shader_prog)
|
||||
if (!m_cur_shader_prog)
|
||||
{
|
||||
LOG_ERROR(RSX, "InitFragmentData: m_cur_shader_prog == NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
for(const RSXTransformConstant& c : m_fragment_constants) {
|
||||
for (const RSXTransformConstant& c : m_fragment_constants)
|
||||
{
|
||||
u32 id = c.id - m_cur_shader_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);
|
||||
@ -1103,13 +1102,13 @@ void GLGSRender::InitFragmentData()
|
||||
checkForGlError("glUniform4f " + name + fmt::Format(" %u [%f %f %f %f]", l, c.x, c.y, c.z, c.w));
|
||||
}
|
||||
|
||||
//if(m_fragment_constants.GetCount())
|
||||
//if (m_fragment_constants.GetCount())
|
||||
// LOG_NOTICE(HLE, "");
|
||||
}
|
||||
|
||||
bool GLGSRender::LoadProgram()
|
||||
{
|
||||
if(!m_cur_shader_prog)
|
||||
if (!m_cur_shader_prog)
|
||||
{
|
||||
LOG_WARNING(RSX, "LoadProgram: m_cur_shader_prog == NULL");
|
||||
return false;
|
||||
@ -1117,7 +1116,7 @@ bool GLGSRender::LoadProgram()
|
||||
|
||||
m_cur_shader_prog->ctrl = m_shader_ctrl;
|
||||
|
||||
if(!m_cur_vertex_prog)
|
||||
if (!m_cur_vertex_prog)
|
||||
{
|
||||
LOG_WARNING(RSX, "LoadProgram: m_cur_vertex_prog == NULL");
|
||||
return false;
|
||||
@ -1126,13 +1125,9 @@ bool GLGSRender::LoadProgram()
|
||||
m_fp_buf_num = m_prog_buffer.SearchFp(*m_cur_shader_prog, m_shader_prog);
|
||||
m_vp_buf_num = m_prog_buffer.SearchVp(*m_cur_vertex_prog, m_vertex_prog);
|
||||
|
||||
//ConLog.Write("Create program");
|
||||
|
||||
if(m_fp_buf_num == -1)
|
||||
if (m_fp_buf_num == -1)
|
||||
{
|
||||
LOG_WARNING(RSX, "FP not found in buffer!");
|
||||
//m_shader_prog.DecompileAsync(*m_cur_shader_prog);
|
||||
//m_shader_prog.Wait();
|
||||
m_shader_prog.Decompile(*m_cur_shader_prog);
|
||||
m_shader_prog.Compile();
|
||||
checkForGlError("m_shader_prog.Compile");
|
||||
@ -1142,11 +1137,9 @@ bool GLGSRender::LoadProgram()
|
||||
f.Write(m_shader_prog.GetShaderText());
|
||||
}
|
||||
|
||||
if(m_vp_buf_num == -1)
|
||||
if (m_vp_buf_num == -1)
|
||||
{
|
||||
LOG_WARNING(RSX, "VP not found in buffer!");
|
||||
//m_vertex_prog.DecompileAsync(*m_cur_vertex_prog);
|
||||
//m_vertex_prog.Wait();
|
||||
m_vertex_prog.Decompile(*m_cur_vertex_prog);
|
||||
m_vertex_prog.Compile();
|
||||
checkForGlError("m_vertex_prog.Compile");
|
||||
@ -1156,17 +1149,17 @@ bool GLGSRender::LoadProgram()
|
||||
f.Write(m_vertex_prog.shader);
|
||||
}
|
||||
|
||||
if(m_fp_buf_num != -1 && m_vp_buf_num != -1)
|
||||
if (m_fp_buf_num != -1 && m_vp_buf_num != -1)
|
||||
{
|
||||
m_program.id = m_prog_buffer.GetProg(m_fp_buf_num, m_vp_buf_num);
|
||||
}
|
||||
|
||||
if(m_program.id)
|
||||
if (m_program.id)
|
||||
{
|
||||
// RSX Debugger: Check if this program was modified and update it
|
||||
if (Ini.GSLogPrograms.GetValue())
|
||||
{
|
||||
for(auto& program : m_debug_programs)
|
||||
for (auto& program : m_debug_programs)
|
||||
{
|
||||
if (program.id == m_program.id && program.modified)
|
||||
{
|
||||
@ -1490,11 +1483,6 @@ void GLGSRender::OnInitThread()
|
||||
|
||||
#ifdef _WIN32
|
||||
glSwapInterval(Ini.GSVSyncEnable.GetValue() ? 1 : 0);
|
||||
// Undefined reference: glXSwapIntervalEXT
|
||||
/*#else
|
||||
if (GLXDrawable drawable = glXGetCurrentDrawable()){
|
||||
glXSwapIntervalEXT(glXGetCurrentDisplay(), drawable, Ini.GSVSyncEnable.GetValue() ? 1 : 0);
|
||||
}*/
|
||||
#endif
|
||||
|
||||
}
|
||||
@ -1520,10 +1508,7 @@ void GLGSRender::OnReset()
|
||||
{
|
||||
m_program.UnUse();
|
||||
|
||||
//m_shader_prog.id = 0;
|
||||
//m_vertex_prog.id = 0;
|
||||
|
||||
if(m_vbo.IsCreated())
|
||||
if (m_vbo.IsCreated())
|
||||
{
|
||||
m_vbo.UnBind();
|
||||
m_vbo.Delete();
|
||||
@ -1534,7 +1519,7 @@ void GLGSRender::OnReset()
|
||||
|
||||
void GLGSRender::InitDrawBuffers()
|
||||
{
|
||||
if(!m_fbo.IsCreated() || RSXThread::m_width != last_width || RSXThread::m_height != last_height || last_depth_format != m_surface_depth_format)
|
||||
if (!m_fbo.IsCreated() || RSXThread::m_width != last_width || RSXThread::m_height != last_height || last_depth_format != m_surface_depth_format)
|
||||
{
|
||||
LOG_WARNING(RSX, "New FBO (%dx%d)", RSXThread::m_width, RSXThread::m_height);
|
||||
last_width = RSXThread::m_width;
|
||||
@ -1548,7 +1533,7 @@ void GLGSRender::InitDrawBuffers()
|
||||
m_rbo.Create(4 + 1);
|
||||
checkForGlError("m_rbo.Create");
|
||||
|
||||
for(int i=0; i<4; ++i)
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
m_rbo.Bind(i);
|
||||
m_rbo.Storage(GL_RGBA, RSXThread::m_width, RSXThread::m_height);
|
||||
@ -1557,17 +1542,8 @@ void GLGSRender::InitDrawBuffers()
|
||||
|
||||
m_rbo.Bind(4);
|
||||
|
||||
switch(m_surface_depth_format)
|
||||
switch (m_surface_depth_format)
|
||||
{
|
||||
// case 0 found in BLJM60410-[Suzukaze no Melt - Days in the Sanctuary]
|
||||
// [E : RSXThread]: Bad depth format! (0)
|
||||
// [E : RSXThread]: glEnable: opengl error 0x0506
|
||||
// [E : RSXThread]: glDrawArrays: opengl error 0x0506
|
||||
case 0:
|
||||
m_rbo.Storage(GL_DEPTH_COMPONENT, RSXThread::m_width, RSXThread::m_height);
|
||||
checkForGlError("m_rbo.Storage(GL_DEPTH_COMPONENT)");
|
||||
break;
|
||||
|
||||
case CELL_GCM_SURFACE_Z16:
|
||||
m_rbo.Storage(GL_DEPTH_COMPONENT16, RSXThread::m_width, RSXThread::m_height);
|
||||
checkForGlError("m_rbo.Storage(GL_DEPTH_COMPONENT16)");
|
||||
@ -1584,7 +1560,7 @@ void GLGSRender::InitDrawBuffers()
|
||||
break;
|
||||
}
|
||||
|
||||
for(int i=0; i<4; ++i)
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
m_fbo.Renderbuffer(GL_COLOR_ATTACHMENT0 + i, m_rbo.GetId(i));
|
||||
checkForGlError(fmt::Format("m_fbo.Renderbuffer(GL_COLOR_ATTACHMENT%d)", i));
|
||||
@ -1593,20 +1569,20 @@ void GLGSRender::InitDrawBuffers()
|
||||
m_fbo.Renderbuffer(GL_DEPTH_ATTACHMENT, m_rbo.GetId(4));
|
||||
checkForGlError("m_fbo.Renderbuffer(GL_DEPTH_ATTACHMENT)");
|
||||
|
||||
if(m_surface_depth_format == 2)
|
||||
if (m_surface_depth_format == 2)
|
||||
{
|
||||
m_fbo.Renderbuffer(GL_STENCIL_ATTACHMENT, m_rbo.GetId(4));
|
||||
checkForGlError("m_fbo.Renderbuffer(GL_STENCIL_ATTACHMENT)");
|
||||
}
|
||||
}
|
||||
|
||||
if(!m_set_surface_clip_horizontal)
|
||||
if (!m_set_surface_clip_horizontal)
|
||||
{
|
||||
m_surface_clip_x = 0;
|
||||
m_surface_clip_w = RSXThread::m_width;
|
||||
}
|
||||
|
||||
if(!m_set_surface_clip_vertical)
|
||||
if (!m_set_surface_clip_vertical)
|
||||
{
|
||||
m_surface_clip_y = 0;
|
||||
m_surface_clip_h = RSXThread::m_height;
|
||||
@ -1664,64 +1640,48 @@ void GLGSRender::InitDrawBuffers()
|
||||
}
|
||||
}
|
||||
|
||||
void GLGSRender::ExecCMD(u32 cmd)
|
||||
void GLGSRender::ClearColor(u32 a, u32 r, u32 g, u32 b)
|
||||
{
|
||||
glClearColor(r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f);
|
||||
checkForGlError("glClearColor");
|
||||
}
|
||||
|
||||
void GLGSRender::ClearStencil(u32 stencil)
|
||||
{
|
||||
glClearStencil(stencil);
|
||||
checkForGlError("glClearStencil");
|
||||
}
|
||||
|
||||
void GLGSRender::ClearDepth(u32 depth)
|
||||
{
|
||||
glClearDepth(depth / (float)0xffffff);
|
||||
checkForGlError("glClearDepth");
|
||||
}
|
||||
|
||||
void GLGSRender::ClearSurface(u32 mask)
|
||||
{
|
||||
assert(cmd == NV4097_CLEAR_SURFACE);
|
||||
|
||||
InitDrawBuffers();
|
||||
|
||||
if(m_set_color_mask)
|
||||
{
|
||||
glColorMask(m_color_mask_r, m_color_mask_g, m_color_mask_b, m_color_mask_a);
|
||||
checkForGlError("glColorMask");
|
||||
}
|
||||
|
||||
if (m_set_scissor_horizontal && m_set_scissor_vertical)
|
||||
{
|
||||
glScissor(m_scissor_x, m_scissor_y, m_scissor_w, m_scissor_h);
|
||||
checkForGlError("glScissor");
|
||||
}
|
||||
|
||||
GLbitfield f = 0;
|
||||
|
||||
if (m_clear_surface_mask & 0x1)
|
||||
{
|
||||
glClearDepth(m_clear_surface_z / (float)0xffffff);
|
||||
checkForGlError("glClearDepth");
|
||||
|
||||
f |= GL_DEPTH_BUFFER_BIT;
|
||||
}
|
||||
|
||||
if (m_clear_surface_mask & 0x2)
|
||||
{
|
||||
glClearStencil(m_clear_surface_s);
|
||||
checkForGlError("glClearStencil");
|
||||
|
||||
f |= GL_STENCIL_BUFFER_BIT;
|
||||
}
|
||||
|
||||
if (m_clear_surface_mask & 0xF0)
|
||||
{
|
||||
glClearColor(
|
||||
m_clear_surface_color_r / 255.0f,
|
||||
m_clear_surface_color_g / 255.0f,
|
||||
m_clear_surface_color_b / 255.0f,
|
||||
m_clear_surface_color_a / 255.0f);
|
||||
checkForGlError("glClearColor");
|
||||
|
||||
f |= GL_COLOR_BUFFER_BIT;
|
||||
}
|
||||
|
||||
glClear(f);
|
||||
checkForGlError("glClear");
|
||||
GLbitfield clearMask = 0;
|
||||
if (mask & 0x01) clearMask |= GL_DEPTH_BUFFER_BIT;
|
||||
if (mask & 0x02) clearMask |= GL_STENCIL_BUFFER_BIT;
|
||||
if (mask & 0xF0) clearMask |= GL_COLOR_BUFFER_BIT;
|
||||
|
||||
glClear(clearMask);
|
||||
checkForGlError("glClear");
|
||||
|
||||
WriteBuffers();
|
||||
}
|
||||
|
||||
void GLGSRender::ColorMask(bool a, bool r, bool g, bool b)
|
||||
{
|
||||
glColorMask(r, g, b, a);
|
||||
checkForGlError("glColorMask");
|
||||
}
|
||||
|
||||
void GLGSRender::ExecCMD()
|
||||
{
|
||||
//return;
|
||||
if(!LoadProgram())
|
||||
if (!LoadProgram())
|
||||
{
|
||||
LOG_ERROR(RSX, "LoadProgram failed.");
|
||||
Emu.Pause();
|
||||
@ -1730,12 +1690,6 @@ void GLGSRender::ExecCMD()
|
||||
|
||||
InitDrawBuffers();
|
||||
|
||||
if (m_set_color_mask)
|
||||
{
|
||||
glColorMask(m_color_mask_r, m_color_mask_g, m_color_mask_b, m_color_mask_a);
|
||||
checkForGlError("glColorMask");
|
||||
}
|
||||
|
||||
Enable(m_set_depth_test, GL_DEPTH_TEST);
|
||||
Enable(m_set_alpha_test, GL_ALPHA_TEST);
|
||||
Enable(m_set_depth_bounds_test, GL_DEPTH_BOUNDS_TEST_EXT);
|
||||
@ -1756,7 +1710,7 @@ void GLGSRender::ExecCMD()
|
||||
Enable(m_set_line_stipple, GL_LINE_STIPPLE);
|
||||
Enable(m_set_polygon_stipple, GL_POLYGON_STIPPLE);
|
||||
|
||||
if(m_set_clip_plane)
|
||||
if (m_set_clip_plane)
|
||||
{
|
||||
Enable(m_clip_plane_0, GL_CLIP_PLANE0);
|
||||
Enable(m_clip_plane_1, GL_CLIP_PLANE1);
|
||||
@ -1806,39 +1760,39 @@ void GLGSRender::ExecCMD()
|
||||
checkForGlError("glScissor");
|
||||
}
|
||||
|
||||
if(m_set_two_sided_stencil_test_enable)
|
||||
if (m_set_two_sided_stencil_test_enable)
|
||||
{
|
||||
if(m_set_stencil_fail && m_set_stencil_zfail && m_set_stencil_zpass)
|
||||
if (m_set_stencil_fail && m_set_stencil_zfail && m_set_stencil_zpass)
|
||||
{
|
||||
glStencilOpSeparate(GL_FRONT, m_stencil_fail, m_stencil_zfail, m_stencil_zpass);
|
||||
checkForGlError("glStencilOpSeparate");
|
||||
}
|
||||
|
||||
if(m_set_stencil_mask)
|
||||
if (m_set_stencil_mask)
|
||||
{
|
||||
glStencilMaskSeparate(GL_FRONT, m_stencil_mask);
|
||||
checkForGlError("glStencilMaskSeparate");
|
||||
}
|
||||
|
||||
if(m_set_stencil_func && m_set_stencil_func_ref && m_set_stencil_func_mask)
|
||||
if (m_set_stencil_func && m_set_stencil_func_ref && m_set_stencil_func_mask)
|
||||
{
|
||||
glStencilFuncSeparate(GL_FRONT, m_stencil_func, m_stencil_func_ref, m_stencil_func_mask);
|
||||
checkForGlError("glStencilFuncSeparate");
|
||||
}
|
||||
|
||||
if(m_set_back_stencil_fail && m_set_back_stencil_zfail && m_set_back_stencil_zpass)
|
||||
if (m_set_back_stencil_fail && m_set_back_stencil_zfail && m_set_back_stencil_zpass)
|
||||
{
|
||||
glStencilOpSeparate(GL_BACK, m_back_stencil_fail, m_back_stencil_zfail, m_back_stencil_zpass);
|
||||
checkForGlError("glStencilOpSeparate(GL_BACK)");
|
||||
}
|
||||
|
||||
if(m_set_back_stencil_mask)
|
||||
if (m_set_back_stencil_mask)
|
||||
{
|
||||
glStencilMaskSeparate(GL_BACK, m_back_stencil_mask);
|
||||
checkForGlError("glStencilMaskSeparate(GL_BACK)");
|
||||
}
|
||||
|
||||
if(m_set_back_stencil_func && m_set_back_stencil_func_ref && m_set_back_stencil_func_mask)
|
||||
if (m_set_back_stencil_func && m_set_back_stencil_func_ref && m_set_back_stencil_func_mask)
|
||||
{
|
||||
glStencilFuncSeparate(GL_BACK, m_back_stencil_func, m_back_stencil_func_ref, m_back_stencil_func_mask);
|
||||
checkForGlError("glStencilFuncSeparate(GL_BACK)");
|
||||
@ -1846,60 +1800,62 @@ void GLGSRender::ExecCMD()
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_set_stencil_fail && m_set_stencil_zfail && m_set_stencil_zpass)
|
||||
if (m_set_stencil_fail && m_set_stencil_zfail && m_set_stencil_zpass)
|
||||
{
|
||||
glStencilOp(m_stencil_fail, m_stencil_zfail, m_stencil_zpass);
|
||||
checkForGlError("glStencilOp");
|
||||
}
|
||||
|
||||
if(m_set_stencil_mask)
|
||||
if (m_set_stencil_mask)
|
||||
{
|
||||
glStencilMask(m_stencil_mask);
|
||||
checkForGlError("glStencilMask");
|
||||
}
|
||||
|
||||
if(m_set_stencil_func && m_set_stencil_func_ref && m_set_stencil_func_mask)
|
||||
if (m_set_stencil_func && m_set_stencil_func_ref && m_set_stencil_func_mask)
|
||||
{
|
||||
glStencilFunc(m_stencil_func, m_stencil_func_ref, m_stencil_func_mask);
|
||||
checkForGlError("glStencilFunc");
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Use other glLightModel functions?
|
||||
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, m_set_two_side_light_enable ? GL_TRUE : GL_FALSE);
|
||||
checkForGlError("glLightModeli");
|
||||
if (m_set_two_side_light_enable)
|
||||
{
|
||||
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
|
||||
checkForGlError("glLightModeli");
|
||||
}
|
||||
|
||||
if(m_set_shade_mode)
|
||||
if (m_set_shade_mode)
|
||||
{
|
||||
glShadeModel(m_shade_mode);
|
||||
checkForGlError("glShadeModel");
|
||||
}
|
||||
|
||||
if(m_set_depth_mask)
|
||||
if (m_set_depth_mask)
|
||||
{
|
||||
glDepthMask(m_depth_mask);
|
||||
checkForGlError("glDepthMask");
|
||||
}
|
||||
|
||||
if(m_set_depth_func)
|
||||
if (m_set_depth_func)
|
||||
{
|
||||
glDepthFunc(m_depth_func);
|
||||
checkForGlError("glDepthFunc");
|
||||
}
|
||||
|
||||
if(m_set_depth_bounds)
|
||||
if (m_set_depth_bounds)
|
||||
{
|
||||
glDepthBoundsEXT(m_depth_bounds_min, m_depth_bounds_max);
|
||||
checkForGlError("glDepthBounds");
|
||||
}
|
||||
|
||||
if(m_set_clip)
|
||||
if (m_set_clip)
|
||||
{
|
||||
glDepthRangef(m_clip_min, m_clip_max);
|
||||
checkForGlError("glDepthRangef");
|
||||
}
|
||||
|
||||
if(m_set_line_width)
|
||||
if (m_set_line_width)
|
||||
{
|
||||
glLineWidth(m_line_width);
|
||||
checkForGlError("glLineWidth");
|
||||
@ -1917,25 +1873,25 @@ void GLGSRender::ExecCMD()
|
||||
checkForGlError("glPolygonStipple");
|
||||
}
|
||||
|
||||
if(m_set_blend_equation)
|
||||
if (m_set_blend_equation)
|
||||
{
|
||||
glBlendEquationSeparate(m_blend_equation_rgb, m_blend_equation_alpha);
|
||||
checkForGlError("glBlendEquationSeparate");
|
||||
}
|
||||
|
||||
if(m_set_blend_sfactor && m_set_blend_dfactor)
|
||||
if (m_set_blend_sfactor && m_set_blend_dfactor)
|
||||
{
|
||||
glBlendFuncSeparate(m_blend_sfactor_rgb, m_blend_dfactor_rgb, m_blend_sfactor_alpha, m_blend_dfactor_alpha);
|
||||
checkForGlError("glBlendFuncSeparate");
|
||||
}
|
||||
|
||||
if(m_set_blend_color)
|
||||
if (m_set_blend_color)
|
||||
{
|
||||
glBlendColor(m_blend_color_r, m_blend_color_g, m_blend_color_b, m_blend_color_a);
|
||||
checkForGlError("glBlendColor");
|
||||
}
|
||||
|
||||
if(m_set_cull_face)
|
||||
if (m_set_cull_face)
|
||||
{
|
||||
glCullFace(m_cull_face);
|
||||
checkForGlError("glCullFace");
|
||||
@ -1947,19 +1903,19 @@ void GLGSRender::ExecCMD()
|
||||
checkForGlError("glFrontFace");
|
||||
}
|
||||
|
||||
if(m_set_alpha_func && m_set_alpha_ref)
|
||||
if (m_set_alpha_func && m_set_alpha_ref)
|
||||
{
|
||||
glAlphaFunc(m_alpha_func, m_alpha_ref);
|
||||
checkForGlError("glAlphaFunc");
|
||||
}
|
||||
|
||||
if(m_set_fog_mode)
|
||||
if (m_set_fog_mode)
|
||||
{
|
||||
glFogi(GL_FOG_MODE, m_fog_mode);
|
||||
checkForGlError("glFogi(GL_FOG_MODE)");
|
||||
}
|
||||
|
||||
if(m_set_fog_params)
|
||||
if (m_set_fog_params)
|
||||
{
|
||||
glFogf(GL_FOG_START, m_fog_param0);
|
||||
checkForGlError("glFogf(GL_FOG_START)");
|
||||
@ -1967,20 +1923,20 @@ void GLGSRender::ExecCMD()
|
||||
checkForGlError("glFogf(GL_FOG_END)");
|
||||
}
|
||||
|
||||
if(m_set_restart_index)
|
||||
if (m_set_restart_index)
|
||||
{
|
||||
glPrimitiveRestartIndex(m_restart_index);
|
||||
checkForGlError("glPrimitiveRestartIndex");
|
||||
}
|
||||
|
||||
if(m_indexed_array.m_count && m_draw_array_count)
|
||||
if (m_indexed_array.m_count && m_draw_array_count)
|
||||
{
|
||||
LOG_WARNING(RSX, "m_indexed_array.m_count && draw_array_count");
|
||||
}
|
||||
|
||||
for(u32 i=0; i<m_textures_count; ++i)
|
||||
for (u32 i=0; i < m_textures_count; ++i)
|
||||
{
|
||||
if(!m_textures[i].IsEnabled()) continue;
|
||||
if (!m_textures[i].IsEnabled()) continue;
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + i);
|
||||
checkForGlError("glActiveTexture");
|
||||
@ -2007,7 +1963,8 @@ void GLGSRender::ExecCMD()
|
||||
}
|
||||
|
||||
m_vao.Bind();
|
||||
if(m_indexed_array.m_count)
|
||||
|
||||
if (m_indexed_array.m_count)
|
||||
{
|
||||
LoadVertexData(m_indexed_array.index_min, m_indexed_array.index_max - m_indexed_array.index_min + 1);
|
||||
}
|
||||
@ -2020,7 +1977,7 @@ void GLGSRender::ExecCMD()
|
||||
InitFragmentData();
|
||||
}
|
||||
|
||||
if(m_indexed_array.m_count)
|
||||
if (m_indexed_array.m_count)
|
||||
{
|
||||
switch(m_indexed_array.m_type)
|
||||
{
|
||||
@ -2043,7 +2000,7 @@ void GLGSRender::ExecCMD()
|
||||
m_indexed_array.Reset();
|
||||
}
|
||||
|
||||
if(m_draw_array_count)
|
||||
if (m_draw_array_count)
|
||||
{
|
||||
//LOG_WARNING(RSX,"glDrawArrays(%d,%d,%d)", m_draw_mode - 1, m_draw_array_first, m_draw_array_count);
|
||||
glDrawArrays(m_draw_mode - 1, 0, m_draw_array_count);
|
||||
@ -2056,129 +2013,106 @@ void GLGSRender::ExecCMD()
|
||||
|
||||
void GLGSRender::Flip()
|
||||
{
|
||||
// Set scissor to FBO size
|
||||
if (m_set_scissor_horizontal && m_set_scissor_vertical)
|
||||
{
|
||||
glScissor(0, 0, RSXThread::m_width, RSXThread::m_height);
|
||||
checkForGlError("glScissor");
|
||||
}
|
||||
|
||||
switch (m_surface_color_target)
|
||||
{
|
||||
case CELL_GCM_SURFACE_TARGET_0:
|
||||
case CELL_GCM_SURFACE_TARGET_1:
|
||||
case CELL_GCM_SURFACE_TARGET_MRT1:
|
||||
case CELL_GCM_SURFACE_TARGET_MRT2:
|
||||
case CELL_GCM_SURFACE_TARGET_MRT3:
|
||||
{
|
||||
// Fast path for non-MRT using glBlitFramebuffer.
|
||||
GLfbo::Bind(GL_DRAW_FRAMEBUFFER, 0);
|
||||
// Renderbuffer is upside turn , swapped srcY0 and srcY1
|
||||
GLfbo::Blit(0, RSXThread::m_height, RSXThread::m_width, 0, 0, 0, RSXThread::m_width, RSXThread::m_height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
}
|
||||
break;
|
||||
static u8* src_buffer = nullptr;
|
||||
static u32 width = 0;
|
||||
static u32 height = 0;
|
||||
GLenum format = GL_RGBA;
|
||||
|
||||
case CELL_GCM_SURFACE_TARGET_NONE:
|
||||
if (m_read_buffer)
|
||||
{
|
||||
// Slow path for MRT/None target using glReadPixels.
|
||||
static u8* src_buffer = nullptr;
|
||||
static u32 width = 0;
|
||||
static u32 height = 0;
|
||||
GLenum format = GL_RGBA;
|
||||
format = GL_BGRA;
|
||||
CellGcmDisplayInfo* buffers = vm::get_ptr<CellGcmDisplayInfo>(m_gcm_buffers_addr);
|
||||
u32 addr = GetAddress(buffers[m_gcm_current_buffer].offset, CELL_GCM_LOCATION_LOCAL);
|
||||
|
||||
if (m_read_buffer)
|
||||
if (Memory.IsGoodAddr(addr))
|
||||
{
|
||||
format = GL_BGRA;
|
||||
CellGcmDisplayInfo* buffers = vm::get_ptr<CellGcmDisplayInfo>(m_gcm_buffers_addr);
|
||||
u32 addr = GetAddress(buffers[m_gcm_current_buffer].offset, CELL_GCM_LOCATION_LOCAL);
|
||||
|
||||
if (Memory.IsGoodAddr(addr))
|
||||
{
|
||||
width = buffers[m_gcm_current_buffer].width;
|
||||
height = buffers[m_gcm_current_buffer].height;
|
||||
src_buffer = vm::get_ptr<u8>(addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
src_buffer = nullptr;
|
||||
}
|
||||
}
|
||||
else if (m_fbo.IsCreated())
|
||||
{
|
||||
format = GL_RGBA;
|
||||
static std::vector<u8> pixels;
|
||||
pixels.resize(RSXThread::m_width * RSXThread::m_height * 4);
|
||||
m_fbo.Bind(GL_READ_FRAMEBUFFER);
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[5]);
|
||||
glBufferData(GL_PIXEL_PACK_BUFFER, RSXThread::m_width * RSXThread::m_height * 4, 0, GL_STREAM_READ);
|
||||
glReadPixels(0, 0, RSXThread::m_width, RSXThread::m_height, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, 0);
|
||||
checkForGlError("Flip(): glReadPixels(GL_BGRA, GL_UNSIGNED_INT_8_8_8_8)");
|
||||
GLubyte *packed = (GLubyte *)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
|
||||
if (packed)
|
||||
{
|
||||
memcpy(pixels.data(), packed, RSXThread::m_width * RSXThread::m_height * 4);
|
||||
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
|
||||
checkForGlError("Flip(): glUnmapBuffer");
|
||||
}
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
||||
|
||||
src_buffer = pixels.data();
|
||||
width = RSXThread::m_width;
|
||||
height = RSXThread::m_height;
|
||||
width = buffers[m_gcm_current_buffer].width;
|
||||
height = buffers[m_gcm_current_buffer].height;
|
||||
src_buffer = vm::get_ptr<u8>(addr);
|
||||
}
|
||||
else
|
||||
src_buffer = nullptr;
|
||||
|
||||
if (src_buffer)
|
||||
{
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_CLIP_PLANE0);
|
||||
glDisable(GL_CLIP_PLANE1);
|
||||
glDisable(GL_CLIP_PLANE2);
|
||||
glDisable(GL_CLIP_PLANE3);
|
||||
glDisable(GL_CLIP_PLANE4);
|
||||
glDisable(GL_CLIP_PLANE5);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, g_flip_tex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, format, GL_UNSIGNED_INT_8_8_8_8, src_buffer);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ONE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(0, 1, 0, 1, 0, 1);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
GLfbo::Bind(GL_DRAW_FRAMEBUFFER, 0);
|
||||
|
||||
m_program.UnUse();
|
||||
m_program.Use();
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_ACCUM_BUFFER_BIT);
|
||||
|
||||
glColor3f(1, 1, 1);
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2i(0, 1);
|
||||
glVertex2i(0, 0);
|
||||
|
||||
glTexCoord2i(1, 1);
|
||||
glVertex2i(1, 0);
|
||||
|
||||
glTexCoord2i(1, 0);
|
||||
glVertex2i(1, 1);
|
||||
|
||||
glTexCoord2i(0, 0);
|
||||
glVertex2i(0, 1);
|
||||
glEnd();
|
||||
src_buffer = nullptr;
|
||||
}
|
||||
}
|
||||
break;
|
||||
else if (m_fbo.IsCreated())
|
||||
{
|
||||
format = GL_RGBA;
|
||||
static std::vector<u8> pixels;
|
||||
pixels.resize(RSXThread::m_width * RSXThread::m_height * 4);
|
||||
m_fbo.Bind(GL_READ_FRAMEBUFFER);
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[5]);
|
||||
glBufferData(GL_PIXEL_PACK_BUFFER, RSXThread::m_width * RSXThread::m_height * 4, 0, GL_STREAM_READ);
|
||||
glReadPixels(0, 0, RSXThread::m_width, RSXThread::m_height, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, 0);
|
||||
checkForGlError("Flip(): glReadPixels(GL_BGRA, GL_UNSIGNED_INT_8_8_8_8)");
|
||||
GLubyte *packed = (GLubyte *)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
|
||||
if (packed)
|
||||
{
|
||||
memcpy(pixels.data(), packed, RSXThread::m_width * RSXThread::m_height * 4);
|
||||
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
|
||||
checkForGlError("Flip(): glUnmapBuffer");
|
||||
}
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
||||
|
||||
src_buffer = pixels.data();
|
||||
width = RSXThread::m_width;
|
||||
height = RSXThread::m_height;
|
||||
}
|
||||
else
|
||||
{
|
||||
src_buffer = nullptr;
|
||||
}
|
||||
|
||||
if (src_buffer)
|
||||
{
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_CLIP_PLANE0);
|
||||
glDisable(GL_CLIP_PLANE1);
|
||||
glDisable(GL_CLIP_PLANE2);
|
||||
glDisable(GL_CLIP_PLANE3);
|
||||
glDisable(GL_CLIP_PLANE4);
|
||||
glDisable(GL_CLIP_PLANE5);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, g_flip_tex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, format, GL_UNSIGNED_INT_8_8_8_8, src_buffer);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ONE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(0, 1, 0, 1, 0, 1);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
GLfbo::Bind(GL_DRAW_FRAMEBUFFER, 0);
|
||||
|
||||
m_program.UnUse();
|
||||
m_program.Use();
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_ACCUM_BUFFER_BIT);
|
||||
|
||||
glColor3f(1, 1, 1);
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2i(0, 1);
|
||||
glVertex2i(0, 0);
|
||||
glTexCoord2i(1, 1);
|
||||
glVertex2i(1, 0);
|
||||
glTexCoord2i(1, 0);
|
||||
glVertex2i(1, 1);
|
||||
glTexCoord2i(0, 0);
|
||||
glVertex2i(0, 1);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
// Draw Objects
|
||||
for (uint i = 0; i<m_post_draw_objs.size(); ++i)
|
||||
for (uint i = 0; i < m_post_draw_objs.size(); ++i)
|
||||
{
|
||||
m_post_draw_objs[i].Draw();
|
||||
}
|
||||
@ -2198,20 +2132,23 @@ u32 LinearToSwizzleAddress(u32 x, u32 y, u32 z, u32 log2_width, u32 log2_height,
|
||||
{
|
||||
u32 offset = 0;
|
||||
u32 shift_count = 0;
|
||||
while(log2_width | log2_height | log2_depth){
|
||||
if(log2_width){
|
||||
while (log2_width | log2_height | log2_depth){
|
||||
if (log2_width)
|
||||
{
|
||||
offset |= (x & 0x01) << shift_count;
|
||||
x >>= 1;
|
||||
++shift_count;
|
||||
--log2_width;
|
||||
}
|
||||
if(log2_height){
|
||||
if (log2_height)
|
||||
{
|
||||
offset |= (y & 0x01) << shift_count;
|
||||
y >>= 1;
|
||||
++shift_count;
|
||||
--log2_height;
|
||||
}
|
||||
if(log2_depth){
|
||||
if (log2_depth)
|
||||
{
|
||||
offset |= (z & 0x01) << shift_count;
|
||||
z >>= 1;
|
||||
++shift_count;
|
||||
|
@ -190,7 +190,11 @@ protected:
|
||||
virtual void OnInitThread();
|
||||
virtual void OnExitThread();
|
||||
virtual void OnReset();
|
||||
virtual void ExecCMD(u32 cmd);
|
||||
virtual void ExecCMD();
|
||||
virtual void ClearColor(u32 a, u32 r, u32 g, u32 b);
|
||||
virtual void ClearStencil(u32 stencil);
|
||||
virtual void ClearDepth(u32 depth);
|
||||
virtual void ClearSurface(u32 mask);
|
||||
virtual void ColorMask(bool a, bool r, bool g, bool b);
|
||||
virtual void Flip();
|
||||
};
|
||||
|
@ -15,34 +15,42 @@
|
||||
|
||||
u32 methodRegisters[0xffff];
|
||||
|
||||
void RSXThread::nativeRescale(float width, float height)
|
||||
void RSXThread::NativeRescale(float width, float height)
|
||||
{
|
||||
switch (Ini.GSResolution.GetValue())
|
||||
{
|
||||
case 1: // 1920x1080 window size
|
||||
{
|
||||
m_width_scale = 1920 / width * 2.0f;
|
||||
m_height_scale = 1080 / height * 2.0f;
|
||||
m_width = 1920;
|
||||
m_height = 1080;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 2: // 1280x720 window size
|
||||
{
|
||||
m_width_scale = 1280 / width * 2.0f;
|
||||
m_height_scale = 720 / height * 2.0f;
|
||||
m_width = 1280;
|
||||
m_height = 720;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 4: // 720x480 window size
|
||||
{
|
||||
m_width_scale = 720 / width * 2.0f;
|
||||
m_height_scale = 480 / height * 2.0f;
|
||||
m_width = 720;
|
||||
m_height = 480;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 5: // 720x576 window size
|
||||
{
|
||||
m_width_scale = 720 / width * 2.0f;
|
||||
m_height_scale = 576 / height * 2.0f;
|
||||
m_width = 720;
|
||||
m_height = 576;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,13 +114,13 @@ void RSXVertexData::Reset()
|
||||
|
||||
void RSXVertexData::Load(u32 start, u32 count, u32 baseOffset, u32 baseIndex=0)
|
||||
{
|
||||
if(!addr) return;
|
||||
if (!addr) return;
|
||||
|
||||
const u32 tsize = GetTypeSize();
|
||||
|
||||
data.resize((start + count) * tsize * size);
|
||||
|
||||
for(u32 i=start; i<start + count; ++i)
|
||||
for (u32 i = start; i < start + count; ++i)
|
||||
{
|
||||
auto src = vm::get_ptr<const u8>(addr + baseOffset + stride * (i + baseIndex));
|
||||
u8* dst = &data[i * tsize * size];
|
||||
@ -129,7 +137,7 @@ void RSXVertexData::Load(u32 start, u32 count, u32 baseOffset, u32 baseIndex=0)
|
||||
{
|
||||
const u16* c_src = (const u16*)src;
|
||||
u16* c_dst = (u16*)dst;
|
||||
for(u32 j=0; j<size; ++j) *c_dst++ = re16(*c_src++);
|
||||
for (u32 j = 0; j < size; ++j) *c_dst++ = re16(*c_src++);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -137,7 +145,7 @@ void RSXVertexData::Load(u32 start, u32 count, u32 baseOffset, u32 baseIndex=0)
|
||||
{
|
||||
const u32* c_src = (const u32*)src;
|
||||
u32* c_dst = (u32*)dst;
|
||||
for(u32 j=0; j<size; ++j) *c_dst++ = re32(*c_src++);
|
||||
for (u32 j = 0; j < size; ++j) *c_dst++ = re32(*c_src++);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -167,7 +175,7 @@ u32 RSXThread::OutOfArgsCount(const uint x, const u32 cmd, const u32 count, cons
|
||||
auto args = vm::ptr<u32>::make(args_addr);
|
||||
std::string debug = GetMethodName(cmd);
|
||||
debug += "(";
|
||||
for(u32 i=0; i<count; ++i) debug += (i ? ", " : "") + fmt::Format("0x%x", ARGS(i));
|
||||
for (u32 i = 0; i < count; ++i) debug += (i ? ", " : "") + fmt::Format("0x%x", ARGS(i));
|
||||
debug += ")";
|
||||
LOG_NOTICE(RSX, "OutOfArgsCount(x=%u, count=%u): %s", x, count, debug.c_str());
|
||||
|
||||
@ -247,7 +255,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||
case NV406E_SEMAPHORE_RELEASE:
|
||||
case NV4097_TEXTURE_READ_SEMAPHORE_RELEASE:
|
||||
{
|
||||
if(m_set_semaphore_offset)
|
||||
if (m_set_semaphore_offset)
|
||||
{
|
||||
m_set_semaphore_offset = false;
|
||||
vm::write32(Memory.RSXCMDMem.GetStartAddr() + m_semaphore_offset, ARGS(0));
|
||||
@ -257,7 +265,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||
|
||||
case NV4097_BACK_END_WRITE_SEMAPHORE_RELEASE:
|
||||
{
|
||||
if(m_set_semaphore_offset)
|
||||
if (m_set_semaphore_offset)
|
||||
{
|
||||
m_set_semaphore_offset = false;
|
||||
u32 value = ARGS(0);
|
||||
@ -303,7 +311,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||
return;
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds((s64)(1000.0 / limit - m_timer_sync.GetElapsedTimeInMilliSec())));
|
||||
std::this_thread::sleep_for (std::chrono::milliseconds((s64)(1000.0 / limit - m_timer_sync.GetElapsedTimeInMilliSec())));
|
||||
m_timer_sync.Start();
|
||||
};
|
||||
|
||||
@ -532,13 +540,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||
// Color Mask
|
||||
case NV4097_SET_COLOR_MASK:
|
||||
{
|
||||
const u32 a0 = ARGS(0);
|
||||
|
||||
m_set_color_mask = true;
|
||||
m_color_mask_a = a0 & 0x1000000 ? true : false;
|
||||
m_color_mask_r = a0 & 0x0010000 ? true : false;
|
||||
m_color_mask_g = a0 & 0x0000100 ? true : false;
|
||||
m_color_mask_b = a0 & 0x0000001 ? true : false;
|
||||
const u32 mask = ARGS(0);
|
||||
ColorMask(mask & 0x1000000, mask & 0x1000000, mask & 0x1000000, mask & 0x0000001);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -857,8 +860,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||
{
|
||||
u32 a0 = ARGS(0);
|
||||
|
||||
if(a0 & 0x01) m_clear_surface_z = m_clear_z;
|
||||
if(a0 & 0x02) m_clear_surface_s = m_clear_s;
|
||||
if (a0 & 0x01) m_clear_surface_z = m_clear_z;
|
||||
if (a0 & 0x02) m_clear_surface_s = m_clear_s;
|
||||
|
||||
m_clear_surface_mask |= a0 & 0x3;
|
||||
}
|
||||
@ -866,35 +869,26 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||
|
||||
case NV4097_CLEAR_SURFACE:
|
||||
{
|
||||
const u32 a0 = ARGS(0);
|
||||
const u32 mask = ARGS(0);
|
||||
|
||||
if(a0 & 0x01) m_clear_surface_z = m_clear_z;
|
||||
if(a0 & 0x02) m_clear_surface_s = m_clear_s;
|
||||
if(a0 & 0x10) m_clear_surface_color_r = m_clear_color_r;
|
||||
if(a0 & 0x20) m_clear_surface_color_g = m_clear_color_g;
|
||||
if(a0 & 0x40) m_clear_surface_color_b = m_clear_color_b;
|
||||
if(a0 & 0x80) m_clear_surface_color_a = m_clear_color_a;
|
||||
|
||||
m_clear_surface_mask = a0;
|
||||
ExecCMD(NV4097_CLEAR_SURFACE);
|
||||
ClearSurface(mask);
|
||||
}
|
||||
break;
|
||||
|
||||
case NV4097_SET_ZSTENCIL_CLEAR_VALUE:
|
||||
{
|
||||
const u32 a0 = ARGS(0);
|
||||
m_clear_s = a0 & 0xff;
|
||||
m_clear_z = a0 >> 8;
|
||||
const u32 value = ARGS(0);
|
||||
|
||||
ClearStencil(value & 0xff);
|
||||
ClearDepth(value >> 8);
|
||||
}
|
||||
break;
|
||||
|
||||
case NV4097_SET_COLOR_CLEAR_VALUE:
|
||||
{
|
||||
const u32 color = ARGS(0);
|
||||
m_clear_color_a = (color >> 24) & 0xff;
|
||||
m_clear_color_r = (color >> 16) & 0xff;
|
||||
m_clear_color_g = (color >> 8) & 0xff;
|
||||
m_clear_color_b = color & 0xff;
|
||||
|
||||
ClearColor((color >> 24) & 0xff, (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -928,7 +922,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||
|
||||
case NV4097_DRAW_ARRAYS:
|
||||
{
|
||||
for(u32 c=0; c<count; ++c)
|
||||
for (u32 c=0; c<count; ++c)
|
||||
{
|
||||
u32 ac = ARGS(c);
|
||||
const u32 first = ac & 0xffffff;
|
||||
@ -957,14 +951,14 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||
|
||||
case NV4097_DRAW_INDEX_ARRAY:
|
||||
{
|
||||
for(u32 c=0; c<count; ++c)
|
||||
for (u32 c=0; c<count; ++c)
|
||||
{
|
||||
const u32 first = ARGS(c) & 0xffffff;
|
||||
const u32 _count = (ARGS(c) >> 24) + 1;
|
||||
|
||||
if(first < m_indexed_array.m_first) m_indexed_array.m_first = first;
|
||||
if (first < m_indexed_array.m_first) m_indexed_array.m_first = first;
|
||||
|
||||
for(u32 i=first; i<_count; ++i)
|
||||
for (u32 i=first; i<_count; ++i)
|
||||
{
|
||||
u32 index;
|
||||
switch(m_indexed_array.m_type)
|
||||
@ -990,8 +984,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||
break;
|
||||
}
|
||||
|
||||
if(index < m_indexed_array.index_min) m_indexed_array.index_min = index;
|
||||
if(index > m_indexed_array.index_max) m_indexed_array.index_max = index;
|
||||
if (index < m_indexed_array.index_min) m_indexed_array.index_min = index;
|
||||
if (index > m_indexed_array.index_max) m_indexed_array.index_max = index;
|
||||
}
|
||||
|
||||
m_indexed_array.m_count += _count;
|
||||
@ -1130,7 +1124,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||
{
|
||||
//LOG_WARNING(RSX, "NV4097_SET_TRANSFORM_PROGRAM[%d](%d)", index, count);
|
||||
|
||||
if(!m_cur_vertex_prog)
|
||||
if (!m_cur_vertex_prog)
|
||||
{
|
||||
LOG_ERROR(RSX, "NV4097_SET_TRANSFORM_PROGRAM: m_cur_vertex_prog is null");
|
||||
break;
|
||||
@ -1148,7 +1142,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||
// TODO:
|
||||
// (cmd)[1] = CELL_GCM_ENDIAN_SWAP((count) | ((registerCount) << 16)); \
|
||||
|
||||
if(!m_cur_vertex_prog)
|
||||
if (!m_cur_vertex_prog)
|
||||
{
|
||||
LOG_ERROR(RSX, "NV4097_SET_TRANSFORM_TIMEOUT: m_cur_vertex_prog is null");
|
||||
break;
|
||||
@ -1168,13 +1162,13 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||
|
||||
case NV4097_SET_TRANSFORM_CONSTANT_LOAD:
|
||||
{
|
||||
if((count - 1) % 4)
|
||||
if ((count - 1) % 4)
|
||||
{
|
||||
LOG_ERROR(RSX, "NV4097_SET_TRANSFORM_CONSTANT_LOAD: bad count %d", count);
|
||||
break;
|
||||
}
|
||||
|
||||
for(u32 id = ARGS(0), i = 1; i<count; ++id)
|
||||
for (u32 id = ARGS(0), i = 1; i<count; ++id)
|
||||
{
|
||||
const u32 x = ARGS(i); i++;
|
||||
const u32 y = ARGS(i); i++;
|
||||
@ -1272,12 +1266,12 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||
m_set_stencil_func = true;
|
||||
m_stencil_func = ARGS(0);
|
||||
|
||||
if(count >= 2)
|
||||
if (count >= 2)
|
||||
{
|
||||
m_set_stencil_func_ref = true;
|
||||
m_stencil_func_ref = ARGS(1);
|
||||
|
||||
if(count >= 3)
|
||||
if (count >= 3)
|
||||
{
|
||||
m_set_stencil_func_mask = true;
|
||||
m_stencil_func_mask = ARGS(2);
|
||||
@ -1305,12 +1299,12 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||
m_set_stencil_fail = true;
|
||||
m_stencil_fail = ARGS(0);
|
||||
|
||||
if(count >= 2)
|
||||
if (count >= 2)
|
||||
{
|
||||
m_set_stencil_zfail = true;
|
||||
m_stencil_zfail = ARGS(1);
|
||||
|
||||
if(count >= 3)
|
||||
if (count >= 3)
|
||||
{
|
||||
m_set_stencil_zpass = true;
|
||||
m_stencil_zpass = ARGS(2);
|
||||
@ -1331,12 +1325,12 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||
m_set_back_stencil_func = true;
|
||||
m_back_stencil_func = ARGS(0);
|
||||
|
||||
if(count >= 2)
|
||||
if (count >= 2)
|
||||
{
|
||||
m_set_back_stencil_func_ref = true;
|
||||
m_back_stencil_func_ref = ARGS(1);
|
||||
|
||||
if(count >= 3)
|
||||
if (count >= 3)
|
||||
{
|
||||
m_set_back_stencil_func_mask = true;
|
||||
m_back_stencil_func_mask = ARGS(2);
|
||||
@ -1364,12 +1358,12 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||
m_set_stencil_fail = true;
|
||||
m_stencil_fail = ARGS(0);
|
||||
|
||||
if(count >= 2)
|
||||
if (count >= 2)
|
||||
{
|
||||
m_set_back_stencil_zfail = true;
|
||||
m_back_stencil_zfail = ARGS(1);
|
||||
|
||||
if(count >= 3)
|
||||
if (count >= 3)
|
||||
{
|
||||
m_set_back_stencil_zpass = true;
|
||||
m_back_stencil_zpass = ARGS(2);
|
||||
@ -1442,7 +1436,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||
m_scissor_x = ARGS(0) & 0xffff;
|
||||
m_scissor_w = ARGS(0) >> 16;
|
||||
|
||||
if(count == 2)
|
||||
if (count == 2)
|
||||
{
|
||||
m_set_scissor_vertical = true;
|
||||
m_scissor_y = ARGS(1) & 0xffff;
|
||||
@ -1484,7 +1478,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||
m_width = buffers[m_gcm_current_buffer].width;
|
||||
m_height = buffers[m_gcm_current_buffer].height;
|
||||
|
||||
nativeRescale((float)m_width, (float)m_height);
|
||||
NativeRescale((float)m_width, (float)m_height);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1600,7 +1594,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||
m_set_context_dma_color_c = true;
|
||||
m_context_dma_color_c = ARGS(0);
|
||||
|
||||
if(count > 1)
|
||||
if (count > 1)
|
||||
{
|
||||
m_set_context_dma_color_d = true;
|
||||
m_context_dma_color_d = ARGS(1);
|
||||
@ -1650,7 +1644,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||
m_surface_clip_x = a0;
|
||||
m_surface_clip_w = a0 >> 16;
|
||||
|
||||
if(count == 2)
|
||||
if (count == 2)
|
||||
{
|
||||
const u32 a1 = ARGS(1);
|
||||
m_set_surface_clip_vertical = true;
|
||||
@ -2058,21 +2052,21 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||
c.y = (float&)a;
|
||||
}
|
||||
|
||||
if(count >= 3)
|
||||
if (count >= 3)
|
||||
{
|
||||
u32 a = ARGS(2);
|
||||
a = a << 16 | a >> 16;
|
||||
c.z = (float&)a;
|
||||
}
|
||||
|
||||
if(count >= 4)
|
||||
if (count >= 4)
|
||||
{
|
||||
u32 a = ARGS(3);
|
||||
a = a << 16 | a >> 16;
|
||||
c.w = (float&)a;
|
||||
}
|
||||
|
||||
if(count >= 5)
|
||||
if (count >= 5)
|
||||
{
|
||||
LOG_WARNING(RSX, "NV308A_COLOR: count = %d", count);
|
||||
}
|
||||
@ -2120,9 +2114,9 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||
LOG_WARNING(RSX, "NV3089_IMAGE_IN_SIZE: m_dst_offset=0x%x, m_color: conv_in_h=0x%x, format_src_pitch=0x%x, conv_in_x=0x%x, conv_in_y=0x%x, conv_out_x=0x%x, conv_out_y=0x%x",
|
||||
m_dst_offset, m_color_conv_in_h, m_color_format_src_pitch, m_color_conv_in_x, m_color_conv_in_y, m_color_conv_out_x, m_color_conv_out_y);
|
||||
|
||||
for(u16 y=0; y<m_color_conv_in_h; ++y)
|
||||
for (u16 y=0; y<m_color_conv_in_h; ++y)
|
||||
{
|
||||
for(u16 x=0; x<m_color_format_src_pitch/4/*m_color_conv_in_w*/; ++x)
|
||||
for (u16 x=0; x<m_color_format_src_pitch/4/*m_color_conv_in_w*/; ++x)
|
||||
{
|
||||
const u32 src_offset = (m_color_conv_in_y + y) * m_color_format_src_pitch + (m_color_conv_in_x + x) * 4;
|
||||
const u32 dst_offset = (m_color_conv_out_y + y) * m_color_format_dst_pitch + (m_color_conv_out_x + x) * 4;
|
||||
@ -2280,18 +2274,18 @@ void RSXThread::End()
|
||||
ExecCMD();
|
||||
|
||||
for (auto &vdata : m_vertex_data)
|
||||
{
|
||||
vdata.data.clear();
|
||||
}
|
||||
|
||||
m_indexed_array.Reset();
|
||||
m_fragment_constants.clear();
|
||||
m_transform_constants.clear();
|
||||
m_cur_shader_prog_num = 0;
|
||||
//m_cur_shader_prog = nullptr;
|
||||
|
||||
m_clear_surface_mask = 0;
|
||||
m_begin_end = 0;
|
||||
|
||||
//Reset();
|
||||
OnReset();
|
||||
}
|
||||
|
||||
@ -2333,14 +2327,14 @@ void RSXThread::Task()
|
||||
continue;
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack
|
||||
std::this_thread::sleep_for (std::chrono::milliseconds(1)); // hack
|
||||
}
|
||||
|
||||
is_vblank_stopped = true;
|
||||
});
|
||||
vblank.detach();
|
||||
|
||||
while(!TestDestroy()) try
|
||||
while (!TestDestroy()) try
|
||||
{
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
@ -2354,62 +2348,61 @@ void RSXThread::Task()
|
||||
u32 get = m_ctrl->get.read_sync();
|
||||
u32 put = m_ctrl->put.read_sync();
|
||||
|
||||
if(put == get || !Emu.IsRunning())
|
||||
if (put == get || !Emu.IsRunning())
|
||||
{
|
||||
if(put == get)
|
||||
if (put == get)
|
||||
{
|
||||
if(m_flip_status == 0)
|
||||
if (m_flip_status == 0)
|
||||
m_sem_flip.post_and_wait();
|
||||
|
||||
m_sem_flush.post_and_wait();
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack
|
||||
std::this_thread::sleep_for (std::chrono::milliseconds(1)); // hack
|
||||
continue;
|
||||
}
|
||||
|
||||
//ConLog.Write("addr = 0x%x", m_ioAddress + get);
|
||||
const u32 cmd = ReadIO32(get);
|
||||
const u32 count = (cmd >> 18) & 0x7ff;
|
||||
//if(cmd == 0) continue;
|
||||
|
||||
|
||||
if (Ini.RSXLogging.GetValue())
|
||||
{
|
||||
LOG_NOTICE(Log::RSX, "%s (cmd=0x%x)", GetMethodName(cmd & 0xffff).c_str(), cmd);
|
||||
}
|
||||
|
||||
//LOG_NOTICE(Log::RSX, "put=0x%x, get=0x%x, cmd=0x%x (%s)", put, get, cmd, GetMethodName(cmd & 0xffff).c_str());
|
||||
|
||||
if(cmd & CELL_GCM_METHOD_FLAG_JUMP)
|
||||
if (cmd & CELL_GCM_METHOD_FLAG_JUMP)
|
||||
{
|
||||
u32 offs = cmd & 0x1fffffff;
|
||||
//LOG_WARNING(RSX, "rsx jump(0x%x) #addr=0x%x, cmd=0x%x, get=0x%x, put=0x%x", offs, m_ioAddress + get, cmd, get, put);
|
||||
m_ctrl->get.exchange(be_t<u32>::make(offs));
|
||||
continue;
|
||||
}
|
||||
if(cmd & CELL_GCM_METHOD_FLAG_CALL)
|
||||
|
||||
if (cmd & CELL_GCM_METHOD_FLAG_CALL)
|
||||
{
|
||||
m_call_stack.push(get + 4);
|
||||
u32 offs = cmd & ~3;
|
||||
//u32 addr = offs;
|
||||
//LOG_WARNING(RSX, "rsx call(0x%x) #0x%x - 0x%x", offs, cmd, get);
|
||||
m_ctrl->get.exchange(be_t<u32>::make(offs));
|
||||
continue;
|
||||
}
|
||||
if(cmd == CELL_GCM_METHOD_FLAG_RETURN)
|
||||
|
||||
if (cmd == CELL_GCM_METHOD_FLAG_RETURN)
|
||||
{
|
||||
//LOG_WARNING(RSX, "rsx return!");
|
||||
u32 get = m_call_stack.top();
|
||||
m_call_stack.pop();
|
||||
//LOG_WARNING(RSX, "rsx return(0x%x)", get);
|
||||
m_ctrl->get.exchange(be_t<u32>::make(get));
|
||||
continue;
|
||||
}
|
||||
if(cmd & CELL_GCM_METHOD_FLAG_NON_INCREMENT)
|
||||
|
||||
if (cmd & CELL_GCM_METHOD_FLAG_NON_INCREMENT)
|
||||
{
|
||||
//LOG_WARNING(RSX, "non increment cmd! 0x%x", cmd);
|
||||
//LOG_WARNING(RSX, "rsx non increment cmd! 0x%x", cmd);
|
||||
inc = 0;
|
||||
}
|
||||
|
||||
if(cmd == 0) //nop
|
||||
if (cmd == 0) //nop
|
||||
{
|
||||
m_ctrl->get.atomic_op([](be_t<u32>& value)
|
||||
{
|
||||
@ -2420,7 +2413,7 @@ void RSXThread::Task()
|
||||
|
||||
auto args = vm::ptr<u32>::make((u32)Memory.RSXIOMem.RealAddr(get + 4));
|
||||
|
||||
for(u32 i=0; i<count; i++)
|
||||
for (u32 i = 0; i < count; i++)
|
||||
{
|
||||
methodRegisters[(cmd & 0xffff) + (i * 4 * inc)] = ARGS(i);
|
||||
}
|
||||
@ -2431,13 +2424,14 @@ void RSXThread::Task()
|
||||
{
|
||||
value += (count + 1) * 4;
|
||||
});
|
||||
//memset(Memory.GetMemFromAddr(p.m_ioAddress + get), 0, (count + 1) * 4);
|
||||
}
|
||||
|
||||
catch (const std::string& e)
|
||||
{
|
||||
LOG_ERROR(RSX, "Exception: %s", e.c_str());
|
||||
Emu.Pause();
|
||||
}
|
||||
|
||||
catch (const char* e)
|
||||
{
|
||||
LOG_ERROR(RSX, "Exception: %s", e);
|
||||
@ -2446,7 +2440,7 @@ void RSXThread::Task()
|
||||
|
||||
while (!is_vblank_stopped)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack
|
||||
std::this_thread::sleep_for (std::chrono::milliseconds(1)); // hack
|
||||
}
|
||||
|
||||
LOG_NOTICE(RSX, "RSX thread ended");
|
||||
|
@ -519,12 +519,15 @@ protected:
|
||||
m_line_stipple_factor = 1;
|
||||
m_vertex_data_base_offset = 0;
|
||||
m_vertex_data_base_index = 0;
|
||||
for (size_t i = 0; i < 32; i++) {
|
||||
|
||||
// Construct Stipple Pattern
|
||||
for (size_t i = 0; i < 32; i++)
|
||||
{
|
||||
m_polygon_stipple_pattern[i] = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
// Construct Textures
|
||||
for(int i=0; i<16; i++)
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
m_textures[i] = RSXTexture(i);
|
||||
}
|
||||
@ -611,7 +614,7 @@ protected:
|
||||
m_clear_surface_mask = 0;
|
||||
m_begin_end = 0;
|
||||
|
||||
for(uint i=0; i<m_textures_count; ++i)
|
||||
for (uint i = 0; i < m_textures_count; ++i)
|
||||
{
|
||||
m_textures[i].Init();
|
||||
}
|
||||
@ -622,19 +625,23 @@ protected:
|
||||
|
||||
u32 OutOfArgsCount(const uint x, const u32 cmd, const u32 count, const u32 args_addr);
|
||||
void DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const u32 count);
|
||||
void nativeRescale(float width, float height);
|
||||
void NativeRescale(float width, float height);
|
||||
|
||||
virtual void OnInit() = 0;
|
||||
virtual void OnInitThread() = 0;
|
||||
virtual void OnExitThread() = 0;
|
||||
virtual void OnReset() = 0;
|
||||
virtual void ExecCMD() = 0;
|
||||
virtual void ExecCMD(u32 cmd) = 0;
|
||||
virtual void ClearColor(u32 a, u32 r, u32 g, u32 b) = 0;
|
||||
virtual void ClearStencil(u32 stencil) = 0;
|
||||
virtual void ClearDepth(u32 depth) = 0;
|
||||
virtual void ClearSurface(u32 mask) = 0;
|
||||
virtual void ColorMask(bool a, bool r, bool g, bool b) = 0;
|
||||
virtual void Flip() = 0;
|
||||
|
||||
void LoadVertexData(u32 first, u32 count)
|
||||
{
|
||||
for(u32 i=0; i<m_vertex_count; ++i)
|
||||
for (u32 i = 0; i < m_vertex_count; ++i)
|
||||
{
|
||||
if(!m_vertex_data[i].IsEnabled()) continue;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user