summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2016-04-26 19:29:57 -0400
committerGravatar bunnei2016-04-26 19:29:57 -0400
commit61992170ac0843da7683b302aa5d46e5ac0f7f1d (patch)
treebce27d93f99dba1099c3bd932de56de35a94e81b /src
parentMerge pull request #1720 from linkmauve/fix-qt (diff)
parentUpdate the code of service y2r! (diff)
downloadyuzu-61992170ac0843da7683b302aa5d46e5ac0f7f1d.tar.gz
yuzu-61992170ac0843da7683b302aa5d46e5ac0f7f1d.tar.xz
yuzu-61992170ac0843da7683b302aa5d46e5ac0f7f1d.zip
Merge pull request #1447 from JamePeng/update-y2r-service
Update the code of service y2r!
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/y2r_u.cpp369
-rw-r--r--src/core/hle/service/y2r_u.h20
2 files changed, 357 insertions, 32 deletions
diff --git a/src/core/hle/service/y2r_u.cpp b/src/core/hle/service/y2r_u.cpp
index 1672ad775..76ec154dd 100644
--- a/src/core/hle/service/y2r_u.cpp
+++ b/src/core/hle/service/y2r_u.cpp
@@ -4,6 +4,7 @@
4 4
5#include <cstring> 5#include <cstring>
6 6
7#include "common/common_funcs.h"
7#include "common/common_types.h" 8#include "common/common_types.h"
8#include "common/logging/log.h" 9#include "common/logging/log.h"
9 10
@@ -25,13 +26,17 @@ struct ConversionParameters {
25 u16 input_line_width; 26 u16 input_line_width;
26 u16 input_lines; 27 u16 input_lines;
27 StandardCoefficient standard_coefficient; 28 StandardCoefficient standard_coefficient;
28 u8 reserved; 29 u8 padding;
29 u16 alpha; 30 u16 alpha;
30}; 31};
31static_assert(sizeof(ConversionParameters) == 12, "ConversionParameters struct has incorrect size"); 32static_assert(sizeof(ConversionParameters) == 12, "ConversionParameters struct has incorrect size");
32 33
33static Kernel::SharedPtr<Kernel::Event> completion_event; 34static Kernel::SharedPtr<Kernel::Event> completion_event;
34static ConversionConfiguration conversion; 35static ConversionConfiguration conversion;
36static DitheringWeightParams dithering_weight_params;
37static u32 temporal_dithering_enabled = 0;
38static u32 transfer_end_interrupt_enabled = 0;
39static u32 spacial_dithering_enabled = 0;
35 40
36static const CoefficientSet standard_coefficients[4] = { 41static const CoefficientSet standard_coefficients[4] = {
37 {{ 0x100, 0x166, 0xB6, 0x58, 0x1C5, -0x166F, 0x10EE, -0x1C5B }}, // ITU_Rec601 42 {{ 0x100, 0x166, 0xB6, 0x58, 0x1C5, -0x166F, 0x10EE, -0x1C5B }}, // ITU_Rec601
@@ -70,7 +75,7 @@ ResultCode ConversionConfiguration::SetInputLines(u16 lines) {
70 75
71ResultCode ConversionConfiguration::SetStandardCoefficient(StandardCoefficient standard_coefficient) { 76ResultCode ConversionConfiguration::SetStandardCoefficient(StandardCoefficient standard_coefficient) {
72 size_t index = static_cast<size_t>(standard_coefficient); 77 size_t index = static_cast<size_t>(standard_coefficient);
73 if (index >= 4) { 78 if (index >= ARRAY_SIZE(standard_coefficients)) {
74 return ResultCode(ErrorDescription::InvalidEnumValue, ErrorModule::CAM, 79 return ResultCode(ErrorDescription::InvalidEnumValue, ErrorModule::CAM,
75 ErrorSummary::InvalidArgument, ErrorLevel::Usage); // 0xE0E053ED 80 ErrorSummary::InvalidArgument, ErrorLevel::Usage); // 0xE0E053ED
76 } 81 }
@@ -85,42 +90,167 @@ static void SetInputFormat(Service::Interface* self) {
85 conversion.input_format = static_cast<InputFormat>(cmd_buff[1]); 90 conversion.input_format = static_cast<InputFormat>(cmd_buff[1]);
86 LOG_DEBUG(Service_Y2R, "called input_format=%hhu", conversion.input_format); 91 LOG_DEBUG(Service_Y2R, "called input_format=%hhu", conversion.input_format);
87 92
93 cmd_buff[0] = IPC::MakeHeader(0x1, 1, 0);
88 cmd_buff[1] = RESULT_SUCCESS.raw; 94 cmd_buff[1] = RESULT_SUCCESS.raw;
89} 95}
90 96
97static void GetInputFormat(Service::Interface* self) {
98 u32* cmd_buff = Kernel::GetCommandBuffer();
99
100 cmd_buff[0] = IPC::MakeHeader(0x2, 2, 0);
101 cmd_buff[1] = RESULT_SUCCESS.raw;
102 cmd_buff[2] = static_cast<u32>(conversion.input_format);
103 LOG_DEBUG(Service_Y2R, "called input_format=%hhu", conversion.input_format);
104}
105
91static void SetOutputFormat(Service::Interface* self) { 106static void SetOutputFormat(Service::Interface* self) {
92 u32* cmd_buff = Kernel::GetCommandBuffer(); 107 u32* cmd_buff = Kernel::GetCommandBuffer();
93 108
94 conversion.output_format = static_cast<OutputFormat>(cmd_buff[1]); 109 conversion.output_format = static_cast<OutputFormat>(cmd_buff[1]);
95 LOG_DEBUG(Service_Y2R, "called output_format=%hhu", conversion.output_format); 110 LOG_DEBUG(Service_Y2R, "called output_format=%hhu", conversion.output_format);
96 111
112 cmd_buff[0] = IPC::MakeHeader(0x3, 1, 0);
97 cmd_buff[1] = RESULT_SUCCESS.raw; 113 cmd_buff[1] = RESULT_SUCCESS.raw;
98} 114}
99 115
116static void GetOutputFormat(Service::Interface* self) {
117 u32* cmd_buff = Kernel::GetCommandBuffer();
118
119 cmd_buff[0] = IPC::MakeHeader(0x4, 2, 0);
120 cmd_buff[1] = RESULT_SUCCESS.raw;
121 cmd_buff[2] = static_cast<u32>(conversion.output_format);
122 LOG_DEBUG(Service_Y2R, "called output_format=%hhu", conversion.output_format);
123}
124
100static void SetRotation(Service::Interface* self) { 125static void SetRotation(Service::Interface* self) {
101 u32* cmd_buff = Kernel::GetCommandBuffer(); 126 u32* cmd_buff = Kernel::GetCommandBuffer();
102 127
103 conversion.rotation = static_cast<Rotation>(cmd_buff[1]); 128 conversion.rotation = static_cast<Rotation>(cmd_buff[1]);
104 LOG_DEBUG(Service_Y2R, "called rotation=%hhu", conversion.rotation); 129 LOG_DEBUG(Service_Y2R, "called rotation=%hhu", conversion.rotation);
105 130
131 cmd_buff[0] = IPC::MakeHeader(0x5, 1, 0);
132 cmd_buff[1] = RESULT_SUCCESS.raw;
133}
134
135static void GetRotation(Service::Interface* self) {
136 u32* cmd_buff = Kernel::GetCommandBuffer();
137
138 cmd_buff[0] = IPC::MakeHeader(0x6, 2, 0);
106 cmd_buff[1] = RESULT_SUCCESS.raw; 139 cmd_buff[1] = RESULT_SUCCESS.raw;
140 cmd_buff[2] = static_cast<u32>(conversion.rotation);
141 LOG_DEBUG(Service_Y2R, "called rotation=%hhu", conversion.rotation);
107} 142}
108 143
109static void SetBlockAlignment(Service::Interface* self) { 144static void SetBlockAlignment(Service::Interface* self) {
110 u32* cmd_buff = Kernel::GetCommandBuffer(); 145 u32* cmd_buff = Kernel::GetCommandBuffer();
111 146
112 conversion.block_alignment = static_cast<BlockAlignment>(cmd_buff[1]); 147 conversion.block_alignment = static_cast<BlockAlignment>(cmd_buff[1]);
113 LOG_DEBUG(Service_Y2R, "called alignment=%hhu", conversion.block_alignment); 148 LOG_DEBUG(Service_Y2R, "called block_alignment=%hhu", conversion.block_alignment);
149
150 cmd_buff[0] = IPC::MakeHeader(0x7, 1, 0);
151 cmd_buff[1] = RESULT_SUCCESS.raw;
152}
153
154static void GetBlockAlignment(Service::Interface* self) {
155 u32* cmd_buff = Kernel::GetCommandBuffer();
156
157 cmd_buff[0] = IPC::MakeHeader(0x8, 2, 0);
158 cmd_buff[1] = RESULT_SUCCESS.raw;
159 cmd_buff[2] = static_cast<u32>(conversion.block_alignment);
160 LOG_DEBUG(Service_Y2R, "called block_alignment=%hhu", conversion.block_alignment);
161}
162
163/**
164 * Y2R_U::SetSpacialDithering service function
165 * Inputs:
166 * 1 : u8, 0 = Disabled, 1 = Enabled
167 * Outputs:
168 * 1 : Result of function, 0 on success, otherwise error code
169 */
170static void SetSpacialDithering(Service::Interface* self) {
171 u32* cmd_buff = Kernel::GetCommandBuffer();
172 spacial_dithering_enabled = cmd_buff[1] & 0xF;
173
174 cmd_buff[0] = IPC::MakeHeader(0x9, 1, 0);
175 cmd_buff[1] = RESULT_SUCCESS.raw;
176 LOG_WARNING(Service_Y2R, "(STUBBED) called");
177}
178
179/**
180 * Y2R_U::GetSpacialDithering service function
181 * Outputs:
182 * 1 : Result of function, 0 on success, otherwise error code
183 * 2 : u8, 0 = Disabled, 1 = Enabled
184 */
185static void GetSpacialDithering(Service::Interface* self) {
186 u32* cmd_buff = Kernel::GetCommandBuffer();
114 187
188 cmd_buff[0] = IPC::MakeHeader(0xA, 2, 0);
115 cmd_buff[1] = RESULT_SUCCESS.raw; 189 cmd_buff[1] = RESULT_SUCCESS.raw;
190 cmd_buff[2] = spacial_dithering_enabled;
191 LOG_WARNING(Service_Y2R, "(STUBBED) called");
192}
193
194/**
195 * Y2R_U::SetTemporalDithering service function
196 * Inputs:
197 * 1 : u8, 0 = Disabled, 1 = Enabled
198 * Outputs:
199 * 1 : Result of function, 0 on success, otherwise error code
200 */
201static void SetTemporalDithering(Service::Interface* self) {
202 u32* cmd_buff = Kernel::GetCommandBuffer();
203 temporal_dithering_enabled = cmd_buff[1] & 0xF;
204
205 cmd_buff[0] = IPC::MakeHeader(0xB, 1, 0);
206 cmd_buff[1] = RESULT_SUCCESS.raw;
207 LOG_WARNING(Service_Y2R, "(STUBBED) called");
208}
209
210/**
211 * Y2R_U::GetTemporalDithering service function
212 * Outputs:
213 * 1 : Result of function, 0 on success, otherwise error code
214 * 2 : u8, 0 = Disabled, 1 = Enabled
215 */
216static void GetTemporalDithering(Service::Interface* self) {
217 u32* cmd_buff = Kernel::GetCommandBuffer();
218
219 cmd_buff[0] = IPC::MakeHeader(0xC, 2, 0);
220 cmd_buff[1] = RESULT_SUCCESS.raw;
221 cmd_buff[2] = temporal_dithering_enabled;
222 LOG_WARNING(Service_Y2R, "(STUBBED) called");
116} 223}
117 224
225/**
226 * Y2R_U::SetTransferEndInterrupt service function
227 * Inputs:
228 * 1 : u8, 0 = Disabled, 1 = Enabled
229 * Outputs:
230 * 1 : Result of function, 0 on success, otherwise error code
231 */
118static void SetTransferEndInterrupt(Service::Interface* self) { 232static void SetTransferEndInterrupt(Service::Interface* self) {
119 u32* cmd_buff = Kernel::GetCommandBuffer(); 233 u32* cmd_buff = Kernel::GetCommandBuffer();
234 transfer_end_interrupt_enabled = cmd_buff[1] & 0xf;
120 235
121 cmd_buff[0] = IPC::MakeHeader(0xD, 1, 0); 236 cmd_buff[0] = IPC::MakeHeader(0xD, 1, 0);
122 cmd_buff[1] = RESULT_SUCCESS.raw; 237 cmd_buff[1] = RESULT_SUCCESS.raw;
123 LOG_DEBUG(Service_Y2R, "(STUBBED) called"); 238 LOG_WARNING(Service_Y2R, "(STUBBED) called");
239}
240
241/**
242 * Y2R_U::GetTransferEndInterrupt service function
243 * Outputs:
244 * 1 : Result of function, 0 on success, otherwise error code
245 * 2 : u8, 0 = Disabled, 1 = Enabled
246 */
247static void GetTransferEndInterrupt(Service::Interface* self) {
248 u32* cmd_buff = Kernel::GetCommandBuffer();
249
250 cmd_buff[0] = IPC::MakeHeader(0xE, 2, 0);
251 cmd_buff[1] = RESULT_SUCCESS.raw;
252 cmd_buff[2] = transfer_end_interrupt_enabled;
253 LOG_WARNING(Service_Y2R, "(STUBBED) called");
124} 254}
125 255
126/** 256/**
@@ -132,6 +262,7 @@ static void SetTransferEndInterrupt(Service::Interface* self) {
132static void GetTransferEndEvent(Service::Interface* self) { 262static void GetTransferEndEvent(Service::Interface* self) {
133 u32* cmd_buff = Kernel::GetCommandBuffer(); 263 u32* cmd_buff = Kernel::GetCommandBuffer();
134 264
265 cmd_buff[0] = IPC::MakeHeader(0xF, 2, 0);
135 cmd_buff[1] = RESULT_SUCCESS.raw; 266 cmd_buff[1] = RESULT_SUCCESS.raw;
136 cmd_buff[3] = Kernel::g_handle_table.Create(completion_event).MoveFrom(); 267 cmd_buff[3] = Kernel::g_handle_table.Create(completion_event).MoveFrom();
137 LOG_DEBUG(Service_Y2R, "called"); 268 LOG_DEBUG(Service_Y2R, "called");
@@ -149,6 +280,7 @@ static void SetSendingY(Service::Interface* self) {
149 "src_process_handle=0x%08X", conversion.src_Y.image_size, 280 "src_process_handle=0x%08X", conversion.src_Y.image_size,
150 conversion.src_Y.transfer_unit, conversion.src_Y.gap, src_process_handle); 281 conversion.src_Y.transfer_unit, conversion.src_Y.gap, src_process_handle);
151 282
283 cmd_buff[0] = IPC::MakeHeader(0x10, 1, 0);
152 cmd_buff[1] = RESULT_SUCCESS.raw; 284 cmd_buff[1] = RESULT_SUCCESS.raw;
153} 285}
154 286
@@ -164,6 +296,7 @@ static void SetSendingU(Service::Interface* self) {
164 "src_process_handle=0x%08X", conversion.src_U.image_size, 296 "src_process_handle=0x%08X", conversion.src_U.image_size,
165 conversion.src_U.transfer_unit, conversion.src_U.gap, src_process_handle); 297 conversion.src_U.transfer_unit, conversion.src_U.gap, src_process_handle);
166 298
299 cmd_buff[0] = IPC::MakeHeader(0x11, 1, 0);
167 cmd_buff[1] = RESULT_SUCCESS.raw; 300 cmd_buff[1] = RESULT_SUCCESS.raw;
168} 301}
169 302
@@ -179,6 +312,7 @@ static void SetSendingV(Service::Interface* self) {
179 "src_process_handle=0x%08X", conversion.src_V.image_size, 312 "src_process_handle=0x%08X", conversion.src_V.image_size,
180 conversion.src_V.transfer_unit, conversion.src_V.gap, src_process_handle); 313 conversion.src_V.transfer_unit, conversion.src_V.gap, src_process_handle);
181 314
315 cmd_buff[0] = IPC::MakeHeader(0x12, 1, 0);
182 cmd_buff[1] = RESULT_SUCCESS.raw; 316 cmd_buff[1] = RESULT_SUCCESS.raw;
183} 317}
184 318
@@ -194,9 +328,70 @@ static void SetSendingYUYV(Service::Interface* self) {
194 "src_process_handle=0x%08X", conversion.src_YUYV.image_size, 328 "src_process_handle=0x%08X", conversion.src_YUYV.image_size,
195 conversion.src_YUYV.transfer_unit, conversion.src_YUYV.gap, src_process_handle); 329 conversion.src_YUYV.transfer_unit, conversion.src_YUYV.gap, src_process_handle);
196 330
331 cmd_buff[0] = IPC::MakeHeader(0x13, 1, 0);
197 cmd_buff[1] = RESULT_SUCCESS.raw; 332 cmd_buff[1] = RESULT_SUCCESS.raw;
198} 333}
199 334
335/**
336 * Y2R::IsFinishedSendingYuv service function
337 * Output:
338 * 1 : Result of the function, 0 on success, otherwise error code
339 * 2 : u8, 0 = Not Finished, 1 = Finished
340 */
341static void IsFinishedSendingYuv(Service::Interface* self) {
342 u32* cmd_buff = Kernel::GetCommandBuffer();
343
344 cmd_buff[0] = IPC::MakeHeader(0x14, 2, 0);
345 cmd_buff[1] = RESULT_SUCCESS.raw;
346 cmd_buff[2] = 1;
347 LOG_WARNING(Service_Y2R, "(STUBBED) called");
348}
349
350/**
351 * Y2R::IsFinishedSendingY service function
352 * Output:
353 * 1 : Result of the function, 0 on success, otherwise error code
354 * 2 : u8, 0 = Not Finished, 1 = Finished
355 */
356static void IsFinishedSendingY(Service::Interface* self) {
357 u32* cmd_buff = Kernel::GetCommandBuffer();
358
359 cmd_buff[0] = IPC::MakeHeader(0x15, 2, 0);
360 cmd_buff[1] = RESULT_SUCCESS.raw;
361 cmd_buff[2] = 1;
362 LOG_WARNING(Service_Y2R, "(STUBBED) called");
363}
364
365/**
366 * Y2R::IsFinishedSendingU service function
367 * Output:
368 * 1 : Result of the function, 0 on success, otherwise error code
369 * 2 : u8, 0 = Not Finished, 1 = Finished
370 */
371static void IsFinishedSendingU(Service::Interface* self) {
372 u32* cmd_buff = Kernel::GetCommandBuffer();
373
374 cmd_buff[0] = IPC::MakeHeader(0x16, 2, 0);
375 cmd_buff[1] = RESULT_SUCCESS.raw;
376 cmd_buff[2] = 1;
377 LOG_WARNING(Service_Y2R, "(STUBBED) called");
378}
379
380/**
381 * Y2R::IsFinishedSendingV service function
382 * Output:
383 * 1 : Result of the function, 0 on success, otherwise error code
384 * 2 : u8, 0 = Not Finished, 1 = Finished
385 */
386static void IsFinishedSendingV(Service::Interface* self) {
387 u32* cmd_buff = Kernel::GetCommandBuffer();
388
389 cmd_buff[0] = IPC::MakeHeader(0x17, 2, 0);
390 cmd_buff[1] = RESULT_SUCCESS.raw;
391 cmd_buff[2] = 1;
392 LOG_WARNING(Service_Y2R, "(STUBBED) called");
393}
394
200static void SetReceiving(Service::Interface* self) { 395static void SetReceiving(Service::Interface* self) {
201 u32* cmd_buff = Kernel::GetCommandBuffer(); 396 u32* cmd_buff = Kernel::GetCommandBuffer();
202 397
@@ -210,23 +405,59 @@ static void SetReceiving(Service::Interface* self) {
210 conversion.dst.transfer_unit, conversion.dst.gap, 405 conversion.dst.transfer_unit, conversion.dst.gap,
211 dst_process_handle); 406 dst_process_handle);
212 407
408 cmd_buff[0] = IPC::MakeHeader(0x18, 1, 0);
213 cmd_buff[1] = RESULT_SUCCESS.raw; 409 cmd_buff[1] = RESULT_SUCCESS.raw;
214} 410}
215 411
412/**
413 * Y2R::IsFinishedReceiving service function
414 * Output:
415 * 1 : Result of the function, 0 on success, otherwise error code
416 * 2 : u8, 0 = Not Finished, 1 = Finished
417 */
418static void IsFinishedReceiving(Service::Interface* self) {
419 u32* cmd_buff = Kernel::GetCommandBuffer();
420
421 cmd_buff[0] = IPC::MakeHeader(0x19, 2, 0);
422 cmd_buff[1] = RESULT_SUCCESS.raw;
423 cmd_buff[2] = 1;
424 LOG_WARNING(Service_Y2R, "(STUBBED) called");
425}
426
216static void SetInputLineWidth(Service::Interface* self) { 427static void SetInputLineWidth(Service::Interface* self) {
217 u32* cmd_buff = Kernel::GetCommandBuffer(); 428 u32* cmd_buff = Kernel::GetCommandBuffer();
218 429
219 LOG_DEBUG(Service_Y2R, "called input_line_width=%u", cmd_buff[1]); 430 LOG_DEBUG(Service_Y2R, "called input_line_width=%u", cmd_buff[1]);
431 cmd_buff[0] = IPC::MakeHeader(0x1A, 1, 0);
220 cmd_buff[1] = conversion.SetInputLineWidth(cmd_buff[1]).raw; 432 cmd_buff[1] = conversion.SetInputLineWidth(cmd_buff[1]).raw;
221} 433}
222 434
435static void GetInputLineWidth(Service::Interface* self) {
436 u32* cmd_buff = Kernel::GetCommandBuffer();
437
438 cmd_buff[0] = IPC::MakeHeader(0x1B, 2, 0);
439 cmd_buff[1] = RESULT_SUCCESS.raw;
440 cmd_buff[2] = conversion.input_line_width;
441 LOG_DEBUG(Service_Y2R, "called input_line_width=%u", conversion.input_line_width);
442}
443
223static void SetInputLines(Service::Interface* self) { 444static void SetInputLines(Service::Interface* self) {
224 u32* cmd_buff = Kernel::GetCommandBuffer(); 445 u32* cmd_buff = Kernel::GetCommandBuffer();
225 446
226 LOG_DEBUG(Service_Y2R, "called input_line_number=%u", cmd_buff[1]); 447 LOG_DEBUG(Service_Y2R, "called input_lines=%u", cmd_buff[1]);
448 cmd_buff[0] = IPC::MakeHeader(0x1C, 1, 0);
227 cmd_buff[1] = conversion.SetInputLines(cmd_buff[1]).raw; 449 cmd_buff[1] = conversion.SetInputLines(cmd_buff[1]).raw;
228} 450}
229 451
452static void GetInputLines(Service::Interface* self) {
453 u32* cmd_buff = Kernel::GetCommandBuffer();
454
455 cmd_buff[0] = IPC::MakeHeader(0x1D, 2, 0);
456 cmd_buff[1] = RESULT_SUCCESS.raw;
457 cmd_buff[2] = static_cast<u32>(conversion.input_lines);
458 LOG_DEBUG(Service_Y2R, "called input_lines=%u", conversion.input_lines);
459}
460
230static void SetCoefficient(Service::Interface* self) { 461static void SetCoefficient(Service::Interface* self) {
231 u32* cmd_buff = Kernel::GetCommandBuffer(); 462 u32* cmd_buff = Kernel::GetCommandBuffer();
232 463
@@ -236,15 +467,45 @@ static void SetCoefficient(Service::Interface* self) {
236 coefficients[0], coefficients[1], coefficients[2], coefficients[3], 467 coefficients[0], coefficients[1], coefficients[2], coefficients[3],
237 coefficients[4], coefficients[5], coefficients[6], coefficients[7]); 468 coefficients[4], coefficients[5], coefficients[6], coefficients[7]);
238 469
470 cmd_buff[0] = IPC::MakeHeader(0x1E, 1, 0);
239 cmd_buff[1] = RESULT_SUCCESS.raw; 471 cmd_buff[1] = RESULT_SUCCESS.raw;
240} 472}
241 473
474static void GetCoefficient(Service::Interface* self) {
475 u32* cmd_buff = Kernel::GetCommandBuffer();
476
477 cmd_buff[0] = IPC::MakeHeader(0x1F, 5, 0);
478 cmd_buff[1] = RESULT_SUCCESS.raw;
479 std::memcpy(&cmd_buff[2], conversion.coefficients.data(), sizeof(CoefficientSet));
480}
481
242static void SetStandardCoefficient(Service::Interface* self) { 482static void SetStandardCoefficient(Service::Interface* self) {
243 u32* cmd_buff = Kernel::GetCommandBuffer(); 483 u32* cmd_buff = Kernel::GetCommandBuffer();
244 484
245 LOG_DEBUG(Service_Y2R, "called standard_coefficient=%u", cmd_buff[1]); 485 u32 index = cmd_buff[1];
246 486
247 cmd_buff[1] = conversion.SetStandardCoefficient((StandardCoefficient)cmd_buff[1]).raw; 487 cmd_buff[0] = IPC::MakeHeader(0x20, 1, 0);
488 cmd_buff[1] = conversion.SetStandardCoefficient((StandardCoefficient)index).raw;
489 LOG_DEBUG(Service_Y2R, "called standard_coefficient=%u", index);
490}
491
492static void GetStandardCoefficient(Service::Interface* self) {
493 u32* cmd_buff = Kernel::GetCommandBuffer();
494
495 u32 index = cmd_buff[1];
496
497 if (index < ARRAY_SIZE(standard_coefficients)) {
498 std::memcpy(&cmd_buff[2], &standard_coefficients[index], sizeof(CoefficientSet));
499
500 cmd_buff[0] = IPC::MakeHeader(0x21, 5, 0);
501 cmd_buff[1] = RESULT_SUCCESS.raw;
502 LOG_DEBUG(Service_Y2R, "called standard_coefficient=%u ", index);
503 }
504 else {
505 cmd_buff[0] = IPC::MakeHeader(0x21, 1, 0);
506 cmd_buff[1] = -1;
507 LOG_ERROR(Service_Y2R, "called standard_coefficient=%u The argument is invalid!", index);
508 }
248} 509}
249 510
250static void SetAlpha(Service::Interface* self) { 511static void SetAlpha(Service::Interface* self) {
@@ -253,7 +514,35 @@ static void SetAlpha(Service::Interface* self) {
253 conversion.alpha = cmd_buff[1]; 514 conversion.alpha = cmd_buff[1];
254 LOG_DEBUG(Service_Y2R, "called alpha=%hu", conversion.alpha); 515 LOG_DEBUG(Service_Y2R, "called alpha=%hu", conversion.alpha);
255 516
517 cmd_buff[0] = IPC::MakeHeader(0x22, 1, 0);
518 cmd_buff[1] = RESULT_SUCCESS.raw;
519}
520
521static void GetAlpha(Service::Interface* self) {
522 u32* cmd_buff = Kernel::GetCommandBuffer();
523
524 cmd_buff[0] = IPC::MakeHeader(0x23, 2, 0);
256 cmd_buff[1] = RESULT_SUCCESS.raw; 525 cmd_buff[1] = RESULT_SUCCESS.raw;
526 cmd_buff[2] = conversion.alpha;
527 LOG_DEBUG(Service_Y2R, "called alpha=%hu", conversion.alpha);
528}
529
530static void SetDitheringWeightParams(Service::Interface* self) {
531 u32* cmd_buff = Kernel::GetCommandBuffer();
532 std::memcpy(&dithering_weight_params, &cmd_buff[1], sizeof(DitheringWeightParams));
533
534 cmd_buff[0] = IPC::MakeHeader(0x24, 1, 0);
535 cmd_buff[1] = RESULT_SUCCESS.raw;
536 LOG_DEBUG(Service_Y2R, "called");
537}
538
539static void GetDitheringWeightParams(Service::Interface* self) {
540 u32* cmd_buff = Kernel::GetCommandBuffer();
541
542 cmd_buff[0] = IPC::MakeHeader(0x25, 9, 0);
543 cmd_buff[1] = RESULT_SUCCESS.raw;
544 std::memcpy(&cmd_buff[2], &dithering_weight_params, sizeof(DitheringWeightParams));
545 LOG_DEBUG(Service_Y2R, "called");
257} 546}
258 547
259static void StartConversion(Service::Interface* self) { 548static void StartConversion(Service::Interface* self) {
@@ -269,6 +558,7 @@ static void StartConversion(Service::Interface* self) {
269 LOG_DEBUG(Service_Y2R, "called"); 558 LOG_DEBUG(Service_Y2R, "called");
270 completion_event->Signal(); 559 completion_event->Signal();
271 560
561 cmd_buff[0] = IPC::MakeHeader(0x26, 1, 0);
272 cmd_buff[1] = RESULT_SUCCESS.raw; 562 cmd_buff[1] = RESULT_SUCCESS.raw;
273} 563}
274 564
@@ -289,15 +579,16 @@ static void StopConversion(Service::Interface* self) {
289static void IsBusyConversion(Service::Interface* self) { 579static void IsBusyConversion(Service::Interface* self) {
290 u32* cmd_buff = Kernel::GetCommandBuffer(); 580 u32* cmd_buff = Kernel::GetCommandBuffer();
291 581
582 cmd_buff[0] = IPC::MakeHeader(0x28, 2, 0);
292 cmd_buff[1] = RESULT_SUCCESS.raw; 583 cmd_buff[1] = RESULT_SUCCESS.raw;
293 cmd_buff[2] = 0; // StartConversion always finishes immediately 584 cmd_buff[2] = 0; // StartConversion always finishes immediately
294 LOG_DEBUG(Service_Y2R, "called"); 585 LOG_DEBUG(Service_Y2R, "called");
295} 586}
296 587
297/** 588/**
298 * Y2R_U::SetConversionParams service function 589 * Y2R_U::SetPackageParameter service function
299 */ 590 */
300static void SetConversionParams(Service::Interface* self) { 591static void SetPackageParameter(Service::Interface* self) {
301 u32* cmd_buff = Kernel::GetCommandBuffer(); 592 u32* cmd_buff = Kernel::GetCommandBuffer();
302 593
303 auto params = reinterpret_cast<const ConversionParameters*>(&cmd_buff[1]); 594 auto params = reinterpret_cast<const ConversionParameters*>(&cmd_buff[1]);
@@ -307,7 +598,7 @@ static void SetConversionParams(Service::Interface* self) {
307 "reserved=%hhu alpha=%hX", 598 "reserved=%hhu alpha=%hX",
308 params->input_format, params->output_format, params->rotation, params->block_alignment, 599 params->input_format, params->output_format, params->rotation, params->block_alignment,
309 params->input_line_width, params->input_lines, params->standard_coefficient, 600 params->input_line_width, params->input_lines, params->standard_coefficient,
310 params->reserved, params->alpha); 601 params->padding, params->alpha);
311 602
312 ResultCode result = RESULT_SUCCESS; 603 ResultCode result = RESULT_SUCCESS;
313 604
@@ -321,6 +612,7 @@ static void SetConversionParams(Service::Interface* self) {
321 if (result.IsError()) goto cleanup; 612 if (result.IsError()) goto cleanup;
322 result = conversion.SetStandardCoefficient(params->standard_coefficient); 613 result = conversion.SetStandardCoefficient(params->standard_coefficient);
323 if (result.IsError()) goto cleanup; 614 if (result.IsError()) goto cleanup;
615 conversion.padding = params->padding;
324 conversion.alpha = params->alpha; 616 conversion.alpha = params->alpha;
325 617
326cleanup: 618cleanup:
@@ -331,6 +623,7 @@ cleanup:
331static void PingProcess(Service::Interface* self) { 623static void PingProcess(Service::Interface* self) {
332 u32* cmd_buff = Kernel::GetCommandBuffer(); 624 u32* cmd_buff = Kernel::GetCommandBuffer();
333 625
626 cmd_buff[0] = IPC::MakeHeader(0x2A, 2, 0);
334 cmd_buff[1] = RESULT_SUCCESS.raw; 627 cmd_buff[1] = RESULT_SUCCESS.raw;
335 cmd_buff[2] = 0; 628 cmd_buff[2] = 0;
336 LOG_WARNING(Service_Y2R, "(STUBBED) called"); 629 LOG_WARNING(Service_Y2R, "(STUBBED) called");
@@ -369,51 +662,63 @@ static void DriverFinalize(Service::Interface* self) {
369 LOG_DEBUG(Service_Y2R, "called"); 662 LOG_DEBUG(Service_Y2R, "called");
370} 663}
371 664
665
666static void GetPackageParameter(Service::Interface* self) {
667 u32* cmd_buff = Kernel::GetCommandBuffer();
668
669 cmd_buff[0] = IPC::MakeHeader(0x2D, 4, 0);
670 cmd_buff[1] = RESULT_SUCCESS.raw;
671 std::memcpy(&cmd_buff[2], &conversion, sizeof(ConversionParameters));
672
673 LOG_DEBUG(Service_Y2R, "called");
674}
675
372const Interface::FunctionInfo FunctionTable[] = { 676const Interface::FunctionInfo FunctionTable[] = {
373 {0x00010040, SetInputFormat, "SetInputFormat"}, 677 {0x00010040, SetInputFormat, "SetInputFormat"},
374 {0x00020000, nullptr, "GetInputFormat"}, 678 {0x00020000, GetInputFormat, "GetInputFormat"},
375 {0x00030040, SetOutputFormat, "SetOutputFormat"}, 679 {0x00030040, SetOutputFormat, "SetOutputFormat"},
376 {0x00040000, nullptr, "GetOutputFormat"}, 680 {0x00040000, GetOutputFormat, "GetOutputFormat"},
377 {0x00050040, SetRotation, "SetRotation"}, 681 {0x00050040, SetRotation, "SetRotation"},
378 {0x00060000, nullptr, "GetRotation"}, 682 {0x00060000, GetRotation, "GetRotation"},
379 {0x00070040, SetBlockAlignment, "SetBlockAlignment"}, 683 {0x00070040, SetBlockAlignment, "SetBlockAlignment"},
380 {0x00080000, nullptr, "GetBlockAlignment"}, 684 {0x00080000, GetBlockAlignment, "GetBlockAlignment"},
381 {0x00090040, nullptr, "SetSpacialDithering"}, 685 {0x00090040, SetSpacialDithering, "SetSpacialDithering"},
382 {0x000A0000, nullptr, "GetSpacialDithering"}, 686 {0x000A0000, GetSpacialDithering, "GetSpacialDithering"},
383 {0x000B0040, nullptr, "SetTemporalDithering"}, 687 {0x000B0040, SetTemporalDithering, "SetTemporalDithering"},
384 {0x000C0000, nullptr, "GetTemporalDithering"}, 688 {0x000C0000, GetTemporalDithering, "GetTemporalDithering"},
385 {0x000D0040, SetTransferEndInterrupt, "SetTransferEndInterrupt"}, 689 {0x000D0040, SetTransferEndInterrupt, "SetTransferEndInterrupt"},
690 {0x000E0000, GetTransferEndInterrupt, "GetTransferEndInterrupt"},
386 {0x000F0000, GetTransferEndEvent, "GetTransferEndEvent"}, 691 {0x000F0000, GetTransferEndEvent, "GetTransferEndEvent"},
387 {0x00100102, SetSendingY, "SetSendingY"}, 692 {0x00100102, SetSendingY, "SetSendingY"},
388 {0x00110102, SetSendingU, "SetSendingU"}, 693 {0x00110102, SetSendingU, "SetSendingU"},
389 {0x00120102, SetSendingV, "SetSendingV"}, 694 {0x00120102, SetSendingV, "SetSendingV"},
390 {0x00130102, SetSendingYUYV, "SetSendingYUYV"}, 695 {0x00130102, SetSendingYUYV, "SetSendingYUYV"},
391 {0x00140000, nullptr, "IsFinishedSendingYuv"}, 696 {0x00140000, IsFinishedSendingYuv, "IsFinishedSendingYuv"},
392 {0x00150000, nullptr, "IsFinishedSendingY"}, 697 {0x00150000, IsFinishedSendingY, "IsFinishedSendingY"},
393 {0x00160000, nullptr, "IsFinishedSendingU"}, 698 {0x00160000, IsFinishedSendingU, "IsFinishedSendingU"},
394 {0x00170000, nullptr, "IsFinishedSendingV"}, 699 {0x00170000, IsFinishedSendingV, "IsFinishedSendingV"},
395 {0x00180102, SetReceiving, "SetReceiving"}, 700 {0x00180102, SetReceiving, "SetReceiving"},
396 {0x00190000, nullptr, "IsFinishedReceiving"}, 701 {0x00190000, IsFinishedReceiving, "IsFinishedReceiving"},
397 {0x001A0040, SetInputLineWidth, "SetInputLineWidth"}, 702 {0x001A0040, SetInputLineWidth, "SetInputLineWidth"},
398 {0x001B0000, nullptr, "GetInputLineWidth"}, 703 {0x001B0000, GetInputLineWidth, "GetInputLineWidth"},
399 {0x001C0040, SetInputLines, "SetInputLines"}, 704 {0x001C0040, SetInputLines, "SetInputLines"},
400 {0x001D0000, nullptr, "GetInputLines"}, 705 {0x001D0000, GetInputLines, "GetInputLines"},
401 {0x001E0100, SetCoefficient, "SetCoefficient"}, 706 {0x001E0100, SetCoefficient, "SetCoefficient"},
402 {0x001F0000, nullptr, "GetCoefficient"}, 707 {0x001F0000, GetCoefficient, "GetCoefficient"},
403 {0x00200040, SetStandardCoefficient, "SetStandardCoefficient"}, 708 {0x00200040, SetStandardCoefficient, "SetStandardCoefficient"},
404 {0x00210040, nullptr, "GetStandardCoefficientParams"}, 709 {0x00210040, GetStandardCoefficient, "GetStandardCoefficient"},
405 {0x00220040, SetAlpha, "SetAlpha"}, 710 {0x00220040, SetAlpha, "SetAlpha"},
406 {0x00230000, nullptr, "GetAlpha"}, 711 {0x00230000, GetAlpha, "GetAlpha"},
407 {0x00240200, nullptr, "SetDitheringWeightParams"}, 712 {0x00240200, SetDitheringWeightParams,"SetDitheringWeightParams"},
408 {0x00250000, nullptr, "GetDitheringWeightParams"}, 713 {0x00250000, GetDitheringWeightParams,"GetDitheringWeightParams"},
409 {0x00260000, StartConversion, "StartConversion"}, 714 {0x00260000, StartConversion, "StartConversion"},
410 {0x00270000, StopConversion, "StopConversion"}, 715 {0x00270000, StopConversion, "StopConversion"},
411 {0x00280000, IsBusyConversion, "IsBusyConversion"}, 716 {0x00280000, IsBusyConversion, "IsBusyConversion"},
412 {0x002901C0, SetConversionParams, "SetConversionParams"}, 717 {0x002901C0, SetPackageParameter, "SetPackageParameter"},
413 {0x002A0000, PingProcess, "PingProcess"}, 718 {0x002A0000, PingProcess, "PingProcess"},
414 {0x002B0000, DriverInitialize, "DriverInitialize"}, 719 {0x002B0000, DriverInitialize, "DriverInitialize"},
415 {0x002C0000, DriverFinalize, "DriverFinalize"}, 720 {0x002C0000, DriverFinalize, "DriverFinalize"},
416 {0x002D0000, nullptr, "GetPackageParameter"}, 721 {0x002D0000, GetPackageParameter, "GetPackageParameter"},
417}; 722};
418 723
419//////////////////////////////////////////////////////////////////////////////////////////////////// 724////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/hle/service/y2r_u.h b/src/core/hle/service/y2r_u.h
index 3965a5545..95fa2fdb7 100644
--- a/src/core/hle/service/y2r_u.h
+++ b/src/core/hle/service/y2r_u.h
@@ -97,6 +97,7 @@ struct ConversionConfiguration {
97 u16 input_line_width; 97 u16 input_line_width;
98 u16 input_lines; 98 u16 input_lines;
99 CoefficientSet coefficients; 99 CoefficientSet coefficients;
100 u8 padding;
100 u16 alpha; 101 u16 alpha;
101 102
102 /// Input parameters for the Y (luma) plane 103 /// Input parameters for the Y (luma) plane
@@ -109,6 +110,25 @@ struct ConversionConfiguration {
109 ResultCode SetStandardCoefficient(StandardCoefficient standard_coefficient); 110 ResultCode SetStandardCoefficient(StandardCoefficient standard_coefficient);
110}; 111};
111 112
113struct DitheringWeightParams {
114 u16 w0_xEven_yEven;
115 u16 w0_xOdd_yEven;
116 u16 w0_xEven_yOdd;
117 u16 w0_xOdd_yOdd;
118 u16 w1_xEven_yEven;
119 u16 w1_xOdd_yEven;
120 u16 w1_xEven_yOdd;
121 u16 w1_xOdd_yOdd;
122 u16 w2_xEven_yEven;
123 u16 w2_xOdd_yEven;
124 u16 w2_xEven_yOdd;
125 u16 w2_xOdd_yOdd;
126 u16 w3_xEven_yEven;
127 u16 w3_xOdd_yEven;
128 u16 w3_xEven_yOdd;
129 u16 w3_xOdd_yOdd;
130};
131
112class Interface : public Service::Interface { 132class Interface : public Service::Interface {
113public: 133public:
114 Interface(); 134 Interface();