diff --git a/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.cpp b/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.cpp index 49ae5616e4..1c9f18e059 100644 --- a/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.cpp @@ -136,13 +136,13 @@ void VertexProgramDecompiler::SetDST(bool is_sca, std::string value) std::string mask = GetMask(is_sca); - value += mask; - - if (is_sca && d0.vec_result) + if (is_sca) { - //value = "vec4(" + value + ")"; + value = getFloatTypeName(4) + "(" + value + ")"; } + value += mask; + if (d0.staturate) { value = "clamp(" + value + ", 0.0, 1.0)"; @@ -309,7 +309,7 @@ void VertexProgramDecompiler::AddCodeCond(const std::string& dst, const std::str if (dst_var.swizzles[0].length() == 1) { - AddCode("if (" + cond + ".x) " + dst + " = " + getFloatTypeName(4) + "(" + src + ".xxxx).x;"); + AddCode("if (" + cond + ".x) " + dst + " = " + src + ";"); } else { @@ -559,7 +559,7 @@ std::string VertexProgramDecompiler::Decompile() case RSX_SCA_OPCODE_MOV: SetDSTSca("$s"); break; case RSX_SCA_OPCODE_RCP: SetDSTSca("(1.0 / $s)"); break; case RSX_SCA_OPCODE_RCC: SetDSTSca("clamp(1.0 / $s, 5.42101e-20, 1.884467e19)"); break; - case RSX_SCA_OPCODE_RSQ: SetDSTSca("1.f / sqrt($s)"); break; + case RSX_SCA_OPCODE_RSQ: SetDSTSca("(1.f / sqrt($s))"); break; case RSX_SCA_OPCODE_EXP: SetDSTSca("exp($s)"); break; case RSX_SCA_OPCODE_LOG: SetDSTSca("log($s)"); break; case RSX_SCA_OPCODE_LIT: SetDSTSca(getFloatTypeName(4) + "(1.0, $s.x, ($s.x > 0.0 ? exp($s.w * log2($s.y)) : 0.0), 1.0)"); break; diff --git a/rpcs3/Emu/RSX/GCM.h b/rpcs3/Emu/RSX/GCM.h index 26906b275b..20a21b590b 100644 --- a/rpcs3/Emu/RSX/GCM.h +++ b/rpcs3/Emu/RSX/GCM.h @@ -498,9 +498,9 @@ struct CellGcmSurface struct CellGcmReportData { - u64 timer; - u32 value; - u32 padding; + be_t timer; + be_t value; + be_t padding; }; struct CellGcmZcullInfo diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index a1159fb22a..3e1b7271f0 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -578,9 +578,9 @@ void GLGSRender::begin() u32 color_mask = rsx::method_registers[NV4097_SET_COLOR_MASK]; bool color_mask_b = color_mask & 0xff; - bool color_mask_g = color_mask >> 8; - bool color_mask_r = color_mask >> 16; - bool color_mask_a = color_mask >> 24; + bool color_mask_g = (color_mask >> 8) & 0xff; + bool color_mask_r = (color_mask >> 16) & 0xff; + bool color_mask_a = (color_mask >> 24) & 0xff; __glcheck glColorMask(color_mask_r, color_mask_g, color_mask_b, color_mask_a); __glcheck glDepthMask(rsx::method_registers[NV4097_SET_DEPTH_MASK]); @@ -591,7 +591,7 @@ void GLGSRender::begin() int viewport_w = int(rsx::method_registers[NV4097_SET_VIEWPORT_HORIZONTAL] >> 16); int viewport_h = int(rsx::method_registers[NV4097_SET_VIEWPORT_VERTICAL] >> 16); glViewport(viewport_x, viewport_y, viewport_w, viewport_h); - + //scissor test is always enabled glEnable(GL_SCISSOR_TEST); @@ -1035,7 +1035,7 @@ void GLGSRender::end() if (vertex_index_array.empty()) { - glDrawArrays(draw_mode - 1, 0, vertex_draw_count); + draw_fbo.draw_arrays(gl::draw_mode(draw_mode - 1), vertex_draw_count);\ } else { @@ -1158,11 +1158,7 @@ void nv4097_clear_surface(u32 arg, GLGSRender* renderer) } renderer->clear_surface_buffers = (gl::buffers)mask; - //renderer->init_buffers(); - //renderer->draw_fbo.draw_buffer(renderer->draw_fbo.color[0]); - //renderer->draw_fbo.clear(gl::buffers(mask)); - //renderer->draw_fbo.draw_arrays(gl::draw_mode::lines, 0); - //renderer->write_buffers(); + renderer->draw_fbo.clear((gl::buffers)mask); } using rsx_method_impl_t = void(*)(u32, GLGSRender*); @@ -1291,6 +1287,18 @@ bool GLGSRender::load_program() __glcheck m_program.uniforms["vc[" + std::to_string(constant.first) + "]"] = constant.second; } + for (u32 constant_offset : m_prog_buffer.getFragmentConstantOffsetsCache(&fragment_program)) + { + be_t *data = vm::get_ptr>(fragment_program.addr + constant_offset); + + u32 c0 = (data[0] >> 16 | data[0] << 16); + u32 c1 = (data[1] >> 16 | data[1] << 16); + u32 c2 = (data[2] >> 16 | data[2] << 16); + u32 c3 = (data[3] >> 16 | data[3] << 16); + + m_program.uniforms["fc" + std::to_string(constant_offset)] = color4f{ (f32&)c0, (f32&)c1, (f32&)c2, (f32&)c3 }; + } + return true; } @@ -1461,11 +1469,11 @@ void GLGSRender::init_buffers() case CELL_GCM_SURFACE_TARGET_NONE: break; case CELL_GCM_SURFACE_TARGET_0: - __glcheck draw_fbo.draw_buffers({ draw_fbo.color[0] }); + __glcheck draw_fbo.draw_buffer(draw_fbo.color[0]); break; case CELL_GCM_SURFACE_TARGET_1: - __glcheck draw_fbo.draw_buffers({ draw_fbo.color[1] }); + __glcheck draw_fbo.draw_buffer(draw_fbo.color[1] ); break; case CELL_GCM_SURFACE_TARGET_MRT1: @@ -1487,7 +1495,7 @@ void GLGSRender::init_buffers() if (clear_surface_buffers != gl::buffers::none) { - draw_fbo.clear(clear_surface_buffers); + //draw_fbo.clear(clear_surface_buffers); clear_surface_buffers = gl::buffers::none; } @@ -1707,6 +1715,8 @@ void GLGSRender::flip(int buffer) if (draw_fbo && !Ini.GSDumpColorBuffers.GetValue()) { + skip_read = true; + /* for (uint i = 0; i < rsx::limits::color_buffers_count; ++i) { u32 color_address = rsx::get_address(rsx::method_registers[mr_color_offset[i]], rsx::method_registers[mr_color_dma[i]]); @@ -1718,6 +1728,7 @@ void GLGSRender::flip(int buffer) break; } } + */ } if (!skip_read) diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 9d75c702dc..607883c720 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -47,13 +47,13 @@ namespace rsx __forceinline void semaphore_acquire(thread* rsx, u32 arg) { //TODO: dma - /*while (vm::read32(rsx->label_addr + method_registers[NV406E_SEMAPHORE_OFFSET]) != arg) + while (vm::read32(rsx->label_addr + method_registers[NV406E_SEMAPHORE_OFFSET]) != arg) { if (Emu.IsStopped()) break; std::this_thread::sleep_for(std::chrono::milliseconds(1)); - }*/ + } } __forceinline void semaphore_release(thread* rsx, u32 arg) @@ -246,7 +246,11 @@ namespace rsx u8 type = arg >> 24; u32 offset = arg & 0xffffff; - u32 value; + //TODO: use DMA + vm::ptr result = { rsx->local_mem_addr + offset }; + + result->timer = rsx->timestamp(); + switch (type) { case CELL_GCM_ZPASS_PIXEL_CNT: @@ -254,24 +258,17 @@ namespace rsx case CELL_GCM_ZCULL_STATS1: case CELL_GCM_ZCULL_STATS2: case CELL_GCM_ZCULL_STATS3: - value = 0; + result->value = 0; LOG_WARNING(RSX, "NV4097_GET_REPORT: Unimplemented type %d", type); break; default: - value = 0; + result->value = 0; LOG_ERROR(RSX, "NV4097_GET_REPORT: Bad type %d", type); break; } - // NOTE: DMA broken, implement proper lpar mapping (sys_rsx) - //dma_write64(dma_report, offset + 0x0, rsx->timestamp()); - //dma_write32(dma_report, offset + 0x8, value); - //dma_write32(dma_report, offset + 0xc, 0); - - vm::write64(rsx->local_mem_addr + offset + 0x0, rsx->timestamp()); - vm::write32(rsx->local_mem_addr + offset + 0x8, value); - vm::write32(rsx->local_mem_addr + offset + 0xc, 0); + //result->padding = 0; } __forceinline void clear_report_value(thread* rsx, u32 arg) @@ -305,7 +302,7 @@ namespace rsx LOG_ERROR(RSX, "%s: y is not null (0x%x)", __FUNCTION__, y); } - u32 address = get_address(method_registers[NV3062_SET_OFFSET_DESTIN] + (x << 2) + index, method_registers[NV3062_SET_CONTEXT_DMA_IMAGE_DESTIN]); + u32 address = get_address(method_registers[NV3062_SET_OFFSET_DESTIN] + (x << 2) + index * 4, method_registers[NV3062_SET_CONTEXT_DMA_IMAGE_DESTIN]); vm::write32(address, arg); } } @@ -916,7 +913,6 @@ namespace rsx for (auto &vertex_array : vertex_arrays) vertex_array.clear(); - fragment_constants.clear(); transform_constants.clear(); } diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index 72ed9a202c..5aa51ae326 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -159,7 +159,6 @@ namespace rsx std::vector vertex_index_array; u32 vertex_draw_count = 0; - std::unordered_map> fragment_constants; std::unordered_map> transform_constants; u32 transform_program[512 * 4] = {};