aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/hle/service/y2r_u.h
blob: 7df47fcb9261c9288e3485a199bc6159a768f747 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// Copyright 2014 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.

#pragma once

#include <array>

#include "common/common_types.h"

#include "core/hle/service/service.h"

////////////////////////////////////////////////////////////////////////////////////////////////////
// Namespace Y2R_U

namespace Y2R_U {

enum class InputFormat : u8 {
    /// 8-bit input, with YUV components in separate planes and 4:2:2 subsampling.
    YUV422_Indiv8 = 0,
    /// 8-bit input, with YUV components in separate planes and 4:2:0 subsampling.
    YUV420_Indiv8 = 1,

    /// 16-bit input (only LSB used), with YUV components in separate planes and 4:2:2 subsampling.
    YUV422_Indiv16 = 2,
    /// 16-bit input (only LSB used), with YUV components in separate planes and 4:2:0 subsampling.
    YUV420_Indiv16 = 3,

    /// 8-bit input, with a single interleaved stream in YUYV format and 4:2:2 subsampling.
    YUYV422_Interleaved = 4,
};

enum class OutputFormat : u8 {
    RGBA8 = 0,
    RGB8 = 1,
    RGB5A1 = 2,
    RGB565 = 3,
};

enum class Rotation : u8 {
    None = 0,
    Clockwise_90 = 1,
    Clockwise_180 = 2,
    Clockwise_270 = 3,
};

enum class BlockAlignment : u8 {
    /// Image is output in linear format suitable for use as a framebuffer.
    Linear = 0,
    /// Image is output in tiled PICA format, suitable for use as a texture.
    Block8x8 = 1,
};

enum class StandardCoefficient : u8 {
    /// ITU Rec. BT.601 primaries, with PC ranges.
    ITU_Rec601 = 0,
    /// ITU Rec. BT.709 primaries, with PC ranges.
    ITU_Rec709 = 1,
    /// ITU Rec. BT.601 primaries, with TV ranges.
    ITU_Rec601_Scaling = 2,
    /// ITU Rec. BT.709 primaries, with TV ranges.
    ITU_Rec709_Scaling = 3,
};

/**
 * A set of coefficients configuring the RGB to YUV conversion. Coefficients 0-4 are unsigned 2.8
 * fixed pointer numbers representing entries on the conversion matrix, while coefficient 5-7 are
 * signed 11.5 fixed point numbers added as offsets to the RGB result.
 *
 * The overall conversion process formula is:
 * ```
 * R = trunc((c_0 * Y           + c_1 * V) + c_5 + 0.75)
 * G = trunc((c_0 * Y - c_3 * U - c_2 * V) + c_6 + 0.75)
 * B = trunc((c_0 * Y + c_4 * U          ) + c_7 + 0.75)
 * ```
 */
using CoefficientSet = std::array<s16, 8>;

struct ConversionBuffer {
    /// Current reading/writing address of this buffer.
    VAddr address;
    /// Remaining amount of bytes to be DMAed, does not include the inter-trasfer gap.
    u32 image_size;
    /// Size of a single DMA transfer.
    u16 transfer_unit;
    /// Amount of bytes to be skipped between copying each `transfer_unit` bytes.
    u16 gap;
};

struct ConversionConfiguration {
    InputFormat input_format;
    OutputFormat output_format;
    Rotation rotation;
    BlockAlignment block_alignment;
    u16 input_line_width;
    u16 input_lines;
    CoefficientSet coefficients;
    u16 alpha;

    /// Input parameters for the Y (luma) plane
    ConversionBuffer src_Y, src_U, src_V, src_YUYV;
    /// Output parameters for the conversion results
    ConversionBuffer dst;

    ResultCode SetInputLineWidth(u16 width);
    ResultCode SetInputLines(u16 lines);
    ResultCode SetStandardCoefficient(StandardCoefficient standard_coefficient);
};

class Interface : public Service::Interface {
public:
    Interface();

    std::string GetPortName() const override {
        return "y2r:u";
    }
};

} // namespace