Skip to content

Commit

Permalink
Make AssetPrimitiveInfo stores only information collected from proces…
Browse files Browse the repository at this point in the history
…sing the asset attribute buffer views.

Information fields that could be obtained without buffer view processing (material index, position min/max, etc) are removed.
  • Loading branch information
stripe2933 committed Jan 28, 2025
1 parent 84a16be commit db0811b
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 29 deletions.
3 changes: 1 addition & 2 deletions impl/gltf/AssetGpuBuffers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ auto vk_gltf_viewer::gltf::AssetGpuBuffers::createPrimitiveInfos() const -> std:
pPrimitive,
AssetPrimitiveInfo {
.index = primitiveIndex,
.materialIndex = to_optional(pPrimitive->materialIndex),
},
};
})
Expand Down Expand Up @@ -85,7 +84,7 @@ std::variant<vku::AllocatedBuffer, vku::MappedBuffer> vk_gltf_viewer::gltf::Asse
.normalByteStride = normalInfo.byteStride,
.tangentByteStride = tangentInfo.byteStride,
.colorByteStride = colorInfo.byteStride,
.materialIndex = primitiveInfo.materialIndex.transform(LIFT(materialBuffer.get().padMaterialIndex)).value_or(0U),
.materialIndex = to_optional(pPrimitive->materialIndex).transform(LIFT(materialBuffer.get().padMaterialIndex)).value_or(0U),
};
}),
gpu.isUmaDevice ? vk::BufferUsageFlagBits::eStorageBuffer : vk::BufferUsageFlagBits::eTransferSrc,
Expand Down
36 changes: 23 additions & 13 deletions impl/vulkan/Frame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,8 @@ auto vk_gltf_viewer::vulkan::Frame::update(const ExecutionTask &task) -> UpdateR
.cullMode = vk::CullModeFlagBits::eBack,
};

if (primitiveInfo.materialIndex) {
const fastgltf::Material &material = task.gltf->asset.materials[*primitiveInfo.materialIndex];
if (primitive.materialIndex) {
const fastgltf::Material &material = task.gltf->asset.materials[*primitive.materialIndex];
result.subpass = material.alphaMode == fastgltf::AlphaMode::Blend;

constexpr auto fetchTextureTransform = [](const fastgltf::TextureInfo &textureInfo) {
Expand Down Expand Up @@ -205,8 +205,8 @@ auto vk_gltf_viewer::vulkan::Frame::update(const ExecutionTask &task) -> UpdateR
.cullMode = vk::CullModeFlagBits::eBack,
};

if (primitiveInfo.materialIndex) {
const fastgltf::Material& material = task.gltf->asset.materials[*primitiveInfo.materialIndex];
if (primitive.materialIndex) {
const fastgltf::Material& material = task.gltf->asset.materials[*primitive.materialIndex];
if (material.alphaMode == fastgltf::AlphaMode::Mask) {
result.pipeline = sharedData.getMaskDepthRenderer({
.baseColorTexcoordComponentType = material.pbrData.baseColorTexture.transform([&](const fastgltf::TextureInfo &textureInfo) {
Expand Down Expand Up @@ -239,8 +239,8 @@ auto vk_gltf_viewer::vulkan::Frame::update(const ExecutionTask &task) -> UpdateR
.cullMode = vk::CullModeFlagBits::eBack,
};

if (primitiveInfo.materialIndex) {
const fastgltf::Material &material = task.gltf->asset.materials[*primitiveInfo.materialIndex];
if (primitive.materialIndex) {
const fastgltf::Material &material = task.gltf->asset.materials[*primitive.materialIndex];
if (material.alphaMode == fastgltf::AlphaMode::Mask) {
result.pipeline = sharedData.getMaskJumpFloodSeedRenderer({
.baseColorTexcoordComponentType = material.pbrData.baseColorTexture.transform([&](const fastgltf::TextureInfo &textureInfo) {
Expand All @@ -267,13 +267,21 @@ auto vk_gltf_viewer::vulkan::Frame::update(const ExecutionTask &task) -> UpdateR
std::uint16_t nodeIndex,
const fastgltf::Primitive &primitive
) -> std::variant<vk::DrawIndirectCommand, vk::DrawIndexedIndirectCommand> {
// Get the accessor which determine the draw count.
// - If the primitive has indices accessor, it will determine the draw count.
// - Otherwise, the POSITION accessor will determine the draw count.
const std::size_t drawCountDeterminingAccessorIndex
= primitive.indicesAccessor.value_or(primitive.findAttribute("POSITION")->accessorIndex);
const std::uint32_t drawCount = task.gltf->asset.accessors[drawCountDeterminingAccessorIndex].count;

// EXT_mesh_gpu_instancing support.
std::uint32_t instanceCount = 1;
if (const fastgltf::Node &node = task.gltf->asset.nodes[nodeIndex]; !node.instancingAttributes.empty()) {
instanceCount = task.gltf->asset.accessors[node.instancingAttributes[0].accessorIndex].count;
}

const gltf::AssetPrimitiveInfo &primitiveInfo = task.gltf->assetGpuBuffers.primitiveInfos.at(&primitive);
const std::uint32_t firstInstance = (static_cast<std::uint32_t>(nodeIndex) << 16U) | static_cast<std::uint32_t>(primitiveInfo.index);
if (const auto &indexInfo = primitiveInfo.indexInfo) {
const std::size_t indexByteSize = [=]() {
switch (indexInfo->type) {
Expand All @@ -285,19 +293,19 @@ auto vk_gltf_viewer::vulkan::Frame::update(const ExecutionTask &task) -> UpdateR
}();

return vk::DrawIndexedIndirectCommand {
primitiveInfo.drawCount,
drawCount,
instanceCount,
static_cast<std::uint32_t>(primitiveInfo.indexInfo->offset / indexByteSize),
0,
(static_cast<std::uint32_t>(nodeIndex) << 16U) | static_cast<std::uint32_t>(primitiveInfo.index),
firstInstance,
};
}
else {
return vk::DrawIndirectCommand {
primitiveInfo.drawCount,
drawCount,
instanceCount,
0,
(static_cast<std::uint32_t>(nodeIndex) << 16U) | static_cast<std::uint32_t>(primitiveInfo.index),
firstInstance,
};
}
};
Expand All @@ -324,11 +332,13 @@ auto vk_gltf_viewer::vulkan::Frame::update(const ExecutionTask &task) -> UpdateR
const std::uint16_t primitiveIndex = command.firstInstance & 0xFFFFU;
const fastgltf::Primitive &primitive = task.gltf->assetGpuBuffers.getPrimitiveByOrder(primitiveIndex);

const gltf::AssetPrimitiveInfo &primitiveInfo = task.gltf->assetGpuBuffers.primitiveInfos.at(&primitive);
const fastgltf::Accessor &positionAccessor = task.gltf->asset.accessors[primitive.findAttribute("POSITION")->accessorIndex];
const double *positionMinData = get_if<std::pmr::vector<double>>(&positionAccessor.min)->data();
const double *positionMaxData = get_if<std::pmr::vector<double>>(&positionAccessor.max)->data();

const glm::mat4 nodeWorldTransform = glm::make_mat4(task.gltf->nodeWorldTransforms[nodeIndex].data());
const glm::vec3 transformedMin { nodeWorldTransform * glm::vec4 { primitiveInfo.min, 1.f } };
const glm::vec3 transformedMax { nodeWorldTransform * glm::vec4 { primitiveInfo.max, 1.f } };
const glm::vec3 transformedMin { nodeWorldTransform * glm::vec4 { glm::make_vec3(positionMinData), 1.f } };
const glm::vec3 transformedMax { nodeWorldTransform * glm::vec4 { glm::make_vec3(positionMinData), 1.f } };

const glm::vec3 halfDisplacement = (transformedMax - transformedMin) / 2.f;
const glm::vec3 center = transformedMin + halfDisplacement;
Expand Down
10 changes: 2 additions & 8 deletions interface/gltf/AssetGpuBuffers.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -111,13 +111,11 @@ namespace vk_gltf_viewer::gltf {
) : asset { asset },
gpu { gpu },
// Ensure the order of function execution:
// Primitive attribute buffers MUST be created before index buffer creation (because fill the AssetPrimitiveInfo
// and determine the drawCount if primitive is non-indexed, and createIndexBuffers() will use it).
indexBuffers { (createPrimitiveAttributeBuffers(adapter), createPrimitiveIndexBuffers(adapter)) },
indexBuffers { createPrimitiveIndexBuffers(adapter) },
materialBuffer { materialBuffer },
// Remaining buffers MUST be created before the primitive buffer creation (because they fill the
// AssetPrimitiveInfo and createPrimitiveBuffer() will stage it).
primitiveBuffer { (createPrimitiveIndexedAttributeMappingBuffers(), createPrimitiveTangentBuffers(threadPool, adapter), createPrimitiveBuffer()) } {
primitiveBuffer { (createPrimitiveAttributeBuffers(adapter), createPrimitiveIndexedAttributeMappingBuffers(), createPrimitiveTangentBuffers(threadPool, adapter), createPrimitiveBuffer()) } {
if (!stagingInfos.empty()) {
// Transfer the asset resources into the GPU using transfer queue.
const vk::raii::CommandPool transferCommandPool { gpu.device, vk::CommandPoolCreateInfo { {}, gpu.queueFamilies.transfer } };
Expand Down Expand Up @@ -252,7 +250,6 @@ namespace vk_gltf_viewer::gltf {
for (auto [pPrimitive, offset] : std::views::zip(primitiveAndIndexBytesPairs | std::views::keys, copyOffsets)) {
AssetPrimitiveInfo &primitiveInfo = primitiveInfos[pPrimitive];
primitiveInfo.indexInfo.emplace(offset, indexType);
primitiveInfo.drawCount = asset.accessors[*pPrimitive->indicesAccessor].count;
}

return std::pair { indexType, std::move(buffer) };
Expand Down Expand Up @@ -341,9 +338,6 @@ namespace vk_gltf_viewer::gltf {

if (attributeName == "POSITION"sv) {
primitiveInfo.positionInfo = getAttributeBufferInfo();
primitiveInfo.drawCount = accessor.count;
primitiveInfo.min = glm::make_vec3(get_if<std::pmr::vector<double>>(&accessor.min)->data());
primitiveInfo.max = glm::make_vec3(get_if<std::pmr::vector<double>>(&accessor.max)->data());
}
else if (attributeName == "NORMAL"sv) {
primitiveInfo.normalInfo.emplace(getAttributeBufferInfo());
Expand Down
7 changes: 1 addition & 6 deletions interface/gltf/AssetPrimitiveInfo.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,21 @@ export module vk_gltf_viewer:gltf.AssetPrimitiveInfo;

import std;
export import fastgltf;
export import glm;
export import vulkan_hpp;

namespace vk_gltf_viewer::gltf {
struct AssetPrimitiveInfo {
export struct AssetPrimitiveInfo {
struct IndexBufferInfo { vk::DeviceSize offset; vk::IndexType type; };
struct AttributeBufferInfo { vk::DeviceAddress address; std::uint8_t byteStride; fastgltf::ComponentType componentType; };
struct ColorAttributeBufferInfo final : AttributeBufferInfo { std::uint8_t numComponent; };
struct IndexedAttributeBufferInfos { vk::DeviceAddress pMappingBuffer; std::vector<AttributeBufferInfo> attributeInfos; };

std::uint16_t index;
std::optional<std::size_t> materialIndex;
std::uint32_t drawCount;
std::optional<IndexBufferInfo> indexInfo{};
AttributeBufferInfo positionInfo;
std::optional<AttributeBufferInfo> normalInfo;
std::optional<AttributeBufferInfo> tangentInfo;
IndexedAttributeBufferInfos texcoordsInfo;
std::optional<ColorAttributeBufferInfo> colorInfo;
glm::dvec3 min;
glm::dvec3 max;
};
}

0 comments on commit db0811b

Please sign in to comment.