📄 intel_fbo.c
字号:
return GL_FALSE;}voidintel_renderbuffer_set_region(struct intel_renderbuffer *rb, struct intel_region *region){ struct intel_region *old; old = rb->region; rb->region = NULL; intel_region_reference(&rb->region, region); intel_region_release(&old); rb->pfMap = region->map; rb->pfPitch = region->pitch;}/** * Create a new intel_renderbuffer which corresponds to an on-screen window, * not a user-created renderbuffer. */struct intel_renderbuffer *intel_create_renderbuffer(GLenum intFormat){ GET_CURRENT_CONTEXT(ctx); struct intel_renderbuffer *irb; const GLuint name = 0; irb = CALLOC_STRUCT(intel_renderbuffer); if (!irb) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer"); return NULL; } _mesa_init_renderbuffer(&irb->Base, name); irb->Base.ClassID = INTEL_RB_CLASS; switch (intFormat) { case GL_RGB5: irb->Base._ActualFormat = GL_RGB5; irb->Base._BaseFormat = GL_RGBA; irb->Base.RedBits = 5; irb->Base.GreenBits = 6; irb->Base.BlueBits = 5; irb->Base.DataType = GL_UNSIGNED_BYTE; break; case GL_RGBA8: irb->Base._ActualFormat = GL_RGBA8; irb->Base._BaseFormat = GL_RGBA; irb->Base.RedBits = 8; irb->Base.GreenBits = 8; irb->Base.BlueBits = 8; irb->Base.AlphaBits = 8; irb->Base.DataType = GL_UNSIGNED_BYTE; break; case GL_STENCIL_INDEX8_EXT: irb->Base._ActualFormat = GL_STENCIL_INDEX8_EXT; irb->Base._BaseFormat = GL_STENCIL_INDEX; irb->Base.StencilBits = 8; irb->Base.DataType = GL_UNSIGNED_BYTE; break; case GL_DEPTH_COMPONENT16: irb->Base._ActualFormat = GL_DEPTH_COMPONENT16; irb->Base._BaseFormat = GL_DEPTH_COMPONENT; irb->Base.DepthBits = 16; irb->Base.DataType = GL_UNSIGNED_SHORT; break; case GL_DEPTH_COMPONENT24: irb->Base._ActualFormat = GL_DEPTH24_STENCIL8_EXT; irb->Base._BaseFormat = GL_DEPTH_COMPONENT; irb->Base.DepthBits = 24; irb->Base.DataType = GL_UNSIGNED_INT; break; case GL_DEPTH24_STENCIL8_EXT: irb->Base._ActualFormat = GL_DEPTH24_STENCIL8_EXT; irb->Base._BaseFormat = GL_DEPTH_STENCIL_EXT; irb->Base.DepthBits = 24; irb->Base.StencilBits = 8; irb->Base.DataType = GL_UNSIGNED_INT_24_8_EXT; break; default: _mesa_problem(NULL, "Unexpected intFormat in intel_create_renderbuffer"); return NULL; } irb->Base.InternalFormat = intFormat; /* intel-specific methods */ irb->Base.Delete = intel_delete_renderbuffer; irb->Base.AllocStorage = intel_alloc_window_storage; irb->Base.GetPointer = intel_get_pointer; /* This sets the Get/PutRow/Value functions */ intel_set_span_functions(&irb->Base); return irb;}/** * Create a new renderbuffer object. * Typically called via glBindRenderbufferEXT(). */static struct gl_renderbuffer *intel_new_renderbuffer(GLcontext * ctx, GLuint name){ /*struct intel_context *intel = intel_context(ctx); */ struct intel_renderbuffer *irb; irb = CALLOC_STRUCT(intel_renderbuffer); if (!irb) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer"); return NULL; } _mesa_init_renderbuffer(&irb->Base, name); irb->Base.ClassID = INTEL_RB_CLASS; /* intel-specific methods */ irb->Base.Delete = intel_delete_renderbuffer; irb->Base.AllocStorage = intel_alloc_renderbuffer_storage; irb->Base.GetPointer = intel_get_pointer; /* span routines set in alloc_storage function */ return &irb->Base;}/** * Called via glBindFramebufferEXT(). */static voidintel_bind_framebuffer(GLcontext * ctx, GLenum target, struct gl_framebuffer *fb, struct gl_framebuffer *fbread){ if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) { intel_draw_buffer(ctx, fb); /* Integer depth range depends on depth buffer bits */ if (ctx->Driver.DepthRange != NULL) ctx->Driver.DepthRange(ctx, ctx->Viewport.Near, ctx->Viewport.Far); } else { /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */ }}/** * Called via glFramebufferRenderbufferEXT(). */static voidintel_framebuffer_renderbuffer(GLcontext * ctx, struct gl_framebuffer *fb, GLenum attachment, struct gl_renderbuffer *rb){ DBG("Intel FramebufferRenderbuffer %u %u\n", fb->Name, rb ? rb->Name : 0); intelFlush(ctx); _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb); intel_draw_buffer(ctx, fb);}static GLbooleanintel_update_wrapper(GLcontext *ctx, struct intel_renderbuffer *irb, struct gl_texture_image *texImage){ if (texImage->TexFormat == &_mesa_texformat_argb8888) { irb->Base._ActualFormat = GL_RGBA8; irb->Base._BaseFormat = GL_RGBA; DBG("Render to RGBA8 texture OK\n"); } else if (texImage->TexFormat == &_mesa_texformat_rgb565) { irb->Base._ActualFormat = GL_RGB5; irb->Base._BaseFormat = GL_RGB; DBG("Render to RGB5 texture OK\n"); } else if (texImage->TexFormat == &_mesa_texformat_z16) { irb->Base._ActualFormat = GL_DEPTH_COMPONENT16; irb->Base._BaseFormat = GL_DEPTH_COMPONENT; DBG("Render to DEPTH16 texture OK\n"); } else if (texImage->TexFormat == &_mesa_texformat_z24_s8) { irb->Base._ActualFormat = GL_DEPTH24_STENCIL8_EXT; irb->Base._BaseFormat = GL_DEPTH_STENCIL_EXT; DBG("Render to DEPTH_STENCIL texture OK\n"); } else { DBG("Render to texture BAD FORMAT %d\n", texImage->TexFormat->MesaFormat); return GL_FALSE; } irb->Base.InternalFormat = irb->Base._ActualFormat; irb->Base.Width = texImage->Width; irb->Base.Height = texImage->Height; irb->Base.DataType = GL_UNSIGNED_BYTE; /* FBO XXX fix */ irb->Base.RedBits = texImage->TexFormat->RedBits; irb->Base.GreenBits = texImage->TexFormat->GreenBits; irb->Base.BlueBits = texImage->TexFormat->BlueBits; irb->Base.AlphaBits = texImage->TexFormat->AlphaBits; irb->Base.DepthBits = texImage->TexFormat->DepthBits; irb->Base.Delete = intel_delete_renderbuffer; irb->Base.AllocStorage = intel_nop_alloc_storage; intel_set_span_functions(&irb->Base); irb->RenderToTexture = GL_TRUE; return GL_TRUE;}/** * When glFramebufferTexture[123]D is called this function sets up the * gl_renderbuffer wrapper around the texture image. * This will have the region info needed for hardware rendering. */static struct intel_renderbuffer *intel_wrap_texture(GLcontext * ctx, struct gl_texture_image *texImage){ const GLuint name = ~0; /* not significant, but distinct for debugging */ struct intel_renderbuffer *irb; /* make an intel_renderbuffer to wrap the texture image */ irb = CALLOC_STRUCT(intel_renderbuffer); if (!irb) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glFramebufferTexture"); return NULL; } _mesa_init_renderbuffer(&irb->Base, name); irb->Base.ClassID = INTEL_RB_CLASS; if (!intel_update_wrapper(ctx, irb, texImage)) { _mesa_free(irb); return NULL; } return irb;}/** * Called by glFramebufferTexture[123]DEXT() (and other places) to * prepare for rendering into texture memory. This might be called * many times to choose different texture levels, cube faces, etc * before intel_finish_render_texture() is ever called. */static voidintel_render_texture(GLcontext * ctx, struct gl_framebuffer *fb, struct gl_renderbuffer_attachment *att){ struct gl_texture_image *newImage = att->Texture->Image[att->CubeMapFace][att->TextureLevel]; struct intel_renderbuffer *irb = intel_renderbuffer(att->Renderbuffer); struct intel_texture_image *intel_image; GLuint imageOffset; (void) fb; ASSERT(newImage); if (!irb) { irb = intel_wrap_texture(ctx, newImage); if (irb) { /* bind the wrapper to the attachment point */ _mesa_reference_renderbuffer(&att->Renderbuffer, &irb->Base); } else { /* fallback to software rendering */ _mesa_render_texture(ctx, fb, att); return; } } if (!intel_update_wrapper(ctx, irb, newImage)) { _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); _mesa_render_texture(ctx, fb, att); return; } DBG("Begin render texture tid %x tex=%u w=%d h=%d refcount=%d\n", _glthread_GetID(), att->Texture->Name, newImage->Width, newImage->Height, irb->Base.RefCount); /* point the renderbufer's region to the texture image region */ intel_image = intel_texture_image(newImage); if (irb->region != intel_image->mt->region) { if (irb->region) intel_region_release(&irb->region); intel_region_reference(&irb->region, intel_image->mt->region); } /* compute offset of the particular 2D image within the texture region */ imageOffset = intel_miptree_image_offset(intel_image->mt, att->CubeMapFace, att->TextureLevel); if (att->Texture->Target == GL_TEXTURE_3D) { const GLuint *offsets = intel_miptree_depth_offsets(intel_image->mt, att->TextureLevel); imageOffset += offsets[att->Zoffset]; } /* store that offset in the region */ intel_image->mt->region->draw_offset = imageOffset; /* update drawing region, etc */ intel_draw_buffer(ctx, fb);}/** * Called by Mesa when rendering to a texture is done. */static voidintel_finish_render_texture(GLcontext * ctx, struct gl_renderbuffer_attachment *att){ struct intel_renderbuffer *irb = intel_renderbuffer(att->Renderbuffer); DBG("End render texture (tid %x) tex %u\n", _glthread_GetID(), att->Texture->Name); if (irb) { /* just release the region */ intel_region_release(&irb->region); } else if (att->Renderbuffer) { /* software fallback */ _mesa_finish_render_texture(ctx, att); /* XXX FBO: Need to unmap the buffer (or in intelSpanRenderStart???) */ }}/** * Do one-time context initializations related to GL_EXT_framebuffer_object. * Hook in device driver functions. */voidintel_fbo_init(struct intel_context *intel){ intel->ctx.Driver.NewFramebuffer = intel_new_framebuffer; intel->ctx.Driver.NewRenderbuffer = intel_new_renderbuffer; intel->ctx.Driver.BindFramebuffer = intel_bind_framebuffer; intel->ctx.Driver.FramebufferRenderbuffer = intel_framebuffer_renderbuffer; intel->ctx.Driver.RenderTexture = intel_render_texture; intel->ctx.Driver.FinishRenderTexture = intel_finish_render_texture; intel->ctx.Driver.ResizeBuffers = intel_resize_buffers;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -