Jason1
December 17, 2025, 6:59am
1
GPU Rendering Pipeline Description
GPU Model: BXEP-4-32
Input Process:
Memory Allocation: VI (Video Input) calls SMR allocator to obtain physical memory and writes YUV422 data into this SMR.
DMA Buffer Creation: Register the SMR physical address to create a DMA buffer, then obtain a DMA file descriptor using dma_buf_export and dma_buf_fd.
EGLImage Creation: Create an EGLImage using the DMA file descriptor.
Texture Creation: Create an input texture based on the EGLImage (using DRM_FORMAT_UYVY format).
Output Process:
Memory Allocation: Call SMR API to allocate physical memory as output buffer.
DMA Buffer Registration: Register the SMR physical address to create a DMA buffer and obtain a DMA file descriptor.
EGLImage Creation: Create an EGLImage using the DMA file descriptor.
Texture Creation: Create a texture based on the EGLImage.
FBO Creation: Create a Framebuffer Object (FBO) with the texture (using DRM_FORMAT_RGB888 format).
Rendering Process:
Bind the FBO.
Bind the input texture.
Execute glDrawArrays for rendering.
Fragment Shader Code:
#version 320 es
#extension GL_EXT_YUV_target : enable
in highp vec2 texcoord;
out highp vec3 myFragColor;
uniform highp __samplerExternal2DY2YEXT basetexture;
void main(void)
{
highp vec4 myFragColorYUV = texture(basetexture, texcoord);
myFragColor = vec3(yuv_2_rgb(myFragColorYUV.xyz, itu_601));
}
Issue Encountered:
The actual output image format appears to be BGR888 instead of the expected RGB888 .
Question:
Is this rendering pipeline incorrect? What could be causing the RGB/BGR channel swap in the final output?
Jason1
December 17, 2025, 7:20am
2
I have verified the output format behaviors in two scenarios as follows:
1. Output Format: DRM_FORMAT_ARGB8888
Fragment Shader Code :
glsl
#version 320 es
#extension GL_EXT_YUV_target : enable
in highp vec2 texcoord;
out highp vec4 myFragColor;
uniform highp __samplerExternal2DY2YEXT basetexture;
void main(void)
{
highp vec4 myFragColorYUV = texture(basetexture, texcoord);
myFragColor = vec4(yuv_2_rgb(myFragColorYUV.xyz, itu_601), 1.0);
}
Observation : The actual output image format is RGBA8888 (instead of the expected ARGB8888).
2. Output Format: DRM_FORMAT_BGR888
Fragment Shader Code :
glsl
#version 320 es
#extension GL_EXT_YUV_target : enable
in highp vec2 texcoord;
out highp vec3 myFragColor;
uniform highp __samplerExternal2DY2YEXT basetexture;
void main(void)
{
highp vec4 myFragColorYUV = texture(basetexture, texcoord);
myFragColor = vec3(yuv_2_rgb(myFragColorYUV.xyz, itu_601));
}
Findings :
I had to set the EGL_DMA_BUF_PLANE0_PITCH_EXT attribute to output_image_width * 4; otherwise, the eglCreateImageKHR function would return an error (failed to create EGLImage).
After setting EGL_DMA_BUF_PLANE0_PITCH_EXT = width * 4, the saved image shows offset (misalignment) and horizontal stripe artifacts .
3 When the fragment shader is configured to output myFragColor = vec3(1.0, 0.0, 0.0); (intended to produce pure red), the saved image actually appears blue instead of the expected red.
Hi Jason1,
Thanks for your message, and welcome to the PowerVR Developer Forum!
I would advice comparing your code with our basic PowerVR SDK OpenGL ES example IntroducingPVRCamera , present in Native_SDK/examples/OpenGLES/05_IntroducingPVRCamera at master · powervr-graphics/Native_SDK · GitHub as there are similarities with your application.
We also have a Vulkan sample which shows how to sample different YUV textures in Native_SDK/examples/Vulkan/YCbCrTextureSampling at master · powervr-graphics/Native_SDK · GitHub in case it is of any help.
Best regards,
Alejandro