summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar namkazy2020-03-22 20:14:12 +0700
committerGravatar namkazy2020-04-05 10:31:29 +0700
commitf24c2e11035dd31deadebb14f9737cb31f73158e (patch)
treed4824508286aa8f002fbc5809aac394412a1d63d /src
parentadd shader stage when init shader ir (diff)
downloadyuzu-f24c2e11035dd31deadebb14f9737cb31f73158e.tar.gz
yuzu-f24c2e11035dd31deadebb14f9737cb31f73158e.tar.xz
yuzu-f24c2e11035dd31deadebb14f9737cb31f73158e.zip
[wip] reimplement SULD.D
Diffstat (limited to 'src')
-rw-r--r--src/video_core/shader/decode/image.cpp251
1 files changed, 229 insertions, 22 deletions
diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp
index 3eb657099..feb451452 100644
--- a/src/video_core/shader/decode/image.cpp
+++ b/src/video_core/shader/decode/image.cpp
@@ -2,6 +2,8 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#pragma optimize("", off)
6
5#include <algorithm> 7#include <algorithm>
6#include <vector> 8#include <vector>
7#include <fmt/format.h> 9#include <fmt/format.h>
@@ -10,9 +12,12 @@
10#include "common/bit_field.h" 12#include "common/bit_field.h"
11#include "common/common_types.h" 13#include "common/common_types.h"
12#include "common/logging/log.h" 14#include "common/logging/log.h"
15#include "core/core.h"
16#include "video_core/engines/maxwell_3d.h"
13#include "video_core/engines/shader_bytecode.h" 17#include "video_core/engines/shader_bytecode.h"
14#include "video_core/shader/node_helper.h" 18#include "video_core/shader/node_helper.h"
15#include "video_core/shader/shader_ir.h" 19#include "video_core/shader/shader_ir.h"
20#include "video_core/textures/texture.h"
16 21
17namespace VideoCommon::Shader { 22namespace VideoCommon::Shader {
18 23
@@ -20,8 +25,162 @@ using Tegra::Shader::Instruction;
20using Tegra::Shader::OpCode; 25using Tegra::Shader::OpCode;
21using Tegra::Shader::PredCondition; 26using Tegra::Shader::PredCondition;
22using Tegra::Shader::StoreType; 27using Tegra::Shader::StoreType;
28using Tegra::Texture::ComponentType;
29using Tegra::Texture::TextureFormat;
30using Tegra::Texture::TICEntry;
23 31
24namespace { 32namespace {
33ComponentType GetComponentType(TICEntry tic, std::size_t component) {
34 constexpr u8 R = 0b0001;
35 constexpr u8 G = 0b0010;
36 constexpr u8 B = 0b0100;
37 constexpr u8 A = 0b1000;
38 if (R & component) {
39 return tic.r_type;
40 }
41 if (G & component) {
42 return tic.g_type;
43 }
44 if (B & component) {
45 return tic.b_type;
46 }
47 if (A & component) {
48 return tic.a_type;
49 }
50 return ComponentType::FLOAT;
51}
52
53bool IsComponentEnabled(std::size_t component_mask, std::size_t component) {
54 constexpr u8 R = 0b0001;
55 constexpr u8 G = 0b0010;
56 constexpr u8 B = 0b0100;
57 constexpr u8 A = 0b1000;
58 constexpr std::array<u8, 16> mask = {
59 0, (R), (G), (R | G), (B), (R | B), (G | B), (R | G | B),
60 (A), (R | A), (G | A), (R | G | A), (B | A), (R | B | A), (G | B | A), (R | G | B | A)};
61 return std::bitset<4>{mask.at(component_mask)}.test(component);
62}
63
64u32 GetComponentSize(TextureFormat format, std::size_t component) {
65 switch (format) {
66 case TextureFormat::R32_G32_B32_A32:
67 return 32;
68 case TextureFormat::R16_G16_B16_A16:
69 return 16;
70 case TextureFormat::R32_G32_B32:
71 return (0 == component || 1 == component || 2 == component) ? 32 : 0;
72 case TextureFormat::R32_G32:
73 return (0 == component || 1 == component) ? 32 : 0;
74 case TextureFormat::R16_G16:
75 return (0 == component || 1 == component) ? 16 : 0;
76 case TextureFormat::R32:
77 return (0 == component) ? 32 : 0;
78 case TextureFormat::R16:
79 return (0 == component) ? 16 : 0;
80 case TextureFormat::R8:
81 return (0 == component) ? 8 : 0;
82 case TextureFormat::R1:
83 return (0 == component) ? 1 : 0;
84 case TextureFormat::A8R8G8B8:
85 return 8;
86 case TextureFormat::A2B10G10R10:
87 return (3 == component || 2 == component || 1 == component) ? 10 : 2;
88 case TextureFormat::A4B4G4R4:
89 return 4;
90 case TextureFormat::A5B5G5R1:
91 return (0 == component || 1 == component || 2 == component) ? 5 : 1;
92 case TextureFormat::A1B5G5R5:
93 return (1 == component || 2 == component || 3 == component) ? 5 : 1;
94 case TextureFormat::R32_B24G8:
95 if (0 == component) {
96 return 32;
97 }
98 if (1 == component) {
99 return 24;
100 }
101 if (2 == component) {
102 return 8;
103 }
104 return 0;
105 case TextureFormat::B5G6R5:
106 if (0 == component || 2 == component) {
107 return 5;
108 }
109 if (1 == component) {
110 return 6;
111 }
112 return 0;
113 case TextureFormat::B6G5R5:
114 if (1 == component || 2 == component) {
115 return 5;
116 }
117 if (0 == component) {
118 return 6;
119 }
120 return 0;
121 case TextureFormat::G8R24:
122 if (0 == component) {
123 return 8;
124 }
125 if (1 == component) {
126 return 24;
127 }
128 return 0;
129 case TextureFormat::G24R8:
130 if (0 == component) {
131 return 8;
132 }
133 if (1 == component) {
134 return 24;
135 }
136 return 0;
137 case TextureFormat::G8R8:
138 return (0 == component || 1 == component) ? 8 : 0;
139 case TextureFormat::G4R4:
140 return (0 == component || 1 == component) ? 4 : 0;
141 default:
142 UNIMPLEMENTED_MSG("texture format not implement={}", format);
143 return 0;
144 }
145}
146
147std::size_t GetImageComponentMask(TextureFormat format) {
148 constexpr u8 R = 0b0001;
149 constexpr u8 G = 0b0010;
150 constexpr u8 B = 0b0100;
151 constexpr u8 A = 0b1000;
152 switch (format) {
153 case TextureFormat::R32_G32_B32_A32:
154 case TextureFormat::R16_G16_B16_A16:
155 case TextureFormat::A8R8G8B8:
156 case TextureFormat::A2B10G10R10:
157 case TextureFormat::A4B4G4R4:
158 case TextureFormat::A5B5G5R1:
159 case TextureFormat::A1B5G5R5:
160 return std::size_t{R | G | B | A};
161 case TextureFormat::R32_G32_B32:
162 case TextureFormat::R32_B24G8:
163 case TextureFormat::B5G6R5:
164 case TextureFormat::B6G5R5:
165 return std::size_t{R | G | B};
166 case TextureFormat::R32_G32:
167 case TextureFormat::R16_G16:
168 case TextureFormat::G8R24:
169 case TextureFormat::G24R8:
170 case TextureFormat::G8R8:
171 case TextureFormat::G4R4:
172 return std::size_t{R | G};
173 case TextureFormat::R32:
174 case TextureFormat::R16:
175 case TextureFormat::R8:
176 case TextureFormat::R1:
177 return std::size_t{R};
178 default:
179 UNIMPLEMENTED_MSG("texture format not implement={}", format);
180 return std::size_t{R | G | B | A};
181 }
182}
183
25std::size_t GetImageTypeNumCoordinates(Tegra::Shader::ImageType image_type) { 184std::size_t GetImageTypeNumCoordinates(Tegra::Shader::ImageType image_type) {
26 switch (image_type) { 185 switch (image_type) {
27 case Tegra::Shader::ImageType::Texture1D: 186 case Tegra::Shader::ImageType::Texture1D:
@@ -79,36 +238,84 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) {
79 } else if (instr.suldst.mode == Tegra::Shader::SurfaceDataMode::D_BA) { 238 } else if (instr.suldst.mode == Tegra::Shader::SurfaceDataMode::D_BA) {
80 UNIMPLEMENTED_IF(instr.suldst.GetStoreDataLayout() != StoreType::Bits32); 239 UNIMPLEMENTED_IF(instr.suldst.GetStoreDataLayout() != StoreType::Bits32);
81 240
241 const auto maxwell3d = &Core::System::GetInstance().GPU().Maxwell3D();
242 const auto tex_info = maxwell3d->GetStageTexture(shader_stage, image.GetOffset());
243
244 const auto comp_mask = GetImageComponentMask(tex_info.tic.format);
245 // TODO(namkazt): let's suppose image format is same as store type. we check on it
246 // later.
247
82 switch (instr.suldst.GetStoreDataLayout()) { 248 switch (instr.suldst.GetStoreDataLayout()) {
83 case StoreType::Bits32: { 249 case StoreType::Bits32: {
84 Node value{}; 250 u32 shifted_counter = 0;
85 for (s32 i = 3; i >= 0; i--) { 251 Node value = Immediate(0);
86 MetaImage meta{image, {}, i}; 252 for (u32 element = 0; element < 4; ++element) {
87 Node element_value = 253 if (!IsComponentEnabled(comp_mask, element)) {
254 continue;
255 }
256 const auto component_type = GetComponentType(tex_info.tic, element);
257 const auto component_size = GetComponentSize(tex_info.tic.format, element);
258 bool is_signed = true;
259 MetaImage meta{image, {}, element};
260 const Node original_value =
88 Operation(OperationCode::ImageLoad, meta, GetCoordinates(type)); 261 Operation(OperationCode::ImageLoad, meta, GetCoordinates(type));
262 Node converted_value = [&] {
263 switch (component_type) {
264 case ComponentType::SNORM: {
265 // range [-1.0, 1.0]
266 auto cnv_value = Operation(OperationCode::FMul, NO_PRECISE,
267 original_value, Immediate(128.f));
268 return SignedOperation(OperationCode::ICastFloat, is_signed, NO_PRECISE,
269 std::move(cnv_value));
270 return cnv_value;
271 }
272 case ComponentType::UNORM: {
273 // range [0.0, 1.0]
274 auto cnv_value = Operation(OperationCode::FMul, NO_PRECISE,
275 original_value, Immediate(255.f));
276 is_signed = false;
277 return SignedOperation(OperationCode::ICastFloat, is_signed, NO_PRECISE,
278 std::move(cnv_value));
279 return cnv_value;
280 }
281 case ComponentType::SINT: // range [-128,128]
282 return original_value;
283 case ComponentType::UINT: // range [0, 255]
284 is_signed = false;
285 return original_value;
286 case ComponentType::FLOAT:
287 if (component_size == 8) {
288 auto cnv_value = Operation(OperationCode::FMul, NO_PRECISE,
289 original_value, Immediate(255.f));
290 return SignedOperation(OperationCode::ICastFloat, is_signed,
291 NO_PRECISE, std::move(cnv_value));
292 }
293 return original_value;
294 default:
295 UNIMPLEMENTED_MSG("Unimplement component type={}", component_type);
296 return original_value;
297 }
298 }();
299 // shift element to correct position
300 shifted_counter += component_size;
301 const auto shifted = 32 - shifted_counter;
302 if (shifted > 0) {
303 /* converted_value =
304 SignedOperation(OperationCode::ILogicalShiftLeft, is_signed,
305 std::move(converted_value), Immediate(shifted));*/
306 }
89 307
90 const Node comp = GetPredicateComparisonFloat(PredCondition::GreaterEqual, 308 // add value into result
91 element_value, Immediate(1.0f)); 309 if (element == 0) {
92 const Node mul = 310 value = original_value;
93 Operation(OperationCode::Select, comp, Immediate(1.f), Immediate(255.f));
94
95 Node element = Operation(OperationCode::FMul, NO_PRECISE, element_value, mul);
96 element = SignedOperation(OperationCode::ICastFloat, true, NO_PRECISE,
97 std::move(element));
98 element = Operation(OperationCode::ULogicalShiftLeft, std::move(element),
99 Immediate(8 * i));
100 if (i == 3) {
101 //(namkazt) for now i'm force it to 0 at alpha component if color is in
102 // range (0-255)
103 value = Operation(OperationCode::Select, comp, Immediate(0),
104 std::move(element));
105 } else { 311 } else {
106 value = Operation(OperationCode::UBitwiseOr, value, 312 value =
107 Operation(OperationCode::Select, comp, 313 Operation(OperationCode::UBitwiseOr, value, std::move(converted_value));
108 std::move(element_value), std::move(element)));
109 } 314 }
315 break;
110 } 316 }
111 SetRegister(bb, instr.gpr0.Value(), std::move(value)); 317 SetRegister(bb, instr.gpr0.Value(), std::move(value));
318
112 break; 319 break;
113 } 320 }
114 default: 321 default: