diff options
Diffstat (limited to 'src')
44 files changed, 2220 insertions, 1441 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index c42f95705..c85c9485f 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -586,6 +586,9 @@ add_library(core STATIC | |||
| 586 | memory/dmnt_cheat_vm.h | 586 | memory/dmnt_cheat_vm.h |
| 587 | memory.cpp | 587 | memory.cpp |
| 588 | memory.h | 588 | memory.h |
| 589 | network/network.cpp | ||
| 590 | network/network.h | ||
| 591 | network/sockets.h | ||
| 589 | perf_stats.cpp | 592 | perf_stats.cpp |
| 590 | perf_stats.h | 593 | perf_stats.h |
| 591 | reporter.cpp | 594 | reporter.cpp |
diff --git a/src/core/core.cpp b/src/core/core.cpp index 69a1aa0a5..e598c0e2b 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp | |||
| @@ -43,6 +43,7 @@ | |||
| 43 | #include "core/loader/loader.h" | 43 | #include "core/loader/loader.h" |
| 44 | #include "core/memory.h" | 44 | #include "core/memory.h" |
| 45 | #include "core/memory/cheat_engine.h" | 45 | #include "core/memory/cheat_engine.h" |
| 46 | #include "core/network/network.h" | ||
| 46 | #include "core/perf_stats.h" | 47 | #include "core/perf_stats.h" |
| 47 | #include "core/reporter.h" | 48 | #include "core/reporter.h" |
| 48 | #include "core/settings.h" | 49 | #include "core/settings.h" |
| @@ -394,6 +395,9 @@ struct System::Impl { | |||
| 394 | /// Telemetry session for this emulation session | 395 | /// Telemetry session for this emulation session |
| 395 | std::unique_ptr<Core::TelemetrySession> telemetry_session; | 396 | std::unique_ptr<Core::TelemetrySession> telemetry_session; |
| 396 | 397 | ||
| 398 | /// Network instance | ||
| 399 | Network::NetworkInstance network_instance; | ||
| 400 | |||
| 397 | ResultStatus status = ResultStatus::Success; | 401 | ResultStatus status = ResultStatus::Success; |
| 398 | std::string status_details = ""; | 402 | std::string status_details = ""; |
| 399 | 403 | ||
diff --git a/src/core/network/network.cpp b/src/core/network/network.cpp new file mode 100644 index 000000000..56d173b5e --- /dev/null +++ b/src/core/network/network.cpp | |||
| @@ -0,0 +1,654 @@ | |||
| 1 | // Copyright 2020 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <algorithm> | ||
| 6 | #include <cstring> | ||
| 7 | #include <limits> | ||
| 8 | #include <utility> | ||
| 9 | #include <vector> | ||
| 10 | |||
| 11 | #ifdef _WIN32 | ||
| 12 | #define _WINSOCK_DEPRECATED_NO_WARNINGS // gethostname | ||
| 13 | #include <winsock2.h> | ||
| 14 | #elif __unix__ | ||
| 15 | #include <errno.h> | ||
| 16 | #include <fcntl.h> | ||
| 17 | #include <netdb.h> | ||
| 18 | #include <netinet/in.h> | ||
| 19 | #include <poll.h> | ||
| 20 | #include <sys/socket.h> | ||
| 21 | #include <unistd.h> | ||
| 22 | #else | ||
| 23 | #error "Unimplemented platform" | ||
| 24 | #endif | ||
| 25 | |||
| 26 | #include "common/assert.h" | ||
| 27 | #include "common/common_types.h" | ||
| 28 | #include "common/logging/log.h" | ||
| 29 | #include "core/network/network.h" | ||
| 30 | #include "core/network/sockets.h" | ||
| 31 | |||
| 32 | namespace Network { | ||
| 33 | |||
| 34 | namespace { | ||
| 35 | |||
| 36 | #ifdef _WIN32 | ||
| 37 | |||
| 38 | using socklen_t = int; | ||
| 39 | |||
| 40 | void Initialize() { | ||
| 41 | WSADATA wsa_data; | ||
| 42 | (void)WSAStartup(MAKEWORD(2, 2), &wsa_data); | ||
| 43 | } | ||
| 44 | |||
| 45 | void Finalize() { | ||
| 46 | WSACleanup(); | ||
| 47 | } | ||
| 48 | |||
| 49 | constexpr IPv4Address TranslateIPv4(in_addr addr) { | ||
| 50 | auto& bytes = addr.S_un.S_un_b; | ||
| 51 | return IPv4Address{bytes.s_b1, bytes.s_b2, bytes.s_b3, bytes.s_b4}; | ||
| 52 | } | ||
| 53 | |||
| 54 | sockaddr TranslateFromSockAddrIn(SockAddrIn input) { | ||
| 55 | sockaddr_in result; | ||
| 56 | |||
| 57 | #ifdef __unix__ | ||
| 58 | result.sin_len = sizeof(result); | ||
| 59 | #endif | ||
| 60 | |||
| 61 | switch (static_cast<Domain>(input.family)) { | ||
| 62 | case Domain::INET: | ||
| 63 | result.sin_family = AF_INET; | ||
| 64 | break; | ||
| 65 | default: | ||
| 66 | UNIMPLEMENTED_MSG("Unhandled sockaddr family={}", static_cast<int>(input.family)); | ||
| 67 | result.sin_family = AF_INET; | ||
| 68 | break; | ||
| 69 | } | ||
| 70 | |||
| 71 | result.sin_port = htons(input.portno); | ||
| 72 | |||
| 73 | auto& ip = result.sin_addr.S_un.S_un_b; | ||
| 74 | ip.s_b1 = input.ip[0]; | ||
| 75 | ip.s_b2 = input.ip[1]; | ||
| 76 | ip.s_b3 = input.ip[2]; | ||
| 77 | ip.s_b4 = input.ip[3]; | ||
| 78 | |||
| 79 | sockaddr addr; | ||
| 80 | std::memcpy(&addr, &result, sizeof(addr)); | ||
| 81 | return addr; | ||
| 82 | } | ||
| 83 | |||
| 84 | LINGER MakeLinger(bool enable, u32 linger_value) { | ||
| 85 | ASSERT(linger_value <= std::numeric_limits<u_short>::max()); | ||
| 86 | |||
| 87 | LINGER value; | ||
| 88 | value.l_onoff = enable ? 1 : 0; | ||
| 89 | value.l_linger = static_cast<u_short>(linger_value); | ||
| 90 | return value; | ||
| 91 | } | ||
| 92 | |||
| 93 | int LastError() { | ||
| 94 | return WSAGetLastError(); | ||
| 95 | } | ||
| 96 | |||
| 97 | bool EnableNonBlock(SOCKET fd, bool enable) { | ||
| 98 | u_long value = enable ? 1 : 0; | ||
| 99 | return ioctlsocket(fd, FIONBIO, &value) != SOCKET_ERROR; | ||
| 100 | } | ||
| 101 | |||
| 102 | #elif __unix__ // ^ _WIN32 v __unix__ | ||
| 103 | |||
| 104 | using SOCKET = int; | ||
| 105 | using WSAPOLLFD = pollfd; | ||
| 106 | using ULONG = u64; | ||
| 107 | |||
| 108 | constexpr SOCKET INVALID_SOCKET = -1; | ||
| 109 | constexpr SOCKET SOCKET_ERROR = -1; | ||
| 110 | |||
| 111 | constexpr int WSAEWOULDBLOCK = EAGAIN; | ||
| 112 | constexpr int WSAENOTCONN = ENOTCONN; | ||
| 113 | |||
| 114 | constexpr int SD_RECEIVE = SHUT_RD; | ||
| 115 | constexpr int SD_SEND = SHUT_WR; | ||
| 116 | constexpr int SD_BOTH = SHUT_RDWR; | ||
| 117 | |||
| 118 | void Initialize() {} | ||
| 119 | |||
| 120 | void Finalize() {} | ||
| 121 | |||
| 122 | constexpr IPv4Address TranslateIPv4(in_addr addr) { | ||
| 123 | const u32 bytes = addr.s_addr; | ||
| 124 | return IPv4Address{static_cast<u8>(bytes), static_cast<u8>(bytes >> 8), | ||
| 125 | static_cast<u8>(bytes >> 16), static_cast<u8>(bytes >> 24)}; | ||
| 126 | } | ||
| 127 | |||
| 128 | sockaddr TranslateFromSockAddrIn(SockAddrIn input) { | ||
| 129 | sockaddr_in result; | ||
| 130 | |||
| 131 | switch (static_cast<Domain>(input.family)) { | ||
| 132 | case Domain::INET: | ||
| 133 | result.sin_family = AF_INET; | ||
| 134 | break; | ||
| 135 | default: | ||
| 136 | UNIMPLEMENTED_MSG("Unhandled sockaddr family={}", static_cast<int>(input.family)); | ||
| 137 | result.sin_family = AF_INET; | ||
| 138 | break; | ||
| 139 | } | ||
| 140 | |||
| 141 | result.sin_port = htons(input.portno); | ||
| 142 | |||
| 143 | result.sin_addr.s_addr = input.ip[0] | input.ip[1] << 8 | input.ip[2] << 16 | input.ip[3] << 24; | ||
| 144 | |||
| 145 | sockaddr addr; | ||
| 146 | std::memcpy(&addr, &result, sizeof(addr)); | ||
| 147 | return addr; | ||
| 148 | } | ||
| 149 | |||
| 150 | int WSAPoll(WSAPOLLFD* fds, ULONG nfds, int timeout) { | ||
| 151 | return poll(fds, nfds, timeout); | ||
| 152 | } | ||
| 153 | |||
| 154 | int closesocket(SOCKET fd) { | ||
| 155 | return close(fd); | ||
| 156 | } | ||
| 157 | |||
| 158 | linger MakeLinger(bool enable, u32 linger_value) { | ||
| 159 | linger value; | ||
| 160 | value.l_onoff = enable ? 1 : 0; | ||
| 161 | value.l_linger = linger_value; | ||
| 162 | return value; | ||
| 163 | } | ||
| 164 | |||
| 165 | int LastError() { | ||
| 166 | return errno; | ||
| 167 | } | ||
| 168 | |||
| 169 | bool EnableNonBlock(int fd, bool enable) { | ||
| 170 | int flags = fcntl(fd, F_GETFD); | ||
| 171 | if (flags == -1) { | ||
| 172 | return false; | ||
| 173 | } | ||
| 174 | if (enable) { | ||
| 175 | flags |= O_NONBLOCK; | ||
| 176 | } else { | ||
| 177 | flags &= ~O_NONBLOCK; | ||
| 178 | } | ||
| 179 | return fcntl(fd, F_SETFD, flags) == 0; | ||
| 180 | } | ||
| 181 | |||
| 182 | #endif | ||
| 183 | |||
| 184 | int TranslateDomain(Domain domain) { | ||
| 185 | switch (domain) { | ||
| 186 | case Domain::INET: | ||
| 187 | return AF_INET; | ||
| 188 | default: | ||
| 189 | UNIMPLEMENTED_MSG("Unimplemented domain={}", static_cast<int>(domain)); | ||
| 190 | return 0; | ||
| 191 | } | ||
| 192 | } | ||
| 193 | |||
| 194 | int TranslateType(Type type) { | ||
| 195 | switch (type) { | ||
| 196 | case Type::STREAM: | ||
| 197 | return SOCK_STREAM; | ||
| 198 | case Type::DGRAM: | ||
| 199 | return SOCK_DGRAM; | ||
| 200 | default: | ||
| 201 | UNIMPLEMENTED_MSG("Unimplemented type={}", static_cast<int>(type)); | ||
| 202 | return 0; | ||
| 203 | } | ||
| 204 | } | ||
| 205 | |||
| 206 | int TranslateProtocol(Protocol protocol) { | ||
| 207 | switch (protocol) { | ||
| 208 | case Protocol::TCP: | ||
| 209 | return IPPROTO_TCP; | ||
| 210 | case Protocol::UDP: | ||
| 211 | return IPPROTO_UDP; | ||
| 212 | default: | ||
| 213 | UNIMPLEMENTED_MSG("Unimplemented protocol={}", static_cast<int>(protocol)); | ||
| 214 | return 0; | ||
| 215 | } | ||
| 216 | } | ||
| 217 | |||
| 218 | SockAddrIn TranslateToSockAddrIn(sockaddr input_) { | ||
| 219 | sockaddr_in input; | ||
| 220 | std::memcpy(&input, &input_, sizeof(input)); | ||
| 221 | |||
| 222 | SockAddrIn result; | ||
| 223 | |||
| 224 | switch (input.sin_family) { | ||
| 225 | case AF_INET: | ||
| 226 | result.family = Domain::INET; | ||
| 227 | break; | ||
| 228 | default: | ||
| 229 | UNIMPLEMENTED_MSG("Unhandled sockaddr family={}", input.sin_family); | ||
| 230 | result.family = Domain::INET; | ||
| 231 | break; | ||
| 232 | } | ||
| 233 | |||
| 234 | result.portno = ntohs(input.sin_port); | ||
| 235 | |||
| 236 | result.ip = TranslateIPv4(input.sin_addr); | ||
| 237 | |||
| 238 | return result; | ||
| 239 | } | ||
| 240 | |||
| 241 | u16 TranslatePollEvents(u16 events) { | ||
| 242 | u16 result = 0; | ||
| 243 | |||
| 244 | if (events & POLL_IN) { | ||
| 245 | events &= ~POLL_IN; | ||
| 246 | result |= POLLIN; | ||
| 247 | } | ||
| 248 | if (events & POLL_PRI) { | ||
| 249 | events &= ~POLL_PRI; | ||
| 250 | #ifdef _WIN32 | ||
| 251 | LOG_WARNING(Service, "Winsock doesn't support POLLPRI"); | ||
| 252 | #else | ||
| 253 | result |= POLL_PRI; | ||
| 254 | #endif | ||
| 255 | } | ||
| 256 | if (events & POLL_OUT) { | ||
| 257 | events &= ~POLL_OUT; | ||
| 258 | result |= POLLOUT; | ||
| 259 | } | ||
| 260 | |||
| 261 | UNIMPLEMENTED_IF_MSG(events != 0, "Unhandled guest events=0x{:x}", events); | ||
| 262 | |||
| 263 | return result; | ||
| 264 | } | ||
| 265 | |||
| 266 | u16 TranslatePollRevents(u16 revents) { | ||
| 267 | u16 result = 0; | ||
| 268 | const auto translate = [&result, &revents](int host, unsigned guest) { | ||
| 269 | if (revents & host) { | ||
| 270 | revents &= ~host; | ||
| 271 | result |= guest; | ||
| 272 | } | ||
| 273 | }; | ||
| 274 | |||
| 275 | translate(POLLIN, POLL_IN); | ||
| 276 | translate(POLLPRI, POLL_PRI); | ||
| 277 | translate(POLLOUT, POLL_OUT); | ||
| 278 | translate(POLLERR, POLL_ERR); | ||
| 279 | translate(POLLHUP, POLL_HUP); | ||
| 280 | |||
| 281 | UNIMPLEMENTED_IF_MSG(revents != 0, "Unhandled host revents=0x{:x}", revents); | ||
| 282 | |||
| 283 | return result; | ||
| 284 | } | ||
| 285 | |||
| 286 | template <typename T> | ||
| 287 | Errno SetSockOpt(SOCKET fd, int option, T value) { | ||
| 288 | const int result = | ||
| 289 | setsockopt(fd, SOL_SOCKET, option, reinterpret_cast<const char*>(&value), sizeof(value)); | ||
| 290 | if (result != SOCKET_ERROR) { | ||
| 291 | return Errno::SUCCESS; | ||
| 292 | } | ||
| 293 | const int ec = LastError(); | ||
| 294 | UNREACHABLE_MSG("Unhandled host socket error={}", ec); | ||
| 295 | return Errno::SUCCESS; | ||
| 296 | } | ||
| 297 | |||
| 298 | } // Anonymous namespace | ||
| 299 | |||
| 300 | NetworkInstance::NetworkInstance() { | ||
| 301 | Initialize(); | ||
| 302 | } | ||
| 303 | |||
| 304 | NetworkInstance::~NetworkInstance() { | ||
| 305 | Finalize(); | ||
| 306 | } | ||
| 307 | |||
| 308 | std::pair<IPv4Address, Errno> GetHostIPv4Address() { | ||
| 309 | std::array<char, 256> name{}; | ||
| 310 | if (gethostname(name.data(), static_cast<int>(name.size()) - 1) == SOCKET_ERROR) { | ||
| 311 | UNIMPLEMENTED_MSG("Unhandled gethostname error"); | ||
| 312 | return {IPv4Address{}, Errno::SUCCESS}; | ||
| 313 | } | ||
| 314 | |||
| 315 | hostent* const ent = gethostbyname(name.data()); | ||
| 316 | if (!ent) { | ||
| 317 | UNIMPLEMENTED_MSG("Unhandled gethostbyname error"); | ||
| 318 | return {IPv4Address{}, Errno::SUCCESS}; | ||
| 319 | } | ||
| 320 | if (ent->h_addr_list == nullptr) { | ||
| 321 | UNIMPLEMENTED_MSG("No addr provided in hostent->h_addr_list"); | ||
| 322 | return {IPv4Address{}, Errno::SUCCESS}; | ||
| 323 | } | ||
| 324 | if (ent->h_length != sizeof(in_addr)) { | ||
| 325 | UNIMPLEMENTED_MSG("Unexpected size={} in hostent->h_length", ent->h_length); | ||
| 326 | } | ||
| 327 | |||
| 328 | in_addr addr; | ||
| 329 | std::memcpy(&addr, ent->h_addr_list[0], sizeof(addr)); | ||
| 330 | return {TranslateIPv4(addr), Errno::SUCCESS}; | ||
| 331 | } | ||
| 332 | |||
| 333 | std::pair<s32, Errno> Poll(std::vector<PollFD>& pollfds, s32 timeout) { | ||
| 334 | const size_t num = pollfds.size(); | ||
| 335 | |||
| 336 | std::vector<WSAPOLLFD> host_pollfds(pollfds.size()); | ||
| 337 | std::transform(pollfds.begin(), pollfds.end(), host_pollfds.begin(), [](PollFD fd) { | ||
| 338 | WSAPOLLFD result; | ||
| 339 | result.fd = fd.socket->fd; | ||
| 340 | result.events = TranslatePollEvents(fd.events); | ||
| 341 | result.revents = 0; | ||
| 342 | return result; | ||
| 343 | }); | ||
| 344 | |||
| 345 | const int result = WSAPoll(host_pollfds.data(), static_cast<ULONG>(num), timeout); | ||
| 346 | if (result == 0) { | ||
| 347 | ASSERT(std::all_of(host_pollfds.begin(), host_pollfds.end(), | ||
| 348 | [](WSAPOLLFD fd) { return fd.revents == 0; })); | ||
| 349 | return {0, Errno::SUCCESS}; | ||
| 350 | } | ||
| 351 | |||
| 352 | for (size_t i = 0; i < num; ++i) { | ||
| 353 | pollfds[i].revents = TranslatePollRevents(host_pollfds[i].revents); | ||
| 354 | } | ||
| 355 | |||
| 356 | if (result > 0) { | ||
| 357 | return {result, Errno::SUCCESS}; | ||
| 358 | } | ||
| 359 | |||
| 360 | ASSERT(result == SOCKET_ERROR); | ||
| 361 | |||
| 362 | const int ec = LastError(); | ||
| 363 | UNREACHABLE_MSG("Unhandled host socket error={}", ec); | ||
| 364 | return {-1, Errno::SUCCESS}; | ||
| 365 | } | ||
| 366 | |||
| 367 | Socket::~Socket() { | ||
| 368 | if (fd == INVALID_SOCKET) { | ||
| 369 | return; | ||
| 370 | } | ||
| 371 | (void)closesocket(fd); | ||
| 372 | fd = INVALID_SOCKET; | ||
| 373 | } | ||
| 374 | |||
| 375 | Socket::Socket(Socket&& rhs) noexcept : fd{std::exchange(rhs.fd, INVALID_SOCKET)} {} | ||
| 376 | |||
| 377 | Errno Socket::Initialize(Domain domain, Type type, Protocol protocol) { | ||
| 378 | fd = socket(TranslateDomain(domain), TranslateType(type), TranslateProtocol(protocol)); | ||
| 379 | if (fd != INVALID_SOCKET) { | ||
| 380 | return Errno::SUCCESS; | ||
| 381 | } | ||
| 382 | |||
| 383 | const int ec = LastError(); | ||
| 384 | UNREACHABLE_MSG("Unhandled host socket error={}", ec); | ||
| 385 | return Errno::SUCCESS; | ||
| 386 | } | ||
| 387 | |||
| 388 | std::pair<Socket::AcceptResult, Errno> Socket::Accept() { | ||
| 389 | sockaddr addr; | ||
| 390 | socklen_t addrlen = sizeof(addr); | ||
| 391 | const SOCKET new_socket = accept(fd, &addr, &addrlen); | ||
| 392 | |||
| 393 | if (new_socket == INVALID_SOCKET) { | ||
| 394 | const int ec = LastError(); | ||
| 395 | UNREACHABLE_MSG("Unhandled host socket error={}", ec); | ||
| 396 | return {AcceptResult{}, Errno::SUCCESS}; | ||
| 397 | } | ||
| 398 | |||
| 399 | AcceptResult result; | ||
| 400 | result.socket = std::make_unique<Socket>(); | ||
| 401 | result.socket->fd = new_socket; | ||
| 402 | |||
| 403 | ASSERT(addrlen == sizeof(sockaddr_in)); | ||
| 404 | result.sockaddr_in = TranslateToSockAddrIn(addr); | ||
| 405 | |||
| 406 | return {std::move(result), Errno::SUCCESS}; | ||
| 407 | } | ||
| 408 | |||
| 409 | Errno Socket::Connect(SockAddrIn addr_in) { | ||
| 410 | const sockaddr host_addr_in = TranslateFromSockAddrIn(addr_in); | ||
| 411 | if (connect(fd, &host_addr_in, sizeof(host_addr_in)) != INVALID_SOCKET) { | ||
| 412 | return Errno::SUCCESS; | ||
| 413 | } | ||
| 414 | |||
| 415 | switch (const int ec = LastError()) { | ||
| 416 | case WSAEWOULDBLOCK: | ||
| 417 | LOG_DEBUG(Service, "EAGAIN generated"); | ||
| 418 | return Errno::AGAIN; | ||
| 419 | default: | ||
| 420 | UNREACHABLE_MSG("Unhandled host socket error={}", ec); | ||
| 421 | return Errno::SUCCESS; | ||
| 422 | } | ||
| 423 | } | ||
| 424 | |||
| 425 | std::pair<SockAddrIn, Errno> Socket::GetPeerName() { | ||
| 426 | sockaddr addr; | ||
| 427 | socklen_t addrlen = sizeof(addr); | ||
| 428 | if (getpeername(fd, &addr, &addrlen) == SOCKET_ERROR) { | ||
| 429 | const int ec = LastError(); | ||
| 430 | UNREACHABLE_MSG("Unhandled host socket error={}", ec); | ||
| 431 | return {SockAddrIn{}, Errno::SUCCESS}; | ||
| 432 | } | ||
| 433 | |||
| 434 | ASSERT(addrlen == sizeof(sockaddr_in)); | ||
| 435 | return {TranslateToSockAddrIn(addr), Errno::SUCCESS}; | ||
| 436 | } | ||
| 437 | |||
| 438 | std::pair<SockAddrIn, Errno> Socket::GetSockName() { | ||
| 439 | sockaddr addr; | ||
| 440 | socklen_t addrlen = sizeof(addr); | ||
| 441 | if (getsockname(fd, &addr, &addrlen) == SOCKET_ERROR) { | ||
| 442 | const int ec = LastError(); | ||
| 443 | UNREACHABLE_MSG("Unhandled host socket error={}", ec); | ||
| 444 | return {SockAddrIn{}, Errno::SUCCESS}; | ||
| 445 | } | ||
| 446 | |||
| 447 | ASSERT(addrlen == sizeof(sockaddr_in)); | ||
| 448 | return {TranslateToSockAddrIn(addr), Errno::SUCCESS}; | ||
| 449 | } | ||
| 450 | |||
| 451 | Errno Socket::Bind(SockAddrIn addr) { | ||
| 452 | const sockaddr addr_in = TranslateFromSockAddrIn(addr); | ||
| 453 | if (bind(fd, &addr_in, sizeof(addr_in)) != SOCKET_ERROR) { | ||
| 454 | return Errno::SUCCESS; | ||
| 455 | } | ||
| 456 | |||
| 457 | const int ec = LastError(); | ||
| 458 | UNREACHABLE_MSG("Unhandled host socket error={}", ec); | ||
| 459 | return Errno::SUCCESS; | ||
| 460 | } | ||
| 461 | |||
| 462 | Errno Socket::Listen(s32 backlog) { | ||
| 463 | if (listen(fd, backlog) != SOCKET_ERROR) { | ||
| 464 | return Errno::SUCCESS; | ||
| 465 | } | ||
| 466 | |||
| 467 | const int ec = LastError(); | ||
| 468 | UNREACHABLE_MSG("Unhandled host socket error={}", ec); | ||
| 469 | return Errno::SUCCESS; | ||
| 470 | } | ||
| 471 | |||
| 472 | Errno Socket::Shutdown(ShutdownHow how) { | ||
| 473 | int host_how = 0; | ||
| 474 | switch (how) { | ||
| 475 | case ShutdownHow::RD: | ||
| 476 | host_how = SD_RECEIVE; | ||
| 477 | break; | ||
| 478 | case ShutdownHow::WR: | ||
| 479 | host_how = SD_SEND; | ||
| 480 | break; | ||
| 481 | case ShutdownHow::RDWR: | ||
| 482 | host_how = SD_BOTH; | ||
| 483 | break; | ||
| 484 | default: | ||
| 485 | UNIMPLEMENTED_MSG("Unimplemented flag how={}", static_cast<int>(how)); | ||
| 486 | return Errno::SUCCESS; | ||
| 487 | } | ||
| 488 | if (shutdown(fd, host_how) != SOCKET_ERROR) { | ||
| 489 | return Errno::SUCCESS; | ||
| 490 | } | ||
| 491 | |||
| 492 | switch (const int ec = LastError()) { | ||
| 493 | case WSAENOTCONN: | ||
| 494 | LOG_ERROR(Service, "ENOTCONN generated"); | ||
| 495 | return Errno::NOTCONN; | ||
| 496 | default: | ||
| 497 | UNREACHABLE_MSG("Unhandled host socket error={}", ec); | ||
| 498 | return Errno::SUCCESS; | ||
| 499 | } | ||
| 500 | } | ||
| 501 | |||
| 502 | std::pair<s32, Errno> Socket::Recv(int flags, std::vector<u8>& message) { | ||
| 503 | ASSERT(flags == 0); | ||
| 504 | ASSERT(message.size() < static_cast<size_t>(std::numeric_limits<int>::max())); | ||
| 505 | |||
| 506 | const int result = | ||
| 507 | recv(fd, reinterpret_cast<char*>(message.data()), static_cast<int>(message.size()), 0); | ||
| 508 | if (result != SOCKET_ERROR) { | ||
| 509 | return {result, Errno::SUCCESS}; | ||
| 510 | } | ||
| 511 | |||
| 512 | switch (const int ec = LastError()) { | ||
| 513 | case WSAEWOULDBLOCK: | ||
| 514 | LOG_DEBUG(Service, "EAGAIN generated"); | ||
| 515 | return {-1, Errno::AGAIN}; | ||
| 516 | case WSAENOTCONN: | ||
| 517 | LOG_ERROR(Service, "ENOTCONN generated"); | ||
| 518 | return {-1, Errno::NOTCONN}; | ||
| 519 | default: | ||
| 520 | UNREACHABLE_MSG("Unhandled host socket error={}", ec); | ||
| 521 | return {0, Errno::SUCCESS}; | ||
| 522 | } | ||
| 523 | } | ||
| 524 | |||
| 525 | std::pair<s32, Errno> Socket::RecvFrom(int flags, std::vector<u8>& message, SockAddrIn* addr) { | ||
| 526 | ASSERT(flags == 0); | ||
| 527 | ASSERT(message.size() < static_cast<size_t>(std::numeric_limits<int>::max())); | ||
| 528 | |||
| 529 | sockaddr addr_in{}; | ||
| 530 | socklen_t addrlen = sizeof(addr_in); | ||
| 531 | socklen_t* const p_addrlen = addr ? &addrlen : nullptr; | ||
| 532 | sockaddr* const p_addr_in = addr ? &addr_in : nullptr; | ||
| 533 | |||
| 534 | const int result = recvfrom(fd, reinterpret_cast<char*>(message.data()), | ||
| 535 | static_cast<int>(message.size()), 0, p_addr_in, p_addrlen); | ||
| 536 | if (result != SOCKET_ERROR) { | ||
| 537 | if (addr) { | ||
| 538 | ASSERT(addrlen == sizeof(addr_in)); | ||
| 539 | *addr = TranslateToSockAddrIn(addr_in); | ||
| 540 | } | ||
| 541 | return {result, Errno::SUCCESS}; | ||
| 542 | } | ||
| 543 | |||
| 544 | switch (const int ec = LastError()) { | ||
| 545 | case WSAEWOULDBLOCK: | ||
| 546 | LOG_DEBUG(Service, "EAGAIN generated"); | ||
| 547 | return {-1, Errno::AGAIN}; | ||
| 548 | case WSAENOTCONN: | ||
| 549 | LOG_ERROR(Service, "ENOTCONN generated"); | ||
| 550 | return {-1, Errno::NOTCONN}; | ||
| 551 | default: | ||
| 552 | UNREACHABLE_MSG("Unhandled host socket error={}", ec); | ||
| 553 | return {-1, Errno::SUCCESS}; | ||
| 554 | } | ||
| 555 | } | ||
| 556 | |||
| 557 | std::pair<s32, Errno> Socket::Send(const std::vector<u8>& message, int flags) { | ||
| 558 | ASSERT(message.size() < static_cast<size_t>(std::numeric_limits<int>::max())); | ||
| 559 | ASSERT(flags == 0); | ||
| 560 | |||
| 561 | const int result = send(fd, reinterpret_cast<const char*>(message.data()), | ||
| 562 | static_cast<int>(message.size()), 0); | ||
| 563 | if (result != SOCKET_ERROR) { | ||
| 564 | return {result, Errno::SUCCESS}; | ||
| 565 | } | ||
| 566 | |||
| 567 | const int ec = LastError(); | ||
| 568 | switch (ec) { | ||
| 569 | case WSAEWOULDBLOCK: | ||
| 570 | LOG_DEBUG(Service, "EAGAIN generated"); | ||
| 571 | return {-1, Errno::AGAIN}; | ||
| 572 | case WSAENOTCONN: | ||
| 573 | LOG_ERROR(Service, "ENOTCONN generated"); | ||
| 574 | return {-1, Errno::NOTCONN}; | ||
| 575 | default: | ||
| 576 | UNREACHABLE_MSG("Unhandled host socket error={}", ec); | ||
| 577 | return {-1, Errno::SUCCESS}; | ||
| 578 | } | ||
| 579 | } | ||
| 580 | |||
| 581 | std::pair<s32, Errno> Socket::SendTo(u32 flags, const std::vector<u8>& message, | ||
| 582 | const SockAddrIn* addr) { | ||
| 583 | ASSERT(flags == 0); | ||
| 584 | |||
| 585 | const sockaddr* to = nullptr; | ||
| 586 | const int tolen = addr ? 0 : sizeof(sockaddr); | ||
| 587 | sockaddr host_addr_in; | ||
| 588 | |||
| 589 | if (addr) { | ||
| 590 | host_addr_in = TranslateFromSockAddrIn(*addr); | ||
| 591 | to = &host_addr_in; | ||
| 592 | } | ||
| 593 | |||
| 594 | const int result = sendto(fd, reinterpret_cast<const char*>(message.data()), | ||
| 595 | static_cast<int>(message.size()), 0, to, tolen); | ||
| 596 | if (result != SOCKET_ERROR) { | ||
| 597 | return {result, Errno::SUCCESS}; | ||
| 598 | } | ||
| 599 | |||
| 600 | const int ec = LastError(); | ||
| 601 | UNREACHABLE_MSG("Unhandled host socket error={}", ec); | ||
| 602 | return {-1, Errno::SUCCESS}; | ||
| 603 | } | ||
| 604 | |||
| 605 | Errno Socket::Close() { | ||
| 606 | [[maybe_unused]] const int result = closesocket(fd); | ||
| 607 | ASSERT(result == 0); | ||
| 608 | fd = INVALID_SOCKET; | ||
| 609 | |||
| 610 | return Errno::SUCCESS; | ||
| 611 | } | ||
| 612 | |||
| 613 | Errno Socket::SetLinger(bool enable, u32 linger) { | ||
| 614 | return SetSockOpt(fd, SO_LINGER, MakeLinger(enable, linger)); | ||
| 615 | } | ||
| 616 | |||
| 617 | Errno Socket::SetReuseAddr(bool enable) { | ||
| 618 | return SetSockOpt<u32>(fd, SO_REUSEADDR, enable ? 1 : 0); | ||
| 619 | } | ||
| 620 | |||
| 621 | Errno Socket::SetBroadcast(bool enable) { | ||
| 622 | return SetSockOpt<u32>(fd, SO_BROADCAST, enable ? 1 : 0); | ||
| 623 | } | ||
| 624 | |||
| 625 | Errno Socket::SetSndBuf(u32 value) { | ||
| 626 | return SetSockOpt(fd, SO_SNDBUF, value); | ||
| 627 | } | ||
| 628 | |||
| 629 | Errno Socket::SetRcvBuf(u32 value) { | ||
| 630 | return SetSockOpt(fd, SO_RCVBUF, value); | ||
| 631 | } | ||
| 632 | |||
| 633 | Errno Socket::SetSndTimeo(u32 value) { | ||
| 634 | return SetSockOpt(fd, SO_SNDTIMEO, value); | ||
| 635 | } | ||
| 636 | |||
| 637 | Errno Socket::SetRcvTimeo(u32 value) { | ||
| 638 | return SetSockOpt(fd, SO_RCVTIMEO, value); | ||
| 639 | } | ||
| 640 | |||
| 641 | Errno Socket::SetNonBlock(bool enable) { | ||
| 642 | if (EnableNonBlock(fd, enable)) { | ||
| 643 | return Errno::SUCCESS; | ||
| 644 | } | ||
| 645 | const int ec = LastError(); | ||
| 646 | UNREACHABLE_MSG("Unhandled host socket error={}", ec); | ||
| 647 | return Errno::SUCCESS; | ||
| 648 | } | ||
| 649 | |||
| 650 | bool Socket::IsOpened() const { | ||
| 651 | return fd != INVALID_SOCKET; | ||
| 652 | } | ||
| 653 | |||
| 654 | } // namespace Network | ||
diff --git a/src/core/network/network.h b/src/core/network/network.h new file mode 100644 index 000000000..0622e4593 --- /dev/null +++ b/src/core/network/network.h | |||
| @@ -0,0 +1,87 @@ | |||
| 1 | // Copyright 2020 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <array> | ||
| 8 | #include <utility> | ||
| 9 | |||
| 10 | #include "common/common_types.h" | ||
| 11 | |||
| 12 | namespace Network { | ||
| 13 | |||
| 14 | class Socket; | ||
| 15 | |||
| 16 | /// Error code for network functions | ||
| 17 | enum class Errno { | ||
| 18 | SUCCESS, | ||
| 19 | BADF, | ||
| 20 | INVAL, | ||
| 21 | MFILE, | ||
| 22 | NOTCONN, | ||
| 23 | AGAIN, | ||
| 24 | }; | ||
| 25 | |||
| 26 | /// Address families | ||
| 27 | enum class Domain { | ||
| 28 | INET, ///< Address family for IPv4 | ||
| 29 | }; | ||
| 30 | |||
| 31 | /// Socket types | ||
| 32 | enum class Type { | ||
| 33 | STREAM, | ||
| 34 | DGRAM, | ||
| 35 | RAW, | ||
| 36 | SEQPACKET, | ||
| 37 | }; | ||
| 38 | |||
| 39 | /// Protocol values for sockets | ||
| 40 | enum class Protocol { | ||
| 41 | ICMP, | ||
| 42 | TCP, | ||
| 43 | UDP, | ||
| 44 | }; | ||
| 45 | |||
| 46 | /// Shutdown mode | ||
| 47 | enum class ShutdownHow { | ||
| 48 | RD, | ||
| 49 | WR, | ||
| 50 | RDWR, | ||
| 51 | }; | ||
| 52 | |||
| 53 | /// Array of IPv4 address | ||
| 54 | using IPv4Address = std::array<u8, 4>; | ||
| 55 | |||
| 56 | /// Cross-platform sockaddr structure | ||
| 57 | struct SockAddrIn { | ||
| 58 | Domain family; | ||
| 59 | IPv4Address ip; | ||
| 60 | u16 portno; | ||
| 61 | }; | ||
| 62 | |||
| 63 | /// Cross-platform poll fd structure | ||
| 64 | struct PollFD { | ||
| 65 | Socket* socket; | ||
| 66 | u16 events; | ||
| 67 | u16 revents; | ||
| 68 | }; | ||
| 69 | |||
| 70 | constexpr u16 POLL_IN = 1 << 0; | ||
| 71 | constexpr u16 POLL_PRI = 1 << 1; | ||
| 72 | constexpr u16 POLL_OUT = 1 << 2; | ||
| 73 | constexpr u16 POLL_ERR = 1 << 3; | ||
| 74 | constexpr u16 POLL_HUP = 1 << 4; | ||
| 75 | constexpr u16 POLL_NVAL = 1 << 5; | ||
| 76 | |||
| 77 | class NetworkInstance { | ||
| 78 | public: | ||
| 79 | explicit NetworkInstance(); | ||
| 80 | ~NetworkInstance(); | ||
| 81 | }; | ||
| 82 | |||
| 83 | /// @brief Returns host's IPv4 address | ||
| 84 | /// @return Pair of an array of human ordered IPv4 address (e.g. 192.168.0.1) and an error code | ||
| 85 | std::pair<IPv4Address, Errno> GetHostIPv4Address(); | ||
| 86 | |||
| 87 | } // namespace Network | ||
diff --git a/src/core/network/sockets.h b/src/core/network/sockets.h new file mode 100644 index 000000000..7bdff0fe4 --- /dev/null +++ b/src/core/network/sockets.h | |||
| @@ -0,0 +1,94 @@ | |||
| 1 | // Copyright 2020 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <memory> | ||
| 8 | #include <utility> | ||
| 9 | |||
| 10 | #if defined(_WIN32) | ||
| 11 | #include <winsock.h> | ||
| 12 | #elif !defined(__unix__) | ||
| 13 | #error "Platform not implemented" | ||
| 14 | #endif | ||
| 15 | |||
| 16 | #include "common/common_types.h" | ||
| 17 | #include "core/network/network.h" | ||
| 18 | |||
| 19 | // TODO: C++20 Replace std::vector usages with std::span | ||
| 20 | |||
| 21 | namespace Network { | ||
| 22 | |||
| 23 | class Socket { | ||
| 24 | public: | ||
| 25 | struct AcceptResult { | ||
| 26 | std::unique_ptr<Socket> socket; | ||
| 27 | SockAddrIn sockaddr_in; | ||
| 28 | }; | ||
| 29 | |||
| 30 | explicit Socket() = default; | ||
| 31 | ~Socket(); | ||
| 32 | |||
| 33 | Socket(const Socket&) = delete; | ||
| 34 | Socket& operator=(const Socket&) = delete; | ||
| 35 | |||
| 36 | Socket(Socket&& rhs) noexcept; | ||
| 37 | |||
| 38 | // Avoid closing sockets implicitly | ||
| 39 | Socket& operator=(Socket&&) noexcept = delete; | ||
| 40 | |||
| 41 | Errno Initialize(Domain domain, Type type, Protocol protocol); | ||
| 42 | |||
| 43 | Errno Close(); | ||
| 44 | |||
| 45 | std::pair<AcceptResult, Errno> Accept(); | ||
| 46 | |||
| 47 | Errno Connect(SockAddrIn addr_in); | ||
| 48 | |||
| 49 | std::pair<SockAddrIn, Errno> GetPeerName(); | ||
| 50 | |||
| 51 | std::pair<SockAddrIn, Errno> GetSockName(); | ||
| 52 | |||
| 53 | Errno Bind(SockAddrIn addr); | ||
| 54 | |||
| 55 | Errno Listen(s32 backlog); | ||
| 56 | |||
| 57 | Errno Shutdown(ShutdownHow how); | ||
| 58 | |||
| 59 | std::pair<s32, Errno> Recv(int flags, std::vector<u8>& message); | ||
| 60 | |||
| 61 | std::pair<s32, Errno> RecvFrom(int flags, std::vector<u8>& message, SockAddrIn* addr); | ||
| 62 | |||
| 63 | std::pair<s32, Errno> Send(const std::vector<u8>& message, int flags); | ||
| 64 | |||
| 65 | std::pair<s32, Errno> SendTo(u32 flags, const std::vector<u8>& message, const SockAddrIn* addr); | ||
| 66 | |||
| 67 | Errno SetLinger(bool enable, u32 linger); | ||
| 68 | |||
| 69 | Errno SetReuseAddr(bool enable); | ||
| 70 | |||
| 71 | Errno SetBroadcast(bool enable); | ||
| 72 | |||
| 73 | Errno SetSndBuf(u32 value); | ||
| 74 | |||
| 75 | Errno SetRcvBuf(u32 value); | ||
| 76 | |||
| 77 | Errno SetSndTimeo(u32 value); | ||
| 78 | |||
| 79 | Errno SetRcvTimeo(u32 value); | ||
| 80 | |||
| 81 | Errno SetNonBlock(bool enable); | ||
| 82 | |||
| 83 | bool IsOpened() const; | ||
| 84 | |||
| 85 | #if defined(_WIN32) | ||
| 86 | SOCKET fd = INVALID_SOCKET; | ||
| 87 | #elif defined(__unix__) | ||
| 88 | int fd = -1; | ||
| 89 | #endif | ||
| 90 | }; | ||
| 91 | |||
| 92 | std::pair<s32, Errno> Poll(std::vector<PollFD>& poll_fds, s32 timeout); | ||
| 93 | |||
| 94 | } // namespace Network | ||
diff --git a/src/input_common/gcadapter/gc_adapter.cpp b/src/input_common/gcadapter/gc_adapter.cpp index 898a278a9..02d06876f 100644 --- a/src/input_common/gcadapter/gc_adapter.cpp +++ b/src/input_common/gcadapter/gc_adapter.cpp | |||
| @@ -24,12 +24,9 @@ Adapter::Adapter() { | |||
| 24 | } | 24 | } |
| 25 | LOG_INFO(Input, "GC Adapter Initialization started"); | 25 | LOG_INFO(Input, "GC Adapter Initialization started"); |
| 26 | 26 | ||
| 27 | current_status = NO_ADAPTER_DETECTED; | ||
| 28 | get_origin.fill(true); | ||
| 29 | |||
| 30 | const int init_res = libusb_init(&libusb_ctx); | 27 | const int init_res = libusb_init(&libusb_ctx); |
| 31 | if (init_res == LIBUSB_SUCCESS) { | 28 | if (init_res == LIBUSB_SUCCESS) { |
| 32 | StartScanThread(); | 29 | Setup(); |
| 33 | } else { | 30 | } else { |
| 34 | LOG_ERROR(Input, "libusb could not be initialized. failed with error = {}", init_res); | 31 | LOG_ERROR(Input, "libusb could not be initialized. failed with error = {}", init_res); |
| 35 | } | 32 | } |
| @@ -37,9 +34,9 @@ Adapter::Adapter() { | |||
| 37 | 34 | ||
| 38 | GCPadStatus Adapter::GetPadStatus(std::size_t port, const std::array<u8, 37>& adapter_payload) { | 35 | GCPadStatus Adapter::GetPadStatus(std::size_t port, const std::array<u8, 37>& adapter_payload) { |
| 39 | GCPadStatus pad = {}; | 36 | GCPadStatus pad = {}; |
| 37 | const std::size_t offset = 1 + (9 * port); | ||
| 40 | 38 | ||
| 41 | ControllerTypes type = ControllerTypes(adapter_payload[1 + (9 * port)] >> 4); | 39 | adapter_controllers_status[port] = static_cast<ControllerTypes>(adapter_payload[offset] >> 4); |
| 42 | adapter_controllers_status[port] = type; | ||
| 43 | 40 | ||
| 44 | static constexpr std::array<PadButton, 8> b1_buttons{ | 41 | static constexpr std::array<PadButton, 8> b1_buttons{ |
| 45 | PadButton::PAD_BUTTON_A, PadButton::PAD_BUTTON_B, PadButton::PAD_BUTTON_X, | 42 | PadButton::PAD_BUTTON_A, PadButton::PAD_BUTTON_B, PadButton::PAD_BUTTON_X, |
| @@ -54,14 +51,19 @@ GCPadStatus Adapter::GetPadStatus(std::size_t port, const std::array<u8, 37>& ad | |||
| 54 | PadButton::PAD_TRIGGER_L, | 51 | PadButton::PAD_TRIGGER_L, |
| 55 | }; | 52 | }; |
| 56 | 53 | ||
| 54 | static constexpr std::array<PadAxes, 6> axes{ | ||
| 55 | PadAxes::StickX, PadAxes::StickY, PadAxes::SubstickX, | ||
| 56 | PadAxes::SubstickY, PadAxes::TriggerLeft, PadAxes::TriggerRight, | ||
| 57 | }; | ||
| 58 | |||
| 57 | if (adapter_controllers_status[port] == ControllerTypes::None && !get_origin[port]) { | 59 | if (adapter_controllers_status[port] == ControllerTypes::None && !get_origin[port]) { |
| 58 | // Controller may have been disconnected, recalibrate if reconnected. | 60 | // Controller may have been disconnected, recalibrate if reconnected. |
| 59 | get_origin[port] = true; | 61 | get_origin[port] = true; |
| 60 | } | 62 | } |
| 61 | 63 | ||
| 62 | if (adapter_controllers_status[port] != ControllerTypes::None) { | 64 | if (adapter_controllers_status[port] != ControllerTypes::None) { |
| 63 | const u8 b1 = adapter_payload[1 + (9 * port) + 1]; | 65 | const u8 b1 = adapter_payload[offset + 1]; |
| 64 | const u8 b2 = adapter_payload[1 + (9 * port) + 2]; | 66 | const u8 b2 = adapter_payload[offset + 2]; |
| 65 | 67 | ||
| 66 | for (std::size_t i = 0; i < b1_buttons.size(); ++i) { | 68 | for (std::size_t i = 0; i < b1_buttons.size(); ++i) { |
| 67 | if ((b1 & (1U << i)) != 0) { | 69 | if ((b1 & (1U << i)) != 0) { |
| @@ -74,21 +76,13 @@ GCPadStatus Adapter::GetPadStatus(std::size_t port, const std::array<u8, 37>& ad | |||
| 74 | pad.button |= static_cast<u16>(b2_buttons[j]); | 76 | pad.button |= static_cast<u16>(b2_buttons[j]); |
| 75 | } | 77 | } |
| 76 | } | 78 | } |
| 77 | 79 | for (PadAxes axis : axes) { | |
| 78 | pad.stick_x = adapter_payload[1 + (9 * port) + 3]; | 80 | const std::size_t index = static_cast<std::size_t>(axis); |
| 79 | pad.stick_y = adapter_payload[1 + (9 * port) + 4]; | 81 | pad.axis_values[index] = adapter_payload[offset + 3 + index]; |
| 80 | pad.substick_x = adapter_payload[1 + (9 * port) + 5]; | 82 | } |
| 81 | pad.substick_y = adapter_payload[1 + (9 * port) + 6]; | ||
| 82 | pad.trigger_left = adapter_payload[1 + (9 * port) + 7]; | ||
| 83 | pad.trigger_right = adapter_payload[1 + (9 * port) + 8]; | ||
| 84 | 83 | ||
| 85 | if (get_origin[port]) { | 84 | if (get_origin[port]) { |
| 86 | origin_status[port].stick_x = pad.stick_x; | 85 | origin_status[port].axis_values = pad.axis_values; |
| 87 | origin_status[port].stick_y = pad.stick_y; | ||
| 88 | origin_status[port].substick_x = pad.substick_x; | ||
| 89 | origin_status[port].substick_y = pad.substick_y; | ||
| 90 | origin_status[port].trigger_left = pad.trigger_left; | ||
| 91 | origin_status[port].trigger_right = pad.trigger_right; | ||
| 92 | get_origin[port] = false; | 86 | get_origin[port] = false; |
| 93 | } | 87 | } |
| 94 | } | 88 | } |
| @@ -101,82 +95,47 @@ void Adapter::PadToState(const GCPadStatus& pad, GCState& state) { | |||
| 101 | state.buttons.insert_or_assign(button_value, pad.button & button_value); | 95 | state.buttons.insert_or_assign(button_value, pad.button & button_value); |
| 102 | } | 96 | } |
| 103 | 97 | ||
| 104 | state.axes.insert_or_assign(static_cast<u8>(PadAxes::StickX), pad.stick_x); | 98 | for (size_t i = 0; i < pad.axis_values.size(); ++i) { |
| 105 | state.axes.insert_or_assign(static_cast<u8>(PadAxes::StickY), pad.stick_y); | 99 | state.axes.insert_or_assign(static_cast<u8>(i), pad.axis_values[i]); |
| 106 | state.axes.insert_or_assign(static_cast<u8>(PadAxes::SubstickX), pad.substick_x); | 100 | } |
| 107 | state.axes.insert_or_assign(static_cast<u8>(PadAxes::SubstickY), pad.substick_y); | ||
| 108 | state.axes.insert_or_assign(static_cast<u8>(PadAxes::TriggerLeft), pad.trigger_left); | ||
| 109 | state.axes.insert_or_assign(static_cast<u8>(PadAxes::TriggerRight), pad.trigger_right); | ||
| 110 | } | 101 | } |
| 111 | 102 | ||
| 112 | void Adapter::Read() { | 103 | void Adapter::Read() { |
| 113 | LOG_DEBUG(Input, "GC Adapter Read() thread started"); | 104 | LOG_DEBUG(Input, "GC Adapter Read() thread started"); |
| 114 | 105 | ||
| 115 | int payload_size_in, payload_size_copy; | 106 | int payload_size; |
| 116 | std::array<u8, 37> adapter_payload; | 107 | std::array<u8, 37> adapter_payload; |
| 117 | std::array<u8, 37> adapter_payload_copy; | ||
| 118 | std::array<GCPadStatus, 4> pads; | 108 | std::array<GCPadStatus, 4> pads; |
| 119 | 109 | ||
| 120 | while (adapter_thread_running) { | 110 | while (adapter_thread_running) { |
| 121 | libusb_interrupt_transfer(usb_adapter_handle, input_endpoint, adapter_payload.data(), | 111 | libusb_interrupt_transfer(usb_adapter_handle, input_endpoint, adapter_payload.data(), |
| 122 | sizeof(adapter_payload), &payload_size_in, 16); | 112 | sizeof(adapter_payload), &payload_size, 16); |
| 123 | payload_size_copy = 0; | ||
| 124 | // this mutex might be redundant? | ||
| 125 | { | ||
| 126 | std::lock_guard<std::mutex> lk(s_mutex); | ||
| 127 | std::copy(std::begin(adapter_payload), std::end(adapter_payload), | ||
| 128 | std::begin(adapter_payload_copy)); | ||
| 129 | payload_size_copy = payload_size_in; | ||
| 130 | } | ||
| 131 | 113 | ||
| 132 | if (payload_size_copy != sizeof(adapter_payload_copy) || | 114 | if (payload_size != sizeof(adapter_payload) || adapter_payload[0] != LIBUSB_DT_HID) { |
| 133 | adapter_payload_copy[0] != LIBUSB_DT_HID) { | 115 | LOG_ERROR(Input, |
| 134 | LOG_ERROR(Input, "error reading payload (size: {}, type: {:02x})", payload_size_copy, | 116 | "Error reading payload (size: {}, type: {:02x}) Is the adapter connected?", |
| 135 | adapter_payload_copy[0]); | 117 | payload_size, adapter_payload[0]); |
| 136 | adapter_thread_running = false; // error reading from adapter, stop reading. | 118 | adapter_thread_running = false; // error reading from adapter, stop reading. |
| 137 | break; | 119 | break; |
| 138 | } | 120 | } |
| 139 | for (std::size_t port = 0; port < pads.size(); ++port) { | 121 | for (std::size_t port = 0; port < pads.size(); ++port) { |
| 140 | pads[port] = GetPadStatus(port, adapter_payload_copy); | 122 | pads[port] = GetPadStatus(port, adapter_payload); |
| 141 | if (DeviceConnected(port) && configuring) { | 123 | if (DeviceConnected(port) && configuring) { |
| 142 | if (pads[port].button != 0) { | 124 | if (pads[port].button != 0) { |
| 143 | pad_queue[port].Push(pads[port]); | 125 | pad_queue[port].Push(pads[port]); |
| 144 | } | 126 | } |
| 145 | 127 | ||
| 146 | // Accounting for a threshold here because of some controller variance | 128 | // Accounting for a threshold here to ensure an intentional press |
| 147 | if (pads[port].stick_x > origin_status[port].stick_x + pads[port].THRESHOLD || | 129 | for (size_t i = 0; i < pads[port].axis_values.size(); ++i) { |
| 148 | pads[port].stick_x < origin_status[port].stick_x - pads[port].THRESHOLD) { | 130 | const u8 value = pads[port].axis_values[i]; |
| 149 | pads[port].axis = GCAdapter::PadAxes::StickX; | 131 | const u8 origin = origin_status[port].axis_values[i]; |
| 150 | pads[port].axis_value = pads[port].stick_x; | 132 | |
| 151 | pad_queue[port].Push(pads[port]); | 133 | if (value > origin + pads[port].THRESHOLD || |
| 152 | } | 134 | value < origin - pads[port].THRESHOLD) { |
| 153 | if (pads[port].stick_y > origin_status[port].stick_y + pads[port].THRESHOLD || | 135 | pads[port].axis = static_cast<PadAxes>(i); |
| 154 | pads[port].stick_y < origin_status[port].stick_y - pads[port].THRESHOLD) { | 136 | pads[port].axis_value = pads[port].axis_values[i]; |
| 155 | pads[port].axis = GCAdapter::PadAxes::StickY; | 137 | pad_queue[port].Push(pads[port]); |
| 156 | pads[port].axis_value = pads[port].stick_y; | 138 | } |
| 157 | pad_queue[port].Push(pads[port]); | ||
| 158 | } | ||
| 159 | if (pads[port].substick_x > origin_status[port].substick_x + pads[port].THRESHOLD || | ||
| 160 | pads[port].substick_x < origin_status[port].substick_x - pads[port].THRESHOLD) { | ||
| 161 | pads[port].axis = GCAdapter::PadAxes::SubstickX; | ||
| 162 | pads[port].axis_value = pads[port].substick_x; | ||
| 163 | pad_queue[port].Push(pads[port]); | ||
| 164 | } | ||
| 165 | if (pads[port].substick_y > origin_status[port].substick_y + pads[port].THRESHOLD || | ||
| 166 | pads[port].substick_y < origin_status[port].substick_y - pads[port].THRESHOLD) { | ||
| 167 | pads[port].axis = GCAdapter::PadAxes::SubstickY; | ||
| 168 | pads[port].axis_value = pads[port].substick_y; | ||
| 169 | pad_queue[port].Push(pads[port]); | ||
| 170 | } | ||
| 171 | if (pads[port].trigger_left > pads[port].TRIGGER_THRESHOLD) { | ||
| 172 | pads[port].axis = GCAdapter::PadAxes::TriggerLeft; | ||
| 173 | pads[port].axis_value = pads[port].trigger_left; | ||
| 174 | pad_queue[port].Push(pads[port]); | ||
| 175 | } | ||
| 176 | if (pads[port].trigger_right > pads[port].TRIGGER_THRESHOLD) { | ||
| 177 | pads[port].axis = GCAdapter::PadAxes::TriggerRight; | ||
| 178 | pads[port].axis_value = pads[port].trigger_right; | ||
| 179 | pad_queue[port].Push(pads[port]); | ||
| 180 | } | 139 | } |
| 181 | } | 140 | } |
| 182 | PadToState(pads[port], state[port]); | 141 | PadToState(pads[port], state[port]); |
| @@ -185,42 +144,11 @@ void Adapter::Read() { | |||
| 185 | } | 144 | } |
| 186 | } | 145 | } |
| 187 | 146 | ||
| 188 | void Adapter::ScanThreadFunc() { | ||
| 189 | LOG_INFO(Input, "GC Adapter scanning thread started"); | ||
| 190 | |||
| 191 | while (detect_thread_running) { | ||
| 192 | if (usb_adapter_handle == nullptr) { | ||
| 193 | std::lock_guard<std::mutex> lk(initialization_mutex); | ||
| 194 | Setup(); | ||
| 195 | } | ||
| 196 | std::this_thread::sleep_for(std::chrono::milliseconds(500)); | ||
| 197 | } | ||
| 198 | } | ||
| 199 | |||
| 200 | void Adapter::StartScanThread() { | ||
| 201 | if (detect_thread_running) { | ||
| 202 | return; | ||
| 203 | } | ||
| 204 | if (!libusb_ctx) { | ||
| 205 | return; | ||
| 206 | } | ||
| 207 | |||
| 208 | detect_thread_running = true; | ||
| 209 | detect_thread = std::thread(&Adapter::ScanThreadFunc, this); | ||
| 210 | } | ||
| 211 | |||
| 212 | void Adapter::StopScanThread() { | ||
| 213 | detect_thread_running = false; | ||
| 214 | detect_thread.join(); | ||
| 215 | } | ||
| 216 | |||
| 217 | void Adapter::Setup() { | 147 | void Adapter::Setup() { |
| 218 | // Reset the error status in case the adapter gets unplugged | 148 | // Initialize all controllers as unplugged |
| 219 | if (current_status < 0) { | ||
| 220 | current_status = NO_ADAPTER_DETECTED; | ||
| 221 | } | ||
| 222 | |||
| 223 | adapter_controllers_status.fill(ControllerTypes::None); | 149 | adapter_controllers_status.fill(ControllerTypes::None); |
| 150 | // Initialize all ports to store axis origin values | ||
| 151 | get_origin.fill(true); | ||
| 224 | 152 | ||
| 225 | // pointer to list of connected usb devices | 153 | // pointer to list of connected usb devices |
| 226 | libusb_device** devices{}; | 154 | libusb_device** devices{}; |
| @@ -229,8 +157,6 @@ void Adapter::Setup() { | |||
| 229 | const ssize_t device_count = libusb_get_device_list(libusb_ctx, &devices); | 157 | const ssize_t device_count = libusb_get_device_list(libusb_ctx, &devices); |
| 230 | if (device_count < 0) { | 158 | if (device_count < 0) { |
| 231 | LOG_ERROR(Input, "libusb_get_device_list failed with error: {}", device_count); | 159 | LOG_ERROR(Input, "libusb_get_device_list failed with error: {}", device_count); |
| 232 | detect_thread_running = false; // Stop the loop constantly checking for gc adapter | ||
| 233 | // TODO: For hotplug+gc adapter checkbox implementation, revert this. | ||
| 234 | return; | 160 | return; |
| 235 | } | 161 | } |
| 236 | 162 | ||
| @@ -244,9 +170,6 @@ void Adapter::Setup() { | |||
| 244 | } | 170 | } |
| 245 | libusb_free_device_list(devices, 1); | 171 | libusb_free_device_list(devices, 1); |
| 246 | } | 172 | } |
| 247 | // Break out of the ScanThreadFunc() loop that is constantly looking for the device | ||
| 248 | // Assumes user has GC adapter plugged in before launch to use the adapter | ||
| 249 | detect_thread_running = false; | ||
| 250 | } | 173 | } |
| 251 | 174 | ||
| 252 | bool Adapter::CheckDeviceAccess(libusb_device* device) { | 175 | bool Adapter::CheckDeviceAccess(libusb_device* device) { |
| @@ -331,24 +254,14 @@ void Adapter::GetGCEndpoint(libusb_device* device) { | |||
| 331 | sizeof(clear_payload), nullptr, 16); | 254 | sizeof(clear_payload), nullptr, 16); |
| 332 | 255 | ||
| 333 | adapter_thread_running = true; | 256 | adapter_thread_running = true; |
| 334 | current_status = ADAPTER_DETECTED; | ||
| 335 | adapter_input_thread = std::thread([=] { Read(); }); // Read input | 257 | adapter_input_thread = std::thread([=] { Read(); }); // Read input |
| 336 | } | 258 | } |
| 337 | 259 | ||
| 338 | Adapter::~Adapter() { | 260 | Adapter::~Adapter() { |
| 339 | StopScanThread(); | ||
| 340 | Reset(); | 261 | Reset(); |
| 341 | } | 262 | } |
| 342 | 263 | ||
| 343 | void Adapter::Reset() { | 264 | void Adapter::Reset() { |
| 344 | std::unique_lock<std::mutex> lock(initialization_mutex, std::defer_lock); | ||
| 345 | if (!lock.try_lock()) { | ||
| 346 | return; | ||
| 347 | } | ||
| 348 | if (current_status != ADAPTER_DETECTED) { | ||
| 349 | return; | ||
| 350 | } | ||
| 351 | |||
| 352 | if (adapter_thread_running) { | 265 | if (adapter_thread_running) { |
| 353 | adapter_thread_running = false; | 266 | adapter_thread_running = false; |
| 354 | } | 267 | } |
| @@ -356,7 +269,6 @@ void Adapter::Reset() { | |||
| 356 | 269 | ||
| 357 | adapter_controllers_status.fill(ControllerTypes::None); | 270 | adapter_controllers_status.fill(ControllerTypes::None); |
| 358 | get_origin.fill(true); | 271 | get_origin.fill(true); |
| 359 | current_status = NO_ADAPTER_DETECTED; | ||
| 360 | 272 | ||
| 361 | if (usb_adapter_handle) { | 273 | if (usb_adapter_handle) { |
| 362 | libusb_release_interface(usb_adapter_handle, 1); | 274 | libusb_release_interface(usb_adapter_handle, 1); |
| @@ -409,24 +321,7 @@ const std::array<GCState, 4>& Adapter::GetPadState() const { | |||
| 409 | } | 321 | } |
| 410 | 322 | ||
| 411 | int Adapter::GetOriginValue(int port, int axis) const { | 323 | int Adapter::GetOriginValue(int port, int axis) const { |
| 412 | const auto& status = origin_status[port]; | 324 | return origin_status[port].axis_values[axis]; |
| 413 | |||
| 414 | switch (static_cast<PadAxes>(axis)) { | ||
| 415 | case PadAxes::StickX: | ||
| 416 | return status.stick_x; | ||
| 417 | case PadAxes::StickY: | ||
| 418 | return status.stick_y; | ||
| 419 | case PadAxes::SubstickX: | ||
| 420 | return status.substick_x; | ||
| 421 | case PadAxes::SubstickY: | ||
| 422 | return status.substick_y; | ||
| 423 | case PadAxes::TriggerLeft: | ||
| 424 | return status.trigger_left; | ||
| 425 | case PadAxes::TriggerRight: | ||
| 426 | return status.trigger_right; | ||
| 427 | default: | ||
| 428 | return 0; | ||
| 429 | } | ||
| 430 | } | 325 | } |
| 431 | 326 | ||
| 432 | } // namespace GCAdapter | 327 | } // namespace GCAdapter |
diff --git a/src/input_common/gcadapter/gc_adapter.h b/src/input_common/gcadapter/gc_adapter.h index 3586c8bda..bed81915c 100644 --- a/src/input_common/gcadapter/gc_adapter.h +++ b/src/input_common/gcadapter/gc_adapter.h | |||
| @@ -47,24 +47,10 @@ enum class PadAxes : u8 { | |||
| 47 | }; | 47 | }; |
| 48 | 48 | ||
| 49 | struct GCPadStatus { | 49 | struct GCPadStatus { |
| 50 | u16 button{}; // Or-ed PAD_BUTTON_* and PAD_TRIGGER_* bits | 50 | u16 button{}; // Or-ed PAD_BUTTON_* and PAD_TRIGGER_* bits |
| 51 | u8 stick_x{}; // 0 <= stick_x <= 255 | 51 | |
| 52 | u8 stick_y{}; // 0 <= stick_y <= 255 | 52 | std::array<u8, 6> axis_values{}; // Triggers and sticks, following indices defined in PadAxes |
| 53 | u8 substick_x{}; // 0 <= substick_x <= 255 | 53 | static constexpr u8 THRESHOLD = 50; // Threshold for axis press for polling |
| 54 | u8 substick_y{}; // 0 <= substick_y <= 255 | ||
| 55 | u8 trigger_left{}; // 0 <= trigger_left <= 255 | ||
| 56 | u8 trigger_right{}; // 0 <= trigger_right <= 255 | ||
| 57 | |||
| 58 | static constexpr u8 MAIN_STICK_CENTER_X = 0x80; | ||
| 59 | static constexpr u8 MAIN_STICK_CENTER_Y = 0x80; | ||
| 60 | static constexpr u8 MAIN_STICK_RADIUS = 0x7f; | ||
| 61 | static constexpr u8 C_STICK_CENTER_X = 0x80; | ||
| 62 | static constexpr u8 C_STICK_CENTER_Y = 0x80; | ||
| 63 | static constexpr u8 C_STICK_RADIUS = 0x7f; | ||
| 64 | static constexpr u8 THRESHOLD = 10; | ||
| 65 | |||
| 66 | // 256/4, at least a quarter press to count as a press. For polling mostly | ||
| 67 | static constexpr u8 TRIGGER_THRESHOLD = 64; | ||
| 68 | 54 | ||
| 69 | u8 port{}; | 55 | u8 port{}; |
| 70 | PadAxes axis{PadAxes::Undefined}; | 56 | PadAxes axis{PadAxes::Undefined}; |
| @@ -78,11 +64,6 @@ struct GCState { | |||
| 78 | 64 | ||
| 79 | enum class ControllerTypes { None, Wired, Wireless }; | 65 | enum class ControllerTypes { None, Wired, Wireless }; |
| 80 | 66 | ||
| 81 | enum { | ||
| 82 | NO_ADAPTER_DETECTED = 0, | ||
| 83 | ADAPTER_DETECTED = 1, | ||
| 84 | }; | ||
| 85 | |||
| 86 | class Adapter { | 67 | class Adapter { |
| 87 | public: | 68 | public: |
| 88 | /// Initialize the GC Adapter capture and read sequence | 69 | /// Initialize the GC Adapter capture and read sequence |
| @@ -111,12 +92,6 @@ private: | |||
| 111 | void PadToState(const GCPadStatus& pad, GCState& state); | 92 | void PadToState(const GCPadStatus& pad, GCState& state); |
| 112 | 93 | ||
| 113 | void Read(); | 94 | void Read(); |
| 114 | void ScanThreadFunc(); | ||
| 115 | /// Begin scanning for the GC Adapter. | ||
| 116 | void StartScanThread(); | ||
| 117 | |||
| 118 | /// Stop scanning for the adapter | ||
| 119 | void StopScanThread(); | ||
| 120 | 95 | ||
| 121 | /// Resets status of device connected to port | 96 | /// Resets status of device connected to port |
| 122 | void ResetDeviceType(std::size_t port); | 97 | void ResetDeviceType(std::size_t port); |
| @@ -133,19 +108,11 @@ private: | |||
| 133 | /// For use in initialization, querying devices to find the adapter | 108 | /// For use in initialization, querying devices to find the adapter |
| 134 | void Setup(); | 109 | void Setup(); |
| 135 | 110 | ||
| 136 | int current_status = NO_ADAPTER_DETECTED; | ||
| 137 | libusb_device_handle* usb_adapter_handle = nullptr; | 111 | libusb_device_handle* usb_adapter_handle = nullptr; |
| 138 | std::array<ControllerTypes, 4> adapter_controllers_status{}; | ||
| 139 | |||
| 140 | std::mutex s_mutex; | ||
| 141 | 112 | ||
| 142 | std::thread adapter_input_thread; | 113 | std::thread adapter_input_thread; |
| 143 | bool adapter_thread_running; | 114 | bool adapter_thread_running; |
| 144 | 115 | ||
| 145 | std::mutex initialization_mutex; | ||
| 146 | std::thread detect_thread; | ||
| 147 | bool detect_thread_running = false; | ||
| 148 | |||
| 149 | libusb_context* libusb_ctx; | 116 | libusb_context* libusb_ctx; |
| 150 | 117 | ||
| 151 | u8 input_endpoint = 0; | 118 | u8 input_endpoint = 0; |
| @@ -153,10 +120,11 @@ private: | |||
| 153 | 120 | ||
| 154 | bool configuring = false; | 121 | bool configuring = false; |
| 155 | 122 | ||
| 156 | std::array<Common::SPSCQueue<GCPadStatus>, 4> pad_queue; | ||
| 157 | std::array<GCState, 4> state; | 123 | std::array<GCState, 4> state; |
| 158 | std::array<bool, 4> get_origin; | 124 | std::array<bool, 4> get_origin; |
| 159 | std::array<GCPadStatus, 4> origin_status; | 125 | std::array<GCPadStatus, 4> origin_status; |
| 126 | std::array<Common::SPSCQueue<GCPadStatus>, 4> pad_queue; | ||
| 127 | std::array<ControllerTypes, 4> adapter_controllers_status{}; | ||
| 160 | }; | 128 | }; |
| 161 | 129 | ||
| 162 | } // namespace GCAdapter | 130 | } // namespace GCAdapter |
diff --git a/src/video_core/compatible_formats.cpp b/src/video_core/compatible_formats.cpp index 6c426b035..b06c32c84 100644 --- a/src/video_core/compatible_formats.cpp +++ b/src/video_core/compatible_formats.cpp | |||
| @@ -17,101 +17,94 @@ namespace { | |||
| 17 | // https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_texture_view.txt | 17 | // https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_texture_view.txt |
| 18 | 18 | ||
| 19 | constexpr std::array VIEW_CLASS_128_BITS = { | 19 | constexpr std::array VIEW_CLASS_128_BITS = { |
| 20 | PixelFormat::RGBA32F, | 20 | PixelFormat::R32G32B32A32_FLOAT, |
| 21 | PixelFormat::RGBA32UI, | 21 | PixelFormat::R32G32B32A32_UINT, |
| 22 | PixelFormat::R32G32B32A32_SINT, | ||
| 22 | }; | 23 | }; |
| 23 | // Missing formats: | ||
| 24 | // PixelFormat::RGBA32I | ||
| 25 | 24 | ||
| 26 | constexpr std::array VIEW_CLASS_96_BITS = { | 25 | constexpr std::array VIEW_CLASS_96_BITS = { |
| 27 | PixelFormat::RGB32F, | 26 | PixelFormat::R32G32B32_FLOAT, |
| 28 | }; | 27 | }; |
| 29 | // Missing formats: | 28 | // Missing formats: |
| 30 | // PixelFormat::RGB32UI, | 29 | // PixelFormat::RGB32UI, |
| 31 | // PixelFormat::RGB32I, | 30 | // PixelFormat::RGB32I, |
| 32 | 31 | ||
| 33 | constexpr std::array VIEW_CLASS_64_BITS = { | 32 | constexpr std::array VIEW_CLASS_64_BITS = { |
| 34 | PixelFormat::RGBA16F, PixelFormat::RG32F, PixelFormat::RGBA16UI, PixelFormat::RG32UI, | 33 | PixelFormat::R32G32_FLOAT, PixelFormat::R32G32_UINT, |
| 35 | PixelFormat::RGBA16U, PixelFormat::RGBA16F, PixelFormat::RGBA16S, | 34 | PixelFormat::R32G32_SINT, PixelFormat::R16G16B16A16_FLOAT, |
| 35 | PixelFormat::R16G16B16A16_UNORM, PixelFormat::R16G16B16A16_SNORM, | ||
| 36 | PixelFormat::R16G16B16A16_UINT, PixelFormat::R16G16B16A16_SINT, | ||
| 36 | }; | 37 | }; |
| 37 | // Missing formats: | ||
| 38 | // PixelFormat::RGBA16I | ||
| 39 | // PixelFormat::RG32I | ||
| 40 | 38 | ||
| 41 | // TODO: How should we handle 48 bits? | 39 | // TODO: How should we handle 48 bits? |
| 42 | 40 | ||
| 43 | constexpr std::array VIEW_CLASS_32_BITS = { | 41 | constexpr std::array VIEW_CLASS_32_BITS = { |
| 44 | PixelFormat::RG16F, PixelFormat::R11FG11FB10F, PixelFormat::R32F, | 42 | PixelFormat::R16G16_FLOAT, PixelFormat::B10G11R11_FLOAT, PixelFormat::R32_FLOAT, |
| 45 | PixelFormat::A2B10G10R10U, PixelFormat::RG16UI, PixelFormat::R32UI, | 43 | PixelFormat::A2B10G10R10_UNORM, PixelFormat::R16G16_UINT, PixelFormat::R32_UINT, |
| 46 | PixelFormat::RG16I, PixelFormat::R32I, PixelFormat::ABGR8U, | 44 | PixelFormat::R16G16_SINT, PixelFormat::R32_SINT, PixelFormat::A8B8G8R8_UNORM, |
| 47 | PixelFormat::RG16, PixelFormat::ABGR8S, PixelFormat::RG16S, | 45 | PixelFormat::R16G16_UNORM, PixelFormat::A8B8G8R8_SNORM, PixelFormat::R16G16_SNORM, |
| 48 | PixelFormat::RGBA8_SRGB, PixelFormat::E5B9G9R9F, PixelFormat::BGRA8, | 46 | PixelFormat::A8B8G8R8_SRGB, PixelFormat::E5B9G9R9_FLOAT, PixelFormat::B8G8R8A8_UNORM, |
| 49 | PixelFormat::BGRA8_SRGB, | 47 | PixelFormat::B8G8R8A8_SRGB, PixelFormat::A8B8G8R8_UINT, PixelFormat::A8B8G8R8_SINT, |
| 48 | PixelFormat::A2B10G10R10_UINT, | ||
| 50 | }; | 49 | }; |
| 51 | // Missing formats: | ||
| 52 | // PixelFormat::RGBA8UI | ||
| 53 | // PixelFormat::RGBA8I | ||
| 54 | // PixelFormat::RGB10_A2_UI | ||
| 55 | 50 | ||
| 56 | // TODO: How should we handle 24 bits? | 51 | // TODO: How should we handle 24 bits? |
| 57 | 52 | ||
| 58 | constexpr std::array VIEW_CLASS_16_BITS = { | 53 | constexpr std::array VIEW_CLASS_16_BITS = { |
| 59 | PixelFormat::R16F, PixelFormat::RG8UI, PixelFormat::R16UI, PixelFormat::R16I, | 54 | PixelFormat::R16_FLOAT, PixelFormat::R8G8_UINT, PixelFormat::R16_UINT, |
| 60 | PixelFormat::RG8U, PixelFormat::R16U, PixelFormat::RG8S, PixelFormat::R16S, | 55 | PixelFormat::R16_SINT, PixelFormat::R8G8_UNORM, PixelFormat::R16_UNORM, |
| 56 | PixelFormat::R8G8_SNORM, PixelFormat::R16_SNORM, PixelFormat::R8G8_SINT, | ||
| 61 | }; | 57 | }; |
| 62 | // Missing formats: | ||
| 63 | // PixelFormat::RG8I | ||
| 64 | 58 | ||
| 65 | constexpr std::array VIEW_CLASS_8_BITS = { | 59 | constexpr std::array VIEW_CLASS_8_BITS = { |
| 66 | PixelFormat::R8UI, | 60 | PixelFormat::R8_UINT, |
| 67 | PixelFormat::R8U, | 61 | PixelFormat::R8_UNORM, |
| 62 | PixelFormat::R8_SINT, | ||
| 63 | PixelFormat::R8_SNORM, | ||
| 68 | }; | 64 | }; |
| 69 | // Missing formats: | ||
| 70 | // PixelFormat::R8I | ||
| 71 | // PixelFormat::R8S | ||
| 72 | 65 | ||
| 73 | constexpr std::array VIEW_CLASS_RGTC1_RED = { | 66 | constexpr std::array VIEW_CLASS_RGTC1_RED = { |
| 74 | PixelFormat::DXN1, | 67 | PixelFormat::BC4_UNORM, |
| 68 | PixelFormat::BC4_SNORM, | ||
| 75 | }; | 69 | }; |
| 76 | // Missing formats: | ||
| 77 | // COMPRESSED_SIGNED_RED_RGTC1 | ||
| 78 | 70 | ||
| 79 | constexpr std::array VIEW_CLASS_RGTC2_RG = { | 71 | constexpr std::array VIEW_CLASS_RGTC2_RG = { |
| 80 | PixelFormat::DXN2UNORM, | 72 | PixelFormat::BC5_UNORM, |
| 81 | PixelFormat::DXN2SNORM, | 73 | PixelFormat::BC5_SNORM, |
| 82 | }; | 74 | }; |
| 83 | 75 | ||
| 84 | constexpr std::array VIEW_CLASS_BPTC_UNORM = { | 76 | constexpr std::array VIEW_CLASS_BPTC_UNORM = { |
| 85 | PixelFormat::BC7U, | 77 | PixelFormat::BC7_UNORM, |
| 86 | PixelFormat::BC7U_SRGB, | 78 | PixelFormat::BC7_SRGB, |
| 87 | }; | 79 | }; |
| 88 | 80 | ||
| 89 | constexpr std::array VIEW_CLASS_BPTC_FLOAT = { | 81 | constexpr std::array VIEW_CLASS_BPTC_FLOAT = { |
| 90 | PixelFormat::BC6H_SF16, | 82 | PixelFormat::BC6H_SFLOAT, |
| 91 | PixelFormat::BC6H_UF16, | 83 | PixelFormat::BC6H_UFLOAT, |
| 92 | }; | 84 | }; |
| 93 | 85 | ||
| 94 | // Compatibility table taken from Table 4.X.1 in: | 86 | // Compatibility table taken from Table 4.X.1 in: |
| 95 | // https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_copy_image.txt | 87 | // https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_copy_image.txt |
| 96 | 88 | ||
| 97 | constexpr std::array COPY_CLASS_128_BITS = { | 89 | constexpr std::array COPY_CLASS_128_BITS = { |
| 98 | PixelFormat::RGBA32UI, PixelFormat::RGBA32F, PixelFormat::DXT23, | 90 | PixelFormat::R32G32B32A32_UINT, PixelFormat::R32G32B32A32_FLOAT, PixelFormat::R32G32B32A32_SINT, |
| 99 | PixelFormat::DXT23_SRGB, PixelFormat::DXT45, PixelFormat::DXT45_SRGB, | 91 | PixelFormat::BC2_UNORM, PixelFormat::BC2_SRGB, PixelFormat::BC3_UNORM, |
| 100 | PixelFormat::DXN2SNORM, PixelFormat::BC7U, PixelFormat::BC7U_SRGB, | 92 | PixelFormat::BC3_SRGB, PixelFormat::BC5_UNORM, PixelFormat::BC5_SNORM, |
| 101 | PixelFormat::BC6H_SF16, PixelFormat::BC6H_UF16, | 93 | PixelFormat::BC7_UNORM, PixelFormat::BC7_SRGB, PixelFormat::BC6H_SFLOAT, |
| 94 | PixelFormat::BC6H_UFLOAT, | ||
| 102 | }; | 95 | }; |
| 103 | // Missing formats: | 96 | // Missing formats: |
| 104 | // PixelFormat::RGBA32I | 97 | // PixelFormat::RGBA32I |
| 105 | // COMPRESSED_RG_RGTC2 | 98 | // COMPRESSED_RG_RGTC2 |
| 106 | 99 | ||
| 107 | constexpr std::array COPY_CLASS_64_BITS = { | 100 | constexpr std::array COPY_CLASS_64_BITS = { |
| 108 | PixelFormat::RGBA16F, PixelFormat::RG32F, PixelFormat::RGBA16UI, PixelFormat::RG32UI, | 101 | PixelFormat::R16G16B16A16_FLOAT, PixelFormat::R16G16B16A16_UINT, |
| 109 | PixelFormat::RGBA16U, PixelFormat::RGBA16S, PixelFormat::DXT1_SRGB, PixelFormat::DXT1, | 102 | PixelFormat::R16G16B16A16_UNORM, PixelFormat::R16G16B16A16_SNORM, |
| 110 | 103 | PixelFormat::R16G16B16A16_SINT, PixelFormat::R32G32_UINT, | |
| 104 | PixelFormat::R32G32_FLOAT, PixelFormat::R32G32_SINT, | ||
| 105 | PixelFormat::BC1_RGBA_UNORM, PixelFormat::BC1_RGBA_SRGB, | ||
| 111 | }; | 106 | }; |
| 112 | // Missing formats: | 107 | // Missing formats: |
| 113 | // PixelFormat::RGBA16I | ||
| 114 | // PixelFormat::RG32I, | ||
| 115 | // COMPRESSED_RGB_S3TC_DXT1_EXT | 108 | // COMPRESSED_RGB_S3TC_DXT1_EXT |
| 116 | // COMPRESSED_SRGB_S3TC_DXT1_EXT | 109 | // COMPRESSED_SRGB_S3TC_DXT1_EXT |
| 117 | // COMPRESSED_RGBA_S3TC_DXT1_EXT | 110 | // COMPRESSED_RGBA_S3TC_DXT1_EXT |
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index 8d04d9fd9..19a34c402 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h | |||
| @@ -40,53 +40,61 @@ namespace Tegra { | |||
| 40 | 40 | ||
| 41 | enum class RenderTargetFormat : u32 { | 41 | enum class RenderTargetFormat : u32 { |
| 42 | NONE = 0x0, | 42 | NONE = 0x0, |
| 43 | RGBA32_FLOAT = 0xC0, | 43 | R32B32G32A32_FLOAT = 0xC0, |
| 44 | RGBA32_UINT = 0xC2, | 44 | R32G32B32A32_SINT = 0xC1, |
| 45 | RGBA16_UNORM = 0xC6, | 45 | R32G32B32A32_UINT = 0xC2, |
| 46 | RGBA16_SNORM = 0xC7, | 46 | R16G16B16A16_UNORM = 0xC6, |
| 47 | RGBA16_UINT = 0xC9, | 47 | R16G16B16A16_SNORM = 0xC7, |
| 48 | RGBA16_FLOAT = 0xCA, | 48 | R16G16B16A16_SINT = 0xC8, |
| 49 | RG32_FLOAT = 0xCB, | 49 | R16G16B16A16_UINT = 0xC9, |
| 50 | RG32_UINT = 0xCD, | 50 | R16G16B16A16_FLOAT = 0xCA, |
| 51 | RGBX16_FLOAT = 0xCE, | 51 | R32G32_FLOAT = 0xCB, |
| 52 | BGRA8_UNORM = 0xCF, | 52 | R32G32_SINT = 0xCC, |
| 53 | BGRA8_SRGB = 0xD0, | 53 | R32G32_UINT = 0xCD, |
| 54 | RGB10_A2_UNORM = 0xD1, | 54 | R16G16B16X16_FLOAT = 0xCE, |
| 55 | RGBA8_UNORM = 0xD5, | 55 | B8G8R8A8_UNORM = 0xCF, |
| 56 | RGBA8_SRGB = 0xD6, | 56 | B8G8R8A8_SRGB = 0xD0, |
| 57 | RGBA8_SNORM = 0xD7, | 57 | A2B10G10R10_UNORM = 0xD1, |
| 58 | RGBA8_UINT = 0xD9, | 58 | A2B10G10R10_UINT = 0xD2, |
| 59 | RG16_UNORM = 0xDA, | 59 | A8B8G8R8_UNORM = 0xD5, |
| 60 | RG16_SNORM = 0xDB, | 60 | A8B8G8R8_SRGB = 0xD6, |
| 61 | RG16_SINT = 0xDC, | 61 | A8B8G8R8_SNORM = 0xD7, |
| 62 | RG16_UINT = 0xDD, | 62 | A8B8G8R8_SINT = 0xD8, |
| 63 | RG16_FLOAT = 0xDE, | 63 | A8B8G8R8_UINT = 0xD9, |
| 64 | R11G11B10_FLOAT = 0xE0, | 64 | R16G16_UNORM = 0xDA, |
| 65 | R16G16_SNORM = 0xDB, | ||
| 66 | R16G16_SINT = 0xDC, | ||
| 67 | R16G16_UINT = 0xDD, | ||
| 68 | R16G16_FLOAT = 0xDE, | ||
| 69 | B10G11R11_FLOAT = 0xE0, | ||
| 65 | R32_SINT = 0xE3, | 70 | R32_SINT = 0xE3, |
| 66 | R32_UINT = 0xE4, | 71 | R32_UINT = 0xE4, |
| 67 | R32_FLOAT = 0xE5, | 72 | R32_FLOAT = 0xE5, |
| 68 | B5G6R5_UNORM = 0xE8, | 73 | R5G6B5_UNORM = 0xE8, |
| 69 | BGR5A1_UNORM = 0xE9, | 74 | A1R5G5B5_UNORM = 0xE9, |
| 70 | RG8_UNORM = 0xEA, | 75 | R8G8_UNORM = 0xEA, |
| 71 | RG8_SNORM = 0xEB, | 76 | R8G8_SNORM = 0xEB, |
| 72 | RG8_UINT = 0xED, | 77 | R8G8_SINT = 0xEC, |
| 78 | R8G8_UINT = 0xED, | ||
| 73 | R16_UNORM = 0xEE, | 79 | R16_UNORM = 0xEE, |
| 74 | R16_SNORM = 0xEF, | 80 | R16_SNORM = 0xEF, |
| 75 | R16_SINT = 0xF0, | 81 | R16_SINT = 0xF0, |
| 76 | R16_UINT = 0xF1, | 82 | R16_UINT = 0xF1, |
| 77 | R16_FLOAT = 0xF2, | 83 | R16_FLOAT = 0xF2, |
| 78 | R8_UNORM = 0xF3, | 84 | R8_UNORM = 0xF3, |
| 85 | R8_SNORM = 0xF4, | ||
| 86 | R8_SINT = 0xF5, | ||
| 79 | R8_UINT = 0xF6, | 87 | R8_UINT = 0xF6, |
| 80 | }; | 88 | }; |
| 81 | 89 | ||
| 82 | enum class DepthFormat : u32 { | 90 | enum class DepthFormat : u32 { |
| 83 | Z32_FLOAT = 0xA, | 91 | D32_FLOAT = 0xA, |
| 84 | Z16_UNORM = 0x13, | 92 | D16_UNORM = 0x13, |
| 85 | S8_Z24_UNORM = 0x14, | 93 | S8_UINT_Z24_UNORM = 0x14, |
| 86 | Z24_X8_UNORM = 0x15, | 94 | D24X8_UNORM = 0x15, |
| 87 | Z24_S8_UNORM = 0x16, | 95 | D24S8_UNORM = 0x16, |
| 88 | Z24_C8_UNORM = 0x18, | 96 | D24C8_UNORM = 0x18, |
| 89 | Z32_S8_X24_FLOAT = 0x19, | 97 | D32_FLOAT_S8X24_UINT = 0x19, |
| 90 | }; | 98 | }; |
| 91 | 99 | ||
| 92 | struct CommandListHeader; | 100 | struct CommandListHeader; |
| @@ -97,9 +105,9 @@ class DebugContext; | |||
| 97 | */ | 105 | */ |
| 98 | struct FramebufferConfig { | 106 | struct FramebufferConfig { |
| 99 | enum class PixelFormat : u32 { | 107 | enum class PixelFormat : u32 { |
| 100 | ABGR8 = 1, | 108 | A8B8G8R8_UNORM = 1, |
| 101 | RGB565 = 4, | 109 | RGB565_UNORM = 4, |
| 102 | BGRA8 = 5, | 110 | B8G8R8A8_UNORM = 5, |
| 103 | }; | 111 | }; |
| 104 | 112 | ||
| 105 | VAddr address; | 113 | VAddr address; |
diff --git a/src/video_core/gpu_thread.cpp b/src/video_core/gpu_thread.cpp index 738c6f0c1..bf761abf2 100644 --- a/src/video_core/gpu_thread.cpp +++ b/src/video_core/gpu_thread.cpp | |||
| @@ -44,9 +44,9 @@ static void RunThread(Core::System& system, VideoCore::RendererBase& renderer, | |||
| 44 | dma_pusher.DispatchCalls(); | 44 | dma_pusher.DispatchCalls(); |
| 45 | } else if (const auto data = std::get_if<SwapBuffersCommand>(&next.data)) { | 45 | } else if (const auto data = std::get_if<SwapBuffersCommand>(&next.data)) { |
| 46 | renderer.SwapBuffers(data->framebuffer ? &*data->framebuffer : nullptr); | 46 | renderer.SwapBuffers(data->framebuffer ? &*data->framebuffer : nullptr); |
| 47 | } else if (const auto data = std::get_if<OnCommandListEndCommand>(&next.data)) { | 47 | } else if (std::holds_alternative<OnCommandListEndCommand>(next.data)) { |
| 48 | renderer.Rasterizer().ReleaseFences(); | 48 | renderer.Rasterizer().ReleaseFences(); |
| 49 | } else if (const auto data = std::get_if<GPUTickCommand>(&next.data)) { | 49 | } else if (std::holds_alternative<GPUTickCommand>(next.data)) { |
| 50 | system.GPU().TickWork(); | 50 | system.GPU().TickWork(); |
| 51 | } else if (const auto data = std::get_if<FlushRegionCommand>(&next.data)) { | 51 | } else if (const auto data = std::get_if<FlushRegionCommand>(&next.data)) { |
| 52 | renderer.Rasterizer().FlushRegion(data->addr, data->size); | 52 | renderer.Rasterizer().FlushRegion(data->addr, data->size); |
diff --git a/src/video_core/macro/macro_jit_x64.cpp b/src/video_core/macro/macro_jit_x64.cpp index 07292702f..c1b9e4ad9 100644 --- a/src/video_core/macro/macro_jit_x64.cpp +++ b/src/video_core/macro/macro_jit_x64.cpp | |||
| @@ -419,7 +419,6 @@ void Tegra::MacroJITx64Impl::Optimizer_ScanFlags() { | |||
| 419 | 419 | ||
| 420 | void MacroJITx64Impl::Compile() { | 420 | void MacroJITx64Impl::Compile() { |
| 421 | MICROPROFILE_SCOPE(MacroJitCompile); | 421 | MICROPROFILE_SCOPE(MacroJitCompile); |
| 422 | bool keep_executing = true; | ||
| 423 | labels.fill(Xbyak::Label()); | 422 | labels.fill(Xbyak::Label()); |
| 424 | 423 | ||
| 425 | Common::X64::ABI_PushRegistersAndAdjustStack(*this, Common::X64::ABI_ALL_CALLEE_SAVED, 8); | 424 | Common::X64::ABI_PushRegistersAndAdjustStack(*this, Common::X64::ABI_ALL_CALLEE_SAVED, 8); |
diff --git a/src/video_core/morton.cpp b/src/video_core/morton.cpp index 836b25c1d..9da9fb4ff 100644 --- a/src/video_core/morton.cpp +++ b/src/video_core/morton.cpp | |||
| @@ -41,146 +41,168 @@ static void MortonCopy(u32 stride, u32 block_height, u32 height, u32 block_depth | |||
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | static constexpr ConversionArray morton_to_linear_fns = { | 43 | static constexpr ConversionArray morton_to_linear_fns = { |
| 44 | MortonCopy<true, PixelFormat::ABGR8U>, | 44 | MortonCopy<true, PixelFormat::A8B8G8R8_UNORM>, |
| 45 | MortonCopy<true, PixelFormat::ABGR8S>, | 45 | MortonCopy<true, PixelFormat::A8B8G8R8_SNORM>, |
| 46 | MortonCopy<true, PixelFormat::ABGR8UI>, | 46 | MortonCopy<true, PixelFormat::A8B8G8R8_SINT>, |
| 47 | MortonCopy<true, PixelFormat::B5G6R5U>, | 47 | MortonCopy<true, PixelFormat::A8B8G8R8_UINT>, |
| 48 | MortonCopy<true, PixelFormat::A2B10G10R10U>, | 48 | MortonCopy<true, PixelFormat::R5G6B5_UNORM>, |
| 49 | MortonCopy<true, PixelFormat::A1B5G5R5U>, | 49 | MortonCopy<true, PixelFormat::B5G6R5_UNORM>, |
| 50 | MortonCopy<true, PixelFormat::R8U>, | 50 | MortonCopy<true, PixelFormat::A1R5G5B5_UNORM>, |
| 51 | MortonCopy<true, PixelFormat::R8UI>, | 51 | MortonCopy<true, PixelFormat::A2B10G10R10_UNORM>, |
| 52 | MortonCopy<true, PixelFormat::RGBA16F>, | 52 | MortonCopy<true, PixelFormat::A2B10G10R10_UINT>, |
| 53 | MortonCopy<true, PixelFormat::RGBA16U>, | 53 | MortonCopy<true, PixelFormat::A1B5G5R5_UNORM>, |
| 54 | MortonCopy<true, PixelFormat::RGBA16S>, | 54 | MortonCopy<true, PixelFormat::R8_UNORM>, |
| 55 | MortonCopy<true, PixelFormat::RGBA16UI>, | 55 | MortonCopy<true, PixelFormat::R8_SNORM>, |
| 56 | MortonCopy<true, PixelFormat::R11FG11FB10F>, | 56 | MortonCopy<true, PixelFormat::R8_SINT>, |
| 57 | MortonCopy<true, PixelFormat::RGBA32UI>, | 57 | MortonCopy<true, PixelFormat::R8_UINT>, |
| 58 | MortonCopy<true, PixelFormat::DXT1>, | 58 | MortonCopy<true, PixelFormat::R16G16B16A16_FLOAT>, |
| 59 | MortonCopy<true, PixelFormat::DXT23>, | 59 | MortonCopy<true, PixelFormat::R16G16B16A16_UNORM>, |
| 60 | MortonCopy<true, PixelFormat::DXT45>, | 60 | MortonCopy<true, PixelFormat::R16G16B16A16_SNORM>, |
| 61 | MortonCopy<true, PixelFormat::DXN1>, | 61 | MortonCopy<true, PixelFormat::R16G16B16A16_SINT>, |
| 62 | MortonCopy<true, PixelFormat::DXN2UNORM>, | 62 | MortonCopy<true, PixelFormat::R16G16B16A16_UINT>, |
| 63 | MortonCopy<true, PixelFormat::DXN2SNORM>, | 63 | MortonCopy<true, PixelFormat::B10G11R11_FLOAT>, |
| 64 | MortonCopy<true, PixelFormat::BC7U>, | 64 | MortonCopy<true, PixelFormat::R32G32B32A32_UINT>, |
| 65 | MortonCopy<true, PixelFormat::BC6H_UF16>, | 65 | MortonCopy<true, PixelFormat::BC1_RGBA_UNORM>, |
| 66 | MortonCopy<true, PixelFormat::BC6H_SF16>, | 66 | MortonCopy<true, PixelFormat::BC2_UNORM>, |
| 67 | MortonCopy<true, PixelFormat::ASTC_2D_4X4>, | 67 | MortonCopy<true, PixelFormat::BC3_UNORM>, |
| 68 | MortonCopy<true, PixelFormat::BGRA8>, | 68 | MortonCopy<true, PixelFormat::BC4_UNORM>, |
| 69 | MortonCopy<true, PixelFormat::RGBA32F>, | 69 | MortonCopy<true, PixelFormat::BC4_SNORM>, |
| 70 | MortonCopy<true, PixelFormat::RG32F>, | 70 | MortonCopy<true, PixelFormat::BC5_UNORM>, |
| 71 | MortonCopy<true, PixelFormat::R32F>, | 71 | MortonCopy<true, PixelFormat::BC5_SNORM>, |
| 72 | MortonCopy<true, PixelFormat::R16F>, | 72 | MortonCopy<true, PixelFormat::BC7_UNORM>, |
| 73 | MortonCopy<true, PixelFormat::R16U>, | 73 | MortonCopy<true, PixelFormat::BC6H_UFLOAT>, |
| 74 | MortonCopy<true, PixelFormat::R16S>, | 74 | MortonCopy<true, PixelFormat::BC6H_SFLOAT>, |
| 75 | MortonCopy<true, PixelFormat::R16UI>, | 75 | MortonCopy<true, PixelFormat::ASTC_2D_4X4_UNORM>, |
| 76 | MortonCopy<true, PixelFormat::R16I>, | 76 | MortonCopy<true, PixelFormat::B8G8R8A8_UNORM>, |
| 77 | MortonCopy<true, PixelFormat::RG16>, | 77 | MortonCopy<true, PixelFormat::R32G32B32A32_FLOAT>, |
| 78 | MortonCopy<true, PixelFormat::RG16F>, | 78 | MortonCopy<true, PixelFormat::R32G32B32A32_SINT>, |
| 79 | MortonCopy<true, PixelFormat::RG16UI>, | 79 | MortonCopy<true, PixelFormat::R32G32_FLOAT>, |
| 80 | MortonCopy<true, PixelFormat::RG16I>, | 80 | MortonCopy<true, PixelFormat::R32G32_SINT>, |
| 81 | MortonCopy<true, PixelFormat::RG16S>, | 81 | MortonCopy<true, PixelFormat::R32_FLOAT>, |
| 82 | MortonCopy<true, PixelFormat::RGB32F>, | 82 | MortonCopy<true, PixelFormat::R16_FLOAT>, |
| 83 | MortonCopy<true, PixelFormat::RGBA8_SRGB>, | 83 | MortonCopy<true, PixelFormat::R16_UNORM>, |
| 84 | MortonCopy<true, PixelFormat::RG8U>, | 84 | MortonCopy<true, PixelFormat::R16_SNORM>, |
| 85 | MortonCopy<true, PixelFormat::RG8S>, | 85 | MortonCopy<true, PixelFormat::R16_UINT>, |
| 86 | MortonCopy<true, PixelFormat::RG8UI>, | 86 | MortonCopy<true, PixelFormat::R16_SINT>, |
| 87 | MortonCopy<true, PixelFormat::RG32UI>, | 87 | MortonCopy<true, PixelFormat::R16G16_UNORM>, |
| 88 | MortonCopy<true, PixelFormat::RGBX16F>, | 88 | MortonCopy<true, PixelFormat::R16G16_FLOAT>, |
| 89 | MortonCopy<true, PixelFormat::R32UI>, | 89 | MortonCopy<true, PixelFormat::R16G16_UINT>, |
| 90 | MortonCopy<true, PixelFormat::R32I>, | 90 | MortonCopy<true, PixelFormat::R16G16_SINT>, |
| 91 | MortonCopy<true, PixelFormat::ASTC_2D_8X8>, | 91 | MortonCopy<true, PixelFormat::R16G16_SNORM>, |
| 92 | MortonCopy<true, PixelFormat::ASTC_2D_8X5>, | 92 | MortonCopy<true, PixelFormat::R32G32B32_FLOAT>, |
| 93 | MortonCopy<true, PixelFormat::ASTC_2D_5X4>, | 93 | MortonCopy<true, PixelFormat::A8B8G8R8_SRGB>, |
| 94 | MortonCopy<true, PixelFormat::BGRA8_SRGB>, | 94 | MortonCopy<true, PixelFormat::R8G8_UNORM>, |
| 95 | MortonCopy<true, PixelFormat::DXT1_SRGB>, | 95 | MortonCopy<true, PixelFormat::R8G8_SNORM>, |
| 96 | MortonCopy<true, PixelFormat::DXT23_SRGB>, | 96 | MortonCopy<true, PixelFormat::R8G8_SINT>, |
| 97 | MortonCopy<true, PixelFormat::DXT45_SRGB>, | 97 | MortonCopy<true, PixelFormat::R8G8_UINT>, |
| 98 | MortonCopy<true, PixelFormat::BC7U_SRGB>, | 98 | MortonCopy<true, PixelFormat::R32G32_UINT>, |
| 99 | MortonCopy<true, PixelFormat::R4G4B4A4U>, | 99 | MortonCopy<true, PixelFormat::R16G16B16X16_FLOAT>, |
| 100 | MortonCopy<true, PixelFormat::R32_UINT>, | ||
| 101 | MortonCopy<true, PixelFormat::R32_SINT>, | ||
| 102 | MortonCopy<true, PixelFormat::ASTC_2D_8X8_UNORM>, | ||
| 103 | MortonCopy<true, PixelFormat::ASTC_2D_8X5_UNORM>, | ||
| 104 | MortonCopy<true, PixelFormat::ASTC_2D_5X4_UNORM>, | ||
| 105 | MortonCopy<true, PixelFormat::B8G8R8A8_SRGB>, | ||
| 106 | MortonCopy<true, PixelFormat::BC1_RGBA_SRGB>, | ||
| 107 | MortonCopy<true, PixelFormat::BC2_SRGB>, | ||
| 108 | MortonCopy<true, PixelFormat::BC3_SRGB>, | ||
| 109 | MortonCopy<true, PixelFormat::BC7_SRGB>, | ||
| 110 | MortonCopy<true, PixelFormat::A4B4G4R4_UNORM>, | ||
| 100 | MortonCopy<true, PixelFormat::ASTC_2D_4X4_SRGB>, | 111 | MortonCopy<true, PixelFormat::ASTC_2D_4X4_SRGB>, |
| 101 | MortonCopy<true, PixelFormat::ASTC_2D_8X8_SRGB>, | 112 | MortonCopy<true, PixelFormat::ASTC_2D_8X8_SRGB>, |
| 102 | MortonCopy<true, PixelFormat::ASTC_2D_8X5_SRGB>, | 113 | MortonCopy<true, PixelFormat::ASTC_2D_8X5_SRGB>, |
| 103 | MortonCopy<true, PixelFormat::ASTC_2D_5X4_SRGB>, | 114 | MortonCopy<true, PixelFormat::ASTC_2D_5X4_SRGB>, |
| 104 | MortonCopy<true, PixelFormat::ASTC_2D_5X5>, | 115 | MortonCopy<true, PixelFormat::ASTC_2D_5X5_UNORM>, |
| 105 | MortonCopy<true, PixelFormat::ASTC_2D_5X5_SRGB>, | 116 | MortonCopy<true, PixelFormat::ASTC_2D_5X5_SRGB>, |
| 106 | MortonCopy<true, PixelFormat::ASTC_2D_10X8>, | 117 | MortonCopy<true, PixelFormat::ASTC_2D_10X8_UNORM>, |
| 107 | MortonCopy<true, PixelFormat::ASTC_2D_10X8_SRGB>, | 118 | MortonCopy<true, PixelFormat::ASTC_2D_10X8_SRGB>, |
| 108 | MortonCopy<true, PixelFormat::ASTC_2D_6X6>, | 119 | MortonCopy<true, PixelFormat::ASTC_2D_6X6_UNORM>, |
| 109 | MortonCopy<true, PixelFormat::ASTC_2D_6X6_SRGB>, | 120 | MortonCopy<true, PixelFormat::ASTC_2D_6X6_SRGB>, |
| 110 | MortonCopy<true, PixelFormat::ASTC_2D_10X10>, | 121 | MortonCopy<true, PixelFormat::ASTC_2D_10X10_UNORM>, |
| 111 | MortonCopy<true, PixelFormat::ASTC_2D_10X10_SRGB>, | 122 | MortonCopy<true, PixelFormat::ASTC_2D_10X10_SRGB>, |
| 112 | MortonCopy<true, PixelFormat::ASTC_2D_12X12>, | 123 | MortonCopy<true, PixelFormat::ASTC_2D_12X12_UNORM>, |
| 113 | MortonCopy<true, PixelFormat::ASTC_2D_12X12_SRGB>, | 124 | MortonCopy<true, PixelFormat::ASTC_2D_12X12_SRGB>, |
| 114 | MortonCopy<true, PixelFormat::ASTC_2D_8X6>, | 125 | MortonCopy<true, PixelFormat::ASTC_2D_8X6_UNORM>, |
| 115 | MortonCopy<true, PixelFormat::ASTC_2D_8X6_SRGB>, | 126 | MortonCopy<true, PixelFormat::ASTC_2D_8X6_SRGB>, |
| 116 | MortonCopy<true, PixelFormat::ASTC_2D_6X5>, | 127 | MortonCopy<true, PixelFormat::ASTC_2D_6X5_UNORM>, |
| 117 | MortonCopy<true, PixelFormat::ASTC_2D_6X5_SRGB>, | 128 | MortonCopy<true, PixelFormat::ASTC_2D_6X5_SRGB>, |
| 118 | MortonCopy<true, PixelFormat::E5B9G9R9F>, | 129 | MortonCopy<true, PixelFormat::E5B9G9R9_FLOAT>, |
| 119 | MortonCopy<true, PixelFormat::Z32F>, | 130 | MortonCopy<true, PixelFormat::D32_FLOAT>, |
| 120 | MortonCopy<true, PixelFormat::Z16>, | 131 | MortonCopy<true, PixelFormat::D16_UNORM>, |
| 121 | MortonCopy<true, PixelFormat::Z24S8>, | 132 | MortonCopy<true, PixelFormat::D24_UNORM_S8_UINT>, |
| 122 | MortonCopy<true, PixelFormat::S8Z24>, | 133 | MortonCopy<true, PixelFormat::S8_UINT_D24_UNORM>, |
| 123 | MortonCopy<true, PixelFormat::Z32FS8>, | 134 | MortonCopy<true, PixelFormat::D32_FLOAT_S8_UINT>, |
| 124 | }; | 135 | }; |
| 125 | 136 | ||
| 126 | static constexpr ConversionArray linear_to_morton_fns = { | 137 | static constexpr ConversionArray linear_to_morton_fns = { |
| 127 | MortonCopy<false, PixelFormat::ABGR8U>, | 138 | MortonCopy<false, PixelFormat::A8B8G8R8_UNORM>, |
| 128 | MortonCopy<false, PixelFormat::ABGR8S>, | 139 | MortonCopy<false, PixelFormat::A8B8G8R8_SNORM>, |
| 129 | MortonCopy<false, PixelFormat::ABGR8UI>, | 140 | MortonCopy<false, PixelFormat::A8B8G8R8_SINT>, |
| 130 | MortonCopy<false, PixelFormat::B5G6R5U>, | 141 | MortonCopy<false, PixelFormat::A8B8G8R8_UINT>, |
| 131 | MortonCopy<false, PixelFormat::A2B10G10R10U>, | 142 | MortonCopy<false, PixelFormat::R5G6B5_UNORM>, |
| 132 | MortonCopy<false, PixelFormat::A1B5G5R5U>, | 143 | MortonCopy<false, PixelFormat::B5G6R5_UNORM>, |
| 133 | MortonCopy<false, PixelFormat::R8U>, | 144 | MortonCopy<false, PixelFormat::A1R5G5B5_UNORM>, |
| 134 | MortonCopy<false, PixelFormat::R8UI>, | 145 | MortonCopy<false, PixelFormat::A2B10G10R10_UNORM>, |
| 135 | MortonCopy<false, PixelFormat::RGBA16F>, | 146 | MortonCopy<false, PixelFormat::A2B10G10R10_UINT>, |
| 136 | MortonCopy<false, PixelFormat::RGBA16S>, | 147 | MortonCopy<false, PixelFormat::A1B5G5R5_UNORM>, |
| 137 | MortonCopy<false, PixelFormat::RGBA16U>, | 148 | MortonCopy<false, PixelFormat::R8_UNORM>, |
| 138 | MortonCopy<false, PixelFormat::RGBA16UI>, | 149 | MortonCopy<false, PixelFormat::R8_SNORM>, |
| 139 | MortonCopy<false, PixelFormat::R11FG11FB10F>, | 150 | MortonCopy<false, PixelFormat::R8_SINT>, |
| 140 | MortonCopy<false, PixelFormat::RGBA32UI>, | 151 | MortonCopy<false, PixelFormat::R8_UINT>, |
| 141 | MortonCopy<false, PixelFormat::DXT1>, | 152 | MortonCopy<false, PixelFormat::R16G16B16A16_FLOAT>, |
| 142 | MortonCopy<false, PixelFormat::DXT23>, | 153 | MortonCopy<false, PixelFormat::R16G16B16A16_SNORM>, |
| 143 | MortonCopy<false, PixelFormat::DXT45>, | 154 | MortonCopy<false, PixelFormat::R16G16B16A16_SINT>, |
| 144 | MortonCopy<false, PixelFormat::DXN1>, | 155 | MortonCopy<false, PixelFormat::R16G16B16A16_UNORM>, |
| 145 | MortonCopy<false, PixelFormat::DXN2UNORM>, | 156 | MortonCopy<false, PixelFormat::R16G16B16A16_UINT>, |
| 146 | MortonCopy<false, PixelFormat::DXN2SNORM>, | 157 | MortonCopy<false, PixelFormat::B10G11R11_FLOAT>, |
| 147 | MortonCopy<false, PixelFormat::BC7U>, | 158 | MortonCopy<false, PixelFormat::R32G32B32A32_UINT>, |
| 148 | MortonCopy<false, PixelFormat::BC6H_UF16>, | 159 | MortonCopy<false, PixelFormat::BC1_RGBA_UNORM>, |
| 149 | MortonCopy<false, PixelFormat::BC6H_SF16>, | 160 | MortonCopy<false, PixelFormat::BC2_UNORM>, |
| 161 | MortonCopy<false, PixelFormat::BC3_UNORM>, | ||
| 162 | MortonCopy<false, PixelFormat::BC4_UNORM>, | ||
| 163 | MortonCopy<false, PixelFormat::BC4_SNORM>, | ||
| 164 | MortonCopy<false, PixelFormat::BC5_UNORM>, | ||
| 165 | MortonCopy<false, PixelFormat::BC5_SNORM>, | ||
| 166 | MortonCopy<false, PixelFormat::BC7_UNORM>, | ||
| 167 | MortonCopy<false, PixelFormat::BC6H_UFLOAT>, | ||
| 168 | MortonCopy<false, PixelFormat::BC6H_SFLOAT>, | ||
| 150 | // TODO(Subv): Swizzling ASTC formats are not supported | 169 | // TODO(Subv): Swizzling ASTC formats are not supported |
| 151 | nullptr, | 170 | nullptr, |
| 152 | MortonCopy<false, PixelFormat::BGRA8>, | 171 | MortonCopy<false, PixelFormat::B8G8R8A8_UNORM>, |
| 153 | MortonCopy<false, PixelFormat::RGBA32F>, | 172 | MortonCopy<false, PixelFormat::R32G32B32A32_FLOAT>, |
| 154 | MortonCopy<false, PixelFormat::RG32F>, | 173 | MortonCopy<false, PixelFormat::R32G32B32A32_SINT>, |
| 155 | MortonCopy<false, PixelFormat::R32F>, | 174 | MortonCopy<false, PixelFormat::R32G32_FLOAT>, |
| 156 | MortonCopy<false, PixelFormat::R16F>, | 175 | MortonCopy<false, PixelFormat::R32G32_SINT>, |
| 157 | MortonCopy<false, PixelFormat::R16U>, | 176 | MortonCopy<false, PixelFormat::R32_FLOAT>, |
| 158 | MortonCopy<false, PixelFormat::R16S>, | 177 | MortonCopy<false, PixelFormat::R16_FLOAT>, |
| 159 | MortonCopy<false, PixelFormat::R16UI>, | 178 | MortonCopy<false, PixelFormat::R16_UNORM>, |
| 160 | MortonCopy<false, PixelFormat::R16I>, | 179 | MortonCopy<false, PixelFormat::R16_SNORM>, |
| 161 | MortonCopy<false, PixelFormat::RG16>, | 180 | MortonCopy<false, PixelFormat::R16_UINT>, |
| 162 | MortonCopy<false, PixelFormat::RG16F>, | 181 | MortonCopy<false, PixelFormat::R16_SINT>, |
| 163 | MortonCopy<false, PixelFormat::RG16UI>, | 182 | MortonCopy<false, PixelFormat::R16G16_UNORM>, |
| 164 | MortonCopy<false, PixelFormat::RG16I>, | 183 | MortonCopy<false, PixelFormat::R16G16_FLOAT>, |
| 165 | MortonCopy<false, PixelFormat::RG16S>, | 184 | MortonCopy<false, PixelFormat::R16G16_UINT>, |
| 166 | MortonCopy<false, PixelFormat::RGB32F>, | 185 | MortonCopy<false, PixelFormat::R16G16_SINT>, |
| 167 | MortonCopy<false, PixelFormat::RGBA8_SRGB>, | 186 | MortonCopy<false, PixelFormat::R16G16_SNORM>, |
| 168 | MortonCopy<false, PixelFormat::RG8U>, | 187 | MortonCopy<false, PixelFormat::R32G32B32_FLOAT>, |
| 169 | MortonCopy<false, PixelFormat::RG8S>, | 188 | MortonCopy<false, PixelFormat::A8B8G8R8_SRGB>, |
| 170 | MortonCopy<false, PixelFormat::RG8UI>, | 189 | MortonCopy<false, PixelFormat::R8G8_UNORM>, |
| 171 | MortonCopy<false, PixelFormat::RG32UI>, | 190 | MortonCopy<false, PixelFormat::R8G8_SNORM>, |
| 172 | MortonCopy<false, PixelFormat::RGBX16F>, | 191 | MortonCopy<false, PixelFormat::R8G8_SINT>, |
| 173 | MortonCopy<false, PixelFormat::R32UI>, | 192 | MortonCopy<false, PixelFormat::R8G8_UINT>, |
| 174 | MortonCopy<false, PixelFormat::R32I>, | 193 | MortonCopy<false, PixelFormat::R32G32_UINT>, |
| 194 | MortonCopy<false, PixelFormat::R16G16B16X16_FLOAT>, | ||
| 195 | MortonCopy<false, PixelFormat::R32_UINT>, | ||
| 196 | MortonCopy<false, PixelFormat::R32_SINT>, | ||
| 175 | nullptr, | 197 | nullptr, |
| 176 | nullptr, | 198 | nullptr, |
| 177 | nullptr, | 199 | nullptr, |
| 178 | MortonCopy<false, PixelFormat::BGRA8_SRGB>, | 200 | MortonCopy<false, PixelFormat::B8G8R8A8_SRGB>, |
| 179 | MortonCopy<false, PixelFormat::DXT1_SRGB>, | 201 | MortonCopy<false, PixelFormat::BC1_RGBA_SRGB>, |
| 180 | MortonCopy<false, PixelFormat::DXT23_SRGB>, | 202 | MortonCopy<false, PixelFormat::BC2_SRGB>, |
| 181 | MortonCopy<false, PixelFormat::DXT45_SRGB>, | 203 | MortonCopy<false, PixelFormat::BC3_SRGB>, |
| 182 | MortonCopy<false, PixelFormat::BC7U_SRGB>, | 204 | MortonCopy<false, PixelFormat::BC7_SRGB>, |
| 183 | MortonCopy<false, PixelFormat::R4G4B4A4U>, | 205 | MortonCopy<false, PixelFormat::A4B4G4R4_UNORM>, |
| 184 | nullptr, | 206 | nullptr, |
| 185 | nullptr, | 207 | nullptr, |
| 186 | nullptr, | 208 | nullptr, |
| @@ -199,12 +221,12 @@ static constexpr ConversionArray linear_to_morton_fns = { | |||
| 199 | nullptr, | 221 | nullptr, |
| 200 | nullptr, | 222 | nullptr, |
| 201 | nullptr, | 223 | nullptr, |
| 202 | MortonCopy<false, PixelFormat::E5B9G9R9F>, | 224 | MortonCopy<false, PixelFormat::E5B9G9R9_FLOAT>, |
| 203 | MortonCopy<false, PixelFormat::Z32F>, | 225 | MortonCopy<false, PixelFormat::D32_FLOAT>, |
| 204 | MortonCopy<false, PixelFormat::Z16>, | 226 | MortonCopy<false, PixelFormat::D16_UNORM>, |
| 205 | MortonCopy<false, PixelFormat::Z24S8>, | 227 | MortonCopy<false, PixelFormat::D24_UNORM_S8_UINT>, |
| 206 | MortonCopy<false, PixelFormat::S8Z24>, | 228 | MortonCopy<false, PixelFormat::S8_UINT_D24_UNORM>, |
| 207 | MortonCopy<false, PixelFormat::Z32FS8>, | 229 | MortonCopy<false, PixelFormat::D32_FLOAT_S8_UINT>, |
| 208 | }; | 230 | }; |
| 209 | 231 | ||
| 210 | static MortonCopyFn GetSwizzleFunction(MortonSwizzleMode mode, Surface::PixelFormat format) { | 232 | static MortonCopyFn GetSwizzleFunction(MortonSwizzleMode mode, Surface::PixelFormat format) { |
diff --git a/src/video_core/renderer_opengl/gl_arb_decompiler.cpp b/src/video_core/renderer_opengl/gl_arb_decompiler.cpp index 7c8d0ef65..b7e9ed2e9 100644 --- a/src/video_core/renderer_opengl/gl_arb_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_arb_decompiler.cpp | |||
| @@ -185,10 +185,6 @@ std::string TextureType(const MetaTexture& meta) { | |||
| 185 | return type; | 185 | return type; |
| 186 | } | 186 | } |
| 187 | 187 | ||
| 188 | std::string GlobalMemoryName(const GlobalMemoryBase& base) { | ||
| 189 | return fmt::format("gmem{}_{}", base.cbuf_index, base.cbuf_offset); | ||
| 190 | } | ||
| 191 | |||
| 192 | class ARBDecompiler final { | 188 | class ARBDecompiler final { |
| 193 | public: | 189 | public: |
| 194 | explicit ARBDecompiler(const Device& device, const ShaderIR& ir, const Registry& registry, | 190 | explicit ARBDecompiler(const Device& device, const ShaderIR& ir, const Registry& registry, |
| @@ -199,6 +195,8 @@ public: | |||
| 199 | } | 195 | } |
| 200 | 196 | ||
| 201 | private: | 197 | private: |
| 198 | void DefineGlobalMemory(); | ||
| 199 | |||
| 202 | void DeclareHeader(); | 200 | void DeclareHeader(); |
| 203 | void DeclareVertex(); | 201 | void DeclareVertex(); |
| 204 | void DeclareGeometry(); | 202 | void DeclareGeometry(); |
| @@ -228,6 +226,7 @@ private: | |||
| 228 | 226 | ||
| 229 | std::pair<std::string, std::size_t> BuildCoords(Operation); | 227 | std::pair<std::string, std::size_t> BuildCoords(Operation); |
| 230 | std::string BuildAoffi(Operation); | 228 | std::string BuildAoffi(Operation); |
| 229 | std::string GlobalMemoryPointer(const GmemNode& gmem); | ||
| 231 | void Exit(); | 230 | void Exit(); |
| 232 | 231 | ||
| 233 | std::string Assign(Operation); | 232 | std::string Assign(Operation); |
| @@ -378,10 +377,8 @@ private: | |||
| 378 | std::string address; | 377 | std::string address; |
| 379 | std::string_view opname; | 378 | std::string_view opname; |
| 380 | if (const auto gmem = std::get_if<GmemNode>(&*operation[0])) { | 379 | if (const auto gmem = std::get_if<GmemNode>(&*operation[0])) { |
| 381 | AddLine("SUB.U {}, {}, {};", temporary, Visit(gmem->GetRealAddress()), | 380 | address = GlobalMemoryPointer(*gmem); |
| 382 | Visit(gmem->GetBaseAddress())); | 381 | opname = "ATOM"; |
| 383 | address = fmt::format("{}[{}]", GlobalMemoryName(gmem->GetDescriptor()), temporary); | ||
| 384 | opname = "ATOMB"; | ||
| 385 | } else if (const auto smem = std::get_if<SmemNode>(&*operation[0])) { | 382 | } else if (const auto smem = std::get_if<SmemNode>(&*operation[0])) { |
| 386 | address = fmt::format("shared_mem[{}]", Visit(smem->GetAddress())); | 383 | address = fmt::format("shared_mem[{}]", Visit(smem->GetAddress())); |
| 387 | opname = "ATOMS"; | 384 | opname = "ATOMS"; |
| @@ -456,9 +453,13 @@ private: | |||
| 456 | shader_source += '\n'; | 453 | shader_source += '\n'; |
| 457 | } | 454 | } |
| 458 | 455 | ||
| 459 | std::string AllocTemporary() { | 456 | std::string AllocLongVectorTemporary() { |
| 460 | max_temporaries = std::max(max_temporaries, num_temporaries + 1); | 457 | max_long_temporaries = std::max(max_long_temporaries, num_long_temporaries + 1); |
| 461 | return fmt::format("T{}.x", num_temporaries++); | 458 | return fmt::format("L{}", num_long_temporaries++); |
| 459 | } | ||
| 460 | |||
| 461 | std::string AllocLongTemporary() { | ||
| 462 | return fmt::format("{}.x", AllocLongVectorTemporary()); | ||
| 462 | } | 463 | } |
| 463 | 464 | ||
| 464 | std::string AllocVectorTemporary() { | 465 | std::string AllocVectorTemporary() { |
| @@ -466,8 +467,13 @@ private: | |||
| 466 | return fmt::format("T{}", num_temporaries++); | 467 | return fmt::format("T{}", num_temporaries++); |
| 467 | } | 468 | } |
| 468 | 469 | ||
| 470 | std::string AllocTemporary() { | ||
| 471 | return fmt::format("{}.x", AllocVectorTemporary()); | ||
| 472 | } | ||
| 473 | |||
| 469 | void ResetTemporaries() noexcept { | 474 | void ResetTemporaries() noexcept { |
| 470 | num_temporaries = 0; | 475 | num_temporaries = 0; |
| 476 | num_long_temporaries = 0; | ||
| 471 | } | 477 | } |
| 472 | 478 | ||
| 473 | const Device& device; | 479 | const Device& device; |
| @@ -478,6 +484,11 @@ private: | |||
| 478 | std::size_t num_temporaries = 0; | 484 | std::size_t num_temporaries = 0; |
| 479 | std::size_t max_temporaries = 0; | 485 | std::size_t max_temporaries = 0; |
| 480 | 486 | ||
| 487 | std::size_t num_long_temporaries = 0; | ||
| 488 | std::size_t max_long_temporaries = 0; | ||
| 489 | |||
| 490 | std::map<GlobalMemoryBase, u32> global_memory_names; | ||
| 491 | |||
| 481 | std::string shader_source; | 492 | std::string shader_source; |
| 482 | 493 | ||
| 483 | static constexpr std::string_view ADD_F32 = "ADD.F32"; | 494 | static constexpr std::string_view ADD_F32 = "ADD.F32"; |
| @@ -784,6 +795,8 @@ private: | |||
| 784 | ARBDecompiler::ARBDecompiler(const Device& device, const ShaderIR& ir, const Registry& registry, | 795 | ARBDecompiler::ARBDecompiler(const Device& device, const ShaderIR& ir, const Registry& registry, |
| 785 | ShaderType stage, std::string_view identifier) | 796 | ShaderType stage, std::string_view identifier) |
| 786 | : device{device}, ir{ir}, registry{registry}, stage{stage} { | 797 | : device{device}, ir{ir}, registry{registry}, stage{stage} { |
| 798 | DefineGlobalMemory(); | ||
| 799 | |||
| 787 | AddLine("TEMP RC;"); | 800 | AddLine("TEMP RC;"); |
| 788 | AddLine("TEMP FSWZA[4];"); | 801 | AddLine("TEMP FSWZA[4];"); |
| 789 | AddLine("TEMP FSWZB[4];"); | 802 | AddLine("TEMP FSWZB[4];"); |
| @@ -829,12 +842,20 @@ std::string_view HeaderStageName(ShaderType stage) { | |||
| 829 | } | 842 | } |
| 830 | } | 843 | } |
| 831 | 844 | ||
| 845 | void ARBDecompiler::DefineGlobalMemory() { | ||
| 846 | u32 binding = 0; | ||
| 847 | for (const auto& pair : ir.GetGlobalMemory()) { | ||
| 848 | const GlobalMemoryBase base = pair.first; | ||
| 849 | global_memory_names.emplace(base, binding); | ||
| 850 | ++binding; | ||
| 851 | } | ||
| 852 | } | ||
| 853 | |||
| 832 | void ARBDecompiler::DeclareHeader() { | 854 | void ARBDecompiler::DeclareHeader() { |
| 833 | AddLine("!!NV{}5.0", HeaderStageName(stage)); | 855 | AddLine("!!NV{}5.0", HeaderStageName(stage)); |
| 834 | // Enabling this allows us to cheat on some instructions like TXL with SHADOWARRAY2D | 856 | // Enabling this allows us to cheat on some instructions like TXL with SHADOWARRAY2D |
| 835 | AddLine("OPTION NV_internal;"); | 857 | AddLine("OPTION NV_internal;"); |
| 836 | AddLine("OPTION NV_gpu_program_fp64;"); | 858 | AddLine("OPTION NV_gpu_program_fp64;"); |
| 837 | AddLine("OPTION NV_shader_storage_buffer;"); | ||
| 838 | AddLine("OPTION NV_shader_thread_group;"); | 859 | AddLine("OPTION NV_shader_thread_group;"); |
| 839 | if (ir.UsesWarps() && device.HasWarpIntrinsics()) { | 860 | if (ir.UsesWarps() && device.HasWarpIntrinsics()) { |
| 840 | AddLine("OPTION NV_shader_thread_shuffle;"); | 861 | AddLine("OPTION NV_shader_thread_shuffle;"); |
| @@ -892,11 +913,19 @@ void ARBDecompiler::DeclareCompute() { | |||
| 892 | const ComputeInfo& info = registry.GetComputeInfo(); | 913 | const ComputeInfo& info = registry.GetComputeInfo(); |
| 893 | AddLine("GROUP_SIZE {} {} {};", info.workgroup_size[0], info.workgroup_size[1], | 914 | AddLine("GROUP_SIZE {} {} {};", info.workgroup_size[0], info.workgroup_size[1], |
| 894 | info.workgroup_size[2]); | 915 | info.workgroup_size[2]); |
| 895 | if (info.shared_memory_size_in_words > 0) { | 916 | if (info.shared_memory_size_in_words == 0) { |
| 896 | const u32 size_in_bytes = info.shared_memory_size_in_words * 4; | 917 | return; |
| 897 | AddLine("SHARED_MEMORY {};", size_in_bytes); | ||
| 898 | AddLine("SHARED shared_mem[] = {{program.sharedmem}};"); | ||
| 899 | } | 918 | } |
| 919 | const u32 limit = device.GetMaxComputeSharedMemorySize(); | ||
| 920 | u32 size_in_bytes = info.shared_memory_size_in_words * 4; | ||
| 921 | if (size_in_bytes > limit) { | ||
| 922 | LOG_ERROR(Render_OpenGL, "Shared memory size {} is clamped to host's limit {}", | ||
| 923 | size_in_bytes, limit); | ||
| 924 | size_in_bytes = limit; | ||
| 925 | } | ||
| 926 | |||
| 927 | AddLine("SHARED_MEMORY {};", size_in_bytes); | ||
| 928 | AddLine("SHARED shared_mem[] = {{program.sharedmem}};"); | ||
| 900 | } | 929 | } |
| 901 | 930 | ||
| 902 | void ARBDecompiler::DeclareInputAttributes() { | 931 | void ARBDecompiler::DeclareInputAttributes() { |
| @@ -951,11 +980,10 @@ void ARBDecompiler::DeclareLocalMemory() { | |||
| 951 | } | 980 | } |
| 952 | 981 | ||
| 953 | void ARBDecompiler::DeclareGlobalMemory() { | 982 | void ARBDecompiler::DeclareGlobalMemory() { |
| 954 | u32 binding = 0; // device.GetBaseBindings(stage).shader_storage_buffer; | 983 | const std::size_t num_entries = ir.GetGlobalMemory().size(); |
| 955 | for (const auto& pair : ir.GetGlobalMemory()) { | 984 | if (num_entries > 0) { |
| 956 | const auto& base = pair.first; | 985 | const std::size_t num_vectors = Common::AlignUp(num_entries, 2) / 2; |
| 957 | AddLine("STORAGE {}[] = {{ program.storage[{}] }};", GlobalMemoryName(base), binding); | 986 | AddLine("PARAM c[{}] = {{ program.local[0..{}] }};", num_vectors, num_vectors - 1); |
| 958 | ++binding; | ||
| 959 | } | 987 | } |
| 960 | } | 988 | } |
| 961 | 989 | ||
| @@ -977,6 +1005,9 @@ void ARBDecompiler::DeclareTemporaries() { | |||
| 977 | for (std::size_t i = 0; i < max_temporaries; ++i) { | 1005 | for (std::size_t i = 0; i < max_temporaries; ++i) { |
| 978 | AddLine("TEMP T{};", i); | 1006 | AddLine("TEMP T{};", i); |
| 979 | } | 1007 | } |
| 1008 | for (std::size_t i = 0; i < max_long_temporaries; ++i) { | ||
| 1009 | AddLine("LONG TEMP L{};", i); | ||
| 1010 | } | ||
| 980 | } | 1011 | } |
| 981 | 1012 | ||
| 982 | void ARBDecompiler::DeclarePredicates() { | 1013 | void ARBDecompiler::DeclarePredicates() { |
| @@ -1260,13 +1291,6 @@ std::string ARBDecompiler::Visit(const Node& node) { | |||
| 1260 | return "{0, 0, 0, 0}.x"; | 1291 | return "{0, 0, 0, 0}.x"; |
| 1261 | } | 1292 | } |
| 1262 | 1293 | ||
| 1263 | const auto buffer_index = [this, &abuf]() -> std::string { | ||
| 1264 | if (stage != ShaderType::Geometry) { | ||
| 1265 | return ""; | ||
| 1266 | } | ||
| 1267 | return fmt::format("[{}]", Visit(abuf->GetBuffer())); | ||
| 1268 | }; | ||
| 1269 | |||
| 1270 | const Attribute::Index index = abuf->GetIndex(); | 1294 | const Attribute::Index index = abuf->GetIndex(); |
| 1271 | const u32 element = abuf->GetElement(); | 1295 | const u32 element = abuf->GetElement(); |
| 1272 | const char swizzle = Swizzle(element); | 1296 | const char swizzle = Swizzle(element); |
| @@ -1339,10 +1363,7 @@ std::string ARBDecompiler::Visit(const Node& node) { | |||
| 1339 | 1363 | ||
| 1340 | if (const auto gmem = std::get_if<GmemNode>(&*node)) { | 1364 | if (const auto gmem = std::get_if<GmemNode>(&*node)) { |
| 1341 | std::string temporary = AllocTemporary(); | 1365 | std::string temporary = AllocTemporary(); |
| 1342 | AddLine("SUB.U {}, {}, {};", temporary, Visit(gmem->GetRealAddress()), | 1366 | AddLine("LOAD.U32 {}, {};", temporary, GlobalMemoryPointer(*gmem)); |
| 1343 | Visit(gmem->GetBaseAddress())); | ||
| 1344 | AddLine("LDB.U32 {}, {}[{}];", temporary, GlobalMemoryName(gmem->GetDescriptor()), | ||
| 1345 | temporary); | ||
| 1346 | return temporary; | 1367 | return temporary; |
| 1347 | } | 1368 | } |
| 1348 | 1369 | ||
| @@ -1375,7 +1396,7 @@ std::string ARBDecompiler::Visit(const Node& node) { | |||
| 1375 | return {}; | 1396 | return {}; |
| 1376 | } | 1397 | } |
| 1377 | 1398 | ||
| 1378 | if (const auto cmt = std::get_if<CommentNode>(&*node)) { | 1399 | if ([[maybe_unused]] const auto cmt = std::get_if<CommentNode>(&*node)) { |
| 1379 | // Uncommenting this will generate invalid code. GLASM lacks comments. | 1400 | // Uncommenting this will generate invalid code. GLASM lacks comments. |
| 1380 | // AddLine("// {}", cmt->GetText()); | 1401 | // AddLine("// {}", cmt->GetText()); |
| 1381 | return {}; | 1402 | return {}; |
| @@ -1419,6 +1440,22 @@ std::string ARBDecompiler::BuildAoffi(Operation operation) { | |||
| 1419 | return fmt::format(", offset({})", temporary); | 1440 | return fmt::format(", offset({})", temporary); |
| 1420 | } | 1441 | } |
| 1421 | 1442 | ||
| 1443 | std::string ARBDecompiler::GlobalMemoryPointer(const GmemNode& gmem) { | ||
| 1444 | const u32 binding = global_memory_names.at(gmem.GetDescriptor()); | ||
| 1445 | const char result_swizzle = binding % 2 == 0 ? 'x' : 'y'; | ||
| 1446 | |||
| 1447 | const std::string pointer = AllocLongVectorTemporary(); | ||
| 1448 | std::string temporary = AllocTemporary(); | ||
| 1449 | |||
| 1450 | const u32 local_index = binding / 2; | ||
| 1451 | AddLine("PK64.U {}, c[{}];", pointer, local_index); | ||
| 1452 | AddLine("SUB.U {}, {}, {};", temporary, Visit(gmem.GetRealAddress()), | ||
| 1453 | Visit(gmem.GetBaseAddress())); | ||
| 1454 | AddLine("CVT.U64.U32 {}.z, {};", pointer, temporary); | ||
| 1455 | AddLine("ADD.U64 {}.x, {}.{}, {}.z;", pointer, pointer, result_swizzle, pointer); | ||
| 1456 | return fmt::format("{}.x", pointer); | ||
| 1457 | } | ||
| 1458 | |||
| 1422 | void ARBDecompiler::Exit() { | 1459 | void ARBDecompiler::Exit() { |
| 1423 | if (stage != ShaderType::Fragment) { | 1460 | if (stage != ShaderType::Fragment) { |
| 1424 | AddLine("RET;"); | 1461 | AddLine("RET;"); |
| @@ -1515,11 +1552,7 @@ std::string ARBDecompiler::Assign(Operation operation) { | |||
| 1515 | ResetTemporaries(); | 1552 | ResetTemporaries(); |
| 1516 | return {}; | 1553 | return {}; |
| 1517 | } else if (const auto gmem = std::get_if<GmemNode>(&*dest)) { | 1554 | } else if (const auto gmem = std::get_if<GmemNode>(&*dest)) { |
| 1518 | const std::string temporary = AllocTemporary(); | 1555 | AddLine("STORE.U32 {}, {};", Visit(src), GlobalMemoryPointer(*gmem)); |
| 1519 | AddLine("SUB.U {}, {}, {};", temporary, Visit(gmem->GetRealAddress()), | ||
| 1520 | Visit(gmem->GetBaseAddress())); | ||
| 1521 | AddLine("STB.U32 {}, {}[{}];", Visit(src), GlobalMemoryName(gmem->GetDescriptor()), | ||
| 1522 | temporary); | ||
| 1523 | ResetTemporaries(); | 1556 | ResetTemporaries(); |
| 1524 | return {}; | 1557 | return {}; |
| 1525 | } else { | 1558 | } else { |
| @@ -2044,10 +2077,6 @@ std::string ARBDecompiler::ShuffleIndexed(Operation operation) { | |||
| 2044 | } | 2077 | } |
| 2045 | 2078 | ||
| 2046 | std::string ARBDecompiler::Barrier(Operation) { | 2079 | std::string ARBDecompiler::Barrier(Operation) { |
| 2047 | if (!ir.IsDecompiled()) { | ||
| 2048 | LOG_ERROR(Render_OpenGL, "BAR used but shader is not decompiled"); | ||
| 2049 | return {}; | ||
| 2050 | } | ||
| 2051 | AddLine("BAR;"); | 2080 | AddLine("BAR;"); |
| 2052 | return {}; | 2081 | return {}; |
| 2053 | } | 2082 | } |
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.cpp b/src/video_core/renderer_opengl/gl_buffer_cache.cpp index e461e4c70..e866d8f2f 100644 --- a/src/video_core/renderer_opengl/gl_buffer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_buffer_cache.cpp | |||
| @@ -26,7 +26,7 @@ Buffer::Buffer(const Device& device, VAddr cpu_addr, std::size_t size) | |||
| 26 | : VideoCommon::BufferBlock{cpu_addr, size} { | 26 | : VideoCommon::BufferBlock{cpu_addr, size} { |
| 27 | gl_buffer.Create(); | 27 | gl_buffer.Create(); |
| 28 | glNamedBufferData(gl_buffer.handle, static_cast<GLsizeiptr>(size), nullptr, GL_DYNAMIC_DRAW); | 28 | glNamedBufferData(gl_buffer.handle, static_cast<GLsizeiptr>(size), nullptr, GL_DYNAMIC_DRAW); |
| 29 | if (device.HasVertexBufferUnifiedMemory()) { | 29 | if (device.UseAssemblyShaders() || device.HasVertexBufferUnifiedMemory()) { |
| 30 | glMakeNamedBufferResidentNV(gl_buffer.handle, GL_READ_WRITE); | 30 | glMakeNamedBufferResidentNV(gl_buffer.handle, GL_READ_WRITE); |
| 31 | glGetNamedBufferParameterui64vNV(gl_buffer.handle, GL_BUFFER_GPU_ADDRESS_NV, &gpu_address); | 31 | glGetNamedBufferParameterui64vNV(gl_buffer.handle, GL_BUFFER_GPU_ADDRESS_NV, &gpu_address); |
| 32 | } | 32 | } |
diff --git a/src/video_core/renderer_opengl/gl_device.cpp b/src/video_core/renderer_opengl/gl_device.cpp index 630acb73b..e7d95149f 100644 --- a/src/video_core/renderer_opengl/gl_device.cpp +++ b/src/video_core/renderer_opengl/gl_device.cpp | |||
| @@ -212,6 +212,7 @@ Device::Device() | |||
| 212 | shader_storage_alignment = GetInteger<std::size_t>(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT); | 212 | shader_storage_alignment = GetInteger<std::size_t>(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT); |
| 213 | max_vertex_attributes = GetInteger<u32>(GL_MAX_VERTEX_ATTRIBS); | 213 | max_vertex_attributes = GetInteger<u32>(GL_MAX_VERTEX_ATTRIBS); |
| 214 | max_varyings = GetInteger<u32>(GL_MAX_VARYING_VECTORS); | 214 | max_varyings = GetInteger<u32>(GL_MAX_VARYING_VECTORS); |
| 215 | max_compute_shared_memory_size = GetInteger<u32>(GL_MAX_COMPUTE_SHARED_MEMORY_SIZE); | ||
| 215 | has_warp_intrinsics = GLAD_GL_NV_gpu_shader5 && GLAD_GL_NV_shader_thread_group && | 216 | has_warp_intrinsics = GLAD_GL_NV_gpu_shader5 && GLAD_GL_NV_shader_thread_group && |
| 216 | GLAD_GL_NV_shader_thread_shuffle; | 217 | GLAD_GL_NV_shader_thread_shuffle; |
| 217 | has_shader_ballot = GLAD_GL_ARB_shader_ballot; | 218 | has_shader_ballot = GLAD_GL_ARB_shader_ballot; |
| @@ -250,6 +251,7 @@ Device::Device(std::nullptr_t) { | |||
| 250 | shader_storage_alignment = 4; | 251 | shader_storage_alignment = 4; |
| 251 | max_vertex_attributes = 16; | 252 | max_vertex_attributes = 16; |
| 252 | max_varyings = 15; | 253 | max_varyings = 15; |
| 254 | max_compute_shared_memory_size = 0x10000; | ||
| 253 | has_warp_intrinsics = true; | 255 | has_warp_intrinsics = true; |
| 254 | has_shader_ballot = true; | 256 | has_shader_ballot = true; |
| 255 | has_vertex_viewport_layer = true; | 257 | has_vertex_viewport_layer = true; |
diff --git a/src/video_core/renderer_opengl/gl_device.h b/src/video_core/renderer_opengl/gl_device.h index 94d38d7d1..8a4b6b9fc 100644 --- a/src/video_core/renderer_opengl/gl_device.h +++ b/src/video_core/renderer_opengl/gl_device.h | |||
| @@ -52,6 +52,10 @@ public: | |||
| 52 | return max_varyings; | 52 | return max_varyings; |
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | u32 GetMaxComputeSharedMemorySize() const { | ||
| 56 | return max_compute_shared_memory_size; | ||
| 57 | } | ||
| 58 | |||
| 55 | bool HasWarpIntrinsics() const { | 59 | bool HasWarpIntrinsics() const { |
| 56 | return has_warp_intrinsics; | 60 | return has_warp_intrinsics; |
| 57 | } | 61 | } |
| @@ -118,6 +122,7 @@ private: | |||
| 118 | std::size_t shader_storage_alignment{}; | 122 | std::size_t shader_storage_alignment{}; |
| 119 | u32 max_vertex_attributes{}; | 123 | u32 max_vertex_attributes{}; |
| 120 | u32 max_varyings{}; | 124 | u32 max_varyings{}; |
| 125 | u32 max_compute_shared_memory_size{}; | ||
| 121 | bool has_warp_intrinsics{}; | 126 | bool has_warp_intrinsics{}; |
| 122 | bool has_shader_ballot{}; | 127 | bool has_shader_ballot{}; |
| 123 | bool has_vertex_viewport_layer{}; | 128 | bool has_vertex_viewport_layer{}; |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index c3fad563c..03e82c599 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -139,6 +139,18 @@ void oglEnable(GLenum cap, bool state) { | |||
| 139 | (state ? glEnable : glDisable)(cap); | 139 | (state ? glEnable : glDisable)(cap); |
| 140 | } | 140 | } |
| 141 | 141 | ||
| 142 | void UpdateBindlessPointers(GLenum target, GLuint64EXT* pointers, std::size_t num_entries) { | ||
| 143 | if (num_entries == 0) { | ||
| 144 | return; | ||
| 145 | } | ||
| 146 | if (num_entries % 2 == 1) { | ||
| 147 | pointers[num_entries] = 0; | ||
| 148 | } | ||
| 149 | const GLsizei num_vectors = static_cast<GLsizei>((num_entries + 1) / 2); | ||
| 150 | glProgramLocalParametersI4uivNV(target, 0, num_vectors, | ||
| 151 | reinterpret_cast<const GLuint*>(pointers)); | ||
| 152 | } | ||
| 153 | |||
| 142 | } // Anonymous namespace | 154 | } // Anonymous namespace |
| 143 | 155 | ||
| 144 | RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window, | 156 | RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window, |
| @@ -324,7 +336,6 @@ GLintptr RasterizerOpenGL::SetupIndexBuffer() { | |||
| 324 | void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) { | 336 | void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) { |
| 325 | MICROPROFILE_SCOPE(OpenGL_Shader); | 337 | MICROPROFILE_SCOPE(OpenGL_Shader); |
| 326 | auto& gpu = system.GPU().Maxwell3D(); | 338 | auto& gpu = system.GPU().Maxwell3D(); |
| 327 | std::size_t num_ssbos = 0; | ||
| 328 | u32 clip_distances = 0; | 339 | u32 clip_distances = 0; |
| 329 | 340 | ||
| 330 | for (std::size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) { | 341 | for (std::size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) { |
| @@ -347,29 +358,13 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) { | |||
| 347 | } | 358 | } |
| 348 | 359 | ||
| 349 | // Currently this stages are not supported in the OpenGL backend. | 360 | // Currently this stages are not supported in the OpenGL backend. |
| 350 | // Todo(Blinkhawk): Port tesselation shaders from Vulkan to OpenGL | 361 | // TODO(Blinkhawk): Port tesselation shaders from Vulkan to OpenGL |
| 351 | if (program == Maxwell::ShaderProgram::TesselationControl) { | 362 | if (program == Maxwell::ShaderProgram::TesselationControl || |
| 363 | program == Maxwell::ShaderProgram::TesselationEval) { | ||
| 352 | continue; | 364 | continue; |
| 353 | } else if (program == Maxwell::ShaderProgram::TesselationEval) { | ||
| 354 | continue; | ||
| 355 | } | ||
| 356 | |||
| 357 | Shader* shader = shader_cache.GetStageProgram(program, async_shaders); | ||
| 358 | |||
| 359 | if (device.UseAssemblyShaders()) { | ||
| 360 | // Check for ARB limitation. We only have 16 SSBOs per context state. To workaround this | ||
| 361 | // all stages share the same bindings. | ||
| 362 | const std::size_t num_stage_ssbos = shader->GetEntries().global_memory_entries.size(); | ||
| 363 | ASSERT_MSG(num_stage_ssbos == 0 || num_ssbos == 0, "SSBOs on more than one stage"); | ||
| 364 | num_ssbos += num_stage_ssbos; | ||
| 365 | } | 365 | } |
| 366 | 366 | ||
| 367 | // Stage indices are 0 - 5 | 367 | Shader* const shader = shader_cache.GetStageProgram(program, async_shaders); |
| 368 | const std::size_t stage = index == 0 ? 0 : index - 1; | ||
| 369 | SetupDrawConstBuffers(stage, shader); | ||
| 370 | SetupDrawGlobalMemory(stage, shader); | ||
| 371 | SetupDrawTextures(stage, shader); | ||
| 372 | SetupDrawImages(stage, shader); | ||
| 373 | 368 | ||
| 374 | const GLuint program_handle = shader->IsBuilt() ? shader->GetHandle() : 0; | 369 | const GLuint program_handle = shader->IsBuilt() ? shader->GetHandle() : 0; |
| 375 | switch (program) { | 370 | switch (program) { |
| @@ -388,6 +383,13 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) { | |||
| 388 | shader_config.enable.Value(), shader_config.offset); | 383 | shader_config.enable.Value(), shader_config.offset); |
| 389 | } | 384 | } |
| 390 | 385 | ||
| 386 | // Stage indices are 0 - 5 | ||
| 387 | const std::size_t stage = index == 0 ? 0 : index - 1; | ||
| 388 | SetupDrawConstBuffers(stage, shader); | ||
| 389 | SetupDrawGlobalMemory(stage, shader); | ||
| 390 | SetupDrawTextures(stage, shader); | ||
| 391 | SetupDrawImages(stage, shader); | ||
| 392 | |||
| 391 | // Workaround for Intel drivers. | 393 | // Workaround for Intel drivers. |
| 392 | // When a clip distance is enabled but not set in the shader it crops parts of the screen | 394 | // When a clip distance is enabled but not set in the shader it crops parts of the screen |
| 393 | // (sometimes it's half the screen, sometimes three quarters). To avoid this, enable the | 395 | // (sometimes it's half the screen, sometimes three quarters). To avoid this, enable the |
| @@ -749,6 +751,8 @@ void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) { | |||
| 749 | current_cbuf = 0; | 751 | current_cbuf = 0; |
| 750 | 752 | ||
| 751 | auto kernel = shader_cache.GetComputeKernel(code_addr); | 753 | auto kernel = shader_cache.GetComputeKernel(code_addr); |
| 754 | program_manager.BindCompute(kernel->GetHandle()); | ||
| 755 | |||
| 752 | SetupComputeTextures(kernel); | 756 | SetupComputeTextures(kernel); |
| 753 | SetupComputeImages(kernel); | 757 | SetupComputeImages(kernel); |
| 754 | 758 | ||
| @@ -763,7 +767,6 @@ void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) { | |||
| 763 | buffer_cache.Unmap(); | 767 | buffer_cache.Unmap(); |
| 764 | 768 | ||
| 765 | const auto& launch_desc = system.GPU().KeplerCompute().launch_description; | 769 | const auto& launch_desc = system.GPU().KeplerCompute().launch_description; |
| 766 | program_manager.BindCompute(kernel->GetHandle()); | ||
| 767 | glDispatchCompute(launch_desc.grid_dim_x, launch_desc.grid_dim_y, launch_desc.grid_dim_z); | 770 | glDispatchCompute(launch_desc.grid_dim_x, launch_desc.grid_dim_y, launch_desc.grid_dim_z); |
| 768 | ++num_queued_commands; | 771 | ++num_queued_commands; |
| 769 | } | 772 | } |
| @@ -1023,40 +1026,66 @@ void RasterizerOpenGL::SetupConstBuffer(GLenum stage, u32 binding, | |||
| 1023 | } | 1026 | } |
| 1024 | 1027 | ||
| 1025 | void RasterizerOpenGL::SetupDrawGlobalMemory(std::size_t stage_index, Shader* shader) { | 1028 | void RasterizerOpenGL::SetupDrawGlobalMemory(std::size_t stage_index, Shader* shader) { |
| 1029 | static constexpr std::array TARGET_LUT = { | ||
| 1030 | GL_VERTEX_PROGRAM_NV, GL_TESS_CONTROL_PROGRAM_NV, GL_TESS_EVALUATION_PROGRAM_NV, | ||
| 1031 | GL_GEOMETRY_PROGRAM_NV, GL_FRAGMENT_PROGRAM_NV, | ||
| 1032 | }; | ||
| 1033 | |||
| 1026 | auto& gpu{system.GPU()}; | 1034 | auto& gpu{system.GPU()}; |
| 1027 | auto& memory_manager{gpu.MemoryManager()}; | 1035 | auto& memory_manager{gpu.MemoryManager()}; |
| 1028 | const auto cbufs{gpu.Maxwell3D().state.shader_stages[stage_index]}; | 1036 | const auto& cbufs{gpu.Maxwell3D().state.shader_stages[stage_index]}; |
| 1037 | const auto& entries{shader->GetEntries().global_memory_entries}; | ||
| 1038 | |||
| 1039 | std::array<GLuint64EXT, 32> pointers; | ||
| 1040 | ASSERT(entries.size() < pointers.size()); | ||
| 1029 | 1041 | ||
| 1030 | u32 binding = | 1042 | const bool assembly_shaders = device.UseAssemblyShaders(); |
| 1031 | device.UseAssemblyShaders() ? 0 : device.GetBaseBindings(stage_index).shader_storage_buffer; | 1043 | u32 binding = assembly_shaders ? 0 : device.GetBaseBindings(stage_index).shader_storage_buffer; |
| 1032 | for (const auto& entry : shader->GetEntries().global_memory_entries) { | 1044 | for (const auto& entry : entries) { |
| 1033 | const GPUVAddr addr{cbufs.const_buffers[entry.cbuf_index].address + entry.cbuf_offset}; | 1045 | const GPUVAddr addr{cbufs.const_buffers[entry.cbuf_index].address + entry.cbuf_offset}; |
| 1034 | const GPUVAddr gpu_addr{memory_manager.Read<u64>(addr)}; | 1046 | const GPUVAddr gpu_addr{memory_manager.Read<u64>(addr)}; |
| 1035 | const u32 size{memory_manager.Read<u32>(addr + 8)}; | 1047 | const u32 size{memory_manager.Read<u32>(addr + 8)}; |
| 1036 | SetupGlobalMemory(binding++, entry, gpu_addr, size); | 1048 | SetupGlobalMemory(binding, entry, gpu_addr, size, &pointers[binding]); |
| 1049 | ++binding; | ||
| 1050 | } | ||
| 1051 | if (assembly_shaders) { | ||
| 1052 | UpdateBindlessPointers(TARGET_LUT[stage_index], pointers.data(), entries.size()); | ||
| 1037 | } | 1053 | } |
| 1038 | } | 1054 | } |
| 1039 | 1055 | ||
| 1040 | void RasterizerOpenGL::SetupComputeGlobalMemory(Shader* kernel) { | 1056 | void RasterizerOpenGL::SetupComputeGlobalMemory(Shader* kernel) { |
| 1041 | auto& gpu{system.GPU()}; | 1057 | auto& gpu{system.GPU()}; |
| 1042 | auto& memory_manager{gpu.MemoryManager()}; | 1058 | auto& memory_manager{gpu.MemoryManager()}; |
| 1043 | const auto cbufs{gpu.KeplerCompute().launch_description.const_buffer_config}; | 1059 | const auto& cbufs{gpu.KeplerCompute().launch_description.const_buffer_config}; |
| 1060 | const auto& entries{kernel->GetEntries().global_memory_entries}; | ||
| 1061 | |||
| 1062 | std::array<GLuint64EXT, 32> pointers; | ||
| 1063 | ASSERT(entries.size() < pointers.size()); | ||
| 1044 | 1064 | ||
| 1045 | u32 binding = 0; | 1065 | u32 binding = 0; |
| 1046 | for (const auto& entry : kernel->GetEntries().global_memory_entries) { | 1066 | for (const auto& entry : entries) { |
| 1047 | const auto addr{cbufs[entry.cbuf_index].Address() + entry.cbuf_offset}; | 1067 | const GPUVAddr addr{cbufs[entry.cbuf_index].Address() + entry.cbuf_offset}; |
| 1048 | const auto gpu_addr{memory_manager.Read<u64>(addr)}; | 1068 | const GPUVAddr gpu_addr{memory_manager.Read<u64>(addr)}; |
| 1049 | const auto size{memory_manager.Read<u32>(addr + 8)}; | 1069 | const u32 size{memory_manager.Read<u32>(addr + 8)}; |
| 1050 | SetupGlobalMemory(binding++, entry, gpu_addr, size); | 1070 | SetupGlobalMemory(binding, entry, gpu_addr, size, &pointers[binding]); |
| 1071 | ++binding; | ||
| 1072 | } | ||
| 1073 | if (device.UseAssemblyShaders()) { | ||
| 1074 | UpdateBindlessPointers(GL_COMPUTE_PROGRAM_NV, pointers.data(), entries.size()); | ||
| 1051 | } | 1075 | } |
| 1052 | } | 1076 | } |
| 1053 | 1077 | ||
| 1054 | void RasterizerOpenGL::SetupGlobalMemory(u32 binding, const GlobalMemoryEntry& entry, | 1078 | void RasterizerOpenGL::SetupGlobalMemory(u32 binding, const GlobalMemoryEntry& entry, |
| 1055 | GPUVAddr gpu_addr, std::size_t size) { | 1079 | GPUVAddr gpu_addr, std::size_t size, |
| 1056 | const auto alignment{device.GetShaderStorageBufferAlignment()}; | 1080 | GLuint64EXT* pointer) { |
| 1081 | const std::size_t alignment{device.GetShaderStorageBufferAlignment()}; | ||
| 1057 | const auto info = buffer_cache.UploadMemory(gpu_addr, size, alignment, entry.is_written); | 1082 | const auto info = buffer_cache.UploadMemory(gpu_addr, size, alignment, entry.is_written); |
| 1058 | glBindBufferRange(GL_SHADER_STORAGE_BUFFER, binding, info.handle, info.offset, | 1083 | if (device.UseAssemblyShaders()) { |
| 1059 | static_cast<GLsizeiptr>(size)); | 1084 | *pointer = info.address + info.offset; |
| 1085 | } else { | ||
| 1086 | glBindBufferRange(GL_SHADER_STORAGE_BUFFER, binding, info.handle, info.offset, | ||
| 1087 | static_cast<GLsizeiptr>(size)); | ||
| 1088 | } | ||
| 1060 | } | 1089 | } |
| 1061 | 1090 | ||
| 1062 | void RasterizerOpenGL::SetupDrawTextures(std::size_t stage_index, Shader* shader) { | 1091 | void RasterizerOpenGL::SetupDrawTextures(std::size_t stage_index, Shader* shader) { |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index a95646936..ccc6f50f6 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h | |||
| @@ -124,9 +124,9 @@ private: | |||
| 124 | /// Configures the current global memory entries to use for the kernel invocation. | 124 | /// Configures the current global memory entries to use for the kernel invocation. |
| 125 | void SetupComputeGlobalMemory(Shader* kernel); | 125 | void SetupComputeGlobalMemory(Shader* kernel); |
| 126 | 126 | ||
| 127 | /// Configures a constant buffer. | 127 | /// Configures a global memory buffer. |
| 128 | void SetupGlobalMemory(u32 binding, const GlobalMemoryEntry& entry, GPUVAddr gpu_addr, | 128 | void SetupGlobalMemory(u32 binding, const GlobalMemoryEntry& entry, GPUVAddr gpu_addr, |
| 129 | std::size_t size); | 129 | std::size_t size, GLuint64EXT* pointer); |
| 130 | 130 | ||
| 131 | /// Configures the current textures to use for the draw command. | 131 | /// Configures the current textures to use for the draw command. |
| 132 | void SetupDrawTextures(std::size_t stage_index, Shader* shader); | 132 | void SetupDrawTextures(std::size_t stage_index, Shader* shader); |
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index b52fa8b6a..be71e1733 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp | |||
| @@ -237,7 +237,6 @@ std::unique_ptr<Shader> Shader::CreateStageFromMemory( | |||
| 237 | const ShaderParameters& params, Maxwell::ShaderProgram program_type, ProgramCode code, | 237 | const ShaderParameters& params, Maxwell::ShaderProgram program_type, ProgramCode code, |
| 238 | ProgramCode code_b, VideoCommon::Shader::AsyncShaders& async_shaders, VAddr cpu_addr) { | 238 | ProgramCode code_b, VideoCommon::Shader::AsyncShaders& async_shaders, VAddr cpu_addr) { |
| 239 | const auto shader_type = GetShaderType(program_type); | 239 | const auto shader_type = GetShaderType(program_type); |
| 240 | const std::size_t size_in_bytes = code.size() * sizeof(u64); | ||
| 241 | 240 | ||
| 242 | auto& gpu = params.system.GPU(); | 241 | auto& gpu = params.system.GPU(); |
| 243 | gpu.ShaderNotify().MarkSharderBuilding(); | 242 | gpu.ShaderNotify().MarkSharderBuilding(); |
| @@ -287,8 +286,6 @@ std::unique_ptr<Shader> Shader::CreateStageFromMemory( | |||
| 287 | 286 | ||
| 288 | std::unique_ptr<Shader> Shader::CreateKernelFromMemory(const ShaderParameters& params, | 287 | std::unique_ptr<Shader> Shader::CreateKernelFromMemory(const ShaderParameters& params, |
| 289 | ProgramCode code) { | 288 | ProgramCode code) { |
| 290 | const std::size_t size_in_bytes = code.size() * sizeof(u64); | ||
| 291 | |||
| 292 | auto& gpu = params.system.GPU(); | 289 | auto& gpu = params.system.GPU(); |
| 293 | gpu.ShaderNotify().MarkSharderBuilding(); | 290 | gpu.ShaderNotify().MarkSharderBuilding(); |
| 294 | 291 | ||
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 71c29fff1..3f75fcd2b 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -602,8 +602,15 @@ private: | |||
| 602 | return; | 602 | return; |
| 603 | } | 603 | } |
| 604 | const auto& info = registry.GetComputeInfo(); | 604 | const auto& info = registry.GetComputeInfo(); |
| 605 | if (const u32 size = info.shared_memory_size_in_words; size > 0) { | 605 | if (u32 size = info.shared_memory_size_in_words * 4; size > 0) { |
| 606 | code.AddLine("shared uint smem[{}];", size); | 606 | const u32 limit = device.GetMaxComputeSharedMemorySize(); |
| 607 | if (size > limit) { | ||
| 608 | LOG_ERROR(Render_OpenGL, "Shared memory size {} is clamped to host's limit {}", | ||
| 609 | size, limit); | ||
| 610 | size = limit; | ||
| 611 | } | ||
| 612 | |||
| 613 | code.AddLine("shared uint smem[{}];", size / 4); | ||
| 607 | code.AddNewLine(); | 614 | code.AddNewLine(); |
| 608 | } | 615 | } |
| 609 | code.AddLine("layout (local_size_x = {}, local_size_y = {}, local_size_z = {}) in;", | 616 | code.AddLine("layout (local_size_x = {}, local_size_y = {}, local_size_z = {}) in;", |
| @@ -1952,10 +1959,6 @@ private: | |||
| 1952 | return {fmt::format("({} != 0)", carry), Type::Bool}; | 1959 | return {fmt::format("({} != 0)", carry), Type::Bool}; |
| 1953 | } | 1960 | } |
| 1954 | 1961 | ||
| 1955 | Expression LogicalFIsNan(Operation operation) { | ||
| 1956 | return GenerateUnary(operation, "isnan", Type::Bool, Type::Float); | ||
| 1957 | } | ||
| 1958 | |||
| 1959 | Expression LogicalAssign(Operation operation) { | 1962 | Expression LogicalAssign(Operation operation) { |
| 1960 | const Node& dest = operation[0]; | 1963 | const Node& dest = operation[0]; |
| 1961 | const Node& src = operation[1]; | 1964 | const Node& src = operation[1]; |
| @@ -2771,15 +2774,6 @@ private: | |||
| 2771 | return std::min<u32>(device.GetMaxVaryings(), Maxwell::NumVaryings); | 2774 | return std::min<u32>(device.GetMaxVaryings(), Maxwell::NumVaryings); |
| 2772 | } | 2775 | } |
| 2773 | 2776 | ||
| 2774 | bool IsRenderTargetEnabled(u32 render_target) const { | ||
| 2775 | for (u32 component = 0; component < 4; ++component) { | ||
| 2776 | if (header.ps.IsColorComponentOutputEnabled(render_target, component)) { | ||
| 2777 | return true; | ||
| 2778 | } | ||
| 2779 | } | ||
| 2780 | return false; | ||
| 2781 | } | ||
| 2782 | |||
| 2783 | const Device& device; | 2777 | const Device& device; |
| 2784 | const ShaderIR& ir; | 2778 | const ShaderIR& ir; |
| 2785 | const Registry& registry; | 2779 | const Registry& registry; |
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.cpp b/src/video_core/renderer_opengl/gl_shader_manager.cpp index 8e754fa90..691c6c79b 100644 --- a/src/video_core/renderer_opengl/gl_shader_manager.cpp +++ b/src/video_core/renderer_opengl/gl_shader_manager.cpp | |||
| @@ -11,8 +11,30 @@ | |||
| 11 | 11 | ||
| 12 | namespace OpenGL { | 12 | namespace OpenGL { |
| 13 | 13 | ||
| 14 | ProgramManager::ProgramManager(const Device& device) { | 14 | namespace { |
| 15 | use_assembly_programs = device.UseAssemblyShaders(); | 15 | |
| 16 | void BindProgram(GLenum stage, GLuint current, GLuint old, bool& enabled) { | ||
| 17 | if (current == old) { | ||
| 18 | return; | ||
| 19 | } | ||
| 20 | if (current == 0) { | ||
| 21 | if (enabled) { | ||
| 22 | enabled = false; | ||
| 23 | glDisable(stage); | ||
| 24 | } | ||
| 25 | return; | ||
| 26 | } | ||
| 27 | if (!enabled) { | ||
| 28 | enabled = true; | ||
| 29 | glEnable(stage); | ||
| 30 | } | ||
| 31 | glBindProgramARB(stage, current); | ||
| 32 | } | ||
| 33 | |||
| 34 | } // Anonymous namespace | ||
| 35 | |||
| 36 | ProgramManager::ProgramManager(const Device& device) | ||
| 37 | : use_assembly_programs{device.UseAssemblyShaders()} { | ||
| 16 | if (use_assembly_programs) { | 38 | if (use_assembly_programs) { |
| 17 | glEnable(GL_COMPUTE_PROGRAM_NV); | 39 | glEnable(GL_COMPUTE_PROGRAM_NV); |
| 18 | } else { | 40 | } else { |
| @@ -33,9 +55,7 @@ void ProgramManager::BindCompute(GLuint program) { | |||
| 33 | } | 55 | } |
| 34 | 56 | ||
| 35 | void ProgramManager::BindGraphicsPipeline() { | 57 | void ProgramManager::BindGraphicsPipeline() { |
| 36 | if (use_assembly_programs) { | 58 | if (!use_assembly_programs) { |
| 37 | UpdateAssemblyPrograms(); | ||
| 38 | } else { | ||
| 39 | UpdateSourcePrograms(); | 59 | UpdateSourcePrograms(); |
| 40 | } | 60 | } |
| 41 | } | 61 | } |
| @@ -63,32 +83,25 @@ void ProgramManager::RestoreGuestPipeline() { | |||
| 63 | } | 83 | } |
| 64 | } | 84 | } |
| 65 | 85 | ||
| 66 | void ProgramManager::UpdateAssemblyPrograms() { | 86 | void ProgramManager::UseVertexShader(GLuint program) { |
| 67 | const auto update_state = [](GLenum stage, bool& enabled, GLuint current, GLuint old) { | 87 | if (use_assembly_programs) { |
| 68 | if (current == old) { | 88 | BindProgram(GL_VERTEX_PROGRAM_NV, program, current_state.vertex, vertex_enabled); |
| 69 | return; | 89 | } |
| 70 | } | 90 | current_state.vertex = program; |
| 71 | if (current == 0) { | 91 | } |
| 72 | if (enabled) { | ||
| 73 | enabled = false; | ||
| 74 | glDisable(stage); | ||
| 75 | } | ||
| 76 | return; | ||
| 77 | } | ||
| 78 | if (!enabled) { | ||
| 79 | enabled = true; | ||
| 80 | glEnable(stage); | ||
| 81 | } | ||
| 82 | glBindProgramARB(stage, current); | ||
| 83 | }; | ||
| 84 | 92 | ||
| 85 | update_state(GL_VERTEX_PROGRAM_NV, vertex_enabled, current_state.vertex, old_state.vertex); | 93 | void ProgramManager::UseGeometryShader(GLuint program) { |
| 86 | update_state(GL_GEOMETRY_PROGRAM_NV, geometry_enabled, current_state.geometry, | 94 | if (use_assembly_programs) { |
| 87 | old_state.geometry); | 95 | BindProgram(GL_GEOMETRY_PROGRAM_NV, program, current_state.vertex, geometry_enabled); |
| 88 | update_state(GL_FRAGMENT_PROGRAM_NV, fragment_enabled, current_state.fragment, | 96 | } |
| 89 | old_state.fragment); | 97 | current_state.geometry = program; |
| 98 | } | ||
| 90 | 99 | ||
| 91 | old_state = current_state; | 100 | void ProgramManager::UseFragmentShader(GLuint program) { |
| 101 | if (use_assembly_programs) { | ||
| 102 | BindProgram(GL_FRAGMENT_PROGRAM_NV, program, current_state.vertex, fragment_enabled); | ||
| 103 | } | ||
| 104 | current_state.fragment = program; | ||
| 92 | } | 105 | } |
| 93 | 106 | ||
| 94 | void ProgramManager::UpdateSourcePrograms() { | 107 | void ProgramManager::UpdateSourcePrograms() { |
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.h b/src/video_core/renderer_opengl/gl_shader_manager.h index 0f03b4f12..950e0dfcb 100644 --- a/src/video_core/renderer_opengl/gl_shader_manager.h +++ b/src/video_core/renderer_opengl/gl_shader_manager.h | |||
| @@ -45,17 +45,9 @@ public: | |||
| 45 | /// Rewinds BindHostPipeline state changes. | 45 | /// Rewinds BindHostPipeline state changes. |
| 46 | void RestoreGuestPipeline(); | 46 | void RestoreGuestPipeline(); |
| 47 | 47 | ||
| 48 | void UseVertexShader(GLuint program) { | 48 | void UseVertexShader(GLuint program); |
| 49 | current_state.vertex = program; | 49 | void UseGeometryShader(GLuint program); |
| 50 | } | 50 | void UseFragmentShader(GLuint program); |
| 51 | |||
| 52 | void UseGeometryShader(GLuint program) { | ||
| 53 | current_state.geometry = program; | ||
| 54 | } | ||
| 55 | |||
| 56 | void UseFragmentShader(GLuint program) { | ||
| 57 | current_state.fragment = program; | ||
| 58 | } | ||
| 59 | 51 | ||
| 60 | private: | 52 | private: |
| 61 | struct PipelineState { | 53 | struct PipelineState { |
| @@ -64,9 +56,6 @@ private: | |||
| 64 | GLuint fragment = 0; | 56 | GLuint fragment = 0; |
| 65 | }; | 57 | }; |
| 66 | 58 | ||
| 67 | /// Update NV_gpu_program5 programs. | ||
| 68 | void UpdateAssemblyPrograms(); | ||
| 69 | |||
| 70 | /// Update GLSL programs. | 59 | /// Update GLSL programs. |
| 71 | void UpdateSourcePrograms(); | 60 | void UpdateSourcePrograms(); |
| 72 | 61 | ||
diff --git a/src/video_core/renderer_opengl/gl_stream_buffer.cpp b/src/video_core/renderer_opengl/gl_stream_buffer.cpp index 3655ff629..887995cf4 100644 --- a/src/video_core/renderer_opengl/gl_stream_buffer.cpp +++ b/src/video_core/renderer_opengl/gl_stream_buffer.cpp | |||
| @@ -35,7 +35,7 @@ OGLStreamBuffer::OGLStreamBuffer(const Device& device, GLsizeiptr size, bool ver | |||
| 35 | mapped_ptr = static_cast<u8*>( | 35 | mapped_ptr = static_cast<u8*>( |
| 36 | glMapNamedBufferRange(gl_buffer.handle, 0, buffer_size, flags | GL_MAP_FLUSH_EXPLICIT_BIT)); | 36 | glMapNamedBufferRange(gl_buffer.handle, 0, buffer_size, flags | GL_MAP_FLUSH_EXPLICIT_BIT)); |
| 37 | 37 | ||
| 38 | if (device.HasVertexBufferUnifiedMemory()) { | 38 | if (device.UseAssemblyShaders() || device.HasVertexBufferUnifiedMemory()) { |
| 39 | glMakeNamedBufferResidentNV(gl_buffer.handle, GL_READ_ONLY); | 39 | glMakeNamedBufferResidentNV(gl_buffer.handle, GL_READ_ONLY); |
| 40 | glGetNamedBufferParameterui64vNV(gl_buffer.handle, GL_BUFFER_GPU_ADDRESS_NV, &gpu_address); | 40 | glGetNamedBufferParameterui64vNV(gl_buffer.handle, GL_BUFFER_GPU_ADDRESS_NV, &gpu_address); |
| 41 | } | 41 | } |
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index 61505879b..0a7bc9e2b 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp | |||
| @@ -41,91 +41,103 @@ struct FormatTuple { | |||
| 41 | }; | 41 | }; |
| 42 | 42 | ||
| 43 | constexpr std::array<FormatTuple, VideoCore::Surface::MaxPixelFormat> tex_format_tuples = {{ | 43 | constexpr std::array<FormatTuple, VideoCore::Surface::MaxPixelFormat> tex_format_tuples = {{ |
| 44 | {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV}, // ABGR8U | 44 | {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV}, // A8B8G8R8_UNORM |
| 45 | {GL_RGBA8_SNORM, GL_RGBA, GL_BYTE}, // ABGR8S | 45 | {GL_RGBA8_SNORM, GL_RGBA, GL_BYTE}, // A8B8G8R8_SNORM |
| 46 | {GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE}, // ABGR8UI | 46 | {GL_RGBA8I, GL_RGBA_INTEGER, GL_BYTE}, // A8B8G8R8_SINT |
| 47 | {GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV}, // B5G6R5U | 47 | {GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE}, // A8B8G8R8_UINT |
| 48 | {GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV}, // A2B10G10R10U | 48 | {GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5}, // R5G6B5_UNORM |
| 49 | {GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV}, // A1B5G5R5U | 49 | {GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV}, // B5G6R5_UNORM |
| 50 | {GL_R8, GL_RED, GL_UNSIGNED_BYTE}, // R8U | 50 | {GL_RGB5_A1, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV}, // A1R5G5B5_UNORM |
| 51 | {GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE}, // R8UI | 51 | {GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV}, // A2B10G10R10_UNORM |
| 52 | {GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT}, // RGBA16F | 52 | {GL_RGB10_A2UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV}, // A2B10G10R10_UINT |
| 53 | {GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT}, // RGBA16U | 53 | {GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV}, // A1B5G5R5_UNORM |
| 54 | {GL_RGBA16_SNORM, GL_RGBA, GL_SHORT}, // RGBA16S | 54 | {GL_R8, GL_RED, GL_UNSIGNED_BYTE}, // R8_UNORM |
| 55 | {GL_RGBA16UI, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT}, // RGBA16UI | 55 | {GL_R8_SNORM, GL_RED, GL_BYTE}, // R8_SNORM |
| 56 | {GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV}, // R11FG11FB10F | 56 | {GL_R8I, GL_RED_INTEGER, GL_BYTE}, // R8_SINT |
| 57 | {GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT}, // RGBA32UI | 57 | {GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE}, // R8_UINT |
| 58 | {GL_COMPRESSED_RGBA_S3TC_DXT1_EXT}, // DXT1 | 58 | {GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT}, // R16G16B16A16_FLOAT |
| 59 | {GL_COMPRESSED_RGBA_S3TC_DXT3_EXT}, // DXT23 | 59 | {GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT}, // R16G16B16A16_UNORM |
| 60 | {GL_COMPRESSED_RGBA_S3TC_DXT5_EXT}, // DXT45 | 60 | {GL_RGBA16_SNORM, GL_RGBA, GL_SHORT}, // R16G16B16A16_SNORM |
| 61 | {GL_COMPRESSED_RED_RGTC1}, // DXN1 | 61 | {GL_RGBA16I, GL_RGBA_INTEGER, GL_SHORT}, // R16G16B16A16_SINT |
| 62 | {GL_COMPRESSED_RG_RGTC2}, // DXN2UNORM | 62 | {GL_RGBA16UI, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT}, // R16G16B16A16_UINT |
| 63 | {GL_COMPRESSED_SIGNED_RG_RGTC2}, // DXN2SNORM | 63 | {GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV}, // B10G11R11_FLOAT |
| 64 | {GL_COMPRESSED_RGBA_BPTC_UNORM}, // BC7U | 64 | {GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT}, // R32G32B32A32_UINT |
| 65 | {GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT}, // BC6H_UF16 | 65 | {GL_COMPRESSED_RGBA_S3TC_DXT1_EXT}, // BC1_RGBA_UNORM |
| 66 | {GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT}, // BC6H_SF16 | 66 | {GL_COMPRESSED_RGBA_S3TC_DXT3_EXT}, // BC2_UNORM |
| 67 | {GL_COMPRESSED_RGBA_ASTC_4x4_KHR}, // ASTC_2D_4X4 | 67 | {GL_COMPRESSED_RGBA_S3TC_DXT5_EXT}, // BC3_UNORM |
| 68 | {GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE}, // BGRA8 | 68 | {GL_COMPRESSED_RED_RGTC1}, // BC4_UNORM |
| 69 | {GL_RGBA32F, GL_RGBA, GL_FLOAT}, // RGBA32F | 69 | {GL_COMPRESSED_SIGNED_RED_RGTC1}, // BC4_SNORM |
| 70 | {GL_RG32F, GL_RG, GL_FLOAT}, // RG32F | 70 | {GL_COMPRESSED_RG_RGTC2}, // BC5_UNORM |
| 71 | {GL_R32F, GL_RED, GL_FLOAT}, // R32F | 71 | {GL_COMPRESSED_SIGNED_RG_RGTC2}, // BC5_SNORM |
| 72 | {GL_R16F, GL_RED, GL_HALF_FLOAT}, // R16F | 72 | {GL_COMPRESSED_RGBA_BPTC_UNORM}, // BC7_UNORM |
| 73 | {GL_R16, GL_RED, GL_UNSIGNED_SHORT}, // R16U | 73 | {GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT}, // BC6H_UFLOAT |
| 74 | {GL_R16_SNORM, GL_RED, GL_SHORT}, // R16S | 74 | {GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT}, // BC6H_SFLOAT |
| 75 | {GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT}, // R16UI | 75 | {GL_COMPRESSED_RGBA_ASTC_4x4_KHR}, // ASTC_2D_4X4_UNORM |
| 76 | {GL_R16I, GL_RED_INTEGER, GL_SHORT}, // R16I | 76 | {GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE}, // B8G8R8A8_UNORM |
| 77 | {GL_RG16, GL_RG, GL_UNSIGNED_SHORT}, // RG16 | 77 | {GL_RGBA32F, GL_RGBA, GL_FLOAT}, // R32G32B32A32_FLOAT |
| 78 | {GL_RG16F, GL_RG, GL_HALF_FLOAT}, // RG16F | 78 | {GL_RGBA32I, GL_RGBA_INTEGER, GL_INT}, // R32G32B32A32_SINT |
| 79 | {GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT}, // RG16UI | 79 | {GL_RG32F, GL_RG, GL_FLOAT}, // R32G32_FLOAT |
| 80 | {GL_RG16I, GL_RG_INTEGER, GL_SHORT}, // RG16I | 80 | {GL_RG32I, GL_RG_INTEGER, GL_INT}, // R32G32_SINT |
| 81 | {GL_RG16_SNORM, GL_RG, GL_SHORT}, // RG16S | 81 | {GL_R32F, GL_RED, GL_FLOAT}, // R32_FLOAT |
| 82 | {GL_RGB32F, GL_RGB, GL_FLOAT}, // RGB32F | 82 | {GL_R16F, GL_RED, GL_HALF_FLOAT}, // R16_FLOAT |
| 83 | {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV}, // RGBA8_SRGB | 83 | {GL_R16, GL_RED, GL_UNSIGNED_SHORT}, // R16_UNORM |
| 84 | {GL_RG8, GL_RG, GL_UNSIGNED_BYTE}, // RG8U | 84 | {GL_R16_SNORM, GL_RED, GL_SHORT}, // R16_SNORM |
| 85 | {GL_RG8_SNORM, GL_RG, GL_BYTE}, // RG8S | 85 | {GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT}, // R16_UINT |
| 86 | {GL_RG8UI, GL_RG_INTEGER, GL_UNSIGNED_INT}, // RG8UI | 86 | {GL_R16I, GL_RED_INTEGER, GL_SHORT}, // R16_SINT |
| 87 | {GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT}, // RG32UI | 87 | {GL_RG16, GL_RG, GL_UNSIGNED_SHORT}, // R16G16_UNORM |
| 88 | {GL_RGB16F, GL_RGBA, GL_HALF_FLOAT}, // RGBX16F | 88 | {GL_RG16F, GL_RG, GL_HALF_FLOAT}, // R16G16_FLOAT |
| 89 | {GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT}, // R32UI | 89 | {GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT}, // R16G16_UINT |
| 90 | {GL_R32I, GL_RED_INTEGER, GL_INT}, // R32I | 90 | {GL_RG16I, GL_RG_INTEGER, GL_SHORT}, // R16G16_SINT |
| 91 | {GL_COMPRESSED_RGBA_ASTC_8x8_KHR}, // ASTC_2D_8X8 | 91 | {GL_RG16_SNORM, GL_RG, GL_SHORT}, // R16G16_SNORM |
| 92 | {GL_COMPRESSED_RGBA_ASTC_8x5_KHR}, // ASTC_2D_8X5 | 92 | {GL_RGB32F, GL_RGB, GL_FLOAT}, // R32G32B32_FLOAT |
| 93 | {GL_COMPRESSED_RGBA_ASTC_5x4_KHR}, // ASTC_2D_5X4 | 93 | {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV}, // A8B8G8R8_SRGB |
| 94 | {GL_SRGB8_ALPHA8, GL_BGRA, GL_UNSIGNED_BYTE}, // BGRA8 | 94 | {GL_RG8, GL_RG, GL_UNSIGNED_BYTE}, // R8G8_UNORM |
| 95 | {GL_RG8_SNORM, GL_RG, GL_BYTE}, // R8G8_SNORM | ||
| 96 | {GL_RG8I, GL_RG_INTEGER, GL_BYTE}, // R8G8_SINT | ||
| 97 | {GL_RG8UI, GL_RG_INTEGER, GL_UNSIGNED_BYTE}, // R8G8_UINT | ||
| 98 | {GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT}, // R32G32_UINT | ||
| 99 | {GL_RGB16F, GL_RGBA, GL_HALF_FLOAT}, // R16G16B16X16_FLOAT | ||
| 100 | {GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT}, // R32_UINT | ||
| 101 | {GL_R32I, GL_RED_INTEGER, GL_INT}, // R32_SINT | ||
| 102 | {GL_COMPRESSED_RGBA_ASTC_8x8_KHR}, // ASTC_2D_8X8_UNORM | ||
| 103 | {GL_COMPRESSED_RGBA_ASTC_8x5_KHR}, // ASTC_2D_8X5_UNORM | ||
| 104 | {GL_COMPRESSED_RGBA_ASTC_5x4_KHR}, // ASTC_2D_5X4_UNORM | ||
| 105 | {GL_SRGB8_ALPHA8, GL_BGRA, GL_UNSIGNED_BYTE}, // B8G8R8A8_UNORM | ||
| 95 | // Compressed sRGB formats | 106 | // Compressed sRGB formats |
| 96 | {GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT}, // DXT1_SRGB | 107 | {GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT}, // BC1_RGBA_SRGB |
| 97 | {GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT}, // DXT23_SRGB | 108 | {GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT}, // BC2_SRGB |
| 98 | {GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT}, // DXT45_SRGB | 109 | {GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT}, // BC3_SRGB |
| 99 | {GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM}, // BC7U_SRGB | 110 | {GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM}, // BC7_SRGB |
| 100 | {GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4_REV}, // R4G4B4A4U | 111 | {GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4_REV}, // A4B4G4R4_UNORM |
| 101 | {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR}, // ASTC_2D_4X4_SRGB | 112 | {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR}, // ASTC_2D_4X4_SRGB |
| 102 | {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR}, // ASTC_2D_8X8_SRGB | 113 | {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR}, // ASTC_2D_8X8_SRGB |
| 103 | {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR}, // ASTC_2D_8X5_SRGB | 114 | {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR}, // ASTC_2D_8X5_SRGB |
| 104 | {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR}, // ASTC_2D_5X4_SRGB | 115 | {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR}, // ASTC_2D_5X4_SRGB |
| 105 | {GL_COMPRESSED_RGBA_ASTC_5x5_KHR}, // ASTC_2D_5X5 | 116 | {GL_COMPRESSED_RGBA_ASTC_5x5_KHR}, // ASTC_2D_5X5_UNORM |
| 106 | {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR}, // ASTC_2D_5X5_SRGB | 117 | {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR}, // ASTC_2D_5X5_SRGB |
| 107 | {GL_COMPRESSED_RGBA_ASTC_10x8_KHR}, // ASTC_2D_10X8 | 118 | {GL_COMPRESSED_RGBA_ASTC_10x8_KHR}, // ASTC_2D_10X8_UNORM |
| 108 | {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR}, // ASTC_2D_10X8_SRGB | 119 | {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR}, // ASTC_2D_10X8_SRGB |
| 109 | {GL_COMPRESSED_RGBA_ASTC_6x6_KHR}, // ASTC_2D_6X6 | 120 | {GL_COMPRESSED_RGBA_ASTC_6x6_KHR}, // ASTC_2D_6X6_UNORM |
| 110 | {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR}, // ASTC_2D_6X6_SRGB | 121 | {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR}, // ASTC_2D_6X6_SRGB |
| 111 | {GL_COMPRESSED_RGBA_ASTC_10x10_KHR}, // ASTC_2D_10X10 | 122 | {GL_COMPRESSED_RGBA_ASTC_10x10_KHR}, // ASTC_2D_10X10_UNORM |
| 112 | {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR}, // ASTC_2D_10X10_SRGB | 123 | {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR}, // ASTC_2D_10X10_SRGB |
| 113 | {GL_COMPRESSED_RGBA_ASTC_12x12_KHR}, // ASTC_2D_12X12 | 124 | {GL_COMPRESSED_RGBA_ASTC_12x12_KHR}, // ASTC_2D_12X12_UNORM |
| 114 | {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR}, // ASTC_2D_12X12_SRGB | 125 | {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR}, // ASTC_2D_12X12_SRGB |
| 115 | {GL_COMPRESSED_RGBA_ASTC_8x6_KHR}, // ASTC_2D_8X6 | 126 | {GL_COMPRESSED_RGBA_ASTC_8x6_KHR}, // ASTC_2D_8X6_UNORM |
| 116 | {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR}, // ASTC_2D_8X6_SRGB | 127 | {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR}, // ASTC_2D_8X6_SRGB |
| 117 | {GL_COMPRESSED_RGBA_ASTC_6x5_KHR}, // ASTC_2D_6X5 | 128 | {GL_COMPRESSED_RGBA_ASTC_6x5_KHR}, // ASTC_2D_6X5_UNORM |
| 118 | {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR}, // ASTC_2D_6X5_SRGB | 129 | {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR}, // ASTC_2D_6X5_SRGB |
| 119 | {GL_RGB9_E5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV}, // E5B9G9R9F | 130 | {GL_RGB9_E5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV}, // E5B9G9R9_FLOAT |
| 120 | 131 | ||
| 121 | // Depth formats | 132 | // Depth formats |
| 122 | {GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT}, // Z32F | 133 | {GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT}, // D32_FLOAT |
| 123 | {GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}, // Z16 | 134 | {GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}, // D16_UNORM |
| 124 | 135 | ||
| 125 | // DepthStencil formats | 136 | // DepthStencil formats |
| 126 | {GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8}, // Z24S8 | 137 | {GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8}, // D24_UNORM_S8_UINT |
| 127 | {GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8}, // S8Z24 | 138 | {GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8}, // S8_UINT_D24_UNORM |
| 128 | {GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV}, // Z32FS8 | 139 | {GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, |
| 140 | GL_FLOAT_32_UNSIGNED_INT_24_8_REV}, // D32_FLOAT_S8_UINT | ||
| 129 | }}; | 141 | }}; |
| 130 | 142 | ||
| 131 | const FormatTuple& GetFormatTuple(PixelFormat pixel_format) { | 143 | const FormatTuple& GetFormatTuple(PixelFormat pixel_format) { |
| @@ -178,10 +190,10 @@ GLint GetSwizzleSource(SwizzleSource source) { | |||
| 178 | 190 | ||
| 179 | GLenum GetComponent(PixelFormat format, bool is_first) { | 191 | GLenum GetComponent(PixelFormat format, bool is_first) { |
| 180 | switch (format) { | 192 | switch (format) { |
| 181 | case PixelFormat::Z24S8: | 193 | case PixelFormat::D24_UNORM_S8_UINT: |
| 182 | case PixelFormat::Z32FS8: | 194 | case PixelFormat::D32_FLOAT_S8_UINT: |
| 183 | return is_first ? GL_DEPTH_COMPONENT : GL_STENCIL_INDEX; | 195 | return is_first ? GL_DEPTH_COMPONENT : GL_STENCIL_INDEX; |
| 184 | case PixelFormat::S8Z24: | 196 | case PixelFormat::S8_UINT_D24_UNORM: |
| 185 | return is_first ? GL_STENCIL_INDEX : GL_DEPTH_COMPONENT; | 197 | return is_first ? GL_STENCIL_INDEX : GL_DEPTH_COMPONENT; |
| 186 | default: | 198 | default: |
| 187 | UNREACHABLE(); | 199 | UNREACHABLE(); |
| @@ -482,9 +494,9 @@ GLuint CachedSurfaceView::GetTexture(SwizzleSource x_source, SwizzleSource y_sou | |||
| 482 | std::array swizzle{x_source, y_source, z_source, w_source}; | 494 | std::array swizzle{x_source, y_source, z_source, w_source}; |
| 483 | 495 | ||
| 484 | switch (const PixelFormat format = GetSurfaceParams().pixel_format) { | 496 | switch (const PixelFormat format = GetSurfaceParams().pixel_format) { |
| 485 | case PixelFormat::Z24S8: | 497 | case PixelFormat::D24_UNORM_S8_UINT: |
| 486 | case PixelFormat::Z32FS8: | 498 | case PixelFormat::D32_FLOAT_S8_UINT: |
| 487 | case PixelFormat::S8Z24: | 499 | case PixelFormat::S8_UINT_D24_UNORM: |
| 488 | UNIMPLEMENTED_IF(x_source != SwizzleSource::R && x_source != SwizzleSource::G); | 500 | UNIMPLEMENTED_IF(x_source != SwizzleSource::R && x_source != SwizzleSource::G); |
| 489 | glTextureParameteri(view.handle, GL_DEPTH_STENCIL_TEXTURE_MODE, | 501 | glTextureParameteri(view.handle, GL_DEPTH_STENCIL_TEXTURE_MODE, |
| 490 | GetComponent(format, x_source == SwizzleSource::R)); | 502 | GetComponent(format, x_source == SwizzleSource::R)); |
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index e66cdc083..52e9e8250 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp | |||
| @@ -535,12 +535,12 @@ void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture, | |||
| 535 | 535 | ||
| 536 | GLint internal_format; | 536 | GLint internal_format; |
| 537 | switch (framebuffer.pixel_format) { | 537 | switch (framebuffer.pixel_format) { |
| 538 | case Tegra::FramebufferConfig::PixelFormat::ABGR8: | 538 | case Tegra::FramebufferConfig::PixelFormat::A8B8G8R8_UNORM: |
| 539 | internal_format = GL_RGBA8; | 539 | internal_format = GL_RGBA8; |
| 540 | texture.gl_format = GL_RGBA; | 540 | texture.gl_format = GL_RGBA; |
| 541 | texture.gl_type = GL_UNSIGNED_INT_8_8_8_8_REV; | 541 | texture.gl_type = GL_UNSIGNED_INT_8_8_8_8_REV; |
| 542 | break; | 542 | break; |
| 543 | case Tegra::FramebufferConfig::PixelFormat::RGB565: | 543 | case Tegra::FramebufferConfig::PixelFormat::RGB565_UNORM: |
| 544 | internal_format = GL_RGB565; | 544 | internal_format = GL_RGB565; |
| 545 | texture.gl_format = GL_RGB; | 545 | texture.gl_format = GL_RGB; |
| 546 | texture.gl_type = GL_UNSIGNED_SHORT_5_6_5; | 546 | texture.gl_type = GL_UNSIGNED_SHORT_5_6_5; |
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp index d1f0ea932..81a39a3b8 100644 --- a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp +++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp | |||
| @@ -40,7 +40,6 @@ constexpr std::array POLYGON_OFFSET_ENABLE_LUT = { | |||
| 40 | } // Anonymous namespace | 40 | } // Anonymous namespace |
| 41 | 41 | ||
| 42 | void FixedPipelineState::Fill(const Maxwell& regs, bool has_extended_dynamic_state) { | 42 | void FixedPipelineState::Fill(const Maxwell& regs, bool has_extended_dynamic_state) { |
| 43 | const auto& clip = regs.view_volume_clip_control; | ||
| 44 | const std::array enabled_lut = {regs.polygon_offset_point_enable, | 43 | const std::array enabled_lut = {regs.polygon_offset_point_enable, |
| 45 | regs.polygon_offset_line_enable, | 44 | regs.polygon_offset_line_enable, |
| 46 | regs.polygon_offset_fill_enable}; | 45 | regs.polygon_offset_fill_enable}; |
diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp index d7f1ae89f..f8c77f4fa 100644 --- a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp +++ b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp | |||
| @@ -117,90 +117,101 @@ struct FormatTuple { | |||
| 117 | VkFormat format; ///< Vulkan format | 117 | VkFormat format; ///< Vulkan format |
| 118 | int usage = 0; ///< Describes image format usage | 118 | int usage = 0; ///< Describes image format usage |
| 119 | } constexpr tex_format_tuples[] = { | 119 | } constexpr tex_format_tuples[] = { |
| 120 | {VK_FORMAT_A8B8G8R8_UNORM_PACK32, Attachable | Storage}, // ABGR8U | 120 | {VK_FORMAT_A8B8G8R8_UNORM_PACK32, Attachable | Storage}, // A8B8G8R8_UNORM |
| 121 | {VK_FORMAT_A8B8G8R8_SNORM_PACK32, Attachable | Storage}, // ABGR8S | 121 | {VK_FORMAT_A8B8G8R8_SNORM_PACK32, Attachable | Storage}, // A8B8G8R8_SNORM |
| 122 | {VK_FORMAT_A8B8G8R8_UINT_PACK32, Attachable | Storage}, // ABGR8UI | 122 | {VK_FORMAT_A8B8G8R8_SINT_PACK32, Attachable | Storage}, // A8B8G8R8_SINT |
| 123 | {VK_FORMAT_B5G6R5_UNORM_PACK16}, // B5G6R5U | 123 | {VK_FORMAT_A8B8G8R8_UINT_PACK32, Attachable | Storage}, // A8B8G8R8_UINT |
| 124 | {VK_FORMAT_A2B10G10R10_UNORM_PACK32, Attachable | Storage}, // A2B10G10R10U | 124 | {VK_FORMAT_R5G6B5_UNORM_PACK16, Attachable}, // R5G6B5_UNORM |
| 125 | {VK_FORMAT_A1R5G5B5_UNORM_PACK16, Attachable}, // A1B5G5R5U (flipped with swizzle) | 125 | {VK_FORMAT_B5G6R5_UNORM_PACK16, Attachable}, // B5G6R5_UNORM |
| 126 | {VK_FORMAT_R8_UNORM, Attachable | Storage}, // R8U | 126 | {VK_FORMAT_A1R5G5B5_UNORM_PACK16, Attachable}, // A1R5G5B5_UNORM |
| 127 | {VK_FORMAT_R8_UINT, Attachable | Storage}, // R8UI | 127 | {VK_FORMAT_A2B10G10R10_UNORM_PACK32, Attachable | Storage}, // A2B10G10R10_UNORM |
| 128 | {VK_FORMAT_R16G16B16A16_SFLOAT, Attachable | Storage}, // RGBA16F | 128 | {VK_FORMAT_A2B10G10R10_UINT_PACK32, Attachable | Storage}, // A2B10G10R10_UINT |
| 129 | {VK_FORMAT_R16G16B16A16_UNORM, Attachable | Storage}, // RGBA16U | 129 | {VK_FORMAT_A1R5G5B5_UNORM_PACK16, Attachable}, // A1B5G5R5_UNORM (flipped with swizzle) |
| 130 | {VK_FORMAT_R16G16B16A16_SNORM, Attachable | Storage}, // RGBA16S | 130 | {VK_FORMAT_R8_UNORM, Attachable | Storage}, // R8_UNORM |
| 131 | {VK_FORMAT_R16G16B16A16_UINT, Attachable | Storage}, // RGBA16UI | 131 | {VK_FORMAT_R8_SNORM, Attachable | Storage}, // R8_SNORM |
| 132 | {VK_FORMAT_B10G11R11_UFLOAT_PACK32, Attachable | Storage}, // R11FG11FB10F | 132 | {VK_FORMAT_R8_SINT, Attachable | Storage}, // R8_SINT |
| 133 | {VK_FORMAT_R32G32B32A32_UINT, Attachable | Storage}, // RGBA32UI | 133 | {VK_FORMAT_R8_UINT, Attachable | Storage}, // R8_UINT |
| 134 | {VK_FORMAT_BC1_RGBA_UNORM_BLOCK}, // DXT1 | 134 | {VK_FORMAT_R16G16B16A16_SFLOAT, Attachable | Storage}, // R16G16B16A16_FLOAT |
| 135 | {VK_FORMAT_BC2_UNORM_BLOCK}, // DXT23 | 135 | {VK_FORMAT_R16G16B16A16_UNORM, Attachable | Storage}, // R16G16B16A16_UNORM |
| 136 | {VK_FORMAT_BC3_UNORM_BLOCK}, // DXT45 | 136 | {VK_FORMAT_R16G16B16A16_SNORM, Attachable | Storage}, // R16G16B16A16_SNORM |
| 137 | {VK_FORMAT_BC4_UNORM_BLOCK}, // DXN1 | 137 | {VK_FORMAT_R16G16B16A16_SINT, Attachable | Storage}, // R16G16B16A16_SINT |
| 138 | {VK_FORMAT_BC5_UNORM_BLOCK}, // DXN2UNORM | 138 | {VK_FORMAT_R16G16B16A16_UINT, Attachable | Storage}, // R16G16B16A16_UINT |
| 139 | {VK_FORMAT_BC5_SNORM_BLOCK}, // DXN2SNORM | 139 | {VK_FORMAT_B10G11R11_UFLOAT_PACK32, Attachable | Storage}, // B10G11R11_FLOAT |
| 140 | {VK_FORMAT_BC7_UNORM_BLOCK}, // BC7U | 140 | {VK_FORMAT_R32G32B32A32_UINT, Attachable | Storage}, // R32G32B32A32_UINT |
| 141 | {VK_FORMAT_BC6H_UFLOAT_BLOCK}, // BC6H_UF16 | 141 | {VK_FORMAT_BC1_RGBA_UNORM_BLOCK}, // BC1_RGBA_UNORM |
| 142 | {VK_FORMAT_BC6H_SFLOAT_BLOCK}, // BC6H_SF16 | 142 | {VK_FORMAT_BC2_UNORM_BLOCK}, // BC2_UNORM |
| 143 | {VK_FORMAT_ASTC_4x4_UNORM_BLOCK}, // ASTC_2D_4X4 | 143 | {VK_FORMAT_BC3_UNORM_BLOCK}, // BC3_UNORM |
| 144 | {VK_FORMAT_B8G8R8A8_UNORM, Attachable}, // BGRA8 | 144 | {VK_FORMAT_BC4_UNORM_BLOCK}, // BC4_UNORM |
| 145 | {VK_FORMAT_R32G32B32A32_SFLOAT, Attachable | Storage}, // RGBA32F | 145 | {VK_FORMAT_BC4_SNORM_BLOCK}, // BC4_SNORM |
| 146 | {VK_FORMAT_R32G32_SFLOAT, Attachable | Storage}, // RG32F | 146 | {VK_FORMAT_BC5_UNORM_BLOCK}, // BC5_UNORM |
| 147 | {VK_FORMAT_R32_SFLOAT, Attachable | Storage}, // R32F | 147 | {VK_FORMAT_BC5_SNORM_BLOCK}, // BC5_SNORM |
| 148 | {VK_FORMAT_R16_SFLOAT, Attachable | Storage}, // R16F | 148 | {VK_FORMAT_BC7_UNORM_BLOCK}, // BC7_UNORM |
| 149 | {VK_FORMAT_R16_UNORM, Attachable | Storage}, // R16U | 149 | {VK_FORMAT_BC6H_UFLOAT_BLOCK}, // BC6H_UFLOAT |
| 150 | {VK_FORMAT_UNDEFINED}, // R16S | 150 | {VK_FORMAT_BC6H_SFLOAT_BLOCK}, // BC6H_SFLOAT |
| 151 | {VK_FORMAT_R16_UINT, Attachable | Storage}, // R16UI | 151 | {VK_FORMAT_ASTC_4x4_UNORM_BLOCK}, // ASTC_2D_4X4_UNORM |
| 152 | {VK_FORMAT_UNDEFINED}, // R16I | 152 | {VK_FORMAT_B8G8R8A8_UNORM, Attachable}, // B8G8R8A8_UNORM |
| 153 | {VK_FORMAT_R16G16_UNORM, Attachable | Storage}, // RG16 | 153 | {VK_FORMAT_R32G32B32A32_SFLOAT, Attachable | Storage}, // R32G32B32A32_FLOAT |
| 154 | {VK_FORMAT_R16G16_SFLOAT, Attachable | Storage}, // RG16F | 154 | {VK_FORMAT_R32G32B32A32_SINT, Attachable | Storage}, // R32G32B32A32_SINT |
| 155 | {VK_FORMAT_UNDEFINED}, // RG16UI | 155 | {VK_FORMAT_R32G32_SFLOAT, Attachable | Storage}, // R32G32_FLOAT |
| 156 | {VK_FORMAT_UNDEFINED}, // RG16I | 156 | {VK_FORMAT_R32G32_SINT, Attachable | Storage}, // R32G32_SINT |
| 157 | {VK_FORMAT_R16G16_SNORM, Attachable | Storage}, // RG16S | 157 | {VK_FORMAT_R32_SFLOAT, Attachable | Storage}, // R32_FLOAT |
| 158 | {VK_FORMAT_UNDEFINED}, // RGB32F | 158 | {VK_FORMAT_R16_SFLOAT, Attachable | Storage}, // R16_FLOAT |
| 159 | {VK_FORMAT_R8G8B8A8_SRGB, Attachable}, // RGBA8_SRGB | 159 | {VK_FORMAT_R16_UNORM, Attachable | Storage}, // R16_UNORM |
| 160 | {VK_FORMAT_R8G8_UNORM, Attachable | Storage}, // RG8U | 160 | {VK_FORMAT_UNDEFINED}, // R16_SNORM |
| 161 | {VK_FORMAT_R8G8_SNORM, Attachable | Storage}, // RG8S | 161 | {VK_FORMAT_R16_UINT, Attachable | Storage}, // R16_UINT |
| 162 | {VK_FORMAT_R8G8_UINT, Attachable | Storage}, // RG8UI | 162 | {VK_FORMAT_UNDEFINED}, // R16_SINT |
| 163 | {VK_FORMAT_R32G32_UINT, Attachable | Storage}, // RG32UI | 163 | {VK_FORMAT_R16G16_UNORM, Attachable | Storage}, // R16G16_UNORM |
| 164 | {VK_FORMAT_UNDEFINED}, // RGBX16F | 164 | {VK_FORMAT_R16G16_SFLOAT, Attachable | Storage}, // R16G16_FLOAT |
| 165 | {VK_FORMAT_R32_UINT, Attachable | Storage}, // R32UI | 165 | {VK_FORMAT_UNDEFINED}, // R16G16_UINT |
| 166 | {VK_FORMAT_R32_SINT, Attachable | Storage}, // R32I | 166 | {VK_FORMAT_UNDEFINED}, // R16G16_SINT |
| 167 | {VK_FORMAT_ASTC_8x8_UNORM_BLOCK}, // ASTC_2D_8X8 | 167 | {VK_FORMAT_R16G16_SNORM, Attachable | Storage}, // R16G16_SNORM |
| 168 | {VK_FORMAT_UNDEFINED}, // ASTC_2D_8X5 | 168 | {VK_FORMAT_UNDEFINED}, // R32G32B32_FLOAT |
| 169 | {VK_FORMAT_UNDEFINED}, // ASTC_2D_5X4 | 169 | {VK_FORMAT_R8G8B8A8_SRGB, Attachable}, // A8B8G8R8_SRGB |
| 170 | {VK_FORMAT_B8G8R8A8_SRGB, Attachable}, // BGRA8_SRGB | 170 | {VK_FORMAT_R8G8_UNORM, Attachable | Storage}, // R8G8_UNORM |
| 171 | {VK_FORMAT_BC1_RGBA_SRGB_BLOCK}, // DXT1_SRGB | 171 | {VK_FORMAT_R8G8_SNORM, Attachable | Storage}, // R8G8_SNORM |
| 172 | {VK_FORMAT_BC2_SRGB_BLOCK}, // DXT23_SRGB | 172 | {VK_FORMAT_R8G8_SINT, Attachable | Storage}, // R8G8_SINT |
| 173 | {VK_FORMAT_BC3_SRGB_BLOCK}, // DXT45_SRGB | 173 | {VK_FORMAT_R8G8_UINT, Attachable | Storage}, // R8G8_UINT |
| 174 | {VK_FORMAT_BC7_SRGB_BLOCK}, // BC7U_SRGB | 174 | {VK_FORMAT_R32G32_UINT, Attachable | Storage}, // R32G32_UINT |
| 175 | {VK_FORMAT_R4G4B4A4_UNORM_PACK16, Attachable}, // R4G4B4A4U | 175 | {VK_FORMAT_UNDEFINED}, // R16G16B16X16_FLOAT |
| 176 | {VK_FORMAT_ASTC_4x4_SRGB_BLOCK}, // ASTC_2D_4X4_SRGB | 176 | {VK_FORMAT_R32_UINT, Attachable | Storage}, // R32_UINT |
| 177 | {VK_FORMAT_ASTC_8x8_SRGB_BLOCK}, // ASTC_2D_8X8_SRGB | 177 | {VK_FORMAT_R32_SINT, Attachable | Storage}, // R32_SINT |
| 178 | {VK_FORMAT_ASTC_8x5_SRGB_BLOCK}, // ASTC_2D_8X5_SRGB | 178 | {VK_FORMAT_ASTC_8x8_UNORM_BLOCK}, // ASTC_2D_8X8_UNORM |
| 179 | {VK_FORMAT_ASTC_5x4_SRGB_BLOCK}, // ASTC_2D_5X4_SRGB | 179 | {VK_FORMAT_UNDEFINED}, // ASTC_2D_8X5_UNORM |
| 180 | {VK_FORMAT_ASTC_5x5_UNORM_BLOCK}, // ASTC_2D_5X5 | 180 | {VK_FORMAT_UNDEFINED}, // ASTC_2D_5X4_UNORM |
| 181 | {VK_FORMAT_ASTC_5x5_SRGB_BLOCK}, // ASTC_2D_5X5_SRGB | 181 | {VK_FORMAT_B8G8R8A8_SRGB, Attachable}, // B8G8R8A8_SRGB |
| 182 | {VK_FORMAT_ASTC_10x8_UNORM_BLOCK}, // ASTC_2D_10X8 | 182 | {VK_FORMAT_BC1_RGBA_SRGB_BLOCK}, // BC1_RGBA_SRGB |
| 183 | {VK_FORMAT_ASTC_10x8_SRGB_BLOCK}, // ASTC_2D_10X8_SRGB | 183 | {VK_FORMAT_BC2_SRGB_BLOCK}, // BC2_SRGB |
| 184 | {VK_FORMAT_ASTC_6x6_UNORM_BLOCK}, // ASTC_2D_6X6 | 184 | {VK_FORMAT_BC3_SRGB_BLOCK}, // BC3_SRGB |
| 185 | {VK_FORMAT_ASTC_6x6_SRGB_BLOCK}, // ASTC_2D_6X6_SRGB | 185 | {VK_FORMAT_BC7_SRGB_BLOCK}, // BC7_SRGB |
| 186 | {VK_FORMAT_ASTC_10x10_UNORM_BLOCK}, // ASTC_2D_10X10 | 186 | {VK_FORMAT_R4G4B4A4_UNORM_PACK16, Attachable}, // A4B4G4R4_UNORM |
| 187 | {VK_FORMAT_ASTC_10x10_SRGB_BLOCK}, // ASTC_2D_10X10_SRGB | 187 | {VK_FORMAT_ASTC_4x4_SRGB_BLOCK}, // ASTC_2D_4X4_SRGB |
| 188 | {VK_FORMAT_ASTC_12x12_UNORM_BLOCK}, // ASTC_2D_12X12 | 188 | {VK_FORMAT_ASTC_8x8_SRGB_BLOCK}, // ASTC_2D_8X8_SRGB |
| 189 | {VK_FORMAT_ASTC_12x12_SRGB_BLOCK}, // ASTC_2D_12X12_SRGB | 189 | {VK_FORMAT_ASTC_8x5_SRGB_BLOCK}, // ASTC_2D_8X5_SRGB |
| 190 | {VK_FORMAT_ASTC_8x6_UNORM_BLOCK}, // ASTC_2D_8X6 | 190 | {VK_FORMAT_ASTC_5x4_SRGB_BLOCK}, // ASTC_2D_5X4_SRGB |
| 191 | {VK_FORMAT_ASTC_8x6_SRGB_BLOCK}, // ASTC_2D_8X6_SRGB | 191 | {VK_FORMAT_ASTC_5x5_UNORM_BLOCK}, // ASTC_2D_5X5_UNORM |
| 192 | {VK_FORMAT_ASTC_6x5_UNORM_BLOCK}, // ASTC_2D_6X5 | 192 | {VK_FORMAT_ASTC_5x5_SRGB_BLOCK}, // ASTC_2D_5X5_SRGB |
| 193 | {VK_FORMAT_ASTC_6x5_SRGB_BLOCK}, // ASTC_2D_6X5_SRGB | 193 | {VK_FORMAT_ASTC_10x8_UNORM_BLOCK}, // ASTC_2D_10X8_UNORM |
| 194 | {VK_FORMAT_E5B9G9R9_UFLOAT_PACK32}, // E5B9G9R9F | 194 | {VK_FORMAT_ASTC_10x8_SRGB_BLOCK}, // ASTC_2D_10X8_SRGB |
| 195 | {VK_FORMAT_ASTC_6x6_UNORM_BLOCK}, // ASTC_2D_6X6_UNORM | ||
| 196 | {VK_FORMAT_ASTC_6x6_SRGB_BLOCK}, // ASTC_2D_6X6_SRGB | ||
| 197 | {VK_FORMAT_ASTC_10x10_UNORM_BLOCK}, // ASTC_2D_10X10_UNORM | ||
| 198 | {VK_FORMAT_ASTC_10x10_SRGB_BLOCK}, // ASTC_2D_10X10_SRGB | ||
| 199 | {VK_FORMAT_ASTC_12x12_UNORM_BLOCK}, // ASTC_2D_12X12_UNORM | ||
| 200 | {VK_FORMAT_ASTC_12x12_SRGB_BLOCK}, // ASTC_2D_12X12_SRGB | ||
| 201 | {VK_FORMAT_ASTC_8x6_UNORM_BLOCK}, // ASTC_2D_8X6_UNORM | ||
| 202 | {VK_FORMAT_ASTC_8x6_SRGB_BLOCK}, // ASTC_2D_8X6_SRGB | ||
| 203 | {VK_FORMAT_ASTC_6x5_UNORM_BLOCK}, // ASTC_2D_6X5_UNORM | ||
| 204 | {VK_FORMAT_ASTC_6x5_SRGB_BLOCK}, // ASTC_2D_6X5_SRGB | ||
| 205 | {VK_FORMAT_E5B9G9R9_UFLOAT_PACK32}, // E5B9G9R9_FLOAT | ||
| 195 | 206 | ||
| 196 | // Depth formats | 207 | // Depth formats |
| 197 | {VK_FORMAT_D32_SFLOAT, Attachable}, // Z32F | 208 | {VK_FORMAT_D32_SFLOAT, Attachable}, // D32_FLOAT |
| 198 | {VK_FORMAT_D16_UNORM, Attachable}, // Z16 | 209 | {VK_FORMAT_D16_UNORM, Attachable}, // D16_UNORM |
| 199 | 210 | ||
| 200 | // DepthStencil formats | 211 | // DepthStencil formats |
| 201 | {VK_FORMAT_D24_UNORM_S8_UINT, Attachable}, // Z24S8 | 212 | {VK_FORMAT_D24_UNORM_S8_UINT, Attachable}, // D24_UNORM_S8_UINT |
| 202 | {VK_FORMAT_D24_UNORM_S8_UINT, Attachable}, // S8Z24 (emulated) | 213 | {VK_FORMAT_D24_UNORM_S8_UINT, Attachable}, // S8_UINT_D24_UNORM (emulated) |
| 203 | {VK_FORMAT_D32_SFLOAT_S8_UINT, Attachable}, // Z32FS8 | 214 | {VK_FORMAT_D32_SFLOAT_S8_UINT, Attachable}, // D32_FLOAT_S8_UINT |
| 204 | }; | 215 | }; |
| 205 | static_assert(std::size(tex_format_tuples) == VideoCore::Surface::MaxPixelFormat); | 216 | static_assert(std::size(tex_format_tuples) == VideoCore::Surface::MaxPixelFormat); |
| 206 | 217 | ||
| @@ -221,7 +232,7 @@ FormatInfo SurfaceFormat(const VKDevice& device, FormatType format_type, PixelFo | |||
| 221 | return {VK_FORMAT_A8B8G8R8_UNORM_PACK32, true, true}; | 232 | return {VK_FORMAT_A8B8G8R8_UNORM_PACK32, true, true}; |
| 222 | } | 233 | } |
| 223 | 234 | ||
| 224 | // Use ABGR8 on hardware that doesn't support ASTC natively | 235 | // Use A8B8G8R8_UNORM on hardware that doesn't support ASTC natively |
| 225 | if (!device.IsOptimalAstcSupported() && VideoCore::Surface::IsPixelFormatASTC(pixel_format)) { | 236 | if (!device.IsOptimalAstcSupported() && VideoCore::Surface::IsPixelFormatASTC(pixel_format)) { |
| 226 | tuple.format = VideoCore::Surface::IsPixelFormatSRGB(pixel_format) | 237 | tuple.format = VideoCore::Surface::IsPixelFormatSRGB(pixel_format) |
| 227 | ? VK_FORMAT_A8B8G8R8_SRGB_PACK32 | 238 | ? VK_FORMAT_A8B8G8R8_SRGB_PACK32 |
diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.cpp b/src/video_core/renderer_vulkan/vk_blit_screen.cpp index 866813465..ce53e5a6b 100644 --- a/src/video_core/renderer_vulkan/vk_blit_screen.cpp +++ b/src/video_core/renderer_vulkan/vk_blit_screen.cpp | |||
| @@ -187,9 +187,9 @@ std::size_t GetSizeInBytes(const Tegra::FramebufferConfig& framebuffer) { | |||
| 187 | 187 | ||
| 188 | VkFormat GetFormat(const Tegra::FramebufferConfig& framebuffer) { | 188 | VkFormat GetFormat(const Tegra::FramebufferConfig& framebuffer) { |
| 189 | switch (framebuffer.pixel_format) { | 189 | switch (framebuffer.pixel_format) { |
| 190 | case Tegra::FramebufferConfig::PixelFormat::ABGR8: | 190 | case Tegra::FramebufferConfig::PixelFormat::A8B8G8R8_UNORM: |
| 191 | return VK_FORMAT_A8B8G8R8_UNORM_PACK32; | 191 | return VK_FORMAT_A8B8G8R8_UNORM_PACK32; |
| 192 | case Tegra::FramebufferConfig::PixelFormat::RGB565: | 192 | case Tegra::FramebufferConfig::PixelFormat::RGB565_UNORM: |
| 193 | return VK_FORMAT_R5G6B5_UNORM_PACK16; | 193 | return VK_FORMAT_R5G6B5_UNORM_PACK16; |
| 194 | default: | 194 | default: |
| 195 | UNIMPLEMENTED_MSG("Unknown framebuffer pixel format: {}", | 195 | UNIMPLEMENTED_MSG("Unknown framebuffer pixel format: {}", |
diff --git a/src/video_core/renderer_vulkan/vk_device.cpp b/src/video_core/renderer_vulkan/vk_device.cpp index 26379ee01..6245e0d78 100644 --- a/src/video_core/renderer_vulkan/vk_device.cpp +++ b/src/video_core/renderer_vulkan/vk_device.cpp | |||
| @@ -84,14 +84,19 @@ std::unordered_map<VkFormat, VkFormatProperties> GetFormatProperties( | |||
| 84 | VK_FORMAT_A8B8G8R8_UNORM_PACK32, | 84 | VK_FORMAT_A8B8G8R8_UNORM_PACK32, |
| 85 | VK_FORMAT_A8B8G8R8_UINT_PACK32, | 85 | VK_FORMAT_A8B8G8R8_UINT_PACK32, |
| 86 | VK_FORMAT_A8B8G8R8_SNORM_PACK32, | 86 | VK_FORMAT_A8B8G8R8_SNORM_PACK32, |
| 87 | VK_FORMAT_A8B8G8R8_SINT_PACK32, | ||
| 87 | VK_FORMAT_A8B8G8R8_SRGB_PACK32, | 88 | VK_FORMAT_A8B8G8R8_SRGB_PACK32, |
| 88 | VK_FORMAT_B5G6R5_UNORM_PACK16, | 89 | VK_FORMAT_B5G6R5_UNORM_PACK16, |
| 89 | VK_FORMAT_A2B10G10R10_UNORM_PACK32, | 90 | VK_FORMAT_A2B10G10R10_UNORM_PACK32, |
| 91 | VK_FORMAT_A2B10G10R10_UINT_PACK32, | ||
| 90 | VK_FORMAT_A1R5G5B5_UNORM_PACK16, | 92 | VK_FORMAT_A1R5G5B5_UNORM_PACK16, |
| 91 | VK_FORMAT_R32G32B32A32_SFLOAT, | 93 | VK_FORMAT_R32G32B32A32_SFLOAT, |
| 94 | VK_FORMAT_R32G32B32A32_SINT, | ||
| 92 | VK_FORMAT_R32G32B32A32_UINT, | 95 | VK_FORMAT_R32G32B32A32_UINT, |
| 93 | VK_FORMAT_R32G32_SFLOAT, | 96 | VK_FORMAT_R32G32_SFLOAT, |
| 97 | VK_FORMAT_R32G32_SINT, | ||
| 94 | VK_FORMAT_R32G32_UINT, | 98 | VK_FORMAT_R32G32_UINT, |
| 99 | VK_FORMAT_R16G16B16A16_SINT, | ||
| 95 | VK_FORMAT_R16G16B16A16_UINT, | 100 | VK_FORMAT_R16G16B16A16_UINT, |
| 96 | VK_FORMAT_R16G16B16A16_SNORM, | 101 | VK_FORMAT_R16G16B16A16_SNORM, |
| 97 | VK_FORMAT_R16G16B16A16_UNORM, | 102 | VK_FORMAT_R16G16B16A16_UNORM, |
| @@ -103,8 +108,11 @@ std::unordered_map<VkFormat, VkFormatProperties> GetFormatProperties( | |||
| 103 | VK_FORMAT_R8G8B8A8_SRGB, | 108 | VK_FORMAT_R8G8B8A8_SRGB, |
| 104 | VK_FORMAT_R8G8_UNORM, | 109 | VK_FORMAT_R8G8_UNORM, |
| 105 | VK_FORMAT_R8G8_SNORM, | 110 | VK_FORMAT_R8G8_SNORM, |
| 111 | VK_FORMAT_R8G8_SINT, | ||
| 106 | VK_FORMAT_R8G8_UINT, | 112 | VK_FORMAT_R8G8_UINT, |
| 107 | VK_FORMAT_R8_UNORM, | 113 | VK_FORMAT_R8_UNORM, |
| 114 | VK_FORMAT_R8_SNORM, | ||
| 115 | VK_FORMAT_R8_SINT, | ||
| 108 | VK_FORMAT_R8_UINT, | 116 | VK_FORMAT_R8_UINT, |
| 109 | VK_FORMAT_B10G11R11_UFLOAT_PACK32, | 117 | VK_FORMAT_B10G11R11_UFLOAT_PACK32, |
| 110 | VK_FORMAT_R32_SFLOAT, | 118 | VK_FORMAT_R32_SFLOAT, |
| @@ -124,6 +132,7 @@ std::unordered_map<VkFormat, VkFormatProperties> GetFormatProperties( | |||
| 124 | VK_FORMAT_BC2_UNORM_BLOCK, | 132 | VK_FORMAT_BC2_UNORM_BLOCK, |
| 125 | VK_FORMAT_BC3_UNORM_BLOCK, | 133 | VK_FORMAT_BC3_UNORM_BLOCK, |
| 126 | VK_FORMAT_BC4_UNORM_BLOCK, | 134 | VK_FORMAT_BC4_UNORM_BLOCK, |
| 135 | VK_FORMAT_BC4_SNORM_BLOCK, | ||
| 127 | VK_FORMAT_BC5_UNORM_BLOCK, | 136 | VK_FORMAT_BC5_UNORM_BLOCK, |
| 128 | VK_FORMAT_BC5_SNORM_BLOCK, | 137 | VK_FORMAT_BC5_SNORM_BLOCK, |
| 129 | VK_FORMAT_BC7_UNORM_BLOCK, | 138 | VK_FORMAT_BC7_UNORM_BLOCK, |
diff --git a/src/video_core/renderer_vulkan/vk_device.h b/src/video_core/renderer_vulkan/vk_device.h index ae5c21baa..529744f2d 100644 --- a/src/video_core/renderer_vulkan/vk_device.h +++ b/src/video_core/renderer_vulkan/vk_device.h | |||
| @@ -122,6 +122,11 @@ public: | |||
| 122 | return properties.limits.maxPushConstantsSize; | 122 | return properties.limits.maxPushConstantsSize; |
| 123 | } | 123 | } |
| 124 | 124 | ||
| 125 | /// Returns the maximum size for shared memory. | ||
| 126 | u32 GetMaxComputeSharedMemorySize() const { | ||
| 127 | return properties.limits.maxComputeSharedMemorySize; | ||
| 128 | } | ||
| 129 | |||
| 125 | /// Returns true if ASTC is natively supported. | 130 | /// Returns true if ASTC is natively supported. |
| 126 | bool IsOptimalAstcSupported() const { | 131 | bool IsOptimalAstcSupported() const { |
| 127 | return is_optimal_astc_supported; | 132 | return is_optimal_astc_supported; |
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp index 97429cc59..cd7d7a4e4 100644 --- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp +++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp | |||
| @@ -685,13 +685,19 @@ private: | |||
| 685 | } | 685 | } |
| 686 | t_smem_uint = TypePointer(spv::StorageClass::Workgroup, t_uint); | 686 | t_smem_uint = TypePointer(spv::StorageClass::Workgroup, t_uint); |
| 687 | 687 | ||
| 688 | const u32 smem_size = specialization.shared_memory_size; | 688 | u32 smem_size = specialization.shared_memory_size * 4; |
| 689 | if (smem_size == 0) { | 689 | if (smem_size == 0) { |
| 690 | // Avoid declaring an empty array. | 690 | // Avoid declaring an empty array. |
| 691 | return; | 691 | return; |
| 692 | } | 692 | } |
| 693 | const auto element_count = static_cast<u32>(Common::AlignUp(smem_size, 4) / 4); | 693 | const u32 limit = device.GetMaxComputeSharedMemorySize(); |
| 694 | const Id type_array = TypeArray(t_uint, Constant(t_uint, element_count)); | 694 | if (smem_size > limit) { |
| 695 | LOG_ERROR(Render_Vulkan, "Shared memory size {} is clamped to host's limit {}", | ||
| 696 | smem_size, limit); | ||
| 697 | smem_size = limit; | ||
| 698 | } | ||
| 699 | |||
| 700 | const Id type_array = TypeArray(t_uint, Constant(t_uint, smem_size / 4)); | ||
| 695 | const Id type_pointer = TypePointer(spv::StorageClass::Workgroup, type_array); | 701 | const Id type_pointer = TypePointer(spv::StorageClass::Workgroup, type_array); |
| 696 | Name(type_pointer, "SharedMemory"); | 702 | Name(type_pointer, "SharedMemory"); |
| 697 | 703 | ||
| @@ -700,9 +706,9 @@ private: | |||
| 700 | } | 706 | } |
| 701 | 707 | ||
| 702 | void DeclareInternalFlags() { | 708 | void DeclareInternalFlags() { |
| 703 | constexpr std::array names = {"zero", "sign", "carry", "overflow"}; | 709 | static constexpr std::array names{"zero", "sign", "carry", "overflow"}; |
| 710 | |||
| 704 | for (std::size_t flag = 0; flag < INTERNAL_FLAGS_COUNT; ++flag) { | 711 | for (std::size_t flag = 0; flag < INTERNAL_FLAGS_COUNT; ++flag) { |
| 705 | const auto flag_code = static_cast<InternalFlag>(flag); | ||
| 706 | const Id id = OpVariable(t_prv_bool, spv::StorageClass::Private, v_false); | 712 | const Id id = OpVariable(t_prv_bool, spv::StorageClass::Private, v_false); |
| 707 | internal_flags[flag] = AddGlobalVariable(Name(id, names[flag])); | 713 | internal_flags[flag] = AddGlobalVariable(Name(id, names[flag])); |
| 708 | } | 714 | } |
| @@ -2798,7 +2804,6 @@ private: | |||
| 2798 | std::map<GlobalMemoryBase, Id> global_buffers; | 2804 | std::map<GlobalMemoryBase, Id> global_buffers; |
| 2799 | std::map<u32, TexelBuffer> uniform_texels; | 2805 | std::map<u32, TexelBuffer> uniform_texels; |
| 2800 | std::map<u32, SampledImage> sampled_images; | 2806 | std::map<u32, SampledImage> sampled_images; |
| 2801 | std::map<u32, TexelBuffer> storage_texels; | ||
| 2802 | std::map<u32, StorageImage> images; | 2807 | std::map<u32, StorageImage> images; |
| 2803 | 2808 | ||
| 2804 | std::array<Id, Maxwell::NumRenderTargets> frag_colors{}; | 2809 | std::array<Id, Maxwell::NumRenderTargets> frag_colors{}; |
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 9bc18c21a..d102e6d27 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp | |||
| @@ -235,7 +235,7 @@ void CachedSurface::UploadTexture(const std::vector<u8>& staging_buffer) { | |||
| 235 | void CachedSurface::DownloadTexture(std::vector<u8>& staging_buffer) { | 235 | void CachedSurface::DownloadTexture(std::vector<u8>& staging_buffer) { |
| 236 | UNIMPLEMENTED_IF(params.IsBuffer()); | 236 | UNIMPLEMENTED_IF(params.IsBuffer()); |
| 237 | 237 | ||
| 238 | if (params.pixel_format == VideoCore::Surface::PixelFormat::A1B5G5R5U) { | 238 | if (params.pixel_format == VideoCore::Surface::PixelFormat::A1B5G5R5_UNORM) { |
| 239 | LOG_WARNING(Render_Vulkan, "A1B5G5R5 flushing is stubbed"); | 239 | LOG_WARNING(Render_Vulkan, "A1B5G5R5 flushing is stubbed"); |
| 240 | } | 240 | } |
| 241 | 241 | ||
| @@ -385,7 +385,7 @@ VkImageView CachedSurfaceView::GetImageView(SwizzleSource x_source, SwizzleSourc | |||
| 385 | 385 | ||
| 386 | std::array swizzle{MaxwellToVK::SwizzleSource(x_source), MaxwellToVK::SwizzleSource(y_source), | 386 | std::array swizzle{MaxwellToVK::SwizzleSource(x_source), MaxwellToVK::SwizzleSource(y_source), |
| 387 | MaxwellToVK::SwizzleSource(z_source), MaxwellToVK::SwizzleSource(w_source)}; | 387 | MaxwellToVK::SwizzleSource(z_source), MaxwellToVK::SwizzleSource(w_source)}; |
| 388 | if (params.pixel_format == VideoCore::Surface::PixelFormat::A1B5G5R5U) { | 388 | if (params.pixel_format == VideoCore::Surface::PixelFormat::A1B5G5R5_UNORM) { |
| 389 | // A1B5G5R5 is implemented as A1R5G5B5, we have to change the swizzle here. | 389 | // A1B5G5R5 is implemented as A1R5G5B5, we have to change the swizzle here. |
| 390 | std::swap(swizzle[0], swizzle[2]); | 390 | std::swap(swizzle[0], swizzle[2]); |
| 391 | } | 391 | } |
| @@ -397,11 +397,11 @@ VkImageView CachedSurfaceView::GetImageView(SwizzleSource x_source, SwizzleSourc | |||
| 397 | UNIMPLEMENTED_IF(x_source != SwizzleSource::R && x_source != SwizzleSource::G); | 397 | UNIMPLEMENTED_IF(x_source != SwizzleSource::R && x_source != SwizzleSource::G); |
| 398 | const bool is_first = x_source == SwizzleSource::R; | 398 | const bool is_first = x_source == SwizzleSource::R; |
| 399 | switch (params.pixel_format) { | 399 | switch (params.pixel_format) { |
| 400 | case VideoCore::Surface::PixelFormat::Z24S8: | 400 | case VideoCore::Surface::PixelFormat::D24_UNORM_S8_UINT: |
| 401 | case VideoCore::Surface::PixelFormat::Z32FS8: | 401 | case VideoCore::Surface::PixelFormat::D32_FLOAT_S8_UINT: |
| 402 | aspect = is_first ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_STENCIL_BIT; | 402 | aspect = is_first ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_STENCIL_BIT; |
| 403 | break; | 403 | break; |
| 404 | case VideoCore::Surface::PixelFormat::S8Z24: | 404 | case VideoCore::Surface::PixelFormat::S8_UINT_D24_UNORM: |
| 405 | aspect = is_first ? VK_IMAGE_ASPECT_STENCIL_BIT : VK_IMAGE_ASPECT_DEPTH_BIT; | 405 | aspect = is_first ? VK_IMAGE_ASPECT_STENCIL_BIT : VK_IMAGE_ASPECT_DEPTH_BIT; |
| 406 | break; | 406 | break; |
| 407 | default: | 407 | default: |
diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index 07778dc3e..e75ca4fdb 100644 --- a/src/video_core/shader/decode/image.cpp +++ b/src/video_core/shader/decode/image.cpp | |||
| @@ -31,11 +31,11 @@ ComponentType GetComponentType(Tegra::Engines::SamplerDescriptor descriptor, | |||
| 31 | std::size_t component) { | 31 | std::size_t component) { |
| 32 | const TextureFormat format{descriptor.format}; | 32 | const TextureFormat format{descriptor.format}; |
| 33 | switch (format) { | 33 | switch (format) { |
| 34 | case TextureFormat::R16_G16_B16_A16: | 34 | case TextureFormat::R16G16B16A16: |
| 35 | case TextureFormat::R32_G32_B32_A32: | 35 | case TextureFormat::R32G32B32A32: |
| 36 | case TextureFormat::R32_G32_B32: | 36 | case TextureFormat::R32G32B32: |
| 37 | case TextureFormat::R32_G32: | 37 | case TextureFormat::R32G32: |
| 38 | case TextureFormat::R16_G16: | 38 | case TextureFormat::R16G16: |
| 39 | case TextureFormat::R32: | 39 | case TextureFormat::R32: |
| 40 | case TextureFormat::R16: | 40 | case TextureFormat::R16: |
| 41 | case TextureFormat::R8: | 41 | case TextureFormat::R8: |
| @@ -97,7 +97,7 @@ ComponentType GetComponentType(Tegra::Engines::SamplerDescriptor descriptor, | |||
| 97 | break; | 97 | break; |
| 98 | case TextureFormat::B5G6R5: | 98 | case TextureFormat::B5G6R5: |
| 99 | case TextureFormat::B6G5R5: | 99 | case TextureFormat::B6G5R5: |
| 100 | case TextureFormat::BF10GF11RF11: | 100 | case TextureFormat::B10G11R11: |
| 101 | if (component == 0) { | 101 | if (component == 0) { |
| 102 | return descriptor.b_type; | 102 | return descriptor.b_type; |
| 103 | } | 103 | } |
| @@ -108,9 +108,9 @@ ComponentType GetComponentType(Tegra::Engines::SamplerDescriptor descriptor, | |||
| 108 | return descriptor.r_type; | 108 | return descriptor.r_type; |
| 109 | } | 109 | } |
| 110 | break; | 110 | break; |
| 111 | case TextureFormat::G8R24: | 111 | case TextureFormat::R24G8: |
| 112 | case TextureFormat::G24R8: | 112 | case TextureFormat::R8G24: |
| 113 | case TextureFormat::G8R8: | 113 | case TextureFormat::R8G8: |
| 114 | case TextureFormat::G4R4: | 114 | case TextureFormat::G4R4: |
| 115 | if (component == 0) { | 115 | if (component == 0) { |
| 116 | return descriptor.g_type; | 116 | return descriptor.g_type; |
| @@ -137,15 +137,15 @@ bool IsComponentEnabled(std::size_t component_mask, std::size_t component) { | |||
| 137 | 137 | ||
| 138 | u32 GetComponentSize(TextureFormat format, std::size_t component) { | 138 | u32 GetComponentSize(TextureFormat format, std::size_t component) { |
| 139 | switch (format) { | 139 | switch (format) { |
| 140 | case TextureFormat::R32_G32_B32_A32: | 140 | case TextureFormat::R32G32B32A32: |
| 141 | return 32; | 141 | return 32; |
| 142 | case TextureFormat::R16_G16_B16_A16: | 142 | case TextureFormat::R16G16B16A16: |
| 143 | return 16; | 143 | return 16; |
| 144 | case TextureFormat::R32_G32_B32: | 144 | case TextureFormat::R32G32B32: |
| 145 | return component <= 2 ? 32 : 0; | 145 | return component <= 2 ? 32 : 0; |
| 146 | case TextureFormat::R32_G32: | 146 | case TextureFormat::R32G32: |
| 147 | return component <= 1 ? 32 : 0; | 147 | return component <= 1 ? 32 : 0; |
| 148 | case TextureFormat::R16_G16: | 148 | case TextureFormat::R16G16: |
| 149 | return component <= 1 ? 16 : 0; | 149 | return component <= 1 ? 16 : 0; |
| 150 | case TextureFormat::R32: | 150 | case TextureFormat::R32: |
| 151 | return component == 0 ? 32 : 0; | 151 | return component == 0 ? 32 : 0; |
| @@ -192,7 +192,7 @@ u32 GetComponentSize(TextureFormat format, std::size_t component) { | |||
| 192 | return 6; | 192 | return 6; |
| 193 | } | 193 | } |
| 194 | return 0; | 194 | return 0; |
| 195 | case TextureFormat::BF10GF11RF11: | 195 | case TextureFormat::B10G11R11: |
| 196 | if (component == 1 || component == 2) { | 196 | if (component == 1 || component == 2) { |
| 197 | return 11; | 197 | return 11; |
| 198 | } | 198 | } |
| @@ -200,7 +200,7 @@ u32 GetComponentSize(TextureFormat format, std::size_t component) { | |||
| 200 | return 10; | 200 | return 10; |
| 201 | } | 201 | } |
| 202 | return 0; | 202 | return 0; |
| 203 | case TextureFormat::G8R24: | 203 | case TextureFormat::R24G8: |
| 204 | if (component == 0) { | 204 | if (component == 0) { |
| 205 | return 8; | 205 | return 8; |
| 206 | } | 206 | } |
| @@ -208,7 +208,7 @@ u32 GetComponentSize(TextureFormat format, std::size_t component) { | |||
| 208 | return 24; | 208 | return 24; |
| 209 | } | 209 | } |
| 210 | return 0; | 210 | return 0; |
| 211 | case TextureFormat::G24R8: | 211 | case TextureFormat::R8G24: |
| 212 | if (component == 0) { | 212 | if (component == 0) { |
| 213 | return 8; | 213 | return 8; |
| 214 | } | 214 | } |
| @@ -216,7 +216,7 @@ u32 GetComponentSize(TextureFormat format, std::size_t component) { | |||
| 216 | return 24; | 216 | return 24; |
| 217 | } | 217 | } |
| 218 | return 0; | 218 | return 0; |
| 219 | case TextureFormat::G8R8: | 219 | case TextureFormat::R8G8: |
| 220 | return (component == 0 || component == 1) ? 8 : 0; | 220 | return (component == 0 || component == 1) ? 8 : 0; |
| 221 | case TextureFormat::G4R4: | 221 | case TextureFormat::G4R4: |
| 222 | return (component == 0 || component == 1) ? 4 : 0; | 222 | return (component == 0 || component == 1) ? 4 : 0; |
| @@ -231,25 +231,25 @@ std::size_t GetImageComponentMask(TextureFormat format) { | |||
| 231 | constexpr u8 B = 0b0100; | 231 | constexpr u8 B = 0b0100; |
| 232 | constexpr u8 A = 0b1000; | 232 | constexpr u8 A = 0b1000; |
| 233 | switch (format) { | 233 | switch (format) { |
| 234 | case TextureFormat::R32_G32_B32_A32: | 234 | case TextureFormat::R32G32B32A32: |
| 235 | case TextureFormat::R16_G16_B16_A16: | 235 | case TextureFormat::R16G16B16A16: |
| 236 | case TextureFormat::A8R8G8B8: | 236 | case TextureFormat::A8R8G8B8: |
| 237 | case TextureFormat::A2B10G10R10: | 237 | case TextureFormat::A2B10G10R10: |
| 238 | case TextureFormat::A4B4G4R4: | 238 | case TextureFormat::A4B4G4R4: |
| 239 | case TextureFormat::A5B5G5R1: | 239 | case TextureFormat::A5B5G5R1: |
| 240 | case TextureFormat::A1B5G5R5: | 240 | case TextureFormat::A1B5G5R5: |
| 241 | return std::size_t{R | G | B | A}; | 241 | return std::size_t{R | G | B | A}; |
| 242 | case TextureFormat::R32_G32_B32: | 242 | case TextureFormat::R32G32B32: |
| 243 | case TextureFormat::R32_B24G8: | 243 | case TextureFormat::R32_B24G8: |
| 244 | case TextureFormat::B5G6R5: | 244 | case TextureFormat::B5G6R5: |
| 245 | case TextureFormat::B6G5R5: | 245 | case TextureFormat::B6G5R5: |
| 246 | case TextureFormat::BF10GF11RF11: | 246 | case TextureFormat::B10G11R11: |
| 247 | return std::size_t{R | G | B}; | 247 | return std::size_t{R | G | B}; |
| 248 | case TextureFormat::R32_G32: | 248 | case TextureFormat::R32G32: |
| 249 | case TextureFormat::R16_G16: | 249 | case TextureFormat::R16G16: |
| 250 | case TextureFormat::G8R24: | 250 | case TextureFormat::R24G8: |
| 251 | case TextureFormat::G24R8: | 251 | case TextureFormat::R8G24: |
| 252 | case TextureFormat::G8R8: | 252 | case TextureFormat::R8G8: |
| 253 | case TextureFormat::G4R4: | 253 | case TextureFormat::G4R4: |
| 254 | return std::size_t{R | G}; | 254 | return std::size_t{R | G}; |
| 255 | case TextureFormat::R32: | 255 | case TextureFormat::R32: |
diff --git a/src/video_core/shader/decode/other.cpp b/src/video_core/shader/decode/other.cpp index c0a8f233f..29a7cfbfe 100644 --- a/src/video_core/shader/decode/other.cpp +++ b/src/video_core/shader/decode/other.cpp | |||
| @@ -75,8 +75,7 @@ u32 ShaderIR::DecodeOther(NodeBlock& bb, u32 pc) { | |||
| 75 | const Node value = [this, instr] { | 75 | const Node value = [this, instr] { |
| 76 | switch (instr.sys20) { | 76 | switch (instr.sys20) { |
| 77 | case SystemVariable::LaneId: | 77 | case SystemVariable::LaneId: |
| 78 | LOG_WARNING(HW_GPU, "S2R instruction with LaneId is incomplete"); | 78 | return Operation(OperationCode::ThreadId); |
| 79 | return Immediate(0U); | ||
| 80 | case SystemVariable::InvocationId: | 79 | case SystemVariable::InvocationId: |
| 81 | return Operation(OperationCode::InvocationId); | 80 | return Operation(OperationCode::InvocationId); |
| 82 | case SystemVariable::Ydirection: | 81 | case SystemVariable::Ydirection: |
diff --git a/src/video_core/surface.cpp b/src/video_core/surface.cpp index bbe93903c..1688267bb 100644 --- a/src/video_core/surface.cpp +++ b/src/video_core/surface.cpp | |||
| @@ -74,117 +74,131 @@ bool SurfaceTargetIsArray(SurfaceTarget target) { | |||
| 74 | 74 | ||
| 75 | PixelFormat PixelFormatFromDepthFormat(Tegra::DepthFormat format) { | 75 | PixelFormat PixelFormatFromDepthFormat(Tegra::DepthFormat format) { |
| 76 | switch (format) { | 76 | switch (format) { |
| 77 | case Tegra::DepthFormat::S8_Z24_UNORM: | 77 | case Tegra::DepthFormat::S8_UINT_Z24_UNORM: |
| 78 | return PixelFormat::S8Z24; | 78 | return PixelFormat::S8_UINT_D24_UNORM; |
| 79 | case Tegra::DepthFormat::Z24_S8_UNORM: | 79 | case Tegra::DepthFormat::D24S8_UNORM: |
| 80 | return PixelFormat::Z24S8; | 80 | return PixelFormat::D24_UNORM_S8_UINT; |
| 81 | case Tegra::DepthFormat::Z32_FLOAT: | 81 | case Tegra::DepthFormat::D32_FLOAT: |
| 82 | return PixelFormat::Z32F; | 82 | return PixelFormat::D32_FLOAT; |
| 83 | case Tegra::DepthFormat::Z16_UNORM: | 83 | case Tegra::DepthFormat::D16_UNORM: |
| 84 | return PixelFormat::Z16; | 84 | return PixelFormat::D16_UNORM; |
| 85 | case Tegra::DepthFormat::Z32_S8_X24_FLOAT: | 85 | case Tegra::DepthFormat::D32_FLOAT_S8X24_UINT: |
| 86 | return PixelFormat::Z32FS8; | 86 | return PixelFormat::D32_FLOAT_S8_UINT; |
| 87 | default: | 87 | default: |
| 88 | LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format)); | 88 | UNIMPLEMENTED_MSG("Unimplemented format={}", static_cast<u32>(format)); |
| 89 | UNREACHABLE(); | 89 | return PixelFormat::S8_UINT_D24_UNORM; |
| 90 | return PixelFormat::S8Z24; | ||
| 91 | } | 90 | } |
| 92 | } | 91 | } |
| 93 | 92 | ||
| 94 | PixelFormat PixelFormatFromRenderTargetFormat(Tegra::RenderTargetFormat format) { | 93 | PixelFormat PixelFormatFromRenderTargetFormat(Tegra::RenderTargetFormat format) { |
| 95 | switch (format) { | 94 | switch (format) { |
| 96 | case Tegra::RenderTargetFormat::RGBA8_SRGB: | 95 | case Tegra::RenderTargetFormat::R32B32G32A32_FLOAT: |
| 97 | return PixelFormat::RGBA8_SRGB; | 96 | return PixelFormat::R32G32B32A32_FLOAT; |
| 98 | case Tegra::RenderTargetFormat::RGBA8_UNORM: | 97 | case Tegra::RenderTargetFormat::R32G32B32A32_SINT: |
| 99 | return PixelFormat::ABGR8U; | 98 | return PixelFormat::R32G32B32A32_SINT; |
| 100 | case Tegra::RenderTargetFormat::RGBA8_SNORM: | 99 | case Tegra::RenderTargetFormat::R32G32B32A32_UINT: |
| 101 | return PixelFormat::ABGR8S; | 100 | return PixelFormat::R32G32B32A32_UINT; |
| 102 | case Tegra::RenderTargetFormat::RGBA8_UINT: | 101 | case Tegra::RenderTargetFormat::R16G16B16A16_UNORM: |
| 103 | return PixelFormat::ABGR8UI; | 102 | return PixelFormat::R16G16B16A16_UNORM; |
| 104 | case Tegra::RenderTargetFormat::BGRA8_SRGB: | 103 | case Tegra::RenderTargetFormat::R16G16B16A16_SNORM: |
| 105 | return PixelFormat::BGRA8_SRGB; | 104 | return PixelFormat::R16G16B16A16_SNORM; |
| 106 | case Tegra::RenderTargetFormat::BGRA8_UNORM: | 105 | case Tegra::RenderTargetFormat::R16G16B16A16_SINT: |
| 107 | return PixelFormat::BGRA8; | 106 | return PixelFormat::R16G16B16A16_SINT; |
| 108 | case Tegra::RenderTargetFormat::RGB10_A2_UNORM: | 107 | case Tegra::RenderTargetFormat::R16G16B16A16_UINT: |
| 109 | return PixelFormat::A2B10G10R10U; | 108 | return PixelFormat::R16G16B16A16_UINT; |
| 110 | case Tegra::RenderTargetFormat::RGBA16_FLOAT: | 109 | case Tegra::RenderTargetFormat::R16G16B16A16_FLOAT: |
| 111 | return PixelFormat::RGBA16F; | 110 | return PixelFormat::R16G16B16A16_FLOAT; |
| 112 | case Tegra::RenderTargetFormat::RGBA16_UNORM: | 111 | case Tegra::RenderTargetFormat::R32G32_FLOAT: |
| 113 | return PixelFormat::RGBA16U; | 112 | return PixelFormat::R32G32_FLOAT; |
| 114 | case Tegra::RenderTargetFormat::RGBA16_SNORM: | 113 | case Tegra::RenderTargetFormat::R32G32_SINT: |
| 115 | return PixelFormat::RGBA16S; | 114 | return PixelFormat::R32G32_SINT; |
| 116 | case Tegra::RenderTargetFormat::RGBA16_UINT: | 115 | case Tegra::RenderTargetFormat::R32G32_UINT: |
| 117 | return PixelFormat::RGBA16UI; | 116 | return PixelFormat::R32G32_UINT; |
| 118 | case Tegra::RenderTargetFormat::RGBA32_FLOAT: | 117 | case Tegra::RenderTargetFormat::R16G16B16X16_FLOAT: |
| 119 | return PixelFormat::RGBA32F; | 118 | return PixelFormat::R16G16B16X16_FLOAT; |
| 120 | case Tegra::RenderTargetFormat::RG32_FLOAT: | 119 | case Tegra::RenderTargetFormat::B8G8R8A8_UNORM: |
| 121 | return PixelFormat::RG32F; | 120 | return PixelFormat::B8G8R8A8_UNORM; |
| 122 | case Tegra::RenderTargetFormat::R11G11B10_FLOAT: | 121 | case Tegra::RenderTargetFormat::B8G8R8A8_SRGB: |
| 123 | return PixelFormat::R11FG11FB10F; | 122 | return PixelFormat::B8G8R8A8_SRGB; |
| 124 | case Tegra::RenderTargetFormat::B5G6R5_UNORM: | 123 | case Tegra::RenderTargetFormat::A2B10G10R10_UNORM: |
| 125 | return PixelFormat::B5G6R5U; | 124 | return PixelFormat::A2B10G10R10_UNORM; |
| 126 | case Tegra::RenderTargetFormat::BGR5A1_UNORM: | 125 | case Tegra::RenderTargetFormat::A2B10G10R10_UINT: |
| 127 | return PixelFormat::A1B5G5R5U; | 126 | return PixelFormat::A2B10G10R10_UINT; |
| 128 | case Tegra::RenderTargetFormat::RGBA32_UINT: | 127 | case Tegra::RenderTargetFormat::A8B8G8R8_UNORM: |
| 129 | return PixelFormat::RGBA32UI; | 128 | return PixelFormat::A8B8G8R8_UNORM; |
| 130 | case Tegra::RenderTargetFormat::R8_UNORM: | 129 | case Tegra::RenderTargetFormat::A8B8G8R8_SRGB: |
| 131 | return PixelFormat::R8U; | 130 | return PixelFormat::A8B8G8R8_SRGB; |
| 132 | case Tegra::RenderTargetFormat::R8_UINT: | 131 | case Tegra::RenderTargetFormat::A8B8G8R8_SNORM: |
| 133 | return PixelFormat::R8UI; | 132 | return PixelFormat::A8B8G8R8_SNORM; |
| 134 | case Tegra::RenderTargetFormat::RG16_FLOAT: | 133 | case Tegra::RenderTargetFormat::A8B8G8R8_SINT: |
| 135 | return PixelFormat::RG16F; | 134 | return PixelFormat::A8B8G8R8_SINT; |
| 136 | case Tegra::RenderTargetFormat::RG16_UINT: | 135 | case Tegra::RenderTargetFormat::A8B8G8R8_UINT: |
| 137 | return PixelFormat::RG16UI; | 136 | return PixelFormat::A8B8G8R8_UINT; |
| 138 | case Tegra::RenderTargetFormat::RG16_SINT: | 137 | case Tegra::RenderTargetFormat::R16G16_UNORM: |
| 139 | return PixelFormat::RG16I; | 138 | return PixelFormat::R16G16_UNORM; |
| 140 | case Tegra::RenderTargetFormat::RG16_UNORM: | 139 | case Tegra::RenderTargetFormat::R16G16_SNORM: |
| 141 | return PixelFormat::RG16; | 140 | return PixelFormat::R16G16_SNORM; |
| 142 | case Tegra::RenderTargetFormat::RG16_SNORM: | 141 | case Tegra::RenderTargetFormat::R16G16_SINT: |
| 143 | return PixelFormat::RG16S; | 142 | return PixelFormat::R16G16_SINT; |
| 144 | case Tegra::RenderTargetFormat::RG8_UNORM: | 143 | case Tegra::RenderTargetFormat::R16G16_UINT: |
| 145 | return PixelFormat::RG8U; | 144 | return PixelFormat::R16G16_UINT; |
| 146 | case Tegra::RenderTargetFormat::RG8_SNORM: | 145 | case Tegra::RenderTargetFormat::R16G16_FLOAT: |
| 147 | return PixelFormat::RG8S; | 146 | return PixelFormat::R16G16_FLOAT; |
| 148 | case Tegra::RenderTargetFormat::RG8_UINT: | 147 | case Tegra::RenderTargetFormat::B10G11R11_FLOAT: |
| 149 | return PixelFormat::RG8UI; | 148 | return PixelFormat::B10G11R11_FLOAT; |
| 150 | case Tegra::RenderTargetFormat::R16_FLOAT: | 149 | case Tegra::RenderTargetFormat::R32_SINT: |
| 151 | return PixelFormat::R16F; | 150 | return PixelFormat::R32_SINT; |
| 151 | case Tegra::RenderTargetFormat::R32_UINT: | ||
| 152 | return PixelFormat::R32_UINT; | ||
| 153 | case Tegra::RenderTargetFormat::R32_FLOAT: | ||
| 154 | return PixelFormat::R32_FLOAT; | ||
| 155 | case Tegra::RenderTargetFormat::R5G6B5_UNORM: | ||
| 156 | return PixelFormat::R5G6B5_UNORM; | ||
| 157 | case Tegra::RenderTargetFormat::A1R5G5B5_UNORM: | ||
| 158 | return PixelFormat::A1R5G5B5_UNORM; | ||
| 159 | case Tegra::RenderTargetFormat::R8G8_UNORM: | ||
| 160 | return PixelFormat::R8G8_UNORM; | ||
| 161 | case Tegra::RenderTargetFormat::R8G8_SNORM: | ||
| 162 | return PixelFormat::R8G8_SNORM; | ||
| 163 | case Tegra::RenderTargetFormat::R8G8_SINT: | ||
| 164 | return PixelFormat::R8G8_SINT; | ||
| 165 | case Tegra::RenderTargetFormat::R8G8_UINT: | ||
| 166 | return PixelFormat::R8G8_UINT; | ||
| 152 | case Tegra::RenderTargetFormat::R16_UNORM: | 167 | case Tegra::RenderTargetFormat::R16_UNORM: |
| 153 | return PixelFormat::R16U; | 168 | return PixelFormat::R16_UNORM; |
| 154 | case Tegra::RenderTargetFormat::R16_SNORM: | 169 | case Tegra::RenderTargetFormat::R16_SNORM: |
| 155 | return PixelFormat::R16S; | 170 | return PixelFormat::R16_SNORM; |
| 156 | case Tegra::RenderTargetFormat::R16_UINT: | ||
| 157 | return PixelFormat::R16UI; | ||
| 158 | case Tegra::RenderTargetFormat::R16_SINT: | 171 | case Tegra::RenderTargetFormat::R16_SINT: |
| 159 | return PixelFormat::R16I; | 172 | return PixelFormat::R16_SINT; |
| 160 | case Tegra::RenderTargetFormat::R32_FLOAT: | 173 | case Tegra::RenderTargetFormat::R16_UINT: |
| 161 | return PixelFormat::R32F; | 174 | return PixelFormat::R16_UINT; |
| 162 | case Tegra::RenderTargetFormat::R32_SINT: | 175 | case Tegra::RenderTargetFormat::R16_FLOAT: |
| 163 | return PixelFormat::R32I; | 176 | return PixelFormat::R16_FLOAT; |
| 164 | case Tegra::RenderTargetFormat::R32_UINT: | 177 | case Tegra::RenderTargetFormat::R8_UNORM: |
| 165 | return PixelFormat::R32UI; | 178 | return PixelFormat::R8_UNORM; |
| 166 | case Tegra::RenderTargetFormat::RG32_UINT: | 179 | case Tegra::RenderTargetFormat::R8_SNORM: |
| 167 | return PixelFormat::RG32UI; | 180 | return PixelFormat::R8_SNORM; |
| 168 | case Tegra::RenderTargetFormat::RGBX16_FLOAT: | 181 | case Tegra::RenderTargetFormat::R8_SINT: |
| 169 | return PixelFormat::RGBX16F; | 182 | return PixelFormat::R8_SINT; |
| 183 | case Tegra::RenderTargetFormat::R8_UINT: | ||
| 184 | return PixelFormat::R8_UINT; | ||
| 170 | default: | 185 | default: |
| 171 | LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format)); | 186 | UNIMPLEMENTED_MSG("Unimplemented format={}", static_cast<int>(format)); |
| 172 | UNREACHABLE(); | 187 | return PixelFormat::A8B8G8R8_UNORM; |
| 173 | return PixelFormat::RGBA8_SRGB; | ||
| 174 | } | 188 | } |
| 175 | } | 189 | } |
| 176 | 190 | ||
| 177 | PixelFormat PixelFormatFromGPUPixelFormat(Tegra::FramebufferConfig::PixelFormat format) { | 191 | PixelFormat PixelFormatFromGPUPixelFormat(Tegra::FramebufferConfig::PixelFormat format) { |
| 178 | switch (format) { | 192 | switch (format) { |
| 179 | case Tegra::FramebufferConfig::PixelFormat::ABGR8: | 193 | case Tegra::FramebufferConfig::PixelFormat::A8B8G8R8_UNORM: |
| 180 | return PixelFormat::ABGR8U; | 194 | return PixelFormat::A8B8G8R8_UNORM; |
| 181 | case Tegra::FramebufferConfig::PixelFormat::RGB565: | 195 | case Tegra::FramebufferConfig::PixelFormat::RGB565_UNORM: |
| 182 | return PixelFormat::B5G6R5U; | 196 | return PixelFormat::R5G6B5_UNORM; |
| 183 | case Tegra::FramebufferConfig::PixelFormat::BGRA8: | 197 | case Tegra::FramebufferConfig::PixelFormat::B8G8R8A8_UNORM: |
| 184 | return PixelFormat::BGRA8; | 198 | return PixelFormat::B8G8R8A8_UNORM; |
| 185 | default: | 199 | default: |
| 186 | UNIMPLEMENTED_MSG("Unimplemented format={}", static_cast<u32>(format)); | 200 | UNIMPLEMENTED_MSG("Unimplemented format={}", static_cast<u32>(format)); |
| 187 | return PixelFormat::ABGR8U; | 201 | return PixelFormat::A8B8G8R8_UNORM; |
| 188 | } | 202 | } |
| 189 | } | 203 | } |
| 190 | 204 | ||
| @@ -212,27 +226,27 @@ SurfaceType GetFormatType(PixelFormat pixel_format) { | |||
| 212 | 226 | ||
| 213 | bool IsPixelFormatASTC(PixelFormat format) { | 227 | bool IsPixelFormatASTC(PixelFormat format) { |
| 214 | switch (format) { | 228 | switch (format) { |
| 215 | case PixelFormat::ASTC_2D_4X4: | 229 | case PixelFormat::ASTC_2D_4X4_UNORM: |
| 216 | case PixelFormat::ASTC_2D_5X4: | 230 | case PixelFormat::ASTC_2D_5X4_UNORM: |
| 217 | case PixelFormat::ASTC_2D_5X5: | 231 | case PixelFormat::ASTC_2D_5X5_UNORM: |
| 218 | case PixelFormat::ASTC_2D_8X8: | 232 | case PixelFormat::ASTC_2D_8X8_UNORM: |
| 219 | case PixelFormat::ASTC_2D_8X5: | 233 | case PixelFormat::ASTC_2D_8X5_UNORM: |
| 220 | case PixelFormat::ASTC_2D_4X4_SRGB: | 234 | case PixelFormat::ASTC_2D_4X4_SRGB: |
| 221 | case PixelFormat::ASTC_2D_5X4_SRGB: | 235 | case PixelFormat::ASTC_2D_5X4_SRGB: |
| 222 | case PixelFormat::ASTC_2D_5X5_SRGB: | 236 | case PixelFormat::ASTC_2D_5X5_SRGB: |
| 223 | case PixelFormat::ASTC_2D_8X8_SRGB: | 237 | case PixelFormat::ASTC_2D_8X8_SRGB: |
| 224 | case PixelFormat::ASTC_2D_8X5_SRGB: | 238 | case PixelFormat::ASTC_2D_8X5_SRGB: |
| 225 | case PixelFormat::ASTC_2D_10X8: | 239 | case PixelFormat::ASTC_2D_10X8_UNORM: |
| 226 | case PixelFormat::ASTC_2D_10X8_SRGB: | 240 | case PixelFormat::ASTC_2D_10X8_SRGB: |
| 227 | case PixelFormat::ASTC_2D_6X6: | 241 | case PixelFormat::ASTC_2D_6X6_UNORM: |
| 228 | case PixelFormat::ASTC_2D_6X6_SRGB: | 242 | case PixelFormat::ASTC_2D_6X6_SRGB: |
| 229 | case PixelFormat::ASTC_2D_10X10: | 243 | case PixelFormat::ASTC_2D_10X10_UNORM: |
| 230 | case PixelFormat::ASTC_2D_10X10_SRGB: | 244 | case PixelFormat::ASTC_2D_10X10_SRGB: |
| 231 | case PixelFormat::ASTC_2D_12X12: | 245 | case PixelFormat::ASTC_2D_12X12_UNORM: |
| 232 | case PixelFormat::ASTC_2D_12X12_SRGB: | 246 | case PixelFormat::ASTC_2D_12X12_SRGB: |
| 233 | case PixelFormat::ASTC_2D_8X6: | 247 | case PixelFormat::ASTC_2D_8X6_UNORM: |
| 234 | case PixelFormat::ASTC_2D_8X6_SRGB: | 248 | case PixelFormat::ASTC_2D_8X6_SRGB: |
| 235 | case PixelFormat::ASTC_2D_6X5: | 249 | case PixelFormat::ASTC_2D_6X5_UNORM: |
| 236 | case PixelFormat::ASTC_2D_6X5_SRGB: | 250 | case PixelFormat::ASTC_2D_6X5_SRGB: |
| 237 | return true; | 251 | return true; |
| 238 | default: | 252 | default: |
| @@ -242,12 +256,12 @@ bool IsPixelFormatASTC(PixelFormat format) { | |||
| 242 | 256 | ||
| 243 | bool IsPixelFormatSRGB(PixelFormat format) { | 257 | bool IsPixelFormatSRGB(PixelFormat format) { |
| 244 | switch (format) { | 258 | switch (format) { |
| 245 | case PixelFormat::RGBA8_SRGB: | 259 | case PixelFormat::A8B8G8R8_SRGB: |
| 246 | case PixelFormat::BGRA8_SRGB: | 260 | case PixelFormat::B8G8R8A8_SRGB: |
| 247 | case PixelFormat::DXT1_SRGB: | 261 | case PixelFormat::BC1_RGBA_SRGB: |
| 248 | case PixelFormat::DXT23_SRGB: | 262 | case PixelFormat::BC2_SRGB: |
| 249 | case PixelFormat::DXT45_SRGB: | 263 | case PixelFormat::BC3_SRGB: |
| 250 | case PixelFormat::BC7U_SRGB: | 264 | case PixelFormat::BC7_SRGB: |
| 251 | case PixelFormat::ASTC_2D_4X4_SRGB: | 265 | case PixelFormat::ASTC_2D_4X4_SRGB: |
| 252 | case PixelFormat::ASTC_2D_8X8_SRGB: | 266 | case PixelFormat::ASTC_2D_8X8_SRGB: |
| 253 | case PixelFormat::ASTC_2D_8X5_SRGB: | 267 | case PixelFormat::ASTC_2D_8X5_SRGB: |
| @@ -269,25 +283,4 @@ std::pair<u32, u32> GetASTCBlockSize(PixelFormat format) { | |||
| 269 | return {GetDefaultBlockWidth(format), GetDefaultBlockHeight(format)}; | 283 | return {GetDefaultBlockWidth(format), GetDefaultBlockHeight(format)}; |
| 270 | } | 284 | } |
| 271 | 285 | ||
| 272 | bool IsFormatBCn(PixelFormat format) { | ||
| 273 | switch (format) { | ||
| 274 | case PixelFormat::DXT1: | ||
| 275 | case PixelFormat::DXT23: | ||
| 276 | case PixelFormat::DXT45: | ||
| 277 | case PixelFormat::DXN1: | ||
| 278 | case PixelFormat::DXN2SNORM: | ||
| 279 | case PixelFormat::DXN2UNORM: | ||
| 280 | case PixelFormat::BC7U: | ||
| 281 | case PixelFormat::BC6H_UF16: | ||
| 282 | case PixelFormat::BC6H_SF16: | ||
| 283 | case PixelFormat::DXT1_SRGB: | ||
| 284 | case PixelFormat::DXT23_SRGB: | ||
| 285 | case PixelFormat::DXT45_SRGB: | ||
| 286 | case PixelFormat::BC7U_SRGB: | ||
| 287 | return true; | ||
| 288 | default: | ||
| 289 | return false; | ||
| 290 | } | ||
| 291 | } | ||
| 292 | |||
| 293 | } // namespace VideoCore::Surface | 286 | } // namespace VideoCore::Surface |
diff --git a/src/video_core/surface.h b/src/video_core/surface.h index 6da6a1b97..cfd12fa61 100644 --- a/src/video_core/surface.h +++ b/src/video_core/surface.h | |||
| @@ -15,94 +15,105 @@ | |||
| 15 | namespace VideoCore::Surface { | 15 | namespace VideoCore::Surface { |
| 16 | 16 | ||
| 17 | enum class PixelFormat { | 17 | enum class PixelFormat { |
| 18 | ABGR8U = 0, | 18 | A8B8G8R8_UNORM, |
| 19 | ABGR8S = 1, | 19 | A8B8G8R8_SNORM, |
| 20 | ABGR8UI = 2, | 20 | A8B8G8R8_SINT, |
| 21 | B5G6R5U = 3, | 21 | A8B8G8R8_UINT, |
| 22 | A2B10G10R10U = 4, | 22 | R5G6B5_UNORM, |
| 23 | A1B5G5R5U = 5, | 23 | B5G6R5_UNORM, |
| 24 | R8U = 6, | 24 | A1R5G5B5_UNORM, |
| 25 | R8UI = 7, | 25 | A2B10G10R10_UNORM, |
| 26 | RGBA16F = 8, | 26 | A2B10G10R10_UINT, |
| 27 | RGBA16U = 9, | 27 | A1B5G5R5_UNORM, |
| 28 | RGBA16S = 10, | 28 | R8_UNORM, |
| 29 | RGBA16UI = 11, | 29 | R8_SNORM, |
| 30 | R11FG11FB10F = 12, | 30 | R8_SINT, |
| 31 | RGBA32UI = 13, | 31 | R8_UINT, |
| 32 | DXT1 = 14, | 32 | R16G16B16A16_FLOAT, |
| 33 | DXT23 = 15, | 33 | R16G16B16A16_UNORM, |
| 34 | DXT45 = 16, | 34 | R16G16B16A16_SNORM, |
| 35 | DXN1 = 17, // This is also known as BC4 | 35 | R16G16B16A16_SINT, |
| 36 | DXN2UNORM = 18, | 36 | R16G16B16A16_UINT, |
| 37 | DXN2SNORM = 19, | 37 | B10G11R11_FLOAT, |
| 38 | BC7U = 20, | 38 | R32G32B32A32_UINT, |
| 39 | BC6H_UF16 = 21, | 39 | BC1_RGBA_UNORM, |
| 40 | BC6H_SF16 = 22, | 40 | BC2_UNORM, |
| 41 | ASTC_2D_4X4 = 23, | 41 | BC3_UNORM, |
| 42 | BGRA8 = 24, | 42 | BC4_UNORM, |
| 43 | RGBA32F = 25, | 43 | BC4_SNORM, |
| 44 | RG32F = 26, | 44 | BC5_UNORM, |
| 45 | R32F = 27, | 45 | BC5_SNORM, |
| 46 | R16F = 28, | 46 | BC7_UNORM, |
| 47 | R16U = 29, | 47 | BC6H_UFLOAT, |
| 48 | R16S = 30, | 48 | BC6H_SFLOAT, |
| 49 | R16UI = 31, | 49 | ASTC_2D_4X4_UNORM, |
| 50 | R16I = 32, | 50 | B8G8R8A8_UNORM, |
| 51 | RG16 = 33, | 51 | R32G32B32A32_FLOAT, |
| 52 | RG16F = 34, | 52 | R32G32B32A32_SINT, |
| 53 | RG16UI = 35, | 53 | R32G32_FLOAT, |
| 54 | RG16I = 36, | 54 | R32G32_SINT, |
| 55 | RG16S = 37, | 55 | R32_FLOAT, |
| 56 | RGB32F = 38, | 56 | R16_FLOAT, |
| 57 | RGBA8_SRGB = 39, | 57 | R16_UNORM, |
| 58 | RG8U = 40, | 58 | R16_SNORM, |
| 59 | RG8S = 41, | 59 | R16_UINT, |
| 60 | RG8UI = 42, | 60 | R16_SINT, |
| 61 | RG32UI = 43, | 61 | R16G16_UNORM, |
| 62 | RGBX16F = 44, | 62 | R16G16_FLOAT, |
| 63 | R32UI = 45, | 63 | R16G16_UINT, |
| 64 | R32I = 46, | 64 | R16G16_SINT, |
| 65 | ASTC_2D_8X8 = 47, | 65 | R16G16_SNORM, |
| 66 | ASTC_2D_8X5 = 48, | 66 | R32G32B32_FLOAT, |
| 67 | ASTC_2D_5X4 = 49, | 67 | A8B8G8R8_SRGB, |
| 68 | BGRA8_SRGB = 50, | 68 | R8G8_UNORM, |
| 69 | DXT1_SRGB = 51, | 69 | R8G8_SNORM, |
| 70 | DXT23_SRGB = 52, | 70 | R8G8_SINT, |
| 71 | DXT45_SRGB = 53, | 71 | R8G8_UINT, |
| 72 | BC7U_SRGB = 54, | 72 | R32G32_UINT, |
| 73 | R4G4B4A4U = 55, | 73 | R16G16B16X16_FLOAT, |
| 74 | ASTC_2D_4X4_SRGB = 56, | 74 | R32_UINT, |
| 75 | ASTC_2D_8X8_SRGB = 57, | 75 | R32_SINT, |
| 76 | ASTC_2D_8X5_SRGB = 58, | 76 | ASTC_2D_8X8_UNORM, |
| 77 | ASTC_2D_5X4_SRGB = 59, | 77 | ASTC_2D_8X5_UNORM, |
| 78 | ASTC_2D_5X5 = 60, | 78 | ASTC_2D_5X4_UNORM, |
| 79 | ASTC_2D_5X5_SRGB = 61, | 79 | B8G8R8A8_SRGB, |
| 80 | ASTC_2D_10X8 = 62, | 80 | BC1_RGBA_SRGB, |
| 81 | ASTC_2D_10X8_SRGB = 63, | 81 | BC2_SRGB, |
| 82 | ASTC_2D_6X6 = 64, | 82 | BC3_SRGB, |
| 83 | ASTC_2D_6X6_SRGB = 65, | 83 | BC7_SRGB, |
| 84 | ASTC_2D_10X10 = 66, | 84 | A4B4G4R4_UNORM, |
| 85 | ASTC_2D_10X10_SRGB = 67, | 85 | ASTC_2D_4X4_SRGB, |
| 86 | ASTC_2D_12X12 = 68, | 86 | ASTC_2D_8X8_SRGB, |
| 87 | ASTC_2D_12X12_SRGB = 69, | 87 | ASTC_2D_8X5_SRGB, |
| 88 | ASTC_2D_8X6 = 70, | 88 | ASTC_2D_5X4_SRGB, |
| 89 | ASTC_2D_8X6_SRGB = 71, | 89 | ASTC_2D_5X5_UNORM, |
| 90 | ASTC_2D_6X5 = 72, | 90 | ASTC_2D_5X5_SRGB, |
| 91 | ASTC_2D_6X5_SRGB = 73, | 91 | ASTC_2D_10X8_UNORM, |
| 92 | E5B9G9R9F = 74, | 92 | ASTC_2D_10X8_SRGB, |
| 93 | ASTC_2D_6X6_UNORM, | ||
| 94 | ASTC_2D_6X6_SRGB, | ||
| 95 | ASTC_2D_10X10_UNORM, | ||
| 96 | ASTC_2D_10X10_SRGB, | ||
| 97 | ASTC_2D_12X12_UNORM, | ||
| 98 | ASTC_2D_12X12_SRGB, | ||
| 99 | ASTC_2D_8X6_UNORM, | ||
| 100 | ASTC_2D_8X6_SRGB, | ||
| 101 | ASTC_2D_6X5_UNORM, | ||
| 102 | ASTC_2D_6X5_SRGB, | ||
| 103 | E5B9G9R9_FLOAT, | ||
| 93 | 104 | ||
| 94 | MaxColorFormat, | 105 | MaxColorFormat, |
| 95 | 106 | ||
| 96 | // Depth formats | 107 | // Depth formats |
| 97 | Z32F = 75, | 108 | D32_FLOAT = MaxColorFormat, |
| 98 | Z16 = 76, | 109 | D16_UNORM, |
| 99 | 110 | ||
| 100 | MaxDepthFormat, | 111 | MaxDepthFormat, |
| 101 | 112 | ||
| 102 | // DepthStencil formats | 113 | // DepthStencil formats |
| 103 | Z24S8 = 77, | 114 | D24_UNORM_S8_UINT = MaxDepthFormat, |
| 104 | S8Z24 = 78, | 115 | S8_UINT_D24_UNORM, |
| 105 | Z32FS8 = 79, | 116 | D32_FLOAT_S8_UINT, |
| 106 | 117 | ||
| 107 | MaxDepthStencilFormat, | 118 | MaxDepthStencilFormat, |
| 108 | 119 | ||
| @@ -130,86 +141,97 @@ enum class SurfaceTarget { | |||
| 130 | }; | 141 | }; |
| 131 | 142 | ||
| 132 | constexpr std::array<u32, MaxPixelFormat> compression_factor_shift_table = {{ | 143 | constexpr std::array<u32, MaxPixelFormat> compression_factor_shift_table = {{ |
| 133 | 0, // ABGR8U | 144 | 0, // A8B8G8R8_UNORM |
| 134 | 0, // ABGR8S | 145 | 0, // A8B8G8R8_SNORM |
| 135 | 0, // ABGR8UI | 146 | 0, // A8B8G8R8_SINT |
| 136 | 0, // B5G6R5U | 147 | 0, // A8B8G8R8_UINT |
| 137 | 0, // A2B10G10R10U | 148 | 0, // R5G6B5_UNORM |
| 138 | 0, // A1B5G5R5U | 149 | 0, // B5G6R5_UNORM |
| 139 | 0, // R8U | 150 | 0, // A1R5G5B5_UNORM |
| 140 | 0, // R8UI | 151 | 0, // A2B10G10R10_UNORM |
| 141 | 0, // RGBA16F | 152 | 0, // A2B10G10R10_UINT |
| 142 | 0, // RGBA16U | 153 | 0, // A1B5G5R5_UNORM |
| 143 | 0, // RGBA16S | 154 | 0, // R8_UNORM |
| 144 | 0, // RGBA16UI | 155 | 0, // R8_SNORM |
| 145 | 0, // R11FG11FB10F | 156 | 0, // R8_SINT |
| 146 | 0, // RGBA32UI | 157 | 0, // R8_UINT |
| 147 | 2, // DXT1 | 158 | 0, // R16G16B16A16_FLOAT |
| 148 | 2, // DXT23 | 159 | 0, // R16G16B16A16_UNORM |
| 149 | 2, // DXT45 | 160 | 0, // R16G16B16A16_SNORM |
| 150 | 2, // DXN1 | 161 | 0, // R16G16B16A16_SINT |
| 151 | 2, // DXN2UNORM | 162 | 0, // R16G16B16A16_UINT |
| 152 | 2, // DXN2SNORM | 163 | 0, // B10G11R11_FLOAT |
| 153 | 2, // BC7U | 164 | 0, // R32G32B32A32_UINT |
| 154 | 2, // BC6H_UF16 | 165 | 2, // BC1_RGBA_UNORM |
| 155 | 2, // BC6H_SF16 | 166 | 2, // BC2_UNORM |
| 156 | 2, // ASTC_2D_4X4 | 167 | 2, // BC3_UNORM |
| 157 | 0, // BGRA8 | 168 | 2, // BC4_UNORM |
| 158 | 0, // RGBA32F | 169 | 2, // BC4_SNORM |
| 159 | 0, // RG32F | 170 | 2, // BC5_UNORM |
| 160 | 0, // R32F | 171 | 2, // BC5_SNORM |
| 161 | 0, // R16F | 172 | 2, // BC7_UNORM |
| 162 | 0, // R16U | 173 | 2, // BC6H_UFLOAT |
| 163 | 0, // R16S | 174 | 2, // BC6H_SFLOAT |
| 164 | 0, // R16UI | 175 | 2, // ASTC_2D_4X4_UNORM |
| 165 | 0, // R16I | 176 | 0, // B8G8R8A8_UNORM |
| 166 | 0, // RG16 | 177 | 0, // R32G32B32A32_FLOAT |
| 167 | 0, // RG16F | 178 | 0, // R32G32B32A32_SINT |
| 168 | 0, // RG16UI | 179 | 0, // R32G32_FLOAT |
| 169 | 0, // RG16I | 180 | 0, // R32G32_SINT |
| 170 | 0, // RG16S | 181 | 0, // R32_FLOAT |
| 171 | 0, // RGB32F | 182 | 0, // R16_FLOAT |
| 172 | 0, // RGBA8_SRGB | 183 | 0, // R16_UNORM |
| 173 | 0, // RG8U | 184 | 0, // R16_SNORM |
| 174 | 0, // RG8S | 185 | 0, // R16_UINT |
| 175 | 0, // RG8UI | 186 | 0, // R16_SINT |
| 176 | 0, // RG32UI | 187 | 0, // R16G16_UNORM |
| 177 | 0, // RGBX16F | 188 | 0, // R16G16_FLOAT |
| 178 | 0, // R32UI | 189 | 0, // R16G16_UINT |
| 179 | 0, // R32I | 190 | 0, // R16G16_SINT |
| 180 | 2, // ASTC_2D_8X8 | 191 | 0, // R16G16_SNORM |
| 181 | 2, // ASTC_2D_8X5 | 192 | 0, // R32G32B32_FLOAT |
| 182 | 2, // ASTC_2D_5X4 | 193 | 0, // A8B8G8R8_SRGB |
| 183 | 0, // BGRA8_SRGB | 194 | 0, // R8G8_UNORM |
| 184 | 2, // DXT1_SRGB | 195 | 0, // R8G8_SNORM |
| 185 | 2, // DXT23_SRGB | 196 | 0, // R8G8_SINT |
| 186 | 2, // DXT45_SRGB | 197 | 0, // R8G8_UINT |
| 187 | 2, // BC7U_SRGB | 198 | 0, // R32G32_UINT |
| 188 | 0, // R4G4B4A4U | 199 | 0, // R16G16B16X16_FLOAT |
| 200 | 0, // R32_UINT | ||
| 201 | 0, // R32_SINT | ||
| 202 | 2, // ASTC_2D_8X8_UNORM | ||
| 203 | 2, // ASTC_2D_8X5_UNORM | ||
| 204 | 2, // ASTC_2D_5X4_UNORM | ||
| 205 | 0, // B8G8R8A8_SRGB | ||
| 206 | 2, // BC1_RGBA_SRGB | ||
| 207 | 2, // BC2_SRGB | ||
| 208 | 2, // BC3_SRGB | ||
| 209 | 2, // BC7_SRGB | ||
| 210 | 0, // A4B4G4R4_UNORM | ||
| 189 | 2, // ASTC_2D_4X4_SRGB | 211 | 2, // ASTC_2D_4X4_SRGB |
| 190 | 2, // ASTC_2D_8X8_SRGB | 212 | 2, // ASTC_2D_8X8_SRGB |
| 191 | 2, // ASTC_2D_8X5_SRGB | 213 | 2, // ASTC_2D_8X5_SRGB |
| 192 | 2, // ASTC_2D_5X4_SRGB | 214 | 2, // ASTC_2D_5X4_SRGB |
| 193 | 2, // ASTC_2D_5X5 | 215 | 2, // ASTC_2D_5X5_UNORM |
| 194 | 2, // ASTC_2D_5X5_SRGB | 216 | 2, // ASTC_2D_5X5_SRGB |
| 195 | 2, // ASTC_2D_10X8 | 217 | 2, // ASTC_2D_10X8_UNORM |
| 196 | 2, // ASTC_2D_10X8_SRGB | 218 | 2, // ASTC_2D_10X8_SRGB |
| 197 | 2, // ASTC_2D_6X6 | 219 | 2, // ASTC_2D_6X6_UNORM |
| 198 | 2, // ASTC_2D_6X6_SRGB | 220 | 2, // ASTC_2D_6X6_SRGB |
| 199 | 2, // ASTC_2D_10X10 | 221 | 2, // ASTC_2D_10X10_UNORM |
| 200 | 2, // ASTC_2D_10X10_SRGB | 222 | 2, // ASTC_2D_10X10_SRGB |
| 201 | 2, // ASTC_2D_12X12 | 223 | 2, // ASTC_2D_12X12_UNORM |
| 202 | 2, // ASTC_2D_12X12_SRGB | 224 | 2, // ASTC_2D_12X12_SRGB |
| 203 | 2, // ASTC_2D_8X6 | 225 | 2, // ASTC_2D_8X6_UNORM |
| 204 | 2, // ASTC_2D_8X6_SRGB | 226 | 2, // ASTC_2D_8X6_SRGB |
| 205 | 2, // ASTC_2D_6X5 | 227 | 2, // ASTC_2D_6X5_UNORM |
| 206 | 2, // ASTC_2D_6X5_SRGB | 228 | 2, // ASTC_2D_6X5_SRGB |
| 207 | 0, // E5B9G9R9F | 229 | 0, // E5B9G9R9_FLOAT |
| 208 | 0, // Z32F | 230 | 0, // D32_FLOAT |
| 209 | 0, // Z16 | 231 | 0, // D16_UNORM |
| 210 | 0, // Z24S8 | 232 | 0, // D24_UNORM_S8_UINT |
| 211 | 0, // S8Z24 | 233 | 0, // S8_UINT_D24_UNORM |
| 212 | 0, // Z32FS8 | 234 | 0, // D32_FLOAT_S8_UINT |
| 213 | }}; | 235 | }}; |
| 214 | 236 | ||
| 215 | /** | 237 | /** |
| @@ -229,86 +251,97 @@ inline constexpr u32 GetCompressionFactor(PixelFormat format) { | |||
| 229 | } | 251 | } |
| 230 | 252 | ||
| 231 | constexpr std::array<u32, MaxPixelFormat> block_width_table = {{ | 253 | constexpr std::array<u32, MaxPixelFormat> block_width_table = {{ |
| 232 | 1, // ABGR8U | 254 | 1, // A8B8G8R8_UNORM |
| 233 | 1, // ABGR8S | 255 | 1, // A8B8G8R8_SNORM |
| 234 | 1, // ABGR8UI | 256 | 1, // A8B8G8R8_SINT |
| 235 | 1, // B5G6R5U | 257 | 1, // A8B8G8R8_UINT |
| 236 | 1, // A2B10G10R10U | 258 | 1, // R5G6B5_UNORM |
| 237 | 1, // A1B5G5R5U | 259 | 1, // B5G6R5_UNORM |
| 238 | 1, // R8U | 260 | 1, // A1R5G5B5_UNORM |
| 239 | 1, // R8UI | 261 | 1, // A2B10G10R10_UNORM |
| 240 | 1, // RGBA16F | 262 | 1, // A2B10G10R10_UINT |
| 241 | 1, // RGBA16U | 263 | 1, // A1B5G5R5_UNORM |
| 242 | 1, // RGBA16S | 264 | 1, // R8_UNORM |
| 243 | 1, // RGBA16UI | 265 | 1, // R8_SNORM |
| 244 | 1, // R11FG11FB10F | 266 | 1, // R8_SINT |
| 245 | 1, // RGBA32UI | 267 | 1, // R8_UINT |
| 246 | 4, // DXT1 | 268 | 1, // R16G16B16A16_FLOAT |
| 247 | 4, // DXT23 | 269 | 1, // R16G16B16A16_UNORM |
| 248 | 4, // DXT45 | 270 | 1, // R16G16B16A16_SNORM |
| 249 | 4, // DXN1 | 271 | 1, // R16G16B16A16_SINT |
| 250 | 4, // DXN2UNORM | 272 | 1, // R16G16B16A16_UINT |
| 251 | 4, // DXN2SNORM | 273 | 1, // B10G11R11_FLOAT |
| 252 | 4, // BC7U | 274 | 1, // R32G32B32A32_UINT |
| 253 | 4, // BC6H_UF16 | 275 | 4, // BC1_RGBA_UNORM |
| 254 | 4, // BC6H_SF16 | 276 | 4, // BC2_UNORM |
| 255 | 4, // ASTC_2D_4X4 | 277 | 4, // BC3_UNORM |
| 256 | 1, // BGRA8 | 278 | 4, // BC4_UNORM |
| 257 | 1, // RGBA32F | 279 | 4, // BC4_SNORM |
| 258 | 1, // RG32F | 280 | 4, // BC5_UNORM |
| 259 | 1, // R32F | 281 | 4, // BC5_SNORM |
| 260 | 1, // R16F | 282 | 4, // BC7_UNORM |
| 261 | 1, // R16U | 283 | 4, // BC6H_UFLOAT |
| 262 | 1, // R16S | 284 | 4, // BC6H_SFLOAT |
| 263 | 1, // R16UI | 285 | 4, // ASTC_2D_4X4_UNORM |
| 264 | 1, // R16I | 286 | 1, // B8G8R8A8_UNORM |
| 265 | 1, // RG16 | 287 | 1, // R32G32B32A32_FLOAT |
| 266 | 1, // RG16F | 288 | 1, // R32G32B32A32_SINT |
| 267 | 1, // RG16UI | 289 | 1, // R32G32_FLOAT |
| 268 | 1, // RG16I | 290 | 1, // R32G32_SINT |
| 269 | 1, // RG16S | 291 | 1, // R32_FLOAT |
| 270 | 1, // RGB32F | 292 | 1, // R16_FLOAT |
| 271 | 1, // RGBA8_SRGB | 293 | 1, // R16_UNORM |
| 272 | 1, // RG8U | 294 | 1, // R16_SNORM |
| 273 | 1, // RG8S | 295 | 1, // R16_UINT |
| 274 | 1, // RG8UI | 296 | 1, // R16_SINT |
| 275 | 1, // RG32UI | 297 | 1, // R16G16_UNORM |
| 276 | 1, // RGBX16F | 298 | 1, // R16G16_FLOAT |
| 277 | 1, // R32UI | 299 | 1, // R16G16_UINT |
| 278 | 1, // R32I | 300 | 1, // R16G16_SINT |
| 279 | 8, // ASTC_2D_8X8 | 301 | 1, // R16G16_SNORM |
| 280 | 8, // ASTC_2D_8X5 | 302 | 1, // R32G32B32_FLOAT |
| 281 | 5, // ASTC_2D_5X4 | 303 | 1, // A8B8G8R8_SRGB |
| 282 | 1, // BGRA8_SRGB | 304 | 1, // R8G8_UNORM |
| 283 | 4, // DXT1_SRGB | 305 | 1, // R8G8_SNORM |
| 284 | 4, // DXT23_SRGB | 306 | 1, // R8G8_SINT |
| 285 | 4, // DXT45_SRGB | 307 | 1, // R8G8_UINT |
| 286 | 4, // BC7U_SRGB | 308 | 1, // R32G32_UINT |
| 287 | 1, // R4G4B4A4U | 309 | 1, // R16G16B16X16_FLOAT |
| 310 | 1, // R32_UINT | ||
| 311 | 1, // R32_SINT | ||
| 312 | 8, // ASTC_2D_8X8_UNORM | ||
| 313 | 8, // ASTC_2D_8X5_UNORM | ||
| 314 | 5, // ASTC_2D_5X4_UNORM | ||
| 315 | 1, // B8G8R8A8_SRGB | ||
| 316 | 4, // BC1_RGBA_SRGB | ||
| 317 | 4, // BC2_SRGB | ||
| 318 | 4, // BC3_SRGB | ||
| 319 | 4, // BC7_SRGB | ||
| 320 | 1, // A4B4G4R4_UNORM | ||
| 288 | 4, // ASTC_2D_4X4_SRGB | 321 | 4, // ASTC_2D_4X4_SRGB |
| 289 | 8, // ASTC_2D_8X8_SRGB | 322 | 8, // ASTC_2D_8X8_SRGB |
| 290 | 8, // ASTC_2D_8X5_SRGB | 323 | 8, // ASTC_2D_8X5_SRGB |
| 291 | 5, // ASTC_2D_5X4_SRGB | 324 | 5, // ASTC_2D_5X4_SRGB |
| 292 | 5, // ASTC_2D_5X5 | 325 | 5, // ASTC_2D_5X5_UNORM |
| 293 | 5, // ASTC_2D_5X5_SRGB | 326 | 5, // ASTC_2D_5X5_SRGB |
| 294 | 10, // ASTC_2D_10X8 | 327 | 10, // ASTC_2D_10X8_UNORM |
| 295 | 10, // ASTC_2D_10X8_SRGB | 328 | 10, // ASTC_2D_10X8_SRGB |
| 296 | 6, // ASTC_2D_6X6 | 329 | 6, // ASTC_2D_6X6_UNORM |
| 297 | 6, // ASTC_2D_6X6_SRGB | 330 | 6, // ASTC_2D_6X6_SRGB |
| 298 | 10, // ASTC_2D_10X10 | 331 | 10, // ASTC_2D_10X10_UNORM |
| 299 | 10, // ASTC_2D_10X10_SRGB | 332 | 10, // ASTC_2D_10X10_SRGB |
| 300 | 12, // ASTC_2D_12X12 | 333 | 12, // ASTC_2D_12X12_UNORM |
| 301 | 12, // ASTC_2D_12X12_SRGB | 334 | 12, // ASTC_2D_12X12_SRGB |
| 302 | 8, // ASTC_2D_8X6 | 335 | 8, // ASTC_2D_8X6_UNORM |
| 303 | 8, // ASTC_2D_8X6_SRGB | 336 | 8, // ASTC_2D_8X6_SRGB |
| 304 | 6, // ASTC_2D_6X5 | 337 | 6, // ASTC_2D_6X5_UNORM |
| 305 | 6, // ASTC_2D_6X5_SRGB | 338 | 6, // ASTC_2D_6X5_SRGB |
| 306 | 1, // E5B9G9R9F | 339 | 1, // E5B9G9R9_FLOAT |
| 307 | 1, // Z32F | 340 | 1, // D32_FLOAT |
| 308 | 1, // Z16 | 341 | 1, // D16_UNORM |
| 309 | 1, // Z24S8 | 342 | 1, // D24_UNORM_S8_UINT |
| 310 | 1, // S8Z24 | 343 | 1, // S8_UINT_D24_UNORM |
| 311 | 1, // Z32FS8 | 344 | 1, // D32_FLOAT_S8_UINT |
| 312 | }}; | 345 | }}; |
| 313 | 346 | ||
| 314 | static constexpr u32 GetDefaultBlockWidth(PixelFormat format) { | 347 | static constexpr u32 GetDefaultBlockWidth(PixelFormat format) { |
| @@ -320,86 +353,97 @@ static constexpr u32 GetDefaultBlockWidth(PixelFormat format) { | |||
| 320 | } | 353 | } |
| 321 | 354 | ||
| 322 | constexpr std::array<u32, MaxPixelFormat> block_height_table = {{ | 355 | constexpr std::array<u32, MaxPixelFormat> block_height_table = {{ |
| 323 | 1, // ABGR8U | 356 | 1, // A8B8G8R8_UNORM |
| 324 | 1, // ABGR8S | 357 | 1, // A8B8G8R8_SNORM |
| 325 | 1, // ABGR8UI | 358 | 1, // A8B8G8R8_SINT |
| 326 | 1, // B5G6R5U | 359 | 1, // A8B8G8R8_UINT |
| 327 | 1, // A2B10G10R10U | 360 | 1, // R5G6B5_UNORM |
| 328 | 1, // A1B5G5R5U | 361 | 1, // B5G6R5_UNORM |
| 329 | 1, // R8U | 362 | 1, // A1R5G5B5_UNORM |
| 330 | 1, // R8UI | 363 | 1, // A2B10G10R10_UNORM |
| 331 | 1, // RGBA16F | 364 | 1, // A2B10G10R10_UINT |
| 332 | 1, // RGBA16U | 365 | 1, // A1B5G5R5_UNORM |
| 333 | 1, // RGBA16S | 366 | 1, // R8_UNORM |
| 334 | 1, // RGBA16UI | 367 | 1, // R8_SNORM |
| 335 | 1, // R11FG11FB10F | 368 | 1, // R8_SINT |
| 336 | 1, // RGBA32UI | 369 | 1, // R8_UINT |
| 337 | 4, // DXT1 | 370 | 1, // R16G16B16A16_FLOAT |
| 338 | 4, // DXT23 | 371 | 1, // R16G16B16A16_UNORM |
| 339 | 4, // DXT45 | 372 | 1, // R16G16B16A16_SNORM |
| 340 | 4, // DXN1 | 373 | 1, // R16G16B16A16_SINT |
| 341 | 4, // DXN2UNORM | 374 | 1, // R16G16B16A16_UINT |
| 342 | 4, // DXN2SNORM | 375 | 1, // B10G11R11_FLOAT |
| 343 | 4, // BC7U | 376 | 1, // R32G32B32A32_UINT |
| 344 | 4, // BC6H_UF16 | 377 | 4, // BC1_RGBA_UNORM |
| 345 | 4, // BC6H_SF16 | 378 | 4, // BC2_UNORM |
| 346 | 4, // ASTC_2D_4X4 | 379 | 4, // BC3_UNORM |
| 347 | 1, // BGRA8 | 380 | 4, // BC4_UNORM |
| 348 | 1, // RGBA32F | 381 | 4, // BC4_SNORM |
| 349 | 1, // RG32F | 382 | 4, // BC5_UNORM |
| 350 | 1, // R32F | 383 | 4, // BC5_SNORM |
| 351 | 1, // R16F | 384 | 4, // BC7_UNORM |
| 352 | 1, // R16U | 385 | 4, // BC6H_UFLOAT |
| 353 | 1, // R16S | 386 | 4, // BC6H_SFLOAT |
| 354 | 1, // R16UI | 387 | 4, // ASTC_2D_4X4_UNORM |
| 355 | 1, // R16I | 388 | 1, // B8G8R8A8_UNORM |
| 356 | 1, // RG16 | 389 | 1, // R32G32B32A32_FLOAT |
| 357 | 1, // RG16F | 390 | 1, // R32G32B32A32_SINT |
| 358 | 1, // RG16UI | 391 | 1, // R32G32_FLOAT |
| 359 | 1, // RG16I | 392 | 1, // R32G32_SINT |
| 360 | 1, // RG16S | 393 | 1, // R32_FLOAT |
| 361 | 1, // RGB32F | 394 | 1, // R16_FLOAT |
| 362 | 1, // RGBA8_SRGB | 395 | 1, // R16_UNORM |
| 363 | 1, // RG8U | 396 | 1, // R16_SNORM |
| 364 | 1, // RG8S | 397 | 1, // R16_UINT |
| 365 | 1, // RG8UI | 398 | 1, // R16_SINT |
| 366 | 1, // RG32UI | 399 | 1, // R16G16_UNORM |
| 367 | 1, // RGBX16F | 400 | 1, // R16G16_FLOAT |
| 368 | 1, // R32UI | 401 | 1, // R16G16_UINT |
| 369 | 1, // R32I | 402 | 1, // R16G16_SINT |
| 370 | 8, // ASTC_2D_8X8 | 403 | 1, // R16G16_SNORM |
| 371 | 5, // ASTC_2D_8X5 | 404 | 1, // R32G32B32_FLOAT |
| 372 | 4, // ASTC_2D_5X4 | 405 | 1, // A8B8G8R8_SRGB |
| 373 | 1, // BGRA8_SRGB | 406 | 1, // R8G8_UNORM |
| 374 | 4, // DXT1_SRGB | 407 | 1, // R8G8_SNORM |
| 375 | 4, // DXT23_SRGB | 408 | 1, // R8G8_SINT |
| 376 | 4, // DXT45_SRGB | 409 | 1, // R8G8_UINT |
| 377 | 4, // BC7U_SRGB | 410 | 1, // R32G32_UINT |
| 378 | 1, // R4G4B4A4U | 411 | 1, // R16G16B16X16_FLOAT |
| 412 | 1, // R32_UINT | ||
| 413 | 1, // R32_SINT | ||
| 414 | 8, // ASTC_2D_8X8_UNORM | ||
| 415 | 5, // ASTC_2D_8X5_UNORM | ||
| 416 | 4, // ASTC_2D_5X4_UNORM | ||
| 417 | 1, // B8G8R8A8_SRGB | ||
| 418 | 4, // BC1_RGBA_SRGB | ||
| 419 | 4, // BC2_SRGB | ||
| 420 | 4, // BC3_SRGB | ||
| 421 | 4, // BC7_SRGB | ||
| 422 | 1, // A4B4G4R4_UNORM | ||
| 379 | 4, // ASTC_2D_4X4_SRGB | 423 | 4, // ASTC_2D_4X4_SRGB |
| 380 | 8, // ASTC_2D_8X8_SRGB | 424 | 8, // ASTC_2D_8X8_SRGB |
| 381 | 5, // ASTC_2D_8X5_SRGB | 425 | 5, // ASTC_2D_8X5_SRGB |
| 382 | 4, // ASTC_2D_5X4_SRGB | 426 | 4, // ASTC_2D_5X4_SRGB |
| 383 | 5, // ASTC_2D_5X5 | 427 | 5, // ASTC_2D_5X5_UNORM |
| 384 | 5, // ASTC_2D_5X5_SRGB | 428 | 5, // ASTC_2D_5X5_SRGB |
| 385 | 8, // ASTC_2D_10X8 | 429 | 8, // ASTC_2D_10X8_UNORM |
| 386 | 8, // ASTC_2D_10X8_SRGB | 430 | 8, // ASTC_2D_10X8_SRGB |
| 387 | 6, // ASTC_2D_6X6 | 431 | 6, // ASTC_2D_6X6_UNORM |
| 388 | 6, // ASTC_2D_6X6_SRGB | 432 | 6, // ASTC_2D_6X6_SRGB |
| 389 | 10, // ASTC_2D_10X10 | 433 | 10, // ASTC_2D_10X10_UNORM |
| 390 | 10, // ASTC_2D_10X10_SRGB | 434 | 10, // ASTC_2D_10X10_SRGB |
| 391 | 12, // ASTC_2D_12X12 | 435 | 12, // ASTC_2D_12X12_UNORM |
| 392 | 12, // ASTC_2D_12X12_SRGB | 436 | 12, // ASTC_2D_12X12_SRGB |
| 393 | 6, // ASTC_2D_8X6 | 437 | 6, // ASTC_2D_8X6_UNORM |
| 394 | 6, // ASTC_2D_8X6_SRGB | 438 | 6, // ASTC_2D_8X6_SRGB |
| 395 | 5, // ASTC_2D_6X5 | 439 | 5, // ASTC_2D_6X5_UNORM |
| 396 | 5, // ASTC_2D_6X5_SRGB | 440 | 5, // ASTC_2D_6X5_SRGB |
| 397 | 1, // E5B9G9R9F | 441 | 1, // E5B9G9R9_FLOAT |
| 398 | 1, // Z32F | 442 | 1, // D32_FLOAT |
| 399 | 1, // Z16 | 443 | 1, // D16_UNORM |
| 400 | 1, // Z24S8 | 444 | 1, // D24_UNORM_S8_UINT |
| 401 | 1, // S8Z24 | 445 | 1, // S8_UINT_D24_UNORM |
| 402 | 1, // Z32FS8 | 446 | 1, // D32_FLOAT_S8_UINT |
| 403 | }}; | 447 | }}; |
| 404 | 448 | ||
| 405 | static constexpr u32 GetDefaultBlockHeight(PixelFormat format) { | 449 | static constexpr u32 GetDefaultBlockHeight(PixelFormat format) { |
| @@ -411,86 +455,97 @@ static constexpr u32 GetDefaultBlockHeight(PixelFormat format) { | |||
| 411 | } | 455 | } |
| 412 | 456 | ||
| 413 | constexpr std::array<u32, MaxPixelFormat> bpp_table = {{ | 457 | constexpr std::array<u32, MaxPixelFormat> bpp_table = {{ |
| 414 | 32, // ABGR8U | 458 | 32, // A8B8G8R8_UNORM |
| 415 | 32, // ABGR8S | 459 | 32, // A8B8G8R8_SNORM |
| 416 | 32, // ABGR8UI | 460 | 32, // A8B8G8R8_SINT |
| 417 | 16, // B5G6R5U | 461 | 32, // A8B8G8R8_UINT |
| 418 | 32, // A2B10G10R10U | 462 | 16, // R5G6B5_UNORM |
| 419 | 16, // A1B5G5R5U | 463 | 16, // B5G6R5_UNORM |
| 420 | 8, // R8U | 464 | 16, // A1R5G5B5_UNORM |
| 421 | 8, // R8UI | 465 | 32, // A2B10G10R10_UNORM |
| 422 | 64, // RGBA16F | 466 | 32, // A2B10G10R10_UINT |
| 423 | 64, // RGBA16U | 467 | 16, // A1B5G5R5_UNORM |
| 424 | 64, // RGBA16S | 468 | 8, // R8_UNORM |
| 425 | 64, // RGBA16UI | 469 | 8, // R8_SNORM |
| 426 | 32, // R11FG11FB10F | 470 | 8, // R8_SINT |
| 427 | 128, // RGBA32UI | 471 | 8, // R8_UINT |
| 428 | 64, // DXT1 | 472 | 64, // R16G16B16A16_FLOAT |
| 429 | 128, // DXT23 | 473 | 64, // R16G16B16A16_UNORM |
| 430 | 128, // DXT45 | 474 | 64, // R16G16B16A16_SNORM |
| 431 | 64, // DXN1 | 475 | 64, // R16G16B16A16_SINT |
| 432 | 128, // DXN2UNORM | 476 | 64, // R16G16B16A16_UINT |
| 433 | 128, // DXN2SNORM | 477 | 32, // B10G11R11_FLOAT |
| 434 | 128, // BC7U | 478 | 128, // R32G32B32A32_UINT |
| 435 | 128, // BC6H_UF16 | 479 | 64, // BC1_RGBA_UNORM |
| 436 | 128, // BC6H_SF16 | 480 | 128, // BC2_UNORM |
| 437 | 128, // ASTC_2D_4X4 | 481 | 128, // BC3_UNORM |
| 438 | 32, // BGRA8 | 482 | 64, // BC4_UNORM |
| 439 | 128, // RGBA32F | 483 | 64, // BC4_SNORM |
| 440 | 64, // RG32F | 484 | 128, // BC5_UNORM |
| 441 | 32, // R32F | 485 | 128, // BC5_SNORM |
| 442 | 16, // R16F | 486 | 128, // BC7_UNORM |
| 443 | 16, // R16U | 487 | 128, // BC6H_UFLOAT |
| 444 | 16, // R16S | 488 | 128, // BC6H_SFLOAT |
| 445 | 16, // R16UI | 489 | 128, // ASTC_2D_4X4_UNORM |
| 446 | 16, // R16I | 490 | 32, // B8G8R8A8_UNORM |
| 447 | 32, // RG16 | 491 | 128, // R32G32B32A32_FLOAT |
| 448 | 32, // RG16F | 492 | 128, // R32G32B32A32_SINT |
| 449 | 32, // RG16UI | 493 | 64, // R32G32_FLOAT |
| 450 | 32, // RG16I | 494 | 64, // R32G32_SINT |
| 451 | 32, // RG16S | 495 | 32, // R32_FLOAT |
| 452 | 96, // RGB32F | 496 | 16, // R16_FLOAT |
| 453 | 32, // RGBA8_SRGB | 497 | 16, // R16_UNORM |
| 454 | 16, // RG8U | 498 | 16, // R16_SNORM |
| 455 | 16, // RG8S | 499 | 16, // R16_UINT |
| 456 | 16, // RG8UI | 500 | 16, // R16_SINT |
| 457 | 64, // RG32UI | 501 | 32, // R16G16_UNORM |
| 458 | 64, // RGBX16F | 502 | 32, // R16G16_FLOAT |
| 459 | 32, // R32UI | 503 | 32, // R16G16_UINT |
| 460 | 32, // R32I | 504 | 32, // R16G16_SINT |
| 461 | 128, // ASTC_2D_8X8 | 505 | 32, // R16G16_SNORM |
| 462 | 128, // ASTC_2D_8X5 | 506 | 96, // R32G32B32_FLOAT |
| 463 | 128, // ASTC_2D_5X4 | 507 | 32, // A8B8G8R8_SRGB |
| 464 | 32, // BGRA8_SRGB | 508 | 16, // R8G8_UNORM |
| 465 | 64, // DXT1_SRGB | 509 | 16, // R8G8_SNORM |
| 466 | 128, // DXT23_SRGB | 510 | 16, // R8G8_SINT |
| 467 | 128, // DXT45_SRGB | 511 | 16, // R8G8_UINT |
| 468 | 128, // BC7U | 512 | 64, // R32G32_UINT |
| 469 | 16, // R4G4B4A4U | 513 | 64, // R16G16B16X16_FLOAT |
| 514 | 32, // R32_UINT | ||
| 515 | 32, // R32_SINT | ||
| 516 | 128, // ASTC_2D_8X8_UNORM | ||
| 517 | 128, // ASTC_2D_8X5_UNORM | ||
| 518 | 128, // ASTC_2D_5X4_UNORM | ||
| 519 | 32, // B8G8R8A8_SRGB | ||
| 520 | 64, // BC1_RGBA_SRGB | ||
| 521 | 128, // BC2_SRGB | ||
| 522 | 128, // BC3_SRGB | ||
| 523 | 128, // BC7_UNORM | ||
| 524 | 16, // A4B4G4R4_UNORM | ||
| 470 | 128, // ASTC_2D_4X4_SRGB | 525 | 128, // ASTC_2D_4X4_SRGB |
| 471 | 128, // ASTC_2D_8X8_SRGB | 526 | 128, // ASTC_2D_8X8_SRGB |
| 472 | 128, // ASTC_2D_8X5_SRGB | 527 | 128, // ASTC_2D_8X5_SRGB |
| 473 | 128, // ASTC_2D_5X4_SRGB | 528 | 128, // ASTC_2D_5X4_SRGB |
| 474 | 128, // ASTC_2D_5X5 | 529 | 128, // ASTC_2D_5X5_UNORM |
| 475 | 128, // ASTC_2D_5X5_SRGB | 530 | 128, // ASTC_2D_5X5_SRGB |
| 476 | 128, // ASTC_2D_10X8 | 531 | 128, // ASTC_2D_10X8_UNORM |
| 477 | 128, // ASTC_2D_10X8_SRGB | 532 | 128, // ASTC_2D_10X8_SRGB |
| 478 | 128, // ASTC_2D_6X6 | 533 | 128, // ASTC_2D_6X6_UNORM |
| 479 | 128, // ASTC_2D_6X6_SRGB | 534 | 128, // ASTC_2D_6X6_SRGB |
| 480 | 128, // ASTC_2D_10X10 | 535 | 128, // ASTC_2D_10X10_UNORM |
| 481 | 128, // ASTC_2D_10X10_SRGB | 536 | 128, // ASTC_2D_10X10_SRGB |
| 482 | 128, // ASTC_2D_12X12 | 537 | 128, // ASTC_2D_12X12_UNORM |
| 483 | 128, // ASTC_2D_12X12_SRGB | 538 | 128, // ASTC_2D_12X12_SRGB |
| 484 | 128, // ASTC_2D_8X6 | 539 | 128, // ASTC_2D_8X6_UNORM |
| 485 | 128, // ASTC_2D_8X6_SRGB | 540 | 128, // ASTC_2D_8X6_SRGB |
| 486 | 128, // ASTC_2D_6X5 | 541 | 128, // ASTC_2D_6X5_UNORM |
| 487 | 128, // ASTC_2D_6X5_SRGB | 542 | 128, // ASTC_2D_6X5_SRGB |
| 488 | 32, // E5B9G9R9F | 543 | 32, // E5B9G9R9_FLOAT |
| 489 | 32, // Z32F | 544 | 32, // D32_FLOAT |
| 490 | 16, // Z16 | 545 | 16, // D16_UNORM |
| 491 | 32, // Z24S8 | 546 | 32, // D24_UNORM_S8_UINT |
| 492 | 32, // S8Z24 | 547 | 32, // S8_UINT_D24_UNORM |
| 493 | 64, // Z32FS8 | 548 | 64, // D32_FLOAT_S8_UINT |
| 494 | }}; | 549 | }}; |
| 495 | 550 | ||
| 496 | static constexpr u32 GetFormatBpp(PixelFormat format) { | 551 | static constexpr u32 GetFormatBpp(PixelFormat format) { |
| @@ -529,7 +584,4 @@ bool IsPixelFormatSRGB(PixelFormat format); | |||
| 529 | 584 | ||
| 530 | std::pair<u32, u32> GetASTCBlockSize(PixelFormat format); | 585 | std::pair<u32, u32> GetASTCBlockSize(PixelFormat format); |
| 531 | 586 | ||
| 532 | /// Returns true if the specified PixelFormat is a BCn format, e.g. DXT or DXN | ||
| 533 | bool IsFormatBCn(PixelFormat format); | ||
| 534 | |||
| 535 | } // namespace VideoCore::Surface | 587 | } // namespace VideoCore::Surface |
diff --git a/src/video_core/texture_cache/format_lookup_table.cpp b/src/video_core/texture_cache/format_lookup_table.cpp index f476f03b0..7d5a75648 100644 --- a/src/video_core/texture_cache/format_lookup_table.cpp +++ b/src/video_core/texture_cache/format_lookup_table.cpp | |||
| @@ -19,8 +19,6 @@ constexpr auto SNORM = ComponentType::SNORM; | |||
| 19 | constexpr auto UNORM = ComponentType::UNORM; | 19 | constexpr auto UNORM = ComponentType::UNORM; |
| 20 | constexpr auto SINT = ComponentType::SINT; | 20 | constexpr auto SINT = ComponentType::SINT; |
| 21 | constexpr auto UINT = ComponentType::UINT; | 21 | constexpr auto UINT = ComponentType::UINT; |
| 22 | constexpr auto SNORM_FORCE_FP16 = ComponentType::SNORM_FORCE_FP16; | ||
| 23 | constexpr auto UNORM_FORCE_FP16 = ComponentType::UNORM_FORCE_FP16; | ||
| 24 | constexpr auto FLOAT = ComponentType::FLOAT; | 22 | constexpr auto FLOAT = ComponentType::FLOAT; |
| 25 | constexpr bool C = false; // Normal color | 23 | constexpr bool C = false; // Normal color |
| 26 | constexpr bool S = true; // Srgb | 24 | constexpr bool S = true; // Srgb |
| @@ -41,119 +39,126 @@ struct Table { | |||
| 41 | ComponentType alpha_component; | 39 | ComponentType alpha_component; |
| 42 | bool is_srgb; | 40 | bool is_srgb; |
| 43 | }; | 41 | }; |
| 44 | constexpr std::array<Table, 78> DefinitionTable = {{ | 42 | constexpr std::array<Table, 86> DefinitionTable = {{ |
| 45 | {TextureFormat::A8R8G8B8, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ABGR8U}, | 43 | {TextureFormat::A8R8G8B8, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::A8B8G8R8_UNORM}, |
| 46 | {TextureFormat::A8R8G8B8, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::ABGR8S}, | 44 | {TextureFormat::A8R8G8B8, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::A8B8G8R8_SNORM}, |
| 47 | {TextureFormat::A8R8G8B8, C, UINT, UINT, UINT, UINT, PixelFormat::ABGR8UI}, | 45 | {TextureFormat::A8R8G8B8, C, UINT, UINT, UINT, UINT, PixelFormat::A8B8G8R8_UINT}, |
| 48 | {TextureFormat::A8R8G8B8, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::RGBA8_SRGB}, | 46 | {TextureFormat::A8R8G8B8, C, SINT, SINT, SINT, SINT, PixelFormat::A8B8G8R8_SINT}, |
| 47 | {TextureFormat::A8R8G8B8, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::A8B8G8R8_SRGB}, | ||
| 49 | 48 | ||
| 50 | {TextureFormat::B5G6R5, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::B5G6R5U}, | 49 | {TextureFormat::B5G6R5, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::B5G6R5_UNORM}, |
| 51 | 50 | ||
| 52 | {TextureFormat::A2B10G10R10, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::A2B10G10R10U}, | 51 | {TextureFormat::A2B10G10R10, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::A2B10G10R10_UNORM}, |
| 52 | {TextureFormat::A2B10G10R10, C, UINT, UINT, UINT, UINT, PixelFormat::A2B10G10R10_UINT}, | ||
| 53 | 53 | ||
| 54 | {TextureFormat::A1B5G5R5, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::A1B5G5R5U}, | 54 | {TextureFormat::A1B5G5R5, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::A1B5G5R5_UNORM}, |
| 55 | 55 | ||
| 56 | {TextureFormat::A4B4G4R4, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::R4G4B4A4U}, | 56 | {TextureFormat::A4B4G4R4, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::A4B4G4R4_UNORM}, |
| 57 | 57 | ||
| 58 | {TextureFormat::R8, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::R8U}, | 58 | {TextureFormat::R8, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::R8_UNORM}, |
| 59 | {TextureFormat::R8, C, UINT, UINT, UINT, UINT, PixelFormat::R8UI}, | 59 | {TextureFormat::R8, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::R8_SNORM}, |
| 60 | {TextureFormat::R8, C, UINT, UINT, UINT, UINT, PixelFormat::R8_UINT}, | ||
| 61 | {TextureFormat::R8, C, SINT, SINT, SINT, SINT, PixelFormat::R8_SINT}, | ||
| 60 | 62 | ||
| 61 | {TextureFormat::G8R8, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::RG8U}, | 63 | {TextureFormat::R8G8, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::R8G8_UNORM}, |
| 62 | {TextureFormat::G8R8, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::RG8S}, | 64 | {TextureFormat::R8G8, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::R8G8_SNORM}, |
| 63 | {TextureFormat::G8R8, C, UINT, UINT, UINT, UINT, PixelFormat::RG8UI}, | 65 | {TextureFormat::R8G8, C, UINT, UINT, UINT, UINT, PixelFormat::R8G8_UINT}, |
| 66 | {TextureFormat::R8G8, C, SINT, SINT, SINT, SINT, PixelFormat::R8G8_SINT}, | ||
| 64 | 67 | ||
| 65 | {TextureFormat::R16_G16_B16_A16, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::RGBA16S}, | 68 | {TextureFormat::R16G16B16A16, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::R16G16B16A16_SNORM}, |
| 66 | {TextureFormat::R16_G16_B16_A16, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::RGBA16U}, | 69 | {TextureFormat::R16G16B16A16, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::R16G16B16A16_UNORM}, |
| 67 | {TextureFormat::R16_G16_B16_A16, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::RGBA16F}, | 70 | {TextureFormat::R16G16B16A16, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::R16G16B16A16_FLOAT}, |
| 68 | {TextureFormat::R16_G16_B16_A16, C, UINT, UINT, UINT, UINT, PixelFormat::RGBA16UI}, | 71 | {TextureFormat::R16G16B16A16, C, UINT, UINT, UINT, UINT, PixelFormat::R16G16B16A16_UINT}, |
| 72 | {TextureFormat::R16G16B16A16, C, SINT, SINT, SINT, SINT, PixelFormat::R16G16B16A16_SINT}, | ||
| 69 | 73 | ||
| 70 | {TextureFormat::R16_G16, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::RG16F}, | 74 | {TextureFormat::R16G16, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::R16G16_FLOAT}, |
| 71 | {TextureFormat::R16_G16, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::RG16}, | 75 | {TextureFormat::R16G16, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::R16G16_UNORM}, |
| 72 | {TextureFormat::R16_G16, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::RG16S}, | 76 | {TextureFormat::R16G16, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::R16G16_SNORM}, |
| 73 | {TextureFormat::R16_G16, C, UINT, UINT, UINT, UINT, PixelFormat::RG16UI}, | 77 | {TextureFormat::R16G16, C, UINT, UINT, UINT, UINT, PixelFormat::R16G16_UINT}, |
| 74 | {TextureFormat::R16_G16, C, SINT, SINT, SINT, SINT, PixelFormat::RG16I}, | 78 | {TextureFormat::R16G16, C, SINT, SINT, SINT, SINT, PixelFormat::R16G16_SINT}, |
| 75 | 79 | ||
| 76 | {TextureFormat::R16, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::R16F}, | 80 | {TextureFormat::R16, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::R16_FLOAT}, |
| 77 | {TextureFormat::R16, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::R16U}, | 81 | {TextureFormat::R16, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::R16_UNORM}, |
| 78 | {TextureFormat::R16, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::R16S}, | 82 | {TextureFormat::R16, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::R16_SNORM}, |
| 79 | {TextureFormat::R16, C, UINT, UINT, UINT, UINT, PixelFormat::R16UI}, | 83 | {TextureFormat::R16, C, UINT, UINT, UINT, UINT, PixelFormat::R16_UINT}, |
| 80 | {TextureFormat::R16, C, SINT, SINT, SINT, SINT, PixelFormat::R16I}, | 84 | {TextureFormat::R16, C, SINT, SINT, SINT, SINT, PixelFormat::R16_SINT}, |
| 81 | 85 | ||
| 82 | {TextureFormat::BF10GF11RF11, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::R11FG11FB10F}, | 86 | {TextureFormat::B10G11R11, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::B10G11R11_FLOAT}, |
| 83 | 87 | ||
| 84 | {TextureFormat::R32_G32_B32_A32, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::RGBA32F}, | 88 | {TextureFormat::R32G32B32A32, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::R32G32B32A32_FLOAT}, |
| 85 | {TextureFormat::R32_G32_B32_A32, C, UINT, UINT, UINT, UINT, PixelFormat::RGBA32UI}, | 89 | {TextureFormat::R32G32B32A32, C, UINT, UINT, UINT, UINT, PixelFormat::R32G32B32A32_UINT}, |
| 90 | {TextureFormat::R32G32B32A32, C, SINT, SINT, SINT, SINT, PixelFormat::R32G32B32A32_SINT}, | ||
| 86 | 91 | ||
| 87 | {TextureFormat::R32_G32_B32, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::RGB32F}, | 92 | {TextureFormat::R32G32B32, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::R32G32B32_FLOAT}, |
| 88 | 93 | ||
| 89 | {TextureFormat::R32_G32, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::RG32F}, | 94 | {TextureFormat::R32G32, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::R32G32_FLOAT}, |
| 90 | {TextureFormat::R32_G32, C, UINT, UINT, UINT, UINT, PixelFormat::RG32UI}, | 95 | {TextureFormat::R32G32, C, UINT, UINT, UINT, UINT, PixelFormat::R32G32_UINT}, |
| 96 | {TextureFormat::R32G32, C, SINT, SINT, SINT, SINT, PixelFormat::R32G32_SINT}, | ||
| 91 | 97 | ||
| 92 | {TextureFormat::R32, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::R32F}, | 98 | {TextureFormat::R32, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::R32_FLOAT}, |
| 93 | {TextureFormat::R32, C, UINT, UINT, UINT, UINT, PixelFormat::R32UI}, | 99 | {TextureFormat::R32, C, UINT, UINT, UINT, UINT, PixelFormat::R32_UINT}, |
| 94 | {TextureFormat::R32, C, SINT, SINT, SINT, SINT, PixelFormat::R32I}, | 100 | {TextureFormat::R32, C, SINT, SINT, SINT, SINT, PixelFormat::R32_SINT}, |
| 95 | 101 | ||
| 96 | {TextureFormat::E5B9G9R9_SHAREDEXP, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::E5B9G9R9F}, | 102 | {TextureFormat::E5B9G9R9, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::E5B9G9R9_FLOAT}, |
| 97 | 103 | ||
| 98 | {TextureFormat::ZF32, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::Z32F}, | 104 | {TextureFormat::D32, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::D32_FLOAT}, |
| 99 | {TextureFormat::Z16, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::Z16}, | 105 | {TextureFormat::D16, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::D16_UNORM}, |
| 100 | {TextureFormat::S8Z24, C, UINT, UNORM, UNORM, UNORM, PixelFormat::S8Z24}, | 106 | {TextureFormat::S8D24, C, UINT, UNORM, UNORM, UNORM, PixelFormat::S8_UINT_D24_UNORM}, |
| 101 | {TextureFormat::G24R8, C, UINT, UNORM, UNORM, UNORM, PixelFormat::S8Z24}, | 107 | {TextureFormat::R8G24, C, UINT, UNORM, UNORM, UNORM, PixelFormat::S8_UINT_D24_UNORM}, |
| 102 | {TextureFormat::ZF32_X24S8, C, FLOAT, UINT, UNORM, UNORM, PixelFormat::Z32FS8}, | 108 | {TextureFormat::D32S8, C, FLOAT, UINT, UNORM, UNORM, PixelFormat::D32_FLOAT_S8_UINT}, |
| 103 | 109 | ||
| 104 | {TextureFormat::DXT1, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::DXT1}, | 110 | {TextureFormat::BC1_RGBA, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::BC1_RGBA_UNORM}, |
| 105 | {TextureFormat::DXT1, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::DXT1_SRGB}, | 111 | {TextureFormat::BC1_RGBA, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::BC1_RGBA_SRGB}, |
| 106 | 112 | ||
| 107 | {TextureFormat::DXT23, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::DXT23}, | 113 | {TextureFormat::BC2, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::BC2_UNORM}, |
| 108 | {TextureFormat::DXT23, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::DXT23_SRGB}, | 114 | {TextureFormat::BC2, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::BC2_SRGB}, |
| 109 | 115 | ||
| 110 | {TextureFormat::DXT45, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::DXT45}, | 116 | {TextureFormat::BC3, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::BC3_UNORM}, |
| 111 | {TextureFormat::DXT45, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::DXT45_SRGB}, | 117 | {TextureFormat::BC3, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::BC3_SRGB}, |
| 112 | 118 | ||
| 113 | // TODO: Use a different pixel format for SNORM | 119 | {TextureFormat::BC4, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::BC4_UNORM}, |
| 114 | {TextureFormat::DXN1, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::DXN1}, | 120 | {TextureFormat::BC4, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::BC4_SNORM}, |
| 115 | {TextureFormat::DXN1, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::DXN1}, | ||
| 116 | 121 | ||
| 117 | {TextureFormat::DXN2, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::DXN2UNORM}, | 122 | {TextureFormat::BC5, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::BC5_UNORM}, |
| 118 | {TextureFormat::DXN2, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::DXN2SNORM}, | 123 | {TextureFormat::BC5, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::BC5_SNORM}, |
| 119 | 124 | ||
| 120 | {TextureFormat::BC7U, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::BC7U}, | 125 | {TextureFormat::BC7, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::BC7_UNORM}, |
| 121 | {TextureFormat::BC7U, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::BC7U_SRGB}, | 126 | {TextureFormat::BC7, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::BC7_SRGB}, |
| 122 | 127 | ||
| 123 | {TextureFormat::BC6H_SF16, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::BC6H_SF16}, | 128 | {TextureFormat::BC6H_SFLOAT, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::BC6H_SFLOAT}, |
| 124 | {TextureFormat::BC6H_UF16, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::BC6H_UF16}, | 129 | {TextureFormat::BC6H_UFLOAT, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::BC6H_UFLOAT}, |
| 125 | 130 | ||
| 126 | {TextureFormat::ASTC_2D_4X4, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_4X4}, | 131 | {TextureFormat::ASTC_2D_4X4, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_4X4_UNORM}, |
| 127 | {TextureFormat::ASTC_2D_4X4, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_4X4_SRGB}, | 132 | {TextureFormat::ASTC_2D_4X4, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_4X4_SRGB}, |
| 128 | 133 | ||
| 129 | {TextureFormat::ASTC_2D_5X4, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_5X4}, | 134 | {TextureFormat::ASTC_2D_5X4, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_5X4_UNORM}, |
| 130 | {TextureFormat::ASTC_2D_5X4, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_5X4_SRGB}, | 135 | {TextureFormat::ASTC_2D_5X4, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_5X4_SRGB}, |
| 131 | 136 | ||
| 132 | {TextureFormat::ASTC_2D_5X5, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_5X5}, | 137 | {TextureFormat::ASTC_2D_5X5, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_5X5_UNORM}, |
| 133 | {TextureFormat::ASTC_2D_5X5, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_5X5_SRGB}, | 138 | {TextureFormat::ASTC_2D_5X5, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_5X5_SRGB}, |
| 134 | 139 | ||
| 135 | {TextureFormat::ASTC_2D_8X8, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_8X8}, | 140 | {TextureFormat::ASTC_2D_8X8, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_8X8_UNORM}, |
| 136 | {TextureFormat::ASTC_2D_8X8, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_8X8_SRGB}, | 141 | {TextureFormat::ASTC_2D_8X8, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_8X8_SRGB}, |
| 137 | 142 | ||
| 138 | {TextureFormat::ASTC_2D_8X5, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_8X5}, | 143 | {TextureFormat::ASTC_2D_8X5, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_8X5_UNORM}, |
| 139 | {TextureFormat::ASTC_2D_8X5, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_8X5_SRGB}, | 144 | {TextureFormat::ASTC_2D_8X5, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_8X5_SRGB}, |
| 140 | 145 | ||
| 141 | {TextureFormat::ASTC_2D_10X8, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_10X8}, | 146 | {TextureFormat::ASTC_2D_10X8, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_10X8_UNORM}, |
| 142 | {TextureFormat::ASTC_2D_10X8, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_10X8_SRGB}, | 147 | {TextureFormat::ASTC_2D_10X8, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_10X8_SRGB}, |
| 143 | 148 | ||
| 144 | {TextureFormat::ASTC_2D_6X6, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_6X6}, | 149 | {TextureFormat::ASTC_2D_6X6, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_6X6_UNORM}, |
| 145 | {TextureFormat::ASTC_2D_6X6, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_6X6_SRGB}, | 150 | {TextureFormat::ASTC_2D_6X6, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_6X6_SRGB}, |
| 146 | 151 | ||
| 147 | {TextureFormat::ASTC_2D_10X10, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_10X10}, | 152 | {TextureFormat::ASTC_2D_10X10, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_10X10_UNORM}, |
| 148 | {TextureFormat::ASTC_2D_10X10, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_10X10_SRGB}, | 153 | {TextureFormat::ASTC_2D_10X10, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_10X10_SRGB}, |
| 149 | 154 | ||
| 150 | {TextureFormat::ASTC_2D_12X12, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_12X12}, | 155 | {TextureFormat::ASTC_2D_12X12, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_12X12_UNORM}, |
| 151 | {TextureFormat::ASTC_2D_12X12, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_12X12_SRGB}, | 156 | {TextureFormat::ASTC_2D_12X12, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_12X12_SRGB}, |
| 152 | 157 | ||
| 153 | {TextureFormat::ASTC_2D_8X6, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_8X6}, | 158 | {TextureFormat::ASTC_2D_8X6, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_8X6_UNORM}, |
| 154 | {TextureFormat::ASTC_2D_8X6, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_8X6_SRGB}, | 159 | {TextureFormat::ASTC_2D_8X6, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_8X6_SRGB}, |
| 155 | 160 | ||
| 156 | {TextureFormat::ASTC_2D_6X5, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_6X5}, | 161 | {TextureFormat::ASTC_2D_6X5, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_6X5_UNORM}, |
| 157 | {TextureFormat::ASTC_2D_6X5, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_6X5_SRGB}, | 162 | {TextureFormat::ASTC_2D_6X5, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_6X5_SRGB}, |
| 158 | }}; | 163 | }}; |
| 159 | 164 | ||
| @@ -184,7 +189,7 @@ PixelFormat FormatLookupTable::GetPixelFormat(TextureFormat format, bool is_srgb | |||
| 184 | static_cast<int>(format), is_srgb, static_cast<int>(red_component), | 189 | static_cast<int>(format), is_srgb, static_cast<int>(red_component), |
| 185 | static_cast<int>(green_component), static_cast<int>(blue_component), | 190 | static_cast<int>(green_component), static_cast<int>(blue_component), |
| 186 | static_cast<int>(alpha_component)); | 191 | static_cast<int>(alpha_component)); |
| 187 | return PixelFormat::ABGR8U; | 192 | return PixelFormat::A8B8G8R8_UNORM; |
| 188 | } | 193 | } |
| 189 | 194 | ||
| 190 | void FormatLookupTable::Set(TextureFormat format, bool is_srgb, ComponentType red_component, | 195 | void FormatLookupTable::Set(TextureFormat format, bool is_srgb, ComponentType red_component, |
diff --git a/src/video_core/texture_cache/surface_base.cpp b/src/video_core/texture_cache/surface_base.cpp index 0caf3b4f0..dfcf36e0b 100644 --- a/src/video_core/texture_cache/surface_base.cpp +++ b/src/video_core/texture_cache/surface_base.cpp | |||
| @@ -228,7 +228,7 @@ void SurfaceBaseImpl::LoadBuffer(Tegra::MemoryManager& memory_manager, | |||
| 228 | } | 228 | } |
| 229 | } | 229 | } |
| 230 | 230 | ||
| 231 | if (!is_converted && params.pixel_format != PixelFormat::S8Z24) { | 231 | if (!is_converted && params.pixel_format != PixelFormat::S8_UINT_D24_UNORM) { |
| 232 | return; | 232 | return; |
| 233 | } | 233 | } |
| 234 | 234 | ||
diff --git a/src/video_core/texture_cache/surface_params.cpp b/src/video_core/texture_cache/surface_params.cpp index 921562c1f..9e5fe2374 100644 --- a/src/video_core/texture_cache/surface_params.cpp +++ b/src/video_core/texture_cache/surface_params.cpp | |||
| @@ -83,12 +83,12 @@ SurfaceParams SurfaceParams::CreateForTexture(const FormatLookupTable& lookup_ta | |||
| 83 | params.type = GetFormatType(params.pixel_format); | 83 | params.type = GetFormatType(params.pixel_format); |
| 84 | if (entry.is_shadow && params.type == SurfaceType::ColorTexture) { | 84 | if (entry.is_shadow && params.type == SurfaceType::ColorTexture) { |
| 85 | switch (params.pixel_format) { | 85 | switch (params.pixel_format) { |
| 86 | case PixelFormat::R16U: | 86 | case PixelFormat::R16_UNORM: |
| 87 | case PixelFormat::R16F: | 87 | case PixelFormat::R16_FLOAT: |
| 88 | params.pixel_format = PixelFormat::Z16; | 88 | params.pixel_format = PixelFormat::D16_UNORM; |
| 89 | break; | 89 | break; |
| 90 | case PixelFormat::R32F: | 90 | case PixelFormat::R32_FLOAT: |
| 91 | params.pixel_format = PixelFormat::Z32F; | 91 | params.pixel_format = PixelFormat::D32_FLOAT; |
| 92 | break; | 92 | break; |
| 93 | default: | 93 | default: |
| 94 | UNIMPLEMENTED_MSG("Unimplemented shadow convert format: {}", | 94 | UNIMPLEMENTED_MSG("Unimplemented shadow convert format: {}", |
| @@ -195,8 +195,8 @@ SurfaceParams SurfaceParams::CreateForFramebuffer(Core::System& system, std::siz | |||
| 195 | SurfaceParams params; | 195 | SurfaceParams params; |
| 196 | params.is_tiled = | 196 | params.is_tiled = |
| 197 | config.memory_layout.type == Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout::BlockLinear; | 197 | config.memory_layout.type == Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout::BlockLinear; |
| 198 | params.srgb_conversion = config.format == Tegra::RenderTargetFormat::BGRA8_SRGB || | 198 | params.srgb_conversion = config.format == Tegra::RenderTargetFormat::B8G8R8A8_SRGB || |
| 199 | config.format == Tegra::RenderTargetFormat::RGBA8_SRGB; | 199 | config.format == Tegra::RenderTargetFormat::A8B8G8R8_SRGB; |
| 200 | params.block_width = config.memory_layout.block_width; | 200 | params.block_width = config.memory_layout.block_width; |
| 201 | params.block_height = config.memory_layout.block_height; | 201 | params.block_height = config.memory_layout.block_height; |
| 202 | params.block_depth = config.memory_layout.block_depth; | 202 | params.block_depth = config.memory_layout.block_depth; |
| @@ -235,8 +235,8 @@ SurfaceParams SurfaceParams::CreateForFermiCopySurface( | |||
| 235 | const Tegra::Engines::Fermi2D::Regs::Surface& config) { | 235 | const Tegra::Engines::Fermi2D::Regs::Surface& config) { |
| 236 | SurfaceParams params{}; | 236 | SurfaceParams params{}; |
| 237 | params.is_tiled = !config.linear; | 237 | params.is_tiled = !config.linear; |
| 238 | params.srgb_conversion = config.format == Tegra::RenderTargetFormat::BGRA8_SRGB || | 238 | params.srgb_conversion = config.format == Tegra::RenderTargetFormat::B8G8R8A8_SRGB || |
| 239 | config.format == Tegra::RenderTargetFormat::RGBA8_SRGB; | 239 | config.format == Tegra::RenderTargetFormat::A8B8G8R8_SRGB; |
| 240 | params.block_width = params.is_tiled ? std::min(config.BlockWidth(), 5U) : 0, | 240 | params.block_width = params.is_tiled ? std::min(config.BlockWidth(), 5U) : 0, |
| 241 | params.block_height = params.is_tiled ? std::min(config.BlockHeight(), 5U) : 0, | 241 | params.block_height = params.is_tiled ? std::min(config.BlockHeight(), 5U) : 0, |
| 242 | params.block_depth = params.is_tiled ? std::min(config.BlockDepth(), 5U) : 0, | 242 | params.block_depth = params.is_tiled ? std::min(config.BlockDepth(), 5U) : 0, |
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index cdcddb225..96c4e4cc2 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h | |||
| @@ -373,9 +373,9 @@ protected: | |||
| 373 | siblings_table[static_cast<std::size_t>(b)] = a; | 373 | siblings_table[static_cast<std::size_t>(b)] = a; |
| 374 | }; | 374 | }; |
| 375 | std::fill(siblings_table.begin(), siblings_table.end(), PixelFormat::Invalid); | 375 | std::fill(siblings_table.begin(), siblings_table.end(), PixelFormat::Invalid); |
| 376 | make_siblings(PixelFormat::Z16, PixelFormat::R16U); | 376 | make_siblings(PixelFormat::D16_UNORM, PixelFormat::R16_UNORM); |
| 377 | make_siblings(PixelFormat::Z32F, PixelFormat::R32F); | 377 | make_siblings(PixelFormat::D32_FLOAT, PixelFormat::R32_FLOAT); |
| 378 | make_siblings(PixelFormat::Z32FS8, PixelFormat::RG32F); | 378 | make_siblings(PixelFormat::D32_FLOAT_S8_UINT, PixelFormat::R32G32_FLOAT); |
| 379 | 379 | ||
| 380 | sampled_textures.reserve(64); | 380 | sampled_textures.reserve(64); |
| 381 | } | 381 | } |
| @@ -1031,7 +1031,7 @@ private: | |||
| 1031 | params.pitch = 4; | 1031 | params.pitch = 4; |
| 1032 | params.num_levels = 1; | 1032 | params.num_levels = 1; |
| 1033 | params.emulated_levels = 1; | 1033 | params.emulated_levels = 1; |
| 1034 | params.pixel_format = VideoCore::Surface::PixelFormat::R8U; | 1034 | params.pixel_format = VideoCore::Surface::PixelFormat::R8_UNORM; |
| 1035 | params.type = VideoCore::Surface::SurfaceType::ColorTexture; | 1035 | params.type = VideoCore::Surface::SurfaceType::ColorTexture; |
| 1036 | auto surface = CreateSurface(0ULL, params); | 1036 | auto surface = CreateSurface(0ULL, params); |
| 1037 | invalid_memory.resize(surface->GetHostSizeInBytes(), 0U); | 1037 | invalid_memory.resize(surface->GetHostSizeInBytes(), 0U); |
diff --git a/src/video_core/textures/convert.cpp b/src/video_core/textures/convert.cpp index f3efa7eb0..962921483 100644 --- a/src/video_core/textures/convert.cpp +++ b/src/video_core/textures/convert.cpp | |||
| @@ -35,7 +35,7 @@ void SwapS8Z24ToZ24S8(u8* data, u32 width, u32 height) { | |||
| 35 | S8Z24 s8z24_pixel{}; | 35 | S8Z24 s8z24_pixel{}; |
| 36 | Z24S8 z24s8_pixel{}; | 36 | Z24S8 z24s8_pixel{}; |
| 37 | constexpr auto bpp{ | 37 | constexpr auto bpp{ |
| 38 | VideoCore::Surface::GetBytesPerPixel(VideoCore::Surface::PixelFormat::S8Z24)}; | 38 | VideoCore::Surface::GetBytesPerPixel(VideoCore::Surface::PixelFormat::S8_UINT_D24_UNORM)}; |
| 39 | for (std::size_t y = 0; y < height; ++y) { | 39 | for (std::size_t y = 0; y < height; ++y) { |
| 40 | for (std::size_t x = 0; x < width; ++x) { | 40 | for (std::size_t x = 0; x < width; ++x) { |
| 41 | const std::size_t offset{bpp * (y * width + x)}; | 41 | const std::size_t offset{bpp * (y * width + x)}; |
| @@ -73,7 +73,7 @@ void ConvertFromGuestToHost(u8* in_data, u8* out_data, PixelFormat pixel_format, | |||
| 73 | in_data, width, height, depth, block_width, block_height); | 73 | in_data, width, height, depth, block_width, block_height); |
| 74 | std::copy(rgba8_data.begin(), rgba8_data.end(), out_data); | 74 | std::copy(rgba8_data.begin(), rgba8_data.end(), out_data); |
| 75 | 75 | ||
| 76 | } else if (convert_s8z24 && pixel_format == PixelFormat::S8Z24) { | 76 | } else if (convert_s8z24 && pixel_format == PixelFormat::S8_UINT_D24_UNORM) { |
| 77 | Tegra::Texture::ConvertS8Z24ToZ24S8(in_data, width, height); | 77 | Tegra::Texture::ConvertS8Z24ToZ24S8(in_data, width, height); |
| 78 | } | 78 | } |
| 79 | } | 79 | } |
| @@ -85,7 +85,7 @@ void ConvertFromHostToGuest(u8* data, PixelFormat pixel_format, u32 width, u32 h | |||
| 85 | static_cast<u32>(pixel_format)); | 85 | static_cast<u32>(pixel_format)); |
| 86 | UNREACHABLE(); | 86 | UNREACHABLE(); |
| 87 | 87 | ||
| 88 | } else if (convert_s8z24 && pixel_format == PixelFormat::S8Z24) { | 88 | } else if (convert_s8z24 && pixel_format == PixelFormat::S8_UINT_D24_UNORM) { |
| 89 | Tegra::Texture::ConvertZ24S8ToS8Z24(data, width, height); | 89 | Tegra::Texture::ConvertZ24S8ToS8Z24(data, width, height); |
| 90 | } | 90 | } |
| 91 | } | 91 | } |
diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp index 98beabef1..474ae620a 100644 --- a/src/video_core/textures/decoders.cpp +++ b/src/video_core/textures/decoders.cpp | |||
| @@ -184,53 +184,6 @@ void CopySwizzledData(u32 width, u32 height, u32 depth, u32 bytes_per_pixel, | |||
| 184 | } | 184 | } |
| 185 | } | 185 | } |
| 186 | 186 | ||
| 187 | u32 BytesPerPixel(TextureFormat format) { | ||
| 188 | switch (format) { | ||
| 189 | case TextureFormat::DXT1: | ||
| 190 | case TextureFormat::DXN1: | ||
| 191 | // In this case a 'pixel' actually refers to a 4x4 tile. | ||
| 192 | return 8; | ||
| 193 | case TextureFormat::DXT23: | ||
| 194 | case TextureFormat::DXT45: | ||
| 195 | case TextureFormat::DXN2: | ||
| 196 | case TextureFormat::BC7U: | ||
| 197 | case TextureFormat::BC6H_UF16: | ||
| 198 | case TextureFormat::BC6H_SF16: | ||
| 199 | // In this case a 'pixel' actually refers to a 4x4 tile. | ||
| 200 | return 16; | ||
| 201 | case TextureFormat::R32_G32_B32: | ||
| 202 | return 12; | ||
| 203 | case TextureFormat::ASTC_2D_4X4: | ||
| 204 | case TextureFormat::ASTC_2D_5X4: | ||
| 205 | case TextureFormat::ASTC_2D_8X8: | ||
| 206 | case TextureFormat::ASTC_2D_8X5: | ||
| 207 | case TextureFormat::ASTC_2D_10X8: | ||
| 208 | case TextureFormat::ASTC_2D_5X5: | ||
| 209 | case TextureFormat::A8R8G8B8: | ||
| 210 | case TextureFormat::A2B10G10R10: | ||
| 211 | case TextureFormat::BF10GF11RF11: | ||
| 212 | case TextureFormat::R32: | ||
| 213 | case TextureFormat::R16_G16: | ||
| 214 | return 4; | ||
| 215 | case TextureFormat::A1B5G5R5: | ||
| 216 | case TextureFormat::B5G6R5: | ||
| 217 | case TextureFormat::G8R8: | ||
| 218 | case TextureFormat::R16: | ||
| 219 | return 2; | ||
| 220 | case TextureFormat::R8: | ||
| 221 | return 1; | ||
| 222 | case TextureFormat::R16_G16_B16_A16: | ||
| 223 | return 8; | ||
| 224 | case TextureFormat::R32_G32_B32_A32: | ||
| 225 | return 16; | ||
| 226 | case TextureFormat::R32_G32: | ||
| 227 | return 8; | ||
| 228 | default: | ||
| 229 | UNIMPLEMENTED_MSG("Format not implemented"); | ||
| 230 | return 1; | ||
| 231 | } | ||
| 232 | } | ||
| 233 | |||
| 234 | void UnswizzleTexture(u8* const unswizzled_data, u8* address, u32 tile_size_x, u32 tile_size_y, | 187 | void UnswizzleTexture(u8* const unswizzled_data, u8* address, u32 tile_size_x, u32 tile_size_y, |
| 235 | u32 bytes_per_pixel, u32 width, u32 height, u32 depth, u32 block_height, | 188 | u32 bytes_per_pixel, u32 width, u32 height, u32 depth, u32 block_height, |
| 236 | u32 block_depth, u32 width_spacing) { | 189 | u32 block_depth, u32 width_spacing) { |
| @@ -348,48 +301,6 @@ void SwizzleKepler(const u32 width, const u32 height, const u32 dst_x, const u32 | |||
| 348 | } | 301 | } |
| 349 | } | 302 | } |
| 350 | 303 | ||
| 351 | std::vector<u8> DecodeTexture(const std::vector<u8>& texture_data, TextureFormat format, u32 width, | ||
| 352 | u32 height) { | ||
| 353 | std::vector<u8> rgba_data; | ||
| 354 | |||
| 355 | // TODO(Subv): Implement. | ||
| 356 | switch (format) { | ||
| 357 | case TextureFormat::DXT1: | ||
| 358 | case TextureFormat::DXT23: | ||
| 359 | case TextureFormat::DXT45: | ||
| 360 | case TextureFormat::DXN1: | ||
| 361 | case TextureFormat::DXN2: | ||
| 362 | case TextureFormat::BC7U: | ||
| 363 | case TextureFormat::BC6H_UF16: | ||
| 364 | case TextureFormat::BC6H_SF16: | ||
| 365 | case TextureFormat::ASTC_2D_4X4: | ||
| 366 | case TextureFormat::ASTC_2D_8X8: | ||
| 367 | case TextureFormat::ASTC_2D_5X5: | ||
| 368 | case TextureFormat::ASTC_2D_10X8: | ||
| 369 | case TextureFormat::A8R8G8B8: | ||
| 370 | case TextureFormat::A2B10G10R10: | ||
| 371 | case TextureFormat::A1B5G5R5: | ||
| 372 | case TextureFormat::B5G6R5: | ||
| 373 | case TextureFormat::R8: | ||
| 374 | case TextureFormat::G8R8: | ||
| 375 | case TextureFormat::BF10GF11RF11: | ||
| 376 | case TextureFormat::R32_G32_B32_A32: | ||
| 377 | case TextureFormat::R32_G32: | ||
| 378 | case TextureFormat::R32: | ||
| 379 | case TextureFormat::R16: | ||
| 380 | case TextureFormat::R16_G16: | ||
| 381 | case TextureFormat::R32_G32_B32: | ||
| 382 | // TODO(Subv): For the time being just forward the same data without any decoding. | ||
| 383 | rgba_data = texture_data; | ||
| 384 | break; | ||
| 385 | default: | ||
| 386 | UNIMPLEMENTED_MSG("Format not implemented"); | ||
| 387 | break; | ||
| 388 | } | ||
| 389 | |||
| 390 | return rgba_data; | ||
| 391 | } | ||
| 392 | |||
| 393 | std::size_t CalculateSize(bool tiled, u32 bytes_per_pixel, u32 width, u32 height, u32 depth, | 304 | std::size_t CalculateSize(bool tiled, u32 bytes_per_pixel, u32 width, u32 height, u32 depth, |
| 394 | u32 block_height, u32 block_depth) { | 305 | u32 block_height, u32 block_depth) { |
| 395 | if (tiled) { | 306 | if (tiled) { |
diff --git a/src/video_core/textures/decoders.h b/src/video_core/textures/decoders.h index 232b696b3..d6fe35d37 100644 --- a/src/video_core/textures/decoders.h +++ b/src/video_core/textures/decoders.h | |||
| @@ -38,10 +38,6 @@ void CopySwizzledData(u32 width, u32 height, u32 depth, u32 bytes_per_pixel, | |||
| 38 | u32 out_bytes_per_pixel, u8* swizzled_data, u8* unswizzled_data, | 38 | u32 out_bytes_per_pixel, u8* swizzled_data, u8* unswizzled_data, |
| 39 | bool unswizzle, u32 block_height, u32 block_depth, u32 width_spacing); | 39 | bool unswizzle, u32 block_height, u32 block_depth, u32 width_spacing); |
| 40 | 40 | ||
| 41 | /// Decodes an unswizzled texture into a A8R8G8B8 texture. | ||
| 42 | std::vector<u8> DecodeTexture(const std::vector<u8>& texture_data, TextureFormat format, u32 width, | ||
| 43 | u32 height); | ||
| 44 | |||
| 45 | /// This function calculates the correct size of a texture depending if it's tiled or not. | 41 | /// This function calculates the correct size of a texture depending if it's tiled or not. |
| 46 | std::size_t CalculateSize(bool tiled, u32 bytes_per_pixel, u32 width, u32 height, u32 depth, | 42 | std::size_t CalculateSize(bool tiled, u32 bytes_per_pixel, u32 width, u32 height, u32 depth, |
| 47 | u32 block_height, u32 block_depth); | 43 | u32 block_height, u32 block_depth); |
diff --git a/src/video_core/textures/texture.h b/src/video_core/textures/texture.h index eba05aced..0574fef12 100644 --- a/src/video_core/textures/texture.h +++ b/src/video_core/textures/texture.h | |||
| @@ -12,10 +12,10 @@ | |||
| 12 | namespace Tegra::Texture { | 12 | namespace Tegra::Texture { |
| 13 | 13 | ||
| 14 | enum class TextureFormat : u32 { | 14 | enum class TextureFormat : u32 { |
| 15 | R32_G32_B32_A32 = 0x01, | 15 | R32G32B32A32 = 0x01, |
| 16 | R32_G32_B32 = 0x02, | 16 | R32G32B32 = 0x02, |
| 17 | R16_G16_B16_A16 = 0x03, | 17 | R16G16B16A16 = 0x03, |
| 18 | R32_G32 = 0x04, | 18 | R32G32 = 0x04, |
| 19 | R32_B24G8 = 0x05, | 19 | R32_B24G8 = 0x05, |
| 20 | ETC2_RGB = 0x06, | 20 | ETC2_RGB = 0x06, |
| 21 | X8B8G8R8 = 0x07, | 21 | X8B8G8R8 = 0x07, |
| @@ -23,19 +23,19 @@ enum class TextureFormat : u32 { | |||
| 23 | A2B10G10R10 = 0x09, | 23 | A2B10G10R10 = 0x09, |
| 24 | ETC2_RGB_PTA = 0x0a, | 24 | ETC2_RGB_PTA = 0x0a, |
| 25 | ETC2_RGBA = 0x0b, | 25 | ETC2_RGBA = 0x0b, |
| 26 | R16_G16 = 0x0c, | 26 | R16G16 = 0x0c, |
| 27 | G8R24 = 0x0d, | 27 | R24G8 = 0x0d, |
| 28 | G24R8 = 0x0e, | 28 | R8G24 = 0x0e, |
| 29 | R32 = 0x0f, | 29 | R32 = 0x0f, |
| 30 | BC6H_SF16 = 0x10, | 30 | BC6H_SFLOAT = 0x10, |
| 31 | BC6H_UF16 = 0x11, | 31 | BC6H_UFLOAT = 0x11, |
| 32 | A4B4G4R4 = 0x12, | 32 | A4B4G4R4 = 0x12, |
| 33 | A5B5G5R1 = 0x13, | 33 | A5B5G5R1 = 0x13, |
| 34 | A1B5G5R5 = 0x14, | 34 | A1B5G5R5 = 0x14, |
| 35 | B5G6R5 = 0x15, | 35 | B5G6R5 = 0x15, |
| 36 | B6G5R5 = 0x16, | 36 | B6G5R5 = 0x16, |
| 37 | BC7U = 0x17, | 37 | BC7 = 0x17, |
| 38 | G8R8 = 0x18, | 38 | R8G8 = 0x18, |
| 39 | EAC = 0x19, | 39 | EAC = 0x19, |
| 40 | EACX2 = 0x1a, | 40 | EACX2 = 0x1a, |
| 41 | R16 = 0x1b, | 41 | R16 = 0x1b, |
| @@ -43,23 +43,23 @@ enum class TextureFormat : u32 { | |||
| 43 | R8 = 0x1d, | 43 | R8 = 0x1d, |
| 44 | G4R4 = 0x1e, | 44 | G4R4 = 0x1e, |
| 45 | R1 = 0x1f, | 45 | R1 = 0x1f, |
| 46 | E5B9G9R9_SHAREDEXP = 0x20, | 46 | E5B9G9R9 = 0x20, |
| 47 | BF10GF11RF11 = 0x21, | 47 | B10G11R11 = 0x21, |
| 48 | G8B8G8R8 = 0x22, | 48 | G8B8G8R8 = 0x22, |
| 49 | B8G8R8G8 = 0x23, | 49 | B8G8R8G8 = 0x23, |
| 50 | DXT1 = 0x24, | 50 | BC1_RGBA = 0x24, |
| 51 | DXT23 = 0x25, | 51 | BC2 = 0x25, |
| 52 | DXT45 = 0x26, | 52 | BC3 = 0x26, |
| 53 | DXN1 = 0x27, | 53 | BC4 = 0x27, |
| 54 | DXN2 = 0x28, | 54 | BC5 = 0x28, |
| 55 | S8Z24 = 0x29, | 55 | S8D24 = 0x29, |
| 56 | X8Z24 = 0x2a, | 56 | X8Z24 = 0x2a, |
| 57 | Z24S8 = 0x2b, | 57 | D24S8 = 0x2b, |
| 58 | X4V4Z24__COV4R4V = 0x2c, | 58 | X4V4Z24__COV4R4V = 0x2c, |
| 59 | X4V4Z24__COV8R8V = 0x2d, | 59 | X4V4Z24__COV8R8V = 0x2d, |
| 60 | V8Z24__COV4R12V = 0x2e, | 60 | V8Z24__COV4R12V = 0x2e, |
| 61 | ZF32 = 0x2f, | 61 | D32 = 0x2f, |
| 62 | ZF32_X24S8 = 0x30, | 62 | D32S8 = 0x30, |
| 63 | X8Z24_X20V4S8__COV4R4V = 0x31, | 63 | X8Z24_X20V4S8__COV4R4V = 0x31, |
| 64 | X8Z24_X20V4S8__COV8R8V = 0x32, | 64 | X8Z24_X20V4S8__COV8R8V = 0x32, |
| 65 | ZF32_X20V4X8__COV4R4V = 0x33, | 65 | ZF32_X20V4X8__COV4R4V = 0x33, |
| @@ -69,7 +69,7 @@ enum class TextureFormat : u32 { | |||
| 69 | X8Z24_X16V8S8__COV4R12V = 0x37, | 69 | X8Z24_X16V8S8__COV4R12V = 0x37, |
| 70 | ZF32_X16V8X8__COV4R12V = 0x38, | 70 | ZF32_X16V8X8__COV4R12V = 0x38, |
| 71 | ZF32_X16V8S8__COV4R12V = 0x39, | 71 | ZF32_X16V8S8__COV4R12V = 0x39, |
| 72 | Z16 = 0x3a, | 72 | D16 = 0x3a, |
| 73 | V8Z24__COV8R24V = 0x3b, | 73 | V8Z24__COV8R24V = 0x3b, |
| 74 | X8Z24_X16V8S8__COV8R24V = 0x3c, | 74 | X8Z24_X16V8S8__COV8R24V = 0x3c, |
| 75 | ZF32_X16V8X8__COV8R24V = 0x3d, | 75 | ZF32_X16V8X8__COV8R24V = 0x3d, |
| @@ -375,7 +375,4 @@ struct FullTextureInfo { | |||
| 375 | TSCEntry tsc; | 375 | TSCEntry tsc; |
| 376 | }; | 376 | }; |
| 377 | 377 | ||
| 378 | /// Returns the number of bytes per pixel of the input texture format. | ||
| 379 | u32 BytesPerPixel(TextureFormat format); | ||
| 380 | |||
| 381 | } // namespace Tegra::Texture | 378 | } // namespace Tegra::Texture |