[Piglit] [PATCH 1/2] util: provide way to read a texture in ES compatible way

Tapani Pälli tapani.palli at intel.com
Fri May 18 08:29:09 UTC 2018


Any comments? I'm planning to push this in soon to be able to push 
oes_texture_view changes to Mesa.

On 05/11/2018 01:17 PM, Tapani Pälli wrote:
> Implementation supports GL_TEXTURE_2D, GL_TEXTURE_2D_ARRAY
> and affects following functions:
> 
>     - piglit_probe_texel_rect_rgba
>     - piglit_probe_texel_volume_rgba
> 
> Signed-off-by: Tapani Pälli <tapani.palli at intel.com>
> ---
>   tests/util/piglit-util-gl.c | 109 ++++++++++++++++++++++++++++++++++++++++++--
>   1 file changed, 105 insertions(+), 4 deletions(-)
> 
> diff --git a/tests/util/piglit-util-gl.c b/tests/util/piglit-util-gl.c
> index 2443be03e..f6a83e717 100644
> --- a/tests/util/piglit-util-gl.c
> +++ b/tests/util/piglit-util-gl.c
> @@ -1882,6 +1882,99 @@ piglit_probe_image_ubyte(int x, int y, int w, int h, GLenum format,
>   	return 1;
>   }
>   
> +static GLuint
> +create_fbo_from_texture(GLenum target, GLint texture, GLint level, GLint layer)
> +{
> +	GLuint fbo;
> +
> +	glGenFramebuffers(1, &fbo);
> +	glBindFramebuffer(GL_FRAMEBUFFER, fbo);
> +
> +	if (layer > 0) {
> +		glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
> +					  texture, level, layer);
> +	} else {
> +		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
> +				       target, texture, level);
> +	}
> +
> +	assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) ==
> +	       GL_FRAMEBUFFER_COMPLETE);
> +	return fbo;
> +}
> +
> +static GLenum
> +binding_from_target(GLenum target)
> +{
> +	switch (target)	{
> +	case GL_TEXTURE_2D:
> +		return GL_TEXTURE_BINDING_2D;
> +	case GL_TEXTURE_2D_ARRAY:
> +		return GL_TEXTURE_BINDING_2D_ARRAY;
> +	default:
> +		fprintf(stderr, "%s: unsupported target 0x%x\n",
> +			__func__, target);
> +		return 0;
> +	}
> +}
> +
> +/**
> + * Read texels in OpenGL ES compatible way.
> + *
> + * Currently bound texture is attached to a framebuffer object and
> + * contents are read using glReadPixels. Supported targets are
> + * GL_TEXTURE_2D, GL_TEXTURE_2D_ARRAY.
> + */
> +static GLfloat *
> +read_texture(int target, int level, int x, int y, int layer, int w, int h)
> +{
> +	GLint width, height, depth;
> +	GLint current_read_fbo, current_draw_fbo, current_texture;
> +	GLenum binding = binding_from_target(target);
> +	unsigned char *buf;
> +	GLfloat *buffer;
> +	unsigned offset;
> +
> +	assert(binding != 0);
> +
> +	glGetIntegerv(binding, &current_texture);
> +	glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &current_read_fbo);
> +	glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &current_draw_fbo);
> +
> +	assert(target == GL_TEXTURE_2D || target == GL_TEXTURE_2D_ARRAY);
> +
> +	glGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, &width);
> +	glGetTexLevelParameteriv(target, level, GL_TEXTURE_HEIGHT, &height);
> +	glGetTexLevelParameteriv(target, level, GL_TEXTURE_DEPTH, &depth);
> +
> +	buffer = malloc(width * height * depth * 4 * sizeof(GLfloat));
> +	buf = malloc(width * height * depth * 4 * sizeof(unsigned char));
> +
> +	GLuint fbo =
> +		create_fbo_from_texture(target, current_texture, level, layer);
> +	assert(fbo != 0);
> +
> +	/* Offset to the layer we are expected to read. */
> +	offset = layer * (width * height * 4);
> +
> +	glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE,
> +		     buf + offset);
> +
> +	for (unsigned k = offset; k < offset + width * height * 4; k++)
> +		buffer[k] = ((float) buf[k]) / 255.0;
> +
> +	free(buf);
> +
> +	glDeleteFramebuffers(1, &fbo);
> +
> +	/* Restore FBO state. */
> +	glBindFramebuffer(GL_READ_FRAMEBUFFER, current_read_fbo);
> +	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, current_draw_fbo);
> +
> +	return buffer;
> +}
> +
> +
>   /**
>    * Read a texel rectangle from the given location and compare its RGB value to
>    * the given expected values.
> @@ -1957,9 +2050,13 @@ int piglit_probe_texel_rect_rgba(int target, int level, int x, int y,
>   
>   	glGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, &width);
>   	glGetTexLevelParameteriv(target, level, GL_TEXTURE_HEIGHT, &height);
> -	buffer = malloc(width * height * 4 * sizeof(GLfloat));
>   
> -	glGetTexImage(target, level, GL_RGBA, GL_FLOAT, buffer);
> +	if (target == GL_TEXTURE_2D) {
> +		buffer = read_texture(target, level, x, y, 0, w, h);
> +	} else {
> +		buffer = malloc(width * height * 4 * sizeof(GLfloat));
> +		glGetTexImage(target, level, GL_RGBA, GL_FLOAT, buffer);
> +	}
>   
>   	assert(x >= 0);
>   	assert(y >= 0);
> @@ -2021,9 +2118,13 @@ int piglit_probe_texel_volume_rgba(int target, int level, int x, int y, int z,
>   	glGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, &width);
>   	glGetTexLevelParameteriv(target, level, GL_TEXTURE_HEIGHT, &height);
>   	glGetTexLevelParameteriv(target, level, GL_TEXTURE_DEPTH, &depth);
> -	buffer = malloc(width * height * depth * 4 * sizeof(GLfloat));
>   
> -	glGetTexImage(target, level, GL_RGBA, GL_FLOAT, buffer);
> +	if (target == GL_TEXTURE_2D || GL_TEXTURE_2D_ARRAY) {
> +		buffer = read_texture(target, level, x, y, z, w, h);
> +        } else {
> +		buffer = malloc(width * height * depth * 4 * sizeof(GLfloat));
> +		glGetTexImage(target, level, GL_RGBA, GL_FLOAT, buffer);
> +	}
>   
>   	assert(x >= 0);
>   	assert(y >= 0);
> 


More information about the Piglit mailing list