From e030d5ba8ac321b4d75587d72a0a381bb906d70e Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Thu, 5 Aug 2021 10:48:28 -0700 Subject: [PATCH] mesa: Delete libmesa_classic We no longer have any classic drivers, so we no longer need libmesa_classic Reviewed-by: Emma Anholt Acked-by: Jason Ekstrand Acked-by: Kenneth Graunke Reviewed-by: Adam Jackson Part-of: --- src/mesa/drivers/common/driverfuncs.c | 312 -- src/mesa/drivers/common/driverfuncs.h | 44 - src/mesa/drivers/common/meta.c | 3618 ---------------------- src/mesa/drivers/common/meta.h | 573 ---- src/mesa/drivers/common/meta_blit.c | 543 ---- src/mesa/drivers/common/meta_generate_mipmap.c | 379 --- src/mesa/math/m_clip_tmp.h | 257 -- src/mesa/math/m_copy_tmp.h | 86 - src/mesa/math/m_dotprod_tmp.h | 102 - src/mesa/math/m_norm_tmp.h | 390 --- src/mesa/math/m_xform.c | 123 - src/mesa/math/m_xform_tmp.h | 810 ----- src/mesa/meson.build | 159 - src/mesa/sparc/norm.S | 605 ---- src/mesa/sparc/sparc.c | 142 - src/mesa/sparc/sparc.h | 36 - src/mesa/sparc/sparc_clip.S | 220 -- src/mesa/sparc/sparc_matrix.h | 153 - src/mesa/sparc/xform.S | 1392 --------- src/mesa/swrast/NOTES | 55 - src/mesa/swrast/s_aaline.c | 493 --- src/mesa/swrast/s_aaline.h | 38 - src/mesa/swrast/s_aalinetemp.h | 245 -- src/mesa/swrast/s_aatriangle.c | 296 -- src/mesa/swrast/s_aatriangle.h | 38 - src/mesa/swrast/s_aatritemp.h | 343 --- src/mesa/swrast/s_alpha.c | 159 - src/mesa/swrast/s_alpha.h | 39 - src/mesa/swrast/s_atifragshader.c | 592 ---- src/mesa/swrast/s_atifragshader.h | 37 - src/mesa/swrast/s_bitmap.c | 223 -- src/mesa/swrast/s_blend.c | 1006 ------- src/mesa/swrast/s_blend.h | 45 - src/mesa/swrast/s_blit.c | 816 ----- src/mesa/swrast/s_chan.h | 128 - src/mesa/swrast/s_clear.c | 333 -- src/mesa/swrast/s_context.c | 953 ------ src/mesa/swrast/s_context.h | 499 --- src/mesa/swrast/s_copypix.c | 668 ---- src/mesa/swrast/s_depth.c | 854 ------ src/mesa/swrast/s_depth.h | 58 - src/mesa/swrast/s_drawpix.c | 791 ----- src/mesa/swrast/s_feedback.c | 137 - src/mesa/swrast/s_feedback.h | 50 - src/mesa/swrast/s_fog.c | 245 -- src/mesa/swrast/s_fog.h | 42 - src/mesa/swrast/s_fragprog.c | 284 -- src/mesa/swrast/s_fragprog.h | 42 - src/mesa/swrast/s_lines.c | 267 -- src/mesa/swrast/s_lines.h | 41 - src/mesa/swrast/s_linetemp.h | 402 --- src/mesa/swrast/s_logic.c | 218 -- src/mesa/swrast/s_logic.h | 40 - src/mesa/swrast/s_masking.c | 108 - src/mesa/swrast/s_masking.h | 41 - src/mesa/swrast/s_points.c | 564 ---- src/mesa/swrast/s_points.h | 39 - src/mesa/swrast/s_renderbuffer.c | 642 ---- src/mesa/swrast/s_renderbuffer.h | 66 - src/mesa/swrast/s_span.c | 1595 ---------- src/mesa/swrast/s_span.h | 217 -- src/mesa/swrast/s_stencil.c | 710 ----- src/mesa/swrast/s_stencil.h | 53 - src/mesa/swrast/s_texcombine.c | 721 ----- src/mesa/swrast/s_texcombine.h | 37 - src/mesa/swrast/s_texfetch.c | 368 --- src/mesa/swrast/s_texfetch.h | 35 - src/mesa/swrast/s_texfetch_tmp.h | 190 -- src/mesa/swrast/s_texfilter.c | 3844 ------------------------ src/mesa/swrast/s_texfilter.h | 42 - src/mesa/swrast/s_texrender.c | 102 - src/mesa/swrast/s_texture.c | 388 --- src/mesa/swrast/s_triangle.c | 1164 ------- src/mesa/swrast/s_triangle.h | 50 - src/mesa/swrast/s_tritemp.h | 935 ------ src/mesa/swrast/s_zoom.c | 442 --- src/mesa/swrast/s_zoom.h | 56 - src/mesa/swrast/swrast.h | 301 -- src/mesa/swrast_setup/NOTES | 65 - src/mesa/swrast_setup/ss_context.c | 305 -- src/mesa/swrast_setup/ss_context.h | 45 - src/mesa/swrast_setup/ss_triangle.c | 267 -- src/mesa/swrast_setup/ss_triangle.h | 38 - src/mesa/swrast_setup/ss_tritmp.h | 248 -- src/mesa/swrast_setup/ss_vb.h | 37 - src/mesa/swrast_setup/swrast_setup.h | 61 - src/mesa/tnl/NOTES | 100 - src/mesa/tnl/t_context.c | 253 -- src/mesa/tnl/t_context.h | 594 ---- src/mesa/tnl/t_draw.c | 657 ---- src/mesa/tnl/t_pipeline.c | 300 -- src/mesa/tnl/t_pipeline.h | 73 - src/mesa/tnl/t_rebase.c | 267 -- src/mesa/tnl/t_rebase.h | 41 - src/mesa/tnl/t_split.c | 162 - src/mesa/tnl/t_split.h | 74 - src/mesa/tnl/t_split_copy.c | 637 ---- src/mesa/tnl/t_split_inplace.c | 296 -- src/mesa/tnl/t_vb_cliptmp.h | 317 -- src/mesa/tnl/t_vb_fog.c | 277 -- src/mesa/tnl/t_vb_light.c | 477 --- src/mesa/tnl/t_vb_lighttmp.h | 641 ---- src/mesa/tnl/t_vb_normals.c | 186 -- src/mesa/tnl/t_vb_points.c | 115 - src/mesa/tnl/t_vb_program.c | 539 ---- src/mesa/tnl/t_vb_render.c | 350 --- src/mesa/tnl/t_vb_rendertmp.h | 487 --- src/mesa/tnl/t_vb_texgen.c | 610 ---- src/mesa/tnl/t_vb_texmat.c | 127 - src/mesa/tnl/t_vb_vertex.c | 288 -- src/mesa/tnl/t_vertex.c | 580 ---- src/mesa/tnl/t_vertex.h | 184 -- src/mesa/tnl/t_vertex_generic.c | 1152 ------- src/mesa/tnl/t_vertex_sse.c | 685 ----- src/mesa/tnl/t_vp_build.c | 49 - src/mesa/tnl/t_vp_build.h | 41 - src/mesa/tnl/tnl.h | 208 -- src/mesa/x86-64/x86-64.c | 119 - src/mesa/x86/3dnow.c | 84 - src/mesa/x86/3dnow.h | 36 - src/mesa/x86/3dnow_xform1.S | 438 --- src/mesa/x86/3dnow_xform2.S | 478 --- src/mesa/x86/3dnow_xform3.S | 562 ---- src/mesa/x86/3dnow_xform4.S | 571 ---- src/mesa/x86/clip_args.h | 59 - src/mesa/x86/mmx.h | 59 - src/mesa/x86/mmx_blend.S | 403 --- src/mesa/x86/mmx_blendtmp.h | 114 - src/mesa/x86/norm_args.h | 57 - src/mesa/x86/rtasm/x86sse.c | 1207 -------- src/mesa/x86/rtasm/x86sse.h | 256 -- src/mesa/x86/sse.c | 123 - src/mesa/x86/sse.h | 36 - src/mesa/x86/sse_normal.S | 262 -- src/mesa/x86/sse_xform1.S | 447 --- src/mesa/x86/sse_xform2.S | 467 --- src/mesa/x86/sse_xform3.S | 513 ---- src/mesa/x86/sse_xform4.S | 236 -- src/mesa/x86/x86_cliptest.S | 408 --- src/mesa/x86/x86_xform.c | 126 - src/mesa/x86/x86_xform.h | 106 - src/mesa/x86/x86_xform2.S | 575 ---- src/mesa/x86/x86_xform3.S | 645 ---- src/mesa/x86/x86_xform4.S | 678 ----- src/mesa/x86/xform_args.h | 51 - 145 files changed, 54080 deletions(-) delete mode 100644 src/mesa/drivers/common/driverfuncs.c delete mode 100644 src/mesa/drivers/common/driverfuncs.h delete mode 100644 src/mesa/drivers/common/meta.c delete mode 100644 src/mesa/drivers/common/meta.h delete mode 100644 src/mesa/drivers/common/meta_blit.c delete mode 100644 src/mesa/drivers/common/meta_generate_mipmap.c delete mode 100644 src/mesa/math/m_clip_tmp.h delete mode 100644 src/mesa/math/m_copy_tmp.h delete mode 100644 src/mesa/math/m_dotprod_tmp.h delete mode 100644 src/mesa/math/m_norm_tmp.h delete mode 100644 src/mesa/math/m_xform.c delete mode 100644 src/mesa/math/m_xform_tmp.h delete mode 100644 src/mesa/sparc/norm.S delete mode 100644 src/mesa/sparc/sparc.c delete mode 100644 src/mesa/sparc/sparc.h delete mode 100644 src/mesa/sparc/sparc_clip.S delete mode 100644 src/mesa/sparc/sparc_matrix.h delete mode 100644 src/mesa/sparc/xform.S delete mode 100644 src/mesa/swrast/NOTES delete mode 100644 src/mesa/swrast/s_aaline.c delete mode 100644 src/mesa/swrast/s_aaline.h delete mode 100644 src/mesa/swrast/s_aalinetemp.h delete mode 100644 src/mesa/swrast/s_aatriangle.c delete mode 100644 src/mesa/swrast/s_aatriangle.h delete mode 100644 src/mesa/swrast/s_aatritemp.h delete mode 100644 src/mesa/swrast/s_alpha.c delete mode 100644 src/mesa/swrast/s_alpha.h delete mode 100644 src/mesa/swrast/s_atifragshader.c delete mode 100644 src/mesa/swrast/s_atifragshader.h delete mode 100644 src/mesa/swrast/s_bitmap.c delete mode 100644 src/mesa/swrast/s_blend.c delete mode 100644 src/mesa/swrast/s_blend.h delete mode 100644 src/mesa/swrast/s_blit.c delete mode 100644 src/mesa/swrast/s_chan.h delete mode 100644 src/mesa/swrast/s_clear.c delete mode 100644 src/mesa/swrast/s_context.c delete mode 100644 src/mesa/swrast/s_context.h delete mode 100644 src/mesa/swrast/s_copypix.c delete mode 100644 src/mesa/swrast/s_depth.c delete mode 100644 src/mesa/swrast/s_depth.h delete mode 100644 src/mesa/swrast/s_drawpix.c delete mode 100644 src/mesa/swrast/s_feedback.c delete mode 100644 src/mesa/swrast/s_feedback.h delete mode 100644 src/mesa/swrast/s_fog.c delete mode 100644 src/mesa/swrast/s_fog.h delete mode 100644 src/mesa/swrast/s_fragprog.c delete mode 100644 src/mesa/swrast/s_fragprog.h delete mode 100644 src/mesa/swrast/s_lines.c delete mode 100644 src/mesa/swrast/s_lines.h delete mode 100644 src/mesa/swrast/s_linetemp.h delete mode 100644 src/mesa/swrast/s_logic.c delete mode 100644 src/mesa/swrast/s_logic.h delete mode 100644 src/mesa/swrast/s_masking.c delete mode 100644 src/mesa/swrast/s_masking.h delete mode 100644 src/mesa/swrast/s_points.c delete mode 100644 src/mesa/swrast/s_points.h delete mode 100644 src/mesa/swrast/s_renderbuffer.c delete mode 100644 src/mesa/swrast/s_renderbuffer.h delete mode 100644 src/mesa/swrast/s_span.c delete mode 100644 src/mesa/swrast/s_span.h delete mode 100644 src/mesa/swrast/s_stencil.c delete mode 100644 src/mesa/swrast/s_stencil.h delete mode 100644 src/mesa/swrast/s_texcombine.c delete mode 100644 src/mesa/swrast/s_texcombine.h delete mode 100644 src/mesa/swrast/s_texfetch.c delete mode 100644 src/mesa/swrast/s_texfetch.h delete mode 100644 src/mesa/swrast/s_texfetch_tmp.h delete mode 100644 src/mesa/swrast/s_texfilter.c delete mode 100644 src/mesa/swrast/s_texfilter.h delete mode 100644 src/mesa/swrast/s_texrender.c delete mode 100644 src/mesa/swrast/s_texture.c delete mode 100644 src/mesa/swrast/s_triangle.c delete mode 100644 src/mesa/swrast/s_triangle.h delete mode 100644 src/mesa/swrast/s_tritemp.h delete mode 100644 src/mesa/swrast/s_zoom.c delete mode 100644 src/mesa/swrast/s_zoom.h delete mode 100644 src/mesa/swrast/swrast.h delete mode 100644 src/mesa/swrast_setup/NOTES delete mode 100644 src/mesa/swrast_setup/ss_context.c delete mode 100644 src/mesa/swrast_setup/ss_context.h delete mode 100644 src/mesa/swrast_setup/ss_triangle.c delete mode 100644 src/mesa/swrast_setup/ss_triangle.h delete mode 100644 src/mesa/swrast_setup/ss_tritmp.h delete mode 100644 src/mesa/swrast_setup/ss_vb.h delete mode 100644 src/mesa/swrast_setup/swrast_setup.h delete mode 100644 src/mesa/tnl/NOTES delete mode 100644 src/mesa/tnl/t_context.c delete mode 100644 src/mesa/tnl/t_context.h delete mode 100644 src/mesa/tnl/t_draw.c delete mode 100644 src/mesa/tnl/t_pipeline.c delete mode 100644 src/mesa/tnl/t_pipeline.h delete mode 100644 src/mesa/tnl/t_rebase.c delete mode 100644 src/mesa/tnl/t_rebase.h delete mode 100644 src/mesa/tnl/t_split.c delete mode 100644 src/mesa/tnl/t_split.h delete mode 100644 src/mesa/tnl/t_split_copy.c delete mode 100644 src/mesa/tnl/t_split_inplace.c delete mode 100644 src/mesa/tnl/t_vb_cliptmp.h delete mode 100644 src/mesa/tnl/t_vb_fog.c delete mode 100644 src/mesa/tnl/t_vb_light.c delete mode 100644 src/mesa/tnl/t_vb_lighttmp.h delete mode 100644 src/mesa/tnl/t_vb_normals.c delete mode 100644 src/mesa/tnl/t_vb_points.c delete mode 100644 src/mesa/tnl/t_vb_program.c delete mode 100644 src/mesa/tnl/t_vb_render.c delete mode 100644 src/mesa/tnl/t_vb_rendertmp.h delete mode 100644 src/mesa/tnl/t_vb_texgen.c delete mode 100644 src/mesa/tnl/t_vb_texmat.c delete mode 100644 src/mesa/tnl/t_vb_vertex.c delete mode 100644 src/mesa/tnl/t_vertex.c delete mode 100644 src/mesa/tnl/t_vertex.h delete mode 100644 src/mesa/tnl/t_vertex_generic.c delete mode 100644 src/mesa/tnl/t_vertex_sse.c delete mode 100644 src/mesa/tnl/t_vp_build.c delete mode 100644 src/mesa/tnl/t_vp_build.h delete mode 100644 src/mesa/tnl/tnl.h delete mode 100644 src/mesa/x86-64/x86-64.c delete mode 100644 src/mesa/x86/3dnow.c delete mode 100644 src/mesa/x86/3dnow.h delete mode 100644 src/mesa/x86/3dnow_xform1.S delete mode 100644 src/mesa/x86/3dnow_xform2.S delete mode 100644 src/mesa/x86/3dnow_xform3.S delete mode 100644 src/mesa/x86/3dnow_xform4.S delete mode 100644 src/mesa/x86/clip_args.h delete mode 100644 src/mesa/x86/mmx.h delete mode 100644 src/mesa/x86/mmx_blend.S delete mode 100644 src/mesa/x86/mmx_blendtmp.h delete mode 100644 src/mesa/x86/norm_args.h delete mode 100644 src/mesa/x86/rtasm/x86sse.c delete mode 100644 src/mesa/x86/rtasm/x86sse.h delete mode 100644 src/mesa/x86/sse.c delete mode 100644 src/mesa/x86/sse.h delete mode 100644 src/mesa/x86/sse_normal.S delete mode 100644 src/mesa/x86/sse_xform1.S delete mode 100644 src/mesa/x86/sse_xform2.S delete mode 100644 src/mesa/x86/sse_xform3.S delete mode 100644 src/mesa/x86/sse_xform4.S delete mode 100644 src/mesa/x86/x86_cliptest.S delete mode 100644 src/mesa/x86/x86_xform.c delete mode 100644 src/mesa/x86/x86_xform.h delete mode 100644 src/mesa/x86/x86_xform2.S delete mode 100644 src/mesa/x86/x86_xform3.S delete mode 100644 src/mesa/x86/x86_xform4.S delete mode 100644 src/mesa/x86/xform_args.h diff --git a/src/mesa/drivers/common/driverfuncs.c b/src/mesa/drivers/common/driverfuncs.c deleted file mode 100644 index 47a10c0..0000000 --- a/src/mesa/drivers/common/driverfuncs.c +++ /dev/null @@ -1,312 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -#include "main/glheader.h" -#include "main/accum.h" -#include "main/arrayobj.h" -#include "main/context.h" -#include "main/draw.h" -#include "main/formatquery.h" -#include "main/framebuffer.h" -#include "main/mipmap.h" -#include "main/queryobj.h" -#include "main/readpix.h" -#include "main/rastpos.h" -#include "main/renderbuffer.h" -#include "main/shaderobj.h" -#include "main/texcompress.h" -#include "main/texformat.h" -#include "main/texgetimage.h" -#include "main/teximage.h" -#include "main/texobj.h" -#include "main/texstorage.h" -#include "main/texstore.h" -#include "main/bufferobj.h" -#include "main/fbobject.h" -#include "main/samplerobj.h" -#include "main/syncobj.h" -#include "main/barrier.h" -#include "main/transformfeedback.h" -#include "main/externalobjects.h" - -#include "program/program.h" -#include "tnl/tnl.h" -#include "swrast/swrast.h" -#include "swrast/s_renderbuffer.h" - -#include "driverfuncs.h" -#include "meta.h" - - - -/** - * Plug in default functions for all pointers in the dd_function_table - * structure. - * Device drivers should call this function and then plug in any - * functions which it wants to override. - * Some functions (pointers) MUST be implemented by all drivers (REQUIRED). - * - * \param table the dd_function_table to initialize - */ -void -_mesa_init_driver_functions(struct dd_function_table *driver) -{ - memset(driver, 0, sizeof(*driver)); - - driver->GetString = NULL; /* REQUIRED! */ - driver->UpdateState = NULL; /* REQUIRED! */ - - driver->Finish = NULL; - driver->Flush = NULL; - - /* framebuffer/image functions */ - driver->Clear = _swrast_Clear; - driver->RasterPos = _mesa_RasterPos; - driver->DrawPixels = _swrast_DrawPixels; - driver->ReadPixels = _mesa_readpixels; - driver->CopyPixels = _swrast_CopyPixels; - driver->Bitmap = _swrast_Bitmap; - - /* Texture functions */ - driver->ChooseTextureFormat = _mesa_choose_tex_format; - driver->QueryInternalFormat = _mesa_query_internal_format_default; - driver->TexImage = _mesa_store_teximage; - driver->TexSubImage = _mesa_store_texsubimage; - driver->GetTexSubImage = _mesa_meta_GetTexSubImage; - driver->ClearTexSubImage = _mesa_meta_ClearTexSubImage; - driver->CopyTexSubImage = _mesa_meta_CopyTexSubImage; - driver->GenerateMipmap = _mesa_meta_GenerateMipmap; - driver->TestProxyTexImage = _mesa_test_proxy_teximage; - driver->CompressedTexImage = _mesa_store_compressed_teximage; - driver->CompressedTexSubImage = _mesa_store_compressed_texsubimage; - driver->BindTexture = NULL; - driver->NewTextureObject = _mesa_new_texture_object; - driver->DeleteTexture = _mesa_delete_texture_object; - driver->NewTextureImage = _swrast_new_texture_image; - driver->DeleteTextureImage = _swrast_delete_texture_image; - driver->AllocTextureImageBuffer = _swrast_alloc_texture_image_buffer; - driver->FreeTextureImageBuffer = _swrast_free_texture_image_buffer; - driver->MapTextureImage = _swrast_map_teximage; - driver->UnmapTextureImage = _swrast_unmap_teximage; - driver->DrawTex = _mesa_meta_DrawTex; - - /* Vertex/fragment programs */ - driver->NewProgram = _mesa_new_program; - driver->DeleteProgram = _mesa_delete_program; - - /* ATI_fragment_shader */ - driver->NewATIfs = NULL; - - /* Draw functions */ - driver->Draw = NULL; - driver->DrawGallium = _mesa_draw_gallium_fallback; - driver->DrawGalliumMultiMode = _mesa_draw_gallium_multimode_fallback; - driver->DrawIndirect = NULL; - driver->DrawTransformFeedback = NULL; - - /* simple state commands */ - driver->AlphaFunc = NULL; - driver->BlendColor = NULL; - driver->BlendEquationSeparate = NULL; - driver->BlendFuncSeparate = NULL; - driver->ClipPlane = NULL; - driver->ColorMask = NULL; - driver->ColorMaterial = NULL; - driver->CullFace = NULL; - driver->DrawBuffer = NULL; - driver->FrontFace = NULL; - driver->DepthFunc = NULL; - driver->DepthMask = NULL; - driver->DepthRange = NULL; - driver->Enable = NULL; - driver->Fogfv = NULL; - driver->Lightfv = NULL; - driver->LightModelfv = NULL; - driver->LineStipple = NULL; - driver->LineWidth = NULL; - driver->LogicOpcode = NULL; - driver->PointParameterfv = NULL; - driver->PointSize = NULL; - driver->PolygonMode = NULL; - driver->PolygonOffset = NULL; - driver->PolygonStipple = NULL; - driver->ReadBuffer = NULL; - driver->RenderMode = NULL; - driver->Scissor = NULL; - driver->ShadeModel = NULL; - driver->StencilFuncSeparate = NULL; - driver->StencilOpSeparate = NULL; - driver->StencilMaskSeparate = NULL; - driver->TexGen = NULL; - driver->TexEnv = NULL; - driver->TexParameter = NULL; - driver->Viewport = NULL; - - /* buffer objects */ - _mesa_init_buffer_object_functions(driver); - - /* query objects */ - _mesa_init_query_object_functions(driver); - - _mesa_init_sync_object_functions(driver); - - /* memory objects */ - _mesa_init_memory_object_functions(driver); - - driver->NewFramebuffer = _mesa_new_framebuffer; - driver->NewRenderbuffer = _swrast_new_soft_renderbuffer; - driver->MapRenderbuffer = _swrast_map_soft_renderbuffer; - driver->UnmapRenderbuffer = _swrast_unmap_soft_renderbuffer; - driver->RenderTexture = _swrast_render_texture; - driver->FinishRenderTexture = _swrast_finish_render_texture; - driver->FramebufferRenderbuffer = _mesa_FramebufferRenderbuffer_sw; - driver->ValidateFramebuffer = _mesa_validate_framebuffer; - - driver->BlitFramebuffer = _swrast_BlitFramebuffer; - driver->DiscardFramebuffer = NULL; - - _mesa_init_barrier_functions(driver); - _mesa_init_shader_object_functions(driver); - _mesa_init_transform_feedback_functions(driver); - _mesa_init_sampler_object_functions(driver); - - /* T&L stuff */ - driver->CurrentExecPrimitive = 0; - driver->CurrentSavePrimitive = 0; - driver->NeedFlush = 0; - driver->SaveNeedFlush = 0; - - driver->ProgramStringNotify = _tnl_program_string; - driver->LightingSpaceChange = NULL; - - /* GL_ARB_texture_storage */ - driver->AllocTextureStorage = _mesa_AllocTextureStorage_sw; - - /* GL_ARB_texture_view */ - driver->TextureView = NULL; - - /* GL_ARB_texture_multisample */ - driver->GetSamplePosition = NULL; - - /* Multithreading */ - driver->SetBackgroundContext = NULL; -} - - -/** - * Call the ctx->Driver.* state functions with current values to initialize - * driver state. - * Only the Intel drivers use this so far. - */ -void -_mesa_init_driver_state(struct gl_context *ctx) -{ - ctx->Driver.AlphaFunc(ctx, ctx->Color.AlphaFunc, ctx->Color.AlphaRef); - - ctx->Driver.BlendColor(ctx, ctx->Color.BlendColor); - - ctx->Driver.BlendEquationSeparate(ctx, - ctx->Color.Blend[0].EquationRGB, - ctx->Color.Blend[0].EquationA); - - ctx->Driver.BlendFuncSeparate(ctx, - ctx->Color.Blend[0].SrcRGB, - ctx->Color.Blend[0].DstRGB, - ctx->Color.Blend[0].SrcA, - ctx->Color.Blend[0].DstA); - - ctx->Driver.ColorMask(ctx, - GET_COLORMASK_BIT(ctx->Color.ColorMask, 0, 0), - GET_COLORMASK_BIT(ctx->Color.ColorMask, 0, 1), - GET_COLORMASK_BIT(ctx->Color.ColorMask, 0, 2), - GET_COLORMASK_BIT(ctx->Color.ColorMask, 0, 3)); - - ctx->Driver.CullFace(ctx, ctx->Polygon.CullFaceMode); - ctx->Driver.DepthFunc(ctx, ctx->Depth.Func); - ctx->Driver.DepthMask(ctx, ctx->Depth.Mask); - - ctx->Driver.Enable(ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled); - ctx->Driver.Enable(ctx, GL_BLEND, ctx->Color.BlendEnabled); - ctx->Driver.Enable(ctx, GL_COLOR_LOGIC_OP, ctx->Color.ColorLogicOpEnabled); - ctx->Driver.Enable(ctx, GL_COLOR_SUM, ctx->Fog.ColorSumEnabled); - ctx->Driver.Enable(ctx, GL_CULL_FACE, ctx->Polygon.CullFlag); - ctx->Driver.Enable(ctx, GL_DEPTH_TEST, ctx->Depth.Test); - ctx->Driver.Enable(ctx, GL_DITHER, ctx->Color.DitherFlag); - ctx->Driver.Enable(ctx, GL_FOG, ctx->Fog.Enabled); - ctx->Driver.Enable(ctx, GL_LIGHTING, ctx->Light.Enabled); - ctx->Driver.Enable(ctx, GL_LINE_SMOOTH, ctx->Line.SmoothFlag); - ctx->Driver.Enable(ctx, GL_POLYGON_STIPPLE, ctx->Polygon.StippleFlag); - ctx->Driver.Enable(ctx, GL_SCISSOR_TEST, ctx->Scissor.EnableFlags); - ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled); - ctx->Driver.Enable(ctx, GL_TEXTURE_1D, GL_FALSE); - ctx->Driver.Enable(ctx, GL_TEXTURE_2D, GL_FALSE); - ctx->Driver.Enable(ctx, GL_TEXTURE_RECTANGLE_NV, GL_FALSE); - ctx->Driver.Enable(ctx, GL_TEXTURE_3D, GL_FALSE); - ctx->Driver.Enable(ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE); - - ctx->Driver.Fogfv(ctx, GL_FOG_COLOR, ctx->Fog.Color); - { - GLfloat mode = (GLfloat) ctx->Fog.Mode; - ctx->Driver.Fogfv(ctx, GL_FOG_MODE, &mode); - } - ctx->Driver.Fogfv(ctx, GL_FOG_DENSITY, &ctx->Fog.Density); - ctx->Driver.Fogfv(ctx, GL_FOG_START, &ctx->Fog.Start); - ctx->Driver.Fogfv(ctx, GL_FOG_END, &ctx->Fog.End); - - ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace); - - { - GLfloat f = (GLfloat) ctx->Light.Model.ColorControl; - ctx->Driver.LightModelfv(ctx, GL_LIGHT_MODEL_COLOR_CONTROL, &f); - } - - ctx->Driver.LineWidth(ctx, ctx->Line.Width); - ctx->Driver.LogicOpcode(ctx, ctx->Color._LogicOp); - ctx->Driver.PointSize(ctx, ctx->Point.Size); - ctx->Driver.PolygonStipple(ctx, (const GLubyte *) ctx->PolygonStipple); - ctx->Driver.Scissor(ctx); - ctx->Driver.ShadeModel(ctx, ctx->Light.ShadeModel); - ctx->Driver.StencilFuncSeparate(ctx, GL_FRONT, - ctx->Stencil.Function[0], - ctx->Stencil.Ref[0], - ctx->Stencil.ValueMask[0]); - ctx->Driver.StencilFuncSeparate(ctx, GL_BACK, - ctx->Stencil.Function[1], - ctx->Stencil.Ref[1], - ctx->Stencil.ValueMask[1]); - ctx->Driver.StencilMaskSeparate(ctx, GL_FRONT, ctx->Stencil.WriteMask[0]); - ctx->Driver.StencilMaskSeparate(ctx, GL_BACK, ctx->Stencil.WriteMask[1]); - ctx->Driver.StencilOpSeparate(ctx, GL_FRONT, - ctx->Stencil.FailFunc[0], - ctx->Stencil.ZFailFunc[0], - ctx->Stencil.ZPassFunc[0]); - ctx->Driver.StencilOpSeparate(ctx, GL_BACK, - ctx->Stencil.FailFunc[1], - ctx->Stencil.ZFailFunc[1], - ctx->Stencil.ZPassFunc[1]); - - - ctx->Driver.DrawBuffer(ctx); -} diff --git a/src/mesa/drivers/common/driverfuncs.h b/src/mesa/drivers/common/driverfuncs.h deleted file mode 100644 index 385ccb8..0000000 --- a/src/mesa/drivers/common/driverfuncs.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -#ifndef DRIVERFUNCS_H -#define DRIVERFUNCS_H - -#ifdef __cplusplus -extern "C" { -#endif - -extern void -_mesa_init_driver_functions(struct dd_function_table *driver); - - -extern void -_mesa_init_driver_state(struct gl_context *ctx); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c deleted file mode 100644 index 5ebe7c5..0000000 --- a/src/mesa/drivers/common/meta.c +++ /dev/null @@ -1,3618 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 2009 VMware, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -/** - * Meta operations. Some GL operations can be expressed in terms of - * other GL operations. For example, glBlitFramebuffer() can be done - * with texture mapping and glClear() can be done with polygon rendering. - * - * \author Brian Paul - */ - - -#include "main/glheader.h" -#include "main/mtypes.h" -#include "main/arbprogram.h" -#include "main/arrayobj.h" -#include "main/blend.h" -#include "main/blit.h" -#include "main/bufferobj.h" -#include "main/buffers.h" -#include "main/clear.h" -#include "main/condrender.h" -#include "main/draw.h" -#include "main/draw_validate.h" -#include "main/depth.h" -#include "main/enable.h" -#include "main/fbobject.h" -#include "main/feedback.h" -#include "main/formats.h" -#include "main/format_unpack.h" -#include "main/framebuffer.h" -#include "main/glformats.h" -#include "main/image.h" -#include "main/macros.h" -#include "main/matrix.h" -#include "main/mipmap.h" -#include "main/multisample.h" -#include "main/objectlabel.h" -#include "main/pipelineobj.h" -#include "main/pixel.h" -#include "main/pbo.h" -#include "main/polygon.h" -#include "main/queryobj.h" -#include "main/readpix.h" -#include "main/renderbuffer.h" -#include "main/scissor.h" -#include "main/shaderapi.h" -#include "main/shaderobj.h" -#include "main/state.h" -#include "main/stencil.h" -#include "main/texobj.h" -#include "main/texenv.h" -#include "main/texgetimage.h" -#include "main/teximage.h" -#include "main/texparam.h" -#include "main/texstate.h" -#include "main/texstore.h" -#include "main/transformfeedback.h" -#include "main/uniforms.h" -#include "main/varray.h" -#include "main/viewport.h" -#include "main/samplerobj.h" -#include "program/program.h" -#include "swrast/swrast.h" -#include "drivers/common/meta.h" -#include "main/enums.h" -#include "main/glformats.h" -#include "util/bitscan.h" -#include "util/ralloc.h" -#include "compiler/nir/nir.h" -#include "util/u_math.h" -#include "util/u_memory.h" - -/** Return offset in bytes of the field within a vertex struct */ -#define OFFSET(FIELD) ((void *) offsetof(struct vertex, FIELD)) - -static void -meta_clear(struct gl_context *ctx, GLbitfield buffers, bool glsl); - -static struct blit_shader * -choose_blit_shader(GLenum target, struct blit_shader_table *table); - -static void cleanup_temp_texture(struct gl_context *ctx, - struct temp_texture *tex); -static void meta_glsl_clear_cleanup(struct gl_context *ctx, - struct clear_state *clear); -static void meta_copypix_cleanup(struct gl_context *ctx, - struct copypix_state *copypix); -static void meta_decompress_cleanup(struct gl_context *ctx, - struct decompress_state *decompress); -static void meta_drawpix_cleanup(struct gl_context *ctx, - struct drawpix_state *drawpix); -static void meta_drawtex_cleanup(struct gl_context *ctx, - struct drawtex_state *drawtex); -static void meta_bitmap_cleanup(struct gl_context *ctx, - struct bitmap_state *bitmap); - -void -_mesa_meta_framebuffer_texture_image(struct gl_context *ctx, - struct gl_framebuffer *fb, - GLenum attachment, - struct gl_texture_image *texImage, - GLuint layer) -{ - struct gl_texture_object *texObj = texImage->TexObject; - int level = texImage->Level; - const GLenum texTarget = texObj->Target == GL_TEXTURE_CUBE_MAP - ? GL_TEXTURE_CUBE_MAP_POSITIVE_X + texImage->Face - : texObj->Target; - - struct gl_renderbuffer_attachment *att = - _mesa_get_and_validate_attachment(ctx, fb, attachment, __func__); - assert(att); - - _mesa_framebuffer_texture(ctx, fb, attachment, att, texObj, texTarget, - level, att->NumSamples, layer, false); -} - -static struct gl_shader * -meta_compile_shader_with_debug(struct gl_context *ctx, gl_shader_stage stage, - const GLcharARB *source) -{ - const GLuint name = ~0; - struct gl_shader *sh; - - sh = _mesa_new_shader(name, stage); - sh->Source = strdup(source); - sh->CompileStatus = COMPILE_FAILURE; - _mesa_compile_shader(ctx, sh); - - if (!sh->CompileStatus) { - if (sh->InfoLog) { - _mesa_problem(ctx, - "meta program compile failed:\n%s\nsource:\n%s\n", - sh->InfoLog, source); - } - - _mesa_reference_shader(ctx, &sh, NULL); - } - - return sh; -} - -void -_mesa_meta_link_program_with_debug(struct gl_context *ctx, - struct gl_shader_program *sh_prog) -{ - _mesa_link_program(ctx, sh_prog); - - if (!sh_prog->data->LinkStatus) { - _mesa_problem(ctx, "meta program link failed:\n%s", - sh_prog->data->InfoLog); - } -} - -void -_mesa_meta_use_program(struct gl_context *ctx, - struct gl_shader_program *sh_prog) -{ - /* Attach shader state to the binding point */ - _mesa_reference_pipeline_object(ctx, &ctx->_Shader, &ctx->Shader); - - /* Update the program */ - _mesa_use_shader_program(ctx, sh_prog); -} - -void -_mesa_meta_compile_and_link_program(struct gl_context *ctx, - const char *vs_source, - const char *fs_source, - const char *name, - struct gl_shader_program **out_sh_prog) -{ - struct gl_shader_program *sh_prog; - const GLuint id = ~0; - - sh_prog = _mesa_new_shader_program(id); - sh_prog->Label = strdup(name); - sh_prog->NumShaders = 2; - sh_prog->Shaders = malloc(2 * sizeof(struct gl_shader *)); - sh_prog->Shaders[0] = - meta_compile_shader_with_debug(ctx, MESA_SHADER_VERTEX, vs_source); - sh_prog->Shaders[1] = - meta_compile_shader_with_debug(ctx, MESA_SHADER_FRAGMENT, fs_source); - - _mesa_meta_link_program_with_debug(ctx, sh_prog); - - struct gl_program *fp = - sh_prog->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program; - - /* texelFetch() can break GL_SKIP_DECODE_EXT, but many meta passes want - * to use both together; pretend that we're not using texelFetch to hack - * around this bad interaction. This is a bit fragile as it may break - * if you re-run the pass that gathers this info, but we probably won't... - */ - BITSET_ZERO(fp->info.textures_used_by_txf); - if (fp->nir) - BITSET_ZERO(fp->nir->info.textures_used_by_txf); - - _mesa_meta_use_program(ctx, sh_prog); - - *out_sh_prog = sh_prog; -} - -/** - * Generate a generic shader to blit from a texture to a framebuffer - * - * \param ctx Current GL context - * \param texTarget Texture target that will be the source of the blit - * - * \returns a handle to a shader program on success or zero on failure. - */ -void -_mesa_meta_setup_blit_shader(struct gl_context *ctx, - GLenum target, - bool do_depth, - struct blit_shader_table *table) -{ - char *vs_source, *fs_source; - struct blit_shader *shader = choose_blit_shader(target, table); - const char *fs_input, *vs_preprocess, *fs_preprocess; - void *mem_ctx; - - if (ctx->Const.GLSLVersion < 130) { - vs_preprocess = ""; - fs_preprocess = "#extension GL_EXT_texture_array : enable"; - fs_input = "varying"; - } else { - vs_preprocess = "#version 130"; - fs_preprocess = "#version 130"; - fs_input = "in"; - shader->func = "texture"; - } - - assert(shader != NULL); - - if (shader->shader_prog != NULL) { - _mesa_meta_use_program(ctx, shader->shader_prog); - return; - } - - mem_ctx = ralloc_context(NULL); - - vs_source = ralloc_asprintf(mem_ctx, - "%s\n" - "#extension GL_ARB_explicit_attrib_location: enable\n" - "layout(location = 0) in vec2 position;\n" - "layout(location = 1) in vec4 textureCoords;\n" - "out vec4 texCoords;\n" - "void main()\n" - "{\n" - " texCoords = textureCoords;\n" - " gl_Position = vec4(position, 0.0, 1.0);\n" - "}\n", - vs_preprocess); - - fs_source = ralloc_asprintf(mem_ctx, - "%s\n" - "#extension GL_ARB_texture_cube_map_array: enable\n" - "uniform %s texSampler;\n" - "%s vec4 texCoords;\n" - "void main()\n" - "{\n" - " gl_FragColor = %s(texSampler, %s);\n" - "%s" - "}\n", - fs_preprocess, shader->type, fs_input, - shader->func, shader->texcoords, - do_depth ? " gl_FragDepth = gl_FragColor.x;\n" : ""); - - _mesa_meta_compile_and_link_program(ctx, vs_source, fs_source, - ralloc_asprintf(mem_ctx, "%s blit", - shader->type), - &shader->shader_prog); - ralloc_free(mem_ctx); -} - -/** - * Configure vertex buffer and vertex array objects for tests - * - * Regardless of whether a new VAO is created, the object referenced by \c VAO - * will be bound into the GL state vector when this function terminates. The - * object referenced by \c VBO will \b not be bound. - * - * \param VAO Storage for vertex array object handle. If 0, a new VAO - * will be created. - * \param buf_obj Storage for vertex buffer object pointer. If \c NULL, a new VBO - * will be created. The new VBO will have storage for 4 - * \c vertex structures. - * \param use_generic_attributes Should generic attributes 0 and 1 be used, - * or should traditional, fixed-function color and texture - * coordinate be used? - * \param vertex_size Number of components for attribute 0 / vertex. - * \param texcoord_size Number of components for attribute 1 / texture - * coordinate. If this is 0, attribute 1 will not be set or - * enabled. - * \param color_size Number of components for attribute 1 / primary color. - * If this is 0, attribute 1 will not be set or enabled. - * - * \note If \c use_generic_attributes is \c true, \c color_size must be zero. - * Use \c texcoord_size instead. - */ -void -_mesa_meta_setup_vertex_objects(struct gl_context *ctx, - GLuint *VAO, struct gl_buffer_object **buf_obj, - bool use_generic_attributes, - unsigned vertex_size, unsigned texcoord_size, - unsigned color_size) -{ - if (*VAO == 0) { - struct gl_vertex_array_object *array_obj; - assert(*buf_obj == NULL); - - /* create vertex array object */ - _mesa_GenVertexArrays(1, VAO); - _mesa_BindVertexArray(*VAO); - - array_obj = _mesa_lookup_vao(ctx, *VAO); - assert(array_obj != NULL); - - /* create vertex array buffer */ - *buf_obj = ctx->Driver.NewBufferObject(ctx, 0xDEADBEEF); - if (*buf_obj == NULL) - return; - - _mesa_buffer_data(ctx, *buf_obj, GL_NONE, 4 * sizeof(struct vertex), NULL, - GL_DYNAMIC_DRAW, __func__); - - /* setup vertex arrays */ - FLUSH_VERTICES(ctx, 0, 0); - if (use_generic_attributes) { - assert(color_size == 0); - - _mesa_update_array_format(ctx, array_obj, VERT_ATTRIB_GENERIC(0), - vertex_size, GL_FLOAT, GL_RGBA, GL_FALSE, - GL_FALSE, GL_FALSE, - offsetof(struct vertex, x)); - _mesa_bind_vertex_buffer(ctx, array_obj, VERT_ATTRIB_GENERIC(0), - *buf_obj, 0, sizeof(struct vertex), false, - false); - _mesa_enable_vertex_array_attrib(ctx, array_obj, - VERT_ATTRIB_GENERIC(0)); - if (texcoord_size > 0) { - _mesa_update_array_format(ctx, array_obj, VERT_ATTRIB_GENERIC(1), - texcoord_size, GL_FLOAT, GL_RGBA, - GL_FALSE, GL_FALSE, GL_FALSE, - offsetof(struct vertex, tex)); - _mesa_bind_vertex_buffer(ctx, array_obj, VERT_ATTRIB_GENERIC(1), - *buf_obj, 0, sizeof(struct vertex), false, - false); - _mesa_enable_vertex_array_attrib(ctx, array_obj, - VERT_ATTRIB_GENERIC(1)); - } - } else { - _mesa_update_array_format(ctx, array_obj, VERT_ATTRIB_POS, - vertex_size, GL_FLOAT, GL_RGBA, GL_FALSE, - GL_FALSE, GL_FALSE, - offsetof(struct vertex, x)); - _mesa_bind_vertex_buffer(ctx, array_obj, VERT_ATTRIB_POS, - *buf_obj, 0, sizeof(struct vertex), false, - false); - _mesa_enable_vertex_array_attrib(ctx, array_obj, VERT_ATTRIB_POS); - - if (texcoord_size > 0) { - _mesa_update_array_format(ctx, array_obj, VERT_ATTRIB_TEX(0), - vertex_size, GL_FLOAT, GL_RGBA, GL_FALSE, - GL_FALSE, GL_FALSE, - offsetof(struct vertex, tex)); - _mesa_bind_vertex_buffer(ctx, array_obj, VERT_ATTRIB_TEX(0), - *buf_obj, 0, sizeof(struct vertex), false, - false); - _mesa_enable_vertex_array_attrib(ctx, array_obj, - VERT_ATTRIB_TEX(0)); - } - - if (color_size > 0) { - _mesa_update_array_format(ctx, array_obj, VERT_ATTRIB_COLOR0, - vertex_size, GL_FLOAT, GL_RGBA, GL_FALSE, - GL_FALSE, GL_FALSE, - offsetof(struct vertex, r)); - _mesa_bind_vertex_buffer(ctx, array_obj, VERT_ATTRIB_COLOR0, - *buf_obj, 0, sizeof(struct vertex), false, - false); - _mesa_enable_vertex_array_attrib(ctx, array_obj, - VERT_ATTRIB_COLOR0); - } - } - } else { - _mesa_BindVertexArray(*VAO); - } -} - -/** - * Initialize meta-ops for a context. - * To be called once during context creation. - */ -void -_mesa_meta_init(struct gl_context *ctx) -{ - assert(!ctx->Meta); - - ctx->Meta = CALLOC_STRUCT(gl_meta_state); -} - -/** - * Free context meta-op state. - * To be called once during context destruction. - */ -void -_mesa_meta_free(struct gl_context *ctx) -{ - GET_CURRENT_CONTEXT(old_context); - _mesa_make_current(ctx, NULL, NULL); - _mesa_meta_glsl_blit_cleanup(ctx, &ctx->Meta->Blit); - meta_glsl_clear_cleanup(ctx, &ctx->Meta->Clear); - meta_copypix_cleanup(ctx, &ctx->Meta->CopyPix); - _mesa_meta_glsl_generate_mipmap_cleanup(ctx, &ctx->Meta->Mipmap); - cleanup_temp_texture(ctx, &ctx->Meta->TempTex); - meta_decompress_cleanup(ctx, &ctx->Meta->Decompress); - meta_drawpix_cleanup(ctx, &ctx->Meta->DrawPix); - meta_drawtex_cleanup(ctx, &ctx->Meta->DrawTex); - meta_bitmap_cleanup(ctx, &ctx->Meta->Bitmap); - - if (old_context) - _mesa_make_current(old_context, old_context->WinSysDrawBuffer, old_context->WinSysReadBuffer); - else - _mesa_make_current(NULL, NULL, NULL); - free(ctx->Meta); - ctx->Meta = NULL; -} - - -/** - * Enter meta state. This is like a light-weight version of glPushAttrib - * but it also resets most GL state back to default values. - * - * \param state bitmask of MESA_META_* flags indicating which attribute groups - * to save and reset to their defaults - */ -void -_mesa_meta_begin(struct gl_context *ctx, GLbitfield state) -{ - struct save_state *save; - - /* hope MAX_META_OPS_DEPTH is large enough */ - assert(ctx->Meta->SaveStackDepth < MAX_META_OPS_DEPTH); - - save = &ctx->Meta->Save[ctx->Meta->SaveStackDepth++]; - memset(save, 0, sizeof(*save)); - save->SavedState = state; - - /* We always push into desktop GL mode and pop out at the end. No sense in - * writing our shaders varying based on the user's context choice, when - * Mesa can handle either. - */ - save->API = ctx->API; - ctx->API = API_OPENGL_COMPAT; - - /* Mesa's extension helper functions use the current context's API to look up - * the version required by an extension as a step in determining whether or - * not it has been advertised. Since meta aims to only be restricted by the - * driver capability (and not by whether or not an extension has been - * advertised), set the helper functions' Version variable to a value that - * will make the checks on the context API and version unconditionally pass. - */ - save->ExtensionsVersion = ctx->Extensions.Version; - ctx->Extensions.Version = ~0; - - /* Pausing transform feedback needs to be done early, or else we won't be - * able to change other state. - */ - save->TransformFeedbackNeedsResume = - _mesa_is_xfb_active_and_unpaused(ctx); - if (save->TransformFeedbackNeedsResume) - _mesa_PauseTransformFeedback(); - - /* After saving the current occlusion object, call EndQuery so that no - * occlusion querying will be active during the meta-operation. - */ - if (state & MESA_META_OCCLUSION_QUERY) { - save->CurrentOcclusionObject = ctx->Query.CurrentOcclusionObject; - if (save->CurrentOcclusionObject) - _mesa_EndQuery(save->CurrentOcclusionObject->Target); - } - - if (state & MESA_META_ALPHA_TEST) { - save->AlphaEnabled = ctx->Color.AlphaEnabled; - save->AlphaFunc = ctx->Color.AlphaFunc; - save->AlphaRef = ctx->Color.AlphaRef; - if (ctx->Color.AlphaEnabled) - _mesa_set_enable(ctx, GL_ALPHA_TEST, GL_FALSE); - } - - if (state & MESA_META_BLEND) { - save->BlendEnabled = ctx->Color.BlendEnabled; - if (ctx->Color.BlendEnabled) { - if (ctx->Extensions.EXT_draw_buffers2) { - GLuint i; - for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { - _mesa_set_enablei(ctx, GL_BLEND, i, GL_FALSE); - } - } - else { - _mesa_set_enable(ctx, GL_BLEND, GL_FALSE); - } - } - save->ColorLogicOpEnabled = ctx->Color.ColorLogicOpEnabled; - if (ctx->Color.ColorLogicOpEnabled) - _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, GL_FALSE); - } - - if (state & MESA_META_DITHER) { - save->DitherFlag = ctx->Color.DitherFlag; - _mesa_set_enable(ctx, GL_DITHER, GL_TRUE); - } - - if (state & MESA_META_COLOR_MASK) - save->ColorMask = ctx->Color.ColorMask; - - if (state & MESA_META_DEPTH_TEST) { - save->Depth = ctx->Depth; /* struct copy */ - if (ctx->Depth.Test) - _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_FALSE); - } - - if (state & MESA_META_FOG) { - save->Fog = ctx->Fog.Enabled; - if (ctx->Fog.Enabled) - _mesa_set_enable(ctx, GL_FOG, GL_FALSE); - } - - if (state & MESA_META_PIXEL_STORE) { - save->Pack = ctx->Pack; - save->Unpack = ctx->Unpack; - ctx->Pack = ctx->DefaultPacking; - ctx->Unpack = ctx->DefaultPacking; - } - - if (state & MESA_META_PIXEL_TRANSFER) { - save->RedScale = ctx->Pixel.RedScale; - save->RedBias = ctx->Pixel.RedBias; - save->GreenScale = ctx->Pixel.GreenScale; - save->GreenBias = ctx->Pixel.GreenBias; - save->BlueScale = ctx->Pixel.BlueScale; - save->BlueBias = ctx->Pixel.BlueBias; - save->AlphaScale = ctx->Pixel.AlphaScale; - save->AlphaBias = ctx->Pixel.AlphaBias; - save->MapColorFlag = ctx->Pixel.MapColorFlag; - ctx->Pixel.RedScale = 1.0F; - ctx->Pixel.RedBias = 0.0F; - ctx->Pixel.GreenScale = 1.0F; - ctx->Pixel.GreenBias = 0.0F; - ctx->Pixel.BlueScale = 1.0F; - ctx->Pixel.BlueBias = 0.0F; - ctx->Pixel.AlphaScale = 1.0F; - ctx->Pixel.AlphaBias = 0.0F; - ctx->Pixel.MapColorFlag = GL_FALSE; - /* XXX more state */ - ctx->NewState |=_NEW_PIXEL; - } - - if (state & MESA_META_RASTERIZATION) { - save->FrontPolygonMode = ctx->Polygon.FrontMode; - save->BackPolygonMode = ctx->Polygon.BackMode; - save->PolygonOffset = ctx->Polygon.OffsetFill; - save->PolygonSmooth = ctx->Polygon.SmoothFlag; - save->PolygonStipple = ctx->Polygon.StippleFlag; - save->PolygonCull = ctx->Polygon.CullFlag; - _mesa_PolygonMode(GL_FRONT_AND_BACK, GL_FILL); - _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL, GL_FALSE); - _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, GL_FALSE); - _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, GL_FALSE); - _mesa_set_enable(ctx, GL_CULL_FACE, GL_FALSE); - } - - if (state & MESA_META_SCISSOR) { - save->Scissor = ctx->Scissor; /* struct copy */ - _mesa_set_enable(ctx, GL_SCISSOR_TEST, GL_FALSE); - } - - if (state & MESA_META_SHADER) { - int i; - - if (ctx->Extensions.ARB_vertex_program) { - save->VertexProgramEnabled = ctx->VertexProgram.Enabled; - _mesa_reference_program(ctx, &save->VertexProgram, - ctx->VertexProgram.Current); - _mesa_set_enable(ctx, GL_VERTEX_PROGRAM_ARB, GL_FALSE); - } - - if (ctx->Extensions.ARB_fragment_program) { - save->FragmentProgramEnabled = ctx->FragmentProgram.Enabled; - _mesa_reference_program(ctx, &save->FragmentProgram, - ctx->FragmentProgram.Current); - _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_FALSE); - } - - if (ctx->Extensions.ATI_fragment_shader) { - save->ATIFragmentShaderEnabled = ctx->ATIFragmentShader.Enabled; - _mesa_set_enable(ctx, GL_FRAGMENT_SHADER_ATI, GL_FALSE); - } - - if (ctx->Pipeline.Current) { - _mesa_reference_pipeline_object(ctx, &save->Pipeline, - ctx->Pipeline.Current); - _mesa_BindProgramPipeline(0); - } - - /* Save the shader state from ctx->Shader (instead of ctx->_Shader) so - * that we don't have to worry about the current pipeline state. - */ - for (i = 0; i < MESA_SHADER_STAGES; i++) { - _mesa_reference_program(ctx, &save->Program[i], - ctx->Shader.CurrentProgram[i]); - } - _mesa_reference_shader_program(ctx, &save->ActiveShader, - ctx->Shader.ActiveProgram); - - _mesa_UseProgram(0); - } - - if (state & MESA_META_STENCIL_TEST) { - save->Stencil = ctx->Stencil; /* struct copy */ - if (ctx->Stencil.Enabled) - _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_FALSE); - /* NOTE: other stencil state not reset */ - } - - if (state & MESA_META_TEXTURE) { - GLuint u, tgt; - - save->ActiveUnit = ctx->Texture.CurrentUnit; - save->EnvMode = ctx->Texture.FixedFuncUnit[0].EnvMode; - - /* Disable all texture units */ - for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - save->TexEnabled[u] = ctx->Texture.FixedFuncUnit[u].Enabled; - save->TexGenEnabled[u] = ctx->Texture.FixedFuncUnit[u].TexGenEnabled; - if (ctx->Texture.FixedFuncUnit[u].Enabled || - ctx->Texture.FixedFuncUnit[u].TexGenEnabled) { - _mesa_ActiveTexture(GL_TEXTURE0 + u); - _mesa_set_enable(ctx, GL_TEXTURE_2D, GL_FALSE); - if (ctx->Extensions.ARB_texture_cube_map) - _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE); - - _mesa_set_enable(ctx, GL_TEXTURE_1D, GL_FALSE); - _mesa_set_enable(ctx, GL_TEXTURE_3D, GL_FALSE); - if (ctx->Extensions.NV_texture_rectangle) - _mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE, GL_FALSE); - _mesa_set_enable(ctx, GL_TEXTURE_GEN_S, GL_FALSE); - _mesa_set_enable(ctx, GL_TEXTURE_GEN_T, GL_FALSE); - _mesa_set_enable(ctx, GL_TEXTURE_GEN_R, GL_FALSE); - _mesa_set_enable(ctx, GL_TEXTURE_GEN_Q, GL_FALSE); - } - } - - /* save current texture objects for unit[0] only */ - for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { - _mesa_reference_texobj(&save->CurrentTexture[tgt], - ctx->Texture.Unit[0].CurrentTex[tgt]); - } - - /* set defaults for unit[0] */ - _mesa_ActiveTexture(GL_TEXTURE0); - _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - } - - if (state & MESA_META_TRANSFORM) { - memcpy(save->ModelviewMatrix, ctx->ModelviewMatrixStack.Top->m, - 16 * sizeof(GLfloat)); - memcpy(save->ProjectionMatrix, ctx->ProjectionMatrixStack.Top->m, - 16 * sizeof(GLfloat)); - memcpy(save->TextureMatrix, ctx->TextureMatrixStack[0].Top->m, - 16 * sizeof(GLfloat)); - - /* set 1:1 vertex:pixel coordinate transform */ - _mesa_load_identity_matrix(ctx, &ctx->ModelviewMatrixStack); - _mesa_load_identity_matrix(ctx, &ctx->TextureMatrixStack[0]); - - /* _math_float_ortho with width = 0 or height = 0 will have a divide by - * zero. This can occur when there is no draw buffer. - */ - if (ctx->DrawBuffer->Width != 0 && ctx->DrawBuffer->Height != 0) { - float m[16]; - - _math_float_ortho(m, - 0.0f, (float) ctx->DrawBuffer->Width, - 0.0f, (float) ctx->DrawBuffer->Height, - -1.0f, 1.0f); - _mesa_load_matrix(ctx, &ctx->ProjectionMatrixStack, m); - } else { - _mesa_load_identity_matrix(ctx, &ctx->ProjectionMatrixStack); - } - - if (ctx->Extensions.ARB_clip_control) { - save->ClipOrigin = ctx->Transform.ClipOrigin; - save->ClipDepthMode = ctx->Transform.ClipDepthMode; - _mesa_ClipControl(GL_LOWER_LEFT, GL_NEGATIVE_ONE_TO_ONE); - } - } - - if (state & MESA_META_CLIP) { - GLbitfield mask; - save->ClipPlanesEnabled = ctx->Transform.ClipPlanesEnabled; - mask = ctx->Transform.ClipPlanesEnabled; - while (mask) { - const int i = u_bit_scan(&mask); - _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_FALSE); - } - } - - if (state & MESA_META_VERTEX) { - /* save vertex array object state */ - _mesa_reference_vao(ctx, &save->VAO, - ctx->Array.VAO); - /* set some default state? */ - } - - if (state & MESA_META_VIEWPORT) { - /* save viewport state */ - save->ViewportX = ctx->ViewportArray[0].X; - save->ViewportY = ctx->ViewportArray[0].Y; - save->ViewportW = ctx->ViewportArray[0].Width; - save->ViewportH = ctx->ViewportArray[0].Height; - /* set viewport to match window size */ - if (ctx->ViewportArray[0].X != 0 || - ctx->ViewportArray[0].Y != 0 || - ctx->ViewportArray[0].Width != (float) ctx->DrawBuffer->Width || - ctx->ViewportArray[0].Height != (float) ctx->DrawBuffer->Height) { - _mesa_set_viewport(ctx, 0, 0, 0, - ctx->DrawBuffer->Width, ctx->DrawBuffer->Height); - } - /* save depth range state */ - save->DepthNear = ctx->ViewportArray[0].Near; - save->DepthFar = ctx->ViewportArray[0].Far; - /* set depth range to default */ - _mesa_set_depth_range(ctx, 0, 0.0, 1.0); - } - - if (state & MESA_META_CLAMP_FRAGMENT_COLOR) { - save->ClampFragmentColor = ctx->Color.ClampFragmentColor; - - /* Generally in here we want to do clamping according to whether - * it's for the pixel path (ClampFragmentColor is GL_TRUE), - * regardless of the internal implementation of the metaops. - */ - if (ctx->Color.ClampFragmentColor != GL_TRUE && - ctx->Extensions.ARB_color_buffer_float) - _mesa_ClampColor(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE); - } - - if (state & MESA_META_CLAMP_VERTEX_COLOR) { - save->ClampVertexColor = ctx->Light.ClampVertexColor; - - /* Generally in here we never want vertex color clamping -- - * result clamping is only dependent on fragment clamping. - */ - if (ctx->Extensions.ARB_color_buffer_float) - _mesa_ClampColor(GL_CLAMP_VERTEX_COLOR, GL_FALSE); - } - - if (state & MESA_META_CONDITIONAL_RENDER) { - save->CondRenderQuery = ctx->Query.CondRenderQuery; - save->CondRenderMode = ctx->Query.CondRenderMode; - - if (ctx->Query.CondRenderQuery) - _mesa_EndConditionalRender(); - } - - if (state & MESA_META_SELECT_FEEDBACK) { - save->RenderMode = ctx->RenderMode; - if (ctx->RenderMode == GL_SELECT) { - save->Select = ctx->Select; /* struct copy */ - _mesa_RenderMode(GL_RENDER); - } else if (ctx->RenderMode == GL_FEEDBACK) { - save->Feedback = ctx->Feedback; /* struct copy */ - _mesa_RenderMode(GL_RENDER); - } - } - - if (state & MESA_META_MULTISAMPLE) { - save->Multisample = ctx->Multisample; /* struct copy */ - - if (ctx->Multisample.Enabled) - _mesa_set_multisample(ctx, GL_FALSE); - if (ctx->Multisample.SampleCoverage) - _mesa_set_enable(ctx, GL_SAMPLE_COVERAGE, GL_FALSE); - if (ctx->Multisample.SampleAlphaToCoverage) - _mesa_set_enable(ctx, GL_SAMPLE_ALPHA_TO_COVERAGE, GL_FALSE); - if (ctx->Multisample.SampleAlphaToOne) - _mesa_set_enable(ctx, GL_SAMPLE_ALPHA_TO_ONE, GL_FALSE); - if (ctx->Multisample.SampleShading) - _mesa_set_enable(ctx, GL_SAMPLE_SHADING, GL_FALSE); - if (ctx->Multisample.SampleMask) - _mesa_set_enable(ctx, GL_SAMPLE_MASK, GL_FALSE); - } - - if (state & MESA_META_FRAMEBUFFER_SRGB) { - save->sRGBEnabled = ctx->Color.sRGBEnabled; - if (ctx->Color.sRGBEnabled) - _mesa_set_framebuffer_srgb(ctx, GL_FALSE); - } - - if (state & MESA_META_DRAW_BUFFERS) { - struct gl_framebuffer *fb = ctx->DrawBuffer; - memcpy(save->ColorDrawBuffers, fb->ColorDrawBuffer, - sizeof(save->ColorDrawBuffers)); - } - - /* misc */ - { - save->Lighting = ctx->Light.Enabled; - if (ctx->Light.Enabled) - _mesa_set_enable(ctx, GL_LIGHTING, GL_FALSE); - save->RasterDiscard = ctx->RasterDiscard; - if (ctx->RasterDiscard) - _mesa_set_enable(ctx, GL_RASTERIZER_DISCARD, GL_FALSE); - - _mesa_reference_framebuffer(&save->DrawBuffer, ctx->DrawBuffer); - _mesa_reference_framebuffer(&save->ReadBuffer, ctx->ReadBuffer); - } -} - - -/** - * Leave meta state. This is like a light-weight version of glPopAttrib(). - */ -void -_mesa_meta_end(struct gl_context *ctx) -{ - assert(ctx->Meta->SaveStackDepth > 0); - - struct save_state *save = &ctx->Meta->Save[ctx->Meta->SaveStackDepth - 1]; - const GLbitfield state = save->SavedState; - int i; - - /* Grab the result of the old occlusion query before starting it again. The - * old result is added to the result of the new query so the driver will - * continue adding where it left off. */ - if (state & MESA_META_OCCLUSION_QUERY) { - if (save->CurrentOcclusionObject) { - struct gl_query_object *q = save->CurrentOcclusionObject; - GLuint64EXT result; - if (!q->Ready) - ctx->Driver.WaitQuery(ctx, q); - result = q->Result; - _mesa_BeginQuery(q->Target, q->Id); - ctx->Query.CurrentOcclusionObject->Result += result; - } - } - - if (state & MESA_META_ALPHA_TEST) { - if (ctx->Color.AlphaEnabled != save->AlphaEnabled) - _mesa_set_enable(ctx, GL_ALPHA_TEST, save->AlphaEnabled); - _mesa_AlphaFunc(save->AlphaFunc, save->AlphaRef); - } - - if (state & MESA_META_BLEND) { - if (ctx->Color.BlendEnabled != save->BlendEnabled) { - if (ctx->Extensions.EXT_draw_buffers2) { - GLuint i; - for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { - _mesa_set_enablei(ctx, GL_BLEND, i, (save->BlendEnabled >> i) & 1); - } - } - else { - _mesa_set_enable(ctx, GL_BLEND, (save->BlendEnabled & 1)); - } - } - if (ctx->Color.ColorLogicOpEnabled != save->ColorLogicOpEnabled) - _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, save->ColorLogicOpEnabled); - } - - if (state & MESA_META_DITHER) - _mesa_set_enable(ctx, GL_DITHER, save->DitherFlag); - - if (state & MESA_META_COLOR_MASK) { - GLuint i; - for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { - if (GET_COLORMASK(ctx->Color.ColorMask, i) != - GET_COLORMASK(save->ColorMask, i)) { - if (i == 0) { - _mesa_ColorMask(GET_COLORMASK_BIT(save->ColorMask, i, 0), - GET_COLORMASK_BIT(save->ColorMask, i, 1), - GET_COLORMASK_BIT(save->ColorMask, i, 2), - GET_COLORMASK_BIT(save->ColorMask, i, 3)); - } - else { - _mesa_ColorMaski(i, - GET_COLORMASK_BIT(save->ColorMask, i, 0), - GET_COLORMASK_BIT(save->ColorMask, i, 1), - GET_COLORMASK_BIT(save->ColorMask, i, 2), - GET_COLORMASK_BIT(save->ColorMask, i, 3)); - } - } - } - } - - if (state & MESA_META_DEPTH_TEST) { - if (ctx->Depth.Test != save->Depth.Test) - _mesa_set_enable(ctx, GL_DEPTH_TEST, save->Depth.Test); - _mesa_DepthFunc(save->Depth.Func); - _mesa_DepthMask(save->Depth.Mask); - } - - if (state & MESA_META_FOG) { - _mesa_set_enable(ctx, GL_FOG, save->Fog); - } - - if (state & MESA_META_PIXEL_STORE) { - ctx->Pack = save->Pack; - ctx->Unpack = save->Unpack; - } - - if (state & MESA_META_PIXEL_TRANSFER) { - ctx->Pixel.RedScale = save->RedScale; - ctx->Pixel.RedBias = save->RedBias; - ctx->Pixel.GreenScale = save->GreenScale; - ctx->Pixel.GreenBias = save->GreenBias; - ctx->Pixel.BlueScale = save->BlueScale; - ctx->Pixel.BlueBias = save->BlueBias; - ctx->Pixel.AlphaScale = save->AlphaScale; - ctx->Pixel.AlphaBias = save->AlphaBias; - ctx->Pixel.MapColorFlag = save->MapColorFlag; - /* XXX more state */ - ctx->NewState |=_NEW_PIXEL; - } - - if (state & MESA_META_RASTERIZATION) { - _mesa_PolygonMode(GL_FRONT, save->FrontPolygonMode); - _mesa_PolygonMode(GL_BACK, save->BackPolygonMode); - _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, save->PolygonStipple); - _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, save->PolygonSmooth); - _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL, save->PolygonOffset); - _mesa_set_enable(ctx, GL_CULL_FACE, save->PolygonCull); - } - - if (state & MESA_META_SCISSOR) { - unsigned i; - - for (i = 0; i < ctx->Const.MaxViewports; i++) { - _mesa_set_scissor(ctx, i, - save->Scissor.ScissorArray[i].X, - save->Scissor.ScissorArray[i].Y, - save->Scissor.ScissorArray[i].Width, - save->Scissor.ScissorArray[i].Height); - _mesa_set_enablei(ctx, GL_SCISSOR_TEST, i, - (save->Scissor.EnableFlags >> i) & 1); - } - } - - if (state & MESA_META_SHADER) { - bool any_shader; - - if (ctx->Extensions.ARB_vertex_program) { - _mesa_set_enable(ctx, GL_VERTEX_PROGRAM_ARB, - save->VertexProgramEnabled); - _mesa_reference_program(ctx, &ctx->VertexProgram.Current, - save->VertexProgram); - _mesa_reference_program(ctx, &save->VertexProgram, NULL); - } - - if (ctx->Extensions.ARB_fragment_program) { - _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, - save->FragmentProgramEnabled); - _mesa_reference_program(ctx, &ctx->FragmentProgram.Current, - save->FragmentProgram); - _mesa_reference_program(ctx, &save->FragmentProgram, NULL); - } - - if (ctx->Extensions.ATI_fragment_shader) { - _mesa_set_enable(ctx, GL_FRAGMENT_SHADER_ATI, - save->ATIFragmentShaderEnabled); - } - - any_shader = false; - for (i = 0; i < MESA_SHADER_STAGES; i++) { - /* It is safe to call _mesa_use_program even if the extension - * necessary for that program state is not supported. In that case, - * the saved program object must be NULL and the currently bound - * program object must be NULL. _mesa_use_program is a no-op - * in that case. - */ - _mesa_use_program(ctx, i, NULL, save->Program[i], &ctx->Shader); - - /* Do this *before* killing the reference. :) - */ - if (save->Program[i] != NULL) - any_shader = true; - - _mesa_reference_program(ctx, &save->Program[i], NULL); - } - - _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, - save->ActiveShader); - _mesa_reference_shader_program(ctx, &save->ActiveShader, NULL); - - /* If there were any stages set with programs, use ctx->Shader as the - * current shader state. Otherwise, use Pipeline.Default. The pipeline - * hasn't been restored yet, and that may modify ctx->_Shader further. - */ - if (any_shader) - _mesa_reference_pipeline_object(ctx, &ctx->_Shader, - &ctx->Shader); - else - _mesa_reference_pipeline_object(ctx, &ctx->_Shader, - ctx->Pipeline.Default); - - if (save->Pipeline) { - _mesa_bind_pipeline(ctx, save->Pipeline); - - _mesa_reference_pipeline_object(ctx, &save->Pipeline, NULL); - } - - _mesa_update_vertex_processing_mode(ctx); - _mesa_update_valid_to_render_state(ctx); - } - - if (state & MESA_META_STENCIL_TEST) { - const struct gl_stencil_attrib *stencil = &save->Stencil; - - _mesa_set_enable(ctx, GL_STENCIL_TEST, stencil->Enabled); - _mesa_ClearStencil(stencil->Clear); - if (ctx->Extensions.EXT_stencil_two_side) { - _mesa_set_enable(ctx, GL_STENCIL_TEST_TWO_SIDE_EXT, - stencil->TestTwoSide); - _mesa_ActiveStencilFaceEXT(stencil->ActiveFace - ? GL_BACK : GL_FRONT); - } - /* front state */ - _mesa_StencilFuncSeparate(GL_FRONT, - stencil->Function[0], - stencil->Ref[0], - stencil->ValueMask[0]); - _mesa_StencilMaskSeparate(GL_FRONT, stencil->WriteMask[0]); - _mesa_StencilOpSeparate(GL_FRONT, stencil->FailFunc[0], - stencil->ZFailFunc[0], - stencil->ZPassFunc[0]); - /* back state */ - _mesa_StencilFuncSeparate(GL_BACK, - stencil->Function[1], - stencil->Ref[1], - stencil->ValueMask[1]); - _mesa_StencilMaskSeparate(GL_BACK, stencil->WriteMask[1]); - _mesa_StencilOpSeparate(GL_BACK, stencil->FailFunc[1], - stencil->ZFailFunc[1], - stencil->ZPassFunc[1]); - } - - if (state & MESA_META_TEXTURE) { - GLuint u, tgt; - - assert(ctx->Texture.CurrentUnit == 0); - - /* restore texenv for unit[0] */ - _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, save->EnvMode); - - /* restore texture objects for unit[0] only */ - for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { - if (ctx->Texture.Unit[0].CurrentTex[tgt] != save->CurrentTexture[tgt]) { - FLUSH_VERTICES(ctx, _NEW_TEXTURE, GL_TEXTURE_BIT); - _mesa_reference_texobj(&ctx->Texture.Unit[0].CurrentTex[tgt], - save->CurrentTexture[tgt]); - } - _mesa_reference_texobj(&save->CurrentTexture[tgt], NULL); - } - - /* Restore fixed function texture enables, texgen */ - for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - if (ctx->Texture.FixedFuncUnit[u].Enabled != save->TexEnabled[u]) { - FLUSH_VERTICES(ctx, _NEW_TEXTURE, GL_TEXTURE_BIT); - ctx->Texture.FixedFuncUnit[u].Enabled = save->TexEnabled[u]; - } - - if (ctx->Texture.FixedFuncUnit[u].TexGenEnabled != save->TexGenEnabled[u]) { - FLUSH_VERTICES(ctx, _NEW_TEXTURE, GL_TEXTURE_BIT); - ctx->Texture.FixedFuncUnit[u].TexGenEnabled = save->TexGenEnabled[u]; - } - } - - /* restore current unit state */ - _mesa_ActiveTexture(GL_TEXTURE0 + save->ActiveUnit); - } - - if (state & MESA_META_TRANSFORM) { - _mesa_load_matrix(ctx, &ctx->ModelviewMatrixStack, save->ModelviewMatrix); - _mesa_load_matrix(ctx, &ctx->ProjectionMatrixStack, save->ProjectionMatrix); - _mesa_load_matrix(ctx, &ctx->TextureMatrixStack[0], save->TextureMatrix); - - if (ctx->Extensions.ARB_clip_control) - _mesa_ClipControl(save->ClipOrigin, save->ClipDepthMode); - } - - if (state & MESA_META_CLIP) { - GLbitfield mask = save->ClipPlanesEnabled; - while (mask) { - const int i = u_bit_scan(&mask); - _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_TRUE); - } - } - - if (state & MESA_META_VERTEX) { - /* restore vertex array object */ - _mesa_BindVertexArray(save->VAO->Name); - _mesa_reference_vao(ctx, &save->VAO, NULL); - } - - if (state & MESA_META_VIEWPORT) { - if (save->ViewportX != ctx->ViewportArray[0].X || - save->ViewportY != ctx->ViewportArray[0].Y || - save->ViewportW != ctx->ViewportArray[0].Width || - save->ViewportH != ctx->ViewportArray[0].Height) { - _mesa_set_viewport(ctx, 0, save->ViewportX, save->ViewportY, - save->ViewportW, save->ViewportH); - } - _mesa_set_depth_range(ctx, 0, save->DepthNear, save->DepthFar); - } - - if (state & MESA_META_CLAMP_FRAGMENT_COLOR && - ctx->Extensions.ARB_color_buffer_float) { - _mesa_ClampColor(GL_CLAMP_FRAGMENT_COLOR, save->ClampFragmentColor); - } - - if (state & MESA_META_CLAMP_VERTEX_COLOR && - ctx->Extensions.ARB_color_buffer_float) { - _mesa_ClampColor(GL_CLAMP_VERTEX_COLOR, save->ClampVertexColor); - } - - if (state & MESA_META_CONDITIONAL_RENDER) { - if (save->CondRenderQuery) - _mesa_BeginConditionalRender(save->CondRenderQuery->Id, - save->CondRenderMode); - } - - if (state & MESA_META_SELECT_FEEDBACK) { - if (save->RenderMode == GL_SELECT) { - _mesa_RenderMode(GL_SELECT); - ctx->Select = save->Select; - } else if (save->RenderMode == GL_FEEDBACK) { - _mesa_RenderMode(GL_FEEDBACK); - ctx->Feedback = save->Feedback; - } - } - - if (state & MESA_META_MULTISAMPLE) { - struct gl_multisample_attrib *ctx_ms = &ctx->Multisample; - struct gl_multisample_attrib *save_ms = &save->Multisample; - - if (ctx_ms->Enabled != save_ms->Enabled) - _mesa_set_multisample(ctx, save_ms->Enabled); - if (ctx_ms->SampleCoverage != save_ms->SampleCoverage) - _mesa_set_enable(ctx, GL_SAMPLE_COVERAGE, save_ms->SampleCoverage); - if (ctx_ms->SampleAlphaToCoverage != save_ms->SampleAlphaToCoverage) - _mesa_set_enable(ctx, GL_SAMPLE_ALPHA_TO_COVERAGE, save_ms->SampleAlphaToCoverage); - if (ctx_ms->SampleAlphaToOne != save_ms->SampleAlphaToOne) - _mesa_set_enable(ctx, GL_SAMPLE_ALPHA_TO_ONE, save_ms->SampleAlphaToOne); - if (ctx_ms->SampleCoverageValue != save_ms->SampleCoverageValue || - ctx_ms->SampleCoverageInvert != save_ms->SampleCoverageInvert) { - _mesa_SampleCoverage(save_ms->SampleCoverageValue, - save_ms->SampleCoverageInvert); - } - if (ctx_ms->SampleShading != save_ms->SampleShading) - _mesa_set_enable(ctx, GL_SAMPLE_SHADING, save_ms->SampleShading); - if (ctx_ms->SampleMask != save_ms->SampleMask) - _mesa_set_enable(ctx, GL_SAMPLE_MASK, save_ms->SampleMask); - if (ctx_ms->SampleMaskValue != save_ms->SampleMaskValue) - _mesa_SampleMaski(0, save_ms->SampleMaskValue); - if (ctx_ms->MinSampleShadingValue != save_ms->MinSampleShadingValue) - _mesa_MinSampleShading(save_ms->MinSampleShadingValue); - } - - if (state & MESA_META_FRAMEBUFFER_SRGB) { - if (ctx->Color.sRGBEnabled != save->sRGBEnabled) - _mesa_set_framebuffer_srgb(ctx, save->sRGBEnabled); - } - - /* misc */ - if (save->Lighting) { - _mesa_set_enable(ctx, GL_LIGHTING, GL_TRUE); - } - if (save->RasterDiscard) { - _mesa_set_enable(ctx, GL_RASTERIZER_DISCARD, GL_TRUE); - } - if (save->TransformFeedbackNeedsResume) - _mesa_ResumeTransformFeedback(); - - _mesa_bind_framebuffers(ctx, save->DrawBuffer, save->ReadBuffer); - _mesa_reference_framebuffer(&save->DrawBuffer, NULL); - _mesa_reference_framebuffer(&save->ReadBuffer, NULL); - - if (state & MESA_META_DRAW_BUFFERS) { - _mesa_drawbuffers(ctx, ctx->DrawBuffer, ctx->Const.MaxDrawBuffers, - save->ColorDrawBuffers, NULL); - } - - ctx->Meta->SaveStackDepth--; - - ctx->API = save->API; - ctx->Extensions.Version = save->ExtensionsVersion; -} - - -/** - * Convert Z from a normalized value in the range [0, 1] to an object-space - * Z coordinate in [-1, +1] so that drawing at the new Z position with the - * default/identity ortho projection results in the original Z value. - * Used by the meta-Clear, Draw/CopyPixels and Bitmap functions where the Z - * value comes from the clear value or raster position. - */ -static inline GLfloat -invert_z(GLfloat normZ) -{ - GLfloat objZ = 1.0f - 2.0f * normZ; - return objZ; -} - - -/** - * One-time init for a temp_texture object. - * Choose tex target, compute max tex size, etc. - */ -static void -init_temp_texture(struct gl_context *ctx, struct temp_texture *tex) -{ - /* prefer texture rectangle */ - if (_mesa_is_desktop_gl(ctx) && ctx->Extensions.NV_texture_rectangle) { - tex->Target = GL_TEXTURE_RECTANGLE; - tex->MaxSize = ctx->Const.MaxTextureRectSize; - tex->NPOT = GL_TRUE; - } - else { - /* use 2D texture, NPOT if possible */ - tex->Target = GL_TEXTURE_2D; - tex->MaxSize = ctx->Const.MaxTextureSize; - tex->NPOT = ctx->Extensions.ARB_texture_non_power_of_two; - } - tex->MinSize = 16; /* 16 x 16 at least */ - assert(tex->MaxSize > 0); - - tex->tex_obj = ctx->Driver.NewTextureObject(ctx, 0xDEADBEEF, tex->Target); -} - -static void -cleanup_temp_texture(struct gl_context *ctx, struct temp_texture *tex) -{ - _mesa_delete_nameless_texture(ctx, tex->tex_obj); - tex->tex_obj = NULL; -} - - -/** - * Return pointer to temp_texture info for non-bitmap ops. - * This does some one-time init if needed. - */ -struct temp_texture * -_mesa_meta_get_temp_texture(struct gl_context *ctx) -{ - struct temp_texture *tex = &ctx->Meta->TempTex; - - if (tex->tex_obj == NULL) { - init_temp_texture(ctx, tex); - } - - return tex; -} - - -/** - * Return pointer to temp_texture info for _mesa_meta_bitmap(). - * We use a separate texture for bitmaps to reduce texture - * allocation/deallocation. - */ -static struct temp_texture * -get_bitmap_temp_texture(struct gl_context *ctx) -{ - struct temp_texture *tex = &ctx->Meta->Bitmap.Tex; - - if (tex->tex_obj == NULL) { - init_temp_texture(ctx, tex); - } - - return tex; -} - -/** - * Return pointer to depth temp_texture. - * This does some one-time init if needed. - */ -struct temp_texture * -_mesa_meta_get_temp_depth_texture(struct gl_context *ctx) -{ - struct temp_texture *tex = &ctx->Meta->Blit.depthTex; - - if (tex->tex_obj == NULL) { - init_temp_texture(ctx, tex); - } - - return tex; -} - -/** - * Compute the width/height of texture needed to draw an image of the - * given size. Return a flag indicating whether the current texture - * can be re-used (glTexSubImage2D) or if a new texture needs to be - * allocated (glTexImage2D). - * Also, compute s/t texcoords for drawing. - * - * \return GL_TRUE if new texture is needed, GL_FALSE otherwise - */ -GLboolean -_mesa_meta_alloc_texture(struct temp_texture *tex, - GLsizei width, GLsizei height, GLenum intFormat) -{ - GLboolean newTex = GL_FALSE; - - assert(width <= tex->MaxSize); - assert(height <= tex->MaxSize); - - if (width > tex->Width || - height > tex->Height || - intFormat != tex->IntFormat) { - /* alloc new texture (larger or different format) */ - - if (tex->NPOT) { - /* use non-power of two size */ - tex->Width = MAX2(tex->MinSize, width); - tex->Height = MAX2(tex->MinSize, height); - } - else { - /* find power of two size */ - GLsizei w, h; - w = h = tex->MinSize; - while (w < width) - w *= 2; - while (h < height) - h *= 2; - tex->Width = w; - tex->Height = h; - } - - tex->IntFormat = intFormat; - - newTex = GL_TRUE; - } - - /* compute texcoords */ - if (tex->Target == GL_TEXTURE_RECTANGLE) { - tex->Sright = (GLfloat) width; - tex->Ttop = (GLfloat) height; - } - else { - tex->Sright = (GLfloat) width / tex->Width; - tex->Ttop = (GLfloat) height / tex->Height; - } - - return newTex; -} - - -/** - * Setup/load texture for glCopyPixels or glBlitFramebuffer. - */ -void -_mesa_meta_setup_copypix_texture(struct gl_context *ctx, - struct temp_texture *tex, - GLint srcX, GLint srcY, - GLsizei width, GLsizei height, - GLenum intFormat, - GLenum filter) -{ - bool newTex; - - _mesa_bind_texture(ctx, tex->Target, tex->tex_obj); - _mesa_texture_parameteriv(ctx, tex->tex_obj, GL_TEXTURE_MIN_FILTER, - (GLint *) &filter, false); - _mesa_texture_parameteriv(ctx, tex->tex_obj, GL_TEXTURE_MAG_FILTER, - (GLint *) &filter, false); - _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - - newTex = _mesa_meta_alloc_texture(tex, width, height, intFormat); - - /* copy framebuffer image to texture */ - if (newTex) { - /* create new tex image */ - if (tex->Width == width && tex->Height == height) { - /* create new tex with framebuffer data */ - _mesa_CopyTexImage2D(tex->Target, 0, tex->IntFormat, - srcX, srcY, width, height, 0); - } - else { - /* create empty texture */ - _mesa_TexImage2D(tex->Target, 0, tex->IntFormat, - tex->Width, tex->Height, 0, - intFormat, GL_UNSIGNED_BYTE, NULL); - /* load image */ - _mesa_CopyTexSubImage2D(tex->Target, 0, - 0, 0, srcX, srcY, width, height); - } - } - else { - /* replace existing tex image */ - _mesa_CopyTexSubImage2D(tex->Target, 0, - 0, 0, srcX, srcY, width, height); - } -} - - -/** - * Setup/load texture for glDrawPixels. - */ -void -_mesa_meta_setup_drawpix_texture(struct gl_context *ctx, - struct temp_texture *tex, - GLboolean newTex, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - const GLvoid *pixels) -{ - /* GLint so the compiler won't complain about type signedness mismatch in - * the call to _mesa_texture_parameteriv below. - */ - static const GLint filter = GL_NEAREST; - - _mesa_bind_texture(ctx, tex->Target, tex->tex_obj); - _mesa_texture_parameteriv(ctx, tex->tex_obj, GL_TEXTURE_MIN_FILTER, &filter, - false); - _mesa_texture_parameteriv(ctx, tex->tex_obj, GL_TEXTURE_MAG_FILTER, &filter, - false); - _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - - /* copy pixel data to texture */ - if (newTex) { - /* create new tex image */ - if (tex->Width == width && tex->Height == height) { - /* create new tex and load image data */ - _mesa_TexImage2D(tex->Target, 0, tex->IntFormat, - tex->Width, tex->Height, 0, format, type, pixels); - } - else { - struct gl_buffer_object *save_unpack_obj = NULL; - - _mesa_reference_buffer_object(ctx, &save_unpack_obj, - ctx->Unpack.BufferObj); - _mesa_BindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0); - /* create empty texture */ - _mesa_TexImage2D(tex->Target, 0, tex->IntFormat, - tex->Width, tex->Height, 0, format, type, NULL); - if (save_unpack_obj != NULL) - _mesa_BindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, - save_unpack_obj->Name); - /* load image */ - _mesa_TexSubImage2D(tex->Target, 0, - 0, 0, width, height, format, type, pixels); - - _mesa_reference_buffer_object(ctx, &save_unpack_obj, NULL); - } - } - else { - /* replace existing tex image */ - _mesa_TexSubImage2D(tex->Target, 0, - 0, 0, width, height, format, type, pixels); - } -} - -void -_mesa_meta_setup_ff_tnl_for_blit(struct gl_context *ctx, - GLuint *VAO, struct gl_buffer_object **buf_obj, - unsigned texcoord_size) -{ - _mesa_meta_setup_vertex_objects(ctx, VAO, buf_obj, false, 2, texcoord_size, - 0); - - /* setup projection matrix */ - _mesa_load_identity_matrix(ctx, &ctx->ProjectionMatrixStack); -} - -/** - * Meta implementation of ctx->Driver.Clear() in terms of polygon rendering. - */ -void -_mesa_meta_Clear(struct gl_context *ctx, GLbitfield buffers) -{ - meta_clear(ctx, buffers, false); -} - -void -_mesa_meta_glsl_Clear(struct gl_context *ctx, GLbitfield buffers) -{ - meta_clear(ctx, buffers, true); -} - -static void -meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear) -{ - const char *vs_source = - "#extension GL_AMD_vertex_shader_layer : enable\n" - "#extension GL_ARB_draw_instanced : enable\n" - "#extension GL_ARB_explicit_attrib_location :enable\n" - "layout(location = 0) in vec4 position;\n" - "void main()\n" - "{\n" - "#ifdef GL_AMD_vertex_shader_layer\n" - " gl_Layer = gl_InstanceID;\n" - "#endif\n" - " gl_Position = position;\n" - "}\n"; - const char *fs_source = - "#extension GL_ARB_explicit_attrib_location :enable\n" - "#extension GL_ARB_explicit_uniform_location :enable\n" - "layout(location = 0) uniform vec4 color;\n" - "void main()\n" - "{\n" - " gl_FragColor = color;\n" - "}\n"; - - _mesa_meta_setup_vertex_objects(ctx, &clear->VAO, &clear->buf_obj, true, - 3, 0, 0); - - if (clear->ShaderProg != 0) - return; - - _mesa_meta_compile_and_link_program(ctx, vs_source, fs_source, "meta clear", - &clear->ShaderProg); -} - -static void -meta_glsl_clear_cleanup(struct gl_context *ctx, struct clear_state *clear) -{ - if (clear->VAO == 0) - return; - _mesa_DeleteVertexArrays(1, &clear->VAO); - clear->VAO = 0; - _mesa_reference_buffer_object(ctx, &clear->buf_obj, NULL); - _mesa_reference_shader_program(ctx, &clear->ShaderProg, NULL); -} - -static void -meta_copypix_cleanup(struct gl_context *ctx, struct copypix_state *copypix) -{ - if (copypix->VAO == 0) - return; - _mesa_DeleteVertexArrays(1, ©pix->VAO); - copypix->VAO = 0; - _mesa_reference_buffer_object(ctx, ©pix->buf_obj, NULL); -} - - -/** - * Given a bitfield of BUFFER_BIT_x draw buffers, call glDrawBuffers to - * set GL to only draw to those buffers. - * - * Since the bitfield has no associated order, the assignment of draw buffer - * indices to color attachment indices is rather arbitrary. - */ -void -_mesa_meta_drawbuffers_from_bitfield(GLbitfield bits) -{ - GLenum enums[MAX_DRAW_BUFFERS]; - int i = 0; - int n; - - /* This function is only legal for color buffer bitfields. */ - assert((bits & ~BUFFER_BITS_COLOR) == 0); - - /* Make sure we don't overflow any arrays. */ - assert(util_bitcount(bits) <= MAX_DRAW_BUFFERS); - - enums[0] = GL_NONE; - - if (bits & BUFFER_BIT_FRONT_LEFT) - enums[i++] = GL_FRONT_LEFT; - - if (bits & BUFFER_BIT_FRONT_RIGHT) - enums[i++] = GL_FRONT_RIGHT; - - if (bits & BUFFER_BIT_BACK_LEFT) - enums[i++] = GL_BACK_LEFT; - - if (bits & BUFFER_BIT_BACK_RIGHT) - enums[i++] = GL_BACK_RIGHT; - - for (n = 0; n < MAX_COLOR_ATTACHMENTS; n++) { - if (bits & (1 << (BUFFER_COLOR0 + n))) - enums[i++] = GL_COLOR_ATTACHMENT0 + n; - } - - _mesa_DrawBuffers(i, enums); -} - -/** - * Given a bitfield of BUFFER_BIT_x draw buffers, call glDrawBuffers to - * set GL to only draw to those buffers. Also, update color masks to - * reflect the new draw buffer ordering. - */ -static void -_mesa_meta_drawbuffers_and_colormask(struct gl_context *ctx, GLbitfield mask) -{ - GLenum enums[MAX_DRAW_BUFFERS]; - GLubyte colormask[MAX_DRAW_BUFFERS][4]; - int num_bufs = 0; - - /* This function is only legal for color buffer bitfields. */ - assert((mask & ~BUFFER_BITS_COLOR) == 0); - - /* Make sure we don't overflow any arrays. */ - assert(util_bitcount(mask) <= MAX_DRAW_BUFFERS); - - enums[0] = GL_NONE; - - for (int i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { - gl_buffer_index b = ctx->DrawBuffer->_ColorDrawBufferIndexes[i]; - int colormask_idx = ctx->Extensions.EXT_draw_buffers2 ? i : 0; - - if (b < 0 || !(mask & (1 << b)) || - GET_COLORMASK(ctx->Color.ColorMask, colormask_idx) == 0) - continue; - - switch (b) { - case BUFFER_FRONT_LEFT: - enums[num_bufs] = GL_FRONT_LEFT; - break; - case BUFFER_FRONT_RIGHT: - enums[num_bufs] = GL_FRONT_RIGHT; - break; - case BUFFER_BACK_LEFT: - enums[num_bufs] = GL_BACK_LEFT; - break; - case BUFFER_BACK_RIGHT: - enums[num_bufs] = GL_BACK_RIGHT; - break; - default: - assert(b >= BUFFER_COLOR0 && b <= BUFFER_COLOR7); - enums[num_bufs] = GL_COLOR_ATTACHMENT0 + (b - BUFFER_COLOR0); - break; - } - - for (int k = 0; k < 4; k++) - colormask[num_bufs][k] = GET_COLORMASK_BIT(ctx->Color.ColorMask, - colormask_idx, k); - - num_bufs++; - } - - _mesa_DrawBuffers(num_bufs, enums); - - for (int i = 0; i < num_bufs; i++) { - _mesa_ColorMaski(i, colormask[i][0], colormask[i][1], - colormask[i][2], colormask[i][3]); - } -} - - -/** - * Meta implementation of ctx->Driver.Clear() in terms of polygon rendering. - */ -static void -meta_clear(struct gl_context *ctx, GLbitfield buffers, bool glsl) -{ - struct clear_state *clear = &ctx->Meta->Clear; - GLbitfield metaSave; - const GLuint stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1; - struct gl_framebuffer *fb = ctx->DrawBuffer; - struct vertex verts[4]; - - metaSave = (MESA_META_ALPHA_TEST | - MESA_META_BLEND | - MESA_META_COLOR_MASK | - MESA_META_DEPTH_TEST | - MESA_META_RASTERIZATION | - MESA_META_SHADER | - MESA_META_STENCIL_TEST | - MESA_META_VERTEX | - MESA_META_VIEWPORT | - MESA_META_CLIP | - MESA_META_CLAMP_FRAGMENT_COLOR | - MESA_META_MULTISAMPLE | - MESA_META_OCCLUSION_QUERY); - - if (!glsl) { - metaSave |= MESA_META_FOG | - MESA_META_PIXEL_TRANSFER | - MESA_META_TRANSFORM | - MESA_META_TEXTURE | - MESA_META_CLAMP_VERTEX_COLOR | - MESA_META_SELECT_FEEDBACK; - } - - if (buffers & BUFFER_BITS_COLOR) { - metaSave |= MESA_META_DRAW_BUFFERS; - } - - _mesa_meta_begin(ctx, metaSave); - - assert(!fb->_IntegerBuffers); - if (glsl) { - meta_glsl_clear_init(ctx, clear); - - _mesa_meta_use_program(ctx, clear->ShaderProg); - _mesa_Uniform4fv(0, 1, ctx->Color.ClearColor.f); - } else { - _mesa_meta_setup_vertex_objects(ctx, &clear->VAO, &clear->buf_obj, false, - 3, 0, 4); - - /* setup projection matrix */ - _mesa_load_identity_matrix(ctx, &ctx->ProjectionMatrixStack); - - for (int i = 0; i < 4; i++) { - verts[i].r = ctx->Color.ClearColor.f[0]; - verts[i].g = ctx->Color.ClearColor.f[1]; - verts[i].b = ctx->Color.ClearColor.f[2]; - verts[i].a = ctx->Color.ClearColor.f[3]; - } - } - - /* GL_COLOR_BUFFER_BIT */ - if (buffers & BUFFER_BITS_COLOR) { - /* Only draw to the buffers we were asked to clear. */ - _mesa_meta_drawbuffers_and_colormask(ctx, buffers & BUFFER_BITS_COLOR); - - /* leave colormask state as-is */ - - /* Clears never have the color clamped. */ - if (ctx->Extensions.ARB_color_buffer_float) - _mesa_ClampColor(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE); - } - else { - _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - } - - /* GL_DEPTH_BUFFER_BIT */ - if (buffers & BUFFER_BIT_DEPTH) { - _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE); - _mesa_DepthFunc(GL_ALWAYS); - _mesa_DepthMask(GL_TRUE); - } - else { - assert(!ctx->Depth.Test); - } - - /* GL_STENCIL_BUFFER_BIT */ - if (buffers & BUFFER_BIT_STENCIL) { - _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_TRUE); - _mesa_StencilOpSeparate(GL_FRONT_AND_BACK, - GL_REPLACE, GL_REPLACE, GL_REPLACE); - _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS, - ctx->Stencil.Clear & stencilMax, - ctx->Stencil.WriteMask[0]); - } - else { - assert(!ctx->Stencil.Enabled); - } - - /* vertex positions */ - const float x0 = ((float) fb->_Xmin / fb->Width) * 2.0f - 1.0f; - const float y0 = ((float) fb->_Ymin / fb->Height) * 2.0f - 1.0f; - const float x1 = ((float) fb->_Xmax / fb->Width) * 2.0f - 1.0f; - const float y1 = ((float) fb->_Ymax / fb->Height) * 2.0f - 1.0f; - const float z = -invert_z(ctx->Depth.Clear); - - verts[0].x = x0; - verts[0].y = y0; - verts[0].z = z; - verts[1].x = x1; - verts[1].y = y0; - verts[1].z = z; - verts[2].x = x1; - verts[2].y = y1; - verts[2].z = z; - verts[3].x = x0; - verts[3].y = y1; - verts[3].z = z; - - /* upload new vertex data */ - _mesa_buffer_data(ctx, clear->buf_obj, GL_NONE, sizeof(verts), verts, - GL_DYNAMIC_DRAW, __func__); - - /* draw quad(s) */ - if (fb->MaxNumLayers > 0) { - _mesa_DrawArraysInstancedARB(GL_TRIANGLE_FAN, 0, 4, fb->MaxNumLayers); - } else { - _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - } - - _mesa_meta_end(ctx); -} - -/** - * Meta implementation of ctx->Driver.CopyPixels() in terms - * of texture mapping and polygon rendering and GLSL shaders. - */ -void -_mesa_meta_CopyPixels(struct gl_context *ctx, GLint srcX, GLint srcY, - GLsizei width, GLsizei height, - GLint dstX, GLint dstY, GLenum type) -{ - struct copypix_state *copypix = &ctx->Meta->CopyPix; - struct temp_texture *tex = _mesa_meta_get_temp_texture(ctx); - struct vertex verts[4]; - - if (type != GL_COLOR || - ctx->_ImageTransferState || - ctx->Fog.Enabled || - width > tex->MaxSize || - height > tex->MaxSize) { - /* XXX avoid this fallback */ - _swrast_CopyPixels(ctx, srcX, srcY, width, height, dstX, dstY, type); - return; - } - - /* Most GL state applies to glCopyPixels, but a there's a few things - * we need to override: - */ - _mesa_meta_begin(ctx, (MESA_META_RASTERIZATION | - MESA_META_SHADER | - MESA_META_TEXTURE | - MESA_META_TRANSFORM | - MESA_META_CLIP | - MESA_META_VERTEX | - MESA_META_VIEWPORT)); - - _mesa_meta_setup_vertex_objects(ctx, ©pix->VAO, ©pix->buf_obj, false, - 3, 2, 0); - - /* Silence valgrind warnings about reading uninitialized stack. */ - memset(verts, 0, sizeof(verts)); - - /* Alloc/setup texture */ - _mesa_meta_setup_copypix_texture(ctx, tex, srcX, srcY, width, height, - GL_RGBA, GL_NEAREST); - - /* vertex positions, texcoords (after texture allocation!) */ - { - const GLfloat dstX0 = (GLfloat) dstX; - const GLfloat dstY0 = (GLfloat) dstY; - const GLfloat dstX1 = dstX + width * ctx->Pixel.ZoomX; - const GLfloat dstY1 = dstY + height * ctx->Pixel.ZoomY; - const GLfloat z = invert_z(ctx->Current.RasterPos[2]); - - verts[0].x = dstX0; - verts[0].y = dstY0; - verts[0].z = z; - verts[0].tex[0] = 0.0F; - verts[0].tex[1] = 0.0F; - verts[1].x = dstX1; - verts[1].y = dstY0; - verts[1].z = z; - verts[1].tex[0] = tex->Sright; - verts[1].tex[1] = 0.0F; - verts[2].x = dstX1; - verts[2].y = dstY1; - verts[2].z = z; - verts[2].tex[0] = tex->Sright; - verts[2].tex[1] = tex->Ttop; - verts[3].x = dstX0; - verts[3].y = dstY1; - verts[3].z = z; - verts[3].tex[0] = 0.0F; - verts[3].tex[1] = tex->Ttop; - - /* upload new vertex data */ - _mesa_buffer_sub_data(ctx, copypix->buf_obj, 0, sizeof(verts), verts); - } - - _mesa_set_enable(ctx, tex->Target, GL_TRUE); - - /* draw textured quad */ - _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - - _mesa_set_enable(ctx, tex->Target, GL_FALSE); - - _mesa_meta_end(ctx); -} - -static void -meta_drawpix_cleanup(struct gl_context *ctx, struct drawpix_state *drawpix) -{ - if (drawpix->VAO != 0) { - _mesa_DeleteVertexArrays(1, &drawpix->VAO); - drawpix->VAO = 0; - - _mesa_reference_buffer_object(ctx, &drawpix->buf_obj, NULL); - } - - if (drawpix->StencilFP != 0) { - _mesa_DeleteProgramsARB(1, &drawpix->StencilFP); - drawpix->StencilFP = 0; - } - - if (drawpix->DepthFP != 0) { - _mesa_DeleteProgramsARB(1, &drawpix->DepthFP); - drawpix->DepthFP = 0; - } -} - -static void -meta_drawtex_cleanup(struct gl_context *ctx, struct drawtex_state *drawtex) -{ - if (drawtex->VAO != 0) { - _mesa_DeleteVertexArrays(1, &drawtex->VAO); - drawtex->VAO = 0; - - _mesa_reference_buffer_object(ctx, &drawtex->buf_obj, NULL); - } -} - -static void -meta_bitmap_cleanup(struct gl_context *ctx, struct bitmap_state *bitmap) -{ - if (bitmap->VAO != 0) { - _mesa_DeleteVertexArrays(1, &bitmap->VAO); - bitmap->VAO = 0; - - _mesa_reference_buffer_object(ctx, &bitmap->buf_obj, NULL); - - cleanup_temp_texture(ctx, &bitmap->Tex); - } -} - -/** - * When the glDrawPixels() image size is greater than the max rectangle - * texture size we use this function to break the glDrawPixels() image - * into tiles which fit into the max texture size. - */ -static void -tiled_draw_pixels(struct gl_context *ctx, - GLint tileSize, - GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *unpack, - const GLvoid *pixels) -{ - struct gl_pixelstore_attrib tileUnpack = *unpack; - GLint i, j; - - if (tileUnpack.RowLength == 0) - tileUnpack.RowLength = width; - - for (i = 0; i < width; i += tileSize) { - const GLint tileWidth = MIN2(tileSize, width - i); - const GLint tileX = (GLint) (x + i * ctx->Pixel.ZoomX); - - tileUnpack.SkipPixels = unpack->SkipPixels + i; - - for (j = 0; j < height; j += tileSize) { - const GLint tileHeight = MIN2(tileSize, height - j); - const GLint tileY = (GLint) (y + j * ctx->Pixel.ZoomY); - - tileUnpack.SkipRows = unpack->SkipRows + j; - - _mesa_meta_DrawPixels(ctx, tileX, tileY, tileWidth, tileHeight, - format, type, &tileUnpack, pixels); - } - } -} - - -/** - * One-time init for drawing stencil pixels. - */ -static void -init_draw_stencil_pixels(struct gl_context *ctx) -{ - /* This program is run eight times, once for each stencil bit. - * The stencil values to draw are found in an 8-bit alpha texture. - * We read the texture/stencil value and test if bit 'b' is set. - * If the bit is not set, use KIL to kill the fragment. - * Finally, we use the stencil test to update the stencil buffer. - * - * The basic algorithm for checking if a bit is set is: - * if (is_odd(value / (1 << bit))) - * result is one (or non-zero). - * else - * result is zero. - * The program parameter contains three values: - * parm.x = 255 / (1 << bit) - * parm.y = 0.5 - * parm.z = 0.0 - */ - static const char *program = - "!!ARBfp1.0\n" - "PARAM parm = program.local[0]; \n" - "TEMP t; \n" - "TEX t, fragment.texcoord[0], texture[0], %s; \n" /* NOTE %s here! */ - "# t = t * 255 / bit \n" - "MUL t.x, t.a, parm.x; \n" - "# t = (int) t \n" - "FRC t.y, t.x; \n" - "SUB t.x, t.x, t.y; \n" - "# t = t * 0.5 \n" - "MUL t.x, t.x, parm.y; \n" - "# t = fract(t.x) \n" - "FRC t.x, t.x; # if t.x != 0, then the bit is set \n" - "# t.x = (t.x == 0 ? 1 : 0) \n" - "SGE t.x, -t.x, parm.z; \n" - "KIL -t.x; \n" - "# for debug only \n" - "#MOV result.color, t.x; \n" - "END \n"; - char program2[1000]; - struct drawpix_state *drawpix = &ctx->Meta->DrawPix; - struct temp_texture *tex = _mesa_meta_get_temp_texture(ctx); - const char *texTarget; - - assert(drawpix->StencilFP == 0); - - /* replace %s with "RECT" or "2D" */ - assert(strlen(program) + 4 < sizeof(program2)); - if (tex->Target == GL_TEXTURE_RECTANGLE) - texTarget = "RECT"; - else - texTarget = "2D"; - snprintf(program2, sizeof(program2), program, texTarget); - - _mesa_GenProgramsARB(1, &drawpix->StencilFP); - _mesa_BindProgramARB(GL_FRAGMENT_PROGRAM_ARB, drawpix->StencilFP); - _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, - strlen(program2), (const GLubyte *) program2); -} - - -/** - * One-time init for drawing depth pixels. - */ -static void -init_draw_depth_pixels(struct gl_context *ctx) -{ - static const char *program = - "!!ARBfp1.0\n" - "PARAM color = program.local[0]; \n" - "TEX result.depth, fragment.texcoord[0], texture[0], %s; \n" - "MOV result.color, color; \n" - "END \n"; - char program2[200]; - struct drawpix_state *drawpix = &ctx->Meta->DrawPix; - struct temp_texture *tex = _mesa_meta_get_temp_texture(ctx); - const char *texTarget; - - assert(drawpix->DepthFP == 0); - - /* replace %s with "RECT" or "2D" */ - assert(strlen(program) + 4 < sizeof(program2)); - if (tex->Target == GL_TEXTURE_RECTANGLE) - texTarget = "RECT"; - else - texTarget = "2D"; - snprintf(program2, sizeof(program2), program, texTarget); - - _mesa_GenProgramsARB(1, &drawpix->DepthFP); - _mesa_BindProgramARB(GL_FRAGMENT_PROGRAM_ARB, drawpix->DepthFP); - _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, - strlen(program2), (const GLubyte *) program2); -} - - -/** - * Meta implementation of ctx->Driver.DrawPixels() in terms - * of texture mapping and polygon rendering. - */ -void -_mesa_meta_DrawPixels(struct gl_context *ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *unpack, - const GLvoid *pixels) -{ - struct drawpix_state *drawpix = &ctx->Meta->DrawPix; - struct temp_texture *tex = _mesa_meta_get_temp_texture(ctx); - const struct gl_pixelstore_attrib unpackSave = ctx->Unpack; - const GLuint origStencilMask = ctx->Stencil.WriteMask[0]; - struct vertex verts[4]; - GLenum texIntFormat; - GLboolean fallback, newTex; - GLbitfield metaExtraSave = 0x0; - - /* - * Determine if we can do the glDrawPixels with texture mapping. - */ - fallback = GL_FALSE; - if (ctx->Fog.Enabled) { - fallback = GL_TRUE; - } - - if (_mesa_is_color_format(format)) { - /* use more compact format when possible */ - /* XXX disable special case for GL_LUMINANCE for now to work around - * apparent i965 driver bug (see bug #23670). - */ - if (/*format == GL_LUMINANCE ||*/ format == GL_LUMINANCE_ALPHA) - texIntFormat = format; - else - texIntFormat = GL_RGBA; - - /* If we're not supposed to clamp the resulting color, then just - * promote our texture to fully float. We could do better by - * just going for the matching set of channels, in floating - * point. - */ - if (ctx->Color.ClampFragmentColor != GL_TRUE && - ctx->Extensions.ARB_texture_float) - texIntFormat = GL_RGBA32F; - } - else if (_mesa_is_stencil_format(format)) { - if (ctx->Extensions.ARB_fragment_program && - ctx->Pixel.IndexShift == 0 && - ctx->Pixel.IndexOffset == 0 && - type == GL_UNSIGNED_BYTE) { - /* We'll store stencil as alpha. This only works for GLubyte - * image data because of how incoming values are mapped to alpha - * in [0,1]. - */ - texIntFormat = GL_ALPHA; - metaExtraSave = (MESA_META_COLOR_MASK | - MESA_META_DEPTH_TEST | - MESA_META_PIXEL_TRANSFER | - MESA_META_SHADER | - MESA_META_STENCIL_TEST); - } - else { - fallback = GL_TRUE; - } - } - else if (_mesa_is_depth_format(format)) { - if (ctx->Extensions.ARB_depth_texture && - ctx->Extensions.ARB_fragment_program) { - texIntFormat = GL_DEPTH_COMPONENT; - metaExtraSave = (MESA_META_SHADER); - } - else { - fallback = GL_TRUE; - } - } - else { - fallback = GL_TRUE; - } - - if (fallback) { - _swrast_DrawPixels(ctx, x, y, width, height, - format, type, unpack, pixels); - return; - } - - /* - * Check image size against max texture size, draw as tiles if needed. - */ - if (width > tex->MaxSize || height > tex->MaxSize) { - tiled_draw_pixels(ctx, tex->MaxSize, x, y, width, height, - format, type, unpack, pixels); - return; - } - - /* Most GL state applies to glDrawPixels (like blending, stencil, etc), - * but a there's a few things we need to override: - */ - _mesa_meta_begin(ctx, (MESA_META_RASTERIZATION | - MESA_META_SHADER | - MESA_META_TEXTURE | - MESA_META_TRANSFORM | - MESA_META_CLIP | - MESA_META_VERTEX | - MESA_META_VIEWPORT | - metaExtraSave)); - - newTex = _mesa_meta_alloc_texture(tex, width, height, texIntFormat); - - _mesa_meta_setup_vertex_objects(ctx, &drawpix->VAO, &drawpix->buf_obj, false, - 3, 2, 0); - - /* Silence valgrind warnings about reading uninitialized stack. */ - memset(verts, 0, sizeof(verts)); - - /* vertex positions, texcoords (after texture allocation!) */ - { - const GLfloat x0 = (GLfloat) x; - const GLfloat y0 = (GLfloat) y; - const GLfloat x1 = x + width * ctx->Pixel.ZoomX; - const GLfloat y1 = y + height * ctx->Pixel.ZoomY; - const GLfloat z = invert_z(ctx->Current.RasterPos[2]); - - verts[0].x = x0; - verts[0].y = y0; - verts[0].z = z; - verts[0].tex[0] = 0.0F; - verts[0].tex[1] = 0.0F; - verts[1].x = x1; - verts[1].y = y0; - verts[1].z = z; - verts[1].tex[0] = tex->Sright; - verts[1].tex[1] = 0.0F; - verts[2].x = x1; - verts[2].y = y1; - verts[2].z = z; - verts[2].tex[0] = tex->Sright; - verts[2].tex[1] = tex->Ttop; - verts[3].x = x0; - verts[3].y = y1; - verts[3].z = z; - verts[3].tex[0] = 0.0F; - verts[3].tex[1] = tex->Ttop; - } - - /* upload new vertex data */ - _mesa_buffer_data(ctx, drawpix->buf_obj, GL_NONE, sizeof(verts), verts, - GL_DYNAMIC_DRAW, __func__); - - /* set given unpack params */ - ctx->Unpack = *unpack; - - _mesa_set_enable(ctx, tex->Target, GL_TRUE); - - if (_mesa_is_stencil_format(format)) { - /* Drawing stencil */ - GLint bit; - - if (!drawpix->StencilFP) - init_draw_stencil_pixels(ctx); - - _mesa_meta_setup_drawpix_texture(ctx, tex, newTex, width, height, - GL_ALPHA, type, pixels); - - _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - - _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_TRUE); - - /* set all stencil bits to 0 */ - _mesa_StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); - _mesa_StencilFunc(GL_ALWAYS, 0, 255); - _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - - /* set stencil bits to 1 where needed */ - _mesa_StencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - - _mesa_BindProgramARB(GL_FRAGMENT_PROGRAM_ARB, drawpix->StencilFP); - _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE); - - for (bit = 0; bit < ctx->DrawBuffer->Visual.stencilBits; bit++) { - const GLuint mask = 1 << bit; - if (mask & origStencilMask) { - _mesa_StencilFunc(GL_ALWAYS, mask, mask); - _mesa_StencilMask(mask); - - _mesa_ProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, - 255.0f / mask, 0.5f, 0.0f, 0.0f); - - _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - } - } - } - else if (_mesa_is_depth_format(format)) { - /* Drawing depth */ - if (!drawpix->DepthFP) - init_draw_depth_pixels(ctx); - - _mesa_BindProgramARB(GL_FRAGMENT_PROGRAM_ARB, drawpix->DepthFP); - _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE); - - /* polygon color = current raster color */ - _mesa_ProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, 0, - ctx->Current.RasterColor); - - _mesa_meta_setup_drawpix_texture(ctx, tex, newTex, width, height, - format, type, pixels); - - _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - } - else { - /* Drawing RGBA */ - _mesa_meta_setup_drawpix_texture(ctx, tex, newTex, width, height, - format, type, pixels); - _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - } - - _mesa_set_enable(ctx, tex->Target, GL_FALSE); - - /* restore unpack params */ - ctx->Unpack = unpackSave; - - _mesa_meta_end(ctx); -} - -static GLboolean -alpha_test_raster_color(struct gl_context *ctx) -{ - GLfloat alpha = ctx->Current.RasterColor[ACOMP]; - GLfloat ref = ctx->Color.AlphaRef; - - switch (ctx->Color.AlphaFunc) { - case GL_NEVER: - return GL_FALSE; - case GL_LESS: - return alpha < ref; - case GL_EQUAL: - return alpha == ref; - case GL_LEQUAL: - return alpha <= ref; - case GL_GREATER: - return alpha > ref; - case GL_NOTEQUAL: - return alpha != ref; - case GL_GEQUAL: - return alpha >= ref; - case GL_ALWAYS: - return GL_TRUE; - default: - assert(0); - return GL_FALSE; - } -} - -/** - * Do glBitmap with a alpha texture quad. Use the alpha test to cull - * the 'off' bits. A bitmap cache as in the gallium/mesa state - * tracker would improve performance a lot. - */ -void -_mesa_meta_Bitmap(struct gl_context *ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - const struct gl_pixelstore_attrib *unpack, - const GLubyte *bitmap1) -{ - struct bitmap_state *bitmap = &ctx->Meta->Bitmap; - struct temp_texture *tex = get_bitmap_temp_texture(ctx); - const GLenum texIntFormat = GL_ALPHA; - const struct gl_pixelstore_attrib unpackSave = *unpack; - GLubyte fg, bg; - struct vertex verts[4]; - GLboolean newTex; - GLubyte *bitmap8; - - /* - * Check if swrast fallback is needed. - */ - if (ctx->_ImageTransferState || - _mesa_arb_fragment_program_enabled(ctx) || - ctx->Fog.Enabled || - ctx->Texture._MaxEnabledTexImageUnit != -1 || - width > tex->MaxSize || - height > tex->MaxSize) { - _swrast_Bitmap(ctx, x, y, width, height, unpack, bitmap1); - return; - } - - if (ctx->Color.AlphaEnabled && !alpha_test_raster_color(ctx)) - return; - - /* Most GL state applies to glBitmap (like blending, stencil, etc), - * but a there's a few things we need to override: - */ - _mesa_meta_begin(ctx, (MESA_META_ALPHA_TEST | - MESA_META_PIXEL_STORE | - MESA_META_RASTERIZATION | - MESA_META_SHADER | - MESA_META_TEXTURE | - MESA_META_TRANSFORM | - MESA_META_CLIP | - MESA_META_VERTEX | - MESA_META_VIEWPORT)); - - _mesa_meta_setup_vertex_objects(ctx, &bitmap->VAO, &bitmap->buf_obj, false, - 3, 2, 4); - - newTex = _mesa_meta_alloc_texture(tex, width, height, texIntFormat); - - /* Silence valgrind warnings about reading uninitialized stack. */ - memset(verts, 0, sizeof(verts)); - - /* vertex positions, texcoords, colors (after texture allocation!) */ - { - const GLfloat x0 = (GLfloat) x; - const GLfloat y0 = (GLfloat) y; - const GLfloat x1 = (GLfloat) (x + width); - const GLfloat y1 = (GLfloat) (y + height); - const GLfloat z = invert_z(ctx->Current.RasterPos[2]); - GLuint i; - - verts[0].x = x0; - verts[0].y = y0; - verts[0].z = z; - verts[0].tex[0] = 0.0F; - verts[0].tex[1] = 0.0F; - verts[1].x = x1; - verts[1].y = y0; - verts[1].z = z; - verts[1].tex[0] = tex->Sright; - verts[1].tex[1] = 0.0F; - verts[2].x = x1; - verts[2].y = y1; - verts[2].z = z; - verts[2].tex[0] = tex->Sright; - verts[2].tex[1] = tex->Ttop; - verts[3].x = x0; - verts[3].y = y1; - verts[3].z = z; - verts[3].tex[0] = 0.0F; - verts[3].tex[1] = tex->Ttop; - - for (i = 0; i < 4; i++) { - verts[i].r = ctx->Current.RasterColor[0]; - verts[i].g = ctx->Current.RasterColor[1]; - verts[i].b = ctx->Current.RasterColor[2]; - verts[i].a = ctx->Current.RasterColor[3]; - } - - /* upload new vertex data */ - _mesa_buffer_sub_data(ctx, bitmap->buf_obj, 0, sizeof(verts), verts); - } - - /* choose different foreground/background alpha values */ - CLAMPED_FLOAT_TO_UBYTE(fg, ctx->Current.RasterColor[ACOMP]); - bg = (fg > 127 ? 0 : 255); - - bitmap1 = _mesa_map_pbo_source(ctx, &unpackSave, bitmap1); - if (!bitmap1) { - _mesa_meta_end(ctx); - return; - } - - bitmap8 = malloc(width * height); - if (bitmap8) { - memset(bitmap8, bg, width * height); - _mesa_expand_bitmap(width, height, &unpackSave, bitmap1, - bitmap8, width, fg); - - _mesa_set_enable(ctx, tex->Target, GL_TRUE); - - _mesa_set_enable(ctx, GL_ALPHA_TEST, GL_TRUE); - _mesa_AlphaFunc(GL_NOTEQUAL, UBYTE_TO_FLOAT(bg)); - - _mesa_meta_setup_drawpix_texture(ctx, tex, newTex, width, height, - GL_ALPHA, GL_UNSIGNED_BYTE, bitmap8); - - _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - - _mesa_set_enable(ctx, tex->Target, GL_FALSE); - - free(bitmap8); - } - - _mesa_unmap_pbo_source(ctx, &unpackSave); - - _mesa_meta_end(ctx); -} - -/** - * Compute the texture coordinates for the four vertices of a quad for - * drawing a 2D texture image or slice of a cube/3D texture. The offset - * and width, height specify a sub-region of the 2D image. - * - * \param faceTarget GL_TEXTURE_1D/2D/3D or cube face name - * \param slice slice of a 1D/2D array texture or 3D texture - * \param xoffset X position of sub texture - * \param yoffset Y position of sub texture - * \param width width of the sub texture image - * \param height height of the sub texture image - * \param total_width total width of the texture image - * \param total_height total height of the texture image - * \param total_depth total depth of the texture image - * \param coords0/1/2/3 returns the computed texcoords - */ -void -_mesa_meta_setup_texture_coords(GLenum faceTarget, - GLint slice, - GLint xoffset, - GLint yoffset, - GLint width, - GLint height, - GLint total_width, - GLint total_height, - GLint total_depth, - GLfloat coords0[4], - GLfloat coords1[4], - GLfloat coords2[4], - GLfloat coords3[4]) -{ - float st[4][2]; - GLuint i; - const float s0 = (float) xoffset / (float) total_width; - const float s1 = (float) (xoffset + width) / (float) total_width; - const float t0 = (float) yoffset / (float) total_height; - const float t1 = (float) (yoffset + height) / (float) total_height; - GLfloat r; - - /* setup the reference texcoords */ - st[0][0] = s0; - st[0][1] = t0; - st[1][0] = s1; - st[1][1] = t0; - st[2][0] = s1; - st[2][1] = t1; - st[3][0] = s0; - st[3][1] = t1; - - if (faceTarget == GL_TEXTURE_CUBE_MAP_ARRAY) - faceTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + slice % 6; - - /* Currently all texture targets want the W component to be 1.0. - */ - coords0[3] = 1.0F; - coords1[3] = 1.0F; - coords2[3] = 1.0F; - coords3[3] = 1.0F; - - switch (faceTarget) { - case GL_TEXTURE_1D: - case GL_TEXTURE_2D: - case GL_TEXTURE_3D: - case GL_TEXTURE_2D_ARRAY: - if (faceTarget == GL_TEXTURE_3D) { - assert(slice < total_depth); - assert(total_depth >= 1); - r = (slice + 0.5f) / total_depth; - } - else if (faceTarget == GL_TEXTURE_2D_ARRAY) - r = (float) slice; - else - r = 0.0F; - coords0[0] = st[0][0]; /* s */ - coords0[1] = st[0][1]; /* t */ - coords0[2] = r; /* r */ - coords1[0] = st[1][0]; - coords1[1] = st[1][1]; - coords1[2] = r; - coords2[0] = st[2][0]; - coords2[1] = st[2][1]; - coords2[2] = r; - coords3[0] = st[3][0]; - coords3[1] = st[3][1]; - coords3[2] = r; - break; - case GL_TEXTURE_RECTANGLE_ARB: - coords0[0] = (float) xoffset; /* s */ - coords0[1] = (float) yoffset; /* t */ - coords0[2] = 0.0F; /* r */ - coords1[0] = (float) (xoffset + width); - coords1[1] = (float) yoffset; - coords1[2] = 0.0F; - coords2[0] = (float) (xoffset + width); - coords2[1] = (float) (yoffset + height); - coords2[2] = 0.0F; - coords3[0] = (float) xoffset; - coords3[1] = (float) (yoffset + height); - coords3[2] = 0.0F; - break; - case GL_TEXTURE_1D_ARRAY: - coords0[0] = st[0][0]; /* s */ - coords0[1] = (float) slice; /* t */ - coords0[2] = 0.0F; /* r */ - coords1[0] = st[1][0]; - coords1[1] = (float) slice; - coords1[2] = 0.0F; - coords2[0] = st[2][0]; - coords2[1] = (float) slice; - coords2[2] = 0.0F; - coords3[0] = st[3][0]; - coords3[1] = (float) slice; - coords3[2] = 0.0F; - break; - - case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - /* loop over quad verts */ - for (i = 0; i < 4; i++) { - /* Compute sc = +/-scale and tc = +/-scale. - * Not +/-1 to avoid cube face selection ambiguity near the edges, - * though that can still sometimes happen with this scale factor... - */ - const GLfloat scale = 0.9999f; - const GLfloat sc = (2.0f * st[i][0] - 1.0f) * scale; - const GLfloat tc = (2.0f * st[i][1] - 1.0f) * scale; - GLfloat *coord; - - switch (i) { - case 0: - coord = coords0; - break; - case 1: - coord = coords1; - break; - case 2: - coord = coords2; - break; - case 3: - coord = coords3; - break; - default: - unreachable("not reached"); - } - - coord[3] = (float) (slice / 6); - - switch (faceTarget) { - case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - coord[0] = 1.0f; - coord[1] = -tc; - coord[2] = -sc; - break; - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - coord[0] = -1.0f; - coord[1] = -tc; - coord[2] = sc; - break; - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - coord[0] = sc; - coord[1] = 1.0f; - coord[2] = tc; - break; - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - coord[0] = sc; - coord[1] = -1.0f; - coord[2] = -tc; - break; - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - coord[0] = sc; - coord[1] = -tc; - coord[2] = 1.0f; - break; - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - coord[0] = -sc; - coord[1] = -tc; - coord[2] = -1.0f; - break; - default: - assert(0); - } - } - break; - default: - assert(!"unexpected target in _mesa_meta_setup_texture_coords()"); - } -} - -static struct blit_shader * -choose_blit_shader(GLenum target, struct blit_shader_table *table) -{ - switch(target) { - case GL_TEXTURE_1D: - table->sampler_1d.type = "sampler1D"; - table->sampler_1d.func = "texture1D"; - table->sampler_1d.texcoords = "texCoords.x"; - return &table->sampler_1d; - case GL_TEXTURE_2D: - table->sampler_2d.type = "sampler2D"; - table->sampler_2d.func = "texture2D"; - table->sampler_2d.texcoords = "texCoords.xy"; - return &table->sampler_2d; - case GL_TEXTURE_RECTANGLE: - table->sampler_rect.type = "sampler2DRect"; - table->sampler_rect.func = "texture2DRect"; - table->sampler_rect.texcoords = "texCoords.xy"; - return &table->sampler_rect; - case GL_TEXTURE_3D: - /* Code for mipmap generation with 3D textures is not used yet. - * It's a sw fallback. - */ - table->sampler_3d.type = "sampler3D"; - table->sampler_3d.func = "texture3D"; - table->sampler_3d.texcoords = "texCoords.xyz"; - return &table->sampler_3d; - case GL_TEXTURE_CUBE_MAP: - table->sampler_cubemap.type = "samplerCube"; - table->sampler_cubemap.func = "textureCube"; - table->sampler_cubemap.texcoords = "texCoords.xyz"; - return &table->sampler_cubemap; - case GL_TEXTURE_1D_ARRAY: - table->sampler_1d_array.type = "sampler1DArray"; - table->sampler_1d_array.func = "texture1DArray"; - table->sampler_1d_array.texcoords = "texCoords.xy"; - return &table->sampler_1d_array; - case GL_TEXTURE_2D_ARRAY: - table->sampler_2d_array.type = "sampler2DArray"; - table->sampler_2d_array.func = "texture2DArray"; - table->sampler_2d_array.texcoords = "texCoords.xyz"; - return &table->sampler_2d_array; - case GL_TEXTURE_CUBE_MAP_ARRAY: - table->sampler_cubemap_array.type = "samplerCubeArray"; - table->sampler_cubemap_array.func = "textureCubeArray"; - table->sampler_cubemap_array.texcoords = "texCoords.xyzw"; - return &table->sampler_cubemap_array; - default: - _mesa_problem(NULL, "Unexpected texture target 0x%x in" - " setup_texture_sampler()\n", target); - return NULL; - } -} - -void -_mesa_meta_blit_shader_table_cleanup(struct gl_context *ctx, - struct blit_shader_table *table) -{ - _mesa_reference_shader_program(ctx, &table->sampler_1d.shader_prog, NULL); - _mesa_reference_shader_program(ctx, &table->sampler_2d.shader_prog, NULL); - _mesa_reference_shader_program(ctx, &table->sampler_3d.shader_prog, NULL); - _mesa_reference_shader_program(ctx, &table->sampler_rect.shader_prog, NULL); - _mesa_reference_shader_program(ctx, &table->sampler_cubemap.shader_prog, NULL); - _mesa_reference_shader_program(ctx, &table->sampler_1d_array.shader_prog, NULL); - _mesa_reference_shader_program(ctx, &table->sampler_2d_array.shader_prog, NULL); - _mesa_reference_shader_program(ctx, &table->sampler_cubemap_array.shader_prog, NULL); -} - -/** - * Determine the GL data type to use for the temporary image read with - * ReadPixels() and passed to Tex[Sub]Image(). - */ -static GLenum -get_temp_image_type(struct gl_context *ctx, mesa_format format) -{ - const GLenum baseFormat = _mesa_get_format_base_format(format); - const GLenum datatype = _mesa_get_format_datatype(format); - const GLint format_red_bits = _mesa_get_format_bits(format, GL_RED_BITS); - - switch (baseFormat) { - case GL_RGBA: - case GL_RGB: - case GL_RG: - case GL_RED: - case GL_ALPHA: - case GL_LUMINANCE: - case GL_LUMINANCE_ALPHA: - case GL_INTENSITY: - if (datatype == GL_INT || datatype == GL_UNSIGNED_INT) { - return datatype; - } else if (format_red_bits <= 8) { - return GL_UNSIGNED_BYTE; - } else if (format_red_bits <= 16) { - return GL_UNSIGNED_SHORT; - } - return GL_FLOAT; - case GL_DEPTH_COMPONENT: - if (datatype == GL_FLOAT) - return GL_FLOAT; - else - return GL_UNSIGNED_INT; - case GL_DEPTH_STENCIL: - if (datatype == GL_FLOAT) - return GL_FLOAT_32_UNSIGNED_INT_24_8_REV; - else - return GL_UNSIGNED_INT_24_8; - default: - _mesa_problem(ctx, "Unexpected format %d in get_temp_image_type()", - baseFormat); - return 0; - } -} - -/** - * Attempts to wrap the destination texture in an FBO and use - * glBlitFramebuffer() to implement glCopyTexSubImage(). - */ -static bool -copytexsubimage_using_blit_framebuffer(struct gl_context *ctx, - struct gl_texture_image *texImage, - GLint xoffset, - GLint yoffset, - GLint zoffset, - struct gl_renderbuffer *rb, - GLint x, GLint y, - GLsizei width, GLsizei height) -{ - struct gl_framebuffer *drawFb; - bool success = false; - GLbitfield mask; - GLenum status; - - if (!ctx->Extensions.ARB_framebuffer_object) - return false; - - drawFb = ctx->Driver.NewFramebuffer(ctx, 0xDEADBEEF); - if (drawFb == NULL) - return false; - - _mesa_meta_begin(ctx, MESA_META_ALL & ~MESA_META_DRAW_BUFFERS); - _mesa_bind_framebuffers(ctx, drawFb, ctx->ReadBuffer); - - if (rb->_BaseFormat == GL_DEPTH_STENCIL || - rb->_BaseFormat == GL_DEPTH_COMPONENT) { - _mesa_meta_framebuffer_texture_image(ctx, ctx->DrawBuffer, - GL_DEPTH_ATTACHMENT, - texImage, zoffset); - mask = GL_DEPTH_BUFFER_BIT; - - if (rb->_BaseFormat == GL_DEPTH_STENCIL && - texImage->_BaseFormat == GL_DEPTH_STENCIL) { - _mesa_meta_framebuffer_texture_image(ctx, ctx->DrawBuffer, - GL_STENCIL_ATTACHMENT, - texImage, zoffset); - mask |= GL_STENCIL_BUFFER_BIT; - } - _mesa_DrawBuffer(GL_NONE); - } else { - _mesa_meta_framebuffer_texture_image(ctx, ctx->DrawBuffer, - GL_COLOR_ATTACHMENT0, - texImage, zoffset); - mask = GL_COLOR_BUFFER_BIT; - _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0); - } - - status = _mesa_check_framebuffer_status(ctx, ctx->DrawBuffer); - if (status != GL_FRAMEBUFFER_COMPLETE) - goto out; - - ctx->Meta->Blit.no_ctsi_fallback = true; - - /* Since we've bound a new draw framebuffer, we need to update - * its derived state -- _Xmin, etc -- for BlitFramebuffer's clipping to - * be correct. - */ - _mesa_update_state(ctx); - - /* We skip the core BlitFramebuffer checks for format consistency, which - * are too strict for CopyTexImage. We know meta will be fine with format - * changes. - */ - mask = _mesa_meta_BlitFramebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer, - x, y, - x + width, y + height, - xoffset, yoffset, - xoffset + width, yoffset + height, - mask, GL_NEAREST); - ctx->Meta->Blit.no_ctsi_fallback = false; - success = mask == 0x0; - - out: - _mesa_reference_framebuffer(&drawFb, NULL); - _mesa_meta_end(ctx); - return success; -} - -/** - * Helper for _mesa_meta_CopyTexSubImage1/2/3D() functions. - * Have to be careful with locking and meta state for pixel transfer. - */ -void -_mesa_meta_CopyTexSubImage(struct gl_context *ctx, GLuint dims, - struct gl_texture_image *texImage, - GLint xoffset, GLint yoffset, GLint zoffset, - struct gl_renderbuffer *rb, - GLint x, GLint y, - GLsizei width, GLsizei height) -{ - GLenum format, type; - GLint bpp; - void *buf; - - if (copytexsubimage_using_blit_framebuffer(ctx, - texImage, - xoffset, yoffset, zoffset, - rb, - x, y, - width, height)) { - return; - } - - /* Choose format/type for temporary image buffer */ - format = _mesa_get_format_base_format(texImage->TexFormat); - if (format == GL_LUMINANCE || - format == GL_LUMINANCE_ALPHA || - format == GL_INTENSITY) { - /* We don't want to use GL_LUMINANCE, GL_INTENSITY, etc. for the - * temp image buffer because glReadPixels will do L=R+G+B which is - * not what we want (should be L=R). - */ - format = GL_RGBA; - } - - type = get_temp_image_type(ctx, texImage->TexFormat); - if (_mesa_is_format_integer_color(texImage->TexFormat)) { - format = _mesa_base_format_to_integer_format(format); - } - bpp = _mesa_bytes_per_pixel(format, type); - if (bpp <= 0) { - _mesa_problem(ctx, "Bad bpp in _mesa_meta_CopyTexSubImage()"); - return; - } - - /* - * Alloc image buffer (XXX could use a PBO) - */ - buf = malloc(width * height * bpp); - if (!buf) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage%uD", dims); - return; - } - - /* - * Read image from framebuffer (disable pixel transfer ops) - */ - _mesa_meta_begin(ctx, MESA_META_PIXEL_STORE | MESA_META_PIXEL_TRANSFER); - ctx->Driver.ReadPixels(ctx, x, y, width, height, - format, type, &ctx->Pack, buf); - _mesa_meta_end(ctx); - - _mesa_update_state(ctx); /* to update pixel transfer state */ - - /* - * Store texture data (with pixel transfer ops) - */ - _mesa_meta_begin(ctx, MESA_META_PIXEL_STORE); - - if (texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY) { - assert(yoffset == 0); - ctx->Driver.TexSubImage(ctx, dims, texImage, - xoffset, zoffset, 0, width, 1, 1, - format, type, buf, &ctx->Unpack); - } else { - ctx->Driver.TexSubImage(ctx, dims, texImage, - xoffset, yoffset, zoffset, width, height, 1, - format, type, buf, &ctx->Unpack); - } - - _mesa_meta_end(ctx); - - free(buf); -} - -static void -meta_decompress_fbo_cleanup(struct decompress_fbo_state *decompress_fbo) -{ - if (decompress_fbo->fb != NULL) { - _mesa_reference_framebuffer(&decompress_fbo->fb, NULL); - _mesa_reference_renderbuffer(&decompress_fbo->rb, NULL); - } - - memset(decompress_fbo, 0, sizeof(*decompress_fbo)); -} - -static void -meta_decompress_cleanup(struct gl_context *ctx, - struct decompress_state *decompress) -{ - meta_decompress_fbo_cleanup(&decompress->byteFBO); - meta_decompress_fbo_cleanup(&decompress->floatFBO); - - if (decompress->VAO != 0) { - _mesa_DeleteVertexArrays(1, &decompress->VAO); - _mesa_reference_buffer_object(ctx, &decompress->buf_obj, NULL); - } - - _mesa_reference_sampler_object(ctx, &decompress->samp_obj, NULL); - _mesa_meta_blit_shader_table_cleanup(ctx, &decompress->shaders); - - memset(decompress, 0, sizeof(*decompress)); -} - -/** - * Decompress a texture image by drawing a quad with the compressed - * texture and reading the pixels out of the color buffer. - * \param slice which slice of a 3D texture or layer of a 1D/2D texture - * \param destFormat format, ala glReadPixels - * \param destType type, ala glReadPixels - * \param dest destination buffer - * \param destRowLength dest image rowLength (ala GL_PACK_ROW_LENGTH) - */ -static bool -decompress_texture_image(struct gl_context *ctx, - struct gl_texture_image *texImage, - GLuint slice, - GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, - GLenum destFormat, GLenum destType, - GLvoid *dest) -{ - struct decompress_state *decompress = &ctx->Meta->Decompress; - struct decompress_fbo_state *decompress_fbo; - struct gl_texture_object *texObj = texImage->TexObject; - const GLenum target = texObj->Target; - GLenum rbFormat; - GLenum faceTarget; - struct vertex verts[4]; - struct gl_sampler_object *samp_obj_save = NULL; - GLenum status; - const bool use_glsl_version = ctx->Extensions.ARB_vertex_shader && - ctx->Extensions.ARB_fragment_shader; - - switch (_mesa_get_format_datatype(texImage->TexFormat)) { - case GL_FLOAT: - decompress_fbo = &decompress->floatFBO; - rbFormat = GL_RGBA32F; - break; - case GL_UNSIGNED_NORMALIZED: - decompress_fbo = &decompress->byteFBO; - rbFormat = GL_RGBA; - break; - default: - return false; - } - - if (slice > 0) { - assert(target == GL_TEXTURE_3D || - target == GL_TEXTURE_2D_ARRAY || - target == GL_TEXTURE_CUBE_MAP_ARRAY); - } - - switch (target) { - case GL_TEXTURE_1D: - case GL_TEXTURE_1D_ARRAY: - assert(!"No compressed 1D textures."); - return false; - - case GL_TEXTURE_CUBE_MAP_ARRAY: - faceTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + (slice % 6); - break; - - case GL_TEXTURE_CUBE_MAP: - faceTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + texImage->Face; - break; - - default: - faceTarget = target; - break; - } - - _mesa_meta_begin(ctx, MESA_META_ALL & ~(MESA_META_PIXEL_STORE | - MESA_META_DRAW_BUFFERS)); - _mesa_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - - _mesa_reference_sampler_object(ctx, &samp_obj_save, - ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler); - - /* Create/bind FBO/renderbuffer */ - if (decompress_fbo->fb == NULL) { - decompress_fbo->rb = ctx->Driver.NewRenderbuffer(ctx, 0xDEADBEEF); - if (decompress_fbo->rb == NULL) { - _mesa_meta_end(ctx); - return false; - } - - decompress_fbo->fb = ctx->Driver.NewFramebuffer(ctx, 0xDEADBEEF); - if (decompress_fbo->fb == NULL) { - _mesa_meta_end(ctx); - return false; - } - - _mesa_bind_framebuffers(ctx, decompress_fbo->fb, decompress_fbo->fb); - _mesa_framebuffer_renderbuffer(ctx, ctx->DrawBuffer, GL_COLOR_ATTACHMENT0, - decompress_fbo->rb); - } - else { - _mesa_bind_framebuffers(ctx, decompress_fbo->fb, decompress_fbo->fb); - } - - /* alloc dest surface */ - if (width > decompress_fbo->Width || height > decompress_fbo->Height) { - _mesa_renderbuffer_storage(ctx, decompress_fbo->rb, rbFormat, - width, height, 0, 0); - - /* Do the full completeness check to recompute - * ctx->DrawBuffer->Width/Height. - */ - ctx->DrawBuffer->_Status = GL_FRAMEBUFFER_UNDEFINED; - status = _mesa_check_framebuffer_status(ctx, ctx->DrawBuffer); - if (status != GL_FRAMEBUFFER_COMPLETE) { - /* If the framebuffer isn't complete then we'll leave - * decompress_fbo->Width as zero so that it will fail again next time - * too */ - _mesa_meta_end(ctx); - return false; - } - decompress_fbo->Width = width; - decompress_fbo->Height = height; - } - - if (use_glsl_version) { - _mesa_meta_setup_vertex_objects(ctx, &decompress->VAO, - &decompress->buf_obj, true, - 2, 4, 0); - - _mesa_meta_setup_blit_shader(ctx, target, false, &decompress->shaders); - } else { - _mesa_meta_setup_ff_tnl_for_blit(ctx, &decompress->VAO, - &decompress->buf_obj, 3); - } - - if (decompress->samp_obj == NULL) { - decompress->samp_obj = ctx->Driver.NewSamplerObject(ctx, 0xDEADBEEF); - if (decompress->samp_obj == NULL) { - _mesa_meta_end(ctx); - - /* This is a bit lazy. Flag out of memory, and then don't bother to - * clean up. Once out of memory is flagged, the only realistic next - * move is to destroy the context. That will trigger all the right - * clean up. - * - * Returning true prevents other GetTexImage methods from attempting - * anything since they will likely fail too. - */ - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage"); - return true; - } - - /* nearest filtering */ - _mesa_set_sampler_filters(ctx, decompress->samp_obj, GL_NEAREST, GL_NEAREST); - - /* We don't want to encode or decode sRGB values; treat them as linear. */ - _mesa_set_sampler_srgb_decode(ctx, decompress->samp_obj, GL_SKIP_DECODE_EXT); - } - - _mesa_bind_sampler(ctx, ctx->Texture.CurrentUnit, decompress->samp_obj); - - /* Silence valgrind warnings about reading uninitialized stack. */ - memset(verts, 0, sizeof(verts)); - - _mesa_meta_setup_texture_coords(faceTarget, slice, - xoffset, yoffset, width, height, - texImage->Width, texImage->Height, - texImage->Depth, - verts[0].tex, - verts[1].tex, - verts[2].tex, - verts[3].tex); - - /* setup vertex positions */ - verts[0].x = -1.0F; - verts[0].y = -1.0F; - verts[1].x = 1.0F; - verts[1].y = -1.0F; - verts[2].x = 1.0F; - verts[2].y = 1.0F; - verts[3].x = -1.0F; - verts[3].y = 1.0F; - - _mesa_set_viewport(ctx, 0, 0, 0, width, height); - - /* upload new vertex data */ - _mesa_buffer_sub_data(ctx, decompress->buf_obj, 0, sizeof(verts), verts); - - /* setup texture state */ - _mesa_bind_texture(ctx, target, texObj); - - if (!use_glsl_version) - _mesa_set_enable(ctx, target, GL_TRUE); - - { - /* save texture object state */ - const GLint baseLevelSave = texObj->Attrib.BaseLevel; - const GLint maxLevelSave = texObj->Attrib.MaxLevel; - - /* restrict sampling to the texture level of interest */ - if (target != GL_TEXTURE_RECTANGLE_ARB) { - _mesa_texture_parameteriv(ctx, texObj, GL_TEXTURE_BASE_LEVEL, - (GLint *) &texImage->Level, false); - _mesa_texture_parameteriv(ctx, texObj, GL_TEXTURE_MAX_LEVEL, - (GLint *) &texImage->Level, false); - } - - /* render quad w/ texture into renderbuffer */ - _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - - /* Restore texture object state, the texture binding will - * be restored by _mesa_meta_end(). - */ - if (target != GL_TEXTURE_RECTANGLE_ARB) { - _mesa_texture_parameteriv(ctx, texObj, GL_TEXTURE_BASE_LEVEL, - &baseLevelSave, false); - _mesa_texture_parameteriv(ctx, texObj, GL_TEXTURE_MAX_LEVEL, - &maxLevelSave, false); - } - - } - - /* read pixels from renderbuffer */ - { - GLenum baseTexFormat = texImage->_BaseFormat; - GLenum destBaseFormat = _mesa_unpack_format_to_base_format(destFormat); - - /* The pixel transfer state will be set to default values at this point - * (see MESA_META_PIXEL_TRANSFER) so pixel transfer ops are effectively - * turned off (as required by glGetTexImage) but we need to handle some - * special cases. In particular, single-channel texture values are - * returned as red and two-channel texture values are returned as - * red/alpha. - */ - if (_mesa_need_luminance_to_rgb_conversion(baseTexFormat, - destBaseFormat) || - /* If we're reading back an RGB(A) texture (using glGetTexImage) as - * luminance then we need to return L=tex(R). - */ - _mesa_need_rgb_to_luminance_conversion(baseTexFormat, - destBaseFormat)) { - /* Green and blue must be zero */ - _mesa_PixelTransferf(GL_GREEN_SCALE, 0.0f); - _mesa_PixelTransferf(GL_BLUE_SCALE, 0.0f); - } - - _mesa_ReadPixels(0, 0, width, height, destFormat, destType, dest); - } - - /* disable texture unit */ - if (!use_glsl_version) - _mesa_set_enable(ctx, target, GL_FALSE); - - _mesa_bind_sampler(ctx, ctx->Texture.CurrentUnit, samp_obj_save); - _mesa_reference_sampler_object(ctx, &samp_obj_save, NULL); - - _mesa_meta_end(ctx); - - return true; -} - - -/** - * This is just a wrapper around _mesa_get_tex_image() and - * decompress_texture_image(). Meta functions should not be directly called - * from core Mesa. - */ -void -_mesa_meta_GetTexSubImage(struct gl_context *ctx, - GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLenum type, GLvoid *pixels, - struct gl_texture_image *texImage) -{ - if (_mesa_is_format_compressed(texImage->TexFormat)) { - GLuint slice; - bool result = true; - - for (slice = 0; slice < depth; slice++) { - void *dst; - /* Section 8.11.4 (Texture Image Queries) of the GL 4.5 spec says: - * - * "For three-dimensional, two-dimensional array, cube map array, - * and cube map textures pixel storage operations are applied as - * if the image were two-dimensional, except that the additional - * pixel storage state values PACK_IMAGE_HEIGHT and - * PACK_SKIP_IMAGES are applied. The correspondence of texels to - * memory locations is as defined for TexImage3D in section 8.5." - */ - switch (texImage->TexObject->Target) { - case GL_TEXTURE_3D: - case GL_TEXTURE_2D_ARRAY: - case GL_TEXTURE_CUBE_MAP: - case GL_TEXTURE_CUBE_MAP_ARRAY: { - /* Setup pixel packing. SkipPixels and SkipRows will be applied - * in the decompress_texture_image() function's call to - * glReadPixels but we need to compute the dest slice's address - * here (according to SkipImages and ImageHeight). - */ - struct gl_pixelstore_attrib packing = ctx->Pack; - packing.SkipPixels = 0; - packing.SkipRows = 0; - dst = _mesa_image_address3d(&packing, pixels, width, height, - format, type, slice, 0, 0); - break; - } - default: - dst = pixels; - break; - } - result = decompress_texture_image(ctx, texImage, slice, - xoffset, yoffset, width, height, - format, type, dst); - if (!result) - break; - } - - if (result) - return; - } - - _mesa_GetTexSubImage_sw(ctx, xoffset, yoffset, zoffset, - width, height, depth, format, type, pixels, texImage); -} - - -/** - * Meta implementation of ctx->Driver.DrawTex() in terms - * of polygon rendering. - */ -void -_mesa_meta_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z, - GLfloat width, GLfloat height) -{ - struct drawtex_state *drawtex = &ctx->Meta->DrawTex; - struct vertex { - GLfloat x, y, z, st[MAX_TEXTURE_UNITS][2]; - }; - struct vertex verts[4]; - GLuint i; - - _mesa_meta_begin(ctx, (MESA_META_RASTERIZATION | - MESA_META_SHADER | - MESA_META_TRANSFORM | - MESA_META_VERTEX | - MESA_META_VIEWPORT)); - - if (drawtex->VAO == 0) { - /* one-time setup */ - struct gl_vertex_array_object *array_obj; - - /* create vertex array object */ - _mesa_GenVertexArrays(1, &drawtex->VAO); - _mesa_BindVertexArray(drawtex->VAO); - - array_obj = _mesa_lookup_vao(ctx, drawtex->VAO); - assert(array_obj != NULL); - - /* create vertex array buffer */ - drawtex->buf_obj = ctx->Driver.NewBufferObject(ctx, 0xDEADBEEF); - if (drawtex->buf_obj == NULL) - return; - - _mesa_buffer_data(ctx, drawtex->buf_obj, GL_NONE, sizeof(verts), verts, - GL_DYNAMIC_DRAW, __func__); - - /* setup vertex arrays */ - FLUSH_VERTICES(ctx, 0, 0); - _mesa_update_array_format(ctx, array_obj, VERT_ATTRIB_POS, - 3, GL_FLOAT, GL_RGBA, GL_FALSE, - GL_FALSE, GL_FALSE, - offsetof(struct vertex, x)); - _mesa_bind_vertex_buffer(ctx, array_obj, VERT_ATTRIB_POS, - drawtex->buf_obj, 0, sizeof(struct vertex), - false, false); - _mesa_enable_vertex_array_attrib(ctx, array_obj, VERT_ATTRIB_POS); - - - for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { - FLUSH_VERTICES(ctx, 0, 0); - _mesa_update_array_format(ctx, array_obj, VERT_ATTRIB_TEX(i), - 2, GL_FLOAT, GL_RGBA, GL_FALSE, - GL_FALSE, GL_FALSE, - offsetof(struct vertex, st[i])); - _mesa_bind_vertex_buffer(ctx, array_obj, VERT_ATTRIB_TEX(i), - drawtex->buf_obj, 0, sizeof(struct vertex), - false, false); - _mesa_enable_vertex_array_attrib(ctx, array_obj, VERT_ATTRIB_TEX(i)); - } - } - else { - _mesa_BindVertexArray(drawtex->VAO); - } - - /* vertex positions, texcoords */ - { - const GLfloat x1 = x + width; - const GLfloat y1 = y + height; - - z = SATURATE(z); - z = invert_z(z); - - verts[0].x = x; - verts[0].y = y; - verts[0].z = z; - - verts[1].x = x1; - verts[1].y = y; - verts[1].z = z; - - verts[2].x = x1; - verts[2].y = y1; - verts[2].z = z; - - verts[3].x = x; - verts[3].y = y1; - verts[3].z = z; - - for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { - const struct gl_texture_object *texObj; - const struct gl_texture_image *texImage; - GLfloat s, t, s1, t1; - GLuint tw, th; - - if (!ctx->Texture.Unit[i]._Current) { - GLuint j; - for (j = 0; j < 4; j++) { - verts[j].st[i][0] = 0.0f; - verts[j].st[i][1] = 0.0f; - } - continue; - } - - texObj = ctx->Texture.Unit[i]._Current; - texImage = texObj->Image[0][texObj->Attrib.BaseLevel]; - tw = texImage->Width2; - th = texImage->Height2; - - s = (GLfloat) texObj->CropRect[0] / tw; - t = (GLfloat) texObj->CropRect[1] / th; - s1 = (GLfloat) (texObj->CropRect[0] + texObj->CropRect[2]) / tw; - t1 = (GLfloat) (texObj->CropRect[1] + texObj->CropRect[3]) / th; - - verts[0].st[i][0] = s; - verts[0].st[i][1] = t; - - verts[1].st[i][0] = s1; - verts[1].st[i][1] = t; - - verts[2].st[i][0] = s1; - verts[2].st[i][1] = t1; - - verts[3].st[i][0] = s; - verts[3].st[i][1] = t1; - } - - _mesa_buffer_sub_data(ctx, drawtex->buf_obj, 0, sizeof(verts), verts); - } - - _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - - _mesa_meta_end(ctx); -} - -static bool -cleartexsubimage_color(struct gl_context *ctx, - struct gl_texture_image *texImage, - const GLvoid *clearValue, - GLint zoffset) -{ - mesa_format format; - union gl_color_union colorValue; - GLenum datatype; - GLenum status; - - _mesa_meta_framebuffer_texture_image(ctx, ctx->DrawBuffer, - GL_COLOR_ATTACHMENT0, - texImage, zoffset); - - status = _mesa_check_framebuffer_status(ctx, ctx->DrawBuffer); - if (status != GL_FRAMEBUFFER_COMPLETE) - return false; - - /* We don't want to apply an sRGB conversion so override the format */ - format = _mesa_get_srgb_format_linear(texImage->TexFormat); - datatype = _mesa_get_format_datatype(format); - - switch (datatype) { - case GL_UNSIGNED_INT: - case GL_INT: - if (clearValue) - _mesa_unpack_uint_rgba_row(format, 1, clearValue, - (GLuint (*)[4]) colorValue.ui); - else - memset(&colorValue, 0, sizeof colorValue); - if (datatype == GL_INT) - _mesa_ClearBufferiv(GL_COLOR, 0, colorValue.i); - else - _mesa_ClearBufferuiv(GL_COLOR, 0, colorValue.ui); - break; - default: - if (clearValue) - _mesa_unpack_rgba_row(format, 1, clearValue, - (GLfloat (*)[4]) colorValue.f); - else - memset(&colorValue, 0, sizeof colorValue); - _mesa_ClearBufferfv(GL_COLOR, 0, colorValue.f); - break; - } - - return true; -} - -static bool -cleartexsubimage_depth_stencil(struct gl_context *ctx, - struct gl_texture_image *texImage, - const GLvoid *clearValue, - GLint zoffset) -{ - GLint stencilValue = 0; - GLfloat depthValue = 0.0f; - GLenum status; - - _mesa_meta_framebuffer_texture_image(ctx, ctx->DrawBuffer, - GL_DEPTH_ATTACHMENT, - texImage, zoffset); - - if (texImage->_BaseFormat == GL_DEPTH_STENCIL) - _mesa_meta_framebuffer_texture_image(ctx, ctx->DrawBuffer, - GL_STENCIL_ATTACHMENT, - texImage, zoffset); - - status = _mesa_check_framebuffer_status(ctx, ctx->DrawBuffer); - if (status != GL_FRAMEBUFFER_COMPLETE) - return false; - - if (clearValue) { - GLuint depthStencilValue[2]; - - /* Convert the clearValue from whatever format it's in to a floating - * point value for the depth and an integer value for the stencil index - */ - if (texImage->_BaseFormat == GL_DEPTH_STENCIL) { - _mesa_unpack_float_32_uint_24_8_depth_stencil_row(texImage->TexFormat, - 1, /* n */ - clearValue, - depthStencilValue); - /* We need a memcpy here instead of a cast because we need to - * reinterpret the bytes as a float rather than converting it - */ - memcpy(&depthValue, depthStencilValue, sizeof depthValue); - stencilValue = depthStencilValue[1] & 0xff; - } else { - _mesa_unpack_float_z_row(texImage->TexFormat, 1 /* n */, - clearValue, &depthValue); - } - } - - if (texImage->_BaseFormat == GL_DEPTH_STENCIL) - _mesa_ClearBufferfi(GL_DEPTH_STENCIL, 0, depthValue, stencilValue); - else - _mesa_ClearBufferfv(GL_DEPTH, 0, &depthValue); - - return true; -} - -static bool -cleartexsubimage_for_zoffset(struct gl_context *ctx, - struct gl_texture_image *texImage, - GLint zoffset, - const GLvoid *clearValue) -{ - struct gl_framebuffer *drawFb; - bool success; - - drawFb = ctx->Driver.NewFramebuffer(ctx, 0xDEADBEEF); - if (drawFb == NULL) - return false; - - _mesa_bind_framebuffers(ctx, drawFb, ctx->ReadBuffer); - - switch(texImage->_BaseFormat) { - case GL_DEPTH_STENCIL: - case GL_DEPTH_COMPONENT: - success = cleartexsubimage_depth_stencil(ctx, texImage, - clearValue, zoffset); - break; - default: - success = cleartexsubimage_color(ctx, texImage, clearValue, zoffset); - break; - } - - _mesa_reference_framebuffer(&drawFb, NULL); - - return success; -} - -static bool -cleartexsubimage_using_fbo(struct gl_context *ctx, - struct gl_texture_image *texImage, - GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, - const GLvoid *clearValue) -{ - bool success = true; - GLint z; - - _mesa_meta_begin(ctx, - MESA_META_SCISSOR | - MESA_META_COLOR_MASK | - MESA_META_DITHER | - MESA_META_FRAMEBUFFER_SRGB); - - _mesa_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - _mesa_set_enable(ctx, GL_DITHER, GL_FALSE); - - _mesa_set_enable(ctx, GL_SCISSOR_TEST, GL_TRUE); - _mesa_Scissor(xoffset, yoffset, width, height); - - for (z = zoffset; z < zoffset + depth; z++) { - if (!cleartexsubimage_for_zoffset(ctx, texImage, z, clearValue)) { - success = false; - break; - } - } - - _mesa_meta_end(ctx); - - return success; -} - -extern void -_mesa_meta_ClearTexSubImage(struct gl_context *ctx, - struct gl_texture_image *texImage, - GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, - const GLvoid *clearValue) -{ - bool res; - - res = cleartexsubimage_using_fbo(ctx, texImage, - xoffset, yoffset, zoffset, - width, height, depth, - clearValue); - - if (res) - return; - - _mesa_warning(ctx, - "Falling back to mapping the texture in " - "glClearTexSubImage\n"); - - _mesa_store_cleartexsubimage(ctx, texImage, - xoffset, yoffset, zoffset, - width, height, depth, - clearValue); -} diff --git a/src/mesa/drivers/common/meta.h b/src/mesa/drivers/common/meta.h deleted file mode 100644 index 799650b..0000000 --- a/src/mesa/drivers/common/meta.h +++ /dev/null @@ -1,573 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 2009 VMware, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -#ifndef META_H -#define META_H - -#include "main/mtypes.h" - -/** - * \name Flags for meta operations - * \{ - * - * These flags are passed to _mesa_meta_begin(). - */ -#define MESA_META_ALL ~0x0 -#define MESA_META_ALPHA_TEST 0x1 -#define MESA_META_BLEND 0x2 /**< includes logicop */ -#define MESA_META_COLOR_MASK 0x4 -#define MESA_META_DEPTH_TEST 0x8 -#define MESA_META_FOG 0x10 -#define MESA_META_PIXEL_STORE 0x20 -#define MESA_META_PIXEL_TRANSFER 0x40 -#define MESA_META_RASTERIZATION 0x80 -#define MESA_META_SCISSOR 0x100 -#define MESA_META_SHADER 0x200 -#define MESA_META_STENCIL_TEST 0x400 -#define MESA_META_TRANSFORM 0x800 /**< modelview/projection matrix state */ -#define MESA_META_TEXTURE 0x1000 -#define MESA_META_VERTEX 0x2000 -#define MESA_META_VIEWPORT 0x4000 -#define MESA_META_CLAMP_FRAGMENT_COLOR 0x8000 -#define MESA_META_CLAMP_VERTEX_COLOR 0x10000 -#define MESA_META_CONDITIONAL_RENDER 0x20000 -#define MESA_META_CLIP 0x40000 -#define MESA_META_SELECT_FEEDBACK 0x80000 -#define MESA_META_MULTISAMPLE 0x100000 -#define MESA_META_FRAMEBUFFER_SRGB 0x200000 -#define MESA_META_OCCLUSION_QUERY 0x400000 -#define MESA_META_DRAW_BUFFERS 0x800000 -#define MESA_META_DITHER 0x1000000 -/**\}*/ - -/** - * State which we may save/restore across meta ops. - * XXX this may be incomplete... - */ -struct save_state -{ - GLbitfield SavedState; /**< bitmask of MESA_META_* flags */ - - /* Always saved/restored with meta. */ - gl_api API; - uint8_t ExtensionsVersion; - - /** MESA_META_CLEAR (and others?) */ - struct gl_query_object *CurrentOcclusionObject; - - /** MESA_META_ALPHA_TEST */ - GLboolean AlphaEnabled; - GLenum AlphaFunc; - GLclampf AlphaRef; - - /** MESA_META_BLEND */ - GLbitfield BlendEnabled; - GLboolean ColorLogicOpEnabled; - - /** MESA_META_DITHER */ - GLboolean DitherFlag; - - /** MESA_META_COLOR_MASK */ - GLbitfield ColorMask; - - /** MESA_META_DEPTH_TEST */ - struct gl_depthbuffer_attrib Depth; - - /** MESA_META_FOG */ - GLboolean Fog; - - /** MESA_META_PIXEL_STORE */ - struct gl_pixelstore_attrib Pack, Unpack; - - /** MESA_META_PIXEL_TRANSFER */ - GLfloat RedBias, RedScale; - GLfloat GreenBias, GreenScale; - GLfloat BlueBias, BlueScale; - GLfloat AlphaBias, AlphaScale; - GLfloat DepthBias, DepthScale; - GLboolean MapColorFlag; - - /** MESA_META_RASTERIZATION */ - GLenum FrontPolygonMode, BackPolygonMode; - GLboolean PolygonOffset; - GLboolean PolygonSmooth; - GLboolean PolygonStipple; - GLboolean PolygonCull; - - /** MESA_META_SCISSOR */ - struct gl_scissor_attrib Scissor; - - /** MESA_META_SHADER */ - GLboolean VertexProgramEnabled; - struct gl_program *VertexProgram; - GLboolean FragmentProgramEnabled; - struct gl_program *FragmentProgram; - GLboolean ATIFragmentShaderEnabled; - struct gl_program *Program[MESA_SHADER_STAGES]; - struct gl_shader_program *ActiveShader; - struct gl_pipeline_object *Pipeline; - - /** MESA_META_STENCIL_TEST */ - struct gl_stencil_attrib Stencil; - - /** MESA_META_TRANSFORM */ - GLfloat ModelviewMatrix[16]; - GLfloat ProjectionMatrix[16]; - GLfloat TextureMatrix[16]; - /** GL_ARB_clip_control */ - GLenum ClipOrigin; /**< GL_LOWER_LEFT or GL_UPPER_LEFT */ - GLenum ClipDepthMode; /**< GL_NEGATIVE_ONE_TO_ONE or GL_ZERO_TO_ONE */ - - /** MESA_META_CLIP */ - GLbitfield ClipPlanesEnabled; - - /** MESA_META_TEXTURE */ - GLuint ActiveUnit; - /** for unit[0] only */ - struct gl_texture_object *CurrentTexture[NUM_TEXTURE_TARGETS]; - /** mask of TEXTURE_2D_BIT, etc */ - GLbitfield TexEnabled[MAX_TEXTURE_UNITS]; - GLbitfield TexGenEnabled[MAX_TEXTURE_UNITS]; - GLuint EnvMode; /* unit[0] only */ - - /** MESA_META_VERTEX */ - struct gl_vertex_array_object *VAO; - - /** MESA_META_VIEWPORT */ - GLfloat ViewportX, ViewportY, ViewportW, ViewportH; - GLclampf DepthNear, DepthFar; - - /** MESA_META_CLAMP_FRAGMENT_COLOR */ - GLenum ClampFragmentColor; - - /** MESA_META_CLAMP_VERTEX_COLOR */ - GLenum ClampVertexColor; - - /** MESA_META_CONDITIONAL_RENDER */ - struct gl_query_object *CondRenderQuery; - GLenum CondRenderMode; - - /** MESA_META_SELECT_FEEDBACK */ - GLenum RenderMode; - struct gl_selection Select; - struct gl_feedback Feedback; - - /** MESA_META_MULTISAMPLE */ - struct gl_multisample_attrib Multisample; - - /** MESA_META_FRAMEBUFFER_SRGB */ - GLboolean sRGBEnabled; - - /** Miscellaneous (always disabled) */ - GLboolean Lighting; - GLboolean RasterDiscard; - GLboolean TransformFeedbackNeedsResume; - - struct gl_framebuffer *DrawBuffer; - struct gl_framebuffer *ReadBuffer; - - /** MESA_META_DRAW_BUFFERS */ - GLenum16 ColorDrawBuffers[MAX_DRAW_BUFFERS]; -}; - -/** - * Temporary texture used for glBlitFramebuffer, glDrawPixels, etc. - * This is currently shared by all the meta ops. But we could create a - * separate one for each of glDrawPixel, glBlitFramebuffer, glCopyPixels, etc. - */ -struct temp_texture -{ - struct gl_texture_object *tex_obj; - GLenum Target; /**< GL_TEXTURE_2D or GL_TEXTURE_RECTANGLE */ - GLsizei MinSize; /**< Min texture size to allocate */ - GLsizei MaxSize; /**< Max possible texture size */ - GLboolean NPOT; /**< Non-power of two size OK? */ - GLsizei Width, Height; /**< Current texture size */ - GLenum IntFormat; - GLfloat Sright, Ttop; /**< right, top texcoords */ -}; - -/** - * State for GLSL texture sampler which is used to generate fragment - * shader in _mesa_meta_generate_mipmap(). - */ -struct blit_shader { - const char *type; - const char *func; - const char *texcoords; - struct gl_shader_program *shader_prog; -}; - -/** - * Table of all sampler types and shaders for accessing them. - */ -struct blit_shader_table { - struct blit_shader sampler_1d; - struct blit_shader sampler_2d; - struct blit_shader sampler_3d; - struct blit_shader sampler_rect; - struct blit_shader sampler_cubemap; - struct blit_shader sampler_1d_array; - struct blit_shader sampler_2d_array; - struct blit_shader sampler_cubemap_array; -}; - -/** - * State for glBlitFramebufer() - */ -struct blit_state -{ - GLuint VAO; - struct gl_buffer_object *buf_obj; - struct blit_shader_table shaders_with_depth; - struct blit_shader_table shaders_without_depth; - struct temp_texture depthTex; - bool no_ctsi_fallback; -}; - -struct fb_tex_blit_state -{ - GLint baseLevelSave, maxLevelSave; - struct gl_sampler_object *samp_obj; - struct gl_sampler_object *samp_obj_save; - struct gl_texture_object *tex_obj; - struct gl_texture_object *temp_tex_obj; - GLuint stencilSamplingSave; -}; - - -/** - * State for glClear() - */ -struct clear_state -{ - GLuint VAO; - struct gl_buffer_object *buf_obj; - struct gl_shader_program *ShaderProg; -}; - - -/** - * State for glCopyPixels() - */ -struct copypix_state -{ - GLuint VAO; - struct gl_buffer_object *buf_obj; -}; - - -/** - * State for glDrawPixels() - */ -struct drawpix_state -{ - GLuint VAO; - struct gl_buffer_object *buf_obj; - - GLuint StencilFP; /**< Fragment program for drawing stencil images */ - GLuint DepthFP; /**< Fragment program for drawing depth images */ -}; - - -/** - * State for glBitmap() - */ -struct bitmap_state -{ - GLuint VAO; - struct gl_buffer_object *buf_obj; - struct temp_texture Tex; /**< separate texture from other meta ops */ -}; - -/** - * State for _mesa_meta_generate_mipmap() - */ -struct gen_mipmap_state -{ - GLuint VAO; - struct gl_buffer_object *buf_obj; - struct gl_framebuffer *fb; - struct gl_sampler_object *samp_obj; - - struct blit_shader_table shaders; -}; - -/** - * One of the FBO states for decompress_state. There will be one for each - * required renderbuffer format. - */ -struct decompress_fbo_state -{ - struct gl_renderbuffer *rb; - struct gl_framebuffer *fb; - GLint Width, Height; -}; - -/** - * State for texture decompression - */ -struct decompress_state -{ - GLuint VAO; - struct decompress_fbo_state byteFBO, floatFBO; - struct gl_buffer_object *buf_obj; - struct gl_sampler_object *samp_obj; - - struct blit_shader_table shaders; -}; - -/** - * State for glDrawTex() - */ -struct drawtex_state -{ - GLuint VAO; - struct gl_buffer_object *buf_obj; -}; - -#define MAX_META_OPS_DEPTH 8 -/** - * All per-context meta state. - */ -struct gl_meta_state -{ - /** Stack of state saved during meta-ops */ - struct save_state Save[MAX_META_OPS_DEPTH]; - /** Save stack depth */ - GLuint SaveStackDepth; - - struct temp_texture TempTex; - - struct blit_state Blit; /**< For _mesa_meta_BlitFramebuffer() */ - struct clear_state Clear; /**< For _mesa_meta_Clear() */ - struct copypix_state CopyPix; /**< For _mesa_meta_CopyPixels() */ - struct drawpix_state DrawPix; /**< For _mesa_meta_DrawPixels() */ - struct bitmap_state Bitmap; /**< For _mesa_meta_Bitmap() */ - struct gen_mipmap_state Mipmap; /**< For _mesa_meta_GenerateMipmap() */ - struct decompress_state Decompress; /**< For texture decompression */ - struct drawtex_state DrawTex; /**< For _mesa_meta_DrawTex() */ -}; - -struct vertex { - GLfloat x, y, z, tex[4]; - GLfloat r, g, b, a; -}; - -extern void -_mesa_meta_init(struct gl_context *ctx); - -extern void -_mesa_meta_free(struct gl_context *ctx); - -extern void -_mesa_meta_begin(struct gl_context *ctx, GLbitfield state); - -extern void -_mesa_meta_end(struct gl_context *ctx); - -static inline bool -_mesa_meta_in_progress(struct gl_context *ctx) -{ - return ctx->Meta->SaveStackDepth != 0; -} - -extern void -_mesa_meta_fb_tex_blit_begin(struct gl_context *ctx, - struct fb_tex_blit_state *blit); - -extern void -_mesa_meta_fb_tex_blit_end(struct gl_context *ctx, GLenum target, - struct fb_tex_blit_state *blit); - -extern GLbitfield -_mesa_meta_BlitFramebuffer(struct gl_context *ctx, - const struct gl_framebuffer *readFb, - const struct gl_framebuffer *drawFb, - GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, - GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, - GLbitfield mask, GLenum filter); - -extern void -_mesa_meta_and_swrast_BlitFramebuffer(struct gl_context *ctx, - struct gl_framebuffer *readFb, - struct gl_framebuffer *drawFb, - GLint srcX0, GLint srcY0, - GLint srcX1, GLint srcY1, - GLint dstX0, GLint dstY0, - GLint dstX1, GLint dstY1, - GLbitfield mask, GLenum filter); - -extern void -_mesa_meta_Clear(struct gl_context *ctx, GLbitfield buffers); - -extern void -_mesa_meta_glsl_Clear(struct gl_context *ctx, GLbitfield buffers); - -extern void -_mesa_meta_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy, - GLsizei width, GLsizei height, - GLint dstx, GLint dsty, GLenum type); - -extern void -_mesa_meta_DrawPixels(struct gl_context *ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *unpack, - const GLvoid *pixels); - -extern void -_mesa_meta_Bitmap(struct gl_context *ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - const struct gl_pixelstore_attrib *unpack, - const GLubyte *bitmap); - -extern void -_mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target, - struct gl_texture_object *texObj); - -extern void -_mesa_meta_CopyTexSubImage(struct gl_context *ctx, GLuint dims, - struct gl_texture_image *texImage, - GLint xoffset, GLint yoffset, GLint slice, - struct gl_renderbuffer *rb, - GLint x, GLint y, - GLsizei width, GLsizei height); - -extern void -_mesa_meta_ClearTexSubImage(struct gl_context *ctx, - struct gl_texture_image *texImage, - GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, - const GLvoid *clearValue); - -extern void -_mesa_meta_GetTexSubImage(struct gl_context *ctx, - GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLenum type, GLvoid *pixels, - struct gl_texture_image *texImage); - -extern void -_mesa_meta_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z, - GLfloat width, GLfloat height); - -/* meta-internal functions */ -void -_mesa_meta_drawbuffers_from_bitfield(GLbitfield bits); - -void -_mesa_meta_link_program_with_debug(struct gl_context *ctx, - struct gl_shader_program *sh_prog); - -void -_mesa_meta_compile_and_link_program(struct gl_context *ctx, - const char *vs_source, - const char *fs_source, - const char *name, - struct gl_shader_program **sh_prog_ptr); - -extern void -_mesa_meta_use_program(struct gl_context *ctx, - struct gl_shader_program *sh_prog); - -GLboolean -_mesa_meta_alloc_texture(struct temp_texture *tex, - GLsizei width, GLsizei height, GLenum intFormat); - -void -_mesa_meta_setup_texture_coords(GLenum faceTarget, - GLint slice, - GLint xoffset, - GLint yoffset, - GLint width, - GLint height, - GLint total_width, - GLint total_height, - GLint total_depth, - GLfloat coords0[4], - GLfloat coords1[4], - GLfloat coords2[4], - GLfloat coords3[4]); - -struct temp_texture * -_mesa_meta_get_temp_texture(struct gl_context *ctx); - -struct temp_texture * -_mesa_meta_get_temp_depth_texture(struct gl_context *ctx); - -void -_mesa_meta_setup_vertex_objects(struct gl_context *ctx, - GLuint *VAO, struct gl_buffer_object **buf_obj, - bool use_generic_attributes, - unsigned vertex_size, unsigned texcoord_size, - unsigned color_size); - -void -_mesa_meta_setup_ff_tnl_for_blit(struct gl_context *ctx, - GLuint *VAO, struct gl_buffer_object **buf_obj, - unsigned texcoord_size); - -void -_mesa_meta_setup_drawpix_texture(struct gl_context *ctx, - struct temp_texture *tex, - GLboolean newTex, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - const GLvoid *pixels); - -void -_mesa_meta_setup_copypix_texture(struct gl_context *ctx, - struct temp_texture *tex, - GLint srcX, GLint srcY, - GLsizei width, GLsizei height, - GLenum intFormat, - GLenum filter); - -void -_mesa_meta_setup_blit_shader(struct gl_context *ctx, - GLenum target, - bool do_depth, - struct blit_shader_table *table); - -void -_mesa_meta_glsl_blit_cleanup(struct gl_context *ctx, struct blit_state *blit); - -void -_mesa_meta_blit_shader_table_cleanup(struct gl_context *ctx, - struct blit_shader_table *table); - -void -_mesa_meta_glsl_generate_mipmap_cleanup(struct gl_context *ctx, - struct gen_mipmap_state *mipmap); - -void -_mesa_meta_framebuffer_texture_image(struct gl_context *ctx, - struct gl_framebuffer *fb, - GLenum attachment, - struct gl_texture_image *texImage, - GLuint layer); - -#endif /* META_H */ diff --git a/src/mesa/drivers/common/meta_blit.c b/src/mesa/drivers/common/meta_blit.c deleted file mode 100644 index 26b054b..0000000 --- a/src/mesa/drivers/common/meta_blit.c +++ /dev/null @@ -1,543 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 2009 VMware, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -#include "main/glheader.h" -#include "main/mtypes.h" -#include "main/arbprogram.h" -#include "main/arrayobj.h" -#include "main/blend.h" -#include "main/depth.h" -#include "main/enable.h" -#include "main/enums.h" -#include "main/fbobject.h" -#include "main/image.h" -#include "main/macros.h" -#include "main/matrix.h" -#include "main/readpix.h" -#include "main/scissor.h" -#include "main/shaderapi.h" -#include "main/texobj.h" -#include "main/texenv.h" -#include "main/teximage.h" -#include "main/texparam.h" -#include "main/uniforms.h" -#include "main/varray.h" -#include "main/viewport.h" -#include "swrast/swrast.h" -#include "drivers/common/meta.h" - -static struct gl_texture_object * -texture_object_from_renderbuffer(struct gl_context *, struct gl_renderbuffer *); - -static struct gl_sampler_object * -setup_sampler(struct gl_context *, struct gl_texture_object *, GLenum target, - GLenum filter, GLuint srcLevel); - -/** Return offset in bytes of the field within a vertex struct */ -#define OFFSET(FIELD) ((void *) offsetof(struct vertex, FIELD)) - -static void -setup_glsl_blit_framebuffer(struct gl_context *ctx, - struct blit_state *blit, - const struct gl_framebuffer *drawFb, - struct gl_renderbuffer *src_rb, - GLenum target, - bool do_depth) -{ - const unsigned texcoord_size = 2 + (src_rb->Depth > 1 ? 1 : 0); - - /* target = GL_TEXTURE_RECTANGLE is not supported in GLES 3.0 */ - assert(_mesa_is_desktop_gl(ctx) || target == GL_TEXTURE_2D); - - - _mesa_meta_setup_vertex_objects(ctx, &blit->VAO, &blit->buf_obj, true, - 2, texcoord_size, 0); - - _mesa_meta_setup_blit_shader(ctx, target, do_depth, - do_depth ? &blit->shaders_with_depth - : &blit->shaders_without_depth); -} - -/** - * Try to do a color or depth glBlitFramebuffer using texturing. - * - * We can do this when the src renderbuffer is actually a texture, or when the - * driver exposes BindRenderbufferTexImage(). - */ -static bool -blitframebuffer_texture(struct gl_context *ctx, - const struct gl_framebuffer *readFb, - const struct gl_framebuffer *drawFb, - GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, - GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, - GLenum filter, GLint flipX, GLint flipY, - GLboolean glsl_version, GLboolean do_depth) -{ - int att_index = do_depth ? BUFFER_DEPTH : readFb->_ColorReadBufferIndex; - const struct gl_renderbuffer_attachment *readAtt = - &readFb->Attachment[att_index]; - struct blit_state *blit = &ctx->Meta->Blit; - struct fb_tex_blit_state fb_tex_blit; - const GLint dstX = MIN2(dstX0, dstX1); - const GLint dstY = MIN2(dstY0, dstY1); - const GLint dstW = abs(dstX1 - dstX0); - const GLint dstH = abs(dstY1 - dstY0); - const int srcW = abs(srcX1 - srcX0); - const int srcH = abs(srcY1 - srcY0); - struct gl_texture_object *texObj; - GLuint srcLevel; - GLenum target; - struct gl_renderbuffer *rb = readAtt->Renderbuffer; - struct temp_texture *meta_temp_texture; - - assert(rb->NumSamples == 0); - - _mesa_meta_fb_tex_blit_begin(ctx, &fb_tex_blit); - - if (readAtt->Texture && - (readAtt->Texture->Target == GL_TEXTURE_2D || - readAtt->Texture->Target == GL_TEXTURE_RECTANGLE)) { - /* If there's a texture attached of a type we can handle, then just use - * it directly. - */ - srcLevel = readAtt->TextureLevel; - texObj = readAtt->Texture; - } else if (!readAtt->Texture && ctx->Driver.BindRenderbufferTexImage) { - texObj = texture_object_from_renderbuffer(ctx, rb); - if (texObj == NULL) - return false; - - fb_tex_blit.temp_tex_obj = texObj; - - srcLevel = 0; - if (_mesa_is_winsys_fbo(readFb)) { - GLint temp = srcY0; - srcY0 = rb->Height - srcY1; - srcY1 = rb->Height - temp; - flipY = -flipY; - } - } else { - GLenum tex_base_format; - /* Fall back to doing a CopyTexSubImage to get the destination - * renderbuffer into a texture. - */ - if (ctx->Meta->Blit.no_ctsi_fallback) - return false; - - if (do_depth) { - meta_temp_texture = _mesa_meta_get_temp_depth_texture(ctx); - tex_base_format = GL_DEPTH_COMPONENT; - } else { - meta_temp_texture = _mesa_meta_get_temp_texture(ctx); - tex_base_format = - _mesa_base_tex_format(ctx, rb->InternalFormat); - } - - srcLevel = 0; - texObj = meta_temp_texture->tex_obj; - if (texObj == NULL) { - return false; - } - - _mesa_meta_setup_copypix_texture(ctx, meta_temp_texture, - srcX0, srcY0, - srcW, srcH, - tex_base_format, - filter); - - assert(texObj->Target == meta_temp_texture->Target); - - srcX0 = 0; - srcY0 = 0; - srcX1 = srcW; - srcY1 = srcH; - } - - target = texObj->Target; - fb_tex_blit.tex_obj = texObj; - fb_tex_blit.baseLevelSave = texObj->Attrib.BaseLevel; - fb_tex_blit.maxLevelSave = texObj->Attrib.MaxLevel; - fb_tex_blit.stencilSamplingSave = texObj->StencilSampling; - - if (glsl_version) { - setup_glsl_blit_framebuffer(ctx, blit, drawFb, rb, target, do_depth); - } - else { - _mesa_meta_setup_ff_tnl_for_blit(ctx, - &ctx->Meta->Blit.VAO, - &ctx->Meta->Blit.buf_obj, - 2); - } - - /* - printf("Blit from texture!\n"); - printf(" srcAtt %p dstAtt %p\n", readAtt, drawAtt); - printf(" srcTex %p dstText %p\n", texObj, drawAtt->Texture); - */ - - fb_tex_blit.samp_obj = setup_sampler(ctx, texObj, target, filter, srcLevel); - - if (ctx->Extensions.EXT_texture_sRGB_decode) { - /* The GL 4.4 spec, section 18.3.1 ("Blitting Pixel Rectangles") says: - * - * "When values are taken from the read buffer, if FRAMEBUFFER_SRGB - * is enabled and the value of FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING - * for the framebuffer attachment corresponding to the read buffer - * is SRGB (see section 9.2.3), the red, green, and blue components - * are converted from the non-linear sRGB color space according to - * equation 3.24. - * - * When values are written to the draw buffers, blit operations - * bypass most of the fragment pipeline. The only fragment - * operations which affect a blit are the pixel ownership test, - * the scissor test, and sRGB conversion (see section 17.3.9)." - * - * ES 3.0 contains nearly the exact same text, but omits the part - * about GL_FRAMEBUFFER_SRGB as that doesn't exist in ES. Mesa - * defaults it to on for ES contexts, so we can safely check it. - */ - const bool decode = - ctx->Color.sRGBEnabled && _mesa_is_format_srgb(rb->Format); - - _mesa_set_sampler_srgb_decode(ctx, fb_tex_blit.samp_obj, - decode ? GL_DECODE_EXT - : GL_SKIP_DECODE_EXT); - } - - if (!glsl_version) { - _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - _mesa_set_enable(ctx, target, GL_TRUE); - } - - /* Prepare vertex data (the VBO was previously created and bound) */ - { - struct vertex verts[4]; - GLfloat s0, t0, s1, t1; - - if (target == GL_TEXTURE_2D) { - const struct gl_texture_image *texImage - = _mesa_select_tex_image(texObj, target, srcLevel); - s0 = srcX0 / (float) texImage->Width; - s1 = srcX1 / (float) texImage->Width; - t0 = srcY0 / (float) texImage->Height; - t1 = srcY1 / (float) texImage->Height; - } - else { - assert(target == GL_TEXTURE_RECTANGLE_ARB); - s0 = (float) srcX0; - s1 = (float) srcX1; - t0 = (float) srcY0; - t1 = (float) srcY1; - } - - /* Silence valgrind warnings about reading uninitialized stack. */ - memset(verts, 0, sizeof(verts)); - - /* setup vertex positions */ - verts[0].x = -1.0F * flipX; - verts[0].y = -1.0F * flipY; - verts[1].x = 1.0F * flipX; - verts[1].y = -1.0F * flipY; - verts[2].x = 1.0F * flipX; - verts[2].y = 1.0F * flipY; - verts[3].x = -1.0F * flipX; - verts[3].y = 1.0F * flipY; - - verts[0].tex[0] = s0; - verts[0].tex[1] = t0; - verts[0].tex[2] = readAtt->Zoffset; - verts[1].tex[0] = s1; - verts[1].tex[1] = t0; - verts[1].tex[2] = readAtt->Zoffset; - verts[2].tex[0] = s1; - verts[2].tex[1] = t1; - verts[2].tex[2] = readAtt->Zoffset; - verts[3].tex[0] = s0; - verts[3].tex[1] = t1; - verts[3].tex[2] = readAtt->Zoffset; - - _mesa_buffer_sub_data(ctx, blit->buf_obj, 0, sizeof(verts), verts); - } - - /* setup viewport */ - _mesa_set_viewport(ctx, 0, dstX, dstY, dstW, dstH); - _mesa_ColorMask(!do_depth, !do_depth, !do_depth, !do_depth); - _mesa_set_enable(ctx, GL_DEPTH_TEST, do_depth); - _mesa_DepthMask(do_depth); - _mesa_DepthFunc(GL_ALWAYS); - - _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - _mesa_meta_fb_tex_blit_end(ctx, target, &fb_tex_blit); - - return true; -} - -void -_mesa_meta_fb_tex_blit_begin(struct gl_context *ctx, - struct fb_tex_blit_state *blit) -{ - /* None of the existing callers preinitialize fb_tex_blit_state to zeros, - * and both use stack variables. If samp_obj_save is not NULL, - * _mesa_reference_sampler_object will try to dereference it. Leaving - * random garbage in samp_obj_save can only lead to crashes. - * - * Since the state isn't persistent across calls, we won't catch ref - * counting problems. - */ - blit->samp_obj_save = NULL; - _mesa_reference_sampler_object(ctx, &blit->samp_obj_save, - ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler); - blit->temp_tex_obj = NULL; -} - -void -_mesa_meta_fb_tex_blit_end(struct gl_context *ctx, GLenum target, - struct fb_tex_blit_state *blit) -{ - struct gl_texture_object *const texObj = - _mesa_get_current_tex_object(ctx, target); - - /* Either there is no temporary texture or the temporary texture is bound. */ - assert(blit->temp_tex_obj == NULL || blit->temp_tex_obj == texObj); - - /* Restore texture object state, the texture binding will be restored by - * _mesa_meta_end(). If the texture is the temporary texture that is about - * to be destroyed, don't bother restoring its state. - */ - if (blit->temp_tex_obj == NULL) { - /* If the target restricts values for base level or max level, we assume - * that the original values were valid. - */ - if (blit->baseLevelSave != texObj->Attrib.BaseLevel) - _mesa_texture_parameteriv(ctx, texObj, GL_TEXTURE_BASE_LEVEL, - &blit->baseLevelSave, false); - - if (blit->maxLevelSave != texObj->Attrib.MaxLevel) - _mesa_texture_parameteriv(ctx, texObj, GL_TEXTURE_MAX_LEVEL, - &blit->maxLevelSave, false); - - /* If ARB_stencil_texturing is not supported, the mode won't have changed. */ - if (texObj->StencilSampling != blit->stencilSamplingSave) { - /* GLint so the compiler won't complain about type signedness mismatch - * in the call to _mesa_texture_parameteriv below. - */ - const GLint param = blit->stencilSamplingSave ? - GL_STENCIL_INDEX : GL_DEPTH_COMPONENT; - - _mesa_texture_parameteriv(ctx, texObj, GL_DEPTH_STENCIL_TEXTURE_MODE, - ¶m, false); - } - } - - _mesa_bind_sampler(ctx, ctx->Texture.CurrentUnit, blit->samp_obj_save); - _mesa_reference_sampler_object(ctx, &blit->samp_obj_save, NULL); - _mesa_reference_sampler_object(ctx, &blit->samp_obj, NULL); - _mesa_delete_nameless_texture(ctx, blit->temp_tex_obj); -} - -static struct gl_texture_object * -texture_object_from_renderbuffer(struct gl_context *ctx, - struct gl_renderbuffer *rb) -{ - struct gl_texture_image *texImage; - struct gl_texture_object *texObj; - const GLenum target = GL_TEXTURE_2D; - - texObj = ctx->Driver.NewTextureObject(ctx, 0xDEADBEEF, target); - texImage = _mesa_get_tex_image(ctx, texObj, target, 0); - - if (!ctx->Driver.BindRenderbufferTexImage(ctx, rb, texImage)) { - _mesa_delete_nameless_texture(ctx, texObj); - return NULL; - } - - if (ctx->Driver.FinishRenderTexture && !rb->NeedsFinishRenderTexture) { - rb->NeedsFinishRenderTexture = true; - ctx->Driver.FinishRenderTexture(ctx, rb); - } - - return texObj; -} - -static struct gl_sampler_object * -setup_sampler(struct gl_context *ctx, struct gl_texture_object *texObj, - GLenum target, GLenum filter, GLuint srcLevel) -{ - struct gl_sampler_object *samp_obj = - ctx->Driver.NewSamplerObject(ctx, 0xDEADBEEF); - - if (samp_obj == NULL) - return NULL; - - _mesa_bind_sampler(ctx, ctx->Texture.CurrentUnit, samp_obj); - _mesa_set_sampler_filters(ctx, samp_obj, filter, filter); - _mesa_set_sampler_wrap(ctx, samp_obj, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, - samp_obj->Attrib.WrapR); - - /* Prepare src texture state */ - _mesa_bind_texture(ctx, target, texObj); - if (target != GL_TEXTURE_RECTANGLE_ARB) { - _mesa_texture_parameteriv(ctx, texObj, GL_TEXTURE_BASE_LEVEL, - (GLint *) &srcLevel, false); - _mesa_texture_parameteriv(ctx, texObj, GL_TEXTURE_MAX_LEVEL, - (GLint *) &srcLevel, false); - } - - return samp_obj; -} - -/** - * Meta implementation of ctx->Driver.BlitFramebuffer() in terms - * of texture mapping and polygon rendering. - */ -GLbitfield -_mesa_meta_BlitFramebuffer(struct gl_context *ctx, - const struct gl_framebuffer *readFb, - const struct gl_framebuffer *drawFb, - GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, - GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, - GLbitfield mask, GLenum filter) -{ - const GLint dstW = abs(dstX1 - dstX0); - const GLint dstH = abs(dstY1 - dstY0); - const GLint dstFlipX = (dstX1 - dstX0) / dstW; - const GLint dstFlipY = (dstY1 - dstY0) / dstH; - - struct { - GLint srcX0, srcY0, srcX1, srcY1; - GLint dstX0, dstY0, dstX1, dstY1; - } clip = { - srcX0, srcY0, srcX1, srcY1, - dstX0, dstY0, dstX1, dstY1 - }; - - const GLboolean use_glsl_version = ctx->Extensions.ARB_vertex_shader && - ctx->Extensions.ARB_fragment_shader; - - /* Multisample blit is not supported. */ - if (readFb->Visual.samples > 0) - return mask; - - /* Clip a copy of the blit coordinates. If these differ from the input - * coordinates, then we'll set the scissor. - */ - if (!_mesa_clip_blit(ctx, readFb, drawFb, - &clip.srcX0, &clip.srcY0, &clip.srcX1, &clip.srcY1, - &clip.dstX0, &clip.dstY0, &clip.dstX1, &clip.dstY1)) { - /* clipped/scissored everything away */ - return 0; - } - - /* Only scissor and FRAMEBUFFER_SRGB affect blit. Leave sRGB alone, but - * save restore scissor as we'll set a custom scissor if necessary. - */ - _mesa_meta_begin(ctx, MESA_META_ALL & - ~(MESA_META_DRAW_BUFFERS | - MESA_META_FRAMEBUFFER_SRGB)); - - /* Dithering shouldn't be performed for glBlitFramebuffer */ - _mesa_set_enable(ctx, GL_DITHER, GL_FALSE); - - /* If the clipping earlier changed the destination rect at all, then - * enable the scissor to clip to it. - */ - if (clip.dstX0 != dstX0 || clip.dstY0 != dstY0 || - clip.dstX1 != dstX1 || clip.dstY1 != dstY1) { - _mesa_set_enable(ctx, GL_SCISSOR_TEST, GL_TRUE); - _mesa_Scissor(MIN2(clip.dstX0, clip.dstX1), - MIN2(clip.dstY0, clip.dstY1), - abs(clip.dstX0 - clip.dstX1), - abs(clip.dstY0 - clip.dstY1)); - } - - /* Try faster, direct texture approach first */ - if (mask & GL_COLOR_BUFFER_BIT) { - if (blitframebuffer_texture(ctx, readFb, drawFb, - srcX0, srcY0, srcX1, srcY1, - dstX0, dstY0, dstX1, dstY1, - filter, dstFlipX, dstFlipY, - use_glsl_version, false)) { - mask &= ~GL_COLOR_BUFFER_BIT; - } - } - - if (mask & GL_DEPTH_BUFFER_BIT && use_glsl_version) { - if (blitframebuffer_texture(ctx, readFb, drawFb, - srcX0, srcY0, srcX1, srcY1, - dstX0, dstY0, dstX1, dstY1, - filter, dstFlipX, dstFlipY, - use_glsl_version, true)) { - mask &= ~GL_DEPTH_BUFFER_BIT; - } - } - - if (mask & GL_STENCIL_BUFFER_BIT) { - /* XXX can't easily do stencil */ - } - - _mesa_meta_end(ctx); - - return mask; -} - -void -_mesa_meta_glsl_blit_cleanup(struct gl_context *ctx, struct blit_state *blit) -{ - if (blit->VAO) { - _mesa_DeleteVertexArrays(1, &blit->VAO); - blit->VAO = 0; - _mesa_reference_buffer_object(ctx, &blit->buf_obj, NULL); - } - - _mesa_meta_blit_shader_table_cleanup(ctx, &blit->shaders_with_depth); - _mesa_meta_blit_shader_table_cleanup(ctx, &blit->shaders_without_depth); - - if (blit->depthTex.tex_obj != NULL) { - _mesa_delete_nameless_texture(ctx, blit->depthTex.tex_obj); - blit->depthTex.tex_obj = NULL; - } -} - -void -_mesa_meta_and_swrast_BlitFramebuffer(struct gl_context *ctx, - struct gl_framebuffer *readFb, - struct gl_framebuffer *drawFb, - GLint srcX0, GLint srcY0, - GLint srcX1, GLint srcY1, - GLint dstX0, GLint dstY0, - GLint dstX1, GLint dstY1, - GLbitfield mask, GLenum filter) -{ - mask = _mesa_meta_BlitFramebuffer(ctx, readFb, drawFb, - srcX0, srcY0, srcX1, srcY1, - dstX0, dstY0, dstX1, dstY1, - mask, filter); - if (mask == 0x0) - return; - - _swrast_BlitFramebuffer(ctx, readFb, drawFb, - srcX0, srcY0, srcX1, srcY1, - dstX0, dstY0, dstX1, dstY1, - mask, filter); -} diff --git a/src/mesa/drivers/common/meta_generate_mipmap.c b/src/mesa/drivers/common/meta_generate_mipmap.c deleted file mode 100644 index aa1f2b2..0000000 --- a/src/mesa/drivers/common/meta_generate_mipmap.c +++ /dev/null @@ -1,379 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 2009 VMware, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -/** - * Meta operations. Some GL operations can be expressed in terms of - * other GL operations. For example, glBlitFramebuffer() can be done - * with texture mapping and glClear() can be done with polygon rendering. - * - * \author Brian Paul - */ - -#include "main/arrayobj.h" -#include "main/blend.h" -#include "main/buffers.h" -#include "main/enums.h" -#include "main/enable.h" -#include "main/fbobject.h" -#include "main/framebuffer.h" -#include "main/macros.h" -#include "main/mipmap.h" -#include "main/teximage.h" -#include "main/texobj.h" -#include "main/texparam.h" -#include "main/varray.h" -#include "main/viewport.h" -#include "drivers/common/meta.h" -#include "program/prog_instruction.h" - - -/** - * Check if the call to _mesa_meta_GenerateMipmap() will require a - * software fallback. The fallback path will require that the texture - * images are mapped. - * \return GL_TRUE if a fallback is needed, GL_FALSE otherwise - */ -static bool -fallback_required(struct gl_context *ctx, GLenum target, - struct gl_texture_object *texObj) -{ - struct gen_mipmap_state *mipmap = &ctx->Meta->Mipmap; - struct gl_texture_image *baseImage; - GLuint srcLevel; - GLenum status; - - /* check for fallbacks */ - if (target == GL_TEXTURE_3D) { - _mesa_perf_debug(ctx, MESA_DEBUG_SEVERITY_HIGH, - "glGenerateMipmap() to %s target\n", - _mesa_enum_to_string(target)); - return true; - } - - srcLevel = texObj->Attrib.BaseLevel; - baseImage = _mesa_select_tex_image(texObj, target, srcLevel); - if (!baseImage) { - _mesa_perf_debug(ctx, MESA_DEBUG_SEVERITY_HIGH, - "glGenerateMipmap() couldn't find base teximage\n"); - return true; - } - - if (_mesa_is_format_compressed(baseImage->TexFormat)) { - _mesa_perf_debug(ctx, MESA_DEBUG_SEVERITY_HIGH, - "glGenerateMipmap() with %s format\n", - _mesa_get_format_name(baseImage->TexFormat)); - return true; - } - - if (_mesa_is_format_srgb(baseImage->TexFormat) && - !ctx->Extensions.EXT_texture_sRGB_decode) { - /* The texture format is sRGB but we can't turn off sRGB->linear - * texture sample conversion. So we won't be able to generate the - * right colors when rendering. Need to use a fallback. - */ - _mesa_perf_debug(ctx, MESA_DEBUG_SEVERITY_HIGH, - "glGenerateMipmap() of sRGB texture without " - "sRGB decode\n"); - return true; - } - - /* - * Test that we can actually render in the texture's format. - */ - if (mipmap->fb == NULL) { - mipmap->fb = ctx->Driver.NewFramebuffer(ctx, 0xDEADBEEF); - if (mipmap->fb == NULL) { - _mesa_perf_debug(ctx, MESA_DEBUG_SEVERITY_HIGH, - "glGenerateMipmap() ran out of memory\n"); - return true; - } - } - - _mesa_meta_framebuffer_texture_image(ctx, mipmap->fb, - GL_COLOR_ATTACHMENT0, baseImage, 0); - - status = _mesa_check_framebuffer_status(ctx, mipmap->fb); - if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { - _mesa_perf_debug(ctx, MESA_DEBUG_SEVERITY_HIGH, - "glGenerateMipmap() got incomplete FBO\n"); - return true; - } - - return false; -} - -void -_mesa_meta_glsl_generate_mipmap_cleanup(struct gl_context *ctx, - struct gen_mipmap_state *mipmap) -{ - if (mipmap->VAO == 0) - return; - _mesa_DeleteVertexArrays(1, &mipmap->VAO); - mipmap->VAO = 0; - _mesa_reference_buffer_object(ctx, &mipmap->buf_obj, NULL); - _mesa_reference_sampler_object(ctx, &mipmap->samp_obj, NULL); - _mesa_reference_framebuffer(&mipmap->fb, NULL); - - _mesa_meta_blit_shader_table_cleanup(ctx, &mipmap->shaders); -} - - -/** - * Called via ctx->Driver.GenerateMipmap() - * Note: We don't yet support 3D textures, or texture borders. - */ -void -_mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target, - struct gl_texture_object *texObj) -{ - struct gen_mipmap_state *mipmap = &ctx->Meta->Mipmap; - struct vertex verts[4]; - const GLuint baseLevel = texObj->Attrib.BaseLevel; - const GLuint maxLevel = texObj->Attrib.MaxLevel; - const GLint maxLevelSave = texObj->Attrib.MaxLevel; - const GLboolean genMipmapSave = texObj->Attrib.GenerateMipmap; - const GLboolean use_glsl_version = ctx->Extensions.ARB_vertex_shader && - ctx->Extensions.ARB_fragment_shader; - GLenum faceTarget; - GLuint dstLevel; - struct gl_sampler_object *samp_obj_save = NULL; - GLint swizzle[4]; - GLboolean swizzleSaved = GL_FALSE; - - /* GLint so the compiler won't complain about type signedness mismatch in - * the calls to _mesa_texture_parameteriv below. - */ - static const GLint always_false = GL_FALSE; - static const GLint always_true = GL_TRUE; - - if (fallback_required(ctx, target, texObj)) { - _mesa_generate_mipmap(ctx, target, texObj); - return; - } - - if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && - target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) { - faceTarget = target; - target = GL_TEXTURE_CUBE_MAP; - } else { - faceTarget = target; - } - - _mesa_meta_begin(ctx, MESA_META_ALL & ~MESA_META_DRAW_BUFFERS); - _mesa_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - _mesa_Disable(GL_DITHER); - - /* Choose between glsl version and fixed function version of - * GenerateMipmap function. - */ - if (use_glsl_version) { - _mesa_meta_setup_vertex_objects(ctx, &mipmap->VAO, &mipmap->buf_obj, true, - 2, 4, 0); - _mesa_meta_setup_blit_shader(ctx, target, false, &mipmap->shaders); - } else { - _mesa_meta_setup_ff_tnl_for_blit(ctx, &mipmap->VAO, &mipmap->buf_obj, 3); - _mesa_set_enable(ctx, target, GL_TRUE); - } - - _mesa_reference_sampler_object(ctx, &samp_obj_save, - ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler); - - /* We may have been called from glGenerateTextureMipmap with CurrentUnit - * still set to 0, so we don't know when we can skip binding the texture. - * Assume that _mesa_bind_texture will be fast if we're rebinding the same - * texture. - */ - _mesa_bind_texture(ctx, target, texObj); - - if (mipmap->samp_obj == NULL) { - mipmap->samp_obj = ctx->Driver.NewSamplerObject(ctx, 0xDEADBEEF); - if (mipmap->samp_obj == NULL) { - /* This is a bit lazy. Flag out of memory, and then don't bother to - * clean up. Once out of memory is flagged, the only realistic next - * move is to destroy the context. That will trigger all the right - * clean up. - */ - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenerateMipmap"); - return; - } - - _mesa_set_sampler_filters(ctx, mipmap->samp_obj, GL_LINEAR_MIPMAP_LINEAR, - GL_LINEAR); - _mesa_set_sampler_wrap(ctx, mipmap->samp_obj, GL_CLAMP_TO_EDGE, - GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE); - } - - if (ctx->Extensions.EXT_texture_sRGB_decode) { - const struct gl_texture_image *baseImage = - _mesa_select_tex_image(texObj, target, texObj->Attrib.BaseLevel); - const bool srgb = _mesa_is_format_srgb(baseImage->TexFormat); - - _mesa_set_sampler_srgb_decode(ctx, mipmap->samp_obj, - srgb ? GL_DECODE_EXT : GL_SKIP_DECODE_EXT); - _mesa_set_framebuffer_srgb(ctx, srgb); - } - - _mesa_bind_sampler(ctx, ctx->Texture.CurrentUnit, mipmap->samp_obj); - - assert(mipmap->fb != NULL); - _mesa_bind_framebuffers(ctx, mipmap->fb, mipmap->fb); - - _mesa_texture_parameteriv(ctx, texObj, GL_GENERATE_MIPMAP, &always_false, false); - - if (texObj->Attrib._Swizzle != SWIZZLE_NOOP) { - static const GLint swizzleNoop[4] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA }; - memcpy(swizzle, texObj->Attrib.Swizzle, sizeof(swizzle)); - swizzleSaved = GL_TRUE; - _mesa_texture_parameteriv(ctx, texObj, GL_TEXTURE_SWIZZLE_RGBA, - swizzleNoop, false); - } - - /* Silence valgrind warnings about reading uninitialized stack. */ - memset(verts, 0, sizeof(verts)); - - /* setup vertex positions */ - verts[0].x = -1.0F; - verts[0].y = -1.0F; - verts[1].x = 1.0F; - verts[1].y = -1.0F; - verts[2].x = 1.0F; - verts[2].y = 1.0F; - verts[3].x = -1.0F; - verts[3].y = 1.0F; - - /* texture is already locked, unlock now */ - _mesa_unlock_texture(ctx, texObj); - - _mesa_prepare_mipmap_levels(ctx, texObj, baseLevel, maxLevel); - - for (dstLevel = baseLevel + 1; dstLevel <= maxLevel; dstLevel++) { - const struct gl_texture_image *srcImage; - struct gl_texture_image *dstImage; - const GLuint srcLevel = dstLevel - 1; - GLuint layer; - GLsizei srcWidth, srcHeight, srcDepth; - GLsizei dstWidth, dstHeight, dstDepth; - - srcImage = _mesa_select_tex_image(texObj, faceTarget, srcLevel); - assert(srcImage->Border == 0); - - /* src size */ - srcWidth = srcImage->Width; - if (target == GL_TEXTURE_1D_ARRAY) { - srcHeight = 1; - srcDepth = srcImage->Height; - } else { - srcHeight = srcImage->Height; - srcDepth = srcImage->Depth; - } - - /* new dst size */ - dstWidth = minify(srcWidth, 1); - dstHeight = minify(srcHeight, 1); - dstDepth = target == GL_TEXTURE_3D ? minify(srcDepth, 1) : srcDepth; - - if (dstWidth == srcWidth && - dstHeight == srcHeight && - dstDepth == srcDepth) { - /* all done */ - break; - } - - /* Allocate storage for the destination mipmap image(s) */ - - /* Set MaxLevel large enough to hold the new level when we allocate it */ - _mesa_texture_parameteriv(ctx, texObj, GL_TEXTURE_MAX_LEVEL, - (GLint *) &dstLevel, false); - - dstImage = _mesa_select_tex_image(texObj, faceTarget, dstLevel); - - /* All done. We either ran out of memory or we would go beyond the last - * valid level of an immutable texture if we continued. - */ - if (dstImage == NULL) - break; - - /* limit minification to src level */ - _mesa_texture_parameteriv(ctx, texObj, GL_TEXTURE_MAX_LEVEL, - (GLint *) &srcLevel, false); - - /* setup viewport */ - _mesa_set_viewport(ctx, 0, 0, 0, dstWidth, dstHeight); - _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0); - - for (layer = 0; layer < dstDepth; ++layer) { - /* Setup texture coordinates */ - _mesa_meta_setup_texture_coords(faceTarget, - layer, - 0, 0, /* xoffset, yoffset */ - srcWidth, srcHeight, /* img size */ - srcWidth, srcHeight, srcDepth, - verts[0].tex, - verts[1].tex, - verts[2].tex, - verts[3].tex); - - /* upload vertex data */ - _mesa_buffer_data(ctx, mipmap->buf_obj, GL_NONE, sizeof(verts), verts, - GL_DYNAMIC_DRAW, __func__); - - _mesa_meta_framebuffer_texture_image(ctx, ctx->DrawBuffer, - GL_COLOR_ATTACHMENT0, dstImage, - layer); - - /* sanity check */ - if (_mesa_check_framebuffer_status(ctx, ctx->DrawBuffer) != - GL_FRAMEBUFFER_COMPLETE) { - _mesa_problem(ctx, "Unexpected incomplete framebuffer in " - "_mesa_meta_GenerateMipmap()"); - break; - } - - assert(dstWidth == ctx->DrawBuffer->Width); - if (target == GL_TEXTURE_1D_ARRAY) { - assert(dstHeight == 1); - } else { - assert(dstHeight == ctx->DrawBuffer->Height); - } - - _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - } - } - - _mesa_lock_texture(ctx, texObj); /* relock */ - - _mesa_bind_sampler(ctx, ctx->Texture.CurrentUnit, samp_obj_save); - _mesa_reference_sampler_object(ctx, &samp_obj_save, NULL); - - _mesa_meta_end(ctx); - - _mesa_texture_parameteriv(ctx, texObj, GL_TEXTURE_MAX_LEVEL, &maxLevelSave, - false); - if (genMipmapSave) - _mesa_texture_parameteriv(ctx, texObj, GL_GENERATE_MIPMAP, &always_true, - false); - if (swizzleSaved) - _mesa_texture_parameteriv(ctx, texObj, GL_TEXTURE_SWIZZLE_RGBA, swizzle, - false); -} diff --git a/src/mesa/math/m_clip_tmp.h b/src/mesa/math/m_clip_tmp.h deleted file mode 100644 index 60c0004..0000000 --- a/src/mesa/math/m_clip_tmp.h +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -/* - * New (3.1) transformation code written by Keith Whitwell. - */ - - -/* KW: a clever asm implementation would nestle integer versions - * of the outcode calculation underneath the division. Gcc won't - * do this, strangely enough, so I only do the divide in - * the case where the cliptest passes. This isn't essential, - * and an asm implementation needn't replicate that behaviour. - * - * \param clip_vec vector of incoming clip-space coords - * \param proj_vec vector of resultant NDC-space projected coords - * \param clipMask resulting array of clip flags - * \param orMask bitwise-OR of clipMask values - * \param andMask bitwise-AND of clipMask values - * \return proj_vec pointer - */ -static GLvector4f * TAG(cliptest_points4)( GLvector4f *clip_vec, - GLvector4f *proj_vec, - GLubyte clipMask[], - GLubyte *orMask, - GLubyte *andMask, - GLboolean viewport_z_clip ) -{ - const GLuint stride = clip_vec->stride; - const GLfloat *from = (GLfloat *)clip_vec->start; - const GLuint count = clip_vec->count; - GLuint c = 0; - GLfloat (*vProj)[4] = (GLfloat (*)[4])proj_vec->start; - GLubyte tmpAndMask = *andMask; - GLubyte tmpOrMask = *orMask; - GLuint i; - STRIDE_LOOP { - const GLfloat cx = from[0]; - const GLfloat cy = from[1]; - const GLfloat cz = from[2]; - const GLfloat cw = from[3]; -#if defined(__powerpc__) - /* on powerpc cliptest is 17% faster in this way. */ - GLuint mask; - mask = (((cw < cx) << CLIP_RIGHT_SHIFT)); - mask |= (((cw < -cx) << CLIP_LEFT_SHIFT)); - mask |= (((cw < cy) << CLIP_TOP_SHIFT)); - mask |= (((cw < -cy) << CLIP_BOTTOM_SHIFT)); - if (viewport_z_clip) { - mask |= (((cw < cz) << CLIP_FAR_SHIFT)); - mask |= (((cw < -cz) << CLIP_NEAR_SHIFT)); - } -#else - GLubyte mask = 0; - if (-cx + cw < 0) mask |= CLIP_RIGHT_BIT; - if ( cx + cw < 0) mask |= CLIP_LEFT_BIT; - if (-cy + cw < 0) mask |= CLIP_TOP_BIT; - if ( cy + cw < 0) mask |= CLIP_BOTTOM_BIT; - if (viewport_z_clip) { - if (-cz + cw < 0) mask |= CLIP_FAR_BIT; - if ( cz + cw < 0) mask |= CLIP_NEAR_BIT; - } -#endif - - clipMask[i] = mask; - if (mask) { - c++; - tmpAndMask &= mask; - tmpOrMask |= mask; - vProj[i][0] = 0; - vProj[i][1] = 0; - vProj[i][2] = 0; - vProj[i][3] = 1; - } else { - GLfloat oow = 1.0F / cw; - vProj[i][0] = cx * oow; - vProj[i][1] = cy * oow; - vProj[i][2] = cz * oow; - vProj[i][3] = oow; - } - } - - *orMask = tmpOrMask; - *andMask = (GLubyte) (c < count ? 0 : tmpAndMask); - - proj_vec->flags |= VEC_SIZE_4; - proj_vec->size = 4; - proj_vec->count = clip_vec->count; - return proj_vec; -} - - - -/* - * \param clip_vec vector of incoming clip-space coords - * \param proj_vec vector of resultant NDC-space projected coords - * \param clipMask resulting array of clip flags - * \param orMask bitwise-OR of clipMask values - * \param andMask bitwise-AND of clipMask values - * \return clip_vec pointer - */ -static GLvector4f * TAG(cliptest_np_points4)( GLvector4f *clip_vec, - GLvector4f *proj_vec, - GLubyte clipMask[], - GLubyte *orMask, - GLubyte *andMask, - GLboolean viewport_z_clip ) -{ - const GLuint stride = clip_vec->stride; - const GLuint count = clip_vec->count; - const GLfloat *from = (GLfloat *)clip_vec->start; - GLuint c = 0; - GLubyte tmpAndMask = *andMask; - GLubyte tmpOrMask = *orMask; - GLuint i; - (void) proj_vec; - STRIDE_LOOP { - const GLfloat cx = from[0]; - const GLfloat cy = from[1]; - const GLfloat cz = from[2]; - const GLfloat cw = from[3]; -#if defined(__powerpc__) - /* on powerpc cliptest is 17% faster in this way. */ - GLuint mask; - mask = (((cw < cx) << CLIP_RIGHT_SHIFT)); - mask |= (((cw < -cx) << CLIP_LEFT_SHIFT)); - mask |= (((cw < cy) << CLIP_TOP_SHIFT)); - mask |= (((cw < -cy) << CLIP_BOTTOM_SHIFT)); - if (viewport_z_clip) { - mask |= (((cw < cz) << CLIP_FAR_SHIFT)); - mask |= (((cw < -cz) << CLIP_NEAR_SHIFT)); - } -#else - GLubyte mask = 0; - if (-cx + cw < 0) mask |= CLIP_RIGHT_BIT; - if ( cx + cw < 0) mask |= CLIP_LEFT_BIT; - if (-cy + cw < 0) mask |= CLIP_TOP_BIT; - if ( cy + cw < 0) mask |= CLIP_BOTTOM_BIT; - if (viewport_z_clip) { - if (-cz + cw < 0) mask |= CLIP_FAR_BIT; - if ( cz + cw < 0) mask |= CLIP_NEAR_BIT; - } -#endif - - clipMask[i] = mask; - if (mask) { - c++; - tmpAndMask &= mask; - tmpOrMask |= mask; - } - } - - *orMask = tmpOrMask; - *andMask = (GLubyte) (c < count ? 0 : tmpAndMask); - return clip_vec; -} - - -static GLvector4f * TAG(cliptest_points3)( GLvector4f *clip_vec, - GLvector4f *proj_vec, - GLubyte clipMask[], - GLubyte *orMask, - GLubyte *andMask, - GLboolean viewport_z_clip ) -{ - const GLuint stride = clip_vec->stride; - const GLuint count = clip_vec->count; - const GLfloat *from = (GLfloat *)clip_vec->start; - GLubyte tmpOrMask = *orMask; - GLubyte tmpAndMask = *andMask; - GLuint i; - (void) proj_vec; - STRIDE_LOOP { - const GLfloat cx = from[0], cy = from[1], cz = from[2]; - GLubyte mask = 0; - if (cx > 1.0F) mask |= CLIP_RIGHT_BIT; - else if (cx < -1.0F) mask |= CLIP_LEFT_BIT; - if (cy > 1.0F) mask |= CLIP_TOP_BIT; - else if (cy < -1.0F) mask |= CLIP_BOTTOM_BIT; - if (viewport_z_clip) { - if (cz > 1.0F) mask |= CLIP_FAR_BIT; - else if (cz < -1.0F) mask |= CLIP_NEAR_BIT; - } - clipMask[i] = mask; - tmpOrMask |= mask; - tmpAndMask &= mask; - } - - *orMask = tmpOrMask; - *andMask = tmpAndMask; - return clip_vec; -} - - -static GLvector4f * TAG(cliptest_points2)( GLvector4f *clip_vec, - GLvector4f *proj_vec, - GLubyte clipMask[], - GLubyte *orMask, - GLubyte *andMask, - GLboolean viewport_z_clip ) -{ - const GLuint stride = clip_vec->stride; - const GLuint count = clip_vec->count; - const GLfloat *from = (GLfloat *)clip_vec->start; - GLubyte tmpOrMask = *orMask; - GLubyte tmpAndMask = *andMask; - GLuint i; - (void) proj_vec; - STRIDE_LOOP { - const GLfloat cx = from[0], cy = from[1]; - GLubyte mask = 0; - if (cx > 1.0F) mask |= CLIP_RIGHT_BIT; - else if (cx < -1.0F) mask |= CLIP_LEFT_BIT; - if (cy > 1.0F) mask |= CLIP_TOP_BIT; - else if (cy < -1.0F) mask |= CLIP_BOTTOM_BIT; - clipMask[i] = mask; - tmpOrMask |= mask; - tmpAndMask &= mask; - } - - *orMask = tmpOrMask; - *andMask = tmpAndMask; - return clip_vec; -} - - -void TAG(init_c_cliptest)( void ) -{ - _mesa_clip_tab[4] = TAG(cliptest_points4); - _mesa_clip_tab[3] = TAG(cliptest_points3); - _mesa_clip_tab[2] = TAG(cliptest_points2); - - _mesa_clip_np_tab[4] = TAG(cliptest_np_points4); - _mesa_clip_np_tab[3] = TAG(cliptest_points3); - _mesa_clip_np_tab[2] = TAG(cliptest_points2); -} diff --git a/src/mesa/math/m_copy_tmp.h b/src/mesa/math/m_copy_tmp.h deleted file mode 100644 index dd174b2..0000000 --- a/src/mesa/math/m_copy_tmp.h +++ /dev/null @@ -1,86 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -/* - * New (3.1) transformation code written by Keith Whitwell. - */ - - -#define COPY_FUNC( BITS ) \ -static void TAG2(copy, BITS)( GLvector4f *to, const GLvector4f *f ) \ -{ \ - GLfloat (*t)[4] = (GLfloat (*)[4])to->start; \ - GLfloat *from = f->start; \ - GLuint stride = f->stride; \ - GLuint count = to->count; \ - GLuint i; \ - \ - if (BITS) \ - STRIDE_LOOP { \ - if (BITS&1) t[i][0] = from[0]; \ - if (BITS&2) t[i][1] = from[1]; \ - if (BITS&4) t[i][2] = from[2]; \ - if (BITS&8) t[i][3] = from[3]; \ - } \ -} - -/* We got them all here: - */ -COPY_FUNC( 0x0 ) /* noop */ -COPY_FUNC( 0x1 ) -COPY_FUNC( 0x2 ) -COPY_FUNC( 0x3 ) -COPY_FUNC( 0x4 ) -COPY_FUNC( 0x5 ) -COPY_FUNC( 0x6 ) -COPY_FUNC( 0x7 ) -COPY_FUNC( 0x8 ) -COPY_FUNC( 0x9 ) -COPY_FUNC( 0xa ) -COPY_FUNC( 0xb ) -COPY_FUNC( 0xc ) -COPY_FUNC( 0xd ) -COPY_FUNC( 0xe ) -COPY_FUNC( 0xf ) - -static void TAG2(init_copy, 0)( void ) -{ - _mesa_copy_tab[0x0] = TAG2(copy, 0x0); - _mesa_copy_tab[0x1] = TAG2(copy, 0x1); - _mesa_copy_tab[0x2] = TAG2(copy, 0x2); - _mesa_copy_tab[0x3] = TAG2(copy, 0x3); - _mesa_copy_tab[0x4] = TAG2(copy, 0x4); - _mesa_copy_tab[0x5] = TAG2(copy, 0x5); - _mesa_copy_tab[0x6] = TAG2(copy, 0x6); - _mesa_copy_tab[0x7] = TAG2(copy, 0x7); - _mesa_copy_tab[0x8] = TAG2(copy, 0x8); - _mesa_copy_tab[0x9] = TAG2(copy, 0x9); - _mesa_copy_tab[0xa] = TAG2(copy, 0xa); - _mesa_copy_tab[0xb] = TAG2(copy, 0xb); - _mesa_copy_tab[0xc] = TAG2(copy, 0xc); - _mesa_copy_tab[0xd] = TAG2(copy, 0xd); - _mesa_copy_tab[0xe] = TAG2(copy, 0xe); - _mesa_copy_tab[0xf] = TAG2(copy, 0xf); -} diff --git a/src/mesa/math/m_dotprod_tmp.h b/src/mesa/math/m_dotprod_tmp.h deleted file mode 100644 index cae8090..0000000 --- a/src/mesa/math/m_dotprod_tmp.h +++ /dev/null @@ -1,102 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -/* - * New (3.1) transformation code written by Keith Whitwell. - */ - - -/* Note - respects the stride of the output vector. - */ -static void TAG(dotprod_vec2)( GLfloat *out, - GLuint outstride, - const GLvector4f *coord_vec, - const GLfloat plane[4] ) -{ - GLuint stride = coord_vec->stride; - GLfloat *coord = coord_vec->start; - GLuint count = coord_vec->count; - - GLuint i; - - const GLfloat plane0 = plane[0], plane1 = plane[1], plane3 = plane[3]; - - for (i=0;istride; - GLfloat *coord = coord_vec->start; - GLuint count = coord_vec->count; - - GLuint i; - - const GLfloat plane0 = plane[0], plane1 = plane[1], plane2 = plane[2]; - const GLfloat plane3 = plane[3]; - - for (i=0;istride; - GLfloat *coord = coord_vec->start; - GLuint count = coord_vec->count; - GLuint i; - - const GLfloat plane0 = plane[0], plane1 = plane[1], plane2 = plane[2]; - const GLfloat plane3 = plane[3]; - - for (i=0;istart; - const GLfloat *from = in->start; - const GLuint stride = in->stride; - const GLuint count = in->count; - const GLfloat *m = mat->inv; - GLfloat m0 = m[0], m4 = m[4], m8 = m[8]; - GLfloat m1 = m[1], m5 = m[5], m9 = m[9]; - GLfloat m2 = m[2], m6 = m[6], m10 = m[10]; - GLuint i; - - if (!lengths) { - STRIDE_LOOP { - GLfloat tx, ty, tz; - { - const GLfloat ux = from[0], uy = from[1], uz = from[2]; - tx = ux * m0 + uy * m1 + uz * m2; - ty = ux * m4 + uy * m5 + uz * m6; - tz = ux * m8 + uy * m9 + uz * m10; - } - { - GLdouble len = tx*tx + ty*ty + tz*tz; - if (len > 1e-20) { - GLfloat scale = 1.0f / sqrtf(len); - out[i][0] = tx * scale; - out[i][1] = ty * scale; - out[i][2] = tz * scale; - } - else { - out[i][0] = out[i][1] = out[i][2] = 0; - } - } - } - } - else { - if (scale != 1.0f) { - m0 *= scale, m4 *= scale, m8 *= scale; - m1 *= scale, m5 *= scale, m9 *= scale; - m2 *= scale, m6 *= scale, m10 *= scale; - } - - STRIDE_LOOP { - GLfloat tx, ty, tz; - { - const GLfloat ux = from[0], uy = from[1], uz = from[2]; - tx = ux * m0 + uy * m1 + uz * m2; - ty = ux * m4 + uy * m5 + uz * m6; - tz = ux * m8 + uy * m9 + uz * m10; - } - { - GLfloat len = lengths[i]; - out[i][0] = tx * len; - out[i][1] = ty * len; - out[i][2] = tz * len; - } - } - } - dest->count = in->count; -} - - -static void -TAG(transform_normalize_normals_no_rot)( const GLmatrix *mat, - GLfloat scale, - const GLvector4f *in, - const GLfloat *lengths, - GLvector4f *dest ) -{ - GLfloat (*out)[4] = (GLfloat (*)[4])dest->start; - const GLfloat *from = in->start; - const GLuint stride = in->stride; - const GLuint count = in->count; - const GLfloat *m = mat->inv; - GLfloat m0 = m[0]; - GLfloat m5 = m[5]; - GLfloat m10 = m[10]; - GLuint i; - - if (!lengths) { - STRIDE_LOOP { - GLfloat tx, ty, tz; - { - const GLfloat ux = from[0], uy = from[1], uz = from[2]; - tx = ux * m0 ; - ty = uy * m5 ; - tz = uz * m10; - } - { - GLdouble len = tx*tx + ty*ty + tz*tz; - if (len > 1e-20) { - GLfloat scale = 1.0f / sqrtf(len); - out[i][0] = tx * scale; - out[i][1] = ty * scale; - out[i][2] = tz * scale; - } - else { - out[i][0] = out[i][1] = out[i][2] = 0; - } - } - } - } - else { - m0 *= scale; - m5 *= scale; - m10 *= scale; - - STRIDE_LOOP { - GLfloat tx, ty, tz; - { - const GLfloat ux = from[0], uy = from[1], uz = from[2]; - tx = ux * m0 ; - ty = uy * m5 ; - tz = uz * m10; - } - { - GLfloat len = lengths[i]; - out[i][0] = tx * len; - out[i][1] = ty * len; - out[i][2] = tz * len; - } - } - } - dest->count = in->count; -} - - -static void -TAG(transform_rescale_normals_no_rot)( const GLmatrix *mat, - GLfloat scale, - const GLvector4f *in, - const GLfloat *lengths, - GLvector4f *dest ) -{ - GLfloat (*out)[4] = (GLfloat (*)[4])dest->start; - const GLfloat *from = in->start; - const GLuint stride = in->stride; - const GLuint count = in->count; - const GLfloat *m = mat->inv; - const GLfloat m0 = scale*m[0]; - const GLfloat m5 = scale*m[5]; - const GLfloat m10 = scale*m[10]; - GLuint i; - - (void) lengths; - - STRIDE_LOOP { - GLfloat ux = from[0], uy = from[1], uz = from[2]; - out[i][0] = ux * m0; - out[i][1] = uy * m5; - out[i][2] = uz * m10; - } - dest->count = in->count; -} - - -static void -TAG(transform_rescale_normals)( const GLmatrix *mat, - GLfloat scale, - const GLvector4f *in, - const GLfloat *lengths, - GLvector4f *dest ) -{ - GLfloat (*out)[4] = (GLfloat (*)[4])dest->start; - const GLfloat *from = in->start; - const GLuint stride = in->stride; - const GLuint count = in->count; - /* Since we are unlikely to have < 3 vertices in the buffer, - * it makes sense to pre-multiply by scale. - */ - const GLfloat *m = mat->inv; - const GLfloat m0 = scale*m[0], m4 = scale*m[4], m8 = scale*m[8]; - const GLfloat m1 = scale*m[1], m5 = scale*m[5], m9 = scale*m[9]; - const GLfloat m2 = scale*m[2], m6 = scale*m[6], m10 = scale*m[10]; - GLuint i; - - (void) lengths; - - STRIDE_LOOP { - GLfloat ux = from[0], uy = from[1], uz = from[2]; - out[i][0] = ux * m0 + uy * m1 + uz * m2; - out[i][1] = ux * m4 + uy * m5 + uz * m6; - out[i][2] = ux * m8 + uy * m9 + uz * m10; - } - dest->count = in->count; -} - - -static void -TAG(transform_normals_no_rot)( const GLmatrix *mat, - GLfloat scale, - const GLvector4f *in, - const GLfloat *lengths, - GLvector4f *dest ) -{ - GLfloat (*out)[4] = (GLfloat (*)[4])dest->start; - const GLfloat *from = in->start; - const GLuint stride = in->stride; - const GLuint count = in->count; - const GLfloat *m = mat->inv; - const GLfloat m0 = m[0]; - const GLfloat m5 = m[5]; - const GLfloat m10 = m[10]; - GLuint i; - - (void) scale; - (void) lengths; - - STRIDE_LOOP { - GLfloat ux = from[0], uy = from[1], uz = from[2]; - out[i][0] = ux * m0; - out[i][1] = uy * m5; - out[i][2] = uz * m10; - } - dest->count = in->count; -} - - -static void -TAG(transform_normals)( const GLmatrix *mat, - GLfloat scale, - const GLvector4f *in, - const GLfloat *lengths, - GLvector4f *dest ) -{ - GLfloat (*out)[4] = (GLfloat (*)[4])dest->start; - const GLfloat *from = in->start; - const GLuint stride = in->stride; - const GLuint count = in->count; - const GLfloat *m = mat->inv; - const GLfloat m0 = m[0], m4 = m[4], m8 = m[8]; - const GLfloat m1 = m[1], m5 = m[5], m9 = m[9]; - const GLfloat m2 = m[2], m6 = m[6], m10 = m[10]; - GLuint i; - - (void) scale; - (void) lengths; - - STRIDE_LOOP { - GLfloat ux = from[0], uy = from[1], uz = from[2]; - out[i][0] = ux * m0 + uy * m1 + uz * m2; - out[i][1] = ux * m4 + uy * m5 + uz * m6; - out[i][2] = ux * m8 + uy * m9 + uz * m10; - } - dest->count = in->count; -} - - -static void -TAG(normalize_normals)( const GLmatrix *mat, - GLfloat scale, - const GLvector4f *in, - const GLfloat *lengths, - GLvector4f *dest ) -{ - GLfloat (*out)[4] = (GLfloat (*)[4])dest->start; - const GLfloat *from = in->start; - const GLuint stride = in->stride; - const GLuint count = in->count; - GLuint i; - - (void) mat; - (void) scale; - - if (lengths) { - STRIDE_LOOP { - const GLfloat x = from[0], y = from[1], z = from[2]; - GLfloat invlen = lengths[i]; - out[i][0] = x * invlen; - out[i][1] = y * invlen; - out[i][2] = z * invlen; - } - } - else { - STRIDE_LOOP { - const GLfloat x = from[0], y = from[1], z = from[2]; - GLdouble len = x * x + y * y + z * z; - if (len > 1e-50) { - len = 1.0f / sqrtf(len); - out[i][0] = (GLfloat)(x * len); - out[i][1] = (GLfloat)(y * len); - out[i][2] = (GLfloat)(z * len); - } - else { - out[i][0] = x; - out[i][1] = y; - out[i][2] = z; - } - } - } - dest->count = in->count; -} - - -static void -TAG(rescale_normals)( const GLmatrix *mat, - GLfloat scale, - const GLvector4f *in, - const GLfloat *lengths, - GLvector4f *dest ) -{ - GLfloat (*out)[4] = (GLfloat (*)[4])dest->start; - const GLfloat *from = in->start; - const GLuint stride = in->stride; - const GLuint count = in->count; - GLuint i; - - (void) mat; - (void) lengths; - - STRIDE_LOOP { - SCALE_SCALAR_3V( out[i], scale, from ); - } - dest->count = in->count; -} - - -static void -TAG(init_c_norm_transform)( void ) -{ - _mesa_normal_tab[NORM_TRANSFORM_NO_ROT] = - TAG(transform_normals_no_rot); - - _mesa_normal_tab[NORM_TRANSFORM_NO_ROT | NORM_RESCALE] = - TAG(transform_rescale_normals_no_rot); - - _mesa_normal_tab[NORM_TRANSFORM_NO_ROT | NORM_NORMALIZE] = - TAG(transform_normalize_normals_no_rot); - - _mesa_normal_tab[NORM_TRANSFORM] = - TAG(transform_normals); - - _mesa_normal_tab[NORM_TRANSFORM | NORM_RESCALE] = - TAG(transform_rescale_normals); - - _mesa_normal_tab[NORM_TRANSFORM | NORM_NORMALIZE] = - TAG(transform_normalize_normals); - - _mesa_normal_tab[NORM_RESCALE] = - TAG(rescale_normals); - - _mesa_normal_tab[NORM_NORMALIZE] = - TAG(normalize_normals); -} diff --git a/src/mesa/math/m_xform.c b/src/mesa/math/m_xform.c deleted file mode 100644 index 718ad49..0000000 --- a/src/mesa/math/m_xform.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2003 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -/* - * Matrix/vertex/vector transformation stuff - * - * - * NOTES: - * 1. 4x4 transformation matrices are stored in memory in column major order. - * 2. Points/vertices are to be thought of as column vectors. - * 3. Transformation of a point p by a matrix M is: p' = M * p - */ - -#include "c99_math.h" -#include "main/glheader.h" -#include "main/macros.h" - -#include "m_eval.h" -#include "m_matrix.h" -#include "m_translate.h" -#include "m_xform.h" - - -#ifdef DEBUG_MATH -#include "m_debug.h" -#endif - -#ifdef USE_X86_ASM -#include "x86/common_x86_asm.h" -#endif - -#ifdef USE_X86_64_ASM -#include "x86-64/x86-64.h" -#endif - -#ifdef USE_SPARC_ASM -#include "sparc/sparc.h" -#endif - -clip_func _mesa_clip_tab[5]; -clip_func _mesa_clip_np_tab[5]; -dotprod_func _mesa_dotprod_tab[5]; -vec_copy_func _mesa_copy_tab[0x10]; -normal_func _mesa_normal_tab[0xf]; -transform_func *_mesa_transform_tab[5]; - - -/* Raw data format used for: - * - Object-to-eye transform prior to culling, although this too - * could be culled under some circumstances. - * - Eye-to-clip transform (via the function above). - * - Cliptesting - * - And everything else too, if culling happens to be disabled. - * - * GH: It's used for everything now, as clipping/culling is done - * elsewhere (most often by the driver itself). - */ -#define TAG(x) x -#define TAG2(x,y) x##y -#define STRIDE_LOOP for ( i = 0 ; i < count ; i++, STRIDE_F(from, stride) ) -#define LOOP for ( i = 0 ; i < n ; i++ ) -#define ARGS -#include "m_xform_tmp.h" -#include "m_clip_tmp.h" -#include "m_norm_tmp.h" -#include "m_dotprod_tmp.h" -#include "m_copy_tmp.h" -#undef TAG -#undef TAG2 -#undef LOOP -#undef ARGS - - -/* - * This is called only once. It initializes several tables with pointers - * to optimized transformation functions. This is where we can test for - * AMD 3Dnow! capability, Intel SSE, etc. and hook in the right code. - */ -void -_math_init_transformation( void ) -{ - init_c_transformations(); - init_c_norm_transform(); - init_c_cliptest(); - init_copy0(); - init_dotprod(); - -#ifdef DEBUG_MATH - _math_test_all_transform_functions( "default" ); - _math_test_all_normal_transform_functions( "default" ); - _math_test_all_cliptest_functions( "default" ); -#endif - -#ifdef USE_X86_ASM - _mesa_init_all_x86_transform_asm(); -#elif defined( USE_SPARC_ASM ) - _mesa_init_all_sparc_transform_asm(); -#elif defined( USE_X86_64_ASM ) - _mesa_init_all_x86_64_transform_asm(); -#endif -} diff --git a/src/mesa/math/m_xform_tmp.h b/src/mesa/math/m_xform_tmp.h deleted file mode 100644 index af85de3..0000000 --- a/src/mesa/math/m_xform_tmp.h +++ /dev/null @@ -1,810 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -/* - * New (3.1) transformation code written by Keith Whitwell. - */ - - -/*---------------------------------------------------------------------- - * Begin Keith's new code - * - *---------------------------------------------------------------------- - */ - -/* KW: Fixed stride, now measured in bytes as is the OpenGL array stride. - */ - -/* KW: These are now parameterized to produce two versions, one - * which transforms all incoming points, and a second which - * takes notice of a cullmask array, and only transforms - * unculled vertices. - */ - -/* KW: 1-vectors can sneak into the texture pipeline via the array - * interface. These functions are here because I want consistant - * treatment of the vertex sizes and a lazy strategy for - * cleaning unused parts of the vector, and so as not to exclude - * them from the vertex array interface. - * - * Under our current analysis of matrices, there is no way that - * the product of a matrix and a 1-vector can remain a 1-vector, - * with the exception of the identity transform. - */ - -/* KW: No longer zero-pad outgoing vectors. Now that external - * vectors can get into the pipeline we cannot ever assume - * that there is more to a vector than indicated by its - * size. - */ - -/* KW: Now uses clipmask and a flag to allow us to skip both/either - * cliped and/or culled vertices. - */ - -/* GH: Not any more -- it's easier (and faster) to just process the - * entire vector. Clipping and culling are handled further down - * the pipe, most often during or after the conversion to some - * driver-specific vertex format. - */ - -static void -TAG(transform_points1_general)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m12 = m[12]; - const GLfloat m1 = m[1], m13 = m[13]; - const GLfloat m2 = m[2], m14 = m[14]; - const GLfloat m3 = m[3], m15 = m[15]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0]; - to[i][0] = m0 * ox + m12; - to[i][1] = m1 * ox + m13; - to[i][2] = m2 * ox + m14; - to[i][3] = m3 * ox + m15; - } - to_vec->size = 4; - to_vec->flags |= VEC_SIZE_4; - to_vec->count = from_vec->count; -} - -static void -TAG(transform_points1_identity)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLuint count = from_vec->count; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint i; - (void) m; - if (to_vec == from_vec) return; - STRIDE_LOOP { - to[i][0] = from[0]; - } - to_vec->size = 1; - to_vec->flags |= VEC_SIZE_1; - to_vec->count = from_vec->count; -} - -static void -TAG(transform_points1_2d)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m1 = m[1]; - const GLfloat m12 = m[12], m13 = m[13]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0]; - to[i][0] = m0 * ox + m12; - to[i][1] = m1 * ox + m13; - } - to_vec->size = 2; - to_vec->flags |= VEC_SIZE_2; - to_vec->count = from_vec->count; -} - -static void -TAG(transform_points1_2d_no_rot)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m12 = m[12], m13 = m[13]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0]; - to[i][0] = m0 * ox + m12; - to[i][1] = m13; - } - to_vec->size = 2; - to_vec->flags |= VEC_SIZE_2; - to_vec->count = from_vec->count; -} - -static void -TAG(transform_points1_3d)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m1 = m[1], m2 = m[2]; - const GLfloat m12 = m[12], m13 = m[13], m14 = m[14]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0]; - to[i][0] = m0 * ox + m12; - to[i][1] = m1 * ox + m13; - to[i][2] = m2 * ox + m14; - } - to_vec->size = 3; - to_vec->flags |= VEC_SIZE_3; - to_vec->count = from_vec->count; -} - - -static void -TAG(transform_points1_3d_no_rot)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0]; - const GLfloat m12 = m[12], m13 = m[13], m14 = m[14]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0]; - to[i][0] = m0 * ox + m12; - to[i][1] = m13; - to[i][2] = m14; - } - to_vec->size = 3; - to_vec->flags |= VEC_SIZE_3; - to_vec->count = from_vec->count; -} - -static void -TAG(transform_points1_perspective)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m14 = m[14]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0]; - to[i][0] = m0 * ox ; - to[i][1] = 0 ; - to[i][2] = m14; - to[i][3] = 0; - } - to_vec->size = 4; - to_vec->flags |= VEC_SIZE_4; - to_vec->count = from_vec->count; -} - - - - -/* 2-vectors, which are a lot more relevant than 1-vectors, are - * present early in the geometry pipeline and throughout the - * texture pipeline. - */ -static void -TAG(transform_points2_general)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m4 = m[4], m12 = m[12]; - const GLfloat m1 = m[1], m5 = m[5], m13 = m[13]; - const GLfloat m2 = m[2], m6 = m[6], m14 = m[14]; - const GLfloat m3 = m[3], m7 = m[7], m15 = m[15]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0], oy = from[1]; - to[i][0] = m0 * ox + m4 * oy + m12; - to[i][1] = m1 * ox + m5 * oy + m13; - to[i][2] = m2 * ox + m6 * oy + m14; - to[i][3] = m3 * ox + m7 * oy + m15; - } - to_vec->size = 4; - to_vec->flags |= VEC_SIZE_4; - to_vec->count = from_vec->count; -} - -static void -TAG(transform_points2_identity)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - GLuint i; - (void) m; - if (to_vec == from_vec) return; - STRIDE_LOOP { - to[i][0] = from[0]; - to[i][1] = from[1]; - } - to_vec->size = 2; - to_vec->flags |= VEC_SIZE_2; - to_vec->count = from_vec->count; -} - -static void -TAG(transform_points2_2d)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m1 = m[1], m4 = m[4], m5 = m[5]; - const GLfloat m12 = m[12], m13 = m[13]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0], oy = from[1]; - to[i][0] = m0 * ox + m4 * oy + m12; - to[i][1] = m1 * ox + m5 * oy + m13; - } - to_vec->size = 2; - to_vec->flags |= VEC_SIZE_2; - to_vec->count = from_vec->count; -} - -static void -TAG(transform_points2_2d_no_rot)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m5 = m[5], m12 = m[12], m13 = m[13]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0], oy = from[1]; - to[i][0] = m0 * ox + m12; - to[i][1] = m5 * oy + m13; - } - to_vec->size = 2; - to_vec->flags |= VEC_SIZE_2; - to_vec->count = from_vec->count; -} - -static void -TAG(transform_points2_3d)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m1 = m[1], m2 = m[2], m4 = m[4], m5 = m[5]; - const GLfloat m6 = m[6], m12 = m[12], m13 = m[13], m14 = m[14]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0], oy = from[1]; - to[i][0] = m0 * ox + m4 * oy + m12; - to[i][1] = m1 * ox + m5 * oy + m13; - to[i][2] = m2 * ox + m6 * oy + m14; - } - to_vec->size = 3; - to_vec->flags |= VEC_SIZE_3; - to_vec->count = from_vec->count; -} - - -/* I would actually say this was a fairly important function, from - * a texture transformation point of view. - */ -static void -TAG(transform_points2_3d_no_rot)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m5 = m[5]; - const GLfloat m12 = m[12], m13 = m[13], m14 = m[14]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0], oy = from[1]; - to[i][0] = m0 * ox + m12; - to[i][1] = m5 * oy + m13; - to[i][2] = m14; - } - if (m14 == 0) { - to_vec->size = 2; - to_vec->flags |= VEC_SIZE_2; - } else { - to_vec->size = 3; - to_vec->flags |= VEC_SIZE_3; - } - to_vec->count = from_vec->count; -} - - -static void -TAG(transform_points2_perspective)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m5 = m[5], m14 = m[14]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0], oy = from[1]; - to[i][0] = m0 * ox ; - to[i][1] = m5 * oy ; - to[i][2] = m14; - to[i][3] = 0; - } - to_vec->size = 4; - to_vec->flags |= VEC_SIZE_4; - to_vec->count = from_vec->count; -} - - - -static void -TAG(transform_points3_general)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m4 = m[4], m8 = m[8], m12 = m[12]; - const GLfloat m1 = m[1], m5 = m[5], m9 = m[9], m13 = m[13]; - const GLfloat m2 = m[2], m6 = m[6], m10 = m[10], m14 = m[14]; - const GLfloat m3 = m[3], m7 = m[7], m11 = m[11], m15 = m[15]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0], oy = from[1], oz = from[2]; - to[i][0] = m0 * ox + m4 * oy + m8 * oz + m12; - to[i][1] = m1 * ox + m5 * oy + m9 * oz + m13; - to[i][2] = m2 * ox + m6 * oy + m10 * oz + m14; - to[i][3] = m3 * ox + m7 * oy + m11 * oz + m15; - } - to_vec->size = 4; - to_vec->flags |= VEC_SIZE_4; - to_vec->count = from_vec->count; -} - -static void -TAG(transform_points3_identity)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - GLuint i; - (void) m; - if (to_vec == from_vec) return; - STRIDE_LOOP { - to[i][0] = from[0]; - to[i][1] = from[1]; - to[i][2] = from[2]; - } - to_vec->size = 3; - to_vec->flags |= VEC_SIZE_3; - to_vec->count = from_vec->count; -} - -static void -TAG(transform_points3_2d)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m1 = m[1], m4 = m[4], m5 = m[5]; - const GLfloat m12 = m[12], m13 = m[13]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0], oy = from[1], oz = from[2]; - to[i][0] = m0 * ox + m4 * oy + m12 ; - to[i][1] = m1 * ox + m5 * oy + m13 ; - to[i][2] = + oz ; - } - to_vec->size = 3; - to_vec->flags |= VEC_SIZE_3; - to_vec->count = from_vec->count; -} - -static void -TAG(transform_points3_2d_no_rot)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m5 = m[5], m12 = m[12], m13 = m[13]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0], oy = from[1], oz = from[2]; - to[i][0] = m0 * ox + m12 ; - to[i][1] = m5 * oy + m13 ; - to[i][2] = + oz ; - } - to_vec->size = 3; - to_vec->flags |= VEC_SIZE_3; - to_vec->count = from_vec->count; -} - -static void -TAG(transform_points3_3d)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m1 = m[1], m2 = m[2], m4 = m[4], m5 = m[5]; - const GLfloat m6 = m[6], m8 = m[8], m9 = m[9], m10 = m[10]; - const GLfloat m12 = m[12], m13 = m[13], m14 = m[14]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0], oy = from[1], oz = from[2]; - to[i][0] = m0 * ox + m4 * oy + m8 * oz + m12 ; - to[i][1] = m1 * ox + m5 * oy + m9 * oz + m13 ; - to[i][2] = m2 * ox + m6 * oy + m10 * oz + m14 ; - } - to_vec->size = 3; - to_vec->flags |= VEC_SIZE_3; - to_vec->count = from_vec->count; -} - -/* previously known as ortho... - */ -static void -TAG(transform_points3_3d_no_rot)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m5 = m[5]; - const GLfloat m10 = m[10], m12 = m[12], m13 = m[13], m14 = m[14]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0], oy = from[1], oz = from[2]; - to[i][0] = m0 * ox + m12 ; - to[i][1] = m5 * oy + m13 ; - to[i][2] = m10 * oz + m14 ; - } - to_vec->size = 3; - to_vec->flags |= VEC_SIZE_3; - to_vec->count = from_vec->count; -} - -static void -TAG(transform_points3_perspective)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m5 = m[5], m8 = m[8], m9 = m[9]; - const GLfloat m10 = m[10], m14 = m[14]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0], oy = from[1], oz = from[2]; - to[i][0] = m0 * ox + m8 * oz ; - to[i][1] = m5 * oy + m9 * oz ; - to[i][2] = m10 * oz + m14 ; - to[i][3] = -oz ; - } - to_vec->size = 4; - to_vec->flags |= VEC_SIZE_4; - to_vec->count = from_vec->count; -} - - - -static void -TAG(transform_points4_general)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m4 = m[4], m8 = m[8], m12 = m[12]; - const GLfloat m1 = m[1], m5 = m[5], m9 = m[9], m13 = m[13]; - const GLfloat m2 = m[2], m6 = m[6], m10 = m[10], m14 = m[14]; - const GLfloat m3 = m[3], m7 = m[7], m11 = m[11], m15 = m[15]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3]; - to[i][0] = m0 * ox + m4 * oy + m8 * oz + m12 * ow; - to[i][1] = m1 * ox + m5 * oy + m9 * oz + m13 * ow; - to[i][2] = m2 * ox + m6 * oy + m10 * oz + m14 * ow; - to[i][3] = m3 * ox + m7 * oy + m11 * oz + m15 * ow; - } - to_vec->size = 4; - to_vec->flags |= VEC_SIZE_4; - to_vec->count = from_vec->count; -} - -static void -TAG(transform_points4_identity)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - GLuint i; - (void) m; - if (to_vec == from_vec) return; - STRIDE_LOOP { - to[i][0] = from[0]; - to[i][1] = from[1]; - to[i][2] = from[2]; - to[i][3] = from[3]; - } - to_vec->size = 4; - to_vec->flags |= VEC_SIZE_4; - to_vec->count = from_vec->count; -} - -static void -TAG(transform_points4_2d)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m1 = m[1], m4 = m[4], m5 = m[5]; - const GLfloat m12 = m[12], m13 = m[13]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3]; - to[i][0] = m0 * ox + m4 * oy + m12 * ow; - to[i][1] = m1 * ox + m5 * oy + m13 * ow; - to[i][2] = + oz ; - to[i][3] = ow; - } - to_vec->size = 4; - to_vec->flags |= VEC_SIZE_4; - to_vec->count = from_vec->count; -} - -static void -TAG(transform_points4_2d_no_rot)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m5 = m[5], m12 = m[12], m13 = m[13]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3]; - to[i][0] = m0 * ox + m12 * ow; - to[i][1] = m5 * oy + m13 * ow; - to[i][2] = + oz ; - to[i][3] = ow; - } - to_vec->size = 4; - to_vec->flags |= VEC_SIZE_4; - to_vec->count = from_vec->count; -} - -static void -TAG(transform_points4_3d)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m1 = m[1], m2 = m[2], m4 = m[4], m5 = m[5]; - const GLfloat m6 = m[6], m8 = m[8], m9 = m[9], m10 = m[10]; - const GLfloat m12 = m[12], m13 = m[13], m14 = m[14]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3]; - to[i][0] = m0 * ox + m4 * oy + m8 * oz + m12 * ow; - to[i][1] = m1 * ox + m5 * oy + m9 * oz + m13 * ow; - to[i][2] = m2 * ox + m6 * oy + m10 * oz + m14 * ow; - to[i][3] = ow; - } - to_vec->size = 4; - to_vec->flags |= VEC_SIZE_4; - to_vec->count = from_vec->count; -} - -static void -TAG(transform_points4_3d_no_rot)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m5 = m[5]; - const GLfloat m10 = m[10], m12 = m[12], m13 = m[13], m14 = m[14]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3]; - to[i][0] = m0 * ox + m12 * ow; - to[i][1] = m5 * oy + m13 * ow; - to[i][2] = m10 * oz + m14 * ow; - to[i][3] = ow; - } - to_vec->size = 4; - to_vec->flags |= VEC_SIZE_4; - to_vec->count = from_vec->count; -} - -static void -TAG(transform_points4_perspective)( GLvector4f *to_vec, - const GLfloat m[16], - const GLvector4f *from_vec ) -{ - const GLuint stride = from_vec->stride; - GLfloat *from = from_vec->start; - GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; - GLuint count = from_vec->count; - const GLfloat m0 = m[0], m5 = m[5], m8 = m[8], m9 = m[9]; - const GLfloat m10 = m[10], m14 = m[14]; - GLuint i; - STRIDE_LOOP { - const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3]; - to[i][0] = m0 * ox + m8 * oz ; - to[i][1] = m5 * oy + m9 * oz ; - to[i][2] = m10 * oz + m14 * ow ; - to[i][3] = -oz ; - } - to_vec->size = 4; - to_vec->flags |= VEC_SIZE_4; - to_vec->count = from_vec->count; -} - -static transform_func TAG(transform_tab_1)[7]; -static transform_func TAG(transform_tab_2)[7]; -static transform_func TAG(transform_tab_3)[7]; -static transform_func TAG(transform_tab_4)[7]; - -/* Similar functions could be called several times, with more highly - * optimized routines overwriting the arrays. This only occurs during - * startup. - */ -static void TAG(init_c_transformations)( void ) -{ -#define TAG_TAB _mesa_transform_tab -#define TAG_TAB_1 TAG(transform_tab_1) -#define TAG_TAB_2 TAG(transform_tab_2) -#define TAG_TAB_3 TAG(transform_tab_3) -#define TAG_TAB_4 TAG(transform_tab_4) - - TAG_TAB[1] = TAG_TAB_1; - TAG_TAB[2] = TAG_TAB_2; - TAG_TAB[3] = TAG_TAB_3; - TAG_TAB[4] = TAG_TAB_4; - - /* 1-D points (ie texcoords) */ - TAG_TAB_1[MATRIX_GENERAL] = TAG(transform_points1_general); - TAG_TAB_1[MATRIX_IDENTITY] = TAG(transform_points1_identity); - TAG_TAB_1[MATRIX_3D_NO_ROT] = TAG(transform_points1_3d_no_rot); - TAG_TAB_1[MATRIX_PERSPECTIVE] = TAG(transform_points1_perspective); - TAG_TAB_1[MATRIX_2D] = TAG(transform_points1_2d); - TAG_TAB_1[MATRIX_2D_NO_ROT] = TAG(transform_points1_2d_no_rot); - TAG_TAB_1[MATRIX_3D] = TAG(transform_points1_3d); - - /* 2-D points */ - TAG_TAB_2[MATRIX_GENERAL] = TAG(transform_points2_general); - TAG_TAB_2[MATRIX_IDENTITY] = TAG(transform_points2_identity); - TAG_TAB_2[MATRIX_3D_NO_ROT] = TAG(transform_points2_3d_no_rot); - TAG_TAB_2[MATRIX_PERSPECTIVE] = TAG(transform_points2_perspective); - TAG_TAB_2[MATRIX_2D] = TAG(transform_points2_2d); - TAG_TAB_2[MATRIX_2D_NO_ROT] = TAG(transform_points2_2d_no_rot); - TAG_TAB_2[MATRIX_3D] = TAG(transform_points2_3d); - - /* 3-D points */ - TAG_TAB_3[MATRIX_GENERAL] = TAG(transform_points3_general); - TAG_TAB_3[MATRIX_IDENTITY] = TAG(transform_points3_identity); - TAG_TAB_3[MATRIX_3D_NO_ROT] = TAG(transform_points3_3d_no_rot); - TAG_TAB_3[MATRIX_PERSPECTIVE] = TAG(transform_points3_perspective); - TAG_TAB_3[MATRIX_2D] = TAG(transform_points3_2d); - TAG_TAB_3[MATRIX_2D_NO_ROT] = TAG(transform_points3_2d_no_rot); - TAG_TAB_3[MATRIX_3D] = TAG(transform_points3_3d); - - /* 4-D points */ - TAG_TAB_4[MATRIX_GENERAL] = TAG(transform_points4_general); - TAG_TAB_4[MATRIX_IDENTITY] = TAG(transform_points4_identity); - TAG_TAB_4[MATRIX_3D_NO_ROT] = TAG(transform_points4_3d_no_rot); - TAG_TAB_4[MATRIX_PERSPECTIVE] = TAG(transform_points4_perspective); - TAG_TAB_4[MATRIX_2D] = TAG(transform_points4_2d); - TAG_TAB_4[MATRIX_2D_NO_ROT] = TAG(transform_points4_2d_no_rot); - TAG_TAB_4[MATRIX_3D] = TAG(transform_points4_3d); - -#undef TAG_TAB -#undef TAG_TAB_1 -#undef TAG_TAB_2 -#undef TAG_TAB_3 -#undef TAG_TAB_4 -} diff --git a/src/mesa/meson.build b/src/mesa/meson.build index ef1de6b..ed6d710 100644 --- a/src/mesa/meson.build +++ b/src/mesa/meson.build @@ -351,124 +351,6 @@ files_libmesa_common = files( 'x86/common_x86.c', ) -# mesa files -files_libmesa_classic = files( - 'math/m_clip_tmp.h', - 'math/m_copy_tmp.h', - 'math/m_dotprod_tmp.h', - 'math/m_norm_tmp.h', - 'math/m_xform.c', - 'math/m_xform.h', - 'math/m_xform_tmp.h', - 'tnl/t_context.c', - 'tnl/t_context.h', - 'tnl/t_draw.c', - 'tnl/tnl.h', - 'tnl/t_pipeline.c', - 'tnl/t_pipeline.h', - 'tnl/t_rebase.c', - 'tnl/t_split.c', - 'tnl/t_split_copy.c', - 'tnl/t_split.h', - 'tnl/t_split_inplace.c', - 'tnl/t_vb_cliptmp.h', - 'tnl/t_vb_fog.c', - 'tnl/t_vb_light.c', - 'tnl/t_vb_lighttmp.h', - 'tnl/t_vb_normals.c', - 'tnl/t_vb_points.c', - 'tnl/t_vb_program.c', - 'tnl/t_vb_render.c', - 'tnl/t_vb_rendertmp.h', - 'tnl/t_vb_texgen.c', - 'tnl/t_vb_texmat.c', - 'tnl/t_vb_vertex.c', - 'tnl/t_vertex.c', - 'tnl/t_vertex_generic.c', - 'tnl/t_vertex.h', - 'tnl/t_vertex_sse.c', - 'tnl/t_vp_build.c', - 'tnl/t_vp_build.h', - 'swrast/s_aaline.c', - 'swrast/s_aaline.h', - 'swrast/s_aalinetemp.h', - 'swrast/s_aatriangle.c', - 'swrast/s_aatriangle.h', - 'swrast/s_aatritemp.h', - 'swrast/s_alpha.c', - 'swrast/s_alpha.h', - 'swrast/s_atifragshader.c', - 'swrast/s_atifragshader.h', - 'swrast/s_bitmap.c', - 'swrast/s_blend.c', - 'swrast/s_blend.h', - 'swrast/s_blit.c', - 'swrast/s_chan.h', - 'swrast/s_clear.c', - 'swrast/s_context.c', - 'swrast/s_context.h', - 'swrast/s_copypix.c', - 'swrast/s_depth.c', - 'swrast/s_depth.h', - 'swrast/s_drawpix.c', - 'swrast_setup/ss_tritmp.h', - 'swrast_setup/ss_vb.h', - 'swrast_setup/swrast_setup.h', - 'swrast/s_feedback.c', - 'swrast/s_feedback.h', - 'swrast/s_fog.c', - 'swrast/s_fog.h', - 'swrast/s_fragprog.c', - 'swrast/s_fragprog.h', - 'swrast/s_lines.c', - 'swrast/s_lines.h', - 'swrast/s_linetemp.h', - 'swrast/s_logic.c', - 'swrast/s_logic.h', - 'swrast/s_masking.c', - 'swrast/s_masking.h', - 'swrast/s_points.c', - 'swrast/s_points.h', - 'swrast/s_renderbuffer.c', - 'swrast/s_renderbuffer.h', - 'swrast/s_span.c', - 'swrast/s_span.h', - 'swrast/s_stencil.c', - 'swrast/s_stencil.h', - 'swrast/s_texcombine.c', - 'swrast/s_texcombine.h', - 'swrast/s_texfetch.c', - 'swrast/s_texfetch.h', - 'swrast/s_texfetch_tmp.h', - 'swrast/s_texfilter.c', - 'swrast/s_texfilter.h', - 'swrast/s_texrender.c', - 'swrast/s_texture.c', - 'swrast/s_triangle.c', - 'swrast/s_triangle.h', - 'swrast/s_tritemp.h', - 'swrast/swrast.h', - 'swrast/s_zoom.c', - 'swrast/s_zoom.h', - 'swrast_setup/ss_context.c', - 'swrast_setup/ss_context.h', - 'swrast_setup/ss_triangle.c', - 'swrast_setup/ss_triangle.h', - 'drivers/common/driverfuncs.c', - 'drivers/common/driverfuncs.h', - 'drivers/common/meta_blit.c', - 'drivers/common/meta_generate_mipmap.c', - 'drivers/common/meta.c', - 'drivers/common/meta.h', - 'x86/x86_xform.c', - 'x86/3dnow.c', - 'x86/sse.c', - 'x86/rtasm/x86sse.c', - 'x86/rtasm/x86sse.h', - 'sparc/sparc.c', - 'x86-64/x86-64.c', -) - files_libmesa_gallium = files( 'state_tracker/st_atifs_to_nir.c', 'state_tracker/st_atifs_to_nir.h', @@ -612,44 +494,15 @@ inc_libmesa_asm = [] if with_asm_arch == 'x86' files_libmesa_common += files( 'x86/assyntax.h', - 'x86/clip_args.h', - 'x86/norm_args.h', - 'x86/xform_args.h', 'x86/common_x86_asm.S', 'x86/common_x86_asm.h', 'x86/common_x86_features.h', - 'x86/x86_xform.h', - 'x86/x86_xform2.S', - 'x86/x86_xform3.S', - 'x86/x86_xform4.S', - 'x86/x86_cliptest.S', - 'x86/mmx.h', - 'x86/mmx_blend.S', - 'x86/mmx_blendtmp.h', - 'x86/3dnow.h', - 'x86/3dnow_xform1.S', - 'x86/3dnow_xform2.S', - 'x86/3dnow_xform3.S', - 'x86/3dnow_xform4.S', - 'x86/sse.h', - 'x86/sse_xform1.S', - 'x86/sse_xform2.S', - 'x86/sse_xform3.S', - 'x86/sse_xform4.S', - 'x86/sse_normal.S', 'x86/read_rgba_span_x86.S', ) inc_libmesa_asm = include_directories('x86') elif with_asm_arch == 'x86_64' files_libmesa_common += files('x86-64/x86-64.h', 'x86-64/xform4.S') inc_libmesa_asm = include_directories('x86-64') -elif with_asm_arch == 'sparc' - files_libmesa_common += files( - 'sparc/sparc_clip.S', - 'sparc/norm.S', - 'sparc/xform.S', - ) - inc_libmesa_asm = include_directories('sparc') endif format_fallback_c = custom_target( @@ -733,18 +586,6 @@ libmesa_common = static_library( build_by_default : false, ) -libmesa_classic = static_library( - 'mesa_classic', - files_libmesa_classic, - c_args : [c_msvc_compat_args], - cpp_args : [cpp_msvc_compat_args], - gnu_symbol_visibility : 'hidden', - include_directories : [inc_include, inc_src, inc_mapi, inc_mesa, inc_gallium, inc_gallium_aux, inc_libmesa_asm, include_directories('main')], - link_with : [libmesa_common, libglsl, libmesa_sse41], - dependencies : [idep_nir_headers, idep_mesautil], - build_by_default : false, -) - libmesa_gallium = static_library( 'mesa_gallium', files_libmesa_gallium, diff --git a/src/mesa/sparc/norm.S b/src/mesa/sparc/norm.S deleted file mode 100644 index 0f12500..0000000 --- a/src/mesa/sparc/norm.S +++ /dev/null @@ -1,605 +0,0 @@ - -#include "sparc_matrix.h" - - .register %g2, #scratch - .register %g3, #scratch - - .text - -#ifdef __arch64__ -#define STACK_VAR_OFF (2047 + (8 * 16)) -#else -#define STACK_VAR_OFF (4 * 16) -#endif - - /* Newton-Raphson approximation turns out to be slower - * (and less accurate) than direct fsqrts/fdivs. - */ -#define ONE_DOT_ZERO 0x3f800000 - - .globl _mesa_sparc_transform_normalize_normals -_mesa_sparc_transform_normalize_normals: - /* o0=mat o1=scale o2=in o3=lengths o4=dest */ - - sethi %hi(ONE_DOT_ZERO), %g2 - sub %sp, 16, %sp - st %g2, [%sp + STACK_VAR_OFF+0x0] - st %o1, [%sp + STACK_VAR_OFF+0x4] - ld [%sp + STACK_VAR_OFF+0x0], %f12 ! f12 = 1.0f - ld [%sp + STACK_VAR_OFF+0x4], %f15 ! f15 = scale - add %sp, 16, %sp - - add %o0, MATRIX_INV, %o0 ! o0 = mat->inv - LDPTR [%o2 + V4F_START], %o5 ! o5 = 'from' in->start - ld [%o2 + V4F_COUNT], %g1 ! g1 = in->count - ld [%o2 + V4F_STRIDE], %g2 ! g2 = in->stride - LDPTR [%o4 + V4F_START], %g3 ! g3 = 'out' dest->start - - LDMATRIX_0_1_2_4_5_6_8_9_10(%o0) - - /* dest->count = in->count */ - st %g1, [%o4 + V4F_COUNT] - - cmp %g1, 1 - bl 7f - cmp %o3, 0 - bne 4f - clr %o4 ! 'i' for STRIDE_LOOP - -1: /* LENGTHS == NULL */ - ld [%o5 + 0x00], %f0 ! ux = from[0] - ld [%o5 + 0x04], %f1 ! uy = from[1] - ld [%o5 + 0x08], %f2 ! uz = from[2] - add %o5, %g2, %o5 ! STRIDE_F(from, stride) - add %o4, 1, %o4 ! i++ - - /* tx (f3) = (ux * m0) + (uy * m1) + (uz * m2) - * ty (f5) = (ux * m4) + (uy * m5) + (uz * m6) - * tz (f7) = (ux * m8) + (uy * m9) + (uz * m10) - */ - fmuls %f0, M0, %f3 ! FGM Group - fmuls %f1, M1, %f4 ! FGM Group - fmuls %f0, M4, %f5 ! FGM Group - fmuls %f1, M5, %f6 ! FGM Group - fmuls %f0, M8, %f7 ! FGM Group f3 available - fmuls %f1, M9, %f8 ! FGM Group f4 available - fadds %f3, %f4, %f3 ! FGA - fmuls %f2, M2, %f10 ! FGM Group f5 available - fmuls %f2, M6, %f0 ! FGM Group f6 available - fadds %f5, %f6, %f5 ! FGA - fmuls %f2, M10, %f4 ! FGM Group f7 available - fadds %f7, %f8, %f7 ! FGA Group f8,f3 available - fadds %f3, %f10, %f3 ! FGA Group f10 available - fadds %f5, %f0, %f5 ! FGA Group stall f0,f5 available - fadds %f7, %f4, %f7 ! FGA Group stall f4,f7 available - - /* f3=tx, f5=ty, f7=tz */ - - /* len (f6) = (tx * tx) + (ty * ty) + (tz * tz) */ - fmuls %f3, %f3, %f6 ! FGM Group f3 available - fmuls %f5, %f5, %f8 ! FGM Group f5 available - fmuls %f7, %f7, %f10 ! FGM Group f7 available - fadds %f6, %f8, %f6 ! FGA Group 2cyc stall f6,f8 available - fadds %f6, %f10, %f6 ! FGA Group 4cyc stall f6,f10 available - - /* scale (f6) = 1.0 / sqrt(len) */ - fsqrts %f6, %f6 ! FDIV 20 cycles - fdivs %f12, %f6, %f6 ! FDIV 14 cycles - - fmuls %f3, %f6, %f3 - st %f3, [%g3 + 0x00] ! out[i][0] = tx * scale - fmuls %f5, %f6, %f5 - st %f5, [%g3 + 0x04] ! out[i][1] = ty * scale - fmuls %f7, %f6, %f7 - st %f7, [%g3 + 0x08] ! out[i][2] = tz * scale - - cmp %o4, %g1 ! continue if (i < count) - bl 1b - add %g3, 0x10, %g3 ! advance out vector pointer - - ba 7f - nop - -4: /* LENGTHS != NULL */ - fmuls M0, %f15, M0 - fmuls M1, %f15, M1 - fmuls M2, %f15, M2 - fmuls M4, %f15, M4 - fmuls M5, %f15, M5 - fmuls M6, %f15, M6 - fmuls M8, %f15, M8 - fmuls M9, %f15, M9 - fmuls M10, %f15, M10 - -5: - ld [%o5 + 0x00], %f0 ! ux = from[0] - ld [%o5 + 0x04], %f1 ! uy = from[1] - ld [%o5 + 0x08], %f2 ! uz = from[2] - add %o5, %g2, %o5 ! STRIDE_F(from, stride) - add %o4, 1, %o4 ! i++ - - /* tx (f3) = (ux * m0) + (uy * m1) + (uz * m2) - * ty (f5) = (ux * m4) + (uy * m5) + (uz * m6) - * tz (f7) = (ux * m8) + (uy * m9) + (uz * m10) - */ - fmuls %f0, M0, %f3 ! FGM Group - fmuls %f1, M1, %f4 ! FGM Group - fmuls %f0, M4, %f5 ! FGM Group - fmuls %f1, M5, %f6 ! FGM Group - fmuls %f0, M8, %f7 ! FGM Group f3 available - fmuls %f1, M9, %f8 ! FGM Group f4 available - fadds %f3, %f4, %f3 ! FGA - fmuls %f2, M2, %f10 ! FGM Group f5 available - fmuls %f2, M6, %f0 ! FGM Group f6 available - fadds %f5, %f6, %f5 ! FGA - fmuls %f2, M10, %f4 ! FGM Group f7 available - fadds %f7, %f8, %f7 ! FGA Group f8,f3 available - fadds %f3, %f10, %f3 ! FGA Group f10 available - ld [%o3], %f13 ! LSU - fadds %f5, %f0, %f5 ! FGA Group stall f0,f5 available - add %o3, 4, %o3 ! IEU0 - fadds %f7, %f4, %f7 ! FGA Group stall f4,f7 available - - /* f3=tx, f5=ty, f7=tz, f13=lengths[i] */ - - fmuls %f3, %f13, %f3 - st %f3, [%g3 + 0x00] ! out[i][0] = tx * len - fmuls %f5, %f13, %f5 - st %f5, [%g3 + 0x04] ! out[i][1] = ty * len - fmuls %f7, %f13, %f7 - st %f7, [%g3 + 0x08] ! out[i][2] = tz * len - - cmp %o4, %g1 ! continue if (i < count) - bl 5b - add %g3, 0x10, %g3 ! advance out vector pointer - -7: retl - nop - - .globl _mesa_sparc_transform_normalize_normals_no_rot -_mesa_sparc_transform_normalize_normals_no_rot: - /* o0=mat o1=scale o2=in o3=lengths o4=dest */ - - sethi %hi(ONE_DOT_ZERO), %g2 - sub %sp, 16, %sp - st %g2, [%sp + STACK_VAR_OFF+0x0] - st %o1, [%sp + STACK_VAR_OFF+0x4] - ld [%sp + STACK_VAR_OFF+0x0], %f12 ! f12 = 1.0f - ld [%sp + STACK_VAR_OFF+0x4], %f15 ! f15 = scale - add %sp, 16, %sp - - add %o0, MATRIX_INV, %o0 ! o0 = mat->inv - LDPTR [%o2 + V4F_START], %o5 ! o5 = 'from' in->start - ld [%o2 + V4F_COUNT], %g1 ! g1 = in->count - ld [%o2 + V4F_STRIDE], %g2 ! g2 = in->stride - LDPTR [%o4 + V4F_START], %g3 ! g3 = 'out' dest->start - - LDMATRIX_0_5_10(%o0) - - /* dest->count = in->count */ - st %g1, [%o4 + V4F_COUNT] - - cmp %g1, 1 - bl 7f - cmp %o3, 0 - bne 4f - clr %o4 ! 'i' for STRIDE_LOOP - -1: /* LENGTHS == NULL */ - ld [%o5 + 0x00], %f0 ! ux = from[0] - ld [%o5 + 0x04], %f1 ! uy = from[1] - ld [%o5 + 0x08], %f2 ! uz = from[2] - add %o5, %g2, %o5 ! STRIDE_F(from, stride) - add %o4, 1, %o4 ! i++ - - /* tx (f3) = (ux * m0) - * ty (f5) = (uy * m5) - * tz (f7) = (uz * m10) - */ - fmuls %f0, M0, %f3 ! FGM Group - fmuls %f1, M5, %f5 ! FGM Group - fmuls %f2, M10, %f7 ! FGM Group - - /* f3=tx, f5=ty, f7=tz */ - - /* len (f6) = (tx * tx) + (ty * ty) + (tz * tz) */ - fmuls %f3, %f3, %f6 ! FGM Group stall, f3 available - fmuls %f5, %f5, %f8 ! FGM Group f5 available - fmuls %f7, %f7, %f10 ! FGM Group f7 available - fadds %f6, %f8, %f6 ! FGA Group 2cyc stall f6,f8 available - fadds %f6, %f10, %f6 ! FGA Group 4cyc stall f6,f10 available - - /* scale (f6) = 1.0 / sqrt(len) */ - fsqrts %f6, %f6 ! FDIV 20 cycles - fdivs %f12, %f6, %f6 ! FDIV 14 cycles - - fmuls %f3, %f6, %f3 - st %f3, [%g3 + 0x00] ! out[i][0] = tx * scale - fmuls %f5, %f6, %f5 - st %f5, [%g3 + 0x04] ! out[i][1] = ty * scale - fmuls %f7, %f6, %f7 - st %f7, [%g3 + 0x08] ! out[i][2] = tz * scale - - cmp %o4, %g1 ! continue if (i < count) - bl 1b - add %g3, 0x10, %g3 ! advance out vector pointer - - ba 7f - nop - -4: /* LENGTHS != NULL */ - fmuls M0, %f15, M0 - fmuls M5, %f15, M5 - fmuls M10, %f15, M10 - -5: - ld [%o5 + 0x00], %f0 ! ux = from[0] - ld [%o5 + 0x04], %f1 ! uy = from[1] - ld [%o5 + 0x08], %f2 ! uz = from[2] - add %o5, %g2, %o5 ! STRIDE_F(from, stride) - add %o4, 1, %o4 ! i++ - - /* tx (f3) = (ux * m0) - * ty (f5) = (uy * m5) - * tz (f7) = (uz * m10) - */ - fmuls %f0, M0, %f3 ! FGM Group - ld [%o3], %f13 ! LSU - fmuls %f1, M5, %f5 ! FGM Group - add %o3, 4, %o3 ! IEU0 - fmuls %f2, M10, %f7 ! FGM Group - - /* f3=tx, f5=ty, f7=tz, f13=lengths[i] */ - - fmuls %f3, %f13, %f3 - st %f3, [%g3 + 0x00] ! out[i][0] = tx * len - fmuls %f5, %f13, %f5 - st %f5, [%g3 + 0x04] ! out[i][1] = ty * len - fmuls %f7, %f13, %f7 - st %f7, [%g3 + 0x08] ! out[i][2] = tz * len - - cmp %o4, %g1 ! continue if (i < count) - bl 5b - add %g3, 0x10, %g3 ! advance out vector pointer - -7: retl - nop - - .globl _mesa_sparc_transform_rescale_normals_no_rot -_mesa_sparc_transform_rescale_normals_no_rot: - /* o0=mat o1=scale o2=in o3=lengths o4=dest */ - sub %sp, 16, %sp - st %o1, [%sp + STACK_VAR_OFF+0x0] - ld [%sp + STACK_VAR_OFF+0x0], %f15 ! f15 = scale - add %sp, 16, %sp - - add %o0, MATRIX_INV, %o0 ! o0 = mat->inv - LDPTR [%o2 + V4F_START], %o5 ! o5 = 'from' in->start - ld [%o2 + V4F_COUNT], %g1 ! g1 = in->count - ld [%o2 + V4F_STRIDE], %g2 ! g2 = in->stride - LDPTR [%o4 + V4F_START], %g3 ! g3 = 'out' dest->start - - LDMATRIX_0_5_10(%o0) - - /* dest->count = in->count */ - st %g1, [%o4 + V4F_COUNT] - - cmp %g1, 1 - bl 7f - clr %o4 ! 'i' for STRIDE_LOOP - - fmuls M0, %f15, M0 - fmuls M5, %f15, M5 - fmuls M10, %f15, M10 - -1: ld [%o5 + 0x00], %f0 ! ux = from[0] - ld [%o5 + 0x04], %f1 ! uy = from[1] - ld [%o5 + 0x08], %f2 ! uz = from[2] - add %o5, %g2, %o5 ! STRIDE_F(from, stride) - add %o4, 1, %o4 ! i++ - - /* tx (f3) = (ux * m0) - * ty (f5) = (uy * m5) - * tz (f7) = (uz * m10) - */ - fmuls %f0, M0, %f3 ! FGM Group - st %f3, [%g3 + 0x00] ! LSU - fmuls %f1, M5, %f5 ! FGM Group - st %f5, [%g3 + 0x04] ! LSU - fmuls %f2, M10, %f7 ! FGM Group - st %f7, [%g3 + 0x08] ! LSU - - cmp %o4, %g1 ! continue if (i < count) - bl 1b - add %g3, 0x10, %g3 ! advance out vector pointer - -7: retl - nop - - .globl _mesa_sparc_transform_rescale_normals -_mesa_sparc_transform_rescale_normals: - /* o0=mat o1=scale o2=in o3=lengths o4=dest */ - sub %sp, 16, %sp - st %o1, [%sp + STACK_VAR_OFF+0x0] - ld [%sp + STACK_VAR_OFF+0x0], %f15 ! f15 = scale - add %sp, 16, %sp - - add %o0, MATRIX_INV, %o0 ! o0 = mat->inv - LDPTR [%o2 + V4F_START], %o5 ! o5 = 'from' in->start - ld [%o2 + V4F_COUNT], %g1 ! g1 = in->count - ld [%o2 + V4F_STRIDE], %g2 ! g2 = in->stride - LDPTR [%o4 + V4F_START], %g3 ! g3 = 'out' dest->start - - LDMATRIX_0_1_2_4_5_6_8_9_10(%o0) - - /* dest->count = in->count */ - st %g1, [%o4 + V4F_COUNT] - - cmp %g1, 1 - bl 7f - clr %o4 ! 'i' for STRIDE_LOOP - - fmuls M0, %f15, M0 - fmuls M1, %f15, M1 - fmuls M2, %f15, M2 - fmuls M4, %f15, M4 - fmuls M5, %f15, M5 - fmuls M6, %f15, M6 - fmuls M8, %f15, M8 - fmuls M9, %f15, M9 - fmuls M10, %f15, M10 - -1: ld [%o5 + 0x00], %f0 ! ux = from[0] - ld [%o5 + 0x04], %f1 ! uy = from[1] - ld [%o5 + 0x08], %f2 ! uz = from[2] - add %o5, %g2, %o5 ! STRIDE_F(from, stride) - add %o4, 1, %o4 ! i++ - - fmuls %f0, M0, %f3 ! FGM Group - fmuls %f1, M1, %f4 ! FGM Group - fmuls %f0, M4, %f5 ! FGM Group - fmuls %f1, M5, %f6 ! FGM Group - fmuls %f0, M8, %f7 ! FGM Group f3 available - fmuls %f1, M9, %f8 ! FGM Group f4 available - fadds %f3, %f4, %f3 ! FGA - fmuls %f2, M2, %f10 ! FGM Group f5 available - fmuls %f2, M6, %f0 ! FGM Group f6 available - fadds %f5, %f6, %f5 ! FGA - fmuls %f2, M10, %f4 ! FGM Group f7 available - fadds %f7, %f8, %f7 ! FGA Group f8,f3 available - fadds %f3, %f10, %f3 ! FGA Group f10 available - st %f3, [%g3 + 0x00] ! LSU - fadds %f5, %f0, %f5 ! FGA Group stall f0,f5 available - st %f5, [%g3 + 0x04] ! LSU - fadds %f7, %f4, %f7 ! FGA Group stall f4,f7 available - st %f7, [%g3 + 0x08] ! LSU - - cmp %o4, %g1 ! continue if (i < count) - bl 1b - add %g3, 0x10, %g3 ! advance out vector pointer - -7: retl - nop - - .globl _mesa_sparc_transform_normals_no_rot -_mesa_sparc_transform_normals_no_rot: - /* o0=mat o1=scale o2=in o3=lengths o4=dest */ - add %o0, MATRIX_INV, %o0 ! o0 = mat->inv - LDPTR [%o2 + V4F_START], %o5 ! o5 = 'from' in->start - ld [%o2 + V4F_COUNT], %g1 ! g1 = in->count - ld [%o2 + V4F_STRIDE], %g2 ! g2 = in->stride - LDPTR [%o4 + V4F_START], %g3 ! g3 = 'out' dest->start - - LDMATRIX_0_5_10(%o0) - - /* dest->count = in->count */ - st %g1, [%o4 + V4F_COUNT] - - cmp %g1, 1 - bl 7f - clr %o4 ! 'i' for STRIDE_LOOP - -1: ld [%o5 + 0x00], %f0 ! ux = from[0] - ld [%o5 + 0x04], %f1 ! uy = from[1] - ld [%o5 + 0x08], %f2 ! uz = from[2] - add %o5, %g2, %o5 ! STRIDE_F(from, stride) - add %o4, 1, %o4 ! i++ - - /* tx (f3) = (ux * m0) - * ty (f5) = (uy * m5) - * tz (f7) = (uz * m10) - */ - fmuls %f0, M0, %f3 ! FGM Group - st %f3, [%g3 + 0x00] ! LSU - fmuls %f1, M5, %f5 ! FGM Group - st %f5, [%g3 + 0x04] ! LSU - fmuls %f2, M10, %f7 ! FGM Group - st %f7, [%g3 + 0x08] ! LSU - - cmp %o4, %g1 ! continue if (i < count) - bl 1b - add %g3, 0x10, %g3 ! advance out vector pointer - -7: retl - nop - - .globl _mesa_sparc_transform_normals -_mesa_sparc_transform_normals: - /* o0=mat o1=scale o2=in o3=lengths o4=dest */ - add %o0, MATRIX_INV, %o0 ! o0 = mat->inv - LDPTR [%o2 + V4F_START], %o5 ! o5 = 'from' in->start - ld [%o2 + V4F_COUNT], %g1 ! g1 = in->count - ld [%o2 + V4F_STRIDE], %g2 ! g2 = in->stride - LDPTR [%o4 + V4F_START], %g3 ! g3 = 'out' dest->start - - LDMATRIX_0_1_2_4_5_6_8_9_10(%o0) - - /* dest->count = in->count */ - st %g1, [%o4 + V4F_COUNT] - - cmp %g1, 1 - bl 7f - clr %o4 ! 'i' for STRIDE_LOOP - -1: ld [%o5 + 0x00], %f0 ! ux = from[0] - ld [%o5 + 0x04], %f1 ! uy = from[1] - ld [%o5 + 0x08], %f2 ! uz = from[2] - add %o5, %g2, %o5 ! STRIDE_F(from, stride) - add %o4, 1, %o4 ! i++ - - fmuls %f0, M0, %f3 ! FGM Group - fmuls %f1, M1, %f4 ! FGM Group - fmuls %f0, M4, %f5 ! FGM Group - fmuls %f1, M5, %f6 ! FGM Group - fmuls %f0, M8, %f7 ! FGM Group f3 available - fmuls %f1, M9, %f8 ! FGM Group f4 available - fadds %f3, %f4, %f3 ! FGA - fmuls %f2, M2, %f10 ! FGM Group f5 available - fmuls %f2, M6, %f0 ! FGM Group f6 available - fadds %f5, %f6, %f5 ! FGA - fmuls %f2, M10, %f4 ! FGM Group f7 available - fadds %f7, %f8, %f7 ! FGA Group f8,f3 available - fadds %f3, %f10, %f3 ! FGA Group f10 available - st %f3, [%g3 + 0x00] ! LSU - fadds %f5, %f0, %f5 ! FGA Group stall f0,f5 available - st %f5, [%g3 + 0x04] ! LSU - fadds %f7, %f4, %f7 ! FGA Group stall f4,f7 available - st %f7, [%g3 + 0x08] ! LSU - - cmp %o4, %g1 ! continue if (i < count) - bl 1b - add %g3, 0x10, %g3 ! advance out vector pointer - -7: retl - nop - - .globl _mesa_sparc_normalize_normals -_mesa_sparc_normalize_normals: - /* o0=mat o1=scale o2=in o3=lengths o4=dest */ - - sethi %hi(ONE_DOT_ZERO), %g2 - sub %sp, 16, %sp - st %g2, [%sp + STACK_VAR_OFF+0x0] - ld [%sp + STACK_VAR_OFF+0x0], %f12 ! f12 = 1.0f - add %sp, 16, %sp - - LDPTR [%o2 + V4F_START], %o5 ! o5 = 'from' in->start - ld [%o2 + V4F_COUNT], %g1 ! g1 = in->count - ld [%o2 + V4F_STRIDE], %g2 ! g2 = in->stride - LDPTR [%o4 + V4F_START], %g3 ! g3 = 'out' dest->start - - /* dest->count = in->count */ - st %g1, [%o4 + V4F_COUNT] - - cmp %g1, 1 - bl 7f - cmp %o3, 0 - bne 4f - clr %o4 ! 'i' for STRIDE_LOOP - -1: /* LENGTHS == NULL */ - ld [%o5 + 0x00], %f3 ! ux = from[0] - ld [%o5 + 0x04], %f5 ! uy = from[1] - ld [%o5 + 0x08], %f7 ! uz = from[2] - add %o5, %g2, %o5 ! STRIDE_F(from, stride) - add %o4, 1, %o4 ! i++ - - /* f3=tx, f5=ty, f7=tz */ - - /* len (f6) = (tx * tx) + (ty * ty) + (tz * tz) */ - fmuls %f3, %f3, %f6 ! FGM Group f3 available - fmuls %f5, %f5, %f8 ! FGM Group f5 available - fmuls %f7, %f7, %f10 ! FGM Group f7 available - fadds %f6, %f8, %f6 ! FGA Group 2cyc stall f6,f8 available - fadds %f6, %f10, %f6 ! FGA Group 4cyc stall f6,f10 available - - /* scale (f6) = 1.0 / sqrt(len) */ - fsqrts %f6, %f6 ! FDIV 20 cycles - fdivs %f12, %f6, %f6 ! FDIV 14 cycles - - fmuls %f3, %f6, %f3 - st %f3, [%g3 + 0x00] ! out[i][0] = tx * scale - fmuls %f5, %f6, %f5 - st %f5, [%g3 + 0x04] ! out[i][1] = ty * scale - fmuls %f7, %f6, %f7 - st %f7, [%g3 + 0x08] ! out[i][2] = tz * scale - - cmp %o4, %g1 ! continue if (i < count) - bl 1b - add %g3, 0x10, %g3 ! advance out vector pointer - - ba 7f - nop - -4: /* LENGTHS != NULL */ - -5: - ld [%o5 + 0x00], %f3 ! ux = from[0] - ld [%o5 + 0x04], %f5 ! uy = from[1] - ld [%o5 + 0x08], %f7 ! uz = from[2] - add %o5, %g2, %o5 ! STRIDE_F(from, stride) - add %o4, 1, %o4 ! i++ - - ld [%o3], %f13 ! LSU - add %o3, 4, %o3 ! IEU0 - - /* f3=tx, f5=ty, f7=tz, f13=lengths[i] */ - - fmuls %f3, %f13, %f3 - st %f3, [%g3 + 0x00] ! out[i][0] = tx * len - fmuls %f5, %f13, %f5 - st %f5, [%g3 + 0x04] ! out[i][1] = ty * len - fmuls %f7, %f13, %f7 - st %f7, [%g3 + 0x08] ! out[i][2] = tz * len - - cmp %o4, %g1 ! continue if (i < count) - bl 5b - add %g3, 0x10, %g3 ! advance out vector pointer - -7: retl - nop - - .globl _mesa_sparc_rescale_normals -_mesa_sparc_rescale_normals: - /* o0=mat o1=scale o2=in o3=lengths o4=dest */ - - sethi %hi(ONE_DOT_ZERO), %g2 - sub %sp, 16, %sp - st %o1, [%sp + STACK_VAR_OFF+0x0] - ld [%sp + STACK_VAR_OFF+0x0], %f15 ! f15 = scale - add %sp, 16, %sp - - LDPTR [%o2 + V4F_START], %o5 ! o5 = 'from' in->start - ld [%o2 + V4F_COUNT], %g1 ! g1 = in->count - ld [%o2 + V4F_STRIDE], %g2 ! g2 = in->stride - LDPTR [%o4 + V4F_START], %g3 ! g3 = 'out' dest->start - - /* dest->count = in->count */ - st %g1, [%o4 + V4F_COUNT] - - cmp %g1, 1 - bl 7f - clr %o4 ! 'i' for STRIDE_LOOP - -1: - ld [%o5 + 0x00], %f3 ! ux = from[0] - ld [%o5 + 0x04], %f5 ! uy = from[1] - ld [%o5 + 0x08], %f7 ! uz = from[2] - add %o5, %g2, %o5 ! STRIDE_F(from, stride) - add %o4, 1, %o4 ! i++ - - /* f3=tx, f5=ty, f7=tz */ - - fmuls %f3, %f15, %f3 - st %f3, [%g3 + 0x00] ! out[i][0] = tx * scale - fmuls %f5, %f15, %f5 - st %f5, [%g3 + 0x04] ! out[i][1] = ty * scale - fmuls %f7, %f15, %f7 - st %f7, [%g3 + 0x08] ! out[i][2] = tz * scale - - cmp %o4, %g1 ! continue if (i < count) - bl 1b - add %g3, 0x10, %g3 ! advance out vector pointer - -7: retl - nop diff --git a/src/mesa/sparc/sparc.c b/src/mesa/sparc/sparc.c deleted file mode 100644 index 8d0509c..0000000 --- a/src/mesa/sparc/sparc.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2003 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -/* - * Sparc assembly code by David S. Miller - */ - - -#include "sparc.h" - -#ifdef USE_SPARC_ASM - -#include "main/context.h" -#include "math/m_xform.h" -#include "tnl/t_context.h" - -#ifdef DEBUG -#include "math/m_debug.h" -#endif - -#define XFORM_ARGS GLvector4f *to_vec, \ - const GLfloat m[16], \ - const GLvector4f *from_vec - -#define DECLARE_XFORM_GROUP(pfx, sz) \ - extern void _mesa_##pfx##_transform_points##sz##_general(XFORM_ARGS); \ - extern void _mesa_##pfx##_transform_points##sz##_identity(XFORM_ARGS); \ - extern void _mesa_##pfx##_transform_points##sz##_3d_no_rot(XFORM_ARGS); \ - extern void _mesa_##pfx##_transform_points##sz##_perspective(XFORM_ARGS); \ - extern void _mesa_##pfx##_transform_points##sz##_2d(XFORM_ARGS); \ - extern void _mesa_##pfx##_transform_points##sz##_2d_no_rot(XFORM_ARGS); \ - extern void _mesa_##pfx##_transform_points##sz##_3d(XFORM_ARGS); - -#define ASSIGN_XFORM_GROUP(pfx, sz) \ - _mesa_transform_tab[sz][MATRIX_GENERAL] = \ - _mesa_##pfx##_transform_points##sz##_general; \ - _mesa_transform_tab[sz][MATRIX_IDENTITY] = \ - _mesa_##pfx##_transform_points##sz##_identity; \ - _mesa_transform_tab[sz][MATRIX_3D_NO_ROT] = \ - _mesa_##pfx##_transform_points##sz##_3d_no_rot; \ - _mesa_transform_tab[sz][MATRIX_PERSPECTIVE] = \ - _mesa_##pfx##_transform_points##sz##_perspective; \ - _mesa_transform_tab[sz][MATRIX_2D] = \ - _mesa_##pfx##_transform_points##sz##_2d; \ - _mesa_transform_tab[sz][MATRIX_2D_NO_ROT] = \ - _mesa_##pfx##_transform_points##sz##_2d_no_rot; \ - _mesa_transform_tab[sz][MATRIX_3D] = \ - _mesa_##pfx##_transform_points##sz##_3d; - - -DECLARE_XFORM_GROUP(sparc, 1) -DECLARE_XFORM_GROUP(sparc, 2) -DECLARE_XFORM_GROUP(sparc, 3) -DECLARE_XFORM_GROUP(sparc, 4) - -extern GLvector4f *_mesa_sparc_cliptest_points4(GLvector4f *clip_vec, - GLvector4f *proj_vec, - GLubyte clipMask[], - GLubyte *orMask, - GLubyte *andMask, - GLboolean viewport_z_clip); - -extern GLvector4f *_mesa_sparc_cliptest_points4_np(GLvector4f *clip_vec, - GLvector4f *proj_vec, - GLubyte clipMask[], - GLubyte *orMask, - GLubyte *andMask, - GLboolean viewport_z_clip); - -#define NORM_ARGS const GLmatrix *mat, \ - GLfloat scale, \ - const GLvector4f *in, \ - const GLfloat *lengths, \ - GLvector4f *dest - -extern void _mesa_sparc_transform_normalize_normals(NORM_ARGS); -extern void _mesa_sparc_transform_normalize_normals_no_rot(NORM_ARGS); -extern void _mesa_sparc_transform_rescale_normals_no_rot(NORM_ARGS); -extern void _mesa_sparc_transform_rescale_normals(NORM_ARGS); -extern void _mesa_sparc_transform_normals_no_rot(NORM_ARGS); -extern void _mesa_sparc_transform_normals(NORM_ARGS); -extern void _mesa_sparc_normalize_normals(NORM_ARGS); -extern void _mesa_sparc_rescale_normals(NORM_ARGS); - - - -void _mesa_init_all_sparc_transform_asm(void) -{ - ASSIGN_XFORM_GROUP(sparc, 1) - ASSIGN_XFORM_GROUP(sparc, 2) - ASSIGN_XFORM_GROUP(sparc, 3) - ASSIGN_XFORM_GROUP(sparc, 4) - - _mesa_clip_tab[4] = _mesa_sparc_cliptest_points4; - _mesa_clip_np_tab[4] = _mesa_sparc_cliptest_points4_np; - - _mesa_normal_tab[NORM_TRANSFORM | NORM_NORMALIZE] = - _mesa_sparc_transform_normalize_normals; - _mesa_normal_tab[NORM_TRANSFORM_NO_ROT | NORM_NORMALIZE] = - _mesa_sparc_transform_normalize_normals_no_rot; - _mesa_normal_tab[NORM_TRANSFORM_NO_ROT | NORM_RESCALE] = - _mesa_sparc_transform_rescale_normals_no_rot; - _mesa_normal_tab[NORM_TRANSFORM | NORM_RESCALE] = - _mesa_sparc_transform_rescale_normals; - _mesa_normal_tab[NORM_TRANSFORM_NO_ROT] = - _mesa_sparc_transform_normals_no_rot; - _mesa_normal_tab[NORM_TRANSFORM] = - _mesa_sparc_transform_normals; - _mesa_normal_tab[NORM_NORMALIZE] = - _mesa_sparc_normalize_normals; - _mesa_normal_tab[NORM_RESCALE] = - _mesa_sparc_rescale_normals; - -#ifdef DEBUG_MATH - _math_test_all_transform_functions("sparc"); - _math_test_all_cliptest_functions("sparc"); - _math_test_all_normal_transform_functions("sparc"); -#endif -} - -#endif /* USE_SPARC_ASM */ diff --git a/src/mesa/sparc/sparc.h b/src/mesa/sparc/sparc.h deleted file mode 100644 index 1b3340f..0000000 --- a/src/mesa/sparc/sparc.h +++ /dev/null @@ -1,36 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -/* - * Sparc assembly code by David S. Miller - */ - - -#ifndef SPARC_H -#define SPARC_H - -extern void _mesa_init_all_sparc_transform_asm(void); - -#endif /* !(SPARC_H) */ diff --git a/src/mesa/sparc/sparc_clip.S b/src/mesa/sparc/sparc_clip.S deleted file mode 100644 index a034acb..0000000 --- a/src/mesa/sparc/sparc_clip.S +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Clip testing in SPARC assembly - */ - -#if __arch64__ -#define LDPTR ldx -#define MATH_ASM_PTR_SIZE 8 -#include "math/m_vector_asm.h" -#else -#define LDPTR ld -#define MATH_ASM_PTR_SIZE 4 -#include "math/m_vector_asm.h" -#endif - - .register %g2, #scratch - .register %g3, #scratch - - .text - .align 64 - -one_dot_zero: - .word 0x3f800000 /* 1.0f */ - - /* This trick is shamelessly stolen from the x86 - * Mesa asm. Very clever, and we can do it too - * since we have the necessary add with carry - * instructions on Sparc. - */ -clip_table: - .byte 0, 1, 0, 2, 4, 5, 4, 6 - .byte 0, 1, 0, 2, 8, 9, 8, 10 - .byte 32, 33, 32, 34, 36, 37, 36, 38 - .byte 32, 33, 32, 34, 40, 41, 40, 42 - .byte 0, 1, 0, 2, 4, 5, 4, 6 - .byte 0, 1, 0, 2, 8, 9, 8, 10 - .byte 16, 17, 16, 18, 20, 21, 20, 22 - .byte 16, 17, 16, 18, 24, 25, 24, 26 - .byte 63, 61, 63, 62, 55, 53, 55, 54 - .byte 63, 61, 63, 62, 59, 57, 59, 58 - .byte 47, 45, 47, 46, 39, 37, 39, 38 - .byte 47, 45, 47, 46, 43, 41, 43, 42 - .byte 63, 61, 63, 62, 55, 53, 55, 54 - .byte 63, 61, 63, 62, 59, 57, 59, 58 - .byte 31, 29, 31, 30, 23, 21, 23, 22 - .byte 31, 29, 31, 30, 27, 25, 27, 26 - -/* GLvector4f *clip_vec, GLvector4f *proj_vec, - GLubyte clipMask[], GLubyte *orMask, GLubyte *andMask, - GLboolean viewport_z_enable */ - - .align 64 -__pc_tramp: - retl - nop - - .globl _mesa_sparc_cliptest_points4 -_mesa_sparc_cliptest_points4: - save %sp, -64, %sp - call __pc_tramp - sub %o7, (. - one_dot_zero - 4), %g1 - ld [%g1 + 0x0], %f4 - add %g1, 0x4, %g1 - - ld [%i0 + V4F_STRIDE], %l1 - ld [%i0 + V4F_COUNT], %l3 - LDPTR [%i0 + V4F_START], %i0 - LDPTR [%i1 + V4F_START], %i5 - ldub [%i3], %g2 - ldub [%i4], %g3 - sll %g3, 8, %g3 - or %g2, %g3, %g2 - - ld [%i1 + V4F_FLAGS], %g3 - or %g3, VEC_SIZE_4, %g3 - st %g3, [%i1 + V4F_FLAGS] - mov 3, %g3 - st %g3, [%i1 + V4F_SIZE] - st %l3, [%i1 + V4F_COUNT] - clr %l2 - clr %l0 - - /* l0: i - * l3: count - * l1: stride - * l2: c - * g2: (tmpAndMask << 8) | tmpOrMask - * g1: clip_table - * i0: from[stride][i] - * i2: clipMask - * i5: vProj[4][i] - */ - -1: ld [%i0 + 0x0c], %f3 ! LSU Group - ld [%i0 + 0x0c], %g5 ! LSU Group - ld [%i0 + 0x08], %g4 ! LSU Group - fdivs %f4, %f3, %f8 ! FGM - addcc %g5, %g5, %g5 ! IEU1 Group - addx %g0, 0x0, %g3 ! IEU1 Group - addcc %g4, %g4, %g4 ! IEU1 Group - addx %g3, %g3, %g3 ! IEU1 Group - subcc %g5, %g4, %g0 ! IEU1 Group - ld [%i0 + 0x04], %g4 ! LSU Group - addx %g3, %g3, %g3 ! IEU1 Group - addcc %g4, %g4, %g4 ! IEU1 Group - addx %g3, %g3, %g3 ! IEU1 Group - subcc %g5, %g4, %g0 ! IEU1 Group - ld [%i0 + 0x00], %g4 ! LSU Group - addx %g3, %g3, %g3 ! IEU1 Group - addcc %g4, %g4, %g4 ! IEU1 Group - addx %g3, %g3, %g3 ! IEU1 Group - subcc %g5, %g4, %g0 ! IEU1 Group - addx %g3, %g3, %g3 ! IEU1 Group - ldub [%g1 + %g3], %g3 ! LSU Group - cmp %g3, 0 ! IEU1 Group, stall - be 2f ! CTI - stb %g3, [%i2] ! LSU - sll %g3, 8, %g4 ! IEU1 Group - add %l2, 1, %l2 ! IEU0 - st %g0, [%i5 + 0x00] ! LSU - or %g4, 0xff, %g4 ! IEU0 Group - or %g2, %g3, %g2 ! IEU1 - st %g0, [%i5 + 0x04] ! LSU - and %g2, %g4, %g2 ! IEU0 Group - st %g0, [%i5 + 0x08] ! LSU - b 3f ! CTI - st %f4, [%i5 + 0x0c] ! LSU Group -2: ld [%i0 + 0x00], %f0 ! LSU Group - ld [%i0 + 0x04], %f1 ! LSU Group - ld [%i0 + 0x08], %f2 ! LSU Group - fmuls %f0, %f8, %f0 ! FGM - st %f0, [%i5 + 0x00] ! LSU Group - fmuls %f1, %f8, %f1 ! FGM - st %f1, [%i5 + 0x04] ! LSU Group - fmuls %f2, %f8, %f2 ! FGM - st %f2, [%i5 + 0x08] ! LSU Group - st %f8, [%i5 + 0x0c] ! LSU Group -3: add %i5, 0x10, %i5 ! IEU1 - add %l0, 1, %l0 ! IEU0 Group - add %i2, 1, %i2 ! IEU0 Group - cmp %l0, %l3 ! IEU1 Group - bne 1b ! CTI - add %i0, %l1, %i0 ! IEU0 Group - stb %g2, [%i3] ! LSU - srl %g2, 8, %g3 ! IEU0 Group - cmp %l2, %l3 ! IEU1 Group - bl,a 1f ! CTI - clr %g3 ! IEU0 -1: stb %g3, [%i4] ! LSU Group - ret ! CTI Group - restore %i1, 0x0, %o0 - - .globl _mesa_sparc_cliptest_points4_np -_mesa_sparc_cliptest_points4_np: - save %sp, -64, %sp - - call __pc_tramp - sub %o7, (. - one_dot_zero - 4), %g1 - add %g1, 0x4, %g1 - - ld [%i0 + V4F_STRIDE], %l1 - ld [%i0 + V4F_COUNT], %l3 - LDPTR [%i0 + V4F_START], %i0 - ldub [%i3], %g2 - ldub [%i4], %g3 - sll %g3, 8, %g3 - or %g2, %g3, %g2 - - clr %l2 - clr %l0 - - /* l0: i - * l3: count - * l1: stride - * l2: c - * g2: (tmpAndMask << 8) | tmpOrMask - * g1: clip_table - * i0: from[stride][i] - * i2: clipMask - */ - -1: ld [%i0 + 0x0c], %g5 ! LSU Group - ld [%i0 + 0x08], %g4 ! LSU Group - addcc %g5, %g5, %g5 ! IEU1 Group - addx %g0, 0x0, %g3 ! IEU1 Group - addcc %g4, %g4, %g4 ! IEU1 Group - addx %g3, %g3, %g3 ! IEU1 Group - subcc %g5, %g4, %g0 ! IEU1 Group - ld [%i0 + 0x04], %g4 ! LSU Group - addx %g3, %g3, %g3 ! IEU1 Group - addcc %g4, %g4, %g4 ! IEU1 Group - addx %g3, %g3, %g3 ! IEU1 Group - subcc %g5, %g4, %g0 ! IEU1 Group - ld [%i0 + 0x00], %g4 ! LSU Group - addx %g3, %g3, %g3 ! IEU1 Group - addcc %g4, %g4, %g4 ! IEU1 Group - addx %g3, %g3, %g3 ! IEU1 Group - subcc %g5, %g4, %g0 ! IEU1 Group - addx %g3, %g3, %g3 ! IEU1 Group - ldub [%g1 + %g3], %g3 ! LSU Group - cmp %g3, 0 ! IEU1 Group, stall - be 2f ! CTI - stb %g3, [%i2] ! LSU - sll %g3, 8, %g4 ! IEU1 Group - add %l2, 1, %l2 ! IEU0 - or %g4, 0xff, %g4 ! IEU0 Group - or %g2, %g3, %g2 ! IEU1 - and %g2, %g4, %g2 ! IEU0 Group -2: add %l0, 1, %l0 ! IEU0 Group - add %i2, 1, %i2 ! IEU0 Group - cmp %l0, %l3 ! IEU1 Group - bne 1b ! CTI - add %i0, %l1, %i0 ! IEU0 Group - stb %g2, [%i3] ! LSU - srl %g2, 8, %g3 ! IEU0 Group - cmp %l2, %l3 ! IEU1 Group - bl,a 1f ! CTI - clr %g3 ! IEU0 -1: stb %g3, [%i4] ! LSU Group - ret ! CTI Group - restore %i1, 0x0, %o0 diff --git a/src/mesa/sparc/sparc_matrix.h b/src/mesa/sparc/sparc_matrix.h deleted file mode 100644 index 41f59bb..0000000 --- a/src/mesa/sparc/sparc_matrix.h +++ /dev/null @@ -1,153 +0,0 @@ -/* - * SPARC assembly matrix code. - */ - -#ifndef _SPARC_MATRIX_H -#define _SPARC_MATRIX_H - -#ifdef __arch64__ -#define LDPTR ldx -#define MATH_ASM_PTR_SIZE 8 -#include "math/m_vector_asm.h" -#else -#define LDPTR ld -#define MATH_ASM_PTR_SIZE 4 -#include "math/m_vector_asm.h" -#endif - -#define M0 %f16 -#define M1 %f17 -#define M2 %f18 -#define M3 %f19 -#define M4 %f20 -#define M5 %f21 -#define M6 %f22 -#define M7 %f23 -#define M8 %f24 -#define M9 %f25 -#define M10 %f26 -#define M11 %f27 -#define M12 %f28 -#define M13 %f29 -#define M14 %f30 -#define M15 %f31 - -#define LDMATRIX_0_1_2_3_12_13_14_15(BASE) \ - ldd [BASE + ( 0 * 0x4)], M0; \ - ldd [BASE + ( 2 * 0x4)], M2; \ - ldd [BASE + (12 * 0x4)], M12; \ - ldd [BASE + (14 * 0x4)], M14 - -#define LDMATRIX_0_1_12_13(BASE) \ - ldd [BASE + ( 0 * 0x4)], M0; \ - ldd [BASE + (12 * 0x4)], M12 - -#define LDMATRIX_0_12_13(BASE) \ - ld [BASE + ( 0 * 0x4)], M0; \ - ldd [BASE + (12 * 0x4)], M12 - -#define LDMATRIX_0_1_2_12_13_14(BASE) \ - ldd [BASE + ( 0 * 0x4)], M0; \ - ld [BASE + ( 2 * 0x4)], M2; \ - ldd [BASE + (12 * 0x4)], M12; \ - ld [BASE + (14 * 0x4)], M14 - -#define LDMATRIX_0_12_13_14(BASE) \ - ld [BASE + ( 0 * 0x4)], M0; \ - ldd [BASE + (12 * 0x4)], M12; \ - ld [BASE + (14 * 0x4)], M14 - -#define LDMATRIX_0_14(BASE) \ - ld [BASE + ( 0 * 0x4)], M0; \ - ld [BASE + (14 * 0x4)], M14 - -#define LDMATRIX_0_1_2_3_4_5_6_7_12_13_14_15(BASE) \ - ldd [BASE + ( 0 * 0x4)], M0; \ - ldd [BASE + ( 2 * 0x4)], M2; \ - ldd [BASE + ( 4 * 0x4)], M4; \ - ldd [BASE + ( 6 * 0x4)], M6; \ - ldd [BASE + (12 * 0x4)], M12; \ - ldd [BASE + (14 * 0x4)], M14 - -#define LDMATRIX_0_5_12_13(BASE) \ - ld [BASE + ( 0 * 0x4)], M0; \ - ld [BASE + ( 5 * 0x4)], M5; \ - ldd [BASE + (12 * 0x4)], M12 - -#define LDMATRIX_0_1_2_3_4_5_6_12_13_14(BASE) \ - ldd [BASE + ( 0 * 0x4)], M0; \ - ldd [BASE + ( 2 * 0x4)], M2; \ - ldd [BASE + ( 4 * 0x4)], M4; \ - ld [BASE + ( 6 * 0x4)], M6; \ - ldd [BASE + (12 * 0x4)], M12; \ - ld [BASE + (14 * 0x4)], M14 - -#define LDMATRIX_0_5_12_13_14(BASE) \ - ld [BASE + ( 0 * 0x4)], M0; \ - ld [BASE + ( 5 * 0x4)], M5; \ - ldd [BASE + (12 * 0x4)], M12; \ - ld [BASE + (14 * 0x4)], M14 - -#define LDMATRIX_0_5_14(BASE) \ - ld [BASE + ( 0 * 0x4)], M0; \ - ld [BASE + ( 5 * 0x4)], M5; \ - ld [BASE + (14 * 0x4)], M14 - -#define LDMATRIX_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15(BASE) \ - ldd [BASE + ( 0 * 0x4)], M0; \ - ldd [BASE + ( 2 * 0x4)], M2; \ - ldd [BASE + ( 4 * 0x4)], M4; \ - ldd [BASE + ( 6 * 0x4)], M6; \ - ldd [BASE + ( 8 * 0x4)], M8; \ - ldd [BASE + (10 * 0x4)], M10; \ - ldd [BASE + (12 * 0x4)], M12; \ - ldd [BASE + (14 * 0x4)], M14 - -#define LDMATRIX_0_1_4_5_12_13(BASE) \ - ldd [BASE + ( 0 * 0x4)], M0; \ - ldd [BASE + ( 4 * 0x4)], M4; \ - ldd [BASE + (12 * 0x4)], M12 - -#define LDMATRIX_0_5_12_13(BASE) \ - ld [BASE + ( 0 * 0x4)], M0; \ - ld [BASE + ( 5 * 0x4)], M5; \ - ldd [BASE + (12 * 0x4)], M12 - -#define LDMATRIX_0_1_2_4_5_6_8_9_10(BASE) \ - ldd [BASE + ( 0 * 0x4)], M0; \ - ld [BASE + ( 2 * 0x4)], M2; \ - ldd [BASE + ( 4 * 0x4)], M4; \ - ld [BASE + ( 6 * 0x4)], M6; \ - ldd [BASE + ( 8 * 0x4)], M8; \ - ld [BASE + (10 * 0x4)], M10 - -#define LDMATRIX_0_1_2_4_5_6_8_9_10_12_13_14(BASE) \ - ldd [BASE + ( 0 * 0x4)], M0; \ - ld [BASE + ( 2 * 0x4)], M2; \ - ldd [BASE + ( 4 * 0x4)], M4; \ - ld [BASE + ( 6 * 0x4)], M6; \ - ldd [BASE + ( 8 * 0x4)], M8; \ - ld [BASE + (10 * 0x4)], M10; \ - ldd [BASE + (12 * 0x4)], M12; \ - ld [BASE + (14 * 0x4)], M14 - -#define LDMATRIX_0_5_10(BASE) \ - ld [BASE + ( 0 * 0x4)], M0; \ - ld [BASE + ( 5 * 0x4)], M5; \ - ld [BASE + (10 * 0x4)], M10; - -#define LDMATRIX_0_5_10_12_13_14(BASE) \ - ld [BASE + ( 0 * 0x4)], M0; \ - ld [BASE + ( 5 * 0x4)], M5; \ - ld [BASE + (10 * 0x4)], M10; \ - ldd [BASE + (12 * 0x4)], M12; \ - ld [BASE + (14 * 0x4)], M14 - -#define LDMATRIX_0_5_8_9_10_14(BASE) \ - ld [BASE + ( 0 * 0x4)], M0; \ - ld [BASE + ( 5 * 0x4)], M5; \ - ldd [BASE + ( 8 * 0x4)], M8; \ - ld [BASE + (10 * 0x4)], M10; \ - ld [BASE + (14 * 0x4)], M14 - -#endif /* !(_SPARC_MATRIX_H) */ diff --git a/src/mesa/sparc/xform.S b/src/mesa/sparc/xform.S deleted file mode 100644 index 2a7cce4..0000000 --- a/src/mesa/sparc/xform.S +++ /dev/null @@ -1,1392 +0,0 @@ - - /* TODO - * - * 1) It would be nice if load/store double could be used - * at least for the matrix parts. I think for the matrices - * it is safe, but for the vertices it probably is not due to - * things like glInterleavedArrays etc. - * - * UPDATE: Trying this now in sparc_matrix.h -DaveM_990624 - * - * 2) One extremely slick trick would be if we could enclose - * groups of xform calls on the same vertices such that - * we just load the matrix into f16-->f31 before the calls - * and then we would not have to do them here. This may be - * tricky and not much of a gain though. - */ - -#include "sparc_matrix.h" - -#if defined(SVR4) || defined(__SVR4) || defined(__svr4__) || defined(__arch64__) - /* Solaris requires this for 64-bit. */ - .register %g2, #scratch - .register %g3, #scratch -#endif - - .text - .align 64 - -__set_v4f_1: - ld [%o0 + V4F_FLAGS], %g2 - mov 1, %g1 - st %g1, [%o0 + V4F_SIZE] - or %g2, VEC_SIZE_1, %g2 - retl - st %g2, [%o0 + V4F_FLAGS] -__set_v4f_2: - ld [%o0 + V4F_FLAGS], %g2 - mov 2, %g1 - st %g1, [%o0 + V4F_SIZE] - or %g2, VEC_SIZE_2, %g2 - retl - st %g2, [%o0 + V4F_FLAGS] -__set_v4f_3: - ld [%o0 + V4F_FLAGS], %g2 - mov 3, %g1 - st %g1, [%o0 + V4F_SIZE] - or %g2, VEC_SIZE_3, %g2 - retl - st %g2, [%o0 + V4F_FLAGS] -__set_v4f_4: - ld [%o0 + V4F_FLAGS], %g2 - mov 4, %g1 - st %g1, [%o0 + V4F_SIZE] - or %g2, VEC_SIZE_4, %g2 - retl - st %g2, [%o0 + V4F_FLAGS] - - /* First the raw versions. */ - - .globl _mesa_sparc_transform_points1_general -_mesa_sparc_transform_points1_general: - ld [%o2 + V4F_STRIDE], %o5 - LDPTR [%o2 + V4F_START], %g1 - LDPTR [%o0 + V4F_START], %g2 - ld [%o2 + V4F_COUNT], %g3 - - LDMATRIX_0_1_2_3_12_13_14_15(%o1) - - cmp %g3, 1 - st %g3, [%o0 + V4F_COUNT] - bl 3f - clr %o1 - - be 2f - andn %g3, 1, %o2 - -1: ld [%g1 + 0x00], %f0 ! LSU Group - add %g1, %o5, %g1 ! IEU0 - ld [%g1 + 0x00], %f8 ! LSU Group - add %o1, 2, %o1 ! IEU0 - add %g1, %o5, %g1 ! IEU1 - fmuls %f0, M0, %f1 ! FGM Group 1-cycle stall on %f0 - fmuls %f0, M1, %f2 ! FGM Group - fmuls %f0, M2, %f3 ! FGM Group - fmuls %f0, M3, %f4 ! FGM Group - fmuls %f8, M0, %f9 ! FGM Group f1 available - fadds %f1, M12, %f1 ! FGA - st %f1, [%g2 + 0x00] ! LSU - fmuls %f8, M1, %f10 ! FGM Group f2 available - fadds %f2, M13, %f2 ! FGA - st %f2, [%g2 + 0x04] ! LSU - fmuls %f8, M2, %f11 ! FGM Group f3 available - fadds %f3, M14, %f3 ! FGA - st %f3, [%g2 + 0x08] ! LSU - fmuls %f8, M3, %f12 ! FGM Group f4 available - fadds %f4, M15, %f4 ! FGA - st %f4, [%g2 + 0x0c] ! LSU - fadds %f9, M12, %f9 ! FGA Group f9 available - st %f9, [%g2 + 0x10] ! LSU - fadds %f10, M13, %f10 ! FGA Group f10 available - st %f10, [%g2 + 0x14] ! LSU - fadds %f11, M14, %f11 ! FGA Group f11 available - st %f11, [%g2 + 0x18] ! LSU - fadds %f12, M15, %f12 ! FGA Group f12 available - st %f12, [%g2 + 0x1c] ! LSU - cmp %o1, %o2 ! IEU1 - bne 1b ! CTI - add %g2, 0x20, %g2 ! IEU0 Group - - cmp %o1, %g3 - be 3f - nop - -2: ld [%g1 + 0x00], %f0 ! LSU Group - fmuls %f0, M0, %f1 ! FGM Group 1-cycle stall on %f0 - fmuls %f0, M1, %f2 ! FGM Group - fmuls %f0, M2, %f3 ! FGM Group - fmuls %f0, M3, %f4 ! FGM Group - fadds %f1, M12, %f1 ! FGA Group - st %f1, [%g2 + 0x00] ! LSU - fadds %f2, M13, %f2 ! FGA Group - st %f2, [%g2 + 0x04] ! LSU - fadds %f3, M14, %f3 ! FGA Group - st %f3, [%g2 + 0x08] ! LSU - fadds %f4, M15, %f4 ! FGA Group - st %f4, [%g2 + 0x0c] ! LSU - -3: - ba __set_v4f_4 - nop - - .globl _mesa_sparc_transform_points1_identity -_mesa_sparc_transform_points1_identity: - cmp %o0, %o2 - be 4f - ld [%o2 + V4F_STRIDE], %o5 - LDPTR [%o2 + V4F_START], %g1 - LDPTR [%o0 + V4F_START], %g2 - ld [%o2 + V4F_COUNT], %g3 - - cmp %g3, 1 - st %g3, [%o0 + V4F_COUNT] - bl 3f - clr %o1 - - be 2f - andn %g3, 1, %o2 - -1: ld [%g1 + 0x00], %f0 ! LSU Group - add %g1, %o5, %g1 ! IEU0 - ld [%g1 + 0x00], %f1 ! LSU Group - add %o1, 2, %o1 ! IEU0 - add %g1, %o5, %g1 ! IEU1 - st %f0, [%g2 + 0x00] ! LSU Group - cmp %o1, %o2 ! IEU1 - st %f1, [%g2 + 0x10] ! LSU Group - bne 1b ! CTI - add %g2, 0x20, %g2 ! IEU0 - - cmp %o1, %g3 - be 3f - nop - -2: ld [%g1 + 0x00], %f0 - addx %g0, %g0, %g0 - st %f0, [%g2 + 0x00] - -3: - ba __set_v4f_1 - nop - -4: retl - nop - - .globl _mesa_sparc_transform_points1_2d -_mesa_sparc_transform_points1_2d: - ld [%o2 + V4F_STRIDE], %o5 - LDPTR [%o2 + V4F_START], %g1 - LDPTR [%o0 + V4F_START], %g2 - ld [%o2 + V4F_COUNT], %g3 - - LDMATRIX_0_1_12_13(%o1) - - cmp %g3, 1 - st %g3, [%o0 + V4F_COUNT] - bl 3f - clr %o1 - - be 2f - andn %g3, 1, %o2 - -1: ld [%g1 + 0x00], %f0 ! LSU Group - add %g1, %o5, %g1 ! IEU0 - ld [%g1 + 0x00], %f8 ! LSU Group - add %o1, 2, %o1 ! IEU0 - add %g1, %o5, %g1 ! IEU1 - fmuls %f0, M0, %f1 ! FGM Group - fmuls %f0, M1, %f2 ! FGM Group - fmuls %f8, M0, %f9 ! FGM Group - fmuls %f8, M1, %f10 ! FGM Group - fadds %f1, M12, %f3 ! FGA Group f1 available - st %f3, [%g2 + 0x00] ! LSU - fadds %f2, M13, %f4 ! FGA Group f2 available - st %f4, [%g2 + 0x04] ! LSU - fadds %f9, M12, %f11 ! FGA Group f9 available - st %f11, [%g2 + 0x10] ! LSU - fadds %f10, M13, %f12 ! FGA Group f10 available - st %f12, [%g2 + 0x14] ! LSU - cmp %o1, %o2 ! IEU1 - bne 1b ! CTI - add %g2, 0x20, %g2 ! IEU0 Group - - cmp %o1, %g3 - be 3f - nop - -2: ld [%g1 + 0x00], %f0 - fmuls %f0, M0, %f1 - fmuls %f0, M1, %f2 - fadds %f1, M12, %f3 - st %f3, [%g2 + 0x00] - fadds %f2, M13, %f4 - st %f4, [%g2 + 0x04] - -3: - ba __set_v4f_2 - nop - - .globl _mesa_sparc_transform_points1_2d_no_rot -_mesa_sparc_transform_points1_2d_no_rot: - ld [%o2 + V4F_STRIDE], %o5 - LDPTR [%o2 + V4F_START], %g1 - LDPTR [%o0 + V4F_START], %g2 - ld [%o2 + V4F_COUNT], %g3 - - LDMATRIX_0_12_13(%o1) - - cmp %g3, 1 - st %g3, [%o0 + V4F_COUNT] - bl 3f - clr %o1 - - be 2f - andn %g3, 1, %o2 - -1: ld [%g1 + 0x00], %f0 ! LSU Group - add %g1, %o5, %g1 ! IEU0 - ld [%g1 + 0x00], %f4 ! LSU Group - add %o1, 2, %o1 ! IEU0 - add %g1, %o5, %g1 ! IEU1 - fmuls %f0, M0, %f1 ! FGM Group - fmuls %f4, M0, %f5 ! FGM Group - fadds %f1, M12, %f3 ! FGA Group, 2 cycle stall, f1 available - st %f3, [%g2 + 0x00] ! LSU - st M13, [%g2 + 0x04] ! LSU Group, f5 available - fadds %f5, M12, %f6 ! FGA - st %f6, [%g2 + 0x10] ! LSU Group - st M13, [%g2 + 0x14] ! LSU Group - cmp %o1, %o2 ! IEU1 - bne 1b ! CTI - add %g2, 0x20, %g2 ! IEU0 Group - - cmp %o1, %g3 - be 3f - nop - -2: ld [%g1 + 0x00], %f0 - fmuls %f0, M0, %f1 - fadds %f1, M12, %f3 - st %f3, [%g2 + 0x00] - st M13, [%g2 + 0x04] - -3: - ba __set_v4f_2 - nop - - .globl _mesa_sparc_transform_points1_3d -_mesa_sparc_transform_points1_3d: - ld [%o2 + V4F_STRIDE], %o5 - LDPTR [%o2 + V4F_START], %g1 - LDPTR [%o0 + V4F_START], %g2 - ld [%o2 + V4F_COUNT], %g3 - - LDMATRIX_0_1_2_12_13_14(%o1) - - cmp %g3, 1 - st %g3, [%o0 + V4F_COUNT] - bl 3f - clr %o1 - - be 2f - andn %g3, 1, %o2 - -1: ld [%g1 + 0x00], %f0 ! LSU Group - add %g1, %o5, %g1 ! IEU0 - ld [%g1 + 0x00], %f4 ! LSU Group - add %o1, 2, %o1 ! IEU0 - add %g1, %o5, %g1 ! IEU1 - fmuls %f0, M0, %f1 ! FGM Group - fmuls %f0, M1, %f2 ! FGM Group - fmuls %f0, M2, %f3 ! FGM Group - fmuls %f4, M0, %f5 ! FGM Group - fadds %f1, M12, %f1 ! FGA Group, f1 available - st %f1, [%g2 + 0x00] ! LSU - fmuls %f4, M1, %f6 ! FGM - fadds %f2, M13, %f2 ! FGA Group, f2 available - st %f2, [%g2 + 0x04] ! LSU - fmuls %f4, M2, %f7 ! FGM - fadds %f3, M14, %f3 ! FGA Group, f3 available - st %f3, [%g2 + 0x08] ! LSU - fadds %f5, M12, %f5 ! FGA Group, f5 available - st %f5, [%g2 + 0x10] ! LSU - fadds %f6, M13, %f6 ! FGA Group, f6 available - st %f6, [%g2 + 0x14] ! LSU - fadds %f7, M14, %f7 ! FGA Group, f7 available - st %f7, [%g2 + 0x18] ! LSU - cmp %o1, %o2 ! IEU1 - bne 1b ! CTI - add %g2, 0x20, %g2 ! IEU0 Group - - cmp %o1, %g3 - be 3f - nop - -2: ld [%g1 + 0x00], %f0 - fmuls %f0, M0, %f1 - fmuls %f0, M1, %f2 - fmuls %f0, M2, %f3 - fadds %f1, M12, %f1 - st %f1, [%g2 + 0x00] - fadds %f2, M13, %f2 - st %f2, [%g2 + 0x04] - fadds %f3, M14, %f3 - st %f3, [%g2 + 0x08] - -3: - ba __set_v4f_3 - nop - - .globl _mesa_sparc_transform_points1_3d_no_rot -_mesa_sparc_transform_points1_3d_no_rot: - ld [%o2 + V4F_STRIDE], %o5 - LDPTR [%o2 + V4F_START], %g1 - LDPTR [%o0 + V4F_START], %g2 - ld [%o2 + V4F_COUNT], %g3 - - LDMATRIX_0_12_13_14(%o1) - - cmp %g3, 1 - st %g3, [%o0 + V4F_COUNT] - bl 3f - clr %o1 - - be 2f - andn %g3, 1, %o2 - -1: ld [%g1 + 0x00], %f0 ! LSU Group - add %g1, %o5, %g1 ! IEU0 - ld [%g1 + 0x00], %f2 ! LSU Group - add %o1, 2, %o1 ! IEU0 - add %g1, %o5, %g1 ! IEU1 - fmuls %f0, M0, %f1 ! FGM Group - fmuls %f2, M0, %f3 ! FGM Group - fadds %f1, M12, %f1 ! FGA Group, 2 cycle stall, f1 available - st %f1, [%g2 + 0x00] ! LSU - fadds %f3, M12, %f3 ! FGA Group, f3 available - st M13, [%g2 + 0x04] ! LSU - st M14, [%g2 + 0x08] ! LSU Group - st %f3, [%g2 + 0x10] ! LSU Group - st M13, [%g2 + 0x14] ! LSU Group - st M14, [%g2 + 0x18] ! LSU Group - cmp %o1, %o2 ! IEU1 - bne 1b ! CTI - add %g2, 0x20, %g2 ! IEU0 Group - - cmp %o1, %g3 - be 3f - nop - -2: ld [%g1 + 0x00], %f0 - fmuls %f0, M0, %f1 - fadds %f1, M12, %f1 - st %f1, [%g2 + 0x00] - st M13, [%g2 + 0x04] - st M14, [%g2 + 0x08] - -3: - ba __set_v4f_3 - nop - - .globl _mesa_sparc_transform_points1_perspective -_mesa_sparc_transform_points1_perspective: - ld [%o2 + V4F_STRIDE], %o5 - LDPTR [%o2 + V4F_START], %g1 - LDPTR [%o0 + V4F_START], %g2 - ld [%o2 + V4F_COUNT], %g3 - - LDMATRIX_0_14(%o1) - - cmp %g3, 1 - st %g3, [%o0 + V4F_COUNT] - bl 3f - clr %o1 - - be 2f - andn %g3, 1, %o2 - -1: ld [%g1 + 0x00], %f0 ! LSU Group - add %g1, %o5, %g1 ! IEU0 - ld [%g1 + 0x00], %f2 ! LSU Group - add %o1, 2, %o1 ! IEU0 - add %g1, %o5, %g1 ! IEU1 - fmuls %f0, M0, %f1 ! FGM Group - st %f1, [%g2 + 0x00] ! LSU - fmuls %f2, M0, %f3 ! FGM Group - st %g0, [%g2 + 0x04] ! LSU - st M14, [%g2 + 0x08] ! LSU Group - st %g0, [%g2 + 0x0c] ! LSU Group - st %f3, [%g2 + 0x10] ! LSU Group - st %g0, [%g2 + 0x14] ! LSU Group - st M14, [%g2 + 0x18] ! LSU Group - st %g0, [%g2 + 0x1c] ! LSU Group - cmp %o1, %o2 ! IEU1 - bne 1b ! CTI - add %g2, 0x20, %g2 ! IEU0 Group - - cmp %o1, %g3 - be 3f - nop - -2: ld [%g1 + 0x00], %f0 - fmuls %f0, M0, %f1 - st %f1, [%g2 + 0x00] - st %g0, [%g2 + 0x04] - st M14, [%g2 + 0x08] - st %g0, [%g2 + 0x0c] - -3: - ba __set_v4f_4 - nop - - .globl _mesa_sparc_transform_points2_general -_mesa_sparc_transform_points2_general: - ld [%o2 + V4F_STRIDE], %o5 - LDPTR [%o2 + V4F_START], %g1 - LDPTR [%o0 + V4F_START], %g2 - ld [%o2 + V4F_COUNT], %g3 - - LDMATRIX_0_1_2_3_4_5_6_7_12_13_14_15(%o1) - - cmp %g3, 0 - st %g3, [%o0 + V4F_COUNT] - be 2f - clr %o1 - -1: ld [%g1 + 0x00], %f0 ! LSU Group - ld [%g1 + 0x04], %f1 ! LSU Group - add %o1, 1, %o1 ! IEU0 - add %g1, %o5, %g1 ! IEU1 - fmuls %f0, M0, %f2 ! FGM Group - fmuls %f0, M1, %f3 ! FGM Group - fmuls %f0, M2, %f4 ! FGM Group - fmuls %f0, M3, %f5 ! FGM Group - fadds %f2, M12, %f2 ! FGA Group f2 available - fmuls %f1, M4, %f6 ! FGM - fadds %f3, M13, %f3 ! FGA Group f3 available - fmuls %f1, M5, %f7 ! FGM - fadds %f4, M14, %f4 ! FGA Group f4 available - fmuls %f1, M6, %f8 ! FGM - fadds %f5, M15, %f5 ! FGA Group f5 available - fmuls %f1, M7, %f9 ! FGM - fadds %f2, %f6, %f2 ! FGA Group f6 available - st %f2, [%g2 + 0x00] ! LSU - fadds %f3, %f7, %f3 ! FGA Group f7 available - st %f3, [%g2 + 0x04] ! LSU - fadds %f4, %f8, %f4 ! FGA Group f8 available - st %f4, [%g2 + 0x08] ! LSU - fadds %f5, %f9, %f5 ! FGA Group f9 available - st %f5, [%g2 + 0x0c] ! LSU - cmp %o1, %g3 ! IEU1 - bne 1b ! CTI - add %g2, 0x10, %g2 ! IEU0 Group -2: - ba __set_v4f_4 - nop - - .globl _mesa_sparc_transform_points2_identity -_mesa_sparc_transform_points2_identity: - cmp %o2, %o0 - be 3f - ld [%o2 + V4F_STRIDE], %o5 - LDPTR [%o2 + V4F_START], %g1 - LDPTR [%o0 + V4F_START], %g2 - ld [%o2 + V4F_COUNT], %g3 - - cmp %g3, 0 - st %g3, [%o0 + V4F_COUNT] - be 2f - clr %o1 - -1: ld [%g1 + 0x00], %f0 ! LSU Group - add %o1, 1, %o1 ! IEU0 - ld [%g1 + 0x04], %f1 ! LSU Group - add %g1, %o5, %g1 ! IEU0 - cmp %o1, %g3 ! IEU1 - st %f0, [%g2 + 0x00] ! LSU Group - st %f1, [%g2 + 0x04] ! LSU Group - bne 1b ! CTI - add %g2, 0x10, %g2 ! IEU0 -2: - ba __set_v4f_2 - nop - -3: retl - nop - - .globl _mesa_sparc_transform_points2_2d -_mesa_sparc_transform_points2_2d: - ld [%o2 + V4F_STRIDE], %o5 - LDPTR [%o2 + V4F_START], %g1 - LDPTR [%o0 + V4F_START], %g2 - ld [%o2 + V4F_COUNT], %g3 - - LDMATRIX_0_1_4_5_12_13(%o1) - - cmp %g3, 1 - st %g3, [%o0 + V4F_COUNT] - bl 3f - clr %o1 - - be 2f - andn %g3, 1, %o2 - -1: ld [%g1 + 0x00], %f0 ! LSU Group - ld [%g1 + 0x04], %f1 ! LSU Group - add %o1, 2, %o1 ! IEU0 - add %g1, %o5, %g1 ! IEU1 - fmuls %f0, M0, %f2 ! FGM - ld [%g1 + 0x00], %f8 ! LSU Group - fmuls %f0, M1, %f3 ! FGM - ld [%g1 + 0x04], %f9 ! LSU Group - fmuls %f1, M4, %f6 ! FGM - fmuls %f1, M5, %f7 ! FGM Group - add %g1, %o5, %g1 ! IEU0 - fmuls %f8, M0, %f10 ! FGM Group f2 available - fadds %f2, M12, %f2 ! FGA - fmuls %f8, M1, %f11 ! FGM Group f3 available - fadds %f3, M13, %f3 ! FGA - fmuls %f9, M4, %f12 ! FGM Group - fmuls %f9, M5, %f13 ! FGM Group - fadds %f10, M12, %f10 ! FGA Group f2, f10 available - fadds %f2, %f6, %f2 ! FGA Group f3, f11 available - st %f2, [%g2 + 0x00] ! LSU - fadds %f11, M13, %f11 ! FGA Group f12 available - fadds %f3, %f7, %f3 ! FGA Group f13 available - st %f3, [%g2 + 0x04] ! LSU - fadds %f10, %f12, %f10 ! FGA Group f10 available - st %f10, [%g2 + 0x10] ! LSU - fadds %f11, %f13, %f11 ! FGA Group f11 available - st %f11, [%g2 + 0x14] ! LSU - cmp %o1, %o2 ! IEU1 - bne 1b ! CTI - add %g2, 0x20, %g2 ! IEU0 Group - - cmp %o1, %g3 - be 3f - nop - -2: ld [%g1 + 0x00], %f0 ! LSU Group - ld [%g1 + 0x04], %f1 ! LSU Group - fmuls %f0, M0, %f2 ! FGM Group - fmuls %f0, M1, %f3 ! FGM Group - fmuls %f1, M4, %f6 ! FGM Group - fmuls %f1, M5, %f7 ! FGM Group - fadds %f2, M12, %f2 ! FGA Group f2 available - fadds %f3, M13, %f3 ! FGA Group f3 available - fadds %f2, %f6, %f2 ! FGA Group 2 cycle stall, f2 available - st %f2, [%g2 + 0x00] ! LSU - fadds %f3, %f7, %f3 ! FGA Group f3 available - st %f3, [%g2 + 0x04] ! LSU - -3: - ba __set_v4f_2 - nop - - .globl _mesa_sparc_transform_points2_2d_no_rot -_mesa_sparc_transform_points2_2d_no_rot: - ld [%o2 + V4F_STRIDE], %o5 - LDPTR [%o2 + V4F_START], %g1 - LDPTR [%o0 + V4F_START], %g2 - ld [%o2 + V4F_COUNT], %g3 - - LDMATRIX_0_5_12_13(%o1) - - cmp %g3, 1 - st %g3, [%o0 + V4F_COUNT] - bl 3f - clr %o1 - - be 2f - andn %g3, 1, %o2 - -1: ld [%g1 + 0x00], %f0 ! LSU Group - ld [%g1 + 0x04], %f1 ! LSU Group - add %o1, 2, %o1 ! IEU0 - add %g1, %o5, %g1 ! IEU1 - ld [%g1 + 0x00], %f4 ! LSU Group - fmuls %f0, M0, %f2 ! FGM - ld [%g1 + 0x04], %f5 ! LSU Group - fmuls %f1, M5, %f3 ! FGM - fmuls %f4, M0, %f6 ! FGM Group - add %g1, %o5, %g1 ! IEU0 - fmuls %f5, M5, %f7 ! FGM Group - fadds %f2, M12, %f2 ! FGA Group f2 available - st %f2, [%g2 + 0x00] ! LSU - fadds %f3, M13, %f3 ! FGA Group f3 available - st %f3, [%g2 + 0x04] ! LSU - fadds %f6, M12, %f6 ! FGA Group f6 available - st %f6, [%g2 + 0x10] ! LSU - fadds %f7, M13, %f7 ! FGA Group f7 available - st %f7, [%g2 + 0x14] ! LSU - cmp %o1, %o2 ! IEU1 - bne 1b ! CTI - add %g2, 0x20, %g2 ! IEU0 Group - - cmp %o1, %g3 - be 3f - nop - -2: ld [%g1 + 0x00], %f0 ! LSU Group - ld [%g1 + 0x04], %f1 ! LSU Group - fmuls %f0, M0, %f2 ! FGM Group - fmuls %f1, M5, %f3 ! FGM Group - fadds %f2, M12, %f2 ! FGA Group, 2 cycle stall, f2 available - st %f2, [%g2 + 0x00] ! LSU - fadds %f3, M13, %f3 ! FGA Group f3 available - st %f3, [%g2 + 0x04] ! LSU - -3: - ba __set_v4f_2 - nop - - /* orig: 12 cycles */ - .globl _mesa_sparc_transform_points2_3d -_mesa_sparc_transform_points2_3d: - ld [%o2 + V4F_STRIDE], %o5 - ld [%o2 + V4F_START], %g1 - ld [%o0 + V4F_START], %g2 - ld [%o2 + V4F_COUNT], %g3 - - LDMATRIX_0_1_2_3_4_5_6_12_13_14(%o1) - - cmp %g3, 1 - st %g3, [%o0 + V4F_COUNT] - bl 3f - clr %o1 - - be 2f - andn %g3, 1, %o2 - -1: ld [%g1 + 0x00], %f0 ! LSU Group - ld [%g1 + 0x04], %f1 ! LSU Group - add %o1, 2, %o1 ! IEU0 - add %g1, %o5, %g1 ! IEU1 - ld [%g1 + 0x00], %f9 ! LSU Group - fmuls %f0, M0, %f2 ! FGM - ld [%g1 + 0x04], %f10 ! LSU Group - fmuls %f0, M1, %f3 ! FGM - fmuls %f0, M2, %f4 ! FGM Group - add %g1, %o5, %g1 ! IEU0 - fmuls %f1, M4, %f6 ! FGM Group - fmuls %f1, M5, %f7 ! FGM Group f2 available - fadds %f2, M12, %f2 ! FGA - fmuls %f1, M6, %f8 ! FGM Group f3 available - fadds %f3, M13, %f3 ! FGA - fmuls %f9, M0, %f11 ! FGM Group f4 available - fadds %f4, M14, %f4 ! FGA - fmuls %f9, M1, %f12 ! FGM Group f6 available - fmuls %f9, M2, %f13 ! FGM Group f2, f7 available - fadds %f2, %f6, %f2 ! FGA - st %f2, [%g2 + 0x00] ! LSU - fmuls %f10, M4, %f14 ! FGM Group f3, f8 available - fadds %f3, %f7, %f3 ! FGA - st %f3, [%g2 + 0x04] ! LSU - fmuls %f10, M5, %f15 ! FGM Group f4, f11 available - fadds %f11, M12, %f11 ! FGA - fmuls %f10, M6, %f0 ! FGM Group f12 available - fadds %f12, M13, %f12 ! FGA - fadds %f13, M14, %f13 ! FGA Group f13 available - fadds %f4, %f8, %f4 ! FGA Group f14 available - st %f4, [%g2 + 0x08] ! LSU - fadds %f11, %f14, %f11 ! FGA Group f15, f11 available - st %f11, [%g2 + 0x10] ! LSU - fadds %f12, %f15, %f12 ! FGA Group f0, f12 available - st %f12, [%g2 + 0x14] ! LSU - fadds %f13, %f0, %f13 ! FGA Group f13 available - st %f13, [%g2 + 0x18] ! LSU - - cmp %o1, %o2 ! IEU1 - bne 1b ! CTI - add %g2, 0x20, %g2 ! IEU0 Group - - cmp %o1, %g3 - be 3f - nop - -2: ld [%g1 + 0x00], %f0 ! LSU Group - ld [%g1 + 0x04], %f1 ! LSU Group - fmuls %f0, M0, %f2 ! FGM Group - fmuls %f0, M1, %f3 ! FGM Group - fmuls %f0, M2, %f4 ! FGM Group - fmuls %f1, M4, %f6 ! FGM Group - fmuls %f1, M5, %f7 ! FGM Group f2 available - fadds %f2, M12, %f2 ! FGA - fmuls %f1, M6, %f8 ! FGM Group f3 available - fadds %f3, M13, %f3 ! FGA - fadds %f4, M14, %f4 ! FGA Group f4 available - fadds %f2, %f6, %f2 ! FGA Group stall, f2, f6, f7 available - st %f2, [%g2 + 0x00] ! LSU - fadds %f3, %f7, %f3 ! FGA Group f3, f8 available - st %f3, [%g2 + 0x04] ! LSU - fadds %f4, %f8, %f4 ! FGA Group f4 available - st %f4, [%g2 + 0x08] ! LSU - -3: - ba __set_v4f_3 - nop - - .globl _mesa_sparc_transform_points2_3d_no_rot -_mesa_sparc_transform_points2_3d_no_rot: - ld [%o2 + V4F_STRIDE], %o5 - LDPTR [%o2 + V4F_START], %g1 - LDPTR [%o0 + V4F_START], %g2 - ld [%o2 + V4F_COUNT], %g3 - - LDMATRIX_0_5_12_13_14(%o1) - - cmp %g3, 1 - st %g3, [%o0 + V4F_COUNT] - bl 3f - clr %o3 - - be 2f - andn %g3, 1, %o2 - -1: ld [%g1 + 0x00], %f0 ! LSU Group - ld [%g1 + 0x04], %f1 ! LSU Group - add %o3, 2, %o3 ! IEU0 - add %g1, %o5, %g1 ! IEU1 - ld [%g1 + 0x00], %f4 ! LSU Group - fmuls %f0, M0, %f2 ! FGM - ld [%g1 + 0x04], %f5 ! LSU Group - fmuls %f1, M5, %f3 ! FGM - fmuls %f4, M0, %f6 ! FGM Group - add %g1, %o5, %g1 ! IEU0 - fmuls %f5, M5, %f7 ! FGM Group - fadds %f2, M12, %f2 ! FGA Group f2 available - st %f2, [%g2 + 0x00] ! LSU - fadds %f3, M13, %f3 ! FGA Group f3 available - st %f3, [%g2 + 0x04] ! LSU - fadds %f6, M12, %f6 ! FGA Group f6 available - st M14, [%g2 + 0x08] ! LSU - fadds %f7, M13, %f7 ! FGA Group f7 available - st %f6, [%g2 + 0x10] ! LSU - st %f7, [%g2 + 0x14] ! LSU Group - st M14, [%g2 + 0x18] ! LSU Group - cmp %o3, %o2 ! IEU1 - bne 1b ! CTI - add %g2, 0x20, %g2 ! IEU0 Group - - cmp %o3, %g3 - be 3f - nop - -2: ld [%g1 + 0x00], %f0 ! LSU Group - ld [%g1 + 0x04], %f1 ! LSU Group - fmuls %f0, M0, %f2 ! FGM Group - fmuls %f1, M5, %f3 ! FGM Group - fadds %f2, M12, %f2 ! FGA Group, 2 cycle stall, f2 available - st %f2, [%g2 + 0x00] ! LSU - fadds %f3, M13, %f3 ! FGA Group f3 available - st %f3, [%g2 + 0x04] ! LSU - st M14, [%g2 + 0x08] ! LSU Group - -3: ld [%o1 + (14 * 0x4)], %g3 - cmp %g3, 0 - bne __set_v4f_3 - nop - ba __set_v4f_2 - nop - - .globl _mesa_sparc_transform_points2_perspective -_mesa_sparc_transform_points2_perspective: - ld [%o2 + V4F_STRIDE], %o5 - LDPTR [%o2 + V4F_START], %g1 - LDPTR [%o0 + V4F_START], %g2 - ld [%o2 + V4F_COUNT], %g3 - - LDMATRIX_0_5_14(%o1) - - cmp %g3, 0 - st %g3, [%o0 + V4F_COUNT] - be 2f - clr %o1 - -1: ld [%g1 + 0x00], %f0 - ld [%g1 + 0x04], %f1 - add %o1, 1, %o1 - add %g1, %o5, %g1 - fmuls %f0, M0, %f2 - st %f2, [%g2 + 0x00] - fmuls %f1, M5, %f3 - st %f3, [%g2 + 0x04] - st M14, [%g2 + 0x08] - st %g0, [%g2 + 0x0c] - cmp %o1, %g3 - bne 1b - add %g2, 0x10, %g2 -2: - ba __set_v4f_4 - nop - - .globl _mesa_sparc_transform_points3_general -_mesa_sparc_transform_points3_general: - ld [%o2 + V4F_STRIDE], %o5 - LDPTR [%o2 + V4F_START], %g1 - LDPTR [%o0 + V4F_START], %g2 - ld [%o2 + V4F_COUNT], %g3 - - LDMATRIX_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15(%o1) - - cmp %g3, 0 - st %g3, [%o0 + V4F_COUNT] - be 2f - clr %o1 - -1: ld [%g1 + 0x00], %f0 ! LSU Group - ld [%g1 + 0x04], %f1 ! LSU Group - ld [%g1 + 0x08], %f2 ! LSU Group - add %o1, 1, %o1 ! IEU0 - add %g1, %o5, %g1 ! IEU1 - fmuls %f0, M0, %f3 ! FGM - fmuls %f1, M4, %f7 ! FGM Group - fmuls %f0, M1, %f4 ! FGM Group - fmuls %f1, M5, %f8 ! FGM Group - fmuls %f0, M2, %f5 ! FGM Group f3 available - fmuls %f1, M6, %f9 ! FGM Group f7 available - fadds %f3, %f7, %f3 ! FGA - fmuls %f0, M3, %f6 ! FGM Group f4 available - fmuls %f1, M7, %f10 ! FGM Group f8 available - fadds %f4, %f8, %f4 ! FGA - fmuls %f2, M8, %f7 ! FGM Group f5 available - fmuls %f2, M9, %f8 ! FGM Group f9,f3 available - fadds %f5, %f9, %f5 ! FGA - fmuls %f2, M10, %f9 ! FGM Group f6 available - fadds %f6, %f10, %f6 ! FGA Group f10,f4 available - fmuls %f2, M11, %f10 ! FGM - fadds %f3, M12, %f3 ! FGA Group f7 available - fadds %f4, M13, %f4 ! FGA Group f8,f5 available - fadds %f5, M14, %f5 ! FGA Group f9 available - fadds %f6, M15, %f6 ! FGA Group f10,f6 available - fadds %f3, %f7, %f3 ! FGA Group f3 available - st %f3, [%g2 + 0x00] ! LSU - fadds %f4, %f8, %f4 ! FGA Group f4 available - st %f4, [%g2 + 0x04] ! LSU - fadds %f5, %f9, %f5 ! FGA Group f5 available - st %f5, [%g2 + 0x08] ! LSU - fadds %f6, %f10, %f6 ! FGA Group f6 available - st %f6, [%g2 + 0x0c] ! LSU - cmp %o1, %g3 ! IEU1 - bne 1b ! CTI - add %g2, 0x10, %g2 ! IEU0 Group -2: - ba __set_v4f_4 - nop - - .globl _mesa_sparc_transform_points3_identity -_mesa_sparc_transform_points3_identity: - ld [%o2 + V4F_STRIDE], %o5 - LDPTR [%o2 + V4F_START], %g1 - LDPTR [%o0 + V4F_START], %g2 - ld [%o2 + V4F_COUNT], %g3 - - cmp %g3, 0 - st %g3, [%o0 + V4F_COUNT] - be 2f - clr %o1 - -1: ld [%g1 + 0x00], %f0 - ld [%g1 + 0x04], %f1 - ld [%g1 + 0x08], %f2 - add %o1, 1, %o1 - add %g1, %o5, %g1 - cmp %o1, %g3 - st %f0, [%g2 + 0x00] - st %f1, [%g2 + 0x04] - st %f2, [%g2 + 0x08] - bne 1b - add %g2, 0x10, %g2 -2: - ba __set_v4f_3 - nop - - .globl _mesa_sparc_transform_points3_2d -_mesa_sparc_transform_points3_2d: - ld [%o2 + V4F_STRIDE], %o5 - LDPTR [%o2 + V4F_START], %g1 - LDPTR [%o0 + V4F_START], %g2 - ld [%o2 + V4F_COUNT], %g3 - - LDMATRIX_0_1_4_5_12_13(%o1) - - cmp %g3, 0 - st %g3, [%o0 + V4F_COUNT] - be 2f - clr %o1 - -1: ld [%g1 + 0x00], %f0 ! LSU Group - ld [%g1 + 0x04], %f1 ! LSU Group - ld [%g1 + 0x08], %f2 ! LSU Group - add %o1, 1, %o1 ! IEU0 - add %g1, %o5, %g1 ! IEU1 - fmuls %f0, M0, %f3 ! FGM - fmuls %f0, M1, %f4 ! FGM Group - fmuls %f1, M4, %f6 ! FGM Group - fmuls %f1, M5, %f7 ! FGM Group - fadds %f3, M12, %f3 ! FGA Group f3 available - fadds %f4, M13, %f4 ! FGA Group f4 available - fadds %f3, %f6, %f3 ! FGA Group f6 available - st %f3, [%g2 + 0x00] ! LSU - fadds %f4, %f7, %f4 ! FGA Group f7 available - st %f4, [%g2 + 0x04] ! LSU - st %f2, [%g2 + 0x08] ! LSU Group - cmp %o1, %g3 ! IEU1 - bne 1b ! CTI - add %g2, 0x10, %g2 ! IEU0 Group -2: - ba __set_v4f_3 - nop - - .globl _mesa_sparc_transform_points3_2d_no_rot -_mesa_sparc_transform_points3_2d_no_rot: - ld [%o2 + V4F_STRIDE], %o5 - LDPTR [%o2 + V4F_START], %g1 - LDPTR [%o0 + V4F_START], %g2 - ld [%o2 + V4F_COUNT], %g3 - - LDMATRIX_0_5_12_13(%o1) - - cmp %g3, 0 - st %g3, [%o0 + V4F_COUNT] - be 2f - clr %o1 - -1: ld [%g1 + 0x00], %f0 ! LSU Group - ld [%g1 + 0x04], %f1 ! LSU Group - ld [%g1 + 0x08], %f2 ! LSU Group - add %o1, 1, %o1 ! IEU0 - add %g1, %o5, %g1 ! IEU1 - fmuls %f0, M0, %f3 ! FGM - fmuls %f1, M5, %f4 ! FGM Group - st %f2, [%g2 + 0x08] ! LSU - fadds %f3, M12, %f3 ! FGA Group - st %f3, [%g2 + 0x00] ! LSU - fadds %f4, M13, %f4 ! FGA Group - st %f4, [%g2 + 0x04] ! LSU - cmp %o1, %g3 ! IEU1 - bne 1b ! CTI - add %g2, 0x10, %g2 ! IEU0 Group -2: - ba __set_v4f_3 - nop - - .globl _mesa_sparc_transform_points3_3d -_mesa_sparc_transform_points3_3d: - ld [%o2 + V4F_STRIDE], %o5 - LDPTR [%o2 + V4F_START], %g1 - LDPTR [%o0 + V4F_START], %g2 - ld [%o2 + V4F_COUNT], %g3 - - LDMATRIX_0_1_2_4_5_6_8_9_10_12_13_14(%o1) - - cmp %g3, 0 - st %g3, [%o0 + V4F_COUNT] - be 2f - clr %o1 - -1: ld [%g1 + 0x00], %f0 ! LSU Group - ld [%g1 + 0x04], %f1 ! LSU Group - ld [%g1 + 0x08], %f2 ! LSU Group - add %o1, 1, %o1 ! IEU0 - add %g1, %o5, %g1 ! IEU1 - fmuls %f0, M0, %f3 ! FGM - fmuls %f1, M4, %f6 ! FGM Group - fmuls %f0, M1, %f4 ! FGM Group - fmuls %f1, M5, %f7 ! FGM Group - fmuls %f0, M2, %f5 ! FGM Group f3 available - fmuls %f1, M6, %f8 ! FGM Group f6 available - fadds %f3, %f6, %f3 ! FGA - fmuls %f2, M8, %f9 ! FGM Group f4 available - fmuls %f2, M9, %f10 ! FGM Group f7 available - fadds %f4, %f7, %f4 ! FGA - fmuls %f2, M10, %f11 ! FGM Group f5 available - fadds %f5, %f8, %f5 ! FGA Group f8, f3 available - fadds %f3, %f9, %f3 ! FGA Group f9 available - fadds %f4, %f10, %f4 ! FGA Group f10, f4 available - fadds %f5, %f11, %f5 ! FGA Group stall, f11, f5 available - fadds %f3, M12, %f3 ! FGA Group f3 available - st %f3, [%g2 + 0x00] ! LSU - fadds %f4, M13, %f4 ! FGA Group f4 available - st %f4, [%g2 + 0x04] ! LSU - fadds %f5, M14, %f5 ! FGA Group f5 available - st %f5, [%g2 + 0x08] ! LSU - cmp %o1, %g3 ! IEU1 - bne 1b ! CTI - add %g2, 0x10, %g2 ! IEU0 Group -2: - ba __set_v4f_3 - nop - - .globl _mesa_sparc_transform_points3_3d_no_rot -_mesa_sparc_transform_points3_3d_no_rot: - ld [%o2 + V4F_STRIDE], %o5 - LDPTR [%o2 + V4F_START], %g1 - LDPTR [%o0 + V4F_START], %g2 - ld [%o2 + V4F_COUNT], %g3 - - LDMATRIX_0_5_10_12_13_14(%o1) - - cmp %g3, 0 - st %g3, [%o0 + V4F_COUNT] - be 2f - clr %o1 - -1: ld [%g1 + 0x00], %f0 ! LSU Group - ld [%g1 + 0x04], %f1 ! LSU Group - ld [%g1 + 0x08], %f2 ! LSU Group - add %o1, 1, %o1 ! IEU0 - add %g1, %o5, %g1 ! IEU1 - cmp %o1, %g3 ! IEU1 Group - fmuls %f0, M0, %f3 ! FGM - fmuls %f1, M5, %f4 ! FGM Group - fmuls %f2, M10, %f5 ! FGM Group - fadds %f3, M12, %f3 ! FGA Group, stall, f3 available - st %f3, [%g2 + 0x00] ! LSU - fadds %f4, M13, %f4 ! FGA Group, f4 available - st %f4, [%g2 + 0x04] ! LSU - fadds %f5, M14, %f5 ! FGA Group, f5 available - st %f5, [%g2 + 0x08] ! LEU - bne 1b ! CTI - add %g2, 0x10, %g2 ! IEU0 Group -2: - ba __set_v4f_3 - nop - - .globl _mesa_sparc_transform_points3_perspective -_mesa_sparc_transform_points3_perspective: - ld [%o2 + V4F_STRIDE], %o5 - LDPTR [%o2 + V4F_START], %g1 - LDPTR [%o0 + V4F_START], %g2 - ld [%o2 + V4F_COUNT], %g3 - - LDMATRIX_0_5_8_9_10_14(%o1) - - cmp %g3, 0 - st %g3, [%o0 + V4F_COUNT] - be 2f - clr %o1 - -1: ld [%g1 + 0x00], %f0 ! LSU Group - ld [%g1 + 0x04], %f1 ! LSU Group - ld [%g1 + 0x08], %f2 ! LSU Group - add %o1, 1, %o1 ! IEU0 - add %g1, %o5, %g1 ! IEU1 - fmuls %f0, M0, %f3 ! FGM - fmuls %f2, M8, %f6 ! FGM Group - fmuls %f1, M5, %f4 ! FGM Group - fmuls %f2, M9, %f7 ! FGM Group - fmuls %f2, M10, %f5 ! FGM Group f3 available - fadds %f3, %f6, %f3 ! FGA Group f6 available - st %f3, [%g2 + 0x00] ! LSU - fadds %f4, %f7, %f4 ! FGA Group stall, f4, f7 available - st %f4, [%g2 + 0x04] ! LSU - fadds %f5, M14, %f5 ! FGA Group - st %f5, [%g2 + 0x08] ! LSU - fnegs %f2, %f6 ! FGA Group - st %f6, [%g2 + 0x0c] ! LSU - cmp %o1, %g3 ! IEU1 - bne 1b ! CTI - add %g2, 0x10, %g2 ! IEU0 Group -2: - ba __set_v4f_4 - nop - - .globl _mesa_sparc_transform_points4_general -_mesa_sparc_transform_points4_general: - ld [%o2 + V4F_STRIDE], %o5 - LDPTR [%o2 + V4F_START], %g1 - LDPTR [%o0 + V4F_START], %g2 - ld [%o2 + V4F_COUNT], %g3 - - LDMATRIX_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15(%o1) - - cmp %g3, 0 - st %g3, [%o0 + V4F_COUNT] - be 2f - clr %o1 - -1: ld [%g1 + 0x00], %f0 ! LSU Group - ld [%g1 + 0x04], %f1 ! LSU Group - ld [%g1 + 0x08], %f2 ! LSU Group - ld [%g1 + 0x0c], %f3 ! LSU Group - add %o1, 1, %o1 ! IEU0 - add %g1, %o5, %g1 ! IEU1 - fmuls %f0, M0, %f4 ! FGM Group - fmuls %f1, M4, %f8 ! FGM Group - fmuls %f0, M1, %f5 ! FGM Group - fmuls %f1, M5, %f9 ! FGM Group - fmuls %f0, M2, %f6 ! FGM Group f4 available - fmuls %f1, M6, %f10 ! FGM Group f8 available - fadds %f4, %f8, %f4 ! FGA - fmuls %f0, M3, %f7 ! FGM Group f5 available - fmuls %f1, M7, %f11 ! FGM Group f9 available - fadds %f5, %f9, %f5 ! FGA - fmuls %f2, M8, %f12 ! FGM Group f6 available - fmuls %f2, M9, %f13 ! FGM Group f10, f4 available - fadds %f6, %f10, %f6 ! FGA - fmuls %f2, M10, %f14 ! FGM Group f7 available - fmuls %f2, M11, %f15 ! FGM Group f11, f5 available - fadds %f7, %f11, %f7 ! FGA - fmuls %f3, M12, %f8 ! FGM Group f12 available - fadds %f4, %f12, %f4 ! FGA - fmuls %f3, M13, %f9 ! FGM Group f13, f6 available - fadds %f5, %f13, %f5 ! FGA - fmuls %f3, M14, %f10 ! FGM Group f14 available - fadds %f6, %f14, %f6 ! FGA - fmuls %f3, M15, %f11 ! FGM Group f15, f7 available - fadds %f7, %f15, %f7 ! FGA - fadds %f4, %f8, %f4 ! FGA Group f8, f4 available - st %f4, [%g2 + 0x00] ! LSU - fadds %f5, %f9, %f5 ! FGA Group f9, f5 available - st %f5, [%g2 + 0x04] ! LSU - fadds %f6, %f10, %f6 ! FGA Group f10, f6 available - st %f6, [%g2 + 0x08] ! LSU - fadds %f7, %f11, %f7 ! FGA Group f11, f7 available - st %f7, [%g2 + 0x0c] ! LSU - cmp %o1, %g3 ! IEU1 - bne 1b ! CTI - add %g2, 0x10, %g2 ! IEU0 Group -2: - ba __set_v4f_4 - nop - - .globl _mesa_sparc_transform_points4_identity -_mesa_sparc_transform_points4_identity: - ld [%o2 + V4F_STRIDE], %o5 - LDPTR [%o2 + V4F_START], %g1 - LDPTR [%o0 + V4F_START], %g2 - ld [%o2 + V4F_COUNT], %g3 - - cmp %g3, 0 - st %g3, [%o0 + V4F_COUNT] - be 2f - clr %o1 - -1: ld [%g1 + 0x00], %f0 - ld [%g1 + 0x04], %f1 - ld [%g1 + 0x08], %f2 - add %o1, 1, %o1 - ld [%g1 + 0x0c], %f3 - add %g1, %o5, %g1 - st %f0, [%g2 + 0x00] - st %f1, [%g2 + 0x04] - st %f2, [%g2 + 0x08] - cmp %o1, %g3 - st %f3, [%g2 + 0x0c] - bne 1b - add %g2, 0x10, %g2 -2: - ba __set_v4f_4 - nop - - .globl _mesa_sparc_transform_points4_2d -_mesa_sparc_transform_points4_2d: - ld [%o2 + V4F_STRIDE], %o5 - LDPTR [%o2 + V4F_START], %g1 - LDPTR [%o0 + V4F_START], %g2 - ld [%o2 + V4F_COUNT], %g3 - - LDMATRIX_0_1_4_5_12_13(%o1) - - cmp %g3, 0 - st %g3, [%o0 + V4F_COUNT] - be 2f - clr %o1 - -1: ld [%g1 + 0x00], %f0 ! LSU Group - ld [%g1 + 0x04], %f1 ! LSU Group - ld [%g1 + 0x08], %f2 ! LSU Group - ld [%g1 + 0x0c], %f3 ! LSU Group - add %o1, 1, %o1 ! IEU0 - add %g1, %o5, %g1 ! IEU1 - fmuls %f0, M0, %f4 ! FGM - fmuls %f1, M4, %f8 ! FGM Group - fmuls %f0, M1, %f5 ! FGM Group - fmuls %f1, M5, %f9 ! FGM Group f4 available - fmuls %f3, M12, %f12 ! FGM Group - fmuls %f3, M13, %f13 ! FGM Group f8 available - fadds %f4, %f8, %f4 ! FGA - fadds %f5, %f9, %f5 ! FGA Group stall, f5, f9 available - fadds %f4, %f12, %f4 ! FGA Group 2 cycle stall, f4, f12, f13 avail - st %f4, [%g2 + 0x00] ! LSU - fadds %f5, %f13, %f5 ! FGA Group f5 available - st %f5, [%g2 + 0x04] ! LSU - st %f2, [%g2 + 0x08] ! LSU Group - st %f3, [%g2 + 0x0c] ! LSU Group - cmp %o1, %g3 ! IEU1 - bne 1b ! CTI - add %g2, 0x10, %g2 ! IEU0 Group -2: - ba __set_v4f_4 - nop - - .globl _mesa_sparc_transform_points4_2d_no_rot -_mesa_sparc_transform_points4_2d_no_rot: - ld [%o2 + V4F_STRIDE], %o5 - LDPTR [%o2 + V4F_START], %g1 - LDPTR [%o0 + V4F_START], %g2 - ld [%o2 + V4F_COUNT], %g3 - - LDMATRIX_0_1_4_5_12_13(%o1) - - cmp %g3, 0 - st %g3, [%o0 + V4F_COUNT] - be 2f - clr %o1 - -1: ld [%g1 + 0x00], %f0 - ld [%g1 + 0x04], %f1 - ld [%g1 + 0x08], %f2 - ld [%g1 + 0x0c], %f3 - add %o1, 1, %o1 - add %g1, %o5, %g1 - fmuls %f0, M0, %f4 - fmuls %f3, M12, %f8 - fmuls %f1, M5, %f5 - fmuls %f3, M13, %f9 - fadds %f4, %f8, %f4 - st %f4, [%g2 + 0x00] - fadds %f5, %f9, %f5 - st %f5, [%g2 + 0x04] - st %f2, [%g2 + 0x08] - st %f3, [%g2 + 0x0c] - cmp %o1, %g3 - bne 1b - add %g2, 0x10, %g2 -2: - ba __set_v4f_4 - nop - - .globl _mesa_sparc_transform_points4_3d -_mesa_sparc_transform_points4_3d: - ld [%o2 + V4F_STRIDE], %o5 - LDPTR [%o2 + V4F_START], %g1 - LDPTR [%o0 + V4F_START], %g2 - ld [%o2 + V4F_COUNT], %g3 - - LDMATRIX_0_1_2_4_5_6_8_9_10_12_13_14(%o1) - - cmp %g3, 0 - st %g3, [%o0 + V4F_COUNT] - be 2f - clr %o1 - -1: ld [%g1 + 0x00], %f0 ! LSU Group - ld [%g1 + 0x04], %f1 ! LSU Group - ld [%g1 + 0x08], %f2 ! LSU Group - ld [%g1 + 0x0c], %f3 ! LSU Group - add %o1, 1, %o1 ! IEU0 - add %g1, %o5, %g1 ! IEU1 - fmuls %f0, M0, %f4 ! FGM - fmuls %f1, M4, %f7 ! FGM Group - fmuls %f0, M1, %f5 ! FGM Group - fmuls %f1, M5, %f8 ! FGM Group - fmuls %f0, M2, %f6 ! FGM Group f4 available - fmuls %f1, M6, %f9 ! FGM Group f7 available - fadds %f4, %f7, %f4 ! FGA - fmuls %f2, M8, %f10 ! FGM Group f5 available - fmuls %f2, M9, %f11 ! FGM Group f8 available - fadds %f5, %f8, %f5 ! FGA - fmuls %f2, M10, %f12 ! FGM Group f6 available - fmuls %f3, M12, %f13 ! FGM Group f9, f4 available - fadds %f6, %f9, %f6 ! FGA - fmuls %f3, M13, %f14 ! FGM Group f10 available - fadds %f4, %f10, %f4 ! FGA - fmuls %f3, M14, %f15 ! FGM Group f11, f5 available - fadds %f5, %f11, %f5 ! FGA - fadds %f6, %f12, %f6 ! FGA Group stall, f12, f13, f6 available - fadds %f4, %f13, %f4 ! FGA Group f14, f4 available - st %f4, [%g2 + 0x00] ! LSU - fadds %f5, %f14, %f5 ! FGA Group f15, f5 available - st %f5, [%g2 + 0x04] ! LSU - fadds %f6, %f15, %f6 ! FGA Group f6 available - st %f6, [%g2 + 0x08] ! LSU - st %f3, [%g2 + 0x0c] ! LSU Group - cmp %o1, %g3 ! IEU1 - bne 1b ! CTI - add %g2, 0x10, %g2 ! IEU0 Group -2: - ba __set_v4f_4 - nop - - .globl _mesa_sparc_transform_points4_3d_no_rot -_mesa_sparc_transform_points4_3d_no_rot: - ld [%o2 + V4F_STRIDE], %o5 - LDPTR [%o2 + V4F_START], %g1 - LDPTR [%o0 + V4F_START], %g2 - ld [%o2 + V4F_COUNT], %g3 - - LDMATRIX_0_5_10_12_13_14(%o1) - - cmp %g3, 0 - st %g3, [%o0 + V4F_COUNT] - be 2f - clr %o1 - -1: ld [%g1 + 0x00], %f0 ! LSU Group - ld [%g1 + 0x04], %f1 ! LSU Group - ld [%g1 + 0x08], %f2 ! LSU Group - ld [%g1 + 0x0c], %f3 ! LSU Group - add %o1, 1, %o1 ! IEU0 - add %g1, %o5, %g1 ! IEU1 - fmuls %f0, M0, %f4 ! FGM - fmuls %f3, M12, %f7 ! FGM Group - fmuls %f1, M5, %f5 ! FGM Group - fmuls %f3, M13, %f8 ! FGM Group - fmuls %f2, M10, %f6 ! FGM Group f4 available - fmuls %f3, M14, %f9 ! FGM Group f7 available - fadds %f4, %f7, %f4 ! FGA - st %f4, [%g2 + 0x00] ! LSU - fadds %f5, %f8, %f5 ! FGA Group stall, f5, f8 available - st %f5, [%g2 + 0x04] ! LSU - fadds %f6, %f9, %f6 ! FGA Group stall, f6, f9 available - st %f6, [%g2 + 0x08] ! LSU - st %f3, [%g2 + 0x0c] ! LSU Group - cmp %o1, %g3 ! IEU1 - bne 1b ! CTI - add %g2, 0x10, %g2 ! IEU0 Group -2: - ba __set_v4f_4 - nop - - .globl _mesa_sparc_transform_points4_perspective -_mesa_sparc_transform_points4_perspective: - ld [%o2 + V4F_STRIDE], %o5 - LDPTR [%o2 + V4F_START], %g1 - LDPTR [%o0 + V4F_START], %g2 - ld [%o2 + V4F_COUNT], %g3 - - LDMATRIX_0_5_8_9_10_14(%o1) - - cmp %g3, 0 - st %g3, [%o0 + V4F_COUNT] - be 2f - clr %o1 - -1: ld [%g1 + 0x00], %f0 ! LSU Group - ld [%g1 + 0x04], %f1 ! LSU Group - ld [%g1 + 0x08], %f2 ! LSU Group - ld [%g1 + 0x0c], %f3 ! LSU Group - add %o1, 1, %o1 ! IEU0 - add %g1, %o5, %g1 ! IEU1 - fmuls %f0, M0, %f4 ! FGM - fmuls %f2, M8, %f7 ! FGM Group - fmuls %f1, M5, %f5 ! FGM Group - fmuls %f2, M9, %f8 ! FGM Group - fmuls %f2, M10, %f6 ! FGM Group f4 available - fmuls %f3, M14, %f9 ! FGM Group f7 available - fadds %f4, %f7, %f4 ! FGA - st %f4, [%g2 + 0x00] ! LSU - fadds %f5, %f8, %f5 ! FGA Group stall, f5, f8 available - st %f5, [%g2 + 0x04] ! LSU - fadds %f6, %f9, %f6 ! FGA Group stall, f6, f9 available - st %f6, [%g2 + 0x08] ! LSU - fnegs %f2, %f7 ! FGA Group - st %f7, [%g2 + 0x0c] ! LSU - cmp %o1, %g3 ! IEU1 - bne 1b ! CTI - add %g2, 0x10, %g2 ! IEU0 Group -2: - ba __set_v4f_4 - nop diff --git a/src/mesa/swrast/NOTES b/src/mesa/swrast/NOTES deleted file mode 100644 index ea373aa..0000000 --- a/src/mesa/swrast/NOTES +++ /dev/null @@ -1,55 +0,0 @@ -INTRODUCTION - -Mesa's native software rasterizer. This module provides the fallback -paths for rasterization operations and states that aren't accelerated -in hardware drivers, and as the full rasterization engine in software -drivers. - -The swrast module 'stands alone', relying only on interfaces to core -mesa and it's own driver interface. It knows nothing about the tnl or -other modules, allowing it to be used for fallback paths in future tnl -schemes without modification. - -As well as providing triangle/line/point rasterization functionality, -the module provides implementations of the pixel operations -(ReadPixels, etc), and texture operations (CopyTexSubImage) which may -be plugged in to the core Mesa driver interface where accelerated -versions of these operations are unavailable. - - -STATE - -To create and destroy the module: - - GLboolean _swrast_CreateContext( struct gl_context *ctx ); - void _swrast_DestroyContext( struct gl_context *ctx ); - -This module tracks state changes internally and maintains derived -values based on the current state. For this to work, the driver -ensure the following funciton is called whenever the state changes and -the swsetup module is 'awake': - - void _swrast_InvalidateState( struct gl_context *ctx, GLuint new_state ); - -There is no explicit call to put the swrast module to sleep. - - -CUSTOMIZATION - - void (*choose_point)( struct gl_context * ); - void (*choose_line)( struct gl_context * ); - void (*choose_triangle)( struct gl_context * ); - -Drivers may add additional triangle/line/point functions to swrast by -overriding these functions. It is necessary for the driver to be very -careful that it doesn't return an inappropriate function, eg a -rasterization function in feedback mode. See the X11 driver for -examples. - -DRIVER INTERFACE - -The swrast device driver provides swrast primarily with span- and -pixel- level interfaces to a framebuffer, with a few additional hooks -for locking and setting the read buffer. - -See the definition of struct swrast_device_driver in swrast.h. \ No newline at end of file diff --git a/src/mesa/swrast/s_aaline.c b/src/mesa/swrast/s_aaline.c deleted file mode 100644 index 03f8fd9..0000000 --- a/src/mesa/swrast/s_aaline.c +++ /dev/null @@ -1,493 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -#include "c99_math.h" -#include "main/glheader.h" -#include "main/macros.h" -#include "main/mtypes.h" -#include "main/teximage.h" -#include "swrast/s_aaline.h" -#include "swrast/s_context.h" -#include "swrast/s_span.h" -#include "swrast/swrast.h" - - -#define SUB_PIXEL 4 - - -/* - * Info about the AA line we're rendering - */ -struct LineInfo -{ - GLfloat x0, y0; /* start */ - GLfloat x1, y1; /* end */ - GLfloat dx, dy; /* direction vector */ - GLfloat len; /* length */ - GLfloat halfWidth; /* half of line width */ - GLfloat xAdj, yAdj; /* X and Y adjustment for quad corners around line */ - /* for coverage computation */ - GLfloat qx0, qy0; /* quad vertices */ - GLfloat qx1, qy1; - GLfloat qx2, qy2; - GLfloat qx3, qy3; - GLfloat ex0, ey0; /* quad edge vectors */ - GLfloat ex1, ey1; - GLfloat ex2, ey2; - GLfloat ex3, ey3; - - /* DO_Z */ - GLfloat zPlane[4]; - /* DO_RGBA - always enabled */ - GLfloat rPlane[4], gPlane[4], bPlane[4], aPlane[4]; - /* DO_ATTRIBS */ - GLfloat wPlane[4]; - GLfloat attrPlane[VARYING_SLOT_MAX][4][4]; - GLfloat lambda[VARYING_SLOT_MAX]; - GLfloat texWidth[VARYING_SLOT_MAX]; - GLfloat texHeight[VARYING_SLOT_MAX]; - - SWspan span; -}; - - - -/* - * Compute the equation of a plane used to interpolate line fragment data - * such as color, Z, texture coords, etc. - * Input: (x0, y0) and (x1,y1) are the endpoints of the line. - * z0, and z1 are the end point values to interpolate. - * Output: plane - the plane equation. - * - * Note: we don't really have enough parameters to specify a plane. - * We take the endpoints of the line and compute a plane such that - * the cross product of the line vector and the plane normal is - * parallel to the projection plane. - */ -static void -compute_plane(GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, - GLfloat z0, GLfloat z1, GLfloat plane[4]) -{ -#if 0 - /* original */ - const GLfloat px = x1 - x0; - const GLfloat py = y1 - y0; - const GLfloat pz = z1 - z0; - const GLfloat qx = -py; - const GLfloat qy = px; - const GLfloat qz = 0; - const GLfloat a = py * qz - pz * qy; - const GLfloat b = pz * qx - px * qz; - const GLfloat c = px * qy - py * qx; - const GLfloat d = -(a * x0 + b * y0 + c * z0); - plane[0] = a; - plane[1] = b; - plane[2] = c; - plane[3] = d; -#else - /* simplified */ - const GLfloat px = x1 - x0; - const GLfloat py = y1 - y0; - const GLfloat pz = z0 - z1; - const GLfloat a = pz * px; - const GLfloat b = pz * py; - const GLfloat c = px * px + py * py; - const GLfloat d = -(a * x0 + b * y0 + c * z0); - if (a == 0.0F && b == 0.0F && c == 0.0F && d == 0.0F) { - plane[0] = 0.0F; - plane[1] = 0.0F; - plane[2] = 1.0F; - plane[3] = 0.0F; - } - else { - plane[0] = a; - plane[1] = b; - plane[2] = c; - plane[3] = d; - } -#endif -} - - -static inline void -constant_plane(GLfloat value, GLfloat plane[4]) -{ - plane[0] = 0.0F; - plane[1] = 0.0F; - plane[2] = -1.0F; - plane[3] = value; -} - - -static inline GLfloat -solve_plane(GLfloat x, GLfloat y, const GLfloat plane[4]) -{ - const GLfloat z = (plane[3] + plane[0] * x + plane[1] * y) / -plane[2]; - return z; -} - -#define SOLVE_PLANE(X, Y, PLANE) \ - ((PLANE[3] + PLANE[0] * (X) + PLANE[1] * (Y)) / -PLANE[2]) - - -/* - * Return 1 / solve_plane(). - */ -static inline GLfloat -solve_plane_recip(GLfloat x, GLfloat y, const GLfloat plane[4]) -{ - const GLfloat denom = plane[3] + plane[0] * x + plane[1] * y; - if (denom == 0.0F) - return 0.0F; - else - return -plane[2] / denom; -} - - -/* - * Solve plane and return clamped GLchan value. - */ -static inline GLchan -solve_plane_chan(GLfloat x, GLfloat y, const GLfloat plane[4]) -{ - const GLfloat z = (plane[3] + plane[0] * x + plane[1] * y) / -plane[2]; -#if CHAN_TYPE == GL_FLOAT - return CLAMP(z, 0.0F, CHAN_MAXF); -#else - if (z < 0) - return 0; - else if (z > CHAN_MAX) - return CHAN_MAX; - return (GLchan) lroundf(z); -#endif -} - - -/* - * Compute mipmap level of detail. - */ -static inline GLfloat -compute_lambda(const GLfloat sPlane[4], const GLfloat tPlane[4], - GLfloat invQ, GLfloat width, GLfloat height) -{ - GLfloat dudx = sPlane[0] / sPlane[2] * invQ * width; - GLfloat dudy = sPlane[1] / sPlane[2] * invQ * width; - GLfloat dvdx = tPlane[0] / tPlane[2] * invQ * height; - GLfloat dvdy = tPlane[1] / tPlane[2] * invQ * height; - GLfloat r1 = dudx * dudx + dudy * dudy; - GLfloat r2 = dvdx * dvdx + dvdy * dvdy; - GLfloat rho2 = r1 + r2; - /* return log base 2 of rho */ - if (rho2 == 0.0F) - return 0.0; - else - return logf(rho2) * 1.442695f * 0.5f;/* 1.442695 = 1/log(2) */ -} - - - - -/* - * Fill in the samples[] array with the (x,y) subpixel positions of - * xSamples * ySamples sample positions. - * Note that the four corner samples are put into the first four - * positions of the array. This allows us to optimize for the common - * case of all samples being inside the polygon. - */ -static void -make_sample_table(GLint xSamples, GLint ySamples, GLfloat samples[][2]) -{ - const GLfloat dx = 1.0F / (GLfloat) xSamples; - const GLfloat dy = 1.0F / (GLfloat) ySamples; - GLint x, y; - GLint i; - - i = 4; - for (x = 0; x < xSamples; x++) { - for (y = 0; y < ySamples; y++) { - GLint j; - if (x == 0 && y == 0) { - /* lower left */ - j = 0; - } - else if (x == xSamples - 1 && y == 0) { - /* lower right */ - j = 1; - } - else if (x == 0 && y == ySamples - 1) { - /* upper left */ - j = 2; - } - else if (x == xSamples - 1 && y == ySamples - 1) { - /* upper right */ - j = 3; - } - else { - j = i++; - } - samples[j][0] = x * dx + 0.5F * dx; - samples[j][1] = y * dy + 0.5F * dy; - } - } -} - - - -/* - * Compute how much of the given pixel's area is inside the rectangle - * defined by vertices v0, v1, v2, v3. - * Vertices MUST be specified in counter-clockwise order. - * Return: coverage in [0, 1]. - */ -static GLfloat -compute_coveragef(const struct LineInfo *info, - GLint winx, GLint winy) -{ - static GLfloat samples[SUB_PIXEL * SUB_PIXEL][2]; - static GLboolean haveSamples = GL_FALSE; - const GLfloat x = (GLfloat) winx; - const GLfloat y = (GLfloat) winy; - GLint stop = 4, i; - GLfloat insideCount = SUB_PIXEL * SUB_PIXEL; - - if (!haveSamples) { - make_sample_table(SUB_PIXEL, SUB_PIXEL, samples); - haveSamples = GL_TRUE; - } - -#if 0 /*DEBUG*/ - { - const GLfloat area = dx0 * dy1 - dx1 * dy0; - assert(area >= 0.0); - } -#endif - - for (i = 0; i < stop; i++) { - const GLfloat sx = x + samples[i][0]; - const GLfloat sy = y + samples[i][1]; - const GLfloat fx0 = sx - info->qx0; - const GLfloat fy0 = sy - info->qy0; - const GLfloat fx1 = sx - info->qx1; - const GLfloat fy1 = sy - info->qy1; - const GLfloat fx2 = sx - info->qx2; - const GLfloat fy2 = sy - info->qy2; - const GLfloat fx3 = sx - info->qx3; - const GLfloat fy3 = sy - info->qy3; - /* cross product determines if sample is inside or outside each edge */ - GLfloat cross0 = (info->ex0 * fy0 - info->ey0 * fx0); - GLfloat cross1 = (info->ex1 * fy1 - info->ey1 * fx1); - GLfloat cross2 = (info->ex2 * fy2 - info->ey2 * fx2); - GLfloat cross3 = (info->ex3 * fy3 - info->ey3 * fx3); - /* Check if the sample is exactly on an edge. If so, let cross be a - * positive or negative value depending on the direction of the edge. - */ - if (cross0 == 0.0F) - cross0 = info->ex0 + info->ey0; - if (cross1 == 0.0F) - cross1 = info->ex1 + info->ey1; - if (cross2 == 0.0F) - cross2 = info->ex2 + info->ey2; - if (cross3 == 0.0F) - cross3 = info->ex3 + info->ey3; - if (cross0 < 0.0F || cross1 < 0.0F || cross2 < 0.0F || cross3 < 0.0F) { - /* point is outside quadrilateral */ - insideCount -= 1.0F; - stop = SUB_PIXEL * SUB_PIXEL; - } - } - if (stop == 4) - return 1.0F; - else - return insideCount * (1.0F / (SUB_PIXEL * SUB_PIXEL)); -} - - -typedef void (*plot_func)(struct gl_context *ctx, struct LineInfo *line, - int ix, int iy); - - - -/* - * Draw an AA line segment (called many times per line when stippling) - */ -static void -segment(struct gl_context *ctx, - struct LineInfo *line, - plot_func plot, - GLfloat t0, GLfloat t1) -{ - const GLfloat absDx = (line->dx < 0.0F) ? -line->dx : line->dx; - const GLfloat absDy = (line->dy < 0.0F) ? -line->dy : line->dy; - /* compute the actual segment's endpoints */ - const GLfloat x0 = line->x0 + t0 * line->dx; - const GLfloat y0 = line->y0 + t0 * line->dy; - const GLfloat x1 = line->x0 + t1 * line->dx; - const GLfloat y1 = line->y0 + t1 * line->dy; - - /* compute vertices of the line-aligned quadrilateral */ - line->qx0 = x0 - line->yAdj; - line->qy0 = y0 + line->xAdj; - line->qx1 = x0 + line->yAdj; - line->qy1 = y0 - line->xAdj; - line->qx2 = x1 + line->yAdj; - line->qy2 = y1 - line->xAdj; - line->qx3 = x1 - line->yAdj; - line->qy3 = y1 + line->xAdj; - /* compute the quad's edge vectors (for coverage calc) */ - line->ex0 = line->qx1 - line->qx0; - line->ey0 = line->qy1 - line->qy0; - line->ex1 = line->qx2 - line->qx1; - line->ey1 = line->qy2 - line->qy1; - line->ex2 = line->qx3 - line->qx2; - line->ey2 = line->qy3 - line->qy2; - line->ex3 = line->qx0 - line->qx3; - line->ey3 = line->qy0 - line->qy3; - - if (absDx > absDy) { - /* X-major line */ - GLfloat dydx = line->dy / line->dx; - GLfloat xLeft, xRight, yBot, yTop; - GLint ix, ixRight; - if (x0 < x1) { - xLeft = x0 - line->halfWidth; - xRight = x1 + line->halfWidth; - if (line->dy >= 0.0F) { - yBot = y0 - 3.0F * line->halfWidth; - yTop = y0 + line->halfWidth; - } - else { - yBot = y0 - line->halfWidth; - yTop = y0 + 3.0F * line->halfWidth; - } - } - else { - xLeft = x1 - line->halfWidth; - xRight = x0 + line->halfWidth; - if (line->dy <= 0.0F) { - yBot = y1 - 3.0F * line->halfWidth; - yTop = y1 + line->halfWidth; - } - else { - yBot = y1 - line->halfWidth; - yTop = y1 + 3.0F * line->halfWidth; - } - } - - /* scan along the line, left-to-right */ - ixRight = (GLint) (xRight + 1.0F); - - /*printf("avg span height: %g\n", yTop - yBot);*/ - for (ix = (GLint) xLeft; ix < ixRight; ix++) { - const GLint iyBot = (GLint) yBot; - const GLint iyTop = (GLint) (yTop + 1.0F); - GLint iy; - /* scan across the line, bottom-to-top */ - for (iy = iyBot; iy < iyTop; iy++) { - plot(ctx, line, ix, iy); - } - yBot += dydx; - yTop += dydx; - } - } - else { - /* Y-major line */ - GLfloat dxdy = line->dx / line->dy; - GLfloat yBot, yTop, xLeft, xRight; - GLint iy, iyTop; - if (y0 < y1) { - yBot = y0 - line->halfWidth; - yTop = y1 + line->halfWidth; - if (line->dx >= 0.0F) { - xLeft = x0 - 3.0F * line->halfWidth; - xRight = x0 + line->halfWidth; - } - else { - xLeft = x0 - line->halfWidth; - xRight = x0 + 3.0F * line->halfWidth; - } - } - else { - yBot = y1 - line->halfWidth; - yTop = y0 + line->halfWidth; - if (line->dx <= 0.0F) { - xLeft = x1 - 3.0F * line->halfWidth; - xRight = x1 + line->halfWidth; - } - else { - xLeft = x1 - line->halfWidth; - xRight = x1 + 3.0F * line->halfWidth; - } - } - - /* scan along the line, bottom-to-top */ - iyTop = (GLint) (yTop + 1.0F); - - /*printf("avg span width: %g\n", xRight - xLeft);*/ - for (iy = (GLint) yBot; iy < iyTop; iy++) { - const GLint ixLeft = (GLint) xLeft; - const GLint ixRight = (GLint) (xRight + 1.0F); - GLint ix; - /* scan across the line, left-to-right */ - for (ix = ixLeft; ix < ixRight; ix++) { - plot(ctx, line, ix, iy); - } - xLeft += dxdy; - xRight += dxdy; - } - } -} - - -#define NAME(x) aa_rgba_##x -#define DO_Z -#include "s_aalinetemp.h" - - -#define NAME(x) aa_general_rgba_##x -#define DO_Z -#define DO_ATTRIBS -#include "s_aalinetemp.h" - - - -void -_swrast_choose_aa_line_function(struct gl_context *ctx) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - - assert(ctx->Line.SmoothFlag); - - if (ctx->Texture._EnabledCoordUnits != 0 - || _swrast_use_fragment_program(ctx) - || (ctx->Light.Enabled && - ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) - || ctx->Fog.ColorSumEnabled - || swrast->_FogEnabled) { - swrast->Line = aa_general_rgba_line; - } - else { - swrast->Line = aa_rgba_line; - } -} diff --git a/src/mesa/swrast/s_aaline.h b/src/mesa/swrast/s_aaline.h deleted file mode 100644 index 6f21563..0000000 --- a/src/mesa/swrast/s_aaline.h +++ /dev/null @@ -1,38 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -#ifndef S_AALINE_H -#define S_AALINE_H - - -struct gl_context; - - -extern void -_swrast_choose_aa_line_function(struct gl_context *ctx); - - -#endif diff --git a/src/mesa/swrast/s_aalinetemp.h b/src/mesa/swrast/s_aalinetemp.h deleted file mode 100644 index 9997d03..0000000 --- a/src/mesa/swrast/s_aalinetemp.h +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -/* - * Antialiased line template. - */ - - -/* - * Function to render each fragment in the AA line. - * \param ix - integer fragment window X coordiante - * \param iy - integer fragment window Y coordiante - */ -static void -NAME(plot)(struct gl_context *ctx, struct LineInfo *line, int ix, int iy) -{ - const SWcontext *swrast = SWRAST_CONTEXT(ctx); - const GLfloat fx = (GLfloat) ix; - const GLfloat fy = (GLfloat) iy; - const GLfloat coverage = compute_coveragef(line, ix, iy); - const GLuint i = line->span.end; - - (void) swrast; - - if (coverage == 0.0F) - return; - - line->span.end++; - line->span.array->coverage[i] = coverage; - line->span.array->x[i] = ix; - line->span.array->y[i] = iy; - - /* - * Compute Z, color, texture coords, fog for the fragment by - * solving the plane equations at (ix,iy). - */ -#ifdef DO_Z - line->span.array->z[i] = (GLuint) solve_plane(fx, fy, line->zPlane); -#endif - line->span.array->rgba[i][RCOMP] = solve_plane_chan(fx, fy, line->rPlane); - line->span.array->rgba[i][GCOMP] = solve_plane_chan(fx, fy, line->gPlane); - line->span.array->rgba[i][BCOMP] = solve_plane_chan(fx, fy, line->bPlane); - line->span.array->rgba[i][ACOMP] = solve_plane_chan(fx, fy, line->aPlane); -#if defined(DO_ATTRIBS) - ATTRIB_LOOP_BEGIN - GLfloat (*attribArray)[4] = line->span.array->attribs[attr]; - if (attr >= VARYING_SLOT_TEX0 && attr < VARYING_SLOT_VAR0 - && !_swrast_use_fragment_program(ctx)) { - /* texcoord w/ divide by Q */ - const GLuint unit = attr - VARYING_SLOT_TEX0; - const GLfloat invQ = solve_plane_recip(fx, fy, line->attrPlane[attr][3]); - GLuint c; - for (c = 0; c < 3; c++) { - attribArray[i][c] = solve_plane(fx, fy, line->attrPlane[attr][c]) * invQ; - } - line->span.array->lambda[unit][i] - = compute_lambda(line->attrPlane[attr][0], - line->attrPlane[attr][1], invQ, - line->texWidth[attr], line->texHeight[attr]); - } - else { - /* non-texture attrib */ - const GLfloat invW = solve_plane_recip(fx, fy, line->wPlane); - GLuint c; - for (c = 0; c < 4; c++) { - attribArray[i][c] = solve_plane(fx, fy, line->attrPlane[attr][c]) * invW; - } - } - ATTRIB_LOOP_END -#endif - - if (line->span.end == SWRAST_MAX_WIDTH) { - _swrast_write_rgba_span(ctx, &(line->span)); - line->span.end = 0; /* reset counter */ - } -} - - - -/* - * Line setup - */ -static void -NAME(line)(struct gl_context *ctx, const SWvertex *v0, const SWvertex *v1) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - GLfloat tStart, tEnd; /* segment start, end along line length */ - GLboolean inSegment; - GLint iLen, i; - - /* Init the LineInfo struct */ - struct LineInfo line; - line.x0 = v0->attrib[VARYING_SLOT_POS][0]; - line.y0 = v0->attrib[VARYING_SLOT_POS][1]; - line.x1 = v1->attrib[VARYING_SLOT_POS][0]; - line.y1 = v1->attrib[VARYING_SLOT_POS][1]; - line.dx = line.x1 - line.x0; - line.dy = line.y1 - line.y0; - line.len = sqrtf(line.dx * line.dx + line.dy * line.dy); - line.halfWidth = 0.5F * CLAMP(ctx->Line.Width, - ctx->Const.MinLineWidthAA, - ctx->Const.MaxLineWidthAA); - - if (line.len == 0.0F || util_is_inf_or_nan(line.len)) - return; - - INIT_SPAN(line.span, GL_LINE); - line.span.arrayMask = SPAN_XY | SPAN_COVERAGE; - line.span.facing = swrast->PointLineFacing; - line.xAdj = line.dx / line.len * line.halfWidth; - line.yAdj = line.dy / line.len * line.halfWidth; - -#ifdef DO_Z - line.span.arrayMask |= SPAN_Z; - compute_plane(line.x0, line.y0, line.x1, line.y1, - v0->attrib[VARYING_SLOT_POS][2], v1->attrib[VARYING_SLOT_POS][2], line.zPlane); -#endif - line.span.arrayMask |= SPAN_RGBA; - if (ctx->Light.ShadeModel == GL_SMOOTH) { - compute_plane(line.x0, line.y0, line.x1, line.y1, - v0->color[RCOMP], v1->color[RCOMP], line.rPlane); - compute_plane(line.x0, line.y0, line.x1, line.y1, - v0->color[GCOMP], v1->color[GCOMP], line.gPlane); - compute_plane(line.x0, line.y0, line.x1, line.y1, - v0->color[BCOMP], v1->color[BCOMP], line.bPlane); - compute_plane(line.x0, line.y0, line.x1, line.y1, - v0->color[ACOMP], v1->color[ACOMP], line.aPlane); - } - else { - constant_plane(v1->color[RCOMP], line.rPlane); - constant_plane(v1->color[GCOMP], line.gPlane); - constant_plane(v1->color[BCOMP], line.bPlane); - constant_plane(v1->color[ACOMP], line.aPlane); - } -#if defined(DO_ATTRIBS) - { - const GLfloat invW0 = v0->attrib[VARYING_SLOT_POS][3]; - const GLfloat invW1 = v1->attrib[VARYING_SLOT_POS][3]; - line.span.arrayMask |= SPAN_LAMBDA; - compute_plane(line.x0, line.y0, line.x1, line.y1, invW0, invW1, line.wPlane); - ATTRIB_LOOP_BEGIN - GLuint c; - if (swrast->_InterpMode[attr] == GL_FLAT) { - for (c = 0; c < 4; c++) { - constant_plane(v1->attrib[attr][c], line.attrPlane[attr][c]); - } - } - else { - for (c = 0; c < 4; c++) { - const GLfloat a0 = v0->attrib[attr][c] * invW0; - const GLfloat a1 = v1->attrib[attr][c] * invW1; - compute_plane(line.x0, line.y0, line.x1, line.y1, a0, a1, - line.attrPlane[attr][c]); - } - } - line.span.arrayAttribs |= BITFIELD64_BIT(attr); - if (attr >= VARYING_SLOT_TEX0 && attr < VARYING_SLOT_VAR0) { - const GLuint u = attr - VARYING_SLOT_TEX0; - const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current; - if (obj) { - const struct gl_texture_image *texImage = - _mesa_base_tex_image(obj); - line.texWidth[attr] = (GLfloat) texImage->Width; - line.texHeight[attr] = (GLfloat) texImage->Height; - } - } - ATTRIB_LOOP_END - } -#endif - - tStart = tEnd = 0.0; - inSegment = GL_FALSE; - iLen = (GLint) line.len; - - if (ctx->Line.StippleFlag) { - for (i = 0; i < iLen; i++) { - const GLuint bit = (swrast->StippleCounter / ctx->Line.StippleFactor) & 0xf; - if ((1 << bit) & ctx->Line.StipplePattern) { - /* stipple bit is on */ - const GLfloat t = (GLfloat) i / (GLfloat) line.len; - if (!inSegment) { - /* start new segment */ - inSegment = GL_TRUE; - tStart = t; - } - else { - /* still in the segment, extend it */ - tEnd = t; - } - } - else { - /* stipple bit is off */ - if (inSegment && (tEnd > tStart)) { - /* draw the segment */ - segment(ctx, &line, NAME(plot), tStart, tEnd); - inSegment = GL_FALSE; - } - else { - /* still between segments, do nothing */ - } - } - swrast->StippleCounter++; - } - - if (inSegment) { - /* draw the final segment of the line */ - segment(ctx, &line, NAME(plot), tStart, 1.0F); - } - } - else { - /* non-stippled */ - segment(ctx, &line, NAME(plot), 0.0, 1.0); - } - - _swrast_write_rgba_span(ctx, &(line.span)); -} - - - - -#undef DO_Z -#undef DO_ATTRIBS -#undef NAME diff --git a/src/mesa/swrast/s_aatriangle.c b/src/mesa/swrast/s_aatriangle.c deleted file mode 100644 index 342b6e9..0000000 --- a/src/mesa/swrast/s_aatriangle.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -/* - * Antialiased Triangle rasterizers - */ - - -#include "main/glheader.h" -#include "main/context.h" -#include "main/macros.h" -#include "main/state.h" -#include "s_aatriangle.h" -#include "s_context.h" -#include "s_span.h" - - -/* - * Compute coefficients of a plane using the X,Y coords of the v0, v1, v2 - * vertices and the given Z values. - * A point (x,y,z) lies on plane iff a*x+b*y+c*z+d = 0. - */ -static inline void -compute_plane(const GLfloat v0[], const GLfloat v1[], const GLfloat v2[], - GLfloat z0, GLfloat z1, GLfloat z2, GLfloat plane[4]) -{ - const GLfloat px = v1[0] - v0[0]; - const GLfloat py = v1[1] - v0[1]; - const GLfloat pz = z1 - z0; - - const GLfloat qx = v2[0] - v0[0]; - const GLfloat qy = v2[1] - v0[1]; - const GLfloat qz = z2 - z0; - - /* Crossproduct "(a,b,c):= dv1 x dv2" is orthogonal to plane. */ - const GLfloat a = py * qz - pz * qy; - const GLfloat b = pz * qx - px * qz; - const GLfloat c = px * qy - py * qx; - /* Point on the plane = "r*(a,b,c) + w", with fixed "r" depending - on the distance of plane from origin and arbitrary "w" parallel - to the plane. */ - /* The scalar product "(r*(a,b,c)+w)*(a,b,c)" is "r*(a^2+b^2+c^2)", - which is equal to "-d" below. */ - const GLfloat d = -(a * v0[0] + b * v0[1] + c * z0); - - plane[0] = a; - plane[1] = b; - plane[2] = c; - plane[3] = d; -} - - -/* - * Compute coefficients of a plane with a constant Z value. - */ -static inline void -constant_plane(GLfloat value, GLfloat plane[4]) -{ - plane[0] = 0.0; - plane[1] = 0.0; - plane[2] = -1.0; - plane[3] = value; -} - -#define CONSTANT_PLANE(VALUE, PLANE) \ -do { \ - PLANE[0] = 0.0F; \ - PLANE[1] = 0.0F; \ - PLANE[2] = -1.0F; \ - PLANE[3] = VALUE; \ -} while (0) - - - -/* - * Solve plane equation for Z at (X,Y). - */ -static inline GLfloat -solve_plane(GLfloat x, GLfloat y, const GLfloat plane[4]) -{ - assert(plane[2] != 0.0F); - return (plane[3] + plane[0] * x + plane[1] * y) / -plane[2]; -} - - -#define SOLVE_PLANE(X, Y, PLANE) \ - ((PLANE[3] + PLANE[0] * (X) + PLANE[1] * (Y)) / -PLANE[2]) - - -/* - * Solve plane and return clamped GLchan value. - */ -static inline GLchan -solve_plane_chan(GLfloat x, GLfloat y, const GLfloat plane[4]) -{ - const GLfloat z = (plane[3] + plane[0] * x + plane[1] * y) / -plane[2]; -#if CHAN_TYPE == GL_FLOAT - return CLAMP(z, 0.0F, CHAN_MAXF); -#else - if (z < 0) - return 0; - else if (z > CHAN_MAX) - return CHAN_MAX; - return (GLchan) lroundf(z); -#endif -} - - -static inline GLfloat -plane_dx(const GLfloat plane[4]) -{ - return -plane[0] / plane[2]; -} - -static inline GLfloat -plane_dy(const GLfloat plane[4]) -{ - return -plane[1] / plane[2]; -} - - - -/* - * Compute how much (area) of the given pixel is inside the triangle. - * Vertices MUST be specified in counter-clockwise order. - * Return: coverage in [0, 1]. - */ -static GLfloat -compute_coveragef(const GLfloat v0[3], const GLfloat v1[3], - const GLfloat v2[3], GLint winx, GLint winy) -{ - /* Given a position [0,3]x[0,3] return the sub-pixel sample position. - * Contributed by Ray Tice. - * - * Jitter sample positions - - * - average should be .5 in x & y for each column - * - each of the 16 rows and columns should be used once - * - the rectangle formed by the first four points - * should contain the other points - * - the distrubition should be fairly even in any given direction - * - * The pattern drawn below isn't optimal, but it's better than a regular - * grid. In the drawing, the center of each subpixel is surrounded by - * four dots. The "x" marks the jittered position relative to the - * subpixel center. - */ -#define POS(a, b) (0.5+a*4+b)/16 - static const GLfloat samples[16][2] = { - /* start with the four corners */ - { POS(0, 2), POS(0, 0) }, - { POS(3, 3), POS(0, 2) }, - { POS(0, 0), POS(3, 1) }, - { POS(3, 1), POS(3, 3) }, - /* continue with interior samples */ - { POS(1, 1), POS(0, 1) }, - { POS(2, 0), POS(0, 3) }, - { POS(0, 3), POS(1, 3) }, - { POS(1, 2), POS(1, 0) }, - { POS(2, 3), POS(1, 2) }, - { POS(3, 2), POS(1, 1) }, - { POS(0, 1), POS(2, 2) }, - { POS(1, 0), POS(2, 1) }, - { POS(2, 1), POS(2, 3) }, - { POS(3, 0), POS(2, 0) }, - { POS(1, 3), POS(3, 0) }, - { POS(2, 2), POS(3, 2) } - }; - - const GLfloat x = (GLfloat) winx; - const GLfloat y = (GLfloat) winy; - const GLfloat dx0 = v1[0] - v0[0]; - const GLfloat dy0 = v1[1] - v0[1]; - const GLfloat dx1 = v2[0] - v1[0]; - const GLfloat dy1 = v2[1] - v1[1]; - const GLfloat dx2 = v0[0] - v2[0]; - const GLfloat dy2 = v0[1] - v2[1]; - GLint stop = 4, i; - GLfloat insideCount = 16.0F; - - assert(dx0 * dy1 - dx1 * dy0 >= 0.0); /* area >= 0.0 */ - - for (i = 0; i < stop; i++) { - const GLfloat sx = x + samples[i][0]; - const GLfloat sy = y + samples[i][1]; - /* cross product determines if sample is inside or outside each edge */ - GLfloat cross = (dx0 * (sy - v0[1]) - dy0 * (sx - v0[0])); - /* Check if the sample is exactly on an edge. If so, let cross be a - * positive or negative value depending on the direction of the edge. - */ - if (cross == 0.0F) - cross = dx0 + dy0; - if (cross < 0.0F) { - /* sample point is outside first edge */ - insideCount -= 1.0F; - stop = 16; - } - else { - /* sample point is inside first edge */ - cross = (dx1 * (sy - v1[1]) - dy1 * (sx - v1[0])); - if (cross == 0.0F) - cross = dx1 + dy1; - if (cross < 0.0F) { - /* sample point is outside second edge */ - insideCount -= 1.0F; - stop = 16; - } - else { - /* sample point is inside first and second edges */ - cross = (dx2 * (sy - v2[1]) - dy2 * (sx - v2[0])); - if (cross == 0.0F) - cross = dx2 + dy2; - if (cross < 0.0F) { - /* sample point is outside third edge */ - insideCount -= 1.0F; - stop = 16; - } - } - } - } - if (stop == 4) - return 1.0F; - else - return insideCount * (1.0F / 16.0F); -} - - - -static void -rgba_aa_tri(struct gl_context *ctx, - const SWvertex *v0, - const SWvertex *v1, - const SWvertex *v2) -{ -#define DO_Z -#include "s_aatritemp.h" -} - - -static void -general_aa_tri(struct gl_context *ctx, - const SWvertex *v0, - const SWvertex *v1, - const SWvertex *v2) -{ -#define DO_Z -#define DO_ATTRIBS -#include "s_aatritemp.h" -} - - - -/* - * Examine GL state and set swrast->Triangle to an - * appropriate antialiased triangle rasterizer function. - */ -void -_swrast_set_aa_triangle_function(struct gl_context *ctx) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - - assert(ctx->Polygon.SmoothFlag); - - if (ctx->Texture._EnabledCoordUnits != 0 - || _swrast_use_fragment_program(ctx) - || swrast->_FogEnabled - || _mesa_need_secondary_color(ctx)) { - SWRAST_CONTEXT(ctx)->Triangle = general_aa_tri; - } - else { - SWRAST_CONTEXT(ctx)->Triangle = rgba_aa_tri; - } - - assert(SWRAST_CONTEXT(ctx)->Triangle); -} diff --git a/src/mesa/swrast/s_aatriangle.h b/src/mesa/swrast/s_aatriangle.h deleted file mode 100644 index 2386b1a..0000000 --- a/src/mesa/swrast/s_aatriangle.h +++ /dev/null @@ -1,38 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -#ifndef S_AATRIANGLE_H -#define S_AATRIANGLE_H - - -struct gl_context; - - -extern void -_swrast_set_aa_triangle_function(struct gl_context *ctx); - - -#endif diff --git a/src/mesa/swrast/s_aatritemp.h b/src/mesa/swrast/s_aatritemp.h deleted file mode 100644 index 1de6272..0000000 --- a/src/mesa/swrast/s_aatritemp.h +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -/* - * Antialiased Triangle Rasterizer Template - * - * This file is #include'd to generate custom AA triangle rasterizers. - * NOTE: this code hasn't been optimized yet. That'll come after it - * works correctly. - * - * The following macros may be defined to indicate what auxillary information - * must be copmuted across the triangle: - * DO_Z - if defined, compute Z values - * DO_ATTRIBS - if defined, compute texcoords, varying, etc. - */ - -/*void triangle( struct gl_context *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint pv )*/ -{ - const SWcontext *swrast = SWRAST_CONTEXT(ctx); - const GLfloat *p0 = v0->attrib[VARYING_SLOT_POS]; - const GLfloat *p1 = v1->attrib[VARYING_SLOT_POS]; - const GLfloat *p2 = v2->attrib[VARYING_SLOT_POS]; - const SWvertex *vMin, *vMid, *vMax; - GLint iyMin, iyMax; - GLfloat yMin, yMax; - GLboolean ltor; - GLfloat majDx, majDy; /* major (i.e. long) edge dx and dy */ - - SWspan span; - -#ifdef DO_Z - GLfloat zPlane[4]; -#endif - GLfloat rPlane[4], gPlane[4], bPlane[4], aPlane[4]; -#if defined(DO_ATTRIBS) - GLfloat attrPlane[VARYING_SLOT_MAX][4][4]; - GLfloat wPlane[4]; /* win[3] */ -#endif - GLfloat bf = SWRAST_CONTEXT(ctx)->_BackfaceCullSign; - - (void) swrast; - - INIT_SPAN(span, GL_POLYGON); - span.arrayMask = SPAN_COVERAGE; - - /* determine bottom to top order of vertices */ - { - GLfloat y0 = v0->attrib[VARYING_SLOT_POS][1]; - GLfloat y1 = v1->attrib[VARYING_SLOT_POS][1]; - GLfloat y2 = v2->attrib[VARYING_SLOT_POS][1]; - if (y0 <= y1) { - if (y1 <= y2) { - vMin = v0; vMid = v1; vMax = v2; /* y0<=y1<=y2 */ - } - else if (y2 <= y0) { - vMin = v2; vMid = v0; vMax = v1; /* y2<=y0<=y1 */ - } - else { - vMin = v0; vMid = v2; vMax = v1; bf = -bf; /* y0<=y2<=y1 */ - } - } - else { - if (y0 <= y2) { - vMin = v1; vMid = v0; vMax = v2; bf = -bf; /* y1<=y0<=y2 */ - } - else if (y2 <= y1) { - vMin = v2; vMid = v1; vMax = v0; bf = -bf; /* y2<=y1<=y0 */ - } - else { - vMin = v1; vMid = v2; vMax = v0; /* y1<=y2<=y0 */ - } - } - } - - majDx = vMax->attrib[VARYING_SLOT_POS][0] - vMin->attrib[VARYING_SLOT_POS][0]; - majDy = vMax->attrib[VARYING_SLOT_POS][1] - vMin->attrib[VARYING_SLOT_POS][1]; - - /* front/back-face determination and cullling */ - { - const GLfloat botDx = vMid->attrib[VARYING_SLOT_POS][0] - vMin->attrib[VARYING_SLOT_POS][0]; - const GLfloat botDy = vMid->attrib[VARYING_SLOT_POS][1] - vMin->attrib[VARYING_SLOT_POS][1]; - const GLfloat area = majDx * botDy - botDx * majDy; - /* Do backface culling */ - if (area * bf < 0 || area == 0 || util_is_inf_or_nan(area)) - return; - ltor = (GLboolean) (area < 0.0F); - - span.facing = area * swrast->_BackfaceSign > 0.0F; - } - - /* Plane equation setup: - * We evaluate plane equations at window (x,y) coordinates in order - * to compute color, Z, fog, texcoords, etc. This isn't terribly - * efficient but it's easy and reliable. - */ -#ifdef DO_Z - compute_plane(p0, p1, p2, p0[2], p1[2], p2[2], zPlane); - span.arrayMask |= SPAN_Z; -#endif - if (ctx->Light.ShadeModel == GL_SMOOTH) { - compute_plane(p0, p1, p2, v0->color[RCOMP], v1->color[RCOMP], v2->color[RCOMP], rPlane); - compute_plane(p0, p1, p2, v0->color[GCOMP], v1->color[GCOMP], v2->color[GCOMP], gPlane); - compute_plane(p0, p1, p2, v0->color[BCOMP], v1->color[BCOMP], v2->color[BCOMP], bPlane); - compute_plane(p0, p1, p2, v0->color[ACOMP], v1->color[ACOMP], v2->color[ACOMP], aPlane); - } - else { - constant_plane(v2->color[RCOMP], rPlane); - constant_plane(v2->color[GCOMP], gPlane); - constant_plane(v2->color[BCOMP], bPlane); - constant_plane(v2->color[ACOMP], aPlane); - } - span.arrayMask |= SPAN_RGBA; -#if defined(DO_ATTRIBS) - { - const GLfloat invW0 = v0->attrib[VARYING_SLOT_POS][3]; - const GLfloat invW1 = v1->attrib[VARYING_SLOT_POS][3]; - const GLfloat invW2 = v2->attrib[VARYING_SLOT_POS][3]; - compute_plane(p0, p1, p2, invW0, invW1, invW2, wPlane); - span.attrStepX[VARYING_SLOT_POS][3] = plane_dx(wPlane); - span.attrStepY[VARYING_SLOT_POS][3] = plane_dy(wPlane); - ATTRIB_LOOP_BEGIN - GLuint c; - if (swrast->_InterpMode[attr] == GL_FLAT) { - for (c = 0; c < 4; c++) { - constant_plane(v2->attrib[attr][c] * invW2, attrPlane[attr][c]); - } - } - else { - for (c = 0; c < 4; c++) { - const GLfloat a0 = v0->attrib[attr][c] * invW0; - const GLfloat a1 = v1->attrib[attr][c] * invW1; - const GLfloat a2 = v2->attrib[attr][c] * invW2; - compute_plane(p0, p1, p2, a0, a1, a2, attrPlane[attr][c]); - } - } - for (c = 0; c < 4; c++) { - span.attrStepX[attr][c] = plane_dx(attrPlane[attr][c]); - span.attrStepY[attr][c] = plane_dy(attrPlane[attr][c]); - } - ATTRIB_LOOP_END - } -#endif - - /* Begin bottom-to-top scan over the triangle. - * The long edge will either be on the left or right side of the - * triangle. We always scan from the long edge toward the shorter - * edges, stopping when we find that coverage = 0. If the long edge - * is on the left we scan left-to-right. Else, we scan right-to-left. - */ - yMin = vMin->attrib[VARYING_SLOT_POS][1]; - yMax = vMax->attrib[VARYING_SLOT_POS][1]; - iyMin = (GLint) yMin; - iyMax = (GLint) yMax + 1; - - if (ltor) { - /* scan left to right */ - const GLfloat *pMin = vMin->attrib[VARYING_SLOT_POS]; - const GLfloat *pMid = vMid->attrib[VARYING_SLOT_POS]; - const GLfloat *pMax = vMax->attrib[VARYING_SLOT_POS]; - const GLfloat dxdy = majDx / majDy; - const GLfloat xAdj = dxdy < 0.0F ? -dxdy : 0.0F; - GLint iy; -#ifdef _OPENMP -#pragma omp parallel for schedule(dynamic) private(iy) firstprivate(span) -#endif - for (iy = iyMin; iy < iyMax; iy++) { - GLfloat x = pMin[0] - (yMin - iy) * dxdy; - GLint ix, startX = (GLint) (x - xAdj); - GLuint count; - GLfloat coverage = 0.0F; - -#ifdef _OPENMP - /* each thread needs to use a different (global) SpanArrays variable */ - span.array = SWRAST_CONTEXT(ctx)->SpanArrays + omp_get_thread_num(); -#endif - /* skip over fragments with zero coverage */ - while (startX < SWRAST_MAX_WIDTH) { - coverage = compute_coveragef(pMin, pMid, pMax, startX, iy); - if (coverage > 0.0F) - break; - startX++; - } - - /* enter interior of triangle */ - ix = startX; - -#if defined(DO_ATTRIBS) - /* compute attributes at left-most fragment */ - span.attrStart[VARYING_SLOT_POS][3] = solve_plane(ix + 0.5F, iy + 0.5F, wPlane); - ATTRIB_LOOP_BEGIN - GLuint c; - for (c = 0; c < 4; c++) { - span.attrStart[attr][c] = solve_plane(ix + 0.5F, iy + 0.5F, attrPlane[attr][c]); - } - ATTRIB_LOOP_END -#endif - - count = 0; - while (coverage > 0.0F) { - /* (cx,cy) = center of fragment */ - const GLfloat cx = ix + 0.5F, cy = iy + 0.5F; - SWspanarrays *array = span.array; - array->coverage[count] = coverage; -#ifdef DO_Z - array->z[count] = (GLuint) solve_plane(cx, cy, zPlane); -#endif - array->rgba[count][RCOMP] = solve_plane_chan(cx, cy, rPlane); - array->rgba[count][GCOMP] = solve_plane_chan(cx, cy, gPlane); - array->rgba[count][BCOMP] = solve_plane_chan(cx, cy, bPlane); - array->rgba[count][ACOMP] = solve_plane_chan(cx, cy, aPlane); - ix++; - count++; - coverage = compute_coveragef(pMin, pMid, pMax, ix, iy); - } - - if (ix > startX) { - span.x = startX; - span.y = iy; - span.end = (GLuint) ix - (GLuint) startX; - _swrast_write_rgba_span(ctx, &span); - } - } - } - else { - /* scan right to left */ - const GLfloat *pMin = vMin->attrib[VARYING_SLOT_POS]; - const GLfloat *pMid = vMid->attrib[VARYING_SLOT_POS]; - const GLfloat *pMax = vMax->attrib[VARYING_SLOT_POS]; - const GLfloat dxdy = majDx / majDy; - const GLfloat xAdj = dxdy > 0 ? dxdy : 0.0F; - GLint iy; -#ifdef _OPENMP -#pragma omp parallel for schedule(dynamic) private(iy) firstprivate(span) -#endif - for (iy = iyMin; iy < iyMax; iy++) { - GLfloat x = pMin[0] - (yMin - iy) * dxdy; - GLint ix, left, startX = (GLint) (x + xAdj); - GLuint count, n; - GLfloat coverage = 0.0F; - -#ifdef _OPENMP - /* each thread needs to use a different (global) SpanArrays variable */ - span.array = SWRAST_CONTEXT(ctx)->SpanArrays + omp_get_thread_num(); -#endif - /* make sure we're not past the window edge */ - if (startX >= ctx->DrawBuffer->_Xmax) { - startX = ctx->DrawBuffer->_Xmax - 1; - } - - /* skip fragments with zero coverage */ - while (startX > 0) { - coverage = compute_coveragef(pMin, pMax, pMid, startX, iy); - if (coverage > 0.0F) - break; - startX--; - } - - /* enter interior of triangle */ - ix = startX; - count = 0; - while (coverage > 0.0F) { - /* (cx,cy) = center of fragment */ - const GLfloat cx = ix + 0.5F, cy = iy + 0.5F; - SWspanarrays *array = span.array; - assert(ix >= 0); - array->coverage[ix] = coverage; -#ifdef DO_Z - array->z[ix] = (GLuint) solve_plane(cx, cy, zPlane); -#endif - array->rgba[ix][RCOMP] = solve_plane_chan(cx, cy, rPlane); - array->rgba[ix][GCOMP] = solve_plane_chan(cx, cy, gPlane); - array->rgba[ix][BCOMP] = solve_plane_chan(cx, cy, bPlane); - array->rgba[ix][ACOMP] = solve_plane_chan(cx, cy, aPlane); - ix--; - count++; - coverage = compute_coveragef(pMin, pMax, pMid, ix, iy); - } - -#if defined(DO_ATTRIBS) - /* compute attributes at left-most fragment */ - span.attrStart[VARYING_SLOT_POS][3] = solve_plane(ix + 1.5F, iy + 0.5F, wPlane); - ATTRIB_LOOP_BEGIN - GLuint c; - for (c = 0; c < 4; c++) { - span.attrStart[attr][c] = solve_plane(ix + 1.5F, iy + 0.5F, attrPlane[attr][c]); - } - ATTRIB_LOOP_END -#endif - - if (startX > ix) { - n = (GLuint) startX - (GLuint) ix; - - left = ix + 1; - - /* shift all values to the left */ - /* XXX this is temporary */ - { - SWspanarrays *array = span.array; - GLint j; - for (j = 0; j < (GLint) n; j++) { - array->coverage[j] = array->coverage[j + left]; - COPY_CHAN4(array->rgba[j], array->rgba[j + left]); -#ifdef DO_Z - array->z[j] = array->z[j + left]; -#endif - } - } - - span.x = left; - span.y = iy; - span.end = n; - _swrast_write_rgba_span(ctx, &span); - } - } - } -} - - -#undef DO_Z -#undef DO_ATTRIBS -#undef DO_OCCLUSION_TEST diff --git a/src/mesa/swrast/s_alpha.c b/src/mesa/swrast/s_alpha.c deleted file mode 100644 index 841642f..0000000 --- a/src/mesa/swrast/s_alpha.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -/** - * \file swrast/s_alpha.c - * \brief Functions to apply alpha test. - */ - -#include "main/glheader.h" -#include "main/context.h" -#include "main/macros.h" - -#include "s_alpha.h" -#include "s_context.h" - - -#define ALPHA_TEST(ALPHA, LOOP_CODE) \ -do { \ - switch (ctx->Color.AlphaFunc) { \ - case GL_LESS: \ - for (i = 0; i < n; i++) { \ - mask[i] &= (ALPHA < ref); \ - LOOP_CODE; \ - } \ - break; \ - case GL_LEQUAL: \ - for (i = 0; i < n; i++) { \ - mask[i] &= (ALPHA <= ref); \ - LOOP_CODE; \ - } \ - break; \ - case GL_GEQUAL: \ - for (i = 0; i < n; i++) { \ - mask[i] &= (ALPHA >= ref); \ - LOOP_CODE; \ - } \ - break; \ - case GL_GREATER: \ - for (i = 0; i < n; i++) { \ - mask[i] &= (ALPHA > ref); \ - LOOP_CODE; \ - } \ - break; \ - case GL_NOTEQUAL: \ - for (i = 0; i < n; i++) { \ - mask[i] &= (ALPHA != ref); \ - LOOP_CODE; \ - } \ - break; \ - case GL_EQUAL: \ - for (i = 0; i < n; i++) { \ - mask[i] &= (ALPHA == ref); \ - LOOP_CODE; \ - } \ - break; \ - default: \ - _mesa_problem(ctx, "Invalid alpha test in _swrast_alpha_test" ); \ - return 0; \ - } \ -} while (0) - - - -/** - * Perform the alpha test for an array of pixels. - * For pixels that fail the test, mask[i] will be set to 0. - * \return 0 if all pixels in the span failed the alpha test, - * 1 if one or more pixels passed the alpha test. - */ -GLint -_swrast_alpha_test(const struct gl_context *ctx, SWspan *span) -{ - const GLuint n = span->end; - GLubyte *mask = span->array->mask; - GLuint i; - - if (ctx->Color.AlphaFunc == GL_ALWAYS) { - /* do nothing */ - return 1; - } - else if (ctx->Color.AlphaFunc == GL_NEVER) { - /* All pixels failed - caller should check for this return value and - * act accordingly. - */ - span->writeAll = GL_FALSE; - return 0; - } - - if (span->arrayMask & SPAN_RGBA) { - /* Use array's alpha values */ - if (span->array->ChanType == GL_UNSIGNED_BYTE) { - GLubyte (*rgba)[4] = span->array->rgba8; - GLubyte ref; - CLAMPED_FLOAT_TO_UBYTE(ref, ctx->Color.AlphaRef); - ALPHA_TEST(rgba[i][ACOMP], ;); - } - else if (span->array->ChanType == GL_UNSIGNED_SHORT) { - GLushort (*rgba)[4] = span->array->rgba16; - GLushort ref; - CLAMPED_FLOAT_TO_USHORT(ref, ctx->Color.AlphaRef); - ALPHA_TEST(rgba[i][ACOMP], ;); - } - else { - GLfloat (*rgba)[4] = span->array->attribs[VARYING_SLOT_COL0]; - const GLfloat ref = ctx->Color.AlphaRef; - ALPHA_TEST(rgba[i][ACOMP], ;); - } - } - else { - /* Interpolate alpha values */ - assert(span->interpMask & SPAN_RGBA); - if (span->array->ChanType == GL_UNSIGNED_BYTE) { - const GLfixed alphaStep = span->alphaStep; - GLfixed alpha = span->alpha; - GLubyte ref; - CLAMPED_FLOAT_TO_UBYTE(ref, ctx->Color.AlphaRef); - ALPHA_TEST(FixedToInt(alpha), alpha += alphaStep); - } - else if (span->array->ChanType == GL_UNSIGNED_SHORT) { - const GLfixed alphaStep = span->alphaStep; - GLfixed alpha = span->alpha; - GLushort ref; - CLAMPED_FLOAT_TO_USHORT(ref, ctx->Color.AlphaRef); - ALPHA_TEST(FixedToInt(alpha), alpha += alphaStep); - } - else { - const GLfloat alphaStep = FixedToFloat(span->alphaStep); - GLfloat alpha = FixedToFloat(span->alpha); - const GLfloat ref = ctx->Color.AlphaRef; - ALPHA_TEST(alpha, alpha += alphaStep); - } - } - - span->writeAll = GL_FALSE; - - /* XXX examine mask[] values? */ - return 1; -} diff --git a/src/mesa/swrast/s_alpha.h b/src/mesa/swrast/s_alpha.h deleted file mode 100644 index cc11262..0000000 --- a/src/mesa/swrast/s_alpha.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2002 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -#ifndef S_ALPHA_H -#define S_ALPHA_H - - -#include "main/glheader.h" -#include "s_span.h" - -struct gl_context; - -extern GLint -_swrast_alpha_test( const struct gl_context *ctx, SWspan *span ); - - -#endif diff --git a/src/mesa/swrast/s_atifragshader.c b/src/mesa/swrast/s_atifragshader.c deleted file mode 100644 index 414a414..0000000 --- a/src/mesa/swrast/s_atifragshader.c +++ /dev/null @@ -1,592 +0,0 @@ -/* - * Copyright (C) 2004 David Airlie All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * DAVID AIRLIE 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. - */ - -#include "main/glheader.h" -#include "main/macros.h" -#include "main/atifragshader.h" -#include "main/samplerobj.h" -#include "swrast/s_atifragshader.h" -#include "swrast/s_context.h" - -#define ATI_FS_INPUT_PRIMARY 0 -#define ATI_FS_INPUT_SECONDARY 1 - -/** - * State for executing ATI fragment shader. - */ -struct atifs_machine -{ - GLfloat Registers[6][4]; /** six temporary registers */ - GLfloat PrevPassRegisters[6][4]; - GLfloat Inputs[2][4]; /** Primary, secondary input colors */ -}; - - - -/** - * Fetch a texel. - */ -static void -fetch_texel(struct gl_context * ctx, const GLfloat texcoord[4], GLfloat lambda, - GLuint unit, GLfloat color[4]) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - - /* XXX use a float-valued TextureSample routine here!!! */ - swrast->TextureSample[unit](ctx, _mesa_get_samplerobj(ctx, unit), - ctx->Texture.Unit[unit]._Current, - 1, (const GLfloat(*)[4]) texcoord, - &lambda, (GLfloat (*)[4]) color); -} - -static void -apply_swizzle(GLfloat values[4], GLuint swizzle) -{ - GLfloat s, t, r, q; - - s = values[0]; - t = values[1]; - r = values[2]; - q = values[3]; - - switch (swizzle) { - case GL_SWIZZLE_STR_ATI: - values[0] = s; - values[1] = t; - values[2] = r; - break; - case GL_SWIZZLE_STQ_ATI: - values[0] = s; - values[1] = t; - values[2] = q; - break; - case GL_SWIZZLE_STR_DR_ATI: - values[0] = s / r; - values[1] = t / r; - values[2] = 1 / r; - break; - case GL_SWIZZLE_STQ_DQ_ATI: -/* make sure q is not 0 to avoid problems later with infinite values (texture lookup)? */ - if (q == 0.0F) - q = 0.000000001F; - values[0] = s / q; - values[1] = t / q; - values[2] = 1.0F / q; - break; - } - values[3] = 0.0; -} - -static void -apply_src_rep(GLint optype, GLuint rep, GLfloat * val) -{ - GLint i; - GLint start, end; - if (!rep) - return; - - start = optype ? 3 : 0; - end = 4; - - for (i = start; i < end; i++) { - switch (rep) { - case GL_RED: - val[i] = val[0]; - break; - case GL_GREEN: - val[i] = val[1]; - break; - case GL_BLUE: - val[i] = val[2]; - break; - case GL_ALPHA: - val[i] = val[3]; - break; - } - } -} - -static void -apply_src_mod(GLint optype, GLuint mod, GLfloat * val) -{ - GLint i; - GLint start, end; - - if (!mod) - return; - - start = optype ? 3 : 0; - end = 4; - - for (i = start; i < end; i++) { - if (mod & GL_COMP_BIT_ATI) - val[i] = 1 - val[i]; - - if (mod & GL_BIAS_BIT_ATI) - val[i] = val[i] - 0.5F; - - if (mod & GL_2X_BIT_ATI) - val[i] = 2 * val[i]; - - if (mod & GL_NEGATE_BIT_ATI) - val[i] = -val[i]; - } -} - -static void -apply_dst_mod(GLuint optype, GLuint mod, GLfloat * val) -{ - GLint i; - GLint has_sat = mod & GL_SATURATE_BIT_ATI; - GLint start, end; - - mod &= ~GL_SATURATE_BIT_ATI; - - start = optype ? 3 : 0; - end = optype ? 4 : 3; - - for (i = start; i < end; i++) { - switch (mod) { - case GL_2X_BIT_ATI: - val[i] = 2 * val[i]; - break; - case GL_4X_BIT_ATI: - val[i] = 4 * val[i]; - break; - case GL_8X_BIT_ATI: - val[i] = 8 * val[i]; - break; - case GL_HALF_BIT_ATI: - val[i] = val[i] * 0.5F; - break; - case GL_QUARTER_BIT_ATI: - val[i] = val[i] * 0.25F; - break; - case GL_EIGHTH_BIT_ATI: - val[i] = val[i] * 0.125F; - break; - } - - if (has_sat) { - if (val[i] < 0.0F) - val[i] = 0.0F; - else if (val[i] > 1.0F) - val[i] = 1.0F; - } - else { - if (val[i] < -8.0F) - val[i] = -8.0F; - else if (val[i] > 8.0F) - val[i] = 8.0F; - } - } -} - - -static void -write_dst_addr(GLuint optype, GLuint mod, GLuint mask, GLfloat * src, - GLfloat * dst) -{ - GLint i; - apply_dst_mod(optype, mod, src); - - if (optype == ATI_FRAGMENT_SHADER_COLOR_OP) { - if (mask) { - if (mask & GL_RED_BIT_ATI) - dst[0] = src[0]; - - if (mask & GL_GREEN_BIT_ATI) - dst[1] = src[1]; - - if (mask & GL_BLUE_BIT_ATI) - dst[2] = src[2]; - } - else { - for (i = 0; i < 3; i++) - dst[i] = src[i]; - } - } - else - dst[3] = src[3]; -} - -static void -finish_pass(struct atifs_machine *machine) -{ - GLint i; - - for (i = 0; i < 6; i++) { - COPY_4V(machine->PrevPassRegisters[i], machine->Registers[i]); - } -} - - -static void -handle_pass_op(struct atifs_machine *machine, struct atifs_setupinst *texinst, - const SWspan *span, GLuint column, GLuint idx) -{ - GLuint swizzle = texinst->swizzle; - GLuint pass_tex = texinst->src; - - if (pass_tex >= GL_TEXTURE0_ARB && pass_tex <= GL_TEXTURE7_ARB) { - pass_tex -= GL_TEXTURE0_ARB; - COPY_4V(machine->Registers[idx], - span->array->attribs[VARYING_SLOT_TEX0 + pass_tex][column]); - } - else if (pass_tex >= GL_REG_0_ATI && pass_tex <= GL_REG_5_ATI) { - pass_tex -= GL_REG_0_ATI; - COPY_4V(machine->Registers[idx], machine->PrevPassRegisters[pass_tex]); - } - apply_swizzle(machine->Registers[idx], swizzle); - -} - -static void -handle_sample_op(struct gl_context * ctx, struct atifs_machine *machine, - struct atifs_setupinst *texinst, const SWspan *span, - GLuint column, GLuint idx) -{ -/* sample from unit idx using texinst->src as coords */ - GLuint swizzle = texinst->swizzle; - GLuint coord_source = texinst->src; - GLfloat tex_coords[4] = { 0 }; - - if (coord_source >= GL_TEXTURE0_ARB && coord_source <= GL_TEXTURE7_ARB) { - coord_source -= GL_TEXTURE0_ARB; - COPY_4V(tex_coords, - span->array->attribs[VARYING_SLOT_TEX0 + coord_source][column]); - } - else if (coord_source >= GL_REG_0_ATI && coord_source <= GL_REG_5_ATI) { - coord_source -= GL_REG_0_ATI; - COPY_4V(tex_coords, machine->PrevPassRegisters[coord_source]); - } - apply_swizzle(tex_coords, swizzle); - fetch_texel(ctx, tex_coords, 0.0F, idx, machine->Registers[idx]); -} - -#define SETUP_SRC_REG(optype, i, x) \ -do { \ - COPY_4V(src[optype][i], x); \ -} while (0) - - - -/** - * Execute the given fragment shader. - * NOTE: we do everything in single-precision floating point - * \param ctx - rendering context - * \param shader - the shader to execute - * \param machine - virtual machine state - * \param span - the SWspan we're operating on - * \param column - which pixel [i] we're operating on in the span - */ -static void -execute_shader(struct gl_context *ctx, const struct ati_fragment_shader *shader, - struct atifs_machine *machine, const SWspan *span, - GLuint column) -{ - GLuint pc; - struct atifs_instruction *inst; - struct atifs_setupinst *texinst; - GLint optype; - GLuint i; - GLint j, pass; - GLint dstreg; - GLfloat src[2][3][4]; - GLfloat zeros[4] = { 0.0, 0.0, 0.0, 0.0 }; - GLfloat ones[4] = { 1.0, 1.0, 1.0, 1.0 }; - GLfloat dst[2][4], *dstp; - - for (pass = 0; pass < shader->NumPasses; pass++) { - if (pass > 0) - finish_pass(machine); - for (j = 0; j < MAX_NUM_FRAGMENT_REGISTERS_ATI; j++) { - texinst = &shader->SetupInst[pass][j]; - if (texinst->Opcode == ATI_FRAGMENT_SHADER_PASS_OP) - handle_pass_op(machine, texinst, span, column, j); - else if (texinst->Opcode == ATI_FRAGMENT_SHADER_SAMPLE_OP) - handle_sample_op(ctx, machine, texinst, span, column, j); - } - - for (pc = 0; pc < shader->numArithInstr[pass]; pc++) { - inst = &shader->Instructions[pass][pc]; - - /* setup the source registers for color and alpha ops */ - for (optype = 0; optype < 2; optype++) { - for (i = 0; i < inst->ArgCount[optype]; i++) { - GLint index = inst->SrcReg[optype][i].Index; - - if (index >= GL_REG_0_ATI && index <= GL_REG_5_ATI) - SETUP_SRC_REG(optype, i, - machine->Registers[index - GL_REG_0_ATI]); - else if (index >= GL_CON_0_ATI && index <= GL_CON_7_ATI) { - if (shader->LocalConstDef & (1 << (index - GL_CON_0_ATI))) { - SETUP_SRC_REG(optype, i, - shader->Constants[index - GL_CON_0_ATI]); - } else { - SETUP_SRC_REG(optype, i, - ctx->ATIFragmentShader.GlobalConstants[index - GL_CON_0_ATI]); - } - } - else if (index == GL_ONE) - SETUP_SRC_REG(optype, i, ones); - else if (index == GL_ZERO) - SETUP_SRC_REG(optype, i, zeros); - else if (index == GL_PRIMARY_COLOR_EXT) - SETUP_SRC_REG(optype, i, - machine->Inputs[ATI_FS_INPUT_PRIMARY]); - else if (index == GL_SECONDARY_INTERPOLATOR_ATI) - SETUP_SRC_REG(optype, i, - machine->Inputs[ATI_FS_INPUT_SECONDARY]); - - apply_src_rep(optype, inst->SrcReg[optype][i].argRep, - src[optype][i]); - apply_src_mod(optype, inst->SrcReg[optype][i].argMod, - src[optype][i]); - } - } - - /* Execute the operations - color then alpha */ - for (optype = 0; optype < 2; optype++) { - if (inst->Opcode[optype]) { - switch (inst->Opcode[optype]) { - case GL_ADD_ATI: - if (!optype) - for (i = 0; i < 3; i++) { - dst[optype][i] = - src[optype][0][i] + src[optype][1][i]; - } - else - dst[optype][3] = src[optype][0][3] + src[optype][1][3]; - break; - case GL_SUB_ATI: - if (!optype) - for (i = 0; i < 3; i++) { - dst[optype][i] = - src[optype][0][i] - src[optype][1][i]; - } - else - dst[optype][3] = src[optype][0][3] - src[optype][1][3]; - break; - case GL_MUL_ATI: - if (!optype) - for (i = 0; i < 3; i++) { - dst[optype][i] = - src[optype][0][i] * src[optype][1][i]; - } - else - dst[optype][3] = src[optype][0][3] * src[optype][1][3]; - break; - case GL_MAD_ATI: - if (!optype) - for (i = 0; i < 3; i++) { - dst[optype][i] = - src[optype][0][i] * src[optype][1][i] + - src[optype][2][i]; - } - else - dst[optype][3] = - src[optype][0][3] * src[optype][1][3] + - src[optype][2][3]; - break; - case GL_LERP_ATI: - if (!optype) - for (i = 0; i < 3; i++) { - dst[optype][i] = - src[optype][0][i] * src[optype][1][i] + (1 - - src - [optype] - [0][i]) * - src[optype][2][i]; - } - else - dst[optype][3] = - src[optype][0][3] * src[optype][1][3] + (1 - - src[optype] - [0][3]) * - src[optype][2][3]; - break; - - case GL_MOV_ATI: - if (!optype) - for (i = 0; i < 3; i++) { - dst[optype][i] = src[optype][0][i]; - } - else - dst[optype][3] = src[optype][0][3]; - break; - case GL_CND_ATI: - if (!optype) { - for (i = 0; i < 3; i++) { - dst[optype][i] = - (src[optype][2][i] > - 0.5F) ? src[optype][0][i] : src[optype][1][i]; - } - } - else { - dst[optype][3] = - (src[optype][2][3] > - 0.5F) ? src[optype][0][3] : src[optype][1][3]; - } - break; - - case GL_CND0_ATI: - if (!optype) - for (i = 0; i < 3; i++) { - dst[optype][i] = - (src[optype][2][i] >= - 0) ? src[optype][0][i] : src[optype][1][i]; - } - else { - dst[optype][3] = - (src[optype][2][3] >= - 0) ? src[optype][0][3] : src[optype][1][3]; - } - break; - case GL_DOT2_ADD_ATI: - { - GLfloat result; - - /* DOT 2 always uses the source from the color op */ - /* could save recalculation of dot products for alpha inst */ - result = src[0][0][0] * src[0][1][0] + - src[0][0][1] * src[0][1][1] + src[0][2][2]; - if (!optype) { - for (i = 0; i < 3; i++) { - dst[optype][i] = result; - } - } - else - dst[optype][3] = result; - } - break; - case GL_DOT3_ATI: - { - GLfloat result; - - /* DOT 3 always uses the source from the color op */ - result = src[0][0][0] * src[0][1][0] + - src[0][0][1] * src[0][1][1] + - src[0][0][2] * src[0][1][2]; - - if (!optype) { - for (i = 0; i < 3; i++) { - dst[optype][i] = result; - } - } - else - dst[optype][3] = result; - } - break; - case GL_DOT4_ATI: - { - GLfloat result; - - /* DOT 4 always uses the source from the color op */ - result = src[0][0][0] * src[0][1][0] + - src[0][0][1] * src[0][1][1] + - src[0][0][2] * src[0][1][2] + - src[0][0][3] * src[0][1][3]; - if (!optype) { - for (i = 0; i < 3; i++) { - dst[optype][i] = result; - } - } - else - dst[optype][3] = result; - } - break; - - } - } - } - - /* write out the destination registers */ - for (optype = 0; optype < 2; optype++) { - if (inst->Opcode[optype]) { - dstreg = inst->DstReg[optype].Index; - dstp = machine->Registers[dstreg - GL_REG_0_ATI]; - - if ((optype == 0) || ((inst->Opcode[1] != GL_DOT2_ADD_ATI) && - (inst->Opcode[1] != GL_DOT3_ATI) && (inst->Opcode[1] != GL_DOT4_ATI))) - write_dst_addr(optype, inst->DstReg[optype].dstMod, - inst->DstReg[optype].dstMask, dst[optype], - dstp); - else - write_dst_addr(1, inst->DstReg[0].dstMod, 0, dst[1], dstp); - } - } - } - } -} - - -/** - * Init fragment shader virtual machine state. - */ -static void -init_machine(struct gl_context * ctx, struct atifs_machine *machine, - const struct ati_fragment_shader *shader, - const SWspan *span, GLuint col) -{ - GLfloat (*inputs)[4] = machine->Inputs; - GLint i, j; - - for (i = 0; i < 6; i++) { - for (j = 0; j < 4; j++) - machine->Registers[i][j] = 0.0; - } - - COPY_4V(inputs[ATI_FS_INPUT_PRIMARY], span->array->attribs[VARYING_SLOT_COL0][col]); - COPY_4V(inputs[ATI_FS_INPUT_SECONDARY], span->array->attribs[VARYING_SLOT_COL1][col]); -} - - - -/** - * Execute the current ATI shader program, operating on the given span. - */ -void -_swrast_exec_fragment_shader(struct gl_context * ctx, SWspan *span) -{ - const struct ati_fragment_shader *shader = ctx->ATIFragmentShader.Current; - struct atifs_machine machine; - GLuint i; - - /* incoming colors should be floats */ - assert(span->array->ChanType == GL_FLOAT); - - for (i = 0; i < span->end; i++) { - if (span->array->mask[i]) { - init_machine(ctx, &machine, shader, span, i); - - execute_shader(ctx, shader, &machine, span, i); - - /* store result color */ - { - const GLfloat *colOut = machine.Registers[0]; - /*fprintf(stderr,"outputs %f %f %f %f\n", - colOut[0], colOut[1], colOut[2], colOut[3]); */ - COPY_4V(span->array->attribs[VARYING_SLOT_COL0][i], colOut); - } - } - } -} diff --git a/src/mesa/swrast/s_atifragshader.h b/src/mesa/swrast/s_atifragshader.h deleted file mode 100644 index ac866aa..0000000 --- a/src/mesa/swrast/s_atifragshader.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2003 David Airlie All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * DAVID AIRLIE 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. - */ - - -#ifndef S_ATIFRAGSHADER_H -#define S_ATIFRAGSHADER_H - - -#include "s_span.h" - -struct gl_context; - -extern void -_swrast_exec_fragment_shader( struct gl_context *ctx, SWspan *span ); - - -#endif diff --git a/src/mesa/swrast/s_bitmap.c b/src/mesa/swrast/s_bitmap.c deleted file mode 100644 index 324daea..0000000 --- a/src/mesa/swrast/s_bitmap.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -/** - * \file swrast/s_bitmap.c - * \brief glBitmap rendering. - * \author Brian Paul - */ - -#include "main/glheader.h" -#include "main/bufferobj.h" -#include "main/condrender.h" -#include "main/image.h" -#include "main/macros.h" -#include "main/pbo.h" - -#include "s_context.h" -#include "s_span.h" - - - -/** - * Render a bitmap. - * Called via ctx->Driver.Bitmap() - * All parameter error checking will have been done before this is called. - */ -void -_swrast_Bitmap( struct gl_context *ctx, GLint px, GLint py, - GLsizei width, GLsizei height, - const struct gl_pixelstore_attrib *unpack, - const GLubyte *bitmap ) -{ - GLint row, col; - GLuint count = 0; - SWspan span; - - assert(ctx->RenderMode == GL_RENDER); - - if (!_mesa_check_conditional_render(ctx)) - return; /* don't draw */ - - bitmap = (const GLubyte *) _mesa_map_pbo_source(ctx, unpack, bitmap); - if (!bitmap) - return; - - swrast_render_start(ctx); - - if (SWRAST_CONTEXT(ctx)->NewState) - _swrast_validate_derived( ctx ); - - INIT_SPAN(span, GL_BITMAP); - span.end = width; - span.arrayMask = SPAN_XY; - _swrast_span_default_attribs(ctx, &span); - - for (row = 0; row < height; row++) { - const GLubyte *src = (const GLubyte *) _mesa_image_address2d(unpack, - bitmap, width, height, GL_COLOR_INDEX, GL_BITMAP, row, 0); - - if (unpack->LsbFirst) { - /* Lsb first */ - GLubyte mask = 1U << (unpack->SkipPixels & 0x7); - for (col = 0; col < width; col++) { - if (*src & mask) { - span.array->x[count] = px + col; - span.array->y[count] = py + row; - count++; - } - if (mask == 128U) { - src++; - mask = 1U; - } - else { - mask = mask << 1; - } - } - - /* get ready for next row */ - if (mask != 1) - src++; - } - else { - /* Msb first */ - GLubyte mask = 128U >> (unpack->SkipPixels & 0x7); - for (col = 0; col < width; col++) { - if (*src & mask) { - span.array->x[count] = px + col; - span.array->y[count] = py + row; - count++; - } - if (mask == 1U) { - src++; - mask = 128U; - } - else { - mask = mask >> 1; - } - } - - /* get ready for next row */ - if (mask != 128) - src++; - } - - if (count + width >= SWRAST_MAX_WIDTH || row + 1 == height) { - /* flush the span */ - span.end = count; - _swrast_write_rgba_span(ctx, &span); - span.end = 0; - count = 0; - } - } - - swrast_render_finish(ctx); - - _mesa_unmap_pbo_source(ctx, unpack); -} - - -#if 0 -/* - * XXX this is another way to implement Bitmap. Use horizontal runs of - * fragments, initializing the mask array to indicate which fragments to - * draw or skip. - */ -void -_swrast_Bitmap( struct gl_context *ctx, GLint px, GLint py, - GLsizei width, GLsizei height, - const struct gl_pixelstore_attrib *unpack, - const GLubyte *bitmap ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - GLint row, col; - SWspan span; - - assert(ctx->RenderMode == GL_RENDER); - assert(bitmap); - - swrast_render_start(ctx); - - if (SWRAST_CONTEXT(ctx)->NewState) - _swrast_validate_derived( ctx ); - - INIT_SPAN(span, GL_BITMAP); - span.end = width; - span.arrayMask = SPAN_MASK; - _swrast_span_default_attribs(ctx, &span); - - /*span.arrayMask |= SPAN_MASK;*/ /* we'll init span.mask[] */ - span.x = px; - span.y = py; - /*span.end = width;*/ - - for (row=0; rowLsbFirst) { - /* Lsb first */ - GLubyte mask = 1U << (unpack->SkipPixels & 0x7); - for (col=0; colmask[col] = (*src & mask) ? GL_TRUE : GL_FALSE; - if (mask == 128U) { - src++; - mask = 1U; - } - else { - mask = mask << 1; - } - } - - _swrast_write_rgba_span(ctx, &span); - - /* get ready for next row */ - if (mask != 1) - src++; - } - else { - /* Msb first */ - GLubyte mask = 128U >> (unpack->SkipPixels & 0x7); - for (col=0; colmask[col] = (*src & mask) ? GL_TRUE : GL_FALSE; - if (mask == 1U) { - src++; - mask = 128U; - } - else { - mask = mask >> 1; - } - } - - _swrast_write_rgba_span(ctx, &span); - - /* get ready for next row */ - if (mask != 128) - src++; - } - } - - swrast_render_finish(ctx); -} -#endif diff --git a/src/mesa/swrast/s_blend.c b/src/mesa/swrast/s_blend.c deleted file mode 100644 index 8479b0b..0000000 --- a/src/mesa/swrast/s_blend.c +++ /dev/null @@ -1,1006 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -/** - * \file swrast/s_blend.c - * \brief software blending. - * \author Brian Paul - * - * Only a few blend modes have been optimized (min, max, transparency, add) - * more optimized cases can easily be added if needed. - * Celestia uses glBlendFunc(GL_SRC_ALPHA, GL_ONE), for example. - */ - - - -#include "main/glheader.h" -#include "main/context.h" -#include "main/colormac.h" -#include "main/macros.h" - -#include "s_blend.h" -#include "s_context.h" -#include "s_span.h" - - -#if defined(USE_MMX_ASM) -#include "x86/mmx.h" -#include "x86/common_x86_asm.h" -#endif - - -/** - * Integer divide by 255 - * Declare "int divtemp" before using. - * This satisfies Glean and should be reasonably fast. - * Contributed by Nathan Hand. - */ -#define DIV255(X) (divtemp = (X), ((divtemp << 8) + divtemp + 256) >> 16) - - - -/** - * Special case for glBlendFunc(GL_ZERO, GL_ONE). - * No-op means the framebuffer values remain unchanged. - * Any chanType ok. - */ -static void -blend_noop(struct gl_context *ctx, GLuint n, const GLubyte mask[], - GLvoid *src, const GLvoid *dst, GLenum chanType) -{ - GLint bytes; - - assert(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD); - assert(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD); - assert(ctx->Color.Blend[0].SrcRGB == GL_ZERO); - assert(ctx->Color.Blend[0].DstRGB == GL_ONE); - (void) ctx; - - /* just memcpy */ - if (chanType == GL_UNSIGNED_BYTE) - bytes = 4 * n * sizeof(GLubyte); - else if (chanType == GL_UNSIGNED_SHORT) - bytes = 4 * n * sizeof(GLushort); - else - bytes = 4 * n * sizeof(GLfloat); - - memcpy(src, dst, bytes); -} - - -/** - * Special case for glBlendFunc(GL_ONE, GL_ZERO) - * Any chanType ok. - */ -static void -blend_replace(struct gl_context *ctx, GLuint n, const GLubyte mask[], - GLvoid *src, const GLvoid *dst, GLenum chanType) -{ - assert(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD); - assert(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD); - assert(ctx->Color.Blend[0].SrcRGB == GL_ONE); - assert(ctx->Color.Blend[0].DstRGB == GL_ZERO); - (void) ctx; - (void) n; - (void) mask; - (void) src; - (void) dst; -} - - -/** - * Common transparency blending mode: - * glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA). - */ -static void -blend_transparency_ubyte(struct gl_context *ctx, GLuint n, const GLubyte mask[], - GLvoid *src, const GLvoid *dst, GLenum chanType) -{ - GLubyte (*rgba)[4] = (GLubyte (*)[4]) src; - const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst; - GLuint i; - - assert(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD); - assert(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD); - assert(ctx->Color.Blend[0].SrcRGB == GL_SRC_ALPHA); - assert(ctx->Color.Blend[0].SrcA == GL_SRC_ALPHA); - assert(ctx->Color.Blend[0].DstRGB == GL_ONE_MINUS_SRC_ALPHA); - assert(ctx->Color.Blend[0].DstA == GL_ONE_MINUS_SRC_ALPHA); - assert(chanType == GL_UNSIGNED_BYTE); - - (void) ctx; - - for (i = 0; i < n; i++) { - if (mask[i]) { - const GLint t = rgba[i][ACOMP]; /* t is in [0, 255] */ - if (t == 0) { - /* 0% alpha */ - COPY_4UBV(rgba[i], dest[i]); - } - else if (t != 255) { - GLint divtemp; - const GLint r = DIV255((rgba[i][RCOMP] - dest[i][RCOMP]) * t) + dest[i][RCOMP]; - const GLint g = DIV255((rgba[i][GCOMP] - dest[i][GCOMP]) * t) + dest[i][GCOMP]; - const GLint b = DIV255((rgba[i][BCOMP] - dest[i][BCOMP]) * t) + dest[i][BCOMP]; - const GLint a = DIV255((rgba[i][ACOMP] - dest[i][ACOMP]) * t) + dest[i][ACOMP]; - assert(r <= 255); - assert(g <= 255); - assert(b <= 255); - assert(a <= 255); - rgba[i][RCOMP] = (GLubyte) r; - rgba[i][GCOMP] = (GLubyte) g; - rgba[i][BCOMP] = (GLubyte) b; - rgba[i][ACOMP] = (GLubyte) a; - } - } - } -} - - -static void -blend_transparency_ushort(struct gl_context *ctx, GLuint n, const GLubyte mask[], - GLvoid *src, const GLvoid *dst, GLenum chanType) -{ - GLushort (*rgba)[4] = (GLushort (*)[4]) src; - const GLushort (*dest)[4] = (const GLushort (*)[4]) dst; - GLuint i; - - assert(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD); - assert(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD); - assert(ctx->Color.Blend[0].SrcRGB == GL_SRC_ALPHA); - assert(ctx->Color.Blend[0].SrcA == GL_SRC_ALPHA); - assert(ctx->Color.Blend[0].DstRGB == GL_ONE_MINUS_SRC_ALPHA); - assert(ctx->Color.Blend[0].DstA == GL_ONE_MINUS_SRC_ALPHA); - assert(chanType == GL_UNSIGNED_SHORT); - - (void) ctx; - - for (i = 0; i < n; i++) { - if (mask[i]) { - const GLint t = rgba[i][ACOMP]; - if (t == 0) { - /* 0% alpha */ - COPY_4V(rgba[i], dest[i]); - } - else if (t != 65535) { - const GLfloat tt = (GLfloat) t / 65535.0F; - GLushort r = (GLushort) ((rgba[i][RCOMP] - dest[i][RCOMP]) * tt + dest[i][RCOMP]); - GLushort g = (GLushort) ((rgba[i][GCOMP] - dest[i][GCOMP]) * tt + dest[i][GCOMP]); - GLushort b = (GLushort) ((rgba[i][BCOMP] - dest[i][BCOMP]) * tt + dest[i][BCOMP]); - GLushort a = (GLushort) ((rgba[i][ACOMP] - dest[i][ACOMP]) * tt + dest[i][ACOMP]); - ASSIGN_4V(rgba[i], r, g, b, a); - } - } - } -} - - -static void -blend_transparency_float(struct gl_context *ctx, GLuint n, const GLubyte mask[], - GLvoid *src, const GLvoid *dst, GLenum chanType) -{ - GLfloat (*rgba)[4] = (GLfloat (*)[4]) src; - const GLfloat (*dest)[4] = (const GLfloat (*)[4]) dst; - GLuint i; - - assert(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD); - assert(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD); - assert(ctx->Color.Blend[0].SrcRGB == GL_SRC_ALPHA); - assert(ctx->Color.Blend[0].SrcA == GL_SRC_ALPHA); - assert(ctx->Color.Blend[0].DstRGB == GL_ONE_MINUS_SRC_ALPHA); - assert(ctx->Color.Blend[0].DstA == GL_ONE_MINUS_SRC_ALPHA); - assert(chanType == GL_FLOAT); - - (void) ctx; - - for (i = 0; i < n; i++) { - if (mask[i]) { - const GLfloat t = rgba[i][ACOMP]; /* t in [0, 1] */ - if (t == 0.0F) { - /* 0% alpha */ - COPY_4V(rgba[i], dest[i]); - } - else if (t != 1.0F) { - GLfloat r = (rgba[i][RCOMP] - dest[i][RCOMP]) * t + dest[i][RCOMP]; - GLfloat g = (rgba[i][GCOMP] - dest[i][GCOMP]) * t + dest[i][GCOMP]; - GLfloat b = (rgba[i][BCOMP] - dest[i][BCOMP]) * t + dest[i][BCOMP]; - GLfloat a = (rgba[i][ACOMP] - dest[i][ACOMP]) * t + dest[i][ACOMP]; - ASSIGN_4V(rgba[i], r, g, b, a); - } - } - } -} - - - -/** - * Add src and dest: glBlendFunc(GL_ONE, GL_ONE). - * Any chanType ok. - */ -static void -blend_add(struct gl_context *ctx, GLuint n, const GLubyte mask[], - GLvoid *src, const GLvoid *dst, GLenum chanType) -{ - GLuint i; - - assert(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD); - assert(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD); - assert(ctx->Color.Blend[0].SrcRGB == GL_ONE); - assert(ctx->Color.Blend[0].DstRGB == GL_ONE); - (void) ctx; - - if (chanType == GL_UNSIGNED_BYTE) { - GLubyte (*rgba)[4] = (GLubyte (*)[4]) src; - const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst; - for (i=0;iColor.Blend[0].EquationRGB == GL_MIN); - assert(ctx->Color.Blend[0].EquationA == GL_MIN); - (void) ctx; - - if (chanType == GL_UNSIGNED_BYTE) { - GLubyte (*rgba)[4] = (GLubyte (*)[4]) src; - const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst; - for (i=0;iColor.Blend[0].EquationRGB == GL_MAX); - assert(ctx->Color.Blend[0].EquationA == GL_MAX); - (void) ctx; - - if (chanType == GL_UNSIGNED_BYTE) { - GLubyte (*rgba)[4] = (GLubyte (*)[4]) src; - const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst; - for (i=0;i> 16; - rgba[i][GCOMP] = (rgba[i][GCOMP] * dest[i][GCOMP] + 65535) >> 16; - rgba[i][BCOMP] = (rgba[i][BCOMP] * dest[i][BCOMP] + 65535) >> 16; - rgba[i][ACOMP] = (rgba[i][ACOMP] * dest[i][ACOMP] + 65535) >> 16; - } - } - } - else { - GLfloat (*rgba)[4] = (GLfloat (*)[4]) src; - const GLfloat (*dest)[4] = (const GLfloat (*)[4]) dst; - assert(chanType == GL_FLOAT); - for (i=0;iColor.Blend[0].SrcRGB) { - case GL_ZERO: - sR = sG = sB = 0.0F; - break; - case GL_ONE: - sR = sG = sB = 1.0F; - break; - case GL_DST_COLOR: - sR = Rd; - sG = Gd; - sB = Bd; - break; - case GL_ONE_MINUS_DST_COLOR: - sR = 1.0F - Rd; - sG = 1.0F - Gd; - sB = 1.0F - Bd; - break; - case GL_SRC_ALPHA: - sR = sG = sB = As; - break; - case GL_ONE_MINUS_SRC_ALPHA: - sR = sG = sB = 1.0F - As; - break; - case GL_DST_ALPHA: - sR = sG = sB = Ad; - break; - case GL_ONE_MINUS_DST_ALPHA: - sR = sG = sB = 1.0F - Ad; - break; - case GL_SRC_ALPHA_SATURATE: - if (As < 1.0F - Ad) { - sR = sG = sB = As; - } - else { - sR = sG = sB = 1.0F - Ad; - } - break; - case GL_CONSTANT_COLOR: - sR = ctx->Color.BlendColor[0]; - sG = ctx->Color.BlendColor[1]; - sB = ctx->Color.BlendColor[2]; - break; - case GL_ONE_MINUS_CONSTANT_COLOR: - sR = 1.0F - ctx->Color.BlendColor[0]; - sG = 1.0F - ctx->Color.BlendColor[1]; - sB = 1.0F - ctx->Color.BlendColor[2]; - break; - case GL_CONSTANT_ALPHA: - sR = sG = sB = ctx->Color.BlendColor[3]; - break; - case GL_ONE_MINUS_CONSTANT_ALPHA: - sR = sG = sB = 1.0F - ctx->Color.BlendColor[3]; - break; - case GL_SRC_COLOR: - sR = Rs; - sG = Gs; - sB = Bs; - break; - case GL_ONE_MINUS_SRC_COLOR: - sR = 1.0F - Rs; - sG = 1.0F - Gs; - sB = 1.0F - Bs; - break; - default: - /* this should never happen */ - _mesa_problem(ctx, "Bad blend source RGB factor in blend_general_float"); - return; - } - - /* Source Alpha factor */ - switch (ctx->Color.Blend[0].SrcA) { - case GL_ZERO: - sA = 0.0F; - break; - case GL_ONE: - sA = 1.0F; - break; - case GL_DST_COLOR: - sA = Ad; - break; - case GL_ONE_MINUS_DST_COLOR: - sA = 1.0F - Ad; - break; - case GL_SRC_ALPHA: - sA = As; - break; - case GL_ONE_MINUS_SRC_ALPHA: - sA = 1.0F - As; - break; - case GL_DST_ALPHA: - sA = Ad; - break; - case GL_ONE_MINUS_DST_ALPHA: - sA = 1.0F - Ad; - break; - case GL_SRC_ALPHA_SATURATE: - sA = 1.0; - break; - case GL_CONSTANT_COLOR: - sA = ctx->Color.BlendColor[3]; - break; - case GL_ONE_MINUS_CONSTANT_COLOR: - sA = 1.0F - ctx->Color.BlendColor[3]; - break; - case GL_CONSTANT_ALPHA: - sA = ctx->Color.BlendColor[3]; - break; - case GL_ONE_MINUS_CONSTANT_ALPHA: - sA = 1.0F - ctx->Color.BlendColor[3]; - break; - case GL_SRC_COLOR: - sA = As; - break; - case GL_ONE_MINUS_SRC_COLOR: - sA = 1.0F - As; - break; - default: - /* this should never happen */ - sA = 0.0F; - _mesa_problem(ctx, "Bad blend source A factor in blend_general_float"); - return; - } - - /* Dest RGB factor */ - switch (ctx->Color.Blend[0].DstRGB) { - case GL_ZERO: - dR = dG = dB = 0.0F; - break; - case GL_ONE: - dR = dG = dB = 1.0F; - break; - case GL_SRC_COLOR: - dR = Rs; - dG = Gs; - dB = Bs; - break; - case GL_ONE_MINUS_SRC_COLOR: - dR = 1.0F - Rs; - dG = 1.0F - Gs; - dB = 1.0F - Bs; - break; - case GL_SRC_ALPHA: - dR = dG = dB = As; - break; - case GL_ONE_MINUS_SRC_ALPHA: - dR = dG = dB = 1.0F - As; - break; - case GL_DST_ALPHA: - dR = dG = dB = Ad; - break; - case GL_ONE_MINUS_DST_ALPHA: - dR = dG = dB = 1.0F - Ad; - break; - case GL_CONSTANT_COLOR: - dR = ctx->Color.BlendColor[0]; - dG = ctx->Color.BlendColor[1]; - dB = ctx->Color.BlendColor[2]; - break; - case GL_ONE_MINUS_CONSTANT_COLOR: - dR = 1.0F - ctx->Color.BlendColor[0]; - dG = 1.0F - ctx->Color.BlendColor[1]; - dB = 1.0F - ctx->Color.BlendColor[2]; - break; - case GL_CONSTANT_ALPHA: - dR = dG = dB = ctx->Color.BlendColor[3]; - break; - case GL_ONE_MINUS_CONSTANT_ALPHA: - dR = dG = dB = 1.0F - ctx->Color.BlendColor[3]; - break; - case GL_DST_COLOR: - dR = Rd; - dG = Gd; - dB = Bd; - break; - case GL_ONE_MINUS_DST_COLOR: - dR = 1.0F - Rd; - dG = 1.0F - Gd; - dB = 1.0F - Bd; - break; - default: - /* this should never happen */ - dR = dG = dB = 0.0F; - _mesa_problem(ctx, "Bad blend dest RGB factor in blend_general_float"); - return; - } - - /* Dest Alpha factor */ - switch (ctx->Color.Blend[0].DstA) { - case GL_ZERO: - dA = 0.0F; - break; - case GL_ONE: - dA = 1.0F; - break; - case GL_SRC_COLOR: - dA = As; - break; - case GL_ONE_MINUS_SRC_COLOR: - dA = 1.0F - As; - break; - case GL_SRC_ALPHA: - dA = As; - break; - case GL_ONE_MINUS_SRC_ALPHA: - dA = 1.0F - As; - break; - case GL_DST_ALPHA: - dA = Ad; - break; - case GL_ONE_MINUS_DST_ALPHA: - dA = 1.0F - Ad; - break; - case GL_CONSTANT_COLOR: - dA = ctx->Color.BlendColor[3]; - break; - case GL_ONE_MINUS_CONSTANT_COLOR: - dA = 1.0F - ctx->Color.BlendColor[3]; - break; - case GL_CONSTANT_ALPHA: - dA = ctx->Color.BlendColor[3]; - break; - case GL_ONE_MINUS_CONSTANT_ALPHA: - dA = 1.0F - ctx->Color.BlendColor[3]; - break; - case GL_DST_COLOR: - dA = Ad; - break; - case GL_ONE_MINUS_DST_COLOR: - dA = 1.0F - Ad; - break; - default: - /* this should never happen */ - dA = 0.0F; - _mesa_problem(ctx, "Bad blend dest A factor in blend_general_float"); - return; - } - - /* compute the blended RGB */ - switch (ctx->Color.Blend[0].EquationRGB) { - case GL_FUNC_ADD: - r = Rs * sR + Rd * dR; - g = Gs * sG + Gd * dG; - b = Bs * sB + Bd * dB; - a = As * sA + Ad * dA; - break; - case GL_FUNC_SUBTRACT: - r = Rs * sR - Rd * dR; - g = Gs * sG - Gd * dG; - b = Bs * sB - Bd * dB; - a = As * sA - Ad * dA; - break; - case GL_FUNC_REVERSE_SUBTRACT: - r = Rd * dR - Rs * sR; - g = Gd * dG - Gs * sG; - b = Bd * dB - Bs * sB; - a = Ad * dA - As * sA; - break; - case GL_MIN: - r = MIN2( Rd, Rs ); - g = MIN2( Gd, Gs ); - b = MIN2( Bd, Bs ); - break; - case GL_MAX: - r = MAX2( Rd, Rs ); - g = MAX2( Gd, Gs ); - b = MAX2( Bd, Bs ); - break; - default: - /* should never get here */ - r = g = b = 0.0F; /* silence uninitialized var warning */ - _mesa_problem(ctx, "unexpected BlendEquation in blend_general()"); - return; - } - - /* compute the blended alpha */ - switch (ctx->Color.Blend[0].EquationA) { - case GL_FUNC_ADD: - a = As * sA + Ad * dA; - break; - case GL_FUNC_SUBTRACT: - a = As * sA - Ad * dA; - break; - case GL_FUNC_REVERSE_SUBTRACT: - a = Ad * dA - As * sA; - break; - case GL_MIN: - a = MIN2( Ad, As ); - break; - case GL_MAX: - a = MAX2( Ad, As ); - break; - default: - /* should never get here */ - a = 0.0F; /* silence uninitialized var warning */ - _mesa_problem(ctx, "unexpected BlendEquation in blend_general()"); - return; - } - - /* final clamping */ -#if 0 - rgba[i][RCOMP] = MAX2( r, 0.0F ); - rgba[i][GCOMP] = MAX2( g, 0.0F ); - rgba[i][BCOMP] = MAX2( b, 0.0F ); - rgba[i][ACOMP] = CLAMP( a, 0.0F, 1.0F ); -#else - ASSIGN_4V(rgba[i], r, g, b, a); -#endif - } - } -} - - -/** - * Do any blending operation, any chanType. - */ -static void -blend_general(struct gl_context *ctx, GLuint n, const GLubyte mask[], - void *src, const void *dst, GLenum chanType) -{ - GLfloat (*rgbaF)[4], (*destF)[4]; - - rgbaF = (GLfloat (*)[4]) malloc(4 * n * sizeof(GLfloat)); - destF = (GLfloat (*)[4]) malloc(4 * n * sizeof(GLfloat)); - if (!rgbaF || !destF) { - free(rgbaF); - free(destF); - _mesa_error(ctx, GL_OUT_OF_MEMORY, "blending"); - return; - } - - if (chanType == GL_UNSIGNED_BYTE) { - GLubyte (*rgba)[4] = (GLubyte (*)[4]) src; - const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst; - GLuint i; - /* convert ubytes to floats */ - for (i = 0; i < n; i++) { - if (mask[i]) { - rgbaF[i][RCOMP] = UBYTE_TO_FLOAT(rgba[i][RCOMP]); - rgbaF[i][GCOMP] = UBYTE_TO_FLOAT(rgba[i][GCOMP]); - rgbaF[i][BCOMP] = UBYTE_TO_FLOAT(rgba[i][BCOMP]); - rgbaF[i][ACOMP] = UBYTE_TO_FLOAT(rgba[i][ACOMP]); - destF[i][RCOMP] = UBYTE_TO_FLOAT(dest[i][RCOMP]); - destF[i][GCOMP] = UBYTE_TO_FLOAT(dest[i][GCOMP]); - destF[i][BCOMP] = UBYTE_TO_FLOAT(dest[i][BCOMP]); - destF[i][ACOMP] = UBYTE_TO_FLOAT(dest[i][ACOMP]); - } - } - /* do blend */ - blend_general_float(ctx, n, mask, rgbaF, destF, chanType); - /* convert back to ubytes */ - for (i = 0; i < n; i++) { - if (mask[i]) - _mesa_unclamped_float_rgba_to_ubyte(rgba[i], rgbaF[i]); - } - } - else if (chanType == GL_UNSIGNED_SHORT) { - GLushort (*rgba)[4] = (GLushort (*)[4]) src; - const GLushort (*dest)[4] = (const GLushort (*)[4]) dst; - GLuint i; - /* convert ushorts to floats */ - for (i = 0; i < n; i++) { - if (mask[i]) { - rgbaF[i][RCOMP] = USHORT_TO_FLOAT(rgba[i][RCOMP]); - rgbaF[i][GCOMP] = USHORT_TO_FLOAT(rgba[i][GCOMP]); - rgbaF[i][BCOMP] = USHORT_TO_FLOAT(rgba[i][BCOMP]); - rgbaF[i][ACOMP] = USHORT_TO_FLOAT(rgba[i][ACOMP]); - destF[i][RCOMP] = USHORT_TO_FLOAT(dest[i][RCOMP]); - destF[i][GCOMP] = USHORT_TO_FLOAT(dest[i][GCOMP]); - destF[i][BCOMP] = USHORT_TO_FLOAT(dest[i][BCOMP]); - destF[i][ACOMP] = USHORT_TO_FLOAT(dest[i][ACOMP]); - } - } - /* do blend */ - blend_general_float(ctx, n, mask, rgbaF, destF, chanType); - /* convert back to ushorts */ - for (i = 0; i < n; i++) { - if (mask[i]) { - UNCLAMPED_FLOAT_TO_USHORT(rgba[i][RCOMP], rgbaF[i][RCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(rgba[i][GCOMP], rgbaF[i][GCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(rgba[i][BCOMP], rgbaF[i][BCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(rgba[i][ACOMP], rgbaF[i][ACOMP]); - } - } - } - else { - blend_general_float(ctx, n, mask, (GLfloat (*)[4]) src, - (GLfloat (*)[4]) dst, chanType); - } - - free(rgbaF); - free(destF); -} - - - -/** - * Analyze current blending parameters to pick fastest blending function. - * Result: the ctx->Color.BlendFunc pointer is updated. - */ -void -_swrast_choose_blend_func(struct gl_context *ctx, GLenum chanType) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - const GLenum eq = ctx->Color.Blend[0].EquationRGB; - const GLenum srcRGB = ctx->Color.Blend[0].SrcRGB; - const GLenum dstRGB = ctx->Color.Blend[0].DstRGB; - const GLenum srcA = ctx->Color.Blend[0].SrcA; - const GLenum dstA = ctx->Color.Blend[0].DstA; - - if (ctx->Color.Blend[0].EquationRGB != ctx->Color.Blend[0].EquationA) { - swrast->BlendFunc = blend_general; - } - else if (eq == GL_MIN) { - /* Note: GL_MIN ignores the blending weight factors */ -#if defined(USE_MMX_ASM) - if (cpu_has_mmx && chanType == GL_UNSIGNED_BYTE) { - swrast->BlendFunc = _mesa_mmx_blend_min; - } - else -#endif - swrast->BlendFunc = blend_min; - } - else if (eq == GL_MAX) { - /* Note: GL_MAX ignores the blending weight factors */ -#if defined(USE_MMX_ASM) - if (cpu_has_mmx && chanType == GL_UNSIGNED_BYTE) { - swrast->BlendFunc = _mesa_mmx_blend_max; - } - else -#endif - swrast->BlendFunc = blend_max; - } - else if (srcRGB != srcA || dstRGB != dstA) { - swrast->BlendFunc = blend_general; - } - else if (eq == GL_FUNC_ADD && srcRGB == GL_SRC_ALPHA - && dstRGB == GL_ONE_MINUS_SRC_ALPHA) { -#if defined(USE_MMX_ASM) - if (cpu_has_mmx && chanType == GL_UNSIGNED_BYTE) { - swrast->BlendFunc = _mesa_mmx_blend_transparency; - } - else -#endif - { - if (chanType == GL_UNSIGNED_BYTE) - swrast->BlendFunc = blend_transparency_ubyte; - else if (chanType == GL_UNSIGNED_SHORT) - swrast->BlendFunc = blend_transparency_ushort; - else - swrast->BlendFunc = blend_transparency_float; - } - } - else if (eq == GL_FUNC_ADD && srcRGB == GL_ONE && dstRGB == GL_ONE) { -#if defined(USE_MMX_ASM) - if (cpu_has_mmx && chanType == GL_UNSIGNED_BYTE) { - swrast->BlendFunc = _mesa_mmx_blend_add; - } - else -#endif - swrast->BlendFunc = blend_add; - } - else if (((eq == GL_FUNC_ADD || eq == GL_FUNC_REVERSE_SUBTRACT) - && (srcRGB == GL_ZERO && dstRGB == GL_SRC_COLOR)) - || - ((eq == GL_FUNC_ADD || eq == GL_FUNC_SUBTRACT) - && (srcRGB == GL_DST_COLOR && dstRGB == GL_ZERO))) { -#if defined(USE_MMX_ASM) - if (cpu_has_mmx && chanType == GL_UNSIGNED_BYTE) { - swrast->BlendFunc = _mesa_mmx_blend_modulate; - } - else -#endif - swrast->BlendFunc = blend_modulate; - } - else if (eq == GL_FUNC_ADD && srcRGB == GL_ZERO && dstRGB == GL_ONE) { - swrast->BlendFunc = blend_noop; - } - else if (eq == GL_FUNC_ADD && srcRGB == GL_ONE && dstRGB == GL_ZERO) { - swrast->BlendFunc = blend_replace; - } - else { - swrast->BlendFunc = blend_general; - } -} - - - -/** - * Apply the blending operator to a span of pixels. - * We can handle horizontal runs of pixels (spans) or arrays of x/y - * pixel coordinates. - */ -void -_swrast_blend_span(struct gl_context *ctx, struct gl_renderbuffer *rb, SWspan *span) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - void *rbPixels; - - assert(span->end <= SWRAST_MAX_WIDTH); - assert(span->arrayMask & SPAN_RGBA); - assert(!ctx->Color.ColorLogicOpEnabled); - - rbPixels = _swrast_get_dest_rgba(ctx, rb, span); - - swrast->BlendFunc(ctx, span->end, span->array->mask, - span->array->rgba, rbPixels, span->array->ChanType); -} diff --git a/src/mesa/swrast/s_blend.h b/src/mesa/swrast/s_blend.h deleted file mode 100644 index b77ec22..0000000 --- a/src/mesa/swrast/s_blend.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -#ifndef S_BLEND_H -#define S_BLEND_H - - -#include "main/glheader.h" -#include "s_span.h" - -struct gl_context; -struct gl_renderbuffer; - - -extern void -_swrast_blend_span(struct gl_context *ctx, struct gl_renderbuffer *rb, SWspan *span); - - -extern void -_swrast_choose_blend_func(struct gl_context *ctx, GLenum chanType); - - -#endif diff --git a/src/mesa/swrast/s_blit.c b/src/mesa/swrast/s_blit.c deleted file mode 100644 index 6b7e5e4..0000000 --- a/src/mesa/swrast/s_blit.c +++ /dev/null @@ -1,816 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -#include "main/glheader.h" -#include "main/condrender.h" -#include "main/image.h" -#include "main/macros.h" -#include "main/format_unpack.h" -#include "main/format_pack.h" -#include "main/condrender.h" -#include "s_context.h" - - -#define ABS(X) ((X) < 0 ? -(X) : (X)) - - -/** - * Generate a row resampler function for GL_NEAREST mode. - */ -#define RESAMPLE(NAME, PIXELTYPE, SIZE) \ -static void \ -NAME(GLint srcWidth, GLint dstWidth, \ - const GLvoid *srcBuffer, GLvoid *dstBuffer, \ - GLboolean flip) \ -{ \ - const PIXELTYPE *src = (const PIXELTYPE *) srcBuffer;\ - PIXELTYPE *dst = (PIXELTYPE *) dstBuffer; \ - GLint dstCol; \ - \ - if (flip) { \ - for (dstCol = 0; dstCol < dstWidth; dstCol++) { \ - GLint srcCol = (dstCol * srcWidth) / dstWidth; \ - assert(srcCol >= 0); \ - assert(srcCol < srcWidth); \ - srcCol = srcWidth - 1 - srcCol; /* flip */ \ - if (SIZE == 1) { \ - dst[dstCol] = src[srcCol]; \ - } \ - else if (SIZE == 2) { \ - dst[dstCol*2+0] = src[srcCol*2+0]; \ - dst[dstCol*2+1] = src[srcCol*2+1]; \ - } \ - else if (SIZE == 4) { \ - dst[dstCol*4+0] = src[srcCol*4+0]; \ - dst[dstCol*4+1] = src[srcCol*4+1]; \ - dst[dstCol*4+2] = src[srcCol*4+2]; \ - dst[dstCol*4+3] = src[srcCol*4+3]; \ - } \ - } \ - } \ - else { \ - for (dstCol = 0; dstCol < dstWidth; dstCol++) { \ - GLint srcCol = (dstCol * srcWidth) / dstWidth; \ - assert(srcCol >= 0); \ - assert(srcCol < srcWidth); \ - if (SIZE == 1) { \ - dst[dstCol] = src[srcCol]; \ - } \ - else if (SIZE == 2) { \ - dst[dstCol*2+0] = src[srcCol*2+0]; \ - dst[dstCol*2+1] = src[srcCol*2+1]; \ - } \ - else if (SIZE == 4) { \ - dst[dstCol*4+0] = src[srcCol*4+0]; \ - dst[dstCol*4+1] = src[srcCol*4+1]; \ - dst[dstCol*4+2] = src[srcCol*4+2]; \ - dst[dstCol*4+3] = src[srcCol*4+3]; \ - } \ - } \ - } \ -} - -/** - * Resamplers for 1, 2, 4, 8 and 16-byte pixels. - */ -RESAMPLE(resample_row_1, GLubyte, 1) -RESAMPLE(resample_row_2, GLushort, 1) -RESAMPLE(resample_row_4, GLuint, 1) -RESAMPLE(resample_row_8, GLuint, 2) -RESAMPLE(resample_row_16, GLuint, 4) - - -/** - * Blit color, depth or stencil with GL_NEAREST filtering. - */ -static void -blit_nearest(struct gl_context *ctx, - struct gl_framebuffer *readFb, - struct gl_framebuffer *drawFb, - GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, - GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, - GLbitfield buffer) -{ - struct gl_renderbuffer *readRb, *drawRb = NULL; - struct gl_renderbuffer_attachment *readAtt = NULL, *drawAtt = NULL; - GLuint numDrawBuffers = 0; - GLuint i; - - const GLint srcWidth = ABS(srcX1 - srcX0); - const GLint dstWidth = ABS(dstX1 - dstX0); - const GLint srcHeight = ABS(srcY1 - srcY0); - const GLint dstHeight = ABS(dstY1 - dstY0); - - const GLint srcXpos = MIN2(srcX0, srcX1); - const GLint srcYpos = MIN2(srcY0, srcY1); - const GLint dstXpos = MIN2(dstX0, dstX1); - const GLint dstYpos = MIN2(dstY0, dstY1); - - const GLboolean invertX = (srcX1 < srcX0) ^ (dstX1 < dstX0); - const GLboolean invertY = (srcY1 < srcY0) ^ (dstY1 < dstY0); - enum mode { - DIRECT, - UNPACK_RGBA_FLOAT, - UNPACK_Z_FLOAT, - UNPACK_Z_INT, - UNPACK_S, - } mode = DIRECT; - GLubyte *srcMap, *dstMap; - GLint srcRowStride, dstRowStride; - GLint dstRow; - - GLint pixelSize = 0; - GLvoid *srcBuffer, *dstBuffer; - GLint prevY = -1; - - typedef void (*resample_func)(GLint srcWidth, GLint dstWidth, - const GLvoid *srcBuffer, GLvoid *dstBuffer, - GLboolean flip); - resample_func resampleRow; - - switch (buffer) { - case GL_COLOR_BUFFER_BIT: - readAtt = &readFb->Attachment[readFb->_ColorReadBufferIndex]; - readRb = readFb->_ColorReadBuffer; - numDrawBuffers = drawFb->_NumColorDrawBuffers; - break; - case GL_DEPTH_BUFFER_BIT: - readAtt = &readFb->Attachment[BUFFER_DEPTH]; - drawAtt = &drawFb->Attachment[BUFFER_DEPTH]; - readRb = readAtt->Renderbuffer; - drawRb = drawAtt->Renderbuffer; - numDrawBuffers = 1; - - /* Note that for depth/stencil, the formats of src/dst must match. By - * using the core helpers for pack/unpack, we avoid needing to handle - * masking for things like DEPTH copies of Z24S8. - */ - if (readRb->Format == MESA_FORMAT_Z_FLOAT32 || - readRb->Format == MESA_FORMAT_Z32_FLOAT_S8X24_UINT) { - mode = UNPACK_Z_FLOAT; - } else { - mode = UNPACK_Z_INT; - } - pixelSize = 4; - break; - case GL_STENCIL_BUFFER_BIT: - readAtt = &readFb->Attachment[BUFFER_STENCIL]; - drawAtt = &drawFb->Attachment[BUFFER_STENCIL]; - readRb = readAtt->Renderbuffer; - drawRb = drawAtt->Renderbuffer; - numDrawBuffers = 1; - mode = UNPACK_S; - pixelSize = 1; - break; - default: - _mesa_problem(ctx, "unexpected buffer in blit_nearest()"); - return; - } - - /* allocate the src/dst row buffers */ - srcBuffer = malloc(MAX_PIXEL_BYTES * srcWidth); - dstBuffer = malloc(MAX_PIXEL_BYTES * dstWidth); - if (!srcBuffer || !dstBuffer) - goto fail_no_memory; - - /* Blit to all the draw buffers */ - for (i = 0; i < numDrawBuffers; i++) { - if (buffer == GL_COLOR_BUFFER_BIT) { - gl_buffer_index idx = drawFb->_ColorDrawBufferIndexes[i]; - if (idx == BUFFER_NONE) - continue; - drawAtt = &drawFb->Attachment[idx]; - drawRb = drawAtt->Renderbuffer; - - if (!drawRb) - continue; - - if (readRb->Format == drawRb->Format) { - mode = DIRECT; - pixelSize = _mesa_get_format_bytes(readRb->Format); - } else { - mode = UNPACK_RGBA_FLOAT; - pixelSize = 16; - } - } - - /* choose row resampler */ - switch (pixelSize) { - case 1: - resampleRow = resample_row_1; - break; - case 2: - resampleRow = resample_row_2; - break; - case 4: - resampleRow = resample_row_4; - break; - case 8: - resampleRow = resample_row_8; - break; - case 16: - resampleRow = resample_row_16; - break; - default: - _mesa_problem(ctx, "unexpected pixel size (%d) in blit_nearest", - pixelSize); - goto fail; - } - - if ((readRb == drawRb) || - (readAtt->Texture && drawAtt->Texture && - (readAtt->Texture == drawAtt->Texture))) { - /* map whole buffer for read/write */ - /* XXX we could be clever and just map the union region of the - * source and dest rects. - */ - GLubyte *map; - GLint rowStride; - GLint formatSize = _mesa_get_format_bytes(readRb->Format); - - ctx->Driver.MapRenderbuffer(ctx, readRb, 0, 0, - readRb->Width, readRb->Height, - GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, - &map, &rowStride, readFb->FlipY); - if (!map) { - goto fail_no_memory; - } - - srcMap = map + srcYpos * rowStride + srcXpos * formatSize; - dstMap = map + dstYpos * rowStride + dstXpos * formatSize; - - /* this handles overlapping copies */ - if (srcY0 < dstY0) { - /* copy in reverse (top->down) order */ - srcMap += rowStride * (readRb->Height - 1); - dstMap += rowStride * (readRb->Height - 1); - srcRowStride = -rowStride; - dstRowStride = -rowStride; - } - else { - /* copy in normal (bottom->up) order */ - srcRowStride = rowStride; - dstRowStride = rowStride; - } - } - else { - /* different src/dst buffers */ - ctx->Driver.MapRenderbuffer(ctx, readRb, - srcXpos, srcYpos, - srcWidth, srcHeight, - GL_MAP_READ_BIT, &srcMap, &srcRowStride, - readFb->FlipY); - if (!srcMap) { - goto fail_no_memory; - } - ctx->Driver.MapRenderbuffer(ctx, drawRb, - dstXpos, dstYpos, - dstWidth, dstHeight, - GL_MAP_WRITE_BIT, &dstMap, &dstRowStride, - drawFb->FlipY); - if (!dstMap) { - ctx->Driver.UnmapRenderbuffer(ctx, readRb); - goto fail_no_memory; - } - } - - for (dstRow = 0; dstRow < dstHeight; dstRow++) { - GLfloat srcRowF = (dstRow + 0.5F) / dstHeight * srcHeight - 0.5F; - GLint srcRow = lroundf(srcRowF); - GLubyte *dstRowStart = dstMap + dstRowStride * dstRow; - - assert(srcRow >= 0); - assert(srcRow < srcHeight); - - if (invertY) { - srcRow = srcHeight - 1 - srcRow; - } - - /* get pixel row from source and resample to match dest width */ - if (prevY != srcRow) { - GLubyte *srcRowStart = srcMap + srcRowStride * srcRow; - - switch (mode) { - case DIRECT: - memcpy(srcBuffer, srcRowStart, pixelSize * srcWidth); - break; - case UNPACK_RGBA_FLOAT: - _mesa_unpack_rgba_row(readRb->Format, srcWidth, srcRowStart, - srcBuffer); - break; - case UNPACK_Z_FLOAT: - _mesa_unpack_float_z_row(readRb->Format, srcWidth, srcRowStart, - srcBuffer); - break; - case UNPACK_Z_INT: - _mesa_unpack_uint_z_row(readRb->Format, srcWidth, srcRowStart, - srcBuffer); - break; - case UNPACK_S: - _mesa_unpack_ubyte_stencil_row(readRb->Format, srcWidth, - srcRowStart, srcBuffer); - break; - } - - resampleRow(srcWidth, dstWidth, srcBuffer, dstBuffer, invertX); - prevY = srcRow; - } - - /* store pixel row in destination */ - switch (mode) { - case DIRECT: - memcpy(dstRowStart, dstBuffer, pixelSize * dstWidth); - break; - case UNPACK_RGBA_FLOAT: - _mesa_pack_float_rgba_row(drawRb->Format, dstWidth, dstBuffer, - dstRowStart); - break; - case UNPACK_Z_FLOAT: - _mesa_pack_float_z_row(drawRb->Format, dstWidth, dstBuffer, - dstRowStart); - break; - case UNPACK_Z_INT: - _mesa_pack_uint_z_row(drawRb->Format, dstWidth, dstBuffer, - dstRowStart); - break; - case UNPACK_S: - _mesa_pack_ubyte_stencil_row(drawRb->Format, dstWidth, dstBuffer, - dstRowStart); - break; - } - } - - ctx->Driver.UnmapRenderbuffer(ctx, readRb); - if (drawRb != readRb) { - ctx->Driver.UnmapRenderbuffer(ctx, drawRb); - } - } - -fail: - free(srcBuffer); - free(dstBuffer); - return; - -fail_no_memory: - free(srcBuffer); - free(dstBuffer); - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBuffer"); -} - - - -#define LERP(T, A, B) ( (A) + (T) * ((B) - (A)) ) - -static inline GLfloat -lerp_2d(GLfloat a, GLfloat b, - GLfloat v00, GLfloat v10, GLfloat v01, GLfloat v11) -{ - const GLfloat temp0 = LERP(a, v00, v10); - const GLfloat temp1 = LERP(a, v01, v11); - return LERP(b, temp0, temp1); -} - - -/** - * Bilinear interpolation of two source rows. - * GLubyte pixels. - */ -static void -resample_linear_row_ub(GLint srcWidth, GLint dstWidth, - const GLvoid *srcBuffer0, const GLvoid *srcBuffer1, - GLvoid *dstBuffer, GLboolean flip, GLfloat rowWeight) -{ - const GLubyte (*srcColor0)[4] = (const GLubyte (*)[4]) srcBuffer0; - const GLubyte (*srcColor1)[4] = (const GLubyte (*)[4]) srcBuffer1; - GLubyte (*dstColor)[4] = (GLubyte (*)[4]) dstBuffer; - GLint dstCol; - - for (dstCol = 0; dstCol < dstWidth; dstCol++) { - const GLfloat srcCol = (dstCol + 0.5F) / dstWidth * srcWidth - 0.5F; - GLint srcCol0 = MAX2(0, util_ifloor(srcCol)); - GLint srcCol1 = srcCol0 + 1; - GLfloat colWeight = srcCol - srcCol0; /* fractional part of srcCol */ - GLfloat red, green, blue, alpha; - - assert(srcCol0 < srcWidth); - assert(srcCol1 <= srcWidth); - - if (srcCol1 == srcWidth) { - /* last column fudge */ - srcCol1--; - colWeight = 0.0; - } - - if (flip) { - srcCol0 = srcWidth - 1 - srcCol0; - srcCol1 = srcWidth - 1 - srcCol1; - } - - red = lerp_2d(colWeight, rowWeight, - srcColor0[srcCol0][RCOMP], srcColor0[srcCol1][RCOMP], - srcColor1[srcCol0][RCOMP], srcColor1[srcCol1][RCOMP]); - green = lerp_2d(colWeight, rowWeight, - srcColor0[srcCol0][GCOMP], srcColor0[srcCol1][GCOMP], - srcColor1[srcCol0][GCOMP], srcColor1[srcCol1][GCOMP]); - blue = lerp_2d(colWeight, rowWeight, - srcColor0[srcCol0][BCOMP], srcColor0[srcCol1][BCOMP], - srcColor1[srcCol0][BCOMP], srcColor1[srcCol1][BCOMP]); - alpha = lerp_2d(colWeight, rowWeight, - srcColor0[srcCol0][ACOMP], srcColor0[srcCol1][ACOMP], - srcColor1[srcCol0][ACOMP], srcColor1[srcCol1][ACOMP]); - - dstColor[dstCol][RCOMP] = util_ifloor(red); - dstColor[dstCol][GCOMP] = util_ifloor(green); - dstColor[dstCol][BCOMP] = util_ifloor(blue); - dstColor[dstCol][ACOMP] = util_ifloor(alpha); - } -} - - -/** - * Bilinear interpolation of two source rows. floating point pixels. - */ -static void -resample_linear_row_float(GLint srcWidth, GLint dstWidth, - const GLvoid *srcBuffer0, const GLvoid *srcBuffer1, - GLvoid *dstBuffer, GLboolean flip, GLfloat rowWeight) -{ - const GLfloat (*srcColor0)[4] = (const GLfloat (*)[4]) srcBuffer0; - const GLfloat (*srcColor1)[4] = (const GLfloat (*)[4]) srcBuffer1; - GLfloat (*dstColor)[4] = (GLfloat (*)[4]) dstBuffer; - GLint dstCol; - - for (dstCol = 0; dstCol < dstWidth; dstCol++) { - const GLfloat srcCol = (dstCol + 0.5F) / dstWidth * srcWidth - 0.5F; - GLint srcCol0 = MAX2(0, util_ifloor(srcCol)); - GLint srcCol1 = srcCol0 + 1; - GLfloat colWeight = srcCol - srcCol0; /* fractional part of srcCol */ - GLfloat red, green, blue, alpha; - - assert(srcCol0 < srcWidth); - assert(srcCol1 <= srcWidth); - - if (srcCol1 == srcWidth) { - /* last column fudge */ - srcCol1--; - colWeight = 0.0; - } - - if (flip) { - srcCol0 = srcWidth - 1 - srcCol0; - srcCol1 = srcWidth - 1 - srcCol1; - } - - red = lerp_2d(colWeight, rowWeight, - srcColor0[srcCol0][RCOMP], srcColor0[srcCol1][RCOMP], - srcColor1[srcCol0][RCOMP], srcColor1[srcCol1][RCOMP]); - green = lerp_2d(colWeight, rowWeight, - srcColor0[srcCol0][GCOMP], srcColor0[srcCol1][GCOMP], - srcColor1[srcCol0][GCOMP], srcColor1[srcCol1][GCOMP]); - blue = lerp_2d(colWeight, rowWeight, - srcColor0[srcCol0][BCOMP], srcColor0[srcCol1][BCOMP], - srcColor1[srcCol0][BCOMP], srcColor1[srcCol1][BCOMP]); - alpha = lerp_2d(colWeight, rowWeight, - srcColor0[srcCol0][ACOMP], srcColor0[srcCol1][ACOMP], - srcColor1[srcCol0][ACOMP], srcColor1[srcCol1][ACOMP]); - - dstColor[dstCol][RCOMP] = red; - dstColor[dstCol][GCOMP] = green; - dstColor[dstCol][BCOMP] = blue; - dstColor[dstCol][ACOMP] = alpha; - } -} - - - -/** - * Bilinear filtered blit (color only, non-integer values). - */ -static void -blit_linear(struct gl_context *ctx, - struct gl_framebuffer *readFb, - struct gl_framebuffer *drawFb, - GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, - GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1) -{ - struct gl_renderbuffer *readRb = readFb->_ColorReadBuffer; - struct gl_renderbuffer_attachment *readAtt = - &readFb->Attachment[readFb->_ColorReadBufferIndex]; - - const GLint srcWidth = ABS(srcX1 - srcX0); - const GLint dstWidth = ABS(dstX1 - dstX0); - const GLint srcHeight = ABS(srcY1 - srcY0); - const GLint dstHeight = ABS(dstY1 - dstY0); - - const GLint srcXpos = MIN2(srcX0, srcX1); - const GLint srcYpos = MIN2(srcY0, srcY1); - const GLint dstXpos = MIN2(dstX0, dstX1); - const GLint dstYpos = MIN2(dstY0, dstY1); - - const GLboolean invertX = (srcX1 < srcX0) ^ (dstX1 < dstX0); - const GLboolean invertY = (srcY1 < srcY0) ^ (dstY1 < dstY0); - - GLint dstRow; - - GLint pixelSize; - GLvoid *srcBuffer0, *srcBuffer1; - GLint srcBufferY0 = -1, srcBufferY1 = -1; - GLvoid *dstBuffer; - - mesa_format readFormat = _mesa_get_srgb_format_linear(readRb->Format); - GLuint bpp = _mesa_get_format_bytes(readFormat); - - GLenum pixelType; - - GLubyte *srcMap, *dstMap; - GLint srcRowStride, dstRowStride; - GLuint i; - - - /* Determine datatype for resampling */ - if (_mesa_get_format_max_bits(readFormat) == 8 && - _mesa_get_format_datatype(readFormat) == GL_UNSIGNED_NORMALIZED) { - pixelType = GL_UNSIGNED_BYTE; - pixelSize = 4 * sizeof(GLubyte); - } - else { - pixelType = GL_FLOAT; - pixelSize = 4 * sizeof(GLfloat); - } - - /* Allocate the src/dst row buffers. - * Keep two adjacent src rows around for bilinear sampling. - */ - srcBuffer0 = malloc(pixelSize * srcWidth); - srcBuffer1 = malloc(pixelSize * srcWidth); - dstBuffer = malloc(pixelSize * dstWidth); - if (!srcBuffer0 || !srcBuffer1 || !dstBuffer) { - goto fail_no_memory; - } - - for (i = 0; i < drawFb->_NumColorDrawBuffers; i++) { - gl_buffer_index idx = drawFb->_ColorDrawBufferIndexes[i]; - struct gl_renderbuffer_attachment *drawAtt; - struct gl_renderbuffer *drawRb; - mesa_format drawFormat; - - if (idx == BUFFER_NONE) - continue; - - drawAtt = &drawFb->Attachment[idx]; - drawRb = drawAtt->Renderbuffer; - if (!drawRb) - continue; - - drawFormat = _mesa_get_srgb_format_linear(drawRb->Format); - - /* - * Map src / dst renderbuffers - */ - if ((readRb == drawRb) || - (readAtt->Texture && drawAtt->Texture && - (readAtt->Texture == drawAtt->Texture))) { - /* map whole buffer for read/write */ - ctx->Driver.MapRenderbuffer(ctx, readRb, - 0, 0, readRb->Width, readRb->Height, - GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, - &srcMap, &srcRowStride, - readFb->FlipY); - if (!srcMap) { - goto fail_no_memory; - } - - dstMap = srcMap; - dstRowStride = srcRowStride; - } - else { - /* different src/dst buffers */ - /* XXX with a bit of work we could just map the regions to be - * read/written instead of the whole buffers. - */ - ctx->Driver.MapRenderbuffer(ctx, readRb, - 0, 0, readRb->Width, readRb->Height, - GL_MAP_READ_BIT, &srcMap, &srcRowStride, - readFb->FlipY); - if (!srcMap) { - goto fail_no_memory; - } - ctx->Driver.MapRenderbuffer(ctx, drawRb, - 0, 0, drawRb->Width, drawRb->Height, - GL_MAP_WRITE_BIT, &dstMap, &dstRowStride, - drawFb->FlipY); - if (!dstMap) { - ctx->Driver.UnmapRenderbuffer(ctx, readRb); - goto fail_no_memory; - } - } - - for (dstRow = 0; dstRow < dstHeight; dstRow++) { - const GLint dstY = dstYpos + dstRow; - GLfloat srcRow = (dstRow + 0.5F) / dstHeight * srcHeight - 0.5F; - GLint srcRow0 = MAX2(0, util_ifloor(srcRow)); - GLint srcRow1 = srcRow0 + 1; - GLfloat rowWeight = srcRow - srcRow0; /* fractional part of srcRow */ - - if (srcRow1 == srcHeight) { - /* last row fudge */ - srcRow1 = srcRow0; - rowWeight = 0.0; - } - - if (invertY) { - srcRow0 = srcHeight - 1 - srcRow0; - srcRow1 = srcHeight - 1 - srcRow1; - } - - srcY0 = srcYpos + srcRow0; - srcY1 = srcYpos + srcRow1; - - /* get the two source rows */ - if (srcY0 == srcBufferY0 && srcY1 == srcBufferY1) { - /* use same source row buffers again */ - } - else if (srcY0 == srcBufferY1) { - /* move buffer1 into buffer0 by swapping pointers */ - GLvoid *tmp = srcBuffer0; - srcBuffer0 = srcBuffer1; - srcBuffer1 = tmp; - /* get y1 row */ - { - GLubyte *src = srcMap + srcY1 * srcRowStride + srcXpos * bpp; - if (pixelType == GL_UNSIGNED_BYTE) { - _mesa_unpack_ubyte_rgba_row(readFormat, srcWidth, - src, srcBuffer1); - } - else { - _mesa_unpack_rgba_row(readFormat, srcWidth, - src, srcBuffer1); - } - } - srcBufferY0 = srcY0; - srcBufferY1 = srcY1; - } - else { - /* get both new rows */ - { - GLubyte *src0 = srcMap + srcY0 * srcRowStride + srcXpos * bpp; - GLubyte *src1 = srcMap + srcY1 * srcRowStride + srcXpos * bpp; - if (pixelType == GL_UNSIGNED_BYTE) { - _mesa_unpack_ubyte_rgba_row(readFormat, srcWidth, - src0, srcBuffer0); - _mesa_unpack_ubyte_rgba_row(readFormat, srcWidth, - src1, srcBuffer1); - } - else { - _mesa_unpack_rgba_row(readFormat, srcWidth, src0, srcBuffer0); - _mesa_unpack_rgba_row(readFormat, srcWidth, src1, srcBuffer1); - } - } - srcBufferY0 = srcY0; - srcBufferY1 = srcY1; - } - - if (pixelType == GL_UNSIGNED_BYTE) { - resample_linear_row_ub(srcWidth, dstWidth, srcBuffer0, srcBuffer1, - dstBuffer, invertX, rowWeight); - } - else { - resample_linear_row_float(srcWidth, dstWidth, srcBuffer0, srcBuffer1, - dstBuffer, invertX, rowWeight); - } - - /* store pixel row in destination */ - { - GLubyte *dst = dstMap + dstY * dstRowStride + dstXpos * bpp; - if (pixelType == GL_UNSIGNED_BYTE) { - _mesa_pack_ubyte_rgba_row(drawFormat, dstWidth, dstBuffer, dst); - } - else { - _mesa_pack_float_rgba_row(drawFormat, dstWidth, dstBuffer, dst); - } - } - } - - ctx->Driver.UnmapRenderbuffer(ctx, readRb); - if (drawRb != readRb) { - ctx->Driver.UnmapRenderbuffer(ctx, drawRb); - } - } - - free(srcBuffer0); - free(srcBuffer1); - free(dstBuffer); - return; - -fail_no_memory: - free(srcBuffer0); - free(srcBuffer1); - free(dstBuffer); - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer"); -} - - - -/** - * Software fallback for glBlitFramebufferEXT(). - */ -void -_swrast_BlitFramebuffer(struct gl_context *ctx, - struct gl_framebuffer *readFb, - struct gl_framebuffer *drawFb, - GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, - GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, - GLbitfield mask, GLenum filter) -{ - static const GLbitfield buffers[3] = { - GL_COLOR_BUFFER_BIT, - GL_DEPTH_BUFFER_BIT, - GL_STENCIL_BUFFER_BIT - }; - static const GLenum buffer_enums[3] = { - GL_COLOR, - GL_DEPTH, - GL_STENCIL, - }; - GLint i; - - /* Page 679 of OpenGL 4.4 spec says: - * "Added BlitFramebuffer to commands affected by conditional rendering in - * section 10.10 (Bug 9562)." - */ - if (!_mesa_check_conditional_render(ctx)) - return; /* Do not blit */ - - if (!_mesa_clip_blit(ctx, readFb, drawFb, &srcX0, &srcY0, &srcX1, &srcY1, - &dstX0, &dstY0, &dstX1, &dstY1)) { - return; - } - - if (SWRAST_CONTEXT(ctx)->NewState) - _swrast_validate_derived(ctx); - - /* First, try covering whatever buffers possible using the fast 1:1 copy - * path. - */ - if (srcX1 - srcX0 == dstX1 - dstX0 && - srcY1 - srcY0 == dstY1 - dstY0 && - srcX0 < srcX1 && - srcY0 < srcY1 && - dstX0 < dstX1 && - dstY0 < dstY1) { - for (i = 0; i < 3; i++) { - if (mask & buffers[i]) { - if (swrast_fast_copy_pixels(ctx, - readFb, drawFb, - srcX0, srcY0, - srcX1 - srcX0, srcY1 - srcY0, - dstX0, dstY0, - buffer_enums[i])) { - mask &= ~buffers[i]; - } - } - } - - if (!mask) - return; - } - - if (filter == GL_NEAREST) { - for (i = 0; i < 3; i++) { - if (mask & buffers[i]) { - blit_nearest(ctx, readFb, drawFb, srcX0, srcY0, srcX1, srcY1, - dstX0, dstY0, dstX1, dstY1, buffers[i]); - } - } - } - else { - assert(filter == GL_LINEAR); - if (mask & GL_COLOR_BUFFER_BIT) { /* depth/stencil not allowed */ - blit_linear(ctx, readFb, drawFb, srcX0, srcY0, srcX1, srcY1, - dstX0, dstY0, dstX1, dstY1); - } - } - -} diff --git a/src/mesa/swrast/s_chan.h b/src/mesa/swrast/s_chan.h deleted file mode 100644 index fa6c962..0000000 --- a/src/mesa/swrast/s_chan.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 2011 VMware, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -/** - * Types, macros, etc for the GLchan datatype. - * The swrast module is kind of hard-coded for 8bpp color channels but - * may be recompiled to use 16- or 32-bit color channels. But that - * feature is seldom used and is likely broken in various ways. - */ - -#ifndef U_CHAN_H -#define U_CHAN_H - - -#include "main/config.h" - - -/** - * Default bits per color channel: 8, 16 or 32 - */ -#ifndef CHAN_BITS -#define CHAN_BITS 8 -#endif - - -/** - * Color channel data type. - */ -#if CHAN_BITS == 8 - typedef GLubyte GLchan; -#define CHAN_MAX 255 -#define CHAN_MAXF 255.0F -#define CHAN_TYPE GL_UNSIGNED_BYTE -#elif CHAN_BITS == 16 - typedef GLushort GLchan; -#define CHAN_MAX 65535 -#define CHAN_MAXF 65535.0F -#define CHAN_TYPE GL_UNSIGNED_SHORT -#elif CHAN_BITS == 32 - typedef GLfloat GLchan; -#define CHAN_MAX 1.0 -#define CHAN_MAXF 1.0F -#define CHAN_TYPE GL_FLOAT -#else -#error "illegal number of color channel bits" -#endif - - -#if CHAN_BITS == 8 - -#define CHAN_TO_UBYTE(c) (c) -#define CHAN_TO_USHORT(c) (((c) << 8) | (c)) -#define CHAN_TO_SHORT(c) (((c) << 7) | ((c) >> 1)) -#define CHAN_TO_FLOAT(c) UBYTE_TO_FLOAT(c) - -#define CLAMPED_FLOAT_TO_CHAN(c, f) CLAMPED_FLOAT_TO_UBYTE(c, f) -#define UNCLAMPED_FLOAT_TO_CHAN(c, f) UNCLAMPED_FLOAT_TO_UBYTE(c, f) - -#define COPY_CHAN4(DST, SRC) COPY_4UBV(DST, SRC) - -#elif CHAN_BITS == 16 - -#define CHAN_TO_UBYTE(c) ((c) >> 8) -#define CHAN_TO_USHORT(c) (c) -#define CHAN_TO_SHORT(c) ((c) >> 1) -#define CHAN_TO_FLOAT(c) ((GLfloat) ((c) * (1.0 / CHAN_MAXF))) - -#define CLAMPED_FLOAT_TO_CHAN(c, f) CLAMPED_FLOAT_TO_USHORT(c, f) -#define UNCLAMPED_FLOAT_TO_CHAN(c, f) UNCLAMPED_FLOAT_TO_USHORT(c, f) - -#define COPY_CHAN4(DST, SRC) COPY_4V(DST, SRC) - -#elif CHAN_BITS == 32 - -#define CHAN_TO_UBYTE(c) FLOAT_TO_UBYTE(c) -#define CHAN_TO_USHORT(c) ((GLushort) (SATURATE((c)) * 65535.0)) -#define CHAN_TO_SHORT(c) ((GLshort) (SATURATE((c)) * 32767.0)) -#define CHAN_TO_FLOAT(c) (c) - -#define CLAMPED_FLOAT_TO_CHAN(c, f) c = (f) -#define UNCLAMPED_FLOAT_TO_CHAN(c, f) c = (f) - -#define COPY_CHAN4(DST, SRC) COPY_4V(DST, SRC) - -#else - -#error unexpected CHAN_BITS size - -#endif - - -/** - * Convert 4 floats to GLchan values. - * \param dst pointer to destination GLchan[4] array. - * \param f pointer to source GLfloat[4] array. - */ -#define UNCLAMPED_FLOAT_TO_RGBA_CHAN(dst, f) \ -do { \ - UNCLAMPED_FLOAT_TO_CHAN((dst)[0], (f)[0]); \ - UNCLAMPED_FLOAT_TO_CHAN((dst)[1], (f)[1]); \ - UNCLAMPED_FLOAT_TO_CHAN((dst)[2], (f)[2]); \ - UNCLAMPED_FLOAT_TO_CHAN((dst)[3], (f)[3]); \ -} while (0) - - - -#endif /* U_CHAN_H */ diff --git a/src/mesa/swrast/s_clear.c b/src/mesa/swrast/s_clear.c deleted file mode 100644 index 91a19f1..0000000 --- a/src/mesa/swrast/s_clear.c +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -#include "main/glheader.h" -#include "main/accum.h" -#include "main/condrender.h" -#include "main/format_pack.h" -#include "main/macros.h" - -#include "main/mtypes.h" - -#include "s_context.h" -#include "s_depth.h" -#include "s_stencil.h" - - -/** - * Convert a boolean color mask to a packed color where each channel of - * the packed value at dst will be 0 or ~0 depending on the colorMask. - */ -static void -_pack_colormask(mesa_format format, const uint8_t colorMask[4], void *dst) -{ - float maskColor[4]; - - switch (_mesa_get_format_datatype(format)) { - case GL_UNSIGNED_NORMALIZED: - /* simple: 1.0 will convert to ~0 in the right bit positions */ - maskColor[0] = colorMask[0] ? 1.0f : 0.0f; - maskColor[1] = colorMask[1] ? 1.0f : 0.0f; - maskColor[2] = colorMask[2] ? 1.0f : 0.0f; - maskColor[3] = colorMask[3] ? 1.0f : 0.0f; - _mesa_pack_float_rgba_row(format, 1, - (const float (*)[4]) maskColor, dst); - break; - case GL_SIGNED_NORMALIZED: - case GL_FLOAT: - /* These formats are harder because it's hard to know the floating - * point values that will convert to ~0 for each color channel's bits. - * This solution just generates a non-zero value for each color channel - * then fixes up the non-zero values to be ~0. - * Note: we'll need to add special case code if we ever have to deal - * with formats with unequal color channel sizes, like R11_G11_B10. - * We issue a warning below for channel sizes other than 8,16,32. - */ - { - uint32_t bits = _mesa_get_format_max_bits(format); /* bits per chan */ - uint32_t bytes = _mesa_get_format_bytes(format); - uint32_t i; - - /* this should put non-zero values into the channels of dst */ - maskColor[0] = colorMask[0] ? -1.0f : 0.0f; - maskColor[1] = colorMask[1] ? -1.0f : 0.0f; - maskColor[2] = colorMask[2] ? -1.0f : 0.0f; - maskColor[3] = colorMask[3] ? -1.0f : 0.0f; - _mesa_pack_float_rgba_row(format, 1, - (const float (*)[4]) maskColor, dst); - - /* fix-up the dst channels by converting non-zero values to ~0 */ - if (bits == 8) { - uint8_t *d = (uint8_t *) dst; - for (i = 0; i < bytes; i++) { - d[i] = d[i] ? 0xff : 0x0; - } - } - else if (bits == 16) { - uint16_t *d = (uint16_t *) dst; - for (i = 0; i < bytes / 2; i++) { - d[i] = d[i] ? 0xffff : 0x0; - } - } - else if (bits == 32) { - uint32_t *d = (uint32_t *) dst; - for (i = 0; i < bytes / 4; i++) { - d[i] = d[i] ? 0xffffffffU : 0x0; - } - } - else { - unreachable("unexpected size in _mesa_pack_colormask()"); - } - } - break; - default: - unreachable("unexpected format data type in gen_color_mask()"); - } -} - -/** - * Clear an rgba color buffer with masking if needed. - */ -static void -clear_rgba_buffer(struct gl_context *ctx, struct gl_renderbuffer *rb, - const GLubyte colorMask[4]) -{ - const GLint x = ctx->DrawBuffer->_Xmin; - const GLint y = ctx->DrawBuffer->_Ymin; - const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; - const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; - const GLuint pixelSize = _mesa_get_format_bytes(rb->Format); - const GLboolean doMasking = (colorMask[0] == 0 || - colorMask[1] == 0 || - colorMask[2] == 0 || - colorMask[3] == 0); - const GLfloat (*clearColor)[4] = - (const GLfloat (*)[4]) ctx->Color.ClearColor.f; - GLbitfield mapMode = GL_MAP_WRITE_BIT; - GLubyte *map; - GLint rowStride; - GLint i, j; - - if (doMasking) { - /* we'll need to read buffer values too */ - mapMode |= GL_MAP_READ_BIT; - } - - /* map dest buffer */ - ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, - mapMode, &map, &rowStride, - ctx->DrawBuffer->FlipY); - if (!map) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClear(color)"); - return; - } - - /* for 1, 2, 4-byte clearing */ -#define SIMPLE_TYPE_CLEAR(TYPE) \ - do { \ - TYPE pixel, pixelMask; \ - _mesa_pack_float_rgba_row(rb->Format, 1, clearColor, &pixel); \ - if (doMasking) { \ - _pack_colormask(rb->Format, colorMask, &pixelMask); \ - pixel &= pixelMask; \ - pixelMask = ~pixelMask; \ - } \ - for (i = 0; i < height; i++) { \ - TYPE *row = (TYPE *) map; \ - if (doMasking) { \ - for (j = 0; j < width; j++) { \ - row[j] = (row[j] & pixelMask) | pixel; \ - } \ - } \ - else { \ - for (j = 0; j < width; j++) { \ - row[j] = pixel; \ - } \ - } \ - map += rowStride; \ - } \ - } while (0) - - - /* for 3, 6, 8, 12, 16-byte clearing */ -#define MULTI_WORD_CLEAR(TYPE, N) \ - do { \ - TYPE pixel[N], pixelMask[N]; \ - GLuint k; \ - _mesa_pack_float_rgba_row(rb->Format, 1, clearColor, pixel); \ - if (doMasking) { \ - _pack_colormask(rb->Format, colorMask, pixelMask); \ - for (k = 0; k < N; k++) { \ - pixel[k] &= pixelMask[k]; \ - pixelMask[k] = ~pixelMask[k]; \ - } \ - } \ - for (i = 0; i < height; i++) { \ - TYPE *row = (TYPE *) map; \ - if (doMasking) { \ - for (j = 0; j < width; j++) { \ - for (k = 0; k < N; k++) { \ - row[j * N + k] = \ - (row[j * N + k] & pixelMask[k]) | pixel[k]; \ - } \ - } \ - } \ - else { \ - for (j = 0; j < width; j++) { \ - for (k = 0; k < N; k++) { \ - row[j * N + k] = pixel[k]; \ - } \ - } \ - } \ - map += rowStride; \ - } \ - } while(0) - - switch (pixelSize) { - case 1: - SIMPLE_TYPE_CLEAR(GLubyte); - break; - case 2: - SIMPLE_TYPE_CLEAR(GLushort); - break; - case 3: - MULTI_WORD_CLEAR(GLubyte, 3); - break; - case 4: - SIMPLE_TYPE_CLEAR(GLuint); - break; - case 6: - MULTI_WORD_CLEAR(GLushort, 3); - break; - case 8: - MULTI_WORD_CLEAR(GLuint, 2); - break; - case 12: - MULTI_WORD_CLEAR(GLuint, 3); - break; - case 16: - MULTI_WORD_CLEAR(GLuint, 4); - break; - default: - _mesa_problem(ctx, "bad pixel size in clear_rgba_buffer()"); - } - - /* unmap buffer */ - ctx->Driver.UnmapRenderbuffer(ctx, rb); -} - - -/** - * Clear the front/back/left/right/aux color buffers. - * This function is usually only called if the device driver can't - * clear its own color buffers for some reason (such as with masking). - */ -static void -clear_color_buffers(struct gl_context *ctx) -{ - GLuint buf; - - for (buf = 0; buf < ctx->DrawBuffer->_NumColorDrawBuffers; buf++) { - struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[buf]; - - /* If this is an ES2 context or GL_ARB_ES2_compatibility is supported, - * the framebuffer can be complete with some attachments be missing. In - * this case the _ColorDrawBuffers pointer will be NULL. - */ - if (rb == NULL) - continue; - - const GLubyte colormask[4] = { - GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 0) ? 0xff : 0, - GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 1) ? 0xff : 0, - GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 2) ? 0xff : 0, - GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 3) ? 0xff : 0, - }; - clear_rgba_buffer(ctx, rb, colormask); - } -} - - -/** - * Called via the device driver's ctx->Driver.Clear() function if the - * device driver can't clear one or more of the buffers itself. - * \param buffers bitfield of BUFFER_BIT_* values indicating which - * renderbuffers are to be cleared. - * \param all if GL_TRUE, clear whole buffer, else clear specified region. - */ -void -_swrast_Clear(struct gl_context *ctx, GLbitfield buffers) -{ - const GLbitfield BUFFER_DS = BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL; - -#ifdef DEBUG_FOO - { - const GLbitfield legalBits = - BUFFER_BIT_FRONT_LEFT | - BUFFER_BIT_FRONT_RIGHT | - BUFFER_BIT_BACK_LEFT | - BUFFER_BIT_BACK_RIGHT | - BUFFER_BIT_DEPTH | - BUFFER_BIT_STENCIL | - BUFFER_BIT_ACCUM; - assert((buffers & (~legalBits)) == 0); - } -#endif - - if (!_mesa_check_conditional_render(ctx)) - return; /* don't clear */ - - if (SWRAST_CONTEXT(ctx)->NewState) - _swrast_validate_derived(ctx); - - if ((buffers & BUFFER_BITS_COLOR) - && (ctx->DrawBuffer->_NumColorDrawBuffers > 0)) { - clear_color_buffers(ctx); - } - - if (buffers & BUFFER_BIT_ACCUM) { - _mesa_clear_accum_buffer(ctx); - } - - if (buffers & BUFFER_DS) { - struct gl_renderbuffer *depthRb = - ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; - struct gl_renderbuffer *stencilRb = - ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer; - - if ((buffers & BUFFER_DS) == BUFFER_DS && depthRb == stencilRb) { - /* clear depth and stencil together */ - _swrast_clear_depth_stencil_buffer(ctx); - } - else { - /* clear depth, stencil separately */ - if (buffers & BUFFER_BIT_DEPTH) { - _swrast_clear_depth_buffer(ctx); - } - if (buffers & BUFFER_BIT_STENCIL) { - _swrast_clear_stencil_buffer(ctx); - } - } - } -} diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c deleted file mode 100644 index fa4eb7a..0000000 --- a/src/mesa/swrast/s_context.c +++ /dev/null @@ -1,953 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - * - * Authors: - * Keith Whitwell Brian Paul - */ - -#include "main/errors.h" - -#include "main/bufferobj.h" -#include "main/mtypes.h" -#include "main/samplerobj.h" -#include "main/state.h" -#include "main/stencil.h" -#include "main/teximage.h" -#include "program/prog_parameter.h" -#include "program/prog_statevars.h" -#include "swrast.h" -#include "s_blend.h" -#include "s_context.h" -#include "s_lines.h" -#include "s_points.h" -#include "s_span.h" -#include "s_texfetch.h" -#include "s_triangle.h" -#include "s_texfilter.h" - - -/** - * Recompute the value of swrast->_RasterMask, etc. according to - * the current context. The _RasterMask field can be easily tested by - * drivers to determine certain basic GL state (does the primitive need - * stenciling, logic-op, fog, etc?). - */ -static void -_swrast_update_rasterflags( struct gl_context *ctx ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - GLbitfield rasterMask = 0; - GLuint i; - - if (ctx->Color.AlphaEnabled) rasterMask |= ALPHATEST_BIT; - if (ctx->Color.BlendEnabled) rasterMask |= BLEND_BIT; - if (ctx->Depth.Test) rasterMask |= DEPTH_BIT; - if (swrast->_FogEnabled) rasterMask |= FOG_BIT; - if (ctx->Scissor.EnableFlags) rasterMask |= CLIP_BIT; - if (_mesa_stencil_is_enabled(ctx)) rasterMask |= STENCIL_BIT; - for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { - if (GET_COLORMASK(ctx->Color.ColorMask, i) != 0xf) { - rasterMask |= MASKING_BIT; - break; - } - } - if (ctx->Color.ColorLogicOpEnabled) rasterMask |= LOGIC_OP_BIT; - if (ctx->Texture._MaxEnabledTexImageUnit >= 0) rasterMask |= TEXTURE_BIT; - if ( ctx->ViewportArray[0].X < 0 - || ctx->ViewportArray[0].X + ctx->ViewportArray[0].Width > (GLfloat) ctx->DrawBuffer->Width - || ctx->ViewportArray[0].Y < 0 - || ctx->ViewportArray[0].Y + ctx->ViewportArray[0].Height > (GLfloat) ctx->DrawBuffer->Height) { - rasterMask |= CLIP_BIT; - } - - if (ctx->Query.CurrentOcclusionObject) - rasterMask |= OCCLUSION_BIT; - - - /* If we're not drawing to exactly one color buffer set the - * MULTI_DRAW_BIT flag. Also set it if we're drawing to no - * buffers or the RGBA or CI mask disables all writes. - */ - if (ctx->DrawBuffer->_NumColorDrawBuffers != 1) { - /* more than one color buffer designated for writing (or zero buffers) */ - rasterMask |= MULTI_DRAW_BIT; - } - - for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { - if (GET_COLORMASK(ctx->Color.ColorMask, i) == 0) { - rasterMask |= MULTI_DRAW_BIT; /* all RGBA channels disabled */ - break; - } - } - - - if (_swrast_use_fragment_program(ctx)) { - rasterMask |= FRAGPROG_BIT; - } - - if (_mesa_ati_fragment_shader_enabled(ctx)) { - rasterMask |= ATIFRAGSHADER_BIT; - } - -#if CHAN_TYPE == GL_FLOAT - if (ctx->Color.ClampFragmentColor == GL_TRUE) { - rasterMask |= CLAMPING_BIT; - } -#endif - - SWRAST_CONTEXT(ctx)->_RasterMask = rasterMask; -} - - -/** - * Examine polygon cull state to compute the _BackfaceCullSign field. - * _BackfaceCullSign will be 0 if no culling, -1 if culling back-faces, - * and 1 if culling front-faces. The Polygon FrontFace state also - * factors in. - */ -static void -_swrast_update_polygon( struct gl_context *ctx ) -{ - GLfloat backface_sign; - - if (ctx->Polygon.CullFlag) { - switch (ctx->Polygon.CullFaceMode) { - case GL_BACK: - backface_sign = -1.0F; - break; - case GL_FRONT: - backface_sign = 1.0F; - break; - case GL_FRONT_AND_BACK: - FALLTHROUGH; - default: - backface_sign = 0.0F; - } - } - else { - backface_sign = 0.0F; - } - - SWRAST_CONTEXT(ctx)->_BackfaceCullSign = backface_sign; - - /* This is for front/back-face determination, but not for culling */ - SWRAST_CONTEXT(ctx)->_BackfaceSign - = (ctx->Polygon.FrontFace == GL_CW) ? -1.0F : 1.0F; -} - - - -/** - * Update the _PreferPixelFog field to indicate if we need to compute - * fog blend factors (from the fog coords) per-fragment. - */ -static void -_swrast_update_fog_hint( struct gl_context *ctx ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - swrast->_PreferPixelFog = (!swrast->AllowVertexFog || - _swrast_use_fragment_program(ctx) || - (ctx->Hint.Fog == GL_NICEST && - swrast->AllowPixelFog)); -} - - - -/** - * Update the swrast->_TextureCombinePrimary flag. - */ -static void -_swrast_update_texture_env( struct gl_context *ctx ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - GLuint i; - - swrast->_TextureCombinePrimary = GL_FALSE; - - for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { - const struct gl_tex_env_combine_state *combine = - ctx->Texture.FixedFuncUnit[i]._CurrentCombine; - GLuint term; - for (term = 0; term < combine->_NumArgsRGB; term++) { - if (combine->SourceRGB[term] == GL_PRIMARY_COLOR) { - swrast->_TextureCombinePrimary = GL_TRUE; - return; - } - if (combine->SourceA[term] == GL_PRIMARY_COLOR) { - swrast->_TextureCombinePrimary = GL_TRUE; - return; - } - } - } -} - - -/** - * Determine if we can defer texturing/shading until after Z/stencil - * testing. This potentially allows us to skip texturing/shading for - * lots of fragments. - */ -static void -_swrast_update_deferred_texture(struct gl_context *ctx) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - if (ctx->Color.AlphaEnabled) { - /* alpha test depends on post-texture/shader colors */ - swrast->_DeferredTexture = GL_FALSE; - } - else { - GLboolean use_fprog = _swrast_use_fragment_program(ctx); - const struct gl_program *fprog = ctx->FragmentProgram._Current; - if (use_fprog && - (fprog->info.outputs_written & (1 << FRAG_RESULT_DEPTH))) { - /* Z comes from fragment program/shader */ - swrast->_DeferredTexture = GL_FALSE; - } - else if (use_fprog && fprog->info.fs.uses_discard) { - swrast->_DeferredTexture = GL_FALSE; - } - else if (ctx->Query.CurrentOcclusionObject) { - /* occlusion query depends on shader discard/kill results */ - swrast->_DeferredTexture = GL_FALSE; - } - else { - swrast->_DeferredTexture = GL_TRUE; - } - } -} - - -/** - * Update swrast->_FogColor and swrast->_FogEnable values. - */ -static void -_swrast_update_fog_state( struct gl_context *ctx ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - const struct gl_program *fp = ctx->FragmentProgram._Current; - - assert(fp == NULL || fp->Target == GL_FRAGMENT_PROGRAM_ARB); - (void) fp; /* silence unused var warning */ - - /* determine if fog is needed, and if so, which fog mode */ - swrast->_FogEnabled = (!_swrast_use_fragment_program(ctx) && - ctx->Fog.Enabled); -} - - -/** - * Update state for running fragment programs. Basically, load the - * program parameters with current state values. - */ -static void -_swrast_update_fragment_program(struct gl_context *ctx, GLbitfield newState) -{ - if (!_swrast_use_fragment_program(ctx)) - return; - - _mesa_load_state_parameters(ctx, - ctx->FragmentProgram._Current->Parameters); -} - - -/** - * See if we can do early diffuse+specular (primary+secondary) color - * add per vertex instead of per-fragment. - */ -static void -_swrast_update_specular_vertex_add(struct gl_context *ctx) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - GLboolean separateSpecular = ctx->Fog.ColorSumEnabled || - (ctx->Light.Enabled && - ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR); - - swrast->SpecularVertexAdd = (separateSpecular - && ctx->Texture._MaxEnabledTexImageUnit == -1 - && !_swrast_use_fragment_program(ctx) - && !_mesa_ati_fragment_shader_enabled(ctx)); -} - - -#define _SWRAST_NEW_DERIVED (_SWRAST_NEW_RASTERMASK | \ - _NEW_PROGRAM_CONSTANTS | \ - _NEW_TEXTURE | \ - _NEW_HINT | \ - _NEW_POLYGON ) - -/* State referenced by _swrast_choose_triangle, _swrast_choose_line. - */ -#define _SWRAST_NEW_TRIANGLE (_SWRAST_NEW_DERIVED | \ - _NEW_RENDERMODE| \ - _NEW_POLYGON| \ - _NEW_DEPTH| \ - _NEW_STENCIL| \ - _NEW_COLOR| \ - _NEW_TEXTURE| \ - _SWRAST_NEW_RASTERMASK| \ - _NEW_LIGHT| \ - _NEW_FOG | \ - _MESA_NEW_SEPARATE_SPECULAR) - -#define _SWRAST_NEW_LINE (_SWRAST_NEW_DERIVED | \ - _NEW_RENDERMODE| \ - _NEW_LINE| \ - _NEW_TEXTURE| \ - _NEW_LIGHT| \ - _NEW_FOG| \ - _NEW_DEPTH | \ - _MESA_NEW_SEPARATE_SPECULAR) - -#define _SWRAST_NEW_POINT (_SWRAST_NEW_DERIVED | \ - _NEW_RENDERMODE | \ - _NEW_POINT | \ - _NEW_TEXTURE | \ - _NEW_LIGHT | \ - _NEW_FOG | \ - _MESA_NEW_SEPARATE_SPECULAR) - -#define _SWRAST_NEW_TEXTURE_SAMPLE_FUNC _NEW_TEXTURE - -#define _SWRAST_NEW_TEXTURE_ENV_MODE _NEW_TEXTURE - -#define _SWRAST_NEW_BLEND_FUNC _NEW_COLOR - - - -/** - * Stub for swrast->Triangle to select a true triangle function - * after a state change. - */ -static void -_swrast_validate_triangle( struct gl_context *ctx, - const SWvertex *v0, - const SWvertex *v1, - const SWvertex *v2 ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - - _swrast_validate_derived( ctx ); - swrast->choose_triangle( ctx ); - assert(swrast->Triangle); - - if (swrast->SpecularVertexAdd) { - /* separate specular color, but no texture */ - swrast->SpecTriangle = swrast->Triangle; - swrast->Triangle = _swrast_add_spec_terms_triangle; - } - - swrast->Triangle( ctx, v0, v1, v2 ); -} - -/** - * Called via swrast->Line. Examine current GL state and choose a software - * line routine. Then call it. - */ -static void -_swrast_validate_line( struct gl_context *ctx, const SWvertex *v0, const SWvertex *v1 ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - - _swrast_validate_derived( ctx ); - swrast->choose_line( ctx ); - assert(swrast->Line); - - if (swrast->SpecularVertexAdd) { - swrast->SpecLine = swrast->Line; - swrast->Line = _swrast_add_spec_terms_line; - } - - swrast->Line( ctx, v0, v1 ); -} - -/** - * Called via swrast->Point. Examine current GL state and choose a software - * point routine. Then call it. - */ -static void -_swrast_validate_point( struct gl_context *ctx, const SWvertex *v0 ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - - _swrast_validate_derived( ctx ); - swrast->choose_point( ctx ); - - if (swrast->SpecularVertexAdd) { - swrast->SpecPoint = swrast->Point; - swrast->Point = _swrast_add_spec_terms_point; - } - - swrast->Point( ctx, v0 ); -} - - -/** - * Called via swrast->BlendFunc. Examine GL state to choose a blending - * function, then call it. - */ -static void -_swrast_validate_blend_func(struct gl_context *ctx, GLuint n, const GLubyte mask[], - GLvoid *src, const GLvoid *dst, - GLenum chanType ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - - _swrast_validate_derived( ctx ); /* why is this needed? */ - _swrast_choose_blend_func( ctx, chanType ); - - swrast->BlendFunc( ctx, n, mask, src, dst, chanType ); -} - -static void -_swrast_sleep( struct gl_context *ctx, GLbitfield new_state ) -{ - (void) ctx; (void) new_state; -} - - -static void -_swrast_invalidate_state( struct gl_context *ctx, GLbitfield new_state ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - GLuint i; - - swrast->NewState |= new_state; - - /* After 10 statechanges without any swrast functions being called, - * put the module to sleep. - */ - if (++swrast->StateChanges > 10) { - swrast->InvalidateState = _swrast_sleep; - swrast->NewState = ~0; - new_state = ~0; - } - - if (new_state & swrast->InvalidateTriangleMask) - swrast->Triangle = _swrast_validate_triangle; - - if (new_state & swrast->InvalidateLineMask) - swrast->Line = _swrast_validate_line; - - if (new_state & swrast->InvalidatePointMask) - swrast->Point = _swrast_validate_point; - - if (new_state & _SWRAST_NEW_BLEND_FUNC) - swrast->BlendFunc = _swrast_validate_blend_func; - - if (new_state & _SWRAST_NEW_TEXTURE_SAMPLE_FUNC) - for (i = 0 ; i < ARRAY_SIZE(swrast->TextureSample); i++) - swrast->TextureSample[i] = NULL; -} - - -void -_swrast_update_texture_samplers(struct gl_context *ctx) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - GLuint u; - - if (!swrast) - return; /* pipe hack */ - - for (u = 0; u < ARRAY_SIZE(swrast->TextureSample); u++) { - struct gl_texture_object *tObj = ctx->Texture.Unit[u]._Current; - /* Note: If tObj is NULL, the sample function will be a simple - * function that just returns opaque black (0,0,0,1). - */ - _mesa_update_fetch_functions(ctx, u); - swrast->TextureSample[u] = - _swrast_choose_texture_sample_func(ctx, tObj, - _mesa_get_samplerobj(ctx, u)); - } -} - - -/** - * Update swrast->_ActiveAttribs, swrast->_NumActiveAttribs, - * swrast->_ActiveAtttribMask. - */ -static void -_swrast_update_active_attribs(struct gl_context *ctx) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - GLbitfield64 attribsMask; - - /* - * Compute _ActiveAttribsMask = which fragment attributes are needed. - */ - if (_swrast_use_fragment_program(ctx)) { - /* fragment program/shader */ - attribsMask = ctx->FragmentProgram._Current->info.inputs_read; - attribsMask &= ~VARYING_BIT_POS; /* WPOS is always handled specially */ - } - else if (_mesa_ati_fragment_shader_enabled(ctx)) { - attribsMask = VARYING_BIT_COL0 | VARYING_BIT_COL1 | - VARYING_BIT_FOGC | VARYING_BITS_TEX_ANY; - } - else { - /* fixed function */ - attribsMask = 0x0; - -#if CHAN_TYPE == GL_FLOAT - attribsMask |= VARYING_BIT_COL0; -#endif - - if (ctx->Fog.ColorSumEnabled || - (ctx->Light.Enabled && - ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) { - attribsMask |= VARYING_BIT_COL1; - } - - if (swrast->_FogEnabled) - attribsMask |= VARYING_BIT_FOGC; - - attribsMask |= (ctx->Texture._EnabledCoordUnits << VARYING_SLOT_TEX0); - } - - swrast->_ActiveAttribMask = attribsMask; - - /* Update _ActiveAttribs[] list */ - { - GLuint i, num = 0; - for (i = 0; i < VARYING_SLOT_MAX; i++) { - if (attribsMask & BITFIELD64_BIT(i)) { - swrast->_ActiveAttribs[num++] = i; - /* how should this attribute be interpolated? */ - if (i == VARYING_SLOT_COL0 || i == VARYING_SLOT_COL1) - swrast->_InterpMode[i] = ctx->Light.ShadeModel; - else - swrast->_InterpMode[i] = GL_SMOOTH; - } - } - swrast->_NumActiveAttribs = num; - } -} - - -void -_swrast_validate_derived( struct gl_context *ctx ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - - if (swrast->NewState) { - if (swrast->NewState & _NEW_POLYGON) - _swrast_update_polygon( ctx ); - - if (swrast->NewState & (_NEW_HINT | _NEW_PROGRAM)) - _swrast_update_fog_hint( ctx ); - - if (swrast->NewState & _SWRAST_NEW_TEXTURE_ENV_MODE) - _swrast_update_texture_env( ctx ); - - if (swrast->NewState & (_NEW_FOG | _NEW_PROGRAM)) - _swrast_update_fog_state( ctx ); - - if (swrast->NewState & (_NEW_PROGRAM_CONSTANTS | _NEW_PROGRAM)) - _swrast_update_fragment_program( ctx, swrast->NewState ); - - if (swrast->NewState & (_NEW_TEXTURE | _NEW_PROGRAM)) { - _swrast_update_texture_samplers( ctx ); - } - - if (swrast->NewState & (_NEW_COLOR | _NEW_PROGRAM)) - _swrast_update_deferred_texture(ctx); - - if (swrast->NewState & _SWRAST_NEW_RASTERMASK) - _swrast_update_rasterflags( ctx ); - - if (swrast->NewState & (_NEW_DEPTH | - _NEW_FOG | - _NEW_LIGHT | - _NEW_PROGRAM | - _NEW_TEXTURE)) - _swrast_update_active_attribs(ctx); - - if (swrast->NewState & (_NEW_FOG | - _NEW_PROGRAM | - _NEW_LIGHT | - _NEW_TEXTURE)) - _swrast_update_specular_vertex_add(ctx); - - swrast->NewState = 0; - swrast->StateChanges = 0; - swrast->InvalidateState = _swrast_invalidate_state; - } -} - -#define SWRAST_DEBUG 0 - -/* Public entrypoints: See also s_bitmap.c, etc. - */ -void -_swrast_Quad( struct gl_context *ctx, - const SWvertex *v0, const SWvertex *v1, - const SWvertex *v2, const SWvertex *v3 ) -{ - if (SWRAST_DEBUG) { - _mesa_debug(ctx, "_swrast_Quad\n"); - _swrast_print_vertex( ctx, v0 ); - _swrast_print_vertex( ctx, v1 ); - _swrast_print_vertex( ctx, v2 ); - _swrast_print_vertex( ctx, v3 ); - } - SWRAST_CONTEXT(ctx)->Triangle( ctx, v0, v1, v3 ); - SWRAST_CONTEXT(ctx)->Triangle( ctx, v1, v2, v3 ); -} - -void -_swrast_Triangle( struct gl_context *ctx, const SWvertex *v0, - const SWvertex *v1, const SWvertex *v2 ) -{ - if (SWRAST_DEBUG) { - _mesa_debug(ctx, "_swrast_Triangle\n"); - _swrast_print_vertex( ctx, v0 ); - _swrast_print_vertex( ctx, v1 ); - _swrast_print_vertex( ctx, v2 ); - } - SWRAST_CONTEXT(ctx)->Triangle( ctx, v0, v1, v2 ); -} - -void -_swrast_Line( struct gl_context *ctx, const SWvertex *v0, const SWvertex *v1 ) -{ - if (SWRAST_DEBUG) { - _mesa_debug(ctx, "_swrast_Line\n"); - _swrast_print_vertex( ctx, v0 ); - _swrast_print_vertex( ctx, v1 ); - } - SWRAST_CONTEXT(ctx)->Line( ctx, v0, v1 ); -} - -void -_swrast_Point( struct gl_context *ctx, const SWvertex *v0 ) -{ - if (SWRAST_DEBUG) { - _mesa_debug(ctx, "_swrast_Point\n"); - _swrast_print_vertex( ctx, v0 ); - } - SWRAST_CONTEXT(ctx)->Point( ctx, v0 ); -} - -void -_swrast_InvalidateState( struct gl_context *ctx, GLbitfield new_state ) -{ - if (SWRAST_DEBUG) { - _mesa_debug(ctx, "_swrast_InvalidateState\n"); - } - SWRAST_CONTEXT(ctx)->InvalidateState( ctx, new_state ); -} - -void -_swrast_ResetLineStipple( struct gl_context *ctx ) -{ - if (SWRAST_DEBUG) { - _mesa_debug(ctx, "_swrast_ResetLineStipple\n"); - } - SWRAST_CONTEXT(ctx)->StippleCounter = 0; -} - -void -_swrast_SetFacing(struct gl_context *ctx, GLuint facing) -{ - SWRAST_CONTEXT(ctx)->PointLineFacing = facing; -} - -void -_swrast_allow_vertex_fog( struct gl_context *ctx, GLboolean value ) -{ - if (SWRAST_DEBUG) { - _mesa_debug(ctx, "_swrast_allow_vertex_fog %d\n", value); - } - SWRAST_CONTEXT(ctx)->InvalidateState( ctx, _NEW_HINT ); - SWRAST_CONTEXT(ctx)->AllowVertexFog = value; -} - -void -_swrast_allow_pixel_fog( struct gl_context *ctx, GLboolean value ) -{ - if (SWRAST_DEBUG) { - _mesa_debug(ctx, "_swrast_allow_pixel_fog %d\n", value); - } - SWRAST_CONTEXT(ctx)->InvalidateState( ctx, _NEW_HINT ); - SWRAST_CONTEXT(ctx)->AllowPixelFog = value; -} - - -/** - * Initialize native program limits by copying the logical limits. - * See comments in init_program_limits() in context.c - */ -static void -init_program_native_limits(struct gl_program_constants *prog) -{ - prog->MaxNativeInstructions = prog->MaxInstructions; - prog->MaxNativeAluInstructions = prog->MaxAluInstructions; - prog->MaxNativeTexInstructions = prog->MaxTexInstructions; - prog->MaxNativeTexIndirections = prog->MaxTexIndirections; - prog->MaxNativeAttribs = prog->MaxAttribs; - prog->MaxNativeTemps = prog->MaxTemps; - prog->MaxNativeAddressRegs = prog->MaxAddressRegs; - prog->MaxNativeParameters = prog->MaxParameters; -} - - -GLboolean -_swrast_CreateContext( struct gl_context *ctx ) -{ - GLuint i; - SWcontext *swrast = calloc(1, sizeof(SWcontext)); -#ifdef _OPENMP - const GLuint maxThreads = omp_get_max_threads(); -#else - const GLuint maxThreads = 1; -#endif - - assert(ctx->Const.MaxViewportWidth <= SWRAST_MAX_WIDTH); - assert(ctx->Const.MaxViewportHeight <= SWRAST_MAX_WIDTH); - - assert(ctx->Const.MaxRenderbufferSize <= SWRAST_MAX_WIDTH); - - /* make sure largest texture image is <= SWRAST_MAX_WIDTH in size */ - assert(ctx->Const.MaxTextureSize <= SWRAST_MAX_WIDTH); - assert((1 << (ctx->Const.MaxCubeTextureLevels - 1)) <= SWRAST_MAX_WIDTH); - assert((1 << (ctx->Const.Max3DTextureLevels - 1)) <= SWRAST_MAX_WIDTH); - - assert(PROG_MAX_WIDTH == SWRAST_MAX_WIDTH); - - if (SWRAST_DEBUG) { - _mesa_debug(ctx, "_swrast_CreateContext\n"); - } - - if (!swrast) - return GL_FALSE; - - swrast->NewState = ~0; - - swrast->choose_point = _swrast_choose_point; - swrast->choose_line = _swrast_choose_line; - swrast->choose_triangle = _swrast_choose_triangle; - - swrast->InvalidatePointMask = _SWRAST_NEW_POINT; - swrast->InvalidateLineMask = _SWRAST_NEW_LINE; - swrast->InvalidateTriangleMask = _SWRAST_NEW_TRIANGLE; - - swrast->Point = _swrast_validate_point; - swrast->Line = _swrast_validate_line; - swrast->Triangle = _swrast_validate_triangle; - swrast->InvalidateState = _swrast_sleep; - swrast->BlendFunc = _swrast_validate_blend_func; - - swrast->AllowVertexFog = GL_TRUE; - swrast->AllowPixelFog = GL_TRUE; - - swrast->Driver.SpanRenderStart = _swrast_span_render_start; - swrast->Driver.SpanRenderFinish = _swrast_span_render_finish; - - for (i = 0; i < ARRAY_SIZE(swrast->TextureSample); i++) - swrast->TextureSample[i] = NULL; - - /* SpanArrays is global and shared by all SWspan instances. However, when - * using multiple threads, it is necessary to have one SpanArrays instance - * per thread. - */ - swrast->SpanArrays = malloc(maxThreads * sizeof(SWspanarrays)); - if (!swrast->SpanArrays) { - free(swrast); - return GL_FALSE; - } - for(i = 0; i < maxThreads; i++) { - swrast->SpanArrays[i].ChanType = CHAN_TYPE; -#if CHAN_TYPE == GL_UNSIGNED_BYTE - swrast->SpanArrays[i].rgba = swrast->SpanArrays[i].rgba8; -#elif CHAN_TYPE == GL_UNSIGNED_SHORT - swrast->SpanArrays[i].rgba = swrast->SpanArrays[i].rgba16; -#else - swrast->SpanArrays[i].rgba = swrast->SpanArrays[i].attribs[VARYING_SLOT_COL0]; -#endif - } - - /* init point span buffer */ - swrast->PointSpan.primitive = GL_POINT; - swrast->PointSpan.end = 0; - swrast->PointSpan.facing = 0; - swrast->PointSpan.array = swrast->SpanArrays; - - init_program_native_limits(&ctx->Const.Program[MESA_SHADER_VERTEX]); - init_program_native_limits(&ctx->Const.Program[MESA_SHADER_GEOMETRY]); - init_program_native_limits(&ctx->Const.Program[MESA_SHADER_FRAGMENT]); - - ctx->swrast_context = swrast; - - swrast->stencil_temp.buf1 = malloc(SWRAST_MAX_WIDTH * sizeof(GLubyte)); - swrast->stencil_temp.buf2 = malloc(SWRAST_MAX_WIDTH * sizeof(GLubyte)); - swrast->stencil_temp.buf3 = malloc(SWRAST_MAX_WIDTH * sizeof(GLubyte)); - swrast->stencil_temp.buf4 = malloc(SWRAST_MAX_WIDTH * sizeof(GLubyte)); - - if (!swrast->stencil_temp.buf1 || - !swrast->stencil_temp.buf2 || - !swrast->stencil_temp.buf3 || - !swrast->stencil_temp.buf4) { - _swrast_DestroyContext(ctx); - return GL_FALSE; - } - - return GL_TRUE; -} - -void -_swrast_DestroyContext( struct gl_context *ctx ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - - if (SWRAST_DEBUG) { - _mesa_debug(ctx, "_swrast_DestroyContext\n"); - } - - free( swrast->SpanArrays ); - free( swrast->ZoomedArrays ); - free( swrast->TexelBuffer ); - - free(swrast->stencil_temp.buf1); - free(swrast->stencil_temp.buf2); - free(swrast->stencil_temp.buf3); - free(swrast->stencil_temp.buf4); - - free( swrast ); - - ctx->swrast_context = 0; -} - - -struct swrast_device_driver * -_swrast_GetDeviceDriverReference( struct gl_context *ctx ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - return &swrast->Driver; -} - -void -_swrast_flush( struct gl_context *ctx ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - /* flush any pending fragments from rendering points */ - if (swrast->PointSpan.end > 0) { - _swrast_write_rgba_span(ctx, &(swrast->PointSpan)); - swrast->PointSpan.end = 0; - } -} - -void -_swrast_render_primitive( struct gl_context *ctx, GLenum prim ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - if (swrast->Primitive == GL_POINTS && prim != GL_POINTS) { - _swrast_flush(ctx); - } - swrast->Primitive = prim; -} - - -/** called via swrast->Driver.SpanRenderStart() */ -void -_swrast_span_render_start(struct gl_context *ctx) -{ - _swrast_map_textures(ctx); - _swrast_map_renderbuffers(ctx); -} - - -/** called via swrast->Driver.SpanRenderFinish() */ -void -_swrast_span_render_finish(struct gl_context *ctx) -{ - _swrast_unmap_textures(ctx); - _swrast_unmap_renderbuffers(ctx); -} - - -void -_swrast_render_start( struct gl_context *ctx ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - if (swrast->Driver.SpanRenderStart) - swrast->Driver.SpanRenderStart( ctx ); - swrast->PointSpan.end = 0; -} - -void -_swrast_render_finish( struct gl_context *ctx ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - struct gl_query_object *query = ctx->Query.CurrentOcclusionObject; - - _swrast_flush(ctx); - - if (swrast->Driver.SpanRenderFinish) - swrast->Driver.SpanRenderFinish( ctx ); - - if (query && (query->Target == GL_ANY_SAMPLES_PASSED || - query->Target == GL_ANY_SAMPLES_PASSED_CONSERVATIVE)) - query->Result = !!query->Result; -} - - -#define SWRAST_DEBUG_VERTICES 0 - -void -_swrast_print_vertex( struct gl_context *ctx, const SWvertex *v ) -{ - GLuint i; - - if (SWRAST_DEBUG_VERTICES) { - _mesa_debug(ctx, "win %f %f %f %f\n", - v->attrib[VARYING_SLOT_POS][0], - v->attrib[VARYING_SLOT_POS][1], - v->attrib[VARYING_SLOT_POS][2], - v->attrib[VARYING_SLOT_POS][3]); - - for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++) - if (ctx->Texture.Unit[i]._Current) - _mesa_debug(ctx, "texcoord[%d] %f %f %f %f\n", i, - v->attrib[VARYING_SLOT_TEX0 + i][0], - v->attrib[VARYING_SLOT_TEX0 + i][1], - v->attrib[VARYING_SLOT_TEX0 + i][2], - v->attrib[VARYING_SLOT_TEX0 + i][3]); - -#if CHAN_TYPE == GL_FLOAT - _mesa_debug(ctx, "color %f %f %f %f\n", - v->color[0], v->color[1], v->color[2], v->color[3]); -#else - _mesa_debug(ctx, "color %d %d %d %d\n", - v->color[0], v->color[1], v->color[2], v->color[3]); -#endif - _mesa_debug(ctx, "spec %g %g %g %g\n", - v->attrib[VARYING_SLOT_COL1][0], - v->attrib[VARYING_SLOT_COL1][1], - v->attrib[VARYING_SLOT_COL1][2], - v->attrib[VARYING_SLOT_COL1][3]); - _mesa_debug(ctx, "fog %f\n", v->attrib[VARYING_SLOT_FOGC][0]); - _mesa_debug(ctx, "index %f\n", v->attrib[VARYING_SLOT_CI][0]); - _mesa_debug(ctx, "pointsize %f\n", v->pointSize); - _mesa_debug(ctx, "\n"); - } -} diff --git a/src/mesa/swrast/s_context.h b/src/mesa/swrast/s_context.h deleted file mode 100644 index 9ccba6b..0000000 --- a/src/mesa/swrast/s_context.h +++ /dev/null @@ -1,499 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -/** - * \file swrast/s_context.h - * \brief Software rasterization context and private types. - * \author Keith Whitwell - */ - -/** - * \mainpage swrast module - * - * This module, software rasterization, contains the software fallback - * routines for drawing points, lines, triangles, bitmaps and images. - * All rendering boils down to writing spans (arrays) of pixels with - * particular colors. The span-writing routines must be implemented - * by the device driver. - */ - - -#ifndef S_CONTEXT_H -#define S_CONTEXT_H - -#include "main/mtypes.h" -#include "main/texcompress.h" -#include "program/prog_execute.h" -#include "swrast.h" -#include "s_fragprog.h" -#include "s_span.h" -#include "util/rounding.h" - - -typedef void (*texture_sample_func)(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoords[][4], - const GLfloat lambda[], GLfloat rgba[][4]); - -typedef void (*swrast_blend_func)(struct gl_context *ctx, GLuint n, - const GLubyte mask[], - GLvoid *src, const GLvoid *dst, - GLenum chanType); - -typedef void (*swrast_point_func)( struct gl_context *ctx, const SWvertex *); - -typedef void (*swrast_line_func)( struct gl_context *ctx, - const SWvertex *, const SWvertex *); - -typedef void (*swrast_tri_func)( struct gl_context *ctx, const SWvertex *, - const SWvertex *, const SWvertex *); - - -typedef void (*validate_texture_image_func)(struct gl_context *ctx, - struct gl_texture_object *texObj, - GLuint face, GLuint level); - - -/** - * \defgroup Bitmasks - * Bitmasks to indicate which rasterization options are enabled - * (RasterMask) - */ -/*@{*/ -#define ALPHATEST_BIT 0x001 /**< Alpha-test pixels */ -#define BLEND_BIT 0x002 /**< Blend pixels */ -#define DEPTH_BIT 0x004 /**< Depth-test pixels */ -#define FOG_BIT 0x008 /**< Fog pixels */ -#define LOGIC_OP_BIT 0x010 /**< Apply logic op in software */ -#define CLIP_BIT 0x020 /**< Scissor or window clip pixels */ -#define STENCIL_BIT 0x040 /**< Stencil pixels */ -#define MASKING_BIT 0x080 /**< Do glColorMask or glIndexMask */ -#define MULTI_DRAW_BIT 0x400 /**< Write to more than one color- */ - /**< buffer or no buffers. */ -#define OCCLUSION_BIT 0x800 /**< GL_HP_occlusion_test enabled */ -#define TEXTURE_BIT 0x1000 /**< Texturing really enabled */ -#define FRAGPROG_BIT 0x2000 /**< Fragment program enabled */ -#define ATIFRAGSHADER_BIT 0x4000 /**< ATI Fragment shader enabled */ -#define CLAMPING_BIT 0x8000 /**< Clamp colors to [0,1] */ -/*@}*/ - -#define _SWRAST_NEW_RASTERMASK (_NEW_BUFFERS| \ - _NEW_SCISSOR| \ - _NEW_COLOR| \ - _NEW_DEPTH| \ - _NEW_FOG| \ - _NEW_PROGRAM| \ - _NEW_STENCIL| \ - _NEW_TEXTURE| \ - _NEW_VIEWPORT| \ - _NEW_DEPTH) - - -struct swrast_texture_image; - - -/** - * Fetch a texel from texture image at given position. - */ -typedef void (*FetchTexelFunc)(const struct swrast_texture_image *texImage, - GLint col, GLint row, GLint img, - GLfloat *texelOut); - - -/** - * Subclass of gl_texture_image. - * We need extra fields/info to keep tracking of mapped texture buffers, - * strides and Fetch functions. - */ -struct swrast_texture_image -{ - struct gl_texture_image Base; - - GLboolean _IsPowerOfTwo; /**< Are all dimensions powers of two? */ - - /** used for mipmap LOD computation */ - GLfloat WidthScale, HeightScale, DepthScale; - - /** - * Byte stride between rows in ImageSlices. - * - * For compressed textures, this is the byte stride between one row of - * blocks and the next row of blocks. - * - * Only valid while one of the ImageSlices is mapped, and must be the same - * between all slices. - */ - GLint RowStride; - /** - * When a texture image is mapped for swrast, this array contains pointers - * to the beginning of each slice. - * - * For swrast-allocated textures, these pointers will always stay - * initialized to point within Buffer. - */ - void **ImageSlices; - - /** Malloc'd texture memory */ - GLubyte *Buffer; - - FetchTexelFunc FetchTexel; - - /** For fetching texels from compressed textures */ - compressed_fetch_func FetchCompressedTexel; -}; - - -/** cast wrapper */ -static inline struct swrast_texture_image * -swrast_texture_image(struct gl_texture_image *img) -{ - return (struct swrast_texture_image *) img; -} - -/** cast wrapper */ -static inline const struct swrast_texture_image * -swrast_texture_image_const(const struct gl_texture_image *img) -{ - return (const struct swrast_texture_image *) img; -} - - -/** - * Subclass of gl_renderbuffer with extra fields needed for software - * rendering. - */ -struct swrast_renderbuffer -{ - struct gl_renderbuffer Base; - - GLubyte *Buffer; /**< The malloc'd memory for buffer */ - - /** These fields are only valid while buffer is mapped for rendering */ - GLubyte *Map; - GLint RowStride; /**< in bytes */ - - /** For span rendering */ - GLenum ColorType; -}; - - -/** cast wrapper */ -static inline struct swrast_renderbuffer * -swrast_renderbuffer(struct gl_renderbuffer *img) -{ - return (struct swrast_renderbuffer *) img; -} - - - -/** - * \struct SWcontext - * \brief Per-context state that's private to the software rasterizer module. - */ -typedef struct -{ - /** Driver interface: - */ - struct swrast_device_driver Driver; - - /** Configuration mechanisms to make software rasterizer match - * characteristics of the hardware rasterizer (if present): - */ - GLboolean AllowVertexFog; - GLboolean AllowPixelFog; - - /** Derived values, invalidated on statechanges, updated from - * _swrast_validate_derived(): - */ - GLbitfield _RasterMask; - GLfloat _BackfaceSign; /** +1 or -1 */ - GLfloat _BackfaceCullSign; /** +1, 0, or -1 */ - GLboolean _PreferPixelFog; /* Compute fog blend factor per fragment? */ - GLboolean _TextureCombinePrimary; - GLboolean _FogEnabled; - GLboolean _DeferredTexture; - - /** List/array of the fragment attributes to interpolate */ - GLuint _ActiveAttribs[VARYING_SLOT_MAX]; - /** Same info, but as a bitmask of VARYING_BIT_x bits */ - GLbitfield64 _ActiveAttribMask; - /** Number of fragment attributes to interpolate */ - GLuint _NumActiveAttribs; - /** Indicates how each attrib is to be interpolated (lines/tris) */ - GLenum _InterpMode[VARYING_SLOT_MAX]; /* GL_FLAT or GL_SMOOTH (for now) */ - - /* Working values: - */ - GLuint StippleCounter; /**< Line stipple counter */ - GLuint PointLineFacing; - GLbitfield NewState; - GLuint StateChanges; - GLenum Primitive; /* current primitive being drawn (ala glBegin) */ - GLboolean SpecularVertexAdd; /**< Add specular/secondary color per vertex */ - - void (*InvalidateState)( struct gl_context *ctx, GLbitfield new_state ); - - /** - * When the NewState mask intersects these masks, we invalidate the - * Point/Line/Triangle function pointers below. - */ - /*@{*/ - GLbitfield InvalidatePointMask; - GLbitfield InvalidateLineMask; - GLbitfield InvalidateTriangleMask; - /*@}*/ - - /** - * Device drivers plug in functions for these callbacks. - * Will be called when the GL state change mask intersects the above masks. - */ - /*@{*/ - void (*choose_point)( struct gl_context * ); - void (*choose_line)( struct gl_context * ); - void (*choose_triangle)( struct gl_context * ); - /*@}*/ - - /** - * Current point, line and triangle drawing functions. - */ - /*@{*/ - swrast_point_func Point; - swrast_line_func Line; - swrast_tri_func Triangle; - /*@}*/ - - /** - * Placeholders for when separate specular (or secondary color) is - * enabled but texturing is not. - */ - /*@{*/ - swrast_point_func SpecPoint; - swrast_line_func SpecLine; - swrast_tri_func SpecTriangle; - /*@}*/ - - /** - * Typically, we'll allocate a sw_span structure as a local variable - * and set its 'array' pointer to point to this object. The reason is - * this object is big and causes problems when allocated on the stack - * on some systems. - */ - SWspanarrays *SpanArrays; - SWspanarrays *ZoomedArrays; /**< For pixel zooming */ - - /** - * Used to buffer N GL_POINTS, instead of rendering one by one. - */ - SWspan PointSpan; - - /** Internal hooks, kept up to date by the same mechanism as above. - */ - swrast_blend_func BlendFunc; - texture_sample_func TextureSample[MAX_COMBINED_TEXTURE_IMAGE_UNITS]; - - /** Buffer for saving the sampled texture colors. - * Needed for GL_ARB_texture_env_crossbar implementation. - */ - GLfloat *TexelBuffer; - - validate_texture_image_func ValidateTextureImage; - - /** State used during execution of fragment programs */ - struct gl_program_machine FragProgMachine; - - /** Temporary arrays for stencil operations. To avoid large stack - * allocations. - */ - struct { - GLubyte *buf1, *buf2, *buf3, *buf4; - } stencil_temp; - -} SWcontext; - - -extern void -_swrast_validate_derived( struct gl_context *ctx ); - -extern void -_swrast_update_texture_samplers(struct gl_context *ctx); - - -/** Return SWcontext for the given struct gl_context */ -static inline SWcontext * -SWRAST_CONTEXT(struct gl_context *ctx) -{ - return (SWcontext *) ctx->swrast_context; -} - -/** const version of above */ -static inline const SWcontext * -CONST_SWRAST_CONTEXT(const struct gl_context *ctx) -{ - return (const SWcontext *) ctx->swrast_context; -} - - -/** - * Called prior to framebuffer reading/writing. - * For drivers that rely on swrast for fallback rendering, this is the - * driver's opportunity to map renderbuffers and textures. - */ -static inline void -swrast_render_start(struct gl_context *ctx) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - if (swrast->Driver.SpanRenderStart) - swrast->Driver.SpanRenderStart(ctx); -} - - -/** Called after framebuffer reading/writing */ -static inline void -swrast_render_finish(struct gl_context *ctx) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - if (swrast->Driver.SpanRenderFinish) - swrast->Driver.SpanRenderFinish(ctx); -} - - -extern void -_swrast_span_render_start(struct gl_context *ctx); - -extern void -_swrast_span_render_finish(struct gl_context *ctx); - -extern void -_swrast_map_textures(struct gl_context *ctx); - -extern void -_swrast_unmap_textures(struct gl_context *ctx); - -extern unsigned int -_swrast_teximage_slice_height(struct gl_texture_image *texImage); - -extern void -_swrast_map_texture(struct gl_context *ctx, struct gl_texture_object *texObj); - -extern void -_swrast_unmap_texture(struct gl_context *ctx, struct gl_texture_object *texObj); - - -extern void -_swrast_map_renderbuffers(struct gl_context *ctx); - -extern void -_swrast_unmap_renderbuffers(struct gl_context *ctx); - - -/** - * Size of an RGBA pixel, in bytes, for given datatype. - */ -#define RGBA_PIXEL_SIZE(TYPE) \ - ((TYPE == GL_UNSIGNED_BYTE) ? 4 * sizeof(GLubyte) : \ - ((TYPE == GL_UNSIGNED_SHORT) ? 4 * sizeof(GLushort) \ - : 4 * sizeof(GLfloat))) - - - -/* - * Fixed point arithmetic macros - */ -#ifndef FIXED_FRAC_BITS -#define FIXED_FRAC_BITS 11 -#endif - -#define FIXED_SHIFT FIXED_FRAC_BITS -#define FIXED_ONE (1 << FIXED_SHIFT) -#define FIXED_HALF (1 << (FIXED_SHIFT-1)) -#define FIXED_FRAC_MASK (FIXED_ONE - 1) -#define FIXED_INT_MASK (~FIXED_FRAC_MASK) -#define FIXED_EPSILON 1 -#define FIXED_SCALE ((float) FIXED_ONE) -#define FIXED_DBL_SCALE ((double) FIXED_ONE) -#define FloatToFixed(X) (lroundf((X) * FIXED_SCALE)) -#define FixedToDouble(X) ((X) * (1.0 / FIXED_DBL_SCALE)) -#define IntToFixed(I) ((I) << FIXED_SHIFT) -#define FixedToInt(X) ((X) >> FIXED_SHIFT) -#define FixedToUns(X) (((unsigned int)(X)) >> FIXED_SHIFT) -#define FixedCeil(X) (((X) + FIXED_ONE - FIXED_EPSILON) & FIXED_INT_MASK) -#define FixedFloor(X) ((X) & FIXED_INT_MASK) -#define FixedToFloat(X) ((X) * (1.0F / FIXED_SCALE)) -#define PosFloatToFixed(X) FloatToFixed(X) -#define SignedFloatToFixed(X) FloatToFixed(X) - - - -/* - * XXX these macros are just bandages for now in order to make - * CHAN_BITS==32 compile cleanly. - * These should probably go elsewhere at some point. - */ -#if CHAN_TYPE == GL_FLOAT -#define ChanToFixed(X) (X) -#define FixedToChan(X) (X) -#else -#define ChanToFixed(X) IntToFixed(X) -#define FixedToChan(X) FixedToInt(X) -#endif - - -/** - * For looping over fragment attributes in the pointe, line - * triangle rasterizers. - */ -#define ATTRIB_LOOP_BEGIN \ - { \ - GLuint a; \ - for (a = 0; a < swrast->_NumActiveAttribs; a++) { \ - const GLuint attr = swrast->_ActiveAttribs[a]; - -#define ATTRIB_LOOP_END } } - - -/** - * Return the address of a pixel value in a mapped renderbuffer. - */ -static inline GLubyte * -_swrast_pixel_address(struct gl_renderbuffer *rb, GLint x, GLint y) -{ - struct swrast_renderbuffer *srb = swrast_renderbuffer(rb); - const GLint bpp = _mesa_get_format_bytes(rb->Format); - const GLint rowStride = srb->RowStride; - assert(x >= 0); - assert(y >= 0); - /* NOTE: using <= only because of s_tritemp.h which gets a pixel - * address but doesn't necessarily access it. - */ - assert(x <= (GLint) rb->Width); - assert(y <= (GLint) rb->Height); - assert(srb->Map); - return (GLubyte *) srb->Map + y * rowStride + x * bpp; -} - - - -#endif diff --git a/src/mesa/swrast/s_copypix.c b/src/mesa/swrast/s_copypix.c deleted file mode 100644 index d6ba441..0000000 --- a/src/mesa/swrast/s_copypix.c +++ /dev/null @@ -1,668 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -#include "main/glheader.h" -#include "main/context.h" -#include "main/condrender.h" -#include "main/macros.h" -#include "main/blit.h" -#include "main/pixeltransfer.h" - - -#include "s_context.h" -#include "s_depth.h" -#include "s_span.h" -#include "s_stencil.h" -#include "s_zoom.h" - - - -/** - * Determine if there's overlap in an image copy. - * This test also compensates for the fact that copies are done from - * bottom to top and overlaps can sometimes be handled correctly - * without making a temporary image copy. - * \return GL_TRUE if the regions overlap, GL_FALSE otherwise. - */ -static GLboolean -regions_overlap(GLint srcx, GLint srcy, - GLint dstx, GLint dsty, - GLint width, GLint height, - GLfloat zoomX, GLfloat zoomY) -{ - if (zoomX == 1.0F && zoomY == 1.0F) { - return _mesa_regions_overlap(srcx, srcy, srcx + width, srcy + height, - dstx, dsty, dstx + width, dsty + height); - } - else { - /* add one pixel of slop when zooming, just to be safe */ - if (srcx > (dstx + ((zoomX > 0.0F) ? (width * zoomX + 1.0F) : 0.0F))) { - /* src is completely right of dest */ - return GL_FALSE; - } - else if (srcx + width + 1.0F < dstx + ((zoomX > 0.0F) ? 0.0F : (width * zoomX))) { - /* src is completely left of dest */ - return GL_FALSE; - } - else if ((srcy < dsty) && (srcy + height < dsty + (height * zoomY))) { - /* src is completely below dest */ - return GL_FALSE; - } - else if ((srcy > dsty) && (srcy + height > dsty + (height * zoomY))) { - /* src is completely above dest */ - return GL_FALSE; - } - else { - return GL_TRUE; - } - } -} - - -/** - * RGBA copypixels - */ -static void -copy_rgba_pixels(struct gl_context *ctx, GLint srcx, GLint srcy, - GLint width, GLint height, GLint destx, GLint desty) -{ - GLfloat *tmpImage, *p; - GLint sy, dy, stepy, row; - const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F; - GLint overlapping; - GLuint transferOps = ctx->_ImageTransferState; - SWspan span; - - if (!ctx->ReadBuffer->_ColorReadBuffer) { - /* no readbuffer - OK */ - return; - } - - if (ctx->DrawBuffer == ctx->ReadBuffer) { - overlapping = regions_overlap(srcx, srcy, destx, desty, width, height, - ctx->Pixel.ZoomX, ctx->Pixel.ZoomY); - } - else { - overlapping = GL_FALSE; - } - - /* Determine if copy should be done bottom-to-top or top-to-bottom */ - if (!overlapping && srcy < desty) { - /* top-down max-to-min */ - sy = srcy + height - 1; - dy = desty + height - 1; - stepy = -1; - } - else { - /* bottom-up min-to-max */ - sy = srcy; - dy = desty; - stepy = 1; - } - - INIT_SPAN(span, GL_BITMAP); - _swrast_span_default_attribs(ctx, &span); - span.arrayMask = SPAN_RGBA; - span.arrayAttribs = VARYING_BIT_COL0; /* we'll fill in COL0 attrib values */ - - if (overlapping) { - tmpImage = malloc(width * height * sizeof(GLfloat) * 4); - if (!tmpImage) { - _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" ); - return; - } - /* read the source image as RGBA/float */ - p = tmpImage; - for (row = 0; row < height; row++) { - _swrast_read_rgba_span( ctx, ctx->ReadBuffer->_ColorReadBuffer, - width, srcx, sy + row, p ); - p += width * 4; - } - p = tmpImage; - } - else { - tmpImage = NULL; /* silence compiler warnings */ - p = NULL; - } - - assert(width < SWRAST_MAX_WIDTH); - - for (row = 0; row < height; row++, sy += stepy, dy += stepy) { - GLvoid *rgba = span.array->attribs[VARYING_SLOT_COL0]; - - /* Get row/span of source pixels */ - if (overlapping) { - /* get from buffered image */ - memcpy(rgba, p, width * sizeof(GLfloat) * 4); - p += width * 4; - } - else { - /* get from framebuffer */ - _swrast_read_rgba_span( ctx, ctx->ReadBuffer->_ColorReadBuffer, - width, srcx, sy, rgba ); - } - - if (transferOps) { - _mesa_apply_rgba_transfer_ops(ctx, transferOps, width, - (GLfloat (*)[4]) rgba); - } - - /* Write color span */ - span.x = destx; - span.y = dy; - span.end = width; - span.array->ChanType = GL_FLOAT; - if (zoom) { - _swrast_write_zoomed_rgba_span(ctx, destx, desty, &span, rgba); - } - else { - _swrast_write_rgba_span(ctx, &span); - } - } - - span.array->ChanType = CHAN_TYPE; /* restore */ - - if (overlapping) - free(tmpImage); -} - - -/** - * Convert floating point Z values to integer Z values with pixel transfer's - * Z scale and bias. - */ -static void -scale_and_bias_z(struct gl_context *ctx, GLuint width, - const GLfloat depth[], GLuint z[]) -{ - const GLuint depthMax = ctx->DrawBuffer->_DepthMax; - GLuint i; - - if (depthMax <= 0xffffff && - ctx->Pixel.DepthScale == 1.0F && - ctx->Pixel.DepthBias == 0.0F) { - /* no scale or bias and no clamping and no worry of overflow */ - const GLfloat depthMaxF = ctx->DrawBuffer->_DepthMaxF; - for (i = 0; i < width; i++) { - z[i] = (GLuint) (depth[i] * depthMaxF); - } - } - else { - /* need to be careful with overflow */ - const GLdouble depthMaxF = ctx->DrawBuffer->_DepthMaxF; - for (i = 0; i < width; i++) { - GLdouble d = depth[i] * ctx->Pixel.DepthScale + ctx->Pixel.DepthBias; - d = SATURATE(d) * depthMaxF; - if (d >= depthMaxF) - z[i] = depthMax; - else - z[i] = (GLuint) d; - } - } -} - - - -/* - * TODO: Optimize!!!! - */ -static void -copy_depth_pixels( struct gl_context *ctx, GLint srcx, GLint srcy, - GLint width, GLint height, - GLint destx, GLint desty ) -{ - struct gl_framebuffer *fb = ctx->ReadBuffer; - struct gl_renderbuffer *readRb = fb->Attachment[BUFFER_DEPTH].Renderbuffer; - GLfloat *p, *tmpImage, *depth; - GLint sy, dy, stepy; - GLint j; - const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F; - GLint overlapping; - SWspan span; - - if (!readRb) { - /* no readbuffer - OK */ - return; - } - - INIT_SPAN(span, GL_BITMAP); - _swrast_span_default_attribs(ctx, &span); - span.arrayMask = SPAN_Z; - - if (ctx->DrawBuffer == ctx->ReadBuffer) { - overlapping = regions_overlap(srcx, srcy, destx, desty, width, height, - ctx->Pixel.ZoomX, ctx->Pixel.ZoomY); - } - else { - overlapping = GL_FALSE; - } - - /* Determine if copy should be bottom-to-top or top-to-bottom */ - if (!overlapping && srcy < desty) { - /* top-down max-to-min */ - sy = srcy + height - 1; - dy = desty + height - 1; - stepy = -1; - } - else { - /* bottom-up min-to-max */ - sy = srcy; - dy = desty; - stepy = 1; - } - - if (overlapping) { - GLint ssy = sy; - tmpImage = malloc(width * height * sizeof(GLfloat)); - if (!tmpImage) { - _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" ); - return; - } - p = tmpImage; - for (j = 0; j < height; j++, ssy += stepy) { - _swrast_read_depth_span_float(ctx, readRb, width, srcx, ssy, p); - p += width; - } - p = tmpImage; - } - else { - tmpImage = NULL; /* silence compiler warning */ - p = NULL; - } - - depth = malloc(width * sizeof(GLfloat)); - if (!depth) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels()"); - goto end; - } - - for (j = 0; j < height; j++, sy += stepy, dy += stepy) { - /* get depth values */ - if (overlapping) { - memcpy(depth, p, width * sizeof(GLfloat)); - p += width; - } - else { - _swrast_read_depth_span_float(ctx, readRb, width, srcx, sy, depth); - } - - /* apply scale and bias */ - scale_and_bias_z(ctx, width, depth, span.array->z); - - /* write depth values */ - span.x = destx; - span.y = dy; - span.end = width; - if (zoom) - _swrast_write_zoomed_depth_span(ctx, destx, desty, &span); - else - _swrast_write_rgba_span(ctx, &span); - } - - free(depth); - -end: - if (overlapping) - free(tmpImage); -} - - - -static void -copy_stencil_pixels( struct gl_context *ctx, GLint srcx, GLint srcy, - GLint width, GLint height, - GLint destx, GLint desty ) -{ - struct gl_framebuffer *fb = ctx->ReadBuffer; - struct gl_renderbuffer *rb = fb->Attachment[BUFFER_STENCIL].Renderbuffer; - GLint sy, dy, stepy; - GLint j; - GLubyte *p, *tmpImage, *stencil; - const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F; - GLint overlapping; - - if (!rb) { - /* no readbuffer - OK */ - return; - } - - if (ctx->DrawBuffer == ctx->ReadBuffer) { - overlapping = regions_overlap(srcx, srcy, destx, desty, width, height, - ctx->Pixel.ZoomX, ctx->Pixel.ZoomY); - } - else { - overlapping = GL_FALSE; - } - - /* Determine if copy should be bottom-to-top or top-to-bottom */ - if (!overlapping && srcy < desty) { - /* top-down max-to-min */ - sy = srcy + height - 1; - dy = desty + height - 1; - stepy = -1; - } - else { - /* bottom-up min-to-max */ - sy = srcy; - dy = desty; - stepy = 1; - } - - if (overlapping) { - GLint ssy = sy; - tmpImage = malloc(width * height * sizeof(GLubyte)); - if (!tmpImage) { - _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" ); - return; - } - p = tmpImage; - for (j = 0; j < height; j++, ssy += stepy) { - _swrast_read_stencil_span( ctx, rb, width, srcx, ssy, p ); - p += width; - } - p = tmpImage; - } - else { - tmpImage = NULL; /* silence compiler warning */ - p = NULL; - } - - stencil = malloc(width * sizeof(GLubyte)); - if (!stencil) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels()"); - goto end; - } - - for (j = 0; j < height; j++, sy += stepy, dy += stepy) { - /* Get stencil values */ - if (overlapping) { - memcpy(stencil, p, width * sizeof(GLubyte)); - p += width; - } - else { - _swrast_read_stencil_span( ctx, rb, width, srcx, sy, stencil ); - } - - _mesa_apply_stencil_transfer_ops(ctx, width, stencil); - - /* Write stencil values */ - if (zoom) { - _swrast_write_zoomed_stencil_span(ctx, destx, desty, width, - destx, dy, stencil); - } - else { - _swrast_write_stencil_span( ctx, width, destx, dy, stencil ); - } - } - - free(stencil); - -end: - if (overlapping) - free(tmpImage); -} - - -/** - * Try to do a fast 1:1 blit with memcpy. - * \return GL_TRUE if successful, GL_FALSE otherwise. - */ -GLboolean -swrast_fast_copy_pixels(struct gl_context *ctx, - struct gl_framebuffer *srcFb, - struct gl_framebuffer *dstFb, - GLint srcX, GLint srcY, GLsizei width, GLsizei height, - GLint dstX, GLint dstY, GLenum type) -{ - struct gl_renderbuffer *srcRb, *dstRb; - GLint row; - GLuint pixelBytes, widthInBytes; - GLubyte *srcMap, *dstMap; - GLint srcRowStride, dstRowStride; - - if (type == GL_COLOR) { - if (dstFb->_NumColorDrawBuffers != 1) - return GL_FALSE; - srcRb = srcFb->_ColorReadBuffer; - dstRb = dstFb->_ColorDrawBuffers[0]; - } - else if (type == GL_STENCIL) { - srcRb = srcFb->Attachment[BUFFER_STENCIL].Renderbuffer; - dstRb = dstFb->Attachment[BUFFER_STENCIL].Renderbuffer; - } - else if (type == GL_DEPTH) { - srcRb = srcFb->Attachment[BUFFER_DEPTH].Renderbuffer; - dstRb = dstFb->Attachment[BUFFER_DEPTH].Renderbuffer; - } - else { - assert(type == GL_DEPTH_STENCIL_EXT); - /* XXX correct? */ - srcRb = srcFb->Attachment[BUFFER_DEPTH].Renderbuffer; - dstRb = dstFb->Attachment[BUFFER_DEPTH].Renderbuffer; - } - - /* src and dst renderbuffers must be same format */ - if (!srcRb || !dstRb || srcRb->Format != dstRb->Format) { - return GL_FALSE; - } - - if (type == GL_STENCIL || type == GL_DEPTH_COMPONENT) { - /* can't handle packed depth+stencil here */ - if (_mesa_is_format_packed_depth_stencil(srcRb->Format) || - _mesa_is_format_packed_depth_stencil(dstRb->Format)) - return GL_FALSE; - } - else if (type == GL_DEPTH_STENCIL) { - /* can't handle separate depth/stencil buffers */ - if (srcRb != srcFb->Attachment[BUFFER_STENCIL].Renderbuffer || - dstRb != dstFb->Attachment[BUFFER_STENCIL].Renderbuffer) - return GL_FALSE; - } - - /* clipping not supported */ - if (srcX < 0 || srcX + width > (GLint) srcFb->Width || - srcY < 0 || srcY + height > (GLint) srcFb->Height || - dstX < dstFb->_Xmin || dstX + width > dstFb->_Xmax || - dstY < dstFb->_Ymin || dstY + height > dstFb->_Ymax) { - return GL_FALSE; - } - - pixelBytes = _mesa_get_format_bytes(srcRb->Format); - widthInBytes = width * pixelBytes; - - if (srcRb == dstRb) { - /* map whole buffer for read/write */ - /* XXX we could be clever and just map the union region of the - * source and dest rects. - */ - GLubyte *map; - GLint rowStride; - - ctx->Driver.MapRenderbuffer(ctx, srcRb, 0, 0, - srcRb->Width, srcRb->Height, - GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, - &map, &rowStride, srcFb->FlipY); - if (!map) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels"); - return GL_TRUE; /* don't retry with slow path */ - } - - srcMap = map + srcY * rowStride + srcX * pixelBytes; - dstMap = map + dstY * rowStride + dstX * pixelBytes; - - /* this handles overlapping copies */ - if (srcY < dstY) { - /* copy in reverse (top->down) order */ - srcMap += rowStride * (height - 1); - dstMap += rowStride * (height - 1); - srcRowStride = -rowStride; - dstRowStride = -rowStride; - } - else { - /* copy in normal (bottom->up) order */ - srcRowStride = rowStride; - dstRowStride = rowStride; - } - } - else { - /* different src/dst buffers */ - ctx->Driver.MapRenderbuffer(ctx, srcRb, srcX, srcY, - width, height, - GL_MAP_READ_BIT, &srcMap, &srcRowStride, - srcFb->FlipY); - if (!srcMap) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels"); - return GL_TRUE; /* don't retry with slow path */ - } - ctx->Driver.MapRenderbuffer(ctx, dstRb, dstX, dstY, - width, height, - GL_MAP_WRITE_BIT, &dstMap, &dstRowStride, - dstFb->FlipY); - if (!dstMap) { - ctx->Driver.UnmapRenderbuffer(ctx, srcRb); - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels"); - return GL_TRUE; /* don't retry with slow path */ - } - } - - for (row = 0; row < height; row++) { - /* memmove() in case of overlap */ - memmove(dstMap, srcMap, widthInBytes); - dstMap += dstRowStride; - srcMap += srcRowStride; - } - - ctx->Driver.UnmapRenderbuffer(ctx, srcRb); - if (dstRb != srcRb) { - ctx->Driver.UnmapRenderbuffer(ctx, dstRb); - } - - return GL_TRUE; -} - - -/** - * Find/map the renderbuffer that we'll be reading from. - * The swrast_render_start() function only maps the drawing buffers, - * not the read buffer. - */ -static struct gl_renderbuffer * -map_readbuffer(struct gl_context *ctx, GLenum type) -{ - struct gl_framebuffer *fb = ctx->ReadBuffer; - struct gl_renderbuffer *rb; - struct swrast_renderbuffer *srb; - - switch (type) { - case GL_COLOR: - rb = fb->Attachment[fb->_ColorReadBufferIndex].Renderbuffer; - break; - case GL_DEPTH: - case GL_DEPTH_STENCIL: - rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer; - break; - case GL_STENCIL: - rb = fb->Attachment[BUFFER_STENCIL].Renderbuffer; - break; - default: - return NULL; - } - - srb = swrast_renderbuffer(rb); - - if (!srb || srb->Map) { - /* no buffer, or buffer is mapped already, we're done */ - return NULL; - } - - ctx->Driver.MapRenderbuffer(ctx, rb, - 0, 0, rb->Width, rb->Height, - GL_MAP_READ_BIT, - &srb->Map, &srb->RowStride, - fb->FlipY); - - return rb; -} - - -/** - * Do software-based glCopyPixels. - * By time we get here, all parameters will have been error-checked. - */ -void -_swrast_CopyPixels(struct gl_context *ctx, - GLint srcx, GLint srcy, GLsizei width, GLsizei height, - GLint destx, GLint desty, GLenum type) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - struct gl_renderbuffer *rb; - - if (!_mesa_check_conditional_render(ctx)) - return; /* don't copy */ - - if (swrast->NewState) - _swrast_validate_derived( ctx ); - - if (!(SWRAST_CONTEXT(ctx)->_RasterMask != 0x0 || - ctx->Pixel.ZoomX != 1.0F || - ctx->Pixel.ZoomY != 1.0F || - ctx->_ImageTransferState) && - swrast_fast_copy_pixels(ctx, ctx->ReadBuffer, ctx->DrawBuffer, - srcx, srcy, width, height, destx, desty, - type)) { - /* all done */ - return; - } - - swrast_render_start(ctx); - rb = map_readbuffer(ctx, type); - - switch (type) { - case GL_COLOR: - copy_rgba_pixels( ctx, srcx, srcy, width, height, destx, desty ); - break; - case GL_DEPTH: - copy_depth_pixels( ctx, srcx, srcy, width, height, destx, desty ); - break; - case GL_STENCIL: - copy_stencil_pixels( ctx, srcx, srcy, width, height, destx, desty ); - break; - case GL_DEPTH_STENCIL_EXT: - /* Copy buffers separately (if the fast copy path wasn't taken) */ - copy_depth_pixels(ctx, srcx, srcy, width, height, destx, desty); - copy_stencil_pixels(ctx, srcx, srcy, width, height, destx, desty); - break; - default: - _mesa_problem(ctx, "unexpected type in _swrast_CopyPixels"); - } - - swrast_render_finish(ctx); - - if (rb) { - struct swrast_renderbuffer *srb = swrast_renderbuffer(rb); - ctx->Driver.UnmapRenderbuffer(ctx, rb); - srb->Map = NULL; - } -} diff --git a/src/mesa/swrast/s_depth.c b/src/mesa/swrast/s_depth.c deleted file mode 100644 index 7e28935..0000000 --- a/src/mesa/swrast/s_depth.c +++ /dev/null @@ -1,854 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -#include "main/glheader.h" -#include "main/context.h" -#include "main/formats.h" -#include "main/format_unpack.h" -#include "main/format_pack.h" -#include "main/macros.h" - - -#include "s_context.h" -#include "s_depth.h" -#include "s_span.h" - - - -#define Z_TEST(COMPARE) \ - do { \ - GLuint i; \ - for (i = 0; i < n; i++) { \ - if (mask[i]) { \ - if (COMPARE) { \ - /* pass */ \ - if (write) { \ - zbuffer[i] = zfrag[i]; \ - } \ - passed++; \ - } \ - else { \ - /* fail */ \ - mask[i] = 0; \ - } \ - } \ - } \ - } while (0) - - -/** - * Do depth test for an array of 16-bit Z values. - * @param zbuffer array of Z buffer values (16-bit) - * @param zfrag array of fragment Z values (use 16-bit in 32-bit uint) - * @param mask which fragments are alive, killed afterward - * @return number of fragments which pass the test. - */ -static GLuint -depth_test_span16( struct gl_context *ctx, GLuint n, - GLushort zbuffer[], const GLuint zfrag[], GLubyte mask[] ) -{ - const GLboolean write = ctx->Depth.Mask; - GLuint passed = 0; - - /* switch cases ordered from most frequent to less frequent */ - switch (ctx->Depth.Func) { - case GL_LESS: - Z_TEST(zfrag[i] < zbuffer[i]); - break; - case GL_LEQUAL: - Z_TEST(zfrag[i] <= zbuffer[i]); - break; - case GL_GEQUAL: - Z_TEST(zfrag[i] >= zbuffer[i]); - break; - case GL_GREATER: - Z_TEST(zfrag[i] > zbuffer[i]); - break; - case GL_NOTEQUAL: - Z_TEST(zfrag[i] != zbuffer[i]); - break; - case GL_EQUAL: - Z_TEST(zfrag[i] == zbuffer[i]); - break; - case GL_ALWAYS: - Z_TEST(1); - break; - case GL_NEVER: - memset(mask, 0, n * sizeof(GLubyte)); - break; - default: - _mesa_problem(ctx, "Bad depth func in depth_test_span16"); - } - - return passed; -} - - -/** - * Do depth test for an array of 32-bit Z values. - * @param zbuffer array of Z buffer values (32-bit) - * @param zfrag array of fragment Z values (use 32-bits in 32-bit uint) - * @param mask which fragments are alive, killed afterward - * @return number of fragments which pass the test. - */ -static GLuint -depth_test_span32( struct gl_context *ctx, GLuint n, - GLuint zbuffer[], const GLuint zfrag[], GLubyte mask[]) -{ - const GLboolean write = ctx->Depth.Mask; - GLuint passed = 0; - - /* switch cases ordered from most frequent to less frequent */ - switch (ctx->Depth.Func) { - case GL_LESS: - Z_TEST(zfrag[i] < zbuffer[i]); - break; - case GL_LEQUAL: - Z_TEST(zfrag[i] <= zbuffer[i]); - break; - case GL_GEQUAL: - Z_TEST(zfrag[i] >= zbuffer[i]); - break; - case GL_GREATER: - Z_TEST(zfrag[i] > zbuffer[i]); - break; - case GL_NOTEQUAL: - Z_TEST(zfrag[i] != zbuffer[i]); - break; - case GL_EQUAL: - Z_TEST(zfrag[i] == zbuffer[i]); - break; - case GL_ALWAYS: - Z_TEST(1); - break; - case GL_NEVER: - memset(mask, 0, n * sizeof(GLubyte)); - break; - default: - _mesa_problem(ctx, "Bad depth func in depth_test_span32"); - } - - return passed; -} - - -/** - * Clamp fragment Z values to the depth near/far range (glDepthRange()). - * This is used when GL_ARB_depth_clamp/GL_DEPTH_CLAMP is turned on. - * In that case, vertexes are not clipped against the near/far planes - * so rasterization will produce fragment Z values outside the usual - * [0,1] range. - */ -void -_swrast_depth_clamp_span( struct gl_context *ctx, SWspan *span ) -{ - struct gl_framebuffer *fb = ctx->DrawBuffer; - const GLuint count = span->end; - GLint *zValues = (GLint *) span->array->z; /* sign change */ - GLint min, max; - GLfloat min_f, max_f; - GLuint i; - - if (ctx->ViewportArray[0].Near < ctx->ViewportArray[0].Far) { - min_f = ctx->ViewportArray[0].Near; - max_f = ctx->ViewportArray[0].Far; - } else { - min_f = ctx->ViewportArray[0].Far; - max_f = ctx->ViewportArray[0].Near; - } - - /* Convert floating point values in [0,1] to device Z coordinates in - * [0, DepthMax]. - * ex: If the Z buffer has 24 bits, DepthMax = 0xffffff. - * - * XXX this all falls apart if we have 31 or more bits of Z because - * the triangle rasterization code produces unsigned Z values. Negative - * vertex Z values come out as large fragment Z uints. - */ - min = (GLint) (min_f * fb->_DepthMaxF); - max = (GLint) (max_f * fb->_DepthMaxF); - if (max < 0) - max = 0x7fffffff; /* catch over flow for 30-bit z */ - - /* Note that we do the comparisons here using signed integers. - */ - for (i = 0; i < count; i++) { - if (zValues[i] < min) - zValues[i] = min; - if (zValues[i] > max) - zValues[i] = max; - } -} - - -/** - * Get array of 32-bit z values from the depth buffer. With clipping. - * Note: the returned values are always in the range [0, 2^32-1]. - */ -static void -get_z32_values(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLuint count, const GLint x[], const GLint y[], - GLuint zbuffer[]) -{ - struct swrast_renderbuffer *srb = swrast_renderbuffer(rb); - const GLint w = rb->Width, h = rb->Height; - const GLubyte *map = _swrast_pixel_address(rb, 0, 0); - GLuint i; - - if (rb->Format == MESA_FORMAT_Z_UNORM32) { - const GLint rowStride = srb->RowStride; - for (i = 0; i < count; i++) { - if (x[i] >= 0 && y[i] >= 0 && x[i] < w && y[i] < h) { - zbuffer[i] = *((GLuint *) (map + y[i] * rowStride + x[i] * 4)); - } - } - } - else { - const GLint bpp = _mesa_get_format_bytes(rb->Format); - const GLint rowStride = srb->RowStride; - for (i = 0; i < count; i++) { - if (x[i] >= 0 && y[i] >= 0 && x[i] < w && y[i] < h) { - const GLubyte *src = map + y[i] * rowStride+ x[i] * bpp; - _mesa_unpack_uint_z_row(rb->Format, 1, src, &zbuffer[i]); - } - } - } -} - - -/** Helper struct for MESA_FORMAT_Z32_FLOAT_S8X24_UINT */ -struct z32f_x24s8 -{ - float z; - uint32_t x24s8; -}; - - -/** - ** Pack uint Z pixels. The incoming src value is always in - ** the range [0, 2^32-1]. - **/ - -static void -pack_uint_S8_UINT_Z24_UNORM(const uint32_t *src, void *dst) -{ - /* don't disturb the stencil values */ - uint32_t *d = ((uint32_t *) dst); - uint32_t s = *d & 0xff; - uint32_t z = *src & 0xffffff00; - *d = z | s; -} - -static void -pack_uint_Z24_UNORM_S8_UINT(const uint32_t *src, void *dst) -{ - /* don't disturb the stencil values */ - uint32_t *d = ((uint32_t *) dst); - uint32_t s = *d & 0xff000000; - uint32_t z = *src >> 8; - *d = s | z; -} - -static void -pack_uint_Z_UNORM16(const uint32_t *src, void *dst) -{ - uint16_t *d = ((uint16_t *) dst); - *d = *src >> 16; -} - -static void -pack_uint_Z_UNORM32(const uint32_t *src, void *dst) -{ - uint32_t *d = ((uint32_t *) dst); - *d = *src; -} - -/** - ** Pack uint to Z_FLOAT32 or Z_FLOAT32_X24S8. - **/ - -static void -pack_uint_Z_FLOAT32(const uint32_t *src, void *dst) -{ - float *d = ((float *) dst); - const double scale = 1.0 / (double) 0xffffffff; - *d = (float) (*src * scale); - assert(*d >= 0.0f); - assert(*d <= 1.0f); -} - -/** Pack a uint32_t Z value to dest address */ -typedef void (*mesa_pack_uint_z_func)(const uint32_t *src, void *dst); - -static mesa_pack_uint_z_func -get_pack_uint_z_func(mesa_format format) -{ - switch (format) { - case MESA_FORMAT_S8_UINT_Z24_UNORM: - case MESA_FORMAT_X8_UINT_Z24_UNORM: - return pack_uint_S8_UINT_Z24_UNORM; - case MESA_FORMAT_Z24_UNORM_S8_UINT: - case MESA_FORMAT_Z24_UNORM_X8_UINT: - return pack_uint_Z24_UNORM_S8_UINT; - case MESA_FORMAT_Z_UNORM16: - return pack_uint_Z_UNORM16; - case MESA_FORMAT_Z_UNORM32: - return pack_uint_Z_UNORM32; - case MESA_FORMAT_Z_FLOAT32: - case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: - return pack_uint_Z_FLOAT32; - default: - unreachable("unexpected format in get_pack_uint_z_func()"); - } -} - -/** - * Put an array of 32-bit z values into the depth buffer. - * Note: the z values are always in the range [0, 2^32-1]. - */ -static void -put_z32_values(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLuint count, const GLint x[], const GLint y[], - const GLuint zvalues[], const GLubyte mask[]) -{ - struct swrast_renderbuffer *srb = swrast_renderbuffer(rb); - const GLint w = rb->Width, h = rb->Height; - GLubyte *map = _swrast_pixel_address(rb, 0, 0); - GLuint i; - - if (rb->Format == MESA_FORMAT_Z_UNORM32) { - const GLint rowStride = srb->RowStride; - for (i = 0; i < count; i++) { - if (mask[i] && x[i] >= 0 && y[i] >= 0 && x[i] < w && y[i] < h) { - GLuint *dst = (GLuint *) (map + y[i] * rowStride + x[i] * 4); - *dst = zvalues[i]; - } - } - } - else { - mesa_pack_uint_z_func packZ = get_pack_uint_z_func(rb->Format); - const GLint bpp = _mesa_get_format_bytes(rb->Format); - const GLint rowStride = srb->RowStride; - for (i = 0; i < count; i++) { - if (mask[i] && x[i] >= 0 && y[i] >= 0 && x[i] < w && y[i] < h) { - void *dst = map + y[i] * rowStride + x[i] * bpp; - packZ(zvalues + i, dst); - } - } - } -} - - -/** - * Apply depth (Z) buffer testing to the span. - * \return approx number of pixels that passed (only zero is reliable) - */ -GLuint -_swrast_depth_test_span(struct gl_context *ctx, SWspan *span) -{ - struct gl_framebuffer *fb = ctx->DrawBuffer; - struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer; - const GLint bpp = _mesa_get_format_bytes(rb->Format); - void *zStart; - const GLuint count = span->end; - const GLuint *fragZ = span->array->z; - GLubyte *mask = span->array->mask; - void *zBufferVals; - GLuint *zBufferTemp = NULL; - GLuint passed; - GLuint zBits = _mesa_get_format_bits(rb->Format, GL_DEPTH_BITS); - GLboolean ztest16 = GL_FALSE; - - if (span->arrayMask & SPAN_XY) - zStart = NULL; - else - zStart = _swrast_pixel_address(rb, span->x, span->y); - - if (rb->Format == MESA_FORMAT_Z_UNORM16 && !(span->arrayMask & SPAN_XY)) { - /* directly read/write row of 16-bit Z values */ - zBufferVals = zStart; - ztest16 = GL_TRUE; - } - else if (rb->Format == MESA_FORMAT_Z_UNORM32 && !(span->arrayMask & SPAN_XY)) { - /* directly read/write row of 32-bit Z values */ - zBufferVals = zStart; - } - else { - /* copy Z buffer values into temp buffer (32-bit Z values) */ - zBufferTemp = malloc(count * sizeof(GLuint)); - if (!zBufferTemp) - return 0; - - if (span->arrayMask & SPAN_XY) { - get_z32_values(ctx, rb, count, - span->array->x, span->array->y, zBufferTemp); - } - else { - _mesa_unpack_uint_z_row(rb->Format, count, zStart, zBufferTemp); - } - - if (zBits == 24) { - GLuint i; - /* Convert depth buffer values from 32 to 24 bits to match the - * fragment Z values generated by rasterization. - */ - for (i = 0; i < count; i++) { - zBufferTemp[i] >>= 8; - } - } - else if (zBits == 16) { - GLuint i; - /* Convert depth buffer values from 32 to 16 bits */ - for (i = 0; i < count; i++) { - zBufferTemp[i] >>= 16; - } - } - else { - assert(zBits == 32); - } - - zBufferVals = zBufferTemp; - } - - /* do the depth test either with 16 or 32-bit values */ - if (ztest16) - passed = depth_test_span16(ctx, count, zBufferVals, fragZ, mask); - else - passed = depth_test_span32(ctx, count, zBufferVals, fragZ, mask); - - if (zBufferTemp) { - /* need to write temp Z values back into the buffer */ - - /* Convert depth buffer values back to 32-bit values. The least - * significant bits don't matter since they'll get dropped when - * they're packed back into the depth buffer. - */ - if (zBits == 24) { - GLuint i; - for (i = 0; i < count; i++) { - zBufferTemp[i] = (zBufferTemp[i] << 8); - } - } - else if (zBits == 16) { - GLuint i; - for (i = 0; i < count; i++) { - zBufferTemp[i] = zBufferTemp[i] << 16; - } - } - - if (span->arrayMask & SPAN_XY) { - /* random locations */ - put_z32_values(ctx, rb, count, span->array->x, span->array->y, - zBufferTemp, mask); - } - else { - /* horizontal row */ - mesa_pack_uint_z_func packZ = get_pack_uint_z_func(rb->Format); - GLubyte *dst = zStart; - GLuint i; - for (i = 0; i < count; i++) { - if (mask[i]) { - packZ(&zBufferTemp[i], dst); - } - dst += bpp; - } - } - - free(zBufferTemp); - } - - if (passed < count) { - span->writeAll = GL_FALSE; - } - return passed; -} - - -/** - * GL_EXT_depth_bounds_test extension. - * Discard fragments depending on whether the corresponding Z-buffer - * values are outside the depth bounds test range. - * Note: we test the Z buffer values, not the fragment Z values! - * \return GL_TRUE if any fragments pass, GL_FALSE if no fragments pass - */ -GLboolean -_swrast_depth_bounds_test( struct gl_context *ctx, SWspan *span ) -{ - struct gl_framebuffer *fb = ctx->DrawBuffer; - struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer; - GLubyte *zStart; - GLuint zMin = (GLuint)((double)ctx->Depth.BoundsMin * 0xffffffff); - GLuint zMax = (GLuint)((double)ctx->Depth.BoundsMax * 0xffffffff); - GLubyte *mask = span->array->mask; - const GLuint count = span->end; - GLuint i; - GLboolean anyPass = GL_FALSE; - GLuint *zBufferTemp; - const GLuint *zBufferVals; - - zBufferTemp = malloc(count * sizeof(GLuint)); - if (!zBufferTemp) { - /* don't generate a stream of OUT_OF_MEMORY errors here */ - return GL_FALSE; - } - - if (span->arrayMask & SPAN_XY) - zStart = NULL; - else - zStart = _swrast_pixel_address(rb, span->x, span->y); - - if (rb->Format == MESA_FORMAT_Z_UNORM32 && !(span->arrayMask & SPAN_XY)) { - /* directly access 32-bit values in the depth buffer */ - zBufferVals = (const GLuint *) zStart; - } - else { - /* Round the bounds to the precision of the zbuffer. */ - if (rb->Format == MESA_FORMAT_Z_UNORM16) { - zMin = (zMin & 0xffff0000) | (zMin >> 16); - zMax = (zMax & 0xffff0000) | (zMax >> 16); - } else { - /* 24 bits */ - zMin = (zMin & 0xffffff00) | (zMin >> 24); - zMax = (zMax & 0xffffff00) | (zMax >> 24); - } - - /* unpack Z values into a temporary array */ - if (span->arrayMask & SPAN_XY) { - get_z32_values(ctx, rb, count, span->array->x, span->array->y, - zBufferTemp); - } - else { - _mesa_unpack_uint_z_row(rb->Format, count, zStart, zBufferTemp); - } - zBufferVals = zBufferTemp; - } - - /* Now do the tests */ - for (i = 0; i < count; i++) { - if (mask[i]) { - if (zBufferVals[i] < zMin || zBufferVals[i] > zMax) - mask[i] = GL_FALSE; - else - anyPass = GL_TRUE; - } - } - - free(zBufferTemp); - - return anyPass; -} - - - -/**********************************************************************/ -/***** Read Depth Buffer *****/ -/**********************************************************************/ - - -/** - * Read a span of depth values from the given depth renderbuffer, returning - * the values as GLfloats. - * This function does clipping to prevent reading outside the depth buffer's - * bounds. - */ -void -_swrast_read_depth_span_float(struct gl_context *ctx, - struct gl_renderbuffer *rb, - GLint n, GLint x, GLint y, GLfloat depth[]) -{ - if (!rb) { - /* really only doing this to prevent FP exceptions later */ - memset(depth, 0, n * sizeof(GLfloat)); - return; - } - - if (y < 0 || y >= (GLint) rb->Height || - x + n <= 0 || x >= (GLint) rb->Width) { - /* span is completely outside framebuffer */ - memset(depth, 0, n * sizeof(GLfloat)); - return; - } - - if (x < 0) { - GLint dx = -x; - GLint i; - for (i = 0; i < dx; i++) - depth[i] = 0.0; - x = 0; - n -= dx; - depth += dx; - } - if (x + n > (GLint) rb->Width) { - GLint dx = x + n - (GLint) rb->Width; - GLint i; - for (i = 0; i < dx; i++) - depth[n - i - 1] = 0.0; - n -= dx; - } - if (n <= 0) { - return; - } - - _mesa_unpack_float_z_row(rb->Format, n, _swrast_pixel_address(rb, x, y), - depth); -} - - -/** - * Clear the given z/depth renderbuffer. If the buffer is a combined - * depth+stencil buffer, only the Z bits will be touched. - */ -void -_swrast_clear_depth_buffer(struct gl_context *ctx) -{ - struct gl_renderbuffer *rb = - ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; - GLint x, y, width, height; - GLubyte *map; - GLint rowStride, i, j; - GLbitfield mapMode; - - if (!rb || !ctx->Depth.Mask) { - /* no depth buffer, or writing to it is disabled */ - return; - } - - /* compute region to clear */ - x = ctx->DrawBuffer->_Xmin; - y = ctx->DrawBuffer->_Ymin; - width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; - height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; - - mapMode = GL_MAP_WRITE_BIT; - if (rb->Format == MESA_FORMAT_Z24_UNORM_S8_UINT || - rb->Format == MESA_FORMAT_Z24_UNORM_X8_UINT || - rb->Format == MESA_FORMAT_S8_UINT_Z24_UNORM || - rb->Format == MESA_FORMAT_X8_UINT_Z24_UNORM) { - mapMode |= GL_MAP_READ_BIT; - } - - ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, - mapMode, &map, &rowStride, - ctx->DrawBuffer->FlipY); - if (!map) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClear(depth)"); - return; - } - - switch (rb->Format) { - case MESA_FORMAT_Z_UNORM16: - { - GLfloat clear = (GLfloat) ctx->Depth.Clear; - GLushort clearVal = 0; - _mesa_pack_float_z_row(rb->Format, 1, &clear, &clearVal); - if (clearVal == 0xffff && width * 2 == rowStride) { - /* common case */ - memset(map, 0xff, width * height * 2); - } - else { - for (i = 0; i < height; i++) { - GLushort *row = (GLushort *) map; - for (j = 0; j < width; j++) { - row[j] = clearVal; - } - map += rowStride; - } - } - } - break; - case MESA_FORMAT_Z_UNORM32: - case MESA_FORMAT_Z_FLOAT32: - { - GLfloat clear = (GLfloat) ctx->Depth.Clear; - GLuint clearVal = 0; - _mesa_pack_float_z_row(rb->Format, 1, &clear, &clearVal); - for (i = 0; i < height; i++) { - GLuint *row = (GLuint *) map; - for (j = 0; j < width; j++) { - row[j] = clearVal; - } - map += rowStride; - } - } - break; - case MESA_FORMAT_Z24_UNORM_S8_UINT: - case MESA_FORMAT_Z24_UNORM_X8_UINT: - case MESA_FORMAT_S8_UINT_Z24_UNORM: - case MESA_FORMAT_X8_UINT_Z24_UNORM: - { - GLfloat clear = (GLfloat) ctx->Depth.Clear; - GLuint clearVal = 0; - GLuint mask; - - if (rb->Format == MESA_FORMAT_Z24_UNORM_S8_UINT || - rb->Format == MESA_FORMAT_Z24_UNORM_X8_UINT) - mask = 0xff000000; - else - mask = 0xff; - - _mesa_pack_float_z_row(rb->Format, 1, &clear, &clearVal); - for (i = 0; i < height; i++) { - GLuint *row = (GLuint *) map; - for (j = 0; j < width; j++) { - row[j] = (row[j] & mask) | clearVal; - } - map += rowStride; - } - - } - break; - case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: - /* XXX untested */ - { - GLfloat clearVal = (GLfloat) ctx->Depth.Clear; - for (i = 0; i < height; i++) { - GLfloat *row = (GLfloat *) map; - for (j = 0; j < width; j++) { - row[j * 2] = clearVal; - } - map += rowStride; - } - } - break; - default: - _mesa_problem(ctx, "Unexpected depth buffer format %s" - " in _swrast_clear_depth_buffer()", - _mesa_get_format_name(rb->Format)); - } - - ctx->Driver.UnmapRenderbuffer(ctx, rb); -} - - - - -/** - * Clear both depth and stencil values in a combined depth+stencil buffer. - */ -void -_swrast_clear_depth_stencil_buffer(struct gl_context *ctx) -{ - const GLubyte stencilBits = ctx->DrawBuffer->Visual.stencilBits; - const GLuint writeMask = ctx->Stencil.WriteMask[0]; - const GLuint stencilMax = (1 << stencilBits) - 1; - struct gl_renderbuffer *rb = - ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; - GLint x, y, width, height; - GLbitfield mapMode; - GLubyte *map; - GLint rowStride, i, j; - - /* check that we really have a combined depth+stencil buffer */ - assert(rb == ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer); - - /* compute region to clear */ - x = ctx->DrawBuffer->_Xmin; - y = ctx->DrawBuffer->_Ymin; - width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; - height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; - - mapMode = GL_MAP_WRITE_BIT; - if ((writeMask & stencilMax) != stencilMax) { - /* need to mask stencil values */ - mapMode |= GL_MAP_READ_BIT; - } - - ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, - mapMode, &map, &rowStride, - ctx->DrawBuffer->FlipY); - if (!map) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClear(depth+stencil)"); - return; - } - - switch (rb->Format) { - case MESA_FORMAT_Z24_UNORM_S8_UINT: - case MESA_FORMAT_S8_UINT_Z24_UNORM: - { - GLfloat zClear = (GLfloat) ctx->Depth.Clear; - GLuint clear = 0, mask; - - _mesa_pack_float_z_row(rb->Format, 1, &zClear, &clear); - - if (rb->Format == MESA_FORMAT_Z24_UNORM_S8_UINT) { - mask = ((~writeMask) & 0xff) << 24; - clear |= (ctx->Stencil.Clear & writeMask & 0xff) << 24; - } - else { - mask = ((~writeMask) & 0xff); - clear |= (ctx->Stencil.Clear & writeMask & 0xff); - } - - for (i = 0; i < height; i++) { - GLuint *row = (GLuint *) map; - if (mask != 0x0) { - for (j = 0; j < width; j++) { - row[j] = (row[j] & mask) | clear; - } - } - else { - for (j = 0; j < width; j++) { - row[j] = clear; - } - } - map += rowStride; - } - } - break; - case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: - /* XXX untested */ - { - const GLfloat zClear = (GLfloat) ctx->Depth.Clear; - const GLuint sClear = ctx->Stencil.Clear & writeMask; - const GLuint sMask = (~writeMask) & 0xff; - for (i = 0; i < height; i++) { - GLfloat *zRow = (GLfloat *) map; - GLuint *sRow = (GLuint *) map; - for (j = 0; j < width; j++) { - zRow[j * 2 + 0] = zClear; - } - if (sMask != 0) { - for (j = 0; j < width; j++) { - sRow[j * 2 + 1] = (sRow[j * 2 + 1] & sMask) | sClear; - } - } - else { - for (j = 0; j < width; j++) { - sRow[j * 2 + 1] = sClear; - } - } - map += rowStride; - } - } - break; - default: - _mesa_problem(ctx, "Unexpected depth buffer format %s" - " in _swrast_clear_depth_buffer()", - _mesa_get_format_name(rb->Format)); - } - - ctx->Driver.UnmapRenderbuffer(ctx, rb); - -} diff --git a/src/mesa/swrast/s_depth.h b/src/mesa/swrast/s_depth.h deleted file mode 100644 index b4b738c..0000000 --- a/src/mesa/swrast/s_depth.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -#ifndef S_DEPTH_H -#define S_DEPTH_H - - -#include "main/glheader.h" -#include "s_span.h" - -struct gl_context; -struct gl_renderbuffer; - - -extern GLuint -_swrast_depth_test_span( struct gl_context *ctx, SWspan *span); - -extern void -_swrast_depth_clamp_span( struct gl_context *ctx, SWspan *span ); - -extern GLboolean -_swrast_depth_bounds_test( struct gl_context *ctx, SWspan *span ); - - -extern void -_swrast_read_depth_span_float( struct gl_context *ctx, struct gl_renderbuffer *rb, - GLint n, GLint x, GLint y, GLfloat depth[] ); - -extern void -_swrast_clear_depth_buffer(struct gl_context *ctx); - -extern void -_swrast_clear_depth_stencil_buffer(struct gl_context *ctx); - - -#endif diff --git a/src/mesa/swrast/s_drawpix.c b/src/mesa/swrast/s_drawpix.c deleted file mode 100644 index c4f6f4b..0000000 --- a/src/mesa/swrast/s_drawpix.c +++ /dev/null @@ -1,791 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -#include "main/glheader.h" -#include "main/bufferobj.h" -#include "main/colormac.h" -#include "main/condrender.h" -#include "main/context.h" -#include "main/format_pack.h" -#include "main/format_utils.h" -#include "main/glformats.h" -#include "main/image.h" - -#include "main/macros.h" -#include "main/pack.h" -#include "main/pbo.h" -#include "main/pixeltransfer.h" -#include "main/state.h" - -#include "s_context.h" -#include "s_span.h" -#include "s_stencil.h" -#include "s_zoom.h" - - -/** - * Handle a common case of drawing GL_RGB/GL_UNSIGNED_BYTE into a - * MESA_FORMAT_XRGB888 or MESA_FORMAT_ARGB888 renderbuffer. - */ -static void -fast_draw_rgb_ubyte_pixels(struct gl_context *ctx, - struct gl_renderbuffer *rb, - GLint x, GLint y, - GLsizei width, GLsizei height, - const struct gl_pixelstore_attrib *unpack, - const GLvoid *pixels, - bool flip_y) -{ - const GLubyte *src = (const GLubyte *) - _mesa_image_address2d(unpack, pixels, width, - height, GL_RGB, GL_UNSIGNED_BYTE, 0, 0); - const GLint srcRowStride = _mesa_image_row_stride(unpack, width, - GL_RGB, GL_UNSIGNED_BYTE); - GLint i, j; - GLubyte *dst; - GLint dstRowStride; - - ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, - GL_MAP_WRITE_BIT, &dst, &dstRowStride, - flip_y); - - if (!dst) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); - return; - } - - if (ctx->Pixel.ZoomY == -1.0f) { - dst = dst + (height - 1) * dstRowStride; - dstRowStride = -dstRowStride; - } - - for (i = 0; i < height; i++) { - GLuint *dst4 = (GLuint *) dst; - for (j = 0; j < width; j++) { - dst4[j] = PACK_COLOR_8888(0xff, src[j*3+0], src[j*3+1], src[j*3+2]); - } - dst += dstRowStride; - src += srcRowStride; - } - - ctx->Driver.UnmapRenderbuffer(ctx, rb); -} - - -/** - * Handle a common case of drawing GL_RGBA/GL_UNSIGNED_BYTE into a - * MESA_FORMAT_ARGB888 or MESA_FORMAT_xRGB888 renderbuffer. - */ -static void -fast_draw_rgba_ubyte_pixels(struct gl_context *ctx, - struct gl_renderbuffer *rb, - GLint x, GLint y, - GLsizei width, GLsizei height, - const struct gl_pixelstore_attrib *unpack, - const GLvoid *pixels, - bool flip_y) -{ - const GLubyte *src = (const GLubyte *) - _mesa_image_address2d(unpack, pixels, width, - height, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0); - const GLint srcRowStride = - _mesa_image_row_stride(unpack, width, GL_RGBA, GL_UNSIGNED_BYTE); - GLint i, j; - GLubyte *dst; - GLint dstRowStride; - - ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, - GL_MAP_WRITE_BIT, &dst, &dstRowStride, - flip_y); - - if (!dst) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); - return; - } - - if (ctx->Pixel.ZoomY == -1.0f) { - dst = dst + (height - 1) * dstRowStride; - dstRowStride = -dstRowStride; - } - - for (i = 0; i < height; i++) { - GLuint *dst4 = (GLuint *) dst; - for (j = 0; j < width; j++) { - dst4[j] = PACK_COLOR_8888(src[j*4+3], src[j*4+0], - src[j*4+1], src[j*4+2]); - } - dst += dstRowStride; - src += srcRowStride; - } - - ctx->Driver.UnmapRenderbuffer(ctx, rb); -} - - -/** - * Handle a common case of drawing a format/type combination that - * exactly matches the renderbuffer format. - */ -static void -fast_draw_generic_pixels(struct gl_context *ctx, - struct gl_renderbuffer *rb, - GLint x, GLint y, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *unpack, - const GLvoid *pixels, - bool flip_y) -{ - const GLubyte *src = (const GLubyte *) - _mesa_image_address2d(unpack, pixels, width, - height, format, type, 0, 0); - const GLint srcRowStride = - _mesa_image_row_stride(unpack, width, format, type); - const GLint rowLength = width * _mesa_get_format_bytes(rb->Format); - GLint i; - GLubyte *dst; - GLint dstRowStride; - - ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, - GL_MAP_WRITE_BIT, &dst, &dstRowStride, - flip_y); - - if (!dst) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); - return; - } - - if (ctx->Pixel.ZoomY == -1.0f) { - dst = dst + (height - 1) * dstRowStride; - dstRowStride = -dstRowStride; - } - - for (i = 0; i < height; i++) { - memcpy(dst, src, rowLength); - dst += dstRowStride; - src += srcRowStride; - } - - ctx->Driver.UnmapRenderbuffer(ctx, rb); -} - - -/** - * Try to do a fast and simple RGB(a) glDrawPixels. - * Return: GL_TRUE if success, GL_FALSE if slow path must be used instead - */ -static GLboolean -fast_draw_rgba_pixels(struct gl_context *ctx, GLint x, GLint y, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *userUnpack, - const GLvoid *pixels) -{ - struct gl_framebuffer *fb = ctx->DrawBuffer; - struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0]; - SWcontext *swrast = SWRAST_CONTEXT(ctx); - struct gl_pixelstore_attrib unpack; - - if (!rb) - return GL_TRUE; /* no-op */ - - if (ctx->DrawBuffer->_NumColorDrawBuffers > 1 || - (swrast->_RasterMask & ~CLIP_BIT) || - ctx->Texture._EnabledCoordUnits || - userUnpack->SwapBytes || - ctx->Pixel.ZoomX != 1.0f || - fabsf(ctx->Pixel.ZoomY) != 1.0f || - ctx->_ImageTransferState) { - /* can't handle any of those conditions */ - return GL_FALSE; - } - - unpack = *userUnpack; - - /* clipping */ - if (!_mesa_clip_drawpixels(ctx, &x, &y, &width, &height, &unpack)) { - /* image was completely clipped: no-op, all done */ - return GL_TRUE; - } - - if (format == GL_RGB && - type == GL_UNSIGNED_BYTE && - (rb->Format == MESA_FORMAT_B8G8R8X8_UNORM || - rb->Format == MESA_FORMAT_B8G8R8A8_UNORM)) { - fast_draw_rgb_ubyte_pixels(ctx, rb, x, y, width, height, - &unpack, pixels, fb->FlipY); - return GL_TRUE; - } - - if (format == GL_RGBA && - type == GL_UNSIGNED_BYTE && - (rb->Format == MESA_FORMAT_B8G8R8X8_UNORM || - rb->Format == MESA_FORMAT_B8G8R8A8_UNORM)) { - fast_draw_rgba_ubyte_pixels(ctx, rb, x, y, width, height, - &unpack, pixels, fb->FlipY); - return GL_TRUE; - } - - if (_mesa_format_matches_format_and_type(rb->Format, format, type, - ctx->Unpack.SwapBytes, NULL)) { - fast_draw_generic_pixels(ctx, rb, x, y, width, height, - format, type, &unpack, pixels, - fb->FlipY); - return GL_TRUE; - } - - /* can't handle this pixel format and/or data type */ - return GL_FALSE; -} - - - -/* - * Draw stencil image. - */ -static void -draw_stencil_pixels( struct gl_context *ctx, GLint x, GLint y, - GLsizei width, GLsizei height, - GLenum type, - const struct gl_pixelstore_attrib *unpack, - const GLvoid *pixels ) -{ - const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F; - const GLenum destType = GL_UNSIGNED_BYTE; - GLint row; - GLubyte *values; - - values = malloc(width * sizeof(GLubyte)); - if (!values) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); - return; - } - - for (row = 0; row < height; row++) { - const GLvoid *source = _mesa_image_address2d(unpack, pixels, - width, height, - GL_STENCIL_INDEX, type, - row, 0); - _mesa_unpack_stencil_span(ctx, width, destType, values, - type, source, unpack, - ctx->_ImageTransferState); - if (zoom) { - _swrast_write_zoomed_stencil_span(ctx, x, y, width, - x, y, values); - } - else { - _swrast_write_stencil_span(ctx, width, x, y, values); - } - - y++; - } - - free(values); -} - - -/* - * Draw depth image. - */ -static void -draw_depth_pixels( struct gl_context *ctx, GLint x, GLint y, - GLsizei width, GLsizei height, - GLenum type, - const struct gl_pixelstore_attrib *unpack, - const GLvoid *pixels ) -{ - const GLboolean scaleOrBias - = ctx->Pixel.DepthScale != 1.0f || ctx->Pixel.DepthBias != 0.0f; - const GLboolean zoom = ctx->Pixel.ZoomX != 1.0f || ctx->Pixel.ZoomY != 1.0f; - SWspan span; - - INIT_SPAN(span, GL_BITMAP); - span.arrayMask = SPAN_Z; - _swrast_span_default_attribs(ctx, &span); - - if (type == GL_UNSIGNED_SHORT - && ctx->DrawBuffer->Visual.depthBits == 16 - && !scaleOrBias - && !zoom - && width <= SWRAST_MAX_WIDTH - && !unpack->SwapBytes) { - /* Special case: directly write 16-bit depth values */ - GLint row; - for (row = 0; row < height; row++) { - const GLushort *zSrc = (const GLushort *) - _mesa_image_address2d(unpack, pixels, width, height, - GL_DEPTH_COMPONENT, type, row, 0); - GLint i; - for (i = 0; i < width; i++) - span.array->z[i] = zSrc[i]; - span.x = x; - span.y = y + row; - span.end = width; - _swrast_write_rgba_span(ctx, &span); - } - } - else if (type == GL_UNSIGNED_INT - && !scaleOrBias - && !zoom - && width <= SWRAST_MAX_WIDTH - && !unpack->SwapBytes) { - /* Special case: shift 32-bit values down to Visual.depthBits */ - const GLint shift = 32 - ctx->DrawBuffer->Visual.depthBits; - GLint row; - for (row = 0; row < height; row++) { - const GLuint *zSrc = (const GLuint *) - _mesa_image_address2d(unpack, pixels, width, height, - GL_DEPTH_COMPONENT, type, row, 0); - if (shift == 0) { - memcpy(span.array->z, zSrc, width * sizeof(GLuint)); - } - else { - GLint col; - for (col = 0; col < width; col++) - span.array->z[col] = zSrc[col] >> shift; - } - span.x = x; - span.y = y + row; - span.end = width; - _swrast_write_rgba_span(ctx, &span); - } - } - else { - /* General case */ - const GLuint depthMax = ctx->DrawBuffer->_DepthMax; - GLint skipPixels = 0; - - /* in case width > SWRAST_MAX_WIDTH do the copy in chunks */ - while (skipPixels < width) { - const GLint spanWidth = MIN2(width - skipPixels, SWRAST_MAX_WIDTH); - GLint row; - assert(span.end <= SWRAST_MAX_WIDTH); - for (row = 0; row < height; row++) { - const GLvoid *zSrc = _mesa_image_address2d(unpack, - pixels, width, height, - GL_DEPTH_COMPONENT, type, - row, skipPixels); - - /* Set these for each row since the _swrast_write_* function may - * change them while clipping. - */ - span.x = x + skipPixels; - span.y = y + row; - span.end = spanWidth; - - _mesa_unpack_depth_span(ctx, spanWidth, - GL_UNSIGNED_INT, span.array->z, depthMax, - type, zSrc, unpack); - if (zoom) { - _swrast_write_zoomed_depth_span(ctx, x, y, &span); - } - else { - _swrast_write_rgba_span(ctx, &span); - } - } - skipPixels += spanWidth; - } - } -} - - - -/** - * Draw RGBA image. - */ -static void -draw_rgba_pixels( struct gl_context *ctx, GLint x, GLint y, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *unpack, - const GLvoid *pixels ) -{ - const GLint imgX = x, imgY = y; - const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F; - GLbitfield transferOps = ctx->_ImageTransferState; - SWspan span; - - /* Try an optimized glDrawPixels first */ - if (fast_draw_rgba_pixels(ctx, x, y, width, height, format, type, - unpack, pixels)) { - return; - } - - swrast_render_start(ctx); - - INIT_SPAN(span, GL_BITMAP); - _swrast_span_default_attribs(ctx, &span); - span.arrayMask = SPAN_RGBA; - span.arrayAttribs = VARYING_BIT_COL0; /* we're fill in COL0 attrib values */ - - if (ctx->DrawBuffer->_NumColorDrawBuffers > 0) { - GLenum datatype = _mesa_get_format_datatype( - ctx->DrawBuffer->_ColorDrawBuffers[0]->Format); - if (datatype != GL_FLOAT && - ctx->Color.ClampFragmentColor != GL_FALSE) { - /* need to clamp colors before applying fragment ops */ - transferOps |= IMAGE_CLAMP_BIT; - } - } - - /* - * General solution - */ - { - const GLbitfield interpMask = span.interpMask; - const GLbitfield arrayMask = span.arrayMask; - GLint skipPixels = 0; - /* use span array for temp color storage */ - GLfloat *rgba = (GLfloat *) span.array->attribs[VARYING_SLOT_COL0]; - void *tempImage = NULL; - - /* We have to deal with GL_COLOR_INDEX manually because - * _mesa_format_convert does not handle this format. So what we do here is - * convert it to RGBA ubyte first and then convert from that to dst as - * usual. - */ - if (format == GL_COLOR_INDEX) { - /* This will handle byte swapping and transferops if needed */ - tempImage = - _mesa_unpack_color_index_to_rgba_ubyte(ctx, 2, - pixels, format, type, - width, height, 1, - unpack, - transferOps); - if (!tempImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); - return; - } - - transferOps = 0; - pixels = tempImage; - format = GL_RGBA; - type = GL_UNSIGNED_BYTE; - } else if (unpack->SwapBytes) { - /* We have to handle byte-swapping scenarios before calling - * _mesa_format_convert - */ - GLint swapSize = _mesa_sizeof_packed_type(type); - if (swapSize == 2 || swapSize == 4) { - int imageStride = _mesa_image_image_stride(unpack, width, height, format, type); - - tempImage = malloc(imageStride); - if (!tempImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); - return; - } - - _mesa_swap_bytes_2d_image(format, type, unpack, - width, height, tempImage, pixels); - - pixels = tempImage; - } - } - - const GLint srcStride - = _mesa_image_row_stride(unpack, width, format, type); - - /* if the span is wider than SWRAST_MAX_WIDTH we have to do it in chunks */ - while (skipPixels < width) { - const GLint spanWidth = MIN2(width - skipPixels, SWRAST_MAX_WIDTH); - const GLubyte *source - = (const GLubyte *) _mesa_image_address2d(unpack, pixels, - width, height, format, - type, 0, skipPixels); - GLint row; - - /* get image row as float/RGBA */ - uint32_t srcMesaFormat = _mesa_format_from_format_and_type(format, type); - for (row = 0; row < height; row++) { - int dstRowStride = 4 * width * sizeof(float); - _mesa_format_convert(rgba, RGBA32_FLOAT, dstRowStride, - (void*)source, srcMesaFormat, srcStride, - spanWidth, 1, NULL); - if (transferOps) - _mesa_apply_rgba_transfer_ops(ctx, transferOps, spanWidth, (GLfloat (*)[4])rgba); - /* Set these for each row since the _swrast_write_* functions - * may change them while clipping/rendering. - */ - span.array->ChanType = GL_FLOAT; - span.x = x + skipPixels; - span.y = y + row; - span.end = spanWidth; - span.arrayMask = arrayMask; - span.interpMask = interpMask; - if (zoom) { - _swrast_write_zoomed_rgba_span(ctx, imgX, imgY, &span, rgba); - } - else { - _swrast_write_rgba_span(ctx, &span); - } - - source += srcStride; - } /* for row */ - - skipPixels += spanWidth; - } /* while skipPixels < width */ - - /* XXX this is ugly/temporary, to undo above change */ - span.array->ChanType = CHAN_TYPE; - - free(tempImage); - } - - swrast_render_finish(ctx); -} - -/** - * Incoming Z/stencil values are always in uint_24_8 format. - */ -static void -pack_uint_24_8_depth_stencil_row(mesa_format format, uint32_t n, - const uint32_t *src, void *dst) -{ - switch (format) { - case MESA_FORMAT_S8_UINT_Z24_UNORM: - memcpy(dst, src, n * sizeof(uint32_t)); - break; - case MESA_FORMAT_Z24_UNORM_S8_UINT: - { - uint32_t *d = ((uint32_t *) dst); - uint32_t i; - for (i = 0; i < n; i++) { - uint32_t s = src[i] << 24; - uint32_t z = src[i] >> 8; - d[i] = s | z; - } - } - break; - default: - unreachable("bad format in _mesa_pack_ubyte_s_row"); - } -} - -/** - * Draw depth+stencil values into a MESA_FORAMT_Z24_S8 or MESA_FORMAT_Z24_UNORM_S8_UINT - * renderbuffer. No masking, zooming, scaling, etc. - */ -static void -fast_draw_depth_stencil(struct gl_context *ctx, GLint x, GLint y, - GLsizei width, GLsizei height, - const struct gl_pixelstore_attrib *unpack, - const GLvoid *pixels) -{ - const GLenum format = GL_DEPTH_STENCIL_EXT; - const GLenum type = GL_UNSIGNED_INT_24_8; - struct gl_renderbuffer *rb = - ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; - struct swrast_renderbuffer *srb = swrast_renderbuffer(rb); - GLubyte *src, *dst; - GLint srcRowStride, dstRowStride; - GLint i; - - src = _mesa_image_address2d(unpack, pixels, width, height, - format, type, 0, 0); - srcRowStride = _mesa_image_row_stride(unpack, width, format, type); - - dst = _swrast_pixel_address(rb, x, y); - dstRowStride = srb->RowStride; - - for (i = 0; i < height; i++) { - pack_uint_24_8_depth_stencil_row(rb->Format, width, (const GLuint *) src, dst); - dst += dstRowStride; - src += srcRowStride; - } -} - - - -/** - * This is a bit different from drawing GL_DEPTH_COMPONENT pixels. - * The only per-pixel operations that apply are depth scale/bias, - * stencil offset/shift, GL_DEPTH_WRITEMASK and GL_STENCIL_WRITEMASK, - * and pixel zoom. - * Also, only the depth buffer and stencil buffers are touched, not the - * color buffer(s). - */ -static void -draw_depth_stencil_pixels(struct gl_context *ctx, GLint x, GLint y, - GLsizei width, GLsizei height, GLenum type, - const struct gl_pixelstore_attrib *unpack, - const GLvoid *pixels) -{ - const GLint imgX = x, imgY = y; - const GLboolean scaleOrBias - = ctx->Pixel.DepthScale != 1.0F || ctx->Pixel.DepthBias != 0.0F; - const GLuint stencilMask = ctx->Stencil.WriteMask[0]; - const GLenum stencilType = GL_UNSIGNED_BYTE; - const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F; - struct gl_renderbuffer *depthRb, *stencilRb; - struct gl_pixelstore_attrib clippedUnpack = *unpack; - - if (!zoom) { - if (!_mesa_clip_drawpixels(ctx, &x, &y, &width, &height, - &clippedUnpack)) { - /* totally clipped */ - return; - } - } - - depthRb = ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; - stencilRb = ctx->ReadBuffer->Attachment[BUFFER_STENCIL].Renderbuffer; - assert(depthRb); - assert(stencilRb); - - if (depthRb == stencilRb && - (depthRb->Format == MESA_FORMAT_S8_UINT_Z24_UNORM || - depthRb->Format == MESA_FORMAT_Z24_UNORM_S8_UINT) && - type == GL_UNSIGNED_INT_24_8 && - !scaleOrBias && - !zoom && - ctx->Depth.Mask && - (stencilMask & 0xff) == 0xff) { - fast_draw_depth_stencil(ctx, x, y, width, height, - &clippedUnpack, pixels); - } - else { - /* sub-optimal cases: - * Separate depth/stencil buffers, or pixel transfer ops required. - */ - /* XXX need to handle very wide images (skippixels) */ - GLuint *zValues; /* 32-bit Z values */ - GLint i; - - zValues = malloc(width * sizeof(GLuint)); - if (!zValues) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); - return; - } - - for (i = 0; i < height; i++) { - const GLuint *depthStencilSrc = (const GLuint *) - _mesa_image_address2d(&clippedUnpack, pixels, width, height, - GL_DEPTH_STENCIL_EXT, type, i, 0); - - if (ctx->Depth.Mask) { - _mesa_unpack_depth_span(ctx, width, - GL_UNSIGNED_INT, /* dest type */ - zValues, /* dest addr */ - 0xffffffff, /* depth max */ - type, /* src type */ - depthStencilSrc, /* src addr */ - &clippedUnpack); - if (zoom) { - _swrast_write_zoomed_z_span(ctx, imgX, imgY, width, x, - y + i, zValues); - } - else { - GLubyte *dst = _swrast_pixel_address(depthRb, x, y + i); - _mesa_pack_uint_z_row(depthRb->Format, width, zValues, dst); - } - } - - if (stencilMask != 0x0) { - GLubyte *stencilValues = (GLubyte *) zValues; /* re-use buffer */ - /* get stencil values, with shift/offset/mapping */ - _mesa_unpack_stencil_span(ctx, width, stencilType, stencilValues, - type, depthStencilSrc, &clippedUnpack, - ctx->_ImageTransferState); - if (zoom) - _swrast_write_zoomed_stencil_span(ctx, imgX, imgY, width, - x, y + i, stencilValues); - else - _swrast_write_stencil_span(ctx, width, x, y + i, stencilValues); - } - } - - free(zValues); - } -} - - -/** - * Execute software-based glDrawPixels. - * By time we get here, all error checking will have been done. - */ -void -_swrast_DrawPixels( struct gl_context *ctx, - GLint x, GLint y, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *unpack, - const GLvoid *pixels ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - GLboolean save_vp_override = ctx->VertexProgram._Overriden; - - if (!_mesa_check_conditional_render(ctx)) - return; /* don't draw */ - - /* We are creating fragments directly, without going through vertex - * programs. - * - * This override flag tells the fragment processing code that its input - * comes from a non-standard source, and it may therefore not rely on - * optimizations that assume e.g. constant color if there is no color - * vertex array. - */ - _mesa_set_vp_override(ctx, GL_TRUE); - - if (ctx->NewState) - _mesa_update_state(ctx); - - if (swrast->NewState) - _swrast_validate_derived( ctx ); - - pixels = _mesa_map_pbo_source(ctx, unpack, pixels); - if (!pixels) { - _mesa_set_vp_override(ctx, save_vp_override); - return; - } - - /* - * By time we get here, all error checking should have been done. - */ - switch (format) { - case GL_STENCIL_INDEX: - swrast_render_start(ctx); - draw_stencil_pixels( ctx, x, y, width, height, type, unpack, pixels ); - swrast_render_finish(ctx); - break; - case GL_DEPTH_COMPONENT: - swrast_render_start(ctx); - draw_depth_pixels( ctx, x, y, width, height, type, unpack, pixels ); - swrast_render_finish(ctx); - break; - case GL_DEPTH_STENCIL_EXT: - swrast_render_start(ctx); - draw_depth_stencil_pixels(ctx, x, y, width, height, type, unpack, pixels); - swrast_render_finish(ctx); - break; - default: - /* all other formats should be color formats */ - draw_rgba_pixels(ctx, x, y, width, height, format, type, unpack, pixels); - } - - _mesa_set_vp_override(ctx, save_vp_override); - - _mesa_unmap_pbo_source(ctx, unpack); -} diff --git a/src/mesa/swrast/s_feedback.c b/src/mesa/swrast/s_feedback.c deleted file mode 100644 index 71f48ce..0000000 --- a/src/mesa/swrast/s_feedback.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -#include "main/glheader.h" -#include "main/feedback.h" -#include "main/macros.h" - -#include "s_context.h" -#include "s_feedback.h" -#include "s_triangle.h" - - - -static void -feedback_vertex(struct gl_context * ctx, const SWvertex * v, const SWvertex * pv) -{ - GLfloat win[4]; - const GLfloat *vtc = v->attrib[VARYING_SLOT_TEX0]; - const GLfloat *color = v->attrib[VARYING_SLOT_COL0]; - - win[0] = v->attrib[VARYING_SLOT_POS][0]; - win[1] = v->attrib[VARYING_SLOT_POS][1]; - win[2] = v->attrib[VARYING_SLOT_POS][2] / ctx->DrawBuffer->_DepthMaxF; - win[3] = 1.0F / v->attrib[VARYING_SLOT_POS][3]; - - _mesa_feedback_vertex(ctx, win, color, vtc); -} - - -/* - * Put triangle in feedback buffer. - */ -void -_swrast_feedback_triangle(struct gl_context *ctx, const SWvertex *v0, - const SWvertex *v1, const SWvertex *v2) -{ - if (!_swrast_culltriangle(ctx, v0, v1, v2)) { - _mesa_feedback_token(ctx, (GLfloat) (GLint) GL_POLYGON_TOKEN); - _mesa_feedback_token(ctx, (GLfloat) 3); /* three vertices */ - - if (ctx->Light.ShadeModel == GL_SMOOTH) { - feedback_vertex(ctx, v0, v0); - feedback_vertex(ctx, v1, v1); - feedback_vertex(ctx, v2, v2); - } - else { - feedback_vertex(ctx, v0, v2); - feedback_vertex(ctx, v1, v2); - feedback_vertex(ctx, v2, v2); - } - } -} - - -void -_swrast_feedback_line(struct gl_context *ctx, const SWvertex *v0, - const SWvertex *v1) -{ - GLenum token = GL_LINE_TOKEN; - SWcontext *swrast = SWRAST_CONTEXT(ctx); - - if (swrast->StippleCounter == 0) - token = GL_LINE_RESET_TOKEN; - - _mesa_feedback_token(ctx, (GLfloat) (GLint) token); - - if (ctx->Light.ShadeModel == GL_SMOOTH) { - feedback_vertex(ctx, v0, v0); - feedback_vertex(ctx, v1, v1); - } - else { - feedback_vertex(ctx, v0, v1); - feedback_vertex(ctx, v1, v1); - } - - swrast->StippleCounter++; -} - - -void -_swrast_feedback_point(struct gl_context *ctx, const SWvertex *v) -{ - _mesa_feedback_token(ctx, (GLfloat) (GLint) GL_POINT_TOKEN); - feedback_vertex(ctx, v, v); -} - - -void -_swrast_select_triangle(struct gl_context *ctx, const SWvertex *v0, - const SWvertex *v1, const SWvertex *v2) -{ - if (!_swrast_culltriangle(ctx, v0, v1, v2)) { - const GLfloat zs = 1.0F / ctx->DrawBuffer->_DepthMaxF; - - _mesa_update_hitflag( ctx, v0->attrib[VARYING_SLOT_POS][2] * zs ); - _mesa_update_hitflag( ctx, v1->attrib[VARYING_SLOT_POS][2] * zs ); - _mesa_update_hitflag( ctx, v2->attrib[VARYING_SLOT_POS][2] * zs ); - } -} - - -void -_swrast_select_line(struct gl_context *ctx, const SWvertex *v0, const SWvertex *v1) -{ - const GLfloat zs = 1.0F / ctx->DrawBuffer->_DepthMaxF; - _mesa_update_hitflag( ctx, v0->attrib[VARYING_SLOT_POS][2] * zs ); - _mesa_update_hitflag( ctx, v1->attrib[VARYING_SLOT_POS][2] * zs ); -} - - -void -_swrast_select_point(struct gl_context *ctx, const SWvertex *v) -{ - const GLfloat zs = 1.0F / ctx->DrawBuffer->_DepthMaxF; - _mesa_update_hitflag( ctx, v->attrib[VARYING_SLOT_POS][2] * zs ); -} diff --git a/src/mesa/swrast/s_feedback.h b/src/mesa/swrast/s_feedback.h deleted file mode 100644 index b031669..0000000 --- a/src/mesa/swrast/s_feedback.h +++ /dev/null @@ -1,50 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -#ifndef S_FEEDBACK_H -#define S_FEEDBACK_H - - -#include "swrast.h" - - -extern void _swrast_feedback_point( struct gl_context *ctx, const SWvertex *v ); - -extern void _swrast_feedback_line( struct gl_context *ctx, - const SWvertex *v1, const SWvertex *v2 ); - -extern void _swrast_feedback_triangle( struct gl_context *ctx, const SWvertex *v0, - const SWvertex *v1, const SWvertex *v2 ); - -extern void _swrast_select_point( struct gl_context *ctx, const SWvertex *v ); - -extern void _swrast_select_line( struct gl_context *ctx, - const SWvertex *v1, const SWvertex *v2 ); - -extern void _swrast_select_triangle( struct gl_context *ctx, const SWvertex *v0, - const SWvertex *v1, const SWvertex *v2 ); - -#endif diff --git a/src/mesa/swrast/s_fog.c b/src/mesa/swrast/s_fog.c deleted file mode 100644 index 33da09b..0000000 --- a/src/mesa/swrast/s_fog.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -#include "c99_math.h" -#include "main/errors.h" -#include "main/glheader.h" -#include "main/macros.h" - -#include "s_context.h" -#include "s_fog.h" - - -/** - * Used to convert current raster distance to a fog factor in [0,1]. - */ -GLfloat -_swrast_z_to_fogfactor(struct gl_context *ctx, GLfloat z) -{ - GLfloat d, f; - - switch (ctx->Fog.Mode) { - case GL_LINEAR: - if (ctx->Fog.Start == ctx->Fog.End) - d = 1.0F; - else - d = 1.0F / (ctx->Fog.End - ctx->Fog.Start); - f = (ctx->Fog.End - z) * d; - return CLAMP(f, 0.0F, 1.0F); - case GL_EXP: - d = ctx->Fog.Density; - f = expf(-d * z); - f = CLAMP(f, 0.0F, 1.0F); - return f; - case GL_EXP2: - d = ctx->Fog.Density; - f = expf(-(d * d * z * z)); - f = CLAMP(f, 0.0F, 1.0F); - return f; - default: - _mesa_problem(ctx, "Bad fog mode in _swrast_z_to_fogfactor"); - return 0.0; - } -} - - -#define LINEAR_FOG(f, coord) f = (fogEnd - coord) * fogScale - -#define EXP_FOG(f, coord) f = expf(density * coord) - -#define EXP2_FOG(f, coord) \ -do { \ - GLfloat tmp = negDensitySquared * coord * coord; \ - if (tmp < FLT_MIN_10_EXP) \ - tmp = FLT_MIN_10_EXP; \ - f = expf(tmp); \ - } while(0) - - -#define BLEND_FOG(f, coord) f = coord - - - -/** - * Template code for computing fog blend factor and applying it to colors. - * \param TYPE either GLubyte, GLushort or GLfloat. - * \param COMPUTE_F code to compute the fog blend factor, f. - */ -#define FOG_LOOP(TYPE, FOG_FUNC) \ -if (span->arrayAttribs & VARYING_BIT_FOGC) { \ - GLuint i; \ - for (i = 0; i < span->end; i++) { \ - const GLfloat fogCoord = span->array->attribs[VARYING_SLOT_FOGC][i][0]; \ - const GLfloat c = fabsf(fogCoord); \ - GLfloat f, oneMinusF; \ - FOG_FUNC(f, c); \ - f = CLAMP(f, 0.0F, 1.0F); \ - oneMinusF = 1.0F - f; \ - rgba[i][RCOMP] = (TYPE) (f * rgba[i][RCOMP] + oneMinusF * rFog); \ - rgba[i][GCOMP] = (TYPE) (f * rgba[i][GCOMP] + oneMinusF * gFog); \ - rgba[i][BCOMP] = (TYPE) (f * rgba[i][BCOMP] + oneMinusF * bFog); \ - } \ -} \ -else { \ - const GLfloat fogStep = span->attrStepX[VARYING_SLOT_FOGC][0]; \ - GLfloat fogCoord = span->attrStart[VARYING_SLOT_FOGC][0]; \ - const GLfloat wStep = span->attrStepX[VARYING_SLOT_POS][3]; \ - GLfloat w = span->attrStart[VARYING_SLOT_POS][3]; \ - GLuint i; \ - for (i = 0; i < span->end; i++) { \ - const GLfloat c = fabsf(fogCoord) / w; \ - GLfloat f, oneMinusF; \ - FOG_FUNC(f, c); \ - f = CLAMP(f, 0.0F, 1.0F); \ - oneMinusF = 1.0F - f; \ - rgba[i][RCOMP] = (TYPE) (f * rgba[i][RCOMP] + oneMinusF * rFog); \ - rgba[i][GCOMP] = (TYPE) (f * rgba[i][GCOMP] + oneMinusF * gFog); \ - rgba[i][BCOMP] = (TYPE) (f * rgba[i][BCOMP] + oneMinusF * bFog); \ - fogCoord += fogStep; \ - w += wStep; \ - } \ -} - -/** - * Apply fog to a span of RGBA pixels. - * The fog value are either in the span->array->fog array or interpolated from - * the fog/fogStep values. - * They fog values are either fog coordinates (Z) or fog blend factors. - * _PreferPixelFog should be in sync with that state! - */ -void -_swrast_fog_rgba_span( const struct gl_context *ctx, SWspan *span ) -{ - const SWcontext *swrast = CONST_SWRAST_CONTEXT(ctx); - GLfloat rFog, gFog, bFog; - - assert(swrast->_FogEnabled); - assert(span->arrayMask & SPAN_RGBA); - - /* compute (scaled) fog color */ - if (span->array->ChanType == GL_UNSIGNED_BYTE) { - rFog = ctx->Fog.Color[RCOMP] * 255.0F; - gFog = ctx->Fog.Color[GCOMP] * 255.0F; - bFog = ctx->Fog.Color[BCOMP] * 255.0F; - } - else if (span->array->ChanType == GL_UNSIGNED_SHORT) { - rFog = ctx->Fog.Color[RCOMP] * 65535.0F; - gFog = ctx->Fog.Color[GCOMP] * 65535.0F; - bFog = ctx->Fog.Color[BCOMP] * 65535.0F; - } - else { - rFog = ctx->Fog.Color[RCOMP]; - gFog = ctx->Fog.Color[GCOMP]; - bFog = ctx->Fog.Color[BCOMP]; - } - - if (swrast->_PreferPixelFog) { - /* The span's fog values are fog coordinates, now compute blend factors - * and blend the fragment colors with the fog color. - */ - switch (ctx->Fog.Mode) { - case GL_LINEAR: - { - const GLfloat fogEnd = ctx->Fog.End; - const GLfloat fogScale = (ctx->Fog.Start == ctx->Fog.End) - ? 1.0F : 1.0F / (ctx->Fog.End - ctx->Fog.Start); - if (span->array->ChanType == GL_UNSIGNED_BYTE) { - GLubyte (*rgba)[4] = span->array->rgba8; - FOG_LOOP(GLubyte, LINEAR_FOG); - } - else if (span->array->ChanType == GL_UNSIGNED_SHORT) { - GLushort (*rgba)[4] = span->array->rgba16; - FOG_LOOP(GLushort, LINEAR_FOG); - } - else { - GLfloat (*rgba)[4] = span->array->attribs[VARYING_SLOT_COL0]; - assert(span->array->ChanType == GL_FLOAT); - FOG_LOOP(GLfloat, LINEAR_FOG); - } - } - break; - - case GL_EXP: - { - const GLfloat density = -ctx->Fog.Density; - if (span->array->ChanType == GL_UNSIGNED_BYTE) { - GLubyte (*rgba)[4] = span->array->rgba8; - FOG_LOOP(GLubyte, EXP_FOG); - } - else if (span->array->ChanType == GL_UNSIGNED_SHORT) { - GLushort (*rgba)[4] = span->array->rgba16; - FOG_LOOP(GLushort, EXP_FOG); - } - else { - GLfloat (*rgba)[4] = span->array->attribs[VARYING_SLOT_COL0]; - assert(span->array->ChanType == GL_FLOAT); - FOG_LOOP(GLfloat, EXP_FOG); - } - } - break; - - case GL_EXP2: - { - const GLfloat negDensitySquared = -ctx->Fog.Density * ctx->Fog.Density; - if (span->array->ChanType == GL_UNSIGNED_BYTE) { - GLubyte (*rgba)[4] = span->array->rgba8; - FOG_LOOP(GLubyte, EXP2_FOG); - } - else if (span->array->ChanType == GL_UNSIGNED_SHORT) { - GLushort (*rgba)[4] = span->array->rgba16; - FOG_LOOP(GLushort, EXP2_FOG); - } - else { - GLfloat (*rgba)[4] = span->array->attribs[VARYING_SLOT_COL0]; - assert(span->array->ChanType == GL_FLOAT); - FOG_LOOP(GLfloat, EXP2_FOG); - } - } - break; - - default: - _mesa_problem(ctx, "Bad fog mode in _swrast_fog_rgba_span"); - return; - } - } - else { - /* The span's fog start/step/array values are blend factors in [0,1]. - * They were previously computed per-vertex. - */ - if (span->array->ChanType == GL_UNSIGNED_BYTE) { - GLubyte (*rgba)[4] = span->array->rgba8; - FOG_LOOP(GLubyte, BLEND_FOG); - } - else if (span->array->ChanType == GL_UNSIGNED_SHORT) { - GLushort (*rgba)[4] = span->array->rgba16; - FOG_LOOP(GLushort, BLEND_FOG); - } - else { - GLfloat (*rgba)[4] = span->array->attribs[VARYING_SLOT_COL0]; - assert(span->array->ChanType == GL_FLOAT); - FOG_LOOP(GLfloat, BLEND_FOG); - } - } -} diff --git a/src/mesa/swrast/s_fog.h b/src/mesa/swrast/s_fog.h deleted file mode 100644 index 0afeb82..0000000 --- a/src/mesa/swrast/s_fog.h +++ /dev/null @@ -1,42 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2002 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -#ifndef S_FOG_H -#define S_FOG_H - - -#include "main/glheader.h" -#include "s_span.h" - -struct gl_context; - -extern GLfloat -_swrast_z_to_fogfactor(struct gl_context *ctx, GLfloat z); - -extern void -_swrast_fog_rgba_span( const struct gl_context *ctx, SWspan *span ); - -#endif diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c deleted file mode 100644 index 6fbf7bc..0000000 --- a/src/mesa/swrast/s_fragprog.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -#include "main/glheader.h" -#include "main/macros.h" -#include "main/samplerobj.h" -#include "main/teximage.h" -#include "program/prog_instruction.h" - -#include "s_context.h" -#include "s_fragprog.h" -#include "s_span.h" - -/** - * \brief Should swrast use a fragment program? - * - * \return true if the current fragment program exists and is not the fixed - * function fragment program - */ -GLboolean -_swrast_use_fragment_program(struct gl_context *ctx) -{ - struct gl_program *fp = ctx->FragmentProgram._Current; - return fp && !(fp == ctx->FragmentProgram._TexEnvProgram - && fp->arb.NumInstructions == 0); -} - -/** - * Apply texture object's swizzle (X/Y/Z/W/0/1) to incoming 'texel' - * and return results in 'colorOut'. - */ -static inline void -swizzle_texel(const GLfloat texel[4], GLfloat colorOut[4], GLuint swizzle) -{ - if (swizzle == SWIZZLE_NOOP) { - COPY_4V(colorOut, texel); - } - else { - GLfloat vector[6]; - vector[SWIZZLE_X] = texel[0]; - vector[SWIZZLE_Y] = texel[1]; - vector[SWIZZLE_Z] = texel[2]; - vector[SWIZZLE_W] = texel[3]; - vector[SWIZZLE_ZERO] = 0.0F; - vector[SWIZZLE_ONE] = 1.0F; - colorOut[0] = vector[GET_SWZ(swizzle, 0)]; - colorOut[1] = vector[GET_SWZ(swizzle, 1)]; - colorOut[2] = vector[GET_SWZ(swizzle, 2)]; - colorOut[3] = vector[GET_SWZ(swizzle, 3)]; - } -} - - -/** - * Fetch a texel with given lod. - * Called via machine->FetchTexelLod() - */ -static void -fetch_texel_lod( struct gl_context *ctx, const GLfloat texcoord[4], GLfloat lambda, - GLuint unit, GLfloat color[4] ) -{ - const struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current; - - if (texObj) { - SWcontext *swrast = SWRAST_CONTEXT(ctx); - GLfloat rgba[4]; - const struct gl_sampler_object *samp = _mesa_get_samplerobj(ctx, unit); - - lambda = CLAMP(lambda, samp->Attrib.MinLod, samp->Attrib.MaxLod); - - swrast->TextureSample[unit](ctx, samp, ctx->Texture.Unit[unit]._Current, - 1, (const GLfloat (*)[4]) texcoord, - &lambda, &rgba); - swizzle_texel(rgba, color, texObj->Attrib._Swizzle); - } - else { - ASSIGN_4V(color, 0.0F, 0.0F, 0.0F, 1.0F); - } -} - - -/** - * Fetch a texel with the given partial derivatives to compute a level - * of detail in the mipmap. - * Called via machine->FetchTexelDeriv() - * \param lodBias the lod bias which may be specified by a TXB instruction, - * otherwise zero. - */ -static void -fetch_texel_deriv( struct gl_context *ctx, const GLfloat texcoord[4], - const GLfloat texdx[4], const GLfloat texdy[4], - GLfloat lodBias, GLuint unit, GLfloat color[4] ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; - const struct gl_texture_object *texObj = texUnit->_Current; - - if (texObj) { - const struct gl_texture_image *texImg = _mesa_base_tex_image(texObj); - const struct swrast_texture_image *swImg = - swrast_texture_image_const(texImg); - const struct gl_sampler_object *samp = _mesa_get_samplerobj(ctx, unit); - const GLfloat texW = (GLfloat) swImg->WidthScale; - const GLfloat texH = (GLfloat) swImg->HeightScale; - GLfloat lambda; - GLfloat rgba[4]; - - lambda = _swrast_compute_lambda(texdx[0], texdy[0], /* ds/dx, ds/dy */ - texdx[1], texdy[1], /* dt/dx, dt/dy */ - texdx[3], texdy[3], /* dq/dx, dq/dy */ - texW, texH, - texcoord[0], texcoord[1], texcoord[3], - 1.0F / texcoord[3]); - - lambda += lodBias + texUnit->LodBias + samp->Attrib.LodBias; - - lambda = CLAMP(lambda, samp->Attrib.MinLod, samp->Attrib.MaxLod); - - swrast->TextureSample[unit](ctx, samp, ctx->Texture.Unit[unit]._Current, - 1, (const GLfloat (*)[4]) texcoord, - &lambda, &rgba); - swizzle_texel(rgba, color, texObj->Attrib._Swizzle); - } - else { - ASSIGN_4V(color, 0.0F, 0.0F, 0.0F, 1.0F); - } -} - - -/** - * Initialize the virtual fragment program machine state prior to running - * fragment program on a fragment. This involves initializing the input - * registers, condition codes, etc. - * \param machine the virtual machine state to init - * \param program the fragment program we're about to run - * \param span the span of pixels we'll operate on - * \param col which element (column) of the span we'll operate on - */ -static void -init_machine(struct gl_context *ctx, struct gl_program_machine *machine, - const struct gl_program *program, const SWspan *span, GLuint col) -{ - GLfloat *wpos = span->array->attribs[VARYING_SLOT_POS][col]; - - /* ARB_fragment_coord_conventions */ - if (program->info.fs.origin_upper_left) - wpos[1] = ctx->DrawBuffer->Height - 1 - wpos[1]; - if (!program->info.fs.pixel_center_integer) { - wpos[0] += 0.5F; - wpos[1] += 0.5F; - } - - /* Setup pointer to input attributes */ - machine->Attribs = span->array->attribs; - - machine->DerivX = (GLfloat (*)[4]) span->attrStepX; - machine->DerivY = (GLfloat (*)[4]) span->attrStepY; - machine->NumDeriv = VARYING_SLOT_MAX; - - machine->Samplers = program->SamplerUnits; - - /* if running a GLSL program (not ARB_fragment_program) */ - if (ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT]) { - /* Store front/back facing value */ - machine->Attribs[VARYING_SLOT_FACE][col][0] = 1.0F - span->facing; - } - - machine->CurElement = col; - - /* init call stack */ - machine->StackDepth = 0; - - machine->FetchTexelLod = fetch_texel_lod; - machine->FetchTexelDeriv = fetch_texel_deriv; -} - - -/** - * Run fragment program on the pixels in span from 'start' to 'end' - 1. - */ -static void -run_program(struct gl_context *ctx, SWspan *span, GLuint start, GLuint end) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - const struct gl_program *program = ctx->FragmentProgram._Current; - const GLbitfield64 outputsWritten = program->info.outputs_written; - struct gl_program_machine *machine = &swrast->FragProgMachine; - GLuint i; - - for (i = start; i < end; i++) { - if (span->array->mask[i]) { - init_machine(ctx, machine, program, span, i); - - if (_mesa_execute_program(ctx, program, machine)) { - - /* Store result color */ - if (outputsWritten & BITFIELD64_BIT(FRAG_RESULT_COLOR)) { - COPY_4V(span->array->attribs[VARYING_SLOT_COL0][i], - machine->Outputs[FRAG_RESULT_COLOR]); - } - else { - /* Multiple drawbuffers / render targets - * Note that colors beyond 0 and 1 will overwrite other - * attributes, such as FOGC, TEX0, TEX1, etc. That's OK. - */ - GLuint buf; - for (buf = 0; buf < ctx->DrawBuffer->_NumColorDrawBuffers; buf++) { - if (outputsWritten & BITFIELD64_BIT(FRAG_RESULT_DATA0 + buf)) { - COPY_4V(span->array->attribs[VARYING_SLOT_COL0 + buf][i], - machine->Outputs[FRAG_RESULT_DATA0 + buf]); - } - } - } - - /* Store result depth/z */ - if (outputsWritten & BITFIELD64_BIT(FRAG_RESULT_DEPTH)) { - const GLfloat depth = machine->Outputs[FRAG_RESULT_DEPTH][2]; - if (depth <= 0.0F) - span->array->z[i] = 0; - else if (depth >= 1.0F) - span->array->z[i] = ctx->DrawBuffer->_DepthMax; - else - span->array->z[i] = - (GLuint) (depth * ctx->DrawBuffer->_DepthMaxF + 0.5F); - } - } - else { - /* killed fragment */ - span->array->mask[i] = GL_FALSE; - span->writeAll = GL_FALSE; - } - } - } -} - - -/** - * Execute the current fragment program for all the fragments - * in the given span. - */ -void -_swrast_exec_fragment_program( struct gl_context *ctx, SWspan *span ) -{ - const struct gl_program *program = ctx->FragmentProgram._Current; - - /* incoming colors should be floats */ - if (program->info.inputs_read & VARYING_BIT_COL0) { - assert(span->array->ChanType == GL_FLOAT); - } - - run_program(ctx, span, 0, span->end); - - if (program->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_COLOR)) { - span->interpMask &= ~SPAN_RGBA; - span->arrayMask |= SPAN_RGBA; - } - - if (program->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_DEPTH)) { - span->interpMask &= ~SPAN_Z; - span->arrayMask |= SPAN_Z; - } -} - diff --git a/src/mesa/swrast/s_fragprog.h b/src/mesa/swrast/s_fragprog.h deleted file mode 100644 index 1ee201e..0000000 --- a/src/mesa/swrast/s_fragprog.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -#ifndef S_FRAGPROG_H -#define S_FRAGPROG_H - - -#include "s_span.h" - -struct gl_context; - -GLboolean -_swrast_use_fragment_program(struct gl_context *ctx); - -extern void -_swrast_exec_fragment_program(struct gl_context *ctx, SWspan *span); - - -#endif /* S_FRAGPROG_H */ - diff --git a/src/mesa/swrast/s_lines.c b/src/mesa/swrast/s_lines.c deleted file mode 100644 index ab8da7d..0000000 --- a/src/mesa/swrast/s_lines.c +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -#include "main/glheader.h" -#include "main/context.h" -#include "main/macros.h" -#include "s_aaline.h" -#include "s_context.h" -#include "s_feedback.h" -#include "s_lines.h" -#include "s_span.h" - - -/* - * Init the mask[] array to implement a line stipple. - */ -static void -compute_stipple_mask( struct gl_context *ctx, GLuint len, GLubyte mask[] ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - GLuint i; - - for (i = 0; i < len; i++) { - GLuint bit = (swrast->StippleCounter / ctx->Line.StippleFactor) & 0xf; - if ((1 << bit) & ctx->Line.StipplePattern) { - mask[i] = GL_TRUE; - } - else { - mask[i] = GL_FALSE; - } - swrast->StippleCounter++; - } -} - - -/* - * To draw a wide line we can simply redraw the span N times, side by side. - */ -static void -draw_wide_line( struct gl_context *ctx, SWspan *span, GLboolean xMajor ) -{ - const GLint width = (GLint) CLAMP(ctx->Line.Width, - ctx->Const.MinLineWidth, - ctx->Const.MaxLineWidth); - GLint start; - - assert(span->end < SWRAST_MAX_WIDTH); - - if (width & 1) - start = width / 2; - else - start = width / 2 - 1; - - if (xMajor) { - GLint *y = span->array->y; - GLuint i; - GLint w; - for (w = 0; w < width; w++) { - if (w == 0) { - for (i = 0; i < span->end; i++) - y[i] -= start; - } - else { - for (i = 0; i < span->end; i++) - y[i]++; - } - _swrast_write_rgba_span(ctx, span); - } - } - else { - GLint *x = span->array->x; - GLuint i; - GLint w; - for (w = 0; w < width; w++) { - if (w == 0) { - for (i = 0; i < span->end; i++) - x[i] -= start; - } - else { - for (i = 0; i < span->end; i++) - x[i]++; - } - _swrast_write_rgba_span(ctx, span); - } - } -} - - - -/**********************************************************************/ -/***** Rasterization *****/ -/**********************************************************************/ - -/* Simple RGBA index line (no stipple, width=1, no Z, no fog, no tex)*/ -#define NAME simple_no_z_rgba_line -#define INTERP_RGBA -#define RENDER_SPAN(span) _swrast_write_rgba_span(ctx, &span); -#include "s_linetemp.h" - - -/* Z, fog, wide, stipple RGBA line */ -#define NAME rgba_line -#define INTERP_RGBA -#define INTERP_Z -#define RENDER_SPAN(span) \ - if (ctx->Line.StippleFlag) { \ - span.arrayMask |= SPAN_MASK; \ - compute_stipple_mask(ctx, span.end, span.array->mask); \ - } \ - if (ctx->Line.Width > 1.0) { \ - draw_wide_line(ctx, &span, (GLboolean)(dx > dy)); \ - } \ - else { \ - _swrast_write_rgba_span(ctx, &span); \ - } -#include "s_linetemp.h" - - -/* General-purpose line (any/all features). */ -#define NAME general_line -#define INTERP_RGBA -#define INTERP_Z -#define INTERP_ATTRIBS -#define RENDER_SPAN(span) \ - if (ctx->Line.StippleFlag) { \ - span.arrayMask |= SPAN_MASK; \ - compute_stipple_mask(ctx, span.end, span.array->mask); \ - } \ - if (ctx->Line.Width > 1.0) { \ - draw_wide_line(ctx, &span, (GLboolean)(dx > dy)); \ - } \ - else { \ - _swrast_write_rgba_span(ctx, &span); \ - } -#include "s_linetemp.h" - - - -void -_swrast_add_spec_terms_line(struct gl_context *ctx, - const SWvertex *v0, const SWvertex *v1) -{ - SWvertex *ncv0 = (SWvertex *)v0; - SWvertex *ncv1 = (SWvertex *)v1; - GLfloat rSum, gSum, bSum; - GLchan cSave[2][4]; - - /* save original colors */ - COPY_CHAN4(cSave[0], ncv0->color); - COPY_CHAN4(cSave[1], ncv1->color); - /* sum v0 */ - rSum = CHAN_TO_FLOAT(ncv0->color[0]) + ncv0->attrib[VARYING_SLOT_COL1][0]; - gSum = CHAN_TO_FLOAT(ncv0->color[1]) + ncv0->attrib[VARYING_SLOT_COL1][1]; - bSum = CHAN_TO_FLOAT(ncv0->color[2]) + ncv0->attrib[VARYING_SLOT_COL1][2]; - UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[0], rSum); - UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[1], gSum); - UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[2], bSum); - /* sum v1 */ - rSum = CHAN_TO_FLOAT(ncv1->color[0]) + ncv1->attrib[VARYING_SLOT_COL1][0]; - gSum = CHAN_TO_FLOAT(ncv1->color[1]) + ncv1->attrib[VARYING_SLOT_COL1][1]; - bSum = CHAN_TO_FLOAT(ncv1->color[2]) + ncv1->attrib[VARYING_SLOT_COL1][2]; - UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[0], rSum); - UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[1], gSum); - UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[2], bSum); - /* draw */ - SWRAST_CONTEXT(ctx)->SpecLine( ctx, ncv0, ncv1 ); - /* restore original colors */ - COPY_CHAN4(ncv0->color, cSave[0]); - COPY_CHAN4(ncv1->color, cSave[1]); -} - - - -#ifdef DEBUG - -/* record the current line function name */ -static const char *lineFuncName = NULL; - -#define USE(lineFunc) \ -do { \ - lineFuncName = #lineFunc; \ - /*printf("%s\n", lineFuncName);*/ \ - swrast->Line = lineFunc; \ -} while (0) - -#else - -#define USE(lineFunc) swrast->Line = lineFunc - -#endif - - - -/** - * Determine which line drawing function to use given the current - * rendering context. - * - * Please update the summary flag _SWRAST_NEW_LINE if you add or remove - * tests to this code. - */ -void -_swrast_choose_line( struct gl_context *ctx ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - GLboolean specular = (ctx->Fog.ColorSumEnabled || - (ctx->Light.Enabled && - ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)); - - if (ctx->RenderMode == GL_RENDER) { - if (ctx->Line.SmoothFlag) { - /* antialiased lines */ - _swrast_choose_aa_line_function(ctx); - assert(swrast->Line); - } - else if (ctx->Texture._EnabledCoordUnits - || _swrast_use_fragment_program(ctx) - || swrast->_FogEnabled - || specular) { - USE(general_line); - } - else if (ctx->Depth.Test - || ctx->Line.Width != 1.0F - || ctx->Line.StippleFlag) { - /* no texture, but Z, fog, width>1, stipple, etc. */ -#if CHAN_BITS == 32 - USE(general_line); -#else - USE(rgba_line); -#endif - } - else { - assert(!ctx->Depth.Test); - assert(ctx->Line.Width == 1.0F); - /* simple lines */ - USE(simple_no_z_rgba_line); - } - } - else if (ctx->RenderMode == GL_FEEDBACK) { - USE(_swrast_feedback_line); - } - else { - assert(ctx->RenderMode == GL_SELECT); - USE(_swrast_select_line); - } -} diff --git a/src/mesa/swrast/s_lines.h b/src/mesa/swrast/s_lines.h deleted file mode 100644 index add72b8..0000000 --- a/src/mesa/swrast/s_lines.h +++ /dev/null @@ -1,41 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -#ifndef S_LINES_H -#define S_LINES_H - -#include "swrast.h" - -void -_swrast_choose_line( struct gl_context *ctx ); - -void -_swrast_add_spec_terms_line( struct gl_context *ctx, - const SWvertex *v0, - const SWvertex *v1 ); - - -#endif diff --git a/src/mesa/swrast/s_linetemp.h b/src/mesa/swrast/s_linetemp.h deleted file mode 100644 index 6706ec7..0000000 --- a/src/mesa/swrast/s_linetemp.h +++ /dev/null @@ -1,402 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -/* - * Line Rasterizer Template - * - * This file is #include'd to generate custom line rasterizers. - * - * The following macros may be defined to indicate what auxillary information - * must be interplated along the line: - * INTERP_Z - if defined, interpolate Z values - * INTERP_ATTRIBS - if defined, interpolate attribs (texcoords, varying, etc) - * - * When one can directly address pixels in the color buffer the following - * macros can be defined and used to directly compute pixel addresses during - * rasterization (see pixelPtr): - * PIXEL_TYPE - the datatype of a pixel (GLubyte, GLushort, GLuint) - * BYTES_PER_ROW - number of bytes per row in the color buffer - * PIXEL_ADDRESS(X,Y) - returns the address of pixel at (X,Y) where - * Y==0 at bottom of screen and increases upward. - * - * Similarly, for direct depth buffer access, this type is used for depth - * buffer addressing: - * DEPTH_TYPE - either GLushort or GLuint - * - * Optionally, one may provide one-time setup code - * SETUP_CODE - code which is to be executed once per line - * - * To actually "plot" each pixel the PLOT macro must be defined... - * PLOT(X,Y) - code to plot a pixel. Example: - * if (Z < *zPtr) { - * *zPtr = Z; - * color = pack_rgb( FixedToInt(r0), FixedToInt(g0), - * FixedToInt(b0) ); - * put_pixel( X, Y, color ); - * } - * - * This code was designed for the origin to be in the lower-left corner. - * - */ - - -static void -NAME( struct gl_context *ctx, const SWvertex *vert0, const SWvertex *vert1 ) -{ - const SWcontext *swrast = SWRAST_CONTEXT(ctx); - SWspan span; - GLuint interpFlags = 0; - GLint x0 = (GLint) vert0->attrib[VARYING_SLOT_POS][0]; - GLint x1 = (GLint) vert1->attrib[VARYING_SLOT_POS][0]; - GLint y0 = (GLint) vert0->attrib[VARYING_SLOT_POS][1]; - GLint y1 = (GLint) vert1->attrib[VARYING_SLOT_POS][1]; - GLint dx, dy; - GLint numPixels; - GLint xstep, ystep; -#if defined(DEPTH_TYPE) - const GLint depthBits = ctx->DrawBuffer->Visual.depthBits; - const GLint fixedToDepthShift = depthBits <= 16 ? FIXED_SHIFT : 0; - struct gl_renderbuffer *zrb = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; -#define FixedToDepth(F) ((F) >> fixedToDepthShift) - GLint zPtrXstep, zPtrYstep; - DEPTH_TYPE *zPtr; -#elif defined(INTERP_Z) - const GLint depthBits = ctx->DrawBuffer->Visual.depthBits; -#endif -#ifdef PIXEL_ADDRESS - PIXEL_TYPE *pixelPtr; - GLint pixelXstep, pixelYstep; -#endif - -#ifdef SETUP_CODE - SETUP_CODE -#endif - - (void) swrast; - - /* Cull primitives with malformed coordinates. - */ - { - GLfloat tmp = vert0->attrib[VARYING_SLOT_POS][0] + vert0->attrib[VARYING_SLOT_POS][1] - + vert1->attrib[VARYING_SLOT_POS][0] + vert1->attrib[VARYING_SLOT_POS][1]; - if (util_is_inf_or_nan(tmp)) - return; - } - - /* - printf("%s():\n", __func__); - printf(" (%f, %f, %f) -> (%f, %f, %f)\n", - vert0->attrib[VARYING_SLOT_POS][0], - vert0->attrib[VARYING_SLOT_POS][1], - vert0->attrib[VARYING_SLOT_POS][2], - vert1->attrib[VARYING_SLOT_POS][0], - vert1->attrib[VARYING_SLOT_POS][1], - vert1->attrib[VARYING_SLOT_POS][2]); - printf(" (%d, %d, %d) -> (%d, %d, %d)\n", - vert0->color[0], vert0->color[1], vert0->color[2], - vert1->color[0], vert1->color[1], vert1->color[2]); - printf(" (%d, %d, %d) -> (%d, %d, %d)\n", - vert0->specular[0], vert0->specular[1], vert0->specular[2], - vert1->specular[0], vert1->specular[1], vert1->specular[2]); - */ - -/* - * Despite being clipped to the view volume, the line's window coordinates - * may just lie outside the window bounds. That is, if the legal window - * coordinates are [0,W-1][0,H-1], it's possible for x==W and/or y==H. - * This quick and dirty code nudges the endpoints inside the window if - * necessary. - */ -#ifdef CLIP_HACK - { - GLint w = ctx->DrawBuffer->Width; - GLint h = ctx->DrawBuffer->Height; - if ((x0==w) | (x1==w)) { - if ((x0==w) & (x1==w)) - return; - x0 -= x0==w; - x1 -= x1==w; - } - if ((y0==h) | (y1==h)) { - if ((y0==h) & (y1==h)) - return; - y0 -= y0==h; - y1 -= y1==h; - } - } -#endif - - dx = x1 - x0; - dy = y1 - y0; - if (dx == 0 && dy == 0) - return; - - /* - printf("%s %d,%d %g %g %g %g %g %g %g %g\n", __func__, dx, dy, - vert0->attrib[VARYING_SLOT_COL1][0], - vert0->attrib[VARYING_SLOT_COL1][1], - vert0->attrib[VARYING_SLOT_COL1][2], - vert0->attrib[VARYING_SLOT_COL1][3], - vert1->attrib[VARYING_SLOT_COL1][0], - vert1->attrib[VARYING_SLOT_COL1][1], - vert1->attrib[VARYING_SLOT_COL1][2], - vert1->attrib[VARYING_SLOT_COL1][3]); - */ - -#ifdef DEPTH_TYPE - zPtr = (DEPTH_TYPE *) _swrast_pixel_address(zrb, x0, y0); -#endif -#ifdef PIXEL_ADDRESS - pixelPtr = (PIXEL_TYPE *) PIXEL_ADDRESS(x0,y0); -#endif - - if (dx<0) { - dx = -dx; /* make positive */ - xstep = -1; -#ifdef DEPTH_TYPE - zPtrXstep = -((GLint)sizeof(DEPTH_TYPE)); -#endif -#ifdef PIXEL_ADDRESS - pixelXstep = -((GLint)sizeof(PIXEL_TYPE)); -#endif - } - else { - xstep = 1; -#ifdef DEPTH_TYPE - zPtrXstep = ((GLint)sizeof(DEPTH_TYPE)); -#endif -#ifdef PIXEL_ADDRESS - pixelXstep = ((GLint)sizeof(PIXEL_TYPE)); -#endif - } - - if (dy<0) { - dy = -dy; /* make positive */ - ystep = -1; -#ifdef DEPTH_TYPE - zPtrYstep = -((GLint) (ctx->DrawBuffer->Width * sizeof(DEPTH_TYPE))); -#endif -#ifdef PIXEL_ADDRESS - pixelYstep = BYTES_PER_ROW; -#endif - } - else { - ystep = 1; -#ifdef DEPTH_TYPE - zPtrYstep = (GLint) (ctx->DrawBuffer->Width * sizeof(DEPTH_TYPE)); -#endif -#ifdef PIXEL_ADDRESS - pixelYstep = -(BYTES_PER_ROW); -#endif - } - - assert(dx >= 0); - assert(dy >= 0); - - numPixels = MAX2(dx, dy); - - /* - * Span setup: compute start and step values for all interpolated values. - */ - interpFlags |= SPAN_RGBA; - if (ctx->Light.ShadeModel == GL_SMOOTH) { - span.red = ChanToFixed(vert0->color[0]); - span.green = ChanToFixed(vert0->color[1]); - span.blue = ChanToFixed(vert0->color[2]); - span.alpha = ChanToFixed(vert0->color[3]); - span.redStep = (ChanToFixed(vert1->color[0]) - span.red ) / numPixels; - span.greenStep = (ChanToFixed(vert1->color[1]) - span.green) / numPixels; - span.blueStep = (ChanToFixed(vert1->color[2]) - span.blue ) / numPixels; - span.alphaStep = (ChanToFixed(vert1->color[3]) - span.alpha) / numPixels; - } - else { - span.red = ChanToFixed(vert1->color[0]); - span.green = ChanToFixed(vert1->color[1]); - span.blue = ChanToFixed(vert1->color[2]); - span.alpha = ChanToFixed(vert1->color[3]); - span.redStep = 0; - span.greenStep = 0; - span.blueStep = 0; - span.alphaStep = 0; - } -#if defined(INTERP_Z) || defined(DEPTH_TYPE) - interpFlags |= SPAN_Z; - { - if (depthBits <= 16) { - span.z = FloatToFixed(vert0->attrib[VARYING_SLOT_POS][2]) + FIXED_HALF; - span.zStep = FloatToFixed( vert1->attrib[VARYING_SLOT_POS][2] - - vert0->attrib[VARYING_SLOT_POS][2]) / numPixels; - } - else { - /* don't use fixed point */ - span.z = (GLuint) vert0->attrib[VARYING_SLOT_POS][2]; - span.zStep = (GLint) (( vert1->attrib[VARYING_SLOT_POS][2] - - vert0->attrib[VARYING_SLOT_POS][2]) / numPixels); - } - } -#endif -#if defined(INTERP_ATTRIBS) - { - const GLfloat invLen = 1.0F / numPixels; - const GLfloat invw0 = vert0->attrib[VARYING_SLOT_POS][3]; - const GLfloat invw1 = vert1->attrib[VARYING_SLOT_POS][3]; - - span.attrStart[VARYING_SLOT_POS][3] = invw0; - span.attrStepX[VARYING_SLOT_POS][3] = (invw1 - invw0) * invLen; - span.attrStepY[VARYING_SLOT_POS][3] = 0.0; - - ATTRIB_LOOP_BEGIN - if (swrast->_InterpMode[attr] == GL_FLAT) { - COPY_4V(span.attrStart[attr], vert1->attrib[attr]); - ASSIGN_4V(span.attrStepX[attr], 0.0, 0.0, 0.0, 0.0); - } - else { - GLuint c; - for (c = 0; c < 4; c++) { - float da; - span.attrStart[attr][c] = invw0 * vert0->attrib[attr][c]; - da = (invw1 * vert1->attrib[attr][c]) - span.attrStart[attr][c]; - span.attrStepX[attr][c] = da * invLen; - } - } - ASSIGN_4V(span.attrStepY[attr], 0.0, 0.0, 0.0, 0.0); - ATTRIB_LOOP_END - } -#endif - - INIT_SPAN(span, GL_LINE); - span.end = numPixels; - span.interpMask = interpFlags; - span.arrayMask = SPAN_XY; - - span.facing = swrast->PointLineFacing; - - - /* - * Draw - */ - - if (dx > dy) { - /*** X-major line ***/ - GLint i; - GLint errorInc = dy+dy; - GLint error = errorInc-dx; - GLint errorDec = error-dx; - - for (i = 0; i < dx; i++) { -#ifdef DEPTH_TYPE - GLuint Z = FixedToDepth(span.z); -#endif -#ifdef PLOT - PLOT( x0, y0 ); -#else - span.array->x[i] = x0; - span.array->y[i] = y0; -#endif - x0 += xstep; -#ifdef DEPTH_TYPE - zPtr = (DEPTH_TYPE *) ((GLubyte*) zPtr + zPtrXstep); - span.z += span.zStep; -#endif -#ifdef PIXEL_ADDRESS - pixelPtr = (PIXEL_TYPE*) ((GLubyte*) pixelPtr + pixelXstep); -#endif - if (error < 0) { - error += errorInc; - } - else { - error += errorDec; - y0 += ystep; -#ifdef DEPTH_TYPE - zPtr = (DEPTH_TYPE *) ((GLubyte*) zPtr + zPtrYstep); -#endif -#ifdef PIXEL_ADDRESS - pixelPtr = (PIXEL_TYPE*) ((GLubyte*) pixelPtr + pixelYstep); -#endif - } - } - } - else { - /*** Y-major line ***/ - GLint i; - GLint errorInc = dx+dx; - GLint error = errorInc-dy; - GLint errorDec = error-dy; - - for (i=0;ix[i] = x0; - span.array->y[i] = y0; -#endif - y0 += ystep; -#ifdef DEPTH_TYPE - zPtr = (DEPTH_TYPE *) ((GLubyte*) zPtr + zPtrYstep); - span.z += span.zStep; -#endif -#ifdef PIXEL_ADDRESS - pixelPtr = (PIXEL_TYPE*) ((GLubyte*) pixelPtr + pixelYstep); -#endif - if (error<0) { - error += errorInc; - } - else { - error += errorDec; - x0 += xstep; -#ifdef DEPTH_TYPE - zPtr = (DEPTH_TYPE *) ((GLubyte*) zPtr + zPtrXstep); -#endif -#ifdef PIXEL_ADDRESS - pixelPtr = (PIXEL_TYPE*) ((GLubyte*) pixelPtr + pixelXstep); -#endif - } - } - } - -#ifdef RENDER_SPAN - RENDER_SPAN( span ); -#endif - - (void)span; - -} - - -#undef NAME -#undef INTERP_Z -#undef INTERP_ATTRIBS -#undef PIXEL_ADDRESS -#undef PIXEL_TYPE -#undef DEPTH_TYPE -#undef BYTES_PER_ROW -#undef SETUP_CODE -#undef PLOT -#undef CLIP_HACK -#undef FixedToDepth -#undef RENDER_SPAN diff --git a/src/mesa/swrast/s_logic.c b/src/mesa/swrast/s_logic.c deleted file mode 100644 index 304e3d5..0000000 --- a/src/mesa/swrast/s_logic.c +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -#include "main/glheader.h" -#include "main/context.h" - -#include "main/macros.h" - -#include "s_context.h" -#include "s_logic.h" -#include "s_span.h" - - -/** - * We do all logic ops on 4-byte GLuints. - * Depending on bytes per pixel, the mask array elements correspond to - * 1, 2 or 4 GLuints. - */ -#define LOGIC_OP_LOOP(MODE, MASKSTRIDE) \ -do { \ - GLuint i; \ - switch (MODE) { \ - case GL_CLEAR: \ - for (i = 0; i < n; i++) { \ - if (mask[i / MASKSTRIDE]) { \ - src[i] = 0; \ - } \ - } \ - break; \ - case GL_SET: \ - for (i = 0; i < n; i++) { \ - if (mask[i / MASKSTRIDE]) { \ - src[i] = ~0; \ - } \ - } \ - break; \ - case GL_COPY: \ - /* do nothing */ \ - break; \ - case GL_COPY_INVERTED: \ - for (i = 0; i < n; i++) { \ - if (mask[i / MASKSTRIDE]) { \ - src[i] = ~src[i]; \ - } \ - } \ - break; \ - case GL_NOOP: \ - for (i = 0; i < n; i++) { \ - if (mask[i / MASKSTRIDE]) { \ - src[i] = dest[i]; \ - } \ - } \ - break; \ - case GL_INVERT: \ - for (i = 0; i < n; i++) { \ - if (mask[i / MASKSTRIDE]) { \ - src[i] = ~dest[i]; \ - } \ - } \ - break; \ - case GL_AND: \ - for (i = 0; i < n; i++) { \ - if (mask[i / MASKSTRIDE]) { \ - src[i] &= dest[i]; \ - } \ - } \ - break; \ - case GL_NAND: \ - for (i = 0; i < n; i++) { \ - if (mask[i / MASKSTRIDE]) { \ - src[i] = ~(src[i] & dest[i]); \ - } \ - } \ - break; \ - case GL_OR: \ - for (i = 0; i < n; i++) { \ - if (mask[i / MASKSTRIDE]) { \ - src[i] |= dest[i]; \ - } \ - } \ - break; \ - case GL_NOR: \ - for (i = 0; i < n; i++) { \ - if (mask[i / MASKSTRIDE]) { \ - src[i] = ~(src[i] | dest[i]); \ - } \ - } \ - break; \ - case GL_XOR: \ - for (i = 0; i < n; i++) { \ - if (mask[i / MASKSTRIDE]) { \ - src[i] ^= dest[i]; \ - } \ - } \ - break; \ - case GL_EQUIV: \ - for (i = 0; i < n; i++) { \ - if (mask[i / MASKSTRIDE]) { \ - src[i] = ~(src[i] ^ dest[i]); \ - } \ - } \ - break; \ - case GL_AND_REVERSE: \ - for (i = 0; i < n; i++) { \ - if (mask[i / MASKSTRIDE]) { \ - src[i] = src[i] & ~dest[i]; \ - } \ - } \ - break; \ - case GL_AND_INVERTED: \ - for (i = 0; i < n; i++) { \ - if (mask[i / MASKSTRIDE]) { \ - src[i] = ~src[i] & dest[i]; \ - } \ - } \ - break; \ - case GL_OR_REVERSE: \ - for (i = 0; i < n; i++) { \ - if (mask[i / MASKSTRIDE]) { \ - src[i] = src[i] | ~dest[i]; \ - } \ - } \ - break; \ - case GL_OR_INVERTED: \ - for (i = 0; i < n; i++) { \ - if (mask[i / MASKSTRIDE]) { \ - src[i] = ~src[i] | dest[i]; \ - } \ - } \ - break; \ - default: \ - _mesa_problem(ctx, "bad logicop mode");\ - } \ -} while (0) - - - -static inline void -logicop_uint1(struct gl_context *ctx, GLuint n, GLuint src[], const GLuint dest[], - const GLubyte mask[]) -{ - LOGIC_OP_LOOP(ctx->Color.LogicOp, 1); -} - - -static inline void -logicop_uint2(struct gl_context *ctx, GLuint n, GLuint src[], const GLuint dest[], - const GLubyte mask[]) -{ - LOGIC_OP_LOOP(ctx->Color.LogicOp, 2); -} - - -static inline void -logicop_uint4(struct gl_context *ctx, GLuint n, GLuint src[], const GLuint dest[], - const GLubyte mask[]) -{ - LOGIC_OP_LOOP(ctx->Color.LogicOp, 4); -} - - - -/** - * Apply the current logic operator to a span of RGBA pixels. - * We can handle horizontal runs of pixels (spans) or arrays of x/y - * pixel coordinates. - */ -void -_swrast_logicop_rgba_span(struct gl_context *ctx, struct gl_renderbuffer *rb, - SWspan *span) -{ - void *rbPixels; - - assert(span->end < SWRAST_MAX_WIDTH); - assert(span->arrayMask & SPAN_RGBA); - - rbPixels = _swrast_get_dest_rgba(ctx, rb, span); - - if (span->array->ChanType == GL_UNSIGNED_BYTE) { - /* treat 4*GLubyte as GLuint */ - logicop_uint1(ctx, span->end, - (GLuint *) span->array->rgba8, - (const GLuint *) rbPixels, span->array->mask); - } - else if (span->array->ChanType == GL_UNSIGNED_SHORT) { - /* treat 2*GLushort as GLuint */ - logicop_uint2(ctx, 2 * span->end, - (GLuint *) span->array->rgba16, - (const GLuint *) rbPixels, span->array->mask); - } - else { - logicop_uint4(ctx, 4 * span->end, - (GLuint *) span->array->attribs[VARYING_SLOT_COL0], - (const GLuint *) rbPixels, span->array->mask); - } -} diff --git a/src/mesa/swrast/s_logic.h b/src/mesa/swrast/s_logic.h deleted file mode 100644 index bcb4b74..0000000 --- a/src/mesa/swrast/s_logic.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -#ifndef S_LOGIC_H -#define S_LOGIC_H - - -#include "s_span.h" - -struct gl_context; -struct gl_renderbuffer; - -extern void -_swrast_logicop_rgba_span(struct gl_context *ctx, struct gl_renderbuffer *rb, - SWspan *span); - - -#endif diff --git a/src/mesa/swrast/s_masking.c b/src/mesa/swrast/s_masking.c deleted file mode 100644 index 8941375..0000000 --- a/src/mesa/swrast/s_masking.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -/* - * Implement the effect of glColorMask and glIndexMask in software. - */ - - -#include "main/glheader.h" -#include "main/macros.h" - -#include "s_context.h" -#include "s_masking.h" -#include "s_span.h" - - -/** - * Apply the color mask to a span of rgba values. - */ -void -_swrast_mask_rgba_span(struct gl_context *ctx, struct gl_renderbuffer *rb, - SWspan *span, GLuint buf) -{ - const GLuint n = span->end; - void *rbPixels; - - assert(n < SWRAST_MAX_WIDTH); - assert(span->arrayMask & SPAN_RGBA); - - rbPixels = _swrast_get_dest_rgba(ctx, rb, span); - - /* - * Do component masking. - * Note that we're not using span->array->mask[] here. We could... - */ - if (span->array->ChanType == GL_UNSIGNED_BYTE) { - const GLubyte colormask[4] = { - GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 0) ? 0xff : 0, - GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 1) ? 0xff : 0, - GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 2) ? 0xff : 0, - GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 3) ? 0xff : 0, - }; - GLuint srcMask; - memcpy(&srcMask, colormask, sizeof(srcMask)); - const GLuint dstMask = ~srcMask; - const GLuint *dst = (const GLuint *) rbPixels; - GLuint *src = (GLuint *) span->array->rgba8; - GLuint i; - for (i = 0; i < n; i++) { - src[i] = (src[i] & srcMask) | (dst[i] & dstMask); - } - } - else if (span->array->ChanType == GL_UNSIGNED_SHORT) { - /* 2-byte components */ - /* XXX try to use 64-bit arithmetic someday */ - const GLushort rMask = GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 0) ? 0xffff : 0x0; - const GLushort gMask = GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 1) ? 0xffff : 0x0; - const GLushort bMask = GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 2) ? 0xffff : 0x0; - const GLushort aMask = GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 3) ? 0xffff : 0x0; - const GLushort (*dst)[4] = (const GLushort (*)[4]) rbPixels; - GLushort (*src)[4] = span->array->rgba16; - GLuint i; - for (i = 0; i < n; i++) { - src[i][RCOMP] = (src[i][RCOMP] & rMask) | (dst[i][RCOMP] & ~rMask); - src[i][GCOMP] = (src[i][GCOMP] & gMask) | (dst[i][GCOMP] & ~gMask); - src[i][BCOMP] = (src[i][BCOMP] & bMask) | (dst[i][BCOMP] & ~bMask); - src[i][ACOMP] = (src[i][ACOMP] & aMask) | (dst[i][ACOMP] & ~aMask); - } - } - else { - /* 4-byte components */ - const GLuint rMask = GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 0) ? ~0x0 : 0x0; - const GLuint gMask = GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 1) ? ~0x0 : 0x0; - const GLuint bMask = GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 2) ? ~0x0 : 0x0; - const GLuint aMask = GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 3) ? ~0x0 : 0x0; - const GLuint (*dst)[4] = (const GLuint (*)[4]) rbPixels; - GLuint (*src)[4] = (GLuint (*)[4]) span->array->attribs[VARYING_SLOT_COL0]; - GLuint i; - for (i = 0; i < n; i++) { - src[i][RCOMP] = (src[i][RCOMP] & rMask) | (dst[i][RCOMP] & ~rMask); - src[i][GCOMP] = (src[i][GCOMP] & gMask) | (dst[i][GCOMP] & ~gMask); - src[i][BCOMP] = (src[i][BCOMP] & bMask) | (dst[i][BCOMP] & ~bMask); - src[i][ACOMP] = (src[i][ACOMP] & aMask) | (dst[i][ACOMP] & ~aMask); - } - } -} diff --git a/src/mesa/swrast/s_masking.h b/src/mesa/swrast/s_masking.h deleted file mode 100644 index 03d7ad9..0000000 --- a/src/mesa/swrast/s_masking.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -#ifndef S_MASKING_H -#define S_MASKING_H - - -#include "main/glheader.h" -#include "s_span.h" - -struct gl_context; -struct gl_renderbuffer; - - -extern void -_swrast_mask_rgba_span(struct gl_context *ctx, struct gl_renderbuffer *rb, - SWspan *span, GLuint buf); - -#endif diff --git a/src/mesa/swrast/s_points.c b/src/mesa/swrast/s_points.c deleted file mode 100644 index 04c85b3..0000000 --- a/src/mesa/swrast/s_points.c +++ /dev/null @@ -1,564 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -#include "main/framebuffer.h" -#include "main/glheader.h" -#include "main/macros.h" -#include "s_context.h" -#include "s_feedback.h" -#include "s_points.h" -#include "s_span.h" - - -/** - * Used to cull points with invalid coords - */ -#define CULL_INVALID(V) \ - do { \ - float tmp = (V)->attrib[VARYING_SLOT_POS][0] \ - + (V)->attrib[VARYING_SLOT_POS][1]; \ - if (util_is_inf_or_nan(tmp)) \ - return; \ - } while(0) - - - -/** - * Get/compute the point size. - * The size may come from a vertex shader, or computed with attentuation - * or just the glPointSize value. - * Must also clamp to user-defined range and implmentation limits. - */ -static inline GLfloat -get_size(const struct gl_context *ctx, const SWvertex *vert, GLboolean smoothed) -{ - GLfloat size; - - if (ctx->Point._Attenuated || ctx->VertexProgram.PointSizeEnabled) { - /* use vertex's point size */ - size = vert->pointSize; - } - else { - /* use constant point size */ - size = ctx->Point.Size; - } - /* always clamp to user-specified limits */ - size = CLAMP(size, ctx->Point.MinSize, ctx->Point.MaxSize); - /* clamp to implementation limits */ - if (smoothed) - size = CLAMP(size, ctx->Const.MinPointSizeAA, ctx->Const.MaxPointSizeAA); - else - size = CLAMP(size, ctx->Const.MinPointSize, ctx->Const.MaxPointSize); - - return size; -} - - -/** - * Draw a point sprite - */ -static void -sprite_point(struct gl_context *ctx, const SWvertex *vert) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - SWspan span; - GLfloat size; - GLuint tCoords[MAX_TEXTURE_COORD_UNITS + 1]; - GLuint numTcoords = 0; - GLfloat t0, dtdy; - - CULL_INVALID(vert); - - /* z coord */ - if (ctx->DrawBuffer->Visual.depthBits <= 16) - span.z = FloatToFixed(vert->attrib[VARYING_SLOT_POS][2] + 0.5F); - else - span.z = (GLuint) (vert->attrib[VARYING_SLOT_POS][2] + 0.5F); - span.zStep = 0; - - size = get_size(ctx, vert, GL_FALSE); - - /* span init */ - INIT_SPAN(span, GL_POINT); - span.interpMask = SPAN_Z | SPAN_RGBA; - - span.facing = swrast->PointLineFacing; - - span.red = ChanToFixed(vert->color[0]); - span.green = ChanToFixed(vert->color[1]); - span.blue = ChanToFixed(vert->color[2]); - span.alpha = ChanToFixed(vert->color[3]); - span.redStep = 0; - span.greenStep = 0; - span.blueStep = 0; - span.alphaStep = 0; - - /* need these for fragment programs */ - span.attrStart[VARYING_SLOT_POS][3] = 1.0F; - span.attrStepX[VARYING_SLOT_POS][3] = 0.0F; - span.attrStepY[VARYING_SLOT_POS][3] = 0.0F; - - { - GLfloat s, dsdx; - - /* texcoord / pointcoord interpolants */ - s = 0.0F; - dsdx = 1.0F / size; - if (ctx->Point.SpriteOrigin == GL_LOWER_LEFT) { - dtdy = 1.0F / size; - t0 = 0.5F * dtdy; - } - else { - /* GL_UPPER_LEFT */ - dtdy = -1.0F / size; - t0 = 1.0F + 0.5F * dtdy; - } - - ATTRIB_LOOP_BEGIN - if (attr >= VARYING_SLOT_TEX0 && attr <= VARYING_SLOT_TEX7) { - /* a texcoord attribute */ - const GLuint u = attr - VARYING_SLOT_TEX0; - assert(u < MAX_TEXTURE_COORD_UNITS); - if (ctx->Point.CoordReplace & (1u << u)) { - tCoords[numTcoords++] = attr; - - span.attrStart[attr][0] = s; - span.attrStart[attr][1] = 0.0; /* overwritten below */ - span.attrStart[attr][2] = 0.0; - span.attrStart[attr][3] = 1.0; - - span.attrStepX[attr][0] = dsdx; - span.attrStepX[attr][1] = 0.0; - span.attrStepX[attr][2] = 0.0; - span.attrStepX[attr][3] = 0.0; - - span.attrStepY[attr][0] = 0.0; - span.attrStepY[attr][1] = dtdy; - span.attrStepY[attr][2] = 0.0; - span.attrStepY[attr][3] = 0.0; - - continue; - } - } - else if (attr == VARYING_SLOT_PNTC) { - /* GLSL gl_PointCoord.xy (.zw undefined) */ - span.attrStart[VARYING_SLOT_PNTC][0] = 0.0; - span.attrStart[VARYING_SLOT_PNTC][1] = 0.0; /* t0 set below */ - span.attrStepX[VARYING_SLOT_PNTC][0] = dsdx; - span.attrStepX[VARYING_SLOT_PNTC][1] = 0.0; - span.attrStepY[VARYING_SLOT_PNTC][0] = 0.0; - span.attrStepY[VARYING_SLOT_PNTC][1] = dtdy; - tCoords[numTcoords++] = VARYING_SLOT_PNTC; - continue; - } - /* use vertex's texcoord/attrib */ - COPY_4V(span.attrStart[attr], vert->attrib[attr]); - ASSIGN_4V(span.attrStepX[attr], 0, 0, 0, 0); - ASSIGN_4V(span.attrStepY[attr], 0, 0, 0, 0); - ATTRIB_LOOP_END; - } - - /* compute pos, bounds and render */ - { - const GLfloat x = vert->attrib[VARYING_SLOT_POS][0]; - const GLfloat y = vert->attrib[VARYING_SLOT_POS][1]; - GLint iSize = (GLint) (size + 0.5F); - GLint xmin, xmax, ymin, ymax, iy; - GLint iRadius; - GLfloat tcoord = t0; - - iSize = MAX2(1, iSize); - iRadius = iSize / 2; - - if (iSize & 1) { - /* odd size */ - xmin = (GLint) (x - iRadius); - xmax = (GLint) (x + iRadius); - ymin = (GLint) (y - iRadius); - ymax = (GLint) (y + iRadius); - } - else { - /* even size */ - /* 0.501 factor allows conformance to pass */ - xmin = (GLint) (x + 0.501F) - iRadius; - xmax = xmin + iSize - 1; - ymin = (GLint) (y + 0.501F) - iRadius; - ymax = ymin + iSize - 1; - } - - /* render spans */ - for (iy = ymin; iy <= ymax; iy++) { - GLuint i; - /* setup texcoord T for this row */ - for (i = 0; i < numTcoords; i++) { - span.attrStart[tCoords[i]][1] = tcoord; - } - - /* these might get changed by span clipping */ - span.x = xmin; - span.y = iy; - span.end = xmax - xmin + 1; - - _swrast_write_rgba_span(ctx, &span); - - tcoord += dtdy; - } - } -} - - -/** - * Draw smooth/antialiased point. RGB or CI mode. - */ -static void -smooth_point(struct gl_context *ctx, const SWvertex *vert) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - SWspan span; - GLfloat size, alphaAtten; - - CULL_INVALID(vert); - - /* z coord */ - if (ctx->DrawBuffer->Visual.depthBits <= 16) - span.z = FloatToFixed(vert->attrib[VARYING_SLOT_POS][2] + 0.5F); - else - span.z = (GLuint) (vert->attrib[VARYING_SLOT_POS][2] + 0.5F); - span.zStep = 0; - - size = get_size(ctx, vert, GL_TRUE); - - /* alpha attenuation / fade factor */ - if (_mesa_is_multisample_enabled(ctx)) { - if (vert->pointSize >= ctx->Point.Threshold) { - alphaAtten = 1.0F; - } - else { - GLfloat dsize = vert->pointSize / ctx->Point.Threshold; - alphaAtten = dsize * dsize; - } - } - else { - alphaAtten = 1.0; - } - (void) alphaAtten; /* not used */ - - /* span init */ - INIT_SPAN(span, GL_POINT); - span.interpMask = SPAN_Z | SPAN_RGBA; - span.arrayMask = SPAN_COVERAGE | SPAN_MASK; - - span.facing = swrast->PointLineFacing; - - span.red = ChanToFixed(vert->color[0]); - span.green = ChanToFixed(vert->color[1]); - span.blue = ChanToFixed(vert->color[2]); - span.alpha = ChanToFixed(vert->color[3]); - span.redStep = 0; - span.greenStep = 0; - span.blueStep = 0; - span.alphaStep = 0; - - /* need these for fragment programs */ - span.attrStart[VARYING_SLOT_POS][3] = 1.0F; - span.attrStepX[VARYING_SLOT_POS][3] = 0.0F; - span.attrStepY[VARYING_SLOT_POS][3] = 0.0F; - - ATTRIB_LOOP_BEGIN - COPY_4V(span.attrStart[attr], vert->attrib[attr]); - ASSIGN_4V(span.attrStepX[attr], 0, 0, 0, 0); - ASSIGN_4V(span.attrStepY[attr], 0, 0, 0, 0); - ATTRIB_LOOP_END - - /* compute pos, bounds and render */ - { - const GLfloat x = vert->attrib[VARYING_SLOT_POS][0]; - const GLfloat y = vert->attrib[VARYING_SLOT_POS][1]; - const GLfloat radius = 0.5F * size; - const GLfloat rmin = radius - 0.7071F; /* 0.7071 = sqrt(2)/2 */ - const GLfloat rmax = radius + 0.7071F; - const GLfloat rmin2 = MAX2(0.0F, rmin * rmin); - const GLfloat rmax2 = rmax * rmax; - const GLfloat cscale = 1.0F / (rmax2 - rmin2); - const GLint xmin = (GLint) (x - radius); - const GLint xmax = (GLint) (x + radius); - const GLint ymin = (GLint) (y - radius); - const GLint ymax = (GLint) (y + radius); - GLint ix, iy; - - for (iy = ymin; iy <= ymax; iy++) { - - /* these might get changed by span clipping */ - span.x = xmin; - span.y = iy; - span.end = xmax - xmin + 1; - - /* compute coverage for each pixel in span */ - for (ix = xmin; ix <= xmax; ix++) { - const GLfloat dx = ix - x + 0.5F; - const GLfloat dy = iy - y + 0.5F; - const GLfloat dist2 = dx * dx + dy * dy; - GLfloat coverage; - - if (dist2 < rmax2) { - if (dist2 >= rmin2) { - /* compute partial coverage */ - coverage = 1.0F - (dist2 - rmin2) * cscale; - } - else { - /* full coverage */ - coverage = 1.0F; - } - span.array->mask[ix - xmin] = 1; - } - else { - /* zero coverage - fragment outside the radius */ - coverage = 0.0; - span.array->mask[ix - xmin] = 0; - } - span.array->coverage[ix - xmin] = coverage; - } - - /* render span */ - _swrast_write_rgba_span(ctx, &span); - - } - } -} - - -/** - * Draw large (size >= 1) non-AA point. RGB or CI mode. - */ -static void -large_point(struct gl_context *ctx, const SWvertex *vert) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - SWspan span; - GLfloat size; - - CULL_INVALID(vert); - - /* z coord */ - if (ctx->DrawBuffer->Visual.depthBits <= 16) - span.z = FloatToFixed(vert->attrib[VARYING_SLOT_POS][2] + 0.5F); - else - span.z = (GLuint) (vert->attrib[VARYING_SLOT_POS][2] + 0.5F); - span.zStep = 0; - - size = get_size(ctx, vert, GL_FALSE); - - /* span init */ - INIT_SPAN(span, GL_POINT); - span.arrayMask = SPAN_XY; - span.facing = swrast->PointLineFacing; - - span.interpMask = SPAN_Z | SPAN_RGBA; - span.red = ChanToFixed(vert->color[0]); - span.green = ChanToFixed(vert->color[1]); - span.blue = ChanToFixed(vert->color[2]); - span.alpha = ChanToFixed(vert->color[3]); - span.redStep = 0; - span.greenStep = 0; - span.blueStep = 0; - span.alphaStep = 0; - - /* need these for fragment programs */ - span.attrStart[VARYING_SLOT_POS][3] = 1.0F; - span.attrStepX[VARYING_SLOT_POS][3] = 0.0F; - span.attrStepY[VARYING_SLOT_POS][3] = 0.0F; - - ATTRIB_LOOP_BEGIN - COPY_4V(span.attrStart[attr], vert->attrib[attr]); - ASSIGN_4V(span.attrStepX[attr], 0, 0, 0, 0); - ASSIGN_4V(span.attrStepY[attr], 0, 0, 0, 0); - ATTRIB_LOOP_END - - /* compute pos, bounds and render */ - { - const GLfloat x = vert->attrib[VARYING_SLOT_POS][0]; - const GLfloat y = vert->attrib[VARYING_SLOT_POS][1]; - GLint iSize = (GLint) (size + 0.5F); - GLint xmin, xmax, ymin, ymax, ix, iy; - GLint iRadius; - - iSize = MAX2(1, iSize); - iRadius = iSize / 2; - - if (iSize & 1) { - /* odd size */ - xmin = (GLint) (x - iRadius); - xmax = (GLint) (x + iRadius); - ymin = (GLint) (y - iRadius); - ymax = (GLint) (y + iRadius); - } - else { - /* even size */ - /* 0.501 factor allows conformance to pass */ - xmin = (GLint) (x + 0.501F) - iRadius; - xmax = xmin + iSize - 1; - ymin = (GLint) (y + 0.501F) - iRadius; - ymax = ymin + iSize - 1; - } - - /* generate fragments */ - span.end = 0; - for (iy = ymin; iy <= ymax; iy++) { - for (ix = xmin; ix <= xmax; ix++) { - span.array->x[span.end] = ix; - span.array->y[span.end] = iy; - span.end++; - } - } - assert(span.end <= SWRAST_MAX_WIDTH); - _swrast_write_rgba_span(ctx, &span); - } -} - - -/** - * Draw size=1, single-pixel point - */ -static void -pixel_point(struct gl_context *ctx, const SWvertex *vert) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - /* - * Note that unlike the other functions, we put single-pixel points - * into a special span array in order to render as many points as - * possible with a single _swrast_write_rgba_span() call. - */ - SWspan *span = &(swrast->PointSpan); - GLuint count; - - CULL_INVALID(vert); - - /* Span init */ - span->interpMask = 0; - span->arrayMask = SPAN_XY | SPAN_Z; - span->arrayMask |= SPAN_RGBA; - /*span->arrayMask |= SPAN_LAMBDA;*/ - span->arrayAttribs = swrast->_ActiveAttribMask; /* we'll produce these vals */ - - /* need these for fragment programs */ - span->attrStart[VARYING_SLOT_POS][3] = 1.0F; - span->attrStepX[VARYING_SLOT_POS][3] = 0.0F; - span->attrStepY[VARYING_SLOT_POS][3] = 0.0F; - - /* check if we need to flush */ - if (span->end >= SWRAST_MAX_WIDTH || - (swrast->_RasterMask & (BLEND_BIT | LOGIC_OP_BIT | MASKING_BIT)) || - span->facing != swrast->PointLineFacing) { - if (span->end > 0) { - _swrast_write_rgba_span(ctx, span); - span->end = 0; - } - } - - count = span->end; - - span->facing = swrast->PointLineFacing; - - /* fragment attributes */ - span->array->rgba[count][RCOMP] = vert->color[0]; - span->array->rgba[count][GCOMP] = vert->color[1]; - span->array->rgba[count][BCOMP] = vert->color[2]; - span->array->rgba[count][ACOMP] = vert->color[3]; - - ATTRIB_LOOP_BEGIN - COPY_4V(span->array->attribs[attr][count], vert->attrib[attr]); - ATTRIB_LOOP_END - - /* fragment position */ - span->array->x[count] = (GLint) vert->attrib[VARYING_SLOT_POS][0]; - span->array->y[count] = (GLint) vert->attrib[VARYING_SLOT_POS][1]; - span->array->z[count] = (GLint) (vert->attrib[VARYING_SLOT_POS][2] + 0.5F); - - span->end = count + 1; - assert(span->end <= SWRAST_MAX_WIDTH); -} - - -/** - * Add specular color to primary color, draw point, restore original - * primary color. - */ -void -_swrast_add_spec_terms_point(struct gl_context *ctx, const SWvertex *v0) -{ - SWvertex *ncv0 = (SWvertex *) v0; /* cast away const */ - GLfloat rSum, gSum, bSum; - GLchan cSave[4]; - - /* save */ - COPY_CHAN4(cSave, ncv0->color); - /* sum */ - rSum = CHAN_TO_FLOAT(ncv0->color[0]) + ncv0->attrib[VARYING_SLOT_COL1][0]; - gSum = CHAN_TO_FLOAT(ncv0->color[1]) + ncv0->attrib[VARYING_SLOT_COL1][1]; - bSum = CHAN_TO_FLOAT(ncv0->color[2]) + ncv0->attrib[VARYING_SLOT_COL1][2]; - UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[0], rSum); - UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[1], gSum); - UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[2], bSum); - /* draw */ - SWRAST_CONTEXT(ctx)->SpecPoint(ctx, ncv0); - /* restore */ - COPY_CHAN4(ncv0->color, cSave); -} - - -/** - * Examine current state to determine which point drawing function to use. - */ -void -_swrast_choose_point(struct gl_context *ctx) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - const GLfloat size = CLAMP(ctx->Point.Size, - ctx->Point.MinSize, - ctx->Point.MaxSize); - - if (ctx->RenderMode == GL_RENDER) { - if (ctx->Point.PointSprite) { - swrast->Point = sprite_point; - } - else if (ctx->Point.SmoothFlag) { - swrast->Point = smooth_point; - } - else if (size > 1.0F || - ctx->Point._Attenuated || - ctx->VertexProgram.PointSizeEnabled) { - swrast->Point = large_point; - } - else { - swrast->Point = pixel_point; - } - } - else if (ctx->RenderMode == GL_FEEDBACK) { - swrast->Point = _swrast_feedback_point; - } - else { - /* GL_SELECT mode */ - swrast->Point = _swrast_select_point; - } -} diff --git a/src/mesa/swrast/s_points.h b/src/mesa/swrast/s_points.h deleted file mode 100644 index 2205257..0000000 --- a/src/mesa/swrast/s_points.h +++ /dev/null @@ -1,39 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -#ifndef S_POINTS_H -#define S_POINTS_H - -#include "swrast.h" - -extern void -_swrast_choose_point( struct gl_context *ctx ); - -extern void -_swrast_add_spec_terms_point( struct gl_context *ctx, - const SWvertex *v0 ); - -#endif diff --git a/src/mesa/swrast/s_renderbuffer.c b/src/mesa/swrast/s_renderbuffer.c deleted file mode 100644 index 22122c2..0000000 --- a/src/mesa/swrast/s_renderbuffer.c +++ /dev/null @@ -1,642 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -/** - * Functions for allocating/managing software-based renderbuffers. - * Also, routines for reading/writing software-based renderbuffer data as - * ubytes, ushorts, uints, etc. - */ - - -#include "main/glheader.h" - -#include "main/context.h" -#include "main/fbobject.h" -#include "main/formats.h" -#include "main/mtypes.h" -#include "main/renderbuffer.h" -#include "util/u_memory.h" -#include "swrast/s_context.h" -#include "swrast/s_renderbuffer.h" - - -/** - * This is a software fallback for the gl_renderbuffer->AllocStorage - * function. - * Device drivers will typically override this function for the buffers - * which it manages (typically color buffers, Z and stencil). - * Other buffers (like software accumulation and aux buffers) which the driver - * doesn't manage can be handled with this function. - * - * This one multi-purpose function can allocate stencil, depth, accum, color - * or color-index buffers! - */ -static GLboolean -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: - case GL_RGB4: - case GL_RGB5: - case GL_RGB8: - case GL_RGB10: - case GL_RGB12: - case GL_RGB16: - rb->Format = MESA_FORMAT_BGR_UNORM8; - break; - case GL_RGBA: - case GL_RGBA2: - case GL_RGBA4: - case GL_RGB5_A1: - case GL_RGBA8: - case GL_RGB10_A2: - case GL_RGBA12: -#if UTIL_ARCH_LITTLE_ENDIAN - rb->Format = MESA_FORMAT_R8G8B8A8_UNORM; -#else - rb->Format = MESA_FORMAT_A8B8G8R8_UNORM; -#endif - break; - case GL_RGBA16: - case GL_RGBA16_SNORM: - /* for accum buffer */ - 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_S_UINT8; - break; - case GL_DEPTH_COMPONENT: - case GL_DEPTH_COMPONENT16: - rb->Format = MESA_FORMAT_Z_UNORM16; - break; - case GL_DEPTH_COMPONENT24: - rb->Format = MESA_FORMAT_Z24_UNORM_X8_UINT; - break; - case GL_DEPTH_COMPONENT32: - rb->Format = MESA_FORMAT_Z_UNORM32; - break; - case GL_DEPTH_STENCIL_EXT: - case GL_DEPTH24_STENCIL8_EXT: - 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 */ - free(srb->Buffer); - srb->Buffer = NULL; - - srb->RowStride = width * bpp; - - if (width > 0 && height > 0) { - /* allocate new buffer storage */ - srb->Buffer = malloc(srb->RowStride * height); - - 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, bpp); - return GL_FALSE; - } - } - - rb->Width = width; - rb->Height = height; - rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat); - - if (rb->Name == 0 && - internalFormat == GL_RGBA16_SNORM && - rb->_BaseFormat == 0) { - /* NOTE: This is a special case just for accumulation buffers. - * This is a very limited use case- there's no snorm texturing or - * rendering going on. - */ - rb->_BaseFormat = GL_RGBA; - } - else { - /* the internalFormat should have been error checked long ago */ - 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, - GLuint x, GLuint y, GLuint w, GLuint h, - GLbitfield mode, - GLubyte **out_map, - GLint *out_stride, - bool flip_y) -{ - struct swrast_renderbuffer *srb = swrast_renderbuffer(rb); - GLubyte *map = srb->Buffer; - int cpp = _mesa_get_format_bytes(rb->Format); - int stride = rb->Width * cpp; - - if (!map) { - *out_map = NULL; - *out_stride = 0; - } - - map += y * stride; - map += x * cpp; - - *out_map = map; - *out_stride = stride; -} - - -void -_swrast_unmap_soft_renderbuffer(struct gl_context *ctx, - struct gl_renderbuffer *rb) -{ -} - - - -/** - * Allocate a software-based renderbuffer. This is called via the - * ctx->Driver.NewRenderbuffer() function when the user creates a new - * renderbuffer. - * This would not be used for hardware-based renderbuffers. - */ -struct gl_renderbuffer * -_swrast_new_soft_renderbuffer(struct gl_context *ctx, GLuint name) -{ - 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 &srb->Base; -} - - -/** - * Add software-based color renderbuffers to the given framebuffer. - * This is a helper routine for device drivers when creating a - * window system framebuffer (not a user-created render/framebuffer). - * Once this function is called, you can basically forget about this - * renderbuffer; core Mesa will handle all the buffer management and - * rendering! - */ -static GLboolean -add_color_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb, - GLuint rgbBits, GLuint alphaBits, - GLboolean frontLeft, GLboolean backLeft, - GLboolean frontRight, GLboolean backRight) -{ - gl_buffer_index b; - - if (rgbBits > 16 || alphaBits > 16) { - _mesa_problem(ctx, - "Unsupported bit depth in add_color_renderbuffers"); - return GL_FALSE; - } - - assert(MAX_COLOR_ATTACHMENTS >= 4); - - for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) { - struct gl_renderbuffer *rb; - - if (b == BUFFER_FRONT_LEFT && !frontLeft) - continue; - else if (b == BUFFER_BACK_LEFT && !backLeft) - continue; - else if (b == BUFFER_FRONT_RIGHT && !frontRight) - continue; - else if (b == BUFFER_BACK_RIGHT && !backRight) - continue; - - assert(fb->Attachment[b].Renderbuffer == NULL); - - rb = ctx->Driver.NewRenderbuffer(ctx, 0); - if (!rb) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating color buffer"); - return GL_FALSE; - } - - rb->InternalFormat = GL_RGBA; - - rb->AllocStorage = soft_renderbuffer_storage; - _mesa_attach_and_own_rb(fb, b, rb); - } - - return GL_TRUE; -} - - -/** - * Add a software-based depth renderbuffer to the given framebuffer. - * This is a helper routine for device drivers when creating a - * window system framebuffer (not a user-created render/framebuffer). - * Once this function is called, you can basically forget about this - * renderbuffer; core Mesa will handle all the buffer management and - * rendering! - */ -static GLboolean -add_depth_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb, - GLuint depthBits) -{ - struct gl_renderbuffer *rb; - - if (depthBits > 32) { - _mesa_problem(ctx, - "Unsupported depthBits in add_depth_renderbuffer"); - return GL_FALSE; - } - - assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer == NULL); - - rb = _swrast_new_soft_renderbuffer(ctx, 0); - if (!rb) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating depth buffer"); - return GL_FALSE; - } - - if (depthBits <= 16) { - rb->InternalFormat = GL_DEPTH_COMPONENT16; - } - else if (depthBits <= 24) { - rb->InternalFormat = GL_DEPTH_COMPONENT24; - } - else { - rb->InternalFormat = GL_DEPTH_COMPONENT32; - } - - rb->AllocStorage = soft_renderbuffer_storage; - _mesa_attach_and_own_rb(fb, BUFFER_DEPTH, rb); - - return GL_TRUE; -} - - -/** - * Add a software-based stencil renderbuffer to the given framebuffer. - * This is a helper routine for device drivers when creating a - * window system framebuffer (not a user-created render/framebuffer). - * Once this function is called, you can basically forget about this - * renderbuffer; core Mesa will handle all the buffer management and - * rendering! - */ -static GLboolean -add_stencil_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb, - GLuint stencilBits) -{ - struct gl_renderbuffer *rb; - - if (stencilBits > 16) { - _mesa_problem(ctx, - "Unsupported stencilBits in add_stencil_renderbuffer"); - return GL_FALSE; - } - - assert(fb->Attachment[BUFFER_STENCIL].Renderbuffer == NULL); - - rb = _swrast_new_soft_renderbuffer(ctx, 0); - if (!rb) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating stencil buffer"); - return GL_FALSE; - } - - assert(stencilBits <= 8); - rb->InternalFormat = GL_STENCIL_INDEX8; - - rb->AllocStorage = soft_renderbuffer_storage; - _mesa_attach_and_own_rb(fb, BUFFER_STENCIL, rb); - - return GL_TRUE; -} - - -static GLboolean -add_depth_stencil_renderbuffer(struct gl_context *ctx, - struct gl_framebuffer *fb) -{ - struct gl_renderbuffer *rb; - - assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer == NULL); - assert(fb->Attachment[BUFFER_STENCIL].Renderbuffer == NULL); - - rb = _swrast_new_soft_renderbuffer(ctx, 0); - if (!rb) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating depth+stencil buffer"); - return GL_FALSE; - } - - rb->InternalFormat = GL_DEPTH_STENCIL; - - rb->AllocStorage = soft_renderbuffer_storage; - _mesa_attach_and_own_rb(fb, BUFFER_DEPTH, rb); - _mesa_attach_and_reference_rb(fb, BUFFER_STENCIL, rb); - - return GL_TRUE; -} - - -/** - * Add a software-based accumulation renderbuffer to the given framebuffer. - * This is a helper routine for device drivers when creating a - * window system framebuffer (not a user-created render/framebuffer). - * Once this function is called, you can basically forget about this - * renderbuffer; core Mesa will handle all the buffer management and - * rendering! - */ -static GLboolean -add_accum_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb, - GLuint redBits, GLuint greenBits, - GLuint blueBits, GLuint alphaBits) -{ - struct gl_renderbuffer *rb; - - if (redBits > 16 || greenBits > 16 || blueBits > 16 || alphaBits > 16) { - _mesa_problem(ctx, - "Unsupported accumBits in add_accum_renderbuffer"); - return GL_FALSE; - } - - assert(fb->Attachment[BUFFER_ACCUM].Renderbuffer == NULL); - - rb = _swrast_new_soft_renderbuffer(ctx, 0); - if (!rb) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating accum buffer"); - return GL_FALSE; - } - - rb->InternalFormat = GL_RGBA16_SNORM; - rb->AllocStorage = soft_renderbuffer_storage; - _mesa_attach_and_own_rb(fb, BUFFER_ACCUM, rb); - - return GL_TRUE; -} - - - -/** - * Create/attach software-based renderbuffers to the given framebuffer. - * This is a helper routine for device drivers. Drivers can just as well - * call the individual _mesa_add_*_renderbuffer() routines directly. - */ -void -_swrast_add_soft_renderbuffers(struct gl_framebuffer *fb, - GLboolean color, - GLboolean depth, - GLboolean stencil, - GLboolean accum, - GLboolean alpha) -{ - GLboolean frontLeft = GL_TRUE; - GLboolean backLeft = fb->Visual.doubleBufferMode; - GLboolean frontRight = fb->Visual.stereoMode; - GLboolean backRight = fb->Visual.stereoMode && fb->Visual.doubleBufferMode; - - if (color) { - assert(fb->Visual.redBits == fb->Visual.greenBits); - assert(fb->Visual.redBits == fb->Visual.blueBits); - add_color_renderbuffers(NULL, fb, - fb->Visual.redBits, - fb->Visual.alphaBits, - frontLeft, backLeft, - frontRight, backRight); - } - -#if 0 - /* This is pretty much for debugging purposes only since there's a perf - * hit for using combined depth/stencil in swrast. - */ - if (depth && fb->Visual.depthBits == 24 && - stencil && fb->Visual.stencilBits == 8) { - /* use combined depth/stencil buffer */ - add_depth_stencil_renderbuffer(NULL, fb); - } - else -#else - (void) add_depth_stencil_renderbuffer; -#endif - { - if (depth) { - assert(fb->Visual.depthBits > 0); - add_depth_renderbuffer(NULL, fb, fb->Visual.depthBits); - } - - if (stencil) { - assert(fb->Visual.stencilBits > 0); - add_stencil_renderbuffer(NULL, fb, fb->Visual.stencilBits); - } - } - - if (accum) { - assert(fb->Visual.accumRedBits > 0); - assert(fb->Visual.accumGreenBits > 0); - assert(fb->Visual.accumBlueBits > 0); - add_accum_renderbuffer(NULL, fb, - fb->Visual.accumRedBits, - fb->Visual.accumGreenBits, - fb->Visual.accumBlueBits, - fb->Visual.accumAlphaBits); - } -} - - - -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, - fb->FlipY); - } - - 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] != BUFFER_NONE) { - 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] != BUFFER_NONE) { - unmap_attachment(ctx, fb, fb->_ColorDrawBufferIndexes[buf]); - } - } -} diff --git a/src/mesa/swrast/s_renderbuffer.h b/src/mesa/swrast/s_renderbuffer.h deleted file mode 100644 index e3b6b4d..0000000 --- a/src/mesa/swrast/s_renderbuffer.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -#ifndef S_RENDERBUFFER_H -#define S_RENDERBUFFER_H - -#include "main/glheader.h" - - -struct gl_context; -struct gl_framebuffer; -struct gl_renderbuffer; - - -extern struct gl_renderbuffer * -_swrast_new_soft_renderbuffer(struct gl_context *ctx, GLuint name); - -extern void -_swrast_map_soft_renderbuffer(struct gl_context *ctx, - struct gl_renderbuffer *rb, - GLuint x, GLuint y, GLuint w, GLuint h, - GLbitfield mode, - GLubyte **out_map, - GLint *out_stride, - bool flip_y); - -extern void -_swrast_unmap_soft_renderbuffer(struct gl_context *ctx, - struct gl_renderbuffer *rb); - -extern void -_swrast_set_renderbuffer_accessors(struct gl_renderbuffer *rb); - - -extern void -_swrast_add_soft_renderbuffers(struct gl_framebuffer *fb, - GLboolean color, - GLboolean depth, - GLboolean stencil, - GLboolean accum, - GLboolean alpha); - - -#endif /* S_RENDERBUFFER_H */ diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c deleted file mode 100644 index cba2ddc..0000000 --- a/src/mesa/swrast/s_span.c +++ /dev/null @@ -1,1595 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. - * Copyright (C) 2009 VMware, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -/** - * \file swrast/s_span.c - * \brief Span processing functions used by all rasterization functions. - * This is where all the per-fragment tests are performed - * \author Brian Paul - */ - -#include "c99_math.h" -#include "main/errors.h" -#include "main/glheader.h" -#include "main/format_pack.h" -#include "main/format_unpack.h" -#include "main/macros.h" - -#include "main/image.h" -#include "main/samplerobj.h" -#include "main/state.h" -#include "main/stencil.h" -#include "main/teximage.h" - -#include "s_atifragshader.h" -#include "s_alpha.h" -#include "s_blend.h" -#include "s_context.h" -#include "s_depth.h" -#include "s_fog.h" -#include "s_logic.h" -#include "s_masking.h" -#include "s_fragprog.h" -#include "s_span.h" -#include "s_stencil.h" -#include "s_texcombine.h" - -#include - -/** - * Set default fragment attributes for the span using the - * current raster values. Used prior to glDraw/CopyPixels - * and glBitmap. - */ -void -_swrast_span_default_attribs(struct gl_context *ctx, SWspan *span) -{ - GLchan r, g, b, a; - /* Z*/ - { - const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF; - if (ctx->DrawBuffer->Visual.depthBits <= 16) - span->z = FloatToFixed(ctx->Current.RasterPos[2] * depthMax + 0.5F); - else { - GLfloat tmpf = ctx->Current.RasterPos[2] * depthMax; - tmpf = MIN2(tmpf, depthMax); - span->z = (GLint)tmpf; - } - span->zStep = 0; - span->interpMask |= SPAN_Z; - } - - /* W (for perspective correction) */ - span->attrStart[VARYING_SLOT_POS][3] = 1.0; - span->attrStepX[VARYING_SLOT_POS][3] = 0.0; - span->attrStepY[VARYING_SLOT_POS][3] = 0.0; - - /* primary color, or color index */ - UNCLAMPED_FLOAT_TO_CHAN(r, ctx->Current.RasterColor[0]); - UNCLAMPED_FLOAT_TO_CHAN(g, ctx->Current.RasterColor[1]); - UNCLAMPED_FLOAT_TO_CHAN(b, ctx->Current.RasterColor[2]); - UNCLAMPED_FLOAT_TO_CHAN(a, ctx->Current.RasterColor[3]); -#if CHAN_TYPE == GL_FLOAT - span->red = r; - span->green = g; - span->blue = b; - span->alpha = a; -#else - span->red = IntToFixed(r); - span->green = IntToFixed(g); - span->blue = IntToFixed(b); - span->alpha = IntToFixed(a); -#endif - span->redStep = 0; - span->greenStep = 0; - span->blueStep = 0; - span->alphaStep = 0; - span->interpMask |= SPAN_RGBA; - - COPY_4V(span->attrStart[VARYING_SLOT_COL0], ctx->Current.RasterColor); - ASSIGN_4V(span->attrStepX[VARYING_SLOT_COL0], 0.0, 0.0, 0.0, 0.0); - ASSIGN_4V(span->attrStepY[VARYING_SLOT_COL0], 0.0, 0.0, 0.0, 0.0); - - /* Secondary color */ - if (ctx->Light.Enabled || ctx->Fog.ColorSumEnabled) - { - COPY_4V(span->attrStart[VARYING_SLOT_COL1], ctx->Current.RasterSecondaryColor); - ASSIGN_4V(span->attrStepX[VARYING_SLOT_COL1], 0.0, 0.0, 0.0, 0.0); - ASSIGN_4V(span->attrStepY[VARYING_SLOT_COL1], 0.0, 0.0, 0.0, 0.0); - } - - /* fog */ - { - const SWcontext *swrast = SWRAST_CONTEXT(ctx); - GLfloat fogVal; /* a coord or a blend factor */ - if (swrast->_PreferPixelFog) { - /* fog blend factors will be computed from fog coordinates per pixel */ - fogVal = ctx->Current.RasterDistance; - } - else { - /* fog blend factor should be computed from fogcoord now */ - fogVal = _swrast_z_to_fogfactor(ctx, ctx->Current.RasterDistance); - } - span->attrStart[VARYING_SLOT_FOGC][0] = fogVal; - span->attrStepX[VARYING_SLOT_FOGC][0] = 0.0; - span->attrStepY[VARYING_SLOT_FOGC][0] = 0.0; - } - - /* texcoords */ - { - GLuint i; - for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { - const GLuint attr = VARYING_SLOT_TEX0 + i; - const GLfloat *tc = ctx->Current.RasterTexCoords[i]; - if (_swrast_use_fragment_program(ctx) || - _mesa_ati_fragment_shader_enabled(ctx)) { - COPY_4V(span->attrStart[attr], tc); - } - else if (tc[3] > 0.0F) { - /* use (s/q, t/q, r/q, 1) */ - span->attrStart[attr][0] = tc[0] / tc[3]; - span->attrStart[attr][1] = tc[1] / tc[3]; - span->attrStart[attr][2] = tc[2] / tc[3]; - span->attrStart[attr][3] = 1.0; - } - else { - ASSIGN_4V(span->attrStart[attr], 0.0F, 0.0F, 0.0F, 1.0F); - } - ASSIGN_4V(span->attrStepX[attr], 0.0F, 0.0F, 0.0F, 0.0F); - ASSIGN_4V(span->attrStepY[attr], 0.0F, 0.0F, 0.0F, 0.0F); - } - } -} - - -/** - * Interpolate the active attributes (and'd with attrMask) to - * fill in span->array->attribs[]. - * Perspective correction will be done. The point/line/triangle function - * should have computed attrStart/Step values for VARYING_SLOT_POS[3]! - */ -static inline void -interpolate_active_attribs(struct gl_context *ctx, SWspan *span, - GLbitfield64 attrMask) -{ - const SWcontext *swrast = SWRAST_CONTEXT(ctx); - - /* - * Don't overwrite existing array values, such as colors that may have - * been produced by glDraw/CopyPixels. - */ - attrMask &= ~span->arrayAttribs; - - ATTRIB_LOOP_BEGIN - if (attrMask & BITFIELD64_BIT(attr)) { - const GLfloat dwdx = span->attrStepX[VARYING_SLOT_POS][3]; - GLfloat w = span->attrStart[VARYING_SLOT_POS][3]; - const GLfloat dv0dx = span->attrStepX[attr][0]; - const GLfloat dv1dx = span->attrStepX[attr][1]; - const GLfloat dv2dx = span->attrStepX[attr][2]; - const GLfloat dv3dx = span->attrStepX[attr][3]; - GLfloat v0 = span->attrStart[attr][0] + span->leftClip * dv0dx; - GLfloat v1 = span->attrStart[attr][1] + span->leftClip * dv1dx; - GLfloat v2 = span->attrStart[attr][2] + span->leftClip * dv2dx; - GLfloat v3 = span->attrStart[attr][3] + span->leftClip * dv3dx; - GLuint k; - for (k = 0; k < span->end; k++) { - const GLfloat invW = 1.0f / w; - span->array->attribs[attr][k][0] = v0 * invW; - span->array->attribs[attr][k][1] = v1 * invW; - span->array->attribs[attr][k][2] = v2 * invW; - span->array->attribs[attr][k][3] = v3 * invW; - v0 += dv0dx; - v1 += dv1dx; - v2 += dv2dx; - v3 += dv3dx; - w += dwdx; - } - assert((span->arrayAttribs & BITFIELD64_BIT(attr)) == 0); - span->arrayAttribs |= BITFIELD64_BIT(attr); - } - ATTRIB_LOOP_END -} - - -/** - * Interpolate primary colors to fill in the span->array->rgba8 (or rgb16) - * color array. - */ -static inline void -interpolate_int_colors(struct gl_context *ctx, SWspan *span) -{ -#if CHAN_BITS != 32 - const GLuint n = span->end; - GLuint i; - - assert(!(span->arrayMask & SPAN_RGBA)); -#endif - - switch (span->array->ChanType) { -#if CHAN_BITS != 32 - case GL_UNSIGNED_BYTE: - { - GLubyte (*rgba)[4] = span->array->rgba8; - if (span->interpMask & SPAN_FLAT) { - GLubyte color[4]; - color[RCOMP] = FixedToInt(span->red); - color[GCOMP] = FixedToInt(span->green); - color[BCOMP] = FixedToInt(span->blue); - color[ACOMP] = FixedToInt(span->alpha); - for (i = 0; i < n; i++) { - COPY_4UBV(rgba[i], color); - } - } - else { - GLfixed r = span->red; - GLfixed g = span->green; - GLfixed b = span->blue; - GLfixed a = span->alpha; - GLint dr = span->redStep; - GLint dg = span->greenStep; - GLint db = span->blueStep; - GLint da = span->alphaStep; - for (i = 0; i < n; i++) { - rgba[i][RCOMP] = FixedToChan(r); - rgba[i][GCOMP] = FixedToChan(g); - rgba[i][BCOMP] = FixedToChan(b); - rgba[i][ACOMP] = FixedToChan(a); - r += dr; - g += dg; - b += db; - a += da; - } - } - } - break; - case GL_UNSIGNED_SHORT: - { - GLushort (*rgba)[4] = span->array->rgba16; - if (span->interpMask & SPAN_FLAT) { - GLushort color[4]; - color[RCOMP] = FixedToInt(span->red); - color[GCOMP] = FixedToInt(span->green); - color[BCOMP] = FixedToInt(span->blue); - color[ACOMP] = FixedToInt(span->alpha); - for (i = 0; i < n; i++) { - COPY_4V(rgba[i], color); - } - } - else { - GLushort (*rgba)[4] = span->array->rgba16; - GLfixed r, g, b, a; - GLint dr, dg, db, da; - r = span->red; - g = span->green; - b = span->blue; - a = span->alpha; - dr = span->redStep; - dg = span->greenStep; - db = span->blueStep; - da = span->alphaStep; - for (i = 0; i < n; i++) { - rgba[i][RCOMP] = FixedToChan(r); - rgba[i][GCOMP] = FixedToChan(g); - rgba[i][BCOMP] = FixedToChan(b); - rgba[i][ACOMP] = FixedToChan(a); - r += dr; - g += dg; - b += db; - a += da; - } - } - } - break; -#endif - case GL_FLOAT: - interpolate_active_attribs(ctx, span, VARYING_BIT_COL0); - break; - default: - _mesa_problem(ctx, "bad datatype 0x%x in interpolate_int_colors", - span->array->ChanType); - } - span->arrayMask |= SPAN_RGBA; -} - - -/** - * Populate the VARYING_SLOT_COL0 array. - */ -static inline void -interpolate_float_colors(SWspan *span) -{ - GLfloat (*col0)[4] = span->array->attribs[VARYING_SLOT_COL0]; - const GLuint n = span->end; - GLuint i; - - assert(!(span->arrayAttribs & VARYING_BIT_COL0)); - - if (span->arrayMask & SPAN_RGBA) { - /* convert array of int colors */ - for (i = 0; i < n; i++) { - col0[i][0] = UBYTE_TO_FLOAT(span->array->rgba8[i][0]); - col0[i][1] = UBYTE_TO_FLOAT(span->array->rgba8[i][1]); - col0[i][2] = UBYTE_TO_FLOAT(span->array->rgba8[i][2]); - col0[i][3] = UBYTE_TO_FLOAT(span->array->rgba8[i][3]); - } - } - else { - /* interpolate red/green/blue/alpha to get float colors */ - assert(span->interpMask & SPAN_RGBA); - if (span->interpMask & SPAN_FLAT) { - GLfloat r = FixedToFloat(span->red); - GLfloat g = FixedToFloat(span->green); - GLfloat b = FixedToFloat(span->blue); - GLfloat a = FixedToFloat(span->alpha); - for (i = 0; i < n; i++) { - ASSIGN_4V(col0[i], r, g, b, a); - } - } - else { - GLfloat r = FixedToFloat(span->red); - GLfloat g = FixedToFloat(span->green); - GLfloat b = FixedToFloat(span->blue); - GLfloat a = FixedToFloat(span->alpha); - GLfloat dr = FixedToFloat(span->redStep); - GLfloat dg = FixedToFloat(span->greenStep); - GLfloat db = FixedToFloat(span->blueStep); - GLfloat da = FixedToFloat(span->alphaStep); - for (i = 0; i < n; i++) { - col0[i][0] = r; - col0[i][1] = g; - col0[i][2] = b; - col0[i][3] = a; - r += dr; - g += dg; - b += db; - a += da; - } - } - } - - span->arrayAttribs |= VARYING_BIT_COL0; - span->array->ChanType = GL_FLOAT; -} - - - -/** - * Fill in the span.zArray array from the span->z, zStep values. - */ -void -_swrast_span_interpolate_z( const struct gl_context *ctx, SWspan *span ) -{ - const GLuint n = span->end; - GLuint i; - - assert(!(span->arrayMask & SPAN_Z)); - - if (ctx->DrawBuffer->Visual.depthBits <= 16) { - GLfixed zval = span->z; - GLuint *z = span->array->z; - for (i = 0; i < n; i++) { - z[i] = FixedToInt(zval); - zval += span->zStep; - } - } - else { - /* Deep Z buffer, no fixed->int shift */ - GLuint zval = span->z; - GLuint *z = span->array->z; - for (i = 0; i < n; i++) { - z[i] = zval; - zval += span->zStep; - } - } - span->interpMask &= ~SPAN_Z; - span->arrayMask |= SPAN_Z; -} - - -/** - * Compute mipmap LOD from partial derivatives. - * This the ideal solution, as given in the OpenGL spec. - */ -GLfloat -_swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, - GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH, - GLfloat s, GLfloat t, GLfloat q, GLfloat invQ) -{ - GLfloat dudx = texW * ((s + dsdx) / (q + dqdx) - s * invQ); - GLfloat dvdx = texH * ((t + dtdx) / (q + dqdx) - t * invQ); - GLfloat dudy = texW * ((s + dsdy) / (q + dqdy) - s * invQ); - GLfloat dvdy = texH * ((t + dtdy) / (q + dqdy) - t * invQ); - GLfloat x = sqrtf(dudx * dudx + dvdx * dvdx); - GLfloat y = sqrtf(dudy * dudy + dvdy * dvdy); - GLfloat rho = MAX2(x, y); - GLfloat lambda = log2f(rho); - return lambda; -} - - -/** - * Compute mipmap LOD from partial derivatives. - * This is a faster approximation than above function. - */ -#if 0 -GLfloat -_swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, - GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH, - GLfloat s, GLfloat t, GLfloat q, GLfloat invQ) -{ - GLfloat dsdx2 = (s + dsdx) / (q + dqdx) - s * invQ; - GLfloat dtdx2 = (t + dtdx) / (q + dqdx) - t * invQ; - GLfloat dsdy2 = (s + dsdy) / (q + dqdy) - s * invQ; - GLfloat dtdy2 = (t + dtdy) / (q + dqdy) - t * invQ; - GLfloat maxU, maxV, rho, lambda; - dsdx2 = fabsf(dsdx2); - dsdy2 = fabsf(dsdy2); - dtdx2 = fabsf(dtdx2); - dtdy2 = fabsf(dtdy2); - maxU = MAX2(dsdx2, dsdy2) * texW; - maxV = MAX2(dtdx2, dtdy2) * texH; - rho = MAX2(maxU, maxV); - lambda = logf2(rho); - return lambda; -} -#endif - - -/** - * Fill in the span.array->attrib[VARYING_SLOT_TEXn] arrays from the - * using the attrStart/Step values. - * - * This function only used during fixed-function fragment processing. - * - * Note: in the places where we divide by Q (or mult by invQ) we're - * really doing two things: perspective correction and texcoord - * projection. Remember, for texcoord (s,t,r,q) we need to index - * texels with (s/q, t/q, r/q). - */ -static void -interpolate_texcoords(struct gl_context *ctx, SWspan *span) -{ - const GLuint maxUnit - = (ctx->Texture._EnabledCoordUnits > 1) ? ctx->Const.MaxTextureUnits : 1; - GLuint u; - - /* XXX CoordUnits vs. ImageUnits */ - for (u = 0; u < maxUnit; u++) { - if (ctx->Texture._EnabledCoordUnits & (1 << u)) { - const GLuint attr = VARYING_SLOT_TEX0 + u; - const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current; - GLfloat texW, texH; - GLboolean needLambda; - GLfloat (*texcoord)[4] = span->array->attribs[attr]; - GLfloat *lambda = span->array->lambda[u]; - const GLfloat dsdx = span->attrStepX[attr][0]; - const GLfloat dsdy = span->attrStepY[attr][0]; - const GLfloat dtdx = span->attrStepX[attr][1]; - const GLfloat dtdy = span->attrStepY[attr][1]; - const GLfloat drdx = span->attrStepX[attr][2]; - const GLfloat dqdx = span->attrStepX[attr][3]; - const GLfloat dqdy = span->attrStepY[attr][3]; - GLfloat s = span->attrStart[attr][0] + span->leftClip * dsdx; - GLfloat t = span->attrStart[attr][1] + span->leftClip * dtdx; - GLfloat r = span->attrStart[attr][2] + span->leftClip * drdx; - GLfloat q = span->attrStart[attr][3] + span->leftClip * dqdx; - - if (obj) { - const struct gl_texture_image *img = _mesa_base_tex_image(obj); - const struct swrast_texture_image *swImg = - swrast_texture_image_const(img); - const struct gl_sampler_object *samp = _mesa_get_samplerobj(ctx, u); - - needLambda = (samp->Attrib.MinFilter != samp->Attrib.MagFilter) - || _swrast_use_fragment_program(ctx); - /* LOD is calculated directly in the ansiotropic filter, we can - * skip the normal lambda function as the result is ignored. - */ - if (samp->Attrib.MaxAnisotropy > 1.0F && - samp->Attrib.MinFilter == GL_LINEAR_MIPMAP_LINEAR) { - needLambda = GL_FALSE; - } - texW = swImg->WidthScale; - texH = swImg->HeightScale; - } - else { - /* using a fragment program */ - texW = 1.0; - texH = 1.0; - needLambda = GL_FALSE; - } - - if (needLambda) { - GLuint i; - if (_swrast_use_fragment_program(ctx) - || _mesa_ati_fragment_shader_enabled(ctx)) { - /* do perspective correction but don't divide s, t, r by q */ - const GLfloat dwdx = span->attrStepX[VARYING_SLOT_POS][3]; - GLfloat w = span->attrStart[VARYING_SLOT_POS][3] + span->leftClip * dwdx; - for (i = 0; i < span->end; i++) { - const GLfloat invW = 1.0F / w; - texcoord[i][0] = s * invW; - texcoord[i][1] = t * invW; - texcoord[i][2] = r * invW; - texcoord[i][3] = q * invW; - lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, - dqdx, dqdy, texW, texH, - s, t, q, invW); - s += dsdx; - t += dtdx; - r += drdx; - q += dqdx; - w += dwdx; - } - } - else { - for (i = 0; i < span->end; i++) { - const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); - texcoord[i][0] = s * invQ; - texcoord[i][1] = t * invQ; - texcoord[i][2] = r * invQ; - texcoord[i][3] = q; - lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, - dqdx, dqdy, texW, texH, - s, t, q, invQ); - s += dsdx; - t += dtdx; - r += drdx; - q += dqdx; - } - } - span->arrayMask |= SPAN_LAMBDA; - } - else { - GLuint i; - if (_swrast_use_fragment_program(ctx) || - _mesa_ati_fragment_shader_enabled(ctx)) { - /* do perspective correction but don't divide s, t, r by q */ - const GLfloat dwdx = span->attrStepX[VARYING_SLOT_POS][3]; - GLfloat w = span->attrStart[VARYING_SLOT_POS][3] + span->leftClip * dwdx; - for (i = 0; i < span->end; i++) { - const GLfloat invW = 1.0F / w; - texcoord[i][0] = s * invW; - texcoord[i][1] = t * invW; - texcoord[i][2] = r * invW; - texcoord[i][3] = q * invW; - lambda[i] = 0.0; - s += dsdx; - t += dtdx; - r += drdx; - q += dqdx; - w += dwdx; - } - } - else if (dqdx == 0.0F) { - /* Ortho projection or polygon's parallel to window X axis */ - const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); - for (i = 0; i < span->end; i++) { - texcoord[i][0] = s * invQ; - texcoord[i][1] = t * invQ; - texcoord[i][2] = r * invQ; - texcoord[i][3] = q; - lambda[i] = 0.0; - s += dsdx; - t += dtdx; - r += drdx; - } - } - else { - for (i = 0; i < span->end; i++) { - const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); - texcoord[i][0] = s * invQ; - texcoord[i][1] = t * invQ; - texcoord[i][2] = r * invQ; - texcoord[i][3] = q; - lambda[i] = 0.0; - s += dsdx; - t += dtdx; - r += drdx; - q += dqdx; - } - } - } /* lambda */ - } /* if */ - } /* for */ -} - - -/** - * Fill in the arrays->attribs[VARYING_SLOT_POS] array. - */ -static inline void -interpolate_wpos(struct gl_context *ctx, SWspan *span) -{ - GLfloat (*wpos)[4] = span->array->attribs[VARYING_SLOT_POS]; - GLuint i; - const GLfloat zScale = 1.0F / ctx->DrawBuffer->_DepthMaxF; - GLfloat w, dw; - - if (span->arrayMask & SPAN_XY) { - for (i = 0; i < span->end; i++) { - wpos[i][0] = (GLfloat) span->array->x[i]; - wpos[i][1] = (GLfloat) span->array->y[i]; - } - } - else { - for (i = 0; i < span->end; i++) { - wpos[i][0] = (GLfloat) span->x + i; - wpos[i][1] = (GLfloat) span->y; - } - } - - dw = span->attrStepX[VARYING_SLOT_POS][3]; - w = span->attrStart[VARYING_SLOT_POS][3] + span->leftClip * dw; - for (i = 0; i < span->end; i++) { - wpos[i][2] = (GLfloat) span->array->z[i] * zScale; - wpos[i][3] = w; - w += dw; - } -} - - -/** - * Apply the current polygon stipple pattern to a span of pixels. - */ -static inline void -stipple_polygon_span(struct gl_context *ctx, SWspan *span) -{ - GLubyte *mask = span->array->mask; - - assert(ctx->Polygon.StippleFlag); - - if (span->arrayMask & SPAN_XY) { - /* arrays of x/y pixel coords */ - GLuint i; - for (i = 0; i < span->end; i++) { - const GLint col = span->array->x[i] % 32; - const GLint row = span->array->y[i] % 32; - const GLuint stipple = ctx->PolygonStipple[row]; - if (((1 << col) & stipple) == 0) { - mask[i] = 0; - } - } - } - else { - /* horizontal span of pixels */ - const GLuint highBit = 1 << 31; - const GLuint stipple = ctx->PolygonStipple[span->y % 32]; - GLuint i, m = highBit >> (GLuint) (span->x % 32); - for (i = 0; i < span->end; i++) { - if ((m & stipple) == 0) { - mask[i] = 0; - } - m = m >> 1; - if (m == 0) { - m = highBit; - } - } - } - span->writeAll = GL_FALSE; -} - - -/** - * Clip a pixel span to the current buffer/window boundaries: - * DrawBuffer->_Xmin, _Xmax, _Ymin, _Ymax. This will accomplish - * window clipping and scissoring. - * Return: GL_TRUE some pixels still visible - * GL_FALSE nothing visible - */ -static inline GLuint -clip_span( struct gl_context *ctx, SWspan *span ) -{ - const GLint xmin = ctx->DrawBuffer->_Xmin; - const GLint xmax = ctx->DrawBuffer->_Xmax; - const GLint ymin = ctx->DrawBuffer->_Ymin; - const GLint ymax = ctx->DrawBuffer->_Ymax; - - span->leftClip = 0; - - if (span->arrayMask & SPAN_XY) { - /* arrays of x/y pixel coords */ - const GLint *x = span->array->x; - const GLint *y = span->array->y; - const GLint n = span->end; - GLubyte *mask = span->array->mask; - GLint i; - GLuint passed = 0; - if (span->arrayMask & SPAN_MASK) { - /* note: using & intead of && to reduce branches */ - for (i = 0; i < n; i++) { - mask[i] &= (x[i] >= xmin) & (x[i] < xmax) - & (y[i] >= ymin) & (y[i] < ymax); - passed += mask[i]; - } - } - else { - /* note: using & intead of && to reduce branches */ - for (i = 0; i < n; i++) { - mask[i] = (x[i] >= xmin) & (x[i] < xmax) - & (y[i] >= ymin) & (y[i] < ymax); - passed += mask[i]; - } - } - return passed > 0; - } - else { - /* horizontal span of pixels */ - const GLint x = span->x; - const GLint y = span->y; - GLint n = span->end; - - /* Trivial rejection tests */ - if (y < ymin || y >= ymax || x + n <= xmin || x >= xmax) { - span->end = 0; - return GL_FALSE; /* all pixels clipped */ - } - - /* Clip to right */ - if (x + n > xmax) { - assert(x < xmax); - n = span->end = xmax - x; - } - - /* Clip to the left */ - if (x < xmin) { - const GLint leftClip = xmin - x; - GLuint i; - - assert(leftClip > 0); - assert(x + n > xmin); - - /* Clip 'leftClip' pixels from the left side. - * The span->leftClip field will be applied when we interpolate - * fragment attributes. - * For arrays of values, shift them left. - */ - for (i = 0; i < VARYING_SLOT_MAX; i++) { - if (span->interpMask & (1u << i)) { - GLuint j; - for (j = 0; j < 4; j++) { - span->attrStart[i][j] += leftClip * span->attrStepX[i][j]; - } - } - } - - span->red += leftClip * span->redStep; - span->green += leftClip * span->greenStep; - span->blue += leftClip * span->blueStep; - span->alpha += leftClip * span->alphaStep; - span->index += leftClip * span->indexStep; - span->z += leftClip * span->zStep; - span->intTex[0] += leftClip * span->intTexStep[0]; - span->intTex[1] += leftClip * span->intTexStep[1]; - -#define SHIFT_ARRAY(ARRAY, SHIFT, LEN) \ - memmove(ARRAY, ARRAY + (SHIFT), (LEN) * sizeof(ARRAY[0])) - - for (i = 0; i < VARYING_SLOT_MAX; i++) { - if (span->arrayAttribs & BITFIELD64_BIT(i)) { - /* shift array elements left by 'leftClip' */ - SHIFT_ARRAY(span->array->attribs[i], leftClip, n - leftClip); - } - } - - SHIFT_ARRAY(span->array->mask, leftClip, n - leftClip); - SHIFT_ARRAY(span->array->rgba8, leftClip, n - leftClip); - SHIFT_ARRAY(span->array->rgba16, leftClip, n - leftClip); - SHIFT_ARRAY(span->array->x, leftClip, n - leftClip); - SHIFT_ARRAY(span->array->y, leftClip, n - leftClip); - SHIFT_ARRAY(span->array->z, leftClip, n - leftClip); - SHIFT_ARRAY(span->array->index, leftClip, n - leftClip); - for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) { - SHIFT_ARRAY(span->array->lambda[i], leftClip, n - leftClip); - } - SHIFT_ARRAY(span->array->coverage, leftClip, n - leftClip); - -#undef SHIFT_ARRAY - - span->leftClip = leftClip; - span->x = xmin; - span->end -= leftClip; - span->writeAll = GL_FALSE; - } - - assert(span->x >= xmin); - assert(span->x + span->end <= xmax); - assert(span->y >= ymin); - assert(span->y < ymax); - - return GL_TRUE; /* some pixels visible */ - } -} - - -/** - * Add specular colors to primary colors. - * Only called during fixed-function operation. - * Result is float color array (VARYING_SLOT_COL0). - */ -static inline void -add_specular(struct gl_context *ctx, SWspan *span) -{ - const SWcontext *swrast = SWRAST_CONTEXT(ctx); - const GLubyte *mask = span->array->mask; - GLfloat (*col0)[4] = span->array->attribs[VARYING_SLOT_COL0]; - GLfloat (*col1)[4] = span->array->attribs[VARYING_SLOT_COL1]; - GLuint i; - - assert(!_swrast_use_fragment_program(ctx)); - assert(span->arrayMask & SPAN_RGBA); - assert(swrast->_ActiveAttribMask & VARYING_BIT_COL1); - (void) swrast; /* silence warning */ - - if (span->array->ChanType == GL_FLOAT) { - if ((span->arrayAttribs & VARYING_BIT_COL0) == 0) { - interpolate_active_attribs(ctx, span, VARYING_BIT_COL0); - } - } - else { - /* need float colors */ - if ((span->arrayAttribs & VARYING_BIT_COL0) == 0) { - interpolate_float_colors(span); - } - } - - if ((span->arrayAttribs & VARYING_BIT_COL1) == 0) { - /* XXX could avoid this and interpolate COL1 in the loop below */ - interpolate_active_attribs(ctx, span, VARYING_BIT_COL1); - } - - assert(span->arrayAttribs & VARYING_BIT_COL0); - assert(span->arrayAttribs & VARYING_BIT_COL1); - - for (i = 0; i < span->end; i++) { - if (mask[i]) { - col0[i][0] += col1[i][0]; - col0[i][1] += col1[i][1]; - col0[i][2] += col1[i][2]; - } - } - - span->array->ChanType = GL_FLOAT; -} - - -/** - * Apply antialiasing coverage value to alpha values. - */ -static inline void -apply_aa_coverage(SWspan *span) -{ - const GLfloat *coverage = span->array->coverage; - GLuint i; - if (span->array->ChanType == GL_UNSIGNED_BYTE) { - GLubyte (*rgba)[4] = span->array->rgba8; - for (i = 0; i < span->end; i++) { - const GLfloat a = rgba[i][ACOMP] * coverage[i]; - rgba[i][ACOMP] = (GLubyte) CLAMP(a, 0.0F, 255.0F); - assert(coverage[i] >= 0.0F); - assert(coverage[i] <= 1.0F); - } - } - else if (span->array->ChanType == GL_UNSIGNED_SHORT) { - GLushort (*rgba)[4] = span->array->rgba16; - for (i = 0; i < span->end; i++) { - const GLfloat a = rgba[i][ACOMP] * coverage[i]; - rgba[i][ACOMP] = (GLushort) CLAMP(a, 0.0F, 65535.0F); - } - } - else { - GLfloat (*rgba)[4] = span->array->attribs[VARYING_SLOT_COL0]; - for (i = 0; i < span->end; i++) { - rgba[i][ACOMP] = rgba[i][ACOMP] * coverage[i]; - /* clamp later */ - } - } -} - - -/** - * Clamp span's float colors to [0,1] - */ -static inline void -clamp_colors(SWspan *span) -{ - GLfloat (*rgba)[4] = span->array->attribs[VARYING_SLOT_COL0]; - GLuint i; - assert(span->array->ChanType == GL_FLOAT); - for (i = 0; i < span->end; i++) { - rgba[i][RCOMP] = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F); - rgba[i][GCOMP] = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F); - rgba[i][BCOMP] = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F); - rgba[i][ACOMP] = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F); - } -} - - -/** - * Convert the span's color arrays to the given type. - * The only way 'output' can be greater than zero is when we have a fragment - * program that writes to gl_FragData[1] or higher. - * \param output which fragment program color output is being processed - */ -static inline void -convert_color_type(SWspan *span, GLenum srcType, GLenum newType, GLuint output) -{ - GLvoid *src, *dst; - - if (output > 0 || srcType == GL_FLOAT) { - src = span->array->attribs[VARYING_SLOT_COL0 + output]; - span->array->ChanType = GL_FLOAT; - } - else if (srcType == GL_UNSIGNED_BYTE) { - src = span->array->rgba8; - } - else { - assert(srcType == GL_UNSIGNED_SHORT); - src = span->array->rgba16; - } - - if (newType == GL_UNSIGNED_BYTE) { - dst = span->array->rgba8; - } - else if (newType == GL_UNSIGNED_SHORT) { - dst = span->array->rgba16; - } - else { - dst = span->array->attribs[VARYING_SLOT_COL0]; - } - - _mesa_convert_colors(span->array->ChanType, src, - newType, dst, - span->end, span->array->mask); - - span->array->ChanType = newType; - span->array->rgba = dst; -} - - - -/** - * Apply fragment shader, fragment program or normal texturing to span. - */ -static inline void -shade_texture_span(struct gl_context *ctx, SWspan *span) -{ - if (_swrast_use_fragment_program(ctx) || - _mesa_ati_fragment_shader_enabled(ctx)) { - /* programmable shading */ - if (span->primitive == GL_BITMAP && span->array->ChanType != GL_FLOAT) { - convert_color_type(span, span->array->ChanType, GL_FLOAT, 0); - } - else { - span->array->rgba = (void *) span->array->attribs[VARYING_SLOT_COL0]; - } - - if (span->primitive != GL_POINT || - (span->interpMask & SPAN_RGBA) || - ctx->Point.PointSprite) { - /* for single-pixel points, we populated the arrays already */ - interpolate_active_attribs(ctx, span, ~0); - } - span->array->ChanType = GL_FLOAT; - - if (!(span->arrayMask & SPAN_Z)) - _swrast_span_interpolate_z (ctx, span); - -#if 0 - if (inputsRead & VARYING_BIT_POS) -#else - /* XXX always interpolate wpos so that DDX/DDY work */ -#endif - interpolate_wpos(ctx, span); - - /* Run fragment program/shader now */ - if (_swrast_use_fragment_program(ctx)) { - _swrast_exec_fragment_program(ctx, span); - } - else { - assert(_mesa_ati_fragment_shader_enabled(ctx)); - _swrast_exec_fragment_shader(ctx, span); - } - } - else if (ctx->Texture._EnabledCoordUnits) { - /* conventional texturing */ - -#if CHAN_BITS == 32 - if ((span->arrayAttribs & VARYING_BIT_COL0) == 0) { - interpolate_int_colors(ctx, span); - } -#else - if (!(span->arrayMask & SPAN_RGBA)) - interpolate_int_colors(ctx, span); -#endif - if ((span->arrayAttribs & VARYING_BITS_TEX_ANY) == 0x0) - interpolate_texcoords(ctx, span); - - _swrast_texture_span(ctx, span); - } -} - - -/** Put colors at x/y locations into a renderbuffer */ -static void -put_values(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLenum datatype, - GLuint count, const GLint x[], const GLint y[], - const void *values, const GLubyte *mask) -{ - struct swrast_renderbuffer *srb = swrast_renderbuffer(rb); - GLuint i; - - for (i = 0; i < count; i++) { - if (mask[i]) { - if (datatype == GL_UNSIGNED_BYTE) { - util_format_write_4ub(rb->Format, - (uint8_t *)values + 4 * i, 0, - srb->Map, srb->RowStride, - x[i], y[i], 1, 1); - } - else { - assert(datatype == GL_FLOAT); - util_format_write_4(rb->Format, - (float *)values + 4 * i, 0, - srb->Map, srb->RowStride, - x[i], y[i], 1, 1); - } - } - } -} - - -/** Put row of colors into renderbuffer */ -void -_swrast_put_row(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLenum datatype, - GLuint count, GLint x, GLint y, - const void *values, const GLubyte *mask) -{ - GLubyte *dst = _swrast_pixel_address(rb, x, y); - - if (!mask) { - if (datatype == GL_UNSIGNED_BYTE) { - _mesa_pack_ubyte_rgba_row(rb->Format, count, values, dst); - } - else { - assert(datatype == GL_FLOAT); - _mesa_pack_float_rgba_row(rb->Format, count, - (const GLfloat (*)[4]) values, dst); - } - } - else { - const GLuint bpp = _mesa_get_format_bytes(rb->Format); - GLuint i, runLen, runStart; - /* We can't pass a 'mask' array to the _mesa_pack_rgba_row() functions - * so look for runs where mask=1... - */ - runLen = runStart = 0; - for (i = 0; i < count; i++) { - if (mask[i]) { - if (runLen == 0) - runStart = i; - runLen++; - } - - if (!mask[i] || i == count - 1) { - /* might be the end of a run of pixels */ - if (runLen > 0) { - if (datatype == GL_UNSIGNED_BYTE) { - _mesa_pack_ubyte_rgba_row(rb->Format, runLen, - (uint8_t *)values + runStart, - dst + runStart * bpp); - } - else { - assert(datatype == GL_FLOAT); - _mesa_pack_float_rgba_row(rb->Format, runLen, - (const GLfloat (*)[4]) values + runStart, - dst + runStart * bpp); - } - runLen = 0; - } - } - } - } -} - - - -/** - * Apply all the per-fragment operations to a span. - * This now includes texturing (_swrast_write_texture_span() is history). - * This function may modify any of the array values in the span. - * span->interpMask and span->arrayMask may be changed but will be restored - * to their original values before returning. - */ -void -_swrast_write_rgba_span( struct gl_context *ctx, SWspan *span) -{ - const SWcontext *swrast = SWRAST_CONTEXT(ctx); - const GLbitfield origInterpMask = span->interpMask; - const GLbitfield origArrayMask = span->arrayMask; - const GLbitfield64 origArrayAttribs = span->arrayAttribs; - const GLenum origChanType = span->array->ChanType; - void * const origRgba = span->array->rgba; - const GLboolean shader = (_swrast_use_fragment_program(ctx) - || _mesa_ati_fragment_shader_enabled(ctx)); - const GLboolean shaderOrTexture = shader || ctx->Texture._EnabledCoordUnits; - struct gl_framebuffer *fb = ctx->DrawBuffer; - - /* - printf("%s() interp 0x%x array 0x%x\n", __func__, - span->interpMask, span->arrayMask); - */ - - assert(span->primitive == GL_POINT || - span->primitive == GL_LINE || - span->primitive == GL_POLYGON || - span->primitive == GL_BITMAP); - - /* Fragment write masks */ - if (span->arrayMask & SPAN_MASK) { - /* mask was initialized by caller, probably glBitmap */ - span->writeAll = GL_FALSE; - } - else { - memset(span->array->mask, 1, span->end); - span->writeAll = GL_TRUE; - } - - /* Clip to window/scissor box */ - if (!clip_span(ctx, span)) { - return; - } - - assert(span->end <= SWRAST_MAX_WIDTH); - - /* Depth bounds test */ - if (ctx->Depth.BoundsTest && fb->Visual.depthBits > 0) { - if (!_swrast_depth_bounds_test(ctx, span)) { - return; - } - } - -#ifdef DEBUG - /* Make sure all fragments are within window bounds */ - if (span->arrayMask & SPAN_XY) { - /* array of pixel locations */ - GLuint i; - for (i = 0; i < span->end; i++) { - if (span->array->mask[i]) { - assert(span->array->x[i] >= fb->_Xmin); - assert(span->array->x[i] < fb->_Xmax); - assert(span->array->y[i] >= fb->_Ymin); - assert(span->array->y[i] < fb->_Ymax); - } - } - } -#endif - - /* Polygon Stippling */ - if (ctx->Polygon.StippleFlag && span->primitive == GL_POLYGON) { - stipple_polygon_span(ctx, span); - } - - /* This is the normal place to compute the fragment color/Z - * from texturing or shading. - */ - if (shaderOrTexture && !swrast->_DeferredTexture) { - shade_texture_span(ctx, span); - } - - /* Do the alpha test */ - if (ctx->Color.AlphaEnabled) { - if (!_swrast_alpha_test(ctx, span)) { - /* all fragments failed test */ - goto end; - } - } - - /* Stencil and Z testing */ - if (_mesa_stencil_is_enabled(ctx) || ctx->Depth.Test) { - if (!(span->arrayMask & SPAN_Z)) - _swrast_span_interpolate_z(ctx, span); - - if (ctx->Transform.DepthClampNear && ctx->Transform.DepthClampFar) - _swrast_depth_clamp_span(ctx, span); - - if (_mesa_stencil_is_enabled(ctx)) { - /* Combined Z/stencil tests */ - if (!_swrast_stencil_and_ztest_span(ctx, span)) { - /* all fragments failed test */ - goto end; - } - } - else if (fb->Visual.depthBits > 0) { - /* Just regular depth testing */ - assert(ctx->Depth.Test); - assert(span->arrayMask & SPAN_Z); - if (!_swrast_depth_test_span(ctx, span)) { - /* all fragments failed test */ - goto end; - } - } - } - - if (ctx->Query.CurrentOcclusionObject) { - /* update count of 'passed' fragments */ - struct gl_query_object *q = ctx->Query.CurrentOcclusionObject; - GLuint i; - for (i = 0; i < span->end; i++) - q->Result += span->array->mask[i]; - } - - /* We had to wait until now to check for glColorMask(0,0,0,0) because of - * the occlusion test. - */ - if (fb->_NumColorDrawBuffers == 1 && - !GET_COLORMASK(ctx->Color.ColorMask, 0)) { - /* no colors to write */ - goto end; - } - - /* If we were able to defer fragment color computation to now, there's - * a good chance that many fragments will have already been killed by - * Z/stencil testing. - */ - if (shaderOrTexture && swrast->_DeferredTexture) { - shade_texture_span(ctx, span); - } - -#if CHAN_BITS == 32 - if ((span->arrayAttribs & VARYING_BIT_COL0) == 0) { - interpolate_active_attribs(ctx, span, VARYING_BIT_COL0); - } -#else - if ((span->arrayMask & SPAN_RGBA) == 0) { - interpolate_int_colors(ctx, span); - } -#endif - - assert(span->arrayMask & SPAN_RGBA); - - if (span->primitive == GL_BITMAP || !swrast->SpecularVertexAdd) { - /* Add primary and specular (diffuse + specular) colors */ - if (!shader) { - if (ctx->Fog.ColorSumEnabled || - (ctx->Light.Enabled && - ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) { - add_specular(ctx, span); - } - } - } - - /* Fog */ - if (swrast->_FogEnabled) { - _swrast_fog_rgba_span(ctx, span); - } - - /* Antialias coverage application */ - if (span->arrayMask & SPAN_COVERAGE) { - apply_aa_coverage(span); - } - - /* Clamp color/alpha values over the range [0.0, 1.0] before storage */ - if (ctx->Color.ClampFragmentColor == GL_TRUE && - span->array->ChanType == GL_FLOAT) { - clamp_colors(span); - } - - /* - * Write to renderbuffers. - * Depending on glDrawBuffer() state and the which color outputs are - * written by the fragment shader, we may either replicate one color to - * all renderbuffers or write a different color to each renderbuffer. - * multiFragOutputs=TRUE for the later case. - */ - { - const GLuint numBuffers = fb->_NumColorDrawBuffers; - const struct gl_program *fp = ctx->FragmentProgram._Current; - const GLboolean multiFragOutputs = - _swrast_use_fragment_program(ctx) - && fp->info.outputs_written >= (1 << FRAG_RESULT_DATA0); - /* Save srcColorType because convert_color_type() can change it */ - const GLenum srcColorType = span->array->ChanType; - GLuint buf; - - for (buf = 0; buf < numBuffers; buf++) { - struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[buf]; - - /* color[fragOutput] will be written to buffer[buf] */ - - if (rb) { - /* re-use one of the attribute array buffers for rgbaSave */ - GLchan (*rgbaSave)[4] = (GLchan (*)[4]) span->array->attribs[0]; - struct swrast_renderbuffer *srb = swrast_renderbuffer(rb); - const GLenum dstColorType = srb->ColorType; - - assert(dstColorType == GL_UNSIGNED_BYTE || - dstColorType == GL_FLOAT); - - /* set span->array->rgba to colors for renderbuffer's datatype */ - if (srcColorType != dstColorType) { - convert_color_type(span, srcColorType, dstColorType, - multiFragOutputs ? buf : 0); - } - else { - if (srcColorType == GL_UNSIGNED_BYTE) { - span->array->rgba = span->array->rgba8; - } - else { - span->array->rgba = (void *) - span->array->attribs[VARYING_SLOT_COL0]; - } - } - - if (!multiFragOutputs && numBuffers > 1) { - /* save colors for second, third renderbuffer writes */ - memcpy(rgbaSave, span->array->rgba, - 4 * span->end * sizeof(GLchan)); - } - - assert(rb->_BaseFormat == GL_RGBA || - rb->_BaseFormat == GL_RGB || - rb->_BaseFormat == GL_RED || - rb->_BaseFormat == GL_RG || - rb->_BaseFormat == GL_ALPHA); - - if (ctx->Color.ColorLogicOpEnabled) { - _swrast_logicop_rgba_span(ctx, rb, span); - } - else if ((ctx->Color.BlendEnabled >> buf) & 1) { - _swrast_blend_span(ctx, rb, span); - } - - if (GET_COLORMASK(ctx->Color.ColorMask, buf) != 0xf) { - _swrast_mask_rgba_span(ctx, rb, span, buf); - } - - if (span->arrayMask & SPAN_XY) { - /* array of pixel coords */ - put_values(ctx, rb, - span->array->ChanType, span->end, - span->array->x, span->array->y, - span->array->rgba, span->array->mask); - } - else { - /* horizontal run of pixels */ - _swrast_put_row(ctx, rb, - span->array->ChanType, - span->end, span->x, span->y, - span->array->rgba, - span->writeAll ? NULL: span->array->mask); - } - - if (!multiFragOutputs && numBuffers > 1) { - /* restore original span values */ - memcpy(span->array->rgba, rgbaSave, - 4 * span->end * sizeof(GLchan)); - } - - } /* if rb */ - } /* for buf */ - } - -end: - /* restore these values before returning */ - span->interpMask = origInterpMask; - span->arrayMask = origArrayMask; - span->arrayAttribs = origArrayAttribs; - span->array->ChanType = origChanType; - span->array->rgba = origRgba; -} - - -/** - * Read float RGBA pixels from a renderbuffer. Clipping will be done to - * prevent reading ouside the buffer's boundaries. - * \param rgba the returned colors - */ -void -_swrast_read_rgba_span( struct gl_context *ctx, struct gl_renderbuffer *rb, - GLuint n, GLint x, GLint y, - GLvoid *rgba) -{ - struct swrast_renderbuffer *srb = swrast_renderbuffer(rb); - GLenum dstType = GL_FLOAT; - const GLint bufWidth = (GLint) rb->Width; - const GLint bufHeight = (GLint) rb->Height; - - if (y < 0 || y >= bufHeight || x + (GLint) n < 0 || x >= bufWidth) { - /* completely above, below, or right */ - /* XXX maybe leave rgba values undefined? */ - memset(rgba, 0, 4 * n * sizeof(GLchan)); - } - else { - GLint skip, length; - GLubyte *src; - - if (x < 0) { - /* left edge clipping */ - skip = -x; - length = (GLint) n - skip; - if (length < 0) { - /* completely left of window */ - return; - } - if (length > bufWidth) { - length = bufWidth; - } - } - else if ((GLint) (x + n) > bufWidth) { - /* right edge clipping */ - skip = 0; - length = bufWidth - x; - if (length < 0) { - /* completely to right of window */ - return; - } - } - else { - /* no clipping */ - skip = 0; - length = (GLint) n; - } - - assert(rb); - assert(rb->_BaseFormat == GL_RGBA || - rb->_BaseFormat == GL_RGB || - rb->_BaseFormat == GL_RG || - rb->_BaseFormat == GL_RED || - rb->_BaseFormat == GL_LUMINANCE || - rb->_BaseFormat == GL_INTENSITY || - rb->_BaseFormat == GL_LUMINANCE_ALPHA || - rb->_BaseFormat == GL_ALPHA); - - assert(srb->Map); - (void) srb; /* silence unused var warning */ - - src = _swrast_pixel_address(rb, x + skip, y); - - if (dstType == GL_UNSIGNED_BYTE) { - _mesa_unpack_ubyte_rgba_row(rb->Format, length, src, - (GLubyte (*)[4]) rgba + skip); - } - else if (dstType == GL_FLOAT) { - _mesa_unpack_rgba_row(rb->Format, length, src, - (GLfloat (*)[4]) rgba + skip); - } - else { - _mesa_problem(ctx, "unexpected type in _swrast_read_rgba_span()"); - } - } -} - - -/** - * Get colors at x/y positions with clipping. - * \param type type of values to return - */ -static void -get_values(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLuint count, const GLint x[], const GLint y[], - void *values, GLenum type) -{ - GLuint i; - - for (i = 0; i < count; i++) { - if (x[i] >= 0 && y[i] >= 0 && - x[i] < (GLint) rb->Width && y[i] < (GLint) rb->Height) { - /* inside */ - const GLubyte *src = _swrast_pixel_address(rb, x[i], y[i]); - - if (type == GL_UNSIGNED_BYTE) { - _mesa_unpack_ubyte_rgba_row(rb->Format, 1, src, - (GLubyte (*)[4]) values + i); - } - else if (type == GL_FLOAT) { - _mesa_unpack_rgba_row(rb->Format, 1, src, - (GLfloat (*)[4]) values + i); - } - else { - _mesa_problem(ctx, "unexpected type in get_values()"); - } - } - } -} - - -/** - * Get row of colors with clipping. - * \param type type of values to return - */ -static void -get_row(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLuint count, GLint x, GLint y, - GLvoid *values, GLenum type) -{ - GLint skip = 0; - GLubyte *src; - - if (y < 0 || y >= (GLint) rb->Height) - return; /* above or below */ - - if (x + (GLint) count <= 0 || x >= (GLint) rb->Width) - return; /* entirely left or right */ - - if (x + count > rb->Width) { - /* right clip */ - GLint clip = x + count - rb->Width; - count -= clip; - } - - if (x < 0) { - /* left clip */ - skip = -x; - x = 0; - count -= skip; - } - - src = _swrast_pixel_address(rb, x, y); - - if (type == GL_UNSIGNED_BYTE) { - _mesa_unpack_ubyte_rgba_row(rb->Format, count, src, - (GLubyte (*)[4]) values + skip); - } - else if (type == GL_FLOAT) { - _mesa_unpack_rgba_row(rb->Format, count, src, - (GLfloat (*)[4]) values + skip); - } - else { - _mesa_problem(ctx, "unexpected type in get_row()"); - } -} - - -/** - * Get RGBA pixels from the given renderbuffer. - * Used by blending, logicop and masking functions. - * \return pointer to the colors we read. - */ -void * -_swrast_get_dest_rgba(struct gl_context *ctx, struct gl_renderbuffer *rb, - SWspan *span) -{ - void *rbPixels; - - /* Point rbPixels to a temporary space */ - rbPixels = span->array->attribs[VARYING_SLOT_MAX - 1]; - - /* Get destination values from renderbuffer */ - if (span->arrayMask & SPAN_XY) { - get_values(ctx, rb, span->end, span->array->x, span->array->y, - rbPixels, span->array->ChanType); - } - else { - get_row(ctx, rb, span->end, span->x, span->y, - rbPixels, span->array->ChanType); - } - - return rbPixels; -} diff --git a/src/mesa/swrast/s_span.h b/src/mesa/swrast/s_span.h deleted file mode 100644 index 794f671..0000000 --- a/src/mesa/swrast/s_span.h +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. - * Copyright (C) 2009 VMware, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -#ifndef S_SPAN_H -#define S_SPAN_H - - -#include "main/config.h" -#include "main/glheader.h" -#include "main/mtypes.h" -#include "swrast/s_chan.h" -#include "swrast/swrast.h" - - -struct gl_context; -struct gl_renderbuffer; - - -/** - * \defgroup SpanFlags - * Special bitflags to describe span data. - * - * In general, the point/line/triangle functions interpolate/emit the - * attributes specified by swrast->_ActiveAttribs (i.e. FRAT_BIT_* values). - * Some things don't fit into that, though, so we have these flags. - */ -/*@{*/ -#define SPAN_RGBA 0x01 /**< interpMask and arrayMask */ -#define SPAN_Z 0x02 /**< interpMask and arrayMask */ -#define SPAN_FLAT 0x04 /**< interpMask: flat shading? */ -#define SPAN_XY 0x08 /**< array.x[], y[] valid? */ -#define SPAN_MASK 0x10 /**< was array.mask[] filled in by caller? */ -#define SPAN_LAMBDA 0x20 /**< array.lambda[] valid? */ -#define SPAN_COVERAGE 0x40 /**< array.coverage[] valid? */ -/*@}*/ - - -/** - * \sw_span_arrays - * \brief Arrays of fragment values. - * - * These will either be computed from the span x/xStep values or - * filled in by glDraw/CopyPixels, etc. - * These arrays are separated out of sw_span to conserve memory. - */ -typedef struct sw_span_arrays -{ - /** Per-fragment attributes (indexed by VARYING_SLOT_* tokens) */ - /* XXX someday look at transposing first two indexes for better memory - * access pattern. - */ - GLfloat attribs[VARYING_SLOT_MAX][SWRAST_MAX_WIDTH][4]; - - /** This mask indicates which fragments are alive or culled */ - GLubyte mask[SWRAST_MAX_WIDTH]; - - GLenum ChanType; /**< Color channel type, GL_UNSIGNED_BYTE, GL_FLOAT */ - - /** Attribute arrays that don't fit into attribs[] array above */ - /*@{*/ - GLubyte rgba8[SWRAST_MAX_WIDTH][4]; - GLushort rgba16[SWRAST_MAX_WIDTH][4]; - GLchan (*rgba)[4]; /** either == rgba8 or rgba16 */ - GLint x[SWRAST_MAX_WIDTH]; /**< fragment X coords */ - GLint y[SWRAST_MAX_WIDTH]; /**< fragment Y coords */ - GLuint z[SWRAST_MAX_WIDTH]; /**< fragment Z coords */ - GLuint index[SWRAST_MAX_WIDTH]; /**< Color indexes */ - GLfloat lambda[MAX_TEXTURE_COORD_UNITS][SWRAST_MAX_WIDTH]; /**< Texture LOD */ - GLfloat coverage[SWRAST_MAX_WIDTH]; /**< Fragment coverage for AA/smoothing */ - /*@}*/ -} SWspanarrays; - - -/** - * The SWspan structure describes the colors, Z, fogcoord, texcoords, - * etc for either a horizontal run or an array of independent pixels. - * We can either specify a base/step to indicate interpolated values, or - * fill in explicit arrays of values. The interpMask and arrayMask bitfields - * indicate which attributes are active interpolants or arrays, respectively. - * - * It would be interesting to experiment with multiprocessor rasterization - * with this structure. The triangle rasterizer could simply emit a - * stream of these structures which would be consumed by one or more - * span-processing threads which could run in parallel. - */ -typedef struct sw_span -{ - /** Coord of first fragment in horizontal span/run */ - GLint x, y; - - /** Number of fragments in the span */ - GLuint end; - - /** for clipping left edge of spans */ - GLuint leftClip; - - /** This flag indicates that mask[] array is effectively filled with ones */ - GLboolean writeAll; - - /** either GL_POLYGON, GL_LINE, GL_POLYGON, GL_BITMAP */ - GLenum primitive; - - /** 0 = front-facing span, 1 = back-facing span (for two-sided stencil) */ - GLuint facing; - - /** - * This bitmask (of \link SpanFlags SPAN_* flags\endlink) indicates - * which of the attrStart/StepX/StepY variables are relevant. - */ - GLbitfield interpMask; - - /** Fragment attribute interpolants */ - GLfloat attrStart[VARYING_SLOT_MAX][4]; /**< initial value */ - GLfloat attrStepX[VARYING_SLOT_MAX][4]; /**< dvalue/dx */ - GLfloat attrStepY[VARYING_SLOT_MAX][4]; /**< dvalue/dy */ - - /* XXX the rest of these will go away eventually... */ - - /* For horizontal spans, step is the partial derivative wrt X. - * For lines, step is the delta from one fragment to the next. - */ - GLfixed red, redStep; - GLfixed green, greenStep; - GLfixed blue, blueStep; - GLfixed alpha, alphaStep; - GLfixed index, indexStep; - GLfixed z, zStep; /**< XXX z should probably be GLuint */ - GLfixed intTex[2], intTexStep[2]; /**< (s,t) for unit[0] only */ - - /** - * This bitmask (of \link SpanFlags SPAN_* flags\endlink) indicates - * which of the fragment arrays in the span_arrays struct are relevant. - */ - GLbitfield arrayMask; - - /** Mask of VARYING_BIT_x bits */ - GLbitfield64 arrayAttribs; - - /** - * We store the arrays of fragment values in a separate struct so - * that we can allocate sw_span structs on the stack without using - * a lot of memory. The span_arrays struct is about 1.4MB while the - * sw_span struct is only about 512 bytes. - */ - SWspanarrays *array; -} SWspan; - - - -#define INIT_SPAN(S, PRIMITIVE) \ -do { \ - (S).primitive = (PRIMITIVE); \ - (S).interpMask = 0x0; \ - (S).arrayMask = 0x0; \ - (S).arrayAttribs = 0x0; \ - (S).end = 0; \ - (S).leftClip = 0; \ - (S).facing = 0; \ - (S).array = SWRAST_CONTEXT(ctx)->SpanArrays; \ -} while (0) - - - -extern void -_swrast_span_default_attribs(struct gl_context *ctx, SWspan *span); - -extern void -_swrast_span_interpolate_z( const struct gl_context *ctx, SWspan *span ); - -extern GLfloat -_swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, - GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH, - GLfloat s, GLfloat t, GLfloat q, GLfloat invQ); - - -extern void -_swrast_write_rgba_span( struct gl_context *ctx, SWspan *span); - - -extern void -_swrast_read_rgba_span(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLuint n, GLint x, GLint y, GLvoid *rgba); - -extern void -_swrast_put_row(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLenum datatype, - GLuint count, GLint x, GLint y, - const void *values, const GLubyte *mask); - -extern void * -_swrast_get_dest_rgba(struct gl_context *ctx, struct gl_renderbuffer *rb, - SWspan *span); - -#endif diff --git a/src/mesa/swrast/s_stencil.c b/src/mesa/swrast/s_stencil.c deleted file mode 100644 index 70d814e..0000000 --- a/src/mesa/swrast/s_stencil.c +++ /dev/null @@ -1,710 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -#include "main/glheader.h" -#include "main/context.h" - -#include "main/format_pack.h" -#include "main/format_unpack.h" -#include "main/stencil.h" - -#include "s_context.h" -#include "s_depth.h" -#include "s_stencil.h" -#include "s_span.h" - - - -/* Stencil Logic: - -IF stencil test fails THEN - Apply fail-op to stencil value - Don't write the pixel (RGBA,Z) -ELSE - IF doing depth test && depth test fails THEN - Apply zfail-op to stencil value - Write RGBA and Z to appropriate buffers - ELSE - Apply zpass-op to stencil value -ENDIF - -*/ - - - -/** - * Compute/return the offset of the stencil value in a pixel. - * For example, if the format is Z24+S8, the position of the stencil bits - * within the 4-byte pixel will be either 0 or 3. - */ -static GLint -get_stencil_offset(mesa_format format) -{ - const GLubyte one = 1; - GLubyte pixel[MAX_PIXEL_BYTES]; - GLint bpp = _mesa_get_format_bytes(format); - GLint i; - - assert(_mesa_get_format_bits(format, GL_STENCIL_BITS) == 8); - memset(pixel, 0, sizeof(pixel)); - _mesa_pack_ubyte_stencil_row(format, 1, &one, pixel); - - for (i = 0; i < bpp; i++) { - if (pixel[i]) - return i; - } - - _mesa_problem(NULL, "get_stencil_offset() failed\n"); - return 0; -} - - -/** Clamp the stencil value to [0, 255] */ -static inline GLubyte -clamp(GLint val) -{ - if (val < 0) - return 0; - else if (val > 255) - return 255; - else - return val; -} - - -#define STENCIL_OP(NEW_VAL) \ - if (invmask == 0) { \ - for (i = j = 0; i < n; i++, j += stride) { \ - if (mask[i]) { \ - GLubyte s = stencil[j]; \ - (void) s; \ - stencil[j] = (GLubyte) (NEW_VAL); \ - } \ - } \ - } \ - else { \ - for (i = j = 0; i < n; i++, j += stride) { \ - if (mask[i]) { \ - GLubyte s = stencil[j]; \ - stencil[j] = (GLubyte) ((invmask & s) | (wrtmask & (NEW_VAL))); \ - } \ - } \ - } - - -/** - * Apply the given stencil operator to the array of stencil values. - * Don't touch stencil[i] if mask[i] is zero. - * @param n number of stencil values - * @param oper the stencil buffer operator - * @param face 0 or 1 for front or back face operation - * @param stencil array of stencil values (in/out) - * @param mask array [n] of flag: 1=apply operator, 0=don't apply operator - * @param stride stride between stencil values - */ -static void -apply_stencil_op(const struct gl_context *ctx, GLenum oper, GLuint face, - GLuint n, GLubyte stencil[], const GLubyte mask[], - GLint stride) -{ - const GLubyte ref = _mesa_get_stencil_ref(ctx, face); - const GLubyte wrtmask = ctx->Stencil.WriteMask[face]; - const GLubyte invmask = (GLubyte) (~wrtmask); - GLuint i, j; - - switch (oper) { - case GL_KEEP: - /* do nothing */ - break; - case GL_ZERO: - /* replace stencil buf values with zero */ - STENCIL_OP(0); - break; - case GL_REPLACE: - /* replace stencil buf values with ref value */ - STENCIL_OP(ref); - break; - case GL_INCR: - /* increment stencil buf values, with clamping */ - STENCIL_OP(clamp(s + 1)); - break; - case GL_DECR: - /* increment stencil buf values, with clamping */ - STENCIL_OP(clamp(s - 1)); - break; - case GL_INCR_WRAP_EXT: - /* increment stencil buf values, without clamping */ - STENCIL_OP(s + 1); - break; - case GL_DECR_WRAP_EXT: - /* increment stencil buf values, without clamping */ - STENCIL_OP(s - 1); - break; - case GL_INVERT: - /* replace stencil buf values with inverted value */ - STENCIL_OP(~s); - break; - default: - _mesa_problem(ctx, "Bad stencil op in apply_stencil_op"); - } -} - - - -#define STENCIL_TEST(FUNC) \ - for (i = j = 0; i < n; i++, j += stride) { \ - if (mask[i]) { \ - s = (GLubyte) (stencil[j] & valueMask); \ - if (FUNC) { \ - /* stencil pass */ \ - fail[i] = 0; \ - } \ - else { \ - /* stencil fail */ \ - fail[i] = 1; \ - mask[i] = 0; \ - } \ - } \ - else { \ - fail[i] = 0; \ - } \ - } - - - -/** - * Apply stencil test to an array of stencil values (before depth buffering). - * For the values that fail, we'll apply the GL_STENCIL_FAIL operator to - * the stencil values. - * - * @param face 0 or 1 for front or back-face polygons - * @param n number of pixels in the array - * @param stencil array of [n] stencil values (in/out) - * @param mask array [n] of flag: 0=skip the pixel, 1=stencil the pixel, - * values are set to zero where the stencil test fails. - * @param stride stride between stencil values - * @return GL_FALSE = all pixels failed, GL_TRUE = zero or more pixels passed. - */ -static GLboolean -do_stencil_test(struct gl_context *ctx, GLuint face, GLuint n, - GLubyte stencil[], GLubyte mask[], GLint stride) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - GLubyte *fail = swrast->stencil_temp.buf2; - GLboolean allfail = GL_FALSE; - GLuint i, j; - const GLuint valueMask = ctx->Stencil.ValueMask[face]; - const GLubyte ref = (GLubyte) (_mesa_get_stencil_ref(ctx, face) & valueMask); - GLubyte s; - - /* - * Perform stencil test. The results of this operation are stored - * in the fail[] array: - * IF fail[i] is non-zero THEN - * the stencil fail operator is to be applied - * ELSE - * the stencil fail operator is not to be applied - * ENDIF - */ - switch (ctx->Stencil.Function[face]) { - case GL_NEVER: - STENCIL_TEST(0); - allfail = GL_TRUE; - break; - case GL_LESS: - STENCIL_TEST(ref < s); - break; - case GL_LEQUAL: - STENCIL_TEST(ref <= s); - break; - case GL_GREATER: - STENCIL_TEST(ref > s); - break; - case GL_GEQUAL: - STENCIL_TEST(ref >= s); - break; - case GL_EQUAL: - STENCIL_TEST(ref == s); - break; - case GL_NOTEQUAL: - STENCIL_TEST(ref != s); - break; - case GL_ALWAYS: - STENCIL_TEST(1); - break; - default: - _mesa_problem(ctx, "Bad stencil func in gl_stencil_span"); - return 0; - } - - if (ctx->Stencil.FailFunc[face] != GL_KEEP) { - apply_stencil_op(ctx, ctx->Stencil.FailFunc[face], face, n, stencil, - fail, stride); - } - - return !allfail; -} - - -/** - * Compute the zpass/zfail masks by comparing the pre- and post-depth test - * masks. - */ -static inline void -compute_pass_fail_masks(GLuint n, const GLubyte origMask[], - const GLubyte newMask[], - GLubyte passMask[], GLubyte failMask[]) -{ - GLuint i; - for (i = 0; i < n; i++) { - assert(newMask[i] == 0 || newMask[i] == 1); - passMask[i] = origMask[i] & newMask[i]; - failMask[i] = origMask[i] & (newMask[i] ^ 1); - } -} - - -/** - * Get 8-bit stencil values from random locations in the stencil buffer. - */ -static void -get_s8_values(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLuint count, const GLint x[], const GLint y[], - GLubyte stencil[]) -{ - struct swrast_renderbuffer *srb = swrast_renderbuffer(rb); - const GLint w = rb->Width, h = rb->Height; - const GLubyte *map = _swrast_pixel_address(rb, 0, 0); - GLuint i; - - if (rb->Format == MESA_FORMAT_S_UINT8) { - const GLint rowStride = srb->RowStride; - for (i = 0; i < count; i++) { - if (x[i] >= 0 && y[i] >= 0 && x[i] < w && y[i] < h) { - stencil[i] = *(map + y[i] * rowStride + x[i]); - } - } - } - else { - const GLint bpp = _mesa_get_format_bytes(rb->Format); - const GLint rowStride = srb->RowStride; - for (i = 0; i < count; i++) { - if (x[i] >= 0 && y[i] >= 0 && x[i] < w && y[i] < h) { - const GLubyte *src = map + y[i] * rowStride + x[i] * bpp; - _mesa_unpack_ubyte_stencil_row(rb->Format, 1, src, &stencil[i]); - } - } - } -} - - - -/** - ** Pack ubyte stencil pixels - **/ - -static void -pack_ubyte_stencil_Z24_S8(const uint8_t *src, void *dst) -{ - /* don't disturb the Z values */ - uint32_t *d = ((uint32_t *) dst); - uint32_t s = *src; - uint32_t z = *d & 0xffffff00; - *d = z | s; -} - -static void -pack_ubyte_stencil_S8_Z24(const uint8_t *src, void *dst) -{ - /* don't disturb the Z values */ - uint32_t *d = ((uint32_t *) dst); - uint32_t s = *src << 24; - uint32_t z = *d & 0xffffff; - *d = s | z; -} - -static void -pack_ubyte_stencil_S8(const uint8_t *src, void *dst) -{ - uint8_t *d = (uint8_t *) dst; - *d = *src; -} - -static void -pack_ubyte_stencil_Z32_FLOAT_X24S8(const uint8_t *src, void *dst) -{ - float *d = ((float *) dst); - d[1] = *src; -} - -/** Pack a uint8_t stencil value to dest address */ -typedef void (*mesa_pack_ubyte_stencil_func)(const uint8_t *src, void *dst); - -static mesa_pack_ubyte_stencil_func -get_pack_ubyte_stencil_func(mesa_format format) -{ - switch (format) { - case MESA_FORMAT_S8_UINT_Z24_UNORM: - return pack_ubyte_stencil_Z24_S8; - case MESA_FORMAT_Z24_UNORM_S8_UINT: - return pack_ubyte_stencil_S8_Z24; - case MESA_FORMAT_S_UINT8: - return pack_ubyte_stencil_S8; - case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: - return pack_ubyte_stencil_Z32_FLOAT_X24S8; - default: - unreachable("unexpected format in get_pack_ubyte_stencil_func()"); - } -} - - -/** - * Put 8-bit stencil values at random locations into the stencil buffer. - */ -static void -put_s8_values(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLuint count, const GLint x[], const GLint y[], - const GLubyte stencil[]) -{ - const GLint w = rb->Width, h = rb->Height; - mesa_pack_ubyte_stencil_func pack_stencil = - get_pack_ubyte_stencil_func(rb->Format); - GLuint i; - - for (i = 0; i < count; i++) { - if (x[i] >= 0 && y[i] >= 0 && x[i] < w && y[i] < h) { - GLubyte *dst = _swrast_pixel_address(rb, x[i], y[i]); - pack_stencil(&stencil[i], dst); - } - } -} - - -/** - * /return GL_TRUE = one or more fragments passed, - * GL_FALSE = all fragments failed. - */ -GLboolean -_swrast_stencil_and_ztest_span(struct gl_context *ctx, SWspan *span) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - struct gl_framebuffer *fb = ctx->DrawBuffer; - struct gl_renderbuffer *rb = fb->Attachment[BUFFER_STENCIL].Renderbuffer; - const GLint stencilOffset = get_stencil_offset(rb->Format); - const GLint stencilStride = _mesa_get_format_bytes(rb->Format); - const GLuint face = (span->facing == 0) ? 0 : ctx->Stencil._BackFace; - const GLuint count = span->end; - GLubyte *mask = span->array->mask; - GLubyte *stencilTemp = swrast->stencil_temp.buf1; - GLubyte *stencilBuf; - - if (span->arrayMask & SPAN_XY) { - /* read stencil values from random locations */ - get_s8_values(ctx, rb, count, span->array->x, span->array->y, - stencilTemp); - stencilBuf = stencilTemp; - } - else { - /* Processing a horizontal run of pixels. Since stencil is always - * 8 bits for all MESA_FORMATs, we just need to use the right offset - * and stride to access them. - */ - stencilBuf = _swrast_pixel_address(rb, span->x, span->y) + stencilOffset; - } - - /* - * Apply the stencil test to the fragments. - * failMask[i] is 1 if the stencil test failed. - */ - if (!do_stencil_test(ctx, face, count, stencilBuf, mask, stencilStride)) { - /* all fragments failed the stencil test, we're done. */ - span->writeAll = GL_FALSE; - if (span->arrayMask & SPAN_XY) { - /* need to write the updated stencil values back to the buffer */ - put_s8_values(ctx, rb, count, span->array->x, span->array->y, - stencilTemp); - } - return GL_FALSE; - } - - /* - * Some fragments passed the stencil test, apply depth test to them - * and apply Zpass and Zfail stencil ops. - */ - if (ctx->Depth.Test == GL_FALSE || - ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer == NULL) { - /* - * No depth buffer, just apply zpass stencil function to active pixels. - */ - apply_stencil_op(ctx, ctx->Stencil.ZPassFunc[face], face, count, - stencilBuf, mask, stencilStride); - } - else { - /* - * Perform depth buffering, then apply zpass or zfail stencil function. - */ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - GLubyte *passMask = swrast->stencil_temp.buf2; - GLubyte *failMask = swrast->stencil_temp.buf3; - GLubyte *origMask = swrast->stencil_temp.buf4; - - /* save the current mask bits */ - memcpy(origMask, mask, count * sizeof(GLubyte)); - - /* apply the depth test */ - _swrast_depth_test_span(ctx, span); - - compute_pass_fail_masks(count, origMask, mask, passMask, failMask); - - /* apply the pass and fail operations */ - if (ctx->Stencil.ZFailFunc[face] != GL_KEEP) { - apply_stencil_op(ctx, ctx->Stencil.ZFailFunc[face], face, - count, stencilBuf, failMask, stencilStride); - } - if (ctx->Stencil.ZPassFunc[face] != GL_KEEP) { - apply_stencil_op(ctx, ctx->Stencil.ZPassFunc[face], face, - count, stencilBuf, passMask, stencilStride); - } - } - - /* Write updated stencil values back into hardware stencil buffer */ - if (span->arrayMask & SPAN_XY) { - put_s8_values(ctx, rb, count, span->array->x, span->array->y, - stencilBuf); - } - - span->writeAll = GL_FALSE; - - return GL_TRUE; /* one or more fragments passed both tests */ -} - - - - -/** - * Return a span of stencil values from the stencil buffer. - * Used for glRead/CopyPixels - * Input: n - how many pixels - * x,y - location of first pixel - * Output: stencil - the array of stencil values - */ -void -_swrast_read_stencil_span(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLint n, GLint x, GLint y, GLubyte stencil[]) -{ - GLubyte *src; - - if (y < 0 || y >= (GLint) rb->Height || - x + n <= 0 || x >= (GLint) rb->Width) { - /* span is completely outside framebuffer */ - return; /* undefined values OK */ - } - - if (x < 0) { - GLint dx = -x; - x = 0; - n -= dx; - stencil += dx; - } - if (x + n > (GLint) rb->Width) { - GLint dx = x + n - rb->Width; - n -= dx; - } - if (n <= 0) { - return; - } - - src = _swrast_pixel_address(rb, x, y); - _mesa_unpack_ubyte_stencil_row(rb->Format, n, src, stencil); -} - - - -/** - * Write a span of stencil values to the stencil buffer. This function - * applies the stencil write mask when needed. - * Used for glDraw/CopyPixels - * Input: n - how many pixels - * x, y - location of first pixel - * stencil - the array of stencil values - */ -void -_swrast_write_stencil_span(struct gl_context *ctx, GLint n, GLint x, GLint y, - const GLubyte stencil[] ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - struct gl_framebuffer *fb = ctx->DrawBuffer; - struct gl_renderbuffer *rb = fb->Attachment[BUFFER_STENCIL].Renderbuffer; - const GLuint stencilMax = (1 << fb->Visual.stencilBits) - 1; - const GLuint stencilMask = ctx->Stencil.WriteMask[0]; - GLubyte *stencilBuf; - - if (y < 0 || y >= (GLint) rb->Height || - x + n <= 0 || x >= (GLint) rb->Width) { - /* span is completely outside framebuffer */ - return; /* undefined values OK */ - } - if (x < 0) { - GLint dx = -x; - x = 0; - n -= dx; - stencil += dx; - } - if (x + n > (GLint) rb->Width) { - GLint dx = x + n - rb->Width; - n -= dx; - } - if (n <= 0) { - return; - } - - stencilBuf = _swrast_pixel_address(rb, x, y); - - if ((stencilMask & stencilMax) != stencilMax) { - /* need to apply writemask */ - GLubyte *destVals = swrast->stencil_temp.buf1; - GLubyte *newVals = swrast->stencil_temp.buf2; - GLint i; - - _mesa_unpack_ubyte_stencil_row(rb->Format, n, stencilBuf, destVals); - for (i = 0; i < n; i++) { - newVals[i] - = (stencil[i] & stencilMask) | (destVals[i] & ~stencilMask); - } - _mesa_pack_ubyte_stencil_row(rb->Format, n, newVals, stencilBuf); - } - else { - _mesa_pack_ubyte_stencil_row(rb->Format, n, stencil, stencilBuf); - } -} - - - -/** - * Clear the stencil buffer. If the buffer is a combined - * depth+stencil buffer, only the stencil bits will be touched. - */ -void -_swrast_clear_stencil_buffer(struct gl_context *ctx) -{ - struct gl_renderbuffer *rb = - ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer; - const GLubyte stencilBits = ctx->DrawBuffer->Visual.stencilBits; - const GLuint writeMask = ctx->Stencil.WriteMask[0]; - const GLuint stencilMax = (1 << stencilBits) - 1; - GLint x, y, width, height; - GLubyte *map; - GLint rowStride, i, j; - GLbitfield mapMode; - - if (!rb || writeMask == 0) - return; - - /* compute region to clear */ - x = ctx->DrawBuffer->_Xmin; - y = ctx->DrawBuffer->_Ymin; - width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; - height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; - - mapMode = GL_MAP_WRITE_BIT; - if ((writeMask & stencilMax) != stencilMax) { - /* need to mask stencil values */ - mapMode |= GL_MAP_READ_BIT; - } - else if (_mesa_get_format_bits(rb->Format, GL_DEPTH_BITS) > 0) { - /* combined depth+stencil, need to mask Z values */ - mapMode |= GL_MAP_READ_BIT; - } - - ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, - mapMode, &map, &rowStride, - ctx->DrawBuffer->FlipY); - if (!map) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClear(stencil)"); - return; - } - - switch (rb->Format) { - case MESA_FORMAT_S_UINT8: - { - GLubyte clear = ctx->Stencil.Clear & writeMask & 0xff; - GLubyte mask = (~writeMask) & 0xff; - if (mask != 0) { - /* masked clear */ - for (i = 0; i < height; i++) { - GLubyte *row = map; - for (j = 0; j < width; j++) { - row[j] = (row[j] & mask) | clear; - } - map += rowStride; - } - } - else if (rowStride == width) { - /* clear whole buffer */ - memset(map, clear, width * height); - } - else { - /* clear scissored */ - for (i = 0; i < height; i++) { - memset(map, clear, width); - map += rowStride; - } - } - } - break; - case MESA_FORMAT_Z24_UNORM_S8_UINT: - { - GLuint clear = (ctx->Stencil.Clear & writeMask & 0xff) << 24; - GLuint mask = (((~writeMask) & 0xff) << 24) | 0xffffff; - for (i = 0; i < height; i++) { - GLuint *row = (GLuint *) map; - for (j = 0; j < width; j++) { - row[j] = (row[j] & mask) | clear; - } - map += rowStride; - } - } - break; - case MESA_FORMAT_S8_UINT_Z24_UNORM: - { - GLuint clear = ctx->Stencil.Clear & writeMask & 0xff; - GLuint mask = 0xffffff00 | ((~writeMask) & 0xff); - for (i = 0; i < height; i++) { - GLuint *row = (GLuint *) map; - for (j = 0; j < width; j++) { - row[j] = (row[j] & mask) | clear; - } - map += rowStride; - } - } - break; - default: - _mesa_problem(ctx, "Unexpected stencil buffer format %s" - " in _swrast_clear_stencil_buffer()", - _mesa_get_format_name(rb->Format)); - } - - ctx->Driver.UnmapRenderbuffer(ctx, rb); -} diff --git a/src/mesa/swrast/s_stencil.h b/src/mesa/swrast/s_stencil.h deleted file mode 100644 index 369e7c3..0000000 --- a/src/mesa/swrast/s_stencil.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -#ifndef S_STENCIL_H -#define S_STENCIL_H - - -#include "main/mtypes.h" -#include "s_span.h" - - - -extern GLboolean -_swrast_stencil_and_ztest_span(struct gl_context *ctx, SWspan *span); - - -extern void -_swrast_read_stencil_span(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLint n, GLint x, GLint y, GLubyte stencil[]); - - -extern void -_swrast_write_stencil_span( struct gl_context *ctx, GLint n, GLint x, GLint y, - const GLubyte stencil[] ); - - -extern void -_swrast_clear_stencil_buffer(struct gl_context *ctx); - - -#endif diff --git a/src/mesa/swrast/s_texcombine.c b/src/mesa/swrast/s_texcombine.c deleted file mode 100644 index 4e177ce..0000000 --- a/src/mesa/swrast/s_texcombine.c +++ /dev/null @@ -1,721 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. - * Copyright (C) 2009 VMware, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -#include "main/glheader.h" -#include "main/context.h" - -#include "main/macros.h" -#include "main/pixeltransfer.h" -#include "main/samplerobj.h" -#include "program/prog_instruction.h" - -#include "s_context.h" -#include "s_texcombine.h" - - -/** - * Pointer to array of float[4] - * This type makes the code below more concise and avoids a lot of casting. - */ -typedef float (*float4_array)[4]; - - -/** - * Return array of texels for given unit. - */ -static inline float4_array -get_texel_array(SWcontext *swrast, GLuint unit) -{ -#ifdef _OPENMP - return (float4_array) (swrast->TexelBuffer + unit * SWRAST_MAX_WIDTH * 4 * omp_get_num_threads() + (SWRAST_MAX_WIDTH * 4 * omp_get_thread_num())); -#else - return (float4_array) (swrast->TexelBuffer + unit * SWRAST_MAX_WIDTH * 4); -#endif -} - - - -/** - * Do texture application for: - * GL_EXT_texture_env_combine - * GL_ARB_texture_env_combine - * GL_EXT_texture_env_dot3 - * GL_ARB_texture_env_dot3 - * GL_ATI_texture_env_combine3 - * GL_NV_texture_env_combine4 - * conventional GL texture env modes - * - * \param ctx rendering context - * \param unit the texture combiner unit - * \param primary_rgba incoming fragment color array - * \param texelBuffer pointer to texel colors for all texture units - * - * \param span two fields are used in this function: - * span->end: number of fragments to process - * span->array->rgba: incoming/result fragment colors - */ -static void -texture_combine( struct gl_context *ctx, GLuint unit, - const float4_array primary_rgba, - const GLfloat *texelBuffer, - SWspan *span ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - const struct gl_fixedfunc_texture_unit *textureUnit = - &ctx->Texture.FixedFuncUnit[unit]; - const struct gl_tex_env_combine_state *combine = textureUnit->_CurrentCombine; - float4_array argRGB[MAX_COMBINER_TERMS]; - float4_array argA[MAX_COMBINER_TERMS]; - const GLfloat scaleRGB = (GLfloat) (1 << combine->ScaleShiftRGB); - const GLfloat scaleA = (GLfloat) (1 << combine->ScaleShiftA); - const GLuint numArgsRGB = combine->_NumArgsRGB; - const GLuint numArgsA = combine->_NumArgsA; - float4_array ccolor[4], rgba; - GLuint i, term; - GLuint n = span->end; - GLchan (*rgbaChan)[4] = span->array->rgba; - - /* alloc temp pixel buffers */ - rgba = malloc(4 * n * sizeof(GLfloat)); - if (!rgba) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture_combine"); - return; - } - - for (i = 0; i < numArgsRGB || i < numArgsA; i++) { - ccolor[i] = malloc(4 * n * sizeof(GLfloat)); - if (!ccolor[i]) { - while (i) { - free(ccolor[i]); - i--; - } - _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture_combine"); - free(rgba); - return; - } - } - - for (i = 0; i < n; i++) { - rgba[i][RCOMP] = CHAN_TO_FLOAT(rgbaChan[i][RCOMP]); - rgba[i][GCOMP] = CHAN_TO_FLOAT(rgbaChan[i][GCOMP]); - rgba[i][BCOMP] = CHAN_TO_FLOAT(rgbaChan[i][BCOMP]); - rgba[i][ACOMP] = CHAN_TO_FLOAT(rgbaChan[i][ACOMP]); - } - - /* - printf("modeRGB 0x%x modeA 0x%x srcRGB1 0x%x srcA1 0x%x srcRGB2 0x%x srcA2 0x%x\n", - combine->ModeRGB, - combine->ModeA, - combine->SourceRGB[0], - combine->SourceA[0], - combine->SourceRGB[1], - combine->SourceA[1]); - */ - - /* - * Do operand setup for up to 4 operands. Loop over the terms. - */ - for (term = 0; term < numArgsRGB; term++) { - const GLenum srcRGB = combine->SourceRGB[term]; - const GLenum operandRGB = combine->OperandRGB[term]; - - switch (srcRGB) { - case GL_TEXTURE: - argRGB[term] = get_texel_array(swrast, unit); - break; - case GL_PRIMARY_COLOR: - argRGB[term] = primary_rgba; - break; - case GL_PREVIOUS: - argRGB[term] = rgba; - break; - case GL_CONSTANT: - { - float4_array c = ccolor[term]; - GLfloat red = textureUnit->EnvColor[0]; - GLfloat green = textureUnit->EnvColor[1]; - GLfloat blue = textureUnit->EnvColor[2]; - GLfloat alpha = textureUnit->EnvColor[3]; - for (i = 0; i < n; i++) { - ASSIGN_4V(c[i], red, green, blue, alpha); - } - argRGB[term] = ccolor[term]; - } - break; - /* GL_ATI_texture_env_combine3 allows GL_ZERO & GL_ONE as sources. - */ - case GL_ZERO: - { - float4_array c = ccolor[term]; - for (i = 0; i < n; i++) { - ASSIGN_4V(c[i], 0.0F, 0.0F, 0.0F, 0.0F); - } - argRGB[term] = ccolor[term]; - } - break; - case GL_ONE: - { - float4_array c = ccolor[term]; - for (i = 0; i < n; i++) { - ASSIGN_4V(c[i], 1.0F, 1.0F, 1.0F, 1.0F); - } - argRGB[term] = ccolor[term]; - } - break; - default: - /* ARB_texture_env_crossbar source */ - { - const GLuint srcUnit = srcRGB - GL_TEXTURE0; - assert(srcUnit < ctx->Const.MaxTextureUnits); - if (!ctx->Texture.Unit[srcUnit]._Current) - goto end; - argRGB[term] = get_texel_array(swrast, srcUnit); - } - } - - if (operandRGB != GL_SRC_COLOR) { - float4_array src = argRGB[term]; - float4_array dst = ccolor[term]; - - /* point to new arg[term] storage */ - argRGB[term] = ccolor[term]; - - switch (operandRGB) { - case GL_ONE_MINUS_SRC_COLOR: - for (i = 0; i < n; i++) { - dst[i][RCOMP] = 1.0F - src[i][RCOMP]; - dst[i][GCOMP] = 1.0F - src[i][GCOMP]; - dst[i][BCOMP] = 1.0F - src[i][BCOMP]; - } - break; - case GL_SRC_ALPHA: - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = src[i][ACOMP]; - } - break; - case GL_ONE_MINUS_SRC_ALPHA: - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = 1.0F - src[i][ACOMP]; - } - break; - default: - _mesa_problem(ctx, "Bad operandRGB"); - } - } - } - - /* - * Set up the argA[term] pointers - */ - for (term = 0; term < numArgsA; term++) { - const GLenum srcA = combine->SourceA[term]; - const GLenum operandA = combine->OperandA[term]; - - switch (srcA) { - case GL_TEXTURE: - argA[term] = get_texel_array(swrast, unit); - break; - case GL_PRIMARY_COLOR: - argA[term] = primary_rgba; - break; - case GL_PREVIOUS: - argA[term] = rgba; - break; - case GL_CONSTANT: - { - float4_array c = ccolor[term]; - GLfloat alpha = textureUnit->EnvColor[3]; - for (i = 0; i < n; i++) - c[i][ACOMP] = alpha; - argA[term] = ccolor[term]; - } - break; - /* GL_ATI_texture_env_combine3 allows GL_ZERO & GL_ONE as sources. - */ - case GL_ZERO: - { - float4_array c = ccolor[term]; - for (i = 0; i < n; i++) - c[i][ACOMP] = 0.0F; - argA[term] = ccolor[term]; - } - break; - case GL_ONE: - { - float4_array c = ccolor[term]; - for (i = 0; i < n; i++) - c[i][ACOMP] = 1.0F; - argA[term] = ccolor[term]; - } - break; - default: - /* ARB_texture_env_crossbar source */ - { - const GLuint srcUnit = srcA - GL_TEXTURE0; - assert(srcUnit < ctx->Const.MaxTextureUnits); - if (!ctx->Texture.Unit[srcUnit]._Current) - goto end; - argA[term] = get_texel_array(swrast, srcUnit); - } - } - - if (operandA == GL_ONE_MINUS_SRC_ALPHA) { - float4_array src = argA[term]; - float4_array dst = ccolor[term]; - argA[term] = ccolor[term]; - for (i = 0; i < n; i++) { - dst[i][ACOMP] = 1.0F - src[i][ACOMP]; - } - } - } - - /* RGB channel combine */ - { - float4_array arg0 = argRGB[0]; - float4_array arg1 = argRGB[1]; - float4_array arg2 = argRGB[2]; - float4_array arg3 = argRGB[3]; - - switch (combine->ModeRGB) { - case GL_REPLACE: - for (i = 0; i < n; i++) { - rgba[i][RCOMP] = arg0[i][RCOMP] * scaleRGB; - rgba[i][GCOMP] = arg0[i][GCOMP] * scaleRGB; - rgba[i][BCOMP] = arg0[i][BCOMP] * scaleRGB; - } - break; - case GL_MODULATE: - for (i = 0; i < n; i++) { - rgba[i][RCOMP] = arg0[i][RCOMP] * arg1[i][RCOMP] * scaleRGB; - rgba[i][GCOMP] = arg0[i][GCOMP] * arg1[i][GCOMP] * scaleRGB; - rgba[i][BCOMP] = arg0[i][BCOMP] * arg1[i][BCOMP] * scaleRGB; - } - break; - case GL_ADD: - if (textureUnit->EnvMode == GL_COMBINE4_NV) { - /* (a * b) + (c * d) */ - for (i = 0; i < n; i++) { - rgba[i][RCOMP] = (arg0[i][RCOMP] * arg1[i][RCOMP] + - arg2[i][RCOMP] * arg3[i][RCOMP]) * scaleRGB; - rgba[i][GCOMP] = (arg0[i][GCOMP] * arg1[i][GCOMP] + - arg2[i][GCOMP] * arg3[i][GCOMP]) * scaleRGB; - rgba[i][BCOMP] = (arg0[i][BCOMP] * arg1[i][BCOMP] + - arg2[i][BCOMP] * arg3[i][BCOMP]) * scaleRGB; - } - } - else { - /* 2-term addition */ - for (i = 0; i < n; i++) { - rgba[i][RCOMP] = (arg0[i][RCOMP] + arg1[i][RCOMP]) * scaleRGB; - rgba[i][GCOMP] = (arg0[i][GCOMP] + arg1[i][GCOMP]) * scaleRGB; - rgba[i][BCOMP] = (arg0[i][BCOMP] + arg1[i][BCOMP]) * scaleRGB; - } - } - break; - case GL_ADD_SIGNED: - if (textureUnit->EnvMode == GL_COMBINE4_NV) { - /* (a * b) + (c * d) - 0.5 */ - for (i = 0; i < n; i++) { - rgba[i][RCOMP] = (arg0[i][RCOMP] * arg1[i][RCOMP] + - arg2[i][RCOMP] * arg3[i][RCOMP] - 0.5F) * scaleRGB; - rgba[i][GCOMP] = (arg0[i][GCOMP] * arg1[i][GCOMP] + - arg2[i][GCOMP] * arg3[i][GCOMP] - 0.5F) * scaleRGB; - rgba[i][BCOMP] = (arg0[i][BCOMP] * arg1[i][BCOMP] + - arg2[i][BCOMP] * arg3[i][BCOMP] - 0.5F) * scaleRGB; - } - } - else { - for (i = 0; i < n; i++) { - rgba[i][RCOMP] = (arg0[i][RCOMP] + arg1[i][RCOMP] - 0.5F) * scaleRGB; - rgba[i][GCOMP] = (arg0[i][GCOMP] + arg1[i][GCOMP] - 0.5F) * scaleRGB; - rgba[i][BCOMP] = (arg0[i][BCOMP] + arg1[i][BCOMP] - 0.5F) * scaleRGB; - } - } - break; - case GL_INTERPOLATE: - for (i = 0; i < n; i++) { - rgba[i][RCOMP] = (arg0[i][RCOMP] * arg2[i][RCOMP] + - arg1[i][RCOMP] * (1.0F - arg2[i][RCOMP])) * scaleRGB; - rgba[i][GCOMP] = (arg0[i][GCOMP] * arg2[i][GCOMP] + - arg1[i][GCOMP] * (1.0F - arg2[i][GCOMP])) * scaleRGB; - rgba[i][BCOMP] = (arg0[i][BCOMP] * arg2[i][BCOMP] + - arg1[i][BCOMP] * (1.0F - arg2[i][BCOMP])) * scaleRGB; - } - break; - case GL_SUBTRACT: - for (i = 0; i < n; i++) { - rgba[i][RCOMP] = (arg0[i][RCOMP] - arg1[i][RCOMP]) * scaleRGB; - rgba[i][GCOMP] = (arg0[i][GCOMP] - arg1[i][GCOMP]) * scaleRGB; - rgba[i][BCOMP] = (arg0[i][BCOMP] - arg1[i][BCOMP]) * scaleRGB; - } - break; - case GL_DOT3_RGB_EXT: - case GL_DOT3_RGBA_EXT: - /* Do not scale the result by 1 2 or 4 */ - for (i = 0; i < n; i++) { - GLfloat dot = ((arg0[i][RCOMP] - 0.5F) * (arg1[i][RCOMP] - 0.5F) + - (arg0[i][GCOMP] - 0.5F) * (arg1[i][GCOMP] - 0.5F) + - (arg0[i][BCOMP] - 0.5F) * (arg1[i][BCOMP] - 0.5F)) - * 4.0F; - dot = CLAMP(dot, 0.0F, 1.0F); - rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = dot; - } - break; - case GL_DOT3_RGB: - case GL_DOT3_RGBA: - /* DO scale the result by 1 2 or 4 */ - for (i = 0; i < n; i++) { - GLfloat dot = ((arg0[i][RCOMP] - 0.5F) * (arg1[i][RCOMP] - 0.5F) + - (arg0[i][GCOMP] - 0.5F) * (arg1[i][GCOMP] - 0.5F) + - (arg0[i][BCOMP] - 0.5F) * (arg1[i][BCOMP] - 0.5F)) - * 4.0F * scaleRGB; - dot = CLAMP(dot, 0.0F, 1.0F); - rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = dot; - } - break; - case GL_MODULATE_ADD_ATI: - for (i = 0; i < n; i++) { - rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) + - arg1[i][RCOMP]) * scaleRGB; - rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) + - arg1[i][GCOMP]) * scaleRGB; - rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) + - arg1[i][BCOMP]) * scaleRGB; - } - break; - case GL_MODULATE_SIGNED_ADD_ATI: - for (i = 0; i < n; i++) { - rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) + - arg1[i][RCOMP] - 0.5F) * scaleRGB; - rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) + - arg1[i][GCOMP] - 0.5F) * scaleRGB; - rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) + - arg1[i][BCOMP] - 0.5F) * scaleRGB; - } - break; - case GL_MODULATE_SUBTRACT_ATI: - for (i = 0; i < n; i++) { - rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) - - arg1[i][RCOMP]) * scaleRGB; - rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) - - arg1[i][GCOMP]) * scaleRGB; - rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) - - arg1[i][BCOMP]) * scaleRGB; - } - break; - default: - _mesa_problem(ctx, "invalid combine mode"); - } - } - - /* Alpha channel combine */ - { - float4_array arg0 = argA[0]; - float4_array arg1 = argA[1]; - float4_array arg2 = argA[2]; - float4_array arg3 = argA[3]; - - switch (combine->ModeA) { - case GL_REPLACE: - for (i = 0; i < n; i++) { - rgba[i][ACOMP] = arg0[i][ACOMP] * scaleA; - } - break; - case GL_MODULATE: - for (i = 0; i < n; i++) { - rgba[i][ACOMP] = arg0[i][ACOMP] * arg1[i][ACOMP] * scaleA; - } - break; - case GL_ADD: - if (textureUnit->EnvMode == GL_COMBINE4_NV) { - /* (a * b) + (c * d) */ - for (i = 0; i < n; i++) { - rgba[i][ACOMP] = (arg0[i][ACOMP] * arg1[i][ACOMP] + - arg2[i][ACOMP] * arg3[i][ACOMP]) * scaleA; - } - } - else { - /* two-term add */ - for (i = 0; i < n; i++) { - rgba[i][ACOMP] = (arg0[i][ACOMP] + arg1[i][ACOMP]) * scaleA; - } - } - break; - case GL_ADD_SIGNED: - if (textureUnit->EnvMode == GL_COMBINE4_NV) { - /* (a * b) + (c * d) - 0.5 */ - for (i = 0; i < n; i++) { - rgba[i][ACOMP] = (arg0[i][ACOMP] * arg1[i][ACOMP] + - arg2[i][ACOMP] * arg3[i][ACOMP] - - 0.5F) * scaleA; - } - } - else { - /* a + b - 0.5 */ - for (i = 0; i < n; i++) { - rgba[i][ACOMP] = (arg0[i][ACOMP] + arg1[i][ACOMP] - 0.5F) * scaleA; - } - } - break; - case GL_INTERPOLATE: - for (i = 0; i < n; i++) { - rgba[i][ACOMP] = (arg0[i][ACOMP] * arg2[i][ACOMP] + - arg1[i][ACOMP] * (1.0F - arg2[i][ACOMP])) - * scaleA; - } - break; - case GL_SUBTRACT: - for (i = 0; i < n; i++) { - rgba[i][ACOMP] = (arg0[i][ACOMP] - arg1[i][ACOMP]) * scaleA; - } - break; - case GL_MODULATE_ADD_ATI: - for (i = 0; i < n; i++) { - rgba[i][ACOMP] = ((arg0[i][ACOMP] * arg2[i][ACOMP]) - + arg1[i][ACOMP]) * scaleA; - } - break; - case GL_MODULATE_SIGNED_ADD_ATI: - for (i = 0; i < n; i++) { - rgba[i][ACOMP] = ((arg0[i][ACOMP] * arg2[i][ACOMP]) + - arg1[i][ACOMP] - 0.5F) * scaleA; - } - break; - case GL_MODULATE_SUBTRACT_ATI: - for (i = 0; i < n; i++) { - rgba[i][ACOMP] = ((arg0[i][ACOMP] * arg2[i][ACOMP]) - - arg1[i][ACOMP]) * scaleA; - } - break; - default: - _mesa_problem(ctx, "invalid combine mode"); - } - } - - /* Fix the alpha component for GL_DOT3_RGBA_EXT/ARB combining. - * This is kind of a kludge. It would have been better if the spec - * were written such that the GL_COMBINE_ALPHA value could be set to - * GL_DOT3. - */ - if (combine->ModeRGB == GL_DOT3_RGBA_EXT || - combine->ModeRGB == GL_DOT3_RGBA) { - for (i = 0; i < n; i++) { - rgba[i][ACOMP] = rgba[i][RCOMP]; - } - } - - for (i = 0; i < n; i++) { - UNCLAMPED_FLOAT_TO_CHAN(rgbaChan[i][RCOMP], rgba[i][RCOMP]); - UNCLAMPED_FLOAT_TO_CHAN(rgbaChan[i][GCOMP], rgba[i][GCOMP]); - UNCLAMPED_FLOAT_TO_CHAN(rgbaChan[i][BCOMP], rgba[i][BCOMP]); - UNCLAMPED_FLOAT_TO_CHAN(rgbaChan[i][ACOMP], rgba[i][ACOMP]); - } - /* The span->array->rgba values are of CHAN type so set - * span->array->ChanType field accordingly. - */ - span->array->ChanType = CHAN_TYPE; - -end: - for (i = 0; i < numArgsRGB || i < numArgsA; i++) { - free(ccolor[i]); - } - free(rgba); -} - - -/** - * Apply X/Y/Z/W/0/1 swizzle to an array of colors/texels. - * See GL_EXT_texture_swizzle. - */ -static void -swizzle_texels(GLuint swizzle, GLuint count, float4_array texels) -{ - const GLuint swzR = GET_SWZ(swizzle, 0); - const GLuint swzG = GET_SWZ(swizzle, 1); - const GLuint swzB = GET_SWZ(swizzle, 2); - const GLuint swzA = GET_SWZ(swizzle, 3); - GLfloat vector[6]; - GLuint i; - - vector[SWIZZLE_ZERO] = 0; - vector[SWIZZLE_ONE] = 1.0F; - - for (i = 0; i < count; i++) { - vector[SWIZZLE_X] = texels[i][0]; - vector[SWIZZLE_Y] = texels[i][1]; - vector[SWIZZLE_Z] = texels[i][2]; - vector[SWIZZLE_W] = texels[i][3]; - texels[i][RCOMP] = vector[swzR]; - texels[i][GCOMP] = vector[swzG]; - texels[i][BCOMP] = vector[swzB]; - texels[i][ACOMP] = vector[swzA]; - } -} - - -/** - * Apply texture mapping to a span of fragments. - */ -void -_swrast_texture_span( struct gl_context *ctx, SWspan *span ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - float4_array primary_rgba; - GLuint unit; - - if (!swrast->TexelBuffer) { -#ifdef _OPENMP - const GLint maxThreads = omp_get_max_threads(); - - /* TexelBuffer memory allocation needs to be done in a critical section - * as this code runs in a parallel loop. - * When entering the section, first check if TexelBuffer has been - * initialized already by another thread while this thread was waiting. - */ - #pragma omp critical - if (!swrast->TexelBuffer) { -#else - const GLint maxThreads = 1; -#endif - - /* TexelBuffer is also global and normally shared by all SWspan - * instances; when running with multiple threads, create one per - * thread. - */ - swrast->TexelBuffer = - malloc(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits * maxThreads * - SWRAST_MAX_WIDTH * 4 * sizeof(GLfloat)); -#ifdef _OPENMP - } /* critical section */ -#endif - - if (!swrast->TexelBuffer) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture_combine"); - return; - } - } - - primary_rgba = malloc(span->end * 4 * sizeof(GLfloat)); - - if (!primary_rgba) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture_span"); - return; - } - - assert(span->end <= SWRAST_MAX_WIDTH); - - /* - * Save copy of the incoming fragment colors (the GL_PRIMARY_COLOR) - */ - if (swrast->_TextureCombinePrimary) { - GLuint i; - for (i = 0; i < span->end; i++) { - primary_rgba[i][RCOMP] = CHAN_TO_FLOAT(span->array->rgba[i][RCOMP]); - primary_rgba[i][GCOMP] = CHAN_TO_FLOAT(span->array->rgba[i][GCOMP]); - primary_rgba[i][BCOMP] = CHAN_TO_FLOAT(span->array->rgba[i][BCOMP]); - primary_rgba[i][ACOMP] = CHAN_TO_FLOAT(span->array->rgba[i][ACOMP]); - } - } - - /* - * Must do all texture sampling before combining in order to - * accommodate GL_ARB_texture_env_crossbar. - */ - for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { - const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; - if (texUnit->_Current) { - const GLfloat (*texcoords)[4] = (const GLfloat (*)[4]) - span->array->attribs[VARYING_SLOT_TEX0 + unit]; - const struct gl_texture_object *curObj = texUnit->_Current; - const struct gl_sampler_object *samp = _mesa_get_samplerobj(ctx, unit); - GLfloat *lambda = span->array->lambda[unit]; - float4_array texels = get_texel_array(swrast, unit); - - /* adjust texture lod (lambda) */ - if (span->arrayMask & SPAN_LAMBDA) { - if (texUnit->LodBias + samp->Attrib.LodBias != 0.0F) { - /* apply LOD bias, but don't clamp yet */ - const GLfloat bias = CLAMP(texUnit->LodBias + samp->Attrib.LodBias, - -ctx->Const.MaxTextureLodBias, - ctx->Const.MaxTextureLodBias); - GLuint i; - for (i = 0; i < span->end; i++) { - lambda[i] += bias; - } - } - - if (samp->Attrib.MinLod != -1000.0F || - samp->Attrib.MaxLod != 1000.0F) { - /* apply LOD clamping to lambda */ - const GLfloat min = samp->Attrib.MinLod; - const GLfloat max = samp->Attrib.MaxLod; - GLuint i; - for (i = 0; i < span->end; i++) { - GLfloat l = lambda[i]; - lambda[i] = CLAMP(l, min, max); - } - } - } - else if (samp->Attrib.MaxAnisotropy > 1.0F && - samp->Attrib.MinFilter == GL_LINEAR_MIPMAP_LINEAR) { - /* sample_lambda_2d_aniso is beeing used as texture_sample_func, - * it requires the current SWspan *span as an additional parameter. - * In order to keep the same function signature, the unused lambda - * parameter will be modified to actually contain the SWspan pointer. - * This is a Hack. To make it right, the texture_sample_func - * signature and all implementing functions need to be modified. - */ - /* "hide" SWspan struct; cast to (GLfloat *) to suppress warning */ - lambda = (GLfloat *)span; - } - - /* Sample the texture (span->end = number of fragments) */ - swrast->TextureSample[unit]( ctx, samp, - ctx->Texture.Unit[unit]._Current, - span->end, texcoords, lambda, texels ); - - /* GL_EXT_texture_swizzle */ - if (curObj->Attrib._Swizzle != SWIZZLE_NOOP) { - swizzle_texels(curObj->Attrib._Swizzle, span->end, texels); - } - } - } - - /* - * OK, now apply the texture (aka texture combine/blend). - * We modify the span->color.rgba values. - */ - for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { - if (ctx->Texture.Unit[unit]._Current) - texture_combine(ctx, unit, primary_rgba, swrast->TexelBuffer, span); - } - - free(primary_rgba); -} diff --git a/src/mesa/swrast/s_texcombine.h b/src/mesa/swrast/s_texcombine.h deleted file mode 100644 index e253837..0000000 --- a/src/mesa/swrast/s_texcombine.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -#ifndef S_TEXCOMBINE_H -#define S_TEXCOMBINE_H - - -#include "s_span.h" - -struct gl_context; - -extern void -_swrast_texture_span( struct gl_context *ctx, SWspan *span ); - -#endif diff --git a/src/mesa/swrast/s_texfetch.c b/src/mesa/swrast/s_texfetch.c deleted file mode 100644 index 5963948..0000000 --- a/src/mesa/swrast/s_texfetch.c +++ /dev/null @@ -1,368 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. - * Copyright (c) 2009 VMware, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -/** - * \file s_texfetch.c - * - * Texel fetch/store functions - * - * \author Gareth Hughes - */ - - -#include "main/errors.h" -#include "main/macros.h" -#include "main/texcompress.h" -#include "main/texcompress_fxt1.h" -#include "main/texcompress_s3tc.h" -#include "main/texcompress_rgtc.h" -#include "main/texcompress_etc.h" -#include "main/teximage.h" -#include "main/samplerobj.h" -#include "s_context.h" -#include "s_texfetch.h" -#include "util/format_rgb9e5.h" -#include "util/format_r11g11b10f.h" -#include "util/format_srgb.h" - - -/* Texel fetch routines for all supported formats - */ -#define DIM 1 -#include "s_texfetch_tmp.h" - -#define DIM 2 -#include "s_texfetch_tmp.h" - -#define DIM 3 -#include "s_texfetch_tmp.h" - - -/** - * All compressed texture texel fetching is done though this function. - * Basically just call a core-Mesa texel fetch function. - */ -static void -fetch_compressed(const struct swrast_texture_image *swImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - /* The FetchCompressedTexel function takes an integer pixel rowstride, - * while the image's rowstride is bytes per row of blocks. - */ - GLuint bw, bh; - GLuint texelBytes = _mesa_get_format_bytes(swImage->Base.TexFormat); - _mesa_get_format_block_size(swImage->Base.TexFormat, &bw, &bh); - assert(swImage->RowStride * bw % texelBytes == 0); - - swImage->FetchCompressedTexel(swImage->ImageSlices[k], - swImage->RowStride * bw / texelBytes, - i, j, texel); -} - - - -/** - * Null texel fetch function. - * - * Have to have this so the FetchTexel function pointer is never NULL. - */ -static void fetch_null_texelf( const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel ) -{ - (void) texImage; (void) i; (void) j; (void) k; - texel[RCOMP] = 0.0; - texel[GCOMP] = 0.0; - texel[BCOMP] = 0.0; - texel[ACOMP] = 0.0; - _mesa_warning(NULL, "fetch_null_texelf() called!"); -} - - -#define FETCH_FUNCS(NAME) \ - [MESA_FORMAT_ ## NAME] = { \ - fetch_texel_1d_ ## NAME, \ - fetch_texel_2d_ ## NAME, \ - fetch_texel_3d_ ## NAME, \ - } - -#define FETCH_COMPRESSED(NAME) \ - [MESA_FORMAT_ ## NAME] = { \ - fetch_compressed, \ - fetch_compressed, \ - fetch_compressed \ - } - -/** - * Table to map MESA_FORMAT_ to texel fetch/store funcs. - */ -static struct { - FetchTexelFunc Fetch1D; - FetchTexelFunc Fetch2D; - FetchTexelFunc Fetch3D; -} -texfetch_funcs[] = -{ - /* Packed unorm formats */ - FETCH_FUNCS(A8B8G8R8_UNORM), - FETCH_FUNCS(X8B8G8R8_UNORM), - FETCH_FUNCS(R8G8B8A8_UNORM), - FETCH_FUNCS(R8G8B8X8_UNORM), - FETCH_FUNCS(B8G8R8A8_UNORM), - FETCH_FUNCS(B8G8R8X8_UNORM), - FETCH_FUNCS(A8R8G8B8_UNORM), - FETCH_FUNCS(X8R8G8B8_UNORM), - FETCH_FUNCS(B5G6R5_UNORM), - FETCH_FUNCS(R5G6B5_UNORM), - FETCH_FUNCS(B4G4R4A4_UNORM), - FETCH_FUNCS(A4R4G4B4_UNORM), - FETCH_FUNCS(A1B5G5R5_UNORM), - FETCH_FUNCS(B5G5R5A1_UNORM), - FETCH_FUNCS(A1R5G5B5_UNORM), - FETCH_FUNCS(L4A4_UNORM), - FETCH_FUNCS(B2G3R3_UNORM), - FETCH_FUNCS(B10G10R10A2_UNORM), - FETCH_FUNCS(R10G10B10A2_UNORM), - - FETCH_FUNCS(S8_UINT_Z24_UNORM), - [MESA_FORMAT_X8_UINT_Z24_UNORM] = { - fetch_texel_1d_S8_UINT_Z24_UNORM, - fetch_texel_2d_S8_UINT_Z24_UNORM, - fetch_texel_3d_S8_UINT_Z24_UNORM - }, - FETCH_FUNCS(Z24_UNORM_S8_UINT), - [MESA_FORMAT_Z24_UNORM_X8_UINT] = { - fetch_texel_1d_Z24_UNORM_S8_UINT, - fetch_texel_2d_Z24_UNORM_S8_UINT, - fetch_texel_3d_Z24_UNORM_S8_UINT - }, - - FETCH_FUNCS(YCBCR), - FETCH_FUNCS(YCBCR_REV), - - /* Array unorm formats */ - FETCH_FUNCS(A_UNORM8), - FETCH_FUNCS(A_UNORM16), - FETCH_FUNCS(L_UNORM8), - FETCH_FUNCS(L_UNORM16), - FETCH_FUNCS(LA_UNORM8), - FETCH_FUNCS(LA_UNORM16), - FETCH_FUNCS(I_UNORM8), - FETCH_FUNCS(I_UNORM16), - FETCH_FUNCS(R_UNORM8), - FETCH_FUNCS(R_UNORM16), - FETCH_FUNCS(RG_UNORM8), - FETCH_FUNCS(RG_UNORM16), - FETCH_FUNCS(BGR_UNORM8), - FETCH_FUNCS(RGB_UNORM8), - FETCH_FUNCS(RGBA_UNORM16), - FETCH_FUNCS(RGBX_UNORM16), - FETCH_FUNCS(Z_UNORM16), - FETCH_FUNCS(Z_UNORM32), - - /* Packed signed/normalized formats */ - FETCH_FUNCS(A8B8G8R8_SNORM), - FETCH_FUNCS(X8B8G8R8_SNORM), - FETCH_FUNCS(R8G8B8A8_SNORM), - - /* Array signed/normalized formats */ - FETCH_FUNCS(A_SNORM8), - FETCH_FUNCS(A_SNORM16), - FETCH_FUNCS(L_SNORM8), - FETCH_FUNCS(L_SNORM16), - FETCH_FUNCS(LA_SNORM8), - FETCH_FUNCS(LA_SNORM16), - FETCH_FUNCS(I_SNORM8), - FETCH_FUNCS(I_SNORM16), - FETCH_FUNCS(R_SNORM8), - FETCH_FUNCS(R_SNORM16), - FETCH_FUNCS(RG_SNORM8), - FETCH_FUNCS(RG_SNORM16), - FETCH_FUNCS(RGB_SNORM16), - FETCH_FUNCS(RGBA_SNORM16), - - /* Packed sRGB formats */ - FETCH_FUNCS(A8B8G8R8_SRGB), - FETCH_FUNCS(B8G8R8A8_SRGB), - FETCH_FUNCS(A8R8G8B8_SRGB), - FETCH_FUNCS(R8G8B8A8_SRGB), - FETCH_FUNCS(R8G8B8X8_SRGB), - FETCH_FUNCS(X8B8G8R8_SRGB), - - /* Array sRGB formats */ - FETCH_FUNCS(R_SRGB8), - FETCH_FUNCS(L_SRGB8), - FETCH_FUNCS(LA_SRGB8), - FETCH_FUNCS(BGR_SRGB8), - - /* Packed float formats */ - FETCH_FUNCS(R9G9B9E5_FLOAT), - FETCH_FUNCS(R11G11B10_FLOAT), - FETCH_FUNCS(Z32_FLOAT_S8X24_UINT), - - /* Array float formats */ - FETCH_FUNCS(A_FLOAT16), - FETCH_FUNCS(A_FLOAT32), - FETCH_FUNCS(L_FLOAT16), - FETCH_FUNCS(L_FLOAT32), - FETCH_FUNCS(LA_FLOAT16), - FETCH_FUNCS(LA_FLOAT32), - FETCH_FUNCS(I_FLOAT16), - FETCH_FUNCS(I_FLOAT32), - FETCH_FUNCS(R_FLOAT16), - FETCH_FUNCS(R_FLOAT32), - FETCH_FUNCS(RG_FLOAT16), - FETCH_FUNCS(RG_FLOAT32), - FETCH_FUNCS(RGB_FLOAT16), - FETCH_FUNCS(RGB_FLOAT32), - FETCH_FUNCS(RGBA_FLOAT16), - FETCH_FUNCS(RGBA_FLOAT32), - FETCH_FUNCS(RGBX_FLOAT16), - FETCH_FUNCS(RGBX_FLOAT32), - [MESA_FORMAT_Z_FLOAT32] = { - fetch_texel_1d_R_FLOAT32, /* Reuse the R32F functions. */ - fetch_texel_2d_R_FLOAT32, - fetch_texel_3d_R_FLOAT32 - }, - - /* Packed signed/unsigned non-normalized integer formats */ - - /* Array signed/unsigned non-normalized integer formats */ - FETCH_FUNCS(RGBA_UINT16), - FETCH_FUNCS(RGBA_UINT32), - FETCH_FUNCS(RGBA_SINT8), - FETCH_FUNCS(RGBA_SINT16), - FETCH_FUNCS(RGBA_SINT32), - - /* DXT compressed formats */ - FETCH_COMPRESSED(RGB_DXT1), - FETCH_COMPRESSED(RGBA_DXT1), - FETCH_COMPRESSED(RGBA_DXT3), - FETCH_COMPRESSED(RGBA_DXT5), - - /* DXT sRGB compressed formats */ - FETCH_COMPRESSED(SRGB_DXT1), - FETCH_COMPRESSED(SRGBA_DXT1), - FETCH_COMPRESSED(SRGBA_DXT3), - FETCH_COMPRESSED(SRGBA_DXT5), - - /* FXT1 compressed formats */ - FETCH_COMPRESSED(RGB_FXT1), - FETCH_COMPRESSED(RGBA_FXT1), - - /* RGTC compressed formats */ - FETCH_COMPRESSED(R_RGTC1_UNORM), - FETCH_COMPRESSED(R_RGTC1_SNORM), - FETCH_COMPRESSED(RG_RGTC2_UNORM), - FETCH_COMPRESSED(RG_RGTC2_SNORM), - - /* LATC1/2 compressed formats */ - FETCH_COMPRESSED(L_LATC1_UNORM), - FETCH_COMPRESSED(L_LATC1_SNORM), - FETCH_COMPRESSED(LA_LATC2_UNORM), - FETCH_COMPRESSED(LA_LATC2_SNORM), - - /* ETC1/2 compressed formats */ - FETCH_COMPRESSED(ETC1_RGB8), - FETCH_COMPRESSED(ETC2_RGB8), - FETCH_COMPRESSED(ETC2_SRGB8), - FETCH_COMPRESSED(ETC2_RGBA8_EAC), - FETCH_COMPRESSED(ETC2_SRGB8_ALPHA8_EAC), - FETCH_COMPRESSED(ETC2_R11_EAC), - FETCH_COMPRESSED(ETC2_RG11_EAC), - FETCH_COMPRESSED(ETC2_SIGNED_R11_EAC), - FETCH_COMPRESSED(ETC2_SIGNED_RG11_EAC), - FETCH_COMPRESSED(ETC2_RGB8_PUNCHTHROUGH_ALPHA1), - FETCH_COMPRESSED(ETC2_SRGB8_PUNCHTHROUGH_ALPHA1), - FETCH_COMPRESSED(BPTC_RGBA_UNORM), - FETCH_COMPRESSED(BPTC_SRGB_ALPHA_UNORM), - FETCH_COMPRESSED(BPTC_RGB_SIGNED_FLOAT), - FETCH_COMPRESSED(BPTC_RGB_UNSIGNED_FLOAT), -}; - - -/** - * Initialize the texture image's FetchTexel methods. - */ -static void -set_fetch_functions(const struct gl_sampler_object *samp, - struct swrast_texture_image *texImage, GLuint dims) -{ - mesa_format format = texImage->Base.TexFormat; - - if (samp->Attrib.sRGBDecode == GL_SKIP_DECODE_EXT) - format = _mesa_get_srgb_format_linear(format); - - texImage->FetchTexel = NULL; - - if (format < ARRAY_SIZE(texfetch_funcs)) { - switch (dims) { - case 1: - texImage->FetchTexel = texfetch_funcs[format].Fetch1D; - break; - case 2: - texImage->FetchTexel = texfetch_funcs[format].Fetch2D; - break; - case 3: - texImage->FetchTexel = texfetch_funcs[format].Fetch3D; - break; - default: - assert(!"Bad dims in set_fetch_functions()"); - } - } - - if (!texImage->FetchTexel) - texImage->FetchTexel = fetch_null_texelf; - - texImage->FetchCompressedTexel = _mesa_get_compressed_fetch_func(format); - - assert(texImage->FetchTexel); -} - -void -_mesa_update_fetch_functions(struct gl_context *ctx, GLuint unit) -{ - struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current; - struct gl_sampler_object *samp; - GLuint face, i; - GLuint dims; - - if (!texObj) - return; - - samp = _mesa_get_samplerobj(ctx, unit); - - dims = _mesa_get_texture_dimensions(texObj->Target); - - for (face = 0; face < 6; face++) { - for (i = 0; i < MAX_TEXTURE_LEVELS; i++) { - if (texObj->Image[face][i]) { - set_fetch_functions(samp, - swrast_texture_image(texObj->Image[face][i]), - dims); - } - } - } -} diff --git a/src/mesa/swrast/s_texfetch.h b/src/mesa/swrast/s_texfetch.h deleted file mode 100644 index 2a9fbb7..0000000 --- a/src/mesa/swrast/s_texfetch.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. - * Copyright (c) 2009 VMware, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -#ifndef S_TEXFETCH_H -#define S_TEXFETCH_H - -#include "swrast/s_context.h" - -void -_mesa_update_fetch_functions(struct gl_context *ctx, GLuint unit); - -#endif /* S_TEXFETCH_H */ diff --git a/src/mesa/swrast/s_texfetch_tmp.h b/src/mesa/swrast/s_texfetch_tmp.h deleted file mode 100644 index 06ff436..0000000 --- a/src/mesa/swrast/s_texfetch_tmp.h +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. - * Copyright (c) 2008-2009 VMware, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -/** - * \file texfetch_tmp.h - * Texel fetch functions template. - * - * This template file is used by texfetch.c to generate texel fetch functions - * for 1-D, 2-D and 3-D texture images. - * - * It should be expanded by defining \p DIM as the number texture dimensions - * (1, 2 or 3). According to the value of \p DIM a series of macros is defined - * for the texel lookup in the gl_texture_image::Data. - * - * \author Gareth Hughes - * \author Brian Paul - */ - -#include - -#if DIM == 1 - -#define TEXEL_ADDR( type, image, i, j, k, size ) \ - ((void) (j), (void) (k), ((type *)(image)->ImageSlices[0] + (i) * (size))) - -#define FETCH(x) fetch_texel_1d_##x - -#elif DIM == 2 - -#define TEXEL_ADDR( type, image, i, j, k, size ) \ - ((void) (k), \ - ((type *)((GLubyte *) (image)->ImageSlices[0] + (image)->RowStride * (j)) + \ - (i) * (size))) - -#define FETCH(x) fetch_texel_2d_##x - -#elif DIM == 3 - -#define TEXEL_ADDR( type, image, i, j, k, size ) \ - ((type *)((GLubyte *) (image)->ImageSlices[k] + \ - (image)->RowStride * (j)) + (i) * (size)) - -#define FETCH(x) fetch_texel_3d_##x - -#else -#error illegal number of texture dimensions -#endif - -#define FETCH_Z(x, type, size) \ - static void \ - FETCH(x) (const struct swrast_texture_image *texImage, \ - GLint i, GLint j, GLint k, GLfloat *texel) \ - { \ - const type *src = TEXEL_ADDR(type, texImage, i, j, k, size); \ - _mesa_unpack_float_z_row(MESA_FORMAT_##x, 1, src, texel); \ - } - -#define FETCH_RGBA(x, type, size) \ - static void \ - FETCH(x) (const struct swrast_texture_image *texImage, \ - GLint i, GLint j, GLint k, GLfloat *texel) \ - { \ - const type *src = TEXEL_ADDR(type, texImage, i, j, k, size); \ - _mesa_unpack_rgba_row(MESA_FORMAT_##x, 1, src, (GLvoid *)texel); \ - } - -FETCH_Z(Z_UNORM32, GLuint, 1) -FETCH_Z(Z_UNORM16, GLushort, 1) -FETCH_Z(S8_UINT_Z24_UNORM, GLuint, 1) /* only return Z, not stencil data */ -FETCH_Z(Z24_UNORM_S8_UINT, GLuint, 1) /* only return Z, not stencil data */ -FETCH_Z(Z32_FLOAT_S8X24_UINT, GLfloat, 2) - -FETCH_RGBA(RGBA_FLOAT32, GLfloat, 4) -FETCH_RGBA(RGBA_FLOAT16, GLhalfARB, 4) -FETCH_RGBA(RGB_FLOAT32, GLfloat, 3) -FETCH_RGBA(RGB_FLOAT16, GLhalfARB, 3) -FETCH_RGBA(A_FLOAT32, GLfloat, 1) -FETCH_RGBA(A_FLOAT16, GLhalfARB, 1) -FETCH_RGBA(L_FLOAT32, GLfloat, 1) -FETCH_RGBA(L_FLOAT16, GLhalfARB, 1) -FETCH_RGBA(LA_FLOAT32, GLfloat, 2) -FETCH_RGBA(LA_FLOAT16, GLhalfARB, 2) -FETCH_RGBA(I_FLOAT32, GLfloat, 1) -FETCH_RGBA(I_FLOAT16, GLhalfARB, 1) -FETCH_RGBA(R_FLOAT32, GLfloat, 1) -FETCH_RGBA(R_FLOAT16, GLhalfARB, 1) -FETCH_RGBA(RG_FLOAT32, GLfloat, 2) -FETCH_RGBA(RG_FLOAT16, GLhalfARB, 2) -FETCH_RGBA(A8B8G8R8_UNORM, GLuint, 1) -FETCH_RGBA(R8G8B8A8_UNORM, GLuint, 1) -FETCH_RGBA(B8G8R8A8_UNORM, GLuint, 1) -FETCH_RGBA(A8R8G8B8_UNORM, GLuint, 1) -FETCH_RGBA(X8B8G8R8_UNORM, GLuint, 1) -FETCH_RGBA(R8G8B8X8_UNORM, GLuint, 1) -FETCH_RGBA(B8G8R8X8_UNORM, GLuint, 1) -FETCH_RGBA(X8R8G8B8_UNORM, GLuint, 1) -FETCH_RGBA(BGR_UNORM8, GLubyte, 3) -FETCH_RGBA(RGB_UNORM8, GLubyte, 3) -FETCH_RGBA(B5G6R5_UNORM, GLushort, 1) -FETCH_RGBA(R5G6B5_UNORM, GLushort, 1) -FETCH_RGBA(B4G4R4A4_UNORM, GLushort, 1) -FETCH_RGBA(A4R4G4B4_UNORM, GLushort, 1) -FETCH_RGBA(A1B5G5R5_UNORM, GLushort, 1) -FETCH_RGBA(B5G5R5A1_UNORM, GLushort, 1) -FETCH_RGBA(A1R5G5B5_UNORM, GLushort, 1) -FETCH_RGBA(B10G10R10A2_UNORM, GLuint, 1) -FETCH_RGBA(R10G10B10A2_UNORM, GLuint, 1) -FETCH_RGBA(RG_UNORM8, GLubyte, 2) -FETCH_RGBA(L4A4_UNORM, GLubyte, 1) -FETCH_RGBA(R_UNORM8, GLubyte, 1) -FETCH_RGBA(R_UNORM16, GLushort, 1) -FETCH_RGBA(LA_UNORM8, GLubyte, 2) -FETCH_RGBA(RG_UNORM16, GLushort, 2) -FETCH_RGBA(B2G3R3_UNORM, GLubyte, 1) -FETCH_RGBA(A_UNORM8, GLubyte, 1) -FETCH_RGBA(A_UNORM16, GLushort, 1) -FETCH_RGBA(L_UNORM8, GLubyte, 1) -FETCH_RGBA(L_UNORM16, GLushort, 1) -FETCH_RGBA(LA_UNORM16, GLushort, 2) -FETCH_RGBA(I_UNORM8, GLubyte, 1) -FETCH_RGBA(I_UNORM16, GLushort, 1) -FETCH_RGBA(BGR_SRGB8, GLubyte, 3) -FETCH_RGBA(A8B8G8R8_SRGB, GLuint, 1) -FETCH_RGBA(B8G8R8A8_SRGB, GLuint, 1) -FETCH_RGBA(A8R8G8B8_SRGB, GLuint, 1) -FETCH_RGBA(R8G8B8A8_SRGB, GLuint, 1) -FETCH_RGBA(R8G8B8X8_SRGB, GLuint, 1) -FETCH_RGBA(X8B8G8R8_SRGB, GLuint, 1) -FETCH_RGBA(R_SRGB8, GLubyte, 1) -FETCH_RGBA(L_SRGB8, GLubyte, 1) -FETCH_RGBA(LA_SRGB8, GLubyte, 2) -FETCH_RGBA(RGBA_SINT8, GLbyte, 4) -FETCH_RGBA(RGBA_SINT16, GLshort, 4) -FETCH_RGBA(RGBA_SINT32, GLint, 4) -FETCH_RGBA(RGBA_UINT16, GLushort, 4) -FETCH_RGBA(RGBA_UINT32, GLuint, 4) -FETCH_RGBA(R_SNORM8, GLbyte, 1) -FETCH_RGBA(A_SNORM8, GLbyte, 1) -FETCH_RGBA(L_SNORM8, GLbyte, 1) -FETCH_RGBA(I_SNORM8, GLbyte, 1) -FETCH_RGBA(LA_SNORM8, GLbyte, 2) -FETCH_RGBA(RG_SNORM8, GLbyte, 2) -FETCH_RGBA(X8B8G8R8_SNORM, GLint, 1) -FETCH_RGBA(A8B8G8R8_SNORM, GLint, 1) -FETCH_RGBA(R8G8B8A8_SNORM, GLint, 1) -FETCH_RGBA(R_SNORM16, GLshort, 1) -FETCH_RGBA(A_SNORM16, GLshort, 1) -FETCH_RGBA(L_SNORM16, GLshort, 1) -FETCH_RGBA(I_SNORM16, GLshort, 1) -FETCH_RGBA(RG_SNORM16, GLshort, 2) -FETCH_RGBA(LA_SNORM16, GLshort, 2) -FETCH_RGBA(RGB_SNORM16, GLshort, 3) -FETCH_RGBA(RGBA_SNORM16, GLshort, 4) -FETCH_RGBA(RGBA_UNORM16, GLushort, 4) -FETCH_RGBA(RGBX_UNORM16, GLushort, 4) -FETCH_RGBA(RGBX_FLOAT16, GLhalfARB, 4) -FETCH_RGBA(RGBX_FLOAT32, GLfloat, 4) -FETCH_RGBA(YCBCR, GLushort, 1) /* Fetch texel from 1D, 2D or 3D ycbcr texture, returning RGBA. */ -FETCH_RGBA(YCBCR_REV, GLushort, 1) /* Fetch texel from 1D, 2D or 3D ycbcr texture, returning RGBA. */ -FETCH_RGBA(R9G9B9E5_FLOAT, GLuint, 1) -FETCH_RGBA(R11G11B10_FLOAT, GLuint, 1) - -#undef TEXEL_ADDR -#undef DIM -#undef FETCH -#undef FETCH_Z -#undef FETCH_RGBA diff --git a/src/mesa/swrast/s_texfilter.c b/src/mesa/swrast/s_texfilter.c deleted file mode 100644 index 4b4c3b7..0000000 --- a/src/mesa/swrast/s_texfilter.c +++ /dev/null @@ -1,3844 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -#include "c99_math.h" -#include "main/glheader.h" -#include "main/context.h" - -#include "main/macros.h" -#include "main/samplerobj.h" -#include "main/teximage.h" -#include "main/texobj.h" - -#include "s_context.h" -#include "s_texfilter.h" - - -/* - * Note, the FRAC macro has to work perfectly. Otherwise you'll sometimes - * see 1-pixel bands of improperly weighted linear-filtered textures. - * The tests/texwrap.c demo is a good test. - * Also note, FRAC(x) doesn't truly return the fractional part of x for x < 0. - * Instead, if x < 0 then FRAC(x) = 1 - true_frac(x). - */ -#define FRAC(f) ((f) - util_ifloor(f)) - - - -/** - * Linear interpolation macro - */ -#define LERP(T, A, B) ( (A) + (T) * ((B) - (A)) ) - - -/** - * Do 2D/biliner interpolation of float values. - * v00, v10, v01 and v11 are typically four texture samples in a square/box. - * a and b are the horizontal and vertical interpolants. - * It's important that this function is inlined when compiled with - * optimization! If we find that's not true on some systems, convert - * to a macro. - */ -static inline GLfloat -lerp_2d(GLfloat a, GLfloat b, - GLfloat v00, GLfloat v10, GLfloat v01, GLfloat v11) -{ - const GLfloat temp0 = LERP(a, v00, v10); - const GLfloat temp1 = LERP(a, v01, v11); - return LERP(b, temp0, temp1); -} - - -/** - * Do 3D/trilinear interpolation of float values. - * \sa lerp_2d - */ -static GLfloat -lerp_3d(GLfloat a, GLfloat b, GLfloat c, - GLfloat v000, GLfloat v100, GLfloat v010, GLfloat v110, - GLfloat v001, GLfloat v101, GLfloat v011, GLfloat v111) -{ - const GLfloat temp00 = LERP(a, v000, v100); - const GLfloat temp10 = LERP(a, v010, v110); - const GLfloat temp01 = LERP(a, v001, v101); - const GLfloat temp11 = LERP(a, v011, v111); - const GLfloat temp0 = LERP(b, temp00, temp10); - const GLfloat temp1 = LERP(b, temp01, temp11); - return LERP(c, temp0, temp1); -} - - -/** - * Do linear interpolation of colors. - */ -static void -lerp_rgba(GLfloat result[4], GLfloat t, const GLfloat a[4], const GLfloat b[4]) -{ - result[0] = LERP(t, a[0], b[0]); - result[1] = LERP(t, a[1], b[1]); - result[2] = LERP(t, a[2], b[2]); - result[3] = LERP(t, a[3], b[3]); -} - - -/** - * Do bilinear interpolation of colors. - */ -static void -lerp_rgba_2d(GLfloat result[4], GLfloat a, GLfloat b, - const GLfloat t00[4], const GLfloat t10[4], - const GLfloat t01[4], const GLfloat t11[4]) -{ - result[0] = lerp_2d(a, b, t00[0], t10[0], t01[0], t11[0]); - result[1] = lerp_2d(a, b, t00[1], t10[1], t01[1], t11[1]); - result[2] = lerp_2d(a, b, t00[2], t10[2], t01[2], t11[2]); - result[3] = lerp_2d(a, b, t00[3], t10[3], t01[3], t11[3]); -} - - -/** - * Do trilinear interpolation of colors. - */ -static void -lerp_rgba_3d(GLfloat result[4], GLfloat a, GLfloat b, GLfloat c, - const GLfloat t000[4], const GLfloat t100[4], - const GLfloat t010[4], const GLfloat t110[4], - const GLfloat t001[4], const GLfloat t101[4], - const GLfloat t011[4], const GLfloat t111[4]) -{ - GLuint k; - /* compiler should unroll these short loops */ - for (k = 0; k < 4; k++) { - result[k] = lerp_3d(a, b, c, t000[k], t100[k], t010[k], t110[k], - t001[k], t101[k], t011[k], t111[k]); - } -} - - -/** - * Used for GL_REPEAT wrap mode. Using A % B doesn't produce the - * right results for A<0. Casting to A to be unsigned only works if B - * is a power of two. Adding a bias to A (which is a multiple of B) - * avoids the problems with A < 0 (for reasonable A) without using a - * conditional. - */ -#define REMAINDER(A, B) (((A) + (B) * 1024) % (B)) - - -/** - * Used to compute texel locations for linear sampling. - * Input: - * wrapMode = GL_REPEAT, GL_CLAMP, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER - * s = texcoord in [0,1] - * size = width (or height or depth) of texture - * Output: - * i0, i1 = returns two nearest texel indexes - * weight = returns blend factor between texels - */ -static void -linear_texel_locations(GLenum wrapMode, - const struct gl_texture_image *img, - GLint size, GLfloat s, - GLint *i0, GLint *i1, GLfloat *weight) -{ - const struct swrast_texture_image *swImg = swrast_texture_image_const(img); - GLfloat u; - switch (wrapMode) { - case GL_REPEAT: - u = s * size - 0.5F; - if (swImg->_IsPowerOfTwo) { - *i0 = util_ifloor(u) & (size - 1); - *i1 = (*i0 + 1) & (size - 1); - } - else { - *i0 = REMAINDER(util_ifloor(u), size); - *i1 = REMAINDER(*i0 + 1, size); - } - break; - case GL_CLAMP_TO_EDGE: - if (s <= 0.0F) - u = 0.0F; - else if (s >= 1.0F) - u = (GLfloat) size; - else - u = s * size; - u -= 0.5F; - *i0 = util_ifloor(u); - *i1 = *i0 + 1; - if (*i0 < 0) - *i0 = 0; - if (*i1 >= (GLint) size) - *i1 = size - 1; - break; - case GL_CLAMP_TO_BORDER: - { - const GLfloat min = -1.0F / (2.0F * size); - const GLfloat max = 1.0F - min; - if (s <= min) - u = min * size; - else if (s >= max) - u = max * size; - else - u = s * size; - u -= 0.5F; - *i0 = util_ifloor(u); - *i1 = *i0 + 1; - } - break; - case GL_MIRRORED_REPEAT: - { - const GLint flr = util_ifloor(s); - if (flr & 1) - u = 1.0F - (s - (GLfloat) flr); - else - u = s - (GLfloat) flr; - u = (u * size) - 0.5F; - *i0 = util_ifloor(u); - *i1 = *i0 + 1; - if (*i0 < 0) - *i0 = 0; - if (*i1 >= (GLint) size) - *i1 = size - 1; - } - break; - case GL_MIRROR_CLAMP_EXT: - u = fabsf(s); - if (u >= 1.0F) - u = (GLfloat) size; - else - u *= size; - u -= 0.5F; - *i0 = util_ifloor(u); - *i1 = *i0 + 1; - break; - case GL_MIRROR_CLAMP_TO_EDGE_EXT: - u = fabsf(s); - if (u >= 1.0F) - u = (GLfloat) size; - else - u *= size; - u -= 0.5F; - *i0 = util_ifloor(u); - *i1 = *i0 + 1; - if (*i0 < 0) - *i0 = 0; - if (*i1 >= (GLint) size) - *i1 = size - 1; - break; - case GL_MIRROR_CLAMP_TO_BORDER_EXT: - { - const GLfloat min = -1.0F / (2.0F * size); - const GLfloat max = 1.0F - min; - u = fabsf(s); - if (u <= min) - u = min * size; - else if (u >= max) - u = max * size; - else - u *= size; - u -= 0.5F; - *i0 = util_ifloor(u); - *i1 = *i0 + 1; - } - break; - case GL_CLAMP: - if (s <= 0.0F) - u = 0.0F; - else if (s >= 1.0F) - u = (GLfloat) size; - else - u = s * size; - u -= 0.5F; - *i0 = util_ifloor(u); - *i1 = *i0 + 1; - break; - default: - _mesa_problem(NULL, "Bad wrap mode"); - *i0 = *i1 = 0; - u = 0.0F; - break; - } - *weight = FRAC(u); -} - - -/** - * Used to compute texel location for nearest sampling. - */ -static GLint -nearest_texel_location(GLenum wrapMode, - const struct gl_texture_image *img, - GLint size, GLfloat s) -{ - const struct swrast_texture_image *swImg = swrast_texture_image_const(img); - GLint i; - - switch (wrapMode) { - case GL_REPEAT: - /* s limited to [0,1) */ - /* i limited to [0,size-1] */ - i = util_ifloor(s * size); - if (swImg->_IsPowerOfTwo) - i &= (size - 1); - else - i = REMAINDER(i, size); - return i; - case GL_CLAMP_TO_EDGE: - { - /* s limited to [min,max] */ - /* i limited to [0, size-1] */ - const GLfloat min = 1.0F / (2.0F * size); - const GLfloat max = 1.0F - min; - if (s < min) - i = 0; - else if (s > max) - i = size - 1; - else - i = util_ifloor(s * size); - } - return i; - case GL_CLAMP_TO_BORDER: - { - /* s limited to [min,max] */ - /* i limited to [-1, size] */ - const GLfloat min = -1.0F / (2.0F * size); - const GLfloat max = 1.0F - min; - if (s <= min) - i = -1; - else if (s >= max) - i = size; - else - i = util_ifloor(s * size); - } - return i; - case GL_MIRRORED_REPEAT: - { - const GLfloat min = 1.0F / (2.0F * size); - const GLfloat max = 1.0F - min; - const GLint flr = util_ifloor(s); - GLfloat u; - if (flr & 1) - u = 1.0F - (s - (GLfloat) flr); - else - u = s - (GLfloat) flr; - if (u < min) - i = 0; - else if (u > max) - i = size - 1; - else - i = util_ifloor(u * size); - } - return i; - case GL_MIRROR_CLAMP_EXT: - { - /* s limited to [0,1] */ - /* i limited to [0,size-1] */ - const GLfloat u = fabsf(s); - if (u <= 0.0F) - i = 0; - else if (u >= 1.0F) - i = size - 1; - else - i = util_ifloor(u * size); - } - return i; - case GL_MIRROR_CLAMP_TO_EDGE_EXT: - { - /* s limited to [min,max] */ - /* i limited to [0, size-1] */ - const GLfloat min = 1.0F / (2.0F * size); - const GLfloat max = 1.0F - min; - const GLfloat u = fabsf(s); - if (u < min) - i = 0; - else if (u > max) - i = size - 1; - else - i = util_ifloor(u * size); - } - return i; - case GL_MIRROR_CLAMP_TO_BORDER_EXT: - { - /* s limited to [min,max] */ - /* i limited to [0, size-1] */ - const GLfloat min = -1.0F / (2.0F * size); - const GLfloat max = 1.0F - min; - const GLfloat u = fabsf(s); - if (u < min) - i = -1; - else if (u > max) - i = size; - else - i = util_ifloor(u * size); - } - return i; - case GL_CLAMP: - /* s limited to [0,1] */ - /* i limited to [0,size-1] */ - if (s <= 0.0F) - i = 0; - else if (s >= 1.0F) - i = size - 1; - else - i = util_ifloor(s * size); - return i; - default: - _mesa_problem(NULL, "Bad wrap mode"); - return 0; - } -} - - -/* Power of two image sizes only */ -static void -linear_repeat_texel_location(GLuint size, GLfloat s, - GLint *i0, GLint *i1, GLfloat *weight) -{ - GLfloat u = s * size - 0.5F; - *i0 = util_ifloor(u) & (size - 1); - *i1 = (*i0 + 1) & (size - 1); - *weight = FRAC(u); -} - - -/** - * Do clamp/wrap for a texture rectangle coord, GL_NEAREST filter mode. - */ -static GLint -clamp_rect_coord_nearest(GLenum wrapMode, GLfloat coord, GLint max) -{ - switch (wrapMode) { - case GL_CLAMP: - return util_ifloor( CLAMP(coord, 0.0F, max - 1) ); - case GL_CLAMP_TO_EDGE: - return util_ifloor( CLAMP(coord, 0.5F, max - 0.5F) ); - case GL_CLAMP_TO_BORDER: - return util_ifloor( CLAMP(coord, -0.5F, max + 0.5F) ); - default: - _mesa_problem(NULL, "bad wrapMode in clamp_rect_coord_nearest"); - return 0; - } -} - - -/** - * As above, but GL_LINEAR filtering. - */ -static void -clamp_rect_coord_linear(GLenum wrapMode, GLfloat coord, GLint max, - GLint *i0out, GLint *i1out, GLfloat *weight) -{ - GLfloat fcol; - GLint i0, i1; - switch (wrapMode) { - case GL_CLAMP: - /* Not exactly what the spec says, but it matches NVIDIA output */ - fcol = CLAMP(coord - 0.5F, 0.0F, max - 1); - i0 = util_ifloor(fcol); - i1 = i0 + 1; - break; - case GL_CLAMP_TO_EDGE: - fcol = CLAMP(coord, 0.5F, max - 0.5F); - fcol -= 0.5F; - i0 = util_ifloor(fcol); - i1 = i0 + 1; - if (i1 > max - 1) - i1 = max - 1; - break; - case GL_CLAMP_TO_BORDER: - fcol = CLAMP(coord, -0.5F, max + 0.5F); - fcol -= 0.5F; - i0 = util_ifloor(fcol); - i1 = i0 + 1; - break; - default: - _mesa_problem(NULL, "bad wrapMode in clamp_rect_coord_linear"); - i0 = i1 = 0; - fcol = 0.0F; - break; - } - *i0out = i0; - *i1out = i1; - *weight = FRAC(fcol); -} - - -/** - * Compute slice/image to use for 1D or 2D array texture. - */ -static GLint -tex_array_slice(GLfloat coord, GLsizei size) -{ - GLint slice = util_ifloor(coord + 0.5f); - slice = CLAMP(slice, 0, size - 1); - return slice; -} - - -/** - * Compute nearest integer texcoords for given texobj and coordinate. - * NOTE: only used for depth texture sampling. - */ -static void -nearest_texcoord(const struct gl_sampler_object *samp, - const struct gl_texture_object *texObj, - GLuint level, - const GLfloat texcoord[4], - GLint *i, GLint *j, GLint *k) -{ - const struct gl_texture_image *img = texObj->Image[0][level]; - const GLint width = img->Width; - const GLint height = img->Height; - const GLint depth = img->Depth; - - switch (texObj->Target) { - case GL_TEXTURE_RECTANGLE_ARB: - *i = clamp_rect_coord_nearest(samp->Attrib.WrapS, texcoord[0], width); - *j = clamp_rect_coord_nearest(samp->Attrib.WrapT, texcoord[1], height); - *k = 0; - break; - case GL_TEXTURE_1D: - *i = nearest_texel_location(samp->Attrib.WrapS, img, width, texcoord[0]); - *j = 0; - *k = 0; - break; - case GL_TEXTURE_2D: - *i = nearest_texel_location(samp->Attrib.WrapS, img, width, texcoord[0]); - *j = nearest_texel_location(samp->Attrib.WrapT, img, height, texcoord[1]); - *k = 0; - break; - case GL_TEXTURE_1D_ARRAY_EXT: - *i = nearest_texel_location(samp->Attrib.WrapS, img, width, texcoord[0]); - *j = tex_array_slice(texcoord[1], height); - *k = 0; - break; - case GL_TEXTURE_2D_ARRAY_EXT: - *i = nearest_texel_location(samp->Attrib.WrapS, img, width, texcoord[0]); - *j = nearest_texel_location(samp->Attrib.WrapT, img, height, texcoord[1]); - *k = tex_array_slice(texcoord[2], depth); - break; - default: - *i = *j = *k = 0; - break; - } -} - - -/** - * Compute linear integer texcoords for given texobj and coordinate. - * NOTE: only used for depth texture sampling. - */ -static void -linear_texcoord(const struct gl_sampler_object *samp, - const struct gl_texture_object *texObj, - GLuint level, - const GLfloat texcoord[4], - GLint *i0, GLint *i1, GLint *j0, GLint *j1, GLint *slice, - GLfloat *wi, GLfloat *wj) -{ - const struct gl_texture_image *img = texObj->Image[0][level]; - const GLint width = img->Width; - const GLint height = img->Height; - const GLint depth = img->Depth; - - switch (texObj->Target) { - case GL_TEXTURE_RECTANGLE_ARB: - clamp_rect_coord_linear(samp->Attrib.WrapS, texcoord[0], - width, i0, i1, wi); - clamp_rect_coord_linear(samp->Attrib.WrapT, texcoord[1], - height, j0, j1, wj); - *slice = 0; - break; - - case GL_TEXTURE_1D: - case GL_TEXTURE_2D: - linear_texel_locations(samp->Attrib.WrapS, img, width, - texcoord[0], i0, i1, wi); - linear_texel_locations(samp->Attrib.WrapT, img, height, - texcoord[1], j0, j1, wj); - *slice = 0; - break; - - case GL_TEXTURE_1D_ARRAY_EXT: - linear_texel_locations(samp->Attrib.WrapS, img, width, - texcoord[0], i0, i1, wi); - *j0 = tex_array_slice(texcoord[1], height); - *j1 = *j0; - *slice = 0; - break; - - case GL_TEXTURE_2D_ARRAY_EXT: - linear_texel_locations(samp->Attrib.WrapS, img, width, - texcoord[0], i0, i1, wi); - linear_texel_locations(samp->Attrib.WrapT, img, height, - texcoord[1], j0, j1, wj); - *slice = tex_array_slice(texcoord[2], depth); - break; - - default: - *slice = 0; - break; - } -} - - - -/** - * For linear interpolation between mipmap levels N and N+1, this function - * computes N. - */ -static GLint -linear_mipmap_level(const struct gl_texture_object *tObj, GLfloat lambda) -{ - if (lambda < 0.0F) - return tObj->Attrib.BaseLevel; - else if (lambda > tObj->_MaxLambda) - return (GLint) (tObj->Attrib.BaseLevel + tObj->_MaxLambda); - else - return (GLint) (tObj->Attrib.BaseLevel + lambda); -} - - -/** - * Compute the nearest mipmap level to take texels from. - */ -static GLint -nearest_mipmap_level(const struct gl_texture_object *tObj, GLfloat lambda) -{ - GLfloat l; - GLint level; - if (lambda <= 0.5F) - l = 0.0F; - else if (lambda > tObj->_MaxLambda + 0.4999F) - l = tObj->_MaxLambda + 0.4999F; - else - l = lambda; - level = (GLint) (tObj->Attrib.BaseLevel + l + 0.5F); - if (level > tObj->_MaxLevel) - level = tObj->_MaxLevel; - return level; -} - - - -/* - * Bitflags for texture border color sampling. - */ -#define I0BIT 1 -#define I1BIT 2 -#define J0BIT 4 -#define J1BIT 8 -#define K0BIT 16 -#define K1BIT 32 - - - -/** - * The lambda[] array values are always monotonic. Either the whole span - * will be minified, magnified, or split between the two. This function - * determines the subranges in [0, n-1] that are to be minified or magnified. - */ -static void -compute_min_mag_ranges(const struct gl_sampler_object *samp, - GLuint n, const GLfloat lambda[], - GLuint *minStart, GLuint *minEnd, - GLuint *magStart, GLuint *magEnd) -{ - GLfloat minMagThresh; - - /* we shouldn't be here if minfilter == magfilter */ - assert(samp->Attrib.MinFilter != samp->Attrib.MagFilter); - - /* This bit comes from the OpenGL spec: */ - if (samp->Attrib.MagFilter == GL_LINEAR - && (samp->Attrib.MinFilter == GL_NEAREST_MIPMAP_NEAREST || - samp->Attrib.MinFilter == GL_NEAREST_MIPMAP_LINEAR)) { - minMagThresh = 0.5F; - } - else { - minMagThresh = 0.0F; - } - -#if 0 - /* DEBUG CODE: Verify that lambda[] is monotonic. - * We can't really use this because the inaccuracy in the LOG2 function - * causes this test to fail, yet the resulting texturing is correct. - */ - if (n > 1) { - GLuint i; - printf("lambda delta = %g\n", lambda[0] - lambda[n-1]); - if (lambda[0] >= lambda[n-1]) { /* decreasing */ - for (i = 0; i < n - 1; i++) { - assert((GLint) (lambda[i] * 10) >= (GLint) (lambda[i+1] * 10)); - } - } - else { /* increasing */ - for (i = 0; i < n - 1; i++) { - assert((GLint) (lambda[i] * 10) <= (GLint) (lambda[i+1] * 10)); - } - } - } -#endif /* DEBUG */ - - if (lambda[0] <= minMagThresh && (n <= 1 || lambda[n-1] <= minMagThresh)) { - /* magnification for whole span */ - *magStart = 0; - *magEnd = n; - *minStart = *minEnd = 0; - } - else if (lambda[0] > minMagThresh && (n <=1 || lambda[n-1] > minMagThresh)) { - /* minification for whole span */ - *minStart = 0; - *minEnd = n; - *magStart = *magEnd = 0; - } - else { - /* a mix of minification and magnification */ - GLuint i; - if (lambda[0] > minMagThresh) { - /* start with minification */ - for (i = 1; i < n; i++) { - if (lambda[i] <= minMagThresh) - break; - } - *minStart = 0; - *minEnd = i; - *magStart = i; - *magEnd = n; - } - else { - /* start with magnification */ - for (i = 1; i < n; i++) { - if (lambda[i] > minMagThresh) - break; - } - *magStart = 0; - *magEnd = i; - *minStart = i; - *minEnd = n; - } - } - -#if 0 - /* Verify the min/mag Start/End values - * We don't use this either (see above) - */ - { - GLint i; - for (i = 0; i < n; i++) { - if (lambda[i] > minMagThresh) { - /* minification */ - assert(i >= *minStart); - assert(i < *minEnd); - } - else { - /* magnification */ - assert(i >= *magStart); - assert(i < *magEnd); - } - } - } -#endif -} - - -/** - * When we sample the border color, it must be interpreted according to - * the base texture format. Ex: if the texture base format it GL_ALPHA, - * we return (0,0,0,BorderAlpha). - */ -static void -get_border_color(const struct gl_sampler_object *samp, - const struct gl_texture_image *img, - GLfloat rgba[4]) -{ - switch (img->_BaseFormat) { - case GL_RGB: - rgba[0] = samp->Attrib.state.border_color.f[0]; - rgba[1] = samp->Attrib.state.border_color.f[1]; - rgba[2] = samp->Attrib.state.border_color.f[2]; - rgba[3] = 1.0F; - break; - case GL_ALPHA: - rgba[0] = rgba[1] = rgba[2] = 0.0; - rgba[3] = samp->Attrib.state.border_color.f[3]; - break; - case GL_LUMINANCE: - rgba[0] = rgba[1] = rgba[2] = samp->Attrib.state.border_color.f[0]; - rgba[3] = 1.0; - break; - case GL_LUMINANCE_ALPHA: - rgba[0] = rgba[1] = rgba[2] = samp->Attrib.state.border_color.f[0]; - rgba[3] = samp->Attrib.state.border_color.f[3]; - break; - case GL_INTENSITY: - rgba[0] = rgba[1] = rgba[2] = rgba[3] = samp->Attrib.state.border_color.f[0]; - break; - default: - COPY_4V(rgba, samp->Attrib.state.border_color.f); - break; - } -} - - -/** - * Put z into texel according to GL_DEPTH_MODE. - */ -static void -apply_depth_mode(GLenum depthMode, GLfloat z, GLfloat texel[4]) -{ - switch (depthMode) { - case GL_LUMINANCE: - ASSIGN_4V(texel, z, z, z, 1.0F); - break; - case GL_INTENSITY: - ASSIGN_4V(texel, z, z, z, z); - break; - case GL_ALPHA: - ASSIGN_4V(texel, 0.0F, 0.0F, 0.0F, z); - break; - case GL_RED: - ASSIGN_4V(texel, z, 0.0F, 0.0F, 1.0F); - break; - default: - _mesa_problem(NULL, "Bad depth texture mode"); - } -} - - -/** - * Is the given texture a depth (or depth/stencil) texture? - */ -static GLboolean -is_depth_texture(const struct gl_texture_object *tObj) -{ - GLenum format = _mesa_texture_base_format(tObj); - return format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL_EXT; -} - - -/**********************************************************************/ -/* 1-D Texture Sampling Functions */ -/**********************************************************************/ - -/** - * Return the texture sample for coordinate (s) using GL_NEAREST filter. - */ -static void -sample_1d_nearest(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_image *img, - const GLfloat texcoord[4], GLfloat rgba[4]) -{ - const struct swrast_texture_image *swImg = swrast_texture_image_const(img); - const GLint width = img->Width2; /* without border, power of two */ - GLint i; - i = nearest_texel_location(samp->Attrib.WrapS, img, width, texcoord[0]); - /* skip over the border, if any */ - i += img->Border; - if (i < 0 || i >= (GLint) img->Width) { - /* Need this test for GL_CLAMP_TO_BORDER mode */ - get_border_color(samp, img, rgba); - } - else { - swImg->FetchTexel(swImg, i, 0, 0, rgba); - } -} - - -/** - * Return the texture sample for coordinate (s) using GL_LINEAR filter. - */ -static void -sample_1d_linear(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_image *img, - const GLfloat texcoord[4], GLfloat rgba[4]) -{ - const struct swrast_texture_image *swImg = swrast_texture_image_const(img); - const GLint width = img->Width2; - GLint i0, i1; - GLbitfield useBorderColor = 0x0; - GLfloat a; - GLfloat t0[4], t1[4]; /* texels */ - - linear_texel_locations(samp->Attrib.WrapS, img, width, texcoord[0], &i0, &i1, &a); - - if (img->Border) { - i0 += img->Border; - i1 += img->Border; - } - else { - if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT; - if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT; - } - - /* fetch texel colors */ - if (useBorderColor & I0BIT) { - get_border_color(samp, img, t0); - } - else { - swImg->FetchTexel(swImg, i0, 0, 0, t0); - } - if (useBorderColor & I1BIT) { - get_border_color(samp, img, t1); - } - else { - swImg->FetchTexel(swImg, i1, 0, 0, t1); - } - - lerp_rgba(rgba, a, t0, t1); -} - - -static void -sample_1d_nearest_mipmap_nearest(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLfloat rgba[][4]) -{ - GLuint i; - assert(lambda != NULL); - for (i = 0; i < n; i++) { - GLint level = nearest_mipmap_level(tObj, lambda[i]); - sample_1d_nearest(ctx, samp, tObj->Image[0][level], texcoord[i], rgba[i]); - } -} - - -static void -sample_1d_linear_mipmap_nearest(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLfloat rgba[][4]) -{ - GLuint i; - assert(lambda != NULL); - for (i = 0; i < n; i++) { - GLint level = nearest_mipmap_level(tObj, lambda[i]); - sample_1d_linear(ctx, samp, tObj->Image[0][level], texcoord[i], rgba[i]); - } -} - - -static void -sample_1d_nearest_mipmap_linear(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLfloat rgba[][4]) -{ - GLuint i; - assert(lambda != NULL); - for (i = 0; i < n; i++) { - GLint level = linear_mipmap_level(tObj, lambda[i]); - if (level >= tObj->_MaxLevel) { - sample_1d_nearest(ctx, samp, tObj->Image[0][tObj->_MaxLevel], - texcoord[i], rgba[i]); - } - else { - GLfloat t0[4], t1[4]; - const GLfloat f = FRAC(lambda[i]); - sample_1d_nearest(ctx, samp, tObj->Image[0][level ], texcoord[i], t0); - sample_1d_nearest(ctx, samp, tObj->Image[0][level+1], texcoord[i], t1); - lerp_rgba(rgba[i], f, t0, t1); - } - } -} - - -static void -sample_1d_linear_mipmap_linear(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLfloat rgba[][4]) -{ - GLuint i; - assert(lambda != NULL); - for (i = 0; i < n; i++) { - GLint level = linear_mipmap_level(tObj, lambda[i]); - if (level >= tObj->_MaxLevel) { - sample_1d_linear(ctx, samp, tObj->Image[0][tObj->_MaxLevel], - texcoord[i], rgba[i]); - } - else { - GLfloat t0[4], t1[4]; - const GLfloat f = FRAC(lambda[i]); - sample_1d_linear(ctx, samp, tObj->Image[0][level ], texcoord[i], t0); - sample_1d_linear(ctx, samp, tObj->Image[0][level+1], texcoord[i], t1); - lerp_rgba(rgba[i], f, t0, t1); - } - } -} - - -/** Sample 1D texture, nearest filtering for both min/magnification */ -static void -sample_nearest_1d( struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, GLuint n, - const GLfloat texcoords[][4], const GLfloat lambda[], - GLfloat rgba[][4] ) -{ - GLuint i; - const struct gl_texture_image *image = _mesa_base_tex_image(tObj); - (void) lambda; - for (i = 0; i < n; i++) { - sample_1d_nearest(ctx, samp, image, texcoords[i], rgba[i]); - } -} - - -/** Sample 1D texture, linear filtering for both min/magnification */ -static void -sample_linear_1d( struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, GLuint n, - const GLfloat texcoords[][4], const GLfloat lambda[], - GLfloat rgba[][4] ) -{ - GLuint i; - const struct gl_texture_image *image = _mesa_base_tex_image(tObj); - (void) lambda; - for (i = 0; i < n; i++) { - sample_1d_linear(ctx, samp, image, texcoords[i], rgba[i]); - } -} - - -/** Sample 1D texture, using lambda to choose between min/magnification */ -static void -sample_lambda_1d( struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, GLuint n, - const GLfloat texcoords[][4], - const GLfloat lambda[], GLfloat rgba[][4] ) -{ - GLuint minStart, minEnd; /* texels with minification */ - GLuint magStart, magEnd; /* texels with magnification */ - GLuint i; - - assert(lambda != NULL); - compute_min_mag_ranges(samp, n, lambda, - &minStart, &minEnd, &magStart, &magEnd); - - if (minStart < minEnd) { - /* do the minified texels */ - const GLuint m = minEnd - minStart; - switch (samp->Attrib.MinFilter) { - case GL_NEAREST: - for (i = minStart; i < minEnd; i++) - sample_1d_nearest(ctx, samp, _mesa_base_tex_image(tObj), - texcoords[i], rgba[i]); - break; - case GL_LINEAR: - for (i = minStart; i < minEnd; i++) - sample_1d_linear(ctx, samp, _mesa_base_tex_image(tObj), - texcoords[i], rgba[i]); - break; - case GL_NEAREST_MIPMAP_NEAREST: - sample_1d_nearest_mipmap_nearest(ctx, samp, tObj, m, texcoords + minStart, - lambda + minStart, rgba + minStart); - break; - case GL_LINEAR_MIPMAP_NEAREST: - sample_1d_linear_mipmap_nearest(ctx, samp, tObj, m, texcoords + minStart, - lambda + minStart, rgba + minStart); - break; - case GL_NEAREST_MIPMAP_LINEAR: - sample_1d_nearest_mipmap_linear(ctx, samp, tObj, m, texcoords + minStart, - lambda + minStart, rgba + minStart); - break; - case GL_LINEAR_MIPMAP_LINEAR: - sample_1d_linear_mipmap_linear(ctx, samp, tObj, m, texcoords + minStart, - lambda + minStart, rgba + minStart); - break; - default: - _mesa_problem(ctx, "Bad min filter in sample_1d_texture"); - return; - } - } - - if (magStart < magEnd) { - /* do the magnified texels */ - switch (samp->Attrib.MagFilter) { - case GL_NEAREST: - for (i = magStart; i < magEnd; i++) - sample_1d_nearest(ctx, samp, _mesa_base_tex_image(tObj), - texcoords[i], rgba[i]); - break; - case GL_LINEAR: - for (i = magStart; i < magEnd; i++) - sample_1d_linear(ctx, samp, _mesa_base_tex_image(tObj), - texcoords[i], rgba[i]); - break; - default: - _mesa_problem(ctx, "Bad mag filter in sample_1d_texture"); - return; - } - } -} - - -/**********************************************************************/ -/* 2-D Texture Sampling Functions */ -/**********************************************************************/ - - -/** - * Return the texture sample for coordinate (s,t) using GL_NEAREST filter. - */ -static void -sample_2d_nearest(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_image *img, - const GLfloat texcoord[2], - GLfloat rgba[]) -{ - const struct swrast_texture_image *swImg = swrast_texture_image_const(img); - const GLint width = img->Width2; /* without border, power of two */ - const GLint height = img->Height2; /* without border, power of two */ - GLint i, j; - (void) ctx; - - i = nearest_texel_location(samp->Attrib.WrapS, img, width, texcoord[0]); - j = nearest_texel_location(samp->Attrib.WrapT, img, height, texcoord[1]); - - /* skip over the border, if any */ - i += img->Border; - j += img->Border; - - if (i < 0 || i >= (GLint) img->Width || j < 0 || j >= (GLint) img->Height) { - /* Need this test for GL_CLAMP_TO_BORDER mode */ - get_border_color(samp, img, rgba); - } - else { - swImg->FetchTexel(swImg, i, j, 0, rgba); - } -} - - -/** - * Return the texture sample for coordinate (s,t) using GL_LINEAR filter. - * New sampling code contributed by Lynn Quam . - */ -static void -sample_2d_linear(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_image *img, - const GLfloat texcoord[2], - GLfloat rgba[]) -{ - const struct swrast_texture_image *swImg = swrast_texture_image_const(img); - const GLint width = img->Width2; - const GLint height = img->Height2; - GLint i0, j0, i1, j1; - GLbitfield useBorderColor = 0x0; - GLfloat a, b; - GLfloat t00[4], t10[4], t01[4], t11[4]; /* sampled texel colors */ - - linear_texel_locations(samp->Attrib.WrapS, img, width, texcoord[0], &i0, &i1, &a); - linear_texel_locations(samp->Attrib.WrapT, img, height, texcoord[1], &j0, &j1, &b); - - if (img->Border) { - i0 += img->Border; - i1 += img->Border; - j0 += img->Border; - j1 += img->Border; - } - else { - if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT; - if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT; - if (j0 < 0 || j0 >= height) useBorderColor |= J0BIT; - if (j1 < 0 || j1 >= height) useBorderColor |= J1BIT; - } - - /* fetch four texel colors */ - if (useBorderColor & (I0BIT | J0BIT)) { - get_border_color(samp, img, t00); - } - else { - swImg->FetchTexel(swImg, i0, j0, 0, t00); - } - if (useBorderColor & (I1BIT | J0BIT)) { - get_border_color(samp, img, t10); - } - else { - swImg->FetchTexel(swImg, i1, j0, 0, t10); - } - if (useBorderColor & (I0BIT | J1BIT)) { - get_border_color(samp, img, t01); - } - else { - swImg->FetchTexel(swImg, i0, j1, 0, t01); - } - if (useBorderColor & (I1BIT | J1BIT)) { - get_border_color(samp, img, t11); - } - else { - swImg->FetchTexel(swImg, i1, j1, 0, t11); - } - - lerp_rgba_2d(rgba, a, b, t00, t10, t01, t11); -} - - -/** - * As above, but we know WRAP_S == REPEAT and WRAP_T == REPEAT. - * We don't have to worry about the texture border. - */ -static void -sample_2d_linear_repeat(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_image *img, - const GLfloat texcoord[4], - GLfloat rgba[]) -{ - const struct swrast_texture_image *swImg = swrast_texture_image_const(img); - const GLint width = img->Width2; - const GLint height = img->Height2; - GLint i0, j0, i1, j1; - GLfloat wi, wj; - GLfloat t00[4], t10[4], t01[4], t11[4]; /* sampled texel colors */ - - (void) ctx; - - assert(samp->Attrib.WrapS == GL_REPEAT); - assert(samp->Attrib.WrapT == GL_REPEAT); - assert(img->Border == 0); - assert(swImg->_IsPowerOfTwo); - - linear_repeat_texel_location(width, texcoord[0], &i0, &i1, &wi); - linear_repeat_texel_location(height, texcoord[1], &j0, &j1, &wj); - - swImg->FetchTexel(swImg, i0, j0, 0, t00); - swImg->FetchTexel(swImg, i1, j0, 0, t10); - swImg->FetchTexel(swImg, i0, j1, 0, t01); - swImg->FetchTexel(swImg, i1, j1, 0, t11); - - lerp_rgba_2d(rgba, wi, wj, t00, t10, t01, t11); -} - - -static void -sample_2d_nearest_mipmap_nearest(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLfloat rgba[][4]) -{ - GLuint i; - for (i = 0; i < n; i++) { - GLint level = nearest_mipmap_level(tObj, lambda[i]); - sample_2d_nearest(ctx, samp, tObj->Image[0][level], texcoord[i], rgba[i]); - } -} - - -static void -sample_2d_linear_mipmap_nearest(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLfloat rgba[][4]) -{ - GLuint i; - assert(lambda != NULL); - for (i = 0; i < n; i++) { - GLint level = nearest_mipmap_level(tObj, lambda[i]); - sample_2d_linear(ctx, samp, tObj->Image[0][level], texcoord[i], rgba[i]); - } -} - - -static void -sample_2d_nearest_mipmap_linear(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLfloat rgba[][4]) -{ - GLuint i; - assert(lambda != NULL); - for (i = 0; i < n; i++) { - GLint level = linear_mipmap_level(tObj, lambda[i]); - if (level >= tObj->_MaxLevel) { - sample_2d_nearest(ctx, samp, tObj->Image[0][tObj->_MaxLevel], - texcoord[i], rgba[i]); - } - else { - GLfloat t0[4], t1[4]; /* texels */ - const GLfloat f = FRAC(lambda[i]); - sample_2d_nearest(ctx, samp, tObj->Image[0][level ], texcoord[i], t0); - sample_2d_nearest(ctx, samp, tObj->Image[0][level+1], texcoord[i], t1); - lerp_rgba(rgba[i], f, t0, t1); - } - } -} - - -static void -sample_2d_linear_mipmap_linear( struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLfloat rgba[][4] ) -{ - GLuint i; - assert(lambda != NULL); - for (i = 0; i < n; i++) { - GLint level = linear_mipmap_level(tObj, lambda[i]); - if (level >= tObj->_MaxLevel) { - sample_2d_linear(ctx, samp, tObj->Image[0][tObj->_MaxLevel], - texcoord[i], rgba[i]); - } - else { - GLfloat t0[4], t1[4]; /* texels */ - const GLfloat f = FRAC(lambda[i]); - sample_2d_linear(ctx, samp, tObj->Image[0][level ], texcoord[i], t0); - sample_2d_linear(ctx, samp, tObj->Image[0][level+1], texcoord[i], t1); - lerp_rgba(rgba[i], f, t0, t1); - } - } -} - - -static void -sample_2d_linear_mipmap_linear_repeat(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLfloat rgba[][4]) -{ - GLuint i; - assert(lambda != NULL); - assert(samp->Attrib.WrapS == GL_REPEAT); - assert(samp->Attrib.WrapT == GL_REPEAT); - for (i = 0; i < n; i++) { - GLint level = linear_mipmap_level(tObj, lambda[i]); - if (level >= tObj->_MaxLevel) { - sample_2d_linear_repeat(ctx, samp, tObj->Image[0][tObj->_MaxLevel], - texcoord[i], rgba[i]); - } - else { - GLfloat t0[4], t1[4]; /* texels */ - const GLfloat f = FRAC(lambda[i]); - sample_2d_linear_repeat(ctx, samp, tObj->Image[0][level ], - texcoord[i], t0); - sample_2d_linear_repeat(ctx, samp, tObj->Image[0][level+1], - texcoord[i], t1); - lerp_rgba(rgba[i], f, t0, t1); - } - } -} - - -/** Sample 2D texture, nearest filtering for both min/magnification */ -static void -sample_nearest_2d(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, GLuint n, - const GLfloat texcoords[][4], - const GLfloat lambda[], GLfloat rgba[][4]) -{ - GLuint i; - const struct gl_texture_image *image = _mesa_base_tex_image(tObj); - (void) lambda; - for (i = 0; i < n; i++) { - sample_2d_nearest(ctx, samp, image, texcoords[i], rgba[i]); - } -} - - -/** Sample 2D texture, linear filtering for both min/magnification */ -static void -sample_linear_2d(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, GLuint n, - const GLfloat texcoords[][4], - const GLfloat lambda[], GLfloat rgba[][4]) -{ - GLuint i; - const struct gl_texture_image *image = _mesa_base_tex_image(tObj); - const struct swrast_texture_image *swImg = swrast_texture_image_const(image); - (void) lambda; - if (samp->Attrib.WrapS == GL_REPEAT && - samp->Attrib.WrapT == GL_REPEAT && - swImg->_IsPowerOfTwo && - image->Border == 0) { - for (i = 0; i < n; i++) { - sample_2d_linear_repeat(ctx, samp, image, texcoords[i], rgba[i]); - } - } - else { - for (i = 0; i < n; i++) { - sample_2d_linear(ctx, samp, image, texcoords[i], rgba[i]); - } - } -} - - -/** - * Optimized 2-D texture sampling: - * S and T wrap mode == GL_REPEAT - * GL_NEAREST min/mag filter - * No border, - * RowStride == Width, - * Format = GL_RGB - */ -static void -opt_sample_rgb_2d(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoords[][4], - const GLfloat lambda[], GLfloat rgba[][4]) -{ - const struct gl_texture_image *img = _mesa_base_tex_image(tObj); - const struct swrast_texture_image *swImg = swrast_texture_image_const(img); - const GLfloat width = (GLfloat) img->Width; - const GLfloat height = (GLfloat) img->Height; - const GLint colMask = img->Width - 1; - const GLint rowMask = img->Height - 1; - const GLint shift = img->WidthLog2; - GLuint k; - (void) ctx; - (void) lambda; - assert(samp->Attrib.WrapS==GL_REPEAT); - assert(samp->Attrib.WrapT==GL_REPEAT); - assert(img->Border==0); - assert(img->TexFormat == MESA_FORMAT_BGR_UNORM8); - assert(swImg->_IsPowerOfTwo); - (void) swImg; - - for (k=0; kImageSlices[0] + 3 * pos; - rgba[k][RCOMP] = UBYTE_TO_FLOAT(texel[2]); - rgba[k][GCOMP] = UBYTE_TO_FLOAT(texel[1]); - rgba[k][BCOMP] = UBYTE_TO_FLOAT(texel[0]); - rgba[k][ACOMP] = 1.0F; - } -} - - -/** - * Optimized 2-D texture sampling: - * S and T wrap mode == GL_REPEAT - * GL_NEAREST min/mag filter - * No border - * RowStride == Width, - * Format = GL_RGBA - */ -static void -opt_sample_rgba_2d(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoords[][4], - const GLfloat lambda[], GLfloat rgba[][4]) -{ - const struct gl_texture_image *img = _mesa_base_tex_image(tObj); - const struct swrast_texture_image *swImg = swrast_texture_image_const(img); - const GLfloat width = (GLfloat) img->Width; - const GLfloat height = (GLfloat) img->Height; - const GLint colMask = img->Width - 1; - const GLint rowMask = img->Height - 1; - const GLint shift = img->WidthLog2; - GLuint i; - (void) ctx; - (void) lambda; - assert(samp->Attrib.WrapS==GL_REPEAT); - assert(samp->Attrib.WrapT==GL_REPEAT); - assert(img->Border==0); - assert(img->TexFormat == MESA_FORMAT_A8B8G8R8_UNORM); - assert(swImg->_IsPowerOfTwo); - (void) swImg; - - for (i = 0; i < n; i++) { - const GLint col = util_ifloor(texcoords[i][0] * width) & colMask; - const GLint row = util_ifloor(texcoords[i][1] * height) & rowMask; - const GLint pos = (row << shift) | col; - const GLuint texel = *((GLuint *) swImg->ImageSlices[0] + pos); - rgba[i][RCOMP] = UBYTE_TO_FLOAT( (texel >> 24) ); - rgba[i][GCOMP] = UBYTE_TO_FLOAT( (texel >> 16) & 0xff ); - rgba[i][BCOMP] = UBYTE_TO_FLOAT( (texel >> 8) & 0xff ); - rgba[i][ACOMP] = UBYTE_TO_FLOAT( (texel ) & 0xff ); - } -} - - -/** Sample 2D texture, using lambda to choose between min/magnification */ -static void -sample_lambda_2d(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoords[][4], - const GLfloat lambda[], GLfloat rgba[][4]) -{ - const struct gl_texture_image *tImg = _mesa_base_tex_image(tObj); - const struct swrast_texture_image *swImg = swrast_texture_image_const(tImg); - GLuint minStart, minEnd; /* texels with minification */ - GLuint magStart, magEnd; /* texels with magnification */ - - const GLboolean repeatNoBorderPOT = (samp->Attrib.WrapS == GL_REPEAT) - && (samp->Attrib.WrapT == GL_REPEAT) - && (tImg->Border == 0) - && (_mesa_format_row_stride(tImg->TexFormat, tImg->Width) == - swImg->RowStride) - && swImg->_IsPowerOfTwo; - - assert(lambda != NULL); - compute_min_mag_ranges(samp, n, lambda, - &minStart, &minEnd, &magStart, &magEnd); - - if (minStart < minEnd) { - /* do the minified texels */ - const GLuint m = minEnd - minStart; - switch (samp->Attrib.MinFilter) { - case GL_NEAREST: - if (repeatNoBorderPOT) { - switch (tImg->TexFormat) { - case MESA_FORMAT_BGR_UNORM8: - opt_sample_rgb_2d(ctx, samp, tObj, m, texcoords + minStart, - NULL, rgba + minStart); - break; - case MESA_FORMAT_A8B8G8R8_UNORM: - opt_sample_rgba_2d(ctx, samp, tObj, m, texcoords + minStart, - NULL, rgba + minStart); - break; - default: - sample_nearest_2d(ctx, samp, tObj, m, texcoords + minStart, - NULL, rgba + minStart ); - } - } - else { - sample_nearest_2d(ctx, samp, tObj, m, texcoords + minStart, - NULL, rgba + minStart); - } - break; - case GL_LINEAR: - sample_linear_2d(ctx, samp, tObj, m, texcoords + minStart, - NULL, rgba + minStart); - break; - case GL_NEAREST_MIPMAP_NEAREST: - sample_2d_nearest_mipmap_nearest(ctx, samp, tObj, m, - texcoords + minStart, - lambda + minStart, rgba + minStart); - break; - case GL_LINEAR_MIPMAP_NEAREST: - sample_2d_linear_mipmap_nearest(ctx, samp, tObj, m, texcoords + minStart, - lambda + minStart, rgba + minStart); - break; - case GL_NEAREST_MIPMAP_LINEAR: - sample_2d_nearest_mipmap_linear(ctx, samp, tObj, m, texcoords + minStart, - lambda + minStart, rgba + minStart); - break; - case GL_LINEAR_MIPMAP_LINEAR: - if (repeatNoBorderPOT) - sample_2d_linear_mipmap_linear_repeat(ctx, samp, tObj, m, - texcoords + minStart, lambda + minStart, rgba + minStart); - else - sample_2d_linear_mipmap_linear(ctx, samp, tObj, m, texcoords + minStart, - lambda + minStart, rgba + minStart); - break; - default: - _mesa_problem(ctx, "Bad min filter in sample_2d_texture"); - return; - } - } - - if (magStart < magEnd) { - /* do the magnified texels */ - const GLuint m = magEnd - magStart; - - switch (samp->Attrib.MagFilter) { - case GL_NEAREST: - if (repeatNoBorderPOT) { - switch (tImg->TexFormat) { - case MESA_FORMAT_BGR_UNORM8: - opt_sample_rgb_2d(ctx, samp, tObj, m, texcoords + magStart, - NULL, rgba + magStart); - break; - case MESA_FORMAT_A8B8G8R8_UNORM: - opt_sample_rgba_2d(ctx, samp, tObj, m, texcoords + magStart, - NULL, rgba + magStart); - break; - default: - sample_nearest_2d(ctx, samp, tObj, m, texcoords + magStart, - NULL, rgba + magStart ); - } - } - else { - sample_nearest_2d(ctx, samp, tObj, m, texcoords + magStart, - NULL, rgba + magStart); - } - break; - case GL_LINEAR: - sample_linear_2d(ctx, samp, tObj, m, texcoords + magStart, - NULL, rgba + magStart); - break; - default: - _mesa_problem(ctx, "Bad mag filter in sample_lambda_2d"); - break; - } - } -} - - -/* For anisotropic filtering */ -#define WEIGHT_LUT_SIZE 1024 - -static GLfloat *weightLut = NULL; - -/** - * Creates the look-up table used to speed-up EWA sampling - */ -static void -create_filter_table(void) -{ - GLuint i; - if (!weightLut) { - weightLut = malloc(WEIGHT_LUT_SIZE * sizeof(GLfloat)); - - for (i = 0; i < WEIGHT_LUT_SIZE; ++i) { - GLfloat alpha = 2; - GLfloat r2 = (GLfloat) i / (GLfloat) (WEIGHT_LUT_SIZE - 1); - GLfloat weight = expf(-alpha * r2); - weightLut[i] = weight; - } - } -} - - -/** - * Elliptical weighted average (EWA) filter for producing high quality - * anisotropic filtered results. - * Based on the Higher Quality Elliptical Weighted Avarage Filter - * published by Paul S. Heckbert in his Master's Thesis - * "Fundamentals of Texture Mapping and Image Warping" (1989) - */ -static void -sample_2d_ewa(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, - const GLfloat texcoord[4], - const GLfloat dudx, const GLfloat dvdx, - const GLfloat dudy, const GLfloat dvdy, const GLint lod, - GLfloat rgba[]) -{ - GLint level = lod > 0 ? lod : 0; - GLfloat scaling = 1.0f / (1 << level); - const struct gl_texture_image *img = tObj->Image[0][level]; - const struct gl_texture_image *mostDetailedImage = - _mesa_base_tex_image(tObj); - const struct swrast_texture_image *swImg = - swrast_texture_image_const(mostDetailedImage); - GLfloat tex_u = -0.5f + texcoord[0] * swImg->WidthScale * scaling; - GLfloat tex_v = -0.5f + texcoord[1] * swImg->HeightScale * scaling; - - GLfloat ux = dudx * scaling; - GLfloat vx = dvdx * scaling; - GLfloat uy = dudy * scaling; - GLfloat vy = dvdy * scaling; - - /* compute ellipse coefficients to bound the region: - * A*x*x + B*x*y + C*y*y = F. - */ - GLfloat A = vx*vx+vy*vy+1; - GLfloat B = -2*(ux*vx+uy*vy); - GLfloat C = ux*ux+uy*uy+1; - GLfloat F = A*C-B*B/4.0f; - - /* check if it is an ellipse */ - /* assert(F > 0.0); */ - - /* Compute the ellipse's (u,v) bounding box in texture space */ - GLfloat d = -B*B+4.0f*C*A; - GLfloat box_u = 2.0f / d * sqrtf(d*C*F); /* box_u -> half of bbox with */ - GLfloat box_v = 2.0f / d * sqrtf(A*d*F); /* box_v -> half of bbox height */ - - GLint u0 = (GLint) floorf(tex_u - box_u); - GLint u1 = (GLint) ceilf (tex_u + box_u); - GLint v0 = (GLint) floorf(tex_v - box_v); - GLint v1 = (GLint) ceilf (tex_v + box_v); - - GLfloat num[4] = {0.0F, 0.0F, 0.0F, 0.0F}; - GLfloat newCoord[2]; - GLfloat den = 0.0F; - GLfloat ddq; - GLfloat U = u0 - tex_u; - GLint v; - - /* Scale ellipse formula to directly index the Filter Lookup Table. - * i.e. scale so that F = WEIGHT_LUT_SIZE-1 - */ - GLfloat formScale = (GLfloat) (WEIGHT_LUT_SIZE - 1) / F; - A *= formScale; - B *= formScale; - C *= formScale; - /* F *= formScale; */ /* no need to scale F as we don't use it below here */ - - /* Heckbert MS thesis, p. 59; scan over the bounding box of the ellipse - * and incrementally update the value of Ax^2+Bxy*Cy^2; when this - * value, q, is less than F, we're inside the ellipse - */ - ddq = 2 * A; - for (v = v0; v <= v1; ++v) { - GLfloat V = v - tex_v; - GLfloat dq = A * (2 * U + 1) + B * V; - GLfloat q = (C * V + B * U) * V + A * U * U; - - GLint u; - for (u = u0; u <= u1; ++u) { - /* Note that the ellipse has been pre-scaled so F = WEIGHT_LUT_SIZE - 1 */ - if (q < WEIGHT_LUT_SIZE) { - /* as a LUT is used, q must never be negative; - * should not happen, though - */ - const GLint qClamped = q >= 0.0F ? (GLint) q : 0; - GLfloat weight = weightLut[qClamped]; - - newCoord[0] = u / ((GLfloat) img->Width2); - newCoord[1] = v / ((GLfloat) img->Height2); - - sample_2d_nearest(ctx, samp, img, newCoord, rgba); - num[0] += weight * rgba[0]; - num[1] += weight * rgba[1]; - num[2] += weight * rgba[2]; - num[3] += weight * rgba[3]; - - den += weight; - } - q += dq; - dq += ddq; - } - } - - if (den <= 0.0F) { - /* Reaching this place would mean - * that no pixels intersected the ellipse. - * This should never happen because - * the filter we use always - * intersects at least one pixel. - */ - - /*rgba[0]=0; - rgba[1]=0; - rgba[2]=0; - rgba[3]=0;*/ - /* not enough pixels in resampling, resort to direct interpolation */ - sample_2d_linear(ctx, samp, img, texcoord, rgba); - return; - } - - rgba[0] = num[0] / den; - rgba[1] = num[1] / den; - rgba[2] = num[2] / den; - rgba[3] = num[3] / den; -} - - -/** - * Anisotropic filtering using footprint assembly as outlined in the - * EXT_texture_filter_anisotropic spec: - * http://www.opengl.org/registry/specs/EXT/texture_filter_anisotropic.txt - * Faster than EWA but has less quality (more aliasing effects) - */ -static void -sample_2d_footprint(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, - const GLfloat texcoord[4], - const GLfloat dudx, const GLfloat dvdx, - const GLfloat dudy, const GLfloat dvdy, const GLint lod, - GLfloat rgba[]) -{ - GLint level = lod > 0 ? lod : 0; - GLfloat scaling = 1.0F / (1 << level); - const struct gl_texture_image *img = tObj->Image[0][level]; - - GLfloat ux = dudx * scaling; - GLfloat vx = dvdx * scaling; - GLfloat uy = dudy * scaling; - GLfloat vy = dvdy * scaling; - - GLfloat Px2 = ux * ux + vx * vx; /* squared length of dx */ - GLfloat Py2 = uy * uy + vy * vy; /* squared length of dy */ - - GLint numSamples; - GLfloat ds; - GLfloat dt; - - GLfloat num[4] = {0.0F, 0.0F, 0.0F, 0.0F}; - GLfloat newCoord[2]; - GLint s; - - /* Calculate the per anisotropic sample offsets in s,t space. */ - if (Px2 > Py2) { - numSamples = (GLint) ceilf(sqrtf(Px2)); - ds = ux / ((GLfloat) img->Width2); - dt = vx / ((GLfloat) img->Height2); - } - else { - numSamples = (GLint) ceilf(sqrtf(Py2)); - ds = uy / ((GLfloat) img->Width2); - dt = vy / ((GLfloat) img->Height2); - } - - for (s = 0; sTexture._EnabledCoordUnits > 1) ? ctx->Const.MaxTextureUnits : 1; - GLuint u; - - /* XXX CoordUnits vs. ImageUnits */ - for (u = 0; u < maxUnit; u++) { - if (ctx->Texture.Unit[u]._Current == tObj) - break; /* found */ - } - if (u >= maxUnit) - u = 0; /* not found, use 1st one; should never happen */ - - return u; -} - - -/** - * Sample 2D texture using an anisotropic filter. - * NOTE: the const GLfloat lambda_iso[] parameter does *NOT* contain - * the lambda float array but a "hidden" SWspan struct which is required - * by this function but is not available in the texture_sample_func signature. - * See _swrast_texture_span( struct gl_context *ctx, SWspan *span ) on how - * this function is called. - */ -static void -sample_lambda_2d_aniso(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoords[][4], - const GLfloat lambda_iso[], GLfloat rgba[][4]) -{ - const struct gl_texture_image *tImg = _mesa_base_tex_image(tObj); - const struct swrast_texture_image *swImg = swrast_texture_image_const(tImg); - const GLfloat maxEccentricity = - samp->Attrib.MaxAnisotropy * samp->Attrib.MaxAnisotropy; - - /* re-calculate the lambda values so that they are usable with anisotropic - * filtering - */ - SWspan *span = (SWspan *)lambda_iso; /* access the "hidden" SWspan struct */ - - /* based on interpolate_texcoords(struct gl_context *ctx, SWspan *span) - * in swrast/s_span.c - */ - - /* find the texture unit index by looking up the current texture object - * from the context list of available texture objects. - */ - const GLuint u = texture_unit_index(ctx, tObj); - const GLuint attr = VARYING_SLOT_TEX0 + u; - GLfloat texW, texH; - - const GLfloat dsdx = span->attrStepX[attr][0]; - const GLfloat dsdy = span->attrStepY[attr][0]; - const GLfloat dtdx = span->attrStepX[attr][1]; - const GLfloat dtdy = span->attrStepY[attr][1]; - const GLfloat dqdx = span->attrStepX[attr][3]; - const GLfloat dqdy = span->attrStepY[attr][3]; - GLfloat s = span->attrStart[attr][0] + span->leftClip * dsdx; - GLfloat t = span->attrStart[attr][1] + span->leftClip * dtdx; - GLfloat q = span->attrStart[attr][3] + span->leftClip * dqdx; - - /* from swrast/s_texcombine.c _swrast_texture_span */ - const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[u]; - const GLboolean adjustLOD = - (texUnit->LodBias + samp->Attrib.LodBias != 0.0F) - || (samp->Attrib.MinLod != -1000.0F || samp->Attrib.MaxLod != 1000.0F); - - GLuint i; - - /* on first access create the lookup table containing the filter weights. */ - if (!weightLut) { - create_filter_table(); - } - - texW = swImg->WidthScale; - texH = swImg->HeightScale; - - for (i = 0; i < n; i++) { - const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); - - GLfloat dudx = texW * ((s + dsdx) / (q + dqdx) - s * invQ); - GLfloat dvdx = texH * ((t + dtdx) / (q + dqdx) - t * invQ); - GLfloat dudy = texW * ((s + dsdy) / (q + dqdy) - s * invQ); - GLfloat dvdy = texH * ((t + dtdy) / (q + dqdy) - t * invQ); - - /* note: instead of working with Px and Py, we will use the - * squared length instead, to avoid sqrt. - */ - GLfloat Px2 = dudx * dudx + dvdx * dvdx; - GLfloat Py2 = dudy * dudy + dvdy * dvdy; - - GLfloat Pmax2; - GLfloat Pmin2; - GLfloat e; - GLfloat lod; - - s += dsdx; - t += dtdx; - q += dqdx; - - if (Px2 < Py2) { - Pmax2 = Py2; - Pmin2 = Px2; - } - else { - Pmax2 = Px2; - Pmin2 = Py2; - } - - /* if the eccentricity of the ellipse is too big, scale up the shorter - * of the two vectors to limit the maximum amount of work per pixel - */ - e = Pmax2 / Pmin2; - if (e > maxEccentricity) { - /* GLfloat s=e / maxEccentricity; - minor[0] *= s; - minor[1] *= s; - Pmin2 *= s; */ - Pmin2 = Pmax2 / maxEccentricity; - } - - /* note: we need to have Pmin=sqrt(Pmin2) here, but we can avoid - * this since 0.5*log(x) = log(sqrt(x)) - */ - lod = 0.5f * log2f(Pmin2); - - if (adjustLOD) { - /* from swrast/s_texcombine.c _swrast_texture_span */ - if (texUnit->LodBias + samp->Attrib.LodBias != 0.0F) { - /* apply LOD bias, but don't clamp yet */ - const GLfloat bias = - CLAMP(texUnit->LodBias + samp->Attrib.LodBias, - -ctx->Const.MaxTextureLodBias, - ctx->Const.MaxTextureLodBias); - lod += bias; - - if (samp->Attrib.MinLod != -1000.0F || - samp->Attrib.MaxLod != 1000.0F) { - /* apply LOD clamping to lambda */ - lod = CLAMP(lod, samp->Attrib.MinLod, samp->Attrib.MaxLod); - } - } - } - - /* If the ellipse covers the whole image, we can - * simply return the average of the whole image. - */ - if (lod >= tObj->_MaxLevel) { - sample_2d_linear(ctx, samp, tObj->Image[0][tObj->_MaxLevel], - texcoords[i], rgba[i]); - } - else { - /* don't bother interpolating between multiple LODs; it doesn't - * seem to be worth the extra running time. - */ - sample_2d_ewa(ctx, samp, tObj, texcoords[i], - dudx, dvdx, dudy, dvdy, (GLint) floorf(lod), rgba[i]); - - /* unused: */ - (void) sample_2d_footprint; - /* - sample_2d_footprint(ctx, tObj, texcoords[i], - dudx, dvdx, dudy, dvdy, floor(lod), rgba[i]); - */ - } - } -} - - - -/**********************************************************************/ -/* 3-D Texture Sampling Functions */ -/**********************************************************************/ - -/** - * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter. - */ -static void -sample_3d_nearest(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_image *img, - const GLfloat texcoord[4], - GLfloat rgba[4]) -{ - const struct swrast_texture_image *swImg = swrast_texture_image_const(img); - const GLint width = img->Width2; /* without border, power of two */ - const GLint height = img->Height2; /* without border, power of two */ - const GLint depth = img->Depth2; /* without border, power of two */ - GLint i, j, k; - (void) ctx; - - i = nearest_texel_location(samp->Attrib.WrapS, img, width, texcoord[0]); - j = nearest_texel_location(samp->Attrib.WrapT, img, height, texcoord[1]); - k = nearest_texel_location(samp->Attrib.WrapR, img, depth, texcoord[2]); - - if (i < 0 || i >= (GLint) img->Width || - j < 0 || j >= (GLint) img->Height || - k < 0 || k >= (GLint) img->Depth) { - /* Need this test for GL_CLAMP_TO_BORDER mode */ - get_border_color(samp, img, rgba); - } - else { - swImg->FetchTexel(swImg, i, j, k, rgba); - } -} - - -/** - * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter. - */ -static void -sample_3d_linear(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_image *img, - const GLfloat texcoord[4], - GLfloat rgba[4]) -{ - const struct swrast_texture_image *swImg = swrast_texture_image_const(img); - const GLint width = img->Width2; - const GLint height = img->Height2; - const GLint depth = img->Depth2; - GLint i0, j0, k0, i1, j1, k1; - GLbitfield useBorderColor = 0x0; - GLfloat a, b, c; - GLfloat t000[4], t010[4], t001[4], t011[4]; - GLfloat t100[4], t110[4], t101[4], t111[4]; - - linear_texel_locations(samp->Attrib.WrapS, img, width, texcoord[0], &i0, &i1, &a); - linear_texel_locations(samp->Attrib.WrapT, img, height, texcoord[1], &j0, &j1, &b); - linear_texel_locations(samp->Attrib.WrapR, img, depth, texcoord[2], &k0, &k1, &c); - - if (img->Border) { - i0 += img->Border; - i1 += img->Border; - j0 += img->Border; - j1 += img->Border; - k0 += img->Border; - k1 += img->Border; - } - else { - /* check if sampling texture border color */ - if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT; - if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT; - if (j0 < 0 || j0 >= height) useBorderColor |= J0BIT; - if (j1 < 0 || j1 >= height) useBorderColor |= J1BIT; - if (k0 < 0 || k0 >= depth) useBorderColor |= K0BIT; - if (k1 < 0 || k1 >= depth) useBorderColor |= K1BIT; - } - - /* Fetch texels */ - if (useBorderColor & (I0BIT | J0BIT | K0BIT)) { - get_border_color(samp, img, t000); - } - else { - swImg->FetchTexel(swImg, i0, j0, k0, t000); - } - if (useBorderColor & (I1BIT | J0BIT | K0BIT)) { - get_border_color(samp, img, t100); - } - else { - swImg->FetchTexel(swImg, i1, j0, k0, t100); - } - if (useBorderColor & (I0BIT | J1BIT | K0BIT)) { - get_border_color(samp, img, t010); - } - else { - swImg->FetchTexel(swImg, i0, j1, k0, t010); - } - if (useBorderColor & (I1BIT | J1BIT | K0BIT)) { - get_border_color(samp, img, t110); - } - else { - swImg->FetchTexel(swImg, i1, j1, k0, t110); - } - - if (useBorderColor & (I0BIT | J0BIT | K1BIT)) { - get_border_color(samp, img, t001); - } - else { - swImg->FetchTexel(swImg, i0, j0, k1, t001); - } - if (useBorderColor & (I1BIT | J0BIT | K1BIT)) { - get_border_color(samp, img, t101); - } - else { - swImg->FetchTexel(swImg, i1, j0, k1, t101); - } - if (useBorderColor & (I0BIT | J1BIT | K1BIT)) { - get_border_color(samp, img, t011); - } - else { - swImg->FetchTexel(swImg, i0, j1, k1, t011); - } - if (useBorderColor & (I1BIT | J1BIT | K1BIT)) { - get_border_color(samp, img, t111); - } - else { - swImg->FetchTexel(swImg, i1, j1, k1, t111); - } - - /* trilinear interpolation of samples */ - lerp_rgba_3d(rgba, a, b, c, t000, t100, t010, t110, t001, t101, t011, t111); -} - - -static void -sample_3d_nearest_mipmap_nearest(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLfloat rgba[][4] ) -{ - GLuint i; - for (i = 0; i < n; i++) { - GLint level = nearest_mipmap_level(tObj, lambda[i]); - sample_3d_nearest(ctx, samp, tObj->Image[0][level], texcoord[i], rgba[i]); - } -} - - -static void -sample_3d_linear_mipmap_nearest(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLfloat rgba[][4]) -{ - GLuint i; - assert(lambda != NULL); - for (i = 0; i < n; i++) { - GLint level = nearest_mipmap_level(tObj, lambda[i]); - sample_3d_linear(ctx, samp, tObj->Image[0][level], texcoord[i], rgba[i]); - } -} - - -static void -sample_3d_nearest_mipmap_linear(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLfloat rgba[][4]) -{ - GLuint i; - assert(lambda != NULL); - for (i = 0; i < n; i++) { - GLint level = linear_mipmap_level(tObj, lambda[i]); - if (level >= tObj->_MaxLevel) { - sample_3d_nearest(ctx, samp, tObj->Image[0][tObj->_MaxLevel], - texcoord[i], rgba[i]); - } - else { - GLfloat t0[4], t1[4]; /* texels */ - const GLfloat f = FRAC(lambda[i]); - sample_3d_nearest(ctx, samp, tObj->Image[0][level ], texcoord[i], t0); - sample_3d_nearest(ctx, samp, tObj->Image[0][level+1], texcoord[i], t1); - lerp_rgba(rgba[i], f, t0, t1); - } - } -} - - -static void -sample_3d_linear_mipmap_linear(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLfloat rgba[][4]) -{ - GLuint i; - assert(lambda != NULL); - for (i = 0; i < n; i++) { - GLint level = linear_mipmap_level(tObj, lambda[i]); - if (level >= tObj->_MaxLevel) { - sample_3d_linear(ctx, samp, tObj->Image[0][tObj->_MaxLevel], - texcoord[i], rgba[i]); - } - else { - GLfloat t0[4], t1[4]; /* texels */ - const GLfloat f = FRAC(lambda[i]); - sample_3d_linear(ctx, samp, tObj->Image[0][level ], texcoord[i], t0); - sample_3d_linear(ctx, samp, tObj->Image[0][level+1], texcoord[i], t1); - lerp_rgba(rgba[i], f, t0, t1); - } - } -} - - -/** Sample 3D texture, nearest filtering for both min/magnification */ -static void -sample_nearest_3d(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, GLuint n, - const GLfloat texcoords[][4], const GLfloat lambda[], - GLfloat rgba[][4]) -{ - GLuint i; - const struct gl_texture_image *image = _mesa_base_tex_image(tObj); - (void) lambda; - for (i = 0; i < n; i++) { - sample_3d_nearest(ctx, samp, image, texcoords[i], rgba[i]); - } -} - - -/** Sample 3D texture, linear filtering for both min/magnification */ -static void -sample_linear_3d(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, GLuint n, - const GLfloat texcoords[][4], - const GLfloat lambda[], GLfloat rgba[][4]) -{ - GLuint i; - const struct gl_texture_image *image = _mesa_base_tex_image(tObj); - (void) lambda; - for (i = 0; i < n; i++) { - sample_3d_linear(ctx, samp, image, texcoords[i], rgba[i]); - } -} - - -/** Sample 3D texture, using lambda to choose between min/magnification */ -static void -sample_lambda_3d(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, GLuint n, - const GLfloat texcoords[][4], const GLfloat lambda[], - GLfloat rgba[][4]) -{ - GLuint minStart, minEnd; /* texels with minification */ - GLuint magStart, magEnd; /* texels with magnification */ - GLuint i; - - assert(lambda != NULL); - compute_min_mag_ranges(samp, n, lambda, - &minStart, &minEnd, &magStart, &magEnd); - - if (minStart < minEnd) { - /* do the minified texels */ - GLuint m = minEnd - minStart; - switch (samp->Attrib.MinFilter) { - case GL_NEAREST: - for (i = minStart; i < minEnd; i++) - sample_3d_nearest(ctx, samp, _mesa_base_tex_image(tObj), - texcoords[i], rgba[i]); - break; - case GL_LINEAR: - for (i = minStart; i < minEnd; i++) - sample_3d_linear(ctx, samp, _mesa_base_tex_image(tObj), - texcoords[i], rgba[i]); - break; - case GL_NEAREST_MIPMAP_NEAREST: - sample_3d_nearest_mipmap_nearest(ctx, samp, tObj, m, texcoords + minStart, - lambda + minStart, rgba + minStart); - break; - case GL_LINEAR_MIPMAP_NEAREST: - sample_3d_linear_mipmap_nearest(ctx, samp, tObj, m, texcoords + minStart, - lambda + minStart, rgba + minStart); - break; - case GL_NEAREST_MIPMAP_LINEAR: - sample_3d_nearest_mipmap_linear(ctx, samp, tObj, m, texcoords + minStart, - lambda + minStart, rgba + minStart); - break; - case GL_LINEAR_MIPMAP_LINEAR: - sample_3d_linear_mipmap_linear(ctx, samp, tObj, m, texcoords + minStart, - lambda + minStart, rgba + minStart); - break; - default: - _mesa_problem(ctx, "Bad min filter in sample_3d_texture"); - return; - } - } - - if (magStart < magEnd) { - /* do the magnified texels */ - switch (samp->Attrib.MagFilter) { - case GL_NEAREST: - for (i = magStart; i < magEnd; i++) - sample_3d_nearest(ctx, samp, _mesa_base_tex_image(tObj), - texcoords[i], rgba[i]); - break; - case GL_LINEAR: - for (i = magStart; i < magEnd; i++) - sample_3d_linear(ctx, samp, _mesa_base_tex_image(tObj), - texcoords[i], rgba[i]); - break; - default: - _mesa_problem(ctx, "Bad mag filter in sample_3d_texture"); - return; - } - } -} - - -/**********************************************************************/ -/* Texture Cube Map Sampling Functions */ -/**********************************************************************/ - -/** - * Choose one of six sides of a texture cube map given the texture - * coord (rx,ry,rz). Return pointer to corresponding array of texture - * images. - */ -static const struct gl_texture_image ** -choose_cube_face(const struct gl_texture_object *texObj, - const GLfloat texcoord[4], GLfloat newCoord[4]) -{ - /* - major axis - direction target sc tc ma - ---------- ------------------------------- --- --- --- - +rx TEXTURE_CUBE_MAP_POSITIVE_X_EXT -rz -ry rx - -rx TEXTURE_CUBE_MAP_NEGATIVE_X_EXT +rz -ry rx - +ry TEXTURE_CUBE_MAP_POSITIVE_Y_EXT +rx +rz ry - -ry TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT +rx -rz ry - +rz TEXTURE_CUBE_MAP_POSITIVE_Z_EXT +rx -ry rz - -rz TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT -rx -ry rz - */ - const GLfloat rx = texcoord[0]; - const GLfloat ry = texcoord[1]; - const GLfloat rz = texcoord[2]; - const GLfloat arx = fabsf(rx), ary = fabsf(ry), arz = fabsf(rz); - GLuint face; - GLfloat sc, tc, ma; - - if (arx >= ary && arx >= arz) { - if (rx >= 0.0F) { - face = FACE_POS_X; - sc = -rz; - tc = -ry; - ma = arx; - } - else { - face = FACE_NEG_X; - sc = rz; - tc = -ry; - ma = arx; - } - } - else if (ary >= arx && ary >= arz) { - if (ry >= 0.0F) { - face = FACE_POS_Y; - sc = rx; - tc = rz; - ma = ary; - } - else { - face = FACE_NEG_Y; - sc = rx; - tc = -rz; - ma = ary; - } - } - else { - if (rz > 0.0F) { - face = FACE_POS_Z; - sc = rx; - tc = -ry; - ma = arz; - } - else { - face = FACE_NEG_Z; - sc = -rx; - tc = -ry; - ma = arz; - } - } - - { - const float ima = 1.0F / ma; - newCoord[0] = ( sc * ima + 1.0F ) * 0.5F; - newCoord[1] = ( tc * ima + 1.0F ) * 0.5F; - } - - return (const struct gl_texture_image **) texObj->Image[face]; -} - - -static void -sample_nearest_cube(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, GLuint n, - const GLfloat texcoords[][4], const GLfloat lambda[], - GLfloat rgba[][4]) -{ - GLuint i; - (void) lambda; - for (i = 0; i < n; i++) { - const struct gl_texture_image **images; - GLfloat newCoord[4]; - images = choose_cube_face(tObj, texcoords[i], newCoord); - sample_2d_nearest(ctx, samp, images[tObj->Attrib.BaseLevel], - newCoord, rgba[i]); - } - if (is_depth_texture(tObj)) { - for (i = 0; i < n; i++) { - apply_depth_mode(tObj->Attrib.DepthMode, rgba[i][0], rgba[i]); - } - } -} - - -static void -sample_linear_cube(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, GLuint n, - const GLfloat texcoords[][4], - const GLfloat lambda[], GLfloat rgba[][4]) -{ - GLuint i; - (void) lambda; - for (i = 0; i < n; i++) { - const struct gl_texture_image **images; - GLfloat newCoord[4]; - images = choose_cube_face(tObj, texcoords[i], newCoord); - sample_2d_linear(ctx, samp, images[tObj->Attrib.BaseLevel], - newCoord, rgba[i]); - } - if (is_depth_texture(tObj)) { - for (i = 0; i < n; i++) { - apply_depth_mode(tObj->Attrib.DepthMode, rgba[i][0], rgba[i]); - } - } -} - - -static void -sample_cube_nearest_mipmap_nearest(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLfloat rgba[][4]) -{ - GLuint i; - assert(lambda != NULL); - for (i = 0; i < n; i++) { - const struct gl_texture_image **images; - GLfloat newCoord[4]; - GLint level; - images = choose_cube_face(tObj, texcoord[i], newCoord); - - /* XXX we actually need to recompute lambda here based on the newCoords. - * But we would need the texcoords of adjacent fragments to compute that - * properly, and we don't have those here. - * For now, do an approximation: subtracting 1 from the chosen mipmap - * level seems to work in some test cases. - * The same adjustment is done in the next few functions. - */ - level = nearest_mipmap_level(tObj, lambda[i]); - level = MAX2(level - 1, 0); - - sample_2d_nearest(ctx, samp, images[level], newCoord, rgba[i]); - } - if (is_depth_texture(tObj)) { - for (i = 0; i < n; i++) { - apply_depth_mode(tObj->Attrib.DepthMode, rgba[i][0], rgba[i]); - } - } -} - - -static void -sample_cube_linear_mipmap_nearest(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLfloat rgba[][4]) -{ - GLuint i; - assert(lambda != NULL); - for (i = 0; i < n; i++) { - const struct gl_texture_image **images; - GLfloat newCoord[4]; - GLint level = nearest_mipmap_level(tObj, lambda[i]); - level = MAX2(level - 1, 0); /* see comment above */ - images = choose_cube_face(tObj, texcoord[i], newCoord); - sample_2d_linear(ctx, samp, images[level], newCoord, rgba[i]); - } - if (is_depth_texture(tObj)) { - for (i = 0; i < n; i++) { - apply_depth_mode(tObj->Attrib.DepthMode, rgba[i][0], rgba[i]); - } - } -} - - -static void -sample_cube_nearest_mipmap_linear(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLfloat rgba[][4]) -{ - GLuint i; - assert(lambda != NULL); - for (i = 0; i < n; i++) { - const struct gl_texture_image **images; - GLfloat newCoord[4]; - GLint level = linear_mipmap_level(tObj, lambda[i]); - level = MAX2(level - 1, 0); /* see comment above */ - images = choose_cube_face(tObj, texcoord[i], newCoord); - if (level >= tObj->_MaxLevel) { - sample_2d_nearest(ctx, samp, images[tObj->_MaxLevel], - newCoord, rgba[i]); - } - else { - GLfloat t0[4], t1[4]; /* texels */ - const GLfloat f = FRAC(lambda[i]); - sample_2d_nearest(ctx, samp, images[level ], newCoord, t0); - sample_2d_nearest(ctx, samp, images[level+1], newCoord, t1); - lerp_rgba(rgba[i], f, t0, t1); - } - } - if (is_depth_texture(tObj)) { - for (i = 0; i < n; i++) { - apply_depth_mode(tObj->Attrib.DepthMode, rgba[i][0], rgba[i]); - } - } -} - - -static void -sample_cube_linear_mipmap_linear(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLfloat rgba[][4]) -{ - GLuint i; - assert(lambda != NULL); - for (i = 0; i < n; i++) { - const struct gl_texture_image **images; - GLfloat newCoord[4]; - GLint level = linear_mipmap_level(tObj, lambda[i]); - level = MAX2(level - 1, 0); /* see comment above */ - images = choose_cube_face(tObj, texcoord[i], newCoord); - if (level >= tObj->_MaxLevel) { - sample_2d_linear(ctx, samp, images[tObj->_MaxLevel], - newCoord, rgba[i]); - } - else { - GLfloat t0[4], t1[4]; - const GLfloat f = FRAC(lambda[i]); - sample_2d_linear(ctx, samp, images[level ], newCoord, t0); - sample_2d_linear(ctx, samp, images[level+1], newCoord, t1); - lerp_rgba(rgba[i], f, t0, t1); - } - } - if (is_depth_texture(tObj)) { - for (i = 0; i < n; i++) { - apply_depth_mode(tObj->Attrib.DepthMode, rgba[i][0], rgba[i]); - } - } -} - - -/** Sample cube texture, using lambda to choose between min/magnification */ -static void -sample_lambda_cube(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, GLuint n, - const GLfloat texcoords[][4], const GLfloat lambda[], - GLfloat rgba[][4]) -{ - GLuint minStart, minEnd; /* texels with minification */ - GLuint magStart, magEnd; /* texels with magnification */ - - assert(lambda != NULL); - compute_min_mag_ranges(samp, n, lambda, - &minStart, &minEnd, &magStart, &magEnd); - - if (minStart < minEnd) { - /* do the minified texels */ - const GLuint m = minEnd - minStart; - switch (samp->Attrib.MinFilter) { - case GL_NEAREST: - sample_nearest_cube(ctx, samp, tObj, m, texcoords + minStart, - lambda + minStart, rgba + minStart); - break; - case GL_LINEAR: - sample_linear_cube(ctx, samp, tObj, m, texcoords + minStart, - lambda + minStart, rgba + minStart); - break; - case GL_NEAREST_MIPMAP_NEAREST: - sample_cube_nearest_mipmap_nearest(ctx, samp, tObj, m, - texcoords + minStart, - lambda + minStart, rgba + minStart); - break; - case GL_LINEAR_MIPMAP_NEAREST: - sample_cube_linear_mipmap_nearest(ctx, samp, tObj, m, - texcoords + minStart, - lambda + minStart, rgba + minStart); - break; - case GL_NEAREST_MIPMAP_LINEAR: - sample_cube_nearest_mipmap_linear(ctx, samp, tObj, m, - texcoords + minStart, - lambda + minStart, rgba + minStart); - break; - case GL_LINEAR_MIPMAP_LINEAR: - sample_cube_linear_mipmap_linear(ctx, samp, tObj, m, - texcoords + minStart, - lambda + minStart, rgba + minStart); - break; - default: - _mesa_problem(ctx, "Bad min filter in sample_lambda_cube"); - break; - } - } - - if (magStart < magEnd) { - /* do the magnified texels */ - const GLuint m = magEnd - magStart; - switch (samp->Attrib.MagFilter) { - case GL_NEAREST: - sample_nearest_cube(ctx, samp, tObj, m, texcoords + magStart, - lambda + magStart, rgba + magStart); - break; - case GL_LINEAR: - sample_linear_cube(ctx, samp, tObj, m, texcoords + magStart, - lambda + magStart, rgba + magStart); - break; - default: - _mesa_problem(ctx, "Bad mag filter in sample_lambda_cube"); - break; - } - } -} - - -/**********************************************************************/ -/* Texture Rectangle Sampling Functions */ -/**********************************************************************/ - - -static void -sample_nearest_rect(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, GLuint n, - const GLfloat texcoords[][4], const GLfloat lambda[], - GLfloat rgba[][4]) -{ - const struct gl_texture_image *img = tObj->Image[0][0]; - const struct swrast_texture_image *swImg = swrast_texture_image_const(img); - const GLint width = img->Width; - const GLint height = img->Height; - GLuint i; - - (void) ctx; - (void) lambda; - - assert(samp->Attrib.WrapS == GL_CLAMP || - samp->Attrib.WrapS == GL_CLAMP_TO_EDGE || - samp->Attrib.WrapS == GL_CLAMP_TO_BORDER); - assert(samp->Attrib.WrapT == GL_CLAMP || - samp->Attrib.WrapT == GL_CLAMP_TO_EDGE || - samp->Attrib.WrapT == GL_CLAMP_TO_BORDER); - - for (i = 0; i < n; i++) { - GLint row, col; - col = clamp_rect_coord_nearest(samp->Attrib.WrapS, texcoords[i][0], width); - row = clamp_rect_coord_nearest(samp->Attrib.WrapT, texcoords[i][1], height); - if (col < 0 || col >= width || row < 0 || row >= height) - get_border_color(samp, img, rgba[i]); - else - swImg->FetchTexel(swImg, col, row, 0, rgba[i]); - } -} - - -static void -sample_linear_rect(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, GLuint n, - const GLfloat texcoords[][4], - const GLfloat lambda[], GLfloat rgba[][4]) -{ - const struct gl_texture_image *img = tObj->Image[0][0]; - const struct swrast_texture_image *swImg = swrast_texture_image_const(img); - const GLint width = img->Width; - const GLint height = img->Height; - GLuint i; - - (void) ctx; - (void) lambda; - - assert(samp->Attrib.WrapS == GL_CLAMP || - samp->Attrib.WrapS == GL_CLAMP_TO_EDGE || - samp->Attrib.WrapS == GL_CLAMP_TO_BORDER); - assert(samp->Attrib.WrapT == GL_CLAMP || - samp->Attrib.WrapT == GL_CLAMP_TO_EDGE || - samp->Attrib.WrapT == GL_CLAMP_TO_BORDER); - - for (i = 0; i < n; i++) { - GLint i0, j0, i1, j1; - GLfloat t00[4], t01[4], t10[4], t11[4]; - GLfloat a, b; - GLbitfield useBorderColor = 0x0; - - clamp_rect_coord_linear(samp->Attrib.WrapS, texcoords[i][0], width, - &i0, &i1, &a); - clamp_rect_coord_linear(samp->Attrib.WrapT, texcoords[i][1], height, - &j0, &j1, &b); - - /* compute integer rows/columns */ - if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT; - if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT; - if (j0 < 0 || j0 >= height) useBorderColor |= J0BIT; - if (j1 < 0 || j1 >= height) useBorderColor |= J1BIT; - - /* get four texel samples */ - if (useBorderColor & (I0BIT | J0BIT)) - get_border_color(samp, img, t00); - else - swImg->FetchTexel(swImg, i0, j0, 0, t00); - - if (useBorderColor & (I1BIT | J0BIT)) - get_border_color(samp, img, t10); - else - swImg->FetchTexel(swImg, i1, j0, 0, t10); - - if (useBorderColor & (I0BIT | J1BIT)) - get_border_color(samp, img, t01); - else - swImg->FetchTexel(swImg, i0, j1, 0, t01); - - if (useBorderColor & (I1BIT | J1BIT)) - get_border_color(samp, img, t11); - else - swImg->FetchTexel(swImg, i1, j1, 0, t11); - - lerp_rgba_2d(rgba[i], a, b, t00, t10, t01, t11); - } -} - - -/** Sample Rect texture, using lambda to choose between min/magnification */ -static void -sample_lambda_rect(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, GLuint n, - const GLfloat texcoords[][4], const GLfloat lambda[], - GLfloat rgba[][4]) -{ - GLuint minStart, minEnd, magStart, magEnd; - - /* We only need lambda to decide between minification and magnification. - * There is no mipmapping with rectangular textures. - */ - compute_min_mag_ranges(samp, n, lambda, - &minStart, &minEnd, &magStart, &magEnd); - - if (minStart < minEnd) { - if (samp->Attrib.MinFilter == GL_NEAREST) { - sample_nearest_rect(ctx, samp, tObj, minEnd - minStart, - texcoords + minStart, NULL, rgba + minStart); - } - else { - sample_linear_rect(ctx, samp, tObj, minEnd - minStart, - texcoords + minStart, NULL, rgba + minStart); - } - } - if (magStart < magEnd) { - if (samp->Attrib.MagFilter == GL_NEAREST) { - sample_nearest_rect(ctx, samp, tObj, magEnd - magStart, - texcoords + magStart, NULL, rgba + magStart); - } - else { - sample_linear_rect(ctx, samp, tObj, magEnd - magStart, - texcoords + magStart, NULL, rgba + magStart); - } - } -} - - -/**********************************************************************/ -/* 2D Texture Array Sampling Functions */ -/**********************************************************************/ - -/** - * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter. - */ -static void -sample_2d_array_nearest(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_image *img, - const GLfloat texcoord[4], - GLfloat rgba[4]) -{ - const struct swrast_texture_image *swImg = swrast_texture_image_const(img); - const GLint width = img->Width2; /* without border, power of two */ - const GLint height = img->Height2; /* without border, power of two */ - const GLint depth = img->Depth; - GLint i, j; - GLint array; - (void) ctx; - - i = nearest_texel_location(samp->Attrib.WrapS, img, width, texcoord[0]); - j = nearest_texel_location(samp->Attrib.WrapT, img, height, texcoord[1]); - array = tex_array_slice(texcoord[2], depth); - - if (i < 0 || i >= (GLint) img->Width || - j < 0 || j >= (GLint) img->Height || - array < 0 || array >= (GLint) img->Depth) { - /* Need this test for GL_CLAMP_TO_BORDER mode */ - get_border_color(samp, img, rgba); - } - else { - swImg->FetchTexel(swImg, i, j, array, rgba); - } -} - - -/** - * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter. - */ -static void -sample_2d_array_linear(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_image *img, - const GLfloat texcoord[4], - GLfloat rgba[4]) -{ - const struct swrast_texture_image *swImg = swrast_texture_image_const(img); - const GLint width = img->Width2; - const GLint height = img->Height2; - const GLint depth = img->Depth; - GLint i0, j0, i1, j1; - GLint array; - GLbitfield useBorderColor = 0x0; - GLfloat a, b; - GLfloat t00[4], t01[4], t10[4], t11[4]; - - linear_texel_locations(samp->Attrib.WrapS, img, width, texcoord[0], &i0, &i1, &a); - linear_texel_locations(samp->Attrib.WrapT, img, height, texcoord[1], &j0, &j1, &b); - array = tex_array_slice(texcoord[2], depth); - - if (array < 0 || array >= depth) { - COPY_4V(rgba, samp->Attrib.state.border_color.f); - } - else { - if (img->Border) { - i0 += img->Border; - i1 += img->Border; - j0 += img->Border; - j1 += img->Border; - } - else { - /* check if sampling texture border color */ - if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT; - if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT; - if (j0 < 0 || j0 >= height) useBorderColor |= J0BIT; - if (j1 < 0 || j1 >= height) useBorderColor |= J1BIT; - } - - /* Fetch texels */ - if (useBorderColor & (I0BIT | J0BIT)) { - get_border_color(samp, img, t00); - } - else { - swImg->FetchTexel(swImg, i0, j0, array, t00); - } - if (useBorderColor & (I1BIT | J0BIT)) { - get_border_color(samp, img, t10); - } - else { - swImg->FetchTexel(swImg, i1, j0, array, t10); - } - if (useBorderColor & (I0BIT | J1BIT)) { - get_border_color(samp, img, t01); - } - else { - swImg->FetchTexel(swImg, i0, j1, array, t01); - } - if (useBorderColor & (I1BIT | J1BIT)) { - get_border_color(samp, img, t11); - } - else { - swImg->FetchTexel(swImg, i1, j1, array, t11); - } - - /* trilinear interpolation of samples */ - lerp_rgba_2d(rgba, a, b, t00, t10, t01, t11); - } -} - - -static void -sample_2d_array_nearest_mipmap_nearest(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLfloat rgba[][4]) -{ - GLuint i; - for (i = 0; i < n; i++) { - GLint level = nearest_mipmap_level(tObj, lambda[i]); - sample_2d_array_nearest(ctx, samp, tObj->Image[0][level], texcoord[i], - rgba[i]); - } -} - - -static void -sample_2d_array_linear_mipmap_nearest(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLfloat rgba[][4]) -{ - GLuint i; - assert(lambda != NULL); - for (i = 0; i < n; i++) { - GLint level = nearest_mipmap_level(tObj, lambda[i]); - sample_2d_array_linear(ctx, samp, tObj->Image[0][level], - texcoord[i], rgba[i]); - } -} - - -static void -sample_2d_array_nearest_mipmap_linear(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLfloat rgba[][4]) -{ - GLuint i; - assert(lambda != NULL); - for (i = 0; i < n; i++) { - GLint level = linear_mipmap_level(tObj, lambda[i]); - if (level >= tObj->_MaxLevel) { - sample_2d_array_nearest(ctx, samp, tObj->Image[0][tObj->_MaxLevel], - texcoord[i], rgba[i]); - } - else { - GLfloat t0[4], t1[4]; /* texels */ - const GLfloat f = FRAC(lambda[i]); - sample_2d_array_nearest(ctx, samp, tObj->Image[0][level ], - texcoord[i], t0); - sample_2d_array_nearest(ctx, samp, tObj->Image[0][level+1], - texcoord[i], t1); - lerp_rgba(rgba[i], f, t0, t1); - } - } -} - - -static void -sample_2d_array_linear_mipmap_linear(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLfloat rgba[][4]) -{ - GLuint i; - assert(lambda != NULL); - for (i = 0; i < n; i++) { - GLint level = linear_mipmap_level(tObj, lambda[i]); - if (level >= tObj->_MaxLevel) { - sample_2d_array_linear(ctx, samp, tObj->Image[0][tObj->_MaxLevel], - texcoord[i], rgba[i]); - } - else { - GLfloat t0[4], t1[4]; /* texels */ - const GLfloat f = FRAC(lambda[i]); - sample_2d_array_linear(ctx, samp, tObj->Image[0][level ], - texcoord[i], t0); - sample_2d_array_linear(ctx, samp, tObj->Image[0][level+1], - texcoord[i], t1); - lerp_rgba(rgba[i], f, t0, t1); - } - } -} - - -/** Sample 2D Array texture, nearest filtering for both min/magnification */ -static void -sample_nearest_2d_array(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, GLuint n, - const GLfloat texcoords[][4], const GLfloat lambda[], - GLfloat rgba[][4]) -{ - GLuint i; - const struct gl_texture_image *image = _mesa_base_tex_image(tObj); - (void) lambda; - for (i = 0; i < n; i++) { - sample_2d_array_nearest(ctx, samp, image, texcoords[i], rgba[i]); - } -} - - - -/** Sample 2D Array texture, linear filtering for both min/magnification */ -static void -sample_linear_2d_array(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, GLuint n, - const GLfloat texcoords[][4], - const GLfloat lambda[], GLfloat rgba[][4]) -{ - GLuint i; - const struct gl_texture_image *image = _mesa_base_tex_image(tObj); - (void) lambda; - for (i = 0; i < n; i++) { - sample_2d_array_linear(ctx, samp, image, texcoords[i], rgba[i]); - } -} - - -/** Sample 2D Array texture, using lambda to choose between min/magnification */ -static void -sample_lambda_2d_array(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, GLuint n, - const GLfloat texcoords[][4], const GLfloat lambda[], - GLfloat rgba[][4]) -{ - GLuint minStart, minEnd; /* texels with minification */ - GLuint magStart, magEnd; /* texels with magnification */ - GLuint i; - - assert(lambda != NULL); - compute_min_mag_ranges(samp, n, lambda, - &minStart, &minEnd, &magStart, &magEnd); - - if (minStart < minEnd) { - /* do the minified texels */ - GLuint m = minEnd - minStart; - switch (samp->Attrib.MinFilter) { - case GL_NEAREST: - for (i = minStart; i < minEnd; i++) - sample_2d_array_nearest(ctx, samp, _mesa_base_tex_image(tObj), - texcoords[i], rgba[i]); - break; - case GL_LINEAR: - for (i = minStart; i < minEnd; i++) - sample_2d_array_linear(ctx, samp, _mesa_base_tex_image(tObj), - texcoords[i], rgba[i]); - break; - case GL_NEAREST_MIPMAP_NEAREST: - sample_2d_array_nearest_mipmap_nearest(ctx, samp, tObj, m, - texcoords + minStart, - lambda + minStart, - rgba + minStart); - break; - case GL_LINEAR_MIPMAP_NEAREST: - sample_2d_array_linear_mipmap_nearest(ctx, samp, tObj, m, - texcoords + minStart, - lambda + minStart, - rgba + minStart); - break; - case GL_NEAREST_MIPMAP_LINEAR: - sample_2d_array_nearest_mipmap_linear(ctx, samp, tObj, m, - texcoords + minStart, - lambda + minStart, - rgba + minStart); - break; - case GL_LINEAR_MIPMAP_LINEAR: - sample_2d_array_linear_mipmap_linear(ctx, samp, tObj, m, - texcoords + minStart, - lambda + minStart, - rgba + minStart); - break; - default: - _mesa_problem(ctx, "Bad min filter in sample_2d_array_texture"); - return; - } - } - - if (magStart < magEnd) { - /* do the magnified texels */ - switch (samp->Attrib.MagFilter) { - case GL_NEAREST: - for (i = magStart; i < magEnd; i++) - sample_2d_array_nearest(ctx, samp, _mesa_base_tex_image(tObj), - texcoords[i], rgba[i]); - break; - case GL_LINEAR: - for (i = magStart; i < magEnd; i++) - sample_2d_array_linear(ctx, samp, _mesa_base_tex_image(tObj), - texcoords[i], rgba[i]); - break; - default: - _mesa_problem(ctx, "Bad mag filter in sample_2d_array_texture"); - return; - } - } -} - - - - -/**********************************************************************/ -/* 1D Texture Array Sampling Functions */ -/**********************************************************************/ - -/** - * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter. - */ -static void -sample_1d_array_nearest(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_image *img, - const GLfloat texcoord[4], - GLfloat rgba[4]) -{ - const struct swrast_texture_image *swImg = swrast_texture_image_const(img); - const GLint width = img->Width2; /* without border, power of two */ - const GLint height = img->Height; - GLint i; - GLint array; - (void) ctx; - - i = nearest_texel_location(samp->Attrib.WrapS, img, width, texcoord[0]); - array = tex_array_slice(texcoord[1], height); - - if (i < 0 || i >= (GLint) img->Width || - array < 0 || array >= (GLint) img->Height) { - /* Need this test for GL_CLAMP_TO_BORDER mode */ - get_border_color(samp, img, rgba); - } - else { - swImg->FetchTexel(swImg, i, array, 0, rgba); - } -} - - -/** - * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter. - */ -static void -sample_1d_array_linear(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_image *img, - const GLfloat texcoord[4], - GLfloat rgba[4]) -{ - const struct swrast_texture_image *swImg = swrast_texture_image_const(img); - const GLint width = img->Width2; - const GLint height = img->Height; - GLint i0, i1; - GLint array; - GLbitfield useBorderColor = 0x0; - GLfloat a; - GLfloat t0[4], t1[4]; - - linear_texel_locations(samp->Attrib.WrapS, img, width, texcoord[0], &i0, &i1, &a); - array = tex_array_slice(texcoord[1], height); - - if (img->Border) { - i0 += img->Border; - i1 += img->Border; - } - else { - /* check if sampling texture border color */ - if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT; - if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT; - } - - if (array < 0 || array >= height) useBorderColor |= K0BIT; - - /* Fetch texels */ - if (useBorderColor & (I0BIT | K0BIT)) { - get_border_color(samp, img, t0); - } - else { - swImg->FetchTexel(swImg, i0, array, 0, t0); - } - if (useBorderColor & (I1BIT | K0BIT)) { - get_border_color(samp, img, t1); - } - else { - swImg->FetchTexel(swImg, i1, array, 0, t1); - } - - /* bilinear interpolation of samples */ - lerp_rgba(rgba, a, t0, t1); -} - - -static void -sample_1d_array_nearest_mipmap_nearest(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLfloat rgba[][4]) -{ - GLuint i; - for (i = 0; i < n; i++) { - GLint level = nearest_mipmap_level(tObj, lambda[i]); - sample_1d_array_nearest(ctx, samp, tObj->Image[0][level], texcoord[i], - rgba[i]); - } -} - - -static void -sample_1d_array_linear_mipmap_nearest(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLfloat rgba[][4]) -{ - GLuint i; - assert(lambda != NULL); - for (i = 0; i < n; i++) { - GLint level = nearest_mipmap_level(tObj, lambda[i]); - sample_1d_array_linear(ctx, samp, tObj->Image[0][level], - texcoord[i], rgba[i]); - } -} - - -static void -sample_1d_array_nearest_mipmap_linear(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLfloat rgba[][4]) -{ - GLuint i; - assert(lambda != NULL); - for (i = 0; i < n; i++) { - GLint level = linear_mipmap_level(tObj, lambda[i]); - if (level >= tObj->_MaxLevel) { - sample_1d_array_nearest(ctx, samp, tObj->Image[0][tObj->_MaxLevel], - texcoord[i], rgba[i]); - } - else { - GLfloat t0[4], t1[4]; /* texels */ - const GLfloat f = FRAC(lambda[i]); - sample_1d_array_nearest(ctx, samp, tObj->Image[0][level ], texcoord[i], t0); - sample_1d_array_nearest(ctx, samp, tObj->Image[0][level+1], texcoord[i], t1); - lerp_rgba(rgba[i], f, t0, t1); - } - } -} - - -static void -sample_1d_array_linear_mipmap_linear(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, - GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLfloat rgba[][4]) -{ - GLuint i; - assert(lambda != NULL); - for (i = 0; i < n; i++) { - GLint level = linear_mipmap_level(tObj, lambda[i]); - if (level >= tObj->_MaxLevel) { - sample_1d_array_linear(ctx, samp, tObj->Image[0][tObj->_MaxLevel], - texcoord[i], rgba[i]); - } - else { - GLfloat t0[4], t1[4]; /* texels */ - const GLfloat f = FRAC(lambda[i]); - sample_1d_array_linear(ctx, samp, tObj->Image[0][level ], texcoord[i], t0); - sample_1d_array_linear(ctx, samp, tObj->Image[0][level+1], texcoord[i], t1); - lerp_rgba(rgba[i], f, t0, t1); - } - } -} - - -/** Sample 1D Array texture, nearest filtering for both min/magnification */ -static void -sample_nearest_1d_array(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, GLuint n, - const GLfloat texcoords[][4], const GLfloat lambda[], - GLfloat rgba[][4]) -{ - GLuint i; - const struct gl_texture_image *image = _mesa_base_tex_image(tObj); - (void) lambda; - for (i = 0; i < n; i++) { - sample_1d_array_nearest(ctx, samp, image, texcoords[i], rgba[i]); - } -} - - -/** Sample 1D Array texture, linear filtering for both min/magnification */ -static void -sample_linear_1d_array(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, GLuint n, - const GLfloat texcoords[][4], - const GLfloat lambda[], GLfloat rgba[][4]) -{ - GLuint i; - const struct gl_texture_image *image = _mesa_base_tex_image(tObj); - (void) lambda; - for (i = 0; i < n; i++) { - sample_1d_array_linear(ctx, samp, image, texcoords[i], rgba[i]); - } -} - - -/** Sample 1D Array texture, using lambda to choose between min/magnification */ -static void -sample_lambda_1d_array(struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, GLuint n, - const GLfloat texcoords[][4], const GLfloat lambda[], - GLfloat rgba[][4]) -{ - GLuint minStart, minEnd; /* texels with minification */ - GLuint magStart, magEnd; /* texels with magnification */ - GLuint i; - - assert(lambda != NULL); - compute_min_mag_ranges(samp, n, lambda, - &minStart, &minEnd, &magStart, &magEnd); - - if (minStart < minEnd) { - /* do the minified texels */ - GLuint m = minEnd - minStart; - switch (samp->Attrib.MinFilter) { - case GL_NEAREST: - for (i = minStart; i < minEnd; i++) - sample_1d_array_nearest(ctx, samp, _mesa_base_tex_image(tObj), - texcoords[i], rgba[i]); - break; - case GL_LINEAR: - for (i = minStart; i < minEnd; i++) - sample_1d_array_linear(ctx, samp, _mesa_base_tex_image(tObj), - texcoords[i], rgba[i]); - break; - case GL_NEAREST_MIPMAP_NEAREST: - sample_1d_array_nearest_mipmap_nearest(ctx, samp, tObj, m, texcoords + minStart, - lambda + minStart, rgba + minStart); - break; - case GL_LINEAR_MIPMAP_NEAREST: - sample_1d_array_linear_mipmap_nearest(ctx, samp, tObj, m, - texcoords + minStart, - lambda + minStart, - rgba + minStart); - break; - case GL_NEAREST_MIPMAP_LINEAR: - sample_1d_array_nearest_mipmap_linear(ctx, samp, tObj, m, texcoords + minStart, - lambda + minStart, rgba + minStart); - break; - case GL_LINEAR_MIPMAP_LINEAR: - sample_1d_array_linear_mipmap_linear(ctx, samp, tObj, m, - texcoords + minStart, - lambda + minStart, - rgba + minStart); - break; - default: - _mesa_problem(ctx, "Bad min filter in sample_1d_array_texture"); - return; - } - } - - if (magStart < magEnd) { - /* do the magnified texels */ - switch (samp->Attrib.MagFilter) { - case GL_NEAREST: - for (i = magStart; i < magEnd; i++) - sample_1d_array_nearest(ctx, samp, _mesa_base_tex_image(tObj), - texcoords[i], rgba[i]); - break; - case GL_LINEAR: - for (i = magStart; i < magEnd; i++) - sample_1d_array_linear(ctx, samp, _mesa_base_tex_image(tObj), - texcoords[i], rgba[i]); - break; - default: - _mesa_problem(ctx, "Bad mag filter in sample_1d_array_texture"); - return; - } - } -} - - -/** - * Compare texcoord against depth sample. Return 1.0 or 0.0 value. - */ -static GLfloat -shadow_compare(GLenum function, GLfloat coord, GLfloat depthSample) -{ - switch (function) { - case GL_LEQUAL: - return (coord <= depthSample) ? 1.0F : 0.0F; - case GL_GEQUAL: - return (coord >= depthSample) ? 1.0F : 0.0F; - case GL_LESS: - return (coord < depthSample) ? 1.0F : 0.0F; - case GL_GREATER: - return (coord > depthSample) ? 1.0F : 0.0F; - case GL_EQUAL: - return (coord == depthSample) ? 1.0F : 0.0F; - case GL_NOTEQUAL: - return (coord != depthSample) ? 1.0F : 0.0F; - case GL_ALWAYS: - return 1.0F; - case GL_NEVER: - return 0.0F; - case GL_NONE: - return depthSample; - default: - _mesa_problem(NULL, "Bad compare func in shadow_compare"); - return 0.0F; - } -} - - -/** - * Compare texcoord against four depth samples. - */ -static GLfloat -shadow_compare4(GLenum function, GLfloat coord, - GLfloat depth00, GLfloat depth01, - GLfloat depth10, GLfloat depth11, - GLfloat wi, GLfloat wj) -{ - const GLfloat d = 0.25F; - GLfloat luminance = 1.0F; - - switch (function) { - case GL_LEQUAL: - if (coord > depth00) luminance -= d; - if (coord > depth01) luminance -= d; - if (coord > depth10) luminance -= d; - if (coord > depth11) luminance -= d; - return luminance; - case GL_GEQUAL: - if (coord < depth00) luminance -= d; - if (coord < depth01) luminance -= d; - if (coord < depth10) luminance -= d; - if (coord < depth11) luminance -= d; - return luminance; - case GL_LESS: - if (coord >= depth00) luminance -= d; - if (coord >= depth01) luminance -= d; - if (coord >= depth10) luminance -= d; - if (coord >= depth11) luminance -= d; - return luminance; - case GL_GREATER: - if (coord <= depth00) luminance -= d; - if (coord <= depth01) luminance -= d; - if (coord <= depth10) luminance -= d; - if (coord <= depth11) luminance -= d; - return luminance; - case GL_EQUAL: - if (coord != depth00) luminance -= d; - if (coord != depth01) luminance -= d; - if (coord != depth10) luminance -= d; - if (coord != depth11) luminance -= d; - return luminance; - case GL_NOTEQUAL: - if (coord == depth00) luminance -= d; - if (coord == depth01) luminance -= d; - if (coord == depth10) luminance -= d; - if (coord == depth11) luminance -= d; - return luminance; - case GL_ALWAYS: - return 1.0F; - case GL_NEVER: - return 0.0F; - case GL_NONE: - /* ordinary bilinear filtering */ - return lerp_2d(wi, wj, depth00, depth10, depth01, depth11); - default: - _mesa_problem(NULL, "Bad compare func in sample_compare4"); - return 0.0F; - } -} - - -/** - * Choose the mipmap level to use when sampling from a depth texture. - */ -static int -choose_depth_texture_level(const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, GLfloat lambda) -{ - GLint level; - - if (samp->Attrib.MinFilter == GL_NEAREST || samp->Attrib.MinFilter == GL_LINEAR) { - /* no mipmapping - use base level */ - level = tObj->Attrib.BaseLevel; - } - else { - /* choose mipmap level */ - lambda = CLAMP(lambda, samp->Attrib.MinLod, samp->Attrib.MaxLod); - level = (GLint) lambda; - level = CLAMP(level, tObj->Attrib.BaseLevel, tObj->_MaxLevel); - } - - return level; -} - - -/** - * Sample a shadow/depth texture. This function is incomplete. It doesn't - * check for minification vs. magnification, etc. - */ -static void -sample_depth_texture( struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, GLuint n, - const GLfloat texcoords[][4], const GLfloat lambda[], - GLfloat texel[][4] ) -{ - const GLint level = choose_depth_texture_level(samp, tObj, lambda[0]); - const struct gl_texture_image *img = tObj->Image[0][level]; - const struct swrast_texture_image *swImg = swrast_texture_image_const(img); - const GLint width = img->Width; - const GLint height = img->Height; - const GLint depth = img->Depth; - const GLuint compare_coord = (tObj->Target == GL_TEXTURE_2D_ARRAY_EXT) - ? 3 : 2; - GLenum function; - GLfloat result; - - assert(img->_BaseFormat == GL_DEPTH_COMPONENT || - img->_BaseFormat == GL_DEPTH_STENCIL_EXT); - - assert(tObj->Target == GL_TEXTURE_1D || - tObj->Target == GL_TEXTURE_2D || - tObj->Target == GL_TEXTURE_RECTANGLE_NV || - tObj->Target == GL_TEXTURE_1D_ARRAY_EXT || - tObj->Target == GL_TEXTURE_2D_ARRAY_EXT || - tObj->Target == GL_TEXTURE_CUBE_MAP); - - /* XXXX if samp->MinFilter != samp->MagFilter, we're ignoring lambda */ - - function = (samp->Attrib.CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB) ? - samp->Attrib.CompareFunc : GL_NONE; - - if (samp->Attrib.MagFilter == GL_NEAREST) { - GLuint i; - for (i = 0; i < n; i++) { - GLfloat depthSample, depthRef; - GLint col, row, slice; - - nearest_texcoord(samp, tObj, level, texcoords[i], &col, &row, &slice); - - if (col >= 0 && row >= 0 && col < width && row < height && - slice >= 0 && slice < depth) { - swImg->FetchTexel(swImg, col, row, slice, &depthSample); - } - else { - depthSample = samp->Attrib.state.border_color.f[0]; - } - - depthRef = CLAMP(texcoords[i][compare_coord], 0.0F, 1.0F); - - result = shadow_compare(function, depthRef, depthSample); - - apply_depth_mode(tObj->Attrib.DepthMode, result, texel[i]); - } - } - else { - GLuint i; - assert(samp->Attrib.MagFilter == GL_LINEAR); - for (i = 0; i < n; i++) { - GLfloat depth00, depth01, depth10, depth11, depthRef; - GLint i0, i1, j0, j1; - GLint slice; - GLfloat wi, wj; - GLuint useBorderTexel; - - linear_texcoord(samp, tObj, level, texcoords[i], &i0, &i1, &j0, &j1, &slice, - &wi, &wj); - - useBorderTexel = 0; - if (img->Border) { - i0 += img->Border; - i1 += img->Border; - if (tObj->Target != GL_TEXTURE_1D_ARRAY_EXT) { - j0 += img->Border; - j1 += img->Border; - } - } - else { - if (i0 < 0 || i0 >= (GLint) width) useBorderTexel |= I0BIT; - if (i1 < 0 || i1 >= (GLint) width) useBorderTexel |= I1BIT; - if (j0 < 0 || j0 >= (GLint) height) useBorderTexel |= J0BIT; - if (j1 < 0 || j1 >= (GLint) height) useBorderTexel |= J1BIT; - } - - if (slice < 0 || slice >= (GLint) depth) { - depth00 = samp->Attrib.state.border_color.f[0]; - depth01 = samp->Attrib.state.border_color.f[0]; - depth10 = samp->Attrib.state.border_color.f[0]; - depth11 = samp->Attrib.state.border_color.f[0]; - } - else { - /* get four depth samples from the texture */ - if (useBorderTexel & (I0BIT | J0BIT)) { - depth00 = samp->Attrib.state.border_color.f[0]; - } - else { - swImg->FetchTexel(swImg, i0, j0, slice, &depth00); - } - if (useBorderTexel & (I1BIT | J0BIT)) { - depth10 = samp->Attrib.state.border_color.f[0]; - } - else { - swImg->FetchTexel(swImg, i1, j0, slice, &depth10); - } - - if (tObj->Target != GL_TEXTURE_1D_ARRAY_EXT) { - if (useBorderTexel & (I0BIT | J1BIT)) { - depth01 = samp->Attrib.state.border_color.f[0]; - } - else { - swImg->FetchTexel(swImg, i0, j1, slice, &depth01); - } - if (useBorderTexel & (I1BIT | J1BIT)) { - depth11 = samp->Attrib.state.border_color.f[0]; - } - else { - swImg->FetchTexel(swImg, i1, j1, slice, &depth11); - } - } - else { - depth01 = depth00; - depth11 = depth10; - } - } - - depthRef = CLAMP(texcoords[i][compare_coord], 0.0F, 1.0F); - - result = shadow_compare4(function, depthRef, - depth00, depth01, depth10, depth11, - wi, wj); - - apply_depth_mode(tObj->Attrib.DepthMode, result, texel[i]); - } /* for */ - } /* if filter */ -} - - -/** - * We use this function when a texture object is in an "incomplete" state. - * When a fragment program attempts to sample an incomplete texture we - * return black (see issue 23 in GL_ARB_fragment_program spec). - * Note: fragment programs don't observe the texture enable/disable flags. - */ -static void -null_sample_func( struct gl_context *ctx, - const struct gl_sampler_object *samp, - const struct gl_texture_object *tObj, GLuint n, - const GLfloat texcoords[][4], const GLfloat lambda[], - GLfloat rgba[][4]) -{ - GLuint i; - (void) ctx; - (void) tObj; - (void) texcoords; - (void) lambda; - (void) samp; - for (i = 0; i < n; i++) { - rgba[i][RCOMP] = 0; - rgba[i][GCOMP] = 0; - rgba[i][BCOMP] = 0; - rgba[i][ACOMP] = 1.0; - } -} - - -/** - * Choose the texture sampling function for the given texture object. - */ -texture_sample_func -_swrast_choose_texture_sample_func( struct gl_context *ctx, - const struct gl_texture_object *t, - const struct gl_sampler_object *sampler) -{ - if (!t || !_mesa_is_texture_complete(t, sampler, - ctx->Const.ForceIntegerTexNearest)) { - return null_sample_func; - } - else { - const GLboolean needLambda = - (GLboolean) (sampler->Attrib.MinFilter != sampler->Attrib.MagFilter); - - switch (t->Target) { - case GL_TEXTURE_1D: - if (is_depth_texture(t)) { - return sample_depth_texture; - } - else if (needLambda) { - return sample_lambda_1d; - } - else if (sampler->Attrib.MinFilter == GL_LINEAR) { - return sample_linear_1d; - } - else { - assert(sampler->Attrib.MinFilter == GL_NEAREST); - return sample_nearest_1d; - } - case GL_TEXTURE_2D: - if (is_depth_texture(t)) { - return sample_depth_texture; - } - else if (needLambda) { - /* Anisotropic filtering extension. Activated only if mipmaps are used */ - if (sampler->Attrib.MaxAnisotropy > 1.0F && - sampler->Attrib.MinFilter == GL_LINEAR_MIPMAP_LINEAR) { - return sample_lambda_2d_aniso; - } - return sample_lambda_2d; - } - else if (sampler->Attrib.MinFilter == GL_LINEAR) { - return sample_linear_2d; - } - else { - /* check for a few optimized cases */ - const struct gl_texture_image *img = _mesa_base_tex_image(t); - const struct swrast_texture_image *swImg = - swrast_texture_image_const(img); - texture_sample_func func; - - assert(sampler->Attrib.MinFilter == GL_NEAREST); - func = &sample_nearest_2d; - if (sampler->Attrib.WrapS == GL_REPEAT && - sampler->Attrib.WrapT == GL_REPEAT && - swImg->_IsPowerOfTwo && - img->Border == 0) { - if (img->TexFormat == MESA_FORMAT_BGR_UNORM8) - func = &opt_sample_rgb_2d; - else if (img->TexFormat == MESA_FORMAT_A8B8G8R8_UNORM) - func = &opt_sample_rgba_2d; - } - - return func; - } - case GL_TEXTURE_3D: - if (needLambda) { - return sample_lambda_3d; - } - else if (sampler->Attrib.MinFilter == GL_LINEAR) { - return sample_linear_3d; - } - else { - assert(sampler->Attrib.MinFilter == GL_NEAREST); - return sample_nearest_3d; - } - case GL_TEXTURE_CUBE_MAP: - if (needLambda) { - return sample_lambda_cube; - } - else if (sampler->Attrib.MinFilter == GL_LINEAR) { - return sample_linear_cube; - } - else { - assert(sampler->Attrib.MinFilter == GL_NEAREST); - return sample_nearest_cube; - } - case GL_TEXTURE_RECTANGLE_NV: - if (is_depth_texture(t)) { - return sample_depth_texture; - } - else if (needLambda) { - return sample_lambda_rect; - } - else if (sampler->Attrib.MinFilter == GL_LINEAR) { - return sample_linear_rect; - } - else { - assert(sampler->Attrib.MinFilter == GL_NEAREST); - return sample_nearest_rect; - } - case GL_TEXTURE_1D_ARRAY_EXT: - if (is_depth_texture(t)) { - return sample_depth_texture; - } - else if (needLambda) { - return sample_lambda_1d_array; - } - else if (sampler->Attrib.MinFilter == GL_LINEAR) { - return sample_linear_1d_array; - } - else { - assert(sampler->Attrib.MinFilter == GL_NEAREST); - return sample_nearest_1d_array; - } - case GL_TEXTURE_2D_ARRAY_EXT: - if (is_depth_texture(t)) { - return sample_depth_texture; - } - else if (needLambda) { - return sample_lambda_2d_array; - } - else if (sampler->Attrib.MinFilter == GL_LINEAR) { - return sample_linear_2d_array; - } - else { - assert(sampler->Attrib.MinFilter == GL_NEAREST); - return sample_nearest_2d_array; - } - default: - _mesa_problem(ctx, - "invalid target in _swrast_choose_texture_sample_func"); - return null_sample_func; - } - } -} diff --git a/src/mesa/swrast/s_texfilter.h b/src/mesa/swrast/s_texfilter.h deleted file mode 100644 index 1aa7f09..0000000 --- a/src/mesa/swrast/s_texfilter.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -#ifndef S_TEXFILTER_H -#define S_TEXFILTER_H - - -#include "s_context.h" - -struct gl_context; -struct gl_texture_object; - - -extern texture_sample_func -_swrast_choose_texture_sample_func( struct gl_context *ctx, - const struct gl_texture_object *tObj, - const struct gl_sampler_object *sampler); - - -#endif diff --git a/src/mesa/swrast/s_texrender.c b/src/mesa/swrast/s_texrender.c deleted file mode 100644 index 4e41b3b..0000000 --- a/src/mesa/swrast/s_texrender.c +++ /dev/null @@ -1,102 +0,0 @@ - -#include "main/context.h" -#include "main/fbobject.h" -#include "main/macros.h" -#include "main/teximage.h" -#include "main/renderbuffer.h" -#include "swrast/swrast.h" -#include "swrast/s_context.h" -#include "swrast/s_texfetch.h" - - -/* - * Render-to-texture code for GL_EXT_framebuffer_object - */ - - -static void -delete_texture_wrapper(struct gl_context *ctx, struct gl_renderbuffer *rb) -{ - assert(rb->RefCount == 0); - free(rb); -} - -/** - * Update the renderbuffer wrapper for rendering to a texture. - * For example, update the width, height of the RB based on the texture size, - * update the internal format info, etc. - */ -static void -update_wrapper(struct gl_context *ctx, struct gl_renderbuffer_attachment *att) -{ - struct gl_renderbuffer *rb = att->Renderbuffer; - struct swrast_renderbuffer *srb = swrast_renderbuffer(rb); - struct swrast_texture_image *swImage; - mesa_format format; - GLuint zOffset; - - (void) ctx; - - swImage = swrast_texture_image(rb->TexImage); - assert(swImage); - - format = swImage->Base.TexFormat; - - if (att->Texture->Target == GL_TEXTURE_1D_ARRAY_EXT) { - zOffset = 0; - } - else { - zOffset = att->Zoffset; - } - - /* Want to store linear values, not sRGB */ - rb->Format = _mesa_get_srgb_format_linear(format); - - srb->Buffer = swImage->ImageSlices[zOffset]; -} - - - -/** - * Called when rendering to a texture image begins, or when changing - * the dest mipmap level, cube face, etc. - * This is a fallback routine for software render-to-texture. - * - * Called via the glRenderbufferTexture1D/2D/3D() functions - * and elsewhere (such as glTexImage2D). - * - * The image we're rendering into is - * att->Texture->Image[att->CubeMapFace][att->TextureLevel]; - * It'll never be NULL. - * - * \param fb the framebuffer object the texture is being bound to - * \param att the fb attachment point of the texture - * - * \sa _mesa_FramebufferRenderbuffer_sw - */ -void -_swrast_render_texture(struct gl_context *ctx, - struct gl_framebuffer *fb, - struct gl_renderbuffer_attachment *att) -{ - struct gl_renderbuffer *rb = att->Renderbuffer; - (void) fb; - - /* plug in our texture_renderbuffer-specific functions */ - rb->Delete = delete_texture_wrapper; - - update_wrapper(ctx, att); -} - - -void -_swrast_finish_render_texture(struct gl_context *ctx, - struct gl_renderbuffer *rb) -{ - /* do nothing */ - /* The renderbuffer texture wrapper will get deleted by the - * normal mechanism for deleting renderbuffers. - */ - (void) ctx; - (void) rb; -} diff --git a/src/mesa/swrast/s_texture.c b/src/mesa/swrast/s_texture.c deleted file mode 100644 index 1592f6e..0000000 --- a/src/mesa/swrast/s_texture.c +++ /dev/null @@ -1,388 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 2011 VMware, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -/** - * Functions for mapping/unmapping texture images. - */ - - -#include "main/context.h" -#include "main/fbobject.h" -#include "main/teximage.h" -#include "main/texobj.h" -#include "util/u_memory.h" -#include "util/u_math.h" -#include "swrast/swrast.h" -#include "swrast/s_context.h" - - -/** - * Allocate a new swrast_texture_image (a subclass of gl_texture_image). - * Called via ctx->Driver.NewTextureImage(). - */ -struct gl_texture_image * -_swrast_new_texture_image( struct gl_context *ctx ) -{ - (void) ctx; - return (struct gl_texture_image *) CALLOC_STRUCT(swrast_texture_image); -} - - -/** - * Free a swrast_texture_image (a subclass of gl_texture_image). - * Called via ctx->Driver.DeleteTextureImage(). - */ -void -_swrast_delete_texture_image(struct gl_context *ctx, - struct gl_texture_image *texImage) -{ - /* Nothing special for the subclass yet */ - _mesa_delete_texture_image(ctx, texImage); -} - -static unsigned int -texture_slices(const struct gl_texture_image *texImage) -{ - if (texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY) - return texImage->Height; - else - return texImage->Depth; -} - -unsigned int -_swrast_teximage_slice_height(struct gl_texture_image *texImage) -{ - /* For 1D array textures, the slices are all 1 pixel high, and Height is - * the number of slices. - */ - if (texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY) - return 1; - else - return texImage->Height; -} - -/** - * Called via ctx->Driver.AllocTextureImageBuffer() - */ -GLboolean -_swrast_alloc_texture_image_buffer(struct gl_context *ctx, - struct gl_texture_image *texImage) -{ - struct swrast_texture_image *swImg = swrast_texture_image(texImage); - GLuint bytesPerSlice; - GLuint slices = texture_slices(texImage); - GLuint i; - - if (!_swrast_init_texture_image(texImage)) - return GL_FALSE; - - bytesPerSlice = _mesa_format_image_size(texImage->TexFormat, texImage->Width, - _swrast_teximage_slice_height(texImage), 1); - - assert(!swImg->Buffer); - swImg->Buffer = align_malloc(bytesPerSlice * slices, 512); - if (!swImg->Buffer) - return GL_FALSE; - - /* RowStride and ImageSlices[] describe how to address texels in 'Data' */ - swImg->RowStride = _mesa_format_row_stride(texImage->TexFormat, - texImage->Width); - - for (i = 0; i < slices; i++) { - swImg->ImageSlices[i] = swImg->Buffer + bytesPerSlice * i; - } - - return GL_TRUE; -} - - -/** - * Code that overrides ctx->Driver.AllocTextureImageBuffer may use this to - * initialize the fields of swrast_texture_image without allocating the image - * buffer or initializing RowStride or the contents of ImageSlices. - * - * Returns GL_TRUE on success, GL_FALSE on memory allocation failure. - */ -GLboolean -_swrast_init_texture_image(struct gl_texture_image *texImage) -{ - struct swrast_texture_image *swImg = swrast_texture_image(texImage); - - if ((texImage->Width == 1 || util_is_power_of_two_or_zero(texImage->Width2)) && - (texImage->Height == 1 || util_is_power_of_two_or_zero(texImage->Height2)) && - (texImage->Depth == 1 || util_is_power_of_two_or_zero(texImage->Depth2))) - swImg->_IsPowerOfTwo = GL_TRUE; - else - swImg->_IsPowerOfTwo = GL_FALSE; - - /* Compute Width/Height/DepthScale for mipmap lod computation */ - if (texImage->TexObject->Target == GL_TEXTURE_RECTANGLE_NV) { - /* scale = 1.0 since texture coords directly map to texels */ - swImg->WidthScale = 1.0; - swImg->HeightScale = 1.0; - swImg->DepthScale = 1.0; - } - else { - swImg->WidthScale = (GLfloat) texImage->Width; - swImg->HeightScale = (GLfloat) texImage->Height; - swImg->DepthScale = (GLfloat) texImage->Depth; - } - - assert(!swImg->ImageSlices); - swImg->ImageSlices = calloc(texture_slices(texImage), sizeof(void *)); - if (!swImg->ImageSlices) - return GL_FALSE; - - return GL_TRUE; -} - - -/** - * Called via ctx->Driver.FreeTextureImageBuffer() - */ -void -_swrast_free_texture_image_buffer(struct gl_context *ctx, - struct gl_texture_image *texImage) -{ - struct swrast_texture_image *swImage = swrast_texture_image(texImage); - - align_free(swImage->Buffer); - swImage->Buffer = NULL; - - free(swImage->ImageSlices); - swImage->ImageSlices = NULL; -} - - -/** - * Error checking for debugging only. - */ -static void -check_map_teximage(const struct gl_texture_image *texImage, - GLuint slice, GLuint x, GLuint y, GLuint w, GLuint h) -{ - - if (texImage->TexObject->Target == GL_TEXTURE_1D) - assert(y == 0 && h == 1); - - assert(x < texImage->Width || texImage->Width == 0); - assert(y < texImage->Height || texImage->Height == 0); - assert(x + w <= texImage->Width); - assert(y + h <= texImage->Height); - assert(slice < texture_slices(texImage)); -} - -/** - * Map a 2D slice of a texture image into user space. - * (x,y,w,h) defines a region of interest (ROI). Reading/writing texels - * outside of the ROI is undefined. - * - * \param texImage the texture image - * \param slice the 3D image slice or array texture slice - * \param x, y, w, h region of interest - * \param mode bitmask of GL_MAP_READ_BIT, GL_MAP_WRITE_BIT - * \param mapOut returns start of mapping of region of interest - * \param rowStrideOut returns row stride (in bytes) - */ -void -_swrast_map_teximage(struct gl_context *ctx, - struct gl_texture_image *texImage, - GLuint slice, - GLuint x, GLuint y, GLuint w, GLuint h, - GLbitfield mode, - GLubyte **mapOut, - GLint *rowStrideOut) -{ - struct swrast_texture_image *swImage = swrast_texture_image(texImage); - GLubyte *map; - GLint stride, texelSize; - GLuint bw, bh; - - check_map_teximage(texImage, slice, x, y, w, h); - - if (!swImage->Buffer) { - /* Either glTexImage was called with a NULL argument or - * we ran out of memory when allocating texture memory, - */ - *mapOut = NULL; - *rowStrideOut = 0; - return; - } - - texelSize = _mesa_get_format_bytes(texImage->TexFormat); - stride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width); - _mesa_get_format_block_size(texImage->TexFormat, &bw, &bh); - - assert(x % bw == 0); - assert(y % bh == 0); - - /* This function can only be used with a swrast-allocated buffer, in which - * case ImageSlices is populated with pointers into Buffer. - */ - assert(swImage->Buffer); - assert(swImage->Buffer == swImage->ImageSlices[0]); - - map = swImage->ImageSlices[slice]; - - /* apply x/y offset to map address */ - map += stride * (y / bh) + texelSize * (x / bw); - - *mapOut = map; - *rowStrideOut = stride; -} - -void -_swrast_unmap_teximage(struct gl_context *ctx, - struct gl_texture_image *texImage, - GLuint slice) -{ - /* nop */ -} - - -void -_swrast_map_texture(struct gl_context *ctx, struct gl_texture_object *texObj) -{ - const GLuint faces = _mesa_num_tex_faces(texObj->Target); - GLuint face, level; - - for (face = 0; face < faces; face++) { - for (level = texObj->Attrib.BaseLevel; level < MAX_TEXTURE_LEVELS; level++) { - struct gl_texture_image *texImage = texObj->Image[face][level]; - struct swrast_texture_image *swImage = swrast_texture_image(texImage); - unsigned int i, slices; - - if (!texImage) - continue; - - /* In the case of a swrast-allocated texture buffer, the ImageSlices - * and RowStride are always available. - */ - if (swImage->Buffer) { - assert(swImage->ImageSlices[0] == swImage->Buffer); - continue; - } - - if (!swImage->ImageSlices) { - swImage->ImageSlices = - calloc(texture_slices(texImage), sizeof(void *)); - if (!swImage->ImageSlices) - continue; - } - - slices = texture_slices(texImage); - - for (i = 0; i < slices; i++) { - GLubyte *map; - GLint rowStride; - - if (swImage->ImageSlices[i]) - continue; - - ctx->Driver.MapTextureImage(ctx, texImage, i, - 0, 0, - texImage->Width, texImage->Height, - GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, - &map, &rowStride); - - swImage->ImageSlices[i] = map; - /* A swrast-using driver has to return the same rowstride for - * every slice of the same texture, since we don't track them - * separately. - */ - if (i == 0) - swImage->RowStride = rowStride; - else - assert(swImage->RowStride == rowStride); - } - } - } -} - - -void -_swrast_unmap_texture(struct gl_context *ctx, struct gl_texture_object *texObj) -{ - const GLuint faces = _mesa_num_tex_faces(texObj->Target); - GLuint face, level; - - for (face = 0; face < faces; face++) { - for (level = texObj->Attrib.BaseLevel; level < MAX_TEXTURE_LEVELS; level++) { - struct gl_texture_image *texImage = texObj->Image[face][level]; - struct swrast_texture_image *swImage = swrast_texture_image(texImage); - unsigned int i, slices; - - if (!texImage) - continue; - - if (swImage->Buffer) - return; - - if (!swImage->ImageSlices) - continue; - - slices = texture_slices(texImage); - - for (i = 0; i < slices; i++) { - if (swImage->ImageSlices[i]) { - ctx->Driver.UnmapTextureImage(ctx, texImage, i); - swImage->ImageSlices[i] = NULL; - } - } - } - } -} - - -/** - * Map all textures for reading prior to software rendering. - */ -void -_swrast_map_textures(struct gl_context *ctx) -{ - int unit; - - for (unit = 0; unit <= ctx->Texture._MaxEnabledTexImageUnit; unit++) { - struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current; - - if (texObj) - _swrast_map_texture(ctx, texObj); - } -} - - -/** - * Unmap all textures for reading prior to software rendering. - */ -void -_swrast_unmap_textures(struct gl_context *ctx) -{ - int unit; - for (unit = 0; unit <= ctx->Texture._MaxEnabledTexImageUnit; unit++) { - struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current; - - if (texObj) - _swrast_unmap_texture(ctx, texObj); - } -} diff --git a/src/mesa/swrast/s_triangle.c b/src/mesa/swrast/s_triangle.c deleted file mode 100644 index c66427c..0000000 --- a/src/mesa/swrast/s_triangle.c +++ /dev/null @@ -1,1164 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -/* - * When the device driver doesn't implement triangle rasterization it - * can hook in _swrast_Triangle, which eventually calls one of these - * functions to draw triangles. - */ - -#include "main/glheader.h" -#include "main/context.h" - -#include "main/macros.h" -#include "main/mtypes.h" -#include "main/state.h" -#include "main/samplerobj.h" -#include "main/stencil.h" -#include "main/teximage.h" -#include "program/prog_instruction.h" - -#include "s_aatriangle.h" -#include "s_context.h" -#include "s_feedback.h" -#include "s_span.h" -#include "s_triangle.h" - - -/** - * Test if a triangle should be culled. Used for feedback and selection mode. - * \return GL_TRUE if the triangle is to be culled, GL_FALSE otherwise. - */ -GLboolean -_swrast_culltriangle( struct gl_context *ctx, - const SWvertex *v0, - const SWvertex *v1, - const SWvertex *v2 ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - GLfloat ex = v1->attrib[VARYING_SLOT_POS][0] - v0->attrib[VARYING_SLOT_POS][0]; - GLfloat ey = v1->attrib[VARYING_SLOT_POS][1] - v0->attrib[VARYING_SLOT_POS][1]; - GLfloat fx = v2->attrib[VARYING_SLOT_POS][0] - v0->attrib[VARYING_SLOT_POS][0]; - GLfloat fy = v2->attrib[VARYING_SLOT_POS][1] - v0->attrib[VARYING_SLOT_POS][1]; - GLfloat c = ex*fy-ey*fx; - - if (c * swrast->_BackfaceSign * swrast->_BackfaceCullSign <= 0.0F) - return GL_FALSE; - - return GL_TRUE; -} - - - -/* - * Render a flat-shaded RGBA triangle. - */ -#define NAME flat_rgba_triangle -#define INTERP_Z 1 -#define SETUP_CODE \ - assert(ctx->Texture._EnabledCoordUnits == 0);\ - assert(ctx->Light.ShadeModel==GL_FLAT); \ - span.interpMask |= SPAN_RGBA; \ - span.red = ChanToFixed(v2->color[0]); \ - span.green = ChanToFixed(v2->color[1]); \ - span.blue = ChanToFixed(v2->color[2]); \ - span.alpha = ChanToFixed(v2->color[3]); \ - span.redStep = 0; \ - span.greenStep = 0; \ - span.blueStep = 0; \ - span.alphaStep = 0; -#define RENDER_SPAN( span ) _swrast_write_rgba_span(ctx, &span); -#include "s_tritemp.h" - - - -/* - * Render a smooth-shaded RGBA triangle. - */ -#define NAME smooth_rgba_triangle -#define INTERP_Z 1 -#define INTERP_RGB 1 -#define INTERP_ALPHA 1 -#define SETUP_CODE \ - { \ - /* texturing must be off */ \ - assert(ctx->Texture._EnabledCoordUnits == 0); \ - assert(ctx->Light.ShadeModel==GL_SMOOTH); \ - } -#define RENDER_SPAN( span ) _swrast_write_rgba_span(ctx, &span); -#include "s_tritemp.h" - - - -/* - * Render an RGB, GL_DECAL, textured triangle. - * Interpolate S,T only w/out mipmapping or perspective correction. - * - * No fog. No depth testing. - */ -#define NAME simple_textured_triangle -#define INTERP_INT_TEX 1 -#define S_SCALE twidth -#define T_SCALE theight - -#define SETUP_CODE \ - struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0]; \ - const struct gl_texture_object *obj = \ - ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX]; \ - const struct gl_texture_image *texImg = \ - _mesa_base_tex_image(obj); \ - const struct swrast_texture_image *swImg = \ - swrast_texture_image_const(texImg); \ - const GLfloat twidth = (GLfloat) texImg->Width; \ - const GLfloat theight = (GLfloat) texImg->Height; \ - const GLint twidth_log2 = texImg->WidthLog2; \ - const GLubyte *texture = (const GLubyte *) swImg->ImageSlices[0]; \ - const GLint smask = texImg->Width - 1; \ - const GLint tmask = texImg->Height - 1; \ - assert(texImg->TexFormat == MESA_FORMAT_BGR_UNORM8); \ - if (!rb || !texture) { \ - return; \ - } - -#define RENDER_SPAN( span ) \ - GLuint i; \ - GLubyte (*rgba)[4] = swrast->SpanArrays->rgba8; \ - span.intTex[0] -= FIXED_HALF; /* off-by-one error? */ \ - span.intTex[1] -= FIXED_HALF; \ - for (i = 0; i < span.end; i++) { \ - GLint s = FixedToInt(span.intTex[0]) & smask; \ - GLint t = FixedToInt(span.intTex[1]) & tmask; \ - GLint pos = (t << twidth_log2) + s; \ - pos = pos + pos + pos; /* multiply by 3 */ \ - rgba[i][RCOMP] = texture[pos+2]; \ - rgba[i][GCOMP] = texture[pos+1]; \ - rgba[i][BCOMP] = texture[pos+0]; \ - rgba[i][ACOMP] = 0xff; \ - span.intTex[0] += span.intTexStep[0]; \ - span.intTex[1] += span.intTexStep[1]; \ - } \ - _swrast_put_row(ctx, rb, GL_UNSIGNED_BYTE, span.end, \ - span.x, span.y, rgba, NULL); - -#include "s_tritemp.h" - - - -/* - * Render an RGB, GL_DECAL, textured triangle. - * Interpolate S,T, GL_LESS depth test, w/out mipmapping or - * perspective correction. - * Depth buffer bits must be <= sizeof(DEFAULT_SOFTWARE_DEPTH_TYPE) - * - * No fog. - */ -#define NAME simple_z_textured_triangle -#define INTERP_Z 1 -#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE -#define INTERP_INT_TEX 1 -#define S_SCALE twidth -#define T_SCALE theight - -#define SETUP_CODE \ - struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0]; \ - const struct gl_texture_object *obj = \ - ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX]; \ - const struct gl_texture_image *texImg = \ - _mesa_base_tex_image(obj); \ - const struct swrast_texture_image *swImg = \ - swrast_texture_image_const(texImg); \ - const GLfloat twidth = (GLfloat) texImg->Width; \ - const GLfloat theight = (GLfloat) texImg->Height; \ - const GLint twidth_log2 = texImg->WidthLog2; \ - const GLubyte *texture = (const GLubyte *) swImg->ImageSlices[0]; \ - const GLint smask = texImg->Width - 1; \ - const GLint tmask = texImg->Height - 1; \ - assert(texImg->TexFormat == MESA_FORMAT_BGR_UNORM8); \ - if (!rb || !texture) { \ - return; \ - } - -#define RENDER_SPAN( span ) \ - GLuint i; \ - GLubyte (*rgba)[4] = swrast->SpanArrays->rgba8; \ - GLubyte *mask = swrast->SpanArrays->mask; \ - span.intTex[0] -= FIXED_HALF; /* off-by-one error? */ \ - span.intTex[1] -= FIXED_HALF; \ - for (i = 0; i < span.end; i++) { \ - const GLuint z = FixedToDepth(span.z); \ - if (z < zRow[i]) { \ - GLint s = FixedToInt(span.intTex[0]) & smask; \ - GLint t = FixedToInt(span.intTex[1]) & tmask; \ - GLint pos = (t << twidth_log2) + s; \ - pos = pos + pos + pos; /* multiply by 3 */ \ - rgba[i][RCOMP] = texture[pos+2]; \ - rgba[i][GCOMP] = texture[pos+1]; \ - rgba[i][BCOMP] = texture[pos+0]; \ - rgba[i][ACOMP] = 0xff; \ - zRow[i] = z; \ - mask[i] = 1; \ - } \ - else { \ - mask[i] = 0; \ - } \ - span.intTex[0] += span.intTexStep[0]; \ - span.intTex[1] += span.intTexStep[1]; \ - span.z += span.zStep; \ - } \ - _swrast_put_row(ctx, rb, GL_UNSIGNED_BYTE, \ - span.end, span.x, span.y, rgba, mask); - -#include "s_tritemp.h" - - -#if CHAN_TYPE != GL_FLOAT - -struct affine_info -{ - GLenum filter; - GLenum format; - GLenum envmode; - GLint smask, tmask; - GLint twidth_log2; - const GLchan *texture; - GLfixed er, eg, eb, ea; - GLint tbytesline, tsize; -}; - - -static inline GLint -ilerp(GLint t, GLint a, GLint b) -{ - return a + ((t * (b - a)) >> FIXED_SHIFT); -} - -static inline GLint -ilerp_2d(GLint ia, GLint ib, GLint v00, GLint v10, GLint v01, GLint v11) -{ - const GLint temp0 = ilerp(ia, v00, v10); - const GLint temp1 = ilerp(ia, v01, v11); - return ilerp(ib, temp0, temp1); -} - - -/* This function can handle GL_NEAREST or GL_LINEAR sampling of 2D RGB or RGBA - * textures with GL_REPLACE, GL_MODULATE, GL_BLEND, GL_DECAL or GL_ADD - * texture env modes. - */ -static inline void -affine_span(struct gl_context *ctx, SWspan *span, - struct affine_info *info) -{ - GLchan sample[4]; /* the filtered texture sample */ - const GLuint texEnableSave = ctx->Texture._EnabledCoordUnits; - - /* Instead of defining a function for each mode, a test is done - * between the outer and inner loops. This is to reduce code size - * and complexity. Observe that an optimizing compiler kills - * unused variables (for instance tf,sf,ti,si in case of GL_NEAREST). - */ - -#define NEAREST_RGB \ - sample[RCOMP] = tex00[2]; \ - sample[GCOMP] = tex00[1]; \ - sample[BCOMP] = tex00[0]; \ - sample[ACOMP] = CHAN_MAX; - -#define LINEAR_RGB \ - sample[RCOMP] = ilerp_2d(sf, tf, tex00[2], tex01[2], tex10[2], tex11[2]);\ - sample[GCOMP] = ilerp_2d(sf, tf, tex00[1], tex01[1], tex10[1], tex11[1]);\ - sample[BCOMP] = ilerp_2d(sf, tf, tex00[0], tex01[0], tex10[0], tex11[0]);\ - sample[ACOMP] = CHAN_MAX; - -#define NEAREST_RGBA \ - sample[RCOMP] = tex00[3]; \ - sample[GCOMP] = tex00[2]; \ - sample[BCOMP] = tex00[1]; \ - sample[ACOMP] = tex00[0]; - -#define LINEAR_RGBA \ - sample[RCOMP] = ilerp_2d(sf, tf, tex00[3], tex01[3], tex10[3], tex11[3]);\ - sample[GCOMP] = ilerp_2d(sf, tf, tex00[2], tex01[2], tex10[2], tex11[2]);\ - sample[BCOMP] = ilerp_2d(sf, tf, tex00[1], tex01[1], tex10[1], tex11[1]);\ - sample[ACOMP] = ilerp_2d(sf, tf, tex00[0], tex01[0], tex10[0], tex11[0]) - -#define MODULATE \ - dest[RCOMP] = span->red * (sample[RCOMP] + 1u) >> (FIXED_SHIFT + 8); \ - dest[GCOMP] = span->green * (sample[GCOMP] + 1u) >> (FIXED_SHIFT + 8); \ - dest[BCOMP] = span->blue * (sample[BCOMP] + 1u) >> (FIXED_SHIFT + 8); \ - dest[ACOMP] = span->alpha * (sample[ACOMP] + 1u) >> (FIXED_SHIFT + 8) - -#define DECAL \ - dest[RCOMP] = ((CHAN_MAX - sample[ACOMP]) * span->red + \ - ((sample[ACOMP] + 1) * sample[RCOMP] << FIXED_SHIFT)) \ - >> (FIXED_SHIFT + 8); \ - dest[GCOMP] = ((CHAN_MAX - sample[ACOMP]) * span->green + \ - ((sample[ACOMP] + 1) * sample[GCOMP] << FIXED_SHIFT)) \ - >> (FIXED_SHIFT + 8); \ - dest[BCOMP] = ((CHAN_MAX - sample[ACOMP]) * span->blue + \ - ((sample[ACOMP] + 1) * sample[BCOMP] << FIXED_SHIFT)) \ - >> (FIXED_SHIFT + 8); \ - dest[ACOMP] = FixedToInt(span->alpha) - -#define BLEND \ - dest[RCOMP] = ((CHAN_MAX - sample[RCOMP]) * span->red \ - + (sample[RCOMP] + 1) * info->er) >> (FIXED_SHIFT + 8); \ - dest[GCOMP] = ((CHAN_MAX - sample[GCOMP]) * span->green \ - + (sample[GCOMP] + 1) * info->eg) >> (FIXED_SHIFT + 8); \ - dest[BCOMP] = ((CHAN_MAX - sample[BCOMP]) * span->blue \ - + (sample[BCOMP] + 1) * info->eb) >> (FIXED_SHIFT + 8); \ - dest[ACOMP] = span->alpha * (sample[ACOMP] + 1) >> (FIXED_SHIFT + 8) - -#define REPLACE COPY_CHAN4(dest, sample) - -#define ADD \ - { \ - GLint rSum = FixedToInt(span->red) + (GLint) sample[RCOMP]; \ - GLint gSum = FixedToInt(span->green) + (GLint) sample[GCOMP]; \ - GLint bSum = FixedToInt(span->blue) + (GLint) sample[BCOMP]; \ - dest[RCOMP] = MIN2(rSum, CHAN_MAX); \ - dest[GCOMP] = MIN2(gSum, CHAN_MAX); \ - dest[BCOMP] = MIN2(bSum, CHAN_MAX); \ - dest[ACOMP] = span->alpha * (sample[ACOMP] + 1) >> (FIXED_SHIFT + 8); \ - } - -/* shortcuts */ - -#define NEAREST_RGB_REPLACE \ - NEAREST_RGB; \ - dest[0] = sample[0]; \ - dest[1] = sample[1]; \ - dest[2] = sample[2]; \ - dest[3] = FixedToInt(span->alpha); - -#define NEAREST_RGBA_REPLACE \ - dest[RCOMP] = tex00[3]; \ - dest[GCOMP] = tex00[2]; \ - dest[BCOMP] = tex00[1]; \ - dest[ACOMP] = tex00[0] - -#define SPAN_NEAREST(DO_TEX, COMPS) \ - for (i = 0; i < span->end; i++) { \ - /* Isn't it necessary to use FixedFloor below?? */ \ - GLint s = FixedToInt(span->intTex[0]) & info->smask; \ - GLint t = FixedToInt(span->intTex[1]) & info->tmask; \ - GLint pos = (t << info->twidth_log2) + s; \ - const GLchan *tex00 = info->texture + COMPS * pos; \ - DO_TEX; \ - span->red += span->redStep; \ - span->green += span->greenStep; \ - span->blue += span->blueStep; \ - span->alpha += span->alphaStep; \ - span->intTex[0] += span->intTexStep[0]; \ - span->intTex[1] += span->intTexStep[1]; \ - dest += 4; \ - } - -#define SPAN_LINEAR(DO_TEX, COMPS) \ - for (i = 0; i < span->end; i++) { \ - /* Isn't it necessary to use FixedFloor below?? */ \ - const GLint s = FixedToInt(span->intTex[0]) & info->smask; \ - const GLint t = FixedToInt(span->intTex[1]) & info->tmask; \ - const GLfixed sf = span->intTex[0] & FIXED_FRAC_MASK; \ - const GLfixed tf = span->intTex[1] & FIXED_FRAC_MASK; \ - const GLint pos = (t << info->twidth_log2) + s; \ - const GLchan *tex00 = info->texture + COMPS * pos; \ - const GLchan *tex10 = tex00 + info->tbytesline; \ - const GLchan *tex01 = tex00 + COMPS; \ - const GLchan *tex11 = tex10 + COMPS; \ - if (t == info->tmask) { \ - tex10 -= info->tsize; \ - tex11 -= info->tsize; \ - } \ - if (s == info->smask) { \ - tex01 -= info->tbytesline; \ - tex11 -= info->tbytesline; \ - } \ - DO_TEX; \ - span->red += span->redStep; \ - span->green += span->greenStep; \ - span->blue += span->blueStep; \ - span->alpha += span->alphaStep; \ - span->intTex[0] += span->intTexStep[0]; \ - span->intTex[1] += span->intTexStep[1]; \ - dest += 4; \ - } - - - GLuint i; - GLchan *dest = span->array->rgba[0]; - - /* Disable tex units so they're not re-applied in swrast_write_rgba_span */ - ctx->Texture._EnabledCoordUnits = 0x0; - - span->intTex[0] -= FIXED_HALF; - span->intTex[1] -= FIXED_HALF; - switch (info->filter) { - case GL_NEAREST: - switch (info->format) { - case MESA_FORMAT_BGR_UNORM8: - switch (info->envmode) { - case GL_MODULATE: - SPAN_NEAREST(NEAREST_RGB;MODULATE,3); - break; - case GL_DECAL: - case GL_REPLACE: - SPAN_NEAREST(NEAREST_RGB_REPLACE,3); - break; - case GL_BLEND: - SPAN_NEAREST(NEAREST_RGB;BLEND,3); - break; - case GL_ADD: - SPAN_NEAREST(NEAREST_RGB;ADD,3); - break; - default: - _mesa_problem(ctx, "bad tex env mode in SPAN_LINEAR"); - return; - } - break; - case MESA_FORMAT_A8B8G8R8_UNORM: - switch(info->envmode) { - case GL_MODULATE: - SPAN_NEAREST(NEAREST_RGBA;MODULATE,4); - break; - case GL_DECAL: - SPAN_NEAREST(NEAREST_RGBA;DECAL,4); - break; - case GL_BLEND: - SPAN_NEAREST(NEAREST_RGBA;BLEND,4); - break; - case GL_ADD: - SPAN_NEAREST(NEAREST_RGBA;ADD,4); - break; - case GL_REPLACE: - SPAN_NEAREST(NEAREST_RGBA_REPLACE,4); - break; - default: - _mesa_problem(ctx, "bad tex env mode (2) in SPAN_LINEAR"); - return; - } - break; - } - break; - - case GL_LINEAR: - span->intTex[0] -= FIXED_HALF; - span->intTex[1] -= FIXED_HALF; - switch (info->format) { - case MESA_FORMAT_BGR_UNORM8: - switch (info->envmode) { - case GL_MODULATE: - SPAN_LINEAR(LINEAR_RGB;MODULATE,3); - break; - case GL_DECAL: - case GL_REPLACE: - SPAN_LINEAR(LINEAR_RGB;REPLACE,3); - break; - case GL_BLEND: - SPAN_LINEAR(LINEAR_RGB;BLEND,3); - break; - case GL_ADD: - SPAN_LINEAR(LINEAR_RGB;ADD,3); - break; - default: - _mesa_problem(ctx, "bad tex env mode (3) in SPAN_LINEAR"); - return; - } - break; - case MESA_FORMAT_A8B8G8R8_UNORM: - switch (info->envmode) { - case GL_MODULATE: - SPAN_LINEAR(LINEAR_RGBA;MODULATE,4); - break; - case GL_DECAL: - SPAN_LINEAR(LINEAR_RGBA;DECAL,4); - break; - case GL_BLEND: - SPAN_LINEAR(LINEAR_RGBA;BLEND,4); - break; - case GL_ADD: - SPAN_LINEAR(LINEAR_RGBA;ADD,4); - break; - case GL_REPLACE: - SPAN_LINEAR(LINEAR_RGBA;REPLACE,4); - break; - default: - _mesa_problem(ctx, "bad tex env mode (4) in SPAN_LINEAR"); - return; - } - break; - } - break; - } - span->interpMask &= ~SPAN_RGBA; - assert(span->arrayMask & SPAN_RGBA); - - _swrast_write_rgba_span(ctx, span); - - /* re-enable texture units */ - ctx->Texture._EnabledCoordUnits = texEnableSave; - -#undef SPAN_NEAREST -#undef SPAN_LINEAR -} - - - -/* - * Render an RGB/RGBA textured triangle without perspective correction. - */ -#define NAME affine_textured_triangle -#define INTERP_Z 1 -#define INTERP_RGB 1 -#define INTERP_ALPHA 1 -#define INTERP_INT_TEX 1 -#define S_SCALE twidth -#define T_SCALE theight - -#define SETUP_CODE \ - struct affine_info info; \ - struct gl_fixedfunc_texture_unit *unit = ctx->Texture.FixedFuncUnit+0; \ - const struct gl_texture_object *obj = \ - ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX]; \ - const struct gl_texture_image *texImg = \ - _mesa_base_tex_image(obj); \ - const struct swrast_texture_image *swImg = \ - swrast_texture_image_const(texImg); \ - const GLfloat twidth = (GLfloat) texImg->Width; \ - const GLfloat theight = (GLfloat) texImg->Height; \ - info.texture = (const GLchan *) swImg->ImageSlices[0]; \ - info.twidth_log2 = texImg->WidthLog2; \ - info.smask = texImg->Width - 1; \ - info.tmask = texImg->Height - 1; \ - info.format = texImg->TexFormat; \ - info.filter = obj->Sampler.Attrib.MinFilter; \ - info.envmode = unit->EnvMode; \ - info.er = 0; \ - info.eg = 0; \ - info.eb = 0; \ - span.arrayMask |= SPAN_RGBA; \ - \ - if (info.envmode == GL_BLEND) { \ - /* potential off-by-one error here? (1.0f -> 2048 -> 0) */ \ - info.er = FloatToFixed(unit->EnvColor[RCOMP] * CHAN_MAXF); \ - info.eg = FloatToFixed(unit->EnvColor[GCOMP] * CHAN_MAXF); \ - info.eb = FloatToFixed(unit->EnvColor[BCOMP] * CHAN_MAXF); \ - info.ea = FloatToFixed(unit->EnvColor[ACOMP] * CHAN_MAXF); \ - } \ - if (!info.texture) { \ - /* this shouldn't happen */ \ - return; \ - } \ - \ - switch (info.format) { \ - case MESA_FORMAT_BGR_UNORM8: \ - info.tbytesline = texImg->Width * 3; \ - break; \ - case MESA_FORMAT_A8B8G8R8_UNORM: \ - info.tbytesline = texImg->Width * 4; \ - break; \ - default: \ - _mesa_problem(NULL, "Bad texture format in affine_texture_triangle");\ - return; \ - } \ - info.tsize = texImg->Height * info.tbytesline; - -#define RENDER_SPAN( span ) affine_span(ctx, &span, &info); - -#include "s_tritemp.h" - - - -struct persp_info -{ - GLenum filter; - GLenum format; - GLenum envmode; - GLint smask, tmask; - GLint twidth_log2; - const GLchan *texture; - GLfixed er, eg, eb, ea; /* texture env color */ - GLint tbytesline, tsize; -}; - - -static inline void -fast_persp_span(struct gl_context *ctx, SWspan *span, - struct persp_info *info) -{ - GLchan sample[4]; /* the filtered texture sample */ - - /* Instead of defining a function for each mode, a test is done - * between the outer and inner loops. This is to reduce code size - * and complexity. Observe that an optimizing compiler kills - * unused variables (for instance tf,sf,ti,si in case of GL_NEAREST). - */ -#define SPAN_NEAREST(DO_TEX,COMP) \ - for (i = 0; i < span->end; i++) { \ - GLdouble invQ = tex_coord[2] ? \ - (1.0 / tex_coord[2]) : 1.0; \ - GLfloat s_tmp = (GLfloat) (tex_coord[0] * invQ); \ - GLfloat t_tmp = (GLfloat) (tex_coord[1] * invQ); \ - GLint s = util_ifloor(s_tmp) & info->smask; \ - GLint t = util_ifloor(t_tmp) & info->tmask; \ - GLint pos = (t << info->twidth_log2) + s; \ - const GLchan *tex00 = info->texture + COMP * pos; \ - DO_TEX; \ - span->red += span->redStep; \ - span->green += span->greenStep; \ - span->blue += span->blueStep; \ - span->alpha += span->alphaStep; \ - tex_coord[0] += tex_step[0]; \ - tex_coord[1] += tex_step[1]; \ - tex_coord[2] += tex_step[2]; \ - dest += 4; \ - } - -#define SPAN_LINEAR(DO_TEX,COMP) \ - for (i = 0; i < span->end; i++) { \ - GLdouble invQ = tex_coord[2] ? \ - (1.0 / tex_coord[2]) : 1.0; \ - const GLfloat s_tmp = (GLfloat) (tex_coord[0] * invQ); \ - const GLfloat t_tmp = (GLfloat) (tex_coord[1] * invQ); \ - const GLfixed s_fix = FloatToFixed(s_tmp) - FIXED_HALF; \ - const GLfixed t_fix = FloatToFixed(t_tmp) - FIXED_HALF; \ - const GLint s = FixedToInt(FixedFloor(s_fix)) & info->smask; \ - const GLint t = FixedToInt(FixedFloor(t_fix)) & info->tmask; \ - const GLfixed sf = s_fix & FIXED_FRAC_MASK; \ - const GLfixed tf = t_fix & FIXED_FRAC_MASK; \ - const GLint pos = (t << info->twidth_log2) + s; \ - const GLchan *tex00 = info->texture + COMP * pos; \ - const GLchan *tex10 = tex00 + info->tbytesline; \ - const GLchan *tex01 = tex00 + COMP; \ - const GLchan *tex11 = tex10 + COMP; \ - if (t == info->tmask) { \ - tex10 -= info->tsize; \ - tex11 -= info->tsize; \ - } \ - if (s == info->smask) { \ - tex01 -= info->tbytesline; \ - tex11 -= info->tbytesline; \ - } \ - DO_TEX; \ - span->red += span->redStep; \ - span->green += span->greenStep; \ - span->blue += span->blueStep; \ - span->alpha += span->alphaStep; \ - tex_coord[0] += tex_step[0]; \ - tex_coord[1] += tex_step[1]; \ - tex_coord[2] += tex_step[2]; \ - dest += 4; \ - } - - GLuint i; - GLfloat tex_coord[3], tex_step[3]; - GLchan *dest = span->array->rgba[0]; - - const GLuint texEnableSave = ctx->Texture._EnabledCoordUnits; - ctx->Texture._EnabledCoordUnits = 0; - - tex_coord[0] = span->attrStart[VARYING_SLOT_TEX0][0] * (info->smask + 1); - tex_step[0] = span->attrStepX[VARYING_SLOT_TEX0][0] * (info->smask + 1); - tex_coord[1] = span->attrStart[VARYING_SLOT_TEX0][1] * (info->tmask + 1); - tex_step[1] = span->attrStepX[VARYING_SLOT_TEX0][1] * (info->tmask + 1); - /* span->attrStart[VARYING_SLOT_TEX0][2] only if 3D-texturing, here only 2D */ - tex_coord[2] = span->attrStart[VARYING_SLOT_TEX0][3]; - tex_step[2] = span->attrStepX[VARYING_SLOT_TEX0][3]; - - switch (info->filter) { - case GL_NEAREST: - switch (info->format) { - case MESA_FORMAT_BGR_UNORM8: - switch (info->envmode) { - case GL_MODULATE: - SPAN_NEAREST(NEAREST_RGB;MODULATE,3); - break; - case GL_DECAL: - case GL_REPLACE: - SPAN_NEAREST(NEAREST_RGB_REPLACE,3); - break; - case GL_BLEND: - SPAN_NEAREST(NEAREST_RGB;BLEND,3); - break; - case GL_ADD: - SPAN_NEAREST(NEAREST_RGB;ADD,3); - break; - default: - _mesa_problem(ctx, "bad tex env mode (5) in SPAN_LINEAR"); - return; - } - break; - case MESA_FORMAT_A8B8G8R8_UNORM: - switch(info->envmode) { - case GL_MODULATE: - SPAN_NEAREST(NEAREST_RGBA;MODULATE,4); - break; - case GL_DECAL: - SPAN_NEAREST(NEAREST_RGBA;DECAL,4); - break; - case GL_BLEND: - SPAN_NEAREST(NEAREST_RGBA;BLEND,4); - break; - case GL_ADD: - SPAN_NEAREST(NEAREST_RGBA;ADD,4); - break; - case GL_REPLACE: - SPAN_NEAREST(NEAREST_RGBA_REPLACE,4); - break; - default: - _mesa_problem(ctx, "bad tex env mode (6) in SPAN_LINEAR"); - return; - } - break; - } - break; - - case GL_LINEAR: - switch (info->format) { - case MESA_FORMAT_BGR_UNORM8: - switch (info->envmode) { - case GL_MODULATE: - SPAN_LINEAR(LINEAR_RGB;MODULATE,3); - break; - case GL_DECAL: - case GL_REPLACE: - SPAN_LINEAR(LINEAR_RGB;REPLACE,3); - break; - case GL_BLEND: - SPAN_LINEAR(LINEAR_RGB;BLEND,3); - break; - case GL_ADD: - SPAN_LINEAR(LINEAR_RGB;ADD,3); - break; - default: - _mesa_problem(ctx, "bad tex env mode (7) in SPAN_LINEAR"); - return; - } - break; - case MESA_FORMAT_A8B8G8R8_UNORM: - switch (info->envmode) { - case GL_MODULATE: - SPAN_LINEAR(LINEAR_RGBA;MODULATE,4); - break; - case GL_DECAL: - SPAN_LINEAR(LINEAR_RGBA;DECAL,4); - break; - case GL_BLEND: - SPAN_LINEAR(LINEAR_RGBA;BLEND,4); - break; - case GL_ADD: - SPAN_LINEAR(LINEAR_RGBA;ADD,4); - break; - case GL_REPLACE: - SPAN_LINEAR(LINEAR_RGBA;REPLACE,4); - break; - default: - _mesa_problem(ctx, "bad tex env mode (8) in SPAN_LINEAR"); - return; - } - break; - } - break; - } - - assert(span->arrayMask & SPAN_RGBA); - _swrast_write_rgba_span(ctx, span); - -#undef SPAN_NEAREST -#undef SPAN_LINEAR - - /* restore state */ - ctx->Texture._EnabledCoordUnits = texEnableSave; -} - - -/* - * Render an perspective corrected RGB/RGBA textured triangle. - * The Q (aka V in Mesa) coordinate must be zero such that the divide - * by interpolated Q/W comes out right. - * - */ -#define NAME persp_textured_triangle -#define INTERP_Z 1 -#define INTERP_RGB 1 -#define INTERP_ALPHA 1 -#define INTERP_ATTRIBS 1 - -#define SETUP_CODE \ - struct persp_info info; \ - const struct gl_fixedfunc_texture_unit *unit = ctx->Texture.FixedFuncUnit+0; \ - const struct gl_texture_object *obj = \ - ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX]; \ - const struct gl_texture_image *texImg = \ - _mesa_base_tex_image(obj); \ - const struct swrast_texture_image *swImg = \ - swrast_texture_image_const(texImg); \ - info.texture = (const GLchan *) swImg->ImageSlices[0]; \ - info.twidth_log2 = texImg->WidthLog2; \ - info.smask = texImg->Width - 1; \ - info.tmask = texImg->Height - 1; \ - info.format = texImg->TexFormat; \ - info.filter = obj->Sampler.Attrib.MinFilter; \ - info.envmode = unit->EnvMode; \ - info.er = 0; \ - info.eg = 0; \ - info.eb = 0; \ - \ - if (info.envmode == GL_BLEND) { \ - /* potential off-by-one error here? (1.0f -> 2048 -> 0) */ \ - info.er = FloatToFixed(unit->EnvColor[RCOMP] * CHAN_MAXF); \ - info.eg = FloatToFixed(unit->EnvColor[GCOMP] * CHAN_MAXF); \ - info.eb = FloatToFixed(unit->EnvColor[BCOMP] * CHAN_MAXF); \ - info.ea = FloatToFixed(unit->EnvColor[ACOMP] * CHAN_MAXF); \ - } \ - if (!info.texture) { \ - /* this shouldn't happen */ \ - return; \ - } \ - \ - switch (info.format) { \ - case MESA_FORMAT_BGR_UNORM8: \ - info.tbytesline = texImg->Width * 3; \ - break; \ - case MESA_FORMAT_A8B8G8R8_UNORM: \ - info.tbytesline = texImg->Width * 4; \ - break; \ - default: \ - _mesa_problem(NULL, "Bad texture format in persp_textured_triangle");\ - return; \ - } \ - info.tsize = texImg->Height * info.tbytesline; - -#define RENDER_SPAN( span ) \ - span.interpMask &= ~SPAN_RGBA; \ - span.arrayMask |= SPAN_RGBA; \ - fast_persp_span(ctx, &span, &info); - -#include "s_tritemp.h" - -#endif /*CHAN_TYPE != GL_FLOAT*/ - - - -/* - * Render an RGBA triangle with arbitrary attributes. - */ -#define NAME general_triangle -#define INTERP_Z 1 -#define INTERP_RGB 1 -#define INTERP_ALPHA 1 -#define INTERP_ATTRIBS 1 -#define RENDER_SPAN( span ) _swrast_write_rgba_span(ctx, &span); -#include "s_tritemp.h" - - - - -/* - * Special tri function for occlusion testing - */ -#define NAME occlusion_zless_16_triangle -#define INTERP_Z 1 -#define SETUP_CODE \ - struct gl_renderbuffer *rb = \ - ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; \ - struct gl_query_object *q = ctx->Query.CurrentOcclusionObject; \ - assert(ctx->Depth.Test); \ - assert(!ctx->Depth.Mask); \ - assert(ctx->Depth.Func == GL_LESS); \ - assert(rb->Format == MESA_FORMAT_Z_UNORM16); \ - if (!q) { \ - return; \ - } -#define RENDER_SPAN( span ) \ - { \ - GLuint i; \ - const GLushort *zRow = (const GLushort *) \ - _swrast_pixel_address(rb, span.x, span.y); \ - for (i = 0; i < span.end; i++) { \ - GLuint z = FixedToDepth(span.z); \ - if (z < zRow[i]) { \ - q->Result++; \ - } \ - span.z += span.zStep; \ - } \ - } -#include "s_tritemp.h" - - - -static void -nodraw_triangle( struct gl_context *ctx, - const SWvertex *v0, - const SWvertex *v1, - const SWvertex *v2 ) -{ - (void) (ctx && v0 && v1 && v2); -} - - -/* - * This is used when separate specular color is enabled, but not - * texturing. We add the specular color to the primary color, - * draw the triangle, then restore the original primary color. - * Inefficient, but seldom needed. - */ -void -_swrast_add_spec_terms_triangle(struct gl_context *ctx, const SWvertex *v0, - const SWvertex *v1, const SWvertex *v2) -{ - SWvertex *ncv0 = (SWvertex *)v0; /* drop const qualifier */ - SWvertex *ncv1 = (SWvertex *)v1; - SWvertex *ncv2 = (SWvertex *)v2; - GLfloat rSum, gSum, bSum; - GLchan cSave[3][4]; - - /* save original colors */ - COPY_CHAN4( cSave[0], ncv0->color ); - COPY_CHAN4( cSave[1], ncv1->color ); - COPY_CHAN4( cSave[2], ncv2->color ); - /* sum v0 */ - rSum = CHAN_TO_FLOAT(ncv0->color[0]) + ncv0->attrib[VARYING_SLOT_COL1][0]; - gSum = CHAN_TO_FLOAT(ncv0->color[1]) + ncv0->attrib[VARYING_SLOT_COL1][1]; - bSum = CHAN_TO_FLOAT(ncv0->color[2]) + ncv0->attrib[VARYING_SLOT_COL1][2]; - UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[0], rSum); - UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[1], gSum); - UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[2], bSum); - /* sum v1 */ - rSum = CHAN_TO_FLOAT(ncv1->color[0]) + ncv1->attrib[VARYING_SLOT_COL1][0]; - gSum = CHAN_TO_FLOAT(ncv1->color[1]) + ncv1->attrib[VARYING_SLOT_COL1][1]; - bSum = CHAN_TO_FLOAT(ncv1->color[2]) + ncv1->attrib[VARYING_SLOT_COL1][2]; - UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[0], rSum); - UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[1], gSum); - UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[2], bSum); - /* sum v2 */ - rSum = CHAN_TO_FLOAT(ncv2->color[0]) + ncv2->attrib[VARYING_SLOT_COL1][0]; - gSum = CHAN_TO_FLOAT(ncv2->color[1]) + ncv2->attrib[VARYING_SLOT_COL1][1]; - bSum = CHAN_TO_FLOAT(ncv2->color[2]) + ncv2->attrib[VARYING_SLOT_COL1][2]; - UNCLAMPED_FLOAT_TO_CHAN(ncv2->color[0], rSum); - UNCLAMPED_FLOAT_TO_CHAN(ncv2->color[1], gSum); - UNCLAMPED_FLOAT_TO_CHAN(ncv2->color[2], bSum); - /* draw */ - SWRAST_CONTEXT(ctx)->SpecTriangle( ctx, ncv0, ncv1, ncv2 ); - /* restore original colors */ - COPY_CHAN4( ncv0->color, cSave[0] ); - COPY_CHAN4( ncv1->color, cSave[1] ); - COPY_CHAN4( ncv2->color, cSave[2] ); -} - - - -#ifdef DEBUG - -/* record the current triangle function name */ -const char *_mesa_triFuncName = NULL; - -#define USE(triFunc) \ -do { \ - _mesa_triFuncName = #triFunc; \ - /*printf("%s\n", _mesa_triFuncName);*/ \ - swrast->Triangle = triFunc; \ -} while (0) - -#else - -#define USE(triFunc) swrast->Triangle = triFunc; - -#endif - - - - -/* - * Determine which triangle rendering function to use given the current - * rendering context. - * - * Please update the summary flag _SWRAST_NEW_TRIANGLE if you add or - * remove tests to this code. - */ -void -_swrast_choose_triangle( struct gl_context *ctx ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - - if (ctx->Polygon.CullFlag && - ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) { - USE(nodraw_triangle); - return; - } - - if (ctx->RenderMode==GL_RENDER) { - struct gl_renderbuffer *depthRb = - ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; - - if (ctx->Polygon.SmoothFlag) { - _swrast_set_aa_triangle_function(ctx); - assert(swrast->Triangle); - return; - } - - /* special case for occlusion testing */ - if (ctx->Query.CurrentOcclusionObject && - ctx->Depth.Test && - ctx->Depth.Mask == GL_FALSE && - ctx->Depth.Func == GL_LESS && - !_mesa_stencil_is_enabled(ctx) && - depthRb && - depthRb->Format == MESA_FORMAT_Z_UNORM16) { - if (GET_COLORMASK_BIT(ctx->Color.ColorMask, 0, 0) == 0 && - GET_COLORMASK_BIT(ctx->Color.ColorMask, 0, 1) == 0 && - GET_COLORMASK_BIT(ctx->Color.ColorMask, 0, 2) == 0 && - GET_COLORMASK_BIT(ctx->Color.ColorMask, 0, 3) == 0) { - USE(occlusion_zless_16_triangle); - return; - } - } - - /* - * XXX should examine swrast->_ActiveAttribMask to determine what - * needs to be interpolated. - */ - if (ctx->Texture._EnabledCoordUnits || - _swrast_use_fragment_program(ctx) || - _mesa_ati_fragment_shader_enabled(ctx) || - _mesa_need_secondary_color(ctx) || - swrast->_FogEnabled) { - /* Ugh, we do a _lot_ of tests to pick the best textured tri func */ - const struct gl_texture_object *texObj2D; - const struct gl_sampler_object *samp; - const struct gl_texture_image *texImg; - const struct swrast_texture_image *swImg; - GLenum minFilter, magFilter, envMode; - mesa_format format; - texObj2D = ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX]; - if (ctx->Texture.Unit[0].Sampler) - samp = ctx->Texture.Unit[0].Sampler; - else if (texObj2D) - samp = &texObj2D->Sampler; - else - samp = NULL; - - texImg = texObj2D ? _mesa_base_tex_image(texObj2D) : NULL; - swImg = swrast_texture_image_const(texImg); - - format = texImg ? texImg->TexFormat : MESA_FORMAT_NONE; - minFilter = texObj2D ? samp->Attrib.MinFilter : GL_NONE; - magFilter = texObj2D ? samp->Attrib.MagFilter : GL_NONE; - envMode = ctx->Texture.FixedFuncUnit[0].EnvMode; - - /* First see if we can use an optimized 2-D texture function */ - if (ctx->Texture._EnabledCoordUnits == 0x1 - && !_swrast_use_fragment_program(ctx) - && !_mesa_ati_fragment_shader_enabled(ctx) - && ctx->Texture._MaxEnabledTexImageUnit == 0 - && ctx->Texture.Unit[0]._Current->Target == GL_TEXTURE_2D - && samp->Attrib.WrapS == GL_REPEAT - && samp->Attrib.WrapT == GL_REPEAT - && texObj2D->Attrib._Swizzle == SWIZZLE_NOOP - && swImg->_IsPowerOfTwo - && texImg->Border == 0 - && (_mesa_format_row_stride(format, texImg->Width) == - swImg->RowStride) - && (format == MESA_FORMAT_BGR_UNORM8 || format == MESA_FORMAT_A8B8G8R8_UNORM) - && minFilter == magFilter - && ctx->Light.Model.ColorControl == GL_SINGLE_COLOR - && !swrast->_FogEnabled - && ctx->Texture.FixedFuncUnit[0].EnvMode != GL_COMBINE_EXT - && ctx->Texture.FixedFuncUnit[0].EnvMode != GL_COMBINE4_NV) { - if (ctx->Hint.PerspectiveCorrection==GL_FASTEST) { - if (minFilter == GL_NEAREST - && format == MESA_FORMAT_BGR_UNORM8 - && (envMode == GL_REPLACE || envMode == GL_DECAL) - && ((swrast->_RasterMask == (DEPTH_BIT | TEXTURE_BIT) - && ctx->Depth.Func == GL_LESS - && ctx->Depth.Mask == GL_TRUE) - || swrast->_RasterMask == TEXTURE_BIT) - && ctx->Polygon.StippleFlag == GL_FALSE - && ctx->DrawBuffer->Visual.depthBits <= 16) { - if (swrast->_RasterMask == (DEPTH_BIT | TEXTURE_BIT)) { - USE(simple_z_textured_triangle); - } - else { - USE(simple_textured_triangle); - } - } - else { -#if CHAN_BITS != 8 - USE(general_triangle); -#else - if (format == MESA_FORMAT_A8B8G8R8_UNORM && !UTIL_ARCH_LITTLE_ENDIAN) { - /* We only handle RGBA8888 correctly on little endian - * in the optimized code above. - */ - USE(general_triangle); - } - else { - USE(affine_textured_triangle); - } -#endif - } - } - else { -#if CHAN_BITS != 8 - USE(general_triangle); -#else - USE(persp_textured_triangle); -#endif - } - } - else { - /* general case textured triangles */ - USE(general_triangle); - } - } - else { - assert(!swrast->_FogEnabled); - assert(!_mesa_need_secondary_color(ctx)); - if (ctx->Light.ShadeModel==GL_SMOOTH) { - /* smooth shaded, no texturing, stippled or some raster ops */ -#if CHAN_BITS != 8 - USE(general_triangle); -#else - USE(smooth_rgba_triangle); -#endif - } - else { - /* flat shaded, no texturing, stippled or some raster ops */ -#if CHAN_BITS != 8 - USE(general_triangle); -#else - USE(flat_rgba_triangle); -#endif - } - } - } - else if (ctx->RenderMode==GL_FEEDBACK) { - USE(_swrast_feedback_triangle); - } - else { - /* GL_SELECT mode */ - USE(_swrast_select_triangle); - } -} diff --git a/src/mesa/swrast/s_triangle.h b/src/mesa/swrast/s_triangle.h deleted file mode 100644 index c34b6d2..0000000 --- a/src/mesa/swrast/s_triangle.h +++ /dev/null @@ -1,50 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2003 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -#ifndef S_TRIANGLES_H -#define S_TRIANGLES_H - - -#include "swrast.h" - - -extern GLboolean -_swrast_culltriangle( struct gl_context *ctx, - const SWvertex *v0, - const SWvertex *v1, - const SWvertex *v2); - -extern void -_swrast_choose_triangle( struct gl_context *ctx ); - -extern void -_swrast_add_spec_terms_triangle( struct gl_context *ctx, - const SWvertex *v0, - const SWvertex *v1, - const SWvertex *v2 ); - - -#endif diff --git a/src/mesa/swrast/s_tritemp.h b/src/mesa/swrast/s_tritemp.h deleted file mode 100644 index 4dc42a8..0000000 --- a/src/mesa/swrast/s_tritemp.h +++ /dev/null @@ -1,935 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -/* - * Triangle Rasterizer Template - * - * This file is #include'd to generate custom triangle rasterizers. - * - * The following macros may be defined to indicate what auxillary information - * must be interpolated across the triangle: - * INTERP_Z - if defined, interpolate integer Z values - * INTERP_RGB - if defined, interpolate integer RGB values - * INTERP_ALPHA - if defined, interpolate integer Alpha values - * INTERP_INT_TEX - if defined, interpolate integer ST texcoords - * (fast, simple 2-D texture mapping, without - * perspective correction) - * INTERP_ATTRIBS - if defined, interpolate arbitrary attribs (texcoords, - * varying vars, etc) This also causes W to be - * computed for perspective correction). - * - * When one can directly address pixels in the color buffer the following - * macros can be defined and used to compute pixel addresses during - * rasterization (see pRow): - * PIXEL_TYPE - the datatype of a pixel (GLubyte, GLushort, GLuint) - * BYTES_PER_ROW - number of bytes per row in the color buffer - * PIXEL_ADDRESS(X,Y) - returns the address of pixel at (X,Y) where - * Y==0 at bottom of screen and increases upward. - * - * Similarly, for direct depth buffer access, this type is used for depth - * buffer addressing (see zRow): - * DEPTH_TYPE - either GLushort or GLuint - * - * Optionally, one may provide one-time setup code per triangle: - * SETUP_CODE - code which is to be executed once per triangle - * - * The following macro MUST be defined: - * RENDER_SPAN(span) - code to write a span of pixels. - * - * This code was designed for the origin to be in the lower-left corner. - * - * Inspired by triangle rasterizer code written by Allen Akin. Thanks Allen! - * - * - * Some notes on rasterization accuracy: - * - * This code uses fixed point arithmetic (the GLfixed type) to iterate - * over the triangle edges and interpolate ancillary data (such as Z, - * color, secondary color, etc). The number of fractional bits in - * GLfixed and the value of SUB_PIXEL_BITS has a direct bearing on the - * accuracy of rasterization. - * - * If SUB_PIXEL_BITS=4 then we'll snap the vertices to the nearest - * 1/16 of a pixel. If we're walking up a long, nearly vertical edge - * (dx=1/16, dy=1024) we'll need 4 + 10 = 14 fractional bits in - * GLfixed to walk the edge without error. If the maximum viewport - * height is 4K pixels, then we'll need 4 + 12 = 16 fractional bits. - * - * Historically, Mesa has used 11 fractional bits in GLfixed, snaps - * vertices to 1/16 pixel and allowed a maximum viewport height of 2K - * pixels. 11 fractional bits is actually insufficient for accurately - * rasterizing some triangles. More recently, the maximum viewport - * height was increased to 4K pixels. Thus, Mesa should be using 16 - * fractional bits in GLfixed. Unfortunately, there may be some issues - * with setting FIXED_FRAC_BITS=16, such as multiplication overflow. - * This will have to be examined in some detail... - * - * For now, if you find rasterization errors, particularly with tall, - * sliver triangles, try increasing FIXED_FRAC_BITS and/or decreasing - * SUB_PIXEL_BITS. - */ - -#include "util/u_math.h" - -#ifndef MAX_GLUINT -#define MAX_GLUINT 0xffffffffu -#endif - - -/* - * Some code we unfortunately need to prevent negative interpolated colors. - */ -#ifndef CLAMP_INTERPOLANT -#define CLAMP_INTERPOLANT(CHANNEL, CHANNELSTEP, LEN) \ -do { \ - GLfixed endVal = span.CHANNEL + (LEN) * span.CHANNELSTEP; \ - if (endVal < 0) { \ - span.CHANNEL -= endVal; \ - } \ - if (span.CHANNEL < 0) { \ - span.CHANNEL = 0; \ - } \ -} while (0) -#endif - - -static void NAME(struct gl_context *ctx, const SWvertex *v0, - const SWvertex *v1, - const SWvertex *v2 ) -{ - typedef struct { - const SWvertex *v0, *v1; /* Y(v0) < Y(v1) */ - GLfloat dx; /* X(v1) - X(v0) */ - GLfloat dy; /* Y(v1) - Y(v0) */ - GLfloat dxdy; /* dx/dy */ - GLfixed fdxdy; /* dx/dy in fixed-point */ - GLfloat adjy; /* adjust from v[0]->fy to fsy, scaled */ - GLfixed fsx; /* first sample point x coord */ - GLfixed fsy; - GLfixed fx0; /* fixed pt X of lower endpoint */ - GLint lines; /* number of lines to be sampled on this edge */ - } EdgeT; - - const SWcontext *swrast = SWRAST_CONTEXT(ctx); -#ifdef INTERP_Z - const GLint depthBits = ctx->DrawBuffer->Visual.depthBits; - const GLint fixedToDepthShift = depthBits <= 16 ? FIXED_SHIFT : 0; - const GLfloat maxDepth = ctx->DrawBuffer->_DepthMaxF; -#define FixedToDepth(F) ((F) >> fixedToDepthShift) -#endif - EdgeT eMaj, eTop, eBot; - GLfloat oneOverArea; - const SWvertex *vMin, *vMid, *vMax; /* Y(vMin)<=Y(vMid)<=Y(vMax) */ - GLfloat bf = SWRAST_CONTEXT(ctx)->_BackfaceSign; - const GLint snapMask = ~((FIXED_ONE / (1 << SUB_PIXEL_BITS)) - 1); /* for x/y coord snapping */ - GLfixed vMin_fx, vMin_fy, vMid_fx, vMid_fy, vMax_fx, vMax_fy; - - SWspan span; - - (void) swrast; - - INIT_SPAN(span, GL_POLYGON); - span.y = 0; /* silence warnings */ - -#ifdef INTERP_Z - (void) fixedToDepthShift; -#endif - - /* - printf("%s()\n", __func__); - printf(" %g, %g, %g\n", - v0->attrib[VARYING_SLOT_POS][0], - v0->attrib[VARYING_SLOT_POS][1], - v0->attrib[VARYING_SLOT_POS][2]); - printf(" %g, %g, %g\n", - v1->attrib[VARYING_SLOT_POS][0], - v1->attrib[VARYING_SLOT_POS][1], - v1->attrib[VARYING_SLOT_POS][2]); - printf(" %g, %g, %g\n", - v2->attrib[VARYING_SLOT_POS][0], - v2->attrib[VARYING_SLOT_POS][1], - v2->attrib[VARYING_SLOT_POS][2]); - */ - - /* Compute fixed point x,y coords w/ half-pixel offsets and snapping. - * And find the order of the 3 vertices along the Y axis. - */ - { - const GLfixed fy0 = FloatToFixed(v0->attrib[VARYING_SLOT_POS][1] - 0.5F) & snapMask; - const GLfixed fy1 = FloatToFixed(v1->attrib[VARYING_SLOT_POS][1] - 0.5F) & snapMask; - const GLfixed fy2 = FloatToFixed(v2->attrib[VARYING_SLOT_POS][1] - 0.5F) & snapMask; - if (fy0 <= fy1) { - if (fy1 <= fy2) { - /* y0 <= y1 <= y2 */ - vMin = v0; vMid = v1; vMax = v2; - vMin_fy = fy0; vMid_fy = fy1; vMax_fy = fy2; - } - else if (fy2 <= fy0) { - /* y2 <= y0 <= y1 */ - vMin = v2; vMid = v0; vMax = v1; - vMin_fy = fy2; vMid_fy = fy0; vMax_fy = fy1; - } - else { - /* y0 <= y2 <= y1 */ - vMin = v0; vMid = v2; vMax = v1; - vMin_fy = fy0; vMid_fy = fy2; vMax_fy = fy1; - bf = -bf; - } - } - else { - if (fy0 <= fy2) { - /* y1 <= y0 <= y2 */ - vMin = v1; vMid = v0; vMax = v2; - vMin_fy = fy1; vMid_fy = fy0; vMax_fy = fy2; - bf = -bf; - } - else if (fy2 <= fy1) { - /* y2 <= y1 <= y0 */ - vMin = v2; vMid = v1; vMax = v0; - vMin_fy = fy2; vMid_fy = fy1; vMax_fy = fy0; - bf = -bf; - } - else { - /* y1 <= y2 <= y0 */ - vMin = v1; vMid = v2; vMax = v0; - vMin_fy = fy1; vMid_fy = fy2; vMax_fy = fy0; - } - } - - /* fixed point X coords */ - vMin_fx = FloatToFixed(vMin->attrib[VARYING_SLOT_POS][0] + 0.5F) & snapMask; - vMid_fx = FloatToFixed(vMid->attrib[VARYING_SLOT_POS][0] + 0.5F) & snapMask; - vMax_fx = FloatToFixed(vMax->attrib[VARYING_SLOT_POS][0] + 0.5F) & snapMask; - } - - /* vertex/edge relationship */ - eMaj.v0 = vMin; eMaj.v1 = vMax; /*TODO: .v1's not needed */ - eTop.v0 = vMid; eTop.v1 = vMax; - eBot.v0 = vMin; eBot.v1 = vMid; - - /* compute deltas for each edge: vertex[upper] - vertex[lower] */ - eMaj.dx = FixedToFloat(vMax_fx - vMin_fx); - eMaj.dy = FixedToFloat(vMax_fy - vMin_fy); - eTop.dx = FixedToFloat(vMax_fx - vMid_fx); - eTop.dy = FixedToFloat(vMax_fy - vMid_fy); - eBot.dx = FixedToFloat(vMid_fx - vMin_fx); - eBot.dy = FixedToFloat(vMid_fy - vMin_fy); - - /* compute area, oneOverArea and perform backface culling */ - { - const GLfloat area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy; - - if (util_is_inf_or_nan(area) || area == 0.0F) - return; - - if (area * bf * swrast->_BackfaceCullSign < 0.0F) - return; - - oneOverArea = 1.0F / area; - - /* 0 = front, 1 = back */ - span.facing = oneOverArea * bf > 0.0F; - } - - /* Edge setup. For a triangle strip these could be reused... */ - { - eMaj.fsy = FixedCeil(vMin_fy); - eMaj.lines = FixedToInt(FixedCeil(vMax_fy - eMaj.fsy)); - if (eMaj.lines > 0) { - eMaj.dxdy = eMaj.dx / eMaj.dy; - eMaj.fdxdy = SignedFloatToFixed(eMaj.dxdy); - eMaj.adjy = (GLfloat) (eMaj.fsy - vMin_fy); /* SCALED! */ - eMaj.fx0 = vMin_fx; - eMaj.fsx = eMaj.fx0 + (GLfixed) (eMaj.adjy * eMaj.dxdy); - } - else { - return; /*CULLED*/ - } - - eTop.fsy = FixedCeil(vMid_fy); - eTop.lines = FixedToInt(FixedCeil(vMax_fy - eTop.fsy)); - if (eTop.lines > 0) { - eTop.dxdy = eTop.dx / eTop.dy; - eTop.fdxdy = SignedFloatToFixed(eTop.dxdy); - eTop.adjy = (GLfloat) (eTop.fsy - vMid_fy); /* SCALED! */ - eTop.fx0 = vMid_fx; - eTop.fsx = eTop.fx0 + (GLfixed) (eTop.adjy * eTop.dxdy); - } - - eBot.fsy = FixedCeil(vMin_fy); - eBot.lines = FixedToInt(FixedCeil(vMid_fy - eBot.fsy)); - if (eBot.lines > 0) { - eBot.dxdy = eBot.dx / eBot.dy; - eBot.fdxdy = SignedFloatToFixed(eBot.dxdy); - eBot.adjy = (GLfloat) (eBot.fsy - vMin_fy); /* SCALED! */ - eBot.fx0 = vMin_fx; - eBot.fsx = eBot.fx0 + (GLfixed) (eBot.adjy * eBot.dxdy); - } - } - - /* - * Conceptually, we view a triangle as two subtriangles - * separated by a perfectly horizontal line. The edge that is - * intersected by this line is one with maximal absolute dy; we - * call it a ``major'' edge. The other two edges are the - * ``top'' edge (for the upper subtriangle) and the ``bottom'' - * edge (for the lower subtriangle). If either of these two - * edges is horizontal or very close to horizontal, the - * corresponding subtriangle might cover zero sample points; - * we take care to handle such cases, for performance as well - * as correctness. - * - * By stepping rasterization parameters along the major edge, - * we can avoid recomputing them at the discontinuity where - * the top and bottom edges meet. However, this forces us to - * be able to scan both left-to-right and right-to-left. - * Also, we must determine whether the major edge is at the - * left or right side of the triangle. We do this by - * computing the magnitude of the cross-product of the major - * and top edges. Since this magnitude depends on the sine of - * the angle between the two edges, its sign tells us whether - * we turn to the left or to the right when travelling along - * the major edge to the top edge, and from this we infer - * whether the major edge is on the left or the right. - * - * Serendipitously, this cross-product magnitude is also a - * value we need to compute the iteration parameter - * derivatives for the triangle, and it can be used to perform - * backface culling because its sign tells us whether the - * triangle is clockwise or counterclockwise. In this code we - * refer to it as ``area'' because it's also proportional to - * the pixel area of the triangle. - */ - - { - GLint scan_from_left_to_right; /* true if scanning left-to-right */ - - /* - * Execute user-supplied setup code - */ -#ifdef SETUP_CODE - SETUP_CODE -#endif - - scan_from_left_to_right = (oneOverArea < 0.0F); - - - /* compute d?/dx and d?/dy derivatives */ -#ifdef INTERP_Z - span.interpMask |= SPAN_Z; - { - GLfloat eMaj_dz = vMax->attrib[VARYING_SLOT_POS][2] - vMin->attrib[VARYING_SLOT_POS][2]; - GLfloat eBot_dz = vMid->attrib[VARYING_SLOT_POS][2] - vMin->attrib[VARYING_SLOT_POS][2]; - span.attrStepX[VARYING_SLOT_POS][2] = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz); - if (span.attrStepX[VARYING_SLOT_POS][2] > maxDepth || - span.attrStepX[VARYING_SLOT_POS][2] < -maxDepth) { - /* probably a sliver triangle */ - span.attrStepX[VARYING_SLOT_POS][2] = 0.0; - span.attrStepY[VARYING_SLOT_POS][2] = 0.0; - } - else { - span.attrStepY[VARYING_SLOT_POS][2] = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx); - } - if (depthBits <= 16) - span.zStep = SignedFloatToFixed(span.attrStepX[VARYING_SLOT_POS][2]); - else - span.zStep = (GLint) span.attrStepX[VARYING_SLOT_POS][2]; - } -#endif -#ifdef INTERP_RGB - span.interpMask |= SPAN_RGBA; - if (ctx->Light.ShadeModel == GL_SMOOTH) { - GLfloat eMaj_dr = (GLfloat) (vMax->color[RCOMP] - vMin->color[RCOMP]); - GLfloat eBot_dr = (GLfloat) (vMid->color[RCOMP] - vMin->color[RCOMP]); - GLfloat eMaj_dg = (GLfloat) (vMax->color[GCOMP] - vMin->color[GCOMP]); - GLfloat eBot_dg = (GLfloat) (vMid->color[GCOMP] - vMin->color[GCOMP]); - GLfloat eMaj_db = (GLfloat) (vMax->color[BCOMP] - vMin->color[BCOMP]); - GLfloat eBot_db = (GLfloat) (vMid->color[BCOMP] - vMin->color[BCOMP]); -# ifdef INTERP_ALPHA - GLfloat eMaj_da = (GLfloat) (vMax->color[ACOMP] - vMin->color[ACOMP]); - GLfloat eBot_da = (GLfloat) (vMid->color[ACOMP] - vMin->color[ACOMP]); -# endif - span.attrStepX[VARYING_SLOT_COL0][0] = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr); - span.attrStepY[VARYING_SLOT_COL0][0] = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx); - span.attrStepX[VARYING_SLOT_COL0][1] = oneOverArea * (eMaj_dg * eBot.dy - eMaj.dy * eBot_dg); - span.attrStepY[VARYING_SLOT_COL0][1] = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx); - span.attrStepX[VARYING_SLOT_COL0][2] = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db); - span.attrStepY[VARYING_SLOT_COL0][2] = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx); - span.redStep = SignedFloatToFixed(span.attrStepX[VARYING_SLOT_COL0][0]); - span.greenStep = SignedFloatToFixed(span.attrStepX[VARYING_SLOT_COL0][1]); - span.blueStep = SignedFloatToFixed(span.attrStepX[VARYING_SLOT_COL0][2]); -# ifdef INTERP_ALPHA - span.attrStepX[VARYING_SLOT_COL0][3] = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da); - span.attrStepY[VARYING_SLOT_COL0][3] = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx); - span.alphaStep = SignedFloatToFixed(span.attrStepX[VARYING_SLOT_COL0][3]); -# endif /* INTERP_ALPHA */ - } - else { - assert(ctx->Light.ShadeModel == GL_FLAT); - span.interpMask |= SPAN_FLAT; - span.attrStepX[VARYING_SLOT_COL0][0] = span.attrStepY[VARYING_SLOT_COL0][0] = 0.0F; - span.attrStepX[VARYING_SLOT_COL0][1] = span.attrStepY[VARYING_SLOT_COL0][1] = 0.0F; - span.attrStepX[VARYING_SLOT_COL0][2] = span.attrStepY[VARYING_SLOT_COL0][2] = 0.0F; - span.redStep = 0; - span.greenStep = 0; - span.blueStep = 0; -# ifdef INTERP_ALPHA - span.attrStepX[VARYING_SLOT_COL0][3] = span.attrStepY[VARYING_SLOT_COL0][3] = 0.0F; - span.alphaStep = 0; -# endif - } -#endif /* INTERP_RGB */ -#ifdef INTERP_INT_TEX - { - GLfloat eMaj_ds = (vMax->attrib[VARYING_SLOT_TEX0][0] - vMin->attrib[VARYING_SLOT_TEX0][0]) * S_SCALE; - GLfloat eBot_ds = (vMid->attrib[VARYING_SLOT_TEX0][0] - vMin->attrib[VARYING_SLOT_TEX0][0]) * S_SCALE; - GLfloat eMaj_dt = (vMax->attrib[VARYING_SLOT_TEX0][1] - vMin->attrib[VARYING_SLOT_TEX0][1]) * T_SCALE; - GLfloat eBot_dt = (vMid->attrib[VARYING_SLOT_TEX0][1] - vMin->attrib[VARYING_SLOT_TEX0][1]) * T_SCALE; - span.attrStepX[VARYING_SLOT_TEX0][0] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds); - span.attrStepY[VARYING_SLOT_TEX0][0] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx); - span.attrStepX[VARYING_SLOT_TEX0][1] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt); - span.attrStepY[VARYING_SLOT_TEX0][1] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx); - span.intTexStep[0] = SignedFloatToFixed(span.attrStepX[VARYING_SLOT_TEX0][0]); - span.intTexStep[1] = SignedFloatToFixed(span.attrStepX[VARYING_SLOT_TEX0][1]); - } -#endif -#ifdef INTERP_ATTRIBS - { - /* attrib[VARYING_SLOT_POS][3] is 1/W */ - const GLfloat wMax = vMax->attrib[VARYING_SLOT_POS][3]; - const GLfloat wMin = vMin->attrib[VARYING_SLOT_POS][3]; - const GLfloat wMid = vMid->attrib[VARYING_SLOT_POS][3]; - { - const GLfloat eMaj_dw = wMax - wMin; - const GLfloat eBot_dw = wMid - wMin; - span.attrStepX[VARYING_SLOT_POS][3] = oneOverArea * (eMaj_dw * eBot.dy - eMaj.dy * eBot_dw); - span.attrStepY[VARYING_SLOT_POS][3] = oneOverArea * (eMaj.dx * eBot_dw - eMaj_dw * eBot.dx); - } - ATTRIB_LOOP_BEGIN - if (swrast->_InterpMode[attr] == GL_FLAT) { - ASSIGN_4V(span.attrStepX[attr], 0.0, 0.0, 0.0, 0.0); - ASSIGN_4V(span.attrStepY[attr], 0.0, 0.0, 0.0, 0.0); - } - else { - GLuint c; - for (c = 0; c < 4; c++) { - GLfloat eMaj_da = vMax->attrib[attr][c] * wMax - vMin->attrib[attr][c] * wMin; - GLfloat eBot_da = vMid->attrib[attr][c] * wMid - vMin->attrib[attr][c] * wMin; - span.attrStepX[attr][c] = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da); - span.attrStepY[attr][c] = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx); - } - } - ATTRIB_LOOP_END - } -#endif - - /* - * We always sample at pixel centers. However, we avoid - * explicit half-pixel offsets in this code by incorporating - * the proper offset in each of x and y during the - * transformation to window coordinates. - * - * We also apply the usual rasterization rules to prevent - * cracks and overlaps. A pixel is considered inside a - * subtriangle if it meets all of four conditions: it is on or - * to the right of the left edge, strictly to the left of the - * right edge, on or below the top edge, and strictly above - * the bottom edge. (Some edges may be degenerate.) - * - * The following discussion assumes left-to-right scanning - * (that is, the major edge is on the left); the right-to-left - * case is a straightforward variation. - * - * We start by finding the half-integral y coordinate that is - * at or below the top of the triangle. This gives us the - * first scan line that could possibly contain pixels that are - * inside the triangle. - * - * Next we creep down the major edge until we reach that y, - * and compute the corresponding x coordinate on the edge. - * Then we find the half-integral x that lies on or just - * inside the edge. This is the first pixel that might lie in - * the interior of the triangle. (We won't know for sure - * until we check the other edges.) - * - * As we rasterize the triangle, we'll step down the major - * edge. For each step in y, we'll move an integer number - * of steps in x. There are two possible x step sizes, which - * we'll call the ``inner'' step (guaranteed to land on the - * edge or inside it) and the ``outer'' step (guaranteed to - * land on the edge or outside it). The inner and outer steps - * differ by one. During rasterization we maintain an error - * term that indicates our distance from the true edge, and - * select either the inner step or the outer step, whichever - * gets us to the first pixel that falls inside the triangle. - * - * All parameters (z, red, etc.) as well as the buffer - * addresses for color and z have inner and outer step values, - * so that we can increment them appropriately. This method - * eliminates the need to adjust parameters by creeping a - * sub-pixel amount into the triangle at each scanline. - */ - - { - GLint subTriangle; - GLfixed fxLeftEdge = 0, fxRightEdge = 0; - GLfixed fdxLeftEdge = 0, fdxRightEdge = 0; - GLfixed fError = 0, fdError = 0; -#ifdef PIXEL_ADDRESS - PIXEL_TYPE *pRow = NULL; - GLint dPRowOuter = 0, dPRowInner; /* offset in bytes */ -#endif -#ifdef INTERP_Z -# ifdef DEPTH_TYPE - struct gl_renderbuffer *zrb - = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; - DEPTH_TYPE *zRow = NULL; - GLint dZRowOuter = 0, dZRowInner; /* offset in bytes */ -# endif - GLuint zLeft = 0; - GLfixed fdzOuter = 0, fdzInner; -#endif -#ifdef INTERP_RGB - GLint rLeft = 0, fdrOuter = 0, fdrInner; - GLint gLeft = 0, fdgOuter = 0, fdgInner; - GLint bLeft = 0, fdbOuter = 0, fdbInner; -#endif -#ifdef INTERP_ALPHA - GLint aLeft = 0, fdaOuter = 0, fdaInner; -#endif -#ifdef INTERP_INT_TEX - GLfixed sLeft=0, dsOuter=0, dsInner; - GLfixed tLeft=0, dtOuter=0, dtInner; -#endif -#ifdef INTERP_ATTRIBS - GLfloat wLeft = 0, dwOuter = 0, dwInner; - GLfloat attrLeft[VARYING_SLOT_MAX][4]; - GLfloat daOuter[VARYING_SLOT_MAX][4], daInner[VARYING_SLOT_MAX][4]; -#endif - - for (subTriangle=0; subTriangle<=1; subTriangle++) { - EdgeT *eLeft, *eRight; - int setupLeft, setupRight; - int lines; - - if (subTriangle==0) { - /* bottom half */ - if (scan_from_left_to_right) { - eLeft = &eMaj; - eRight = &eBot; - lines = eRight->lines; - setupLeft = 1; - setupRight = 1; - } - else { - eLeft = &eBot; - eRight = &eMaj; - lines = eLeft->lines; - setupLeft = 1; - setupRight = 1; - } - } - else { - /* top half */ - if (scan_from_left_to_right) { - eLeft = &eMaj; - eRight = &eTop; - lines = eRight->lines; - setupLeft = 0; - setupRight = 1; - } - else { - eLeft = &eTop; - eRight = &eMaj; - lines = eLeft->lines; - setupLeft = 1; - setupRight = 0; - } - if (lines == 0) - return; - } - - if (setupLeft && eLeft->lines > 0) { - const SWvertex *vLower = eLeft->v0; - const GLfixed fsy = eLeft->fsy; - const GLfixed fsx = eLeft->fsx; /* no fractional part */ - const GLfixed fx = FixedCeil(fsx); /* no fractional part */ - const GLfixed adjx = (GLfixed) (fx - eLeft->fx0); /* SCALED! */ - const GLfixed adjy = (GLfixed) eLeft->adjy; /* SCALED! */ - GLint idxOuter; - GLfloat dxOuter; - GLfixed fdxOuter; - - fError = fx - fsx - FIXED_ONE; - fxLeftEdge = fsx - FIXED_EPSILON; - fdxLeftEdge = eLeft->fdxdy; - fdxOuter = FixedFloor(fdxLeftEdge - FIXED_EPSILON); - fdError = fdxOuter - fdxLeftEdge + FIXED_ONE; - idxOuter = FixedToInt(fdxOuter); - dxOuter = (GLfloat) idxOuter; - span.y = FixedToInt(fsy); - - /* silence warnings on some compilers */ - (void) dxOuter; - (void) adjx; - (void) adjy; - (void) vLower; - -#ifdef PIXEL_ADDRESS - { - pRow = (PIXEL_TYPE *) PIXEL_ADDRESS(FixedToInt(fxLeftEdge), span.y); - dPRowOuter = -((int)BYTES_PER_ROW) + idxOuter * sizeof(PIXEL_TYPE); - /* negative because Y=0 at bottom and increases upward */ - } -#endif - /* - * Now we need the set of parameter (z, color, etc.) values at - * the point (fx, fsy). This gives us properly-sampled parameter - * values that we can step from pixel to pixel. Furthermore, - * although we might have intermediate results that overflow - * the normal parameter range when we step temporarily outside - * the triangle, we shouldn't overflow or underflow for any - * pixel that's actually inside the triangle. - */ - -#ifdef INTERP_Z - { - GLfloat z0 = vLower->attrib[VARYING_SLOT_POS][2]; - if (depthBits <= 16) { - /* interpolate fixed-pt values */ - GLfloat tmp = (z0 * FIXED_SCALE - + span.attrStepX[VARYING_SLOT_POS][2] * adjx - + span.attrStepY[VARYING_SLOT_POS][2] * adjy) + FIXED_HALF; - if (tmp < MAX_GLUINT / 2) - zLeft = (GLfixed) tmp; - else - zLeft = MAX_GLUINT / 2; - fdzOuter = SignedFloatToFixed(span.attrStepY[VARYING_SLOT_POS][2] + - dxOuter * span.attrStepX[VARYING_SLOT_POS][2]); - } - else { - /* interpolate depth values w/out scaling */ - zLeft = (GLuint) (z0 + span.attrStepX[VARYING_SLOT_POS][2] * FixedToFloat(adjx) - + span.attrStepY[VARYING_SLOT_POS][2] * FixedToFloat(adjy)); - fdzOuter = (GLint) (span.attrStepY[VARYING_SLOT_POS][2] + - dxOuter * span.attrStepX[VARYING_SLOT_POS][2]); - } -# ifdef DEPTH_TYPE - zRow = (DEPTH_TYPE *) - _swrast_pixel_address(zrb, FixedToInt(fxLeftEdge), span.y); - dZRowOuter = (ctx->DrawBuffer->Width + idxOuter) * sizeof(DEPTH_TYPE); -# endif - } -#endif -#ifdef INTERP_RGB - if (ctx->Light.ShadeModel == GL_SMOOTH) { - rLeft = (GLint)(ChanToFixed(vLower->color[RCOMP]) - + span.attrStepX[VARYING_SLOT_COL0][0] * adjx - + span.attrStepY[VARYING_SLOT_COL0][0] * adjy) + FIXED_HALF; - gLeft = (GLint)(ChanToFixed(vLower->color[GCOMP]) - + span.attrStepX[VARYING_SLOT_COL0][1] * adjx - + span.attrStepY[VARYING_SLOT_COL0][1] * adjy) + FIXED_HALF; - bLeft = (GLint)(ChanToFixed(vLower->color[BCOMP]) - + span.attrStepX[VARYING_SLOT_COL0][2] * adjx - + span.attrStepY[VARYING_SLOT_COL0][2] * adjy) + FIXED_HALF; - fdrOuter = SignedFloatToFixed(span.attrStepY[VARYING_SLOT_COL0][0] - + dxOuter * span.attrStepX[VARYING_SLOT_COL0][0]); - fdgOuter = SignedFloatToFixed(span.attrStepY[VARYING_SLOT_COL0][1] - + dxOuter * span.attrStepX[VARYING_SLOT_COL0][1]); - fdbOuter = SignedFloatToFixed(span.attrStepY[VARYING_SLOT_COL0][2] - + dxOuter * span.attrStepX[VARYING_SLOT_COL0][2]); -# ifdef INTERP_ALPHA - aLeft = (GLint)(ChanToFixed(vLower->color[ACOMP]) - + span.attrStepX[VARYING_SLOT_COL0][3] * adjx - + span.attrStepY[VARYING_SLOT_COL0][3] * adjy) + FIXED_HALF; - fdaOuter = SignedFloatToFixed(span.attrStepY[VARYING_SLOT_COL0][3] - + dxOuter * span.attrStepX[VARYING_SLOT_COL0][3]); -# endif - } - else { - assert(ctx->Light.ShadeModel == GL_FLAT); - rLeft = ChanToFixed(v2->color[RCOMP]); - gLeft = ChanToFixed(v2->color[GCOMP]); - bLeft = ChanToFixed(v2->color[BCOMP]); - fdrOuter = fdgOuter = fdbOuter = 0; -# ifdef INTERP_ALPHA - aLeft = ChanToFixed(v2->color[ACOMP]); - fdaOuter = 0; -# endif - } -#endif /* INTERP_RGB */ - - -#ifdef INTERP_INT_TEX - { - GLfloat s0, t0; - s0 = vLower->attrib[VARYING_SLOT_TEX0][0] * S_SCALE; - sLeft = (GLfixed)(s0 * FIXED_SCALE + span.attrStepX[VARYING_SLOT_TEX0][0] * adjx - + span.attrStepY[VARYING_SLOT_TEX0][0] * adjy) + FIXED_HALF; - dsOuter = SignedFloatToFixed(span.attrStepY[VARYING_SLOT_TEX0][0] - + dxOuter * span.attrStepX[VARYING_SLOT_TEX0][0]); - - t0 = vLower->attrib[VARYING_SLOT_TEX0][1] * T_SCALE; - tLeft = (GLfixed)(t0 * FIXED_SCALE + span.attrStepX[VARYING_SLOT_TEX0][1] * adjx - + span.attrStepY[VARYING_SLOT_TEX0][1] * adjy) + FIXED_HALF; - dtOuter = SignedFloatToFixed(span.attrStepY[VARYING_SLOT_TEX0][1] - + dxOuter * span.attrStepX[VARYING_SLOT_TEX0][1]); - } -#endif -#ifdef INTERP_ATTRIBS - { - const GLuint attr = VARYING_SLOT_POS; - wLeft = vLower->attrib[VARYING_SLOT_POS][3] - + (span.attrStepX[attr][3] * adjx - + span.attrStepY[attr][3] * adjy) * (1.0F/FIXED_SCALE); - dwOuter = span.attrStepY[attr][3] + dxOuter * span.attrStepX[attr][3]; - } - ATTRIB_LOOP_BEGIN - const GLfloat invW = vLower->attrib[VARYING_SLOT_POS][3]; - if (swrast->_InterpMode[attr] == GL_FLAT) { - GLuint c; - for (c = 0; c < 4; c++) { - attrLeft[attr][c] = v2->attrib[attr][c] * invW; - daOuter[attr][c] = 0.0; - } - } - else { - GLuint c; - for (c = 0; c < 4; c++) { - const GLfloat a = vLower->attrib[attr][c] * invW; - attrLeft[attr][c] = a + ( span.attrStepX[attr][c] * adjx - + span.attrStepY[attr][c] * adjy) * (1.0F/FIXED_SCALE); - daOuter[attr][c] = span.attrStepY[attr][c] + dxOuter * span.attrStepX[attr][c]; - } - } - ATTRIB_LOOP_END -#endif - } /*if setupLeft*/ - - - if (setupRight && eRight->lines>0) { - fxRightEdge = eRight->fsx - FIXED_EPSILON; - fdxRightEdge = eRight->fdxdy; - } - - if (lines==0) { - continue; - } - - - /* Rasterize setup */ -#ifdef PIXEL_ADDRESS - dPRowInner = dPRowOuter + sizeof(PIXEL_TYPE); -#endif -#ifdef INTERP_Z -# ifdef DEPTH_TYPE - dZRowInner = dZRowOuter + sizeof(DEPTH_TYPE); -# endif - fdzInner = fdzOuter + span.zStep; -#endif -#ifdef INTERP_RGB - fdrInner = fdrOuter + span.redStep; - fdgInner = fdgOuter + span.greenStep; - fdbInner = fdbOuter + span.blueStep; -#endif -#ifdef INTERP_ALPHA - fdaInner = fdaOuter + span.alphaStep; -#endif -#ifdef INTERP_INT_TEX - dsInner = dsOuter + span.intTexStep[0]; - dtInner = dtOuter + span.intTexStep[1]; -#endif -#ifdef INTERP_ATTRIBS - dwInner = dwOuter + span.attrStepX[VARYING_SLOT_POS][3]; - ATTRIB_LOOP_BEGIN - GLuint c; - for (c = 0; c < 4; c++) { - daInner[attr][c] = daOuter[attr][c] + span.attrStepX[attr][c]; - } - ATTRIB_LOOP_END -#endif - - while (lines > 0) { - /* initialize the span interpolants to the leftmost value */ - /* ff = fixed-pt fragment */ - const GLint right = FixedToInt(fxRightEdge); - span.x = FixedToInt(fxLeftEdge); - if (right <= span.x) - span.end = 0; - else - span.end = right - span.x; - -#ifdef INTERP_Z - span.z = zLeft; -#endif -#ifdef INTERP_RGB - span.red = rLeft; - span.green = gLeft; - span.blue = bLeft; -#endif -#ifdef INTERP_ALPHA - span.alpha = aLeft; -#endif -#ifdef INTERP_INT_TEX - span.intTex[0] = sLeft; - span.intTex[1] = tLeft; -#endif - -#ifdef INTERP_ATTRIBS - span.attrStart[VARYING_SLOT_POS][3] = wLeft; - ATTRIB_LOOP_BEGIN - GLuint c; - for (c = 0; c < 4; c++) { - span.attrStart[attr][c] = attrLeft[attr][c]; - } - ATTRIB_LOOP_END -#endif - - /* This is where we actually generate fragments */ - /* XXX the test for span.y > 0 _shouldn't_ be needed but - * it fixes a problem on 64-bit Opterons (bug 4842). - */ - if (span.end > 0 && span.y >= 0) { - const GLint len = span.end - 1; - (void) len; -#ifdef INTERP_RGB - CLAMP_INTERPOLANT(red, redStep, len); - CLAMP_INTERPOLANT(green, greenStep, len); - CLAMP_INTERPOLANT(blue, blueStep, len); -#endif -#ifdef INTERP_ALPHA - CLAMP_INTERPOLANT(alpha, alphaStep, len); -#endif - { - RENDER_SPAN( span ); - } - } - - /* - * Advance to the next scan line. Compute the - * new edge coordinates, and adjust the - * pixel-center x coordinate so that it stays - * on or inside the major edge. - */ - span.y++; - lines--; - - fxLeftEdge += fdxLeftEdge; - fxRightEdge += fdxRightEdge; - - fError += fdError; - if (fError >= 0) { - fError -= FIXED_ONE; - -#ifdef PIXEL_ADDRESS - pRow = (PIXEL_TYPE *) ((GLubyte *) pRow + dPRowOuter); -#endif -#ifdef INTERP_Z -# ifdef DEPTH_TYPE - zRow = (DEPTH_TYPE *) ((GLubyte *) zRow + dZRowOuter); -# endif - zLeft += fdzOuter; -#endif -#ifdef INTERP_RGB - rLeft += fdrOuter; - gLeft += fdgOuter; - bLeft += fdbOuter; -#endif -#ifdef INTERP_ALPHA - aLeft += fdaOuter; -#endif -#ifdef INTERP_INT_TEX - sLeft += dsOuter; - tLeft += dtOuter; -#endif -#ifdef INTERP_ATTRIBS - wLeft += dwOuter; - ATTRIB_LOOP_BEGIN - GLuint c; - for (c = 0; c < 4; c++) { - attrLeft[attr][c] += daOuter[attr][c]; - } - ATTRIB_LOOP_END -#endif - } - else { -#ifdef PIXEL_ADDRESS - pRow = (PIXEL_TYPE *) ((GLubyte *) pRow + dPRowInner); -#endif -#ifdef INTERP_Z -# ifdef DEPTH_TYPE - zRow = (DEPTH_TYPE *) ((GLubyte *) zRow + dZRowInner); -# endif - zLeft += fdzInner; -#endif -#ifdef INTERP_RGB - rLeft += fdrInner; - gLeft += fdgInner; - bLeft += fdbInner; -#endif -#ifdef INTERP_ALPHA - aLeft += fdaInner; -#endif -#ifdef INTERP_INT_TEX - sLeft += dsInner; - tLeft += dtInner; -#endif -#ifdef INTERP_ATTRIBS - wLeft += dwInner; - ATTRIB_LOOP_BEGIN - GLuint c; - for (c = 0; c < 4; c++) { - attrLeft[attr][c] += daInner[attr][c]; - } - ATTRIB_LOOP_END -#endif - } - } /*while lines>0*/ - - } /* for subTriangle */ - - } - } -} - -#undef SETUP_CODE -#undef RENDER_SPAN - -#undef PIXEL_TYPE -#undef BYTES_PER_ROW -#undef PIXEL_ADDRESS -#undef DEPTH_TYPE - -#undef INTERP_Z -#undef INTERP_RGB -#undef INTERP_ALPHA -#undef INTERP_INT_TEX -#undef INTERP_ATTRIBS - -#undef S_SCALE -#undef T_SCALE - -#undef FixedToDepth - -#undef NAME diff --git a/src/mesa/swrast/s_zoom.c b/src/mesa/swrast/s_zoom.c deleted file mode 100644 index ca4ead9..0000000 --- a/src/mesa/swrast/s_zoom.c +++ /dev/null @@ -1,442 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -#include "main/errors.h" -#include "main/glheader.h" -#include "main/macros.h" - -#include "main/format_pack.h" - -#include "s_context.h" -#include "s_span.h" -#include "s_stencil.h" -#include "s_zoom.h" - - -/** - * Compute the bounds of the region resulting from zooming a pixel span. - * The resulting region will be entirely inside the window/scissor bounds - * so no additional clipping is needed. - * \param imageX, imageY position of the mage being drawn (gl WindowPos) - * \param spanX, spanY position of span being drawing - * \param width number of pixels in span - * \param x0, x1 returned X bounds of zoomed region [x0, x1) - * \param y0, y1 returned Y bounds of zoomed region [y0, y1) - * \return GL_TRUE if any zoomed pixels visible, GL_FALSE if totally clipped - */ -static GLboolean -compute_zoomed_bounds(struct gl_context *ctx, GLint imageX, GLint imageY, - GLint spanX, GLint spanY, GLint width, - GLint *x0, GLint *x1, GLint *y0, GLint *y1) -{ - const struct gl_framebuffer *fb = ctx->DrawBuffer; - GLint c0, c1, r0, r1; - - assert(spanX >= imageX); - assert(spanY >= imageY); - - /* - * Compute destination columns: [c0, c1) - */ - c0 = imageX + (GLint) ((spanX - imageX) * ctx->Pixel.ZoomX); - c1 = imageX + (GLint) ((spanX + width - imageX) * ctx->Pixel.ZoomX); - if (c1 < c0) { - /* swap */ - GLint tmp = c1; - c1 = c0; - c0 = tmp; - } - c0 = CLAMP(c0, fb->_Xmin, fb->_Xmax); - c1 = CLAMP(c1, fb->_Xmin, fb->_Xmax); - if (c0 == c1) { - return GL_FALSE; /* no width */ - } - - /* - * Compute destination rows: [r0, r1) - */ - r0 = imageY + (GLint) ((spanY - imageY) * ctx->Pixel.ZoomY); - r1 = imageY + (GLint) ((spanY + 1 - imageY) * ctx->Pixel.ZoomY); - if (r1 < r0) { - /* swap */ - GLint tmp = r1; - r1 = r0; - r0 = tmp; - } - r0 = CLAMP(r0, fb->_Ymin, fb->_Ymax); - r1 = CLAMP(r1, fb->_Ymin, fb->_Ymax); - if (r0 == r1) { - return GL_FALSE; /* no height */ - } - - *x0 = c0; - *x1 = c1; - *y0 = r0; - *y1 = r1; - - return GL_TRUE; -} - - -/** - * Convert a zoomed x image coordinate back to an unzoomed x coord. - * 'zx' is screen position of a pixel in the zoomed image, who's left edge - * is at 'imageX'. - * return corresponding x coord in the original, unzoomed image. - * This can use this for unzooming X or Y values. - */ -static inline GLint -unzoom_x(GLfloat zoomX, GLint imageX, GLint zx) -{ - /* - zx = imageX + (x - imageX) * zoomX; - zx - imageX = (x - imageX) * zoomX; - (zx - imageX) / zoomX = x - imageX; - */ - GLint x; - if (zoomX < 0.0F) - zx++; - x = imageX + (GLint) ((zx - imageX) / zoomX); - return x; -} - - - -/** - * Helper function called from _swrast_write_zoomed_rgba/rgb/ - * index/depth_span(). - */ -static void -zoom_span( struct gl_context *ctx, GLint imgX, GLint imgY, const SWspan *span, - const GLvoid *src, GLenum format ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - SWspan zoomed; - GLint x0, x1, y0, y1; - GLint zoomedWidth; - - if (!compute_zoomed_bounds(ctx, imgX, imgY, span->x, span->y, span->end, - &x0, &x1, &y0, &y1)) { - return; /* totally clipped */ - } - - if (!swrast->ZoomedArrays) { - /* allocate on demand */ - swrast->ZoomedArrays = (SWspanarrays *) calloc(1, sizeof(SWspanarrays)); - if (!swrast->ZoomedArrays) - return; - } - - zoomedWidth = x1 - x0; - assert(zoomedWidth > 0); - assert(zoomedWidth <= SWRAST_MAX_WIDTH); - - /* no pixel arrays! must be horizontal spans. */ - assert((span->arrayMask & SPAN_XY) == 0); - assert(span->primitive == GL_BITMAP); - - INIT_SPAN(zoomed, GL_BITMAP); - zoomed.x = x0; - zoomed.end = zoomedWidth; - zoomed.array = swrast->ZoomedArrays; - zoomed.array->ChanType = span->array->ChanType; - if (zoomed.array->ChanType == GL_UNSIGNED_BYTE) - zoomed.array->rgba = (GLchan (*)[4]) zoomed.array->rgba8; - else if (zoomed.array->ChanType == GL_UNSIGNED_SHORT) - zoomed.array->rgba = (GLchan (*)[4]) zoomed.array->rgba16; - else - zoomed.array->rgba = (GLchan (*)[4]) zoomed.array->attribs[VARYING_SLOT_COL0]; - - COPY_4V(zoomed.attrStart[VARYING_SLOT_POS], span->attrStart[VARYING_SLOT_POS]); - COPY_4V(zoomed.attrStepX[VARYING_SLOT_POS], span->attrStepX[VARYING_SLOT_POS]); - COPY_4V(zoomed.attrStepY[VARYING_SLOT_POS], span->attrStepY[VARYING_SLOT_POS]); - - zoomed.attrStart[VARYING_SLOT_FOGC][0] = span->attrStart[VARYING_SLOT_FOGC][0]; - zoomed.attrStepX[VARYING_SLOT_FOGC][0] = span->attrStepX[VARYING_SLOT_FOGC][0]; - zoomed.attrStepY[VARYING_SLOT_FOGC][0] = span->attrStepY[VARYING_SLOT_FOGC][0]; - - if (format == GL_RGBA || format == GL_RGB) { - /* copy Z info */ - zoomed.z = span->z; - zoomed.zStep = span->zStep; - /* we'll generate an array of colorss */ - zoomed.interpMask = span->interpMask & ~SPAN_RGBA; - zoomed.arrayMask |= SPAN_RGBA; - zoomed.arrayAttribs |= VARYING_BIT_COL0; /* we'll produce these values */ - assert(span->arrayMask & SPAN_RGBA); - } - else if (format == GL_DEPTH_COMPONENT) { - /* Copy color info */ - zoomed.red = span->red; - zoomed.green = span->green; - zoomed.blue = span->blue; - zoomed.alpha = span->alpha; - zoomed.redStep = span->redStep; - zoomed.greenStep = span->greenStep; - zoomed.blueStep = span->blueStep; - zoomed.alphaStep = span->alphaStep; - /* we'll generate an array of depth values */ - zoomed.interpMask = span->interpMask & ~SPAN_Z; - zoomed.arrayMask |= SPAN_Z; - assert(span->arrayMask & SPAN_Z); - } - else { - _mesa_problem(ctx, "Bad format in zoom_span"); - return; - } - - /* zoom the span horizontally */ - if (format == GL_RGBA) { - if (zoomed.array->ChanType == GL_UNSIGNED_BYTE) { - const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) src; - GLint i; - for (i = 0; i < zoomedWidth; i++) { - GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x; - assert(j >= 0); - assert(j < (GLint) span->end); - COPY_4UBV(zoomed.array->rgba8[i], rgba[j]); - } - } - else if (zoomed.array->ChanType == GL_UNSIGNED_SHORT) { - const GLushort (*rgba)[4] = (const GLushort (*)[4]) src; - GLint i; - for (i = 0; i < zoomedWidth; i++) { - GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x; - assert(j >= 0); - assert(j < (GLint) span->end); - COPY_4V(zoomed.array->rgba16[i], rgba[j]); - } - } - else { - const GLfloat (*rgba)[4] = (const GLfloat (*)[4]) src; - GLint i; - for (i = 0; i < zoomedWidth; i++) { - GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x; - assert(j >= 0); - assert(j < (GLint) span->end); - COPY_4V(zoomed.array->attribs[VARYING_SLOT_COL0][i], rgba[j]); - } - } - } - else if (format == GL_RGB) { - if (zoomed.array->ChanType == GL_UNSIGNED_BYTE) { - const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) src; - GLint i; - for (i = 0; i < zoomedWidth; i++) { - GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x; - assert(j >= 0); - assert(j < (GLint) span->end); - zoomed.array->rgba8[i][0] = rgb[j][0]; - zoomed.array->rgba8[i][1] = rgb[j][1]; - zoomed.array->rgba8[i][2] = rgb[j][2]; - zoomed.array->rgba8[i][3] = 0xff; - } - } - else if (zoomed.array->ChanType == GL_UNSIGNED_SHORT) { - const GLushort (*rgb)[3] = (const GLushort (*)[3]) src; - GLint i; - for (i = 0; i < zoomedWidth; i++) { - GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x; - assert(j >= 0); - assert(j < (GLint) span->end); - zoomed.array->rgba16[i][0] = rgb[j][0]; - zoomed.array->rgba16[i][1] = rgb[j][1]; - zoomed.array->rgba16[i][2] = rgb[j][2]; - zoomed.array->rgba16[i][3] = 0xffff; - } - } - else { - const GLfloat (*rgb)[3] = (const GLfloat (*)[3]) src; - GLint i; - for (i = 0; i < zoomedWidth; i++) { - GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x; - assert(j >= 0); - assert(j < (GLint) span->end); - zoomed.array->attribs[VARYING_SLOT_COL0][i][0] = rgb[j][0]; - zoomed.array->attribs[VARYING_SLOT_COL0][i][1] = rgb[j][1]; - zoomed.array->attribs[VARYING_SLOT_COL0][i][2] = rgb[j][2]; - zoomed.array->attribs[VARYING_SLOT_COL0][i][3] = 1.0F; - } - } - } - else if (format == GL_DEPTH_COMPONENT) { - const GLuint *zValues = (const GLuint *) src; - GLint i; - for (i = 0; i < zoomedWidth; i++) { - GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x; - assert(j >= 0); - assert(j < (GLint) span->end); - zoomed.array->z[i] = zValues[j]; - } - /* Now, fall into the RGB path below */ - format = GL_RGBA; - } - - /* write the span in rows [r0, r1) */ - if (format == GL_RGBA || format == GL_RGB) { - /* Writing the span may modify the colors, so make a backup now if we're - * going to call _swrast_write_zoomed_span() more than once. - * Also, clipping may change the span end value, so store it as well. - */ - const GLint end = zoomed.end; /* save */ - void *rgbaSave; - const GLint pixelSize = - (zoomed.array->ChanType == GL_UNSIGNED_BYTE) ? 4 * sizeof(GLubyte) : - ((zoomed.array->ChanType == GL_UNSIGNED_SHORT) ? 4 * sizeof(GLushort) - : 4 * sizeof(GLfloat)); - - rgbaSave = malloc(zoomed.end * pixelSize); - if (!rgbaSave) { - return; - } - - if (y1 - y0 > 1) { - memcpy(rgbaSave, zoomed.array->rgba, zoomed.end * pixelSize); - } - for (zoomed.y = y0; zoomed.y < y1; zoomed.y++) { - _swrast_write_rgba_span(ctx, &zoomed); - zoomed.end = end; /* restore */ - if (y1 - y0 > 1) { - /* restore the colors */ - memcpy(zoomed.array->rgba, rgbaSave, zoomed.end * pixelSize); - } - } - - free(rgbaSave); - } -} - - -void -_swrast_write_zoomed_rgba_span(struct gl_context *ctx, GLint imgX, GLint imgY, - const SWspan *span, const GLvoid *rgba) -{ - zoom_span(ctx, imgX, imgY, span, rgba, GL_RGBA); -} - - -void -_swrast_write_zoomed_rgb_span(struct gl_context *ctx, GLint imgX, GLint imgY, - const SWspan *span, const GLvoid *rgb) -{ - zoom_span(ctx, imgX, imgY, span, rgb, GL_RGB); -} - - -void -_swrast_write_zoomed_depth_span(struct gl_context *ctx, GLint imgX, GLint imgY, - const SWspan *span) -{ - zoom_span(ctx, imgX, imgY, span, - (const GLvoid *) span->array->z, GL_DEPTH_COMPONENT); -} - - -/** - * Zoom/write stencil values. - * No per-fragment operations are applied. - */ -void -_swrast_write_zoomed_stencil_span(struct gl_context *ctx, GLint imgX, GLint imgY, - GLint width, GLint spanX, GLint spanY, - const GLubyte stencil[]) -{ - GLubyte *zoomedVals; - GLint x0, x1, y0, y1, y; - GLint i, zoomedWidth; - - if (!compute_zoomed_bounds(ctx, imgX, imgY, spanX, spanY, width, - &x0, &x1, &y0, &y1)) { - return; /* totally clipped */ - } - - zoomedWidth = x1 - x0; - assert(zoomedWidth > 0); - assert(zoomedWidth <= SWRAST_MAX_WIDTH); - - zoomedVals = malloc(zoomedWidth * sizeof(GLubyte)); - if (!zoomedVals) - return; - - /* zoom the span horizontally */ - for (i = 0; i < zoomedWidth; i++) { - GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - spanX; - assert(j >= 0); - assert(j < width); - zoomedVals[i] = stencil[j]; - } - - /* write the zoomed spans */ - for (y = y0; y < y1; y++) { - _swrast_write_stencil_span(ctx, zoomedWidth, x0, y, zoomedVals); - } - - free(zoomedVals); -} - - -/** - * Zoom/write 32-bit Z values. - * No per-fragment operations are applied. - */ -void -_swrast_write_zoomed_z_span(struct gl_context *ctx, GLint imgX, GLint imgY, - GLint width, GLint spanX, GLint spanY, - const GLuint *zVals) -{ - struct gl_renderbuffer *rb = - ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; - GLuint *zoomedVals; - GLint x0, x1, y0, y1, y; - GLint i, zoomedWidth; - - if (!compute_zoomed_bounds(ctx, imgX, imgY, spanX, spanY, width, - &x0, &x1, &y0, &y1)) { - return; /* totally clipped */ - } - - zoomedWidth = x1 - x0; - assert(zoomedWidth > 0); - assert(zoomedWidth <= SWRAST_MAX_WIDTH); - - zoomedVals = malloc(zoomedWidth * sizeof(GLuint)); - if (!zoomedVals) - return; - - /* zoom the span horizontally */ - for (i = 0; i < zoomedWidth; i++) { - GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - spanX; - assert(j >= 0); - assert(j < width); - zoomedVals[i] = zVals[j]; - } - - /* write the zoomed spans */ - for (y = y0; y < y1; y++) { - GLubyte *dst = _swrast_pixel_address(rb, x0, y); - _mesa_pack_uint_z_row(rb->Format, zoomedWidth, zoomedVals, dst); - } - - free(zoomedVals); -} diff --git a/src/mesa/swrast/s_zoom.h b/src/mesa/swrast/s_zoom.h deleted file mode 100644 index ae2f444..0000000 --- a/src/mesa/swrast/s_zoom.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -#ifndef S_ZOOM_H -#define S_ZOOM_H - -#include "main/mtypes.h" -#include "s_span.h" - - -extern void -_swrast_write_zoomed_rgba_span(struct gl_context *ctx, GLint imgX, GLint imgY, - const SWspan *span, const GLvoid *rgba); - -extern void -_swrast_write_zoomed_rgb_span(struct gl_context *ctx, GLint imgX, GLint imgY, - const SWspan *span, const GLvoid *rgb); - -extern void -_swrast_write_zoomed_depth_span(struct gl_context *ctx, GLint imgX, GLint imgY, - const SWspan *span); - - -extern void -_swrast_write_zoomed_stencil_span(struct gl_context *ctx, GLint imgX, GLint imgY, - GLint width, GLint spanX, GLint spanY, - const GLubyte stencil[]); - -extern void -_swrast_write_zoomed_z_span(struct gl_context *ctx, GLint imgX, GLint imgY, - GLint width, GLint spanX, GLint spanY, - const GLuint *zVals); - - -#endif diff --git a/src/mesa/swrast/swrast.h b/src/mesa/swrast/swrast.h deleted file mode 100644 index a89dc6c..0000000 --- a/src/mesa/swrast/swrast.h +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - * - */ - -/** - * \file swrast/swrast.h - * \brief Public interface to the software rasterization functions. - * \author Keith Whitwell - */ - -#ifndef SWRAST_H -#define SWRAST_H - -#include "main/mtypes.h" -#include "swrast/s_chan.h" - - -/** - * If non-zero use GLdouble for walking triangle edges, for better accuracy. - */ -#define TRIANGLE_WALK_DOUBLE 0 - - -/** - * Bits per depth buffer value (max is 32). - */ -#ifndef DEFAULT_SOFTWARE_DEPTH_BITS -#define DEFAULT_SOFTWARE_DEPTH_BITS 16 -#endif -/** Depth buffer data type */ -#if DEFAULT_SOFTWARE_DEPTH_BITS <= 16 -#define DEFAULT_SOFTWARE_DEPTH_TYPE GLushort -#else -#define DEFAULT_SOFTWARE_DEPTH_TYPE GLuint -#endif - - -/** - * Max image/surface/texture size. - */ -#define SWRAST_MAX_WIDTH 16384 -#define SWRAST_MAX_HEIGHT 16384 - - -/** - * \struct SWvertex - * \brief Data-structure to handle vertices in the software rasterizer. - * - * The software rasterizer now uses this format for vertices. Thus a - * 'RasterSetup' stage or other translation is required between the - * tnl module and the swrast rasterization functions. This serves to - * isolate the swrast module from the internals of the tnl module, and - * improve its usefulness as a fallback mechanism for hardware - * drivers. - * - * wpos = attr[VARYING_SLOT_POS] and MUST BE THE FIRST values in the - * vertex because of the tnl clipping code. - - * wpos[0] and [1] are the screen-coords of SWvertex. - * wpos[2] is the z-buffer coord (if 16-bit Z buffer, in range [0,65535]). - * wpos[3] is 1/w where w is the clip-space W coord. This is the value - * that clip{XYZ} were multiplied by to get ndc{XYZ}. - * - * Full software drivers: - * - Register the rastersetup and triangle functions from - * utils/software_helper. - * - On statechange, update the rasterization pointers in that module. - * - * Rasterization hardware drivers: - * - Keep native rastersetup. - * - Implement native twoside,offset and unfilled triangle setup. - * - Implement a translator from native vertices to swrast vertices. - * - On partial fallback (mix of accelerated and unaccelerated - * prims), call a pass-through function which translates native - * vertices to SWvertices and calls the appropriate swrast function. - * - On total fallback (vertex format insufficient for state or all - * primitives unaccelerated), hook in swrast_setup instead. - */ -typedef struct { - GLfloat attrib[VARYING_SLOT_MAX][4]; - GLchan color[4]; /** integer color */ - GLfloat pointSize; -} SWvertex; - - -#define VARYING_SLOT_CI VARYING_SLOT_COL0 - - -struct swrast_device_driver; - - -/* These are the public-access functions exported from swrast. - */ - -extern GLboolean -_swrast_CreateContext( struct gl_context *ctx ); - -extern void -_swrast_DestroyContext( struct gl_context *ctx ); - -/* Get a (non-const) reference to the device driver struct for swrast. - */ -extern struct swrast_device_driver * -_swrast_GetDeviceDriverReference( struct gl_context *ctx ); - -extern void -_swrast_Bitmap( struct gl_context *ctx, - GLint px, GLint py, - GLsizei width, GLsizei height, - const struct gl_pixelstore_attrib *unpack, - const GLubyte *bitmap ); - -extern void -_swrast_CopyPixels(struct gl_context *ctx, - GLint srcx, GLint srcy, - GLint destx, GLint desty, - GLsizei width, GLsizei height, - GLenum type); - -extern GLboolean -swrast_fast_copy_pixels(struct gl_context *ctx, - struct gl_framebuffer *srcFb, - struct gl_framebuffer *dstFb, - GLint srcX, GLint srcY, GLsizei width, GLsizei height, - GLint dstX, GLint dstY, GLenum type); - -extern void -_swrast_DrawPixels( struct gl_context *ctx, - GLint x, GLint y, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *unpack, - const GLvoid *pixels ); - -extern void -_swrast_BlitFramebuffer(struct gl_context *ctx, - struct gl_framebuffer *readFb, - struct gl_framebuffer *drawFb, - GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, - GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, - GLbitfield mask, GLenum filter); - -extern void -_swrast_Clear(struct gl_context *ctx, GLbitfield buffers); - - - -/* Reset the stipple counter - */ -extern void -_swrast_ResetLineStipple( struct gl_context *ctx ); - -/** - * Indicates front/back facing for subsequent points/lines when drawing - * unfilled polygons. Needed for two-side stencil. - */ -extern void -_swrast_SetFacing(struct gl_context *ctx, GLuint facing); - -/* These will always render the correct point/line/triangle for the - * current state. - * - * For flatshaded primitives, the provoking vertex is the final one. - */ -extern void -_swrast_Point( struct gl_context *ctx, const SWvertex *v ); - -extern void -_swrast_Line( struct gl_context *ctx, const SWvertex *v0, const SWvertex *v1 ); - -extern void -_swrast_Triangle( struct gl_context *ctx, const SWvertex *v0, - const SWvertex *v1, const SWvertex *v2 ); - -extern void -_swrast_Quad( struct gl_context *ctx, - const SWvertex *v0, const SWvertex *v1, - const SWvertex *v2, const SWvertex *v3); - -extern void -_swrast_flush( struct gl_context *ctx ); - -extern void -_swrast_render_primitive( struct gl_context *ctx, GLenum mode ); - -extern void -_swrast_render_start( struct gl_context *ctx ); - -extern void -_swrast_render_finish( struct gl_context *ctx ); - -extern struct gl_texture_image * -_swrast_new_texture_image( struct gl_context *ctx ); - -extern void -_swrast_delete_texture_image(struct gl_context *ctx, - struct gl_texture_image *texImage); - -extern GLboolean -_swrast_alloc_texture_image_buffer(struct gl_context *ctx, - struct gl_texture_image *texImage); - -extern GLboolean -_swrast_init_texture_image(struct gl_texture_image *texImage); - -extern void -_swrast_free_texture_image_buffer(struct gl_context *ctx, - struct gl_texture_image *texImage); - -extern void -_swrast_map_teximage(struct gl_context *ctx, - struct gl_texture_image *texImage, - GLuint slice, - GLuint x, GLuint y, GLuint w, GLuint h, - GLbitfield mode, - GLubyte **mapOut, - GLint *rowStrideOut); - -extern void -_swrast_unmap_teximage(struct gl_context *ctx, - struct gl_texture_image *texImage, - GLuint slice); - -/* Tell the software rasterizer about core state changes. - */ -extern void -_swrast_InvalidateState( struct gl_context *ctx, GLbitfield new_state ); - -/* Configure software rasterizer to match hardware rasterizer characteristics: - */ -extern void -_swrast_allow_vertex_fog( struct gl_context *ctx, GLboolean value ); - -extern void -_swrast_allow_pixel_fog( struct gl_context *ctx, GLboolean value ); - -/* Debug: - */ -extern void -_swrast_print_vertex( struct gl_context *ctx, const SWvertex *v ); - - - -extern void -_swrast_eject_texture_images(struct gl_context *ctx); - - -extern void -_swrast_render_texture(struct gl_context *ctx, - struct gl_framebuffer *fb, - struct gl_renderbuffer_attachment *att); - -extern void -_swrast_finish_render_texture(struct gl_context *ctx, - struct gl_renderbuffer *rb); - - -/** - * The driver interface for the software rasterizer. - * XXX this may go away. - * We may move these functions to ctx->Driver.RenderStart, RenderEnd. - */ -struct swrast_device_driver { - /* - * These are called before and after accessing renderbuffers during - * software rasterization. - * - * These are a suitable place for grabbing/releasing hardware locks. - * - * NOTE: The swrast triangle/line/point routines *DO NOT* call - * these functions. Locking in that case must be organized by the - * driver by other mechanisms. - */ - void (*SpanRenderStart)(struct gl_context *ctx); - void (*SpanRenderFinish)(struct gl_context *ctx); -}; - - - -#endif diff --git a/src/mesa/swrast_setup/NOTES b/src/mesa/swrast_setup/NOTES deleted file mode 100644 index bdf57c3..0000000 --- a/src/mesa/swrast_setup/NOTES +++ /dev/null @@ -1,65 +0,0 @@ -INTRODUCTION - -A helper module which provides glue to bind the software rasterizer to -the software t&l module. The main task of this module is to build -swrast vertices from the t&l vertex_buffer structs, and to use them to -perform triangle setup functions not implemented in the software -rasterizer. - -The module implements a full set of functions to plug into the -t_vb_render.c driver interface (tnl->Driver.Render.*). - -There are strong advantages to decoupling the software rasterizer from -the t&l module, primarily allowing hardware drivers better control -over fallbacks, the removal of implicit knowledge about the software -rasterizer in the t&l module, allowing the two modules to evolve -independently and allowing either to be substituted with equivalent -functionality from another codebase. - -This module implements triangle/quad setup for offset, unfilled and -twoside-lit triangles. The software rasterizer doesn't handle these -primitives directly. - -Hardware rasterization drivers typically use this module in situations -where no hardware rasterization is possible, ie during total -fallbacks. - -STATE - -To create and destroy the module: - - GLboolean _swsetup_CreateContext( struct gl_context *ctx ); - void _swsetup_DestroyContext( struct gl_context *ctx ); - -The module is not active by default, and must be installed by calling -_swrast_Wakeup(). This function installs internal swrast_setup -functions into all the tnl->Driver.Render driver hooks, thus taking -over the task of rasterization entirely: - - void _swrast_Wakeup( struct gl_context *ctx ); - - -This module tracks state changes internally and maintains derived -values based on the current state. For this to work, the driver -ensure the following funciton is called whenever the state changes and -the swsetup module is 'awake': - - void _swsetup_InvalidateState( struct gl_context *ctx, GLuint new_state ); - -There is no explicit call to put the swsetup module to sleep. Simply -install other function pointers into all the tnl->Driver.Render.* -hooks, and (optionally) cease calling _swsetup_InvalidateState(). - -DRIVER INTERFACE - -The module offers a minimal driver interface: - - void (*Start)( struct gl_context *ctx ); - void (*Finish)( struct gl_context *ctx ); - -These are called before and after the completion of all swrast drawing -activity. As swrast doesn't call callbacks during triangle, line or -point rasterization, these are necessary to provide locking hooks for -some drivers. They may otherwise be left null. - - diff --git a/src/mesa/swrast_setup/ss_context.c b/src/mesa/swrast_setup/ss_context.c deleted file mode 100644 index a435972..0000000 --- a/src/mesa/swrast_setup/ss_context.c +++ /dev/null @@ -1,305 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - * - * Authors: - * Keith Whitwell - */ - -#include "main/glheader.h" - -#include "main/macros.h" -#include "main/state.h" -#include "tnl/tnl.h" -#include "tnl/t_context.h" -#include "tnl/t_pipeline.h" -#include "tnl/t_vertex.h" -#include "swrast_setup.h" -#include "ss_context.h" -#include "ss_triangle.h" - - -/* Need to check lighting state and vertex program state to know - * if two-sided lighting is in effect. - */ -#define _SWSETUP_NEW_RENDERINDEX (_NEW_POLYGON|_NEW_LIGHT|_NEW_PROGRAM) - - -#define VARYING_EMIT_STYLE EMIT_4F - - -GLboolean -_swsetup_CreateContext( struct gl_context *ctx ) -{ - SScontext *swsetup = calloc(1, sizeof(SScontext)); - - if (!swsetup) - return GL_FALSE; - - ctx->swsetup_context = swsetup; - - swsetup->NewState = ~0; - _swsetup_trifuncs_init( ctx ); - - _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12, - sizeof(SWvertex) ); - - - return GL_TRUE; -} - -void -_swsetup_DestroyContext( struct gl_context *ctx ) -{ - SScontext *swsetup = SWSETUP_CONTEXT(ctx); - - if (swsetup) { - free(swsetup); - ctx->swsetup_context = 0; - } - - _tnl_free_vertices( ctx ); -} - -static void -_swsetup_RenderPrimitive( struct gl_context *ctx, GLenum mode ) -{ - SWSETUP_CONTEXT(ctx)->render_prim = mode; - _swrast_render_primitive( ctx, mode ); -} - - -/** - * Helper macros for setup_vertex_format() - */ -#define SWZ ((SWvertex *)0) -#define SWOffset(MEMBER) (((char *)&(SWZ->MEMBER)) - ((char *)SWZ)) - -#define EMIT_ATTR( ATTR, STYLE, MEMBER ) \ -do { \ - map[e].attrib = (ATTR); \ - map[e].format = (STYLE); \ - map[e].offset = SWOffset(MEMBER); \ - e++; \ -} while (0) - - -/** - * Tell the tnl module how to build SWvertex objects for swrast. - * We'll build the map[] array with that info and pass it to - * _tnl_install_attrs(). - */ -static void -setup_vertex_format(struct gl_context *ctx) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - SScontext *swsetup = SWSETUP_CONTEXT(ctx); - GLboolean intColors = !ctx->FragmentProgram._Current - && !_mesa_ati_fragment_shader_enabled(ctx) - && ctx->RenderMode == GL_RENDER - && CHAN_TYPE != GL_FLOAT; - - if (intColors != swsetup->intColors || - tnl->render_inputs_bitset != swsetup->last_index_bitset) { - GLbitfield64 index_bitset = tnl->render_inputs_bitset; - struct tnl_attr_map map[_TNL_ATTRIB_MAX]; - unsigned int i, e = 0; - - swsetup->intColors = intColors; - - EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, attrib[VARYING_SLOT_POS] ); - - if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_COLOR0)) { - if (swsetup->intColors) - EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4CHAN_4F_RGBA, color ); - else - EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4F, attrib[VARYING_SLOT_COL0]); - } - - if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_COLOR1)) { - EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_4F, attrib[VARYING_SLOT_COL1]); - } - - if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_FOG)) { - const GLint emit = ctx->FragmentProgram._Current ? EMIT_4F : EMIT_1F; - EMIT_ATTR( _TNL_ATTRIB_FOG, emit, attrib[VARYING_SLOT_FOGC]); - } - - if (index_bitset & BITFIELD64_RANGE(_TNL_ATTRIB_TEX0, _TNL_NUM_TEX)) - { - for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) { - if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_TEX(i))) { - EMIT_ATTR( _TNL_ATTRIB_TEX(i), EMIT_4F, - attrib[VARYING_SLOT_TEX0 + i] ); - } - } - } - - /* shader varying vars */ - if (index_bitset & BITFIELD64_RANGE(_TNL_ATTRIB_GENERIC0, _TNL_NUM_GENERIC)) { - for (i = 0; i < ctx->Const.MaxVarying; i++) { - if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_GENERIC(i))) { - EMIT_ATTR( _TNL_ATTRIB_GENERIC(i), VARYING_EMIT_STYLE, - attrib[VARYING_SLOT_VAR0 + i] ); - } - } - } - - if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_POINTSIZE)) - EMIT_ATTR( _TNL_ATTRIB_POINTSIZE, EMIT_1F, pointSize ); - - _tnl_install_attrs( ctx, map, e, - tnl->_WindowMap.m, - sizeof(SWvertex) ); - - swsetup->last_index_bitset = index_bitset; - } -} - - -/** - * Prepare to render a vertex buffer. - * Called via tnl->Driver.Render.Start. - */ -static void -_swsetup_RenderStart( struct gl_context *ctx ) -{ - SScontext *swsetup = SWSETUP_CONTEXT(ctx); - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &tnl->vb; - - if (swsetup->NewState & _SWSETUP_NEW_RENDERINDEX) { - _swsetup_choose_trifuncs(ctx); - } - - if (swsetup->NewState & _NEW_PROGRAM) { - swsetup->last_index_bitset = 0; - } - - swsetup->NewState = 0; - - /* This will change if drawing unfilled tris */ - _swrast_SetFacing(ctx, 0); - - _swrast_render_start(ctx); - - /* Important */ - VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr; - - setup_vertex_format(ctx); -} - - -/* - * We patch this function into tnl->Driver.Render.Finish. - * It's called when we finish rendering a vertex buffer. - */ -static void -_swsetup_RenderFinish( struct gl_context *ctx ) -{ - _swrast_render_finish( ctx ); -} - -void -_swsetup_InvalidateState( struct gl_context *ctx, GLuint new_state ) -{ - SScontext *swsetup = SWSETUP_CONTEXT(ctx); - swsetup->NewState |= new_state; - _tnl_invalidate_vertex_state( ctx, new_state ); -} - - -void -_swsetup_Wakeup( struct gl_context *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - SScontext *swsetup = SWSETUP_CONTEXT(ctx); - - tnl->Driver.Render.Start = _swsetup_RenderStart; - tnl->Driver.Render.Finish = _swsetup_RenderFinish; - tnl->Driver.Render.PrimitiveNotify = _swsetup_RenderPrimitive; - tnl->Driver.Render.Interp = _tnl_interp; - tnl->Driver.Render.CopyPV = _tnl_copy_pv; - tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon; /* new */ - tnl->Driver.Render.ClippedLine = _tnl_RenderClippedLine; /* new */ - /* points */ - /* line */ - /* triangle */ - /* quad */ - tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; - tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; - tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple; - tnl->Driver.Render.BuildVertices = _tnl_build_vertices; - tnl->Driver.Render.Multipass = 0; - - _tnl_invalidate_vertices( ctx, ~0 ); - _tnl_need_projected_coords( ctx, GL_TRUE ); - _swsetup_InvalidateState( ctx, ~0 ); - - swsetup->verts = (SWvertex *)tnl->clipspace.vertex_buf; - swsetup->last_index_bitset = 0; -} - - -/** - * Populate a swrast SWvertex from an attrib-style vertex. - */ -void -_swsetup_Translate( struct gl_context *ctx, const void *vertex, SWvertex *dest ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - const GLfloat *m = tnl->_WindowMap.m; - GLfloat tmp[4]; - GLuint i; - - _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_POS, tmp ); - - dest->attrib[VARYING_SLOT_POS][0] = m[0] * tmp[0] + m[12]; - dest->attrib[VARYING_SLOT_POS][1] = m[5] * tmp[1] + m[13]; - dest->attrib[VARYING_SLOT_POS][2] = m[10] * tmp[2] + m[14]; - dest->attrib[VARYING_SLOT_POS][3] = tmp[3]; - - /** XXX try to limit these loops someday */ - for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++) - _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_TEX0 + i, - dest->attrib[VARYING_SLOT_TEX0 + i] ); - - for (i = 0 ; i < ctx->Const.MaxVarying ; i++) - _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_GENERIC0 + i, - dest->attrib[VARYING_SLOT_VAR0 + i] ); - - _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_COLOR0, - dest->attrib[VARYING_SLOT_COL0] ); - - UNCLAMPED_FLOAT_TO_RGBA_CHAN(dest->color, dest->attrib[VARYING_SLOT_COL0]); - - _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_COLOR1, - dest->attrib[VARYING_SLOT_COL1]); - - _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_FOG, tmp ); - dest->attrib[VARYING_SLOT_FOGC][0] = tmp[0]; - - /* XXX See _tnl_get_attr about pointsize ... */ - _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_POINTSIZE, tmp ); - dest->pointSize = tmp[0]; -} - diff --git a/src/mesa/swrast_setup/ss_context.h b/src/mesa/swrast_setup/ss_context.h deleted file mode 100644 index 256d363..0000000 --- a/src/mesa/swrast_setup/ss_context.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - * - * Authors: - * Keith Whitwell - */ - -#ifndef SS_CONTEXT_H -#define SS_CONTEXT_H - -#include "main/glheader.h" -#include "swrast/swrast.h" -#include "tnl/t_context.h" - -typedef struct { - GLuint NewState; - GLenum render_prim; - GLbitfield64 last_index_bitset; - SWvertex *verts; - GLboolean intColors; -} SScontext; - -#define SWSETUP_CONTEXT(ctx) ((SScontext *)ctx->swsetup_context) - -#endif diff --git a/src/mesa/swrast_setup/ss_triangle.c b/src/mesa/swrast_setup/ss_triangle.c deleted file mode 100644 index d3a0e23..0000000 --- a/src/mesa/swrast_setup/ss_triangle.c +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - * - * Authors: - * Keith Whitwell - */ - -#include "c99_math.h" -#include "main/glheader.h" -#include "main/macros.h" -#include "main/mtypes.h" -#include "main/stencil.h" -#include "main/state.h" - -#include "tnl/t_context.h" - -#include "ss_triangle.h" -#include "ss_context.h" - -#define SS_OFFSET_BIT 0x1 -#define SS_TWOSIDE_BIT 0x2 -#define SS_UNFILLED_BIT 0x4 -#define SS_MAX_TRIFUNC 0x8 - -static tnl_triangle_func tri_tab[SS_MAX_TRIFUNC]; -static tnl_quad_func quad_tab[SS_MAX_TRIFUNC]; - - -/* - * Render a triangle respecting edge flags. - */ -typedef void (* swsetup_edge_render_prim_tri)(struct gl_context *ctx, - const GLubyte *ef, - GLuint e0, - GLuint e1, - GLuint e2, - const SWvertex *v0, - const SWvertex *v1, - const SWvertex *v2); - -/* - * Render a triangle using lines and respecting edge flags. - */ -static void -_swsetup_edge_render_line_tri(struct gl_context *ctx, - const GLubyte *ef, - GLuint e0, - GLuint e1, - GLuint e2, - const SWvertex *v0, - const SWvertex *v1, - const SWvertex *v2) -{ - SScontext *swsetup = SWSETUP_CONTEXT(ctx); - - if (swsetup->render_prim == GL_POLYGON) { - if (ef[e2]) _swrast_Line( ctx, v2, v0 ); - if (ef[e0]) _swrast_Line( ctx, v0, v1 ); - if (ef[e1]) _swrast_Line( ctx, v1, v2 ); - } else { - if (ef[e0]) _swrast_Line( ctx, v0, v1 ); - if (ef[e1]) _swrast_Line( ctx, v1, v2 ); - if (ef[e2]) _swrast_Line( ctx, v2, v0 ); - } -} - -/* - * Render a triangle using points and respecting edge flags. - */ -static void -_swsetup_edge_render_point_tri(struct gl_context *ctx, - const GLubyte *ef, - GLuint e0, - GLuint e1, - GLuint e2, - const SWvertex *v0, - const SWvertex *v1, - const SWvertex *v2) -{ - if (ef[e0]) _swrast_Point( ctx, v0 ); - if (ef[e1]) _swrast_Point( ctx, v1 ); - if (ef[e2]) _swrast_Point( ctx, v2 ); - - _swrast_flush(ctx); -} - -/* - * Render a triangle respecting cull and shade model. - */ -static void _swsetup_render_tri(struct gl_context *ctx, - GLuint e0, - GLuint e1, - GLuint e2, - GLuint facing, - swsetup_edge_render_prim_tri render) -{ - SScontext *swsetup = SWSETUP_CONTEXT(ctx); - struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - GLubyte *ef = VB->EdgeFlag; - SWvertex *verts = swsetup->verts; - SWvertex *v0 = &verts[e0]; - SWvertex *v1 = &verts[e1]; - SWvertex *v2 = &verts[e2]; - - /* cull testing */ - if (ctx->Polygon.CullFlag) { - if (facing == 1 && ctx->Polygon.CullFaceMode != GL_FRONT) - return; - if (facing == 0 && ctx->Polygon.CullFaceMode != GL_BACK) - return; - } - - _swrast_SetFacing(ctx, facing); - - if (ctx->Light.ShadeModel == GL_FLAT) { - GLchan c[2][4]; - GLfloat s[2][4]; - - /* save colors/indexes for v0, v1 vertices */ - COPY_CHAN4(c[0], v0->color); - COPY_CHAN4(c[1], v1->color); - COPY_4V(s[0], v0->attrib[VARYING_SLOT_COL1]); - COPY_4V(s[1], v1->attrib[VARYING_SLOT_COL1]); - - /* copy v2 color/indexes to v0, v1 indexes */ - COPY_CHAN4(v0->color, v2->color); - COPY_CHAN4(v1->color, v2->color); - COPY_4V(v0->attrib[VARYING_SLOT_COL1], v2->attrib[VARYING_SLOT_COL1]); - COPY_4V(v1->attrib[VARYING_SLOT_COL1], v2->attrib[VARYING_SLOT_COL1]); - - render(ctx, ef, e0, e1, e2, v0, v1, v2); - - COPY_CHAN4(v0->color, c[0]); - COPY_CHAN4(v1->color, c[1]); - COPY_4V(v0->attrib[VARYING_SLOT_COL1], s[0]); - COPY_4V(v1->attrib[VARYING_SLOT_COL1], s[1]); - } - else { - render(ctx, ef, e0, e1, e2, v0, v1, v2); - } -} - -#define SS_COLOR(a,b) UNCLAMPED_FLOAT_TO_RGBA_CHAN(a,b) -#define SS_SPEC(a,b) COPY_4V(a,b) -#define SS_IND(a,b) (a = b) - -#define IND (0) -#define TAG(x) x##_rgba -#include "ss_tritmp.h" - -#define IND (SS_OFFSET_BIT) -#define TAG(x) x##_offset_rgba -#include "ss_tritmp.h" - -#define IND (SS_TWOSIDE_BIT) -#define TAG(x) x##_twoside_rgba -#include "ss_tritmp.h" - -#define IND (SS_OFFSET_BIT|SS_TWOSIDE_BIT) -#define TAG(x) x##_offset_twoside_rgba -#include "ss_tritmp.h" - -#define IND (SS_UNFILLED_BIT) -#define TAG(x) x##_unfilled_rgba -#include "ss_tritmp.h" - -#define IND (SS_OFFSET_BIT|SS_UNFILLED_BIT) -#define TAG(x) x##_offset_unfilled_rgba -#include "ss_tritmp.h" - -#define IND (SS_TWOSIDE_BIT|SS_UNFILLED_BIT) -#define TAG(x) x##_twoside_unfilled_rgba -#include "ss_tritmp.h" - -#define IND (SS_OFFSET_BIT|SS_TWOSIDE_BIT|SS_UNFILLED_BIT) -#define TAG(x) x##_offset_twoside_unfilled_rgba -#include "ss_tritmp.h" - - -void _swsetup_trifuncs_init( struct gl_context *ctx ) -{ - (void) ctx; - - init_rgba(); - init_offset_rgba(); - init_twoside_rgba(); - init_offset_twoside_rgba(); - init_unfilled_rgba(); - init_offset_unfilled_rgba(); - init_twoside_unfilled_rgba(); - init_offset_twoside_unfilled_rgba(); -} - - -static void swsetup_points( struct gl_context *ctx, GLuint first, GLuint last ) -{ - struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - SWvertex *verts = SWSETUP_CONTEXT(ctx)->verts; - GLuint i; - - if (VB->Elts) { - for (i = first; i < last; i++) - if (VB->ClipMask[VB->Elts[i]] == 0) - _swrast_Point( ctx, &verts[VB->Elts[i]] ); - } - else { - for (i = first; i < last; i++) - if (VB->ClipMask[i] == 0) - _swrast_Point( ctx, &verts[i] ); - } -} - -static void swsetup_line( struct gl_context *ctx, GLuint v0, GLuint v1 ) -{ - SWvertex *verts = SWSETUP_CONTEXT(ctx)->verts; - _swrast_Line( ctx, &verts[v0], &verts[v1] ); -} - - - -void _swsetup_choose_trifuncs( struct gl_context *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLuint ind = 0; - - if (ctx->Polygon.OffsetPoint || - ctx->Polygon.OffsetLine || - ctx->Polygon.OffsetFill) - ind |= SS_OFFSET_BIT; - - if ((ctx->Light.Enabled && ctx->Light.Model.TwoSide) || - (ctx->VertexProgram._Current && ctx->VertexProgram.TwoSideEnabled)) - ind |= SS_TWOSIDE_BIT; - - /* We piggyback the two-sided stencil front/back determination on the - * unfilled triangle path. - */ - if (ctx->Polygon.FrontMode != GL_FILL || - ctx->Polygon.BackMode != GL_FILL || - (ctx->Stencil.Enabled && _mesa_stencil_is_two_sided(ctx))) - ind |= SS_UNFILLED_BIT; - - tnl->Driver.Render.Triangle = tri_tab[ind]; - tnl->Driver.Render.Quad = quad_tab[ind]; - tnl->Driver.Render.Line = swsetup_line; - tnl->Driver.Render.Points = swsetup_points; -} diff --git a/src/mesa/swrast_setup/ss_triangle.h b/src/mesa/swrast_setup/ss_triangle.h deleted file mode 100644 index 8a9f7ee..0000000 --- a/src/mesa/swrast_setup/ss_triangle.h +++ /dev/null @@ -1,38 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - * - * Authors: - * Keith Whitwell - */ - -#ifndef SS_TRIANGLE_H -#define SS_TRIANGLE_H - -struct gl_context; - - -void _swsetup_trifuncs_init( struct gl_context *ctx ); -void _swsetup_choose_trifuncs( struct gl_context *ctx ); - -#endif diff --git a/src/mesa/swrast_setup/ss_tritmp.h b/src/mesa/swrast_setup/ss_tritmp.h deleted file mode 100644 index c887472..0000000 --- a/src/mesa/swrast_setup/ss_tritmp.h +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - * - * Authors: - * Keith Whitwell - */ - - -/** - * This is where we handle assigning vertex colors based on front/back - * facing, compute polygon offset and handle glPolygonMode(). - */ -static void TAG(triangle)(struct gl_context *ctx, GLuint e0, GLuint e1, GLuint e2 ) -{ - struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - SScontext *swsetup = SWSETUP_CONTEXT(ctx); - SWvertex *verts = SWSETUP_CONTEXT(ctx)->verts; - SWvertex *v[3]; - GLfloat z[3]; - GLfloat offset, oz0, oz1, oz2; - GLenum mode = GL_FILL; - GLuint facing = 0; - GLchan saved_color[3][4] = { { 0 } }; - GLfloat saved_col0[3][4] = { { 0 } }; - GLfloat saved_spec[3][4] = { { 0 } }; - - v[0] = &verts[e0]; - v[1] = &verts[e1]; - v[2] = &verts[e2]; - - if (IND & (SS_TWOSIDE_BIT | SS_OFFSET_BIT | SS_UNFILLED_BIT)) - { - GLfloat ex = v[0]->attrib[VARYING_SLOT_POS][0] - v[2]->attrib[VARYING_SLOT_POS][0]; - GLfloat ey = v[0]->attrib[VARYING_SLOT_POS][1] - v[2]->attrib[VARYING_SLOT_POS][1]; - GLfloat fx = v[1]->attrib[VARYING_SLOT_POS][0] - v[2]->attrib[VARYING_SLOT_POS][0]; - GLfloat fy = v[1]->attrib[VARYING_SLOT_POS][1] - v[2]->attrib[VARYING_SLOT_POS][1]; - GLfloat cc = ex*fy - ey*fx; - - if (IND & (SS_TWOSIDE_BIT | SS_UNFILLED_BIT)) - { - facing = (cc < 0.0F) ^ _mesa_polygon_get_front_bit(ctx); - - if (IND & SS_UNFILLED_BIT) - mode = facing ? ctx->Polygon.BackMode : ctx->Polygon.FrontMode; - - if (facing == 1) { - if (IND & SS_TWOSIDE_BIT) { - if (VB->BackfaceColorPtr) { - GLfloat (*vbcolor)[4] = VB->BackfaceColorPtr->data; - - if (swsetup->intColors) { - COPY_CHAN4(saved_color[0], v[0]->color); - COPY_CHAN4(saved_color[1], v[1]->color); - COPY_CHAN4(saved_color[2], v[2]->color); - } - else { - COPY_4V(saved_col0[0], v[0]->attrib[VARYING_SLOT_COL0]); - COPY_4V(saved_col0[1], v[1]->attrib[VARYING_SLOT_COL0]); - COPY_4V(saved_col0[2], v[2]->attrib[VARYING_SLOT_COL0]); - } - - if (VB->BackfaceColorPtr->stride) { - if (swsetup->intColors) { - SS_COLOR(v[0]->color, vbcolor[e0]); - SS_COLOR(v[1]->color, vbcolor[e1]); - SS_COLOR(v[2]->color, vbcolor[e2]); - } - else { - COPY_4V(v[0]->attrib[VARYING_SLOT_COL0], vbcolor[e0]); - COPY_4V(v[1]->attrib[VARYING_SLOT_COL0], vbcolor[e1]); - COPY_4V(v[2]->attrib[VARYING_SLOT_COL0], vbcolor[e2]); - } - } - else { - /* flat shade */ - if (swsetup->intColors) { - SS_COLOR(v[0]->color, vbcolor[0]); - SS_COLOR(v[1]->color, vbcolor[0]); - SS_COLOR(v[2]->color, vbcolor[0]); - } - else { - COPY_4V(v[0]->attrib[VARYING_SLOT_COL0], vbcolor[0]); - COPY_4V(v[1]->attrib[VARYING_SLOT_COL0], vbcolor[0]); - COPY_4V(v[2]->attrib[VARYING_SLOT_COL0], vbcolor[0]); - } - } - } - - if (VB->BackfaceSecondaryColorPtr) { - GLfloat (*vbspec)[4] = VB->BackfaceSecondaryColorPtr->data; - - COPY_4V(saved_spec[0], v[0]->attrib[VARYING_SLOT_COL1]); - COPY_4V(saved_spec[1], v[1]->attrib[VARYING_SLOT_COL1]); - COPY_4V(saved_spec[2], v[2]->attrib[VARYING_SLOT_COL1]); - - if (VB->BackfaceSecondaryColorPtr->stride) { - SS_SPEC(v[0]->attrib[VARYING_SLOT_COL1], vbspec[e0]); - SS_SPEC(v[1]->attrib[VARYING_SLOT_COL1], vbspec[e1]); - SS_SPEC(v[2]->attrib[VARYING_SLOT_COL1], vbspec[e2]); - } - else { - SS_SPEC(v[0]->attrib[VARYING_SLOT_COL1], vbspec[0]); - SS_SPEC(v[1]->attrib[VARYING_SLOT_COL1], vbspec[0]); - SS_SPEC(v[2]->attrib[VARYING_SLOT_COL1], vbspec[0]); - } - } - } - } - } - - if (IND & SS_OFFSET_BIT) { - const GLfloat max = ctx->DrawBuffer->_DepthMaxF; - /* save original Z values (restored later) */ - z[0] = v[0]->attrib[VARYING_SLOT_POS][2]; - z[1] = v[1]->attrib[VARYING_SLOT_POS][2]; - z[2] = v[2]->attrib[VARYING_SLOT_POS][2]; - /* Note that Z values are already scaled to [0,65535] (for example) - * so no MRD value is used here. - */ - offset = ctx->Polygon.OffsetUnits; - if (cc * cc > 1e-16F) { - const GLfloat ez = z[0] - z[2]; - const GLfloat fz = z[1] - z[2]; - const GLfloat oneOverArea = 1.0F / cc; - const GLfloat dzdx = fabsf((ey * fz - ez * fy) * oneOverArea); - const GLfloat dzdy = fabsf((ez * fx - ex * fz) * oneOverArea); - offset += MAX2(dzdx, dzdy) * ctx->Polygon.OffsetFactor; - } - /* new Z values */ - oz0 = CLAMP(v[0]->attrib[VARYING_SLOT_POS][2] + offset, 0.0F, max); - oz1 = CLAMP(v[1]->attrib[VARYING_SLOT_POS][2] + offset, 0.0F, max); - oz2 = CLAMP(v[2]->attrib[VARYING_SLOT_POS][2] + offset, 0.0F, max); - } - } - - if (mode == GL_POINT) { - if ((IND & SS_OFFSET_BIT) && ctx->Polygon.OffsetPoint) { - v[0]->attrib[VARYING_SLOT_POS][2] = oz0; - v[1]->attrib[VARYING_SLOT_POS][2] = oz1; - v[2]->attrib[VARYING_SLOT_POS][2] = oz2; - } - _swsetup_render_tri(ctx, e0, e1, e2, facing, _swsetup_edge_render_point_tri); - } else if (mode == GL_LINE) { - if ((IND & SS_OFFSET_BIT) && ctx->Polygon.OffsetLine) { - v[0]->attrib[VARYING_SLOT_POS][2] = oz0; - v[1]->attrib[VARYING_SLOT_POS][2] = oz1; - v[2]->attrib[VARYING_SLOT_POS][2] = oz2; - } - _swsetup_render_tri(ctx, e0, e1, e2, facing, _swsetup_edge_render_line_tri); - } else { - if ((IND & SS_OFFSET_BIT) && ctx->Polygon.OffsetFill) { - v[0]->attrib[VARYING_SLOT_POS][2] = oz0; - v[1]->attrib[VARYING_SLOT_POS][2] = oz1; - v[2]->attrib[VARYING_SLOT_POS][2] = oz2; - } - _swrast_Triangle( ctx, v[0], v[1], v[2] ); - } - - /* - * Restore original vertex colors, etc. - */ - if (IND & SS_OFFSET_BIT) { - v[0]->attrib[VARYING_SLOT_POS][2] = z[0]; - v[1]->attrib[VARYING_SLOT_POS][2] = z[1]; - v[2]->attrib[VARYING_SLOT_POS][2] = z[2]; - } - - if (IND & SS_TWOSIDE_BIT) { - if (facing == 1) { - if (VB->BackfaceColorPtr) { - if (swsetup->intColors) { - COPY_CHAN4(v[0]->color, saved_color[0]); - COPY_CHAN4(v[1]->color, saved_color[1]); - COPY_CHAN4(v[2]->color, saved_color[2]); - } - else { - COPY_4V(v[0]->attrib[VARYING_SLOT_COL0], saved_col0[0]); - COPY_4V(v[1]->attrib[VARYING_SLOT_COL0], saved_col0[1]); - COPY_4V(v[2]->attrib[VARYING_SLOT_COL0], saved_col0[2]); - } - } - - if (VB->BackfaceSecondaryColorPtr) { - COPY_4V(v[0]->attrib[VARYING_SLOT_COL1], saved_spec[0]); - COPY_4V(v[1]->attrib[VARYING_SLOT_COL1], saved_spec[1]); - COPY_4V(v[2]->attrib[VARYING_SLOT_COL1], saved_spec[2]); - } - } - } -} - - - -/* Need to fixup edgeflags when decomposing to triangles: - */ -static void TAG(quadfunc)( struct gl_context *ctx, GLuint v0, - GLuint v1, GLuint v2, GLuint v3 ) -{ - if (IND & SS_UNFILLED_BIT) { - struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - if (VB->EdgeFlag) { /* XXX this test shouldn't be needed (bug 12614) */ - GLubyte ef1 = VB->EdgeFlag[v1]; - GLubyte ef3 = VB->EdgeFlag[v3]; - VB->EdgeFlag[v1] = 0; - TAG(triangle)( ctx, v0, v1, v3 ); - VB->EdgeFlag[v1] = ef1; - VB->EdgeFlag[v3] = 0; - TAG(triangle)( ctx, v1, v2, v3 ); - VB->EdgeFlag[v3] = ef3; - } - } else { - TAG(triangle)( ctx, v0, v1, v3 ); - TAG(triangle)( ctx, v1, v2, v3 ); - } -} - - - - -static void TAG(init)( void ) -{ - tri_tab[IND] = TAG(triangle); - quad_tab[IND] = TAG(quadfunc); -} - - -#undef IND -#undef TAG diff --git a/src/mesa/swrast_setup/ss_vb.h b/src/mesa/swrast_setup/ss_vb.h deleted file mode 100644 index 05aa32c..0000000 --- a/src/mesa/swrast_setup/ss_vb.h +++ /dev/null @@ -1,37 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - * - * Authors: - * Keith Whitwell - */ - -#ifndef SS_VB_H -#define SS_VB_H - -struct gl_context; - -void _swsetup_vb_init( struct gl_context *ctx ); -void _swsetup_choose_rastersetup_func( struct gl_context *ctx ); - -#endif diff --git a/src/mesa/swrast_setup/swrast_setup.h b/src/mesa/swrast_setup/swrast_setup.h deleted file mode 100644 index 537c45c..0000000 --- a/src/mesa/swrast_setup/swrast_setup.h +++ /dev/null @@ -1,61 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - * - * Authors: - * Keith Whitwell - */ - -/* Public interface to the swrast_setup module. This module provides - * an implementation of the driver interface to t_vb_render.c, and uses - * the software rasterizer (swrast) to perform actual rasterization. - * - * The internals of the implementation are private, but can be hooked - * into tnl at any time (except between RenderStart/RenderEnd) by - * calling _swsetup_Wakeup(). - */ - -#ifndef SWRAST_SETUP_H -#define SWRAST_SETUP_H - -#include "swrast/swrast.h" - -extern GLboolean -_swsetup_CreateContext( struct gl_context *ctx ); - -extern void -_swsetup_DestroyContext( struct gl_context *ctx ); - -extern void -_swsetup_InvalidateState( struct gl_context *ctx, GLuint new_state ); - -extern void -_swsetup_Wakeup( struct gl_context *ctx ); - -/* Helper function to translate a hardware vertex (as understood by - * the tnl/t_vertex.c code) to a swrast vertex. - */ -extern void -_swsetup_Translate( struct gl_context *ctx, const void *vertex, SWvertex *dest ); - -#endif diff --git a/src/mesa/tnl/NOTES b/src/mesa/tnl/NOTES deleted file mode 100644 index 43c4692..0000000 --- a/src/mesa/tnl/NOTES +++ /dev/null @@ -1,100 +0,0 @@ -INTRODUCTION - -A generic, configurable software implementation of GL transformation & -lighting. - -This module provides an implementation of the routines required by the -'vtxfmt' mechanism of core mesa for tnl functionality in all -combinations of compile and execute modes. - -Most current drivers use the tnl module exclusively to provide this -functionality. - - -STATE - -To create and destroy the module: - - GLboolean _tnl_CreateContext( struct gl_context *ctx ); - void _tnl_DestroyContext( struct gl_context *ctx ); - -The module is not active by default, and must be installed by calling -_tnl_Wakeup(). This function installs internal tnl functions into all -the vtxfmt dispatch hooks, thus taking over the task of transformation -and lighting entirely: - - void _tnl_wakeup_exec( struct gl_context *ctx ); - void _tnl_wakeup_save_exec( struct gl_context *ctx ); - - -This module tracks state changes internally and maintains derived -values based on the current state. For this to work, the driver -ensure the following funciton is called whenever the state changes and -the swsetup module is 'awake': - - void _tnl_InvalidateState( struct gl_context *ctx, GLuint new_state ); - -There is no explicit call to put the tnl module to sleep. Simply -install other function pointers into all the vtxfmt dispatch slots, -and (optionally) cease calling _tnl_InvalidateState(). - -CUSTOMIZATION - -The module provides customizability through several mechanisms. The -most important is by allowing drivers to specify the pipeline through -which vertex data is passed, including its eventual transfer to -rasterization hardware (or software). - -The default pipeline is specified in t_pipeline.c, and is usually a -starting point for driver pipelines. Some drivers will remove a stage -where hardware provides support for the implemented operation (for -instance fog where per-pixel hardware fog is available), -or add stages to shortcircuit latter operations (for -example taking advantage of hardware support for strips and other -higher-level primitives (for example the radeon driver). - -In addition, the following functions provide further tweaks: - -extern void -_tnl_need_projected_coords( struct gl_context *ctx, GLboolean flag ); - - - Direct the default vertex transformation stage to - produce/not produce projected clip coordinates. - -extern void -_tnl_need_dlist_loopback( struct gl_context *ctx, GLboolean flag ); - - - Direct the display list component of the tnl module to - replay display lists as 'glVertex' type calls, rather than - passing the display list data directly into the tnl pipeline - mechanism. - - This allows display lists to be replayed by the tnl module - even when the module is not strictly active. - - -extern void -_tnl_need_dlist_norm_lengths( struct gl_context *ctx, GLboolean flag ); - - - Direct the display list component to enable/disable caching - 1/length values for display list normals. Doing so is - ususally helpful when lighting is performed in software, but - wasteful otherwise. - - -DRIVER INTERFACE - -The module itself offers a minimal driver interface: - - void (*RunPipeline)( struct gl_context *ctx ); - -Normally this is set to _tnl_RunPipeline(), however the driver can use -this hook to wrap checks or other code around this call. - -In addition, the driver interface for the default render pipeline -stage is housed in the tnl context struct (this could be cleaner). - - -RENDER DRIVER INTERFACE - -See t_context.h for the definition and explanation of this. \ No newline at end of file diff --git a/src/mesa/tnl/t_context.c b/src/mesa/tnl/t_context.c deleted file mode 100644 index 0c5ce82..0000000 --- a/src/mesa/tnl/t_context.c +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - * - * Authors: - * Keith Whitwell - */ - - -#include "main/glheader.h" - -#include "main/context.h" -#include "main/macros.h" -#include "main/mtypes.h" -#include "main/light.h" -#include "math/m_translate.h" -#include "math/m_xform.h" -#include "main/state.h" -#include "main/viewport.h" -#include "util/simple_list.h" -#include "util/u_memory.h" - -#include "tnl.h" -#include "t_context.h" -#include "t_pipeline.h" - -#include "vbo/vbo.h" - -GLboolean -_tnl_CreateContext( struct gl_context *ctx ) -{ - TNLcontext *tnl; - GLuint i; - - /* Create the TNLcontext structure - */ - ctx->swtnl_context = tnl = calloc(1, sizeof(TNLcontext)); - - if (!tnl) { - return GL_FALSE; - } - - /* Initialize the VB. - */ - tnl->vb.Size = ctx->Const.MaxArrayLockSize + MAX_CLIPPED_VERTICES; - - - /* Initialize tnl state. - */ - if (ctx->VertexProgram._MaintainTnlProgram) { - _tnl_install_pipeline( ctx, _tnl_vp_pipeline ); - } else { - _tnl_install_pipeline( ctx, _tnl_default_pipeline ); - } - - _math_matrix_ctr(&tnl->_WindowMap); - - tnl->NeedNdcCoords = GL_TRUE; - tnl->AllowVertexFog = GL_TRUE; - tnl->AllowPixelFog = GL_TRUE; - - /* Set a few default values in the driver struct. - */ - tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; - tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; - tnl->Driver.NotifyMaterialChange = _tnl_validate_shine_tables; - - tnl->nr_blocks = 0; - - /* Lighting miscellaneous */ - tnl->_ShineTabList = MALLOC_STRUCT( tnl_shine_tab ); - make_empty_list( tnl->_ShineTabList ); - /* Allocate 10 (arbitrary) shininess lookup tables */ - for (i = 0 ; i < 10 ; i++) { - struct tnl_shine_tab *s = MALLOC_STRUCT( tnl_shine_tab ); - s->shininess = -1; - s->refcount = 0; - insert_at_tail( tnl->_ShineTabList, s ); - } - - _math_init_transformation(); - _math_init_translate(); - - /* Keep our list of tnl_vertex_array inputs */ - _tnl_init_inputs(&tnl->draw_arrays); - - return GL_TRUE; -} - - -void -_tnl_DestroyContext( struct gl_context *ctx ) -{ - struct tnl_shine_tab *s, *tmps; - TNLcontext *tnl = TNL_CONTEXT(ctx); - - /* Free lighting shininess exponentiation table */ - foreach_s( s, tmps, tnl->_ShineTabList ) { - free( s ); - } - free( tnl->_ShineTabList ); - - _tnl_destroy_pipeline( ctx ); - - free(tnl); - ctx->swtnl_context = NULL; -} - - -void -_tnl_InvalidateState( struct gl_context *ctx, GLuint new_state ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - const struct gl_program *vp = ctx->VertexProgram._Current; - const struct gl_program *fp = ctx->FragmentProgram._Current; - GLuint i; - - if (new_state & (_NEW_LIGHT_CONSTANTS | _NEW_MATERIAL)) - _mesa_update_light_materials(ctx); - - if (new_state & (_NEW_HINT | _NEW_PROGRAM)) { - assert(tnl->AllowVertexFog || tnl->AllowPixelFog); - tnl->_DoVertexFog = ((tnl->AllowVertexFog && (ctx->Hint.Fog != GL_NICEST)) - || !tnl->AllowPixelFog) && !fp; - } - - tnl->pipeline.new_state |= new_state; - - /* Calculate tnl->render_inputs. This bitmask indicates which vertex - * attributes need to be emitted to the rasterizer. - */ - tnl->render_inputs_bitset = BITFIELD64_BIT(_TNL_ATTRIB_POS); - - if (!fp || (fp->info.inputs_read & VARYING_BIT_COL0)) { - tnl->render_inputs_bitset |= BITFIELD64_BIT(_TNL_ATTRIB_COLOR0); - } - - if (_mesa_need_secondary_color(ctx)) - tnl->render_inputs_bitset |= BITFIELD64_BIT(_TNL_ATTRIB_COLOR1); - - for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { - if (ctx->Texture._EnabledCoordUnits & (1 << i) || - (fp && fp->info.inputs_read & VARYING_BIT_TEX(i)) || - _mesa_ati_fragment_shader_enabled(ctx)) { - tnl->render_inputs_bitset |= BITFIELD64_BIT(_TNL_ATTRIB_TEX(i)); - } - } - - if (ctx->Fog.Enabled - || (fp != NULL && (fp->info.inputs_read & VARYING_BIT_FOGC) != 0)) { - /* Either fixed-function fog or a fragment program needs fog coord. - */ - tnl->render_inputs_bitset |= BITFIELD64_BIT(_TNL_ATTRIB_FOG); - } - - if (ctx->Polygon.FrontMode != GL_FILL || - ctx->Polygon.BackMode != GL_FILL) - tnl->render_inputs_bitset |= BITFIELD64_BIT(_TNL_ATTRIB_EDGEFLAG); - - if (ctx->RenderMode == GL_FEEDBACK) - tnl->render_inputs_bitset |= BITFIELD64_BIT(_TNL_ATTRIB_TEX0); - - if (ctx->Point._Attenuated || ctx->VertexProgram.PointSizeEnabled) - tnl->render_inputs_bitset |= BITFIELD64_BIT(_TNL_ATTRIB_POINTSIZE); - - /* check for varying vars which are written by the vertex program */ - if (vp) { - GLuint i; - for (i = 0; i < MAX_VARYING; i++) { - if (vp->info.outputs_written & - BITFIELD64_BIT(VARYING_SLOT_VAR0 + i)) { - tnl->render_inputs_bitset |= BITFIELD64_BIT(_TNL_ATTRIB_GENERIC(i)); - } - } - } - - if (new_state & (_NEW_VIEWPORT | _NEW_BUFFERS)) { - float scale[3], translate[3]; - _mesa_get_viewport_xform(ctx, 0, scale, translate); - _math_matrix_viewport(&tnl->_WindowMap, scale, translate, - ctx->DrawBuffer->_DepthMaxF); - } -} - - -void -_tnl_wakeup( struct gl_context *ctx ) -{ - /* Assume we haven't been getting state updates either: - */ - _tnl_InvalidateState( ctx, ~0 ); - -#if 0 - if (ctx->Light.ColorMaterialEnabled) { - _mesa_update_color_material( ctx, - ctx->Current.Attrib[VERT_ATTRIB_COLOR0] ); - } -#endif -} - - - - -/** - * Drivers call this function to tell the TCL module whether or not - * it wants Normalized Device Coords (NDC) computed. I.e. whether - * we should "Divide-by-W". Software renders will want that. - */ -void -_tnl_need_projected_coords( struct gl_context *ctx, GLboolean mode ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - tnl->NeedNdcCoords = mode; -} - -void -_tnl_allow_vertex_fog( struct gl_context *ctx, GLboolean value ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - tnl->AllowVertexFog = value; - tnl->_DoVertexFog = ((tnl->AllowVertexFog && (ctx->Hint.Fog != GL_NICEST)) - || !tnl->AllowPixelFog) && !ctx->FragmentProgram._Current; - -} - -void -_tnl_allow_pixel_fog( struct gl_context *ctx, GLboolean value ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - tnl->AllowPixelFog = value; - tnl->_DoVertexFog = ((tnl->AllowVertexFog && (ctx->Hint.Fog != GL_NICEST)) - || !tnl->AllowPixelFog) && !ctx->FragmentProgram._Current; -} - diff --git a/src/mesa/tnl/t_context.h b/src/mesa/tnl/t_context.h deleted file mode 100644 index e675639..0000000 --- a/src/mesa/tnl/t_context.h +++ /dev/null @@ -1,594 +0,0 @@ -/* - * mesa 3-D graphics library - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -/** - * \file t_context.h - * \brief TnL module datatypes and definitions. - * \author Keith Whitwell - */ - - -/** - * \mainpage The TNL-module - * - * TNL stands for "transform and lighting", i.e. this module implements - * a pipeline that receives as input a buffer of vertices and does all - * necessary transformations (rotations, clipping, vertex shader etc.) - * and passes then the output to the rasterizer. - * - * The tnl_pipeline contains the array of all stages, which should be - * applied. Each stage is a black-box, which is described by an - * tnl_pipeline_stage. The function ::_tnl_run_pipeline applies all the - * stages to the vertex_buffer TNLcontext::vb, where the vertex data - * is stored. The last stage in the pipeline is the rasterizer. - * - */ - - -#ifndef _T_CONTEXT_H -#define _T_CONTEXT_H - -#include "main/glheader.h" - -#include "main/mtypes.h" - -#include "math/m_vector.h" - -#include "vbo/vbo.h" - -#include "tnl.h" - -#define MAX_PIPELINE_STAGES 30 - -/* - * Note: The first attributes match the VERT_ATTRIB_* definitions - * in mtypes.h. However, the tnl module has additional attributes - * for materials, color indexes, edge flags, etc. - */ -/* Although it's nice to use these as bit indexes in a DWORD flag, we - * could manage without if necessary. Another limit currently is the - * number of bits allocated for these numbers in places like vertex - * program instruction formats and register layouts. - */ -/* The bit space exhaustion is a fact now, done by _TNL_ATTRIB_ATTRIBUTE* for - * GLSL vertex shader which cannot be aliased with conventional vertex attribs. - * Compacting _TNL_ATTRIB_MAT_* attribs would not work, they would not give - * as many free bits (11 plus already 1 free bit) as _TNL_ATTRIB_ATTRIBUTE* - * attribs want (16). - */ -enum { - _TNL_ATTRIB_POS, - _TNL_ATTRIB_NORMAL, - _TNL_ATTRIB_COLOR0, - _TNL_ATTRIB_COLOR1, - _TNL_ATTRIB_FOG, - _TNL_ATTRIB_COLOR_INDEX, - _TNL_ATTRIB_TEX0, - _TNL_ATTRIB_TEX1, - _TNL_ATTRIB_TEX2, - _TNL_ATTRIB_TEX3, - _TNL_ATTRIB_TEX4, - _TNL_ATTRIB_TEX5, - _TNL_ATTRIB_TEX6, - _TNL_ATTRIB_TEX7, - - /* This is really a VARYING_SLOT, not an attrib. Need to fix - * tnl to understand the difference. - */ - _TNL_ATTRIB_POINTSIZE, - - _TNL_ATTRIB_GENERIC0, /* doesn't really exist! */ - _TNL_ATTRIB_GENERIC1, - _TNL_ATTRIB_GENERIC2, - _TNL_ATTRIB_GENERIC3, - _TNL_ATTRIB_GENERIC4, - _TNL_ATTRIB_GENERIC5, - _TNL_ATTRIB_GENERIC6, - _TNL_ATTRIB_GENERIC7, - _TNL_ATTRIB_GENERIC8, - _TNL_ATTRIB_GENERIC9, - _TNL_ATTRIB_GENERIC10, - _TNL_ATTRIB_GENERIC11, - _TNL_ATTRIB_GENERIC12, - _TNL_ATTRIB_GENERIC13, - _TNL_ATTRIB_GENERIC14, - _TNL_ATTRIB_GENERIC15, - _TNL_ATTRIB_EDGEFLAG, - - _TNL_ATTRIB_MAX, - - /* These alias with the generics, but they are not active - * concurrently, so it's not a problem. The TNL module - * doesn't have to do anything about this as this is how they - * are passed into the _draw_prims callback. - * - * When we generate fixed-function replacement programs (in - * t_vp_build.c currently), they refer to the appropriate - * generic attribute in order to pick up per-vertex material - * data. - */ - _TNL_ATTRIB_MAT_FRONT_AMBIENT=VERT_ATTRIB_MAT(MAT_ATTRIB_FRONT_AMBIENT), - _TNL_ATTRIB_MAT_BACK_AMBIENT, - _TNL_ATTRIB_MAT_FRONT_DIFFUSE, - _TNL_ATTRIB_MAT_BACK_DIFFUSE, - _TNL_ATTRIB_MAT_FRONT_SPECULAR, - _TNL_ATTRIB_MAT_BACK_SPECULAR, - _TNL_ATTRIB_MAT_FRONT_EMISSION, - _TNL_ATTRIB_MAT_BACK_EMISSION, - _TNL_ATTRIB_MAT_FRONT_SHININESS, - _TNL_ATTRIB_MAT_BACK_SHININESS, - _TNL_ATTRIB_MAT_FRONT_INDEXES, - _TNL_ATTRIB_MAT_BACK_INDEXES, -}; - -#define _TNL_ATTRIB_TEX(u) (_TNL_ATTRIB_TEX0 + (u)) -#define _TNL_ATTRIB_GENERIC(n) (_TNL_ATTRIB_GENERIC0 + (n)) - -/* special index used for handing invalid glVertexAttribute() indices */ -#define _TNL_ATTRIB_ERROR (_TNL_ATTRIB_GENERIC15 + 1) - -/** - * Handy attribute ranges: - */ -#define _TNL_FIRST_PROG _TNL_ATTRIB_NORMAL -#define _TNL_LAST_PROG _TNL_ATTRIB_TEX7 - -#define _TNL_FIRST_TEX _TNL_ATTRIB_TEX0 -#define _TNL_LAST_TEX _TNL_ATTRIB_TEX7 - -#define _TNL_FIRST_GENERIC _TNL_ATTRIB_GENERIC0 -#define _TNL_LAST_GENERIC _TNL_ATTRIB_GENERIC15 - -#define _TNL_FIRST_MAT _TNL_ATTRIB_MAT_FRONT_AMBIENT /* GENERIC4 */ -#define _TNL_LAST_MAT _TNL_ATTRIB_MAT_BACK_INDEXES /* GENERIC15 */ - -/* Number of available texture attributes */ -#define _TNL_NUM_TEX 8 - -/* Number of available generic attributes */ -#define _TNL_NUM_GENERIC 16 - -/* Number of attributes used for evaluators */ -#define _TNL_NUM_EVAL 16 - - -#define PRIM_BEGIN 0x10 -#define PRIM_END 0x20 -#define PRIM_MODE_MASK 0x0f - -static inline GLuint _tnl_translate_prim( const struct _mesa_prim *prim ) -{ - GLuint flag; - flag = prim->mode; - if (prim->begin) flag |= PRIM_BEGIN; - if (prim->end) flag |= PRIM_END; - return flag; -} - - - - -/** - * Contains the current state of a running pipeline. - */ -struct vertex_buffer -{ - GLuint Size; /**< Max vertices per vertex buffer, constant */ - - /* Constant over the pipeline. - */ - GLuint Count; /**< Number of vertices currently in buffer */ - - /* Pointers to current data. Most of the data is in AttribPtr -- all of - * it that is one of VERT_ATTRIB_X. For things only produced by TNL, - * such as backface color or eye-space coordinates, they are stored - * here. - */ - GLuint *Elts; - GLvector4f *EyePtr; /* _TNL_BIT_POS */ - GLvector4f *ClipPtr; /* _TNL_BIT_POS */ - GLvector4f *NdcPtr; /* _TNL_BIT_POS */ - GLubyte ClipOrMask; /* _TNL_BIT_POS */ - GLubyte ClipAndMask; /* _TNL_BIT_POS */ - GLubyte *ClipMask; /* _TNL_BIT_POS */ - GLfloat *NormalLengthPtr; /* _TNL_BIT_NORMAL */ - GLboolean *EdgeFlag; /* _TNL_BIT_EDGEFLAG */ - GLvector4f *BackfaceIndexPtr; - GLvector4f *BackfaceColorPtr; - GLvector4f *BackfaceSecondaryColorPtr; - - const struct _mesa_prim *Primitive; - GLuint PrimitiveCount; - - /* Inputs to the vertex program stage */ - GLvector4f *AttribPtr[_TNL_ATTRIB_MAX]; -}; - - -/** - * Describes an individual operation on the pipeline. - */ -struct tnl_pipeline_stage -{ - const char *name; - - /* Private data for the pipeline stage: - */ - void *privatePtr; - - /* Allocate private data - */ - GLboolean (*create)( struct gl_context *ctx, struct tnl_pipeline_stage * ); - - /* Free private data. - */ - void (*destroy)( struct tnl_pipeline_stage * ); - - /* Called on any statechange or input array size change or - * input array change to/from zero stride. - */ - void (*validate)( struct gl_context *ctx, struct tnl_pipeline_stage * ); - - /* Called from _tnl_run_pipeline(). The stage.changed_inputs value - * encodes all inputs to thee struct which have changed. If - * non-zero, recompute all affected outputs of the stage, otherwise - * execute any 'sideeffects' of the stage. - * - * Return value: GL_TRUE - keep going - * GL_FALSE - finished pipeline - */ - GLboolean (*run)( struct gl_context *ctx, struct tnl_pipeline_stage * ); -}; - - - -/** Contains the array of all pipeline stages. - * The default values are defined at the end of t_pipeline.c - */ -struct tnl_pipeline { - - GLuint last_attrib_stride[_TNL_ATTRIB_MAX]; - GLuint last_attrib_size[_TNL_ATTRIB_MAX]; - GLuint input_changes; - GLuint new_state; - - struct tnl_pipeline_stage stages[MAX_PIPELINE_STAGES+1]; - GLuint nr_stages; -}; - -struct tnl_clipspace; -struct tnl_clipspace_attr; - -typedef void (*tnl_extract_func)( const struct tnl_clipspace_attr *a, - GLfloat *out, - const GLubyte *v ); - -typedef void (*tnl_insert_func)( const struct tnl_clipspace_attr *a, - GLubyte *v, - const GLfloat *in ); - -typedef void (*tnl_emit_func)( struct gl_context *ctx, - GLuint count, - GLubyte *dest ); - - -/** - * Describes how to convert/move a vertex attribute from a vertex array - * to a vertex structure. - */ -struct tnl_clipspace_attr -{ - GLuint attrib; /* which vertex attrib (0=position, etc) */ - GLuint format; - GLuint vertoffset; /* position of the attrib in the vertex struct */ - GLuint vertattrsize; /* size of the attribute in bytes */ - GLubyte *inputptr; - GLuint inputstride; - GLuint inputsize; - const tnl_insert_func *insert; - tnl_insert_func emit; - tnl_extract_func extract; - const GLfloat *vp; /* NDC->Viewport mapping matrix */ -}; - - - - -typedef void (*tnl_points_func)( struct gl_context *ctx, GLuint first, GLuint last ); -typedef void (*tnl_line_func)( struct gl_context *ctx, GLuint v1, GLuint v2 ); -typedef void (*tnl_triangle_func)( struct gl_context *ctx, - GLuint v1, GLuint v2, GLuint v3 ); -typedef void (*tnl_quad_func)( struct gl_context *ctx, GLuint v1, GLuint v2, - GLuint v3, GLuint v4 ); -typedef void (*tnl_render_func)( struct gl_context *ctx, GLuint start, GLuint count, - GLuint flags ); -typedef void (*tnl_interp_func)( struct gl_context *ctx, - GLfloat t, GLuint dst, GLuint out, GLuint in, - GLboolean force_boundary ); -typedef void (*tnl_copy_pv_func)( struct gl_context *ctx, GLuint dst, GLuint src ); -typedef void (*tnl_setup_func)( struct gl_context *ctx, - GLuint start, GLuint end, - GLuint new_inputs); - - -struct tnl_attr_type { - GLuint format; - GLuint size; - GLuint stride; - GLuint offset; -}; - -struct tnl_clipspace_fastpath { - GLuint vertex_size; - GLuint attr_count; - GLboolean match_strides; - - struct tnl_attr_type *attr; - - tnl_emit_func func; - struct tnl_clipspace_fastpath *next; -}; - -/** - * Used to describe conversion of vertex arrays to vertex structures. - * I.e. Structure of arrays to arrays of structs. - */ -struct tnl_clipspace -{ - GLboolean need_extras; - - GLuint new_inputs; - - GLubyte *vertex_buf; - GLuint vertex_size; - GLuint max_vertex_size; - - struct tnl_clipspace_attr attr[_TNL_ATTRIB_MAX]; - GLuint attr_count; - - tnl_emit_func emit; - tnl_interp_func interp; - tnl_copy_pv_func copy_pv; - - /* Parameters and constants for codegen: - */ - GLboolean need_viewport; - GLfloat vp_scale[4]; - GLfloat vp_xlate[4]; - GLfloat chan_scale[4]; - GLfloat identity[4]; - - struct tnl_clipspace_fastpath *fastpath; - - void (*codegen_emit)( struct gl_context *ctx ); -}; - - -#define SHINE_TABLE_SIZE 256 /**< Material shininess lookup table sizes */ - -/** - * Material shininess lookup table. - */ -struct tnl_shine_tab -{ - struct tnl_shine_tab *next, *prev; - GLfloat tab[SHINE_TABLE_SIZE+1]; - GLfloat shininess; - GLuint refcount; -}; - - -struct tnl_device_driver -{ - /*** - *** TNL Pipeline - ***/ - - void (*RunPipeline)(struct gl_context *ctx); - /* Replaces PipelineStart/PipelineFinish -- intended to allow - * drivers to wrap _tnl_run_pipeline() with code to validate state - * and grab/release hardware locks. - */ - - void (*NotifyMaterialChange)(struct gl_context *ctx); - /* Alert tnl-aware drivers of changes to material. - */ - - /*** - *** Rendering -- These functions called only from t_vb_render.c - ***/ - struct - { - void (*Start)(struct gl_context *ctx); - void (*Finish)(struct gl_context *ctx); - /* Called before and after all rendering operations, including DrawPixels, - * ReadPixels, Bitmap, span functions, and CopyTexImage, etc commands. - * These are a suitable place for grabbing/releasing hardware locks. - */ - - void (*PrimitiveNotify)(struct gl_context *ctx, GLenum mode); - /* Called between RenderStart() and RenderFinish() to indicate the - * type of primitive we're about to draw. Mode will be one of the - * modes accepted by glBegin(). - */ - - tnl_interp_func Interp; - /* The interp function is called by the clipping routines when we need - * to generate an interpolated vertex. All pertinant vertex ancilliary - * data should be computed by interpolating between the 'in' and 'out' - * vertices. - */ - - tnl_copy_pv_func CopyPV; - /* The copy function is used to make a copy of a vertex. All pertinant - * vertex attributes should be copied. - */ - - void (*ClippedPolygon)( struct gl_context *ctx, const GLuint *elts, GLuint n ); - /* Render a polygon with vertices whose indexes are in the - * array. - */ - - void (*ClippedLine)( struct gl_context *ctx, GLuint v0, GLuint v1 ); - /* Render a line between the two vertices given by indexes v0 and v1. */ - - tnl_points_func Points; /* must now respect vb->elts */ - tnl_line_func Line; - tnl_triangle_func Triangle; - tnl_quad_func Quad; - /* These functions are called in order to render points, lines, - * triangles and quads. These are only called via the T&L module. - */ - - tnl_render_func *PrimTabVerts; - tnl_render_func *PrimTabElts; - /* Render whole unclipped primitives (points, lines, linestrips, - * lineloops, etc). The tables are indexed by the GL enum of the - * primitive to be rendered. RenderTabVerts is used for non-indexed - * arrays of vertices. RenderTabElts is used for indexed arrays of - * vertices. - */ - - void (*ResetLineStipple)( struct gl_context *ctx ); - /* Reset the hardware's line stipple counter. - */ - - tnl_setup_func BuildVertices; - /* This function is called whenever new vertices are required for - * rendering. The vertices in question are those n such that start - * <= n < end. The new_inputs parameter indicates those fields of - * the vertex which need to be updated, if only a partial repair of - * the vertex is required. - * - * This function is called only from _tnl_render_stage in tnl/t_render.c. - */ - - - GLboolean (*Multipass)( struct gl_context *ctx, GLuint passno ); - /* Driver may request additional render passes by returning GL_TRUE - * when this function is called. This function will be called - * after the first pass, and passes will be made until the function - * returns GL_FALSE. If no function is registered, only one pass - * is made. - * - * This function will be first invoked with passno == 1. - */ - } Render; -}; - - -/** - * Utility that tracks and updates the current array entries. - */ -struct tnl_inputs -{ - /** - * Array of inputs to be set to the _DrawArrays pointer. - * The array contains pointers into the _DrawVAO and to the vbo modules - * current values. The array of pointers is updated incrementally - * based on the current and vertex_processing_mode values below. - */ - struct tnl_vertex_array inputs[VERT_ATTRIB_MAX]; - /** Those VERT_BIT_'s where the inputs array point to current values. */ - GLbitfield current; - /** Store which aliasing current values - generics or materials - are set. */ - gl_vertex_processing_mode vertex_processing_mode; -}; - - -/** - * Initialize inputs. - */ -void -_tnl_init_inputs(struct tnl_inputs *inputs); - - -/** - * Update the tnl_vertex_array array inside the tnl_inputs structure - * provided the current _VPMode, the provided vao and - * the vao's enabled arrays filtered by the filter bitmask. - */ -void -_tnl_update_inputs(struct gl_context *ctx, struct tnl_inputs *inputs); - - -/** - * Context state for T&L context. - */ -typedef struct -{ - /* Driver interface. - */ - struct tnl_device_driver Driver; - - /* Pipeline - */ - struct tnl_pipeline pipeline; - struct vertex_buffer vb; - - /* Clipspace/ndc/window vertex managment: - */ - struct tnl_clipspace clipspace; - GLmatrix _WindowMap; - - /* Probably need a better configuration mechanism: - */ - GLboolean NeedNdcCoords; - GLboolean AllowVertexFog; - GLboolean AllowPixelFog; - GLboolean _DoVertexFog; /* eval fog function at each vertex? */ - - GLbitfield64 render_inputs_bitset; - - GLvector4f tmp_inputs[VERT_ATTRIB_MAX]; - - /* Temp storage for t_draw.c: - */ - GLubyte *block[VERT_ATTRIB_MAX]; - GLuint nr_blocks; - - GLuint CurInstance; - - struct tnl_shine_tab *_ShineTable[2]; /**< Active shine tables */ - struct tnl_shine_tab *_ShineTabList; /**< MRU list of inactive shine tables */ - /**@}*/ - - /* The list of tnl_vertex_array inputs. */ - struct tnl_inputs draw_arrays; -} TNLcontext; - - - -#define TNL_CONTEXT(ctx) ((TNLcontext *)((ctx)->swtnl_context)) - - -#define TYPE_IDX(t) ((t) & 0xf) -#define MAX_TYPES TYPE_IDX(GL_DOUBLE)+1 /* 0xa + 1 */ - - -extern void -tnl_clip_prepare(struct gl_context *ctx); - - -#endif diff --git a/src/mesa/tnl/t_draw.c b/src/mesa/tnl/t_draw.c deleted file mode 100644 index d48687e..0000000 --- a/src/mesa/tnl/t_draw.c +++ /dev/null @@ -1,657 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - * - * Authors: - * Keith Whitwell - */ - -#include - -#include "main/glheader.h" -#include "main/arrayobj.h" -#include "main/bufferobj.h" -#include "main/condrender.h" -#include "main/context.h" - -#include "main/mtypes.h" -#include "main/macros.h" -#include "main/enums.h" -#include "main/varray.h" -#include "util/half_float.h" - -#include "t_context.h" -#include "t_rebase.h" -#include "tnl.h" - - -static GLubyte *get_space(struct gl_context *ctx, GLuint bytes) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLubyte *space = malloc(bytes); - - tnl->block[tnl->nr_blocks++] = space; - return space; -} - - -static void free_space(struct gl_context *ctx) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - - for (GLuint i = 0; i < tnl->nr_blocks; i++) - free(tnl->block[i]); - - tnl->nr_blocks = 0; -} - - -/* Convert the incoming array to GLfloats. Understands the - * array->Normalized flag and selects the correct conversion method. - */ -#define CONVERT( TYPE, MACRO ) do { \ - GLuint i, j; \ - if (attrib->Format.Normalized) { \ - for (i = 0; i < count; i++) { \ - const TYPE *in = (TYPE *)ptr; \ - for (j = 0; j < sz; j++) { \ - *fptr++ = MACRO(*in); \ - in++; \ - } \ - ptr += binding->Stride; \ - } \ - } else { \ - for (i = 0; i < count; i++) { \ - const TYPE *in = (TYPE *)ptr; \ - for (j = 0; j < sz; j++) { \ - *fptr++ = (GLfloat)(*in); \ - in++; \ - } \ - ptr += binding->Stride; \ - } \ - } \ -} while (0) - - -/** - * Convert array of BGRA/GLubyte[4] values to RGBA/float[4] - * \param ptr input/ubyte array - * \param fptr output/float array - */ -static void -convert_bgra_to_float(const struct gl_vertex_buffer_binding *binding, - const struct gl_array_attributes *attrib, - const GLubyte *ptr, GLfloat *fptr, - GLuint count) -{ - GLuint i; - assert(attrib->Format.Normalized); - assert(attrib->Format.Size == 4); - for (i = 0; i < count; i++) { - const GLubyte *in = (GLubyte *) ptr; /* in is in BGRA order */ - *fptr++ = UBYTE_TO_FLOAT(in[2]); /* red */ - *fptr++ = UBYTE_TO_FLOAT(in[1]); /* green */ - *fptr++ = UBYTE_TO_FLOAT(in[0]); /* blue */ - *fptr++ = UBYTE_TO_FLOAT(in[3]); /* alpha */ - ptr += binding->Stride; - } -} - -static void -convert_half_to_float(const struct gl_vertex_buffer_binding *binding, - const GLubyte *ptr, GLfloat *fptr, - GLuint count, GLuint sz) -{ - GLuint i, j; - - for (i = 0; i < count; i++) { - GLhalfARB *in = (GLhalfARB *)ptr; - - for (j = 0; j < sz; j++) - *fptr++ = _mesa_half_to_float(in[j]); - - ptr += binding->Stride; - } -} - -/** - * \brief Convert fixed-point to floating-point. - * - * In OpenGL, a fixed-point number is a "signed 2's complement 16.16 scaled - * integer" (Table 2.2 of the OpenGL ES 2.0 spec). - * - * If the buffer has the \c normalized flag set, the formula - * \code normalize(x) := (2*x + 1) / (2^16 - 1) \endcode - * is used to map the fixed-point numbers into the range [-1, 1]. - */ -static void -convert_fixed_to_float(const struct gl_vertex_buffer_binding *binding, - const struct gl_array_attributes *attrib, - const GLubyte *ptr, GLfloat *fptr, - GLuint count) -{ - GLuint i; - GLint j; - const GLint size = attrib->Format.Size; - - if (attrib->Format.Normalized) { - for (i = 0; i < count; ++i) { - const GLfixed *in = (GLfixed *) ptr; - for (j = 0; j < size; ++j) { - *fptr++ = (GLfloat) (2 * in[j] + 1) / (GLfloat) ((1 << 16) - 1); - } - ptr += binding->Stride; - } - } else { - for (i = 0; i < count; ++i) { - const GLfixed *in = (GLfixed *) ptr; - for (j = 0; j < size; ++j) { - *fptr++ = in[j] / (GLfloat) (1 << 16); - } - ptr += binding->Stride; - } - } -} - -/* Adjust pointer to point at first requested element, convert to - * floating point, populate VB->AttribPtr[]. - */ -static void _tnl_import_array(struct gl_context *ctx, - GLuint attr, - GLuint count, - const struct gl_vertex_buffer_binding *binding, - const struct gl_array_attributes *attrib, - const GLubyte *ptr) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &tnl->vb; - GLuint stride = binding->Stride; - - if (attrib->Format.Type != GL_FLOAT) { - const GLuint sz = attrib->Format.Size; - GLubyte *buf = get_space(ctx, count * sz * sizeof(GLfloat)); - GLfloat *fptr = (GLfloat *)buf; - - switch (attrib->Format.Type) { - case GL_BYTE: - CONVERT(GLbyte, BYTE_TO_FLOAT); - break; - case GL_UNSIGNED_BYTE: - if (attrib->Format.Format == GL_BGRA) { - /* See GL_EXT_vertex_array_bgra */ - convert_bgra_to_float(binding, attrib, ptr, fptr, count); - } - else { - CONVERT(GLubyte, UBYTE_TO_FLOAT); - } - break; - case GL_SHORT: - CONVERT(GLshort, SHORT_TO_FLOAT); - break; - case GL_UNSIGNED_SHORT: - CONVERT(GLushort, USHORT_TO_FLOAT); - break; - case GL_INT: - CONVERT(GLint, INT_TO_FLOAT); - break; - case GL_UNSIGNED_INT: - CONVERT(GLuint, UINT_TO_FLOAT); - break; - case GL_DOUBLE: - CONVERT(GLdouble, (GLfloat)); - break; - case GL_HALF_FLOAT: - convert_half_to_float(binding, ptr, fptr, count, sz); - break; - case GL_FIXED: - convert_fixed_to_float(binding, attrib, ptr, fptr, count); - break; - default: - unreachable("Invalid type."); - } - - ptr = buf; - stride = sz * sizeof(GLfloat); - } - - VB->AttribPtr[attr] = &tnl->tmp_inputs[attr]; - VB->AttribPtr[attr]->data = (GLfloat (*)[4])ptr; - VB->AttribPtr[attr]->start = (GLfloat *)ptr; - VB->AttribPtr[attr]->count = count; - VB->AttribPtr[attr]->stride = stride; - VB->AttribPtr[attr]->size = attrib->Format.Size; - - /* This should die, but so should the whole GLvector4f concept: - */ - VB->AttribPtr[attr]->flags = (((1<Format.Size)-1) | - VEC_NOT_WRITEABLE | - (stride == 4*sizeof(GLfloat) ? 0 : VEC_BAD_STRIDE)); - - VB->AttribPtr[attr]->storage = NULL; -} - -#define CLIPVERTS ((6 + MAX_CLIP_PLANES) * 2) - - -static GLboolean *_tnl_import_edgeflag(struct gl_context *ctx, - const GLvector4f *input, - GLuint count) -{ - const GLubyte *ptr = (const GLubyte *)input->data; - const GLuint stride = input->stride; - GLboolean *space = (GLboolean *)get_space(ctx, count + CLIPVERTS); - GLboolean *bptr = space; - - for (GLuint i = 0; i < count; i++) { - *bptr++ = ((GLfloat *)ptr)[0] == 1.0F; - ptr += stride; - } - - return space; -} - - -static void bind_inputs(struct gl_context *ctx, - const struct tnl_vertex_array *inputs, - GLint count, - struct gl_buffer_object **bo, - GLuint *nr_bo) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &tnl->vb; - - /* Map all the VBOs - */ - for (unsigned i = 0; i < VERT_ATTRIB_MAX; i++) { - const struct tnl_vertex_array *array = &inputs[i]; - const struct gl_vertex_buffer_binding *binding = array->BufferBinding; - const struct gl_array_attributes *attrib = array->VertexAttrib; - const void *ptr; - - if (binding->BufferObj) { - if (!binding->BufferObj->Mappings[MAP_INTERNAL].Pointer) { - bo[*nr_bo] = binding->BufferObj; - (*nr_bo)++; - ctx->Driver.MapBufferRange(ctx, 0, binding->BufferObj->Size, - GL_MAP_READ_BIT, - binding->BufferObj, - MAP_INTERNAL); - - assert(binding->BufferObj->Mappings[MAP_INTERNAL].Pointer); - } - - ptr = ADD_POINTERS(binding->BufferObj->Mappings[MAP_INTERNAL].Pointer, - binding->Offset + attrib->RelativeOffset); - } else - ptr = attrib->Ptr; - - /* Just make sure the array is floating point, otherwise convert to - * temporary storage. - * - * XXX: remove the GLvector4f type at some stage and just use - * client arrays. - */ - _tnl_import_array(ctx, i, count, binding, attrib, ptr); - } - - /* We process only the vertices between min & max index: - */ - VB->Count = count; - - /* These should perhaps be part of _TNL_ATTRIB_* */ - VB->BackfaceColorPtr = NULL; - VB->BackfaceIndexPtr = NULL; - VB->BackfaceSecondaryColorPtr = NULL; - - /* Clipping and drawing code still requires this to be a packed - * array of ubytes which can be written into. TODO: Fix and - * remove. - */ - if (ctx->Polygon.FrontMode != GL_FILL || - ctx->Polygon.BackMode != GL_FILL) { - VB->EdgeFlag = _tnl_import_edgeflag(ctx, - VB->AttribPtr[_TNL_ATTRIB_EDGEFLAG], - VB->Count); - } else { - /* the data previously pointed to by EdgeFlag may have been freed */ - VB->EdgeFlag = NULL; - } -} - - -/* Translate indices to GLuints and store in VB->Elts. - */ -static void bind_indices(struct gl_context *ctx, - unsigned start, - const struct _mesa_index_buffer *ib, - struct gl_buffer_object **bo, - GLuint *nr_bo) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &tnl->vb; - GLuint i; - const void *ptr; - - if (!ib) { - VB->Elts = NULL; - return; - } - - if (ib->obj) { - if (!_mesa_bufferobj_mapped(ib->obj, MAP_INTERNAL)) { - /* if the buffer object isn't mapped yet, map it now */ - bo[*nr_bo] = ib->obj; - (*nr_bo)++; - ptr = ctx->Driver.MapBufferRange(ctx, (GLsizeiptr) ib->ptr, - ib->count << ib->index_size_shift, - GL_MAP_READ_BIT, ib->obj, - MAP_INTERNAL); - assert(ib->obj->Mappings[MAP_INTERNAL].Pointer); - } else { - /* user-space elements, or buffer already mapped */ - ptr = ADD_POINTERS(ib->obj->Mappings[MAP_INTERNAL].Pointer, ib->ptr); - } - } else - ptr = ib->ptr; - - if (ib->index_size_shift == 2 && VB->Primitive[0].basevertex == 0) { - VB->Elts = (GLuint *) ptr; - } - else { - GLuint *elts = (GLuint *)get_space(ctx, (start + ib->count) * sizeof(GLuint)); - VB->Elts = elts; - - elts += start; - - if (ib->index_size_shift == 2) { - const GLuint *in = (GLuint *)ptr + start; - for (i = 0; i < ib->count; i++) - *elts++ = (GLuint)(*in++) + VB->Primitive[0].basevertex; - } - else if (ib->index_size_shift == 1) { - const GLushort *in = (GLushort *)ptr + start; - for (i = 0; i < ib->count; i++) - *elts++ = (GLuint)(*in++) + VB->Primitive[0].basevertex; - } - else { - const GLubyte *in = (GLubyte *)ptr + start; - for (i = 0; i < ib->count; i++) - *elts++ = (GLuint)(*in++) + VB->Primitive[0].basevertex; - } - } -} - -static void bind_prims(struct gl_context *ctx, - const struct _mesa_prim *prim, - GLuint nr_prims) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &tnl->vb; - - VB->Primitive = prim; - VB->PrimitiveCount = nr_prims; -} - -static void unmap_vbos(struct gl_context *ctx, - struct gl_buffer_object **bo, - GLuint nr_bo) -{ - for (GLuint i = 0; i < nr_bo; i++) { - ctx->Driver.UnmapBuffer(ctx, bo[i], MAP_INTERNAL); - } -} - - -/* This is the main workhorse doing all the rendering work. - */ -void _tnl_draw_prims(struct gl_context *ctx, - const struct tnl_vertex_array *arrays, - const struct _mesa_prim *prim, - GLuint nr_prims, - const struct _mesa_index_buffer *ib, - GLboolean index_bounds_valid, - GLuint min_index, - GLuint max_index, - GLuint num_instances, - GLuint base_instance) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - const GLuint TEST_SPLIT = 0; - const GLint max = TEST_SPLIT ? 8 : tnl->vb.Size - MAX_CLIPPED_VERTICES; - GLint max_basevertex = prim->basevertex; - GLuint i; - - if (!index_bounds_valid) - vbo_get_minmax_indices(ctx, prim, ib, &min_index, &max_index, nr_prims, - false, 0); - - /* Mesa core state should have been validated already */ - assert(ctx->NewState == 0x0); - - if (!_mesa_check_conditional_render(ctx)) - return; /* don't draw */ - - for (i = 1; i < nr_prims; i++) - max_basevertex = MAX2(max_basevertex, prim[i].basevertex); - - if (0) { - printf("%s %d..%d\n", __func__, min_index, max_index); - for (i = 0; i < nr_prims; i++) - printf("prim %d: %s start %d count %d\n", i, - _mesa_enum_to_string(prim[i].mode), - prim[i].start, - prim[i].count); - } - - if (min_index) { - /* We always translate away calls with min_index != 0. - */ - t_rebase_prims(ctx, arrays, prim, nr_prims, ib, - min_index, max_index, num_instances, base_instance, - _tnl_draw_prims); - return; - } - else if ((GLint)max_index + max_basevertex > max) { - /* The software TNL pipeline has a fixed amount of storage for - * vertices and it is necessary to split incoming drawing commands - * if they exceed that limit. - */ - struct split_limits limits; - limits.max_verts = max; - limits.max_vb_size = ~0; - limits.max_indices = ~0; - - /* This will split the buffers one way or another and - * recursively call back into this function. - */ - _tnl_split_prims(ctx, arrays, prim, nr_prims, ib, - 0, max_index + prim->basevertex, - num_instances, base_instance, - _tnl_draw_prims, - &limits); - } - else { - /* May need to map a vertex buffer object for every attribute plus - * one for the index buffer. - */ - struct gl_buffer_object *bo[VERT_ATTRIB_MAX + 1]; - GLuint nr_bo; - GLuint inst; - - assert(num_instances > 0); - - for (i = 0; i < nr_prims;) { - GLuint this_nr_prims; - - /* Our SW TNL pipeline doesn't handle basevertex yet, so bind_indices - * will rebase the elements to the basevertex, and we'll only - * emit strings of prims with the same basevertex in one draw call. - */ - for (this_nr_prims = 1; i + this_nr_prims < nr_prims; - this_nr_prims++) { - if (prim[i].basevertex != prim[i + this_nr_prims].basevertex || - prim[i].start != prim[i + this_nr_prims].start) - break; - } - - /* Binding inputs may imply mapping some vertex buffer objects. - * They will need to be unmapped below. - */ - for (inst = 0; inst < num_instances; inst++) { - nr_bo = 0; - - bind_prims(ctx, &prim[i], this_nr_prims); - bind_inputs(ctx, arrays, max_index + prim[i].basevertex + 1, - bo, &nr_bo); - bind_indices(ctx, prim[i].start, ib, bo, &nr_bo); - - tnl->CurInstance = inst; - TNL_CONTEXT(ctx)->Driver.RunPipeline(ctx); - - unmap_vbos(ctx, bo, nr_bo); - free_space(ctx); - } - - i += this_nr_prims; - } - } -} - - -void -_tnl_init_inputs(struct tnl_inputs *inputs) -{ - inputs->current = 0; - inputs->vertex_processing_mode = VP_MODE_FF; -} - - -/** - * Update the tnl_inputs's arrays to point to the vao->_VertexArray arrays - * according to the 'enable' bitmask. - * \param enable bitfield of VERT_BIT_x flags. - */ -static inline void -update_vao_inputs(struct gl_context *ctx, - struct tnl_inputs *inputs, GLbitfield enable) -{ - const struct gl_vertex_array_object *vao = ctx->Array._DrawVAO; - - /* Make sure we process only arrays enabled in the VAO */ - assert((enable & ~vao->_EnabledWithMapMode) == 0); - - /* Fill in the client arrays from the VAO */ - const struct gl_vertex_buffer_binding *bindings = &vao->BufferBinding[0]; - while (enable) { - const int attr = u_bit_scan(&enable); - struct tnl_vertex_array *input = &inputs->inputs[attr]; - const struct gl_array_attributes *attrib; - attrib = _mesa_draw_array_attrib(vao, attr); - input->VertexAttrib = attrib; - input->BufferBinding = &bindings[attrib->BufferBindingIndex]; - } -} - - -/** - * Update the tnl_inputs's arrays to point to the vbo->currval arrays - * according to the 'current' bitmask. - * \param current bitfield of VERT_BIT_x flags. - */ -static inline void -update_current_inputs(struct gl_context *ctx, - struct tnl_inputs *inputs, GLbitfield current) -{ - gl_vertex_processing_mode mode = ctx->VertexProgram._VPMode; - - /* All previously non current array pointers need update. */ - GLbitfield mask = current & ~inputs->current; - /* On mode change, the slots aliasing with materials need update too */ - if (mode != inputs->vertex_processing_mode) - mask |= current & VERT_BIT_MAT_ALL; - - while (mask) { - const int attr = u_bit_scan(&mask); - struct tnl_vertex_array *input = &inputs->inputs[attr]; - input->VertexAttrib = _vbo_current_attrib(ctx, attr); - input->BufferBinding = _vbo_current_binding(ctx); - } - - inputs->current = current; - inputs->vertex_processing_mode = mode; -} - - -/** - * Update the tnl_inputs's arrays to point to the vao->_VertexArray and - * vbo->currval arrays according to Array._DrawVAO and - * Array._DrawVAOEnableAttribs. - */ -void -_tnl_update_inputs(struct gl_context *ctx, struct tnl_inputs *inputs) -{ - const GLbitfield enable = ctx->Array._DrawVAOEnabledAttribs; - - /* Update array input pointers */ - update_vao_inputs(ctx, inputs, enable); - - /* The rest must be current inputs. */ - update_current_inputs(ctx, inputs, ~enable & VERT_BIT_ALL); -} - - -const struct tnl_vertex_array * -_tnl_bind_inputs(struct gl_context *ctx) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - _tnl_update_inputs(ctx, &tnl->draw_arrays); - return tnl->draw_arrays.inputs; -} - - -/* This is the main entrypoint into the slimmed-down software tnl - * module. In a regular swtnl driver, this can be plugged straight - * into the ctx->Driver.Draw() callback. - */ -void -_tnl_draw(struct gl_context *ctx, - const struct _mesa_prim *prim, unsigned nr_prims, - const struct _mesa_index_buffer *ib, - bool index_bounds_valid, bool primitive_restart, - unsigned restart_index, unsigned min_index, unsigned max_index, - unsigned num_instances, unsigned base_instance) -{ - /* Update TNLcontext::draw_arrays and return that pointer. - */ - const struct tnl_vertex_array* arrays = _tnl_bind_inputs(ctx); - - _tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, - index_bounds_valid, min_index, max_index, - num_instances, base_instance); -} - - -void -_tnl_init_driver_draw_function(struct dd_function_table *functions) -{ - functions->Draw = _tnl_draw; -} diff --git a/src/mesa/tnl/t_pipeline.c b/src/mesa/tnl/t_pipeline.c deleted file mode 100644 index 760e69d..0000000 --- a/src/mesa/tnl/t_pipeline.c +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - * - * Authors: - * Keith Whitwell - */ - -#include "main/glheader.h" -#include "main/context.h" - -#include "main/mtypes.h" - -#include "t_context.h" -#include "t_pipeline.h" -#include "t_vp_build.h" -#include "t_vertex.h" - -void _tnl_install_pipeline( struct gl_context *ctx, - const struct tnl_pipeline_stage **stages ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLuint i; - - tnl->pipeline.new_state = ~0; - - /* Create a writeable copy of each stage. - */ - for (i = 0 ; i < MAX_PIPELINE_STAGES && stages[i] ; i++) { - struct tnl_pipeline_stage *s = &tnl->pipeline.stages[i]; - memcpy(s, stages[i], sizeof(*s)); - if (s->create) - s->create(ctx, s); - } - - tnl->pipeline.nr_stages = i; -} - -void _tnl_destroy_pipeline( struct gl_context *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLuint i; - - for (i = 0 ; i < tnl->pipeline.nr_stages ; i++) { - struct tnl_pipeline_stage *s = &tnl->pipeline.stages[i]; - if (s->destroy) - s->destroy(s); - } - - tnl->pipeline.nr_stages = 0; -} - - - -static GLuint check_input_changes( struct gl_context *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLuint i; - - for (i = 0; i <= _TNL_LAST_MAT; i++) { - if (tnl->vb.AttribPtr[i]->size != tnl->pipeline.last_attrib_size[i] || - tnl->vb.AttribPtr[i]->stride != tnl->pipeline.last_attrib_stride[i]) { - tnl->pipeline.last_attrib_size[i] = tnl->vb.AttribPtr[i]->size; - tnl->pipeline.last_attrib_stride[i] = tnl->vb.AttribPtr[i]->stride; - tnl->pipeline.input_changes |= 1<pipeline.input_changes; -} - - -static GLuint check_output_changes( struct gl_context *ctx ) -{ -#if 0 - TNLcontext *tnl = TNL_CONTEXT(ctx); - - for (i = 0; i < VARYING_SLOT_MAX; i++) { - if (tnl->vb.ResultPtr[i]->size != tnl->last_result_size[i] || - tnl->vb.ResultPtr[i]->stride != tnl->last_result_stride[i]) { - tnl->last_result_size[i] = tnl->vb.ResultPtr[i]->size; - tnl->last_result_stride[i] = tnl->vb.ResultPtr[i]->stride; - tnl->pipeline.output_changes |= 1<pipeline.output_changes) - tnl->Driver.NotifyOutputChanges( ctx, tnl->pipeline.output_changes ); - - return tnl->pipeline.output_changes; -#else - return ~0; -#endif -} - -/** - * START/END_FAST_MATH macros: - * - * START_FAST_MATH: Set x86 FPU to faster, 32-bit precision mode (and save - * original mode to a temporary). - * END_FAST_MATH: Restore x86 FPU to original mode. - */ -#if defined(__GNUC__) && defined(__i386__) -/* - * Set the x86 FPU control word to guarentee only 32 bits of precision - * are stored in registers. Allowing the FPU to store more introduces - * differences between situations where numbers are pulled out of memory - * vs. situations where the compiler is able to optimize register usage. - * - * In the worst case, we force the compiler to use a memory access to - * truncate the float, by specifying the 'volatile' keyword. - */ -/* Hardware default: All exceptions masked, extended double precision, - * round to nearest (IEEE compliant): - */ -#define DEFAULT_X86_FPU 0x037f -/* All exceptions masked, single precision, round to nearest: - */ -#define FAST_X86_FPU 0x003f -/* The fldcw instruction will cause any pending FP exceptions to be - * raised prior to entering the block, and we clear any pending - * exceptions before exiting the block. Hence, asm code has free - * reign over the FPU while in the fast math block. - */ -#if defined(NO_FAST_MATH) -#define START_FAST_MATH(x) \ -do { \ - static GLuint mask = DEFAULT_X86_FPU; \ - __asm__ ( "fnstcw %0" : "=m" (*&(x)) ); \ - __asm__ ( "fldcw %0" : : "m" (mask) ); \ -} while (0) -#else -#define START_FAST_MATH(x) \ -do { \ - static GLuint mask = FAST_X86_FPU; \ - __asm__ ( "fnstcw %0" : "=m" (*&(x)) ); \ - __asm__ ( "fldcw %0" : : "m" (mask) ); \ -} while (0) -#endif -/* Restore original FPU mode, and clear any exceptions that may have - * occurred in the FAST_MATH block. - */ -#define END_FAST_MATH(x) \ -do { \ - __asm__ ( "fnclex ; fldcw %0" : : "m" (*&(x)) ); \ -} while (0) - -#elif defined(_MSC_VER) && defined(_M_IX86) -#define DEFAULT_X86_FPU 0x037f /* See GCC comments above */ -#define FAST_X86_FPU 0x003f /* See GCC comments above */ -#if defined(NO_FAST_MATH) -#define START_FAST_MATH(x) do {\ - static GLuint mask = DEFAULT_X86_FPU;\ - __asm fnstcw word ptr [x]\ - __asm fldcw word ptr [mask]\ -} while(0) -#else -#define START_FAST_MATH(x) do {\ - static GLuint mask = FAST_X86_FPU;\ - __asm fnstcw word ptr [x]\ - __asm fldcw word ptr [mask]\ -} while(0) -#endif -#define END_FAST_MATH(x) do {\ - __asm fnclex\ - __asm fldcw word ptr [x]\ -} while(0) - -#else -#define START_FAST_MATH(x) x = 0 -#define END_FAST_MATH(x) (void)(x) -#endif - - -void _tnl_run_pipeline( struct gl_context *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - unsigned short __tmp; - GLuint i; - - if (!tnl->vb.Count) - return; - - /* Check for changed input sizes or change in stride to/from zero - * (ie const or non-const). - */ - if (check_input_changes( ctx ) || tnl->pipeline.new_state) { - if (ctx->VertexProgram._MaintainTnlProgram) - _tnl_UpdateFixedFunctionProgram( ctx ); - - for (i = 0; i < tnl->pipeline.nr_stages ; i++) { - struct tnl_pipeline_stage *s = &tnl->pipeline.stages[i]; - if (s->validate) - s->validate( ctx, s ); - } - - tnl->pipeline.new_state = 0; - tnl->pipeline.input_changes = 0; - - /* Pipeline can only change its output in response to either a - * statechange or an input size/stride change. No other changes - * are allowed. - */ - if (check_output_changes( ctx )) - _tnl_notify_pipeline_output_change( ctx ); - } - -#ifndef _OPENMP - /* Don't adjust FPU precision mode in case multiple threads are to be used. - * This would require that the additional threads also changed the FPU mode - * which is quite a mess as this had to be done in all parallelized sections; - * otherwise the master thread and all other threads are running in different - * modes, producing inconsistent results. - * Note that all x64 implementations don't define/use START_FAST_MATH, so - * this is "hack" is only used in i386 mode - */ - START_FAST_MATH(__tmp); -#endif - - for (i = 0; i < tnl->pipeline.nr_stages ; i++) { - struct tnl_pipeline_stage *s = &tnl->pipeline.stages[i]; - if (!s->run( ctx, s )) - break; - } - -#ifndef _OPENMP - END_FAST_MATH(__tmp); -#endif -} - - - -/* The default pipeline. This is useful for software rasterizers, and - * simple hardware rasterizers. For customization, I don't recommend - * tampering with the internals of these stages in the way that - * drivers did in Mesa 3.4. These stages are basically black boxes, - * and should be left intact. - * - * To customize the pipeline, consider: - * - * - removing redundant stages (making sure that the software rasterizer - * can cope with this on fallback paths). An example is fog - * coordinate generation, which is not required in the FX driver. - * - * - replacing general-purpose machine-independent stages with - * general-purpose machine-specific stages. There is no example of - * this to date, though it must be borne in mind that all subsequent - * stages that reference the output of the new stage must cope with - * any machine-specific data introduced. This may not be easy - * unless there are no such stages (ie the new stage is the last in - * the pipe). - * - * - inserting optimized (but specialized) stages ahead of the - * general-purpose fallback implementation. For example, the old - * fastpath mechanism, which only works when the VB->Elts input is - * available, can be duplicated by placing the fastpath stage at the - * head of this pipeline. Such specialized stages are currently - * constrained to have no outputs (ie. they must either finish the * - * pipeline by returning GL_FALSE from run(), or do nothing). - * - * Some work can be done to lift some of the restrictions in the final - * case, if it becomes necessary to do so. - */ -const struct tnl_pipeline_stage *_tnl_default_pipeline[] = { - &_tnl_vertex_transform_stage, - &_tnl_normal_transform_stage, - &_tnl_lighting_stage, - &_tnl_texgen_stage, - &_tnl_texture_transform_stage, - &_tnl_point_attenuation_stage, - &_tnl_vertex_program_stage, - &_tnl_fog_coordinate_stage, - &_tnl_render_stage, - NULL -}; - -const struct tnl_pipeline_stage *_tnl_vp_pipeline[] = { - &_tnl_vertex_program_stage, - &_tnl_render_stage, - NULL -}; diff --git a/src/mesa/tnl/t_pipeline.h b/src/mesa/tnl/t_pipeline.h deleted file mode 100644 index 48963df..0000000 --- a/src/mesa/tnl/t_pipeline.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - * - * Authors: - * Keith Whitwell - */ - - - -#ifndef _T_PIPELINE_H_ -#define _T_PIPELINE_H_ - -#include "main/mtypes.h" -#include "t_context.h" - -extern void _tnl_run_pipeline( struct gl_context *ctx ); - -extern void _tnl_destroy_pipeline( struct gl_context *ctx ); - -extern void _tnl_install_pipeline( struct gl_context *ctx, - const struct tnl_pipeline_stage **stages ); - - -/* These are implemented in the t_vb_*.c files: - */ -extern const struct tnl_pipeline_stage _tnl_vertex_transform_stage; -extern const struct tnl_pipeline_stage _tnl_normal_transform_stage; -extern const struct tnl_pipeline_stage _tnl_lighting_stage; -extern const struct tnl_pipeline_stage _tnl_fog_coordinate_stage; -extern const struct tnl_pipeline_stage _tnl_texgen_stage; -extern const struct tnl_pipeline_stage _tnl_texture_transform_stage; -extern const struct tnl_pipeline_stage _tnl_point_attenuation_stage; -extern const struct tnl_pipeline_stage _tnl_vertex_program_stage; -extern const struct tnl_pipeline_stage _tnl_render_stage; - -/* Shorthand to plug in the default pipeline: - */ -extern const struct tnl_pipeline_stage *_tnl_default_pipeline[]; -extern const struct tnl_pipeline_stage *_tnl_vp_pipeline[]; - - -/* Convenience routines provided by t_vb_render.c: - */ -extern tnl_render_func _tnl_render_tab_elts[]; -extern tnl_render_func _tnl_render_tab_verts[]; - -extern void _tnl_RenderClippedPolygon( struct gl_context *ctx, - const GLuint *elts, GLuint n ); - -extern void _tnl_RenderClippedLine( struct gl_context *ctx, GLuint ii, GLuint jj ); - - -#endif diff --git a/src/mesa/tnl/t_rebase.c b/src/mesa/tnl/t_rebase.c deleted file mode 100644 index 0471895..0000000 --- a/src/mesa/tnl/t_rebase.c +++ /dev/null @@ -1,267 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - * - * Authors: - * Keith Whitwell - */ - -/* Helper for drivers which find themselves rendering a range of - * indices starting somewhere above zero. Typically the application - * is issuing multiple DrawArrays() or DrawElements() to draw - * successive primitives layed out linearly in the vertex arrays. - * Unless the vertex arrays are all in a VBO, the OpenGL semantics - * imply that we need to re-upload the vertex data on each draw call. - * In that case, we want to avoid starting the upload at zero, as it - * will mean every draw call uploads an increasing amount of not-used - * vertex data. Worse - in the software tnl module, all those - * vertices will be transformed and lit. - * - * If we just upload the new data, however, the indices will be - * incorrect as we tend to upload each set of vertex data to a new - * region. - * - * This file provides a helper to adjust the arrays, primitives and - * indices of a draw call so that it can be re-issued with a min_index - * of zero. - */ - -#include -#include "main/bufferobj.h" -#include "main/errors.h" -#include "main/glheader.h" -#include "main/macros.h" -#include "main/mtypes.h" -#include "vbo/vbo.h" - -#include "t_rebase.h" - - -#define REBASE(TYPE) \ -static void *rebase_##TYPE(const void *ptr, \ - unsigned start, \ - unsigned count, \ - TYPE min_index) \ -{ \ - const TYPE *in = (TYPE *)ptr; \ - TYPE *tmp_indices = malloc((start + count) * sizeof(TYPE)); \ - \ - if (tmp_indices == NULL) { \ - _mesa_error_no_memory(__func__); \ - return NULL; \ - } \ - \ - for (unsigned i = 0; i < count; i++) \ - tmp_indices[start + i] = in[start + i] - min_index; \ - \ - return (void *)tmp_indices; \ -} - -REBASE(GLuint) -REBASE(GLushort) -REBASE(GLubyte) - - -/* Adjust primitives, indices and vertex definitions so that min_index - * becomes zero. There are lots of reasons for wanting to do this, eg: - * - * Software tnl: - * - any time min_index != 0, otherwise unused vertices lower than - * min_index will be transformed. - * - * Hardware tnl: - * - if ib != NULL and min_index != 0, otherwise vertices lower than - * min_index will be uploaded. Requires adjusting index values. - * - * - if ib == NULL and min_index != 0, just for convenience so this doesn't - * have to be handled within the driver. - * - * Hardware tnl with VBO support: - * - as above, but only when vertices are not (all?) in VBO's. - * - can't save time by trying to upload half a vbo - typically it is - * all or nothing. - */ -void t_rebase_prims(struct gl_context *ctx, - const struct tnl_vertex_array *arrays, - const struct _mesa_prim *prim, - GLuint nr_prims, - const struct _mesa_index_buffer *ib, - GLuint min_index, - GLuint max_index, - GLuint num_instances, - GLuint base_instance, - tnl_draw_func draw) -{ - struct gl_array_attributes tmp_attribs[VERT_ATTRIB_MAX]; - struct tnl_vertex_array tmp_arrays[VERT_ATTRIB_MAX]; - - struct _mesa_index_buffer tmp_ib; - struct _mesa_prim *tmp_prims = NULL; - void *tmp_indices = NULL; - GLuint i; - - assert(min_index != 0); - - if (0) - printf("%s %d..%d\n", __func__, min_index, max_index); - - /* XXX this path is disabled for now. - * There's rendering corruption in some apps when it's enabled. - */ - if (0 && ib && ctx->Extensions.ARB_draw_elements_base_vertex) { - /* If we can just tell the hardware or the TNL to interpret our indices - * with a different base, do so. - */ - tmp_prims = malloc(sizeof(*prim) * nr_prims); - - if (tmp_prims == NULL) { - _mesa_error_no_memory(__func__); - return; - } - - for (i = 0; i < nr_prims; i++) { - tmp_prims[i] = prim[i]; - tmp_prims[i].basevertex -= min_index; - } - - prim = tmp_prims; - } else if (ib) { - unsigned start = prim[0].start; - for (i = 1; i < nr_prims; i++) { - if (prim[i].start != start) { - if (0) { - printf("%s recursing due to mismatched start " - "(prim[0].start = %u vs. prim[%u].start = %u)\n", - __func__, start, i, prim[i].start); - } - - t_rebase_prims(ctx, arrays, &prim[0], i, ib, min_index, - max_index, num_instances, base_instance, draw); - t_rebase_prims(ctx, arrays, &prim[i], nr_prims - i, ib, min_index, - max_index, num_instances, base_instance, draw); - return; - } - } - - /* Unfortunately need to adjust each index individually. - */ - bool map_ib = false; - const void *ptr; - - if (ib->obj) { - if (!ib->obj->Mappings[MAP_INTERNAL].Pointer) { - ctx->Driver.MapBufferRange(ctx, 0, ib->obj->Size, GL_MAP_READ_BIT, - ib->obj, MAP_INTERNAL); - map_ib = true; - } - - ptr = ADD_POINTERS(ib->obj->Mappings[MAP_INTERNAL].Pointer, ib->ptr); - } else - ptr = ib->ptr; - - /* Some users might prefer it if we translated elements to GLuints here. - * Others wouldn't... - */ - switch (ib->index_size_shift) { - case 2: - tmp_indices = rebase_GLuint(ptr, start, ib->count, min_index); - break; - case 1: - tmp_indices = rebase_GLushort(ptr, start, ib->count, min_index); - break; - case 0: - tmp_indices = rebase_GLubyte(ptr, start, ib->count, min_index); - break; - } - - if (map_ib) - ctx->Driver.UnmapBuffer(ctx, ib->obj, MAP_INTERNAL); - - if (tmp_indices == NULL) - return; - - tmp_ib.obj = NULL; - tmp_ib.ptr = tmp_indices; - tmp_ib.count = ib->count; - tmp_ib.index_size_shift = ib->index_size_shift; - - ib = &tmp_ib; - } - else { - /* Otherwise the primitives need adjustment. */ - tmp_prims = malloc(sizeof(*prim) * nr_prims); - - if (tmp_prims == NULL) { - _mesa_error_no_memory(__func__); - return; - } - - for (i = 0; i < nr_prims; i++) { - /* If this fails, it could indicate an application error: */ - assert(prim[i].start >= min_index); - - tmp_prims[i] = prim[i]; - tmp_prims[i].start -= min_index; - } - - prim = tmp_prims; - } - - /* Just need to adjust the pointer values on each incoming array. - * This works for VBO and non-vbo rendering and shouldn't pesimize - * VBO-based upload schemes. However this may still not be a fast - * path for hardware tnl for VBO based rendering as most machines - * will be happier if you just specify a starting vertex value in - * each primitive. - * - * For drivers with hardware tnl, you only want to do this if you - * are forced to, eg non-VBO indexed rendering with start != 0. - */ - for (i = 0; i < VERT_ATTRIB_MAX; i++) { - tmp_attribs[i] = *(arrays[i].VertexAttrib); - tmp_arrays[i].BufferBinding = arrays[i].BufferBinding; - tmp_arrays[i].VertexAttrib = &tmp_attribs[i]; - if (arrays[i].BufferBinding->BufferObj) - tmp_attribs[i].RelativeOffset += - min_index * arrays[i].BufferBinding->Stride; - else - tmp_attribs[i].Ptr += min_index * arrays[i].BufferBinding->Stride; - } - - /* Re-issue the draw call. */ - draw(ctx, - tmp_arrays, - prim, - nr_prims, - ib, - GL_TRUE, - 0, - max_index - min_index, - num_instances, base_instance); - - free(tmp_indices); - free(tmp_prims); -} - - - diff --git a/src/mesa/tnl/t_rebase.h b/src/mesa/tnl/t_rebase.h deleted file mode 100644 index b596d93..0000000 --- a/src/mesa/tnl/t_rebase.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * mesa 3-D graphics library - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -#ifndef _T_REBASE_H_ -#define _T_REBASE_H_ - -#include "tnl.h" - -void t_rebase_prims( struct gl_context *ctx, - const struct tnl_vertex_array *arrays, - const struct _mesa_prim *prim, - GLuint nr_prims, - const struct _mesa_index_buffer *ib, - GLuint min_index, - GLuint max_index, - GLuint num_instances, - GLuint base_instance, - tnl_draw_func draw ); - -#endif diff --git a/src/mesa/tnl/t_split.c b/src/mesa/tnl/t_split.c deleted file mode 100644 index 3959e11..0000000 --- a/src/mesa/tnl/t_split.c +++ /dev/null @@ -1,162 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - * - * Authors: - * Keith Whitwell - */ - -/* Deal with hardware and/or swtnl maximums: - * - maximum number of vertices in buffer - * - maximum number of elements (maybe zero) - * - * The maximums may vary with opengl state (eg if a larger hardware - * vertex is required in this state, the maximum number of vertices - * may be smaller than in another state). - * - * We want buffer splitting to be a convenience function for the code - * actually drawing the primitives rather than a system-wide maximum, - * otherwise it is hard to avoid pessimism. - * - * For instance, if a driver has no hardware limits on vertex buffer - * dimensions, it would not ordinarily want to split vbos. But if - * there is an unexpected fallback, eg memory manager fails to upload - * textures, it will want to pass the drawing commands onto swtnl, - * which does have limitations. A convenience function allows swtnl - * to split the drawing and vbos internally without imposing its - * limitations on drivers which want to use it as a fallback path. - */ - -#include "main/glheader.h" -#include "main/mtypes.h" -#include "vbo/vbo.h" - -#include "t_split.h" - - -/* True if a primitive can be split without copying of vertices, false - * otherwise. - */ -GLboolean -_tnl_split_prim_inplace(GLenum mode, GLuint *first, GLuint *incr) -{ - switch (mode) { - case GL_POINTS: - *first = 1; - *incr = 1; - return GL_TRUE; - case GL_LINES: - *first = 2; - *incr = 2; - return GL_TRUE; - case GL_LINE_STRIP: - *first = 2; - *incr = 1; - return GL_TRUE; - case GL_TRIANGLES: - *first = 3; - *incr = 3; - return GL_TRUE; - case GL_TRIANGLE_STRIP: - *first = 3; - *incr = 1; - return GL_TRUE; - case GL_QUADS: - *first = 4; - *incr = 4; - return GL_TRUE; - case GL_QUAD_STRIP: - *first = 4; - *incr = 2; - return GL_TRUE; - default: - *first = 0; - *incr = 1; /* so that count % incr works */ - return GL_FALSE; - } -} - - - -void -_tnl_split_prims(struct gl_context *ctx, - const struct tnl_vertex_array arrays[], - const struct _mesa_prim *prim, - GLuint nr_prims, - const struct _mesa_index_buffer *ib, - GLuint min_index, - GLuint max_index, - GLuint num_instances, - GLuint base_instance, - tnl_draw_func draw, - const struct split_limits *limits) -{ - if (ib) { - if (limits->max_indices == 0) { - /* Could traverse the indices, re-emitting vertices in turn. - * But it's hard to see why this case would be needed - for - * software tnl, it is better to convert to non-indexed - * rendering after transformation is complete. Are there any devices - * with hardware tnl that cannot do indexed rendering? - * - * For now, this path is disabled. - */ - assert(0); - } - else if (max_index - min_index >= limits->max_verts) { - /* The vertex buffers are too large for hardware (or the - * swtnl module). Traverse the indices, re-emitting vertices - * in turn. Use a vertex cache to preserve some of the - * sharing from the original index list. - */ - _tnl_split_copy(ctx, arrays, prim, nr_prims, ib, draw, limits); - } - else if (ib->count > limits->max_indices) { - /* The index buffer is too large for hardware. Try to split - * on whole-primitive boundaries, otherwise try to split the - * individual primitives. - */ - _tnl_split_inplace(ctx, arrays, prim, nr_prims, ib, - num_instances, base_instance, draw, limits); - } - else { - /* Why were we called? */ - assert(0); - } - } - else { - if (max_index - min_index >= limits->max_verts) { - /* The vertex buffer is too large for hardware (or the swtnl - * module). Try to split on whole-primitive boundaries, - * otherwise try to split the individual primitives. - */ - _tnl_split_inplace(ctx, arrays, prim, nr_prims, ib, - num_instances, base_instance, draw, limits); - } - else { - /* Why were we called? */ - assert(0); - } - } -} - diff --git a/src/mesa/tnl/t_split.h b/src/mesa/tnl/t_split.h deleted file mode 100644 index 8f2d1ba..0000000 --- a/src/mesa/tnl/t_split.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * mesa 3-D graphics library - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -/** - * \brief VBO builder module datatypes and definitions. - * \author Keith Whitwell - */ - - -/** - * \mainpage The TNL splitter - * - * This is the private data used internally to the _tnl_split_prims() - * helper function. Nobody outside the _tnl_split* files needs to - * include or know about this structure. - */ - - -#ifndef _TNL_SPLIT_H -#define _TNL_SPLIT_H - -#include "tnl.h" - - -/* True if a primitive can be split without copying of vertices, false - * otherwise. - */ -GLboolean -_tnl_split_prim_inplace(GLenum mode, GLuint *first, GLuint *incr); - -void -_tnl_split_inplace(struct gl_context *ctx, - const struct tnl_vertex_array arrays[], - const struct _mesa_prim *prim, - GLuint nr_prims, - const struct _mesa_index_buffer *ib, - GLuint num_instances, - GLuint base_instance, - tnl_draw_func draw, - const struct split_limits *limits); - -/* Requires ib != NULL: - */ -void -_tnl_split_copy(struct gl_context *ctx, - const struct tnl_vertex_array arrays[], - const struct _mesa_prim *prim, - GLuint nr_prims, - const struct _mesa_index_buffer *ib, - tnl_draw_func draw, - const struct split_limits *limits); - -#endif diff --git a/src/mesa/tnl/t_split_copy.c b/src/mesa/tnl/t_split_copy.c deleted file mode 100644 index cee50fc..0000000 --- a/src/mesa/tnl/t_split_copy.c +++ /dev/null @@ -1,637 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - * - * Authors: - * Keith Whitwell - */ - -/* Split indexed primitives with per-vertex copying. - */ - -#include - -#include "main/glheader.h" -#include "main/bufferobj.h" - -#include "main/glformats.h" -#include "main/macros.h" -#include "main/mtypes.h" -#include "main/varray.h" -#include "vbo/vbo.h" - -#include "t_split.h" -#include "tnl.h" - - -#define ELT_TABLE_SIZE 16 - -/** - * Used for vertex-level splitting of indexed buffers. Note that - * non-indexed primitives may be converted to indexed in some cases - * (eg loops, fans) in order to use this splitting path. - */ -struct copy_context { - struct gl_context *ctx; - const struct tnl_vertex_array *array; - const struct _mesa_prim *prim; - GLuint nr_prims; - const struct _mesa_index_buffer *ib; - tnl_draw_func draw; - - const struct split_limits *limits; - - struct { - GLuint attr; - GLuint size; - const struct tnl_vertex_array *array; - const GLubyte *src_ptr; - - struct gl_vertex_buffer_binding dstbinding; - struct gl_array_attributes dstattribs; - - } varying[VERT_ATTRIB_MAX]; - GLuint nr_varying; - - struct tnl_vertex_array dstarray[VERT_ATTRIB_MAX]; - struct _mesa_index_buffer dstib; - - GLuint *translated_elt_buf; - const GLuint *srcelt; - - /** A baby hash table to avoid re-emitting (some) duplicate - * vertices when splitting indexed primitives. - */ - struct { - GLuint in; - GLuint out; - } vert_cache[ELT_TABLE_SIZE]; - - GLuint vertex_size; - GLubyte *dstbuf; - GLubyte *dstptr; /**< dstptr == dstbuf + dstelt_max * vertsize */ - GLuint dstbuf_size; /**< in vertices */ - GLuint dstbuf_nr; /**< count of emitted vertices, also the largest value - * in dstelt. Our MaxIndex. - */ - - GLuint *dstelt; - GLuint dstelt_nr; - GLuint dstelt_size; - -#define MAX_PRIM 32 - struct _mesa_prim dstprim[MAX_PRIM]; - GLuint dstprim_nr; -}; - - -/** - * Shallow copy one vertex array to another. - */ -static inline void -copy_vertex_array(struct tnl_vertex_array *dst, - const struct tnl_vertex_array *src) -{ - dst->VertexAttrib = src->VertexAttrib; - dst->BufferBinding = src->BufferBinding; -} - - -/** - * Starts returning true slightly before the buffer fills, to ensure - * that there is sufficient room for any remaining vertices to finish - * off the prim: - */ -static GLboolean -check_flush(struct copy_context *copy) -{ - GLenum mode = copy->dstprim[copy->dstprim_nr].mode; - - if (GL_TRIANGLE_STRIP == mode && - copy->dstelt_nr & 1) { /* see bug9962 */ - return GL_FALSE; - } - - if (copy->dstbuf_nr + 4 > copy->dstbuf_size) - return GL_TRUE; - - if (copy->dstelt_nr + 4 > copy->dstelt_size) - return GL_TRUE; - - return GL_FALSE; -} - - -/** - * Dump the parameters/info for a vbo->draw() call. - */ -static void -dump_draw_info(const struct tnl_vertex_array *arrays, - const struct _mesa_prim *prims, - GLuint nr_prims, - const struct _mesa_index_buffer *ib) -{ - GLuint i, j; - - printf("VBO Draw:\n"); - for (i = 0; i < nr_prims; i++) { - printf("Prim %u of %u\n", i, nr_prims); - printf(" Prim mode 0x%x\n", prims[i].mode); - printf(" IB: %p\n", (void*) ib); - for (j = 0; j < VERT_ATTRIB_MAX; j++) { - const struct tnl_vertex_array *array = &arrays[j]; - const struct gl_vertex_buffer_binding *binding - = array->BufferBinding; - const struct gl_array_attributes *attrib = array->VertexAttrib; - const GLubyte *ptr = _mesa_vertex_attrib_address(attrib, binding); - printf(" array %d at %p:\n", j, (void*) &arrays[j]); - printf(" ptr %p, size %d, type 0x%x, stride %d\n", - ptr, attrib->Format.Size, attrib->Format.Type, binding->Stride); - if (0) { - GLint k = prims[i].start + prims[i].count - 1; - GLfloat *last = (GLfloat *) (ptr + binding->Stride * k); - printf(" last: %f %f %f\n", - last[0], last[1], last[2]); - } - } - } -} - - -static void -flush(struct copy_context *copy) -{ - struct gl_context *ctx = copy->ctx; - GLuint i; - - /* Set some counters: - */ - copy->dstib.count = copy->dstelt_nr; - -#if 0 - dump_draw_info(copy->dstarray, - copy->dstprim, - copy->dstprim_nr, - ©->dstib); -#else - (void) dump_draw_info; -#endif - - copy->draw(ctx, - copy->dstarray, - copy->dstprim, - copy->dstprim_nr, - ©->dstib, - GL_TRUE, - 0, - copy->dstbuf_nr - 1, - 1, - 0); - - /* Reset all pointers: - */ - copy->dstprim_nr = 0; - copy->dstelt_nr = 0; - copy->dstbuf_nr = 0; - copy->dstptr = copy->dstbuf; - - /* Clear the vertex cache: - */ - for (i = 0; i < ELT_TABLE_SIZE; i++) - copy->vert_cache[i].in = ~0; -} - - -/** - * Called at begin of each primitive during replay. - */ -static void -begin(struct copy_context *copy, GLenum mode, GLboolean begin_flag) -{ - struct _mesa_prim *prim = ©->dstprim[copy->dstprim_nr]; - - prim->mode = mode; - prim->begin = begin_flag; -} - - -/** - * Use a hashtable to attempt to identify recently-emitted vertices - * and avoid re-emitting them. - */ -static GLuint -elt(struct copy_context *copy, GLuint elt_idx) -{ - GLuint elt = copy->srcelt[elt_idx] + copy->prim->basevertex; - GLuint slot = elt & (ELT_TABLE_SIZE-1); - - /* Look up the incoming element in the vertex cache. Re-emit if - * necessary. - */ - if (copy->vert_cache[slot].in != elt) { - GLubyte *csr = copy->dstptr; - GLuint i; - - for (i = 0; i < copy->nr_varying; i++) { - const struct tnl_vertex_array *srcarray = copy->varying[i].array; - const struct gl_vertex_buffer_binding* srcbinding - = srcarray->BufferBinding; - const GLubyte *srcptr - = copy->varying[i].src_ptr + elt * srcbinding->Stride; - - memcpy(csr, srcptr, copy->varying[i].size); - csr += copy->varying[i].size; - -#ifdef NAN_CHECK - if (srcarray->Format.Type == GL_FLOAT) { - GLuint k; - GLfloat *f = (GLfloat *) srcptr; - for (k = 0; k < srcarray->Size; k++) { - assert(!util_is_inf_or_nan(f[k])); - assert(f[k] <= 1.0e20 && f[k] >= -1.0e20); - } - } -#endif - - if (0) { - const GLuint *f = (const GLuint *)srcptr; - GLuint j; - printf(" varying %d: ", i); - for (j = 0; j < copy->varying[i].size / 4; j++) - printf("%x ", f[j]); - printf("\n"); - } - } - - copy->vert_cache[slot].in = elt; - copy->vert_cache[slot].out = copy->dstbuf_nr++; - copy->dstptr += copy->vertex_size; - - assert(csr == copy->dstptr); - assert(copy->dstptr == (copy->dstbuf + - copy->dstbuf_nr * copy->vertex_size)); - } - - copy->dstelt[copy->dstelt_nr++] = copy->vert_cache[slot].out; - return check_flush(copy); -} - - -/** - * Called at end of each primitive during replay. - */ -static void -end(struct copy_context *copy, GLboolean end_flag) -{ - struct _mesa_prim *prim = ©->dstprim[copy->dstprim_nr]; - - prim->end = end_flag; - prim->count = copy->dstelt_nr - prim->start; - - if (++copy->dstprim_nr == MAX_PRIM || check_flush(copy)) { - flush(copy); - } -} - - -static void -replay_elts(struct copy_context *copy) -{ - GLuint i, j, k; - GLboolean split; - - for (i = 0; i < copy->nr_prims; i++) { - const struct _mesa_prim *prim = ©->prim[i]; - const GLuint start = prim->start; - GLuint first, incr; - - switch (prim->mode) { - case GL_LINE_LOOP: - /* Convert to linestrip and emit the final vertex explicitly, - * but only in the resultant strip that requires it. - */ - j = 0; - while (j != prim->count) { - begin(copy, GL_LINE_STRIP, prim->begin && j == 0); - - for (split = GL_FALSE; j != prim->count && !split; j++) - split = elt(copy, start + j); - - if (j == prim->count) { - /* Done, emit final line. Split doesn't matter as - * it is always raised a bit early so we can emit - * the last verts if necessary! - */ - if (prim->end) - (void)elt(copy, start + 0); - - end(copy, prim->end); - } - else { - /* Wrap - */ - assert(split); - end(copy, 0); - j--; - } - } - break; - - case GL_TRIANGLE_FAN: - case GL_POLYGON: - j = 2; - while (j != prim->count) { - begin(copy, prim->mode, prim->begin && j == 0); - - split = elt(copy, start+0); - assert(!split); - - split = elt(copy, start+j-1); - assert(!split); - - for (; j != prim->count && !split; j++) - split = elt(copy, start+j); - - end(copy, prim->end && j == prim->count); - - if (j != prim->count) { - /* Wrapped the primitive, need to repeat some vertices: - */ - j -= 1; - } - } - break; - - default: - (void)_tnl_split_prim_inplace(prim->mode, &first, &incr); - - j = 0; - while (j != prim->count) { - - begin(copy, prim->mode, prim->begin && j == 0); - - split = 0; - for (k = 0; k < first; k++, j++) - split |= elt(copy, start+j); - - assert(!split); - - for (; j != prim->count && !split;) - for (k = 0; k < incr; k++, j++) - split |= elt(copy, start+j); - - end(copy, prim->end && j == prim->count); - - if (j != prim->count) { - /* Wrapped the primitive, need to repeat some vertices: - */ - assert(j > first - incr); - j -= (first - incr); - } - } - break; - } - } - - if (copy->dstprim_nr) - flush(copy); -} - - -static void -replay_init(struct copy_context *copy) -{ - struct gl_context *ctx = copy->ctx; - GLuint i; - GLuint offset; - const GLvoid *srcptr; - - /* Make a list of varying attributes and their vbo's. Also - * calculate vertex size. - */ - copy->vertex_size = 0; - for (i = 0; i < VERT_ATTRIB_MAX; i++) { - const struct tnl_vertex_array *array = ©->array[i]; - const struct gl_vertex_buffer_binding *binding = array->BufferBinding; - - if (binding->Stride == 0) { - copy_vertex_array(©->dstarray[i], array); - } - else { - const struct gl_array_attributes *attrib = array->VertexAttrib; - struct gl_buffer_object *vbo = binding->BufferObj; - const GLubyte *ptr = _mesa_vertex_attrib_address(attrib, binding); - GLuint j = copy->nr_varying++; - - copy->varying[j].attr = i; - copy->varying[j].array = ©->array[i]; - copy->varying[j].size = attrib->Format._ElementSize; - copy->vertex_size += attrib->Format._ElementSize; - - if (vbo) { - if (!_mesa_bufferobj_mapped(vbo, MAP_INTERNAL)) { - ctx->Driver.MapBufferRange(ctx, 0, vbo->Size, GL_MAP_READ_BIT, vbo, - MAP_INTERNAL); - } - - copy->varying[j].src_ptr = - ADD_POINTERS(vbo->Mappings[MAP_INTERNAL].Pointer, ptr); - } else { - copy->varying[j].src_ptr = ptr; - } - - copy->dstarray[i].VertexAttrib = ©->varying[j].dstattribs; - copy->dstarray[i].BufferBinding = ©->varying[j].dstbinding; - } - } - - /* There must always be an index buffer. Currently require the - * caller convert non-indexed prims to indexed. Could alternately - * do it internally. - */ - if (copy->ib->obj) { - if (!_mesa_bufferobj_mapped(copy->ib->obj, MAP_INTERNAL)) - ctx->Driver.MapBufferRange(ctx, 0, copy->ib->obj->Size, GL_MAP_READ_BIT, - copy->ib->obj, MAP_INTERNAL); - - srcptr = (const GLubyte *) - ADD_POINTERS(copy->ib->obj->Mappings[MAP_INTERNAL].Pointer, - copy->ib->ptr); - } else - srcptr = copy->ib->ptr; - - switch (copy->ib->index_size_shift) { - case 0: - copy->translated_elt_buf = malloc(sizeof(GLuint) * copy->ib->count); - copy->srcelt = copy->translated_elt_buf; - - for (i = 0; i < copy->ib->count; i++) - copy->translated_elt_buf[i] = ((const GLubyte *)srcptr)[i]; - break; - - case 1: - copy->translated_elt_buf = malloc(sizeof(GLuint) * copy->ib->count); - copy->srcelt = copy->translated_elt_buf; - - for (i = 0; i < copy->ib->count; i++) - copy->translated_elt_buf[i] = ((const GLushort *)srcptr)[i]; - break; - - case 2: - copy->translated_elt_buf = NULL; - copy->srcelt = (const GLuint *)srcptr; - break; - } - - /* Figure out the maximum allowed vertex buffer size: - */ - if (copy->vertex_size * copy->limits->max_verts <= copy->limits->max_vb_size) { - copy->dstbuf_size = copy->limits->max_verts; - } - else { - copy->dstbuf_size = copy->limits->max_vb_size / copy->vertex_size; - } - - /* Allocate an output vertex buffer: - * - * XXX: This should be a VBO! - */ - copy->dstbuf = malloc(copy->dstbuf_size * copy->vertex_size); - copy->dstptr = copy->dstbuf; - - /* Setup new vertex arrays to point into the output buffer: - */ - for (offset = 0, i = 0; i < copy->nr_varying; i++) { - const struct tnl_vertex_array *src = copy->varying[i].array; - const struct gl_array_attributes *srcattr = src->VertexAttrib; - struct tnl_vertex_array *dst = ©->dstarray[copy->varying[i].attr]; - struct gl_vertex_buffer_binding *dstbind = ©->varying[i].dstbinding; - struct gl_array_attributes *dstattr = ©->varying[i].dstattribs; - - dstattr->Format = srcattr->Format; - dstattr->Ptr = copy->dstbuf + offset; - dstbind->Stride = copy->vertex_size; - dstbind->BufferObj = NULL; - dst->BufferBinding = dstbind; - dst->VertexAttrib = dstattr; - - offset += copy->varying[i].size; - } - - /* Allocate an output element list: - */ - copy->dstelt_size = MIN2(65536, copy->ib->count * 2 + 3); - copy->dstelt_size = MIN2(copy->dstelt_size, copy->limits->max_indices); - copy->dstelt = malloc(sizeof(GLuint) * copy->dstelt_size); - copy->dstelt_nr = 0; - - /* Setup the new index buffer to point to the allocated element - * list: - */ - copy->dstib.count = 0; /* duplicates dstelt_nr */ - copy->dstib.index_size_shift = 2; - copy->dstib.obj = NULL; - copy->dstib.ptr = copy->dstelt; -} - - -/** - * Free up everything allocated during split/replay. - */ -static void -replay_finish(struct copy_context *copy) -{ - struct gl_context *ctx = copy->ctx; - GLuint i; - - /* Free our vertex and index buffers */ - free(copy->translated_elt_buf); - free(copy->dstbuf); - free(copy->dstelt); - - /* Unmap VBO's */ - for (i = 0; i < copy->nr_varying; i++) { - struct gl_buffer_object *vbo = - copy->varying[i].array->BufferBinding->BufferObj; - if (vbo && _mesa_bufferobj_mapped(vbo, MAP_INTERNAL)) - ctx->Driver.UnmapBuffer(ctx, vbo, MAP_INTERNAL); - } - - /* Unmap index buffer */ - if (copy->ib->obj && - _mesa_bufferobj_mapped(copy->ib->obj, MAP_INTERNAL)) { - ctx->Driver.UnmapBuffer(ctx, copy->ib->obj, MAP_INTERNAL); - } -} - - -/** - * Split VBO into smaller pieces, draw the pieces. - */ -void -_tnl_split_copy(struct gl_context *ctx, - const struct tnl_vertex_array *arrays, - const struct _mesa_prim *prim, - GLuint nr_prims, - const struct _mesa_index_buffer *ib, - tnl_draw_func draw, - const struct split_limits *limits) -{ - struct copy_context copy; - GLuint i, this_nr_prims; - - for (i = 0; i < nr_prims;) { - /* Our SW TNL pipeline doesn't handle basevertex yet, so bind_indices - * will rebase the elements to the basevertex, and we'll only - * emit strings of prims with the same basevertex in one draw call. - */ - for (this_nr_prims = 1; i + this_nr_prims < nr_prims; - this_nr_prims++) { - if (prim[i].basevertex != prim[i + this_nr_prims].basevertex) - break; - } - - memset(©, 0, sizeof(copy)); - - /* Require indexed primitives: - */ - assert(ib); - - copy.ctx = ctx; - copy.array = arrays; - copy.prim = &prim[i]; - copy.nr_prims = this_nr_prims; - copy.ib = ib; - copy.draw = draw; - copy.limits = limits; - - /* Clear the vertex cache: - */ - for (i = 0; i < ELT_TABLE_SIZE; i++) - copy.vert_cache[i].in = ~0; - - replay_init(©); - replay_elts(©); - replay_finish(©); - } -} diff --git a/src/mesa/tnl/t_split_inplace.c b/src/mesa/tnl/t_split_inplace.c deleted file mode 100644 index 126f6fd..0000000 --- a/src/mesa/tnl/t_split_inplace.c +++ /dev/null @@ -1,296 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - * - * Authors: - * Keith Whitwell - */ - - -#include "main/mtypes.h" -#include "main/macros.h" -#include "main/enums.h" -#include "vbo/vbo.h" - -#include "t_split.h" - - -#define MAX_PRIM 32 - -/* Used for splitting without copying. No attempt is made to handle - * too large indexed vertex buffers: In general you need to copy to do - * that. - */ -struct split_context { - struct gl_context *ctx; - const struct tnl_vertex_array *array; - const struct _mesa_prim *prim; - GLuint nr_prims; - const struct _mesa_index_buffer *ib; - GLuint min_index; - GLuint max_index; - GLuint num_instances; - GLuint base_instance; - tnl_draw_func draw; - - const struct split_limits *limits; - GLuint limit; - - struct _mesa_prim dstprim[MAX_PRIM]; - GLuint dstprim_nr; -}; - - - - -static void -flush_vertex( struct split_context *split) -{ - struct gl_context *ctx = split->ctx; - struct _mesa_index_buffer ib; - GLuint i; - - if (!split->dstprim_nr) - return; - - if (split->ib) { - ib = *split->ib; - - ib.count = split->max_index - split->min_index + 1; - ib.ptr = (const void *)((const char *)ib.ptr + - (split->min_index << ib.index_size_shift)); - - /* Rebase the primitives to save index buffer entries. */ - for (i = 0; i < split->dstprim_nr; i++) - split->dstprim[i].start -= split->min_index; - } - - assert(split->max_index >= split->min_index); - - split->draw(ctx, - split->array, - split->dstprim, - split->dstprim_nr, - split->ib ? &ib : NULL, - !split->ib, - split->min_index, - split->max_index, - split->num_instances, - split->base_instance); - - split->dstprim_nr = 0; - split->min_index = ~0; - split->max_index = 0; -} - - -static struct _mesa_prim * -next_outprim(struct split_context *split) -{ - if (split->dstprim_nr == MAX_PRIM-1) { - flush_vertex(split); - } - - { - struct _mesa_prim *prim = &split->dstprim[split->dstprim_nr++]; - memset(prim, 0, sizeof(*prim)); - return prim; - } -} - - -static void -update_index_bounds(struct split_context *split, - const struct _mesa_prim *prim) -{ - split->min_index = MIN2(split->min_index, prim->start); - split->max_index = MAX2(split->max_index, prim->start + prim->count - 1); -} - - -/* Return the maximum amount of vertices that can be emitted for a - * primitive starting at 'prim->start', depending on the previous - * index bounds. - */ -static GLuint -get_max_vertices(struct split_context *split, - const struct _mesa_prim *prim) -{ - if ((prim->start > split->min_index && - prim->start - split->min_index >= split->limit) || - (prim->start < split->max_index && - split->max_index - prim->start >= split->limit)) - /* "prim" starts too far away from the old range. */ - return 0; - - return MIN2(split->min_index, prim->start) + split->limit - prim->start; -} - - -/* Break large primitives into smaller ones. If not possible, convert - * the primitive to indexed and pass to split_elts(). - */ -static void -split_prims(struct split_context *split) -{ - GLuint i; - - for (i = 0; i < split->nr_prims; i++) { - const struct _mesa_prim *prim = &split->prim[i]; - GLuint first, incr; - GLboolean split_inplace = - _tnl_split_prim_inplace(prim->mode, &first, &incr); - GLuint available = get_max_vertices(split, prim); - GLuint count = prim->count - (prim->count - first) % incr; - - if (prim->count < first) - continue; - - if ((available < count && !split_inplace) || - (available < first && split_inplace)) { - flush_vertex(split); - available = get_max_vertices(split, prim); - } - - if (available >= count) { - struct _mesa_prim *outprim = next_outprim(split); - - *outprim = *prim; - update_index_bounds(split, outprim); - } - else if (split_inplace) { - GLuint j, nr; - - for (j = 0 ; j < count ;) { - GLuint remaining = count - j; - struct _mesa_prim *outprim = next_outprim(split); - - nr = MIN2(available, remaining); - nr -= (nr - first) % incr; - - outprim->mode = prim->mode; - outprim->begin = (j == 0 && prim->begin); - outprim->end = (nr == remaining && prim->end); - outprim->start = prim->start + j; - outprim->count = nr; - - update_index_bounds(split, outprim); - - if (nr == remaining) { - /* Finished */ - j += nr; - } - else { - /* Wrapped the primitive */ - j += nr - (first - incr); - flush_vertex(split); - available = get_max_vertices(split, prim); - } - } - } - else if (split->ib == NULL) { - /* XXX: could at least send the first max_verts off from the - * inplace buffers. - */ - - /* else convert to indexed primitive and pass to split_elts, - * which will do the necessary copying and turn it back into a - * vertex primitive for rendering... - */ - struct _mesa_index_buffer ib; - struct _mesa_prim tmpprim; - GLuint *elts = malloc(count * sizeof(GLuint)); - GLuint j; - - for (j = 0; j < count; j++) - elts[j] = prim->start + j; - - ib.count = count; - ib.index_size_shift = 2; - ib.obj = NULL; - ib.ptr = elts; - - tmpprim = *prim; - tmpprim.start = 0; - tmpprim.count = count; - - flush_vertex(split); - - _tnl_split_copy(split->ctx, - split->array, - &tmpprim, 1, - &ib, - split->draw, - split->limits); - - free(elts); - } - else { - flush_vertex(split); - - _tnl_split_copy(split->ctx, - split->array, - prim, 1, - split->ib, - split->draw, - split->limits); - } - } - - flush_vertex(split); -} - - -void -_tnl_split_inplace(struct gl_context *ctx, - const struct tnl_vertex_array *arrays, - const struct _mesa_prim *prim, - GLuint nr_prims, - const struct _mesa_index_buffer *ib, - GLuint num_instances, - GLuint base_instance, - tnl_draw_func draw, - const struct split_limits *limits) -{ - struct split_context split; - - memset(&split, 0, sizeof(split)); - - split.ctx = ctx; - split.array = arrays; - split.prim = prim; - split.nr_prims = nr_prims; - split.ib = ib; - - /* Empty interval, makes calculations simpler. */ - split.min_index = ~0; - split.max_index = 0; - split.num_instances = num_instances; - split.base_instance = base_instance; - - split.draw = draw; - split.limits = limits; - split.limit = ib ? limits->max_indices : limits->max_verts; - - split_prims(&split); -} diff --git a/src/mesa/tnl/t_vb_cliptmp.h b/src/mesa/tnl/t_vb_cliptmp.h deleted file mode 100644 index 9f2d516..0000000 --- a/src/mesa/tnl/t_vb_cliptmp.h +++ /dev/null @@ -1,317 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - * - * Authors: - * Keith Whitwell - */ - - -#define CLIP_DOTPROD(K, A, B, C, D) X(K)*A + Y(K)*B + Z(K)*C + W(K)*D - -#define POLY_CLIP( PLANE_BIT, A, B, C, D ) \ -do { \ - if (mask & PLANE_BIT) { \ - GLuint idxPrev = inlist[0]; \ - GLfloat dpPrev = CLIP_DOTPROD(idxPrev, A, B, C, D ); \ - GLuint outcount = 0; \ - GLuint i; \ - \ - inlist[n] = inlist[0]; /* prevent rotation of vertices */ \ - for (i = 1; i <= n; i++) { \ - GLuint idx = inlist[i]; \ - GLfloat dp = CLIP_DOTPROD(idx, A, B, C, D ); \ - \ - if (dpPrev >= 0.0f) { \ - outlist[outcount++] = idxPrev; \ - } \ - \ - if (DIFFERENT_SIGNS(dp, dpPrev)) { \ - if (dp < 0.0f) { \ - /* Going out of bounds. Avoid division by zero as we \ - * know dp != dpPrev from DIFFERENT_SIGNS, above. \ - */ \ - GLfloat t = dp / (dp - dpPrev); \ - INTERP_4F( t, coord[newvert], coord[idx], coord[idxPrev]); \ - interp( ctx, t, newvert, idx, idxPrev, GL_TRUE ); \ - } else { \ - /* Coming back in. \ - */ \ - GLfloat t = dpPrev / (dpPrev - dp); \ - INTERP_4F( t, coord[newvert], coord[idxPrev], coord[idx]); \ - interp( ctx, t, newvert, idxPrev, idx, GL_FALSE ); \ - } \ - outlist[outcount++] = newvert++; \ - } \ - \ - idxPrev = idx; \ - dpPrev = dp; \ - } \ - \ - if (outcount < 3) \ - return; \ - \ - { \ - GLuint *tmp = inlist; \ - inlist = outlist; \ - outlist = tmp; \ - n = outcount; \ - } \ - } \ -} while (0) - - -#define LINE_CLIP(PLANE_BIT, A, B, C, D ) \ -do { \ - if (mask & PLANE_BIT) { \ - const GLfloat dp0 = CLIP_DOTPROD( v0, A, B, C, D ); \ - const GLfloat dp1 = CLIP_DOTPROD( v1, A, B, C, D ); \ - const GLboolean neg_dp0 = dp0 < 0.0f; \ - const GLboolean neg_dp1 = dp1 < 0.0f; \ - \ - /* For regular clipping, we know from the clipmask that one \ - * (or both) of these must be negative (otherwise we wouldn't \ - * be here). \ - * For userclip, there is only a single bit for all active \ - * planes, so we can end up here when there is nothing to do, \ - * hence the second < 0.0f test: \ - */ \ - if (neg_dp0 && neg_dp1) \ - return; /* both vertices outside clip plane: discard */ \ - \ - if (neg_dp1) { \ - GLfloat t = dp1 / (dp1 - dp0); \ - if (t > t1) t1 = t; \ - } else if (neg_dp0) { \ - GLfloat t = dp0 / (dp0 - dp1); \ - if (t > t0) t0 = t; \ - } \ - if (t0 + t1 >= 1.0) \ - return; /* discard */ \ - } \ -} while (0) - - - -/* Clip a line against the viewport and user clip planes. - */ -static inline void -TAG(clip_line)( struct gl_context *ctx, GLuint v0, GLuint v1, GLubyte mask ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &tnl->vb; - tnl_interp_func interp = tnl->Driver.Render.Interp; - GLfloat (*coord)[4] = VB->ClipPtr->data; - GLuint newvert = VB->Count; - GLfloat t0 = 0; - GLfloat t1 = 0; - const GLuint v0_orig = v0; - - if (mask & CLIP_FRUSTUM_BITS) { - LINE_CLIP( CLIP_RIGHT_BIT, -1, 0, 0, 1 ); - LINE_CLIP( CLIP_LEFT_BIT, 1, 0, 0, 1 ); - LINE_CLIP( CLIP_TOP_BIT, 0, -1, 0, 1 ); - LINE_CLIP( CLIP_BOTTOM_BIT, 0, 1, 0, 1 ); - LINE_CLIP( CLIP_FAR_BIT, 0, 0, -1, 1 ); - LINE_CLIP( CLIP_NEAR_BIT, 0, 0, 1, 1 ); - } - - if (mask & CLIP_USER_BIT) { - GLbitfield enabled = ctx->Transform.ClipPlanesEnabled; - while (enabled) { - const int p = u_bit_scan(&enabled); - const GLfloat a = ctx->Transform._ClipUserPlane[p][0]; - const GLfloat b = ctx->Transform._ClipUserPlane[p][1]; - const GLfloat c = ctx->Transform._ClipUserPlane[p][2]; - const GLfloat d = ctx->Transform._ClipUserPlane[p][3]; - LINE_CLIP( CLIP_USER_BIT, a, b, c, d ); - } - } - - if (VB->ClipMask[v0]) { - INTERP_4F( t0, coord[newvert], coord[v0], coord[v1] ); - interp( ctx, t0, newvert, v0, v1, GL_FALSE ); - v0 = newvert; - newvert++; - } - else { - assert(t0 == 0.0); - } - - /* Note: we need to use vertex v0_orig when computing the new - * interpolated/clipped vertex position, not the current v0 which - * may have got set when we clipped the other end of the line! - */ - if (VB->ClipMask[v1]) { - INTERP_4F( t1, coord[newvert], coord[v1], coord[v0_orig] ); - interp( ctx, t1, newvert, v1, v0_orig, GL_FALSE ); - - if (ctx->Light.ShadeModel == GL_FLAT) - tnl->Driver.Render.CopyPV( ctx, newvert, v1 ); - - v1 = newvert; - - newvert++; - } - else { - assert(t1 == 0.0); - } - - tnl->Driver.Render.ClippedLine( ctx, v0, v1 ); -} - - -/* Clip a triangle against the viewport and user clip planes. - */ -static inline void -TAG(clip_tri)( struct gl_context *ctx, GLuint v0, GLuint v1, GLuint v2, GLubyte mask ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &tnl->vb; - tnl_interp_func interp = tnl->Driver.Render.Interp; - GLuint newvert = VB->Count; - GLfloat (*coord)[4] = VB->ClipPtr->data; - GLuint pv = v2; - GLuint vlist[2][MAX_CLIPPED_VERTICES]; - GLuint *inlist = vlist[0], *outlist = vlist[1]; - GLuint n = 3; - - ASSIGN_3V(inlist, v2, v0, v1 ); /* pv rotated to slot zero */ - - if (0) { - /* print pre-clip vertex coords */ - GLuint i, j; - printf("pre clip:\n"); - for (i = 0; i < n; i++) { - j = inlist[i]; - printf(" %u: %u: %f, %f, %f, %f\n", - i, j, - coord[j][0], coord[j][1], coord[j][2], coord[j][3]); - assert(!util_is_inf_or_nan(coord[j][0])); - assert(!util_is_inf_or_nan(coord[j][1])); - assert(!util_is_inf_or_nan(coord[j][2])); - assert(!util_is_inf_or_nan(coord[j][3])); - } - } - - - if (mask & CLIP_FRUSTUM_BITS) { - POLY_CLIP( CLIP_RIGHT_BIT, -1, 0, 0, 1 ); - POLY_CLIP( CLIP_LEFT_BIT, 1, 0, 0, 1 ); - POLY_CLIP( CLIP_TOP_BIT, 0, -1, 0, 1 ); - POLY_CLIP( CLIP_BOTTOM_BIT, 0, 1, 0, 1 ); - POLY_CLIP( CLIP_FAR_BIT, 0, 0, -1, 1 ); - POLY_CLIP( CLIP_NEAR_BIT, 0, 0, 1, 1 ); - } - - if (mask & CLIP_USER_BIT) { - GLbitfield enabled = ctx->Transform.ClipPlanesEnabled; - while (enabled) { - const int p = u_bit_scan(&enabled); - const GLfloat a = ctx->Transform._ClipUserPlane[p][0]; - const GLfloat b = ctx->Transform._ClipUserPlane[p][1]; - const GLfloat c = ctx->Transform._ClipUserPlane[p][2]; - const GLfloat d = ctx->Transform._ClipUserPlane[p][3]; - POLY_CLIP( CLIP_USER_BIT, a, b, c, d ); - } - } - - if (ctx->Light.ShadeModel == GL_FLAT) { - if (pv != inlist[0]) { - assert( inlist[0] >= VB->Count ); - tnl->Driver.Render.CopyPV( ctx, inlist[0], pv ); - } - } - - if (0) { - /* print post-clip vertex coords */ - GLuint i, j; - printf("post clip:\n"); - for (i = 0; i < n; i++) { - j = inlist[i]; - printf(" %u: %u: %f, %f, %f, %f\n", - i, j, - coord[j][0], coord[j][1], coord[j][2], coord[j][3]); - } - } - - tnl->Driver.Render.ClippedPolygon( ctx, inlist, n ); -} - - -/* Clip a quad against the viewport and user clip planes. - */ -static inline void -TAG(clip_quad)( struct gl_context *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3, - GLubyte mask ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &tnl->vb; - tnl_interp_func interp = tnl->Driver.Render.Interp; - GLuint newvert = VB->Count; - GLfloat (*coord)[4] = VB->ClipPtr->data; - GLuint pv = v3; - GLuint vlist[2][MAX_CLIPPED_VERTICES]; - GLuint *inlist = vlist[0], *outlist = vlist[1]; - GLuint n = 4; - - ASSIGN_4V(inlist, v3, v0, v1, v2 ); /* pv rotated to slot zero */ - - if (mask & CLIP_FRUSTUM_BITS) { - POLY_CLIP( CLIP_RIGHT_BIT, -1, 0, 0, 1 ); - POLY_CLIP( CLIP_LEFT_BIT, 1, 0, 0, 1 ); - POLY_CLIP( CLIP_TOP_BIT, 0, -1, 0, 1 ); - POLY_CLIP( CLIP_BOTTOM_BIT, 0, 1, 0, 1 ); - POLY_CLIP( CLIP_FAR_BIT, 0, 0, -1, 1 ); - POLY_CLIP( CLIP_NEAR_BIT, 0, 0, 1, 1 ); - } - - if (mask & CLIP_USER_BIT) { - GLbitfield enabled = ctx->Transform.ClipPlanesEnabled; - while (enabled) { - const int p = u_bit_scan(&enabled); - const GLfloat a = ctx->Transform._ClipUserPlane[p][0]; - const GLfloat b = ctx->Transform._ClipUserPlane[p][1]; - const GLfloat c = ctx->Transform._ClipUserPlane[p][2]; - const GLfloat d = ctx->Transform._ClipUserPlane[p][3]; - POLY_CLIP( CLIP_USER_BIT, a, b, c, d ); - } - } - - if (ctx->Light.ShadeModel == GL_FLAT) { - if (pv != inlist[0]) { - assert( inlist[0] >= VB->Count ); - tnl->Driver.Render.CopyPV( ctx, inlist[0], pv ); - } - } - - tnl->Driver.Render.ClippedPolygon( ctx, inlist, n ); -} - -#undef W -#undef Z -#undef Y -#undef X -#undef SIZE -#undef TAG -#undef POLY_CLIP -#undef LINE_CLIP diff --git a/src/mesa/tnl/t_vb_fog.c b/src/mesa/tnl/t_vb_fog.c deleted file mode 100644 index 6c95006..0000000 --- a/src/mesa/tnl/t_vb_fog.c +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - * - * Authors: - * Keith Whitwell - */ - - -#include "c99_math.h" -#include "main/errors.h" -#include "main/glheader.h" -#include "main/macros.h" - -#include "main/mtypes.h" - -#include "math/m_xform.h" - -#include "t_context.h" -#include "t_pipeline.h" - - -struct fog_stage_data { - GLvector4f fogcoord; /* has actual storage allocated */ -}; - -#define FOG_STAGE_DATA(stage) ((struct fog_stage_data *)stage->privatePtr) - -#define FOG_EXP_TABLE_SIZE 256 -#define FOG_MAX (10.0F) -#define EXP_FOG_MAX .0006595F -#define FOG_INCR (FOG_MAX/FOG_EXP_TABLE_SIZE) -static GLfloat exp_table[FOG_EXP_TABLE_SIZE]; -static GLfloat inited = 0; - -#if 1 -#define NEG_EXP( result, narg ) \ -do { \ - GLfloat f = (GLfloat) (narg * (1.0F / FOG_INCR)); \ - GLint k = (GLint) f; \ - if (k > FOG_EXP_TABLE_SIZE-2) \ - result = (GLfloat) EXP_FOG_MAX; \ - else \ - result = exp_table[k] + (f-k)*(exp_table[k+1]-exp_table[k]); \ -} while (0) -#else -#define NEG_EXP( result, narg ) \ -do { \ - result = exp(-narg); \ -} while (0) -#endif - - -/** - * Initialize the exp_table[] lookup table for approximating exp(). - */ -static void -init_static_data( void ) -{ - GLfloat f = 0.0F; - GLint i = 0; - for ( ; i < FOG_EXP_TABLE_SIZE ; i++, f += FOG_INCR) { - exp_table[i] = expf(-f); - } - inited = 1; -} - - -/** - * Compute per-vertex fog blend factors from fog coordinates by - * evaluating the GL_LINEAR, GL_EXP or GL_EXP2 fog function. - * Fog coordinates are distances from the eye (typically between the - * near and far clip plane distances). - * Note that fogcoords may be negative, if eye z is source absolute - * value must be taken earlier. - * Fog blend factors are in the range [0,1]. - */ -static void -compute_fog_blend_factors(struct gl_context *ctx, GLvector4f *out, const GLvector4f *in) -{ - GLfloat end = ctx->Fog.End; - GLfloat *v = in->start; - GLuint stride = in->stride; - GLuint n = in->count; - GLfloat (*data)[4] = out->data; - GLfloat d; - GLuint i; - - out->count = in->count; - - switch (ctx->Fog.Mode) { - case GL_LINEAR: - if (ctx->Fog.Start == ctx->Fog.End) - d = 1.0F; - else - d = 1.0F / (ctx->Fog.End - ctx->Fog.Start); - for ( i = 0 ; i < n ; i++, STRIDE_F(v, stride)) { - const GLfloat z = *v; - GLfloat f = (end - z) * d; - data[i][0] = CLAMP(f, 0.0F, 1.0F); - } - break; - case GL_EXP: - d = ctx->Fog.Density; - for ( i = 0 ; i < n ; i++, STRIDE_F(v,stride)) { - const GLfloat z = *v; - NEG_EXP( data[i][0], d * z ); - } - break; - case GL_EXP2: - d = ctx->Fog.Density*ctx->Fog.Density; - for ( i = 0 ; i < n ; i++, STRIDE_F(v, stride)) { - const GLfloat z = *v; - NEG_EXP( data[i][0], d * z * z ); - } - break; - default: - _mesa_problem(ctx, "Bad fog mode in make_fog_coord"); - return; - } -} - - -static GLboolean -run_fog_stage(struct gl_context *ctx, struct tnl_pipeline_stage *stage) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &tnl->vb; - struct fog_stage_data *store = FOG_STAGE_DATA(stage); - GLvector4f *input; - - - if (!ctx->Fog.Enabled) - return GL_TRUE; - - if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT && !ctx->VertexProgram._Current) { - GLuint i; - GLfloat *coord; - /* Fog is computed from vertex or fragment Z values */ - /* source = VB->AttribPtr[_TNL_ATTRIB_POS] or VB->EyePtr coords */ - /* dest = VB->AttribPtr[_TNL_ATTRIB_FOG] = fog stage private storage */ - VB->AttribPtr[_TNL_ATTRIB_FOG] = &store->fogcoord; - - if (!ctx->_NeedEyeCoords) { - /* compute fog coords from object coords */ - const GLfloat *m = ctx->ModelviewMatrixStack.Top->m; - GLfloat plane[4]; - - /* Use this to store calculated eye z values: - */ - input = &store->fogcoord; - - plane[0] = m[2]; - plane[1] = m[6]; - plane[2] = m[10]; - plane[3] = m[14]; - /* Full eye coords weren't required, just calculate the - * eye Z values. - */ - _mesa_dotprod_tab[VB->AttribPtr[_TNL_ATTRIB_POS]->size] - ( (GLfloat *) input->data, - 4 * sizeof(GLfloat), - VB->AttribPtr[_TNL_ATTRIB_POS], plane ); - - input->count = VB->AttribPtr[_TNL_ATTRIB_POS]->count; - - /* make sure coords are really positive - NOTE should avoid going through array twice */ - coord = input->start; - for (i = 0; i < input->count; i++) { - *coord = fabsf(*coord); - STRIDE_F(coord, input->stride); - } - } - else { - /* fog coordinates = eye Z coordinates - need to copy for ABS */ - input = &store->fogcoord; - - if (VB->EyePtr->size < 2) - _mesa_vector4f_clean_elem( VB->EyePtr, VB->Count, 2 ); - - input->stride = 4 * sizeof(GLfloat); - input->count = VB->EyePtr->count; - coord = VB->EyePtr->start; - for (i = 0 ; i < VB->EyePtr->count; i++) { - input->data[i][0] = fabsf(coord[2]); - STRIDE_F(coord, VB->EyePtr->stride); - } - } - } - else { - /* use glFogCoord() coordinates */ - input = VB->AttribPtr[_TNL_ATTRIB_FOG]; /* source data */ - - /* input->count may be one if glFogCoord was only called once - * before glBegin. But we need to compute fog for all vertices. - */ - input->count = VB->AttribPtr[_TNL_ATTRIB_POS]->count; - - VB->AttribPtr[_TNL_ATTRIB_FOG] = &store->fogcoord; /* dest data */ - } - - if (tnl->_DoVertexFog) { - /* compute blend factors from fog coordinates */ - compute_fog_blend_factors( ctx, VB->AttribPtr[_TNL_ATTRIB_FOG], input ); - } - else { - /* results = incoming fog coords (compute fog per-fragment later) */ - VB->AttribPtr[_TNL_ATTRIB_FOG] = input; - } - - return GL_TRUE; -} - - - -/* Called the first time stage->run() is invoked. - */ -static GLboolean -alloc_fog_data(struct gl_context *ctx, struct tnl_pipeline_stage *stage) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct fog_stage_data *store; - stage->privatePtr = malloc(sizeof(*store)); - store = FOG_STAGE_DATA(stage); - if (!store) - return GL_FALSE; - - _mesa_vector4f_alloc( &store->fogcoord, 0, tnl->vb.Size, 32 ); - - if (!inited) - init_static_data(); - - return GL_TRUE; -} - - -static void -free_fog_data(struct tnl_pipeline_stage *stage) -{ - struct fog_stage_data *store = FOG_STAGE_DATA(stage); - if (store) { - _mesa_vector4f_free( &store->fogcoord ); - free( store ); - stage->privatePtr = NULL; - } -} - - -const struct tnl_pipeline_stage _tnl_fog_coordinate_stage = -{ - "build fog coordinates", /* name */ - NULL, /* private_data */ - alloc_fog_data, /* dtr */ - free_fog_data, /* dtr */ - NULL, /* check */ - run_fog_stage /* run -- initially set to init. */ -}; diff --git a/src/mesa/tnl/t_vb_light.c b/src/mesa/tnl/t_vb_light.c deleted file mode 100644 index 15c8b0e..0000000 --- a/src/mesa/tnl/t_vb_light.c +++ /dev/null @@ -1,477 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -#include "c99_math.h" -#include "main/glheader.h" -#include "main/light.h" -#include "main/macros.h" - -#include "util/simple_list.h" -#include "main/mtypes.h" - -#include "math/m_translate.h" - -#include "util/bitscan.h" - -#include "t_context.h" -#include "t_pipeline.h" -#include "tnl.h" - -#define LIGHT_TWOSIDE 0x1 -#define LIGHT_MATERIAL 0x2 -#define MAX_LIGHT_FUNC 0x4 - -typedef void (*light_func)( struct gl_context *ctx, - struct vertex_buffer *VB, - struct tnl_pipeline_stage *stage, - GLvector4f *input ); - -/** - * Information for updating current material attributes from vertex color, - * for GL_COLOR_MATERIAL. - */ -struct material_cursor { - const GLfloat *ptr; /* points to src vertex color (in VB array) */ - GLuint stride; /* stride to next vertex color (bytes) */ - GLfloat *current; /* points to material attribute to update */ - GLuint size; /* vertex/color size: 1, 2, 3 or 4 */ -}; - -/** - * Data private to this pipeline stage. - */ -struct light_stage_data { - GLvector4f Input; - GLvector4f LitColor[2]; - GLvector4f LitSecondary[2]; - light_func *light_func_tab; - - struct material_cursor mat[MAT_ATTRIB_MAX]; - GLuint mat_count; - GLuint mat_bitmask; -}; - - -#define LIGHT_STAGE_DATA(stage) ((struct light_stage_data *)(stage->privatePtr)) - - - -/**********************************************************************/ -/***** Lighting computation *****/ -/**********************************************************************/ - - -/* - * Notes: - * When two-sided lighting is enabled we compute the color (or index) - * for both the front and back side of the primitive. Then, when the - * orientation of the facet is later learned, we can determine which - * color (or index) to use for rendering. - * - * KW: We now know orientation in advance and only shade for - * the side or sides which are actually required. - * - * Variables: - * n = normal vector - * V = vertex position - * P = light source position - * Pe = (0,0,0,1) - * - * Precomputed: - * IF P[3]==0 THEN - * // light at infinity - * IF local_viewer THEN - * _VP_inf_norm = unit vector from V to P // Precompute - * ELSE - * // eye at infinity - * _h_inf_norm = Normalize( VP + <0,0,1> ) // Precompute - * ENDIF - * ENDIF - * - * Functions: - * Normalize( v ) = normalized vector v - * Magnitude( v ) = length of vector v - */ - - - -static void -validate_shine_table( struct gl_context *ctx, GLuint side, GLfloat shininess ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct tnl_shine_tab *list = tnl->_ShineTabList; - struct tnl_shine_tab *s; - - assert(side < 2); - - foreach(s, list) - if ( s->shininess == shininess ) - break; - - if (s == list) { - GLint j; - GLfloat *m; - - foreach(s, list) - if (s->refcount == 0) - break; - - m = s->tab; - m[0] = 0.0F; - if (shininess == 0.0F) { - for (j = 1 ; j <= SHINE_TABLE_SIZE ; j++) - m[j] = 1.0F; - } - else { - for (j = 1 ; j < SHINE_TABLE_SIZE ; j++) { - GLfloat t, x = j / (GLfloat) (SHINE_TABLE_SIZE - 1); - if (x < 0.005F) /* underflow check */ - x = 0.005F; - t = powf(x, shininess); - if (t > 1e-20F) - m[j] = t; - else - m[j] = 0.0F; - } - m[SHINE_TABLE_SIZE] = 1.0F; - } - - s->shininess = shininess; - } - - if (tnl->_ShineTable[side]) - tnl->_ShineTable[side]->refcount--; - - tnl->_ShineTable[side] = s; - move_to_tail( list, s ); - s->refcount++; -} - - -void -_tnl_validate_shine_tables( struct gl_context *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLfloat shininess; - - shininess = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SHININESS][0]; - if (!tnl->_ShineTable[0] || tnl->_ShineTable[0]->shininess != shininess) - validate_shine_table( ctx, 0, shininess ); - - shininess = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_SHININESS][0]; - if (!tnl->_ShineTable[1] || tnl->_ShineTable[1]->shininess != shininess) - validate_shine_table( ctx, 1, shininess ); -} - - -/** - * In the case of colormaterial, the effected material attributes - * should already have been bound to point to the incoming color data, - * prior to running the pipeline. - * This function copies the vertex's color to the material attributes - * which are tracking glColor. - * It's called per-vertex in the lighting loop. - */ -static void -update_materials(struct gl_context *ctx, struct light_stage_data *store) -{ - GLuint i; - - for (i = 0 ; i < store->mat_count ; i++) { - /* update the material */ - COPY_CLEAN_4V(store->mat[i].current, store->mat[i].size, store->mat[i].ptr); - /* increment src vertex color pointer */ - STRIDE_F(store->mat[i].ptr, store->mat[i].stride); - } - - /* recompute derived light/material values */ - _mesa_update_material( ctx, store->mat_bitmask ); - /* XXX we should only call this if we're tracking/changing the specular - * exponent. - */ - _tnl_validate_shine_tables( ctx ); -} - - -/** - * Prepare things prior to running the lighting stage. - * Return number of material attributes which will track vertex color. - */ -static GLuint -prepare_materials(struct gl_context *ctx, - struct vertex_buffer *VB, struct light_stage_data *store) -{ - GLuint i; - - store->mat_count = 0; - store->mat_bitmask = 0; - - /* Examine the _ColorMaterialBitmask to determine which materials - * track vertex color. Override the material attribute's pointer - * with the color pointer for each one. - */ - if (ctx->Light.ColorMaterialEnabled) { - GLbitfield bitmask = ctx->Light._ColorMaterialBitmask; - while (bitmask) { - const int i = u_bit_scan(&bitmask); - VB->AttribPtr[_TNL_ATTRIB_MAT_FRONT_AMBIENT + i] = - VB->AttribPtr[_TNL_ATTRIB_COLOR0]; - } - } - - /* Now, for each material attribute that's tracking vertex color, save - * some values (ptr, stride, size, current) that we'll need in - * update_materials(), above, that'll actually copy the vertex color to - * the material attribute(s). - */ - for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) { - if (VB->AttribPtr[i]->stride) { - const GLuint j = store->mat_count++; - const GLuint attr = i - _TNL_ATTRIB_MAT_FRONT_AMBIENT; - store->mat[j].ptr = VB->AttribPtr[i]->start; - store->mat[j].stride = VB->AttribPtr[i]->stride; - store->mat[j].size = VB->AttribPtr[i]->size; - store->mat[j].current = ctx->Light.Material.Attrib[attr]; - store->mat_bitmask |= (1<mat_count; -} - -/* - * Compute dp ^ SpecularExponent. - * Lerp between adjacent values in the f(x) lookup table, giving a - * continuous function, with adequate overall accuracy. (Though still - * pretty good compared to a straight lookup). - */ -static inline GLfloat -lookup_shininess(const struct gl_context *ctx, GLuint face, GLfloat dp) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - const struct tnl_shine_tab *tab = tnl->_ShineTable[face]; - float f = dp * (SHINE_TABLE_SIZE - 1); - int k = (int) f; - if (k < 0 /* gcc may cast an overflow float value to negative int value */ - || k > SHINE_TABLE_SIZE - 2) - return powf(dp, tab->shininess); - else - return tab->tab[k] + (f - k) * (tab->tab[k+1] - tab->tab[k]); -} - -/* Tables for all the shading functions. - */ -static light_func _tnl_light_tab[MAX_LIGHT_FUNC]; -static light_func _tnl_light_fast_tab[MAX_LIGHT_FUNC]; -static light_func _tnl_light_fast_single_tab[MAX_LIGHT_FUNC]; -static light_func _tnl_light_spec_tab[MAX_LIGHT_FUNC]; - -#define TAG(x) x -#define IDX (0) -#include "t_vb_lighttmp.h" - -#define TAG(x) x##_twoside -#define IDX (LIGHT_TWOSIDE) -#include "t_vb_lighttmp.h" - -#define TAG(x) x##_material -#define IDX (LIGHT_MATERIAL) -#include "t_vb_lighttmp.h" - -#define TAG(x) x##_twoside_material -#define IDX (LIGHT_TWOSIDE|LIGHT_MATERIAL) -#include "t_vb_lighttmp.h" - - -static void init_lighting_tables( void ) -{ - static int done; - - if (!done) { - init_light_tab(); - init_light_tab_twoside(); - init_light_tab_material(); - init_light_tab_twoside_material(); - done = 1; - } -} - - -static GLboolean run_lighting( struct gl_context *ctx, - struct tnl_pipeline_stage *stage ) -{ - struct light_stage_data *store = LIGHT_STAGE_DATA(stage); - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &tnl->vb; - GLvector4f *input = ctx->_NeedEyeCoords ? VB->EyePtr : VB->AttribPtr[_TNL_ATTRIB_POS]; - GLuint idx; - - if (!ctx->Light.Enabled || ctx->VertexProgram._Current) - return GL_TRUE; - - /* Make sure we can talk about position x,y and z: - */ - if (input->size <= 2 && input == VB->AttribPtr[_TNL_ATTRIB_POS]) { - - _math_trans_4f( store->Input.data, - VB->AttribPtr[_TNL_ATTRIB_POS]->data, - VB->AttribPtr[_TNL_ATTRIB_POS]->stride, - GL_FLOAT, - VB->AttribPtr[_TNL_ATTRIB_POS]->size, - 0, - VB->Count ); - - if (input->size <= 2) { - /* Clean z. - */ - _mesa_vector4f_clean_elem(&store->Input, VB->Count, 2); - } - - if (input->size <= 1) { - /* Clean y. - */ - _mesa_vector4f_clean_elem(&store->Input, VB->Count, 1); - } - - input = &store->Input; - } - - idx = 0; - - if (prepare_materials( ctx, VB, store )) - idx |= LIGHT_MATERIAL; - - if (ctx->Light.Model.TwoSide) - idx |= LIGHT_TWOSIDE; - - /* The individual functions know about replaying side-effects - * vs. full re-execution. - */ - store->light_func_tab[idx]( ctx, VB, stage, input ); - - return GL_TRUE; -} - - -/* Called in place of do_lighting when the light table may have changed. - */ -static void validate_lighting( struct gl_context *ctx, - struct tnl_pipeline_stage *stage ) -{ - light_func *tab; - - if (!ctx->Light.Enabled || ctx->VertexProgram._Current) - return; - - if (ctx->Light._NeedVertices) { - if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) - tab = _tnl_light_spec_tab; - else - tab = _tnl_light_tab; - } - else { - /* Power of two means only a single active light. */ - if (util_is_power_of_two_or_zero(ctx->Light._EnabledLights)) - tab = _tnl_light_fast_single_tab; - else - tab = _tnl_light_fast_tab; - } - - - LIGHT_STAGE_DATA(stage)->light_func_tab = tab; - - /* This and the above should only be done on _NEW_LIGHT: - */ - TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange( ctx ); -} - - - -/* Called the first time stage->run is called. In effect, don't - * allocate data until the first time the stage is run. - */ -static GLboolean init_lighting( struct gl_context *ctx, - struct tnl_pipeline_stage *stage ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct light_stage_data *store; - GLuint size = tnl->vb.Size; - - stage->privatePtr = malloc(sizeof(*store)); - store = LIGHT_STAGE_DATA(stage); - if (!store) - return GL_FALSE; - - /* Do onetime init. - */ - init_lighting_tables(); - - _mesa_vector4f_alloc( &store->Input, 0, size, 32 ); - _mesa_vector4f_alloc( &store->LitColor[0], 0, size, 32 ); - _mesa_vector4f_alloc( &store->LitColor[1], 0, size, 32 ); - _mesa_vector4f_alloc( &store->LitSecondary[0], 0, size, 32 ); - _mesa_vector4f_alloc( &store->LitSecondary[1], 0, size, 32 ); - - store->LitColor[0].size = 4; - store->LitColor[1].size = 4; - store->LitSecondary[0].size = 3; - store->LitSecondary[1].size = 3; - - return GL_TRUE; -} - - - - -static void dtr( struct tnl_pipeline_stage *stage ) -{ - struct light_stage_data *store = LIGHT_STAGE_DATA(stage); - - if (store) { - _mesa_vector4f_free( &store->Input ); - _mesa_vector4f_free( &store->LitColor[0] ); - _mesa_vector4f_free( &store->LitColor[1] ); - _mesa_vector4f_free( &store->LitSecondary[0] ); - _mesa_vector4f_free( &store->LitSecondary[1] ); - free( store ); - stage->privatePtr = NULL; - } -} - -const struct tnl_pipeline_stage _tnl_lighting_stage = -{ - "lighting", /* name */ - NULL, /* private_data */ - init_lighting, - dtr, /* destroy */ - validate_lighting, - run_lighting -}; diff --git a/src/mesa/tnl/t_vb_lighttmp.h b/src/mesa/tnl/t_vb_lighttmp.h deleted file mode 100644 index 1d0ed8f..0000000 --- a/src/mesa/tnl/t_vb_lighttmp.h +++ /dev/null @@ -1,641 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2003 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - * - * - * Authors: - * Brian Paul Keith Whitwell - */ - - -#if IDX & LIGHT_TWOSIDE -# define NR_SIDES 2 -#else -# define NR_SIDES 1 -#endif - - -/* define TRACE to trace lighting code */ -/* #define TRACE 1 */ - -/* - * ctx is the current context - * VB is the vertex buffer - * stage is the lighting stage-private data - * input is the vector of eye or object-space vertex coordinates - */ -static void TAG(light_rgba_spec)( struct gl_context *ctx, - struct vertex_buffer *VB, - struct tnl_pipeline_stage *stage, - GLvector4f *input ) -{ - struct light_stage_data *store = LIGHT_STAGE_DATA(stage); - GLfloat (*base)[3] = ctx->Light._BaseColor; - GLfloat sumA[2]; - GLuint j; - - const GLuint vstride = input->stride; - const GLfloat *vertex = (GLfloat *)input->data; - const GLuint nstride = VB->AttribPtr[_TNL_ATTRIB_NORMAL]->stride; - const GLfloat *normal = (GLfloat *)VB->AttribPtr[_TNL_ATTRIB_NORMAL]->data; - - GLfloat (*Fcolor)[4] = (GLfloat (*)[4]) store->LitColor[0].data; - GLfloat (*Fspec)[4] = (GLfloat (*)[4]) store->LitSecondary[0].data; -#if IDX & LIGHT_TWOSIDE - GLfloat (*Bcolor)[4] = (GLfloat (*)[4]) store->LitColor[1].data; - GLfloat (*Bspec)[4] = (GLfloat (*)[4]) store->LitSecondary[1].data; -#endif - - const GLuint nr = VB->Count; - -#ifdef TRACE - fprintf(stderr, "%s\n", __func__ ); -#endif - - VB->AttribPtr[_TNL_ATTRIB_COLOR0] = &store->LitColor[0]; - VB->AttribPtr[_TNL_ATTRIB_COLOR1] = &store->LitSecondary[0]; - sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3]; - -#if IDX & LIGHT_TWOSIDE - VB->BackfaceColorPtr = &store->LitColor[1]; - VB->BackfaceSecondaryColorPtr = &store->LitSecondary[1]; - sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3]; -#endif - - - store->LitColor[0].stride = 16; - store->LitColor[1].stride = 16; - - for (j = 0; j < nr; j++,STRIDE_F(vertex,vstride),STRIDE_F(normal,nstride)) { - GLfloat sum[2][3], spec[2][3]; - GLbitfield mask; - -#if IDX & LIGHT_MATERIAL - update_materials( ctx, store ); - sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3]; -#if IDX & LIGHT_TWOSIDE - sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3]; -#endif -#endif - - COPY_3V(sum[0], base[0]); - ZERO_3V(spec[0]); - -#if IDX & LIGHT_TWOSIDE - COPY_3V(sum[1], base[1]); - ZERO_3V(spec[1]); -#endif - - /* Add contribution from each enabled light source */ - mask = ctx->Light._EnabledLights; - while (mask) { - const int l = u_bit_scan(&mask); - struct gl_light *light = &ctx->Light.Light[l]; - struct gl_light_uniforms *lu = &ctx->Light.LightSource[l]; - GLfloat n_dot_h; - GLfloat correction; - GLint side; - GLfloat contrib[3]; - GLfloat attenuation; - GLfloat VP[3]; /* unit vector from vertex to light */ - GLfloat n_dot_VP; /* n dot VP */ - GLfloat *h; - - /* compute VP and attenuation */ - if (!(light->_Flags & LIGHT_POSITIONAL)) { - /* directional light */ - COPY_3V(VP, light->_VP_inf_norm); - attenuation = light->_VP_inf_spot_attenuation; - } - else { - GLfloat d; /* distance from vertex to light */ - - SUB_3V(VP, light->_Position, vertex); - - d = (GLfloat) LEN_3FV( VP ); - - if (d > 1e-6F) { - GLfloat invd = 1.0F / d; - SELF_SCALE_SCALAR_3V(VP, invd); - } - - attenuation = 1.0F / (lu->ConstantAttenuation + d * - (lu->LinearAttenuation + d * - lu->QuadraticAttenuation)); - - /* spotlight attenuation */ - if (light->_Flags & LIGHT_SPOT) { - GLfloat PV_dot_dir = - DOT3(VP, light->_NormSpotDirection); - - if (PV_dot_dir_CosCutoff) { - continue; /* this light makes no contribution */ - } - else { - GLfloat spot = powf(PV_dot_dir, lu->SpotExponent); - attenuation *= spot; - } - } - } - - if (attenuation < 1e-3F) - continue; /* this light makes no contribution */ - - /* Compute dot product or normal and vector from V to light pos */ - n_dot_VP = DOT3( normal, VP ); - - /* Which side gets the diffuse & specular terms? */ - if (n_dot_VP < 0.0F) { - ACC_SCALE_SCALAR_3V(sum[0], attenuation, light->_MatAmbient[0]); -#if IDX & LIGHT_TWOSIDE - side = 1; - correction = -1; - n_dot_VP = -n_dot_VP; -#else - continue; -#endif - } - else { -#if IDX & LIGHT_TWOSIDE - ACC_SCALE_SCALAR_3V( sum[1], attenuation, light->_MatAmbient[1]); -#endif - side = 0; - correction = 1; - } - - /* diffuse term */ - COPY_3V(contrib, light->_MatAmbient[side]); - ACC_SCALE_SCALAR_3V(contrib, n_dot_VP, light->_MatDiffuse[side]); - ACC_SCALE_SCALAR_3V(sum[side], attenuation, contrib ); - - /* specular term - cannibalize VP... */ - if (ctx->Light.Model.LocalViewer) { - GLfloat v[3]; - COPY_3V(v, vertex); - NORMALIZE_3FV(v); - SUB_3V(VP, VP, v); /* h = VP + VPe */ - h = VP; - NORMALIZE_3FV(h); - } - else if (light->_Flags & LIGHT_POSITIONAL) { - h = VP; - ACC_3V(h, ctx->_EyeZDir); - NORMALIZE_3FV(h); - } - else { - h = light->_h_inf_norm; - } - - n_dot_h = correction * DOT3(normal, h); - - if (n_dot_h > 0.0F) { - GLfloat spec_coef = lookup_shininess(ctx, side, n_dot_h); - if (spec_coef > 1.0e-10F) { - spec_coef *= attenuation; - ACC_SCALE_SCALAR_3V( spec[side], spec_coef, - light->_MatSpecular[side]); - } - } - } /*loop over lights*/ - - COPY_3V( Fcolor[j], sum[0] ); - COPY_3V( Fspec[j], spec[0] ); - Fcolor[j][3] = sumA[0]; - -#if IDX & LIGHT_TWOSIDE - COPY_3V( Bcolor[j], sum[1] ); - COPY_3V( Bspec[j], spec[1] ); - Bcolor[j][3] = sumA[1]; -#endif - } -} - - -static void TAG(light_rgba)( struct gl_context *ctx, - struct vertex_buffer *VB, - struct tnl_pipeline_stage *stage, - GLvector4f *input ) -{ - struct light_stage_data *store = LIGHT_STAGE_DATA(stage); - GLuint j; - - GLfloat (*base)[3] = ctx->Light._BaseColor; - GLfloat sumA[2]; - - const GLuint vstride = input->stride; - const GLfloat *vertex = (GLfloat *) input->data; - const GLuint nstride = VB->AttribPtr[_TNL_ATTRIB_NORMAL]->stride; - const GLfloat *normal = (GLfloat *)VB->AttribPtr[_TNL_ATTRIB_NORMAL]->data; - - GLfloat (*Fcolor)[4] = (GLfloat (*)[4]) store->LitColor[0].data; -#if IDX & LIGHT_TWOSIDE - GLfloat (*Bcolor)[4] = (GLfloat (*)[4]) store->LitColor[1].data; -#endif - - const GLuint nr = VB->Count; - -#ifdef TRACE - fprintf(stderr, "%s\n", __func__ ); -#endif - - VB->AttribPtr[_TNL_ATTRIB_COLOR0] = &store->LitColor[0]; - sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3]; - -#if IDX & LIGHT_TWOSIDE - VB->BackfaceColorPtr = &store->LitColor[1]; - sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3]; -#endif - - store->LitColor[0].stride = 16; - store->LitColor[1].stride = 16; - - for (j = 0; j < nr; j++,STRIDE_F(vertex,vstride),STRIDE_F(normal,nstride)) { - GLfloat sum[2][3]; - GLbitfield mask; - -#if IDX & LIGHT_MATERIAL - update_materials( ctx, store ); - sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3]; -#if IDX & LIGHT_TWOSIDE - sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3]; -#endif -#endif - - COPY_3V(sum[0], base[0]); - -#if IDX & LIGHT_TWOSIDE - COPY_3V(sum[1], base[1]); -#endif - - /* Add contribution from each enabled light source */ - mask = ctx->Light._EnabledLights; - while (mask) { - const int l = u_bit_scan(&mask); - struct gl_light *light = &ctx->Light.Light[l]; - struct gl_light_uniforms *lu = &ctx->Light.LightSource[l]; - GLfloat n_dot_h; - GLfloat correction; - GLint side; - GLfloat contrib[3]; - GLfloat attenuation; - GLfloat VP[3]; /* unit vector from vertex to light */ - GLfloat n_dot_VP; /* n dot VP */ - GLfloat *h; - - /* compute VP and attenuation */ - if (!(light->_Flags & LIGHT_POSITIONAL)) { - /* directional light */ - COPY_3V(VP, light->_VP_inf_norm); - attenuation = light->_VP_inf_spot_attenuation; - } - else { - GLfloat d; /* distance from vertex to light */ - - SUB_3V(VP, light->_Position, vertex); - - d = (GLfloat) LEN_3FV( VP ); - - if (d > 1e-6F) { - GLfloat invd = 1.0F / d; - SELF_SCALE_SCALAR_3V(VP, invd); - } - - attenuation = 1.0F / (lu->ConstantAttenuation + d * - (lu->LinearAttenuation + d * - lu->QuadraticAttenuation)); - - /* spotlight attenuation */ - if (light->_Flags & LIGHT_SPOT) { - GLfloat PV_dot_dir = - DOT3(VP, light->_NormSpotDirection); - - if (PV_dot_dir_CosCutoff) { - continue; /* this light makes no contribution */ - } - else { - GLfloat spot = powf(PV_dot_dir, lu->SpotExponent); - attenuation *= spot; - } - } - } - - if (attenuation < 1e-3F) - continue; /* this light makes no contribution */ - - /* Compute dot product or normal and vector from V to light pos */ - n_dot_VP = DOT3( normal, VP ); - - /* which side are we lighting? */ - if (n_dot_VP < 0.0F) { - ACC_SCALE_SCALAR_3V(sum[0], attenuation, light->_MatAmbient[0]); -#if IDX & LIGHT_TWOSIDE - side = 1; - correction = -1; - n_dot_VP = -n_dot_VP; -#else - continue; -#endif - } - else { -#if IDX & LIGHT_TWOSIDE - ACC_SCALE_SCALAR_3V( sum[1], attenuation, light->_MatAmbient[1]); -#endif - side = 0; - correction = 1; - } - - COPY_3V(contrib, light->_MatAmbient[side]); - - /* diffuse term */ - ACC_SCALE_SCALAR_3V(contrib, n_dot_VP, light->_MatDiffuse[side]); - - /* specular term - cannibalize VP... */ - { - if (ctx->Light.Model.LocalViewer) { - GLfloat v[3]; - COPY_3V(v, vertex); - NORMALIZE_3FV(v); - SUB_3V(VP, VP, v); /* h = VP + VPe */ - h = VP; - NORMALIZE_3FV(h); - } - else if (light->_Flags & LIGHT_POSITIONAL) { - h = VP; - ACC_3V(h, ctx->_EyeZDir); - NORMALIZE_3FV(h); - } - else { - h = light->_h_inf_norm; - } - - n_dot_h = correction * DOT3(normal, h); - - if (n_dot_h > 0.0F) { - GLfloat spec_coef = lookup_shininess(ctx, side, n_dot_h); - ACC_SCALE_SCALAR_3V( contrib, spec_coef, - light->_MatSpecular[side]); - } - } - - ACC_SCALE_SCALAR_3V( sum[side], attenuation, contrib ); - } - - COPY_3V( Fcolor[j], sum[0] ); - Fcolor[j][3] = sumA[0]; - -#if IDX & LIGHT_TWOSIDE - COPY_3V( Bcolor[j], sum[1] ); - Bcolor[j][3] = sumA[1]; -#endif - } -} - - - - -/* As below, but with just a single light. - */ -static void TAG(light_fast_rgba_single)( struct gl_context *ctx, - struct vertex_buffer *VB, - struct tnl_pipeline_stage *stage, - GLvector4f *input ) - -{ - struct light_stage_data *store = LIGHT_STAGE_DATA(stage); - const GLuint nstride = VB->AttribPtr[_TNL_ATTRIB_NORMAL]->stride; - const GLfloat *normal = (GLfloat *)VB->AttribPtr[_TNL_ATTRIB_NORMAL]->data; - GLfloat (*Fcolor)[4] = (GLfloat (*)[4]) store->LitColor[0].data; -#if IDX & LIGHT_TWOSIDE - GLfloat (*Bcolor)[4] = (GLfloat (*)[4]) store->LitColor[1].data; -#endif - const struct gl_light *light = - &ctx->Light.Light[ffs(ctx->Light._EnabledLights) - 1]; - GLuint j = 0; - GLfloat base[2][4]; -#if IDX & LIGHT_MATERIAL - const GLuint nr = VB->Count; -#else - const GLuint nr = VB->AttribPtr[_TNL_ATTRIB_NORMAL]->count; -#endif - -#ifdef TRACE - fprintf(stderr, "%s\n", __func__ ); -#endif - - (void) input; /* doesn't refer to Eye or Obj */ - - VB->AttribPtr[_TNL_ATTRIB_COLOR0] = &store->LitColor[0]; -#if IDX & LIGHT_TWOSIDE - VB->BackfaceColorPtr = &store->LitColor[1]; -#endif - - if (nr > 1) { - store->LitColor[0].stride = 16; - store->LitColor[1].stride = 16; - } - else { - store->LitColor[0].stride = 0; - store->LitColor[1].stride = 0; - } - - for (j = 0; j < nr; j++, STRIDE_F(normal,nstride)) { - - GLfloat n_dot_VP; - -#if IDX & LIGHT_MATERIAL - update_materials( ctx, store ); -#endif - - /* No attenuation, so incoporate _MatAmbient into base color. - */ -#if !(IDX & LIGHT_MATERIAL) - if ( j == 0 ) -#endif - { - COPY_3V(base[0], light->_MatAmbient[0]); - ACC_3V(base[0], ctx->Light._BaseColor[0] ); - base[0][3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3]; - -#if IDX & LIGHT_TWOSIDE - COPY_3V(base[1], light->_MatAmbient[1]); - ACC_3V(base[1], ctx->Light._BaseColor[1]); - base[1][3] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3]; -#endif - } - - n_dot_VP = DOT3(normal, light->_VP_inf_norm); - - if (n_dot_VP < 0.0F) { -#if IDX & LIGHT_TWOSIDE - GLfloat n_dot_h = -DOT3(normal, light->_h_inf_norm); - GLfloat sum[3]; - COPY_3V(sum, base[1]); - ACC_SCALE_SCALAR_3V(sum, -n_dot_VP, light->_MatDiffuse[1]); - if (n_dot_h > 0.0F) { - GLfloat spec = lookup_shininess(ctx, 1, n_dot_h); - ACC_SCALE_SCALAR_3V(sum, spec, light->_MatSpecular[1]); - } - COPY_3V(Bcolor[j], sum ); - Bcolor[j][3] = base[1][3]; -#endif - COPY_4FV(Fcolor[j], base[0]); - } - else { - GLfloat n_dot_h = DOT3(normal, light->_h_inf_norm); - GLfloat sum[3]; - COPY_3V(sum, base[0]); - ACC_SCALE_SCALAR_3V(sum, n_dot_VP, light->_MatDiffuse[0]); - if (n_dot_h > 0.0F) { - GLfloat spec = lookup_shininess(ctx, 0, n_dot_h); - ACC_SCALE_SCALAR_3V(sum, spec, light->_MatSpecular[0]); - } - COPY_3V(Fcolor[j], sum ); - Fcolor[j][3] = base[0][3]; -#if IDX & LIGHT_TWOSIDE - COPY_4FV(Bcolor[j], base[1]); -#endif - } - } -} - - -/* Light infinite lights - */ -static void TAG(light_fast_rgba)( struct gl_context *ctx, - struct vertex_buffer *VB, - struct tnl_pipeline_stage *stage, - GLvector4f *input ) -{ - struct light_stage_data *store = LIGHT_STAGE_DATA(stage); - GLfloat sumA[2]; - const GLuint nstride = VB->AttribPtr[_TNL_ATTRIB_NORMAL]->stride; - const GLfloat *normal = (GLfloat *)VB->AttribPtr[_TNL_ATTRIB_NORMAL]->data; - GLfloat (*Fcolor)[4] = (GLfloat (*)[4]) store->LitColor[0].data; -#if IDX & LIGHT_TWOSIDE - GLfloat (*Bcolor)[4] = (GLfloat (*)[4]) store->LitColor[1].data; -#endif - GLuint j = 0; -#if IDX & LIGHT_MATERIAL - const GLuint nr = VB->Count; -#else - const GLuint nr = VB->AttribPtr[_TNL_ATTRIB_NORMAL]->count; -#endif - -#ifdef TRACE - fprintf(stderr, "%s %d\n", __func__, nr ); -#endif - - (void) input; - - sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3]; - sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3]; - - VB->AttribPtr[_TNL_ATTRIB_COLOR0] = &store->LitColor[0]; -#if IDX & LIGHT_TWOSIDE - VB->BackfaceColorPtr = &store->LitColor[1]; -#endif - - if (nr > 1) { - store->LitColor[0].stride = 16; - store->LitColor[1].stride = 16; - } - else { - store->LitColor[0].stride = 0; - store->LitColor[1].stride = 0; - } - - for (j = 0; j < nr; j++, STRIDE_F(normal,nstride)) { - - GLfloat sum[2][3]; - GLbitfield mask; - -#if IDX & LIGHT_MATERIAL - update_materials( ctx, store ); - - sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3]; -#if IDX & LIGHT_TWOSIDE - sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3]; -#endif -#endif - - - COPY_3V(sum[0], ctx->Light._BaseColor[0]); -#if IDX & LIGHT_TWOSIDE - COPY_3V(sum[1], ctx->Light._BaseColor[1]); -#endif - - mask = ctx->Light._EnabledLights; - while (mask) { - const int l = u_bit_scan(&mask); - const struct gl_light *light = &ctx->Light.Light[l]; - GLfloat n_dot_h, n_dot_VP, spec; - - ACC_3V(sum[0], light->_MatAmbient[0]); -#if IDX & LIGHT_TWOSIDE - ACC_3V(sum[1], light->_MatAmbient[1]); -#endif - - n_dot_VP = DOT3(normal, light->_VP_inf_norm); - - if (n_dot_VP > 0.0F) { - ACC_SCALE_SCALAR_3V(sum[0], n_dot_VP, light->_MatDiffuse[0]); - n_dot_h = DOT3(normal, light->_h_inf_norm); - if (n_dot_h > 0.0F) { - spec = lookup_shininess(ctx, 0, n_dot_h); - ACC_SCALE_SCALAR_3V( sum[0], spec, light->_MatSpecular[0]); - } - } -#if IDX & LIGHT_TWOSIDE - else { - ACC_SCALE_SCALAR_3V(sum[1], -n_dot_VP, light->_MatDiffuse[1]); - n_dot_h = -DOT3(normal, light->_h_inf_norm); - if (n_dot_h > 0.0F) { - spec = lookup_shininess(ctx, 1, n_dot_h); - ACC_SCALE_SCALAR_3V( sum[1], spec, light->_MatSpecular[1]); - } - } -#endif - } - - COPY_3V( Fcolor[j], sum[0] ); - Fcolor[j][3] = sumA[0]; - -#if IDX & LIGHT_TWOSIDE - COPY_3V( Bcolor[j], sum[1] ); - Bcolor[j][3] = sumA[1]; -#endif - } -} - - - - -static void TAG(init_light_tab)( void ) -{ - _tnl_light_tab[IDX] = TAG(light_rgba); - _tnl_light_fast_tab[IDX] = TAG(light_fast_rgba); - _tnl_light_fast_single_tab[IDX] = TAG(light_fast_rgba_single); - _tnl_light_spec_tab[IDX] = TAG(light_rgba_spec); -} - - -#undef TAG -#undef IDX -#undef NR_SIDES diff --git a/src/mesa/tnl/t_vb_normals.c b/src/mesa/tnl/t_vb_normals.c deleted file mode 100644 index ca75331..0000000 --- a/src/mesa/tnl/t_vb_normals.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - * - * Authors: - * Keith Whitwell - */ - - -#include "main/glheader.h" -#include "main/macros.h" - -#include "main/mtypes.h" - -#include "math/m_xform.h" - -#include "t_context.h" -#include "t_pipeline.h" - - -struct normal_stage_data { - normal_func NormalTransform; - GLvector4f normal; -}; - -#define NORMAL_STAGE_DATA(stage) ((struct normal_stage_data *)stage->privatePtr) - - -static GLboolean -run_normal_stage(struct gl_context *ctx, struct tnl_pipeline_stage *stage) -{ - struct normal_stage_data *store = NORMAL_STAGE_DATA(stage); - struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - const GLfloat *lengths; - - if (!store->NormalTransform) - return GL_TRUE; - - /* We can only use the display list's saved normal lengths if we've - * got a transformation matrix with uniform scaling. - */ - if (_math_matrix_is_general_scale(ctx->ModelviewMatrixStack.Top)) - lengths = NULL; - else - lengths = VB->NormalLengthPtr; - - store->NormalTransform( ctx->ModelviewMatrixStack.Top, - ctx->_ModelViewInvScale, - VB->AttribPtr[_TNL_ATTRIB_NORMAL], /* input normals */ - lengths, - &store->normal ); /* resulting normals */ - - if (VB->AttribPtr[_TNL_ATTRIB_NORMAL]->count > 1) { - store->normal.stride = 4 * sizeof(GLfloat); - } - else { - store->normal.stride = 0; - } - - VB->AttribPtr[_TNL_ATTRIB_NORMAL] = &store->normal; - - VB->NormalLengthPtr = NULL; /* no longer valid */ - return GL_TRUE; -} - - -/** - * Examine current GL state and set the store->NormalTransform pointer - * to point to the appropriate normal transformation routine. - */ -static void -validate_normal_stage(struct gl_context *ctx, struct tnl_pipeline_stage *stage) -{ - struct normal_stage_data *store = NORMAL_STAGE_DATA(stage); - - if (ctx->VertexProgram._Current || - (!ctx->Light.Enabled && - !(ctx->Texture._GenFlags & TEXGEN_NEED_NORMALS))) { - store->NormalTransform = NULL; - return; - } - - if (ctx->_NeedEyeCoords) { - /* Eye coordinates are needed, for whatever reasons. - * Do lighting in eye coordinates, as the GL spec says. - */ - GLuint transform = NORM_TRANSFORM_NO_ROT; - - if (_math_matrix_has_rotation(ctx->ModelviewMatrixStack.Top)) { - /* need to do full (3x3) matrix transform */ - transform = NORM_TRANSFORM; - } - - if (ctx->Transform.Normalize) { - store->NormalTransform = _mesa_normal_tab[transform | NORM_NORMALIZE]; - } - else if (ctx->Transform.RescaleNormals && - ctx->_ModelViewInvScale != 1.0F) { - store->NormalTransform = _mesa_normal_tab[transform | NORM_RESCALE]; - } - else { - store->NormalTransform = _mesa_normal_tab[transform]; - } - } - else { - /* We don't need eye coordinates. - * Do lighting in object coordinates. Thus, we don't need to fully - * transform normal vectors (just leave them in object coordinates) - * but we still need to do normalization/rescaling if enabled. - */ - if (ctx->Transform.Normalize) { - store->NormalTransform = _mesa_normal_tab[NORM_NORMALIZE]; - } - else if (!ctx->Transform.RescaleNormals && - ctx->_ModelViewInvScale != 1.0F) { - store->NormalTransform = _mesa_normal_tab[NORM_RESCALE]; - } - else { - store->NormalTransform = NULL; - } - } -} - - -/** - * Allocate stage's private data (storage for transformed normals). - */ -static GLboolean -alloc_normal_data(struct gl_context *ctx, struct tnl_pipeline_stage *stage) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct normal_stage_data *store; - - stage->privatePtr = malloc(sizeof(*store)); - store = NORMAL_STAGE_DATA(stage); - if (!store) - return GL_FALSE; - - _mesa_vector4f_alloc( &store->normal, 0, tnl->vb.Size, 32 ); - return GL_TRUE; -} - - -/** - * Free stage's private data. - */ -static void -free_normal_data(struct tnl_pipeline_stage *stage) -{ - struct normal_stage_data *store = NORMAL_STAGE_DATA(stage); - if (store) { - _mesa_vector4f_free( &store->normal ); - free( store ); - stage->privatePtr = NULL; - } -} - - -const struct tnl_pipeline_stage _tnl_normal_transform_stage = -{ - "normal transform", /* name */ - NULL, /* privatePtr */ - alloc_normal_data, /* create */ - free_normal_data, /* destroy */ - validate_normal_stage, /* validate */ - run_normal_stage /* run */ -}; diff --git a/src/mesa/tnl/t_vb_points.c b/src/mesa/tnl/t_vb_points.c deleted file mode 100644 index 4e7801b..0000000 --- a/src/mesa/tnl/t_vb_points.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - * - * Authors: - * Brian Paul - */ - -#include "c99_math.h" -#include "main/glheader.h" -#include "main/mtypes.h" -#include "main/dd.h" - -#include "t_context.h" -#include "t_pipeline.h" - - -struct point_stage_data { - GLvector4f PointSize; -}; - -#define POINT_STAGE_DATA(stage) ((struct point_stage_data *)stage->privatePtr) - - -/** - * Compute point size for each vertex from the vertex eye-space Z - * coordinate and the point size attenuation factors. - * Only done when point size attenuation is enabled and vertex program is - * disabled. - */ -static GLboolean -run_point_stage(struct gl_context *ctx, struct tnl_pipeline_stage *stage) -{ - if (ctx->Point._Attenuated && !ctx->VertexProgram._Current) { - struct point_stage_data *store = POINT_STAGE_DATA(stage); - struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - const GLfloat *eyeCoord = (GLfloat *) VB->EyePtr->data + 2; - const GLint eyeCoordStride = VB->EyePtr->stride / sizeof(GLfloat); - const GLfloat p0 = ctx->Point.Params[0]; - const GLfloat p1 = ctx->Point.Params[1]; - const GLfloat p2 = ctx->Point.Params[2]; - const GLfloat pointSize = ctx->Point.Size; - GLfloat (*size)[4] = store->PointSize.data; - GLuint i; - - for (i = 0; i < VB->Count; i++) { - const GLfloat dist = fabsf(*eyeCoord); - const GLfloat q = p0 + dist * (p1 + dist * p2); - const GLfloat atten = (q != 0.0F) ? (1.0f / sqrtf(q)) : 1.0F; - size[i][0] = pointSize * atten; /* clamping done in rasterization */ - eyeCoord += eyeCoordStride; - } - - VB->AttribPtr[_TNL_ATTRIB_POINTSIZE] = &store->PointSize; - } - - return GL_TRUE; -} - - -static GLboolean -alloc_point_data(struct gl_context *ctx, struct tnl_pipeline_stage *stage) -{ - struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - struct point_stage_data *store; - stage->privatePtr = malloc(sizeof(*store)); - store = POINT_STAGE_DATA(stage); - if (!store) - return GL_FALSE; - - _mesa_vector4f_alloc( &store->PointSize, 0, VB->Size, 32 ); - return GL_TRUE; -} - - -static void -free_point_data(struct tnl_pipeline_stage *stage) -{ - struct point_stage_data *store = POINT_STAGE_DATA(stage); - if (store) { - _mesa_vector4f_free( &store->PointSize ); - free( store ); - stage->privatePtr = NULL; - } -} - - -const struct tnl_pipeline_stage _tnl_point_attenuation_stage = -{ - "point size attenuation", /* name */ - NULL, /* stage private data */ - alloc_point_data, /* alloc data */ - free_point_data, /* destructor */ - NULL, - run_point_stage /* run */ -}; diff --git a/src/mesa/tnl/t_vb_program.c b/src/mesa/tnl/t_vb_program.c deleted file mode 100644 index 3b17ba9..0000000 --- a/src/mesa/tnl/t_vb_program.c +++ /dev/null @@ -1,539 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. - * Copyright (C) 2009 VMware, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -/** - * \file tnl/t_vb_program.c - * \brief Pipeline stage for executing vertex programs. - * \author Brian Paul, Keith Whitwell - */ - - -#include "main/glheader.h" -#include "main/macros.h" -#include "main/samplerobj.h" -#include "main/state.h" -#include "math/m_xform.h" -#include "program/prog_instruction.h" -#include "program/prog_statevars.h" -#include "program/prog_execute.h" -#include "swrast/s_context.h" -#include "util/bitscan.h" -#include "util/u_memory.h" - -#include "tnl/tnl.h" -#include "tnl/t_context.h" -#include "tnl/t_pipeline.h" - - -#ifdef NAN_CHECK -/** Check for NaNs and very large values */ -static inline void -check_float(float x) -{ - assert(!util_is_inf_or_nan(x)); - assert(1.0e-15 <= x && x <= 1.0e15); -} -#endif - - -/*! - * Private storage for the vertex program pipeline stage. - */ -struct vp_stage_data { - /** The results of running the vertex program go into these arrays. */ - GLvector4f results[VARYING_SLOT_MAX]; - - GLvector4f ndcCoords; /**< normalized device coords */ - GLubyte *clipmask; /**< clip flags */ - GLubyte ormask, andmask; /**< for clipping */ - - GLboolean vertex_textures; - - struct gl_program_machine machine; -}; - - -#define VP_STAGE_DATA(stage) ((struct vp_stage_data *)(stage->privatePtr)) - - -static void -userclip( struct gl_context *ctx, - GLvector4f *clip, - GLubyte *clipmask, - GLubyte *clipormask, - GLubyte *clipandmask ) -{ - GLbitfield mask = ctx->Transform.ClipPlanesEnabled; - while (mask) { - const int p = u_bit_scan(&mask); - GLuint nr, i; - const GLfloat a = ctx->Transform._ClipUserPlane[p][0]; - const GLfloat b = ctx->Transform._ClipUserPlane[p][1]; - const GLfloat c = ctx->Transform._ClipUserPlane[p][2]; - const GLfloat d = ctx->Transform._ClipUserPlane[p][3]; - GLfloat *coord = (GLfloat *)clip->data; - GLuint stride = clip->stride; - GLuint count = clip->count; - - for (nr = 0, i = 0 ; i < count ; i++) { - GLfloat dp = (coord[0] * a + - coord[1] * b + - coord[2] * c + - coord[3] * d); - - if (dp < 0) { - nr++; - clipmask[i] |= CLIP_USER_BIT; - } - - STRIDE_F(coord, stride); - } - - if (nr > 0) { - *clipormask |= CLIP_USER_BIT; - if (nr == count) { - *clipandmask |= CLIP_USER_BIT; - return; - } - } - } -} - - -static GLboolean -do_ndc_cliptest(struct gl_context *ctx, struct vp_stage_data *store) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &tnl->vb; - /* Cliptest and perspective divide. Clip functions must clear - * the clipmask. - */ - store->ormask = 0; - store->andmask = CLIP_FRUSTUM_BITS; - - tnl_clip_prepare(ctx); - - if (tnl->NeedNdcCoords) { - VB->NdcPtr = - _mesa_clip_tab[VB->ClipPtr->size]( VB->ClipPtr, - &store->ndcCoords, - store->clipmask, - &store->ormask, - &store->andmask, - !(ctx->Transform.DepthClampNear && - ctx->Transform.DepthClampFar) ); - } - else { - VB->NdcPtr = NULL; - _mesa_clip_np_tab[VB->ClipPtr->size]( VB->ClipPtr, - NULL, - store->clipmask, - &store->ormask, - &store->andmask, - !(ctx->Transform.DepthClampNear && - ctx->Transform.DepthClampFar) ); - } - - if (store->andmask) { - /* All vertices are outside the frustum */ - return GL_FALSE; - } - - /* Test userclip planes. This contributes to VB->ClipMask. - */ - /** XXX NEW_SLANG _Enabled ??? */ - if (ctx->Transform.ClipPlanesEnabled && - (!_mesa_arb_vertex_program_enabled(ctx) || - ctx->VertexProgram.Current->arb.IsPositionInvariant)) { - userclip( ctx, - VB->ClipPtr, - store->clipmask, - &store->ormask, - &store->andmask ); - - if (store->andmask) { - return GL_FALSE; - } - } - - VB->ClipAndMask = store->andmask; - VB->ClipOrMask = store->ormask; - VB->ClipMask = store->clipmask; - - return GL_TRUE; -} - - -/** - * XXX the texture sampling code in this module is a bit of a hack. - * The texture sampling code is in swrast, though it doesn't have any - * real dependencies on the rest of swrast. It should probably be - * moved into main/ someday. - */ -static void -vp_fetch_texel(struct gl_context *ctx, const GLfloat texcoord[4], GLfloat lambda, - GLuint unit, GLfloat color[4]) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - - /* XXX use a float-valued TextureSample routine here!!! */ - swrast->TextureSample[unit](ctx, _mesa_get_samplerobj(ctx, unit), - ctx->Texture.Unit[unit]._Current, - 1, (const GLfloat (*)[4]) texcoord, - &lambda, (GLfloat (*)[4]) color); -} - - -/** - * Called via ctx->Driver.ProgramStringNotify() after a new vertex program - * string has been parsed. - */ -GLboolean -_tnl_program_string(struct gl_context *ctx, GLenum target, struct gl_program *program) -{ - /* No-op. - * If we had derived anything from the program that was private to this - * stage we'd recompute/validate it here. - */ - return GL_TRUE; -} - - -/** - * Initialize virtual machine state prior to executing vertex program. - */ -static void -init_machine(struct gl_context *ctx, struct gl_program_machine *machine, - GLuint instID) -{ - /* Input registers get initialized from the current vertex attribs */ - memcpy(machine->VertAttribs, ctx->Current.Attrib, - MAX_VERTEX_GENERIC_ATTRIBS * 4 * sizeof(GLfloat)); - - machine->NumDeriv = 0; - - /* init call stack */ - machine->StackDepth = 0; - - machine->FetchTexelLod = vp_fetch_texel; - machine->FetchTexelDeriv = NULL; /* not used by vertex programs */ - - machine->Samplers = ctx->VertexProgram._Current->SamplerUnits; - - machine->SystemValues[SYSTEM_VALUE_INSTANCE_ID][0] = (GLfloat) instID; -} - - -/** - * Map the texture images which the vertex program will access (if any). - */ -static void -map_textures(struct gl_context *ctx, const struct gl_program *vp) -{ - GLuint u; - - for (u = 0; u < ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits; u++) { - if (vp->TexturesUsed[u]) { - /* Note: _Current *should* correspond to the target indicated - * in TexturesUsed[u]. - */ - _swrast_map_texture(ctx, ctx->Texture.Unit[u]._Current); - } - } -} - - -/** - * Unmap the texture images which were used by the vertex program (if any). - */ -static void -unmap_textures(struct gl_context *ctx, const struct gl_program *vp) -{ - GLuint u; - - for (u = 0; u < ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits; u++) { - if (vp->TexturesUsed[u]) { - /* Note: _Current *should* correspond to the target indicated - * in TexturesUsed[u]. - */ - _swrast_unmap_texture(ctx, ctx->Texture.Unit[u]._Current); - } - } -} - - -/** - * This function executes vertex programs - */ -static GLboolean -run_vp( struct gl_context *ctx, struct tnl_pipeline_stage *stage ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vp_stage_data *store = VP_STAGE_DATA(stage); - struct vertex_buffer *VB = &tnl->vb; - struct gl_program *program = ctx->VertexProgram._Current; - struct gl_program_machine *machine = &store->machine; - GLuint outputs[VARYING_SLOT_MAX], numOutputs; - GLuint i, j; - - if (!program) - return GL_TRUE; - - /* ARB program or vertex shader */ - _mesa_load_state_parameters(ctx, program->Parameters); - - /* make list of outputs to save some time below */ - numOutputs = 0; - for (i = 0; i < VARYING_SLOT_MAX; i++) { - if (program->info.outputs_written & BITFIELD64_BIT(i)) { - outputs[numOutputs++] = i; - } - } - - /* Allocate result vectors. We delay this until now to avoid allocating - * memory that would never be used if we don't run the software tnl pipeline. - */ - if (!store->results[0].storage) { - for (i = 0; i < VARYING_SLOT_MAX; i++) { - assert(!store->results[i].storage); - _mesa_vector4f_alloc( &store->results[i], 0, VB->Size, 32 ); - store->results[i].size = 4; - } - } - - map_textures(ctx, program); - - for (i = 0; i < VB->Count; i++) { - GLuint attr; - - init_machine(ctx, machine, tnl->CurInstance); - -#if 0 - printf("Input %d: %f, %f, %f, %f\n", i, - VB->AttribPtr[0]->data[i][0], - VB->AttribPtr[0]->data[i][1], - VB->AttribPtr[0]->data[i][2], - VB->AttribPtr[0]->data[i][3]); - printf(" color: %f, %f, %f, %f\n", - VB->AttribPtr[3]->data[i][0], - VB->AttribPtr[3]->data[i][1], - VB->AttribPtr[3]->data[i][2], - VB->AttribPtr[3]->data[i][3]); - printf(" normal: %f, %f, %f, %f\n", - VB->AttribPtr[2]->data[i][0], - VB->AttribPtr[2]->data[i][1], - VB->AttribPtr[2]->data[i][2], - VB->AttribPtr[2]->data[i][3]); -#endif - - /* the vertex array case */ - for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) { - if (program->info.inputs_read & BITFIELD64_BIT(attr)) { - const GLubyte *ptr = (const GLubyte*) VB->AttribPtr[attr]->data; - const GLuint size = VB->AttribPtr[attr]->size; - const GLuint stride = VB->AttribPtr[attr]->stride; - const GLfloat *data = (GLfloat *) (ptr + stride * i); -#ifdef NAN_CHECK - check_float(data[0]); - check_float(data[1]); - check_float(data[2]); - check_float(data[3]); -#endif - COPY_CLEAN_4V(machine->VertAttribs[attr], size, data); - } - } - - /* execute the program */ - _mesa_execute_program(ctx, program, machine); - - /* copy the output registers into the VB->attribs arrays */ - for (j = 0; j < numOutputs; j++) { - const GLuint attr = outputs[j]; -#ifdef NAN_CHECK - check_float(machine->Outputs[attr][0]); - check_float(machine->Outputs[attr][1]); - check_float(machine->Outputs[attr][2]); - check_float(machine->Outputs[attr][3]); -#endif - COPY_4V(store->results[attr].data[i], machine->Outputs[attr]); - } - - /* FOGC is a special case. Fragment shader expects (f,0,0,1) */ - if (program->info.outputs_written & BITFIELD64_BIT(VARYING_SLOT_FOGC)) { - store->results[VARYING_SLOT_FOGC].data[i][1] = 0.0; - store->results[VARYING_SLOT_FOGC].data[i][2] = 0.0; - store->results[VARYING_SLOT_FOGC].data[i][3] = 1.0; - } -#ifdef NAN_CHECK - assert(machine->Outputs[0][3] != 0.0F); -#endif -#if 0 - printf("HPOS: %f %f %f %f\n", - machine->Outputs[0][0], - machine->Outputs[0][1], - machine->Outputs[0][2], - machine->Outputs[0][3]); -#endif - } - - unmap_textures(ctx, program); - - if (program->arb.IsPositionInvariant) { - /* make sure the inverse is up to date */ - _math_matrix_analyse(&ctx->_ModelProjectMatrix); - - /* We need the exact same transform as in the fixed function path here - * to guarantee invariance, depending on compiler optimization flags - * results could be different otherwise. - */ - VB->ClipPtr = TransformRaw( &store->results[0], - &ctx->_ModelProjectMatrix, - VB->AttribPtr[0] ); - - /* Drivers expect this to be clean to element 4... - */ - switch (VB->ClipPtr->size) { - case 1: - /* impossible */ - case 2: - _mesa_vector4f_clean_elem( VB->ClipPtr, VB->Count, 2 ); - FALLTHROUGH; - case 3: - _mesa_vector4f_clean_elem( VB->ClipPtr, VB->Count, 3 ); - FALLTHROUGH; - case 4: - break; - } - } - else { - /* Setup the VB pointers so that the next pipeline stages get - * their data from the right place (the program output arrays). - */ - VB->ClipPtr = &store->results[VARYING_SLOT_POS]; - VB->ClipPtr->size = 4; - VB->ClipPtr->count = VB->Count; - } - - VB->AttribPtr[VERT_ATTRIB_COLOR0] = &store->results[VARYING_SLOT_COL0]; - VB->AttribPtr[VERT_ATTRIB_COLOR1] = &store->results[VARYING_SLOT_COL1]; - VB->AttribPtr[VERT_ATTRIB_FOG] = &store->results[VARYING_SLOT_FOGC]; - VB->AttribPtr[_TNL_ATTRIB_POINTSIZE] = &store->results[VARYING_SLOT_PSIZ]; - VB->BackfaceColorPtr = &store->results[VARYING_SLOT_BFC0]; - VB->BackfaceSecondaryColorPtr = &store->results[VARYING_SLOT_BFC1]; - - for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { - VB->AttribPtr[_TNL_ATTRIB_TEX0 + i] - = &store->results[VARYING_SLOT_TEX0 + i]; - } - - for (i = 0; i < ctx->Const.MaxVarying; i++) { - if (program->info.outputs_written & - BITFIELD64_BIT(VARYING_SLOT_VAR0 + i)) { - /* Note: varying results get put into the generic attributes */ - VB->AttribPtr[VERT_ATTRIB_GENERIC0+i] - = &store->results[VARYING_SLOT_VAR0 + i]; - } - } - - - /* Perform NDC and cliptest operations: - */ - return do_ndc_cliptest(ctx, store); -} - - -/** - * Called the first time stage->run is called. In effect, don't - * allocate data until the first time the stage is run. - */ -static GLboolean -init_vp(struct gl_context *ctx, struct tnl_pipeline_stage *stage) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &(tnl->vb); - struct vp_stage_data *store; - const GLuint size = VB->Size; - - stage->privatePtr = calloc(1, sizeof(*store)); - store = VP_STAGE_DATA(stage); - if (!store) - return GL_FALSE; - - /* a few other misc allocations */ - _mesa_vector4f_alloc( &store->ndcCoords, 0, size, 32 ); - store->clipmask = align_malloc(sizeof(GLubyte)*size, 32 ); - - return GL_TRUE; -} - - -/** - * Destructor for this pipeline stage. - */ -static void -dtr(struct tnl_pipeline_stage *stage) -{ - struct vp_stage_data *store = VP_STAGE_DATA(stage); - - if (store) { - GLuint i; - - /* free the vertex program result arrays */ - for (i = 0; i < VARYING_SLOT_MAX; i++) - _mesa_vector4f_free( &store->results[i] ); - - /* free misc arrays */ - _mesa_vector4f_free( &store->ndcCoords ); - align_free( store->clipmask ); - - free( store ); - stage->privatePtr = NULL; - } -} - - -static void -validate_vp_stage(struct gl_context *ctx, struct tnl_pipeline_stage *stage) -{ - if (ctx->VertexProgram._Current) { - _swrast_update_texture_samplers(ctx); - } -} - - - -/** - * Public description of this pipeline stage. - */ -const struct tnl_pipeline_stage _tnl_vertex_program_stage = -{ - "vertex-program", - NULL, /* private_data */ - init_vp, /* create */ - dtr, /* destroy */ - validate_vp_stage, /* validate */ - run_vp /* run -- initially set to ctr */ -}; diff --git a/src/mesa/tnl/t_vb_render.c b/src/mesa/tnl/t_vb_render.c deleted file mode 100644 index 02f521c..0000000 --- a/src/mesa/tnl/t_vb_render.c +++ /dev/null @@ -1,350 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - * - * Authors: - * Keith Whitwell - */ - - -/* - * Render whole vertex buffers, including projection of vertices from - * clip space and clipping of primitives. - * - * This file makes calls to project vertices and to the point, line - * and triangle rasterizers via the function pointers: - * - * context->Driver.Render.* - * - */ - - -#include -#include "main/glheader.h" -#include "main/context.h" -#include "main/enums.h" -#include "main/macros.h" - -#include "main/mtypes.h" -#include "math/m_xform.h" -#include "util/bitscan.h" - -#include "t_pipeline.h" - - - -/**********************************************************************/ -/* Clip single primitives */ -/**********************************************************************/ - - -#define W(i) coord[i][3] -#define Z(i) coord[i][2] -#define Y(i) coord[i][1] -#define X(i) coord[i][0] -#define SIZE 4 -#define TAG(x) x##_4 -#include "t_vb_cliptmp.h" - - - -/**********************************************************************/ -/* Clip and render whole begin/end objects */ -/**********************************************************************/ - -#define NEED_EDGEFLAG_SETUP (ctx->Polygon.FrontMode != GL_FILL || ctx->Polygon.BackMode != GL_FILL) -#define EDGEFLAG_GET(idx) VB->EdgeFlag[idx] -#define EDGEFLAG_SET(idx, val) VB->EdgeFlag[idx] = val - - -/* This does NOT include the CLIP_USER_BIT! */ -#define CLIPMASK (CLIP_FRUSTUM_BITS | CLIP_CULL_BIT) - - -/* Vertices, with the possibility of clipping. - */ -#define RENDER_POINTS( start, count ) \ - tnl->Driver.Render.Points( ctx, start, count ) - -#define RENDER_LINE( v1, v2 ) \ -do { \ - GLubyte c1 = mask[v1], c2 = mask[v2]; \ - GLubyte ormask = c1|c2; \ - if (!ormask) \ - LineFunc( ctx, v1, v2 ); \ - else if (!(c1 & c2 & CLIPMASK)) \ - clip_line_4( ctx, v1, v2, ormask ); \ -} while (0) - -#define RENDER_TRI( v1, v2, v3 ) \ -do { \ - GLubyte c1 = mask[v1], c2 = mask[v2], c3 = mask[v3]; \ - GLubyte ormask = c1|c2|c3; \ - if (!ormask) \ - TriangleFunc( ctx, v1, v2, v3 ); \ - else if (!(c1 & c2 & c3 & CLIPMASK)) \ - clip_tri_4( ctx, v1, v2, v3, ormask ); \ -} while (0) - -#define RENDER_QUAD( v1, v2, v3, v4 ) \ -do { \ - GLubyte c1 = mask[v1], c2 = mask[v2]; \ - GLubyte c3 = mask[v3], c4 = mask[v4]; \ - GLubyte ormask = c1|c2|c3|c4; \ - if (!ormask) \ - QuadFunc( ctx, v1, v2, v3, v4 ); \ - else if (!(c1 & c2 & c3 & c4 & CLIPMASK)) \ - clip_quad_4( ctx, v1, v2, v3, v4, ormask ); \ -} while (0) - - -#define LOCAL_VARS \ - TNLcontext *tnl = TNL_CONTEXT(ctx); \ - struct vertex_buffer *VB = &tnl->vb; \ - const GLuint * const elt = VB->Elts; \ - const GLubyte *mask = VB->ClipMask; \ - const GLuint sz = VB->ClipPtr->size; \ - const tnl_line_func LineFunc = tnl->Driver.Render.Line; \ - const tnl_triangle_func TriangleFunc = tnl->Driver.Render.Triangle; \ - const tnl_quad_func QuadFunc = tnl->Driver.Render.Quad; \ - const GLboolean stipple = ctx->Line.StippleFlag; \ - (void) (LineFunc && TriangleFunc && QuadFunc); \ - (void) elt; (void) mask; (void) sz; (void) stipple; - -#define TAG(x) clip_##x##_verts -#define INIT(x) tnl->Driver.Render.PrimitiveNotify( ctx, x ) -#define RESET_STIPPLE if (stipple) tnl->Driver.Render.ResetLineStipple( ctx ) -#define PRESERVE_VB_DEFS -#include "t_vb_rendertmp.h" - - - -/* Elts, with the possibility of clipping. - */ -#undef ELT -#undef TAG -#define ELT(x) elt[x] -#define TAG(x) clip_##x##_elts -#include "t_vb_rendertmp.h" - -/* TODO: do this for all primitives, verts and elts: - */ -static void clip_elt_triangles( struct gl_context *ctx, - GLuint start, - GLuint count, - GLuint flags ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - tnl_render_func render_tris = tnl->Driver.Render.PrimTabElts[GL_TRIANGLES]; - struct vertex_buffer *VB = &tnl->vb; - const GLuint * const elt = VB->Elts; - GLubyte *mask = VB->ClipMask; - GLuint last = count-2; - GLuint j; - (void) flags; - - tnl->Driver.Render.PrimitiveNotify( ctx, GL_TRIANGLES ); - - for (j=start; j < last; j+=3 ) { - GLubyte c1 = mask[elt[j]]; - GLubyte c2 = mask[elt[j+1]]; - GLubyte c3 = mask[elt[j+2]]; - GLubyte ormask = c1|c2|c3; - if (ormask) { - if (start < j) - render_tris( ctx, start, j, 0 ); - if (!(c1&c2&c3&CLIPMASK)) - clip_tri_4( ctx, elt[j], elt[j+1], elt[j+2], ormask ); - start = j+3; - } - } - - if (start < j) - render_tris( ctx, start, j, 0 ); -} - -/**********************************************************************/ -/* Render whole begin/end objects */ -/**********************************************************************/ - -#define NEED_EDGEFLAG_SETUP (ctx->Polygon.FrontMode != GL_FILL || ctx->Polygon.BackMode != GL_FILL) -#define EDGEFLAG_GET(idx) VB->EdgeFlag[idx] -#define EDGEFLAG_SET(idx, val) VB->EdgeFlag[idx] = val - - -/* Vertices, no clipping. - */ -#define RENDER_POINTS( start, count ) \ - tnl->Driver.Render.Points( ctx, start, count ) - -#define RENDER_LINE( v1, v2 ) \ - LineFunc( ctx, v1, v2 ) - -#define RENDER_TRI( v1, v2, v3 ) \ - TriangleFunc( ctx, v1, v2, v3 ) - -#define RENDER_QUAD( v1, v2, v3, v4 ) \ - QuadFunc( ctx, v1, v2, v3, v4 ) - -#define TAG(x) _tnl_##x##_verts - -#define LOCAL_VARS \ - TNLcontext *tnl = TNL_CONTEXT(ctx); \ - struct vertex_buffer *VB = &tnl->vb; \ - const GLuint * const elt = VB->Elts; \ - const tnl_line_func LineFunc = tnl->Driver.Render.Line; \ - const tnl_triangle_func TriangleFunc = tnl->Driver.Render.Triangle; \ - const tnl_quad_func QuadFunc = tnl->Driver.Render.Quad; \ - const GLboolean stipple = ctx->Line.StippleFlag; \ - (void) (LineFunc && TriangleFunc && QuadFunc); \ - (void) elt; (void) stipple - -#define RESET_STIPPLE if (stipple) tnl->Driver.Render.ResetLineStipple( ctx ) -#define INIT(x) tnl->Driver.Render.PrimitiveNotify( ctx, x ) -#define RENDER_TAB_QUALIFIER -#define PRESERVE_VB_DEFS -#include "t_vb_rendertmp.h" - - -/* Elts, no clipping. - */ -#undef ELT -#define TAG(x) _tnl_##x##_elts -#define ELT(x) elt[x] -#include "t_vb_rendertmp.h" - - -/**********************************************************************/ -/* Helper functions for drivers */ -/**********************************************************************/ - -void _tnl_RenderClippedPolygon( struct gl_context *ctx, const GLuint *elts, GLuint n ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &tnl->vb; - GLuint *tmp = VB->Elts; - - VB->Elts = (GLuint *)elts; - tnl->Driver.Render.PrimTabElts[GL_POLYGON]( ctx, 0, n, PRIM_BEGIN|PRIM_END ); - VB->Elts = tmp; -} - -void _tnl_RenderClippedLine( struct gl_context *ctx, GLuint ii, GLuint jj ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - tnl->Driver.Render.Line( ctx, ii, jj ); -} - - - -/**********************************************************************/ -/* Clip and render whole vertex buffers */ -/**********************************************************************/ - - -static GLboolean run_render( struct gl_context *ctx, - struct tnl_pipeline_stage *stage ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &tnl->vb; - tnl_render_func *tab; - GLint pass = 0; - - /* Allow the drivers to lock before projected verts are built so - * that window coordinates are guarenteed not to change before - * rendering. - */ - assert(tnl->Driver.Render.Start); - - tnl->Driver.Render.Start( ctx ); - - assert(tnl->Driver.Render.BuildVertices); - assert(tnl->Driver.Render.PrimitiveNotify); - assert(tnl->Driver.Render.Points); - assert(tnl->Driver.Render.Line); - assert(tnl->Driver.Render.Triangle); - assert(tnl->Driver.Render.Quad); - assert(tnl->Driver.Render.ResetLineStipple); - assert(tnl->Driver.Render.Interp); - assert(tnl->Driver.Render.CopyPV); - assert(tnl->Driver.Render.ClippedLine); - assert(tnl->Driver.Render.ClippedPolygon); - assert(tnl->Driver.Render.Finish); - - tnl->Driver.Render.BuildVertices( ctx, 0, VB->Count, ~0 ); - - if (VB->ClipOrMask) { - tab = VB->Elts ? clip_render_tab_elts : clip_render_tab_verts; - clip_render_tab_elts[GL_TRIANGLES] = clip_elt_triangles; - } - else { - tab = (VB->Elts ? - tnl->Driver.Render.PrimTabElts : - tnl->Driver.Render.PrimTabVerts); - } - - do - { - GLuint i; - - for (i = 0 ; i < VB->PrimitiveCount ; i++) - { - GLuint prim = _tnl_translate_prim(&VB->Primitive[i]); - GLuint start = VB->Primitive[i].start; - GLuint length = VB->Primitive[i].count; - - assert((prim & PRIM_MODE_MASK) <= GL_POLYGON); - - if (MESA_VERBOSE & VERBOSE_PRIMS) - _mesa_debug(NULL, "MESA prim %s %d..%d\n", - _mesa_enum_to_string(prim & PRIM_MODE_MASK), - start, start+length); - - if (length) - tab[prim & PRIM_MODE_MASK]( ctx, start, start + length, prim ); - } - } while (tnl->Driver.Render.Multipass && - tnl->Driver.Render.Multipass( ctx, ++pass )); - - tnl->Driver.Render.Finish( ctx ); - - return GL_FALSE; /* finished the pipe */ -} - - -/**********************************************************************/ -/* Render pipeline stage */ -/**********************************************************************/ - - - - - -const struct tnl_pipeline_stage _tnl_render_stage = -{ - "render", /* name */ - NULL, /* private data */ - NULL, /* creator */ - NULL, /* destructor */ - NULL, /* validate */ - run_render /* run */ -}; diff --git a/src/mesa/tnl/t_vb_rendertmp.h b/src/mesa/tnl/t_vb_rendertmp.h deleted file mode 100644 index 4bfc6b1..0000000 --- a/src/mesa/tnl/t_vb_rendertmp.h +++ /dev/null @@ -1,487 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - * - * Authors: - * Keith Whitwell - */ - - -#ifndef POSTFIX -#define POSTFIX -#endif - -#ifndef INIT -#define INIT(x) -#endif - -#ifndef NEED_EDGEFLAG_SETUP -#define NEED_EDGEFLAG_SETUP 0 -#define EDGEFLAG_GET(a) 0 -#define EDGEFLAG_SET(a,b) (void)b -#endif - -#ifndef RESET_STIPPLE -#define RESET_STIPPLE -#endif - -#ifndef TEST_PRIM_END -#define TEST_PRIM_END(prim) (flags & PRIM_END) -#define TEST_PRIM_BEGIN(prim) (flags & PRIM_BEGIN) -#endif - -#ifndef ELT -#define ELT(x) x -#endif - -#ifndef RENDER_TAB_QUALIFIER -#define RENDER_TAB_QUALIFIER static -#endif - -static void TAG(render_points)( struct gl_context *ctx, - GLuint start, - GLuint count, - GLuint flags ) -{ - LOCAL_VARS; - (void) flags; - - INIT(GL_POINTS); - RENDER_POINTS( start, count ); - POSTFIX; -} - -static void TAG(render_lines)( struct gl_context *ctx, - GLuint start, - GLuint count, - GLuint flags ) -{ - GLuint j; - LOCAL_VARS; - (void) flags; - - INIT(GL_LINES); - for (j=start+1; jLight.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT) - RENDER_LINE( ELT(j-1), ELT(j) ); - else - RENDER_LINE( ELT(j), ELT(j-1) ); - } - POSTFIX; -} - - -static void TAG(render_line_strip)( struct gl_context *ctx, - GLuint start, - GLuint count, - GLuint flags ) -{ - GLuint j; - LOCAL_VARS; - (void) flags; - - INIT(GL_LINE_STRIP); - - if (TEST_PRIM_BEGIN(flags)) { - RESET_STIPPLE; - } - - for (j=start+1; jLight.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT) - RENDER_LINE( ELT(j-1), ELT(j) ); - else - RENDER_LINE( ELT(j), ELT(j-1) ); - } - POSTFIX; -} - - -static void TAG(render_line_loop)( struct gl_context *ctx, - GLuint start, - GLuint count, - GLuint flags ) -{ - GLuint i; - LOCAL_VARS; - - INIT(GL_LINE_LOOP); - - if (start+1 < count) { - if (TEST_PRIM_BEGIN(flags)) { - RESET_STIPPLE; - /* draw the first line from v[0] to v[1] */ - if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT) - RENDER_LINE( ELT(start), ELT(start+1) ); - else - RENDER_LINE( ELT(start+1), ELT(start) ); - } - - /* draw lines from v[1] to v[n-1] */ - for ( i = start+2 ; i < count ; i++) { - if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT) - RENDER_LINE( ELT(i-1), ELT(i) ); - else - RENDER_LINE( ELT(i), ELT(i-1) ); - } - - if ( TEST_PRIM_END(flags)) { - /* draw final line from v[n-1] to v[0] (the very first vertex) */ - if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT) - RENDER_LINE( ELT(count-1), ELT(start) ); - else - RENDER_LINE( ELT(start), ELT(count-1) ); - } - } - - POSTFIX; -} - - -static void TAG(render_triangles)( struct gl_context *ctx, - GLuint start, - GLuint count, - GLuint flags ) -{ - GLuint j; - LOCAL_VARS; - (void) flags; - - INIT(GL_TRIANGLES); - if (NEED_EDGEFLAG_SETUP) { - for (j=start+2; jLight.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT) - RENDER_TRI( ELT(j-2), ELT(j-1), ELT(j) ); - else - RENDER_TRI( ELT(j-1), ELT(j), ELT(j-2) ); - } - } else { - for (j=start+2; jLight.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT) - RENDER_TRI( ELT(j-2), ELT(j-1), ELT(j) ); - else - RENDER_TRI( ELT(j-1), ELT(j), ELT(j-2) ); - } - } - POSTFIX; -} - - - -static void TAG(render_tri_strip)( struct gl_context *ctx, - GLuint start, - GLuint count, - GLuint flags ) -{ - GLuint j; - GLuint parity = 0; - LOCAL_VARS; - - INIT(GL_TRIANGLE_STRIP); - if (NEED_EDGEFLAG_SETUP) { - for (j=start+2;jLight.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT) { - ej2 = ELT(j-2+parity); - ej1 = ELT(j-1-parity); - ej = ELT(j); - } - else { - ej2 = ELT(j-1+parity); - ej1 = ELT(j-parity); - ej = ELT(j-2); - } - ef2 = EDGEFLAG_GET( ej2 ); - ef1 = EDGEFLAG_GET( ej1 ); - ef = EDGEFLAG_GET( ej ); - if (TEST_PRIM_BEGIN(flags)) { - RESET_STIPPLE; - } - EDGEFLAG_SET( ej2, GL_TRUE ); - EDGEFLAG_SET( ej1, GL_TRUE ); - EDGEFLAG_SET( ej, GL_TRUE ); - RENDER_TRI( ej2, ej1, ej ); - EDGEFLAG_SET( ej2, ef2 ); - EDGEFLAG_SET( ej1, ef1 ); - EDGEFLAG_SET( ej, ef ); - } - } else { - for (j=start+2; jLight.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT) - RENDER_TRI( ELT(j-2+parity), ELT(j-1-parity), ELT(j) ); - else - RENDER_TRI( ELT(j-1+parity), ELT(j-parity), ELT(j-2) ); - } - } - POSTFIX; -} - - -static void TAG(render_tri_fan)( struct gl_context *ctx, - GLuint start, - GLuint count, - GLuint flags ) -{ - GLuint j; - LOCAL_VARS; - (void) flags; - - INIT(GL_TRIANGLE_FAN); - if (NEED_EDGEFLAG_SETUP) { - for (j=start+2;jLight.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT) - RENDER_TRI( ejs, ej1, ej); - else - RENDER_TRI( ej, ejs, ej1); - EDGEFLAG_SET( ejs, efs ); - EDGEFLAG_SET( ej1, ef1 ); - EDGEFLAG_SET( ej, ef ); - } - } else { - for (j=start+2;jLight.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT) - RENDER_TRI( ELT(start), ELT(j-1), ELT(j) ); - else - RENDER_TRI( ELT(j), ELT(start), ELT(j-1) ); - } - } - - POSTFIX; -} - - -static void TAG(render_poly)( struct gl_context *ctx, - GLuint start, - GLuint count, - GLuint flags ) -{ - GLuint j = start+2; - LOCAL_VARS; - (void) flags; - - INIT(GL_POLYGON); - if (NEED_EDGEFLAG_SETUP) { - GLboolean efstart = EDGEFLAG_GET( ELT(start) ); - GLboolean efcount = EDGEFLAG_GET( ELT(count-1) ); - - /* If the primitive does not begin here, the first edge - * is non-boundary. - */ - if (!TEST_PRIM_BEGIN(flags)) - EDGEFLAG_SET( ELT(start), GL_FALSE ); - else { - RESET_STIPPLE; - } - - /* If the primitive does not end here, the final edge is - * non-boundary. - */ - if (!TEST_PRIM_END(flags)) - EDGEFLAG_SET( ELT(count-1), GL_FALSE ); - - /* Draw the first triangles (possibly zero) - */ - if (j+1Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT || - !ctx->Const.QuadsFollowProvokingVertexConvention) - RENDER_QUAD( ELT(j-3), ELT(j-2), ELT(j-1), ELT(j) ); - else - RENDER_QUAD( ELT(j-2), ELT(j-1), ELT(j), ELT(j-3) ); - } - } else { - for (j=start+3; jLight.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT || - !ctx->Const.QuadsFollowProvokingVertexConvention) - RENDER_QUAD( ELT(j-3), ELT(j-2), ELT(j-1), ELT(j) ); - else - RENDER_QUAD( ELT(j-2), ELT(j-1), ELT(j), ELT(j-3) ); - } - } - POSTFIX; -} - -static void TAG(render_quad_strip)( struct gl_context *ctx, - GLuint start, - GLuint count, - GLuint flags ) -{ - GLuint j; - LOCAL_VARS; - (void) flags; - - INIT(GL_QUAD_STRIP); - if (NEED_EDGEFLAG_SETUP) { - for (j=start+3;jLight.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT || - !ctx->Const.QuadsFollowProvokingVertexConvention) - RENDER_QUAD( ELT(j-1), ELT(j-3), ELT(j-2), ELT(j) ); - else - RENDER_QUAD( ELT(j-2), ELT(j), ELT(j-1), ELT(j-3) ); - EDGEFLAG_SET( ELT(j-3), ef3 ); - EDGEFLAG_SET( ELT(j-2), ef2 ); - EDGEFLAG_SET( ELT(j-1), ef1 ); - EDGEFLAG_SET( ELT(j), ef ); - } - } else { - for (j=start+3;jLight.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT || - !ctx->Const.QuadsFollowProvokingVertexConvention) - RENDER_QUAD( ELT(j-1), ELT(j-3), ELT(j-2), ELT(j) ); - else - RENDER_QUAD( ELT(j-2), ELT(j), ELT(j-1), ELT(j-3) ); - } - } - POSTFIX; -} - -static void TAG(render_noop)( struct gl_context *ctx, - GLuint start, - GLuint count, - GLuint flags ) -{ - (void)(ctx && start && count && flags); -} - -RENDER_TAB_QUALIFIER void (*TAG(render_tab)[GL_POLYGON+2])(struct gl_context *, - GLuint, - GLuint, - GLuint) = -{ - TAG(render_points), - TAG(render_lines), - TAG(render_line_loop), - TAG(render_line_strip), - TAG(render_triangles), - TAG(render_tri_strip), - TAG(render_tri_fan), - TAG(render_quads), - TAG(render_quad_strip), - TAG(render_poly), - TAG(render_noop), -}; - - - -#ifndef PRESERVE_VB_DEFS -#undef RENDER_TRI -#undef RENDER_QUAD -#undef RENDER_LINE -#undef RENDER_POINTS -#undef LOCAL_VARS -#undef INIT -#undef POSTFIX -#undef RESET_STIPPLE -#undef DBG -#undef ELT -#undef RENDER_TAB_QUALIFIER -#endif - -#ifndef PRESERVE_TAG -#undef TAG -#endif - -#undef PRESERVE_VB_DEFS -#undef PRESERVE_TAG diff --git a/src/mesa/tnl/t_vb_texgen.c b/src/mesa/tnl/t_vb_texgen.c deleted file mode 100644 index 6a86f5e..0000000 --- a/src/mesa/tnl/t_vb_texgen.c +++ /dev/null @@ -1,610 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - * - * Authors: - * Brian Paul Keith Whitwell - */ - -/* - * Regarding GL_NV_texgen_reflection: - * - * Portions of this software may use or implement intellectual - * property owned and licensed by NVIDIA Corporation. NVIDIA disclaims - * any and all warranties with respect to such intellectual property, - * including any use thereof or modifications thereto. - */ - -#include "main/errors.h" -#include "main/glheader.h" -#include "main/macros.h" - -#include "main/mtypes.h" - -#include "math/m_xform.h" - -#include "t_context.h" -#include "t_pipeline.h" - - -/*********************************************************************** - * Automatic texture coordinate generation (texgen) code. - */ - - -struct texgen_stage_data; - -typedef void (*texgen_func)( struct gl_context *ctx, - struct texgen_stage_data *store, - GLuint unit); - - -struct texgen_stage_data { - - /* Per-texunit derived state. - */ - GLuint TexgenSize[MAX_TEXTURE_COORD_UNITS]; - texgen_func TexgenFunc[MAX_TEXTURE_COORD_UNITS]; - - /* Temporary values used in texgen. - */ - GLfloat (*tmp_f)[3]; - GLfloat *tmp_m; - - /* Buffered outputs of the stage. - */ - GLvector4f texcoord[MAX_TEXTURE_COORD_UNITS]; -}; - - -#define TEXGEN_STAGE_DATA(stage) ((struct texgen_stage_data *)stage->privatePtr) - - - -static GLuint all_bits[5] = { - 0, - VEC_SIZE_1, - VEC_SIZE_2, - VEC_SIZE_3, - VEC_SIZE_4, -}; - -#define VEC_SIZE_FLAGS (VEC_SIZE_1|VEC_SIZE_2|VEC_SIZE_3|VEC_SIZE_4) - -#define TEXGEN_NEED_M (TEXGEN_SPHERE_MAP) -#define TEXGEN_NEED_F (TEXGEN_SPHERE_MAP | \ - TEXGEN_REFLECTION_MAP_NV) - - - -static void build_m3( GLfloat f[][3], GLfloat m[], - const GLvector4f *normal, - const GLvector4f *eye ) -{ - GLuint stride = eye->stride; - GLfloat *coord = (GLfloat *)eye->start; - GLuint count = eye->count; - const GLfloat *norm = normal->start; - GLuint i; - - for (i=0;istride)) { - GLfloat u[3], two_nu, fx, fy, fz; - COPY_3V( u, coord ); - NORMALIZE_3FV( u ); - two_nu = 2.0F * DOT3(norm,u); - fx = f[i][0] = u[0] - norm[0] * two_nu; - fy = f[i][1] = u[1] - norm[1] * two_nu; - fz = f[i][2] = u[2] - norm[2] * two_nu; - m[i] = fx * fx + fy * fy + (fz + 1.0F) * (fz + 1.0F); - if (m[i] != 0.0F) { - m[i] = 0.5F * (1.0f / sqrtf(m[i])); - } - } -} - - - -static void build_m2( GLfloat f[][3], GLfloat m[], - const GLvector4f *normal, - const GLvector4f *eye ) -{ - GLuint stride = eye->stride; - GLfloat *coord = eye->start; - GLuint count = eye->count; - - GLfloat *norm = normal->start; - GLuint i; - - for (i=0;istride)) { - GLfloat u[3], two_nu, fx, fy, fz; - COPY_2V( u, coord ); - u[2] = 0; - NORMALIZE_3FV( u ); - two_nu = 2.0F * DOT3(norm,u); - fx = f[i][0] = u[0] - norm[0] * two_nu; - fy = f[i][1] = u[1] - norm[1] * two_nu; - fz = f[i][2] = u[2] - norm[2] * two_nu; - m[i] = fx * fx + fy * fy + (fz + 1.0F) * (fz + 1.0F); - if (m[i] != 0.0F) { - m[i] = 0.5F * (1.0f / sqrtf(m[i])); - } - } -} - - - -typedef void (*build_m_func)( GLfloat f[][3], - GLfloat m[], - const GLvector4f *normal, - const GLvector4f *eye ); - - -static build_m_func build_m_tab[5] = { - NULL, - NULL, - build_m2, - build_m3, - build_m3 -}; - - -/* This is unusual in that we respect the stride of the output vector - * (f). This allows us to pass in either a texcoord vector4f, or a - * temporary vector3f. - */ -static void build_f3( GLfloat *f, - GLuint fstride, - const GLvector4f *normal, - const GLvector4f *eye ) -{ - GLuint stride = eye->stride; - GLfloat *coord = eye->start; - GLuint count = eye->count; - - GLfloat *norm = normal->start; - GLuint i; - - for (i=0;istride); - } -} - - -static void build_f2( GLfloat *f, - GLuint fstride, - const GLvector4f *normal, - const GLvector4f *eye ) -{ - GLuint stride = eye->stride; - GLfloat *coord = eye->start; - GLuint count = eye->count; - GLfloat *norm = normal->start; - GLuint i; - - for (i=0;istride); - } -} - -typedef void (*build_f_func)( GLfloat *f, - GLuint fstride, - const GLvector4f *normal_vec, - const GLvector4f *eye ); - - - -/* Just treat 4-vectors as 3-vectors. - */ -static build_f_func build_f_tab[5] = { - NULL, - NULL, - build_f2, - build_f3, - build_f3 -}; - - - -/* Special case texgen functions. - */ -static void texgen_reflection_map_nv( struct gl_context *ctx, - struct texgen_stage_data *store, - GLuint unit ) -{ - struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - GLvector4f *in = VB->AttribPtr[VERT_ATTRIB_TEX0 + unit]; - GLvector4f *out = &store->texcoord[unit]; - - build_f_tab[VB->EyePtr->size]( out->start, - out->stride, - VB->AttribPtr[_TNL_ATTRIB_NORMAL], - VB->EyePtr ); - - out->flags |= (in->flags & VEC_SIZE_FLAGS) | VEC_SIZE_3; - out->count = VB->Count; - out->size = MAX2(in->size, 3); - if (in->size == 4) - _mesa_copy_tab[0x8]( out, in ); -} - - - -static void texgen_normal_map_nv( struct gl_context *ctx, - struct texgen_stage_data *store, - GLuint unit ) -{ - struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - GLvector4f *in = VB->AttribPtr[VERT_ATTRIB_TEX0 + unit]; - GLvector4f *out = &store->texcoord[unit]; - GLvector4f *normal = VB->AttribPtr[_TNL_ATTRIB_NORMAL]; - GLfloat (*texcoord)[4] = (GLfloat (*)[4])out->start; - GLuint count = VB->Count; - GLuint i; - const GLfloat *norm = normal->start; - - for (i=0;istride)) { - texcoord[i][0] = norm[0]; - texcoord[i][1] = norm[1]; - texcoord[i][2] = norm[2]; - } - - - out->flags |= (in->flags & VEC_SIZE_FLAGS) | VEC_SIZE_3; - out->count = count; - out->size = MAX2(in->size, 3); - if (in->size == 4) - _mesa_copy_tab[0x8]( out, in ); -} - - -static void texgen_sphere_map( struct gl_context *ctx, - struct texgen_stage_data *store, - GLuint unit ) -{ - struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - GLvector4f *in = VB->AttribPtr[VERT_ATTRIB_TEX0 + unit]; - GLvector4f *out = &store->texcoord[unit]; - GLfloat (*texcoord)[4] = (GLfloat (*)[4]) out->start; - GLuint count = VB->Count; - GLuint i; - GLfloat (*f)[3] = store->tmp_f; - GLfloat *m = store->tmp_m; - - (build_m_tab[VB->EyePtr->size])( store->tmp_f, - store->tmp_m, - VB->AttribPtr[_TNL_ATTRIB_NORMAL], - VB->EyePtr ); - - out->size = MAX2(in->size,2); - - for (i=0;icount = count; - out->flags |= (in->flags & VEC_SIZE_FLAGS) | VEC_SIZE_2; - if (in->size > 2) - _mesa_copy_tab[all_bits[in->size] & ~0x3]( out, in ); -} - - - -static void texgen( struct gl_context *ctx, - struct texgen_stage_data *store, - GLuint unit ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &tnl->vb; - GLvector4f *in = VB->AttribPtr[VERT_ATTRIB_TEX0 + unit]; - GLvector4f *out = &store->texcoord[unit]; - const struct gl_fixedfunc_texture_unit *texUnit = - &ctx->Texture.FixedFuncUnit[unit]; - const GLvector4f *obj = VB->AttribPtr[_TNL_ATTRIB_POS]; - const GLvector4f *eye = VB->EyePtr; - const GLvector4f *normal = VB->AttribPtr[_TNL_ATTRIB_NORMAL]; - const GLfloat *m = store->tmp_m; - const GLuint count = VB->Count; - GLfloat (*texcoord)[4] = (GLfloat (*)[4])out->data; - GLfloat (*f)[3] = store->tmp_f; - GLuint copy; - - if (texUnit->_GenFlags & TEXGEN_NEED_M) { - build_m_tab[eye->size]( store->tmp_f, store->tmp_m, normal, eye ); - } else if (texUnit->_GenFlags & TEXGEN_NEED_F) { - build_f_tab[eye->size]( (GLfloat *)store->tmp_f, 3, normal, eye ); - } - - - out->size = MAX2(in->size, store->TexgenSize[unit]); - out->flags |= (in->flags & VEC_SIZE_FLAGS) | texUnit->TexGenEnabled; - out->count = count; - - copy = (all_bits[in->size] & ~texUnit->TexGenEnabled); - if (copy) - _mesa_copy_tab[copy]( out, in ); - - if (texUnit->TexGenEnabled & S_BIT) { - GLuint i; - switch (texUnit->GenS.Mode) { - case GL_OBJECT_LINEAR: - _mesa_dotprod_tab[obj->size]( (GLfloat *)out->data, - sizeof(out->data[0]), obj, - texUnit->ObjectPlane[GEN_S] ); - break; - case GL_EYE_LINEAR: - _mesa_dotprod_tab[eye->size]( (GLfloat *)out->data, - sizeof(out->data[0]), eye, - texUnit->EyePlane[GEN_S] ); - break; - case GL_SPHERE_MAP: - for (i = 0; i < count; i++) - texcoord[i][0] = f[i][0] * m[i] + 0.5F; - break; - case GL_REFLECTION_MAP_NV: - for (i=0;istart; - for (i=0;istride)) { - texcoord[i][0] = norm[0]; - } - break; - } - default: - _mesa_problem(ctx, "Bad S texgen"); - } - } - - if (texUnit->TexGenEnabled & T_BIT) { - GLuint i; - switch (texUnit->GenT.Mode) { - case GL_OBJECT_LINEAR: - _mesa_dotprod_tab[obj->size]( &(out->data[0][1]), - sizeof(out->data[0]), obj, - texUnit->ObjectPlane[GEN_T] ); - break; - case GL_EYE_LINEAR: - _mesa_dotprod_tab[eye->size]( &(out->data[0][1]), - sizeof(out->data[0]), eye, - texUnit->EyePlane[GEN_T] ); - break; - case GL_SPHERE_MAP: - for (i = 0; i < count; i++) - texcoord[i][1] = f[i][1] * m[i] + 0.5F; - break; - case GL_REFLECTION_MAP_NV: - for (i=0;istart; - for (i=0;istride)) { - texcoord[i][1] = norm[1]; - } - break; - } - default: - _mesa_problem(ctx, "Bad T texgen"); - } - } - - if (texUnit->TexGenEnabled & R_BIT) { - GLuint i; - switch (texUnit->GenR.Mode) { - case GL_OBJECT_LINEAR: - _mesa_dotprod_tab[obj->size]( &(out->data[0][2]), - sizeof(out->data[0]), obj, - texUnit->ObjectPlane[GEN_R] ); - break; - case GL_EYE_LINEAR: - _mesa_dotprod_tab[eye->size]( &(out->data[0][2]), - sizeof(out->data[0]), eye, - texUnit->EyePlane[GEN_R] ); - break; - case GL_REFLECTION_MAP_NV: - for (i=0;istart; - for (i=0;istride)) { - texcoord[i][2] = norm[2]; - } - break; - } - default: - _mesa_problem(ctx, "Bad R texgen"); - } - } - - if (texUnit->TexGenEnabled & Q_BIT) { - switch (texUnit->GenQ.Mode) { - case GL_OBJECT_LINEAR: - _mesa_dotprod_tab[obj->size]( &(out->data[0][3]), - sizeof(out->data[0]), obj, - texUnit->ObjectPlane[GEN_Q] ); - break; - case GL_EYE_LINEAR: - _mesa_dotprod_tab[eye->size]( &(out->data[0][3]), - sizeof(out->data[0]), eye, - texUnit->EyePlane[GEN_Q] ); - break; - default: - _mesa_problem(ctx, "Bad Q texgen"); - } - } -} - - - - -static GLboolean run_texgen_stage( struct gl_context *ctx, - struct tnl_pipeline_stage *stage ) -{ - struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - struct texgen_stage_data *store = TEXGEN_STAGE_DATA(stage); - GLuint i; - - if (!ctx->Texture._TexGenEnabled || ctx->VertexProgram._Current) - return GL_TRUE; - - for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++) { - struct gl_fixedfunc_texture_unit *texUnit = - &ctx->Texture.FixedFuncUnit[i]; - - if (texUnit->TexGenEnabled) { - store->TexgenFunc[i]( ctx, store, i ); - - VB->AttribPtr[VERT_ATTRIB_TEX0 + i] = &store->texcoord[i]; - } - } - - return GL_TRUE; -} - - -static void validate_texgen_stage( struct gl_context *ctx, - struct tnl_pipeline_stage *stage ) -{ - struct texgen_stage_data *store = TEXGEN_STAGE_DATA(stage); - GLuint i; - - if (!ctx->Texture._TexGenEnabled || ctx->VertexProgram._Current) - return; - - for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++) { - struct gl_fixedfunc_texture_unit *texUnit = - &ctx->Texture.FixedFuncUnit[i]; - - if (texUnit->TexGenEnabled) { - GLuint sz; - - if (texUnit->TexGenEnabled & Q_BIT) - sz = 4; - else if (texUnit->TexGenEnabled & R_BIT) - sz = 3; - else if (texUnit->TexGenEnabled & T_BIT) - sz = 2; - else - sz = 1; - - store->TexgenSize[i] = sz; - store->TexgenFunc[i] = texgen; /* general solution */ - - /* look for special texgen cases */ - if (texUnit->TexGenEnabled == (S_BIT|T_BIT|R_BIT)) { - if (texUnit->_GenFlags == TEXGEN_REFLECTION_MAP_NV) { - store->TexgenFunc[i] = texgen_reflection_map_nv; - } - else if (texUnit->_GenFlags == TEXGEN_NORMAL_MAP_NV) { - store->TexgenFunc[i] = texgen_normal_map_nv; - } - } - else if (texUnit->TexGenEnabled == (S_BIT|T_BIT) && - texUnit->_GenFlags == TEXGEN_SPHERE_MAP) { - store->TexgenFunc[i] = texgen_sphere_map; - } - } - } -} - - - - - -/* Called the first time stage->run() is invoked. - */ -static GLboolean alloc_texgen_data( struct gl_context *ctx, - struct tnl_pipeline_stage *stage ) -{ - struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - struct texgen_stage_data *store; - GLuint i; - - stage->privatePtr = calloc(1, sizeof(*store)); - store = TEXGEN_STAGE_DATA(stage); - if (!store) - return GL_FALSE; - - for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++) - _mesa_vector4f_alloc( &store->texcoord[i], 0, VB->Size, 32 ); - - store->tmp_f = malloc(VB->Size * sizeof(GLfloat) * 3); - store->tmp_m = malloc(VB->Size * sizeof(GLfloat)); - - return GL_TRUE; -} - - -static void free_texgen_data( struct tnl_pipeline_stage *stage ) - -{ - struct texgen_stage_data *store = TEXGEN_STAGE_DATA(stage); - GLuint i; - - if (store) { - for (i = 0 ; i < MAX_TEXTURE_COORD_UNITS ; i++) - if (store->texcoord[i].data) - _mesa_vector4f_free( &store->texcoord[i] ); - - - free( store->tmp_f ); - free( store->tmp_m ); - free( store ); - stage->privatePtr = NULL; - } -} - - - -const struct tnl_pipeline_stage _tnl_texgen_stage = -{ - "texgen", /* name */ - NULL, /* private data */ - alloc_texgen_data, /* destructor */ - free_texgen_data, /* destructor */ - validate_texgen_stage, /* check */ - run_texgen_stage /* run -- initially set to alloc data */ -}; diff --git a/src/mesa/tnl/t_vb_texmat.c b/src/mesa/tnl/t_vb_texmat.c deleted file mode 100644 index cf80995..0000000 --- a/src/mesa/tnl/t_vb_texmat.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - * - * Authors: - * Keith Whitwell - */ - - -#include "main/glheader.h" -#include "main/macros.h" - -#include "main/mtypes.h" - -#include "math/m_xform.h" - -#include "t_context.h" -#include "t_pipeline.h" - -/* Is there any real benefit seperating texmat from texgen? It means - * we need two lots of intermediate storage. Any changes to - * _NEW_TEXTURE will invalidate both sets -- it's only on changes to - * *only* _NEW_TEXTURE_MATRIX that texgen survives but texmat doesn't. - * - * However, the seperation of this code from the complex texgen stuff - * is very appealing. - */ -struct texmat_stage_data { - GLvector4f texcoord[MAX_TEXTURE_COORD_UNITS]; -}; - -#define TEXMAT_STAGE_DATA(stage) ((struct texmat_stage_data *)stage->privatePtr) - - - -static GLboolean run_texmat_stage( struct gl_context *ctx, - struct tnl_pipeline_stage *stage ) -{ - struct texmat_stage_data *store = TEXMAT_STAGE_DATA(stage); - struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - GLuint i; - - if (!ctx->Texture._TexMatEnabled || ctx->VertexProgram._Current) - return GL_TRUE; - - /* ENABLE_TEXMAT implies that the texture matrix is not the - * identity, so we don't have to check that here. - */ - for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++) { - if (ctx->Texture._TexMatEnabled & ENABLE_TEXMAT(i)) { - (void) TransformRaw( &store->texcoord[i], - ctx->TextureMatrixStack[i].Top, - VB->AttribPtr[_TNL_ATTRIB_TEX0 + i]); - - VB->AttribPtr[VERT_ATTRIB_TEX0+i] = &store->texcoord[i]; - } - } - - return GL_TRUE; -} - - -/* Called the first time stage->run() is invoked. - */ -static GLboolean alloc_texmat_data( struct gl_context *ctx, - struct tnl_pipeline_stage *stage ) -{ - struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - struct texmat_stage_data *store; - GLuint i; - - stage->privatePtr = calloc(1, sizeof(*store)); - store = TEXMAT_STAGE_DATA(stage); - if (!store) - return GL_FALSE; - - for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++) - _mesa_vector4f_alloc( &store->texcoord[i], 0, VB->Size, 32 ); - - return GL_TRUE; -} - - -static void free_texmat_data( struct tnl_pipeline_stage *stage ) -{ - struct texmat_stage_data *store = TEXMAT_STAGE_DATA(stage); - GLuint i; - - if (store) { - for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) - if (store->texcoord[i].data) - _mesa_vector4f_free( &store->texcoord[i] ); - free( store ); - stage->privatePtr = NULL; - } -} - - - -const struct tnl_pipeline_stage _tnl_texture_transform_stage = -{ - "texture transform", /* name */ - NULL, /* private data */ - alloc_texmat_data, - free_texmat_data, /* destructor */ - NULL, - run_texmat_stage, -}; diff --git a/src/mesa/tnl/t_vb_vertex.c b/src/mesa/tnl/t_vb_vertex.c deleted file mode 100644 index 053900e..0000000 --- a/src/mesa/tnl/t_vb_vertex.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - * - * Authors: - * Keith Whitwell - */ - - -#include "main/glheader.h" -#include "main/macros.h" -#include "main/mtypes.h" - -#include "math/m_xform.h" - -#include "util/bitscan.h" -#include "util/u_memory.h" - -#include "t_context.h" -#include "t_pipeline.h" - - - -struct vertex_stage_data { - GLvector4f eye; - GLvector4f clip; - GLvector4f proj; - GLubyte *clipmask; - GLubyte ormask; - GLubyte andmask; -}; - -#define VERTEX_STAGE_DATA(stage) ((struct vertex_stage_data *)stage->privatePtr) - - - - -/* This function implements cliptesting for user-defined clip planes. - * The clipping of primitives to these planes is implemented in - * t_render_clip.h. - */ -#define USER_CLIPTEST(NAME, SZ) \ -static void NAME( struct gl_context *ctx, \ - GLvector4f *clip, \ - GLubyte *clipmask, \ - GLubyte *clipormask, \ - GLubyte *clipandmask ) \ -{ \ - GLbitfield mask = ctx->Transform.ClipPlanesEnabled; \ - while (mask) { \ - const int p = u_bit_scan(&mask); \ - GLuint nr, i; \ - const GLfloat a = ctx->Transform._ClipUserPlane[p][0]; \ - const GLfloat b = ctx->Transform._ClipUserPlane[p][1]; \ - const GLfloat c = ctx->Transform._ClipUserPlane[p][2]; \ - const GLfloat d = ctx->Transform._ClipUserPlane[p][3]; \ - GLfloat *coord = (GLfloat *)clip->data; \ - GLuint stride = clip->stride; \ - GLuint count = clip->count; \ - \ - for (nr = 0, i = 0 ; i < count ; i++) { \ - GLfloat dp = coord[0] * a + coord[1] * b; \ - if (SZ > 2) dp += coord[2] * c; \ - if (SZ > 3) dp += coord[3] * d; else dp += d; \ - \ - if (dp < 0) { \ - nr++; \ - clipmask[i] |= CLIP_USER_BIT; \ - } \ - \ - STRIDE_F(coord, stride); \ - } \ - \ - if (nr > 0) { \ - *clipormask |= CLIP_USER_BIT; \ - if (nr == count) { \ - *clipandmask |= CLIP_USER_BIT; \ - return; \ - } \ - } \ - } \ -} - - -USER_CLIPTEST(userclip2, 2) -USER_CLIPTEST(userclip3, 3) -USER_CLIPTEST(userclip4, 4) - -static void (*(usercliptab[5]))( struct gl_context *, - GLvector4f *, GLubyte *, - GLubyte *, GLubyte * ) = -{ - NULL, - NULL, - userclip2, - userclip3, - userclip4 -}; - - -void -tnl_clip_prepare(struct gl_context *ctx) -{ - /* Neither the x86 nor sparc asm cliptest functions have been updated - * for ARB_depth_clamp, so force the C paths. - */ - if (ctx->Transform.DepthClampNear && ctx->Transform.DepthClampFar) { - static GLboolean c_funcs_installed = GL_FALSE; - if (!c_funcs_installed) { - init_c_cliptest(); - c_funcs_installed = GL_TRUE; - } - } -} - - - -static GLboolean run_vertex_stage( struct gl_context *ctx, - struct tnl_pipeline_stage *stage ) -{ - struct vertex_stage_data *store = (struct vertex_stage_data *)stage->privatePtr; - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &tnl->vb; - - if (ctx->VertexProgram._Current) - return GL_TRUE; - - tnl_clip_prepare(ctx); - - if (ctx->_NeedEyeCoords) { - /* Separate modelview transformation: - * Use combined ModelProject to avoid some depth artifacts - */ - if (ctx->ModelviewMatrixStack.Top->type == MATRIX_IDENTITY) - VB->EyePtr = VB->AttribPtr[_TNL_ATTRIB_POS]; - else - VB->EyePtr = TransformRaw( &store->eye, - ctx->ModelviewMatrixStack.Top, - VB->AttribPtr[_TNL_ATTRIB_POS]); - } - - /* make sure the inverse is up to date */ - _math_matrix_analyse(&ctx->_ModelProjectMatrix); - - VB->ClipPtr = TransformRaw( &store->clip, - &ctx->_ModelProjectMatrix, - VB->AttribPtr[_TNL_ATTRIB_POS] ); - - /* Drivers expect this to be clean to element 4... - */ - switch (VB->ClipPtr->size) { - case 1: - /* impossible */ - case 2: - _mesa_vector4f_clean_elem( VB->ClipPtr, VB->Count, 2 ); - FALLTHROUGH; - case 3: - _mesa_vector4f_clean_elem( VB->ClipPtr, VB->Count, 3 ); - FALLTHROUGH; - case 4: - break; - } - - - /* Cliptest and perspective divide. Clip functions must clear - * the clipmask. - */ - store->ormask = 0; - store->andmask = CLIP_FRUSTUM_BITS; - - if (tnl->NeedNdcCoords) { - VB->NdcPtr = - _mesa_clip_tab[VB->ClipPtr->size]( VB->ClipPtr, - &store->proj, - store->clipmask, - &store->ormask, - &store->andmask, - !(ctx->Transform.DepthClampNear && - ctx->Transform.DepthClampFar) ); - } - else { - VB->NdcPtr = NULL; - _mesa_clip_np_tab[VB->ClipPtr->size]( VB->ClipPtr, - NULL, - store->clipmask, - &store->ormask, - &store->andmask, - !(ctx->Transform.DepthClampNear && - ctx->Transform.DepthClampFar) ); - } - - if (store->andmask) - return GL_FALSE; - - - /* Test userclip planes. This contributes to VB->ClipMask, so - * is essentially required to be in this stage. - */ - if (ctx->Transform.ClipPlanesEnabled) { - usercliptab[VB->ClipPtr->size]( ctx, - VB->ClipPtr, - store->clipmask, - &store->ormask, - &store->andmask ); - - if (store->andmask) - return GL_FALSE; - } - - VB->ClipAndMask = store->andmask; - VB->ClipOrMask = store->ormask; - VB->ClipMask = store->clipmask; - - return GL_TRUE; -} - - -static GLboolean init_vertex_stage( struct gl_context *ctx, - struct tnl_pipeline_stage *stage ) -{ - struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - struct vertex_stage_data *store; - GLuint size = VB->Size; - - stage->privatePtr = calloc(1, sizeof(*store)); - store = VERTEX_STAGE_DATA(stage); - if (!store) - return GL_FALSE; - - _mesa_vector4f_alloc( &store->eye, 0, size, 32 ); - _mesa_vector4f_alloc( &store->clip, 0, size, 32 ); - _mesa_vector4f_alloc( &store->proj, 0, size, 32 ); - - store->clipmask = align_malloc(sizeof(GLubyte)*size, 32 ); - - if (!store->clipmask || - !store->eye.data || - !store->clip.data || - !store->proj.data) - return GL_FALSE; - - return GL_TRUE; -} - -static void dtr( struct tnl_pipeline_stage *stage ) -{ - struct vertex_stage_data *store = VERTEX_STAGE_DATA(stage); - - if (store) { - _mesa_vector4f_free( &store->eye ); - _mesa_vector4f_free( &store->clip ); - _mesa_vector4f_free( &store->proj ); - align_free( store->clipmask ); - free(store); - stage->privatePtr = NULL; - stage->run = init_vertex_stage; - } -} - - -const struct tnl_pipeline_stage _tnl_vertex_transform_stage = -{ - "modelview/project/cliptest/divide", - NULL, /* private data */ - init_vertex_stage, - dtr, /* destructor */ - NULL, - run_vertex_stage /* run -- initially set to init */ -}; diff --git a/src/mesa/tnl/t_vertex.c b/src/mesa/tnl/t_vertex.c deleted file mode 100644 index 0d29403..0000000 --- a/src/mesa/tnl/t_vertex.c +++ /dev/null @@ -1,580 +0,0 @@ -/* - * Copyright 2003 VMware, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * 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 NON-INFRINGEMENT. IN NO EVENT SHALL - * VMWARE AND/OR THEIR SUPPLIERS 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. - * - * Authors: - * Keith Whitwell - */ - -#include -#include "main/glheader.h" -#include "main/context.h" -#include "main/execmem.h" -#include "util/u_memory.h" -#include "swrast/s_chan.h" -#include "t_context.h" -#include "t_vertex.h" - -#define DBG 0 - -/* Build and manage clipspace/ndc/window vertices. - */ - -static GLboolean match_fastpath( struct tnl_clipspace *vtx, - const struct tnl_clipspace_fastpath *fp) -{ - GLuint j; - - if (vtx->attr_count != fp->attr_count) - return GL_FALSE; - - for (j = 0; j < vtx->attr_count; j++) - if (vtx->attr[j].format != fp->attr[j].format || - vtx->attr[j].inputsize != fp->attr[j].size || - vtx->attr[j].vertoffset != fp->attr[j].offset) - return GL_FALSE; - - if (fp->match_strides) { - if (vtx->vertex_size != fp->vertex_size) - return GL_FALSE; - - for (j = 0; j < vtx->attr_count; j++) - if (vtx->attr[j].inputstride != fp->attr[j].stride) - return GL_FALSE; - } - - return GL_TRUE; -} - -static GLboolean search_fastpath_emit( struct tnl_clipspace *vtx ) -{ - struct tnl_clipspace_fastpath *fp = vtx->fastpath; - - for ( ; fp ; fp = fp->next) { - if (match_fastpath(vtx, fp)) { - vtx->emit = fp->func; - return GL_TRUE; - } - } - - return GL_FALSE; -} - -void _tnl_register_fastpath( struct tnl_clipspace *vtx, - GLboolean match_strides ) -{ - struct tnl_clipspace_fastpath *fastpath = CALLOC_STRUCT(tnl_clipspace_fastpath); - GLuint i; - - if (fastpath == NULL) { - _mesa_error_no_memory(__func__); - return; - } - - fastpath->vertex_size = vtx->vertex_size; - fastpath->attr_count = vtx->attr_count; - fastpath->match_strides = match_strides; - fastpath->func = vtx->emit; - fastpath->attr = malloc(vtx->attr_count * sizeof(fastpath->attr[0])); - - if (fastpath->attr == NULL) { - free(fastpath); - _mesa_error_no_memory(__func__); - return; - } - - for (i = 0; i < vtx->attr_count; i++) { - fastpath->attr[i].format = vtx->attr[i].format; - fastpath->attr[i].stride = vtx->attr[i].inputstride; - fastpath->attr[i].size = vtx->attr[i].inputsize; - fastpath->attr[i].offset = vtx->attr[i].vertoffset; - } - - fastpath->next = vtx->fastpath; - vtx->fastpath = fastpath; -} - - - -/*********************************************************************** - * Build codegen functions or return generic ones: - */ -static void choose_emit_func( struct gl_context *ctx, GLuint count, GLubyte *dest) -{ - struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); - struct tnl_clipspace_attr *a = vtx->attr; - const GLuint attr_count = vtx->attr_count; - GLuint j; - - for (j = 0; j < attr_count; j++) { - GLvector4f *vptr = VB->AttribPtr[a[j].attrib]; - a[j].inputstride = vptr->stride; - a[j].inputsize = vptr->size; - a[j].emit = a[j].insert[vptr->size - 1]; /* not always used */ - } - - vtx->emit = NULL; - - /* Does this match an existing (hardwired, codegen or known-bad) - * fastpath? - */ - if (search_fastpath_emit(vtx)) { - /* Use this result. If it is null, then it is already known - * that the current state will fail for codegen and there is no - * point trying again. - */ - } - else if (vtx->codegen_emit) { - vtx->codegen_emit(ctx); - } - - if (!vtx->emit) { - _tnl_generate_hardwired_emit(ctx); - } - - /* Otherwise use the generic version: - */ - if (!vtx->emit) - vtx->emit = _tnl_generic_emit; - - vtx->emit( ctx, count, dest ); -} - - - -static void choose_interp_func( struct gl_context *ctx, - GLfloat t, - GLuint edst, GLuint eout, GLuint ein, - GLboolean force_boundary ) -{ - struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); - GLboolean unfilled = (ctx->Polygon.FrontMode != GL_FILL || - ctx->Polygon.BackMode != GL_FILL); - GLboolean twosided = ctx->Light.Enabled && ctx->Light.Model.TwoSide; - - if (vtx->need_extras && (twosided || unfilled)) { - vtx->interp = _tnl_generic_interp_extras; - } else { - vtx->interp = _tnl_generic_interp; - } - - vtx->interp( ctx, t, edst, eout, ein, force_boundary ); -} - - -static void choose_copy_pv_func( struct gl_context *ctx, GLuint edst, GLuint esrc ) -{ - struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); - GLboolean unfilled = (ctx->Polygon.FrontMode != GL_FILL || - ctx->Polygon.BackMode != GL_FILL); - - GLboolean twosided = ctx->Light.Enabled && ctx->Light.Model.TwoSide; - - if (vtx->need_extras && (twosided || unfilled)) { - vtx->copy_pv = _tnl_generic_copy_pv_extras; - } else { - vtx->copy_pv = _tnl_generic_copy_pv; - } - - vtx->copy_pv( ctx, edst, esrc ); -} - - -/*********************************************************************** - * Public entrypoints, mostly dispatch to the above: - */ - - -/* Interpolate between two vertices to produce a third: - */ -void _tnl_interp( struct gl_context *ctx, - GLfloat t, - GLuint edst, GLuint eout, GLuint ein, - GLboolean force_boundary ) -{ - struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); - vtx->interp( ctx, t, edst, eout, ein, force_boundary ); -} - -/* Copy colors from one vertex to another: - */ -void _tnl_copy_pv( struct gl_context *ctx, GLuint edst, GLuint esrc ) -{ - struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); - vtx->copy_pv( ctx, edst, esrc ); -} - - -/* Extract a named attribute from a hardware vertex. Will have to - * reverse any viewport transformation, swizzling or other conversions - * which may have been applied: - */ -void _tnl_get_attr( struct gl_context *ctx, const void *vin, - GLenum attr, GLfloat *dest ) -{ - struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); - const struct tnl_clipspace_attr *a = vtx->attr; - const GLuint attr_count = vtx->attr_count; - GLuint j; - - for (j = 0; j < attr_count; j++) { - if (a[j].attrib == attr) { - a[j].extract( &a[j], dest, (GLubyte *)vin + a[j].vertoffset ); - return; - } - } - - /* Else return the value from ctx->Current. - */ - if (attr == _TNL_ATTRIB_POINTSIZE) { - /* If the hardware vertex doesn't have point size then use size from - * struct gl_context. XXX this will be wrong if drawing attenuated points! - */ - dest[0] = ctx->Point.Size; - } - else { - memcpy( dest, ctx->Current.Attrib[attr], 4*sizeof(GLfloat)); - } -} - - -/* Complementary operation to the above. - */ -void _tnl_set_attr( struct gl_context *ctx, void *vout, - GLenum attr, const GLfloat *src ) -{ - struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); - const struct tnl_clipspace_attr *a = vtx->attr; - const GLuint attr_count = vtx->attr_count; - GLuint j; - - for (j = 0; j < attr_count; j++) { - if (a[j].attrib == attr) { - a[j].insert[4-1]( &a[j], (GLubyte *)vout + a[j].vertoffset, src ); - return; - } - } -} - - -void *_tnl_get_vertex( struct gl_context *ctx, GLuint nr ) -{ - struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); - - return vtx->vertex_buf + nr * vtx->vertex_size; -} - -void _tnl_invalidate_vertex_state( struct gl_context *ctx, GLuint new_state ) -{ - /* if two-sided lighting changes or filled/unfilled polygon state changes */ - if (new_state & (_NEW_LIGHT | _NEW_POLYGON) ) { - struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); - vtx->new_inputs = ~0; - vtx->interp = choose_interp_func; - vtx->copy_pv = choose_copy_pv_func; - } -} - -static void invalidate_funcs( struct tnl_clipspace *vtx ) -{ - vtx->emit = choose_emit_func; - vtx->interp = choose_interp_func; - vtx->copy_pv = choose_copy_pv_func; - vtx->new_inputs = ~0; -} - -GLuint _tnl_install_attrs( struct gl_context *ctx, const struct tnl_attr_map *map, - GLuint nr, const GLfloat *vp, - GLuint unpacked_size ) -{ - struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); - GLuint offset = 0; - GLuint i, j; - - assert(nr < _TNL_ATTRIB_MAX); - assert(nr == 0 || map[0].attrib == VERT_ATTRIB_POS); - - vtx->new_inputs = ~0; - vtx->need_viewport = GL_FALSE; - - if (vp) { - vtx->need_viewport = GL_TRUE; - } - - for (j = 0, i = 0; i < nr; i++) { - const GLuint format = map[i].format; - if (format == EMIT_PAD) { - if (DBG) - printf("%d: pad %d, offset %d\n", i, - map[i].offset, offset); - - offset += map[i].offset; - - } - else { - GLuint tmpoffset; - - if (unpacked_size) - tmpoffset = map[i].offset; - else - tmpoffset = offset; - - if (vtx->attr_count != j || - vtx->attr[j].attrib != map[i].attrib || - vtx->attr[j].format != format || - vtx->attr[j].vertoffset != tmpoffset) { - invalidate_funcs(vtx); - - vtx->attr[j].attrib = map[i].attrib; - vtx->attr[j].format = format; - vtx->attr[j].vp = vp; - vtx->attr[j].insert = _tnl_format_info[format].insert; - vtx->attr[j].extract = _tnl_format_info[format].extract; - vtx->attr[j].vertattrsize = _tnl_format_info[format].attrsize; - vtx->attr[j].vertoffset = tmpoffset; - } - - - if (DBG) - printf("%d: %s, vp %p, offset %d\n", i, - _tnl_format_info[format].name, (void *)vp, - vtx->attr[j].vertoffset); - - offset += _tnl_format_info[format].attrsize; - j++; - } - } - - vtx->attr_count = j; - - if (unpacked_size) - vtx->vertex_size = unpacked_size; - else - vtx->vertex_size = offset; - - assert(vtx->vertex_size <= vtx->max_vertex_size); - return vtx->vertex_size; -} - - - -void _tnl_invalidate_vertices( struct gl_context *ctx, GLuint newinputs ) -{ - struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); - vtx->new_inputs |= newinputs; -} - - -/* This event has broader use beyond this file - will move elsewhere - * and probably invoke a driver callback. - */ -void _tnl_notify_pipeline_output_change( struct gl_context *ctx ) -{ - struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); - invalidate_funcs(vtx); -} - - -static void adjust_input_ptrs( struct gl_context *ctx, GLint diff) -{ - struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); - struct tnl_clipspace_attr *a = vtx->attr; - const GLuint count = vtx->attr_count; - GLuint j; - - diff -= 1; - for (j=0; jAttribPtr[a->attrib]; - (a++)->inputptr += diff*vptr->stride; - } -} - -static void update_input_ptrs( struct gl_context *ctx, GLuint start ) -{ - struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); - struct tnl_clipspace_attr *a = vtx->attr; - const GLuint count = vtx->attr_count; - GLuint j; - - for (j = 0; j < count; j++) { - GLvector4f *vptr = VB->AttribPtr[a[j].attrib]; - - if (vtx->emit != choose_emit_func) { - assert(a[j].inputstride == vptr->stride); - assert(a[j].inputsize == vptr->size); - } - - a[j].inputptr = ((GLubyte *)vptr->data) + start * vptr->stride; - } - - if (a->vp) { - vtx->vp_scale[0] = a->vp[MAT_SX]; - vtx->vp_scale[1] = a->vp[MAT_SY]; - vtx->vp_scale[2] = a->vp[MAT_SZ]; - vtx->vp_scale[3] = 1.0; - vtx->vp_xlate[0] = a->vp[MAT_TX]; - vtx->vp_xlate[1] = a->vp[MAT_TY]; - vtx->vp_xlate[2] = a->vp[MAT_TZ]; - vtx->vp_xlate[3] = 0.0; - } -} - - -void _tnl_build_vertices( struct gl_context *ctx, - GLuint start, - GLuint end, - GLuint newinputs ) -{ - struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); - update_input_ptrs( ctx, start ); - vtx->emit( ctx, end - start, - (GLubyte *)(vtx->vertex_buf + - start * vtx->vertex_size)); -} - -/* Emit VB vertices start..end to dest. Note that VB vertex at - * postion start will be emitted to dest at position zero. - */ -void *_tnl_emit_vertices_to_buffer( struct gl_context *ctx, - GLuint start, - GLuint end, - void *dest ) -{ - struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); - - update_input_ptrs(ctx, start); - /* Note: dest should not be adjusted for non-zero 'start' values: - */ - vtx->emit( ctx, end - start, (GLubyte*) dest ); - return (void *)((GLubyte *)dest + vtx->vertex_size * (end - start)); -} - -/* Emit indexed VB vertices start..end to dest. Note that VB vertex at - * postion start will be emitted to dest at position zero. - */ - -void *_tnl_emit_indexed_vertices_to_buffer( struct gl_context *ctx, - const GLuint *elts, - GLuint start, - GLuint end, - void *dest ) -{ - struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); - GLuint oldIndex; - GLubyte *cdest = dest; - - update_input_ptrs(ctx, oldIndex = elts[start++]); - vtx->emit( ctx, 1, cdest ); - cdest += vtx->vertex_size; - - for (; start < end; ++start) { - adjust_input_ptrs(ctx, elts[start] - oldIndex); - oldIndex = elts[start]; - vtx->emit( ctx, 1, cdest); - cdest += vtx->vertex_size; - } - - return (void *) cdest; -} - - -void _tnl_init_vertices( struct gl_context *ctx, - GLuint vb_size, - GLuint max_vertex_size ) -{ - struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); - - _tnl_install_attrs( ctx, NULL, 0, NULL, 0 ); - - vtx->need_extras = GL_TRUE; - if (max_vertex_size > vtx->max_vertex_size) { - _tnl_free_vertices( ctx ); - vtx->max_vertex_size = max_vertex_size; - vtx->vertex_buf = align_calloc(vb_size * max_vertex_size, 32 ); - invalidate_funcs(vtx); - } - - switch(CHAN_TYPE) { - case GL_UNSIGNED_BYTE: - vtx->chan_scale[0] = 255.0; - vtx->chan_scale[1] = 255.0; - vtx->chan_scale[2] = 255.0; - vtx->chan_scale[3] = 255.0; - break; - case GL_UNSIGNED_SHORT: - vtx->chan_scale[0] = 65535.0; - vtx->chan_scale[1] = 65535.0; - vtx->chan_scale[2] = 65535.0; - vtx->chan_scale[3] = 65535.0; - break; - default: - vtx->chan_scale[0] = 1.0; - vtx->chan_scale[1] = 1.0; - vtx->chan_scale[2] = 1.0; - vtx->chan_scale[3] = 1.0; - break; - } - - vtx->identity[0] = 0.0; - vtx->identity[1] = 0.0; - vtx->identity[2] = 0.0; - vtx->identity[3] = 1.0; - - vtx->codegen_emit = NULL; - -#ifdef USE_SSE_ASM - if (!getenv("MESA_NO_CODEGEN")) - vtx->codegen_emit = _tnl_generate_sse_emit; -#endif -} - - -void _tnl_free_vertices( struct gl_context *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - if (tnl) { - struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); - struct tnl_clipspace_fastpath *fp, *tmp; - - align_free(vtx->vertex_buf); - vtx->vertex_buf = NULL; - - for (fp = vtx->fastpath ; fp ; fp = tmp) { - tmp = fp->next; - free(fp->attr); - - /* KW: At the moment, fp->func is constrained to be allocated by - * _mesa_exec_alloc(), as the hardwired fastpaths in - * t_vertex_generic.c are handled specially. It would be nice - * to unify them, but this probably won't change until this - * module gets another overhaul. - */ - _mesa_exec_free((void *) fp->func); - free(fp); - } - - vtx->fastpath = NULL; - } -} diff --git a/src/mesa/tnl/t_vertex.h b/src/mesa/tnl/t_vertex.h deleted file mode 100644 index a84b299..0000000 --- a/src/mesa/tnl/t_vertex.h +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright 2003 VMware, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * 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 NON-INFRINGEMENT. IN NO EVENT SHALL - * VMWARE AND/OR THEIR SUPPLIERS 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. - * - * Authors: - * Keith Whitwell - */ - -#ifndef _TNL_VERTEX_H -#define _TNL_VERTEX_H - -#include "main/glheader.h" -#include "t_context.h" - -struct gl_context; -struct tnl_clipspace; - -/* New mechanism to specify hardware vertices so that tnl can build - * and manipulate them directly. - */ - - -/* It will probably be necessary to allow drivers to specify new - * emit-styles to cover all the weird and wacky things out there. - */ -enum tnl_attr_format { - EMIT_1F, - EMIT_2F, - EMIT_3F, - EMIT_4F, - EMIT_2F_VIEWPORT, /* do viewport transform and emit */ - EMIT_3F_VIEWPORT, /* do viewport transform and emit */ - EMIT_4F_VIEWPORT, /* do viewport transform and emit */ - EMIT_3F_XYW, /* for projective texture */ - EMIT_1UB_1F, /* for fog coordinate */ - EMIT_3UB_3F_RGB, /* for specular color */ - EMIT_3UB_3F_BGR, /* for specular color */ - EMIT_4UB_4F_RGBA, /* for color */ - EMIT_4UB_4F_BGRA, /* for color */ - EMIT_4UB_4F_ARGB, /* for color */ - EMIT_4UB_4F_ABGR, /* for color */ - EMIT_4CHAN_4F_RGBA, /* for swrast color */ - EMIT_PAD, /* leave a hole of 'offset' bytes */ - EMIT_MAX -}; - -struct tnl_attr_map { - GLuint attrib; /* _TNL_ATTRIB_ enum */ - enum tnl_attr_format format; - GLuint offset; -}; - -struct tnl_format_info { - const char *name; - tnl_extract_func extract; - tnl_insert_func insert[4]; - const GLuint attrsize; -}; - -extern const struct tnl_format_info _tnl_format_info[EMIT_MAX]; - - -/* Interpolate between two vertices to produce a third: - */ -extern void _tnl_interp( struct gl_context *ctx, - GLfloat t, - GLuint edst, GLuint eout, GLuint ein, - GLboolean force_boundary ); - -/* Copy colors from one vertex to another: - */ -extern void _tnl_copy_pv( struct gl_context *ctx, GLuint edst, GLuint esrc ); - - -/* Extract a named attribute from a hardware vertex. Will have to - * reverse any viewport transformation, swizzling or other conversions - * which may have been applied: - */ -extern void _tnl_get_attr( struct gl_context *ctx, const void *vertex, GLenum attrib, - GLfloat *dest ); - -/* Complementary to the above. - */ -extern void _tnl_set_attr( struct gl_context *ctx, void *vout, GLenum attrib, - const GLfloat *src ); - - -extern void *_tnl_get_vertex( struct gl_context *ctx, GLuint nr ); - -extern GLuint _tnl_install_attrs( struct gl_context *ctx, - const struct tnl_attr_map *map, - GLuint nr, const GLfloat *vp, - GLuint unpacked_size ); - -extern void _tnl_free_vertices( struct gl_context *ctx ); - -extern void _tnl_init_vertices( struct gl_context *ctx, - GLuint vb_size, - GLuint max_vertex_size ); - -extern void *_tnl_emit_vertices_to_buffer( struct gl_context *ctx, - GLuint start, - GLuint end, - void *dest ); - -/* This function isn't optimal. Check out - * gallium/auxilary/translate for a more comprehensive implementation of - * the same functionality. - */ - -extern void *_tnl_emit_indexed_vertices_to_buffer( struct gl_context *ctx, - const GLuint *elts, - GLuint start, - GLuint end, - void *dest ); - - -extern void _tnl_build_vertices( struct gl_context *ctx, - GLuint start, - GLuint end, - GLuint newinputs ); - -extern void _tnl_invalidate_vertices( struct gl_context *ctx, GLuint newinputs ); - -extern void _tnl_invalidate_vertex_state( struct gl_context *ctx, GLuint new_state ); - -extern void _tnl_notify_pipeline_output_change( struct gl_context *ctx ); - - -#define GET_VERTEX_STATE(ctx) &(TNL_CONTEXT(ctx)->clipspace) - -/* Internal function: - */ -void _tnl_register_fastpath( struct tnl_clipspace *vtx, - GLboolean match_strides ); - - -/* t_vertex_generic.c -- Internal functions for t_vertex.c - */ -void _tnl_generic_copy_pv_extras( struct gl_context *ctx, - GLuint dst, GLuint src ); - -void _tnl_generic_interp_extras( struct gl_context *ctx, - GLfloat t, - GLuint dst, GLuint out, GLuint in, - GLboolean force_boundary ); - -void _tnl_generic_copy_pv( struct gl_context *ctx, GLuint edst, GLuint esrc ); - -void _tnl_generic_interp( struct gl_context *ctx, - GLfloat t, - GLuint edst, GLuint eout, GLuint ein, - GLboolean force_boundary ); - -void _tnl_generic_emit( struct gl_context *ctx, - GLuint count, - GLubyte *v ); - -void _tnl_generate_hardwired_emit( struct gl_context *ctx ); - -/* t_vertex_sse.c -- Internal functions for t_vertex.c - */ -void _tnl_generate_sse_emit( struct gl_context *ctx ); - -#endif diff --git a/src/mesa/tnl/t_vertex_generic.c b/src/mesa/tnl/t_vertex_generic.c deleted file mode 100644 index 7f871a4..0000000 --- a/src/mesa/tnl/t_vertex_generic.c +++ /dev/null @@ -1,1152 +0,0 @@ - -/* - * Copyright 2003 VMware, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * 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 NON-INFRINGEMENT. IN NO EVENT SHALL - * VMWARE AND/OR THEIR SUPPLIERS 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. - * - * Authors: - * Keith Whitwell - */ - -#include "main/glheader.h" -#include "main/context.h" -#include "main/macros.h" -#include "swrast/s_chan.h" -#include "t_context.h" -#include "t_vertex.h" - - -#if 0 -#define DEBUG_INSERT printf("%s\n", __func__) -#else -#define DEBUG_INSERT -#endif - - -/* - * These functions take the NDC coordinates pointed to by 'in', apply the - * NDC->Viewport mapping and store the results at 'v'. - */ - -static inline void insert_4f_viewport_4( const struct tnl_clipspace_attr *a, GLubyte *v, - const GLfloat *in ) -{ - GLfloat *out = (GLfloat *)v; - const GLfloat * const vp = a->vp; - DEBUG_INSERT; - out[0] = vp[0] * in[0] + vp[12]; - out[1] = vp[5] * in[1] + vp[13]; - out[2] = vp[10] * in[2] + vp[14]; - out[3] = in[3]; -} - -static inline void insert_4f_viewport_3( const struct tnl_clipspace_attr *a, GLubyte *v, - const GLfloat *in ) -{ - GLfloat *out = (GLfloat *)v; - const GLfloat * const vp = a->vp; - DEBUG_INSERT; - out[0] = vp[0] * in[0] + vp[12]; - out[1] = vp[5] * in[1] + vp[13]; - out[2] = vp[10] * in[2] + vp[14]; - out[3] = 1; -} - -static inline void insert_4f_viewport_2( const struct tnl_clipspace_attr *a, GLubyte *v, - const GLfloat *in ) -{ - GLfloat *out = (GLfloat *)v; - const GLfloat * const vp = a->vp; - DEBUG_INSERT; - out[0] = vp[0] * in[0] + vp[12]; - out[1] = vp[5] * in[1] + vp[13]; - out[2] = vp[14]; - out[3] = 1; -} - -static inline void insert_4f_viewport_1( const struct tnl_clipspace_attr *a, GLubyte *v, - const GLfloat *in ) -{ - GLfloat *out = (GLfloat *)v; - const GLfloat * const vp = a->vp; - DEBUG_INSERT; - out[0] = vp[0] * in[0] + vp[12]; - out[1] = vp[13]; - out[2] = vp[14]; - out[3] = 1; -} - -static inline void insert_3f_viewport_3( const struct tnl_clipspace_attr *a, GLubyte *v, - const GLfloat *in ) -{ - GLfloat *out = (GLfloat *)v; - const GLfloat * const vp = a->vp; - DEBUG_INSERT; - out[0] = vp[0] * in[0] + vp[12]; - out[1] = vp[5] * in[1] + vp[13]; - out[2] = vp[10] * in[2] + vp[14]; -} - -static inline void insert_3f_viewport_2( const struct tnl_clipspace_attr *a, GLubyte *v, - const GLfloat *in ) -{ - GLfloat *out = (GLfloat *)v; - const GLfloat * const vp = a->vp; - DEBUG_INSERT; - out[0] = vp[0] * in[0] + vp[12]; - out[1] = vp[5] * in[1] + vp[13]; - out[2] = vp[14]; -} - -static inline void insert_3f_viewport_1( const struct tnl_clipspace_attr *a, GLubyte *v, - const GLfloat *in ) -{ - GLfloat *out = (GLfloat *)v; - const GLfloat * const vp = a->vp; - DEBUG_INSERT; - out[0] = vp[0] * in[0] + vp[12]; - out[1] = vp[13]; - out[2] = vp[14]; -} - -static inline void insert_2f_viewport_2( const struct tnl_clipspace_attr *a, GLubyte *v, - const GLfloat *in ) -{ - GLfloat *out = (GLfloat *)v; - const GLfloat * const vp = a->vp; - DEBUG_INSERT; - out[0] = vp[0] * in[0] + vp[12]; - out[1] = vp[5] * in[1] + vp[13]; -} - -static inline void insert_2f_viewport_1( const struct tnl_clipspace_attr *a, GLubyte *v, - const GLfloat *in ) -{ - GLfloat *out = (GLfloat *)v; - const GLfloat * const vp = a->vp; - DEBUG_INSERT; - out[0] = vp[0] * in[0] + vp[12]; - out[1] = vp[13]; -} - - -/* - * These functions do the same as above, except for the viewport mapping. - */ - -static inline void insert_4f_4( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in ) -{ - GLfloat *out = (GLfloat *)(v); - (void) a; - DEBUG_INSERT; - out[0] = in[0]; - out[1] = in[1]; - out[2] = in[2]; - out[3] = in[3]; -} - -static inline void insert_4f_3( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in ) -{ - GLfloat *out = (GLfloat *)(v); - (void) a; - DEBUG_INSERT; - out[0] = in[0]; - out[1] = in[1]; - out[2] = in[2]; - out[3] = 1; -} - -static inline void insert_4f_2( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in ) -{ - GLfloat *out = (GLfloat *)(v); - (void) a; - DEBUG_INSERT; - out[0] = in[0]; - out[1] = in[1]; - out[2] = 0; - out[3] = 1; -} - -static inline void insert_4f_1( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in ) -{ - GLfloat *out = (GLfloat *)(v); - (void) a; - DEBUG_INSERT; - out[0] = in[0]; - out[1] = 0; - out[2] = 0; - out[3] = 1; -} - -static inline void insert_3f_xyw_4( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in ) -{ - GLfloat *out = (GLfloat *)(v); - (void) a; - DEBUG_INSERT; - out[0] = in[0]; - out[1] = in[1]; - out[2] = in[3]; -} - -static inline void insert_3f_xyw_err( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in ) -{ - (void) a; (void) v; (void) in; - DEBUG_INSERT; - exit(1); -} - -static inline void insert_3f_3( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in ) -{ - GLfloat *out = (GLfloat *)(v); - (void) a; - DEBUG_INSERT; - out[0] = in[0]; - out[1] = in[1]; - out[2] = in[2]; -} - -static inline void insert_3f_2( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in ) -{ - GLfloat *out = (GLfloat *)(v); - (void) a; - DEBUG_INSERT; - out[0] = in[0]; - out[1] = in[1]; - out[2] = 0; -} - -static inline void insert_3f_1( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in ) -{ - GLfloat *out = (GLfloat *)(v); - (void) a; - DEBUG_INSERT; - out[0] = in[0]; - out[1] = 0; - out[2] = 0; -} - - -static inline void insert_2f_2( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in ) -{ - GLfloat *out = (GLfloat *)(v); - (void) a; - DEBUG_INSERT; - out[0] = in[0]; - out[1] = in[1]; -} - -static inline void insert_2f_1( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in ) -{ - GLfloat *out = (GLfloat *)(v); - (void) a; - DEBUG_INSERT; - out[0] = in[0]; - out[1] = 0; -} - -static inline void insert_1f_1( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in ) -{ - GLfloat *out = (GLfloat *)(v); - (void) a; - DEBUG_INSERT; - out[0] = in[0]; -} - -static inline void insert_null( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in ) -{ - DEBUG_INSERT; - (void) a; (void) v; (void) in; -} - -static inline void insert_4chan_4f_rgba_4( const struct tnl_clipspace_attr *a, GLubyte *v, - const GLfloat *in ) -{ - GLchan *c = (GLchan *)v; - DEBUG_INSERT; - (void) a; - UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]); - UNCLAMPED_FLOAT_TO_CHAN(c[1], in[1]); - UNCLAMPED_FLOAT_TO_CHAN(c[2], in[2]); - UNCLAMPED_FLOAT_TO_CHAN(c[3], in[3]); -} - -static inline void insert_4chan_4f_rgba_3( const struct tnl_clipspace_attr *a, GLubyte *v, - const GLfloat *in ) -{ - GLchan *c = (GLchan *)v; - DEBUG_INSERT; - (void) a; - UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]); - UNCLAMPED_FLOAT_TO_CHAN(c[1], in[1]); - UNCLAMPED_FLOAT_TO_CHAN(c[2], in[2]); - c[3] = CHAN_MAX; -} - -static inline void insert_4chan_4f_rgba_2( const struct tnl_clipspace_attr *a, GLubyte *v, - const GLfloat *in ) -{ - GLchan *c = (GLchan *)v; - DEBUG_INSERT; - (void) a; - UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]); - UNCLAMPED_FLOAT_TO_CHAN(c[1], in[1]); - c[2] = 0; - c[3] = CHAN_MAX; -} - -static inline void insert_4chan_4f_rgba_1( const struct tnl_clipspace_attr *a, GLubyte *v, - const GLfloat *in ) -{ - GLchan *c = (GLchan *)v; - DEBUG_INSERT; - (void) a; - UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]); - c[1] = 0; - c[2] = 0; - c[3] = CHAN_MAX; -} - -static inline void insert_4ub_4f_rgba_4( const struct tnl_clipspace_attr *a, GLubyte *v, - const GLfloat *in ) -{ - DEBUG_INSERT; - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]); - UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]); -} - -static inline void insert_4ub_4f_rgba_3( const struct tnl_clipspace_attr *a, GLubyte *v, - const GLfloat *in ) -{ - DEBUG_INSERT; - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]); - v[3] = 0xff; -} - -static inline void insert_4ub_4f_rgba_2( const struct tnl_clipspace_attr *a, GLubyte *v, - const GLfloat *in ) -{ - DEBUG_INSERT; - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - v[2] = 0; - v[3] = 0xff; -} - -static inline void insert_4ub_4f_rgba_1( const struct tnl_clipspace_attr *a, GLubyte *v, - const GLfloat *in ) -{ - DEBUG_INSERT; - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); - v[1] = 0; - v[2] = 0; - v[3] = 0xff; -} - -static inline void insert_4ub_4f_bgra_4( const struct tnl_clipspace_attr *a, GLubyte *v, - const GLfloat *in ) -{ - DEBUG_INSERT; - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]); - UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]); -} - -static inline void insert_4ub_4f_bgra_3( const struct tnl_clipspace_attr *a, GLubyte *v, - const GLfloat *in ) -{ - DEBUG_INSERT; - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]); - v[3] = 0xff; -} - -static inline void insert_4ub_4f_bgra_2( const struct tnl_clipspace_attr *a, GLubyte *v, - const GLfloat *in ) -{ - DEBUG_INSERT; - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - v[0] = 0; - v[3] = 0xff; -} - -static inline void insert_4ub_4f_bgra_1( const struct tnl_clipspace_attr *a, GLubyte *v, - const GLfloat *in ) -{ - DEBUG_INSERT; - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); - v[1] = 0; - v[0] = 0; - v[3] = 0xff; -} - -static inline void insert_4ub_4f_argb_4( const struct tnl_clipspace_attr *a, GLubyte *v, - const GLfloat *in ) -{ - DEBUG_INSERT; - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[2]); - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[3]); -} - -static inline void insert_4ub_4f_argb_3( const struct tnl_clipspace_attr *a, GLubyte *v, - const GLfloat *in ) -{ - DEBUG_INSERT; - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[2]); - v[0] = 0xff; -} - -static inline void insert_4ub_4f_argb_2( const struct tnl_clipspace_attr *a, GLubyte *v, - const GLfloat *in ) -{ - DEBUG_INSERT; - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); - v[3] = 0x00; - v[0] = 0xff; -} - -static inline void insert_4ub_4f_argb_1( const struct tnl_clipspace_attr *a, GLubyte *v, - const GLfloat *in ) -{ - DEBUG_INSERT; - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]); - v[2] = 0x00; - v[3] = 0x00; - v[0] = 0xff; -} - -static inline void insert_4ub_4f_abgr_4( const struct tnl_clipspace_attr *a, GLubyte *v, - const GLfloat *in ) -{ - DEBUG_INSERT; - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[2]); - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[3]); -} - -static inline void insert_4ub_4f_abgr_3( const struct tnl_clipspace_attr *a, GLubyte *v, - const GLfloat *in ) -{ - DEBUG_INSERT; - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[2]); - v[0] = 0xff; -} - -static inline void insert_4ub_4f_abgr_2( const struct tnl_clipspace_attr *a, GLubyte *v, - const GLfloat *in ) -{ - DEBUG_INSERT; - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); - v[1] = 0x00; - v[0] = 0xff; -} - -static inline void insert_4ub_4f_abgr_1( const struct tnl_clipspace_attr *a, GLubyte *v, - const GLfloat *in ) -{ - DEBUG_INSERT; - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]); - v[2] = 0x00; - v[1] = 0x00; - v[0] = 0xff; -} - -static inline void insert_3ub_3f_rgb_3( const struct tnl_clipspace_attr *a, GLubyte *v, - const GLfloat *in ) -{ - DEBUG_INSERT; - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]); -} - -static inline void insert_3ub_3f_rgb_2( const struct tnl_clipspace_attr *a, GLubyte *v, - const GLfloat *in ) -{ - DEBUG_INSERT; - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - v[2] = 0; -} - -static inline void insert_3ub_3f_rgb_1( const struct tnl_clipspace_attr *a, GLubyte *v, - const GLfloat *in ) -{ - DEBUG_INSERT; - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); - v[1] = 0; - v[2] = 0; -} - -static inline void insert_3ub_3f_bgr_3( const struct tnl_clipspace_attr *a, GLubyte *v, - const GLfloat *in ) -{ - DEBUG_INSERT; - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]); -} - -static inline void insert_3ub_3f_bgr_2( const struct tnl_clipspace_attr *a, GLubyte *v, - const GLfloat *in ) -{ - DEBUG_INSERT; - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - v[0] = 0; -} - -static inline void insert_3ub_3f_bgr_1( const struct tnl_clipspace_attr *a, GLubyte *v, - const GLfloat *in ) -{ - DEBUG_INSERT; - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); - v[1] = 0; - v[0] = 0; -} - - -static inline void insert_1ub_1f_1( const struct tnl_clipspace_attr *a, GLubyte *v, - const GLfloat *in ) -{ - DEBUG_INSERT; - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); -} - - -/*********************************************************************** - * Functions to perform the reverse operations to the above, for - * swrast translation and clip-interpolation. - * - * Currently always extracts a full 4 floats. - */ - -static void extract_4f_viewport( const struct tnl_clipspace_attr *a, GLfloat *out, - const GLubyte *v ) -{ - const GLfloat *in = (const GLfloat *)v; - const GLfloat * const vp = a->vp; - - /* Although included for completeness, the position coordinate is - * usually handled differently during clipping. - */ - DEBUG_INSERT; - out[0] = (in[0] - vp[12]) / vp[0]; - out[1] = (in[1] - vp[13]) / vp[5]; - out[2] = (in[2] - vp[14]) / vp[10]; - out[3] = in[3]; -} - -static void extract_3f_viewport( const struct tnl_clipspace_attr *a, GLfloat *out, - const GLubyte *v ) -{ - const GLfloat *in = (const GLfloat *)v; - const GLfloat * const vp = a->vp; - DEBUG_INSERT; - out[0] = (in[0] - vp[12]) / vp[0]; - out[1] = (in[1] - vp[13]) / vp[5]; - out[2] = (in[2] - vp[14]) / vp[10]; - out[3] = 1; -} - - -static void extract_2f_viewport( const struct tnl_clipspace_attr *a, GLfloat *out, - const GLubyte *v ) -{ - const GLfloat *in = (const GLfloat *)v; - const GLfloat * const vp = a->vp; - DEBUG_INSERT; - out[0] = (in[0] - vp[12]) / vp[0]; - out[1] = (in[1] - vp[13]) / vp[5]; - out[2] = 0; - out[3] = 1; -} - - -static void extract_4f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v ) -{ - const GLfloat *in = (const GLfloat *)v; - (void) a; - - out[0] = in[0]; - out[1] = in[1]; - out[2] = in[2]; - out[3] = in[3]; -} - -static void extract_3f_xyw( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v ) -{ - const GLfloat *in = (const GLfloat *)v; - (void) a; - - out[0] = in[0]; - out[1] = in[1]; - out[2] = 0; - out[3] = in[2]; -} - - -static void extract_3f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v ) -{ - const GLfloat *in = (const GLfloat *)v; - (void) a; - - out[0] = in[0]; - out[1] = in[1]; - out[2] = in[2]; - out[3] = 1; -} - - -static void extract_2f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v ) -{ - const GLfloat *in = (const GLfloat *)v; - (void) a; - - out[0] = in[0]; - out[1] = in[1]; - out[2] = 0; - out[3] = 1; -} - -static void extract_1f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v ) -{ - const GLfloat *in = (const GLfloat *)v; - (void) a; - - out[0] = in[0]; - out[1] = 0; - out[2] = 0; - out[3] = 1; -} - -static void extract_4chan_4f_rgba( const struct tnl_clipspace_attr *a, GLfloat *out, - const GLubyte *v ) -{ - GLchan *c = (GLchan *)v; - (void) a; - - out[0] = CHAN_TO_FLOAT(c[0]); - out[1] = CHAN_TO_FLOAT(c[1]); - out[2] = CHAN_TO_FLOAT(c[2]); - out[3] = CHAN_TO_FLOAT(c[3]); -} - -static void extract_4ub_4f_rgba( const struct tnl_clipspace_attr *a, GLfloat *out, - const GLubyte *v ) -{ - (void) a; - out[0] = UBYTE_TO_FLOAT(v[0]); - out[1] = UBYTE_TO_FLOAT(v[1]); - out[2] = UBYTE_TO_FLOAT(v[2]); - out[3] = UBYTE_TO_FLOAT(v[3]); -} - -static void extract_4ub_4f_bgra( const struct tnl_clipspace_attr *a, GLfloat *out, - const GLubyte *v ) -{ - (void) a; - out[2] = UBYTE_TO_FLOAT(v[0]); - out[1] = UBYTE_TO_FLOAT(v[1]); - out[0] = UBYTE_TO_FLOAT(v[2]); - out[3] = UBYTE_TO_FLOAT(v[3]); -} - -static void extract_4ub_4f_argb( const struct tnl_clipspace_attr *a, GLfloat *out, - const GLubyte *v ) -{ - (void) a; - out[3] = UBYTE_TO_FLOAT(v[0]); - out[0] = UBYTE_TO_FLOAT(v[1]); - out[1] = UBYTE_TO_FLOAT(v[2]); - out[2] = UBYTE_TO_FLOAT(v[3]); -} - -static void extract_4ub_4f_abgr( const struct tnl_clipspace_attr *a, GLfloat *out, - const GLubyte *v ) -{ - (void) a; - out[3] = UBYTE_TO_FLOAT(v[0]); - out[2] = UBYTE_TO_FLOAT(v[1]); - out[1] = UBYTE_TO_FLOAT(v[2]); - out[0] = UBYTE_TO_FLOAT(v[3]); -} - -static void extract_3ub_3f_rgb( const struct tnl_clipspace_attr *a, GLfloat *out, - const GLubyte *v ) -{ - (void) a; - out[0] = UBYTE_TO_FLOAT(v[0]); - out[1] = UBYTE_TO_FLOAT(v[1]); - out[2] = UBYTE_TO_FLOAT(v[2]); - out[3] = 1; -} - -static void extract_3ub_3f_bgr( const struct tnl_clipspace_attr *a, GLfloat *out, - const GLubyte *v ) -{ - (void) a; - out[2] = UBYTE_TO_FLOAT(v[0]); - out[1] = UBYTE_TO_FLOAT(v[1]); - out[0] = UBYTE_TO_FLOAT(v[2]); - out[3] = 1; -} - -static void extract_1ub_1f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v ) -{ - (void) a; - out[0] = UBYTE_TO_FLOAT(v[0]); - out[1] = 0; - out[2] = 0; - out[3] = 1; -} - - -const struct tnl_format_info _tnl_format_info[EMIT_MAX] = -{ - { "1f", - extract_1f, - { insert_1f_1, insert_1f_1, insert_1f_1, insert_1f_1 }, - sizeof(GLfloat) }, - - { "2f", - extract_2f, - { insert_2f_1, insert_2f_2, insert_2f_2, insert_2f_2 }, - 2 * sizeof(GLfloat) }, - - { "3f", - extract_3f, - { insert_3f_1, insert_3f_2, insert_3f_3, insert_3f_3 }, - 3 * sizeof(GLfloat) }, - - { "4f", - extract_4f, - { insert_4f_1, insert_4f_2, insert_4f_3, insert_4f_4 }, - 4 * sizeof(GLfloat) }, - - { "2f_viewport", - extract_2f_viewport, - { insert_2f_viewport_1, insert_2f_viewport_2, insert_2f_viewport_2, - insert_2f_viewport_2 }, - 2 * sizeof(GLfloat) }, - - { "3f_viewport", - extract_3f_viewport, - { insert_3f_viewport_1, insert_3f_viewport_2, insert_3f_viewport_3, - insert_3f_viewport_3 }, - 3 * sizeof(GLfloat) }, - - { "4f_viewport", - extract_4f_viewport, - { insert_4f_viewport_1, insert_4f_viewport_2, insert_4f_viewport_3, - insert_4f_viewport_4 }, - 4 * sizeof(GLfloat) }, - - { "3f_xyw", - extract_3f_xyw, - { insert_3f_xyw_err, insert_3f_xyw_err, insert_3f_xyw_err, - insert_3f_xyw_4 }, - 3 * sizeof(GLfloat) }, - - { "1ub_1f", - extract_1ub_1f, - { insert_1ub_1f_1, insert_1ub_1f_1, insert_1ub_1f_1, insert_1ub_1f_1 }, - sizeof(GLubyte) }, - - { "3ub_3f_rgb", - extract_3ub_3f_rgb, - { insert_3ub_3f_rgb_1, insert_3ub_3f_rgb_2, insert_3ub_3f_rgb_3, - insert_3ub_3f_rgb_3 }, - 3 * sizeof(GLubyte) }, - - { "3ub_3f_bgr", - extract_3ub_3f_bgr, - { insert_3ub_3f_bgr_1, insert_3ub_3f_bgr_2, insert_3ub_3f_bgr_3, - insert_3ub_3f_bgr_3 }, - 3 * sizeof(GLubyte) }, - - { "4ub_4f_rgba", - extract_4ub_4f_rgba, - { insert_4ub_4f_rgba_1, insert_4ub_4f_rgba_2, insert_4ub_4f_rgba_3, - insert_4ub_4f_rgba_4 }, - 4 * sizeof(GLubyte) }, - - { "4ub_4f_bgra", - extract_4ub_4f_bgra, - { insert_4ub_4f_bgra_1, insert_4ub_4f_bgra_2, insert_4ub_4f_bgra_3, - insert_4ub_4f_bgra_4 }, - 4 * sizeof(GLubyte) }, - - { "4ub_4f_argb", - extract_4ub_4f_argb, - { insert_4ub_4f_argb_1, insert_4ub_4f_argb_2, insert_4ub_4f_argb_3, - insert_4ub_4f_argb_4 }, - 4 * sizeof(GLubyte) }, - - { "4ub_4f_abgr", - extract_4ub_4f_abgr, - { insert_4ub_4f_abgr_1, insert_4ub_4f_abgr_2, insert_4ub_4f_abgr_3, - insert_4ub_4f_abgr_4 }, - 4 * sizeof(GLubyte) }, - - { "4chan_4f_rgba", - extract_4chan_4f_rgba, - { insert_4chan_4f_rgba_1, insert_4chan_4f_rgba_2, insert_4chan_4f_rgba_3, - insert_4chan_4f_rgba_4 }, - 4 * sizeof(GLchan) }, - - { "pad", - NULL, - { NULL, NULL, NULL, NULL }, - 0 } - -}; - - - - -/*********************************************************************** - * Hardwired fastpaths for emitting whole vertices or groups of - * vertices - */ -#define EMIT5(NR, F0, F1, F2, F3, F4, NAME) \ -static void NAME( struct gl_context *ctx, \ - GLuint count, \ - GLubyte *v ) \ -{ \ - struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); \ - struct tnl_clipspace_attr *a = vtx->attr; \ - GLuint i; \ - \ - for (i = 0 ; i < count ; i++, v += vtx->vertex_size) { \ - if (NR > 0) { \ - F0( &a[0], v + a[0].vertoffset, (GLfloat *)a[0].inputptr ); \ - a[0].inputptr += a[0].inputstride; \ - } \ - \ - if (NR > 1) { \ - F1( &a[1], v + a[1].vertoffset, (GLfloat *)a[1].inputptr ); \ - a[1].inputptr += a[1].inputstride; \ - } \ - \ - if (NR > 2) { \ - F2( &a[2], v + a[2].vertoffset, (GLfloat *)a[2].inputptr ); \ - a[2].inputptr += a[2].inputstride; \ - } \ - \ - if (NR > 3) { \ - F3( &a[3], v + a[3].vertoffset, (GLfloat *)a[3].inputptr ); \ - a[3].inputptr += a[3].inputstride; \ - } \ - \ - if (NR > 4) { \ - F4( &a[4], v + a[4].vertoffset, (GLfloat *)a[4].inputptr ); \ - a[4].inputptr += a[4].inputstride; \ - } \ - } \ -} - - -#define EMIT2(F0, F1, NAME) EMIT5(2, F0, F1, insert_null, \ - insert_null, insert_null, NAME) - -#define EMIT3(F0, F1, F2, NAME) EMIT5(3, F0, F1, F2, insert_null, \ - insert_null, NAME) - -#define EMIT4(F0, F1, F2, F3, NAME) EMIT5(4, F0, F1, F2, F3, \ - insert_null, NAME) - - -EMIT2(insert_3f_viewport_3, insert_4ub_4f_rgba_4, emit_viewport3_rgba4) -EMIT2(insert_3f_viewport_3, insert_4ub_4f_bgra_4, emit_viewport3_bgra4) -EMIT2(insert_3f_3, insert_4ub_4f_rgba_4, emit_xyz3_rgba4) - -EMIT3(insert_4f_viewport_4, insert_4ub_4f_rgba_4, insert_2f_2, emit_viewport4_rgba4_st2) -EMIT3(insert_4f_viewport_4, insert_4ub_4f_bgra_4, insert_2f_2, emit_viewport4_bgra4_st2) -EMIT3(insert_4f_4, insert_4ub_4f_rgba_4, insert_2f_2, emit_xyzw4_rgba4_st2) - -EMIT4(insert_4f_viewport_4, insert_4ub_4f_rgba_4, insert_2f_2, insert_2f_2, emit_viewport4_rgba4_st2_st2) -EMIT4(insert_4f_viewport_4, insert_4ub_4f_bgra_4, insert_2f_2, insert_2f_2, emit_viewport4_bgra4_st2_st2) -EMIT4(insert_4f_4, insert_4ub_4f_rgba_4, insert_2f_2, insert_2f_2, emit_xyzw4_rgba4_st2_st2) - - -/* Use the codegen paths to select one of a number of hardwired - * fastpaths. - */ -void _tnl_generate_hardwired_emit( struct gl_context *ctx ) -{ - struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); - tnl_emit_func func = NULL; - - /* Does it fit a hardwired fastpath? Help! this is growing out of - * control! - */ - switch (vtx->attr_count) { - case 2: - if (vtx->attr[0].emit == insert_3f_viewport_3) { - if (vtx->attr[1].emit == insert_4ub_4f_bgra_4) - func = emit_viewport3_bgra4; - else if (vtx->attr[1].emit == insert_4ub_4f_rgba_4) - func = emit_viewport3_rgba4; - } - else if (vtx->attr[0].emit == insert_3f_3 && - vtx->attr[1].emit == insert_4ub_4f_rgba_4) { - func = emit_xyz3_rgba4; - } - break; - case 3: - if (vtx->attr[2].emit == insert_2f_2) { - if (vtx->attr[1].emit == insert_4ub_4f_rgba_4) { - if (vtx->attr[0].emit == insert_4f_viewport_4) - func = emit_viewport4_rgba4_st2; - else if (vtx->attr[0].emit == insert_4f_4) - func = emit_xyzw4_rgba4_st2; - } - else if (vtx->attr[1].emit == insert_4ub_4f_bgra_4 && - vtx->attr[0].emit == insert_4f_viewport_4) - func = emit_viewport4_bgra4_st2; - } - break; - case 4: - if (vtx->attr[2].emit == insert_2f_2 && - vtx->attr[3].emit == insert_2f_2) { - if (vtx->attr[1].emit == insert_4ub_4f_rgba_4) { - if (vtx->attr[0].emit == insert_4f_viewport_4) - func = emit_viewport4_rgba4_st2_st2; - else if (vtx->attr[0].emit == insert_4f_4) - func = emit_xyzw4_rgba4_st2_st2; - } - else if (vtx->attr[1].emit == insert_4ub_4f_bgra_4 && - vtx->attr[0].emit == insert_4f_viewport_4) - func = emit_viewport4_bgra4_st2_st2; - } - break; - } - - vtx->emit = func; -} - -/*********************************************************************** - * Generic (non-codegen) functions for whole vertices or groups of - * vertices - */ - -void _tnl_generic_emit( struct gl_context *ctx, - GLuint count, - GLubyte *v ) -{ - struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); - struct tnl_clipspace_attr *a = vtx->attr; - const GLuint attr_count = vtx->attr_count; - const GLuint stride = vtx->vertex_size; - GLuint i, j; - - for (i = 0 ; i < count ; i++, v += stride) { - for (j = 0; j < attr_count; j++) { - GLfloat *in = (GLfloat *)a[j].inputptr; - a[j].inputptr += a[j].inputstride; - a[j].emit( &a[j], v + a[j].vertoffset, in ); - } - } -} - - -void _tnl_generic_interp( struct gl_context *ctx, - GLfloat t, - GLuint edst, GLuint eout, GLuint ein, - GLboolean force_boundary ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &tnl->vb; - struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); - const GLubyte *vin = vtx->vertex_buf + ein * vtx->vertex_size; - const GLubyte *vout = vtx->vertex_buf + eout * vtx->vertex_size; - GLubyte *vdst = vtx->vertex_buf + edst * vtx->vertex_size; - const struct tnl_clipspace_attr *a = vtx->attr; - const GLuint attr_count = vtx->attr_count; - GLuint j; - (void) force_boundary; - - if (tnl->NeedNdcCoords) { - const GLfloat *dstclip = VB->ClipPtr->data[edst]; - if (dstclip[3] != 0.0f) { - const GLfloat w = 1.0f / dstclip[3]; - GLfloat pos[4]; - - pos[0] = dstclip[0] * w; - pos[1] = dstclip[1] * w; - pos[2] = dstclip[2] * w; - pos[3] = w; - - a[0].insert[4-1]( &a[0], vdst, pos ); - } - } - else { - a[0].insert[4-1]( &a[0], vdst, VB->ClipPtr->data[edst] ); - } - - - for (j = 1; j < attr_count; j++) { - GLfloat fin[4], fout[4], fdst[4]; - - a[j].extract( &a[j], fin, vin + a[j].vertoffset ); - a[j].extract( &a[j], fout, vout + a[j].vertoffset ); - - INTERP_4F(t, fdst, fout, fin); - - a[j].insert[4-1]( &a[j], vdst + a[j].vertoffset, fdst ); - } -} - - -/* Extract color attributes from one vertex and insert them into - * another. (Shortcircuit extract/insert with memcpy). - */ -void _tnl_generic_copy_pv( struct gl_context *ctx, GLuint edst, GLuint esrc ) -{ - struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); - GLubyte *vsrc = vtx->vertex_buf + esrc * vtx->vertex_size; - GLubyte *vdst = vtx->vertex_buf + edst * vtx->vertex_size; - const struct tnl_clipspace_attr *a = vtx->attr; - const GLuint attr_count = vtx->attr_count; - GLuint j; - - for (j = 0; j < attr_count; j++) { - if (a[j].attrib == VERT_ATTRIB_COLOR0 || - a[j].attrib == VERT_ATTRIB_COLOR1) { - - memcpy( vdst + a[j].vertoffset, - vsrc + a[j].vertoffset, - a[j].vertattrsize ); - } - } -} - - -/* Helper functions for hardware which doesn't put back colors and/or - * edgeflags into vertices. - */ -void _tnl_generic_interp_extras( struct gl_context *ctx, - GLfloat t, - GLuint dst, GLuint out, GLuint in, - GLboolean force_boundary ) -{ - struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - - /* If stride is zero, BackfaceColorPtr is constant across the VB, so - * there is no point interpolating between two values as they will - * be identical. In all other cases, this value is generated by - * t_vb_lighttmp.h and has a stride of 4 dwords. - */ - if (VB->BackfaceColorPtr && VB->BackfaceColorPtr->stride) { - assert(VB->BackfaceColorPtr->stride == 4 * sizeof(GLfloat)); - - INTERP_4F( t, - VB->BackfaceColorPtr->data[dst], - VB->BackfaceColorPtr->data[out], - VB->BackfaceColorPtr->data[in] ); - } - - if (VB->BackfaceSecondaryColorPtr) { - assert(VB->BackfaceSecondaryColorPtr->stride == 4 * sizeof(GLfloat)); - - INTERP_3F( t, - VB->BackfaceSecondaryColorPtr->data[dst], - VB->BackfaceSecondaryColorPtr->data[out], - VB->BackfaceSecondaryColorPtr->data[in] ); - } - - if (VB->BackfaceIndexPtr) { - VB->BackfaceIndexPtr->data[dst][0] = LINTERP( t, - VB->BackfaceIndexPtr->data[out][0], - VB->BackfaceIndexPtr->data[in][0] ); - } - - if (VB->EdgeFlag) { - VB->EdgeFlag[dst] = VB->EdgeFlag[out] || force_boundary; - } - - _tnl_generic_interp(ctx, t, dst, out, in, force_boundary); -} - -void _tnl_generic_copy_pv_extras( struct gl_context *ctx, - GLuint dst, GLuint src ) -{ - struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - - /* See above comment: - */ - if (VB->BackfaceColorPtr && VB->BackfaceColorPtr->stride) { - COPY_4FV( VB->BackfaceColorPtr->data[dst], - VB->BackfaceColorPtr->data[src] ); - } - - if (VB->BackfaceSecondaryColorPtr) { - COPY_4FV( VB->BackfaceSecondaryColorPtr->data[dst], - VB->BackfaceSecondaryColorPtr->data[src] ); - } - - if (VB->BackfaceIndexPtr) { - VB->BackfaceIndexPtr->data[dst][0] = VB->BackfaceIndexPtr->data[src][0]; - } - - _tnl_generic_copy_pv(ctx, dst, src); -} - - diff --git a/src/mesa/tnl/t_vertex_sse.c b/src/mesa/tnl/t_vertex_sse.c deleted file mode 100644 index 191a68d..0000000 --- a/src/mesa/tnl/t_vertex_sse.c +++ /dev/null @@ -1,685 +0,0 @@ -/* - * Copyright 2003 VMware, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * 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 NON-INFRINGEMENT. IN NO EVENT SHALL - * VMWARE AND/OR THEIR SUPPLIERS 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. - * - * Authors: - * Keith Whitwell - */ - -#include - -#include "main/glheader.h" -#include "main/context.h" -#include "main/enums.h" -#include "swrast/s_chan.h" -#include "t_context.h" -#include "t_vertex.h" - -#if defined(USE_SSE_ASM) - -#include "x86/rtasm/x86sse.h" -#include "x86/common_x86_asm.h" - - -/** - * Number of bytes to allocate for generated SSE functions - */ -#define MAX_SSE_CODE_SIZE 1024 - - -#define X 0 -#define Y 1 -#define Z 2 -#define W 3 - - -struct x86_program { - struct x86_function func; - - struct gl_context *ctx; - GLboolean inputs_safe; - GLboolean outputs_safe; - GLboolean have_sse2; - - struct x86_reg identity; - struct x86_reg chan0; -}; - - -static struct x86_reg get_identity( struct x86_program *p ) -{ - return p->identity; -} - -static void emit_load4f_4( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - sse_movups(&p->func, dest, arg0); -} - -static void emit_load4f_3( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - /* Have to jump through some hoops: - * - * c 0 0 0 - * c 0 0 1 - * 0 0 c 1 - * a b c 1 - */ - sse_movss(&p->func, dest, x86_make_disp(arg0, 8)); - sse_shufps(&p->func, dest, get_identity(p), SHUF(X,Y,Z,W) ); - sse_shufps(&p->func, dest, dest, SHUF(Y,Z,X,W) ); - sse_movlps(&p->func, dest, arg0); -} - -static void emit_load4f_2( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - /* Initialize from identity, then pull in low two words: - */ - sse_movups(&p->func, dest, get_identity(p)); - sse_movlps(&p->func, dest, arg0); -} - -static void emit_load4f_1( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - /* Pull in low word, then swizzle in identity */ - sse_movss(&p->func, dest, arg0); - sse_shufps(&p->func, dest, get_identity(p), SHUF(X,Y,Z,W) ); -} - - - -static void emit_load3f_3( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - /* Over-reads by 1 dword - potential SEGV if input is a vertex - * array. - */ - if (p->inputs_safe) { - sse_movups(&p->func, dest, arg0); - } - else { - /* c 0 0 0 - * c c c c - * a b c c - */ - sse_movss(&p->func, dest, x86_make_disp(arg0, 8)); - sse_shufps(&p->func, dest, dest, SHUF(X,X,X,X)); - sse_movlps(&p->func, dest, arg0); - } -} - -static void emit_load3f_2( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - emit_load4f_2(p, dest, arg0); -} - -static void emit_load3f_1( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - /* Loading from memory erases the upper bits. */ - sse_movss(&p->func, dest, arg0); -} - -static void emit_load2f_2( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - sse_movlps(&p->func, dest, arg0); -} - -static void emit_load2f_1( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - /* Loading from memory erases the upper bits. */ - sse_movss(&p->func, dest, arg0); -} - -static void emit_load1f_1( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - sse_movss(&p->func, dest, arg0); -} - -static void (*load[4][4])( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) = { - { emit_load1f_1, - emit_load1f_1, - emit_load1f_1, - emit_load1f_1 }, - - { emit_load2f_1, - emit_load2f_2, - emit_load2f_2, - emit_load2f_2 }, - - { emit_load3f_1, - emit_load3f_2, - emit_load3f_3, - emit_load3f_3 }, - - { emit_load4f_1, - emit_load4f_2, - emit_load4f_3, - emit_load4f_4 } -}; - -static void emit_load( struct x86_program *p, - struct x86_reg dest, - GLuint sz, - struct x86_reg src, - GLuint src_sz) -{ - load[sz-1][src_sz-1](p, dest, src); -} - -static void emit_store4f( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - sse_movups(&p->func, dest, arg0); -} - -static void emit_store3f( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - if (p->outputs_safe) { - /* Emit the extra dword anyway. This may hurt writecombining, - * may cause other problems. - */ - sse_movups(&p->func, dest, arg0); - } - else { - /* Alternate strategy - emit two, shuffle, emit one. - */ - sse_movlps(&p->func, dest, arg0); - sse_shufps(&p->func, arg0, arg0, SHUF(Z,Z,Z,Z) ); /* NOTE! destructive */ - sse_movss(&p->func, x86_make_disp(dest,8), arg0); - } -} - -static void emit_store2f( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - sse_movlps(&p->func, dest, arg0); -} - -static void emit_store1f( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - sse_movss(&p->func, dest, arg0); -} - - -static void (*store[4])( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) = -{ - emit_store1f, - emit_store2f, - emit_store3f, - emit_store4f -}; - -static void emit_store( struct x86_program *p, - struct x86_reg dest, - GLuint sz, - struct x86_reg temp ) - -{ - store[sz-1](p, dest, temp); -} - -static void emit_pack_store_4ub( struct x86_program *p, - struct x86_reg dest, - struct x86_reg temp ) -{ - /* Scale by 255.0 - */ - sse_mulps(&p->func, temp, p->chan0); - - if (p->have_sse2) { - sse2_cvtps2dq(&p->func, temp, temp); - sse2_packssdw(&p->func, temp, temp); - sse2_packuswb(&p->func, temp, temp); - sse_movss(&p->func, dest, temp); - } - else { - struct x86_reg mmx0 = x86_make_reg(file_MMX, 0); - struct x86_reg mmx1 = x86_make_reg(file_MMX, 1); - sse_cvtps2pi(&p->func, mmx0, temp); - sse_movhlps(&p->func, temp, temp); - sse_cvtps2pi(&p->func, mmx1, temp); - mmx_packssdw(&p->func, mmx0, mmx1); - mmx_packuswb(&p->func, mmx0, mmx0); - mmx_movd(&p->func, dest, mmx0); - } -} - -static GLint get_offset( const void *a, const void *b ) -{ - return (const char *)b - (const char *)a; -} - -/* Not much happens here. Eventually use this function to try and - * avoid saving/reloading the source pointers each vertex (if some of - * them can fit in registers). - */ -static void get_src_ptr( struct x86_program *p, - struct x86_reg srcREG, - struct x86_reg vtxREG, - struct tnl_clipspace_attr *a ) -{ - struct tnl_clipspace *vtx = GET_VERTEX_STATE(p->ctx); - struct x86_reg ptr_to_src = x86_make_disp(vtxREG, get_offset(vtx, &a->inputptr)); - - /* Load current a[j].inputptr - */ - x86_mov(&p->func, srcREG, ptr_to_src); -} - -static void update_src_ptr( struct x86_program *p, - struct x86_reg srcREG, - struct x86_reg vtxREG, - struct tnl_clipspace_attr *a ) -{ - if (a->inputstride) { - struct tnl_clipspace *vtx = GET_VERTEX_STATE(p->ctx); - struct x86_reg ptr_to_src = x86_make_disp(vtxREG, get_offset(vtx, &a->inputptr)); - - /* add a[j].inputstride (hardcoded value - could just as easily - * pull the stride value from memory each time). - */ - x86_lea(&p->func, srcREG, x86_make_disp(srcREG, a->inputstride)); - - /* save new value of a[j].inputptr - */ - x86_mov(&p->func, ptr_to_src, srcREG); - } -} - - -/* Lots of hardcoding - * - * EAX -- pointer to current output vertex - * ECX -- pointer to current attribute - * - */ -static GLboolean build_vertex_emit( struct x86_program *p ) -{ - struct gl_context *ctx = p->ctx; - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); - GLuint j = 0; - - struct x86_reg vertexEAX = x86_make_reg(file_REG32, reg_AX); - struct x86_reg srcECX = x86_make_reg(file_REG32, reg_CX); - struct x86_reg countEBP = x86_make_reg(file_REG32, reg_BP); - struct x86_reg vtxESI = x86_make_reg(file_REG32, reg_SI); - struct x86_reg temp = x86_make_reg(file_XMM, 0); - struct x86_reg vp0 = x86_make_reg(file_XMM, 1); - struct x86_reg vp1 = x86_make_reg(file_XMM, 2); - struct x86_reg temp2 = x86_make_reg(file_XMM, 3); - GLubyte *fixup, *label; - - /* Push a few regs? - */ - x86_push(&p->func, countEBP); - x86_push(&p->func, vtxESI); - - - /* Get vertex count, compare to zero - */ - x86_xor(&p->func, srcECX, srcECX); - x86_mov(&p->func, countEBP, x86_fn_arg(&p->func, 2)); - x86_cmp(&p->func, countEBP, srcECX); - fixup = x86_jcc_forward(&p->func, cc_E); - - /* Initialize destination register. - */ - x86_mov(&p->func, vertexEAX, x86_fn_arg(&p->func, 3)); - - /* Dereference ctx to get tnl, then vtx: - */ - x86_mov(&p->func, vtxESI, x86_fn_arg(&p->func, 1)); - x86_mov(&p->func, vtxESI, x86_make_disp(vtxESI, get_offset(ctx, &ctx->swtnl_context))); - vtxESI = x86_make_disp(vtxESI, get_offset(tnl, &tnl->clipspace)); - - - /* Possibly load vp0, vp1 for viewport calcs: - */ - if (vtx->need_viewport) { - sse_movups(&p->func, vp0, x86_make_disp(vtxESI, get_offset(vtx, &vtx->vp_scale[0]))); - sse_movups(&p->func, vp1, x86_make_disp(vtxESI, get_offset(vtx, &vtx->vp_xlate[0]))); - } - - /* always load, needed or not: - */ - sse_movups(&p->func, p->chan0, x86_make_disp(vtxESI, get_offset(vtx, &vtx->chan_scale[0]))); - sse_movups(&p->func, p->identity, x86_make_disp(vtxESI, get_offset(vtx, &vtx->identity[0]))); - - /* Note address for loop jump */ - label = x86_get_label(&p->func); - - /* Emit code for each of the attributes. Currently routes - * everything through SSE registers, even when it might be more - * efficient to stick with regular old x86. No optimization or - * other tricks - enough new ground to cover here just getting - * things working. - */ - while (j < vtx->attr_count) { - struct tnl_clipspace_attr *a = &vtx->attr[j]; - struct x86_reg dest = x86_make_disp(vertexEAX, a->vertoffset); - - /* Now, load an XMM reg from src, perhaps transform, then save. - * Could be shortcircuited in specific cases: - */ - switch (a->format) { - case EMIT_1F: - get_src_ptr(p, srcECX, vtxESI, a); - emit_load(p, temp, 1, x86_deref(srcECX), a->inputsize); - emit_store(p, dest, 1, temp); - update_src_ptr(p, srcECX, vtxESI, a); - break; - case EMIT_2F: - get_src_ptr(p, srcECX, vtxESI, a); - emit_load(p, temp, 2, x86_deref(srcECX), a->inputsize); - emit_store(p, dest, 2, temp); - update_src_ptr(p, srcECX, vtxESI, a); - break; - case EMIT_3F: - /* Potentially the worst case - hardcode 2+1 copying: - */ - if (0) { - get_src_ptr(p, srcECX, vtxESI, a); - emit_load(p, temp, 3, x86_deref(srcECX), a->inputsize); - emit_store(p, dest, 3, temp); - update_src_ptr(p, srcECX, vtxESI, a); - } - else { - get_src_ptr(p, srcECX, vtxESI, a); - emit_load(p, temp, 2, x86_deref(srcECX), a->inputsize); - emit_store(p, dest, 2, temp); - if (a->inputsize > 2) { - emit_load(p, temp, 1, x86_make_disp(srcECX, 8), 1); - emit_store(p, x86_make_disp(dest,8), 1, temp); - } - else { - sse_movss(&p->func, x86_make_disp(dest,8), get_identity(p)); - } - update_src_ptr(p, srcECX, vtxESI, a); - } - break; - case EMIT_4F: - get_src_ptr(p, srcECX, vtxESI, a); - emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); - emit_store(p, dest, 4, temp); - update_src_ptr(p, srcECX, vtxESI, a); - break; - case EMIT_2F_VIEWPORT: - get_src_ptr(p, srcECX, vtxESI, a); - emit_load(p, temp, 2, x86_deref(srcECX), a->inputsize); - sse_mulps(&p->func, temp, vp0); - sse_addps(&p->func, temp, vp1); - emit_store(p, dest, 2, temp); - update_src_ptr(p, srcECX, vtxESI, a); - break; - case EMIT_3F_VIEWPORT: - get_src_ptr(p, srcECX, vtxESI, a); - emit_load(p, temp, 3, x86_deref(srcECX), a->inputsize); - sse_mulps(&p->func, temp, vp0); - sse_addps(&p->func, temp, vp1); - emit_store(p, dest, 3, temp); - update_src_ptr(p, srcECX, vtxESI, a); - break; - case EMIT_4F_VIEWPORT: - get_src_ptr(p, srcECX, vtxESI, a); - emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); - sse_mulps(&p->func, temp, vp0); - sse_addps(&p->func, temp, vp1); - emit_store(p, dest, 4, temp); - update_src_ptr(p, srcECX, vtxESI, a); - break; - case EMIT_3F_XYW: - get_src_ptr(p, srcECX, vtxESI, a); - emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); - sse_shufps(&p->func, temp, temp, SHUF(X,Y,W,Z)); - emit_store(p, dest, 3, temp); - update_src_ptr(p, srcECX, vtxESI, a); - break; - - case EMIT_1UB_1F: - /* Test for PAD3 + 1UB: - */ - if (j > 0 && - a[-1].vertoffset + a[-1].vertattrsize <= a->vertoffset - 3) - { - get_src_ptr(p, srcECX, vtxESI, a); - emit_load(p, temp, 1, x86_deref(srcECX), a->inputsize); - sse_shufps(&p->func, temp, temp, SHUF(X,X,X,X)); - emit_pack_store_4ub(p, x86_make_disp(dest, -3), temp); /* overkill! */ - update_src_ptr(p, srcECX, vtxESI, a); - } - else { - printf("Can't emit 1ub %x %x %d\n", a->vertoffset, a[-1].vertoffset, a[-1].vertattrsize ); - return GL_FALSE; - } - break; - case EMIT_3UB_3F_RGB: - case EMIT_3UB_3F_BGR: - /* Test for 3UB + PAD1: - */ - if (j == vtx->attr_count - 1 || - a[1].vertoffset >= a->vertoffset + 4) { - get_src_ptr(p, srcECX, vtxESI, a); - emit_load(p, temp, 3, x86_deref(srcECX), a->inputsize); - if (a->format == EMIT_3UB_3F_BGR) - sse_shufps(&p->func, temp, temp, SHUF(Z,Y,X,W)); - emit_pack_store_4ub(p, dest, temp); - update_src_ptr(p, srcECX, vtxESI, a); - } - /* Test for 3UB + 1UB: - */ - else if (j < vtx->attr_count - 1 && - a[1].format == EMIT_1UB_1F && - a[1].vertoffset == a->vertoffset + 3) { - get_src_ptr(p, srcECX, vtxESI, a); - emit_load(p, temp, 3, x86_deref(srcECX), a->inputsize); - update_src_ptr(p, srcECX, vtxESI, a); - - /* Make room for incoming value: - */ - sse_shufps(&p->func, temp, temp, SHUF(W,X,Y,Z)); - - get_src_ptr(p, srcECX, vtxESI, &a[1]); - emit_load(p, temp2, 1, x86_deref(srcECX), a[1].inputsize); - sse_movss(&p->func, temp, temp2); - update_src_ptr(p, srcECX, vtxESI, &a[1]); - - /* Rearrange and possibly do BGR conversion: - */ - if (a->format == EMIT_3UB_3F_BGR) - sse_shufps(&p->func, temp, temp, SHUF(W,Z,Y,X)); - else - sse_shufps(&p->func, temp, temp, SHUF(Y,Z,W,X)); - - emit_pack_store_4ub(p, dest, temp); - j++; /* NOTE: two attrs consumed */ - } - else { - printf("Can't emit 3ub\n"); - return GL_FALSE; /* add this later */ - } - break; - - case EMIT_4UB_4F_RGBA: - get_src_ptr(p, srcECX, vtxESI, a); - emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); - emit_pack_store_4ub(p, dest, temp); - update_src_ptr(p, srcECX, vtxESI, a); - break; - case EMIT_4UB_4F_BGRA: - get_src_ptr(p, srcECX, vtxESI, a); - emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); - sse_shufps(&p->func, temp, temp, SHUF(Z,Y,X,W)); - emit_pack_store_4ub(p, dest, temp); - update_src_ptr(p, srcECX, vtxESI, a); - break; - case EMIT_4UB_4F_ARGB: - get_src_ptr(p, srcECX, vtxESI, a); - emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); - sse_shufps(&p->func, temp, temp, SHUF(W,X,Y,Z)); - emit_pack_store_4ub(p, dest, temp); - update_src_ptr(p, srcECX, vtxESI, a); - break; - case EMIT_4UB_4F_ABGR: - get_src_ptr(p, srcECX, vtxESI, a); - emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); - sse_shufps(&p->func, temp, temp, SHUF(W,Z,Y,X)); - emit_pack_store_4ub(p, dest, temp); - update_src_ptr(p, srcECX, vtxESI, a); - break; - case EMIT_4CHAN_4F_RGBA: - switch (CHAN_TYPE) { - case GL_UNSIGNED_BYTE: - get_src_ptr(p, srcECX, vtxESI, a); - emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); - emit_pack_store_4ub(p, dest, temp); - update_src_ptr(p, srcECX, vtxESI, a); - break; - case GL_FLOAT: - get_src_ptr(p, srcECX, vtxESI, a); - emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); - emit_store(p, dest, 4, temp); - update_src_ptr(p, srcECX, vtxESI, a); - break; - case GL_UNSIGNED_SHORT: - default: - printf("unknown CHAN_TYPE %s\n", _mesa_enum_to_string(CHAN_TYPE)); - return GL_FALSE; - } - break; - default: - printf("unknown a[%d].format %d\n", j, a->format); - return GL_FALSE; /* catch any new opcodes */ - } - - /* Increment j by at least 1 - may have been incremented above also: - */ - j++; - } - - /* Next vertex: - */ - x86_lea(&p->func, vertexEAX, x86_make_disp(vertexEAX, vtx->vertex_size)); - - /* decr count, loop if not zero - */ - x86_dec(&p->func, countEBP); - x86_test(&p->func, countEBP, countEBP); - x86_jcc(&p->func, cc_NZ, label); - - /* Exit mmx state? - */ - if (p->func.need_emms) - mmx_emms(&p->func); - - /* Land forward jump here: - */ - x86_fixup_fwd_jump(&p->func, fixup); - - /* Pop regs and return - */ - x86_pop(&p->func, x86_get_base_reg(vtxESI)); - x86_pop(&p->func, countEBP); - x86_ret(&p->func); - - assert(!vtx->emit); - vtx->emit = (tnl_emit_func)x86_get_func(&p->func); - - assert( (char *) p->func.csr - (char *) p->func.store <= MAX_SSE_CODE_SIZE ); - return GL_TRUE; -} - - - -void _tnl_generate_sse_emit( struct gl_context *ctx ) -{ - struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); - struct x86_program p; - - if (!cpu_has_xmm) { - vtx->codegen_emit = NULL; - return; - } - - memset(&p, 0, sizeof(p)); - - p.ctx = ctx; - p.inputs_safe = 0; /* for now */ - p.outputs_safe = 0; /* for now */ - p.have_sse2 = cpu_has_xmm2; - p.identity = x86_make_reg(file_XMM, 6); - p.chan0 = x86_make_reg(file_XMM, 7); - - if (!x86_init_func_size(&p.func, MAX_SSE_CODE_SIZE)) { - vtx->emit = NULL; - return; - } - - if (build_vertex_emit(&p)) { - _tnl_register_fastpath( vtx, GL_TRUE ); - } - else { - /* Note the failure so that we don't keep trying to codegen an - * impossible state: - */ - _tnl_register_fastpath( vtx, GL_FALSE ); - x86_release_func(&p.func); - } -} - -#else - -void _tnl_generate_sse_emit( struct gl_context *ctx ) -{ - /* Dummy version for when USE_SSE_ASM not defined */ -} - -#endif diff --git a/src/mesa/tnl/t_vp_build.c b/src/mesa/tnl/t_vp_build.c deleted file mode 100644 index 7de2105..0000000 --- a/src/mesa/tnl/t_vp_build.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 2007 VMware, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * VMWARE 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. - */ - -/** - * \file t_vp_build.c - * Create a vertex program to execute the current fixed function T&L pipeline. - * \author Keith Whitwell - */ - - -#include "main/glheader.h" -#include "main/ffvertex_prog.h" -#include "main/mtypes.h" -#include "t_vp_build.h" - - -/** - * XXX This should go away someday, but still referenced by some drivers... - */ -void _tnl_UpdateFixedFunctionProgram( struct gl_context *ctx ) -{ - if (!ctx->VertexProgram._Current || - ctx->VertexProgram._Current == ctx->VertexProgram._TnlProgram) { - ctx->VertexProgram._Current - = ctx->VertexProgram._TnlProgram - = _mesa_get_fixed_func_vertex_program(ctx); - } -} diff --git a/src/mesa/tnl/t_vp_build.h b/src/mesa/tnl/t_vp_build.h deleted file mode 100644 index 5bc7b33..0000000 --- a/src/mesa/tnl/t_vp_build.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 2005 VMware, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * VMWARE 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. - */ - - -#ifndef T_VP_BUILD_H -#define T_VP_BUILD_H - -struct gl_context; - -#define TNL_FIXED_FUNCTION_STATE_FLAGS (_NEW_PROGRAM | \ - _NEW_LIGHT | \ - _NEW_TEXTURE | \ - _NEW_TEXTURE_MATRIX | \ - _NEW_TRANSFORM | \ - _NEW_FOG | \ - _NEW_POINT) - -extern void _tnl_UpdateFixedFunctionProgram( struct gl_context *ctx ); - -#endif diff --git a/src/mesa/tnl/tnl.h b/src/mesa/tnl/tnl.h deleted file mode 100644 index 7f47dd3..0000000 --- a/src/mesa/tnl/tnl.h +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - * - * Authors: - * Keith Whitwell - */ - -#ifndef _TNL_H -#define _TNL_H - -#include "main/glheader.h" - -struct gl_context; -struct gl_program; -struct gl_buffer_object; -struct gl_transform_feedback_object; -struct dd_function_table; - - -/* These are the public-access functions exported from tnl. (A few - * more are currently hooked into dispatch directly by the module - * itself.) - */ -extern GLboolean -_tnl_CreateContext( struct gl_context *ctx ); - -extern void -_tnl_DestroyContext( struct gl_context *ctx ); - -extern void -_tnl_InvalidateState( struct gl_context *ctx, GLuint new_state ); - -extern void -_tnl_init_driver_draw_function(struct dd_function_table *functions); - -/* Functions to revive the tnl module after being unhooked from - * dispatch and/or driver callbacks. - */ - -extern void -_tnl_wakeup( struct gl_context *ctx ); - -/* Driver configuration options: - */ -extern void -_tnl_need_projected_coords( struct gl_context *ctx, GLboolean flag ); - - -/** - * Vertex array information which is derived from gl_array_attributes - * and gl_vertex_buffer_binding information. Used by the TNL module and - * device drivers. - */ -struct tnl_vertex_array -{ - /** Vertex attribute array */ - const struct gl_array_attributes *VertexAttrib; - /** Vertex buffer binding */ - const struct gl_vertex_buffer_binding *BufferBinding; -}; - - -extern const struct tnl_vertex_array* -_tnl_bind_inputs( struct gl_context *ctx ); - - -/* Control whether T&L does per-vertex fog - */ -extern void -_tnl_allow_vertex_fog( struct gl_context *ctx, GLboolean value ); - -extern void -_tnl_allow_pixel_fog( struct gl_context *ctx, GLboolean value ); - -extern GLboolean -_tnl_program_string(struct gl_context *ctx, GLenum target, struct gl_program *program); - -struct _mesa_prim; -struct _mesa_index_buffer; - -void -_tnl_draw_prims(struct gl_context *ctx, - const struct tnl_vertex_array *arrays, - const struct _mesa_prim *prim, - GLuint nr_prims, - const struct _mesa_index_buffer *ib, - GLboolean index_bounds_valid, - GLuint min_index, - GLuint max_index, - GLuint num_instances, - GLuint base_instance); - -void -_tnl_draw(struct gl_context *ctx, - const struct _mesa_prim *prim, unsigned nr_prims, - const struct _mesa_index_buffer *ib, - bool index_bounds_valid, bool primitive_restart, - unsigned restart_index, unsigned min_index, unsigned max_index, - unsigned num_instances, unsigned base_instance); - -extern void -_tnl_RasterPos(struct gl_context *ctx, const GLfloat vObj[4]); - -extern void -_tnl_validate_shine_tables( struct gl_context *ctx ); - - - -/** - * For indirect array drawing: - * - * typedef struct { - * GLuint count; - * GLuint primCount; - * GLuint first; - * GLuint baseInstance; // in GL 4.2 and later, must be zero otherwise - * } DrawArraysIndirectCommand; - * - * For indirect indexed drawing: - * - * typedef struct { - * GLuint count; - * GLuint primCount; - * GLuint firstIndex; - * GLint baseVertex; - * GLuint baseInstance; // in GL 4.2 and later, must be zero otherwise - * } DrawElementsIndirectCommand; - */ - - -/** - * Draw a number of primitives. - * \param prims array [nr_prims] describing what to draw (prim type, - * vertex count, first index, instance count, etc). - * \param arrays array of vertex arrays for draw - * \param ib index buffer for indexed drawing, NULL for array drawing - * \param index_bounds_valid are min_index and max_index valid? - * \param min_index lowest vertex index used - * \param max_index highest vertex index used - * \param tfb_vertcount if non-null, indicates which transform feedback - * object has the vertex count. - * \param tfb_stream If called via DrawTransformFeedbackStream, specifies the - * vertex stream buffer from which to get the vertex count. - * \param indirect If any prims are indirect, this specifies the buffer - * to find the "DrawArrays/ElementsIndirectCommand" data. - * This may be deprecated in the future - */ -typedef void (*tnl_draw_func)(struct gl_context *ctx, - const struct tnl_vertex_array* arrays, - const struct _mesa_prim *prims, - GLuint nr_prims, - const struct _mesa_index_buffer *ib, - GLboolean index_bounds_valid, - GLuint min_index, - GLuint max_index, - GLuint num_instances, - GLuint base_instance); - - -/* Utility function to cope with various constraints on tnl modules or - * hardware. This can be used to split an incoming set of arrays and - * primitives against the following constraints: - * - Maximum number of indices in index buffer. - * - Maximum number of vertices referenced by index buffer. - * - Maximum hardware vertex buffer size. - */ -struct split_limits -{ - GLuint max_verts; - GLuint max_indices; - GLuint max_vb_size; /* bytes */ -}; - -void -_tnl_split_prims(struct gl_context *ctx, - const struct tnl_vertex_array *arrays, - const struct _mesa_prim *prim, - GLuint nr_prims, - const struct _mesa_index_buffer *ib, - GLuint min_index, - GLuint max_index, - GLuint num_instances, - GLuint base_instance, - tnl_draw_func draw, - const struct split_limits *limits); - - -#endif diff --git a/src/mesa/x86-64/x86-64.c b/src/mesa/x86-64/x86-64.c deleted file mode 100644 index d484038..0000000 --- a/src/mesa/x86-64/x86-64.c +++ /dev/null @@ -1,119 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2003 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -/* - * x86-64 optimizations shamelessy converted from x86/sse/3dnow assembly by - * Mikko Tiihonen - */ - -#ifdef USE_X86_64_ASM - -#include "main/glheader.h" -#include "main/context.h" -#include "math/m_xform.h" -#include "tnl/t_context.h" -#include "x86-64.h" -#include "../x86/x86_xform.h" - -#ifdef DEBUG -#include "math/m_debug.h" -#endif - -extern void _mesa_x86_64_cpuid(unsigned int *regs); - -DECLARE_XFORM_GROUP( x86_64, 4 ) -DECLARE_XFORM_GROUP( 3dnow, 4 ) - -#else -/* just to silence warning below */ -#include "x86-64.h" -#endif - -/* -extern void _mesa_x86_64_transform_points4_general( XFORM_ARGS ); -extern void _mesa_x86_64_transform_points4_identity( XFORM_ARGS ); -extern void _mesa_x86_64_transform_points4_perspective( XFORM_ARGS ); -extern void _mesa_x86_64_transform_points4_3d( XFORM_ARGS ); -extern void _mesa_x86_64_transform_points4_3d_no_rot( XFORM_ARGS ); -extern void _mesa_x86_64_transform_points4_2d_no_rot( XFORM_ARGS ); -extern void _mesa_x86_64_transform_points4_2d( XFORM_ARGS ); -*/ - -#ifdef USE_X86_64_ASM -static void message( const char *msg ) -{ - if (getenv("MESA_DEBUG")) { - _mesa_debug( NULL, "%s", msg ); - } -} -#endif - - -void _mesa_init_all_x86_64_transform_asm(void) -{ -#ifdef USE_X86_64_ASM - unsigned int regs[4]; - - if ( getenv( "MESA_NO_ASM" ) ) { - return; - } - - message("Initializing x86-64 optimizations\n"); - - - _mesa_transform_tab[4][MATRIX_GENERAL] = - _mesa_x86_64_transform_points4_general; - _mesa_transform_tab[4][MATRIX_IDENTITY] = - _mesa_x86_64_transform_points4_identity; - _mesa_transform_tab[4][MATRIX_3D] = - _mesa_x86_64_transform_points4_3d; - - regs[0] = 0x80000001; - regs[1] = 0x00000000; - regs[2] = 0x00000000; - regs[3] = 0x00000000; - _mesa_x86_64_cpuid(regs); - if (regs[3] & (1U << 31)) { - message("3Dnow! detected\n"); - _mesa_transform_tab[4][MATRIX_3D_NO_ROT] = - _mesa_3dnow_transform_points4_3d_no_rot; - _mesa_transform_tab[4][MATRIX_PERSPECTIVE] = - _mesa_3dnow_transform_points4_perspective; - _mesa_transform_tab[4][MATRIX_2D_NO_ROT] = - _mesa_3dnow_transform_points4_2d_no_rot; - _mesa_transform_tab[4][MATRIX_2D] = - _mesa_3dnow_transform_points4_2d; - - } - - -#ifdef DEBUG_MATH - _math_test_all_transform_functions("x86_64"); - _math_test_all_cliptest_functions("x86_64"); - _math_test_all_normal_transform_functions("x86_64"); -#endif - -#endif -} diff --git a/src/mesa/x86/3dnow.c b/src/mesa/x86/3dnow.c deleted file mode 100644 index df7c64f..0000000 --- a/src/mesa/x86/3dnow.c +++ /dev/null @@ -1,84 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2003 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -/* - * 3DNow! optimizations contributed by - * Holger Waechtler - */ - -#include "main/glheader.h" -#include "main/context.h" -#include "math/m_xform.h" -#include "tnl/t_context.h" - -#include "3dnow.h" -#include "x86_xform.h" - -#ifdef DEBUG_MATH -#include "math/m_debug.h" -#endif - - -#ifdef USE_3DNOW_ASM -DECLARE_XFORM_GROUP( 3dnow, 2 ) -DECLARE_XFORM_GROUP( 3dnow, 3 ) -DECLARE_XFORM_GROUP( 3dnow, 4 ) - - -extern void -_mesa_v16_3dnow_general_xform( GLfloat *first_vert, - const GLfloat *m, - const GLfloat *src, - GLuint src_stride, - GLuint count ); - -extern void -_mesa_3dnow_project_vertices( GLfloat *first, - GLfloat *last, - const GLfloat *m, - GLuint stride ); - -extern void -_mesa_3dnow_project_clipped_vertices( GLfloat *first, - GLfloat *last, - const GLfloat *m, - GLuint stride, - const GLubyte *clipmask ); -#endif - - -void _mesa_init_3dnow_transform_asm( void ) -{ -#ifdef USE_3DNOW_ASM - ASSIGN_XFORM_GROUP( 3dnow, 2 ); - ASSIGN_XFORM_GROUP( 3dnow, 3 ); - ASSIGN_XFORM_GROUP( 3dnow, 4 ); - -#ifdef DEBUG_MATH - _math_test_all_transform_functions( "3DNow!" ); - _math_test_all_normal_transform_functions( "3DNow!" ); -#endif -#endif -} diff --git a/src/mesa/x86/3dnow.h b/src/mesa/x86/3dnow.h deleted file mode 100644 index f61858f..0000000 --- a/src/mesa/x86/3dnow.h +++ /dev/null @@ -1,36 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -/* - * 3DNow! optimizations contributed by - * Holger Waechtler - */ - -#ifndef __3DNOW_H__ -#define __3DNOW_H__ - -void _mesa_init_3dnow_transform_asm( void ); - -#endif diff --git a/src/mesa/x86/3dnow_xform1.S b/src/mesa/x86/3dnow_xform1.S deleted file mode 100644 index b158a5a..0000000 --- a/src/mesa/x86/3dnow_xform1.S +++ /dev/null @@ -1,438 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -#ifdef USE_3DNOW_ASM -#include "assyntax.h" -#define MATH_ASM_PTR_SIZE 4 -#include "math/m_vector_asm.h" -#include "xform_args.h" - - SEG_TEXT - -#define FRAME_OFFSET 4 - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_3dnow_transform_points1_general ) -HIDDEN(_mesa_3dnow_transform_points1_general) -GLNAME( _mesa_3dnow_transform_points1_general ): - _CET_ENDBR - PUSH_L ( ESI ) - - MOV_L ( ARG_DEST, ECX ) - MOV_L ( ARG_MATRIX, ESI ) - MOV_L ( ARG_SOURCE, EAX ) - MOV_L ( CONST(4), REGOFF(V4F_SIZE, ECX) ) - OR_B ( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, ECX) ) - MOV_L ( REGOFF(V4F_COUNT, EAX), EDX ) - MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) ) - - PUSH_L ( EDI ) - - MOV_L ( REGOFF(4, ECX), EDX ) - MOV_L ( ESI, ECX ) - MOV_L ( REGOFF(V4F_COUNT, EAX), ESI ) - MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI ) - MOV_L ( REGOFF(V4F_START, EAX), EAX ) - - TEST_L ( ESI, ESI ) - JZ ( LLBL( G3TPGR_3 ) ) - - MOVQ ( REGIND(ECX), MM0 ) /* m01 | m00 */ - MOVQ ( REGOFF(8, ECX), MM1 ) /* m03 | m02 */ - - MOVQ ( REGOFF(48, ECX), MM2 ) /* m31 | m30 */ - MOVQ ( REGOFF(56, ECX), MM3 ) /* m33 | m32 */ - -ALIGNTEXT16 -LLBL( G3TPGR_2 ): - - MOVD ( REGIND(EAX), MM4 ) /* | x0 */ - PUNPCKLDQ ( MM4, MM4 ) /* x0 | x0 */ - - MOVQ ( MM4, MM5 ) /* x0 | x0 */ - PFMUL ( MM0, MM4 ) /* x0*m01 | x0*m00 */ - - PFMUL ( MM1, MM5 ) /* x0*m03 | x0*m02 */ - PFADD ( MM2, MM4 ) /* x0*m01+m31 | x0*m00+m30 */ - - PFADD ( MM3, MM5 ) /* x0*m03+m33 | x0*m02+m32 */ - MOVQ ( MM4, REGIND(EDX) ) /* write r1, r0 */ - - MOVQ ( MM5, REGOFF(8, EDX) ) /* write r3, r2 */ - ADD_L ( EDI, EAX ) /* next vertex */ - - ADD_L ( CONST(16), EDX ) /* next r */ - DEC_L ( ESI ) /* decrement vertex counter */ - - JNZ ( LLBL( G3TPGR_2 ) ) /* cnt > 0 ? -> process next vertex */ - -LLBL( G3TPGR_3 ): - - FEMMS - POP_L ( EDI ) - POP_L ( ESI ) - RET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_3dnow_transform_points1_identity ) -HIDDEN(_mesa_3dnow_transform_points1_identity) -GLNAME( _mesa_3dnow_transform_points1_identity ): - _CET_ENDBR - PUSH_L ( ESI ) - - MOV_L ( ARG_DEST, ECX ) - MOV_L ( ARG_MATRIX, ESI ) - MOV_L ( ARG_SOURCE, EAX ) - MOV_L ( CONST(1), REGOFF(V4F_SIZE, ECX) ) - OR_B ( CONST(VEC_SIZE_1), REGOFF(V4F_FLAGS, ECX) ) - MOV_L ( REGOFF(V4F_COUNT, EAX), EDX ) - MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) ) - - PUSH_L ( EDI ) - - MOV_L ( REGOFF(4, ECX), EDX ) - MOV_L ( ESI, ECX ) - MOV_L ( REGOFF(V4F_COUNT, EAX), ESI ) - MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI ) - MOV_L ( REGOFF(V4F_START, EAX), EAX ) - - TEST_L ( ESI, ESI ) - JZ ( LLBL( G3TPIR_4) ) - -ALIGNTEXT16 -LLBL( G3TPIR_3 ): - - MOVD ( REGIND(EAX), MM0 ) /* | x0 */ - ADD_L ( EDI, EAX ) /* next vertex */ - - MOVD ( MM0, REGIND(EDX) ) /* | r0 */ - ADD_L ( CONST(16), EDX ) /* next r */ - - DEC_L ( ESI ) /* decrement vertex counter */ - JNZ ( LLBL( G3TPIR_3 ) ) /* cnt > 0 ? -> process next vertex */ - -LLBL( G3TPIR_4 ): - - FEMMS - POP_L ( EDI ) - POP_L ( ESI ) - RET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_3dnow_transform_points1_3d_no_rot ) -HIDDEN(_mesa_3dnow_transform_points1_3d_no_rot) -GLNAME( _mesa_3dnow_transform_points1_3d_no_rot ): - _CET_ENDBR - PUSH_L ( ESI ) - - MOV_L ( ARG_DEST, ECX ) - MOV_L ( ARG_MATRIX, ESI ) - MOV_L ( ARG_SOURCE, EAX ) - MOV_L ( CONST(3), REGOFF(V4F_SIZE, ECX) ) - OR_B ( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, ECX) ) - MOV_L ( REGOFF(V4F_COUNT, EAX), EDX ) - MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) ) - - PUSH_L ( EDI ) - - MOV_L ( REGOFF(4, ECX), EDX ) - MOV_L ( ESI, ECX ) - MOV_L ( REGOFF(V4F_COUNT, EAX), ESI ) - MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI ) - MOV_L ( REGOFF(V4F_START, EAX), EAX ) - - TEST_L ( ESI, ESI ) - JZ ( LLBL( G3TP3NRR_3 ) ) - - MOVD ( REGIND(ECX), MM0 ) /* | m00 */ - MOVQ ( REGOFF(48, ECX), MM2 ) /* m31 | m30 */ - - MOVD ( REGOFF(56, ECX), MM3 ) /* | m32 */ - -ALIGNTEXT16 -LLBL( G3TP3NRR_2 ): - - MOVD ( REGIND(EAX), MM4 ) /* | x0 */ - PFMUL ( MM0, MM4 ) /* | x0*m00 */ - - PFADD ( MM2, MM4 ) /* m31 | x0*m00+m30 */ - MOVQ ( MM4, REGIND(EDX) ) /* write r1, r0 */ - - MOVD ( MM3, REGOFF(8, EDX) ) /* write r2 */ - ADD_L ( EDI, EAX ) /* next vertex */ - - ADD_L ( CONST(16), EDX ) /* next r */ - DEC_L ( ESI ) /* decrement vertex counter */ - - JNZ ( LLBL( G3TP3NRR_2 ) ) /* cnt > 0 ? -> process next vertex */ - -LLBL( G3TP3NRR_3 ): - - FEMMS - POP_L ( EDI ) - POP_L ( ESI ) - RET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_3dnow_transform_points1_perspective ) -HIDDEN(_mesa_3dnow_transform_points1_perspective) -GLNAME( _mesa_3dnow_transform_points1_perspective ): - _CET_ENDBR - PUSH_L ( ESI ) - - MOV_L ( ARG_DEST, ECX ) - MOV_L ( ARG_MATRIX, ESI ) - MOV_L ( ARG_SOURCE, EAX ) - MOV_L ( CONST(4), REGOFF(V4F_SIZE, ECX) ) - OR_B ( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, ECX) ) - MOV_L ( REGOFF(V4F_COUNT, EAX), EDX ) - MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) ) - - PUSH_L ( EDI ) - - MOV_L ( REGOFF(4, ECX), EDX ) - MOV_L ( ESI, ECX ) - MOV_L ( REGOFF(V4F_COUNT, EAX), ESI ) - MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI ) - MOV_L ( REGOFF(V4F_START, EAX), EAX ) - - TEST_L ( ESI, ESI ) - JZ ( LLBL( G3TPPR_3 ) ) - - MOVD ( REGIND(ECX), MM0 ) /* | m00 */ - MOVD ( REGOFF(56, ECX), MM3 ) /* | m32 */ - -ALIGNTEXT16 -LLBL( G3TPPR_2 ): - - MOVD ( REGIND(EAX), MM4 ) /* 0 | x0 */ - PFMUL ( MM0, MM4 ) /* 0 | x0*m00 */ - - MOVQ ( MM4, REGIND(EDX) ) /* write r1, r0 */ - MOVQ ( MM3, REGOFF(8, EDX) ) /* write r2 (=m32), r3 (=0) */ - - ADD_L ( EDI, EAX ) /* next vertex */ - ADD_L ( CONST(16), EDX ) /* next r */ - - DEC_L ( ESI ) /* decrement vertex counter */ - JNZ ( LLBL( G3TPPR_2 ) ) /* cnt > 0 ? -> process next vertex */ - -LLBL( G3TPPR_3 ): - - FEMMS - POP_L ( EDI ) - POP_L ( ESI ) - RET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_3dnow_transform_points1_2d ) -HIDDEN(_mesa_3dnow_transform_points1_2d) -GLNAME( _mesa_3dnow_transform_points1_2d ): - _CET_ENDBR - PUSH_L ( ESI ) - - MOV_L ( ARG_DEST, ECX ) - MOV_L ( ARG_MATRIX, ESI ) - MOV_L ( ARG_SOURCE, EAX ) - MOV_L ( CONST(2), REGOFF(V4F_SIZE, ECX) ) - OR_B ( CONST(VEC_SIZE_2), REGOFF(V4F_FLAGS, ECX) ) - MOV_L ( REGOFF(V4F_COUNT, EAX), EDX ) - MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) ) - - PUSH_L ( EDI ) - - MOV_L ( REGOFF(4, ECX), EDX ) - MOV_L ( ESI, ECX ) - MOV_L ( REGOFF(V4F_COUNT, EAX), ESI ) - MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI ) - MOV_L ( REGOFF(V4F_START, EAX), EAX ) - - TEST_L ( ESI, ESI ) - JZ ( LLBL( G3TP2R_3 ) ) - - MOVQ ( REGIND(ECX), MM0 ) /* m01 | m00 */ - MOVQ ( REGOFF(48, ECX), MM2 ) /* m31 | m30 */ - -ALIGNTEXT16 -LLBL( G3TP2R_2 ): - - MOVD ( REGIND(EAX), MM4 ) /* | x0 */ - PUNPCKLDQ ( MM4, MM4 ) /* x0 | x0 */ - - PFMUL ( MM0, MM4 ) /* x0*m01 | x0*m00 */ - PFADD ( MM2, MM4 ) /* x0*m01+m31 | x0*m00+m30 */ - - MOVQ ( MM4, REGIND(EDX) ) /* write r1, r0 */ - ADD_L ( EDI, EAX ) /* next vertex */ - - ADD_L ( CONST(16), EDX ) /* next r */ - DEC_L ( ESI ) /* decrement vertex counter */ - - JNZ ( LLBL( G3TP2R_2 ) ) /* cnt > 0 ? -> process next vertex */ - -LLBL( G3TP2R_3 ): - - FEMMS - POP_L ( EDI ) - POP_L ( ESI ) - RET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_3dnow_transform_points1_2d_no_rot ) -HIDDEN(_mesa_3dnow_transform_points1_2d_no_rot) -GLNAME( _mesa_3dnow_transform_points1_2d_no_rot ): - _CET_ENDBR - PUSH_L ( ESI ) - - MOV_L ( ARG_DEST, ECX ) - MOV_L ( ARG_MATRIX, ESI ) - MOV_L ( ARG_SOURCE, EAX ) - MOV_L ( CONST(2), REGOFF(V4F_SIZE, ECX) ) - OR_B ( CONST(VEC_SIZE_2), REGOFF(V4F_FLAGS, ECX) ) - MOV_L ( REGOFF(V4F_COUNT, EAX), EDX ) - MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) ) - - PUSH_L ( EDI ) - - MOV_L ( REGOFF(4, ECX), EDX ) - MOV_L ( ESI, ECX ) - MOV_L ( REGOFF(V4F_COUNT, EAX), ESI ) - MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI ) - MOV_L ( REGOFF(V4F_START, EAX), EAX ) - - TEST_L ( ESI, ESI ) - JZ ( LLBL( G3TP2NRR_3 ) ) - - MOVD ( REGIND(ECX), MM0 ) /* | m00 */ - MOVQ ( REGOFF(48, ECX), MM2 ) /* m31 | m30 */ - -ALIGNTEXT16 -LLBL( G3TP2NRR_2 ): - - MOVD ( REGIND(EAX), MM4 ) /* | x0 */ - ADD_L ( EDI, EAX ) /* next vertex */ - - PFMUL ( MM0, MM4 ) /* | x0*m00 */ - PFADD ( MM2, MM4 ) /* m31 | x0*m00+m30 */ - - MOVQ ( MM4, REGIND(EDX) ) /* write r1, r0 */ - ADD_L ( CONST(16), EDX ) /* next r */ - - DEC_L ( ESI ) /* decrement vertex counter */ - JNZ ( LLBL( G3TP2NRR_2 ) ) /* cnt > 0 ? -> process next vertex */ - -LLBL( G3TP2NRR_3 ): - - FEMMS - POP_L ( EDI ) - POP_L ( ESI ) - RET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_3dnow_transform_points1_3d ) -HIDDEN(_mesa_3dnow_transform_points1_3d) -GLNAME( _mesa_3dnow_transform_points1_3d ): - _CET_ENDBR - PUSH_L ( ESI ) - - MOV_L ( ARG_DEST, ECX ) - MOV_L ( ARG_MATRIX, ESI ) - MOV_L ( ARG_SOURCE, EAX ) - MOV_L ( CONST(3), REGOFF(V4F_SIZE, ECX) ) - OR_B ( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, ECX) ) - MOV_L ( REGOFF(V4F_COUNT, EAX), EDX ) - MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) ) - - PUSH_L ( EDI ) - - MOV_L ( REGOFF(4, ECX), EDX ) - MOV_L ( ESI, ECX ) - MOV_L ( REGOFF(V4F_COUNT, EAX), ESI ) - MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI ) - MOV_L ( REGOFF(V4F_START, EAX), EAX ) - - TEST_L ( ESI, ESI ) - JZ ( LLBL( G3TP3R_3 ) ) - - MOVQ ( REGIND(ECX), MM0 ) /* m01 | m00 */ - MOVD ( REGOFF(8, ECX), MM1 ) /* | m02 */ - - MOVQ ( REGOFF(48, ECX), MM2 ) /* m31 | m30 */ - MOVD ( REGOFF(56, ECX), MM3 ) /* | m32 */ - -ALIGNTEXT16 -LLBL( G3TP3R_2 ): - - MOVD ( REGIND(EAX), MM4 ) /* | x0 */ - PUNPCKLDQ ( MM4, MM4 ) /* x0 | x0 */ - - MOVQ ( MM4, MM5 ) /* | x0 */ - PFMUL ( MM0, MM4 ) /* x0*m01 | x0*m00 */ - - PFMUL ( MM1, MM5 ) /* | x0*m02 */ - PFADD ( MM2, MM4 ) /* x0*m01+m31 | x0*m00+m30 */ - - PFADD ( MM3, MM5 ) /* | x0*m02+m32 */ - MOVQ ( MM4, REGIND(EDX) ) /* write r1, r0 */ - - MOVD ( MM5, REGOFF(8, EDX) ) /* write r2 */ - ADD_L ( EDI, EAX ) /* next vertex */ - - ADD_L ( CONST(16), EDX ) /* next r */ - DEC_L ( ESI ) /* decrement vertex counter */ - - JNZ ( LLBL( G3TP3R_2 ) ) /* cnt > 0 ? -> process next vertex */ - -LLBL( G3TP3R_3 ): - - FEMMS - POP_L ( EDI ) - POP_L ( ESI ) - RET - -#endif - -#if defined (__ELF__) && defined (__linux__) - .section .note.GNU-stack,"",%progbits -#endif diff --git a/src/mesa/x86/3dnow_xform2.S b/src/mesa/x86/3dnow_xform2.S deleted file mode 100644 index bed217b..0000000 --- a/src/mesa/x86/3dnow_xform2.S +++ /dev/null @@ -1,478 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -#ifdef USE_3DNOW_ASM -#include "assyntax.h" -#define MATH_ASM_PTR_SIZE 4 -#include "math/m_vector_asm.h" -#include "xform_args.h" - - SEG_TEXT - -#define FRAME_OFFSET 4 - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_3dnow_transform_points2_general ) -HIDDEN(_mesa_3dnow_transform_points2_general) -GLNAME( _mesa_3dnow_transform_points2_general ): - _CET_ENDBR - PUSH_L ( ESI ) - - MOV_L ( ARG_DEST, ECX ) - MOV_L ( ARG_MATRIX, ESI ) - MOV_L ( ARG_SOURCE, EAX ) - MOV_L ( CONST(4), REGOFF(V4F_SIZE, ECX) ) - OR_B ( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, ECX) ) - MOV_L ( REGOFF(V4F_COUNT, EAX), EDX ) - MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) ) - - PUSH_L ( EDI ) - - MOV_L ( REGOFF(V4F_START, ECX), EDX ) - MOV_L ( ESI, ECX ) - MOV_L ( REGOFF(V4F_COUNT, EAX), ESI ) - MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI ) - MOV_L ( REGOFF(V4F_START, EAX), EAX ) - - TEST_L ( ESI, ESI ) - JZ ( LLBL( G3TPGR_3 ) ) - - MOVD ( REGIND(ECX), MM0 ) /* | m00 */ - PUNPCKLDQ ( REGOFF(16, ECX), MM0 ) /* m10 | m00 */ - - MOVD ( REGOFF(4, ECX), MM1 ) /* | m01 */ - PUNPCKLDQ ( REGOFF(20, ECX), MM1 ) /* m11 | m01 */ - - MOVD ( REGOFF(8, ECX), MM2 ) /* | m02 */ - PUNPCKLDQ ( REGOFF(24, ECX), MM2 ) /* m12 | m02 */ - - MOVD ( REGOFF(12, ECX), MM3 ) /* | m03 */ - PUNPCKLDQ ( REGOFF(28, ECX), MM3 ) /* m13 | m03 */ - - MOVQ ( REGOFF(48, ECX), MM4 ) /* m31 | m30 */ - MOVQ ( REGOFF(56, ECX), MM5 ) /* m33 | m32 */ - -ALIGNTEXT16 -LLBL( G3TPGR_2 ): - - MOVQ ( REGIND(EAX), MM6 ) /* x1 | x0 */ - MOVQ ( MM6, MM7 ) /* x1 | x0 */ - - PFMUL ( MM0, MM6 ) /* x1*m10 | x0*m00 */ - PFMUL ( MM1, MM7 ) /* x1*m11 | x0*m01 */ - - PFACC ( MM7, MM6 ) /* x0*m01+x1*m11 | x0*x00+x1*m10 */ - PFADD ( MM4, MM6 ) /* x0*...*m11+m31 | x0*...*m10+m30 */ - - MOVQ ( MM6, REGIND(EDX) ) /* write r1, r0 */ - MOVQ ( REGIND(EAX), MM6 ) /* x1 | x0 */ - - MOVQ ( MM6, MM7 ) /* x1 | x0 */ - PFMUL ( MM2, MM6 ) /* x1*m12 | x0*m02 */ - - PFMUL ( MM3, MM7 ) /* x1*m13 | x0*m03 */ - ADD_L ( EDI, EAX ) /* next vertex */ - - PFACC ( MM7, MM6 ) /* x0*m03+x1*m13 | x0*x02+x1*m12 */ - PFADD ( MM5, MM6 ) /* x0*...*m13+m33 | x0*...*m12+m32 */ - - MOVQ ( MM6, REGOFF(8, EDX) ) /* write r3, r2 */ - ADD_L ( CONST(16), EDX ) /* next r */ - - DEC_L ( ESI ) /* decrement vertex counter */ - JNZ ( LLBL( G3TPGR_2 ) ) /* cnt > 0 ? -> process next vertex */ - -LLBL( G3TPGR_3 ): - - FEMMS - POP_L ( EDI ) - POP_L ( ESI ) - RET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_3dnow_transform_points2_perspective ) -HIDDEN(_mesa_3dnow_transform_points2_perspective) -GLNAME( _mesa_3dnow_transform_points2_perspective ): - _CET_ENDBR - PUSH_L ( ESI ) - - MOV_L ( ARG_DEST, ECX ) - MOV_L ( ARG_MATRIX, ESI ) - MOV_L ( ARG_SOURCE, EAX ) - MOV_L ( CONST(4), REGOFF(V4F_SIZE, ECX) ) - OR_B ( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, ECX) ) - MOV_L ( REGOFF(V4F_COUNT, EAX), EDX ) - MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) ) - - PUSH_L ( EDI ) - - MOV_L ( REGOFF(V4F_START, ECX), EDX ) - MOV_L ( ESI, ECX ) - MOV_L ( REGOFF(V4F_COUNT, EAX), ESI ) - MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI ) - MOV_L ( REGOFF(V4F_START, EAX), EAX ) - - TEST_L ( ESI, ESI ) - JZ ( LLBL( G3TPPR_3 ) ) - - MOVD ( REGIND(ECX), MM0 ) /* | m00 */ - PUNPCKLDQ ( REGOFF(20, ECX), MM0 ) /* m11 | m00 */ - - MOVD ( REGOFF(56, ECX), MM3 ) /* | m32 */ - -ALIGNTEXT16 -LLBL( G3TPPR_2 ): - - MOVQ ( REGIND(EAX), MM4 ) /* x1 | x0 */ - PFMUL ( MM0, MM4 ) /* x1*m11 | x0*m00 */ - - MOVQ ( MM4, REGIND(EDX) ) /* write r1, r0 */ - MOVQ ( MM3, REGOFF(8, EDX) ) /* write r2 (=m32), r3 (=0) */ - - ADD_L ( EDI, EAX ) /* next vertex */ - ADD_L ( CONST(16), EDX ) /* next r */ - - DEC_L ( ESI ) /* decrement vertex counter */ - JNZ ( LLBL( G3TPPR_2 ) ) /* cnt > 0 ? -> process next vertex */ - -LLBL( G3TPPR_3 ): - - FEMMS - POP_L ( EDI ) - POP_L ( ESI ) - RET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_3dnow_transform_points2_3d ) -HIDDEN(_mesa_3dnow_transform_points2_3d) -GLNAME( _mesa_3dnow_transform_points2_3d ): - _CET_ENDBR - PUSH_L ( ESI ) - - MOV_L ( ARG_DEST, ECX ) - MOV_L ( ARG_MATRIX, ESI ) - MOV_L ( ARG_SOURCE, EAX ) - MOV_L ( CONST(3), REGOFF(V4F_SIZE, ECX) ) - OR_B ( CONST(VEC_SIZE_3 ), REGOFF(V4F_FLAGS, ECX) ) - MOV_L ( REGOFF(V4F_COUNT, EAX), EDX ) - MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) ) - - PUSH_L ( EDI ) - - MOV_L ( REGOFF(V4F_START, ECX), EDX ) - MOV_L ( ESI, ECX ) - MOV_L ( REGOFF(V4F_COUNT, EAX), ESI ) - MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI ) - MOV_L ( REGOFF(V4F_START, EAX), EAX ) - - TEST_L ( ESI, ESI ) - JZ ( LLBL( G3TP3R_3 ) ) - - MOVD ( REGIND(ECX), MM0 ) /* | m00 */ - PUNPCKLDQ ( REGOFF(16, ECX), MM0 ) /* m10 | m00 */ - - MOVD ( REGOFF(4, ECX), MM1 ) /* | m01 */ - PUNPCKLDQ ( REGOFF(20, ECX), MM1 ) /* m11 | m01 */ - - MOVD ( REGOFF(8, ECX), MM2 ) /* | m02 */ - PUNPCKLDQ ( REGOFF(24, ECX), MM2 ) /* m12 | m02 */ - - MOVQ ( REGOFF(48, ECX), MM4 ) /* m31 | m30 */ - MOVD ( REGOFF(56, ECX), MM5 ) /* | m32 */ - -ALIGNTEXT16 -LLBL( G3TP3R_2 ): - - MOVQ ( REGIND(EAX), MM6 ) /* x1 | x0 */ - MOVQ ( MM6, MM7 ) /* x1 | x0 */ - - PFMUL ( MM0, MM6 ) /* x1*m10 | x0*m00 */ - PFMUL ( MM1, MM7 ) /* x1*m11 | x0*m01 */ - - PFACC ( MM7, MM6 ) /* x0*m01+x1*m11 | x0*x00+x1*m10 */ - PFADD ( MM4, MM6 ) /* x0*...*m11+m31 | x0*...*m10+m30 */ - - MOVQ ( MM6, REGIND(EDX) ) /* write r1, r0 */ - MOVQ ( REGIND(EAX), MM6 ) /* x1 | x0 */ - - MOVQ ( MM6, MM7 ) /* x1 | x0 */ - PFMUL ( MM2, MM6 ) /* x1*m12 | x0*m02 */ - - PFACC ( MM7, MM6 ) /* ***trash*** | x0*x02+x1*m12 */ - PFADD ( MM5, MM6 ) /* ***trash*** | x0*...*m12+m32 */ - - MOVD ( MM6, REGOFF(8, EDX) ) /* write r2 */ - ADD_L ( EDI, EAX ) /* next vertex */ - - ADD_L ( CONST(16), EDX ) /* next r */ - DEC_L ( ESI ) /* decrement vertex counter */ - - JNZ ( LLBL( G3TP3R_2 ) ) /* cnt > 0 ? -> process next vertex */ - -LLBL( G3TP3R_3 ): - - FEMMS - POP_L ( EDI ) - POP_L ( ESI ) - RET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_3dnow_transform_points2_3d_no_rot ) -HIDDEN(_mesa_3dnow_transform_points2_3d_no_rot) -GLNAME( _mesa_3dnow_transform_points2_3d_no_rot ): - _CET_ENDBR - PUSH_L ( ESI ) - - MOV_L ( ARG_DEST, ECX ) - MOV_L ( ARG_MATRIX, ESI ) - MOV_L ( ARG_SOURCE, EAX ) - MOV_L ( CONST(3), REGOFF(V4F_SIZE, ECX) ) - OR_B ( CONST(VEC_SIZE_3 ), REGOFF(V4F_FLAGS, ECX) ) - MOV_L ( REGOFF(V4F_COUNT, EAX), EDX ) - MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) ) - - PUSH_L ( EDI ) - - MOV_L ( REGOFF(V4F_START, ECX), EDX ) - MOV_L ( ESI, ECX ) - MOV_L ( REGOFF(V4F_COUNT, EAX), ESI ) - MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI ) - MOV_L ( REGOFF(V4F_START, EAX), EAX ) - - TEST_L ( ESI, ESI ) - JZ ( LLBL( G3TP3NRR_3 ) ) - - MOVD ( REGIND(ECX), MM0 ) /* | m00 */ - PUNPCKLDQ ( REGOFF(20, ECX), MM0 ) /* m11 | m00 */ - - MOVQ ( REGOFF(48, ECX), MM2 ) /* m31 | m30 */ - MOVD ( REGOFF(56, ECX), MM3 ) /* | m32 */ - -ALIGNTEXT16 -LLBL( G3TP3NRR_2 ): - - MOVQ ( REGIND(EAX), MM4 ) /* x1 | x0 */ - PFMUL ( MM0, MM4 ) /* x1*m11 | x0*m00 */ - - PFADD ( MM2, MM4 ) /* x1*m11+m31 | x0*m00+m30 */ - MOVQ ( MM4, REGIND(EDX) ) /* write r1, r0 */ - - MOVD ( MM3, REGOFF(8, EDX) ) /* write r2 */ - ADD_L ( EDI, EAX ) /* next vertex */ - - ADD_L ( CONST(16), EDX ) /* next r */ - DEC_L ( ESI ) /* decrement vertex counter */ - - JNZ ( LLBL( G3TP3NRR_2 ) ) /* cnt > 0 ? -> process next vertex */ - -LLBL( G3TP3NRR_3 ): - - FEMMS - POP_L ( EDI ) - POP_L ( ESI ) - RET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_3dnow_transform_points2_2d ) -HIDDEN(_mesa_3dnow_transform_points2_2d) -GLNAME( _mesa_3dnow_transform_points2_2d ): - _CET_ENDBR - PUSH_L ( ESI ) - - MOV_L ( ARG_DEST, ECX ) - MOV_L ( ARG_MATRIX, ESI ) - MOV_L ( ARG_SOURCE, EAX ) - MOV_L ( CONST(2), REGOFF(V4F_SIZE, ECX) ) - OR_B ( CONST(VEC_SIZE_2), REGOFF(V4F_FLAGS, ECX) ) - MOV_L ( REGOFF(V4F_COUNT, EAX), EDX ) - MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) ) - - PUSH_L ( EDI ) - - MOV_L ( REGOFF(V4F_START, ECX), EDX ) - MOV_L ( ESI, ECX ) - MOV_L ( REGOFF(V4F_COUNT, EAX), ESI ) - MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI ) - MOV_L ( REGOFF(V4F_START, EAX), EAX ) - - TEST_L ( ESI, ESI ) - JZ ( LLBL( G3TP2R_3 ) ) - - MOVQ ( REGIND(ECX), MM0 ) /* m01 | m00 */ - MOVQ ( REGOFF(16, ECX), MM1 ) /* m11 | m10 */ - - MOVQ ( REGOFF(48, ECX), MM2 ) /* m31 | m30 */ - -ALIGNTEXT16 -LLBL( G3TP2R_2 ): - - MOVD ( REGIND(EAX), MM4 ) /* | x0 */ - MOVD ( REGOFF(4, EAX), MM5 ) /* | x1 */ - - PUNPCKLDQ ( MM4, MM4 ) /* x0 | x0 */ - ADD_L ( EDI, EAX ) /* next vertex */ - - PFMUL ( MM0, MM4 ) /* x0*m01 | x0*m00 */ - PUNPCKLDQ ( MM5, MM5 ) /* x1 | x1 */ - - PFMUL ( MM1, MM5 ) /* x1*m11 | x1*m10 */ - PFADD ( MM2, MM4 ) /* x...x1*m11+31 | x0*..*m10+m30 */ - - PFADD ( MM5, MM4 ) /* x0*m01+x1*m11 | x0*m00+x1*m10 */ - MOVQ ( MM4, REGIND(EDX) ) /* write r1, r0 */ - - ADD_L ( CONST(16), EDX ) /* next r */ - DEC_L ( ESI ) /* decrement vertex counter */ - - JNZ ( LLBL( G3TP2R_2 ) ) /* cnt > 0 ? -> process next vertex */ - -LLBL( G3TP2R_3 ): - - FEMMS - POP_L ( EDI ) - POP_L ( ESI ) - RET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_3dnow_transform_points2_2d_no_rot ) -HIDDEN(_mesa_3dnow_transform_points2_2d_no_rot) -GLNAME( _mesa_3dnow_transform_points2_2d_no_rot ): - _CET_ENDBR - PUSH_L ( ESI ) - - MOV_L ( ARG_DEST, ECX ) - MOV_L ( ARG_MATRIX, ESI ) - MOV_L ( ARG_SOURCE, EAX ) - MOV_L ( CONST(2), REGOFF(V4F_SIZE, ECX) ) - OR_B ( CONST(VEC_SIZE_2), REGOFF(V4F_FLAGS, ECX) ) - MOV_L ( REGOFF(V4F_COUNT, EAX), EDX ) - MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) ) - - PUSH_L ( EDI ) - - MOV_L ( REGOFF(V4F_START, ECX), EDX ) - MOV_L ( ESI, ECX ) - MOV_L ( REGOFF(V4F_COUNT, EAX), ESI ) - MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI ) - MOV_L ( REGOFF(V4F_START, EAX), EAX ) - - TEST_L ( ESI, ESI ) - JZ ( LLBL( G3TP2NRR_3 ) ) - - MOVD ( REGIND(ECX), MM0 ) /* | m00 */ - PUNPCKLDQ ( REGOFF(20, ECX), MM0 ) /* m11 | m00 */ - - MOVQ ( REGOFF(48, ECX), MM2 ) /* m31 | m30 */ - -ALIGNTEXT16 -LLBL( G3TP2NRR_2 ): - - MOVQ ( REGIND(EAX), MM4 ) /* x1 | x0 */ - ADD_L ( EDI, EAX ) /* next vertex */ - - PFMUL ( MM0, MM4 ) /* x1*m11 | x0*m00 */ - PFADD ( MM2, MM4 ) /* m31 | x0*m00+m30 */ - - MOVQ ( MM4, REGIND(EDX) ) /* write r1, r0 */ - ADD_L ( CONST(16), EDX ) /* next r */ - - DEC_L ( ESI ) /* decrement vertex counter */ - JNZ ( LLBL( G3TP2NRR_2 ) ) /* cnt > 0 ? -> process next vertex */ - -LLBL( G3TP2NRR_3 ): - - FEMMS - POP_L ( EDI ) - POP_L ( ESI ) - RET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_3dnow_transform_points2_identity ) -HIDDEN(_mesa_3dnow_transform_points2_identity) -GLNAME( _mesa_3dnow_transform_points2_identity ): - _CET_ENDBR - PUSH_L ( ESI ) - - MOV_L ( ARG_DEST, ECX ) - MOV_L ( ARG_MATRIX, ESI ) - MOV_L ( ARG_SOURCE, EAX ) - MOV_L ( CONST(2), REGOFF(V4F_SIZE, ECX) ) - OR_B ( CONST(VEC_SIZE_2), REGOFF(V4F_FLAGS, ECX) ) - MOV_L ( REGOFF(V4F_COUNT, EAX), EDX ) - MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) ) - - PUSH_L ( EDI ) - - MOV_L ( REGOFF(V4F_START, ECX), EDX ) - MOV_L ( ESI, ECX ) - MOV_L ( REGOFF(V4F_COUNT, EAX), ESI ) - MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI ) - MOV_L ( REGOFF(V4F_START, EAX), EAX ) - - TEST_L ( ESI, ESI ) - JZ ( LLBL( G3TPIR_3 ) ) - -ALIGNTEXT16 -LLBL( G3TPIR_3 ): - - MOVQ ( REGIND(EAX), MM0 ) /* x1 | x0 */ - ADD_L ( EDI, EAX ) /* next vertex */ - - MOVQ ( MM0, REGIND(EDX) ) /* r1 | r0 */ - ADD_L ( CONST(16), EDX ) /* next r */ - - DEC_L ( ESI ) /* decrement vertex counter */ - JNZ ( LLBL( G3TPIR_3 ) ) /* cnt > 0 ? -> process next vertex */ - -LLBL( G3TPIR_4 ): - - FEMMS - POP_L ( EDI ) - POP_L ( ESI ) - RET -#endif - -#if defined (__ELF__) && defined (__linux__) - .section .note.GNU-stack,"",%progbits -#endif diff --git a/src/mesa/x86/3dnow_xform3.S b/src/mesa/x86/3dnow_xform3.S deleted file mode 100644 index 85ad301..0000000 --- a/src/mesa/x86/3dnow_xform3.S +++ /dev/null @@ -1,562 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -#ifdef USE_3DNOW_ASM -#include "assyntax.h" -#define MATH_ASM_PTR_SIZE 4 -#include "math/m_vector_asm.h" -#include "xform_args.h" - - SEG_TEXT - -#define FRAME_OFFSET 4 - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_3dnow_transform_points3_general ) -HIDDEN(_mesa_3dnow_transform_points3_general) -GLNAME( _mesa_3dnow_transform_points3_general ): - _CET_ENDBR - PUSH_L ( ESI ) - - MOV_L ( ARG_DEST, ECX ) - MOV_L ( ARG_MATRIX, ESI ) - MOV_L ( ARG_SOURCE, EAX ) - MOV_L ( CONST(4), REGOFF(V4F_SIZE, ECX) ) - OR_B ( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, ECX) ) - MOV_L ( REGOFF(V4F_COUNT, EAX), EDX ) - MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) ) - - PUSH_L ( EDI ) - - MOV_L ( REGOFF(V4F_START, ECX), EDX ) - MOV_L ( ESI, ECX ) - MOV_L ( REGOFF(V4F_COUNT, EAX), ESI ) - MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI ) - MOV_L ( REGOFF(V4F_START, EAX), EAX ) - - TEST_L ( ESI, ESI ) - JZ ( LLBL( G3TPGR_2 ) ) - - PREFETCHW ( REGIND(EDX) ) - -ALIGNTEXT16 -LLBL( G3TPGR_1 ): - - PREFETCHW ( REGOFF(32, EDX) ) /* prefetch 2 vertices ahead */ - - MOVQ ( REGIND(EAX), MM0 ) /* x1 | x0 */ - MOVD ( REGOFF(8, EAX), MM2 ) /* | x2 */ - - ADD_L ( EDI, EAX ) /* next vertex */ - PREFETCH ( REGIND(EAX) ) - - MOVQ ( MM0, MM1 ) /* x1 | x0 */ - PUNPCKLDQ ( MM2, MM2 ) /* x2 | x2 */ - - PUNPCKLDQ ( MM0, MM0 ) /* x0 | x0 */ - MOVQ ( MM2, MM5 ) /* x2 | x2 */ - - PUNPCKHDQ ( MM1, MM1 ) /* x1 | x1 */ - PFMUL ( REGOFF(32, ECX), MM2 ) /* x2*m9 | x2*m8 */ - - MOVQ ( MM0, MM3 ) /* x0 | x0 */ - PFMUL ( REGOFF(40, ECX), MM5 ) /* x2*m11 | x2*m10 */ - - MOVQ ( MM1, MM4 ) /* x1 | x1 */ - PFMUL ( REGIND(ECX), MM0 ) /* x0*m1 | x0*m0 */ - - PFADD ( REGOFF(48, ECX), MM2 ) /* x2*m9+m13 | x2*m8+m12 */ - PFMUL ( REGOFF(16, ECX), MM1 ) /* x1*m5 | x1*m4 */ - - PFADD ( REGOFF(56, ECX), MM5 ) /* x2*m11+m15 | x2*m10+m14 */ - PFADD ( MM0, MM1 ) /* x0*m1+x1*m5 | x0*m0+x1*m4 */ - - PFMUL ( REGOFF(8, ECX), MM3 ) /* x0*m3 | x0*m2 */ - PFADD ( MM1, MM2 ) /* r1 | r0 */ - - PFMUL ( REGOFF(24, ECX), MM4 ) /* x1*m7 | x1*m6 */ - ADD_L ( CONST(16), EDX ) /* next output vertex */ - - PFADD ( MM3, MM4 ) /* x0*m3+x1*m7 | x0*m2+x1*m6 */ - MOVQ ( MM2, REGOFF(-16, EDX) ) /* write r0, r1 */ - - PFADD ( MM4, MM5 ) /* r3 | r2 */ - MOVQ ( MM5, REGOFF(-8, EDX) ) /* write r2, r3 */ - - DEC_L ( ESI ) /* decrement vertex counter */ - JNZ ( LLBL( G3TPGR_1 ) ) /* cnt > 0 ? -> process next vertex */ - -LLBL( G3TPGR_2 ): - - FEMMS - POP_L ( EDI ) - POP_L ( ESI ) - RET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_3dnow_transform_points3_perspective ) -HIDDEN(_mesa_3dnow_transform_points3_perspective) -GLNAME( _mesa_3dnow_transform_points3_perspective ): - _CET_ENDBR - PUSH_L ( ESI ) - - MOV_L ( ARG_DEST, ECX ) - MOV_L ( ARG_MATRIX, ESI ) - MOV_L ( ARG_SOURCE, EAX ) - MOV_L ( CONST(4), REGOFF(V4F_SIZE, ECX) ) - OR_B ( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, ECX) ) - MOV_L ( REGOFF(V4F_COUNT, EAX), EDX ) - MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) ) - - PUSH_L ( EDI ) - - MOV_L ( REGOFF(V4F_START, ECX), EDX ) - MOV_L ( ESI, ECX ) - MOV_L ( REGOFF(V4F_COUNT, EAX), ESI ) - MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI ) - MOV_L ( REGOFF(V4F_START, EAX), EAX ) - - TEST_L ( ESI, ESI ) - JZ ( LLBL( G3TPPR_2 ) ) - - PREFETCH ( REGIND(EAX) ) - PREFETCHW ( REGIND(EDX) ) - - MOVD ( REGIND(ECX), MM0 ) /* | m00 */ - PUNPCKLDQ ( REGOFF(20, ECX), MM0 ) /* m11 | m00 */ - - MOVQ ( REGOFF(32, ECX), MM1 ) /* m21 | m20 */ - MOVD ( REGOFF(40, ECX), MM2 ) /* | m22 */ - - MOVD ( REGOFF(56, ECX), MM3 ) /* | m32 */ - -ALIGNTEXT16 -LLBL( G3TPPR_1 ): - - PREFETCHW ( REGOFF(32, EDX) ) /* prefetch 2 vertices ahead */ - - MOVD ( REGOFF(8, EAX), MM5 ) /* | x2 */ - MOVQ ( REGIND(EAX), MM4 ) /* x1 | x0 */ - - ADD_L ( EDI, EAX ) /* next vertex */ - PREFETCH ( REGIND(EAX) ) - - PXOR ( MM7, MM7 ) /* 0 | 0 */ - MOVQ ( MM5, MM6 ) /* | x2 */ - - PFMUL ( MM0, MM4 ) /* x1*m11 | x0*m00 */ - PFSUB ( MM5, MM7 ) /* | -x2 */ - - PFMUL ( MM2, MM6 ) /* | x2*m22 */ - PUNPCKLDQ ( MM5, MM5 ) /* x2 | x2 */ - - ADD_L ( CONST(16), EDX ) /* next r */ - PFMUL ( MM1, MM5 ) /* x2*m21 | x2*m20 */ - - PFADD ( MM3, MM6 ) /* | x2*m22+m32 */ - PFADD ( MM4, MM5 ) /* x1*m11+x2*m21 | x0*m00+x2*m20 */ - - MOVQ ( MM5, REGOFF(-16, EDX) ) /* write r0, r1 */ - MOVD ( MM6, REGOFF(-8, EDX) ) /* write r2 */ - - MOVD ( MM7, REGOFF(-4, EDX) ) /* write r3 */ - - DEC_L ( ESI ) /* decrement vertex counter */ - JNZ ( LLBL( G3TPPR_1 ) ) /* cnt > 0 ? -> process next vertex */ - -LLBL( G3TPPR_2 ): - - FEMMS - POP_L ( EDI ) - POP_L ( ESI ) - RET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_3dnow_transform_points3_3d ) -HIDDEN(_mesa_3dnow_transform_points3_3d) -GLNAME( _mesa_3dnow_transform_points3_3d ): - _CET_ENDBR - PUSH_L ( ESI ) - - MOV_L ( ARG_DEST, ECX ) - MOV_L ( ARG_MATRIX, ESI ) - MOV_L ( ARG_SOURCE, EAX ) - MOV_L ( CONST(3), REGOFF(V4F_SIZE, ECX) ) - OR_B ( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, ECX) ) - MOV_L ( REGOFF(V4F_COUNT, EAX), EDX ) - MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) ) - - PUSH_L ( EDI ) - - MOV_L ( REGOFF(V4F_START, ECX), EDX ) - MOV_L ( ESI, ECX ) - MOV_L ( REGOFF(V4F_COUNT, EAX), ESI ) - MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI ) - MOV_L ( REGOFF(V4F_START, EAX), EAX ) - - TEST_L ( ESI, ESI ) - JZ ( LLBL( G3TP3R_2 ) ) - - PREFETCH ( REGIND(EAX) ) - PREFETCH ( REGIND(EDX) ) - - MOVD ( REGOFF(8, ECX), MM7 ) /* | m2 */ - PUNPCKLDQ ( REGOFF(24, ECX), MM7 ) /* m6 | m2 */ - - -ALIGNTEXT16 -LLBL( G3TP3R_1 ): - - PREFETCHW ( REGOFF(32, EDX) ) /* prefetch 2 vertices ahead */ - - MOVQ ( REGIND(EAX), MM0 ) /* x1 | x0 */ - MOVD ( REGOFF(8, EAX), MM1 ) /* | x2 */ - - ADD_L ( EDI, EAX ) /* next vertex */ - PREFETCH ( REGIND(EAX) ) - - MOVQ ( MM0, MM2 ) /* x1 | x0 */ - ADD_L ( CONST(16), EDX ) /* next r */ - - PUNPCKLDQ ( MM2, MM2 ) /* x0 | x0 */ - MOVQ ( MM0, MM3 ) /* x1 | x0 */ - - PFMUL ( REGIND(ECX), MM2 ) /* x0*m1 | x0*m0 */ - PUNPCKHDQ ( MM3, MM3 ) /* x1 | x1 */ - - MOVQ ( MM1, MM4 ) /* | x2 */ - PFMUL ( REGOFF(16, ECX), MM3 ) /* x1*m5 | x1*m4 */ - - PUNPCKLDQ ( MM4, MM4 ) /* x2 | x2 */ - PFADD ( MM2, MM3 ) /* x0*m1+x1*m5 | x0*m0+x1*m4 */ - - PFMUL ( REGOFF(32, ECX), MM4 ) /* x2*m9 | x2*m8 */ - PFADD ( REGOFF(48, ECX), MM3 ) /* x0*m1+...+m11 | x0*m0+x1*m4+m12 */ - - PFMUL ( MM7, MM0 ) /* x1*m6 | x0*m2 */ - PFADD ( MM4, MM3 ) /* r1 | r0 */ - - PFMUL ( REGOFF(40, ECX), MM1 ) /* | x2*m10 */ - PUNPCKLDQ ( REGOFF(56, ECX), MM1 ) /* m14 | x2*m10 */ - - PFACC ( MM0, MM1 ) - - MOVQ ( MM3, REGOFF(-16, EDX) ) /* write r0, r1 */ - PFACC ( MM1, MM1 ) /* | r2 */ - - MOVD ( MM1, REGOFF(-8, EDX) ) /* write r2 */ - - DEC_L ( ESI ) /* decrement vertex counter */ - JNZ ( LLBL( G3TP3R_1 ) ) /* cnt > 0 ? -> process next vertex */ - -LLBL( G3TP3R_2 ): - - FEMMS - POP_L ( EDI ) - POP_L ( ESI ) - RET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_3dnow_transform_points3_3d_no_rot ) -HIDDEN(_mesa_3dnow_transform_points3_3d_no_rot) -GLNAME( _mesa_3dnow_transform_points3_3d_no_rot ): - _CET_ENDBR - PUSH_L ( ESI ) - - MOV_L ( ARG_DEST, ECX ) - MOV_L ( ARG_MATRIX, ESI ) - MOV_L ( ARG_SOURCE, EAX ) - MOV_L ( CONST(3), REGOFF(V4F_SIZE, ECX) ) - OR_B ( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, ECX) ) - MOV_L ( REGOFF(V4F_COUNT, EAX), EDX ) - MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) ) - - PUSH_L ( EDI ) - - MOV_L ( REGOFF(V4F_START, ECX), EDX ) - MOV_L ( ESI, ECX ) - MOV_L ( REGOFF(V4F_COUNT, EAX), ESI ) - MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI ) - MOV_L ( REGOFF(V4F_START, EAX), EAX ) - - TEST_L ( ESI, ESI ) - JZ ( LLBL( G3TP3NRR_2 ) ) - - PREFETCH ( REGIND(EAX) ) - PREFETCHW ( REGIND(EDX) ) - - MOVD ( REGIND(ECX), MM0 ) /* | m00 */ - PUNPCKLDQ ( REGOFF(20, ECX), MM0 ) /* m11 | m00 */ - - MOVD ( REGOFF(40, ECX), MM2 ) /* | m22 */ - PUNPCKLDQ ( MM2, MM2 ) /* m22 | m22 */ - - MOVQ ( REGOFF(48, ECX), MM1 ) /* m31 | m30 */ - MOVD ( REGOFF(56, ECX), MM3 ) /* | m32 */ - - PUNPCKLDQ ( MM3, MM3 ) /* m32 | m32 */ - - -ALIGNTEXT16 -LLBL( G3TP3NRR_1 ): - - PREFETCHW ( REGOFF(32, EDX) ) /* prefetch 2 vertices ahead */ - - MOVQ ( REGIND(EAX), MM4 ) /* x1 | x0 */ - MOVD ( REGOFF(8, EAX), MM5 ) /* | x2 */ - - ADD_L ( EDI, EAX ) /* next vertex */ - PREFETCHW ( REGIND(EAX) ) - - PFMUL ( MM0, MM4 ) /* x1*m11 | x0*m00 */ - - PFADD ( MM1, MM4 ) /* x1*m11+m31 | x0*m00+m30 */ - PFMUL ( MM2, MM5 ) /* | x2*m22 */ - - PFADD ( MM3, MM5 ) /* | x2*m22+m32 */ - MOVQ ( MM4, REGIND(EDX) ) /* write r0, r1 */ - - ADD_L ( CONST(16), EDX ) /* next r */ - DEC_L ( ESI ) /* decrement vertex counter */ - - MOVD ( MM5, REGOFF(-8, EDX) ) /* write r2 */ - JNZ ( LLBL( G3TP3NRR_1 ) ) /* cnt > 0 ? -> process next vertex */ - -LLBL( G3TP3NRR_2 ): - - FEMMS - POP_L ( EDI ) - POP_L ( ESI ) - RET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_3dnow_transform_points3_2d ) -HIDDEN(_mesa_3dnow_transform_points3_2d) -GLNAME( _mesa_3dnow_transform_points3_2d ): - _CET_ENDBR - PUSH_L ( ESI ) - - MOV_L ( ARG_DEST, ECX ) - MOV_L ( ARG_MATRIX, ESI ) - MOV_L ( ARG_SOURCE, EAX ) - MOV_L ( CONST(3), REGOFF(V4F_SIZE, ECX) ) - OR_B ( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, ECX) ) - MOV_L ( REGOFF(V4F_COUNT, EAX), EDX ) - MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) ) - - PUSH_L ( EDI ) - - MOV_L ( REGOFF(V4F_START, ECX), EDX ) - MOV_L ( ESI, ECX ) - MOV_L ( REGOFF(V4F_COUNT, EAX), ESI ) - MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI ) - MOV_L ( REGOFF(V4F_START, EAX), EAX ) - - TEST_L ( ESI, ESI ) - JZ ( LLBL( G3TP2R_3) ) - - PREFETCH ( REGIND(EAX) ) - PREFETCHW ( REGIND(EDX) ) - - MOVD ( REGIND(ECX), MM0 ) /* | m00 */ - PUNPCKLDQ ( REGOFF(16, ECX), MM0 ) /* m10 | m00 */ - - MOVD ( REGOFF(4, ECX), MM1 ) /* | m01 */ - PUNPCKLDQ ( REGOFF(20, ECX), MM1 ) /* m11 | m01 */ - - MOVQ ( REGOFF(48, ECX), MM2 ) /* m31 | m30 */ - -ALIGNTEXT16 -LLBL( G3TP2R_2 ): - - PREFETCHW ( REGOFF(32, EDX) ) /* prefetch 2 vertices ahead */ - - MOVQ ( REGIND(EAX), MM3 ) /* x1 | x0 */ - MOVD ( REGOFF(8, EAX), MM5 ) /* | x2 */ - - ADD_L ( EDI, EAX ) /* next vertex */ - PREFETCH ( REGIND(EAX) ) - - MOVQ ( MM3, MM4 ) /* x1 | x0 */ - PFMUL ( MM0, MM3 ) /* x1*m10 | x0*m00 */ - - ADD_L ( CONST(16), EDX ) /* next r */ - PFMUL ( MM1, MM4 ) /* x1*m11 | x0*m01 */ - - PFACC ( MM4, MM3 ) /* x0*m00+x1*m10 | x0*m01+x1*m11 */ - MOVD ( MM5, REGOFF(-8, EDX) ) /* write r2 (=x2) */ - - PFADD ( MM2, MM3 ) /* x0*...*m10+m30 | x0*...*m11+m31 */ - MOVQ ( MM3, REGOFF(-16, EDX) ) /* write r0, r1 */ - - DEC_L ( ESI ) /* decrement vertex counter */ - JNZ ( LLBL( G3TP2R_2 ) ) /* cnt > 0 ? -> process next vertex */ - -LLBL( G3TP2R_3 ): - - FEMMS - POP_L ( EDI ) - POP_L ( ESI ) - RET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_3dnow_transform_points3_2d_no_rot ) -HIDDEN(_mesa_3dnow_transform_points3_2d_no_rot) -GLNAME( _mesa_3dnow_transform_points3_2d_no_rot ): - _CET_ENDBR - PUSH_L ( ESI ) - - MOV_L ( ARG_DEST, ECX ) - MOV_L ( ARG_MATRIX, ESI ) - MOV_L ( ARG_SOURCE, EAX ) - MOV_L ( CONST(3), REGOFF(V4F_SIZE, ECX) ) - OR_B ( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, ECX) ) - MOV_L ( REGOFF(V4F_COUNT, EAX), EDX ) - MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) ) - - PUSH_L ( EDI ) - - MOV_L ( REGOFF(V4F_START, ECX), EDX ) - MOV_L ( ESI, ECX ) - MOV_L ( REGOFF(V4F_COUNT, EAX), ESI ) - MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI ) - MOV_L ( REGOFF(V4F_START, EAX), EAX ) - - TEST_L ( ESI, ESI ) - JZ ( LLBL( G3TP2NRR_2 ) ) - - PREFETCH ( REGIND(EAX) ) - PREFETCHW ( REGIND(EDX) ) - - MOVD ( REGIND(ECX), MM0 ) /* | m00 */ - PUNPCKLDQ ( REGOFF(20, ECX), MM0 ) /* m11 | m00 */ - - MOVQ ( REGOFF(48, ECX), MM1 ) /* m31 | m30 */ - - -ALIGNTEXT16 -LLBL( G3TP2NRR_1 ): - - PREFETCHW ( REGOFF(32, EDX) ) /* prefetch 2 vertices ahead */ - - MOVQ ( REGIND(EAX), MM4 ) /* x1 | x0 */ - MOVD ( REGOFF(8, EAX), MM5 ) /* | x2 */ - - ADD_L ( EDI, EAX ) /* next vertex */ - PREFETCH ( REGIND(EAX) ) - - PFMUL ( MM0, MM4 ) /* x1*m11 | x0*m00 */ - ADD_L ( CONST(16), EDX ) /* next r */ - - PFADD ( MM1, MM4 ) /* x1*m11+m31 | x0*m00+m30 */ - - MOVQ ( MM4, REGOFF(-16, EDX) ) /* write r0, r1 */ - MOVD ( MM5, REGOFF(-8, EDX) ) /* write r2 (=x2) */ - - DEC_L ( ESI ) /* decrement vertex counter */ - JNZ ( LLBL( G3TP2NRR_1 ) ) /* cnt > 0 ? -> process next vertex */ - -LLBL( G3TP2NRR_2 ): - - FEMMS - POP_L ( EDI ) - POP_L ( ESI ) - RET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_3dnow_transform_points3_identity ) -HIDDEN(_mesa_3dnow_transform_points3_identity) -GLNAME( _mesa_3dnow_transform_points3_identity ): - _CET_ENDBR - PUSH_L ( ESI ) - - MOV_L ( ARG_DEST, ECX ) - MOV_L ( ARG_MATRIX, ESI ) - MOV_L ( ARG_SOURCE, EAX ) - MOV_L ( CONST(3), REGOFF(V4F_SIZE, ECX) ) - OR_B ( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, ECX) ) - MOV_L ( REGOFF(V4F_COUNT, EAX), EDX ) - MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) ) - - PUSH_L ( EDI ) - - MOV_L ( REGOFF(V4F_START, ECX), EDX ) - MOV_L ( ESI, ECX ) - MOV_L ( REGOFF(V4F_COUNT, EAX), ESI ) - MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI ) - MOV_L ( REGOFF(V4F_START, EAX), EAX ) - - TEST_L ( ESI, ESI ) - JZ ( LLBL( G3TPIR_2 ) ) - - PREFETCHW ( REGIND(EDX) ) - -ALIGNTEXT16 -LLBL( G3TPIR_1 ): - - PREFETCHW ( REGOFF(32, EDX) ) - - MOVQ ( REGIND(EAX), MM0 ) /* x1 | x0 */ - MOVD ( REGOFF(8, EAX), MM1 ) /* | x2 */ - - ADD_L ( EDI, EAX ) /* next vertex */ - ADD_L ( CONST(16), EDX ) /* next r */ - - DEC_L ( ESI ) /* decrement vertex counter */ - MOVQ ( MM0, REGOFF(-16, EDX) ) /* r1 | r0 */ - - MOVD ( MM1, REGOFF(-8, EDX) ) /* | r2 */ - JNZ ( LLBL( G3TPIR_1 ) ) /* cnt > 0 ? -> process next vertex */ - -LLBL( G3TPIR_2 ): - - FEMMS - POP_L ( EDI ) - POP_L ( ESI ) - RET -#endif - -#if defined (__ELF__) && defined (__linux__) - .section .note.GNU-stack,"",%progbits -#endif diff --git a/src/mesa/x86/3dnow_xform4.S b/src/mesa/x86/3dnow_xform4.S deleted file mode 100644 index 87868e44..0000000 --- a/src/mesa/x86/3dnow_xform4.S +++ /dev/null @@ -1,571 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -#ifdef USE_3DNOW_ASM -#include "assyntax.h" -#define MATH_ASM_PTR_SIZE 4 -#include "math/m_vector_asm.h" -#include "xform_args.h" - - SEG_TEXT - -#define FRAME_OFFSET 4 - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_3dnow_transform_points4_general ) -HIDDEN(_mesa_3dnow_transform_points4_general) -GLNAME( _mesa_3dnow_transform_points4_general ): - _CET_ENDBR - PUSH_L ( ESI ) - - MOV_L ( ARG_DEST, ECX ) - MOV_L ( ARG_MATRIX, ESI ) - MOV_L ( ARG_SOURCE, EAX ) - MOV_L ( CONST(4), REGOFF(V4F_SIZE, ECX) ) - OR_B ( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, ECX) ) - MOV_L ( REGOFF(V4F_COUNT, EAX), EDX ) - MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) ) - - PUSH_L ( EDI ) - - MOV_L ( REGOFF(V4F_START, ECX), EDX ) - MOV_L ( ESI, ECX ) - MOV_L ( REGOFF(V4F_COUNT, EAX), ESI ) - MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI ) - MOV_L ( REGOFF(V4F_START, EAX), EAX ) - - TEST_L ( ESI, ESI ) - JZ ( LLBL( G3TPGR_2 ) ) - - PREFETCHW ( REGIND(EDX) ) - -ALIGNTEXT16 -LLBL( G3TPGR_1 ): - - PREFETCHW ( REGOFF(32, EDX) ) /* prefetch 2 vertices ahead */ - - MOVQ ( REGIND(EAX), MM0 ) /* x1 | x0 */ - MOVQ ( REGOFF(8, EAX), MM4 ) /* x3 | x2 */ - - ADD_L ( EDI, EAX ) /* next vertex */ - PREFETCH ( REGIND(EAX) ) - - MOVQ ( MM0, MM2 ) /* x1 | x0 */ - MOVQ ( MM4, MM6 ) /* x3 | x2 */ - - PUNPCKLDQ ( MM0, MM0 ) /* x0 | x0 */ - PUNPCKHDQ ( MM2, MM2 ) /* x1 | x1 */ - - MOVQ ( MM0, MM1 ) /* x0 | x0 */ - ADD_L ( CONST(16), EDX ) /* next r */ - - PFMUL ( REGIND(ECX), MM0 ) /* x0*m1 | x0*m0 */ - MOVQ ( MM2, MM3 ) /* x1 | x1 */ - - PFMUL ( REGOFF(8, ECX), MM1 ) /* x0*m3 | x0*m2 */ - PUNPCKLDQ ( MM4, MM4 ) /* x2 | x2 */ - - PFMUL ( REGOFF(16, ECX), MM2 ) /* x1*m5 | x1*m4 */ - MOVQ ( MM4, MM5 ) /* x2 | x2 */ - - PFMUL ( REGOFF(24, ECX), MM3 ) /* x1*m7 | x1*m6 */ - PUNPCKHDQ ( MM6, MM6 ) /* x3 | x3 */ - - PFMUL ( REGOFF(32, ECX), MM4 ) /* x2*m9 | x2*m8 */ - MOVQ ( MM6, MM7 ) /* x3 | x3 */ - - PFMUL ( REGOFF(40, ECX), MM5 ) /* x2*m11 | x2*m10 */ - PFADD ( MM0, MM2 ) - - PFMUL ( REGOFF(48, ECX), MM6 ) /* x3*m13 | x3*m12 */ - PFADD ( MM1, MM3 ) - - PFMUL ( REGOFF(56, ECX), MM7 ) /* x3*m15 | x3*m14 */ - PFADD ( MM4, MM6 ) - - PFADD ( MM5, MM7 ) - PFADD ( MM2, MM6 ) - - PFADD ( MM3, MM7 ) - MOVQ ( MM6, REGOFF(-16, EDX) ) - - MOVQ ( MM7, REGOFF(-8, EDX) ) - - DEC_L ( ESI ) /* decrement vertex counter */ - JNZ ( LLBL( G3TPGR_1 ) ) /* cnt > 0 ? -> process next vertex */ - -LLBL( G3TPGR_2 ): - - FEMMS - POP_L ( EDI ) - POP_L ( ESI ) - RET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_3dnow_transform_points4_perspective ) -HIDDEN(_mesa_3dnow_transform_points4_perspective) -GLNAME( _mesa_3dnow_transform_points4_perspective ): - _CET_ENDBR - PUSH_L ( ESI ) - - MOV_L ( ARG_DEST, ECX ) - MOV_L ( ARG_MATRIX, ESI ) - MOV_L ( ARG_SOURCE, EAX ) - MOV_L ( CONST(4), REGOFF(V4F_SIZE, ECX) ) - OR_B ( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, ECX) ) - MOV_L ( REGOFF(V4F_COUNT, EAX), EDX ) - MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) ) - - PUSH_L ( EDI ) - - MOV_L ( REGOFF(V4F_START, ECX), EDX ) - MOV_L ( ESI, ECX ) - MOV_L ( REGOFF(V4F_COUNT, EAX), ESI ) - MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI ) - MOV_L ( REGOFF(V4F_START, EAX), EAX ) - - TEST_L ( ESI, ESI ) - JZ ( LLBL( G3TPPR_2 ) ) - - PREFETCH ( REGIND(EAX) ) - PREFETCHW ( REGIND(EDX) ) - - MOVD ( REGIND(ECX), MM0 ) /* | m00 */ - PUNPCKLDQ ( REGOFF(20, ECX), MM0 ) /* m11 | m00 */ - - MOVD ( REGOFF(40, ECX), MM1 ) /* | m22 */ - PUNPCKLDQ ( REGOFF(56, ECX), MM1 ) /* m32 | m22 */ - - MOVQ ( REGOFF(32, ECX), MM2 ) /* m21 | m20 */ - PXOR ( MM7, MM7 ) /* 0 | 0 */ - -ALIGNTEXT16 -LLBL( G3TPPR_1 ): - - PREFETCHW ( REGOFF(32, EDX) ) /* prefetch 2 vertices ahead */ - - MOVQ ( REGIND(EAX), MM4 ) /* x1 | x0 */ - MOVQ ( REGOFF(8, EAX), MM5 ) /* x3 | x2 */ - MOVD ( REGOFF(8, EAX), MM3 ) /* | x2 */ - - ADD_L ( EDI, EAX ) /* next vertex */ - PREFETCH ( REGOFF(32, EAX) ) /* hopefully stride is zero */ - - MOVQ ( MM5, MM6 ) /* x3 | x2 */ - PFMUL ( MM0, MM4 ) /* x1*m11 | x0*m00 */ - - PUNPCKLDQ ( MM5, MM5 ) /* x2 | x2 */ - ADD_L ( CONST(16), EDX ) /* next r */ - - PFMUL ( MM2, MM5 ) /* x2*m21 | x2*m20 */ - PFSUBR ( MM7, MM3 ) /* | -x2 */ - - PFMUL ( MM1, MM6 ) /* x3*m32 | x2*m22 */ - PFADD ( MM4, MM5 ) /* x1*m11+x2*m21 | x0*m00+x2*m20 */ - - PFACC ( MM3, MM6 ) /* -x2 | x2*m22+x3*m32 */ - MOVQ ( MM5, REGOFF(-16, EDX) ) /* write r0, r1 */ - - MOVQ ( MM6, REGOFF(-8, EDX) ) /* write r2, r3 */ - DEC_L ( ESI ) /* decrement vertex counter */ - - JNZ ( LLBL( G3TPPR_1 ) ) /* cnt > 0 ? -> process next vertex */ - -LLBL( G3TPPR_2 ): - - FEMMS - POP_L ( EDI ) - POP_L ( ESI ) - RET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_3dnow_transform_points4_3d ) -HIDDEN(_mesa_3dnow_transform_points4_3d) -GLNAME( _mesa_3dnow_transform_points4_3d ): - _CET_ENDBR - PUSH_L ( ESI ) - - MOV_L ( ARG_DEST, ECX ) - MOV_L ( ARG_MATRIX, ESI ) - MOV_L ( ARG_SOURCE, EAX ) - MOV_L ( CONST(4), REGOFF(V4F_SIZE, ECX) ) - OR_B ( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, ECX) ) - MOV_L ( REGOFF(V4F_COUNT, EAX), EDX ) - MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) ) - - PUSH_L ( EDI ) - - MOV_L ( REGOFF(V4F_START, ECX), EDX ) - MOV_L ( ESI, ECX ) - MOV_L ( REGOFF(V4F_COUNT, EAX), ESI ) - MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI ) - MOV_L ( REGOFF(V4F_START, EAX), EAX ) - - TEST_L ( ESI, ESI ) - JZ ( LLBL( G3TP3R_2 ) ) - - MOVD ( REGOFF(8, ECX), MM6 ) /* | m2 */ - PUNPCKLDQ ( REGOFF(24, ECX), MM6 ) /* m6 | m2 */ - - MOVD ( REGOFF(40, ECX), MM7 ) /* | m10 */ - PUNPCKLDQ ( REGOFF(56, ECX), MM7 ) /* m14 | m10 */ - -ALIGNTEXT16 -LLBL( G3TP3R_1 ): - - PREFETCHW ( REGOFF(32, EDX) ) /* prefetch 2 vertices ahead */ - PREFETCH ( REGOFF(32, EAX) ) /* hopefully array is tightly packed */ - - MOVQ ( REGIND(EAX), MM2 ) /* x1 | x0 */ - MOVQ ( REGOFF(8, EAX), MM3 ) /* x3 | x2 */ - - MOVQ ( MM2, MM0 ) /* x1 | x0 */ - MOVQ ( MM3, MM4 ) /* x3 | x2 */ - - MOVQ ( MM0, MM1 ) /* x1 | x0 */ - MOVQ ( MM4, MM5 ) /* x3 | x2 */ - - PUNPCKLDQ ( MM0, MM0 ) /* x0 | x0 */ - PUNPCKHDQ ( MM1, MM1 ) /* x1 | x1 */ - - PFMUL ( REGIND(ECX), MM0 ) /* x0*m1 | x0*m0 */ - PUNPCKLDQ ( MM3, MM3 ) /* x2 | x2 */ - - PFMUL ( REGOFF(16, ECX), MM1 ) /* x1*m5 | x1*m4 */ - PUNPCKHDQ ( MM4, MM4 ) /* x3 | x3 */ - - PFMUL ( MM6, MM2 ) /* x1*m6 | x0*m2 */ - PFADD ( MM0, MM1 ) /* x0*m1+x1*m5 | x0*m0+x1*m4 */ - - PFMUL ( REGOFF(32, ECX), MM3 ) /* x2*m9 | x2*m8 */ - ADD_L ( CONST(16), EDX ) /* next r */ - - PFMUL ( REGOFF(48, ECX), MM4 ) /* x3*m13 | x3*m12 */ - PFADD ( MM1, MM3 ) /* x0*m1+..+x2*m9 | x0*m0+...+x2*m8 */ - - PFMUL ( MM7, MM5 ) /* x3*m14 | x2*m10 */ - PFADD ( MM3, MM4 ) /* r1 | r0 */ - - PFACC ( MM2, MM5 ) /* x0*m2+x1*m6 | x2*m10+x3*m14 */ - MOVD ( REGOFF(12, EAX), MM0 ) /* | x3 */ - - ADD_L ( EDI, EAX ) /* next vertex */ - PFACC ( MM0, MM5 ) /* r3 | r2 */ - - MOVQ ( MM4, REGOFF(-16, EDX) ) /* write r0, r1 */ - MOVQ ( MM5, REGOFF(-8, EDX) ) /* write r2, r3 */ - - DEC_L ( ESI ) /* decrement vertex counter */ - JNZ ( LLBL( G3TP3R_1 ) ) /* cnt > 0 ? -> process next vertex */ - -LLBL( G3TP3R_2 ): - - FEMMS - POP_L ( EDI ) - POP_L ( ESI ) - RET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_3dnow_transform_points4_3d_no_rot ) -HIDDEN(_mesa_3dnow_transform_points4_3d_no_rot) -GLNAME( _mesa_3dnow_transform_points4_3d_no_rot ): - _CET_ENDBR - PUSH_L ( ESI ) - MOV_L ( ARG_DEST, ECX ) - MOV_L ( ARG_MATRIX, ESI ) - MOV_L ( ARG_SOURCE, EAX ) - MOV_L ( CONST(4), REGOFF(V4F_SIZE, ECX) ) - OR_B ( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, ECX) ) - MOV_L ( REGOFF(V4F_COUNT, EAX), EDX ) - MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) ) - - PUSH_L ( EDI ) - - MOV_L ( REGOFF(V4F_START, ECX), EDX ) - MOV_L ( ESI, ECX ) - MOV_L ( REGOFF(V4F_COUNT, EAX), ESI ) - MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI ) - MOV_L ( REGOFF(V4F_START, EAX), EAX ) - - TEST_L ( ESI, ESI ) - JZ ( LLBL( G3TP3NRR_2 ) ) - - MOVD ( REGIND(ECX), MM0 ) /* | m00 */ - PUNPCKLDQ ( REGOFF(20, ECX), MM0 ) /* m11 | m00 */ - - MOVD ( REGOFF(40, ECX), MM2 ) /* | m22 */ - PUNPCKLDQ ( REGOFF(56, ECX), MM2 ) /* m32 | m22 */ - - MOVQ ( REGOFF(48, ECX), MM1 ) /* m31 | m30 */ - -ALIGNTEXT16 -LLBL( G3TP3NRR_1 ): - - PREFETCHW ( REGOFF(32, EDX) ) /* prefetch 2 vertices ahead */ - - MOVQ ( REGIND(EAX), MM4 ) /* x1 | x0 */ - MOVQ ( REGOFF(8, EAX), MM5 ) /* x3 | x2 */ - MOVD ( REGOFF(12, EAX), MM7 ) /* | x3 */ - - ADD_L ( EDI, EAX ) /* next vertex */ - PREFETCH ( REGOFF(32, EAX) ) /* hopefully stride is zero */ - - MOVQ ( MM5, MM6 ) /* x3 | x2 */ - PFMUL ( MM0, MM4 ) /* x1*m11 | x0*m00 */ - - PUNPCKHDQ ( MM6, MM6 ) /* x3 | x3 */ - PFMUL ( MM2, MM5 ) /* x3*m32 | x2*m22 */ - - PFMUL ( MM1, MM6 ) /* x3*m31 | x3*m30 */ - PFACC ( MM7, MM5 ) /* x3 | x2*m22+x3*m32 */ - - PFADD ( MM6, MM4 ) /* x1*m11+x3*m31 | x0*m00+x3*m30 */ - ADD_L ( CONST(16), EDX ) /* next r */ - - MOVQ ( MM4, REGOFF(-16, EDX) ) /* write r0, r1 */ - MOVQ ( MM5, REGOFF(-8, EDX) ) /* write r2, r3 */ - - DEC_L ( ESI ) /* decrement vertex counter */ - JNZ ( LLBL( G3TP3NRR_1 ) ) /* cnt > 0 ? -> process next vertex */ - -LLBL( G3TP3NRR_2 ): - - FEMMS - POP_L ( EDI ) - POP_L ( ESI ) - RET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_3dnow_transform_points4_2d ) -HIDDEN(_mesa_3dnow_transform_points4_2d) -GLNAME( _mesa_3dnow_transform_points4_2d ): - _CET_ENDBR - PUSH_L ( ESI ) - - MOV_L ( ARG_DEST, ECX ) - MOV_L ( ARG_MATRIX, ESI ) - MOV_L ( ARG_SOURCE, EAX ) - MOV_L ( CONST(4), REGOFF(V4F_SIZE, ECX) ) - OR_B ( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, ECX) ) - MOV_L ( REGOFF(V4F_COUNT, EAX), EDX ) - MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) ) - - PUSH_L ( EDI ) - - MOV_L ( REGOFF(V4F_START, ECX), EDX ) - MOV_L ( ESI, ECX ) - MOV_L ( REGOFF(V4F_COUNT, EAX), ESI ) - MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI ) - MOV_L ( REGOFF(V4F_START, EAX), EAX ) - - TEST_L ( ESI, ESI ) - JZ ( LLBL( G3TP2R_2 ) ) - - MOVD ( REGIND(ECX), MM0 ) /* | m00 */ - PUNPCKLDQ ( REGOFF(16, ECX), MM0 ) /* m10 | m00 */ - - MOVD ( REGOFF(4, ECX), MM1 ) /* | m01 */ - PUNPCKLDQ ( REGOFF(20, ECX), MM1 ) /* m11 | m01 */ - - MOVQ ( REGOFF(48, ECX), MM2 ) /* m31 | m30 */ - -ALIGNTEXT16 -LLBL( G3TP2R_1 ): - - PREFETCHW ( REGOFF(32, EDX) ) /* prefetch 2 vertices ahead */ - - MOVQ ( REGIND(EAX), MM3 ) /* x1 | x0 */ - MOVQ ( REGOFF(8, EAX), MM5 ) /* x3 | x2 */ - - ADD_L ( EDI, EAX ) /* next vertex */ - PREFETCH ( REGIND(EAX) ) - - MOVQ ( MM3, MM4 ) /* x1 | x0 */ - MOVQ ( MM5, MM6 ) /* x3 | x2 */ - - PFMUL ( MM1, MM4 ) /* x1*m11 | x0*m01 */ - PUNPCKHDQ ( MM6, MM6 ) /* x3 | x3 */ - - PFMUL ( MM0, MM3 ) /* x1*m10 | x0*m00 */ - ADD_L ( CONST(16), EDX ) /* next r */ - - PFACC ( MM4, MM3 ) /* x0*m01+x1*m11 | x0*m00+x1*m10 */ - PFMUL ( MM2, MM6 ) /* x3*m31 | x3*m30 */ - - PFADD ( MM6, MM3 ) /* r1 | r0 */ - MOVQ ( MM5, REGOFF(-8, EDX) ) /* write r2, r3 */ - - MOVQ ( MM3, REGOFF(-16, EDX) ) /* write r0, r1 */ - - DEC_L ( ESI ) /* decrement vertex counter */ - JNZ ( LLBL( G3TP2R_1 ) ) /* cnt > 0 ? -> process next vertex */ - -LLBL( G3TP2R_2 ): - - FEMMS - POP_L ( EDI ) - POP_L ( ESI ) - RET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_3dnow_transform_points4_2d_no_rot ) -HIDDEN(_mesa_3dnow_transform_points4_2d_no_rot) -GLNAME( _mesa_3dnow_transform_points4_2d_no_rot ): - _CET_ENDBR - PUSH_L ( ESI ) - - MOV_L ( ARG_DEST, ECX ) - MOV_L ( ARG_MATRIX, ESI ) - MOV_L ( ARG_SOURCE, EAX ) - MOV_L ( CONST(4), REGOFF(V4F_SIZE, ECX) ) - OR_B ( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, ECX) ) - MOV_L ( REGOFF(V4F_COUNT, EAX), EDX ) - MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) ) - - PUSH_L ( EDI ) - - MOV_L ( REGOFF(V4F_START, ECX), EDX ) - MOV_L ( ESI, ECX ) - MOV_L ( REGOFF(V4F_COUNT, EAX), ESI ) - MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI ) - MOV_L ( REGOFF(V4F_START, EAX), EAX ) - - TEST_L ( ESI, ESI ) - JZ ( LLBL( G3TP2NRR_3 ) ) - - MOVD ( REGIND(ECX), MM0 ) /* | m00 */ - PUNPCKLDQ ( REGOFF(20, ECX), MM0 ) /* m11 | m00 */ - - MOVQ ( REGOFF(48, ECX), MM1 ) /* m31 | m30 */ - -ALIGNTEXT16 -LLBL( G3TP2NRR_2 ): - - PREFETCHW ( REGOFF(32, EDX) ) /* prefetch 2 vertices ahead */ - - MOVQ ( REGIND(EAX), MM4 ) /* x1 | x0 */ - MOVQ ( REGOFF(8, EAX), MM5 ) /* x3 | x2 */ - - ADD_L ( EDI, EAX ) /* next vertex */ - PREFETCH ( REGIND(EAX) ) - - PFMUL ( MM0, MM4 ) /* x1*m11 | x0*m00 */ - MOVQ ( MM5, MM6 ) /* x3 | x2 */ - - ADD_L ( CONST(16), EDX ) /* next r */ - PUNPCKHDQ ( MM6, MM6 ) /* x3 | x3 */ - - PFMUL ( MM1, MM6 ) /* x3*m31 | x3*m30 */ - PFADD ( MM4, MM6 ) /* x1*m11+x3*m31 | x0*m00+x3*m30 */ - - MOVQ ( MM6, REGOFF(-16, EDX) ) /* write r0, r1 */ - MOVQ ( MM5, REGOFF(-8, EDX) ) /* write r2, r3 */ - - DEC_L ( ESI ) /* decrement vertex counter */ - - JNZ ( LLBL( G3TP2NRR_2 ) ) /* cnt > 0 ? -> process next vertex */ - -LLBL( G3TP2NRR_3 ): - - FEMMS - POP_L ( EDI ) - POP_L ( ESI ) - RET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_3dnow_transform_points4_identity ) -HIDDEN(_mesa_3dnow_transform_points4_identity) -GLNAME( _mesa_3dnow_transform_points4_identity ): - _CET_ENDBR - PUSH_L ( ESI ) - - MOV_L ( ARG_DEST, ECX ) - MOV_L ( ARG_MATRIX, ESI ) - MOV_L ( ARG_SOURCE, EAX ) - MOV_L ( CONST(4), REGOFF(V4F_SIZE, ECX) ) - OR_B ( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, ECX) ) - MOV_L ( REGOFF(V4F_COUNT, EAX), EDX ) - MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) ) - - PUSH_L ( EDI ) - - MOV_L ( REGOFF(V4F_START, ECX), EDX ) - MOV_L ( ESI, ECX ) - MOV_L ( REGOFF(V4F_COUNT, EAX), ESI ) - MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI ) - MOV_L ( REGOFF(V4F_START, EAX), EAX ) - - TEST_L ( ESI, ESI ) - JZ ( LLBL( G3TPIR_2 ) ) - -ALIGNTEXT16 -LLBL( G3TPIR_1 ): - - PREFETCHW ( REGOFF(32, EDX) ) /* prefetch 2 vertices ahead */ - - MOVQ ( REGIND(EAX), MM0 ) /* x1 | x0 */ - MOVQ ( REGOFF(8, EAX), MM1 ) /* x3 | x2 */ - - ADD_L ( EDI, EAX ) /* next vertex */ - PREFETCH ( REGIND(EAX) ) - - ADD_L ( CONST(16), EDX ) /* next r */ - MOVQ ( MM0, REGOFF(-16, EDX) ) /* r1 | r0 */ - - MOVQ ( MM1, REGOFF(-8, EDX) ) /* r3 | r2 */ - - DEC_L ( ESI ) /* decrement vertex counter */ - JNZ ( LLBL( G3TPIR_1 ) ) /* cnt > 0 ? -> process next vertex */ - -LLBL( G3TPIR_2 ): - - FEMMS - POP_L ( EDI ) - POP_L ( ESI ) - RET -#endif - -#if defined (__ELF__) && defined (__linux__) - .section .note.GNU-stack,"",%progbits -#endif diff --git a/src/mesa/x86/clip_args.h b/src/mesa/x86/clip_args.h deleted file mode 100644 index 92e7b59..0000000 --- a/src/mesa/x86/clip_args.h +++ /dev/null @@ -1,59 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -/* - * Clip test function interface for assembly code. Simply define - * FRAME_OFFSET to the number of bytes pushed onto the stack before - * using the ARG_* argument macros. - * - * Gareth Hughes - */ - -#ifndef __CLIP_ARGS_H__ -#define __CLIP_ARGS_H__ - -/* - * Offsets for clip_func arguments - * - * typedef GLvector4f *(*clip_func)( GLvector4f *clip_vec, - * GLvector4f *proj_vec, - * GLubyte clipMask[], - * GLubyte *orMask, - * GLubyte *andMask ); - */ - -#define OFFSET_SOURCE 4 -#define OFFSET_DEST 8 -#define OFFSET_CLIP 12 -#define OFFSET_OR 16 -#define OFFSET_AND 20 - -#define ARG_SOURCE REGOFF(FRAME_OFFSET+OFFSET_SOURCE, ESP) -#define ARG_DEST REGOFF(FRAME_OFFSET+OFFSET_DEST, ESP) -#define ARG_CLIP REGOFF(FRAME_OFFSET+OFFSET_CLIP, ESP) -#define ARG_OR REGOFF(FRAME_OFFSET+OFFSET_OR, ESP) -#define ARG_AND REGOFF(FRAME_OFFSET+OFFSET_AND, ESP) - -#endif diff --git a/src/mesa/x86/mmx.h b/src/mesa/x86/mmx.h deleted file mode 100644 index 0befe1d..0000000 --- a/src/mesa/x86/mmx.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - - -#ifndef ASM_MMX_H -#define ASM_MMX_H - -#include "util/compiler.h" -#include "main/glheader.h" - -struct gl_context; - -extern void -_mesa_mmx_blend_transparency( struct gl_context *ctx, GLuint n, const GLubyte mask[], - GLvoid *rgba, const GLvoid *dest, - GLenum chanType ); - -extern void -_mesa_mmx_blend_add( struct gl_context *ctx, GLuint n, const GLubyte mask[], - GLvoid *rgba, const GLvoid *dest, - GLenum chanType ); - -extern void -_mesa_mmx_blend_min( struct gl_context *ctx, GLuint n, const GLubyte mask[], - GLvoid *rgba, const GLvoid *dest, - GLenum chanType ); - -extern void -_mesa_mmx_blend_max( struct gl_context *ctx, GLuint n, const GLubyte mask[], - GLvoid *rgba, const GLvoid *dest, - GLenum chanType ); - -extern void -_mesa_mmx_blend_modulate( struct gl_context *ctx, GLuint n, const GLubyte mask[], - GLvoid *rgba, const GLvoid *dest, - GLenum chanType ); - -#endif diff --git a/src/mesa/x86/mmx_blend.S b/src/mesa/x86/mmx_blend.S deleted file mode 100644 index 500e54a..0000000 --- a/src/mesa/x86/mmx_blend.S +++ /dev/null @@ -1,403 +0,0 @@ - ; -/* - * Written by Jos� Fonseca - */ - - -#ifdef USE_MMX_ASM -#include "assyntax.h" -#define MATH_ASM_PTR_SIZE 4 -#include "math/m_vector_asm.h" - -/* integer multiplication - alpha plus one - * - * makes the following approximation to the division (Sree) - * - * rgb*a/255 ~= (rgb*(a+1)) >> 256 - * - * which is the fastest method that satisfies the following OpenGL criteria - * - * 0*0 = 0 and 255*255 = 255 - * - * note that MX1 is a register with 0xffffffffffffffff constant which can be easily obtained making - * - * PCMPEQW ( MX1, MX1 ) - */ -#define GMB_MULT_AP1( MP1, MA1, MP2, MA2, MX1 ) \ - PSUBW ( MX1, MA1 ) /* a1 + 1 | a1 + 1 | a1 + 1 | a1 + 1 */ ;\ - PMULLW ( MP1, MA1 ) /* t1 = p1*a1 */ ;\ - ;\ -TWO(PSUBW ( MX1, MA2 )) /* a2 + 1 | a2 + 1 | a2 + 1 | a2 + 1 */ ;\ -TWO(PMULLW ( MP2, MA2 )) /* t2 = p2*a2 */ ;\ - ;\ - PSRLW ( CONST(8), MA1 ) /* t1 >> 8 ~= t1/255 */ ;\ -TWO(PSRLW ( CONST(8), MA2 )) /* t2 >> 8 ~= t2/255 */ - - -/* integer multiplication - geometric series - * - * takes the geometric series approximation to the division - * - * t/255 = (t >> 8) + (t >> 16) + (t >> 24) .. - * - * in this case just the first two terms to fit in 16bit arithmetic - * - * t/255 ~= (t + (t >> 8)) >> 8 - * - * note that just by itself it doesn't satisfies the OpenGL criteria, as 255*255 = 254, - * so the special case a = 255 must be accounted or roundoff must be used - */ -#define GMB_MULT_GS( MP1, MA1, MP2, MA2 ) \ - PMULLW ( MP1, MA1 ) /* t1 = p1*a1 */ ;\ -TWO(PMULLW ( MP2, MA2 )) /* t2 = p2*a2 */ ;\ - ;\ - MOVQ ( MA1, MP1 ) ;\ - PSRLW ( CONST(8), MA1 ) /* t1 >> 8 */ ;\ - ;\ -TWO(MOVQ ( MA2, MP2 )) ;\ -TWO(PSRLW ( CONST(8), MA2 )) /* t2 >> 8 */ ;\ - ;\ - PADDW ( MP1, MA1 ) /* t1 + (t1 >> 8) ~= (t1/255) << 8 */ ;\ - PSRLW ( CONST(8), MA1 ) /* sa1 | sb1 | sg1 | sr1 */ ;\ - ;\ -TWO(PADDW ( MP2, MA2 )) /* t2 + (t2 >> 8) ~= (t2/255) << 8 */ ;\ -TWO(PSRLW ( CONST(8), MA2 )) /* sa2 | sb2 | sg2 | sr2 */ - - -/* integer multiplication - geometric series plus rounding - * - * when using a geometric series division instead of truncating the result - * use roundoff in the approximation (Jim Blinn) - * - * t = rgb*a + 0x80 - * - * achieving the exact results - * - * note that M80 is register with the 0x0080008000800080 constant - */ -#define GMB_MULT_GSR( MP1, MA1, MP2, MA2, M80 ) \ - PMULLW ( MP1, MA1 ) /* t1 = p1*a1 */ ;\ - PADDW ( M80, MA1 ) /* t1 += 0x80 */ ;\ - ;\ -TWO(PMULLW ( MP2, MA2 )) /* t2 = p2*a2 */ ;\ -TWO(PADDW ( M80, MA2 )) /* t2 += 0x80 */ ;\ - ;\ - MOVQ ( MA1, MP1 ) ;\ - PSRLW ( CONST(8), MA1 ) /* t1 >> 8 */ ;\ - ;\ -TWO(MOVQ ( MA2, MP2 )) ;\ -TWO(PSRLW ( CONST(8), MA2 )) /* t2 >> 8 */ ;\ - ;\ - PADDW ( MP1, MA1 ) /* t1 + (t1 >> 8) ~= (t1/255) << 8 */ ;\ - PSRLW ( CONST(8), MA1 ) /* sa1 | sb1 | sg1 | sr1 */ ;\ - ;\ -TWO(PADDW ( MP2, MA2 )) /* t2 + (t2 >> 8) ~= (t2/255) << 8 */ ;\ -TWO(PSRLW ( CONST(8), MA2 )) /* sa2 | sb2 | sg2 | sr2 */ - - -/* linear interpolation - geometric series - */ -#define GMB_LERP_GS( MP1, MQ1, MA1, MP2, MQ2, MA2) \ - PSUBW ( MQ1, MP1 ) /* pa1 - qa1 | pb1 - qb1 | pg1 - qg1 | pr1 - qr1 */ ;\ - PSLLW ( CONST(8), MQ1 ) /* q1 << 8 */ ;\ - PMULLW ( MP1, MA1 ) /* t1 = (q1 - p1)*pa1 */ ;\ - ;\ -TWO(PSUBW ( MQ2, MP2 )) /* pa2 - qa2 | pb2 - qb2 | pg2 - qg2 | pr2 - qr2 */ ;\ -TWO(PSLLW ( CONST(8), MQ2 )) /* q2 << 8 */ ;\ -TWO(PMULLW ( MP2, MA2 )) /* t2 = (q2 - p2)*pa2 */ ;\ - ;\ - MOVQ ( MA1, MP1 ) ;\ - PSRLW ( CONST(8), MA1 ) /* t1 >> 8 */ ;\ - ;\ -TWO(MOVQ ( MA2, MP2 )) ;\ -TWO(PSRLW ( CONST(8), MA2 )) /* t2 >> 8 */ ;\ - ;\ - PADDW ( MP1, MA1 ) /* t1 + (t1 >> 8) ~= (t1/255) << 8 */ ;\ -TWO(PADDW ( MP2, MA2 )) /* t2 + (t2 >> 8) ~= (t2/255) << 8 */ ;\ - ;\ - PADDW ( MQ1, MA1 ) /* (t1/255 + q1) << 8 */ ;\ -TWO(PADDW ( MQ2, MA2 )) /* (t2/255 + q2) << 8 */ ;\ - ;\ - PSRLW ( CONST(8), MA1 ) /* sa1 | sb1 | sg1 | sr1 */ ;\ -TWO(PSRLW ( CONST(8), MA2 )) /* sa2 | sb2 | sg2 | sr2 */ - - -/* linear interpolation - geometric series with roundoff - * - * this is a generalization of Blinn's formula to signed arithmetic - * - * note that M80 is a register with the 0x0080008000800080 constant - */ -#define GMB_LERP_GSR( MP1, MQ1, MA1, MP2, MQ2, MA2, M80) \ - PSUBW ( MQ1, MP1 ) /* pa1 - qa1 | pb1 - qb1 | pg1 - qg1 | pr1 - qr1 */ ;\ - PSLLW ( CONST(8), MQ1 ) /* q1 << 8 */ ;\ - PMULLW ( MP1, MA1 ) /* t1 = (q1 - p1)*pa1 */ ;\ - ;\ -TWO(PSUBW ( MQ2, MP2 )) /* pa2 - qa2 | pb2 - qb2 | pg2 - qg2 | pr2 - qr2 */ ;\ -TWO(PSLLW ( CONST(8), MQ2 )) /* q2 << 8 */ ;\ -TWO(PMULLW ( MP2, MA2 )) /* t2 = (q2 - p2)*pa2 */ ;\ - ;\ - PSRLW ( CONST(15), MP1 ) /* q1 > p1 ? 1 : 0 */ ;\ -TWO(PSRLW ( CONST(15), MP2 )) /* q2 > q2 ? 1 : 0 */ ;\ - ;\ - PSLLW ( CONST(8), MP1 ) /* q1 > p1 ? 0x100 : 0 */ ;\ -TWO(PSLLW ( CONST(8), MP2 )) /* q2 > q2 ? 0x100 : 0 */ ;\ - ;\ - PSUBW ( MP1, MA1 ) /* t1 -=? 0x100 */ ;\ -TWO(PSUBW ( MP2, MA2 )) /* t2 -=? 0x100 */ ;\ - ;\ - PADDW ( M80, MA1 ) /* t1 += 0x80 */ ;\ -TWO(PADDW ( M80, MA2 )) /* t2 += 0x80 */ ;\ - ;\ - MOVQ ( MA1, MP1 ) ;\ - PSRLW ( CONST(8), MA1 ) /* t1 >> 8 */ ;\ - ;\ -TWO(MOVQ ( MA2, MP2 )) ;\ -TWO(PSRLW ( CONST(8), MA2 )) /* t2 >> 8 */ ;\ - ;\ - PADDW ( MP1, MA1 ) /* t1 + (t1 >> 8) ~= (t1/255) << 8 */ ;\ -TWO(PADDW ( MP2, MA2 )) /* t2 + (t2 >> 8) ~= (t2/255) << 8 */ ;\ - ;\ - PADDW ( MQ1, MA1 ) /* (t1/255 + q1) << 8 */ ;\ -TWO(PADDW ( MQ2, MA2 )) /* (t2/255 + q2) << 8 */ ;\ - ;\ - PSRLW ( CONST(8), MA1 ) /* sa1 | sb1 | sg1 | sr1 */ ;\ -TWO(PSRLW ( CONST(8), MA2 )) /* sa2 | sb2 | sg2 | sr2 */ - - -/* linear interpolation - geometric series with correction - * - * instead of the roundoff this adds a small correction to satisfy the OpenGL criteria - * - * t/255 ~= (t + (t >> 8) + (t >> 15)) >> 8 - * - * note that although is faster than rounding off it doesn't give always the exact results - */ -#define GMB_LERP_GSC( MP1, MQ1, MA1, MP2, MQ2, MA2) \ - PSUBW ( MQ1, MP1 ) /* pa1 - qa1 | pb1 - qb1 | pg1 - qg1 | pr1 - qr1 */ ;\ - PSLLW ( CONST(8), MQ1 ) /* q1 << 8 */ ;\ - PMULLW ( MP1, MA1 ) /* t1 = (q1 - p1)*pa1 */ ;\ - ;\ -TWO(PSUBW ( MQ2, MP2 )) /* pa2 - qa2 | pb2 - qb2 | pg2 - qg2 | pr2 - qr2 */ ;\ -TWO(PSLLW ( CONST(8), MQ2 )) /* q2 << 8 */ ;\ -TWO(PMULLW ( MP2, MA2 )) /* t2 = (q2 - p2)*pa2 */ ;\ - ;\ - MOVQ ( MA1, MP1 ) ;\ - PSRLW ( CONST(8), MA1 ) /* t1 >> 8 */ ;\ - ;\ -TWO(MOVQ ( MA2, MP2 )) ;\ -TWO(PSRLW ( CONST(8), MA2 )) /* t2 >> 8 */ ;\ - ;\ - PADDW ( MA1, MP1 ) /* t1 + (t1 >> 8) ~= (t1/255) << 8 */ ;\ - PSRLW ( CONST(7), MA1 ) /* t1 >> 15 */ ;\ - ;\ -TWO(PADDW ( MA2, MP2 )) /* t2 + (t2 >> 8) ~= (t2/255) << 8 */ ;\ -TWO(PSRLW ( CONST(7), MA2 )) /* t2 >> 15 */ ;\ - ;\ - PADDW ( MP1, MA1 ) /* t1 + (t1 >> 8) + (t1 >>15) ~= (t1/255) << 8 */ ;\ -TWO(PADDW ( MP2, MA2 )) /* t2 + (t2 >> 8) + (t2 >>15) ~= (t2/255) << 8 */ ;\ - ;\ - PADDW ( MQ1, MA1 ) /* (t1/255 + q1) << 8 */ ;\ -TWO(PADDW ( MQ2, MA2 )) /* (t2/255 + q2) << 8 */ ;\ - ;\ - PSRLW ( CONST(8), MA1 ) /* sa1 | sb1 | sg1 | sr1 */ ;\ -TWO(PSRLW ( CONST(8), MA2 )) /* sa2 | sb2 | sg2 | sr2 */ - - -/* common blending setup code - * - * note that M00 is a register with 0x0000000000000000 constant which can be easily obtained making - * - * PXOR ( M00, M00 ) - */ -#define GMB_LOAD(rgba, dest, MPP, MQQ) \ -ONE(MOVD ( REGIND(rgba), MPP )) /* | | | | qa1 | qb1 | qg1 | qr1 */ ;\ -ONE(MOVD ( REGIND(dest), MQQ )) /* | | | | pa1 | pb1 | pg1 | pr1 */ ;\ - ;\ -TWO(MOVQ ( REGIND(rgba), MPP )) /* qa2 | qb2 | qg2 | qr2 | qa1 | qb1 | qg1 | qr1 */ ;\ -TWO(MOVQ ( REGIND(dest), MQQ )) /* pa2 | pb2 | pg2 | pr2 | pa1 | pb1 | pg1 | pr1 */ - -#define GMB_UNPACK(MP1, MQ1, MP2, MQ2, M00) \ -TWO(MOVQ ( MP1, MP2 )) ;\ -TWO(MOVQ ( MQ1, MQ2 )) ;\ - ;\ - PUNPCKLBW ( M00, MQ1 ) /* qa1 | qb1 | qg1 | qr1 */ ;\ -TWO(PUNPCKHBW ( M00, MQ2 )) /* qa2 | qb2 | qg2 | qr2 */ ;\ - PUNPCKLBW ( M00, MP1 ) /* pa1 | pb1 | pg1 | pr1 */ ;\ -TWO(PUNPCKHBW ( M00, MP2 )) /* pa2 | pb2 | pg2 | pr2 */ - -#define GMB_ALPHA(MP1, MA1, MP2, MA2) \ - MOVQ ( MP1, MA1 ) ;\ -TWO(MOVQ ( MP2, MA2 )) ;\ - ;\ - PUNPCKHWD ( MA1, MA1 ) /* pa1 | pa1 | | */ ;\ -TWO(PUNPCKHWD ( MA2, MA2 )) /* pa2 | pa2 | | */ ;\ - PUNPCKHDQ ( MA1, MA1 ) /* pa1 | pa1 | pa1 | pa1 */ ;\ -TWO(PUNPCKHDQ ( MA2, MA2 )) /* pa2 | pa2 | pa2 | pa2 */ - -#define GMB_PACK( MS1, MS2 ) \ - PACKUSWB ( MS2, MS1 ) /* sa2 | sb2 | sg2 | sr2 | sa1 | sb1 | sg1 | sr1 */ ; - -#define GMB_STORE(rgba, MSS ) \ -ONE(MOVD ( MSS, REGIND(rgba) )) /* | | | | sa1 | sb1 | sg1 | sr1 */ ;\ -TWO(MOVQ ( MSS, REGIND(rgba) )) /* sa2 | sb2 | sg2 | sr2 | sa1 | sb1 | sg1 | sr1 */ - -/* Kevin F. Quinn 2 July 2006 - * Replace data segment constants with text-segment - * constants (via pushl/movq) - SEG_DATA - -ALIGNDATA8 -const_0080: - D_LONG 0x00800080, 0x00800080 - -const_80: - D_LONG 0x80808080, 0x80808080 -*/ -#define const_0080_l 0x00800080 -#define const_0080_h 0x00800080 -#define const_80_l 0x80808080 -#define const_80_h 0x80808080 - - SEG_TEXT - - -/* Blend transparency function - */ - -#define TAG(x) CONCAT(x,_transparency) -#define LLTAG(x) LLBL2(x,_transparency) - -#define INIT \ - PXOR ( MM0, MM0 ) /* 0x0000 | 0x0000 | 0x0000 | 0x0000 */ - -#define MAIN( rgba, dest ) \ - GMB_LOAD( rgba, dest, MM1, MM2 ) ;\ - GMB_UNPACK( MM1, MM2, MM4, MM5, MM0 ) ;\ - GMB_ALPHA( MM1, MM3, MM4, MM6 ) ;\ - GMB_LERP_GSC( MM1, MM2, MM3, MM4, MM5, MM6 ) ;\ - GMB_PACK( MM3, MM6 ) ;\ - GMB_STORE( rgba, MM3 ) - -#include "mmx_blendtmp.h" - - -/* Blend add function - * - * FIXME: Add some loop unrolling here... - */ - -#define TAG(x) CONCAT(x,_add) -#define LLTAG(x) LLBL2(x,_add) - -#define INIT - -#define MAIN( rgba, dest ) \ -ONE(MOVD ( REGIND(rgba), MM1 )) /* | | | | qa1 | qb1 | qg1 | qr1 */ ;\ -ONE(MOVD ( REGIND(dest), MM2 )) /* | | | | pa1 | pb1 | pg1 | pr1 */ ;\ -ONE(PADDUSB ( MM2, MM1 )) ;\ -ONE(MOVD ( MM1, REGIND(rgba) )) /* | | | | sa1 | sb1 | sg1 | sr1 */ ;\ - ;\ -TWO(MOVQ ( REGIND(rgba), MM1 )) /* qa2 | qb2 | qg2 | qr2 | qa1 | qb1 | qg1 | qr1 */ ;\ -TWO(PADDUSB ( REGIND(dest), MM1 )) /* sa2 | sb2 | sg2 | sr2 | sa1 | sb1 | sg1 | sr1 */ ;\ -TWO(MOVQ ( MM1, REGIND(rgba) )) - -#include "mmx_blendtmp.h" - - -/* Blend min function - */ - -#define TAG(x) CONCAT(x,_min) -#define LLTAG(x) LLBL2(x,_min) - -/* Kevin F. Quinn 2nd July 2006 - * Replace data segment constants with text-segment instructions -#define INIT \ - MOVQ ( CONTENT(const_80), MM7 ) - */ -#define INIT \ - PUSH_L ( CONST(const_80_h) ) /* 0x80| 0x80| 0x80| 0x80| 0x80| 0x80| 0x80| 0x80*/ ;\ - PUSH_L ( CONST(const_80_l) ) ;\ - MOVQ ( REGIND(ESP), MM7 ) ;\ - ADD_L ( CONST(8), ESP) - -#define MAIN( rgba, dest ) \ - GMB_LOAD( rgba, dest, MM1, MM2 ) ;\ - MOVQ ( MM1, MM3 ) ;\ - MOVQ ( MM2, MM4 ) ;\ - PXOR ( MM7, MM3 ) /* unsigned -> signed */ ;\ - PXOR ( MM7, MM4 ) /* unsigned -> signed */ ;\ - PCMPGTB ( MM3, MM4 ) /* q > p ? 0xff : 0x00 */ ;\ - PAND ( MM4, MM1 ) /* q > p ? p : 0 */ ;\ - PANDN ( MM2, MM4 ) /* q > p ? 0 : q */ ;\ - POR ( MM1, MM4 ) /* q > p ? p : q */ ;\ - GMB_STORE( rgba, MM4 ) - -#include "mmx_blendtmp.h" - - -/* Blend max function - */ - -#define TAG(x) CONCAT(x,_max) -#define LLTAG(x) LLBL2(x,_max) - -/* Kevin F. Quinn 2nd July 2006 - * Replace data segment constants with text-segment instructions -#define INIT \ - MOVQ ( CONTENT(const_80), MM7 ) - */ -#define INIT \ - PUSH_L ( CONST(const_80_l) ) /* 0x80| 0x80| 0x80| 0x80| 0x80| 0x80| 0x80| 0x80*/ ;\ - PUSH_L ( CONST(const_80_h) ) ;\ - MOVQ ( REGIND(ESP), MM7 ) ;\ - ADD_L ( CONST(8), ESP) - -#define MAIN( rgba, dest ) \ - GMB_LOAD( rgba, dest, MM1, MM2 ) ;\ - MOVQ ( MM1, MM3 ) ;\ - MOVQ ( MM2, MM4 ) ;\ - PXOR ( MM7, MM3 ) /* unsigned -> signed */ ;\ - PXOR ( MM7, MM4 ) /* unsigned -> signed */ ;\ - PCMPGTB ( MM3, MM4 ) /* q > p ? 0xff : 0x00 */ ;\ - PAND ( MM4, MM2 ) /* q > p ? q : 0 */ ;\ - PANDN ( MM1, MM4 ) /* q > p ? 0 : p */ ;\ - POR ( MM2, MM4 ) /* q > p ? p : q */ ;\ - GMB_STORE( rgba, MM4 ) - -#include "mmx_blendtmp.h" - - -/* Blend modulate function - */ - -#define TAG(x) CONCAT(x,_modulate) -#define LLTAG(x) LLBL2(x,_modulate) - -/* Kevin F. Quinn 2nd July 2006 - * Replace data segment constants with text-segment instructions -#define INIT \ - MOVQ ( CONTENT(const_0080), MM7 ) - */ -#define INIT \ - PXOR ( MM0, MM0 ) /* 0x0000 | 0x0000 | 0x0000 | 0x0000 */ ;\ - PUSH_L ( CONST(const_0080_l) ) /* 0x0080 | 0x0080 | 0x0080 | 0x0080 */ ;\ - PUSH_L ( CONST(const_0080_h) ) ;\ - MOVQ ( REGIND(ESP), MM7 ) ;\ - ADD_L ( CONST(8), ESP) - -#define MAIN( rgba, dest ) \ - GMB_LOAD( rgba, dest, MM1, MM2 ) ;\ - GMB_UNPACK( MM1, MM2, MM4, MM5, MM0 ) ;\ - GMB_MULT_GSR( MM1, MM2, MM4, MM5, MM7 ) ;\ - GMB_PACK( MM2, MM5 ) ;\ - GMB_STORE( rgba, MM2 ) - -#include "mmx_blendtmp.h" - -#endif - -#if defined (__ELF__) && defined (__linux__) - .section .note.GNU-stack,"",%progbits -#endif diff --git a/src/mesa/x86/mmx_blendtmp.h b/src/mesa/x86/mmx_blendtmp.h deleted file mode 100644 index 05d5f61..0000000 --- a/src/mesa/x86/mmx_blendtmp.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Written by José Fonseca - */ - - -/* - * void _mesa_mmx_blend( struct gl_context *ctx, - * GLuint n, - * const GLubyte mask[], - * GLchan rgba[][4], - * CONST GLchan dest[][4] ) - * - */ -ALIGNTEXT16 -GLOBL GLNAME( TAG(_mesa_mmx_blend) ) -HIDDEN( TAG(_mesa_mmx_blend) ) -GLNAME( TAG(_mesa_mmx_blend) ): - _CET_ENDBR - PUSH_L ( EBP ) - MOV_L ( ESP, EBP ) - PUSH_L ( ESI ) - PUSH_L ( EDI ) - PUSH_L ( EBX ) - - MOV_L ( REGOFF(12, EBP), ECX ) /* n */ - CMP_L ( CONST(0), ECX) - JE ( LLTAG(GMB_return) ) - - MOV_L ( REGOFF(16, EBP), EBX ) /* mask */ - MOV_L ( REGOFF(20, EBP), EDI ) /* rgba */ - MOV_L ( REGOFF(24, EBP), ESI ) /* dest */ - - INIT - - TEST_L ( CONST(4), EDI ) /* align rgba on an 8-byte boundary */ - JZ ( LLTAG(GMB_align_end) ) - - CMP_B ( CONST(0), REGIND(EBX) ) /* *mask == 0 */ - JE ( LLTAG(GMB_align_continue) ) - - /* runin */ -#define ONE(x) x -#define TWO(x) - MAIN ( EDI, ESI ) -#undef ONE -#undef TWO - -LLTAG(GMB_align_continue): - - DEC_L ( ECX ) /* n -= 1 */ - INC_L ( EBX ) /* mask += 1 */ - ADD_L ( CONST(4), EDI ) /* rgba += 1 */ - ADD_L ( CONST(4), ESI ) /* dest += 1 */ - -LLTAG(GMB_align_end): - - CMP_L ( CONST(2), ECX) - JB ( LLTAG(GMB_loop_end) ) - -ALIGNTEXT16 -LLTAG(GMB_loop_begin): - - CMP_W ( CONST(0), REGIND(EBX) ) /* *mask == 0 && *(mask + 1) == 0 */ - JE ( LLTAG(GMB_loop_continue) ) - - /* main loop */ -#define ONE(x) -#define TWO(x) x - MAIN ( EDI, ESI ) -#undef ONE -#undef TWO - -LLTAG(GMB_loop_continue): - - DEC_L ( ECX ) - DEC_L ( ECX ) /* n -= 2 */ - ADD_L ( CONST(2), EBX ) /* mask += 2 */ - ADD_L ( CONST(8), EDI ) /* rgba += 2 */ - ADD_L ( CONST(8), ESI ) /* dest += 2 */ - CMP_L ( CONST(2), ECX ) - JAE ( LLTAG(GMB_loop_begin) ) - -LLTAG(GMB_loop_end): - - CMP_L ( CONST(1), ECX ) - JB ( LLTAG(GMB_done) ) - - CMP_B ( CONST(0), REGIND(EBX) ) /* *mask == 0 */ - JE ( LLTAG(GMB_done) ) - - /* runout */ -#define ONE(x) x -#define TWO(x) - MAIN ( EDI, ESI ) -#undef ONE -#undef TWO - -LLTAG(GMB_done): - - EMMS - -LLTAG(GMB_return): - - POP_L ( EBX ) - POP_L ( EDI ) - POP_L ( ESI ) - MOV_L ( EBP, ESP ) - POP_L ( EBP ) - RET - -#undef TAG -#undef LLTAG -#undef INIT -#undef MAIN diff --git a/src/mesa/x86/norm_args.h b/src/mesa/x86/norm_args.h deleted file mode 100644 index a85c711..0000000 --- a/src/mesa/x86/norm_args.h +++ /dev/null @@ -1,57 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -/* - * Normal transform function interface for assembly code. Simply define - * FRAME_OFFSET to the number of bytes pushed onto the stack before - * using the ARG_* argument macros. - * - * Gareth Hughes - */ - -#ifndef __NORM_ARGS_H__ -#define __NORM_ARGS_H__ - -/* Offsets for normal_func arguments - * - * typedef void (*normal_func)( const GLmatrix *mat, - * GLfloat scale, - * const GLvector4f *in, - * const GLfloat lengths[], - * GLvector4f *dest ); - */ -#define OFFSET_MAT 4 -#define OFFSET_SCALE 8 -#define OFFSET_IN 12 -#define OFFSET_LENGTHS 16 -#define OFFSET_DEST 20 - -#define ARG_MAT REGOFF(FRAME_OFFSET+OFFSET_MAT, ESP) -#define ARG_SCALE REGOFF(FRAME_OFFSET+OFFSET_SCALE, ESP) -#define ARG_IN REGOFF(FRAME_OFFSET+OFFSET_IN, ESP) -#define ARG_LENGTHS REGOFF(FRAME_OFFSET+OFFSET_LENGTHS, ESP) -#define ARG_DEST REGOFF(FRAME_OFFSET+OFFSET_DEST, ESP) - -#endif diff --git a/src/mesa/x86/rtasm/x86sse.c b/src/mesa/x86/rtasm/x86sse.c deleted file mode 100644 index 0d3242f..0000000 --- a/src/mesa/x86/rtasm/x86sse.c +++ /dev/null @@ -1,1207 +0,0 @@ -#ifdef USE_X86_ASM -#if defined(__i386__) || defined(__386__) - -#include -#include -#include - -#include "main/execmem.h" -#include "x86sse.h" - -#define DISASSEM 0 -#define X86_TWOB 0x0f - -#if 0 -static unsigned char *cptr( void (*label)() ) -{ - return (unsigned char *)(unsigned long)label; -} -#endif - - -static void do_realloc( struct x86_function *p ) -{ - if (p->size == 0) { - p->size = 1024; - p->store = _mesa_exec_malloc(p->size); - p->csr = p->store; - } - else { - unsigned used = p->csr - p->store; - unsigned char *tmp = p->store; - p->size *= 2; - p->store = _mesa_exec_malloc(p->size); - memcpy(p->store, tmp, used); - p->csr = p->store + used; - _mesa_exec_free(tmp); - } -} - -/* Emit bytes to the instruction stream: - */ -static unsigned char *reserve( struct x86_function *p, int bytes ) -{ - if (p->csr + bytes - p->store > p->size) - do_realloc(p); - - { - unsigned char *csr = p->csr; - p->csr += bytes; - return csr; - } -} - - - -static void emit_1b( struct x86_function *p, char b0 ) -{ - char *csr = (char *)reserve(p, 1); - *csr = b0; -} - -static void emit_1i( struct x86_function *p, int i0 ) -{ - int *icsr = (int *)reserve(p, sizeof(i0)); - *icsr = i0; -} - -static void emit_1ub( struct x86_function *p, unsigned char b0 ) -{ - unsigned char *csr = reserve(p, 1); - *csr++ = b0; -} - -static void emit_2ub( struct x86_function *p, unsigned char b0, unsigned char b1 ) -{ - unsigned char *csr = reserve(p, 2); - *csr++ = b0; - *csr++ = b1; -} - -static void emit_3ub( struct x86_function *p, unsigned char b0, unsigned char b1, unsigned char b2 ) -{ - unsigned char *csr = reserve(p, 3); - *csr++ = b0; - *csr++ = b1; - *csr++ = b2; -} - - -/* Build a modRM byte + possible displacement. No treatment of SIB - * indexing. BZZT - no way to encode an absolute address. - */ -static void emit_modrm( struct x86_function *p, - struct x86_reg reg, - struct x86_reg regmem ) -{ - unsigned char val = 0; - - assert(reg.mod == mod_REG); - - val |= regmem.mod << 6; /* mod field */ - val |= reg.idx << 3; /* reg field */ - val |= regmem.idx; /* r/m field */ - - emit_1ub(p, val); - - /* Oh-oh we've stumbled into the SIB thing. - */ - if (regmem.file == file_REG32 && - regmem.idx == reg_SP) { - emit_1ub(p, 0x24); /* simplistic! */ - } - - switch (regmem.mod) { - case mod_REG: - case mod_INDIRECT: - break; - case mod_DISP8: - emit_1b(p, regmem.disp); - break; - case mod_DISP32: - emit_1i(p, regmem.disp); - break; - default: - assert(0); - break; - } -} - - -static void emit_modrm_noreg( struct x86_function *p, - unsigned op, - struct x86_reg regmem ) -{ - struct x86_reg dummy = x86_make_reg(file_REG32, op); - emit_modrm(p, dummy, regmem); -} - -/* Many x86 instructions have two opcodes to cope with the situations - * where the destination is a register or memory reference - * respectively. This function selects the correct opcode based on - * the arguments presented. - */ -static void emit_op_modrm( struct x86_function *p, - unsigned char op_dst_is_reg, - unsigned char op_dst_is_mem, - struct x86_reg dst, - struct x86_reg src ) -{ - switch (dst.mod) { - case mod_REG: - emit_1ub(p, op_dst_is_reg); - emit_modrm(p, dst, src); - break; - case mod_INDIRECT: - case mod_DISP32: - case mod_DISP8: - assert(src.mod == mod_REG); - emit_1ub(p, op_dst_is_mem); - emit_modrm(p, src, dst); - break; - default: - assert(0); - break; - } -} - - - - - - - -/* Create and manipulate registers and regmem values: - */ -struct x86_reg x86_make_reg( enum x86_reg_file file, - enum x86_reg_name idx ) -{ - struct x86_reg reg; - - reg.file = file; - reg.idx = idx; - reg.mod = mod_REG; - reg.disp = 0; - - return reg; -} - -struct x86_reg x86_make_disp( struct x86_reg reg, - int disp ) -{ - assert(reg.file == file_REG32); - - if (reg.mod == mod_REG) - reg.disp = disp; - else - reg.disp += disp; - - if (reg.disp == 0) - reg.mod = mod_INDIRECT; - else if (reg.disp <= 127 && reg.disp >= -128) - reg.mod = mod_DISP8; - else - reg.mod = mod_DISP32; - - return reg; -} - -struct x86_reg x86_deref( struct x86_reg reg ) -{ - return x86_make_disp(reg, 0); -} - -struct x86_reg x86_get_base_reg( struct x86_reg reg ) -{ - return x86_make_reg( reg.file, reg.idx ); -} - -unsigned char *x86_get_label( struct x86_function *p ) -{ - return p->csr; -} - - - -/*********************************************************************** - * x86 instructions - */ - - -void x86_jcc( struct x86_function *p, - enum x86_cc cc, - unsigned char *label ) -{ - int offset = label - (x86_get_label(p) + 2); - - if (offset <= 127 && offset >= -128) { - emit_1ub(p, 0x70 + cc); - emit_1b(p, (char) offset); - } - else { - offset = label - (x86_get_label(p) + 6); - emit_2ub(p, 0x0f, 0x80 + cc); - emit_1i(p, offset); - } -} - -/* Always use a 32bit offset for forward jumps: - */ -unsigned char *x86_jcc_forward( struct x86_function *p, - enum x86_cc cc ) -{ - emit_2ub(p, 0x0f, 0x80 + cc); - emit_1i(p, 0); - return x86_get_label(p); -} - -unsigned char *x86_jmp_forward( struct x86_function *p) -{ - emit_1ub(p, 0xe9); - emit_1i(p, 0); - return x86_get_label(p); -} - -unsigned char *x86_call_forward( struct x86_function *p) -{ - emit_1ub(p, 0xe8); - emit_1i(p, 0); - return x86_get_label(p); -} - -/* Fixup offset from forward jump: - */ -void x86_fixup_fwd_jump( struct x86_function *p, - unsigned char *fixup ) -{ - *(int *)(fixup - 4) = x86_get_label(p) - fixup; -} - -void x86_jmp( struct x86_function *p, unsigned char *label) -{ - emit_1ub(p, 0xe9); - emit_1i(p, label - x86_get_label(p) - 4); -} - -#if 0 -/* This doesn't work once we start reallocating & copying the - * generated code on buffer fills, because the call is relative to the - * current pc. - */ -void x86_call( struct x86_function *p, void (*label)()) -{ - emit_1ub(p, 0xe8); - emit_1i(p, cptr(label) - x86_get_label(p) - 4); -} -#else -void x86_call( struct x86_function *p, struct x86_reg reg) -{ - emit_1ub(p, 0xff); - emit_modrm_noreg(p, 2, reg); -} -#endif - - -/* michal: - * Temporary. As I need immediate operands, and dont want to mess with the codegen, - * I load the immediate into general purpose register and use it. - */ -void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, int imm ) -{ - assert(dst.mod == mod_REG); - emit_1ub(p, 0xb8 + dst.idx); - emit_1i(p, imm); -} - -void x86_push( struct x86_function *p, - struct x86_reg reg ) -{ - assert(reg.mod == mod_REG); - emit_1ub(p, 0x50 + reg.idx); - p->stack_offset += 4; -} - -void x86_pop( struct x86_function *p, - struct x86_reg reg ) -{ - assert(reg.mod == mod_REG); - emit_1ub(p, 0x58 + reg.idx); - p->stack_offset -= 4; -} - -void x86_inc( struct x86_function *p, - struct x86_reg reg ) -{ - assert(reg.mod == mod_REG); - emit_1ub(p, 0x40 + reg.idx); -} - -void x86_dec( struct x86_function *p, - struct x86_reg reg ) -{ - assert(reg.mod == mod_REG); - emit_1ub(p, 0x48 + reg.idx); -} - -void x86_ret( struct x86_function *p ) -{ - emit_1ub(p, 0xc3); -} - -void x86_sahf( struct x86_function *p ) -{ - emit_1ub(p, 0x9e); -} - -void x86_mov( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_op_modrm( p, 0x8b, 0x89, dst, src ); -} - -void x86_xor( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_op_modrm( p, 0x33, 0x31, dst, src ); -} - -void x86_cmp( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_op_modrm( p, 0x3b, 0x39, dst, src ); -} - -void x86_lea( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_1ub(p, 0x8d); - emit_modrm( p, dst, src ); -} - -void x86_test( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_1ub(p, 0x85); - emit_modrm( p, dst, src ); -} - -void x86_add( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_op_modrm(p, 0x03, 0x01, dst, src ); -} - -void x86_mul( struct x86_function *p, - struct x86_reg src ) -{ - assert (src.file == file_REG32 && src.mod == mod_REG); - emit_op_modrm(p, 0xf7, 0, x86_make_reg (file_REG32, reg_SP), src ); -} - -void x86_sub( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_op_modrm(p, 0x2b, 0x29, dst, src ); -} - -void x86_or( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_op_modrm( p, 0x0b, 0x09, dst, src ); -} - -void x86_and( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_op_modrm( p, 0x23, 0x21, dst, src ); -} - - - -/*********************************************************************** - * SSE instructions - */ - - -void sse_movss( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, 0xF3, X86_TWOB); - emit_op_modrm( p, 0x10, 0x11, dst, src ); -} - -void sse_movaps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_1ub(p, X86_TWOB); - emit_op_modrm( p, 0x28, 0x29, dst, src ); -} - -void sse_movups( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_1ub(p, X86_TWOB); - emit_op_modrm( p, 0x10, 0x11, dst, src ); -} - -void sse_movhps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - assert(dst.mod != mod_REG || src.mod != mod_REG); - emit_1ub(p, X86_TWOB); - emit_op_modrm( p, 0x16, 0x17, dst, src ); /* cf movlhps */ -} - -void sse_movlps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - assert(dst.mod != mod_REG || src.mod != mod_REG); - emit_1ub(p, X86_TWOB); - emit_op_modrm( p, 0x12, 0x13, dst, src ); /* cf movhlps */ -} - -void sse_maxps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x5F); - emit_modrm( p, dst, src ); -} - -void sse_maxss( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0xF3, X86_TWOB, 0x5F); - emit_modrm( p, dst, src ); -} - -void sse_divss( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0xF3, X86_TWOB, 0x5E); - emit_modrm( p, dst, src ); -} - -void sse_minps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x5D); - emit_modrm( p, dst, src ); -} - -void sse_subps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x5C); - emit_modrm( p, dst, src ); -} - -void sse_mulps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x59); - emit_modrm( p, dst, src ); -} - -void sse_mulss( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0xF3, X86_TWOB, 0x59); - emit_modrm( p, dst, src ); -} - -void sse_addps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x58); - emit_modrm( p, dst, src ); -} - -void sse_addss( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0xF3, X86_TWOB, 0x58); - emit_modrm( p, dst, src ); -} - -void sse_andnps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x55); - emit_modrm( p, dst, src ); -} - -void sse_andps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x54); - emit_modrm( p, dst, src ); -} - -void sse_rsqrtps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x52); - emit_modrm( p, dst, src ); -} - -void sse_rsqrtss( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0xF3, X86_TWOB, 0x52); - emit_modrm( p, dst, src ); - -} - -void sse_movhlps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - assert(dst.mod == mod_REG && src.mod == mod_REG); - emit_2ub(p, X86_TWOB, 0x12); - emit_modrm( p, dst, src ); -} - -void sse_movlhps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - assert(dst.mod == mod_REG && src.mod == mod_REG); - emit_2ub(p, X86_TWOB, 0x16); - emit_modrm( p, dst, src ); -} - -void sse_orps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x56); - emit_modrm( p, dst, src ); -} - -void sse_xorps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x57); - emit_modrm( p, dst, src ); -} - -void sse_cvtps2pi( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - assert(dst.file == file_MMX && - (src.file == file_XMM || src.mod != mod_REG)); - - p->need_emms = 1; - - emit_2ub(p, X86_TWOB, 0x2d); - emit_modrm( p, dst, src ); -} - - -/* Shufps can also be used to implement a reduced swizzle when dest == - * arg0. - */ -void sse_shufps( struct x86_function *p, - struct x86_reg dest, - struct x86_reg arg0, - unsigned char shuf) -{ - emit_2ub(p, X86_TWOB, 0xC6); - emit_modrm(p, dest, arg0); - emit_1ub(p, shuf); -} - -void sse_cmpps( struct x86_function *p, - struct x86_reg dest, - struct x86_reg arg0, - unsigned char cc) -{ - emit_2ub(p, X86_TWOB, 0xC2); - emit_modrm(p, dest, arg0); - emit_1ub(p, cc); -} - -void sse_pmovmskb( struct x86_function *p, - struct x86_reg dest, - struct x86_reg src) -{ - emit_3ub(p, 0x66, X86_TWOB, 0xD7); - emit_modrm(p, dest, src); -} - -/*********************************************************************** - * SSE2 instructions - */ - -/** - * Perform a reduced swizzle: - */ -void sse2_pshufd( struct x86_function *p, - struct x86_reg dest, - struct x86_reg arg0, - unsigned char shuf) -{ - emit_3ub(p, 0x66, X86_TWOB, 0x70); - emit_modrm(p, dest, arg0); - emit_1ub(p, shuf); -} - -void sse2_cvttps2dq( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub( p, 0xF3, X86_TWOB, 0x5B ); - emit_modrm( p, dst, src ); -} - -void sse2_cvtps2dq( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0x66, X86_TWOB, 0x5B); - emit_modrm( p, dst, src ); -} - -void sse2_packssdw( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0x66, X86_TWOB, 0x6B); - emit_modrm( p, dst, src ); -} - -void sse2_packsswb( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0x66, X86_TWOB, 0x63); - emit_modrm( p, dst, src ); -} - -void sse2_packuswb( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0x66, X86_TWOB, 0x67); - emit_modrm( p, dst, src ); -} - -void sse2_rcpps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x53); - emit_modrm( p, dst, src ); -} - -void sse2_rcpss( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0xF3, X86_TWOB, 0x53); - emit_modrm( p, dst, src ); -} - -void sse2_movd( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, 0x66, X86_TWOB); - emit_op_modrm( p, 0x6e, 0x7e, dst, src ); -} - - - - -/*********************************************************************** - * x87 instructions - */ -void x87_fist( struct x86_function *p, struct x86_reg dst ) -{ - emit_1ub(p, 0xdb); - emit_modrm_noreg(p, 2, dst); -} - -void x87_fistp( struct x86_function *p, struct x86_reg dst ) -{ - emit_1ub(p, 0xdb); - emit_modrm_noreg(p, 3, dst); -} - -void x87_fild( struct x86_function *p, struct x86_reg arg ) -{ - emit_1ub(p, 0xdf); - emit_modrm_noreg(p, 0, arg); -} - -void x87_fldz( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xee); -} - - -void x87_fldcw( struct x86_function *p, struct x86_reg arg ) -{ - assert(arg.file == file_REG32); - assert(arg.mod != mod_REG); - emit_1ub(p, 0xd9); - emit_modrm_noreg(p, 5, arg); -} - -void x87_fld1( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xe8); -} - -void x87_fldl2e( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xea); -} - -void x87_fldln2( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xed); -} - -void x87_fwait( struct x86_function *p ) -{ - emit_1ub(p, 0x9b); -} - -void x87_fnclex( struct x86_function *p ) -{ - emit_2ub(p, 0xdb, 0xe2); -} - -void x87_fclex( struct x86_function *p ) -{ - x87_fwait(p); - x87_fnclex(p); -} - - -static void x87_arith_op( struct x86_function *p, struct x86_reg dst, struct x86_reg arg, - unsigned char dst0ub0, - unsigned char dst0ub1, - unsigned char arg0ub0, - unsigned char arg0ub1, - unsigned char argmem_noreg) -{ - assert(dst.file == file_x87); - - if (arg.file == file_x87) { - if (dst.idx == 0) - emit_2ub(p, dst0ub0, dst0ub1+arg.idx); - else if (arg.idx == 0) - emit_2ub(p, arg0ub0, arg0ub1+arg.idx); - else - assert(0); - } - else if (dst.idx == 0) { - assert(arg.file == file_REG32); - emit_1ub(p, 0xd8); - emit_modrm_noreg(p, argmem_noreg, arg); - } - else - assert(0); -} - -void x87_fmul( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) -{ - x87_arith_op(p, dst, arg, - 0xd8, 0xc8, - 0xdc, 0xc8, - 4); -} - -void x87_fsub( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) -{ - x87_arith_op(p, dst, arg, - 0xd8, 0xe0, - 0xdc, 0xe8, - 4); -} - -void x87_fsubr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) -{ - x87_arith_op(p, dst, arg, - 0xd8, 0xe8, - 0xdc, 0xe0, - 5); -} - -void x87_fadd( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) -{ - x87_arith_op(p, dst, arg, - 0xd8, 0xc0, - 0xdc, 0xc0, - 0); -} - -void x87_fdiv( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) -{ - x87_arith_op(p, dst, arg, - 0xd8, 0xf0, - 0xdc, 0xf8, - 6); -} - -void x87_fdivr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) -{ - x87_arith_op(p, dst, arg, - 0xd8, 0xf8, - 0xdc, 0xf0, - 7); -} - -void x87_fmulp( struct x86_function *p, struct x86_reg dst ) -{ - assert(dst.file == file_x87); - assert(dst.idx >= 1); - emit_2ub(p, 0xde, 0xc8+dst.idx); -} - -void x87_fsubp( struct x86_function *p, struct x86_reg dst ) -{ - assert(dst.file == file_x87); - assert(dst.idx >= 1); - emit_2ub(p, 0xde, 0xe8+dst.idx); -} - -void x87_fsubrp( struct x86_function *p, struct x86_reg dst ) -{ - assert(dst.file == file_x87); - assert(dst.idx >= 1); - emit_2ub(p, 0xde, 0xe0+dst.idx); -} - -void x87_faddp( struct x86_function *p, struct x86_reg dst ) -{ - assert(dst.file == file_x87); - assert(dst.idx >= 1); - emit_2ub(p, 0xde, 0xc0+dst.idx); -} - -void x87_fdivp( struct x86_function *p, struct x86_reg dst ) -{ - assert(dst.file == file_x87); - assert(dst.idx >= 1); - emit_2ub(p, 0xde, 0xf8+dst.idx); -} - -void x87_fdivrp( struct x86_function *p, struct x86_reg dst ) -{ - assert(dst.file == file_x87); - assert(dst.idx >= 1); - emit_2ub(p, 0xde, 0xf0+dst.idx); -} - -void x87_fucom( struct x86_function *p, struct x86_reg arg ) -{ - assert(arg.file == file_x87); - emit_2ub(p, 0xdd, 0xe0+arg.idx); -} - -void x87_fucomp( struct x86_function *p, struct x86_reg arg ) -{ - assert(arg.file == file_x87); - emit_2ub(p, 0xdd, 0xe8+arg.idx); -} - -void x87_fucompp( struct x86_function *p ) -{ - emit_2ub(p, 0xda, 0xe9); -} - -void x87_fxch( struct x86_function *p, struct x86_reg arg ) -{ - assert(arg.file == file_x87); - emit_2ub(p, 0xd9, 0xc8+arg.idx); -} - -void x87_fabs( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xe1); -} - -void x87_fchs( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xe0); -} - -void x87_fcos( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xff); -} - - -void x87_fprndint( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xfc); -} - -void x87_fscale( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xfd); -} - -void x87_fsin( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xfe); -} - -void x87_fsincos( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xfb); -} - -void x87_fsqrt( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xfa); -} - -void x87_fxtract( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xf4); -} - -/* st0 = (2^st0)-1 - * - * Restrictions: -1.0 <= st0 <= 1.0 - */ -void x87_f2xm1( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xf0); -} - -/* st1 = st1 * log2(st0); - * pop_stack; - */ -void x87_fyl2x( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xf1); -} - -/* st1 = st1 * log2(st0 + 1.0); - * pop_stack; - * - * A fast operation, with restrictions: -.29 < st0 < .29 - */ -void x87_fyl2xp1( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xf9); -} - - -void x87_fld( struct x86_function *p, struct x86_reg arg ) -{ - if (arg.file == file_x87) - emit_2ub(p, 0xd9, 0xc0 + arg.idx); - else { - emit_1ub(p, 0xd9); - emit_modrm_noreg(p, 0, arg); - } -} - -void x87_fst( struct x86_function *p, struct x86_reg dst ) -{ - if (dst.file == file_x87) - emit_2ub(p, 0xdd, 0xd0 + dst.idx); - else { - emit_1ub(p, 0xd9); - emit_modrm_noreg(p, 2, dst); - } -} - -void x87_fstp( struct x86_function *p, struct x86_reg dst ) -{ - if (dst.file == file_x87) - emit_2ub(p, 0xdd, 0xd8 + dst.idx); - else { - emit_1ub(p, 0xd9); - emit_modrm_noreg(p, 3, dst); - } -} - -void x87_fcom( struct x86_function *p, struct x86_reg dst ) -{ - if (dst.file == file_x87) - emit_2ub(p, 0xd8, 0xd0 + dst.idx); - else { - emit_1ub(p, 0xd8); - emit_modrm_noreg(p, 2, dst); - } -} - -void x87_fcomp( struct x86_function *p, struct x86_reg dst ) -{ - if (dst.file == file_x87) - emit_2ub(p, 0xd8, 0xd8 + dst.idx); - else { - emit_1ub(p, 0xd8); - emit_modrm_noreg(p, 3, dst); - } -} - - -void x87_fnstsw( struct x86_function *p, struct x86_reg dst ) -{ - assert(dst.file == file_REG32); - - if (dst.idx == reg_AX && - dst.mod == mod_REG) - emit_2ub(p, 0xdf, 0xe0); - else { - emit_1ub(p, 0xdd); - emit_modrm_noreg(p, 7, dst); - } -} - - - - -/*********************************************************************** - * MMX instructions - */ - -void mmx_emms( struct x86_function *p ) -{ - assert(p->need_emms); - emit_2ub(p, 0x0f, 0x77); - p->need_emms = 0; -} - -void mmx_packssdw( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - assert(dst.file == file_MMX && - (src.file == file_MMX || src.mod != mod_REG)); - - p->need_emms = 1; - - emit_2ub(p, X86_TWOB, 0x6b); - emit_modrm( p, dst, src ); -} - -void mmx_packuswb( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - assert(dst.file == file_MMX && - (src.file == file_MMX || src.mod != mod_REG)); - - p->need_emms = 1; - - emit_2ub(p, X86_TWOB, 0x67); - emit_modrm( p, dst, src ); -} - -void mmx_movd( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - p->need_emms = 1; - emit_1ub(p, X86_TWOB); - emit_op_modrm( p, 0x6e, 0x7e, dst, src ); -} - -void mmx_movq( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - p->need_emms = 1; - emit_1ub(p, X86_TWOB); - emit_op_modrm( p, 0x6f, 0x7f, dst, src ); -} - - -/*********************************************************************** - * Helper functions - */ - - -/* Retreive a reference to one of the function arguments, taking into - * account any push/pop activity: - */ -struct x86_reg x86_fn_arg( struct x86_function *p, - unsigned arg ) -{ - return x86_make_disp(x86_make_reg(file_REG32, reg_SP), - p->stack_offset + arg * 4); /* ??? */ -} - - -void x86_init_func( struct x86_function *p ) -{ - p->size = 0; - p->store = NULL; - p->csr = p->store; -} - -int x86_init_func_size( struct x86_function *p, unsigned code_size ) -{ - p->size = code_size; - p->store = _mesa_exec_malloc(code_size); - p->csr = p->store; - return p->store != NULL; -} - -void x86_release_func( struct x86_function *p ) -{ - _mesa_exec_free(p->store); - p->store = NULL; - p->csr = NULL; - p->size = 0; -} - - -void (*x86_get_func( struct x86_function *p ))(void) -{ - if (DISASSEM && p->store) - printf("disassemble %p %p\n", p->store, p->csr); - return (void (*)(void)) (unsigned long) p->store; -} - -#else - -void x86sse_dummy( void ) -{ -} - -#endif - -#else /* USE_X86_ASM */ - -int x86sse_c_dummy_var; /* silence warning */ - -#endif /* USE_X86_ASM */ diff --git a/src/mesa/x86/rtasm/x86sse.h b/src/mesa/x86/rtasm/x86sse.h deleted file mode 100644 index f6282f5..0000000 --- a/src/mesa/x86/rtasm/x86sse.h +++ /dev/null @@ -1,256 +0,0 @@ - -#ifndef _X86SSE_H_ -#define _X86SSE_H_ - -#if defined(__i386__) || defined(__386__) - -/* It is up to the caller to ensure that instructions issued are - * suitable for the host cpu. There are no checks made in this module - * for mmx/sse/sse2 support on the cpu. - */ -struct x86_reg { - unsigned file:3; - unsigned idx:3; - unsigned mod:2; /* mod_REG if this is just a register */ - int disp:24; /* only +/- 23bits of offset - should be enough... */ -}; - -struct x86_function { - unsigned size; - unsigned char *store; - unsigned char *csr; - unsigned stack_offset; - int need_emms; - const char *fn; -}; - -enum x86_reg_file { - file_REG32, - file_MMX, - file_XMM, - file_x87 -}; - -/* Values for mod field of modr/m byte - */ -enum x86_reg_mod { - mod_INDIRECT, - mod_DISP8, - mod_DISP32, - mod_REG -}; - -enum x86_reg_name { - reg_AX, - reg_CX, - reg_DX, - reg_BX, - reg_SP, - reg_BP, - reg_SI, - reg_DI -}; - - -enum x86_cc { - cc_O, /* overflow */ - cc_NO, /* not overflow */ - cc_NAE, /* not above or equal / carry */ - cc_AE, /* above or equal / not carry */ - cc_E, /* equal / zero */ - cc_NE /* not equal / not zero */ -}; - -enum sse_cc { - cc_Equal, - cc_LessThan, - cc_LessThanEqual, - cc_Unordered, - cc_NotEqual, - cc_NotLessThan, - cc_NotLessThanEqual, - cc_Ordered -}; - -#define cc_Z cc_E -#define cc_NZ cc_NE - -/* Begin/end/retreive function creation: - */ - - -void x86_init_func( struct x86_function *p ); -int x86_init_func_size( struct x86_function *p, unsigned code_size ); -void x86_release_func( struct x86_function *p ); -void (*x86_get_func( struct x86_function *p ))( void ); - - - -/* Create and manipulate registers and regmem values: - */ -struct x86_reg x86_make_reg( enum x86_reg_file file, - enum x86_reg_name idx ); - -struct x86_reg x86_make_disp( struct x86_reg reg, - int disp ); - -struct x86_reg x86_deref( struct x86_reg reg ); - -struct x86_reg x86_get_base_reg( struct x86_reg reg ); - - -/* Labels, jumps and fixup: - */ -unsigned char *x86_get_label( struct x86_function *p ); - -void x86_jcc( struct x86_function *p, - enum x86_cc cc, - unsigned char *label ); - -unsigned char *x86_jcc_forward( struct x86_function *p, - enum x86_cc cc ); - -unsigned char *x86_jmp_forward( struct x86_function *p); - -unsigned char *x86_call_forward( struct x86_function *p); - -void x86_fixup_fwd_jump( struct x86_function *p, - unsigned char *fixup ); - -void x86_jmp( struct x86_function *p, unsigned char *label ); - -/* void x86_call( struct x86_function *p, void (*label)() ); */ -void x86_call( struct x86_function *p, struct x86_reg reg); - -/* michal: - * Temporary. As I need immediate operands, and dont want to mess with the codegen, - * I load the immediate into general purpose register and use it. - */ -void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, int imm ); - - -/* Macro for sse_shufps() and sse2_pshufd(): - */ -#define SHUF(_x,_y,_z,_w) (((_x)<<0) | ((_y)<<2) | ((_z)<<4) | ((_w)<<6)) -#define SHUF_NOOP RSW(0,1,2,3) -#define GET_SHUF(swz, idx) (((swz) >> ((idx)*2)) & 0x3) - -void mmx_emms( struct x86_function *p ); -void mmx_movd( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void mmx_movq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void mmx_packssdw( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void mmx_packuswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); - -void sse2_cvtps2dq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse2_cvttps2dq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse2_movd( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse2_packssdw( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse2_packsswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse2_packuswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse2_pshufd( struct x86_function *p, struct x86_reg dest, struct x86_reg arg0, - unsigned char shuf ); -void sse2_rcpps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse2_rcpss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); - -void sse_addps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_addss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_cvtps2pi( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_divss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_andnps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_andps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_cmpps( struct x86_function *p, struct x86_reg dst, struct x86_reg src, - unsigned char cc ); -void sse_maxps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_maxss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_minps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_movaps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_movhlps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_movhps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_movlhps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_movlps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_movss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_movups( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_mulps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_mulss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_orps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_xorps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_subps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_rsqrtps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_rsqrtss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_shufps( struct x86_function *p, struct x86_reg dest, struct x86_reg arg0, - unsigned char shuf ); -void sse_pmovmskb( struct x86_function *p, struct x86_reg dest, struct x86_reg src ); - -void x86_add( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void x86_and( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void x86_cmp( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void x86_dec( struct x86_function *p, struct x86_reg reg ); -void x86_inc( struct x86_function *p, struct x86_reg reg ); -void x86_lea( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void x86_mov( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void x86_mul( struct x86_function *p, struct x86_reg src ); -void x86_or( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void x86_pop( struct x86_function *p, struct x86_reg reg ); -void x86_push( struct x86_function *p, struct x86_reg reg ); -void x86_ret( struct x86_function *p ); -void x86_sub( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void x86_test( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void x86_xor( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void x86_sahf( struct x86_function *p ); - -void x87_f2xm1( struct x86_function *p ); -void x87_fabs( struct x86_function *p ); -void x87_fadd( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); -void x87_faddp( struct x86_function *p, struct x86_reg dst ); -void x87_fchs( struct x86_function *p ); -void x87_fclex( struct x86_function *p ); -void x87_fcom( struct x86_function *p, struct x86_reg dst ); -void x87_fcomp( struct x86_function *p, struct x86_reg dst ); -void x87_fcos( struct x86_function *p ); -void x87_fdiv( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); -void x87_fdivp( struct x86_function *p, struct x86_reg dst ); -void x87_fdivr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); -void x87_fdivrp( struct x86_function *p, struct x86_reg dst ); -void x87_fild( struct x86_function *p, struct x86_reg arg ); -void x87_fist( struct x86_function *p, struct x86_reg dst ); -void x87_fistp( struct x86_function *p, struct x86_reg dst ); -void x87_fld( struct x86_function *p, struct x86_reg arg ); -void x87_fld1( struct x86_function *p ); -void x87_fldcw( struct x86_function *p, struct x86_reg arg ); -void x87_fldl2e( struct x86_function *p ); -void x87_fldln2( struct x86_function *p ); -void x87_fldz( struct x86_function *p ); -void x87_fmul( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); -void x87_fmulp( struct x86_function *p, struct x86_reg dst ); -void x87_fnclex( struct x86_function *p ); -void x87_fprndint( struct x86_function *p ); -void x87_fscale( struct x86_function *p ); -void x87_fsin( struct x86_function *p ); -void x87_fsincos( struct x86_function *p ); -void x87_fsqrt( struct x86_function *p ); -void x87_fst( struct x86_function *p, struct x86_reg dst ); -void x87_fstp( struct x86_function *p, struct x86_reg dst ); -void x87_fsub( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); -void x87_fsubp( struct x86_function *p, struct x86_reg dst ); -void x87_fsubr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); -void x87_fsubrp( struct x86_function *p, struct x86_reg dst ); -void x87_fxch( struct x86_function *p, struct x86_reg dst ); -void x87_fxtract( struct x86_function *p ); -void x87_fyl2x( struct x86_function *p ); -void x87_fyl2xp1( struct x86_function *p ); -void x87_fwait( struct x86_function *p ); -void x87_fnstsw( struct x86_function *p, struct x86_reg dst ); -void x87_fucompp( struct x86_function *p ); -void x87_fucomp( struct x86_function *p, struct x86_reg arg ); -void x87_fucom( struct x86_function *p, struct x86_reg arg ); - - - -/* Retreive a reference to one of the function arguments, taking into - * account any push/pop activity. Note - doesn't track explict - * manipulation of ESP by other instructions. - */ -struct x86_reg x86_fn_arg( struct x86_function *p, unsigned arg ); - -#endif -#endif diff --git a/src/mesa/x86/sse.c b/src/mesa/x86/sse.c deleted file mode 100644 index 02fe18fa..0000000 --- a/src/mesa/x86/sse.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -/* - * PentiumIII-SIMD (SSE) optimizations contributed by - * Andre Werthmann - */ - -#include "main/glheader.h" -#include "main/context.h" -#include "math/m_xform.h" -#include "tnl/t_context.h" - -#include "sse.h" -#include "x86_xform.h" - -#ifdef DEBUG_MATH -#include "math/m_debug.h" -#endif - - -#ifdef USE_SSE_ASM -DECLARE_XFORM_GROUP( sse, 2 ) -DECLARE_XFORM_GROUP( sse, 3 ) - -#if 1 -/* Some functions are not written in SSE-assembly, because the fpu ones are faster */ -extern void _mesa_sse_transform_normals_no_rot( NORM_ARGS ); -extern void _mesa_sse_transform_rescale_normals( NORM_ARGS ); -extern void _mesa_sse_transform_rescale_normals_no_rot( NORM_ARGS ); - -extern void _mesa_sse_transform_points4_general( XFORM_ARGS ); -extern void _mesa_sse_transform_points4_3d( XFORM_ARGS ); -/* XXX this function segfaults, see below */ -extern void _mesa_sse_transform_points4_identity( XFORM_ARGS ); -/* XXX this one works, see below */ -extern void _mesa_x86_transform_points4_identity( XFORM_ARGS ); -#else -DECLARE_NORM_GROUP( sse ) -#endif - - -extern void -_mesa_v16_sse_general_xform( GLfloat *first_vert, - const GLfloat *m, - const GLfloat *src, - GLuint src_stride, - GLuint count ); - -extern void -_mesa_sse_project_vertices( GLfloat *first, - GLfloat *last, - const GLfloat *m, - GLuint stride ); - -extern void -_mesa_sse_project_clipped_vertices( GLfloat *first, - GLfloat *last, - const GLfloat *m, - GLuint stride, - const GLubyte *clipmask ); -#endif - - -void _mesa_init_sse_transform_asm( void ) -{ -#ifdef USE_SSE_ASM - ASSIGN_XFORM_GROUP( sse, 2 ); - ASSIGN_XFORM_GROUP( sse, 3 ); - -#if 1 - /* TODO: Finish these off. - */ - _mesa_transform_tab[4][MATRIX_GENERAL] = - _mesa_sse_transform_points4_general; - _mesa_transform_tab[4][MATRIX_3D] = - _mesa_sse_transform_points4_3d; - /* XXX NOTE: _mesa_sse_transform_points4_identity segfaults with the - conformance tests, so use the x86 version. - */ - _mesa_transform_tab[4][MATRIX_IDENTITY] = - _mesa_x86_transform_points4_identity;/*_mesa_sse_transform_points4_identity;*/ - - _mesa_normal_tab[NORM_TRANSFORM_NO_ROT] = - _mesa_sse_transform_normals_no_rot; - _mesa_normal_tab[NORM_TRANSFORM | NORM_RESCALE] = - _mesa_sse_transform_rescale_normals; - _mesa_normal_tab[NORM_TRANSFORM_NO_ROT | NORM_RESCALE] = - _mesa_sse_transform_rescale_normals_no_rot; -#else - ASSIGN_XFORM_GROUP( sse, 4 ); - - ASSIGN_NORM_GROUP( sse ); -#endif - -#ifdef DEBUG_MATH - _math_test_all_transform_functions( "SSE" ); - _math_test_all_normal_transform_functions( "SSE" ); -#endif -#endif -} - diff --git a/src/mesa/x86/sse.h b/src/mesa/x86/sse.h deleted file mode 100644 index 72b4553..0000000 --- a/src/mesa/x86/sse.h +++ /dev/null @@ -1,36 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -/* - * PentiumIII-SIMD (SSE) optimizations contributed by - * Andre Werthmann - */ - -#ifndef __SSE_H__ -#define __SSE_H__ - -void _mesa_init_sse_transform_asm( void ); - -#endif diff --git a/src/mesa/x86/sse_normal.S b/src/mesa/x86/sse_normal.S deleted file mode 100644 index 4a6573c..0000000 --- a/src/mesa/x86/sse_normal.S +++ /dev/null @@ -1,262 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -/** TODO: - * - insert PREFETCH instructions to avoid cache-misses ! - * - some more optimizations are possible... - * - for 40-50% more performance in the SSE-functions, the - * data (trans-matrix, src_vert, dst_vert) needs to be 16byte aligned ! - */ - -#ifdef USE_SSE_ASM -#include "assyntax.h" -#define MATH_ASM_PTR_SIZE 4 -#include "math/m_vector_asm.h" -#include "norm_args.h" - - SEG_TEXT - -#define M(i) REGOFF(i * 4, EDX) -#define S(i) REGOFF(i * 4, ESI) -#define D(i) REGOFF(i * 4, EDI) -#define STRIDE REGOFF(12, ESI) - - -ALIGNTEXT16 -GLOBL GLNAME(_mesa_sse_transform_rescale_normals_no_rot) -HIDDEN(_mesa_sse_transform_rescale_normals_no_rot) -GLNAME(_mesa_sse_transform_rescale_normals_no_rot): - _CET_ENDBR -#define FRAME_OFFSET 8 - PUSH_L ( ESI ) - PUSH_L ( EDI ) - - MOV_L ( ARG_IN, ESI ) /* ptr to source GLvector3f */ - MOV_L ( ARG_DEST, EDI ) /* ptr to dest GLvector3f */ - - MOV_L ( ARG_MAT, EDX ) /* ptr to matrix */ - ADD_L ( CONST(MATRIX_INV), EDX ) /* matrix->inv */ - - MOV_L ( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */ - - TEST_L ( ECX, ECX ) - JZ( LLBL(K_G3TRNNRR_finish) ) /* count was zero; go to finish */ - - MOV_L ( STRIDE, EAX ) /* stride */ - MOV_L ( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest-count */ - - IMUL_L( CONST(16), ECX ) /* count *= 16 */ - MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */ - - MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */ - ADD_L( EDI, ECX ) /* count += dest ptr */ - -ALIGNTEXT32 - MOVSS ( M(0), XMM1 ) /* m0 */ - MOVSS ( M(5), XMM2 ) /* m5 */ - UNPCKLPS( XMM2, XMM1 ) /* m5 | m0 */ - MOVSS ( ARG_SCALE, XMM0 ) /* scale */ - SHUFPS ( CONST(0x0), XMM0, XMM0 ) /* scale | scale */ - MULPS ( XMM0, XMM1 ) /* m5*scale | m0*scale */ - MULSS ( M(10), XMM0 ) /* m10*scale */ - -ALIGNTEXT32 -LLBL(K_G3TRNNRR_top): - MOVLPS ( S(0), XMM2 ) /* uy | ux */ - MULPS ( XMM1, XMM2 ) /* uy*m5*scale | ux*m0*scale */ - MOVLPS ( XMM2, D(0) ) /* ->D(1) | D(0) */ - - MOVSS ( S(2), XMM2 ) /* uz */ - MULSS ( XMM0, XMM2 ) /* uz*m10*scale */ - MOVSS ( XMM2, D(2) ) /* ->D(2) */ - -LLBL(K_G3TRNNRR_skip): - ADD_L ( CONST(16), EDI ) - ADD_L ( EAX, ESI ) - CMP_L ( ECX, EDI ) - JNE ( LLBL(K_G3TRNNRR_top) ) - -LLBL(K_G3TRNNRR_finish): - POP_L ( EDI ) - POP_L ( ESI ) - RET -#undef FRAME_OFFSET - - - -ALIGNTEXT16 -GLOBL GLNAME(_mesa_sse_transform_rescale_normals) -HIDDEN(_mesa_sse_transform_rescale_normals) -GLNAME(_mesa_sse_transform_rescale_normals): - _CET_ENDBR -#define FRAME_OFFSET 8 - PUSH_L ( ESI ) - PUSH_L ( EDI ) - - MOV_L ( ARG_IN, ESI ) /* ptr to source GLvector3f */ - MOV_L ( ARG_DEST, EDI ) /* ptr to dest GLvector3f */ - - MOV_L ( ARG_MAT, EDX ) /* ptr to matrix */ - ADD_L ( CONST(MATRIX_INV), EDX ) /* matrix->inv */ - - MOV_L ( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */ - - TEST_L ( ECX, ECX ) - JZ( LLBL(K_G3TRNR_finish) ) /* count was zero; go to finish */ - - MOV_L ( STRIDE, EAX ) /* stride */ - MOV_L ( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest-count */ - - IMUL_L( CONST(16), ECX ) /* count *= 16 */ - MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */ - - MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */ - ADD_L( EDI, ECX ) /* count += dest ptr */ - -ALIGNTEXT32 - MOVSS ( M(0), XMM0 ) /* m0 */ - MOVSS ( M(4), XMM1 ) /* m4 */ - UNPCKLPS( XMM1, XMM0 ) /* m4 | m0 */ - - MOVSS ( ARG_SCALE, XMM4 ) /* scale */ - SHUFPS ( CONST(0x0), XMM4, XMM4 ) /* scale | scale */ - - MULPS ( XMM4, XMM0 ) /* m4*scale | m0*scale */ - MOVSS ( M(1), XMM1 ) /* m1 */ - MOVSS ( M(5), XMM2 ) /* m5 */ - UNPCKLPS( XMM2, XMM1 ) /* m5 | m1 */ - MULPS ( XMM4, XMM1 ) /* m5*scale | m1*scale */ - MOVSS ( M(2), XMM2 ) /* m2 */ - MOVSS ( M(6), XMM3 ) /* m6 */ - UNPCKLPS( XMM3, XMM2 ) /* m6 | m2 */ - MULPS ( XMM4, XMM2 ) /* m6*scale | m2*scale */ - - MOVSS ( M(8), XMM6 ) /* m8 */ - MULSS ( ARG_SCALE, XMM6 ) /* m8*scale */ - MOVSS ( M(9), XMM7 ) /* m9 */ - MULSS ( ARG_SCALE, XMM7 ) /* m9*scale */ - -ALIGNTEXT32 -LLBL(K_G3TRNR_top): - MOVSS ( S(0), XMM3 ) /* ux */ - SHUFPS ( CONST(0x0), XMM3, XMM3 ) /* ux | ux */ - MULPS ( XMM0, XMM3 ) /* ux*m4 | ux*m0 */ - MOVSS ( S(1), XMM4 ) /* uy */ - SHUFPS ( CONST(0x0), XMM4, XMM4 ) /* uy | uy */ - MULPS ( XMM1, XMM4 ) /* uy*m5 | uy*m1 */ - MOVSS ( S(2), XMM5 ) /* uz */ - SHUFPS ( CONST(0x0), XMM5, XMM5 ) /* uz | uz */ - MULPS ( XMM2, XMM5 ) /* uz*m6 | uz*m2 */ - - ADDPS ( XMM4, XMM3 ) - ADDPS ( XMM5, XMM3 ) - MOVLPS ( XMM3, D(0) ) - - MOVSS ( M(10), XMM3 ) /* m10 */ - MULSS ( ARG_SCALE, XMM3 ) /* m10*scale */ - MULSS ( S(2), XMM3 ) /* m10*scale*uz */ - MOVSS ( S(1), XMM4 ) /* uy */ - MULSS ( XMM7, XMM4 ) /* uy*m9*scale */ - MOVSS ( S(0), XMM5 ) /* ux */ - MULSS ( XMM6, XMM5 ) /* ux*m8*scale */ - - ADDSS ( XMM4, XMM3 ) - ADDSS ( XMM5, XMM3 ) - MOVSS ( XMM3, D(2) ) - -LLBL(K_G3TRNR_skip): - ADD_L ( CONST(16), EDI ) - ADD_L ( EAX, ESI ) - CMP_L ( ECX, EDI ) - JNE ( LLBL(K_G3TRNR_top) ) - -LLBL(K_G3TRNR_finish): - POP_L ( EDI ) - POP_L ( ESI ) - RET -#undef FRAME_OFFSET - - -ALIGNTEXT16 -GLOBL GLNAME(_mesa_sse_transform_normals_no_rot) -HIDDEN(_mesa_sse_transform_normals_no_rot) -GLNAME(_mesa_sse_transform_normals_no_rot): - _CET_ENDBR -#define FRAME_OFFSET 8 - PUSH_L ( ESI ) - PUSH_L ( EDI ) - - MOV_L ( ARG_IN, ESI ) /* ptr to source GLvector3f */ - MOV_L ( ARG_DEST, EDI ) /* ptr to dest GLvector3f */ - - MOV_L ( ARG_MAT, EDX ) /* ptr to matrix */ - ADD_L ( CONST(MATRIX_INV), EDX ) /* matrix->inv */ - - MOV_L ( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */ - - TEST_L ( ECX, ECX ) - JZ( LLBL(K_G3TNNRR_finish) ) /* count was zero; go to finish */ - - MOV_L ( STRIDE, EAX ) /* stride */ - MOV_L ( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest-count */ - - IMUL_L( CONST(16), ECX ) /* count *= 16 */ - MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */ - - MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */ - ADD_L( EDI, ECX ) /* count += dest ptr */ - -ALIGNTEXT32 - MOVSS( M(0), XMM0 ) /* m0 */ - MOVSS( M(5), XMM1 ) /* m5 */ - UNPCKLPS( XMM1, XMM0 ) /* m5 | m0 */ - MOVSS( M(10), XMM1 ) /* m10 */ - -ALIGNTEXT32 -LLBL(K_G3TNNRR_top): - MOVLPS( S(0), XMM2 ) /* uy | ux */ - MULPS( XMM0, XMM2 ) /* uy*m5 | ux*m0 */ - MOVLPS( XMM2, D(0) ) - - MOVSS( S(2), XMM2 ) /* uz */ - MULSS( XMM1, XMM2 ) /* uz*m10 */ - MOVSS( XMM2, D(2) ) - -LLBL(K_G3TNNRR_skip): - ADD_L ( CONST(16), EDI ) - ADD_L ( EAX, ESI ) - CMP_L ( ECX, EDI ) - JNE ( LLBL(K_G3TNNRR_top) ) - -LLBL(K_G3TNNRR_finish): - POP_L ( EDI ) - POP_L ( ESI ) - RET -#undef FRAME_OFFSET -#endif - -#if defined (__ELF__) && defined (__linux__) - .section .note.GNU-stack,"",%progbits -#endif diff --git a/src/mesa/x86/sse_xform1.S b/src/mesa/x86/sse_xform1.S deleted file mode 100644 index aeeda86..0000000 --- a/src/mesa/x86/sse_xform1.S +++ /dev/null @@ -1,447 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -/** TODO: - * - insert PREFETCH instructions to avoid cache-misses ! - * - some more optimizations are possible... - * - for 40-50% more performance in the SSE-functions, the - * data (trans-matrix, src_vert, dst_vert) needs to be 16byte aligned ! - */ - -#ifdef USE_SSE_ASM -#include "assyntax.h" -#define MATH_ASM_PTR_SIZE 4 -#include "math/m_vector_asm.h" -#include "xform_args.h" - - SEG_TEXT - -#define S(i) REGOFF(i * 4, ESI) -#define D(i) REGOFF(i * 4, EDI) -#define M(i) REGOFF(i * 4, EDX) - - -ALIGNTEXT4 -GLOBL GLNAME(_mesa_sse_transform_points1_general) -HIDDEN( _mesa_sse_transform_points1_general ) -GLNAME( _mesa_sse_transform_points1_general ): - _CET_ENDBR -#define FRAME_OFFSET 8 - PUSH_L ( ESI ) - PUSH_L ( EDI ) - - MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */ - MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */ - - MOV_L( ARG_MATRIX, EDX ) /* ptr to matrix */ - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */ - - CMP_L( CONST(0), ECX ) /* count == 0 ? */ - JE( LLBL(K_GTP1GR_finish) ) /* yes -> nothing to do. */ - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */ - OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */ - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */ - MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) ) /* set dest size */ - - SHL_L( CONST(4), ECX ) /* count *= 16 */ - MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */ - - MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */ - ADD_L( EDI, ECX ) /* count += dest ptr */ - - -ALIGNTEXT32 - MOVAPS( M(0), XMM0 ) /* m3 | m2 | m1 | m0 */ - MOVAPS( M(12), XMM1 ) /* m15 | m14 | m13 | m12 */ - -ALIGNTEXT32 -LLBL(K_GTP1GR_top): - MOVSS( S(0), XMM2 ) /* ox */ - SHUFPS( CONST(0x0), XMM2, XMM2 ) /* ox | ox | ox | ox */ - MULPS( XMM0, XMM2 ) /* ox*m3 | ox*m2 | ox*m1 | ox*m0 */ - ADDPS( XMM1, XMM2 ) /* + | + | + | + */ - MOVUPS( XMM2, D(0) ) - -LLBL(K_GTP1GR_skip): - ADD_L ( CONST(16), EDI ) - ADD_L ( EAX, ESI ) - CMP_L ( ECX, EDI ) - JNE ( LLBL(K_GTP1GR_top) ) - -LLBL(K_GTP1GR_finish): - POP_L ( EDI ) - POP_L ( ESI ) - RET -#undef FRAME_OFFSET - - - -ALIGNTEXT4 -GLOBL GLNAME(_mesa_sse_transform_points1_identity) -HIDDEN(_mesa_sse_transform_points1_identity) -GLNAME( _mesa_sse_transform_points1_identity ): - _CET_ENDBR -#define FRAME_OFFSET 8 - PUSH_L ( ESI ) - PUSH_L ( EDI ) - - MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */ - MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */ - - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */ - - TEST_L( ECX, ECX) - JZ( LLBL(K_GTP1IR_finish) ) /* count was zero; go to finish */ - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */ - OR_L( CONST(VEC_SIZE_1), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */ - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */ - MOV_L( CONST(1), REGOFF(V4F_SIZE, EDI) ) /* set dest size */ - - SHL_L( CONST(4), ECX ) /* count *= 16 */ - MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */ - - MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */ - ADD_L( EDI, ECX ) /* count += dest ptr */ - - CMP_L( ESI, EDI ) - JE( LLBL(K_GTP1IR_finish) ) - - -ALIGNTEXT32 -LLBL(K_GTP1IR_top): - MOV_L( S(0), EDX ) - MOV_L( EDX, D(0) ) - -LLBL(K_GTP1IR_skip): - ADD_L ( CONST(16), EDI ) - ADD_L ( EAX, ESI ) - CMP_L ( ECX, EDI ) - JNE ( LLBL(K_GTP1IR_top) ) - -LLBL(K_GTP1IR_finish): - POP_L ( EDI ) - POP_L ( ESI ) - RET -#undef FRAME_OFFSET - - - -ALIGNTEXT4 -GLOBL GLNAME(_mesa_sse_transform_points1_3d_no_rot) -HIDDEN(_mesa_sse_transform_points1_3d_no_rot) -GLNAME(_mesa_sse_transform_points1_3d_no_rot): - _CET_ENDBR -#define FRAME_OFFSET 8 - PUSH_L( ESI ) - PUSH_L( EDI ) - - MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */ - MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */ - - MOV_L( ARG_MATRIX, EDX ) /* ptr to matrix */ - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */ - - TEST_L( ECX, ECX) - JZ( LLBL(K_GTP13DNRR_finish) ) /* count was zero; go to finish */ - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */ - OR_L( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */ - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */ - MOV_L( CONST(3), REGOFF(V4F_SIZE, EDI) ) /* set dest size */ - - SHL_L( CONST(4), ECX ) /* count *= 16 */ - MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */ - - MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */ - ADD_L( EDI, ECX ) /* count += dest ptr */ - - -ALIGNTEXT32 - MOVSS( M(0), XMM0 ) /* m0 */ - MOVSS( M(12), XMM1 ) /* m12 */ - MOVSS( M(13), XMM2 ) /* m13 */ - MOVSS( M(14), XMM3 ) /* m14 */ - -ALIGNTEXT32 -LLBL(K_GTP13DNRR_top): - MOVSS( S(0), XMM4 ) /* ox */ - MULSS( XMM0, XMM4 ) /* ox*m0 */ - ADDSS( XMM1, XMM4 ) /* ox*m0+m12 */ - MOVSS( XMM4, D(0) ) - - MOVSS( XMM2, D(1) ) - MOVSS( XMM3, D(2) ) - -LLBL(K_GTP13DNRR_skip): - ADD_L ( CONST(16), EDI ) - ADD_L ( EAX, ESI ) - CMP_L ( ECX, EDI ) - JNE ( LLBL(K_GTP13DNRR_top) ) - -LLBL(K_GTP13DNRR_finish): - POP_L ( EDI ) - POP_L ( ESI ) - RET -#undef FRAME_OFFSET - - - -ALIGNTEXT4 -GLOBL GLNAME(_mesa_sse_transform_points1_perspective) -HIDDEN(_mesa_sse_transform_points1_perspective) -GLNAME(_mesa_sse_transform_points1_perspective): - _CET_ENDBR -#define FRAME_OFFSET 8 - PUSH_L ( ESI ) - PUSH_L ( EDI ) - - MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */ - MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */ - - MOV_L( ARG_MATRIX, EDX ) /* ptr to matrix */ - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */ - - TEST_L( ECX, ECX) - JZ( LLBL(K_GTP13PR_finish) ) /* count was zero; go to finish */ - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */ - OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */ - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */ - MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) ) /* set dest size */ - - SHL_L( CONST(4), ECX ) /* count *= 16 */ - MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */ - - MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */ - ADD_L( EDI, ECX ) /* count += dest ptr */ - - -ALIGNTEXT32 - XORPS( XMM0, XMM0 ) /* 0 | 0 | 0 | 0 */ - MOVSS( M(0), XMM1 ) /* m0 */ - MOVSS( M(14), XMM2 ) /* m14 */ - -ALIGNTEXT32 -LLBL(K_GTP13PR_top): - MOVSS( S(0), XMM3 ) /* ox */ - MULSS( XMM1, XMM3 ) /* ox*m0 */ - MOVSS( XMM3, D(0) ) /* ox*m0->D(0) */ - MOVSS( XMM2, D(2) ) /* m14->D(2) */ - - MOVSS( XMM0, D(1) ) - MOVSS( XMM0, D(3) ) - -LLBL(K_GTP13PR_skip): - ADD_L( CONST(16), EDI ) - ADD_L( EAX, ESI ) - CMP_L( ECX, EDI ) - JNE( LLBL(K_GTP13PR_top) ) - -LLBL(K_GTP13PR_finish): - POP_L ( EDI ) - POP_L ( ESI ) - RET -#undef FRAME_OFFSET - - -ALIGNTEXT4 -GLOBL GLNAME(_mesa_sse_transform_points1_2d) -HIDDEN(_mesa_sse_transform_points1_2d) -GLNAME(_mesa_sse_transform_points1_2d): - _CET_ENDBR -#define FRAME_OFFSET 8 - PUSH_L( ESI ) - PUSH_L( EDI ) - - MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */ - MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */ - - MOV_L( ARG_MATRIX, EDX ) /* ptr to matrix */ - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */ - - TEST_L( ECX, ECX) - JZ( LLBL(K_GTP13P2DR_finish) ) /* count was zero; go to finish */ - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */ - OR_L( CONST(VEC_SIZE_2), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */ - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */ - MOV_L( CONST(2), REGOFF(V4F_SIZE, EDI) ) /* set dest size */ - - SHL_L( CONST(4), ECX ) /* count *= 16 */ - MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */ - - MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */ - ADD_L( EDI, ECX ) /* count += dest ptr */ - -ALIGNTEXT32 - MOVLPS( M(0), XMM0 ) /* m1 | m0 */ - MOVLPS( M(12), XMM1 ) /* m13 | m12 */ - -ALIGNTEXT32 -LLBL(K_GTP13P2DR_top): - MOVSS( S(0), XMM2 ) /* ox */ - SHUFPS( CONST(0x0), XMM2, XMM2 ) /* ox | ox | ox | ox */ - MULPS( XMM0, XMM2 ) /* - | - | ox*m1 | ox*m0 */ - ADDPS( XMM1, XMM2 ) /* - | - | ox*m1+m13 | ox*m0+m12 */ - MOVLPS( XMM2, D(0) ) - -LLBL(K_GTP13P2DR_skip): - ADD_L ( CONST(16), EDI ) - ADD_L ( EAX, ESI ) - CMP_L ( ECX, EDI ) - JNE ( LLBL(K_GTP13P2DR_top) ) - -LLBL(K_GTP13P2DR_finish): - POP_L ( EDI ) - POP_L ( ESI ) - RET -#undef FRAME_OFFSET - - -ALIGNTEXT4 -GLOBL GLNAME(_mesa_sse_transform_points1_2d_no_rot) -HIDDEN(_mesa_sse_transform_points1_2d_no_rot) -GLNAME(_mesa_sse_transform_points1_2d_no_rot): - _CET_ENDBR -#define FRAME_OFFSET 8 - PUSH_L( ESI ) - PUSH_L( EDI ) - - MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */ - MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */ - - MOV_L( ARG_MATRIX, EDX ) /* ptr to matrix */ - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */ - - TEST_L( ECX, ECX) - JZ( LLBL(K_GTP13P2DNRR_finish) ) /* count was zero; go to finish */ - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */ - OR_L( CONST(VEC_SIZE_2), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */ - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */ - MOV_L( CONST(2), REGOFF(V4F_SIZE, EDI) ) /* set dest size */ - - SHL_L( CONST(4), ECX ) /* count *= 16 */ - MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */ - - MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */ - ADD_L( EDI, ECX ) /* count += dest ptr */ - -ALIGNTEXT32 - MOVSS( M(0), XMM0 ) /* m0 */ - MOVSS( M(12), XMM1 ) /* m12 */ - MOVSS( M(13), XMM2 ) /* m13 */ - -ALIGNTEXT32 -LLBL(K_GTP13P2DNRR_top): - MOVSS( S(0), XMM3 ) /* ox */ - MULSS( XMM0, XMM3 ) /* ox*m0 */ - ADDSS( XMM1, XMM3 ) /* ox*m0+m12 */ - MOVSS( XMM3, D(0) ) - MOVSS( XMM2, D(1) ) - -LLBL(K_GTP13P2DNRR_skip): - ADD_L( CONST(16), EDI ) - ADD_L( EAX, ESI ) - CMP_L( ECX, EDI ) - JNE( LLBL(K_GTP13P2DNRR_top) ) - -LLBL(K_GTP13P2DNRR_finish): - POP_L( EDI ) - POP_L( ESI ) - RET -#undef FRAME_OFFSET - - - -ALIGNTEXT4 -GLOBL GLNAME(_mesa_sse_transform_points1_3d) -HIDDEN(_mesa_sse_transform_points1_3d) -GLNAME(_mesa_sse_transform_points1_3d): - _CET_ENDBR -#define FRAME_OFFSET 8 - PUSH_L( ESI ) - PUSH_L( EDI ) - - MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */ - MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */ - - MOV_L( ARG_MATRIX, EDX ) /* ptr to matrix */ - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */ - - TEST_L( ECX, ECX) - JZ( LLBL(K_GTP13P3DR_finish) ) /* count was zero; go to finish */ - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */ - OR_L( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */ - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */ - MOV_L( CONST(3), REGOFF(V4F_SIZE, EDI) ) /* set dest size */ - - SHL_L( CONST(4), ECX ) /* count *= 16 */ - MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */ - - MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */ - ADD_L( EDI, ECX ) /* count += dest ptr */ - - -ALIGNTEXT32 - MOVAPS( M(0), XMM0 ) /* m3 | m2 | m1 | m0 */ - MOVAPS( M(12), XMM1 ) /* m15 | m14 | m13 | m12 */ - -ALIGNTEXT32 -LLBL(K_GTP13P3DR_top): - MOVSS( S(0), XMM2 ) /* ox */ - SHUFPS( CONST(0x0), XMM2, XMM2 ) /* ox | ox | ox | ox */ - MULPS( XMM0, XMM2 ) /* ox*m3 | ox*m2 | ox*m1 | ox*m0 */ - ADDPS( XMM1, XMM2 ) /* +m15 | +m14 | +m13 | +m12 */ - MOVLPS( XMM2, D(0) ) /* - | - | ->D(1)| ->D(0)*/ - UNPCKHPS( XMM2, XMM2 ) /* ox*m3+m15 | ox*m3+m15 | ox*m2+m14 | ox*m2+m14 */ - MOVSS( XMM2, D(2) ) - -LLBL(K_GTP13P3DR_skip): - ADD_L( CONST(16), EDI ) - ADD_L( EAX, ESI ) - CMP_L( ECX, EDI ) - JNE( LLBL(K_GTP13P3DR_top) ) - -LLBL(K_GTP13P3DR_finish): - POP_L( EDI ) - POP_L( ESI ) - RET -#undef FRAME_OFFSET -#endif - -#if defined (__ELF__) && defined (__linux__) - .section .note.GNU-stack,"",%progbits -#endif diff --git a/src/mesa/x86/sse_xform2.S b/src/mesa/x86/sse_xform2.S deleted file mode 100644 index 5ba9afa..0000000 --- a/src/mesa/x86/sse_xform2.S +++ /dev/null @@ -1,467 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -/** TODO: - * - insert PREFETCH instructions to avoid cache-misses ! - * - some more optimizations are possible... - * - for 40-50% more performance in the SSE-functions, the - * data (trans-matrix, src_vert, dst_vert) needs to be 16byte aligned ! - */ - -#ifdef USE_SSE_ASM -#include "assyntax.h" -#define MATH_ASM_PTR_SIZE 4 -#include "math/m_vector_asm.h" -#include "xform_args.h" - - SEG_TEXT - -#define S(i) REGOFF(i * 4, ESI) -#define D(i) REGOFF(i * 4, EDI) -#define M(i) REGOFF(i * 4, EDX) - - -ALIGNTEXT4 -GLOBL GLNAME(_mesa_sse_transform_points2_general) -HIDDEN (_mesa_sse_transform_points2_general) -GLNAME( _mesa_sse_transform_points2_general ): - _CET_ENDBR -#define FRAME_OFFSET 8 - PUSH_L ( ESI ) - PUSH_L ( EDI ) - - MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */ - MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */ - - MOV_L( ARG_MATRIX, EDX ) /* ptr to matrix */ - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */ - - TEST_L( ECX, ECX ) - JZ( LLBL(K_GTP2GR_finish) ) /* count was zero; go to finish */ - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */ - OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */ - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */ - MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) ) /* set dest size */ - - SHL_L( CONST(4), ECX ) /* count *= 16 */ - MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */ - - MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */ - ADD_L( EDI, ECX ) /* count += dest ptr */ - -ALIGNTEXT32 - MOVAPS( M(0), XMM0 ) /* m3 | m2 | m1 | m0 */ - MOVAPS( M(4), XMM1 ) /* m7 | m6 | m5 | m4 */ - MOVAPS( M(12), XMM2 ) /* m15 | m14 | m13 | m12 */ - -ALIGNTEXT32 -LLBL(K_GTP2GR_top): - MOVSS( S(0), XMM3 ) /* ox */ - SHUFPS( CONST(0x0), XMM3, XMM3 ) /* ox | ox | ox | ox */ - MULPS( XMM0, XMM3 ) /* ox*m3 | ox*m2 | ox*m1 | ox*m0 */ - MOVSS( S(1), XMM4 ) /* oy */ - SHUFPS( CONST(0x0), XMM4, XMM4 ) /* oy | oy | oy | oy */ - MULPS( XMM1, XMM4 ) /* oy*m7 | oy*m6 | oy*m5 | oy*m4 */ - - ADDPS( XMM4, XMM3 ) - ADDPS( XMM2, XMM3 ) - MOVAPS( XMM3, D(0) ) - -LLBL(K_GTP2GR_skip): - ADD_L ( CONST(16), EDI ) - ADD_L ( EAX, ESI ) - CMP_L ( ECX, EDI ) - JNE ( LLBL(K_GTP2GR_top) ) - -LLBL(K_GTP2GR_finish): - POP_L ( EDI ) - POP_L ( ESI ) - RET -#undef FRAME_OFFSET - - -ALIGNTEXT4 -GLOBL GLNAME(_mesa_sse_transform_points2_identity) -HIDDEN(_mesa_sse_transform_points2_identity) -GLNAME( _mesa_sse_transform_points2_identity ): - _CET_ENDBR -#define FRAME_OFFSET 8 - PUSH_L ( ESI ) - PUSH_L ( EDI ) - - MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */ - MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */ - - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */ - - TEST_L( ECX, ECX) - JZ( LLBL(K_GTP2IR_finish) ) /* count was zero; go to finish */ - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */ - OR_L( CONST(VEC_SIZE_2), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */ - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */ - MOV_L( CONST(2), REGOFF(V4F_SIZE, EDI) ) /* set dest size */ - - SHL_L( CONST(4), ECX ) /* count *= 16 */ - MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */ - - MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */ - ADD_L( EDI, ECX ) /* count += dest ptr */ - - CMP_L( ESI, EDI ) - JE( LLBL(K_GTP2IR_finish) ) - - -ALIGNTEXT32 -LLBL(K_GTP2IR_top): - MOV_L ( S(0), EDX ) - MOV_L ( EDX, D(0) ) - MOV_L ( S(1), EDX ) - MOV_L ( EDX, D(1) ) - -LLBL(K_GTP2IR_skip): - ADD_L ( CONST(16), EDI ) - ADD_L ( EAX, ESI ) - CMP_L ( ECX, EDI ) - JNE ( LLBL(K_GTP2IR_top) ) - -LLBL(K_GTP2IR_finish): - POP_L ( EDI ) - POP_L ( ESI ) - RET -#undef FRAME_OFFSET - - -ALIGNTEXT4 -GLOBL GLNAME(_mesa_sse_transform_points2_3d_no_rot) -HIDDEN(_mesa_sse_transform_points2_3d_no_rot) -GLNAME(_mesa_sse_transform_points2_3d_no_rot): - _CET_ENDBR -#define FRAME_OFFSET 8 - PUSH_L( ESI ) - PUSH_L( EDI ) - - MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */ - MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */ - - MOV_L( ARG_MATRIX, EDX ) /* ptr to matrix */ - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */ - - TEST_L( ECX, ECX) - JZ( LLBL(K_GTP23DNRR_finish) ) /* count was zero; go to finish */ - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */ - OR_L( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */ - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */ - MOV_L( CONST(3), REGOFF(V4F_SIZE, EDI) ) /* set dest size */ - - SHL_L( CONST(4), ECX ) /* count *= 16 */ - MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */ - - MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */ - ADD_L( EDI, ECX ) /* count += dest ptr */ - - XORPS( XMM0, XMM0 ) /* clean the working register */ - -ALIGNTEXT32 - MOVSS ( M(0), XMM1 ) /* - | - | - | m0 */ - MOVSS ( M(5), XMM2 ) /* - | - | - | m5 */ - UNPCKLPS ( XMM2, XMM1 ) /* - | - | m5 | m0 */ - MOVLPS ( M(12), XMM2 ) /* - | - | m13 | m12 */ - MOVSS ( M(14), XMM3 ) /* - | - | - | m14 */ - -ALIGNTEXT32 -LLBL(K_GTP23DNRR_top): - MOVLPS ( S(0), XMM0 ) /* - | - | oy | ox */ - MULPS ( XMM1, XMM0 ) /* - | - | oy*m5 | ox*m0 */ - ADDPS ( XMM2, XMM0 ) /* - | - | +m13 | +m12 */ - MOVLPS ( XMM0, D(0) ) /* -> D(1) | -> D(0) */ - - MOVSS ( XMM3, D(2) ) /* -> D(2) */ - -LLBL(K_GTP23DNRR_skip): - ADD_L ( CONST(16), EDI ) - ADD_L ( EAX, ESI ) - CMP_L ( ECX, EDI ) - JNE ( LLBL(K_GTP23DNRR_top) ) - -LLBL(K_GTP23DNRR_finish): - POP_L ( EDI ) - POP_L ( ESI ) - RET -#undef FRAME_OFFSET - - -ALIGNTEXT4 -GLOBL GLNAME(_mesa_sse_transform_points2_perspective) -HIDDEN(_mesa_sse_transform_points2_perspective) -GLNAME(_mesa_sse_transform_points2_perspective): - _CET_ENDBR -#define FRAME_OFFSET 8 - PUSH_L ( ESI ) - PUSH_L ( EDI ) - - MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */ - MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */ - - MOV_L( ARG_MATRIX, EDX ) /* ptr to matrix */ - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */ - - TEST_L( ECX, ECX) - JZ( LLBL(K_GTP23PR_finish) ) /* count was zero; go to finish */ - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */ - OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */ - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */ - MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) ) /* set dest size */ - - SHL_L( CONST(4), ECX ) /* count *= 16 */ - MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */ - - MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */ - ADD_L( EDI, ECX ) /* count += dest ptr */ - -ALIGNTEXT32 - MOVSS ( M(0), XMM1 ) /* - | - | - | m0 */ - MOVSS ( M(5), XMM2 ) /* - | - | - | m5 */ - UNPCKLPS ( XMM2, XMM1 ) /* - | - | m5 | m0 */ - MOVSS ( M(14), XMM3 ) /* m14 */ - XORPS ( XMM0, XMM0 ) /* 0 | 0 | 0 | 0 */ - -ALIGNTEXT32 -LLBL(K_GTP23PR_top): - MOVLPS( S(0), XMM4 ) /* oy | ox */ - MULPS( XMM1, XMM4 ) /* oy*m5 | ox*m0 */ - MOVLPS( XMM4, D(0) ) /* ->D(1) | ->D(0) */ - MOVSS( XMM3, D(2) ) /* ->D(2) */ - MOVSS( XMM0, D(3) ) /* ->D(3) */ - -LLBL(K_GTP23PR_skip): - ADD_L( CONST(16), EDI ) - ADD_L( EAX, ESI ) - CMP_L( ECX, EDI ) - JNE( LLBL(K_GTP23PR_top) ) - -LLBL(K_GTP23PR_finish): - POP_L ( EDI ) - POP_L ( ESI ) - RET -#undef FRAME_OFFSET - - - -ALIGNTEXT4 -GLOBL GLNAME(_mesa_sse_transform_points2_2d) -HIDDEN(_mesa_sse_transform_points2_2d) -GLNAME(_mesa_sse_transform_points2_2d): - _CET_ENDBR -#define FRAME_OFFSET 8 - PUSH_L( ESI ) - PUSH_L( EDI ) - - MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */ - MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */ - - MOV_L( ARG_MATRIX, EDX ) /* ptr to matrix */ - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */ - - TEST_L( ECX, ECX) - JZ( LLBL(K_GTP23P2DR_finish) ) /* count was zero; go to finish */ - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */ - OR_L( CONST(VEC_SIZE_2), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */ - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */ - MOV_L( CONST(2), REGOFF(V4F_SIZE, EDI) ) /* set dest size */ - - SHL_L( CONST(4), ECX ) /* count *= 16 */ - MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */ - - MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */ - ADD_L( EDI, ECX ) /* count += dest ptr */ - -ALIGNTEXT32 - MOVLPS( M(0), XMM0 ) /* m1 | m0 */ - MOVLPS( M(4), XMM1 ) /* m5 | m4 */ - MOVLPS( M(12), XMM2 ) /* m13 | m12 */ - -ALIGNTEXT32 -LLBL(K_GTP23P2DR_top): - MOVSS( S(0), XMM3 ) /* ox */ - SHUFPS( CONST(0x0), XMM3, XMM3 ) /* ox | ox */ - MULPS( XMM0, XMM3 ) /* ox*m1 | ox*m0 */ - - MOVSS( S(1), XMM4 ) /* oy */ - SHUFPS( CONST(0x0), XMM4, XMM4 ) /* oy | oy */ - MULPS( XMM1, XMM4 ) /* oy*m5 | oy*m4 */ - - ADDPS( XMM4, XMM3 ) - ADDPS( XMM2, XMM3 ) - MOVLPS( XMM3, D(0) ) /* ->D(1) | ->D(0) */ - -LLBL(K_GTP23P2DR_skip): - ADD_L ( CONST(16), EDI ) - ADD_L ( EAX, ESI ) - CMP_L ( ECX, EDI ) - JNE ( LLBL(K_GTP23P2DR_top) ) - -LLBL(K_GTP23P2DR_finish): - POP_L ( EDI ) - POP_L ( ESI ) - RET -#undef FRAME_OFFSET - - - -ALIGNTEXT4 -GLOBL GLNAME(_mesa_sse_transform_points2_2d_no_rot) -HIDDEN(_mesa_sse_transform_points2_2d_no_rot) -GLNAME(_mesa_sse_transform_points2_2d_no_rot): - _CET_ENDBR -#define FRAME_OFFSET 8 - PUSH_L( ESI ) - PUSH_L( EDI ) - - MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */ - MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */ - - MOV_L( ARG_MATRIX, EDX ) /* ptr to matrix */ - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */ - - TEST_L( ECX, ECX) - JZ( LLBL(K_GTP23P2DNRR_finish) ) /* count was zero; go to finish */ - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */ - OR_L( CONST(VEC_SIZE_2), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */ - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */ - MOV_L( CONST(2), REGOFF(V4F_SIZE, EDI) ) /* set dest size */ - - SHL_L( CONST(4), ECX ) /* count *= 16 */ - MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */ - - MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */ - ADD_L( EDI, ECX ) /* count += dest ptr */ - -ALIGNTEXT32 - MOVSS ( M(0), XMM1 ) /* m0 */ - MOVSS ( M(5), XMM2 ) /* m5 */ - UNPCKLPS ( XMM2, XMM1 ) /* m5 | m0 */ - MOVLPS ( M(12), XMM2 ) /* m13 | m12 */ - -ALIGNTEXT32 -LLBL(K_GTP23P2DNRR_top): - MOVLPS( S(0), XMM0 ) /* oy | ox */ - MULPS( XMM1, XMM0 ) /* oy*m5 | ox*m0 */ - ADDPS( XMM2, XMM0 ) /* +m13 | +m12 */ - MOVLPS( XMM0, D(0) ) /* ->D(1) | ->D(0) */ - -LLBL(K_GTP23P2DNRR_skip): - ADD_L( CONST(16), EDI ) - ADD_L( EAX, ESI ) - CMP_L( ECX, EDI ) - JNE( LLBL(K_GTP23P2DNRR_top) ) - -LLBL(K_GTP23P2DNRR_finish): - POP_L( EDI ) - POP_L( ESI ) - RET -#undef FRAME_OFFSET - - - -ALIGNTEXT4 -GLOBL GLNAME(_mesa_sse_transform_points2_3d) -HIDDEN(_mesa_sse_transform_points2_3d) -GLNAME(_mesa_sse_transform_points2_3d): - _CET_ENDBR -#define FRAME_OFFSET 8 - PUSH_L( ESI ) - PUSH_L( EDI ) - - MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */ - MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */ - - MOV_L( ARG_MATRIX, EDX ) /* ptr to matrix */ - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */ - - TEST_L( ECX, ECX) - JZ( LLBL(K_GTP23P3DR_finish) ) /* count was zero; go to finish */ - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */ - OR_L( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */ - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */ - MOV_L( CONST(3), REGOFF(V4F_SIZE, EDI) ) /* set dest size */ - - SHL_L( CONST(4), ECX ) /* count *= 16 */ - MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */ - - MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */ - ADD_L( EDI, ECX ) /* count += dest ptr */ - -ALIGNTEXT32 - MOVAPS( M(0), XMM0 ) /* m2 | m1 | m0 */ - MOVAPS( M(4), XMM1 ) /* m6 | m5 | m4 */ - MOVAPS( M(12), XMM2 ) /* m14 | m13 | m12 */ - -ALIGNTEXT32 -LLBL(K_GTP23P3DR_top): - MOVSS( S(0), XMM3 ) /* ox */ - SHUFPS( CONST(0x0), XMM3, XMM3 ) /* ox | ox | ox */ - MULPS( XMM0, XMM3 ) /* ox*m2 | ox*m1 | ox*m0 */ - - MOVSS( S(1), XMM4 ) /* oy */ - SHUFPS( CONST(0x0), XMM4, XMM4 ) /* oy | oy | oy */ - MULPS( XMM1, XMM4 ) /* oy*m6 | oy*m5 | oy*m4 */ - - ADDPS( XMM4, XMM3 ) - ADDPS( XMM2, XMM3 ) - - MOVLPS( XMM3, D(0) ) /* ->D(1) | ->D(0) */ - UNPCKHPS( XMM3, XMM3 ) - MOVSS( XMM3, D(2) ) /* ->D(2) */ - -LLBL(K_GTP23P3DR_skip): - ADD_L( CONST(16), EDI ) - ADD_L( EAX, ESI ) - CMP_L( ECX, EDI ) - JNE( LLBL(K_GTP23P3DR_top) ) - -LLBL(K_GTP23P3DR_finish): - POP_L( EDI ) - POP_L( ESI ) - RET -#undef FRAME_OFFSET -#endif - -#if defined (__ELF__) && defined (__linux__) - .section .note.GNU-stack,"",%progbits -#endif diff --git a/src/mesa/x86/sse_xform3.S b/src/mesa/x86/sse_xform3.S deleted file mode 100644 index fe0ccca..0000000 --- a/src/mesa/x86/sse_xform3.S +++ /dev/null @@ -1,513 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -/** TODO: - * - insert PREFETCH instructions to avoid cache-misses ! - * - some more optimizations are possible... - * - for 40-50% more performance in the SSE-functions, the - * data (trans-matrix, src_vert, dst_vert) needs to be 16byte aligned ! - */ - -#ifdef USE_SSE_ASM -#include "assyntax.h" -#define MATH_ASM_PTR_SIZE 4 -#include "math/m_vector_asm.h" -#include "xform_args.h" - - SEG_TEXT - -#define S(i) REGOFF(i * 4, ESI) -#define D(i) REGOFF(i * 4, EDI) -#define M(i) REGOFF(i * 4, EDX) - - -ALIGNTEXT4 -GLOBL GLNAME(_mesa_sse_transform_points3_general) -HIDDEN(_mesa_sse_transform_points3_general) -GLNAME( _mesa_sse_transform_points3_general ): - _CET_ENDBR -#define FRAME_OFFSET 8 - PUSH_L ( ESI ) - PUSH_L ( EDI ) - - MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */ - MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */ - - MOV_L( ARG_MATRIX, EDX ) /* ptr to matrix */ - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */ - - CMP_L ( CONST(0), ECX ) /* count == 0 ? */ - JE ( LLBL(K_GTPGR_finish) ) /* yes -> nothing to do. */ - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */ - OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */ - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */ - MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) ) /* set dest size */ - - SHL_L( CONST(4), ECX ) /* count *= 16 */ - MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */ - - MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */ - ADD_L( EDI, ECX ) /* count += dest ptr */ - - -ALIGNTEXT32 - MOVAPS ( REGOFF(0, EDX), XMM0 ) /* m0 | m1 | m2 | m3 */ - MOVAPS ( REGOFF(16, EDX), XMM1 ) /* m4 | m5 | m6 | m7 */ - MOVAPS ( REGOFF(32, EDX), XMM2 ) /* m8 | m9 | m10 | m11 */ - MOVAPS ( REGOFF(48, EDX), XMM3 ) /* m12 | m13 | m14 | m15 */ - - -ALIGNTEXT32 -LLBL(K_GTPGR_top): - MOVSS ( REGOFF(0, ESI), XMM4 ) /* | | | ox */ - SHUFPS ( CONST(0x0), XMM4, XMM4 ) /* ox | ox | ox | ox */ - MOVSS ( REGOFF(4, ESI), XMM5 ) /* | | | oy */ - SHUFPS ( CONST(0x0), XMM5, XMM5 ) /* oy | oy | oy | oy */ - MOVSS ( REGOFF(8, ESI), XMM6 ) /* | | | oz */ - SHUFPS ( CONST(0x0), XMM6, XMM6 ) /* oz | oz | oz | oz */ - - MULPS ( XMM0, XMM4 ) /* m3*ox | m2*ox | m1*ox | m0*ox */ - MULPS ( XMM1, XMM5 ) /* m7*oy | m6*oy | m5*oy | m4*oy */ - MULPS ( XMM2, XMM6 ) /* m11*oz | m10*oz | m9*oz | m8*oz */ - - ADDPS ( XMM5, XMM4 ) - ADDPS ( XMM6, XMM4 ) - ADDPS ( XMM3, XMM4 ) - - MOVAPS ( XMM4, REGOFF(0, EDI) ) - -LLBL(K_GTPGR_skip): - ADD_L ( CONST(16), EDI ) - ADD_L ( EAX, ESI ) - CMP_L ( ECX, EDI ) - JNE ( LLBL(K_GTPGR_top) ) - -LLBL(K_GTPGR_finish): - POP_L ( EDI ) - POP_L ( ESI ) - RET -#undef FRAME_OFFSET - - -ALIGNTEXT4 -GLOBL GLNAME(_mesa_sse_transform_points3_identity) -HIDDEN(_mesa_sse_transform_points3_identity) -GLNAME( _mesa_sse_transform_points3_identity ): - _CET_ENDBR -#define FRAME_OFFSET 8 - PUSH_L ( ESI ) - PUSH_L ( EDI ) - - MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */ - MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */ - - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */ - - TEST_L( ECX, ECX) - JZ( LLBL(K_GTPIR_finish) ) /* count was zero; go to finish */ - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */ - OR_L( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */ - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */ - MOV_L( CONST(3), REGOFF(V4F_SIZE, EDI) ) /* set dest size */ - - SHL_L( CONST(4), ECX ) /* count *= 16 */ - MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */ - - MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */ - ADD_L( EDI, ECX ) /* count += dest ptr */ - - CMP_L( ESI, EDI ) - JE( LLBL(K_GTPIR_finish) ) - - -ALIGNTEXT32 -LLBL(K_GTPIR_top): - MOVLPS ( S(0), XMM0 ) - MOVLPS ( XMM0, D(0) ) - MOVSS ( S(2), XMM0 ) - MOVSS ( XMM0, D(2) ) - -LLBL(K_GTPIR_skip): - ADD_L ( CONST(16), EDI ) - ADD_L ( EAX, ESI ) - CMP_L ( ECX, EDI ) - JNE ( LLBL(K_GTPIR_top) ) - -LLBL(K_GTPIR_finish): - POP_L ( EDI ) - POP_L ( ESI ) - RET -#undef FRAME_OFFSET - - - - -ALIGNTEXT4 -GLOBL GLNAME(_mesa_sse_transform_points3_3d_no_rot) -HIDDEN(_mesa_sse_transform_points3_3d_no_rot) -GLNAME(_mesa_sse_transform_points3_3d_no_rot): - _CET_ENDBR -#define FRAME_OFFSET 8 - PUSH_L( ESI ) - PUSH_L( EDI ) - - MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */ - MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */ - - - MOV_L( ARG_MATRIX, EDX ) /* ptr to matrix */ - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */ - - TEST_L( ECX, ECX) - JZ( LLBL(K_GTP3DNRR_finish) ) /* count was zero; go to finish */ - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */ - OR_L( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */ - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */ - MOV_L( CONST(3), REGOFF(V4F_SIZE, EDI) ) /* set dest size */ - - SHL_L( CONST(4), ECX ) /* count *= 16 */ - MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */ - - MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */ - ADD_L( EDI, ECX ) /* count += dest ptr */ - - XORPS( XMM0, XMM0 ) /* clean the working register */ - -ALIGNTEXT32 - MOVSS ( M(0), XMM1 ) /* - | - | - | m0 */ - MOVSS ( M(5), XMM2 ) /* - | - | - | m5 */ - UNPCKLPS ( XMM2, XMM1 ) /* - | - | m5 | m0 */ - MOVLPS ( M(12), XMM2 ) /* - | - | m13 | m12 */ - MOVSS ( M(10), XMM3 ) /* - | - | - | m10 */ - MOVSS ( M(14), XMM4 ) /* - | - | - | m14 */ - -ALIGNTEXT32 -LLBL(K_GTP3DNRR_top): - - MOVLPS ( S(0), XMM0 ) /* - | - | s1 | s0 */ - MULPS ( XMM1, XMM0 ) /* - | - | s1*m5 | s0*m0 */ - ADDPS ( XMM2, XMM0 ) /* - | - | +m13 | +m12 */ - MOVLPS ( XMM0, D(0) ) /* -> D(1) | -> D(0) */ - - MOVSS ( S(2), XMM0 ) /* sz */ - MULSS ( XMM3, XMM0 ) /* sz*m10 */ - ADDSS ( XMM4, XMM0 ) /* +m14 */ - MOVSS ( XMM0, D(2) ) /* -> D(2) */ - -LLBL(K_GTP3DNRR_skip): - ADD_L ( CONST(16), EDI ) - ADD_L ( EAX, ESI ) - CMP_L ( ECX, EDI ) - JNE ( LLBL(K_GTP3DNRR_top) ) - -LLBL(K_GTP3DNRR_finish): - POP_L ( EDI ) - POP_L ( ESI ) - RET -#undef FRAME_OFFSET - - - -ALIGNTEXT4 -GLOBL GLNAME(_mesa_sse_transform_points3_perspective) -HIDDEN(_mesa_sse_transform_points3_perspective) -GLNAME(_mesa_sse_transform_points3_perspective): - _CET_ENDBR -#define FRAME_OFFSET 8 - PUSH_L ( ESI ) - PUSH_L ( EDI ) - - MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */ - MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */ - - MOV_L( ARG_MATRIX, EDX ) /* ptr to matrix */ - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */ - - TEST_L( ECX, ECX) - JZ( LLBL(K_GTP3PR_finish) ) /* count was zero; go to finish */ - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */ - OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */ - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */ - MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) ) /* set dest size */ - - SHL_L( CONST(4), ECX ) /* count *= 16 */ - MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */ - - MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */ - ADD_L( EDI, ECX ) /* count += dest ptr */ - -ALIGNTEXT32 - MOVSS ( M(0), XMM1 ) /* - | - | - | m0 */ - MOVSS ( M(5), XMM2 ) /* - | - | - | m5 */ - UNPCKLPS ( XMM2, XMM1 ) /* - | - | m5 | m0 */ - MOVLPS ( M(8), XMM2 ) /* - | - | m9 | m8 */ - MOVSS ( M(10), XMM3 ) /* m10 */ - MOVSS ( M(14), XMM4 ) /* m14 */ - XORPS ( XMM6, XMM6 ) /* 0 */ - -ALIGNTEXT32 -LLBL(K_GTP3PR_top): - MOVLPS ( S(0), XMM0 ) /* oy | ox */ - MULPS ( XMM1, XMM0 ) /* oy*m5 | ox*m0 */ - MOVSS ( S(2), XMM5 ) /* oz */ - SHUFPS ( CONST(0x0), XMM5, XMM5 ) /* oz | oz */ - MULPS ( XMM2, XMM5 ) /* oz*m9 | oz*m8 */ - ADDPS ( XMM5, XMM0 ) /* +oy*m5 | +ox*m0 */ - MOVLPS ( XMM0, D(0) ) /* ->D(1) | ->D(0) */ - - MOVSS ( S(2), XMM0 ) /* oz */ - MULSS ( XMM3, XMM0 ) /* oz*m10 */ - ADDSS ( XMM4, XMM0 ) /* +m14 */ - MOVSS ( XMM0, D(2) ) /* ->D(2) */ - - MOVSS ( S(2), XMM0 ) /* oz */ - MOVSS ( XMM6, XMM5 ) /* 0 */ - SUBPS ( XMM0, XMM5 ) /* -oz */ - MOVSS ( XMM5, D(3) ) /* ->D(3) */ - -LLBL(K_GTP3PR_skip): - ADD_L( CONST(16), EDI ) - ADD_L( EAX, ESI ) - CMP_L( ECX, EDI ) - JNE( LLBL(K_GTP3PR_top) ) - -LLBL(K_GTP3PR_finish): - POP_L ( EDI ) - POP_L ( ESI ) - RET -#undef FRAME_OFFSET - - - -ALIGNTEXT4 -GLOBL GLNAME(_mesa_sse_transform_points3_2d) -HIDDEN(_mesa_sse_transform_points3_2d) -GLNAME(_mesa_sse_transform_points3_2d): - _CET_ENDBR -#define FRAME_OFFSET 8 - PUSH_L( ESI ) - PUSH_L( EDI ) - - MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */ - MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */ - - MOV_L( ARG_MATRIX, EDX ) /* ptr to matrix */ - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */ - - TEST_L( ECX, ECX) - JZ( LLBL(K_GTP3P2DR_finish) ) /* count was zero; go to finish */ - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */ - OR_L( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */ - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */ - MOV_L( CONST(3), REGOFF(V4F_SIZE, EDI) ) /* set dest size */ - - SHL_L( CONST(4), ECX ) /* count *= 16 */ - MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */ - - MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */ - ADD_L( EDI, ECX ) /* count += dest ptr */ - -ALIGNTEXT32 - MOVLPS( M(0), XMM0 ) /* m1 | m0 */ - MOVLPS( M(4), XMM1 ) /* m5 | m4 */ - MOVLPS( M(12), XMM2 ) /* m13 | m12 */ - -ALIGNTEXT32 -LLBL(K_GTP3P2DR_top): - MOVSS ( S(0), XMM3 ) /* ox */ - SHUFPS ( CONST(0x0), XMM3, XMM3 ) /* ox | ox */ - MULPS ( XMM0, XMM3 ) /* ox*m1 | ox*m0 */ - MOVSS ( S(1), XMM4 ) /* oy */ - SHUFPS ( CONST(0x0), XMM4, XMM4 ) /* oy | oy */ - MULPS ( XMM1, XMM4 ) /* oy*m5 | oy*m4 */ - - ADDPS ( XMM4, XMM3 ) - ADDPS ( XMM2, XMM3 ) - MOVLPS ( XMM3, D(0) ) - - MOVSS ( S(2), XMM3 ) - MOVSS ( XMM3, D(2) ) - -LLBL(K_GTP3P2DR_skip): - ADD_L ( CONST(16), EDI ) - ADD_L ( EAX, ESI ) - CMP_L ( ECX, EDI ) - JNE ( LLBL(K_GTP3P2DR_top) ) - -LLBL(K_GTP3P2DR_finish): - POP_L ( EDI ) - POP_L ( ESI ) - RET -#undef FRAME_OFFSET - - - -ALIGNTEXT4 -GLOBL GLNAME(_mesa_sse_transform_points3_2d_no_rot) -HIDDEN(_mesa_sse_transform_points3_2d_no_rot) -GLNAME(_mesa_sse_transform_points3_2d_no_rot): - _CET_ENDBR -#define FRAME_OFFSET 8 - PUSH_L( ESI ) - PUSH_L( EDI ) - - MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */ - MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */ - - MOV_L( ARG_MATRIX, EDX ) /* ptr to matrix */ - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */ - - TEST_L( ECX, ECX) - JZ( LLBL(K_GTP3P2DNRR_finish) ) /* count was zero; go to finish */ - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */ - OR_L( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */ - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */ - MOV_L( CONST(3), REGOFF(V4F_SIZE, EDI) ) /* set dest size */ - - SHL_L( CONST(4), ECX ) /* count *= 16 */ - MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */ - - MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */ - ADD_L( EDI, ECX ) /* count += dest ptr */ - -ALIGNTEXT32 - MOVSS ( M(0), XMM1 ) /* m0 */ - MOVSS ( M(5), XMM2 ) /* m5 */ - UNPCKLPS ( XMM2, XMM1 ) /* m5 | m0 */ - MOVLPS ( M(12), XMM2 ) /* m13 | m12 */ - -ALIGNTEXT32 -LLBL(K_GTP3P2DNRR_top): - MOVLPS( S(0), XMM0 ) /* oy | ox */ - MULPS( XMM1, XMM0 ) /* oy*m5 | ox*m0 */ - ADDPS( XMM2, XMM0 ) /* +m13 | +m12 */ - MOVLPS( XMM0, D(0) ) /* ->D(1) | ->D(0) */ - - MOVSS( S(2), XMM0 ) - MOVSS( XMM0, D(2) ) - -LLBL(K_GTP3P2DNRR_skip): - ADD_L( CONST(16), EDI ) - ADD_L( EAX, ESI ) - CMP_L( ECX, EDI ) - JNE( LLBL(K_GTP3P2DNRR_top) ) - -LLBL(K_GTP3P2DNRR_finish): - POP_L( EDI ) - POP_L( ESI ) - RET -#undef FRAME_OFFSET - - - - -ALIGNTEXT4 -GLOBL GLNAME(_mesa_sse_transform_points3_3d) -HIDDEN(_mesa_sse_transform_points3_3d) -GLNAME(_mesa_sse_transform_points3_3d): - _CET_ENDBR -#define FRAME_OFFSET 8 - PUSH_L( ESI ) - PUSH_L( EDI ) - - MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */ - MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */ - - - MOV_L( ARG_MATRIX, EDX ) /* ptr to matrix */ - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */ - - TEST_L( ECX, ECX) - JZ( LLBL(K_GTP3P3DR_finish) ) /* count was zero; go to finish */ - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */ - OR_L( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */ - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */ - MOV_L( CONST(3), REGOFF(V4F_SIZE, EDI) ) /* set dest size */ - - SHL_L( CONST(4), ECX ) /* count *= 16 */ - MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */ - - MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */ - ADD_L( EDI, ECX ) /* count += dest ptr */ - - -ALIGNTEXT32 - MOVAPS( M(0), XMM0 ) /* m2 | m1 | m0 */ - MOVAPS( M(4), XMM1 ) /* m6 | m5 | m4 */ - MOVAPS( M(8), XMM2 ) /* m10 | m9 | m8 */ - MOVAPS( M(12), XMM3 ) /* m14 | m13 | m12 */ - -ALIGNTEXT32 -LLBL(K_GTP3P3DR_top): - MOVSS( S(0), XMM4 ) - SHUFPS( CONST(0x0), XMM4, XMM4 ) /* ox | ox | ox */ - MULPS( XMM0, XMM4 ) /* ox*m2 | ox*m1 | ox*m0 */ - - MOVSS( S(1), XMM5 ) - SHUFPS( CONST(0x0), XMM5, XMM5 ) /* oy | oy | oy */ - MULPS( XMM1, XMM5 ) /* oy*m6 | oy*m5 | oy*m4 */ - - MOVSS( S(2), XMM6 ) - SHUFPS( CONST(0x0), XMM6, XMM6 ) /* oz | oz | oz */ - MULPS( XMM2, XMM6 ) /* oz*m10 | oz*m9 | oz*m8 */ - - ADDPS( XMM5, XMM4 ) /* + | + | + */ - ADDPS( XMM6, XMM4 ) /* + | + | + */ - ADDPS( XMM3, XMM4 ) /* + | + | + */ - - MOVLPS( XMM4, D(0) ) /* => D(1) | => D(0) */ - UNPCKHPS( XMM4, XMM4 ) - MOVSS( XMM4, D(2) ) - -LLBL(K_GTP3P3DR_skip): - ADD_L( CONST(16), EDI ) - ADD_L( EAX, ESI ) - CMP_L( ECX, EDI ) - JNE( LLBL(K_GTP3P3DR_top) ) - -LLBL(K_GTP3P3DR_finish): - POP_L( EDI ) - POP_L( ESI ) - RET -#undef FRAME_OFFSET -#endif - -#if defined (__ELF__) && defined (__linux__) - .section .note.GNU-stack,"",%progbits -#endif diff --git a/src/mesa/x86/sse_xform4.S b/src/mesa/x86/sse_xform4.S deleted file mode 100644 index bd322e8..0000000 --- a/src/mesa/x86/sse_xform4.S +++ /dev/null @@ -1,236 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -#ifdef USE_SSE_ASM -#include "assyntax.h" -#define MATH_ASM_PTR_SIZE 4 -#include "math/m_vector_asm.h" -#include "xform_args.h" - - SEG_TEXT - -#define FRAME_OFFSET 8 - -#define SRC(i) REGOFF(i * 4, ESI) -#define DST(i) REGOFF(i * 4, EDI) -#define MAT(i) REGOFF(i * 4, EDX) - -#define SELECT(r0, r1, r2, r3) CONST( r0 * 64 + r1 * 16 + r2 * 4 + r3 ) - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_sse_transform_points4_general ) -HIDDEN(_mesa_sse_transform_points4_general) -GLNAME( _mesa_sse_transform_points4_general ): - _CET_ENDBR - PUSH_L( ESI ) - PUSH_L( EDI ) - - MOV_L( ARG_SOURCE, ESI ) - MOV_L( ARG_DEST, EDI ) - - MOV_L( ARG_MATRIX, EDX ) - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) - - TEST_L( ECX, ECX ) /* verify non-zero count */ - JE( LLBL( sse_general_done ) ) - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */ - OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */ - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */ - MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) )/* set dest size */ - - MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */ - MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */ - - PREFETCHT0( REGIND(ESI) ) - - MOVAPS( MAT(0), XMM4 ) /* m3 | m2 | m1 | m0 */ - MOVAPS( MAT(4), XMM5 ) /* m7 | m6 | m5 | m4 */ - MOVAPS( MAT(8), XMM6 ) /* m11 | m10 | m9 | m8 */ - MOVAPS( MAT(12), XMM7 ) /* m15 | m14 | m13 | m12 */ - -ALIGNTEXT16 -LLBL( sse_general_loop ): - - MOVSS( SRC(0), XMM0 ) /* ox */ - SHUFPS( CONST(0x0), XMM0, XMM0 ) /* ox | ox | ox | ox */ - MULPS( XMM4, XMM0 ) /* ox*m3 | ox*m2 | ox*m1 | ox*m0 */ - - MOVSS( SRC(1), XMM1 ) /* oy */ - SHUFPS( CONST(0x0), XMM1, XMM1 ) /* oy | oy | oy | oy */ - MULPS( XMM5, XMM1 ) /* oy*m7 | oy*m6 | oy*m5 | oy*m4 */ - - MOVSS( SRC(2), XMM2 ) /* oz */ - SHUFPS( CONST(0x0), XMM2, XMM2 ) /* oz | oz | oz | oz */ - MULPS( XMM6, XMM2 ) /* oz*m11 | oz*m10 | oz*m9 | oz*m8 */ - - MOVSS( SRC(3), XMM3 ) /* ow */ - SHUFPS( CONST(0x0), XMM3, XMM3 ) /* ow | ow | ow | ow */ - MULPS( XMM7, XMM3 ) /* ow*m15 | ow*m14 | ow*m13 | ow*m12 */ - - ADDPS( XMM1, XMM0 ) /* ox*m3+oy*m7 | ... */ - ADDPS( XMM2, XMM0 ) /* ox*m3+oy*m7+oz*m11 | ... */ - ADDPS( XMM3, XMM0 ) /* ox*m3+oy*m7+oz*m11+ow*m15 | ... */ - MOVAPS( XMM0, DST(0) ) /* ->D(3) | ->D(2) | ->D(1) | ->D(0) */ - - ADD_L( CONST(16), EDI ) - ADD_L( EAX, ESI ) - - DEC_L( ECX ) - JNZ( LLBL( sse_general_loop ) ) - -LLBL( sse_general_done ): - - POP_L( EDI ) - POP_L( ESI ) - RET - - - - -ALIGNTEXT4 -GLOBL GLNAME( _mesa_sse_transform_points4_3d ) -HIDDEN(_mesa_sse_transform_points4_3d) -GLNAME( _mesa_sse_transform_points4_3d ): - _CET_ENDBR - PUSH_L( ESI ) - PUSH_L( EDI ) - - MOV_L( ARG_SOURCE, ESI ) /* ptr to source GLvector4f */ - MOV_L( ARG_DEST, EDI ) /* ptr to dest GLvector4f */ - - MOV_L( ARG_MATRIX, EDX ) /* ptr to matrix */ - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */ - - TEST_L( ECX, ECX) - JZ( LLBL(K_GTP43P3DR_finish) ) /* count was zero; go to finish */ - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */ - OR_L( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */ - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */ - MOV_L( CONST(3), REGOFF(V4F_SIZE, EDI) )/* set dest size */ - - SHL_L( CONST(4), ECX ) /* count *= 16 */ - MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */ - - MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */ - ADD_L( EDI, ECX ) /* count += dest ptr */ - - MOVAPS( MAT(0), XMM0 ) /* m3 | m2 | m1 | m0 */ - MOVAPS( MAT(4), XMM1 ) /* m7 | m6 | m5 | m4 */ - MOVAPS( MAT(8), XMM2 ) /* m11 | m10 | m9 | m8 */ - MOVAPS( MAT(12), XMM3 ) /* m15 | m14 | m13 | m12 */ - -ALIGNTEXT32 -LLBL( K_GTP43P3DR_top ): - MOVSS( SRC(0), XMM4 ) /* ox */ - SHUFPS( CONST(0x0), XMM4, XMM4 ) /* ox | ox | ox | ox */ - MULPS( XMM0, XMM4 ) /* ox*m3 | ox*m2 | ox*m1 | ox*m0 */ - - MOVSS( SRC(1), XMM5 ) /* oy */ - SHUFPS( CONST(0x0), XMM5, XMM5 ) /* oy | oy | oy | oy */ - MULPS( XMM1, XMM5 ) /* oy*m7 | oy*m6 | oy*m5 | oy*m4 */ - - MOVSS( SRC(2), XMM6 ) /* oz */ - SHUFPS( CONST(0x0), XMM6, XMM6 ) /* oz | oz | oz | oz */ - MULPS( XMM2, XMM6 ) /* oz*m11 | oz*m10 | oz*m9 | oz*m8 */ - - MOVSS( SRC(3), XMM7 ) /* ow */ - SHUFPS( CONST(0x0), XMM7, XMM7 ) /* ow | ow | ow | ow */ - MULPS( XMM3, XMM7 ) /* ow*m15 | ow*m14 | ow*m13 | ow*m12 */ - - ADDPS( XMM5, XMM4 ) /* ox*m3+oy*m7 | ... */ - ADDPS( XMM6, XMM4 ) /* ox*m3+oy*m7+oz*m11 | ... */ - ADDPS( XMM7, XMM4 ) /* ox*m3+oy*m7+oz*m11+ow*m15 | ... */ - MOVAPS( XMM4, DST(0) ) /* ->D(3) | ->D(2) | ->D(1) | ->D(0) */ - - MOVSS( SRC(3), XMM4 ) /* ow */ - MOVSS( XMM4, DST(3) ) /* ->D(3) */ - -LLBL( K_GTP43P3DR_skip ): - ADD_L( CONST(16), EDI ) - ADD_L( EAX, ESI ) - CMP_L( ECX, EDI ) - JNE( LLBL(K_GTP43P3DR_top) ) - -LLBL( K_GTP43P3DR_finish ): - POP_L( EDI ) - POP_L( ESI ) - RET - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_sse_transform_points4_identity ) -HIDDEN(_mesa_sse_transform_points4_identity) -GLNAME( _mesa_sse_transform_points4_identity ): - _CET_ENDBR - PUSH_L( ESI ) - PUSH_L( EDI ) - - MOV_L( ARG_SOURCE, ESI ) - MOV_L( ARG_DEST, EDI ) - - MOV_L( ARG_MATRIX, EDX ) - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) - - TEST_L( ECX, ECX ) /* verify non-zero count */ - JE( LLBL( sse_identity_done ) ) - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */ - OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */ - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */ - MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) )/* set dest size */ - - MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */ - MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */ - -ALIGNTEXT16 -LLBL( sse_identity_loop ): - - PREFETCHNTA( REGOFF(32, ESI) ) - - MOVAPS( REGIND(ESI), XMM0 ) - ADD_L( EAX, ESI ) - - MOVAPS( XMM0, REGIND(EDI) ) - ADD_L( CONST(16), EDI ) - - DEC_L( ECX ) - JNZ( LLBL( sse_identity_loop ) ) - -LLBL( sse_identity_done ): - - POP_L( EDI ) - POP_L( ESI ) - RET -#endif - -#if defined (__ELF__) && defined (__linux__) - .section .note.GNU-stack,"",%progbits -#endif diff --git a/src/mesa/x86/x86_cliptest.S b/src/mesa/x86/x86_cliptest.S deleted file mode 100644 index 6ae64ae..0000000 --- a/src/mesa/x86/x86_cliptest.S +++ /dev/null @@ -1,408 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -/* - * NOTE: Avoid using spaces in between '(' ')' and arguments, especially - * with macros like CONST, LLBL that expand to CONCAT(...). Putting spaces - * in there will break the build on some platforms. - */ - -#include "assyntax.h" -#define MATH_ASM_PTR_SIZE 4 -#include "math/m_vector_asm.h" -#include "clip_args.h" - -#define SRC0 REGOFF(0, ESI) -#define SRC1 REGOFF(4, ESI) -#define SRC2 REGOFF(8, ESI) -#define SRC3 REGOFF(12, ESI) -#define DST0 REGOFF(0, EDI) -#define DST1 REGOFF(4, EDI) -#define DST2 REGOFF(8, EDI) -#define DST3 REGOFF(12, EDI) -#define MAT0 REGOFF(0, EDX) -#define MAT1 REGOFF(4, EDX) -#define MAT2 REGOFF(8, EDX) -#define MAT3 REGOFF(12, EDX) - - -/* - * Table for clip test. - * - * bit6 = SRC3 < 0 - * bit5 = SRC2 < 0 - * bit4 = abs(S(2)) > abs(S(3)) - * bit3 = SRC1 < 0 - * bit2 = abs(S(1)) > abs(S(3)) - * bit1 = SRC0 < 0 - * bit0 = abs(S(0)) > abs(S(3)) - */ - - SEG_DATA - -clip_table: - D_BYTE 0x00, 0x01, 0x00, 0x02, 0x04, 0x05, 0x04, 0x06 - D_BYTE 0x00, 0x01, 0x00, 0x02, 0x08, 0x09, 0x08, 0x0a - D_BYTE 0x20, 0x21, 0x20, 0x22, 0x24, 0x25, 0x24, 0x26 - D_BYTE 0x20, 0x21, 0x20, 0x22, 0x28, 0x29, 0x28, 0x2a - D_BYTE 0x00, 0x01, 0x00, 0x02, 0x04, 0x05, 0x04, 0x06 - D_BYTE 0x00, 0x01, 0x00, 0x02, 0x08, 0x09, 0x08, 0x0a - D_BYTE 0x10, 0x11, 0x10, 0x12, 0x14, 0x15, 0x14, 0x16 - D_BYTE 0x10, 0x11, 0x10, 0x12, 0x18, 0x19, 0x18, 0x1a - D_BYTE 0x3f, 0x3d, 0x3f, 0x3e, 0x37, 0x35, 0x37, 0x36 - D_BYTE 0x3f, 0x3d, 0x3f, 0x3e, 0x3b, 0x39, 0x3b, 0x3a - D_BYTE 0x2f, 0x2d, 0x2f, 0x2e, 0x27, 0x25, 0x27, 0x26 - D_BYTE 0x2f, 0x2d, 0x2f, 0x2e, 0x2b, 0x29, 0x2b, 0x2a - D_BYTE 0x3f, 0x3d, 0x3f, 0x3e, 0x37, 0x35, 0x37, 0x36 - D_BYTE 0x3f, 0x3d, 0x3f, 0x3e, 0x3b, 0x39, 0x3b, 0x3a - D_BYTE 0x1f, 0x1d, 0x1f, 0x1e, 0x17, 0x15, 0x17, 0x16 - D_BYTE 0x1f, 0x1d, 0x1f, 0x1e, 0x1b, 0x19, 0x1b, 0x1a - - - SEG_TEXT - -/* - * _mesa_x86_cliptest_points4 - * - * AL: ormask - * AH: andmask - * EBX: temp0 - * ECX: temp1 - * EDX: clipmask[] - * ESI: clip[] - * EDI: proj[] - * EBP: temp2 - */ - -#if defined(__ELF__) && defined(__PIC__) && defined(GNU_ASSEMBLER) && !defined(ELFPIC) -#define ELFPIC -#endif - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_x86_cliptest_points4 ) -HIDDEN(_mesa_x86_cliptest_points4) -GLNAME( _mesa_x86_cliptest_points4 ): - _CET_ENDBR -#ifdef ELFPIC -#define FRAME_OFFSET 20 -#else -#define FRAME_OFFSET 16 -#endif - PUSH_L( ESI ) - PUSH_L( EDI ) - PUSH_L( EBP ) - PUSH_L( EBX ) - -#ifdef ELFPIC - /* store pointer to clip_table on stack */ - CALL( LLBL(ctp4_get_eip) ) - ADD_L( CONST(_GLOBAL_OFFSET_TABLE_), EBX ) - MOV_L( REGOFF(clip_table@GOT, EBX), EBX ) - PUSH_L( EBX ) - JMP( LLBL(ctp4_clip_table_ready) ) - -LLBL(ctp4_get_eip): - /* store eip in ebx */ - MOV_L( REGIND(ESP), EBX ) - RET - -LLBL(ctp4_clip_table_ready): -#endif - - MOV_L( ARG_SOURCE, ESI ) - MOV_L( ARG_DEST, EDI ) - - MOV_L( ARG_CLIP, EDX ) - MOV_L( ARG_OR, EBX ) - - MOV_L( ARG_AND, EBP ) - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) - - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) - MOV_L( REGOFF(V4F_START, ESI), ESI ) - - OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) ) - MOV_L( EAX, ARG_SOURCE ) /* put stride in ARG_SOURCE */ - - MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) ) - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) - - MOV_L( REGOFF(V4F_START, EDI), EDI ) - ADD_L( EDX, ECX ) - - MOV_L( ECX, ARG_CLIP ) /* put clipmask + count in ARG_CLIP */ - CMP_L( ECX, EDX ) - - MOV_B( REGIND(EBX), AL ) - MOV_B( REGIND(EBP), AH ) - - JZ( LLBL(ctp4_finish) ) - -ALIGNTEXT16 -LLBL(ctp4_top): - - FLD1 /* F3 */ - FDIV_S( SRC3 ) /* GH: don't care about div-by-zero */ - - MOV_L( SRC3, EBP ) - MOV_L( SRC2, EBX ) - - XOR_L( ECX, ECX ) - ADD_L( EBP, EBP ) /* ebp = abs(S(3))*2 ; carry = sign of S(3) */ - - ADC_L( ECX, ECX ) - ADD_L( EBX, EBX ) /* ebx = abs(S(2))*2 ; carry = sign of S(2) */ - - ADC_L( ECX, ECX ) - CMP_L( EBX, EBP ) /* carry = abs(S(2))*2 > abs(S(3))*2 */ - - ADC_L( ECX, ECX ) - MOV_L( SRC1, EBX ) - - ADD_L( EBX, EBX ) /* ebx = abs(S(1))*2 ; carry = sign of S(1) */ - - ADC_L( ECX, ECX ) - CMP_L( EBX, EBP ) /* carry = abs(S(1))*2 > abs(S(3))*2 */ - - ADC_L( ECX, ECX ) - MOV_L( SRC0, EBX ) - - ADD_L( EBX, EBX ) /* ebx = abs(S(0))*2 ; carry = sign of S(0) */ - - ADC_L( ECX, ECX ) - CMP_L( EBX, EBP ) /* carry = abs(S(0))*2 > abs(S(3))*2 */ - - ADC_L( ECX, ECX ) - -#ifdef ELFPIC - MOV_L( REGIND(ESP), EBP ) /* clip_table */ - - MOV_B( REGBI(EBP, ECX), CL ) -#else - MOV_B( REGOFF(clip_table,ECX), CL ) -#endif - - OR_B( CL, AL ) - AND_B( CL, AH ) - - TEST_B( CL, CL ) - MOV_B( CL, REGIND(EDX) ) - - JZ( LLBL(ctp4_proj) ) - -LLBL(ctp4_noproj): - - FSTP( ST(0) ) /* */ - - MOV_L( CONST(0), DST0 ) - MOV_L( CONST(0), DST1 ) - MOV_L( CONST(0), DST2 ) - MOV_L( CONST(0x3f800000), DST3 ) - - JMP( LLBL(ctp4_next) ) - -LLBL(ctp4_proj): - - FLD_S( SRC0 ) /* F0 F3 */ - FMUL2( ST(1), ST0 ) - - FLD_S( SRC1 ) /* F1 F0 F3 */ - FMUL2( ST(2), ST0 ) - - FLD_S( SRC2 ) /* F2 F1 F0 F3 */ - FMUL2( ST(3), ST0 ) - - FXCH( ST(2) ) /* F0 F1 F2 F3 */ - FSTP_S( DST0 ) /* F1 F2 F3 */ - FSTP_S( DST1 ) /* F2 F3 */ - FSTP_S( DST2 ) /* F3 */ - FSTP_S( DST3 ) /* */ - -LLBL(ctp4_next): - - INC_L( EDX ) - ADD_L( CONST(16), EDI ) - - ADD_L( ARG_SOURCE, ESI ) - CMP_L( EDX, ARG_CLIP ) - - JNZ( LLBL(ctp4_top) ) - - MOV_L( ARG_OR, ECX ) - MOV_L( ARG_AND, EDX ) - - MOV_B( AL, REGIND(ECX) ) - MOV_B( AH, REGIND(EDX) ) - -LLBL(ctp4_finish): - - MOV_L( ARG_DEST, EAX ) -#ifdef ELFPIC - POP_L( ESI ) /* discard ptr to clip_table */ -#endif - POP_L( EBX ) - POP_L( EBP ) - POP_L( EDI ) - POP_L( ESI ) - - RET - - - - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_x86_cliptest_points4_np ) -HIDDEN(_mesa_x86_cliptest_points4_np) -GLNAME( _mesa_x86_cliptest_points4_np ): - _CET_ENDBR -#ifdef ELFPIC -#define FRAME_OFFSET 20 -#else -#define FRAME_OFFSET 16 -#endif - PUSH_L( ESI ) - PUSH_L( EDI ) - PUSH_L( EBP ) - PUSH_L( EBX ) - -#ifdef ELFPIC - /* store pointer to clip_table on stack */ - CALL( LLBL(ctp4_np_get_eip) ) - ADD_L( CONST(_GLOBAL_OFFSET_TABLE_), EBX ) - MOV_L( REGOFF(clip_table@GOT, EBX), EBX ) - PUSH_L( EBX ) - JMP( LLBL(ctp4_np_clip_table_ready) ) - -LLBL(ctp4_np_get_eip): - /* store eip in ebx */ - MOV_L( REGIND(ESP), EBX ) - RET - -LLBL(ctp4_np_clip_table_ready): -#endif - - MOV_L( ARG_SOURCE, ESI ) - /* slot */ - - MOV_L( ARG_CLIP, EDX ) - MOV_L( ARG_OR, EBX ) - - MOV_L( ARG_AND, EBP ) - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) - - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) - MOV_L( REGOFF(V4F_START, ESI), ESI ) - - MOV_L( EAX, ARG_DEST ) /* put stride in ARG_DEST */ - ADD_L( EDX, ECX ) - - MOV_L( ECX, EDI ) /* put clipmask + count in EDI */ - CMP_L( ECX, EDX ) - - MOV_B( REGIND(EBX), AL ) - MOV_B( REGIND(EBP), AH ) - - JZ( LLBL(ctp4_np_finish) ) - -ALIGNTEXT16 -LLBL(ctp4_np_top): - - MOV_L( SRC3, EBP ) - MOV_L( SRC2, EBX ) - - XOR_L( ECX, ECX ) - ADD_L( EBP, EBP ) /* ebp = abs(S(3))*2 ; carry = sign of S(3) */ - - ADC_L( ECX, ECX ) - ADD_L( EBX, EBX ) /* ebx = abs(S(2))*2 ; carry = sign of S(2) */ - - ADC_L( ECX, ECX ) - CMP_L( EBX, EBP ) /* carry = abs(S(2))*2 > abs(S(3))*2 */ - - ADC_L( ECX, ECX ) - MOV_L( SRC1, EBX ) - - ADD_L( EBX, EBX ) /* ebx = abs(S(1))*2 ; carry = sign of S(1) */ - - ADC_L( ECX, ECX ) - CMP_L( EBX, EBP ) /* carry = abs(S(1))*2 > abs(S(3))*2 */ - - ADC_L( ECX, ECX ) - MOV_L( SRC0, EBX ) - - ADD_L( EBX, EBX ) /* ebx = abs(S(0))*2 ; carry = sign of S(0) */ - - ADC_L( ECX, ECX ) - CMP_L( EBX, EBP ) /* carry = abs(S(0))*2 > abs(S(3))*2 */ - - ADC_L( ECX, ECX ) - -#ifdef ELFPIC - MOV_L( REGIND(ESP), EBP ) /* clip_table */ - - MOV_B( REGBI(EBP, ECX), CL ) -#else - MOV_B( REGOFF(clip_table,ECX), CL ) -#endif - - OR_B( CL, AL ) - AND_B( CL, AH ) - - TEST_B( CL, CL ) - MOV_B( CL, REGIND(EDX) ) - - INC_L( EDX ) - /* slot */ - - ADD_L( ARG_DEST, ESI ) - CMP_L( EDX, EDI ) - - JNZ( LLBL(ctp4_np_top) ) - - MOV_L( ARG_OR, ECX ) - MOV_L( ARG_AND, EDX ) - - MOV_B( AL, REGIND(ECX) ) - MOV_B( AH, REGIND(EDX) ) - -LLBL(ctp4_np_finish): - - MOV_L( ARG_SOURCE, EAX ) -#ifdef ELFPIC - POP_L( ESI ) /* discard ptr to clip_table */ -#endif - POP_L( EBX ) - POP_L( EBP ) - POP_L( EDI ) - POP_L( ESI ) - - RET - -#if defined (__ELF__) && defined (__linux__) - .section .note.GNU-stack,"",%progbits -#endif diff --git a/src/mesa/x86/x86_xform.c b/src/mesa/x86/x86_xform.c deleted file mode 100644 index 8b5cf91..0000000 --- a/src/mesa/x86/x86_xform.c +++ /dev/null @@ -1,126 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -/* - * Intel x86 assembly code by Josh Vanderhoof - */ - -#include "main/glheader.h" -#include "main/context.h" -#include "math/m_xform.h" - -#include "x86_xform.h" -#include "common_x86_asm.h" - -#ifdef USE_X86_ASM -#ifdef USE_3DNOW_ASM -#include "3dnow.h" -#endif -#ifdef USE_SSE_ASM -#include "sse.h" -#endif -#endif - -#ifdef DEBUG_MATH -#include "math/m_debug.h" -#endif - - -#ifdef USE_X86_ASM -DECLARE_XFORM_GROUP( x86, 2 ) -DECLARE_XFORM_GROUP( x86, 3 ) -DECLARE_XFORM_GROUP( x86, 4 ) - - -extern GLvector4f * -_mesa_x86_cliptest_points4( GLvector4f *clip_vec, - GLvector4f *proj_vec, - GLubyte clipMask[], - GLubyte *orMask, - GLubyte *andMask, - GLboolean viewport_z_clip ); - -extern GLvector4f * -_mesa_x86_cliptest_points4_np( GLvector4f *clip_vec, - GLvector4f *proj_vec, - GLubyte clipMask[], - GLubyte *orMask, - GLubyte *andMask, - GLboolean viewport_z_clip ); - -extern void -_mesa_v16_x86_cliptest_points4( GLfloat *first_vert, - GLfloat *last_vert, - GLubyte *or_mask, - GLubyte *and_mask, - GLubyte *clip_mask, - GLboolean viewport_z_clip ); - -extern void -_mesa_v16_x86_general_xform( GLfloat *dest, - const GLfloat *m, - const GLfloat *src, - GLuint src_stride, - GLuint count ); -#endif - - -#ifdef USE_X86_ASM -static void _mesa_init_x86_transform_asm( void ) -{ - ASSIGN_XFORM_GROUP( x86, 2 ); - ASSIGN_XFORM_GROUP( x86, 3 ); - ASSIGN_XFORM_GROUP( x86, 4 ); - - _mesa_clip_tab[4] = _mesa_x86_cliptest_points4; - _mesa_clip_np_tab[4] = _mesa_x86_cliptest_points4_np; - -#ifdef DEBUG_MATH - _math_test_all_transform_functions( "x86" ); - _math_test_all_cliptest_functions( "x86" ); -#endif -} -#endif - - -void _mesa_init_all_x86_transform_asm( void ) -{ - _mesa_get_x86_features(); - -#ifdef USE_X86_ASM - if ( _mesa_x86_cpu_features ) { - _mesa_init_x86_transform_asm(); - } - - if (cpu_has_3dnow) { - _mesa_init_3dnow_transform_asm(); - } - - if ( cpu_has_xmm ) { - _mesa_init_sse_transform_asm(); - } - -#endif -} diff --git a/src/mesa/x86/x86_xform.h b/src/mesa/x86/x86_xform.h deleted file mode 100644 index e398f64..0000000 --- a/src/mesa/x86/x86_xform.h +++ /dev/null @@ -1,106 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - * - * Authors: - * Gareth Hughes - */ - -#ifndef X86_XFORM_H -#define X86_XFORM_H - - -/* ============================================================= - * Transformation function declarations: - */ - -#define XFORM_ARGS GLvector4f *to_vec, \ - const GLfloat m[16], \ - const GLvector4f *from_vec - -#define DECLARE_XFORM_GROUP( pfx, sz ) \ -extern void _mesa_##pfx##_transform_points##sz##_general( XFORM_ARGS ); \ -extern void _mesa_##pfx##_transform_points##sz##_identity( XFORM_ARGS ); \ -extern void _mesa_##pfx##_transform_points##sz##_3d_no_rot( XFORM_ARGS ); \ -extern void _mesa_##pfx##_transform_points##sz##_perspective( XFORM_ARGS ); \ -extern void _mesa_##pfx##_transform_points##sz##_2d( XFORM_ARGS ); \ -extern void _mesa_##pfx##_transform_points##sz##_2d_no_rot( XFORM_ARGS ); \ -extern void _mesa_##pfx##_transform_points##sz##_3d( XFORM_ARGS ); - -#define ASSIGN_XFORM_GROUP( pfx, sz ) \ - _mesa_transform_tab[sz][MATRIX_GENERAL] = \ - _mesa_##pfx##_transform_points##sz##_general; \ - _mesa_transform_tab[sz][MATRIX_IDENTITY] = \ - _mesa_##pfx##_transform_points##sz##_identity; \ - _mesa_transform_tab[sz][MATRIX_3D_NO_ROT] = \ - _mesa_##pfx##_transform_points##sz##_3d_no_rot; \ - _mesa_transform_tab[sz][MATRIX_PERSPECTIVE] = \ - _mesa_##pfx##_transform_points##sz##_perspective; \ - _mesa_transform_tab[sz][MATRIX_2D] = \ - _mesa_##pfx##_transform_points##sz##_2d; \ - _mesa_transform_tab[sz][MATRIX_2D_NO_ROT] = \ - _mesa_##pfx##_transform_points##sz##_2d_no_rot; \ - _mesa_transform_tab[sz][MATRIX_3D] = \ - _mesa_##pfx##_transform_points##sz##_3d; - - -/* ============================================================= - * Normal transformation function declarations: - */ - -#define NORM_ARGS const GLmatrix *mat, \ - GLfloat scale, \ - const GLvector4f *in, \ - const GLfloat *lengths, \ - GLvector4f *dest - -#define DECLARE_NORM_GROUP( pfx ) \ -extern void _mesa_##pfx##_rescale_normals( NORM_ARGS ); \ -extern void _mesa_##pfx##_normalize_normals( NORM_ARGS ); \ -extern void _mesa_##pfx##_transform_normals( NORM_ARGS ); \ -extern void _mesa_##pfx##_transform_normals_no_rot( NORM_ARGS ); \ -extern void _mesa_##pfx##_transform_rescale_normals( NORM_ARGS ); \ -extern void _mesa_##pfx##_transform_rescale_normals_no_rot( NORM_ARGS ); \ -extern void _mesa_##pfx##_transform_normalize_normals( NORM_ARGS ); \ -extern void _mesa_##pfx##_transform_normalize_normals_no_rot( NORM_ARGS ); - -#define ASSIGN_NORM_GROUP( pfx ) \ - _mesa_normal_tab[NORM_RESCALE] = \ - _mesa_##pfx##_rescale_normals; \ - _mesa_normal_tab[NORM_NORMALIZE] = \ - _mesa_##pfx##_normalize_normals; \ - _mesa_normal_tab[NORM_TRANSFORM] = \ - _mesa_##pfx##_transform_normals; \ - _mesa_normal_tab[NORM_TRANSFORM_NO_ROT] = \ - _mesa_##pfx##_transform_normals_no_rot; \ - _mesa_normal_tab[NORM_TRANSFORM | NORM_RESCALE] = \ - _mesa_##pfx##_transform_rescale_normals; \ - _mesa_normal_tab[NORM_TRANSFORM_NO_ROT | NORM_RESCALE] = \ - _mesa_##pfx##_transform_rescale_normals_no_rot; \ - _mesa_normal_tab[NORM_TRANSFORM | NORM_NORMALIZE] = \ - _mesa_##pfx##_transform_normalize_normals; \ - _mesa_normal_tab[NORM_TRANSFORM_NO_ROT | NORM_NORMALIZE] = \ - _mesa_##pfx##_transform_normalize_normals_no_rot; - - -#endif diff --git a/src/mesa/x86/x86_xform2.S b/src/mesa/x86/x86_xform2.S deleted file mode 100644 index fb1b4be..0000000 --- a/src/mesa/x86/x86_xform2.S +++ /dev/null @@ -1,575 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -/* - * NOTE: Avoid using spaces in between '(' ')' and arguments, especially - * with macros like CONST, LLBL that expand to CONCAT(...). Putting spaces - * in there will break the build on some platforms. - */ - -#include "assyntax.h" -#define MATH_ASM_PTR_SIZE 4 -#include "math/m_vector_asm.h" -#include "xform_args.h" - - SEG_TEXT - -#define FP_ONE 1065353216 -#define FP_ZERO 0 - -#define SRC0 REGOFF(0, ESI) -#define SRC1 REGOFF(4, ESI) -#define SRC2 REGOFF(8, ESI) -#define SRC3 REGOFF(12, ESI) -#define DST0 REGOFF(0, EDI) -#define DST1 REGOFF(4, EDI) -#define DST2 REGOFF(8, EDI) -#define DST3 REGOFF(12, EDI) -#define MAT0 REGOFF(0, EDX) -#define MAT1 REGOFF(4, EDX) -#define MAT2 REGOFF(8, EDX) -#define MAT3 REGOFF(12, EDX) -#define MAT4 REGOFF(16, EDX) -#define MAT5 REGOFF(20, EDX) -#define MAT6 REGOFF(24, EDX) -#define MAT7 REGOFF(28, EDX) -#define MAT8 REGOFF(32, EDX) -#define MAT9 REGOFF(36, EDX) -#define MAT10 REGOFF(40, EDX) -#define MAT11 REGOFF(44, EDX) -#define MAT12 REGOFF(48, EDX) -#define MAT13 REGOFF(52, EDX) -#define MAT14 REGOFF(56, EDX) -#define MAT15 REGOFF(60, EDX) - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_x86_transform_points2_general ) -HIDDEN(_mesa_x86_transform_points2_general) -GLNAME( _mesa_x86_transform_points2_general ): - -#define FRAME_OFFSET 8 - PUSH_L( ESI ) - PUSH_L( EDI ) - - MOV_L( ARG_SOURCE, ESI ) - MOV_L( ARG_DEST, EDI ) - - MOV_L( ARG_MATRIX, EDX ) - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) - - TEST_L( ECX, ECX ) - JZ( LLBL(x86_p2_gr_done) ) - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) - OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) ) - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) - MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) ) - - SHL_L( CONST(4), ECX ) - MOV_L( REGOFF(V4F_START, ESI), ESI ) - - MOV_L( REGOFF(V4F_START, EDI), EDI ) - ADD_L( EDI, ECX ) - -ALIGNTEXT16 -LLBL(x86_p2_gr_loop): - - FLD_S( SRC0 ) /* F4 */ - FMUL_S( MAT0 ) - FLD_S( SRC0 ) /* F5 F4 */ - FMUL_S( MAT1 ) - FLD_S( SRC0 ) /* F6 F5 F4 */ - FMUL_S( MAT2 ) - FLD_S( SRC0 ) /* F7 F6 F5 F4 */ - FMUL_S( MAT3 ) - - FLD_S( SRC1 ) /* F0 F7 F6 F5 F4 */ - FMUL_S( MAT4 ) - FLD_S( SRC1 ) /* F1 F0 F7 F6 F5 F4 */ - FMUL_S( MAT5 ) - FLD_S( SRC1 ) /* F2 F1 F0 F7 F6 F5 F4 */ - FMUL_S( MAT6 ) - FLD_S( SRC1 ) /* F3 F2 F1 F0 F7 F6 F5 F4 */ - FMUL_S( MAT7 ) - - FXCH( ST(3) ) /* F0 F2 F1 F3 F7 F6 F5 F4 */ - FADDP( ST0, ST(7) ) /* F2 F1 F3 F7 F6 F5 F4 */ - FXCH( ST(1) ) /* F1 F2 F3 F7 F6 F5 F4 */ - FADDP( ST0, ST(5) ) /* F2 F3 F7 F6 F5 F4 */ - FADDP( ST0, ST(3) ) /* F3 F7 F6 F5 F4 */ - FADDP( ST0, ST(1) ) /* F7 F6 F5 F4 */ - - FXCH( ST(3) ) /* F4 F6 F5 F7 */ - FADD_S( MAT12 ) - FXCH( ST(2) ) /* F5 F6 F4 F7 */ - FADD_S( MAT13 ) - FXCH( ST(1) ) /* F6 F5 F4 F7 */ - FADD_S( MAT14 ) - FXCH( ST(3) ) /* F7 F5 F4 F6 */ - FADD_S( MAT15 ) - - FXCH( ST(2) ) /* F4 F5 F7 F6 */ - FSTP_S( DST0 ) /* F5 F7 F6 */ - FSTP_S( DST1 ) /* F7 F6 */ - FXCH( ST(1) ) /* F6 F7 */ - FSTP_S( DST2 ) /* F7 */ - FSTP_S( DST3 ) /* */ - -LLBL(x86_p2_gr_skip): - - ADD_L( CONST(16), EDI ) - ADD_L( EAX, ESI ) - CMP_L( ECX, EDI ) - JNE( LLBL(x86_p2_gr_loop) ) - -LLBL(x86_p2_gr_done): - - POP_L( EDI ) - POP_L( ESI ) - RET -#undef FRAME_OFFSET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_x86_transform_points2_perspective ) -HIDDEN(_mesa_x86_transform_points2_perspective) -GLNAME( _mesa_x86_transform_points2_perspective ): - -#define FRAME_OFFSET 12 - PUSH_L( ESI ) - PUSH_L( EDI ) - PUSH_L( EBX ) - - MOV_L( ARG_SOURCE, ESI ) - MOV_L( ARG_DEST, EDI ) - - MOV_L( ARG_MATRIX, EDX ) - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) - - TEST_L( ECX, ECX ) - JZ( LLBL(x86_p2_pr_done) ) - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) - OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) ) - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) - MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) ) - - SHL_L( CONST(4), ECX ) - MOV_L( REGOFF(V4F_START, ESI), ESI ) - - MOV_L( REGOFF(V4F_START, EDI), EDI ) - ADD_L( EDI, ECX ) - - MOV_L( MAT14, EBX ) - -ALIGNTEXT16 -LLBL(x86_p2_pr_loop): - - FLD_S( SRC0 ) /* F4 */ - FMUL_S( MAT0 ) - - FLD_S( SRC1 ) /* F1 F4 */ - FMUL_S( MAT5 ) - - FXCH( ST(1) ) /* F4 F1 */ - FSTP_S( DST0 ) /* F1 */ - FSTP_S( DST1 ) /* */ - MOV_L( EBX, DST2 ) - MOV_L( CONST(FP_ZERO), DST3 ) - -LLBL(x86_p2_pr_skip): - - ADD_L( CONST(16), EDI ) - ADD_L( EAX, ESI ) - CMP_L( ECX, EDI ) - JNE( LLBL(x86_p2_pr_loop) ) - -LLBL(x86_p2_pr_done): - - POP_L( EBX ) - POP_L( EDI ) - POP_L( ESI ) - RET -#undef FRAME_OFFSET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_x86_transform_points2_3d ) -HIDDEN(_mesa_x86_transform_points2_3d) -GLNAME( _mesa_x86_transform_points2_3d ): - -#define FRAME_OFFSET 8 - PUSH_L( ESI ) - PUSH_L( EDI ) - - MOV_L( ARG_SOURCE, ESI ) - MOV_L( ARG_DEST, EDI ) - - MOV_L( ARG_MATRIX, EDX ) - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) - - TEST_L( ECX, ECX ) - JZ( LLBL(x86_p2_3dr_done) ) - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) - OR_L( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, EDI) ) - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) - MOV_L( CONST(3), REGOFF(V4F_SIZE, EDI) ) - - SHL_L( CONST(4), ECX ) - MOV_L( REGOFF(V4F_START, ESI), ESI ) - - MOV_L( REGOFF(V4F_START, EDI), EDI ) - ADD_L( EDI, ECX ) - -ALIGNTEXT16 -LLBL(x86_p2_3dr_loop): - - FLD_S( SRC0 ) /* F4 */ - FMUL_S( MAT0 ) - FLD_S( SRC0 ) /* F5 F4 */ - FMUL_S( MAT1 ) - FLD_S( SRC0 ) /* F6 F5 F4 */ - FMUL_S( MAT2 ) - - FLD_S( SRC1 ) /* F0 F6 F5 F4 */ - FMUL_S( MAT4 ) - FLD_S( SRC1 ) /* F1 F0 F6 F5 F4 */ - FMUL_S( MAT5 ) - FLD_S( SRC1 ) /* F2 F1 F0 F6 F5 F4 */ - FMUL_S( MAT6 ) - - FXCH( ST(2) ) /* F0 F1 F2 F6 F5 F4 */ - FADDP( ST0, ST(5) ) /* F1 F2 F6 F5 F4 */ - FADDP( ST0, ST(3) ) /* F2 F6 F5 F4 */ - FADDP( ST0, ST(1) ) /* F6 F5 F4 */ - - FXCH( ST(2) ) /* F4 F5 F6 */ - FADD_S( MAT12 ) - FXCH( ST(1) ) /* F5 F4 F6 */ - FADD_S( MAT13 ) - FXCH( ST(2) ) /* F6 F4 F5 */ - FADD_S( MAT14 ) - - FXCH( ST(1) ) /* F4 F6 F5 */ - FSTP_S( DST0 ) /* F6 F5 */ - FXCH( ST(1) ) /* F5 F6 */ - FSTP_S( DST1 ) /* F6 */ - FSTP_S( DST2 ) /* */ - -LLBL(x86_p2_3dr_skip): - - ADD_L( CONST(16), EDI ) - ADD_L( EAX, ESI ) - CMP_L( ECX, EDI ) - JNE( LLBL(x86_p2_3dr_loop) ) - -LLBL(x86_p2_3dr_done): - - POP_L( EDI ) - POP_L( ESI ) - RET -#undef FRAME_OFFSET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_x86_transform_points2_3d_no_rot ) -HIDDEN(_mesa_x86_transform_points2_3d_no_rot) -GLNAME( _mesa_x86_transform_points2_3d_no_rot ): - -#define FRAME_OFFSET 12 - PUSH_L( ESI ) - PUSH_L( EDI ) - PUSH_L( EBX ) - - MOV_L( ARG_SOURCE, ESI ) - MOV_L( ARG_DEST, EDI ) - - MOV_L( ARG_MATRIX, EDX ) - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) - - TEST_L( ECX, ECX ) - JZ( LLBL(x86_p2_3dnrr_done) ) - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) - OR_L( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, EDI) ) - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) - MOV_L( CONST(3), REGOFF(V4F_SIZE, EDI) ) - - SHL_L( CONST(4), ECX ) - MOV_L( REGOFF(V4F_START, ESI), ESI ) - - MOV_L( REGOFF(V4F_START, EDI), EDI ) - ADD_L( EDI, ECX ) - - MOV_L( MAT14, EBX ) - -ALIGNTEXT16 -LLBL(x86_p2_3dnrr_loop): - - FLD_S( SRC0 ) /* F4 */ - FMUL_S( MAT0 ) - - FLD_S( SRC1 ) /* F1 F4 */ - FMUL_S( MAT5 ) - - FXCH( ST(1) ) /* F4 F1 */ - FADD_S( MAT12 ) - FLD_S( MAT13 ) /* F5 F4 F1 */ - FXCH( ST(2) ) /* F1 F4 F5 */ - FADDP( ST0, ST(2) ) /* F4 F5 */ - - FSTP_S( DST0 ) /* F5 */ - FSTP_S( DST1 ) /* */ - MOV_L( EBX, DST2 ) - -LLBL(x86_p2_3dnrr_skip): - - ADD_L( CONST(16), EDI ) - ADD_L( EAX, ESI ) - CMP_L( ECX, EDI ) - JNE( LLBL(x86_p2_3dnrr_loop) ) - -LLBL(x86_p2_3dnrr_done): - - POP_L( EBX ) - POP_L( EDI ) - POP_L( ESI ) - RET -#undef FRAME_OFFSET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_x86_transform_points2_2d ) -HIDDEN(_mesa_x86_transform_points2_2d) -GLNAME( _mesa_x86_transform_points2_2d ): - -#define FRAME_OFFSET 8 - PUSH_L( ESI ) - PUSH_L( EDI ) - - MOV_L( ARG_SOURCE, ESI ) - MOV_L( ARG_DEST, EDI ) - - MOV_L( ARG_MATRIX, EDX ) - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) - - TEST_L( ECX, ECX ) - JZ( LLBL(x86_p2_2dr_done) ) - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) - OR_L( CONST(VEC_SIZE_2), REGOFF(V4F_FLAGS, EDI) ) - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) - MOV_L( CONST(2), REGOFF(V4F_SIZE, EDI) ) - - SHL_L( CONST(4), ECX ) - MOV_L( REGOFF(V4F_START, ESI), ESI ) - - MOV_L( REGOFF(V4F_START, EDI), EDI ) - ADD_L( EDI, ECX ) - -ALIGNTEXT16 -LLBL(x86_p2_2dr_loop): - - FLD_S( SRC0 ) /* F4 */ - FMUL_S( MAT0 ) - FLD_S( SRC0 ) /* F5 F4 */ - FMUL_S( MAT1 ) - - FLD_S( SRC1 ) /* F0 F5 F4 */ - FMUL_S( MAT4 ) - FLD_S( SRC1 ) /* F1 F0 F5 F4 */ - FMUL_S( MAT5 ) - - FXCH( ST(1) ) /* F0 F1 F5 F4 */ - FADDP( ST0, ST(3) ) /* F1 F5 F4 */ - FADDP( ST0, ST(1) ) /* F5 F4 */ - - FXCH( ST(1) ) /* F4 F5 */ - FADD_S( MAT12 ) - FXCH( ST(1) ) /* F5 F4 */ - FADD_S( MAT13 ) - - FXCH( ST(1) ) /* F4 F5 */ - FSTP_S( DST0 ) /* F5 */ - FSTP_S( DST1 ) /* */ - -LLBL(x86_p2_2dr_skip): - - ADD_L( CONST(16), EDI ) - ADD_L( EAX, ESI ) - CMP_L( ECX, EDI ) - JNE( LLBL(x86_p2_2dr_loop) ) - -LLBL(x86_p2_2dr_done): - - POP_L( EDI ) - POP_L( ESI ) - RET -#undef FRAME_OFFSET - - - - -ALIGNTEXT4 -GLOBL GLNAME( _mesa_x86_transform_points2_2d_no_rot ) -HIDDEN(_mesa_x86_transform_points2_2d_no_rot) -GLNAME( _mesa_x86_transform_points2_2d_no_rot ): - -#define FRAME_OFFSET 8 - PUSH_L( ESI ) - PUSH_L( EDI ) - - MOV_L( ARG_SOURCE, ESI ) - MOV_L( ARG_DEST, EDI ) - - MOV_L( ARG_MATRIX, EDX ) - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) - - TEST_L( ECX, ECX ) - JZ( LLBL(x86_p2_2dnrr_done) ) - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) - OR_L( CONST(VEC_SIZE_2), REGOFF(V4F_FLAGS, EDI) ) - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) - MOV_L( CONST(2), REGOFF(V4F_SIZE, EDI) ) - - SHL_L( CONST(4), ECX ) - MOV_L( REGOFF(V4F_START, ESI), ESI ) - - MOV_L( REGOFF(V4F_START, EDI), EDI ) - ADD_L( EDI, ECX ) - -ALIGNTEXT16 -LLBL(x86_p2_2dnrr_loop): - - FLD_S( SRC0 ) /* F4 */ - FMUL_S( MAT0 ) - - FLD_S( SRC1 ) /* F1 F4 */ - FMUL_S( MAT5 ) - - FXCH( ST(1) ) /* F4 F1 */ - FADD_S( MAT12 ) - FLD_S( MAT13 ) /* F5 F4 F1 */ - FXCH( ST(2) ) /* F1 F4 F5 */ - FADDP( ST0, ST(2) ) /* F4 F5 */ - - FSTP_S( DST0 ) /* F5 */ - FSTP_S( DST1 ) /* */ - -LLBL(x86_p2_2dnrr_skip): - - ADD_L( CONST(16), EDI ) - ADD_L( EAX, ESI ) - CMP_L( ECX, EDI ) - JNE( LLBL(x86_p2_2dnrr_loop) ) - -LLBL(x86_p2_2dnrr_done): - - POP_L( EDI ) - POP_L( ESI ) - RET -#undef FRAME_OFFSET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_x86_transform_points2_identity ) -HIDDEN(_mesa_x86_transform_points2_identity) -GLNAME( _mesa_x86_transform_points2_identity ): - -#define FRAME_OFFSET 12 - PUSH_L( ESI ) - PUSH_L( EDI ) - PUSH_L( EBX ) - - MOV_L( ARG_SOURCE, ESI ) - MOV_L( ARG_DEST, EDI ) - - MOV_L( ARG_MATRIX, EDX ) - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) - - TEST_L( ECX, ECX ) - JZ( LLBL(x86_p2_ir_done) ) - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) - OR_L( CONST(VEC_SIZE_2), REGOFF(V4F_FLAGS, EDI) ) - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) - MOV_L( CONST(2), REGOFF(V4F_SIZE, EDI) ) - - SHL_L( CONST(4), ECX ) - MOV_L( REGOFF(V4F_START, ESI), ESI ) - - MOV_L( REGOFF(V4F_START, EDI), EDI ) - ADD_L( EDI, ECX ) - - CMP_L( ESI, EDI ) - JE( LLBL(x86_p2_ir_done) ) - -ALIGNTEXT16 -LLBL(x86_p2_ir_loop): - - MOV_L( SRC0, EBX ) - MOV_L( SRC1, EDX ) - - MOV_L( EBX, DST0 ) - MOV_L( EDX, DST1 ) - -LLBL(x86_p2_ir_skip): - - ADD_L( CONST(16), EDI ) - ADD_L( EAX, ESI ) - CMP_L( ECX, EDI ) - JNE( LLBL(x86_p2_ir_loop) ) - -LLBL(x86_p2_ir_done): - - POP_L( EBX ) - POP_L( EDI ) - POP_L( ESI ) - RET -#undef FRAME_OFFSET - -#if defined (__ELF__) && defined (__linux__) - .section .note.GNU-stack,"",%progbits -#endif diff --git a/src/mesa/x86/x86_xform3.S b/src/mesa/x86/x86_xform3.S deleted file mode 100644 index 6d2d518..0000000 --- a/src/mesa/x86/x86_xform3.S +++ /dev/null @@ -1,645 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -/* - * NOTE: Avoid using spaces in between '(' ')' and arguments, especially - * with macros like CONST, LLBL that expand to CONCAT(...). Putting spaces - * in there will break the build on some platforms. - */ - -#include "assyntax.h" -#define MATH_ASM_PTR_SIZE 4 -#include "math/m_vector_asm.h" -#include "xform_args.h" - - SEG_TEXT - -#define FP_ONE 1065353216 -#define FP_ZERO 0 - -#define SRC0 REGOFF(0, ESI) -#define SRC1 REGOFF(4, ESI) -#define SRC2 REGOFF(8, ESI) -#define SRC3 REGOFF(12, ESI) -#define DST0 REGOFF(0, EDI) -#define DST1 REGOFF(4, EDI) -#define DST2 REGOFF(8, EDI) -#define DST3 REGOFF(12, EDI) -#define MAT0 REGOFF(0, EDX) -#define MAT1 REGOFF(4, EDX) -#define MAT2 REGOFF(8, EDX) -#define MAT3 REGOFF(12, EDX) -#define MAT4 REGOFF(16, EDX) -#define MAT5 REGOFF(20, EDX) -#define MAT6 REGOFF(24, EDX) -#define MAT7 REGOFF(28, EDX) -#define MAT8 REGOFF(32, EDX) -#define MAT9 REGOFF(36, EDX) -#define MAT10 REGOFF(40, EDX) -#define MAT11 REGOFF(44, EDX) -#define MAT12 REGOFF(48, EDX) -#define MAT13 REGOFF(52, EDX) -#define MAT14 REGOFF(56, EDX) -#define MAT15 REGOFF(60, EDX) - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_x86_transform_points3_general ) -HIDDEN(_mesa_x86_transform_points3_general) -GLNAME( _mesa_x86_transform_points3_general ): - -#define FRAME_OFFSET 8 - PUSH_L( ESI ) - PUSH_L( EDI ) - - MOV_L( ARG_SOURCE, ESI ) - MOV_L( ARG_DEST, EDI ) - - MOV_L( ARG_MATRIX, EDX ) - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) - - TEST_L( ECX, ECX ) - JZ( LLBL(x86_p3_gr_done) ) - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) - OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) ) - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) - MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) ) - - SHL_L( CONST(4), ECX ) - MOV_L( REGOFF(V4F_START, ESI), ESI ) - - MOV_L( REGOFF(V4F_START, EDI), EDI ) - ADD_L( EDI, ECX ) - -ALIGNTEXT16 -LLBL(x86_p3_gr_loop): - - FLD_S( SRC0 ) /* F4 */ - FMUL_S( MAT0 ) - FLD_S( SRC0 ) /* F5 F4 */ - FMUL_S( MAT1 ) - FLD_S( SRC0 ) /* F6 F5 F4 */ - FMUL_S( MAT2 ) - FLD_S( SRC0 ) /* F7 F6 F5 F4 */ - FMUL_S( MAT3 ) - - FLD_S( SRC1 ) /* F0 F7 F6 F5 F4 */ - FMUL_S( MAT4 ) - FLD_S( SRC1 ) /* F1 F0 F7 F6 F5 F4 */ - FMUL_S( MAT5 ) - FLD_S( SRC1 ) /* F2 F1 F0 F7 F6 F5 F4 */ - FMUL_S( MAT6 ) - FLD_S( SRC1 ) /* F3 F2 F1 F0 F7 F6 F5 F4 */ - FMUL_S( MAT7 ) - - FXCH( ST(3) ) /* F0 F2 F1 F3 F7 F6 F5 F4 */ - FADDP( ST0, ST(7) ) /* F2 F1 F3 F7 F6 F5 F4 */ - FXCH( ST(1) ) /* F1 F2 F3 F7 F6 F5 F4 */ - FADDP( ST0, ST(5) ) /* F2 F3 F7 F6 F5 F4 */ - FADDP( ST0, ST(3) ) /* F3 F7 F6 F5 F4 */ - FADDP( ST0, ST(1) ) /* F7 F6 F5 F4 */ - - FLD_S( SRC2 ) /* F0 F7 F6 F5 F4 */ - FMUL_S( MAT8 ) - FLD_S( SRC2 ) /* F1 F0 F7 F6 F5 F4 */ - FMUL_S( MAT9 ) - FLD_S( SRC2 ) /* F2 F1 F0 F7 F6 F5 F4 */ - FMUL_S( MAT10 ) - FLD_S( SRC2 ) /* F3 F2 F1 F0 F7 F6 F5 F4 */ - FMUL_S( MAT11 ) - - FXCH( ST(3) ) /* F0 F2 F1 F3 F7 F6 F5 F4 */ - FADDP( ST0, ST(7) ) /* F2 F1 F3 F7 F6 F5 F4 */ - FXCH( ST(1) ) /* F1 F2 F3 F7 F6 F5 F4 */ - FADDP( ST0, ST(5) ) /* F2 F3 F7 F6 F5 F4 */ - FADDP( ST0, ST(3) ) /* F3 F7 F6 F5 F4 */ - FADDP( ST0, ST(1) ) /* F7 F6 F5 F4 */ - - FXCH( ST(3) ) /* F4 F6 F5 F7 */ - FADD_S( MAT12 ) - FXCH( ST(2) ) /* F5 F6 F4 F7 */ - FADD_S( MAT13 ) - FXCH( ST(1) ) /* F6 F5 F4 F7 */ - FADD_S( MAT14 ) - FXCH( ST(3) ) /* F7 F5 F4 F6 */ - FADD_S( MAT15 ) - - FXCH( ST(2) ) /* F4 F5 F7 F6 */ - FSTP_S( DST0 ) /* F5 F7 F6 */ - FSTP_S( DST1 ) /* F7 F6 */ - FXCH( ST(1) ) /* F6 F7 */ - FSTP_S( DST2 ) /* F7 */ - FSTP_S( DST3 ) /* */ - -LLBL(x86_p3_gr_skip): - - ADD_L( CONST(16), EDI ) - ADD_L( EAX, ESI ) - CMP_L( ECX, EDI ) - JNE( LLBL(x86_p3_gr_loop) ) - -LLBL(x86_p3_gr_done): - - POP_L( EDI ) - POP_L( ESI ) - RET -#undef FRAME_OFFSET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_x86_transform_points3_perspective ) -HIDDEN(_mesa_x86_transform_points3_perspective) -GLNAME( _mesa_x86_transform_points3_perspective ): - -#define FRAME_OFFSET 12 - PUSH_L( ESI ) - PUSH_L( EDI ) - PUSH_L( EBX ) - - MOV_L( ARG_SOURCE, ESI ) - MOV_L( ARG_DEST, EDI ) - - MOV_L( ARG_MATRIX, EDX ) - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) - - TEST_L( ECX, ECX ) - JZ( LLBL(x86_p3_pr_done) ) - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) - OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) ) - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) - MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) ) - - SHL_L( CONST(4), ECX ) - MOV_L( REGOFF(V4F_START, ESI), ESI ) - - MOV_L( REGOFF(V4F_START, EDI), EDI ) - ADD_L( EDI, ECX ) - -ALIGNTEXT16 -LLBL(x86_p3_pr_loop): - - FLD_S( SRC0 ) /* F4 */ - FMUL_S( MAT0 ) - - FLD_S( SRC1 ) /* F5 F4 */ - FMUL_S( MAT5 ) - - FLD_S( SRC2 ) /* F0 F5 F4 */ - FMUL_S( MAT8 ) - FLD_S( SRC2 ) /* F1 F0 F5 F4 */ - FMUL_S( MAT9 ) - FLD_S( SRC2 ) /* F2 F1 F0 F5 F4 */ - FMUL_S( MAT10 ) - - FXCH( ST(2) ) /* F0 F1 F2 F5 F4 */ - FADDP( ST0, ST(4) ) /* F1 F2 F5 F4 */ - FADDP( ST0, ST(2) ) /* F2 F5 F4 */ - FLD_S( MAT14 ) /* F6 F2 F5 F4 */ - FXCH( ST(1) ) /* F2 F6 F5 F4 */ - FADDP( ST0, ST(1) ) /* F6 F5 F4 */ - - MOV_L( SRC2, EBX ) - XOR_L( CONST(-2147483648), EBX )/* change sign */ - - FXCH( ST(2) ) /* F4 F5 F6 */ - FSTP_S( DST0 ) /* F5 F6 */ - FSTP_S( DST1 ) /* F6 */ - FSTP_S( DST2 ) /* */ - MOV_L( EBX, DST3 ) - -LLBL(x86_p3_pr_skip): - - ADD_L( CONST(16), EDI ) - ADD_L( EAX, ESI ) - CMP_L( ECX, EDI ) - JNE( LLBL(x86_p3_pr_loop) ) - -LLBL(x86_p3_pr_done): - - POP_L( EBX ) - POP_L( EDI ) - POP_L( ESI ) - RET -#undef FRAME_OFFSET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_x86_transform_points3_3d ) -HIDDEN(_mesa_x86_transform_points3_3d) -GLNAME( _mesa_x86_transform_points3_3d ): - -#define FRAME_OFFSET 8 - PUSH_L( ESI ) - PUSH_L( EDI ) - - MOV_L( ARG_SOURCE, ESI ) - MOV_L( ARG_DEST, EDI ) - - MOV_L( ARG_MATRIX, EDX ) - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) - - TEST_L( ECX, ECX ) - JZ( LLBL(x86_p3_3dr_done) ) - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) - OR_L( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, EDI) ) - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) - MOV_L( CONST(3), REGOFF(V4F_SIZE, EDI) ) - - SHL_L( CONST(4), ECX ) - MOV_L( REGOFF(V4F_START, ESI), ESI ) - - MOV_L( REGOFF(V4F_START, EDI), EDI ) - ADD_L( EDI, ECX ) - -ALIGNTEXT16 -LLBL(x86_p3_3dr_loop): - - FLD_S( SRC0 ) /* F4 */ - FMUL_S( MAT0 ) - FLD_S( SRC0 ) /* F5 F4 */ - FMUL_S( MAT1 ) - FLD_S( SRC0 ) /* F6 F5 F4 */ - FMUL_S( MAT2 ) - - FLD_S( SRC1 ) /* F0 F6 F5 F4 */ - FMUL_S( MAT4 ) - FLD_S( SRC1 ) /* F1 F0 F6 F5 F4 */ - FMUL_S( MAT5 ) - FLD_S( SRC1 ) /* F2 F1 F0 F6 F5 F4 */ - FMUL_S( MAT6 ) - - FXCH( ST(2) ) /* F0 F1 F2 F6 F5 F4 */ - FADDP( ST0, ST(5) ) /* F1 F2 F6 F5 F4 */ - FADDP( ST0, ST(3) ) /* F2 F6 F5 F4 */ - FADDP( ST0, ST(1) ) /* F6 F5 F4 */ - - FLD_S( SRC2 ) /* F0 F6 F5 F4 */ - FMUL_S( MAT8 ) - FLD_S( SRC2 ) /* F1 F0 F6 F5 F4 */ - FMUL_S( MAT9 ) - FLD_S( SRC2 ) /* F2 F1 F0 F6 F5 F4 */ - FMUL_S( MAT10 ) - - FXCH( ST(2) ) /* F0 F1 F2 F6 F5 F4 */ - FADDP( ST0, ST(5) ) /* F1 F2 F6 F5 F4 */ - FADDP( ST0, ST(3) ) /* F2 F6 F5 F4 */ - FADDP( ST0, ST(1) ) /* F6 F5 F4 */ - - FXCH( ST(2) ) /* F4 F5 F6 */ - FADD_S( MAT12 ) - FXCH( ST(1) ) /* F5 F4 F6 */ - FADD_S( MAT13 ) - FXCH( ST(2) ) /* F6 F4 F5 */ - FADD_S( MAT14 ) - - FXCH( ST(1) ) /* F4 F6 F5 */ - FSTP_S( DST0 ) /* F6 F5 */ - FXCH( ST(1) ) /* F5 F6 */ - FSTP_S( DST1 ) /* F6 */ - FSTP_S( DST2 ) /* */ - -LLBL(x86_p3_3dr_skip): - - ADD_L( CONST(16), EDI ) - ADD_L( EAX, ESI ) - CMP_L( ECX, EDI ) - JNE( LLBL(x86_p3_3dr_loop) ) - -LLBL(x86_p3_3dr_done): - - POP_L( EDI ) - POP_L( ESI ) - RET -#undef FRAME_OFFSET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_x86_transform_points3_3d_no_rot ) -HIDDEN(_mesa_x86_transform_points3_3d_no_rot) -GLNAME( _mesa_x86_transform_points3_3d_no_rot ): - -#define FRAME_OFFSET 8 - PUSH_L( ESI ) - PUSH_L( EDI ) - - MOV_L( ARG_SOURCE, ESI ) - MOV_L( ARG_DEST, EDI ) - - - MOV_L( ARG_MATRIX, EDX ) - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) - - TEST_L( ECX, ECX ) - JZ( LLBL(x86_p3_3dnrr_done) ) - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) - OR_L( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, EDI) ) - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) - MOV_L( CONST(3), REGOFF(V4F_SIZE, EDI) ) - - SHL_L( CONST(4), ECX ) - MOV_L( REGOFF(V4F_START, ESI), ESI ) - - MOV_L( REGOFF(V4F_START, EDI), EDI ) - ADD_L( EDI, ECX ) - -ALIGNTEXT16 -LLBL(x86_p3_3dnrr_loop): - - FLD_S( SRC0 ) /* F4 */ - FMUL_S( MAT0 ) - - FLD_S( SRC1 ) /* F1 F4 */ - FMUL_S( MAT5 ) - - FLD_S( SRC2 ) /* F2 F1 F4 */ - FMUL_S( MAT10 ) - - FXCH( ST(2) ) /* F4 F1 F2 */ - FADD_S( MAT12 ) - FLD_S( MAT13 ) /* F5 F4 F1 F2 */ - FXCH( ST(2) ) /* F1 F4 F5 F2 */ - FADDP( ST0, ST(2) ) /* F4 F5 F2 */ - FLD_S( MAT14 ) /* F6 F4 F5 F2 */ - FXCH( ST(3) ) /* F2 F4 F5 F6 */ - FADDP( ST0, ST(3) ) /* F4 F5 F6 */ - - FSTP_S( DST0 ) /* F5 F6 */ - FSTP_S( DST1 ) /* F6 */ - FSTP_S( DST2 ) /* */ - -LLBL(x86_p3_3dnrr_skip): - - ADD_L( CONST(16), EDI ) - ADD_L( EAX, ESI ) - CMP_L( ECX, EDI ) - JNE( LLBL(x86_p3_3dnrr_loop) ) - -LLBL(x86_p3_3dnrr_done): - - POP_L( EDI ) - POP_L( ESI ) - RET -#undef FRAME_OFFSET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_x86_transform_points3_2d ) -HIDDEN(_mesa_x86_transform_points3_2d) -GLNAME( _mesa_x86_transform_points3_2d ): - -#define FRAME_OFFSET 12 - PUSH_L( ESI ) - PUSH_L( EDI ) - PUSH_L( EBX ) - - MOV_L( ARG_SOURCE, ESI ) - MOV_L( ARG_DEST, EDI ) - - MOV_L( ARG_MATRIX, EDX ) - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) - - TEST_L( ECX, ECX ) - JZ( LLBL(x86_p3_2dr_done) ) - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) - OR_L( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, EDI) ) - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) - MOV_L( CONST(3), REGOFF(V4F_SIZE, EDI) ) - - SHL_L( CONST(4), ECX ) - MOV_L( REGOFF(V4F_START, ESI), ESI ) - - MOV_L( REGOFF(V4F_START, EDI), EDI ) - ADD_L( EDI, ECX ) - -ALIGNTEXT16 -LLBL(x86_p3_2dr_loop): - - FLD_S( SRC0 ) /* F4 */ - FMUL_S( MAT0 ) - FLD_S( SRC0 ) /* F5 F4 */ - FMUL_S( MAT1 ) - - FLD_S( SRC1 ) /* F0 F5 F4 */ - FMUL_S( MAT4 ) - FLD_S( SRC1 ) /* F1 F0 F5 F4 */ - FMUL_S( MAT5 ) - - FXCH( ST(1) ) /* F0 F1 F5 F4 */ - FADDP( ST0, ST(3) ) /* F1 F5 F4 */ - FADDP( ST0, ST(1) ) /* F5 F4 */ - - FXCH( ST(1) ) /* F4 F5 */ - FADD_S( MAT12 ) - FXCH( ST(1) ) /* F5 F4 */ - FADD_S( MAT13 ) - - MOV_L( SRC2, EBX ) - - FXCH( ST(1) ) /* F4 F5 */ - FSTP_S( DST0 ) /* F5 */ - FSTP_S( DST1 ) /* */ - MOV_L( EBX, DST2 ) - -LLBL(x86_p3_2dr_skip): - - ADD_L( CONST(16), EDI ) - ADD_L( EAX, ESI ) - CMP_L( ECX, EDI ) - JNE( LLBL(x86_p3_2dr_loop) ) - -LLBL(x86_p3_2dr_done): - - POP_L( EBX ) - POP_L( EDI ) - POP_L( ESI ) - RET -#undef FRAME_OFFSET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_x86_transform_points3_2d_no_rot ) -HIDDEN(_mesa_x86_transform_points3_2d_no_rot) -GLNAME( _mesa_x86_transform_points3_2d_no_rot ): - -#define FRAME_OFFSET 12 - PUSH_L( ESI ) - PUSH_L( EDI ) - PUSH_L( EBX ) - - MOV_L( ARG_SOURCE, ESI ) - MOV_L( ARG_DEST, EDI ) - - MOV_L( ARG_MATRIX, EDX ) - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) - - TEST_L( ECX, ECX ) - JZ( LLBL(x86_p3_2dnrr_done) ) - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) - OR_L( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, EDI) ) - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) - MOV_L( CONST(3), REGOFF(V4F_SIZE, EDI) ) - - SHL_L( CONST(4), ECX ) - MOV_L( REGOFF(V4F_START, ESI), ESI ) - - MOV_L( REGOFF(V4F_START, EDI), EDI ) - ADD_L( EDI, ECX ) - -ALIGNTEXT16 -LLBL(x86_p3_2dnrr_loop): - - FLD_S( SRC0 ) /* F4 */ - FMUL_S( MAT0 ) - - FLD_S( SRC1 ) /* F1 F4 */ - FMUL_S( MAT5 ) - - FXCH( ST(1) ) /* F4 F1 */ - FADD_S( MAT12 ) - FLD_S( MAT13 ) /* F5 F4 F1 */ - - FXCH( ST(2) ) /* F1 F4 F5 */ - FADDP( ST0, ST(2) ) /* F4 F5 */ - - MOV_L( SRC2, EBX ) - - FSTP_S( DST0 ) /* F5 */ - FSTP_S( DST1 ) /* */ - MOV_L( EBX, DST2 ) - -LLBL(x86_p3_2dnrr_skip): - - ADD_L( CONST(16), EDI ) - ADD_L( EAX, ESI ) - CMP_L( ECX, EDI ) - JNE( LLBL(x86_p3_2dnrr_loop) ) - -LLBL(x86_p3_2dnrr_done): - - POP_L( EBX ) - POP_L( EDI ) - POP_L( ESI ) - RET -#undef FRAME_OFFSET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_x86_transform_points3_identity ) -HIDDEN(_mesa_x86_transform_points3_identity) -GLNAME(_mesa_x86_transform_points3_identity ): - -#define FRAME_OFFSET 16 - PUSH_L( ESI ) - PUSH_L( EDI ) - PUSH_L( EBX ) - PUSH_L( EBP ) - - MOV_L( ARG_SOURCE, ESI ) - MOV_L( ARG_DEST, EDI ) - - MOV_L( ARG_MATRIX, EDX ) - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) - - TEST_L( ECX, ECX ) - JZ( LLBL(x86_p3_ir_done) ) - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) - OR_L( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, EDI) ) - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) - MOV_L( CONST(3), REGOFF(V4F_SIZE, EDI) ) - - SHL_L( CONST(4), ECX ) - MOV_L( REGOFF(V4F_START, ESI), ESI ) - - MOV_L( REGOFF(V4F_START, EDI), EDI ) - ADD_L( EDI, ECX ) - - CMP_L( ESI, EDI ) - JE( LLBL(x86_p3_ir_done) ) - -ALIGNTEXT16 -LLBL(x86_p3_ir_loop): - -#if 1 - MOV_L( SRC0, EBX ) - MOV_L( SRC1, EBP ) - MOV_L( SRC2, EDX ) - - MOV_L( EBX, DST0 ) - MOV_L( EBP, DST1 ) - MOV_L( EDX, DST2 ) -#else - FLD_S( SRC0 ) - FLD_S( SRC1 ) - FLD_S( SRC2 ) - - FSTP_S( DST2 ) - FSTP_S( DST1 ) - FSTP_S( DST0 ) -#endif - -LLBL(x86_p3_ir_skip): - - ADD_L( CONST(16), EDI ) - ADD_L( EAX, ESI ) - CMP_L( ECX, EDI ) - JNE( LLBL(x86_p3_ir_loop) ) - -LLBL(x86_p3_ir_done): - - POP_L( EBP ) - POP_L( EBX ) - POP_L( EDI ) - POP_L( ESI ) - RET - -#if defined (__ELF__) && defined (__linux__) - .section .note.GNU-stack,"",%progbits -#endif diff --git a/src/mesa/x86/x86_xform4.S b/src/mesa/x86/x86_xform4.S deleted file mode 100644 index f6db5e3..0000000 --- a/src/mesa/x86/x86_xform4.S +++ /dev/null @@ -1,678 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -/* - * NOTE: Avoid using spaces in between '(' ')' and arguments, especially - * with macros like CONST, LLBL that expand to CONCAT(...). Putting spaces - * in there will break the build on some platforms. - */ - -#include "assyntax.h" -#define MATH_ASM_PTR_SIZE 4 -#include "math/m_vector_asm.h" -#include "xform_args.h" - - SEG_TEXT - -#define FP_ONE 1065353216 -#define FP_ZERO 0 - -#define SRC0 REGOFF(0, ESI) -#define SRC1 REGOFF(4, ESI) -#define SRC2 REGOFF(8, ESI) -#define SRC3 REGOFF(12, ESI) -#define DST0 REGOFF(0, EDI) -#define DST1 REGOFF(4, EDI) -#define DST2 REGOFF(8, EDI) -#define DST3 REGOFF(12, EDI) -#define MAT0 REGOFF(0, EDX) -#define MAT1 REGOFF(4, EDX) -#define MAT2 REGOFF(8, EDX) -#define MAT3 REGOFF(12, EDX) -#define MAT4 REGOFF(16, EDX) -#define MAT5 REGOFF(20, EDX) -#define MAT6 REGOFF(24, EDX) -#define MAT7 REGOFF(28, EDX) -#define MAT8 REGOFF(32, EDX) -#define MAT9 REGOFF(36, EDX) -#define MAT10 REGOFF(40, EDX) -#define MAT11 REGOFF(44, EDX) -#define MAT12 REGOFF(48, EDX) -#define MAT13 REGOFF(52, EDX) -#define MAT14 REGOFF(56, EDX) -#define MAT15 REGOFF(60, EDX) - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_x86_transform_points4_general ) -HIDDEN(_mesa_x86_transform_points4_general) -GLNAME( _mesa_x86_transform_points4_general ): - -#define FRAME_OFFSET 8 - PUSH_L( ESI ) - PUSH_L( EDI ) - - MOV_L( ARG_SOURCE, ESI ) - MOV_L( ARG_DEST, EDI ) - - MOV_L( ARG_MATRIX, EDX ) - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) - - TEST_L( ECX, ECX ) - JZ( LLBL(x86_p4_gr_done) ) - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) - OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) ) - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) - MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) ) - - SHL_L( CONST(4), ECX ) - MOV_L( REGOFF(V4F_START, ESI), ESI ) - - MOV_L( REGOFF(V4F_START, EDI), EDI ) - ADD_L( EDI, ECX ) - -ALIGNTEXT16 -LLBL(x86_p4_gr_loop): - - FLD_S( SRC0 ) /* F4 */ - FMUL_S( MAT0 ) - FLD_S( SRC0 ) /* F5 F4 */ - FMUL_S( MAT1 ) - FLD_S( SRC0 ) /* F6 F5 F4 */ - FMUL_S( MAT2 ) - FLD_S( SRC0 ) /* F7 F6 F5 F4 */ - FMUL_S( MAT3 ) - - FLD_S( SRC1 ) /* F0 F7 F6 F5 F4 */ - FMUL_S( MAT4 ) - FLD_S( SRC1 ) /* F1 F0 F7 F6 F5 F4 */ - FMUL_S( MAT5 ) - FLD_S( SRC1 ) /* F2 F1 F0 F7 F6 F5 F4 */ - FMUL_S( MAT6 ) - FLD_S( SRC1 ) /* F3 F2 F1 F0 F7 F6 F5 F4 */ - FMUL_S( MAT7 ) - - FXCH( ST(3) ) /* F0 F2 F1 F3 F7 F6 F5 F4 */ - FADDP( ST0, ST(7) ) /* F2 F1 F3 F7 F6 F5 F4 */ - FXCH( ST(1) ) /* F1 F2 F3 F7 F6 F5 F4 */ - FADDP( ST0, ST(5) ) /* F2 F3 F7 F6 F5 F4 */ - FADDP( ST0, ST(3) ) /* F3 F7 F6 F5 F4 */ - FADDP( ST0, ST(1) ) /* F7 F6 F5 F4 */ - - FLD_S( SRC2 ) /* F0 F7 F6 F5 F4 */ - FMUL_S( MAT8 ) - FLD_S( SRC2 ) /* F1 F0 F7 F6 F5 F4 */ - FMUL_S( MAT9 ) - FLD_S( SRC2 ) /* F2 F1 F0 F7 F6 F5 F4 */ - FMUL_S( MAT10 ) - FLD_S( SRC2 ) /* F3 F2 F1 F0 F7 F6 F5 F4 */ - FMUL_S( MAT11 ) - - FXCH( ST(3) ) /* F0 F2 F1 F3 F7 F6 F5 F4 */ - FADDP( ST0, ST(7) ) /* F2 F1 F3 F7 F6 F5 F4 */ - FXCH( ST(1) ) /* F1 F2 F3 F7 F6 F5 F4 */ - FADDP( ST0, ST(5) ) /* F2 F3 F7 F6 F5 F4 */ - FADDP( ST0, ST(3) ) /* F3 F7 F6 F5 F4 */ - FADDP( ST0, ST(1) ) /* F7 F6 F5 F4 */ - - FLD_S( SRC3 ) /* F0 F7 F6 F5 F4 */ - FMUL_S( MAT12 ) - FLD_S( SRC3 ) /* F1 F0 F7 F6 F5 F4 */ - FMUL_S( MAT13 ) - FLD_S( SRC3 ) /* F2 F1 F0 F7 F6 F5 F4 */ - FMUL_S( MAT14 ) - FLD_S( SRC3 ) /* F3 F2 F1 F0 F7 F6 F5 F4 */ - FMUL_S( MAT15 ) - - FXCH( ST(3) ) /* F0 F2 F1 F3 F7 F6 F5 F4 */ - FADDP( ST0, ST(7) ) /* F2 F1 F3 F7 F6 F5 F4 */ - FXCH( ST(1) ) /* F1 F2 F3 F7 F6 F5 F4 */ - FADDP( ST0, ST(5) ) /* F2 F3 F7 F6 F5 F4 */ - FADDP( ST0, ST(3) ) /* F3 F7 F6 F5 F4 */ - FADDP( ST0, ST(1) ) /* F7 F6 F5 F4 */ - - FXCH( ST(3) ) /* F4 F6 F5 F7 */ - FSTP_S( DST0 ) /* F6 F5 F7 */ - FXCH( ST(1) ) /* F5 F6 F7 */ - FSTP_S( DST1 ) /* F6 F7 */ - FSTP_S( DST2 ) /* F7 */ - FSTP_S( DST3 ) /* */ - -LLBL(x86_p4_gr_skip): - - ADD_L( CONST(16), EDI ) - ADD_L( EAX, ESI ) - CMP_L( ECX, EDI ) - JNE( LLBL(x86_p4_gr_loop) ) - -LLBL(x86_p4_gr_done): - - POP_L( EDI ) - POP_L( ESI ) - RET -#undef FRAME_OFFSET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_x86_transform_points4_perspective ) -HIDDEN(_mesa_x86_transform_points4_perspective) -GLNAME( _mesa_x86_transform_points4_perspective ): - -#define FRAME_OFFSET 12 - PUSH_L( ESI ) - PUSH_L( EDI ) - PUSH_L( EBX ) - - MOV_L( ARG_SOURCE, ESI ) - MOV_L( ARG_DEST, EDI ) - - MOV_L( ARG_MATRIX, EDX ) - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) - - TEST_L( ECX, ECX ) - JZ( LLBL(x86_p4_pr_done) ) - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) - OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) ) - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) - MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) ) - - SHL_L( CONST(4), ECX ) - MOV_L( REGOFF(V4F_START, ESI), ESI ) - - MOV_L( REGOFF(V4F_START, EDI), EDI ) - ADD_L( EDI, ECX ) - -ALIGNTEXT16 -LLBL(x86_p4_pr_loop): - - FLD_S( SRC0 ) /* F4 */ - FMUL_S( MAT0 ) - - FLD_S( SRC1 ) /* F5 F4 */ - FMUL_S( MAT5 ) - - FLD_S( SRC2 ) /* F0 F5 F4 */ - FMUL_S( MAT8 ) - FLD_S( SRC2 ) /* F1 F0 F5 F4 */ - FMUL_S( MAT9 ) - FLD_S( SRC2 ) /* F6 F1 F0 F5 F4 */ - FMUL_S( MAT10 ) - - FXCH( ST(2) ) /* F0 F1 F6 F5 F4 */ - FADDP( ST0, ST(4) ) /* F1 F6 F5 F4 */ - FADDP( ST0, ST(2) ) /* F6 F5 F4 */ - - FLD_S( SRC3 ) /* F2 F6 F5 F4 */ - FMUL_S( MAT14 ) - - FADDP( ST0, ST(1) ) /* F6 F5 F4 */ - - MOV_L( SRC2, EBX ) - XOR_L( CONST(-2147483648), EBX )/* change sign */ - - FXCH( ST(2) ) /* F4 F5 F6 */ - FSTP_S( DST0 ) /* F5 F6 */ - FSTP_S( DST1 ) /* F6 */ - FSTP_S( DST2 ) /* */ - MOV_L( EBX, DST3 ) - -LLBL(x86_p4_pr_skip): - - ADD_L( CONST(16), EDI ) - ADD_L( EAX, ESI ) - CMP_L( ECX, EDI ) - JNE( LLBL(x86_p4_pr_loop) ) - -LLBL(x86_p4_pr_done): - - POP_L( EBX ) - POP_L( EDI ) - POP_L( ESI ) - RET -#undef FRAME_OFFSET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_x86_transform_points4_3d ) -HIDDEN(_mesa_x86_transform_points4_3d) -GLNAME( _mesa_x86_transform_points4_3d ): - -#define FRAME_OFFSET 12 - PUSH_L( ESI ) - PUSH_L( EDI ) - PUSH_L( EBX ) - - MOV_L( ARG_SOURCE, ESI ) - MOV_L( ARG_DEST, EDI ) - - MOV_L( ARG_MATRIX, EDX ) - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) - - TEST_L( ECX, ECX ) - JZ( LLBL(x86_p4_3dr_done) ) - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) - OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) ) - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) - MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) ) - - SHL_L( CONST(4), ECX ) - MOV_L( REGOFF(V4F_START, ESI), ESI ) - - MOV_L( REGOFF(V4F_START, EDI), EDI ) - ADD_L( EDI, ECX ) - -ALIGNTEXT16 -LLBL(x86_p4_3dr_loop): - - FLD_S( SRC0 ) /* F4 */ - FMUL_S( MAT0 ) - FLD_S( SRC0 ) /* F5 F4 */ - FMUL_S( MAT1 ) - FLD_S( SRC0 ) /* F6 F5 F4 */ - FMUL_S( MAT2 ) - - FLD_S( SRC1 ) /* F0 F6 F5 F4 */ - FMUL_S( MAT4 ) - FLD_S( SRC1 ) /* F1 F0 F6 F5 F4 */ - FMUL_S( MAT5 ) - FLD_S( SRC1 ) /* F2 F1 F0 F6 F5 F4 */ - FMUL_S( MAT6 ) - - FXCH( ST(2) ) /* F0 F1 F2 F6 F5 F4 */ - FADDP( ST0, ST(5) ) /* F1 F2 F6 F5 F4 */ - FADDP( ST0, ST(3) ) /* F2 F6 F5 F4 */ - FADDP( ST0, ST(1) ) /* F6 F5 F4 */ - - FLD_S( SRC2 ) /* F0 F6 F5 F4 */ - FMUL_S( MAT8 ) - FLD_S( SRC2 ) /* F1 F0 F6 F5 F4 */ - FMUL_S( MAT9 ) - FLD_S( SRC2 ) /* F2 F1 F0 F6 F5 F4 */ - FMUL_S( MAT10 ) - - FXCH( ST(2) ) /* F0 F1 F2 F6 F5 F4 */ - FADDP( ST0, ST(5) ) /* F1 F2 F6 F5 F4 */ - FADDP( ST0, ST(3) ) /* F2 F6 F5 F4 */ - FADDP( ST0, ST(1) ) /* F6 F5 F4 */ - - FLD_S( SRC3 ) /* F0 F6 F5 F4 */ - FMUL_S( MAT12 ) - FLD_S( SRC3 ) /* F1 F0 F6 F5 F4 */ - FMUL_S( MAT13 ) - FLD_S( SRC3 ) /* F2 F1 F0 F6 F5 F4 */ - FMUL_S( MAT14 ) - - FXCH( ST(2) ) /* F0 F1 F2 F6 F5 F4 */ - FADDP( ST0, ST(5) ) /* F1 F2 F6 F5 F4 */ - FADDP( ST0, ST(3) ) /* F2 F6 F5 F4 */ - FADDP( ST0, ST(1) ) /* F6 F5 F4 */ - - MOV_L( SRC3, EBX ) - - FXCH( ST(2) ) /* F4 F5 F6 */ - FSTP_S( DST0 ) /* F5 F6 */ - FSTP_S( DST1 ) /* F6 */ - FSTP_S( DST2 ) /* */ - MOV_L( EBX, DST3 ) - -LLBL(x86_p4_3dr_skip): - - ADD_L( CONST(16), EDI ) - ADD_L( EAX, ESI ) - CMP_L( ECX, EDI ) - JNE( LLBL(x86_p4_3dr_loop) ) - -LLBL(x86_p4_3dr_done): - - POP_L( EBX ) - POP_L( EDI ) - POP_L( ESI ) - RET -#undef FRAME_OFFSET - - - - -ALIGNTEXT16 -GLOBL GLNAME(_mesa_x86_transform_points4_3d_no_rot) -HIDDEN(_mesa_x86_transform_points4_3d_no_rot) -GLNAME(_mesa_x86_transform_points4_3d_no_rot): - -#define FRAME_OFFSET 12 - PUSH_L( ESI ) - PUSH_L( EDI ) - PUSH_L( EBX ) - - MOV_L( ARG_SOURCE, ESI ) - MOV_L( ARG_DEST, EDI ) - - MOV_L( ARG_MATRIX, EDX ) - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) - - TEST_L( ECX, ECX ) - JZ( LLBL(x86_p4_3dnrr_done) ) - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) - OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) ) - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) - MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) ) - - SHL_L( CONST(4), ECX ) - MOV_L( REGOFF(V4F_START, ESI), ESI ) - - MOV_L( REGOFF(V4F_START, EDI), EDI ) - ADD_L( EDI, ECX ) - -ALIGNTEXT16 -LLBL(x86_p4_3dnrr_loop): - - FLD_S( SRC0 ) /* F4 */ - FMUL_S( MAT0 ) - - FLD_S( SRC1 ) /* F5 F4 */ - FMUL_S( MAT5 ) - - FLD_S( SRC2 ) /* F6 F5 F4 */ - FMUL_S( MAT10 ) - - FLD_S( SRC3 ) /* F0 F6 F5 F4 */ - FMUL_S( MAT12 ) - FLD_S( SRC3 ) /* F1 F0 F6 F5 F4 */ - FMUL_S( MAT13 ) - FLD_S( SRC3 ) /* F2 F1 F0 F6 F5 F4 */ - FMUL_S( MAT14 ) - - FXCH( ST(2) ) /* F0 F1 F2 F6 F5 F4 */ - FADDP( ST0, ST(5) ) /* F1 F2 F6 F5 F4 */ - FADDP( ST0, ST(3) ) /* F2 F6 F5 F4 */ - FADDP( ST0, ST(1) ) /* F6 F5 F4 */ - - MOV_L( SRC3, EBX ) - - FXCH( ST(2) ) /* F4 F5 F6 */ - FSTP_S( DST0 ) /* F5 F6 */ - FSTP_S( DST1 ) /* F6 */ - FSTP_S( DST2 ) /* */ - MOV_L( EBX, DST3 ) - -LLBL(x86_p4_3dnrr_skip): - - ADD_L( CONST(16), EDI ) - ADD_L( EAX, ESI ) - CMP_L( ECX, EDI ) - JNE( LLBL(x86_p4_3dnrr_loop) ) - -LLBL(x86_p4_3dnrr_done): - - POP_L( EBX ) - POP_L( EDI ) - POP_L( ESI ) - RET -#undef FRAME_OFFSET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_x86_transform_points4_2d ) -HIDDEN(_mesa_x86_transform_points4_2d) -GLNAME( _mesa_x86_transform_points4_2d ): - -#define FRAME_OFFSET 16 - PUSH_L( ESI ) - PUSH_L( EDI ) - PUSH_L( EBX ) - PUSH_L( EBP ) - - MOV_L( ARG_SOURCE, ESI ) - MOV_L( ARG_DEST, EDI ) - - MOV_L( ARG_MATRIX, EDX ) - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) - - TEST_L( ECX, ECX ) - JZ( LLBL(x86_p4_2dr_done) ) - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) - OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) ) - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) - MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) ) - - SHL_L( CONST(4), ECX ) - MOV_L( REGOFF(V4F_START, ESI), ESI ) - - MOV_L( REGOFF(V4F_START, EDI), EDI ) - ADD_L( EDI, ECX ) - -ALIGNTEXT16 -LLBL(x86_p4_2dr_loop): - - FLD_S( SRC0 ) /* F4 */ - FMUL_S( MAT0 ) - FLD_S( SRC0 ) /* F5 F4 */ - FMUL_S( MAT1 ) - - FLD_S( SRC1 ) /* F0 F5 F4 */ - FMUL_S( MAT4 ) - FLD_S( SRC1 ) /* F1 F0 F5 F4 */ - FMUL_S( MAT5 ) - - FXCH( ST(1) ) /* F0 F1 F5 F4 */ - FADDP( ST0, ST(3) ) /* F1 F5 F4 */ - FADDP( ST0, ST(1) ) /* F5 F4 */ - - FLD_S( SRC3 ) /* F0 F5 F4 */ - FMUL_S( MAT12 ) - FLD_S( SRC3 ) /* F1 F0 F5 F4 */ - FMUL_S( MAT13 ) - - FXCH( ST(1) ) /* F0 F1 F5 F4 */ - FADDP( ST0, ST(3) ) /* F1 F5 F4 */ - FADDP( ST0, ST(1) ) /* F5 F4 */ - - MOV_L( SRC2, EBX ) - MOV_L( SRC3, EBP ) - - FXCH( ST(1) ) /* F4 F5 */ - FSTP_S( DST0 ) /* F5 */ - FSTP_S( DST1 ) /* */ - MOV_L( EBX, DST2 ) - MOV_L( EBP, DST3 ) - -LLBL(x86_p4_2dr_skip): - - ADD_L( CONST(16), EDI ) - ADD_L( EAX, ESI ) - CMP_L( ECX, EDI ) - JNE( LLBL(x86_p4_2dr_loop) ) - -LLBL(x86_p4_2dr_done): - - POP_L( EBP ) - POP_L( EBX ) - POP_L( EDI ) - POP_L( ESI ) - RET -#undef FRAME_OFFSET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_x86_transform_points4_2d_no_rot ) -HIDDEN(_mesa_x86_transform_points4_2d_no_rot) -GLNAME( _mesa_x86_transform_points4_2d_no_rot ): - -#define FRAME_OFFSET 16 - PUSH_L( ESI ) - PUSH_L( EDI ) - PUSH_L( EBX ) - PUSH_L( EBP ) - - MOV_L( ARG_SOURCE, ESI ) - MOV_L( ARG_DEST, EDI ) - - MOV_L( ARG_MATRIX, EDX ) - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) - - TEST_L( ECX, ECX ) - JZ( LLBL(x86_p4_2dnrr_done) ) - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) - OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) ) - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) - MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) ) - - SHL_L( CONST(4), ECX ) - MOV_L( REGOFF(V4F_START, ESI), ESI ) - - MOV_L( REGOFF(V4F_START, EDI), EDI ) - ADD_L( EDI, ECX ) - -ALIGNTEXT16 -LLBL(x86_p4_2dnrr_loop): - - FLD_S( SRC0 ) /* F4 */ - FMUL_S( MAT0 ) - - FLD_S( SRC1 ) /* F5 F4 */ - FMUL_S( MAT5 ) - - FLD_S( SRC3 ) /* F0 F5 F4 */ - FMUL_S( MAT12 ) - FLD_S( SRC3 ) /* F1 F0 F5 F4 */ - FMUL_S( MAT13 ) - - FXCH( ST(1) ) /* F0 F1 F5 F4 */ - FADDP( ST0, ST(3) ) /* F1 F5 F4 */ - FADDP( ST0, ST(1) ) /* F5 F4 */ - - MOV_L( SRC2, EBX ) - MOV_L( SRC3, EBP ) - - FXCH( ST(1) ) /* F4 F5 */ - FSTP_S( DST0 ) /* F5 */ - FSTP_S( DST1 ) /* */ - MOV_L( EBX, DST2 ) - MOV_L( EBP, DST3 ) - -LLBL(x86_p4_2dnrr_skip): - - ADD_L( CONST(16), EDI ) - ADD_L( EAX, ESI ) - CMP_L( ECX, EDI ) - JNE( LLBL(x86_p4_2dnrr_loop) ) - -LLBL(x86_p4_2dnrr_done): - - POP_L( EBP ) - POP_L( EBX ) - POP_L( EDI ) - POP_L( ESI ) - RET -#undef FRAME_OFFSET - - - - -ALIGNTEXT16 -GLOBL GLNAME( _mesa_x86_transform_points4_identity ) -HIDDEN(_mesa_x86_transform_points4_identity) -GLNAME( _mesa_x86_transform_points4_identity ): - -#define FRAME_OFFSET 12 - PUSH_L( ESI ) - PUSH_L( EDI ) - PUSH_L( EBX ) - - MOV_L( ARG_SOURCE, ESI ) - MOV_L( ARG_DEST, EDI ) - - MOV_L( ARG_MATRIX, EDX ) - MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) - - TEST_L( ECX, ECX ) - JZ( LLBL(x86_p4_ir_done) ) - - MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) - OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) ) - - MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) - MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) ) - - SHL_L( CONST(4), ECX ) - MOV_L( REGOFF(V4F_START, ESI), ESI ) - - MOV_L( REGOFF(V4F_START, EDI), EDI ) - ADD_L( EDI, ECX ) - - CMP_L( ESI, EDI ) - JE( LLBL(x86_p4_ir_done) ) - -ALIGNTEXT16 -LLBL(x86_p4_ir_loop): - - MOV_L( SRC0, EBX ) - MOV_L( SRC1, EDX ) - - MOV_L( EBX, DST0 ) - MOV_L( EDX, DST1 ) - - MOV_L( SRC2, EBX ) - MOV_L( SRC3, EDX ) - - MOV_L( EBX, DST2 ) - MOV_L( EDX, DST3 ) - -LLBL(x86_p4_ir_skip): - - ADD_L( CONST(16), EDI ) - ADD_L( EAX, ESI ) - CMP_L( ECX, EDI ) - JNE( LLBL(x86_p4_ir_loop) ) - -LLBL(x86_p4_ir_done): - - POP_L( EBX ) - POP_L( EDI ) - POP_L( ESI ) - RET - -#if defined (__ELF__) && defined (__linux__) - .section .note.GNU-stack,"",%progbits -#endif diff --git a/src/mesa/x86/xform_args.h b/src/mesa/x86/xform_args.h deleted file mode 100644 index b20d6a1..0000000 --- a/src/mesa/x86/xform_args.h +++ /dev/null @@ -1,51 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * 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 - * 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. - */ - -/* - * Transform function interface for assembly code. Simply define - * FRAME_OFFSET to the number of bytes pushed onto the stack before - * using the ARG_* argument macros. - * - * Gareth Hughes - */ - -#ifndef __XFORM_ARGS_H__ -#define __XFORM_ARGS_H__ - -/* Offsets for transform_func arguments - * - * typedef void (*transform_func)( GLvector4f *to_vec, - * const GLfloat m[16], - * const GLvector4f *from_vec ); - */ -#define OFFSET_DEST 4 -#define OFFSET_MATRIX 8 -#define OFFSET_SOURCE 12 - -#define ARG_DEST REGOFF(FRAME_OFFSET+OFFSET_DEST, ESP) -#define ARG_MATRIX REGOFF(FRAME_OFFSET+OFFSET_MATRIX, ESP) -#define ARG_SOURCE REGOFF(FRAME_OFFSET+OFFSET_SOURCE, ESP) - -#endif -- 2.7.4