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

View file

@ -112,8 +112,13 @@ public:
void enableSkybox(bool enable = true); void enableSkybox(bool enable = true);
bool isSkyboxEnabled() const; bool isSkyboxEnabled() const;
// Push user Drawcall info // Drawcall Uniform value
void setDrawcallInfo(uint16 user); // 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 // Drawcalls
void draw(Primitive primitiveType, uint32 numVertices, uint32 startVertex = 0); void draw(Primitive primitiveType, uint32 numVertices, uint32 startVertex = 0);
@ -503,7 +508,8 @@ public:
NamedBatchDataMap _namedData; NamedBatchDataMap _namedData;
uint16_t _drawcallUserInfo{ 0 }; uint16_t _drawcallUniform{ 0 };
uint16_t _drawcallUniformReset{ 0 };
glm::vec2 _projectionJitter{ 0.0f, 0.0f }; glm::vec2 _projectionJitter{ 0.0f, 0.0f };
bool _enableStereo{ true }; bool _enableStereo{ true };

View file

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

View file

@ -423,7 +423,7 @@ void ModelMeshPartPayload::render(RenderArgs* args) {
// IF deformed pass the mesh key // IF deformed pass the mesh key
auto drawcallInfo = (uint16_t) (((_isBlendShaped && args->_enableBlendshape) << 0) | ((_isSkinned && args->_enableSkinning) << 1)); auto drawcallInfo = (uint16_t) (((_isBlendShaped && args->_enableBlendshape) << 0) | ((_isSkinned && args->_enableSkinning) << 1));
if (drawcallInfo) { if (drawcallInfo) {
batch.setDrawcallInfo(drawcallInfo); batch.setDrawcallUniform(drawcallInfo);
} }
// apply material properties // 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 { class Blender : public QRunnable {
public: public:
@ -1632,9 +1663,6 @@ Blender::Blender(ModelPointer model, int blendNumber, const Geometry::WeakPointe
_blendshapeCoefficients(blendshapeCoefficients) { _blendshapeCoefficients(blendshapeCoefficients) {
} }
#define DEBUG_PACKED_BLENDSHAPE_OFFSET 1
void Blender::run() { void Blender::run() {
QVector<BlendshapeOffset> blendshapeOffsets; QVector<BlendshapeOffset> blendshapeOffsets;
if (_model && _model->isLoaded()) { if (_model && _model->isLoaded()) {
@ -1687,29 +1715,8 @@ void Blender::run() {
auto unpacked = unpackedBlendshapeOffsets.data() + range.begin(); auto unpacked = unpackedBlendshapeOffsets.data() + range.begin();
auto packed = meshBlendshapeOffsets + range.begin(); auto packed = meshBlendshapeOffsets + range.begin();
for (auto j = range.begin(); j < range.end(); j++) { for (auto j = range.begin(); j < range.end(); j++) {
packBlendshapeOffsetTo_Pos_F32_3xSN10_Nor_3xSN10_Tan_3xSN10((*packed).packedPosNorTan, (*unpacked));
#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
unpacked++; unpacked++;
packed++; packed++;
} }