diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp | 6 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvdisp_disp0.h | 4 | ||||
| -rw-r--r-- | src/core/hle/service/nvflinger/buffer_queue.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/service/nvflinger/buffer_queue.h | 5 | ||||
| -rw-r--r-- | src/core/hle/service/nvflinger/nvflinger.cpp | 3 | ||||
| -rw-r--r-- | src/core/hle/service/vi/vi.cpp | 20 | ||||
| -rw-r--r-- | src/video_core/gpu.h | 1 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.cpp | 22 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.h | 1 | ||||
| -rw-r--r-- | src/video_core/textures/astc.cpp | 138 | ||||
| -rw-r--r-- | src/yuzu/configuration/config.cpp | 2 | ||||
| -rw-r--r-- | src/yuzu_cmd/config.cpp | 2 | ||||
| -rw-r--r-- | src/yuzu_cmd/default_ini.h | 2 |
13 files changed, 112 insertions, 98 deletions
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp index c39d5a164..ed69a4325 100644 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp | |||
| @@ -18,7 +18,8 @@ u32 nvdisp_disp0::ioctl(Ioctl command, const std::vector<u8>& input, std::vector | |||
| 18 | } | 18 | } |
| 19 | 19 | ||
| 20 | void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height, | 20 | void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height, |
| 21 | u32 stride, NVFlinger::BufferQueue::BufferTransformFlags transform) { | 21 | u32 stride, NVFlinger::BufferQueue::BufferTransformFlags transform, |
| 22 | const MathUtil::Rectangle<int>& crop_rect) { | ||
| 22 | VAddr addr = nvmap_dev->GetObjectAddress(buffer_handle); | 23 | VAddr addr = nvmap_dev->GetObjectAddress(buffer_handle); |
| 23 | LOG_WARNING(Service, | 24 | LOG_WARNING(Service, |
| 24 | "Drawing from address {:X} offset {:08X} Width {} Height {} Stride {} Format {}", | 25 | "Drawing from address {:X} offset {:08X} Width {} Height {} Stride {} Format {}", |
| @@ -26,7 +27,8 @@ void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u3 | |||
| 26 | 27 | ||
| 27 | using PixelFormat = Tegra::FramebufferConfig::PixelFormat; | 28 | using PixelFormat = Tegra::FramebufferConfig::PixelFormat; |
| 28 | const Tegra::FramebufferConfig framebuffer{ | 29 | const Tegra::FramebufferConfig framebuffer{ |
| 29 | addr, offset, width, height, stride, static_cast<PixelFormat>(format), transform}; | 30 | addr, offset, width, height, stride, static_cast<PixelFormat>(format), |
| 31 | transform, crop_rect}; | ||
| 30 | 32 | ||
| 31 | Core::System::GetInstance().perf_stats.EndGameFrame(); | 33 | Core::System::GetInstance().perf_stats.EndGameFrame(); |
| 32 | 34 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h index 3d3979723..d4631a32b 100644 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #include <memory> | 7 | #include <memory> |
| 8 | #include <vector> | 8 | #include <vector> |
| 9 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 10 | #include "common/math_util.h" | ||
| 10 | #include "core/hle/service/nvdrv/devices/nvdevice.h" | 11 | #include "core/hle/service/nvdrv/devices/nvdevice.h" |
| 11 | #include "core/hle/service/nvflinger/buffer_queue.h" | 12 | #include "core/hle/service/nvflinger/buffer_queue.h" |
| 12 | 13 | ||
| @@ -23,7 +24,8 @@ public: | |||
| 23 | 24 | ||
| 24 | /// Performs a screen flip, drawing the buffer pointed to by the handle. | 25 | /// Performs a screen flip, drawing the buffer pointed to by the handle. |
| 25 | void flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height, u32 stride, | 26 | void flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height, u32 stride, |
| 26 | NVFlinger::BufferQueue::BufferTransformFlags transform); | 27 | NVFlinger::BufferQueue::BufferTransformFlags transform, |
| 28 | const MathUtil::Rectangle<int>& crop_rect); | ||
| 27 | 29 | ||
| 28 | private: | 30 | private: |
| 29 | std::shared_ptr<nvmap> nvmap_dev; | 31 | std::shared_ptr<nvmap> nvmap_dev; |
diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp index a181cd2dc..7132b18ad 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue.cpp | |||
| @@ -57,13 +57,15 @@ const IGBPBuffer& BufferQueue::RequestBuffer(u32 slot) const { | |||
| 57 | return itr->igbp_buffer; | 57 | return itr->igbp_buffer; |
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | void BufferQueue::QueueBuffer(u32 slot, BufferTransformFlags transform) { | 60 | void BufferQueue::QueueBuffer(u32 slot, BufferTransformFlags transform, |
| 61 | const MathUtil::Rectangle<int>& crop_rect) { | ||
| 61 | auto itr = std::find_if(queue.begin(), queue.end(), | 62 | auto itr = std::find_if(queue.begin(), queue.end(), |
| 62 | [&](const Buffer& buffer) { return buffer.slot == slot; }); | 63 | [&](const Buffer& buffer) { return buffer.slot == slot; }); |
| 63 | ASSERT(itr != queue.end()); | 64 | ASSERT(itr != queue.end()); |
| 64 | ASSERT(itr->status == Buffer::Status::Dequeued); | 65 | ASSERT(itr->status == Buffer::Status::Dequeued); |
| 65 | itr->status = Buffer::Status::Queued; | 66 | itr->status = Buffer::Status::Queued; |
| 66 | itr->transform = transform; | 67 | itr->transform = transform; |
| 68 | itr->crop_rect = crop_rect; | ||
| 67 | } | 69 | } |
| 68 | 70 | ||
| 69 | boost::optional<const BufferQueue::Buffer&> BufferQueue::AcquireBuffer() { | 71 | boost::optional<const BufferQueue::Buffer&> BufferQueue::AcquireBuffer() { |
diff --git a/src/core/hle/service/nvflinger/buffer_queue.h b/src/core/hle/service/nvflinger/buffer_queue.h index 1e55b487e..004170538 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.h +++ b/src/core/hle/service/nvflinger/buffer_queue.h | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | #include <vector> | 7 | #include <vector> |
| 8 | #include <boost/optional.hpp> | 8 | #include <boost/optional.hpp> |
| 9 | #include "common/math_util.h" | ||
| 9 | #include "common/swap.h" | 10 | #include "common/swap.h" |
| 10 | #include "core/hle/kernel/event.h" | 11 | #include "core/hle/kernel/event.h" |
| 11 | 12 | ||
| @@ -68,12 +69,14 @@ public: | |||
| 68 | Status status = Status::Free; | 69 | Status status = Status::Free; |
| 69 | IGBPBuffer igbp_buffer; | 70 | IGBPBuffer igbp_buffer; |
| 70 | BufferTransformFlags transform; | 71 | BufferTransformFlags transform; |
| 72 | MathUtil::Rectangle<int> crop_rect; | ||
| 71 | }; | 73 | }; |
| 72 | 74 | ||
| 73 | void SetPreallocatedBuffer(u32 slot, IGBPBuffer& buffer); | 75 | void SetPreallocatedBuffer(u32 slot, IGBPBuffer& buffer); |
| 74 | boost::optional<u32> DequeueBuffer(u32 width, u32 height); | 76 | boost::optional<u32> DequeueBuffer(u32 width, u32 height); |
| 75 | const IGBPBuffer& RequestBuffer(u32 slot) const; | 77 | const IGBPBuffer& RequestBuffer(u32 slot) const; |
| 76 | void QueueBuffer(u32 slot, BufferTransformFlags transform); | 78 | void QueueBuffer(u32 slot, BufferTransformFlags transform, |
| 79 | const MathUtil::Rectangle<int>& crop_rect); | ||
| 77 | boost::optional<const Buffer&> AcquireBuffer(); | 80 | boost::optional<const Buffer&> AcquireBuffer(); |
| 78 | void ReleaseBuffer(u32 slot); | 81 | void ReleaseBuffer(u32 slot); |
| 79 | u32 Query(QueryType type); | 82 | u32 Query(QueryType type); |
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp index 826646b7d..d580f779e 100644 --- a/src/core/hle/service/nvflinger/nvflinger.cpp +++ b/src/core/hle/service/nvflinger/nvflinger.cpp | |||
| @@ -149,7 +149,8 @@ void NVFlinger::Compose() { | |||
| 149 | ASSERT(nvdisp); | 149 | ASSERT(nvdisp); |
| 150 | 150 | ||
| 151 | nvdisp->flip(igbp_buffer.gpu_buffer_id, igbp_buffer.offset, igbp_buffer.format, | 151 | nvdisp->flip(igbp_buffer.gpu_buffer_id, igbp_buffer.offset, igbp_buffer.format, |
| 152 | igbp_buffer.width, igbp_buffer.height, igbp_buffer.stride, buffer->transform); | 152 | igbp_buffer.width, igbp_buffer.height, igbp_buffer.stride, buffer->transform, |
| 153 | buffer->crop_rect); | ||
| 153 | 154 | ||
| 154 | buffer_queue->ReleaseBuffer(buffer->slot); | 155 | buffer_queue->ReleaseBuffer(buffer->slot); |
| 155 | } | 156 | } |
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index e094510bf..eccee6e33 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #include <memory> | 7 | #include <memory> |
| 8 | #include <boost/optional.hpp> | 8 | #include <boost/optional.hpp> |
| 9 | #include "common/alignment.h" | 9 | #include "common/alignment.h" |
| 10 | #include "common/math_util.h" | ||
| 10 | #include "common/scope_exit.h" | 11 | #include "common/scope_exit.h" |
| 11 | #include "core/core_timing.h" | 12 | #include "core/core_timing.h" |
| 12 | #include "core/hle/ipc_helpers.h" | 13 | #include "core/hle/ipc_helpers.h" |
| @@ -27,8 +28,8 @@ struct DisplayInfo { | |||
| 27 | char display_name[0x40]{"Default"}; | 28 | char display_name[0x40]{"Default"}; |
| 28 | u64 unknown_1{1}; | 29 | u64 unknown_1{1}; |
| 29 | u64 unknown_2{1}; | 30 | u64 unknown_2{1}; |
| 30 | u64 width{1920}; | 31 | u64 width{1280}; |
| 31 | u64 height{1080}; | 32 | u64 height{720}; |
| 32 | }; | 33 | }; |
| 33 | static_assert(sizeof(DisplayInfo) == 0x60, "DisplayInfo has wrong size"); | 34 | static_assert(sizeof(DisplayInfo) == 0x60, "DisplayInfo has wrong size"); |
| 34 | 35 | ||
| @@ -327,8 +328,8 @@ public: | |||
| 327 | 328 | ||
| 328 | protected: | 329 | protected: |
| 329 | void SerializeData() override { | 330 | void SerializeData() override { |
| 330 | // TODO(Subv): Figure out what this value means, writing non-zero here will make libnx try | 331 | // TODO(Subv): Figure out what this value means, writing non-zero here will make libnx |
| 331 | // to read an IGBPBuffer object from the parcel. | 332 | // try to read an IGBPBuffer object from the parcel. |
| 332 | Write<u32_le>(1); | 333 | Write<u32_le>(1); |
| 333 | WriteObject(buffer); | 334 | WriteObject(buffer); |
| 334 | Write<u32_le>(0); | 335 | Write<u32_le>(0); |
| @@ -360,8 +361,8 @@ public: | |||
| 360 | INSERT_PADDING_WORDS(3); | 361 | INSERT_PADDING_WORDS(3); |
| 361 | u32_le timestamp; | 362 | u32_le timestamp; |
| 362 | s32_le is_auto_timestamp; | 363 | s32_le is_auto_timestamp; |
| 363 | s32_le crop_left; | ||
| 364 | s32_le crop_top; | 364 | s32_le crop_top; |
| 365 | s32_le crop_left; | ||
| 365 | s32_le crop_right; | 366 | s32_le crop_right; |
| 366 | s32_le crop_bottom; | 367 | s32_le crop_bottom; |
| 367 | s32_le scaling_mode; | 368 | s32_le scaling_mode; |
| @@ -370,6 +371,10 @@ public: | |||
| 370 | INSERT_PADDING_WORDS(2); | 371 | INSERT_PADDING_WORDS(2); |
| 371 | u32_le fence_is_valid; | 372 | u32_le fence_is_valid; |
| 372 | std::array<Fence, 2> fences; | 373 | std::array<Fence, 2> fences; |
| 374 | |||
| 375 | MathUtil::Rectangle<int> GetCropRect() const { | ||
| 376 | return {crop_left, crop_top, crop_right, crop_bottom}; | ||
| 377 | } | ||
| 373 | }; | 378 | }; |
| 374 | static_assert(sizeof(Data) == 80, "ParcelData has wrong size"); | 379 | static_assert(sizeof(Data) == 80, "ParcelData has wrong size"); |
| 375 | 380 | ||
| @@ -519,7 +524,8 @@ private: | |||
| 519 | } else if (transaction == TransactionId::QueueBuffer) { | 524 | } else if (transaction == TransactionId::QueueBuffer) { |
| 520 | IGBPQueueBufferRequestParcel request{ctx.ReadBuffer()}; | 525 | IGBPQueueBufferRequestParcel request{ctx.ReadBuffer()}; |
| 521 | 526 | ||
| 522 | buffer_queue->QueueBuffer(request.data.slot, request.data.transform); | 527 | buffer_queue->QueueBuffer(request.data.slot, request.data.transform, |
| 528 | request.data.GetCropRect()); | ||
| 523 | 529 | ||
| 524 | IGBPQueueBufferResponseParcel response{1280, 720}; | 530 | IGBPQueueBufferResponseParcel response{1280, 720}; |
| 525 | ctx.WriteBuffer(response.Serialize()); | 531 | ctx.WriteBuffer(response.Serialize()); |
| @@ -532,7 +538,7 @@ private: | |||
| 532 | IGBPQueryResponseParcel response{value}; | 538 | IGBPQueryResponseParcel response{value}; |
| 533 | ctx.WriteBuffer(response.Serialize()); | 539 | ctx.WriteBuffer(response.Serialize()); |
| 534 | } else if (transaction == TransactionId::CancelBuffer) { | 540 | } else if (transaction == TransactionId::CancelBuffer) { |
| 535 | LOG_WARNING(Service_VI, "(STUBBED) called, transaction=CancelBuffer"); | 541 | LOG_CRITICAL(Service_VI, "(STUBBED) called, transaction=CancelBuffer"); |
| 536 | } else { | 542 | } else { |
| 537 | ASSERT_MSG(false, "Unimplemented"); | 543 | ASSERT_MSG(false, "Unimplemented"); |
| 538 | } | 544 | } |
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index cc5ca656e..60930e997 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h | |||
| @@ -67,6 +67,7 @@ struct FramebufferConfig { | |||
| 67 | 67 | ||
| 68 | using TransformFlags = Service::NVFlinger::BufferQueue::BufferTransformFlags; | 68 | using TransformFlags = Service::NVFlinger::BufferQueue::BufferTransformFlags; |
| 69 | TransformFlags transform_flags; | 69 | TransformFlags transform_flags; |
| 70 | MathUtil::Rectangle<int> crop_rect; | ||
| 70 | }; | 71 | }; |
| 71 | 72 | ||
| 72 | namespace Engines { | 73 | namespace Engines { |
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 1930fa6ef..7810b9147 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp | |||
| @@ -154,6 +154,7 @@ void RendererOpenGL::LoadFBToScreenInfo(const Tegra::FramebufferConfig& framebuf | |||
| 154 | 154 | ||
| 155 | // Framebuffer orientation handling | 155 | // Framebuffer orientation handling |
| 156 | framebuffer_transform_flags = framebuffer.transform_flags; | 156 | framebuffer_transform_flags = framebuffer.transform_flags; |
| 157 | framebuffer_crop_rect = framebuffer.crop_rect; | ||
| 157 | 158 | ||
| 158 | // Ensure no bad interactions with GL_UNPACK_ALIGNMENT, which by default | 159 | // Ensure no bad interactions with GL_UNPACK_ALIGNMENT, which by default |
| 159 | // only allows rows to have a memory alignement of 4. | 160 | // only allows rows to have a memory alignement of 4. |
| @@ -320,11 +321,24 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x, | |||
| 320 | } | 321 | } |
| 321 | } | 322 | } |
| 322 | 323 | ||
| 324 | ASSERT_MSG(framebuffer_crop_rect.top == 0, "Unimplemented"); | ||
| 325 | ASSERT_MSG(framebuffer_crop_rect.left == 0, "Unimplemented"); | ||
| 326 | |||
| 327 | // Scale the output by the crop width/height. This is commonly used with 1280x720 rendering | ||
| 328 | // (e.g. handheld mode) on a 1920x1080 framebuffer. | ||
| 329 | f32 scale_u = 1.f, scale_v = 1.f; | ||
| 330 | if (framebuffer_crop_rect.GetWidth() > 0) { | ||
| 331 | scale_u = static_cast<f32>(framebuffer_crop_rect.GetWidth()) / screen_info.texture.width; | ||
| 332 | } | ||
| 333 | if (framebuffer_crop_rect.GetHeight() > 0) { | ||
| 334 | scale_v = static_cast<f32>(framebuffer_crop_rect.GetHeight()) / screen_info.texture.height; | ||
| 335 | } | ||
| 336 | |||
| 323 | std::array<ScreenRectVertex, 4> vertices = {{ | 337 | std::array<ScreenRectVertex, 4> vertices = {{ |
| 324 | ScreenRectVertex(x, y, texcoords.top, left), | 338 | ScreenRectVertex(x, y, texcoords.top * scale_u, left * scale_v), |
| 325 | ScreenRectVertex(x + w, y, texcoords.bottom, left), | 339 | ScreenRectVertex(x + w, y, texcoords.bottom * scale_u, left * scale_v), |
| 326 | ScreenRectVertex(x, y + h, texcoords.top, right), | 340 | ScreenRectVertex(x, y + h, texcoords.top * scale_u, right * scale_v), |
| 327 | ScreenRectVertex(x + w, y + h, texcoords.bottom, right), | 341 | ScreenRectVertex(x + w, y + h, texcoords.bottom * scale_u, right * scale_v), |
| 328 | }}; | 342 | }}; |
| 329 | 343 | ||
| 330 | state.texture_units[0].texture_2d = screen_info.display_texture; | 344 | state.texture_units[0].texture_2d = screen_info.display_texture; |
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h index fd0267cf5..59d92a3dc 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.h +++ b/src/video_core/renderer_opengl/renderer_opengl.h | |||
| @@ -97,4 +97,5 @@ private: | |||
| 97 | 97 | ||
| 98 | /// Used for transforming the framebuffer orientation | 98 | /// Used for transforming the framebuffer orientation |
| 99 | Tegra::FramebufferConfig::TransformFlags framebuffer_transform_flags; | 99 | Tegra::FramebufferConfig::TransformFlags framebuffer_transform_flags; |
| 100 | MathUtil::Rectangle<int> framebuffer_crop_rect; | ||
| 100 | }; | 101 | }; |
diff --git a/src/video_core/textures/astc.cpp b/src/video_core/textures/astc.cpp index 3c4ad1c9d..b1feacae9 100644 --- a/src/video_core/textures/astc.cpp +++ b/src/video_core/textures/astc.cpp | |||
| @@ -25,16 +25,15 @@ | |||
| 25 | 25 | ||
| 26 | class BitStream { | 26 | class BitStream { |
| 27 | public: | 27 | public: |
| 28 | BitStream(unsigned char* ptr, int nBits = 0, int start_offset = 0) | 28 | explicit BitStream(unsigned char* ptr, int nBits = 0, int start_offset = 0) |
| 29 | : m_BitsWritten(0), m_BitsRead(0), m_NumBits(nBits), m_CurByte(ptr), | 29 | : m_NumBits(nBits), m_CurByte(ptr), m_NextBit(start_offset % 8) {} |
| 30 | m_NextBit(start_offset % 8), done(false) {} | 30 | |
| 31 | ~BitStream() = default; | ||
| 31 | 32 | ||
| 32 | int GetBitsWritten() const { | 33 | int GetBitsWritten() const { |
| 33 | return m_BitsWritten; | 34 | return m_BitsWritten; |
| 34 | } | 35 | } |
| 35 | 36 | ||
| 36 | ~BitStream() {} | ||
| 37 | |||
| 38 | void WriteBitsR(unsigned int val, unsigned int nBits) { | 37 | void WriteBitsR(unsigned int val, unsigned int nBits) { |
| 39 | for (unsigned int i = 0; i < nBits; i++) { | 38 | for (unsigned int i = 0; i < nBits; i++) { |
| 40 | WriteBit((val >> (nBits - i - 1)) & 1); | 39 | WriteBit((val >> (nBits - i - 1)) & 1); |
| @@ -95,33 +94,28 @@ private: | |||
| 95 | done = done || ++m_BitsWritten >= m_NumBits; | 94 | done = done || ++m_BitsWritten >= m_NumBits; |
| 96 | } | 95 | } |
| 97 | 96 | ||
| 98 | int m_BitsWritten; | 97 | int m_BitsWritten = 0; |
| 99 | const int m_NumBits; | 98 | const int m_NumBits; |
| 100 | unsigned char* m_CurByte; | 99 | unsigned char* m_CurByte; |
| 101 | int m_NextBit; | 100 | int m_NextBit = 0; |
| 102 | int m_BitsRead; | 101 | int m_BitsRead = 0; |
| 103 | 102 | ||
| 104 | bool done; | 103 | bool done = false; |
| 105 | }; | 104 | }; |
| 106 | 105 | ||
| 107 | template <typename IntType> | 106 | template <typename IntType> |
| 108 | class Bits { | 107 | class Bits { |
| 109 | private: | ||
| 110 | const IntType& m_Bits; | ||
| 111 | |||
| 112 | // Don't copy | ||
| 113 | Bits() {} | ||
| 114 | Bits(const Bits&) {} | ||
| 115 | Bits& operator=(const Bits&) {} | ||
| 116 | |||
| 117 | public: | 108 | public: |
| 118 | explicit Bits(IntType& v) : m_Bits(v) {} | 109 | explicit Bits(const IntType& v) : m_Bits(v) {} |
| 119 | 110 | ||
| 120 | uint8_t operator[](uint32_t bitPos) { | 111 | Bits(const Bits&) = delete; |
| 112 | Bits& operator=(const Bits&) = delete; | ||
| 113 | |||
| 114 | uint8_t operator[](uint32_t bitPos) const { | ||
| 121 | return static_cast<uint8_t>((m_Bits >> bitPos) & 1); | 115 | return static_cast<uint8_t>((m_Bits >> bitPos) & 1); |
| 122 | } | 116 | } |
| 123 | 117 | ||
| 124 | IntType operator()(uint32_t start, uint32_t end) { | 118 | IntType operator()(uint32_t start, uint32_t end) const { |
| 125 | if (start == end) { | 119 | if (start == end) { |
| 126 | return (*this)[start]; | 120 | return (*this)[start]; |
| 127 | } else if (start > end) { | 121 | } else if (start > end) { |
| @@ -133,6 +127,9 @@ public: | |||
| 133 | uint64_t mask = (1 << (end - start + 1)) - 1; | 127 | uint64_t mask = (1 << (end - start + 1)) - 1; |
| 134 | return (m_Bits >> start) & mask; | 128 | return (m_Bits >> start) & mask; |
| 135 | } | 129 | } |
| 130 | |||
| 131 | private: | ||
| 132 | const IntType& m_Bits; | ||
| 136 | }; | 133 | }; |
| 137 | 134 | ||
| 138 | enum EIntegerEncoding { eIntegerEncoding_JustBits, eIntegerEncoding_Quint, eIntegerEncoding_Trit }; | 135 | enum EIntegerEncoding { eIntegerEncoding_JustBits, eIntegerEncoding_Quint, eIntegerEncoding_Trit }; |
| @@ -186,12 +183,12 @@ public: | |||
| 186 | m_QuintValue = val; | 183 | m_QuintValue = val; |
| 187 | } | 184 | } |
| 188 | 185 | ||
| 189 | bool MatchesEncoding(const IntegerEncodedValue& other) { | 186 | bool MatchesEncoding(const IntegerEncodedValue& other) const { |
| 190 | return m_Encoding == other.m_Encoding && m_NumBits == other.m_NumBits; | 187 | return m_Encoding == other.m_Encoding && m_NumBits == other.m_NumBits; |
| 191 | } | 188 | } |
| 192 | 189 | ||
| 193 | // Returns the number of bits required to encode nVals values. | 190 | // Returns the number of bits required to encode nVals values. |
| 194 | uint32_t GetBitLength(uint32_t nVals) { | 191 | uint32_t GetBitLength(uint32_t nVals) const { |
| 195 | uint32_t totalBits = m_NumBits * nVals; | 192 | uint32_t totalBits = m_NumBits * nVals; |
| 196 | if (m_Encoding == eIntegerEncoding_Trit) { | 193 | if (m_Encoding == eIntegerEncoding_Trit) { |
| 197 | totalBits += (nVals * 8 + 4) / 5; | 194 | totalBits += (nVals * 8 + 4) / 5; |
| @@ -382,19 +379,15 @@ private: | |||
| 382 | namespace ASTCC { | 379 | namespace ASTCC { |
| 383 | 380 | ||
| 384 | struct TexelWeightParams { | 381 | struct TexelWeightParams { |
| 385 | uint32_t m_Width; | 382 | uint32_t m_Width = 0; |
| 386 | uint32_t m_Height; | 383 | uint32_t m_Height = 0; |
| 387 | bool m_bDualPlane; | 384 | bool m_bDualPlane = false; |
| 388 | uint32_t m_MaxWeight; | 385 | uint32_t m_MaxWeight = 0; |
| 389 | bool m_bError; | 386 | bool m_bError = false; |
| 390 | bool m_bVoidExtentLDR; | 387 | bool m_bVoidExtentLDR = false; |
| 391 | bool m_bVoidExtentHDR; | 388 | bool m_bVoidExtentHDR = false; |
| 392 | 389 | ||
| 393 | TexelWeightParams() { | 390 | uint32_t GetPackedBitSize() const { |
| 394 | memset(this, 0, sizeof(*this)); | ||
| 395 | } | ||
| 396 | |||
| 397 | uint32_t GetPackedBitSize() { | ||
| 398 | // How many indices do we have? | 391 | // How many indices do we have? |
| 399 | uint32_t nIdxs = m_Height * m_Width; | 392 | uint32_t nIdxs = m_Height * m_Width; |
| 400 | if (m_bDualPlane) { | 393 | if (m_bDualPlane) { |
| @@ -413,7 +406,7 @@ struct TexelWeightParams { | |||
| 413 | } | 406 | } |
| 414 | }; | 407 | }; |
| 415 | 408 | ||
| 416 | TexelWeightParams DecodeBlockInfo(BitStream& strm) { | 409 | static TexelWeightParams DecodeBlockInfo(BitStream& strm) { |
| 417 | TexelWeightParams params; | 410 | TexelWeightParams params; |
| 418 | 411 | ||
| 419 | // Read the entire block mode all at once | 412 | // Read the entire block mode all at once |
| @@ -612,8 +605,8 @@ TexelWeightParams DecodeBlockInfo(BitStream& strm) { | |||
| 612 | return params; | 605 | return params; |
| 613 | } | 606 | } |
| 614 | 607 | ||
| 615 | void FillVoidExtentLDR(BitStream& strm, uint32_t* const outBuf, uint32_t blockWidth, | 608 | static void FillVoidExtentLDR(BitStream& strm, uint32_t* const outBuf, uint32_t blockWidth, |
| 616 | uint32_t blockHeight) { | 609 | uint32_t blockHeight) { |
| 617 | // Don't actually care about the void extent, just read the bits... | 610 | // Don't actually care about the void extent, just read the bits... |
| 618 | for (int i = 0; i < 4; ++i) { | 611 | for (int i = 0; i < 4; ++i) { |
| 619 | strm.ReadBits(13); | 612 | strm.ReadBits(13); |
| @@ -628,23 +621,25 @@ void FillVoidExtentLDR(BitStream& strm, uint32_t* const outBuf, uint32_t blockWi | |||
| 628 | uint32_t rgba = (r >> 8) | (g & 0xFF00) | (static_cast<uint32_t>(b) & 0xFF00) << 8 | | 621 | uint32_t rgba = (r >> 8) | (g & 0xFF00) | (static_cast<uint32_t>(b) & 0xFF00) << 8 | |
| 629 | (static_cast<uint32_t>(a) & 0xFF00) << 16; | 622 | (static_cast<uint32_t>(a) & 0xFF00) << 16; |
| 630 | 623 | ||
| 631 | for (uint32_t j = 0; j < blockHeight; j++) | 624 | for (uint32_t j = 0; j < blockHeight; j++) { |
| 632 | for (uint32_t i = 0; i < blockWidth; i++) { | 625 | for (uint32_t i = 0; i < blockWidth; i++) { |
| 633 | outBuf[j * blockWidth + i] = rgba; | 626 | outBuf[j * blockWidth + i] = rgba; |
| 634 | } | 627 | } |
| 628 | } | ||
| 635 | } | 629 | } |
| 636 | 630 | ||
| 637 | void FillError(uint32_t* outBuf, uint32_t blockWidth, uint32_t blockHeight) { | 631 | static void FillError(uint32_t* outBuf, uint32_t blockWidth, uint32_t blockHeight) { |
| 638 | for (uint32_t j = 0; j < blockHeight; j++) | 632 | for (uint32_t j = 0; j < blockHeight; j++) { |
| 639 | for (uint32_t i = 0; i < blockWidth; i++) { | 633 | for (uint32_t i = 0; i < blockWidth; i++) { |
| 640 | outBuf[j * blockWidth + i] = 0xFFFF00FF; | 634 | outBuf[j * blockWidth + i] = 0xFFFF00FF; |
| 641 | } | 635 | } |
| 636 | } | ||
| 642 | } | 637 | } |
| 643 | 638 | ||
| 644 | // Replicates low numBits such that [(toBit - 1):(toBit - 1 - fromBit)] | 639 | // Replicates low numBits such that [(toBit - 1):(toBit - 1 - fromBit)] |
| 645 | // is the same as [(numBits - 1):0] and repeats all the way down. | 640 | // is the same as [(numBits - 1):0] and repeats all the way down. |
| 646 | template <typename IntType> | 641 | template <typename IntType> |
| 647 | IntType Replicate(const IntType& val, uint32_t numBits, uint32_t toBit) { | 642 | static IntType Replicate(const IntType& val, uint32_t numBits, uint32_t toBit) { |
| 648 | if (numBits == 0) | 643 | if (numBits == 0) |
| 649 | return 0; | 644 | return 0; |
| 650 | if (toBit == 0) | 645 | if (toBit == 0) |
| @@ -668,27 +663,15 @@ IntType Replicate(const IntType& val, uint32_t numBits, uint32_t toBit) { | |||
| 668 | 663 | ||
| 669 | class Pixel { | 664 | class Pixel { |
| 670 | protected: | 665 | protected: |
| 671 | typedef int16_t ChannelType; | 666 | using ChannelType = int16_t; |
| 672 | uint8_t m_BitDepth[4]; | 667 | uint8_t m_BitDepth[4] = {8, 8, 8, 8}; |
| 673 | int16_t color[4]; | 668 | int16_t color[4] = {}; |
| 674 | 669 | ||
| 675 | public: | 670 | public: |
| 676 | Pixel() { | 671 | Pixel() = default; |
| 677 | for (int i = 0; i < 4; i++) { | 672 | Pixel(ChannelType a, ChannelType r, ChannelType g, ChannelType b, unsigned bitDepth = 8) |
| 678 | m_BitDepth[i] = 8; | 673 | : m_BitDepth{uint8_t(bitDepth), uint8_t(bitDepth), uint8_t(bitDepth), uint8_t(bitDepth)}, |
| 679 | color[i] = 0; | 674 | color{a, r, g, b} {} |
| 680 | } | ||
| 681 | } | ||
| 682 | |||
| 683 | Pixel(ChannelType a, ChannelType r, ChannelType g, ChannelType b, unsigned bitDepth = 8) { | ||
| 684 | for (int i = 0; i < 4; i++) | ||
| 685 | m_BitDepth[i] = bitDepth; | ||
| 686 | |||
| 687 | color[0] = a; | ||
| 688 | color[1] = r; | ||
| 689 | color[2] = g; | ||
| 690 | color[3] = b; | ||
| 691 | } | ||
| 692 | 675 | ||
| 693 | // Changes the depth of each pixel. This scales the values to | 676 | // Changes the depth of each pixel. This scales the values to |
| 694 | // the appropriate bit depth by either truncating the least | 677 | // the appropriate bit depth by either truncating the least |
| @@ -807,8 +790,8 @@ public: | |||
| 807 | } | 790 | } |
| 808 | }; | 791 | }; |
| 809 | 792 | ||
| 810 | void DecodeColorValues(uint32_t* out, uint8_t* data, uint32_t* modes, const uint32_t nPartitions, | 793 | static void DecodeColorValues(uint32_t* out, uint8_t* data, const uint32_t* modes, |
| 811 | const uint32_t nBitsForColorData) { | 794 | const uint32_t nPartitions, const uint32_t nBitsForColorData) { |
| 812 | // First figure out how many color values we have | 795 | // First figure out how many color values we have |
| 813 | uint32_t nValues = 0; | 796 | uint32_t nValues = 0; |
| 814 | for (uint32_t i = 0; i < nPartitions; i++) { | 797 | for (uint32_t i = 0; i < nPartitions; i++) { |
| @@ -844,8 +827,7 @@ void DecodeColorValues(uint32_t* out, uint8_t* data, uint32_t* modes, const uint | |||
| 844 | // Once we have the decoded values, we need to dequantize them to the 0-255 range | 827 | // Once we have the decoded values, we need to dequantize them to the 0-255 range |
| 845 | // This procedure is outlined in ASTC spec C.2.13 | 828 | // This procedure is outlined in ASTC spec C.2.13 |
| 846 | uint32_t outIdx = 0; | 829 | uint32_t outIdx = 0; |
| 847 | std::vector<IntegerEncodedValue>::const_iterator itr; | 830 | for (auto itr = decodedColorValues.begin(); itr != decodedColorValues.end(); ++itr) { |
| 848 | for (itr = decodedColorValues.begin(); itr != decodedColorValues.end(); itr++) { | ||
| 849 | // Have we already decoded all that we need? | 831 | // Have we already decoded all that we need? |
| 850 | if (outIdx >= nValues) { | 832 | if (outIdx >= nValues) { |
| 851 | break; | 833 | break; |
| @@ -978,7 +960,7 @@ void DecodeColorValues(uint32_t* out, uint8_t* data, uint32_t* modes, const uint | |||
| 978 | } | 960 | } |
| 979 | } | 961 | } |
| 980 | 962 | ||
| 981 | uint32_t UnquantizeTexelWeight(const IntegerEncodedValue& val) { | 963 | static uint32_t UnquantizeTexelWeight(const IntegerEncodedValue& val) { |
| 982 | uint32_t bitval = val.GetBitValue(); | 964 | uint32_t bitval = val.GetBitValue(); |
| 983 | uint32_t bitlen = val.BaseBitLength(); | 965 | uint32_t bitlen = val.BaseBitLength(); |
| 984 | 966 | ||
| @@ -1067,17 +1049,18 @@ uint32_t UnquantizeTexelWeight(const IntegerEncodedValue& val) { | |||
| 1067 | return result; | 1049 | return result; |
| 1068 | } | 1050 | } |
| 1069 | 1051 | ||
| 1070 | void UnquantizeTexelWeights(uint32_t out[2][144], std::vector<IntegerEncodedValue>& weights, | 1052 | static void UnquantizeTexelWeights(uint32_t out[2][144], |
| 1071 | const TexelWeightParams& params, const uint32_t blockWidth, | 1053 | const std::vector<IntegerEncodedValue>& weights, |
| 1072 | const uint32_t blockHeight) { | 1054 | const TexelWeightParams& params, const uint32_t blockWidth, |
| 1055 | const uint32_t blockHeight) { | ||
| 1073 | uint32_t weightIdx = 0; | 1056 | uint32_t weightIdx = 0; |
| 1074 | uint32_t unquantized[2][144]; | 1057 | uint32_t unquantized[2][144]; |
| 1075 | std::vector<IntegerEncodedValue>::const_iterator itr; | 1058 | |
| 1076 | for (itr = weights.begin(); itr != weights.end(); itr++) { | 1059 | for (auto itr = weights.begin(); itr != weights.end(); ++itr) { |
| 1077 | unquantized[0][weightIdx] = UnquantizeTexelWeight(*itr); | 1060 | unquantized[0][weightIdx] = UnquantizeTexelWeight(*itr); |
| 1078 | 1061 | ||
| 1079 | if (params.m_bDualPlane) { | 1062 | if (params.m_bDualPlane) { |
| 1080 | itr++; | 1063 | ++itr; |
| 1081 | unquantized[1][weightIdx] = UnquantizeTexelWeight(*itr); | 1064 | unquantized[1][weightIdx] = UnquantizeTexelWeight(*itr); |
| 1082 | if (itr == weights.end()) { | 1065 | if (itr == weights.end()) { |
| 1083 | break; | 1066 | break; |
| @@ -1261,8 +1244,8 @@ static inline uint32_t Select2DPartition(int32_t seed, int32_t x, int32_t y, int | |||
| 1261 | } | 1244 | } |
| 1262 | 1245 | ||
| 1263 | // Section C.2.14 | 1246 | // Section C.2.14 |
| 1264 | void ComputeEndpoints(Pixel& ep1, Pixel& ep2, const uint32_t*& colorValues, | 1247 | static void ComputeEndpoints(Pixel& ep1, Pixel& ep2, const uint32_t*& colorValues, |
| 1265 | uint32_t colorEndpointMode) { | 1248 | uint32_t colorEndpointMode) { |
| 1266 | #define READ_UINT_VALUES(N) \ | 1249 | #define READ_UINT_VALUES(N) \ |
| 1267 | uint32_t v[N]; \ | 1250 | uint32_t v[N]; \ |
| 1268 | for (uint32_t i = 0; i < N; i++) { \ | 1251 | for (uint32_t i = 0; i < N; i++) { \ |
| @@ -1382,8 +1365,8 @@ void ComputeEndpoints(Pixel& ep1, Pixel& ep2, const uint32_t*& colorValues, | |||
| 1382 | #undef READ_INT_VALUES | 1365 | #undef READ_INT_VALUES |
| 1383 | } | 1366 | } |
| 1384 | 1367 | ||
| 1385 | void DecompressBlock(uint8_t inBuf[16], const uint32_t blockWidth, const uint32_t blockHeight, | 1368 | static void DecompressBlock(uint8_t inBuf[16], const uint32_t blockWidth, |
| 1386 | uint32_t* outBuf) { | 1369 | const uint32_t blockHeight, uint32_t* outBuf) { |
| 1387 | BitStream strm(inBuf); | 1370 | BitStream strm(inBuf); |
| 1388 | TexelWeightParams weightParams = DecodeBlockInfo(strm); | 1371 | TexelWeightParams weightParams = DecodeBlockInfo(strm); |
| 1389 | 1372 | ||
| @@ -1617,8 +1600,7 @@ namespace Tegra::Texture::ASTC { | |||
| 1617 | std::vector<uint8_t> Decompress(std::vector<uint8_t>& data, uint32_t width, uint32_t height, | 1600 | std::vector<uint8_t> Decompress(std::vector<uint8_t>& data, uint32_t width, uint32_t height, |
| 1618 | uint32_t block_width, uint32_t block_height) { | 1601 | uint32_t block_width, uint32_t block_height) { |
| 1619 | uint32_t blockIdx = 0; | 1602 | uint32_t blockIdx = 0; |
| 1620 | std::vector<uint8_t> outData; | 1603 | std::vector<uint8_t> outData(height * width * 4); |
| 1621 | outData.resize(height * width * 4); | ||
| 1622 | for (uint32_t j = 0; j < height; j += block_height) { | 1604 | for (uint32_t j = 0; j < height; j += block_height) { |
| 1623 | for (uint32_t i = 0; i < width; i += block_width) { | 1605 | for (uint32_t i = 0; i < width; i += block_width) { |
| 1624 | 1606 | ||
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index a32134fbe..62754a1a9 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp | |||
| @@ -97,7 +97,7 @@ void Config::ReadValues() { | |||
| 97 | qt_config->endGroup(); | 97 | qt_config->endGroup(); |
| 98 | 98 | ||
| 99 | qt_config->beginGroup("System"); | 99 | qt_config->beginGroup("System"); |
| 100 | Settings::values.use_docked_mode = qt_config->value("use_docked_mode", true).toBool(); | 100 | Settings::values.use_docked_mode = qt_config->value("use_docked_mode", false).toBool(); |
| 101 | qt_config->endGroup(); | 101 | qt_config->endGroup(); |
| 102 | 102 | ||
| 103 | qt_config->beginGroup("Miscellaneous"); | 103 | qt_config->beginGroup("Miscellaneous"); |
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp index 3a311b69f..723e8b4cc 100644 --- a/src/yuzu_cmd/config.cpp +++ b/src/yuzu_cmd/config.cpp | |||
| @@ -110,7 +110,7 @@ void Config::ReadValues() { | |||
| 110 | sdl2_config->GetBoolean("Data Storage", "use_virtual_sd", true); | 110 | sdl2_config->GetBoolean("Data Storage", "use_virtual_sd", true); |
| 111 | 111 | ||
| 112 | // System | 112 | // System |
| 113 | Settings::values.use_docked_mode = sdl2_config->GetBoolean("System", "use_docked_mode", true); | 113 | Settings::values.use_docked_mode = sdl2_config->GetBoolean("System", "use_docked_mode", false); |
| 114 | 114 | ||
| 115 | // Miscellaneous | 115 | // Miscellaneous |
| 116 | Settings::values.log_filter = sdl2_config->Get("Miscellaneous", "log_filter", "*:Trace"); | 116 | Settings::values.log_filter = sdl2_config->Get("Miscellaneous", "log_filter", "*:Trace"); |
diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h index 71d2e040f..5eca38b48 100644 --- a/src/yuzu_cmd/default_ini.h +++ b/src/yuzu_cmd/default_ini.h | |||
| @@ -163,7 +163,7 @@ use_virtual_sd = | |||
| 163 | 163 | ||
| 164 | [System] | 164 | [System] |
| 165 | # Whether the system is docked | 165 | # Whether the system is docked |
| 166 | # 1 (default): Yes, 0: No | 166 | # 1: Yes, 0 (default): No |
| 167 | use_docked_mode = | 167 | use_docked_mode = |
| 168 | 168 | ||
| 169 | # The system region that yuzu will use during emulation | 169 | # The system region that yuzu will use during emulation |