mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-04 11:20:20 +01:00
checkpoint: code refactoring for glCopyPixels
This commit is contained in:
parent
bdc574c5bd
commit
563584a4ee
1 changed files with 171 additions and 98 deletions
|
|
@ -55,15 +55,21 @@
|
|||
/**
|
||||
* Create a simple fragment shader that does a TEX() instruction to get
|
||||
* the fragment color.
|
||||
* If bitmapMode, use KIL instruction to kill the "0-pixels".
|
||||
*/
|
||||
static struct st_fragment_program *
|
||||
make_fragment_shader(struct st_context *st, GLboolean bitmapMode)
|
||||
{
|
||||
/* only make programs once and re-use */
|
||||
static struct st_fragment_program *progs[2] = { NULL, NULL };
|
||||
GLcontext *ctx = st->ctx;
|
||||
struct st_fragment_program *stfp;
|
||||
struct gl_program *p;
|
||||
GLuint ic = 0;
|
||||
|
||||
if (progs[bitmapMode])
|
||||
return progs[bitmapMode];
|
||||
|
||||
p = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
|
@ -159,6 +165,8 @@ make_fragment_shader(struct st_context *st, GLboolean bitmapMode)
|
|||
st_translate_fragment_program(st, stfp, NULL,
|
||||
stfp->tokens, ST_MAX_SHADER_TOKENS);
|
||||
|
||||
progs[bitmapMode] = stfp;
|
||||
|
||||
return stfp;
|
||||
}
|
||||
|
||||
|
|
@ -166,15 +174,20 @@ make_fragment_shader(struct st_context *st, GLboolean bitmapMode)
|
|||
/**
|
||||
* Create fragment shader that does a TEX() instruction to get a Z
|
||||
* value, then writes to FRAG_RESULT_DEPR.
|
||||
* Pass fragment color through as-is.
|
||||
*/
|
||||
static struct st_fragment_program *
|
||||
make_fragment_shader_z(struct st_context *st)
|
||||
{
|
||||
GLcontext *ctx = st->ctx;
|
||||
struct st_fragment_program *stfp;
|
||||
/* only make programs once and re-use */
|
||||
static struct st_fragment_program *stfp = NULL;
|
||||
struct gl_program *p;
|
||||
GLuint ic = 0;
|
||||
|
||||
if (stfp)
|
||||
return stfp;
|
||||
|
||||
p = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
|
@ -226,16 +239,21 @@ make_fragment_shader_z(struct st_context *st)
|
|||
|
||||
/**
|
||||
* Create a simple vertex shader that just passes through the
|
||||
* vertex position and texcoord (and color).
|
||||
* vertex position and texcoord (and optionally, color).
|
||||
*/
|
||||
static struct st_vertex_program *
|
||||
make_vertex_shader(struct st_context *st, GLboolean passColor)
|
||||
{
|
||||
/* only make programs once and re-use */
|
||||
static struct st_vertex_program *progs[2] = { NULL, NULL };
|
||||
GLcontext *ctx = st->ctx;
|
||||
struct st_vertex_program *stvp;
|
||||
struct gl_program *p;
|
||||
GLuint ic = 0;
|
||||
|
||||
if (progs[passColor])
|
||||
return progs[passColor];
|
||||
|
||||
p = ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0);
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
|
@ -292,6 +310,8 @@ make_vertex_shader(struct st_context *st, GLboolean passColor)
|
|||
st_translate_vertex_program(st, stvp, NULL,
|
||||
stvp->tokens, ST_MAX_SHADER_TOKENS);
|
||||
|
||||
progs[passColor] = stvp;
|
||||
|
||||
return stvp;
|
||||
}
|
||||
|
||||
|
|
@ -311,75 +331,22 @@ _mesa_base_format(GLenum format)
|
|||
|
||||
|
||||
|
||||
/**
|
||||
* Make mipmap tree containing the glDrawPixels image.
|
||||
*/
|
||||
static struct pipe_mipmap_tree *
|
||||
make_mipmap_tree(struct st_context *st,
|
||||
GLsizei width, GLsizei height, GLenum format, GLenum type,
|
||||
const struct gl_pixelstore_attrib *unpack,
|
||||
const GLvoid *pixels)
|
||||
alloc_mipmap_tree(struct st_context *st,
|
||||
GLsizei width, GLsizei height, uint pipeFormat)
|
||||
{
|
||||
struct pipe_context *pipe = st->pipe;
|
||||
const struct gl_texture_format *mformat;
|
||||
const GLbitfield flags = PIPE_SURFACE_FLAG_TEXTURE;
|
||||
struct pipe_mipmap_tree *mt;
|
||||
GLuint pipeFormat, cpp;
|
||||
GLenum baseFormat;
|
||||
|
||||
baseFormat = _mesa_base_format(format);
|
||||
|
||||
mformat = st_ChooseTextureFormat(st->ctx, baseFormat, format, type);
|
||||
assert(mformat);
|
||||
|
||||
pipeFormat = st_mesa_format_to_pipe_format(mformat->MesaFormat);
|
||||
assert(pipeFormat);
|
||||
cpp = st_sizeof_format(pipeFormat);
|
||||
GLuint cpp;
|
||||
|
||||
mt = CALLOC_STRUCT(pipe_mipmap_tree);
|
||||
if (!mt)
|
||||
return NULL;
|
||||
|
||||
if (unpack->BufferObj && unpack->BufferObj->Name) {
|
||||
/*
|
||||
mt->region = buffer_object_region(unpack->BufferObj);
|
||||
*/
|
||||
printf("st_DrawPixels (sourcing from PBO not implemented yet)\n");
|
||||
}
|
||||
else {
|
||||
static const GLuint dstImageOffsets = 0;
|
||||
GLboolean success;
|
||||
GLubyte *dest;
|
||||
GLuint pitch;
|
||||
cpp = st_sizeof_format(pipeFormat);
|
||||
|
||||
/* allocate texture region/storage */
|
||||
mt->region = st->pipe->region_alloc(st->pipe, cpp, width, height, flags);
|
||||
pitch = mt->region->pitch;
|
||||
|
||||
/* map texture region */
|
||||
dest = pipe->region_map(pipe, mt->region);
|
||||
|
||||
/* Put image into texture region.
|
||||
* Note that the image is actually going to be upside down in
|
||||
* the texture. We deal with that with texcoords.
|
||||
*/
|
||||
success = mformat->StoreImage(st->ctx, 2, /* dims */
|
||||
baseFormat, /* baseInternalFormat */
|
||||
mformat, /* gl_texture_format */
|
||||
dest, /* dest */
|
||||
0, 0, 0, /* dstX/Y/Zoffset */
|
||||
pitch * cpp, /* dstRowStride, bytes */
|
||||
&dstImageOffsets, /* dstImageOffsets */
|
||||
width, height, 1, /* size */
|
||||
format, type, /* src format/type */
|
||||
pixels, /* data source */
|
||||
unpack);
|
||||
|
||||
/* unmap */
|
||||
pipe->region_unmap(pipe, mt->region);
|
||||
|
||||
assert(success);
|
||||
}
|
||||
/* allocate texture region/storage */
|
||||
mt->region = st->pipe->region_alloc(st->pipe, cpp, width, height, flags);
|
||||
|
||||
mt->target = PIPE_TEXTURE_2D;
|
||||
mt->internal_format = GL_RGBA;
|
||||
|
|
@ -406,6 +373,98 @@ make_mipmap_tree(struct st_context *st,
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make mipmap tree containing an image for glDrawPixels image.
|
||||
* If 'pixels' is NULL, leave the texture image data undefined.
|
||||
*/
|
||||
static struct pipe_mipmap_tree *
|
||||
make_mipmap_tree(struct st_context *st,
|
||||
GLsizei width, GLsizei height, GLenum format, GLenum type,
|
||||
const struct gl_pixelstore_attrib *unpack,
|
||||
const GLvoid *pixels)
|
||||
{
|
||||
struct pipe_context *pipe = st->pipe;
|
||||
const struct gl_texture_format *mformat;
|
||||
struct pipe_mipmap_tree *mt;
|
||||
GLuint pipeFormat, cpp;
|
||||
GLenum baseFormat;
|
||||
|
||||
baseFormat = _mesa_base_format(format);
|
||||
|
||||
mformat = st_ChooseTextureFormat(st->ctx, baseFormat, format, type);
|
||||
assert(mformat);
|
||||
|
||||
pipeFormat = st_mesa_format_to_pipe_format(mformat->MesaFormat);
|
||||
assert(pipeFormat);
|
||||
cpp = st_sizeof_format(pipeFormat);
|
||||
|
||||
mt = alloc_mipmap_tree(st, width, height, pipeFormat);
|
||||
if (!mt)
|
||||
return NULL;
|
||||
|
||||
if (unpack->BufferObj && unpack->BufferObj->Name) {
|
||||
/*
|
||||
mt->region = buffer_object_region(unpack->BufferObj);
|
||||
*/
|
||||
printf("st_DrawPixels (sourcing from PBO not implemented yet)\n");
|
||||
}
|
||||
|
||||
{
|
||||
static const GLuint dstImageOffsets = 0;
|
||||
GLboolean success;
|
||||
GLuint pitch = mt->region->pitch;
|
||||
GLubyte *dest;
|
||||
|
||||
/* map texture region */
|
||||
dest = pipe->region_map(pipe, mt->region);
|
||||
|
||||
/* Put image into texture region.
|
||||
* Note that the image is actually going to be upside down in
|
||||
* the texture. We deal with that with texcoords.
|
||||
*/
|
||||
success = mformat->StoreImage(st->ctx, 2, /* dims */
|
||||
baseFormat, /* baseInternalFormat */
|
||||
mformat, /* gl_texture_format */
|
||||
dest, /* dest */
|
||||
0, 0, 0, /* dstX/Y/Zoffset */
|
||||
pitch * cpp, /* dstRowStride, bytes */
|
||||
&dstImageOffsets, /* dstImageOffsets */
|
||||
width, height, 1, /* size */
|
||||
format, type, /* src format/type */
|
||||
pixels, /* data source */
|
||||
unpack);
|
||||
|
||||
/* unmap */
|
||||
pipe->region_unmap(pipe, mt->region);
|
||||
assert(success);
|
||||
}
|
||||
|
||||
#if 0
|
||||
mt->target = PIPE_TEXTURE_2D;
|
||||
mt->internal_format = GL_RGBA;
|
||||
mt->format = pipeFormat;
|
||||
mt->first_level = 0;
|
||||
mt->last_level = 0;
|
||||
mt->width0 = width;
|
||||
mt->height0 = height;
|
||||
mt->depth0 = 1;
|
||||
mt->cpp = cpp;
|
||||
mt->compressed = 0;
|
||||
mt->pitch = mt->region->pitch;
|
||||
mt->depth_pitch = 0;
|
||||
mt->total_height = height;
|
||||
mt->level[0].level_offset = 0;
|
||||
mt->level[0].width = width;
|
||||
mt->level[0].height = height;
|
||||
mt->level[0].depth = 1;
|
||||
mt->level[0].nr_images = 1;
|
||||
mt->level[0].image_offset = NULL;
|
||||
mt->refcount = 1;
|
||||
#endif
|
||||
return mt;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
free_mipmap_tree(struct pipe_context *pipe, struct pipe_mipmap_tree *mt)
|
||||
{
|
||||
|
|
@ -804,10 +863,6 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
|
|||
GLenum format, GLenum type,
|
||||
const struct gl_pixelstore_attrib *unpack, const GLvoid *pixels)
|
||||
{
|
||||
static struct st_fragment_program *stfp_c = NULL; /* color */
|
||||
static struct st_fragment_program *stfp_z = NULL; /* z */
|
||||
static struct st_vertex_program *stvp_t = NULL; /* just emit texcoord */
|
||||
static struct st_vertex_program *stvp_c = NULL; /* emit color too */
|
||||
struct st_fragment_program *stfp;
|
||||
struct st_vertex_program *stvp;
|
||||
struct st_context *st = ctx->st;
|
||||
|
|
@ -820,28 +875,12 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
|
|||
return;
|
||||
}
|
||||
|
||||
/* create the fragment programs if needed */
|
||||
if (!stfp_c) {
|
||||
stfp_c = make_fragment_shader(ctx->st, GL_FALSE);
|
||||
}
|
||||
if (!stfp_z) {
|
||||
stfp_z = make_fragment_shader_z(ctx->st);
|
||||
}
|
||||
|
||||
/* and vertex programs */
|
||||
if (!stvp_t) {
|
||||
stvp_t = make_vertex_shader(ctx->st, GL_FALSE);
|
||||
}
|
||||
if (!stvp_c) {
|
||||
stvp_c = make_vertex_shader(ctx->st, GL_TRUE);
|
||||
}
|
||||
|
||||
st_validate_state(st);
|
||||
|
||||
if (format == GL_DEPTH_COMPONENT) {
|
||||
ps = st->state.framebuffer.zbuf;
|
||||
stfp = stfp_z;
|
||||
stvp = stvp_c;
|
||||
stfp = make_fragment_shader_z(ctx->st);
|
||||
stvp = make_vertex_shader(ctx->st, GL_TRUE);
|
||||
color = ctx->Current.RasterColor;
|
||||
}
|
||||
else if (format == GL_STENCIL_INDEX) {
|
||||
|
|
@ -851,8 +890,8 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
|
|||
}
|
||||
else {
|
||||
ps = st->state.framebuffer.cbufs[0];
|
||||
stfp = stfp_c;
|
||||
stvp = stvp_t;
|
||||
stfp = make_fragment_shader(ctx->st, GL_FALSE);
|
||||
stvp = make_vertex_shader(ctx->st, GL_FALSE);
|
||||
color = NULL;
|
||||
}
|
||||
|
||||
|
|
@ -1032,19 +1071,16 @@ static void
|
|||
st_Bitmap(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
|
||||
const struct gl_pixelstore_attrib *unpack, const GLubyte *bitmap )
|
||||
{
|
||||
static struct st_vertex_program *stvp = NULL;
|
||||
static struct st_fragment_program *stfp = NULL;
|
||||
struct st_vertex_program *stvp;
|
||||
struct st_fragment_program *stfp;
|
||||
struct st_context *st = ctx->st;
|
||||
struct pipe_mipmap_tree *mt;
|
||||
|
||||
/* create the fragment program if needed */
|
||||
if (!stfp) {
|
||||
stfp = make_fragment_shader(ctx->st, GL_TRUE);
|
||||
}
|
||||
/* create the fragment program */
|
||||
stfp = make_fragment_shader(ctx->st, GL_TRUE);
|
||||
|
||||
/* and vertex program */
|
||||
if (!stvp) {
|
||||
stvp = make_vertex_shader(ctx->st, GL_TRUE);
|
||||
}
|
||||
stvp = make_vertex_shader(ctx->st, GL_TRUE);
|
||||
|
||||
st_validate_state(st);
|
||||
|
||||
|
|
@ -1138,22 +1174,59 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
|
|||
GLint dstx, GLint dsty, GLenum type)
|
||||
{
|
||||
struct st_context *st = ctx->st;
|
||||
struct pipe_context *pipe = st->pipe;
|
||||
struct st_renderbuffer *rbRead;
|
||||
struct st_vertex_program *stvp;
|
||||
struct st_fragment_program *stfp;
|
||||
struct pipe_surface *psRead;
|
||||
struct pipe_mipmap_tree *mt;
|
||||
GLfloat *color;
|
||||
uint format;
|
||||
|
||||
st_validate_state(st);
|
||||
|
||||
if (type == GL_STENCIL) {
|
||||
/* can't use texturing to do stencil */
|
||||
copy_stencil_pixels(ctx, srcx, srcy, width, height, dstx, dsty);
|
||||
return;
|
||||
}
|
||||
|
||||
/* allocate a texture of size width x height */
|
||||
if (type == GL_COLOR) {
|
||||
rbRead = st_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer);
|
||||
color = NULL;
|
||||
stfp = make_fragment_shader(ctx->st, GL_FALSE);
|
||||
stvp = make_vertex_shader(ctx->st, GL_FALSE);
|
||||
}
|
||||
else {
|
||||
rbRead = st_renderbuffer(ctx->ReadBuffer->_DepthBuffer);
|
||||
color = ctx->Current.Attrib[VERT_ATTRIB_COLOR0];
|
||||
stfp = make_fragment_shader_z(ctx->st);
|
||||
stvp = make_vertex_shader(ctx->st, GL_TRUE);
|
||||
}
|
||||
|
||||
psRead = rbRead->surface;
|
||||
format = psRead->format;
|
||||
|
||||
mt = alloc_mipmap_tree(ctx->st, width, height, format);
|
||||
if (!mt)
|
||||
return;
|
||||
|
||||
/* copy source framebuffer region into mipmap/texture */
|
||||
pipe->region_copy(pipe,
|
||||
mt->region, /* dest */
|
||||
0, /* dest_offset */
|
||||
0, 0, /* destx/y */
|
||||
psRead->region,
|
||||
0, /* src_offset */
|
||||
srcx, srcy, width, height);
|
||||
|
||||
/* blit/copy framebuffer region into texture */
|
||||
|
||||
/* draw textured quad */
|
||||
draw_textured_quad(ctx, dstx, dsty, ctx->Current.RasterPos[2],
|
||||
width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY,
|
||||
mt, stvp, stfp, color);
|
||||
|
||||
|
||||
fprintf(stderr, "st_CopyPixels not implemented yet\n");
|
||||
free_mipmap_tree(st->pipe, mt);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue