| Message ID | 20260626113325.3218045-6-bryan.odonoghue@linaro.org |
|---|---|
| State | Superseded |
| Headers | show |
| Series |
|
| Related | show |
On 26.06.26 13:33, Bryan O'Donoghue wrote: > The internet box tells me that glTextSubImage2D lets us update a texture's > data only, instead of recreating the texture and uploading data. > > This is a smallish optimisation but we are hunting for every possible cycle > and watt so add the routine as precursor to using it in-place of > createTexture2D on every upload cycle. > > Reviewed-by: Robert Mader <robert.mader@collabora.com> > Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> > --- > include/libcamera/internal/egl.h | 1 + > src/libcamera/egl.cpp | 35 ++++++++++++++++++++++++++++++++ > 2 files changed, 36 insertions(+) > > diff --git a/include/libcamera/internal/egl.h b/include/libcamera/internal/egl.h > index e24a726dc..9b679332c 100644 > --- a/include/libcamera/internal/egl.h > +++ b/include/libcamera/internal/egl.h > @@ -108,6 +108,7 @@ public: > int createInputDMABufTexture2D(eGLImage &eglImage, int fd); > int createOutputDMABufTexture2D(eGLImage &eglImage, int fd); > void createTexture2D(eGLImage &eglImage, void *data); > + void updateTexture2D(eGLImage &eglImage, void *data); > void createOutputTexture2D(eGLImage &eglImage); > > int attachTextureToFBO(eGLImage &eglImage); > diff --git a/src/libcamera/egl.cpp b/src/libcamera/egl.cpp > index 8e8d61813..22f46e92a 100644 > --- a/src/libcamera/egl.cpp > +++ b/src/libcamera/egl.cpp > @@ -329,6 +329,41 @@ bool eGL::isAvailable() > return true; > } > > +/** > + * \brief Update a 2D texture already created > + * \param[in,out] eglImage EGL image to associate with the texture > + * \param[data] Data to update the texture with > + * > + * Updates a 2D texture in VRAM. > + */ > +void eGL::updateTexture2D(eGLImage &eglImage, void *data) > +{ > + GLenum format; > + GLenum type = GL_UNSIGNED_BYTE; > + > + ASSERT(tid_ == Thread::currentId()); > + > + glActiveTexture(eglImage.texture_unit_); > + glBindTexture(GL_TEXTURE_2D, eglImage.texture_); As mentioned before I think it would be better to move this commit after the next so you can use "activateBindTexture()" here. > + > + switch (eglImage.format_) { > + case GL_R16F: > + format = GL_RED; > + type = GL_HALF_FLOAT; > + break; > + case GL_RG8: > + format = GL_RG; > + break; > + case GL_LUMINANCE: > + default: > + format = GL_LUMINANCE; > + break; > + } This should be removed now as well. > + > + // Update an already exsiting texture > + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, eglImage.width_, eglImage.height_, format, type, data); > +} > + > /** > * \brief Create a 2D texture attached to an FBO for render-to-texture > * \param[in,out] eglImage EGL image to associate with the texture Just some suggestions for cleanups - my R-B still holds.
On 26/06/2026 13:09, Robert Mader wrote: > On 26.06.26 13:33, Bryan O'Donoghue wrote: >> The internet box tells me that glTextSubImage2D lets us update a >> texture's >> data only, instead of recreating the texture and uploading data. >> >> This is a smallish optimisation but we are hunting for every possible >> cycle >> and watt so add the routine as precursor to using it in-place of >> createTexture2D on every upload cycle. >> >> Reviewed-by: Robert Mader <robert.mader@collabora.com> >> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> >> --- >> include/libcamera/internal/egl.h | 1 + >> src/libcamera/egl.cpp | 35 ++++++++++++++++++++++++++++++++ >> 2 files changed, 36 insertions(+) >> >> diff --git a/include/libcamera/internal/egl.h b/include/libcamera/ >> internal/egl.h >> index e24a726dc..9b679332c 100644 >> --- a/include/libcamera/internal/egl.h >> +++ b/include/libcamera/internal/egl.h >> @@ -108,6 +108,7 @@ public: >> int createInputDMABufTexture2D(eGLImage &eglImage, int fd); >> int createOutputDMABufTexture2D(eGLImage &eglImage, int fd); >> void createTexture2D(eGLImage &eglImage, void *data); >> + void updateTexture2D(eGLImage &eglImage, void *data); >> void createOutputTexture2D(eGLImage &eglImage); >> int attachTextureToFBO(eGLImage &eglImage); >> diff --git a/src/libcamera/egl.cpp b/src/libcamera/egl.cpp >> index 8e8d61813..22f46e92a 100644 >> --- a/src/libcamera/egl.cpp >> +++ b/src/libcamera/egl.cpp >> @@ -329,6 +329,41 @@ bool eGL::isAvailable() >> return true; >> } >> +/** >> + * \brief Update a 2D texture already created >> + * \param[in,out] eglImage EGL image to associate with the texture >> + * \param[data] Data to update the texture with >> + * >> + * Updates a 2D texture in VRAM. >> + */ >> +void eGL::updateTexture2D(eGLImage &eglImage, void *data) >> +{ >> + GLenum format; >> + GLenum type = GL_UNSIGNED_BYTE; >> + >> + ASSERT(tid_ == Thread::currentId()); >> + >> + glActiveTexture(eglImage.texture_unit_); >> + glBindTexture(GL_TEXTURE_2D, eglImage.texture_); > As mentioned before I think it would be better to move this commit after > the next so you can use "activateBindTexture()" here. Ah, now I get what you said. My brain runs hiberno-english and said `no comprendo` at the last iteration.. >> + >> + switch (eglImage.format_) { >> + case GL_R16F: >> + format = GL_RED; >> + type = GL_HALF_FLOAT; >> + break; >> + case GL_RG8: >> + format = GL_RG; >> + break; >> + case GL_LUMINANCE: >> + default: >> + format = GL_LUMINANCE; >> + break; >> + } > This should be removed now as well. eh. yes >> + >> + // Update an already exsiting texture >> + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, eglImage.width_, >> eglImage.height_, format, type, data); >> +} >> + >> /** >> * \brief Create a 2D texture attached to an FBO for render-to-texture >> * \param[in,out] eglImage EGL image to associate with the texture > Just some suggestions for cleanups - my R-B still holds.
Bryan O'Donoghue <bryan.odonoghue@linaro.org> writes: > The internet box tells me that glTextSubImage2D lets us update a texture's > data only, instead of recreating the texture and uploading data. > > This is a smallish optimisation but we are hunting for every possible cycle > and watt so add the routine as precursor to using it in-place of > createTexture2D on every upload cycle. > > Reviewed-by: Robert Mader <robert.mader@collabora.com> > Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> > --- > include/libcamera/internal/egl.h | 1 + > src/libcamera/egl.cpp | 35 ++++++++++++++++++++++++++++++++ > 2 files changed, 36 insertions(+) > > diff --git a/include/libcamera/internal/egl.h b/include/libcamera/internal/egl.h > index e24a726dc..9b679332c 100644 > --- a/include/libcamera/internal/egl.h > +++ b/include/libcamera/internal/egl.h > @@ -108,6 +108,7 @@ public: > int createInputDMABufTexture2D(eGLImage &eglImage, int fd); > int createOutputDMABufTexture2D(eGLImage &eglImage, int fd); > void createTexture2D(eGLImage &eglImage, void *data); > + void updateTexture2D(eGLImage &eglImage, void *data); > void createOutputTexture2D(eGLImage &eglImage); > > int attachTextureToFBO(eGLImage &eglImage); > diff --git a/src/libcamera/egl.cpp b/src/libcamera/egl.cpp > index 8e8d61813..22f46e92a 100644 > --- a/src/libcamera/egl.cpp > +++ b/src/libcamera/egl.cpp > @@ -329,6 +329,41 @@ bool eGL::isAvailable() > return true; > } > > +/** > + * \brief Update a 2D texture already created > + * \param[in,out] eglImage EGL image to associate with the texture > + * \param[data] Data to update the texture with > + * > + * Updates a 2D texture in VRAM. > + */ > +void eGL::updateTexture2D(eGLImage &eglImage, void *data) > +{ > + GLenum format; Uninitialised. > + GLenum type = GL_UNSIGNED_BYTE; > + > + ASSERT(tid_ == Thread::currentId()); > + > + glActiveTexture(eglImage.texture_unit_); > + glBindTexture(GL_TEXTURE_2D, eglImage.texture_); > + > + switch (eglImage.format_) { > + case GL_R16F: > + format = GL_RED; > + type = GL_HALF_FLOAT; > + break; > + case GL_RG8: > + format = GL_RG; > + break; > + case GL_LUMINANCE: > + default: > + format = GL_LUMINANCE; > + break; > + } > + > + // Update an already exsiting texture C-style s/exsiting/existing/ > + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, eglImage.width_, eglImage.height_, format, type, data); > +} > + > /** > * \brief Create a 2D texture attached to an FBO for render-to-texture > * \param[in,out] eglImage EGL image to associate with the texture
Bryan O'Donoghue <bryan.odonoghue@linaro.org> writes: > The internet box tells me that glTextSubImage2D lets us update a texture's > data only, instead of recreating the texture and uploading data. > > This is a smallish optimisation but we are hunting for every possible cycle > and watt so add the routine as precursor to using it in-place of > createTexture2D on every upload cycle. > > Reviewed-by: Robert Mader <robert.mader@collabora.com> > Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> > --- > include/libcamera/internal/egl.h | 1 + > src/libcamera/egl.cpp | 35 ++++++++++++++++++++++++++++++++ > 2 files changed, 36 insertions(+) > > diff --git a/include/libcamera/internal/egl.h b/include/libcamera/internal/egl.h > index e24a726dc..9b679332c 100644 > --- a/include/libcamera/internal/egl.h > +++ b/include/libcamera/internal/egl.h > @@ -108,6 +108,7 @@ public: > int createInputDMABufTexture2D(eGLImage &eglImage, int fd); > int createOutputDMABufTexture2D(eGLImage &eglImage, int fd); > void createTexture2D(eGLImage &eglImage, void *data); > + void updateTexture2D(eGLImage &eglImage, void *data); > void createOutputTexture2D(eGLImage &eglImage); > > int attachTextureToFBO(eGLImage &eglImage); > diff --git a/src/libcamera/egl.cpp b/src/libcamera/egl.cpp > index 8e8d61813..22f46e92a 100644 > --- a/src/libcamera/egl.cpp > +++ b/src/libcamera/egl.cpp > @@ -329,6 +329,41 @@ bool eGL::isAvailable() > return true; > } > > +/** > + * \brief Update a 2D texture already created > + * \param[in,out] eglImage EGL image to associate with the texture > + * \param[data] Data to update the texture with > + * > + * Updates a 2D texture in VRAM. > + */ > +void eGL::updateTexture2D(eGLImage &eglImage, void *data) > +{ > + GLenum format; > + GLenum type = GL_UNSIGNED_BYTE; > + > + ASSERT(tid_ == Thread::currentId()); > + > + glActiveTexture(eglImage.texture_unit_); > + glBindTexture(GL_TEXTURE_2D, eglImage.texture_); > + > + switch (eglImage.format_) { > + case GL_R16F: > + format = GL_RED; > + type = GL_HALF_FLOAT; > + break; > + case GL_RG8: > + format = GL_RG; > + break; > + case GL_LUMINANCE: > + default: > + format = GL_LUMINANCE; > + break; > + } > + > + // Update an already exsiting texture > + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, eglImage.width_, eglImage.height_, format, type, data); This fails in my environment with GL_INVALID_OPERATION. Which means: GL_INVALID_OPERATION is generated by glTextureSubImage2D if texture is not the name of an existing texture object. Which is misleading because the real cause seems to be that eglImage.format_ is GL_RG, which is not represented in the switch. When I use it instead GL_RG8, it works. > +} > + > /** > * \brief Create a 2D texture attached to an FBO for render-to-texture > * \param[in,out] eglImage EGL image to associate with the texture
2026. 06. 26. 15:59 keltezéssel, Milan Zamazal írta: > Bryan O'Donoghue <bryan.odonoghue@linaro.org> writes: > >> The internet box tells me that glTextSubImage2D lets us update a texture's >> data only, instead of recreating the texture and uploading data. >> >> This is a smallish optimisation but we are hunting for every possible cycle >> and watt so add the routine as precursor to using it in-place of >> createTexture2D on every upload cycle. >> >> Reviewed-by: Robert Mader <robert.mader@collabora.com> >> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> >> --- >> include/libcamera/internal/egl.h | 1 + >> src/libcamera/egl.cpp | 35 ++++++++++++++++++++++++++++++++ >> 2 files changed, 36 insertions(+) >> >> diff --git a/include/libcamera/internal/egl.h b/include/libcamera/internal/egl.h >> index e24a726dc..9b679332c 100644 >> --- a/include/libcamera/internal/egl.h >> +++ b/include/libcamera/internal/egl.h >> @@ -108,6 +108,7 @@ public: >> int createInputDMABufTexture2D(eGLImage &eglImage, int fd); >> int createOutputDMABufTexture2D(eGLImage &eglImage, int fd); >> void createTexture2D(eGLImage &eglImage, void *data); >> + void updateTexture2D(eGLImage &eglImage, void *data); >> void createOutputTexture2D(eGLImage &eglImage); >> >> int attachTextureToFBO(eGLImage &eglImage); >> diff --git a/src/libcamera/egl.cpp b/src/libcamera/egl.cpp >> index 8e8d61813..22f46e92a 100644 >> --- a/src/libcamera/egl.cpp >> +++ b/src/libcamera/egl.cpp >> @@ -329,6 +329,41 @@ bool eGL::isAvailable() >> return true; >> } >> >> +/** >> + * \brief Update a 2D texture already created >> + * \param[in,out] eglImage EGL image to associate with the texture >> + * \param[data] Data to update the texture with >> + * >> + * Updates a 2D texture in VRAM. >> + */ >> +void eGL::updateTexture2D(eGLImage &eglImage, void *data) >> +{ >> + GLenum format; >> + GLenum type = GL_UNSIGNED_BYTE; >> + >> + ASSERT(tid_ == Thread::currentId()); >> + >> + glActiveTexture(eglImage.texture_unit_); >> + glBindTexture(GL_TEXTURE_2D, eglImage.texture_); >> + >> + switch (eglImage.format_) { >> + case GL_R16F: >> + format = GL_RED; >> + type = GL_HALF_FLOAT; >> + break; >> + case GL_RG8: >> + format = GL_RG; >> + break; >> + case GL_LUMINANCE: >> + default: >> + format = GL_LUMINANCE; >> + break; >> + } >> + >> + // Update an already exsiting texture >> + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, eglImage.width_, eglImage.height_, format, type, data); > > This fails in my environment with GL_INVALID_OPERATION. Which means: > > GL_INVALID_OPERATION is generated by glTextureSubImage2D if texture is > not the name of an existing texture object. > > Which is misleading because the real cause seems to be that > eglImage.format_ is GL_RG, which is not represented in the switch. When > I use it instead GL_RG8, it works. I think that's the same issue I'm seeing on thinkpad x1 yoga gen 7 with ov2740: $ MESA_DEBUG=1 cam -c1 -C32 [...] [0:51:49.691397665] [21292] INFO eGL egl.cpp:473 EGL: GL_RENDERER: Mesa Intel(R) Iris(R) Xe Graphics (ADL GT2) [0:51:49.691458648] [21292] INFO eGL egl.cpp:474 EGL: GL_VERSION: OpenGL ES 3.2 Mesa 26.1.3-arch1.2 cam0: Capture 32 frames [0:51:50.300449756] [21292] INFO Debayer debayer_egl.cpp:537 Importing input buffer with DMABuf import failed, falling back to upload 3110.265485 (0.00 fps) cam0-stream0 seq: 000000 bytesused: 8666112 3110.298788 (30.03 fps) cam0-stream0 seq: 000001 bytesused: 8666112 3110.332089 (30.03 fps) cam0-stream0 seq: 000002 bytesused: 8666112 3110.365383 (30.04 fps) cam0-stream0 seq: 000003 bytesused: 8666112 Mesa: error: GL_INVALID_OPERATION in glTexSubImage2D(format = GL_LUMINANCE, type = GL_UNSIGNED_BYTE, internalformat = GL_RG) [0:51:50.434042673] [21292] ERROR eGL debayer_egl.cpp:604 Drawing scene fail 1282 [0:51:50.434290491] [21292] ERROR Debayer debayer_egl.cpp:627 debayerGPU failed [...] > >> +} >> + >> /** >> * \brief Create a 2D texture attached to an FBO for render-to-texture >> * \param[in,out] eglImage EGL image to associate with the texture >
On 30.06.26 12:16, Barnabás Pőcze wrote: > 2026. 06. 26. 15:59 keltezéssel, Milan Zamazal írta: >> Bryan O'Donoghue <bryan.odonoghue@linaro.org> writes: >> >>> The internet box tells me that glTextSubImage2D lets us update a >>> texture's >>> data only, instead of recreating the texture and uploading data. >>> >>> This is a smallish optimisation but we are hunting for every >>> possible cycle >>> and watt so add the routine as precursor to using it in-place of >>> createTexture2D on every upload cycle. >>> >>> Reviewed-by: Robert Mader <robert.mader@collabora.com> >>> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> >>> --- >>> include/libcamera/internal/egl.h | 1 + >>> src/libcamera/egl.cpp | 35 >>> ++++++++++++++++++++++++++++++++ >>> 2 files changed, 36 insertions(+) >>> >>> diff --git a/include/libcamera/internal/egl.h >>> b/include/libcamera/internal/egl.h >>> index e24a726dc..9b679332c 100644 >>> --- a/include/libcamera/internal/egl.h >>> +++ b/include/libcamera/internal/egl.h >>> @@ -108,6 +108,7 @@ public: >>> int createInputDMABufTexture2D(eGLImage &eglImage, int fd); >>> int createOutputDMABufTexture2D(eGLImage &eglImage, int fd); >>> void createTexture2D(eGLImage &eglImage, void *data); >>> + void updateTexture2D(eGLImage &eglImage, void *data); >>> void createOutputTexture2D(eGLImage &eglImage); >>> int attachTextureToFBO(eGLImage &eglImage); >>> diff --git a/src/libcamera/egl.cpp b/src/libcamera/egl.cpp >>> index 8e8d61813..22f46e92a 100644 >>> --- a/src/libcamera/egl.cpp >>> +++ b/src/libcamera/egl.cpp >>> @@ -329,6 +329,41 @@ bool eGL::isAvailable() >>> return true; >>> } >>> +/** >>> + * \brief Update a 2D texture already created >>> + * \param[in,out] eglImage EGL image to associate with the texture >>> + * \param[data] Data to update the texture with >>> + * >>> + * Updates a 2D texture in VRAM. >>> + */ >>> +void eGL::updateTexture2D(eGLImage &eglImage, void *data) >>> +{ >>> + GLenum format; >>> + GLenum type = GL_UNSIGNED_BYTE; >>> + >>> + ASSERT(tid_ == Thread::currentId()); >>> + >>> + glActiveTexture(eglImage.texture_unit_); >>> + glBindTexture(GL_TEXTURE_2D, eglImage.texture_); >>> + >>> + switch (eglImage.format_) { >>> + case GL_R16F: >>> + format = GL_RED; >>> + type = GL_HALF_FLOAT; >>> + break; >>> + case GL_RG8: >>> + format = GL_RG; >>> + break; >>> + case GL_LUMINANCE: >>> + default: >>> + format = GL_LUMINANCE; >>> + break; >>> + } >>> + >>> + // Update an already exsiting texture >>> + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, eglImage.width_, >>> eglImage.height_, format, type, data); >> >> This fails in my environment with GL_INVALID_OPERATION. Which means: >> >> GL_INVALID_OPERATION is generated by glTextureSubImage2D if >> texture is >> not the name of an existing texture object. >> >> Which is misleading because the real cause seems to be that >> eglImage.format_ is GL_RG, which is not represented in the switch. When >> I use it instead GL_RG8, it works. > > I think that's the same issue I'm seeing on thinkpad x1 yoga gen 7 > with ov2740: > > $ MESA_DEBUG=1 cam -c1 -C32 > [...] > [0:51:49.691397665] [21292] INFO eGL egl.cpp:473 EGL: GL_RENDERER: > Mesa Intel(R) Iris(R) Xe Graphics (ADL GT2) > [0:51:49.691458648] [21292] INFO eGL egl.cpp:474 EGL: GL_VERSION: > OpenGL ES 3.2 Mesa 26.1.3-arch1.2 > cam0: Capture 32 frames > [0:51:50.300449756] [21292] INFO Debayer debayer_egl.cpp:537 > Importing input buffer with DMABuf import failed, falling back to upload > 3110.265485 (0.00 fps) cam0-stream0 seq: 000000 bytesused: 8666112 > 3110.298788 (30.03 fps) cam0-stream0 seq: 000001 bytesused: 8666112 > 3110.332089 (30.03 fps) cam0-stream0 seq: 000002 bytesused: 8666112 > 3110.365383 (30.04 fps) cam0-stream0 seq: 000003 bytesused: 8666112 > Mesa: error: GL_INVALID_OPERATION in glTexSubImage2D(format = > GL_LUMINANCE, type = GL_UNSIGNED_BYTE, internalformat = GL_RG) > [0:51:50.434042673] [21292] ERROR eGL debayer_egl.cpp:604 Drawing > scene fail 1282 > [0:51:50.434290491] [21292] ERROR Debayer debayer_egl.cpp:627 > debayerGPU failed > [...] Fortunately this would be fixed by dropping the switch-case and using eglImage.format_ directly in v4, as discussed previously (the block / half-float support will only be needed for multi-pass).
diff --git a/include/libcamera/internal/egl.h b/include/libcamera/internal/egl.h index e24a726dc..9b679332c 100644 --- a/include/libcamera/internal/egl.h +++ b/include/libcamera/internal/egl.h @@ -108,6 +108,7 @@ public: int createInputDMABufTexture2D(eGLImage &eglImage, int fd); int createOutputDMABufTexture2D(eGLImage &eglImage, int fd); void createTexture2D(eGLImage &eglImage, void *data); + void updateTexture2D(eGLImage &eglImage, void *data); void createOutputTexture2D(eGLImage &eglImage); int attachTextureToFBO(eGLImage &eglImage); diff --git a/src/libcamera/egl.cpp b/src/libcamera/egl.cpp index 8e8d61813..22f46e92a 100644 --- a/src/libcamera/egl.cpp +++ b/src/libcamera/egl.cpp @@ -329,6 +329,41 @@ bool eGL::isAvailable() return true; } +/** + * \brief Update a 2D texture already created + * \param[in,out] eglImage EGL image to associate with the texture + * \param[data] Data to update the texture with + * + * Updates a 2D texture in VRAM. + */ +void eGL::updateTexture2D(eGLImage &eglImage, void *data) +{ + GLenum format; + GLenum type = GL_UNSIGNED_BYTE; + + ASSERT(tid_ == Thread::currentId()); + + glActiveTexture(eglImage.texture_unit_); + glBindTexture(GL_TEXTURE_2D, eglImage.texture_); + + switch (eglImage.format_) { + case GL_R16F: + format = GL_RED; + type = GL_HALF_FLOAT; + break; + case GL_RG8: + format = GL_RG; + break; + case GL_LUMINANCE: + default: + format = GL_LUMINANCE; + break; + } + + // Update an already exsiting texture + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, eglImage.width_, eglImage.height_, format, type, data); +} + /** * \brief Create a 2D texture attached to an FBO for render-to-texture * \param[in,out] eglImage EGL image to associate with the texture