[dxbc] Simplified f16tof32 implementation

This commit is contained in:
Philip Rebohle 2018-01-10 09:16:42 +01:00
parent da867d4bca
commit bde8ba9400
1 changed files with 19 additions and 32 deletions

View File

@ -1957,9 +1957,8 @@ namespace dxvk {
// The conversion instructions do not map very well to the // The conversion instructions do not map very well to the
// SPIR-V pack instructions, which operate on 2D vectors. // SPIR-V pack instructions, which operate on 2D vectors.
std::array<uint32_t, 4> scalarIds = {{ 0, 0, 0, 0 }}; std::array<uint32_t, 4> scalarIds = {{ 0, 0, 0, 0 }};
std::array<uint32_t, 4> swizzleIds = {{ 0, 0, 0, 0 }};
uint32_t componentIndex = 0; const uint32_t componentCount = src.type.ccount;
// These types are used in both pack and unpack operations // These types are used in both pack and unpack operations
const uint32_t t_u32 = getVectorTypeId({ DxbcScalarType::Uint32, 1 }); const uint32_t t_u32 = getVectorTypeId({ DxbcScalarType::Uint32, 1 });
@ -1969,46 +1968,34 @@ namespace dxvk {
// Constant zero-bit pattern, used for packing // Constant zero-bit pattern, used for packing
const uint32_t zerof32 = isPack ? m_module.constf32(0.0f) : 0; const uint32_t zerof32 = isPack ? m_module.constf32(0.0f) : 0;
for (uint32_t i = 0; i < 4; i++) { for (uint32_t i = 0; i < componentCount; i++) {
if (ins.dst[0].mask[i]) { const DxbcRegisterValue componentValue
const uint32_t swizzleIndex = ins.src[0].swizzle[i]; = emitRegisterExtract(src, DxbcRegMask::select(i));
if (isPack) { // f32tof16
const std::array<uint32_t, 2> packIds =
{{ componentValue.id, zerof32 }};
// When extracting components from the source register, we must scalarIds[i] = m_module.opPackHalf2x16(t_u32,
// take into account that it it ozzled and masked. m_module.opCompositeConstruct(t_f32v2, packIds.size(), packIds.data()));
if (scalarIds[swizzleIndex] == 0) { } else { // f16tof32
const DxbcRegisterValue componentValue const uint32_t zeroIndex = 0;
= emitRegisterExtract(src, DxbcRegMask::select(componentIndex));
if (isPack) { // f32tof16
const std::array<uint32_t, 2> packIds =
{{ componentValue.id, zerof32 }};
scalarIds[swizzleIndex] = m_module.opPackHalf2x16(t_u32,
m_module.opCompositeConstruct(t_f32v2, packIds.size(), packIds.data()));
} else { // f16tof32
const uint32_t zeroIndex = 0;
scalarIds[swizzleIndex] = m_module.opCompositeExtract(t_f32,
m_module.opUnpackHalf2x16(t_f32v2, componentValue.id),
1, &zeroIndex);
}
}
// Apply write mask and source swizzle at the same time scalarIds[i] = m_module.opCompositeExtract(t_f32,
swizzleIds[componentIndex++] = scalarIds[swizzleIndex]; m_module.opUnpackHalf2x16(t_f32v2, componentValue.id),
1, &zeroIndex);
} }
} }
// Store result in the destination register // Store result in the destination register
DxbcRegisterValue result; DxbcRegisterValue result;
result.type.ctype = ins.dst[0].dataType; result.type.ctype = ins.dst[0].dataType;
result.type.ccount = componentIndex; result.type.ccount = componentCount;
result.id = componentIndex > 1 result.id = componentCount > 1
? m_module.opCompositeConstruct( ? m_module.opCompositeConstruct(
getVectorTypeId(result.type), getVectorTypeId(result.type),
componentIndex, swizzleIds.data()) componentCount, scalarIds.data())
: swizzleIds[0]; : scalarIds[0];
emitRegisterStore(ins.dst[0], result); emitRegisterStore(ins.dst[0], result);
} }