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