CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
hrydgard

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: hrydgard/ppsspp
Path: blob/master/GPU/Common/ReinterpretFramebuffer.cpp
Views: 1401
1
#include <cstdarg>
2
3
#include "Common/GPU/Shader.h"
4
#include "Common/GPU/ShaderWriter.h"
5
#include "Common/Log.h"
6
#include "Common/GPU/thin3d.h"
7
#include "Core/System.h"
8
#include "GPU/Common/ReinterpretFramebuffer.h"
9
#include "GPU/Common/FramebufferManagerCommon.h"
10
#include "GPU/Common/TextureCacheCommon.h"
11
12
static const VaryingDef varyings[1] = {
13
{ "vec2", "v_texcoord", Draw::SEM_TEXCOORD0, 0, "highp" },
14
};
15
16
static const SamplerDef samplers[1] = {
17
{ 0, "tex", SamplerFlags::ARRAY_ON_VULKAN }
18
};
19
20
// Requires full size integer math. It would be possible to make a floating point-only version with lots of
21
// modulo and stuff, might do it one day.
22
Draw2DPipelineInfo GenerateReinterpretFragmentShader(ShaderWriter &writer, GEBufferFormat from, GEBufferFormat to) {
23
writer.HighPrecisionFloat();
24
writer.DeclareSamplers(samplers);
25
26
if (writer.Lang().bitwiseOps) {
27
switch (from) {
28
case GE_FORMAT_4444:
29
writer.C("uint packColor(vec4 val) {\n");
30
writer.C(" return uint(val.r * 15.99) | (uint(val.g * 15.99) << 0x4u) | (uint(val.b * 15.99) << 0x8u) | (uint(val.a * 15.99) << 0xCu);\n");
31
writer.C("}\n");
32
break;
33
case GE_FORMAT_5551:
34
writer.C("uint packColor(vec4 val) {\n");
35
writer.C(" uint color = uint(val.r * 31.99) | (uint(val.g * 31.99) << 0x5u) | (uint(val.b * 31.99) << 0xAu);\n");
36
writer.C(" if (val.a >= 0.5) color |= 0x8000U;\n");
37
writer.C(" return color;\n");
38
writer.C("}\n");
39
break;
40
case GE_FORMAT_565:
41
writer.C("uint packColor(vec4 val) {\n");
42
writer.C(" return uint(val.r * 31.99) | (uint(val.g * 63.99) << 0x5u) | (uint(val.b * 31.99) << 0xBu);\n");
43
writer.C("}\n");
44
break;
45
case GE_FORMAT_8888:
46
writer.C("uint packColor(vec2 val) {\n");
47
writer.C(" return uint(val.r * 255.99) | (uint(val.g * 255.99) << 8u);\n");
48
writer.C("}\n");
49
break;
50
default:
51
_assert_(false);
52
break;
53
}
54
} else {
55
// Floating point can comfortably represent integers up to 16 million, we only need 65536 since these textures are 16-bit.
56
switch (from) {
57
case GE_FORMAT_4444:
58
writer.C("float packColor(vec4 val) {\n");
59
writer.C(" return (floor(val.r * 15.99) + floor(val.g * 15.99) * 16.0) + (floor(val.b * 15.99) * 256.0 + floor(val.a * 15.99) * 4096.0);\n");
60
writer.C("}\n");
61
break;
62
case GE_FORMAT_5551:
63
writer.C("float packColor(vec4 val) {\n");
64
writer.C(" float color = floor(val.r * 31.99) + floor(val.g * 31.99) * 32.0 + floor(val.b * 31.99) * 1024.0;\n");
65
writer.C(" if (val.a >= 0.5) color += 32768.0;\n");
66
writer.C(" return color;\n");
67
writer.C("}\n");
68
break;
69
case GE_FORMAT_565:
70
writer.C("float packColor(vec4 val) {\n");
71
writer.C(" return floor(val.r * 31.99) + floor(val.g * 63.99) * 32.0 + floor(val.b * 31.99) * 2048.0;\n");
72
writer.C("}\n");
73
break;
74
case GE_FORMAT_8888:
75
writer.C("float packColor(vec2 val) {\n");
76
writer.C(" return floor(val.r * 255.99) + floor(val.g * 255.99) * 256.0;\n");
77
writer.C("}\n");
78
break;
79
default:
80
_assert_(false);
81
break;
82
}
83
}
84
85
if (writer.Lang().bitwiseOps) {
86
switch (to) {
87
case GE_FORMAT_4444:
88
writer.C("vec4 unpackColor(uint color) {\n");
89
writer.C(" vec4 outColor = vec4(float(color & 0xFu), float((color >> 0x4u) & 0xFu), float((color >> 0x8u) & 0xFu), float((color >> 0xCu) & 0xFu));\n");
90
writer.C(" outColor *= 1.0 / 15.0;\n");
91
writer.C(" return outColor;\n");
92
writer.C("}\n");
93
break;
94
case GE_FORMAT_5551:
95
writer.C("vec4 unpackColor(uint color) {\n");
96
writer.C(" vec4 outColor = vec4(float(color & 0x1Fu), float((color >> 0x5u) & 0x1Fu), float((color >> 0xAu) & 0x1Fu), 0.0);\n");
97
writer.C(" outColor.rgb *= 1.0 / 31.0;\n");
98
writer.C(" outColor.a = float(color >> 0xFu);\n");
99
writer.C(" return outColor;\n");
100
writer.C("}\n");
101
break;
102
case GE_FORMAT_565:
103
writer.C("vec4 unpackColor(uint color) {\n");
104
writer.C(" vec4 outColor = vec4(float(color & 0x1Fu), float((color >> 0x5u) & 0x3Fu), float((color >> 0xBu) & 0x1Fu), 1.0);\n");
105
writer.C(" outColor.rb *= 1.0 / 31.0;\n");
106
writer.C(" outColor.g *= 1.0 / 63.0;\n");
107
writer.C(" return outColor;\n");
108
writer.C("}\n");
109
break;
110
case GE_FORMAT_8888:
111
writer.C("vec4 unpackColor(uint colorLeft, uint colorRight) {\n");
112
writer.C(" vec4 outColor = vec4(float(colorLeft & 0xFFu), float((colorLeft >> 0x8u) & 0xFFu),\n");
113
writer.C(" float(colorRight & 0xFFu), float((colorRight >> 0x8u) & 0xFFu));\n");
114
writer.C(" outColor *= 1.0 / 255.0;\n");
115
writer.C(" return outColor;\n");
116
writer.C("}\n");
117
break;
118
default:
119
_assert_(false);
120
break;
121
}
122
} else {
123
switch (to) {
124
case GE_FORMAT_4444:
125
writer.C("vec4 unpackColor(float color) {\n");
126
writer.C(" vec4 outColor = vec4(mod(floor(color), 16.0), mod(floor(color / 16.0), 16.0),");
127
writer.C(" mod(floor(color / 256.0), 16.0), mod(floor(color / 4096.0), 16.0)); \n");
128
writer.C(" outColor *= 1.0 / 15.0;\n");
129
writer.C(" return outColor;\n");
130
writer.C("}\n");
131
break;
132
case GE_FORMAT_5551:
133
writer.C("vec4 unpackColor(float color) {\n");
134
writer.C(" vec4 outColor = vec4(mod(floor(color), 32.0), mod(floor(color / 32.0), 32.0), mod(floor(color / 1024.0), 32.0), 0.0);\n");
135
writer.C(" outColor.rgb *= 1.0 / 31.0;\n");
136
writer.C(" outColor.a = floor(color / 32768.0);\n");
137
writer.C(" return outColor;\n");
138
writer.C("}\n");
139
break;
140
case GE_FORMAT_565:
141
writer.C("vec4 unpackColor(float color) {\n");
142
writer.C(" vec4 outColor = vec4(mod(floor(color), 32.0), mod(floor(color / 32.0), 64.0), mod(floor(color / 2048.0), 32.0), 0.0);\n");
143
writer.C(" outColor.rb *= 1.0 / 31.0;\n");
144
writer.C(" outColor.g *= 1.0 / 63.0;\n");
145
writer.C(" outColor.a = 1.0;\n");
146
writer.C(" return outColor;\n");
147
writer.C("}\n");
148
break;
149
case GE_FORMAT_8888:
150
writer.C("vec4 unpackColor(float colorLeft, float colorRight) {\n");
151
writer.C(" vec4 outColor = vec4(mod(floor(colorLeft), 256.0), mod(floor(colorLeft / 256.0), 256.0),\n");
152
writer.C(" mod(floor(colorRight), 256.0), mod(floor(colorRight / 256.0), 256.0));\n");
153
writer.C(" outColor *= 1.0 / 255.0;\n");
154
writer.C(" return outColor;\n");
155
writer.C("}\n");
156
break;
157
default:
158
_assert_(false);
159
break;
160
}
161
}
162
163
writer.BeginFSMain(g_draw2Duniforms, varyings);
164
165
if (IsBufferFormat16Bit(from) && IsBufferFormat16Bit(to)) {
166
writer.C(" vec4 val = ").SampleTexture2D("tex", "v_texcoord.xy").C(";\n");
167
writer.C(" vec4 outColor = unpackColor(packColor(val));\n");
168
} else if (IsBufferFormat16Bit(from) && !IsBufferFormat16Bit(to)) {
169
// 16-to-32-bit (two pixels, draw size is halved)
170
171
writer.C(" vec4 valLeft = ").SampleTexture2D("tex", "v_texcoord.xy + vec2(-0.25 / texSize.x, 0.0)").C(";\n");
172
writer.C(" vec4 valRight = ").SampleTexture2D("tex", "v_texcoord.xy + vec2(0.25 / texSize.x, 0.0)").C(";\n");
173
writer.C(" vec4 outColor = unpackColor(packColor(valLeft), packColor(valRight));\n");
174
175
_assert_("not yet implemented");
176
} else if (!IsBufferFormat16Bit(from) && IsBufferFormat16Bit(to)) {
177
// 32-to-16-bit (half of the pixel, draw size is doubled).
178
179
writer.C(" vec4 val = ").SampleTexture2D("tex", "v_texcoord.xy").C(";\n");
180
writer.C(" float u = mod(floor(v_texcoord.x * texSize.x * 2.0), 2.0);\n");
181
writer.C(" vec4 outColor = unpackColor(u == 0.0 ? packColor(val.rg) : packColor(val.ba));\n");
182
}
183
184
writer.EndFSMain("outColor");
185
186
return Draw2DPipelineInfo{
187
"reinterpret",
188
RASTER_COLOR,
189
RASTER_COLOR,
190
};
191
}
192
193
194