X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fswrast%2Fs_renderbuffer.c;h=d8c4ed3863881dec1cd7cb84d5755fd6b2f0d1b5;hb=e81aaeba37f5419323d8f88bc10943c77e25ed14;hp=a78c6a191b97fe8cc9e7dea3aa1dd5fa1d84dd3d;hpb=f9874feef4d8952df5054bd8e8f4e0deda4ef44f;p=mesa.git diff --git a/src/mesa/swrast/s_renderbuffer.c b/src/mesa/swrast/s_renderbuffer.c index a78c6a191b9..d8c4ed38638 100644 --- a/src/mesa/swrast/s_renderbuffer.c +++ b/src/mesa/swrast/s_renderbuffer.c @@ -1,6 +1,5 @@ /* * Mesa 3-D graphics library - * Version: 6.5 * * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. * @@ -17,9 +16,10 @@ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. */ @@ -37,6 +37,7 @@ #include "main/formats.h" #include "main/mtypes.h" #include "main/renderbuffer.h" +#include "swrast/s_context.h" #include "swrast/s_renderbuffer.h" @@ -56,6 +57,9 @@ soft_renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb, GLenum internalFormat, GLuint width, GLuint height) { + struct swrast_renderbuffer *srb = swrast_renderbuffer(rb); + GLuint bpp; + switch (internalFormat) { case GL_RGB: case GL_R3_G3_B2: @@ -65,7 +69,7 @@ soft_renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb, case GL_RGB10: case GL_RGB12: case GL_RGB16: - rb->Format = MESA_FORMAT_RGB888; + rb->Format = MESA_FORMAT_BGR_UNORM8; break; case GL_RGBA: case GL_RGBA2: @@ -77,59 +81,59 @@ soft_renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb, case GL_RGBA12: #endif if (_mesa_little_endian()) - rb->Format = MESA_FORMAT_RGBA8888_REV; + rb->Format = MESA_FORMAT_R8G8B8A8_UNORM; else - rb->Format = MESA_FORMAT_RGBA8888; + rb->Format = MESA_FORMAT_A8B8G8R8_UNORM; break; case GL_RGBA16: case GL_RGBA16_SNORM: /* for accum buffer */ - rb->Format = MESA_FORMAT_SIGNED_RGBA_16; + rb->Format = MESA_FORMAT_RGBA_SNORM16; break; case GL_STENCIL_INDEX: case GL_STENCIL_INDEX1_EXT: case GL_STENCIL_INDEX4_EXT: case GL_STENCIL_INDEX8_EXT: case GL_STENCIL_INDEX16_EXT: - rb->Format = MESA_FORMAT_S8; + rb->Format = MESA_FORMAT_S_UINT8; break; case GL_DEPTH_COMPONENT: case GL_DEPTH_COMPONENT16: - rb->Format = MESA_FORMAT_Z16; + rb->Format = MESA_FORMAT_Z_UNORM16; break; case GL_DEPTH_COMPONENT24: - rb->Format = MESA_FORMAT_X8_Z24; + rb->Format = MESA_FORMAT_Z24_UNORM_X8_UINT; break; case GL_DEPTH_COMPONENT32: - rb->Format = MESA_FORMAT_Z32; + rb->Format = MESA_FORMAT_Z_UNORM32; break; case GL_DEPTH_STENCIL_EXT: case GL_DEPTH24_STENCIL8_EXT: - rb->Format = MESA_FORMAT_Z24_S8; + rb->Format = MESA_FORMAT_S8_UINT_Z24_UNORM; break; default: /* unsupported format */ return GL_FALSE; } + bpp = _mesa_get_format_bytes(rb->Format); + /* free old buffer storage */ - if (rb->Data) { - free(rb->Data); - rb->Data = NULL; - } + free(srb->Buffer); + srb->Buffer = NULL; - rb->RowStrideBytes = width * _mesa_get_format_bytes(rb->Format); + srb->RowStride = width * bpp; if (width > 0 && height > 0) { /* allocate new buffer storage */ - rb->Data = malloc(width * height * _mesa_get_format_bytes(rb->Format)); + srb->Buffer = malloc(srb->RowStride * height); - if (rb->Data == NULL) { + if (srb->Buffer == NULL) { rb->Width = 0; rb->Height = 0; _mesa_error(ctx, GL_OUT_OF_MEMORY, "software renderbuffer allocation (%d x %d x %d)", - width, height, _mesa_get_format_bytes(rb->Format)); + width, height, bpp); return GL_FALSE; } } @@ -149,13 +153,27 @@ soft_renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb, } else { /* the internalFormat should have been error checked long ago */ - ASSERT(rb->_BaseFormat); + assert(rb->_BaseFormat); } return GL_TRUE; } +/** + * Called via gl_renderbuffer::Delete() + */ +static void +soft_renderbuffer_delete(struct gl_context *ctx, struct gl_renderbuffer *rb) +{ + struct swrast_renderbuffer *srb = swrast_renderbuffer(rb); + + free(srb->Buffer); + srb->Buffer = NULL; + _mesa_delete_renderbuffer(ctx, rb); +} + + void _swrast_map_soft_renderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb, @@ -164,11 +182,15 @@ _swrast_map_soft_renderbuffer(struct gl_context *ctx, GLubyte **out_map, GLint *out_stride) { - GLubyte *map = rb->Data; + struct swrast_renderbuffer *srb = swrast_renderbuffer(rb); + GLubyte *map = srb->Buffer; int cpp = _mesa_get_format_bytes(rb->Format); int stride = rb->Width * cpp; - ASSERT(rb->Data); + if (!map) { + *out_map = NULL; + *out_stride = 0; + } map += y * stride; map += x * cpp; @@ -195,11 +217,13 @@ _swrast_unmap_soft_renderbuffer(struct gl_context *ctx, struct gl_renderbuffer * _swrast_new_soft_renderbuffer(struct gl_context *ctx, GLuint name) { - struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, name); - if (rb) { - rb->AllocStorage = soft_renderbuffer_storage; + struct swrast_renderbuffer *srb = CALLOC_STRUCT(swrast_renderbuffer); + if (srb) { + _mesa_init_renderbuffer(&srb->Base, name); + srb->Base.AllocStorage = soft_renderbuffer_storage; + srb->Base.Delete = soft_renderbuffer_delete; } - return rb; + return &srb->Base; } @@ -241,7 +265,7 @@ add_color_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb, assert(fb->Attachment[b].Renderbuffer == NULL); - rb = _mesa_new_renderbuffer(ctx, 0); + rb = ctx->Driver.NewRenderbuffer(ctx, 0); if (!rb) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating color buffer"); return GL_FALSE; @@ -279,7 +303,7 @@ add_depth_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb, assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer == NULL); - rb = _mesa_new_renderbuffer(ctx, 0); + rb = _swrast_new_soft_renderbuffer(ctx, 0); if (!rb) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating depth buffer"); return GL_FALSE; @@ -324,7 +348,7 @@ add_stencil_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb, assert(fb->Attachment[BUFFER_STENCIL].Renderbuffer == NULL); - rb = _mesa_new_renderbuffer(ctx, 0); + rb = _swrast_new_soft_renderbuffer(ctx, 0); if (!rb) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating stencil buffer"); return GL_FALSE; @@ -349,7 +373,7 @@ add_depth_stencil_renderbuffer(struct gl_context *ctx, assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer == NULL); assert(fb->Attachment[BUFFER_STENCIL].Renderbuffer == NULL); - rb = _mesa_new_renderbuffer(ctx, 0); + rb = _swrast_new_soft_renderbuffer(ctx, 0); if (!rb) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating depth+stencil buffer"); return GL_FALSE; @@ -388,7 +412,7 @@ add_accum_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb, assert(fb->Attachment[BUFFER_ACCUM].Renderbuffer == NULL); - rb = _mesa_new_renderbuffer(ctx, 0); + rb = _swrast_new_soft_renderbuffer(ctx, 0); if (!rb) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating accum buffer"); return GL_FALSE; @@ -428,7 +452,7 @@ add_aux_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb, assert(numBuffers <= MAX_AUX_BUFFERS); for (i = 0; i < numBuffers; i++) { - struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, 0); + struct gl_renderbuffer *rb = _swrast_new_soft_renderbuffer(ctx, 0); assert(fb->Attachment[BUFFER_AUX0 + i].Renderbuffer == NULL); @@ -524,3 +548,150 @@ _swrast_add_soft_renderbuffers(struct gl_framebuffer *fb, } #endif } + + + +static void +map_attachment(struct gl_context *ctx, + struct gl_framebuffer *fb, + gl_buffer_index buffer) +{ + struct gl_texture_object *texObj = fb->Attachment[buffer].Texture; + struct gl_renderbuffer *rb = fb->Attachment[buffer].Renderbuffer; + struct swrast_renderbuffer *srb = swrast_renderbuffer(rb); + + if (texObj) { + /* map texture image (render to texture) */ + const GLuint level = fb->Attachment[buffer].TextureLevel; + const GLuint face = fb->Attachment[buffer].CubeMapFace; + const GLuint slice = fb->Attachment[buffer].Zoffset; + struct gl_texture_image *texImage = texObj->Image[face][level]; + if (texImage) { + ctx->Driver.MapTextureImage(ctx, texImage, slice, + 0, 0, texImage->Width, texImage->Height, + GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, + &srb->Map, &srb->RowStride); + } + } + else if (rb) { + /* Map ordinary renderbuffer */ + ctx->Driver.MapRenderbuffer(ctx, rb, + 0, 0, rb->Width, rb->Height, + GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, + &srb->Map, &srb->RowStride); + } + + assert(srb->Map); +} + + +static void +unmap_attachment(struct gl_context *ctx, + struct gl_framebuffer *fb, + gl_buffer_index buffer) +{ + struct gl_texture_object *texObj = fb->Attachment[buffer].Texture; + struct gl_renderbuffer *rb = fb->Attachment[buffer].Renderbuffer; + struct swrast_renderbuffer *srb = swrast_renderbuffer(rb); + + if (texObj) { + /* unmap texture image (render to texture) */ + const GLuint level = fb->Attachment[buffer].TextureLevel; + const GLuint face = fb->Attachment[buffer].CubeMapFace; + const GLuint slice = fb->Attachment[buffer].Zoffset; + struct gl_texture_image *texImage = texObj->Image[face][level]; + if (texImage) { + ctx->Driver.UnmapTextureImage(ctx, texImage, slice); + } + } + else if (rb) { + /* unmap ordinary renderbuffer */ + ctx->Driver.UnmapRenderbuffer(ctx, rb); + } + + srb->Map = NULL; +} + + +/** + * Determine what type to use (ubyte vs. float) for span colors for the + * given renderbuffer. + * See also _swrast_write_rgba_span(). + */ +static void +find_renderbuffer_colortype(struct gl_renderbuffer *rb) +{ + struct swrast_renderbuffer *srb = swrast_renderbuffer(rb); + GLuint rbMaxBits = _mesa_get_format_max_bits(rb->Format); + GLenum rbDatatype = _mesa_get_format_datatype(rb->Format); + + if (rbDatatype == GL_UNSIGNED_NORMALIZED && rbMaxBits <= 8) { + /* the buffer's values fit in GLubyte values */ + srb->ColorType = GL_UNSIGNED_BYTE; + } + else { + /* use floats otherwise */ + srb->ColorType = GL_FLOAT; + } +} + + +/** + * Map the renderbuffers we'll use for tri/line/point rendering. + */ +void +_swrast_map_renderbuffers(struct gl_context *ctx) +{ + struct gl_framebuffer *fb = ctx->DrawBuffer; + struct gl_renderbuffer *depthRb, *stencilRb; + GLuint buf; + + depthRb = fb->Attachment[BUFFER_DEPTH].Renderbuffer; + if (depthRb) { + /* map depth buffer */ + map_attachment(ctx, fb, BUFFER_DEPTH); + } + + stencilRb = fb->Attachment[BUFFER_STENCIL].Renderbuffer; + if (stencilRb && stencilRb != depthRb) { + /* map stencil buffer */ + map_attachment(ctx, fb, BUFFER_STENCIL); + } + + for (buf = 0; buf < fb->_NumColorDrawBuffers; buf++) { + if (fb->_ColorDrawBufferIndexes[buf] >= 0) { + map_attachment(ctx, fb, fb->_ColorDrawBufferIndexes[buf]); + find_renderbuffer_colortype(fb->_ColorDrawBuffers[buf]); + } + } +} + + +/** + * Unmap renderbuffers after rendering. + */ +void +_swrast_unmap_renderbuffers(struct gl_context *ctx) +{ + struct gl_framebuffer *fb = ctx->DrawBuffer; + struct gl_renderbuffer *depthRb, *stencilRb; + GLuint buf; + + depthRb = fb->Attachment[BUFFER_DEPTH].Renderbuffer; + if (depthRb) { + /* map depth buffer */ + unmap_attachment(ctx, fb, BUFFER_DEPTH); + } + + stencilRb = fb->Attachment[BUFFER_STENCIL].Renderbuffer; + if (stencilRb && stencilRb != depthRb) { + /* map stencil buffer */ + unmap_attachment(ctx, fb, BUFFER_STENCIL); + } + + for (buf = 0; buf < fb->_NumColorDrawBuffers; buf++) { + if (fb->_ColorDrawBufferIndexes[buf] >= 0) { + unmap_attachment(ctx, fb, fb->_ColorDrawBufferIndexes[buf]); + } + } +}