feat: Introduce new shader environment, OpenGL renderer components, and HLE socket/DNS services with internal network support.
This commit is contained in:
@@ -29,7 +29,7 @@ SFDNSRES::SFDNSRES(Core::System& system_) : ServiceFramework{system_, "sfdnsres"
|
|||||||
{4, nullptr, "GetHostStringErrorRequest"},
|
{4, nullptr, "GetHostStringErrorRequest"},
|
||||||
{5, &SFDNSRES::GetGaiStringErrorRequest, "GetGaiStringErrorRequest"},
|
{5, &SFDNSRES::GetGaiStringErrorRequest, "GetGaiStringErrorRequest"},
|
||||||
{6, &SFDNSRES::GetAddrInfoRequest, "GetAddrInfoRequest"},
|
{6, &SFDNSRES::GetAddrInfoRequest, "GetAddrInfoRequest"},
|
||||||
{7, nullptr, "GetNameInfoRequest"},
|
{7, &SFDNSRES::GetNameInfoRequest, "GetNameInfoRequest"},
|
||||||
{8, &SFDNSRES::RequestCancelHandleRequest, "RequestCancelHandleRequest"},
|
{8, &SFDNSRES::RequestCancelHandleRequest, "RequestCancelHandleRequest"},
|
||||||
{9, nullptr, "CancelRequest"},
|
{9, nullptr, "CancelRequest"},
|
||||||
{10, &SFDNSRES::GetHostByNameRequestWithOptions, "GetHostByNameRequestWithOptions"},
|
{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<SockAddrIn>();
|
||||||
|
const u32 flags = rp.Pop<u32>();
|
||||||
|
const u32 cancel_handle = rp.Pop<u32>();
|
||||||
|
const u64 process_id = rp.Pop<u64>();
|
||||||
|
|
||||||
|
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<u32>(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) {
|
void SFDNSRES::GetNameInfoRequestWithOptions(HLERequestContext& ctx) {
|
||||||
struct InputParameters {
|
struct InputParameters {
|
||||||
u32 flags;
|
u32 flags;
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ private:
|
|||||||
void GetHostByNameRequestWithOptions(HLERequestContext& ctx);
|
void GetHostByNameRequestWithOptions(HLERequestContext& ctx);
|
||||||
void GetAddrInfoRequest(HLERequestContext& ctx);
|
void GetAddrInfoRequest(HLERequestContext& ctx);
|
||||||
void GetAddrInfoRequestWithOptions(HLERequestContext& ctx);
|
void GetAddrInfoRequestWithOptions(HLERequestContext& ctx);
|
||||||
|
void GetNameInfoRequest(HLERequestContext& ctx);
|
||||||
void GetNameInfoRequestWithOptions(HLERequestContext& ctx);
|
void GetNameInfoRequestWithOptions(HLERequestContext& ctx);
|
||||||
void ResolverSetOptionRequest(HLERequestContext& ctx);
|
void ResolverSetOptionRequest(HLERequestContext& ctx);
|
||||||
void RequestCancelHandleRequest(HLERequestContext& ctx);
|
void RequestCancelHandleRequest(HLERequestContext& ctx);
|
||||||
|
|||||||
@@ -16,10 +16,12 @@ enum class Errno : u32 {
|
|||||||
SUCCESS = 0,
|
SUCCESS = 0,
|
||||||
BADF = 9,
|
BADF = 9,
|
||||||
AGAIN = 11,
|
AGAIN = 11,
|
||||||
|
ACCES = 13,
|
||||||
INVAL = 22,
|
INVAL = 22,
|
||||||
MFILE = 24,
|
MFILE = 24,
|
||||||
PIPE = 32,
|
PIPE = 32,
|
||||||
MSGSIZE = 90,
|
MSGSIZE = 90,
|
||||||
|
ADDRINUSE = 98,
|
||||||
CONNABORTED = 103,
|
CONNABORTED = 103,
|
||||||
CONNRESET = 104,
|
CONNRESET = 104,
|
||||||
NOTCONN = 107,
|
NOTCONN = 107,
|
||||||
|
|||||||
@@ -37,6 +37,10 @@ Errno Translate(Network::Errno value) {
|
|||||||
return Errno::CONNRESET;
|
return Errno::CONNRESET;
|
||||||
case Network::Errno::INPROGRESS:
|
case Network::Errno::INPROGRESS:
|
||||||
return Errno::INPROGRESS;
|
return Errno::INPROGRESS;
|
||||||
|
case Network::Errno::ACCES:
|
||||||
|
return Errno::ACCES;
|
||||||
|
case Network::Errno::ADDRINUSE:
|
||||||
|
return Errno::ADDRINUSE;
|
||||||
default:
|
default:
|
||||||
UNIMPLEMENTED_MSG("Unimplemented errno={}", value);
|
UNIMPLEMENTED_MSG("Unimplemented errno={}", value);
|
||||||
return Errno::SUCCESS;
|
return Errno::SUCCESS;
|
||||||
@@ -261,7 +265,9 @@ PollEvents Translate(Network::PollEvents flags) {
|
|||||||
Network::SockAddrIn Translate(SockAddrIn value) {
|
Network::SockAddrIn Translate(SockAddrIn value) {
|
||||||
// Note: 6 is incorrect, but can be passed by homebrew (because libnx sets
|
// Note: 6 is incorrect, but can be passed by homebrew (because libnx sets
|
||||||
// sin_len to 6 when deserializing getaddrinfo results).
|
// 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 {
|
return {
|
||||||
.family = Translate(static_cast<Domain>(value.family)),
|
.family = Translate(static_cast<Domain>(value.family)),
|
||||||
|
|||||||
@@ -85,6 +85,7 @@ sockaddr TranslateFromSockAddrIn(SockAddrIn input) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch (static_cast<Domain>(input.family)) {
|
switch (static_cast<Domain>(input.family)) {
|
||||||
|
case Domain::Unspecified:
|
||||||
case Domain::INET:
|
case Domain::INET:
|
||||||
result.sin_family = AF_INET;
|
result.sin_family = AF_INET;
|
||||||
break;
|
break;
|
||||||
@@ -128,6 +129,7 @@ Errno TranslateNativeError(int e, CallType call_type = CallType::Other) {
|
|||||||
case 0:
|
case 0:
|
||||||
return Errno::SUCCESS;
|
return Errno::SUCCESS;
|
||||||
case WSAEBADF:
|
case WSAEBADF:
|
||||||
|
case WSAENOTSOCK:
|
||||||
return Errno::BADF;
|
return Errno::BADF;
|
||||||
case WSAEINVAL:
|
case WSAEINVAL:
|
||||||
return Errno::INVAL;
|
return Errno::INVAL;
|
||||||
@@ -161,6 +163,10 @@ Errno TranslateNativeError(int e, CallType call_type = CallType::Other) {
|
|||||||
return Errno::TIMEDOUT;
|
return Errno::TIMEDOUT;
|
||||||
case WSAEINPROGRESS:
|
case WSAEINPROGRESS:
|
||||||
return Errno::INPROGRESS;
|
return Errno::INPROGRESS;
|
||||||
|
case WSAEACCES:
|
||||||
|
return Errno::ACCES;
|
||||||
|
case WSAEADDRINUSE:
|
||||||
|
return Errno::ADDRINUSE;
|
||||||
default:
|
default:
|
||||||
UNIMPLEMENTED_MSG("Unimplemented errno={}", e);
|
UNIMPLEMENTED_MSG("Unimplemented errno={}", e);
|
||||||
return Errno::OTHER;
|
return Errno::OTHER;
|
||||||
@@ -886,7 +892,9 @@ std::pair<s32, Errno> Socket::SendTo(u32 flags, std::span<const u8> message,
|
|||||||
|
|
||||||
Errno Socket::Close() {
|
Errno Socket::Close() {
|
||||||
[[maybe_unused]] const int result = closesocket(fd);
|
[[maybe_unused]] const int result = closesocket(fd);
|
||||||
ASSERT(result == 0);
|
if (result != 0) {
|
||||||
|
GetAndLogLastError();
|
||||||
|
}
|
||||||
fd = INVALID_SOCKET;
|
fd = INVALID_SOCKET;
|
||||||
|
|
||||||
return Errno::SUCCESS;
|
return Errno::SUCCESS;
|
||||||
|
|||||||
@@ -48,6 +48,8 @@ enum class Errno {
|
|||||||
TIMEDOUT,
|
TIMEDOUT,
|
||||||
MSGSIZE,
|
MSGSIZE,
|
||||||
INPROGRESS,
|
INPROGRESS,
|
||||||
|
ACCES,
|
||||||
|
ADDRINUSE,
|
||||||
OTHER,
|
OTHER,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -446,10 +446,12 @@ void EmitIsHelperInvocation(EmitContext& ctx, IR::Inst& inst) {
|
|||||||
|
|
||||||
void EmitSR_WScaleFactorXY(EmitContext& ctx, IR::Inst& inst) {
|
void EmitSR_WScaleFactorXY(EmitContext& ctx, IR::Inst& inst) {
|
||||||
LOG_WARNING(Shader, "(STUBBED) called");
|
LOG_WARNING(Shader, "(STUBBED) called");
|
||||||
|
ctx.AddU32("{}=0x3c003c00u;", inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitSR_WScaleFactorZ(EmitContext& ctx, IR::Inst& inst) {
|
void EmitSR_WScaleFactorZ(EmitContext& ctx, IR::Inst& inst) {
|
||||||
LOG_WARNING(Shader, "(STUBBED) called");
|
LOG_WARNING(Shader, "(STUBBED) called");
|
||||||
|
ctx.AddU32("{}=0x3f800000u;", inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitYDirection(EmitContext& ctx, IR::Inst& inst) {
|
void EmitYDirection(EmitContext& ctx, IR::Inst& inst) {
|
||||||
|
|||||||
@@ -58,6 +58,9 @@ std::string FormatFloat(std::string_view value, IR::Type type) {
|
|||||||
if (value == "nan") {
|
if (value == "nan") {
|
||||||
return "utof(0x7fc00000)";
|
return "utof(0x7fc00000)";
|
||||||
}
|
}
|
||||||
|
if (value == "-nan") {
|
||||||
|
return "utof(0xffc00000)";
|
||||||
|
}
|
||||||
if (value == "inf") {
|
if (value == "inf") {
|
||||||
return "utof(0x7f800000)";
|
return "utof(0x7f800000)";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ static OGLProgram LinkSeparableProgram(GLuint shader) {
|
|||||||
glGetProgramInfoLog(program.handle, log_length, nullptr, log.data());
|
glGetProgramInfoLog(program.handle, log_length, nullptr, log.data());
|
||||||
if (link_status == GL_FALSE) {
|
if (link_status == GL_FALSE) {
|
||||||
LOG_ERROR(Render_OpenGL, "{}", log);
|
LOG_ERROR(Render_OpenGL, "{}", log);
|
||||||
|
glDeleteProgram(program.handle);
|
||||||
|
program.handle = 0;
|
||||||
} else {
|
} else {
|
||||||
LOG_WARNING(Render_OpenGL, "{}", log);
|
LOG_WARNING(Render_OpenGL, "{}", log);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,9 +116,14 @@ void WindowAdaptPass::DrawToFramebuffer(ProgramManager& program_manager, std::li
|
|||||||
glBindTextureUnit(0, textures[i]);
|
glBindTextureUnit(0, textures[i]);
|
||||||
glProgramUniformMatrix3x2fv(vert.handle, ModelViewMatrixLocation, 1, GL_FALSE,
|
glProgramUniformMatrix3x2fv(vert.handle, ModelViewMatrixLocation, 1, GL_FALSE,
|
||||||
matrices[i].data());
|
matrices[i].data());
|
||||||
glProgramUniform2ui(frag.handle, ScreenSizeLocation,
|
if (frag.handle != 0) {
|
||||||
static_cast<GLuint>(layout.screen.GetWidth()),
|
const GLint screen_size_loc = glGetUniformLocation(frag.handle, "screen_size");
|
||||||
static_cast<GLuint>(layout.screen.GetHeight()));
|
if (screen_size_loc != -1) {
|
||||||
|
glProgramUniform2ui(frag.handle, screen_size_loc,
|
||||||
|
static_cast<GLuint>(layout.screen.GetWidth()),
|
||||||
|
static_cast<GLuint>(layout.screen.GetHeight()));
|
||||||
|
}
|
||||||
|
}
|
||||||
glNamedBufferSubData(vertex_buffer.handle, 0, sizeof(vertices[i]), std::data(vertices[i]));
|
glNamedBufferSubData(vertex_buffer.handle, 0, sizeof(vertices[i]), std::data(vertices[i]));
|
||||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -277,7 +277,10 @@ std::optional<u64> GenericEnvironment::TryFindSize() {
|
|||||||
Tegra::Texture::TICEntry GenericEnvironment::ReadTextureInfo(GPUVAddr tic_addr, u32 tic_limit,
|
Tegra::Texture::TICEntry GenericEnvironment::ReadTextureInfo(GPUVAddr tic_addr, u32 tic_limit,
|
||||||
bool via_header_index, u32 raw) {
|
bool via_header_index, u32 raw) {
|
||||||
const auto handle{Tegra::Texture::TexturePair(raw, via_header_index)};
|
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)};
|
const GPUVAddr descriptor_addr{tic_addr + handle.first * sizeof(Tegra::Texture::TICEntry)};
|
||||||
Tegra::Texture::TICEntry entry;
|
Tegra::Texture::TICEntry entry;
|
||||||
gpu_memory->ReadBlock(descriptor_addr, &entry, sizeof(entry));
|
gpu_memory->ReadBlock(descriptor_addr, &entry, sizeof(entry));
|
||||||
|
|||||||
Reference in New Issue
Block a user