mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	vulkan: perform sRGB-to-linear conversion correctly for premultiplied values
Pre-multipled sRGB values need to be un-multiplied before conversion to linear and then re-multiplied after. Compare shaders/texture.frag. This fixes an issue in labwc where titlebar corners (rendered as ARGB textures) did not match the rest of the titlebar (rendered as a solid wlr_scene_rect).
This commit is contained in:
		
							parent
							
								
									6dce6ae2ed
								
							
						
					
					
						commit
						d98a3eb492
					
				
					 2 changed files with 17 additions and 9 deletions
				
			
		| 
						 | 
				
			
			@ -48,6 +48,10 @@ static float color_to_linear(float non_linear) {
 | 
			
		|||
		non_linear / 12.92;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static float color_to_linear_premult(float non_linear, float alpha) {
 | 
			
		||||
	return (alpha == 0) ? 0 : color_to_linear(non_linear / alpha) * alpha;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void mat3_to_mat4(const float mat3[9], float mat4[4][4]) {
 | 
			
		||||
	memset(mat4, 0, sizeof(float) * 16);
 | 
			
		||||
	mat4[0][0] = mat3[0];
 | 
			
		||||
| 
						 | 
				
			
			@ -439,9 +443,9 @@ static void render_pass_add_rect(struct wlr_render_pass *wlr_pass,
 | 
			
		|||
	// colors in linear space as well (and vulkan then automatically
 | 
			
		||||
	// does the conversion for out sRGB render targets).
 | 
			
		||||
	float linear_color[] = {
 | 
			
		||||
		color_to_linear(options->color.r),
 | 
			
		||||
		color_to_linear(options->color.g),
 | 
			
		||||
		color_to_linear(options->color.b),
 | 
			
		||||
		color_to_linear_premult(options->color.r, options->color.a),
 | 
			
		||||
		color_to_linear_premult(options->color.g, options->color.a),
 | 
			
		||||
		color_to_linear_premult(options->color.b, options->color.a),
 | 
			
		||||
		options->color.a, // no conversion for alpha
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -67,6 +67,10 @@ static float color_to_linear(float non_linear) {
 | 
			
		|||
		non_linear / 12.92;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static float color_to_linear_premult(float non_linear, float alpha) {
 | 
			
		||||
	return (alpha == 0) ? 0 : color_to_linear(non_linear / alpha) * alpha;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void mat3_to_mat4(const float mat3[9], float mat4[4][4]) {
 | 
			
		||||
	memset(mat4, 0, sizeof(float) * 16);
 | 
			
		||||
	mat4[0][0] = mat3[0];
 | 
			
		||||
| 
						 | 
				
			
			@ -1475,9 +1479,9 @@ static void vulkan_clear(struct wlr_renderer *wlr_renderer,
 | 
			
		|||
		// But in other parts of wlroots we just always assume
 | 
			
		||||
		// srgb so that's why we have to convert here.
 | 
			
		||||
		.clearValue.color.float32 = {
 | 
			
		||||
			color_to_linear(color[0]),
 | 
			
		||||
			color_to_linear(color[1]),
 | 
			
		||||
			color_to_linear(color[2]),
 | 
			
		||||
			color_to_linear_premult(color[0], color[3]),
 | 
			
		||||
			color_to_linear_premult(color[1], color[3]),
 | 
			
		||||
			color_to_linear_premult(color[2], color[3]),
 | 
			
		||||
			color[3], // no conversion for alpha
 | 
			
		||||
		},
 | 
			
		||||
	};
 | 
			
		||||
| 
						 | 
				
			
			@ -1553,9 +1557,9 @@ static void vulkan_render_quad_with_matrix(struct wlr_renderer *wlr_renderer,
 | 
			
		|||
	// But in other parts of wlroots we just always assume
 | 
			
		||||
	// srgb so that's why we have to convert here.
 | 
			
		||||
	float linear_color[4];
 | 
			
		||||
	linear_color[0] = color_to_linear(color[0]);
 | 
			
		||||
	linear_color[1] = color_to_linear(color[1]);
 | 
			
		||||
	linear_color[2] = color_to_linear(color[2]);
 | 
			
		||||
	linear_color[0] = color_to_linear_premult(color[0], color[3]);
 | 
			
		||||
	linear_color[1] = color_to_linear_premult(color[1], color[3]);
 | 
			
		||||
	linear_color[2] = color_to_linear_premult(color[2], color[3]);
 | 
			
		||||
	linear_color[3] = color[3]; // no conversion for alpha
 | 
			
		||||
 | 
			
		||||
	vkCmdPushConstants(cb, pipe->layout->vk,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue