mesa: Pure software accum buffer.
The existing implementation was already implemented on software, but relied on the pipe driver to always support the R16G16B16A16_SNORM format. This patch eliminates that, without prejudice against a future hardware-only implementation. It also avoids some of the short <-> float conversions, and only does a read transfer of the color buffer on GL_RETURN if absolutely necessary.
This commit is contained in:
@@ -48,10 +48,6 @@
|
||||
#include "util/u_tile.h"
|
||||
|
||||
|
||||
#define UNCLAMPED_FLOAT_TO_SHORT(us, f) \
|
||||
us = ( (short) ( CLAMP((f), -1.0, 1.0) * 32767.0F) )
|
||||
|
||||
|
||||
/**
|
||||
* For hardware that supports deep color buffers, we could accelerate
|
||||
* most/all the accum operations with blending/texturing.
|
||||
@@ -59,74 +55,20 @@
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* 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_transfer *acc_pt,
|
||||
uint x, uint y, uint w, uint h, float *p)
|
||||
{
|
||||
const enum pipe_format f = acc_pt->format;
|
||||
const struct pipe_format_block b = acc_pt->block;
|
||||
|
||||
acc_pt->format = DEFAULT_ACCUM_PIPE_FORMAT;
|
||||
acc_pt->block.size = 8;
|
||||
acc_pt->block.width = 1;
|
||||
acc_pt->block.height = 1;
|
||||
|
||||
pipe_get_tile_rgba(acc_pt, x, y, w, h, p);
|
||||
|
||||
acc_pt->format = f;
|
||||
acc_pt->block = b;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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_transfer *acc_pt,
|
||||
uint x, uint y, uint w, uint h, const float *p)
|
||||
{
|
||||
enum pipe_format f = acc_pt->format;
|
||||
const struct pipe_format_block b = acc_pt->block;
|
||||
|
||||
acc_pt->format = DEFAULT_ACCUM_PIPE_FORMAT;
|
||||
acc_pt->block.size = 8;
|
||||
acc_pt->block.width = 1;
|
||||
acc_pt->block.height = 1;
|
||||
|
||||
pipe_put_tile_rgba(acc_pt, x, y, w, h, p);
|
||||
|
||||
acc_pt->format = f;
|
||||
acc_pt->block = b;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
|
||||
{
|
||||
struct st_renderbuffer *acc_strb = st_renderbuffer(rb);
|
||||
struct pipe_transfer *acc_pt;
|
||||
struct pipe_screen *screen = ctx->st->pipe->screen;
|
||||
const GLint xpos = ctx->DrawBuffer->_Xmin;
|
||||
const GLint ypos = ctx->DrawBuffer->_Ymin;
|
||||
const GLint width = ctx->DrawBuffer->_Xmax - xpos;
|
||||
const GLint height = ctx->DrawBuffer->_Ymax - ypos;
|
||||
GLubyte *map;
|
||||
size_t stride = acc_strb->stride;
|
||||
GLubyte *data = acc_strb->data;
|
||||
|
||||
acc_pt = st_cond_flush_get_tex_transfer(st_context(ctx), acc_strb->texture,
|
||||
0, 0, 0,
|
||||
PIPE_TRANSFER_WRITE, xpos, ypos,
|
||||
width, height);
|
||||
map = screen->transfer_map(screen, acc_pt);
|
||||
|
||||
/* note acc_strb->format might not equal acc_pt->format */
|
||||
if(!data)
|
||||
return;
|
||||
|
||||
switch (acc_strb->format) {
|
||||
case PIPE_FORMAT_R16G16B16A16_SNORM:
|
||||
{
|
||||
@@ -136,7 +78,7 @@ st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
|
||||
GLshort a = FLOAT_TO_SHORT(ctx->Accum.ClearColor[3]);
|
||||
int i, j;
|
||||
for (i = 0; i < height; i++) {
|
||||
GLshort *dst = (GLshort *) (map + i * acc_pt->stride + xpos * 8);
|
||||
GLshort *dst = (GLshort *) (data + (ypos + i) * stride + xpos * 8);
|
||||
for (j = 0; j < width; j++) {
|
||||
dst[0] = r;
|
||||
dst[1] = g;
|
||||
@@ -150,9 +92,6 @@ st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
|
||||
default:
|
||||
_mesa_problem(ctx, "unexpected format in st_clear_accum_buffer()");
|
||||
}
|
||||
|
||||
screen->transfer_unmap(screen, acc_pt);
|
||||
screen->tex_transfer_destroy(acc_pt);
|
||||
}
|
||||
|
||||
|
||||
@@ -162,27 +101,18 @@ accum_mad(GLcontext *ctx, GLfloat scale, GLfloat bias,
|
||||
GLint xpos, GLint ypos, GLint width, GLint height,
|
||||
struct st_renderbuffer *acc_strb)
|
||||
{
|
||||
struct pipe_screen *screen = ctx->st->pipe->screen;
|
||||
struct pipe_transfer *acc_pt;
|
||||
GLubyte *map;
|
||||
size_t stride = acc_strb->stride;
|
||||
GLubyte *data = acc_strb->data;
|
||||
|
||||
acc_pt = st_cond_flush_get_tex_transfer(st_context(ctx), acc_strb->texture,
|
||||
0, 0, 0,
|
||||
PIPE_TRANSFER_READ_WRITE,
|
||||
xpos, ypos,
|
||||
width, height);
|
||||
map = screen->transfer_map(screen, acc_pt);
|
||||
|
||||
/* note acc_strb->format might not equal acc_pt->format */
|
||||
switch (acc_strb->format) {
|
||||
case PIPE_FORMAT_R16G16B16A16_SNORM:
|
||||
{
|
||||
int i, j;
|
||||
for (i = 0; i < height; i++) {
|
||||
GLshort *acc = (GLshort *) (map + (ypos + i) * acc_pt->stride + xpos * 8);
|
||||
GLshort *acc = (GLshort *) (data + (ypos + i) * stride + xpos * 8);
|
||||
for (j = 0; j < width * 4; j++) {
|
||||
float val = SHORT_TO_FLOAT(acc[j]) * scale + bias;
|
||||
acc[j] = FLOAT_TO_SHORT(val);
|
||||
float val = SHORT_TO_FLOAT(*acc) * scale + bias;
|
||||
*acc++ = FLOAT_TO_SHORT(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -190,9 +120,6 @@ accum_mad(GLcontext *ctx, GLfloat scale, GLfloat bias,
|
||||
default:
|
||||
_mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()");
|
||||
}
|
||||
|
||||
screen->transfer_unmap(screen, acc_pt);
|
||||
screen->tex_transfer_destroy(acc_pt);
|
||||
}
|
||||
|
||||
|
||||
@@ -204,39 +131,39 @@ accum_accum(struct st_context *st, GLfloat value,
|
||||
{
|
||||
struct pipe_context *pipe = st->pipe;
|
||||
struct pipe_screen *screen = pipe->screen;
|
||||
struct pipe_transfer *acc_trans, *color_trans;
|
||||
GLfloat *colorBuf, *accBuf;
|
||||
GLint i;
|
||||
|
||||
acc_trans = st_cond_flush_get_tex_transfer(st, acc_strb->texture, 0, 0, 0,
|
||||
PIPE_TRANSFER_READ, xpos, ypos,
|
||||
width, height);
|
||||
struct pipe_transfer *color_trans;
|
||||
size_t stride = acc_strb->stride;
|
||||
GLubyte *data = acc_strb->data;
|
||||
GLfloat *buf;
|
||||
|
||||
color_trans = st_cond_flush_get_tex_transfer(st, color_strb->texture,
|
||||
0, 0, 0,
|
||||
PIPE_TRANSFER_READ, xpos, ypos,
|
||||
width, height);
|
||||
|
||||
colorBuf = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
|
||||
accBuf = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
|
||||
buf = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
|
||||
|
||||
pipe_get_tile_rgba(color_trans, 0, 0, width, height, colorBuf);
|
||||
acc_get_tile_rgba(pipe, acc_trans, 0, 0, width, height, accBuf);
|
||||
pipe_get_tile_rgba(color_trans, 0, 0, width, height, buf);
|
||||
|
||||
for (i = 0; i < 4 * width * height; i++) {
|
||||
accBuf[i] = accBuf[i] + colorBuf[i] * value;
|
||||
switch (acc_strb->format) {
|
||||
case PIPE_FORMAT_R16G16B16A16_SNORM:
|
||||
{
|
||||
const GLfloat *color = buf;
|
||||
int i, j;
|
||||
for (i = 0; i < height; i++) {
|
||||
GLshort *acc = (GLshort *) (data + (ypos + i) * stride + xpos * 8);
|
||||
for (j = 0; j < width * 4; j++) {
|
||||
float val = *color++ * value;
|
||||
*acc++ += FLOAT_TO_SHORT(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
_mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()");
|
||||
}
|
||||
|
||||
screen->tex_transfer_destroy(acc_trans);
|
||||
acc_trans = st_no_flush_get_tex_transfer(st, acc_strb->texture, 0, 0, 0,
|
||||
PIPE_TRANSFER_WRITE, xpos, ypos,
|
||||
width, height);
|
||||
|
||||
acc_put_tile_rgba(pipe, acc_trans, 0, 0, width, height, accBuf);
|
||||
|
||||
_mesa_free(colorBuf);
|
||||
_mesa_free(accBuf);
|
||||
screen->tex_transfer_destroy(acc_trans);
|
||||
_mesa_free(buf);
|
||||
screen->tex_transfer_destroy(color_trans);
|
||||
}
|
||||
|
||||
@@ -249,13 +176,10 @@ accum_load(struct st_context *st, GLfloat value,
|
||||
{
|
||||
struct pipe_context *pipe = st->pipe;
|
||||
struct pipe_screen *screen = pipe->screen;
|
||||
struct pipe_transfer *acc_trans, *color_trans;
|
||||
struct pipe_transfer *color_trans;
|
||||
size_t stride = acc_strb->stride;
|
||||
GLubyte *data = acc_strb->data;
|
||||
GLfloat *buf;
|
||||
GLint i;
|
||||
|
||||
acc_trans = st_cond_flush_get_tex_transfer(st, acc_strb->texture, 0, 0, 0,
|
||||
PIPE_TRANSFER_WRITE, xpos, ypos,
|
||||
width, height);
|
||||
|
||||
color_trans = st_cond_flush_get_tex_transfer(st, color_strb->texture,
|
||||
0, 0, 0,
|
||||
@@ -266,14 +190,25 @@ accum_load(struct st_context *st, GLfloat value,
|
||||
|
||||
pipe_get_tile_rgba(color_trans, 0, 0, width, height, buf);
|
||||
|
||||
for (i = 0; i < 4 * width * height; i++) {
|
||||
buf[i] = buf[i] * value;
|
||||
switch (acc_strb->format) {
|
||||
case PIPE_FORMAT_R16G16B16A16_SNORM:
|
||||
{
|
||||
const GLfloat *color = buf;
|
||||
int i, j;
|
||||
for (i = 0; i < height; i++) {
|
||||
GLshort *acc = (GLshort *) (data + (ypos + i) * stride + xpos * 8);
|
||||
for (j = 0; j < width * 4; j++) {
|
||||
float val = *color++ * value;
|
||||
*acc++ = FLOAT_TO_SHORT(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
_mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()");
|
||||
}
|
||||
|
||||
acc_put_tile_rgba(pipe, acc_trans, 0, 0, width, height, buf);
|
||||
|
||||
_mesa_free(buf);
|
||||
screen->tex_transfer_destroy(acc_trans);
|
||||
screen->tex_transfer_destroy(color_trans);
|
||||
}
|
||||
|
||||
@@ -287,48 +222,58 @@ accum_return(GLcontext *ctx, GLfloat value,
|
||||
struct pipe_context *pipe = ctx->st->pipe;
|
||||
struct pipe_screen *screen = pipe->screen;
|
||||
const GLubyte *colormask = ctx->Color.ColorMask;
|
||||
struct pipe_transfer *acc_trans, *color_trans;
|
||||
GLfloat *abuf, *cbuf = NULL;
|
||||
GLint i, ch;
|
||||
enum pipe_transfer_usage usage;
|
||||
struct pipe_transfer *color_trans;
|
||||
size_t stride = acc_strb->stride;
|
||||
const GLubyte *data = acc_strb->data;
|
||||
GLfloat *buf;
|
||||
|
||||
abuf = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
|
||||
|
||||
acc_trans = st_cond_flush_get_tex_transfer(st_context(ctx),
|
||||
acc_strb->texture, 0, 0, 0,
|
||||
PIPE_TRANSFER_READ, xpos, ypos,
|
||||
width, height);
|
||||
buf = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
|
||||
|
||||
if (!colormask[0] || !colormask[1] || !colormask[2] || !colormask[3])
|
||||
usage = PIPE_TRANSFER_READ_WRITE;
|
||||
else
|
||||
usage = PIPE_TRANSFER_WRITE;
|
||||
|
||||
color_trans = st_cond_flush_get_tex_transfer(st_context(ctx),
|
||||
color_strb->texture, 0, 0, 0,
|
||||
PIPE_TRANSFER_READ_WRITE,
|
||||
usage,
|
||||
xpos, ypos,
|
||||
width, height);
|
||||
|
||||
acc_get_tile_rgba(pipe, acc_trans, 0, 0, width, height, abuf);
|
||||
if (usage != PIPE_TRANSFER_WRITE)
|
||||
pipe_get_tile_rgba(color_trans, 0, 0, width, height, buf);
|
||||
|
||||
if (!colormask[0] || !colormask[1] || !colormask[2] || !colormask[3]) {
|
||||
cbuf = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
|
||||
pipe_get_tile_rgba(color_trans, 0, 0, width, height, cbuf);
|
||||
}
|
||||
|
||||
for (i = 0; i < width * height; i++) {
|
||||
for (ch = 0; ch < 4; ch++) {
|
||||
if (colormask[ch]) {
|
||||
GLfloat val = abuf[i * 4 + ch] * value;
|
||||
abuf[i * 4 + ch] = CLAMP(val, 0.0f, 1.0f);
|
||||
}
|
||||
else {
|
||||
abuf[i * 4 + ch] = cbuf[i * 4 + ch];
|
||||
switch (acc_strb->format) {
|
||||
case PIPE_FORMAT_R16G16B16A16_SNORM:
|
||||
{
|
||||
GLfloat *color = buf;
|
||||
int i, j, ch;
|
||||
for (i = 0; i < height; i++) {
|
||||
const GLshort *acc = (const GLshort *) (data + (ypos + i) * stride + xpos * 8);
|
||||
for (j = 0; j < width; j++) {
|
||||
for (ch = 0; ch < 4; ch++) {
|
||||
if (colormask[ch]) {
|
||||
GLfloat val = SHORT_TO_FLOAT(*acc * value);
|
||||
*color = CLAMP(val, 0.0f, 1.0f);
|
||||
}
|
||||
else {
|
||||
/* No change */
|
||||
}
|
||||
++acc;
|
||||
++color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
_mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()");
|
||||
}
|
||||
|
||||
pipe_put_tile_rgba(color_trans, 0, 0, width, height, abuf);
|
||||
pipe_put_tile_rgba(color_trans, 0, 0, width, height, buf);
|
||||
|
||||
_mesa_free(abuf);
|
||||
if (cbuf)
|
||||
_mesa_free(cbuf);
|
||||
screen->tex_transfer_destroy(acc_trans);
|
||||
_mesa_free(buf);
|
||||
screen->tex_transfer_destroy(color_trans);
|
||||
}
|
||||
|
||||
@@ -347,6 +292,9 @@ st_Accum(GLcontext *ctx, GLenum op, GLfloat value)
|
||||
const GLint width = ctx->DrawBuffer->_Xmax - xpos;
|
||||
const GLint height = ctx->DrawBuffer->_Ymax - ypos;
|
||||
|
||||
if(!acc_strb->data)
|
||||
return;
|
||||
|
||||
/* make sure color bufs aren't cached */
|
||||
st_flush( st, PIPE_FLUSH_RENDER_CACHE, NULL );
|
||||
|
||||
|
@@ -88,91 +88,90 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
|
||||
{
|
||||
struct pipe_context *pipe = ctx->st->pipe;
|
||||
struct st_renderbuffer *strb = st_renderbuffer(rb);
|
||||
struct pipe_texture template;
|
||||
unsigned surface_usage;
|
||||
|
||||
/* Free the old surface and texture
|
||||
*/
|
||||
pipe_surface_reference( &strb->surface, NULL );
|
||||
pipe_texture_reference( &strb->texture, NULL );
|
||||
|
||||
/* Setup new texture template.
|
||||
*/
|
||||
memset(&template, 0, sizeof(template));
|
||||
template.target = PIPE_TEXTURE_2D;
|
||||
if (strb->format != PIPE_FORMAT_NONE) {
|
||||
template.format = strb->format;
|
||||
}
|
||||
else {
|
||||
template.format = st_choose_renderbuffer_format(pipe, internalFormat);
|
||||
}
|
||||
pf_get_block(template.format, &template.block);
|
||||
template.width[0] = width;
|
||||
template.height[0] = height;
|
||||
template.depth[0] = 1;
|
||||
template.last_level = 0;
|
||||
template.nr_samples = rb->NumSamples;
|
||||
if (pf_is_depth_stencil(template.format)) {
|
||||
template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
|
||||
}
|
||||
else {
|
||||
template.tex_usage = (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
|
||||
PIPE_TEXTURE_USAGE_RENDER_TARGET);
|
||||
}
|
||||
enum pipe_format format;
|
||||
|
||||
if (strb->format != PIPE_FORMAT_NONE)
|
||||
format = strb->format;
|
||||
else
|
||||
format = st_choose_renderbuffer_format(pipe, internalFormat);
|
||||
|
||||
/* init renderbuffer fields */
|
||||
strb->Base.Width = width;
|
||||
strb->Base.Height = height;
|
||||
init_renderbuffer_bits(strb, template.format);
|
||||
init_renderbuffer_bits(strb, format);
|
||||
|
||||
/* Probably need dedicated flags for surface usage too:
|
||||
*/
|
||||
surface_usage = (PIPE_BUFFER_USAGE_GPU_READ |
|
||||
PIPE_BUFFER_USAGE_GPU_WRITE);
|
||||
#if 0
|
||||
PIPE_BUFFER_USAGE_CPU_READ |
|
||||
PIPE_BUFFER_USAGE_CPU_WRITE);
|
||||
#endif
|
||||
if(strb->software) {
|
||||
struct pipe_format_block block;
|
||||
size_t size;
|
||||
|
||||
_mesa_free(strb->data);
|
||||
|
||||
strb->texture = pipe->screen->texture_create( pipe->screen,
|
||||
&template );
|
||||
|
||||
/* Special path for accum buffers.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
if (!strb->texture && template.format == DEFAULT_ACCUM_PIPE_FORMAT)
|
||||
{
|
||||
/* Actually, just setting this usage value should be sufficient
|
||||
* to tell the driver to go ahead and allocate the buffer, even
|
||||
* if HW doesn't support the format.
|
||||
assert(strb->format != PIPE_FORMAT_NONE);
|
||||
pf_get_block(strb->format, &block);
|
||||
|
||||
strb->stride = pf_get_stride(&block, width);
|
||||
size = pf_get_2d_size(&block, strb->stride, height);
|
||||
|
||||
strb->data = _mesa_malloc(size);
|
||||
|
||||
return strb->data != NULL;
|
||||
}
|
||||
else {
|
||||
struct pipe_texture template;
|
||||
unsigned surface_usage;
|
||||
|
||||
/* Free the old surface and texture
|
||||
*/
|
||||
template.tex_usage = 0;
|
||||
surface_usage = (PIPE_BUFFER_USAGE_CPU_READ |
|
||||
pipe_surface_reference( &strb->surface, NULL );
|
||||
pipe_texture_reference( &strb->texture, NULL );
|
||||
|
||||
/* Setup new texture template.
|
||||
*/
|
||||
memset(&template, 0, sizeof(template));
|
||||
template.target = PIPE_TEXTURE_2D;
|
||||
template.format = format;
|
||||
pf_get_block(format, &template.block);
|
||||
template.width[0] = width;
|
||||
template.height[0] = height;
|
||||
template.depth[0] = 1;
|
||||
template.last_level = 0;
|
||||
template.nr_samples = rb->NumSamples;
|
||||
if (pf_is_depth_stencil(format)) {
|
||||
template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
|
||||
}
|
||||
else {
|
||||
template.tex_usage = (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
|
||||
PIPE_TEXTURE_USAGE_RENDER_TARGET);
|
||||
}
|
||||
|
||||
/* Probably need dedicated flags for surface usage too:
|
||||
*/
|
||||
surface_usage = (PIPE_BUFFER_USAGE_GPU_READ |
|
||||
PIPE_BUFFER_USAGE_GPU_WRITE);
|
||||
#if 0
|
||||
PIPE_BUFFER_USAGE_CPU_READ |
|
||||
PIPE_BUFFER_USAGE_CPU_WRITE);
|
||||
#endif
|
||||
|
||||
strb->texture = pipe->screen->texture_create( pipe->screen,
|
||||
&template );
|
||||
|
||||
if (!strb->texture)
|
||||
return FALSE;
|
||||
|
||||
strb->surface = pipe->screen->get_tex_surface( pipe->screen,
|
||||
strb->texture,
|
||||
0, 0, 0,
|
||||
surface_usage );
|
||||
|
||||
assert(strb->surface->texture);
|
||||
assert(strb->surface->format);
|
||||
assert(strb->surface->width == width);
|
||||
assert(strb->surface->height == height);
|
||||
|
||||
|
||||
return strb->surface != NULL;
|
||||
}
|
||||
|
||||
if (!strb->texture)
|
||||
return FALSE;
|
||||
|
||||
strb->surface = pipe->screen->get_tex_surface( pipe->screen,
|
||||
strb->texture,
|
||||
0, 0, 0,
|
||||
surface_usage );
|
||||
|
||||
assert(strb->surface->texture);
|
||||
assert(strb->surface->format);
|
||||
assert(strb->surface->width == width);
|
||||
assert(strb->surface->height == height);
|
||||
|
||||
|
||||
return strb->surface != NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -186,6 +185,7 @@ st_renderbuffer_delete(struct gl_renderbuffer *rb)
|
||||
ASSERT(strb);
|
||||
pipe_surface_reference(&strb->surface, NULL);
|
||||
pipe_texture_reference(&strb->texture, NULL);
|
||||
_mesa_free(strb->data);
|
||||
_mesa_free(strb);
|
||||
}
|
||||
|
||||
@@ -242,7 +242,7 @@ st_new_renderbuffer(GLcontext *ctx, GLuint name)
|
||||
* renderbuffer). The window system code determines the format.
|
||||
*/
|
||||
struct gl_renderbuffer *
|
||||
st_new_renderbuffer_fb(enum pipe_format format, int samples)
|
||||
st_new_renderbuffer_fb(enum pipe_format format, int samples, boolean sw)
|
||||
{
|
||||
struct st_renderbuffer *strb;
|
||||
|
||||
@@ -256,7 +256,8 @@ st_new_renderbuffer_fb(enum pipe_format format, int samples)
|
||||
strb->Base.ClassID = 0x4242; /* just a unique value */
|
||||
strb->Base.NumSamples = samples;
|
||||
strb->format = format;
|
||||
|
||||
strb->software = sw;
|
||||
|
||||
switch (format) {
|
||||
case PIPE_FORMAT_A8R8G8B8_UNORM:
|
||||
case PIPE_FORMAT_B8G8R8A8_UNORM:
|
||||
@@ -287,7 +288,7 @@ st_new_renderbuffer_fb(enum pipe_format format, int samples)
|
||||
strb->Base.InternalFormat = GL_STENCIL_INDEX8_EXT;
|
||||
strb->Base._BaseFormat = GL_STENCIL_INDEX;
|
||||
break;
|
||||
case DEFAULT_ACCUM_PIPE_FORMAT: /*PIPE_FORMAT_R16G16B16A16_SNORM*/
|
||||
case PIPE_FORMAT_R16G16B16A16_SNORM:
|
||||
strb->Base.InternalFormat = GL_RGBA16;
|
||||
strb->Base._BaseFormat = GL_RGBA;
|
||||
break;
|
||||
|
@@ -30,10 +30,6 @@
|
||||
#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
|
||||
* pipe surface.
|
||||
@@ -45,6 +41,13 @@ struct st_renderbuffer
|
||||
struct pipe_surface *surface; /* temporary view into texture */
|
||||
enum pipe_format format; /** preferred format, or PIPE_FORMAT_NONE */
|
||||
|
||||
/**
|
||||
* Used only when hardware accumulation buffers are not supported.
|
||||
*/
|
||||
boolean software;
|
||||
size_t stride;
|
||||
void *data;
|
||||
|
||||
struct st_texture_object *rtt; /**< GL render to texture's texture */
|
||||
int rtt_level, rtt_face, rtt_slice;
|
||||
|
||||
@@ -62,7 +65,7 @@ st_renderbuffer(struct gl_renderbuffer *rb)
|
||||
|
||||
|
||||
extern struct gl_renderbuffer *
|
||||
st_new_renderbuffer_fb(enum pipe_format format, int samples);
|
||||
st_new_renderbuffer_fb(enum pipe_format format, int samples, boolean sw);
|
||||
|
||||
extern void
|
||||
st_init_fbo_functions(struct dd_function_table *functions);
|
||||
|
@@ -63,20 +63,20 @@ st_create_framebuffer( const __GLcontextModes *visual,
|
||||
/* XXX allocation should only happen in the unusual case
|
||||
it's actually needed */
|
||||
struct gl_renderbuffer *rb
|
||||
= st_new_renderbuffer_fb(colorFormat, samples);
|
||||
= st_new_renderbuffer_fb(colorFormat, samples, FALSE);
|
||||
_mesa_add_renderbuffer(&stfb->Base, BUFFER_FRONT_LEFT, rb);
|
||||
}
|
||||
|
||||
if (visual->doubleBufferMode) {
|
||||
struct gl_renderbuffer *rb
|
||||
= st_new_renderbuffer_fb(colorFormat, samples);
|
||||
= st_new_renderbuffer_fb(colorFormat, samples, FALSE);
|
||||
_mesa_add_renderbuffer(&stfb->Base, BUFFER_BACK_LEFT, rb);
|
||||
}
|
||||
|
||||
if (depthFormat == stencilFormat && depthFormat != PIPE_FORMAT_NONE) {
|
||||
/* combined depth/stencil buffer */
|
||||
struct gl_renderbuffer *depthStencilRb
|
||||
= st_new_renderbuffer_fb(depthFormat, samples);
|
||||
= st_new_renderbuffer_fb(depthFormat, samples, FALSE);
|
||||
/* note: bind RB to two attachment points */
|
||||
_mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthStencilRb);
|
||||
_mesa_add_renderbuffer(&stfb->Base, BUFFER_STENCIL, depthStencilRb);
|
||||
@@ -87,34 +87,35 @@ st_create_framebuffer( const __GLcontextModes *visual,
|
||||
if (visual->depthBits == 32) {
|
||||
/* 32-bit depth buffer */
|
||||
struct gl_renderbuffer *depthRb
|
||||
= st_new_renderbuffer_fb(depthFormat, samples);
|
||||
= st_new_renderbuffer_fb(depthFormat, samples, FALSE);
|
||||
_mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb);
|
||||
}
|
||||
else if (visual->depthBits == 24) {
|
||||
/* 24-bit depth buffer, ignore stencil bits */
|
||||
struct gl_renderbuffer *depthRb
|
||||
= st_new_renderbuffer_fb(depthFormat, samples);
|
||||
= st_new_renderbuffer_fb(depthFormat, samples, FALSE);
|
||||
_mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb);
|
||||
}
|
||||
else if (visual->depthBits > 0) {
|
||||
/* 16-bit depth buffer */
|
||||
struct gl_renderbuffer *depthRb
|
||||
= st_new_renderbuffer_fb(depthFormat, samples);
|
||||
= st_new_renderbuffer_fb(depthFormat, samples, FALSE);
|
||||
_mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb);
|
||||
}
|
||||
|
||||
if (visual->stencilBits > 0) {
|
||||
/* 8-bit stencil */
|
||||
struct gl_renderbuffer *stencilRb
|
||||
= st_new_renderbuffer_fb(stencilFormat, samples);
|
||||
= st_new_renderbuffer_fb(stencilFormat, samples, FALSE);
|
||||
_mesa_add_renderbuffer(&stfb->Base, BUFFER_STENCIL, stencilRb);
|
||||
}
|
||||
}
|
||||
|
||||
if (visual->accumRedBits > 0) {
|
||||
/* 16-bit/channel accum */
|
||||
/* TODO: query the pipe screen for accumulation buffer format support */
|
||||
struct gl_renderbuffer *accumRb
|
||||
= st_new_renderbuffer_fb(DEFAULT_ACCUM_PIPE_FORMAT, 0); /* XXX accum isn't multisampled right? */
|
||||
= st_new_renderbuffer_fb(PIPE_FORMAT_R16G16B16A16_SNORM, 0, TRUE);
|
||||
_mesa_add_renderbuffer(&stfb->Base, BUFFER_ACCUM, accumRb);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user