From 6fc4d22bdeb499191580306191d561b3018f2aea Mon Sep 17 00:00:00 2001 From: Gregor Anich Date: Fri, 16 Jul 2004 22:12:43 +0000 Subject: [PATCH] Import Mesa-6.0.1 for use as software OpenGL renderer. svn path=/trunk/; revision=10149 --- .../lib/mesa32/src/array_cache/ac_context.c | 375 + .../lib/mesa32/src/array_cache/ac_context.h | 99 + .../lib/mesa32/src/array_cache/ac_import.c | 881 + reactos/lib/mesa32/src/array_cache/acache.h | 132 + .../mesa32/src/array_cache/array_cache.dsp | 108 + .../lib/mesa32/src/drivers/beos/GLView.cpp | 1427 ++ reactos/lib/mesa32/src/drivers/beos/GLView.h | 196 + reactos/lib/mesa32/src/drivers/common/t_dd.c | 58 + .../mesa32/src/drivers/common/t_dd_dmatmp.h | 1093 + .../mesa32/src/drivers/common/t_dd_dmatmp2.h | 935 + .../src/drivers/common/t_dd_rendertmp.h | 434 + .../mesa32/src/drivers/common/t_dd_triemit.h | 157 + .../mesa32/src/drivers/common/t_dd_tritmp.h | 743 + .../mesa32/src/drivers/common/t_dd_unfilled.h | 212 + .../lib/mesa32/src/drivers/common/t_dd_vb.c | 344 + .../mesa32/src/drivers/common/t_dd_vbtmp.h | 679 + .../mesa32/src/drivers/common/t_dd_vertex.h | 78 + reactos/lib/mesa32/src/drivers/dos/blit.S | 210 + reactos/lib/mesa32/src/drivers/dos/dmesa.c | 1418 ++ reactos/lib/mesa32/src/drivers/dos/dpmi.c | 148 + reactos/lib/mesa32/src/drivers/dos/internal.h | 130 + reactos/lib/mesa32/src/drivers/dos/vesa.c | 534 + reactos/lib/mesa32/src/drivers/dos/vesa.h | 47 + reactos/lib/mesa32/src/drivers/dos/vga.c | 236 + reactos/lib/mesa32/src/drivers/dos/vga.h | 42 + reactos/lib/mesa32/src/drivers/dos/video.c | 651 + reactos/lib/mesa32/src/drivers/dos/video.h | 65 + reactos/lib/mesa32/src/drivers/dos/virtual.S | 495 + .../mesa32/src/drivers/dri/common/depthtmp.h | 176 + .../lib/mesa32/src/drivers/dri/common/mm.c | 196 + .../lib/mesa32/src/drivers/dri/common/mm.h | 82 + .../lib/mesa32/src/drivers/dri/common/mmx.h | 560 + .../mesa32/src/drivers/dri/common/spantmp.h | 259 + .../src/drivers/dri/common/stenciltmp.h | 147 + .../mesa32/src/drivers/dri/common/texmem.c | 1230 + .../mesa32/src/drivers/dri/common/texmem.h | 295 + .../lib/mesa32/src/drivers/dri/common/utils.c | 219 + .../lib/mesa32/src/drivers/dri/common/utils.h | 58 + .../mesa32/src/drivers/dri/common/vblank.c | 363 + .../mesa32/src/drivers/dri/common/vblank.h | 64 + .../mesa32/src/drivers/dri/common/xmlconfig.c | 993 + .../mesa32/src/drivers/dri/common/xmlconfig.h | 124 + .../mesa32/src/drivers/dri/common/xmlpool.h | 270 + .../lib/mesa32/src/drivers/fbdev/glfbdev.c | 828 + .../src/drivers/ggi/default/genkgi.conf.in | 4 + .../src/drivers/ggi/default/genkgi_mode.c | 97 + .../src/drivers/ggi/default/genkgi_visual.c | 190 + .../mesa32/src/drivers/ggi/default/linear.c | 409 + .../src/drivers/ggi/default/linear_15.c | 36 + .../src/drivers/ggi/default/linear_16.c | 36 + .../src/drivers/ggi/default/linear_24.c | 36 + .../src/drivers/ggi/default/linear_32.c | 36 + .../mesa32/src/drivers/ggi/default/linear_8.c | 36 + .../mesa32/src/drivers/ggi/default/stubs.c | 512 + .../src/drivers/ggi/display/fbdev.conf.in | 4 + .../src/drivers/ggi/display/fbdev_mode.c | 134 + .../src/drivers/ggi/display/fbdev_visual.c | 150 + .../src/drivers/ggi/include/ggi/mesa/debug.h | 260 + .../ggi/include/ggi/mesa/display_fbdev.h | 20 + .../drivers/ggi/include/ggi/mesa/ggimesa.h | 84 + .../ggi/include/ggi/mesa/ggimesa_int.h | 45 + reactos/lib/mesa32/src/drivers/glide/fxapi.c | 932 + reactos/lib/mesa32/src/drivers/glide/fxdd.c | 1759 ++ .../lib/mesa32/src/drivers/glide/fxddspan.c | 663 + .../lib/mesa32/src/drivers/glide/fxddtex.c | 1684 ++ reactos/lib/mesa32/src/drivers/glide/fxdrv.h | 721 + reactos/lib/mesa32/src/drivers/glide/fxg.c | 2294 ++ reactos/lib/mesa32/src/drivers/glide/fxg.h | 381 + .../lib/mesa32/src/drivers/glide/fxglidew.c | 263 + .../lib/mesa32/src/drivers/glide/fxglidew.h | 197 + .../lib/mesa32/src/drivers/glide/fxopengl.def | 938 + .../lib/mesa32/src/drivers/glide/fxsetup.c | 2179 ++ .../lib/mesa32/src/drivers/glide/fxsetup.h | 1250 + .../lib/mesa32/src/drivers/glide/fxtexman.c | 884 + reactos/lib/mesa32/src/drivers/glide/fxtris.c | 1466 ++ reactos/lib/mesa32/src/drivers/glide/fxvb.c | 593 + .../lib/mesa32/src/drivers/glide/fxvbtmp.h | 317 + reactos/lib/mesa32/src/drivers/glide/fxwgl.c | 1017 + .../mesa32/src/drivers/osmesa/Makefile.win | 39 + .../lib/mesa32/src/drivers/osmesa/osmesa.c | 1337 ++ .../lib/mesa32/src/drivers/osmesa/osmesa.def | 13 + .../lib/mesa32/src/drivers/osmesa/osmesa.dsp | 119 + .../lib/mesa32/src/drivers/svga/svgamesa.c | 513 + .../lib/mesa32/src/drivers/svga/svgamesa15.c | 217 + .../lib/mesa32/src/drivers/svga/svgamesa15.h | 43 + .../lib/mesa32/src/drivers/svga/svgamesa16.c | 215 + .../lib/mesa32/src/drivers/svga/svgamesa16.h | 44 + .../lib/mesa32/src/drivers/svga/svgamesa24.c | 239 + .../lib/mesa32/src/drivers/svga/svgamesa24.h | 44 + .../lib/mesa32/src/drivers/svga/svgamesa32.c | 220 + .../lib/mesa32/src/drivers/svga/svgamesa32.h | 44 + .../lib/mesa32/src/drivers/svga/svgamesa8.c | 191 + .../lib/mesa32/src/drivers/svga/svgamesa8.h | 44 + reactos/lib/mesa32/src/drivers/svga/svgapix.h | 71 + .../mesa32/src/drivers/windows/gdi/colors.h | 539 + .../mesa32/src/drivers/windows/gdi/gdi.dsp | 129 + .../mesa32/src/drivers/windows/gdi/mesa.def | 1057 + .../lib/mesa32/src/drivers/windows/gdi/wgl.c | 623 + .../mesa32/src/drivers/windows/gdi/wmesa.c | 3328 +++ .../mesa32/src/drivers/windows/gdi/wmesadef.h | 174 + .../mesa32/src/drivers/windows/icd/colors.h | 539 + .../lib/mesa32/src/drivers/windows/icd/icd.c | 332 + .../mesa32/src/drivers/windows/icd/icdlist.h | 336 + .../mesa32/src/drivers/windows/icd/mesa.def | 138 + .../mesa32/src/drivers/windows/icd/wmesadef.h | 173 + reactos/lib/mesa32/src/drivers/x11/fakeglx.c | 2868 +++ reactos/lib/mesa32/src/drivers/x11/glxapi.c | 1343 ++ reactos/lib/mesa32/src/drivers/x11/glxapi.h | 236 + .../lib/mesa32/src/drivers/x11/glxheader.h | 71 + reactos/lib/mesa32/src/drivers/x11/realglx.c | 185 + reactos/lib/mesa32/src/drivers/x11/realglx.h | 326 + reactos/lib/mesa32/src/drivers/x11/xfonts.c | 377 + reactos/lib/mesa32/src/drivers/x11/xfonts.h | 41 + reactos/lib/mesa32/src/drivers/x11/xm_api.c | 2626 +++ reactos/lib/mesa32/src/drivers/x11/xm_dd.c | 1231 + reactos/lib/mesa32/src/drivers/x11/xm_line.c | 574 + reactos/lib/mesa32/src/drivers/x11/xm_span.c | 4485 ++++ reactos/lib/mesa32/src/drivers/x11/xm_tri.c | 1495 ++ reactos/lib/mesa32/src/drivers/x11/xmesaP.h | 551 + reactos/lib/mesa32/src/glapi/glapi.c | 923 + reactos/lib/mesa32/src/glapi/glapi.dsp | 124 + reactos/lib/mesa32/src/glapi/glapi.h | 109 + reactos/lib/mesa32/src/glapi/glapioffsets.h | 716 + reactos/lib/mesa32/src/glapi/glapitable.h | 723 + reactos/lib/mesa32/src/glapi/glapitemp.h | 5823 +++++ reactos/lib/mesa32/src/glapi/glprocs.h | 923 + reactos/lib/mesa32/src/glapi/glthread.c | 367 + reactos/lib/mesa32/src/glapi/glthread.h | 295 + reactos/lib/mesa32/src/main/accum.c | 97 + reactos/lib/mesa32/src/main/accum.h | 62 + reactos/lib/mesa32/src/main/api_arrayelt.c | 830 + reactos/lib/mesa32/src/main/api_arrayelt.h | 37 + reactos/lib/mesa32/src/main/api_eval.h | 42 + reactos/lib/mesa32/src/main/api_loopback.c | 1563 ++ reactos/lib/mesa32/src/main/api_loopback.h | 37 + reactos/lib/mesa32/src/main/api_noop.c | 863 + reactos/lib/mesa32/src/main/api_noop.h | 180 + reactos/lib/mesa32/src/main/api_validate.c | 239 + reactos/lib/mesa32/src/main/api_validate.h | 49 + reactos/lib/mesa32/src/main/arbfragparse.c | 238 + reactos/lib/mesa32/src/main/arbfragparse.h | 35 + reactos/lib/mesa32/src/main/arbparse.c | 6058 +++++ reactos/lib/mesa32/src/main/arbparse.h | 83 + reactos/lib/mesa32/src/main/arbparse_syn.h | 1267 + reactos/lib/mesa32/src/main/arbprogram.c | 712 + reactos/lib/mesa32/src/main/arbprogram.h | 128 + reactos/lib/mesa32/src/main/arbvertparse.c | 223 + reactos/lib/mesa32/src/main/arbvertparse.h | 33 + reactos/lib/mesa32/src/main/attrib.c | 1244 + reactos/lib/mesa32/src/main/attrib.h | 68 + reactos/lib/mesa32/src/main/blend.c | 590 + reactos/lib/mesa32/src/main/blend.h | 74 + reactos/lib/mesa32/src/main/bufferobj.c | 804 + reactos/lib/mesa32/src/main/bufferobj.h | 116 + reactos/lib/mesa32/src/main/buffers.c | 620 + reactos/lib/mesa32/src/main/buffers.h | 70 + reactos/lib/mesa32/src/main/clip.c | 119 + reactos/lib/mesa32/src/main/clip.h | 42 + reactos/lib/mesa32/src/main/colormac.h | 239 + reactos/lib/mesa32/src/main/colortab.c | 1381 ++ reactos/lib/mesa32/src/main/colortab.h | 110 + reactos/lib/mesa32/src/main/config.h | 269 + reactos/lib/mesa32/src/main/context.c | 1945 ++ reactos/lib/mesa32/src/main/context.h | 395 + reactos/lib/mesa32/src/main/convolve.c | 1412 ++ reactos/lib/mesa32/src/main/convolve.h | 114 + reactos/lib/mesa32/src/main/dd.h | 1011 + reactos/lib/mesa32/src/main/debug.c | 251 + reactos/lib/mesa32/src/main/debug.h | 64 + reactos/lib/mesa32/src/main/depth.c | 186 + reactos/lib/mesa32/src/main/depth.h | 62 + reactos/lib/mesa32/src/main/dispatch.c | 90 + reactos/lib/mesa32/src/main/dlist.c | 7815 +++++++ reactos/lib/mesa32/src/main/dlist.h | 104 + reactos/lib/mesa32/src/main/drawpix.c | 308 + reactos/lib/mesa32/src/main/drawpix.h | 55 + reactos/lib/mesa32/src/main/enable.c | 1441 ++ reactos/lib/mesa32/src/main/enable.h | 57 + reactos/lib/mesa32/src/main/enums.c | 973 + reactos/lib/mesa32/src/main/enums.h | 55 + reactos/lib/mesa32/src/main/eval.c | 962 + reactos/lib/mesa32/src/main/eval.h | 128 + reactos/lib/mesa32/src/main/extensions.c | 450 + reactos/lib/mesa32/src/main/extensions.h | 82 + reactos/lib/mesa32/src/main/feedback.c | 529 + reactos/lib/mesa32/src/main/feedback.h | 82 + reactos/lib/mesa32/src/main/fog.c | 177 + reactos/lib/mesa32/src/main/fog.h | 66 + reactos/lib/mesa32/src/main/get.c | 6488 ++++++ reactos/lib/mesa32/src/main/get.h | 59 + reactos/lib/mesa32/src/main/glheader.h | 300 + reactos/lib/mesa32/src/main/hash.c | 360 + reactos/lib/mesa32/src/main/hash.h | 62 + reactos/lib/mesa32/src/main/hint.c | 140 + reactos/lib/mesa32/src/main/hint.h | 57 + reactos/lib/mesa32/src/main/histogram.c | 1136 + reactos/lib/mesa32/src/main/histogram.h | 89 + reactos/lib/mesa32/src/main/image.c | 4136 ++++ reactos/lib/mesa32/src/main/image.h | 178 + reactos/lib/mesa32/src/main/imports.c | 1190 + reactos/lib/mesa32/src/main/imports.h | 776 + reactos/lib/mesa32/src/main/light.c | 1323 ++ reactos/lib/mesa32/src/main/light.h | 141 + reactos/lib/mesa32/src/main/lines.c | 134 + reactos/lib/mesa32/src/main/lines.h | 48 + reactos/lib/mesa32/src/main/macros.h | 658 + reactos/lib/mesa32/src/main/main.dsp | 612 + reactos/lib/mesa32/src/main/matrix.c | 938 + reactos/lib/mesa32/src/main/matrix.h | 131 + reactos/lib/mesa32/src/main/mtypes.h | 2320 ++ reactos/lib/mesa32/src/main/nvfragparse.c | 1767 ++ reactos/lib/mesa32/src/main/nvfragparse.h | 52 + reactos/lib/mesa32/src/main/nvfragprog.h | 190 + reactos/lib/mesa32/src/main/nvprogram.c | 871 + reactos/lib/mesa32/src/main/nvprogram.h | 119 + reactos/lib/mesa32/src/main/nvvertexec.c | 839 + reactos/lib/mesa32/src/main/nvvertexec.h | 43 + reactos/lib/mesa32/src/main/nvvertparse.c | 1496 ++ reactos/lib/mesa32/src/main/nvvertparse.h | 50 + reactos/lib/mesa32/src/main/nvvertprog.h | 107 + reactos/lib/mesa32/src/main/occlude.c | 329 + reactos/lib/mesa32/src/main/occlude.h | 58 + reactos/lib/mesa32/src/main/pixel.c | 1529 ++ reactos/lib/mesa32/src/main/pixel.h | 149 + reactos/lib/mesa32/src/main/points.c | 272 + reactos/lib/mesa32/src/main/points.h | 57 + reactos/lib/mesa32/src/main/polygon.c | 304 + reactos/lib/mesa32/src/main/polygon.h | 65 + reactos/lib/mesa32/src/main/program.c | 1244 + reactos/lib/mesa32/src/main/program.h | 236 + reactos/lib/mesa32/src/main/rastpos.c | 905 + reactos/lib/mesa32/src/main/rastpos.h | 193 + reactos/lib/mesa32/src/main/simple_list.h | 197 + reactos/lib/mesa32/src/main/state.c | 935 + reactos/lib/mesa32/src/main/state.h | 46 + reactos/lib/mesa32/src/main/stencil.c | 296 + reactos/lib/mesa32/src/main/stencil.h | 61 + reactos/lib/mesa32/src/main/texcompress.c | 274 + reactos/lib/mesa32/src/main/texcompress.h | 64 + reactos/lib/mesa32/src/main/texformat.c | 978 + reactos/lib/mesa32/src/main/texformat.h | 180 + reactos/lib/mesa32/src/main/texformat_tmp.h | 529 + reactos/lib/mesa32/src/main/teximage.c | 3204 +++ reactos/lib/mesa32/src/main/teximage.h | 227 + reactos/lib/mesa32/src/main/texobj.c | 1020 + reactos/lib/mesa32/src/main/texobj.h | 101 + reactos/lib/mesa32/src/main/texstate.c | 2996 +++ reactos/lib/mesa32/src/main/texstate.h | 192 + reactos/lib/mesa32/src/main/texstore.c | 2083 ++ reactos/lib/mesa32/src/main/texstore.h | 173 + reactos/lib/mesa32/src/main/texutil.c | 1035 + reactos/lib/mesa32/src/main/texutil.h | 72 + reactos/lib/mesa32/src/main/texutil_tmp.h | 526 + reactos/lib/mesa32/src/main/varray.c | 989 + reactos/lib/mesa32/src/main/varray.h | 160 + reactos/lib/mesa32/src/main/version.h | 52 + reactos/lib/mesa32/src/main/vsnprintf.c | 165 + reactos/lib/mesa32/src/main/vtxfmt.c | 174 + reactos/lib/mesa32/src/main/vtxfmt.h | 43 + reactos/lib/mesa32/src/main/vtxfmt_tmp.h | 478 + reactos/lib/mesa32/src/math/m_clip_tmp.h | 243 + reactos/lib/mesa32/src/math/m_copy_tmp.h | 86 + reactos/lib/mesa32/src/math/m_debug.h | 42 + reactos/lib/mesa32/src/math/m_debug_clip.c | 366 + reactos/lib/mesa32/src/math/m_debug_norm.c | 379 + reactos/lib/mesa32/src/math/m_debug_util.h | 281 + reactos/lib/mesa32/src/math/m_debug_xform.c | 334 + reactos/lib/mesa32/src/math/m_dotprod_tmp.h | 102 + reactos/lib/mesa32/src/math/m_eval.c | 461 + reactos/lib/mesa32/src/math/m_eval.h | 103 + reactos/lib/mesa32/src/math/m_matrix.c | 1486 ++ reactos/lib/mesa32/src/math/m_matrix.h | 248 + reactos/lib/mesa32/src/math/m_norm_tmp.h | 390 + reactos/lib/mesa32/src/math/m_trans_tmp.h | 287 + reactos/lib/mesa32/src/math/m_translate.c | 718 + reactos/lib/mesa32/src/math/m_translate.h | 106 + reactos/lib/mesa32/src/math/m_vector.c | 190 + reactos/lib/mesa32/src/math/m_vector.h | 95 + reactos/lib/mesa32/src/math/m_xform.c | 219 + reactos/lib/mesa32/src/math/m_xform.h | 216 + reactos/lib/mesa32/src/math/m_xform_tmp.h | 806 + reactos/lib/mesa32/src/math/math.dsp | 180 + reactos/lib/mesa32/src/math/mathmod.h | 41 + reactos/lib/mesa32/src/sparc/clip.S | 236 + reactos/lib/mesa32/src/sparc/glapi_sparc.S | 19243 ++++++++++++++++ reactos/lib/mesa32/src/sparc/norm.S | 603 + reactos/lib/mesa32/src/sparc/sparc.c | 187 + reactos/lib/mesa32/src/sparc/sparc.h | 38 + reactos/lib/mesa32/src/sparc/sparc_matrix.h | 170 + reactos/lib/mesa32/src/sparc/xform.S | 1387 ++ reactos/lib/mesa32/src/swrast/s_aaline.c | 554 + reactos/lib/mesa32/src/swrast/s_aaline.h | 39 + reactos/lib/mesa32/src/swrast/s_aalinetemp.h | 317 + reactos/lib/mesa32/src/swrast/s_aatriangle.c | 495 + reactos/lib/mesa32/src/swrast/s_aatriangle.h | 39 + reactos/lib/mesa32/src/swrast/s_aatritemp.h | 554 + reactos/lib/mesa32/src/swrast/s_accum.c | 527 + reactos/lib/mesa32/src/swrast/s_accum.h | 43 + reactos/lib/mesa32/src/swrast/s_alpha.c | 224 + reactos/lib/mesa32/src/swrast/s_alpha.h | 39 + reactos/lib/mesa32/src/swrast/s_alphabuf.c | 337 + reactos/lib/mesa32/src/swrast/s_alphabuf.h | 80 + reactos/lib/mesa32/src/swrast/s_bitmap.c | 256 + reactos/lib/mesa32/src/swrast/s_blend.c | 812 + reactos/lib/mesa32/src/swrast/s_blend.h | 45 + reactos/lib/mesa32/src/swrast/s_buffers.c | 287 + reactos/lib/mesa32/src/swrast/s_context.c | 683 + reactos/lib/mesa32/src/swrast/s_context.h | 383 + reactos/lib/mesa32/src/swrast/s_copypix.c | 846 + reactos/lib/mesa32/src/swrast/s_depth.c | 1777 ++ reactos/lib/mesa32/src/swrast/s_depth.h | 64 + reactos/lib/mesa32/src/swrast/s_drawpix.c | 999 + reactos/lib/mesa32/src/swrast/s_drawpix.h | 41 + reactos/lib/mesa32/src/swrast/s_feedback.c | 165 + reactos/lib/mesa32/src/swrast/s_feedback.h | 51 + reactos/lib/mesa32/src/swrast/s_fog.c | 313 + reactos/lib/mesa32/src/swrast/s_fog.h | 45 + reactos/lib/mesa32/src/swrast/s_imaging.c | 155 + reactos/lib/mesa32/src/swrast/s_lines.c | 342 + reactos/lib/mesa32/src/swrast/s_lines.h | 41 + reactos/lib/mesa32/src/swrast/s_linetemp.h | 447 + reactos/lib/mesa32/src/swrast/s_logic.c | 497 + reactos/lib/mesa32/src/swrast/s_logic.h | 45 + reactos/lib/mesa32/src/swrast/s_masking.c | 191 + reactos/lib/mesa32/src/swrast/s_masking.h | 61 + reactos/lib/mesa32/src/swrast/s_nvfragprog.c | 1382 ++ reactos/lib/mesa32/src/swrast/s_nvfragprog.h | 38 + reactos/lib/mesa32/src/swrast/s_pixeltex.c | 117 + reactos/lib/mesa32/src/swrast/s_pixeltex.h | 38 + reactos/lib/mesa32/src/swrast/s_points.c | 275 + reactos/lib/mesa32/src/swrast/s_points.h | 39 + reactos/lib/mesa32/src/swrast/s_pointtemp.h | 384 + reactos/lib/mesa32/src/swrast/s_readpix.c | 535 + reactos/lib/mesa32/src/swrast/s_span.c | 1520 ++ reactos/lib/mesa32/src/swrast/s_span.h | 75 + reactos/lib/mesa32/src/swrast/s_spantemp.h | 376 + reactos/lib/mesa32/src/swrast/s_stencil.c | 1326 ++ reactos/lib/mesa32/src/swrast/s_stencil.h | 59 + reactos/lib/mesa32/src/swrast/s_texstore.c | 429 + reactos/lib/mesa32/src/swrast/s_texture.c | 4292 ++++ reactos/lib/mesa32/src/swrast/s_texture.h | 47 + reactos/lib/mesa32/src/swrast/s_triangle.c | 1155 + reactos/lib/mesa32/src/swrast/s_triangle.h | 51 + reactos/lib/mesa32/src/swrast/s_trispan.h | 31 + reactos/lib/mesa32/src/swrast/s_tritemp.h | 1183 + reactos/lib/mesa32/src/swrast/s_zoom.c | 428 + reactos/lib/mesa32/src/swrast/s_zoom.h | 54 + reactos/lib/mesa32/src/swrast/swrast.dsp | 324 + reactos/lib/mesa32/src/swrast/swrast.h | 458 + .../lib/mesa32/src/swrast_setup/ss_context.c | 250 + .../lib/mesa32/src/swrast_setup/ss_context.h | 45 + .../lib/mesa32/src/swrast_setup/ss_triangle.c | 314 + .../lib/mesa32/src/swrast_setup/ss_triangle.h | 39 + .../lib/mesa32/src/swrast_setup/ss_tritmp.h | 209 + reactos/lib/mesa32/src/swrast_setup/ss_vb.h | 38 + .../mesa32/src/swrast_setup/swrast_setup.dsp | 124 + .../mesa32/src/swrast_setup/swrast_setup.h | 61 + reactos/lib/mesa32/src/tnl/t_array_api.c | 441 + reactos/lib/mesa32/src/tnl/t_array_api.h | 46 + reactos/lib/mesa32/src/tnl/t_array_import.c | 360 + reactos/lib/mesa32/src/tnl/t_array_import.h | 36 + reactos/lib/mesa32/src/tnl/t_context.c | 261 + reactos/lib/mesa32/src/tnl/t_context.h | 734 + reactos/lib/mesa32/src/tnl/t_pipeline.c | 216 + reactos/lib/mesa32/src/tnl/t_pipeline.h | 75 + reactos/lib/mesa32/src/tnl/t_save_api.c | 1587 ++ reactos/lib/mesa32/src/tnl/t_save_api.h | 58 + reactos/lib/mesa32/src/tnl/t_save_loopback.c | 305 + reactos/lib/mesa32/src/tnl/t_save_playback.c | 217 + reactos/lib/mesa32/src/tnl/t_vb_cliptmp.h | 270 + reactos/lib/mesa32/src/tnl/t_vb_fog.c | 254 + reactos/lib/mesa32/src/tnl/t_vb_light.c | 367 + reactos/lib/mesa32/src/tnl/t_vb_lighttmp.h | 817 + reactos/lib/mesa32/src/tnl/t_vb_normals.c | 201 + reactos/lib/mesa32/src/tnl/t_vb_points.c | 124 + reactos/lib/mesa32/src/tnl/t_vb_program.c | 365 + reactos/lib/mesa32/src/tnl/t_vb_render.c | 377 + reactos/lib/mesa32/src/tnl/t_vb_rendertmp.h | 440 + reactos/lib/mesa32/src/tnl/t_vb_texgen.c | 691 + reactos/lib/mesa32/src/tnl/t_vb_texmat.c | 150 + reactos/lib/mesa32/src/tnl/t_vb_vertex.c | 303 + reactos/lib/mesa32/src/tnl/t_vertex.c | 1066 + reactos/lib/mesa32/src/tnl/t_vertex.h | 119 + reactos/lib/mesa32/src/tnl/t_vtx_api.c | 1194 + reactos/lib/mesa32/src/tnl/t_vtx_api.h | 58 + reactos/lib/mesa32/src/tnl/t_vtx_eval.c | 253 + reactos/lib/mesa32/src/tnl/t_vtx_exec.c | 289 + reactos/lib/mesa32/src/tnl/tnl.dsp | 212 + reactos/lib/mesa32/src/tnl/tnl.h | 78 + reactos/lib/mesa32/src/tnl_dd/imm/NOTES.imm | 112 + .../lib/mesa32/src/tnl_dd/imm/t_dd_imm_capi.h | 419 + .../lib/mesa32/src/tnl_dd/imm/t_dd_imm_napi.h | 226 + .../mesa32/src/tnl_dd/imm/t_dd_imm_primtmp.h | 570 + .../lib/mesa32/src/tnl_dd/imm/t_dd_imm_tapi.h | 75 + .../lib/mesa32/src/tnl_dd/imm/t_dd_imm_vapi.h | 159 + .../lib/mesa32/src/tnl_dd/imm/t_dd_imm_vb.c | 204 + .../mesa32/src/tnl_dd/imm/t_dd_imm_vbtmp.h | 268 + reactos/lib/mesa32/src/tnl_dd/t_dd.c | 58 + reactos/lib/mesa32/src/tnl_dd/t_dd_dmatmp.h | 1234 + reactos/lib/mesa32/src/tnl_dd/t_dd_dmatmp2.h | 914 + .../lib/mesa32/src/tnl_dd/t_dd_rendertmp.h | 434 + reactos/lib/mesa32/src/tnl_dd/t_dd_triemit.h | 157 + reactos/lib/mesa32/src/tnl_dd/t_dd_tritmp.h | 743 + reactos/lib/mesa32/src/tnl_dd/t_dd_unfilled.h | 212 + reactos/lib/mesa32/src/tnl_dd/t_dd_vb.c | 344 + reactos/lib/mesa32/src/tnl_dd/t_dd_vbtmp.h | 665 + reactos/lib/mesa32/src/tnl_dd/t_dd_vertex.h | 78 + reactos/lib/mesa32/src/x86/3dnow.c | 92 + reactos/lib/mesa32/src/x86/3dnow.h | 39 + reactos/lib/mesa32/src/x86/3dnow_normal.S | 836 + reactos/lib/mesa32/src/x86/3dnow_xform1.S | 423 + reactos/lib/mesa32/src/x86/3dnow_xform2.S | 464 + reactos/lib/mesa32/src/x86/3dnow_xform3.S | 548 + reactos/lib/mesa32/src/x86/3dnow_xform4.S | 557 + reactos/lib/mesa32/src/x86/assyntax.h | 1715 ++ reactos/lib/mesa32/src/x86/clip_args.h | 60 + reactos/lib/mesa32/src/x86/common_x86.c | 366 + reactos/lib/mesa32/src/x86/common_x86_asm.S | 203 + reactos/lib/mesa32/src/x86/common_x86_asm.h | 64 + .../lib/mesa32/src/x86/common_x86_features.h | 68 + .../lib/mesa32/src/x86/common_x86_macros.h | 107 + reactos/lib/mesa32/src/x86/gen_matypes.c | 251 + reactos/lib/mesa32/src/x86/glapi_x86.S | 5522 +++++ reactos/lib/mesa32/src/x86/matypes.h | 165 + reactos/lib/mesa32/src/x86/mmx.h | 51 + reactos/lib/mesa32/src/x86/mmx_blend.S | 363 + reactos/lib/mesa32/src/x86/mmx_blendtmp.h | 114 + reactos/lib/mesa32/src/x86/norm_args.h | 58 + reactos/lib/mesa32/src/x86/sse.c | 123 + reactos/lib/mesa32/src/x86/sse.h | 39 + reactos/lib/mesa32/src/x86/sse_normal.S | 252 + reactos/lib/mesa32/src/x86/sse_xform1.S | 433 + reactos/lib/mesa32/src/x86/sse_xform2.S | 452 + reactos/lib/mesa32/src/x86/sse_xform3.S | 498 + reactos/lib/mesa32/src/x86/sse_xform4.S | 226 + reactos/lib/mesa32/src/x86/x86.c | 96 + reactos/lib/mesa32/src/x86/x86.h | 36 + reactos/lib/mesa32/src/x86/x86_cliptest.S | 401 + reactos/lib/mesa32/src/x86/x86_xform2.S | 563 + reactos/lib/mesa32/src/x86/x86_xform3.S | 633 + reactos/lib/mesa32/src/x86/x86_xform4.S | 666 + reactos/lib/mesa32/src/x86/xform_args.h | 52 + 442 files changed, 253433 insertions(+) create mode 100644 reactos/lib/mesa32/src/array_cache/ac_context.c create mode 100644 reactos/lib/mesa32/src/array_cache/ac_context.h create mode 100644 reactos/lib/mesa32/src/array_cache/ac_import.c create mode 100644 reactos/lib/mesa32/src/array_cache/acache.h create mode 100644 reactos/lib/mesa32/src/array_cache/array_cache.dsp create mode 100644 reactos/lib/mesa32/src/drivers/beos/GLView.cpp create mode 100644 reactos/lib/mesa32/src/drivers/beos/GLView.h create mode 100644 reactos/lib/mesa32/src/drivers/common/t_dd.c create mode 100644 reactos/lib/mesa32/src/drivers/common/t_dd_dmatmp.h create mode 100644 reactos/lib/mesa32/src/drivers/common/t_dd_dmatmp2.h create mode 100644 reactos/lib/mesa32/src/drivers/common/t_dd_rendertmp.h create mode 100644 reactos/lib/mesa32/src/drivers/common/t_dd_triemit.h create mode 100644 reactos/lib/mesa32/src/drivers/common/t_dd_tritmp.h create mode 100644 reactos/lib/mesa32/src/drivers/common/t_dd_unfilled.h create mode 100644 reactos/lib/mesa32/src/drivers/common/t_dd_vb.c create mode 100644 reactos/lib/mesa32/src/drivers/common/t_dd_vbtmp.h create mode 100644 reactos/lib/mesa32/src/drivers/common/t_dd_vertex.h create mode 100644 reactos/lib/mesa32/src/drivers/dos/blit.S create mode 100644 reactos/lib/mesa32/src/drivers/dos/dmesa.c create mode 100644 reactos/lib/mesa32/src/drivers/dos/dpmi.c create mode 100644 reactos/lib/mesa32/src/drivers/dos/internal.h create mode 100644 reactos/lib/mesa32/src/drivers/dos/vesa.c create mode 100644 reactos/lib/mesa32/src/drivers/dos/vesa.h create mode 100644 reactos/lib/mesa32/src/drivers/dos/vga.c create mode 100644 reactos/lib/mesa32/src/drivers/dos/vga.h create mode 100644 reactos/lib/mesa32/src/drivers/dos/video.c create mode 100644 reactos/lib/mesa32/src/drivers/dos/video.h create mode 100644 reactos/lib/mesa32/src/drivers/dos/virtual.S create mode 100644 reactos/lib/mesa32/src/drivers/dri/common/depthtmp.h create mode 100644 reactos/lib/mesa32/src/drivers/dri/common/mm.c create mode 100644 reactos/lib/mesa32/src/drivers/dri/common/mm.h create mode 100644 reactos/lib/mesa32/src/drivers/dri/common/mmx.h create mode 100644 reactos/lib/mesa32/src/drivers/dri/common/spantmp.h create mode 100644 reactos/lib/mesa32/src/drivers/dri/common/stenciltmp.h create mode 100644 reactos/lib/mesa32/src/drivers/dri/common/texmem.c create mode 100644 reactos/lib/mesa32/src/drivers/dri/common/texmem.h create mode 100644 reactos/lib/mesa32/src/drivers/dri/common/utils.c create mode 100644 reactos/lib/mesa32/src/drivers/dri/common/utils.h create mode 100644 reactos/lib/mesa32/src/drivers/dri/common/vblank.c create mode 100644 reactos/lib/mesa32/src/drivers/dri/common/vblank.h create mode 100644 reactos/lib/mesa32/src/drivers/dri/common/xmlconfig.c create mode 100644 reactos/lib/mesa32/src/drivers/dri/common/xmlconfig.h create mode 100644 reactos/lib/mesa32/src/drivers/dri/common/xmlpool.h create mode 100644 reactos/lib/mesa32/src/drivers/fbdev/glfbdev.c create mode 100644 reactos/lib/mesa32/src/drivers/ggi/default/genkgi.conf.in create mode 100644 reactos/lib/mesa32/src/drivers/ggi/default/genkgi_mode.c create mode 100644 reactos/lib/mesa32/src/drivers/ggi/default/genkgi_visual.c create mode 100644 reactos/lib/mesa32/src/drivers/ggi/default/linear.c create mode 100644 reactos/lib/mesa32/src/drivers/ggi/default/linear_15.c create mode 100644 reactos/lib/mesa32/src/drivers/ggi/default/linear_16.c create mode 100644 reactos/lib/mesa32/src/drivers/ggi/default/linear_24.c create mode 100644 reactos/lib/mesa32/src/drivers/ggi/default/linear_32.c create mode 100644 reactos/lib/mesa32/src/drivers/ggi/default/linear_8.c create mode 100644 reactos/lib/mesa32/src/drivers/ggi/default/stubs.c create mode 100644 reactos/lib/mesa32/src/drivers/ggi/display/fbdev.conf.in create mode 100644 reactos/lib/mesa32/src/drivers/ggi/display/fbdev_mode.c create mode 100644 reactos/lib/mesa32/src/drivers/ggi/display/fbdev_visual.c create mode 100644 reactos/lib/mesa32/src/drivers/ggi/include/ggi/mesa/debug.h create mode 100644 reactos/lib/mesa32/src/drivers/ggi/include/ggi/mesa/display_fbdev.h create mode 100644 reactos/lib/mesa32/src/drivers/ggi/include/ggi/mesa/ggimesa.h create mode 100644 reactos/lib/mesa32/src/drivers/ggi/include/ggi/mesa/ggimesa_int.h create mode 100644 reactos/lib/mesa32/src/drivers/glide/fxapi.c create mode 100644 reactos/lib/mesa32/src/drivers/glide/fxdd.c create mode 100644 reactos/lib/mesa32/src/drivers/glide/fxddspan.c create mode 100644 reactos/lib/mesa32/src/drivers/glide/fxddtex.c create mode 100644 reactos/lib/mesa32/src/drivers/glide/fxdrv.h create mode 100644 reactos/lib/mesa32/src/drivers/glide/fxg.c create mode 100644 reactos/lib/mesa32/src/drivers/glide/fxg.h create mode 100644 reactos/lib/mesa32/src/drivers/glide/fxglidew.c create mode 100644 reactos/lib/mesa32/src/drivers/glide/fxglidew.h create mode 100644 reactos/lib/mesa32/src/drivers/glide/fxopengl.def create mode 100644 reactos/lib/mesa32/src/drivers/glide/fxsetup.c create mode 100644 reactos/lib/mesa32/src/drivers/glide/fxsetup.h create mode 100644 reactos/lib/mesa32/src/drivers/glide/fxtexman.c create mode 100644 reactos/lib/mesa32/src/drivers/glide/fxtris.c create mode 100644 reactos/lib/mesa32/src/drivers/glide/fxvb.c create mode 100644 reactos/lib/mesa32/src/drivers/glide/fxvbtmp.h create mode 100644 reactos/lib/mesa32/src/drivers/glide/fxwgl.c create mode 100644 reactos/lib/mesa32/src/drivers/osmesa/Makefile.win create mode 100644 reactos/lib/mesa32/src/drivers/osmesa/osmesa.c create mode 100644 reactos/lib/mesa32/src/drivers/osmesa/osmesa.def create mode 100644 reactos/lib/mesa32/src/drivers/osmesa/osmesa.dsp create mode 100644 reactos/lib/mesa32/src/drivers/svga/svgamesa.c create mode 100644 reactos/lib/mesa32/src/drivers/svga/svgamesa15.c create mode 100644 reactos/lib/mesa32/src/drivers/svga/svgamesa15.h create mode 100644 reactos/lib/mesa32/src/drivers/svga/svgamesa16.c create mode 100644 reactos/lib/mesa32/src/drivers/svga/svgamesa16.h create mode 100644 reactos/lib/mesa32/src/drivers/svga/svgamesa24.c create mode 100644 reactos/lib/mesa32/src/drivers/svga/svgamesa24.h create mode 100644 reactos/lib/mesa32/src/drivers/svga/svgamesa32.c create mode 100644 reactos/lib/mesa32/src/drivers/svga/svgamesa32.h create mode 100644 reactos/lib/mesa32/src/drivers/svga/svgamesa8.c create mode 100644 reactos/lib/mesa32/src/drivers/svga/svgamesa8.h create mode 100644 reactos/lib/mesa32/src/drivers/svga/svgapix.h create mode 100644 reactos/lib/mesa32/src/drivers/windows/gdi/colors.h create mode 100644 reactos/lib/mesa32/src/drivers/windows/gdi/gdi.dsp create mode 100644 reactos/lib/mesa32/src/drivers/windows/gdi/mesa.def create mode 100644 reactos/lib/mesa32/src/drivers/windows/gdi/wgl.c create mode 100644 reactos/lib/mesa32/src/drivers/windows/gdi/wmesa.c create mode 100644 reactos/lib/mesa32/src/drivers/windows/gdi/wmesadef.h create mode 100644 reactos/lib/mesa32/src/drivers/windows/icd/colors.h create mode 100644 reactos/lib/mesa32/src/drivers/windows/icd/icd.c create mode 100644 reactos/lib/mesa32/src/drivers/windows/icd/icdlist.h create mode 100644 reactos/lib/mesa32/src/drivers/windows/icd/mesa.def create mode 100644 reactos/lib/mesa32/src/drivers/windows/icd/wmesadef.h create mode 100644 reactos/lib/mesa32/src/drivers/x11/fakeglx.c create mode 100644 reactos/lib/mesa32/src/drivers/x11/glxapi.c create mode 100644 reactos/lib/mesa32/src/drivers/x11/glxapi.h create mode 100644 reactos/lib/mesa32/src/drivers/x11/glxheader.h create mode 100644 reactos/lib/mesa32/src/drivers/x11/realglx.c create mode 100644 reactos/lib/mesa32/src/drivers/x11/realglx.h create mode 100644 reactos/lib/mesa32/src/drivers/x11/xfonts.c create mode 100644 reactos/lib/mesa32/src/drivers/x11/xfonts.h create mode 100644 reactos/lib/mesa32/src/drivers/x11/xm_api.c create mode 100644 reactos/lib/mesa32/src/drivers/x11/xm_dd.c create mode 100644 reactos/lib/mesa32/src/drivers/x11/xm_line.c create mode 100644 reactos/lib/mesa32/src/drivers/x11/xm_span.c create mode 100644 reactos/lib/mesa32/src/drivers/x11/xm_tri.c create mode 100644 reactos/lib/mesa32/src/drivers/x11/xmesaP.h create mode 100644 reactos/lib/mesa32/src/glapi/glapi.c create mode 100644 reactos/lib/mesa32/src/glapi/glapi.dsp create mode 100644 reactos/lib/mesa32/src/glapi/glapi.h create mode 100644 reactos/lib/mesa32/src/glapi/glapioffsets.h create mode 100644 reactos/lib/mesa32/src/glapi/glapitable.h create mode 100644 reactos/lib/mesa32/src/glapi/glapitemp.h create mode 100644 reactos/lib/mesa32/src/glapi/glprocs.h create mode 100644 reactos/lib/mesa32/src/glapi/glthread.c create mode 100644 reactos/lib/mesa32/src/glapi/glthread.h create mode 100644 reactos/lib/mesa32/src/main/accum.c create mode 100644 reactos/lib/mesa32/src/main/accum.h create mode 100644 reactos/lib/mesa32/src/main/api_arrayelt.c create mode 100644 reactos/lib/mesa32/src/main/api_arrayelt.h create mode 100644 reactos/lib/mesa32/src/main/api_eval.h create mode 100644 reactos/lib/mesa32/src/main/api_loopback.c create mode 100644 reactos/lib/mesa32/src/main/api_loopback.h create mode 100644 reactos/lib/mesa32/src/main/api_noop.c create mode 100644 reactos/lib/mesa32/src/main/api_noop.h create mode 100644 reactos/lib/mesa32/src/main/api_validate.c create mode 100644 reactos/lib/mesa32/src/main/api_validate.h create mode 100644 reactos/lib/mesa32/src/main/arbfragparse.c create mode 100644 reactos/lib/mesa32/src/main/arbfragparse.h create mode 100644 reactos/lib/mesa32/src/main/arbparse.c create mode 100644 reactos/lib/mesa32/src/main/arbparse.h create mode 100644 reactos/lib/mesa32/src/main/arbparse_syn.h create mode 100644 reactos/lib/mesa32/src/main/arbprogram.c create mode 100644 reactos/lib/mesa32/src/main/arbprogram.h create mode 100644 reactos/lib/mesa32/src/main/arbvertparse.c create mode 100644 reactos/lib/mesa32/src/main/arbvertparse.h create mode 100644 reactos/lib/mesa32/src/main/attrib.c create mode 100644 reactos/lib/mesa32/src/main/attrib.h create mode 100644 reactos/lib/mesa32/src/main/blend.c create mode 100644 reactos/lib/mesa32/src/main/blend.h create mode 100644 reactos/lib/mesa32/src/main/bufferobj.c create mode 100644 reactos/lib/mesa32/src/main/bufferobj.h create mode 100644 reactos/lib/mesa32/src/main/buffers.c create mode 100644 reactos/lib/mesa32/src/main/buffers.h create mode 100644 reactos/lib/mesa32/src/main/clip.c create mode 100644 reactos/lib/mesa32/src/main/clip.h create mode 100644 reactos/lib/mesa32/src/main/colormac.h create mode 100644 reactos/lib/mesa32/src/main/colortab.c create mode 100644 reactos/lib/mesa32/src/main/colortab.h create mode 100644 reactos/lib/mesa32/src/main/config.h create mode 100644 reactos/lib/mesa32/src/main/context.c create mode 100644 reactos/lib/mesa32/src/main/context.h create mode 100644 reactos/lib/mesa32/src/main/convolve.c create mode 100644 reactos/lib/mesa32/src/main/convolve.h create mode 100644 reactos/lib/mesa32/src/main/dd.h create mode 100644 reactos/lib/mesa32/src/main/debug.c create mode 100644 reactos/lib/mesa32/src/main/debug.h create mode 100644 reactos/lib/mesa32/src/main/depth.c create mode 100644 reactos/lib/mesa32/src/main/depth.h create mode 100644 reactos/lib/mesa32/src/main/dispatch.c create mode 100644 reactos/lib/mesa32/src/main/dlist.c create mode 100644 reactos/lib/mesa32/src/main/dlist.h create mode 100644 reactos/lib/mesa32/src/main/drawpix.c create mode 100644 reactos/lib/mesa32/src/main/drawpix.h create mode 100644 reactos/lib/mesa32/src/main/enable.c create mode 100644 reactos/lib/mesa32/src/main/enable.h create mode 100644 reactos/lib/mesa32/src/main/enums.c create mode 100644 reactos/lib/mesa32/src/main/enums.h create mode 100644 reactos/lib/mesa32/src/main/eval.c create mode 100644 reactos/lib/mesa32/src/main/eval.h create mode 100644 reactos/lib/mesa32/src/main/extensions.c create mode 100644 reactos/lib/mesa32/src/main/extensions.h create mode 100644 reactos/lib/mesa32/src/main/feedback.c create mode 100644 reactos/lib/mesa32/src/main/feedback.h create mode 100644 reactos/lib/mesa32/src/main/fog.c create mode 100644 reactos/lib/mesa32/src/main/fog.h create mode 100644 reactos/lib/mesa32/src/main/get.c create mode 100644 reactos/lib/mesa32/src/main/get.h create mode 100644 reactos/lib/mesa32/src/main/glheader.h create mode 100644 reactos/lib/mesa32/src/main/hash.c create mode 100644 reactos/lib/mesa32/src/main/hash.h create mode 100644 reactos/lib/mesa32/src/main/hint.c create mode 100644 reactos/lib/mesa32/src/main/hint.h create mode 100644 reactos/lib/mesa32/src/main/histogram.c create mode 100644 reactos/lib/mesa32/src/main/histogram.h create mode 100644 reactos/lib/mesa32/src/main/image.c create mode 100644 reactos/lib/mesa32/src/main/image.h create mode 100644 reactos/lib/mesa32/src/main/imports.c create mode 100644 reactos/lib/mesa32/src/main/imports.h create mode 100644 reactos/lib/mesa32/src/main/light.c create mode 100644 reactos/lib/mesa32/src/main/light.h create mode 100644 reactos/lib/mesa32/src/main/lines.c create mode 100644 reactos/lib/mesa32/src/main/lines.h create mode 100644 reactos/lib/mesa32/src/main/macros.h create mode 100644 reactos/lib/mesa32/src/main/main.dsp create mode 100644 reactos/lib/mesa32/src/main/matrix.c create mode 100644 reactos/lib/mesa32/src/main/matrix.h create mode 100644 reactos/lib/mesa32/src/main/mtypes.h create mode 100644 reactos/lib/mesa32/src/main/nvfragparse.c create mode 100644 reactos/lib/mesa32/src/main/nvfragparse.h create mode 100644 reactos/lib/mesa32/src/main/nvfragprog.h create mode 100644 reactos/lib/mesa32/src/main/nvprogram.c create mode 100644 reactos/lib/mesa32/src/main/nvprogram.h create mode 100644 reactos/lib/mesa32/src/main/nvvertexec.c create mode 100644 reactos/lib/mesa32/src/main/nvvertexec.h create mode 100644 reactos/lib/mesa32/src/main/nvvertparse.c create mode 100644 reactos/lib/mesa32/src/main/nvvertparse.h create mode 100644 reactos/lib/mesa32/src/main/nvvertprog.h create mode 100644 reactos/lib/mesa32/src/main/occlude.c create mode 100644 reactos/lib/mesa32/src/main/occlude.h create mode 100644 reactos/lib/mesa32/src/main/pixel.c create mode 100644 reactos/lib/mesa32/src/main/pixel.h create mode 100644 reactos/lib/mesa32/src/main/points.c create mode 100644 reactos/lib/mesa32/src/main/points.h create mode 100644 reactos/lib/mesa32/src/main/polygon.c create mode 100644 reactos/lib/mesa32/src/main/polygon.h create mode 100644 reactos/lib/mesa32/src/main/program.c create mode 100644 reactos/lib/mesa32/src/main/program.h create mode 100644 reactos/lib/mesa32/src/main/rastpos.c create mode 100644 reactos/lib/mesa32/src/main/rastpos.h create mode 100644 reactos/lib/mesa32/src/main/simple_list.h create mode 100644 reactos/lib/mesa32/src/main/state.c create mode 100644 reactos/lib/mesa32/src/main/state.h create mode 100644 reactos/lib/mesa32/src/main/stencil.c create mode 100644 reactos/lib/mesa32/src/main/stencil.h create mode 100644 reactos/lib/mesa32/src/main/texcompress.c create mode 100644 reactos/lib/mesa32/src/main/texcompress.h create mode 100644 reactos/lib/mesa32/src/main/texformat.c create mode 100644 reactos/lib/mesa32/src/main/texformat.h create mode 100644 reactos/lib/mesa32/src/main/texformat_tmp.h create mode 100644 reactos/lib/mesa32/src/main/teximage.c create mode 100644 reactos/lib/mesa32/src/main/teximage.h create mode 100644 reactos/lib/mesa32/src/main/texobj.c create mode 100644 reactos/lib/mesa32/src/main/texobj.h create mode 100644 reactos/lib/mesa32/src/main/texstate.c create mode 100644 reactos/lib/mesa32/src/main/texstate.h create mode 100644 reactos/lib/mesa32/src/main/texstore.c create mode 100644 reactos/lib/mesa32/src/main/texstore.h create mode 100644 reactos/lib/mesa32/src/main/texutil.c create mode 100644 reactos/lib/mesa32/src/main/texutil.h create mode 100644 reactos/lib/mesa32/src/main/texutil_tmp.h create mode 100644 reactos/lib/mesa32/src/main/varray.c create mode 100644 reactos/lib/mesa32/src/main/varray.h create mode 100644 reactos/lib/mesa32/src/main/version.h create mode 100644 reactos/lib/mesa32/src/main/vsnprintf.c create mode 100644 reactos/lib/mesa32/src/main/vtxfmt.c create mode 100644 reactos/lib/mesa32/src/main/vtxfmt.h create mode 100644 reactos/lib/mesa32/src/main/vtxfmt_tmp.h create mode 100644 reactos/lib/mesa32/src/math/m_clip_tmp.h create mode 100644 reactos/lib/mesa32/src/math/m_copy_tmp.h create mode 100644 reactos/lib/mesa32/src/math/m_debug.h create mode 100644 reactos/lib/mesa32/src/math/m_debug_clip.c create mode 100644 reactos/lib/mesa32/src/math/m_debug_norm.c create mode 100644 reactos/lib/mesa32/src/math/m_debug_util.h create mode 100644 reactos/lib/mesa32/src/math/m_debug_xform.c create mode 100644 reactos/lib/mesa32/src/math/m_dotprod_tmp.h create mode 100644 reactos/lib/mesa32/src/math/m_eval.c create mode 100644 reactos/lib/mesa32/src/math/m_eval.h create mode 100644 reactos/lib/mesa32/src/math/m_matrix.c create mode 100644 reactos/lib/mesa32/src/math/m_matrix.h create mode 100644 reactos/lib/mesa32/src/math/m_norm_tmp.h create mode 100644 reactos/lib/mesa32/src/math/m_trans_tmp.h create mode 100644 reactos/lib/mesa32/src/math/m_translate.c create mode 100644 reactos/lib/mesa32/src/math/m_translate.h create mode 100644 reactos/lib/mesa32/src/math/m_vector.c create mode 100644 reactos/lib/mesa32/src/math/m_vector.h create mode 100644 reactos/lib/mesa32/src/math/m_xform.c create mode 100644 reactos/lib/mesa32/src/math/m_xform.h create mode 100644 reactos/lib/mesa32/src/math/m_xform_tmp.h create mode 100644 reactos/lib/mesa32/src/math/math.dsp create mode 100644 reactos/lib/mesa32/src/math/mathmod.h create mode 100644 reactos/lib/mesa32/src/sparc/clip.S create mode 100644 reactos/lib/mesa32/src/sparc/glapi_sparc.S create mode 100644 reactos/lib/mesa32/src/sparc/norm.S create mode 100644 reactos/lib/mesa32/src/sparc/sparc.c create mode 100644 reactos/lib/mesa32/src/sparc/sparc.h create mode 100644 reactos/lib/mesa32/src/sparc/sparc_matrix.h create mode 100644 reactos/lib/mesa32/src/sparc/xform.S create mode 100644 reactos/lib/mesa32/src/swrast/s_aaline.c create mode 100644 reactos/lib/mesa32/src/swrast/s_aaline.h create mode 100644 reactos/lib/mesa32/src/swrast/s_aalinetemp.h create mode 100644 reactos/lib/mesa32/src/swrast/s_aatriangle.c create mode 100644 reactos/lib/mesa32/src/swrast/s_aatriangle.h create mode 100644 reactos/lib/mesa32/src/swrast/s_aatritemp.h create mode 100644 reactos/lib/mesa32/src/swrast/s_accum.c create mode 100644 reactos/lib/mesa32/src/swrast/s_accum.h create mode 100644 reactos/lib/mesa32/src/swrast/s_alpha.c create mode 100644 reactos/lib/mesa32/src/swrast/s_alpha.h create mode 100644 reactos/lib/mesa32/src/swrast/s_alphabuf.c create mode 100644 reactos/lib/mesa32/src/swrast/s_alphabuf.h create mode 100644 reactos/lib/mesa32/src/swrast/s_bitmap.c create mode 100644 reactos/lib/mesa32/src/swrast/s_blend.c create mode 100644 reactos/lib/mesa32/src/swrast/s_blend.h create mode 100644 reactos/lib/mesa32/src/swrast/s_buffers.c create mode 100644 reactos/lib/mesa32/src/swrast/s_context.c create mode 100644 reactos/lib/mesa32/src/swrast/s_context.h create mode 100644 reactos/lib/mesa32/src/swrast/s_copypix.c create mode 100644 reactos/lib/mesa32/src/swrast/s_depth.c create mode 100644 reactos/lib/mesa32/src/swrast/s_depth.h create mode 100644 reactos/lib/mesa32/src/swrast/s_drawpix.c create mode 100644 reactos/lib/mesa32/src/swrast/s_drawpix.h create mode 100644 reactos/lib/mesa32/src/swrast/s_feedback.c create mode 100644 reactos/lib/mesa32/src/swrast/s_feedback.h create mode 100644 reactos/lib/mesa32/src/swrast/s_fog.c create mode 100644 reactos/lib/mesa32/src/swrast/s_fog.h create mode 100644 reactos/lib/mesa32/src/swrast/s_imaging.c create mode 100644 reactos/lib/mesa32/src/swrast/s_lines.c create mode 100644 reactos/lib/mesa32/src/swrast/s_lines.h create mode 100644 reactos/lib/mesa32/src/swrast/s_linetemp.h create mode 100644 reactos/lib/mesa32/src/swrast/s_logic.c create mode 100644 reactos/lib/mesa32/src/swrast/s_logic.h create mode 100644 reactos/lib/mesa32/src/swrast/s_masking.c create mode 100644 reactos/lib/mesa32/src/swrast/s_masking.h create mode 100644 reactos/lib/mesa32/src/swrast/s_nvfragprog.c create mode 100644 reactos/lib/mesa32/src/swrast/s_nvfragprog.h create mode 100644 reactos/lib/mesa32/src/swrast/s_pixeltex.c create mode 100644 reactos/lib/mesa32/src/swrast/s_pixeltex.h create mode 100644 reactos/lib/mesa32/src/swrast/s_points.c create mode 100644 reactos/lib/mesa32/src/swrast/s_points.h create mode 100644 reactos/lib/mesa32/src/swrast/s_pointtemp.h create mode 100644 reactos/lib/mesa32/src/swrast/s_readpix.c create mode 100644 reactos/lib/mesa32/src/swrast/s_span.c create mode 100644 reactos/lib/mesa32/src/swrast/s_span.h create mode 100644 reactos/lib/mesa32/src/swrast/s_spantemp.h create mode 100644 reactos/lib/mesa32/src/swrast/s_stencil.c create mode 100644 reactos/lib/mesa32/src/swrast/s_stencil.h create mode 100644 reactos/lib/mesa32/src/swrast/s_texstore.c create mode 100644 reactos/lib/mesa32/src/swrast/s_texture.c create mode 100644 reactos/lib/mesa32/src/swrast/s_texture.h create mode 100644 reactos/lib/mesa32/src/swrast/s_triangle.c create mode 100644 reactos/lib/mesa32/src/swrast/s_triangle.h create mode 100644 reactos/lib/mesa32/src/swrast/s_trispan.h create mode 100644 reactos/lib/mesa32/src/swrast/s_tritemp.h create mode 100644 reactos/lib/mesa32/src/swrast/s_zoom.c create mode 100644 reactos/lib/mesa32/src/swrast/s_zoom.h create mode 100644 reactos/lib/mesa32/src/swrast/swrast.dsp create mode 100644 reactos/lib/mesa32/src/swrast/swrast.h create mode 100644 reactos/lib/mesa32/src/swrast_setup/ss_context.c create mode 100644 reactos/lib/mesa32/src/swrast_setup/ss_context.h create mode 100644 reactos/lib/mesa32/src/swrast_setup/ss_triangle.c create mode 100644 reactos/lib/mesa32/src/swrast_setup/ss_triangle.h create mode 100644 reactos/lib/mesa32/src/swrast_setup/ss_tritmp.h create mode 100644 reactos/lib/mesa32/src/swrast_setup/ss_vb.h create mode 100644 reactos/lib/mesa32/src/swrast_setup/swrast_setup.dsp create mode 100644 reactos/lib/mesa32/src/swrast_setup/swrast_setup.h create mode 100644 reactos/lib/mesa32/src/tnl/t_array_api.c create mode 100644 reactos/lib/mesa32/src/tnl/t_array_api.h create mode 100644 reactos/lib/mesa32/src/tnl/t_array_import.c create mode 100644 reactos/lib/mesa32/src/tnl/t_array_import.h create mode 100644 reactos/lib/mesa32/src/tnl/t_context.c create mode 100644 reactos/lib/mesa32/src/tnl/t_context.h create mode 100644 reactos/lib/mesa32/src/tnl/t_pipeline.c create mode 100644 reactos/lib/mesa32/src/tnl/t_pipeline.h create mode 100644 reactos/lib/mesa32/src/tnl/t_save_api.c create mode 100644 reactos/lib/mesa32/src/tnl/t_save_api.h create mode 100644 reactos/lib/mesa32/src/tnl/t_save_loopback.c create mode 100644 reactos/lib/mesa32/src/tnl/t_save_playback.c create mode 100644 reactos/lib/mesa32/src/tnl/t_vb_cliptmp.h create mode 100644 reactos/lib/mesa32/src/tnl/t_vb_fog.c create mode 100644 reactos/lib/mesa32/src/tnl/t_vb_light.c create mode 100644 reactos/lib/mesa32/src/tnl/t_vb_lighttmp.h create mode 100644 reactos/lib/mesa32/src/tnl/t_vb_normals.c create mode 100644 reactos/lib/mesa32/src/tnl/t_vb_points.c create mode 100644 reactos/lib/mesa32/src/tnl/t_vb_program.c create mode 100644 reactos/lib/mesa32/src/tnl/t_vb_render.c create mode 100644 reactos/lib/mesa32/src/tnl/t_vb_rendertmp.h create mode 100644 reactos/lib/mesa32/src/tnl/t_vb_texgen.c create mode 100644 reactos/lib/mesa32/src/tnl/t_vb_texmat.c create mode 100644 reactos/lib/mesa32/src/tnl/t_vb_vertex.c create mode 100644 reactos/lib/mesa32/src/tnl/t_vertex.c create mode 100644 reactos/lib/mesa32/src/tnl/t_vertex.h create mode 100644 reactos/lib/mesa32/src/tnl/t_vtx_api.c create mode 100644 reactos/lib/mesa32/src/tnl/t_vtx_api.h create mode 100644 reactos/lib/mesa32/src/tnl/t_vtx_eval.c create mode 100644 reactos/lib/mesa32/src/tnl/t_vtx_exec.c create mode 100644 reactos/lib/mesa32/src/tnl/tnl.dsp create mode 100644 reactos/lib/mesa32/src/tnl/tnl.h create mode 100644 reactos/lib/mesa32/src/tnl_dd/imm/NOTES.imm create mode 100644 reactos/lib/mesa32/src/tnl_dd/imm/t_dd_imm_capi.h create mode 100644 reactos/lib/mesa32/src/tnl_dd/imm/t_dd_imm_napi.h create mode 100644 reactos/lib/mesa32/src/tnl_dd/imm/t_dd_imm_primtmp.h create mode 100644 reactos/lib/mesa32/src/tnl_dd/imm/t_dd_imm_tapi.h create mode 100644 reactos/lib/mesa32/src/tnl_dd/imm/t_dd_imm_vapi.h create mode 100644 reactos/lib/mesa32/src/tnl_dd/imm/t_dd_imm_vb.c create mode 100644 reactos/lib/mesa32/src/tnl_dd/imm/t_dd_imm_vbtmp.h create mode 100644 reactos/lib/mesa32/src/tnl_dd/t_dd.c create mode 100644 reactos/lib/mesa32/src/tnl_dd/t_dd_dmatmp.h create mode 100644 reactos/lib/mesa32/src/tnl_dd/t_dd_dmatmp2.h create mode 100644 reactos/lib/mesa32/src/tnl_dd/t_dd_rendertmp.h create mode 100644 reactos/lib/mesa32/src/tnl_dd/t_dd_triemit.h create mode 100644 reactos/lib/mesa32/src/tnl_dd/t_dd_tritmp.h create mode 100644 reactos/lib/mesa32/src/tnl_dd/t_dd_unfilled.h create mode 100644 reactos/lib/mesa32/src/tnl_dd/t_dd_vb.c create mode 100644 reactos/lib/mesa32/src/tnl_dd/t_dd_vbtmp.h create mode 100644 reactos/lib/mesa32/src/tnl_dd/t_dd_vertex.h create mode 100644 reactos/lib/mesa32/src/x86/3dnow.c create mode 100644 reactos/lib/mesa32/src/x86/3dnow.h create mode 100644 reactos/lib/mesa32/src/x86/3dnow_normal.S create mode 100644 reactos/lib/mesa32/src/x86/3dnow_xform1.S create mode 100644 reactos/lib/mesa32/src/x86/3dnow_xform2.S create mode 100644 reactos/lib/mesa32/src/x86/3dnow_xform3.S create mode 100644 reactos/lib/mesa32/src/x86/3dnow_xform4.S create mode 100644 reactos/lib/mesa32/src/x86/assyntax.h create mode 100644 reactos/lib/mesa32/src/x86/clip_args.h create mode 100644 reactos/lib/mesa32/src/x86/common_x86.c create mode 100644 reactos/lib/mesa32/src/x86/common_x86_asm.S create mode 100644 reactos/lib/mesa32/src/x86/common_x86_asm.h create mode 100644 reactos/lib/mesa32/src/x86/common_x86_features.h create mode 100644 reactos/lib/mesa32/src/x86/common_x86_macros.h create mode 100644 reactos/lib/mesa32/src/x86/gen_matypes.c create mode 100644 reactos/lib/mesa32/src/x86/glapi_x86.S create mode 100644 reactos/lib/mesa32/src/x86/matypes.h create mode 100644 reactos/lib/mesa32/src/x86/mmx.h create mode 100644 reactos/lib/mesa32/src/x86/mmx_blend.S create mode 100644 reactos/lib/mesa32/src/x86/mmx_blendtmp.h create mode 100644 reactos/lib/mesa32/src/x86/norm_args.h create mode 100644 reactos/lib/mesa32/src/x86/sse.c create mode 100644 reactos/lib/mesa32/src/x86/sse.h create mode 100644 reactos/lib/mesa32/src/x86/sse_normal.S create mode 100644 reactos/lib/mesa32/src/x86/sse_xform1.S create mode 100644 reactos/lib/mesa32/src/x86/sse_xform2.S create mode 100644 reactos/lib/mesa32/src/x86/sse_xform3.S create mode 100644 reactos/lib/mesa32/src/x86/sse_xform4.S create mode 100644 reactos/lib/mesa32/src/x86/x86.c create mode 100644 reactos/lib/mesa32/src/x86/x86.h create mode 100644 reactos/lib/mesa32/src/x86/x86_cliptest.S create mode 100644 reactos/lib/mesa32/src/x86/x86_xform2.S create mode 100644 reactos/lib/mesa32/src/x86/x86_xform3.S create mode 100644 reactos/lib/mesa32/src/x86/x86_xform4.S create mode 100644 reactos/lib/mesa32/src/x86/xform_args.h diff --git a/reactos/lib/mesa32/src/array_cache/ac_context.c b/reactos/lib/mesa32/src/array_cache/ac_context.c new file mode 100644 index 00000000000..ebf3a3dc47b --- /dev/null +++ b/reactos/lib/mesa32/src/array_cache/ac_context.c @@ -0,0 +1,375 @@ +/* + * Mesa 3-D graphics library + * Version: 5.1 + * + * 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 + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Keith Whitwell + */ + +#include "glheader.h" +#include "macros.h" +#include "imports.h" +#include "mtypes.h" + +#include "array_cache/ac_context.h" + + +/* + * Initialize the array fallbacks. That is, by default the fallback arrays + * point into the current vertex attribute values in ctx->Current.Attrib[] + */ +static void _ac_fallbacks_init( GLcontext *ctx ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + struct gl_client_array *cl; + GLuint i; + + cl = &ac->Fallback.Normal; + cl->Size = 3; + cl->Type = GL_FLOAT; + cl->Stride = 0; + cl->StrideB = 0; + cl->Ptr = (GLubyte *) ctx->Current.Attrib[VERT_ATTRIB_NORMAL]; + cl->Enabled = 1; + cl->Flags = CA_CLIENT_DATA; /* hack */ +#if FEATURE_ARB_vertex_buffer_object + cl->BufferObj = ctx->Array.NullBufferObj; +#endif + + cl = &ac->Fallback.Color; + cl->Size = 4; + cl->Type = GL_FLOAT; + cl->Stride = 0; + cl->StrideB = 0; + cl->Ptr = (GLubyte *) ctx->Current.Attrib[VERT_ATTRIB_COLOR0]; + cl->Enabled = 1; + cl->Flags = CA_CLIENT_DATA; /* hack */ +#if FEATURE_ARB_vertex_buffer_object + cl->BufferObj = ctx->Array.NullBufferObj; +#endif + + cl = &ac->Fallback.SecondaryColor; + cl->Size = 3; + cl->Type = GL_FLOAT; + cl->Stride = 0; + cl->StrideB = 0; + cl->Ptr = (GLubyte *) ctx->Current.Attrib[VERT_ATTRIB_COLOR1]; + cl->Enabled = 1; + cl->Flags = CA_CLIENT_DATA; /* hack */ +#if FEATURE_ARB_vertex_buffer_object + cl->BufferObj = ctx->Array.NullBufferObj; +#endif + + cl = &ac->Fallback.FogCoord; + cl->Size = 1; + cl->Type = GL_FLOAT; + cl->Stride = 0; + cl->StrideB = 0; + cl->Ptr = (GLubyte *) &ctx->Current.Attrib[VERT_ATTRIB_FOG]; + cl->Enabled = 1; + cl->Flags = CA_CLIENT_DATA; /* hack */ +#if FEATURE_ARB_vertex_buffer_object + cl->BufferObj = ctx->Array.NullBufferObj; +#endif + + cl = &ac->Fallback.Index; + cl->Size = 1; + cl->Type = GL_FLOAT; + cl->Stride = 0; + cl->StrideB = 0; + cl->Ptr = (GLubyte *) &ctx->Current.Index; + cl->Enabled = 1; + cl->Flags = CA_CLIENT_DATA; /* hack */ +#if FEATURE_ARB_vertex_buffer_object + cl->BufferObj = ctx->Array.NullBufferObj; +#endif + + for (i = 0 ; i < MAX_TEXTURE_COORD_UNITS ; i++) { + cl = &ac->Fallback.TexCoord[i]; + cl->Size = 4; + cl->Type = GL_FLOAT; + cl->Stride = 0; + cl->StrideB = 0; + cl->Ptr = (GLubyte *) ctx->Current.Attrib[VERT_ATTRIB_TEX0 + i]; + cl->Enabled = 1; + cl->Flags = CA_CLIENT_DATA; /* hack */ +#if FEATURE_ARB_vertex_buffer_object + cl->BufferObj = ctx->Array.NullBufferObj; +#endif + } + + cl = &ac->Fallback.EdgeFlag; + cl->Size = 1; + cl->Type = GL_UNSIGNED_BYTE; + cl->Stride = 0; + cl->StrideB = 0; + cl->Ptr = (GLubyte *) &ctx->Current.EdgeFlag; + cl->Enabled = 1; + cl->Flags = CA_CLIENT_DATA; /* hack */ +#if FEATURE_ARB_vertex_buffer_object + cl->BufferObj = ctx->Array.NullBufferObj; +#endif + + for (i = 0; i < VERT_ATTRIB_MAX; i++) { + cl = &ac->Fallback.Attrib[i]; + cl->Size = 4; + cl->Type = GL_FLOAT; + cl->Stride = 0; + cl->StrideB = 0; + cl->Ptr = (GLubyte *) ctx->Current.Attrib[i]; + cl->Enabled = 1; + cl->Flags = CA_CLIENT_DATA; /* hack */ +#if FEATURE_ARB_vertex_buffer_object + cl->BufferObj = ctx->Array.NullBufferObj; +#endif + } +} + + +/* + * Initialize the array cache pointers, types, strides, etc. + */ +static void _ac_cache_init( GLcontext *ctx ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + struct gl_client_array *cl; + GLuint size = ctx->Const.MaxArrayLockSize + MAX_CLIPPED_VERTICES; + GLuint i; + + cl = &ac->Cache.Vertex; + cl->Size = 4; + cl->Type = GL_FLOAT; + cl->Stride = 0; + cl->StrideB = 4 * sizeof(GLfloat); + cl->Ptr = (GLubyte *) MALLOC( cl->StrideB * size ); + cl->Enabled = 1; + cl->Flags = 0; +#if FEATURE_ARB_vertex_buffer_object + cl->BufferObj = ctx->Array.NullBufferObj; +#endif + + cl = &ac->Cache.Normal; + cl->Size = 3; + cl->Type = GL_FLOAT; + cl->Stride = 0; + cl->StrideB = 3 * sizeof(GLfloat); + cl->Ptr = (GLubyte *) MALLOC( cl->StrideB * size ); + cl->Enabled = 1; + cl->Flags = 0; +#if FEATURE_ARB_vertex_buffer_object + cl->BufferObj = ctx->Array.NullBufferObj; +#endif + + cl = &ac->Cache.Color; + cl->Size = 4; + cl->Type = GL_FLOAT; + cl->Stride = 0; + cl->StrideB = 4 * sizeof(GLfloat); + cl->Ptr = (GLubyte *) MALLOC( cl->StrideB * size ); + cl->Enabled = 1; + cl->Flags = 0; +#if FEATURE_ARB_vertex_buffer_object + cl->BufferObj = ctx->Array.NullBufferObj; +#endif + + cl = &ac->Cache.SecondaryColor; + cl->Size = 3; + cl->Type = GL_FLOAT; + cl->Stride = 0; + cl->StrideB = 4 * sizeof(GLfloat); + cl->Ptr = (GLubyte *) MALLOC( cl->StrideB * size ); + cl->Enabled = 1; + cl->Flags = 0; +#if FEATURE_ARB_vertex_buffer_object + cl->BufferObj = ctx->Array.NullBufferObj; +#endif + + cl = &ac->Cache.FogCoord; + cl->Size = 1; + cl->Type = GL_FLOAT; + cl->Stride = 0; + cl->StrideB = sizeof(GLfloat); + cl->Ptr = (GLubyte *) MALLOC( cl->StrideB * size ); + cl->Enabled = 1; + cl->Flags = 0; +#if FEATURE_ARB_vertex_buffer_object + cl->BufferObj = ctx->Array.NullBufferObj; +#endif + + cl = &ac->Cache.Index; + cl->Size = 1; + cl->Type = GL_FLOAT; + cl->Stride = 0; + cl->StrideB = sizeof(GLfloat); + cl->Ptr = (GLubyte *) MALLOC( cl->StrideB * size ); + cl->Enabled = 1; + cl->Flags = 0; +#if FEATURE_ARB_vertex_buffer_object + cl->BufferObj = ctx->Array.NullBufferObj; +#endif + + for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) { + cl = &ac->Cache.TexCoord[i]; + cl->Size = 4; + cl->Type = GL_FLOAT; + cl->Stride = 0; + cl->StrideB = 4 * sizeof(GLfloat); + cl->Ptr = (GLubyte *) MALLOC( cl->StrideB * size ); + cl->Enabled = 1; + cl->Flags = 0; +#if FEATURE_ARB_vertex_buffer_object + cl->BufferObj = ctx->Array.NullBufferObj; +#endif + } + + cl = &ac->Cache.EdgeFlag; + cl->Size = 1; + cl->Type = GL_UNSIGNED_BYTE; + cl->Stride = 0; + cl->StrideB = sizeof(GLubyte); + cl->Ptr = (GLubyte *) MALLOC( cl->StrideB * size ); + cl->Enabled = 1; + cl->Flags = 0; +#if FEATURE_ARB_vertex_buffer_object + cl->BufferObj = ctx->Array.NullBufferObj; +#endif + + for (i = 0 ; i < VERT_ATTRIB_MAX; i++) { + cl = &ac->Cache.Attrib[i]; + cl->Size = 4; + cl->Type = GL_FLOAT; + cl->Stride = 0; + cl->StrideB = 4 * sizeof(GLfloat); + cl->Ptr = (GLubyte *) MALLOC( cl->StrideB * size ); + cl->Enabled = 1; + cl->Flags = 0; +#if FEATURE_ARB_vertex_buffer_object + cl->BufferObj = ctx->Array.NullBufferObj; +#endif + } +} + + +/* This storage used to hold translated client data if type or stride + * need to be fixed. + */ +static void _ac_elts_init( GLcontext *ctx ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + GLuint size = 1000; + + ac->Elts = (GLuint *)MALLOC( sizeof(GLuint) * size ); + ac->elt_size = size; +} + +static void _ac_raw_init( GLcontext *ctx ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + GLuint i; + + ac->Raw.Color = ac->Fallback.Color; + ac->Raw.EdgeFlag = ac->Fallback.EdgeFlag; + ac->Raw.FogCoord = ac->Fallback.FogCoord; + ac->Raw.Index = ac->Fallback.Index; + ac->Raw.Normal = ac->Fallback.Normal; + ac->Raw.SecondaryColor = ac->Fallback.SecondaryColor; + ac->Raw.Vertex = ctx->Array.Vertex; + + ac->IsCached.Color = GL_FALSE; + ac->IsCached.EdgeFlag = GL_FALSE; + ac->IsCached.FogCoord = GL_FALSE; + ac->IsCached.Index = GL_FALSE; + ac->IsCached.Normal = GL_FALSE; + ac->IsCached.SecondaryColor = GL_FALSE; + ac->IsCached.Vertex = GL_FALSE; + + for (i = 0 ; i < MAX_TEXTURE_COORD_UNITS ; i++) { + ac->Raw.TexCoord[i] = ac->Fallback.TexCoord[i]; + ac->IsCached.TexCoord[i] = GL_FALSE; + } + + for (i = 0 ; i < VERT_ATTRIB_MAX ; i++) { + ac->Raw.Attrib[i] = ac->Fallback.Attrib[i]; + ac->IsCached.Attrib[i] = GL_FALSE; + } +} + +GLboolean _ac_CreateContext( GLcontext *ctx ) +{ + ctx->acache_context = CALLOC(sizeof(ACcontext)); + if (ctx->acache_context) { + _ac_cache_init( ctx ); + _ac_fallbacks_init( ctx ); + _ac_raw_init( ctx ); + _ac_elts_init( ctx ); + return GL_TRUE; + } + return GL_FALSE; +} + +void _ac_DestroyContext( GLcontext *ctx ) +{ + struct gl_buffer_object *nullObj = ctx->Array.NullBufferObj; + ACcontext *ac = AC_CONTEXT(ctx); + GLint i; + + /* only free vertex data if it's really a pointer to vertex data and + * not an offset into a buffer object. + */ + if (ac->Cache.Vertex.Ptr && ac->Cache.Vertex.BufferObj == nullObj) + FREE( (void *) ac->Cache.Vertex.Ptr ); + if (ac->Cache.Normal.Ptr && ac->Cache.Normal.BufferObj == nullObj) + FREE( (void *) ac->Cache.Normal.Ptr ); + if (ac->Cache.Color.Ptr && ac->Cache.Color.BufferObj == nullObj) + FREE( (void *) ac->Cache.Color.Ptr ); + if (ac->Cache.SecondaryColor.Ptr && ac->Cache.SecondaryColor.BufferObj == nullObj) + FREE( (void *) ac->Cache.SecondaryColor.Ptr ); + if (ac->Cache.EdgeFlag.Ptr && ac->Cache.EdgeFlag.BufferObj == nullObj) + FREE( (void *) ac->Cache.EdgeFlag.Ptr ); + if (ac->Cache.Index.Ptr && ac->Cache.Index.BufferObj == nullObj) + FREE( (void *) ac->Cache.Index.Ptr ); + if (ac->Cache.FogCoord.Ptr && ac->Cache.FogCoord.BufferObj == nullObj) + FREE( (void *) ac->Cache.FogCoord.Ptr ); + + for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) { + if (ac->Cache.TexCoord[i].Ptr && ac->Cache.TexCoord[i].BufferObj == nullObj) + FREE( (void *) ac->Cache.TexCoord[i].Ptr ); + } + + for (i = 0; i < VERT_ATTRIB_MAX; i++) { + if (ac->Cache.Attrib[i].Ptr && ac->Cache.Attrib[i].BufferObj == nullObj) + FREE( (void *) ac->Cache.Attrib[i].Ptr ); + } + + if (ac->Elts) + FREE( ac->Elts ); + + /* Free the context structure itself */ + FREE(ac); + ctx->acache_context = NULL; +} + +void _ac_InvalidateState( GLcontext *ctx, GLuint new_state ) +{ + AC_CONTEXT(ctx)->NewState |= new_state; + AC_CONTEXT(ctx)->NewArrayState |= ctx->Array.NewState; +} diff --git a/reactos/lib/mesa32/src/array_cache/ac_context.h b/reactos/lib/mesa32/src/array_cache/ac_context.h new file mode 100644 index 00000000000..36aded3152c --- /dev/null +++ b/reactos/lib/mesa32/src/array_cache/ac_context.h @@ -0,0 +1,99 @@ + +/* + * Mesa 3-D graphics library + * Version: 5.1 + * + * 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 + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Keith Whitwell + */ + +#ifndef _AC_CONTEXT_H +#define _AC_CONTEXT_H + +#include "glheader.h" +#include "mtypes.h" + +#include "array_cache/acache.h" + +/* These are used to make the ctx->Current values look like + * arrays (with zero StrideB). + */ +struct ac_arrays { + struct gl_client_array Vertex; + struct gl_client_array Normal; + struct gl_client_array Color; + struct gl_client_array SecondaryColor; + struct gl_client_array FogCoord; + struct gl_client_array Index; + struct gl_client_array TexCoord[MAX_TEXTURE_COORD_UNITS]; + struct gl_client_array EdgeFlag; + struct gl_client_array Attrib[VERT_ATTRIB_MAX]; /* GL_NV_vertex_program */ +}; + +struct ac_array_pointers { + struct gl_client_array *Vertex; + struct gl_client_array *Normal; + struct gl_client_array *Color; + struct gl_client_array *SecondaryColor; + struct gl_client_array *FogCoord; + struct gl_client_array *Index; + struct gl_client_array *TexCoord[MAX_TEXTURE_COORD_UNITS]; + struct gl_client_array *EdgeFlag; + struct gl_client_array *Attrib[VERT_ATTRIB_MAX]; /* GL_NV_vertex_program */ +}; + +struct ac_array_flags { + GLboolean Vertex; + GLboolean Normal; + GLboolean Color; + GLboolean SecondaryColor; + GLboolean FogCoord; + GLboolean Index; + GLboolean TexCoord[MAX_TEXTURE_COORD_UNITS]; + GLboolean EdgeFlag; + GLboolean Attrib[VERT_ATTRIB_MAX]; /* GL_NV_vertex_program */ +}; + + +typedef struct { + GLuint NewState; /* not needed? */ + GLuint NewArrayState; + + /* Facility for importing and caching array data: + */ + struct ac_arrays Fallback; + struct ac_arrays Cache; + struct ac_arrays Raw; + struct ac_array_flags IsCached; + GLuint start; + GLuint count; + + /* Facility for importing element lists: + */ + GLuint *Elts; + GLuint elt_size; + +} ACcontext; + +#define AC_CONTEXT(ctx) ((ACcontext *)ctx->acache_context) + +#endif diff --git a/reactos/lib/mesa32/src/array_cache/ac_import.c b/reactos/lib/mesa32/src/array_cache/ac_import.c new file mode 100644 index 00000000000..7ec1d00ee58 --- /dev/null +++ b/reactos/lib/mesa32/src/array_cache/ac_import.c @@ -0,0 +1,881 @@ +/* + * Mesa 3-D graphics library + * Version: 5.1 + * + * 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 + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Keith Whitwell + */ + +#include "glheader.h" +#include "macros.h" +#include "imports.h" +#include "mtypes.h" + +#include "math/m_translate.h" +#include "array_cache/ac_context.h" +#include "math/m_translate.h" + +#define STRIDE_ARRAY( array, offset ) \ +do { \ + GLubyte *tmp = ADD_POINTERS( (array).BufferObj->Data, (array).Ptr ) \ + + (offset) * (array).StrideB; \ + (array).Ptr = tmp; \ +} while (0) + + +/* Set the array pointer back to its source when the cached data is + * invalidated: + */ +static void reset_texcoord( GLcontext *ctx, GLuint unit ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + if (ctx->Array.TexCoord[unit].Enabled) { + ac->Raw.TexCoord[unit] = ctx->Array.TexCoord[unit]; + STRIDE_ARRAY(ac->Raw.TexCoord[unit], ac->start); + } + else { + ac->Raw.TexCoord[unit] = ac->Fallback.TexCoord[unit]; + + if (ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][3] != 1.0) + ac->Raw.TexCoord[unit].Size = 4; + else if (ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][2] != 0.0) + ac->Raw.TexCoord[unit].Size = 3; + else + ac->Raw.TexCoord[unit].Size = 2; + } + + ac->IsCached.TexCoord[unit] = GL_FALSE; + ac->NewArrayState &= ~_NEW_ARRAY_TEXCOORD(unit); +} + +static void reset_vertex( GLcontext *ctx ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + ASSERT(ctx->Array.Vertex.Enabled + || (ctx->VertexProgram.Enabled && ctx->Array.VertexAttrib[0].Enabled)); + ac->Raw.Vertex = ctx->Array.Vertex; + STRIDE_ARRAY(ac->Raw.Vertex, ac->start); + ac->IsCached.Vertex = GL_FALSE; + ac->NewArrayState &= ~_NEW_ARRAY_VERTEX; +} + + +static void reset_normal( GLcontext *ctx ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + if (ctx->Array.Normal.Enabled) { + ac->Raw.Normal = ctx->Array.Normal; + STRIDE_ARRAY(ac->Raw.Normal, ac->start); + } + else { + ac->Raw.Normal = ac->Fallback.Normal; + } + + ac->IsCached.Normal = GL_FALSE; + ac->NewArrayState &= ~_NEW_ARRAY_NORMAL; +} + + +static void reset_color( GLcontext *ctx ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + + if (ctx->Array.Color.Enabled) { + ac->Raw.Color = ctx->Array.Color; + STRIDE_ARRAY(ac->Raw.Color, ac->start); + } + else + ac->Raw.Color = ac->Fallback.Color; + + ac->IsCached.Color = GL_FALSE; + ac->NewArrayState &= ~_NEW_ARRAY_COLOR0; +} + + +static void reset_secondarycolor( GLcontext *ctx ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + if (ctx->Array.SecondaryColor.Enabled & _NEW_ARRAY_COLOR1) { + ac->Raw.SecondaryColor = ctx->Array.SecondaryColor; + STRIDE_ARRAY(ac->Raw.SecondaryColor, ac->start); + } + else + ac->Raw.SecondaryColor = ac->Fallback.SecondaryColor; + + ac->IsCached.SecondaryColor = GL_FALSE; + ac->NewArrayState &= ~_NEW_ARRAY_COLOR1; +} + + +static void reset_index( GLcontext *ctx ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + if (ctx->Array.Index.Enabled & _NEW_ARRAY_INDEX) { + ac->Raw.Index = ctx->Array.Index; + STRIDE_ARRAY(ac->Raw.Index, ac->start); + } + else + ac->Raw.Index = ac->Fallback.Index; + + ac->IsCached.Index = GL_FALSE; + ac->NewArrayState &= ~_NEW_ARRAY_INDEX; +} + + +static void reset_fogcoord( GLcontext *ctx ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + if (ctx->Array.FogCoord.Enabled & _NEW_ARRAY_FOGCOORD) { + ac->Raw.FogCoord = ctx->Array.FogCoord; + STRIDE_ARRAY(ac->Raw.FogCoord, ac->start); + } + else + ac->Raw.FogCoord = ac->Fallback.FogCoord; + + ac->IsCached.FogCoord = GL_FALSE; + ac->NewArrayState &= ~_NEW_ARRAY_FOGCOORD; +} + + +static void reset_edgeflag( GLcontext *ctx ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + if (ctx->Array.EdgeFlag.Enabled & _NEW_ARRAY_EDGEFLAG) { + ac->Raw.EdgeFlag = ctx->Array.EdgeFlag; + STRIDE_ARRAY(ac->Raw.EdgeFlag, ac->start); + } + else + ac->Raw.EdgeFlag = ac->Fallback.EdgeFlag; + + ac->IsCached.EdgeFlag = GL_FALSE; + ac->NewArrayState &= ~_NEW_ARRAY_EDGEFLAG; +} + + +static void reset_attrib( GLcontext *ctx, GLuint index ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + if (ctx->Array.VertexAttrib[index].Enabled) { + ac->Raw.Attrib[index] = ctx->Array.VertexAttrib[index]; + STRIDE_ARRAY(ac->Raw.Attrib[index], ac->start); + } + else + ac->Raw.Attrib[index] = ac->Fallback.Attrib[index]; + + ac->IsCached.Attrib[index] = GL_FALSE; + ac->NewArrayState &= ~_NEW_ARRAY_ATTRIB(index); +} + + +/* + * Generic import function for color data + */ +static void import( GLcontext *ctx, + GLenum type, + struct gl_client_array *to, + struct gl_client_array *from ) +{ + GLubyte *dest; + const GLubyte *src; + ACcontext *ac = AC_CONTEXT(ctx); + + if (type == 0) + type = from->Type; + + /* The dest and source data addresses are the sum of the buffer + * object's start plus the vertex array pointer/offset. + */ + dest = ADD_POINTERS(to->BufferObj->Data, to->Ptr); + src = ADD_POINTERS(from->BufferObj->Data, from->Ptr); + + switch (type) { + case GL_FLOAT: + _math_trans_4fc( (GLfloat (*)[4]) dest, + src, + from->StrideB, + from->Type, + from->Size, + 0, + ac->count - ac->start); + + to->StrideB = 4 * sizeof(GLfloat); + to->Type = GL_FLOAT; + break; + + case GL_UNSIGNED_BYTE: + _math_trans_4ub( (GLubyte (*)[4]) dest, + src, + from->StrideB, + from->Type, + from->Size, + 0, + ac->count - ac->start); + + to->StrideB = 4 * sizeof(GLubyte); + to->Type = GL_UNSIGNED_BYTE; + break; + + case GL_UNSIGNED_SHORT: + _math_trans_4us( (GLushort (*)[4]) dest, + src, + from->StrideB, + from->Type, + from->Size, + 0, + ac->count - ac->start); + + to->StrideB = 4 * sizeof(GLushort); + to->Type = GL_UNSIGNED_SHORT; + break; + + default: + ASSERT(0); + break; + } +} + + + +/* + * Functions to import array ranges with specified types and strides. + * For example, if the vertex data is GLshort[2] and we want GLfloat[3] + * we'll use an import function to do the data conversion. + */ + +static void import_texcoord( GLcontext *ctx, GLuint unit, + GLenum type, GLuint stride ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + struct gl_client_array *from = &ac->Raw.TexCoord[unit]; + struct gl_client_array *to = &ac->Cache.TexCoord[unit]; + + ASSERT(unit < ctx->Const.MaxTextureCoordUnits); + + /* Limited choices at this stage: + */ + ASSERT(type == GL_FLOAT); + ASSERT(stride == 4*sizeof(GLfloat) || stride == 0); + ASSERT(ac->count - ac->start < ctx->Const.MaxArrayLockSize); + + _math_trans_4f( (GLfloat (*)[4]) to->Ptr, + from->Ptr, + from->StrideB, + from->Type, + from->Size, + 0, + ac->count - ac->start); + + to->Size = from->Size; + to->StrideB = 4 * sizeof(GLfloat); + to->Type = GL_FLOAT; + ac->IsCached.TexCoord[unit] = GL_TRUE; +} + +static void import_vertex( GLcontext *ctx, + GLenum type, GLuint stride ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + struct gl_client_array *from = &ac->Raw.Vertex; + struct gl_client_array *to = &ac->Cache.Vertex; + + /* Limited choices at this stage: + */ + ASSERT(type == GL_FLOAT); + ASSERT(stride == 4*sizeof(GLfloat) || stride == 0); + + _math_trans_4f( (GLfloat (*)[4]) to->Ptr, + from->Ptr, + from->StrideB, + from->Type, + from->Size, + 0, + ac->count - ac->start); + + to->Size = from->Size; + to->StrideB = 4 * sizeof(GLfloat); + to->Type = GL_FLOAT; + ac->IsCached.Vertex = GL_TRUE; +} + +static void import_normal( GLcontext *ctx, + GLenum type, GLuint stride ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + struct gl_client_array *from = &ac->Raw.Normal; + struct gl_client_array *to = &ac->Cache.Normal; + + /* Limited choices at this stage: + */ + ASSERT(type == GL_FLOAT); + ASSERT(stride == 3*sizeof(GLfloat) || stride == 0); + + _math_trans_3f( (GLfloat (*)[3]) to->Ptr, + from->Ptr, + from->StrideB, + from->Type, + 0, + ac->count - ac->start); + + to->StrideB = 3 * sizeof(GLfloat); + to->Type = GL_FLOAT; + ac->IsCached.Normal = GL_TRUE; +} + +static void import_color( GLcontext *ctx, + GLenum type, GLuint stride ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + struct gl_client_array *from = &ac->Raw.Color; + struct gl_client_array *to = &ac->Cache.Color; + + import( ctx, type, to, from ); + + ac->IsCached.Color = GL_TRUE; +} + +static void import_index( GLcontext *ctx, + GLenum type, GLuint stride ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + struct gl_client_array *from = &ac->Raw.Index; + struct gl_client_array *to = &ac->Cache.Index; + + /* Limited choices at this stage: + */ + ASSERT(type == GL_UNSIGNED_INT); + ASSERT(stride == sizeof(GLuint) || stride == 0); + + _math_trans_1ui( (GLuint *) to->Ptr, + from->Ptr, + from->StrideB, + from->Type, + 0, + ac->count - ac->start); + + to->StrideB = sizeof(GLuint); + to->Type = GL_UNSIGNED_INT; + ac->IsCached.Index = GL_TRUE; +} + +static void import_secondarycolor( GLcontext *ctx, + GLenum type, GLuint stride ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + struct gl_client_array *from = &ac->Raw.SecondaryColor; + struct gl_client_array *to = &ac->Cache.SecondaryColor; + + import( ctx, type, to, from ); + + ac->IsCached.SecondaryColor = GL_TRUE; +} + +static void import_fogcoord( GLcontext *ctx, + GLenum type, GLuint stride ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + struct gl_client_array *from = &ac->Raw.FogCoord; + struct gl_client_array *to = &ac->Cache.FogCoord; + + /* Limited choices at this stage: + */ + ASSERT(type == GL_FLOAT); + ASSERT(stride == sizeof(GLfloat) || stride == 0); + + _math_trans_1f( (GLfloat *) to->Ptr, + from->Ptr, + from->StrideB, + from->Type, + 0, + ac->count - ac->start); + + to->StrideB = sizeof(GLfloat); + to->Type = GL_FLOAT; + ac->IsCached.FogCoord = GL_TRUE; +} + +static void import_edgeflag( GLcontext *ctx, + GLenum type, GLuint stride ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + struct gl_client_array *from = &ac->Raw.EdgeFlag; + struct gl_client_array *to = &ac->Cache.EdgeFlag; + + /* Limited choices at this stage: + */ + ASSERT(type == GL_UNSIGNED_BYTE); + ASSERT(stride == sizeof(GLubyte) || stride == 0); + + _math_trans_1ub( (GLubyte *) to->Ptr, + from->Ptr, + from->StrideB, + from->Type, + 0, + ac->count - ac->start); + + to->StrideB = sizeof(GLubyte); + to->Type = GL_UNSIGNED_BYTE; + ac->IsCached.EdgeFlag = GL_TRUE; +} + +static void import_attrib( GLcontext *ctx, GLuint index, + GLenum type, GLuint stride ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + struct gl_client_array *from = &ac->Raw.Attrib[index]; + struct gl_client_array *to = &ac->Cache.Attrib[index]; + + ASSERT(index < VERT_ATTRIB_MAX); + + /* Limited choices at this stage: + */ + ASSERT(type == GL_FLOAT); + ASSERT(stride == 4*sizeof(GLfloat) || stride == 0); + ASSERT(ac->count - ac->start < ctx->Const.MaxArrayLockSize); + + _math_trans_4f( (GLfloat (*)[4]) to->Ptr, + from->Ptr, + from->StrideB, + from->Type, + from->Size, + 0, + ac->count - ac->start); + + to->Size = from->Size; + to->StrideB = 4 * sizeof(GLfloat); + to->Type = GL_FLOAT; + ac->IsCached.Attrib[index] = GL_TRUE; +} + + + +/* + * Externals to request arrays with specific properties: + */ + + +struct gl_client_array *_ac_import_texcoord( GLcontext *ctx, + GLuint unit, + GLenum type, + GLuint reqstride, + GLuint reqsize, + GLboolean reqwriteable, + GLboolean *writeable ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + ASSERT(unit < ctx->Const.MaxTextureCoordUnits); + + /* Can we keep the existing version? + */ + if (ac->NewArrayState & _NEW_ARRAY_TEXCOORD(unit)) + reset_texcoord( ctx, unit ); + + /* Is the request impossible? + */ + if (reqsize != 0 && ac->Raw.TexCoord[unit].Size > (GLint) reqsize) + return 0; + + /* Do we need to pull in a copy of the client data: + */ + if (ac->Raw.TexCoord[unit].Type != type || + (reqstride != 0 && ac->Raw.TexCoord[unit].StrideB != (GLint)reqstride) || + reqwriteable) + { + if (!ac->IsCached.TexCoord[unit]) + import_texcoord(ctx, unit, type, reqstride ); + *writeable = GL_TRUE; + return &ac->Cache.TexCoord[unit]; + } + else { + *writeable = GL_FALSE; + return &ac->Raw.TexCoord[unit]; + } +} + +struct gl_client_array *_ac_import_vertex( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLuint reqsize, + GLboolean reqwriteable, + GLboolean *writeable ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + /* Can we keep the existing version? + */ + if (ac->NewArrayState & _NEW_ARRAY_VERTEX) + reset_vertex( ctx ); + + /* Is the request impossible? + */ + if (reqsize != 0 && ac->Raw.Vertex.Size > (GLint) reqsize) + return 0; + + /* Do we need to pull in a copy of the client data: + */ + if (ac->Raw.Vertex.Type != type || + (reqstride != 0 && ac->Raw.Vertex.StrideB != (GLint) reqstride) || + reqwriteable) + { + if (!ac->IsCached.Vertex) + import_vertex(ctx, type, reqstride ); + *writeable = GL_TRUE; + return &ac->Cache.Vertex; + } + else { + *writeable = GL_FALSE; + return &ac->Raw.Vertex; + } +} + +struct gl_client_array *_ac_import_normal( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLboolean reqwriteable, + GLboolean *writeable ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + /* Can we keep the existing version? + */ + if (ac->NewArrayState & _NEW_ARRAY_NORMAL) + reset_normal( ctx ); + + /* Do we need to pull in a copy of the client data: + */ + if (ac->Raw.Normal.Type != type || + (reqstride != 0 && ac->Raw.Normal.StrideB != (GLint) reqstride) || + reqwriteable) + { + if (!ac->IsCached.Normal) + import_normal(ctx, type, reqstride ); + *writeable = GL_TRUE; + return &ac->Cache.Normal; + } + else { + *writeable = GL_FALSE; + return &ac->Raw.Normal; + } +} + +struct gl_client_array *_ac_import_color( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLuint reqsize, + GLboolean reqwriteable, + GLboolean *writeable ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + /* Can we keep the existing version? + */ + if (ac->NewArrayState & _NEW_ARRAY_COLOR0) + reset_color( ctx ); + + /* Is the request impossible? + */ + if (reqsize != 0 && ac->Raw.Color.Size > (GLint) reqsize) { + return 0; + } + + /* Do we need to pull in a copy of the client data: + */ + if ((type != 0 && ac->Raw.Color.Type != type) || + (reqstride != 0 && ac->Raw.Color.StrideB != (GLint) reqstride) || + reqwriteable) + { + if (!ac->IsCached.Color) + import_color(ctx, type, reqstride ); + *writeable = GL_TRUE; + return &ac->Cache.Color; + } + else { + *writeable = GL_FALSE; + return &ac->Raw.Color; + } +} + +struct gl_client_array *_ac_import_index( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLboolean reqwriteable, + GLboolean *writeable ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + /* Can we keep the existing version? + */ + if (ac->NewArrayState & _NEW_ARRAY_INDEX) + reset_index( ctx ); + + + /* Do we need to pull in a copy of the client data: + */ + if (ac->Raw.Index.Type != type || + (reqstride != 0 && ac->Raw.Index.StrideB != (GLint) reqstride) || + reqwriteable) + { + if (!ac->IsCached.Index) + import_index(ctx, type, reqstride ); + *writeable = GL_TRUE; + return &ac->Cache.Index; + } + else { + *writeable = GL_FALSE; + return &ac->Raw.Index; + } +} + +struct gl_client_array *_ac_import_secondarycolor( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLuint reqsize, + GLboolean reqwriteable, + GLboolean *writeable ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + /* Can we keep the existing version? + */ + if (ac->NewArrayState & _NEW_ARRAY_COLOR1) + reset_secondarycolor( ctx ); + + /* Is the request impossible? + */ + if (reqsize != 0 && ac->Raw.SecondaryColor.Size > (GLint) reqsize) + return 0; + + /* Do we need to pull in a copy of the client data: + */ + if ((type != 0 && ac->Raw.SecondaryColor.Type != type) || + (reqstride != 0 && ac->Raw.SecondaryColor.StrideB != (GLint)reqstride) || + reqwriteable) + { + if (!ac->IsCached.SecondaryColor) + import_secondarycolor(ctx, type, reqstride ); + *writeable = GL_TRUE; + return &ac->Cache.SecondaryColor; + } + else { + *writeable = GL_FALSE; + return &ac->Raw.SecondaryColor; + } +} + +struct gl_client_array *_ac_import_fogcoord( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLboolean reqwriteable, + GLboolean *writeable ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + /* Can we keep the existing version? + */ + if (ac->NewArrayState & _NEW_ARRAY_FOGCOORD) + reset_fogcoord( ctx ); + + /* Do we need to pull in a copy of the client data: + */ + if (ac->Raw.FogCoord.Type != type || + (reqstride != 0 && ac->Raw.FogCoord.StrideB != (GLint) reqstride) || + reqwriteable) + { + if (!ac->IsCached.FogCoord) + import_fogcoord(ctx, type, reqstride ); + *writeable = GL_TRUE; + return &ac->Cache.FogCoord; + } + else { + *writeable = GL_FALSE; + return &ac->Raw.FogCoord; + } +} + +struct gl_client_array *_ac_import_edgeflag( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLboolean reqwriteable, + GLboolean *writeable ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + /* Can we keep the existing version? + */ + if (ac->NewArrayState & _NEW_ARRAY_EDGEFLAG) + reset_edgeflag( ctx ); + + /* Do we need to pull in a copy of the client data: + */ + if (ac->Raw.EdgeFlag.Type != type || + (reqstride != 0 && ac->Raw.EdgeFlag.StrideB != (GLint) reqstride) || + reqwriteable) + { + if (!ac->IsCached.EdgeFlag) + import_edgeflag(ctx, type, reqstride ); + *writeable = GL_TRUE; + return &ac->Cache.EdgeFlag; + } + else { + *writeable = GL_FALSE; + return &ac->Raw.EdgeFlag; + } +} + +/* GL_NV_vertex_program */ +struct gl_client_array *_ac_import_attrib( GLcontext *ctx, + GLuint index, + GLenum type, + GLuint reqstride, + GLuint reqsize, + GLboolean reqwriteable, + GLboolean *writeable ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + ASSERT(index < VERT_ATTRIB_MAX); + + /* Can we keep the existing version? + */ + if (ac->NewArrayState & _NEW_ARRAY_ATTRIB(index)) + reset_attrib( ctx, index ); + + /* Is the request impossible? + */ + if (reqsize != 0 && ac->Raw.Attrib[index].Size > (GLint) reqsize) + return NULL; + + /* Do we need to pull in a copy of the client data: + */ + if (ac->Raw.Attrib[index].Type != type || + (reqstride != 0 && ac->Raw.Attrib[index].StrideB != (GLint)reqstride) || + reqwriteable) + { + if (!ac->IsCached.Attrib[index]) + import_attrib(ctx, index, type, reqstride ); + *writeable = GL_TRUE; + return &ac->Cache.Attrib[index]; + } + else { + *writeable = GL_FALSE; + return &ac->Raw.Attrib[index]; + } +} + + +/* Clients must call this function to validate state and set bounds + * before importing any data: + */ +void _ac_import_range( GLcontext *ctx, GLuint start, GLuint count ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + if (!ctx->Array.LockCount) { + /* Not locked, discard cached data. Changes to lock + * status are caught via. _ac_invalidate_state(). + */ + ac->NewArrayState = _NEW_ARRAY_ALL; + ac->start = start; + ac->count = count; + } + else { + /* Locked, discard data for any disabled arrays. Require that + * the whole locked range always be dealt with, otherwise hard to + * maintain cached data in the face of clipping. + */ + ac->NewArrayState |= ~ctx->Array._Enabled; + ac->start = ctx->Array.LockFirst; + ac->count = ctx->Array.LockCount; + ASSERT(ac->start == start); /* hmm? */ + ASSERT(ac->count == count); + } +} + + + +/* Additional convienence function for importing the element list + * for glDrawElements() and glDrawRangeElements(). + */ +CONST void * +_ac_import_elements( GLcontext *ctx, + GLenum new_type, + GLuint count, + GLenum old_type, + CONST void *indices ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + if (old_type == new_type) + return indices; + + if (ac->elt_size < count * sizeof(GLuint)) { + if (ac->Elts) FREE(ac->Elts); + while (ac->elt_size < count * sizeof(GLuint)) + ac->elt_size *= 2; + ac->Elts = (GLuint *) MALLOC(ac->elt_size); + } + + switch (new_type) { + case GL_UNSIGNED_BYTE: + ASSERT(0); + return 0; + case GL_UNSIGNED_SHORT: + ASSERT(0); + return 0; + case GL_UNSIGNED_INT: { + GLuint *out = (GLuint *)ac->Elts; + GLuint i; + + switch (old_type) { + case GL_UNSIGNED_BYTE: { + CONST GLubyte *in = (CONST GLubyte *)indices; + for (i = 0 ; i < count ; i++) + out[i] = in[i]; + break; + } + case GL_UNSIGNED_SHORT: { + CONST GLushort *in = (CONST GLushort *)indices; + for (i = 0 ; i < count ; i++) + out[i] = in[i]; + break; + } + default: + ASSERT(0); + } + + return (CONST void *)out; + } + default: + ASSERT(0); + break; + } + + return 0; +} diff --git a/reactos/lib/mesa32/src/array_cache/acache.h b/reactos/lib/mesa32/src/array_cache/acache.h new file mode 100644 index 00000000000..2bb64f3656c --- /dev/null +++ b/reactos/lib/mesa32/src/array_cache/acache.h @@ -0,0 +1,132 @@ + +/* + * Mesa 3-D graphics library + * Version: 4.1 + * + * 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 + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Keith Whitwell + */ + +#ifndef _ARRAYCACHE_H +#define _ARRAYCACHE_H + +#include "mtypes.h" + + +extern GLboolean +_ac_CreateContext( GLcontext *ctx ); + +extern void +_ac_DestroyContext( GLcontext *ctx ); + +extern void +_ac_InvalidateState( GLcontext *ctx, GLuint new_state ); + +extern struct gl_client_array * +_ac_import_vertex( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLuint reqsize, + GLboolean reqwritable, + GLboolean *writable ); + +extern struct gl_client_array * +_ac_import_normal( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLboolean reqwritable, + GLboolean *writable ); + +extern struct gl_client_array * +_ac_import_color( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLuint reqsize, + GLboolean reqwritable, + GLboolean *writable ); + +extern struct gl_client_array * +_ac_import_index( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLboolean reqwritable, + GLboolean *writable ); + +extern struct gl_client_array * +_ac_import_secondarycolor( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLuint reqsize, + GLboolean reqwritable, + GLboolean *writable ); + +extern struct gl_client_array * +_ac_import_fogcoord( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLboolean reqwritable, + GLboolean *writable ); + +extern struct gl_client_array * +_ac_import_edgeflag( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLboolean reqwritable, + GLboolean *writable ); + +extern struct gl_client_array * +_ac_import_texcoord( GLcontext *ctx, + GLuint unit, + GLenum type, + GLuint reqstride, + GLuint reqsize, + GLboolean reqwritable, + GLboolean *writable ); + +extern struct gl_client_array * +_ac_import_attrib( GLcontext *ctx, + GLuint index, + GLenum type, + GLuint reqstride, + GLuint reqsize, + GLboolean reqwritable, + GLboolean *writable ); + + +/* Clients must call this function to validate state and set bounds + * before importing any data: + */ +extern void +_ac_import_range( GLcontext *ctx, GLuint start, GLuint count ); + + +/* Additional convenience function: + */ +extern CONST void * +_ac_import_elements( GLcontext *ctx, + GLenum new_type, + GLuint count, + GLenum old_type, + CONST void *indices ); + + +#endif diff --git a/reactos/lib/mesa32/src/array_cache/array_cache.dsp b/reactos/lib/mesa32/src/array_cache/array_cache.dsp new file mode 100644 index 00000000000..5f1138dab5c --- /dev/null +++ b/reactos/lib/mesa32/src/array_cache/array_cache.dsp @@ -0,0 +1,108 @@ +# Microsoft Developer Studio Project File - Name="array_cache" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=array_cache - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "array_cache.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "array_cache.mak" CFG="array_cache - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "array_cache - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "array_cache - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "array_cache - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /I "../" /I "../main" /I "../glapi" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "array_cache - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /I "../" /I "../main" /I "../glapi" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ENDIF + +# Begin Target + +# Name "array_cache - Win32 Release" +# Name "array_cache - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\ac_context.c +# End Source File +# Begin Source File + +SOURCE=.\ac_import.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\ac_context.h +# End Source File +# Begin Source File + +SOURCE=.\acache.h +# End Source File +# End Group +# End Target +# End Project diff --git a/reactos/lib/mesa32/src/drivers/beos/GLView.cpp b/reactos/lib/mesa32/src/drivers/beos/GLView.cpp new file mode 100644 index 00000000000..38da3161b30 --- /dev/null +++ b/reactos/lib/mesa32/src/drivers/beos/GLView.cpp @@ -0,0 +1,1427 @@ +/* $Id: GLView.cpp,v 1.1 2004/07/16 22:12:29 blight Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 5.0 + * + * 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 + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#include +#include + +extern "C" { + +#include "glheader.h" +#include "buffers.h" +#include "bufferobj.h" +#include "context.h" +#include "colormac.h" +#include "depth.h" +#include "extensions.h" +#include "macros.h" +#include "matrix.h" +#include "mtypes.h" +#include "texformat.h" +#include "texobj.h" +#include "teximage.h" +#include "texstore.h" +#include "array_cache/acache.h" +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "swrast/s_context.h" +#include "swrast/s_depth.h" +#include "swrast/s_lines.h" +#include "swrast/s_triangle.h" +#include "swrast/s_trispan.h" +#include "tnl/tnl.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" + +} // extern "C" + +#include "GLView.h" + +// BeOS component ordering for B_RGBA32 bitmap format +#define BE_RCOMP 2 +#define BE_GCOMP 1 +#define BE_BCOMP 0 +#define BE_ACOMP 3 + +#define PACK_B_RGBA32(color) (color[BCOMP] | (color[GCOMP] << 8) | \ + (color[RCOMP] << 16) | (color[ACOMP] << 24)) + +#define PACK_B_RGB32(color) (color[BCOMP] | (color[GCOMP] << 8) | \ + (color[RCOMP] << 16) | 0xFF000000) + +#define FLIP(coord) (LIBGGI_MODE(ggi_ctx->ggi_visual)->visible.y-(coord) - 1) + +// +// This object hangs off of the BGLView object. We have to use +// Be's BGLView class as-is to maintain binary compatibility (we +// can't add new members to it). Instead we just put all our data +// in this class and use BGLVIew::m_gc to point to it. +// +class MesaDriver +{ +public: + MesaDriver(); + ~MesaDriver(); + void Init(BGLView * bglview, GLcontext * c, GLvisual * v, GLframebuffer * b); + + void LockGL(); + void UnlockGL(); + void SwapBuffers() const; + void CopySubBuffer(GLint x, GLint y, GLuint width, GLuint height) const; + void Draw(BRect updateRect) const; + +private: + MesaDriver(const MesaDriver &rhs); // copy constructor illegal + MesaDriver &operator=(const MesaDriver &rhs); // assignment oper. illegal + + GLcontext * m_glcontext; + GLvisual * m_glvisual; + GLframebuffer * m_glframebuffer; + + BGLView * m_bglview; + BBitmap * m_bitmap; + + GLchan m_clear_color[4]; // buffer clear color + GLuint m_clear_index; // buffer clear color index + GLint m_bottom; // used for flipping Y coords + GLuint m_width; + GLuint m_height; + + // Mesa Device Driver functions + static void UpdateState(GLcontext *ctx, GLuint new_state); + static void ClearIndex(GLcontext *ctx, GLuint index); + static void ClearColor(GLcontext *ctx, const GLfloat color[4]); + static void Clear(GLcontext *ctx, GLbitfield mask, + GLboolean all, GLint x, GLint y, + GLint width, GLint height); + static void ClearFront(GLcontext *ctx, GLboolean all, GLint x, GLint y, + GLint width, GLint height); + static void ClearBack(GLcontext *ctx, GLboolean all, GLint x, GLint y, + GLint width, GLint height); + static void Index(GLcontext *ctx, GLuint index); + static void Color(GLcontext *ctx, GLubyte r, GLubyte g, + GLubyte b, GLubyte a); + static void SetBuffer(GLcontext *ctx, GLframebuffer *colorBuffer, + GLenum mode); + static void GetBufferSize(GLframebuffer * framebuffer, GLuint *width, + GLuint *height); + static const GLubyte * GetString(GLcontext *ctx, GLenum name); + + // Front-buffer functions + static void WriteRGBASpanFront(const GLcontext *ctx, GLuint n, + GLint x, GLint y, + CONST GLubyte rgba[][4], + const GLubyte mask[]); + static void WriteRGBSpanFront(const GLcontext *ctx, GLuint n, + GLint x, GLint y, + CONST GLubyte rgba[][3], + const GLubyte mask[]); + static void WriteMonoRGBASpanFront(const GLcontext *ctx, GLuint n, + GLint x, GLint y, + const GLchan color[4], + const GLubyte mask[]); + static void WriteRGBAPixelsFront(const GLcontext *ctx, GLuint n, + const GLint x[], const GLint y[], + CONST GLubyte rgba[][4], + const GLubyte mask[]); + static void WriteMonoRGBAPixelsFront(const GLcontext *ctx, GLuint n, + const GLint x[], const GLint y[], + const GLchan color[4], + const GLubyte mask[]); + static void WriteCI32SpanFront(const GLcontext *ctx, GLuint n, + GLint x, GLint y, + const GLuint index[], const GLubyte mask[]); + static void WriteCI8SpanFront(const GLcontext *ctx, GLuint n, + GLint x, GLint y, + const GLubyte index[], const GLubyte mask[]); + static void WriteMonoCISpanFront(const GLcontext *ctx, GLuint n, + GLint x, GLint y, + GLuint colorIndex, const GLubyte mask[]); + static void WriteCI32PixelsFront(const GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + const GLuint index[], const GLubyte mask[]); + static void WriteMonoCIPixelsFront(const GLcontext *ctx, GLuint n, + const GLint x[], const GLint y[], + GLuint colorIndex, const GLubyte mask[]); + static void ReadCI32SpanFront(const GLcontext *ctx, + GLuint n, GLint x, GLint y, GLuint index[]); + static void ReadRGBASpanFront(const GLcontext *ctx, GLuint n, + GLint x, GLint y, + GLubyte rgba[][4]); + static void ReadCI32PixelsFront(const GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + GLuint indx[], const GLubyte mask[]); + static void ReadRGBAPixelsFront(const GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + GLubyte rgba[][4], const GLubyte mask[]); + + // Back buffer functions + static void WriteRGBASpanBack(const GLcontext *ctx, GLuint n, + GLint x, GLint y, + CONST GLubyte rgba[][4], + const GLubyte mask[]); + static void WriteRGBSpanBack(const GLcontext *ctx, GLuint n, + GLint x, GLint y, + CONST GLubyte rgba[][3], + const GLubyte mask[]); + static void WriteMonoRGBASpanBack(const GLcontext *ctx, GLuint n, + GLint x, GLint y, + const GLchan color[4], + const GLubyte mask[]); + static void WriteRGBAPixelsBack(const GLcontext *ctx, GLuint n, + const GLint x[], const GLint y[], + CONST GLubyte rgba[][4], + const GLubyte mask[]); + static void WriteMonoRGBAPixelsBack(const GLcontext *ctx, GLuint n, + const GLint x[], const GLint y[], + const GLchan color[4], + const GLubyte mask[]); + static void WriteCI32SpanBack(const GLcontext *ctx, GLuint n, + GLint x, GLint y, + const GLuint index[], const GLubyte mask[]); + static void WriteCI8SpanBack(const GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLubyte index[], const GLubyte mask[]); + static void WriteMonoCISpanBack(const GLcontext *ctx, GLuint n, + GLint x, GLint y, GLuint colorIndex, + const GLubyte mask[]); + static void WriteCI32PixelsBack(const GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + const GLuint index[], const GLubyte mask[]); + static void WriteMonoCIPixelsBack(const GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + GLuint colorIndex, const GLubyte mask[]); + static void ReadCI32SpanBack(const GLcontext *ctx, + GLuint n, GLint x, GLint y, GLuint index[]); + static void ReadRGBASpanBack(const GLcontext *ctx, GLuint n, + GLint x, GLint y, + GLubyte rgba[][4]); + static void ReadCI32PixelsBack(const GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + GLuint indx[], const GLubyte mask[]); + static void ReadRGBAPixelsBack(const GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + GLubyte rgba[][4], const GLubyte mask[]); + +}; + +//------------------------------------------------------------------ +// Public interface methods +//------------------------------------------------------------------ + + +// +// Input: rect - initial rectangle +// name - window name +// resizingMode - example: B_FOLLOW_NONE +// mode - usually 0 ? +// options - Bitwise-OR of BGL_* tokens +// +BGLView::BGLView(BRect rect, char *name, + ulong resizingMode, ulong mode, + ulong options) + :BView(rect, name, resizingMode, mode | B_WILL_DRAW | B_FRAME_EVENTS) // | B_FULL_UPDATE_ON_RESIZE) +{ + const GLboolean rgbFlag = (options & BGL_RGB) == BGL_RGB; + const GLboolean alphaFlag = (options & BGL_ALPHA) == BGL_ALPHA; + const GLboolean dblFlag = (options & BGL_DOUBLE) == BGL_DOUBLE; + const GLboolean stereoFlag = false; + const GLint depth = (options & BGL_DEPTH) ? 16 : 0; + const GLint stencil = (options & BGL_STENCIL) ? 8 : 0; + const GLint accum = (options & BGL_ACCUM) ? 16 : 0; + const GLint index = (options & BGL_INDEX) ? 32 : 0; + const GLint red = (options & BGL_RGB) ? 8 : 0; + const GLint green = (options & BGL_RGB) ? 8 : 0; + const GLint blue = (options & BGL_RGB) ? 8 : 0; + const GLint alpha = (options & BGL_RGB) ? 8 : 0; + + if (!rgbFlag) { + fprintf(stderr, "Mesa Warning: color index mode not supported\n"); + } + + // Allocate auxiliary data object + MesaDriver * md = new MesaDriver; + + // examine option flags and create gl_context struct + GLvisual * visual = _mesa_create_visual( rgbFlag, + dblFlag, + stereoFlag, + red, green, blue, alpha, + index, + depth, + stencil, + accum, accum, accum, accum, + 1 + ); + + // create core context + GLcontext * ctx = _mesa_create_context(visual, NULL, md, GL_FALSE); + + ctx->Driver.NewTextureObject = _mesa_new_texture_object; + ctx->Driver.DeleteTexture = _mesa_delete_texture_object; + + _mesa_initialize_context(ctx, visual, NULL, md, GL_FALSE); + + _mesa_enable_sw_extensions(ctx); + _mesa_enable_1_3_extensions(ctx); + _mesa_enable_1_4_extensions(ctx); + _mesa_enable_1_5_extensions(ctx); + + + + // create core framebuffer + GLframebuffer * buffer = _mesa_create_framebuffer(visual, + depth > 0 ? GL_TRUE : GL_FALSE, + stencil > 0 ? GL_TRUE: GL_FALSE, + accum > 0 ? GL_TRUE : GL_FALSE, + alphaFlag + ); + + /* Initialize the software rasterizer and helper modules. + */ + _swrast_CreateContext(ctx); + _ac_CreateContext(ctx); + _tnl_CreateContext(ctx); + _swsetup_CreateContext(ctx); + _swsetup_Wakeup(ctx); + + md->Init(this, ctx, visual, buffer ); + + // Hook aux data into BGLView object + m_gc = md; +} + + +BGLView::~BGLView() +{ + printf("BGLView destructor\n"); + MesaDriver * md = (MesaDriver *) m_gc; + assert(md); + delete md; +} + +void BGLView::LockGL() +{ + MesaDriver * md = (MesaDriver *) m_gc; + assert(md); + md->LockGL(); +} + +void BGLView::UnlockGL() +{ + MesaDriver * md = (MesaDriver *) m_gc; + assert(md); + md->UnlockGL(); +} + +void BGLView::SwapBuffers() +{ + MesaDriver * md = (MesaDriver *) m_gc; + assert(md); + md->SwapBuffers(); +} + + +void BGLView::CopySubBufferMESA(GLint x, GLint y, GLuint width, GLuint height) +{ + MesaDriver * md = (MesaDriver *) m_gc; + assert(md); + md->CopySubBuffer(x, y, width, height); +} + + +BView * BGLView::EmbeddedView() +{ + // XXX to do + return NULL; +} + +status_t BGLView::CopyPixelsOut(BPoint source, BBitmap *dest) +{ + // XXX to do + printf("BGLView::CopyPixelsOut() not implemented yet!\n"); + return B_UNSUPPORTED; +} + + +status_t BGLView::CopyPixelsIn(BBitmap *source, BPoint dest) +{ + // XXX to do + printf("BGLView::CopyPixelsIn() not implemented yet!\n"); + return B_UNSUPPORTED; +} + +void BGLView::ErrorCallback(unsigned long errorCode) // GLenum errorCode) +{ + // XXX to do + printf("BGLView::ErrorCallback() not implemented yet!\n"); + return; +} + +void BGLView::Draw(BRect updateRect) +{ + // printf("BGLView::Draw()\n"); + MesaDriver * md = (MesaDriver *) m_gc; + assert(md); + md->Draw(updateRect); +} + +void BGLView::AttachedToWindow() +{ + BView::AttachedToWindow(); + + // don't paint window background white when resized + SetViewColor(B_TRANSPARENT_32_BIT); +} + +void BGLView::AllAttached() +{ + BView::AllAttached(); +// printf("BGLView AllAttached\n"); +} + +void BGLView::DetachedFromWindow() +{ + BView::DetachedFromWindow(); +} + +void BGLView::AllDetached() +{ + BView::AllDetached(); +// printf("BGLView AllDetached"); +} + +void BGLView::FrameResized(float width, float height) +{ + return BView::FrameResized(width, height); +} + +status_t BGLView::Perform(perform_code d, void *arg) +{ + return BView::Perform(d, arg); +} + + +status_t BGLView::Archive(BMessage *data, bool deep) const +{ + return BView::Archive(data, deep); +} + +void BGLView::MessageReceived(BMessage *msg) +{ + BView::MessageReceived(msg); +} + +void BGLView::SetResizingMode(uint32 mode) +{ + BView::SetResizingMode(mode); +} + +void BGLView::Show() +{ +// printf("BGLView Show\n"); + BView::Show(); +} + +void BGLView::Hide() +{ +// printf("BGLView Hide\n"); + BView::Hide(); +} + +BHandler *BGLView::ResolveSpecifier(BMessage *msg, int32 index, + BMessage *specifier, int32 form, + const char *property) +{ + return BView::ResolveSpecifier(msg, index, specifier, form, property); +} + +status_t BGLView::GetSupportedSuites(BMessage *data) +{ + return BView::GetSupportedSuites(data); +} + +void BGLView::DirectConnected( direct_buffer_info *info ) +{ + // XXX to do +} + +void BGLView::EnableDirectMode( bool enabled ) +{ + // XXX to do +} + + + +//---- private methods ---------- + +void BGLView::_ReservedGLView1() {} +void BGLView::_ReservedGLView2() {} +void BGLView::_ReservedGLView3() {} +void BGLView::_ReservedGLView4() {} +void BGLView::_ReservedGLView5() {} +void BGLView::_ReservedGLView6() {} +void BGLView::_ReservedGLView7() {} +void BGLView::_ReservedGLView8() {} + +#if 0 +BGLView::BGLView(const BGLView &v) + : BView(v) +{ + // XXX not sure how this should work + printf("Warning BGLView::copy constructor not implemented\n"); +} +#endif + + +BGLView &BGLView::operator=(const BGLView &v) +{ + printf("Warning BGLView::operator= not implemented\n"); + return *this; +} + +void BGLView::dither_front() +{ + // no-op +} + +bool BGLView::confirm_dither() +{ + // no-op + return false; +} + +void BGLView::draw(BRect r) +{ + // XXX no-op ??? +} + +/* Direct Window stuff */ +void BGLView::drawScanline( int x1, int x2, int y, void *data ) +{ + // no-op +} + +void BGLView::scanlineHandler(struct rasStateRec *state, + GLint x1, GLint x2) +{ + // no-op +} + +void BGLView::lock_draw() +{ + // no-op +} + +void BGLView::unlock_draw() +{ + // no-op +} + +bool BGLView::validateView() +{ + // no-op + return true; +} + +// #pragma mark - + +MesaDriver::MesaDriver() +{ + m_glcontext = NULL; + m_glvisual = NULL; + m_glframebuffer = NULL; + m_bglview = NULL; + m_bitmap = NULL; + + m_clear_color[BE_RCOMP] = 0; + m_clear_color[BE_GCOMP] = 0; + m_clear_color[BE_BCOMP] = 0; + m_clear_color[BE_ACOMP] = 0; + + m_clear_index = 0; +} + + +MesaDriver::~MesaDriver() +{ + _mesa_destroy_visual(m_glvisual); + _mesa_destroy_framebuffer(m_glframebuffer); + _mesa_destroy_context(m_glcontext); + +} + + +void MesaDriver::Init(BGLView * bglview, GLcontext * ctx, GLvisual * visual, GLframebuffer * framebuffer) +{ + m_bglview = bglview; + m_glcontext = ctx; + m_glvisual = visual; + m_glframebuffer = framebuffer; + + MesaDriver * md = (MesaDriver *) ctx->DriverCtx; + struct swrast_device_driver * swdd = _swrast_GetDeviceDriverReference( ctx ); + TNLcontext * tnl = TNL_CONTEXT(ctx); + + assert(md->m_glcontext == ctx ); + + // Use default TCL pipeline + tnl->Driver.RunPipeline = _tnl_run_pipeline; + + ctx->Driver.GetString = MesaDriver::GetString; + ctx->Driver.UpdateState = MesaDriver::UpdateState; + ctx->Driver.ResizeBuffers = _swrast_alloc_buffers; + ctx->Driver.GetBufferSize = MesaDriver::GetBufferSize; + + ctx->Driver.Accum = _swrast_Accum; + ctx->Driver.Bitmap = _swrast_Bitmap; + ctx->Driver.Clear = MesaDriver::Clear; + // ctx->Driver.ClearIndex = MesaDriver::ClearIndex; + // ctx->Driver.ClearColor = MesaDriver::ClearColor; + ctx->Driver.CopyPixels = _swrast_CopyPixels; + ctx->Driver.DrawPixels = _swrast_DrawPixels; + ctx->Driver.ReadPixels = _swrast_ReadPixels; + ctx->Driver.DrawBuffer = _swrast_DrawBuffer; + + ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format; + ctx->Driver.TexImage1D = _mesa_store_teximage1d; + ctx->Driver.TexImage2D = _mesa_store_teximage2d; + ctx->Driver.TexImage3D = _mesa_store_teximage3d; + ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d; + ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d; + ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d; + ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage; + + ctx->Driver.CompressedTexImage1D = _mesa_store_compressed_teximage1d; + ctx->Driver.CompressedTexImage2D = _mesa_store_compressed_teximage2d; + ctx->Driver.CompressedTexImage3D = _mesa_store_compressed_teximage3d; + ctx->Driver.CompressedTexSubImage1D = _mesa_store_compressed_texsubimage1d; + ctx->Driver.CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d; + ctx->Driver.CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d; + + ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d; + ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d; + ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d; + ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d; + ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d; + ctx->Driver.CopyColorTable = _swrast_CopyColorTable; + ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable; + ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D; + ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D; + + swdd->SetBuffer = MesaDriver::SetBuffer; +} + + +void MesaDriver::LockGL() +{ + m_bglview->LockLooper(); + + UpdateState(m_glcontext, 0); + _mesa_make_current(m_glcontext, m_glframebuffer); +} + + +void MesaDriver::UnlockGL() +{ + m_bglview->UnlockLooper(); + // Could call _mesa_make_current(NULL, NULL) but it would just + // hinder performance +} + + +void MesaDriver::SwapBuffers() const +{ + // _mesa_notifySwapBuffers(m_glcontext); + + if (m_bitmap) { + m_bglview->LockLooper(); + m_bglview->DrawBitmap(m_bitmap, BPoint(0, 0)); + m_bglview->UnlockLooper(); + }; +} + + +void MesaDriver::CopySubBuffer(GLint x, GLint y, GLuint width, GLuint height) const +{ + if (m_bitmap) { + // Source bitmap and view's bitmap are same size. + // Source and dest rectangle are the same. + // Note (x,y) = (0,0) is the lower-left corner, have to flip Y + BRect srcAndDest; + srcAndDest.left = x; + srcAndDest.right = x + width - 1; + srcAndDest.bottom = m_bottom - y; + srcAndDest.top = srcAndDest.bottom - height + 1; + m_bglview->DrawBitmap(m_bitmap, srcAndDest, srcAndDest); + } +} + + +void MesaDriver::Draw(BRect updateRect) const +{ + if (m_bitmap) + m_bglview->DrawBitmap(m_bitmap, updateRect, updateRect); +} + + +void MesaDriver::UpdateState( GLcontext *ctx, GLuint new_state ) +{ + struct swrast_device_driver * swdd = _swrast_GetDeviceDriverReference( ctx ); + + _swrast_InvalidateState( ctx, new_state ); + _swsetup_InvalidateState( ctx, new_state ); + _ac_InvalidateState( ctx, new_state ); + _tnl_InvalidateState( ctx, new_state ); + + if (ctx->Color.DrawBuffer == GL_FRONT) { + /* read/write front buffer */ + swdd->WriteRGBASpan = MesaDriver::WriteRGBASpanFront; + swdd->WriteRGBSpan = MesaDriver::WriteRGBSpanFront; + swdd->WriteRGBAPixels = MesaDriver::WriteRGBAPixelsFront; + swdd->WriteMonoRGBASpan = MesaDriver::WriteMonoRGBASpanFront; + swdd->WriteMonoRGBAPixels = MesaDriver::WriteMonoRGBAPixelsFront; + swdd->WriteCI32Span = MesaDriver::WriteCI32SpanFront; + swdd->WriteCI8Span = MesaDriver::WriteCI8SpanFront; + swdd->WriteMonoCISpan = MesaDriver::WriteMonoCISpanFront; + swdd->WriteCI32Pixels = MesaDriver::WriteCI32PixelsFront; + swdd->WriteMonoCIPixels = MesaDriver::WriteMonoCIPixelsFront; + swdd->ReadRGBASpan = MesaDriver::ReadRGBASpanFront; + swdd->ReadRGBAPixels = MesaDriver::ReadRGBAPixelsFront; + swdd->ReadCI32Span = MesaDriver::ReadCI32SpanFront; + swdd->ReadCI32Pixels = MesaDriver::ReadCI32PixelsFront; + } + else { + /* read/write back buffer */ + swdd->WriteRGBASpan = MesaDriver::WriteRGBASpanBack; + swdd->WriteRGBSpan = MesaDriver::WriteRGBSpanBack; + swdd->WriteRGBAPixels = MesaDriver::WriteRGBAPixelsBack; + swdd->WriteMonoRGBASpan = MesaDriver::WriteMonoRGBASpanBack; + swdd->WriteMonoRGBAPixels = MesaDriver::WriteMonoRGBAPixelsBack; + swdd->WriteCI32Span = MesaDriver::WriteCI32SpanBack; + swdd->WriteCI8Span = MesaDriver::WriteCI8SpanBack; + swdd->WriteMonoCISpan = MesaDriver::WriteMonoCISpanBack; + swdd->WriteCI32Pixels = MesaDriver::WriteCI32PixelsBack; + swdd->WriteMonoCIPixels = MesaDriver::WriteMonoCIPixelsBack; + swdd->ReadRGBASpan = MesaDriver::ReadRGBASpanBack; + swdd->ReadRGBAPixels = MesaDriver::ReadRGBAPixelsBack; + swdd->ReadCI32Span = MesaDriver::ReadCI32SpanBack; + swdd->ReadCI32Pixels = MesaDriver::ReadCI32PixelsBack; + } +} + + +void MesaDriver::ClearIndex(GLcontext *ctx, GLuint index) +{ + MesaDriver *md = (MesaDriver *) ctx->DriverCtx; + md->m_clear_index = index; +} + + +void MesaDriver::ClearColor(GLcontext *ctx, const GLfloat color[4]) +{ + MesaDriver *md = (MesaDriver *) ctx->DriverCtx; + CLAMPED_FLOAT_TO_CHAN(md->m_clear_color[BE_RCOMP], color[0]); + CLAMPED_FLOAT_TO_CHAN(md->m_clear_color[BE_GCOMP], color[1]); + CLAMPED_FLOAT_TO_CHAN(md->m_clear_color[BE_BCOMP], color[2]); + CLAMPED_FLOAT_TO_CHAN(md->m_clear_color[BE_ACOMP], color[3]); + assert(md->m_bglview); +} + + +void MesaDriver::Clear(GLcontext *ctx, GLbitfield mask, + GLboolean all, GLint x, GLint y, + GLint width, GLint height) +{ + if (mask & DD_FRONT_LEFT_BIT) + ClearFront(ctx, all, x, y, width, height); + if (mask & DD_BACK_LEFT_BIT) + ClearBack(ctx, all, x, y, width, height); + + mask &= ~(DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT); + if (mask) + _swrast_Clear( ctx, mask, all, x, y, width, height ); + + return; +} + + +void MesaDriver::ClearFront(GLcontext *ctx, + GLboolean all, GLint x, GLint y, + GLint width, GLint height) +{ + MesaDriver *md = (MesaDriver *) ctx->DriverCtx; + BGLView *bglview = md->m_bglview; + assert(bglview); + + bglview->SetHighColor(md->m_clear_color[BE_RCOMP], + md->m_clear_color[BE_GCOMP], + md->m_clear_color[BE_BCOMP], + md->m_clear_color[BE_ACOMP]); + bglview->SetLowColor(md->m_clear_color[BE_RCOMP], + md->m_clear_color[BE_GCOMP], + md->m_clear_color[BE_BCOMP], + md->m_clear_color[BE_ACOMP]); + if (all) { + BRect b = bglview->Bounds(); + bglview->FillRect(b); + } + else { + // XXX untested + BRect b; + b.left = x; + b.right = x + width; + b.bottom = md->m_height - y - 1; + b.top = b.bottom - height; + bglview->FillRect(b); + } + + // restore drawing color +#if 0 + bglview->SetHighColor(md->mColor[BE_RCOMP], + md->mColor[BE_GCOMP], + md->mColor[BE_BCOMP], + md->mColor[BE_ACOMP]); + bglview->SetLowColor(md->mColor[BE_RCOMP], + md->mColor[BE_GCOMP], + md->mColor[BE_BCOMP], + md->mColor[BE_ACOMP]); +#endif +} + + +void MesaDriver::ClearBack(GLcontext *ctx, + GLboolean all, GLint x, GLint y, + GLint width, GLint height) +{ + MesaDriver *md = (MesaDriver *) ctx->DriverCtx; + BGLView *bglview = md->m_bglview; + assert(bglview); + BBitmap *bitmap = md->m_bitmap; + assert(bitmap); + GLuint *start = (GLuint *) bitmap->Bits(); + const GLuint *clearPixelPtr = (const GLuint *) md->m_clear_color; + const GLuint clearPixel = *clearPixelPtr; + + if (all) { + const int numPixels = md->m_width * md->m_height; + if (clearPixel == 0) { + memset(start, 0, numPixels * 4); + } + else { + for (int i = 0; i < numPixels; i++) { + start[i] = clearPixel; + } + } + } + else { + // XXX untested + start += y * md->m_width + x; + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { + start[j] = clearPixel; + } + start += md->m_width; + } + } +} + + +void MesaDriver::SetBuffer(GLcontext *ctx, GLframebuffer *buffer, + GLenum mode) +{ + /* TODO */ + (void) ctx; + (void) buffer; + (void) mode; +} + +void MesaDriver::GetBufferSize(GLframebuffer * framebuffer, GLuint *width, + GLuint *height) +{ + GET_CURRENT_CONTEXT(ctx); + if (!ctx) + return; + + MesaDriver * md = (MesaDriver *) ctx->DriverCtx; + BGLView *bglview = md->m_bglview; + assert(bglview); + + BRect b = bglview->Bounds(); + *width = (GLuint) b.IntegerWidth() + 1; // (b.right - b.left + 1); + *height = (GLuint) b.IntegerHeight() + 1; // (b.bottom - b.top + 1); + md->m_bottom = (GLint) b.bottom; + + if (ctx->Visual.doubleBufferMode) { + if (*width != md->m_width || *height != md->m_height) { + // allocate new size of back buffer bitmap + if (md->m_bitmap) + delete md->m_bitmap; + BRect rect(0.0, 0.0, *width - 1, *height - 1); + md->m_bitmap = new BBitmap(rect, B_RGBA32); + } + } + else + { + md->m_bitmap = NULL; + } + + md->m_width = *width; + md->m_height = *height; +} + + +const GLubyte *MesaDriver::GetString(GLcontext *ctx, GLenum name) +{ + switch (name) { + case GL_RENDERER: + return (const GLubyte *) "Mesa BGLView (software)"; + default: + // Let core library handle all other cases + return NULL; + } +} + + +// Plot a pixel. (0,0) is upper-left corner +// This is only used when drawing to the front buffer. +inline void Plot(BGLView *bglview, int x, int y) +{ + // XXX There's got to be a better way! + BPoint p(x, y), q(x+1, y); + bglview->StrokeLine(p, q); +} + + +void MesaDriver::WriteRGBASpanFront(const GLcontext *ctx, GLuint n, + GLint x, GLint y, + CONST GLubyte rgba[][4], + const GLubyte mask[]) +{ + MesaDriver *md = (MesaDriver *) ctx->DriverCtx; + BGLView *bglview = md->m_bglview; + assert(bglview); + int flippedY = md->m_bottom - y; + if (mask) { + for (GLuint i = 0; i < n; i++) { + if (mask[i]) { + bglview->SetHighColor(rgba[i][0], rgba[i][1], rgba[i][2], rgba[i][3]); + Plot(bglview, x++, flippedY); + } + } + } + else { + for (GLuint i = 0; i < n; i++) { + bglview->SetHighColor(rgba[i][0], rgba[i][1], rgba[i][2], rgba[i][3]); + Plot(bglview, x++, flippedY); + } + } +} + +void MesaDriver::WriteRGBSpanFront(const GLcontext *ctx, GLuint n, + GLint x, GLint y, + CONST GLubyte rgba[][3], + const GLubyte mask[]) +{ + MesaDriver *md = (MesaDriver *) ctx->DriverCtx; + BGLView *bglview = md->m_bglview; + assert(bglview); + int flippedY = md->m_bottom - y; + if (mask) { + for (GLuint i = 0; i < n; i++) { + if (mask[i]) { + bglview->SetHighColor(rgba[i][0], rgba[i][1], rgba[i][2]); + Plot(bglview, x++, flippedY); + } + } + } + else { + for (GLuint i = 0; i < n; i++) { + bglview->SetHighColor(rgba[i][0], rgba[i][1], rgba[i][2]); + Plot(bglview, x++, flippedY); + } + } +} + +void MesaDriver::WriteMonoRGBASpanFront(const GLcontext *ctx, GLuint n, + GLint x, GLint y, + const GLchan color[4], + const GLubyte mask[]) +{ + MesaDriver *md = (MesaDriver *) ctx->DriverCtx; + BGLView *bglview = md->m_bglview; + assert(bglview); + int flippedY = md->m_bottom - y; + bglview->SetHighColor(color[RCOMP], color[GCOMP], color[BCOMP]); + if (mask) { + for (GLuint i = 0; i < n; i++) { + if (mask[i]) { + Plot(bglview, x++, flippedY); + } + } + } + else { + for (GLuint i = 0; i < n; i++) { + Plot(bglview, x++, flippedY); + } + } +} + +void MesaDriver::WriteRGBAPixelsFront(const GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + CONST GLubyte rgba[][4], + const GLubyte mask[] ) +{ + MesaDriver *md = (MesaDriver *) ctx->DriverCtx; + BGLView *bglview = md->m_bglview; + assert(bglview); + if (mask) { + for (GLuint i = 0; i < n; i++) { + if (mask[i]) { + bglview->SetHighColor(rgba[i][0], rgba[i][1], rgba[i][2]); + Plot(bglview, x[i], md->m_bottom - y[i]); + } + } + } + else { + for (GLuint i = 0; i < n; i++) { + bglview->SetHighColor(rgba[i][0], rgba[i][1], rgba[i][2]); + Plot(bglview, x[i], md->m_bottom - y[i]); + } + } +} + + +void MesaDriver::WriteMonoRGBAPixelsFront(const GLcontext *ctx, GLuint n, + const GLint x[], const GLint y[], + const GLchan color[4], + const GLubyte mask[]) +{ + MesaDriver *md = (MesaDriver *) ctx->DriverCtx; + BGLView *bglview = md->m_bglview; + assert(bglview); + // plot points using current color + bglview->SetHighColor(color[RCOMP], color[GCOMP], color[BCOMP]); + if (mask) { + for (GLuint i = 0; i < n; i++) { + if (mask[i]) { + Plot(bglview, x[i], md->m_bottom - y[i]); + } + } + } + else { + for (GLuint i = 0; i < n; i++) { + Plot(bglview, x[i], md->m_bottom - y[i]); + } + } +} + + +void MesaDriver::WriteCI32SpanFront( const GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLuint index[], const GLubyte mask[] ) +{ + // XXX to do +} + +void MesaDriver::WriteCI8SpanFront( const GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLubyte index[], const GLubyte mask[] ) +{ + // XXX to do +} + +void MesaDriver::WriteMonoCISpanFront( const GLcontext *ctx, GLuint n, + GLint x, GLint y, + GLuint colorIndex, const GLubyte mask[] ) +{ + // XXX to do +} + + +void MesaDriver::WriteCI32PixelsFront( const GLcontext *ctx, GLuint n, + const GLint x[], const GLint y[], + const GLuint index[], const GLubyte mask[] ) +{ + // XXX to do +} + +void MesaDriver::WriteMonoCIPixelsFront( const GLcontext *ctx, GLuint n, + const GLint x[], const GLint y[], + GLuint colorIndex, const GLubyte mask[] ) +{ + // XXX to do +} + + +void MesaDriver::ReadCI32SpanFront( const GLcontext *ctx, + GLuint n, GLint x, GLint y, GLuint index[] ) +{ + printf("ReadCI32SpanFront() not implemented yet!\n"); + // XXX to do +} + + +void MesaDriver::ReadRGBASpanFront( const GLcontext *ctx, GLuint n, + GLint x, GLint y, GLubyte rgba[][4] ) +{ + printf("ReadRGBASpanFront() not implemented yet!\n"); + // XXX to do +} + + +void MesaDriver::ReadCI32PixelsFront( const GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + GLuint indx[], const GLubyte mask[] ) +{ + printf("ReadCI32PixelsFront() not implemented yet!\n"); + // XXX to do +} + + +void MesaDriver::ReadRGBAPixelsFront( const GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + GLubyte rgba[][4], const GLubyte mask[] ) +{ + printf("ReadRGBAPixelsFront() not implemented yet!\n"); + // XXX to do +} + + + + +void MesaDriver::WriteRGBASpanBack(const GLcontext *ctx, GLuint n, + GLint x, GLint y, + CONST GLubyte rgba[][4], + const GLubyte mask[]) +{ + MesaDriver *md = (MesaDriver *) ctx->DriverCtx; + BBitmap *bitmap = md->m_bitmap; + + static bool already_called = false; + if (! already_called) { + printf("WriteRGBASpanBack() called.\n"); + already_called = true; + } + + assert(bitmap); + + int row = md->m_bottom - y; + uint8 * ptr = (uint8 *) bitmap->Bits() + (row * bitmap->BytesPerRow()) + x * 4; + uint32 * pixel = (uint32 *) ptr; + + if (mask) { + while(n--) { + if (*mask++) + *pixel = PACK_B_RGBA32(rgba[0]); + pixel++; + rgba++; + }; + } else { + while(n--) { + *pixel++ = PACK_B_RGBA32(rgba[0]); + rgba++; + }; + }; + } + + +void MesaDriver::WriteRGBSpanBack(const GLcontext *ctx, GLuint n, + GLint x, GLint y, + CONST GLubyte rgb[][3], + const GLubyte mask[]) +{ + MesaDriver *md = (MesaDriver *) ctx->DriverCtx; + BBitmap *bitmap = md->m_bitmap; + + static bool already_called = false; + if (! already_called) { + printf("WriteRGBSpanBack() called.\n"); + already_called = true; + } + + assert(bitmap); + + int row = md->m_bottom - y; + uint8 * ptr = (uint8 *) bitmap->Bits() + (row * bitmap->BytesPerRow()) + x * 4; + uint32 * pixel = (uint32 *) ptr; + + if (mask) { + while(n--) { + if (*mask++) + *pixel = PACK_B_RGB32(rgb[0]); + pixel++; + rgb++; + }; + } else { + while(n--) { + *pixel++ = PACK_B_RGB32(rgb[0]); + rgb++; + }; + }; +} + + + + +void MesaDriver::WriteMonoRGBASpanBack(const GLcontext *ctx, GLuint n, + GLint x, GLint y, + const GLchan color[4], const GLubyte mask[]) +{ + MesaDriver *md = (MesaDriver *) ctx->DriverCtx; + BBitmap *bitmap = md->m_bitmap; + + static bool already_called = false; + if (! already_called) { + printf("WriteMonoRGBASpanBack() called.\n"); + already_called = true; + } + + assert(bitmap); + + int row = md->m_bottom - y; + uint8 * ptr = (uint8 *) bitmap->Bits() + (row * bitmap->BytesPerRow()) + x * 4; + uint32 * pixel = (uint32 *) ptr; + uint32 pixel_color = PACK_B_RGBA32(color); + + if (mask) { + while(n--) { + if (*mask++) + *pixel = pixel_color; + pixel++; + }; + } else { + while(n--) { + *pixel++ = pixel_color; + }; + }; +} + + +void MesaDriver::WriteRGBAPixelsBack(const GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + CONST GLubyte rgba[][4], + const GLubyte mask[] ) +{ + MesaDriver *md = (MesaDriver *) ctx->DriverCtx; + BBitmap *bitmap = md->m_bitmap; + + static bool already_called = false; + if (! already_called) { + printf("WriteRGBAPixelsBack() called.\n"); + already_called = true; + } + + assert(bitmap); +#if 0 + while(n--) { + if (*mask++) { + int row = md->m_bottom - *y; + uint8 * pixel = (uint8 *) bitmap->Bits() + (row * bitmap->BytesPerRow()) + *x * 4; + *((uint32 *) pixel) = PACK_B_RGBA32(rgba[0]); + }; + x++; + y++; + rgba++; + }; +#else + if (mask) { + for (GLuint i = 0; i < n; i++) { + if (mask[i]) { + GLubyte *pixel = (GLubyte *) bitmap->Bits() + + ((md->m_bottom - y[i]) * bitmap->BytesPerRow()) + x[i] * 4; + pixel[BE_RCOMP] = rgba[i][RCOMP]; + pixel[BE_GCOMP] = rgba[i][GCOMP]; + pixel[BE_BCOMP] = rgba[i][BCOMP]; + pixel[BE_ACOMP] = rgba[i][ACOMP]; + } + } + } + else { + for (GLuint i = 0; i < n; i++) { + GLubyte *pixel = (GLubyte *) bitmap->Bits() + + ((md->m_bottom - y[i]) * bitmap->BytesPerRow()) + x[i] * 4; + pixel[BE_RCOMP] = rgba[i][RCOMP]; + pixel[BE_GCOMP] = rgba[i][GCOMP]; + pixel[BE_BCOMP] = rgba[i][BCOMP]; + pixel[BE_ACOMP] = rgba[i][ACOMP]; + } + } +#endif +} + + +void MesaDriver::WriteMonoRGBAPixelsBack(const GLcontext *ctx, GLuint n, + const GLint x[], const GLint y[], + const GLchan color[4], + const GLubyte mask[]) +{ + MesaDriver *md = (MesaDriver *) ctx->DriverCtx; + BBitmap *bitmap = md->m_bitmap; + + static bool already_called = false; + if (! already_called) { + printf("WriteMonoRGBAPixelsBack() called.\n"); + already_called = true; + } + + assert(bitmap); + + uint32 pixel_color = PACK_B_RGBA32(color); +#if 0 + while(n--) { + if (*mask++) { + int row = md->m_bottom - *y; + uint8 * pixel = (uint8 *) bitmap->Bits() + (row * bitmap->BytesPerRow()) + *x * 4; + + *((uint32 *) pixel) = pixel_color; + }; + x++; + y++; + }; +#else + if (mask) { + for (GLuint i = 0; i < n; i++) { + if (mask[i]) { + GLubyte * ptr = (GLubyte *) bitmap->Bits() + + ((md->m_bottom - y[i]) * bitmap->BytesPerRow()) + x[i] * 4; + *((uint32 *) ptr) = pixel_color; + } + } + } + else { + for (GLuint i = 0; i < n; i++) { + GLubyte * ptr = (GLubyte *) bitmap->Bits() + + ((md->m_bottom - y[i]) * bitmap->BytesPerRow()) + x[i] * 4; + *((uint32 *) ptr) = pixel_color; + } + } +#endif +} + + +void MesaDriver::WriteCI32SpanBack( const GLcontext *ctx, GLuint n, + GLint x, GLint y, + const GLuint index[], const GLubyte mask[] ) +{ + // XXX to do +} + +void MesaDriver::WriteCI8SpanBack( const GLcontext *ctx, GLuint n, + GLint x, GLint y, + const GLubyte index[], const GLubyte mask[] ) +{ + // XXX to do +} + +void MesaDriver::WriteMonoCISpanBack( const GLcontext *ctx, GLuint n, + GLint x, GLint y, + GLuint colorIndex, const GLubyte mask[] ) +{ + // XXX to do +} + + +void MesaDriver::WriteCI32PixelsBack( const GLcontext *ctx, GLuint n, + const GLint x[], const GLint y[], + const GLuint index[], const GLubyte mask[] ) +{ + // XXX to do +} + +void MesaDriver::WriteMonoCIPixelsBack( const GLcontext *ctx, GLuint n, + const GLint x[], const GLint y[], + GLuint colorIndex, const GLubyte mask[] ) +{ + // XXX to do +} + + +void MesaDriver::ReadCI32SpanBack( const GLcontext *ctx, + GLuint n, GLint x, GLint y, GLuint index[] ) +{ + // XXX to do +} + + +void MesaDriver::ReadRGBASpanBack( const GLcontext *ctx, GLuint n, + GLint x, GLint y, GLubyte rgba[][4] ) +{ + MesaDriver *md = (MesaDriver *) ctx->DriverCtx; + const BBitmap *bitmap = md->m_bitmap; + assert(bitmap); + int row = md->m_bottom - y; + const GLubyte *pixel = (GLubyte *) bitmap->Bits() + + (row * bitmap->BytesPerRow()) + x * 4; + + for (GLuint i = 0; i < n; i++) { + rgba[i][RCOMP] = pixel[BE_RCOMP]; + rgba[i][GCOMP] = pixel[BE_GCOMP]; + rgba[i][BCOMP] = pixel[BE_BCOMP]; + rgba[i][ACOMP] = pixel[BE_ACOMP]; + pixel += 4; + } +} + + +void MesaDriver::ReadCI32PixelsBack( const GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + GLuint indx[], const GLubyte mask[] ) +{ + // XXX to do +} + + +void MesaDriver::ReadRGBAPixelsBack( const GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + GLubyte rgba[][4], const GLubyte mask[] ) +{ + MesaDriver *md = (MesaDriver *) ctx->DriverCtx; + const BBitmap *bitmap = md->m_bitmap; + assert(bitmap); + + if (mask) { + for (GLuint i = 0; i < n; i++) { + if (mask[i]) { + GLubyte *pixel = (GLubyte *) bitmap->Bits() + + ((md->m_bottom - y[i]) * bitmap->BytesPerRow()) + x[i] * 4; + rgba[i][RCOMP] = pixel[BE_RCOMP]; + rgba[i][GCOMP] = pixel[BE_GCOMP]; + rgba[i][BCOMP] = pixel[BE_BCOMP]; + rgba[i][ACOMP] = pixel[BE_ACOMP]; + }; + }; + } else { + for (GLuint i = 0; i < n; i++) { + GLubyte *pixel = (GLubyte *) bitmap->Bits() + + ((md->m_bottom - y[i]) * bitmap->BytesPerRow()) + x[i] * 4; + rgba[i][RCOMP] = pixel[BE_RCOMP]; + rgba[i][GCOMP] = pixel[BE_GCOMP]; + rgba[i][BCOMP] = pixel[BE_BCOMP]; + rgba[i][ACOMP] = pixel[BE_ACOMP]; + }; + }; +} + + + diff --git a/reactos/lib/mesa32/src/drivers/beos/GLView.h b/reactos/lib/mesa32/src/drivers/beos/GLView.h new file mode 100644 index 00000000000..595000bb56c --- /dev/null +++ b/reactos/lib/mesa32/src/drivers/beos/GLView.h @@ -0,0 +1,196 @@ +/******************************************************************************* +/ +/ File: GLView.h +/ +/ Copyright 1993-98, Be Incorporated, All Rights Reserved. +/ +*******************************************************************************/ + +#ifndef BGLVIEW_H +#define BGLVIEW_H + +// added by Brian Paul: +#ifndef BGL_RGB +#define BGL_RGB 0 +#define BGL_INDEX 1 +#define BGL_SINGLE 0 +#define BGL_DOUBLE 2 +#define BGL_DIRECT 0 +#define BGL_INDIRECT 4 +#define BGL_ACCUM 8 +#define BGL_ALPHA 16 +#define BGL_DEPTH 32 +#define BGL_OVERLAY 64 +#define BGL_UNDERLAY 128 +#define BGL_STENCIL 512 +#endif + + +#include +#include +#include +#include +#include +#include +#include + +class BGLView : public BView { +public: + + BGLView(BRect rect, char *name, + ulong resizingMode, ulong mode, + ulong options); + virtual ~BGLView(); + + void LockGL(); + void UnlockGL(); + void SwapBuffers(); + + // Added for Mesa (can't be virtual!) + void CopySubBufferMESA(GLint x, GLint y, GLuint width, GLuint height); + + BView * EmbeddedView(); + status_t CopyPixelsOut(BPoint source, BBitmap *dest); + status_t CopyPixelsIn(BBitmap *source, BPoint dest); + + virtual void ErrorCallback(unsigned long errorCode); // GLenum errorCode); + + virtual void Draw(BRect updateRect); + + virtual void AttachedToWindow(); + virtual void AllAttached(); + virtual void DetachedFromWindow(); + virtual void AllDetached(); + + virtual void FrameResized(float width, float height); + virtual status_t Perform(perform_code d, void *arg); + + /* The public methods below, for the moment, + are just pass-throughs to BView */ + + virtual status_t Archive(BMessage *data, bool deep = true) const; + + virtual void MessageReceived(BMessage *msg); + virtual void SetResizingMode(uint32 mode); + + virtual void Show(); + virtual void Hide(); + + virtual BHandler *ResolveSpecifier(BMessage *msg, int32 index, + BMessage *specifier, int32 form, + const char *property); + virtual status_t GetSupportedSuites(BMessage *data); + + /* New public functions */ + void DirectConnected( direct_buffer_info *info ); + void EnableDirectMode( bool enabled ); + +private: + + virtual void _ReservedGLView1(); + virtual void _ReservedGLView2(); + virtual void _ReservedGLView3(); + virtual void _ReservedGLView4(); + virtual void _ReservedGLView5(); + virtual void _ReservedGLView6(); + virtual void _ReservedGLView7(); + virtual void _ReservedGLView8(); + + BGLView(const BGLView &); + BGLView &operator=(const BGLView &); + + void dither_front(); + bool confirm_dither(); + void draw(BRect r); + + void * m_gc; + uint32 m_options; + uint32 m_ditherCount; + BLocker m_drawLock; + BLocker m_displayLock; +#if OLD_GLVIEW + BView * m_embeddedFront; + BView * m_embeddedBack; +#else + void * m_clip_info; + void * _reserved1; +#endif + BBitmap * m_ditherMap; + BRect m_bounds; + int16 * m_errorBuffer[2]; + uint64 _reserved[8]; + + /* Direct Window stuff */ +private: + void drawScanline( int x1, int x2, int y, void *data ); + static void scanlineHandler(struct rasStateRec *state, GLint x1, GLint x2); + void lock_draw(); + void unlock_draw(); + bool validateView(); +}; + + + +class BGLScreen : public BWindowScreen { +public: + BGLScreen(char *name, + ulong screenMode, ulong options, + status_t *error, bool debug=false); + ~BGLScreen(); + + void LockGL(); + void UnlockGL(); + void SwapBuffers(); + virtual void ErrorCallback(GLenum errorCode); + + virtual void ScreenConnected(bool connected); + virtual void FrameResized(float width, float height); + virtual status_t Perform(perform_code d, void *arg); + + /* The public methods below, for the moment, + are just pass-throughs to BWindowScreen */ + + virtual status_t Archive(BMessage *data, bool deep = true) const; + virtual void MessageReceived(BMessage *msg); + + virtual void Show(); + virtual void Hide(); + + virtual BHandler *ResolveSpecifier(BMessage *msg, + int32 index, + BMessage *specifier, + int32 form, + const char *property); + virtual status_t GetSupportedSuites(BMessage *data); + +private: + + virtual void _ReservedGLScreen1(); + virtual void _ReservedGLScreen2(); + virtual void _ReservedGLScreen3(); + virtual void _ReservedGLScreen4(); + virtual void _ReservedGLScreen5(); + virtual void _ReservedGLScreen6(); + virtual void _ReservedGLScreen7(); + virtual void _ReservedGLScreen8(); + + BGLScreen(const BGLScreen &); + BGLScreen &operator=(const BGLScreen &); + + void * m_gc; + long m_options; + BLocker m_drawLock; + + int32 m_colorSpace; + uint32 m_screen_mode; + + uint64 _reserved[7]; +}; + + +#endif + + + + + diff --git a/reactos/lib/mesa32/src/drivers/common/t_dd.c b/reactos/lib/mesa32/src/drivers/common/t_dd.c new file mode 100644 index 00000000000..731da5c320d --- /dev/null +++ b/reactos/lib/mesa32/src/drivers/common/t_dd.c @@ -0,0 +1,58 @@ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * 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 + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Keith Whitwell + */ + +static void copy_pv_rgba4_spec5( GLcontext *ctx, GLuint edst, GLuint esrc ) +{ + i810ContextPtr imesa = I810_CONTEXT( ctx ); + GLubyte *i810verts = (GLubyte *)imesa->verts; + GLuint shift = imesa->vertex_stride_shift; + i810Vertex *dst = (i810Vertex *)(i810verts + (edst << shift)); + i810Vertex *src = (i810Vertex *)(i810verts + (esrc << shift)); + dst->ui[4] = src->ui[4]; + dst->ui[5] = src->ui[5]; +} + +static void copy_pv_rgba4( GLcontext *ctx, GLuint edst, GLuint esrc ) +{ + i810ContextPtr imesa = I810_CONTEXT( ctx ); + GLubyte *i810verts = (GLubyte *)imesa->verts; + GLuint shift = imesa->vertex_stride_shift; + i810Vertex *dst = (i810Vertex *)(i810verts + (edst << shift)); + i810Vertex *src = (i810Vertex *)(i810verts + (esrc << shift)); + dst->ui[4] = src->ui[4]; +} + +static void copy_pv_rgba3( GLcontext *ctx, GLuint edst, GLuint esrc ) +{ + i810ContextPtr imesa = I810_CONTEXT( ctx ); + GLubyte *i810verts = (GLubyte *)imesa->verts; + GLuint shift = imesa->vertex_stride_shift; + i810Vertex *dst = (i810Vertex *)(i810verts + (edst << shift)); + i810Vertex *src = (i810Vertex *)(i810verts + (esrc << shift)); + dst->ui[3] = src->ui[3]; +} diff --git a/reactos/lib/mesa32/src/drivers/common/t_dd_dmatmp.h b/reactos/lib/mesa32/src/drivers/common/t_dd_dmatmp.h new file mode 100644 index 00000000000..10ff1df5f0b --- /dev/null +++ b/reactos/lib/mesa32/src/drivers/common/t_dd_dmatmp.h @@ -0,0 +1,1093 @@ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * 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 + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Keith Whitwell + */ + + +/* Template for render stages which build and emit vertices directly + * to fixed-size dma buffers. Useful for rendering strips and other + * native primitives where clipping and per-vertex tweaks such as + * those in t_dd_tritmp.h are not required. + * + * Produces code for both inline triangles and indexed triangles. + * Where various primitive types are unaccelerated by hardware, the + * code attempts to fallback to other primitive types (quadstrips to + * tristrips, lineloops to linestrips), or to indexed vertices. + * Ultimately, a FALLBACK() macro is invoked if there is no way to + * render the primitive natively. + */ + +#if !defined(HAVE_TRIANGLES) +#error "must have at least triangles to use render template" +#endif + +#if !HAVE_ELTS +#define ELTS_VARS +#define ALLOC_ELTS( nr ) +#define EMIT_ELT( offset, elt ) +#define EMIT_TWO_ELTS( offset, elt0, elt1 ) +#define INCR_ELTS( nr ) +#define ELT_INIT(prim) +#define GET_CURRENT_VB_MAX_ELTS() 0 +#define GET_SUBSEQUENT_VB_MAX_ELTS() 0 +#define ALLOC_ELTS_NEW_PRIMITIVE(nr) +#define RELEASE_ELT_VERTS() +#define EMIT_INDEXED_VERTS( ctx, start, count ) +#endif + +#ifndef EMIT_TWO_ELTS +#define EMIT_TWO_ELTS( offset, elt0, elt1 ) \ +do { \ + EMIT_ELT( offset, elt0 ); \ + EMIT_ELT( offset+1, elt1 ); \ +} while (0) +#endif + +#ifndef FINISH +#define FINISH +#endif + +/**********************************************************************/ +/* Render whole begin/end objects */ +/**********************************************************************/ + + + +static GLboolean TAG(emit_elt_verts)( GLcontext *ctx, + GLuint start, GLuint count ) +{ + if (HAVE_ELTS) { + LOCAL_VARS; + GLuint nr = count - start; + + if ( nr >= GET_SUBSEQUENT_VB_MAX_VERTS() ) /* assumes same packing for + * indexed and regualar verts + */ + return GL_FALSE; + + NEW_PRIMITIVE(); /* finish last prim */ + EMIT_INDEXED_VERTS( ctx, start, count ); + return GL_TRUE; + } else { + return GL_FALSE; + } +} + +#if (HAVE_ELTS) +static void TAG(emit_elts)( GLcontext *ctx, GLuint *elts, GLuint nr ) +{ + GLint i; + LOCAL_VARS; + ELTS_VARS; + + ALLOC_ELTS( nr ); + + for ( i = 0 ; i < nr ; i+=2, elts += 2 ) { + EMIT_TWO_ELTS( 0, elts[0], elts[1] ); + INCR_ELTS( 2 ); + } +} +#endif + + +/*********************************************************************** + * Render non-indexed primitives. + ***********************************************************************/ + + + +static void TAG(render_points_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (HAVE_POINTS) { + LOCAL_VARS; + int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS(); + int currentsz = GET_CURRENT_VB_MAX_VERTS(); + GLuint j, nr; + + INIT( GL_POINTS ); + + if (currentsz < 8) + currentsz = dmasz; + + for (j = start; j < count; j += nr ) { + nr = MIN2( currentsz, count - j ); + EMIT_VERTS( ctx, j, nr ); + currentsz = dmasz; + } + + FINISH; + + } else { + VERT_FALLBACK( ctx, start, count, flags ); + } +} + +static void TAG(render_lines_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (HAVE_LINES) { + LOCAL_VARS; + int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS(); + int currentsz = GET_CURRENT_VB_MAX_VERTS(); + GLuint j, nr; + + INIT( GL_LINES ); + + /* Emit whole number of lines in total and in each buffer: + */ + count -= (count-start) & 1; + currentsz -= currentsz & 1; + dmasz -= dmasz & 1; + + if (currentsz < 8) + currentsz = dmasz; + + for (j = start; j < count; j += nr ) { + nr = MIN2( currentsz, count - j ); + EMIT_VERTS( ctx, j, nr ); + currentsz = dmasz; + } + + FINISH; + + } else { + VERT_FALLBACK( ctx, start, count, flags ); + } +} + + +static void TAG(render_line_strip_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (HAVE_LINE_STRIPS) { + LOCAL_VARS; + int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS(); + int currentsz = GET_CURRENT_VB_MAX_VERTS(); + GLuint j, nr; + + NEW_PRIMITIVE(); /* always a new primitive */ + INIT( GL_LINE_STRIP ); + + if (currentsz < 8) + currentsz = dmasz; + + for (j = start; j + 1 < count; j += nr - 1 ) { + nr = MIN2( currentsz, count - j ); + EMIT_VERTS( ctx, j, nr ); + currentsz = dmasz; + } + + FINISH; + + } else { + VERT_FALLBACK( ctx, start, count, flags ); + } +} + + +static void TAG(render_line_loop_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (HAVE_LINE_STRIPS) { + LOCAL_VARS; + int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS(); + int currentsz = GET_CURRENT_VB_MAX_VERTS(); + GLuint j, nr; + + NEW_PRIMITIVE(); + INIT( GL_LINE_STRIP ); + + if (flags & PRIM_BEGIN) + j = start; + else + j = start + 1; + + /* Ensure last vertex won't wrap buffers: + */ + currentsz--; + dmasz--; + + if (currentsz < 8) { + NEW_BUFFER(); + currentsz = dmasz; + } + + if (j + 1 < count) { + for ( ; j + 1 < count; j += nr - 1 ) { + nr = MIN2( currentsz, count - j ); + EMIT_VERTS( ctx, j, nr ); + currentsz = dmasz; + } + + if (start < count - 1 && (flags & PRIM_END)) + EMIT_VERTS( ctx, start, 1 ); + } + else if (start + 1 < count && (flags & PRIM_END)) { + EMIT_VERTS( ctx, start+1, 1 ); + EMIT_VERTS( ctx, start, 1 ); + } + + FINISH; + + } else { + VERT_FALLBACK( ctx, start, count, flags ); + } +} + + +static void TAG(render_triangles_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + int dmasz = (GET_SUBSEQUENT_VB_MAX_VERTS()/3) * 3; + int currentsz = (GET_CURRENT_VB_MAX_VERTS()/3) * 3; + GLuint j, nr; + + INIT(GL_TRIANGLES); + + /* Emit whole number of tris in total. dmasz is already a multiple + * of 3. + */ + count -= (count-start)%3; + + if (currentsz < 8) + currentsz = dmasz; + + for (j = start; j < count; j += nr) { + nr = MIN2( currentsz, count - j ); + EMIT_VERTS( ctx, j, nr ); + currentsz = dmasz; + } + FINISH; +} + + + +static void TAG(render_tri_strip_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (HAVE_TRI_STRIPS) { + LOCAL_VARS; + GLuint j, nr; + int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS(); + int currentsz; + + INIT(GL_TRIANGLE_STRIP); + NEW_PRIMITIVE(); + + currentsz = GET_CURRENT_VB_MAX_VERTS(); + + if (currentsz < 8) { + NEW_BUFFER(); + currentsz = dmasz; + } + + /* From here on emit even numbers of tris when wrapping over buffers: + */ + dmasz -= (dmasz & 1); + currentsz -= (currentsz & 1); + + for (j = start ; j + 2 < count; j += nr - 2 ) { + nr = MIN2( currentsz, count - j ); + EMIT_VERTS( ctx, j, nr ); + currentsz = dmasz; + } + + FINISH; + + } else { + VERT_FALLBACK( ctx, start, count, flags ); + } +} + +static void TAG(render_tri_fan_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (HAVE_TRI_FANS) { + LOCAL_VARS; + GLuint j, nr; + int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS(); + int currentsz = GET_CURRENT_VB_MAX_VERTS(); + + NEW_PRIMITIVE(); + INIT(GL_TRIANGLE_FAN); + + if (currentsz < 8) { + NEW_BUFFER(); + currentsz = dmasz; + } + + for (j = start + 1 ; j + 1 < count; j += nr - 1 ) { + nr = MIN2( currentsz, count - j + 1 ); + EMIT_VERTS( ctx, start, 1 ); + EMIT_VERTS( ctx, j, nr - 1 ); + currentsz = dmasz; + } + + FINISH; + + } + else { + /* Could write code to emit these as indexed vertices (for the + * g400, for instance). + */ + VERT_FALLBACK( ctx, start, count, flags ); + } +} + + +static void TAG(render_poly_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (HAVE_POLYGONS) { + LOCAL_VARS; + GLuint j, nr; + int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS(); + int currentsz = GET_CURRENT_VB_MAX_VERTS(); + + NEW_PRIMITIVE(); + INIT(GL_POLYGON); + + if (currentsz < 8) { + NEW_BUFFER(); + currentsz = dmasz; + } + + for (j = start + 1 ; j + 1 < count ; j += nr - 1 ) { + nr = MIN2( currentsz, count - j + 1 ); + EMIT_VERTS( ctx, start, 1 ); + EMIT_VERTS( ctx, j, nr - 1 ); + currentsz = dmasz; + } + + FINISH; + + } + else if (HAVE_TRI_FANS && !(ctx->_TriangleCaps & DD_FLATSHADE)) { + TAG(render_tri_fan_verts)( ctx, start, count, flags ); + } else { + VERT_FALLBACK( ctx, start, count, flags ); + } +} + +static void TAG(render_quad_strip_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + GLuint j, nr; + + if (HAVE_QUAD_STRIPS) { + LOCAL_VARS; + GLuint j, nr; + int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS(); + int currentsz; + + INIT(GL_QUAD_STRIP); + NEW_PRIMITIVE(); + + currentsz = GET_CURRENT_VB_MAX_VERTS(); + + if (currentsz < 8) { + NEW_BUFFER(); + currentsz = dmasz; + } + + dmasz -= (dmasz & 2); + currentsz -= (currentsz & 2); + + for (j = start ; j + 3 < count; j += nr - 2 ) { + nr = MIN2( currentsz, count - j ); + EMIT_VERTS( ctx, j, nr ); + currentsz = dmasz; + } + + FINISH; + + } else if (HAVE_TRI_STRIPS && (ctx->_TriangleCaps & DD_FLATSHADE)) { + if (TAG(emit_elt_verts)( ctx, start, count )) { + LOCAL_VARS; + int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); + int currentsz; + GLuint j, nr; + + /* Simulate flat-shaded quadstrips using indexed vertices: + */ + NEW_PRIMITIVE(); + ELT_INIT( GL_TRIANGLES ); + + currentsz = GET_CURRENT_VB_MAX_ELTS(); + + /* Emit whole number of quads in total, and in each buffer. + */ + dmasz -= dmasz & 1; + count -= (count-start) & 1; + currentsz -= currentsz & 1; + + if (currentsz < 12) + currentsz = dmasz; + + currentsz = currentsz/6*2; + dmasz = dmasz/6*2; + + for (j = start; j + 3 < count; j += nr - 2 ) { + nr = MIN2( currentsz, count - j ); + if (nr >= 4) { + GLint quads = (nr/2)-1; + GLint i; + ELTS_VARS; + + NEW_PRIMITIVE(); + ALLOC_ELTS_NEW_PRIMITIVE( quads*6 ); + + for ( i = j-start ; i < j-start+quads*2 ; i+=2 ) { + EMIT_TWO_ELTS( 0, (i+0), (i+1) ); + EMIT_TWO_ELTS( 2, (i+2), (i+1) ); + EMIT_TWO_ELTS( 4, (i+3), (i+2) ); + INCR_ELTS( 6 ); + } + + NEW_PRIMITIVE(); + } + currentsz = dmasz; + } + + RELEASE_ELT_VERTS(); + } + else { + /* Vertices won't fit in a single buffer or elts not available, + * VERT_FALLBACK. + */ + VERT_FALLBACK( ctx, start, count, flags ); + } + } + else if (HAVE_TRI_STRIPS) { + LOCAL_VARS; + int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS(); + int currentsz = GET_CURRENT_VB_MAX_VERTS(); + + /* Emit smooth-shaded quadstrips as tristrips: + */ + NEW_PRIMITIVE(); + INIT( GL_TRIANGLE_STRIP ); + + /* Emit whole number of quads in total, and in each buffer. + */ + dmasz -= dmasz & 1; + currentsz -= currentsz & 1; + count -= (count-start) & 1; + + if (currentsz < 8) { + NEW_BUFFER(); + currentsz = dmasz; + } + + for (j = start; j + 3 < count; j += nr - 2 ) { + nr = MIN2( currentsz, count - j ); + EMIT_VERTS( ctx, j, nr ); + currentsz = dmasz; + } + + FINISH; + + } else { + VERT_FALLBACK( ctx, start, count, flags ); + } +} + + +static void TAG(render_quads_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (HAVE_QUADS) { + LOCAL_VARS; + int dmasz = (GET_SUBSEQUENT_VB_MAX_VERTS()/4) * 4; + int currentsz = (GET_CURRENT_VB_MAX_VERTS()/4) * 4; + GLuint j, nr; + + INIT(GL_QUADS); + + /* Emit whole number of quads in total. dmasz is already a multiple + * of 4. + */ + count -= (count-start)%4; + + if (currentsz < 8) + currentsz = dmasz; + + for (j = start; j < count; j += nr) { + nr = MIN2( currentsz, count - j ); + EMIT_VERTS( ctx, j, nr ); + currentsz = dmasz; + } + FINISH; + } else if (TAG(emit_elt_verts)( ctx, start, count )) { + /* Hardware doesn't have a quad primitive type -- try to + * simulate it using indexed vertices and the triangle + * primitive: + */ + LOCAL_VARS; + int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); + int currentsz; + GLuint j, nr; + + NEW_PRIMITIVE(); + ELT_INIT( GL_TRIANGLES ); + currentsz = GET_CURRENT_VB_MAX_ELTS(); + + /* Emit whole number of quads in total, and in each buffer. + */ + dmasz -= dmasz & 3; + count -= (count-start) & 3; + currentsz -= currentsz & 3; + + /* Adjust for rendering as triangles: + */ + currentsz = currentsz/6*4; + dmasz = dmasz/6*4; + + if (currentsz < 8) + currentsz = dmasz; + + for (j = start; j < count; j += nr ) { + nr = MIN2( currentsz, count - j ); + if (nr >= 4) { + GLint quads = nr/4; + GLint i; + ELTS_VARS; + + NEW_PRIMITIVE(); + ALLOC_ELTS_NEW_PRIMITIVE( quads*6 ); + + for ( i = j-start ; i < j-start+quads*4 ; i+=4 ) { + EMIT_TWO_ELTS( 0, (i+0), (i+1) ); + EMIT_TWO_ELTS( 2, (i+3), (i+1) ); + EMIT_TWO_ELTS( 4, (i+2), (i+3) ); + INCR_ELTS( 6 ); + } + + NEW_PRIMITIVE(); + } + currentsz = dmasz; + } + + RELEASE_ELT_VERTS(); + } + else { + /* Vertices won't fit in a single buffer, fallback. + */ + VERT_FALLBACK( ctx, start, count, flags ); + } +} + +static void TAG(render_noop)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ +} + + + + +static render_func TAG(render_tab_verts)[GL_POLYGON+2] = +{ + TAG(render_points_verts), + TAG(render_lines_verts), + TAG(render_line_loop_verts), + TAG(render_line_strip_verts), + TAG(render_triangles_verts), + TAG(render_tri_strip_verts), + TAG(render_tri_fan_verts), + TAG(render_quads_verts), + TAG(render_quad_strip_verts), + TAG(render_poly_verts), + TAG(render_noop), +}; + + +/**************************************************************************** + * Render elts using hardware indexed verts * + ****************************************************************************/ + +#if (HAVE_ELTS) +static void TAG(render_points_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (HAVE_POINTS) { + LOCAL_VARS; + int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); + int currentsz; + GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts; + GLuint j, nr; + + ELT_INIT( GL_POINTS ); + + currentsz = GET_CURRENT_VB_MAX_ELTS(); + if (currentsz < 8) + currentsz = dmasz; + + for (j = start; j < count; j += nr ) { + nr = MIN2( currentsz, count - j ); + TAG(emit_elts)( ctx, elts+j, nr ); + NEW_PRIMITIVE(); + currentsz = dmasz; + } + } else { + ELT_FALLBACK( ctx, start, count, flags ); + } +} + + + +static void TAG(render_lines_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (HAVE_LINES) { + LOCAL_VARS; + int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); + int currentsz; + GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts; + GLuint j, nr; + + ELT_INIT( GL_LINES ); + + /* Emit whole number of lines in total and in each buffer: + */ + count -= (count-start) & 1; + currentsz -= currentsz & 1; + dmasz -= dmasz & 1; + + currentsz = GET_CURRENT_VB_MAX_ELTS(); + if (currentsz < 8) + currentsz = dmasz; + + for (j = start; j < count; j += nr ) { + nr = MIN2( currentsz, count - j ); + TAG(emit_elts)( ctx, elts+j, nr ); + NEW_PRIMITIVE(); + currentsz = dmasz; + } + } else { + ELT_FALLBACK( ctx, start, count, flags ); + } +} + + +static void TAG(render_line_strip_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (HAVE_LINE_STRIPS) { + LOCAL_VARS; + int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); + int currentsz; + GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts; + GLuint j, nr; + + NEW_PRIMITIVE(); /* always a new primitive */ + ELT_INIT( GL_LINE_STRIP ); + + currentsz = GET_CURRENT_VB_MAX_ELTS(); + if (currentsz < 8) + currentsz = dmasz; + + for (j = start; j + 1 < count; j += nr - 1 ) { + nr = MIN2( currentsz, count - j ); + TAG(emit_elts)( ctx, elts+j, nr ); + NEW_PRIMITIVE(); + currentsz = dmasz; + } + } else { + /* TODO: Try to emit as indexed lines. + */ + ELT_FALLBACK( ctx, start, count, flags ); + } +} + + +static void TAG(render_line_loop_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (HAVE_LINE_STRIPS) { + LOCAL_VARS; + int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); + int currentsz; + GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts; + GLuint j, nr; + + NEW_PRIMITIVE(); + ELT_INIT( GL_LINE_STRIP ); + + if (flags & PRIM_BEGIN) + j = start; + else + j = start + 1; + + currentsz = GET_CURRENT_VB_MAX_ELTS(); + if (currentsz < 8) { + NEW_BUFFER(); + currentsz = dmasz; + } + + /* Ensure last vertex doesn't wrap: + */ + currentsz--; + dmasz--; + + for ( ; j + 1 < count; j += nr - 1 ) { + nr = MIN2( currentsz, count - j ); +/* NEW_PRIMITIVE(); */ + TAG(emit_elts)( ctx, elts+j, nr ); + currentsz = dmasz; + } + + if (flags & PRIM_END) + TAG(emit_elts)( ctx, elts+start, 1 ); + + NEW_PRIMITIVE(); + } else { + /* TODO: Try to emit as indexed lines */ + ELT_FALLBACK( ctx, start, count, flags ); + } +} + + +/* For verts, we still eliminate the copy from main memory to dma + * buffers. For elts, this is probably no better (worse?) than the + * standard path. + */ +static void TAG(render_triangles_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts; + int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS()/3*3; + int currentsz; + GLuint j, nr; + + NEW_PRIMITIVE(); + ELT_INIT( GL_TRIANGLES ); + + currentsz = GET_CURRENT_VB_MAX_ELTS(); + + /* Emit whole number of tris in total. dmasz is already a multiple + * of 3. + */ + count -= (count-start)%3; + currentsz -= currentsz%3; + if (currentsz < 8) + currentsz = dmasz; + + for (j = start; j < count; j += nr) { + nr = MIN2( currentsz, count - j ); + TAG(emit_elts)( ctx, elts+j, nr ); + NEW_PRIMITIVE(); + currentsz = dmasz; + } +} + + + +static void TAG(render_tri_strip_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (HAVE_TRI_STRIPS) { + LOCAL_VARS; + GLuint j, nr; + GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts; + int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); + int currentsz; + + NEW_PRIMITIVE(); + ELT_INIT( GL_TRIANGLE_STRIP ); + + currentsz = GET_CURRENT_VB_MAX_ELTS(); + if (currentsz < 8) { + NEW_BUFFER(); + currentsz = dmasz; + } + + /* Keep the same winding over multiple buffers: + */ + dmasz -= (dmasz & 1); + currentsz -= (currentsz & 1); + + for (j = start ; j + 2 < count; j += nr - 2 ) { + nr = MIN2( currentsz, count - j ); + TAG(emit_elts)( ctx, elts+j, nr ); + NEW_PRIMITIVE(); + currentsz = dmasz; + } + } else { + /* TODO: try to emit as indexed triangles */ + ELT_FALLBACK( ctx, start, count, flags ); + } +} + +static void TAG(render_tri_fan_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (HAVE_TRI_FANS) { + LOCAL_VARS; + GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts; + GLuint j, nr; + int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); + int currentsz; + + NEW_PRIMITIVE(); + ELT_INIT( GL_TRIANGLE_FAN ); + + currentsz = GET_CURRENT_VB_MAX_ELTS(); + if (currentsz < 8) { + NEW_BUFFER(); + currentsz = dmasz; + } + + for (j = start + 1 ; j + 1 < count; j += nr - 1 ) { + nr = MIN2( currentsz, count - j + 1 ); + TAG(emit_elts)( ctx, elts+start, 1 ); + TAG(emit_elts)( ctx, elts+j, nr - 1 ); + NEW_PRIMITIVE(); + currentsz = dmasz; + } + } else { + /* TODO: try to emit as indexed triangles */ + ELT_FALLBACK( ctx, start, count, flags ); + } +} + + +static void TAG(render_poly_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (HAVE_POLYGONS && 0) { + } else if (HAVE_TRI_FANS && !(ctx->_TriangleCaps & DD_FLATSHADE)) { + LOCAL_VARS; + GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts; + GLuint j, nr; + int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); + int currentsz; + + NEW_PRIMITIVE(); + ELT_INIT( GL_TRIANGLE_FAN ); + + currentsz = GET_CURRENT_VB_MAX_ELTS(); + if (currentsz < 8) { + NEW_BUFFER(); + currentsz = dmasz; + } + + for (j = start + 1 ; j + 1 < count ; j += nr - 1 ) { + nr = MIN2( currentsz, count - j + 1 ); + TAG(emit_elts)( ctx, elts+start, 1 ); + TAG(emit_elts)( ctx, elts+j, nr - 1 ); + NEW_PRIMITIVE(); + currentsz = dmasz; + } + } else { + ELT_FALLBACK( ctx, start, count, flags ); + } +} + +static void TAG(render_quad_strip_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (HAVE_QUAD_STRIPS && 0) { + } + else if (HAVE_TRI_STRIPS) { + LOCAL_VARS; + GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts; + int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); + int currentsz; + GLuint j, nr; + + NEW_PRIMITIVE(); + currentsz = GET_CURRENT_VB_MAX_ELTS(); + + /* Emit whole number of quads in total, and in each buffer. + */ + dmasz -= dmasz & 1; + count -= (count-start) & 1; + currentsz -= currentsz & 1; + + if (currentsz < 12) + currentsz = dmasz; + + if (ctx->_TriangleCaps & DD_FLATSHADE) { + ELT_INIT( GL_TRIANGLES ); + + currentsz = currentsz/6*2; + dmasz = dmasz/6*2; + + for (j = start; j + 3 < count; j += nr - 2 ) { + nr = MIN2( currentsz, count - j ); + + if (nr >= 4) + { + GLint i; + GLint quads = (nr/2)-1; + ELTS_VARS; + + + NEW_PRIMITIVE(); + ALLOC_ELTS_NEW_PRIMITIVE( quads*6 ); + + for ( i = j-start ; i < j-start+quads ; i++, elts += 2 ) { + EMIT_TWO_ELTS( 0, elts[0], elts[1] ); + EMIT_TWO_ELTS( 2, elts[2], elts[1] ); + EMIT_TWO_ELTS( 4, elts[3], elts[2] ); + INCR_ELTS( 6 ); + } + + NEW_PRIMITIVE(); + } + + currentsz = dmasz; + } + } + else { + ELT_INIT( GL_TRIANGLE_STRIP ); + + for (j = start; j + 3 < count; j += nr - 2 ) { + nr = MIN2( currentsz, count - j ); + TAG(emit_elts)( ctx, elts+j, nr ); + NEW_PRIMITIVE(); + currentsz = dmasz; + } + } + } +} + + +static void TAG(render_quads_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (HAVE_QUADS && 0) { + } else { + LOCAL_VARS; + GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts; + int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); + int currentsz; + GLuint j, nr; + + ELT_INIT( GL_TRIANGLES ); + currentsz = GET_CURRENT_VB_MAX_ELTS(); + + /* Emit whole number of quads in total, and in each buffer. + */ + dmasz -= dmasz & 3; + count -= (count-start) & 3; + currentsz -= currentsz & 3; + + /* Adjust for rendering as triangles: + */ + currentsz = currentsz/6*4; + dmasz = dmasz/6*4; + + if (currentsz < 8) + currentsz = dmasz; + + for (j = start; j + 3 < count; j += nr - 2 ) { + nr = MIN2( currentsz, count - j ); + + if (nr >= 4) + { + GLint quads = nr/4; + GLint i; + ELTS_VARS; + NEW_PRIMITIVE(); + ALLOC_ELTS_NEW_PRIMITIVE( quads * 6 ); + + for ( i = j-start ; i < j-start+quads ; i++, elts += 4 ) { + EMIT_TWO_ELTS( 0, elts[0], elts[1] ); + EMIT_TWO_ELTS( 2, elts[3], elts[1] ); + EMIT_TWO_ELTS( 4, elts[2], elts[3] ); + INCR_ELTS( 6 ); + } + } + + NEW_PRIMITIVE(); + currentsz = dmasz; + } + } +} + + + +static render_func TAG(render_tab_elts)[GL_POLYGON+2] = +{ + TAG(render_points_elts), + TAG(render_lines_elts), + TAG(render_line_loop_elts), + TAG(render_line_strip_elts), + TAG(render_triangles_elts), + TAG(render_tri_strip_elts), + TAG(render_tri_fan_elts), + TAG(render_quads_elts), + TAG(render_quad_strip_elts), + TAG(render_poly_elts), + TAG(render_noop), +}; +#endif diff --git a/reactos/lib/mesa32/src/drivers/common/t_dd_dmatmp2.h b/reactos/lib/mesa32/src/drivers/common/t_dd_dmatmp2.h new file mode 100644 index 00000000000..dd0286b453b --- /dev/null +++ b/reactos/lib/mesa32/src/drivers/common/t_dd_dmatmp2.h @@ -0,0 +1,935 @@ + +/* + * Mesa 3-D graphics library + * Version: 4.0.3 + * + * 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 + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Keith Whitwell + */ + + +/* Template for render stages which build and emit vertices directly + * to fixed-size dma buffers. Useful for rendering strips and other + * native primitives where clipping and per-vertex tweaks such as + * those in t_dd_tritmp.h are not required. + * + */ + +#if !HAVE_TRIANGLES || !HAVE_POINTS || !HAVE_LINES +#error "must have points, lines & triangles to use render template" +#endif + +#if !HAVE_TRI_STRIPS || !HAVE_TRI_FANS +#error "must have tri strip and fans to use render template" +#endif + +#if !HAVE_LINE_STRIPS +#error "must have line strips to use render template" +#endif + +#if !HAVE_POLYGONS +#error "must have polygons to use render template" +#endif + +#if !HAVE_ELTS +#error "must have elts to use render template" +#endif + + +#ifndef EMIT_TWO_ELTS +#define EMIT_TWO_ELTS( dest, offset, elt0, elt1 ) \ +do { \ + (dest)[offset] = (elt0); \ + (dest)[offset+1] = (elt1); \ +} while (0) +#endif + + +/**********************************************************************/ +/* Render whole begin/end objects */ +/**********************************************************************/ + + +static ELT_TYPE *TAG(emit_elts)( GLcontext *ctx, + ELT_TYPE *dest, + GLuint *elts, GLuint nr ) +{ + GLint i; + LOCAL_VARS; + + for ( i = 0 ; i+1 < nr ; i+=2, elts += 2 ) { + EMIT_TWO_ELTS( dest, 0, elts[0], elts[1] ); + dest += 2; + } + if (i < nr) { + EMIT_ELT( dest, 0, elts[0] ); + dest += 1; + } + + return dest; +} + +static ELT_TYPE *TAG(emit_consecutive_elts)( GLcontext *ctx, + ELT_TYPE *dest, + GLuint start, GLuint nr ) +{ + GLint i; + LOCAL_VARS; + + for ( i = 0 ; i+1 < nr ; i+=2, start += 2 ) { + EMIT_TWO_ELTS( dest, 0, start, start+1 ); + dest += 2; + } + if (i < nr) { + EMIT_ELT( dest, 0, start ); + dest += 1; + } + + return dest; +} + +/*********************************************************************** + * Render non-indexed primitives. + ***********************************************************************/ + + + +static void TAG(render_points_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (start < count) { + LOCAL_VARS; + if (0) fprintf(stderr, "%s\n", __FUNCTION__); + EMIT_PRIM( ctx, GL_POINTS, HW_POINTS, start, count ); + } +} + +static void TAG(render_lines_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + if (0) fprintf(stderr, "%s\n", __FUNCTION__); + count -= (count-start) & 1; + + if (start+1 >= count) + return; + + if ((flags & PRIM_BEGIN) && ctx->Line.StippleFlag) { + RESET_STIPPLE(); + AUTO_STIPPLE( GL_TRUE ); + } + + EMIT_PRIM( ctx, GL_LINES, HW_LINES, start, count ); + + if ((flags & PRIM_END) && ctx->Line.StippleFlag) + AUTO_STIPPLE( GL_FALSE ); +} + + +static void TAG(render_line_strip_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + if (0) fprintf(stderr, "%s\n", __FUNCTION__); + + if (start+1 >= count) + return; + + if ((flags & PRIM_BEGIN) && ctx->Line.StippleFlag) + RESET_STIPPLE(); + + + if (PREFER_DISCRETE_ELT_PRIM( count-start, HW_LINES )) + { + int dmasz = GET_MAX_HW_ELTS(); + GLuint j, nr; + + ELT_INIT( GL_LINES, HW_LINES ); + + /* Emit whole number of lines in each full buffer. + */ + dmasz = dmasz/2; + + + for (j = start; j + 1 < count; j += nr - 1 ) { + ELT_TYPE *dest; + GLint i; + + nr = MIN2( dmasz, count - j ); + dest = ALLOC_ELTS( (nr-1)*2 ); + + for ( i = j ; i+1 < j+nr ; i+=1 ) { + EMIT_TWO_ELTS( dest, 0, (i+0), (i+1) ); + dest += 2; + } + + CLOSE_ELTS(); + } + } + else + EMIT_PRIM( ctx, GL_LINE_STRIP, HW_LINE_STRIP, start, count ); +} + + +static void TAG(render_line_loop_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + GLuint j, nr; + if (0) fprintf(stderr, "%s\n", __FUNCTION__); + + if (flags & PRIM_BEGIN) { + j = start; + if (ctx->Line.StippleFlag) + RESET_STIPPLE( ); + } + else + j = start + 1; + + if (flags & PRIM_END) { + + if (start+1 >= count) + return; + + if (PREFER_DISCRETE_ELT_PRIM( count-start, HW_LINES )) { + int dmasz = GET_MAX_HW_ELTS(); + + ELT_INIT( GL_LINES, HW_LINES ); + + /* Emit whole number of lines in each full buffer. + */ + dmasz = dmasz/2; + + /* Ensure last vertex doesn't wrap: + */ + dmasz--; + + for (; j + 1 < count; ) { + GLint i; + ELT_TYPE *dest; + + nr = MIN2( dmasz, count - j ); + dest = ALLOC_ELTS( nr*2 ); /* allocs room for 1 more line */ + + for ( i = 0 ; i < nr - 1 ; i+=1 ) { + EMIT_TWO_ELTS( dest, 0, (j+i), (j+i+1) ); + dest += 2; + } + + j += nr - 1; + + /* Emit 1 more line into space alloced above */ + if (j + 1 >= count) { + EMIT_TWO_ELTS( dest, 0, (j), (start) ); + dest += 2; + } + + CLOSE_ELTS(); + } + } + else + { + int dmasz = GET_MAX_HW_ELTS() - 1; + + ELT_INIT( GL_LINE_STRIP, HW_LINE_STRIP ); + + for ( ; j + 1 < count; ) { + nr = MIN2( dmasz, count - j ); + if (j + nr < count) { + ELT_TYPE *dest = ALLOC_ELTS( nr ); + dest = TAG(emit_consecutive_elts)( ctx, dest, j, nr ); + j += nr - 1; + CLOSE_ELTS(); + } + else if (nr) { + ELT_TYPE *dest = ALLOC_ELTS( nr + 1 ); + dest = TAG(emit_consecutive_elts)( ctx, dest, j, nr ); + dest = TAG(emit_consecutive_elts)( ctx, dest, start, 1 ); + j += nr; + CLOSE_ELTS(); + } + } + } + } else { + TAG(render_line_strip_verts)( ctx, j, count, flags ); + } +} + + +static void TAG(render_triangles_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + if (0) fprintf(stderr, "%s\n", __FUNCTION__); + + count -= (count-start)%3; + + if (start+2 >= count) { + return; + } + + /* need a PREFER_DISCRETE_ELT_PRIM here too.. + */ + EMIT_PRIM( ctx, GL_TRIANGLES, HW_TRIANGLES, start, count ); +} + + + +static void TAG(render_tri_strip_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + if (0) fprintf(stderr, "%s\n", __FUNCTION__); + + if (start + 2 >= count) + return; + + if (PREFER_DISCRETE_ELT_PRIM( count-start, HW_TRIANGLES )) + { + int dmasz = GET_MAX_HW_ELTS(); + int parity = 0; + GLuint j, nr; + + ELT_INIT( GL_TRIANGLES, HW_TRIANGLES ); + + /* Emit even number of tris in each full buffer. + */ + dmasz = dmasz/3; + dmasz -= dmasz & 1; + + for (j = start; j + 2 < count; j += nr - 2 ) { + ELT_TYPE *dest; + GLint i; + + nr = MIN2( dmasz, count - j ); + dest = ALLOC_ELTS( (nr-2)*3 ); + + for ( i = j ; i+2 < j+nr ; i++, parity^=1 ) { + EMIT_ELT( dest, 0, (i+0+parity) ); + EMIT_ELT( dest, 1, (i+1-parity) ); + EMIT_ELT( dest, 2, (i+2) ); + dest += 3; + } + + CLOSE_ELTS(); + } + } + else if (HAVE_TRI_STRIP_1) + EMIT_PRIM( ctx, GL_TRIANGLE_STRIP, HW_TRIANGLE_STRIP_1, start, count ); + else { + /* Emit the first triangle with elts, then the rest as a regular strip. + * TODO: Make this unlikely in t_imm_api.c + */ + ELT_TYPE *dest; + + ELT_INIT( GL_TRIANGLES, HW_TRIANGLES ); + dest = ALLOC_ELTS( 3 ); + EMIT_ELT( dest, 0, (start+1) ); + EMIT_ELT( dest, 1, (start+0) ); + EMIT_ELT( dest, 2, (start+2) ); + dest += 3; + CLOSE_ELTS(); + + start++; + if (start + 2 >= count) + return; + + EMIT_PRIM( ctx, GL_TRIANGLE_STRIP, HW_TRIANGLE_STRIP_0, start, + count ); + } +} + +static void TAG(render_tri_fan_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + if (0) fprintf(stderr, "%s\n", __FUNCTION__); + + if (start+2 >= count) + return; + + if (PREFER_DISCRETE_ELT_PRIM( count-start, HW_TRIANGLES )) + { + int dmasz = GET_MAX_HW_ELTS(); + GLuint j, nr; + + ELT_INIT( GL_TRIANGLES, HW_TRIANGLES ); + + dmasz = dmasz/3; + + for (j = start + 1; j + 1 < count; j += nr - 1 ) { + ELT_TYPE *dest; + GLint i; + + nr = MIN2( dmasz, count - j ); + dest = ALLOC_ELTS( (nr-1)*3 ); + + for ( i = j ; i+1 < j+nr ; i++ ) { + EMIT_ELT( dest, 0, (start) ); + EMIT_ELT( dest, 1, (i) ); + EMIT_ELT( dest, 2, (i+1) ); + dest += 3; + } + + CLOSE_ELTS(); + } + } + else { + EMIT_PRIM( ctx, GL_TRIANGLE_FAN, HW_TRIANGLE_FAN, start, count ); + } +} + + +static void TAG(render_poly_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + if (0) fprintf(stderr, "%s\n", __FUNCTION__); + + if (start+2 >= count) + return; + + EMIT_PRIM( ctx, GL_POLYGON, HW_POLYGON, start, count ); +} + +static void TAG(render_quad_strip_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + if (0) fprintf(stderr, "%s\n", __FUNCTION__); + + count -= (count-start) & 1; + + if (start+3 >= count) + return; + + if (HAVE_QUAD_STRIPS) { + EMIT_PRIM( ctx, GL_QUAD_STRIP, HW_QUAD_STRIP, start, count ); + } + else if (ctx->_TriangleCaps & DD_FLATSHADE) { + LOCAL_VARS; + int dmasz = GET_MAX_HW_ELTS(); + GLuint j, nr; + + ELT_INIT( GL_TRIANGLES, HW_TRIANGLES ); + + /* Emit whole number of quads in total, and in each buffer. + */ + dmasz = (dmasz/6)*2; + + for (j = start; j + 3 < count; j += nr - 2 ) { + ELT_TYPE *dest; + GLint quads, i; + + nr = MIN2( dmasz, count - j ); + quads = (nr/2)-1; + dest = ALLOC_ELTS( quads*6 ); + + for ( i = j ; i < j+quads*2 ; i+=2 ) { + EMIT_TWO_ELTS( dest, 0, (i+0), (i+1) ); + EMIT_TWO_ELTS( dest, 2, (i+2), (i+1) ); + EMIT_TWO_ELTS( dest, 4, (i+3), (i+2) ); + dest += 6; + } + + CLOSE_ELTS(); + } + } + else { + EMIT_PRIM( ctx, GL_TRIANGLE_STRIP, HW_TRIANGLE_STRIP_0, start, count ); + } +} + + +static void TAG(render_quads_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + if (0) fprintf(stderr, "%s\n", __FUNCTION__); + count -= (count-start)%4; + + if (start+3 >= count) + return; + + if (HAVE_QUADS) { + EMIT_PRIM( ctx, HW_QUADS, GL_QUADS, start, count ); + } + else { + /* Hardware doesn't have a quad primitive type -- simulate it + * using indexed vertices and the triangle primitive: + */ + LOCAL_VARS; + int dmasz = GET_MAX_HW_ELTS(); + GLuint j, nr; + + ELT_INIT( GL_TRIANGLES, HW_TRIANGLES ); + + /* Adjust for rendering as triangles: + */ + dmasz = (dmasz/6)*4; + + for (j = start; j < count; j += nr ) { + ELT_TYPE *dest; + GLint quads, i; + + nr = MIN2( dmasz, count - j ); + quads = nr/4; + dest = ALLOC_ELTS( quads*6 ); + + for ( i = j ; i < j+quads*4 ; i+=4 ) { + EMIT_TWO_ELTS( dest, 0, (i+0), (i+1) ); + EMIT_TWO_ELTS( dest, 2, (i+3), (i+1) ); + EMIT_TWO_ELTS( dest, 4, (i+2), (i+3) ); + dest += 6; + } + + CLOSE_ELTS(); + } + } +} + +static void TAG(render_noop)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ +} + + + + +static render_func TAG(render_tab_verts)[GL_POLYGON+2] = +{ + TAG(render_points_verts), + TAG(render_lines_verts), + TAG(render_line_loop_verts), + TAG(render_line_strip_verts), + TAG(render_triangles_verts), + TAG(render_tri_strip_verts), + TAG(render_tri_fan_verts), + TAG(render_quads_verts), + TAG(render_quad_strip_verts), + TAG(render_poly_verts), + TAG(render_noop), +}; + + +/**************************************************************************** + * Render elts using hardware indexed verts * + ****************************************************************************/ + +static void TAG(render_points_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + int dmasz = GET_MAX_HW_ELTS(); + GLuint *elts = GET_MESA_ELTS(); + GLuint j, nr; + ELT_TYPE *dest; + + ELT_INIT( GL_POINTS, HW_POINTS ); + + for (j = start; j < count; j += nr ) { + nr = MIN2( dmasz, count - j ); + dest = ALLOC_ELTS( nr ); + dest = TAG(emit_elts)( ctx, dest, elts+j, nr ); + CLOSE_ELTS(); + } +} + + + +static void TAG(render_lines_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + int dmasz = GET_MAX_HW_ELTS(); + GLuint *elts = GET_MESA_ELTS(); + GLuint j, nr; + ELT_TYPE *dest; + + if (start+1 >= count) + return; + + if ((flags & PRIM_BEGIN) && ctx->Line.StippleFlag) { + RESET_STIPPLE(); + AUTO_STIPPLE( GL_TRUE ); + } + + ELT_INIT( GL_LINES, HW_LINES ); + + /* Emit whole number of lines in total and in each buffer: + */ + count -= (count-start) & 1; + dmasz -= dmasz & 1; + + for (j = start; j < count; j += nr ) { + nr = MIN2( dmasz, count - j ); + dest = ALLOC_ELTS( nr ); + dest = TAG(emit_elts)( ctx, dest, elts+j, nr ); + CLOSE_ELTS(); + } + + if ((flags & PRIM_END) && ctx->Line.StippleFlag) + AUTO_STIPPLE( GL_FALSE ); +} + + +static void TAG(render_line_strip_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + int dmasz = GET_MAX_HW_ELTS(); + GLuint *elts = GET_MESA_ELTS(); + GLuint j, nr; + ELT_TYPE *dest; + + if (start+1 >= count) + return; + + ELT_INIT( GL_LINE_STRIP, HW_LINE_STRIP ); + + if ((flags & PRIM_BEGIN) && ctx->Line.StippleFlag) + RESET_STIPPLE(); + + for (j = start; j + 1 < count; j += nr - 1 ) { + nr = MIN2( dmasz, count - j ); + dest = ALLOC_ELTS( nr ); + dest = TAG(emit_elts)( ctx, dest, elts+j, nr ); + CLOSE_ELTS(); + } +} + + +static void TAG(render_line_loop_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + int dmasz = GET_MAX_HW_ELTS(); + GLuint *elts = GET_MESA_ELTS(); + GLuint j, nr; + ELT_TYPE *dest; + + if (0) fprintf(stderr, "%s\n", __FUNCTION__); + + if (flags & PRIM_BEGIN) + j = start; + else + j = start + 1; + + + if (flags & PRIM_END) { + if (start+1 >= count) + return; + } + else { + if (j+1 >= count) + return; + } + + ELT_INIT( GL_LINE_STRIP, HW_LINE_STRIP ); + + if ((flags & PRIM_BEGIN) && ctx->Line.StippleFlag) + RESET_STIPPLE(); + + + /* Ensure last vertex doesn't wrap: + */ + dmasz--; + + for ( ; j + 1 < count; ) { + nr = MIN2( dmasz, count - j ); + dest = ALLOC_ELTS( nr+1 ); /* Reserve possible space for last elt */ + dest = TAG(emit_elts)( ctx, dest, elts+j, nr ); + j += nr - 1; + if (j + 1 >= count && (flags & PRIM_END)) { + dest = TAG(emit_elts)( ctx, dest, elts+start, 1 ); + } + CLOSE_ELTS(); + } +} + + +static void TAG(render_triangles_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + GLuint *elts = GET_MESA_ELTS(); + int dmasz = GET_MAX_HW_ELTS()/3*3; + GLuint j, nr; + ELT_TYPE *dest; + + if (start+2 >= count) + return; + + ELT_INIT( GL_TRIANGLES, HW_TRIANGLES ); + + + /* Emit whole number of tris in total. dmasz is already a multiple + * of 3. + */ + count -= (count-start)%3; + + for (j = start; j < count; j += nr) { + nr = MIN2( dmasz, count - j ); + dest = ALLOC_ELTS( nr ); + dest = TAG(emit_elts)( ctx, dest, elts+j, nr ); + CLOSE_ELTS(); + } +} + + + +static void TAG(render_tri_strip_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + GLuint j, nr; + GLuint *elts = GET_MESA_ELTS(); + int dmasz = GET_MAX_HW_ELTS(); + ELT_TYPE *dest; + + if (start+2 >= count) + return; + + ELT_INIT( GL_TRIANGLE_STRIP, HW_TRIANGLE_STRIP_0 ); + + /* Keep the same winding over multiple buffers: + */ + dmasz -= (dmasz & 1); + + for (j = start ; j + 2 < count; j += nr - 2 ) { + nr = MIN2( dmasz, count - j ); + + dest = ALLOC_ELTS( nr ); + dest = TAG(emit_elts)( ctx, dest, elts+j, nr ); + CLOSE_ELTS(); + } +} + +static void TAG(render_tri_fan_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + GLuint *elts = GET_MESA_ELTS(); + GLuint j, nr; + int dmasz = GET_MAX_HW_ELTS(); + ELT_TYPE *dest; + + if (start+2 >= count) + return; + + ELT_INIT( GL_TRIANGLE_FAN, HW_TRIANGLE_FAN ); + + for (j = start + 1 ; j + 1 < count; j += nr - 1 ) { + nr = MIN2( dmasz, count - j + 1 ); + dest = ALLOC_ELTS( nr ); + dest = TAG(emit_elts)( ctx, dest, elts+start, 1 ); + dest = TAG(emit_elts)( ctx, dest, elts+j, nr - 1 ); + CLOSE_ELTS(); + } +} + + +static void TAG(render_poly_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + GLuint *elts = GET_MESA_ELTS(); + GLuint j, nr; + int dmasz = GET_MAX_HW_ELTS(); + ELT_TYPE *dest; + + if (start+2 >= count) + return; + + ELT_INIT( GL_POLYGON, HW_POLYGON ); + + for (j = start + 1 ; j + 1 < count ; j += nr - 1 ) { + nr = MIN2( dmasz, count - j + 1 ); + dest = ALLOC_ELTS( nr ); + dest = TAG(emit_elts)( ctx, dest, elts+start, 1 ); + dest = TAG(emit_elts)( ctx, dest, elts+j, nr - 1 ); + CLOSE_ELTS(); + } +} + +static void TAG(render_quad_strip_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (start+3 >= count) + return; + + if (HAVE_QUAD_STRIPS && 0) { + } + else { + LOCAL_VARS; + GLuint *elts = GET_MESA_ELTS(); + int dmasz = GET_MAX_HW_ELTS(); + GLuint j, nr; + ELT_TYPE *dest; + + /* Emit whole number of quads in total, and in each buffer. + */ + dmasz -= dmasz & 1; + count -= (count-start) & 1; + + if (ctx->_TriangleCaps & DD_FLATSHADE) { + ELT_INIT( GL_TRIANGLES, HW_TRIANGLES ); + + dmasz = dmasz/6*2; + + for (j = start; j + 3 < count; j += nr - 2 ) { + nr = MIN2( dmasz, count - j ); + + if (nr >= 4) + { + GLint quads = (nr/2)-1; + ELT_TYPE *dest = ALLOC_ELTS( quads*6 ); + GLint i; + + for ( i = j-start ; i < j-start+quads ; i++, elts += 2 ) { + EMIT_TWO_ELTS( dest, 0, elts[0], elts[1] ); + EMIT_TWO_ELTS( dest, 2, elts[2], elts[1] ); + EMIT_TWO_ELTS( dest, 4, elts[3], elts[2] ); + dest += 6; + } + + CLOSE_ELTS(); + } + } + } + else { + ELT_INIT( GL_TRIANGLE_STRIP, HW_TRIANGLE_STRIP_0 ); + + for (j = start; j + 3 < count; j += nr - 2 ) { + nr = MIN2( dmasz, count - j ); + dest = ALLOC_ELTS( nr ); + dest = TAG(emit_elts)( ctx, dest, elts+j, nr ); + CLOSE_ELTS(); + } + } + } +} + + +static void TAG(render_quads_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (start+3 >= count) + return; + + if (HAVE_QUADS && 0) { + } else { + LOCAL_VARS; + GLuint *elts = GET_MESA_ELTS(); + int dmasz = GET_MAX_HW_ELTS(); + GLuint j, nr; + + ELT_INIT( GL_TRIANGLES, HW_TRIANGLES ); + + /* Emit whole number of quads in total, and in each buffer. + */ + dmasz -= dmasz & 3; + count -= (count-start) & 3; + + /* Adjust for rendering as triangles: + */ + dmasz = dmasz/6*4; + + for (j = start; j + 3 < count; j += nr ) { + nr = MIN2( dmasz, count - j ); + + { + GLint quads = nr/4; + ELT_TYPE *dest = ALLOC_ELTS( quads * 6 ); + GLint i; + + for ( i = j-start ; i < j-start+quads ; i++, elts += 4 ) { + EMIT_TWO_ELTS( dest, 0, elts[0], elts[1] ); + EMIT_TWO_ELTS( dest, 2, elts[3], elts[1] ); + EMIT_TWO_ELTS( dest, 4, elts[2], elts[3] ); + dest += 6; + } + + CLOSE_ELTS(); + } + } + } +} + + + +static render_func TAG(render_tab_elts)[GL_POLYGON+2] = +{ + TAG(render_points_elts), + TAG(render_lines_elts), + TAG(render_line_loop_elts), + TAG(render_line_strip_elts), + TAG(render_triangles_elts), + TAG(render_tri_strip_elts), + TAG(render_tri_fan_elts), + TAG(render_quads_elts), + TAG(render_quad_strip_elts), + TAG(render_poly_elts), + TAG(render_noop), +}; diff --git a/reactos/lib/mesa32/src/drivers/common/t_dd_rendertmp.h b/reactos/lib/mesa32/src/drivers/common/t_dd_rendertmp.h new file mode 100644 index 00000000000..b9f030195d5 --- /dev/null +++ b/reactos/lib/mesa32/src/drivers/common/t_dd_rendertmp.h @@ -0,0 +1,434 @@ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * 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 + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * 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 RESET_OCCLUSION +#define RESET_OCCLUSION +#endif + +#ifndef TEST_PRIM_END +#define TEST_PRIM_END(flags) (flags & PRIM_END) +#define TEST_PRIM_BEGIN(flags) (flags & PRIM_BEGIN) +#define TEST_PRIM_PARITY(flags) (flags & PRIM_PARITY) +#endif + +#ifndef ELT +#define ELT(x) x +#endif + +#ifndef RENDER_TAB_QUALIFIER +#define RENDER_TAB_QUALIFIER static +#endif + +static void TAG(render_points)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + (void) flags; + + RESET_OCCLUSION; + INIT(GL_POINTS); + RENDER_POINTS( start, count ); + POSTFIX; +} + +static void TAG(render_lines)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + GLuint j; + LOCAL_VARS; + (void) flags; + + RESET_OCCLUSION; + INIT(GL_LINES); + for (j=start+1; j + */ + + +/* Template for building functions to plug into the driver interface + * of t_vb_render.c: + * ctx->Driver.QuadFunc + * ctx->Driver.TriangleFunc + * ctx->Driver.LineFunc + * ctx->Driver.PointsFunc + * + * DO_TWOSIDE: Plug back-color values from the VB into backfacing triangles, + * and restore vertices afterwards. + * DO_OFFSET: Calculate offset for triangles and adjust vertices. Restore + * vertices after rendering. + * DO_FLAT: For hardware without native flatshading, copy provoking colors + * into the other vertices. Restore after rendering. + * DO_UNFILLED: Decompose triangles to lines and points where appropriate. + * + * HAVE_RGBA: Vertices have rgba values (otherwise index values). + * HAVE_SPEC: Vertices have secondary rgba values. + * + * VERT_X(v): Alias for vertex x value. + * VERT_Y(v): Alias for vertex y value. + * VERT_Z(v): Alias for vertex z value. + * DEPTH_SCALE: Scale for offset. + * + * VERTEX: Hardware vertex type. + * GET_VERTEX(n): Retreive vertex with index n. + * AREA_IS_CCW(a): Return true if triangle with signed area a is ccw. + * + * VERT_SET_RGBA: Assign vertex rgba from VB color. + * VERT_COPY_RGBA: Copy vertex rgba another vertex. + * VERT_SAVE_RGBA: Save vertex rgba to a local variable. + * VERT_RESTORE_RGBA: Restore vertex rgba from a local variable. + * --> Similar for IND and SPEC. + * + * LOCAL_VARS(n): (At least) define local vars for save/restore rgba. + * + */ + +#if HAVE_RGBA +#define VERT_SET_IND( v, c ) (void) c +#define VERT_COPY_IND( v0, v1 ) +#define VERT_SAVE_IND( idx ) +#define VERT_RESTORE_IND( idx ) +#if HAVE_BACK_COLORS +#define VERT_SET_RGBA( v, c ) +#endif +#else +#define VERT_SET_RGBA( v, c ) (void) c +#define VERT_COPY_RGBA( v0, v1 ) +#define VERT_SAVE_RGBA( idx ) +#define VERT_RESTORE_RGBA( idx ) +#if HAVE_BACK_COLORS +#define VERT_SET_IND( v, c ) +#endif +#endif + +#if !HAVE_SPEC +#define VERT_SET_SPEC( v, c ) (void) c +#define VERT_COPY_SPEC( v0, v1 ) +#define VERT_SAVE_SPEC( idx ) +#define VERT_RESTORE_SPEC( idx ) +#if HAVE_BACK_COLORS +#define VERT_COPY_SPEC1( v ) +#endif +#else +#if HAVE_BACK_COLORS +#define VERT_SET_SPEC( v, c ) +#endif +#endif + +#if !HAVE_BACK_COLORS +#define VERT_COPY_SPEC1( v ) +#define VERT_COPY_IND1( v ) +#define VERT_COPY_RGBA1( v ) +#endif + +#ifndef INSANE_VERTICES +#define VERT_SET_Z(v,val) VERT_Z(v) = val +#define VERT_Z_ADD(v,val) VERT_Z(v) += val +#endif + +#if DO_TRI +static void TAG(triangle)( GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 ) +{ + struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb; + VERTEX *v[3]; + GLfloat offset; + GLfloat z[3]; + GLenum mode = GL_FILL; + GLuint facing; + LOCAL_VARS(3); + +/* fprintf(stderr, "%s\n", __FUNCTION__); */ + + v[0] = (VERTEX *)GET_VERTEX(e0); + v[1] = (VERTEX *)GET_VERTEX(e1); + v[2] = (VERTEX *)GET_VERTEX(e2); + + if (DO_TWOSIDE || DO_OFFSET || DO_UNFILLED) + { + GLfloat ex = VERT_X(v[0]) - VERT_X(v[2]); + GLfloat ey = VERT_Y(v[0]) - VERT_Y(v[2]); + GLfloat fx = VERT_X(v[1]) - VERT_X(v[2]); + GLfloat fy = VERT_Y(v[1]) - VERT_Y(v[2]); + GLfloat cc = ex*fy - ey*fx; + + if (DO_TWOSIDE || DO_UNFILLED) + { + facing = AREA_IS_CCW( cc ) ^ ctx->Polygon._FrontBit; + + if (DO_UNFILLED) { + if (facing) { + mode = ctx->Polygon.BackMode; + if (ctx->Polygon.CullFlag && + ctx->Polygon.CullFaceMode != GL_FRONT) { + return; + } + } else { + mode = ctx->Polygon.FrontMode; + if (ctx->Polygon.CullFlag && + ctx->Polygon.CullFaceMode != GL_BACK) { + return; + } + } + } + + if (DO_TWOSIDE && facing == 1) + { + if (HAVE_RGBA) { + if (HAVE_BACK_COLORS) { + if (!DO_FLAT) { + VERT_SAVE_RGBA( 0 ); + VERT_SAVE_RGBA( 1 ); + VERT_COPY_RGBA1( v[0] ); + VERT_COPY_RGBA1( v[1] ); + } + VERT_SAVE_RGBA( 2 ); + VERT_COPY_RGBA1( v[2] ); + if (HAVE_SPEC) { + if (!DO_FLAT) { + VERT_SAVE_SPEC( 0 ); + VERT_SAVE_SPEC( 1 ); + VERT_COPY_SPEC1( v[0] ); + VERT_COPY_SPEC1( v[1] ); + } + VERT_SAVE_SPEC( 2 ); + VERT_COPY_SPEC1( v[2] ); + } + } + else { + GLfloat (*vbcolor)[4] = VB->ColorPtr[1]->data; + ASSERT(VB->ColorPtr[1]->stride == 4*sizeof(GLfloat)); + (void) vbcolor; + + if (!DO_FLAT) { + VERT_SAVE_RGBA( 0 ); + VERT_SAVE_RGBA( 1 ); + VERT_SET_RGBA( v[0], vbcolor[e0] ); + VERT_SET_RGBA( v[1], vbcolor[e1] ); + } + VERT_SAVE_RGBA( 2 ); + VERT_SET_RGBA( v[2], vbcolor[e2] ); + + if (HAVE_SPEC && VB->SecondaryColorPtr[1]) { + GLfloat (*vbspec)[4] = VB->SecondaryColorPtr[1]->data; + + if (!DO_FLAT) { + VERT_SAVE_SPEC( 0 ); + VERT_SAVE_SPEC( 1 ); + VERT_SET_SPEC( v[0], vbspec[e0] ); + VERT_SET_SPEC( v[1], vbspec[e1] ); + } + VERT_SAVE_SPEC( 2 ); + VERT_SET_SPEC( v[2], vbspec[e2] ); + } + } + } + else { + GLfloat (*vbindex) = (GLfloat *)VB->IndexPtr[1]->data; + if (!DO_FLAT) { + VERT_SAVE_IND( 0 ); + VERT_SAVE_IND( 1 ); + VERT_SET_IND( v[0], vbindex[e0] ); + VERT_SET_IND( v[1], vbindex[e1] ); + } + VERT_SAVE_IND( 2 ); + VERT_SET_IND( v[2], vbindex[e2] ); + } + } + } + + + if (DO_OFFSET) + { + offset = ctx->Polygon.OffsetUnits * DEPTH_SCALE; + z[0] = VERT_Z(v[0]); + z[1] = VERT_Z(v[1]); + z[2] = VERT_Z(v[2]); + if (cc * cc > 1e-16) { + GLfloat ic = 1.0 / cc; + GLfloat ez = z[0] - z[2]; + GLfloat fz = z[1] - z[2]; + GLfloat a = ey*fz - ez*fy; + GLfloat b = ez*fx - ex*fz; + GLfloat ac = a * ic; + GLfloat bc = b * ic; + if ( ac < 0.0f ) ac = -ac; + if ( bc < 0.0f ) bc = -bc; + offset += MAX2( ac, bc ) * ctx->Polygon.OffsetFactor; + } + offset *= ctx->MRD; + } + } + + if (DO_FLAT) { + if (HAVE_RGBA) { + VERT_SAVE_RGBA( 0 ); + VERT_SAVE_RGBA( 1 ); + VERT_COPY_RGBA( v[0], v[2] ); + VERT_COPY_RGBA( v[1], v[2] ); + if (HAVE_SPEC && VB->SecondaryColorPtr[0]) { + VERT_SAVE_SPEC( 0 ); + VERT_SAVE_SPEC( 1 ); + VERT_COPY_SPEC( v[0], v[2] ); + VERT_COPY_SPEC( v[1], v[2] ); + } + } + else { + VERT_SAVE_IND( 0 ); + VERT_SAVE_IND( 1 ); + VERT_COPY_IND( v[0], v[2] ); + VERT_COPY_IND( v[1], v[2] ); + } + } + + if (mode == GL_POINT) { + if (DO_OFFSET && ctx->Polygon.OffsetPoint) { + VERT_Z_ADD(v[0], offset); + VERT_Z_ADD(v[1], offset); + VERT_Z_ADD(v[2], offset); + } + UNFILLED_TRI( ctx, GL_POINT, e0, e1, e2 ); + } else if (mode == GL_LINE) { + if (DO_OFFSET && ctx->Polygon.OffsetLine) { + VERT_Z_ADD(v[0], offset); + VERT_Z_ADD(v[1], offset); + VERT_Z_ADD(v[2], offset); + } + UNFILLED_TRI( ctx, GL_LINE, e0, e1, e2 ); + } else { + if (DO_OFFSET && ctx->Polygon.OffsetFill) { + VERT_Z_ADD(v[0], offset); + VERT_Z_ADD(v[1], offset); + VERT_Z_ADD(v[2], offset); + } + if (DO_UNFILLED) + RASTERIZE( GL_TRIANGLES ); + TRI( v[0], v[1], v[2] ); + } + + if (DO_OFFSET) + { + VERT_SET_Z(v[0], z[0]); + VERT_SET_Z(v[1], z[1]); + VERT_SET_Z(v[2], z[2]); + } + + if (DO_TWOSIDE && facing == 1) + { + if (HAVE_RGBA) { + if (!DO_FLAT) { + VERT_RESTORE_RGBA( 0 ); + VERT_RESTORE_RGBA( 1 ); + } + VERT_RESTORE_RGBA( 2 ); + if (HAVE_SPEC) { + if (!DO_FLAT) { + VERT_RESTORE_SPEC( 0 ); + VERT_RESTORE_SPEC( 1 ); + } + VERT_RESTORE_SPEC( 2 ); + } + } + else { + if (!DO_FLAT) { + VERT_RESTORE_IND( 0 ); + VERT_RESTORE_IND( 1 ); + } + VERT_RESTORE_IND( 2 ); + } + } + + + if (DO_FLAT) { + if (HAVE_RGBA) { + VERT_RESTORE_RGBA( 0 ); + VERT_RESTORE_RGBA( 1 ); + if (HAVE_SPEC && VB->SecondaryColorPtr[0]) { + VERT_RESTORE_SPEC( 0 ); + VERT_RESTORE_SPEC( 1 ); + } + } + else { + VERT_RESTORE_IND( 0 ); + VERT_RESTORE_IND( 1 ); + } + } +} +#endif + +#if DO_QUAD +#if DO_FULL_QUAD +static void TAG(quad)( GLcontext *ctx, + GLuint e0, GLuint e1, GLuint e2, GLuint e3 ) +{ + struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb; + VERTEX *v[4]; + GLfloat offset; + GLfloat z[4]; + GLenum mode = GL_FILL; + GLuint facing; + LOCAL_VARS(4); + + v[0] = (VERTEX *)GET_VERTEX(e0); + v[1] = (VERTEX *)GET_VERTEX(e1); + v[2] = (VERTEX *)GET_VERTEX(e2); + v[3] = (VERTEX *)GET_VERTEX(e3); + + if (DO_TWOSIDE || DO_OFFSET || DO_UNFILLED) + { + GLfloat ex = VERT_X(v[2]) - VERT_X(v[0]); + GLfloat ey = VERT_Y(v[2]) - VERT_Y(v[0]); + GLfloat fx = VERT_X(v[3]) - VERT_X(v[1]); + GLfloat fy = VERT_Y(v[3]) - VERT_Y(v[1]); + GLfloat cc = ex*fy - ey*fx; + + if (DO_TWOSIDE || DO_UNFILLED) + { + facing = AREA_IS_CCW( cc ) ^ ctx->Polygon._FrontBit; + + if (DO_UNFILLED) { + if (facing) { + mode = ctx->Polygon.BackMode; + if (ctx->Polygon.CullFlag && + ctx->Polygon.CullFaceMode != GL_FRONT) { + return; + } + } else { + mode = ctx->Polygon.FrontMode; + if (ctx->Polygon.CullFlag && + ctx->Polygon.CullFaceMode != GL_BACK) { + return; + } + } + } + + if (DO_TWOSIDE && facing == 1) + { + if (HAVE_RGBA) { + GLfloat (*vbcolor)[4] = VB->ColorPtr[1]->data; + (void)vbcolor; + + if (HAVE_BACK_COLORS) { + if (!DO_FLAT) { + VERT_SAVE_RGBA( 0 ); + VERT_SAVE_RGBA( 1 ); + VERT_SAVE_RGBA( 2 ); + VERT_COPY_RGBA1( v[0] ); + VERT_COPY_RGBA1( v[1] ); + VERT_COPY_RGBA1( v[2] ); + } + VERT_SAVE_RGBA( 3 ); + VERT_COPY_RGBA1( v[3] ); + if (HAVE_SPEC) { + if (!DO_FLAT) { + VERT_SAVE_SPEC( 0 ); + VERT_SAVE_SPEC( 1 ); + VERT_SAVE_SPEC( 2 ); + VERT_COPY_SPEC1( v[0] ); + VERT_COPY_SPEC1( v[1] ); + VERT_COPY_SPEC1( v[2] ); + } + VERT_SAVE_SPEC( 3 ); + VERT_COPY_SPEC1( v[3] ); + } + } + else { + if (!DO_FLAT) { + VERT_SAVE_RGBA( 0 ); + VERT_SAVE_RGBA( 1 ); + VERT_SAVE_RGBA( 2 ); + VERT_SET_RGBA( v[0], vbcolor[e0] ); + VERT_SET_RGBA( v[1], vbcolor[e1] ); + VERT_SET_RGBA( v[2], vbcolor[e2] ); + } + VERT_SAVE_RGBA( 3 ); + VERT_SET_RGBA( v[3], vbcolor[e3] ); + + if (HAVE_SPEC && VB->SecondaryColorPtr[1]) { + GLfloat (*vbspec)[4] = VB->SecondaryColorPtr[1]->data; + ASSERT(VB->SecondaryColorPtr[1]->stride==4*sizeof(GLfloat)); + + if (!DO_FLAT) { + VERT_SAVE_SPEC( 0 ); + VERT_SAVE_SPEC( 1 ); + VERT_SAVE_SPEC( 2 ); + VERT_SET_SPEC( v[0], vbspec[e0] ); + VERT_SET_SPEC( v[1], vbspec[e1] ); + VERT_SET_SPEC( v[2], vbspec[e2] ); + } + VERT_SAVE_SPEC( 3 ); + VERT_SET_SPEC( v[3], vbspec[e3] ); + } + } + } + else { + GLfloat *vbindex = (GLfloat *)VB->IndexPtr[1]->data; + if (!DO_FLAT) { + VERT_SAVE_IND( 0 ); + VERT_SAVE_IND( 1 ); + VERT_SAVE_IND( 2 ); + VERT_SET_IND( v[0], vbindex[e0] ); + VERT_SET_IND( v[1], vbindex[e1] ); + VERT_SET_IND( v[2], vbindex[e2] ); + } + VERT_SAVE_IND( 3 ); + VERT_SET_IND( v[3], vbindex[e3] ); + } + } + } + + + if (DO_OFFSET) + { + offset = ctx->Polygon.OffsetUnits * DEPTH_SCALE; + z[0] = VERT_Z(v[0]); + z[1] = VERT_Z(v[1]); + z[2] = VERT_Z(v[2]); + z[3] = VERT_Z(v[3]); + if (cc * cc > 1e-16) { + GLfloat ez = z[2] - z[0]; + GLfloat fz = z[3] - z[1]; + GLfloat a = ey*fz - ez*fy; + GLfloat b = ez*fx - ex*fz; + GLfloat ic = 1.0 / cc; + GLfloat ac = a * ic; + GLfloat bc = b * ic; + if ( ac < 0.0f ) ac = -ac; + if ( bc < 0.0f ) bc = -bc; + offset += MAX2( ac, bc ) * ctx->Polygon.OffsetFactor; + } + offset *= ctx->MRD; + } + } + + if (DO_FLAT) { + if (HAVE_RGBA) { + VERT_SAVE_RGBA( 0 ); + VERT_SAVE_RGBA( 1 ); + VERT_SAVE_RGBA( 2 ); + VERT_COPY_RGBA( v[0], v[3] ); + VERT_COPY_RGBA( v[1], v[3] ); + VERT_COPY_RGBA( v[2], v[3] ); + if (HAVE_SPEC && VB->SecondaryColorPtr[0]) { + VERT_SAVE_SPEC( 0 ); + VERT_SAVE_SPEC( 1 ); + VERT_SAVE_SPEC( 2 ); + VERT_COPY_SPEC( v[0], v[3] ); + VERT_COPY_SPEC( v[1], v[3] ); + VERT_COPY_SPEC( v[2], v[3] ); + } + } + else { + VERT_SAVE_IND( 0 ); + VERT_SAVE_IND( 1 ); + VERT_SAVE_IND( 2 ); + VERT_COPY_IND( v[0], v[3] ); + VERT_COPY_IND( v[1], v[3] ); + VERT_COPY_IND( v[2], v[3] ); + } + } + + if (mode == GL_POINT) { + if (( DO_OFFSET) && ctx->Polygon.OffsetPoint) { + VERT_Z_ADD(v[0], offset); + VERT_Z_ADD(v[1], offset); + VERT_Z_ADD(v[2], offset); + VERT_Z_ADD(v[3], offset); + } + UNFILLED_QUAD( ctx, GL_POINT, e0, e1, e2, e3 ); + } else if (mode == GL_LINE) { + if (DO_OFFSET && ctx->Polygon.OffsetLine) { + VERT_Z_ADD(v[0], offset); + VERT_Z_ADD(v[1], offset); + VERT_Z_ADD(v[2], offset); + VERT_Z_ADD(v[3], offset); + } + UNFILLED_QUAD( ctx, GL_LINE, e0, e1, e2, e3 ); + } else { + if (DO_OFFSET && ctx->Polygon.OffsetFill) { + VERT_Z_ADD(v[0], offset); + VERT_Z_ADD(v[1], offset); + VERT_Z_ADD(v[2], offset); + VERT_Z_ADD(v[3], offset); + } + RASTERIZE( GL_TRIANGLES ); + QUAD( (v[0]), (v[1]), (v[2]), (v[3]) ); + } + + if (DO_OFFSET) + { + VERT_SET_Z(v[0], z[0]); + VERT_SET_Z(v[1], z[1]); + VERT_SET_Z(v[2], z[2]); + VERT_SET_Z(v[3], z[3]); + } + + if (DO_TWOSIDE && facing == 1) + { + if (HAVE_RGBA) { + if (!DO_FLAT) { + VERT_RESTORE_RGBA( 0 ); + VERT_RESTORE_RGBA( 1 ); + VERT_RESTORE_RGBA( 2 ); + } + VERT_RESTORE_RGBA( 3 ); + if (HAVE_SPEC) { + if (!DO_FLAT) { + VERT_RESTORE_SPEC( 0 ); + VERT_RESTORE_SPEC( 1 ); + VERT_RESTORE_SPEC( 2 ); + } + VERT_RESTORE_SPEC( 3 ); + } + } + else { + if (!DO_FLAT) { + VERT_RESTORE_IND( 0 ); + VERT_RESTORE_IND( 1 ); + VERT_RESTORE_IND( 2 ); + } + VERT_RESTORE_IND( 3 ); + } + } + + + if (DO_FLAT) { + if (HAVE_RGBA) { + VERT_RESTORE_RGBA( 0 ); + VERT_RESTORE_RGBA( 1 ); + VERT_RESTORE_RGBA( 2 ); + if (HAVE_SPEC && VB->SecondaryColorPtr[0]) { + VERT_RESTORE_SPEC( 0 ); + VERT_RESTORE_SPEC( 1 ); + VERT_RESTORE_SPEC( 2 ); + } + } + else { + VERT_RESTORE_IND( 0 ); + VERT_RESTORE_IND( 1 ); + VERT_RESTORE_IND( 2 ); + } + } +} +#else +static void TAG(quad)( GLcontext *ctx, GLuint e0, + GLuint e1, GLuint e2, GLuint e3 ) +{ + if (DO_UNFILLED) { + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + GLubyte ef1 = VB->EdgeFlag[e1]; + GLubyte ef3 = VB->EdgeFlag[e3]; + VB->EdgeFlag[e1] = 0; + TAG(triangle)( ctx, e0, e1, e3 ); + VB->EdgeFlag[e1] = ef1; + VB->EdgeFlag[e3] = 0; + TAG(triangle)( ctx, e1, e2, e3 ); + VB->EdgeFlag[e3] = ef3; + } else { + TAG(triangle)( ctx, e0, e1, e3 ); + TAG(triangle)( ctx, e1, e2, e3 ); + } +} +#endif +#endif + +#if DO_LINE +static void TAG(line)( GLcontext *ctx, GLuint e0, GLuint e1 ) +{ + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + VERTEX *v[2]; + LOCAL_VARS(2); + + v[0] = (VERTEX *)GET_VERTEX(e0); + v[1] = (VERTEX *)GET_VERTEX(e1); + + if (DO_FLAT) { + if (HAVE_RGBA) { + VERT_SAVE_RGBA( 0 ); + VERT_COPY_RGBA( v[0], v[1] ); + if (HAVE_SPEC && VB->SecondaryColorPtr[0]) { + VERT_SAVE_SPEC( 0 ); + VERT_COPY_SPEC( v[0], v[1] ); + } + } + else { + VERT_SAVE_IND( 0 ); + VERT_COPY_IND( v[0], v[1] ); + } + } + + LINE( v[0], v[1] ); + + if (DO_FLAT) { + if (HAVE_RGBA) { + VERT_RESTORE_RGBA( 0 ); + + if (HAVE_SPEC && VB->SecondaryColorPtr[0]) { + VERT_RESTORE_SPEC( 0 ); + } + } + else { + VERT_RESTORE_IND( 0 ); + } + } +} +#endif + +#if DO_POINTS +static void TAG(points)( GLcontext *ctx, GLuint first, GLuint last ) +{ + struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb; + int i; + LOCAL_VARS(1); + + if (VB->Elts == 0) { + for ( i = first ; i < last ; i++ ) { + if ( VB->ClipMask[i] == 0 ) { + VERTEX *v = (VERTEX *)GET_VERTEX(i); + POINT( v ); + } + } + } else { + for ( i = first ; i < last ; i++ ) { + GLuint e = VB->Elts[i]; + if ( VB->ClipMask[e] == 0 ) { + VERTEX *v = (VERTEX *)GET_VERTEX(e); + POINT( v ); + } + } + } +} +#endif + +static void TAG(init)( void ) +{ +#if DO_QUAD + TAB[IND].quad = TAG(quad); +#endif +#if DO_TRI + TAB[IND].triangle = TAG(triangle); +#endif +#if DO_LINE + TAB[IND].line = TAG(line); +#endif +#if DO_POINTS + TAB[IND].points = TAG(points); +#endif +} + +#undef IND +#undef TAG + +#if HAVE_RGBA +#undef VERT_SET_IND +#undef VERT_COPY_IND +#undef VERT_SAVE_IND +#undef VERT_RESTORE_IND +#if HAVE_BACK_COLORS +#undef VERT_SET_RGBA +#endif +#else +#undef VERT_SET_RGBA +#undef VERT_COPY_RGBA +#undef VERT_SAVE_RGBA +#undef VERT_RESTORE_RGBA +#if HAVE_BACK_COLORS +#undef VERT_SET_IND +#endif +#endif + +#if !HAVE_SPEC +#undef VERT_SET_SPEC +#undef VERT_COPY_SPEC +#undef VERT_SAVE_SPEC +#undef VERT_RESTORE_SPEC +#if HAVE_BACK_COLORS +#undef VERT_COPY_SPEC1 +#endif +#else +#if HAVE_BACK_COLORS +#undef VERT_SET_SPEC +#endif +#endif + +#if !HAVE_BACK_COLORS +#undef VERT_COPY_SPEC1 +#undef VERT_COPY_IND1 +#undef VERT_COPY_RGBA1 +#endif + +#ifndef INSANE_VERTICES +#undef VERT_SET_Z +#undef VERT_Z_ADD +#endif diff --git a/reactos/lib/mesa32/src/drivers/common/t_dd_unfilled.h b/reactos/lib/mesa32/src/drivers/common/t_dd_unfilled.h new file mode 100644 index 00000000000..46415ea5f68 --- /dev/null +++ b/reactos/lib/mesa32/src/drivers/common/t_dd_unfilled.h @@ -0,0 +1,212 @@ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * 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 + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Keith Whitwell + */ + +#if HAVE_RGBA +#define VERT_SET_IND( v, c ) +#define VERT_COPY_IND( v0, v1 ) +#define VERT_SAVE_IND( idx ) +#define VERT_RESTORE_IND( idx ) +#endif + +#if !HAVE_SPEC +#define VERT_SET_SPEC( v, c ) +#define VERT_COPY_SPEC( v0, v1 ) +#define VERT_SAVE_SPEC( idx ) +#define VERT_RESTORE_SPEC( idx ) +#endif + +static void TAG(unfilled_tri)( GLcontext *ctx, + GLenum mode, + GLuint e0, GLuint e1, GLuint e2 ) +{ + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + GLubyte *ef = VB->EdgeFlag; + VERTEX *v[3]; + LOCAL_VARS(3); + + v[0] = (VERTEX *)GET_VERTEX(e0); + v[1] = (VERTEX *)GET_VERTEX(e1); + v[2] = (VERTEX *)GET_VERTEX(e2); + + if ((ctx->_TriangleCaps & DD_FLATSHADE) && HAVE_HW_FLATSHADE) { + if (HAVE_RGBA) { + VERT_SAVE_RGBA(0); + VERT_SAVE_RGBA(1); + VERT_COPY_RGBA(v[0], v[2]); + VERT_COPY_RGBA(v[1], v[2]); + + if (HAVE_SPEC) { + VERT_SAVE_SPEC(0); + VERT_SAVE_SPEC(1); + VERT_COPY_SPEC(v[0], v[2]); + VERT_COPY_SPEC(v[1], v[2]); + } + } else { + VERT_SAVE_IND(0); + VERT_SAVE_IND(1); + VERT_COPY_IND(v[0], v[2]); + VERT_COPY_IND(v[1], v[2]); + } + } + +/* fprintf(stderr, "%s %s %d %d %d\n", __FUNCTION__, */ +/* _mesa_lookup_enum_by_nr( mode ), */ +/* ef[e0], ef[e1], ef[e2]); */ + + if (mode == GL_POINT) { + RASTERIZE(GL_POINTS); + if (ef[e0]) POINT( v[0] ); + if (ef[e1]) POINT( v[1] ); + if (ef[e2]) POINT( v[2] ); + } + else { + RASTERIZE(GL_LINES); + if (RENDER_PRIMITIVE == GL_POLYGON) { + if (ef[e2]) LINE( v[2], v[0] ); + if (ef[e0]) LINE( v[0], v[1] ); + if (ef[e1]) LINE( v[1], v[2] ); + } + else { + if (ef[e0]) LINE( v[0], v[1] ); + if (ef[e1]) LINE( v[1], v[2] ); + if (ef[e2]) LINE( v[2], v[0] ); + } + } + + if ((ctx->_TriangleCaps & DD_FLATSHADE) && HAVE_HW_FLATSHADE) { + if (HAVE_RGBA) { + VERT_RESTORE_RGBA(0); + VERT_RESTORE_RGBA(1); + + if (HAVE_SPEC) { + VERT_RESTORE_SPEC(0); + VERT_RESTORE_SPEC(1); + } + } else { + VERT_RESTORE_IND(0); + VERT_RESTORE_IND(1); + } + } +} + + +static void TAG(unfilled_quad)( GLcontext *ctx, + GLenum mode, + GLuint e0, GLuint e1, + GLuint e2, GLuint e3 ) +{ + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + GLubyte *ef = VB->EdgeFlag; + VERTEX *v[4]; + LOCAL_VARS(4); + + v[0] = (VERTEX *)GET_VERTEX(e0); + v[1] = (VERTEX *)GET_VERTEX(e1); + v[2] = (VERTEX *)GET_VERTEX(e2); + v[3] = (VERTEX *)GET_VERTEX(e3); + + /* Hardware flatshading breaks down here. If the hardware doesn't + * support flatshading, this will already have been done: + */ + if ((ctx->_TriangleCaps & DD_FLATSHADE) && HAVE_HW_FLATSHADE) { + if (HAVE_RGBA) { + VERT_SAVE_RGBA(0); + VERT_SAVE_RGBA(1); + VERT_SAVE_RGBA(2); + VERT_COPY_RGBA(v[0], v[3]); + VERT_COPY_RGBA(v[1], v[3]); + VERT_COPY_RGBA(v[2], v[3]); + + if (HAVE_SPEC) { + VERT_SAVE_SPEC(0); + VERT_SAVE_SPEC(1); + VERT_SAVE_SPEC(2); + VERT_COPY_SPEC(v[0], v[3]); + VERT_COPY_SPEC(v[1], v[3]); + VERT_COPY_SPEC(v[2], v[3]); + } + } else { + VERT_SAVE_IND(0); + VERT_SAVE_IND(1); + VERT_SAVE_IND(2); + VERT_COPY_IND(v[0], v[3]); + VERT_COPY_IND(v[1], v[3]); + VERT_COPY_IND(v[2], v[3]); + } + } + + if (mode == GL_POINT) { + RASTERIZE(GL_POINTS); + if (ef[e0]) POINT( v[0] ); + if (ef[e1]) POINT( v[1] ); + if (ef[e2]) POINT( v[2] ); + if (ef[e3]) POINT( v[3] ); + } + else { + RASTERIZE(GL_LINES); + if (ef[e0]) LINE( v[0], v[1] ); + if (ef[e1]) LINE( v[1], v[2] ); + if (ef[e2]) LINE( v[2], v[3] ); + if (ef[e3]) LINE( v[3], v[0] ); + } + + if ((ctx->_TriangleCaps & DD_FLATSHADE) && HAVE_HW_FLATSHADE) { + if (HAVE_RGBA) { + VERT_RESTORE_RGBA(0); + VERT_RESTORE_RGBA(1); + VERT_RESTORE_RGBA(2); + + if (HAVE_SPEC) { + VERT_RESTORE_SPEC(0); + VERT_RESTORE_SPEC(1); + VERT_RESTORE_SPEC(2); + } + } else { + VERT_RESTORE_IND(0); + VERT_RESTORE_IND(1); + VERT_RESTORE_IND(2); + } + } +} + + +#if HAVE_RGBA +#undef VERT_SET_IND +#undef VERT_COPY_IND +#undef VERT_SAVE_IND +#undef VERT_RESTORE_IND +#endif + +#if !HAVE_SPEC +#undef VERT_SET_SPEC +#undef VERT_COPY_SPEC +#undef VERT_SAVE_SPEC +#undef VERT_RESTORE_SPEC +#endif + +#undef TAG diff --git a/reactos/lib/mesa32/src/drivers/common/t_dd_vb.c b/reactos/lib/mesa32/src/drivers/common/t_dd_vb.c new file mode 100644 index 00000000000..380b0424b4f --- /dev/null +++ b/reactos/lib/mesa32/src/drivers/common/t_dd_vb.c @@ -0,0 +1,344 @@ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * 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 + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Keith Whitwell + */ +#include "math/m_translate.h" + +#if (HAVE_HW_VIEWPORT) +#define UNVIEWPORT_VARS +#define UNVIEWPORT_X(x) x +#define UNVIEWPORT_Y(x) x +#define UNVIEWPORT_Z(x) x +#endif + +#ifndef LOCALVARS +#define LOCALVARS +#endif + +#ifndef CHECK_HW_DIVIDE +#define CHECK_HW_DIVIDE 1 +#endif + +/* These don't need to be duplicated, but there's currently nowhere + * really convenient to put them. Need to build some actual .o files in + * this directory? + */ +static void copy_pv_rgba4_spec5( GLcontext *ctx, GLuint edst, GLuint esrc ) +{ + LOCALVARS + GLubyte *verts = GET_VERTEX_STORE(); + GLuint shift = GET_VERTEX_STRIDE_SHIFT(); + GLuint *dst = (GLuint *)(verts + (edst << shift)); + GLuint *src = (GLuint *)(verts + (esrc << shift)); + dst[4] = src[4]; + dst[5] = src[5]; +} + +static void copy_pv_rgba4( GLcontext *ctx, GLuint edst, GLuint esrc ) +{ + LOCALVARS + GLubyte *verts = GET_VERTEX_STORE(); + GLuint shift = GET_VERTEX_STRIDE_SHIFT(); + GLuint *dst = (GLuint *)(verts + (edst << shift)); + GLuint *src = (GLuint *)(verts + (esrc << shift)); + dst[4] = src[4]; +} + +static void copy_pv_rgba3( GLcontext *ctx, GLuint edst, GLuint esrc ) +{ + LOCALVARS + GLubyte *verts = GET_VERTEX_STORE(); + GLuint shift = GET_VERTEX_STRIDE_SHIFT(); + GLuint *dst = (GLuint *)(verts + (edst << shift)); + GLuint *src = (GLuint *)(verts + (esrc << shift)); + dst[3] = src[3]; +} + + +void TAG(translate_vertex)(GLcontext *ctx, + const VERTEX *src, + SWvertex *dst) +{ + LOCALVARS + GLuint format = GET_VERTEX_FORMAT(); + GLfloat *s = ctx->Viewport._WindowMap.m; + UNVIEWPORT_VARS; + + if (format == TINY_VERTEX_FORMAT) { + if (HAVE_HW_VIEWPORT) { + dst->win[0] = s[0] * src->v.x + s[12]; + dst->win[1] = s[5] * src->v.y + s[13]; + dst->win[2] = s[10] * src->v.z + s[14]; + dst->win[3] = 1.0; + } else { + dst->win[0] = UNVIEWPORT_X( src->v.x ); + dst->win[1] = UNVIEWPORT_Y( src->v.y ); + dst->win[2] = UNVIEWPORT_Z( src->v.z ); + dst->win[3] = 1.0; + } + + dst->color[0] = src->tv.color.red; + dst->color[1] = src->tv.color.green; + dst->color[2] = src->tv.color.blue; + dst->color[3] = src->tv.color.alpha; + } + else { + if (HAVE_HW_VIEWPORT) { + if (HAVE_HW_DIVIDE && CHECK_HW_DIVIDE) { + GLfloat oow = 1.0 / src->v.w; + dst->win[0] = s[0] * src->v.x * oow + s[12]; + dst->win[1] = s[5] * src->v.y * oow + s[13]; + dst->win[2] = s[10] * src->v.z * oow + s[14]; + dst->win[3] = oow; + } else { + dst->win[0] = s[0] * src->v.x + s[12]; + dst->win[1] = s[5] * src->v.y + s[13]; + dst->win[2] = s[10] * src->v.z + s[14]; + dst->win[3] = src->v.w; + } + } else { + dst->win[0] = UNVIEWPORT_X( src->v.x ); + dst->win[1] = UNVIEWPORT_Y( src->v.y ); + dst->win[2] = UNVIEWPORT_Z( src->v.z ); + dst->win[3] = src->v.w; + } + + dst->color[0] = src->v.color.red; + dst->color[1] = src->v.color.green; + dst->color[2] = src->v.color.blue; + dst->color[3] = src->v.color.alpha; + + dst->specular[0] = src->v.specular.red; + dst->specular[1] = src->v.specular.green; + dst->specular[2] = src->v.specular.blue; + + dst->fog = src->v.specular.alpha/255.0; + + if (HAVE_PTEX_VERTICES && + ((HAVE_TEX2_VERTICES && format == PROJ_TEX3_VERTEX_FORMAT) || + (format == PROJ_TEX1_VERTEX_FORMAT))) { + + dst->texcoord[0][0] = src->pv.u0; + dst->texcoord[0][1] = src->pv.v0; + dst->texcoord[0][3] = src->pv.q0; + + dst->texcoord[1][0] = src->pv.u1; + dst->texcoord[1][1] = src->pv.v1; + dst->texcoord[1][3] = src->pv.q1; + + if (HAVE_TEX2_VERTICES) { + dst->texcoord[2][0] = src->pv.u2; + dst->texcoord[2][1] = src->pv.v2; + dst->texcoord[2][3] = src->pv.q2; + } + + if (HAVE_TEX3_VERTICES) { + dst->texcoord[3][0] = src->pv.u3; + dst->texcoord[3][1] = src->pv.v3; + dst->texcoord[3][3] = src->pv.q3; + } + } + else { + dst->texcoord[0][0] = src->v.u0; + dst->texcoord[0][1] = src->v.v0; + dst->texcoord[0][3] = 1.0; + + dst->texcoord[1][0] = src->v.u1; + dst->texcoord[1][1] = src->v.v1; + dst->texcoord[1][3] = 1.0; + + if (HAVE_TEX2_VERTICES) { + dst->texcoord[2][0] = src->v.u2; + dst->texcoord[2][1] = src->v.v2; + dst->texcoord[2][3] = 1.0; + } + + if (HAVE_TEX3_VERTICES) { + dst->texcoord[3][0] = src->v.u3; + dst->texcoord[3][1] = src->v.v3; + dst->texcoord[3][3] = 1.0; + } + } + } + + dst->pointSize = ctx->Point._Size; +} + + + +void TAG(print_vertex)( GLcontext *ctx, const VERTEX *v ) +{ + LOCALVARS + GLuint format = GET_VERTEX_FORMAT(); + + fprintf(stderr, "(%x) ", format); + + switch (format) { +#if HAVE_TINY_VERTICES + case TINY_VERTEX_FORMAT: + fprintf(stderr, "xyz %.4f,%.4f,%.4f rgba %x:%x:%x:%x\n", + v->v.x, v->v.y, v->v.z, + v->tv.color.red, + v->tv.color.green, + v->tv.color.blue, + v->tv.color.alpha); + break; +#endif +#if HAVE_NOTEX_VERTICES + case NOTEX_VERTEX_FORMAT: + fprintf(stderr, "xyzw %.4f,%.4f,%.4f,%.4f rgba %x:%x:%x:%x spec %x:%x:%x:%x\n", + v->v.x, v->v.y, v->v.z, v->v.w, + v->v.color.red, + v->v.color.green, + v->v.color.blue, + v->v.color.alpha, + v->v.specular.red, + v->v.specular.green, + v->v.specular.blue, + v->v.specular.alpha); + break; +#endif +#if HAVE_TEX0_VERTICES + case TEX0_VERTEX_FORMAT: + fprintf(stderr, "xyzw %.4f,%.4f,%.4f,%.4f rgba %x:%x:%x:%x st %.4f,%.4f\n", + v->v.x, v->v.y, v->v.z, v->v.w, + v->v.color.red, + v->v.color.green, + v->v.color.blue, + v->v.color.alpha, + v->v.u0, + v->v.v0); + break; +#endif +#if HAVE_TEX1_VERTICES + case TEX1_VERTEX_FORMAT: + fprintf(stderr, "xyzw %.4f,%.4f,%.4f,%.4f rgba %x:%x:%x:%x st %.4f,%.4f st %.4f,%.4f\n", + v->v.x, v->v.y, v->v.z, v->v.w, + v->v.color.red, + v->v.color.green, + v->v.color.blue, + v->v.color.alpha, + v->v.u0, + v->v.v0, + v->v.u1, + v->v.u2); + break; +#endif +#if HAVE_PTEX_VERTICES + case PROJ_TEX1_VERTEX_FORMAT: + fprintf(stderr, "xyzw %.4f,%.4f,%.4f,%.4f rgba %x:%x:%x:%x stq %.4f,%.4f,%.4f stq %.4f,%.4f,%.4f\n", + v->v.x, v->v.y, v->v.z, v->v.w, + v->v.color.red, + v->v.color.green, + v->v.color.blue, + v->v.color.alpha, + v->pv.u0, + v->pv.v0, + v->pv.q0, + v->pv.u1, + v->pv.v1, + v->pv.q1); + break; +#endif + default: + fprintf(stderr, "???\n"); + break; + } + + fprintf(stderr, "\n"); +} + + + +/* Interpolate the elements of the VB not included in typical hardware + * vertices. + * + * NOTE: All these arrays are guarenteed by tnl to be writeable and + * have good stride. + */ +#ifndef INTERP_QUALIFIER +#define INTERP_QUALIFIER static +#endif + +#define GET_COLOR(ptr, idx) ((ptr)->data[idx]) + + +INTERP_QUALIFIER void TAG(interp_extras)( GLcontext *ctx, + GLfloat t, + GLuint dst, GLuint out, GLuint in, + GLboolean force_boundary ) +{ + LOCALVARS + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + + if (VB->ColorPtr[1]) { + assert(VB->ColorPtr[1]->stride == 4 * sizeof(GLfloat)); + + INTERP_4F( t, + GET_COLOR(VB->ColorPtr[1], dst), + GET_COLOR(VB->ColorPtr[1], out), + GET_COLOR(VB->ColorPtr[1], in) ); + + if (VB->SecondaryColorPtr[1]) { + INTERP_3F( t, + GET_COLOR(VB->SecondaryColorPtr[1], dst), + GET_COLOR(VB->SecondaryColorPtr[1], out), + GET_COLOR(VB->SecondaryColorPtr[1], in) ); + } + } + + if (VB->EdgeFlag) { + VB->EdgeFlag[dst] = VB->EdgeFlag[out] || force_boundary; + } + + INTERP_VERTEX(ctx, t, dst, out, in, force_boundary); +} + +INTERP_QUALIFIER void TAG(copy_pv_extras)( GLcontext *ctx, + GLuint dst, GLuint src ) +{ + LOCALVARS + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + + if (VB->ColorPtr[1]) { + COPY_4FV( GET_COLOR(VB->ColorPtr[1], dst), + GET_COLOR(VB->ColorPtr[1], src) ); + + if (VB->SecondaryColorPtr[1]) { + COPY_4FV( GET_COLOR(VB->SecondaryColorPtr[1], dst), + GET_COLOR(VB->SecondaryColorPtr[1], src) ); + } + } + + COPY_PV_VERTEX(ctx, dst, src); +} + + +#undef INTERP_QUALIFIER +#undef GET_COLOR + +#undef IND +#undef TAG diff --git a/reactos/lib/mesa32/src/drivers/common/t_dd_vbtmp.h b/reactos/lib/mesa32/src/drivers/common/t_dd_vbtmp.h new file mode 100644 index 00000000000..14b4a28651a --- /dev/null +++ b/reactos/lib/mesa32/src/drivers/common/t_dd_vbtmp.h @@ -0,0 +1,679 @@ + +/* + * Mesa 3-D graphics library + * Version: 5.0.1 + * + * 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 + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Keith Whitwell + */ + + +/* Unlike the other templates here, this assumes quite a bit about the + * underlying hardware. Specifically it assumes a d3d-like vertex + * format, with a layout more or less constrained to look like the + * following: + * + * union { + * struct { + * float x, y, z, w; + * struct { char r, g, b, a; } color; + * struct { char r, g, b, fog; } spec; + * float u0, v0; + * float u1, v1; + * float u2, v2; + * float u3, v3; + * } v; + * struct { + * float x, y, z, w; + * struct { char r, g, b, a; } color; + * struct { char r, g, b, fog; } spec; + * float u0, v0, q0; + * float u1, v1, q1; + * float u2, v2, q2; + * float u3, v3, q3; + * } pv; + * struct { + * float x, y, z; + * struct { char r, g, b, a; } color; + * } tv; + * float f[16]; + * unsigned int ui[16]; + * unsigned char ub4[4][16]; + * } + * + + * VERTEX: hw vertex type as above + * VERTEX_COLOR: hw color struct type in VERTEX + * + * DO_XYZW: Emit xyz and maybe w coordinates. + * DO_RGBA: Emit color. + * DO_SPEC: Emit specular color. + * DO_FOG: Emit fog coordinate in specular alpha. + * DO_TEX0: Emit tex0 u,v coordinates. + * DO_TEX1: Emit tex1 u,v coordinates. + * DO_TEX2: Emit tex2 u,v coordinates. + * DO_TEX3: Emit tex3 u,v coordinates. + * DO_PTEX: Emit tex0,1,2,3 q coordinates where possible. + * + * HAVE_RGBA_COLOR: Hardware takes color in rgba order (else bgra). + * + * HAVE_HW_VIEWPORT: Hardware performs viewport transform. + * HAVE_HW_DIVIDE: Hardware performs perspective divide. + * + * HAVE_TINY_VERTICES: Hardware understands v.tv format. + * HAVE_PTEX_VERTICES: Hardware understands v.pv format. + * HAVE_NOTEX_VERTICES: Hardware understands v.v format with texcount 0. + * + * Additionally, this template assumes it is emitting *transformed* + * vertices; the modifications to emit untransformed vertices (ie. to + * t&l hardware) are probably too great to cooexist with the code + * already in this file. + * + * NOTE: The PTEX vertex format always includes TEX0 and TEX1, even if + * only TEX0 is enabled, in order to maintain a vertex size which is + * an exact number of quadwords. + */ + +#if (HAVE_HW_VIEWPORT) +#define VIEWPORT_X(dst,x) dst = x +#define VIEWPORT_Y(dst,y) dst = y +#define VIEWPORT_Z(dst,z) dst = z +#else +#define VIEWPORT_X(dst,x) dst = s[0] * x + s[12] +#define VIEWPORT_Y(dst,y) dst = s[5] * y + s[13] +#define VIEWPORT_Z(dst,z) dst = s[10] * z + s[14] +#endif + +#if (HAVE_HW_DIVIDE && !HAVE_PTEX_VERTICES) +#error "can't cope with this combination" +#endif + +#ifndef LOCALVARS +#define LOCALVARS +#endif + +#ifndef CHECK_HW_DIVIDE +#define CHECK_HW_DIVIDE 1 +#endif + +#if (HAVE_HW_DIVIDE || DO_SPEC || DO_TEX0 || DO_FOG || !HAVE_TINY_VERTICES) + +static void TAG(emit)( GLcontext *ctx, + GLuint start, GLuint end, + void *dest, + GLuint stride ) +{ + LOCALVARS + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + GLfloat (*tc0)[4], (*tc1)[4], (*fog)[4]; + GLfloat (*tc2)[4], (*tc3)[4]; + GLfloat (*col)[4], (*spec)[4]; + GLuint tc0_stride, tc1_stride, col_stride, spec_stride, fog_stride; + GLuint tc2_stride, tc3_stride; + GLuint tc0_size, tc1_size; + GLuint tc2_size, tc3_size; + GLfloat (*coord)[4]; + GLuint coord_stride; + VERTEX *v = (VERTEX *)dest; + const GLfloat *s = GET_VIEWPORT_MAT(); + const GLubyte *mask = VB->ClipMask; + int i; + +/* fprintf(stderr, "%s(big) importable %d %d..%d\n", */ +/* __FUNCTION__, VB->importable_data, start, end); */ + + if (HAVE_HW_VIEWPORT && HAVE_HW_DIVIDE && CHECK_HW_DIVIDE) { + (void) s; + coord = VB->ClipPtr->data; + coord_stride = VB->ClipPtr->stride; + } + else { + coord = VB->NdcPtr->data; + coord_stride = VB->NdcPtr->stride; + } + + if (DO_TEX3) { + const GLuint t3 = GET_TEXSOURCE(3); + tc3 = VB->TexCoordPtr[t3]->data; + tc3_stride = VB->TexCoordPtr[t3]->stride; + if (DO_PTEX) + tc3_size = VB->TexCoordPtr[t3]->size; + } + + if (DO_TEX2) { + const GLuint t2 = GET_TEXSOURCE(2); + tc2 = VB->TexCoordPtr[t2]->data; + tc2_stride = VB->TexCoordPtr[t2]->stride; + if (DO_PTEX) + tc2_size = VB->TexCoordPtr[t2]->size; + } + + if (DO_TEX1) { + const GLuint t1 = GET_TEXSOURCE(1); + tc1 = VB->TexCoordPtr[t1]->data; + tc1_stride = VB->TexCoordPtr[t1]->stride; + if (DO_PTEX) + tc1_size = VB->TexCoordPtr[t1]->size; + } + + if (DO_TEX0) { + const GLuint t0 = GET_TEXSOURCE(0); + tc0_stride = VB->TexCoordPtr[t0]->stride; + tc0 = VB->TexCoordPtr[t0]->data; + if (DO_PTEX) + tc0_size = VB->TexCoordPtr[t0]->size; + } + + if (DO_RGBA) { + col_stride = VB->ColorPtr[0]->stride; + col = VB->ColorPtr[0]->data; + } + + if (DO_SPEC) { + if (VB->SecondaryColorPtr[0]) { + spec_stride = VB->SecondaryColorPtr[0]->stride; + spec = VB->SecondaryColorPtr[0]->data; + } else { + spec = (GLfloat (*)[4])ctx->Current.Attrib[VERT_ATTRIB_COLOR1]; + spec_stride = 0; + } + } + + if (DO_FOG) { + if (VB->FogCoordPtr) { + fog = VB->FogCoordPtr->data; + fog_stride = VB->FogCoordPtr->stride; + } + else { + static GLfloat tmp[4] = {0, 0, 0, 0}; + fog = &tmp; + fog_stride = 0; + } + } + + /* May have nonstandard strides: + */ + if (start) { + STRIDE_4F(coord, start * coord_stride); + if (DO_TEX0) + STRIDE_4F(tc0, start * tc0_stride); + if (DO_TEX1) + STRIDE_4F(tc1, start * tc1_stride); + if (DO_TEX2) + STRIDE_4F(tc2, start * tc2_stride); + if (DO_TEX3) + STRIDE_4F(tc3, start * tc3_stride); + if (DO_RGBA) + STRIDE_4F(col, start * col_stride); + if (DO_SPEC) + STRIDE_4F(spec, start * spec_stride); + if (DO_FOG) + STRIDE_4F(fog, start * fog_stride); + } + + for (i=start; i < end; i++, v = (VERTEX *)((GLubyte *)v + stride)) { + if (DO_XYZW) { + if (HAVE_HW_VIEWPORT || mask[i] == 0) { + VIEWPORT_X(v->v.x, coord[0][0]); + VIEWPORT_Y(v->v.y, coord[0][1]); + VIEWPORT_Z(v->v.z, coord[0][2]); + v->v.w = coord[0][3]; + } + STRIDE_4F(coord, coord_stride); + } + if (DO_RGBA) { + UNCLAMPED_FLOAT_TO_UBYTE(v->v.color.red, col[0][0]); + UNCLAMPED_FLOAT_TO_UBYTE(v->v.color.green, col[0][1]); + UNCLAMPED_FLOAT_TO_UBYTE(v->v.color.blue, col[0][2]); + UNCLAMPED_FLOAT_TO_UBYTE(v->v.color.alpha, col[0][3]); + STRIDE_4F(col, col_stride); + } + if (DO_SPEC) { + UNCLAMPED_FLOAT_TO_UBYTE(v->v.specular.red, spec[0][0]); + UNCLAMPED_FLOAT_TO_UBYTE(v->v.specular.green, spec[0][1]); + UNCLAMPED_FLOAT_TO_UBYTE(v->v.specular.blue, spec[0][2]); + STRIDE_4F(spec, spec_stride); + } + if (DO_FOG) { + UNCLAMPED_FLOAT_TO_UBYTE(v->v.specular.alpha, fog[0][0]); + STRIDE_4F(fog, fog_stride); + } + if (DO_TEX0) { + v->v.u0 = tc0[0][0]; + v->v.v0 = tc0[0][1]; + if (DO_PTEX) { + if (HAVE_PTEX_VERTICES) { + if (tc0_size == 4) + v->pv.q0 = tc0[0][3]; + else + v->pv.q0 = 1.0; + } + else if (tc0_size == 4) { + float rhw = 1.0 / tc0[0][3]; + v->v.w *= tc0[0][3]; + v->v.u0 *= rhw; + v->v.v0 *= rhw; + } + } + STRIDE_4F(tc0, tc0_stride); + } + if (DO_TEX1) { + if (DO_PTEX) { + v->pv.u1 = tc1[0][0]; + v->pv.v1 = tc1[0][1]; + if (tc1_size == 4) + v->pv.q1 = tc1[0][3]; + else + v->pv.q1 = 1.0; + } + else { + v->v.u1 = tc1[0][0]; + v->v.v1 = tc1[0][1]; + } + STRIDE_4F(tc1, tc1_stride); + } + else if (DO_PTEX) { + *(GLuint *)&v->pv.q1 = 0; /* avoid culling on radeon */ + } + if (DO_TEX2) { + if (DO_PTEX) { + v->pv.u2 = tc2[0][0]; + v->pv.v2 = tc2[0][1]; + if (tc2_size == 4) + v->pv.q2 = tc2[0][3]; + else + v->pv.q2 = 1.0; + } + else { + v->v.u2 = tc2[0][0]; + v->v.v2 = tc2[0][1]; + } + STRIDE_4F(tc2, tc2_stride); + } + if (DO_TEX3) { + if (DO_PTEX) { + v->pv.u3 = tc3[0][0]; + v->pv.v3 = tc3[0][1]; + if (tc3_size == 4) + v->pv.q3 = tc3[0][3]; + else + v->pv.q3 = 1.0; + } + else { + v->v.u3 = tc3[0][0]; + v->v.v3 = tc3[0][1]; + } + STRIDE_4F(tc3, tc3_stride); + } + } + +} +#else + +#if HAVE_HW_DIVIDE +#error "cannot use tiny vertices with hw perspective divide" +#endif + +static void TAG(emit)( GLcontext *ctx, GLuint start, GLuint end, + void *dest, GLuint stride ) +{ + LOCALVARS + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + GLfloat (*col)[4]; + GLuint col_stride; + GLfloat (*coord)[4] = VB->NdcPtr->data; + GLuint coord_stride = VB->NdcPtr->stride; + GLfloat *v = (GLfloat *)dest; + const GLubyte *mask = VB->ClipMask; + const GLfloat *s = GET_VIEWPORT_MAT(); + int i; + + (void) s; + + ASSERT(stride == 4); + + col = VB->ColorPtr[0]->data; + col_stride = VB->ColorPtr[0]->stride; + +/* fprintf(stderr, "%s(small) importable %x\n", */ +/* __FUNCTION__, VB->importable_data); */ + + /* Pack what's left into a 4-dword vertex. Color is in a different + * place, and there is no 'w' coordinate. + */ + if (start) { + STRIDE_4F(coord, start * coord_stride); + STRIDE_4F(col, start * col_stride); + } + + for (i=start; i < end; i++, v+=4) { + if (DO_XYZW) { + if (HAVE_HW_VIEWPORT || mask[i] == 0) { + VIEWPORT_X(v[0], coord[0][0]); + VIEWPORT_Y(v[1], coord[0][1]); + VIEWPORT_Z(v[2], coord[0][2]); + } + STRIDE_4F( coord, coord_stride ); + } + if (DO_RGBA) { + VERTEX_COLOR *c = (VERTEX_COLOR *)&v[3]; + UNCLAMPED_FLOAT_TO_UBYTE(c->red, col[0][0]); + UNCLAMPED_FLOAT_TO_UBYTE(c->green, col[0][1]); + UNCLAMPED_FLOAT_TO_UBYTE(c->blue, col[0][2]); + UNCLAMPED_FLOAT_TO_UBYTE(c->alpha, col[0][3]); + STRIDE_4F( col, col_stride ); + } +/* fprintf(stderr, "vert %d: %.2f %.2f %.2f %x\n", */ +/* i, v[0], v[1], v[2], *(int *)&v[3]); */ + } +} + +#endif /* emit */ + +#if (DO_XYZW) && (DO_RGBA) + + +#if (HAVE_PTEX_VERTICES) +static GLboolean TAG(check_tex_sizes)( GLcontext *ctx ) +{ + LOCALVARS + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + + /* Force 'missing' texcoords to something valid. + */ + if (DO_TEX3 && VB->TexCoordPtr[2] == 0) + VB->TexCoordPtr[2] = VB->TexCoordPtr[3]; + + if (DO_TEX2 && VB->TexCoordPtr[1] == 0) + VB->TexCoordPtr[1] = VB->TexCoordPtr[2]; + + if (DO_TEX1 && VB->TexCoordPtr[0] == 0) + VB->TexCoordPtr[0] = VB->TexCoordPtr[1]; + + if (DO_PTEX) + return GL_TRUE; + + if ((DO_TEX3 && VB->TexCoordPtr[GET_TEXSOURCE(3)]->size == 4) || + (DO_TEX2 && VB->TexCoordPtr[GET_TEXSOURCE(2)]->size == 4) || + (DO_TEX1 && VB->TexCoordPtr[GET_TEXSOURCE(1)]->size == 4) || + (DO_TEX0 && VB->TexCoordPtr[GET_TEXSOURCE(0)]->size == 4)) + return GL_FALSE; + + return GL_TRUE; +} +#else +static GLboolean TAG(check_tex_sizes)( GLcontext *ctx ) +{ + LOCALVARS + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + + /* Force 'missing' texcoords to something valid. + */ + if (DO_TEX3 && VB->TexCoordPtr[2] == 0) + VB->TexCoordPtr[2] = VB->TexCoordPtr[3]; + + if (DO_TEX2 && VB->TexCoordPtr[1] == 0) + VB->TexCoordPtr[1] = VB->TexCoordPtr[2]; + + if (DO_TEX1 && VB->TexCoordPtr[0] == 0) + VB->TexCoordPtr[0] = VB->TexCoordPtr[1]; + + if (DO_PTEX) + return GL_TRUE; + + /* No hardware support for projective texture. Can fake it for + * TEX0 only. + */ + if ((DO_TEX3 && VB->TexCoordPtr[GET_TEXSOURCE(3)]->size == 4) || + (DO_TEX2 && VB->TexCoordPtr[GET_TEXSOURCE(2)]->size == 4) || + (DO_TEX1 && VB->TexCoordPtr[GET_TEXSOURCE(1)]->size == 4)) { + PTEX_FALLBACK(); + return GL_FALSE; + } + + if (DO_TEX0 && VB->TexCoordPtr[GET_TEXSOURCE(0)]->size == 4) { + if (DO_TEX1 || DO_TEX2 || DO_TEX3) { + PTEX_FALLBACK(); + } + return GL_FALSE; + } + + return GL_TRUE; +} +#endif /* ptex */ + + +static void TAG(interp)( GLcontext *ctx, + GLfloat t, + GLuint edst, GLuint eout, GLuint ein, + GLboolean force_boundary ) +{ + LOCALVARS + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + GLubyte *ddverts = GET_VERTEX_STORE(); + GLuint shift = GET_VERTEX_STRIDE_SHIFT(); + const GLfloat *dstclip = VB->ClipPtr->data[edst]; + GLfloat w; + const GLfloat *s = GET_VIEWPORT_MAT(); + + VERTEX *dst = (VERTEX *)(ddverts + (edst << shift)); + VERTEX *in = (VERTEX *)(ddverts + (ein << shift)); + VERTEX *out = (VERTEX *)(ddverts + (eout << shift)); + + (void)s; + + if (HAVE_HW_DIVIDE && CHECK_HW_DIVIDE) { + VIEWPORT_X( dst->v.x, dstclip[0] ); + VIEWPORT_Y( dst->v.y, dstclip[1] ); + VIEWPORT_Z( dst->v.z, dstclip[2] ); + w = dstclip[3]; + } + else { + w = 1.0 / dstclip[3]; + VIEWPORT_X( dst->v.x, dstclip[0] * w ); + VIEWPORT_Y( dst->v.y, dstclip[1] * w ); + VIEWPORT_Z( dst->v.z, dstclip[2] * w ); + } + + if ((HAVE_HW_DIVIDE && CHECK_HW_DIVIDE) || + DO_FOG || DO_SPEC || DO_TEX0 || DO_TEX1 || + DO_TEX2 || DO_TEX3 || !HAVE_TINY_VERTICES) { + + dst->v.w = w; + + INTERP_UB( t, dst->ub4[4][0], out->ub4[4][0], in->ub4[4][0] ); + INTERP_UB( t, dst->ub4[4][1], out->ub4[4][1], in->ub4[4][1] ); + INTERP_UB( t, dst->ub4[4][2], out->ub4[4][2], in->ub4[4][2] ); + INTERP_UB( t, dst->ub4[4][3], out->ub4[4][3], in->ub4[4][3] ); + + if (DO_SPEC) { + INTERP_UB( t, dst->v.specular.red, out->v.specular.red, in->v.specular.red ); + INTERP_UB( t, dst->v.specular.green, out->v.specular.green, in->v.specular.green ); + INTERP_UB( t, dst->v.specular.blue, out->v.specular.blue, in->v.specular.blue ); + } + if (DO_FOG) { + INTERP_UB( t, dst->v.specular.alpha, out->v.specular.alpha, in->v.specular.alpha ); + } + if (DO_TEX0) { + if (DO_PTEX) { + if (HAVE_PTEX_VERTICES) { + INTERP_F( t, dst->pv.u0, out->pv.u0, in->pv.u0 ); + INTERP_F( t, dst->pv.v0, out->pv.v0, in->pv.v0 ); + INTERP_F( t, dst->pv.q0, out->pv.q0, in->pv.q0 ); + } else { + GLfloat wout = VB->NdcPtr->data[eout][3]; + GLfloat win = VB->NdcPtr->data[ein][3]; + GLfloat qout = out->pv.w / wout; + GLfloat qin = in->pv.w / win; + GLfloat qdst, rqdst; + + ASSERT( !HAVE_HW_DIVIDE ); + + INTERP_F( t, dst->v.u0, out->v.u0 * qout, in->v.u0 * qin ); + INTERP_F( t, dst->v.v0, out->v.v0 * qout, in->v.v0 * qin ); + INTERP_F( t, qdst, qout, qin ); + + rqdst = 1.0 / qdst; + dst->v.u0 *= rqdst; + dst->v.v0 *= rqdst; + dst->v.w *= rqdst; + } + } + else { + INTERP_F( t, dst->v.u0, out->v.u0, in->v.u0 ); + INTERP_F( t, dst->v.v0, out->v.v0, in->v.v0 ); + } + } + if (DO_TEX1) { + if (DO_PTEX) { + INTERP_F( t, dst->pv.u1, out->pv.u1, in->pv.u1 ); + INTERP_F( t, dst->pv.v1, out->pv.v1, in->pv.v1 ); + INTERP_F( t, dst->pv.q1, out->pv.q1, in->pv.q1 ); + } else { + INTERP_F( t, dst->v.u1, out->v.u1, in->v.u1 ); + INTERP_F( t, dst->v.v1, out->v.v1, in->v.v1 ); + } + } + else if (DO_PTEX) { + dst->pv.q1 = 0.0; /* must be a valid float on radeon */ + } + if (DO_TEX2) { + if (DO_PTEX) { + INTERP_F( t, dst->pv.u2, out->pv.u2, in->pv.u2 ); + INTERP_F( t, dst->pv.v2, out->pv.v2, in->pv.v2 ); + INTERP_F( t, dst->pv.q2, out->pv.q2, in->pv.q2 ); + } else { + INTERP_F( t, dst->v.u2, out->v.u2, in->v.u2 ); + INTERP_F( t, dst->v.v2, out->v.v2, in->v.v2 ); + } + } + if (DO_TEX3) { + if (DO_PTEX) { + INTERP_F( t, dst->pv.u3, out->pv.u3, in->pv.u3 ); + INTERP_F( t, dst->pv.v3, out->pv.v3, in->pv.v3 ); + INTERP_F( t, dst->pv.q3, out->pv.q3, in->pv.q3 ); + } else { + INTERP_F( t, dst->v.u3, out->v.u3, in->v.u3 ); + INTERP_F( t, dst->v.v3, out->v.v3, in->v.v3 ); + } + } + } else { + /* 4-dword vertex. Color is in v[3] and there is no oow coordinate. + */ + INTERP_UB( t, dst->ub4[3][0], out->ub4[3][0], in->ub4[3][0] ); + INTERP_UB( t, dst->ub4[3][1], out->ub4[3][1], in->ub4[3][1] ); + INTERP_UB( t, dst->ub4[3][2], out->ub4[3][2], in->ub4[3][2] ); + INTERP_UB( t, dst->ub4[3][3], out->ub4[3][3], in->ub4[3][3] ); + } +} + +#endif /* rgba && xyzw */ + + +static void TAG(init)( void ) +{ + setup_tab[IND].emit = TAG(emit); + +#if (DO_XYZW && DO_RGBA) + setup_tab[IND].check_tex_sizes = TAG(check_tex_sizes); + setup_tab[IND].interp = TAG(interp); +#endif + + if (DO_SPEC) + setup_tab[IND].copy_pv = copy_pv_rgba4_spec5; + else if (HAVE_HW_DIVIDE || DO_SPEC || DO_FOG || DO_TEX0 || DO_TEX1 || + DO_TEX2 || DO_TEX3 || !HAVE_TINY_VERTICES) + setup_tab[IND].copy_pv = copy_pv_rgba4; + else + setup_tab[IND].copy_pv = copy_pv_rgba3; + + if (DO_TEX3) { + if (DO_PTEX) { + ASSERT(HAVE_PTEX_VERTICES); + setup_tab[IND].vertex_format = PROJ_TEX3_VERTEX_FORMAT; + setup_tab[IND].vertex_size = 18; + setup_tab[IND].vertex_stride_shift = 7; + } + else { + setup_tab[IND].vertex_format = TEX3_VERTEX_FORMAT; + setup_tab[IND].vertex_size = 14; + setup_tab[IND].vertex_stride_shift = 6; + } + } + else if (DO_TEX2) { + if (DO_PTEX) { + ASSERT(HAVE_PTEX_VERTICES); + setup_tab[IND].vertex_format = PROJ_TEX3_VERTEX_FORMAT; + setup_tab[IND].vertex_size = 18; + setup_tab[IND].vertex_stride_shift = 7; + } + else { + setup_tab[IND].vertex_format = TEX2_VERTEX_FORMAT; + setup_tab[IND].vertex_size = 12; + setup_tab[IND].vertex_stride_shift = 6; + } + } + else if (DO_TEX1) { + if (DO_PTEX) { + ASSERT(HAVE_PTEX_VERTICES); + setup_tab[IND].vertex_format = PROJ_TEX1_VERTEX_FORMAT; + setup_tab[IND].vertex_size = 12; + setup_tab[IND].vertex_stride_shift = 6; + } + else { + setup_tab[IND].vertex_format = TEX1_VERTEX_FORMAT; + setup_tab[IND].vertex_size = 10; + setup_tab[IND].vertex_stride_shift = 6; + } + } + else if (DO_TEX0) { + if (DO_PTEX && HAVE_PTEX_VERTICES) { + setup_tab[IND].vertex_format = PROJ_TEX1_VERTEX_FORMAT; + setup_tab[IND].vertex_size = 12; + setup_tab[IND].vertex_stride_shift = 6; + } else { + setup_tab[IND].vertex_format = TEX0_VERTEX_FORMAT; + setup_tab[IND].vertex_size = 8; + setup_tab[IND].vertex_stride_shift = 5; + } + } + else if (!HAVE_HW_DIVIDE && !DO_SPEC && !DO_FOG && HAVE_TINY_VERTICES) { + setup_tab[IND].vertex_format = TINY_VERTEX_FORMAT; + setup_tab[IND].vertex_size = 4; + setup_tab[IND].vertex_stride_shift = 4; + } else if (HAVE_NOTEX_VERTICES) { + setup_tab[IND].vertex_format = NOTEX_VERTEX_FORMAT; + setup_tab[IND].vertex_size = 6; + setup_tab[IND].vertex_stride_shift = 5; + } else { + setup_tab[IND].vertex_format = TEX0_VERTEX_FORMAT; + setup_tab[IND].vertex_size = 8; + setup_tab[IND].vertex_stride_shift = 5; + } + + assert(setup_tab[IND].vertex_size * 4 <= + 1 << setup_tab[IND].vertex_stride_shift); +} + + +#undef IND +#undef TAG diff --git a/reactos/lib/mesa32/src/drivers/common/t_dd_vertex.h b/reactos/lib/mesa32/src/drivers/common/t_dd_vertex.h new file mode 100644 index 00000000000..d45dd09fbd7 --- /dev/null +++ b/reactos/lib/mesa32/src/drivers/common/t_dd_vertex.h @@ -0,0 +1,78 @@ + +/* + * Mesa 3-D graphics library + * Version: 4.0.3 + * + * 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 + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Keith Whitwell + */ + +typedef struct { + GLfloat x, y, z, w; +} TAG(_coord_t); + +#ifdef COLOR_IS_RGBA +typedef struct { +#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN + GLubyte alpha, blue, green, red; +#else + GLubyte red, green, blue, alpha; +#endif +} TAG(_color_t); +#else +typedef struct { +#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN + GLubyte alpha, red, green, blue; +#else + GLubyte blue, green, red, alpha; +#endif +} TAG(_color_t); +#endif + +typedef union { + struct { + GLfloat x, y, z, w; + TAG(_color_t) color; + TAG(_color_t) specular; + GLfloat u0, v0; + GLfloat u1, v1; + GLfloat u2, v2; + GLfloat u3, v3; + } v; + struct { + GLfloat x, y, z, w; + TAG(_color_t) color; + TAG(_color_t) specular; + GLfloat u0, v0, q0; + GLfloat u1, v1, q1; + GLfloat u2, v2, q2; + GLfloat u3, v3, q3; + } pv; + struct { + GLfloat x, y, z; + TAG(_color_t) color; + } tv; + GLfloat f[24]; + GLuint ui[24]; + GLubyte ub4[24][4]; +} TAG(Vertex), *TAG(VertexPtr); + diff --git a/reactos/lib/mesa32/src/drivers/dos/blit.S b/reactos/lib/mesa32/src/drivers/dos/blit.S new file mode 100644 index 00000000000..1f1c77bd563 --- /dev/null +++ b/reactos/lib/mesa32/src/drivers/dos/blit.S @@ -0,0 +1,210 @@ +/* + * Mesa 3-D graphics library + * Version: 4.0 + * + * 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 + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * DOS/DJGPP device driver v1.4 for Mesa + * + * Copyright (C) 2002 - Borca Daniel + * Email : dborca@yahoo.com + * Web : http://www.geocities.com/dborca + */ + + +#include "x86/assyntax.h" + + + FILE("blit.S") + +/* + * extern unsigned int vesa_gran_mask, vesa_gran_shift; + * extern int vl_video_selector; + + * extern void *vl_current_draw_buffer; + * extern int vl_current_stride, vl_current_height; + * extern int vl_current_offset, vl_current_delta; + */ +EXTERN _vesa_gran_mask, _vesa_gran_shift +EXTERN _vl_video_selector + +EXTERN _vl_current_draw_buffer +EXTERN _vl_current_stride, _vl_current_height +EXTERN _vl_current_offset, _vl_current_delta + + SEG_TEXT + USE32 + +/* Desc: VESA bank switching routine (BIOS) + * + * In : EBX=0, EDX = bank number + * Out : - + * + * Note: thrashes EAX + */ + ALIGNTEXT32 +_vesa_swbankBIOS: + MOV_W (CONST(0x4f05), AX) + INT (CONST(0x10)) + RET + + ALIGNTEXT8 + GLOBL _vesa_swbank +_vesa_swbank: D_LONG _vesa_swbankBIOS + +/* Desc: void vesa_b_dump_virtual (void); + * + * In : - + * Out : - + * + * Note: uses current draw buffer + */ + ALIGNTEXT32 + GLOBL _vesa_b_dump_virtual +_vesa_b_dump_virtual: + CLD + PUSH_SR (ES) + PUSH_L (EBX) + PUSH_L (ESI) + PUSH_L (EDI) + PUSH_L (EBP) + MOV_SR (CONTENT(_vl_video_selector), ES) + MOV_L (CONTENT(_vl_current_draw_buffer), ESI) + MOV_L (CONTENT(_vl_current_offset), EDI) + MOV_L (CONTENT(_vesa_gran_shift), ECX) + MOV_L (CONTENT(_vesa_gran_mask), EBP) + MOV_L (EDI, EDX) + XOR_L (EBX, EBX) + AND_L (EBP, EDI) + SHR_L (CL, EDX) + INC_L (EBP) + CALL (VARINDIRECT(_vesa_swbank)) + MOV_L (CONTENT(_vl_current_stride), ECX) + MOV_L (CONTENT(_vl_current_height), EAX) + MOV_L (CONTENT(_vl_current_delta), EBX) + SHR_L (CONST(2), ECX) + ALIGNTEXT4 + TLBL(0): + PUSH_L (ECX) + ALIGNTEXT4 + TLBL(1): + CMP_L (EBP, EDI) + jb TLBL(2) + PUSH_L (EAX) + PUSH_L (EBX) + INC_L (EDX) + XOR_L (EBX, EBX) + CALL (VARINDIRECT(_vesa_swbank)) + POP_L (EBX) + POP_L (EAX) + SUB_L (EBP, EDI) + ALIGNTEXT4 + TLBL(2): + MOVS_L + DEC_L (ECX) + jnz TLBL(1) + POP_L (ECX) + ADD_L (EBX, EDI) + DEC_L (EAX) + jnz TLBL(0) + POP_L (EBP) + POP_L (EDI) + POP_L (ESI) + POP_L (EBX) + POP_SR (ES) + RET + +/* Desc: void vesa_l_dump_virtual (void); + * + * In : - + * Out : - + * + * Note: uses current draw buffer + */ + ALIGNTEXT32 + GLOBL _vesa_l_dump_virtual +_vesa_l_dump_virtual: + CLD + PUSH_SR (ES) + PUSH_L (ESI) + PUSH_L (EDI) + MOV_SR (CONTENT(_vl_video_selector), ES) + MOV_L (CONTENT(_vl_current_draw_buffer), ESI) + MOV_L (CONTENT(_vl_current_offset), EDI) + MOV_L (CONTENT(_vl_current_stride), ECX) + MOV_L (CONTENT(_vl_current_height), EDX) + MOV_L (CONTENT(_vl_current_delta), EAX) + SHR_L (CONST(2), ECX) + ALIGNTEXT4 + TLBL(0): + PUSH_L (ECX) + REP MOVS_L + POP_L (ECX) + ADD_L (EAX, EDI) + DEC_L (EDX) + jnz TLBL(0) + POP_L (EDI) + POP_L (ESI) + POP_SR (ES) + RET + +/* Desc: void vesa_l_dump_virtual_mmx (void); + * + * In : - + * Out : - + * + * Note: uses current draw buffer + */ + ALIGNTEXT32 + GLOBL _vesa_l_dump_virtual_mmx +_vesa_l_dump_virtual_mmx: +#ifdef USE_MMX_ASM + PUSH_L (ESI) + PUSH_L (EDI) + MOV_SR (CONTENT(_vl_video_selector), FS) + MOV_L (CONTENT(_vl_current_draw_buffer), ESI) + MOV_L (CONTENT(_vl_current_offset), EDI) + MOV_L (CONTENT(_vl_current_stride), ECX) + MOV_L (CONTENT(_vl_current_height), EDX) + MOV_L (CONTENT(_vl_current_delta), EAX) + SHR_L (CONST(3), ECX) + ALIGNTEXT4 + TLBL(0): + PUSH_L (ECX) + ALIGNTEXT4 + TLBL(1): + MOVQ (REGIND(ESI), MM0) + ADD_L (CONST(8), ESI) + SEGFS + MOVQ (MM0, REGIND(EDI)) + ADD_L (CONST(8), EDI) + DEC_L (ECX) + jnz TLBL(1) + POP_L (ECX) + ADD_L (EAX, EDI) + DEC_L (EDX) + jnz TLBL(0) + POP_L (EDI) + POP_L (ESI) + EMMS +#endif + RET diff --git a/reactos/lib/mesa32/src/drivers/dos/dmesa.c b/reactos/lib/mesa32/src/drivers/dos/dmesa.c new file mode 100644 index 00000000000..54323713864 --- /dev/null +++ b/reactos/lib/mesa32/src/drivers/dos/dmesa.c @@ -0,0 +1,1418 @@ +/* + * Mesa 3-D graphics library + * Version: 5.1 + * + * 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 + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * DOS/DJGPP device driver v1.5 for Mesa + * + * Copyright (c) 2003 - Borca Daniel + * Email : dborca@users.sourceforge.net + * Web : http://www.geocities.com/dborca + */ + + +#include "glheader.h" +#include "context.h" +#ifndef FX +#include "bufferobj.h" +#include "extensions.h" +#include "macros.h" +#include "matrix.h" +#include "mtypes.h" +#include "texformat.h" +#include "teximage.h" +#include "texstore.h" +#include "imports.h" +#include "array_cache/acache.h" +#include "swrast/s_context.h" +#include "swrast/s_depth.h" +#include "swrast/s_lines.h" +#include "swrast/s_triangle.h" +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "tnl/tnl.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" +#include "video.h" +#else /* FX */ +#include "GL/fxmesa.h" +#endif /* FX */ + +#include "GL/dmesa.h" + + + +/* + * In C++ terms, this class derives from the GLvisual class. + * Add system-specific fields to it. + */ +struct dmesa_visual { + GLvisual gl_visual; + GLboolean db_flag; /* double buffered? */ + GLboolean rgb_flag; /* RGB mode? */ + GLboolean sw_alpha; /* use Mesa's alpha buffer? */ + GLuint depth; /* bits per pixel (1, 8, 24, etc) */ + int zbuffer; /* Z=buffer: 0=no, 1=SW, -1=HW */ +}; + +/* + * In C++ terms, this class derives from the GLframebuffer class. + * Add system-specific fields to it. + */ +struct dmesa_buffer { + GLframebuffer gl_buffer; /* The depth, stencil, accum, etc buffers */ + void *the_window; /* your window handle, etc */ + + int xpos, ypos; /* position */ + int width, height; /* size in pixels */ +}; + +/* + * In C++ terms, this class derives from the GLcontext class. + * Add system-specific fields to it. + */ +struct dmesa_context { + GLcontext gl_ctx; /* the core library context */ + DMesaVisual visual; + DMesaBuffer Buffer; + GLuint ClearColor; + GLuint ClearIndex; + /* etc... */ +}; + + + +#ifndef FX +/**************************************************************************** + * Read/Write pixels + ***************************************************************************/ +#define FLIP(y) (dmesa->Buffer->height - (y) - 1) +#define FLIP2(y) (_b_ - (y)) + +#define DSTRIDE dmesa->Buffer->width + +/**************************************************************************** + * RGB[A] + ***************************************************************************/ +static void write_rgba_span (const GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLubyte rgba[][4], const GLubyte mask[]) +{ + const DMesaContext dmesa = (DMesaContext)ctx; + GLuint i, offset; + + offset = DSTRIDE * FLIP(y) + x; + if (mask) { + /* draw some pixels */ + for (i=0; iBuffer->height - 1; + + if (mask) { + /* draw some pixels */ + for (i=0; iBuffer->height - 1, rgba = vl_mixrgba(color); + + if (mask) { + /* draw some pixels */ + for (i=0; iBuffer->height - 1; + + if (mask) { + /* read some pixels */ + for (i=0; iBuffer->height - 1; + + if (mask) { + /* draw some pixels */ + for (i=0; iBuffer->height - 1; + + if (mask) { + /* draw some pixels */ + for (i=0; iBuffer->height - 1; + + if (mask) { + /* read some pixels */ + for (i=0; iBuffer->height - 1; \ + GLuint _w_ = dmesa->Buffer->width; \ + GLuint rgb = vl_mixrgb(v2->color); + +#define RENDER_SPAN(span) \ + GLuint i, offset = FLIP2(span.y)*_w_ + span.x; \ + for (i = 0; i < span.end; i++, offset++) { \ + vl_putpixel(offset, rgb); \ + } + +#include "swrast/s_tritemp.h" + + + +/* + * Z-less flat triangle. + */ +#define NAME tri_rgb_flat_zless + +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE + +#define SETUP_CODE \ + const DMesaContext dmesa = (DMesaContext)ctx; \ + GLuint _b_ = dmesa->Buffer->height - 1; \ + GLuint _w_ = dmesa->Buffer->width; \ + GLuint rgb = vl_mixrgb(v2->color); + +#define RENDER_SPAN(span) \ + GLuint i, offset = FLIP2(span.y)*_w_ + span.x; \ + for (i = 0; i < span.end; i++, offset++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + vl_putpixel(offset, rgb); \ + zRow[i] = z; \ + } \ + span.z += span.zStep; \ + } + +#include "swrast/s_tritemp.h" + + + +/* + * NON-depth-buffered iterated triangle. + */ +#define NAME tri_rgb_iter + +#define INTERP_RGB 1 + +#define SETUP_CODE \ + const DMesaContext dmesa = (DMesaContext)ctx; \ + GLuint _b_ = dmesa->Buffer->height - 1; \ + GLuint _w_ = dmesa->Buffer->width; + +#define RENDER_SPAN(span) \ + GLuint i, offset = FLIP2(span.y)*_w_ + span.x; \ + for (i = 0; i < span.end; i++, offset++) { \ + vl_putpixel(offset, vl_mixfix(span.red, span.green, span.blue)); \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + } + +#include "swrast/s_tritemp.h" + + + +/* + * Z-less iterated triangle. + */ +#define NAME tri_rgb_iter_zless + +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define INTERP_RGB 1 + +#define SETUP_CODE \ + const DMesaContext dmesa = (DMesaContext)ctx; \ + GLuint _b_ = dmesa->Buffer->height - 1; \ + GLuint _w_ = dmesa->Buffer->width; + +#define RENDER_SPAN(span) \ + GLuint i, offset = FLIP2(span.y)*_w_ + span.x; \ + for (i = 0; i < span.end; i++, offset++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + vl_putpixel(offset, vl_mixfix(span.red, span.green, span.blue));\ + zRow[i] = z; \ + } \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + span.z += span.zStep; \ + } + +#include "swrast/s_tritemp.h" + + + +/* + * Analyze context state to see if we can provide a fast triangle function + * Otherwise, return NULL. + */ +static swrast_tri_func dmesa_choose_tri_function (GLcontext *ctx) +{ + const SWcontext *swrast = SWRAST_CONTEXT(ctx); + + if ((ctx->RenderMode != GL_RENDER) + || (ctx->Polygon.SmoothFlag) + || (ctx->Polygon.StippleFlag) + || (ctx->Texture._EnabledUnits) + || (swrast->_RasterMask & MULTI_DRAW_BIT) + || (ctx->Polygon.CullFlag && ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK)) { + return (swrast_tri_func)NULL; + } + + if (swrast->_RasterMask==DEPTH_BIT + && ctx->Depth.Func==GL_LESS + && ctx->Depth.Mask==GL_TRUE + && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) { + return (ctx->Light.ShadeModel==GL_SMOOTH) ? tri_rgb_iter_zless : tri_rgb_flat_zless; + } + + if (swrast->_RasterMask==0) { /* no depth test */ + return (ctx->Light.ShadeModel==GL_SMOOTH) ? tri_rgb_iter : tri_rgb_flat; + } + + return (swrast_tri_func)NULL; +} + + + +/* Override for the swrast triangle-selection function. Try to use one + * of our internal triangle functions, otherwise fall back to the + * standard swrast functions. + */ +static void dmesa_choose_tri (GLcontext *ctx) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + + if (!(swrast->Triangle=dmesa_choose_tri_function(ctx))) + _swrast_choose_triangle(ctx); +} + + + +/**************************************************************************** + * Optimized line rendering + ***************************************************************************/ + +/* + * NON-depth-buffered flat line. + */ +#define NAME line_rgb_flat + +#define INTERP_XY 1 +#define CLIP_HACK 1 + +#define SETUP_CODE \ + const DMesaContext dmesa = (DMesaContext)ctx; \ + GLuint _b_ = dmesa->Buffer->height - 1; \ + GLuint _w_ = dmesa->Buffer->width; \ + GLuint rgb = vl_mixrgb(vert1->color); + +#define PLOT(X,Y) vl_putpixel(FLIP2(Y) * _w_ + X, rgb); + +#include "swrast/s_linetemp.h" + + + +/* + * Z-less flat line. + */ +#define NAME line_rgb_flat_zless + +#define INTERP_XY 1 +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define CLIP_HACK 1 + +#define SETUP_CODE \ + const DMesaContext dmesa = (DMesaContext)ctx; \ + GLuint _b_ = dmesa->Buffer->height - 1; \ + GLuint _w_ = dmesa->Buffer->width; \ + GLuint rgb = vl_mixrgb(vert1->color); + +#define PLOT(X,Y) \ + if (Z < *zPtr) { \ + *zPtr = Z; \ + vl_putpixel(FLIP2(Y) * _w_ + X, rgb); \ + } + +#include "swrast/s_linetemp.h" + + + +/* + * NON-depth-buffered iterated line. + */ +#define line_rgb_iter NULL + + + +/* + * Z-less iterated line. + */ +#define line_rgb_iter_zless NULL + + + +/* + * Analyze context state to see if we can provide a fast line function + * Otherwise, return NULL. + */ +static swrast_line_func dmesa_choose_line_function (GLcontext *ctx) +{ + const SWcontext *swrast = SWRAST_CONTEXT(ctx); + + if ((ctx->RenderMode != GL_RENDER) + || (ctx->Line.SmoothFlag) + || (ctx->Texture._EnabledUnits) + || (ctx->Line.StippleFlag) + || (swrast->_RasterMask & MULTI_DRAW_BIT) + || (ctx->Line.Width!=1.0F)) { + return (swrast_line_func)NULL; + } + + if (swrast->_RasterMask==DEPTH_BIT + && ctx->Depth.Func==GL_LESS + && ctx->Depth.Mask==GL_TRUE + && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) { + return (ctx->Light.ShadeModel==GL_SMOOTH) ? line_rgb_iter_zless : line_rgb_flat_zless; + } + + if (swrast->_RasterMask==0) { /* no depth test */ + return (ctx->Light.ShadeModel==GL_SMOOTH) ? line_rgb_iter : line_rgb_flat; + } + + return (swrast_line_func)NULL; +} + + + +/* Override for the swrast line-selection function. Try to use one + * of our internal line functions, otherwise fall back to the + * standard swrast functions. + */ +static void dmesa_choose_line (GLcontext *ctx) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + + if (!(swrast->Line=dmesa_choose_line_function(ctx))) + _swrast_choose_line(ctx); +} + + + +/**************************************************************************** + * Miscellaneous device driver funcs + ***************************************************************************/ + +static void clear_index (GLcontext *ctx, GLuint index) +{ + ((DMesaContext)ctx)->ClearIndex = index; +} + +static void clear_color (GLcontext *ctx, const GLfloat color[4]) +{ + GLubyte col[4]; + CLAMPED_FLOAT_TO_UBYTE(col[0], color[0]); + CLAMPED_FLOAT_TO_UBYTE(col[1], color[1]); + CLAMPED_FLOAT_TO_UBYTE(col[2], color[2]); + CLAMPED_FLOAT_TO_UBYTE(col[3], color[3]); + ((DMesaContext)ctx)->ClearColor = vl_mixrgba(col); +} + + + +static void clear (GLcontext *ctx, GLbitfield mask, GLboolean all, + GLint x, GLint y, GLint width, GLint height) +{ + const DMesaContext c = (DMesaContext)ctx; + const GLuint *colorMask = (GLuint *)&ctx->Color.ColorMask; + +/* + * Clear the specified region of the buffers indicated by 'mask' + * using the clear color or index as specified by one of the two + * functions above. + * If all==GL_TRUE, clear whole buffer, else just clear region defined + * by x,y,width,height + */ + + /* we can't handle color or index masking */ + if ((*colorMask == 0xffffffff) && (ctx->Color.IndexMask == 0xffffffff)) { + if (mask & DD_BACK_LEFT_BIT) { + int color = c->visual->rgb_flag ? c->ClearColor : c->ClearIndex; + + if (all) { + vl_clear(color); + } else { + vl_rect(x, y, width, height, color); + } + + mask &= ~DD_BACK_LEFT_BIT; + } + } + + if (mask) { + _swrast_Clear(ctx, mask, all, x, y, width, height); + } +} + + + +/* + * This function is called to specify which buffer to read and write + * for software rasterization (swrast) fallbacks. This doesn't necessarily + * correspond to glDrawBuffer() or glReadBuffer() calls. + */ +static void set_buffer (GLcontext *ctx, GLframebuffer *colorBuffer, GLuint bufferBit) +{ + /* + * XXX todo - examine bufferBit and set read/write pointers + */ + /* Normally, we would have + * ctx->Driver.ReadBuffer == set_read_buffer + * ctx->Driver.DrawBuffer == set_draw_buffer + * and make sure set_draw_buffer calls _swrast_DrawBuffer, + * which in turn will call this routine via dd->SetBuffer. + */ +} + + + +/* + * Return the width and height of the current buffer. + * If anything special has to been done when the buffer/window is + * resized, do it now. + */ +static void get_buffer_size (GLframebuffer *buffer, GLuint *width, GLuint *height) +{ + DMesaBuffer b = (DMesaBuffer)buffer; + + *width = b->width; + *height = b->height; +} + + + +static const GLubyte* get_string (GLcontext *ctx, GLenum name) +{ + switch (name) { + case GL_RENDERER: + return (const GLubyte *)"Mesa DJGPP" + "\0port (c) Borca Daniel dec-2003"; + default: + return NULL; + } +} + + + +static void finish (GLcontext *ctx) +{ + /* + * XXX todo - OPTIONAL FUNCTION: implements glFinish if possible + */ +} + + + +static void flush (GLcontext *ctx) +{ + /* + * XXX todo - OPTIONAL FUNCTION: implements glFlush if possible + */ +} + + + +/**************************************************************************** + * State + ***************************************************************************/ +#define DMESA_NEW_LINE (_NEW_LINE | \ + _NEW_TEXTURE | \ + _NEW_LIGHT | \ + _NEW_DEPTH | \ + _NEW_RENDERMODE | \ + _SWRAST_NEW_RASTERMASK) + +#define DMESA_NEW_TRIANGLE (_NEW_POLYGON | \ + _NEW_TEXTURE | \ + _NEW_LIGHT | \ + _NEW_DEPTH | \ + _NEW_RENDERMODE | \ + _SWRAST_NEW_RASTERMASK) + +/* Extend the software rasterizer with our line and triangle + * functions. + */ +static void dmesa_register_swrast_functions (GLcontext *ctx) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + + swrast->choose_line = dmesa_choose_line; + swrast->choose_triangle = dmesa_choose_tri; + + swrast->invalidate_line |= DMESA_NEW_LINE; + swrast->invalidate_triangle |= DMESA_NEW_TRIANGLE; +} + + + +/* Setup pointers and other driver state that is constant for the life + * of a context. + */ +static void dmesa_init_pointers (GLcontext *ctx) +{ + TNLcontext *tnl; + struct swrast_device_driver *dd = _swrast_GetDeviceDriverReference(ctx); + + ctx->Driver.GetString = get_string; + ctx->Driver.GetBufferSize = get_buffer_size; + ctx->Driver.Flush = flush; + ctx->Driver.Finish = finish; + + /* Software rasterizer pixel paths: + */ + ctx->Driver.Accum = _swrast_Accum; + ctx->Driver.Bitmap = _swrast_Bitmap; + ctx->Driver.Clear = clear; + ctx->Driver.ResizeBuffers = _swrast_alloc_buffers; + ctx->Driver.CopyPixels = _swrast_CopyPixels; + ctx->Driver.DrawPixels = _swrast_DrawPixels; + ctx->Driver.ReadPixels = _swrast_ReadPixels; + ctx->Driver.DrawBuffer = _swrast_DrawBuffer; + + /* Software texture functions: + */ + ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format; + ctx->Driver.TexImage1D = _mesa_store_teximage1d; + ctx->Driver.TexImage2D = _mesa_store_teximage2d; + ctx->Driver.TexImage3D = _mesa_store_teximage3d; + ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d; + ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d; + ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d; + ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage; + + ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d; + ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d; + ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d; + ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d; + ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d; + + ctx->Driver.CompressedTexImage1D = _mesa_store_compressed_teximage1d; + ctx->Driver.CompressedTexImage2D = _mesa_store_compressed_teximage2d; + ctx->Driver.CompressedTexImage3D = _mesa_store_compressed_teximage3d; + ctx->Driver.CompressedTexSubImage1D = _mesa_store_compressed_texsubimage1d; + ctx->Driver.CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d; + ctx->Driver.CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d; + + /* Swrast hooks for imaging extensions: + */ + ctx->Driver.CopyColorTable = _swrast_CopyColorTable; + ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable; + ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D; + ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D; + + /* Statechange callbacks: + */ + ctx->Driver.ClearColor = clear_color; + ctx->Driver.ClearIndex = clear_index; + + /* Initialize the TNL driver interface: + */ + tnl = TNL_CONTEXT(ctx); + tnl->Driver.RunPipeline = _tnl_run_pipeline; + + dd->SetBuffer = set_buffer; + + /* Install swsetup for tnl->Driver.Render.*: + */ + _swsetup_Wakeup(ctx); + + /* The span functions should be in `dmesa_update_state', but I'm + * pretty sure they will never change during the life of the Visual + */ + + /* Index span/pixel functions */ + dd->WriteCI32Span = write_index_span; + dd->WriteCI8Span = write_index8_span; + dd->WriteMonoCISpan = write_mono_index_span; + dd->WriteCI32Pixels = write_index_pixels; + dd->WriteMonoCIPixels = write_mono_index_pixels; + dd->ReadCI32Span = read_index_span; + dd->ReadCI32Pixels = read_index_pixels; + + /* RGB(A) span/pixel functions */ + dd->WriteRGBASpan = write_rgba_span; + dd->WriteRGBSpan = write_rgb_span; + dd->WriteMonoRGBASpan = write_mono_rgba_span; + dd->WriteRGBAPixels = write_rgba_pixels; + dd->WriteMonoRGBAPixels = write_mono_rgba_pixels; + dd->ReadRGBASpan = read_rgba_span; + dd->ReadRGBAPixels = read_rgba_pixels; +} + + + +static void dmesa_update_state (GLcontext *ctx, GLuint new_state) +{ + /* Propagate statechange information to swrast and swrast_setup + * modules. The DMesa driver has no internal GL-dependent state. + */ + _swrast_InvalidateState( ctx, new_state ); + _ac_InvalidateState( ctx, new_state ); + _tnl_InvalidateState( ctx, new_state ); + _swsetup_InvalidateState( ctx, new_state ); +} +#endif /* FX */ + + + +/**************************************************************************** + * DMesa Public API Functions + ***************************************************************************/ + +/* + * The exact arguments to this function will depend on your window system + */ +DMesaVisual DMesaCreateVisual (GLint width, + GLint height, + GLint colDepth, + GLint refresh, + GLboolean dbFlag, + GLboolean rgbFlag, + GLint alphaSize, + GLint depthSize, + GLint stencilSize, + GLint accumSize) +{ +#ifndef FX + DMesaVisual v; + GLint redBits, greenBits, blueBits, alphaBits, indexBits; + GLboolean sw_alpha; + + if (!dbFlag) { + return NULL; + } + + alphaBits = 0; + + if (!rgbFlag) { + indexBits = 8; + redBits = 0; + greenBits = 0; + blueBits = 0; + } else { + indexBits = 0; + switch (colDepth) { + case 8: + redBits = 8; + greenBits = 8; + blueBits = 8; + break; + case 15: + alphaBits = 1; + redBits = 5; + greenBits = 5; + blueBits = 5; + break; + case 16: + redBits = 5; + greenBits = 6; + blueBits = 5; + break; + case 32: + alphaBits = 8; + case 24: + redBits = 8; + greenBits = 8; + blueBits = 8; + break; + default: + return NULL; + } + } + + /* Okay, + * `alphaBits' is what we can provide + * `alphaSize' is what app requests + * + * Note that alpha buffering is required only if destination alpha is used + * in alpha blending; alpha blending modes that do not use destination alpha + * can be used w/o alpha buffer. + * + * We will use whatever ALPHA app requests. Later, in `CreateBuffer' we'll + * instruct Mesa to use its own ALPHA buffer, by passing a non-FALSE value + * for ALPHA to `_mesa_initialize_framebuffer'. + * + * Basically, 32bit modes provide ALPHA storage, but can we rely on this? + */ + alphaBits = alphaSize; + sw_alpha = (alphaBits > 0); + + if ((colDepth=vl_video_init(width, height, colDepth, rgbFlag, refresh)) <= 0) { + return NULL; + } + + if ((v=(DMesaVisual)CALLOC_STRUCT(dmesa_visual)) != NULL) { + /* Create core visual */ + _mesa_initialize_visual((GLvisual *)v, + rgbFlag, /* rgb */ + dbFlag, + GL_FALSE, /* stereo */ + redBits, + greenBits, + blueBits, + alphaBits, + indexBits, /* indexBits */ + depthSize, + stencilSize, + accumSize, /* accumRed */ + accumSize, /* accumGreen */ + accumSize, /* accumBlue */ + alphaBits?accumSize:0, /* accumAlpha */ + 1); /* numSamples */ + + v->depth = colDepth; + v->db_flag = dbFlag; + v->rgb_flag = rgbFlag; + v->sw_alpha = sw_alpha; + + v->zbuffer = (depthSize > 0) ? 1 : 0; + } + + return v; + +#else /* FX */ + + char *env; + int i = 0, fx_attrib[32]; + + if (!rgbFlag) { + return NULL; + } + + if (dbFlag) fx_attrib[i++] = FXMESA_DOUBLEBUFFER; + if (depthSize > 0) { fx_attrib[i++] = FXMESA_DEPTH_SIZE; fx_attrib[i++] = depthSize; } + if (stencilSize > 0) { fx_attrib[i++] = FXMESA_STENCIL_SIZE; fx_attrib[i++] = stencilSize; } + if (accumSize > 0) { fx_attrib[i++] = FXMESA_ACCUM_SIZE; fx_attrib[i++] = accumSize; } + if (alphaSize) { fx_attrib[i++] = FXMESA_ALPHA_SIZE; fx_attrib[i++] = alphaSize; } + fx_attrib[i++] = FXMESA_COLORDEPTH; + fx_attrib[i++] = colDepth; + fx_attrib[i] = FXMESA_NONE; + + if ((env = getenv("MESA_FX_INFO")) && (env[0] == 'r')) { + freopen("MESA.LOG", "w", stderr); + } + + if (refresh && (((env = getenv("FX_GLIDE_REFRESH")) == NULL) || !atoi(env))) { + /* if we are passed non-zero value for refresh, we need to override + * default refresh rate. However, if FX_GLIDE_REFRESH is already set + * to 0, we won't override it, because it has a special meaning for + * DJGPP Glide3x (switch via VESA, using BIOS default refresh). + */ + char tmp[256]; + sprintf(tmp, "FX_GLIDE_REFRESH=%u", refresh); + putenv(tmp); + } + + return (DMesaVisual)fxMesaCreateBestContext(-1, width, height, fx_attrib); +#endif /* FX */ +} + + + +void DMesaDestroyVisual (DMesaVisual v) +{ +#ifndef FX + _mesa_destroy_visual((GLvisual *)v); + + vl_video_exit(); + +#else + fxMesaDestroyContext((fxMesaContext)v); +#endif +} + + + +DMesaBuffer DMesaCreateBuffer (DMesaVisual visual, + GLint xpos, GLint ypos, + GLint width, GLint height) +{ +#ifndef FX + DMesaBuffer b; + + if ((b=(DMesaBuffer)CALLOC_STRUCT(dmesa_buffer)) != NULL) { + _mesa_initialize_framebuffer((GLframebuffer *)b, + (GLvisual *)visual, + visual->zbuffer == 1, + ((GLvisual *)visual)->stencilBits > 0, + ((GLvisual *)visual)->accumRedBits > 0, + visual->sw_alpha); + b->xpos = xpos; + b->ypos = ypos; + b->width = width; + b->height = height; + } + + return b; +#else + return (DMesaBuffer)visual; +#endif +} + + + +void DMesaDestroyBuffer (DMesaBuffer b) +{ +#ifndef FX + free(b->the_window); + _mesa_destroy_framebuffer((GLframebuffer *)b); +#endif +} + + + +DMesaContext DMesaCreateContext (DMesaVisual visual, + DMesaContext share) +{ +#ifndef FX + DMesaContext c; + GLboolean direct = GL_FALSE; + + if ((c=(DMesaContext)CALLOC_STRUCT(dmesa_context)) != NULL) { + _mesa_initialize_context((GLcontext *)c, + (GLvisual *)visual, + (GLcontext *)share, + (void *)c, direct); + + _mesa_enable_sw_extensions((GLcontext *)c); + _mesa_enable_1_3_extensions((GLcontext *)c); + _mesa_enable_1_4_extensions((GLcontext *)c); + _mesa_enable_1_5_extensions((GLcontext *)c); + + /* you probably have to do a bunch of other initializations here. */ + c->visual = visual; + + ((GLcontext *)c)->Driver.UpdateState = dmesa_update_state; + + /* Initialize the software rasterizer and helper modules. + */ + _swrast_CreateContext((GLcontext *)c); + _ac_CreateContext((GLcontext *)c); + _tnl_CreateContext((GLcontext *)c); + _swsetup_CreateContext((GLcontext *)c); + if (visual->rgb_flag) dmesa_register_swrast_functions((GLcontext *)c); + dmesa_init_pointers((GLcontext *)c); + } + + return c; + +#else /* FX */ + return (DMesaContext)visual; +#endif /* FX */ +} + + + +void DMesaDestroyContext (DMesaContext c) +{ +#ifndef FX + if (c) { + _swsetup_DestroyContext((GLcontext *)c); + _swrast_DestroyContext((GLcontext *)c); + _tnl_DestroyContext((GLcontext *)c); + _ac_DestroyContext((GLcontext *)c); + _mesa_destroy_context((GLcontext *)c); + } +#endif +} + + + +GLboolean DMesaMoveBuffer (GLint xpos, GLint ypos) +{ +#ifndef FX + GET_CURRENT_CONTEXT(ctx); + DMesaBuffer b = ((DMesaContext)ctx)->Buffer; + + if (vl_sync_buffer(&b->the_window, xpos, ypos, b->width, b->height) != 0) { + return GL_FALSE; + } else { + b->xpos = xpos; + b->ypos = ypos; + return GL_TRUE; + } + +#else + return GL_FALSE; +#endif +} + + + +GLboolean DMesaResizeBuffer (GLint width, GLint height) +{ +#ifndef FX + GET_CURRENT_CONTEXT(ctx); + DMesaBuffer b = ((DMesaContext)ctx)->Buffer; + + if (vl_sync_buffer(&b->the_window, b->xpos, b->ypos, width, height) != 0) { + return GL_FALSE; + } else { + b->width = width; + b->height = height; + return GL_TRUE; + } + +#else + return GL_FALSE; +#endif +} + + + +/* + * Make the specified context and buffer the current one. + */ +GLboolean DMesaMakeCurrent (DMesaContext c, DMesaBuffer b) +{ +#ifndef FX + if ((c != NULL) && (b != NULL)) { + if (vl_sync_buffer(&b->the_window, b->xpos, b->ypos, b->width, b->height) != 0) { + return GL_FALSE; + } + + c->Buffer = b; + + _mesa_make_current((GLcontext *)c, (GLframebuffer *)b); + if (((GLcontext *)c)->Viewport.Width == 0) { + /* initialize viewport to window size */ + _mesa_Viewport(0, 0, b->width, b->height); + } + } else { + /* Detach */ + _mesa_make_current(NULL, NULL); + } + +#else + fxMesaMakeCurrent((fxMesaContext)c); +#endif + + return GL_TRUE; +} + + + +void DMesaSwapBuffers (DMesaBuffer b) +{ + /* copy/swap back buffer to front if applicable */ +#ifndef FX + GET_CURRENT_CONTEXT(ctx); + _mesa_notifySwapBuffers(ctx); + vl_flip(); +#else + fxMesaSwapBuffers(); +#endif +} + + + +void DMesaSetCI (int ndx, GLfloat red, GLfloat green, GLfloat blue) +{ +#ifndef FX + vl_setCI(ndx, red, green, blue); +#endif +} + + + +void *DMesaGetCurrentContext (void) +{ +#ifndef FX + GET_CURRENT_CONTEXT(ctx); + return ctx; +#else + return fxMesaGetCurrentContext(); +#endif +} + + + +int DMesaGetIntegerv (GLenum pname, GLint *params) +{ + switch (pname) { + case DMESA_GET_SCREEN_SIZE: + #ifndef FX + vl_get(VL_GET_SCREEN_SIZE, params); + #else + fxGetScreenGeometry(¶ms[0], ¶ms[1]); + #endif + break; + case DMESA_GET_DRIVER_CAPS: + #ifndef FX + params[0] = DMESA_DRIVER_SWDB_BIT; + #else + params[0] = DMESA_DRIVER_LLWO_BIT; + #endif + break; + case DMESA_GET_VIDEO_MODES: + #ifndef FX + return vl_get(VL_GET_VIDEO_MODES, params); + #else + { + /* `vmode' struct must be sync'ed with `internal.h' (vl_mode) + * `vmode' list must be sync'ed with `fxapi.c' + * `hw >= 6' means Napalm and can do 32bit rendering + * TODO: we should take an envvar for `fxMesaSelectCurrentBoard' + */ + static struct { + int width, height; + int bpp; + } vmode[] = { + { 320, 200, 16 }, + { 320, 240, 16 }, + { 512, 384, 16 }, + { 640, 400, 16 }, + { 640, 480, 16 }, + { 800, 600, 16 }, + {1024, 768, 16 }, + + { 320, 200, 32 }, + { 320, 240, 32 }, + { 512, 384, 32 }, + { 640, 400, 32 }, + { 640, 480, 32 }, + { 800, 600, 32 }, + {1024, 768, 32 } + }; + int hw = fxMesaSelectCurrentBoard(0); + int i, n = sizeof(vmode) / sizeof(vmode[0]); + if (hw < 6) { + n /= 2; + } + if (params) { + for (i = 0; i < n; i++) { + params[i] = (GLint)(&vmode[i]); + } + } + return n; + } + #endif + default: + return -1; + } + + return 0; +} diff --git a/reactos/lib/mesa32/src/drivers/dos/dpmi.c b/reactos/lib/mesa32/src/drivers/dos/dpmi.c new file mode 100644 index 00000000000..f9943ea60bf --- /dev/null +++ b/reactos/lib/mesa32/src/drivers/dos/dpmi.c @@ -0,0 +1,148 @@ +/* + * Mesa 3-D graphics library + * Version: 4.0 + * + * 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 + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * DOS/DJGPP device driver v1.4 for Mesa + * + * Copyright (C) 2002 - Borca Daniel + * Email : dborca@yahoo.com + * Web : http://www.geocities.com/dborca + */ + + +#include + +#include "internal.h" + + + +#ifndef MAX +#define MAX(x, y) (((x)<(y))?(y):(x)) +#endif + + + +/* _create_linear_mapping: + * Maps a physical address range into linear memory. + */ +int _create_linear_mapping (unsigned long *linear, unsigned long physaddr, int size) +{ + __dpmi_meminfo meminfo; + + if (physaddr >= 0x100000) { + /* map into linear memory */ + meminfo.address = physaddr; + meminfo.size = size; + if (__dpmi_physical_address_mapping(&meminfo) != 0) + return -1; + + *linear = meminfo.address; + } else { + /* exploit 1 -> 1 physical to linear mapping in low megabyte */ + *linear = physaddr; + } + + return 0; +} + + + +/* _remove_linear_mapping: + * Frees the DPMI resources being used to map a linear address range. + */ +void _remove_linear_mapping (unsigned long *linear) +{ + __dpmi_meminfo meminfo; + + if (*linear) { + if (*linear >= 0x100000) { + meminfo.address = *linear; + __dpmi_free_physical_address_mapping(&meminfo); + } + + *linear = 0; + } +} + + + +/* _create_selector: + * Allocates a selector to access a region of linear memory. + */ +int _create_selector (int *segment, unsigned long base, int size) +{ + /* allocate an ldt descriptor */ + if ((*segment=__dpmi_allocate_ldt_descriptors(1)) < 0) { + *segment = 0; + return -1; + } + + /* create the linear mapping */ + if (_create_linear_mapping(&base, base, size)) { + __dpmi_free_ldt_descriptor(*segment); + *segment = 0; + return -1; + } + + /* set the descriptor base and limit */ + __dpmi_set_segment_base_address(*segment, base); + __dpmi_set_segment_limit(*segment, MAX(size-1, 0xFFFF)); + + return 0; +} + + + +/* _remove_selector: + * Frees a DPMI segment selector. + */ +void _remove_selector (int *segment) +{ + if (*segment) { + unsigned long base; + __dpmi_get_segment_base_address(*segment, &base); + _remove_linear_mapping(&base); + __dpmi_free_ldt_descriptor(*segment); + *segment = 0; + } +} + + + +/* Desc: retrieve CPU MMX capability + * + * In : - + * Out : FALSE if CPU cannot do MMX + * + * Note: - + */ +int _can_mmx (void) +{ +#ifdef USE_MMX_ASM + extern int _mesa_x86_cpu_features; + return (_mesa_x86_cpu_features & 0x00800000); +#else + return 0; +#endif +} diff --git a/reactos/lib/mesa32/src/drivers/dos/internal.h b/reactos/lib/mesa32/src/drivers/dos/internal.h new file mode 100644 index 00000000000..fd47dbb7b82 --- /dev/null +++ b/reactos/lib/mesa32/src/drivers/dos/internal.h @@ -0,0 +1,130 @@ +/* + * Mesa 3-D graphics library + * Version: 4.0 + * + * 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 + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * DOS/DJGPP device driver v1.5 for Mesa + * + * Copyright (C) 2002 - Borca Daniel + * Email : dborca@users.sourceforge.net + * Web : http://www.geocities.com/dborca + */ + + +#ifndef INTERNAL_H_included +#define INTERNAL_H_included + +#include "../main/mtypes.h" + +/* + * general purpose defines, etc. + */ +#ifndef FALSE +#define FALSE 0 +#define TRUE !FALSE +#endif + +#define __PACKED__ __attribute__((packed)) + +typedef unsigned char word8; +typedef unsigned short word16; +typedef unsigned long word32; + +#define _16_ *(word16 *)& +#define _32_ *(word32 *)& + + + +/* + * video mode structure + */ +typedef struct vl_mode { + int xres, yres; + int bpp; + + int mode; + int scanlen; + + int sel; + int gran; +} vl_mode; + + + +/* + * video driver structure + */ +typedef struct { + vl_mode *(*init) (void); + int (*entermode) (vl_mode *p, int refresh); + void (*blit) (void); + void (*setCI_f) (int index, float red, float green, float blue); + void (*setCI_i) (int index, int red, int green, int blue); + int (*get) (int pname, int *params); + void (*restore) (void); + void (*fini) (void); +} vl_driver; + + + +/* + * memory mapping + */ +int _create_linear_mapping (unsigned long *linear, unsigned long physaddr, int size); +void _remove_linear_mapping (unsigned long *linear); +int _create_selector (int *segment, unsigned long base, int size); +void _remove_selector (int *segment); + +/* + * system routines + */ +int _can_mmx (void); + +/* + * asm routines to deal with virtual buffering + */ +extern void v_clear8 (int color); +#define v_clear15 v_clear16 +extern void v_clear16 (int color); +extern void v_clear24 (int color); +extern void v_clear32 (int color); + +extern void v_clear8_mmx (int color); +#define v_clear15_mmx v_clear16_mmx +extern void v_clear16_mmx (int color); +extern void v_clear24_mmx (int color); +extern void v_clear32_mmx (int color); + +extern void v_rect8 (int x, int y, int width, int height, int color); +#define v_rect15 v_rect16 +extern void v_rect16 (int x, int y, int width, int height, int color); +extern void v_rect24 (int x, int y, int width, int height, int color); +extern void v_rect32 (int x, int y, int width, int height, int color); + +extern void v_putpixel8 (unsigned int offset, int color); +#define v_putpixel15 v_putpixel16 +extern void v_putpixel16 (unsigned int offset, int color); +extern void v_putpixel24 (unsigned int offset, int color); +extern void v_putpixel32 (unsigned int offset, int color); + +#endif diff --git a/reactos/lib/mesa32/src/drivers/dos/vesa.c b/reactos/lib/mesa32/src/drivers/dos/vesa.c new file mode 100644 index 00000000000..e87651e4fd2 --- /dev/null +++ b/reactos/lib/mesa32/src/drivers/dos/vesa.c @@ -0,0 +1,534 @@ +/* + * Mesa 3-D graphics library + * Version: 4.1 + * + * 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 + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * DOS/DJGPP device driver v1.5 for Mesa + * + * Copyright (C) 2002 - Borca Daniel + * Email : dborca@users.sourceforge.net + * Web : http://www.geocities.com/dborca + */ + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "video.h" +#include "vesa.h" + + + +static vl_mode modes[128]; + +static word16 vesa_ver; +static int banked_selector, linear_selector; +static int oldmode = -1; + +static int vesa_color_precision = 6; + +static word16 *vesa_pmcode; +unsigned int vesa_gran_mask, vesa_gran_shift; + + + +/* + * VESA info + */ +#define V_SIGN 0 +#define V_MINOR 4 +#define V_MAJOR 5 +#define V_OEM_OFS 6 +#define V_OEM_SEG 8 +#define V_MODE_OFS 14 +#define V_MODE_SEG 16 +#define V_MEMORY 18 + +/* + * mode info + */ +#define M_ATTR 0 +#define M_GRAN 4 +#define M_SCANLEN 16 +#define M_XRES 18 +#define M_YRES 20 +#define M_BPP 25 +#define M_RED 31 +#define M_GREEN 33 +#define M_BLUE 35 +#define M_PHYS_PTR 40 + +/* + * VESA 3.0 CRTC timings structure + */ +typedef struct CRTCInfoBlock { + unsigned short HorizontalTotal; + unsigned short HorizontalSyncStart; + unsigned short HorizontalSyncEnd; + unsigned short VerticalTotal; + unsigned short VerticalSyncStart; + unsigned short VerticalSyncEnd; + unsigned char Flags; + unsigned long PixelClock; /* units of Hz */ + unsigned short RefreshRate; /* units of 0.01 Hz */ + unsigned char reserved[40]; +} __PACKED__ CRTCInfoBlock; + +#define HNEG (1 << 2) +#define VNEG (1 << 3) +#define DOUBLESCAN (1 << 0) + + + +/* Desc: Attempts to detect VESA, check video modes and create selectors. + * + * In : - + * Out : mode array + * + * Note: - + */ +static vl_mode *vesa_init (void) +{ + __dpmi_regs r; + word16 *p; + vl_mode *q; + char vesa_info[512], tmp[512]; + int maxsize = 0; + word32 linearfb = 0; + + if (vesa_ver) { + return modes; + } + + _farpokel(_stubinfo->ds_selector, 0, 0x32454256); + r.x.ax = 0x4f00; + r.x.di = 0; + r.x.es = _stubinfo->ds_segment; + __dpmi_int(0x10, &r); + movedata(_stubinfo->ds_selector, 0, _my_ds(), (unsigned)vesa_info, 512); + if ((r.x.ax!=0x004f) || ((_32_ vesa_info[V_SIGN])!=0x41534556)) { + return NULL; + } + + p = (word16 *)(((_16_ vesa_info[V_MODE_SEG])<<4) + (_16_ vesa_info[V_MODE_OFS])); + q = modes; + do { + if ((q->mode=_farpeekw(__djgpp_dos_sel, (unsigned long)(p++)))==0xffff) { + break; + } + + r.x.ax = 0x4f01; + r.x.cx = q->mode; + r.x.di = 512; + r.x.es = _stubinfo->ds_segment; + __dpmi_int(0x10, &r); + movedata(_stubinfo->ds_selector, 512, _my_ds(), (unsigned)tmp, 256); + switch (tmp[M_BPP]) { + case 16: + q->bpp = tmp[M_RED] + tmp[M_GREEN] + tmp[M_BLUE]; + break; + case 8: + case 15: + case 24: + case 32: + q->bpp = tmp[M_BPP]; + break; + default: + q->bpp = 0; + } + if ((r.x.ax==0x004f) && ((tmp[M_ATTR]&0x11)==0x11) && q->bpp) { + q->xres = _16_ tmp[M_XRES]; + q->yres = _16_ tmp[M_YRES]; + q->scanlen = _16_ tmp[M_SCANLEN]; + q->gran = (_16_ tmp[M_GRAN])<<10; + if (tmp[M_ATTR]&0x80) { +#if 0 + *(q+1) = *q++; +#else + vl_mode *q1 = q + 1; + *q1 = *q++; +#endif + linearfb = _32_ tmp[M_PHYS_PTR]; + q->mode |= 0x4000; + } + if (maxsize<(q->scanlen*q->yres)) { + maxsize = q->scanlen*q->yres; + } + q++; + } + } while (TRUE); + + if (q==modes) { + return NULL; + } + if (linearfb) { + maxsize = ((maxsize+0xfffUL)&~0xfffUL); + if (_create_selector(&linear_selector, linearfb, maxsize)) { + return NULL; + } + } + if (_create_selector(&banked_selector, 0xa0000, modes[0].gran)) { + _remove_selector(&linear_selector); + return NULL; + } + + for (q=modes; q->mode!=0xffff; q++) { + q->sel = (q->mode&0x4000) ? linear_selector : banked_selector; + } + + if (vesa_info[V_MAJOR] >= 2) { + r.x.ax = 0x4f0a; + r.x.bx = 0; + __dpmi_int(0x10, &r); + if (r.x.ax == 0x004f) { + vesa_pmcode = (word16 *)malloc(r.x.cx); + movedata(__djgpp_dos_sel, (r.x.es << 4) + r.x.di, _my_ds(), (unsigned)vesa_pmcode, r.x.cx); + if (vesa_pmcode[3]) { + p = (word16 *)((long)vesa_pmcode + vesa_pmcode[3]); + while (*p++ != 0xffff) ; + } else { + p = NULL; + } + if (p && (*p != 0xffff)) { + free(vesa_pmcode); + vesa_pmcode = NULL; + } else { + vesa_swbank = (void *)((long)vesa_pmcode + vesa_pmcode[0]); + } + } + } + + vesa_ver = _16_ vesa_info[V_MINOR]; + return modes; +} + + + +/* Desc: Frees all resources allocated by VESA init code. + * + * In : - + * Out : - + * + * Note: - + */ +static void vesa_fini (void) +{ + if (vesa_ver) { + _remove_selector(&linear_selector); + _remove_selector(&banked_selector); + if (vesa_pmcode != NULL) { + free(vesa_pmcode); + vesa_pmcode = NULL; + } + } +} + + + +/* Desc: Uses VESA 3.0 function 0x4F0B to find the closest pixel clock to the requested value. + * + * In : mode, clock + * Out : desired clock + * + * Note: - + */ +static unsigned long _closest_pixclk (int mode_no, unsigned long vclk) +{ + __dpmi_regs r; + + r.x.ax = 0x4F0B; + r.h.bl = 0; + r.d.ecx = vclk; + r.x.dx = mode_no; + __dpmi_int(0x10, &r); + + return (r.x.ax==0x004f) ? r.d.ecx : 0; +} + + + +/* Desc: Calculates CRTC mode timings. + * + * In : crtc block, geometry, adjust + * Out : + * + * Note: + */ +static void _crtc_timing (CRTCInfoBlock *crtc, int xres, int yres, int xadjust, int yadjust) +{ + int HTotal, VTotal; + int HDisp, VDisp; + int HSS, VSS; + int HSE, VSE; + int HSWidth, VSWidth; + int SS, SE; + int doublescan = FALSE; + + if (yres < 400) { + doublescan = TRUE; + yres *= 2; + } + + HDisp = xres; + HTotal = (int)(HDisp * 1.27) & ~0x7; + HSWidth = (int)((HTotal - HDisp) / 5) & ~0x7; + HSS = HDisp + 16; + HSE = HSS + HSWidth; + VDisp = yres; + VTotal = VDisp * 1.07; + VSWidth = (VTotal / 100) + 1; + VSS = VDisp + ((int)(VTotal - VDisp) / 5) + 1; + VSE = VSS + VSWidth; + + SS = HSS + xadjust; + SE = HSE + xadjust; + + if (xadjust < 0) { + if (SS < (HDisp + 8)) { + SS = HDisp + 8; + SE = SS + HSWidth; + } + } else { + if ((HTotal - 24) < SE) { + SE = HTotal - 24; + SS = SE - HSWidth; + } + } + + HSS = SS; + HSE = SE; + + SS = VSS + yadjust; + SE = VSE + yadjust; + + if (yadjust < 0) { + if (SS < (VDisp + 3)) { + SS = VDisp + 3; + SE = SS + VSWidth; + } + } else { + if ((VTotal - 4) < SE) { + SE = VTotal - 4; + SS = SE - VSWidth; + } + } + + VSS = SS; + VSE = SE; + + crtc->HorizontalTotal = HTotal; + crtc->HorizontalSyncStart = HSS; + crtc->HorizontalSyncEnd = HSE; + crtc->VerticalTotal = VTotal; + crtc->VerticalSyncStart = VSS; + crtc->VerticalSyncEnd = VSE; + crtc->Flags = HNEG | VNEG; + + if (doublescan) + crtc->Flags |= DOUBLESCAN; +} + + + +/* Desc: Attempts to enter specified video mode. + * + * In : ptr to mode structure, refresh rate + * Out : 0 if success + * + * Note: - + */ +static int vesa_entermode (vl_mode *p, int refresh) +{ + __dpmi_regs r; + + if (p->mode & 0x4000) { + VESA.blit = _can_mmx() ? vesa_l_dump_virtual_mmx : vesa_l_dump_virtual; + } else { + VESA.blit = vesa_b_dump_virtual; + { int n; for (vesa_gran_shift=0, n=p->gran; n; vesa_gran_shift++, n>>=1) ; } + vesa_gran_mask = (1<<(--vesa_gran_shift)) - 1; + if ((unsigned)p->gran != (vesa_gran_mask+1)) { + return !0; + } + } + + if (oldmode == -1) { + r.x.ax = 0x4f03; + __dpmi_int(0x10, &r); + oldmode = r.x.bx; + } + + r.x.ax = 0x4f02; + r.x.bx = p->mode; + + if (refresh && ((vesa_ver>>8) >= 3)) { + /* VESA 3.0 stuff for controlling the refresh rate */ + CRTCInfoBlock crtc; + unsigned long vclk; + double f0; + + _crtc_timing(&crtc, p->xres, p->yres, 0, 0); + + vclk = (double)crtc.HorizontalTotal * crtc.VerticalTotal * refresh; + vclk = _closest_pixclk(p->mode, vclk); + + if (vclk != 0) { + f0 = (double)vclk / (crtc.HorizontalTotal * crtc.VerticalTotal); + /*_current_refresh_rate = (int)(f0 + 0.5);*/ + + crtc.PixelClock = vclk; + crtc.RefreshRate = refresh * 100; + + movedata(_my_ds(), (unsigned)&crtc, _stubinfo->ds_selector, 0, sizeof(crtc)); + + r.x.di = 0; + r.x.es = _stubinfo->ds_segment; + r.x.bx |= 0x0800; + } + } + + __dpmi_int(0x10, &r); + if (r.x.ax != 0x004f) { + return !0; + } + + if (p->bpp == 8) { + r.x.ax = 0x4f08; + r.x.bx = 0x0800; + __dpmi_int(0x10, &r); + if (r.x.ax == 0x004f) { + r.x.ax = 0x4f08; + r.h.bl = 0x01; + __dpmi_int(0x10, &r); + vesa_color_precision = r.h.bh; + } + } + + return 0; +} + + + +/* Desc: Restores to the mode prior to first call to vesa_entermode. + * + * In : - + * Out : - + * + * Note: - + */ +static void vesa_restore (void) +{ + __dpmi_regs r; + + if (oldmode != -1) { + r.x.ax = 0x4f02; + r.x.bx = oldmode; + __dpmi_int(0x10, &r); + oldmode = -1; + } +} + + + +/* Desc: set one palette entry + * + * In : color index, R, G, B + * Out : - + * + * Note: uses integer values + */ +static void vesa_setCI_i (int index, int red, int green, int blue) +{ +#if 0 + __asm("\n\ + movw $0x1010, %%ax \n\ + movb %1, %%dh \n\ + movb %2, %%ch \n\ + int $0x10 \n\ + "::"b"(index), "m"(red), "m"(green), "c"(blue):"%eax", "%edx"); +#else + outportb(0x03C8, index); + outportb(0x03C9, red); + outportb(0x03C9, green); + outportb(0x03C9, blue); +#endif +} + + + +/* Desc: set one palette entry + * + * In : color index, R, G, B + * Out : - + * + * Note: uses normalized values + */ +static void vesa_setCI_f (int index, float red, float green, float blue) +{ + float max = (1 << vesa_color_precision) - 1; + + vesa_setCI_i(index, (int)(red * max), (int)(green * max), (int)(blue * max)); +} + + + +/* Desc: state retrieval + * + * In : parameter name, ptr to storage + * Out : 0 if request successfully processed + * + * Note: - + */ +static int vesa_get (int pname, int *params) +{ + switch (pname) { + case VL_GET_CI_PREC: + params[0] = vesa_color_precision; + break; + default: + return -1; + } + return 0; +} + + + +/* + * the driver + */ +vl_driver VESA = { + vesa_init, + vesa_entermode, + NULL, + vesa_setCI_f, + vesa_setCI_i, + vesa_get, + vesa_restore, + vesa_fini +}; diff --git a/reactos/lib/mesa32/src/drivers/dos/vesa.h b/reactos/lib/mesa32/src/drivers/dos/vesa.h new file mode 100644 index 00000000000..9287697c370 --- /dev/null +++ b/reactos/lib/mesa32/src/drivers/dos/vesa.h @@ -0,0 +1,47 @@ +/* + * Mesa 3-D graphics library + * Version: 4.0 + * + * 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 + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * DOS/DJGPP device driver v1.3 for Mesa + * + * Copyright (C) 2002 - Borca Daniel + * Email : dborca@yahoo.com + * Web : http://www.geocities.com/dborca + */ + + +#ifndef VESA_H_included +#define VESA_H_included + +#include "internal.h" + +extern void *vesa_swbank; + +extern void vesa_b_dump_virtual (void); +extern void vesa_l_dump_virtual (void); +extern void vesa_l_dump_virtual_mmx (void); + +extern vl_driver VESA; + +#endif diff --git a/reactos/lib/mesa32/src/drivers/dos/vga.c b/reactos/lib/mesa32/src/drivers/dos/vga.c new file mode 100644 index 00000000000..3a4bd9b6876 --- /dev/null +++ b/reactos/lib/mesa32/src/drivers/dos/vga.c @@ -0,0 +1,236 @@ +/* + * Mesa 3-D graphics library + * Version: 4.1 + * + * 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 + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * DOS/DJGPP device driver v1.5 for Mesa + * + * Copyright (C) 2002 - Borca Daniel + * Email : dborca@users.sourceforge.net + * Web : http://www.geocities.com/dborca + */ + + +#include +#include + +#include "video.h" +#include "vga.h" + + + +static vl_mode modes[] = { + {0x13 | 0x4000, 320, 200, 320, 8, -1, 320*200}, + {0xffff, -1, -1, -1, -1, -1, -1} +}; + +static word16 vga_ver; +static int linear_selector; +static int oldmode = -1; + +#define vga_color_precision 6 + + + +/* Desc: Attempts to detect VGA, check video modes and create selectors. + * + * In : - + * Out : mode array + * + * Note: - + */ +static vl_mode *vga_init (void) +{ + int rv = 0; + + if (vga_ver) { + return modes; + } + + __asm("\n\ + movw $0x1a00, %%ax \n\ + int $0x10 \n\ + cmpb $0x1a, %%al \n\ + jne 0f \n\ + cmpb $0x07, %%bl \n\ + jb 0f \n\ + andl $0xff, %%ebx \n\ + movl %%ebx, %0 \n\ + 0:":"=g"(rv)::"%eax", "%ebx"); + if (rv == 0) { + return NULL; + } + + if (_create_selector(&linear_selector, 0xa0000, 0x10000)) { + return NULL; + } + + modes[0].sel = linear_selector; + + vga_ver = rv; + return modes; +} + + + +/* Desc: Frees all resources allocated by VGA init code. + * + * In : - + * Out : - + * + * Note: - + */ +static void vga_fini (void) +{ + if (vga_ver) { + _remove_selector(&linear_selector); + } +} + + + +/* Desc: Attempts to enter specified video mode. + * + * In : ptr to mode structure, refresh rate + * Out : 0 if success + * + * Note: - + */ +static int vga_entermode (vl_mode *p, int refresh) +{ + if (!(p->mode & 0x4000)) { + return -1; + } + VGA.blit = _can_mmx() ? vesa_l_dump_virtual_mmx : vesa_l_dump_virtual; + + if (oldmode == -1) { + __asm("\n\ + movb $0x0f, %%ah \n\ + int $0x10 \n\ + andl $0xff, %%eax \n\ + movl %%eax, %0 \n\ + ":"=g"(oldmode)::"%eax", "%ebx"); + } + + __asm("int $0x10"::"a"(p->mode&0xff)); + + return 0; + + (void)refresh; /* silence compiler warning */ +} + + + +/* Desc: Restores to the mode prior to first call to vga_entermode. + * + * In : - + * Out : - + * + * Note: - + */ +static void vga_restore (void) +{ + if (oldmode != -1) { + __asm("int $0x10"::"a"(oldmode)); + oldmode = -1; + } +} + + + +/* Desc: set one palette entry + * + * In : color index, R, G, B + * Out : - + * + * Note: uses integer values + */ +static void vga_setCI_i (int index, int red, int green, int blue) +{ +#if 0 + __asm("\n\ + movw $0x1010, %%ax \n\ + movb %1, %%dh \n\ + movb %2, %%ch \n\ + int $0x10 \n\ + "::"b"(index), "m"(red), "m"(green), "c"(blue):"%eax", "%edx"); +#else + outportb(0x03C8, index); + outportb(0x03C9, red); + outportb(0x03C9, green); + outportb(0x03C9, blue); +#endif +} + + + +/* Desc: set one palette entry + * + * In : color index, R, G, B + * Out : - + * + * Note: uses normalized values + */ +static void vga_setCI_f (int index, float red, float green, float blue) +{ + float max = (1 << vga_color_precision) - 1; + + vga_setCI_i(index, (int)(red * max), (int)(green * max), (int)(blue * max)); +} + + + +/* Desc: state retrieval + * + * In : parameter name, ptr to storage + * Out : 0 if request successfully processed + * + * Note: - + */ +static int vga_get (int pname, int *params) +{ + switch (pname) { + case VL_GET_CI_PREC: + params[0] = vga_color_precision; + break; + default: + return -1; + } + return 0; +} + + + +/* + * the driver + */ +vl_driver VGA = { + vga_init, + vga_entermode, + NULL, + vga_setCI_f, + vga_setCI_i, + vga_get, + vga_restore, + vga_fini +}; diff --git a/reactos/lib/mesa32/src/drivers/dos/vga.h b/reactos/lib/mesa32/src/drivers/dos/vga.h new file mode 100644 index 00000000000..aeb8faddaed --- /dev/null +++ b/reactos/lib/mesa32/src/drivers/dos/vga.h @@ -0,0 +1,42 @@ +/* + * Mesa 3-D graphics library + * Version: 4.0 + * + * 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 + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * DOS/DJGPP device driver v1.3 for Mesa + * + * Copyright (C) 2002 - Borca Daniel + * Email : dborca@yahoo.com + * Web : http://www.geocities.com/dborca + */ + + +#ifndef VGA_H_included +#define VGA_H_included + +#include "internal.h" +#include "vesa.h" + +extern vl_driver VGA; + +#endif diff --git a/reactos/lib/mesa32/src/drivers/dos/video.c b/reactos/lib/mesa32/src/drivers/dos/video.c new file mode 100644 index 00000000000..41903ebe799 --- /dev/null +++ b/reactos/lib/mesa32/src/drivers/dos/video.c @@ -0,0 +1,651 @@ +/* + * Mesa 3-D graphics library + * Version: 4.0 + * + * 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 + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * DOS/DJGPP device driver v1.5 for Mesa + * + * Copyright (C) 2002 - Borca Daniel + * Email : dborca@users.sourceforge.net + * Web : http://www.geocities.com/dborca + * + * Thanks to CrazyPyro (Neil Funk) for FakeColor + */ + + +#include + +#include "internal.h" +#include "vesa.h" +#include "vga.h" +#include "video.h" + + + +static vl_driver *drv; +/* based upon mode specific data: valid entire session */ +int vl_video_selector; +static vl_mode *video_mode; +static int video_scanlen, video_bypp; +/* valid until next buffer */ +void *vl_current_draw_buffer, *vl_current_read_buffer; +int vl_current_stride, vl_current_width, vl_current_height, vl_current_bytes; +int vl_current_offset, vl_current_delta; + + + +#if HUGE_LOOKUP +/* These lookup tables are used to extract RGB values in [0,255] + * from 15/16-bit pixel values. + */ +static unsigned char pix15r[0x8000]; +static unsigned char pix15g[0x8000]; +static unsigned char pix15b[0x8000]; +static unsigned char pix16r[0x10000]; +static unsigned char pix16g[0x10000]; +static unsigned char pix16b[0x10000]; +#else +/* lookup table for scaling 5 bit colors up to 8 bits */ +static int _rgb_scale_5[32] = { + 0, 8, 16, 25, 33, 41, 49, 58, + 66, 74, 82, 90, 99, 107, 115, 123, + 132, 140, 148, 156, 165, 173, 181, 189, + 197, 206, 214, 222, 230, 239, 247, 255 +}; +#endif + +/* lookup table for scaling 6 bit colors up to 8 bits */ +static int _rgb_scale_6[64] = { + 0, 4, 8, 12, 16, 20, 24, 28, + 32, 36, 40, 45, 49, 53, 57, 61, + 65, 69, 73, 77, 81, 85, 89, 93, + 97, 101, 105, 109, 113, 117, 121, 125, + 130, 134, 138, 142, 146, 150, 154, 158, + 162, 166, 170, 174, 178, 182, 186, 190, + 194, 198, 202, 206, 210, 215, 219, 223, + 227, 231, 235, 239, 243, 247, 251, 255 +}; + +/* FakeColor data */ +#define R_CNT 6 +#define G_CNT 6 +#define B_CNT 6 + +#define R_BIAS 7 +#define G_BIAS 7 +#define B_BIAS 7 + +static word32 VGAPalette[256]; +static word8 array_r[256]; +static word8 array_g[256]; +static word8 array_b[256]; + + + +int (*vl_mixfix) (fixed r, fixed g, fixed b); +int (*vl_mixrgb) (const unsigned char rgb[]); +int (*vl_mixrgba) (const unsigned char rgba[]); +void (*vl_getrgba) (unsigned int offset, unsigned char rgba[4]); +int (*vl_getpixel) (unsigned int offset); +void (*vl_clear) (int color); +void (*vl_rect) (int x, int y, int width, int height, int color); +void (*vl_flip) (void); +void (*vl_putpixel) (unsigned int offset, int color); + + + +/* Desc: color composition (w/o ALPHA) + * + * In : R, G, B + * Out : color + * + * Note: - + */ +static int vl_mixfix8fake (fixed r, fixed g, fixed b) +{ + return array_b[b>>FIXED_SHIFT]*G_CNT*R_CNT + + array_g[g>>FIXED_SHIFT]*R_CNT + + array_r[r>>FIXED_SHIFT]; +} +#define vl_mixfix8 vl_mixfix8fake +static int vl_mixfix15 (fixed r, fixed g, fixed b) +{ + return ((r>>(3+FIXED_SHIFT))<<10) + |((g>>(3+FIXED_SHIFT))<<5) + |(b>>(3+FIXED_SHIFT)); +} +static int vl_mixfix16 (fixed r, fixed g, fixed b) +{ + return ((r>>(3+FIXED_SHIFT))<<11) + |((g>>(2+FIXED_SHIFT))<<5) + |(b>>(3+FIXED_SHIFT)); +} +#define vl_mixfix24 vl_mixfix32 +static int vl_mixfix32 (fixed r, fixed g, fixed b) +{ + return ((r>>FIXED_SHIFT)<<16) + |((g>>FIXED_SHIFT)<<8) + |(b>>FIXED_SHIFT); +} + + + +/* Desc: color composition (w/ ALPHA) + * + * In : array of integers (R, G, B, A) + * Out : color + * + * Note: - + */ +#define vl_mixrgba8 vl_mixrgb8fake +#define vl_mixrgba15 vl_mixrgb15 +#define vl_mixrgba16 vl_mixrgb16 +#define vl_mixrgba24 vl_mixrgb24 +static int vl_mixrgba32 (const unsigned char rgba[]) +{ + /* Hack alert: + * currently, DMesa uses Mesa's alpha buffer; + * so we don't really care about alpha value here... + */ + return /*(rgba[3]<<24)|*/(rgba[0]<<16)|(rgba[1]<<8)|(rgba[2]); +} + + + +/* Desc: color composition (w/o ALPHA) + * + * In : array of integers (R, G, B) + * Out : color + * + * Note: - + */ +static int vl_mixrgb8fake (const unsigned char rgb[]) +{ + return array_b[rgb[2]]*G_CNT*R_CNT + + array_g[rgb[1]]*R_CNT + + array_r[rgb[0]]; +} +#define vl_mixrgb8 vl_mixrgb8fake +static int vl_mixrgb15 (const unsigned char rgb[]) +{ + return ((rgb[0]>>3)<<10)|((rgb[1]>>3)<<5)|(rgb[2]>>3); +} +static int vl_mixrgb16 (const unsigned char rgb[]) +{ + return ((rgb[0]>>3)<<11)|((rgb[1]>>2)<<5)|(rgb[2]>>3); +} +#define vl_mixrgb24 vl_mixrgb32 +static int vl_mixrgb32 (const unsigned char rgb[]) +{ + return (rgb[0]<<16)|(rgb[1]<<8)|(rgb[2]); +} + + + +/* Desc: color decomposition + * + * In : pixel offset, array of integers to hold color components (R, G, B, A) + * Out : - + * + * Note: uses current read buffer + */ +static void v_getrgba8fake6 (unsigned int offset, unsigned char rgba[4]) +{ + word32 c = VGAPalette[((word8 *)vl_current_read_buffer)[offset]]; + rgba[0] = _rgb_scale_6[(c >> 16) & 0x3F]; + rgba[1] = _rgb_scale_6[(c >> 8) & 0x3F]; + rgba[2] = _rgb_scale_6[c & 0x3F]; + /*rgba[3] = c >> 24;*/ /* dummy alpha; we have separate SW alpha, so ignore */ +} +static void v_getrgba8fake8 (unsigned int offset, unsigned char rgba[4]) +{ + word32 c = VGAPalette[((word8 *)vl_current_read_buffer)[offset]]; + rgba[0] = c >> 16; + rgba[1] = c >> 8; + rgba[2] = c; + /*rgba[3] = c >> 24;*/ /* dummy alpha; we have separate SW alpha, so ignore */ +} +#define v_getrgba8 v_getrgba8fake6 +static void v_getrgba15 (unsigned int offset, unsigned char rgba[4]) +{ + word32 c = ((word16 *)vl_current_read_buffer)[offset]; +#if HUGE_LOOKUP + c &= 0x7fff; + rgba[0] = pix15r[c]; + rgba[1] = pix15g[c]; + rgba[2] = pix15b[c]; +#else + rgba[0] = _rgb_scale_5[(c >> 10) & 0x1F]; + rgba[1] = _rgb_scale_5[(c >> 5) & 0x1F]; + rgba[2] = _rgb_scale_5[c & 0x1F]; +#endif + /*rgba[3] = 255;*/ /* dummy alpha; we have separate SW alpha, so ignore */ +} +static void v_getrgba16 (unsigned int offset, unsigned char rgba[4]) +{ + word32 c = ((word16 *)vl_current_read_buffer)[offset]; +#if HUGE_LOOKUP + rgba[0] = pix16r[c]; + rgba[1] = pix16g[c]; + rgba[2] = pix16b[c]; +#else + rgba[0] = _rgb_scale_5[(c >> 11) & 0x1F]; + rgba[1] = _rgb_scale_6[(c >> 5) & 0x3F]; + rgba[2] = _rgb_scale_5[c & 0x1F]; +#endif + /*rgba[3] = 255;*/ /* dummy alpha; we have separate SW alpha, so ignore */ +} +static void v_getrgba24 (unsigned int offset, unsigned char rgba[4]) +{ + word32 c = *(word32 *)((long)vl_current_read_buffer+offset*3); + rgba[0] = c >> 16; + rgba[1] = c >> 8; + rgba[2] = c; + /*rgba[3] = 255;*/ /* dummy alpha; we have separate SW alpha, so ignore */ +} +static void v_getrgba32 (unsigned int offset, unsigned char rgba[4]) +{ + word32 c = ((word32 *)vl_current_read_buffer)[offset]; + rgba[0] = c >> 16; + rgba[1] = c >> 8; + rgba[2] = c; + /*rgba[3] = c >> 24;*/ /* dummy alpha; we have separate SW alpha, so ignore */ +} + + + +/* Desc: pixel retrieval + * + * In : pixel offset + * Out : pixel value + * + * Note: uses current read buffer + */ +static int v_getpixel8 (unsigned int offset) +{ + return ((word8 *)vl_current_read_buffer)[offset]; +} +#define v_getpixel15 v_getpixel16 +static int v_getpixel16 (unsigned int offset) +{ + return ((word16 *)vl_current_read_buffer)[offset]; +} +static int v_getpixel24 (unsigned int offset) +{ + return *(word32 *)((long)vl_current_read_buffer+offset*3); +} +static int v_getpixel32 (unsigned int offset) +{ + return ((word32 *)vl_current_read_buffer)[offset]; +} + + + +/* Desc: set one palette entry + * + * In : index, R, G, B + * Out : - + * + * Note: color components are in range [0.0 .. 1.0] + */ +void vl_setCI (int index, float red, float green, float blue) +{ + drv->setCI_f(index, red, green, blue); +} + + + +/* Desc: set one palette entry + * + * In : color, R, G, B + * Out : - + * + * Note: - + */ +static void fake_setcolor (int c, int r, int g, int b) +{ + VGAPalette[c] = 0xff000000 | (r<<16) | (g<<8) | b; + + drv->setCI_i(c, r, g, b); +} + + + +/* Desc: build FakeColor palette + * + * In : CI precision in bits + * Out : - + * + * Note: - + */ +static void fake_buildpalette (int bits) +{ + double c_r, c_g, c_b; + int r, g, b, color = 0; + + double max = (1 << bits) - 1; + + for (b=0; b> 8; + g = (pixel & 0x03E0) >> 3; + b = (pixel & 0x001F) << 2; + + r = (unsigned int)(((double)r * 255. / 0x7c) + 0.5); + g = (unsigned int)(((double)g * 255. / 0x7c) + 0.5); + b = (unsigned int)(((double)b * 255. / 0x7c) + 0.5); + + pix15r[pixel] = r; + pix15g[pixel] = g; + pix15b[pixel] = b; + } + + /* 16bit */ + r = (pixel & 0xF800) >> 8; + g = (pixel & 0x07E0) >> 3; + b = (pixel & 0x001F) << 3; + + r = (unsigned int)(((double)r * 255. / 0xF8) + 0.5); + g = (unsigned int)(((double)g * 255. / 0xFC) + 0.5); + b = (unsigned int)(((double)b * 255. / 0xF8) + 0.5); + + pix16r[pixel] = r; + pix16g[pixel] = g; + pix16b[pixel] = b; + } +} +#endif + + + +/* Desc: initialize hardware + * + * In : - + * Out : list of available modes + * + * Note: when returning non-NULL, global variable `drv' is guaranteed to be ok + */ +static vl_mode *v_init_hw (void) +{ + static vl_mode *q = NULL; + + if (q == NULL) { + /* initialize hardware */ + if ((q = VESA.init()) != NULL) { + drv = &VESA; + } else if ((q = VGA.init()) != NULL) { + drv = &VGA; + } else { + drv = NULL; + } + } + + return q; +} + + + +/* Desc: sync buffer with video hardware + * + * In : ptr to old buffer, position, size + * Out : 0 if success + * + * Note: - + */ +int vl_sync_buffer (void **buffer, int x, int y, int width, int height) +{ + if ((width & 7) || (x < 0) || (y < 0) || (x+width > video_mode->xres) || (y+height > video_mode->yres)) { + return -1; + } else { + void *newbuf = *buffer; + + if ((newbuf == NULL) || (vl_current_width != width) || (vl_current_height != height)) { + newbuf = realloc(newbuf, width * height * video_bypp); + } + + if (newbuf == NULL) { + return -2; + } + + vl_current_width = width; + vl_current_height = height; + vl_current_stride = vl_current_width * video_bypp; + vl_current_bytes = vl_current_stride * height; + + vl_current_offset = video_scanlen * y + video_bypp * x; + vl_current_delta = video_scanlen - vl_current_stride; + + vl_current_draw_buffer = vl_current_read_buffer = *buffer = newbuf; + return 0; + } +} + + + +/* Desc: state retrieval + * + * In : name, storage + * Out : -1 for an error + * + * Note: - + */ +int vl_get (int pname, int *params) +{ + switch (pname) { + case VL_GET_SCREEN_SIZE: + params[0] = video_mode->xres; + params[1] = video_mode->yres; + break; + case VL_GET_VIDEO_MODES: + { + int n; + vl_mode *q; + if ((q = v_init_hw()) == NULL) { + return -1; + } + /* count available visuals */ + for (n = 0; q->mode != 0xffff; q++) { + if ((q + 1)->mode == (q->mode | 0x4000)) { + /* same mode, but linear */ + q++; + } + if (params) { + params[n] = (int)q; + } + n++; + } + return n; + } + default: + return (drv != NULL) ? drv->get(pname, params) : -1; + } + return 0; +} + + + +/* Desc: setup mode + * + * In : ptr to mode definition + * Out : 0 if success + * + * Note: - + */ +static int vl_setup_mode (vl_mode *p) +{ + if (p == NULL) { + return -1; + } + +#define INITPTR(bpp) \ + vl_putpixel = v_putpixel##bpp; \ + vl_getrgba = v_getrgba##bpp; \ + vl_getpixel = v_getpixel##bpp; \ + vl_rect = v_rect##bpp; \ + vl_mixfix = vl_mixfix##bpp; \ + vl_mixrgb = vl_mixrgb##bpp; \ + vl_mixrgba = vl_mixrgba##bpp; \ + vl_clear = _can_mmx() ? v_clear##bpp##_mmx : v_clear##bpp + + switch (p->bpp) { + case 8: + INITPTR(8); + break; + case 15: + INITPTR(15); + break; + case 16: + INITPTR(16); + break; + case 24: + INITPTR(24); + break; + case 32: + INITPTR(32); + break; + default: + return -1; + } + +#undef INITPTR + + video_mode = p; + video_bypp = (p->bpp+7)/8; + video_scanlen = p->scanlen; + vl_video_selector = p->sel; + + return 0; +} + + + +/* Desc: restore to the mode prior to first call to `vl_video_init'. + * + * In : - + * Out : - + * + * Note: - + */ +void vl_video_exit (void) +{ + drv->restore(); + drv->fini(); + video_mode = NULL; +} + + + +/* Desc: enter mode + * + * In : xres, yres, bits/pixel, RGB, refresh rate + * Out : pixel width in bits if success + * + * Note: - + */ +int vl_video_init (int width, int height, int bpp, int rgb, int refresh) +{ + int fake; + vl_mode *p, *q; + unsigned int min; + + fake = 0; + if (!rgb) { + bpp = 8; + } else if (bpp == 8) { + fake = 1; + } +#if HUGE_LOOKUP + else if (bpp < 24) { + v_init_pixeltables(); + } +#endif + + /* initialize hardware */ + if ((q = v_init_hw()) == NULL) { + return 0; + } + + /* search for a mode that fits our request */ + for (min=-1, p=NULL; q->mode!=0xffff; q++) { + if ((q->xres>=width) && (q->yres>=height) && (q->bpp==bpp)) { + if (min>=(unsigned)(q->xres*q->yres)) { + min = q->xres*q->yres; + p = q; + } + } + } + + /* setup and enter mode */ + if ((vl_setup_mode(p) == 0) && (drv->entermode(p, refresh) == 0)) { + vl_flip = drv->blit; + if (fake) { + drv->get(VL_GET_CI_PREC, (int *)(&min)); + fake_buildpalette(min); + if (min == 8) { + vl_getrgba = v_getrgba8fake8; + } + } + return bpp; + } + + /* abort */ + return 0; +} diff --git a/reactos/lib/mesa32/src/drivers/dos/video.h b/reactos/lib/mesa32/src/drivers/dos/video.h new file mode 100644 index 00000000000..e928f19c373 --- /dev/null +++ b/reactos/lib/mesa32/src/drivers/dos/video.h @@ -0,0 +1,65 @@ +/* + * Mesa 3-D graphics library + * Version: 4.0 + * + * 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 + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * DOS/DJGPP device driver v1.5 for Mesa + * + * Copyright (C) 2002 - Borca Daniel + * Email : dborca@users.sourceforge.net + * Web : http://www.geocities.com/dborca + */ + + +#ifndef VIDEO_H_included +#define VIDEO_H_included + +typedef int fixed; + +#define VL_GET_CARD_NAME 0x0100 +#define VL_GET_VRAM 0x0101 +#define VL_GET_CI_PREC 0x0200 +#define VL_GET_HPIXELS 0x0201 +#define VL_GET_SCREEN_SIZE 0x0202 +#define VL_GET_VIDEO_MODES 0x0300 + +extern int (*vl_mixfix) (fixed r, fixed g, fixed b); +extern int (*vl_mixrgb) (const unsigned char rgb[]); +extern int (*vl_mixrgba) (const unsigned char rgba[]); +extern void (*vl_getrgba) (unsigned int offset, unsigned char rgba[4]); + +extern void (*vl_clear) (int color); +extern void (*vl_rect) (int x, int y, int width, int height, int color); +extern void (*vl_flip) (void); +extern void (*vl_putpixel) (unsigned int offset, int color); +extern int (*vl_getpixel) (unsigned int offset); + +void vl_setCI (int index, float red, float green, float blue); + +int vl_sync_buffer (void **buffer, int x, int y, int width, int height); +int vl_get (int pname, int *params); + +void vl_video_exit (void); +int vl_video_init (int width, int height, int bpp, int rgb, int refresh); + +#endif diff --git a/reactos/lib/mesa32/src/drivers/dos/virtual.S b/reactos/lib/mesa32/src/drivers/dos/virtual.S new file mode 100644 index 00000000000..677f07a6263 --- /dev/null +++ b/reactos/lib/mesa32/src/drivers/dos/virtual.S @@ -0,0 +1,495 @@ +/* + * Mesa 3-D graphics library + * Version: 4.0 + * + * 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 + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * DOS/DJGPP device driver v1.4 for Mesa + * + * Copyright (C) 2002 - Borca Daniel + * Email : dborca@yahoo.com + * Web : http://www.geocities.com/dborca + */ + + +#include "x86/assyntax.h" + + + FILE("virtual.S") + +/* + * extern void *vl_current_draw_buffer; + * extern int vl_current_width, vl_current_bytes; + */ +EXTERN _vl_current_draw_buffer +EXTERN _vl_current_width, _vl_current_bytes + + SEG_TEXT + USE32 + +/* Desc: void v_clear8 (int color); + * + * In : color + * Out : - + * + * Note: uses current draw buffer + */ + ALIGNTEXT32 + GLOBL _v_clear8 +_v_clear8: + MOV_L (REGOFF(4, ESP), EAX) + MOV_B (AL, AH) + PUSH_W (AX) + PUSH_W (AX) + POP_L (EAX) + jmp _v_clear_common + +/* Desc: void v_clear16 (int color); + * + * In : color + * Out : - + * + * Note: uses current draw buffer + */ + ALIGNTEXT32 + GLOBL _v_clear16 +_v_clear16: + MOV_L (REGOFF(4, ESP), EAX) + PUSH_W (AX) + PUSH_W (AX) + POP_L (EAX) + jmp _v_clear_common + +/* Desc: void v_clear32 (int color); + * + * In : color + * Out : - + * + * Note: uses current draw buffer + */ + ALIGNTEXT32 + GLOBL _v_clear32 +_v_clear32: + MOV_L (REGOFF(4, ESP), EAX) + ALIGNTEXT4 +_v_clear_common: + MOV_L (CONTENT(_vl_current_bytes), ECX) + MOV_L (CONTENT(_vl_current_draw_buffer), EDX) + SHR_L (CONST(2), ECX) + ALIGNTEXT4 + TLBL(0): + MOV_L (EAX, REGIND(EDX)) + ADD_L (CONST(4), EDX) + DEC_L (ECX) + jnz TLBL(0) + RET + +/* Desc: void v_clear8_mmx (int color); + * + * In : color + * Out : - + * + * Note: uses current draw buffer + */ + ALIGNTEXT32 + GLOBL _v_clear8_mmx +_v_clear8_mmx: +#ifdef USE_MMX_ASM + MOVD (REGOFF(4, ESP), MM0) + PUNPCKLBW (MM0, MM0) + PUNPCKLWD (MM0, MM0) + jmp _v_clear_common_mmx +#endif + +/* Desc: void v_clear16_mmx (int color); + * + * In : color + * Out : - + * + * Note: uses current draw buffer + */ + ALIGNTEXT32 + GLOBL _v_clear16_mmx +_v_clear16_mmx: +#ifdef USE_MMX_ASM + MOVD (REGOFF(4, ESP), MM0) + PUNPCKLWD (MM0, MM0) + jmp _v_clear_common_mmx +#endif + +/* Desc: void v_clear32_mmx (int color); + * + * In : color + * Out : - + * + * Note: uses current draw buffer + */ + ALIGNTEXT32 + GLOBL _v_clear32_mmx +_v_clear32_mmx: +#ifdef USE_MMX_ASM + MOVD (REGOFF(4, ESP), MM0) + ALIGNTEXT4 +_v_clear_common_mmx: + PUNPCKLDQ (MM0, MM0) + MOV_L (CONTENT(_vl_current_bytes), ECX) + MOV_L (CONTENT(_vl_current_draw_buffer), EDX) + SHR_L (CONST(3), ECX) + ALIGNTEXT4 + TLBL(0): + MOVQ (MM0, REGIND(EDX)) + ADD_L (CONST(8), EDX) + DEC_L (ECX) + jnz TLBL(0) + EMMS +#endif + RET + +/* Desc: void v_clear24 (int color); + * + * In : color + * Out : - + * + * Note: uses current draw buffer + */ + ALIGNTEXT32 + GLOBL _v_clear24 +_v_clear24: + MOV_L (CONST(0xaaaaaaab), EAX) + MUL_L (CONTENT(_vl_current_bytes)) + MOV_L (REGOFF(4, ESP), EAX) + MOV_L (EDX, ECX) + PUSH_L (EBX) + MOV_L (CONTENT(_vl_current_draw_buffer), EDX) + SHR_L (CONST(1), ECX) + MOV_B (REGOFF(10,ESP), BL) + ALIGNTEXT4 + TLBL(0): + MOV_W (AX, REGIND(EDX)) + MOV_B (BL, REGOFF(2,EDX)) + ADD_L (CONST(3), EDX) + DEC_L (ECX) + jnz TLBL(0) + POP_L (EBX) + RET + +/* Desc: void v_clear24_mmx (int color); + * + * In : color + * Out : - + * + * Note: uses current draw buffer + */ + ALIGNTEXT32 + GLOBL _v_clear24_mmx +_v_clear24_mmx: +#ifdef USE_MMX_ASM + MOV_L (REGOFF(4, ESP), EAX) + MOV_L (EAX, EDX) + MOV_L (EAX, ECX) + SHL_L (CONST(16), EDX) + ROR_L (CONST(8), ECX) + MOV_W (CX, DX) + ROR_L (CONST(16), ECX) + MOV_B (DH, CL) + SHL_L (CONST(8), EAX) + MOV_B (CH, AL) + ROR_L (CONST(8), EAX) + + PUSH_L (EDX) + PUSH_L (EAX) + MOVQ (REGIND(ESP), MM0) + PUSH_L (ECX) + MOVQ (REGIND(ESP), MM1) + PUSH_L (EDX) + MOVQ (REGIND(ESP), MM2) + + MOV_L (CONST(0xaaaaaaab), EAX) + MUL_L (CONTENT(_vl_current_bytes)) + MOV_L (EDX, ECX) + MOV_L (CONTENT(_vl_current_draw_buffer), EDX) + SHR_L (CONST(4), ECX) + ALIGNTEXT4 + TLBL(0): + MOVQ (MM0, REGIND(EDX)) + MOVQ (MM1, REGOFF(8,EDX)) + MOVQ (MM2, REGOFF(16,EDX)) + ADD_L (CONST(24), EDX) + DEC_L (ECX) + jnz TLBL(0) + EMMS + ADD_L (CONST(16), ESP) +#endif + RET + +/* Desc: void v_rect8 (int color); + * + * In : color + * Out : - + * + * Note: uses current draw buffer + */ + ALIGNTEXT32 + GLOBL _v_rect8 +_v_rect8: + CLD + PUSH_L (ESI) + PUSH_L (EDI) + MOV_L (REGOFF(28, ESP), EAX) + MOV_L (CONTENT(_vl_current_width), ESI) + MOV_L (REGOFF(16, ESP), EDI) + MOV_B (AL, AH) + MOV_L (REGOFF(20, ESP), ECX) + IMUL_L (ESI, EDI) + MOV_L (REGOFF(24, ESP), EDX) + SUB_L (ECX, ESI) + ADD_L (REGOFF(12, ESP), EDI) + PUSH_W (AX) + PUSH_W (AX) + PUSH_SR (DS) + POP_SR (ES) + ADD_L (CONTENT(_vl_current_draw_buffer), EDI) + POP_L (EAX) + PUSH_L (EBX) + MOV_L (ECX, EBX) + AND_L (CONST(3), EBX) + ALIGNTEXT4 + TLBL(0): + PUSH_L (ECX) + ALIGNTEXT4 + TLBL(1): + SHR_L (CONST(2), ECX) + REP STOS_L + TEST_L (EBX, EBX) + jz TLBL(2) + MOV_L (EBX, ECX) + REP STOS_B + ALIGNTEXT4 + TLBL(2): + POP_L (ECX) + ADD_L (ESI, EDI) + DEC_L (EDX) + jnz TLBL(0) + POP_L (EBX) + POP_L (EDI) + POP_L (ESI) + RET + +/* Desc: void v_rect16 (int color); + * + * In : color + * Out : - + * + * Note: uses current draw buffer + */ + ALIGNTEXT32 + GLOBL _v_rect16 +_v_rect16: + CLD + PUSH_L (ESI) + PUSH_L (EDI) + MOV_L (REGOFF(28, ESP), EAX) + MOV_L (CONTENT(_vl_current_width), ESI) + MOV_L (REGOFF(16, ESP), EDI) + MOV_L (REGOFF(20, ESP), ECX) + IMUL_L (ESI, EDI) + MOV_L (REGOFF(24, ESP), EDX) + SUB_L (ECX, ESI) + ADD_L (REGOFF(12, ESP), EDI) + PUSH_W (AX) + SHL_L (CONST(1), ESI) + PUSH_W (AX) + SHL_L (CONST(1), EDI) + PUSH_SR (DS) + POP_SR (ES) + ADD_L (CONTENT(_vl_current_draw_buffer), EDI) + POP_L (EAX) + ALIGNTEXT4 + TLBL(0): + PUSH_L (ECX) + ALIGNTEXT4 + TLBL(1): + SHR_L (CONST(1), ECX) + REP STOS_L + jnc TLBL(2) + STOS_W + ALIGNTEXT4 + TLBL(2): + POP_L (ECX) + ADD_L (ESI, EDI) + DEC_L (EDX) + jnz TLBL(0) + POP_L (EDI) + POP_L (ESI) + RET + +/* Desc: void v_rect24 (int color); + * + * In : color + * Out : - + * + * Note: uses current draw buffer + */ + ALIGNTEXT32 + GLOBL _v_rect24 +_v_rect24: + PUSH_L (ESI) + PUSH_L (EDI) + MOV_L (REGOFF(28, ESP), EAX) + MOV_L (CONTENT(_vl_current_width), ESI) + MOV_L (REGOFF(16, ESP), EDI) + MOV_L (REGOFF(20, ESP), ECX) + IMUL_L (ESI, EDI) + MOV_L (REGOFF(24, ESP), EDX) + SUB_L (ECX, ESI) + ADD_L (REGOFF(12, ESP), EDI) + LEA_L (REGBIS(ESI, ESI, 2), ESI) + PUSH_L (EBX) + LEA_L (REGBIS(EDI, EDI, 2), EDI) + MOV_L (EAX, EBX) + ADD_L (CONTENT(_vl_current_draw_buffer), EDI) + SHR_L (CONST(16), EBX) + ALIGNTEXT4 + TLBL(0): + PUSH_L (ECX) + ALIGNTEXT4 + TLBL(1): + MOV_W (AX, REGIND(EDI)) + MOV_B (BL, REGOFF(2,EDI)) + ADD_L (CONST(3), EDI) + DEC_L (ECX) + jnz TLBL(1) + POP_L (ECX) + ADD_L (ESI, EDI) + DEC_L (EDX) + jnz TLBL(0) + POP_L (EBX) + POP_L (EDI) + POP_L (ESI) + RET + +/* Desc: void v_rect32 (int color); + * + * In : color + * Out : - + * + * Note: uses current draw buffer + */ + ALIGNTEXT32 + GLOBL _v_rect32 +_v_rect32: + PUSH_L (ESI) + PUSH_L (EDI) + MOV_L (CONTENT(_vl_current_width), ESI) + MOV_L (REGOFF(16, ESP), EDI) + MOV_L (REGOFF(20, ESP), ECX) + IMUL_L (ESI, EDI) + MOV_L (REGOFF(24, ESP), EDX) + SUB_L (ECX, ESI) + ADD_L (REGOFF(12, ESP), EDI) + SHL_L (CONST(2), ESI) + SHL_L (CONST(2), EDI) + MOV_L (REGOFF(28, ESP), EAX) + ADD_L (CONTENT(_vl_current_draw_buffer), EDI) + ALIGNTEXT4 + TLBL(0): + PUSH_L (ECX) + ALIGNTEXT4 + TLBL(1): + MOV_L (EAX, REGIND(EDI)) + ADD_L (CONST(4), EDI) + DEC_L (ECX) + jnz TLBL(1) + POP_L (ECX) + ADD_L (ESI, EDI) + DEC_L (EDX) + jnz TLBL(0) + POP_L (EDI) + POP_L (ESI) + RET + +/* Desc: void v_putpixel8 (unsigned int offset, int color); + * + * In : offset within buffer, color + * Out : - + * + * Note: uses current draw buffer + */ + ALIGNTEXT32 + GLOBL _v_putpixel8 +_v_putpixel8: + MOV_L (REGOFF(8, ESP), ECX) + MOV_L (REGOFF(4, ESP), EDX) + MOV_L (CONTENT(_vl_current_draw_buffer), EAX) + MOV_B (CL, REGBI(EAX,EDX)) + RET + +/* Desc: void v_putpixel16 (unsigned int offset, int color); + * + * In : offset within buffer, color + * Out : - + * + * Note: uses current draw buffer + */ + ALIGNTEXT32 + GLOBL _v_putpixel16 +_v_putpixel16: + MOV_L (REGOFF(8, ESP), ECX) + MOV_L (REGOFF(4, ESP), EDX) + MOV_L (CONTENT(_vl_current_draw_buffer), EAX) + MOV_W (CX, REGBIS(EAX,EDX,2)) + RET + +/* Desc: void v_putpixel24 (unsigned int offset, int color); + * + * In : offset within buffer, color + * Out : - + * + * Note: uses current draw buffer + */ + ALIGNTEXT32 + GLOBL _v_putpixel24 +_v_putpixel24: + MOV_L (REGOFF(4, ESP), EAX) + MOV_L (REGOFF(8, ESP), EDX) + MOV_L (CONTENT(_vl_current_draw_buffer), ECX) + LEA_L (REGBIS(EAX,EAX,2), EAX) + MOV_W (DX, REGBI(ECX,EAX)) + SHR_L (CONST(16), EDX) + MOV_B (DL, REGBID(ECX,EAX,2)) + RET + +/* Desc: void v_putpixel32 (unsigned int offset, int color); + * + * In : offset within buffer, color + * Out : - + * + * Note: uses current draw buffer + */ + ALIGNTEXT32 + GLOBL _v_putpixel32 +_v_putpixel32: + MOV_L (REGOFF(8, ESP), ECX) + MOV_L (REGOFF(4, ESP), EDX) + MOV_L (CONTENT(_vl_current_draw_buffer), EAX) + MOV_L (ECX, REGBIS(EAX,EDX,4)) + RET diff --git a/reactos/lib/mesa32/src/drivers/dri/common/depthtmp.h b/reactos/lib/mesa32/src/drivers/dri/common/depthtmp.h new file mode 100644 index 00000000000..f3da61e5199 --- /dev/null +++ b/reactos/lib/mesa32/src/drivers/dri/common/depthtmp.h @@ -0,0 +1,176 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/common/depthtmp.h,v 1.5 2001/03/21 16:14:20 dawes Exp $ */ + +#ifndef DBG +#define DBG 0 +#endif + + +#ifndef HAVE_HW_DEPTH_SPANS +#define HAVE_HW_DEPTH_SPANS 0 +#endif +#ifndef HAVE_HW_DEPTH_PIXELS +#define HAVE_HW_DEPTH_PIXELS 0 +#endif + +#ifndef HW_READ_LOCK +#define HW_READ_LOCK() HW_LOCK() +#endif +#ifndef HW_READ_UNLOCK +#define HW_READ_UNLOCK() HW_UNLOCK() +#endif + +static void TAG(WriteDepthSpan)( GLcontext *ctx, + GLuint n, GLint x, GLint y, + const GLdepth *depth, + const GLubyte mask[] ) +{ + HW_WRITE_LOCK() + { + GLint x1; + GLint n1; + LOCAL_DEPTH_VARS; + + y = Y_FLIP( y ); + +#if HAVE_HW_DEPTH_SPANS + (void) x1; (void) n1; + + if ( DBG ) fprintf( stderr, "WriteDepthSpan 0..%d (x1 %d)\n", + (int)n, (int)x ); + + WRITE_DEPTH_SPAN(); +#else + HW_CLIPLOOP() + { + GLint i = 0; + CLIPSPAN( x, y, n, x1, n1, i ); + + if ( DBG ) fprintf( stderr, "WriteDepthSpan %d..%d (x1 %d)\n", + (int)i, (int)n1, (int)x1 ); + + if ( mask ) { + for ( ; i < n1 ; i++, x1++ ) { + if ( mask[i] ) WRITE_DEPTH( x1, y, depth[i] ); + } + } else { + for ( ; i < n1 ; i++, x1++ ) { + WRITE_DEPTH( x1, y, depth[i] ); + } + } + } + HW_ENDCLIPLOOP(); +#endif + } + HW_WRITE_UNLOCK(); +} + +static void TAG(WriteDepthPixels)( GLcontext *ctx, + GLuint n, + const GLint x[], + const GLint y[], + const GLdepth depth[], + const GLubyte mask[] ) +{ + HW_WRITE_LOCK() + { + GLint i; + LOCAL_DEPTH_VARS; + + if ( DBG ) fprintf( stderr, "WriteDepthPixels\n" ); + +#if HAVE_HW_DEPTH_PIXELS + (void) i; + + WRITE_DEPTH_PIXELS(); +#else + HW_CLIPLOOP() + { + for ( i = 0 ; i < n ; i++ ) { + if ( mask[i] ) { + const int fy = Y_FLIP( y[i] ); + if ( CLIPPIXEL( x[i], fy ) ) + WRITE_DEPTH( x[i], fy, depth[i] ); + } + } + } + HW_ENDCLIPLOOP(); +#endif + } + HW_WRITE_UNLOCK(); +} + + +/* Read depth spans and pixels + */ +static void TAG(ReadDepthSpan)( GLcontext *ctx, + GLuint n, GLint x, GLint y, + GLdepth depth[] ) +{ + HW_READ_LOCK() + { + GLint x1, n1; + LOCAL_DEPTH_VARS; + + y = Y_FLIP( y ); + + if ( DBG ) fprintf( stderr, "ReadDepthSpan\n" ); + +#if HAVE_HW_DEPTH_SPANS + (void) x1; (void) n1; + + READ_DEPTH_SPAN(); +#else + HW_CLIPLOOP() + { + GLint i = 0; + CLIPSPAN( x, y, n, x1, n1, i ); + for ( ; i < n1 ; i++ ) + READ_DEPTH( depth[i], (x1+i), y ); + } + HW_ENDCLIPLOOP(); +#endif + } + HW_READ_UNLOCK(); +} + +static void TAG(ReadDepthPixels)( GLcontext *ctx, GLuint n, + const GLint x[], const GLint y[], + GLdepth depth[] ) +{ + HW_READ_LOCK() + { + GLint i; + LOCAL_DEPTH_VARS; + + if ( DBG ) fprintf( stderr, "ReadDepthPixels\n" ); + +#if HAVE_HW_DEPTH_PIXELS + (void) i; + + READ_DEPTH_PIXELS(); +#else + HW_CLIPLOOP() + { + for ( i = 0 ; i < n ;i++ ) { + int fy = Y_FLIP( y[i] ); + if ( CLIPPIXEL( x[i], fy ) ) + READ_DEPTH( depth[i], x[i], fy ); + } + } + HW_ENDCLIPLOOP(); +#endif + } + HW_READ_UNLOCK(); +} + + +#if HAVE_HW_DEPTH_SPANS +#undef WRITE_DEPTH_SPAN +#undef WRITE_DEPTH_PIXELS +#undef READ_DEPTH_SPAN +#undef READ_DEPTH_PIXELS +#else +#undef WRITE_DEPTH +#undef READ_DEPTH +#endif +#undef TAG diff --git a/reactos/lib/mesa32/src/drivers/dri/common/mm.c b/reactos/lib/mesa32/src/drivers/dri/common/mm.c new file mode 100644 index 00000000000..6572ccd9914 --- /dev/null +++ b/reactos/lib/mesa32/src/drivers/dri/common/mm.c @@ -0,0 +1,196 @@ +/* + * GLX Hardware Device Driver common code + * Copyright (C) 1999 Wittawat Yamwong + * + * 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 + * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS 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. + * + */ +/* $XFree86: xc/lib/GL/mesa/src/drv/common/mm.c,v 1.4 2002/10/30 12:51:27 alanh Exp $ */ + +#include +#include + +#include "mm.h" + + +void mmDumpMemInfo( memHeap_t *heap ) +{ + TMemBlock *p; + + fprintf(stderr, "Memory heap %p:\n", (void *)heap); + if (heap == 0) { + fprintf(stderr, " heap == 0\n"); + } else { + p = (TMemBlock *)heap; + while (p) { + fprintf(stderr, " Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size, + p->free ? '.':'U', + p->reserved ? 'R':'.'); + p = p->next; + } + } + fprintf(stderr, "End of memory blocks\n"); +} + +memHeap_t *mmInit(int ofs, + int size) +{ + PMemBlock blocks; + + if (size <= 0) { + return 0; + } + blocks = (TMemBlock *) calloc(1,sizeof(TMemBlock)); + if (blocks) { + blocks->ofs = ofs; + blocks->size = size; + blocks->free = 1; + return (memHeap_t *)blocks; + } else + return 0; +} + + +static TMemBlock* SliceBlock(TMemBlock *p, + int startofs, int size, + int reserved, int alignment) +{ + TMemBlock *newblock; + + /* break left */ + if (startofs > p->ofs) { + newblock = (TMemBlock*) calloc(1,sizeof(TMemBlock)); + if (!newblock) + return NULL; + newblock->ofs = startofs; + newblock->size = p->size - (startofs - p->ofs); + newblock->free = 1; + newblock->next = p->next; + p->size -= newblock->size; + p->next = newblock; + p = newblock; + } + + /* break right */ + if (size < p->size) { + newblock = (TMemBlock*) calloc(1,sizeof(TMemBlock)); + if (!newblock) + return NULL; + newblock->ofs = startofs + size; + newblock->size = p->size - size; + newblock->free = 1; + newblock->next = p->next; + p->size = size; + p->next = newblock; + } + + /* p = middle block */ + p->align = alignment; + p->free = 0; + p->reserved = reserved; + return p; +} + +PMemBlock mmAllocMem( memHeap_t *heap, int size, int align2, int startSearch) +{ + int mask,startofs,endofs; + TMemBlock *p; + + if (!heap || align2 < 0 || size <= 0) + return NULL; + mask = (1 << align2)-1; + startofs = 0; + p = (TMemBlock *)heap; + while (p) { + if ((p)->free) { + startofs = (p->ofs + mask) & ~mask; + if ( startofs < startSearch ) { + startofs = startSearch; + } + endofs = startofs+size; + if (endofs <= (p->ofs+p->size)) + break; + } + p = p->next; + } + if (!p) + return NULL; + p = SliceBlock(p,startofs,size,0,mask+1); + p->heap = heap; + return p; +} + +static __inline__ int Join2Blocks(TMemBlock *p) +{ + if (p->free && p->next && p->next->free) { + TMemBlock *q = p->next; + p->size += q->size; + p->next = q->next; + free(q); + return 1; + } + return 0; +} + +int mmFreeMem(PMemBlock b) +{ + TMemBlock *p,*prev; + + if (!b) + return 0; + if (!b->heap) { + fprintf(stderr, "no heap\n"); + return -1; + } + p = b->heap; + prev = NULL; + while (p && p != b) { + prev = p; + p = p->next; + } + if (!p || p->free || p->reserved) { + if (!p) + fprintf(stderr, "block not found in heap\n"); + else if (p->free) + fprintf(stderr, "block already free\n"); + else + fprintf(stderr, "block is reserved\n"); + return -1; + } + p->free = 1; + Join2Blocks(p); + if (prev) + Join2Blocks(prev); + return 0; +} + + +void mmDestroy(memHeap_t *heap) +{ + TMemBlock *p,*q; + + if (!heap) + return; + p = (TMemBlock *)heap; + while (p) { + q = p->next; + free(p); + p = q; + } +} diff --git a/reactos/lib/mesa32/src/drivers/dri/common/mm.h b/reactos/lib/mesa32/src/drivers/dri/common/mm.h new file mode 100644 index 00000000000..d52871d39f3 --- /dev/null +++ b/reactos/lib/mesa32/src/drivers/dri/common/mm.h @@ -0,0 +1,82 @@ +/* + * GLX Hardware Device Driver common code + * Copyright (C) 1999 Keith Whitwell + * + * 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 + * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS 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 MM_INC +#define MM_INC + +struct mem_block_t { + struct mem_block_t *next; + struct mem_block_t *heap; + int ofs,size; + int align; + int free:1; + int reserved:1; +}; +typedef struct mem_block_t TMemBlock; +typedef struct mem_block_t *PMemBlock; + +/* a heap is just the first block in a chain */ +typedef struct mem_block_t memHeap_t; + +static __inline__ int mmBlockSize(PMemBlock b) +{ return b->size; } + +static __inline__ int mmOffset(PMemBlock b) +{ return b->ofs; } + +/* + * input: total size in bytes + * return: a heap pointer if OK, NULL if error + */ +memHeap_t *mmInit( int ofs, int size ); + +/* + * Allocate 'size' bytes with 2^align2 bytes alignment, + * restrict the search to free memory after 'startSearch' + * depth and back buffers should be in different 4mb banks + * to get better page hits if possible + * input: size = size of block + * align2 = 2^align2 bytes alignment + * startSearch = linear offset from start of heap to begin search + * return: pointer to the allocated block, 0 if error + */ +PMemBlock mmAllocMem( memHeap_t *heap, int size, int align2, + int startSearch ); + +/* + * Free block starts at offset + * input: pointer to a block + * return: 0 if OK, -1 if error + */ +int mmFreeMem( PMemBlock b ); + +/* + * destroy MM + */ +void mmDestroy( memHeap_t *mmInit ); + +/* For debuging purpose. */ +void mmDumpMemInfo( memHeap_t *mmInit ); + +#endif diff --git a/reactos/lib/mesa32/src/drivers/dri/common/mmx.h b/reactos/lib/mesa32/src/drivers/dri/common/mmx.h new file mode 100644 index 00000000000..49ce7e3e342 --- /dev/null +++ b/reactos/lib/mesa32/src/drivers/dri/common/mmx.h @@ -0,0 +1,560 @@ +/* mmx.h + + MultiMedia eXtensions GCC interface library for IA32. + + To use this library, simply include this header file + and compile with GCC. You MUST have inlining enabled + in order for mmx_ok() to work; this can be done by + simply using -O on the GCC command line. + + Compiling with -DMMX_TRACE will cause detailed trace + output to be sent to stderr for each mmx operation. + This adds lots of code, and obviously slows execution to + a crawl, but can be very useful for debugging. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT + LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR ANY PARTICULAR PURPOSE. + + 1997-98 by H. Dietz and R. Fisher + + History: + 97-98* R.Fisher Early versions + 980501 R.Fisher Original Release + 980611* H.Dietz Rewrite, correctly implementing inlines, and + R.Fisher including direct register accesses. + 980616 R.Fisher Release of 980611 as 980616. + 980714 R.Fisher Minor corrections to Makefile, etc. + 980715 R.Fisher mmx_ok() now prevents optimizer from using + clobbered values. + mmx_ok() now checks if cpuid instruction is + available before trying to use it. + 980726* R.Fisher mm_support() searches for AMD 3DNow, Cyrix + Extended MMX, and standard MMX. It returns a + value which is positive if any of these are + supported, and can be masked with constants to + see which. mmx_ok() is now a call to this + 980726* R.Fisher Added i2r support for shift functions + 980919 R.Fisher Fixed AMD extended feature recognition bug. + 980921 R.Fisher Added definition/check for _MMX_H. + Added "float s[2]" to mmx_t for use with + 3DNow and EMMX. So same mmx_t can be used. + 981013 R.Fisher Fixed cpuid function 1 bug (looked at wrong reg) + Fixed psllq_i2r error in mmxtest.c + + * Unreleased (internal or interim) versions + + Notes: + It appears that the latest gas has the pand problem fixed, therefore + I'll undefine BROKEN_PAND by default. + String compares may be quicker than the multiple test/jumps in vendor + test sequence in mmx_ok(), but I'm not concerned with that right now. + + Acknowledgments: + Jussi Laako for pointing out the errors ultimately found to be + connected to the failure to notify the optimizer of clobbered values. + Roger Hardiman for reminding us that CPUID isn't everywhere, and that + someone may actually try to use this on a machine without CPUID. + Also for suggesting code for checking this. + Robert Dale for pointing out the AMD recognition bug. + Jimmy Mayfield and Carl Witty for pointing out the Intel recognition + bug. + Carl Witty for pointing out the psllq_i2r test bug. +*/ + +#ifndef _MMX_H +#define _MMX_H + +//#define MMX_TRACE + +/* Warning: at this writing, the version of GAS packaged + with most Linux distributions does not handle the + parallel AND operation mnemonic correctly. If the + symbol BROKEN_PAND is defined, a slower alternative + coding will be used. If execution of mmxtest results + in an illegal instruction fault, define this symbol. +*/ +#undef BROKEN_PAND + + +/* The type of an value that fits in an MMX register + (note that long long constant values MUST be suffixed + by LL and unsigned long long values by ULL, lest + they be truncated by the compiler) +*/ +typedef union { + long long q; /* Quadword (64-bit) value */ + unsigned long long uq; /* Unsigned Quadword */ + int d[2]; /* 2 Doubleword (32-bit) values */ + unsigned int ud[2]; /* 2 Unsigned Doubleword */ + short w[4]; /* 4 Word (16-bit) values */ + unsigned short uw[4]; /* 4 Unsigned Word */ + char b[8]; /* 8 Byte (8-bit) values */ + unsigned char ub[8]; /* 8 Unsigned Byte */ + float s[2]; /* Single-precision (32-bit) value */ +} mmx_t; + +/* Helper functions for the instruction macros that follow... + (note that memory-to-register, m2r, instructions are nearly + as efficient as register-to-register, r2r, instructions; + however, memory-to-memory instructions are really simulated + as a convenience, and are only 1/3 as efficient) +*/ +#ifdef MMX_TRACE + +/* Include the stuff for printing a trace to stderr... +*/ + +#include + +#define mmx_i2r(op, imm, reg) \ + { \ + mmx_t mmx_trace; \ + mmx_trace = (imm); \ + fprintf(stderr, #op "_i2r(" #imm "=0x%016llx, ", mmx_trace.q); \ + __asm__ __volatile__ ("movq %%" #reg ", %0" \ + : "=X" (mmx_trace) \ + : /* nothing */ ); \ + fprintf(stderr, #reg "=0x%016llx) => ", mmx_trace.q); \ + __asm__ __volatile__ (#op " %0, %%" #reg \ + : /* nothing */ \ + : "X" (imm)); \ + __asm__ __volatile__ ("movq %%" #reg ", %0" \ + : "=X" (mmx_trace) \ + : /* nothing */ ); \ + fprintf(stderr, #reg "=0x%016llx\n", mmx_trace.q); \ + } + +#define mmx_m2r(op, mem, reg) \ + { \ + mmx_t mmx_trace; \ + mmx_trace = (mem); \ + fprintf(stderr, #op "_m2r(" #mem "=0x%016llx, ", mmx_trace.q); \ + __asm__ __volatile__ ("movq %%" #reg ", %0" \ + : "=X" (mmx_trace) \ + : /* nothing */ ); \ + fprintf(stderr, #reg "=0x%016llx) => ", mmx_trace.q); \ + __asm__ __volatile__ (#op " %0, %%" #reg \ + : /* nothing */ \ + : "X" (mem)); \ + __asm__ __volatile__ ("movq %%" #reg ", %0" \ + : "=X" (mmx_trace) \ + : /* nothing */ ); \ + fprintf(stderr, #reg "=0x%016llx\n", mmx_trace.q); \ + } + +#define mmx_r2m(op, reg, mem) \ + { \ + mmx_t mmx_trace; \ + __asm__ __volatile__ ("movq %%" #reg ", %0" \ + : "=X" (mmx_trace) \ + : /* nothing */ ); \ + fprintf(stderr, #op "_r2m(" #reg "=0x%016llx, ", mmx_trace.q); \ + mmx_trace = (mem); \ + fprintf(stderr, #mem "=0x%016llx) => ", mmx_trace.q); \ + __asm__ __volatile__ (#op " %%" #reg ", %0" \ + : "=X" (mem) \ + : /* nothing */ ); \ + mmx_trace = (mem); \ + fprintf(stderr, #mem "=0x%016llx\n", mmx_trace.q); \ + } + +#define mmx_r2r(op, regs, regd) \ + { \ + mmx_t mmx_trace; \ + __asm__ __volatile__ ("movq %%" #regs ", %0" \ + : "=X" (mmx_trace) \ + : /* nothing */ ); \ + fprintf(stderr, #op "_r2r(" #regs "=0x%016llx, ", mmx_trace.q); \ + __asm__ __volatile__ ("movq %%" #regd ", %0" \ + : "=X" (mmx_trace) \ + : /* nothing */ ); \ + fprintf(stderr, #regd "=0x%016llx) => ", mmx_trace.q); \ + __asm__ __volatile__ (#op " %" #regs ", %" #regd); \ + __asm__ __volatile__ ("movq %%" #regd ", %0" \ + : "=X" (mmx_trace) \ + : /* nothing */ ); \ + fprintf(stderr, #regd "=0x%016llx\n", mmx_trace.q); \ + } + +#define mmx_m2m(op, mems, memd) \ + { \ + mmx_t mmx_trace; \ + mmx_trace = (mems); \ + fprintf(stderr, #op "_m2m(" #mems "=0x%016llx, ", mmx_trace.q); \ + mmx_trace = (memd); \ + fprintf(stderr, #memd "=0x%016llx) => ", mmx_trace.q); \ + __asm__ __volatile__ ("movq %0, %%mm0\n\t" \ + #op " %1, %%mm0\n\t" \ + "movq %%mm0, %0" \ + : "=X" (memd) \ + : "X" (mems)); \ + mmx_trace = (memd); \ + fprintf(stderr, #memd "=0x%016llx\n", mmx_trace.q); \ + } + +#else + +/* These macros are a lot simpler without the tracing... +*/ + +#define mmx_i2r(op, imm, reg) \ + __asm__ __volatile__ (#op " $" #imm ", %%" #reg \ + : /* nothing */ \ + : /* nothing */); + +#define mmx_m2r(op, mem, reg) \ + __asm__ __volatile__ (#op " %0, %%" #reg \ + : /* nothing */ \ + : "X" (mem)) + +#define mmx_r2m(op, reg, mem) \ + __asm__ __volatile__ (#op " %%" #reg ", %0" \ + : "=X" (mem) \ + : /* nothing */ ) + +#define mmx_r2r(op, regs, regd) \ + __asm__ __volatile__ (#op " %" #regs ", %" #regd) + +#define mmx_m2m(op, mems, memd) \ + __asm__ __volatile__ ("movq %0, %%mm0\n\t" \ + #op " %1, %%mm0\n\t" \ + "movq %%mm0, %0" \ + : "=X" (memd) \ + : "X" (mems)) + +#endif + + +/* 1x64 MOVe Quadword + (this is both a load and a store... + in fact, it is the only way to store) +*/ +#define movq_m2r(var, reg) mmx_m2r(movq, var, reg) +#define movq_r2m(reg, var) mmx_r2m(movq, reg, var) +#define movq_r2r(regs, regd) mmx_r2r(movq, regs, regd) +#define movq(vars, vard) \ + __asm__ __volatile__ ("movq %1, %%mm0\n\t" \ + "movq %%mm0, %0" \ + : "=X" (vard) \ + : "X" (vars)) + + +/* 1x32 MOVe Doubleword + (like movq, this is both load and store... + but is most useful for moving things between + mmx registers and ordinary registers) +*/ +#define movd_m2r(var, reg) mmx_m2r(movd, var, reg) +#define movd_r2m(reg, var) mmx_r2m(movd, reg, var) +#define movd_r2r(regs, regd) mmx_r2r(movd, regs, regd) +#define movd(vars, vard) \ + __asm__ __volatile__ ("movd %1, %%mm0\n\t" \ + "movd %%mm0, %0" \ + : "=X" (vard) \ + : "X" (vars)) + + +/* 2x32, 4x16, and 8x8 Parallel ADDs +*/ +#define paddd_m2r(var, reg) mmx_m2r(paddd, var, reg) +#define paddd_r2r(regs, regd) mmx_r2r(paddd, regs, regd) +#define paddd(vars, vard) mmx_m2m(paddd, vars, vard) + +#define paddw_m2r(var, reg) mmx_m2r(paddw, var, reg) +#define paddw_r2r(regs, regd) mmx_r2r(paddw, regs, regd) +#define paddw(vars, vard) mmx_m2m(paddw, vars, vard) + +#define paddb_m2r(var, reg) mmx_m2r(paddb, var, reg) +#define paddb_r2r(regs, regd) mmx_r2r(paddb, regs, regd) +#define paddb(vars, vard) mmx_m2m(paddb, vars, vard) + + +/* 4x16 and 8x8 Parallel ADDs using Saturation arithmetic +*/ +#define paddsw_m2r(var, reg) mmx_m2r(paddsw, var, reg) +#define paddsw_r2r(regs, regd) mmx_r2r(paddsw, regs, regd) +#define paddsw(vars, vard) mmx_m2m(paddsw, vars, vard) + +#define paddsb_m2r(var, reg) mmx_m2r(paddsb, var, reg) +#define paddsb_r2r(regs, regd) mmx_r2r(paddsb, regs, regd) +#define paddsb(vars, vard) mmx_m2m(paddsb, vars, vard) + + +/* 4x16 and 8x8 Parallel ADDs using Unsigned Saturation arithmetic +*/ +#define paddusw_m2r(var, reg) mmx_m2r(paddusw, var, reg) +#define paddusw_r2r(regs, regd) mmx_r2r(paddusw, regs, regd) +#define paddusw(vars, vard) mmx_m2m(paddusw, vars, vard) + +#define paddusb_m2r(var, reg) mmx_m2r(paddusb, var, reg) +#define paddusb_r2r(regs, regd) mmx_r2r(paddusb, regs, regd) +#define paddusb(vars, vard) mmx_m2m(paddusb, vars, vard) + + +/* 2x32, 4x16, and 8x8 Parallel SUBs +*/ +#define psubd_m2r(var, reg) mmx_m2r(psubd, var, reg) +#define psubd_r2r(regs, regd) mmx_r2r(psubd, regs, regd) +#define psubd(vars, vard) mmx_m2m(psubd, vars, vard) + +#define psubw_m2r(var, reg) mmx_m2r(psubw, var, reg) +#define psubw_r2r(regs, regd) mmx_r2r(psubw, regs, regd) +#define psubw(vars, vard) mmx_m2m(psubw, vars, vard) + +#define psubb_m2r(var, reg) mmx_m2r(psubb, var, reg) +#define psubb_r2r(regs, regd) mmx_r2r(psubb, regs, regd) +#define psubb(vars, vard) mmx_m2m(psubb, vars, vard) + + +/* 4x16 and 8x8 Parallel SUBs using Saturation arithmetic +*/ +#define psubsw_m2r(var, reg) mmx_m2r(psubsw, var, reg) +#define psubsw_r2r(regs, regd) mmx_r2r(psubsw, regs, regd) +#define psubsw(vars, vard) mmx_m2m(psubsw, vars, vard) + +#define psubsb_m2r(var, reg) mmx_m2r(psubsb, var, reg) +#define psubsb_r2r(regs, regd) mmx_r2r(psubsb, regs, regd) +#define psubsb(vars, vard) mmx_m2m(psubsb, vars, vard) + + +/* 4x16 and 8x8 Parallel SUBs using Unsigned Saturation arithmetic +*/ +#define psubusw_m2r(var, reg) mmx_m2r(psubusw, var, reg) +#define psubusw_r2r(regs, regd) mmx_r2r(psubusw, regs, regd) +#define psubusw(vars, vard) mmx_m2m(psubusw, vars, vard) + +#define psubusb_m2r(var, reg) mmx_m2r(psubusb, var, reg) +#define psubusb_r2r(regs, regd) mmx_r2r(psubusb, regs, regd) +#define psubusb(vars, vard) mmx_m2m(psubusb, vars, vard) + + +/* 4x16 Parallel MULs giving Low 4x16 portions of results +*/ +#define pmullw_m2r(var, reg) mmx_m2r(pmullw, var, reg) +#define pmullw_r2r(regs, regd) mmx_r2r(pmullw, regs, regd) +#define pmullw(vars, vard) mmx_m2m(pmullw, vars, vard) + + +/* 4x16 Parallel MULs giving High 4x16 portions of results +*/ +#define pmulhw_m2r(var, reg) mmx_m2r(pmulhw, var, reg) +#define pmulhw_r2r(regs, regd) mmx_r2r(pmulhw, regs, regd) +#define pmulhw(vars, vard) mmx_m2m(pmulhw, vars, vard) + + +/* 4x16->2x32 Parallel Mul-ADD + (muls like pmullw, then adds adjacent 16-bit fields + in the multiply result to make the final 2x32 result) +*/ +#define pmaddwd_m2r(var, reg) mmx_m2r(pmaddwd, var, reg) +#define pmaddwd_r2r(regs, regd) mmx_r2r(pmaddwd, regs, regd) +#define pmaddwd(vars, vard) mmx_m2m(pmaddwd, vars, vard) + + +/* 1x64 bitwise AND +*/ +#ifdef BROKEN_PAND +#define pand_m2r(var, reg) \ + { \ + mmx_m2r(pandn, (mmx_t) -1LL, reg); \ + mmx_m2r(pandn, var, reg); \ + } +#define pand_r2r(regs, regd) \ + { \ + mmx_m2r(pandn, (mmx_t) -1LL, regd); \ + mmx_r2r(pandn, regs, regd) \ + } +#define pand(vars, vard) \ + { \ + movq_m2r(vard, mm0); \ + mmx_m2r(pandn, (mmx_t) -1LL, mm0); \ + mmx_m2r(pandn, vars, mm0); \ + movq_r2m(mm0, vard); \ + } +#else +#define pand_m2r(var, reg) mmx_m2r(pand, var, reg) +#define pand_r2r(regs, regd) mmx_r2r(pand, regs, regd) +#define pand(vars, vard) mmx_m2m(pand, vars, vard) +#endif + + +/* 1x64 bitwise AND with Not the destination +*/ +#define pandn_m2r(var, reg) mmx_m2r(pandn, var, reg) +#define pandn_r2r(regs, regd) mmx_r2r(pandn, regs, regd) +#define pandn(vars, vard) mmx_m2m(pandn, vars, vard) + + +/* 1x64 bitwise OR +*/ +#define por_m2r(var, reg) mmx_m2r(por, var, reg) +#define por_r2r(regs, regd) mmx_r2r(por, regs, regd) +#define por(vars, vard) mmx_m2m(por, vars, vard) + + +/* 1x64 bitwise eXclusive OR +*/ +#define pxor_m2r(var, reg) mmx_m2r(pxor, var, reg) +#define pxor_r2r(regs, regd) mmx_r2r(pxor, regs, regd) +#define pxor(vars, vard) mmx_m2m(pxor, vars, vard) + + +/* 2x32, 4x16, and 8x8 Parallel CoMPare for EQuality + (resulting fields are either 0 or -1) +*/ +#define pcmpeqd_m2r(var, reg) mmx_m2r(pcmpeqd, var, reg) +#define pcmpeqd_r2r(regs, regd) mmx_r2r(pcmpeqd, regs, regd) +#define pcmpeqd(vars, vard) mmx_m2m(pcmpeqd, vars, vard) + +#define pcmpeqw_m2r(var, reg) mmx_m2r(pcmpeqw, var, reg) +#define pcmpeqw_r2r(regs, regd) mmx_r2r(pcmpeqw, regs, regd) +#define pcmpeqw(vars, vard) mmx_m2m(pcmpeqw, vars, vard) + +#define pcmpeqb_m2r(var, reg) mmx_m2r(pcmpeqb, var, reg) +#define pcmpeqb_r2r(regs, regd) mmx_r2r(pcmpeqb, regs, regd) +#define pcmpeqb(vars, vard) mmx_m2m(pcmpeqb, vars, vard) + + +/* 2x32, 4x16, and 8x8 Parallel CoMPare for Greater Than + (resulting fields are either 0 or -1) +*/ +#define pcmpgtd_m2r(var, reg) mmx_m2r(pcmpgtd, var, reg) +#define pcmpgtd_r2r(regs, regd) mmx_r2r(pcmpgtd, regs, regd) +#define pcmpgtd(vars, vard) mmx_m2m(pcmpgtd, vars, vard) + +#define pcmpgtw_m2r(var, reg) mmx_m2r(pcmpgtw, var, reg) +#define pcmpgtw_r2r(regs, regd) mmx_r2r(pcmpgtw, regs, regd) +#define pcmpgtw(vars, vard) mmx_m2m(pcmpgtw, vars, vard) + +#define pcmpgtb_m2r(var, reg) mmx_m2r(pcmpgtb, var, reg) +#define pcmpgtb_r2r(regs, regd) mmx_r2r(pcmpgtb, regs, regd) +#define pcmpgtb(vars, vard) mmx_m2m(pcmpgtb, vars, vard) + + +/* 1x64, 2x32, and 4x16 Parallel Shift Left Logical +*/ +#define psllq_i2r(imm, reg) mmx_i2r(psllq, imm, reg) +#define psllq_m2r(var, reg) mmx_m2r(psllq, var, reg) +#define psllq_r2r(regs, regd) mmx_r2r(psllq, regs, regd) +#define psllq(vars, vard) mmx_m2m(psllq, vars, vard) + +#define pslld_i2r(imm, reg) mmx_i2r(pslld, imm, reg) +#define pslld_m2r(var, reg) mmx_m2r(pslld, var, reg) +#define pslld_r2r(regs, regd) mmx_r2r(pslld, regs, regd) +#define pslld(vars, vard) mmx_m2m(pslld, vars, vard) + +#define psllw_i2r(imm, reg) mmx_i2r(psllw, imm, reg) +#define psllw_m2r(var, reg) mmx_m2r(psllw, var, reg) +#define psllw_r2r(regs, regd) mmx_r2r(psllw, regs, regd) +#define psllw(vars, vard) mmx_m2m(psllw, vars, vard) + + +/* 1x64, 2x32, and 4x16 Parallel Shift Right Logical +*/ +#define psrlq_i2r(imm, reg) mmx_i2r(psrlq, imm, reg) +#define psrlq_m2r(var, reg) mmx_m2r(psrlq, var, reg) +#define psrlq_r2r(regs, regd) mmx_r2r(psrlq, regs, regd) +#define psrlq(vars, vard) mmx_m2m(psrlq, vars, vard) + +#define psrld_i2r(imm, reg) mmx_i2r(psrld, imm, reg) +#define psrld_m2r(var, reg) mmx_m2r(psrld, var, reg) +#define psrld_r2r(regs, regd) mmx_r2r(psrld, regs, regd) +#define psrld(vars, vard) mmx_m2m(psrld, vars, vard) + +#define psrlw_i2r(imm, reg) mmx_i2r(psrlw, imm, reg) +#define psrlw_m2r(var, reg) mmx_m2r(psrlw, var, reg) +#define psrlw_r2r(regs, regd) mmx_r2r(psrlw, regs, regd) +#define psrlw(vars, vard) mmx_m2m(psrlw, vars, vard) + + +/* 2x32 and 4x16 Parallel Shift Right Arithmetic +*/ +#define psrad_i2r(imm, reg) mmx_i2r(psrad, imm, reg) +#define psrad_m2r(var, reg) mmx_m2r(psrad, var, reg) +#define psrad_r2r(regs, regd) mmx_r2r(psrad, regs, regd) +#define psrad(vars, vard) mmx_m2m(psrad, vars, vard) + +#define psraw_i2r(imm, reg) mmx_i2r(psraw, imm, reg) +#define psraw_m2r(var, reg) mmx_m2r(psraw, var, reg) +#define psraw_r2r(regs, regd) mmx_r2r(psraw, regs, regd) +#define psraw(vars, vard) mmx_m2m(psraw, vars, vard) + + +/* 2x32->4x16 and 4x16->8x8 PACK and Signed Saturate + (packs source and dest fields into dest in that order) +*/ +#define packssdw_m2r(var, reg) mmx_m2r(packssdw, var, reg) +#define packssdw_r2r(regs, regd) mmx_r2r(packssdw, regs, regd) +#define packssdw(vars, vard) mmx_m2m(packssdw, vars, vard) + +#define packsswb_m2r(var, reg) mmx_m2r(packsswb, var, reg) +#define packsswb_r2r(regs, regd) mmx_r2r(packsswb, regs, regd) +#define packsswb(vars, vard) mmx_m2m(packsswb, vars, vard) + + +/* 4x16->8x8 PACK and Unsigned Saturate + (packs source and dest fields into dest in that order) +*/ +#define packuswb_m2r(var, reg) mmx_m2r(packuswb, var, reg) +#define packuswb_r2r(regs, regd) mmx_r2r(packuswb, regs, regd) +#define packuswb(vars, vard) mmx_m2m(packuswb, vars, vard) + + +/* 2x32->1x64, 4x16->2x32, and 8x8->4x16 UNPaCK Low + (interleaves low half of dest with low half of source + as padding in each result field) +*/ +#define punpckldq_m2r(var, reg) mmx_m2r(punpckldq, var, reg) +#define punpckldq_r2r(regs, regd) mmx_r2r(punpckldq, regs, regd) +#define punpckldq(vars, vard) mmx_m2m(punpckldq, vars, vard) + +#define punpcklwd_m2r(var, reg) mmx_m2r(punpcklwd, var, reg) +#define punpcklwd_r2r(regs, regd) mmx_r2r(punpcklwd, regs, regd) +#define punpcklwd(vars, vard) mmx_m2m(punpcklwd, vars, vard) + +#define punpcklbw_m2r(var, reg) mmx_m2r(punpcklbw, var, reg) +#define punpcklbw_r2r(regs, regd) mmx_r2r(punpcklbw, regs, regd) +#define punpcklbw(vars, vard) mmx_m2m(punpcklbw, vars, vard) + + +/* 2x32->1x64, 4x16->2x32, and 8x8->4x16 UNPaCK High + (interleaves high half of dest with high half of source + as padding in each result field) +*/ +#define punpckhdq_m2r(var, reg) mmx_m2r(punpckhdq, var, reg) +#define punpckhdq_r2r(regs, regd) mmx_r2r(punpckhdq, regs, regd) +#define punpckhdq(vars, vard) mmx_m2m(punpckhdq, vars, vard) + +#define punpckhwd_m2r(var, reg) mmx_m2r(punpckhwd, var, reg) +#define punpckhwd_r2r(regs, regd) mmx_r2r(punpckhwd, regs, regd) +#define punpckhwd(vars, vard) mmx_m2m(punpckhwd, vars, vard) + +#define punpckhbw_m2r(var, reg) mmx_m2r(punpckhbw, var, reg) +#define punpckhbw_r2r(regs, regd) mmx_r2r(punpckhbw, regs, regd) +#define punpckhbw(vars, vard) mmx_m2m(punpckhbw, vars, vard) + + +/* Empty MMx State + (used to clean-up when going from mmx to float use + of the registers that are shared by both; note that + there is no float-to-mmx operation needed, because + only the float tag word info is corruptible) +*/ +#ifdef MMX_TRACE + +#define emms() \ + { \ + fprintf(stderr, "emms()\n"); \ + __asm__ __volatile__ ("emms"); \ + } + +#else + +#define emms() __asm__ __volatile__ ("emms") + +#endif + +#endif + diff --git a/reactos/lib/mesa32/src/drivers/dri/common/spantmp.h b/reactos/lib/mesa32/src/drivers/dri/common/spantmp.h new file mode 100644 index 00000000000..888be0465e5 --- /dev/null +++ b/reactos/lib/mesa32/src/drivers/dri/common/spantmp.h @@ -0,0 +1,259 @@ +#ifndef DBG +#define DBG 0 +#endif + +#ifndef HW_WRITE_LOCK +#define HW_WRITE_LOCK() HW_LOCK() +#endif + +#ifndef HW_WRITE_UNLOCK +#define HW_WRITE_UNLOCK() HW_UNLOCK() +#endif + +#ifndef HW_READ_LOCK +#define HW_READ_LOCK() HW_LOCK() +#endif + +#ifndef HW_READ_UNLOCK +#define HW_READ_UNLOCK() HW_UNLOCK() +#endif + +#ifndef HW_READ_CLIPLOOP +#define HW_READ_CLIPLOOP() HW_CLIPLOOP() +#endif + +#ifndef HW_WRITE_CLIPLOOP +#define HW_WRITE_CLIPLOOP() HW_CLIPLOOP() +#endif + + +static void TAG(WriteRGBASpan)( const GLcontext *ctx, + GLuint n, GLint x, GLint y, + const GLubyte rgba[][4], + const GLubyte mask[] ) +{ + HW_WRITE_LOCK() + { + GLint x1; + GLint n1; + LOCAL_VARS; + + y = Y_FLIP(y); + + HW_WRITE_CLIPLOOP() + { + GLint i = 0; + CLIPSPAN(x,y,n,x1,n1,i); + + if (DBG) fprintf(stderr, "WriteRGBASpan %d..%d (x1 %d)\n", + (int)i, (int)n1, (int)x1); + + if (mask) + { + for (;n1>0;i++,x1++,n1--) + if (mask[i]) + WRITE_RGBA( x1, y, + rgba[i][0], rgba[i][1], + rgba[i][2], rgba[i][3] ); + } + else + { + for (;n1>0;i++,x1++,n1--) + WRITE_RGBA( x1, y, + rgba[i][0], rgba[i][1], + rgba[i][2], rgba[i][3] ); + } + } + HW_ENDCLIPLOOP(); + } + HW_WRITE_UNLOCK(); +} + +static void TAG(WriteRGBSpan)( const GLcontext *ctx, + GLuint n, GLint x, GLint y, + const GLubyte rgb[][3], + const GLubyte mask[] ) +{ + HW_WRITE_LOCK() + { + GLint x1; + GLint n1; + LOCAL_VARS; + + y = Y_FLIP(y); + + HW_WRITE_CLIPLOOP() + { + GLint i = 0; + CLIPSPAN(x,y,n,x1,n1,i); + + if (DBG) fprintf(stderr, "WriteRGBSpan %d..%d (x1 %d)\n", + (int)i, (int)n1, (int)x1); + + if (mask) + { + for (;n1>0;i++,x1++,n1--) + if (mask[i]) + WRITE_RGBA( x1, y, rgb[i][0], rgb[i][1], rgb[i][2], 255 ); + } + else + { + for (;n1>0;i++,x1++,n1--) + WRITE_RGBA( x1, y, rgb[i][0], rgb[i][1], rgb[i][2], 255 ); + } + } + HW_ENDCLIPLOOP(); + } + HW_WRITE_UNLOCK(); +} + +static void TAG(WriteRGBAPixels)( const GLcontext *ctx, + GLuint n, + const GLint x[], + const GLint y[], + const GLubyte rgba[][4], + const GLubyte mask[] ) +{ + HW_WRITE_LOCK() + { + GLint i; + LOCAL_VARS; + + if (DBG) fprintf(stderr, "WriteRGBAPixels\n"); + + HW_WRITE_CLIPLOOP() + { + for (i=0;i0;i++,x1++,n1--) + if (mask[i]) + WRITE_PIXEL( x1, y, p ); + } + HW_ENDCLIPLOOP(); + } + HW_WRITE_UNLOCK(); +} + + +static void TAG(WriteMonoRGBAPixels)( const GLcontext *ctx, + GLuint n, + const GLint x[], const GLint y[], + const GLchan color[], + const GLubyte mask[] ) +{ + HW_WRITE_LOCK() + { + GLint i; + LOCAL_VARS; + INIT_MONO_PIXEL(p, color); + + if (DBG) fprintf(stderr, "WriteMonoRGBAPixels\n"); + + HW_WRITE_CLIPLOOP() + { + for (i=0;i0;i++,x1++,n1--) + READ_RGBA( rgba[i], x1, y ); + } + HW_ENDCLIPLOOP(); + } + HW_READ_UNLOCK(); +} + + +static void TAG(ReadRGBAPixels)( const GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + GLubyte rgba[][4], const GLubyte mask[] ) +{ + HW_READ_LOCK() + { + GLint i; + LOCAL_VARS; + + if (DBG) fprintf(stderr, "ReadRGBAPixels\n"); + + HW_READ_CLIPLOOP() + { + for (i=0;i + * Keith Whitwell + * Kevin E. Martin + * Gareth Hughes + */ +/* $XFree86:$ */ + +/** \file texmem.c + * Implements all of the device-independent texture memory management. + * + * Currently, only a simple LRU texture memory management policy is + * implemented. In the (hopefully very near) future, better policies will be + * implemented. The idea is that the DRI should be able to run in one of two + * modes. In the default mode the DRI will dynamically attempt to discover + * the best texture management policy for the running application. In the + * other mode, the user (via some sort of as yet TBD mechanism) will select + * a texture management policy that is known to work well with the + * application. + */ + +#include "texmem.h" +#include "simple_list.h" +#include "imports.h" +#include "macros.h" + +#include + + + +static unsigned dummy_swap_counter; + + +/** + * Calculate \f$\log_2\f$ of a value. This is a particularly poor + * implementation of this function. However, since system performance is in + * no way dependent on this function, the slowness of the implementation is + * irrelevent. + * + * \param n Value whose \f$\log_2\f$ is to be calculated + */ + +static unsigned +driLog2( unsigned n ) +{ + unsigned log2; + + + for ( log2 = 1 ; n > 1 ; log2++ ) { + n >>= 1; + } + + return log2; +} + + + + +/** + * Determine if a texture is resident in textureable memory. Depending on + * the driver, this may or may not be on-card memory. It could be AGP memory + * or anyother type of memory from which the hardware can directly read + * texels. + * + * This function is intended to be used as the \c IsTextureResident function + * in the device's \c dd_function_table. + * + * \param ctx GL context pointer (currently unused) + * \param texObj Texture object to be tested + */ + +GLboolean +driIsTextureResident( GLcontext * ctx, + struct gl_texture_object * texObj ) +{ + driTextureObject * t; + + + t = (driTextureObject *) texObj->DriverData; + return( (t != NULL) && (t->memBlock != NULL) ); +} + + + + +/** + * (Re)initialize the global circular LRU list. The last element + * in the array (\a heap->nrRegions) is the sentinal. Keeping it + * at the end of the array allows the other elements of the array + * to be addressed rationally when looking up objects at a particular + * location in texture memory. + * + * \param heap Texture heap to be reset + */ + +static void resetGlobalLRU( driTexHeap * heap ) +{ + drmTextureRegionPtr list = heap->global_regions; + unsigned sz = 1U << heap->logGranularity; + unsigned i; + + for (i = 0 ; (i+1) * sz <= heap->size ; i++) { + list[i].prev = i-1; + list[i].next = i+1; + list[i].age = 0; + } + + i--; + list[0].prev = heap->nrRegions; + list[i].prev = i-1; + list[i].next = heap->nrRegions; + list[heap->nrRegions].prev = i; + list[heap->nrRegions].next = 0; + heap->global_age[0] = 0; +} + +/** + * Print out debugging information about the local texture LRU. + * + * \param heap Texture heap to be printed + * \param callername Name of calling function + */ +static void printLocalLRU( driTexHeap * heap, const char *callername ) +{ + driTextureObject *t; + unsigned sz = 1U << heap->logGranularity; + + fprintf( stderr, "%s in %s:\nLocal LRU, heap %d:\n", + __FUNCTION__, callername, heap->heapId ); + + foreach ( t, &heap->texture_objects ) { + if (!t->memBlock) + continue; + if (!t->tObj) { + fprintf( stderr, "Placeholder (%p) %d at 0x%x sz 0x%x\n", + (void *)t, + t->memBlock->ofs / sz, + t->memBlock->ofs, + t->memBlock->size ); + } else { + fprintf( stderr, "Texture (%p) at 0x%x sz 0x%x\n", + (void *)t, + t->memBlock->ofs, + t->memBlock->size ); + } + } + foreach ( t, heap->swapped_objects ) { + if (!t->tObj) { + fprintf( stderr, "Swapped Placeholder (%p)\n", (void *)t ); + } else { + fprintf( stderr, "Swapped Texture (%p)\n", (void *)t ); + } + } + + fprintf( stderr, "\n" ); +} + +/** + * Print out debugging information about the global texture LRU. + * + * \param heap Texture heap to be printed + * \param callername Name of calling function + */ +static void printGlobalLRU( driTexHeap * heap, const char *callername ) +{ + drmTextureRegionPtr list = heap->global_regions; + int i, j; + + fprintf( stderr, "%s in %s:\nGlobal LRU, heap %d list %p:\n", + __FUNCTION__, callername, heap->heapId, (void *)list ); + + for ( i = 0, j = heap->nrRegions ; i < heap->nrRegions ; i++ ) { + fprintf( stderr, "list[%d] age %d next %d prev %d in_use %d\n", + j, list[j].age, list[j].next, list[j].prev, list[j].in_use ); + j = list[j].next; + if ( j == heap->nrRegions ) break; + } + + if ( j != heap->nrRegions ) { + fprintf( stderr, "Loop detected in global LRU\n" ); + for ( i = 0 ; i < heap->nrRegions ; i++ ) { + fprintf( stderr, "list[%d] age %d next %d prev %d in_use %d\n", + i, list[i].age, list[i].next, list[i].prev, list[i].in_use ); + } + } + + fprintf( stderr, "\n" ); +} + + +/** + * Called by the client whenever it touches a local texture. + * + * \param t Texture object that the client has accessed + */ + +void driUpdateTextureLRU( driTextureObject * t ) +{ + driTexHeap * heap; + drmTextureRegionPtr list; + unsigned shift; + unsigned start; + unsigned end; + unsigned i; + + + heap = t->heap; + if ( heap != NULL ) { + shift = heap->logGranularity; + start = t->memBlock->ofs >> shift; + end = (t->memBlock->ofs + t->memBlock->size - 1) >> shift; + + + heap->local_age = ++heap->global_age[0]; + list = heap->global_regions; + + + /* Update the context's local LRU + */ + + move_to_head( & heap->texture_objects, t ); + + + for (i = start ; i <= end ; i++) { + list[i].age = heap->local_age; + + /* remove_from_list(i) + */ + list[(unsigned)list[i].next].prev = list[i].prev; + list[(unsigned)list[i].prev].next = list[i].next; + + /* insert_at_head(list, i) + */ + list[i].prev = heap->nrRegions; + list[i].next = list[heap->nrRegions].next; + list[(unsigned)list[heap->nrRegions].next].prev = i; + list[heap->nrRegions].next = i; + } + + if ( 0 ) { + printGlobalLRU( heap, __FUNCTION__ ); + printLocalLRU( heap, __FUNCTION__ ); + } + } +} + + + + +/** + * Keep track of swapped out texture objects. + * + * \param t Texture object to be "swapped" out of its texture heap + */ + +void driSwapOutTextureObject( driTextureObject * t ) +{ + unsigned face; + + + if ( t->memBlock != NULL ) { + assert( t->heap != NULL ); + mmFreeMem( t->memBlock ); + t->memBlock = NULL; + + if (t->timestamp > t->heap->timestamp) + t->heap->timestamp = t->timestamp; + + t->heap->texture_swaps[0]++; + move_to_tail( t->heap->swapped_objects, t ); + t->heap = NULL; + } + else { + assert( t->heap == NULL ); + } + + + for ( face = 0 ; face < 6 ; face++ ) { + t->dirty_images[face] = ~0; + } +} + + + + +/** + * Destroy hardware state associated with texture \a t. Calls the + * \a destroy_texture_object method associated with the heap from which + * \a t was allocated. + * + * \param t Texture object to be destroyed + */ + +void driDestroyTextureObject( driTextureObject * t ) +{ + driTexHeap * heap; + + + if ( 0 ) { + fprintf( stderr, "[%s:%d] freeing %p (tObj = %p, DriverData = %p)\n", + __FILE__, __LINE__, + (void *)t, + (void *)((t != NULL) ? t->tObj : NULL), + (void *)((t != NULL && t->tObj != NULL) ? t->tObj->DriverData : NULL )); + } + + if ( t != NULL ) { + if ( t->memBlock ) { + heap = t->heap; + assert( heap != NULL ); + + heap->texture_swaps[0]++; + + mmFreeMem( t->memBlock ); + t->memBlock = NULL; + + if (t->timestamp > t->heap->timestamp) + t->heap->timestamp = t->timestamp; + + heap->destroy_texture_object( heap->driverContext, t ); + t->heap = NULL; + } + + if ( t->tObj != NULL ) { + assert( t->tObj->DriverData == t ); + t->tObj->DriverData = NULL; + } + + remove_from_list( t ); + FREE( t ); + } + + if ( 0 ) { + fprintf( stderr, "[%s:%d] done freeing %p\n", __FILE__, __LINE__, (void *)t ); + } +} + + + + +/** + * Update the local heap's representation of texture memory based on + * data in the SAREA. This is done each time it is detected that some other + * direct rendering client has held the lock. This pertains to both our local + * textures and the textures belonging to other clients. Keep track of other + * client's textures by pushing a placeholder texture onto the LRU list -- + * these are denoted by \a tObj being \a NULL. + * + * \param heap Heap whose state is to be updated + * \param offset Byte offset in the heap that has been stolen + * \param size Size, in bytes, of the stolen block + * \param in_use Non-zero if the block is pinned/reserved by the kernel + */ + +static void driTexturesGone( driTexHeap * heap, int offset, int size, + int in_use ) +{ + driTextureObject * t; + driTextureObject * tmp; + + + foreach_s ( t, tmp, & heap->texture_objects ) { + if ( (t->memBlock->ofs < (offset + size)) + && ((t->memBlock->ofs + t->memBlock->size) > offset) ) { + /* It overlaps - kick it out. If the texture object is just a + * place holder, then destroy it all together. Otherwise, mark + * it as being swapped out. + */ + + if ( t->tObj != NULL ) { + driSwapOutTextureObject( t ); + } + else { + driDestroyTextureObject( t ); + } + } + } + + + { + t = (driTextureObject *) CALLOC( heap->texture_object_size ); + if ( t == NULL ) return; + + t->memBlock = mmAllocMem( heap->memory_heap, size, 0, offset ); + if ( t->memBlock == NULL ) { + fprintf( stderr, "Couldn't alloc placeholder: heap %u sz %x ofs %x\n", heap->heapId, + (int)size, (int)offset ); + mmDumpMemInfo( heap->memory_heap ); + return; + } + t->heap = heap; + if (in_use) + t->bound = 99; + insert_at_head( & heap->texture_objects, t ); + } +} + + + + +/** + * Called by the client on lock contention to determine whether textures have + * been stolen. If another client has modified a region in which we have + * textures, then we need to figure out which of our textures have been + * removed and update our global LRU. + * + * \param heap Texture heap to be updated + */ + +void driAgeTextures( driTexHeap * heap ) +{ + drmTextureRegionPtr list = heap->global_regions; + unsigned sz = 1U << (heap->logGranularity); + unsigned i, nr = 0; + + + /* Have to go right round from the back to ensure stuff ends up + * LRU in the local list... Fix with a cursor pointer. + */ + + for (i = list[heap->nrRegions].prev ; + i != heap->nrRegions && nr < heap->nrRegions ; + i = list[i].prev, nr++) { + /* If switching texturing schemes, then the SAREA might not have been + * properly cleared, so we need to reset the global texture LRU. + */ + + if ( (i * sz) > heap->size ) { + nr = heap->nrRegions; + break; + } + + if (list[i].age > heap->local_age) + driTexturesGone( heap, i * sz, sz, list[i].in_use); + } + + /* Loop or uninitialized heap detected. Reset. + */ + + if (nr == heap->nrRegions) { + driTexturesGone( heap, 0, heap->size, 0); + resetGlobalLRU( heap ); + } + + if ( 0 ) { + printGlobalLRU( heap, __FUNCTION__ ); + printLocalLRU( heap, __FUNCTION__ ); + } + + heap->local_age = heap->global_age[0]; +} + + + + +/** + * Allocate memory from a texture heap to hold a texture object. This + * routine will attempt to allocate memory for the texture from the heaps + * specified by \c heap_array in order. That is, first it will try to + * allocate from \c heap_array[0], then \c heap_array[1], and so on. + * + * \param heap_array Array of pointers to texture heaps to use + * \param nr_heaps Number of heap pointer in \a heap_array + * \param t Texture object for which space is needed + * \return The ID of the heap from which memory was allocated, or -1 if + * memory could not be allocated. + * + * \bug The replacement policy implemented by this function is horrible. + */ + + +int +driAllocateTexture( driTexHeap * const * heap_array, unsigned nr_heaps, + driTextureObject * t ) +{ + driTexHeap * heap; + driTextureObject * temp; + driTextureObject * cursor; + unsigned id; + + + /* In case it already has texture space, initialize heap. This also + * prevents GCC from issuing a warning that heap might be used + * uninitialized. + */ + + heap = t->heap; + + + /* Run through each of the existing heaps and try to allocate a buffer + * to hold the texture. + */ + + for ( id = 0 ; (t->memBlock == NULL) && (id < nr_heaps) ; id++ ) { + heap = heap_array[ id ]; + if ( heap != NULL ) { + t->memBlock = mmAllocMem( heap->memory_heap, t->totalSize, + heap->alignmentShift, 0 ); + } + } + + + /* Kick textures out until the requested texture fits. + */ + + if ( t->memBlock == NULL ) { + for ( id = 0 ; (t->memBlock == NULL) && (id < nr_heaps) ; id++ ) { + heap = heap_array[ id ]; + if ( t->totalSize <= heap->size ) { + + for ( cursor = heap->texture_objects.prev, temp = cursor->prev; + cursor != &heap->texture_objects ; + cursor = temp, temp = cursor->prev ) { + + /* The the LRU element. If the texture is bound to one of + * the texture units, then we cannot kick it out. + */ + if ( cursor->bound /* || cursor->reserved */ ) { + continue; + } + + /* If this is a placeholder, there's no need to keep it */ + if (cursor->tObj) + driSwapOutTextureObject( cursor ); + else + driDestroyTextureObject( cursor ); + + t->memBlock = mmAllocMem( heap->memory_heap, t->totalSize, + heap->alignmentShift, 0 ); + + if (t->memBlock) + break; + } + } /* if ( t->totalSize <= heap->size ) ... */ + } + } + + + if ( t->memBlock != NULL ) { + /* id and heap->heapId may or may not be the same value here. + */ + + assert( heap != NULL ); + assert( (t->heap == NULL) || (t->heap == heap) ); + + t->heap = heap; + return heap->heapId; + } + else { + assert( t->heap == NULL ); + + fprintf( stderr, "[%s:%d] unable to allocate texture\n", + __FUNCTION__, __LINE__ ); + return -1; + } +} + + + + + + +/** + * Set the location where the texture-swap counter is stored. + */ + +void +driSetTextureSwapCounterLocation( driTexHeap * heap, unsigned * counter ) +{ + heap->texture_swaps = (counter == NULL) ? & dummy_swap_counter : counter; +} + + + + +/** + * Create a new heap for texture data. + * + * \param heap_id Device-dependent heap identifier. This value + * will returned by driAllocateTexture when memory + * is allocated from this heap. + * \param context Device-dependent driver context. This is + * supplied as the first parameter to the + * \c destroy_tex_obj function. + * \param size Size, in bytes, of the texture region + * \param alignmentShift Alignment requirement for textures. If textures + * must be allocated on a 4096 byte boundry, this + * would be 12. + * \param nr_regions Number of regions into which this texture space + * should be partitioned + * \param global_regions Array of \c drmTextureRegion structures in the SAREA + * \param global_age Pointer to the global texture age in the SAREA + * \param swapped_objects Pointer to the list of texture objects that are + * not in texture memory (i.e., have been swapped + * out). + * \param texture_object_size Size, in bytes, of a device-dependent texture + * object + * \param destroy_tex_obj Function used to destroy a device-dependent + * texture object + * + * \sa driDestroyTextureHeap + */ + +driTexHeap * +driCreateTextureHeap( unsigned heap_id, void * context, unsigned size, + unsigned alignmentShift, unsigned nr_regions, + drmTextureRegionPtr global_regions, unsigned * global_age, + driTextureObject * swapped_objects, + unsigned texture_object_size, + destroy_texture_object_t * destroy_tex_obj + ) +{ + driTexHeap * heap; + unsigned l; + + + if ( 0 ) + fprintf( stderr, "%s( %u, %p, %u, %u, %u )\n", + __FUNCTION__, + heap_id, (void *)context, size, alignmentShift, nr_regions ); + + heap = (driTexHeap *) CALLOC( sizeof( driTexHeap ) ); + if ( heap != NULL ) { + l = driLog2( (size - 1) / nr_regions ); + if ( l < alignmentShift ) + { + l = alignmentShift; + } + + heap->logGranularity = l; + heap->size = size & ~((1L << l) - 1); + + heap->memory_heap = mmInit( 0, heap->size ); + if ( heap->memory_heap != NULL ) { + heap->heapId = heap_id; + heap->driverContext = context; + + heap->alignmentShift = alignmentShift; + heap->nrRegions = nr_regions; + heap->global_regions = global_regions; + heap->global_age = global_age; + heap->swapped_objects = swapped_objects; + heap->texture_object_size = texture_object_size; + heap->destroy_texture_object = destroy_tex_obj; + + /* Force global heap init */ + if (heap->global_age[0] == 0) + heap->local_age = ~0; + else + heap->local_age = 0; + + make_empty_list( & heap->texture_objects ); + driSetTextureSwapCounterLocation( heap, NULL ); + } + else { + FREE( heap ); + heap = NULL; + } + } + + + if ( 0 ) + fprintf( stderr, "%s returning %p\n", __FUNCTION__, (void *)heap ); + + return heap; +} + + + + +/** Destroys a texture heap + * + * \param heap Texture heap to be destroyed + */ + +void +driDestroyTextureHeap( driTexHeap * heap ) +{ + driTextureObject * t; + driTextureObject * temp; + + + if ( heap != NULL ) { + foreach_s( t, temp, & heap->texture_objects ) { + driDestroyTextureObject( t ); + } + foreach_s( t, temp, heap->swapped_objects ) { + driDestroyTextureObject( t ); + } + + mmDestroy( heap->memory_heap ); + FREE( heap ); + } +} + + + + +/****************************************************************************/ +/** + * Determine how many texels (including all mipmap levels) would be required + * for a texture map of size \f$2^^\c base_size_log2\f$ would require. + * + * \param base_size_log2 \f$log_2\f$ of the size of a side of the texture + * \param dimensions Number of dimensions of the texture. Either 2 or 3. + * \param faces Number of faces of the texture. Either 1 or 6 (for cube maps). + * \return Number of texels + */ + +static unsigned +texels_this_map_size( int base_size_log2, unsigned dimensions, unsigned faces ) +{ + unsigned texels; + + + assert( (faces == 1) || (faces == 6) ); + assert( (dimensions == 2) || (dimensions == 3) ); + + texels = 0; + if ( base_size_log2 >= 0 ) { + texels = (1U << (dimensions * base_size_log2)); + + /* See http://www.mail-archive.com/dri-devel@lists.sourceforge.net/msg03636.html + * for the complete explaination of why this formulation is used. + * Basically, the smaller mipmap levels sum to 0.333 the size of the + * level 0 map. The total size is therefore the size of the map + * multipled by 1.333. The +2 is there to round up. + */ + + texels = (texels * 4 * faces + 2) / 3; + } + + return texels; +} + + + + +struct maps_per_heap { + unsigned c[32]; +}; + +static void +fill_in_maximums( driTexHeap * const * heaps, unsigned nr_heaps, + unsigned max_bytes_per_texel, unsigned max_size, + unsigned mipmaps_at_once, unsigned dimensions, + unsigned faces, struct maps_per_heap * max_textures ) +{ + unsigned heap; + unsigned log2_size; + unsigned mask; + + + /* Determine how many textures of each size can be stored in each + * texture heap. + */ + + for ( heap = 0 ; heap < nr_heaps ; heap++ ) { + if ( heaps[ heap ] == NULL ) { + (void) memset( max_textures[ heap ].c, 0, + sizeof( max_textures[ heap ].c ) ); + continue; + } + + mask = (1U << heaps[ heap ]->logGranularity) - 1; + + if ( 0 ) { + fprintf( stderr, "[%s:%d] heap[%u] = %u bytes, mask = 0x%08x\n", + __FILE__, __LINE__, + heap, heaps[ heap ]->size, mask ); + } + + for ( log2_size = max_size ; log2_size > 0 ; log2_size-- ) { + unsigned total; + + + /* Determine the total number of bytes required by a texture of + * size log2_size. + */ + + total = texels_this_map_size( log2_size, dimensions, faces ) + - texels_this_map_size( log2_size - mipmaps_at_once, + dimensions, faces ); + total *= max_bytes_per_texel; + total = (total + mask) & ~mask; + + /* The number of textures of a given size that will fit in a heap + * is equal to the size of the heap divided by the size of the + * texture. + */ + + max_textures[ heap ].c[ log2_size ] = heaps[ heap ]->size / total; + + if ( 0 ) { + fprintf( stderr, "[%s:%d] max_textures[%u].c[%02u] " + "= 0x%08x / 0x%08x " + "= %u (%u)\n", + __FILE__, __LINE__, + heap, log2_size, + heaps[ heap ]->size, total, + heaps[ heap ]->size / total, + max_textures[ heap ].c[ log2_size ] ); + } + } + } +} + + +static unsigned +get_max_size( unsigned nr_heaps, + unsigned texture_units, + unsigned max_size, + int all_textures_one_heap, + struct maps_per_heap * max_textures ) +{ + unsigned heap; + unsigned log2_size; + + + /* Determine the largest texture size such that a texture of that size + * can be bound to each texture unit at the same time. Some hardware + * may require that all textures be in the same texture heap for + * multitexturing. + */ + + for ( log2_size = max_size ; log2_size > 0 ; log2_size-- ) { + unsigned total = 0; + + for ( heap = 0 ; heap < nr_heaps ; heap++ ) + { + total += max_textures[ heap ].c[ log2_size ]; + + if ( 0 ) { + fprintf( stderr, "[%s:%d] max_textures[%u].c[%02u] = %u, " + "total = %u\n", __FILE__, __LINE__, heap, log2_size, + max_textures[ heap ].c[ log2_size ], total ); + } + + if ( (max_textures[ heap ].c[ log2_size ] >= texture_units) + || (!all_textures_one_heap && (total >= texture_units)) ) { + /* The number of mipmap levels is the log-base-2 of the + * maximum texture size plus 1. If the maximum texture size + * is 1x1, the log-base-2 is 0 and 1 mipmap level (the base + * level) is available. + */ + + return log2_size + 1; + } + } + } + + /* This should NEVER happen. It should always be possible to have at + * *least* a 1x1 texture in memory! + */ + assert( log2_size != 0 ); + return 0; +} + +#define SET_MAX(f,v) \ + do { if ( max_sizes[v] != 0 ) { limits-> f = max_sizes[v]; } } while( 0 ) + +#define SET_MAX_RECT(f,v) \ + do { if ( max_sizes[v] != 0 ) { limits-> f = 1 << max_sizes[v]; } } while( 0 ) + + +/** + * Given the amount of texture memory, the number of texture units, and the + * maximum size of a texel, calculate the maximum texture size the driver can + * advertise. + * + * \param heaps Texture heaps for this card + * \param nr_heap Number of texture heaps + * \param limits OpenGL contants. MaxTextureUnits must be set. + * \param max_bytes_per_texel Maximum size of a single texel, in bytes + * \param max_2D_size \f$\log_2\f$ of the maximum 2D texture size (i.e., + * 1024x1024 textures, this would be 10) + * \param max_3D_size \f$\log_2\f$ of the maximum 3D texture size (i.e., + * 1024x1024x1024 textures, this would be 10) + * \param max_cube_size \f$\log_2\f$ of the maximum cube texture size (i.e., + * 1024x1024 textures, this would be 10) + * \param max_rect_size \f$\log_2\f$ of the maximum texture rectangle size + * (i.e., 1024x1024 textures, this would be 10). This is a power-of-2 + * even though texture rectangles need not be a power-of-2. + * \param mipmaps_at_once Total number of mipmaps that can be used + * at one time. For most hardware this will be \f$\c max_size + 1\f$. + * For hardware that does not support mipmapping, this will be 1. + * \param all_textures_one_heap True if the hardware requires that all + * textures be in a single texture heap for multitexturing. + */ + +void +driCalculateMaxTextureLevels( driTexHeap * const * heaps, + unsigned nr_heaps, + struct gl_constants * limits, + unsigned max_bytes_per_texel, + unsigned max_2D_size, + unsigned max_3D_size, + unsigned max_cube_size, + unsigned max_rect_size, + unsigned mipmaps_at_once, + int all_textures_one_heap ) +{ + struct maps_per_heap max_textures[8]; + unsigned i; + const unsigned dimensions[4] = { 2, 3, 2, 2 }; + const unsigned faces[4] = { 1, 1, 6, 1 }; + unsigned max_sizes[4]; + unsigned mipmaps[4]; + + + max_sizes[0] = max_2D_size; + max_sizes[1] = max_3D_size; + max_sizes[2] = max_cube_size; + max_sizes[3] = max_rect_size; + + mipmaps[0] = mipmaps_at_once; + mipmaps[1] = mipmaps_at_once; + mipmaps[2] = 1; + mipmaps[3] = mipmaps_at_once; + + + /* Calculate the maximum number of texture levels in two passes. The + * first pass determines how many textures of each power-of-two size + * (including all mipmap levels for that size) can fit in each texture + * heap. The second pass finds the largest texture size that allows + * a texture of that size to be bound to every texture unit. + */ + + for ( i = 0 ; i < 4 ; i++ ) { + if ( max_sizes[ i ] != 0 ) { + fill_in_maximums( heaps, nr_heaps, max_bytes_per_texel, + max_sizes[ i ], mipmaps[ i ], + dimensions[ i ], faces[ i ], + max_textures ); + + max_sizes[ i ] = get_max_size( nr_heaps, + limits->MaxTextureUnits, + max_sizes[ i ], + all_textures_one_heap, + max_textures ); + } + } + + SET_MAX( MaxTextureLevels, 0 ); + SET_MAX( Max3DTextureLevels, 1 ); + SET_MAX( MaxCubeTextureLevels, 2 ); + SET_MAX_RECT( MaxTextureRectSize, 3 ); +} + + + + +/** + * Perform initial binding of default textures objects on a per unit, per + * texture target basis. + * + * \param ctx Current OpenGL context + * \param swapped List of swapped-out textures + * \param targets Bit-mask of value texture targets + */ + +void driInitTextureObjects( GLcontext *ctx, driTextureObject * swapped, + GLuint targets ) +{ + struct gl_texture_object *texObj; + GLuint tmp = ctx->Texture.CurrentUnit; + unsigned i; + + + for ( i = 0 ; i < ctx->Const.MaxTextureUnits ; i++ ) { + ctx->Texture.CurrentUnit = i; + + if ( (targets & DRI_TEXMGR_DO_TEXTURE_1D) != 0 ) { + texObj = ctx->Texture.Unit[i].Current1D; + ctx->Driver.BindTexture( ctx, GL_TEXTURE_1D, texObj ); + move_to_tail( swapped, (driTextureObject *) texObj->DriverData ); + } + + if ( (targets & DRI_TEXMGR_DO_TEXTURE_2D) != 0 ) { + texObj = ctx->Texture.Unit[i].Current2D; + ctx->Driver.BindTexture( ctx, GL_TEXTURE_2D, texObj ); + move_to_tail( swapped, (driTextureObject *) texObj->DriverData ); + } + + if ( (targets & DRI_TEXMGR_DO_TEXTURE_3D) != 0 ) { + texObj = ctx->Texture.Unit[i].Current3D; + ctx->Driver.BindTexture( ctx, GL_TEXTURE_3D, texObj ); + move_to_tail( swapped, (driTextureObject *) texObj->DriverData ); + } + + if ( (targets & DRI_TEXMGR_DO_TEXTURE_CUBE) != 0 ) { + texObj = ctx->Texture.Unit[i].CurrentCubeMap; + ctx->Driver.BindTexture( ctx, GL_TEXTURE_CUBE_MAP_ARB, texObj ); + move_to_tail( swapped, (driTextureObject *) texObj->DriverData ); + } + + if ( (targets & DRI_TEXMGR_DO_TEXTURE_RECT) != 0 ) { + texObj = ctx->Texture.Unit[i].CurrentRect; + ctx->Driver.BindTexture( ctx, GL_TEXTURE_RECTANGLE_NV, texObj ); + move_to_tail( swapped, (driTextureObject *) texObj->DriverData ); + } + } + + ctx->Texture.CurrentUnit = tmp; +} + + + + +/** + * Verify that the specified texture is in the specificed heap. + * + * \param tex Texture to be tested. + * \param heap Texture memory heap to be tested. + * \return True if the texture is in the heap, false otherwise. + */ + +static GLboolean +check_in_heap( const driTextureObject * tex, const driTexHeap * heap ) +{ +#if 1 + return tex->heap == heap; +#else + driTextureObject * curr; + + foreach( curr, & heap->texture_objects ) { + if ( curr == tex ) { + break; + } + } + + return curr == tex; +#endif +} + + + +/****************************************************************************/ +/** + * Validate the consistency of a set of texture heaps. + * Original version by Keith Whitwell in r200/r200_sanity.c. + */ + +GLboolean +driValidateTextureHeaps( driTexHeap * const * texture_heaps, + unsigned nr_heaps, const driTextureObject * swapped ) +{ + driTextureObject *t; + unsigned i; + + for ( i = 0 ; i < nr_heaps ; i++ ) { + int last_end = 0; + unsigned textures_in_heap = 0; + unsigned blocks_in_mempool = 0; + const driTexHeap * heap = texture_heaps[i]; + const memHeap_t * p = heap->memory_heap; + + /* Check each texture object has a MemBlock, and is linked into + * the correct heap. + * + * Check the texobj base address corresponds to the MemBlock + * range. Check the texobj size (recalculate???) fits within + * the MemBlock. + * + * Count the number of texobj's using this heap. + */ + + foreach ( t, &heap->texture_objects ) { + if ( !check_in_heap( t, heap ) ) { + fprintf( stderr, "%s memory block for texture object @ %p not " + "found in heap #%d\n", + __FUNCTION__, (void *)t, i ); + return GL_FALSE; + } + + + if ( t->totalSize > t->memBlock->size ) { + fprintf( stderr, "%s: Memory block for texture object @ %p is " + "only %u bytes, but %u are required\n", + __FUNCTION__, (void *)t, t->totalSize, t->memBlock->size ); + return GL_FALSE; + } + + textures_in_heap++; + } + + /* Validate the contents of the heap: + * - Ordering + * - Overlaps + * - Bounds + */ + + while ( p != NULL ) { + if (p->reserved) { + fprintf( stderr, "%s: Block (%08x,%x), is reserved?!\n", + __FUNCTION__, p->ofs, p->size ); + return GL_FALSE; + } + + if (p->ofs != last_end) { + fprintf( stderr, "%s: blocks_in_mempool = %d, last_end = %d, p->ofs = %d\n", + __FUNCTION__, blocks_in_mempool, last_end, p->ofs ); + return GL_FALSE; + } + + if (!p->reserved && !p->free) { + blocks_in_mempool++; + } + + last_end = p->ofs + p->size; + p = p->next; + } + + if (textures_in_heap != blocks_in_mempool) { + fprintf( stderr, "%s: Different number of textures objects (%u) and " + "inuse memory blocks (%u)\n", + __FUNCTION__, textures_in_heap, blocks_in_mempool ); + return GL_FALSE; + } + +#if 0 + fprintf( stderr, "%s: textures_in_heap = %u\n", + __FUNCTION__, textures_in_heap ); +#endif + } + + + /* Check swapped texobj's have zero memblocks + */ + i = 0; + foreach ( t, swapped ) { + if ( t->memBlock != NULL ) { + fprintf( stderr, "%s: Swapped texobj %p has non-NULL memblock %p\n", + __FUNCTION__, (void *)t, (void *)t->memBlock ); + return GL_FALSE; + } + i++; + } + +#if 0 + fprintf( stderr, "%s: swapped texture count = %u\n", __FUNCTION__, i ); +#endif + + return GL_TRUE; +} + + + + +/****************************************************************************/ +/** + * Compute which mipmap levels that really need to be sent to the hardware. + * This depends on the base image size, GL_TEXTURE_MIN_LOD, + * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL. + */ + +void +driCalculateTextureFirstLastLevel( driTextureObject * t ) +{ + struct gl_texture_object * const tObj = t->tObj; + const struct gl_texture_image * const baseImage = + tObj->Image[tObj->BaseLevel]; + + /* These must be signed values. MinLod and MaxLod can be negative numbers, + * and having firstLevel and lastLevel as signed prevents the need for + * extra sign checks. + */ + int firstLevel; + int lastLevel; + + /* Yes, this looks overly complicated, but it's all needed. + */ + + switch (tObj->Target) { + case GL_TEXTURE_1D: + case GL_TEXTURE_2D: + case GL_TEXTURE_3D: + case GL_TEXTURE_CUBE_MAP: + if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) { + /* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL. + */ + + firstLevel = lastLevel = tObj->BaseLevel; + } + else { + firstLevel = tObj->BaseLevel + (GLint)(tObj->MinLod + 0.5); + firstLevel = MAX2(firstLevel, tObj->BaseLevel); + lastLevel = tObj->BaseLevel + (GLint)(tObj->MaxLod + 0.5); + lastLevel = MAX2(lastLevel, t->tObj->BaseLevel); + lastLevel = MIN2(lastLevel, t->tObj->BaseLevel + baseImage->MaxLog2); + lastLevel = MIN2(lastLevel, t->tObj->MaxLevel); + lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */ + } + break; + case GL_TEXTURE_RECTANGLE_NV: + case GL_TEXTURE_4D_SGIS: + firstLevel = lastLevel = 0; + break; + default: + return; + } + + /* save these values */ + t->firstLevel = firstLevel; + t->lastLevel = lastLevel; +} diff --git a/reactos/lib/mesa32/src/drivers/dri/common/texmem.h b/reactos/lib/mesa32/src/drivers/dri/common/texmem.h new file mode 100644 index 00000000000..9afbb0c865b --- /dev/null +++ b/reactos/lib/mesa32/src/drivers/dri/common/texmem.h @@ -0,0 +1,295 @@ +/* + * Copyright 2000-2001 VA Linux Systems, Inc. + * (c) Copyright IBM Corporation 2002 + * 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 + * VA LINUX SYSTEM, IBM 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: + * Ian Romanick + * Keith Whitwell + * Kevin E. Martin + * Gareth Hughes + */ +/* $XFree86:$ */ + +/** \file texmem.h + * Public interface to the DRI texture memory management routines. + * + * \sa texmem.c + */ + +#ifndef DRI_TEXMEM_H +#define DRI_TEXMEM_H + +#include "mtypes.h" +#include "mm.h" +#include "xf86drm.h" + +struct dri_tex_heap; +typedef struct dri_tex_heap driTexHeap; + +struct dri_texture_object; +typedef struct dri_texture_object driTextureObject; + + +/** + * Base texture object type. Each driver will extend this type with its own + * private data members. + */ + +struct dri_texture_object { + struct dri_texture_object * next; + struct dri_texture_object * prev; + + driTexHeap * heap; /**< Texture heap currently stored in */ + struct gl_texture_object * tObj;/**< Pointer to Mesa texture object + * If NULL, this texture object is a + * "placeholder" object representing + * texture memory in use by another context. + * A placeholder should have a heap and a memBlock. + */ + PMemBlock memBlock; /**< Memory block containing texture */ + unsigned bound; /**< Texture unit currently bound to */ + + unsigned totalSize; /**< Total size of the texture, + * including all mipmap levels + */ + + unsigned dirty_images[6]; /**< Flags for whether or not images + * need to be uploaded to local or + * AGP texture space. One flag set + * for each cube face for cubic + * textures. Bit zero corresponds to + * the base-level, which may or may + * not be the level zero mipmap. + */ + + unsigned timestamp; /**< Timestamp used to + * synchronize with 3d engine + * in hardware where textures + * are uploaded directly to + * the framebuffer. + */ + + unsigned firstLevel; /**< Image in \c tObj->Image that + * corresponds to the base-level of + * this texture object. + */ + + unsigned lastLevel; /**< Last image in \c tObj->Image used + * by the current LOD settings of this + * texture object. This value must be + * greater than or equal to + * \c firstLevel. + */ +}; + + +typedef void (destroy_texture_object_t)( void * driverContext, + driTextureObject * t ); + +/** + * Client-private representation of texture memory state. + * + * Clients will place one or more of these structs in their driver + * context struct to manage one or more global texture heaps. + */ + +struct dri_tex_heap { + + /** Client-supplied heap identifier + */ + unsigned heapId; + + /** Pointer to the client's private context + */ + void *driverContext; + + /** Total size of the heap, in bytes + */ + unsigned size; + + /** \brief \f$log_2\f$ of size of single heap region + * + * Each context takes memory from the global texture heap in + * \f$2^{logGranularity}\f$ byte blocks. The value of + * \a logGranularity is based on the amount of memory represented + * by the heap and the maximum number of regions in the SAREA. Given + * \a b bytes of texture memory an \a n regions in the SAREA, + * \a logGranularity will be \f$\lfloor\log_2( b / n )\rfloor\f$. + */ + unsigned logGranularity; + + /** \brief Required alignment of allocations in this heap + * + * The alignment shift is supplied to \a mmAllocMem when memory is + * allocated from this heap. The value of \a alignmentShift will + * typically reflect some require of the hardware. This value has + * \b no \b relation to \a logGranularity. \a alignmentShift is a + * per-context value. + * + * \sa mmAllocMem + */ + unsigned alignmentShift; + + /** Number of elements in global list (the SAREA). + */ + unsigned nrRegions; + + /** Pointer to SAREA \a driTexRegion array + */ + drmTextureRegionPtr global_regions; + + /** Pointer to the texture state age (generation number) in the SAREA + */ + unsigned * global_age; + + /** Local age (generation number) of texture state + */ + unsigned local_age; + + /** Memory heap used to manage texture memory represented by + * this texture heap. + */ + memHeap_t * memory_heap; + + /** List of objects that we currently believe to be in texture + * memory. + */ + driTextureObject texture_objects; + + /** Pointer to the list of texture objects that are not in + * texture memory. + */ + driTextureObject * swapped_objects; + + /** Size of the driver-speicific texture object. + */ + unsigned texture_object_size; + + + /** + * \brief Function to destroy driver-specific texture object data. + * + * This function is supplied by the driver so that the texture manager + * can release all resources associated with a texture object. This + * function should only release driver-specific data. That is, + * \a driDestroyTextureObject will release the texture memory + * associated with the texture object, it will release the memory + * for the texture object itself, and it will unlink the texture + * object from the texture object lists. + * + * \param driverContext Pointer to the driver supplied context + * \param t Texture object that is to be destroyed + * \sa driDestroyTextureObject + */ + + destroy_texture_object_t * destroy_texture_object; + + + /** + */ + unsigned * texture_swaps; + + /** + * Timestamp used to synchronize with 3d engine in hardware + * where textures are uploaded directly to the + * framebuffer. + */ + unsigned timestamp; +}; + + + + +/** + * Called by the client on lock contention to determine whether textures have + * been stolen. If another client has modified a region in which we have + * textures, then we need to figure out which of our textures have been + * removed and update our global LRU. + * + * \param heap Texture heap to be updated + * \hideinitializer + */ + +#define DRI_AGE_TEXTURES( heap ) \ + do { \ + if ( ((heap) != NULL) \ + && ((heap)->local_age != (heap)->global_age[0]) ) \ + driAgeTextures( heap ); \ + } while( 0 ) + + + + +/* This should be called whenever there has been contention on the hardware + * lock. driAgeTextures should not be called directly. Instead, clients + * should use DRI_AGE_TEXTURES, above. + */ + +void driAgeTextures( driTexHeap * heap ); + +void driUpdateTextureLRU( driTextureObject * t ); +void driSwapOutTextureObject( driTextureObject * t ); +void driDestroyTextureObject( driTextureObject * t ); +int driAllocateTexture( driTexHeap * const * heap_array, unsigned nr_heaps, + driTextureObject * t ); + +GLboolean driIsTextureResident( GLcontext * ctx, + struct gl_texture_object * texObj ); + +driTexHeap * driCreateTextureHeap( unsigned heap_id, void * context, + unsigned size, unsigned alignmentShift, unsigned nr_regions, + drmTextureRegionPtr global_regions, unsigned * global_age, + driTextureObject * swapped_objects, unsigned texture_object_size, + destroy_texture_object_t * destroy_tex_obj ); +void driDestroyTextureHeap( driTexHeap * heap ); + +void +driCalculateMaxTextureLevels( driTexHeap * const * heaps, + unsigned nr_heaps, + struct gl_constants * limits, + unsigned max_bytes_per_texel, + unsigned max_2D_size, + unsigned max_3D_size, + unsigned max_cube_size, + unsigned max_rect_size, + unsigned mipmaps_at_once, + int all_textures_one_heap ); + +void +driSetTextureSwapCounterLocation( driTexHeap * heap, unsigned * counter ); + +#define DRI_TEXMGR_DO_TEXTURE_1D 0x0001 +#define DRI_TEXMGR_DO_TEXTURE_2D 0x0002 +#define DRI_TEXMGR_DO_TEXTURE_3D 0x0004 +#define DRI_TEXMGR_DO_TEXTURE_CUBE 0x0008 +#define DRI_TEXMGR_DO_TEXTURE_RECT 0x0010 + +void driInitTextureObjects( GLcontext *ctx, driTextureObject * swapped, + GLuint targets ); + +GLboolean driValidateTextureHeaps( driTexHeap * const * texture_heaps, + unsigned nr_heaps, const driTextureObject * swapped ); + +extern void driCalculateTextureFirstLastLevel( driTextureObject * t ); + +#endif /* DRI_TEXMEM_H */ diff --git a/reactos/lib/mesa32/src/drivers/dri/common/utils.c b/reactos/lib/mesa32/src/drivers/dri/common/utils.c new file mode 100644 index 00000000000..4276854224d --- /dev/null +++ b/reactos/lib/mesa32/src/drivers/dri/common/utils.c @@ -0,0 +1,219 @@ +/* + * (c) Copyright IBM Corporation 2002 + * 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 + * VA LINUX SYSTEM, IBM 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: + * Ian Romanick + */ +/* $XFree86:$ */ + +#include +#include +#include "mtypes.h" +#include "extensions.h" +#include "utils.h" + +#if defined(USE_X86_ASM) +#include "x86/common_x86_asm.h" +#endif + +unsigned +driParseDebugString( const char * debug, + const struct dri_debug_control * control ) +{ + unsigned flag; + + + flag = 0; + if ( debug != NULL ) { + while( control->string != NULL ) { + if ( strstr( debug, control->string ) != NULL ) { + flag |= control->flag; + } + + control++; + } + } + + return flag; +} + + + + +unsigned +driGetRendererString( char * buffer, const char * hardware_name, + const char * driver_date, GLuint agp_mode ) +{ +#ifdef USE_X86_ASM + char * x86_str = ""; + char * mmx_str = ""; + char * tdnow_str = ""; + char * sse_str = ""; +#endif + unsigned offset; + + + offset = sprintf( buffer, "Mesa DRI %s %s", hardware_name, driver_date ); + + /* Append any AGP-specific information. + */ + switch ( agp_mode ) { + case 1: + case 2: + case 4: + case 8: + offset += sprintf( & buffer[ offset ], " AGP %ux", agp_mode ); + break; + + default: + break; + } + + /* Append any CPU-specific information. + */ +#ifdef USE_X86_ASM + if ( _mesa_x86_cpu_features ) { + x86_str = " x86"; + } +# ifdef USE_MMX_ASM + if ( cpu_has_mmx ) { + mmx_str = (cpu_has_mmxext) ? "/MMX+" : "/MMX"; + } +# endif +# ifdef USE_3DNOW_ASM + if ( cpu_has_3dnow ) { + tdnow_str = (cpu_has_3dnowext) ? "/3DNow!+" : "/3DNow!"; + } +# endif +# ifdef USE_SSE_ASM + if ( cpu_has_xmm ) { + sse_str = (cpu_has_xmm2) ? "/SSE2" : "/SSE"; + } +# endif + + offset += sprintf( & buffer[ offset ], "%s%s%s%s", + x86_str, mmx_str, tdnow_str, sse_str ); + +#elif defined(USE_SPARC_ASM) + + offset += sprintf( & buffer[ offset ], " Sparc" ); + +#endif + + return offset; +} + + + + +void driInitExtensions( GLcontext * ctx, + const char * const extensions_to_enable[], + GLboolean enable_imaging ) +{ + unsigned i; + + if ( enable_imaging ) { + _mesa_enable_imaging_extensions( ctx ); + } + + for ( i = 0 ; extensions_to_enable[i] != NULL ; i++ ) { + _mesa_enable_extension( ctx, extensions_to_enable[i] ); + } +} + + + + +GLboolean +driCheckDriDdxDrmVersions(__DRIscreenPrivate *sPriv, + const char * driver_name, + int dri_major, int dri_minor, + int ddx_major, int ddx_minor, + int drm_major, int drm_minor) +{ + static const char format[] = "%s DRI driver expected %s version %d.%d.x " + "but got version %d.%d.%d"; + int major, minor, patch; + +#ifndef _SOLO + /* Check the DRI version */ + if (XF86DRIQueryVersion(sPriv->display, &major, &minor, &patch)) { + if (major != dri_major || minor < dri_minor) { + __driUtilMessage(format, "DRI", driver_name, dri_major, dri_minor, + major, minor, patch); + return GL_FALSE; + } + } +#else + (void)major;(void)minor;(void)patch; +#endif + + /* Check that the DDX driver version is compatible */ + if (sPriv->ddxMajor != ddx_major || sPriv->ddxMinor < ddx_minor) { + __driUtilMessage(format, "DDX", driver_name, ddx_major, ddx_minor, + sPriv->ddxMajor, sPriv->ddxMinor, sPriv->ddxPatch); + return GL_FALSE; + } + + /* Check that the DRM driver version is compatible */ + if (sPriv->drmMajor != drm_major || sPriv->drmMinor < drm_minor) { + __driUtilMessage(format, "DRM", driver_name, drm_major, drm_minor, + sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch); + return GL_FALSE; + } + + return GL_TRUE; +} + +GLboolean driClipRectToFramebuffer( const GLframebuffer *buffer, + GLint *x, GLint *y, + GLsizei *width, GLsizei *height ) +{ + /* left clipping */ + if (*x < buffer->_Xmin) { + *width -= (buffer->_Xmin - *x); + *x = buffer->_Xmin; + } + + /* right clipping */ + if (*x + *width > buffer->_Xmax) + *width -= (*x + *width - buffer->_Xmax - 1); + + if (*width <= 0) + return GL_FALSE; + + /* bottom clipping */ + if (*y < buffer->_Ymin) { + *height -= (buffer->_Ymin - *y); + *y = buffer->_Ymin; + } + + /* top clipping */ + if (*y + *height > buffer->_Ymax) + *height -= (*y + *height - buffer->_Ymax - 1); + + if (*height <= 0) + return GL_FALSE; + + return GL_TRUE; +} diff --git a/reactos/lib/mesa32/src/drivers/dri/common/utils.h b/reactos/lib/mesa32/src/drivers/dri/common/utils.h new file mode 100644 index 00000000000..401a1b882f5 --- /dev/null +++ b/reactos/lib/mesa32/src/drivers/dri/common/utils.h @@ -0,0 +1,58 @@ +/* + * (c) Copyright IBM Corporation 2002 + * 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 + * VA LINUX SYSTEM, IBM 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: + * Ian Romanick + */ +/* $XFree86:$ */ + +#ifndef DRI_DEBUG_H +#define DRI_DEBUG_H + +#include "context.h" +#include "dri_util.h" + +struct dri_debug_control +{ + const char * string; + unsigned flag; +}; + +extern unsigned driParseDebugString( const char * debug, + const struct dri_debug_control * control ); + +extern unsigned driGetRendererString( char * buffer, + const char * hardware_name, const char * driver_date, GLuint agp_mode ); + +extern void driInitExtensions( GLcontext * ctx, + const char * const card_extensions[], GLboolean enable_imaging ); + +extern GLboolean driCheckDriDdxDrmVersions( __DRIscreenPrivate *sPriv, + const char * driver_name, int dri_major, int dri_minor, + int ddx_major, int ddx_minor, int drm_major, int drm_minor ); + +extern GLboolean driClipRectToFramebuffer( const GLframebuffer *buffer, + GLint *x, GLint *y, + GLsizei *width, GLsizei *height ); + +#endif /* DRI_DEBUG_H */ diff --git a/reactos/lib/mesa32/src/drivers/dri/common/vblank.c b/reactos/lib/mesa32/src/drivers/dri/common/vblank.c new file mode 100644 index 00000000000..d20f743bc9a --- /dev/null +++ b/reactos/lib/mesa32/src/drivers/dri/common/vblank.c @@ -0,0 +1,363 @@ +/* -*- mode: c; c-basic-offset: 3 -*- */ +/* + * (c) Copyright IBM Corporation 2002 + * 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 + * VA LINUX SYSTEM, IBM 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: + * Ian Romanick + */ +/* $XFree86:$ */ + +#include "glheader.h" +#include "xf86drm.h" +#include "mtypes.h" +#include "macros.h" +#include "dd.h" +#include "vblank.h" +#include "xmlpool.h" + + +/****************************************************************************/ +/** + * Get the current MSC refresh counter. + * + * Stores the 64-bit count of vertical refreshes since some (arbitrary) + * point in time in \c count. Unless the value wraps around, which it + * may, it will never decrease. + * + * \warning This function is called from \c glXGetVideoSyncSGI, which expects + * a \c count of type \c unsigned (32-bit), and \c glXGetSyncValuesOML, which + * expects a \c count of type \c int64_t (signed 64-bit). The kernel ioctl + * currently always returns a \c sequence of type \c unsigned. + * + * \param priv Pointer to the DRI screen private struct. + * \param count Storage to hold MSC counter. + * \return Zero is returned on success. A negative errno value + * is returned on failure. + */ +int driGetMSC32( __DRIscreenPrivate * priv, int64_t * count ) +{ + drmVBlank vbl; + int ret; + + /* Don't wait for anything. Just get the current refresh count. */ + + vbl.request.type = DRM_VBLANK_RELATIVE; + vbl.request.sequence = 0; + + ret = drmWaitVBlank( priv->fd, &vbl ); + *count = (int64_t)vbl.reply.sequence; + + return ret; +} + + +/****************************************************************************/ +/** + * Wait for a specified refresh count. This implements most of the + * functionality of \c glXWaitForMscOML from the GLX_OML_sync_control spec. + * Waits for the \c target_msc refresh. If that has already passed, it + * waits until \f$(MSC \bmod divisor)\f$ is equal to \c remainder. If + * \c target_msc is 0, use the behavior of glXWaitVideoSyncSGI(), which + * omits the initial check against a target MSC value. + * + * This function is actually something of a hack. The problem is that, at + * the time of this writing, none of the existing DRM modules support an + * ioctl that returns a 64-bit count (at least not on 32-bit platforms). + * However, this function exists to support a GLX function that requires + * the use of 64-bit counts. As such, there is a little bit of ugly + * hackery at the end of this function to make the 32-bit count act like + * a 64-bit count. There are still some cases where this will break, but + * I believe it catches the most common cases. + * + * The real solution is to provide an ioctl that uses a 64-bit count. + * + * \param dpy Pointer to the \c Display. + * \param priv Pointer to the DRI drawable private. + * \param target_msc Desired refresh count to wait for. A value of 0 + * means to use the glXWaitVideoSyncSGI() behavior. + * \param divisor MSC divisor if \c target_msc is already reached. + * \param remainder Desired MSC remainder if \c target_msc is already + * reached. + * \param msc Buffer to hold MSC when done waiting. + * + * \return Zero on success or \c GLX_BAD_CONTEXT on failure. + */ + +int driWaitForMSC32( __DRIdrawablePrivate *priv, + int64_t target_msc, int64_t divisor, int64_t remainder, + int64_t * msc ) +{ + drmVBlank vbl; + + + if ( divisor != 0 ) { + unsigned int target = (unsigned int)target_msc; + unsigned int next = target; + unsigned int r; + int dont_wait = (target_msc == 0); + + do { + /* dont_wait means we're using the glXWaitVideoSyncSGI() behavior. + * The first time around, just get the current count and proceed + * to the test for (MSC % divisor) == remainder. + */ + vbl.request.type = dont_wait ? DRM_VBLANK_RELATIVE : + DRM_VBLANK_ABSOLUTE; + vbl.request.sequence = next; + + if ( drmWaitVBlank( priv->driScreenPriv->fd, &vbl ) != 0 ) { + /* FIXME: This doesn't seem like the right thing to return here. + */ +#ifndef _SOLO + return GLX_BAD_CONTEXT; +#else + return -1; +#endif + } + + dont_wait = 0; + if (target_msc != 0 && vbl.reply.sequence == target) + break; + + /* Assuming the wait-done test fails, the next refresh to wait for + * will be one that satisfies (MSC % divisor) == remainder. The + * value (MSC - (MSC % divisor) + remainder) is the refresh value + * closest to the current value that would satisfy the equation. + * If this refresh has already happened, we add divisor to obtain + * the next refresh after the current one that will satisfy it. + */ + r = (vbl.reply.sequence % (unsigned int)divisor); + next = (vbl.reply.sequence - r + (unsigned int)remainder); + if (next <= vbl.reply.sequence) next += (unsigned int)divisor; + + } while ( r != (unsigned int)remainder ); + } + else { + /* If the \c divisor is zero, just wait until the MSC is greater + * than or equal to \c target_msc. + */ + + vbl.request.type = DRM_VBLANK_ABSOLUTE; + vbl.request.sequence = target_msc; + + if ( drmWaitVBlank( priv->driScreenPriv->fd, &vbl ) != 0 ) { + /* FIXME: This doesn't seem like the right thing to return here. + */ +#ifndef _SOLO + return GLX_BAD_CONTEXT; +#else + return -1; +#endif + } + } + + *msc = (target_msc & 0xffffffff00000000LL); + *msc |= vbl.reply.sequence; + if ( *msc < target_msc ) { + *msc += 0x0000000100000000LL; + } + + return 0; +} + + +/****************************************************************************/ +/** + * Gets a set of default vertical-blank-wait flags based on the internal GLX + * API version and several configuration options. + */ + +GLuint driGetDefaultVBlankFlags( const driOptionCache *optionCache ) +{ + GLuint flags = 0; + int vblank_mode; + + flags |= (driCompareGLXAPIVersion( 20030317 ) >= 0) + ? VBLANK_FLAG_INTERVAL : 0; + + if ( driCheckOption( optionCache, "vblank_mode", DRI_ENUM ) ) + vblank_mode = driQueryOptioni( optionCache, "vblank_mode" ); + else + vblank_mode = DRI_CONF_VBLANK_DEF_INTERVAL_1; + + switch (vblank_mode) { + case DRI_CONF_VBLANK_NEVER: + flags = 0; + break; + case DRI_CONF_VBLANK_DEF_INTERVAL_0: + break; + case DRI_CONF_VBLANK_DEF_INTERVAL_1: + flags |= VBLANK_FLAG_THROTTLE; + break; + case DRI_CONF_VBLANK_ALWAYS_SYNC: + flags |= VBLANK_FLAG_SYNC; + break; + } + + return flags; +} + + +/****************************************************************************/ +/** + * Sets the default swap interval when the drawable is first bound to a + * direct rendering context. + */ + +void driDrawableInitVBlank( __DRIdrawablePrivate *priv, GLuint flags ) +{ +#ifndef _SOLO + if ( priv->pdraw->swap_interval == (unsigned)-1 ) { + priv->pdraw->swap_interval = (flags & VBLANK_FLAG_THROTTLE) != 0 ? 1 : 0; + } +#endif +} + + +/****************************************************************************/ +/** + * Wrapper to call \c drmWaitVBlank. The main purpose of this function is to + * wrap the error message logging. The error message should only be logged + * the first time the \c drmWaitVBlank fails. If \c drmWaitVBlank is + * successful, \c vbl_seq will be set the sequence value in the reply. + * + * \param vbl Pointer to drmVBlank packet desribing how to wait. + * \param vbl_seq Location to store the current refresh counter. + * \param fd File descriptor use to call into the DRM. + * \return Zero on success or -1 on failure. + */ + +static int do_wait( drmVBlank * vbl, GLuint * vbl_seq, int fd ) +{ + int ret; + + + ret = drmWaitVBlank( fd, vbl ); + if ( ret != 0 ) { + static GLboolean first_time = GL_TRUE; + + if ( first_time ) { + fprintf(stderr, + "%s: drmWaitVBlank returned %d, IRQs don't seem to be" + " working correctly.\nTry running with LIBGL_THROTTLE_REFRESH" + " and LIBL_SYNC_REFRESH unset.\n", __FUNCTION__, ret); + first_time = GL_FALSE; + } + + return -1; + } + + *vbl_seq = vbl->reply.sequence; + return 0; +} + + +/****************************************************************************/ +/** + * Waits for the vertical blank for use with glXSwapBuffers. + * + * \param vbl_seq Vertical blank sequence number (MSC) after the last buffer + * swap. Updated after this wait. + * \param flags \c VBLANK_FLAG bits that control how long to wait. + * \param missed_deadline Set to \c GL_TRUE if the MSC after waiting is later + * than the "target" based on \c flags. The idea is that if + * \c missed_deadline is set, then the application is not + * achieving its desired framerate. + * \return Zero on success, -1 on error. + */ + +int +driWaitForVBlank( const __DRIdrawablePrivate *priv, GLuint * vbl_seq, + GLuint flags, GLboolean * missed_deadline ) +{ + drmVBlank vbl; + unsigned original_seq; + unsigned deadline; + unsigned interval; + + + *missed_deadline = GL_FALSE; + if ( (flags & (VBLANK_FLAG_INTERVAL | + VBLANK_FLAG_THROTTLE | + VBLANK_FLAG_SYNC)) == 0 || + (flags & VBLANK_FLAG_NO_IRQ) != 0 ) { + return 0; + } + + + /* VBLANK_FLAG_SYNC means to wait for at least one vertical blank. If + * that flag is not set, do a fake wait for zero vertical blanking + * periods so that we can get the current MSC. + * + * VBLANK_FLAG_INTERVAL and VBLANK_FLAG_THROTTLE mean to wait for at + * least one vertical blank since the last wait. Since do_wait modifies + * vbl_seq, we have to save the original value of vbl_seq for the + * VBLANK_FLAG_INTERVAL / VBLANK_FLAG_THROTTLE calculation later. + */ + + original_seq = *vbl_seq; + + vbl.request.sequence = ((flags & VBLANK_FLAG_SYNC) != 0) ? 1 : 0; + vbl.request.type = DRM_VBLANK_RELATIVE; + + if ( do_wait( & vbl, vbl_seq, priv->driScreenPriv->fd ) != 0 ) { + return -1; + } + + + vbl.request.type = DRM_VBLANK_ABSOLUTE; + + if ( (flags & VBLANK_FLAG_INTERVAL) != 0 ) { +#ifndef _SOLO + interval = priv->pdraw->swap_interval; +#else + interval = 0; +#endif + /* this must have been initialized when the drawable was first bound + * to a direct rendering context. */ + assert ( interval != (unsigned)-1 ); + } + else if ( (flags & VBLANK_FLAG_THROTTLE) != 0 ) { + interval = 1; + } + else { + interval = 0; + } + + + /* Wait until the next vertical blank. If the interval is zero, then + * the deadline is one vertical blank after the previous wait. + */ + + vbl.request.sequence = original_seq + interval; + if ( *vbl_seq < vbl.request.sequence ) { + if ( do_wait( & vbl, vbl_seq, priv->driScreenPriv->fd ) != 0 ) { + return -1; + } + } + + deadline = original_seq + ((interval == 0) ? 1 : interval); + *missed_deadline = ( *vbl_seq > deadline ); + + return 0; +} diff --git a/reactos/lib/mesa32/src/drivers/dri/common/vblank.h b/reactos/lib/mesa32/src/drivers/dri/common/vblank.h new file mode 100644 index 00000000000..d460d7a84ad --- /dev/null +++ b/reactos/lib/mesa32/src/drivers/dri/common/vblank.h @@ -0,0 +1,64 @@ +/* -*- mode: c; c-basic-offset: 3 -*- */ +/* + * (c) Copyright IBM Corporation 2002 + * 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 + * VA LINUX SYSTEM, IBM 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: + * Ian Romanick + */ +/* $XFree86:$ */ + +#ifndef DRI_VBLANK_H +#define DRI_VBLANK_H + +#include "context.h" +#include "dri_util.h" +#include "xmlconfig.h" + +#define VBLANK_FLAG_INTERVAL (1U << 0) /* Respect the swap_interval setting + */ +#define VBLANK_FLAG_THROTTLE (1U << 1) /* Wait 1 refresh since last call. + */ +#define VBLANK_FLAG_SYNC (1U << 2) /* Sync to the next refresh. + */ +#define VBLANK_FLAG_NO_IRQ (1U << 7) /* DRM has no IRQ to wait on. + */ + +extern int driGetMSC32( __DRIscreenPrivate * priv, int64_t * count ); +extern int driWaitForMSC32( __DRIdrawablePrivate *priv, + int64_t target_msc, int64_t divisor, int64_t remainder, int64_t * msc ); +extern GLuint driGetDefaultVBlankFlags( const driOptionCache *optionCache ); +extern void driDrawableInitVBlank ( __DRIdrawablePrivate *priv, GLuint flags ); +extern int driWaitForVBlank( const __DRIdrawablePrivate *priv, + GLuint * vbl_seq, GLuint flags, GLboolean * missed_deadline ); + +#undef usleep +#include /* for usleep() */ + +#define DO_USLEEP(nr) \ + do { \ + if (0) fprintf(stderr, "%s: usleep for %u\n", __FUNCTION__, nr ); \ + if (1) usleep( nr ); \ + sched_yield(); \ + } while( 0 ) + +#endif /* DRI_VBLANK_H */ diff --git a/reactos/lib/mesa32/src/drivers/dri/common/xmlconfig.c b/reactos/lib/mesa32/src/drivers/dri/common/xmlconfig.c new file mode 100644 index 00000000000..f45ab06ac41 --- /dev/null +++ b/reactos/lib/mesa32/src/drivers/dri/common/xmlconfig.c @@ -0,0 +1,993 @@ +/* + * XML DRI client-side driver configuration + * Copyright (C) 2003 Felix Kuehling + * + * 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 + * FELIX KUEHLING, OR ANY OTHER CONTRIBUTORS 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 xmlconfig.c + * \brief Driver-independent client-side part of the XML configuration + * \author Felix Kuehling + */ + +#include "glheader.h" + +#include +#include +#include +#include +#include +#include +#include "imports.h" +#include "dri_util.h" +#include "xmlconfig.h" + +/* + * OS dependent ways of getting the name of the running program + */ +#if (defined(__unix__) || defined(unix)) && !defined(USG) +#include +#endif + +#undef GET_PROGRAM_NAME + +#if defined(__GNU_LIBRARY__) || defined(__GLIBC__) +# define GET_PROGRAM_NAME() program_invocation_short_name +#elif defined(__FreeBSD__) && (__FreeBSD__ >= 2) +# include +# if (__FreeBSD_version >= 440000) +# include +# define GET_PROGRAM_NAME() getprogname() +# endif +#elif defined(__NetBSD__) && defined(__NetBSD_Version) && (__NetBSD_Version >= 106000100) +# include +# define GET_PROGRAM_NAME() getprogname() +#endif + +#if !defined(GET_PROGRAM_NAME) +# if defined(OpenBSD) || defined(NetBSD) +/* This is a hack. It's said to work on OpenBSD, NetBSD and GNU. It's + * used as a last resort, if there is no documented facility available. */ +static const char *__getProgramName () { + extern const char *__progname; + return progname; +} +# define GET_PROGRAM_NAME() __getProgramName() +# else +# define GET_PROGRAM_NAME() "" +# warning "Per application configuration won't with your OS version work." +# endif +#endif + +/** \brief Find an option in an option cache with the name as key */ +static GLuint findOption (const driOptionCache *cache, const char *name) { + GLuint len = strlen (name); + GLuint size = 1 << cache->tableSize, mask = size - 1; + GLuint hash = 0; + GLuint i, shift; + + /* compute a hash from the variable length name */ + for (i = 0, shift = 0; i < len; ++i, shift = (shift+8) & 31) + hash += (GLuint)name[i] << shift; + hash *= hash; + hash = (hash >> (16-cache->tableSize/2)) & mask; + + /* this is just the starting point of the linear search for the option */ + for (i = 0; i < size; ++i, hash = (hash+1) & mask) { + /* if we hit an empty entry then the option is not defined (yet) */ + if (cache->info[hash].name == 0) + break; + else if (!strcmp (name, cache->info[hash].name)) + break; + } + /* this assertion fails if the hash table is full */ + assert (i < size); + + return hash; +} + +/** \brief Count the real number of options in an option cache */ +static GLuint countOptions (const driOptionCache *cache) { + GLuint size = 1 << cache->tableSize; + GLuint i, count = 0; + for (i = 0; i < size; ++i) + if (cache->info[i].name) + count++; + return count; +} + +/** \brief Like strdup but using MALLOC and with error checking. */ +#define XSTRDUP(dest,source) do { \ + GLuint len = strlen (source); \ + if (!(dest = MALLOC (len+1))) { \ + fprintf (stderr, "%s: %d: out of memory.\n", __FILE__, __LINE__); \ + abort(); \ + } \ + memcpy (dest, source, len+1); \ +} while (0) + +static int compare (const void *a, const void *b) { + return strcmp (*(char *const*)a, *(char *const*)b); +} +/** \brief Binary search in a string array. */ +static GLuint bsearchStr (const XML_Char *name, + const XML_Char *elems[], GLuint count) { + const XML_Char **found; + found = bsearch (&name, elems, count, sizeof (XML_Char *), compare); + if (found) + return found - elems; + else + return count; +} + +/** \brief Locale-independent integer parser. + * + * Works similar to strtol. Leading space is NOT skipped. The input + * number may have an optional sign. Radix is specified by base. If + * base is 0 then decimal is assumed unless the input number is + * prefixed by 0x or 0X for hexadecimal or 0 for octal. After + * returning tail points to the first character that is not part of + * the integer number. If no number was found then tail points to the + * start of the input string. */ +static GLint strToI (const XML_Char *string, const XML_Char **tail, int base) { + GLint radix = base == 0 ? 10 : base; + GLint result = 0; + GLint sign = 1; + GLboolean numberFound = GL_FALSE; + const XML_Char *start = string; + + assert (radix >= 2 && radix <= 36); + + if (*string == '-') { + sign = -1; + string++; + } else if (*string == '+') + string++; + if (base == 0 && *string == '0') { + numberFound = GL_TRUE; + if (*(string+1) == 'x' || *(string+1) == 'X') { + radix = 16; + string += 2; + } else { + radix = 8; + string++; + } + } + do { + GLint digit = -1; + if (radix <= 10) { + if (*string >= '0' && *string < '0' + radix) + digit = *string - '0'; + } else { + if (*string >= '0' && *string <= '9') + digit = *string - '0'; + else if (*string >= 'a' && *string < 'a' + radix - 10) + digit = *string - 'a' + 10; + else if (*string >= 'A' && *string < 'A' + radix - 10) + digit = *string - 'A' + 10; + } + if (digit != -1) { + numberFound = GL_TRUE; + result = radix*result + digit; + string++; + } else + break; + } while (GL_TRUE); + *tail = numberFound ? string : start; + return sign * result; +} + +/** \brief Locale-independent floating-point parser. + * + * Works similar to strtod. Leading space is NOT skipped. The input + * number may have an optional sign. '.' is interpreted as decimal + * point and may occor at most once. Optionally the number may end in + * [eE], where is an integer as recognized by + * strToI. In that case the result is number * 10^exponent. After + * returning tail points to the first character that is not part of + * the floating point number. If no number was found then tail points + * to the start of the input string. + * + * Uses two passes for maximum accuracy. */ +static GLfloat strToF (const XML_Char *string, const XML_Char **tail) { + GLint nDigits = 0, pointPos, exponent; + GLfloat sign = 1.0f, result = 0.0f, scale; + const XML_Char *start = string, *numStart; + + /* sign */ + if (*string == '-') { + sign = -1.0f; + string++; + } else if (*string == '+') + string++; + + /* first pass: determine position of decimal point, number of + * digits, exponent and the end of the number. */ + numStart = string; + while (*string >= '0' && *string <= '9') { + string++; + nDigits++; + } + pointPos = nDigits; + if (*string == '.') { + string++; + while (*string >= '0' && *string <= '9') { + string++; + nDigits++; + } + } + if (nDigits == 0) { + /* no digits, no number */ + *tail = start; + return 0.0f; + } + *tail = string; + if (*string == 'e' || *string == 'E') { + const XML_Char *expTail; + exponent = strToI (string+1, &expTail, 10); + if (expTail == string+1) + exponent = 0; + else + *tail = expTail; + } else + exponent = 0; + string = numStart; + + /* scale of the first digit */ + scale = sign * powf (10.0f, (GLfloat)(pointPos-1 + exponent)); + + /* second pass: parse digits */ + do { + if (*string != '.') { + assert (*string >= '0' && *string <= '9'); + result += scale * (GLfloat)(*string - '0'); + scale *= 0.1f; + nDigits--; + } + string++; + } while (nDigits > 0); + + return result; +} + +/** \brief Parse a value of a given type. */ +static GLboolean parseValue (driOptionValue *v, driOptionType type, + const XML_Char *string) { + const XML_Char *tail; + /* skip leading white-space */ + string += strspn (string, " \f\n\r\t\v"); + switch (type) { + case DRI_BOOL: + if (!strcmp (string, "false")) { + v->_bool = GL_FALSE; + tail = string + 5; + } else if (!strcmp (string, "true")) { + v->_bool = GL_TRUE; + tail = string + 4; + } + else + return GL_FALSE; + break; + case DRI_ENUM: /* enum is just a special integer */ + case DRI_INT: + v->_int = strToI (string, &tail, 0); + break; + case DRI_FLOAT: + v->_float = strToF (string, &tail); + break; + } + + if (tail == string) + return GL_FALSE; /* empty string (or containing only white-space) */ + /* skip trailing white space */ + if (*tail) + tail += strspn (tail, " \f\n\r\t\v"); + if (*tail) + return GL_FALSE; /* something left over that is not part of value */ + + return GL_TRUE; +} + +/** \brief Parse a list of ranges of type info->type. */ +static GLboolean parseRanges (driOptionInfo *info, const XML_Char *string) { + XML_Char *cp, *range; + GLuint nRanges, i; + driOptionRange *ranges; + + XSTRDUP (cp, string); + /* pass 1: determine the number of ranges (number of commas + 1) */ + range = cp; + for (nRanges = 1; *range; ++range) + if (*range == ',') + ++nRanges; + + if ((ranges = MALLOC (nRanges*sizeof(driOptionRange))) == NULL) { + fprintf (stderr, "%s: %d: out of memory.\n", __FILE__, __LINE__); + abort(); + } + + /* pass 2: parse all ranges into preallocated array */ + range = cp; + for (i = 0; i < nRanges; ++i) { + XML_Char *end, *sep; + assert (range); + end = strchr (range, ','); + if (end) + *end = '\0'; + sep = strchr (range, ':'); + if (sep) { /* non-empty interval */ + *sep = '\0'; + if (!parseValue (&ranges[i].start, info->type, range) || + !parseValue (&ranges[i].end, info->type, sep+1)) + break; + if (info->type == DRI_INT && + ranges[i].start._int > ranges[i].end._int) + break; + if (info->type == DRI_FLOAT && + ranges[i].start._float > ranges[i].end._float) + break; + } else { /* empty interval */ + if (!parseValue (&ranges[i].start, info->type, range)) + break; + ranges[i].end = ranges[i].start; + } + if (end) + range = end+1; + else + range = NULL; + } + FREE (cp); + if (i < nRanges) { + FREE (ranges); + return GL_FALSE; + } else + assert (range == NULL); + + info->nRanges = nRanges; + info->ranges = ranges; + return GL_TRUE; +} + +/** \brief Check if a value is in one of info->ranges. */ +static GLboolean checkValue (const driOptionValue *v, const driOptionInfo *info) { + GLuint i; + assert (info->type != DRI_BOOL); /* should be caught by the parser */ + if (info->nRanges == 0) + return GL_TRUE; + switch (info->type) { + case DRI_ENUM: /* enum is just a special integer */ + case DRI_INT: + for (i = 0; i < info->nRanges; ++i) + if (v->_int >= info->ranges[i].start._int && + v->_int <= info->ranges[i].end._int) + return GL_TRUE; + break; + case DRI_FLOAT: + for (i = 0; i < info->nRanges; ++i) + if (v->_float >= info->ranges[i].start._float && + v->_float <= info->ranges[i].end._float) + return GL_TRUE; + break; + default: + assert (0); /* should never happen */ + } + return GL_FALSE; +} + +/** \brief Output a warning message. */ +#define XML_WARNING1(msg) do {\ + __driUtilMessage ("Warning in %s line %d, column %d: "msg, data->name, \ + XML_GetCurrentLineNumber(data->parser), \ + XML_GetCurrentColumnNumber(data->parser)); \ +} while (0) +#define XML_WARNING(msg,args...) do { \ + __driUtilMessage ("Warning in %s line %d, column %d: "msg, data->name, \ + XML_GetCurrentLineNumber(data->parser), \ + XML_GetCurrentColumnNumber(data->parser), \ + args); \ +} while (0) +/** \brief Output an error message. */ +#define XML_ERROR1(msg) do { \ + __driUtilMessage ("Error in %s line %d, column %d: "msg, data->name, \ + XML_GetCurrentLineNumber(data->parser), \ + XML_GetCurrentColumnNumber(data->parser)); \ +} while (0) +#define XML_ERROR(msg,args...) do { \ + __driUtilMessage ("Error in %s line %d, column %d: "msg, data->name, \ + XML_GetCurrentLineNumber(data->parser), \ + XML_GetCurrentColumnNumber(data->parser), \ + args); \ +} while (0) +/** \brief Output a fatal error message and abort. */ +#define XML_FATAL1(msg) do { \ + fprintf (stderr, "Fatal error in %s line %d, column %d: "msg"\n", \ + data->name, \ + XML_GetCurrentLineNumber(data->parser), \ + XML_GetCurrentColumnNumber(data->parser)); \ + abort();\ +} while (0) +#define XML_FATAL(msg,args...) do { \ + fprintf (stderr, "Fatal error in %s line %d, column %d: "msg"\n", \ + data->name, \ + XML_GetCurrentLineNumber(data->parser), \ + XML_GetCurrentColumnNumber(data->parser), \ + args); \ + abort();\ +} while (0) + +/** \brief Parser context for __driConfigOptions. */ +struct OptInfoData { + const char *name; + XML_Parser parser; + driOptionCache *cache; + GLboolean inDriInfo; + GLboolean inSection; + GLboolean inDesc; + GLboolean inOption; + GLboolean inEnum; + int curOption; +}; + +/** \brief Elements in __driConfigOptions. */ +enum OptInfoElem { + OI_DESCRIPTION = 0, OI_DRIINFO, OI_ENUM, OI_OPTION, OI_SECTION, OI_COUNT +}; +static const XML_Char *OptInfoElems[] = { + "description", "driinfo", "enum", "option", "section" +}; + +/** \brief Parse attributes of an enum element. + * + * We're not actually interested in the data. Just make sure this is ok + * for external configuration tools. + */ +static void parseEnumAttr (struct OptInfoData *data, const XML_Char **attr) { + GLuint i; + const XML_Char *value = NULL, *text = NULL; + driOptionValue v; + GLuint opt = data->curOption; + for (i = 0; attr[i]; i += 2) { + if (!strcmp (attr[i], "value")) value = attr[i+1]; + else if (!strcmp (attr[i], "text")) text = attr[i+1]; + else XML_FATAL("illegal enum attribute: %s.", attr[i]); + } + if (!value) XML_FATAL1 ("value attribute missing in enum."); + if (!text) XML_FATAL1 ("text attribute missing in enum."); + if (!parseValue (&v, data->cache->info[opt].type, value)) + XML_FATAL ("illegal enum value: %s.", value); + if (!checkValue (&v, &data->cache->info[opt])) + XML_FATAL ("enum value out of valid range: %s.", value); +} + +/** \brief Parse attributes of a description element. + * + * We're not actually interested in the data. Just make sure this is ok + * for external configuration tools. + */ +static void parseDescAttr (struct OptInfoData *data, const XML_Char **attr) { + GLuint i; + const XML_Char *lang = NULL, *text = NULL; + for (i = 0; attr[i]; i += 2) { + if (!strcmp (attr[i], "lang")) lang = attr[i+1]; + else if (!strcmp (attr[i], "text")) text = attr[i+1]; + else XML_FATAL("illegal description attribute: %s.", attr[i]); + } + if (!lang) XML_FATAL1 ("lang attribute missing in description."); + if (!text) XML_FATAL1 ("text attribute missing in description."); +} + +/** \brief Parse attributes of an option element. */ +static void parseOptInfoAttr (struct OptInfoData *data, const XML_Char **attr) { + enum OptAttr {OA_DEFAULT = 0, OA_NAME, OA_TYPE, OA_VALID, OA_COUNT}; + static const XML_Char *optAttr[] = {"default", "name", "type", "valid"}; + const XML_Char *attrVal[OA_COUNT] = {NULL, NULL, NULL, NULL}; + const char *defaultVal; + driOptionCache *cache = data->cache; + GLuint opt, i; + for (i = 0; attr[i]; i += 2) { + GLuint attrName = bsearchStr (attr[i], optAttr, OA_COUNT); + if (attrName >= OA_COUNT) + XML_FATAL ("illegal option attribute: %s", attr[i]); + attrVal[attrName] = attr[i+1]; + } + if (!attrVal[OA_NAME]) XML_FATAL1 ("name attribute missing in option."); + if (!attrVal[OA_TYPE]) XML_FATAL1 ("type attribute missing in option."); + if (!attrVal[OA_DEFAULT]) XML_FATAL1 ("default attribute missing in option."); + + opt = findOption (cache, attrVal[OA_NAME]); + if (cache->info[opt].name) + XML_FATAL ("option %s redefined.", attrVal[OA_NAME]); + data->curOption = opt; + + XSTRDUP (cache->info[opt].name, attrVal[OA_NAME]); + + if (!strcmp (attrVal[OA_TYPE], "bool")) + cache->info[opt].type = DRI_BOOL; + else if (!strcmp (attrVal[OA_TYPE], "enum")) + cache->info[opt].type = DRI_ENUM; + else if (!strcmp (attrVal[OA_TYPE], "int")) + cache->info[opt].type = DRI_INT; + else if (!strcmp (attrVal[OA_TYPE], "float")) + cache->info[opt].type = DRI_FLOAT; + else + XML_FATAL ("illegal type in option: %s.", attrVal[OA_TYPE]); + + defaultVal = getenv (cache->info[opt].name); + if (defaultVal != NULL) { + /* don't use XML_WARNING, we want the user to see this! */ + fprintf (stderr, + "ATTENTION: default value of option %s overridden by environment.\n", + cache->info[opt].name); + } else + defaultVal = attrVal[OA_DEFAULT]; + if (!parseValue (&cache->values[opt], cache->info[opt].type, defaultVal)) + XML_FATAL ("illegal default value: %s.", defaultVal); + + if (attrVal[OA_VALID]) { + if (cache->info[opt].type == DRI_BOOL) + XML_FATAL1 ("boolean option with valid attribute."); + if (!parseRanges (&cache->info[opt], attrVal[OA_VALID])) + XML_FATAL ("illegal valid attribute: %s.", attrVal[OA_VALID]); + if (!checkValue (&cache->values[opt], &cache->info[opt])) + XML_FATAL ("default value out of valid range '%s': %s.", + attrVal[OA_VALID], defaultVal); + } else if (cache->info[opt].type == DRI_ENUM) { + XML_FATAL1 ("valid attribute missing in option (mandatory for enums)."); + } else { + cache->info[opt].nRanges = 0; + cache->info[opt].ranges = NULL; + } +} + +/** \brief Handler for start element events. */ +static void optInfoStartElem (void *userData, const XML_Char *name, + const XML_Char **attr) { + struct OptInfoData *data = (struct OptInfoData *)userData; + enum OptInfoElem elem = bsearchStr (name, OptInfoElems, OI_COUNT); + switch (elem) { + case OI_DRIINFO: + if (data->inDriInfo) + XML_FATAL1 ("nested elements."); + if (attr[0]) + XML_FATAL1 ("attributes specified on element."); + data->inDriInfo = GL_TRUE; + break; + case OI_SECTION: + if (!data->inDriInfo) + XML_FATAL1 ("
must be inside ."); + if (data->inSection) + XML_FATAL1 ("nested
elements."); + if (attr[0]) + XML_FATAL1 ("attributes specified on
element."); + data->inSection = GL_TRUE; + break; + case OI_DESCRIPTION: + if (!data->inSection && !data->inOption) + XML_FATAL1 (" must be inside or inDesc) + XML_FATAL1 ("nested elements."); + data->inDesc = GL_TRUE; + parseDescAttr (data, attr); + break; + case OI_OPTION: + if (!data->inSection) + XML_FATAL1 ("