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