shader/texture: Allow 2D shadow arrays and simplify code

Shadow sampler 2D arrays are supported on OpenGL, so there's no reason
to forbid these. Enable textureLod usage on these.

Minor style changes.
This commit is contained in:
ReinUsesLisp 2020-02-15 02:33:16 -03:00
parent f552d553ba
commit 6910ade146
1 changed files with 28 additions and 43 deletions

View File

@ -522,52 +522,38 @@ Node4 ShaderIR::GetTextureCode(Instruction instr, TextureType texture_type,
Node array, Node depth_compare, u32 bias_offset, Node array, Node depth_compare, u32 bias_offset,
std::vector<Node> aoffi, std::vector<Node> aoffi,
std::optional<Tegra::Shader::Register> bindless_reg) { std::optional<Tegra::Shader::Register> bindless_reg) {
const auto is_array = static_cast<bool>(array); const bool is_array = array != nullptr;
const auto is_shadow = static_cast<bool>(depth_compare); 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_MSG((texture_type == TextureType::Texture3D && (is_array || is_shadow)) || UNIMPLEMENTED_IF(texture_type == TextureType::TextureCube && is_array && is_shadow);
(texture_type == TextureType::TextureCube && is_array && is_shadow), ASSERT_MSG(texture_type != TextureType::Texture3D || is_array || is_shadow,
"This method is not supported."); "Illegal texture type");
const SamplerInfo info{texture_type, is_array, is_shadow, false}; const SamplerInfo info{texture_type, is_array, is_shadow, false};
Node index_var{}; Node index_var;
const Sampler* sampler = is_bindless ? GetBindlessSampler(*bindless_reg, index_var, info) const Sampler* sampler = is_bindless ? GetBindlessSampler(*bindless_reg, index_var, info)
: GetSampler(instr.sampler, info); : GetSampler(instr.sampler, info);
Node4 values; if (!sampler) {
if (sampler == nullptr) { return {Immediate(0), Immediate(0), Immediate(0), Immediate(0)};
for (u32 element = 0; element < values.size(); ++element) {
values[element] = Immediate(0);
}
return values;
} }
const bool lod_needed = process_mode == TextureProcessMode::LZ || const bool lod_needed = process_mode == TextureProcessMode::LZ ||
process_mode == TextureProcessMode::LL || process_mode == TextureProcessMode::LL ||
process_mode == TextureProcessMode::LLA; process_mode == TextureProcessMode::LLA;
const OperationCode opcode = lod_needed ? OperationCode::TextureLod : OperationCode::Texture;
// LOD selection (either via bias or explicit textureLod) not supported in GL for
// sampler2DArrayShadow and samplerCubeArrayShadow.
const bool gl_lod_supported =
!((texture_type == Tegra::Shader::TextureType::Texture2D && is_array && is_shadow) ||
(texture_type == Tegra::Shader::TextureType::TextureCube && is_array && is_shadow));
const OperationCode read_method =
(lod_needed && gl_lod_supported) ? OperationCode::TextureLod : OperationCode::Texture;
UNIMPLEMENTED_IF(process_mode != TextureProcessMode::None && !gl_lod_supported);
Node bias; Node bias;
Node lod; Node lod;
if (process_mode != TextureProcessMode::None && gl_lod_supported) {
switch (process_mode) { switch (process_mode) {
case TextureProcessMode::None:
break;
case TextureProcessMode::LZ: case TextureProcessMode::LZ:
lod = Immediate(0.0f); lod = Immediate(0.0f);
break; break;
case TextureProcessMode::LB: case TextureProcessMode::LB:
// If present, lod or bias are always stored in the register // If present, lod or bias are always stored in the register indexed by the gpr20 field with
// indexed by the gpr20 field with an offset depending on the // an offset depending on the usage of the other registers.
// usage of the other registers
bias = GetRegister(instr.gpr20.Value() + bias_offset); bias = GetRegister(instr.gpr20.Value() + bias_offset);
break; break;
case TextureProcessMode::LL: case TextureProcessMode::LL:
@ -577,13 +563,12 @@ Node4 ShaderIR::GetTextureCode(Instruction instr, TextureType texture_type,
UNIMPLEMENTED_MSG("Unimplemented process mode={}", static_cast<u32>(process_mode)); UNIMPLEMENTED_MSG("Unimplemented process mode={}", static_cast<u32>(process_mode));
break; break;
} }
}
Node4 values;
for (u32 element = 0; element < values.size(); ++element) { for (u32 element = 0; element < values.size(); ++element) {
auto copy_coords = coords;
MetaTexture meta{*sampler, array, depth_compare, aoffi, {}, {}, bias, MetaTexture meta{*sampler, array, depth_compare, aoffi, {}, {}, bias,
lod, {}, element, index_var}; lod, {}, element, index_var};
values[element] = Operation(read_method, meta, std::move(copy_coords)); values[element] = Operation(opcode, meta, coords);
} }
return values; return values;