realized past me realized that aliasing buffers isn't foolproof and added a system to fetch buffer descriptors by name from a source, yet never used it (re-bind buffer descriptors on mesh updates, need to fix the crash for graph storage when it resizes...)
This commit is contained in:
parent
6d4837e3cc
commit
0a29063869
@ -78,8 +78,8 @@
|
||||
"stream": {
|
||||
"tag": "worldspawn",
|
||||
"player": "info_player_spawn",
|
||||
"enabled": "auto",
|
||||
"radius": 32,
|
||||
"enabled": true, // "auto",
|
||||
"radius": 16,
|
||||
"every": 1
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
}
|
||||
},
|
||||
"graph": {
|
||||
"initial buffer elements": 256
|
||||
"initial buffer elements": 128
|
||||
},
|
||||
"ext": {
|
||||
"opengl": {
|
||||
|
@ -161,7 +161,7 @@ namespace uf {
|
||||
void UF_API initialize( uf::Object&, size_t = uf::graph::initialBufferElements );
|
||||
void UF_API initialize( pod::Graph::Storage&, size_t = uf::graph::initialBufferElements );
|
||||
void UF_API tick( uf::Object& );
|
||||
void UF_API tick( pod::Graph::Storage& );
|
||||
bool UF_API tick( pod::Graph::Storage& );
|
||||
void UF_API render( uf::Object& );
|
||||
void UF_API render( pod::Graph::Storage& );
|
||||
void UF_API destroy( uf::Object&, bool soft = false );
|
||||
|
@ -13,6 +13,7 @@ namespace ext {
|
||||
struct Device;
|
||||
|
||||
struct UF_API Buffer {
|
||||
bool aliased = false;
|
||||
Device* device;
|
||||
GLuint buffer = 0;
|
||||
|
||||
|
@ -38,6 +38,10 @@ namespace ext {
|
||||
|
||||
} textures, buffers;
|
||||
|
||||
struct {
|
||||
uf::stl::vector<Buffer> buffers;
|
||||
} transient;
|
||||
|
||||
void initialize();
|
||||
void destroy();
|
||||
|
||||
|
@ -110,6 +110,11 @@ namespace ext {
|
||||
void destroy();
|
||||
bool validate();
|
||||
|
||||
bool hasBuffer( const uf::stl::string& name );
|
||||
void aliasBuffer( const Metadata::BufferDescriptor& descriptor );
|
||||
void aliasBuffer( const ext::opengl::Buffer& buffer );
|
||||
void aliasBuffer( const uf::stl::string& name, const ext::opengl::Buffer& = {}, const ext::opengl::RenderMode* renderMode = NULL, GLenum = 0 );
|
||||
|
||||
bool hasUniform( const uf::stl::string& name ) const;
|
||||
|
||||
Buffer& getUniformBuffer( const uf::stl::string& name );
|
||||
|
@ -144,6 +144,7 @@ namespace ext {
|
||||
|
||||
bool hasBuffer( const uf::stl::string& name );
|
||||
void aliasBuffer( const Metadata::BufferDescriptor& descriptor );
|
||||
void aliasBuffer( const ext::vulkan::Buffer& buffer );
|
||||
void aliasBuffer( const uf::stl::string& name, const ext::vulkan::Buffer& = {}, const ext::vulkan::RenderMode* renderMode = NULL, VkBufferUsageFlags = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT );
|
||||
|
||||
bool hasUniform( const uf::stl::string& name ) const;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -12,15 +12,14 @@ ext::opengl::Buffer ext::opengl::Buffer::alias() const {
|
||||
return buffer;
|
||||
}
|
||||
void ext::opengl::Buffer::aliasBuffer( const ext::opengl::Buffer& buffer ) {
|
||||
*this = {
|
||||
.device = NULL,
|
||||
.buffer = buffer.buffer,
|
||||
.descriptor = buffer.descriptor,
|
||||
.size = buffer.size,
|
||||
.alignment = buffer.alignment,
|
||||
.usage = buffer.usage,
|
||||
.allocationInfo = buffer.allocationInfo,
|
||||
};
|
||||
this->aliased = true;
|
||||
this->device = NULL;
|
||||
this->buffer = buffer.buffer;
|
||||
this->descriptor = buffer.descriptor;
|
||||
this->size = buffer.size;
|
||||
this->alignment = buffer.alignment;
|
||||
this->usage = buffer.usage;
|
||||
this->allocationInfo = buffer.allocationInfo;
|
||||
}
|
||||
|
||||
void* ext::opengl::Buffer::map( GLsizeiptr size, GLsizeiptr offset ) {
|
||||
@ -52,9 +51,18 @@ void ext::opengl::Buffer::initialize( const void* data, GLsizeiptr length, GLenu
|
||||
} );
|
||||
if ( !alias ) this->update( data, length );
|
||||
}
|
||||
bool ext::opengl::Buffer::update( const void* data, GLsizeiptr len ) const {
|
||||
bool ext::opengl::Buffer::update( const void* data, GLsizeiptr length ) const {
|
||||
if ( !buffer || !data ) return false;
|
||||
if ( len >= size ) len = size;
|
||||
if ( length > allocationInfo.size ) {
|
||||
UF_MSG_WARNING("Buffer update of {} exceeds buffer size of {}", length, allocationInfo.size);
|
||||
|
||||
auto savedUsage = usage;
|
||||
Buffer& self = const_cast<Buffer&>(*this);
|
||||
self.destroy(true);
|
||||
self.initialize(data, length, savedUsage);
|
||||
|
||||
return true;
|
||||
}
|
||||
#if !UF_USE_OPENGL_FIXED_FUNCTION
|
||||
// GPU-bound buffer
|
||||
GLenum usage;
|
||||
@ -74,12 +82,12 @@ bool ext::opengl::Buffer::update( const void* data, GLsizeiptr len ) const {
|
||||
if ( usage & enums::Buffer::COPY ) usage = GL_DYNAMIC_COPY;
|
||||
}
|
||||
GL_ERROR_CHECK(glBindBuffer(GL_COPY_WRITE_BUFFER, buffer));
|
||||
GL_ERROR_CHECK(glBufferData(GL_COPY_WRITE_BUFFER, len, data, usage));
|
||||
GL_ERROR_CHECK(glBufferData(GL_COPY_WRITE_BUFFER, length, data, usage));
|
||||
GL_ERROR_CHECK(glBindBuffer(GL_COPY_WRITE_BUFFER, 0));
|
||||
#else
|
||||
// CPU-bound buffer
|
||||
void* pointer = device->getBuffer( buffer );
|
||||
if ( pointer && pointer != data ) memcpy( pointer, data, len );
|
||||
if ( pointer && pointer != data ) memcpy( pointer, data, length );
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
@ -113,7 +121,15 @@ void ext::opengl::Buffer::initialize( Device& device ) {
|
||||
this->device = &device;
|
||||
}
|
||||
void ext::opengl::Buffer::destroy( bool defer ) {
|
||||
if ( device && buffer ) device->destroyBuffer( buffer );
|
||||
if ( !device || aliased ) return;
|
||||
|
||||
if ( defer ) {
|
||||
ext::opengl::mutex.lock();
|
||||
device->transient.buffers.emplace_back(*this);
|
||||
ext::opengl::mutex.unlock();
|
||||
} else if ( buffer ) {
|
||||
device->destroyBuffer( buffer );
|
||||
}
|
||||
device = NULL;
|
||||
buffer = NULL;
|
||||
}
|
||||
|
@ -410,6 +410,7 @@ void ext::opengl::render(){
|
||||
#if !UF_ENV_DREAMCAST
|
||||
ext::opengl::device.activateContext();
|
||||
#endif
|
||||
auto transient = std::move(ext::opengl::device.transient);
|
||||
|
||||
{
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
@ -470,6 +471,11 @@ void ext::opengl::render(){
|
||||
#if UF_USE_OPENVR
|
||||
// if ( ext::openvr::context ) ext::openvr::postSubmit();
|
||||
#endif
|
||||
|
||||
// cleanup in-flight buffers
|
||||
for ( auto& buffer : transient.buffers ) buffer.destroy(false);
|
||||
transient.buffers.clear();
|
||||
|
||||
ext::opengl::mutex.unlock();
|
||||
}
|
||||
void ext::opengl::destroy() {
|
||||
|
@ -116,6 +116,19 @@ bool ext::opengl::Shader::hasUniform( const uf::stl::string& name ) const {
|
||||
// return metadata.definitions.uniforms.count(name) > 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ext::opengl::Shader::aliasBuffer( const ext::opengl::Shader::Metadata::BufferDescriptor& descriptor ) {
|
||||
metadata.aliases.buffers.emplace_back(descriptor);
|
||||
}
|
||||
// aliases by name
|
||||
void ext::opengl::Shader::aliasBuffer( const uf::stl::string& name, const ext::opengl::Buffer& fallback, const ext::opengl::RenderMode* renderMode, GLenum flags ) {
|
||||
return aliasBuffer({ name, fallback.alias(), renderMode, flags });
|
||||
}
|
||||
// aliases directly
|
||||
void ext::opengl::Shader::aliasBuffer( const ext::opengl::Buffer& buffer ) {
|
||||
return aliasBuffer({ "", buffer.alias(), NULL, buffer.usage });
|
||||
}
|
||||
|
||||
ext::opengl::Buffer& ext::opengl::Shader::getUniformBuffer( const uf::stl::string& name ) {
|
||||
UF_ASSERT( hasUniform(name) );
|
||||
size_t uniformIndex = 0; // metadata.definitions.uniforms[name].index;
|
||||
|
@ -195,14 +195,11 @@ bool ext::vulkan::Buffer::update( const void* data, VkDeviceSize length, bool st
|
||||
auto savedMemProps = memoryProperties;
|
||||
auto savedAlignment = alignment;
|
||||
|
||||
Buffer& oldBuffer = *const_cast<Buffer*>(this);
|
||||
Buffer newBuffer = {};
|
||||
Buffer& self = const_cast<Buffer&>(*this);
|
||||
|
||||
oldBuffer.swap(newBuffer);
|
||||
newBuffer.destroy(true);
|
||||
|
||||
oldBuffer.initialize(*device, savedAlignment);
|
||||
oldBuffer.initialize(data, length, savedUsage, savedMemProps, stage);
|
||||
self.destroy(true);
|
||||
self.initialize(*device, savedAlignment);
|
||||
self.initialize(data, length, savedUsage, savedMemProps, stage);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -516,6 +516,7 @@ void ext::vulkan::Pipeline::update( const Graphic& graphic, const GraphicDescrip
|
||||
auto& infos = INFOS.emplace_back();
|
||||
uf::stl::vector<ext::vulkan::enums::Image::viewType_t> types;
|
||||
|
||||
// add aliased-by-name buffers
|
||||
for ( auto& descriptor : shader->metadata.aliases.buffers ) {
|
||||
auto matches = uf::string::match(descriptor.name, R"(/^(.+?)\[(\d+)\]$/)");
|
||||
auto name = matches.size() == 2 ? matches[0] : descriptor.name;
|
||||
|
@ -881,9 +881,14 @@ bool ext::vulkan::Shader::hasBuffer( const uf::stl::string& name ) {
|
||||
void ext::vulkan::Shader::aliasBuffer( const ext::vulkan::Shader::Metadata::BufferDescriptor& descriptor ) {
|
||||
metadata.aliases.buffers.emplace_back(descriptor);
|
||||
}
|
||||
// aliases by name
|
||||
void ext::vulkan::Shader::aliasBuffer( const uf::stl::string& name, const ext::vulkan::Buffer& fallback, const ext::vulkan::RenderMode* renderMode, VkBufferUsageFlags flags ) {
|
||||
return aliasBuffer({ name, fallback.alias(), renderMode, flags });
|
||||
}
|
||||
// aliases directly
|
||||
void ext::vulkan::Shader::aliasBuffer( const ext::vulkan::Buffer& buffer ) {
|
||||
return aliasBuffer({ "", buffer.alias(), NULL, buffer.usage });
|
||||
}
|
||||
|
||||
bool ext::vulkan::Shader::hasUniform( const uf::stl::string& name ) const {
|
||||
return metadata.definitions.uniforms.count(name) > 0;
|
||||
|
Loading…
Reference in New Issue
Block a user