mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-02 10:08:08 +02:00
gallium: accum buffer fixes
If the driver can't create a PIPE_FORMAT_R16G16B16A16_SNORM surface, create an accum surface using a shallower format and taller height. Since only the accum buffer code accesses the surface the actual format doesn't really matter, just that there's enough memory.
This commit is contained in:
parent
29b65a709c
commit
0dd596fbc7
4 changed files with 84 additions and 11 deletions
|
|
@ -56,6 +56,51 @@
|
|||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper for pipe_get_tile_rgba(). Do format/cpp override to make the
|
||||
* tile util function think the surface is 16bit/channel, even if it's not.
|
||||
* See also: st_renderbuffer_alloc_storage()
|
||||
*/
|
||||
static void
|
||||
acc_get_tile_rgba(struct pipe_context *pipe, struct pipe_surface *acc_ps,
|
||||
uint x, uint y, uint w, uint h, float *p)
|
||||
{
|
||||
const enum pipe_format f = acc_ps->format;
|
||||
const int cpp = acc_ps->cpp;
|
||||
|
||||
acc_ps->format = DEFAULT_ACCUM_PIPE_FORMAT;
|
||||
acc_ps->cpp = 8;
|
||||
|
||||
pipe_get_tile_rgba(pipe, acc_ps, x, y, w, h, p);
|
||||
|
||||
acc_ps->format = f;
|
||||
acc_ps->cpp = cpp;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper for pipe_put_tile_rgba(). Do format/cpp override to make the
|
||||
* tile util function think the surface is 16bit/channel, even if it's not.
|
||||
* See also: st_renderbuffer_alloc_storage()
|
||||
*/
|
||||
static void
|
||||
acc_put_tile_rgba(struct pipe_context *pipe, struct pipe_surface *acc_ps,
|
||||
uint x, uint y, uint w, uint h, const float *p)
|
||||
{
|
||||
enum pipe_format f = acc_ps->format;
|
||||
const int cpp = acc_ps->cpp;
|
||||
|
||||
acc_ps->format = DEFAULT_ACCUM_PIPE_FORMAT;
|
||||
acc_ps->cpp = 8;
|
||||
|
||||
pipe_put_tile_rgba(pipe, acc_ps, x, y, w, h, p);
|
||||
|
||||
acc_ps->format = f;
|
||||
acc_ps->cpp = cpp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
|
||||
{
|
||||
|
|
@ -80,7 +125,9 @@ st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
|
|||
accBuf[i*4+3] = a;
|
||||
}
|
||||
|
||||
pipe_put_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, accBuf);
|
||||
acc_put_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, accBuf);
|
||||
|
||||
free(accBuf);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -95,13 +142,13 @@ accum_mad(struct pipe_context *pipe, GLfloat scale, GLfloat bias,
|
|||
|
||||
accBuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
|
||||
|
||||
pipe_get_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, accBuf);
|
||||
acc_get_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, accBuf);
|
||||
|
||||
for (i = 0; i < 4 * width * height; i++) {
|
||||
accBuf[i] = accBuf[i] * scale + bias;
|
||||
}
|
||||
|
||||
pipe_put_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, accBuf);
|
||||
acc_put_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, accBuf);
|
||||
|
||||
free(accBuf);
|
||||
}
|
||||
|
|
@ -120,13 +167,13 @@ accum_accum(struct pipe_context *pipe, GLfloat value,
|
|||
accBuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
|
||||
|
||||
pipe_get_tile_rgba(pipe, color_ps, xpos, ypos, width, height, colorBuf);
|
||||
pipe_get_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, accBuf);
|
||||
acc_get_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, accBuf);
|
||||
|
||||
for (i = 0; i < 4 * width * height; i++) {
|
||||
accBuf[i] = accBuf[i] + colorBuf[i] * value;
|
||||
}
|
||||
|
||||
pipe_put_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, accBuf);
|
||||
acc_put_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, accBuf);
|
||||
|
||||
free(colorBuf);
|
||||
free(accBuf);
|
||||
|
|
@ -150,7 +197,7 @@ accum_load(struct pipe_context *pipe, GLfloat value,
|
|||
buf[i] = buf[i] * value;
|
||||
}
|
||||
|
||||
pipe_put_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, buf);
|
||||
acc_put_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, buf);
|
||||
|
||||
free(buf);
|
||||
}
|
||||
|
|
@ -169,7 +216,7 @@ accum_return(GLcontext *ctx, GLfloat value,
|
|||
|
||||
abuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
|
||||
|
||||
pipe_get_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, abuf);
|
||||
acc_get_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, abuf);
|
||||
|
||||
if (!colormask[0] || !colormask[1] || !colormask[2] || !colormask[3]) {
|
||||
cbuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
|
||||
|
|
|
|||
|
|
@ -127,14 +127,37 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
|
|||
pipeFormat,
|
||||
flags);
|
||||
if (ret || !strb->surface->buffer) {
|
||||
return GL_FALSE; /* out of memory, try s/w buffer? */
|
||||
if (pipeFormat == DEFAULT_ACCUM_PIPE_FORMAT) {
|
||||
/* Accum buffer. Try a different surface format. Since accum
|
||||
* buffers are s/w only for now, the surface pixel format doesn't
|
||||
* really matter, only that the buffer is large enough.
|
||||
*/
|
||||
int sz, mult;
|
||||
enum pipe_format accum_format;
|
||||
|
||||
/* allocate a buffer of (typically) double height to get 64bpp */
|
||||
accum_format = st_choose_renderbuffer_format(pipe, GL_RGBA);
|
||||
sz = pf_get_size(accum_format);
|
||||
mult = pf_get_size(DEFAULT_ACCUM_PIPE_FORMAT) / sz;
|
||||
|
||||
ret = pipe->winsys->surface_alloc_storage(pipe->winsys,
|
||||
strb->surface,
|
||||
width, height * mult,
|
||||
accum_format, flags);
|
||||
if (ret)
|
||||
return GL_FALSE; /* we've _really_ failed */
|
||||
|
||||
}
|
||||
else {
|
||||
return GL_FALSE; /* out of memory, try s/w buffer? */
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(strb->surface->buffer);
|
||||
ASSERT(strb->surface->format);
|
||||
ASSERT(strb->surface->cpp);
|
||||
ASSERT(strb->surface->width == width);
|
||||
ASSERT(strb->surface->height == height);
|
||||
/*ASSERT(strb->surface->height == height);*/
|
||||
ASSERT(strb->surface->pitch);
|
||||
|
||||
strb->Base.Width = width;
|
||||
|
|
@ -252,7 +275,7 @@ st_new_renderbuffer_fb(enum pipe_format format)
|
|||
strb->Base.InternalFormat = GL_STENCIL_INDEX8_EXT;
|
||||
strb->Base._BaseFormat = GL_STENCIL_INDEX;
|
||||
break;
|
||||
case PIPE_FORMAT_R16G16B16A16_SNORM:
|
||||
case DEFAULT_ACCUM_PIPE_FORMAT: /*PIPE_FORMAT_R16G16B16A16_SNORM*/
|
||||
strb->Base.InternalFormat = GL_RGBA16;
|
||||
strb->Base._BaseFormat = GL_RGBA;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,9 @@
|
|||
#define ST_CB_FBO_H
|
||||
|
||||
|
||||
#define DEFAULT_ACCUM_PIPE_FORMAT PIPE_FORMAT_R16G16B16A16_SNORM
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Derived renderbuffer class. Just need to add a pointer to the
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ st_create_framebuffer( const __GLcontextModes *visual,
|
|||
if (visual->accumRedBits > 0) {
|
||||
/* 16-bit/channel accum */
|
||||
struct gl_renderbuffer *accumRb
|
||||
= st_new_renderbuffer_fb(PIPE_FORMAT_R16G16B16A16_SNORM);
|
||||
= st_new_renderbuffer_fb(DEFAULT_ACCUM_PIPE_FORMAT);
|
||||
_mesa_add_renderbuffer(&stfb->Base, BUFFER_ACCUM, accumRb);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue