From 384cb5e4153d79896fac17d1ec4a6082227c042e Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Sat, 31 Jan 2015 16:01:34 +0300 Subject: [PATCH] RSX "refactoring" reverted --- rpcs3/Emu/RSX/GL/GLGSRender.cpp | 1077 ++++++++++++++++------------- rpcs3/Emu/RSX/GL/GLGSRender.h | 41 +- rpcs3/Emu/RSX/Null/NullGSRender.h | 84 ++- rpcs3/Emu/RSX/RSXThread.cpp | 969 +++++++++++++------------- rpcs3/Emu/RSX/RSXThread.h | 46 +- 5 files changed, 1104 insertions(+), 1113 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index 35ec0a7dc5..1b3df4a0bd 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -18,9 +18,9 @@ void SetGetGSFrameCallback(GetGSFrameCb value) #define DUMP_VERTEX_DATA 0 #if CMD_DEBUG - #define CMD_LOG(...) LOG_NOTICE(RSX, __VA_ARGS__) +#define CMD_LOG(...) LOG_NOTICE(RSX, __VA_ARGS__) #else - #define CMD_LOG(...) +#define CMD_LOG(...) #endif GLuint g_flip_tex, g_depth_tex, g_pbo[6]; @@ -41,7 +41,7 @@ void printGlError(GLenum err, const std::string& situation) } #if 0 - #define checkForGlError(x) /*x*/ +#define checkForGlError(x) /*x*/ #endif void GLTexture::Create() @@ -110,9 +110,9 @@ void GLTexture::Init(RSXTexture& tex) LOG_ERROR(RSX, "Bad texture address=0x%x", texaddr); return; } - //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", + //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"); @@ -134,10 +134,11 @@ void GLTexture::Init(RSXTexture& tex) static const GLint swizzleMaskB8[] = { GL_BLUE, GL_BLUE, GL_BLUE, GL_BLUE }; glRemap = swizzleMaskB8; + break; } - break; case CELL_GCM_TEXTURE_A1R5G5B5: + { glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); checkForGlError("GLTexture::Init() -> glPixelStorei"); @@ -147,7 +148,8 @@ void GLTexture::Init(RSXTexture& tex) glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_A1R5G5B5)"); - break; + break; + } case CELL_GCM_TEXTURE_A4R4G4B4: { @@ -157,8 +159,8 @@ void GLTexture::Init(RSXTexture& tex) // We read it in as R4G4B4A4, so we need to remap each component. static const GLint swizzleMaskA4R4G4B4[] = { GL_BLUE, GL_ALPHA, GL_RED, GL_GREEN }; glRemap = swizzleMaskA4R4G4B4; + break; } - break; case CELL_GCM_TEXTURE_R5G6B5: { @@ -170,8 +172,8 @@ void GLTexture::Init(RSXTexture& tex) glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_R5G6B5)"); + break; } - break; case CELL_GCM_TEXTURE_A8R8G8B8: { @@ -195,11 +197,11 @@ void GLTexture::Init(RSXTexture& tex) } } } - + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, is_swizzled ? unswizzledPixels : pixels); checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_A8R8G8B8)"); + break; } - break; case CELL_GCM_TEXTURE_COMPRESSED_DXT1: // Compressed 4x4 pixels into 8 bytes { @@ -207,8 +209,8 @@ void GLTexture::Init(RSXTexture& tex) glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, tex.GetWidth(), tex.GetHeight(), 0, size, pixels); checkForGlError("GLTexture::Init() -> glCompressedTexImage2D(CELL_GCM_TEXTURE_COMPRESSED_DXT1)"); + break; } - break; case CELL_GCM_TEXTURE_COMPRESSED_DXT23: // Compressed 4x4 pixels into 16 bytes { @@ -217,7 +219,7 @@ void GLTexture::Init(RSXTexture& tex) glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, tex.GetWidth(), tex.GetHeight(), 0, size, pixels); checkForGlError("GLTexture::Init() -> glCompressedTexImage2D(CELL_GCM_TEXTURE_COMPRESSED_DXT23)"); } - break; + break; case CELL_GCM_TEXTURE_COMPRESSED_DXT45: // Compressed 4x4 pixels into 16 bytes { @@ -225,8 +227,8 @@ void GLTexture::Init(RSXTexture& tex) glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, tex.GetWidth(), tex.GetHeight(), 0, size, pixels); checkForGlError("GLTexture::Init() -> glCompressedTexImage2D(CELL_GCM_TEXTURE_COMPRESSED_DXT45)"); + break; } - break; case CELL_GCM_TEXTURE_G8B8: { @@ -235,8 +237,8 @@ void GLTexture::Init(RSXTexture& tex) static const GLint swizzleMaskG8B8[] = { GL_RED, GL_GREEN, GL_RED, GL_GREEN }; glRemap = swizzleMaskG8B8; + break; } - break; case CELL_GCM_TEXTURE_R6G5B5: { @@ -256,36 +258,36 @@ void GLTexture::Init(RSXTexture& tex) checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_R6G5B5)"); free(unswizzledPixels); + break; } - break; case CELL_GCM_TEXTURE_DEPTH24_D8: // 24-bit unsigned fixed-point number and 8 bits of garbage { glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, tex.GetWidth(), tex.GetHeight(), 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, pixels); checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_DEPTH24_D8)"); + break; } - break; case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT: // 24-bit unsigned float and 8 bits of garbage { glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, tex.GetWidth(), tex.GetHeight(), 0, GL_DEPTH_COMPONENT, GL_FLOAT, pixels); checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT)"); + break; } - break; case CELL_GCM_TEXTURE_DEPTH16: // 16-bit unsigned fixed-point number { glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, tex.GetWidth(), tex.GetHeight(), 0, GL_DEPTH_COMPONENT, GL_SHORT, pixels); checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_DEPTH16)"); + break; } - break; case CELL_GCM_TEXTURE_DEPTH16_FLOAT: // 16-bit unsigned float { glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, tex.GetWidth(), tex.GetHeight(), 0, GL_DEPTH_COMPONENT, GL_FLOAT, pixels); checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_DEPTH16_FLOAT)"); + break; } - break; case CELL_GCM_TEXTURE_X16: // A 16-bit fixed-point number { @@ -300,8 +302,8 @@ void GLTexture::Init(RSXTexture& tex) static const GLint swizzleMaskX16[] = { GL_RED, GL_ONE, GL_RED, GL_ONE }; glRemap = swizzleMaskX16; + break; } - break; case CELL_GCM_TEXTURE_Y16_X16: // Two 16-bit fixed-point numbers { @@ -316,8 +318,8 @@ void GLTexture::Init(RSXTexture& tex) static const GLint swizzleMaskX32_Y16_X16[] = { GL_GREEN, GL_RED, GL_GREEN, GL_RED }; glRemap = swizzleMaskX32_Y16_X16; + break; } - break; case CELL_GCM_TEXTURE_R5G5B5A1: { @@ -329,8 +331,8 @@ void GLTexture::Init(RSXTexture& tex) glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_R5G5B5A1)"); + break; } - break; case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: // Four fp16 values { @@ -342,15 +344,15 @@ void GLTexture::Init(RSXTexture& tex) glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT)"); + break; } - break; case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT: // Four fp32 values { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_BGRA, GL_FLOAT, pixels); checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT)"); + break; } - break; case CELL_GCM_TEXTURE_X32_FLOAT: // One 32-bit floating-point number { @@ -359,8 +361,8 @@ void GLTexture::Init(RSXTexture& tex) static const GLint swizzleMaskX32_FLOAT[] = { GL_RED, GL_ONE, GL_ONE, GL_ONE }; glRemap = swizzleMaskX32_FLOAT; + break; } - break; case CELL_GCM_TEXTURE_D1R5G5B5: { @@ -376,8 +378,8 @@ void GLTexture::Init(RSXTexture& tex) glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_D1R5G5B5)"); + break; } - break; case CELL_GCM_TEXTURE_D8R8G8B8: // 8 bits of garbage and three unsigned 8-bit fixed-point numbers { @@ -386,8 +388,9 @@ void GLTexture::Init(RSXTexture& tex) static const GLint swizzleMaskX32_D8R8G8B8[] = { GL_ONE, GL_RED, GL_GREEN, GL_BLUE }; glRemap = swizzleMaskX32_D8R8G8B8; + break; } - break; + case CELL_GCM_TEXTURE_Y16_X16_FLOAT: // Two fp16 values { @@ -402,15 +405,16 @@ void GLTexture::Init(RSXTexture& tex) static const GLint swizzleMaskX32_Y16_X16_FLOAT[] = { GL_RED, GL_GREEN, GL_RED, GL_GREEN }; glRemap = swizzleMaskX32_Y16_X16_FLOAT; + break; } - break; - case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8 & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN): + case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: { const u32 numPixels = tex.GetWidth() * tex.GetHeight(); unswizzledPixels = (u8 *)malloc(numPixels * 4); // TODO: Speed. - for (u32 i = 0; i < numPixels; i += 2) { + for (u32 i = 0; i < numPixels; i += 2) + { unswizzledPixels[i * 4 + 0 + 0] = pixels[i * 2 + 3]; unswizzledPixels[i * 4 + 0 + 1] = pixels[i * 2 + 2]; unswizzledPixels[i * 4 + 0 + 2] = pixels[i * 2 + 0]; @@ -427,15 +431,16 @@ void GLTexture::Init(RSXTexture& tex) checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8 & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN)"); free(unswizzledPixels); + break; } - break; - case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8 & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN): + case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: { const u32 numPixels = tex.GetWidth() * tex.GetHeight(); unswizzledPixels = (u8 *)malloc(numPixels * 4); // TODO: Speed. - for (u32 i = 0; i < numPixels; i += 2) { + for (u32 i = 0; i < numPixels; i += 2) + { unswizzledPixels[i * 4 + 0 + 0] = pixels[i * 2 + 2]; unswizzledPixels[i * 4 + 0 + 1] = pixels[i * 2 + 3]; unswizzledPixels[i * 4 + 0 + 2] = pixels[i * 2 + 1]; @@ -452,13 +457,16 @@ void GLTexture::Init(RSXTexture& tex) checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8 & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN)"); free(unswizzledPixels); - } - break; - - default: LOG_ERROR(RSX, "Init tex error: Bad tex format (0x%x | %s | 0x%x)", format, (is_swizzled ? "swizzled" : "linear"), tex.GetFormat() & 0x40); break; } + default: + { + LOG_ERROR(RSX, "Init tex error: Bad tex format (0x%x | %s | 0x%x)", format, (is_swizzled ? "swizzled" : "linear"), tex.GetFormat() & 0x40); + break; + } + } + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, tex.GetMipmap() - 1); glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, tex.GetMipmap() > 1); @@ -746,7 +754,7 @@ void DrawCursorObj::InitializeShaders() " gl_Position = in_pos;\n" "}\n"; - m_fp.shader = + m_fp.shader = "#version 420\n" "\n" "in vec2 tc;\n" @@ -797,6 +805,18 @@ GLGSRender::~GLGSRender() m_frame->DeleteContext(m_context); } +void GLGSRender::Enable(bool enable, const u32 cap) +{ + if (enable) + { + glEnable(cap); + } + else + { + glDisable(cap); + } +} + extern CellGcmContextData current_context; void GLGSRender::Close() @@ -887,58 +907,58 @@ void GLGSRender::EnableVertexData(bool indexed_draw) 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; + 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; + 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; + break; case CELL_GCM_VERTEX_UB: 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; + 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: - + break; + + // case CELL_GCM_VERTEX_CMP: + case CELL_GCM_VERTEX_UB256: 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; + break; default: LOG_ERROR(HLE, "Bad cv type! %d", m_vertex_data[i].type); - return; + return; } dump.Write("\n"); @@ -966,7 +986,7 @@ 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); } @@ -984,7 +1004,7 @@ void GLGSRender::EnableVertexData(bool indexed_draw) case 3: glVertexAttrib3sv(i, (GLshort*)&m_vertex_data[i].data[0]); break; case 4: glVertexAttrib4sv(i, (GLshort*)&m_vertex_data[i].data[0]); break; } - break; + break; case CELL_GCM_VERTEX_F: switch (m_vertex_data[i].size) @@ -994,12 +1014,12 @@ void GLGSRender::EnableVertexData(bool indexed_draw) case 3: glVertexAttrib3fv(i, (GLfloat*)&m_vertex_data[i].data[0]); break; case 4: glVertexAttrib4fv(i, (GLfloat*)&m_vertex_data[i].data[0]); break; } - break; + break; case CELL_GCM_VERTEX_CMP: case CELL_GCM_VERTEX_UB: glVertexAttrib4ubv(i, (GLubyte*)&m_vertex_data[i].data[0]); - break; + break; } checkForGlError("glVertexAttrib"); @@ -1034,9 +1054,9 @@ void GLGSRender::InitVertexData() int l; GLfloat scaleOffsetMat[16] = { - 1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }; @@ -1076,7 +1096,7 @@ void GLGSRender::InitFragmentData() return; } - for (const RSXTransformConstant& c : m_fragment_constants) + for (const RSXTransformConstant& c : m_fragment_constants) { u32 id = c.id - m_cur_fragment_prog->offset; @@ -1101,15 +1121,15 @@ bool GLGSRender::LoadProgram() LOG_WARNING(RSX, "LoadProgram: m_cur_shader_prog == NULL"); return false; } - + m_cur_fragment_prog->ctrl = m_shader_ctrl; - + if (!m_cur_vertex_prog) { LOG_WARNING(RSX, "LoadProgram: m_cur_vertex_prog == NULL"); return false; } - + 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); @@ -1391,14 +1411,14 @@ void GLGSRender::WriteColorBuffers() glBufferData(GL_PIXEL_PACK_BUFFER, RSXThread::m_width * RSXThread::m_height * 4, 0, GL_STREAM_READ); glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); WriteColorBufferA(); - break; + break; case CELL_GCM_SURFACE_TARGET_1: glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[1]); glBufferData(GL_PIXEL_PACK_BUFFER, RSXThread::m_width * RSXThread::m_height * 4, 0, GL_STREAM_READ); glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); WriteColorBufferB(); - break; + break; case CELL_GCM_SURFACE_TARGET_MRT1: for (int i = 0; i < 2; i++) @@ -1409,7 +1429,7 @@ void GLGSRender::WriteColorBuffers() glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); WriteColorBufferA(); WriteColorBufferB(); - break; + break; case CELL_GCM_SURFACE_TARGET_MRT2: for (int i = 0; i < 3; i++) @@ -1421,7 +1441,7 @@ void GLGSRender::WriteColorBuffers() WriteColorBufferA(); WriteColorBufferB(); WriteColorBufferC(); - break; + break; case CELL_GCM_SURFACE_TARGET_MRT3: for (int i = 0; i < 4; i++) @@ -1434,7 +1454,7 @@ void GLGSRender::WriteColorBuffers() WriteColorBufferB(); WriteColorBufferC(); WriteColorBufferD(); - break; + break; } } @@ -1480,7 +1500,7 @@ void GLGSRender::OnExitThread() glDeleteTextures(1, &g_flip_tex); glDeleteTextures(1, &g_depth_tex); glDeleteBuffers(6, g_pbo); - + glDisable(GL_TEXTURE_2D); glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); @@ -1530,15 +1550,31 @@ void GLGSRender::InitDrawBuffers() m_rbo.Bind(4); - if (m_surface_depth_format == CELL_GCM_SURFACE_Z16) + switch (m_surface_depth_format) + { + case 0: + { + // 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 + 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)"); m_fbo.Renderbuffer(GL_DEPTH_ATTACHMENT, m_rbo.GetId(4)); checkForGlError("m_fbo.Renderbuffer(GL_DEPTH_ATTACHMENT)"); + break; } - else if (m_surface_depth_format == CELL_GCM_SURFACE_Z24S8) + + + case CELL_GCM_SURFACE_Z24S8: { m_rbo.Storage(GL_DEPTH24_STENCIL8, RSXThread::m_width, RSXThread::m_height); checkForGlError("m_rbo.Storage(GL_DEPTH24_STENCIL8)"); @@ -1548,6 +1584,18 @@ void GLGSRender::InitDrawBuffers() m_fbo.Renderbuffer(GL_STENCIL_ATTACHMENT, m_rbo.GetId(4)); checkForGlError("m_fbo.Renderbuffer(GL_STENCIL_ATTACHMENT)"); + + break; + + } + + + default: + { + LOG_ERROR(RSX, "Bad depth format! (%d)", m_surface_depth_format); + assert(0); + break; + } } for (int i = 0; i < 4; ++i) @@ -1555,6 +1603,15 @@ void GLGSRender::InitDrawBuffers() m_fbo.Renderbuffer(GL_COLOR_ATTACHMENT0 + i, m_rbo.GetId(i)); checkForGlError(fmt::Format("m_fbo.Renderbuffer(GL_COLOR_ATTACHMENT%d)", i)); } + + //m_fbo.Renderbuffer(GL_DEPTH_ATTACHMENT, m_rbo.GetId(4)); + //checkForGlError("m_fbo.Renderbuffer(GL_DEPTH_ATTACHMENT)"); + + //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) @@ -1568,41 +1625,56 @@ void GLGSRender::InitDrawBuffers() m_surface_clip_y = 0; m_surface_clip_h = RSXThread::m_height; } - + m_fbo.Bind(); static const GLenum draw_buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 }; switch (m_surface_color_target) { - case CELL_GCM_SURFACE_TARGET_NONE: - break; + case CELL_GCM_SURFACE_TARGET_NONE: break; case CELL_GCM_SURFACE_TARGET_0: + { glDrawBuffer(draw_buffers[0]); - break; - + checkForGlError("glDrawBuffer(0)"); + break; + } + case CELL_GCM_SURFACE_TARGET_1: + { glDrawBuffer(draw_buffers[1]); - break; - + checkForGlError("glDrawBuffer(1)"); + break; + } + case CELL_GCM_SURFACE_TARGET_MRT1: + { glDrawBuffers(2, draw_buffers); - break; - + checkForGlError("glDrawBuffers(2)"); + break; + } + case CELL_GCM_SURFACE_TARGET_MRT2: + { glDrawBuffers(3, draw_buffers); - break; + checkForGlError("glDrawBuffers(3)"); + break; + } case CELL_GCM_SURFACE_TARGET_MRT3: + { glDrawBuffers(4, draw_buffers); - break; - - checkForGlError("glDrawBuffers"); + checkForGlError("glDrawBuffers(4)"); + break; + } default: + { LOG_ERROR(RSX, "Bad surface color target: %d", m_surface_color_target); - break; + break; + } + } if (m_read_buffer) @@ -1621,326 +1693,63 @@ void GLGSRender::InitDrawBuffers() } } -void GLGSRender::Enable(u32 cmd, u32 enable) +void GLGSRender::ExecCMD(u32 cmd) { - switch (cmd) - { - case NV4097_SET_DITHER_ENABLE: - enable ? glEnable(GL_DITHER) : glDisable(GL_DITHER); - break; + assert(cmd == NV4097_CLEAR_SURFACE); - case NV4097_SET_ALPHA_TEST_ENABLE: - enable ? glEnable(GL_ALPHA_TEST) : glDisable(GL_ALPHA_TEST); - break; - - case NV4097_SET_STENCIL_TEST_ENABLE: - enable ? glEnable(GL_STENCIL_TEST) : glDisable(GL_STENCIL_TEST); - break; - - case NV4097_SET_DEPTH_TEST_ENABLE: - enable ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST); - break; - - case NV4097_SET_CULL_FACE_ENABLE: - enable ? glEnable(GL_CULL_FACE) : glDisable(GL_CULL_FACE); - break; - - case NV4097_SET_BLEND_ENABLE: - enable ? glEnable(GL_BLEND) : glDisable(GL_BLEND); - break; - - case NV4097_SET_POLY_OFFSET_FILL_ENABLE: - enable ? glEnable(GL_POLYGON_OFFSET_FILL) : glDisable(GL_POLYGON_OFFSET_FILL); - break; - - case NV4097_SET_POLY_OFFSET_LINE_ENABLE: - enable ? glEnable(GL_POLYGON_OFFSET_LINE) : glDisable(GL_POLYGON_OFFSET_LINE); - break; - - case NV4097_SET_POLY_OFFSET_POINT_ENABLE: - enable ? glEnable(GL_POLYGON_OFFSET_POINT) : glDisable(GL_POLYGON_OFFSET_POINT); - break; - - case NV4097_SET_LOGIC_OP_ENABLE: - enable ? glEnable(GL_LOGIC_OP) : glDisable(GL_LOGIC_OP); - break; - - case NV4097_SET_SPECULAR_ENABLE: - enable ? glEnable(GL_LIGHTING) : glDisable(GL_LIGHTING); - break; - - case NV4097_SET_LINE_SMOOTH_ENABLE: - enable ? glEnable(GL_LINE_SMOOTH) : glDisable(GL_LINE_SMOOTH); - break; - - case NV4097_SET_POLY_SMOOTH_ENABLE: - enable ? glEnable(GL_POLYGON_SMOOTH) : glDisable(GL_POLYGON_SMOOTH); - break; - - case NV4097_SET_RESTART_INDEX_ENABLE: - enable ? glEnable(GL_PRIMITIVE_RESTART) : glDisable(GL_PRIMITIVE_RESTART); - break; - - case NV4097_SET_POINT_SPRITE_CONTROL: - enable ? glEnable(GL_POINT_SPRITE) : glDisable(GL_POINT_SPRITE); - break; - - case NV4097_SET_LINE_STIPPLE: - enable ? glEnable(GL_LINE_STIPPLE) : glDisable(GL_LINE_STIPPLE); - break; - - case NV4097_SET_POLYGON_STIPPLE: - enable ? glEnable(GL_POLYGON_STIPPLE) : glDisable(GL_POLYGON_STIPPLE); - break; - - case NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE: - enable ? glEnable(GL_DEPTH_BOUNDS_TEST_EXT) : glDisable(GL_DEPTH_BOUNDS_TEST_EXT); - break; - - case NV4097_SET_TWO_SIDED_STENCIL_TEST_ENABLE: - enable ? glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT) : glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT); - break; - - case NV4097_SET_USER_CLIP_PLANE_CONTROL: - const u32 clip_plane_0 = enable & 0xf; - const u32 clip_plane_1 = (enable >> 4) & 0xf; - const u32 clip_plane_2 = (enable >> 8) & 0xf; - const u32 clip_plane_3 = (enable >> 12) & 0xf; - const u32 clip_plane_4 = (enable >> 16) & 0xf; - const u32 clip_plane_5 = enable >> 20; - - clip_plane_0 ? glEnable(GL_CLIP_PLANE0) : glDisable(GL_CLIP_PLANE0); - clip_plane_1 ? glEnable(GL_CLIP_PLANE1) : glDisable(GL_CLIP_PLANE1); - clip_plane_2 ? glEnable(GL_CLIP_PLANE2) : glDisable(GL_CLIP_PLANE2); - clip_plane_3 ? glEnable(GL_CLIP_PLANE3) : glDisable(GL_CLIP_PLANE3); - clip_plane_4 ? glEnable(GL_CLIP_PLANE4) : glDisable(GL_CLIP_PLANE4); - clip_plane_5 ? glEnable(GL_CLIP_PLANE5) : glDisable(GL_CLIP_PLANE5); - break; - } -} - -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) -{ InitDrawBuffers(); - 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); + 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"); WriteBuffers(); } -void GLGSRender::ColorMask(bool a, bool r, bool g, bool b) -{ - glColorMask(r, g, b, a); - checkForGlError("glColorMask"); -} - -void GLGSRender::AlphaFunc(u32 func, float ref) -{ - glAlphaFunc(func, ref); - checkForGlError("glAlphaFunc"); -} - -void GLGSRender::DepthFunc(u32 func) -{ - glDepthFunc(func); - checkForGlError("glDepthFunc"); -} - -void GLGSRender::DepthMask(u32 flag) -{ - glDepthMask(flag); - checkForGlError("glDepthMask"); -} - -void GLGSRender::PolygonMode(u32 face, u32 mode) -{ - switch (face) - { - case NV4097_SET_FRONT_POLYGON_MODE: - glPolygonMode(GL_FRONT, mode); - break; - case NV4097_SET_BACK_POLYGON_MODE: - glPolygonMode(GL_BACK, mode); - break; - } - checkForGlError("glPolygonMode"); -} - -void GLGSRender::PointSize(float size) -{ - glPointSize(m_point_size); - checkForGlError("glPointSize"); -} - -void GLGSRender::LogicOp(u32 opcode) -{ - glLogicOp(opcode); - checkForGlError("glLogicOp"); -} - -void GLGSRender::LineWidth(float width) -{ - glLineWidth(width); - checkForGlError("glLineWidth"); -} - -void GLGSRender::LineStipple(u16 factor, u16 pattern) -{ - glLineStipple(factor, pattern); - checkForGlError("glLineStipple"); -} - -void GLGSRender::PolygonStipple(u32 pattern) -{ - glPolygonStipple((const GLubyte*)pattern); - checkForGlError("glPolygonStipple"); -} - -void GLGSRender::PrimitiveRestartIndex(u32 index) -{ - glPrimitiveRestartIndex(index); - checkForGlError("glPrimitiveRestartIndex"); -} - -void GLGSRender::CullFace(u32 mode) -{ - glCullFace(mode); - checkForGlError("glCullFace"); -} - -void GLGSRender::FrontFace(u32 mode) -{ - glFrontFace(mode); - checkForGlError("glFrontFace"); -} - -void GLGSRender::Fogi(u32 mode) -{ - glFogi(GL_FOG_MODE, mode); - checkForGlError("glFogi(GL_FOG_MODE)"); -} - -void GLGSRender::Fogf(float start, float end) -{ - glFogf(GL_FOG_START, start); - checkForGlError("glFogf(GL_FOG_START)"); - glFogf(GL_FOG_END, end); - checkForGlError("glFogf(GL_FOG_END)"); -} - -void GLGSRender::PolygonOffset(float factor , float bias) -{ - glPolygonOffset(factor, bias); - checkForGlError("glPolygonOffset"); -} - -void GLGSRender::DepthRangef(float min, float max) -{ - glDepthRangef(min, max); - checkForGlError("glDepthRangef"); -} - -void GLGSRender::BlendEquationSeparate(u16 rgb, u16 a) -{ - glBlendEquationSeparate(rgb, a); - checkForGlError("glBlendEquationSeparate"); -} - -void GLGSRender::BlendFuncSeparate(u16 srcRGB, u16 dstRGB, u16 srcAlpha, u16 dstAlpha) -{ - glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha); - checkForGlError("glBlendFuncSeparate"); -} - -void GLGSRender::BlendColor(u8 r, u8 g, u8 b, u8 a) -{ - glBlendColor(r, g, b, a); - checkForGlError("glBlendColor"); -} - -void GLGSRender::LightModeli(u32 enable) -{ - enable ? glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE) : glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); - checkForGlError("glLightModeli"); -} - -void GLGSRender::ShadeModel(u32 mode) -{ - glShadeModel(m_shade_mode); - checkForGlError("glShadeModel"); -} - -void GLGSRender::DepthBoundsEXT(float min, float max) -{ - glDepthBoundsEXT(min, max); - checkForGlError("glDepthBoundsEXT"); -} - -void GLGSRender::Scissor(u16 x, u16 y, u16 width, u16 height) -{ - glScissor(x, y, width, height); - checkForGlError("glScissor"); -} - -void GLGSRender::StencilOp(u32 fail, u32 zfail, u32 zpass) -{ - glStencilOp(fail, zfail, zpass); - checkForGlError("glStencilOp"); -} - -void GLGSRender::StencilMask(u32 mask) -{ - glStencilMask(mask); - checkForGlError("glStencilMask"); -} - -void GLGSRender::StencilFunc(u32 func, u32 ref, u32 mask) -{ - glStencilFunc(func, ref, mask); - checkForGlError("glStencilFunc"); -} - -void GLGSRender::StencilOpSeparate(u32 mode, u32 fail, u32 zfail, u32 zpass) -{ - mode ? glStencilOpSeparate(GL_FRONT, fail, zfail, zpass) : glStencilOpSeparate(GL_BACK, fail, zfail, zpass); -} - -void GLGSRender::StencilMaskSeparate(u32 mode, u32 mask) -{ - mode ? glStencilMaskSeparate(GL_FRONT, mask) : glStencilMaskSeparate(GL_BACK, mask); -} - -void GLGSRender::StencilFuncSeparate(u32 mode, u32 func, u32 ref, u32 mask) -{ - mode ? glStencilFuncSeparate(GL_FRONT, func, ref, mask) : glStencilFuncSeparate(GL_BACK, func, ref, mask); -} - void GLGSRender::ExecCMD() { + //return; if (!LoadProgram()) { LOG_ERROR(RSX, "LoadProgram failed."); @@ -1949,7 +1758,268 @@ 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"); + } + + if (!m_indexed_array.m_count && !m_draw_array_count) + { + u32 min_vertex_size = ~0; + for (auto &i : m_vertex_data) + { + if (!i.size) + continue; + + u32 vertex_size = i.data.size() / (i.size * i.GetTypeSize()); + + if (min_vertex_size > vertex_size) + min_vertex_size = vertex_size; + } + + m_draw_array_count = min_vertex_size; + m_draw_array_first = 0; + } + + 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); + Enable(m_set_blend || m_set_blend_mrt1 || m_set_blend_mrt2 || m_set_blend_mrt3, GL_BLEND); + Enable(m_set_scissor_horizontal && m_set_scissor_vertical, GL_SCISSOR_TEST); + Enable(m_set_logic_op, GL_LOGIC_OP); + Enable(m_set_cull_face, GL_CULL_FACE); + Enable(m_set_dither, GL_DITHER); + Enable(m_set_stencil_test, GL_STENCIL_TEST); + Enable(m_set_line_smooth, GL_LINE_SMOOTH); + Enable(m_set_poly_smooth, GL_POLYGON_SMOOTH); + Enable(m_set_point_sprite_control, GL_POINT_SPRITE); + Enable(m_set_specular, GL_LIGHTING); + Enable(m_set_poly_offset_fill, GL_POLYGON_OFFSET_FILL); + Enable(m_set_poly_offset_line, GL_POLYGON_OFFSET_LINE); + Enable(m_set_poly_offset_point, GL_POLYGON_OFFSET_POINT); + Enable(m_set_restart_index, GL_PRIMITIVE_RESTART); + Enable(m_set_line_stipple, GL_LINE_STIPPLE); + Enable(m_set_polygon_stipple, GL_POLYGON_STIPPLE); + + if (m_set_clip_plane) + { + Enable(m_clip_plane_0, GL_CLIP_PLANE0); + Enable(m_clip_plane_1, GL_CLIP_PLANE1); + Enable(m_clip_plane_2, GL_CLIP_PLANE2); + Enable(m_clip_plane_3, GL_CLIP_PLANE3); + Enable(m_clip_plane_4, GL_CLIP_PLANE4); + Enable(m_clip_plane_5, GL_CLIP_PLANE5); + + checkForGlError("m_set_clip_plane"); + } + + checkForGlError("glEnable"); + + if (m_set_front_polygon_mode) + { + glPolygonMode(GL_FRONT, m_front_polygon_mode); + checkForGlError("glPolygonMode(Front)"); + } + + if (m_set_back_polygon_mode) + { + glPolygonMode(GL_BACK, m_back_polygon_mode); + checkForGlError("glPolygonMode(Back)"); + } + + if (m_set_point_size) + { + glPointSize(m_point_size); + checkForGlError("glPointSize"); + } + + if (m_set_poly_offset_mode) + { + glPolygonOffset(m_poly_offset_scale_factor, m_poly_offset_bias); + checkForGlError("glPolygonOffset"); + } + + if (m_set_logic_op) + { + glLogicOp(m_logic_op); + checkForGlError("glLogicOp"); + } + + if (m_set_scissor_horizontal && m_set_scissor_vertical) + { + glScissor(m_scissor_x, m_scissor_y, m_scissor_w, m_scissor_h); + checkForGlError("glScissor"); + } + + if (m_set_two_sided_stencil_test_enable) + { + 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) + { + glStencilMaskSeparate(GL_FRONT, m_stencil_mask); + checkForGlError("glStencilMaskSeparate"); + } + + 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) + { + 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) + { + 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) + { + glStencilFuncSeparate(GL_BACK, m_back_stencil_func, m_back_stencil_func_ref, m_back_stencil_func_mask); + checkForGlError("glStencilFuncSeparate(GL_BACK)"); + } + } + else + { + 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) + { + glStencilMask(m_stencil_mask); + checkForGlError("glStencilMask"); + } + + 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_shade_mode) + { + glShadeModel(m_shade_mode); + checkForGlError("glShadeModel"); + } + + if (m_set_depth_mask) + { + glDepthMask(m_depth_mask); + checkForGlError("glDepthMask"); + } + + if (m_set_depth_func) + { + glDepthFunc(m_depth_func); + checkForGlError("glDepthFunc"); + } + + if (m_set_depth_bounds) + { + glDepthBoundsEXT(m_depth_bounds_min, m_depth_bounds_max); + checkForGlError("glDepthBounds"); + } + + if (m_set_clip) + { + glDepthRangef(m_clip_min, m_clip_max); + checkForGlError("glDepthRangef"); + } + + if (m_set_line_width) + { + glLineWidth(m_line_width); + checkForGlError("glLineWidth"); + } + + if (m_set_line_stipple) + { + glLineStipple(m_line_stipple_factor, m_line_stipple_pattern); + checkForGlError("glLineStipple"); + } + + if (m_set_polygon_stipple) + { + glPolygonStipple((const GLubyte*)m_polygon_stipple_pattern); + checkForGlError("glPolygonStipple"); + } + + 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) + { + glBlendFuncSeparate(m_blend_sfactor_rgb, m_blend_dfactor_rgb, m_blend_sfactor_alpha, m_blend_dfactor_alpha); + checkForGlError("glBlendFuncSeparate"); + } + + 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) + { + glCullFace(m_cull_face); + checkForGlError("glCullFace"); + } + + if (m_set_front_face) + { + glFrontFace(m_front_face); + checkForGlError("glFrontFace"); + } + + if (m_set_alpha_func && m_set_alpha_ref) + { + glAlphaFunc(m_alpha_func, m_alpha_ref); + checkForGlError("glAlphaFunc"); + } + + if (m_set_fog_mode) + { + glFogi(GL_FOG_MODE, m_fog_mode); + checkForGlError("glFogi(GL_FOG_MODE)"); + } + + if (m_set_fog_params) + { + glFogf(GL_FOG_START, m_fog_param0); + checkForGlError("glFogf(GL_FOG_START)"); + glFogf(GL_FOG_END, m_fog_param1); + checkForGlError("glFogf(GL_FOG_END)"); + } + + if (m_set_restart_index) + { + glPrimitiveRestartIndex(m_restart_index); + checkForGlError("glPrimitiveRestartIndex"); + } + if (m_indexed_array.m_count && m_draw_array_count) { LOG_WARNING(RSX, "m_indexed_array.m_count && draw_array_count"); @@ -2005,16 +2075,16 @@ void GLGSRender::ExecCMD() case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32: glDrawElements(m_draw_mode - 1, m_indexed_array.m_count, GL_UNSIGNED_INT, nullptr); checkForGlError("glDrawElements #4"); - break; + break; case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16: glDrawElements(m_draw_mode - 1, m_indexed_array.m_count, GL_UNSIGNED_SHORT, nullptr); checkForGlError("glDrawElements #2"); - break; + break; default: LOG_ERROR(RSX, "Bad indexed array type (%d)", m_indexed_array.m_type); - break; + break; } DisableVertexData(); @@ -2028,102 +2098,130 @@ void GLGSRender::ExecCMD() checkForGlError("glDrawArrays"); DisableVertexData(); } - + WriteBuffers(); } void GLGSRender::Flip() { - static u8* src_buffer = nullptr; - static u32 width = 0; - static u32 height = 0; - GLenum format = GL_RGBA; - - if (m_read_buffer) + // Set scissor to FBO size + if (m_set_scissor_horizontal && m_set_scissor_vertical) { - format = GL_BGRA; - CellGcmDisplayInfo* buffers = vm::get_ptr(m_gcm_buffers_addr); - u32 addr = GetAddress(buffers[m_gcm_current_buffer].offset, CELL_GCM_LOCATION_LOCAL); + glScissor(0, 0, RSXThread::m_width, RSXThread::m_height); + checkForGlError("glScissor"); + } - if (Memory.IsGoodAddr(addr)) + 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 u32 width = 0; + static u32 height = 0; + GLenum format = GL_RGBA; + + if (m_read_buffer) { - width = buffers[m_gcm_current_buffer].width; - height = buffers[m_gcm_current_buffer].height; - src_buffer = vm::get_ptr(addr); + format = GL_BGRA; + CellGcmDisplayInfo* buffers = vm::get_ptr(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(addr); + } + else + { + src_buffer = nullptr; + } + } + else if (m_fbo.IsCreated()) + { + format = GL_RGBA; + static std::vector 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; } - } - else if (m_fbo.IsCreated()) - { - format = GL_RGBA; - static std::vector 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) + + if (src_buffer) { - memcpy(pixels.data(), packed, RSXThread::m_width * RSXThread::m_height * 4); - glUnmapBuffer(GL_PIXEL_PACK_BUFFER); - checkForGlError("Flip(): glUnmapBuffer"); + 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(); } - 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(); + break; } // Draw Objects @@ -2133,7 +2231,14 @@ void GLGSRender::Flip() } m_frame->Flip(m_context); - + + // Restore scissor + if (m_set_scissor_horizontal && m_set_scissor_vertical) + { + glScissor(m_scissor_x, m_scissor_y, m_scissor_w, m_scissor_h); + checkForGlError("glScissor"); + } + } u32 LinearToSwizzleAddress(u32 x, u32 y, u32 z, u32 log2_width, u32 log2_height, u32 log2_depth) diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.h b/rpcs3/Emu/RSX/GL/GLGSRender.h index 7ab9f406d1..a509664ded 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.h +++ b/rpcs3/Emu/RSX/GL/GLGSRender.h @@ -21,7 +21,7 @@ u32 LinearToSwizzleAddress(u32 x, u32 y, u32 z, u32 log2_width, u32 log2_height, class GLTexture { u32 m_id; - + public: GLTexture() : m_id(0) { @@ -166,11 +166,12 @@ public: virtual ~GLGSRender(); private: - void EnableVertexData(bool indexed_draw=false); + void EnableVertexData(bool indexed_draw = false); void DisableVertexData(); void InitVertexData(); void InitFragmentData(); + void Enable(bool enable, const u32 cap); virtual void Close(); bool LoadProgram(); void WriteBuffers(); @@ -189,41 +190,7 @@ protected: virtual void OnInitThread(); virtual void OnExitThread(); virtual void OnReset(); + virtual void ExecCMD(u32 cmd); virtual void ExecCMD(); - virtual void Enable(u32 cmd, u32 enable); - 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 AlphaFunc(u32 func, float ref); - virtual void DepthFunc(u32 func); - virtual void DepthMask(u32 flag); - virtual void PolygonMode(u32 face, u32 mode); - virtual void PointSize(float size); - virtual void LogicOp(u32 opcode); - virtual void LineWidth(float width); - virtual void LineStipple(u16 factor, u16 pattern); - virtual void PolygonStipple(u32 pattern); - virtual void PrimitiveRestartIndex(u32 index); - virtual void CullFace(u32 mode); - virtual void FrontFace(u32 mode); - virtual void Fogi(u32 mode); - virtual void Fogf(float start, float end); - virtual void PolygonOffset(float factor, float bias); - virtual void DepthRangef(float min, float max); - virtual void BlendEquationSeparate(u16 rgb, u16 a); - virtual void BlendFuncSeparate(u16 srcRGB, u16 dstRGB, u16 srcAlpha, u16 dstAlpha); - virtual void BlendColor(u8 r, u8 g, u8 b, u8 a); - virtual void LightModeli(u32 enable); - virtual void ShadeModel(u32 mode); - virtual void DepthBoundsEXT(float min, float max); - virtual void Scissor(u16 x, u16 y, u16 width, u16 height); - virtual void StencilOp(u32 fail, u32 zfail, u32 zpass); - virtual void StencilMask(u32 mask); - virtual void StencilFunc(u32 func, u32 ref, u32 mask); - virtual void StencilOpSeparate(u32 mode, u32 fail, u32 zfail, u32 zpass); - virtual void StencilMaskSeparate(u32 mode, u32 mask); - virtual void StencilFuncSeparate(u32 mode, u32 func, u32 ref, u32 mask); virtual void Flip(); }; diff --git a/rpcs3/Emu/RSX/Null/NullGSRender.h b/rpcs3/Emu/RSX/Null/NullGSRender.h index 53786c3b8e..33875cbabe 100644 --- a/rpcs3/Emu/RSX/Null/NullGSRender.h +++ b/rpcs3/Emu/RSX/Null/NullGSRender.h @@ -6,50 +6,44 @@ class NullGSRender { public: - NullGSRender() {} - virtual ~NullGSRender() {} + NullGSRender() + { + } + + virtual ~NullGSRender() + { + } private: - virtual void OnInit() {} - virtual void OnInitThread() {} - virtual void OnExitThread() {} - virtual void OnReset() {} - virtual void Enable(u32 cmd, u32 enable) {} - 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 ExecCMD() {} - virtual void AlphaFunc(u32 func, float ref) {} - virtual void DepthFunc(u32 func) {} - virtual void DepthMask(u32 flag) {} - virtual void PolygonMode(u32 face, u32 mode) {} - virtual void PointSize(float size) {} - virtual void LogicOp(u32 opcode) {} - virtual void LineWidth(float width) {} - virtual void LineStipple(u16 factor, u16 pattern) {} - virtual void PolygonStipple(u32 pattern) {} - virtual void PrimitiveRestartIndex(u32 index) {} - virtual void CullFace(u32 mode) {} - virtual void FrontFace(u32 mode) {} - virtual void Fogi(u32 mode) {} - virtual void Fogf(float start, float end) {} - virtual void PolygonOffset(float factor, float bias) {} - virtual void DepthRangef(float min, float max) {} - virtual void BlendEquationSeparate(u16 rgb, u16 a) {} - virtual void BlendFuncSeparate(u16 srcRGB, u16 dstRGB, u16 srcAlpha, u16 dstAlpha) {} - virtual void BlendColor(u8 r, u8 g, u8 b, u8 a) {} - virtual void LightModeli(u32 enable) {} - virtual void ShadeModel(u32 mode) {} - virtual void DepthBoundsEXT(float min, float max) {} - virtual void Scissor(u16 x, u16 y, u16 width, u16 height) {} - virtual void StencilOp(u32 fail, u32 zfail, u32 zpass) {} - virtual void StencilMask(u32 mask) {} - virtual void StencilFunc(u32 func, u32 ref, u32 mask) {} - virtual void StencilOpSeparate(u32 mode, u32 fail, u32 zfail, u32 zpass) {} - virtual void StencilMaskSeparate(u32 mode, u32 mask) {} - virtual void StencilFuncSeparate(u32 mode, u32 func, u32 ref, u32 mask) {} - virtual void Flip() {} - virtual void Close() {} -}; + virtual void OnInit() + { + } + + virtual void OnInitThread() + { + } + + virtual void OnExitThread() + { + } + + virtual void OnReset() + { + } + + virtual void ExecCMD(u32 cmd) + { + } + + virtual void ExecCMD() + { + } + + virtual void Flip() + { + } + + virtual void Close() + { + } +}; \ No newline at end of file diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 906b0281c3..2c7f2086ba 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -25,32 +25,32 @@ void RSXThread::NativeRescale(float width, float height) 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; } } @@ -58,7 +58,7 @@ u32 GetAddress(u32 offset, u32 location) { u32 res = 0; - switch(location) + switch (location) { case CELL_GCM_LOCATION_LOCAL: { @@ -70,22 +70,19 @@ u32 GetAddress(u32 offset, u32 location) res = (u32)Memory.RSXIOMem.RealAddr(offset); // TODO: Error Check? if (res == 0) { - LOG_ERROR(RSX, "GetAddress(offset=0x%x): RSXIO memory not mapped", offset); - Emu.Pause(); - break; + throw fmt::format("GetAddress(offset=0x%x, location=0x%x): RSXIO memory not mapped", offset, location); } if (Emu.GetGSManager().GetRender().m_strict_ordering[offset >> 20]) { _mm_mfence(); // probably doesn't have any effect on current implementation } + break; } default: { - LOG_ERROR(RSX, "GetAddress(offset=0x%x, location=0x%x): invalid location", offset, location); - Emu.Pause(); - break; + throw fmt::format("GetAddress(offset=0x%x, location=0x%x): invalid location", offset, location); } } @@ -112,7 +109,7 @@ void RSXVertexData::Reset() data.clear(); } -void RSXVertexData::Load(u32 start, u32 count, u32 baseOffset, u32 baseIndex=0) +void RSXVertexData::Load(u32 start, u32 count, u32 baseOffset, u32 baseIndex = 0) { if (!addr) return; @@ -125,29 +122,29 @@ void RSXVertexData::Load(u32 start, u32 count, u32 baseOffset, u32 baseIndex=0) auto src = vm::get_ptr(addr + baseOffset + stride * (i + baseIndex)); u8* dst = &data[i * tsize * size]; - switch(tsize) + switch (tsize) { case 1: { - memcpy(dst, src, size); // may be dangerous + memcpy(dst, src, size); + break; } - break; case 2: { const u16* c_src = (const u16*)src; u16* c_dst = (u16*)dst; for (u32 j = 0; j < size; ++j) *c_dst++ = re16(*c_src++); + break; } - break; case 4: { const u32* c_src = (const u32*)src; u32* c_dst = (u32*)dst; for (u32 j = 0; j < size; ++j) *c_dst++ = re32(*c_src++); + break; } - break; } } } @@ -199,7 +196,7 @@ u32 RSXThread::OutOfArgsCount(const uint x, const u32 cmd, const u32 count, cons case_16(offset + 16*step, step) #define case_range(n, offset, step) \ case_##n(offset, step) \ - index = (cmd - offset) / step; + index = (cmd - offset) / step void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const u32 count) { @@ -217,14 +214,14 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const m_used_gcm_commands.insert(cmd); - switch(cmd) + switch (cmd) { // NV406E case NV406E_SET_REFERENCE: { m_ctrl->ref.exchange(be_t::make(ARGS(0))); + break; } - break; case NV406E_SET_CONTEXT_DMA_SEMAPHORE: { @@ -232,16 +229,16 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const { LOG_WARNING(RSX, "TODO: NV406E_SET_CONTEXT_DMA_SEMAPHORE: 0x%x", ARGS(0)); } + break; } - break; case NV4097_SET_SEMAPHORE_OFFSET: case NV406E_SEMAPHORE_OFFSET: { m_set_semaphore_offset = true; m_semaphore_offset = ARGS(0); + break; } - break; case NV406E_SEMAPHORE_ACQUIRE: { @@ -249,8 +246,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const { LOG_WARNING(RSX, "TODO: NV406E_SEMAPHORE_ACQUIRE: 0x%x", ARGS(0)); } + break; } - break; case NV406E_SEMAPHORE_RELEASE: case NV4097_TEXTURE_READ_SEMAPHORE_RELEASE: @@ -260,8 +257,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const m_set_semaphore_offset = false; vm::write32(Memory.RSXCMDMem.GetStartAddr() + m_semaphore_offset, ARGS(0)); } + break; } - break; case NV4097_BACK_END_WRITE_SEMAPHORE_RELEASE: { @@ -273,8 +270,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const vm::write32(Memory.RSXCMDMem.GetStartAddr() + m_semaphore_offset, value); } + break; } - break; // NV4097 case 0x0003fead: @@ -311,30 +308,30 @@ 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(); }; sync(); //Emu.Pause(); + break; } - break; case NV4097_NO_OPERATION: { // Nothing to do here + break; } - break; - + case NV4097_SET_CONTEXT_DMA_REPORT: { if (ARGS(0)) { LOG_WARNING(RSX, "TODO: NV4097_SET_CONTEXT_DMA_REPORT: 0x%x", ARGS(0)); } + break; } - break; case NV4097_NOTIFY: { @@ -342,8 +339,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const { LOG_WARNING(RSX, "TODO: NV4097_NOTIFY: 0x%x", ARGS(0)); } + break; } - break; case NV4097_WAIT_FOR_IDLE: { @@ -351,8 +348,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const { LOG_WARNING(RSX, "TODO: NV4097_WAIT_FOR_IDLE: 0x%x", ARGS(0)); } + break; } - break; case NV4097_PM_TRIGGER: { @@ -360,64 +357,64 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const { LOG_WARNING(RSX, "TODO: NV4097_PM_TRIGGER: 0x%x", ARGS(0)); } + break; } - break; // Texture - case_range(16, NV4097_SET_TEXTURE_FORMAT, 0x20) - case_range(16, NV4097_SET_TEXTURE_OFFSET, 0x20) - case_range(16, NV4097_SET_TEXTURE_FILTER, 0x20) - case_range(16, NV4097_SET_TEXTURE_ADDRESS, 0x20) - case_range(16, NV4097_SET_TEXTURE_IMAGE_RECT, 32) - case_range(16, NV4097_SET_TEXTURE_BORDER_COLOR, 0x20) - case_range(16, NV4097_SET_TEXTURE_CONTROL0, 0x20) - case_range(16, NV4097_SET_TEXTURE_CONTROL1, 0x20) + case_range(16, NV4097_SET_TEXTURE_FORMAT, 0x20); + case_range(16, NV4097_SET_TEXTURE_OFFSET, 0x20); + case_range(16, NV4097_SET_TEXTURE_FILTER, 0x20); + case_range(16, NV4097_SET_TEXTURE_ADDRESS, 0x20); + case_range(16, NV4097_SET_TEXTURE_IMAGE_RECT, 32); + case_range(16, NV4097_SET_TEXTURE_BORDER_COLOR, 0x20); + case_range(16, NV4097_SET_TEXTURE_CONTROL0, 0x20); + case_range(16, NV4097_SET_TEXTURE_CONTROL1, 0x20); { // Done using methodRegisters in RSXTexture.cpp + break; } - break; - case_range(16, NV4097_SET_TEX_COORD_CONTROL, 4) + case_range(16, NV4097_SET_TEX_COORD_CONTROL, 4); { LOG_WARNING(RSX, "TODO: NV4097_SET_TEX_COORD_CONTROL"); + break; } - break; - case_range(16, NV4097_SET_TEXTURE_CONTROL3, 4) + case_range(16, NV4097_SET_TEXTURE_CONTROL3, 4); { RSXTexture& tex = m_textures[index]; const u32 a0 = ARGS(0); u32 pitch = a0 & 0xFFFFF; u16 depth = a0 >> 20; tex.SetControl3(depth, pitch); + break; } - break; - - // Vertex Texture - case_range(4, NV4097_SET_VERTEX_TEXTURE_FORMAT, 0x20) - case_range(4, NV4097_SET_VERTEX_TEXTURE_OFFSET, 0x20) - case_range(4, NV4097_SET_VERTEX_TEXTURE_FILTER, 0x20) - case_range(4, NV4097_SET_VERTEX_TEXTURE_ADDRESS, 0x20) - case_range(4, NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT, 0x20) - case_range(4, NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR, 0x20) - case_range(4, NV4097_SET_VERTEX_TEXTURE_CONTROL0, 0x20) + + // Vertex Texture + case_range(4, NV4097_SET_VERTEX_TEXTURE_FORMAT, 0x20); + case_range(4, NV4097_SET_VERTEX_TEXTURE_OFFSET, 0x20); + case_range(4, NV4097_SET_VERTEX_TEXTURE_FILTER, 0x20); + case_range(4, NV4097_SET_VERTEX_TEXTURE_ADDRESS, 0x20); + case_range(4, NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT, 0x20); + case_range(4, NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR, 0x20); + case_range(4, NV4097_SET_VERTEX_TEXTURE_CONTROL0, 0x20); { // Done using methodRegisters in RSXTexture.cpp + break; } - break; - case_range(4, NV4097_SET_VERTEX_TEXTURE_CONTROL3, 0x20) + case_range(4, NV4097_SET_VERTEX_TEXTURE_CONTROL3, 0x20); { RSXVertexTexture& tex = m_vertex_textures[index]; const u32 a0 = ARGS(0); u32 pitch = a0 & 0xFFFFF; u16 depth = a0 >> 20; tex.SetControl3(depth, pitch); + break; } - break; - // Vertex data - case_range(16, NV4097_SET_VERTEX_DATA4UB_M, 4) + // Vertex data + case_range(16, NV4097_SET_VERTEX_DATA4UB_M, 4); { const u32 a0 = ARGS(0); u8 v0 = a0; @@ -434,17 +431,17 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const m_vertex_data[index].data.push_back(v3); //LOG_WARNING(RSX, "NV4097_SET_VERTEX_DATA4UB_M: index = %d, v0 = 0x%x, v1 = 0x%x, v2 = 0x%x, v3 = 0x%x", index, v0, v1, v2, v3); + break; } - break; - case_range(16, NV4097_SET_VERTEX_DATA2F_M, 8) + case_range(16, NV4097_SET_VERTEX_DATA2F_M, 8); { const u32 a0 = ARGS(0); const u32 a1 = ARGS(1); float v0 = (float&)a0; float v1 = (float&)a1; - + m_vertex_data[index].Reset(); m_vertex_data[index].type = CELL_GCM_VERTEX_F; m_vertex_data[index].size = 2; @@ -454,10 +451,10 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const (float&)m_vertex_data[index].data[pos + sizeof(float) * 1] = v1; //LOG_WARNING(RSX, "NV4097_SET_VERTEX_DATA2F_M: index = %d, v0 = %f, v1 = %f", index, v0, v1); + break; } - break; - case_range(16, NV4097_SET_VERTEX_DATA4F_M, 16) + case_range(16, NV4097_SET_VERTEX_DATA4F_M, 16); { const u32 a0 = ARGS(0); const u32 a1 = ARGS(1); @@ -480,10 +477,10 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const (float&)m_vertex_data[index].data[pos + sizeof(float) * 3] = v3; //LOG_WARNING(RSX, "NV4097_SET_VERTEX_DATA4F_M: index = %d, v0 = %f, v1 = %f, v2 = %f, v3 = %f", index, v0, v1, v2, v3); + break; } - break; - case_range(16, NV4097_SET_VERTEX_DATA_ARRAY_OFFSET, 4) + case_range(16, NV4097_SET_VERTEX_DATA_ARRAY_OFFSET, 4); { const u32 addr = GetAddress(ARGS(0) & 0x7fffffff, ARGS(0) >> 31); @@ -491,10 +488,10 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const m_vertex_data[index].data.clear(); //LOG_WARNING(RSX, "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET: num=%d, addr=0x%x", index, addr); + break; } - break; - case_range(16, NV4097_SET_VERTEX_DATA_ARRAY_FORMAT, 4) + case_range(16, NV4097_SET_VERTEX_DATA_ARRAY_FORMAT, 4); { const u32 a0 = ARGS(0); u16 frequency = a0 >> 16; @@ -510,8 +507,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const //LOG_WARNING(RSX, "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT: index=%d, frequency=%d, stride=%d, size=%d, type=%d", index, frequency, stride, size, type); + break; } - break; // Vertex Attribute case NV4097_SET_VERTEX_ATTRIB_INPUT_MASK: @@ -522,8 +519,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const } //VertexData[0].prog.attributeInputMask = ARGS(0); + break; } - break; case NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK: { @@ -534,16 +531,21 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const //VertexData[0].prog.attributeOutputMask = ARGS(0); //FragmentData.prog.attributeInputMask = ARGS(0)/* & ~0x20*/; + break; } - break; // Color Mask case NV4097_SET_COLOR_MASK: { - const u32 mask = ARGS(0); - ColorMask(mask & 0x1000000, mask & 0x1000000, mask & 0x1000000, mask & 0x0000001); + 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; + break; } - break; case NV4097_SET_COLOR_MASK_MRT: { @@ -551,118 +553,105 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const { LOG_WARNING(RSX, "TODO: NV4097_SET_COLOR_MASK_MRT: 0x%x", mask); } + break; } - break; // Alpha testing case NV4097_SET_ALPHA_TEST_ENABLE: { - const u32 value = ARGS(0); - Enable(cmd, value); + m_set_alpha_test = ARGS(0) ? true : false; + break; } - break; case NV4097_SET_ALPHA_FUNC: { - const u32 value = ARGS(0); - m_alpha_func = value; + m_set_alpha_func = true; + m_alpha_func = ARGS(0); - // Sanity check here for invalid alpha func - if (m_alpha_func) + if (count == 2) { - AlphaFunc(m_alpha_func, m_alpha_ref); + m_set_alpha_ref = true; + const u32 a1 = ARGS(1); + m_alpha_ref = (float&)a1; } + break; } - break; case NV4097_SET_ALPHA_REF: { - const u32 value = ARGS(0); - m_alpha_ref = (float&)value; - - // Sanity check here for invalid alpha func - if (m_alpha_func) - { - AlphaFunc(m_alpha_func, m_alpha_ref); - } + m_set_alpha_ref = true; + const u32 a0 = ARGS(0); + m_alpha_ref = (float&)a0; + break; } - break; // Cull face case NV4097_SET_CULL_FACE_ENABLE: { - const u32 value = ARGS(0); - Enable(cmd, value); + m_set_cull_face = ARGS(0) ? true : false; + break; } - break; case NV4097_SET_CULL_FACE: { - const u32 value = ARGS(0); - CullFace(value); + m_cull_face = ARGS(0); + break; } - break; // Front face case NV4097_SET_FRONT_FACE: { - const u32 value = ARGS(0); - //FrontFace(value); + m_front_face = ARGS(0); + break; } - break; // Blending case NV4097_SET_BLEND_ENABLE: { - const u32 value = ARGS(0); - Enable(cmd, value); + m_set_blend = ARGS(0) ? true : false; + break; } - break; case NV4097_SET_BLEND_ENABLE_MRT: { m_set_blend_mrt1 = ARGS(0) & 0x02 ? true : false; m_set_blend_mrt2 = ARGS(0) & 0x04 ? true : false; m_set_blend_mrt3 = ARGS(0) & 0x08 ? true : false; + break; } - break; case NV4097_SET_BLEND_FUNC_SFACTOR: { - const u32 value = ARGS(0); m_set_blend_sfactor = true; - m_blend_sfactor_rgb = value & 0xffff; - m_blend_sfactor_alpha = value >> 16; + m_blend_sfactor_rgb = ARGS(0) & 0xffff; + m_blend_sfactor_alpha = ARGS(0) >> 16; if (count == 2) { - const u32 value1 = ARGS(1); - m_blend_dfactor_rgb = value1 & 0xffff; - m_blend_dfactor_alpha = value1 >> 16; - BlendFuncSeparate(m_blend_sfactor_rgb, m_blend_dfactor_rgb, m_blend_sfactor_alpha, m_blend_dfactor_alpha); + m_set_blend_dfactor = true; + m_blend_dfactor_rgb = ARGS(1) & 0xffff; + m_blend_dfactor_alpha = ARGS(1) >> 16; } + break; } - break; case NV4097_SET_BLEND_FUNC_DFACTOR: { - const u32 value = ARGS(0); - m_blend_dfactor_rgb = value & 0xffff; - m_blend_dfactor_alpha = value >> 16; - - if (m_set_blend_sfactor) - { - BlendFuncSeparate(m_blend_sfactor_rgb, m_blend_dfactor_rgb, m_blend_sfactor_alpha, m_blend_dfactor_alpha); - } + m_set_blend_dfactor = true; + m_blend_dfactor_rgb = ARGS(0) & 0xffff; + m_blend_dfactor_alpha = ARGS(0) >> 16; + break; } - break; case NV4097_SET_BLEND_COLOR: { - const u32 value = ARGS(0); - BlendColor(value & 0xff, (value >> 8) & 0xff, (value >> 16) & 0xff, (value >> 24) & 0xff); + m_set_blend_color = true; + m_blend_color_r = ARGS(0) & 0xff; + m_blend_color_g = (ARGS(0) >> 8) & 0xff; + m_blend_color_b = (ARGS(0) >> 16) & 0xff; + m_blend_color_a = (ARGS(0) >> 24) & 0xff; + break; } - break; case NV4097_SET_BLEND_COLOR2: { @@ -670,15 +659,16 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const { LOG_WARNING(RSX, "TODO : NV4097_SET_BLEND_COLOR2: 0x%x", value); } + break; } - break; case NV4097_SET_BLEND_EQUATION: { - const u32 value = ARGS(0); - BlendEquationSeparate(value & 0xffff, value >> 16); + m_set_blend_equation = true; + m_blend_equation_rgb = ARGS(0) & 0xffff; + m_blend_equation_alpha = ARGS(0) >> 16; + break; } - break; case NV4097_SET_REDUCE_DST_COLOR: { @@ -686,43 +676,37 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const { LOG_WARNING(RSX, "TODO: NV4097_SET_REDUCE_DST_COLOR: 0x%x", value); } + break; } - break; // Depth bound testing case NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE: { - const u32 value = ARGS(0); - Enable(cmd, value); + m_set_depth_bounds_test = ARGS(0) ? true : false; + break; } - break; case NV4097_SET_DEPTH_BOUNDS_MIN: { - const u32 value = ARGS(0); m_set_depth_bounds = true; - m_depth_bounds_min = (float&)value; + const u32 a0 = ARGS(0); + m_depth_bounds_min = (float&)a0; if (count == 2) { - const u32 value1 = ARGS(1); - m_depth_bounds_max = (float&)value1; - DepthBoundsEXT(m_depth_bounds_min, m_depth_bounds_max); + const u32 a1 = ARGS(1); + m_depth_bounds_max = (float&)a1; } + break; } - break; case NV4097_SET_DEPTH_BOUNDS_MAX: { - const u32 value = ARGS(0); - m_depth_bounds_max = (float&)value; - - if (m_set_depth_bounds) - { - DepthBoundsEXT(m_depth_bounds_min, m_depth_bounds_max); - } + m_set_depth_bounds = true; + const u32 a0 = ARGS(0); + m_depth_bounds_max = (float&)a0; + break; } - break; // Viewport case NV4097_SET_VIEWPORT_HORIZONTAL: @@ -739,8 +723,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const } //LOG_NOTICE(RSX, "NV4097_SET_VIEWPORT_HORIZONTAL: x=%d, y=%d, w=%d, h=%d", m_viewport_x, m_viewport_y, m_viewport_w, m_viewport_h); + break; } - break; case NV4097_SET_VIEWPORT_VERTICAL: { @@ -749,124 +733,120 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const m_viewport_h = ARGS(0) >> 16; //LOG_NOTICE(RSX, "NV4097_SET_VIEWPORT_VERTICAL: y=%d, h=%d", m_viewport_y, m_viewport_h); + break; } - break; case NV4097_SET_VIEWPORT_SCALE: case NV4097_SET_VIEWPORT_OFFSET: { // Done in Vertex Shader + break; } - break; // Clipping case NV4097_SET_CLIP_MIN: { - const u32 value = ARGS(0); - m_clip_min = (float&)value; - DepthRangef(m_clip_min, m_clip_max); + const u32 a0 = ARGS(0); + const u32 a1 = ARGS(1); + + m_set_clip = true; + m_clip_min = (float&)a0; + m_clip_max = (float&)a1; + + //LOG_NOTICE(RSX, "NV4097_SET_CLIP_MIN: clip_min=%.01f, clip_max=%.01f", m_clip_min, m_clip_max); + break; } - break; case NV4097_SET_CLIP_MAX: { - const u32 value = ARGS(0); - m_clip_max = (float&)value; - DepthRangef(m_clip_min, m_clip_max); + const u32 a0 = ARGS(0); + + m_set_clip = true; + m_clip_max = (float&)a0; + + //LOG_NOTICE(RSX, "NV4097_SET_CLIP_MAX: clip_max=%.01f", m_clip_max); + break; } - break; // Depth testing case NV4097_SET_DEPTH_TEST_ENABLE: { - const u32 value = ARGS(0); - Enable(cmd, value); + m_set_depth_test = ARGS(0) ? true : false; + break; } - break; - + case NV4097_SET_DEPTH_FUNC: { - const u32 value = ARGS(0); - // Sanity check here for invalid depth func - if (value) - { - DepthFunc(value); - } + m_set_depth_func = true; + m_depth_func = ARGS(0); + break; } - break; case NV4097_SET_DEPTH_MASK: { - const u32 value = ARGS(0); - DepthMask(value); + m_set_depth_mask = true; + m_depth_mask = ARGS(0); + break; } - break; // Polygon mode/offset case NV4097_SET_FRONT_POLYGON_MODE: { - const u32 value = ARGS(0); - PolygonMode(cmd, value); + m_set_front_polygon_mode = true; + m_front_polygon_mode = ARGS(0); + break; } - break; case NV4097_SET_BACK_POLYGON_MODE: { - const u32 value = ARGS(0); - PolygonMode(cmd, value); + m_set_back_polygon_mode = true; + m_back_polygon_mode = ARGS(0); + break; } - break; - + case NV4097_SET_POLY_OFFSET_FILL_ENABLE: { - Enable(cmd, ARGS(0)); + m_set_poly_offset_fill = ARGS(0) ? true : false; + break; } - break; case NV4097_SET_POLY_OFFSET_LINE_ENABLE: { - const u32 value = ARGS(0); - Enable(cmd, value); + m_set_poly_offset_line = ARGS(0) ? true : false; + break; } - break; case NV4097_SET_POLY_OFFSET_POINT_ENABLE: { - const u32 value = ARGS(0); - Enable(cmd, value); + m_set_poly_offset_point = ARGS(0) ? true : false; + break; } - break; case NV4097_SET_POLYGON_OFFSET_SCALE_FACTOR: { - Enable(NV4097_SET_DEPTH_TEST_ENABLE, 1); - - const u32 value = ARGS(0); + m_set_depth_test = true; m_set_poly_offset_mode = true; - m_poly_offset_scale_factor = (float&)value; + + const u32 a0 = ARGS(0); + m_poly_offset_scale_factor = (float&)a0; if (count == 2) { - const u32 value1 = ARGS(1); - m_poly_offset_bias = (float&)value1; - PolygonOffset(m_poly_offset_scale_factor, m_poly_offset_bias); + const u32 a1 = ARGS(1); + m_poly_offset_bias = (float&)a1; } + break; } - break; case NV4097_SET_POLYGON_OFFSET_BIAS: { - Enable(NV4097_SET_DEPTH_TEST_ENABLE, 1); + m_set_depth_test = true; + m_set_poly_offset_mode = true; - const u32 value = ARGS(0); - m_poly_offset_bias = (float&)value; - - if (m_set_poly_offset_mode) - { - PolygonOffset(m_poly_offset_scale_factor, m_poly_offset_bias); - } + const u32 a0 = ARGS(0); + m_poly_offset_bias = (float&)a0; + break; } - break; case NV4097_SET_CYLINDRICAL_WRAP: { @@ -874,8 +854,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const { LOG_WARNING(RSX, "TODO: NV4097_SET_CYLINDRICAL_WRAP: 0x%x", ARGS(0)); } + break; } - break; // Clearing case NV4097_CLEAR_ZCULL_SURFACE: @@ -886,33 +866,42 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const if (a0 & 0x02) m_clear_surface_s = m_clear_s; m_clear_surface_mask |= a0 & 0x3; + break; } - break; case NV4097_CLEAR_SURFACE: { - const u32 mask = ARGS(0); + const u32 a0 = ARGS(0); - ClearSurface(mask); + 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); + break; } - break; case NV4097_SET_ZSTENCIL_CLEAR_VALUE: { - const u32 value = ARGS(0); - - ClearStencil(value & 0xff); - ClearDepth(value >> 8); + const u32 a0 = ARGS(0); + m_clear_s = a0 & 0xff; + m_clear_z = a0 >> 8; + break; } - break; case NV4097_SET_COLOR_CLEAR_VALUE: { const u32 color = ARGS(0); - - ClearColor((color >> 24) & 0xff, (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff); + 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; + break; } - break; case NV4097_SET_CLEAR_RECT_HORIZONTAL: { @@ -920,8 +909,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const { LOG_WARNING(RSX, "TODO: NV4097_SET_CLEAR_RECT_HORIZONTAL: 0x%x", value); } + break; } - break; case NV4097_SET_CLEAR_RECT_VERTICAL: { @@ -929,8 +918,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const { LOG_WARNING(RSX, "TODO: NV4097_SET_CLEAR_RECT_VERTICAL: 0x%x", value); } + break; } - break; // Arrays case NV4097_INLINE_ARRAY: @@ -939,12 +928,12 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const { LOG_WARNING(RSX, "TODO: NNV4097_INLINE_ARRAY: 0x%x", value); } + break; } - break; case NV4097_DRAW_ARRAYS: { - for (u32 c=0; c> 4; + break; } - break; case NV4097_DRAW_INDEX_ARRAY: { @@ -985,24 +974,24 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const u32 index; switch(m_indexed_array.m_type) { - case 0: - { - int pos = (int)m_indexed_array.m_data.size(); - m_indexed_array.m_data.resize(m_indexed_array.m_data.size() + 4); - index = vm::read32(m_indexed_array.m_addr + i * 4); - *(u32*)&m_indexed_array.m_data[pos] = index; - //LOG_WARNING(RSX, "index 4: %d", *(u32*)&m_indexed_array.m_data[pos]); - } + case 0: + { + int pos = (int)m_indexed_array.m_data.size(); + m_indexed_array.m_data.resize(m_indexed_array.m_data.size() + 4); + index = vm::read32(m_indexed_array.m_addr + i * 4); + *(u32*)&m_indexed_array.m_data[pos] = index; + //LOG_WARNING(RSX, "index 4: %d", *(u32*)&m_indexed_array.m_data[pos]); + } break; - case 1: - { - int pos = (int)m_indexed_array.m_data.size(); - m_indexed_array.m_data.resize(m_indexed_array.m_data.size() + 2); - index = vm::read16(m_indexed_array.m_addr + i * 2); - //LOG_WARNING(RSX, "index 2: %d", index); - *(u16*)&m_indexed_array.m_data[pos] = index; - } + case 1: + { + int pos = (int)m_indexed_array.m_data.size(); + m_indexed_array.m_data.resize(m_indexed_array.m_data.size() + 2); + index = vm::read16(m_indexed_array.m_addr + i * 2); + //LOG_WARNING(RSX, "index 2: %d", index); + *(u16*)&m_indexed_array.m_data[pos] = index; + } break; } @@ -1012,27 +1001,27 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const m_indexed_array.m_count += _count; } + break; } - break; case NV4097_SET_VERTEX_DATA_BASE_OFFSET: { m_vertex_data_base_offset = ARGS(0); - if (count >= 2) + if (count >= 2) { m_vertex_data_base_index = ARGS(1); } //LOG_WARNING(RSX, "NV4097_SET_VERTEX_DATA_BASE_OFFSET: 0x%x", m_vertex_data_base_offset); + break; } - break; case NV4097_SET_VERTEX_DATA_BASE_INDEX: { m_vertex_data_base_index = ARGS(0); + break; } - break; case NV4097_SET_BEGIN_END: { @@ -1068,8 +1057,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const { End(); } + break; } - break; // Shader case NV4097_SET_SHADER_PROGRAM: @@ -1080,21 +1069,21 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const 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; } - break; case NV4097_SET_SHADER_CONTROL: { m_shader_ctrl = ARGS(0); + break; } - break; case NV4097_SET_SHADE_MODE: { - const u32 value = ARGS(0); - ShadeModel(value); + m_set_shade_mode = true; + m_shade_mode = ARGS(0); + break; } - break; case NV4097_SET_SHADER_PACKER: { @@ -1110,8 +1099,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const m_shader_window_height = a0 & 0xfff; m_shader_window_origin = (a0 >> 12) & 0xf; m_shader_window_pixel_centers = a0 >> 16; + break; } - break; // Transform case NV4097_SET_TRANSFORM_PROGRAM_LOAD: @@ -1129,20 +1118,20 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const LOG_WARNING(RSX, "NV4097_SET_TRANSFORM_PROGRAM_LOAD: start = %d", start); } } + break; } - break; case NV4097_SET_TRANSFORM_PROGRAM_START: { const u32 start = ARGS(0); - if (start) + if (start) { LOG_WARNING(RSX, "NV4097_SET_TRANSFORM_PROGRAM_START: start = %d", start); } + break; } - break; - case_range(32, NV4097_SET_TRANSFORM_PROGRAM, 4) + case_range(32, NV4097_SET_TRANSFORM_PROGRAM, 4); { //LOG_WARNING(RSX, "NV4097_SET_TRANSFORM_PROGRAM[%d](%d)", index, count); @@ -1156,11 +1145,11 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const { m_cur_vertex_prog->data.push_back(ARGS(i)); } + break; } - break; case NV4097_SET_TRANSFORM_TIMEOUT: - + { // TODO: // (cmd)[1] = CELL_GCM_ENDIAN_SWAP((count) | ((registerCount) << 16)); \ @@ -1171,7 +1160,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const } //m_cur_vertex_prog->Decompile(); - break; + break; + } case NV4097_SET_TRANSFORM_BRANCH_BITS: { @@ -1179,8 +1169,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const { LOG_WARNING(RSX, "TODO: NV4097_SET_TRANSFORM_BRANCH_BITS: 0x%x", value); } + break; } - break; case NV4097_SET_TRANSFORM_CONSTANT_LOAD: { @@ -1203,8 +1193,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const //LOG_NOTICE(RSX, "NV4097_SET_TRANSFORM_CONSTANT_LOAD: [%d : %d] = (%f, %f, %f, %f)", i, id, c.x, c.y, c.z, c.w); } + break; } - break; // Invalidation case NV4097_INVALIDATE_L2: @@ -1213,20 +1203,20 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const { LOG_WARNING(RSX, "TODO: NV4097_INVALIDATE_L2: 0x%x", value); } + break; } - break; case NV4097_INVALIDATE_VERTEX_CACHE_FILE: { // Nothing to do here + break; } - break; case NV4097_INVALIDATE_VERTEX_FILE: { // Nothing to do here + break; } - break; case NV4097_INVALIDATE_ZCULL: { @@ -1234,190 +1224,165 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const { LOG_WARNING(RSX, "TODO: NV4097_INVALIDATE_ZCULL: 0x%x", value); } + break; } - break; // Logic Ops case NV4097_SET_LOGIC_OP_ENABLE: { - const u32 value = ARGS(0); - Enable(cmd, value); + m_set_logic_op = ARGS(0) ? true : false; + break; } - break; case NV4097_SET_LOGIC_OP: { - const u32 value = ARGS(0); - LogicOp(value); + m_logic_op = ARGS(0); + break; } - break; - + // Dithering case NV4097_SET_DITHER_ENABLE: { - const u32 value = ARGS(0); - Enable(cmd, value); + m_set_dither = ARGS(0) ? true : false; + break; } - break; // Stencil testing case NV4097_SET_STENCIL_TEST_ENABLE: { - const u32 value = ARGS(0); - Enable(cmd, ARGS(0)); + m_set_stencil_test = ARGS(0) ? true : false; + break; } - break; case NV4097_SET_TWO_SIDED_STENCIL_TEST_ENABLE: { - const u32 value = ARGS(0); - Enable(cmd, ARGS(0)); + m_set_two_sided_stencil_test_enable = ARGS(0) ? true : false; + break; } - break; case NV4097_SET_TWO_SIDE_LIGHT_EN: { - const u32 value = ARGS(0); - LightModeli(value); + m_set_two_side_light_enable = ARGS(0) ? true : false; + break; } - break; case NV4097_SET_STENCIL_MASK: { - const u32 value = ARGS(0); m_set_stencil_mask = true; - StencilMask(value); + m_stencil_mask = ARGS(0); + break; } - break; case NV4097_SET_STENCIL_FUNC: { - if (count == 3) + m_set_stencil_func = true; + m_stencil_func = ARGS(0); + + if (count >= 2) { - m_set_stencil_func = true; - m_stencil_func = ARGS(0); + m_set_stencil_func_ref = true; m_stencil_func_ref = ARGS(1); - m_stencil_func_mask = ARGS(2); - StencilFunc(m_stencil_func, m_stencil_func_ref, m_stencil_func_mask); + + if (count >= 3) + { + m_set_stencil_func_mask = true; + m_stencil_func_mask = ARGS(2); + } } + break; } - break; case NV4097_SET_STENCIL_FUNC_REF: { + m_set_stencil_func_ref = true; m_stencil_func_ref = ARGS(0); - - if (m_set_stencil_func) - { - StencilFunc(m_stencil_func, m_stencil_func_ref, m_stencil_func_mask); - } + break; } - break; case NV4097_SET_STENCIL_FUNC_MASK: { + m_set_stencil_func_mask = true; m_stencil_func_mask = ARGS(0); - - if (m_set_stencil_func) - { - StencilFunc(m_stencil_func, m_stencil_func_ref, m_stencil_func_mask); - } + break; } - break; case NV4097_SET_STENCIL_OP_FAIL: { - if (count == 3) + m_set_stencil_fail = true; + m_stencil_fail = ARGS(0); + + if (count >= 2) { - m_set_stencil_op_fail = true; - m_stencil_fail = ARGS(0); + m_set_stencil_zfail = true; m_stencil_zfail = ARGS(1); - m_stencil_zpass = ARGS(2); - StencilOp(m_stencil_fail, m_stencil_zfail, m_stencil_zpass); + + if (count >= 3) + { + m_set_stencil_zpass = true; + m_stencil_zpass = ARGS(2); + } } + break; } - break; case NV4097_SET_BACK_STENCIL_MASK: { + m_set_back_stencil_mask = true; m_back_stencil_mask = ARGS(0); - - StencilMaskSeparate(0, m_back_stencil_mask); // GL_BACK - - if (m_set_stencil_mask) - { - StencilMaskSeparate(1, m_stencil_mask); // GL_FRONT - } + break; } - break; case NV4097_SET_BACK_STENCIL_FUNC: { - if (count == 3) + m_set_back_stencil_func = true; + m_back_stencil_func = ARGS(0); + + if (count >= 2) { - m_set_back_stencil_func = true; - m_back_stencil_func = ARGS(0); + m_set_back_stencil_func_ref = true; m_back_stencil_func_ref = ARGS(1); - m_back_stencil_func_mask = ARGS(2); - StencilFuncSeparate(0, m_back_stencil_func, m_back_stencil_func_ref, m_back_stencil_func_mask); // GL_BACK - if (m_set_stencil_func) + + if (count >= 3) { - StencilFuncSeparate(1, m_stencil_func, m_stencil_func_ref, m_stencil_func_mask); // GL_FRONT + m_set_back_stencil_func_mask = true; + m_back_stencil_func_mask = ARGS(2); } } + break; } - break; case NV4097_SET_BACK_STENCIL_FUNC_REF: { + m_set_back_stencil_func_ref = true; m_back_stencil_func_ref = ARGS(0); - - if (m_set_back_stencil_func) - { - StencilFuncSeparate(0, m_back_stencil_func, m_back_stencil_func_ref, m_back_stencil_func_mask); // GL_BACK - - if (m_set_stencil_func) - { - StencilFuncSeparate(1, m_stencil_func, m_stencil_func_ref, m_stencil_func_mask); // GL_FRONT - } - } - + break; } - break; case NV4097_SET_BACK_STENCIL_FUNC_MASK: { + m_set_back_stencil_func_mask = true; m_back_stencil_func_mask = ARGS(0); - - if (m_set_back_stencil_func) - { - StencilFuncSeparate(0, m_back_stencil_func, m_back_stencil_func_ref, m_back_stencil_func_mask); // GL_BACK - - if (m_set_stencil_func) - { - StencilFuncSeparate(1, m_stencil_func, m_stencil_func_ref, m_stencil_func_mask); // GL_FRONT - } - } + break; } - break; case NV4097_SET_BACK_STENCIL_OP_FAIL: { - if (count == 3) - { - m_back_stencil_fail = ARGS(0); - m_back_stencil_zfail = ARGS(1); - m_back_stencil_zpass = ARGS(2); - StencilOpSeparate(0, m_back_stencil_fail, m_back_stencil_zfail, m_back_stencil_zpass); // GL_BACK + m_set_stencil_fail = true; + m_stencil_fail = ARGS(0); - if (m_set_stencil_op_fail) + if (count >= 2) + { + m_set_back_stencil_zfail = true; + m_back_stencil_zfail = ARGS(1); + + if (count >= 3) { - StencilOpSeparate(1, m_stencil_fail, m_stencil_zfail, m_stencil_zpass); // GL_FRONT + m_set_back_stencil_zpass = true; + m_back_stencil_zpass = ARGS(2); } } - + break; } - break; case NV4097_SET_SCULL_CONTROL: { @@ -1425,31 +1390,30 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const { LOG_WARNING(RSX, "TODO: NV4097_SET_SCULL_CONTROL: 0x%x", value); } + break; } - break; // Primitive restart index case NV4097_SET_RESTART_INDEX_ENABLE: { - const u32 value = ARGS(0); - Enable(cmd, value); + m_set_restart_index = ARGS(0) ? true : false; + break; } - break; case NV4097_SET_RESTART_INDEX: { - const u32 value = ARGS(0); - PrimitiveRestartIndex(value); + m_restart_index = ARGS(0); + break; } - break; // Point size case NV4097_SET_POINT_SIZE: { - const u32 value = ARGS(0); - PointSize((float&)value); + m_set_point_size = true; + const u32 a0 = ARGS(0); + m_point_size = (float&)a0; + break; } - break; // Point sprite case NV4097_SET_POINT_PARAMS_ENABLE: @@ -1458,57 +1422,48 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const { LOG_WARNING(RSX, "TODO: NV4097_SET_POINT_PARAMS_ENABLE: 0x%x", value); } + break; } - break; case NV4097_SET_POINT_SPRITE_CONTROL: { - const u32 value = ARGS(0); - Enable(cmd, value); + m_set_point_sprite_control = ARGS(0) ? true : false; // TODO: //(cmd)[1] = CELL_GCM_ENDIAN_SWAP((enable) | ((rmode) << 1) | (texcoordMask)); + break; } - break; // Lighting case NV4097_SET_SPECULAR_ENABLE: { - const u32 value = ARGS(0); - Enable(cmd, value); + m_set_specular = ARGS(0) ? true : false; + break; } - break; // Scissor case NV4097_SET_SCISSOR_HORIZONTAL: { - const u32 value = ARGS(0); m_set_scissor_horizontal = true; - m_scissor_x = value & 0xffff; - m_scissor_w = value >> 16; + m_scissor_x = ARGS(0) & 0xffff; + m_scissor_w = ARGS(0) >> 16; if (count == 2) { - const u32 value1 = ARGS(1); - m_scissor_y = value1 & 0xffff; - m_scissor_h = value1 >> 16; - Scissor(m_scissor_x, m_scissor_y, m_scissor_w, m_scissor_h); + m_set_scissor_vertical = true; + m_scissor_y = ARGS(1) & 0xffff; + m_scissor_h = ARGS(1) >> 16; } + break; } - break; case NV4097_SET_SCISSOR_VERTICAL: { - const u32 value = ARGS(0); - m_scissor_y = value & 0xffff; - m_scissor_h = value >> 16; - - if (m_set_scissor_horizontal) - { - Scissor(m_scissor_x, m_scissor_y, m_scissor_w, m_scissor_h); - } + m_set_scissor_vertical = true; + m_scissor_y = ARGS(0) & 0xffff; + m_scissor_h = ARGS(0) >> 16; + break; } - break; // Depth/Color buffer usage case NV4097_SET_SURFACE_FORMAT: @@ -1536,56 +1491,56 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const m_height = buffers[m_gcm_current_buffer].height; NativeRescale((float)m_width, (float)m_height); + break; } - break; case NV4097_SET_SURFACE_COLOR_TARGET: { m_surface_color_target = ARGS(0); + break; } - break; case NV4097_SET_SURFACE_COLOR_AOFFSET: { m_surface_offset_a = ARGS(0); + break; } - break; case NV4097_SET_SURFACE_COLOR_BOFFSET: { m_surface_offset_b = ARGS(0); + break; } - break; case NV4097_SET_SURFACE_COLOR_COFFSET: { m_surface_offset_c = ARGS(0); + break; } - break; case NV4097_SET_SURFACE_COLOR_DOFFSET: { m_surface_offset_d = ARGS(0); + break; } - break; case NV4097_SET_SURFACE_ZETA_OFFSET: { m_surface_offset_z = ARGS(0); + break; } - break; case NV4097_SET_SURFACE_PITCH_A: { m_surface_pitch_a = ARGS(0); + break; } - break; case NV4097_SET_SURFACE_PITCH_B: { m_surface_pitch_b = ARGS(0); + break; } - break; case NV4097_SET_SURFACE_PITCH_C: { @@ -1599,8 +1554,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const m_surface_pitch_d = ARGS(1); m_surface_offset_c = ARGS(2); m_surface_offset_d = ARGS(3); + break; } - break; case NV4097_SET_SURFACE_PITCH_D: { @@ -1611,8 +1566,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const LOG_ERROR(RSX, "NV4097_SET_SURFACE_PITCH_D: Bad count (%d)", count); break; } + break; } - break; case NV4097_SET_SURFACE_PITCH_Z: { @@ -1623,8 +1578,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const LOG_ERROR(RSX, "NV4097_SET_SURFACE_PITCH_Z: Bad count (%d)", count); break; } + break; } - break; case NV4097_SET_CONTEXT_DMA_COLOR_A: { @@ -1636,15 +1591,15 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const LOG_ERROR(RSX, "NV4097_SET_CONTEXT_DMA_COLOR_A: Bad count (%d)", count); break; } + break; } - break; case NV4097_SET_CONTEXT_DMA_COLOR_B: { m_set_context_dma_color_b = true; m_context_dma_color_b = ARGS(0); + break; } - break; case NV4097_SET_CONTEXT_DMA_COLOR_C: { @@ -1656,8 +1611,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const m_set_context_dma_color_d = true; m_context_dma_color_d = ARGS(1); } + break; } - break; case NV4097_SET_CONTEXT_DMA_COLOR_D: { @@ -1665,15 +1620,15 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const { LOG_WARNING(RSX, "TODO: NV4097_SET_CONTEXT_DMA_COLOR_D: 0x%x", ARGS(0)); } + break; } - break; case NV4097_SET_CONTEXT_DMA_ZETA: { m_set_context_dma_z = true; m_context_dma_z = ARGS(0); + break; } - break; case NV4097_SET_CONTEXT_DMA_SEMAPHORE: { @@ -1681,8 +1636,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const { LOG_WARNING(RSX, "TODO: NV4097_SET_CONTEXT_DMA_SEMAPHORE: 0x%x", value); } + break; } - break; case NV4097_SET_CONTEXT_DMA_NOTIFIES: { @@ -1690,8 +1645,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const { LOG_WARNING(RSX, "TODO: NV4097_SET_CONTEXT_DMA_NOTIFIES: 0x%x", value); } + break; } - break; case NV4097_SET_SURFACE_CLIP_HORIZONTAL: { @@ -1708,8 +1663,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const m_surface_clip_y = a1; m_surface_clip_h = a1 >> 16; } + break; } - break; case NV4097_SET_SURFACE_CLIP_VERTICAL: { @@ -1717,8 +1672,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const m_set_surface_clip_vertical = true; m_surface_clip_y = a0; m_surface_clip_h = a0 >> 16; + break; } - break; // Anti-aliasing case NV4097_SET_ANTI_ALIASING_CONTROL: @@ -1729,78 +1684,76 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const const u8 alphaToCoverage = (a0 >> 4) & 0xf; const u8 alphaToOne = (a0 >> 8) & 0xf; const u16 sampleMask = a0 >> 16; - + if (a0) { LOG_WARNING(RSX, "TODO: NV4097_SET_ANTI_ALIASING_CONTROL: 0x%x", a0); } + break; } - break; // Line/Polygon smoothing case NV4097_SET_LINE_SMOOTH_ENABLE: { - const u32 value = ARGS(0); - Enable(cmd, value); + m_set_line_smooth = ARGS(0) ? true : false; + break; } - break; case NV4097_SET_POLY_SMOOTH_ENABLE: { - const u32 value = ARGS(0); - Enable(cmd, value); + m_set_poly_smooth = ARGS(0) ? true : false; + break; } - break; // Line width case NV4097_SET_LINE_WIDTH: { - const u32 value = ARGS(0); - LineWidth((float)value / 8.0f); + m_set_line_width = true; + const u32 a0 = ARGS(0); + m_line_width = (float)a0 / 8.0f; + break; } - break; // Line/Polygon stipple case NV4097_SET_LINE_STIPPLE: { - const u32 value = ARGS(0); - Enable(cmd, value); + m_set_line_stipple = ARGS(0) ? true : false; + break; } - break; case NV4097_SET_LINE_STIPPLE_PATTERN: { - const u32 value = ARGS(0); - LineStipple(value & 0xffff, value >> 16); + m_set_line_stipple = true; + const u32 a0 = ARGS(0); + m_line_stipple_factor = a0 & 0xffff; + m_line_stipple_pattern = a0 >> 16; + break; } - break; case NV4097_SET_POLYGON_STIPPLE: { - const u32 value = ARGS(0); - Enable(cmd, value); + m_set_polygon_stipple = ARGS(0) ? true : false; + break; } - break; case NV4097_SET_POLYGON_STIPPLE_PATTERN: { - u32 pattern[32]; for (u32 i = 0; i < 32; i++) { - pattern[i] = ARGS(i); - PolygonStipple(pattern[i]); + m_polygon_stipple_pattern[i] = ARGS(i); } + break; } - break; // Zcull case NV4097_SET_ZCULL_EN: { - const u32 value = ARGS(0); - Enable(NV4097_SET_DEPTH_TEST_ENABLE, value & 0x1); - Enable(NV4097_SET_STENCIL_TEST_ENABLE, value & 0x2); + const u32 a0 = ARGS(0); + + m_set_depth_test = a0 & 0x1 ? true : false; + m_set_stencil_test = a0 & 0x2 ? true : false; + break; } - break; case NV4097_SET_ZCULL_CONTROL0: { @@ -1808,17 +1761,17 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const { LOG_WARNING(RSX, "TODO: NV4097_SET_ZCULL_CONTROL0: 0x%x", value); } + break; } - break; - + case NV4097_SET_ZCULL_CONTROL1: { if (u32 value = ARGS(0)) { LOG_WARNING(RSX, "TODO: NV4097_SET_ZCULL_CONTROL1: 0x%x", value); } + break; } - break; case NV4097_SET_ZCULL_STATS_ENABLE: { @@ -1826,8 +1779,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const { LOG_WARNING(RSX, "TODO: NV4097_SET_ZCULL_STATS_ENABLE: 0x%x", value); } + break; } - break; case NV4097_ZCULL_SYNC: { @@ -1835,8 +1788,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const { LOG_WARNING(RSX, "TODO: NV4097_ZCULL_SYNC: 0x%x", value); } + break; } - break; // Reports case NV4097_GET_REPORT: @@ -1855,12 +1808,12 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const case CELL_GCM_ZCULL_STATS3: value = 0; LOG_WARNING(RSX, "NV4097_GET_REPORT: Unimplemented type %d", type); - break; + break; default: value = 0; LOG_ERROR(RSX, "NV4097_GET_REPORT: Bad type %d", type); - break; + break; } // Get timestamp, and convert it from microseconds to nanoseconds @@ -1870,14 +1823,14 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const vm::write64(m_local_mem_addr + offset + 0x0, timestamp); vm::write32(m_local_mem_addr + offset + 0x8, value); vm::write32(m_local_mem_addr + offset + 0xc, 0); + break; } - break; case NV4097_CLEAR_REPORT_VALUE: { const u32 type = ARGS(0); - switch(type) + switch (type) { case CELL_GCM_ZPASS_PIXEL_CNT: LOG_WARNING(RSX, "TODO: NV4097_CLEAR_REPORT_VALUE: ZPASS_PIXEL_CNT"); @@ -1888,33 +1841,41 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const default: LOG_ERROR(RSX, "NV4097_CLEAR_REPORT_VALUE: Bad type: %d", type); break; - } + } + break; } - break; // Clip Plane case NV4097_SET_USER_CLIP_PLANE_CONTROL: { - const u32 value = ARGS(0); - Enable(cmd, value); + const u32 a0 = ARGS(0); + m_set_clip_plane = true; + m_clip_plane_0 = (a0 & 0xf) ? true : false; + m_clip_plane_1 = ((a0 >> 4)) & 0xf ? true : false; + m_clip_plane_2 = ((a0 >> 8)) & 0xf ? true : false; + m_clip_plane_3 = ((a0 >> 12)) & 0xf ? true : false; + m_clip_plane_4 = ((a0 >> 16)) & 0xf ? true : false; + m_clip_plane_5 = (a0 >> 20) ? true : false; + break; } - break; // Fog case NV4097_SET_FOG_MODE: { - const u32 value = ARGS(0); - Fogi(value); + m_set_fog_mode = true; + m_fog_mode = ARGS(0); + break; } - break; case NV4097_SET_FOG_PARAMS: { - const u32 start = ARGS(0); - const u32 end = ARGS(1); - Fogf((float&)start, (float&)end); + m_set_fog_params = true; + const u32 a0 = ARGS(0); + const u32 a1 = ARGS(1); + m_fog_param0 = (float&)a0; + m_fog_param1 = (float&)a1; + break; } - break; // Zmin_max case NV4097_SET_ZMIN_MAX_CONTROL: @@ -1924,8 +1885,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const const u8 cullIgnoreW = (ARGS(0) >> 8) & 0xf; LOG_WARNING(RSX, "TODO: NV4097_SET_ZMIN_MAX_CONTROL: cullNearFarEnable=%d, zclampEnable=%d, cullIgnoreW=%d", cullNearFarEnable, zclampEnable, cullIgnoreW); + break; } - break; case NV4097_SET_WINDOW_OFFSET: { @@ -1933,16 +1894,16 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const const u16 y = ARGS(0) >> 16; LOG_WARNING(RSX, "TODO: NV4097_SET_WINDOW_OFFSET: x=%d, y=%d", x, y); + break; } - break; case NV4097_SET_FREQUENCY_DIVIDER_OPERATION: { m_set_frequency_divider_operation = ARGS(0); - + LOG_WARNING(RSX, "TODO: NV4097_SET_FREQUENCY_DIVIDER_OPERATION: %d", m_set_frequency_divider_operation); + break; } - break; case NV4097_SET_RENDER_ENABLE: { @@ -1950,16 +1911,16 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const const u8 mode = ARGS(0) >> 24; LOG_WARNING(RSX, "TODO: NV4097_SET_RENDER_ENABLE: Offset=0x%06x, Mode=0x%x", offset, mode); + break; } - break; case NV4097_SET_ZPASS_PIXEL_COUNT_ENABLE: { const u32 enable = ARGS(0); LOG_WARNING(RSX, "TODO: NV4097_SET_ZPASS_PIXEL_COUNT_ENABLE: %d", enable); + break; } - break; // NV0039 case NV0039_SET_CONTEXT_DMA_BUFFER_IN: @@ -1968,8 +1929,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const const u32 dstContext = ARGS(1); m_context_dma_buffer_in_src = srcContext; m_context_dma_buffer_in_dst = dstContext; + break; } - break; case NV0039_OFFSET_IN: { @@ -1984,7 +1945,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const const u32 notify = ARGS(7); // The existing GCM commands use only the value 0x1 for inFormat and outFormat - if (inFormat != 0x01 || outFormat != 0x01) + if (inFormat != 0x01 || outFormat != 0x01) { LOG_ERROR(RSX, "NV0039_OFFSET_IN: Unsupported format: inFormat=%d, outFormat=%d", inFormat, outFormat); } @@ -1998,8 +1959,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const LOG_ERROR(RSX, "NV0039_OFFSET_IN: bad offset(in=0x%x, out=0x%x), pitch(in=0x%x, out=0x%x), line(len=0x%x, cnt=0x%x), fmt(in=0x%x, out=0x%x), notify=0x%x", inOffset, outOffset, inPitch, outPitch, lineLength, lineCount, inFormat, outFormat, notify); } + break; } - break; case NV0039_OFFSET_OUT: // [E : RSXThread]: TODO: unknown/illegal method [0x00002310](0x0) { @@ -2012,8 +1973,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const { LOG_ERROR(RSX, "TODO: NV0039_OFFSET_OUT: offset=0x%x", offset); } + break; } - break; case NV0039_PITCH_IN: { @@ -2021,8 +1982,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const { LOG_WARNING(RSX, "TODO: NV0039_PITCH_IN: 0x%x", value); } + break; } - break; case NV0039_BUFFER_NOTIFY: { @@ -2030,29 +1991,29 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const { LOG_WARNING(RSX, "TODO: NV0039_BUFFER_NOTIFY: 0x%x", value); } + break; } - break; // NV3062 case NV3062_SET_CONTEXT_DMA_IMAGE_DESTIN: { m_context_dma_img_dst = ARGS(0); + break; } - break; case NV3062_SET_OFFSET_DESTIN: { m_dst_offset = ARGS(0); + break; } - break; case NV3062_SET_COLOR_FORMAT: { m_color_format = ARGS(0); m_color_format_src_pitch = ARGS(1); m_color_format_dst_pitch = ARGS(1) >> 16; + break; } - break; // NV309E case NV309E_SET_CONTEXT_DMA_IMAGE: @@ -2061,8 +2022,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const { LOG_WARNING(RSX, "TODO: NV309E_SET_CONTEXT_DMA_IMAGE: 0x%x", value); } + break; } - break; case NV309E_SET_FORMAT: { @@ -2072,8 +2033,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const const u32 offset = ARGS(1); LOG_WARNING(RSX, "TODO: NV309E_SET_FORMAT: Format:0x%x, Width:%d, Height:%d, Offset:0x%x", format, width, height, offset); + break; } - break; // NV308A case NV308A_POINT: @@ -2081,8 +2042,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const const u32 a0 = ARGS(0); m_point_x = a0 & 0xffff; m_point_y = a0 >> 16; + break; } - break; case NV308A_COLOR: { @@ -2125,15 +2086,15 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const m_fragment_constants.push_back(c); //LOG_WARNING(RSX, "NV308A_COLOR: [%d]: %f, %f, %f, %f", c.id, c.x, c.y, c.z, c.w); + break; } - break; // NV3089 case NV3089_SET_CONTEXT_DMA_IMAGE: { m_context_dma_img_src = ARGS(0); + break; } - break; case NV3089_SET_CONTEXT_SURFACE: { @@ -2141,8 +2102,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const { LOG_ERROR(RSX, "NV3089_SET_CONTEXT_SURFACE: Unsupported surface (0x%x)", ARGS(0)); } + break; } - break; case NV3089_IMAGE_IN_SIZE: { @@ -2174,8 +2135,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const //(u32&)pixels_dst[dst_offset] = (u32&)pixels_src[src_offset]; } } + break; } - break; case NV3089_SET_COLOR_CONVERSION: { @@ -2194,8 +2155,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const m_color_conv_dtdy = ARGS(8); LOG_WARNING(RSX, "TODO: NV3089_SET_COLOR_CONVERSION"); + break; } - break; case GCM_SET_USER_COMMAND: { @@ -2205,8 +2166,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const { cb(CPU, cause); }); + break; } - break; // Note: What is this? NV4097 offsets? case 0x000002c8: @@ -2216,7 +2177,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const case 0x000002e8: case 0x000002f0: case 0x000002f8: - break; + break; // The existing GCM commands don't use any of the following NV4097 / NV0039 / NV3062 / NV309E / NV308A / NV3089 methods case NV4097_SET_WINDOW_CLIP_TYPE: @@ -2224,8 +2185,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const case NV4097_SET_WINDOW_CLIP_VERTICAL: { LOG_WARNING(RSX, "Unused NV4097 method 0x%x detected!", cmd); + break; } - break; case NV0039_SET_CONTEXT_DMA_BUFFER_OUT: case NV0039_PITCH_OUT: @@ -2236,8 +2197,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const case NV0039_SET_CONTEXT_DMA_NOTIFIES: { LOG_WARNING(RSX, "Unused NV0039 method 0x%x detected!", cmd); + break; } - break; case NV3062_SET_OBJECT: case NV3062_SET_CONTEXT_DMA_NOTIFIES: @@ -2246,8 +2207,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const case NV3062_SET_OFFSET_SOURCE: { LOG_WARNING(RSX, "Unused NV3062 method 0x%x detected!", cmd); + break; } - break; case NV308A_SET_OBJECT: case NV308A_SET_CONTEXT_DMA_NOTIFIES: @@ -2265,16 +2226,16 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const case NV308A_SIZE_IN: { LOG_WARNING(RSX, "Unused NV308A method 0x%x detected!", cmd); + break; } - break; case NV309E_SET_OBJECT: case NV309E_SET_CONTEXT_DMA_NOTIFIES: case NV309E_SET_OFFSET: { LOG_WARNING(RSX, "Unused NV309E method 0x%x detected!", cmd); + break; } - break; case NV3089_SET_OBJECT: case NV3089_SET_CONTEXT_DMA_NOTIFIES: @@ -2295,20 +2256,21 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const case NV3089_IMAGE_IN: { LOG_WARNING(RSX, "Unused NV3089 methods 0x%x detected!", cmd); + break; } - break; default: { std::string log = GetMethodName(cmd); log += "("; - for (u32 i=0; i lock(m_cs_main); - inc=1; + inc = 1; u32 get = m_ctrl->get.read_sync(); u32 put = m_ctrl->put.read_sync(); @@ -2405,12 +2367,12 @@ void RSXThread::Task() const u32 cmd = ReadIO32(get); const u32 count = (cmd >> 18) & 0x7ff; - + if (Ini.RSXLogging.GetValue()) { LOG_NOTICE(Log::RSX, "%s (cmd=0x%x)", GetMethodName(cmd & 0xffff).c_str(), cmd); } - + if (cmd & CELL_GCM_METHOD_FLAG_JUMP) { u32 offs = cmd & 0x1fffffff; @@ -2418,7 +2380,6 @@ void RSXThread::Task() m_ctrl->get.exchange(be_t::make(offs)); continue; } - if (cmd & CELL_GCM_METHOD_FLAG_CALL) { m_call_stack.push(get + 4); @@ -2427,7 +2388,6 @@ void RSXThread::Task() m_ctrl->get.exchange(be_t::make(offs)); continue; } - if (cmd == CELL_GCM_METHOD_FLAG_RETURN) { u32 get = m_call_stack.top(); @@ -2436,7 +2396,6 @@ void RSXThread::Task() m_ctrl->get.exchange(be_t::make(get)); continue; } - if (cmd & CELL_GCM_METHOD_FLAG_NON_INCREMENT) { //LOG_WARNING(RSX, "rsx non increment cmd! 0x%x", cmd); diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index c0f412f648..9732c8a418 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -90,7 +90,7 @@ struct RSXTransformConstant } }; -class RSXThread : public ThreadBase +class RSXThread : public ThreadBase { public: static const uint m_textures_count = 16; @@ -498,7 +498,7 @@ protected: m_front_face = 0x0901; // GL_CCW m_cull_face = 0x0405; // GL_BACK m_alpha_func = 0x0207; // GL_ALWAYS - m_alpha_ref = 0.0; + m_alpha_ref = 0.0f; m_logic_op = 0x1503; // GL_COPY m_shade_mode = 0x1D01; // GL_SMOOTH m_depth_mask = 1; @@ -523,7 +523,7 @@ protected: m_vertex_data_base_index = 0; // Construct Stipple Pattern - for (size_t i = 0; i < 32; i++) + for (size_t i = 0; i < 32; i++) { m_polygon_stipple_pattern[i] = 0xFFFFFFFF; } @@ -629,54 +629,20 @@ 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); - + virtual void OnInit() = 0; virtual void OnInitThread() = 0; virtual void OnExitThread() = 0; virtual void OnReset() = 0; virtual void ExecCMD() = 0; - virtual void Enable(u32 cmd, u32 enable) = 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 AlphaFunc(u32 func, float ref) = 0; - virtual void DepthFunc(u32 func) = 0; - virtual void DepthMask(u32 flag) = 0; - virtual void PolygonMode(u32 face, u32 mode) = 0; - virtual void PointSize(float size) = 0; - virtual void LogicOp(u32 opcode) = 0; - virtual void LineWidth(float width) = 0; - virtual void LineStipple(u16 factor, u16 pattern) = 0; - virtual void PolygonStipple(u32 pattern) = 0; - virtual void PrimitiveRestartIndex(u32 index) = 0; - virtual void CullFace(u32 mode) = 0; - virtual void FrontFace(u32 mode) = 0; - virtual void Fogi(u32 mode) = 0; - virtual void Fogf(float start, float end) = 0; - virtual void PolygonOffset(float factor, float bias) = 0; - virtual void DepthRangef(float min, float max) = 0; - virtual void BlendEquationSeparate(u16 rgb, u16 a) = 0; - virtual void BlendFuncSeparate(u16 srcRGB, u16 dstRGB, u16 srcAlpha, u16 dstAlpha) = 0; - virtual void BlendColor(u8 r, u8 g, u8 b, u8 a) = 0; - virtual void LightModeli(u32 enable) = 0; - virtual void ShadeModel(u32 mode) = 0; - virtual void DepthBoundsEXT(float min, float max) = 0; - virtual void Scissor(u16 x, u16 y, u16 width, u16 height) = 0; - virtual void StencilOp(u32 fail, u32 zfail, u32 zpass) = 0; - virtual void StencilMask(u32 mask) = 0; - virtual void StencilFunc(u32 func, u32 ref, u32 mask) = 0; - virtual void StencilOpSeparate(u32 mode, u32 fail, u32 zfail, u32 zpass) = 0; - virtual void StencilMaskSeparate(u32 mode, u32 mask) = 0; - virtual void StencilFuncSeparate(u32 mode, u32 func, u32 ref, u32 mask) = 0; + virtual void ExecCMD(u32 cmd) = 0; virtual void Flip() = 0; void LoadVertexData(u32 first, u32 count) { for (u32 i = 0; i < m_vertex_count; ++i) { - if(!m_vertex_data[i].IsEnabled()) continue; + if (!m_vertex_data[i].IsEnabled()) continue; m_vertex_data[i].Load(first, count, m_vertex_data_base_offset, m_vertex_data_base_index); }