Unify the the packing of the blendshape offset for simplicity and settle on the name DrawcallUniform

This commit is contained in:
sam gateau 2018-10-02 11:18:20 -07:00
parent c95c736b1f
commit ff24a99032
5 changed files with 72 additions and 68 deletions

View file

@ -98,7 +98,8 @@ void Batch::clear() {
_name = nullptr;
_invalidModel = true;
_currentModel = Transform();
_drawcallUserInfo = 0;
_drawcallUniform = 0;
_drawcallUniformReset = 0;
_projectionJitter = glm::vec2(0.0f);
_enableStereo = true;
_enableSkybox = false;
@ -113,8 +114,11 @@ size_t Batch::cacheData(size_t size, const void* data) {
return offset;
}
void Batch::setDrawcallInfo(uint16_t user) {
_drawcallUserInfo = user;
void Batch::setDrawcallUniform(uint16_t uniform) {
_drawcallUniform = uniform;
}
void Batch::setDrawcallUniformReset(uint16_t uniformReset) {
_drawcallUniformReset = uniformReset;
}
void Batch::draw(Primitive primitiveType, uint32 numVertices, uint32 startVertex) {
@ -550,8 +554,8 @@ void Batch::captureDrawCallInfoImpl() {
}
auto& drawCallInfos = getDrawCallInfoBuffer();
drawCallInfos.emplace_back((uint16)_objects.size() - 1, _drawcallUserInfo);
_drawcallUserInfo = 0;
drawCallInfos.emplace_back((uint16)_objects.size() - 1, _drawcallUniform);
_drawcallUniform = _drawcallUniformReset;
}
void Batch::captureDrawCallInfo() {

View file

@ -112,8 +112,13 @@ public:
void enableSkybox(bool enable = true);
bool isSkyboxEnabled() const;
// Push user Drawcall info
void setDrawcallInfo(uint16 user);
// Drawcall Uniform value
// One 16bit word uniform value is available during the drawcall
// its value must be set before each drawcall
void setDrawcallUniform(uint16 uniform);
// It is reset to the reset value between each drawcalls
// The reset value is 0 by default and can be changed as a batch state with this call
void setDrawcallUniformReset(uint16 resetUniform);
// Drawcalls
void draw(Primitive primitiveType, uint32 numVertices, uint32 startVertex = 0);
@ -503,7 +508,8 @@ public:
NamedBatchDataMap _namedData;
uint16_t _drawcallUserInfo{ 0 };
uint16_t _drawcallUniform{ 0 };
uint16_t _drawcallUniformReset{ 0 };
glm::vec2 _projectionJitter{ 0.0f, 0.0f };
bool _enableStereo{ true };

View file

@ -10,9 +10,19 @@
<@func declareBlendshape(USE_NORMAL, USE_TANGENT)@>
struct PackedBlendshapeOffset {
uvec4 packedPosNorTan;
#if defined(GPU_GL410)
layout(binding=0) uniform samplerBuffer blendshapeOffsetsBuffer;
uvec4 getPackedBlendshapeOffset(int i) {
return floatBitsToUint(texelFetch(blendshapeOffsetsBuffer, i));
}
#else
layout(std140, binding=0) buffer blendshapeOffsetsBuffer {
uvec4 _packedBlendshapeOffsets[];
};
uvec4 getPackedBlendshapeOffset(int i) {
return _packedBlendshapeOffsets[i];
}
#endif
struct BlendshapeOffset {
vec3 position;
@ -24,9 +34,8 @@ struct BlendshapeOffset {
<@endif@>
};
const float oneOver511 = 1.0 / 511.0;
vec3 unpackSnorm3x10_1x2(int packedValue) {
vec3 unpackSnorm3x10_1x2(int packedValue) {
const float oneOver511 = 1.0 / 511.0;
return vec3(
clamp( float( bitfieldExtract(packedValue, 0, 10)) * oneOver511, -1.0, 1.0),
clamp( float( bitfieldExtract(packedValue, 10, 10)) * oneOver511, -1.0, 1.0),
@ -34,43 +43,21 @@ vec3 unpackSnorm3x10_1x2(int packedValue) {
);
}
#if defined(GPU_GL410)
layout(binding=0) uniform samplerBuffer blendshapeOffsetsBuffer;
BlendshapeOffset getBlendshapeOffset(int i) {
uvec4 elem_packed = floatBitsToUint(texelFetch(blendshapeOffsetsBuffer, i));
BlendshapeOffset unpackBlendshapeOffset(uvec4 packedValue) {
BlendshapeOffset unpacked;
unpacked.position = unpackSnorm3x10_1x2(int(elem_packed.y)).xyz * uintBitsToFloat(elem_packed.x);
unpacked.position = unpackSnorm3x10_1x2(int(packedValue.y)).xyz * uintBitsToFloat(packedValue.x);
<@if USE_NORMAL@>
unpacked.normal = unpackSnorm3x10_1x2(int(elem_packed.z)).xyz;
unpacked.normal = unpackSnorm3x10_1x2(int(packedValue.z)).xyz;
<@endif@>
<@if USE_TANGENT@>
unpacked.tangent = unpackSnorm3x10_1x2(int(elem_packed.w)).xyz;
unpacked.tangent = unpackSnorm3x10_1x2(int(packedValue.w)).xyz;
<@endif@>
return unpacked;
}
#else
layout(std140, binding=0) buffer blendshapeOffsetsBuffer {
uvec4 _packedBlendshapeOffsets[];
};
BlendshapeOffset getBlendshapeOffset(int i) {
uvec4 elem_packed = _packedBlendshapeOffsets[i];
BlendshapeOffset unpacked;
unpacked.position = vec3(unpackHalf2x16((elem_packed.x)), unpackHalf2x16(uint(elem_packed.y)).x);
<@if USE_NORMAL@>
unpacked.normal = unpackSnorm3x10_1x2(int(elem_packed.z)).xyz;
<@endif@>
<@if USE_TANGENT@>
unpacked.tangent = unpackSnorm3x10_1x2(int(elem_packed.w)).xyz;
<@endif@>
return unpacked;
return unpackBlendshapeOffset(getPackedBlendshapeOffset(i));
}
#endif
void evalBlendshape(int i, vec4 inPosition, out vec4 position
<@if USE_NORMAL@>

View file

@ -423,7 +423,7 @@ void ModelMeshPartPayload::render(RenderArgs* args) {
// IF deformed pass the mesh key
auto drawcallInfo = (uint16_t) (((_isBlendShaped && args->_enableBlendshape) << 0) | ((_isSkinned && args->_enableSkinning) << 1));
if (drawcallInfo) {
batch.setDrawcallInfo(drawcallInfo);
batch.setDrawcallUniform(drawcallInfo);
}
// apply material properties

View file

@ -1610,6 +1610,37 @@ public:
}
};
using packBlendshapeOffsetTo = void(glm::uvec4& packed, const BlendshapeOffsetUnpacked& unpacked);
void packBlendshapeOffsetTo_Pos_F32_3xSN10_Nor_3xSN10_Tan_3xSN10(glm::uvec4& packed, const BlendshapeOffsetUnpacked& unpacked) {
float len = glm::compMax(glm::abs(unpacked.positionOffsetAndSpare));
glm::vec3 normalizedPos(unpacked.positionOffsetAndSpare);
if (len > 1.0f) {
normalizedPos /= len;
}
else {
len = 1.0f;
}
packed = glm::uvec4(
glm::floatBitsToUint(len),
glm::packSnorm3x10_1x2(glm::vec4(normalizedPos, 0.0f)),
glm::packSnorm3x10_1x2(glm::vec4(unpacked.normalOffsetAndSpare, 0.0f)),
glm::packSnorm3x10_1x2(glm::vec4(unpacked.tangentOffsetAndSpare, 0.0f))
);
}
void packBlendshapeOffsetTo_Pos_3xF16_Nor_3xSN10_Tan_3xSN10(glm::uvec4& packed, const BlendshapeOffsetUnpacked& unpacked) {
packed = glm::uvec4(
glm::packHalf2x16(glm::vec2(unpacked.positionOffsetAndSpare)),
glm::packHalf2x16(glm::vec2(unpacked.positionOffsetAndSpare.z, 0.0f)),
glm::packSnorm3x10_1x2(glm::vec4(unpacked.normalOffsetAndSpare, 0.0f)),
glm::packSnorm3x10_1x2(glm::vec4(unpacked.tangentOffsetAndSpare, 0.0f))
);
}
class Blender : public QRunnable {
public:
@ -1632,9 +1663,6 @@ Blender::Blender(ModelPointer model, int blendNumber, const Geometry::WeakPointe
_blendshapeCoefficients(blendshapeCoefficients) {
}
#define DEBUG_PACKED_BLENDSHAPE_OFFSET 1
void Blender::run() {
QVector<BlendshapeOffset> blendshapeOffsets;
if (_model && _model->isLoaded()) {
@ -1687,29 +1715,8 @@ void Blender::run() {
auto unpacked = unpackedBlendshapeOffsets.data() + range.begin();
auto packed = meshBlendshapeOffsets + range.begin();
for (auto j = range.begin(); j < range.end(); j++) {
#ifdef Q_OS_MAC
float len = glm::compMax(glm::abs(unpacked->positionOffsetAndSpare));
if (len > 1.0f) {
unpacked->positionOffsetAndSpare /= len;
} else {
len = 1.0f;
}
(*packed).packedPosNorTan = glm::uvec4(
glm::floatBitsToUint(len),
glm::packSnorm3x10_1x2(glm::vec4(unpacked->positionOffsetAndSpare, 0.0f)),
glm::packSnorm3x10_1x2(glm::vec4(unpacked->normalOffsetAndSpare, 0.0f)),
glm::packSnorm3x10_1x2(glm::vec4(unpacked->tangentOffsetAndSpare, 0.0f))
);
#else
(*packed).packedPosNorTan = glm::uvec4(
glm::packHalf2x16(glm::vec2(unpacked->positionOffsetAndSpare)),
glm::packHalf2x16(glm::vec2(unpacked->positionOffsetAndSpare.z, 0.0f)),
glm::packSnorm3x10_1x2(glm::vec4(unpacked->normalOffsetAndSpare, 0.0f)),
glm::packSnorm3x10_1x2(glm::vec4(unpacked->tangentOffsetAndSpare, 0.0f))
);
#endif
packBlendshapeOffsetTo_Pos_F32_3xSN10_Nor_3xSN10_Tan_3xSN10((*packed).packedPosNorTan, (*unpacked));
unpacked++;
packed++;
}