1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/context.h" 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/colormac.h" 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/fbobject.h" 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/macros.h" 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/teximage.h" 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/renderbuffer.h" 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "swrast/swrast.h" 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "swrast/s_context.h" 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "swrast/s_texfetch.h" 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Render-to-texture code for GL_EXT_framebuffer_object 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdelete_texture_wrapper(struct gl_context *ctx, struct gl_renderbuffer *rb) 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT(rb->RefCount == 0); 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(rb); 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This function creates a renderbuffer object which wraps a texture image. 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The new renderbuffer is plugged into the given attachment point. 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This allows rendering into the texture as if it were a renderbuffer. 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgwrap_texture(struct gl_context *ctx, struct gl_renderbuffer_attachment *att) 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_renderbuffer *rb; 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLuint name = 0; 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT(att->Type == GL_TEXTURE); 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT(att->Renderbuffer == NULL); 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rb = ctx->Driver.NewRenderbuffer(ctx, name); 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!rb) { 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_OUT_OF_MEMORY, "wrap_texture"); 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* init base gl_renderbuffer fields */ 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_init_renderbuffer(rb, name); 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* plug in our texture_renderbuffer-specific functions */ 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rb->Delete = delete_texture_wrapper; 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rb->AllocStorage = NULL; /* illegal! */ 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* update attachment point */ 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_reference_renderbuffer(&att->Renderbuffer, rb); 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Update the renderbuffer wrapper for rendering to a texture. 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * For example, update the width, height of the RB based on the texture size, 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * update the internal format info, etc. 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgupdate_wrapper(struct gl_context *ctx, struct gl_renderbuffer_attachment *att) 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_renderbuffer *rb = att->Renderbuffer; 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct swrast_renderbuffer *srb = swrast_renderbuffer(rb); 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct swrast_texture_image *swImage; 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org gl_format format; 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint zOffset; 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (void) ctx; 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org swImage = swrast_texture_image(_mesa_get_attachment_teximage(att)); 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(swImage); 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org format = swImage->Base.TexFormat; 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (att->Texture->Target == GL_TEXTURE_1D_ARRAY_EXT) { 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org zOffset = 0; 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org zOffset = att->Zoffset; 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rb->Width = swImage->Base.Width; 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rb->Height = swImage->Base.Height; 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rb->InternalFormat = swImage->Base.InternalFormat; 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rb->_BaseFormat = _mesa_get_format_base_format(format); 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Want to store linear values, not sRGB */ 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rb->Format = _mesa_get_srgb_format_linear(format); 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Set the gl_renderbuffer::Buffer field so that mapping the buffer 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * succeeds. 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (att->Texture->Target == GL_TEXTURE_3D || 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org att->Texture->Target == GL_TEXTURE_2D_ARRAY_EXT) { 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org srb->Buffer = swImage->Buffer + 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org swImage->ImageOffsets[zOffset] * _mesa_get_format_bytes(format); 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org srb->Buffer = swImage->Buffer; 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Called when rendering to a texture image begins, or when changing 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the dest mipmap level, cube face, etc. 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This is a fallback routine for software render-to-texture. 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Called via the glRenderbufferTexture1D/2D/3D() functions 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and elsewhere (such as glTexImage2D). 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The image we're rendering into is 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * att->Texture->Image[att->CubeMapFace][att->TextureLevel]; 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * It'll never be NULL. 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param fb the framebuffer object the texture is being bound to 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param att the fb attachment point of the texture 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \sa _mesa_framebuffer_renderbuffer 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_swrast_render_texture(struct gl_context *ctx, 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_framebuffer *fb, 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_renderbuffer_attachment *att) 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (void) fb; 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!att->Renderbuffer) { 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org wrap_texture(ctx, att); 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org update_wrapper(ctx, att); 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_swrast_finish_render_texture(struct gl_context *ctx, 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_renderbuffer_attachment *att) 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* do nothing */ 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* The renderbuffer texture wrapper will get deleted by the 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * normal mechanism for deleting renderbuffers. 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (void) ctx; 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (void) att; 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 149