fixed graph buffers not getting updated (for opengl, vulkan still crashes...)
This commit is contained in:
parent
114bed0d5d
commit
81a3125fcd
@ -59,7 +59,7 @@
|
||||
}
|
||||
},
|
||||
"graph": {
|
||||
"initial buffer elements": 2048,
|
||||
"initial buffer elements": 128,
|
||||
"global storage": false
|
||||
},
|
||||
"ext": {
|
||||
|
||||
@ -17,7 +17,8 @@
|
||||
}
|
||||
},
|
||||
"graph": {
|
||||
"initial buffer elements": 128
|
||||
"initial buffer elements": 128,
|
||||
"global storage": false
|
||||
},
|
||||
"ext": {
|
||||
"opengl": {
|
||||
@ -85,7 +86,7 @@
|
||||
"subPools": false,
|
||||
"alignment": 4,
|
||||
"override": false,
|
||||
"size": "512 KiB",
|
||||
"size": "1024 KiB",
|
||||
"pools": {
|
||||
"entity": "128 KiB",
|
||||
"userdata": "128 KiB",
|
||||
|
||||
@ -33,6 +33,7 @@
|
||||
|
||||
namespace {
|
||||
bool newGraphAdded = true;
|
||||
bool shouldRebind = false;
|
||||
|
||||
// todo: shove it into the "std"lib
|
||||
inline uint64_t fnv1aHash(const uf::stl::vector<bool>& bits) {
|
||||
@ -415,17 +416,13 @@ namespace {
|
||||
|
||||
// bind buffers
|
||||
::resetBuffers( shader );
|
||||
#if UF_USE_VULKAN
|
||||
shader.aliasBuffer( "camera", storage.buffers.camera );
|
||||
#else
|
||||
shader.aliasBuffer( storage.buffers.camera );
|
||||
#endif
|
||||
|
||||
#if UF_USE_VULKAN
|
||||
shader.aliasBuffer( *indirect );
|
||||
shader.aliasBuffer( "indirect", *indirect );
|
||||
#endif
|
||||
shader.aliasBuffer( storage.buffers.instance );
|
||||
shader.aliasBuffer( storage.buffers.joint );
|
||||
shader.aliasBuffer( "instance", storage.buffers.instance );
|
||||
shader.aliasBuffer( "joint", storage.buffers.joint );
|
||||
}
|
||||
// fragment shader
|
||||
{
|
||||
@ -433,12 +430,12 @@ namespace {
|
||||
|
||||
// bind buffers
|
||||
::resetBuffers( shader );
|
||||
shader.aliasBuffer( storage.buffers.drawCommands );
|
||||
shader.aliasBuffer( storage.buffers.instance );
|
||||
shader.aliasBuffer( storage.buffers.instanceAddresses );
|
||||
shader.aliasBuffer( storage.buffers.material );
|
||||
shader.aliasBuffer( storage.buffers.texture );
|
||||
shader.aliasBuffer( storage.buffers.light );
|
||||
shader.aliasBuffer( "drawCommands", storage.buffers.drawCommands );
|
||||
shader.aliasBuffer( "instance", storage.buffers.instance );
|
||||
shader.aliasBuffer( "instanceAddresses", storage.buffers.instanceAddresses );
|
||||
shader.aliasBuffer( "material", storage.buffers.material );
|
||||
shader.aliasBuffer( "texture", storage.buffers.texture );
|
||||
shader.aliasBuffer( "light", storage.buffers.light );
|
||||
}
|
||||
}
|
||||
|
||||
@ -451,12 +448,12 @@ namespace {
|
||||
|
||||
// bind buffers
|
||||
::resetBuffers( shader );
|
||||
shader.aliasBuffer( storage.buffers.drawCommands );
|
||||
shader.aliasBuffer( storage.buffers.instance );
|
||||
shader.aliasBuffer( storage.buffers.instanceAddresses );
|
||||
shader.aliasBuffer( storage.buffers.material );
|
||||
shader.aliasBuffer( storage.buffers.texture );
|
||||
shader.aliasBuffer( storage.buffers.light );
|
||||
shader.aliasBuffer( "drawCommands", storage.buffers.drawCommands );
|
||||
shader.aliasBuffer( "instance", storage.buffers.instance );
|
||||
shader.aliasBuffer( "instanceAddresses", storage.buffers.instanceAddresses );
|
||||
shader.aliasBuffer( "material", storage.buffers.material );
|
||||
shader.aliasBuffer( "texture", storage.buffers.texture );
|
||||
shader.aliasBuffer( "light", storage.buffers.light );
|
||||
}
|
||||
// culling pipeline
|
||||
if ( uf::renderer::settings::pipelines::culling && indirect ) {
|
||||
@ -466,8 +463,8 @@ namespace {
|
||||
// bind buffers
|
||||
::resetBuffers( shader );
|
||||
shader.aliasBuffer( "camera", storage.buffers.camera );
|
||||
shader.aliasBuffer( *indirect );
|
||||
shader.aliasBuffer( storage.buffers.instance );
|
||||
shader.aliasBuffer( "indirect", *indirect );
|
||||
shader.aliasBuffer( "instance", storage.buffers.instance );
|
||||
}
|
||||
|
||||
// vxgi pipeline
|
||||
@ -478,12 +475,12 @@ namespace {
|
||||
|
||||
// bind buffers
|
||||
::resetBuffers( shader );
|
||||
shader.aliasBuffer( storage.buffers.drawCommands );
|
||||
shader.aliasBuffer( storage.buffers.instance );
|
||||
shader.aliasBuffer( storage.buffers.instanceAddresses );
|
||||
shader.aliasBuffer( storage.buffers.material );
|
||||
shader.aliasBuffer( storage.buffers.texture );
|
||||
shader.aliasBuffer( storage.buffers.light );
|
||||
shader.aliasBuffer( "drawCommands", storage.buffers.drawCommands );
|
||||
shader.aliasBuffer( "instance", storage.buffers.instance );
|
||||
shader.aliasBuffer( "instanceAddresses", storage.buffers.instanceAddresses );
|
||||
shader.aliasBuffer( "material", storage.buffers.material );
|
||||
shader.aliasBuffer( "texture", storage.buffers.texture );
|
||||
shader.aliasBuffer( "light", storage.buffers.light );
|
||||
}
|
||||
}
|
||||
// baking pipeline
|
||||
@ -495,10 +492,10 @@ namespace {
|
||||
// bind buffers
|
||||
::resetBuffers( shader );
|
||||
#if UF_USE_VULKAN
|
||||
shader.aliasBuffer( *indirect );
|
||||
shader.aliasBuffer( "indirect", *indirect );
|
||||
#endif
|
||||
shader.aliasBuffer( storage.buffers.instance );
|
||||
shader.aliasBuffer( storage.buffers.joint );
|
||||
shader.aliasBuffer( "instance", storage.buffers.instance );
|
||||
shader.aliasBuffer( "joint", storage.buffers.joint );
|
||||
}
|
||||
|
||||
// fragment shader
|
||||
@ -508,12 +505,12 @@ namespace {
|
||||
// bind buffers
|
||||
::resetBuffers( shader );
|
||||
shader.aliasBuffer( "camera", storage.buffers.camera );
|
||||
shader.aliasBuffer( storage.buffers.drawCommands );
|
||||
shader.aliasBuffer( storage.buffers.instance );
|
||||
shader.aliasBuffer( storage.buffers.instanceAddresses );
|
||||
shader.aliasBuffer( storage.buffers.material );
|
||||
shader.aliasBuffer( storage.buffers.texture );
|
||||
shader.aliasBuffer( storage.buffers.light );
|
||||
shader.aliasBuffer( "drawCommands", storage.buffers.drawCommands );
|
||||
shader.aliasBuffer( "instance", storage.buffers.instance );
|
||||
shader.aliasBuffer( "instanceAddresses", storage.buffers.instanceAddresses );
|
||||
shader.aliasBuffer( "material", storage.buffers.material );
|
||||
shader.aliasBuffer( "texture", storage.buffers.texture );
|
||||
shader.aliasBuffer( "light", storage.buffers.light );
|
||||
}
|
||||
}
|
||||
|
||||
@ -623,7 +620,7 @@ namespace {
|
||||
|
||||
size_t uf::graph::initialBufferElements = 1024;
|
||||
|
||||
bool uf::graph::globalStorage;
|
||||
bool uf::graph::globalStorage = false;
|
||||
pod::Graph::Storage uf::graph::storage;
|
||||
|
||||
UF_VERTEX_DESCRIPTOR(uf::graph::mesh::Base,
|
||||
@ -1762,6 +1759,23 @@ void uf::graph::update( pod::Graph& graph, float delta ) {
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
auto& storage = uf::graph::globalStorage ? uf::graph::storage : scene.getComponent<pod::Graph::Storage>();
|
||||
|
||||
// rebuild
|
||||
if ( ::shouldRebind ) {
|
||||
for ( auto& node : graph.nodes ) {
|
||||
if ( !(0 <= node.mesh && node.mesh < graph.meshes.size()) ) continue;
|
||||
if ( !node.entity ) continue;
|
||||
|
||||
auto& entity = node.entity->as<uf::Object>();
|
||||
|
||||
if ( !entity.hasComponent<uf::renderer::Graphic>() ) continue;
|
||||
|
||||
auto& graphic = entity.getComponent<uf::renderer::Graphic>();
|
||||
auto& mesh = storage.meshes.map[graph.meshes[node.mesh]];
|
||||
|
||||
::bindBuffers( graphic, mesh );
|
||||
}
|
||||
}
|
||||
|
||||
// get last update time
|
||||
#if UF_GRAPH_EXTENDED
|
||||
if ( graph.settings.stream.enabled && graph.settings.stream.hash != 0 && uf::physics::time::current - graph.settings.stream.lastUpdate > graph.settings.stream.every ) {
|
||||
@ -1888,11 +1902,10 @@ void uf::graph::destroy( pod::Graph& graph ) {
|
||||
}
|
||||
|
||||
void uf::graph::initialize() {
|
||||
if ( uf::graph::globalStorage ) return uf::graph::initialize( uf::graph::storage );
|
||||
return uf::graph::initialize( uf::scene::getCurrentScene() );
|
||||
uf::graph::initialize( uf::scene::getCurrentScene() );
|
||||
}
|
||||
void uf::graph::initialize( uf::Object& object, size_t initialElements ) {
|
||||
return uf::graph::initialize( object.getComponent<pod::Graph::Storage>(), initialElements );
|
||||
return uf::graph::initialize( uf::graph::globalStorage ? uf::graph::storage : object.getComponent<pod::Graph::Storage>(), initialElements );
|
||||
}
|
||||
void uf::graph::initialize( pod::Graph::Storage& storage, size_t initialElements ) {
|
||||
storage.buffers.camera.initialize( (const void*) nullptr, sizeof(pod::Camera::Viewports), uf::renderer::enums::Buffer::UNIFORM );
|
||||
@ -1906,31 +1919,13 @@ void uf::graph::initialize( pod::Graph::Storage& storage, size_t initialElements
|
||||
storage.buffers.light.initialize( (const void*) nullptr, sizeof(pod::Light) * initialElements, uf::renderer::enums::Buffer::STORAGE );
|
||||
}
|
||||
void uf::graph::tick() {
|
||||
if ( uf::graph::globalStorage ) uf::graph::tick( uf::graph::storage );
|
||||
else uf::graph::tick( uf::scene::getCurrentScene() );
|
||||
uf::graph::tick( uf::scene::getCurrentScene() );
|
||||
}
|
||||
void uf::graph::tick( uf::Object& object ) {
|
||||
auto& storage = object.getComponent<pod::Graph::Storage>();
|
||||
|
||||
bool rebuild = uf::graph::tick( storage );
|
||||
|
||||
// rebind buffers
|
||||
if ( rebuild ) {
|
||||
auto& graph = object.getComponent<pod::Graph>();
|
||||
for ( auto& node : graph.nodes ) {
|
||||
if ( !(0 <= node.mesh && node.mesh < graph.meshes.size()) ) continue;
|
||||
if ( !node.entity ) continue;
|
||||
auto& storage = uf::graph::globalStorage ? uf::graph::storage : object.getComponent<pod::Graph::Storage>();
|
||||
auto& graph = object.getComponent<pod::Graph>();
|
||||
|
||||
auto& entity = node.entity->as<uf::Object>();
|
||||
|
||||
if ( !entity.hasComponent<uf::renderer::Graphic>() ) continue;
|
||||
|
||||
auto& graphic = entity.getComponent<uf::renderer::Graphic>();
|
||||
auto& mesh = storage.meshes.map[graph.meshes[node.mesh]];
|
||||
|
||||
::bindBuffers( graphic, mesh );
|
||||
}
|
||||
}
|
||||
::shouldRebind = uf::graph::tick( storage );
|
||||
}
|
||||
bool uf::graph::tick( pod::Graph::Storage& storage ) {
|
||||
/*
|
||||
@ -1984,39 +1979,43 @@ bool uf::graph::tick( pod::Graph::Storage& storage ) {
|
||||
UF_MSG_DEBUG("Graph buffers requesting renderer update");
|
||||
uf::renderer::states::rebuild = true;
|
||||
|
||||
/*
|
||||
if ( uf::renderer::hasRenderMode("", true) ) {
|
||||
auto& renderMode = uf::renderer::getRenderMode("", true);
|
||||
|
||||
/*
|
||||
renderMode.metadata.buffers["camera"] = storage.buffers.camera;
|
||||
renderMode.metadata.buffers["drawCommands"] = storage.buffers.drawCommands;
|
||||
renderMode.metadata.buffers["instance"] = storage.buffers.instance;
|
||||
renderMode.metadata.buffers["instanceAddresses"] = storage.buffers.instanceAddresses;
|
||||
renderMode.metadata.buffers["joint"] = storage.buffers.joint;
|
||||
renderMode.metadata.buffers["material"] = storage.buffers.material;
|
||||
renderMode.metadata.buffers["texture"] = storage.buffers.texture;
|
||||
renderMode.metadata.buffers["light"] = storage.buffers.light;
|
||||
*/
|
||||
|
||||
#if UF_USE_VULKAN
|
||||
auto& blitter = renderMode.getBlitter();
|
||||
auto& shader = blitter.material.getShader(blitter.material.hasShader("compute", "deferred") ? "compute" : "fragment", "deferred");
|
||||
|
||||
blitter.material.textures.clear();
|
||||
shader.metadata.aliases.buffers.clear();
|
||||
|
||||
auto moved = std::move( shader.buffers );
|
||||
for ( auto& buffer : moved ) {
|
||||
if ( buffer.aliased ) continue;
|
||||
shader.aliasBuffer( buffer );
|
||||
buffer.aliased = true;
|
||||
}
|
||||
|
||||
shader.aliasBuffer( storage.buffers.drawCommands );
|
||||
shader.aliasBuffer( storage.buffers.instance );
|
||||
shader.aliasBuffer( storage.buffers.instanceAddresses );
|
||||
shader.aliasBuffer( storage.buffers.material );
|
||||
shader.aliasBuffer( storage.buffers.texture );
|
||||
shader.aliasBuffer( storage.buffers.light );
|
||||
shader.aliasBuffer( "drawCommands", storage.buffers.drawCommands );
|
||||
shader.aliasBuffer( "instance", storage.buffers.instance );
|
||||
shader.aliasBuffer( "instanceAddresses", storage.buffers.instanceAddresses );
|
||||
shader.aliasBuffer( "material", storage.buffers.material );
|
||||
shader.aliasBuffer( "texture", storage.buffers.texture );
|
||||
shader.aliasBuffer( "light", storage.buffers.light );
|
||||
#endif
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
return rebuild;
|
||||
}
|
||||
void uf::graph::render() {
|
||||
if ( uf::graph::globalStorage ) return uf::graph::render( uf::graph::storage );
|
||||
return uf::graph::render( uf::scene::getCurrentScene() );
|
||||
uf::graph::render( uf::scene::getCurrentScene() );
|
||||
}
|
||||
void uf::graph::render( uf::Object& object ) {
|
||||
return uf::graph::render( object.getComponent<pod::Graph::Storage>() );
|
||||
return uf::graph::render( uf::graph::globalStorage ? uf::graph::storage : object.getComponent<pod::Graph::Storage>() );
|
||||
}
|
||||
void uf::graph::render( pod::Graph::Storage& storage ) {
|
||||
auto* renderMode = uf::renderer::getCurrentRenderMode();
|
||||
@ -2057,12 +2056,11 @@ void uf::graph::render( pod::Graph::Storage& storage ) {
|
||||
}
|
||||
void uf::graph::destroy( bool soft ) {
|
||||
soft = false;
|
||||
if ( uf::graph::globalStorage ) return uf::graph::destroy( uf::graph::storage, soft );
|
||||
return uf::graph::destroy( uf::scene::getCurrentScene(), soft );
|
||||
}
|
||||
void uf::graph::destroy( uf::Object& object, bool soft ) {
|
||||
soft = false;
|
||||
return uf::graph::destroy( object.getComponent<pod::Graph::Storage>(), soft );
|
||||
return uf::graph::destroy( uf::graph::globalStorage ? uf::graph::storage : object.getComponent<pod::Graph::Storage>(), soft );
|
||||
}
|
||||
void uf::graph::destroy( pod::Graph::Storage& storage, bool soft ) {
|
||||
soft = false;
|
||||
|
||||
@ -60,7 +60,7 @@ bool ext::opengl::Buffer::update( const void* data, GLsizeiptr length ) const {
|
||||
Buffer& self = const_cast<Buffer&>(*this);
|
||||
self.destroy(true);
|
||||
self.initialize(data, length, savedUsage);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
#if !UF_USE_OPENGL_FIXED_FUNCTION
|
||||
|
||||
@ -356,6 +356,8 @@ void ext::opengl::Graphic::record( CommandBuffer& commandBuffer, const GraphicDe
|
||||
auto& pipeline = this->getPipeline( descriptor );
|
||||
auto shaders = pipeline.getShaders( material.shaders );
|
||||
|
||||
uf::stl::unordered_map<uf::stl::string, ext::opengl::Buffer::Descriptor> bufferMap;
|
||||
|
||||
for ( auto shader : shaders ) {
|
||||
// bind aliased buffers
|
||||
for ( auto& descriptor : shader->metadata.aliases.buffers ) {
|
||||
@ -374,6 +376,8 @@ void ext::opengl::Graphic::record( CommandBuffer& commandBuffer, const GraphicDe
|
||||
|
||||
if ( buffer->usage & uf::renderer::enums::Buffer::UNIFORM ) uniformBuffers.emplace_back(buffer->descriptor);
|
||||
if ( buffer->usage & uf::renderer::enums::Buffer::STORAGE ) storageBuffers.emplace_back(buffer->descriptor);
|
||||
|
||||
// if ( descriptor.name != "" ) bufferMap[descriptor.name] = buffer->descriptor;
|
||||
}
|
||||
// bind shader
|
||||
for ( auto& buffer : shader->buffers ) {
|
||||
@ -437,15 +441,27 @@ void ext::opengl::Graphic::record( CommandBuffer& commandBuffer, const GraphicDe
|
||||
|
||||
auto storageBufferIt = storageBuffers.begin();
|
||||
|
||||
storageBufferIt++;
|
||||
storageBufferIt++;
|
||||
|
||||
auto _instanceBuffer = (*storageBufferIt++).buffer;
|
||||
auto jointBuffer = (*storageBufferIt++).buffer;
|
||||
|
||||
auto drawCommandsBuffer = (*storageBufferIt++).buffer;
|
||||
auto instanceBuffer = (*storageBufferIt++).buffer;
|
||||
auto instanceAddressBuffer = (*storageBufferIt++).buffer;
|
||||
auto materialBuffer = (*storageBufferIt++).buffer;
|
||||
auto textureBuffer = (*storageBufferIt++).buffer;
|
||||
|
||||
/*
|
||||
auto _instanceBuffer = bufferMap["instance"].buffer;
|
||||
auto jointBuffer = bufferMap["joint"].buffer;
|
||||
|
||||
auto drawCommandsBuffer = bufferMap["drawCommands"].buffer;
|
||||
auto instanceBuffer = bufferMap["instance"].buffer;
|
||||
auto instanceAddressBuffer = bufferMap["instanceAddress"].buffer;
|
||||
auto materialBuffer = bufferMap["material"].buffer;
|
||||
auto textureBuffer = bufferMap["texture"].buffer;
|
||||
*/
|
||||
|
||||
|
||||
pod::DrawCommand* drawCommands = (pod::DrawCommand*) indirectAttribute.pointer;
|
||||
pod::Instance* instances = (pod::Instance*) device->getBuffer( instanceBuffer );
|
||||
pod::Material* materials = (pod::Material*) device->getBuffer( materialBuffer );
|
||||
|
||||
@ -56,7 +56,11 @@ bool ext::opengl::settings::experimental::registerRenderMode = true;
|
||||
bool ext::opengl::settings::invariant::waitOnRenderEnd = false;
|
||||
bool ext::opengl::settings::invariant::individualPipelines = true;
|
||||
|
||||
#if UF_ENV_DREAMCAST
|
||||
bool ext::opengl::settings::invariant::multithreadedRecording = false;
|
||||
#else
|
||||
bool ext::opengl::settings::invariant::multithreadedRecording = true;
|
||||
#endif
|
||||
|
||||
uf::stl::string ext::opengl::settings::invariant::deferredMode = "";
|
||||
|
||||
@ -475,7 +479,7 @@ void ext::opengl::render(){
|
||||
// cleanup in-flight buffers
|
||||
for ( auto& buffer : transient.buffers ) buffer.destroy(false);
|
||||
transient.buffers.clear();
|
||||
|
||||
|
||||
ext::opengl::mutex.unlock();
|
||||
}
|
||||
void ext::opengl::destroy() {
|
||||
|
||||
@ -297,14 +297,14 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
|
||||
{ "voxelOutput", maxCascades },
|
||||
});
|
||||
|
||||
// shader.buffers.emplace_back( storage.buffers.camera.alias() );
|
||||
// shader.buffers.emplace_back( storage.buffers.joint.alias() );
|
||||
shader.buffers.emplace_back( storage.buffers.drawCommands.alias() );
|
||||
shader.buffers.emplace_back( storage.buffers.instance.alias() );
|
||||
shader.buffers.emplace_back( storage.buffers.instanceAddresses.alias() );
|
||||
shader.buffers.emplace_back( storage.buffers.material.alias() );
|
||||
shader.buffers.emplace_back( storage.buffers.texture.alias() );
|
||||
shader.buffers.emplace_back( storage.buffers.light.alias() );
|
||||
// shader.aliasBuffer( storage.buffers.camera );
|
||||
// shader.aliasBuffer( storage.buffers.joint );
|
||||
shader.aliasBuffer( storage.buffers.drawCommands );
|
||||
shader.aliasBuffer( storage.buffers.instance );
|
||||
shader.aliasBuffer( storage.buffers.instanceAddresses );
|
||||
shader.aliasBuffer( storage.buffers.material );
|
||||
shader.aliasBuffer( storage.buffers.texture );
|
||||
shader.aliasBuffer( storage.buffers.light );
|
||||
|
||||
shader.aliasAttachment("id", this);
|
||||
#if BARYCENTRIC
|
||||
@ -521,19 +521,15 @@ void ext::vulkan::DeferredRenderMode::tick() {
|
||||
if ( blitter.material.hasShader(DEFERRED_MODE, "deferred") ) {
|
||||
auto& shader = blitter.material.getShader(DEFERRED_MODE, "deferred");
|
||||
|
||||
auto moved = std::move( shader.buffers );
|
||||
for ( auto& buffer : moved ) {
|
||||
if ( buffer.aliased ) continue;
|
||||
shader.buffers.emplace_back( buffer );
|
||||
buffer.aliased = true;
|
||||
}
|
||||
|
||||
shader.buffers.emplace_back( storage.buffers.drawCommands.alias() );
|
||||
shader.buffers.emplace_back( storage.buffers.instance.alias() );
|
||||
shader.buffers.emplace_back( storage.buffers.instanceAddresses.alias() );
|
||||
shader.buffers.emplace_back( storage.buffers.material.alias() );
|
||||
shader.buffers.emplace_back( storage.buffers.texture.alias() );
|
||||
shader.buffers.emplace_back( storage.buffers.light.alias() );
|
||||
shader.metadata.aliases.buffers.clear();
|
||||
// shader.aliasBuffer( storage.buffers.camera );
|
||||
// shader.aliasBuffer( storage.buffers.joint );
|
||||
shader.aliasBuffer( storage.buffers.drawCommands );
|
||||
shader.aliasBuffer( storage.buffers.instance );
|
||||
shader.aliasBuffer( storage.buffers.instanceAddresses );
|
||||
shader.aliasBuffer( storage.buffers.material );
|
||||
shader.aliasBuffer( storage.buffers.texture );
|
||||
shader.aliasBuffer( storage.buffers.light );
|
||||
}
|
||||
|
||||
if ( blitter.hasPipeline( blitter.descriptor ) ){
|
||||
|
||||
Loading…
Reference in New Issue
Block a user