[2.2] TextureGpu pixel format for PF_R3G3B2 Topic is solved

Discussion area about developing with Ogre-Next (2.1, 2.2 and beyond)


Post Reply
dermont
Bugbear
Posts: 812
Joined: Thu Dec 09, 2004 2:51 am
x 42

[2.2] TextureGpu pixel format for PF_R3G3B2

Post by dermont »

I'm rendering a video with a single texture(glsl) for yuv/rgba/grey(planar/packed) using ffmpeg/ogrev2.2 and a slightly modified version of HlmsUnlit.

https://ibb.co/mxCn0z
https://ibb.co/cQwfLz
https://ibb.co/hBCbtK
https://ibb.co/fuf97z
https://ibb.co/hKQ3Ze

I'm testing other video/pixel formats. What is the equivalent TextureGpu pixel format for PF_R3G3B2? I can't seem to find it. I've tried PFG_R8_UNORM with bitwise operators and failed, also PFG_R8_UINT.

Code: Select all

AV_PIX_FMT_RGB8 	packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb)
AV_PIX_FMT_BGR8 	packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb)

opengl_format_desc[] = {
   { AV_PIX_FMT_RGB8,       &FF_OPENGL_FRAGMENT_SHADER_RGB_PACKET,  GL_RGB, FF_GL_UNSIGNED_BYTE_3_3_2 },
   { AV_PIX_FMT_BGR8,       &FF_OPENGL_FRAGMENT_SHADER_RGB_PACKET,  GL_RGB, FF_GL_UNSIGNED_BYTE_2_3_3_REV },
This is the output from PFG_R8_UINT:
https://ibb.co/io90Ee

This is the relevant parts of the shader:

Code: Select all

#if 0
	***	hlms_uv_count0	2
	***	none_filter_idx	0
	***	hlms_uv_count	1
	***	PsoBlendblock	2
	***	diffuse_map0_idx	0
	***	hlms_disable_stage	0
	***	glsl	635204550
	***	uv_diffuse0	0
	***	out_uv_count	1
	***	hlms_high_quality	0
	***	rgbap_count	0
	***	num_array_textures	1
	***	PsoMacroblock	4
	***	alpha_test	0
	***	glsles	1070293233
	***	out_uv0_out_uv	0
	***	sampler_unit_slot_start	2
	***	ellipse_filter_idx	1
	***	diffuse_map0	1
	***	out_uv0_texture_matrix	0
	***	filter_count	2
	***	GL_ARB_shading_language_420pack	1
	***	hlms_alphablend	1
	***	num_textures	0
	***	hlms_shadow_uses_depth_texture	0
	***	diffuse_map0_array	1
	***	hlms_tangent	0
	***	hlms_bones_per_vertex	0
	***	out_uv0_tex_unit	0
	***	materials_per_buffer	819
	***	border_filter_idx	0
	***	hlms_skeleton	0
	***	rgba_count	1
	***	out_uv0_source_uv	0
	***	syntax	635204550
	***	metal	-1698855755
	***	gamma	1
	***	GL_ARB_base_instance	1
	***	diffuse_map	1
	***	array_texture_bind0	2
	***	GL3+	450
	***	hlms_render_depth_only	0
	***	video	1
	***	hlms_qtangent	0
	***	out_uv_half_count0	2
	***	diffuse	0
	***	out_uv_half_count	1
	***	hlms_normal	0
	***	num_samplers	1
	***	hlsl	-334286542
	***	yuvp_count	0
	***	yuv_count	0
	***	GL_ARB_texture_buffer_range	1
	DONE DUMPING PROPERTIES
	***	videochroma_idx10	vec3(3,1,1)
	***	blend_mode_idx3	@insertpiece( NormalNonPremul)
	***	videochroma_idx8	vec3(3,1,1)
	***	videochroma_idx7	vec3(3,1,1)
	***	videoformat_idx12	@insertpiece(pixelformat_none)
	***	uv_diffuse_swizzle0	xy
	***	videoformat_idx14	@insertpiece(pixelformat_none)
	***	videochroma_idx13	vec3(3,1,1)
	***	colourspace_idx14	@insertpiece(colourSpaceBt709)
	***	colourspace_idx0	@insertpiece(colourSpaceBt709)
	***	blend_mode_idx11	@insertpiece( NormalNonPremul)
	***	videoformattype_idx12	@insertpiece(none_video)
	***	blend_mode_idx2	@insertpiece( NormalNonPremul)
	***	videoformat_idx15	@insertpiece(pixelformat_none)
	***	blend_mode_idx14	@insertpiece( NormalNonPremul)
	***	videochroma_idx0	vec3(1,1,1)
	***	blend_mode_idx5	@insertpiece( NormalNonPremul)
	***	colourspace_idx13	@insertpiece(colourSpaceBt709)
	***	colourspace_idx6	@insertpiece(colourSpaceBt709)
	***	videoformattype_idx15	@insertpiece(none_video)
	***	videoformattype_idx0	@insertpiece(rgbU_video)
	***	videochroma_idx6	vec3(3,1,1)
	***	colourspace_idx3	@insertpiece(colourSpaceBt709)
	***	blend_mode_idx8	@insertpiece( NormalNonPremul)
	***	videoformat_idx13	@insertpiece(pixelformat_none)
	***	colourspace_idx12	@insertpiece(colourSpaceBt709)
	***	videoformattype_idx13	@insertpiece(none_video)
	***	videochroma_idx14	vec3(3,1,1)
	***	colourspace_idx7	@insertpiece(colourSpaceBt709)
	***	videoformattype_idx9	@insertpiece(none_video)
	***	videoformattype_idx4	@insertpiece(none_video)
	***	videoformattype_idx1	@insertpiece(none_video)
	***	videoformat_idx4	@insertpiece(pixelformat_none)
	***	videochroma_idx15	vec3(3,1,1)
	***	videochroma_idx1	vec3(3,1,1)
	***	videoformat_idx1	@insertpiece(pixelformat_none)
	***	blend_mode_idx10	@insertpiece( NormalNonPremul)
	***	blend_mode_idx9	@insertpiece( NormalNonPremul)
	***	videoformattype_idx6	@insertpiece(none_video)
	***	blend_mode_idx15	@insertpiece( NormalNonPremul)
	***	videoformat_idx11	@insertpiece(pixelformat_none)
	***	blend_mode_idx6	@insertpiece( NormalNonPremul)
	***	videochroma_idx11	vec3(3,1,1)
	***	colourspace_idx15	@insertpiece(colourSpaceBt709)
	***	colourspace_idx8	@insertpiece(colourSpaceBt709)
	***	videochroma_idx4	vec3(3,1,1)
	***	videoformat_idx2	@insertpiece(pixelformat_none)
	***	videoformat_idx7	@insertpiece(pixelformat_none)
	***	blend_mode_idx7	@insertpiece( NormalNonPremul)
	***	blend_mode_idx1	@insertpiece( NormalNonPremul)
	***	videoformat_idx3	@insertpiece(pixelformat_none)
	***	videoformattype_idx3	@insertpiece(none_video)
	***	videoformat_idx0	@insertpiece(pixelformat_rgb8)
	***	colourspace_idx5	@insertpiece(colourSpaceBt709)
	***	blend_mode_idx0	@insertpiece( NormalNonPremul)
	***	blend_mode_idx12	@insertpiece( NormalNonPremul)
	***	colourspace_idx2	@insertpiece(colourSpaceBt709)
	***	colourspace_idx4	@insertpiece(colourSpaceBt709)
	***	blend_mode_idx4	@insertpiece( NormalNonPremul)
	***	videoformattype_idx14	@insertpiece(none_video)
	***	videoformat_idx10	@insertpiece(pixelformat_none)
	***	videochroma_idx2	vec3(3,1,1)
	***	videoformat_idx9	@insertpiece(pixelformat_none)
	***	videoformattype_idx8	@insertpiece(none_video)
	***	colourspace_idx10	@insertpiece(colourSpaceBt709)
	***	videoformat_idx6	@insertpiece(pixelformat_none)
	***	videoformattype_idx11	@insertpiece(none_video)
	***	videoformattype_idx2	@insertpiece(none_video)
	***	videochroma_idx3	vec3(3,1,1)
	***	videochroma_idx5	vec3(3,1,1)
	***	videoformattype_idx7	@insertpiece(none_video)
	***	videochroma_idx9	vec3(3,1,1)
	***	videoformat_idx8	@insertpiece(pixelformat_none)
	***	blend_mode_idx13	@insertpiece( NormalNonPremul)
	***	videochroma_idx12	vec3(3,1,1)
	***	videoformattype_idx10	@insertpiece(none_video)
	***	diffuse_map0_tex_swizzle	xyzw
	***	colourspace_idx9	@insertpiece(colourSpaceBt709)
	***	colourspace_idx11	@insertpiece(colourSpaceBt709)
	***	videoformat_idx5	@insertpiece(pixelformat_none)
	***	videoformattype_idx5	@insertpiece(none_video)
	***	colourspace_idx1	@insertpiece(colourSpaceBt709)
	DONE DUMPING PIECES
#endif

#version 430 core


    #extension GL_ARB_shading_language_420pack: require
    #define layout_constbuffer(x) layout( std140, x )

    #define bufferFetch texelFetch

#define float2 vec2
#define float3 vec3
#define float4 vec4

#define int2 ivec2
#define int3 ivec3
#define int4 ivec4

#define uint2 uvec2
#define uint3 uvec3
#define uint4 uvec4

#define float3x3 mat3
#define float4x4 mat4

#define mul( x, y ) ((x) * (y))
#define saturate(x) clamp( (x), 0.0, 1.0 )
#define lerp mix
#define INLINE
#define NO_INTERPOLATION_PREFIX flat
#define NO_INTERPOLATION_SUFFIX

#define finalDrawId drawId

#define outVs_Position gl_Position
#define OGRE_SampleLevel( tex, sampler, uv, lod ) textureLod( tex, uv.xy, lod )
#define OGRE_SampleArray2DLevel( tex, sampler, uv, arrayIdx, lod ) textureLod( tex, vec3( uv, arrayIdx ), lod )
#define OGRE_BufferFetch1( buffer, intLocation ) texelFetch( buffer, intLocation ).x



layout(std140) uniform;
#define FRAG_COLOR		0




layout(location = FRAG_COLOR, index = 0) out vec4 outColour;


// START UNIFORM DECLARATION



struct Material
{
	vec4 alpha_test_threshold;
	vec4 diffuse;
	vec3 gamma;
	uvec4 indices0_3;
	uvec4 indices4_7;

	
};



layout_constbuffer(binding = 1) uniform MaterialBuf
{
	Material m[819];
} materialArray;



// ----------------------------------------------
// rgba for usamplerArray
// ----------------------------------------------
uvec4 rgbtorgbU( vec3 uvTextCoords, usampler2DArray sampler )
{
   return texture( sampler, vec3(uvTextCoords.x,uvTextCoords.y,uvTextCoords.z));
}




void fake_gamma(inout vec4 outColour) { 
    outColour.xyz = clamp(outColour.xyz * outColour.xyz,0.0,1.0);
}


void pixelformat_fixesU(inout vec4 outColour, in uvec4 outColourU) { 
    // ffmpeg pixelformat e.g. pixelformat_rgb8
         
    uint col = outColourU.x;
    uint r = ( (col & 244u) >> 0x5u)*(1<<8)/((1<<3)-1);
    uint g = ( (col & 28u ) >> 0x2u)*(1<<8)/((1<<3)-1);
    uint b = ( (col & 3u))*(1<<8)/((1<<2)-1);
    outColour.rgba =             outColour.rgba = clamp(vec4( float(r)/255.0, float(g)/255.0, float(b)/255.0, 1.0 ),0.0,1.0);
    fake_gamma(outColour);
}




//Uniforms that change per Item/Entity
layout_constbuffer(binding = 2) uniform InstanceBuffer
{
	//.x =
	//Contains the material's start index.
	//
	//.y =
	//shadowConstantBias. Send the bias directly to avoid an
	//unnecessary indirection during the shadow mapping pass.
	//Must be loaded with uintBitsToFloat
	//
	//.z =
	//Contains 0 or 1 to index into passBuf.viewProj[]. Only used
	//if hlms_identity_viewproj_dynamic is set.
	uvec4 worldMaterialIdx[4096];
} instance;



// END UNIFORM DECLARATION

in block
{

    flat uint drawId;
	
		vec2 uv0;	
} inPs;


uniform usampler2DArray	textureMapsArray[1];


Material material;

void main()
{
   uint materialId	= instance.worldMaterialIdx[inPs.drawId].x;
    material = materialArray.m[materialId];
    uvec4 outColourU = rgbtorgbU(vec3( inPs.uv0.xy, material.indices0_3.x & 0x0000FFFFu ), textureMapsArray[0]).xyzw;
    pixelformat_fixesU(outColour, outColourU);
}
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5298
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1279
Contact:

Re: [2.2] TextureGpu pixel format for PF_R3G3B2

Post by dark_sylinc »

Hi!

We're exposing the pixel formats modern APIs are exposing, and GL was the only one exposing R3G3B2. Not even Vulkan exposes it. Most likely the HW doesn't actually support this format and is getting emulated (or there is so little interest that it gets overlooked by APIs)

R8_UINT and manually unpacking is exactly the way to go. However your conversion routine is suspicious because it mixes unsigned with signed bitshifts and that can cause chaos. You're also needlessly losing precision in rounding/truncation, e.g. 4 * 256 / 7 = 146.28, not 146.

Because you are converting the values to floats anyway by dividing by 255.0, try taking advantage of that (most GPUs are better at floating point calculations than at integer bit shifts) and let the GPU handle the rounding instead when converting to the target's format:

Code: Select all

uint r = col & 244u;
uint g = col & 28u;
uint b = col & 3u;
outColour.rgb = clamp( vec4( float(r) / 224.0, float(g) / 28.0, float(b) / 3.0, 1.0 ), 0.0, 1.0 );
This is cleaner, more efficient (for GPUs), gives you a more precise result (no rounding/truncation), and may end up cleaning up any potential bug in the routine you posted.

Cheers

Edit: I forgot something important: Your code defines inout outColour as a function argument in at least two functions, which has the same name as the global variable outColour used for storing the pixel shader's final colour. In my experience, that is inviting lots of potential, avoidable driver bugs.

Edit 2: Make sure your sampler is using point filtering. Bilinear filtering a packed R8_UINT may yield undefined or undesired results.
dermont
Bugbear
Posts: 812
Joined: Thu Dec 09, 2004 2:51 am
x 42

Re: [2.2] TextureGpu pixel format for PF_R3G3B2

Post by dermont »

Thanks for the reply and suggestions. I made the changes you provided and it didn't change anything.

I double checked the ffmpeg software encoder(used for converting to different pixel formats) was using point filtering.

I set the samplerBlock filtering to point, that's TFO_NONE?

Code: Select all

samplerBlock.setFiltering(TextureFilterOptions::TFO_NONE);
mDatablock->setSamplerblock( index , samplerBlock );
I created an full screen quad opengl example for GL_R3_G3_B2, the quality was much better but when the screen is resized similar artifacts are
shown the smaller the screen size is.

For Ogre when I resize the renderable containing the video texture I can get similar results to the opengl example at certain xy scales which
don't appear to be related to the video aspect ratio.

I'll just ditch the rgb formats or try double checking my code, the ffmpeg swEncoder's dithering values and do further reading such as:
http://alex-charlton.com/posts/Ditherin ... PU/#fnref6

I'll mark as closed since you answered my original question. Thanks again.
Post Reply