------------------------------------------------------------------------------
| 1233 | |
| 1234 | //------------------------------------------------------------------------------ |
| 1235 | bool vtkTextureObject::EmulateTextureBufferWith2DTextures( |
| 1236 | unsigned int numValues, int numComps, int dataType, vtkOpenGLBufferObject* bo) |
| 1237 | { |
| 1238 | assert(this->Context); |
| 1239 | auto ostate = this->GetContext()->GetState(); |
| 1240 | int maxSize = 0; |
| 1241 | ostate->vtkglGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxSize); |
| 1242 | if (numValues > static_cast<unsigned int>(maxSize * maxSize)) |
| 1243 | { |
| 1244 | vtkErrorMacro("Requested texture buffer size exceeds hardware limits. " |
| 1245 | "On the current OpenGL device, GL_MAX_TEXTURE_SIZE x GL_MAX_TEXTURE_SIZE = " |
| 1246 | << maxSize << " values. However, requested size is " << numValues << "."); |
| 1247 | return false; |
| 1248 | } |
| 1249 | else |
| 1250 | { |
| 1251 | unsigned int maxTexDim = maxSize; |
| 1252 | int width = numValues > maxTexDim ? maxTexDim : numValues % (maxTexDim + 1); |
| 1253 | int height = vtkMath::Ceil(static_cast<double>(numValues) / width); |
| 1254 | |
| 1255 | // copy data from 'src' array buffer object to a pbo's unpacked buffer. |
| 1256 | GLenum srcTarget = GL_ARRAY_BUFFER; |
| 1257 | GLenum dstTarget = GL_PIXEL_UNPACK_BUFFER; |
| 1258 | if (bo->GetType() == vtkOpenGLBufferObject::ElementArrayBuffer) |
| 1259 | { |
| 1260 | srcTarget = GL_ELEMENT_ARRAY_BUFFER; |
| 1261 | } |
| 1262 | bo->Bind(); |
| 1263 | // issue 3 (https://registry.khronos.org/OpenGL/extensions/ARB/ARB_pixel_buffer_object.txt) |
| 1264 | // says it's alright to bind any b.o (GL_ARRAY_BUFFER, etc) to unpacked buffer |
| 1265 | // and go ahead with glTexImage, |
| 1266 | // however, issue 4 cautions that some driver implementations |
| 1267 | // may perform sub-optimally. so let's do a b.o->b.o copy instead of shortcuts. |
| 1268 | vtkNew<vtkPixelBufferObject> pbo; |
| 1269 | pbo->SetContext(this->GetContext()); |
| 1270 | pbo->Allocate(dataType, width * height, numComps, vtkPixelBufferObject::UNPACKED_BUFFER); |
| 1271 | pbo->BindToUnPackedBuffer(); |
| 1272 | // transfers within gpu memory space on most GL driver implementations. |
| 1273 | glCopyBufferSubData(srcTarget, dstTarget, 0, 0, bo->GetSize()); |
| 1274 | vtkOpenGLCheckErrors("glCopyBufferSubData "); |
| 1275 | |
| 1276 | // Get rid of the original buffer data |
| 1277 | bo->ReleaseGraphicsResources(); |
| 1278 | // unbind |
| 1279 | pbo->UnBind(); |
| 1280 | |
| 1281 | // source a 2D texture with the pbo. |
| 1282 | const int vtktype = pbo->GetType(); |
| 1283 | bool isIntegral = false; |
| 1284 | switch (vtktype) |
| 1285 | { |
| 1286 | vtkTemplateMacro(isIntegral = std::is_integral<VTK_TT>()); |
| 1287 | } |
| 1288 | this->Create2D(width, height, numComps, pbo, isIntegral); |
| 1289 | return true; |
| 1290 | } |
| 1291 | } |
| 1292 |