Merge pull request #940 from raven02/patch-11

RSX : add ClearColor() / ClearStencil() / ClearDepth() / ClearSurface()
This commit is contained in:
B1ackDaemon 2014-12-30 08:30:46 +02:00
commit 99a9a1e38d
5 changed files with 338 additions and 380 deletions

View File

@ -98,7 +98,9 @@ float GLTexture::GetMaxAniso(int aniso)
void GLTexture::Init(RSXTexture& tex) void GLTexture::Init(RSXTexture& tex)
{ {
if (tex.GetLocation() > 1) if (tex.GetLocation() > 1)
{
return; return;
}
Bind(); Bind();
@ -108,8 +110,9 @@ void GLTexture::Init(RSXTexture& tex)
LOG_ERROR(RSX, "Bad texture address=0x%x", texaddr); LOG_ERROR(RSX, "Bad texture address=0x%x", texaddr);
return; return;
} }
//ConLog.Warning("texture addr = 0x%x, width = %d, height = %d, max_aniso=%d, mipmap=%d, remap=0x%x, zfunc=0x%x, wraps=0x%x, wrapt=0x%x, wrapr=0x%x, minlod=0x%x, maxlod=0x%x", //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); // 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 //TODO: safe init
checkForGlError("GLTexture::Init() -> glBindTexture"); checkForGlError("GLTexture::Init() -> glBindTexture");
@ -452,8 +455,7 @@ void GLTexture::Init(RSXTexture& tex)
} }
break; break;
default: LOG_ERROR(RSX, "Init tex error: Bad tex format (0x%x | %s | 0x%x)", format, default: LOG_ERROR(RSX, "Init tex error: Bad tex format (0x%x | %s | 0x%x)", format, (is_swizzled ? "swizzled" : "linear"), tex.GetFormat() & 0x40);
(is_swizzled ? "swizzled" : "linear"), tex.GetFormat() & 0x40);
break; break;
} }
@ -693,8 +695,6 @@ void DrawCursorObj::Draw()
if (m_update_texture) if (m_update_texture)
{ {
//m_update_texture = false;
glUniform2f(m_program.GetLocation("in_tc"), m_width, m_height); glUniform2f(m_program.GetLocation("in_tc"), m_width, m_height);
checkForGlError("DrawCursorObj : glUniform2f"); checkForGlError("DrawCursorObj : glUniform2f");
if (!m_tex_id) if (!m_tex_id)
@ -714,8 +714,6 @@ void DrawCursorObj::Draw()
if (m_update_pos) 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); glUniform4f(m_program.GetLocation("in_pos"), m_pos_x, m_pos_y, m_pos_z, 1.0f);
checkForGlError("DrawCursorObj : glUniform4f"); checkForGlError("DrawCursorObj : glUniform4f");
} }
@ -727,10 +725,7 @@ void DrawCursorObj::Draw()
checkForGlError("DrawCursorObj : m_fbo.Bind(GL_READ_FRAMEBUFFER)"); checkForGlError("DrawCursorObj : m_fbo.Bind(GL_READ_FRAMEBUFFER)");
GLfbo::Bind(GL_DRAW_FRAMEBUFFER, 0); GLfbo::Bind(GL_DRAW_FRAMEBUFFER, 0);
checkForGlError("DrawCursorObj : GLfbo::Bind(GL_DRAW_FRAMEBUFFER, 0)"); checkForGlError("DrawCursorObj : GLfbo::Bind(GL_DRAW_FRAMEBUFFER, 0)");
GLfbo::Blit( GLfbo::Blit(0, 0, m_width, m_height, 0, 0, m_width, m_height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
0, 0, m_width, m_height,
0, 0, m_width, m_height,
GL_COLOR_BUFFER_BIT, GL_NEAREST);
checkForGlError("DrawCursorObj : GLfbo::Blit"); checkForGlError("DrawCursorObj : GLfbo::Blit");
m_fbo.Bind(); m_fbo.Bind();
checkForGlError("DrawCursorObj : m_fbo.Bind"); checkForGlError("DrawCursorObj : m_fbo.Bind");
@ -783,7 +778,7 @@ void DrawCursorObj::SetPosition(float x, float y, float z)
void DrawCursorObj::InitializeLocations() 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() GLGSRender::GLGSRender()
@ -820,7 +815,10 @@ void GLGSRender::Close()
{ {
Stop(); Stop();
if(m_frame->IsShown()) m_frame->Hide(); if (m_frame->IsShown())
{
m_frame->Hide();
}
m_ctrl = nullptr; m_ctrl = nullptr;
} }
@ -980,7 +978,8 @@ void GLGSRender::EnableVertexData(bool indexed_draw)
GL_FALSE, 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); LOG_ERROR(RSX, "GLGSRender::EnableVertexData: Bad vertex data type (%d)!", m_vertex_data[i].type);
} }
@ -1059,7 +1058,6 @@ void GLGSRender::InitVertexData()
l = m_program.GetLocation(name); l = m_program.GetLocation(name);
checkForGlError("glGetUniformLocation " + 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); 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)); checkForGlError("glUniform4f " + name + fmt::Format(" %d [%f %f %f %f]", l, c.x, c.y, c.z, c.w));
} }
@ -1090,7 +1088,8 @@ void GLGSRender::InitFragmentData()
return; return;
} }
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_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); //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);
@ -1126,13 +1125,9 @@ bool GLGSRender::LoadProgram()
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_shader_prog, m_shader_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);
//ConLog.Write("Create program");
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.DecompileAsync(*m_cur_shader_prog);
//m_shader_prog.Wait();
m_shader_prog.Decompile(*m_cur_shader_prog); m_shader_prog.Decompile(*m_cur_shader_prog);
m_shader_prog.Compile(); m_shader_prog.Compile();
checkForGlError("m_shader_prog.Compile"); checkForGlError("m_shader_prog.Compile");
@ -1145,8 +1140,6 @@ bool GLGSRender::LoadProgram()
if (m_vp_buf_num == -1) if (m_vp_buf_num == -1)
{ {
LOG_WARNING(RSX, "VP not found in buffer!"); 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.Decompile(*m_cur_vertex_prog);
m_vertex_prog.Compile(); m_vertex_prog.Compile();
checkForGlError("m_vertex_prog.Compile"); checkForGlError("m_vertex_prog.Compile");
@ -1490,11 +1483,6 @@ void GLGSRender::OnInitThread()
#ifdef _WIN32 #ifdef _WIN32
glSwapInterval(Ini.GSVSyncEnable.GetValue() ? 1 : 0); glSwapInterval(Ini.GSVSyncEnable.GetValue() ? 1 : 0);
// Undefined reference: glXSwapIntervalEXT
/*#else
if (GLXDrawable drawable = glXGetCurrentDrawable()){
glXSwapIntervalEXT(glXGetCurrentDisplay(), drawable, Ini.GSVSyncEnable.GetValue() ? 1 : 0);
}*/
#endif #endif
} }
@ -1520,9 +1508,6 @@ void GLGSRender::OnReset()
{ {
m_program.UnUse(); 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.UnBind();
@ -1559,15 +1544,6 @@ void GLGSRender::InitDrawBuffers()
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: case CELL_GCM_SURFACE_Z16:
m_rbo.Storage(GL_DEPTH_COMPONENT16, RSXThread::m_width, RSXThread::m_height); m_rbo.Storage(GL_DEPTH_COMPONENT16, RSXThread::m_width, RSXThread::m_height);
checkForGlError("m_rbo.Storage(GL_DEPTH_COMPONENT16)"); checkForGlError("m_rbo.Storage(GL_DEPTH_COMPONENT16)");
@ -1664,63 +1640,47 @@ void GLGSRender::InitDrawBuffers()
} }
} }
void GLGSRender::ExecCMD(u32 cmd) void GLGSRender::ClearColor(u32 a, u32 r, u32 g, u32 b)
{ {
assert(cmd == NV4097_CLEAR_SURFACE); 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)
{
InitDrawBuffers(); InitDrawBuffers();
if(m_set_color_mask) GLbitfield clearMask = 0;
{ if (mask & 0x01) clearMask |= GL_DEPTH_BUFFER_BIT;
glColorMask(m_color_mask_r, m_color_mask_g, m_color_mask_b, m_color_mask_a); if (mask & 0x02) clearMask |= GL_STENCIL_BUFFER_BIT;
checkForGlError("glColorMask"); if (mask & 0xF0) clearMask |= GL_COLOR_BUFFER_BIT;
}
if (m_set_scissor_horizontal && m_set_scissor_vertical) glClear(clearMask);
{
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"); checkForGlError("glClear");
WriteBuffers(); WriteBuffers();
} }
void GLGSRender::ColorMask(bool a, bool r, bool g, bool b)
{
glColorMask(r, g, b, a);
checkForGlError("glColorMask");
}
void GLGSRender::ExecCMD() void GLGSRender::ExecCMD()
{ {
//return;
if (!LoadProgram()) if (!LoadProgram())
{ {
LOG_ERROR(RSX, "LoadProgram failed."); LOG_ERROR(RSX, "LoadProgram failed.");
@ -1730,12 +1690,6 @@ void GLGSRender::ExecCMD()
InitDrawBuffers(); 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_depth_test, GL_DEPTH_TEST);
Enable(m_set_alpha_test, GL_ALPHA_TEST); Enable(m_set_alpha_test, GL_ALPHA_TEST);
Enable(m_set_depth_bounds_test, GL_DEPTH_BOUNDS_TEST_EXT); Enable(m_set_depth_bounds_test, GL_DEPTH_BOUNDS_TEST_EXT);
@ -1865,9 +1819,11 @@ void GLGSRender::ExecCMD()
} }
} }
// TODO: Use other glLightModel functions? if (m_set_two_side_light_enable)
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, m_set_two_side_light_enable ? GL_TRUE : GL_FALSE); {
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
checkForGlError("glLightModeli"); checkForGlError("glLightModeli");
}
if (m_set_shade_mode) if (m_set_shade_mode)
{ {
@ -2007,6 +1963,7 @@ void GLGSRender::ExecCMD()
} }
m_vao.Bind(); 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); LoadVertexData(m_indexed_array.index_min, m_indexed_array.index_max - m_indexed_array.index_min + 1);
@ -2056,31 +2013,12 @@ void GLGSRender::ExecCMD()
void GLGSRender::Flip() void GLGSRender::Flip()
{ {
// Set scissor to FBO size
if (m_set_scissor_horizontal && m_set_scissor_vertical) if (m_set_scissor_horizontal && m_set_scissor_vertical)
{ {
glScissor(0, 0, RSXThread::m_width, RSXThread::m_height); glScissor(0, 0, RSXThread::m_width, RSXThread::m_height);
checkForGlError("glScissor"); 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;
case CELL_GCM_SURFACE_TARGET_NONE:
{
// Slow path for MRT/None target using glReadPixels.
static u8* src_buffer = nullptr; static u8* src_buffer = nullptr;
static u32 width = 0; static u32 width = 0;
static u32 height = 0; static u32 height = 0;
@ -2127,7 +2065,9 @@ void GLGSRender::Flip()
height = RSXThread::m_height; height = RSXThread::m_height;
} }
else else
{
src_buffer = nullptr; src_buffer = nullptr;
}
if (src_buffer) if (src_buffer)
{ {
@ -2162,20 +2102,14 @@ void GLGSRender::Flip()
glBegin(GL_QUADS); glBegin(GL_QUADS);
glTexCoord2i(0, 1); glTexCoord2i(0, 1);
glVertex2i(0, 0); glVertex2i(0, 0);
glTexCoord2i(1, 1); glTexCoord2i(1, 1);
glVertex2i(1, 0); glVertex2i(1, 0);
glTexCoord2i(1, 0); glTexCoord2i(1, 0);
glVertex2i(1, 1); glVertex2i(1, 1);
glTexCoord2i(0, 0); glTexCoord2i(0, 0);
glVertex2i(0, 1); glVertex2i(0, 1);
glEnd(); glEnd();
} }
}
break;
}
// Draw Objects // Draw Objects
for (uint i = 0; i < m_post_draw_objs.size(); ++i) for (uint i = 0; i < m_post_draw_objs.size(); ++i)
@ -2199,19 +2133,22 @@ u32 LinearToSwizzleAddress(u32 x, u32 y, u32 z, u32 log2_width, u32 log2_height,
u32 offset = 0; u32 offset = 0;
u32 shift_count = 0; u32 shift_count = 0;
while (log2_width | log2_height | log2_depth){ while (log2_width | log2_height | log2_depth){
if(log2_width){ if (log2_width)
{
offset |= (x & 0x01) << shift_count; offset |= (x & 0x01) << shift_count;
x >>= 1; x >>= 1;
++shift_count; ++shift_count;
--log2_width; --log2_width;
} }
if(log2_height){ if (log2_height)
{
offset |= (y & 0x01) << shift_count; offset |= (y & 0x01) << shift_count;
y >>= 1; y >>= 1;
++shift_count; ++shift_count;
--log2_height; --log2_height;
} }
if(log2_depth){ if (log2_depth)
{
offset |= (z & 0x01) << shift_count; offset |= (z & 0x01) << shift_count;
z >>= 1; z >>= 1;
++shift_count; ++shift_count;

View File

@ -190,7 +190,11 @@ protected:
virtual void OnInitThread(); virtual void OnInitThread();
virtual void OnExitThread(); virtual void OnExitThread();
virtual void OnReset(); virtual void OnReset();
virtual void ExecCMD(u32 cmd);
virtual void ExecCMD(); 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(); virtual void Flip();
}; };

View File

@ -31,7 +31,23 @@ private:
{ {
} }
virtual void ExecCMD(u32 cmd) 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)
{ {
} }

View File

@ -15,33 +15,41 @@
u32 methodRegisters[0xffff]; u32 methodRegisters[0xffff];
void RSXThread::nativeRescale(float width, float height) void RSXThread::NativeRescale(float width, float height)
{ {
switch (Ini.GSResolution.GetValue()) switch (Ini.GSResolution.GetValue())
{ {
case 1: // 1920x1080 window size case 1: // 1920x1080 window size
{
m_width_scale = 1920 / width * 2.0f; m_width_scale = 1920 / width * 2.0f;
m_height_scale = 1080 / height * 2.0f; m_height_scale = 1080 / height * 2.0f;
m_width = 1920; m_width = 1920;
m_height = 1080; m_height = 1080;
}
break; break;
case 2: // 1280x720 window size case 2: // 1280x720 window size
{
m_width_scale = 1280 / width * 2.0f; m_width_scale = 1280 / width * 2.0f;
m_height_scale = 720 / height * 2.0f; m_height_scale = 720 / height * 2.0f;
m_width = 1280; m_width = 1280;
m_height = 720; m_height = 720;
}
break; break;
case 4: // 720x480 window size case 4: // 720x480 window size
{
m_width_scale = 720 / width * 2.0f; m_width_scale = 720 / width * 2.0f;
m_height_scale = 480 / height * 2.0f; m_height_scale = 480 / height * 2.0f;
m_width = 720; m_width = 720;
m_height = 480; m_height = 480;
}
break; break;
case 5: // 720x576 window size case 5: // 720x576 window size
{
m_width_scale = 720 / width * 2.0f; m_width_scale = 720 / width * 2.0f;
m_height_scale = 576 / height * 2.0f; m_height_scale = 576 / height * 2.0f;
m_width = 720; m_width = 720;
m_height = 576; m_height = 576;
}
break; break;
} }
} }
@ -532,13 +540,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
// Color Mask // Color Mask
case NV4097_SET_COLOR_MASK: case NV4097_SET_COLOR_MASK:
{ {
const u32 a0 = ARGS(0); const u32 mask = ARGS(0);
ColorMask(mask & 0x1000000, mask & 0x1000000, mask & 0x1000000, mask & 0x0000001);
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;
} }
break; break;
@ -866,35 +869,26 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
case NV4097_CLEAR_SURFACE: case NV4097_CLEAR_SURFACE:
{ {
const u32 a0 = ARGS(0); const u32 mask = ARGS(0);
if(a0 & 0x01) m_clear_surface_z = m_clear_z; ClearSurface(mask);
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);
} }
break; break;
case NV4097_SET_ZSTENCIL_CLEAR_VALUE: case NV4097_SET_ZSTENCIL_CLEAR_VALUE:
{ {
const u32 a0 = ARGS(0); const u32 value = ARGS(0);
m_clear_s = a0 & 0xff;
m_clear_z = a0 >> 8; ClearStencil(value & 0xff);
ClearDepth(value >> 8);
} }
break; break;
case NV4097_SET_COLOR_CLEAR_VALUE: case NV4097_SET_COLOR_CLEAR_VALUE:
{ {
const u32 color = ARGS(0); const u32 color = ARGS(0);
m_clear_color_a = (color >> 24) & 0xff;
m_clear_color_r = (color >> 16) & 0xff; ClearColor((color >> 24) & 0xff, (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
m_clear_color_g = (color >> 8) & 0xff;
m_clear_color_b = color & 0xff;
} }
break; break;
@ -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_width = buffers[m_gcm_current_buffer].width;
m_height = buffers[m_gcm_current_buffer].height; m_height = buffers[m_gcm_current_buffer].height;
nativeRescale((float)m_width, (float)m_height); NativeRescale((float)m_width, (float)m_height);
} }
break; break;
@ -2280,18 +2274,18 @@ void RSXThread::End()
ExecCMD(); ExecCMD();
for (auto &vdata : m_vertex_data) for (auto &vdata : m_vertex_data)
{
vdata.data.clear(); vdata.data.clear();
}
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_shader_prog_num = 0;
//m_cur_shader_prog = nullptr;
m_clear_surface_mask = 0; m_clear_surface_mask = 0;
m_begin_end = 0; m_begin_end = 0;
//Reset();
OnReset(); OnReset();
} }
@ -2368,15 +2362,13 @@ void RSXThread::Task()
continue; continue;
} }
//ConLog.Write("addr = 0x%x", m_ioAddress + get);
const u32 cmd = ReadIO32(get); const u32 cmd = ReadIO32(get);
const u32 count = (cmd >> 18) & 0x7ff; const u32 count = (cmd >> 18) & 0x7ff;
//if(cmd == 0) continue;
if (Ini.RSXLogging.GetValue()) if (Ini.RSXLogging.GetValue())
{
LOG_NOTICE(Log::RSX, "%s (cmd=0x%x)", GetMethodName(cmd & 0xffff).c_str(), cmd); 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)
{ {
@ -2385,27 +2377,28 @@ void RSXThread::Task()
m_ctrl->get.exchange(be_t<u32>::make(offs)); m_ctrl->get.exchange(be_t<u32>::make(offs));
continue; continue;
} }
if (cmd & CELL_GCM_METHOD_FLAG_CALL) if (cmd & CELL_GCM_METHOD_FLAG_CALL)
{ {
m_call_stack.push(get + 4); m_call_stack.push(get + 4);
u32 offs = cmd & ~3; u32 offs = cmd & ~3;
//u32 addr = offs;
//LOG_WARNING(RSX, "rsx call(0x%x) #0x%x - 0x%x", offs, cmd, get); //LOG_WARNING(RSX, "rsx call(0x%x) #0x%x - 0x%x", offs, cmd, get);
m_ctrl->get.exchange(be_t<u32>::make(offs)); m_ctrl->get.exchange(be_t<u32>::make(offs));
continue; 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(); u32 get = m_call_stack.top();
m_call_stack.pop(); m_call_stack.pop();
//LOG_WARNING(RSX, "rsx return(0x%x)", get); //LOG_WARNING(RSX, "rsx return(0x%x)", get);
m_ctrl->get.exchange(be_t<u32>::make(get)); m_ctrl->get.exchange(be_t<u32>::make(get));
continue; 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; inc = 0;
} }
@ -2431,13 +2424,14 @@ void RSXThread::Task()
{ {
value += (count + 1) * 4; value += (count + 1) * 4;
}); });
//memset(Memory.GetMemFromAddr(p.m_ioAddress + get), 0, (count + 1) * 4);
} }
catch (const std::string& e) catch (const std::string& e)
{ {
LOG_ERROR(RSX, "Exception: %s", e.c_str()); LOG_ERROR(RSX, "Exception: %s", e.c_str());
Emu.Pause(); Emu.Pause();
} }
catch (const char* e) catch (const char* e)
{ {
LOG_ERROR(RSX, "Exception: %s", e); LOG_ERROR(RSX, "Exception: %s", e);

View File

@ -519,7 +519,10 @@ protected:
m_line_stipple_factor = 1; m_line_stipple_factor = 1;
m_vertex_data_base_offset = 0; m_vertex_data_base_offset = 0;
m_vertex_data_base_index = 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; m_polygon_stipple_pattern[i] = 0xFFFFFFFF;
} }
@ -622,14 +625,18 @@ protected:
u32 OutOfArgsCount(const uint x, const u32 cmd, const u32 count, const u32 args_addr); 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 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 OnInit() = 0;
virtual void OnInitThread() = 0; virtual void OnInitThread() = 0;
virtual void OnExitThread() = 0; virtual void OnExitThread() = 0;
virtual void OnReset() = 0; virtual void OnReset() = 0;
virtual void ExecCMD() = 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; virtual void Flip() = 0;
void LoadVertexData(u32 first, u32 count) void LoadVertexData(u32 first, u32 count)