|
|
|
@ -836,24 +836,81 @@ private: |
|
|
|
: Emit(OpCompositeConstruct(t_float_lut.at(coords.size() - 1), coords)); |
|
|
|
} |
|
|
|
|
|
|
|
Id GetTextureElement(Operation operation, Id sample_value) { |
|
|
|
const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); |
|
|
|
ASSERT(meta); |
|
|
|
return Emit(OpCompositeExtract(t_float, sample_value, meta->element)); |
|
|
|
} |
|
|
|
|
|
|
|
Id Texture(Operation operation) { |
|
|
|
UNIMPLEMENTED(); |
|
|
|
return {}; |
|
|
|
const Id texture = Emit(OpImageSampleImplicitLod(t_float4, GetTextureSampler(operation), |
|
|
|
GetTextureCoordinates(operation))); |
|
|
|
return GetTextureElement(operation, texture); |
|
|
|
} |
|
|
|
|
|
|
|
Id TextureLod(Operation operation) { |
|
|
|
UNIMPLEMENTED(); |
|
|
|
return {}; |
|
|
|
const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); |
|
|
|
const Id texture = Emit(OpImageSampleExplicitLod( |
|
|
|
t_float4, GetTextureSampler(operation), GetTextureCoordinates(operation), |
|
|
|
spv::ImageOperandsMask::Lod, Visit(meta->lod))); |
|
|
|
return GetTextureElement(operation, texture); |
|
|
|
} |
|
|
|
|
|
|
|
Id TextureGather(Operation operation) { |
|
|
|
UNIMPLEMENTED(); |
|
|
|
return {}; |
|
|
|
const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); |
|
|
|
const auto coords = GetTextureCoordinates(operation); |
|
|
|
|
|
|
|
Id texture; |
|
|
|
if (meta->sampler.IsShadow()) { |
|
|
|
texture = Emit(OpImageDrefGather(t_float4, GetTextureSampler(operation), coords, |
|
|
|
Visit(meta->component))); |
|
|
|
} else { |
|
|
|
u32 component_value = 0; |
|
|
|
if (meta->component) { |
|
|
|
const auto component = std::get_if<ImmediateNode>(meta->component); |
|
|
|
ASSERT_MSG(component, "Component is not an immediate value"); |
|
|
|
component_value = component->GetValue(); |
|
|
|
} |
|
|
|
texture = Emit(OpImageGather(t_float4, GetTextureSampler(operation), coords, |
|
|
|
Constant(t_uint, component_value))); |
|
|
|
} |
|
|
|
|
|
|
|
return GetTextureElement(operation, texture); |
|
|
|
} |
|
|
|
|
|
|
|
Id TextureQueryDimensions(Operation operation) { |
|
|
|
UNIMPLEMENTED(); |
|
|
|
return {}; |
|
|
|
const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); |
|
|
|
const auto image_id = GetTextureImage(operation); |
|
|
|
AddCapability(spv::Capability::ImageQuery); |
|
|
|
|
|
|
|
if (meta->element == 3) { |
|
|
|
return BitcastTo<Type::Float>(Emit(OpImageQueryLevels(t_int, image_id))); |
|
|
|
} |
|
|
|
|
|
|
|
const Id lod = VisitOperand<Type::Uint>(operation, 0); |
|
|
|
const std::size_t coords_count = [&]() { |
|
|
|
switch (const auto type = meta->sampler.GetType(); type) { |
|
|
|
case Tegra::Shader::TextureType::Texture1D: |
|
|
|
return 1; |
|
|
|
case Tegra::Shader::TextureType::Texture2D: |
|
|
|
case Tegra::Shader::TextureType::TextureCube: |
|
|
|
return 2; |
|
|
|
case Tegra::Shader::TextureType::Texture3D: |
|
|
|
return 3; |
|
|
|
default: |
|
|
|
UNREACHABLE_MSG("Invalid texture type={}", static_cast<u32>(type)); |
|
|
|
return 2; |
|
|
|
} |
|
|
|
}(); |
|
|
|
|
|
|
|
if (meta->element >= coords_count) { |
|
|
|
return Constant(t_float, 0.0f); |
|
|
|
} |
|
|
|
|
|
|
|
const std::array<Id, 3> types = {t_int, t_int2, t_int3}; |
|
|
|
const Id sizes = Emit(OpImageQuerySizeLod(types.at(coords_count - 1), image_id, lod)); |
|
|
|
const Id size = Emit(OpCompositeExtract(t_int, sizes, meta->element)); |
|
|
|
return BitcastTo<Type::Float>(size); |
|
|
|
} |
|
|
|
|
|
|
|
Id TextureQueryLod(Operation operation) { |
|
|
|
|