committed by
ameerj
31 changed files with 732 additions and 202 deletions
-
1src/shader_recompiler/CMakeLists.txt
-
97src/shader_recompiler/backend/spirv/emit_context.cpp
-
9src/shader_recompiler/backend/spirv/emit_context.h
-
1src/shader_recompiler/backend/spirv/emit_spirv.cpp
-
6src/shader_recompiler/backend/spirv/emit_spirv.h
-
46src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
-
11src/shader_recompiler/frontend/ir/ir_emitter.cpp
-
7src/shader_recompiler/frontend/ir/ir_emitter.h
-
12src/shader_recompiler/frontend/ir/modifiers.h
-
6src/shader_recompiler/frontend/ir/opcodes.inc
-
8src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp
-
280src/shader_recompiler/frontend/maxwell/translate/impl/surface_load_store.cpp
-
19src/shader_recompiler/frontend/maxwell/translate/impl/texture_fetch.cpp
-
12src/shader_recompiler/frontend/maxwell/translate/impl/texture_fetch_swizzled.cpp
-
19src/shader_recompiler/frontend/maxwell/translate/impl/texture_gather.cpp
-
3src/shader_recompiler/frontend/maxwell/translate/impl/texture_gather_swizzled.cpp
-
18src/shader_recompiler/frontend/maxwell/translate/impl/texture_gradient.cpp
-
18src/shader_recompiler/frontend/maxwell/translate/impl/texture_load.cpp
-
2src/shader_recompiler/frontend/maxwell/translate/impl/texture_load_swizzled.cpp
-
18src/shader_recompiler/frontend/maxwell/translate/impl/texture_mipmap_level.cpp
-
3src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp
-
91src/shader_recompiler/ir_opt/texture_pass.cpp
-
47src/shader_recompiler/shader_info.h
-
4src/video_core/renderer_vulkan/blit_image.cpp
-
43src/video_core/renderer_vulkan/pipeline_helper.h
-
4src/video_core/renderer_vulkan/vk_compute_pipeline.cpp
-
4src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
-
2src/video_core/renderer_vulkan/vk_rasterizer.cpp
-
112src/video_core/renderer_vulkan/vk_texture_cache.cpp
-
23src/video_core/renderer_vulkan/vk_texture_cache.h
-
8src/video_core/texture_cache/texture_cache.h
@ -0,0 +1,280 @@ |
|||
// Copyright 2021 yuzu Emulator Project
|
|||
// Licensed under GPLv2 or any later version
|
|||
// Refer to the license.txt file included.
|
|||
|
|||
#include <array>
|
|||
#include <bit>
|
|||
|
|||
#include "common/bit_field.h"
|
|||
#include "common/common_types.h"
|
|||
#include "shader_recompiler/frontend/ir/modifiers.h"
|
|||
#include "shader_recompiler/frontend/maxwell/translate/impl/impl.h"
|
|||
|
|||
namespace Shader::Maxwell { |
|||
namespace { |
|||
enum class Type : u64 { |
|||
_1D, |
|||
BUFFER_1D, |
|||
ARRAY_1D, |
|||
_2D, |
|||
ARRAY_2D, |
|||
_3D, |
|||
}; |
|||
|
|||
constexpr unsigned R = 1 << 0; |
|||
constexpr unsigned G = 1 << 1; |
|||
constexpr unsigned B = 1 << 2; |
|||
constexpr unsigned A = 1 << 3; |
|||
|
|||
constexpr std::array MASK{ |
|||
0U, //
|
|||
R, //
|
|||
G, //
|
|||
R | G, //
|
|||
B, //
|
|||
R | B, //
|
|||
G | B, //
|
|||
R | G | B, //
|
|||
A, //
|
|||
R | A, //
|
|||
G | A, //
|
|||
R | G | A, //
|
|||
B | A, //
|
|||
R | B | A, //
|
|||
G | B | A, //
|
|||
R | G | B | A, //
|
|||
}; |
|||
|
|||
enum class Size : u64 { |
|||
U8, |
|||
S8, |
|||
U16, |
|||
S16, |
|||
B32, |
|||
B64, |
|||
B128, |
|||
}; |
|||
|
|||
enum class Clamp : u64 { |
|||
IGN, |
|||
Default, |
|||
TRAP, |
|||
}; |
|||
|
|||
enum class LoadCache : u64 { |
|||
Default, |
|||
CG, |
|||
CI, |
|||
CV, |
|||
}; |
|||
|
|||
enum class StoreCache : u64 { |
|||
Default, |
|||
CG, |
|||
CS, |
|||
WT, |
|||
}; |
|||
|
|||
ImageFormat Format(Size size) { |
|||
switch (size) { |
|||
case Size::U8: |
|||
return ImageFormat::R8_UINT; |
|||
case Size::S8: |
|||
return ImageFormat::R8_SINT; |
|||
case Size::U16: |
|||
return ImageFormat::R16_UINT; |
|||
case Size::S16: |
|||
return ImageFormat::R16_SINT; |
|||
case Size::B32: |
|||
return ImageFormat::R32_UINT; |
|||
case Size::B64: |
|||
return ImageFormat::R32G32_UINT; |
|||
case Size::B128: |
|||
return ImageFormat::R32G32B32A32_UINT; |
|||
} |
|||
throw NotImplementedException("Invalid size {}", size); |
|||
} |
|||
|
|||
int SizeInRegs(Size size) { |
|||
switch (size) { |
|||
case Size::U8: |
|||
case Size::S8: |
|||
case Size::U16: |
|||
case Size::S16: |
|||
case Size::B32: |
|||
return 1; |
|||
case Size::B64: |
|||
return 2; |
|||
case Size::B128: |
|||
return 4; |
|||
} |
|||
throw NotImplementedException("Invalid size {}", size); |
|||
} |
|||
|
|||
TextureType GetType(Type type) { |
|||
switch (type) { |
|||
case Type::_1D: |
|||
return TextureType::Color1D; |
|||
case Type::BUFFER_1D: |
|||
return TextureType::Buffer; |
|||
case Type::ARRAY_1D: |
|||
return TextureType::ColorArray1D; |
|||
case Type::_2D: |
|||
return TextureType::Color2D; |
|||
case Type::ARRAY_2D: |
|||
return TextureType::ColorArray2D; |
|||
case Type::_3D: |
|||
return TextureType::Color3D; |
|||
} |
|||
throw NotImplementedException("Invalid type {}", type); |
|||
} |
|||
|
|||
IR::Value MakeCoords(TranslatorVisitor& v, IR::Reg reg, Type type) { |
|||
const auto array{[&](int index) { |
|||
return v.ir.BitFieldExtract(v.X(reg + index), v.ir.Imm32(0), v.ir.Imm32(16)); |
|||
}}; |
|||
switch (type) { |
|||
case Type::_1D: |
|||
case Type::BUFFER_1D: |
|||
return v.X(reg); |
|||
case Type::ARRAY_1D: |
|||
return v.ir.CompositeConstruct(v.X(reg), array(1)); |
|||
case Type::_2D: |
|||
return v.ir.CompositeConstruct(v.X(reg), v.X(reg + 1)); |
|||
case Type::ARRAY_2D: |
|||
return v.ir.CompositeConstruct(v.X(reg), v.X(reg + 1), array(2)); |
|||
case Type::_3D: |
|||
return v.ir.CompositeConstruct(v.X(reg), v.X(reg + 1), v.X(reg + 3)); |
|||
} |
|||
throw NotImplementedException("Invalid type {}", type); |
|||
} |
|||
|
|||
unsigned SwizzleMask(u64 swizzle) { |
|||
if (swizzle == 0 || swizzle >= MASK.size()) { |
|||
throw NotImplementedException("Invalid swizzle {}", swizzle); |
|||
} |
|||
return MASK[swizzle]; |
|||
} |
|||
|
|||
IR::Value MakeColor(IR::IREmitter& ir, IR::Reg reg, int num_regs) { |
|||
std::array<IR::U32, 4> colors; |
|||
for (int i = 0; i < num_regs; ++i) { |
|||
colors[i] = ir.GetReg(reg + i); |
|||
} |
|||
for (int i = num_regs; i < 4; ++i) { |
|||
colors[i] = ir.Imm32(0); |
|||
} |
|||
return ir.CompositeConstruct(colors[0], colors[1], colors[2], colors[3]); |
|||
} |
|||
} // Anonymous namespace
|
|||
|
|||
void TranslatorVisitor::SULD(u64 insn) { |
|||
union { |
|||
u64 raw; |
|||
BitField<51, 1, u64> is_bound; |
|||
BitField<52, 1, u64> d; |
|||
BitField<23, 1, u64> ba; |
|||
BitField<33, 3, Type> type; |
|||
BitField<24, 2, LoadCache> cache; |
|||
BitField<20, 3, Size> size; // .D
|
|||
BitField<20, 4, u64> swizzle; // .P
|
|||
BitField<49, 2, Clamp> clamp; |
|||
BitField<0, 8, IR::Reg> dest_reg; |
|||
BitField<8, 8, IR::Reg> coord_reg; |
|||
BitField<36, 13, u64> bound_offset; // is_bound
|
|||
BitField<39, 8, IR::Reg> bindless_reg; // !is_bound
|
|||
} const suld{insn}; |
|||
|
|||
if (suld.clamp != Clamp::IGN) { |
|||
throw NotImplementedException("Clamp {}", suld.clamp.Value()); |
|||
} |
|||
if (suld.cache != LoadCache::Default) { |
|||
throw NotImplementedException("Cache {}", suld.cache.Value()); |
|||
} |
|||
const bool is_typed{suld.d != 0}; |
|||
if (is_typed && suld.ba != 0) { |
|||
throw NotImplementedException("BA"); |
|||
} |
|||
|
|||
const ImageFormat format{is_typed ? Format(suld.size) : ImageFormat::Typeless}; |
|||
const TextureType type{GetType(suld.type)}; |
|||
const IR::Value coords{MakeCoords(*this, suld.coord_reg, suld.type)}; |
|||
const IR::U32 handle{suld.is_bound != 0 ? ir.Imm32(static_cast<u32>(suld.bound_offset * 4)) |
|||
: X(suld.bindless_reg)}; |
|||
IR::TextureInstInfo info{}; |
|||
info.type.Assign(type); |
|||
info.image_format.Assign(format); |
|||
|
|||
const IR::Value result{ir.ImageRead(handle, coords, info)}; |
|||
IR::Reg dest_reg{suld.dest_reg}; |
|||
if (is_typed) { |
|||
const int num_regs{SizeInRegs(suld.size)}; |
|||
for (int i = 0; i < num_regs; ++i) { |
|||
X(dest_reg + i, IR::U32{ir.CompositeExtract(result, i)}); |
|||
} |
|||
} else { |
|||
const unsigned mask{SwizzleMask(suld.swizzle)}; |
|||
const int bits{std::popcount(mask)}; |
|||
if (!IR::IsAligned(dest_reg, bits == 3 ? 4 : bits)) { |
|||
throw NotImplementedException("Unaligned destination register"); |
|||
} |
|||
for (unsigned component = 0; component < 4; ++component) { |
|||
if (((mask >> component) & 1) == 0) { |
|||
continue; |
|||
} |
|||
X(dest_reg, IR::U32{ir.CompositeExtract(result, component)}); |
|||
++dest_reg; |
|||
} |
|||
} |
|||
} |
|||
|
|||
void TranslatorVisitor::SUST(u64 insn) { |
|||
union { |
|||
u64 raw; |
|||
BitField<51, 1, u64> is_bound; |
|||
BitField<52, 1, u64> d; |
|||
BitField<23, 1, u64> ba; |
|||
BitField<33, 3, Type> type; |
|||
BitField<24, 2, StoreCache> cache; |
|||
BitField<20, 3, Size> size; // .D
|
|||
BitField<20, 4, u64> swizzle; // .P
|
|||
BitField<49, 2, Clamp> clamp; |
|||
BitField<0, 8, IR::Reg> data_reg; |
|||
BitField<8, 8, IR::Reg> coord_reg; |
|||
BitField<36, 13, u64> bound_offset; // is_bound
|
|||
BitField<39, 8, IR::Reg> bindless_reg; // !is_bound
|
|||
} const sust{insn}; |
|||
|
|||
if (sust.clamp != Clamp::IGN) { |
|||
throw NotImplementedException("Clamp {}", sust.clamp.Value()); |
|||
} |
|||
if (sust.cache != StoreCache::Default) { |
|||
throw NotImplementedException("Cache {}", sust.cache.Value()); |
|||
} |
|||
const bool is_typed{sust.d != 0}; |
|||
if (is_typed && sust.ba != 0) { |
|||
throw NotImplementedException("BA"); |
|||
} |
|||
const ImageFormat format{is_typed ? Format(sust.size) : ImageFormat::Typeless}; |
|||
const TextureType type{GetType(sust.type)}; |
|||
const IR::Value coords{MakeCoords(*this, sust.coord_reg, sust.type)}; |
|||
const IR::U32 handle{sust.is_bound != 0 ? ir.Imm32(static_cast<u32>(sust.bound_offset * 4)) |
|||
: X(sust.bindless_reg)}; |
|||
IR::TextureInstInfo info{}; |
|||
info.type.Assign(type); |
|||
info.image_format.Assign(format); |
|||
|
|||
IR::Value color; |
|||
if (is_typed) { |
|||
color = MakeColor(ir, sust.data_reg, SizeInRegs(sust.size)); |
|||
} else { |
|||
const unsigned mask{SwizzleMask(sust.swizzle)}; |
|||
if (mask != 0xf) { |
|||
throw NotImplementedException("Non-full mask"); |
|||
} |
|||
color = MakeColor(ir, sust.data_reg, 4); |
|||
} |
|||
ir.ImageWrite(handle, coords, color, info); |
|||
} |
|||
|
|||
} // namespace Shader::Maxwell
|
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue