Make loading the asset into VRAM optional.

meow-7.2.2
Jonathan "Geenz" Goodman 2025-05-21 21:00:06 -04:00
parent 30b72ba410
commit 30aa14d0b3
4 changed files with 83 additions and 77 deletions

View File

@ -516,7 +516,7 @@ bool Asset::prep()
for (auto& image : mImages)
{
if (!image.prep(*this))
if (!image.prep(*this, mLoadIntoVRAM))
{
return false;
}
@ -545,101 +545,103 @@ bool Asset::prep()
return false;
}
}
// prepare vertex buffers
// material count is number of materials + 1 for default material
U32 mat_count = (U32) mMaterials.size() + 1;
if (LLGLSLShader::sCurBoundShaderPtr == nullptr)
{ // make sure a shader is bound to satisfy mVertexBuffer->setBuffer
gDebugProgram.bind();
}
for (S32 double_sided = 0; double_sided < 2; ++double_sided)
if (mLoadIntoVRAM)
{
RenderData& rd = mRenderData[double_sided];
for (U32 i = 0; i < LLGLSLShader::NUM_GLTF_VARIANTS; ++i)
{
rd.mBatches[i].resize(mat_count);
// prepare vertex buffers
// material count is number of materials + 1 for default material
U32 mat_count = (U32) mMaterials.size() + 1;
if (LLGLSLShader::sCurBoundShaderPtr == nullptr)
{ // make sure a shader is bound to satisfy mVertexBuffer->setBuffer
gDebugProgram.bind();
}
// for each material
for (S32 mat_id = -1; mat_id < (S32)mMaterials.size(); ++mat_id)
for (S32 double_sided = 0; double_sided < 2; ++double_sided)
{
// for each shader variant
U32 vertex_count[LLGLSLShader::NUM_GLTF_VARIANTS] = { 0 };
U32 index_count[LLGLSLShader::NUM_GLTF_VARIANTS] = { 0 };
S32 ds_mat = mat_id == -1 ? 0 : mMaterials[mat_id].mDoubleSided;
if (ds_mat != double_sided)
RenderData& rd = mRenderData[double_sided];
for (U32 i = 0; i < LLGLSLShader::NUM_GLTF_VARIANTS; ++i)
{
continue;
rd.mBatches[i].resize(mat_count);
}
for (U32 variant = 0; variant < LLGLSLShader::NUM_GLTF_VARIANTS; ++variant)
// for each material
for (S32 mat_id = -1; mat_id < (S32)mMaterials.size(); ++mat_id)
{
U32 attribute_mask = 0;
// for each mesh
for (auto& mesh : mMeshes)
// for each shader variant
U32 vertex_count[LLGLSLShader::NUM_GLTF_VARIANTS] = { 0 };
U32 index_count[LLGLSLShader::NUM_GLTF_VARIANTS] = { 0 };
S32 ds_mat = mat_id == -1 ? 0 : mMaterials[mat_id].mDoubleSided;
if (ds_mat != double_sided)
{
// for each primitive
for (auto& primitive : mesh.mPrimitives)
{
if (primitive.mMaterial == mat_id && primitive.mShaderVariant == variant)
{
// accumulate vertex and index counts
primitive.mVertexOffset = vertex_count[variant];
primitive.mIndexOffset = index_count[variant];
vertex_count[variant] += primitive.getVertexCount();
index_count[variant] += primitive.getIndexCount();
// all primitives of a given variant and material should all have the same attribute mask
llassert(attribute_mask == 0 || primitive.mAttributeMask == attribute_mask);
attribute_mask |= primitive.mAttributeMask;
}
}
continue;
}
// allocate vertex buffer and pack it
if (vertex_count[variant] > 0)
for (U32 variant = 0; variant < LLGLSLShader::NUM_GLTF_VARIANTS; ++variant)
{
U32 mat_idx = mat_id + 1;
#if 0
LLVertexBuffer* vb = new LLVertexBuffer(attribute_mask);
rd.mBatches[variant][mat_idx].mVertexBuffer = vb;
vb->allocateBuffer(vertex_count[variant],
index_count[variant] * 2); // hack double index count... TODO: find a better way to indicate 32-bit indices will be used
vb->setBuffer();
U32 attribute_mask = 0;
// for each mesh
for (auto& mesh : mMeshes)
{
// for each primitive
for (auto& primitive : mesh.mPrimitives)
{
if (primitive.mMaterial == mat_id && primitive.mShaderVariant == variant)
{
primitive.upload(vb);
// accumulate vertex and index counts
primitive.mVertexOffset = vertex_count[variant];
primitive.mIndexOffset = index_count[variant];
vertex_count[variant] += primitive.getVertexCount();
index_count[variant] += primitive.getIndexCount();
// all primitives of a given variant and material should all have the same attribute mask
llassert(attribute_mask == 0 || primitive.mAttributeMask == attribute_mask);
attribute_mask |= primitive.mAttributeMask;
}
}
}
vb->unmapBuffer();
// allocate vertex buffer and pack it
if (vertex_count[variant] > 0)
{
U32 mat_idx = mat_id + 1;
#if 0
LLVertexBuffer* vb = new LLVertexBuffer(attribute_mask);
vb->unbind();
#endif
rd.mBatches[variant][mat_idx].mVertexBuffer = vb;
vb->allocateBuffer(vertex_count[variant],
index_count[variant] * 2); // hack double index count... TODO: find a better way to indicate 32-bit indices will be used
vb->setBuffer();
for (auto& mesh : mMeshes)
{
for (auto& primitive : mesh.mPrimitives)
{
if (primitive.mMaterial == mat_id && primitive.mShaderVariant == variant)
{
primitive.upload(vb);
}
}
}
vb->unmapBuffer();
vb->unbind();
#endif
}
}
}
}
}
// sanity check that all primitives have a vertex buffer
for (auto& mesh : mMeshes)
{
for (auto& primitive : mesh.mPrimitives)
// sanity check that all primitives have a vertex buffer
for (auto& mesh : mMeshes)
{
//llassert(primitive.mVertexBuffer.notNull());
for (auto& primitive : mesh.mPrimitives)
{
//llassert(primitive.mVertexBuffer.notNull());
}
}
}
#if 0
@ -678,9 +680,10 @@ Asset::Asset(const Value& src)
*this = src;
}
bool Asset::load(std::string_view filename)
bool Asset::load(std::string_view filename, bool loadIntoVRAM)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_GLTF;
mLoadIntoVRAM = loadIntoVRAM;
mFilename = filename;
std::string ext = gDirUtilp->getExtension(mFilename);
@ -698,7 +701,7 @@ bool Asset::load(std::string_view filename)
}
else if (ext == "glb")
{
return loadBinary(str);
return loadBinary(str, mLoadIntoVRAM);
}
else
{
@ -715,8 +718,9 @@ bool Asset::load(std::string_view filename)
return false;
}
bool Asset::loadBinary(const std::string& data)
bool Asset::loadBinary(const std::string& data, bool loadIntoVRAM)
{
mLoadIntoVRAM = loadIntoVRAM;
// load from binary gltf
const U8* ptr = (const U8*)data.data();
const U8* end = ptr + data.size();
@ -941,8 +945,9 @@ void Asset::eraseBufferView(S32 bufferView)
LLViewerFetchedTexture* fetch_texture(const LLUUID& id);
bool Image::prep(Asset& asset)
bool Image::prep(Asset& asset, bool loadIntoVRAM)
{
mLoadIntoTexturePipe = loadIntoVRAM;
LLUUID id;
if (mUri.size() == UUID_STR_SIZE && LLUUID::parseUUID(mUri, &id) && id.notNull())
{ // loaded from an asset, fetch the texture from the asset system

View File

@ -319,7 +319,7 @@ namespace LL
// preserve only uri and name
void clearData(Asset& asset);
bool prep(Asset& asset);
bool prep(Asset& asset, bool loadIntoVRAM);
};
// Render Batch -- vertex buffer and list of primitives to render using
@ -394,6 +394,7 @@ namespace LL
// UBO for storing material data
U32 mMaterialsUBO = 0;
bool mLoadIntoVRAM = false;
// prepare for first time use
bool prep();
@ -431,12 +432,12 @@ namespace LL
// accepts .gltf and .glb files
// Any existing data will be lost
// returns result of prep() on success
bool load(std::string_view filename);
bool load(std::string_view filename, bool loadIntoVRAM);
// load .glb contents from memory
// data - binary contents of .glb file
// returns result of prep() on success
bool loadBinary(const std::string& data);
bool loadBinary(const std::string& data, bool loadIntoVRAM);
const Asset& operator=(const Value& src);
void serialize(boost::json::object& dst) const;

View File

@ -108,7 +108,7 @@ bool LLGLTFLoader::OpenFile(const std::string &filename)
std::string filename_lc(filename);
LLStringUtil::toLower(filename_lc);
mGltfLoaded = mGLTFAsset.load(filename);
mGltfLoaded = mGLTFAsset.load(filename, false);
if (!mGltfLoaded)
{

View File

@ -317,7 +317,7 @@ void GLTFSceneManager::load(const std::string& filename)
{
std::shared_ptr<Asset> asset = std::make_shared<Asset>();
if (asset->load(filename))
if (asset->load(filename, true))
{
gDebugProgram.bind(); // bind a shader to satisfy LLVertexBuffer assertions
asset->updateTransforms();