diff options
-rw-r--r-- | externals/cmake-modules/FindSDL2.cmake | 8 | ||||
-rw-r--r-- | src/core/arm/skyeye_common/armstate.cpp | 7 | ||||
-rw-r--r-- | src/core/file_sys/archive_extsavedata.h | 3 | ||||
-rw-r--r-- | src/core/hle/kernel/session.h | 12 | ||||
-rw-r--r-- | src/core/hle/service/soc_u.cpp | 13 | ||||
-rw-r--r-- | src/core/loader/loader.h | 2 | ||||
-rw-r--r-- | src/video_core/command_processor.cpp | 46 | ||||
-rw-r--r-- | src/video_core/pica.cpp | 15 | ||||
-rw-r--r-- | src/video_core/pica.h | 15 | ||||
-rw-r--r-- | src/video_core/pica_state.h | 15 | ||||
-rw-r--r-- | src/video_core/primitive_assembly.h | 2 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 3 | ||||
-rw-r--r-- | src/video_core/shader/shader.cpp | 18 |
13 files changed, 102 insertions, 57 deletions
diff --git a/externals/cmake-modules/FindSDL2.cmake b/externals/cmake-modules/FindSDL2.cmake index 0af86840a..9b8daa0d1 100644 --- a/externals/cmake-modules/FindSDL2.cmake +++ b/externals/cmake-modules/FindSDL2.cmake @@ -134,11 +134,17 @@ SET(SDL2_SEARCH_PATHS ${SDL2_PATH} ) +if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(VC_LIB_PATH_SUFFIX lib/x64) +else() + set(VC_LIB_PATH_SUFFIX lib/x86) +endif() + FIND_LIBRARY(SDL2_LIBRARY_TEMP NAMES SDL2 HINTS $ENV{SDL2DIR} - PATH_SUFFIXES lib64 lib + PATH_SUFFIXES lib64 lib ${VC_LIB_PATH_SUFFIX} PATHS ${SDL2_SEARCH_PATHS} ) diff --git a/src/core/arm/skyeye_common/armstate.cpp b/src/core/arm/skyeye_common/armstate.cpp index 2d814345a..5550c112e 100644 --- a/src/core/arm/skyeye_common/armstate.cpp +++ b/src/core/arm/skyeye_common/armstate.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include <algorithm> #include "common/swap.h" #include "common/logging/log.h" #include "core/memory.h" @@ -48,8 +49,7 @@ void ARMul_State::ChangePrivilegeMode(u32 new_mode) Spsr[UNDEFBANK] = Spsr_copy; break; case FIQ32MODE: - Reg_firq[0] = Reg[13]; - Reg_firq[1] = Reg[14]; + std::copy(Reg.begin() + 8, Reg.end() - 1, Reg_firq.begin()); Spsr[FIQBANK] = Spsr_copy; break; } @@ -85,8 +85,7 @@ void ARMul_State::ChangePrivilegeMode(u32 new_mode) Bank = UNDEFBANK; break; case FIQ32MODE: - Reg[13] = Reg_firq[0]; - Reg[14] = Reg_firq[1]; + std::copy(Reg_firq.begin(), Reg_firq.end(), Reg.begin() + 8); Spsr_copy = Spsr[FIQBANK]; Bank = FIQBANK; break; diff --git a/src/core/file_sys/archive_extsavedata.h b/src/core/file_sys/archive_extsavedata.h index 287a6fee1..e9a72850d 100644 --- a/src/core/file_sys/archive_extsavedata.h +++ b/src/core/file_sys/archive_extsavedata.h @@ -45,13 +45,14 @@ public: void WriteIcon(const Path& path, const u8* icon_data, size_t icon_size); private: + bool shared; ///< Whether this archive represents an ExtSaveData archive or a SharedExtSaveData archive + /** * This holds the full directory path for this archive, it is only set after a successful call * to Open, this is formed as <base extsavedatapath>/<type>/<high>/<low>. * See GetExtSaveDataPath for the code that extracts this data from an archive path. */ std::string mount_point; - bool shared; ///< Whether this archive represents an ExtSaveData archive or a SharedExtSaveData archive }; /** diff --git a/src/core/hle/kernel/session.h b/src/core/hle/kernel/session.h index adaffcafe..6ddaf970e 100644 --- a/src/core/hle/kernel/session.h +++ b/src/core/hle/kernel/session.h @@ -16,23 +16,23 @@ namespace IPC { -inline u32 MakeHeader(u16 command_id, unsigned int regular_params, unsigned int translate_params) { +constexpr u32 MakeHeader(u16 command_id, unsigned int regular_params, unsigned int translate_params) { return ((u32)command_id << 16) | (((u32)regular_params & 0x3F) << 6) | (((u32)translate_params & 0x3F) << 0); } -inline u32 MoveHandleDesc(unsigned int num_handles = 1) { +constexpr u32 MoveHandleDesc(unsigned int num_handles = 1) { return 0x0 | ((num_handles - 1) << 26); } -inline u32 CopyHandleDesc(unsigned int num_handles = 1) { +constexpr u32 CopyHandleDesc(unsigned int num_handles = 1) { return 0x10 | ((num_handles - 1) << 26); } -inline u32 CallingPidDesc() { +constexpr u32 CallingPidDesc() { return 0x20; } -inline u32 StaticBufferDesc(u32 size, unsigned int buffer_id) { +constexpr u32 StaticBufferDesc(u32 size, unsigned int buffer_id) { return 0x2 | (size << 14) | ((buffer_id & 0xF) << 10); } @@ -42,7 +42,7 @@ enum MappedBufferPermissions { RW = R | W, }; -inline u32 MappedBufferDesc(u32 size, MappedBufferPermissions perms) { +constexpr u32 MappedBufferDesc(u32 size, MappedBufferPermissions perms) { return 0x8 | (size << 4) | (u32)perms; } diff --git a/src/core/hle/service/soc_u.cpp b/src/core/hle/service/soc_u.cpp index b52e52d4a..ff0af8f12 100644 --- a/src/core/hle/service/soc_u.cpp +++ b/src/core/hle/service/soc_u.cpp @@ -5,6 +5,7 @@ #include <algorithm> #include <cstring> #include <unordered_map> +#include <vector> #include "common/assert.h" #include "common/bit_field.h" @@ -593,17 +594,13 @@ static void Poll(Service::Interface* self) { // The 3ds_pollfd and the pollfd structures may be different (Windows/Linux have different sizes) // so we have to copy the data - pollfd* platform_pollfd = new pollfd[nfds]; - for (unsigned current_fds = 0; current_fds < nfds; ++current_fds) - platform_pollfd[current_fds] = CTRPollFD::ToPlatform(input_fds[current_fds]); + std::vector<pollfd> platform_pollfd(nfds); + std::transform(input_fds, input_fds + nfds, platform_pollfd.begin(), CTRPollFD::ToPlatform); - int ret = ::poll(platform_pollfd, nfds, timeout); + const int ret = ::poll(platform_pollfd.data(), nfds, timeout); // Now update the output pollfd structure - for (unsigned current_fds = 0; current_fds < nfds; ++current_fds) - output_fds[current_fds] = CTRPollFD::FromPlatform(platform_pollfd[current_fds]); - - delete[] platform_pollfd; + std::transform(platform_pollfd.begin(), platform_pollfd.end(), output_fds, CTRPollFD::FromPlatform); int result = 0; if (ret == SOCKET_ERROR_VALUE) diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h index a7f2715ba..84a4ce5fc 100644 --- a/src/core/loader/loader.h +++ b/src/core/loader/loader.h @@ -74,7 +74,7 @@ enum class ResultStatus { ErrorEncrypted, }; -static inline u32 MakeMagic(char a, char b, char c, char d) { +constexpr u32 MakeMagic(char a, char b, char c, char d) { return a | b << 8 | c << 16 | d << 24; } diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp index 4b59984ad..028b59348 100644 --- a/src/video_core/command_processor.cpp +++ b/src/video_core/command_processor.cpp @@ -75,12 +75,17 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::P3D); break; + case PICA_REG_INDEX_WORKAROUND(triangle_topology, 0x25E): + g_state.primitive_assembler.Reconfigure(regs.triangle_topology); + break; + + case PICA_REG_INDEX_WORKAROUND(restart_primitive, 0x25F): + g_state.primitive_assembler.Reset(); + break; + case PICA_REG_INDEX_WORKAROUND(vs_default_attributes_setup.index, 0x232): - if (regs.vs_default_attributes_setup.index == 15) { - // Reset immediate primitive state - g_state.immediate.primitive_assembler.Reconfigure(regs.triangle_topology); - g_state.immediate.attribute_id = 0; - } + g_state.immediate.current_attribute = 0; + default_attr_counter = 0; break; // Load default vertex input attributes @@ -105,7 +110,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { break; } - Math::Vec4<float24>& attribute = g_state.vs.default_attributes[setup.index]; + Math::Vec4<float24> attribute; // NOTE: The destination component order indeed is "backwards" attribute.w = float24::FromRaw(default_attr_write_buffer[0] >> 8); @@ -119,26 +124,29 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { // TODO: Verify that this actually modifies the register! if (setup.index < 15) { + g_state.vs.default_attributes[setup.index] = attribute; setup.index++; } else { // Put each attribute into an immediate input buffer. // When all specified immediate attributes are present, the Vertex Shader is invoked and everything is // sent to the primitive assembler. - auto& immediate_input = g_state.immediate.input; - auto& immediate_attribute_id = g_state.immediate.attribute_id; - const auto& attribute_config = regs.vertex_attributes; + auto& immediate_input = g_state.immediate.input_vertex; + auto& immediate_attribute_id = g_state.immediate.current_attribute; immediate_input.attr[immediate_attribute_id++] = attribute; - if (immediate_attribute_id >= attribute_config.GetNumTotalAttributes()) { + if (immediate_attribute_id >= regs.vs.num_input_attributes+1) { immediate_attribute_id = 0; Shader::UnitState<false> shader_unit; Shader::Setup(shader_unit); + if (g_debug_context) + g_debug_context->OnEvent(DebugContext::Event::VertexLoaded, static_cast<void*>(&immediate_input)); + // Send to vertex shader - Shader::OutputVertex output = Shader::Run(shader_unit, immediate_input, attribute_config.GetNumTotalAttributes()); + Shader::OutputVertex output = Shader::Run(shader_unit, immediate_input, regs.vs.num_input_attributes+1); // Send to renderer using Pica::Shader::OutputVertex; @@ -146,7 +154,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { VideoCore::g_renderer->Rasterizer()->AddTriangle(v0, v1, v2); }; - g_state.immediate.primitive_assembler.SubmitVertex(output, AddTriangle); + g_state.primitive_assembler.SubmitVertex(output, AddTriangle); } } } @@ -154,9 +162,13 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { } case PICA_REG_INDEX(gpu_mode): - if (regs.gpu_mode == Regs::GPUMode::Configuring && regs.vs_default_attributes_setup.index == 15) { + if (regs.gpu_mode == Regs::GPUMode::Configuring) { // Draw immediate mode triangles when GPU Mode is set to GPUMode::Configuring VideoCore::g_renderer->Rasterizer()->DrawTriangles(); + + if (g_debug_context) { + g_debug_context->OnEvent(DebugContext::Event::FinishedPrimitiveBatch, nullptr); + } } break; @@ -241,7 +253,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { DebugUtils::GeometryDumper geometry_dumper; PrimitiveAssembler<DebugUtils::GeometryDumper::Vertex> dumping_primitive_assembler(regs.triangle_topology.Value()); #endif - PrimitiveAssembler<Shader::OutputVertex> primitive_assembler(regs.triangle_topology.Value()); + PrimitiveAssembler<Shader::OutputVertex>& primitive_assembler = g_state.primitive_assembler; if (g_debug_context) { for (int i = 0; i < 3; ++i) { @@ -412,16 +424,10 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { range.second, range.first); } - VideoCore::g_renderer->Rasterizer()->DrawTriangles(); - #if PICA_DUMP_GEOMETRY geometry_dumper.Dump(); #endif - if (g_debug_context) { - g_debug_context->OnEvent(DebugContext::Event::FinishedPrimitiveBatch, nullptr); - } - break; } diff --git a/src/video_core/pica.cpp b/src/video_core/pica.cpp index 32ad72674..ccbaf071b 100644 --- a/src/video_core/pica.cpp +++ b/src/video_core/pica.cpp @@ -493,12 +493,25 @@ std::string Regs::GetCommandName(int index) { } void Init() { + g_state.Reset(); } void Shutdown() { Shader::Shutdown(); +} + +template <typename T> +void Zero(T& o) { + memset(&o, 0, sizeof(o)); +} - memset(&g_state, 0, sizeof(State)); +void State::Reset() { + Zero(regs); + Zero(vs); + Zero(gs); + Zero(cmd_list); + Zero(immediate); + primitive_assembler.Reconfigure(Regs::TriangleTopology::List); } } diff --git a/src/video_core/pica.h b/src/video_core/pica.h index 337cff8ce..16f9e4006 100644 --- a/src/video_core/pica.h +++ b/src/video_core/pica.h @@ -71,7 +71,7 @@ struct Regs { BitField<0, 24, u32> viewport_depth_range; // float24 BitField<0, 24, u32> viewport_depth_far_plane; // float24 - INSERT_PADDING_WORDS(0x1); + BitField<0, 3, u32> vs_output_total; union VSOutputAttributes { // Maps components of output vertex attributes to semantics @@ -1123,7 +1123,12 @@ struct Regs { BitField<24, 8, u32> w; } int_uniforms[4]; - INSERT_PADDING_WORDS(0x5); + INSERT_PADDING_WORDS(0x4); + + union { + // Number of input attributes to shader unit - 1 + BitField<0, 4, u32> num_input_attributes; + }; // Offset to shader program entry point (in words) BitField<0, 16, u32> main_offset; @@ -1157,8 +1162,10 @@ struct Regs { } } input_register_map; - // OUTMAP_MASK, 0x28E, CODETRANSFER_END - INSERT_PADDING_WORDS(0x3); + BitField<0, 16, u32> output_mask; + + // 0x28E, CODETRANSFER_END + INSERT_PADDING_WORDS(0x2); struct { enum Format : u32 diff --git a/src/video_core/pica_state.h b/src/video_core/pica_state.h index c7616bc55..323290054 100644 --- a/src/video_core/pica_state.h +++ b/src/video_core/pica_state.h @@ -12,6 +12,8 @@ namespace Pica { /// Struct used to describe current Pica state struct State { + void Reset(); + /// Pica registers Regs regs; @@ -46,13 +48,14 @@ struct State { /// Struct used to describe immediate mode rendering state struct ImmediateModeState { - Shader::InputVertex input; - // This is constructed with a dummy triangle topology - PrimitiveAssembler<Shader::OutputVertex> primitive_assembler; - int attribute_id = 0; - - ImmediateModeState() : primitive_assembler(Regs::TriangleTopology::List) {} + // Used to buffer partial vertices for immediate-mode rendering. + Shader::InputVertex input_vertex; + // Index of the next attribute to be loaded into `input_vertex`. + int current_attribute = 0; } immediate; + + // This is constructed with a dummy triangle topology + PrimitiveAssembler<Shader::OutputVertex> primitive_assembler; }; extern State g_state; ///< Current Pica state diff --git a/src/video_core/primitive_assembly.h b/src/video_core/primitive_assembly.h index cc6e5fde5..9396b4c85 100644 --- a/src/video_core/primitive_assembly.h +++ b/src/video_core/primitive_assembly.h @@ -20,7 +20,7 @@ struct PrimitiveAssembler { VertexType& v1, VertexType& v2)>; - PrimitiveAssembler(Regs::TriangleTopology topology); + PrimitiveAssembler(Regs::TriangleTopology topology = Regs::TriangleTopology::List); /* * Queues a vertex, builds primitives from the vertex queue according to the given diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index b3dc6aa19..1fadcf5ae 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -190,6 +190,9 @@ void RasterizerOpenGL::AddTriangle(const Pica::Shader::OutputVertex& v0, } void RasterizerOpenGL::DrawTriangles() { + if (vertex_batch.empty()) + return; + SyncFramebuffer(); SyncDrawState(); diff --git a/src/video_core/shader/shader.cpp b/src/video_core/shader/shader.cpp index 509558fc0..eb1db0778 100644 --- a/src/video_core/shader/shader.cpp +++ b/src/video_core/shader/shader.cpp @@ -121,15 +121,23 @@ OutputVertex Run(UnitState<false>& state, const InputVertex& input, int num_attr OutputVertex ret; // TODO(neobrain): Under some circumstances, up to 16 attributes may be output. We need to // figure out what those circumstances are and enable the remaining outputs then. - for (int i = 0; i < 7; ++i) { - const auto& output_register_map = g_state.regs.vs_output_attributes[i]; // TODO: Don't hardcode VS here + unsigned index = 0; + for (unsigned i = 0; i < 7; ++i) { + + if (index >= g_state.regs.vs_output_total) + break; + + if ((g_state.regs.vs.output_mask & (1 << i)) == 0) + continue; + + const auto& output_register_map = g_state.regs.vs_output_attributes[index]; // TODO: Don't hardcode VS here u32 semantics[4] = { output_register_map.map_x, output_register_map.map_y, output_register_map.map_z, output_register_map.map_w }; - for (int comp = 0; comp < 4; ++comp) { + for (unsigned comp = 0; comp < 4; ++comp) { float24* out = ((float24*)&ret) + semantics[comp]; if (semantics[comp] != Regs::VSOutputAttributes::INVALID) { *out = state.registers.output[i][comp]; @@ -139,10 +147,12 @@ OutputVertex Run(UnitState<false>& state, const InputVertex& input, int num_attr memset(out, 0, sizeof(*out)); } } + + index++; } // The hardware takes the absolute and saturates vertex colors like this, *before* doing interpolation - for (int i = 0; i < 4; ++i) { + for (unsigned i = 0; i < 4; ++i) { ret.color[i] = float24::FromFloat32( std::fmin(std::fabs(ret.color[i].ToFloat32()), 1.0f)); } |