Message ID | 20250611013245.133785-34-bryan.odonoghue@linaro.org |
---|---|
State | New |
Headers | show |
Series |
|
Related | show |
On 11/06/2025 02:32, Bryan O'Donoghue wrote: > From: Milan Zamazal <mzamazal@redhat.com> > > The GPU processing supports 8-bit sensor formats and 10/12-bit packed > formats. Support for 10/12-bit unpacked formats is missing, let's add > it. > > 10/12-bit unpacked formats use two adjacent bytes to store the value. > This means the 8-bit shaders can be used if we can modify them for > additional support of 16-bit addressing. This requires the following > modifications: > > - Using GL_RG (two bytes per pixel) instead of GL_LUMINANCE (one byte > per pixel) as the texture format for the given input formats. > > - Setting the texture width to the number of pixels rather than the > number of bytes. > > - Making the definition of `fetch' macro variable, according to the > pixel format. > > - Using only `fetch' for accessing the texture. > > Signed-off-by: Milan Zamazal <mzamazal@redhat.com> > Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> > --- > .../libcamera/internal/shaders/bayer_8.frag | 10 +++- > src/libcamera/software_isp/debayer_egl.cpp | 46 +++++++++++++------ > src/libcamera/software_isp/debayer_egl.h | 2 + > 3 files changed, 44 insertions(+), 14 deletions(-) > > diff --git a/include/libcamera/internal/shaders/bayer_8.frag b/include/libcamera/internal/shaders/bayer_8.frag > index 74ce1509..78c2609c 100644 > --- a/include/libcamera/internal/shaders/bayer_8.frag > +++ b/include/libcamera/internal/shaders/bayer_8.frag > @@ -32,9 +32,17 @@ uniform mat3 ccm; > void main(void) { > vec3 rgb; > > + #if defined(RAW10P) > + #define pixel(p) p.r / 4.0 + p.g * 64.0 > + #define fetch(x, y) pixel(texture2D(tex_y, vec2(x, y))) > + #elif defined(RAW12P) > + #define pixel(p) p.r / 16.0 + p.g * 16.0 > + #define fetch(x, y) pixel(texture2D(tex_y, vec2(x, y))) > + #else > #define fetch(x, y) texture2D(tex_y, vec2(x, y)).r > + #endif > > - float C = texture2D(tex_y, center.xy).r; // ( 0, 0) > + float C = fetch(center.x, center.y); // ( 0, 0) > const vec4 kC = vec4( 4.0, 6.0, 5.0, 5.0) / 8.0; Same feedback I gave to myself "The fragment shader changes and CPU side class changes should be in individual patches, one patch for the shader, one patch for the CPU." > > // Determine which of four types of pixels we are on. > diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp > index b30d2107..71742d84 100644 > --- a/src/libcamera/software_isp/debayer_egl.cpp > +++ b/src/libcamera/software_isp/debayer_egl.cpp > @@ -151,6 +151,8 @@ int DebayerEGL::initBayerShaders(PixelFormat inputFormat, PixelFormat outputForm > } > > // Pixel location parameters > + glFormat_ = GL_LUMINANCE; > + bytesPerPixel_ = 1; > switch (inputFormat) { > case libcamera::formats::SBGGR8: > case libcamera::formats::SBGGR10_CSI2P: > @@ -197,20 +199,38 @@ int DebayerEGL::initBayerShaders(PixelFormat inputFormat, PixelFormat outputForm > case libcamera::formats::SGRBG10_CSI2P: > case libcamera::formats::SRGGB10_CSI2P: > egl_.pushEnv(shaderEnv, "#define RAW10P"); > - fragmentShaderData = bayer_1x_packed_frag; > - fragmentShaderDataLen = bayer_1x_packed_frag_len; > - vertexShaderData = identity_vert; > - vertexShaderDataLen = identity_vert_len; > + if (BayerFormat::fromPixelFormat(inputFormat).packing == BayerFormat::Packing::None) { > + fragmentShaderData = bayer_8_frag; > + fragmentShaderDataLen = bayer_8_frag_len; > + vertexShaderData = bayer_8_vert; > + vertexShaderDataLen = bayer_8_vert_len; > + glFormat_ = GL_RG; > + bytesPerPixel_ = 2; > + } else { > + fragmentShaderData = bayer_1x_packed_frag; > + fragmentShaderDataLen = bayer_1x_packed_frag_len; > + vertexShaderData = identity_vert; > + vertexShaderDataLen = identity_vert_len; > + } Ah I see the 8bpp stuff should be unaffected by your change now. Good stuff. Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> --- bod
diff --git a/include/libcamera/internal/shaders/bayer_8.frag b/include/libcamera/internal/shaders/bayer_8.frag index 74ce1509..78c2609c 100644 --- a/include/libcamera/internal/shaders/bayer_8.frag +++ b/include/libcamera/internal/shaders/bayer_8.frag @@ -32,9 +32,17 @@ uniform mat3 ccm; void main(void) { vec3 rgb; + #if defined(RAW10P) + #define pixel(p) p.r / 4.0 + p.g * 64.0 + #define fetch(x, y) pixel(texture2D(tex_y, vec2(x, y))) + #elif defined(RAW12P) + #define pixel(p) p.r / 16.0 + p.g * 16.0 + #define fetch(x, y) pixel(texture2D(tex_y, vec2(x, y))) + #else #define fetch(x, y) texture2D(tex_y, vec2(x, y)).r + #endif - float C = texture2D(tex_y, center.xy).r; // ( 0, 0) + float C = fetch(center.x, center.y); // ( 0, 0) const vec4 kC = vec4( 4.0, 6.0, 5.0, 5.0) / 8.0; // Determine which of four types of pixels we are on. diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp index b30d2107..71742d84 100644 --- a/src/libcamera/software_isp/debayer_egl.cpp +++ b/src/libcamera/software_isp/debayer_egl.cpp @@ -151,6 +151,8 @@ int DebayerEGL::initBayerShaders(PixelFormat inputFormat, PixelFormat outputForm } // Pixel location parameters + glFormat_ = GL_LUMINANCE; + bytesPerPixel_ = 1; switch (inputFormat) { case libcamera::formats::SBGGR8: case libcamera::formats::SBGGR10_CSI2P: @@ -197,20 +199,38 @@ int DebayerEGL::initBayerShaders(PixelFormat inputFormat, PixelFormat outputForm case libcamera::formats::SGRBG10_CSI2P: case libcamera::formats::SRGGB10_CSI2P: egl_.pushEnv(shaderEnv, "#define RAW10P"); - fragmentShaderData = bayer_1x_packed_frag; - fragmentShaderDataLen = bayer_1x_packed_frag_len; - vertexShaderData = identity_vert; - vertexShaderDataLen = identity_vert_len; + if (BayerFormat::fromPixelFormat(inputFormat).packing == BayerFormat::Packing::None) { + fragmentShaderData = bayer_8_frag; + fragmentShaderDataLen = bayer_8_frag_len; + vertexShaderData = bayer_8_vert; + vertexShaderDataLen = bayer_8_vert_len; + glFormat_ = GL_RG; + bytesPerPixel_ = 2; + } else { + fragmentShaderData = bayer_1x_packed_frag; + fragmentShaderDataLen = bayer_1x_packed_frag_len; + vertexShaderData = identity_vert; + vertexShaderDataLen = identity_vert_len; + } break; case libcamera::formats::SBGGR12_CSI2P: case libcamera::formats::SGBRG12_CSI2P: case libcamera::formats::SGRBG12_CSI2P: case libcamera::formats::SRGGB12_CSI2P: egl_.pushEnv(shaderEnv, "#define RAW12P"); - fragmentShaderData = bayer_1x_packed_frag; - fragmentShaderDataLen = bayer_1x_packed_frag_len; - vertexShaderData = identity_vert; - vertexShaderDataLen = identity_vert_len; + if (BayerFormat::fromPixelFormat(inputFormat).packing == BayerFormat::Packing::None) { + fragmentShaderData = bayer_8_frag; + fragmentShaderDataLen = bayer_8_frag_len; + vertexShaderData = bayer_8_vert; + vertexShaderDataLen = bayer_8_vert_len; + glFormat_ = GL_RG; + bytesPerPixel_ = 2; + } else { + fragmentShaderData = bayer_1x_packed_frag; + fragmentShaderDataLen = bayer_1x_packed_frag_len; + vertexShaderData = identity_vert; + vertexShaderDataLen = identity_vert_len; + } break; default: goto invalid_fmt; @@ -430,7 +450,7 @@ void DebayerEGL::setShaderVariableValues(void) GLfloat firstRed[] = { firstRed_x_, firstRed_y_ }; GLfloat imgSize[] = { (GLfloat)width_, (GLfloat)height_ }; - GLfloat Step[] = { 1.0f / (inputConfig_.stride - 1), + GLfloat Step[] = { static_cast<float>(bytesPerPixel_) / (inputConfig_.stride - 1), 1.0f / (height_ - 1) }; GLfloat Stride = 1.0f; GLfloat projIdentityMatrix[] = { @@ -507,7 +527,7 @@ void DebayerEGL::debayerGPU(MappedFrameBuffer &in, MappedFrameBuffer &out, Debay // Greate a standard texture // we will replace this with the DMA version at some point - egl_.createTexture2D(eglImageBayerIn_, inputConfig_.stride, height_, in.planes()[0].data()); + egl_.createTexture2D(eglImageBayerIn_, glFormat_, inputConfig_.stride / bytesPerPixel_, height_, in.planes()[0].data()); // Populate bayer parameters if (ccmEnabled_) { @@ -518,9 +538,9 @@ void DebayerEGL::debayerGPU(MappedFrameBuffer &in, MappedFrameBuffer &out, Debay }; glUniformMatrix3fv(ccmUniformDataIn_, 1, GL_FALSE, ccm); } else { - egl_.createTexture2D(eglImageRedLookup_, DebayerParams::kRGBLookupSize, 1, ¶ms.red); - egl_.createTexture2D(eglImageGreenLookup_, DebayerParams::kRGBLookupSize, 1, ¶ms.green); - egl_.createTexture2D(eglImageBlueLookup_, DebayerParams::kRGBLookupSize, 1, ¶ms.blue); + egl_.createTexture2D(eglImageRedLookup_, GL_LUMINANCE, DebayerParams::kRGBLookupSize, 1, ¶ms.red); + egl_.createTexture2D(eglImageGreenLookup_, GL_LUMINANCE, DebayerParams::kRGBLookupSize, 1, ¶ms.green); + egl_.createTexture2D(eglImageBlueLookup_, GL_LUMINANCE, DebayerParams::kRGBLookupSize, 1, ¶ms.blue); } // Setup the scene diff --git a/src/libcamera/software_isp/debayer_egl.h b/src/libcamera/software_isp/debayer_egl.h index 94bc6fc4..56f5434a 100644 --- a/src/libcamera/software_isp/debayer_egl.h +++ b/src/libcamera/software_isp/debayer_egl.h @@ -150,6 +150,8 @@ private: GBM gbmSurface_; uint32_t width_; uint32_t height_; + GLint glFormat_; + unsigned int bytesPerPixel_; GLfloat vcoordinates[DEBAYER_OPENGL_COORDS][2] = { { -1.0f, -1.0f },