mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 00:58:05 +02:00
st/mesa: add support for layered framebuffers and consolidate code
This is a subset of geometry shaders. It's all about setting first_layer and last_layer correctly. Also some code between st_render_texture and update_framebuffer_state is consolidated. It doesn't use rtt_level and derives the level from dimensions instead as the code in st_atom_framebuffer.c did.
This commit is contained in:
parent
0b3b901cff
commit
d8d67d2e1f
6 changed files with 99 additions and 93 deletions
|
|
@ -43,56 +43,6 @@
|
|||
#include "util/u_format.h"
|
||||
|
||||
|
||||
/**
|
||||
* When doing GL render to texture, we have to be sure that finalize_texture()
|
||||
* didn't yank out the pipe_resource that we earlier created a surface for.
|
||||
* Check for that here and create a new surface if needed.
|
||||
*/
|
||||
static void
|
||||
update_renderbuffer_surface(struct st_context *st,
|
||||
struct st_renderbuffer *strb)
|
||||
{
|
||||
struct pipe_context *pipe = st->pipe;
|
||||
struct pipe_resource *resource = strb->rtt ? strb->rtt->pt : strb->texture;
|
||||
int rtt_width = strb->Base.Width;
|
||||
int rtt_height = strb->Base.Height;
|
||||
enum pipe_format format = st->ctx->Color.sRGBEnabled ? resource->format : util_format_linear(resource->format);
|
||||
|
||||
if (!strb->surface ||
|
||||
strb->surface->texture->nr_samples != strb->Base.NumSamples ||
|
||||
strb->surface->format != format ||
|
||||
strb->surface->texture != resource ||
|
||||
strb->surface->width != rtt_width ||
|
||||
strb->surface->height != rtt_height) {
|
||||
GLuint level;
|
||||
/* find matching mipmap level size */
|
||||
for (level = 0; level <= resource->last_level; level++) {
|
||||
if (u_minify(resource->width0, level) == rtt_width &&
|
||||
u_minify(resource->height0, level) == rtt_height) {
|
||||
struct pipe_surface surf_tmpl;
|
||||
memset(&surf_tmpl, 0, sizeof(surf_tmpl));
|
||||
surf_tmpl.format = format;
|
||||
surf_tmpl.u.tex.level = level;
|
||||
surf_tmpl.u.tex.first_layer = strb->rtt_face + strb->rtt_slice;
|
||||
surf_tmpl.u.tex.last_layer = strb->rtt_face + strb->rtt_slice;
|
||||
|
||||
pipe_surface_reference(&strb->surface, NULL);
|
||||
|
||||
strb->surface = pipe->create_surface(pipe,
|
||||
resource,
|
||||
&surf_tmpl);
|
||||
#if 0
|
||||
printf("-- alloc new surface %d x %d into tex %p\n",
|
||||
strb->surface->width, strb->surface->height,
|
||||
texture);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update framebuffer state (color, depth, stencil, etc. buffers)
|
||||
*/
|
||||
|
|
@ -121,10 +71,10 @@ update_framebuffer_state( struct st_context *st )
|
|||
|
||||
if (strb) {
|
||||
/*printf("--------- framebuffer surface rtt %p\n", strb->rtt);*/
|
||||
if (strb->rtt ||
|
||||
if (strb->is_rtt ||
|
||||
(strb->texture && util_format_is_srgb(strb->texture->format))) {
|
||||
/* rendering to a GL texture, may have to update surface */
|
||||
update_renderbuffer_surface(st, strb);
|
||||
st_update_renderbuffer_surface(st, strb);
|
||||
}
|
||||
|
||||
if (strb->surface) {
|
||||
|
|
@ -144,9 +94,9 @@ update_framebuffer_state( struct st_context *st )
|
|||
*/
|
||||
strb = st_renderbuffer(fb->Attachment[BUFFER_DEPTH].Renderbuffer);
|
||||
if (strb) {
|
||||
if (strb->rtt) {
|
||||
if (strb->is_rtt) {
|
||||
/* rendering to a GL texture, may have to update surface */
|
||||
update_renderbuffer_surface(st, strb);
|
||||
st_update_renderbuffer_surface(st, strb);
|
||||
}
|
||||
pipe_surface_reference(&framebuffer->zsbuf, strb->surface);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -878,7 +878,8 @@ draw_stencil_pixels(struct gl_context *ctx, GLint x, GLint y,
|
|||
}
|
||||
|
||||
stmap = pipe_transfer_map(pipe, strb->texture,
|
||||
strb->rtt_level, strb->rtt_face + strb->rtt_slice,
|
||||
strb->surface->u.tex.level,
|
||||
strb->surface->u.tex.first_layer,
|
||||
usage, x, y,
|
||||
width, height, &pt);
|
||||
|
||||
|
|
@ -1263,8 +1264,8 @@ copy_stencil_pixels(struct gl_context *ctx, GLint srcx, GLint srcy,
|
|||
/* map the stencil buffer */
|
||||
drawMap = pipe_transfer_map(pipe,
|
||||
rbDraw->texture,
|
||||
rbDraw->rtt_level,
|
||||
rbDraw->rtt_face + rbDraw->rtt_slice,
|
||||
rbDraw->surface->u.tex.level,
|
||||
rbDraw->surface->u.tex.first_layer,
|
||||
usage, dstx, dsty,
|
||||
width, height, &ptDraw);
|
||||
|
||||
|
|
@ -1422,20 +1423,20 @@ blit_copy_pixels(struct gl_context *ctx, GLint srcx, GLint srcy,
|
|||
|
||||
memset(&blit, 0, sizeof(blit));
|
||||
blit.src.resource = rbRead->texture;
|
||||
blit.src.level = rbRead->rtt_level;
|
||||
blit.src.level = rbRead->surface->u.tex.level;
|
||||
blit.src.format = rbRead->texture->format;
|
||||
blit.src.box.x = readX;
|
||||
blit.src.box.y = readY;
|
||||
blit.src.box.z = rbRead->rtt_face + rbRead->rtt_slice;
|
||||
blit.src.box.z = rbRead->surface->u.tex.first_layer;
|
||||
blit.src.box.width = readW;
|
||||
blit.src.box.height = readH;
|
||||
blit.src.box.depth = 1;
|
||||
blit.dst.resource = rbDraw->texture;
|
||||
blit.dst.level = rbDraw->rtt_level;
|
||||
blit.dst.level = rbDraw->surface->u.tex.level;
|
||||
blit.dst.format = rbDraw->texture->format;
|
||||
blit.dst.box.x = drawX;
|
||||
blit.dst.box.y = drawY;
|
||||
blit.dst.box.z = rbDraw->rtt_face + rbDraw->rtt_slice;
|
||||
blit.dst.box.z = rbDraw->surface->u.tex.first_layer;
|
||||
blit.dst.box.width = drawW;
|
||||
blit.dst.box.height = drawH;
|
||||
blit.dst.box.depth = 1;
|
||||
|
|
@ -1633,11 +1634,11 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
|
|||
|
||||
memset(&blit, 0, sizeof(blit));
|
||||
blit.src.resource = rbRead->texture;
|
||||
blit.src.level = rbRead->rtt_level;
|
||||
blit.src.level = rbRead->surface->u.tex.level;
|
||||
blit.src.format = rbRead->texture->format;
|
||||
blit.src.box.x = readX;
|
||||
blit.src.box.y = readY;
|
||||
blit.src.box.z = rbRead->rtt_face + rbRead->rtt_slice;
|
||||
blit.src.box.z = rbRead->surface->u.tex.first_layer;
|
||||
blit.src.box.width = readW;
|
||||
blit.src.box.height = readH;
|
||||
blit.src.box.depth = 1;
|
||||
|
|
|
|||
|
|
@ -388,6 +388,72 @@ st_bind_framebuffer(struct gl_context *ctx, GLenum target,
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create or update the pipe_surface of a FBO renderbuffer.
|
||||
* This is usually called after st_finalize_texture.
|
||||
*/
|
||||
void
|
||||
st_update_renderbuffer_surface(struct st_context *st,
|
||||
struct st_renderbuffer *strb)
|
||||
{
|
||||
struct pipe_context *pipe = st->pipe;
|
||||
struct pipe_resource *resource = strb->texture;
|
||||
int rtt_width = strb->Base.Width;
|
||||
int rtt_height = strb->Base.Height;
|
||||
int rtt_depth = strb->Base.Depth;
|
||||
enum pipe_format format = st->ctx->Color.sRGBEnabled ? resource->format :
|
||||
util_format_linear(resource->format);
|
||||
unsigned first_layer, last_layer, level;
|
||||
|
||||
if (resource->target == PIPE_TEXTURE_1D_ARRAY) {
|
||||
rtt_depth = rtt_height;
|
||||
rtt_height = 1;
|
||||
}
|
||||
|
||||
/* find matching mipmap level size */
|
||||
for (level = 0; level <= resource->last_level; level++) {
|
||||
if (u_minify(resource->width0, level) == rtt_width &&
|
||||
u_minify(resource->height0, level) == rtt_height &&
|
||||
(resource->target != PIPE_TEXTURE_3D ||
|
||||
u_minify(resource->depth0, level) == rtt_depth)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(level <= resource->last_level);
|
||||
|
||||
/* determine the layer bounds */
|
||||
if (strb->rtt_layered) {
|
||||
first_layer = 0;
|
||||
last_layer = util_max_layer(strb->texture, level);
|
||||
}
|
||||
else {
|
||||
first_layer =
|
||||
last_layer = strb->rtt_face + strb->rtt_slice;
|
||||
}
|
||||
|
||||
if (!strb->surface ||
|
||||
strb->surface->texture->nr_samples != strb->Base.NumSamples ||
|
||||
strb->surface->format != format ||
|
||||
strb->surface->texture != resource ||
|
||||
strb->surface->width != rtt_width ||
|
||||
strb->surface->height != rtt_height ||
|
||||
strb->surface->u.tex.level != level ||
|
||||
strb->surface->u.tex.first_layer != first_layer ||
|
||||
strb->surface->u.tex.last_layer != last_layer) {
|
||||
/* create a new pipe_surface */
|
||||
struct pipe_surface surf_tmpl;
|
||||
memset(&surf_tmpl, 0, sizeof(surf_tmpl));
|
||||
surf_tmpl.format = format;
|
||||
surf_tmpl.u.tex.level = level;
|
||||
surf_tmpl.u.tex.first_layer = first_layer;
|
||||
surf_tmpl.u.tex.last_layer = last_layer;
|
||||
|
||||
pipe_surface_reference(&strb->surface, NULL);
|
||||
|
||||
strb->surface = pipe->create_surface(pipe, resource, &surf_tmpl);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by ctx->Driver.RenderTexture
|
||||
*/
|
||||
|
|
@ -401,8 +467,6 @@ st_render_texture(struct gl_context *ctx,
|
|||
struct gl_renderbuffer *rb = att->Renderbuffer;
|
||||
struct st_renderbuffer *strb = st_renderbuffer(rb);
|
||||
struct pipe_resource *pt;
|
||||
struct st_texture_object *stObj;
|
||||
struct pipe_surface surf_tmpl;
|
||||
|
||||
if (!st_finalize_texture(ctx, pipe, att->Texture))
|
||||
return;
|
||||
|
|
@ -410,31 +474,16 @@ st_render_texture(struct gl_context *ctx,
|
|||
pt = st_get_texobj_resource(att->Texture);
|
||||
assert(pt);
|
||||
|
||||
/* get the texture for the texture object */
|
||||
stObj = st_texture_object(att->Texture);
|
||||
|
||||
/* point renderbuffer at texobject */
|
||||
strb->rtt = stObj;
|
||||
strb->rtt_level = att->TextureLevel;
|
||||
strb->is_rtt = TRUE;
|
||||
strb->rtt_face = att->CubeMapFace;
|
||||
strb->rtt_slice = att->Zoffset;
|
||||
|
||||
pipe_resource_reference( &strb->texture, pt );
|
||||
strb->rtt_layered = att->Layered;
|
||||
pipe_resource_reference(&strb->texture, pt);
|
||||
|
||||
pipe_surface_release(pipe, &strb->surface);
|
||||
|
||||
assert(strb->rtt_level <= strb->texture->last_level);
|
||||
|
||||
/* new surface for rendering into the texture */
|
||||
memset(&surf_tmpl, 0, sizeof(surf_tmpl));
|
||||
surf_tmpl.format = ctx->Color.sRGBEnabled
|
||||
? strb->texture->format : util_format_linear(strb->texture->format);
|
||||
surf_tmpl.u.tex.level = strb->rtt_level;
|
||||
surf_tmpl.u.tex.first_layer = strb->rtt_face + strb->rtt_slice;
|
||||
surf_tmpl.u.tex.last_layer = strb->rtt_face + strb->rtt_slice;
|
||||
strb->surface = pipe->create_surface(pipe,
|
||||
strb->texture,
|
||||
&surf_tmpl);
|
||||
st_update_renderbuffer_surface(st, strb);
|
||||
|
||||
strb->Base.Format = st_pipe_format_to_mesa_format(pt->format);
|
||||
|
||||
|
|
@ -464,7 +513,7 @@ st_finish_render_texture(struct gl_context *ctx, struct gl_renderbuffer *rb)
|
|||
if (!strb)
|
||||
return;
|
||||
|
||||
strb->rtt = NULL;
|
||||
strb->is_rtt = FALSE;
|
||||
|
||||
/* restore previous framebuffer state */
|
||||
st_invalidate_state(ctx, _NEW_BUFFERS);
|
||||
|
|
@ -706,8 +755,8 @@ st_MapRenderbuffer(struct gl_context *ctx,
|
|||
|
||||
map = pipe_transfer_map(pipe,
|
||||
strb->texture,
|
||||
strb->rtt_level,
|
||||
strb->rtt_face + strb->rtt_slice,
|
||||
strb->surface->u.tex.level,
|
||||
strb->surface->u.tex.first_layer,
|
||||
usage, x, y2, w, h, &strb->transfer);
|
||||
if (map) {
|
||||
if (invert) {
|
||||
|
|
|
|||
|
|
@ -58,8 +58,10 @@ struct st_renderbuffer
|
|||
boolean software;
|
||||
void *data;
|
||||
|
||||
struct st_texture_object *rtt; /**< GL render to texture's texture */
|
||||
unsigned rtt_level, rtt_face, rtt_slice;
|
||||
/* Inputs from Driver.RenderTexture, don't use directly. */
|
||||
boolean is_rtt; /**< whether Driver.RenderTexture was called */
|
||||
unsigned rtt_face, rtt_slice;
|
||||
boolean rtt_layered; /**< whether glFramebufferTexture was called */
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -73,6 +75,10 @@ st_renderbuffer(struct gl_renderbuffer *rb)
|
|||
extern struct gl_renderbuffer *
|
||||
st_new_renderbuffer_fb(enum pipe_format format, int samples, boolean sw);
|
||||
|
||||
extern void
|
||||
st_update_renderbuffer_surface(struct st_context *st,
|
||||
struct st_renderbuffer *strb);
|
||||
|
||||
extern void
|
||||
st_init_fbo_functions(struct dd_function_table *functions);
|
||||
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y,
|
|||
}
|
||||
|
||||
blit.src.resource = src;
|
||||
blit.src.level = strb->rtt_level;
|
||||
blit.src.level = strb->surface->u.tex.level;
|
||||
blit.src.format = src_format;
|
||||
blit.dst.resource = dst;
|
||||
blit.dst.level = 0;
|
||||
|
|
@ -175,7 +175,7 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y,
|
|||
blit.dst.box.x = 0;
|
||||
blit.src.box.y = y;
|
||||
blit.dst.box.y = 0;
|
||||
blit.src.box.z = strb->rtt_face + strb->rtt_slice;
|
||||
blit.src.box.z = strb->surface->u.tex.first_layer;
|
||||
blit.dst.box.z = 0;
|
||||
blit.src.box.width = blit.dst.box.width = width;
|
||||
blit.src.box.height = blit.dst.box.height = height;
|
||||
|
|
|
|||
|
|
@ -1156,8 +1156,8 @@ fallback_copy_texsubimage(struct gl_context *ctx,
|
|||
|
||||
map = pipe_transfer_map(pipe,
|
||||
strb->texture,
|
||||
strb->rtt_level,
|
||||
strb->rtt_face + strb->rtt_slice,
|
||||
strb->surface->u.tex.level,
|
||||
strb->surface->u.tex.first_layer,
|
||||
PIPE_TRANSFER_READ,
|
||||
srcX, srcY,
|
||||
width, height, &src_trans);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue