// -------------------------------------------------------------------------------------------------------------------- bool TexturedQuadsGLBindless::Init(const std::vector<TexturedQuadsProblem::Vertex>& _vertices, const std::vector<TexturedQuadsProblem::Index>& _indices, const std::vector<TextureDetails*>& _textures, size_t _objectCount) { if (!TexturedQuadsSolution::Init(_vertices, _indices, _textures, _objectCount)) { return false; } // Prerequisites if (glGetTextureHandleARB == nullptr) { console::warn("Unable to initialize solution '%s', requires support for bindless textures (not present).", GetName().c_str()); return false; } // Program const char* kUniformNames[] = { "ViewProjection", "DrawID", "gTex", nullptr }; mProgram = CreateProgramT("textures_gl_bindless_vs.glsl", "textures_gl_bindless_fs.glsl", kUniformNames, &mUniformLocation); if (mProgram == 0) { console::warn("Unable to initialize solution '%s', shader compilation/linking failed.", GetName().c_str()); return false; } // Textures for (auto it = _textures.begin(); it != _textures.end(); ++it) { GLuint tex = NewTex2DFromDetails(*(*it)); if (!tex) { console::warn("Unable to initialize solution '%s', texture creation failed.", GetName().c_str()); return false; } // Needs to be freed later. mTextures.push_back(tex); GLuint64 texHandle = glGetTextureHandleARB(tex); if (texHandle == 0) { console::warn("Unable to initialize solution '%s', couldn't get texture handle.", GetName().c_str()); } mTexHandles.push_back(texHandle); } // Buffers glGenVertexArrays(1, &mVertexArray); glBindVertexArray(mVertexArray); mVertexBuffer = NewBufferFromVector(GL_ARRAY_BUFFER, _vertices, GL_STATIC_DRAW); mIndexBuffer = NewBufferFromVector(GL_ELEMENT_ARRAY_BUFFER, _indices, GL_STATIC_DRAW); glGenBuffers(1, &mTransformBuffer); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, mTransformBuffer); glGenVertexArrays(1, &mVAO); glBindVertexArray(mVAO); return glGetError() == GL_NO_ERROR; }
// -------------------------------------------------------------------------------------------------------------------- bool TexturedQuadsGLSparseBindlessTextureArray::Init(const std::vector<TexturedQuadsProblem::Vertex>& _vertices, const std::vector<TexturedQuadsProblem::Index>& _indices, const std::vector<TextureDetails*>& _textures, size_t _objectCount) { if (!TexturedQuadsSolution::Init(_vertices, _indices, _textures, _objectCount)) { return false; } // Prerequisites if (!mTexManager.Init()) { return false; } if (glGetTextureHandleARB == nullptr) { console::warn("Unable to initialize solution '%s', requires support for bindless textures (not present).", GetName().c_str()); return false; } // Program const char* kUniformNames[] = { "ViewProjection", "DrawID", nullptr }; mProgram = CreateProgramT("textures_gl_sparse_bindless_texture_array_vs.glsl", "textures_gl_sparse_bindless_texture_array_fs.glsl", kUniformNames, &mUniformLocation); if (mProgram == 0) { console::warn("Unable to initialize solution '%s', shader compilation/linking failed.", GetName().c_str()); return false; } // Textures for (auto it = _textures.begin(); it != _textures.end(); ++it) { mTextures.push_back(mTexManager.newTexture2DFromDetails(*it)); } // Buffers mVertexBuffer = NewBufferFromVector(GL_ARRAY_BUFFER, _vertices, GL_STATIC_DRAW); mIndexBuffer = NewBufferFromVector(GL_ELEMENT_ARRAY_BUFFER, _indices, GL_STATIC_DRAW); glGenBuffers(1, &mTransformBuffer); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, mTransformBuffer); auto srcIt = mTextures.cbegin(); std::vector<TexAddress> texAddressContents(_objectCount); for (auto dstIt = texAddressContents.begin(); dstIt != texAddressContents.end(); ++dstIt) { if (srcIt == mTextures.cend()) { srcIt = mTextures.cbegin(); } (*dstIt) = (*srcIt)->GetAddress(); ++srcIt; } mTexAddressBuffer = NewBufferFromVector(GL_SHADER_STORAGE_BUFFER, texAddressContents, GL_DYNAMIC_DRAW); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, mTexAddressBuffer); return glGetError() == GL_NO_ERROR; }
// -------------------------------------------------------------------------------------------------------------------- bool TexturedQuadsGLNaive::Init(const std::vector<TexturedQuadsProblem::Vertex>& _vertices, const std::vector<TexturedQuadsProblem::Index>& _indices, const std::vector<TextureDetails*>& _textures, size_t _objectCount) { if (!TexturedQuadsSolution::Init(_vertices, _indices, _textures, _objectCount)) { return false; } // Program const char* kUniformNames[] = { "ViewProjection", "World", "gTex", nullptr }; mProgram = CreateProgramT("textures_gl_naive_vs.glsl", "textures_gl_naive_fs.glsl", kUniformNames, &mUniformLocation); if (mProgram == 0) { console::warn("Unable to initialize solution '%s', shader compilation/linking failed.", GetName().c_str()); return false; } // Textures for (auto it = _textures.begin(); it != _textures.end(); ++it) { GLuint tex = NewTex2DFromDetails(*(*it)); if (!tex) { console::warn("Unable to initialize solution '%s', texture creation failed.", GetName().c_str()); return false; } // Needs to be freed later. mTextures.push_back(tex); } // Buffers glGenVertexArrays(1, &mVertexArray); glBindVertexArray(mVertexArray); mVertexBuffer = NewBufferFromVector(GL_ARRAY_BUFFER, _vertices, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(TexturedQuadsProblem::Vertex), (void*)offsetof(TexturedQuadsProblem::Vertex, pos)); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedQuadsProblem::Vertex), (void*)offsetof(TexturedQuadsProblem::Vertex, tex)); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); mIndexBuffer = NewBufferFromVector(GL_ELEMENT_ARRAY_BUFFER, _indices, GL_STATIC_DRAW); return GLRenderer::GetApiError() == GL_NO_ERROR; }
// -------------------------------------------------------------------------------------------------------------------- bool TexturedQuadsGLNaiveUniform::Init(const std::vector<TexturedQuadsProblem::Vertex>& _vertices, const std::vector<TexturedQuadsProblem::Index>& _indices, const std::vector<TextureDetails*>& _textures, size_t _objectCount) { if (!TexturedQuadsSolution::Init(_vertices, _indices, _textures, _objectCount)) { return false; } // Program const char* kUniformNames[] = { "ViewProjection", "DrawID", "gTex", nullptr }; mProgram = CreateProgramT("textures_gl_naive_uniform_vs.glsl", "textures_gl_naive_uniform_fs.glsl", kUniformNames, &mUniformLocation); if (mProgram == 0) { console::warn("Unable to initialize solution '%s', shader compilation/linking failed.", GetName().c_str()); return false; } glGenVertexArrays(1, &mVertexArrayObject); glBindVertexArray(mVertexArrayObject); // Textures for (auto it = _textures.begin(); it != _textures.end(); ++it) { GLuint tex = NewTex2DFromDetails(*(*it)); if (!tex) { console::warn("Unable to initialize solution '%s', texture creation failed.", GetName().c_str()); return false; } // Needs to be freed later. mTextures.push_back(tex); } // Buffers mVertexBuffer = NewBufferFromVector(GL_ARRAY_BUFFER, _vertices, GL_STATIC_DRAW); mIndexBuffer = NewBufferFromVector(GL_ELEMENT_ARRAY_BUFFER, _indices, GL_STATIC_DRAW); glGenBuffers(1, &mTransformBuffer); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, mTransformBuffer); return GLRenderer::GetApiError() == GL_NO_ERROR; }
// -------------------------------------------------------------------------------------------------------------------- bool TexturedQuadsGLNoTexUniform::Init(const std::vector<TexturedQuadsProblem::Vertex>& _vertices, const std::vector<TexturedQuadsProblem::Index>& _indices, const std::vector<TextureDetails*>& _textures, size_t _objectCount) { if (!TexturedQuadsSolution::Init(_vertices, _indices, _textures, _objectCount)) { return false; } // Program const char* kUniformNames[] = { "ViewProjection", "DrawID", nullptr }; mProgram = CreateProgramT("textures_gl_notex_uniform_vs.glsl", "textures_gl_notex_uniform_fs.glsl", kUniformNames, &mUniformLocation); if (mProgram == 0) { console::warn("Unable to initialize solution '%s', shader compilation/linking failed.", GetName().c_str()); return false; } glGenVertexArrays(1, &mVertexArrayObject); glBindVertexArray(mVertexArrayObject); // Buffers mVertexBuffer = NewBufferFromVector(GL_ARRAY_BUFFER, _vertices, GL_STATIC_DRAW); mIndexBuffer = NewBufferFromVector(GL_ELEMENT_ARRAY_BUFFER, _indices, GL_STATIC_DRAW); glGenBuffers(1, &mTransformBuffer); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, mTransformBuffer); glGenVertexArrays(1, &mVAO); glBindVertexArray(mVAO); return glGetError() == GL_NO_ERROR; }
// -------------------------------------------------------------------------------------------------------------------- bool TexturedQuadsGLSparseBindlessTextureArrayMultiDraw::Init(const std::vector<TexturedQuadsProblem::Vertex>& _vertices, const std::vector<TexturedQuadsProblem::Index>& _indices, const std::vector<TextureDetails*>& _textures, size_t _objectCount) { if (!TexturedQuadsSolution::Init(_vertices, _indices, _textures, _objectCount)) { return false; } // Prerequisites if (!mTexManager.Init()) { return false; } if (glGetTextureHandleARB == nullptr) { console::warn("Unable to initialize solution '%s', requires support for bindless textures (not present).", GetName().c_str()); return false; } if (mUseShaderDrawParameters && !HasExtension(ARB_shader_draw_parameters)) { console::warn("Unable to initialize solution, ARB_shader_draw_parameters is required but not available."); return false; } // Program mProgram = CreateProgram("textures_gl_sparse_bindless_texture_array_multidraw_vs.glsl", "textures_gl_sparse_bindless_texture_array_multidraw_fs.glsl", mUseShaderDrawParameters ? std::string("#define USE_SHADER_DRAW_PARAMETERS 1\n") : std::string("") ); if (mProgram == 0) { console::warn("Unable to initialize solution '%s', shader compilation/linking failed.", GetName().c_str()); return false; } // Textures for (auto it = _textures.begin(); it != _textures.end(); ++it) { mTextures.push_back(mTexManager.newTexture2DFromDetails(*it)); } // Buffers mVertexBuffer = NewBufferFromVector(GL_ARRAY_BUFFER, _vertices, GL_STATIC_DRAW); mIndexBuffer = NewBufferFromVector(GL_ELEMENT_ARRAY_BUFFER, _indices, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(TexturedQuadsProblem::Vertex), (void*)offsetof(TexturedQuadsProblem::Vertex, pos)); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedQuadsProblem::Vertex), (void*)offsetof(TexturedQuadsProblem::Vertex, tex)); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); // If we aren't using shader draw parameters, use the workaround instead. if (!mUseShaderDrawParameters) { std::vector<uint32_t> drawids(_objectCount); for (uint32_t i = 0; i < _objectCount; ++i) { drawids[i] = i; } mDrawIDBuffer = NewBufferFromVector(GL_ARRAY_BUFFER, drawids, GL_STATIC_DRAW); glVertexAttribIPointer(2, 1, GL_UNSIGNED_INT, sizeof(uint32_t), 0); glVertexAttribDivisor(2, 1); glEnableVertexAttribArray(2); } glGenBuffers(1, &mTransformBuffer); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, mTransformBuffer); auto srcIt = mTextures.cbegin(); std::vector<TexAddress> texAddressContents(_objectCount); for (auto dstIt = texAddressContents.begin(); dstIt != texAddressContents.end(); ++dstIt) { if (srcIt == mTextures.cend()) { srcIt = mTextures.cbegin(); } (*dstIt) = (*srcIt)->GetAddress(); ++srcIt; } mTexAddressBuffer = NewBufferFromVector(GL_SHADER_STORAGE_BUFFER, texAddressContents, GL_DYNAMIC_DRAW); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, mTexAddressBuffer); mCommands.resize(_objectCount); return glGetError() == GL_NO_ERROR; }
// -------------------------------------------------------------------------------------------------------------------- bool TexturedQuadsGLTextureArrayUniform::Init(const std::vector<TexturedQuadsProblem::Vertex>& _vertices, const std::vector<TexturedQuadsProblem::Index>& _indices, const std::vector<TextureDetails*>& _textures, size_t _objectCount) { if (!TexturedQuadsSolution::Init(_vertices, _indices, _textures, _objectCount)) { return false; } // Prerequisites auto numTextures = _textures.size(); if (!mTexManager.Init(false, numTextures)) { return false; } // Program const char* kUniformNames[] = { "ViewProjection", "DrawID", "TexContainer", nullptr }; mProgram = CreateProgramT("textures_gl_texture_array_uniform_vs.glsl", "textures_gl_texture_array_uniform_fs.glsl", kUniformNames, &mUniformLocation); if (mProgram == 0) { console::warn("Unable to initialize solution '%s', shader compilation/linking failed.", GetName().c_str()); return false; } // Textures for (auto it = _textures.begin(); it != _textures.end(); ++it) { mTextures.push_back(mTexManager.newTexture2DFromDetails(*it)); } GLint lastTexId = -1; GLint lastTexUnit = -1; std::vector<DenseTexAddress> texAddress(numTextures); for (size_t i = 0; i < numTextures; ++i) { auto texture = mTextures[i]; auto texId = texture->GetTexId(); if (lastTexId != texId) { lastTexId = texId; lastTexUnit = (GLint) mTexUnits.size(); glActiveTexture(GL_TEXTURE0 + lastTexUnit); glBindTexture(GL_TEXTURE_2D_ARRAY, texId); mTexUnits.push_back(lastTexUnit); } texAddress[i].m_container_index = lastTexUnit; texAddress[i].m_layer = ((float) texture->getSliceNum() + 0.5f) / numTextures; } std::vector<DenseTexAddress> texAddressContents(_objectCount); for (uint32_t i = 0; i < _objectCount; ++i) { texAddressContents[i] = texAddress[i % numTextures]; } mTexAddressBuffer = NewBufferFromVector(GL_SHADER_STORAGE_BUFFER, texAddressContents, GL_DYNAMIC_DRAW); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, mTexAddressBuffer); // Buffers mVertexBuffer = NewBufferFromVector(GL_ARRAY_BUFFER, _vertices, GL_STATIC_DRAW); mIndexBuffer = NewBufferFromVector(GL_ELEMENT_ARRAY_BUFFER, _indices, GL_STATIC_DRAW); glGenBuffers(1, &mTransformBuffer); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, mTransformBuffer); return glGetError() == GL_NO_ERROR; }
// -------------------------------------------------------------------------------------------------------------------- bool TexturedQuadsGLBindlessMultiDraw::Init(const std::vector<TexturedQuadsProblem::Vertex>& _vertices, const std::vector<TexturedQuadsProblem::Index>& _indices, const std::vector<TextureDetails*>& _textures, size_t _objectCount) { if (!TexturedQuadsSolution::Init(_vertices, _indices, _textures, _objectCount)) { return false; } // Prerequisites if (glGetTextureHandleARB == nullptr) { console::warn("Unable to initialize solution '%s', requires support for bindless textures (not present).", GetName().c_str()); return false; } // Programs mProgram = CreateProgram("textures_gl_bindless_multidraw_vs.glsl", "textures_gl_bindless_multidraw_fs.glsl"); if (mProgram == 0) { console::warn("Unable to initialize solution '%s', shader compilation/linking failed.", GetName().c_str()); return false; } // Textures for (auto it = _textures.begin(); it != _textures.end(); ++it) { GLuint tex = NewTex2DFromDetails(*(*it)); if (!tex) { console::warn("Unable to initialize solution '%s', texture creation failed.", GetName().c_str()); return false; } // Needs to be freed later. mTextures.push_back(tex); GLuint64 texHandle = glGetTextureHandleARB(tex); if (texHandle == 0) { console::warn("Unable to initialize solution '%s', couldn't get texture handle.", GetName().c_str()); } mTexHandles.push_back(texHandle); } // Buffers mVertexBuffer = NewBufferFromVector(GL_ARRAY_BUFFER, _vertices, GL_STATIC_DRAW); mIndexBuffer = NewBufferFromVector(GL_ELEMENT_ARRAY_BUFFER, _indices, GL_STATIC_DRAW); glGenBuffers(1, &mTransformBuffer); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, mTransformBuffer); auto srcIt = mTexHandles.cbegin(); std::vector<GLuint64> texAddressContents(_objectCount); for (auto dstIt = texAddressContents.begin(); dstIt != texAddressContents.end(); ++dstIt) { if (srcIt == mTexHandles.cend()) { srcIt = mTexHandles.cbegin(); } (*dstIt) = *srcIt; ++srcIt; } mTexAddressBuffer = NewBufferFromVector(GL_SHADER_STORAGE_BUFFER, texAddressContents, GL_STATIC_DRAW); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, mTexAddressBuffer); mCommands.resize(_objectCount); return GLRenderer::GetApiError() == GL_NO_ERROR; }
// -------------------------------------------------------------------------------------------------------------------- bool TexturedQuadsGLTextureArrayMultiDraw::Init(const std::vector<TexturedQuadsProblem::Vertex>& _vertices, const std::vector<TexturedQuadsProblem::Index>& _indices, const std::vector<TextureDetails*>& _textures, size_t _objectCount) { if (!TexturedQuadsSolution::Init(_vertices, _indices, _textures, _objectCount)) { return false; } // Prerequisites auto numTextures = _textures.size(); if (!mTexManager.Init(false, numTextures)) { return false; } if (mUseShaderDrawParameters && !HasExtension("GL_ARB_shader_draw_parameters")) { console::warn("Unable to initialize solution, ARB_shader_draw_parameters is required but not available."); return false; } // Program const char* kUniformNames[] = { "ViewProjection", "TexContainer", nullptr }; mProgram = CreateProgramT("textures_gl_texture_array_multidraw_vs.glsl", "textures_gl_texture_array_multidraw_fs.glsl", mUseShaderDrawParameters ? std::string("#define USE_SHADER_DRAW_PARAMETERS 1\n") : std::string(""), kUniformNames, &mUniformLocation); if (mProgram == 0) { console::warn("Unable to initialize solution '%s', shader compilation/linking failed.", GetName().c_str()); return false; } // Textures for (auto it = _textures.begin(); it != _textures.end(); ++it) { mTextures.push_back(mTexManager.newTexture2DFromDetails(*it)); } GLint lastTexId = -1; GLint lastTexUnit = -1; std::vector<DenseTexAddress> texAddress(numTextures); for (size_t i = 0; i < numTextures; ++i) { auto texture = mTextures[i]; auto texId = texture->GetTexId(); if (lastTexId != texId) { lastTexId = texId; lastTexUnit = (GLint) mTexUnits.size(); glActiveTexture(GL_TEXTURE0 + lastTexUnit); glBindTexture(GL_TEXTURE_2D_ARRAY, texId); mTexUnits.push_back(lastTexUnit); } texAddress[i].m_container_index = lastTexUnit; texAddress[i].m_layer = ((float) texture->getSliceNum() + 0.5f) / numTextures; } std::vector<DenseTexAddress> texAddressContents(_objectCount); for (uint32_t i = 0; i < _objectCount; ++i) { texAddressContents[i] = texAddress[i % numTextures]; } mTexAddressBuffer = NewBufferFromVector(GL_SHADER_STORAGE_BUFFER, texAddressContents, GL_DYNAMIC_DRAW); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, mTexAddressBuffer); // Buffers glGenVertexArrays(1, &mVertexArray); glBindVertexArray(mVertexArray); mVertexBuffer = NewBufferFromVector(GL_ARRAY_BUFFER, _vertices, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(TexturedQuadsProblem::Vertex), (void*)offsetof(TexturedQuadsProblem::Vertex, pos)); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedQuadsProblem::Vertex), (void*)offsetof(TexturedQuadsProblem::Vertex, tex)); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); // If we aren't using shader draw parameters, use the workaround instead. if (!mUseShaderDrawParameters) { std::vector<uint32_t> drawids(_objectCount); for (uint32_t i = 0; i < _objectCount; ++i) { drawids[i] = i; } mDrawIDBuffer = NewBufferFromVector(GL_ARRAY_BUFFER, drawids, GL_STATIC_DRAW); glVertexAttribIPointer(2, 1, GL_UNSIGNED_INT, sizeof(uint32_t), 0); glVertexAttribDivisor(2, 1); glEnableVertexAttribArray(2); } mIndexBuffer = NewBufferFromVector(GL_ELEMENT_ARRAY_BUFFER, _indices, GL_STATIC_DRAW); glGenBuffers(1, &mTransformBuffer); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, mTransformBuffer); // Set the command buffer size. m_commands.resize(_objectCount); return glGetError() == GL_NO_ERROR; }