Move UvStreamTangentBitmask to new files.

This commit is contained in:
jiaweig
2021-05-25 18:47:04 -07:00
parent 3dc76d76c0
commit f64bd999e0
6 changed files with 147 additions and 103 deletions
@@ -14,6 +14,7 @@
#include <Atom/RPI.Public/Buffer/Buffer.h>
#include <Atom/RPI.Public/Material/Material.h>
#include <Atom/RPI.Public/Model/UvStreamTangentBitmask.h>
#include <Atom/RHI/DrawItem.h>
@@ -34,8 +35,6 @@ namespace AZ
//! A map matches the UV shader inputs of this material to the custom UV names from the model.
using MaterialModelUvOverrideMap = AZStd::unordered_map<RHI::ShaderSemantic, AZ::Name>;
class UvStreamTangentBitmask;
class ModelLod final
: public Data::InstanceData
{
@@ -175,54 +174,5 @@ namespace AZ
AZStd::mutex m_callbackMutex;
};
//! An encoded bitmask for tangent used by UV streams.
//! It contains the information about number of UV streams and which tangent/bitangent is used by each UV stream.
//! See m_mask for more details.
//! The mask will be passed through per draw SRG.
class UvStreamTangentBitmask
{
public:
//! Get the full mask including number of UVs and tangent/bitangent assignment to each UV.
uint32_t GetFullTangentBitmask() const;
//! Get number of UVs that have tangent/bitangent assigned.
uint32_t GetUvStreamCount() const;
//! Get tangent/bitangent assignment to the specified UV in the material.
//! @param uvIndex the index of the UV from the material, in default order as in the shader code.
uint32_t GetTangentAtUv(uint32_t uvIndex) const;
//! Apply the tangent to the next UV, whose index is the same as GetUvStreamCount.
//! @param tangent the tangent/bitangent to be assigned. Ranged in [0, 0xF)
//! It comes from the model in order, e.g. 0 means the first available tangent stream from the model.
//! Specially, value 0xF(=UnassignedTangent) means generated tangent/bitangent will be used in shader.
//! If ranged out of definition, unassigned tangent will be applied.
void ApplyTangent(uint32_t tangent);
//! Reset the bitmask to clear state.
void Reset();
//! The bit mask indicating generated tangent/bitangent will be used.
static constexpr uint32_t UnassignedTangent = 0b1111u;
//! The variable name defined in the SRG shader code.
static constexpr const char* SrgName = "m_uvStreamTangentBitmask";
private:
//! Mask composition:
//! The number of UV slots (highest 4 bits) + tangent mask (4 bits each) * 7
//! e.g. 0x200000F0 means there are 2 UV streams,
//! the first UV stream uses 0th tangent stream (0x0),
//! the second UV stream uses the generated tangent stream (0xF).
uint32_t m_mask = 0;
//! Bit size in the mask composition.
static constexpr uint32_t BitsPerTangent = 4;
static constexpr uint32_t BitsForUvIndex = 4;
public:
//! Max UV slots available in this bit mask.
static constexpr uint32_t MaxUvSlots = (sizeof(m_mask) * CHAR_BIT - BitsForUvIndex) / BitsPerTangent;
};
} // namespace RPI
} // namespace AZ
@@ -0,0 +1,72 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <limits.h>
#include <AzCore/base.h>
namespace AZ
{
namespace RPI
{
//! An encoded bitmask for tangent used by UV streams.
//! It contains the information about number of UV streams and which tangent/bitangent is used by each UV stream.
//! See m_mask for more details.
//! The mask will be passed through per draw SRG.
class UvStreamTangentBitmask
{
public:
//! Get the full mask including number of UVs and tangent/bitangent assignment to each UV.
uint32_t GetFullTangentBitmask() const;
//! Get number of UVs that have tangent/bitangent assigned.
uint32_t GetUvStreamCount() const;
//! Get tangent/bitangent assignment to the specified UV in the material.
//! @param uvIndex the index of the UV from the material, in default order as in the shader code.
uint32_t GetTangentAtUv(uint32_t uvIndex) const;
//! Apply the tangent to the next UV, whose index is the same as GetUvStreamCount.
//! @param tangent the tangent/bitangent to be assigned. Ranged in [0, 0xF)
//! It comes from the model in order, e.g. 0 means the first available tangent stream from the model.
//! Specially, value 0xF(=UnassignedTangent) means generated tangent/bitangent will be used in shader.
//! If ranged out of definition, unassigned tangent will be applied.
void ApplyTangent(uint32_t tangent);
//! Reset the bitmask to clear state.
void Reset();
//! The bit mask indicating generated tangent/bitangent will be used.
static constexpr uint32_t UnassignedTangent = 0b1111u;
//! The variable name defined in the SRG shader code.
static constexpr const char* SrgName = "m_uvStreamTangentBitmask";
private:
//! Mask composition:
//! The number of UV slots (highest 4 bits) + tangent mask (4 bits each) * 7
//! e.g. 0x200000F0 means there are 2 UV streams,
//! the first UV stream uses 0th tangent stream (0x0),
//! the second UV stream uses the generated tangent stream (0xF).
uint32_t m_mask = 0;
//! Bit size in the mask composition.
static constexpr uint32_t BitsPerTangent = 4;
static constexpr uint32_t BitsForUvIndex = 4;
public:
//! Max UV slots available in this bit mask.
static constexpr uint32_t MaxUvSlots = (sizeof(m_mask) * CHAR_BIT - BitsForUvIndex) / BitsPerTangent;
};
}
}
@@ -439,56 +439,5 @@ namespace AZ
m_buffers.emplace_back(buffer);
return static_cast<uint32_t>(m_buffers.size() - 1);
}
uint32_t UvStreamTangentBitmask::GetFullTangentBitmask() const
{
return m_mask;
}
uint32_t UvStreamTangentBitmask::GetUvStreamCount() const
{
return m_mask >> (sizeof(m_mask) * CHAR_BIT - BitsForUvIndex);
}
uint32_t UvStreamTangentBitmask::GetTangentAtUv(uint32_t uvIndex) const
{
return (m_mask >> (BitsPerTangent * uvIndex)) & 0b1111u;
}
void UvStreamTangentBitmask::ApplyTangent(uint32_t tangentIndex)
{
uint32_t currentSlot = GetUvStreamCount();
if (currentSlot >= MaxUvSlots)
{
AZ_Error("UV Stream", false, "Reaching the max of avaiblable stream slots.");
return;
}
if (tangentIndex > UnassignedTangent)
{
AZ_Warning(
"UV Stream", false,
"Tangent index must use %d bits as defined in UvStreamTangentIndex::m_flag. Unassigned index will be applied.",
BitsPerTangent);
tangentIndex = UnassignedTangent;
}
uint32_t clearMask = 0b1111u << (BitsPerTangent * currentSlot);
clearMask = ~clearMask;
// Clear the writing bits in case
m_mask &= clearMask;
// Write the bits to the slot
m_mask |= (tangentIndex << (BitsPerTangent * currentSlot));
// Increase the index
m_mask += (1u << (sizeof(m_mask) * CHAR_BIT - BitsForUvIndex));
}
void UvStreamTangentBitmask::Reset()
{
m_mask = 0;
}
} // namespace RPI
} // namespace AZ
@@ -0,0 +1,71 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <Atom/RPI.Public/Model/UvStreamTangentBitmask.h>
#include <AzCore/Debug/Trace.h>
namespace AZ
{
namespace RPI
{
uint32_t UvStreamTangentBitmask::GetFullTangentBitmask() const
{
return m_mask;
}
uint32_t UvStreamTangentBitmask::GetUvStreamCount() const
{
return m_mask >> (sizeof(m_mask) * CHAR_BIT - BitsForUvIndex);
}
uint32_t UvStreamTangentBitmask::GetTangentAtUv(uint32_t uvIndex) const
{
return (m_mask >> (BitsPerTangent * uvIndex)) & 0b1111u;
}
void UvStreamTangentBitmask::ApplyTangent(uint32_t tangentIndex)
{
uint32_t currentSlot = GetUvStreamCount();
if (currentSlot >= MaxUvSlots)
{
AZ_Error("UV Stream", false, "Reaching the max of avaiblable stream slots.");
return;
}
if (tangentIndex > UnassignedTangent)
{
AZ_Warning(
"UV Stream", false,
"Tangent index must use %d bits as defined in UvStreamTangentIndex::m_flag. Unassigned index will be applied.",
BitsPerTangent);
tangentIndex = UnassignedTangent;
}
uint32_t clearMask = 0b1111u << (BitsPerTangent * currentSlot);
clearMask = ~clearMask;
// Clear the writing bits in case
m_mask &= clearMask;
// Write the bits to the slot
m_mask |= (tangentIndex << (BitsPerTangent * currentSlot));
// Increase the index
m_mask += (1u << (sizeof(m_mask) * CHAR_BIT - BitsForUvIndex));
}
void UvStreamTangentBitmask::Reset()
{
m_mask = 0;
}
}
}
@@ -17,7 +17,7 @@
#include <Atom/RPI.Reflect/Model/ModelKdTree.h>
#include <Atom/RPI.Reflect/Model/ModelLodAsset.h>
#include <Atom/RPI.Reflect/ResourcePoolAssetCreator.h>
#include <Atom/RPI.Public/Model/ModelLod.h>
#include <Atom/RPI.Public/Model/UvStreamTangentBitmask.h>
#include <AzCore/std/limits.h>
#include <AzCore/Component/Entity.h>
@@ -57,6 +57,7 @@ set(FILES
Include/Atom/RPI.Public/Model/ModelLod.h
Include/Atom/RPI.Public/Model/ModelLodUtils.h
Include/Atom/RPI.Public/Model/ModelSystem.h
Include/Atom/RPI.Public/Model/UvStreamTangentBitmask.h
Include/Atom/RPI.Public/Pass/AttachmentReadback.h
Include/Atom/RPI.Public/Pass/ComputePass.h
Include/Atom/RPI.Public/Pass/CopyPass.h
@@ -136,6 +137,7 @@ set(FILES
Source/RPI.Public/Model/ModelLod.cpp
Source/RPI.Public/Model/ModelLodUtils.cpp
Source/RPI.Public/Model/ModelSystem.cpp
Source/RPI.Public/Model/UvStreamTangentBitmask.cpp
Source/RPI.Public/Pass/AttachmentReadback.cpp
Source/RPI.Public/Pass/ComputePass.cpp
Source/RPI.Public/Pass/CopyPass.cpp