summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2019-11-12 13:43:08 -0400
committerGravatar FernandoS272019-11-14 11:15:27 -0400
commitcd0f5dfc17209eab146879faad51186b130c4951 (patch)
tree0185de18a433f22edb69260d3f54779419e2b807 /src
parentShader_IR: Implement FLO instruction. (diff)
downloadyuzu-cd0f5dfc17209eab146879faad51186b130c4951.tar.gz
yuzu-cd0f5dfc17209eab146879faad51186b130c4951.tar.xz
yuzu-cd0f5dfc17209eab146879faad51186b130c4951.zip
Shader_IR: Implement TXD instruction.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/shader_bytecode.h20
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp44
-rw-r--r--src/video_core/renderer_vulkan/vk_shader_decompiler.cpp6
-rw-r--r--src/video_core/shader/decode/texture.cpp56
-rw-r--r--src/video_core/shader/node.h2
5 files changed, 120 insertions, 8 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index 16f410538..9c7b9b370 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -1446,6 +1446,26 @@ union Instruction {
1446 } tlds; 1446 } tlds;
1447 1447
1448 union { 1448 union {
1449 BitField<28, 1, u64> is_array;
1450 BitField<29, 2, TextureType> texture_type;
1451 BitField<35, 1, u64> aoffi_flag;
1452 BitField<49, 1, u64> nodep_flag;
1453
1454 bool UsesMiscMode(TextureMiscMode mode) const {
1455 switch (mode) {
1456 case TextureMiscMode::AOFFI:
1457 return aoffi_flag != 0;
1458 case TextureMiscMode::NODEP:
1459 return nodep_flag != 0;
1460 default:
1461 break;
1462 }
1463 return false;
1464 }
1465
1466 } txd;
1467
1468 union {
1449 BitField<24, 2, StoreCacheManagement> cache_management; 1469 BitField<24, 2, StoreCacheManagement> cache_management;
1450 BitField<33, 3, ImageType> image_type; 1470 BitField<33, 3, ImageType> image_type;
1451 BitField<49, 2, OutOfBoundsStore> out_of_bounds_store; 1471 BitField<49, 2, OutOfBoundsStore> out_of_bounds_store;
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index b87ee2ae8..49f0b1620 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -44,8 +44,9 @@ using Operation = const OperationNode&;
44enum class Type { Void, Bool, Bool2, Float, Int, Uint, HalfFloat }; 44enum class Type { Void, Bool, Bool2, Float, Int, Uint, HalfFloat };
45 45
46struct TextureAoffi {}; 46struct TextureAoffi {};
47struct TextureDerivates {};
47using TextureArgument = std::pair<Type, Node>; 48using TextureArgument = std::pair<Type, Node>;
48using TextureIR = std::variant<TextureAoffi, TextureArgument>; 49using TextureIR = std::variant<TextureAoffi, TextureDerivates, TextureArgument>;
49 50
50constexpr u32 MAX_CONSTBUFFER_ELEMENTS = 51constexpr u32 MAX_CONSTBUFFER_ELEMENTS =
51 static_cast<u32>(Maxwell::MaxConstBufferSize) / (4 * sizeof(float)); 52 static_cast<u32>(Maxwell::MaxConstBufferSize) / (4 * sizeof(float));
@@ -1129,6 +1130,8 @@ private:
1129 expr += GenerateTextureArgument(*argument); 1130 expr += GenerateTextureArgument(*argument);
1130 } else if (std::holds_alternative<TextureAoffi>(variant)) { 1131 } else if (std::holds_alternative<TextureAoffi>(variant)) {
1131 expr += GenerateTextureAoffi(meta->aoffi); 1132 expr += GenerateTextureAoffi(meta->aoffi);
1133 } else if (std::holds_alternative<TextureDerivates>(variant)) {
1134 expr += GenerateTextureDerivates(meta->derivates);
1132 } else { 1135 } else {
1133 UNREACHABLE(); 1136 UNREACHABLE();
1134 } 1137 }
@@ -1198,6 +1201,36 @@ private:
1198 return expr; 1201 return expr;
1199 } 1202 }
1200 1203
1204 std::string GenerateTextureDerivates(const std::vector<Node>& derivates) {
1205 if (derivates.empty()) {
1206 return {};
1207 }
1208 constexpr std::array coord_constructors = {"float", "vec2", "vec3"};
1209 std::string expr = ", ";
1210 const std::size_t components = derivates.size() / 2;
1211 std::string dx = coord_constructors.at(components - 1);
1212 std::string dy = coord_constructors.at(components - 1);
1213 dx += '(';
1214 dy += '(';
1215
1216 for (std::size_t index = 0; index < components; ++index) {
1217 const auto operand_x{derivates.at(index * 2)};
1218 const auto operand_y{derivates.at(index * 2 + 1)};
1219 dx += Visit(operand_x).AsFloat();
1220 dy += Visit(operand_y).AsFloat();
1221
1222 if (index + 1 < components) {
1223 dx += ", ";
1224 dy += ", ";
1225 }
1226 }
1227 dx += ')';
1228 dy += ')';
1229 expr += dx + ", " + dy;
1230
1231 return expr;
1232 }
1233
1201 std::string BuildIntegerCoordinates(Operation operation) { 1234 std::string BuildIntegerCoordinates(Operation operation) {
1202 constexpr std::array constructors{"int(", "ivec2(", "ivec3(", "ivec4("}; 1235 constexpr std::array constructors{"int(", "ivec2(", "ivec3(", "ivec4("};
1203 const std::size_t coords_count{operation.GetOperandsCount()}; 1236 const std::size_t coords_count{operation.GetOperandsCount()};
@@ -1777,6 +1810,14 @@ private:
1777 return {tmp, Type::Float}; 1810 return {tmp, Type::Float};
1778 } 1811 }
1779 1812
1813 Expression TextureGradient(Operation operation) {
1814 const auto meta = std::get_if<MetaTexture>(&operation.GetMeta());
1815 ASSERT(meta);
1816
1817 std::string expr = GenerateTexture(operation, "Grad", {TextureDerivates{}, TextureAoffi{}});
1818 return {expr + GetSwizzle(meta->element), Type::Float};
1819 }
1820
1780 Expression ImageLoad(Operation operation) { 1821 Expression ImageLoad(Operation operation) {
1781 if (!device.HasImageLoadFormatted()) { 1822 if (!device.HasImageLoadFormatted()) {
1782 LOG_ERROR(Render_OpenGL, 1823 LOG_ERROR(Render_OpenGL,
@@ -2131,6 +2172,7 @@ private:
2131 &GLSLDecompiler::TextureQueryDimensions, 2172 &GLSLDecompiler::TextureQueryDimensions,
2132 &GLSLDecompiler::TextureQueryLod, 2173 &GLSLDecompiler::TextureQueryLod,
2133 &GLSLDecompiler::TexelFetch, 2174 &GLSLDecompiler::TexelFetch,
2175 &GLSLDecompiler::TextureGradient,
2134 2176
2135 &GLSLDecompiler::ImageLoad, 2177 &GLSLDecompiler::ImageLoad,
2136 &GLSLDecompiler::ImageStore, 2178 &GLSLDecompiler::ImageStore,
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
index 8378b35ac..30a525e5d 100644
--- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
+++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
@@ -982,6 +982,11 @@ private:
982 return {}; 982 return {};
983 } 983 }
984 984
985 Id TextureGradient(Operation operation) {
986 UNIMPLEMENTED();
987 return {};
988 }
989
985 Id ImageLoad(Operation operation) { 990 Id ImageLoad(Operation operation) {
986 UNIMPLEMENTED(); 991 UNIMPLEMENTED();
987 return {}; 992 return {};
@@ -1474,6 +1479,7 @@ private:
1474 &SPIRVDecompiler::TextureQueryDimensions, 1479 &SPIRVDecompiler::TextureQueryDimensions,
1475 &SPIRVDecompiler::TextureQueryLod, 1480 &SPIRVDecompiler::TextureQueryLod,
1476 &SPIRVDecompiler::TexelFetch, 1481 &SPIRVDecompiler::TexelFetch,
1482 &SPIRVDecompiler::TextureGradient,
1477 1483
1478 &SPIRVDecompiler::ImageLoad, 1484 &SPIRVDecompiler::ImageLoad,
1479 &SPIRVDecompiler::ImageStore, 1485 &SPIRVDecompiler::ImageStore,
diff --git a/src/video_core/shader/decode/texture.cpp b/src/video_core/shader/decode/texture.cpp
index bb926a132..0e501919d 100644
--- a/src/video_core/shader/decode/texture.cpp
+++ b/src/video_core/shader/decode/texture.cpp
@@ -134,13 +134,55 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
134 Node4 values; 134 Node4 values;
135 for (u32 element = 0; element < values.size(); ++element) { 135 for (u32 element = 0; element < values.size(); ++element) {
136 auto coords_copy = coords; 136 auto coords_copy = coords;
137 MetaTexture meta{sampler, {}, {}, {}, {}, {}, component, element}; 137 MetaTexture meta{sampler, {}, {}, {}, {}, {}, {}, component, element};
138 values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy)); 138 values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy));
139 } 139 }
140 140
141 WriteTexsInstructionFloat(bb, instr, values, true); 141 WriteTexsInstructionFloat(bb, instr, values, true);
142 break; 142 break;
143 } 143 }
144 case OpCode::Id::TXD_B:
145 is_bindless = true;
146 [[fallthrough]];
147 case OpCode::Id::TXD: {
148 UNIMPLEMENTED_IF_MSG(instr.txd.UsesMiscMode(TextureMiscMode::AOFFI),
149 "AOFFI is not implemented");
150 const auto is_array = static_cast<bool>(instr.txd.is_array != 0);
151 UNIMPLEMENTED_IF_MSG(is_array, "TXD Array is not implemented");
152
153 u64 base_reg = instr.gpr8.Value();
154 const auto derivate_reg = instr.gpr20.Value();
155 const auto texture_type = instr.txd.texture_type.Value();
156 const auto coord_count = GetCoordCount(texture_type);
157
158 const auto& sampler = is_bindless
159 ? GetBindlessSampler(base_reg, {{texture_type, false, false}})
160 : GetSampler(instr.sampler, {{texture_type, false, false}});
161 if (is_bindless) {
162 base_reg++;
163 }
164
165 std::vector<Node> coords;
166 std::vector<Node> derivates;
167 for (std::size_t i = 0; i < coord_count; ++i) {
168 coords.push_back(GetRegister(base_reg + i));
169 const std::size_t derivate = i * 2;
170 derivates.push_back(GetRegister(derivate_reg + derivate));
171 derivates.push_back(GetRegister(derivate_reg + derivate + 1));
172 }
173
174 Node4 values;
175 for (u32 element = 0; element < values.size(); ++element) {
176 auto coords_copy = coords;
177 MetaTexture meta{sampler, {}, {}, {}, derivates, {}, {}, {}, element};
178 values[element] =
179 Operation(OperationCode::TextureGradient, meta, std::move(coords_copy));
180 }
181
182 WriteTexInstructionFloat(bb, instr, values);
183
184 break;
185 }
144 case OpCode::Id::TXQ_B: 186 case OpCode::Id::TXQ_B:
145 is_bindless = true; 187 is_bindless = true;
146 [[fallthrough]]; 188 [[fallthrough]];
@@ -158,7 +200,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
158 if (!instr.txq.IsComponentEnabled(element)) { 200 if (!instr.txq.IsComponentEnabled(element)) {
159 continue; 201 continue;
160 } 202 }
161 MetaTexture meta{sampler, {}, {}, {}, {}, {}, {}, element}; 203 MetaTexture meta{sampler, {}, {}, {}, {}, {}, {}, {}, element};
162 const Node value = 204 const Node value =
163 Operation(OperationCode::TextureQueryDimensions, meta, 205 Operation(OperationCode::TextureQueryDimensions, meta,
164 GetRegister(instr.gpr8.Value() + (is_bindless ? 1 : 0))); 206 GetRegister(instr.gpr8.Value() + (is_bindless ? 1 : 0)));
@@ -213,7 +255,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
213 continue; 255 continue;
214 } 256 }
215 auto params = coords; 257 auto params = coords;
216 MetaTexture meta{sampler, {}, {}, {}, {}, {}, {}, element}; 258 MetaTexture meta{sampler, {}, {}, {}, {}, {}, {}, {}, element};
217 const Node value = Operation(OperationCode::TextureQueryLod, meta, std::move(params)); 259 const Node value = Operation(OperationCode::TextureQueryLod, meta, std::move(params));
218 SetTemporary(bb, indexer++, value); 260 SetTemporary(bb, indexer++, value);
219 } 261 }
@@ -461,7 +503,7 @@ Node4 ShaderIR::GetTextureCode(Instruction instr, TextureType texture_type,
461 Node4 values; 503 Node4 values;
462 for (u32 element = 0; element < values.size(); ++element) { 504 for (u32 element = 0; element < values.size(); ++element) {
463 auto copy_coords = coords; 505 auto copy_coords = coords;
464 MetaTexture meta{sampler, array, depth_compare, aoffi, bias, lod, {}, element}; 506 MetaTexture meta{sampler, array, depth_compare, aoffi, {}, bias, lod, {}, element};
465 values[element] = Operation(read_method, meta, std::move(copy_coords)); 507 values[element] = Operation(read_method, meta, std::move(copy_coords));
466 } 508 }
467 509
@@ -594,7 +636,7 @@ Node4 ShaderIR::GetTld4Code(Instruction instr, TextureType texture_type, bool de
594 Node4 values; 636 Node4 values;
595 for (u32 element = 0; element < values.size(); ++element) { 637 for (u32 element = 0; element < values.size(); ++element) {
596 auto coords_copy = coords; 638 auto coords_copy = coords;
597 MetaTexture meta{sampler, GetRegister(array_register), dc, aoffi, {}, {}, component, 639 MetaTexture meta{sampler, GetRegister(array_register), dc, aoffi, {}, {}, {}, component,
598 element}; 640 element};
599 values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy)); 641 values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy));
600 } 642 }
@@ -628,7 +670,7 @@ Node4 ShaderIR::GetTldCode(Tegra::Shader::Instruction instr) {
628 Node4 values; 670 Node4 values;
629 for (u32 element = 0; element < values.size(); ++element) { 671 for (u32 element = 0; element < values.size(); ++element) {
630 auto coords_copy = coords; 672 auto coords_copy = coords;
631 MetaTexture meta{sampler, array_register, {}, {}, {}, lod, {}, element}; 673 MetaTexture meta{sampler, array_register, {}, {}, {}, {}, lod, {}, element};
632 values[element] = Operation(OperationCode::TexelFetch, meta, std::move(coords_copy)); 674 values[element] = Operation(OperationCode::TexelFetch, meta, std::move(coords_copy));
633 } 675 }
634 676
@@ -664,7 +706,7 @@ Node4 ShaderIR::GetTldsCode(Instruction instr, TextureType texture_type, bool is
664 Node4 values; 706 Node4 values;
665 for (u32 element = 0; element < values.size(); ++element) { 707 for (u32 element = 0; element < values.size(); ++element) {
666 auto coords_copy = coords; 708 auto coords_copy = coords;
667 MetaTexture meta{sampler, array, {}, {}, {}, lod, {}, element}; 709 MetaTexture meta{sampler, array, {}, {}, {}, {}, lod, {}, element};
668 values[element] = Operation(OperationCode::TexelFetch, meta, std::move(coords_copy)); 710 values[element] = Operation(OperationCode::TexelFetch, meta, std::move(coords_copy));
669 } 711 }
670 return values; 712 return values;
diff --git a/src/video_core/shader/node.h b/src/video_core/shader/node.h
index 2d11facaf..6c5046d3b 100644
--- a/src/video_core/shader/node.h
+++ b/src/video_core/shader/node.h
@@ -151,6 +151,7 @@ enum class OperationCode {
151 TextureQueryDimensions, /// (MetaTexture, float a) -> float4 151 TextureQueryDimensions, /// (MetaTexture, float a) -> float4
152 TextureQueryLod, /// (MetaTexture, float[N] coords) -> float4 152 TextureQueryLod, /// (MetaTexture, float[N] coords) -> float4
153 TexelFetch, /// (MetaTexture, int[N], int) -> float4 153 TexelFetch, /// (MetaTexture, int[N], int) -> float4
154 TextureGradient, /// (MetaTexture, float[N] coords, float[N*2] derivates) -> float4
154 155
155 ImageLoad, /// (MetaImage, int[N] coords) -> void 156 ImageLoad, /// (MetaImage, int[N] coords) -> void
156 ImageStore, /// (MetaImage, int[N] coords) -> void 157 ImageStore, /// (MetaImage, int[N] coords) -> void
@@ -363,6 +364,7 @@ struct MetaTexture {
363 Node array; 364 Node array;
364 Node depth_compare; 365 Node depth_compare;
365 std::vector<Node> aoffi; 366 std::vector<Node> aoffi;
367 std::vector<Node> derivates;
366 Node bias; 368 Node bias;
367 Node lod; 369 Node lod;
368 Node component{}; 370 Node component{};