diff --git a/libraries/gpu/src/gpu/Batch.cpp b/libraries/gpu/src/gpu/Batch.cpp index 26222a2cc0..018ca8f02f 100644 --- a/libraries/gpu/src/gpu/Batch.cpp +++ b/libraries/gpu/src/gpu/Batch.cpp @@ -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() { diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index 6e74d210ed..0f9c2f554b 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -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 }; diff --git a/libraries/render-utils/src/Blendshape.slh b/libraries/render-utils/src/Blendshape.slh index 34bd43cabb..df62af5a77 100644 --- a/libraries/render-utils/src/Blendshape.slh +++ b/libraries/render-utils/src/Blendshape.slh @@ -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@> diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index a1220c04fa..13ee688fac 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -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 diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 6ee39ca3aa..5d46ee49f1 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -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 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++; }