Skip to content

Commit e798485

Browse files
committed
Descriptor sets binding should now work without ARB_multi_bind
1 parent e93fdee commit e798485

File tree

2 files changed

+114
-95
lines changed

2 files changed

+114
-95
lines changed

source/Nabla/COpenGLDriver.cpp

Lines changed: 90 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1883,108 +1883,110 @@ void COpenGLDriver::SAuxContext::flushState_descriptors(E_PIPELINE_BIND_POINT _p
18831883
//bind new descriptor sets
18841884
int32_t compatibilityLimit = 0u;
18851885
if (prevLayout && _currentLayout)
1886-
compatibilityLimit = prevLayout->isCompatibleUpToSet(IGPUPipelineLayout::DESCRIPTOR_SET_COUNT-1u, _currentLayout)+1u;
1887-
if (!prevLayout && !_currentLayout)
1886+
compatibilityLimit = prevLayout->isCompatibleUpToSet(IGPUPipelineLayout::DESCRIPTOR_SET_COUNT - 1u, _currentLayout) + 1u;
1887+
if (!prevLayout && !_currentLayout)
18881888
compatibilityLimit = static_cast<int32_t>(IGPUPipelineLayout::DESCRIPTOR_SET_COUNT);
18891889

18901890
int64_t newUboCount = 0u, newSsboCount = 0u, newTexCount = 0u, newImgCount = 0u;
1891-
if (_currentLayout)
1892-
for (uint32_t i=0u; i<static_cast<int32_t>(IGPUPipelineLayout::DESCRIPTOR_SET_COUNT); ++i)
1893-
{
1894-
const auto& first_count = _currentLayout->getMultibindParamsForDescSet(i);
1895-
1891+
if (_currentLayout)
1892+
for (uint32_t i = 0u; i < static_cast<int32_t>(IGPUPipelineLayout::DESCRIPTOR_SET_COUNT); ++i)
18961893
{
1897-
GLsizei count{};
1894+
const auto& first_count = _currentLayout->getMultibindParamsForDescSet(i);
1895+
1896+
{
1897+
GLsizei count{};
18981898

18991899
#define CLAMP_COUNT(resname,limit,printstr) \
19001900
count = (first_count.resname.count - std::max(0, static_cast<int32_t>(first_count.resname.first + first_count.resname.count)-static_cast<int32_t>(limit)))
19011901

1902-
CLAMP_COUNT(ubos, COpenGLExtensionHandler::maxUBOBindings, UBO);
1903-
newUboCount = first_count.ubos.first + count;
1904-
CLAMP_COUNT(ssbos, COpenGLExtensionHandler::maxSSBOBindings, SSBO);
1905-
newSsboCount = first_count.ssbos.first + count;
1906-
CLAMP_COUNT(textures, COpenGLExtensionHandler::maxTextureBindings, texture); //TODO should use maxTextureBindingsCompute for compute
1907-
newTexCount = first_count.textures.first + count;
1908-
CLAMP_COUNT(textureImages, COpenGLExtensionHandler::maxImageBindings, image);
1909-
newImgCount = first_count.textureImages.first + count;
1902+
CLAMP_COUNT(ubos, COpenGLExtensionHandler::maxUBOBindings, UBO);
1903+
newUboCount = first_count.ubos.first + count;
1904+
CLAMP_COUNT(ssbos, COpenGLExtensionHandler::maxSSBOBindings, SSBO);
1905+
newSsboCount = first_count.ssbos.first + count;
1906+
CLAMP_COUNT(textures, COpenGLExtensionHandler::maxTextureBindings, texture); //TODO should use maxTextureBindingsCompute for compute
1907+
newTexCount = first_count.textures.first + count;
1908+
CLAMP_COUNT(textureImages, COpenGLExtensionHandler::maxImageBindings, image);
1909+
newImgCount = first_count.textureImages.first + count;
19101910
#undef CLAMP_COUNT
1911-
}
1911+
}
19121912

1913-
//if prev and curr pipeline layouts are compatible for set N, currState.set[N]==nextState.set[N] and the sets were bound with same dynamic offsets, then binding set N would be redundant
1914-
if ((i < compatibilityLimit) &&
1915-
(effectivelyBoundDescriptors.descSets[i].set == nextState.descriptorsParams[_pbp].descSets[i].set) &&
1916-
(effectivelyBoundDescriptors.descSets[i].dynamicOffsets == nextState.descriptorsParams[_pbp].descSets[i].dynamicOffsets)
1917-
)
1918-
{
1919-
continue;
1920-
}
1913+
//if prev and curr pipeline layouts are compatible for set N, currState.set[N]==nextState.set[N] and the sets were bound with same dynamic offsets, then binding set N would be redundant
1914+
if ((i < compatibilityLimit) &&
1915+
(effectivelyBoundDescriptors.descSets[i].set == nextState.descriptorsParams[_pbp].descSets[i].set) &&
1916+
(effectivelyBoundDescriptors.descSets[i].dynamicOffsets == nextState.descriptorsParams[_pbp].descSets[i].dynamicOffsets)
1917+
)
1918+
{
1919+
continue;
1920+
}
19211921

1922-
const auto multibind_params = nextState.descriptorsParams[_pbp].descSets[i].set ?
1923-
nextState.descriptorsParams[_pbp].descSets[i].set->getMultibindParams() :
1924-
COpenGLDescriptorSet::SMultibindParams{};//all nullptr
1922+
const auto multibind_params = nextState.descriptorsParams[_pbp].descSets[i].set ?
1923+
nextState.descriptorsParams[_pbp].descSets[i].set->getMultibindParams() :
1924+
COpenGLDescriptorSet::SMultibindParams{};//all nullptr
19251925

1926-
const GLsizei localStorageImageCount = newImgCount-first_count.textureImages.first;
1927-
if (localStorageImageCount)
1928-
{
1929-
assert(multibind_params.textureImages.textures);
1930-
extGlBindImageTextures(first_count.textureImages.first, localStorageImageCount, multibind_params.textureImages.textures, nullptr); //formats=nullptr: assuming ARB_multi_bind (or GL>4.4) is always available
1931-
}
1932-
1933-
const GLsizei localTextureCount = newTexCount-first_count.textures.first;
1934-
if (localTextureCount)
1935-
{
1936-
assert(multibind_params.textures.textures && multibind_params.textures.samplers);
1937-
extGlBindTextures(first_count.textures.first, localTextureCount, multibind_params.textures.textures, nullptr); //targets=nullptr: assuming ARB_multi_bind (or GL>4.4) is always available
1938-
extGlBindSamplers(first_count.textures.first, localTextureCount, multibind_params.textures.samplers);
1939-
}
1926+
const GLsizei localStorageImageCount = newImgCount - first_count.textureImages.first;
1927+
if (localStorageImageCount)
1928+
{
1929+
assert(multibind_params.textureImages.textures);
1930+
//formats must be provided since we dont have ARB_multi_bind on ES
1931+
extGlBindImageTextures(first_count.textureImages.first, localStorageImageCount, multibind_params.textureImages.textures, multibind_params.textureImages.formats);
1932+
}
19401933

1941-
const bool nonNullSet = !!nextState.descriptorsParams[_pbp].descSets[i].set;
1942-
const bool useDynamicOffsets = !!nextState.descriptorsParams[_pbp].descSets[i].dynamicOffsets;
1943-
//not entirely sure those MAXes are right
1944-
constexpr size_t MAX_UBO_COUNT = 96ull;
1945-
constexpr size_t MAX_SSBO_COUNT = 91ull;
1946-
constexpr size_t MAX_OFFSETS = MAX_UBO_COUNT>MAX_SSBO_COUNT ? MAX_UBO_COUNT:MAX_SSBO_COUNT;
1947-
GLintptr offsetsArray[MAX_OFFSETS]{};
1948-
GLintptr sizesArray[MAX_OFFSETS]{};
1949-
1950-
const GLsizei localSsboCount = newSsboCount-first_count.ssbos.first;//"local" as in this DS
1951-
if (localSsboCount)
1952-
{
1953-
if (nonNullSet)
1954-
for (GLsizei s=0u;s<localSsboCount; ++s)
1955-
{
1956-
offsetsArray[s] = multibind_params.ssbos.offsets[s];
1957-
sizesArray[s] = multibind_params.ssbos.sizes[s];
1958-
//if it crashes below, it means that there are dynamic Buffer Objects in the DS, but the DS was bound with no (or not enough) dynamic offsets
1959-
//or for some weird reason (bug) descSets[i].set is nullptr, but descSets[i].dynamicOffsets is not
1960-
if (useDynamicOffsets && multibind_params.ssbos.dynOffsetIxs[s] < nextState.descriptorsParams[_pbp].descSets[i].dynamicOffsets->size())
1961-
offsetsArray[s] += nextState.descriptorsParams[_pbp].descSets[i].dynamicOffsets->operator[](multibind_params.ssbos.dynOffsetIxs[s]);
1962-
if (sizesArray[s]==IGPUBufferView::whole_buffer)
1963-
sizesArray[s] = nextState.descriptorsParams[_pbp].descSets[i].set->getSSBO(s)->getSize()-offsetsArray[s];
1964-
}
1965-
assert(multibind_params.ssbos.buffers);
1966-
extGlBindBuffersRange(GL_SHADER_STORAGE_BUFFER, first_count.ssbos.first, localSsboCount, multibind_params.ssbos.buffers, nonNullSet ? offsetsArray:nullptr, nonNullSet ? sizesArray:nullptr);
1967-
}
1934+
const GLsizei localTextureCount = newTexCount - first_count.textures.first;
1935+
if (localTextureCount)
1936+
{
1937+
assert(multibind_params.textures.textures && multibind_params.textures.samplers);
1938+
//targets must be provided since we dont have ARB_multi_bind on ES
1939+
extGlBindTextures(first_count.textures.first, localTextureCount, multibind_params.textures.textures, multibind_params.textures.targets);
1940+
extGlBindSamplers(first_count.textures.first, localTextureCount, multibind_params.textures.samplers);
1941+
}
19681942

1969-
const GLsizei localUboCount = (newUboCount - first_count.ubos.first);//"local" as in this DS
1970-
if (localUboCount)
1971-
{
1972-
if (nonNullSet)
1973-
for (GLsizei s=0u;s<localUboCount; ++s)
1974-
{
1975-
offsetsArray[s] = multibind_params.ubos.offsets[s];
1976-
sizesArray[s] = multibind_params.ubos.sizes[s];
1977-
//if it crashes below, it means that there are dynamic Buffer Objects in the DS, but the DS was bound with no (or not enough) dynamic offsets
1978-
//or for some weird reason (bug) descSets[i].set is nullptr, but descSets[i].dynamicOffsets is not
1979-
if (useDynamicOffsets && multibind_params.ubos.dynOffsetIxs[s] < nextState.descriptorsParams[_pbp].descSets[i].dynamicOffsets->size())
1980-
offsetsArray[s] += nextState.descriptorsParams[_pbp].descSets[i].dynamicOffsets->operator[](multibind_params.ubos.dynOffsetIxs[s]);
1981-
if (sizesArray[s]==IGPUBufferView::whole_buffer)
1982-
sizesArray[s] = nextState.descriptorsParams[_pbp].descSets[i].set->getUBO(s)->getSize()-offsetsArray[s];
1983-
}
1984-
assert(multibind_params.ubos.buffers);
1985-
extGlBindBuffersRange(GL_UNIFORM_BUFFER, first_count.ubos.first, localUboCount, multibind_params.ubos.buffers, nonNullSet ? offsetsArray:nullptr, nonNullSet ? sizesArray:nullptr);
1986-
}
1987-
}
1943+
const bool nonNullSet = !!nextState.descriptorsParams[_pbp].descSets[i].set;
1944+
const bool useDynamicOffsets = !!nextState.descriptorsParams[_pbp].descSets[i].dynamicOffsets;
1945+
//not entirely sure those MAXes are right
1946+
constexpr size_t MAX_UBO_COUNT = 96ull;
1947+
constexpr size_t MAX_SSBO_COUNT = 91ull;
1948+
constexpr size_t MAX_OFFSETS = MAX_UBO_COUNT > MAX_SSBO_COUNT ? MAX_UBO_COUNT : MAX_SSBO_COUNT;
1949+
GLintptr offsetsArray[MAX_OFFSETS]{};
1950+
GLintptr sizesArray[MAX_OFFSETS]{};
1951+
1952+
const GLsizei localSsboCount = newSsboCount - first_count.ssbos.first;//"local" as in this DS
1953+
if (localSsboCount)
1954+
{
1955+
if (nonNullSet)
1956+
for (GLsizei s = 0u; s < localSsboCount; ++s)
1957+
{
1958+
offsetsArray[s] = multibind_params.ssbos.offsets[s];
1959+
sizesArray[s] = multibind_params.ssbos.sizes[s];
1960+
//if it crashes below, it means that there are dynamic Buffer Objects in the DS, but the DS was bound with no (or not enough) dynamic offsets
1961+
//or for some weird reason (bug) descSets[i].set is nullptr, but descSets[i].dynamicOffsets is not
1962+
if (useDynamicOffsets && multibind_params.ssbos.dynOffsetIxs[s] < nextState.descriptorsParams[_pbp].descSets[i].dynamicOffsets->size())
1963+
offsetsArray[s] += nextState.descriptorsParams[_pbp].descSets[i].dynamicOffsets->operator[](multibind_params.ssbos.dynOffsetIxs[s]);
1964+
if (sizesArray[s] == IGPUBufferView::whole_buffer)
1965+
sizesArray[s] = nextState.descriptorsParams[_pbp].descSets[i].set->getSSBO(s)->getSize() - offsetsArray[s];
1966+
}
1967+
assert(multibind_params.ssbos.buffers);
1968+
extGlBindBuffersRange(GL_SHADER_STORAGE_BUFFER, first_count.ssbos.first, localSsboCount, multibind_params.ssbos.buffers, nonNullSet ? offsetsArray : nullptr, nonNullSet ? sizesArray : nullptr);
1969+
}
1970+
1971+
const GLsizei localUboCount = (newUboCount - first_count.ubos.first);//"local" as in this DS
1972+
if (localUboCount)
1973+
{
1974+
if (nonNullSet)
1975+
for (GLsizei s = 0u; s < localUboCount; ++s)
1976+
{
1977+
offsetsArray[s] = multibind_params.ubos.offsets[s];
1978+
sizesArray[s] = multibind_params.ubos.sizes[s];
1979+
//if it crashes below, it means that there are dynamic Buffer Objects in the DS, but the DS was bound with no (or not enough) dynamic offsets
1980+
//or for some weird reason (bug) descSets[i].set is nullptr, but descSets[i].dynamicOffsets is not
1981+
if (useDynamicOffsets && multibind_params.ubos.dynOffsetIxs[s] < nextState.descriptorsParams[_pbp].descSets[i].dynamicOffsets->size())
1982+
offsetsArray[s] += nextState.descriptorsParams[_pbp].descSets[i].dynamicOffsets->operator[](multibind_params.ubos.dynOffsetIxs[s]);
1983+
if (sizesArray[s] == IGPUBufferView::whole_buffer)
1984+
sizesArray[s] = nextState.descriptorsParams[_pbp].descSets[i].set->getUBO(s)->getSize() - offsetsArray[s];
1985+
}
1986+
assert(multibind_params.ubos.buffers);
1987+
extGlBindBuffersRange(GL_UNIFORM_BUFFER, first_count.ubos.first, localUboCount, multibind_params.ubos.buffers, nonNullSet ? offsetsArray : nullptr, nonNullSet ? sizesArray : nullptr);
1988+
}
1989+
}
19881990

19891991
//unbind previous descriptors if needed (if bindings not replaced by new multibind calls)
19901992
if (prevLayout)//if previous pipeline was nullptr, then no descriptors were bound
@@ -2018,7 +2020,6 @@ count = (first_count.resname.count - std::max(0, static_cast<int32_t>(first_coun
20182020
effectivelyBoundDescriptors.descSets[i] = nextState.descriptorsParams[_pbp].descSets[i];
20192021
}
20202022
}
2021-
20222023
void COpenGLDriver::SAuxContext::flushStateGraphics(uint32_t stateBits)
20232024
{
20242025
if (stateBits & GSB_PIPELINE)

src/nbl/video/COpenGLDescriptorSet.h

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,12 @@
77

88
#include "nbl/video/IGPUDescriptorSet.h"
99
#include "nbl/macros.h"
10-
#include "COpenGLExtensionHandler.h"
1110
#include "COpenGLBuffer.h"
1211
#include "COpenGLBufferView.h"
1312
#include "COpenGLImage.h"
1413
#include "COpenGLImageView.h"
1514
#include "nbl/video/COpenGLSampler.h"
1615

17-
#ifdef _NBL_COMPILE_WITH_OPENGL_
1816
namespace nbl
1917
{
2018
namespace video
@@ -36,10 +34,12 @@ class COpenGLDescriptorSet : public IGPUDescriptorSet, protected asset::impl::IE
3634
{
3735
GLuint* textures = nullptr;
3836
GLuint* samplers = nullptr;
37+
GLenum* targets = nullptr;
3938
};
4039
struct SMultibindTextureImages
4140
{
4241
GLuint* textures = nullptr;
42+
GLenum* formats = nullptr;
4343
};
4444

4545
SMultibindBuffers ubos;
@@ -101,6 +101,9 @@ class COpenGLDescriptorSet : public IGPUDescriptorSet, protected asset::impl::IE
101101
std::fill(m_sizes->begin(), m_sizes->end(), ~0u);
102102
m_dynOffsetIxs = core::make_refctd_dynamic_array<core::smart_refctd_dynamic_array<uint32_t> >(m_offsets->size());
103103
std::fill(m_dynOffsetIxs->begin(), m_dynOffsetIxs->end(), 0u);
104+
m_targetsAndFormats = core::make_refctd_dynamic_array<core::smart_refctd_dynamic_array<GLenum> >(textureCount + imageCount);
105+
std::fill(m_targetsAndFormats->begin(), m_targetsAndFormats->begin()+textureCount, GL_TEXTURE_2D);
106+
std::fill(m_targetsAndFormats->begin()+textureCount, m_targetsAndFormats->end(), GL_R8);
104107

105108
const size_t uboNamesOffset = 0ull;
106109
const size_t ssboNamesOffset = uboCount;
@@ -121,7 +124,9 @@ class COpenGLDescriptorSet : public IGPUDescriptorSet, protected asset::impl::IE
121124
setBufMultibindParams(m_multibindParams.ssbos, ssboNamesOffset, ssboBufOffset);
122125
m_multibindParams.textures.textures = (*m_names).data() + texNamesOffset;
123126
m_multibindParams.textures.samplers = (*m_names).data() + samplerNamesOffset;
127+
m_multibindParams.textures.targets = (*m_targetsAndFormats).data();
124128
m_multibindParams.textureImages.textures = (*m_names).data() + imagNamesOffset;
129+
m_multibindParams.textureImages.formats = (*m_targetsAndFormats).data() + textureCount;
125130

126131
// set up dynamic offset redirects
127132
uint32_t dyn_offset_iter = 0u;
@@ -301,7 +306,9 @@ class COpenGLDescriptorSet : public IGPUDescriptorSet, protected asset::impl::IE
301306
}
302307
else if (descriptorType==asset::EDT_COMBINED_IMAGE_SAMPLER)
303308
{
304-
m_multibindParams.textures.textures[offset] = static_cast<COpenGLImageView*>(info.desc.get())->getOpenGLName();
309+
auto* glimgview = static_cast<COpenGLImageView*>(info.desc.get());
310+
311+
m_multibindParams.textures.textures[offset] = glimgview->getOpenGLName();
305312

306313
auto layoutBindings = m_layout->getBindings();
307314
auto layoutBinding = std::lower_bound(layoutBindings.begin(), layoutBindings.end(),
@@ -310,16 +317,27 @@ class COpenGLDescriptorSet : public IGPUDescriptorSet, protected asset::impl::IE
310317
m_multibindParams.textures.samplers[offset] = layoutBinding->samplers ? //take immutable sampler if present
311318
static_cast<COpenGLSampler*>(layoutBinding->samplers[local_iter].get())->getOpenGLName() :
312319
static_cast<COpenGLSampler*>(info.image.sampler.get())->getOpenGLName();
320+
// m_multibindParams.textures.targets[offset] = glimgview->getOpenGLTarget();
313321
}
314322
else if (descriptorType==asset::EDT_UNIFORM_TEXEL_BUFFER)
315323
{
316324
m_multibindParams.textures.textures[offset] = static_cast<COpenGLBufferView*>(info.desc.get())->getOpenGLName();
317325
m_multibindParams.textures.samplers[offset] = 0u;//no sampler for samplerBuffer descriptor
318326
}
319327
else if (descriptorType==asset::EDT_STORAGE_IMAGE)
320-
m_multibindParams.textureImages.textures[offset] = static_cast<COpenGLImageView*>(info.desc.get())->getOpenGLName();
328+
{
329+
auto* glimgview = static_cast<COpenGLImageView*>(info.desc.get());
330+
331+
m_multibindParams.textureImages.textures[offset] = glimgview->getOpenGLName();
332+
m_multibindParams.textureImages.formats[offset] = glimgview->getInternalFormat();
333+
}
321334
else if (descriptorType==asset::EDT_STORAGE_TEXEL_BUFFER)
322-
m_multibindParams.textureImages.textures[offset] = static_cast<COpenGLBufferView*>(info.desc.get())->getOpenGLName();
335+
{
336+
auto* glbufview = static_cast<COpenGLBufferView*>(info.desc.get());
337+
338+
m_multibindParams.textureImages.textures[offset] = glbufview->getOpenGLName();
339+
m_multibindParams.textureImages.formats[offset] = glbufview->getInternalFormat();
340+
}
323341
}
324342

325343
SMultibindParams m_multibindParams;
@@ -330,11 +348,11 @@ class COpenGLDescriptorSet : public IGPUDescriptorSet, protected asset::impl::IE
330348
core::smart_refctd_dynamic_array<GLuint> m_names;
331349
core::smart_refctd_dynamic_array<GLintptr> m_offsets;
332350
core::smart_refctd_dynamic_array<GLsizeiptr> m_sizes;
351+
core::smart_refctd_dynamic_array<GLenum> m_targetsAndFormats;
333352
core::smart_refctd_dynamic_array<uint32_t> m_dynOffsetIxs;
334353
};
335354

336355
}
337356
}
338-
#endif
339357

340358
#endif

0 commit comments

Comments
 (0)