summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/soc_u.cpp18
-rw-r--r--src/core/hw/gpu.cpp79
2 files changed, 59 insertions, 38 deletions
diff --git a/src/core/hle/service/soc_u.cpp b/src/core/hle/service/soc_u.cpp
index 1e0f5df9b..1bd420552 100644
--- a/src/core/hle/service/soc_u.cpp
+++ b/src/core/hle/service/soc_u.cpp
@@ -328,6 +328,7 @@ static void Socket(Service::Interface* self) {
328 if ((s32)socket_handle == SOCKET_ERROR_VALUE) 328 if ((s32)socket_handle == SOCKET_ERROR_VALUE)
329 result = TranslateError(GET_ERRNO); 329 result = TranslateError(GET_ERRNO);
330 330
331 cmd_buffer[0] = IPC::MakeHeader(2, 2, 0);
331 cmd_buffer[1] = result; 332 cmd_buffer[1] = result;
332 cmd_buffer[2] = socket_handle; 333 cmd_buffer[2] = socket_handle;
333} 334}
@@ -351,8 +352,9 @@ static void Bind(Service::Interface* self) {
351 if (res != 0) 352 if (res != 0)
352 result = TranslateError(GET_ERRNO); 353 result = TranslateError(GET_ERRNO);
353 354
354 cmd_buffer[2] = res; 355 cmd_buffer[0] = IPC::MakeHeader(5, 2, 0);
355 cmd_buffer[1] = result; 356 cmd_buffer[1] = result;
357 cmd_buffer[2] = res;
356} 358}
357 359
358static void Fcntl(Service::Interface* self) { 360static void Fcntl(Service::Interface* self) {
@@ -434,8 +436,9 @@ static void Listen(Service::Interface* self) {
434 if (ret != 0) 436 if (ret != 0)
435 result = TranslateError(GET_ERRNO); 437 result = TranslateError(GET_ERRNO);
436 438
437 cmd_buffer[2] = ret; 439 cmd_buffer[0] = IPC::MakeHeader(3, 2, 0);
438 cmd_buffer[1] = result; 440 cmd_buffer[1] = result;
441 cmd_buffer[2] = ret;
439} 442}
440 443
441static void Accept(Service::Interface* self) { 444static void Accept(Service::Interface* self) {
@@ -460,8 +463,10 @@ static void Accept(Service::Interface* self) {
460 Memory::WriteBlock(cmd_buffer[0x104 >> 2], (const u8*)&ctr_addr, max_addr_len); 463 Memory::WriteBlock(cmd_buffer[0x104 >> 2], (const u8*)&ctr_addr, max_addr_len);
461 } 464 }
462 465
463 cmd_buffer[2] = ret; 466 cmd_buffer[0] = IPC::MakeHeader(4, 2, 2);
464 cmd_buffer[1] = result; 467 cmd_buffer[1] = result;
468 cmd_buffer[2] = ret;
469 cmd_buffer[3] = IPC::StaticBufferDesc(static_cast<u32>(max_addr_len), 0);
465} 470}
466 471
467static void GetHostId(Service::Interface* self) { 472static void GetHostId(Service::Interface* self) {
@@ -669,8 +674,10 @@ static void Connect(Service::Interface* self) {
669 int result = 0; 674 int result = 0;
670 if (ret != 0) 675 if (ret != 0)
671 result = TranslateError(GET_ERRNO); 676 result = TranslateError(GET_ERRNO);
672 cmd_buffer[2] = ret; 677
678 cmd_buffer[0] = IPC::MakeHeader(6, 2, 0);
673 cmd_buffer[1] = result; 679 cmd_buffer[1] = result;
680 cmd_buffer[2] = ret;
674} 681}
675 682
676static void InitializeSockets(Service::Interface* self) { 683static void InitializeSockets(Service::Interface* self) {
@@ -681,7 +688,8 @@ static void InitializeSockets(Service::Interface* self) {
681#endif 688#endif
682 689
683 u32* cmd_buffer = Kernel::GetCommandBuffer(); 690 u32* cmd_buffer = Kernel::GetCommandBuffer();
684 cmd_buffer[1] = 0; 691 cmd_buffer[0] = IPC::MakeHeader(1, 1, 0);
692 cmd_buffer[1] = RESULT_SUCCESS.raw;
685} 693}
686 694
687static void ShutdownSockets(Service::Interface* self) { 695static void ShutdownSockets(Service::Interface* self) {
diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp
index 7471def57..dd3b31650 100644
--- a/src/core/hw/gpu.cpp
+++ b/src/core/hw/gpu.cpp
@@ -53,6 +53,29 @@ inline void Read(T &var, const u32 raw_addr) {
53 var = g_regs[addr / 4]; 53 var = g_regs[addr / 4];
54} 54}
55 55
56static Math::Vec4<u8> DecodePixel(Regs::PixelFormat input_format, const u8* src_pixel) {
57 switch (input_format) {
58 case Regs::PixelFormat::RGBA8:
59 return Color::DecodeRGBA8(src_pixel);
60
61 case Regs::PixelFormat::RGB8:
62 return Color::DecodeRGB8(src_pixel);
63
64 case Regs::PixelFormat::RGB565:
65 return Color::DecodeRGB565(src_pixel);
66
67 case Regs::PixelFormat::RGB5A1:
68 return Color::DecodeRGB5A1(src_pixel);
69
70 case Regs::PixelFormat::RGBA4:
71 return Color::DecodeRGBA4(src_pixel);
72
73 default:
74 LOG_ERROR(HW_GPU, "Unknown source framebuffer format %x", input_format);
75 return {0, 0, 0, 0};
76 }
77}
78
56template <typename T> 79template <typename T>
57inline void Write(u32 addr, const T data) { 80inline void Write(u32 addr, const T data) {
58 addr -= HW::VADDR_GPU; 81 addr -= HW::VADDR_GPU;
@@ -125,11 +148,18 @@ inline void Write(u32 addr, const T data) {
125 break; 148 break;
126 } 149 }
127 150
128 unsigned horizontal_scale = (config.scaling != config.NoScale) ? 2 : 1; 151 if (config.output_tiled &&
129 unsigned vertical_scale = (config.scaling == config.ScaleXY) ? 2 : 1; 152 (config.scaling == config.ScaleXY || config.scaling == config.ScaleX)) {
153 LOG_CRITICAL(HW_GPU, "Scaling is only implemented on tiled input");
154 UNIMPLEMENTED();
155 break;
156 }
130 157
131 u32 output_width = config.output_width / horizontal_scale; 158 bool horizontal_scale = config.scaling != config.NoScale;
132 u32 output_height = config.output_height / vertical_scale; 159 bool vertical_scale = config.scaling == config.ScaleXY;
160
161 u32 output_width = config.output_width >> horizontal_scale;
162 u32 output_height = config.output_height >> vertical_scale;
133 163
134 u32 input_size = config.input_width * config.input_height * GPU::Regs::BytesPerPixel(config.input_format); 164 u32 input_size = config.input_width * config.input_height * GPU::Regs::BytesPerPixel(config.input_format);
135 u32 output_size = output_width * output_height * GPU::Regs::BytesPerPixel(config.output_format); 165 u32 output_size = output_width * output_height * GPU::Regs::BytesPerPixel(config.output_format);
@@ -153,16 +183,14 @@ inline void Write(u32 addr, const T data) {
153 break; 183 break;
154 } 184 }
155 185
156 // TODO(Subv): Implement the box filter when scaling is enabled
157 // right now we're just skipping the extra pixels.
158 for (u32 y = 0; y < output_height; ++y) { 186 for (u32 y = 0; y < output_height; ++y) {
159 for (u32 x = 0; x < output_width; ++x) { 187 for (u32 x = 0; x < output_width; ++x) {
160 Math::Vec4<u8> src_color = { 0, 0, 0, 0 }; 188 Math::Vec4<u8> src_color;
161 189
162 // Calculate the [x,y] position of the input image 190 // Calculate the [x,y] position of the input image
163 // based on the current output position and the scale 191 // based on the current output position and the scale
164 u32 input_x = x * horizontal_scale; 192 u32 input_x = x << horizontal_scale;
165 u32 input_y = y * vertical_scale; 193 u32 input_y = y << vertical_scale;
166 194
167 if (config.flip_vertically) { 195 if (config.flip_vertically) {
168 // Flip the y value of the output data, 196 // Flip the y value of the output data,
@@ -193,30 +221,15 @@ inline void Write(u32 addr, const T data) {
193 } 221 }
194 222
195 const u8* src_pixel = src_pointer + src_offset; 223 const u8* src_pixel = src_pointer + src_offset;
196 switch (config.input_format) { 224 src_color = DecodePixel(config.input_format, src_pixel);
197 case Regs::PixelFormat::RGBA8: 225 if (config.scaling == config.ScaleX) {
198 src_color = Color::DecodeRGBA8(src_pixel); 226 Math::Vec4<u8> pixel = DecodePixel(config.input_format, src_pixel + src_bytes_per_pixel);
199 break; 227 src_color = ((src_color + pixel) / 2).Cast<u8>();
200 228 } else if (config.scaling == config.ScaleXY) {
201 case Regs::PixelFormat::RGB8: 229 Math::Vec4<u8> pixel1 = DecodePixel(config.input_format, src_pixel + 1 * src_bytes_per_pixel);
202 src_color = Color::DecodeRGB8(src_pixel); 230 Math::Vec4<u8> pixel2 = DecodePixel(config.input_format, src_pixel + 2 * src_bytes_per_pixel);
203 break; 231 Math::Vec4<u8> pixel3 = DecodePixel(config.input_format, src_pixel + 3 * src_bytes_per_pixel);
204 232 src_color = (((src_color + pixel1) + (pixel2 + pixel3)) / 4).Cast<u8>();
205 case Regs::PixelFormat::RGB565:
206 src_color = Color::DecodeRGB565(src_pixel);
207 break;
208
209 case Regs::PixelFormat::RGB5A1:
210 src_color = Color::DecodeRGB5A1(src_pixel);
211 break;
212
213 case Regs::PixelFormat::RGBA4:
214 src_color = Color::DecodeRGBA4(src_pixel);
215 break;
216
217 default:
218 LOG_ERROR(HW_GPU, "Unknown source framebuffer format %x", config.input_format.Value());
219 break;
220 } 233 }
221 234
222 u8* dst_pixel = dst_pointer + dst_offset; 235 u8* dst_pixel = dst_pointer + dst_offset;