Merge pull request #4854 from ReinUsesLisp/cube-array-shadow

shader: Partially implement texture cube array shadow
This commit is contained in:
bunnei 2020-11-05 16:25:00 -08:00 committed by GitHub
commit a111a9ae2c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 37 additions and 25 deletions

View file

@ -39,8 +39,8 @@ using Operation = const OperationNode&;
constexpr std::array INTERNAL_FLAG_NAMES = {"ZERO", "SIGN", "CARRY", "OVERFLOW"}; constexpr std::array INTERNAL_FLAG_NAMES = {"ZERO", "SIGN", "CARRY", "OVERFLOW"};
char Swizzle(std::size_t component) { char Swizzle(std::size_t component) {
ASSERT(component < 4); static constexpr std::string_view SWIZZLE{"xyzw"};
return component["xyzw"]; return SWIZZLE.at(component);
} }
constexpr bool IsGenericAttribute(Attribute::Index index) { constexpr bool IsGenericAttribute(Attribute::Index index) {
@ -224,7 +224,7 @@ private:
std::string Visit(const Node& node); std::string Visit(const Node& node);
std::pair<std::string, std::size_t> BuildCoords(Operation); std::tuple<std::string, std::string, std::size_t> BuildCoords(Operation);
std::string BuildAoffi(Operation); std::string BuildAoffi(Operation);
std::string GlobalMemoryPointer(const GmemNode& gmem); std::string GlobalMemoryPointer(const GmemNode& gmem);
void Exit(); void Exit();
@ -1416,12 +1416,12 @@ std::string ARBDecompiler::Visit(const Node& node) {
return {}; return {};
} }
std::pair<std::string, std::size_t> ARBDecompiler::BuildCoords(Operation operation) { std::tuple<std::string, std::string, std::size_t> ARBDecompiler::BuildCoords(Operation operation) {
const auto& meta = std::get<MetaTexture>(operation.GetMeta()); const auto& meta = std::get<MetaTexture>(operation.GetMeta());
UNIMPLEMENTED_IF(meta.sampler.is_indexed); UNIMPLEMENTED_IF(meta.sampler.is_indexed);
UNIMPLEMENTED_IF(meta.sampler.is_shadow && meta.sampler.is_array &&
meta.sampler.type == Tegra::Shader::TextureType::TextureCube);
const bool is_extended = meta.sampler.is_shadow && meta.sampler.is_array &&
meta.sampler.type == Tegra::Shader::TextureType::TextureCube;
const std::size_t count = operation.GetOperandsCount(); const std::size_t count = operation.GetOperandsCount();
std::string temporary = AllocVectorTemporary(); std::string temporary = AllocVectorTemporary();
std::size_t i = 0; std::size_t i = 0;
@ -1429,12 +1429,21 @@ std::pair<std::string, std::size_t> ARBDecompiler::BuildCoords(Operation operati
AddLine("MOV.F {}.{}, {};", temporary, Swizzle(i), Visit(operation[i])); AddLine("MOV.F {}.{}, {};", temporary, Swizzle(i), Visit(operation[i]));
} }
if (meta.sampler.is_array) { if (meta.sampler.is_array) {
AddLine("I2F.S {}.{}, {};", temporary, Swizzle(i++), Visit(meta.array)); AddLine("I2F.S {}.{}, {};", temporary, Swizzle(i), Visit(meta.array));
++i;
} }
if (meta.sampler.is_shadow) { if (meta.sampler.is_shadow) {
AddLine("MOV.F {}.{}, {};", temporary, Swizzle(i++), Visit(meta.depth_compare)); std::string compare = Visit(meta.depth_compare);
if (is_extended) {
ASSERT(i == 4);
std::string extra_coord = AllocVectorTemporary();
AddLine("MOV.F {}.x, {};", extra_coord, compare);
return {fmt::format("{}, {}", temporary, extra_coord), extra_coord, 0};
}
AddLine("MOV.F {}.{}, {};", temporary, Swizzle(i), compare);
++i;
} }
return {std::move(temporary), i}; return {temporary, temporary, i};
} }
std::string ARBDecompiler::BuildAoffi(Operation operation) { std::string ARBDecompiler::BuildAoffi(Operation operation) {
@ -1859,7 +1868,7 @@ std::string ARBDecompiler::LogicalAddCarry(Operation operation) {
std::string ARBDecompiler::Texture(Operation operation) { std::string ARBDecompiler::Texture(Operation operation) {
const auto& meta = std::get<MetaTexture>(operation.GetMeta()); const auto& meta = std::get<MetaTexture>(operation.GetMeta());
const u32 sampler_id = device.GetBaseBindings(stage).sampler + meta.sampler.index; const u32 sampler_id = device.GetBaseBindings(stage).sampler + meta.sampler.index;
const auto [temporary, swizzle] = BuildCoords(operation); const auto [coords, temporary, swizzle] = BuildCoords(operation);
std::string_view opcode = "TEX"; std::string_view opcode = "TEX";
std::string extra; std::string extra;
@ -1888,7 +1897,7 @@ std::string ARBDecompiler::Texture(Operation operation) {
} }
} }
AddLine("{}.F {}, {},{} texture[{}], {}{};", opcode, temporary, temporary, extra, sampler_id, AddLine("{}.F {}, {},{} texture[{}], {}{};", opcode, temporary, coords, extra, sampler_id,
TextureType(meta), BuildAoffi(operation)); TextureType(meta), BuildAoffi(operation));
AddLine("MOV.U {}.x, {}.{};", temporary, temporary, Swizzle(meta.element)); AddLine("MOV.U {}.x, {}.{};", temporary, temporary, Swizzle(meta.element));
return fmt::format("{}.x", temporary); return fmt::format("{}.x", temporary);
@ -1897,7 +1906,7 @@ std::string ARBDecompiler::Texture(Operation operation) {
std::string ARBDecompiler::TextureGather(Operation operation) { std::string ARBDecompiler::TextureGather(Operation operation) {
const auto& meta = std::get<MetaTexture>(operation.GetMeta()); const auto& meta = std::get<MetaTexture>(operation.GetMeta());
const u32 sampler_id = device.GetBaseBindings(stage).sampler + meta.sampler.index; const u32 sampler_id = device.GetBaseBindings(stage).sampler + meta.sampler.index;
const auto [temporary, swizzle] = BuildCoords(operation); const auto [coords, temporary, swizzle] = BuildCoords(operation);
std::string comp; std::string comp;
if (!meta.sampler.is_shadow) { if (!meta.sampler.is_shadow) {
@ -1907,7 +1916,7 @@ std::string ARBDecompiler::TextureGather(Operation operation) {
AddLine("TXG.F {}, {}, texture[{}]{}, {}{};", temporary, temporary, sampler_id, comp, AddLine("TXG.F {}, {}, texture[{}]{}, {}{};", temporary, temporary, sampler_id, comp,
TextureType(meta), BuildAoffi(operation)); TextureType(meta), BuildAoffi(operation));
AddLine("MOV.U {}.x, {}.{};", temporary, temporary, Swizzle(meta.element)); AddLine("MOV.U {}.x, {}.{};", temporary, coords, Swizzle(meta.element));
return fmt::format("{}.x", temporary); return fmt::format("{}.x", temporary);
} }
@ -1945,13 +1954,13 @@ std::string ARBDecompiler::TextureQueryLod(Operation operation) {
std::string ARBDecompiler::TexelFetch(Operation operation) { std::string ARBDecompiler::TexelFetch(Operation operation) {
const auto& meta = std::get<MetaTexture>(operation.GetMeta()); const auto& meta = std::get<MetaTexture>(operation.GetMeta());
const u32 sampler_id = device.GetBaseBindings(stage).sampler + meta.sampler.index; const u32 sampler_id = device.GetBaseBindings(stage).sampler + meta.sampler.index;
const auto [temporary, swizzle] = BuildCoords(operation); const auto [coords, temporary, swizzle] = BuildCoords(operation);
if (!meta.sampler.is_buffer) { if (!meta.sampler.is_buffer) {
ASSERT(swizzle < 4); ASSERT(swizzle < 4);
AddLine("MOV.F {}.w, {};", temporary, Visit(meta.lod)); AddLine("MOV.F {}.w, {};", temporary, Visit(meta.lod));
} }
AddLine("TXF.F {}, {}, texture[{}], {}{};", temporary, temporary, sampler_id, TextureType(meta), AddLine("TXF.F {}, {}, texture[{}], {}{};", temporary, coords, sampler_id, TextureType(meta),
BuildAoffi(operation)); BuildAoffi(operation));
AddLine("MOV.U {}.x, {}.{};", temporary, temporary, Swizzle(meta.element)); AddLine("MOV.U {}.x, {}.{};", temporary, temporary, Swizzle(meta.element));
return fmt::format("{}.x", temporary); return fmt::format("{}.x", temporary);
@ -1962,7 +1971,7 @@ std::string ARBDecompiler::TextureGradient(Operation operation) {
const u32 sampler_id = device.GetBaseBindings(stage).sampler + meta.sampler.index; const u32 sampler_id = device.GetBaseBindings(stage).sampler + meta.sampler.index;
const std::string ddx = AllocVectorTemporary(); const std::string ddx = AllocVectorTemporary();
const std::string ddy = AllocVectorTemporary(); const std::string ddy = AllocVectorTemporary();
const std::string coord = BuildCoords(operation).first; const std::string coord = std::get<1>(BuildCoords(operation));
const std::size_t num_components = meta.derivates.size() / 2; const std::size_t num_components = meta.derivates.size() / 2;
for (std::size_t index = 0; index < num_components; ++index) { for (std::size_t index = 0; index < num_components; ++index) {

View file

@ -2056,15 +2056,19 @@ private:
} }
Expression Texture(Operation operation) { Expression Texture(Operation operation) {
const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); const auto meta = std::get<MetaTexture>(operation.GetMeta());
ASSERT(meta); const bool separate_dc = meta.sampler.type == TextureType::TextureCube &&
meta.sampler.is_array && meta.sampler.is_shadow;
std::string expr = GenerateTexture( // TODO: Replace this with an array and make GenerateTexture use C++20 std::span
operation, "", {TextureOffset{}, TextureArgument{Type::Float, meta->bias}}); const std::vector<TextureIR> extras{
if (meta->sampler.is_shadow) { TextureOffset{},
expr = "vec4(" + expr + ')'; TextureArgument{Type::Float, meta.bias},
};
std::string expr = GenerateTexture(operation, "", extras, separate_dc);
if (meta.sampler.is_shadow) {
expr = fmt::format("vec4({})", expr);
} }
return {expr + GetSwizzle(meta->element), Type::Float}; return {expr + GetSwizzle(meta.element), Type::Float};
} }
Expression TextureLod(Operation operation) { Expression TextureLod(Operation operation) {

View file

@ -556,7 +556,6 @@ Node4 ShaderIR::GetTextureCode(Instruction instr, TextureType texture_type,
const bool is_shadow = depth_compare != nullptr; const bool is_shadow = depth_compare != nullptr;
const bool is_bindless = bindless_reg.has_value(); const bool is_bindless = bindless_reg.has_value();
UNIMPLEMENTED_IF(texture_type == TextureType::TextureCube && is_array && is_shadow);
ASSERT_MSG(texture_type != TextureType::Texture3D || !is_array || !is_shadow, ASSERT_MSG(texture_type != TextureType::Texture3D || !is_array || !is_shadow,
"Illegal texture type"); "Illegal texture type");