diff --git a/src/core/hle/service/sockets/sfdnsres.cpp b/src/core/hle/service/sockets/sfdnsres.cpp index 04a42b7197..486d07c0d1 100644 --- a/src/core/hle/service/sockets/sfdnsres.cpp +++ b/src/core/hle/service/sockets/sfdnsres.cpp @@ -29,7 +29,7 @@ SFDNSRES::SFDNSRES(Core::System& system_) : ServiceFramework{system_, "sfdnsres" {4, nullptr, "GetHostStringErrorRequest"}, {5, &SFDNSRES::GetGaiStringErrorRequest, "GetGaiStringErrorRequest"}, {6, &SFDNSRES::GetAddrInfoRequest, "GetAddrInfoRequest"}, - {7, nullptr, "GetNameInfoRequest"}, + {7, &SFDNSRES::GetNameInfoRequest, "GetNameInfoRequest"}, {8, &SFDNSRES::RequestCancelHandleRequest, "RequestCancelHandleRequest"}, {9, nullptr, "CancelRequest"}, {10, &SFDNSRES::GetHostByNameRequestWithOptions, "GetHostByNameRequestWithOptions"}, @@ -382,6 +382,54 @@ void SFDNSRES::GetAddrInfoRequestWithOptions(HLERequestContext& ctx) { } +void SFDNSRES::GetNameInfoRequest(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto addr_in = rp.PopRaw(); + const u32 flags = rp.Pop(); + const u32 cancel_handle = rp.Pop(); + const u64 process_id = rp.Pop(); + + LOG_DEBUG(Service, "called. flags={}, cancel_handle={}, process_id={}", flags, cancel_handle, + process_id); + + struct OutputParameters { + u32 data_size; + GetAddrInfoError gai_error; + NetDbError netdb_error; + Errno bsd_errno; + }; + static_assert(sizeof(OutputParameters) == 0x10); + + const auto res = Network::GetNameInfo(Translate(addr_in)); + if (res.second != 0) { + const auto network_error = Network::TranslateGetAddrInfoErrorFromNative(res.second); + const auto service_error = Translate(network_error); + IPC::ResponseBuilder rb{ctx, 6}; + rb.Push(ResultSuccess); + rb.PushRaw(OutputParameters{ + .data_size = 0, + .gai_error = service_error, + .netdb_error = GetAddrInfoErrorToNetDbError(service_error), + .bsd_errno = GetAddrInfoErrorToErrno(service_error), + }); + return; + } + + const std::string& host = res.first; + const u32 data_size = static_cast(host.size() + 1); + + ctx.WriteBuffer(host.data(), data_size, 0); + + IPC::ResponseBuilder rb{ctx, 6}; + rb.Push(ResultSuccess); + rb.PushRaw(OutputParameters{ + .data_size = data_size, + .gai_error = GetAddrInfoError::SUCCESS, + .netdb_error = NetDbError::Success, + .bsd_errno = Errno::SUCCESS, + }); +} + void SFDNSRES::GetNameInfoRequestWithOptions(HLERequestContext& ctx) { struct InputParameters { u32 flags; diff --git a/src/core/hle/service/sockets/sfdnsres.h b/src/core/hle/service/sockets/sfdnsres.h index d853037853..c0c258ddd9 100644 --- a/src/core/hle/service/sockets/sfdnsres.h +++ b/src/core/hle/service/sockets/sfdnsres.h @@ -22,6 +22,7 @@ private: void GetHostByNameRequestWithOptions(HLERequestContext& ctx); void GetAddrInfoRequest(HLERequestContext& ctx); void GetAddrInfoRequestWithOptions(HLERequestContext& ctx); + void GetNameInfoRequest(HLERequestContext& ctx); void GetNameInfoRequestWithOptions(HLERequestContext& ctx); void ResolverSetOptionRequest(HLERequestContext& ctx); void RequestCancelHandleRequest(HLERequestContext& ctx); diff --git a/src/core/hle/service/sockets/sockets.h b/src/core/hle/service/sockets/sockets.h index f3ea31bde5..7bb0e82e51 100644 --- a/src/core/hle/service/sockets/sockets.h +++ b/src/core/hle/service/sockets/sockets.h @@ -16,10 +16,12 @@ enum class Errno : u32 { SUCCESS = 0, BADF = 9, AGAIN = 11, + ACCES = 13, INVAL = 22, MFILE = 24, PIPE = 32, MSGSIZE = 90, + ADDRINUSE = 98, CONNABORTED = 103, CONNRESET = 104, NOTCONN = 107, diff --git a/src/core/hle/service/sockets/sockets_translate.cpp b/src/core/hle/service/sockets/sockets_translate.cpp index 21bb3e7764..a6545fa4bb 100644 --- a/src/core/hle/service/sockets/sockets_translate.cpp +++ b/src/core/hle/service/sockets/sockets_translate.cpp @@ -37,6 +37,10 @@ Errno Translate(Network::Errno value) { return Errno::CONNRESET; case Network::Errno::INPROGRESS: return Errno::INPROGRESS; + case Network::Errno::ACCES: + return Errno::ACCES; + case Network::Errno::ADDRINUSE: + return Errno::ADDRINUSE; default: UNIMPLEMENTED_MSG("Unimplemented errno={}", value); return Errno::SUCCESS; @@ -261,7 +265,9 @@ PollEvents Translate(Network::PollEvents flags) { Network::SockAddrIn Translate(SockAddrIn value) { // Note: 6 is incorrect, but can be passed by homebrew (because libnx sets // sin_len to 6 when deserializing getaddrinfo results). - ASSERT(value.len == 0 || value.len == sizeof(value) || value.len == 6); + if (value.len != 0 && value.len != sizeof(value) && value.len != 6) { + LOG_WARNING(Service, "Unexpected SockAddrIn length={}", value.len); + } return { .family = Translate(static_cast(value.family)), diff --git a/src/core/internal_network/network.cpp b/src/core/internal_network/network.cpp index f6aa336d4a..343af3280b 100644 --- a/src/core/internal_network/network.cpp +++ b/src/core/internal_network/network.cpp @@ -85,6 +85,7 @@ sockaddr TranslateFromSockAddrIn(SockAddrIn input) { #endif switch (static_cast(input.family)) { + case Domain::Unspecified: case Domain::INET: result.sin_family = AF_INET; break; @@ -128,6 +129,7 @@ Errno TranslateNativeError(int e, CallType call_type = CallType::Other) { case 0: return Errno::SUCCESS; case WSAEBADF: + case WSAENOTSOCK: return Errno::BADF; case WSAEINVAL: return Errno::INVAL; @@ -161,6 +163,10 @@ Errno TranslateNativeError(int e, CallType call_type = CallType::Other) { return Errno::TIMEDOUT; case WSAEINPROGRESS: return Errno::INPROGRESS; + case WSAEACCES: + return Errno::ACCES; + case WSAEADDRINUSE: + return Errno::ADDRINUSE; default: UNIMPLEMENTED_MSG("Unimplemented errno={}", e); return Errno::OTHER; @@ -886,7 +892,9 @@ std::pair Socket::SendTo(u32 flags, std::span message, Errno Socket::Close() { [[maybe_unused]] const int result = closesocket(fd); - ASSERT(result == 0); + if (result != 0) { + GetAndLogLastError(); + } fd = INVALID_SOCKET; return Errno::SUCCESS; diff --git a/src/core/internal_network/network.h b/src/core/internal_network/network.h index 2dc612de71..58951ebc29 100644 --- a/src/core/internal_network/network.h +++ b/src/core/internal_network/network.h @@ -48,6 +48,8 @@ enum class Errno { TIMEDOUT, MSGSIZE, INPROGRESS, + ACCES, + ADDRINUSE, OTHER, }; diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp index ffe5cd116c..7e48328405 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp @@ -446,10 +446,12 @@ void EmitIsHelperInvocation(EmitContext& ctx, IR::Inst& inst) { void EmitSR_WScaleFactorXY(EmitContext& ctx, IR::Inst& inst) { LOG_WARNING(Shader, "(STUBBED) called"); + ctx.AddU32("{}=0x3c003c00u;", inst); } void EmitSR_WScaleFactorZ(EmitContext& ctx, IR::Inst& inst) { LOG_WARNING(Shader, "(STUBBED) called"); + ctx.AddU32("{}=0x3f800000u;", inst); } void EmitYDirection(EmitContext& ctx, IR::Inst& inst) { diff --git a/src/shader_recompiler/backend/glsl/var_alloc.cpp b/src/shader_recompiler/backend/glsl/var_alloc.cpp index 3bb84ad32a..ae9e0ef5e2 100644 --- a/src/shader_recompiler/backend/glsl/var_alloc.cpp +++ b/src/shader_recompiler/backend/glsl/var_alloc.cpp @@ -58,6 +58,9 @@ std::string FormatFloat(std::string_view value, IR::Type type) { if (value == "nan") { return "utof(0x7fc00000)"; } + if (value == "-nan") { + return "utof(0xffc00000)"; + } if (value == "inf") { return "utof(0x7f800000)"; } diff --git a/src/video_core/renderer_opengl/gl_shader_util.cpp b/src/video_core/renderer_opengl/gl_shader_util.cpp index a0d9d10ef0..2a3054ef7f 100644 --- a/src/video_core/renderer_opengl/gl_shader_util.cpp +++ b/src/video_core/renderer_opengl/gl_shader_util.cpp @@ -33,6 +33,8 @@ static OGLProgram LinkSeparableProgram(GLuint shader) { glGetProgramInfoLog(program.handle, log_length, nullptr, log.data()); if (link_status == GL_FALSE) { LOG_ERROR(Render_OpenGL, "{}", log); + glDeleteProgram(program.handle); + program.handle = 0; } else { LOG_WARNING(Render_OpenGL, "{}", log); } diff --git a/src/video_core/renderer_opengl/present/window_adapt_pass.cpp b/src/video_core/renderer_opengl/present/window_adapt_pass.cpp index 37fb766139..dced67514a 100644 --- a/src/video_core/renderer_opengl/present/window_adapt_pass.cpp +++ b/src/video_core/renderer_opengl/present/window_adapt_pass.cpp @@ -116,9 +116,14 @@ void WindowAdaptPass::DrawToFramebuffer(ProgramManager& program_manager, std::li glBindTextureUnit(0, textures[i]); glProgramUniformMatrix3x2fv(vert.handle, ModelViewMatrixLocation, 1, GL_FALSE, matrices[i].data()); - glProgramUniform2ui(frag.handle, ScreenSizeLocation, - static_cast(layout.screen.GetWidth()), - static_cast(layout.screen.GetHeight())); + if (frag.handle != 0) { + const GLint screen_size_loc = glGetUniformLocation(frag.handle, "screen_size"); + if (screen_size_loc != -1) { + glProgramUniform2ui(frag.handle, screen_size_loc, + static_cast(layout.screen.GetWidth()), + static_cast(layout.screen.GetHeight())); + } + } glNamedBufferSubData(vertex_buffer.handle, 0, sizeof(vertices[i]), std::data(vertices[i])); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } diff --git a/src/video_core/shader_environment.cpp b/src/video_core/shader_environment.cpp index de12d795c8..dc6e7c5684 100644 --- a/src/video_core/shader_environment.cpp +++ b/src/video_core/shader_environment.cpp @@ -277,7 +277,10 @@ std::optional GenericEnvironment::TryFindSize() { Tegra::Texture::TICEntry GenericEnvironment::ReadTextureInfo(GPUVAddr tic_addr, u32 tic_limit, bool via_header_index, u32 raw) { const auto handle{Tegra::Texture::TexturePair(raw, via_header_index)}; - ASSERT(handle.first <= tic_limit); + if (handle.first > tic_limit) { + LOG_WARNING(Shader, "Texture ID {} is out of bounds (limit {})", handle.first, tic_limit); + return {}; + } const GPUVAddr descriptor_addr{tic_addr + handle.first * sizeof(Tegra::Texture::TICEntry)}; Tegra::Texture::TICEntry entry; gpu_memory->ReadBlock(descriptor_addr, &entry, sizeof(entry));