|
|
@@ -17,146 +17,221 @@
|
|
|
|
|
|
namespace anki {
|
|
|
|
|
|
+//==============================================================================
|
|
|
+template<typename InBindings, typename OutBindings>
|
|
|
+void ResourceGroupImpl::initBuffers(
|
|
|
+ const InBindings& in, OutBindings& out, U8& count, U& resourcesCount)
|
|
|
+{
|
|
|
+ count = 0;
|
|
|
+
|
|
|
+ for(U i = 0; i < in.getSize(); ++i)
|
|
|
+ {
|
|
|
+ const BufferBinding& binding = in[i];
|
|
|
+
|
|
|
+ if(binding.m_buffer.isCreated())
|
|
|
+ {
|
|
|
+ const BufferImpl& buff = binding.m_buffer->getImplementation();
|
|
|
+ InternalBufferBinding& outBinding = out[count];
|
|
|
+
|
|
|
+ outBinding.m_name = buff.getGlName();
|
|
|
+ outBinding.m_offset = binding.m_offset;
|
|
|
+ outBinding.m_range =
|
|
|
+ (binding.m_range != 0)
|
|
|
+ ? binding.m_range
|
|
|
+ : (buff.m_size - binding.m_offset);
|
|
|
+
|
|
|
+ ANKI_ASSERT(
|
|
|
+ outBinding.m_offset + outBinding.m_range <= buff.m_size);
|
|
|
+ ANKI_ASSERT(outBinding.m_range > 0);
|
|
|
+
|
|
|
+ ++count;
|
|
|
+ ++resourcesCount;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
//==============================================================================
|
|
|
void ResourceGroupImpl::create(const ResourceGroupInitializer& init)
|
|
|
{
|
|
|
- m_in = init;
|
|
|
+ U resourcesCount = 0;
|
|
|
|
|
|
// Init textures & samplers
|
|
|
- m_cache.m_textureNamesCount = 0;
|
|
|
- m_cache.m_allSamplersZero = true;
|
|
|
- for(U i = 0; i < MAX_TEXTURE_BINDINGS; ++i)
|
|
|
+ m_textureNamesCount = 0;
|
|
|
+ m_allSamplersZero = true;
|
|
|
+ for(U i = 0; i < init.m_textures.getSize(); ++i)
|
|
|
{
|
|
|
- if(m_in.m_textures[i].m_texture.isCreated())
|
|
|
+ if(init.m_textures[i].m_texture.isCreated())
|
|
|
{
|
|
|
- m_cache.m_textureNames[i] =
|
|
|
- m_in.m_textures[i].m_texture->getImplementation().getGlName();
|
|
|
- ++m_cache.m_textureNamesCount;
|
|
|
+ m_textureNames[i] =
|
|
|
+ init.m_textures[i].m_texture->getImplementation().getGlName();
|
|
|
+ ++m_textureNamesCount;
|
|
|
+ ++resourcesCount;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- m_cache.m_textureNames[i] = 0;
|
|
|
+ m_textureNames[i] = 0;
|
|
|
}
|
|
|
|
|
|
- if(m_in.m_textures[i].m_sampler.isCreated())
|
|
|
+ if(init.m_textures[i].m_sampler.isCreated())
|
|
|
{
|
|
|
- m_cache.m_samplerNames[i] =
|
|
|
- m_in.m_textures[i].m_sampler->getImplementation().getGlName();
|
|
|
- m_cache.m_allSamplersZero = false;
|
|
|
+ m_samplerNames[i] =
|
|
|
+ init.m_textures[i].m_sampler->getImplementation().getGlName();
|
|
|
+ m_allSamplersZero = false;
|
|
|
+ ++resourcesCount;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- m_cache.m_samplerNames[i] = 0;
|
|
|
+ m_samplerNames[i] = 0;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// Init buffers
|
|
|
- m_cache.m_ubosCount = 0;
|
|
|
- for(U i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; ++i)
|
|
|
+ initBuffers(init.m_uniformBuffers, m_ubos, m_ubosCount, resourcesCount);
|
|
|
+ initBuffers(init.m_storageBuffers, m_ssbos, m_ssbosCount, resourcesCount);
|
|
|
+
|
|
|
+ // Init vert buffers
|
|
|
+ m_vertBindingsCount = 0;
|
|
|
+ for(U i = 0; i < init.m_vertexBuffers.getSize(); ++i)
|
|
|
{
|
|
|
- if(m_in.m_uniformBuffers[i].m_buffer.isCreated())
|
|
|
+ const BufferBinding& binding = init.m_vertexBuffers[i];
|
|
|
+ if(binding.m_buffer.isCreated())
|
|
|
{
|
|
|
- ++m_cache.m_ubosCount;
|
|
|
+ m_vertBuffNames[i] =
|
|
|
+ binding.m_buffer->getImplementation().getGlName();
|
|
|
+ m_vertBuffOffsets[i] = binding.m_offset;
|
|
|
+
|
|
|
+ ++m_vertBindingsCount;
|
|
|
+ ++resourcesCount;
|
|
|
}
|
|
|
+ else
|
|
|
+ {
|
|
|
+ m_vertBuffNames[i] = 0;
|
|
|
+ m_vertBuffOffsets[i] = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Init index buffer
|
|
|
+ if(init.m_indexBuffer.m_buffer.isCreated())
|
|
|
+ {
|
|
|
+ const BufferImpl& buff =
|
|
|
+ init.m_indexBuffer.m_buffer->getImplementation();
|
|
|
+
|
|
|
+ ANKI_ASSERT(init.m_indexSize == 2 || init.m_indexSize == 4);
|
|
|
+
|
|
|
+ m_indexBuffName = buff.getGlName();
|
|
|
+ m_indexSize = init.m_indexSize;
|
|
|
+ ++resourcesCount;
|
|
|
}
|
|
|
|
|
|
- m_cache.m_ssbosCount = 0;
|
|
|
- for(U i = 0; i < MAX_STORAGE_BUFFER_BINDINGS; ++i)
|
|
|
+ // Hold references
|
|
|
+ initResourceReferences(init, resourcesCount);
|
|
|
+}
|
|
|
+
|
|
|
+//==============================================================================
|
|
|
+void ResourceGroupImpl::initResourceReferences(
|
|
|
+ const ResourceGroupInitializer& init, U refCount)
|
|
|
+{
|
|
|
+ m_refs.create(getAllocator(), refCount);
|
|
|
+
|
|
|
+ U count = 0;
|
|
|
+
|
|
|
+ for(U i = 0; i < init.m_textures.getSize(); ++i)
|
|
|
{
|
|
|
- if(m_in.m_storageBuffers[i].m_buffer.isCreated())
|
|
|
+ if(init.m_textures[i].m_texture.isCreated())
|
|
|
{
|
|
|
- ++m_cache.m_ssbosCount;
|
|
|
+ m_refs[count++] = init.m_textures[i].m_texture;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(init.m_textures[i].m_sampler.isCreated())
|
|
|
+ {
|
|
|
+ m_refs[count++] = init.m_textures[i].m_sampler;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // Init vert buffers
|
|
|
- m_cache.m_vertBindingsCount = 0;
|
|
|
- for(U i = 0; i < MAX_VERTEX_ATTRIBUTES; ++i)
|
|
|
+ for(U i = 0; i < init.m_uniformBuffers.getSize(); ++i)
|
|
|
{
|
|
|
- const BufferBinding& binding = m_in.m_vertexBuffers[i];
|
|
|
+ const BufferBinding& binding = init.m_uniformBuffers[i];
|
|
|
if(binding.m_buffer.isCreated())
|
|
|
{
|
|
|
- m_cache.m_vertBuffNames[i] =
|
|
|
- binding.m_buffer->getImplementation().getGlName();
|
|
|
- m_cache.m_vertBuffOffsets[i] = binding.m_offset;
|
|
|
+ m_refs[count++] = binding.m_buffer;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- ++m_cache.m_vertBindingsCount;
|
|
|
+ for(U i = 0; i < init.m_storageBuffers.getSize(); ++i)
|
|
|
+ {
|
|
|
+ const BufferBinding& binding = init.m_storageBuffers[i];
|
|
|
+ if(binding.m_buffer.isCreated())
|
|
|
+ {
|
|
|
+ m_refs[count++] = binding.m_buffer;
|
|
|
}
|
|
|
- else
|
|
|
+ }
|
|
|
+
|
|
|
+ for(U i = 0; i < init.m_vertexBuffers.getSize(); ++i)
|
|
|
+ {
|
|
|
+ const BufferBinding& binding = init.m_vertexBuffers[i];
|
|
|
+ if(binding.m_buffer.isCreated())
|
|
|
{
|
|
|
- m_cache.m_vertBuffNames[i] = 0;
|
|
|
- m_cache.m_vertBuffOffsets[i] = 0;
|
|
|
+ m_refs[count++] = binding.m_buffer;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ if(init.m_indexBuffer.m_buffer.isCreated())
|
|
|
+ {
|
|
|
+ m_refs[count++] = init.m_indexBuffer.m_buffer;
|
|
|
+ }
|
|
|
+
|
|
|
+ ANKI_ASSERT(refCount == count);
|
|
|
}
|
|
|
|
|
|
//==============================================================================
|
|
|
void ResourceGroupImpl::bind(GlState& state)
|
|
|
{
|
|
|
// Bind textures
|
|
|
- if(m_cache.m_textureNamesCount)
|
|
|
+ if(m_textureNamesCount)
|
|
|
{
|
|
|
glBindTextures(
|
|
|
- 0, m_cache.m_textureNamesCount, &m_cache.m_textureNames[0]);
|
|
|
+ 0, m_textureNamesCount, &m_textureNames[0]);
|
|
|
|
|
|
- if(m_cache.m_allSamplersZero)
|
|
|
+ if(m_allSamplersZero)
|
|
|
{
|
|
|
- glBindSamplers(0, m_cache.m_textureNamesCount, nullptr);
|
|
|
+ glBindSamplers(0, m_textureNamesCount, nullptr);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
glBindSamplers(
|
|
|
- 0, m_cache.m_textureNamesCount, &m_cache.m_samplerNames[0]);
|
|
|
+ 0, m_textureNamesCount, &m_samplerNames[0]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// Uniform buffers
|
|
|
- for(U i = 0; i < m_cache.m_ubosCount; ++i)
|
|
|
+ for(U i = 0; i < m_ubosCount; ++i)
|
|
|
{
|
|
|
- const BufferBinding& binding = m_in.m_uniformBuffers[i];
|
|
|
-
|
|
|
- if(binding.m_buffer.isCreated())
|
|
|
- {
|
|
|
- const BufferImpl& buff = binding.m_buffer->getImplementation();
|
|
|
- PtrSize range = (binding.m_range != 0)
|
|
|
- ? binding.m_range
|
|
|
- : (buff.m_size - binding.m_offset);
|
|
|
- buff.bind(GL_UNIFORM_BUFFER, i, binding.m_offset, range);
|
|
|
- }
|
|
|
+ const auto& binding = m_ubos[i];
|
|
|
+ glBindBufferRange(GL_UNIFORM_BUFFER, i, binding.m_name,
|
|
|
+ binding.m_offset, binding.m_range);
|
|
|
}
|
|
|
|
|
|
// Storage buffers
|
|
|
- for(U i = 0; i < m_cache.m_ssbosCount; ++i)
|
|
|
+ for(U i = 0; i < m_ssbosCount; ++i)
|
|
|
{
|
|
|
- BufferBinding& binding = m_in.m_storageBuffers[i];
|
|
|
-
|
|
|
- if(binding.m_buffer.isCreated())
|
|
|
- {
|
|
|
- const BufferImpl& buff = binding.m_buffer->getImplementation();
|
|
|
- PtrSize range = (binding.m_range != 0)
|
|
|
- ? binding.m_range
|
|
|
- : (buff.m_size - binding.m_offset);
|
|
|
- buff.bind(GL_SHADER_STORAGE_BUFFER, i, binding.m_offset, range);
|
|
|
- }
|
|
|
+ const auto& binding = m_ssbos[i];
|
|
|
+ glBindBufferRange(GL_SHADER_STORAGE_BUFFER, i, binding.m_name,
|
|
|
+ binding.m_offset, binding.m_range);
|
|
|
}
|
|
|
|
|
|
// Vertex buffers
|
|
|
- if(m_cache.m_vertBindingsCount)
|
|
|
+ if(m_vertBindingsCount)
|
|
|
{
|
|
|
glBindVertexBuffers(
|
|
|
- 0, m_cache.m_vertBindingsCount, &m_cache.m_vertBuffNames[0],
|
|
|
- &m_cache.m_vertBuffOffsets[0], &state.m_vertexBindingStrides[0]);
|
|
|
+ 0, m_vertBindingsCount, &m_vertBuffNames[0],
|
|
|
+ &m_vertBuffOffsets[0], &state.m_vertexBindingStrides[0]);
|
|
|
}
|
|
|
|
|
|
// Index buffer
|
|
|
- if(m_in.m_indexBuffer.m_buffer.isCreated())
|
|
|
+ if(m_indexSize > 0)
|
|
|
{
|
|
|
- const BufferImpl& buff =
|
|
|
- m_in.m_indexBuffer.m_buffer->getImplementation();
|
|
|
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buff.getGlName());
|
|
|
-
|
|
|
- ANKI_ASSERT(m_in.m_indexSize == 2 || m_in.m_indexSize == 4);
|
|
|
- state.m_indexSize = m_in.m_indexSize;
|
|
|
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffName);
|
|
|
+ state.m_indexSize = m_indexSize;
|
|
|
}
|
|
|
}
|
|
|
|