From 1e723abc27bdc2ad675bce79467a7308c2966861 Mon Sep 17 00:00:00 2001 From: marha Date: Tue, 22 Dec 2009 18:34:14 +0000 Subject: Forgotten files in previous commit --- mesalib/src/mesa/SConscript | 356 + .../mesa/drivers/dri/common/xmlpool/gen_xmlpool.py | 191 + mesalib/src/mesa/drivers/windows/fx/fx.rc | 39 + .../mesa/drivers/windows/gdi/InitCritSections.cpp | 32 + .../drivers/windows/gldirect/dx7/gld_driver_dx7.c | 1196 ++ .../mesa/drivers/windows/gldirect/dx7/gld_dx7.h | 292 + .../mesa/drivers/windows/gldirect/dx7/gld_dxerr7.h | 77 + .../drivers/windows/gldirect/dx7/gld_ext_dx7.c | 346 + .../windows/gldirect/dx7/gld_pipeline_dx7.c | 77 + .../windows/gldirect/dx7/gld_primitive_dx7.c | 1448 +++ .../drivers/windows/gldirect/dx7/gld_texture_dx7.c | 2196 ++++ .../windows/gldirect/dx7/gld_vb_d3d_render_dx7.c | 257 + .../windows/gldirect/dx7/gld_vb_mesa_render_dx7.c | 422 + .../drivers/windows/gldirect/dx7/gld_wgl_dx7.c | 1613 +++ .../drivers/windows/gldirect/dx8/gld_driver_dx8.c | 1176 ++ .../mesa/drivers/windows/gldirect/dx8/gld_dx8.h | 324 + .../mesa/drivers/windows/gldirect/dx8/gld_dxerr8.h | 77 + .../drivers/windows/gldirect/dx8/gld_ext_dx8.c | 344 + .../windows/gldirect/dx8/gld_pipeline_dx8.c | 77 + .../windows/gldirect/dx8/gld_primitive_dx8.c | 1446 +++ .../drivers/windows/gldirect/dx8/gld_texture_dx8.c | 2046 +++ .../windows/gldirect/dx8/gld_vb_d3d_render_dx8.c | 249 + .../windows/gldirect/dx8/gld_vb_mesa_render_dx8.c | 448 + .../drivers/windows/gldirect/dx8/gld_wgl_dx8.c | 1336 ++ .../drivers/windows/gldirect/dx9/gld_driver_dx9.c | 1206 ++ .../mesa/drivers/windows/gldirect/dx9/gld_dx9.h | 327 + .../mesa/drivers/windows/gldirect/dx9/gld_dxerr9.h | 77 + .../drivers/windows/gldirect/dx9/gld_ext_dx9.c | 344 + .../windows/gldirect/dx9/gld_pipeline_dx9.c | 77 + .../windows/gldirect/dx9/gld_primitive_dx9.c | 1446 +++ .../drivers/windows/gldirect/dx9/gld_texture_dx9.c | 2104 ++++ .../windows/gldirect/dx9/gld_vb_d3d_render_dx9.c | 263 + .../windows/gldirect/dx9/gld_vb_mesa_render_dx9.c | 443 + .../drivers/windows/gldirect/dx9/gld_wgl_dx9.c | 1346 ++ .../src/mesa/drivers/windows/gldirect/gldirect.rc | 43 + .../mesa/drivers/windows/gldirect/mesasw/colors.h | 520 + .../windows/gldirect/mesasw/gld_wgl_mesasw.c | 1720 +++ .../src/mesa/drivers/windows/gldirect/opengl32.ref | 495 + .../src/mesa/glapi/APPLE_vertex_array_object.xml | 27 + mesalib/src/mesa/glapi/ARB_copy_buffer.xml | 24 + mesalib/src/mesa/glapi/ARB_framebuffer_object.xml | 269 + mesalib/src/mesa/glapi/ARB_map_buffer_range.xml | 34 + mesalib/src/mesa/glapi/ARB_seamless_cube_map.xml | 12 + mesalib/src/mesa/glapi/ARB_sync.xml | 82 + mesalib/src/mesa/glapi/ARB_vertex_array_object.xml | 34 + mesalib/src/mesa/glapi/EXT_framebuffer_object.xml | 195 + mesalib/src/mesa/glapi/EXT_provoking_vertex.xml | 22 + mesalib/src/mesa/glapi/EXT_texture_array.xml | 41 + mesalib/src/mesa/glapi/Makefile | 152 + mesalib/src/mesa/glapi/extension_helper.py | 324 + mesalib/src/mesa/glapi/glX_API.xml | 220 + mesalib/src/mesa/glapi/glX_XML.py | 570 + mesalib/src/mesa/glapi/glX_doc.py | 280 + mesalib/src/mesa/glapi/glX_proto_common.py | 95 + mesalib/src/mesa/glapi/glX_proto_recv.py | 554 + mesalib/src/mesa/glapi/glX_proto_send.py | 1042 ++ mesalib/src/mesa/glapi/glX_proto_size.py | 704 ++ mesalib/src/mesa/glapi/glX_server_table.py | 411 + mesalib/src/mesa/glapi/gl_API.dtd | 140 + mesalib/src/mesa/glapi/gl_API.xml | 12514 +++++++++++++++++++ mesalib/src/mesa/glapi/gl_SPARC_asm.py | 275 + mesalib/src/mesa/glapi/gl_XML.py | 964 ++ mesalib/src/mesa/glapi/gl_and_glX_API.xml | 7 + mesalib/src/mesa/glapi/gl_apitemp.py | 253 + mesalib/src/mesa/glapi/gl_enums.py | 243 + mesalib/src/mesa/glapi/gl_offsets.py | 103 + mesalib/src/mesa/glapi/gl_procs.py | 188 + mesalib/src/mesa/glapi/gl_table.py | 199 + mesalib/src/mesa/glapi/gl_x86-64_asm.py | 334 + mesalib/src/mesa/glapi/gl_x86_asm.py | 270 + mesalib/src/mesa/glapi/license.py | 47 + mesalib/src/mesa/glapi/mesadef.py | 222 + mesalib/src/mesa/glapi/next_available_offset.sh | 39 + mesalib/src/mesa/glapi/typeexpr.py | 292 + mesalib/src/mesa/main/Makefile.ugl | 364 + mesalib/src/mesa/main/Makefile.win | 208 + mesalib/src/mesa/main/get_gen.py | 1252 ++ mesalib/src/mesa/main/sources | 158 + mesalib/src/mesa/shader/grammar/grammar.syn | 567 + mesalib/src/mesa/swrast/NOTES | 55 + mesalib/src/mesa/swrast_setup/NOTES | 65 + mesalib/src/mesa/tnl/NOTES | 102 + 82 files changed, 50429 insertions(+) create mode 100644 mesalib/src/mesa/SConscript create mode 100644 mesalib/src/mesa/drivers/dri/common/xmlpool/gen_xmlpool.py create mode 100644 mesalib/src/mesa/drivers/windows/fx/fx.rc create mode 100644 mesalib/src/mesa/drivers/windows/gdi/InitCritSections.cpp create mode 100644 mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_driver_dx7.c create mode 100644 mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_dx7.h create mode 100644 mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_dxerr7.h create mode 100644 mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_ext_dx7.c create mode 100644 mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_pipeline_dx7.c create mode 100644 mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_primitive_dx7.c create mode 100644 mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_texture_dx7.c create mode 100644 mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_vb_d3d_render_dx7.c create mode 100644 mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_vb_mesa_render_dx7.c create mode 100644 mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_wgl_dx7.c create mode 100644 mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_driver_dx8.c create mode 100644 mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_dx8.h create mode 100644 mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_dxerr8.h create mode 100644 mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_ext_dx8.c create mode 100644 mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_pipeline_dx8.c create mode 100644 mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_primitive_dx8.c create mode 100644 mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_texture_dx8.c create mode 100644 mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_vb_d3d_render_dx8.c create mode 100644 mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_vb_mesa_render_dx8.c create mode 100644 mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_wgl_dx8.c create mode 100644 mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_driver_dx9.c create mode 100644 mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_dx9.h create mode 100644 mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_dxerr9.h create mode 100644 mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_ext_dx9.c create mode 100644 mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_pipeline_dx9.c create mode 100644 mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_primitive_dx9.c create mode 100644 mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_texture_dx9.c create mode 100644 mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_vb_d3d_render_dx9.c create mode 100644 mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_vb_mesa_render_dx9.c create mode 100644 mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_wgl_dx9.c create mode 100644 mesalib/src/mesa/drivers/windows/gldirect/gldirect.rc create mode 100644 mesalib/src/mesa/drivers/windows/gldirect/mesasw/colors.h create mode 100644 mesalib/src/mesa/drivers/windows/gldirect/mesasw/gld_wgl_mesasw.c create mode 100644 mesalib/src/mesa/drivers/windows/gldirect/opengl32.ref create mode 100644 mesalib/src/mesa/glapi/APPLE_vertex_array_object.xml create mode 100644 mesalib/src/mesa/glapi/ARB_copy_buffer.xml create mode 100644 mesalib/src/mesa/glapi/ARB_framebuffer_object.xml create mode 100644 mesalib/src/mesa/glapi/ARB_map_buffer_range.xml create mode 100644 mesalib/src/mesa/glapi/ARB_seamless_cube_map.xml create mode 100644 mesalib/src/mesa/glapi/ARB_sync.xml create mode 100644 mesalib/src/mesa/glapi/ARB_vertex_array_object.xml create mode 100644 mesalib/src/mesa/glapi/EXT_framebuffer_object.xml create mode 100644 mesalib/src/mesa/glapi/EXT_provoking_vertex.xml create mode 100644 mesalib/src/mesa/glapi/EXT_texture_array.xml create mode 100644 mesalib/src/mesa/glapi/Makefile create mode 100644 mesalib/src/mesa/glapi/extension_helper.py create mode 100644 mesalib/src/mesa/glapi/glX_API.xml create mode 100644 mesalib/src/mesa/glapi/glX_XML.py create mode 100644 mesalib/src/mesa/glapi/glX_doc.py create mode 100644 mesalib/src/mesa/glapi/glX_proto_common.py create mode 100644 mesalib/src/mesa/glapi/glX_proto_recv.py create mode 100644 mesalib/src/mesa/glapi/glX_proto_send.py create mode 100644 mesalib/src/mesa/glapi/glX_proto_size.py create mode 100644 mesalib/src/mesa/glapi/glX_server_table.py create mode 100644 mesalib/src/mesa/glapi/gl_API.dtd create mode 100644 mesalib/src/mesa/glapi/gl_API.xml create mode 100644 mesalib/src/mesa/glapi/gl_SPARC_asm.py create mode 100644 mesalib/src/mesa/glapi/gl_XML.py create mode 100644 mesalib/src/mesa/glapi/gl_and_glX_API.xml create mode 100644 mesalib/src/mesa/glapi/gl_apitemp.py create mode 100644 mesalib/src/mesa/glapi/gl_enums.py create mode 100644 mesalib/src/mesa/glapi/gl_offsets.py create mode 100644 mesalib/src/mesa/glapi/gl_procs.py create mode 100644 mesalib/src/mesa/glapi/gl_table.py create mode 100644 mesalib/src/mesa/glapi/gl_x86-64_asm.py create mode 100644 mesalib/src/mesa/glapi/gl_x86_asm.py create mode 100644 mesalib/src/mesa/glapi/license.py create mode 100644 mesalib/src/mesa/glapi/mesadef.py create mode 100644 mesalib/src/mesa/glapi/next_available_offset.sh create mode 100644 mesalib/src/mesa/glapi/typeexpr.py create mode 100644 mesalib/src/mesa/main/Makefile.ugl create mode 100644 mesalib/src/mesa/main/Makefile.win create mode 100644 mesalib/src/mesa/main/get_gen.py create mode 100644 mesalib/src/mesa/main/sources create mode 100644 mesalib/src/mesa/shader/grammar/grammar.syn create mode 100644 mesalib/src/mesa/swrast/NOTES create mode 100644 mesalib/src/mesa/swrast_setup/NOTES create mode 100644 mesalib/src/mesa/tnl/NOTES (limited to 'mesalib/src/mesa') diff --git a/mesalib/src/mesa/SConscript b/mesalib/src/mesa/SConscript new file mode 100644 index 000000000..cad567632 --- /dev/null +++ b/mesalib/src/mesa/SConscript @@ -0,0 +1,356 @@ +####################################################################### +# SConscript for Mesa + + +Import('*') + +if env['platform'] != 'winddk': + + env = env.Clone() + + env.Append(CPPPATH = [ + '#/src/mesa', + ]) + + if env['platform'] == 'windows': + env.Append(CPPDEFINES = [ + '_GDI32_', # prevent gl* being declared __declspec(dllimport) in MS headers + 'BUILD_GL32', # declare gl* as __declspec(dllexport) in Mesa headers + 'WIN32_THREADS', # use Win32 thread API + ]) + + # + # Source files + # + + main_sources = [ + 'main/api_arrayelt.c', + 'main/api_exec.c', + 'main/api_loopback.c', + 'main/api_noop.c', + 'main/api_validate.c', + 'main/accum.c', + 'main/attrib.c', + 'main/arrayobj.c', + 'main/blend.c', + 'main/bufferobj.c', + 'main/buffers.c', + 'main/clear.c', + 'main/clip.c', + 'main/colortab.c', + 'main/context.c', + 'main/convolve.c', + 'main/cpuinfo.c', + 'main/debug.c', + 'main/depth.c', + 'main/depthstencil.c', + 'main/dlist.c', + 'main/dlopen.c', + 'main/drawpix.c', + 'main/enable.c', + 'main/enums.c', + 'main/eval.c', + 'main/execmem.c', + 'main/extensions.c', + 'main/fbobject.c', + 'main/feedback.c', + 'main/ffvertex_prog.c', + 'main/fog.c', + 'main/framebuffer.c', + 'main/get.c', + 'main/getstring.c', + 'main/hash.c', + 'main/hint.c', + 'main/histogram.c', + 'main/image.c', + 'main/imports.c', + 'main/light.c', + 'main/lines.c', + 'main/matrix.c', + 'main/mipmap.c', + 'main/mm.c', + 'main/multisample.c', + 'main/pixel.c', + 'main/pixelstore.c', + 'main/points.c', + 'main/polygon.c', + 'main/queryobj.c', + 'main/rastpos.c', + 'main/rbadaptors.c', + 'main/readpix.c', + 'main/renderbuffer.c', + 'main/scissor.c', + 'main/shaders.c', + 'main/shared.c', + 'main/state.c', + 'main/stencil.c', + 'main/syncobj.c', + 'main/texcompress.c', + 'main/texcompress_s3tc.c', + 'main/texcompress_fxt1.c', + 'main/texenv.c', + 'main/texenvprogram.c', + 'main/texformat.c', + 'main/texgen.c', + 'main/texgetimage.c', + 'main/teximage.c', + 'main/texobj.c', + 'main/texparam.c', + 'main/texrender.c', + 'main/texstate.c', + 'main/texstore.c', + 'main/varray.c', + 'main/viewport.c', + 'main/vtxfmt.c', + ] + + math_sources = [ + 'math/m_debug_clip.c', + 'math/m_debug_norm.c', + 'math/m_debug_xform.c', + 'math/m_eval.c', + 'math/m_matrix.c', + 'math/m_translate.c', + 'math/m_vector.c', + 'math/m_xform.c', + ] + + vbo_sources = [ + 'vbo/vbo_context.c', + 'vbo/vbo_exec.c', + 'vbo/vbo_exec_api.c', + 'vbo/vbo_exec_array.c', + 'vbo/vbo_exec_draw.c', + 'vbo/vbo_exec_eval.c', + 'vbo/vbo_rebase.c', + 'vbo/vbo_split.c', + 'vbo/vbo_split_copy.c', + 'vbo/vbo_split_inplace.c', + 'vbo/vbo_save.c', + 'vbo/vbo_save_api.c', + 'vbo/vbo_save_draw.c', + 'vbo/vbo_save_loopback.c', + ] + + vf_sources = [ + 'vf/vf.c', + 'vf/vf_generic.c', + 'vf/vf_sse.c', + ] + + statetracker_sources = [ + 'state_tracker/st_atom.c', + 'state_tracker/st_atom_blend.c', + 'state_tracker/st_atom_clip.c', + 'state_tracker/st_atom_constbuf.c', + 'state_tracker/st_atom_depth.c', + 'state_tracker/st_atom_framebuffer.c', + 'state_tracker/st_atom_pixeltransfer.c', + 'state_tracker/st_atom_sampler.c', + 'state_tracker/st_atom_scissor.c', + 'state_tracker/st_atom_shader.c', + 'state_tracker/st_atom_rasterizer.c', + 'state_tracker/st_atom_stipple.c', + 'state_tracker/st_atom_texture.c', + 'state_tracker/st_atom_viewport.c', + 'state_tracker/st_cb_accum.c', + 'state_tracker/st_cb_bitmap.c', + 'state_tracker/st_cb_blit.c', + 'state_tracker/st_cb_bufferobjects.c', + 'state_tracker/st_cb_clear.c', + 'state_tracker/st_cb_flush.c', + 'state_tracker/st_cb_drawpixels.c', + 'state_tracker/st_cb_fbo.c', + 'state_tracker/st_cb_get.c', + 'state_tracker/st_cb_feedback.c', + 'state_tracker/st_cb_program.c', + 'state_tracker/st_cb_queryobj.c', + 'state_tracker/st_cb_rasterpos.c', + 'state_tracker/st_cb_readpixels.c', + 'state_tracker/st_cb_strings.c', + 'state_tracker/st_cb_texture.c', + 'state_tracker/st_cb_viewport.c', + 'state_tracker/st_context.c', + 'state_tracker/st_debug.c', + 'state_tracker/st_draw.c', + 'state_tracker/st_draw_feedback.c', + 'state_tracker/st_extensions.c', + 'state_tracker/st_format.c', + 'state_tracker/st_framebuffer.c', + 'state_tracker/st_gen_mipmap.c', + 'state_tracker/st_mesa_to_tgsi.c', + 'state_tracker/st_program.c', + 'state_tracker/st_texture.c', + ] + + shader_sources = [ + 'shader/arbprogparse.c', + 'shader/arbprogram.c', + 'shader/atifragshader.c', + 'shader/grammar/grammar_mesa.c', + 'shader/hash_table.c', + 'shader/lex.yy.c', + 'shader/nvfragparse.c', + 'shader/nvprogram.c', + 'shader/nvvertparse.c', + 'shader/program.c', + 'shader/program_parse.tab.c', + 'shader/program_parse_extra.c', + 'shader/prog_cache.c', + 'shader/prog_execute.c', + 'shader/prog_instruction.c', + 'shader/prog_noise.c', + 'shader/prog_optimize.c', + 'shader/prog_parameter.c', + 'shader/prog_parameter_layout.c', + 'shader/prog_print.c', + 'shader/prog_statevars.c', + 'shader/prog_uniform.c', + 'shader/programopt.c', + 'shader/symbol_table.c', + 'shader/shader_api.c', + ] + + slang_sources = [ + 'shader/slang/slang_builtin.c', + 'shader/slang/slang_codegen.c', + 'shader/slang/slang_compile.c', + 'shader/slang/slang_compile_function.c', + 'shader/slang/slang_compile_operation.c', + 'shader/slang/slang_compile_struct.c', + 'shader/slang/slang_compile_variable.c', + 'shader/slang/slang_emit.c', + 'shader/slang/slang_ir.c', + 'shader/slang/slang_label.c', + 'shader/slang/slang_link.c', + 'shader/slang/slang_log.c', + 'shader/slang/slang_mem.c', + 'shader/slang/slang_preprocess.c', + 'shader/slang/slang_print.c', + 'shader/slang/slang_simplify.c', + 'shader/slang/slang_storage.c', + 'shader/slang/slang_typeinfo.c', + 'shader/slang/slang_vartable.c', + 'shader/slang/slang_utility.c', + ] + + mesa_sources = ( + main_sources + + math_sources + + vbo_sources + + vf_sources + + statetracker_sources + + shader_sources + + slang_sources + ) + + glapi_sources = [ + 'main/dispatch.c', + 'glapi/glapi.c', + 'glapi/glapi_getproc.c', + 'glapi/glthread.c', + ] + + # + # Assembly sources + # + if gcc and env['machine'] == 'x86': + env.Append(CPPDEFINES = [ + 'USE_X86_ASM', + 'USE_MMX_ASM', + 'USE_3DNOW_ASM', + 'USE_SSE_ASM', + ]) + mesa_sources += [ + 'x86/common_x86.c', + 'x86/x86_xform.c', + 'x86/3dnow.c', + 'x86/sse.c', + 'x86/common_x86_asm.S', + 'x86/x86_xform2.S', + 'x86/x86_xform3.S', + 'x86/x86_xform4.S', + 'x86/x86_cliptest.S', + 'x86/mmx_blend.S', + 'x86/3dnow_xform1.S', + 'x86/3dnow_xform2.S', + 'x86/3dnow_xform3.S', + 'x86/3dnow_xform4.S', + 'x86/3dnow_normal.S', + 'x86/sse_xform1.S', + 'x86/sse_xform2.S', + 'x86/sse_xform3.S', + 'x86/sse_xform4.S', + 'x86/sse_normal.S', + 'x86/read_rgba_span_x86.S', + ] + glapi_sources += [ + 'x86/glapi_x86.S', + ] + elif gcc and env['machine'] == 'x86_64': + env.Append(CPPDEFINES = [ + 'USE_X86_64_ASM', + ]) + mesa_sources += [ + 'x86-64/x86-64.c', + 'x86-64/xform4.S', + ] + glapi_sources += [ + 'x86-64/glapi_x86-64.S' + ] + elif gcc and env['machine'] == 'ppc': + env.Append(CPPDEFINES = [ + 'USE_PPC_ASM', + 'USE_VMX_ASM', + ]) + mesa_sources += [ + 'ppc/common_ppc.c', + ] + glapi_sources += [ + ] + elif gcc and env['machine'] == 'sparc': + mesa_sources += [ + 'sparc/sparc.c', + 'sparc/clip.S', + 'sparc/norm.S', + 'sparc/xform.S', + ] + glapi_sources += [ + 'sparc/glapi_sparc.S' + ] + else: + pass + + # Generate matypes.h + if gcc and env['machine'] in ('x86', 'x86_64'): + # See http://www.scons.org/wiki/UsingCodeGenerators + gen_matypes = env.Program( + target = 'gen_matypes', + source = 'x86/gen_matypes.c', + ) + matypes = env.Command( + 'matypes.h', + gen_matypes, + gen_matypes[0].abspath + ' > $TARGET', + ) + # Add the dir containing the generated header (somewhere inside the + # build dir) to the include path + env.Append(CPPPATH = [matypes[0].dir]) + + # + # Libraries + # + + mesa = env.ConvenienceLibrary( + target = 'mesa', + source = mesa_sources, + ) + Export('mesa') + + if not dri: + glapi = env.ConvenienceLibrary( + target = 'glapi', + source = glapi_sources, + ) + Export('glapi') + diff --git a/mesalib/src/mesa/drivers/dri/common/xmlpool/gen_xmlpool.py b/mesalib/src/mesa/drivers/dri/common/xmlpool/gen_xmlpool.py new file mode 100644 index 000000000..7398c4cd0 --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/common/xmlpool/gen_xmlpool.py @@ -0,0 +1,191 @@ +#!/usr/bin/python + +import sys +import gettext +import re + +# List of supported languages +languages = sys.argv[1:] + +# Escape special characters in C strings +def escapeCString (s): + escapeSeqs = {'\a' : '\\a', '\b' : '\\b', '\f' : '\\f', '\n' : '\\n', + '\r' : '\\r', '\t' : '\\t', '\v' : '\\v', '\\' : '\\\\'} + # " -> '' is a hack. Quotes (") aren't possible in XML attributes. + # Better use Unicode characters for typographic quotes in option + # descriptions and translations. + i = 0 + r = '' + while i < len(s): + # Special case: escape double quote with \u201c or \u201d, depending + # on whether it's an open or close quote. This is needed because plain + # double quotes are not possible in XML attributes. + if s[i] == '"': + if i == len(s)-1 or s[i+1].isspace(): + # close quote + q = u'\u201c' + else: + # open quote + q = u'\u201d' + r = r + q + elif escapeSeqs.has_key(s[i]): + r = r + escapeSeqs[s[i]] + else: + r = r + s[i] + i = i + 1 + return r + +# Expand escape sequences in C strings (needed for gettext lookup) +def expandCString (s): + escapeSeqs = {'a' : '\a', 'b' : '\b', 'f' : '\f', 'n' : '\n', + 'r' : '\r', 't' : '\t', 'v' : '\v', + '"' : '"', '\\' : '\\'} + i = 0 + escape = False + hexa = False + octa = False + num = 0 + digits = 0 + r = '' + while i < len(s): + if not escape: + if s[i] == '\\': + escape = True + else: + r = r + s[i] + elif hexa: + if (s[i] >= '0' and s[i] <= '9') or \ + (s[i] >= 'a' and s[i] <= 'f') or \ + (s[i] >= 'A' and s[i] <= 'F'): + num = num * 16 + int(s[i],16) + digits = digits + 1 + else: + digits = 2 + if digits >= 2: + hexa = False + escape = False + r = r + chr(num) + elif octa: + if s[i] >= '0' and s[i] <= '7': + num = num * 8 + int(s[i],8) + digits = digits + 1 + else: + digits = 3 + if digits >= 3: + octa = False + escape = False + r = r + chr(num) + else: + if escapeSeqs.has_key(s[i]): + r = r + escapeSeqs[s[i]] + escape = False + elif s[i] >= '0' and s[i] <= '7': + octa = True + num = int(s[i],8) + if num <= 3: + digits = 1 + else: + digits = 2 + elif s[i] == 'x' or s[i] == 'X': + hexa = True + num = 0 + digits = 0 + else: + r = r + s[i] + escape = False + i = i + 1 + return r + +# Expand matches. The first match is always a DESC or DESC_BEGIN match. +# Subsequent matches are ENUM matches. +# +# DESC, DESC_BEGIN format: \1 \2= \3 \4=gettext(" \5= \6=") \7 +# ENUM format: \1 \2=gettext(" \3= \4=") \5 +def expandMatches (matches, translations, end=None): + assert len(matches) > 0 + nTranslations = len(translations) + i = 0 + # Expand the description+enums for all translations + for lang,trans in translations: + i = i + 1 + # Make sure that all but the last line of a simple description + # are extended with a backslash. + suffix = '' + if len(matches) == 1 and i < len(translations) and \ + not matches[0].expand (r'\7').endswith('\\'): + suffix = ' \\' + # Expand the description line. Need to use ugettext in order to allow + # non-ascii unicode chars in the original English descriptions. + text = escapeCString (trans.ugettext (unicode (expandCString ( + matches[0].expand (r'\5')), "utf-8"))).encode("utf-8") + print matches[0].expand (r'\1' + lang + r'\3"' + text + r'"\7') + suffix + # Expand any subsequent enum lines + for match in matches[1:]: + text = escapeCString (trans.ugettext (unicode (expandCString ( + match.expand (r'\3')), "utf-8"))).encode("utf-8") + print match.expand (r'\1"' + text + r'"\5') + + # Expand description end + if end: + print end, + +# Compile a list of translation classes to all supported languages. +# The first translation is always a NullTranslations. +translations = [("en", gettext.NullTranslations())] +for lang in languages: + try: + trans = gettext.translation ("options", ".", [lang]) + except IOError: + sys.stderr.write ("Warning: language '%s' not found.\n" % lang) + continue + translations.append ((lang, trans)) + +# Regular expressions: +reLibintl_h = re.compile (r'#\s*include\s*') +reDESC = re.compile (r'(\s*DRI_CONF_DESC\s*\(\s*)([a-z]+)(\s*,\s*)(gettext\s*\(\s*")(.*)("\s*\))(\s*\)[ \t]*\\?)$') +reDESC_BEGIN = re.compile (r'(\s*DRI_CONF_DESC_BEGIN\s*\(\s*)([a-z]+)(\s*,\s*)(gettext\s*\(\s*")(.*)("\s*\))(\s*\)[ \t]*\\?)$') +reENUM = re.compile (r'(\s*DRI_CONF_ENUM\s*\([^,]+,\s*)(gettext\s*\(\s*")(.*)("\s*\))(\s*\)[ \t]*\\?)$') +reDESC_END = re.compile (r'\s*DRI_CONF_DESC_END') + +# Print a header +print \ +"/***********************************************************************\n" \ +" *** THIS FILE IS GENERATED AUTOMATICALLY. DON'T EDIT! ***\n" \ +" ***********************************************************************/" + +# Process the options template and generate options.h with all +# translations. +template = file ("t_options.h", "r") +descMatches = [] +for line in template: + if len(descMatches) > 0: + matchENUM = reENUM .match (line) + matchDESC_END = reDESC_END.match (line) + if matchENUM: + descMatches.append (matchENUM) + elif matchDESC_END: + expandMatches (descMatches, translations, line) + descMatches = [] + else: + sys.stderr.write ( + "Warning: unexpected line inside description dropped:\n%s\n" \ + % line) + continue + if reLibintl_h.search (line): + # Ignore (comment out) #include + print "/* %s * commented out by gen_xmlpool.py */" % line + continue + matchDESC = reDESC .match (line) + matchDESC_BEGIN = reDESC_BEGIN.match (line) + if matchDESC: + assert len(descMatches) == 0 + expandMatches ([matchDESC], translations) + elif matchDESC_BEGIN: + assert len(descMatches) == 0 + descMatches = [matchDESC_BEGIN] + else: + print line, + +if len(descMatches) > 0: + sys.stderr.write ("Warning: unterminated description at end of file.\n") + expandMatches (descMatches, translations) diff --git a/mesalib/src/mesa/drivers/windows/fx/fx.rc b/mesalib/src/mesa/drivers/windows/fx/fx.rc new file mode 100644 index 000000000..f920b8768 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/fx/fx.rc @@ -0,0 +1,39 @@ +#include + +#define PRODNAME "Mesa 6.x" +#define CONTACTSTR "http://www.mesa3d.org" +#define HWSTR "3dfx Voodoo Graphics, Voodoo Rush, Voodoo^2, Voodoo Banshee, Velocity 100/200, Voodoo3, Voodoo4, Voodoo5" +#define COPYRIGHTSTR "Copyright \251 Brian E. Paul" + +#define VERSIONSTR "6.3.0.1" +#define MANVERSION 6 +#define MANREVISION 3 +#define BUILD_NUMBER 1 + +VS_VERSION_INFO VERSIONINFO + FILEVERSION MANVERSION, MANREVISION, 0, BUILD_NUMBER + PRODUCTVERSION MANVERSION, MANREVISION, 0, BUILD_NUMBER + FILEFLAGSMASK 0x0030003FL + + FILEOS VOS_DOS_WINDOWS32 + FILETYPE VFT_DRV + FILESUBTYPE VFT2_DRV_INSTALLABLE +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + BEGIN + VALUE "FileDescription", PRODNAME + VALUE "FileVersion", VERSIONSTR + VALUE "LegalCopyright", COPYRIGHTSTR + VALUE "ProductName", PRODNAME + VALUE "Graphics Subsystem", HWSTR + VALUE "Contact", CONTACTSTR + END + END + BLOCK "VarFileInfo" + BEGIN + /* the following line should be extended for localized versions */ + VALUE "Translation", 0x409, 1252 + END +END diff --git a/mesalib/src/mesa/drivers/windows/gdi/InitCritSections.cpp b/mesalib/src/mesa/drivers/windows/gdi/InitCritSections.cpp new file mode 100644 index 000000000..7145bffa5 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gdi/InitCritSections.cpp @@ -0,0 +1,32 @@ +#include "glapi.h" +#include "glThread.h" + +#ifdef WIN32_THREADS +extern "C" _glthread_Mutex OneTimeLock; +extern "C" _glthread_Mutex GenTexturesLock; + +extern "C" void FreeAllTSD(void); + +class _CriticalSectionInit +{ +public: + static _CriticalSectionInit m_inst; + + _CriticalSectionInit() + { + _glthread_INIT_MUTEX(OneTimeLock); + _glthread_INIT_MUTEX(GenTexturesLock); + } + + ~_CriticalSectionInit() + { + _glthread_DESTROY_MUTEX(OneTimeLock); + _glthread_DESTROY_MUTEX(GenTexturesLock); + FreeAllTSD(); + } +}; + +_CriticalSectionInit _CriticalSectionInit::m_inst; + + +#endif diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_driver_dx7.c b/mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_driver_dx7.c new file mode 100644 index 000000000..d5fa64280 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_driver_dx7.c @@ -0,0 +1,1196 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x/2000/XP/XBox (Win32) +* +* Description: Driver interface code to Mesa +* +****************************************************************************/ + +//#include +#include "dglcontext.h" +#include "ddlog.h" +#include "gld_dx7.h" + +#include "glheader.h" +#include "context.h" +#include "colormac.h" +#include "depth.h" +#include "extensions.h" +#include "macros.h" +#include "matrix.h" +// #include "mem.h" +//#include "mmath.h" +#include "mtypes.h" +#include "texformat.h" +#include "teximage.h" +#include "texstore.h" +#include "vbo/vbo.h" +#include "swrast_setup/swrast_setup.h" +#include "swrast_setup/ss_context.h" +#include "tnl/tnl.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" + +extern BOOL dglSwapBuffers(HDC hDC); + +// HACK: Hack the _33 member of the OpenGL perspective projection matrix +const float _fPersp_33 = 1.6f; + +//--------------------------------------------------------------------------- +// Internal functions +//--------------------------------------------------------------------------- + +void _gld_mesa_warning( + __GLcontext *gc, + char *str) +{ + // Intercept Mesa's internal warning mechanism + gldLogPrintf(GLDLOG_WARN, "Mesa warning: %s", str); +} + +//--------------------------------------------------------------------------- + +void _gld_mesa_fatal( + __GLcontext *gc, + char *str) +{ + // Intercept Mesa's internal fatal-message mechanism + gldLogPrintf(GLDLOG_CRITICAL, "Mesa FATAL: %s", str); + + // Mesa calls abort(0) here. + ddlogClose(); + exit(0); +} + +//--------------------------------------------------------------------------- + +D3DSTENCILOP _gldConvertStencilOp( + GLenum StencilOp) +{ + // Used by Stencil: pass, fail and zfail + + switch (StencilOp) { + case GL_KEEP: + return D3DSTENCILOP_KEEP; + case GL_ZERO: + return D3DSTENCILOP_ZERO; + case GL_REPLACE: + return D3DSTENCILOP_REPLACE; + case GL_INCR: + return D3DSTENCILOP_INCRSAT; + case GL_DECR: + return D3DSTENCILOP_DECRSAT; + case GL_INVERT: + return D3DSTENCILOP_INVERT; + case GL_INCR_WRAP_EXT: // GL_EXT_stencil_wrap + return D3DSTENCILOP_INCR; + case GL_DECR_WRAP_EXT: // GL_EXT_stencil_wrap + return D3DSTENCILOP_DECR; + } + +#ifdef _DEBUG + gldLogMessage(GLDLOG_ERROR, "_gldConvertStencilOp: Unknown StencilOp\n"); +#endif + + return D3DSTENCILOP_KEEP; +} + +//--------------------------------------------------------------------------- + +D3DCMPFUNC _gldConvertCompareFunc( + GLenum CmpFunc) +{ + // Used for Alpha func, depth func and stencil func. + + switch (CmpFunc) { + case GL_NEVER: + return D3DCMP_NEVER; + case GL_LESS: + return D3DCMP_LESS; + case GL_EQUAL: + return D3DCMP_EQUAL; + case GL_LEQUAL: + return D3DCMP_LESSEQUAL; + case GL_GREATER: + return D3DCMP_GREATER; + case GL_NOTEQUAL: + return D3DCMP_NOTEQUAL; + case GL_GEQUAL: + return D3DCMP_GREATEREQUAL; + case GL_ALWAYS: + return D3DCMP_ALWAYS; + }; + +#ifdef _DEBUG + gldLogMessage(GLDLOG_ERROR, "_gldConvertCompareFunc: Unknown CompareFunc\n"); +#endif + + return D3DCMP_ALWAYS; +} + +//--------------------------------------------------------------------------- + +D3DBLEND _gldConvertBlendFunc( + GLenum blend, + GLenum DefaultBlend) +{ + switch (blend) { + case GL_ZERO: + return D3DBLEND_ZERO; + case GL_ONE: + return D3DBLEND_ONE; + case GL_DST_COLOR: + return D3DBLEND_DESTCOLOR; + case GL_SRC_COLOR: + return D3DBLEND_SRCCOLOR; + case GL_ONE_MINUS_DST_COLOR: + return D3DBLEND_INVDESTCOLOR; + case GL_ONE_MINUS_SRC_COLOR: + return D3DBLEND_INVSRCCOLOR; + case GL_SRC_ALPHA: + return D3DBLEND_SRCALPHA; + case GL_ONE_MINUS_SRC_ALPHA: + return D3DBLEND_INVSRCALPHA; + case GL_DST_ALPHA: + return D3DBLEND_DESTALPHA; + case GL_ONE_MINUS_DST_ALPHA: + return D3DBLEND_INVDESTALPHA; + case GL_SRC_ALPHA_SATURATE: + return D3DBLEND_SRCALPHASAT; + } + +#ifdef _DEBUG + gldLogMessage(GLDLOG_ERROR, "_gldConvertBlendFunc: Unknown BlendFunc\n"); +#endif + + return DefaultBlend; +} + +//--------------------------------------------------------------------------- +// Misc. functions +//--------------------------------------------------------------------------- + +void gld_Noop_DX7( + GLcontext *ctx) +{ +#ifdef _DEBUG + gldLogMessage(GLDLOG_ERROR, "gld_Noop called!\n"); +#endif +} + +//--------------------------------------------------------------------------- + +void gld_Error_DX7( + GLcontext *ctx) +{ +#ifdef _DEBUG + // Quite useless. +// gldLogMessage(GLDLOG_ERROR, "ctx->Driver.Error called!\n"); +#endif +} + +//--------------------------------------------------------------------------- +// Required Mesa functions +//--------------------------------------------------------------------------- + +static GLboolean gld_set_draw_buffer_DX7( + GLcontext *ctx, + GLenum mode) +{ + (void) ctx; + if ((mode==GL_FRONT_LEFT) || (mode == GL_BACK_LEFT)) { + return GL_TRUE; + } + else { + return GL_FALSE; + } +} + +//--------------------------------------------------------------------------- + +static void gld_set_read_buffer_DX7( + GLcontext *ctx, + GLframebuffer *buffer, + GLenum mode) +{ + /* separate read buffer not supported */ +/* + ASSERT(buffer == ctx->DrawBuffer); + ASSERT(mode == GL_FRONT_LEFT); +*/ +} + +//--------------------------------------------------------------------------- + +void gld_Clear_DX7( + GLcontext *ctx, + GLbitfield mask, + GLboolean all, + GLint x, + GLint y, + GLint width, + GLint height) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); + + DWORD dwFlags = 0; + D3DCOLOR Color = 0; + float Z = 0.0f; + DWORD Stencil = 0; + D3DRECT d3dClearRect; + + // TODO: Colourmask + const GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask; + + if (!gld->pDev) + return; + + if (mask & (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT)) { + GLubyte col[4]; + CLAMPED_FLOAT_TO_UBYTE(col[0], ctx->Color.ClearColor[0]); + CLAMPED_FLOAT_TO_UBYTE(col[1], ctx->Color.ClearColor[1]); + CLAMPED_FLOAT_TO_UBYTE(col[2], ctx->Color.ClearColor[2]); + CLAMPED_FLOAT_TO_UBYTE(col[3], ctx->Color.ClearColor[3]); + dwFlags |= D3DCLEAR_TARGET; + Color = D3DCOLOR_RGBA(col[0], col[1], col[2], col[3]); +// ctx->Color.ClearColor[1], +// ctx->Color.ClearColor[2], +// ctx->Color.ClearColor[3]); + } + + if (mask & DD_DEPTH_BIT) { + // D3D7 will fail the Clear call if we try and clear a + // depth buffer and we haven't created one. + // Also, some apps try and clear a depth buffer, + // when a depth buffer hasn't been requested by the app. + if (ctx->Visual.depthBits == 0) { + mask &= ~DD_DEPTH_BIT; // Remove depth bit from mask + } else { + dwFlags |= D3DCLEAR_ZBUFFER; + Z = ctx->Depth.Clear; + } + } + + if (mask & DD_STENCIL_BIT) { + if (ctx->Visual.stencilBits == 0) { + // No stencil bits in depth buffer + mask &= ~DD_STENCIL_BIT; // Remove stencil bit from mask + } else { + dwFlags |= D3DCLEAR_STENCIL; + Stencil = ctx->Stencil.Clear; + } + } + + // Some apps do really weird things with the rect, such as Quake3. + if ((x < 0) || (y < 0) || (width <= 0) || (height <= 0)) { + all = GL_TRUE; + } + + if (!all) { + // Calculate clear subrect + d3dClearRect.x1 = x; + d3dClearRect.y1 = gldCtx->dwHeight - (y + height); + d3dClearRect.x2 = x + width; + d3dClearRect.y2 = d3dClearRect.y1 + height; + } + + // dwFlags will be zero if there's nothing to clear + if (dwFlags) { + _GLD_DX7_DEV(Clear( + gld->pDev, + all ? 0 : 1, + all ? NULL : &d3dClearRect, + dwFlags, + Color, Z, Stencil)); + } + + if (mask & DD_ACCUM_BIT) { + // Clear accumulation buffer + } +} + +//--------------------------------------------------------------------------- + +// Mesa 5: Parameter change +static void gld_buffer_size_DX7( +// GLcontext *ctx, + GLframebuffer *fb, + GLuint *width, + GLuint *height) +{ +// GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + + *width = fb->Width; // gldCtx->dwWidth; + *height = fb->Height; // gldCtx->dwHeight; +} + +//--------------------------------------------------------------------------- + +static void gld_Finish_DX7( + GLcontext *ctx) +{ +} + +//--------------------------------------------------------------------------- + +static void gld_Flush_DX7( + GLcontext *ctx) +{ + GLD_context *gld = GLD_GET_CONTEXT(ctx); + + // TODO: Detect apps that glFlush() then SwapBuffers() ? + + if (gld->EmulateSingle) { + // Emulating a single-buffered context. + // [Direct3D doesn't allow rendering to front buffer] + dglSwapBuffers(gld->hDC); + } +} + +//--------------------------------------------------------------------------- + +void gld_NEW_STENCIL( + GLcontext *ctx) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); + + // Two-sided stencil. New for Mesa 5 + const GLuint uiFace = 0UL; + + struct gl_stencil_attrib *pStencil = &ctx->Stencil; + + _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_STENCILENABLE, pStencil->Enabled ? TRUE : FALSE)); + if (pStencil->Enabled) { + _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_STENCILFUNC, _gldConvertCompareFunc(pStencil->Function[uiFace]))); + _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_STENCILREF, pStencil->Ref[uiFace])); + _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_STENCILMASK, pStencil->ValueMask[uiFace])); + _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_STENCILWRITEMASK, pStencil->WriteMask[uiFace])); + _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_STENCILFAIL, _gldConvertStencilOp(pStencil->FailFunc[uiFace]))); + _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_STENCILZFAIL, _gldConvertStencilOp(pStencil->ZFailFunc[uiFace]))); + _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_STENCILPASS, _gldConvertStencilOp(pStencil->ZPassFunc[uiFace]))); + } +} + +//--------------------------------------------------------------------------- + +void gld_NEW_COLOR( + GLcontext *ctx) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); + + DWORD dwFlags = 0; + D3DBLEND src; + D3DBLEND dest; + + // Alpha func + _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_ALPHAFUNC, _gldConvertCompareFunc(ctx->Color.AlphaFunc))); + _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_ALPHAREF, (DWORD)ctx->Color.AlphaRef)); + _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_ALPHATESTENABLE, ctx->Color.AlphaEnabled)); + + // Blend func + _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_ALPHABLENDENABLE, ctx->Color.BlendEnabled)); + src = _gldConvertBlendFunc(ctx->Color.BlendSrcRGB, GL_ONE); + dest = _gldConvertBlendFunc(ctx->Color.BlendDstRGB, GL_ZERO); + _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_SRCBLEND, src)); + _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_DESTBLEND, dest)); + +/* + // Color mask - unsupported by DX7 + if (ctx->Color.ColorMask[0]) dwFlags |= D3DCOLORWRITEENABLE_RED; + if (ctx->Color.ColorMask[1]) dwFlags |= D3DCOLORWRITEENABLE_GREEN; + if (ctx->Color.ColorMask[2]) dwFlags |= D3DCOLORWRITEENABLE_BLUE; + if (ctx->Color.ColorMask[3]) dwFlags |= D3DCOLORWRITEENABLE_ALPHA; + _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_COLORWRITEENABLE, dwFlags)); +*/ +} + +//--------------------------------------------------------------------------- + +void gld_NEW_DEPTH( + GLcontext *ctx) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); + + _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_ZENABLE, ctx->Depth.Test ? D3DZB_TRUE : D3DZB_FALSE)); + _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_ZFUNC, _gldConvertCompareFunc(ctx->Depth.Func))); + _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_ZWRITEENABLE, ctx->Depth.Mask ? TRUE : FALSE)); +} + +//--------------------------------------------------------------------------- + +void gld_NEW_POLYGON( + GLcontext *ctx) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); + + D3DFILLMODE d3dFillMode = D3DFILL_SOLID; + D3DCULL d3dCullMode = D3DCULL_NONE; + int iOffset = 0; + + // Fillmode + switch (ctx->Polygon.FrontMode) { + case GL_POINT: + d3dFillMode = D3DFILL_POINT; + break; + case GL_LINE: + d3dFillMode = D3DFILL_WIREFRAME; + break; + case GL_FILL: + d3dFillMode = D3DFILL_SOLID; + break; + } + _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_FILLMODE, d3dFillMode)); + + if (ctx->Polygon.CullFlag) { + switch (ctx->Polygon.CullFaceMode) { + case GL_BACK: + if (ctx->Polygon.FrontFace == GL_CCW) + d3dCullMode = D3DCULL_CW; + else + d3dCullMode = D3DCULL_CCW; + break; + case GL_FRONT: + if (ctx->Polygon.FrontFace == GL_CCW) + d3dCullMode = D3DCULL_CCW; + else + d3dCullMode = D3DCULL_CW; + break; + case GL_FRONT_AND_BACK: + d3dCullMode = D3DCULL_NONE; + break; + default: + break; + } + } else { + d3dCullMode = D3DCULL_NONE; + } +// d3dCullMode = D3DCULL_NONE; // TODO: DEBUGGING + _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_CULLMODE, d3dCullMode)); + + // Polygon offset + // ZBIAS ranges from 0 to 16 and can only move towards the viewer + // Mesa5: ctx->Polygon._OffsetAny removed + if (ctx->Polygon.OffsetFill) { + iOffset = (int)ctx->Polygon.OffsetUnits; + if (iOffset < 0) + iOffset = -iOffset; + else + iOffset = 0; // D3D can't push away + } + _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_ZBIAS, iOffset)); +} + +//--------------------------------------------------------------------------- + +void gld_NEW_FOG( + GLcontext *ctx) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); + + D3DCOLOR d3dFogColour; + D3DFOGMODE d3dFogMode = D3DFOG_LINEAR; + + // TODO: Fog is calculated seperately in the Mesa pipeline + _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_FOGENABLE, FALSE)); + return; + + // Fog enable + _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_FOGENABLE, ctx->Fog.Enabled)); + if (!ctx->Fog.Enabled) { + _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_FOGTABLEMODE, D3DFOG_NONE)); + _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_FOGVERTEXMODE, D3DFOG_NONE)); + return; // If disabled, don't bother setting any fog state + } + + // Fog colour + d3dFogColour = D3DCOLOR_COLORVALUE( ctx->Fog.Color[0], + ctx->Fog.Color[1], + ctx->Fog.Color[2], + ctx->Fog.Color[3]); + _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_FOGCOLOR, d3dFogColour)); + + // Fog density + _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_FOGDENSITY, *((DWORD*) (&ctx->Fog.Density)))); + + // Fog start + _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_FOGSTART, *((DWORD*) (&ctx->Fog.Start)))); + + // Fog end + _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_FOGEND, *((DWORD*) (&ctx->Fog.End)))); + + // Fog mode + switch (ctx->Fog.Mode) { + case GL_LINEAR: + d3dFogMode = D3DFOG_LINEAR; + break; + case GL_EXP: + d3dFogMode = D3DFOG_EXP; + break; + case GL_EXP2: + d3dFogMode = D3DFOG_EXP2; + break; + } + _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_FOGTABLEMODE, d3dFogMode)); + _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_FOGVERTEXMODE, D3DFOG_NONE)); +} + +//--------------------------------------------------------------------------- + +void gld_NEW_LIGHT( + GLcontext *ctx) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); + DWORD dwSpecularEnable; + + // Shademode + _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_SHADEMODE, (ctx->Light.ShadeModel == GL_SMOOTH) ? D3DSHADE_GOURAUD : D3DSHADE_FLAT)); + + // Separate specular colour + if (ctx->Light.Enabled) + dwSpecularEnable = (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) ? TRUE: FALSE; + else + dwSpecularEnable = FALSE; + _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_SPECULARENABLE, dwSpecularEnable)); +} + +//--------------------------------------------------------------------------- + +void gld_NEW_MODELVIEW( + GLcontext *ctx) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); + + D3DMATRIX m; + //GLfloat *pM = ctx->ModelView.m; + // Mesa5: Model-view is now a stack + GLfloat *pM = ctx->ModelviewMatrixStack.Top->m; + m._11 = pM[0]; + m._12 = pM[1]; + m._13 = pM[2]; + m._14 = pM[3]; + m._21 = pM[4]; + m._22 = pM[5]; + m._23 = pM[6]; + m._24 = pM[7]; + m._31 = pM[8]; + m._32 = pM[9]; + m._33 = pM[10]; + m._34 = pM[11]; + m._41 = pM[12]; + m._42 = pM[13]; + m._43 = pM[14]; + m._44 = pM[15]; +/* m[0][0] = pM[0]; + m[0][1] = pM[1]; + m[0][2] = pM[2]; + m[0][3] = pM[3]; + m[1][0] = pM[4]; + m[1][1] = pM[5]; + m[1][2] = pM[6]; + m[1][3] = pM[7]; + m[2][0] = pM[8]; + m[2][1] = pM[9]; + m[2][2] = pM[10]; + m[2][3] = pM[11]; + m[3][0] = pM[12]; + m[3][1] = pM[13]; + m[3][2] = pM[14]; + m[3][3] = pM[15];*/ + + gld->matModelView = m; +} + +//--------------------------------------------------------------------------- + +void gld_NEW_PROJECTION( + GLcontext *ctx) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); + + D3DMATRIX m; + //GLfloat *pM = ctx->ProjectionMatrix.m; + // Mesa 5: Now a stack + GLfloat *pM = ctx->ProjectionMatrixStack.Top->m; + m._11 = pM[0]; + m._12 = pM[1]; + m._13 = pM[2]; + m._14 = pM[3]; + + m._21 = pM[4]; + m._22 = pM[5]; + m._23 = pM[6]; + m._24 = pM[7]; + + m._31 = pM[8]; + m._32 = pM[9]; + m._33 = pM[10] / _fPersp_33; // / 1.6f; + m._34 = pM[11]; + + m._41 = pM[12]; + m._42 = pM[13]; + m._43 = pM[14] / 2.0f; + m._44 = pM[15]; + + gld->matProjection = m; +} + +//--------------------------------------------------------------------------- +/* +void gldFrustumHook_DX7( + GLdouble left, + GLdouble right, + GLdouble bottom, + GLdouble top, + GLdouble nearval, + GLdouble farval) +{ + GET_CURRENT_CONTEXT(ctx); + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); + + // Pass values on to Mesa first (in case we mess with them) + _mesa_Frustum(left, right, bottom, top, nearval, farval); + + _fPersp_33 = farval / (nearval - farval); + +// ddlogPrintf(GLDLOG_SYSTEM, "Frustum: %f", farval/nearval); +} + +//--------------------------------------------------------------------------- + +void gldOrthoHook_DX7( + GLdouble left, + GLdouble right, + GLdouble bottom, + GLdouble top, + GLdouble nearval, + GLdouble farval) +{ + GET_CURRENT_CONTEXT(ctx); + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); + + // Pass values on to Mesa first (in case we mess with them) + _mesa_Ortho(left, right, bottom, top, nearval, farval); + + _fPersp_33 = 1.6f; + +// ddlogPrintf(GLDLOG_SYSTEM, "Ortho: %f", farval/nearval); +} +*/ +//--------------------------------------------------------------------------- + +void gld_NEW_VIEWPORT( + GLcontext *ctx) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); + + D3DVIEWPORT7 d3dvp; +// GLint x, y; +// GLsizei w, h; + + // Set depth range + _GLD_DX7_DEV(GetViewport(gld->pDev, &d3dvp)); + // D3D can't do Quake1/Quake2 z-trick + if (ctx->Viewport.Near <= ctx->Viewport.Far) { + d3dvp.dvMinZ = ctx->Viewport.Near; + d3dvp.dvMaxZ = ctx->Viewport.Far; + } else { + d3dvp.dvMinZ = ctx->Viewport.Far; + d3dvp.dvMaxZ = ctx->Viewport.Near; + } +/* x = ctx->Viewport.X; + y = ctx->Viewport.Y; + w = ctx->Viewport.Width; + h = ctx->Viewport.Height; + if (x < 0) x = 0; + if (y < 0) y = 0; + if (w > gldCtx->dwWidth) w = gldCtx->dwWidth; + if (h > gldCtx->dwHeight) h = gldCtx->dwHeight; + // Ditto for D3D viewport dimensions + if (w+x > gldCtx->dwWidth) w = gldCtx->dwWidth-x; + if (h+y > gldCtx->dwHeight) h = gldCtx->dwHeight-y; + d3dvp.X = x; + d3dvp.Y = gldCtx->dwHeight - (y + h); + d3dvp.Width = w; + d3dvp.Height = h;*/ + _GLD_DX7_DEV(SetViewport(gld->pDev, &d3dvp)); + +// gld->fFlipWindowY = (float)gldCtx->dwHeight; +} + +//--------------------------------------------------------------------------- + +__inline BOOL _gldAnyEvalEnabled( + GLcontext *ctx) +{ + struct gl_eval_attrib *eval = &ctx->Eval; + + if ((eval->AutoNormal) || + (eval->Map1Color4) || + (eval->Map1Index) || + (eval->Map1Normal) || + (eval->Map1TextureCoord1) || + (eval->Map1TextureCoord2) || + (eval->Map1TextureCoord3) || + (eval->Map1TextureCoord4) || + (eval->Map1Vertex3) || + (eval->Map1Vertex4) || + (eval->Map2Color4) || + (eval->Map2Index) || + (eval->Map2Normal) || + (eval->Map2TextureCoord1) || + (eval->Map2TextureCoord2) || + (eval->Map2TextureCoord3) || + (eval->Map2TextureCoord4) || + (eval->Map2Vertex3) || + (eval->Map2Vertex4) + ) + return TRUE; + + return FALSE; +} + +//--------------------------------------------------------------------------- + +BOOL _gldChooseInternalPipeline( + GLcontext *ctx, + GLD_driver_dx7 *gld) +{ +// return TRUE; // DEBUGGING: ALWAYS USE MESA +// return FALSE; // DEBUGGING: ALWAYS USE D3D + + if ((glb.dwTnL == GLDS_TNL_MESA) || (gld->bHasHWTnL == FALSE)) + { + gld->PipelineUsage.qwMesa.QuadPart++; + return TRUE; // Force Mesa TnL + } + + if ((ctx->Light.Enabled) || + (1) || + (ctx->Texture._TexGenEnabled) || + (ctx->Texture._TexMatEnabled) || +// (ctx->Transform._AnyClip) || + (ctx->Scissor.Enabled) || + _gldAnyEvalEnabled(ctx) // Put this last so we can early-out + ) + { + gld->PipelineUsage.qwMesa.QuadPart++; + return TRUE; + } + + gld->PipelineUsage.qwD3DFVF.QuadPart++; + return FALSE; + +/* // Force Mesa pipeline? + if (glb.dwTnL == GLDS_TNL_MESA) { + gld->PipelineUsage.dwMesa.QuadPart++; + return GLD_PIPELINE_MESA; + } + + // Test for functionality not exposed in the D3D pathways + if ((ctx->Texture._GenFlags)) { + gld->PipelineUsage.dwMesa.QuadPart++; + return GLD_PIPELINE_MESA; + } + + // Now decide if vertex shader can be used. + // If two sided lighting is enabled then we must either + // use Mesa TnL or the vertex shader + if (ctx->_TriangleCaps & DD_TRI_LIGHT_TWOSIDE) { + if (gld->VStwosidelight.hShader && !ctx->Fog.Enabled) { + // Use Vertex Shader + gld->PipelineUsage.dwD3D2SVS.QuadPart++; + return GLD_PIPELINE_D3D_VS_TWOSIDE; + } else { + // Use Mesa TnL + gld->PipelineUsage.dwMesa.QuadPart++; + return GLD_PIPELINE_MESA; + } + } + + // Must be D3D fixed-function pipeline + gld->PipelineUsage.dwD3DFVF.QuadPart++; + return GLD_PIPELINE_D3D_FVF; +*/ +} + +//--------------------------------------------------------------------------- + +void gld_update_state_DX7( + GLcontext *ctx, + GLuint new_state) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLD_pb_dx7 *gldPB; + + if (!gld || !gld->pDev) + return; + + _swsetup_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); + _tnl_InvalidateState( ctx, new_state ); + + // SetupIndex will be used in the pipelines for choosing setup function + if ((ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE | DD_SEPARATE_SPECULAR)) || + (ctx->Fog.Enabled)) + { + if (ctx->_TriangleCaps & DD_FLATSHADE) + gld->iSetupFunc = GLD_SI_FLAT_EXTRAS; + else + gld->iSetupFunc = GLD_SI_SMOOTH_EXTRAS; + } else { + if (ctx->_TriangleCaps & DD_FLATSHADE) + gld->iSetupFunc = GLD_SI_FLAT; // Setup flat shade + texture + else + gld->iSetupFunc = GLD_SI_SMOOTH; // Setup smooth shade + texture + } + + gld->bUseMesaTnL = _gldChooseInternalPipeline(ctx, gld); + if (gld->bUseMesaTnL) { + gldPB = &gld->PB2d; + // DX7 Does not implement D3DRS_SOFTWAREVERTEXPROCESSING +// _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_SOFTWAREVERTEXPROCESSING, TRUE)); + _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_CLIPPING, FALSE)); +// _GLD_DX7_DEV(SetVertexShader(gld->pDev, gldPB->dwFVF)); + } else { + gldPB = &gld->PB3d; + _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_CLIPPING, TRUE)); +// if (gld->TnLPipeline == GLD_PIPELINE_D3D_VS_TWOSIDE) { +// _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_SOFTWAREVERTEXPROCESSING, !gld->VStwosidelight.bHardware)); +// _GLD_DX7_DEV(SetVertexShader(gld->pDev, gld->VStwosidelight.hShader)); +// } else { + // DX7 Does not implement D3DRS_SOFTWAREVERTEXPROCESSING +// _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_SOFTWAREVERTEXPROCESSING, !gld->bHasHWTnL)); +// _GLD_DX7_DEV(SetVertexShader(gld->pDev, gldPB->dwFVF)); +// } + } + +#define _GLD_TEST_STATE(a) \ + if (new_state & (a)) { \ + gld##a(ctx); \ + new_state &= ~(a); \ + } + +#define _GLD_TEST_STATE_DX7(a) \ + if (new_state & (a)) { \ + gld##a##_DX7(ctx); \ + new_state &= ~(a); \ + } + +#define _GLD_IGNORE_STATE(a) new_state &= ~(a); + +// if (!gld->bUseMesaTnL) { + // Not required if Mesa is doing the TnL. + // Problem: If gld->bUseMesaTnL is TRUE when these are signaled, + // then we'll miss updating the D3D TnL pipeline. + // Therefore, don't test for gld->bUseMesaTnL + _GLD_TEST_STATE(_NEW_MODELVIEW); + _GLD_TEST_STATE(_NEW_PROJECTION); +// } + + _GLD_TEST_STATE_DX7(_NEW_TEXTURE); // extern, so guard with _DX7 + _GLD_TEST_STATE(_NEW_COLOR); + _GLD_TEST_STATE(_NEW_DEPTH); + _GLD_TEST_STATE(_NEW_POLYGON); + _GLD_TEST_STATE(_NEW_STENCIL); + _GLD_TEST_STATE(_NEW_FOG); + _GLD_TEST_STATE(_NEW_LIGHT); + _GLD_TEST_STATE(_NEW_VIEWPORT); + + _GLD_IGNORE_STATE(_NEW_TRANSFORM); + + +// Stubs for future use. +/* _GLD_TEST_STATE(_NEW_TEXTURE_MATRIX); + _GLD_TEST_STATE(_NEW_COLOR_MATRIX); + _GLD_TEST_STATE(_NEW_ACCUM); + _GLD_TEST_STATE(_NEW_EVAL); + _GLD_TEST_STATE(_NEW_HINT); + _GLD_TEST_STATE(_NEW_LINE); + _GLD_TEST_STATE(_NEW_PIXEL); + _GLD_TEST_STATE(_NEW_POINT); + _GLD_TEST_STATE(_NEW_POLYGONSTIPPLE); + _GLD_TEST_STATE(_NEW_SCISSOR); + _GLD_TEST_STATE(_NEW_PACKUNPACK); + _GLD_TEST_STATE(_NEW_ARRAY); + _GLD_TEST_STATE(_NEW_RENDERMODE); + _GLD_TEST_STATE(_NEW_BUFFERS); + _GLD_TEST_STATE(_NEW_MULTISAMPLE); +*/ + +// For debugging. +#if 0 +#define _GLD_TEST_UNHANDLED_STATE(a) \ + if (new_state & (a)) { \ + gldLogMessage(GLDLOG_ERROR, "Unhandled " #a "\n"); \ + } + _GLD_TEST_UNHANDLED_STATE(_NEW_TEXTURE_MATRIX); + _GLD_TEST_UNHANDLED_STATE(_NEW_COLOR_MATRIX); + _GLD_TEST_UNHANDLED_STATE(_NEW_ACCUM); + _GLD_TEST_UNHANDLED_STATE(_NEW_EVAL); + _GLD_TEST_UNHANDLED_STATE(_NEW_HINT); + _GLD_TEST_UNHANDLED_STATE(_NEW_LINE); + _GLD_TEST_UNHANDLED_STATE(_NEW_PIXEL); + _GLD_TEST_UNHANDLED_STATE(_NEW_POINT); + _GLD_TEST_UNHANDLED_STATE(_NEW_POLYGONSTIPPLE); + _GLD_TEST_UNHANDLED_STATE(_NEW_SCISSOR); + _GLD_TEST_UNHANDLED_STATE(_NEW_PACKUNPACK); + _GLD_TEST_UNHANDLED_STATE(_NEW_ARRAY); + _GLD_TEST_UNHANDLED_STATE(_NEW_RENDERMODE); + _GLD_TEST_UNHANDLED_STATE(_NEW_BUFFERS); + _GLD_TEST_UNHANDLED_STATE(_NEW_MULTISAMPLE); +#undef _GLD_UNHANDLED_STATE +#endif + +#undef _GLD_TEST_STATE +} + +//--------------------------------------------------------------------------- +// Viewport +//--------------------------------------------------------------------------- + +void gld_Viewport_DX7( + GLcontext *ctx, + GLint x, + GLint y, + GLsizei w, + GLsizei h) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); + + D3DVIEWPORT7 d3dvp; + + if (!gld || !gld->pDev) + return; + + // This is a hack. When the app is minimized, Mesa passes + // w=1 and h=1 for viewport dimensions. Without this test + // we get a GPF in gld_wgl_resize_buffers(). + if ((w==1) && (h==1)) + return; + + // Call ResizeBuffersMESA. This function will early-out + // if no resize is needed. + //ctx->Driver.ResizeBuffersMESA(ctx); + // Mesa 5: Changed parameters + ctx->Driver.ResizeBuffers(gldCtx->glBuffer); + +#if 0 + ddlogPrintf(GLDLOG_SYSTEM, ">> Viewport x=%d y=%d w=%d h=%d", x,y,w,h); +#endif + + // ** D3D viewport must not be outside the render target surface ** + // Sanity check the GL viewport dimensions + if (x < 0) x = 0; + if (y < 0) y = 0; + if (w > gldCtx->dwWidth) w = gldCtx->dwWidth; + if (h > gldCtx->dwHeight) h = gldCtx->dwHeight; + // Ditto for D3D viewport dimensions + if (w+x > gldCtx->dwWidth) w = gldCtx->dwWidth-x; + if (h+y > gldCtx->dwHeight) h = gldCtx->dwHeight-y; + + d3dvp.dwX = x; + d3dvp.dwY = gldCtx->dwHeight - (y + h); + d3dvp.dwWidth = w; + d3dvp.dwHeight = h; + if (ctx->Viewport.Near <= ctx->Viewport.Far) { + d3dvp.dvMinZ = ctx->Viewport.Near; + d3dvp.dvMaxZ = ctx->Viewport.Far; + } else { + d3dvp.dvMinZ = ctx->Viewport.Far; + d3dvp.dvMaxZ = ctx->Viewport.Near; + } + + // TODO: DEBUGGING +// d3dvp.MinZ = 0.0f; +// d3dvp.MaxZ = 1.0f; + + _GLD_DX7_DEV(SetViewport(gld->pDev, &d3dvp)); + +} + +//--------------------------------------------------------------------------- + +extern BOOL dglWglResizeBuffers(GLcontext *ctx, BOOL bDefaultDriver); + +// Mesa 5: Parameter change +void gldResizeBuffers_DX7( +// GLcontext *ctx) + GLframebuffer *fb) +{ + GET_CURRENT_CONTEXT(ctx); + dglWglResizeBuffers(ctx, TRUE); +} + +//--------------------------------------------------------------------------- +#ifdef _DEBUG +// This is only for debugging. +// To use, plug into ctx->Driver.Enable pointer below. +void gld_Enable( + GLcontext *ctx, + GLenum e, + GLboolean b) +{ + char buf[1024]; + sprintf(buf, "Enable: %s (%s)\n", _mesa_lookup_enum_by_nr(e), b?"TRUE":"FALSE"); + ddlogMessage(DDLOG_SYSTEM, buf); +} +#endif +//--------------------------------------------------------------------------- +// Driver pointer setup +//--------------------------------------------------------------------------- + +extern const GLubyte* _gldGetStringGeneric(GLcontext*, GLenum); + +void gldSetupDriverPointers_DX7( + GLcontext *ctx) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); + + TNLcontext *tnl = TNL_CONTEXT(ctx); + + // Mandatory functions + ctx->Driver.GetString = _gldGetStringGeneric; + ctx->Driver.UpdateState = gld_update_state_DX7; + ctx->Driver.Clear = gld_Clear_DX7; + ctx->Driver.DrawBuffer = gld_set_draw_buffer_DX7; + ctx->Driver.GetBufferSize = gld_buffer_size_DX7; + ctx->Driver.Finish = gld_Finish_DX7; + ctx->Driver.Flush = gld_Flush_DX7; + ctx->Driver.Error = gld_Error_DX7; + + // Hardware accumulation buffer + ctx->Driver.Accum = NULL; // TODO: gld_Accum; + + // Bitmap functions + ctx->Driver.CopyPixels = gld_CopyPixels_DX7; + ctx->Driver.DrawPixels = gld_DrawPixels_DX7; + ctx->Driver.ReadPixels = gld_ReadPixels_DX7; + ctx->Driver.Bitmap = gld_Bitmap_DX7; + + // Buffer resize + ctx->Driver.ResizeBuffers = gldResizeBuffers_DX7; + + // Texture image functions + ctx->Driver.ChooseTextureFormat = gld_ChooseTextureFormat_DX7; + ctx->Driver.TexImage1D = gld_TexImage1D_DX7; + ctx->Driver.TexImage2D = gld_TexImage2D_DX7; + ctx->Driver.TexImage3D = _mesa_store_teximage3d; + ctx->Driver.TexSubImage1D = gld_TexSubImage1D_DX7; + ctx->Driver.TexSubImage2D = gld_TexSubImage2D_DX7; + ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d; + + ctx->Driver.CopyTexImage1D = gldCopyTexImage1D_DX7; //NULL; + ctx->Driver.CopyTexImage2D = gldCopyTexImage2D_DX7; //NULL; + ctx->Driver.CopyTexSubImage1D = gldCopyTexSubImage1D_DX7; //NULL; + ctx->Driver.CopyTexSubImage2D = gldCopyTexSubImage2D_DX7; //NULL; + ctx->Driver.CopyTexSubImage3D = gldCopyTexSubImage3D_DX7; + ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage; + + // Texture object functions + ctx->Driver.BindTexture = NULL; + ctx->Driver.NewTextureObject = NULL; // Not yet implemented by Mesa!; + ctx->Driver.DeleteTexture = gld_DeleteTexture_DX7; + ctx->Driver.PrioritizeTexture = NULL; + + // Imaging functionality + ctx->Driver.CopyColorTable = NULL; + ctx->Driver.CopyColorSubTable = NULL; + ctx->Driver.CopyConvolutionFilter1D = NULL; + ctx->Driver.CopyConvolutionFilter2D = NULL; + + // State changing functions + ctx->Driver.AlphaFunc = NULL; //gld_AlphaFunc; + ctx->Driver.BlendFuncSeparate = NULL; //gld_BlendFunc; + ctx->Driver.ClearColor = NULL; //gld_ClearColor; + ctx->Driver.ClearDepth = NULL; //gld_ClearDepth; + ctx->Driver.ClearStencil = NULL; //gld_ClearStencil; + ctx->Driver.ColorMask = NULL; //gld_ColorMask; + ctx->Driver.CullFace = NULL; //gld_CullFace; + ctx->Driver.ClipPlane = NULL; //gld_ClipPlane; + ctx->Driver.FrontFace = NULL; //gld_FrontFace; + ctx->Driver.DepthFunc = NULL; //gld_DepthFunc; + ctx->Driver.DepthMask = NULL; //gld_DepthMask; + ctx->Driver.DepthRange = NULL; + ctx->Driver.Enable = NULL; //gld_Enable; + ctx->Driver.Fogfv = NULL; //gld_Fogfv; + ctx->Driver.Hint = NULL; //gld_Hint; + ctx->Driver.Lightfv = NULL; //gld_Lightfv; + ctx->Driver.LightModelfv = NULL; //gld_LightModelfv; + ctx->Driver.LineStipple = NULL; //gld_LineStipple; + ctx->Driver.LineWidth = NULL; //gld_LineWidth; + ctx->Driver.LogicOpcode = NULL; //gld_LogicOpcode; + ctx->Driver.PointParameterfv = NULL; //gld_PointParameterfv; + ctx->Driver.PointSize = NULL; //gld_PointSize; + ctx->Driver.PolygonMode = NULL; //gld_PolygonMode; + ctx->Driver.PolygonOffset = NULL; //gld_PolygonOffset; + ctx->Driver.PolygonStipple = NULL; //gld_PolygonStipple; + ctx->Driver.RenderMode = NULL; //gld_RenderMode; + ctx->Driver.Scissor = NULL; //gld_Scissor; + ctx->Driver.ShadeModel = NULL; //gld_ShadeModel; + ctx->Driver.StencilFunc = NULL; //gld_StencilFunc; + ctx->Driver.StencilMask = NULL; //gld_StencilMask; + ctx->Driver.StencilOp = NULL; //gld_StencilOp; + ctx->Driver.TexGen = NULL; //gld_TexGen; + ctx->Driver.TexEnv = NULL; + ctx->Driver.TexParameter = NULL; + ctx->Driver.TextureMatrix = NULL; //gld_TextureMatrix; + ctx->Driver.Viewport = gld_Viewport_DX7; + + _swsetup_Wakeup(ctx); + + tnl->Driver.RunPipeline = _tnl_run_pipeline; + tnl->Driver.Render.ResetLineStipple = gld_ResetLineStipple_DX7; + tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon; + tnl->Driver.Render.ClippedLine = _tnl_RenderClippedLine; + + // Hook into glFrustum() and glOrtho() +// ctx->Exec->Frustum = gldFrustumHook_DX7; +// ctx->Exec->Ortho = gldOrthoHook_DX7; + +} + +//--------------------------------------------------------------------------- diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_dx7.h b/mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_dx7.h new file mode 100644 index 000000000..b5a491e41 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_dx7.h @@ -0,0 +1,292 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x/2000/XP/XBox (Win32) +* +* Description: GLDirect Direct3D 7.0a header file +* +****************************************************************************/ + +#ifndef _GLD_DX7_H +#define _GLD_DX7_H + +//--------------------------------------------------------------------------- +// Windows includes +//--------------------------------------------------------------------------- + +#define DIRECTDRAW_VERSION 0x0700 +#define DIRECT3D_VERSION 0x0700 +#include +#include + +// Typedef for obtaining function from d3d7.dll +//typedef IDirect3D7* (WINAPI *FNDIRECT3DCREATE7) (UINT); + + +//--------------------------------------------------------------------------- +// Defines +//--------------------------------------------------------------------------- + +#ifdef _DEBUG +// Debug build tests the return value of D3D calls +#define _GLD_TEST_HRESULT(h) \ +{ \ + HRESULT _hr = (h); \ + if (FAILED(_hr)) { \ + gldLogError(GLDLOG_ERROR, #h, _hr); \ + } \ +} +#define _GLD_DX7(func) _GLD_TEST_HRESULT(IDirect3D7_##func##) +#define _GLD_DX7_DEV(func) _GLD_TEST_HRESULT(IDirect3DDevice7_##func##) +#define _GLD_DX7_VB(func) _GLD_TEST_HRESULT(IDirect3DVertexBuffer7_##func##) +#define _GLD_DX7_TEX(func) _GLD_TEST_HRESULT(IDirectDrawSurface7_##func##) +#else +#define _GLD_DX7(func) IDirect3D7_##func +#define _GLD_DX7_DEV(func) IDirect3DDevice7_##func +#define _GLD_DX7_VB(func) IDirect3DVertexBuffer7_##func +#define _GLD_DX7_TEX(func) IDirectDrawSurface7_##func +#endif + +#define SAFE_RELEASE(p) \ +{ \ + if (p) { \ + (p)->lpVtbl->Release(p); \ + (p) = NULL; \ + } \ +} + +#define SAFE_RELEASE_VB7(p) \ +{ \ + if (p) { \ + IDirect3DVertexBuffer7_Release((p)); \ + (p) = NULL; \ + } \ +} + +#define SAFE_RELEASE_SURFACE7(p) \ +{ \ + if (p) { \ + IDirectDrawSurface7_Release((p)); \ + (p) = NULL; \ + } \ +} + +// Emulate some DX8 defines +#define D3DCOLOR_ARGB(a,r,g,b) ((D3DCOLOR)((((a)&0xff)<<24)|(((r)&0xff)<<16)|(((g)&0xff)<<8)|((b)&0xff))) +#define D3DCOLOR_RGBA(r,g,b,a) D3DCOLOR_ARGB(a,r,g,b) +#define D3DCOLOR_COLORVALUE(r,g,b,a) D3DCOLOR_RGBA((DWORD)((r)*255.f),(DWORD)((g)*255.f),(DWORD)((b)*255.f),(DWORD)((a)*255.f)) + + +// Setup index. +enum { + GLD_SI_FLAT = 0, + GLD_SI_SMOOTH = 1, + GLD_SI_FLAT_EXTRAS = 2, + GLD_SI_SMOOTH_EXTRAS = 3, +}; + +//--------------------------------------------------------------------------- +// Vertex definitions for Fixed-Function pipeline +//--------------------------------------------------------------------------- + +// +// NOTE: If the number of texture units is altered then most of +// the texture code will need to be revised. +// + +#define GLD_MAX_TEXTURE_UNITS_DX7 2 + +// +// 2D vertex transformed by Mesa +// +#define GLD_FVF_2D_VERTEX ( D3DFVF_XYZRHW | \ + D3DFVF_DIFFUSE | \ + D3DFVF_SPECULAR | \ + D3DFVF_TEX2) +typedef struct { + FLOAT x, y; // 2D raster coords + FLOAT sz; // Screen Z (depth) + FLOAT rhw; // Reciprocal homogenous W + DWORD diffuse; // Diffuse colour + DWORD specular; // For separate-specular support + FLOAT t0_u, t0_v; // 1st set of texture coords + FLOAT t1_u, t1_v; // 2nd set of texture coords +} GLD_2D_VERTEX; + + +// +// 3D vertex transformed by Direct3D +// +#define GLD_FVF_3D_VERTEX ( D3DFVF_XYZ | \ + D3DFVF_DIFFUSE | \ + D3DFVF_TEX2) + +typedef struct { + D3DXVECTOR3 Position; // XYZ Vector in object space + D3DCOLOR Diffuse; // Diffuse colour + D3DXVECTOR2 TexUnit0; // Texture unit 0 + D3DXVECTOR2 TexUnit1; // Texture unit 1 +} GLD_3D_VERTEX; + +//--------------------------------------------------------------------------- +// Structs +//--------------------------------------------------------------------------- + +// This keeps a count of how many times we choose each individual internal +// pathway. Useful for seeing if a certain pathway was ever used by an app, and +// how much each pathway is biased. +// Zero the members at context creation and dump stats at context deletion. +typedef struct { + // Note: DWORD is probably too small + ULARGE_INTEGER qwMesa; // Mesa TnL pipeline + ULARGE_INTEGER qwD3DFVF; // Direct3D Fixed-Function pipeline +} GLD_pipeline_usage; + +// GLDirect Primitive Buffer (points, lines, triangles and quads) +typedef struct { + // Data for IDirect3D7::CreateVertexBuffer() + DWORD dwStride; // Stride of vertex + DWORD dwCreateFlags; // Create flags + DWORD dwFVF; // Direct3D Flexible Vertex Format + + IDirect3DVertexBuffer7 *pVB; // Holds points, lines, tris and quads. + + // Point list is assumed to be at start of buffer + DWORD iFirstLine; // Index of start of line list + DWORD iFirstTriangle; // Index of start of triangle list + + BYTE *pPoints; // Pointer to next free point + BYTE *pLines; // Pointer to next free line + BYTE *pTriangles; // Pointer to next free triangle + + DWORD nPoints; // Number of points ready to render + DWORD nLines; // Number of lines ready to render + DWORD nTriangles; // Number of triangles ready to render +} GLD_pb_dx7; + +// GLDirect DX7 driver data +typedef struct { + // GLDirect vars + BOOL bDoublebuffer; // Doublebuffer (otherwise single-buffered) + BOOL bDepthStencil; // Depth buffer needed (stencil optional) + D3DX_SURFACEFORMAT RenderFormat; // Format of back/front buffer + D3DX_SURFACEFORMAT DepthFormat; // Format of depth/stencil + + // Direct3D vars + DDCAPS ddCaps; + D3DDEVICEDESC7 d3dCaps; + BOOL bHasHWTnL; // Device has Hardware Transform/Light? + ID3DXContext *pD3DXContext; // Base D3DX context + IDirectDraw7 *pDD; // DirectDraw7 interface + IDirect3D7 *pD3D; // Base Direct3D7 interface + IDirect3DDevice7 *pDev; // Direct3D7 Device interface + GLD_pb_dx7 PB2d; // Vertices transformed by Mesa + GLD_pb_dx7 PB3d; // Vertices transformed by Direct3D + D3DPRIMITIVETYPE d3dpt; // Current Direct3D primitive type + D3DMATRIX matProjection; // Projection matrix for D3D TnL + D3DMATRIX matModelView; // Model/View matrix for D3D TnL + int iSetupFunc; // Which setup functions to use + BOOL bUseMesaTnL; // Whether to use Mesa or D3D for TnL + + GLD_pipeline_usage PipelineUsage; +} GLD_driver_dx7; + +#define GLD_GET_DX7_DRIVER(c) (GLD_driver_dx7*)(c)->glPriv + +//--------------------------------------------------------------------------- +// Function prototypes +//--------------------------------------------------------------------------- + +PROC gldGetProcAddress_DX7(LPCSTR a); +void gldEnableExtensions_DX7(GLcontext *ctx); +void gldInstallPipeline_DX7(GLcontext *ctx); +void gldSetupDriverPointers_DX7(GLcontext *ctx); +void gldResizeBuffers_DX7(GLframebuffer *fb); + + +// Texture functions + +void gldCopyTexImage1D_DX7(GLcontext *ctx, GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border); +void gldCopyTexImage2D_DX7(GLcontext *ctx, GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +void gldCopyTexSubImage1D_DX7(GLcontext *ctx, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width ); +void gldCopyTexSubImage2D_DX7(GLcontext *ctx, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height ); +void gldCopyTexSubImage3D_DX7(GLcontext *ctx, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height ); + +void gld_NEW_TEXTURE_DX7(GLcontext *ctx); +void gld_DrawPixels_DX7(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, const struct gl_pixelstore_attrib *unpack, const GLvoid *pixels); +void gld_ReadPixels_DX7(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, const struct gl_pixelstore_attrib *unpack, GLvoid *dest); +void gld_CopyPixels_DX7(GLcontext *ctx, GLint srcx, GLint srcy, GLsizei width, GLsizei height, GLint dstx, GLint dsty, GLenum type); +void gld_Bitmap_DX7(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, const struct gl_pixelstore_attrib *unpack, const GLubyte *bitmap); +const struct gl_texture_format* gld_ChooseTextureFormat_DX7(GLcontext *ctx, GLint internalFormat, GLenum srcFormat, GLenum srcType); +void gld_TexImage2D_DX7(GLcontext *ctx, GLenum target, GLint level, GLint internalFormat, GLint width, GLint height, GLint border, GLenum format, GLenum type, const GLvoid *pixels, const struct gl_pixelstore_attrib *packing, struct gl_texture_object *tObj, struct gl_texture_image *texImage); +void gld_TexImage1D_DX7(GLcontext *ctx, GLenum target, GLint level, GLint internalFormat, GLint width, GLint border, GLenum format, GLenum type, const GLvoid *pixels, const struct gl_pixelstore_attrib *packing, struct gl_texture_object *texObj, struct gl_texture_image *texImage ); +void gld_TexSubImage2D_DX7( GLcontext *ctx, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels, const struct gl_pixelstore_attrib *packing, struct gl_texture_object *texObj, struct gl_texture_image *texImage ); +void gld_TexSubImage1D_DX7(GLcontext *ctx, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels, const struct gl_pixelstore_attrib *packing, struct gl_texture_object *texObj, struct gl_texture_image *texImage); +void gld_DeleteTexture_DX7(GLcontext *ctx, struct gl_texture_object *tObj); +void gld_ResetLineStipple_DX7(GLcontext *ctx); + +// 2D primitive functions + +void gld_Points2D_DX7(GLcontext *ctx, GLuint first, GLuint last); + +void gld_Line2DFlat_DX7(GLcontext *ctx, GLuint v0, GLuint v1); +void gld_Line2DSmooth_DX7(GLcontext *ctx, GLuint v0, GLuint v1); + +void gld_Triangle2DFlat_DX7(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2); +void gld_Triangle2DSmooth_DX7(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2); +void gld_Triangle2DFlatExtras_DX7(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2); +void gld_Triangle2DSmoothExtras_DX7(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2); + +void gld_Quad2DFlat_DX7(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +void gld_Quad2DSmooth_DX7(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +void gld_Quad2DFlatExtras_DX7(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +void gld_Quad2DSmoothExtras_DX7(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3); + +// 3D primitive functions + +void gld_Points3D_DX7(GLcontext *ctx, GLuint first, GLuint last); +void gld_Line3DFlat_DX7(GLcontext *ctx, GLuint v0, GLuint v1); +void gld_Triangle3DFlat_DX7(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2); +void gld_Quad3DFlat_DX7(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +void gld_Line3DSmooth_DX7(GLcontext *ctx, GLuint v0, GLuint v1); +void gld_Triangle3DSmooth_DX7(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2); +void gld_Quad3DSmooth_DX7(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3); + +// Primitive functions for Two-sided-lighting Vertex Shader + +void gld_Points2DTwoside_DX7(GLcontext *ctx, GLuint first, GLuint last); +void gld_Line2DFlatTwoside_DX7(GLcontext *ctx, GLuint v0, GLuint v1); +void gld_Line2DSmoothTwoside_DX7(GLcontext *ctx, GLuint v0, GLuint v1); +void gld_Triangle2DFlatTwoside_DX7(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2); +void gld_Triangle2DSmoothTwoside_DX7(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2); +void gld_Quad2DFlatTwoside_DX7(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +void gld_Quad2DSmoothTwoside_DX7(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3); + +#endif diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_dxerr7.h b/mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_dxerr7.h new file mode 100644 index 000000000..df6fceb43 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_dxerr7.h @@ -0,0 +1,77 @@ +/*==========================================================================; + * + * + * File: dxerr8.h + * Content: DirectX Error Library Include File + * + ****************************************************************************/ + +#ifndef _GLD_DXERR7_H_ +#define _GLD_DXERR7_H_ + + +#include + +// +// DXGetErrorString8 +// +// Desc: Converts an DirectX HRESULT to a string +// +// Args: HRESULT hr Can be any error code from +// DPLAY D3D8 D3DX8 DMUSIC DSOUND +// +// Return: Converted string +// +const char* __stdcall DXGetErrorString8A(HRESULT hr); +const WCHAR* __stdcall DXGetErrorString8W(HRESULT hr); + +#ifdef UNICODE + #define DXGetErrorString8 DXGetErrorString8W +#else + #define DXGetErrorString8 DXGetErrorString8A +#endif + + +// +// DXTrace +// +// Desc: Outputs a formatted error message to the debug stream +// +// Args: CHAR* strFile The current file, typically passed in using the +// __FILE__ macro. +// DWORD dwLine The current line number, typically passed in using the +// __LINE__ macro. +// HRESULT hr An HRESULT that will be traced to the debug stream. +// CHAR* strMsg A string that will be traced to the debug stream (may be NULL) +// BOOL bPopMsgBox If TRUE, then a message box will popup also containing the passed info. +// +// Return: The hr that was passed in. +// +//HRESULT __stdcall DXTraceA( char* strFile, DWORD dwLine, HRESULT hr, char* strMsg, BOOL bPopMsgBox = FALSE ); +//HRESULT __stdcall DXTraceW( char* strFile, DWORD dwLine, HRESULT hr, WCHAR* strMsg, BOOL bPopMsgBox = FALSE ); +HRESULT __stdcall DXTraceA( char* strFile, DWORD dwLine, HRESULT hr, char* strMsg, BOOL bPopMsgBox); +HRESULT __stdcall DXTraceW( char* strFile, DWORD dwLine, HRESULT hr, WCHAR* strMsg, BOOL bPopMsgBox); + +#ifdef UNICODE + #define DXTrace DXTraceW +#else + #define DXTrace DXTraceA +#endif + + +// +// Helper macros +// +#if defined(DEBUG) | defined(_DEBUG) + #define DXTRACE_MSG(str) DXTrace( __FILE__, (DWORD)__LINE__, 0, str, FALSE ) + #define DXTRACE_ERR(str,hr) DXTrace( __FILE__, (DWORD)__LINE__, hr, str, TRUE ) + #define DXTRACE_ERR_NOMSGBOX(str,hr) DXTrace( __FILE__, (DWORD)__LINE__, hr, str, FALSE ) +#else + #define DXTRACE_MSG(str) (0L) + #define DXTRACE_ERR(str,hr) (hr) + #define DXTRACE_ERR_NOMSGBOX(str,hr) (hr) +#endif + + +#endif + diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_ext_dx7.c b/mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_ext_dx7.c new file mode 100644 index 000000000..ba60980bb --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_ext_dx7.c @@ -0,0 +1,346 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x/2000/XP/XBox (Win32) +* +* Description: GL extensions +* +****************************************************************************/ + +//#include "../GLDirect.h" +//#include "../gld_log.h" +//#include "../gld_settings.h" + +#include +#define GL_GLEXT_PROTOTYPES +#include +#include + +//#include "ddlog.h" +//#include "gld_dx8.h" + +#include "glheader.h" +#include "context.h" +#include "colormac.h" +#include "depth.h" +#include "extensions.h" +#include "macros.h" +#include "matrix.h" +// #include "mem.h" +//#include "mmath.h" +#include "mtypes.h" +#include "texformat.h" +#include "texstore.h" +#include "vbo/vbo.h" +#include "swrast_setup/swrast_setup.h" +#include "swrast_setup/ss_context.h" +#include "tnl/tnl.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" + +#include "dglcontext.h" +#include "extensions.h" + +// For some reason this is not defined in an above header... +extern void _mesa_enable_imaging_extensions(GLcontext *ctx); + +//--------------------------------------------------------------------------- +// Hack for the SGIS_multitexture extension that was removed from Mesa +// NOTE: SGIS_multitexture enums also clash with GL_SGIX_async_pixel + + // NOTE: Quake2 ran *slower* with this enabled, so I've + // disabled it for now. + // To enable, uncomment: + // _mesa_add_extension(ctx, GL_TRUE, szGL_SGIS_multitexture, 0); + +//--------------------------------------------------------------------------- + +enum { + /* Quake2 GL_SGIS_multitexture */ + GL_SELECTED_TEXTURE_SGIS = 0x835B, + GL_SELECTED_TEXTURE_COORD_SET_SGIS = 0x835C, + GL_MAX_TEXTURES_SGIS = 0x835D, + GL_TEXTURE0_SGIS = 0x835E, + GL_TEXTURE1_SGIS = 0x835F, + GL_TEXTURE2_SGIS = 0x8360, + GL_TEXTURE3_SGIS = 0x8361, + GL_TEXTURE_COORD_SET_SOURCE_SGIS = 0x8363, +}; + +//--------------------------------------------------------------------------- + +void APIENTRY gldSelectTextureSGIS( + GLenum target) +{ + GLenum ARB_target = GL_TEXTURE0_ARB + (target - GL_TEXTURE0_SGIS); + glActiveTextureARB(ARB_target); +} + +//--------------------------------------------------------------------------- + +void APIENTRY gldMTexCoord2fSGIS( + GLenum target, + GLfloat s, + GLfloat t) +{ + GLenum ARB_target = GL_TEXTURE0_ARB + (target - GL_TEXTURE0_SGIS); + glMultiTexCoord2fARB(ARB_target, s, t); +} + +//--------------------------------------------------------------------------- + +void APIENTRY gldMTexCoord2fvSGIS( + GLenum target, + const GLfloat *v) +{ + GLenum ARB_target = GL_TEXTURE0_ARB + (target - GL_TEXTURE0_SGIS); + glMultiTexCoord2fvARB(ARB_target, v); +} + +//--------------------------------------------------------------------------- +// Extensions +//--------------------------------------------------------------------------- + +typedef struct { + PROC proc; + char *name; +} GLD_extension; + +GLD_extension GLD_extList[] = { +#ifdef GL_EXT_polygon_offset + { (PROC)glPolygonOffsetEXT, "glPolygonOffsetEXT" }, +#endif + { (PROC)glBlendEquationEXT, "glBlendEquationEXT" }, + { (PROC)glBlendColorEXT, "glBlendColorExt" }, + { (PROC)glVertexPointerEXT, "glVertexPointerEXT" }, + { (PROC)glNormalPointerEXT, "glNormalPointerEXT" }, + { (PROC)glColorPointerEXT, "glColorPointerEXT" }, + { (PROC)glIndexPointerEXT, "glIndexPointerEXT" }, + { (PROC)glTexCoordPointerEXT, "glTexCoordPointer" }, + { (PROC)glEdgeFlagPointerEXT, "glEdgeFlagPointerEXT" }, + { (PROC)glGetPointervEXT, "glGetPointervEXT" }, + { (PROC)glArrayElementEXT, "glArrayElementEXT" }, + { (PROC)glDrawArraysEXT, "glDrawArrayEXT" }, + { (PROC)glAreTexturesResidentEXT, "glAreTexturesResidentEXT" }, + { (PROC)glBindTextureEXT, "glBindTextureEXT" }, + { (PROC)glDeleteTexturesEXT, "glDeleteTexturesEXT" }, + { (PROC)glGenTexturesEXT, "glGenTexturesEXT" }, + { (PROC)glIsTextureEXT, "glIsTextureEXT" }, + { (PROC)glPrioritizeTexturesEXT, "glPrioritizeTexturesEXT" }, + { (PROC)glCopyTexSubImage3DEXT, "glCopyTexSubImage3DEXT" }, + { (PROC)glTexImage3DEXT, "glTexImage3DEXT" }, + { (PROC)glTexSubImage3DEXT, "glTexSubImage3DEXT" }, + { (PROC)glPointParameterfEXT, "glPointParameterfEXT" }, + { (PROC)glPointParameterfvEXT, "glPointParameterfvEXT" }, + + { (PROC)glLockArraysEXT, "glLockArraysEXT" }, + { (PROC)glUnlockArraysEXT, "glUnlockArraysEXT" }, + { NULL, "\0" } +}; + +GLD_extension GLD_multitexList[] = { +/* + { (PROC)glMultiTexCoord1dSGIS, "glMTexCoord1dSGIS" }, + { (PROC)glMultiTexCoord1dvSGIS, "glMTexCoord1dvSGIS" }, + { (PROC)glMultiTexCoord1fSGIS, "glMTexCoord1fSGIS" }, + { (PROC)glMultiTexCoord1fvSGIS, "glMTexCoord1fvSGIS" }, + { (PROC)glMultiTexCoord1iSGIS, "glMTexCoord1iSGIS" }, + { (PROC)glMultiTexCoord1ivSGIS, "glMTexCoord1ivSGIS" }, + { (PROC)glMultiTexCoord1sSGIS, "glMTexCoord1sSGIS" }, + { (PROC)glMultiTexCoord1svSGIS, "glMTexCoord1svSGIS" }, + { (PROC)glMultiTexCoord2dSGIS, "glMTexCoord2dSGIS" }, + { (PROC)glMultiTexCoord2dvSGIS, "glMTexCoord2dvSGIS" }, + { (PROC)glMultiTexCoord2fSGIS, "glMTexCoord2fSGIS" }, + { (PROC)glMultiTexCoord2fvSGIS, "glMTexCoord2fvSGIS" }, + { (PROC)glMultiTexCoord2iSGIS, "glMTexCoord2iSGIS" }, + { (PROC)glMultiTexCoord2ivSGIS, "glMTexCoord2ivSGIS" }, + { (PROC)glMultiTexCoord2sSGIS, "glMTexCoord2sSGIS" }, + { (PROC)glMultiTexCoord2svSGIS, "glMTexCoord2svSGIS" }, + { (PROC)glMultiTexCoord3dSGIS, "glMTexCoord3dSGIS" }, + { (PROC)glMultiTexCoord3dvSGIS, "glMTexCoord3dvSGIS" }, + { (PROC)glMultiTexCoord3fSGIS, "glMTexCoord3fSGIS" }, + { (PROC)glMultiTexCoord3fvSGIS, "glMTexCoord3fvSGIS" }, + { (PROC)glMultiTexCoord3iSGIS, "glMTexCoord3iSGIS" }, + { (PROC)glMultiTexCoord3ivSGIS, "glMTexCoord3ivSGIS" }, + { (PROC)glMultiTexCoord3sSGIS, "glMTexCoord3sSGIS" }, + { (PROC)glMultiTexCoord3svSGIS, "glMTexCoord3svSGIS" }, + { (PROC)glMultiTexCoord4dSGIS, "glMTexCoord4dSGIS" }, + { (PROC)glMultiTexCoord4dvSGIS, "glMTexCoord4dvSGIS" }, + { (PROC)glMultiTexCoord4fSGIS, "glMTexCoord4fSGIS" }, + { (PROC)glMultiTexCoord4fvSGIS, "glMTexCoord4fvSGIS" }, + { (PROC)glMultiTexCoord4iSGIS, "glMTexCoord4iSGIS" }, + { (PROC)glMultiTexCoord4ivSGIS, "glMTexCoord4ivSGIS" }, + { (PROC)glMultiTexCoord4sSGIS, "glMTexCoord4sSGIS" }, + { (PROC)glMultiTexCoord4svSGIS, "glMTexCoord4svSGIS" }, + { (PROC)glMultiTexCoordPointerSGIS, "glMTexCoordPointerSGIS" }, + { (PROC)glSelectTextureSGIS, "glSelectTextureSGIS" }, + { (PROC)glSelectTextureCoordSetSGIS, "glSelectTextureCoordSetSGIS" }, +*/ + { (PROC)glActiveTextureARB, "glActiveTextureARB" }, + { (PROC)glClientActiveTextureARB, "glClientActiveTextureARB" }, + { (PROC)glMultiTexCoord1dARB, "glMultiTexCoord1dARB" }, + { (PROC)glMultiTexCoord1dvARB, "glMultiTexCoord1dvARB" }, + { (PROC)glMultiTexCoord1fARB, "glMultiTexCoord1fARB" }, + { (PROC)glMultiTexCoord1fvARB, "glMultiTexCoord1fvARB" }, + { (PROC)glMultiTexCoord1iARB, "glMultiTexCoord1iARB" }, + { (PROC)glMultiTexCoord1ivARB, "glMultiTexCoord1ivARB" }, + { (PROC)glMultiTexCoord1sARB, "glMultiTexCoord1sARB" }, + { (PROC)glMultiTexCoord1svARB, "glMultiTexCoord1svARB" }, + { (PROC)glMultiTexCoord2dARB, "glMultiTexCoord2dARB" }, + { (PROC)glMultiTexCoord2dvARB, "glMultiTexCoord2dvARB" }, + { (PROC)glMultiTexCoord2fARB, "glMultiTexCoord2fARB" }, + { (PROC)glMultiTexCoord2fvARB, "glMultiTexCoord2fvARB" }, + { (PROC)glMultiTexCoord2iARB, "glMultiTexCoord2iARB" }, + { (PROC)glMultiTexCoord2ivARB, "glMultiTexCoord2ivARB" }, + { (PROC)glMultiTexCoord2sARB, "glMultiTexCoord2sARB" }, + { (PROC)glMultiTexCoord2svARB, "glMultiTexCoord2svARB" }, + { (PROC)glMultiTexCoord3dARB, "glMultiTexCoord3dARB" }, + { (PROC)glMultiTexCoord3dvARB, "glMultiTexCoord3dvARB" }, + { (PROC)glMultiTexCoord3fARB, "glMultiTexCoord3fARB" }, + { (PROC)glMultiTexCoord3fvARB, "glMultiTexCoord3fvARB" }, + { (PROC)glMultiTexCoord3iARB, "glMultiTexCoord3iARB" }, + { (PROC)glMultiTexCoord3ivARB, "glMultiTexCoord3ivARB" }, + { (PROC)glMultiTexCoord3sARB, "glMultiTexCoord3sARB" }, + { (PROC)glMultiTexCoord3svARB, "glMultiTexCoord3svARB" }, + { (PROC)glMultiTexCoord4dARB, "glMultiTexCoord4dARB" }, + { (PROC)glMultiTexCoord4dvARB, "glMultiTexCoord4dvARB" }, + { (PROC)glMultiTexCoord4fARB, "glMultiTexCoord4fARB" }, + { (PROC)glMultiTexCoord4fvARB, "glMultiTexCoord4fvARB" }, + { (PROC)glMultiTexCoord4iARB, "glMultiTexCoord4iARB" }, + { (PROC)glMultiTexCoord4ivARB, "glMultiTexCoord4ivARB" }, + { (PROC)glMultiTexCoord4sARB, "glMultiTexCoord4sARB" }, + { (PROC)glMultiTexCoord4svARB, "glMultiTexCoord4svARB" }, + + // Descent3 doesn't use correct string, hence this hack + { (PROC)glMultiTexCoord4fARB, "glMultiTexCoord4f" }, + + // Quake2 SGIS multitexture + { (PROC)gldSelectTextureSGIS, "glSelectTextureSGIS" }, + { (PROC)gldMTexCoord2fSGIS, "glMTexCoord2fSGIS" }, + { (PROC)gldMTexCoord2fvSGIS, "glMTexCoord2fvSGIS" }, + + { NULL, "\0" } +}; + +//--------------------------------------------------------------------------- + +PROC gldGetProcAddress_DX( + LPCSTR a) +{ + int i; + PROC proc = NULL; + + for (i=0; GLD_extList[i].proc; i++) { + if (!strcmp(a, GLD_extList[i].name)) { + proc = GLD_extList[i].proc; + break; + } + } + + if (glb.bMultitexture) { + for (i=0; GLD_multitexList[i].proc; i++) { + if (!strcmp(a, GLD_multitexList[i].name)) { + proc = GLD_multitexList[i].proc; + break; + } + } + } + + gldLogPrintf(GLDLOG_INFO, "GetProcAddress: %s (%s)", a, proc ? "OK" : "Failed"); + + return proc; +} + +//--------------------------------------------------------------------------- + +void gldEnableExtensions_DX7( + GLcontext *ctx) +{ + GLuint i; + + // Mesa enables some extensions by default. + // This table decides which ones we want to switch off again. + + // NOTE: GL_EXT_compiled_vertex_array appears broken. + + const char *gld_disable_extensions[] = { +// "GL_ARB_transpose_matrix", +// "GL_EXT_compiled_vertex_array", +// "GL_EXT_polygon_offset", +// "GL_EXT_rescale_normal", + "GL_EXT_texture3D", +// "GL_NV_texgen_reflection", + "GL_EXT_abgr", + "GL_EXT_bgra", + NULL + }; + + const char *gld_multitex_extensions[] = { + "GL_ARB_multitexture", // Quake 3 + NULL + }; + + // Quake 2 engines + const char *szGL_SGIS_multitexture = "GL_SGIS_multitexture"; + + const char *gld_enable_extensions[] = { + "GL_EXT_texture_env_add", // Quake 3 + "GL_ARB_texture_env_add", // Quake 3 + NULL + }; + + for (i=0; gld_disable_extensions[i]; i++) { + _mesa_disable_extension(ctx, gld_disable_extensions[i]); + } + + for (i=0; gld_enable_extensions[i]; i++) { + _mesa_enable_extension(ctx, gld_enable_extensions[i]); + } + + if (glb.bMultitexture) { + for (i=0; gld_multitex_extensions[i]; i++) { + _mesa_enable_extension(ctx, gld_multitex_extensions[i]); + } + + // GL_SGIS_multitexture + // NOTE: Quake2 ran *slower* with this enabled, so I've + // disabled it for now. + // Fair bit slower on GeForce256, + // Much slower on 3dfx Voodoo5 5500. +// _mesa_add_extension(ctx, GL_TRUE, szGL_SGIS_multitexture, 0); + + } + + _mesa_enable_imaging_extensions(ctx); + _mesa_enable_1_3_extensions(ctx); + _mesa_enable_1_4_extensions(ctx); +} + +//--------------------------------------------------------------------------- diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_pipeline_dx7.c b/mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_pipeline_dx7.c new file mode 100644 index 000000000..9ccec69b9 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_pipeline_dx7.c @@ -0,0 +1,77 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x/2000/XP/XBox (Win32) +* +* Description: Mesa transformation pipeline with GLDirect fastpath +* +****************************************************************************/ + +//#include "../GLDirect.h" + +#include "dglcontext.h" +#include "ddlog.h" +#include "gld_dx7.h" + +#include "tnl/tnl.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" + +//--------------------------------------------------------------------------- + +extern struct tnl_pipeline_stage _gld_d3d_render_stage; +extern struct tnl_pipeline_stage _gld_mesa_render_stage; + +static const struct tnl_pipeline_stage *gld_pipeline[] = { + &_gld_d3d_render_stage, // Direct3D TnL + &_tnl_vertex_transform_stage, + &_tnl_normal_transform_stage, + &_tnl_lighting_stage, + &_tnl_fog_coordinate_stage, /* TODO: Omit fog stage. ??? */ + &_tnl_texgen_stage, + &_tnl_texture_transform_stage, + &_tnl_point_attenuation_stage, + &_gld_mesa_render_stage, // Mesa TnL, D3D rendering + 0, +}; + +//--------------------------------------------------------------------------- + +void gldInstallPipeline_DX7( + GLcontext *ctx) +{ + // Remove any existing pipeline stages, + // then install GLDirect pipeline stages. + + _tnl_destroy_pipeline(ctx); + _tnl_install_pipeline(ctx, gld_pipeline); +} + +//--------------------------------------------------------------------------- diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_primitive_dx7.c b/mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_primitive_dx7.c new file mode 100644 index 000000000..c99ba0bba --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_primitive_dx7.c @@ -0,0 +1,1448 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x/2000/XP/XBox (Win32) +* +* Description: Primitive (points/lines/tris/quads) rendering +* +****************************************************************************/ + +//#include "../GLDirect.h" + +//#include "gld_dx8.h" + +#include "dglcontext.h" +#include "ddlog.h" +#include "gld_dx7.h" + +#include "glheader.h" +#include "context.h" +#include "colormac.h" +#include "depth.h" +#include "extensions.h" +#include "macros.h" +#include "matrix.h" +// #include "mem.h" +//#include "mmath.h" +#include "mtypes.h" +#include "texformat.h" +#include "texstore.h" +#include "vbo/vbo.h" +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "swrast_setup/ss_context.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" + +// Disable compiler complaints about unreferenced local variables +#pragma warning (disable:4101) + +//--------------------------------------------------------------------------- +// Helper defines for primitives +//--------------------------------------------------------------------------- + +//static const float ooZ = 1.0f / 65536.0f; // One over Z + +#define GLD_COLOUR (D3DCOLOR_RGBA(swv->color[0], swv->color[1], swv->color[2], swv->color[3])) +#define GLD_SPECULAR (D3DCOLOR_RGBA(swv->specular[0], swv->specular[1], swv->specular[2], swv->specular[3])) +#define GLD_FLIP_Y(y) (gldCtx->dwHeight - (y)) + +//--------------------------------------------------------------------------- +// 2D vertex setup +//--------------------------------------------------------------------------- + +#define GLD_SETUP_2D_VARS_POINTS \ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); \ + GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); \ + GLD_2D_VERTEX *pV = (GLD_2D_VERTEX*)gld->PB2d.pPoints; \ + SScontext *ss = SWSETUP_CONTEXT(ctx); \ + SWvertex *swv; \ + DWORD dwSpecularColour; \ + DWORD dwFlatColour + +#define GLD_SETUP_2D_VARS_LINES \ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); \ + GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); \ + GLD_2D_VERTEX *pV = (GLD_2D_VERTEX*)gld->PB2d.pLines; \ + SScontext *ss = SWSETUP_CONTEXT(ctx); \ + SWvertex *swv; \ + DWORD dwSpecularColour; \ + DWORD dwFlatColour + +#define GLD_SETUP_2D_VARS_TRIANGLES \ + BOOL bFog = ctx->Fog.Enabled; \ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); \ + GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); \ + GLD_2D_VERTEX *pV = (GLD_2D_VERTEX*)gld->PB2d.pTriangles; \ + SScontext *ss = SWSETUP_CONTEXT(ctx); \ + SWvertex *swv; \ + DWORD dwSpecularColour; \ + DWORD dwFlatColour; \ + GLuint facing = 0; \ + struct vertex_buffer *VB; \ + GLchan (*vbcolor)[4]; \ + GLchan (*vbspec)[4] + +#define GLD_SETUP_GET_SWVERT(s) \ + swv = &ss->verts[##s] + +#define GLD_SETUP_2D_VERTEX \ + pV->x = swv->win[0]; \ + pV->y = GLD_FLIP_Y(swv->win[1]); \ + pV->rhw = swv->win[3] + +#define GLD_SETUP_SMOOTH_COLOUR \ + pV->diffuse = GLD_COLOUR + +#define GLD_SETUP_GET_FLAT_COLOUR \ + dwFlatColour = GLD_COLOUR +#define GLD_SETUP_GET_FLAT_FOG_COLOUR \ + dwFlatColour = _gldComputeFog(ctx, swv) + +#define GLD_SETUP_USE_FLAT_COLOUR \ + pV->diffuse = dwFlatColour + +#define GLD_SETUP_GET_FLAT_SPECULAR \ + dwSpecularColour= GLD_SPECULAR + +#define GLD_SETUP_USE_FLAT_SPECULAR \ + pV->specular = dwSpecularColour + +#define GLD_SETUP_DEPTH \ + pV->sz = swv->win[2] / ctx->DepthMaxF +// pV->z = swv->win[2] * ooZ; + +#define GLD_SETUP_SPECULAR \ + pV->specular = GLD_SPECULAR + +#define GLD_SETUP_FOG \ + pV->diffuse = _gldComputeFog(ctx, swv) + +#define GLD_SETUP_TEX0 \ + pV->t0_u = swv->texcoord[0][0]; \ + pV->t0_v = swv->texcoord[0][1] + +#define GLD_SETUP_TEX1 \ + pV->t1_u = swv->texcoord[1][0]; \ + pV->t1_v = swv->texcoord[1][1] + +#define GLD_SETUP_LIGHTING(v) \ + if (facing == 1) { \ + pV->diffuse = D3DCOLOR_RGBA(vbcolor[##v][0], vbcolor[##v][1], vbcolor[##v][2], vbcolor[##v][3]); \ + if (vbspec) { \ + pV->specular = D3DCOLOR_RGBA(vbspec[##v][0], vbspec[##v][1], vbspec[##v][2], vbspec[##v][3]); \ + } \ + } else { \ + if (bFog) \ + GLD_SETUP_FOG; \ + else \ + GLD_SETUP_SMOOTH_COLOUR; \ + GLD_SETUP_SPECULAR; \ + } + +#define GLD_SETUP_GET_FLAT_LIGHTING(v) \ + if (facing == 1) { \ + dwFlatColour = D3DCOLOR_RGBA(vbcolor[##v][0], vbcolor[##v][1], vbcolor[##v][2], vbcolor[##v][3]); \ + if (vbspec) { \ + dwSpecularColour = D3DCOLOR_RGBA(vbspec[##v][0], vbspec[##v][1], vbspec[##v][2], vbspec[##v][3]); \ + } \ + } + +#define GLD_SETUP_TWOSIDED_LIGHTING \ + /* Two-sided lighting */ \ + if (ctx->_TriangleCaps & DD_TRI_LIGHT_TWOSIDE) { \ + SWvertex *verts = SWSETUP_CONTEXT(ctx)->verts; \ + SWvertex *v[3]; \ + GLfloat ex,ey,fx,fy,cc; \ + /* Get vars for later */ \ + VB = &TNL_CONTEXT(ctx)->vb; \ + vbcolor = (GLchan (*)[4])VB->ColorPtr[1]->data; \ + if (VB->SecondaryColorPtr[1]) { \ + vbspec = (GLchan (*)[4])VB->SecondaryColorPtr[1]->data; \ + } else { \ + vbspec = NULL; \ + } \ + v[0] = &verts[v0]; \ + v[1] = &verts[v1]; \ + v[2] = &verts[v2]; \ + ex = v[0]->win[0] - v[2]->win[0]; \ + ey = v[0]->win[1] - v[2]->win[1]; \ + fx = v[1]->win[0] - v[2]->win[0]; \ + fy = v[1]->win[1] - v[2]->win[1]; \ + cc = ex*fy - ey*fx; \ + facing = (cc < 0.0) ^ ctx->Polygon._FrontBit; \ + } + +//--------------------------------------------------------------------------- +// 3D vertex setup +//--------------------------------------------------------------------------- + +#define GLD_SETUP_3D_VARS_POINTS \ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); \ + GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); \ + GLD_3D_VERTEX *pV = (GLD_3D_VERTEX*)gld->PB3d.pPoints; \ + TNLcontext *tnl = TNL_CONTEXT(ctx); \ + struct vertex_buffer *VB = &tnl->vb; \ + GLfloat (*p4f)[4]; \ + GLfloat (*tc)[4]; \ + DWORD dwColor; + +#define GLD_SETUP_3D_VARS_LINES \ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); \ + GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); \ + GLD_3D_VERTEX *pV = (GLD_3D_VERTEX*)gld->PB3d.pLines; \ + TNLcontext *tnl = TNL_CONTEXT(ctx); \ + struct vertex_buffer *VB = &tnl->vb; \ + GLfloat (*p4f)[4]; \ + GLfloat (*tc)[4]; \ + DWORD dwColor; + +#define GLD_SETUP_3D_VARS_TRIANGLES \ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); \ + GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); \ + GLD_3D_VERTEX *pV = (GLD_3D_VERTEX*)gld->PB3d.pTriangles; \ + TNLcontext *tnl = TNL_CONTEXT(ctx); \ + struct vertex_buffer *VB = &tnl->vb; \ + GLfloat (*p4f)[4]; \ + GLfloat (*tc)[4]; \ + DWORD dwColor; + +#define GLD_SETUP_3D_VERTEX(v) \ + p4f = VB->ObjPtr->data; \ + pV->Position.x = p4f[##v][0]; \ + pV->Position.y = p4f[##v][1]; \ + pV->Position.z = p4f[##v][2]; + +#define GLD_SETUP_SMOOTH_COLOUR_3D(v) \ + p4f = (GLfloat (*)[4])VB->ColorPtr[0]->data; \ + pV->Diffuse = D3DCOLOR_COLORVALUE(p4f[##v][0], p4f[##v][1], p4f[##v][2], p4f[##v][3]); + + +#define GLD_SETUP_GET_FLAT_COLOUR_3D(v) \ + p4f = (GLfloat (*)[4])VB->ColorPtr[0]->data; \ + dwColor = D3DCOLOR_COLORVALUE(p4f[##v][0], p4f[##v][1], p4f[##v][2], p4f[##v][3]); + +#define GLD_SETUP_USE_FLAT_COLOUR_3D \ + pV->Diffuse = dwColor; + +#define GLD_SETUP_TEX0_3D(v) \ + if (VB->TexCoordPtr[0]) { \ + tc = VB->TexCoordPtr[0]->data; \ + pV->TexUnit0.x = tc[##v][0]; \ + pV->TexUnit0.y = tc[##v][1]; \ + } + +#define GLD_SETUP_TEX1_3D(v) \ + if (VB->TexCoordPtr[1]) { \ + tc = VB->TexCoordPtr[1]->data; \ + pV->TexUnit1.x = tc[##v][0]; \ + pV->TexUnit1.y = tc[##v][1]; \ + } + +//--------------------------------------------------------------------------- +// Helper functions +//--------------------------------------------------------------------------- + +__inline DWORD _gldComputeFog( + GLcontext *ctx, + SWvertex *swv) +{ + // Full fog calculation. + // Based on Mesa code. + + GLchan rFog, gFog, bFog; + GLchan fR, fG, fB; + const GLfloat f = swv->fog; + const GLfloat g = 1.0 - f; + + UNCLAMPED_FLOAT_TO_CHAN(rFog, ctx->Fog.Color[RCOMP]); + UNCLAMPED_FLOAT_TO_CHAN(gFog, ctx->Fog.Color[GCOMP]); + UNCLAMPED_FLOAT_TO_CHAN(bFog, ctx->Fog.Color[BCOMP]); + fR = f * swv->color[0] + g * rFog; + fG = f * swv->color[1] + g * gFog; + fB = f * swv->color[2] + g * bFog; + return D3DCOLOR_RGBA(fR, fG, fB, swv->color[3]); +} + +//--------------------------------------------------------------------------- + +void gld_ResetLineStipple_DX7( + GLcontext *ctx) +{ + // TODO: Fake stipple with a 32x32 texture. +} + +//--------------------------------------------------------------------------- +// 2D (post-transformed) primitives +//--------------------------------------------------------------------------- + +void gld_Points2D_DX7( + GLcontext *ctx, + GLuint first, + GLuint last) +{ + GLD_SETUP_2D_VARS_POINTS; + + unsigned i; + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + + // _Size is already clamped to MaxPointSize and MinPointSize + // Not supported by DX7 +// IDirect3DDevice8_SetRenderState(gld->pDev, D3DRS_POINTSIZE, *((DWORD*)&ctx->Point._Size)); + + if (VB->Elts) { + for (i=first; iClipMask[VB->Elts[i]] == 0) { +// _swrast_Point( ctx, &verts[VB->Elts[i]] ); + GLD_SETUP_GET_SWVERT(VB->Elts[i]); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_SMOOTH_COLOUR; + GLD_SETUP_DEPTH; + GLD_SETUP_SPECULAR; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + } + } + } else { + GLD_SETUP_GET_SWVERT(first); + for (i=first; iClipMask[i] == 0) { +// _swrast_Point( ctx, &verts[i] ); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_SMOOTH_COLOUR; + GLD_SETUP_DEPTH; + GLD_SETUP_SPECULAR; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + } + } + } + + gld->PB2d.pPoints = (BYTE*)pV; + gld->PB2d.nPoints += (last-first); +} + +//--------------------------------------------------------------------------- + +void gld_Line2DFlat_DX7( + GLcontext *ctx, + GLuint v0, + GLuint v1) +{ + GLD_SETUP_2D_VARS_LINES; + + GLD_SETUP_GET_SWVERT(v1); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_GET_FLAT_COLOUR; + GLD_SETUP_USE_FLAT_COLOUR; + GLD_SETUP_GET_FLAT_SPECULAR; + GLD_SETUP_USE_FLAT_SPECULAR; + pV++; + + GLD_SETUP_GET_SWVERT(v0); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + GLD_SETUP_USE_FLAT_SPECULAR; + pV++; + + gld->PB2d.pLines = (BYTE*)pV; + gld->PB2d.nLines++; +} + +//--------------------------------------------------------------------------- + +void gld_Line2DSmooth_DX7( + GLcontext *ctx, + GLuint v0, + GLuint v1) +{ + GLD_SETUP_2D_VARS_LINES; + + GLD_SETUP_GET_SWVERT(v0); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_SMOOTH_COLOUR; + GLD_SETUP_DEPTH; + GLD_SETUP_SPECULAR; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + pV++; + + GLD_SETUP_GET_SWVERT(v1); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_SMOOTH_COLOUR; + GLD_SETUP_SPECULAR; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + pV++; + + gld->PB2d.pLines = (BYTE*)pV; + gld->PB2d.nLines++; +} + +//--------------------------------------------------------------------------- + +void gld_Triangle2DFlat_DX7( + GLcontext *ctx, + GLuint v0, + GLuint v1, + GLuint v2) +{ + GLD_SETUP_2D_VARS_TRIANGLES; + + GLD_SETUP_GET_SWVERT(v2); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_GET_FLAT_COLOUR; + GLD_SETUP_USE_FLAT_COLOUR; + pV++;; + + GLD_SETUP_GET_SWVERT(v0); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + pV++; + + GLD_SETUP_GET_SWVERT(v1); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + pV++; + + gld->PB2d.pTriangles = (BYTE*)pV; + gld->PB2d.nTriangles++; +} + +//--------------------------------------------------------------------------- + +void gld_Triangle2DSmooth_DX7( + GLcontext *ctx, + GLuint v0, + GLuint v1, + GLuint v2) +{ + + GLD_SETUP_2D_VARS_TRIANGLES; + + GLD_SETUP_GET_SWVERT(v0); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_SMOOTH_COLOUR; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + pV++; + + GLD_SETUP_GET_SWVERT(v1); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_SMOOTH_COLOUR; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + pV++; + + GLD_SETUP_GET_SWVERT(v2); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_SMOOTH_COLOUR; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + pV++; + + gld->PB2d.pTriangles = (BYTE*)pV; + gld->PB2d.nTriangles++; +} + +//--------------------------------------------------------------------------- + +void gld_Triangle2DFlatExtras_DX7( + GLcontext *ctx, + GLuint v0, + GLuint v1, + GLuint v2) +{ + GLD_SETUP_2D_VARS_TRIANGLES; + + GLD_SETUP_TWOSIDED_LIGHTING(v2); + + GLD_SETUP_GET_SWVERT(v2); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + if (bFog) + GLD_SETUP_GET_FLAT_FOG_COLOUR; + else + GLD_SETUP_GET_FLAT_COLOUR; + GLD_SETUP_GET_FLAT_SPECULAR; + GLD_SETUP_GET_FLAT_LIGHTING(v2); + GLD_SETUP_USE_FLAT_COLOUR; + GLD_SETUP_USE_FLAT_SPECULAR; + pV++; + + GLD_SETUP_GET_SWVERT(v0); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + GLD_SETUP_USE_FLAT_SPECULAR; + pV++; + + GLD_SETUP_GET_SWVERT(v1); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + GLD_SETUP_USE_FLAT_SPECULAR; + pV++; + + gld->PB2d.pTriangles = (BYTE*)pV; + gld->PB2d.nTriangles++; +} + +//--------------------------------------------------------------------------- + +void gld_Triangle2DSmoothExtras_DX7( + GLcontext *ctx, + GLuint v0, + GLuint v1, + GLuint v2) +{ + GLD_SETUP_2D_VARS_TRIANGLES; + + GLD_SETUP_TWOSIDED_LIGHTING(v0); + + GLD_SETUP_GET_SWVERT(v0); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_LIGHTING(v0); + pV++; + + GLD_SETUP_GET_SWVERT(v1); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_LIGHTING(v1); + pV++; + + GLD_SETUP_GET_SWVERT(v2); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_LIGHTING(v2); + pV++; + + gld->PB2d.pTriangles = (BYTE*)pV; + gld->PB2d.nTriangles++; +} + +//--------------------------------------------------------------------------- + +void gld_Quad2DFlat_DX7( + GLcontext *ctx, + GLuint v0, + GLuint v1, + GLuint v2, + GLuint v3) +{ + GLD_SETUP_2D_VARS_TRIANGLES; + + GLD_SETUP_GET_SWVERT(v3); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_GET_FLAT_COLOUR; + GLD_SETUP_USE_FLAT_COLOUR; + pV++; + + GLD_SETUP_GET_SWVERT(v0); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + pV++; + + GLD_SETUP_GET_SWVERT(v1); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + pV++; + + GLD_SETUP_GET_SWVERT(v1); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + pV++; + + GLD_SETUP_GET_SWVERT(v2); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + pV++; + + GLD_SETUP_GET_SWVERT(v3); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + pV++; + + gld->PB2d.pTriangles = (BYTE*)pV; + gld->PB2d.nTriangles += 2; +} + +//--------------------------------------------------------------------------- + +void gld_Quad2DSmooth_DX7( + GLcontext *ctx, + GLuint v0, + GLuint v1, + GLuint v2, + GLuint v3) +{ + GLD_SETUP_2D_VARS_TRIANGLES; + + GLD_SETUP_GET_SWVERT(v0); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_SMOOTH_COLOUR; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + pV++; + + GLD_SETUP_GET_SWVERT(v1); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_SMOOTH_COLOUR; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + pV++; + + GLD_SETUP_GET_SWVERT(v2); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_SMOOTH_COLOUR; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + pV++; + + GLD_SETUP_GET_SWVERT(v2); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_SMOOTH_COLOUR; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + pV++; + + GLD_SETUP_GET_SWVERT(v3); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_SMOOTH_COLOUR; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + pV++; + + GLD_SETUP_GET_SWVERT(v0); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_SMOOTH_COLOUR; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + pV++; + + gld->PB2d.pTriangles = (BYTE*)pV; + gld->PB2d.nTriangles += 2; +} + +//--------------------------------------------------------------------------- + +void gld_Quad2DFlatExtras_DX7( + GLcontext *ctx, + GLuint v0, + GLuint v1, + GLuint v2, + GLuint v3) +{ + GLD_SETUP_2D_VARS_TRIANGLES; + + GLD_SETUP_TWOSIDED_LIGHTING(v3); + + GLD_SETUP_GET_SWVERT(v3); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + if (bFog) + GLD_SETUP_GET_FLAT_FOG_COLOUR; + else + GLD_SETUP_GET_FLAT_COLOUR; + GLD_SETUP_GET_FLAT_SPECULAR; + GLD_SETUP_GET_FLAT_LIGHTING(v3); + GLD_SETUP_USE_FLAT_COLOUR; + GLD_SETUP_USE_FLAT_SPECULAR; + pV++; + + GLD_SETUP_GET_SWVERT(v0); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + GLD_SETUP_USE_FLAT_SPECULAR; + pV++; + + GLD_SETUP_GET_SWVERT(v1); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + GLD_SETUP_USE_FLAT_SPECULAR; + pV++; + + GLD_SETUP_GET_SWVERT(v1); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + GLD_SETUP_USE_FLAT_SPECULAR; + pV++; + + GLD_SETUP_GET_SWVERT(v2); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + GLD_SETUP_USE_FLAT_SPECULAR; + pV++; + + GLD_SETUP_GET_SWVERT(v3); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + GLD_SETUP_USE_FLAT_SPECULAR; + pV++; + + gld->PB2d.pTriangles = (BYTE*)pV; + gld->PB2d.nTriangles += 2; +} + +//--------------------------------------------------------------------------- + +void gld_Quad2DSmoothExtras_DX7( + GLcontext *ctx, + GLuint v0, + GLuint v1, + GLuint v2, + GLuint v3) +{ + GLD_SETUP_2D_VARS_TRIANGLES; + + GLD_SETUP_TWOSIDED_LIGHTING(v0); + + GLD_SETUP_GET_SWVERT(v0); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_LIGHTING(v0); + pV++; + + GLD_SETUP_GET_SWVERT(v1); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_LIGHTING(v1); + pV++; + + GLD_SETUP_GET_SWVERT(v2); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_LIGHTING(v2); + pV++; + + GLD_SETUP_GET_SWVERT(v2); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_LIGHTING(v2); + pV++; + + GLD_SETUP_GET_SWVERT(v3); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_LIGHTING(v3); + pV++; + + GLD_SETUP_GET_SWVERT(v0); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_LIGHTING(v0); + pV++; + + gld->PB2d.pTriangles = (BYTE*)pV; + gld->PB2d.nTriangles += 2; +} + +//--------------------------------------------------------------------------- +// 3D (pre-transformed) primitives +//--------------------------------------------------------------------------- + +void gld_Points3D_DX7( + GLcontext *ctx, + GLuint first, + GLuint last) +{ + GLD_SETUP_3D_VARS_POINTS + + unsigned i; +// struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + + // _Size is already clamped to MaxPointSize and MinPointSize + // Not supported by DX7 +// IDirect3DDevice8_SetRenderState(gld->pDev, D3DRS_POINTSIZE, *((DWORD*)&ctx->Point._Size)); + + if (VB->Elts) { + for (i=first; iClipMask[VB->Elts[i]] == 0) { +// _swrast_Point( ctx, &verts[VB->Elts[i]] ); +// GLD_SETUP_GET_SWVERT(VB->Elts[i]); + GLD_SETUP_3D_VERTEX(VB->Elts[i]) + GLD_SETUP_SMOOTH_COLOUR_3D(i) + GLD_SETUP_TEX0_3D(i) + GLD_SETUP_TEX1_3D(i) + } + } + } else { +// GLD_SETUP_GET_SWVERT(first); + for (i=first; iClipMask[i] == 0) { +// _swrast_Point( ctx, &verts[i] ); + GLD_SETUP_3D_VERTEX(i) + GLD_SETUP_SMOOTH_COLOUR_3D(i) + GLD_SETUP_TEX0_3D(i) + GLD_SETUP_TEX1_3D(i) + } + } + } +/* + for (i=first; iPB3d.pPoints = (BYTE*)pV; + gld->PB3d.nPoints += (last-first); +} + +//--------------------------------------------------------------------------- +// Line functions +//--------------------------------------------------------------------------- + +void gld_Line3DFlat_DX7( + GLcontext *ctx, + GLuint v0, + GLuint v1) +{ + GLD_SETUP_3D_VARS_LINES + + GLD_SETUP_3D_VERTEX(v1) + GLD_SETUP_GET_FLAT_COLOUR_3D(v1) + GLD_SETUP_USE_FLAT_COLOUR_3D + GLD_SETUP_TEX0_3D(v1) + GLD_SETUP_TEX1_3D(v1) + pV++; + + GLD_SETUP_3D_VERTEX(v0) + GLD_SETUP_USE_FLAT_COLOUR_3D + GLD_SETUP_TEX0_3D(v0) + GLD_SETUP_TEX1_3D(v0) + pV++; + + gld->PB3d.pLines = (BYTE*)pV; + gld->PB3d.nLines++; +} + +//--------------------------------------------------------------------------- + +void gld_Line3DSmooth_DX7( + GLcontext *ctx, + GLuint v0, + GLuint v1) +{ + GLD_SETUP_3D_VARS_LINES + + GLD_SETUP_3D_VERTEX(v1) + GLD_SETUP_SMOOTH_COLOUR_3D(v1) + GLD_SETUP_TEX0_3D(v1) + GLD_SETUP_TEX1_3D(v1) + pV++; + + GLD_SETUP_3D_VERTEX(v0) + GLD_SETUP_SMOOTH_COLOUR_3D(v0) + GLD_SETUP_TEX0_3D(v0) + GLD_SETUP_TEX1_3D(v0) + pV++; + + gld->PB3d.pLines = (BYTE*)pV; + gld->PB3d.nLines++; +} + +//--------------------------------------------------------------------------- +// Triangle functions +//--------------------------------------------------------------------------- + +void gld_Triangle3DFlat_DX7( + GLcontext *ctx, + GLuint v0, + GLuint v1, + GLuint v2) +{ + GLD_SETUP_3D_VARS_TRIANGLES + + GLD_SETUP_3D_VERTEX(v2) + GLD_SETUP_TEX0_3D(v2) + GLD_SETUP_TEX1_3D(v2) + GLD_SETUP_GET_FLAT_COLOUR_3D(v2) + GLD_SETUP_USE_FLAT_COLOUR_3D + pV++; + + GLD_SETUP_3D_VERTEX(v0) + GLD_SETUP_TEX0_3D(v0) + GLD_SETUP_TEX1_3D(v0) + GLD_SETUP_USE_FLAT_COLOUR_3D + pV++; + + GLD_SETUP_3D_VERTEX(v1) + GLD_SETUP_TEX0_3D(v1) + GLD_SETUP_TEX1_3D(v1) + GLD_SETUP_USE_FLAT_COLOUR_3D + pV++; + + gld->PB3d.pTriangles = (BYTE*)pV; + gld->PB3d.nTriangles++; +} + +//--------------------------------------------------------------------------- + +void gld_Triangle3DSmooth_DX7( + GLcontext *ctx, + GLuint v0, + GLuint v1, + GLuint v2) +{ + GLD_SETUP_3D_VARS_TRIANGLES + + GLD_SETUP_3D_VERTEX(v0) + GLD_SETUP_SMOOTH_COLOUR_3D(v0) + GLD_SETUP_TEX0_3D(v0) + GLD_SETUP_TEX1_3D(v0) + pV++; + + GLD_SETUP_3D_VERTEX(v1) + GLD_SETUP_SMOOTH_COLOUR_3D(v1) + GLD_SETUP_TEX0_3D(v1) + GLD_SETUP_TEX1_3D(v1) + pV++; + + GLD_SETUP_3D_VERTEX(v2) + GLD_SETUP_SMOOTH_COLOUR_3D(v2) + GLD_SETUP_TEX0_3D(v2) + GLD_SETUP_TEX1_3D(v2) + pV++; + + gld->PB3d.pTriangles = (BYTE*)pV; + gld->PB3d.nTriangles++; +} + +//--------------------------------------------------------------------------- +// Quad functions +//--------------------------------------------------------------------------- + +void gld_Quad3DFlat_DX7( + GLcontext *ctx, + GLuint v0, + GLuint v1, + GLuint v2, + GLuint v3) +{ + GLD_SETUP_3D_VARS_TRIANGLES + + GLD_SETUP_3D_VERTEX(v3) + GLD_SETUP_GET_FLAT_COLOUR_3D(v3) + GLD_SETUP_USE_FLAT_COLOUR_3D + GLD_SETUP_TEX0_3D(v3) + GLD_SETUP_TEX1_3D(v3) + pV++; + + GLD_SETUP_3D_VERTEX(v0) + GLD_SETUP_USE_FLAT_COLOUR_3D + GLD_SETUP_TEX0_3D(v0) + GLD_SETUP_TEX1_3D(v0) + pV++; + + GLD_SETUP_3D_VERTEX(v1) + GLD_SETUP_USE_FLAT_COLOUR_3D + GLD_SETUP_TEX0_3D(v1) + GLD_SETUP_TEX1_3D(v1) + pV++; + + GLD_SETUP_3D_VERTEX(v1) + GLD_SETUP_USE_FLAT_COLOUR_3D + GLD_SETUP_TEX0_3D(v1) + GLD_SETUP_TEX1_3D(v1) + pV++; + + GLD_SETUP_3D_VERTEX(v2) + GLD_SETUP_USE_FLAT_COLOUR_3D + GLD_SETUP_TEX0_3D(v2) + GLD_SETUP_TEX1_3D(v2) + pV++; + + GLD_SETUP_3D_VERTEX(v3) + GLD_SETUP_USE_FLAT_COLOUR_3D + GLD_SETUP_TEX0_3D(v3) + GLD_SETUP_TEX1_3D(v3) + pV++; + + gld->PB3d.pTriangles = (BYTE*)pV; + gld->PB3d.nTriangles += 2; +} + +//--------------------------------------------------------------------------- + +void gld_Quad3DSmooth_DX7( + GLcontext *ctx, + GLuint v0, + GLuint v1, + GLuint v2, + GLuint v3) +{ + GLD_SETUP_3D_VARS_TRIANGLES + + GLD_SETUP_3D_VERTEX(v0) + GLD_SETUP_SMOOTH_COLOUR_3D(v0) + GLD_SETUP_TEX0_3D(v0) + GLD_SETUP_TEX1_3D(v0) + pV++; + + GLD_SETUP_3D_VERTEX(v1) + GLD_SETUP_SMOOTH_COLOUR_3D(v1) + GLD_SETUP_TEX0_3D(v1) + GLD_SETUP_TEX1_3D(v1) + pV++; + + GLD_SETUP_3D_VERTEX(v2) + GLD_SETUP_SMOOTH_COLOUR_3D(v2) + GLD_SETUP_TEX0_3D(v2) + GLD_SETUP_TEX1_3D(v2) + pV++; + + GLD_SETUP_3D_VERTEX(v2) + GLD_SETUP_SMOOTH_COLOUR_3D(v2) + GLD_SETUP_TEX0_3D(v2) + GLD_SETUP_TEX1_3D(v2) + pV++; + + GLD_SETUP_3D_VERTEX(v3) + GLD_SETUP_SMOOTH_COLOUR_3D(v3) + GLD_SETUP_TEX0_3D(v3) + GLD_SETUP_TEX1_3D(v3) + pV++; + + GLD_SETUP_3D_VERTEX(v0) + GLD_SETUP_SMOOTH_COLOUR_3D(v0) + GLD_SETUP_TEX0_3D(v0) + GLD_SETUP_TEX1_3D(v0) + pV++; + + gld->PB3d.pTriangles = (BYTE*)pV; + gld->PB3d.nTriangles += 2; +} + +//--------------------------------------------------------------------------- +// Vertex setup for two-sided-lighting vertex shader +//--------------------------------------------------------------------------- + +/* + +void gld_Points2DTwoside_DX8(GLcontext *ctx, GLuint first, GLuint last) +{ + // NOTE: Two-sided lighting does not apply to Points +} + +//--------------------------------------------------------------------------- + +void gld_Line2DFlatTwoside_DX8(GLcontext *ctx, GLuint v0, GLuint v1) +{ + // NOTE: Two-sided lighting does not apply to Lines +} + +//--------------------------------------------------------------------------- + +void gld_Line2DSmoothTwoside_DX8(GLcontext *ctx, GLuint v0, GLuint v1) +{ + // NOTE: Two-sided lighting does not apply to Lines +} + +//--------------------------------------------------------------------------- + +void gld_Triangle2DFlatTwoside_DX8(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2) +{ +} + +//--------------------------------------------------------------------------- + +void gld_Triangle2DSmoothTwoside_DX8(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx); + GLD_TWOSIDED_VERTEX *pV = (GLD_TWOSIDED_VERTEX*)gld->PBtwosidelight.pTriangles; + SScontext *ss = SWSETUP_CONTEXT(ctx); + SWvertex *swv; + DWORD dwSpecularColour; + DWORD dwFlatColour; + GLuint facing = 0; + struct vertex_buffer *VB; + GLchan (*vbcolor)[4]; + GLchan (*vbspec)[4]; + + // Reciprocal of DepthMax + const float ooDepthMax = 1.0f / ctx->DepthMaxF; + + // 1st vert + swv = &ss->verts[v0]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + // 2nd vert + swv = &ss->verts[v1]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + // 3rd vert + swv = &ss->verts[v2]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + gld->PBtwosidelight.pTriangles = (BYTE*)pV; + gld->PBtwosidelight.nTriangles++; +} + +//--------------------------------------------------------------------------- + +void gld_Quad2DFlatTwoside_DX8(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx); + GLD_TWOSIDED_VERTEX *pV = (GLD_TWOSIDED_VERTEX*)gld->PBtwosidelight.pTriangles; + SScontext *ss = SWSETUP_CONTEXT(ctx); + SWvertex *swv; + DWORD dwSpecularColour; + DWORD dwFlatColour; + GLuint facing = 0; + struct vertex_buffer *VB; + GLchan (*vbcolor)[4]; + GLchan (*vbspec)[4]; + + // Reciprocal of DepthMax + const float ooDepthMax = 1.0f / ctx->DepthMaxF; + + // 1st vert + swv = &ss->verts[v0]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + // 2nd vert + swv = &ss->verts[v1]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + // 3rd vert + swv = &ss->verts[v2]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + // 4th vert + swv = &ss->verts[v2]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + // 5th vert + swv = &ss->verts[v3]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + // 6th vert + swv = &ss->verts[v0]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + gld->PBtwosidelight.pTriangles = (BYTE*)pV; + gld->PBtwosidelight.nTriangles += 2; +} + +//--------------------------------------------------------------------------- + +void gld_Quad2DSmoothTwoside_DX8(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx); + GLD_TWOSIDED_VERTEX *pV = (GLD_TWOSIDED_VERTEX*)gld->PBtwosidelight.pTriangles; + SScontext *ss = SWSETUP_CONTEXT(ctx); + SWvertex *swv; + DWORD dwSpecularColour; + DWORD dwFlatColour; + GLuint facing = 0; + struct vertex_buffer *VB; + GLchan (*vbcolor)[4]; + GLchan (*vbspec)[4]; + + // Reciprocal of DepthMax + const float ooDepthMax = 1.0f / ctx->DepthMaxF; + + // 1st vert + swv = &ss->verts[v0]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + // 2nd vert + swv = &ss->verts[v1]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + // 3rd vert + swv = &ss->verts[v2]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + // 4th vert + swv = &ss->verts[v2]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + // 5th vert + swv = &ss->verts[v3]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + // 6th vert + swv = &ss->verts[v0]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + gld->PBtwosidelight.pTriangles = (BYTE*)pV; + gld->PBtwosidelight.nTriangles += 2; +} + +//--------------------------------------------------------------------------- + +*/ diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_texture_dx7.c b/mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_texture_dx7.c new file mode 100644 index 000000000..bbe673516 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_texture_dx7.c @@ -0,0 +1,2196 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x/2000/XP/XBox (Win32) +* +* Description: Texture / Bitmap functions +* +****************************************************************************/ + +#include "dglcontext.h" +#include "ddlog.h" +#include "gld_dx7.h" + +//#include + +#include "texformat.h" +#include "colormac.h" +#include "texstore.h" +#include "image.h" +// #include "mem.h" + +//--------------------------------------------------------------------------- + +#define GLD_FLIP_HEIGHT(y,h) (gldCtx->dwHeight - (y) - (h)) + +D3DX_SURFACEFORMAT _gldD3DXFormatFromSurface(IDirectDrawSurface7 *pSurface); + +//--------------------------------------------------------------------------- +// 1D texture fetch +//--------------------------------------------------------------------------- + +#define CHAN_SRC( t, i, j, k, sz ) \ + ((GLchan *)(t)->Data + (i) * (sz)) +#define UBYTE_SRC( t, i, j, k, sz ) \ + ((GLubyte *)(t)->Data + (i) * (sz)) +#define USHORT_SRC( t, i, j, k ) \ + ((GLushort *)(t)->Data + (i)) +#define FLOAT_SRC( t, i, j, k ) \ + ((GLfloat *)(t)->Data + (i)) + +//--------------------------------------------------------------------------- + +static void gld_fetch_1d_texel_X8R8G8B8( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *texel ) +{ + const GLchan *src = CHAN_SRC( texImage, i, j, k, 4 ); + GLchan *rgba = (GLchan *)texel; + rgba[RCOMP] = src[2]; + rgba[GCOMP] = src[1]; + rgba[BCOMP] = src[0]; + rgba[ACOMP] = CHAN_MAX; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_1d_texel_f_X8R8G8B8( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLfloat *texel ) +{ + const GLchan *src = CHAN_SRC( texImage, i, j, k, 4 ); + texel[RCOMP] = CHAN_TO_FLOAT(src[0]); + texel[GCOMP] = CHAN_TO_FLOAT(src[1]); + texel[BCOMP] = CHAN_TO_FLOAT(src[2]); + texel[ACOMP] = 1.f; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_1d_texel_X1R5G5B5( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *texel ) +{ + const GLushort *src = USHORT_SRC( texImage, i, j, k ); + GLchan *rgba = (GLchan *) texel; GLushort s = *src; + rgba[RCOMP] = UBYTE_TO_CHAN( ((s >> 10) & 0xf8) * 255 / 0xf8 ); + rgba[GCOMP] = UBYTE_TO_CHAN( ((s >> 5) & 0xf8) * 255 / 0xf8 ); + rgba[BCOMP] = UBYTE_TO_CHAN( ((s ) & 0xf8) * 255 / 0xf8 ); + rgba[ACOMP] = CHAN_MAX; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_1d_texel_f_X1R5G5B5( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLfloat *texel ) +{ + const GLushort *src = USHORT_SRC( texImage, i, j, k ); + GLushort s = *src; + texel[RCOMP] = UBYTE_TO_FLOAT( ((s >> 10) & 0xf8) * 255 / 0xf8 ); + texel[GCOMP] = UBYTE_TO_FLOAT( ((s >> 5) & 0xf8) * 255 / 0xf8 ); + texel[BCOMP] = UBYTE_TO_FLOAT( ((s ) & 0xf8) * 255 / 0xf8 ); + texel[ACOMP] = 1.f; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_1d_texel_X4R4G4B4( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *texel ) +{ + const GLushort *src = USHORT_SRC( texImage, i, j, k ); + GLchan *rgba = (GLchan *) texel; GLushort s = *src; + rgba[RCOMP] = UBYTE_TO_CHAN( ((s >> 8) & 0xf) * 255 / 0xf ); + rgba[GCOMP] = UBYTE_TO_CHAN( ((s >> 4) & 0xf) * 255 / 0xf ); + rgba[BCOMP] = UBYTE_TO_CHAN( ((s ) & 0xf) * 255 / 0xf ); + rgba[ACOMP] = CHAN_MAX; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_1d_texel_f_X4R4G4B4( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLfloat *texel ) +{ + const GLushort *src = USHORT_SRC( texImage, i, j, k ); + GLushort s = *src; + texel[RCOMP] = UBYTE_TO_FLOAT( ((s >> 8) & 0xf) * 255 / 0xf ); + texel[GCOMP] = UBYTE_TO_FLOAT( ((s >> 4) & 0xf) * 255 / 0xf ); + texel[BCOMP] = UBYTE_TO_FLOAT( ((s ) & 0xf) * 255 / 0xf ); + texel[ACOMP] = 1.f; +} + +//--------------------------------------------------------------------------- + +#undef CHAN_SRC +#undef UBYTE_SRC +#undef USHORT_SRC +#undef FLOAT_SRC + +//--------------------------------------------------------------------------- +// 2D texture fetch +//--------------------------------------------------------------------------- + +#define CHAN_SRC( t, i, j, k, sz ) \ + ((GLchan *)(t)->Data + ((t)->Width * (j) + (i)) * (sz)) +#define UBYTE_SRC( t, i, j, k, sz ) \ + ((GLubyte *)(t)->Data + ((t)->Width * (j) + (i)) * (sz)) +#define USHORT_SRC( t, i, j, k ) \ + ((GLushort *)(t)->Data + ((t)->Width * (j) + (i))) +#define FLOAT_SRC( t, i, j, k ) \ + ((GLfloat *)(t)->Data + ((t)->Width * (j) + (i))) + +//--------------------------------------------------------------------------- + +static void gld_fetch_2d_texel_X8R8G8B8( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *texel ) +{ + const GLchan *src = CHAN_SRC( texImage, i, j, k, 4 ); + GLchan *rgba = (GLchan *)texel; + rgba[RCOMP] = src[2]; + rgba[GCOMP] = src[1]; + rgba[BCOMP] = src[0]; + rgba[ACOMP] = CHAN_MAX; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_2d_texel_f_X8R8G8B8( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLfloat *texel ) +{ + const GLchan *src = CHAN_SRC( texImage, i, j, k, 4 ); + texel[RCOMP] = CHAN_TO_FLOAT(src[0]); + texel[GCOMP] = CHAN_TO_FLOAT(src[1]); + texel[BCOMP] = CHAN_TO_FLOAT(src[2]); + texel[ACOMP] = 1.f; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_2d_texel_X1R5G5B5( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *texel ) +{ + const GLushort *src = USHORT_SRC( texImage, i, j, k ); + GLchan *rgba = (GLchan *) texel; GLushort s = *src; + rgba[RCOMP] = UBYTE_TO_CHAN( ((s >> 10) & 0xf8) * 255 / 0xf8 ); + rgba[GCOMP] = UBYTE_TO_CHAN( ((s >> 5) & 0xf8) * 255 / 0xf8 ); + rgba[BCOMP] = UBYTE_TO_CHAN( ((s ) & 0xf8) * 255 / 0xf8 ); + rgba[ACOMP] = CHAN_MAX; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_2d_texel_f_X1R5G5B5( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLfloat *texel ) +{ + const GLushort *src = USHORT_SRC( texImage, i, j, k ); + GLushort s = *src; + texel[RCOMP] = UBYTE_TO_FLOAT( ((s >> 10) & 0xf8) * 255 / 0xf8 ); + texel[GCOMP] = UBYTE_TO_FLOAT( ((s >> 5) & 0xf8) * 255 / 0xf8 ); + texel[BCOMP] = UBYTE_TO_FLOAT( ((s ) & 0xf8) * 255 / 0xf8 ); + texel[ACOMP] = 1.f; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_2d_texel_X4R4G4B4( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *texel ) +{ + const GLushort *src = USHORT_SRC( texImage, i, j, k ); + GLchan *rgba = (GLchan *) texel; GLushort s = *src; + rgba[RCOMP] = UBYTE_TO_CHAN( ((s >> 8) & 0xf) * 255 / 0xf ); + rgba[GCOMP] = UBYTE_TO_CHAN( ((s >> 4) & 0xf) * 255 / 0xf ); + rgba[BCOMP] = UBYTE_TO_CHAN( ((s ) & 0xf) * 255 / 0xf ); + rgba[ACOMP] = CHAN_MAX; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_2d_texel_f_X4R4G4B4( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLfloat *texel ) +{ + const GLushort *src = USHORT_SRC( texImage, i, j, k ); + GLushort s = *src; + texel[RCOMP] = UBYTE_TO_FLOAT( ((s >> 8) & 0xf) * 255 / 0xf ); + texel[GCOMP] = UBYTE_TO_FLOAT( ((s >> 4) & 0xf) * 255 / 0xf ); + texel[BCOMP] = UBYTE_TO_FLOAT( ((s ) & 0xf) * 255 / 0xf ); + texel[ACOMP] = 1.f; +} + +//--------------------------------------------------------------------------- + +#undef CHAN_SRC +#undef UBYTE_SRC +#undef USHORT_SRC +#undef FLOAT_SRC + +//--------------------------------------------------------------------------- +// 3D texture fetch +//--------------------------------------------------------------------------- + +#define CHAN_SRC( t, i, j, k, sz ) \ + (GLchan *)(t)->Data + (((t)->Height * (k) + (j)) * \ + (t)->Width + (i)) * (sz) +#define UBYTE_SRC( t, i, j, k, sz ) \ + ((GLubyte *)(t)->Data + (((t)->Height * (k) + (j)) * \ + (t)->Width + (i)) * (sz)) +#define USHORT_SRC( t, i, j, k ) \ + ((GLushort *)(t)->Data + (((t)->Height * (k) + (j)) * \ + (t)->Width + (i))) +#define FLOAT_SRC( t, i, j, k ) \ + ((GLfloat *)(t)->Data + (((t)->Height * (k) + (j)) * \ + (t)->Width + (i))) + +//--------------------------------------------------------------------------- + +static void gld_fetch_3d_texel_X8R8G8B8( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *texel ) +{ + const GLchan *src = CHAN_SRC( texImage, i, j, k, 4 ); + GLchan *rgba = (GLchan *)texel; + rgba[RCOMP] = src[2]; + rgba[GCOMP] = src[1]; + rgba[BCOMP] = src[0]; + rgba[ACOMP] = CHAN_MAX; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_3d_texel_f_X8R8G8B8( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLfloat *texel ) +{ + const GLchan *src = CHAN_SRC( texImage, i, j, k, 4 ); + texel[RCOMP] = CHAN_TO_FLOAT(src[0]); + texel[GCOMP] = CHAN_TO_FLOAT(src[1]); + texel[BCOMP] = CHAN_TO_FLOAT(src[2]); + texel[ACOMP] = 1.f; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_3d_texel_X1R5G5B5( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *texel ) +{ + const GLushort *src = USHORT_SRC( texImage, i, j, k ); + GLchan *rgba = (GLchan *) texel; GLushort s = *src; + rgba[RCOMP] = UBYTE_TO_CHAN( ((s >> 10) & 0xf8) * 255 / 0xf8 ); + rgba[GCOMP] = UBYTE_TO_CHAN( ((s >> 5) & 0xf8) * 255 / 0xf8 ); + rgba[BCOMP] = UBYTE_TO_CHAN( ((s ) & 0xf8) * 255 / 0xf8 ); + rgba[ACOMP] = CHAN_MAX; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_3d_texel_f_X1R5G5B5( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLfloat *texel ) +{ + const GLushort *src = USHORT_SRC( texImage, i, j, k ); + GLushort s = *src; + texel[RCOMP] = UBYTE_TO_FLOAT( ((s >> 10) & 0xf8) * 255 / 0xf8 ); + texel[GCOMP] = UBYTE_TO_FLOAT( ((s >> 5) & 0xf8) * 255 / 0xf8 ); + texel[BCOMP] = UBYTE_TO_FLOAT( ((s ) & 0xf8) * 255 / 0xf8 ); + texel[ACOMP] = 1.f; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_3d_texel_X4R4G4B4( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *texel ) +{ + const GLushort *src = USHORT_SRC( texImage, i, j, k ); + GLchan *rgba = (GLchan *) texel; GLushort s = *src; + rgba[RCOMP] = UBYTE_TO_CHAN( ((s >> 8) & 0xf) * 255 / 0xf ); + rgba[GCOMP] = UBYTE_TO_CHAN( ((s >> 4) & 0xf) * 255 / 0xf ); + rgba[BCOMP] = UBYTE_TO_CHAN( ((s ) & 0xf) * 255 / 0xf ); + rgba[ACOMP] = CHAN_MAX; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_3d_texel_f_X4R4G4B4( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLfloat *texel ) +{ + const GLushort *src = USHORT_SRC( texImage, i, j, k ); + GLushort s = *src; + texel[RCOMP] = UBYTE_TO_FLOAT( ((s >> 8) & 0xf) * 255 / 0xf ); + texel[GCOMP] = UBYTE_TO_FLOAT( ((s >> 4) & 0xf) * 255 / 0xf ); + texel[BCOMP] = UBYTE_TO_FLOAT( ((s ) & 0xf) * 255 / 0xf ); + texel[ACOMP] = 1.f; +} + +//--------------------------------------------------------------------------- + +#undef CHAN_SRC +#undef UBYTE_SRC +#undef USHORT_SRC +#undef FLOAT_SRC + +//--------------------------------------------------------------------------- +// Direct3D texture formats that have no Mesa equivalent +//--------------------------------------------------------------------------- + +const struct gl_texture_format _gld_texformat_X8R8G8B8 = { + MESA_FORMAT_ARGB8888, /* MesaFormat */ + GL_RGBA, /* BaseFormat */ + GL_UNSIGNED_NORMALIZED_ARB, /* DataType */ + 8, /* RedBits */ + 8, /* GreenBits */ + 8, /* BlueBits */ + 0, /* AlphaBits */ + 0, /* LuminanceBits */ + 0, /* IntensityBits */ + 0, /* IndexBits */ + 0, /* DepthBits */ + 4, /* TexelBytes */ + _mesa_texstore_argb8888, /* StoreTexImageFunc */ + gld_fetch_1d_texel_X8R8G8B8, /* FetchTexel1D */ + gld_fetch_2d_texel_X8R8G8B8, /* FetchTexel2D */ + gld_fetch_3d_texel_X8R8G8B8, /* FetchTexel3D */ + gld_fetch_1d_texel_f_X8R8G8B8, /* FetchTexel1Df */ + gld_fetch_2d_texel_f_X8R8G8B8, /* FetchTexel2Df */ + gld_fetch_3d_texel_f_X8R8G8B8, /* FetchTexel3Df */ +}; + +const struct gl_texture_format _gld_texformat_X1R5G5B5 = { + MESA_FORMAT_ARGB1555, /* MesaFormat */ + GL_RGBA, /* BaseFormat */ + GL_UNSIGNED_NORMALIZED_ARB, /* DataType */ + 5, /* RedBits */ + 5, /* GreenBits */ + 5, /* BlueBits */ + 0, /* AlphaBits */ + 0, /* LuminanceBits */ + 0, /* IntensityBits */ + 0, /* IndexBits */ + 0, /* DepthBits */ + 2, /* TexelBytes */ + _mesa_texstore_argb1555, /* StoreTexImageFunc */ + gld_fetch_1d_texel_X1R5G5B5, /* FetchTexel1D */ + gld_fetch_2d_texel_X1R5G5B5, /* FetchTexel2D */ + gld_fetch_3d_texel_X1R5G5B5, /* FetchTexel3D */ + gld_fetch_1d_texel_f_X1R5G5B5, /* FetchTexel1Df */ + gld_fetch_2d_texel_f_X1R5G5B5, /* FetchTexel2Df */ + gld_fetch_3d_texel_f_X1R5G5B5, /* FetchTexel3Df */ +}; + +const struct gl_texture_format _gld_texformat_X4R4G4B4 = { + MESA_FORMAT_ARGB4444, /* MesaFormat */ + GL_RGBA, /* BaseFormat */ + GL_UNSIGNED_NORMALIZED_ARB, /* DataType */ + 4, /* RedBits */ + 4, /* GreenBits */ + 4, /* BlueBits */ + 0, /* AlphaBits */ + 0, /* LuminanceBits */ + 0, /* IntensityBits */ + 0, /* IndexBits */ + 0, /* DepthBits */ + 2, /* TexelBytes */ + _mesa_texstore_argb4444, /* StoreTexImageFunc */ + gld_fetch_1d_texel_X4R4G4B4, /* FetchTexel1D */ + gld_fetch_2d_texel_X4R4G4B4, /* FetchTexel2D */ + gld_fetch_3d_texel_X4R4G4B4, /* FetchTexel3D */ + gld_fetch_1d_texel_f_X4R4G4B4, /* FetchTexel1Df */ + gld_fetch_2d_texel_f_X4R4G4B4, /* FetchTexel2Df */ + gld_fetch_3d_texel_f_X4R4G4B4, /* FetchTexel3Df */ +}; + +//--------------------------------------------------------------------------- +// Texture unit constants +//--------------------------------------------------------------------------- + +// List of possible combinations of texture environments. +// Example: GLD_TEXENV_MODULATE_RGBA means +// GL_MODULATE, GL_RGBA base internal format. +#define GLD_TEXENV_DECAL_RGB 0 +#define GLD_TEXENV_DECAL_RGBA 1 +#define GLD_TEXENV_DECAL_ALPHA 2 +#define GLD_TEXENV_REPLACE_RGB 3 +#define GLD_TEXENV_REPLACE_RGBA 4 +#define GLD_TEXENV_REPLACE_ALPHA 5 +#define GLD_TEXENV_MODULATE_RGB 6 +#define GLD_TEXENV_MODULATE_RGBA 7 +#define GLD_TEXENV_MODULATE_ALPHA 8 +#define GLD_TEXENV_BLEND_RGB 9 +#define GLD_TEXENV_BLEND_RGBA 10 +#define GLD_TEXENV_BLEND_ALPHA 11 +#define GLD_TEXENV_ADD_RGB 12 +#define GLD_TEXENV_ADD_RGBA 13 +#define GLD_TEXENV_ADD_ALPHA 14 + +// Per-stage (i.e. per-unit) texture environment +typedef struct { + DWORD ColorArg1; // Colour argument 1 + D3DTEXTUREOP ColorOp; // Colour operation + DWORD ColorArg2; // Colour argument 2 + DWORD AlphaArg1; // Alpha argument 1 + D3DTEXTUREOP AlphaOp; // Alpha operation + DWORD AlphaArg2; // Alpha argument 2 +} GLD_texenv; + +// TODO: Do we really need to set ARG1 and ARG2 every time? +// They seem to always be TEXTURE and CURRENT respectively. + +// C = Colour out +// A = Alpha out +// Ct = Colour from Texture +// Cf = Colour from fragment (diffuse) +// At = Alpha from Texture +// Af = Alpha from fragment (diffuse) +// Cc = GL_TEXTURE_ENV_COLOUR (GL_BLEND) +const GLD_texenv gldTexEnv[] = { + // DECAL_RGB: C=Ct, A=Af + {D3DTA_TEXTURE, D3DTOP_SELECTARG1, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT}, + // DECAL_RGBA: C=Cf(1-At)+CtAt, A=Af + {D3DTA_TEXTURE, D3DTOP_BLENDTEXTUREALPHA, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT}, + // DECAL_ALPHA: use DECAL_RGB + {D3DTA_TEXTURE, D3DTOP_SELECTARG1, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT}, + + // REPLACE_RGB: C=Ct, A=Af + {D3DTA_TEXTURE, D3DTOP_SELECTARG1, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT}, + // REPLACE_RGBA: C=Ct, A=At + {D3DTA_TEXTURE, D3DTOP_SELECTARG1, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_SELECTARG1, D3DTA_CURRENT}, + // REPLACE_ALPHA: C=Cf, A=At + {D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_SELECTARG1, D3DTA_CURRENT}, + + // MODULATE_RGB: C=CfCt, A=Af + {D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT}, + // MODULATE_RGBA: C=CfCt, A=AfAt + {D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT}, + // MODULATE_ALPHA: C=Cf, A=AfAt + {D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT}, + + // + // DX7 Does not support D3DTOP_LERP + // Emulate(?) via D3DTOP_ADDSMOOTH + // +#if 0 + // BLEND_RGB: C=Cf(1-Ct)+CcCt, A=Af + {D3DTA_TEXTURE, D3DTOP_LERP, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT}, + // BLEND_RGBA: C=Cf(1-Ct)+CcCt, A=AfAt + {D3DTA_TEXTURE, D3DTOP_LERP, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT}, +#else + // BLEND_RGB: C=Cf(1-Ct)+CcCt, A=Af + {D3DTA_TEXTURE, D3DTOP_ADDSMOOTH, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT}, + // BLEND_RGBA: C=Cf(1-Ct)+CcCt, A=AfAt + {D3DTA_TEXTURE, D3DTOP_ADDSMOOTH, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT}, +#endif + // BLEND_ALPHA: C=Cf, A=AfAt + {D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT}, + + // ADD_RGB: C=Cf+Ct, A=Af + {D3DTA_TEXTURE, D3DTOP_ADD, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT}, + // ADD_RGBA: C=Cf+Ct, A=AfAt + {D3DTA_TEXTURE, D3DTOP_ADD, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT}, + // ADD_ALPHA: C=Cf, A=AfAt + {D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT}, +}; + +//--------------------------------------------------------------------------- + +D3DTEXTUREADDRESS _gldConvertWrap( + GLenum wrap) +{ +// ASSERT(wrap==GL_CLAMP || wrap==GL_REPEAT); + return (wrap == GL_CLAMP) ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP; +} + +//--------------------------------------------------------------------------- + +D3DTEXTUREMAGFILTER _gldConvertMagFilter( + GLenum magfilter) +{ + ASSERT(magfilter==GL_LINEAR || magfilter==GL_NEAREST); + return (magfilter == GL_LINEAR) ? D3DTFG_LINEAR : D3DTFG_POINT; +} + +//--------------------------------------------------------------------------- + +void _gldConvertMinFilter( + GLenum minfilter, + D3DTEXTUREMINFILTER *min_filter, + D3DTEXTUREMIPFILTER *mip_filter) +{ + switch (minfilter) { + case GL_NEAREST: + *min_filter = D3DTFN_POINT; + *mip_filter = D3DTFP_NONE; + break; + case GL_LINEAR: + *min_filter = D3DTFN_LINEAR; + *mip_filter = D3DTFP_NONE; + break; + case GL_NEAREST_MIPMAP_NEAREST: + *min_filter = D3DTFN_POINT; + *mip_filter = D3DTFP_POINT; + break; + case GL_LINEAR_MIPMAP_NEAREST: + *min_filter = D3DTFN_LINEAR; + *mip_filter = D3DTFP_POINT; + break; + case GL_NEAREST_MIPMAP_LINEAR: + *min_filter = D3DTFN_POINT; + *mip_filter = D3DTFP_LINEAR; + break; + case GL_LINEAR_MIPMAP_LINEAR: + *min_filter = D3DTFN_LINEAR; + *mip_filter = D3DTFP_LINEAR; + break; + default: + ASSERT(0); + } +} + +//--------------------------------------------------------------------------- + +D3DX_SURFACEFORMAT _gldGLFormatToD3DFormat( + GLenum internalFormat) +{ + switch (internalFormat) { + case GL_INTENSITY: + case GL_INTENSITY4: + case GL_INTENSITY8: + case GL_INTENSITY12: + case GL_INTENSITY16: + // LUNIMANCE != INTENSITY, but D3D doesn't have I8 textures + return D3DX_SF_L8; + case 1: + case GL_LUMINANCE: + case GL_LUMINANCE4: + case GL_LUMINANCE8: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + return D3DX_SF_L8; + case GL_ALPHA: + case GL_ALPHA4: + case GL_ALPHA8: + case GL_ALPHA12: + case GL_ALPHA16: + return D3DX_SF_A8; + case GL_COLOR_INDEX: + case GL_COLOR_INDEX1_EXT: + case GL_COLOR_INDEX2_EXT: + case GL_COLOR_INDEX4_EXT: + case GL_COLOR_INDEX8_EXT: + case GL_COLOR_INDEX12_EXT: + case GL_COLOR_INDEX16_EXT: + return D3DX_SF_X8R8G8B8; + case 2: + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE4_ALPHA4: + case GL_LUMINANCE6_ALPHA2: + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE12_ALPHA4: + case GL_LUMINANCE12_ALPHA12: + case GL_LUMINANCE16_ALPHA16: + return D3DX_SF_A8L8; + case GL_R3_G3_B2: + // TODO: Mesa does not support RGB332 internally + return D3DX_SF_X4R4G4B4; //D3DFMT_R3G3B2; + case GL_RGB4: + return D3DX_SF_X4R4G4B4; + case GL_RGB5: + return D3DX_SF_R5G5B5; + case 3: + case GL_RGB: + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + return D3DX_SF_R8G8B8; + case GL_RGBA4: + return D3DX_SF_A4R4G4B4; + case 4: + case GL_RGBA: + case GL_RGBA2: + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + return D3DX_SF_A8R8G8B8; + case GL_RGB5_A1: + return D3DX_SF_A1R5G5B5; + } + + ASSERT(0); + + // Return an acceptable default + return D3DX_SF_A8R8G8B8; +} + +//--------------------------------------------------------------------------- + +GLenum _gldDecodeBaseFormat( + IDirectDrawSurface7 *pTex) +{ + // Examine Direct3D texture and return base OpenGL internal texture format + // NOTE: We can't use any base format info from Mesa because D3D might have + // used a different texture format when we used D3DXCreateTexture(). + + // Base internal format is one of (Red Book p355): + // GL_ALPHA, + // GL_LUMINANCE, + // GL_LUMINANCE_ALPHA, + // GL_INTENSITY, + // GL_RGB, + // GL_RGBA + + // NOTE: INTENSITY not used (not supported by Direct3D) + // LUMINANCE has same texture functions as RGB + // LUMINANCE_ALPHA has same texture functions as RGBA + + // TODO: cache format instead of using GetLevelDesc() +// D3DSURFACE_DESC desc; +// _GLD_DX7_TEX(GetLevelDesc(pTex, 0, &desc)); + + D3DX_SURFACEFORMAT sf; + + sf = _gldD3DXFormatFromSurface(pTex); + + switch (sf) { + case D3DX_SF_R8G8B8: + case D3DX_SF_X8R8G8B8: + case D3DX_SF_R5G6B5: + case D3DX_SF_R5G5B5: + case D3DX_SF_R3G3B2: + case D3DX_SF_X4R4G4B4: + case D3DX_SF_PALETTE8: + case D3DX_SF_L8: + return GL_RGB; + case D3DX_SF_A8R8G8B8: + case D3DX_SF_A1R5G5B5: + case D3DX_SF_A4R4G4B4: +// case D3DX_SF_A8R3G3B2: // Unsupported by DX7 +// case D3DX_SF_A8P8: // Unsupported by DX7 + case D3DX_SF_A8L8: +// case D3DX_SF_A4L4: // Unsupported by DX7 + return GL_RGBA; + case D3DX_SF_A8: + return GL_ALPHA; + // Compressed texture formats. Need to check these... + case D3DX_SF_DXT1: + return GL_RGBA; +// case D3DX_SF_DXT2: // Unsupported by DX7 + return GL_RGB; + case D3DX_SF_DXT3: + return GL_RGBA; +// case D3DX_SF_DXT4: // Unsupported by DX7 + return GL_RGB; + case D3DX_SF_DXT5: + return GL_RGBA; + } + + // Fell through. Return arbitary default. + ASSERT(0); // BANG! + return GL_RGBA; +} + +//--------------------------------------------------------------------------- + +const struct gl_texture_format* _gldMesaFormatForD3DFormat( + D3DX_SURFACEFORMAT d3dfmt) +{ + switch (d3dfmt) { + case D3DX_SF_A8R8G8B8: + return &_mesa_texformat_argb8888; + case D3DX_SF_R8G8B8: + return &_mesa_texformat_rgb888; + case D3DX_SF_R5G6B5: + return &_mesa_texformat_rgb565; + case D3DX_SF_A4R4G4B4: + return &_mesa_texformat_argb4444; + case D3DX_SF_A1R5G5B5: + return &_mesa_texformat_argb1555; + case D3DX_SF_A8L8: + return &_mesa_texformat_al88; + case D3DX_SF_R3G3B2: + return &_mesa_texformat_rgb332; + case D3DX_SF_A8: + return &_mesa_texformat_a8; + case D3DX_SF_L8: + return &_mesa_texformat_l8; + case D3DX_SF_X8R8G8B8: + return &_gld_texformat_X8R8G8B8; + case D3DX_SF_R5G5B5: + return &_gld_texformat_X1R5G5B5; + case D3DX_SF_X4R4G4B4: + return &_gld_texformat_X4R4G4B4; + } + + // If we reach here then we've made an error somewhere else + // by allowing a format that is not supported. + ASSERT(0); + + return NULL; // Shut up compiler warning +} + +//--------------------------------------------------------------------------- + +D3DX_SURFACEFORMAT _gldD3DXFormatFromSurface( + IDirectDrawSurface7 *pSurface) +{ + DDPIXELFORMAT ddpf; + + ddpf.dwSize = sizeof(ddpf); + + // Obtain pixel format of surface + _GLD_DX7_TEX(GetPixelFormat(pSurface, &ddpf)); + // Decode to D3DX surface format + return D3DXMakeSurfaceFormat(&ddpf); +} + +//--------------------------------------------------------------------------- + +void _gldClearSurface( + IDirectDrawSurface *pSurface, + D3DCOLOR dwColour) +{ + DDBLTFX bltFX; // Used for colour fill + + // Initialise struct + bltFX.dwSize = sizeof(bltFX); + // Set clear colour + bltFX.dwFillColor = dwColour; + // Clear surface. HW accelerated if available. + IDirectDrawSurface7_Blt(pSurface, NULL, NULL, NULL, DDBLT_COLORFILL, &bltFX); +} + +//--------------------------------------------------------------------------- +// Copy* functions +//--------------------------------------------------------------------------- + +void gldCopyTexImage1D_DX7( + GLcontext *ctx, + GLenum target, GLint level, + GLenum internalFormat, + GLint x, GLint y, + GLsizei width, GLint border ) +{ + // TODO +} + +//--------------------------------------------------------------------------- + +void gldCopyTexImage2D_DX7( + GLcontext *ctx, + GLenum target, + GLint level, + GLenum internalFormat, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLint border) +{ + // TODO +} + +//--------------------------------------------------------------------------- + +void gldCopyTexSubImage1D_DX7( + GLcontext *ctx, + GLenum target, GLint level, + GLint xoffset, GLint x, GLint y, GLsizei width ) +{ + // TODO +} + +//--------------------------------------------------------------------------- + +void gldCopyTexSubImage2D_DX7( + GLcontext *ctx, + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height) +{ + // TODO +} + +//--------------------------------------------------------------------------- + +void gldCopyTexSubImage3D_DX7( + GLcontext *ctx, + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height ) +{ + // TODO ? +} + +//--------------------------------------------------------------------------- +// Bitmap/Pixel functions +//--------------------------------------------------------------------------- + +#define GLD_FLIP_Y(y) (gldCtx->dwHeight - (y)) + +#define _GLD_FVF_IMAGE (D3DFVF_XYZRHW | D3DFVF_TEX1) + +typedef struct { + FLOAT x, y; // 2D raster coords + FLOAT z; // depth value + FLOAT rhw; // reciprocal homogenous W (always 1.0f) + FLOAT tu, tv; // texture coords +} _GLD_IMAGE_VERTEX; + +//--------------------------------------------------------------------------- + +HRESULT _gldDrawPixels( + GLcontext *ctx, + BOOL bChromakey, // Alpha test for glBitmap() images + GLint x, // GL x position + GLint y, // GL y position (needs flipping) + GLsizei width, // Width of input image + GLsizei height, // Height of input image + IDirectDrawSurface7 *pImage) +{ + // + // Draw input image as texture implementing PixelZoom and clipping. + // Any fragment operations currently enabled will be used. + // + + // NOTE: This DX7 version does not create a new texture in which + // to copy the input image, as the image is already a texture. + + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); + + DDSURFACEDESC2 ddsd; + _GLD_IMAGE_VERTEX v[4]; + + float ZoomWidth, ZoomHeight; + float ScaleWidth, ScaleHeight; + + // Fixup for rasterisation rules + const float cfEpsilon = 1.0f / (float)height; + + // + // Set up the quad like this (ascii-art ahead!) + // + // 3--2 + // | | + // 0--1 + // + // + + // Set depth + v[0].z = v[1].z = v[2].z = v[3].z = ctx->Current.RasterPos[2]; + // Set Reciprocal Homogenous W + v[0].rhw = v[1].rhw = v[2].rhw = v[3].rhw = 1.0f; + + // Set texcoords + // Examine texture size - if different to input width and height + // then we'll need to munge the texcoords to fit. + ddsd.dwSize = sizeof(DDSURFACEDESC2); + IDirectDrawSurface7_GetSurfaceDesc(pImage, &ddsd); + ScaleWidth = (float)width / (float)ddsd.dwWidth; + ScaleHeight = (float)height / (float)ddsd.dwHeight; + v[0].tu = 0.0f; v[0].tv = 0.0f; + v[1].tu = ScaleWidth; v[1].tv = 0.0f; + v[2].tu = ScaleWidth; v[2].tv = ScaleHeight; + v[3].tu = 0.0f; v[3].tv = ScaleHeight; + + // Set raster positions + ZoomWidth = (float)width * ctx->Pixel.ZoomX; + ZoomHeight = (float)height * ctx->Pixel.ZoomY; + + v[0].x = x; v[0].y = GLD_FLIP_Y(y+cfEpsilon); + v[1].x = x+ZoomWidth; v[1].y = GLD_FLIP_Y(y+cfEpsilon); + v[2].x = x+ZoomWidth; v[2].y = GLD_FLIP_Y(y+ZoomHeight+cfEpsilon); + v[3].x = x; v[3].y = GLD_FLIP_Y(y+ZoomHeight+cfEpsilon); + + // Draw image with full HW acceleration + // NOTE: Be nice to use a State Block for all this state... + IDirect3DDevice7_SetTexture(gld->pDev, 0, pImage); + IDirect3DDevice7_SetRenderState(gld->pDev, D3DRENDERSTATE_CULLMODE, D3DCULL_NONE); + IDirect3DDevice7_SetRenderState(gld->pDev, D3DRENDERSTATE_CLIPPING, TRUE); + IDirect3DDevice7_SetTextureStageState(gld->pDev, 0, D3DTSS_MINFILTER, D3DTFN_POINT); + IDirect3DDevice7_SetTextureStageState(gld->pDev, 0, D3DTSS_MIPFILTER, D3DTFP_POINT); + IDirect3DDevice7_SetTextureStageState(gld->pDev, 0, D3DTSS_MAGFILTER, D3DTFG_POINT); + IDirect3DDevice7_SetTextureStageState(gld->pDev, 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); + IDirect3DDevice7_SetTextureStageState(gld->pDev, 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); + IDirect3DDevice7_SetTextureStageState(gld->pDev, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + IDirect3DDevice7_SetTextureStageState(gld->pDev, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + IDirect3DDevice7_SetTextureStageState(gld->pDev, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + IDirect3DDevice7_SetTextureStageState(gld->pDev, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + // Ensure texture unit 1 is disabled + IDirect3DDevice7_SetTextureStageState(gld->pDev, 1, D3DTSS_COLOROP, D3DTOP_DISABLE); + IDirect3DDevice7_SetTextureStageState(gld->pDev, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + // + // Emulate Chromakey with an Alpha Test. + // [Alpha Test is more widely supported anyway] + // + if (bChromakey) { + // Switch on alpha testing + IDirect3DDevice7_SetRenderState(gld->pDev, D3DRENDERSTATE_ALPHATESTENABLE, TRUE); + // Fragment passes is alpha is greater than reference value + IDirect3DDevice7_SetRenderState(gld->pDev, D3DRENDERSTATE_ALPHAFUNC, D3DCMP_GREATER); + // Set alpha reference value between Bitmap alpha values of + // zero (transparent) and one (opaque). + IDirect3DDevice7_SetRenderState(gld->pDev, D3DRENDERSTATE_ALPHAREF, 0x7f); + } + + IDirect3DDevice7_DrawPrimitive(gld->pDev, D3DPT_TRIANGLEFAN, _GLD_FVF_IMAGE, &v, 4, 0); + + // Reset state to before we messed it up + FLUSH_VERTICES(ctx, _NEW_ALL); + + return S_OK; +} + +//--------------------------------------------------------------------------- + +void gld_DrawPixels_DX7( + GLcontext *ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid *pixels ) +{ + GLD_context *gldCtx; + GLD_driver_dx7 *gld; + + IDirectDrawSurface7 *pImage; + HRESULT hr; + DDSURFACEDESC2 ddsd; + DWORD dwFlags; + D3DX_SURFACEFORMAT sf; + DWORD dwMipmaps; + + const struct gl_texture_format *MesaFormat; + + MesaFormat = _mesa_choose_tex_format(ctx, format, format, type); + + gldCtx = GLD_GET_CONTEXT(ctx); + gld = GLD_GET_DX7_DRIVER(gldCtx); + + dwFlags = D3DX_TEXTURE_NOMIPMAP; + sf = D3DX_SF_A8R8G8B8; + dwMipmaps = 1; + + hr = D3DXCreateTexture( + gld->pDev, + &dwFlags, + &width, &height, + &sf, // format + NULL, // palette + &pImage, // Output texture + &dwMipmaps); + if (FAILED(hr)) { + return; + } + + // D3DXCreateTexture() may not clear the texture is creates. + _gldClearSurface(pImage, 0); + + // + // Use Mesa to fill in image + // + + // Lock all of surface + ddsd.dwSize = sizeof(DDSURFACEDESC2); + dwFlags = DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT; + hr = IDirectDrawSurface7_Lock(pImage, NULL, &ddsd, dwFlags, NULL); + if (FAILED(hr)) { + SAFE_RELEASE_SURFACE7(pImage); + return; + } + + // unpack image, apply transfer ops and store directly in texture + MesaFormat->StoreImage( + ctx, + 2, + GL_RGBA, + &_mesa_texformat_argb8888, + ddsd.lpSurface, + width, height, 1, 0, 0, 0, + ddsd.lPitch, + 0, /* dstImageStride */ + format, type, pixels, unpack); + + IDirectDrawSurface7_Unlock(pImage, NULL); + + _gldDrawPixels(ctx, FALSE, x, y, width, height, pImage); + + SAFE_RELEASE_SURFACE7(pImage); +} + +//--------------------------------------------------------------------------- + +void gld_ReadPixels_DX7( + GLcontext *ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *pack, + GLvoid *dest) +{ +// TODO +#if 0 + GLD_context *gldCtx; + GLD_driver_dx7 *gld; + + IDirect3DSurface8 *pBackbuffer = NULL; + IDirect3DSurface8 *pNativeImage = NULL; + IDirect3DSurface8 *pCanonicalImage = NULL; + + D3DSURFACE_DESC d3dsd; + RECT rcSrc; // Source rect + POINT ptDst; // Dest point + HRESULT hr; + D3DLOCKED_RECT d3dLockedRect; + struct gl_pixelstore_attrib srcPacking; + int i; + GLint DstRowStride; + const struct gl_texture_format *MesaFormat; + + switch (format) { + case GL_STENCIL_INDEX: + case GL_DEPTH_COMPONENT: + return; + } + + MesaFormat = _mesa_choose_tex_format(ctx, format, format, type); + DstRowStride = _mesa_image_row_stride(pack, width, format, type); + + gldCtx = GLD_GET_CONTEXT(ctx); + gld = GLD_GET_DX7_DRIVER(gldCtx); + + // Get backbuffer + hr = IDirect3DDevice8_GetBackBuffer( + gld->pDev, + 0, // First backbuffer + D3DBACKBUFFER_TYPE_MONO, + &pBackbuffer); + if (FAILED(hr)) + return; + + // Get backbuffer description + hr = IDirect3DSurface8_GetDesc(pBackbuffer, &d3dsd); + if (FAILED(hr)) { + goto gld_ReadPixels_DX7_return; + } + + // Create a surface compatible with backbuffer + hr = IDirect3DDevice8_CreateImageSurface( + gld->pDev, + width, + height, + d3dsd.Format, + &pNativeImage); + if (FAILED(hr)) { + goto gld_ReadPixels_DX7_return; + } + + // Compute source rect and dest point + SetRect(&rcSrc, 0, 0, width, height); + OffsetRect(&rcSrc, x, GLD_FLIP_HEIGHT(y, height)); + ptDst.x = ptDst.y = 0; + + // Get source pixels. + // + // This intermediate surface ensure that we can use CopyRects() + // instead of relying on D3DXLoadSurfaceFromSurface(), which may + // try and lock the backbuffer. This way seems safer. + // + hr = IDirect3DDevice8_CopyRects( + gld->pDev, + pBackbuffer, + &rcSrc, + 1, + pNativeImage, + &ptDst); + if (FAILED(hr)) { + goto gld_ReadPixels_DX7_return; + } + + // Create an RGBA8888 surface + hr = IDirect3DDevice8_CreateImageSurface( + gld->pDev, + width, + height, + D3DFMT_A8R8G8B8, + &pCanonicalImage); + if (FAILED(hr)) { + goto gld_ReadPixels_DX7_return; + } + + // Convert to RGBA8888 + hr = D3DXLoadSurfaceFromSurface( + pCanonicalImage, // Dest surface + NULL, NULL, // Dest palette, RECT + pNativeImage, // Src surface + NULL, NULL, // Src palette, RECT + D3DX_FILTER_NONE, // Filter + 0); // Colourkey + if (FAILED(hr)) { + goto gld_ReadPixels_DX7_return; + } + + srcPacking.Alignment = 1; + srcPacking.ImageHeight = height; + srcPacking.LsbFirst = GL_FALSE; + srcPacking.RowLength = 0; + srcPacking.SkipImages = 0; + srcPacking.SkipPixels = 0; + srcPacking.SkipRows = 0; + srcPacking.SwapBytes = GL_FALSE; + + // Lock all of image + hr = IDirect3DSurface8_LockRect(pCanonicalImage, &d3dLockedRect, NULL, 0); + if (FAILED(hr)) { + goto gld_ReadPixels_DX7_return; + } + + // We need to flip the data. Yuck. + // Perhaps Mesa has a span packer we can use in future... + for (i=0; iTexFormat->StoreImage( + ctx, + 2, + GL_RGBA, // base format + MesaFormat, // dst format + pDestRow, // dest addr + width, 1, 1, 0, 0, 0, // src x,y,z & dst offsets x,y,z + DstRowStride, // dst row stride + 0, // dstImageStride + GL_BGRA, // src format + GL_UNSIGNED_BYTE, // src type + pSrcRow, // src addr + &srcPacking); // packing params of source image + } + + IDirect3DSurface8_UnlockRect(pCanonicalImage); + +gld_ReadPixels_DX7_return: + SAFE_RELEASE_SURFACE8(pCanonicalImage); + SAFE_RELEASE_SURFACE8(pNativeImage); + SAFE_RELEASE_SURFACE8(pBackbuffer); +#endif +} + +//--------------------------------------------------------------------------- + +void gld_CopyPixels_DX7( + GLcontext *ctx, + GLint srcx, + GLint srcy, + GLsizei width, + GLsizei height, + GLint dstx, + GLint dsty, + GLenum type) +{ +// TODO +#if 0 + // + // NOTE: Not allowed to copy vidmem to vidmem! + // Therefore we use an intermediate image surface. + // + + GLD_context *gldCtx; + GLD_driver_dx7 *gld; + + IDirect3DSurface8 *pBackbuffer; + D3DSURFACE_DESC d3dsd; + IDirect3DSurface8 *pImage; + RECT rcSrc; // Source rect + POINT ptDst; // Dest point + HRESULT hr; + + // Only backbuffer + if (type != GL_COLOR) + return; + + gldCtx = GLD_GET_CONTEXT(ctx); + gld = GLD_GET_DX7_DRIVER(gldCtx); + + // Get backbuffer + hr = IDirect3DDevice8_GetBackBuffer( + gld->pDev, + 0, // First backbuffer + D3DBACKBUFFER_TYPE_MONO, + &pBackbuffer); + if (FAILED(hr)) + return; + + // Get backbuffer description + hr = IDirect3DSurface8_GetDesc(pBackbuffer, &d3dsd); + if (FAILED(hr)) { + IDirect3DSurface8_Release(pBackbuffer); + return; + } + + // Create a surface compatible with backbuffer + hr = IDirect3DDevice8_CreateImageSurface( + gld->pDev, + width, + height, + d3dsd.Format, + &pImage); + if (FAILED(hr)) { + IDirect3DSurface8_Release(pBackbuffer); + return; + } + + // Compute source rect and dest point + SetRect(&rcSrc, 0, 0, width, height); + OffsetRect(&rcSrc, srcx, GLD_FLIP_HEIGHT(srcy, height)); + ptDst.x = ptDst.y = 0; + + // Get source pixels + hr = IDirect3DDevice8_CopyRects( + gld->pDev, + pBackbuffer, + &rcSrc, + 1, + pImage, + &ptDst); + IDirect3DSurface8_Release(pBackbuffer); + if (FAILED(hr)) { + IDirect3DSurface8_Release(pImage); + return; + } + + _gldDrawPixels(ctx, FALSE, dstx, dsty, width, height, pImage); + + IDirect3DSurface8_Release(pImage); +#endif +} + +//--------------------------------------------------------------------------- + +void gld_Bitmap_DX7( + GLcontext *ctx, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + const struct gl_pixelstore_attrib *unpack, + const GLubyte *bitmap) +{ + GLD_context *gldCtx; + GLD_driver_dx7 *gld; + + IDirectDrawSurface7 *pImage; // Bitmap texture + HRESULT hr; + BYTE *pTempBitmap; // Pointer to unpacked bitmap + D3DCOLOR clBitmapOne; // Opaque bitmap colour + D3DCOLOR clBitmapZero; // Transparent bitmap colour + D3DCOLOR *pBits; // Pointer to texture surface + const GLubyte *src; + int i, j, k; + + DDSURFACEDESC2 ddsd; // Surface desc returned by lock call + DWORD dwFlags; + D3DX_SURFACEFORMAT sf; + DWORD dwMipmaps; + + // Keep a copy of width/height as D3DXCreateTexture() call may alter input dimensions + GLsizei dwWidth = width; + GLsizei dwHeight = height; + + gldCtx = GLD_GET_CONTEXT(ctx); + gld = GLD_GET_DX7_DRIVER(gldCtx); + + // Bail if no bitmap (only raster pos is updated) + if ((bitmap == NULL) && (width==0) && (height==0)) + return; + + // + // TODO: Detect conditions when created texture (pImage) is non-pow2. + // Texture coords may need to be adjusted to compensate. + // + + clBitmapZero = D3DCOLOR_RGBA(0,0,0,0); // NOTE: Alpha is Zero + clBitmapOne = D3DCOLOR_COLORVALUE( + ctx->Current.RasterColor[0], + ctx->Current.RasterColor[1], + ctx->Current.RasterColor[2], + 1.0f); // NOTE: Alpha is One + + // Use Mesa to unpack bitmap into a canonical format + pTempBitmap = _mesa_unpack_bitmap(width, height, bitmap, unpack); + if (pTempBitmap == NULL) + return; + + // Flags for texture creation + dwFlags = D3DX_TEXTURE_NOMIPMAP; + sf = D3DX_SF_A8R8G8B8; + dwMipmaps = 1; + + // Create a D3D texture to hold the bitmap + hr = D3DXCreateTexture( + gld->pDev, + &dwFlags, + &dwWidth, &dwHeight, + &sf, // format + NULL, // palette + &pImage, // Output texture + &dwMipmaps); + if (FAILED(hr)) { + FREE(pTempBitmap); + return; + } + + // D3DXCreateTexture may return a texture bigger than we asked for + // (i.e. padded to POW2) so let's clear the entire image bitmap. + // Additional: Looks like this is not strictly necessary. +// _gldClearSurface(pImage, clBitmapZero); + + ddsd.dwSize = sizeof(DDSURFACEDESC2); + dwFlags = DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT; + hr = IDirectDrawSurface7_Lock(pImage, NULL, &ddsd, dwFlags, NULL); + if (FAILED(hr)) { + FREE(pTempBitmap); + SAFE_RELEASE_SURFACE7(pImage); + return; + } + +#if 0 + // DEBUG CODE + if (!(width==ddsd.dwWidth && height==ddsd.dwHeight)) + ddlogPrintf(GLDLOG_WARN, "gld_Bitmap: In=%d,%d / Tex=%d,%d", width,height,ddsd.dwWidth,ddsd.dwHeight); +#endif + +#if 0 + // DEBUG CODE + ddlogPrintf(GLDLOG_SYSTEM, "gld_Bitmap: In=%d,%d / Tex=%d,%d", width,height,ddsd.dwWidth,ddsd.dwHeight); + ddlogPrintf(GLDLOG_SYSTEM, "gld_Bitmap: bpp=%d", ddsd.ddpfPixelFormat.dwRGBBitCount); +#endif + + // Cast texel pointer to texture surface. + // We can do this because we used D3DX_SF_A8R8G8B8 as the format + pBits = (D3DCOLOR*)ddsd.lpSurface; + + + // Copy from the input bitmap into the texture + for (i=0; iDefaultPacking, pTempBitmap, width, height, GL_COLOR_INDEX, GL_BITMAP, + 0, i, 0); + for (j=0; j<(width>>3); j++) { + byte = *src++; + for (k=0; k<8; k++) { + *pBits++ = (byte & 128) ? clBitmapOne : clBitmapZero; + byte <<= 1; + } + } + // Fill remaining bits from bitmap + if (width & 7) { + byte = *src; + for (k=0; k<(width & 7); k++) { + *pBits++ = (byte & 128) ? clBitmapOne : clBitmapZero; + byte <<= 1; + } + } + } + + // We're done with the unpacked bitmap + FREE(pTempBitmap); + + // Finished with texture surface - unlock it + IDirectDrawSurface7_Unlock(pImage, NULL); + + // Use internal function to draw bitmap onto rendertarget + _gldDrawPixels(ctx, TRUE, x, y, width, height, pImage); + + // We're done with the bitmap texure - release it + IDirectDrawSurface7_Release(pImage); +} + +//--------------------------------------------------------------------------- +// Texture functions +//--------------------------------------------------------------------------- + +void _gldAllocateTexture( + GLcontext *ctx, + struct gl_texture_object *tObj, + struct gl_texture_image *texImage) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); + + HRESULT hr; + IDirectDrawSurface7 *pTex; + D3DX_SURFACEFORMAT d3dFormat; + DWORD dwFlags; + DWORD dwMipmaps; + DWORD dwWidth, dwHeight; + + if (!tObj || !texImage) + return; + + pTex = (IDirectDrawSurface7*)tObj->DriverData; + if (pTex) { + // Decide whether we can keep existing D3D texture + // by examining top-level surface. + DDSURFACEDESC2 ddsd; + ddsd.dwSize = sizeof(DDSURFACEDESC2); + _GLD_DX7_TEX(GetSurfaceDesc(pTex, &ddsd)); + // Release existing texture if not compatible + if ((ddsd.dwWidth == texImage->Width) || + (ddsd.dwHeight == texImage->Height)) + { + return; // Keep the existing texture + } + tObj->DriverData = NULL; + _GLD_DX7_TEX(Release(pTex)); + } + + dwFlags = (glb.bUseMipmaps) ? 0 : D3DX_TEXTURE_NOMIPMAP; + dwMipmaps = (glb.bUseMipmaps) ? D3DX_DEFAULT : 1; + dwWidth = texImage->Width; + dwHeight = texImage->Height; + + d3dFormat = _gldGLFormatToD3DFormat(texImage->IntFormat); + hr = D3DXCreateTexture( + gld->pDev, + &dwFlags, + &dwWidth, + &dwHeight, + &d3dFormat, + NULL, + &pTex, + &dwMipmaps); + if (FAILED(hr)) { + gldLogError(GLDLOG_ERROR, "AllocateTexture failed", hr); + } + tObj->DriverData = pTex; +} + +//--------------------------------------------------------------------------- + +const struct gl_texture_format* gld_ChooseTextureFormat_DX7( + GLcontext *ctx, + GLint internalFormat, + GLenum srcFormat, + GLenum srcType) +{ + // [Based on mesa_choose_tex_format()] + // + // We will choose only texture formats that are supported + // by Direct3D. If the hardware doesn't support a particular + // texture format, then the D3DX texture calls that we use + // will automatically use a HW supported format. + // + // The most critical aim is to reduce copying; if we can use + // texture-image data directly then it will be a big performance assist. + // + + switch (internalFormat) { + case GL_INTENSITY: + case GL_INTENSITY4: + case GL_INTENSITY8: + case GL_INTENSITY12: + case GL_INTENSITY16: + return &_mesa_texformat_l8; // D3DFMT_L8 + case 1: + case GL_LUMINANCE: + case GL_LUMINANCE4: + case GL_LUMINANCE8: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + return &_mesa_texformat_l8; // D3DFMT_L8 + case GL_ALPHA: + case GL_ALPHA4: + case GL_ALPHA8: + case GL_ALPHA12: + case GL_ALPHA16: + return &_mesa_texformat_a8; // D3DFMT_A8 + case GL_COLOR_INDEX: + case GL_COLOR_INDEX1_EXT: + case GL_COLOR_INDEX2_EXT: + case GL_COLOR_INDEX4_EXT: + case GL_COLOR_INDEX8_EXT: + case GL_COLOR_INDEX12_EXT: + case GL_COLOR_INDEX16_EXT: + return &_mesa_texformat_rgb565; // D3DFMT_R5G6B5 + // Mesa will convert this for us later... + // return &_mesa_texformat_ci8; // D3DFMT_R5G6B5 + case 2: + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE4_ALPHA4: + case GL_LUMINANCE6_ALPHA2: + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE12_ALPHA4: + case GL_LUMINANCE12_ALPHA12: + case GL_LUMINANCE16_ALPHA16: + return &_mesa_texformat_al88; // D3DFMT_A8L8 + case GL_R3_G3_B2: + return &_mesa_texformat_rgb332; // D3DFMT_R3G3B2 + case GL_RGB4: + case GL_RGBA4: + case GL_RGBA2: + return &_mesa_texformat_argb4444; // D3DFMT_A4R4G4B4 + case 3: + case GL_RGB: + case GL_RGB5: + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + return &_mesa_texformat_rgb565; + case 4: + case GL_RGBA: + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + return &_mesa_texformat_argb8888; + case GL_RGB5_A1: + return &_mesa_texformat_argb1555; + default: + _mesa_problem(NULL, "unexpected format in fxDDChooseTextureFormat"); + return NULL; + } +} + +//--------------------------------------------------------------------------- + +/* +// Safer(?), slower version. +void gld_TexImage2D_DX7( + GLcontext *ctx, + GLenum target, + GLint level, + GLint internalFormat, + GLint width, + GLint height, + GLint border, + GLenum format, + GLenum type, + const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *tObj, + struct gl_texture_image *texImage) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); + + IDirect3DTexture8 *pTex; + IDirect3DSurface8 *pSurface; + RECT rcSrcRect; + HRESULT hr; + GLint texelBytes = 4; + GLvoid *tempImage; + + if (!tObj || !texImage) + return; + + if (level == 0) { + _gldAllocateTexture(ctx, tObj, texImage); + } + + pTex = (IDirect3DTexture8*)tObj->DriverData; + if (!pTex) + return; // Texture has not been created + if (level >= IDirect3DTexture8_GetLevelCount(pTex)) + return; // Level does not exist + hr = IDirect3DTexture8_GetSurfaceLevel(pTex, level, &pSurface); + if (FAILED(hr)) + return; // Surface level doesn't exist (or just a plain error) + + tempImage = MALLOC(width * height * texelBytes); + if (!tempImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + IDirect3DSurface8_Release(pSurface); + return; + } + // unpack image, apply transfer ops and store in tempImage + texImage->TexFormat->StoreImage(ctx, 2, texImage->Format, + &_mesa_texformat_argb8888, // dest format + tempImage, + width, height, 1, 0, 0, 0, + width * texelBytes, + 0, // dstImageStride + format, type, pixels, packing); + + SetRect(&rcSrcRect, 0, 0, width, height); + D3DXLoadSurfaceFromMemory( + pSurface, + NULL, + NULL, + tempImage, + D3DFMT_A8R8G8B8, + width * texelBytes, + NULL, + &rcSrcRect, + D3DX_FILTER_NONE, + 0); + + FREE(tempImage); + IDirect3DSurface8_Release(pSurface); +} +*/ + +//--------------------------------------------------------------------------- + +// Faster, more efficient version. +// Copies subimage straight to dest texture +void gld_TexImage2D_DX7( + GLcontext *ctx, + GLenum target, + GLint level, + GLint internalFormat, + GLint width, + GLint height, + GLint border, + GLenum format, + GLenum type, + const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *tObj, + struct gl_texture_image *texImage) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); + + IDirectDrawSurface7 *pTex = NULL; + IDirectDrawSurface7 *pSurface = NULL; + HRESULT hr; + DDSURFACEDESC2 ddsd; + int i; + DDSCAPS2 ddsCaps; + + if (!tObj || !texImage) + return; + + // GLQUAKE FIX + // Test for input alpha data with non-alpha internalformat + if (((internalFormat==3) || (internalFormat==GL_RGB)) && (format==GL_RGBA)) { + // Input format has alpha, but a non-alpha format has been requested. + texImage->IntFormat = GL_RGBA; + internalFormat = GL_RGBA; + } + + if (level == 0) { + _gldAllocateTexture(ctx, tObj, texImage); + } + + pTex = (IDirectDrawSurface7*)tObj->DriverData; + if (!pTex) { + ASSERT(0); + return; // Texture has not been created + } + + pSurface = pTex; + if (level != 0) { + ddsd.dwSize = sizeof(ddsd); + _GLD_DX7_TEX(GetSurfaceDesc(pTex, &ddsd)); + if ((level > 0) && (level >= ddsd.dwMipMapCount)) + return; // Level does not exist + ZeroMemory(&ddsCaps, sizeof(ddsCaps)); + for (i=0; iTexFormat->StoreImage( + ctx, + 2, + texImage->Format, + //_gldMesaFormatForD3DFormat(d3dsd.Format), + _gldMesaFormatForD3DFormat(_gldD3DXFormatFromSurface(pSurface)), + ddsd.lpSurface, + width, height, 1, 0, 0, 0, + ddsd.lPitch, + 0, // dstImageStride + format, type, pixels, packing); + + IDirectDrawSurface7_Unlock(pSurface, NULL); +} + +//--------------------------------------------------------------------------- + +void gld_TexImage1D_DX7(GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint border, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) +{ + // A 1D texture is a 2D texture with a height of zero + gld_TexImage2D_DX7(ctx, target, level, internalFormat, width, 1, border, format, type, pixels, packing, texObj, texImage); +} + +//--------------------------------------------------------------------------- + +/* +void gld_TexSubImage2D( GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *tObj, + struct gl_texture_image *texImage ) +{ + GLD_GET_CONTEXT + IDirect3DTexture8 *pTex; + IDirect3DSurface8 *pSurface; + D3DFORMAT d3dFormat; + HRESULT hr; + GLint texelBytes = 4; + GLvoid *tempImage; + RECT rcSrcRect; + RECT rcDstRect; + + if (!tObj || !texImage) + return; + + pTex = (IDirect3DTexture8*)tObj->DriverData; + if (!pTex) + return; // Texture has not been created + if (level >= _GLD_DX8_TEX(GetLevelCount(pTex)) + return; // Level does not exist + hr = _GLD_DX8_TEX(GetSurfaceLevel(pTex, level, &pSurface); + if (FAILED(hr)) + return; // Surface level doesn't exist (or just a plain error) + + d3dFormat = _gldGLFormatToD3DFormat(texImage->Format); + tempImage = MALLOC(width * height * texelBytes); + if (!tempImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + IDirect3DSurface8_Release(pSurface); + return; + } + + // unpack image, apply transfer ops and store in tempImage + texImage->TexFormat->StoreImage(ctx, 2, texImage->Format, + &_mesa_texformat_argb8888, // dest format + tempImage, + width, height, 1, 0, 0, 0, + width * texelBytes, + 0, // dstImageStride + format, type, pixels, packing); + + // Source rectangle is whole of input image + SetRect(&rcSrcRect, 0, 0, width, height); + + // Dest rectangle must be offset to dest image + SetRect(&rcDstRect, 0, 0, width, height); + OffsetRect(&rcDstRect, xoffset, yoffset); + + D3DXLoadSurfaceFromMemory( + pSurface, + NULL, + &rcDstRect, + tempImage, + D3DFMT_A8R8G8B8, + width * texelBytes, + NULL, + &rcSrcRect, + D3DX_FILTER_NONE, + 0); + + FREE(tempImage); + IDirect3DSurface8_Release(pSurface); +} +*/ + +//--------------------------------------------------------------------------- + +// Faster, more efficient version. +// Copies subimage straight to dest texture +void gld_TexSubImage2D_DX7( GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *tObj, + struct gl_texture_image *texImage ) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); + + IDirectDrawSurface7 *pTex; + IDirectDrawSurface7 *pSurface; + HRESULT hr; + RECT rcDstRect; + DDSURFACEDESC2 ddsd; + int i; + DDSCAPS2 ddsCaps; + + if (!tObj || !texImage) + return; + + pTex = (IDirectDrawSurface7*)tObj->DriverData; + if (!pTex) + return; // Texture has not been created + + __try { + + ddsd.dwSize = sizeof(ddsd); + _GLD_DX7_TEX(GetSurfaceDesc(pTex, &ddsd)); + if ((level > 0) && (level >= ddsd.dwMipMapCount)) + return; // Level does not exist + + ZeroMemory(&ddsCaps, sizeof(ddsCaps)); + pSurface = pTex; + for (i=0; iTexFormat->StoreImage(ctx, 2, texImage->Format, + _gldMesaFormatForD3DFormat(_gldD3DXFormatFromSurface(pSurface)), + ddsd.lpSurface, + width, height, 1, + 0, 0, 0, // NOTE: d3dLockedRect.pBits is already offset!!! + ddsd.lPitch, + 0, // dstImageStride + format, type, pixels, packing); + + + IDirectDrawSurface7_Unlock(pSurface, &rcDstRect); + } + __except(EXCEPTION_EXECUTE_HANDLER) { + ; + } +} + +//--------------------------------------------------------------------------- + +void gld_TexSubImage1D_DX7( GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLsizei width, + GLenum format, GLenum type, + const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) +{ + gld_TexSubImage2D_DX7(ctx, target, level, xoffset, 0, width, 1, format, type, pixels, packing, texObj, texImage); +} + +//--------------------------------------------------------------------------- + +void gld_DeleteTexture_DX7( + GLcontext *ctx, + struct gl_texture_object *tObj) +{ + GLD_context *gld = (GLD_context*)(ctx->DriverCtx); + + __try { + + if (tObj) { + IDirectDrawSurface7 *pTex = (IDirectDrawSurface7*)tObj->DriverData; + if (pTex) { +/* // Make sure texture is not bound to a stage before releasing it + for (int i=0; iCurrentTexture[i] == pTex) { + gld->pDev->SetTexture(i, NULL); + gld->CurrentTexture[i] = NULL; + } + }*/ + _GLD_DX7_TEX(Release(pTex)); + tObj->DriverData = NULL; + } + } + + } + __except(EXCEPTION_EXECUTE_HANDLER) { + ; + } +} + +//--------------------------------------------------------------------------- + +__inline void _gldSetColorOps( + const GLD_driver_dx7 *gld, + GLuint unit, + DWORD ColorArg1, + D3DTEXTUREOP ColorOp, + DWORD ColorArg2) +{ + _GLD_DX7_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_COLORARG1, ColorArg1)); + _GLD_DX7_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_COLOROP, ColorOp)); + _GLD_DX7_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_COLORARG2, ColorArg2)); +} + +//--------------------------------------------------------------------------- + +__inline void _gldSetAlphaOps( + const GLD_driver_dx7 *gld, + GLuint unit, + DWORD AlphaArg1, + D3DTEXTUREOP AlphaOp, + DWORD AlphaArg2) +{ + _GLD_DX7_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_ALPHAARG1, AlphaArg1)); + _GLD_DX7_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_ALPHAOP, AlphaOp)); + _GLD_DX7_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_ALPHAARG2, AlphaArg2)); +} + +//--------------------------------------------------------------------------- + +void gldUpdateTextureUnit( + GLcontext *ctx, + GLuint unit, + BOOL bPassThrough) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); + + D3DTEXTUREMINFILTER minfilter; + D3DTEXTUREMIPFILTER mipfilter; + GLenum BaseFormat; + DWORD dwColorArg0; + int iTexEnv = 0; + GLD_texenv *pTexenv; + + // NOTE: If bPassThrough is FALSE then texture stage can be + // disabled otherwise it must pass-through it's current fragment. + + const struct gl_texture_unit *pUnit = &ctx->Texture.Unit[unit]; + const struct gl_texture_object *tObj = pUnit->_Current; + + IDirectDrawSurface7 *pTex = NULL; + if (tObj) { + pTex = (IDirectDrawSurface7*)tObj->DriverData; + } + + __try { + + // Enable texturing if unit is enabled and a valid D3D texture exists + // Mesa 5: TEXTUREn_x altered to TEXTURE_nD_BIT + //if (pTex && (pUnit->Enabled & (TEXTURE0_1D | TEXTURE0_2D))) { + if (pTex && (pUnit->_ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT))) { + // Enable texturing + _GLD_DX7_DEV(SetTexture(gld->pDev, unit, pTex)); + } else { + // Disable texturing, then return + _GLD_DX7_DEV(SetTexture(gld->pDev, unit, NULL)); + if (bPassThrough) { + _gldSetColorOps(gld, unit, D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_DIFFUSE); + _gldSetAlphaOps(gld, unit, D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_DIFFUSE); + } else { + _gldSetColorOps(gld, unit, D3DTA_TEXTURE, D3DTOP_DISABLE, D3DTA_DIFFUSE); + _gldSetAlphaOps(gld, unit, D3DTA_TEXTURE, D3DTOP_DISABLE, D3DTA_DIFFUSE); + } + return; + } + + // Texture parameters + _gldConvertMinFilter(tObj->MinFilter, &minfilter, &mipfilter); + _GLD_DX7_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_MINFILTER, minfilter)); + _GLD_DX7_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_MIPFILTER, mipfilter)); + _GLD_DX7_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_MAGFILTER, _gldConvertMagFilter(tObj->MagFilter))); + _GLD_DX7_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_ADDRESSU, _gldConvertWrap(tObj->WrapS))); + _GLD_DX7_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_ADDRESSV, _gldConvertWrap(tObj->WrapT))); + + // Texture priority + _GLD_DX7_TEX(SetPriority(pTex, (DWORD)(tObj->Priority*65535.0f))); + + // Texture environment + // TODO: Examine input texture for alpha and use specific alpha/non-alpha ops. + // See Page 355 of the Red Book. + BaseFormat = _gldDecodeBaseFormat(pTex); + + switch (BaseFormat) { + case GL_RGB: + iTexEnv = 0; + break; + case GL_RGBA: + iTexEnv = 1; + break; + case GL_ALPHA: + iTexEnv = 2; + break; + } + + switch (pUnit->EnvMode) { + case GL_DECAL: + iTexEnv += 0; + break; + case GL_REPLACE: + iTexEnv += 3; + break; + case GL_MODULATE: + iTexEnv += 6; + break; + case GL_BLEND: + // Set blend colour + // Unsupported by DX7 +// dwColorArg0 = D3DCOLOR_COLORVALUE(pUnit->EnvColor[0], pUnit->EnvColor[1], pUnit->EnvColor[2], pUnit->EnvColor[3]); +// _GLD_DX7_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_COLORARG0, dwColorArg0)); +// gldLogMessage(GLDLOG_WARN, "GL_BLEND\n"); + iTexEnv += 9; + break; + case GL_ADD: + iTexEnv += 12; + break; + } + pTexenv = (GLD_texenv*)&gldTexEnv[iTexEnv]; + _gldSetColorOps(gld, unit, pTexenv->ColorArg1, pTexenv->ColorOp, pTexenv->ColorArg2); + _gldSetAlphaOps(gld, unit, pTexenv->AlphaArg1, pTexenv->AlphaOp, pTexenv->AlphaArg2); + + } + __except(EXCEPTION_EXECUTE_HANDLER) { + ; + } +} + +//--------------------------------------------------------------------------- + +void gld_NEW_TEXTURE_DX7( + GLcontext *ctx) +{ + // TODO: Support for three (ATI Radeon) or more (nVidia GeForce3) texture units + + BOOL bUnit0Enabled; + BOOL bUnit1Enabled; + + if (!ctx) + return; // Sanity check + + if (ctx->Const.MaxTextureUnits == 1) { + gldUpdateTextureUnit(ctx, 0, TRUE); + return; + } + + // + // NOTE: THE FOLLOWING RELATES TO TWO TEXTURE UNITS, AND TWO ONLY!! + // + + // Mesa 5: Texture Units altered + bUnit0Enabled = (ctx->Texture.Unit[0]._ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT)) ? TRUE : FALSE; + bUnit1Enabled = (ctx->Texture.Unit[1]._ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT)) ? TRUE : FALSE; + + // If Unit0 is disabled and Unit1 is enabled then we must pass-though + gldUpdateTextureUnit(ctx, 0, (!bUnit0Enabled && bUnit1Enabled) ? TRUE : FALSE); + // We can always disable the last texture unit + gldUpdateTextureUnit(ctx, 1, FALSE); + +#ifdef _DEBUG + { + // Find out whether device supports current renderstates + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); + + DWORD dwPasses; + _GLD_DX7_DEV(ValidateDevice(gld->pDev, &dwPasses)); +#if 0 + if (FAILED(hr)) { + gldLogError(GLDLOG_ERROR, "ValidateDevice failed", hr); + } +#endif + if (dwPasses != 1) { + gldLogMessage(GLDLOG_ERROR, "ValidateDevice: Can't do in one pass\n"); + } + } +#endif +}; + +//--------------------------------------------------------------------------- diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_vb_d3d_render_dx7.c b/mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_vb_d3d_render_dx7.c new file mode 100644 index 000000000..a85620dde --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_vb_d3d_render_dx7.c @@ -0,0 +1,257 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x/2000/XP/XBox (Win32) +* +* Description: GLDirect fastpath pipeline stage +* +****************************************************************************/ + +//--------------------------------------------------------------------------- + +//#include "../GLDirect.h" +//#include "../gld_log.h" +//#include "gld_dx8.h" + +#include "dglcontext.h" +#include "ddlog.h" +#include "gld_dx7.h" + +//--------------------------------------------------------------------------- + +#include "glheader.h" +#include "context.h" +#include "macros.h" +// #include "mem.h" +#include "mtypes.h" +//#include "mmath.h" + +#include "math/m_matrix.h" +#include "math/m_xform.h" + +#include "tnl/t_pipeline.h" + +//--------------------------------------------------------------------------- +/* +__inline void _gldSetVertexShaderConstants( + GLcontext *ctx, + GLD_driver_dx8 *gld) +{ + D3DXMATRIX mat, matView, matProj; + GLfloat *pM; + + // Mesa 5: Altered to a Stack + //pM = ctx->ModelView.m; + pM = ctx->ModelviewMatrixStack.Top->m; + matView._11 = pM[0]; + matView._12 = pM[1]; + matView._13 = pM[2]; + matView._14 = pM[3]; + matView._21 = pM[4]; + matView._22 = pM[5]; + matView._23 = pM[6]; + matView._24 = pM[7]; + matView._31 = pM[8]; + matView._32 = pM[9]; + matView._33 = pM[10]; + matView._34 = pM[11]; + matView._41 = pM[12]; + matView._42 = pM[13]; + matView._43 = pM[14]; + matView._44 = pM[15]; + + // Mesa 5: Altered to a Stack + //pM = ctx->ProjectionMatrix.m; + pM = ctx->ProjectionMatrixStack.Top->m; + matProj._11 = pM[0]; + matProj._12 = pM[1]; + matProj._13 = pM[2]; + matProj._14 = pM[3]; + matProj._21 = pM[4]; + matProj._22 = pM[5]; + matProj._23 = pM[6]; + matProj._24 = pM[7]; + matProj._31 = pM[8]; + matProj._32 = pM[9]; + matProj._33 = pM[10]; + matProj._34 = pM[11]; + matProj._41 = pM[12]; + matProj._42 = pM[13]; + matProj._43 = pM[14]; + matProj._44 = pM[15]; + + D3DXMatrixMultiply( &mat, &matView, &matProj ); + D3DXMatrixTranspose( &mat, &mat ); + + _GLD_DX8_DEV(SetVertexShaderConstant(gld->pDev, 0, &mat, 4)); +} +*/ +//--------------------------------------------------------------------------- + +static GLboolean gld_d3d_render_stage_run( + GLcontext *ctx, + struct tnl_pipeline_stage *stage) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); + + TNLcontext *tnl; + struct vertex_buffer *VB; + tnl_render_func *tab; + GLint pass; + GLD_pb_dx7 *gldPB = &gld->PB3d; + DWORD dwFlags; + +/* + static int count = 0; + count++; + if (count != 2) + return GL_FALSE; +*/ + // The "check" function should disable this stage, + // but we'll test gld->bUseMesaTnL anyway. + if (gld->bUseMesaTnL) { + // Do nothing in this stage, but continue pipeline + return GL_TRUE; + } + + tnl = TNL_CONTEXT(ctx); + VB = &tnl->vb; + pass = 0; + + tnl->Driver.Render.Start( ctx ); + +#if 0 + // For debugging: Useful to see if an app passes colour data in + // an unusual format. + switch (VB->ColorPtr[0]->Type) { + case GL_FLOAT: + ddlogMessage(GLDLOG_SYSTEM, "ColorPtr: GL_FLOAT\n"); + break; + case GL_UNSIGNED_BYTE: + ddlogMessage(GLDLOG_SYSTEM, "ColorPtr: GL_UNSIGNED_BYTE\n"); + break; + default: + ddlogMessage(GLDLOG_SYSTEM, "ColorPtr: *?*\n"); + break; + } +#endif + + tnl->Driver.Render.Points = gld_Points3D_DX7; + if (ctx->_TriangleCaps & DD_FLATSHADE) { + tnl->Driver.Render.Line = gld_Line3DFlat_DX7; + tnl->Driver.Render.Triangle = gld_Triangle3DFlat_DX7; + tnl->Driver.Render.Quad = gld_Quad3DFlat_DX7; + } else { + tnl->Driver.Render.Line = gld_Line3DSmooth_DX7; + tnl->Driver.Render.Triangle = gld_Triangle3DSmooth_DX7; + tnl->Driver.Render.Quad = gld_Quad3DSmooth_DX7; + } + +// _GLD_DX7_VB(Lock(gldPB->pVB, 0, 0, &gldPB->pPoints, D3DLOCK_DISCARD)); + dwFlags = DDLOCK_DISCARDCONTENTS | DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR | DDLOCK_WRITEONLY; + _GLD_DX7_VB(Lock(gldPB->pVB, dwFlags, &gldPB->pPoints, NULL)); + gldPB->nPoints = gldPB->nLines = gldPB->nTriangles = 0; + // Allocate primitive pointers + // gldPB->pPoints is always first + gldPB->pLines = gldPB->pPoints + (gldPB->dwStride * gldPB->iFirstLine); + gldPB->pTriangles = gldPB->pPoints + (gldPB->dwStride * gldPB->iFirstTriangle); + + ASSERT(tnl->Driver.Render.BuildVertices); + ASSERT(tnl->Driver.Render.PrimitiveNotify); + ASSERT(tnl->Driver.Render.Points); + ASSERT(tnl->Driver.Render.Line); + ASSERT(tnl->Driver.Render.Triangle); + ASSERT(tnl->Driver.Render.Quad); + ASSERT(tnl->Driver.Render.ResetLineStipple); + ASSERT(tnl->Driver.Render.Interp); + ASSERT(tnl->Driver.Render.CopyPV); + ASSERT(tnl->Driver.Render.ClippedLine); + ASSERT(tnl->Driver.Render.ClippedPolygon); + ASSERT(tnl->Driver.Render.Finish); + + tab = (VB->Elts ? tnl->Driver.Render.PrimTabElts : tnl->Driver.Render.PrimTabVerts); + + do { + GLuint i, length, flags = 0; + for (i = 0 ; !(flags & PRIM_END) ; i += length) + { + flags = VB->Primitive[i].mode; + length= VB->Primitive[i].count; + ASSERT(length || (flags & PRIM_END)); + ASSERT((flags & PRIM_MODE_MASK) <= GL_POLYGON+1); + if (length) + tab[flags & PRIM_MODE_MASK]( ctx, i, i + length, flags ); + } + } while (tnl->Driver.Render.Multipass && + tnl->Driver.Render.Multipass( ctx, ++pass )); + + _GLD_DX7_VB(Unlock(gldPB->pVB)); + +// _GLD_DX7_DEV(SetStreamSource(gld->pDev, 0, gldPB->pVB, gldPB->dwStride)); + + _GLD_DX7_DEV(SetTransform(gld->pDev, D3DTRANSFORMSTATE_PROJECTION, &gld->matProjection)); + _GLD_DX7_DEV(SetTransform(gld->pDev, D3DTRANSFORMSTATE_WORLD, &gld->matModelView)); + + if (gldPB->nPoints) { +// _GLD_DX7_DEV(DrawPrimitive(gld->pDev, D3DPT_POINTLIST, 0, gldPB->nPoints)); + _GLD_DX7_DEV(DrawPrimitiveVB(gld->pDev, D3DPT_POINTLIST, gldPB->pVB, 0, gldPB->nPoints, 0)); + gldPB->nPoints = 0; + } + + if (gldPB->nLines) { +// _GLD_DX7_DEV(DrawPrimitive(gld->pDev, D3DPT_LINELIST, gldPB->iFirstLine, gldPB->nLines)); + _GLD_DX7_DEV(DrawPrimitiveVB(gld->pDev, D3DPT_LINELIST, gldPB->pVB, gldPB->iFirstLine, gldPB->nLines, 0)); + gldPB->nLines = 0; + } + + if (gldPB->nTriangles) { +// _GLD_DX7_DEV(DrawPrimitive(gld->pDev, D3DPT_TRIANGLELIST, gldPB->iFirstTriangle, gldPB->nTriangles)); + _GLD_DX7_DEV(DrawPrimitiveVB(gld->pDev, D3DPT_TRIANGLELIST, gldPB->pVB, gldPB->iFirstTriangle, gldPB->nTriangles, 0)); + gldPB->nTriangles = 0; + } + + return GL_FALSE; /* finished the pipe */ +} + + +//--------------------------------------------------------------------------- + +const struct tnl_pipeline_stage _gld_d3d_render_stage = +{ + "gld_d3d_render_stage", + NULL, + NULL, + NULL, + NULL, + gld_d3d_render_stage_run /* run */ +}; + +//--------------------------------------------------------------------------- diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_vb_mesa_render_dx7.c b/mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_vb_mesa_render_dx7.c new file mode 100644 index 000000000..72e5e1308 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_vb_mesa_render_dx7.c @@ -0,0 +1,422 @@ + +/* + * 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 + */ + + +/* + * Render whole vertex buffers, including projection of vertices from + * clip space and clipping of primitives. + * + * This file makes calls to project vertices and to the point, line + * and triangle rasterizers via the function pointers: + * + * context->Driver.Render.* + * + */ + + +//--------------------------------------------------------------------------- + +//#include "../GLDirect.h" +//#include "../gld_log.h" +//#include "gld_dx8.h" + +#include "dglcontext.h" +#include "ddlog.h" +#include "gld_dx7.h" + +//--------------------------------------------------------------------------- + +#include "glheader.h" +#include "context.h" +#include "macros.h" +// #include "mem.h" +#include "mtypes.h" +//#include "mmath.h" + +#include "math/m_matrix.h" +#include "math/m_xform.h" + +#include "tnl/t_pipeline.h" + +/**********************************************************************/ +/* Clip single primitives */ +/**********************************************************************/ + + +#if defined(USE_IEEE) +#define NEGATIVE(x) (GET_FLOAT_BITS(x) & (1<<31)) +//#define DIFFERENT_SIGNS(x,y) ((GET_FLOAT_BITS(x) ^ GET_FLOAT_BITS(y)) & (1<<31)) +#else +#define NEGATIVE(x) (x < 0) +//#define DIFFERENT_SIGNS(x,y) (x * y <= 0 && x - y != 0) +/* Could just use (x*y<0) except for the flatshading requirements. + * Maybe there's a better way? + */ +#endif + + +#define W(i) coord[i][3] +#define Z(i) coord[i][2] +#define Y(i) coord[i][1] +#define X(i) coord[i][0] +#define SIZE 4 +#define TAG(x) x##_4 +#include "tnl/t_vb_cliptmp.h" + + + +/**********************************************************************/ +/* Clip and render whole begin/end objects */ +/**********************************************************************/ + +#define NEED_EDGEFLAG_SETUP (ctx->_TriangleCaps & DD_TRI_UNFILLED) +#define EDGEFLAG_GET(idx) VB->EdgeFlag[idx] +#define EDGEFLAG_SET(idx, val) VB->EdgeFlag[idx] = val + + +/* Vertices, with the possibility of clipping. + */ +#define RENDER_POINTS( start, count ) \ + tnl->Driver.Render.Points( ctx, start, count ) + +#define RENDER_LINE( v1, v2 ) \ +do { \ + GLubyte c1 = mask[v1], c2 = mask[v2]; \ + GLubyte ormask = c1|c2; \ + if (!ormask) \ + LineFunc( ctx, v1, v2 ); \ + else if (!(c1 & c2 & 0x3f)) \ + clip_line_4( ctx, v1, v2, ormask ); \ +} while (0) + +#define RENDER_TRI( v1, v2, v3 ) \ +do { \ + GLubyte c1 = mask[v1], c2 = mask[v2], c3 = mask[v3]; \ + GLubyte ormask = c1|c2|c3; \ + if (!ormask) \ + TriangleFunc( ctx, v1, v2, v3 ); \ + else if (!(c1 & c2 & c3 & 0x3f)) \ + clip_tri_4( ctx, v1, v2, v3, ormask ); \ +} while (0) + +#define RENDER_QUAD( v1, v2, v3, v4 ) \ +do { \ + GLubyte c1 = mask[v1], c2 = mask[v2]; \ + GLubyte c3 = mask[v3], c4 = mask[v4]; \ + GLubyte ormask = c1|c2|c3|c4; \ + if (!ormask) \ + QuadFunc( ctx, v1, v2, v3, v4 ); \ + else if (!(c1 & c2 & c3 & c4 & 0x3f)) \ + clip_quad_4( ctx, v1, v2, v3, v4, ormask ); \ +} while (0) + + +#define LOCAL_VARS \ + TNLcontext *tnl = TNL_CONTEXT(ctx); \ + struct vertex_buffer *VB = &tnl->vb; \ + const GLuint * const elt = VB->Elts; \ + const GLubyte *mask = VB->ClipMask; \ + const GLuint sz = VB->ClipPtr->size; \ + const tnl_line_func LineFunc = tnl->Driver.Render.Line; \ + const tnl_triangle_func TriangleFunc = tnl->Driver.Render.Triangle; \ + const tnl_quad_func QuadFunc = tnl->Driver.Render.Quad; \ + const GLboolean stipple = ctx->Line.StippleFlag; \ + (void) (LineFunc && TriangleFunc && QuadFunc); \ + (void) elt; (void) mask; (void) sz; (void) stipple; + +#define TAG(x) clip_##x##_verts +#define INIT(x) tnl->Driver.Render.PrimitiveNotify( ctx, x ) +#define RESET_STIPPLE if (stipple) tnl->Driver.Render.ResetLineStipple( ctx ) +#define PRESERVE_VB_DEFS +#include "tnl/t_vb_rendertmp.h" + + + +/* Elts, with the possibility of clipping. + */ +#undef ELT +#undef TAG +#define ELT(x) elt[x] +#define TAG(x) clip_##x##_elts +#include "tnl/t_vb_rendertmp.h" + +/* TODO: do this for all primitives, verts and elts: + */ +static void clip_elt_triangles( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + tnl_render_func render_tris = tnl->Driver.Render.PrimTabElts[GL_TRIANGLES]; + struct vertex_buffer *VB = &tnl->vb; + const GLuint * const elt = VB->Elts; + GLubyte *mask = VB->ClipMask; + GLuint last = count-2; + GLuint j; + (void) flags; + + tnl->Driver.Render.PrimitiveNotify( ctx, GL_TRIANGLES ); + + for (j=start; j < last; j+=3 ) { + GLubyte c1 = mask[elt[j]]; + GLubyte c2 = mask[elt[j+1]]; + GLubyte c3 = mask[elt[j+2]]; + GLubyte ormask = c1|c2|c3; + if (ormask) { + if (start < j) + render_tris( ctx, start, j, 0 ); + if (!(c1&c2&c3&0x3f)) + clip_tri_4( ctx, elt[j], elt[j+1], elt[j+2], ormask ); + start = j+3; + } + } + + if (start < j) + render_tris( ctx, start, j, 0 ); +} + +/**********************************************************************/ +/* Render whole begin/end objects */ +/**********************************************************************/ + +#define NEED_EDGEFLAG_SETUP (ctx->_TriangleCaps & DD_TRI_UNFILLED) +#define EDGEFLAG_GET(idx) VB->EdgeFlag[idx] +#define EDGEFLAG_SET(idx, val) VB->EdgeFlag[idx] = val + + +/* Vertices, no clipping. + */ +#define RENDER_POINTS( start, count ) \ + tnl->Driver.Render.Points( ctx, start, count ) + +#define RENDER_LINE( v1, v2 ) \ + LineFunc( ctx, v1, v2 ) + +#define RENDER_TRI( v1, v2, v3 ) \ + TriangleFunc( ctx, v1, v2, v3 ) + +#define RENDER_QUAD( v1, v2, v3, v4 ) \ + QuadFunc( ctx, v1, v2, v3, v4 ) + +#define TAG(x) _gld_tnl_##x##_verts + +#define LOCAL_VARS \ + TNLcontext *tnl = TNL_CONTEXT(ctx); \ + struct vertex_buffer *VB = &tnl->vb; \ + const GLuint * const elt = VB->Elts; \ + const tnl_line_func LineFunc = tnl->Driver.Render.Line; \ + const tnl_triangle_func TriangleFunc = tnl->Driver.Render.Triangle; \ + const tnl_quad_func QuadFunc = tnl->Driver.Render.Quad; \ + (void) (LineFunc && TriangleFunc && QuadFunc); \ + (void) elt; + +#define RESET_STIPPLE tnl->Driver.Render.ResetLineStipple( ctx ) +#define INIT(x) tnl->Driver.Render.PrimitiveNotify( ctx, x ) +#define RENDER_TAB_QUALIFIER +#define PRESERVE_VB_DEFS +#include "tnl/t_vb_rendertmp.h" + + +/* Elts, no clipping. + */ +#undef ELT +#define TAG(x) _gld_tnl_##x##_elts +#define ELT(x) elt[x] +#include "tnl/t_vb_rendertmp.h" + + +/**********************************************************************/ +/* Helper functions for drivers */ +/**********************************************************************/ +/* +void _tnl_RenderClippedPolygon( GLcontext *ctx, const GLuint *elts, GLuint n ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + GLuint *tmp = VB->Elts; + + VB->Elts = (GLuint *)elts; + tnl->Driver.Render.PrimTabElts[GL_POLYGON]( ctx, 0, n, PRIM_BEGIN|PRIM_END ); + VB->Elts = tmp; +} + +void _tnl_RenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + tnl->Driver.Render.Line( ctx, ii, jj ); +} +*/ + + +/**********************************************************************/ +/* Clip and render whole vertex buffers */ +/**********************************************************************/ + +tnl_points_func _gldSetupPoints[4] = { + gld_Points2D_DX7, + gld_Points2D_DX7, + gld_Points2D_DX7, + gld_Points2D_DX7 +}; +tnl_line_func _gldSetupLine[4] = { + gld_Line2DFlat_DX7, + gld_Line2DSmooth_DX7, + gld_Line2DFlat_DX7, + gld_Line2DSmooth_DX7, +}; +tnl_triangle_func _gldSetupTriangle[4] = { + gld_Triangle2DFlat_DX7, + gld_Triangle2DSmooth_DX7, + gld_Triangle2DFlatExtras_DX7, + gld_Triangle2DSmoothExtras_DX7 +}; +tnl_quad_func _gldSetupQuad[4] = { + gld_Quad2DFlat_DX7, + gld_Quad2DSmooth_DX7, + gld_Quad2DFlatExtras_DX7, + gld_Quad2DSmoothExtras_DX7 +}; + +//--------------------------------------------------------------------------- + +static GLboolean _gld_mesa_render_stage_run( + GLcontext *ctx, + struct tnl_pipeline_stage *stage) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); + + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + tnl_render_func *tab; + GLint pass = 0; + GLD_pb_dx7 *gldPB; + DWORD dwFlags; + + /* Allow the drivers to lock before projected verts are built so + * that window coordinates are guarenteed not to change before + * rendering. + */ + ASSERT(tnl->Driver.Render.Start); + + tnl->Driver.Render.Start( ctx ); + + gldPB = &gld->PB2d; + tnl->Driver.Render.Points = _gldSetupPoints[gld->iSetupFunc]; + tnl->Driver.Render.Line = _gldSetupLine[gld->iSetupFunc]; + tnl->Driver.Render.Triangle = _gldSetupTriangle[gld->iSetupFunc]; + tnl->Driver.Render.Quad = _gldSetupQuad[gld->iSetupFunc]; + + dwFlags = DDLOCK_DISCARDCONTENTS | DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR | DDLOCK_WRITEONLY; + _GLD_DX7_VB(Lock(gldPB->pVB, dwFlags, &gldPB->pPoints, NULL)); + gldPB->nPoints = gldPB->nLines = gldPB->nTriangles = 0; + + // Allocate primitive pointers - gldPB->pPoints is always first + gldPB->pLines = gldPB->pPoints + (gldPB->dwStride * gldPB->iFirstLine); + gldPB->pTriangles = gldPB->pPoints + (gldPB->dwStride * gldPB->iFirstTriangle); + + ASSERT(tnl->Driver.Render.BuildVertices); + ASSERT(tnl->Driver.Render.PrimitiveNotify); + ASSERT(tnl->Driver.Render.Points); + ASSERT(tnl->Driver.Render.Line); + ASSERT(tnl->Driver.Render.Triangle); + ASSERT(tnl->Driver.Render.Quad); + ASSERT(tnl->Driver.Render.ResetLineStipple); + ASSERT(tnl->Driver.Render.Interp); + ASSERT(tnl->Driver.Render.CopyPV); + ASSERT(tnl->Driver.Render.ClippedLine); + ASSERT(tnl->Driver.Render.ClippedPolygon); + ASSERT(tnl->Driver.Render.Finish); + + tnl->Driver.Render.BuildVertices( ctx, 0, VB->Count, ~0 ); + + if (VB->ClipOrMask) { + tab = VB->Elts ? clip_render_tab_elts : clip_render_tab_verts; + clip_render_tab_elts[GL_TRIANGLES] = clip_elt_triangles; + } + else { + tab = (VB->Elts ? + tnl->Driver.Render.PrimTabElts : + tnl->Driver.Render.PrimTabVerts); + } + + do { + GLuint i, length, flags = 0; + for (i = 0 ; !(flags & PRIM_END) ; i += length) { + flags = VB->Primitive[i].mode; + length= VB->Primitive[i].count; + ASSERT(length || (flags & PRIM_END)); + ASSERT((flags & PRIM_MODE_MASK) <= GL_POLYGON+1); + if (length) + tab[flags & PRIM_MODE_MASK]( ctx, i, i + length, flags ); + } + } while (tnl->Driver.Render.Multipass && + tnl->Driver.Render.Multipass( ctx, ++pass )); + + +// tnl->Driver.Render.Finish( ctx ); + + _GLD_DX7_VB(Unlock(gldPB->pVB)); + + if (gldPB->nPoints) { + _GLD_DX7_DEV(DrawPrimitiveVB(gld->pDev, D3DPT_POINTLIST, gldPB->pVB, 0, gldPB->nPoints, 0)); + gldPB->nPoints = 0; + } + + if (gldPB->nLines) { + _GLD_DX7_DEV(DrawPrimitiveVB(gld->pDev, D3DPT_LINELIST, gldPB->pVB, gldPB->iFirstLine, gldPB->nLines*2, 0)); + gldPB->nLines = 0; + } + + if (gldPB->nTriangles) { + _GLD_DX7_DEV(DrawPrimitiveVB(gld->pDev, D3DPT_TRIANGLELIST, gldPB->pVB, gldPB->iFirstTriangle, gldPB->nTriangles*3, 0)); + gldPB->nTriangles = 0; + } + + return GL_FALSE; /* finished the pipe */ +} + + +/**********************************************************************/ +/* Render pipeline stage */ +/**********************************************************************/ + + + +const struct tnl_pipeline_stage _gld_mesa_render_stage = +{ + "gld_mesa_render_stage", + NULL, + NULL, + NULL, + NULL, + _gld_mesa_render_stage_run /* run */ +}; + +//--------------------------------------------------------------------------- diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_wgl_dx7.c b/mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_wgl_dx7.c new file mode 100644 index 000000000..fa44a952a --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dx7/gld_wgl_dx7.c @@ -0,0 +1,1613 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x/2000/XP/XBox (Win32) +* +* Description: GLDirect Direct3D 8.x WGL (WindowsGL) +* +****************************************************************************/ + +#include "dglcontext.h" +#include "gld_driver.h" +//#include "gld_dxerr8.h" +#include "gld_dx7.h" + +#include "tnl/tnl.h" +#include "tnl/t_context.h" + +// Copied from dglcontect.c +#define GLDERR_NONE 0 +#define GLDERR_MEM 1 +#define GLDERR_DDRAW 2 +#define GLDERR_D3D 3 +#define GLDERR_BPP 4 +#define GLDERR_DDS 5 +// This external var keeps track of any error +extern int nContextError; + +// Uncomment this for persistant resources +//#define _GLD_PERSISTANT + +#define DDLOG_CRITICAL_OR_WARN DDLOG_CRITICAL + +extern void _gld_mesa_warning(GLcontext *, char *); +extern void _gld_mesa_fatal(GLcontext *, char *); + +//--------------------------------------------------------------------------- + +static char szColorDepthWarning[] = +"GLDirect does not support the current desktop\n\ +color depth.\n\n\ +You may need to change the display resolution to\n\ +16 bits per pixel or higher color depth using\n\ +the Windows Display Settings control panel\n\ +before running this OpenGL application.\n"; + +// The only depth-stencil formats currently supported by Direct3D +// Surface Format Depth Stencil Total Bits +// D3DFMT_D32 32 - 32 +// D3DFMT_D15S1 15 1 16 +// D3DFMT_D24S8 24 8 32 +// D3DFMT_D16 16 - 16 +// D3DFMT_D24X8 24 - 32 +// D3DFMT_D24X4S4 24 4 32 + +// This pixel format will be used as a template when compiling the list +// of pixel formats supported by the hardware. Many fields will be +// filled in at runtime. +// PFD flag defaults are upgraded to match ChoosePixelFormat() -- DaveM +static DGL_pixelFormat pfTemplateHW = +{ + { + sizeof(PIXELFORMATDESCRIPTOR), // Size of the data structure + 1, // Structure version - should be 1 + // Flags: + PFD_DRAW_TO_WINDOW | // The buffer can draw to a window or device surface. + PFD_DRAW_TO_BITMAP | // The buffer can draw to a bitmap. (DaveM) + PFD_SUPPORT_GDI | // The buffer supports GDI drawing. (DaveM) + PFD_SUPPORT_OPENGL | // The buffer supports OpenGL drawing. + PFD_DOUBLEBUFFER | // The buffer is double-buffered. + 0, // Placeholder for easy commenting of above flags + PFD_TYPE_RGBA, // Pixel type RGBA. + 16, // Total colour bitplanes (excluding alpha bitplanes) + 5, 0, // Red bits, shift + 5, 0, // Green bits, shift + 5, 0, // Blue bits, shift + 0, 0, // Alpha bits, shift (destination alpha) + 0, // Accumulator bits (total) + 0, 0, 0, 0, // Accumulator bits: Red, Green, Blue, Alpha + 0, // Depth bits + 0, // Stencil bits + 0, // Number of auxiliary buffers + 0, // Layer type + 0, // Specifies the number of overlay and underlay planes. + 0, // Layer mask + 0, // Specifies the transparent color or index of an underlay plane. + 0 // Damage mask + }, + D3DX_SF_UNKNOWN, // No depth/stencil buffer +}; + +//--------------------------------------------------------------------------- +// Vertex Shaders +//--------------------------------------------------------------------------- +/* +// Vertex Shader Declaration +static DWORD dwTwoSidedLightingDecl[] = +{ + D3DVSD_STREAM(0), + D3DVSD_REG(0, D3DVSDT_FLOAT3), // XYZ position + D3DVSD_REG(1, D3DVSDT_FLOAT3), // XYZ normal + D3DVSD_REG(2, D3DVSDT_D3DCOLOR), // Diffuse color + D3DVSD_REG(3, D3DVSDT_D3DCOLOR), // Specular color + D3DVSD_REG(4, D3DVSDT_FLOAT2), // 2D texture unit 0 + D3DVSD_REG(5, D3DVSDT_FLOAT2), // 2D texture unit 1 + D3DVSD_END() +}; + +// Vertex Shader for two-sided lighting +static char *szTwoSidedLightingVS = +// This is a test shader! +"vs.1.0\n" +"m4x4 oPos,v0,c0\n" +"mov oD0,v2\n" +"mov oD1,v3\n" +"mov oT0,v4\n" +"mov oT1,v5\n" +; +*/ +//--------------------------------------------------------------------------- +//--------------------------------------------------------------------------- + +typedef struct { +// HINSTANCE hD3D8DLL; // Handle to d3d8.dll +// FNDIRECT3DCREATE7 fnDirect3DCreate7; // Direct3DCreate8 function prototype +// BOOL bDirect3D; // Persistant Direct3D7 exists +// BOOL bDirect3DDevice; // Persistant Direct3DDevice7 exists +// IDirect3D7 *pD3D; // Persistant Direct3D7 +// IDirect3DDevice7 *pDev; // Persistant Direct3DDevice7 + BOOL bD3DXStarted; +} GLD_dx7_globals; + +// These are "global" to all DX7 contexts. KeithH +static GLD_dx7_globals dx7Globals; + +// Added for correct clipping of multiple open windows. (DaveM) +LPDIRECTDRAWSURFACE7 lpDDSPrimary = NULL; +LPDIRECTDRAWCLIPPER lpDDClipper = NULL; + +//--------------------------------------------------------------------------- +//--------------------------------------------------------------------------- + +BOOL gldGetDXErrorString_DX( + HRESULT hr, + char *buf, + int nBufSize) +{ + // + // Return a string describing the input HRESULT error code + // + + D3DXGetErrorString(hr, nBufSize, buf); + return TRUE; +} + +//--------------------------------------------------------------------------- +// +// DX7 does not support multisample +/* +static D3DMULTISAMPLE_TYPE _gldGetDeviceMultiSampleType( + IDirect3D8 *pD3D8, + D3DFORMAT SurfaceFormat, + D3DDEVTYPE d3dDevType, + BOOL Windowed) +{ + int i; + HRESULT hr; + + if (glb.dwMultisample == GLDS_MULTISAMPLE_NONE) + return D3DMULTISAMPLE_NONE; + + if (glb.dwMultisample == GLDS_MULTISAMPLE_FASTEST) { + // Find fastest multisample + for (i=2; i<17; i++) { + hr = IDirect3D8_CheckDeviceMultiSampleType( + pD3D8, + glb.dwAdapter, + d3dDevType, + SurfaceFormat, + Windowed, + (D3DMULTISAMPLE_TYPE)i); + if (SUCCEEDED(hr)) { + return (D3DMULTISAMPLE_TYPE)i; + } + } + } else { + // Find nicest multisample + for (i=16; i>1; i--) { + hr = IDirect3D8_CheckDeviceMultiSampleType( + pD3D8, + glb.dwAdapter, + d3dDevType, + SurfaceFormat, + Windowed, + (D3DMULTISAMPLE_TYPE)i); + if (SUCCEEDED(hr)) { + return (D3DMULTISAMPLE_TYPE)i; + } + } + } + + // Nothing found - return default + return D3DMULTISAMPLE_NONE; +} +*/ +//--------------------------------------------------------------------------- + +void _gldDestroyPrimitiveBuffer( + GLD_pb_dx7 *gldVB) +{ + SAFE_RELEASE(gldVB->pVB); + + // Sanity check... + gldVB->nLines = gldVB->nPoints = gldVB->nTriangles = 0; +} + +//--------------------------------------------------------------------------- + +HRESULT _gldCreatePrimitiveBuffer( + GLcontext *ctx, + GLD_driver_dx7 *lpCtx, + GLD_pb_dx7 *gldVB) +{ + HRESULT hResult; + char *szCreateVertexBufferFailed = "CreateVertexBuffer failed"; + DWORD dwMaxVertices; // Max number of vertices in vertex buffer + DWORD dwVBSize; // Total size of vertex buffer + D3DVERTEXBUFFERDESC vbdesc; + + // If CVA (Compiled Vertex Array) is used by an OpenGL app, then we + // will need enough vertices to cater for Mesa::Const.MaxArrayLockSize. + // We'll use IMM_SIZE if it's larger (which it should not be). + dwMaxVertices = MAX_ARRAY_LOCK_SIZE; + + // Max vertex buffer size limited in DX7. (DaveM) + if (dwMaxVertices*9 > D3DMAXNUMVERTICES) + dwMaxVertices = D3DMAXNUMVERTICES/9; + + // Now calculate how many vertices to allow for in total + // 1 per point, 2 per line, 6 per quad = 9 + dwVBSize = dwMaxVertices * 9 * gldVB->dwStride; + + vbdesc.dwSize = sizeof(vbdesc); + vbdesc.dwCaps = gldVB->dwCreateFlags; + vbdesc.dwFVF = gldVB->dwFVF; + vbdesc.dwNumVertices = dwMaxVertices * 9; + +/* hResult = IDirect3DDevice8_CreateVertexBuffer( + lpCtx->pDev, + dwVBSize, +RAgldVB->dwUsage, + gldVB->dwFVF, + gldVB->dwPool, + &gldVB->pVB);*/ + hResult = IDirect3D7_CreateVertexBuffer( + lpCtx->pD3D, + &vbdesc, + &gldVB->pVB, + 0); + if (FAILED(hResult)) { + ddlogMessage(DDLOG_CRITICAL_OR_WARN, szCreateVertexBufferFailed); + return hResult; + } + + gldVB->nLines = gldVB->nPoints = gldVB->nTriangles = 0; + gldVB->pPoints = gldVB->pLines = gldVB->pTriangles = NULL; + gldVB->iFirstLine = dwMaxVertices; // Index of first line in VB + gldVB->iFirstTriangle = dwMaxVertices*3; // Index of first triangle in VB + + return S_OK; +} + +//--------------------------------------------------------------------------- +// Function: _gldCreateVertexShaders +// Create DX8 Vertex Shaders. +//--------------------------------------------------------------------------- +/* +void _gldCreateVertexShaders( + GLD_driver_dx8 *gld) +{ + DWORD dwFlags; + LPD3DXBUFFER pVSOpcodeBuffer; // Vertex Shader opcode buffer + HRESULT hr; + +#ifdef _DEBUG + dwFlags = D3DXASM_DEBUG; +#else + dwFlags = 0; // D3DXASM_SKIPVALIDATION; +#endif + + ddlogMessage(DDLOG_INFO, "Creating shaders...\n"); + + // Init the shader handle + gld->VStwosidelight.hShader = 0; + + if (gld->d3dCaps8.MaxStreams == 0) { + // Lame DX8 driver doesn't support streams + // Not fatal, as defaults will be used + ddlogMessage(DDLOG_WARN, "Driver doesn't support Vertex Shaders (MaxStreams==0)\n"); + return; + } + + // ** THIS DISABLES VERTEX SHADER SUPPORT ** +// return; + // ** THIS DISABLES VERTEX SHADER SUPPORT ** + + // + // Two-sided lighting + // + +#if 0 + // + // DEBUGGING: Load shader from a text file + // + { + LPD3DXBUFFER pVSErrorBuffer; // Vertex Shader error buffer + hr = D3DXAssembleShaderFromFile( + "twoside.vsh", + dwFlags, + NULL, // No constants + &pVSOpcodeBuffer, + &pVSErrorBuffer); + if (pVSErrorBuffer && pVSErrorBuffer->lpVtbl->GetBufferPointer(pVSErrorBuffer)) + ddlogMessage(DDLOG_INFO, pVSErrorBuffer->lpVtbl->GetBufferPointer(pVSErrorBuffer)); + SAFE_RELEASE(pVSErrorBuffer); + } +#else + { + LPD3DXBUFFER pVSErrorBuffer; // Vertex Shader error buffer + // Assemble ascii shader text into shader opcodes + hr = D3DXAssembleShader( + szTwoSidedLightingVS, + strlen(szTwoSidedLightingVS), + dwFlags, + NULL, // No constants + &pVSOpcodeBuffer, + &pVSErrorBuffer); + if (pVSErrorBuffer && pVSErrorBuffer->lpVtbl->GetBufferPointer(pVSErrorBuffer)) + ddlogMessage(DDLOG_INFO, pVSErrorBuffer->lpVtbl->GetBufferPointer(pVSErrorBuffer)); + SAFE_RELEASE(pVSErrorBuffer); + } +#endif + if (FAILED(hr)) { + ddlogError(DDLOG_WARN, "AssembleShader failed", hr); + SAFE_RELEASE(pVSOpcodeBuffer); + return; + } + +// This is for debugging. Remove to enable vertex shaders in HW +#define _GLD_FORCE_SW_VS 0 + + if (_GLD_FORCE_SW_VS) { + // _GLD_FORCE_SW_VS should be disabled for Final Release + ddlogMessage(DDLOG_SYSTEM, "[Forcing shaders in SW]\n"); + } + + // Try and create shader in hardware. + // NOTE: The D3D Ref device appears to succeed when trying to + // create the device in hardware, but later complains + // when trying to set it with SetVertexShader(). Go figure. + if (_GLD_FORCE_SW_VS || glb.dwDriver == GLDS_DRIVER_REF) { + // Don't try and create a hardware shader with the Ref device + hr = E_FAIL; // COM error/fail result + } else { + gld->VStwosidelight.bHardware = TRUE; + hr = IDirect3DDevice8_CreateVertexShader( + gld->pDev, + dwTwoSidedLightingDecl, + pVSOpcodeBuffer->lpVtbl->GetBufferPointer(pVSOpcodeBuffer), + &gld->VStwosidelight.hShader, + 0); + } + if (FAILED(hr)) { + ddlogMessage(DDLOG_INFO, "... HW failed, trying SW...\n"); + // Failed. Try and create shader for software processing + hr = IDirect3DDevice8_CreateVertexShader( + gld->pDev, + dwTwoSidedLightingDecl, + pVSOpcodeBuffer->lpVtbl->GetBufferPointer(pVSOpcodeBuffer), + &gld->VStwosidelight.hShader, + D3DUSAGE_SOFTWAREPROCESSING); + if (FAILED(hr)) { + gld->VStwosidelight.hShader = 0; // Sanity check + ddlogError(DDLOG_WARN, "CreateVertexShader failed", hr); + return; + } + // Succeeded, but for software processing + gld->VStwosidelight.bHardware = FALSE; + } + + SAFE_RELEASE(pVSOpcodeBuffer); + + ddlogMessage(DDLOG_INFO, "... OK\n"); +} + +//--------------------------------------------------------------------------- + +void _gldDestroyVertexShaders( + GLD_driver_dx8 *gld) +{ + if (gld->VStwosidelight.hShader) { + IDirect3DDevice8_DeleteVertexShader(gld->pDev, gld->VStwosidelight.hShader); + gld->VStwosidelight.hShader = 0; + } +} +*/ +//--------------------------------------------------------------------------- + +BOOL gldCreateDrawable_DX( + DGL_ctx *ctx, +// BOOL bDefaultDriver, + BOOL bDirectDrawPersistant, + BOOL bPersistantBuffers) +{ + // + // bDirectDrawPersistant: applies to IDirect3D8 + // bPersistantBuffers: applies to IDirect3DDevice8 + // + +// D3DDEVTYPE d3dDevType; +// D3DPRESENT_PARAMETERS d3dpp; +// D3DDISPLAYMODE d3ddm; +// DWORD dwBehaviourFlags; +// D3DADAPTER_IDENTIFIER8 d3dIdent; + + HRESULT hr; + GLD_driver_dx7 *lpCtx = NULL; + D3DX_VIDMODEDESC d3ddm; + + // Parameters for D3DXCreateContextEx + // These will be different for fullscreen and windowed + DWORD dwDeviceIndex; + DWORD dwFlags; + HWND hwnd; + HWND hwndFocus; + DWORD numColorBits; + DWORD numAlphaBits; + DWORD numDepthBits; + DWORD numStencilBits; + DWORD numBackBuffers; + DWORD dwWidth; + DWORD dwHeight; + DWORD refreshRate; + + // Error if context is NULL. + if (ctx == NULL) + return FALSE; + + if (ctx->glPriv) { + lpCtx = ctx->glPriv; + // Release any existing interfaces (in reverse order) + SAFE_RELEASE(lpCtx->pDev); + SAFE_RELEASE(lpCtx->pD3D); + lpCtx->pD3DXContext->lpVtbl->Release(lpCtx->pD3DXContext); + lpCtx->pD3DXContext = NULL; + } else { + lpCtx = (GLD_driver_dx7*)malloc(sizeof(GLD_driver_dx7)); + ZeroMemory(lpCtx, sizeof(lpCtx)); + } + +// d3dDevType = (glb.dwDriver == GLDS_DRIVER_HAL) ? D3DDEVTYPE_HAL : D3DDEVTYPE_REF; + // Use REF device if requested. Otherwise D3DX_DEFAULT will choose highest level + // of HW acceleration. + dwDeviceIndex = (glb.dwDriver == GLDS_DRIVER_REF) ? D3DX_HWLEVEL_REFERENCE : D3DX_DEFAULT; + + // TODO: Check this +// if (bDefaultDriver) +// d3dDevType = D3DDEVTYPE_REF; + +#ifdef _GLD_PERSISTANT + // Use persistant interface if needed + if (bDirectDrawPersistant && dx7Globals.bDirect3D) { + lpCtx->pD3D = dx7Globals.pD3D; + IDirect3D7_AddRef(lpCtx->pD3D); + goto SkipDirectDrawCreate; + } +#endif +/* + // Create Direct3D7 object + lpCtx->pD3D = dx7Globals.fnDirect3DCreate8(D3D_SDK_VERSION_DX8_SUPPORT_WIN95); + if (lpCtx->pD3D == NULL) { + MessageBox(NULL, "Unable to initialize Direct3D8", "GLDirect", MB_OK); + ddlogMessage(DDLOG_CRITICAL_OR_WARN, "Unable to create Direct3D8 interface"); + nContextError = GLDERR_D3D; + goto return_with_error; + } +*/ + +#ifdef _GLD_PERSISTANT + // Cache Direct3D interface for subsequent GLRCs + if (bDirectDrawPersistant && !dx8Globals.bDirect3D) { + dx7Globals.pD3D = lpCtx->pD3D; + IDirect3D7_AddRef(dx7Globals.pD3D); + dx7Globals.bDirect3D = TRUE; + } +SkipDirectDrawCreate: +#endif +/* + // Get the display mode so we can make a compatible backbuffer + hResult = IDirect3D8_GetAdapterDisplayMode(lpCtx->pD3D, glb.dwAdapter, &d3ddm); + if (FAILED(hResult)) { + nContextError = GLDERR_D3D; + goto return_with_error; + } +*/ + +#if 0 + // Get device caps + hResult = IDirect3D8_GetDeviceCaps(lpCtx->pD3D, glb.dwAdapter, d3dDevType, &lpCtx->d3dCaps8); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "IDirect3D8_GetDeviceCaps failed", hResult); + nContextError = GLDERR_D3D; + goto return_with_error; + } + + // Check for hardware transform & lighting + lpCtx->bHasHWTnL = lpCtx->d3dCaps8.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ? TRUE : FALSE; + + // If this flag is present then we can't default to Mesa + // SW rendering between BeginScene() and EndScene(). + if (lpCtx->d3dCaps8.Caps2 & D3DCAPS2_NO2DDURING3DSCENE) { + ddlogMessage(DDLOG_WARN, + "Warning : No 2D allowed during 3D scene.\n"); + } +#endif + + // + // Create the Direct3D context + // + +#ifdef _GLD_PERSISTANT + // Re-use original IDirect3DDevice if persistant buffers exist. + // Note that we test for persistant IDirect3D8 as well + // bDirectDrawPersistant == persistant IDirect3D8 (DirectDraw8 does not exist) + if (bDirectDrawPersistant && bPersistantBuffers && dx7Globals.pD3D && dx7Globals.pDev) { + lpCtx->pDev = dx7Globals.pDev; + IDirect3DDevice7_AddRef(dx7Globals.pDev); + goto skip_direct3ddevice_create; + } +#endif +/* + // Clear the presentation parameters (sets all members to zero) + ZeroMemory(&d3dpp, sizeof(d3dpp)); + + // Recommended by MS; needed for MultiSample. + // Be careful if altering this for FullScreenBlit + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + + d3dpp.BackBufferFormat = d3ddm.Format; + d3dpp.BackBufferCount = 1; + d3dpp.MultiSampleType = _gldGetDeviceMultiSampleType(lpCtx->pD3D, d3ddm.Format, d3dDevType, !ctx->bFullscreen); + d3dpp.AutoDepthStencilFormat = ctx->lpPF->dwDriverData; + d3dpp.EnableAutoDepthStencil = (d3dpp.AutoDepthStencilFormat == D3DFMT_UNKNOWN) ? FALSE : TRUE; + + if (ctx->bFullscreen) { + ddlogWarnOption(FALSE); // Don't popup any messages in fullscreen + d3dpp.Windowed = FALSE; + d3dpp.BackBufferWidth = d3ddm.Width; + d3dpp.BackBufferHeight = d3ddm.Height; + d3dpp.hDeviceWindow = ctx->hWnd; + d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; + + // Support for vertical retrace synchronisation. + // Set default presentation interval in case caps bits are missing + d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; + if (glb.bWaitForRetrace) { + if (lpCtx->d3dCaps8.PresentationIntervals & D3DPRESENT_INTERVAL_ONE) + d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_ONE; + } else { + if (lpCtx->d3dCaps8.PresentationIntervals & D3DPRESENT_INTERVAL_IMMEDIATE) + d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + } + } else { + ddlogWarnOption(glb.bMessageBoxWarnings); // OK to popup messages + d3dpp.Windowed = TRUE; + d3dpp.BackBufferWidth = ctx->dwWidth; + d3dpp.BackBufferHeight = ctx->dwHeight; + d3dpp.hDeviceWindow = ctx->hWnd; + d3dpp.FullScreen_RefreshRateInHz = 0; + // FullScreen_PresentationInterval must be default for Windowed mode + d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; + } + + // Decide if we can use hardware TnL + dwBehaviourFlags = (lpCtx->bHasHWTnL) ? + D3DCREATE_MIXED_VERTEXPROCESSING : D3DCREATE_SOFTWARE_VERTEXPROCESSING; + // Add flag to tell D3D to be thread-safe + if (glb.bMultiThreaded) + dwBehaviourFlags |= D3DCREATE_MULTITHREADED; + hResult = IDirect3D8_CreateDevice(lpCtx->pD3D, + glb.dwAdapter, + d3dDevType, + ctx->hWnd, + dwBehaviourFlags, + &d3dpp, + &lpCtx->pDev); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "IDirect3D8_CreateDevice failed", hResult); + nContextError = GLDERR_D3D; + goto return_with_error; + } +*/ + + // Create D3DX context + if (ctx->bFullscreen) { + // + // FULLSCREEN + // + + // Get display mode + D3DXGetCurrentVideoMode(D3DX_DEFAULT, &d3ddm); + + // Fullscreen Parameters + dwFlags = D3DX_CONTEXT_FULLSCREEN; + hwnd = ctx->hWnd; + hwndFocus = ctx->hWnd; + numColorBits = ctx->lpPF->pfd.cColorBits; + numAlphaBits = ctx->lpPF->pfd.cAlphaBits; + numDepthBits = ctx->lpPF->pfd.cDepthBits + ctx->lpPF->pfd.cStencilBits; + numStencilBits = ctx->lpPF->pfd.cStencilBits; + numBackBuffers = D3DX_DEFAULT; // Default is 1 backbuffer + dwWidth = d3ddm.width; + dwHeight = d3ddm.height; + refreshRate = d3ddm.refreshRate; // D3DX_DEFAULT; + } else { + // + // WINDOWED + // + + // Windowed Parameters + dwFlags = 0; // No flags means "windowed" + hwnd = ctx->hWnd; + hwndFocus = (HWND)D3DX_DEFAULT; + numColorBits = D3DX_DEFAULT; // Use Desktop depth + numAlphaBits = ctx->lpPF->pfd.cAlphaBits; + numDepthBits = ctx->lpPF->pfd.cDepthBits + ctx->lpPF->pfd.cStencilBits; + numStencilBits = ctx->lpPF->pfd.cStencilBits; + numBackBuffers = D3DX_DEFAULT; // Default is 1 backbuffer + dwWidth = ctx->dwWidth; + dwHeight = ctx->dwHeight; + refreshRate = D3DX_DEFAULT; + } + hr = D3DXCreateContextEx(dwDeviceIndex, dwFlags, hwnd, hwndFocus, + numColorBits, numAlphaBits, numDepthBits, numStencilBits, + numBackBuffers, + dwWidth, dwHeight, refreshRate, + &lpCtx->pD3DXContext); + if (FAILED(hr)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "D3DXCreateContextEx failed", hr); + nContextError = GLDERR_D3D; + goto return_with_error; + } + + // Obtain D3D7 interfaces from ID3DXContext +// lpCtx->pDD = ID3DXContext_GetDD(lpCtx->pD3DXContext); + lpCtx->pDD = lpCtx->pD3DXContext->lpVtbl->GetDD(lpCtx->pD3DXContext); + if (lpCtx->pDD == NULL) + goto return_with_error; + lpCtx->pD3D = lpCtx->pD3DXContext->lpVtbl->GetD3D(lpCtx->pD3DXContext); + if (lpCtx->pD3D == NULL) + goto return_with_error; + lpCtx->pDev = lpCtx->pD3DXContext->lpVtbl->GetD3DDevice(lpCtx->pD3DXContext); + if (lpCtx->pDev == NULL) + goto return_with_error; + + // Need to manage clipper manually for multiple windows + // since DX7 D3DX utility lib does not appear to do that. (DaveM) + if (!ctx->bFullscreen) { + // Get primary surface too + lpDDSPrimary = lpCtx->pD3DXContext->lpVtbl->GetPrimary(lpCtx->pD3DXContext); + if (lpDDSPrimary == NULL) { + ddlogPrintf(DDLOG_WARN, "GetPrimary"); + goto return_with_error; + } + // Create clipper for correct window updates + if (IDirectDraw7_CreateClipper(lpCtx->pDD, 0, &lpDDClipper, NULL) != DD_OK) { + ddlogPrintf(DDLOG_WARN, "CreateClipper"); + goto return_with_error; + } + // Set the window that the clipper belongs to + if (IDirectDrawClipper_SetHWnd(lpDDClipper, 0, hwnd) != DD_OK) { + ddlogPrintf(DDLOG_WARN, "SetHWnd"); + goto return_with_error; + } + // Attach the clipper to the primary surface + if (IDirectDrawSurface7_SetClipper(lpDDSPrimary, lpDDClipper) != DD_OK) { + ddlogPrintf(DDLOG_WARN, "SetClipper"); + goto return_with_error; + } + } + + // Get device caps + IDirect3DDevice7_GetCaps(lpCtx->pDev, &lpCtx->d3dCaps); + + // Determine HW TnL + lpCtx->bHasHWTnL = lpCtx->d3dCaps.dwDevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ? TRUE : FALSE; + +#ifdef _GLD_PERSISTANT + if (bDirectDrawPersistant && bPersistantBuffers && dx7Globals.pD3D) { + dx7Globals.pDev = lpCtx->pDev; + dx7Globals.bDirect3DDevice = TRUE; + } +#endif + +#if 0 + // Dump some useful stats + hResult = IDirect3D8_GetAdapterIdentifier( + lpCtx->pD3D, + glb.dwAdapter, + D3DENUM_NO_WHQL_LEVEL, // Avoids 1 to 2 second delay + &d3dIdent); + if (SUCCEEDED(hResult)) { + ddlogPrintf(DDLOG_INFO, "[Driver Description: %s]", &d3dIdent.Description); + ddlogPrintf(DDLOG_INFO, "[Driver file: %s %d.%d.%02d.%d]", + d3dIdent.Driver, + HIWORD(d3dIdent.DriverVersion.HighPart), + LOWORD(d3dIdent.DriverVersion.HighPart), + HIWORD(d3dIdent.DriverVersion.LowPart), + LOWORD(d3dIdent.DriverVersion.LowPart)); + ddlogPrintf(DDLOG_INFO, "[VendorId: 0x%X, DeviceId: 0x%X, SubSysId: 0x%X, Revision: 0x%X]", + d3dIdent.VendorId, d3dIdent.DeviceId, d3dIdent.SubSysId, d3dIdent.Revision); + } +#endif + + // Init projection matrix for D3D TnL + D3DXMatrixIdentity((D3DXMATRIX*)&lpCtx->matProjection); + lpCtx->matModelView = lpCtx->matProjection; +// gld->bUseMesaProjection = TRUE; + +skip_direct3ddevice_create: + + // Create buffers to hold primitives + lpCtx->PB2d.dwFVF = GLD_FVF_2D_VERTEX; +// lpCtx->PB2d.dwPool = D3DPOOL_SYSTEMMEM; + lpCtx->PB2d.dwStride = sizeof(GLD_2D_VERTEX); + lpCtx->PB2d.dwCreateFlags = D3DVBCAPS_DONOTCLIP | + D3DVBCAPS_SYSTEMMEMORY | + D3DVBCAPS_WRITEONLY; + hr = _gldCreatePrimitiveBuffer(ctx->glCtx, lpCtx, &lpCtx->PB2d); + if (FAILED(hr)) + goto return_with_error; + + lpCtx->PB3d.dwFVF = GLD_FVF_3D_VERTEX; +// lpCtx->PB3d.dwPool = D3DPOOL_DEFAULT; + lpCtx->PB3d.dwStride = sizeof(GLD_3D_VERTEX); + lpCtx->PB3d.dwCreateFlags = D3DVBCAPS_WRITEONLY; + + hr = _gldCreatePrimitiveBuffer(ctx->glCtx, lpCtx, &lpCtx->PB3d); + if (FAILED(hr)) + goto return_with_error; + + // Zero the pipeline usage counters + lpCtx->PipelineUsage.qwMesa.QuadPart = +// lpCtx->PipelineUsage.dwD3D2SVS.QuadPart = + lpCtx->PipelineUsage.qwD3DFVF.QuadPart = 0; + + // Assign drawable to GL private + ctx->glPriv = lpCtx; + return TRUE; + +return_with_error: + // Clean up and bail + _gldDestroyPrimitiveBuffer(&lpCtx->PB3d); + _gldDestroyPrimitiveBuffer(&lpCtx->PB2d); + + SAFE_RELEASE(lpCtx->pDev); + SAFE_RELEASE(lpCtx->pD3D); + //SAFE_RELEASE(lpCtx->pD3DXContext); + lpCtx->pD3DXContext->lpVtbl->Release(lpCtx->pD3DXContext); + return FALSE; +} + +//--------------------------------------------------------------------------- + +BOOL gldResizeDrawable_DX( + DGL_ctx *ctx, + BOOL bDefaultDriver, + BOOL bPersistantInterface, + BOOL bPersistantBuffers) +{ + GLD_driver_dx7 *gld = NULL; +// D3DDEVTYPE d3dDevType; +// D3DPRESENT_PARAMETERS d3dpp; +// D3DDISPLAYMODE d3ddm; + D3DX_VIDMODEDESC d3ddm; + HRESULT hr; + DWORD dwWidth, dwHeight; + + // Error if context is NULL. + if (ctx == NULL) + return FALSE; + + gld = ctx->glPriv; + if (gld == NULL) + return FALSE; + + if (ctx->bSceneStarted) { + IDirect3DDevice7_EndScene(gld->pDev); + ctx->bSceneStarted = FALSE; + } +/* + d3dDevType = (glb.dwDriver == GLDS_DRIVER_HAL) ? D3DDEVTYPE_HAL : D3DDEVTYPE_REF; + if (!bDefaultDriver) + d3dDevType = D3DDEVTYPE_REF; // Force Direct3D Reference Rasterise (software) + + // Get the display mode so we can make a compatible backbuffer + hResult = IDirect3D8_GetAdapterDisplayMode(gld->pD3D, glb.dwAdapter, &d3ddm); + if (FAILED(hResult)) { + nContextError = GLDERR_D3D; +// goto return_with_error; + return FALSE; + } +*/ + // Release objects before Reset() + _gldDestroyPrimitiveBuffer(&gld->PB3d); + _gldDestroyPrimitiveBuffer(&gld->PB2d); + +/* + // Clear the presentation parameters (sets all members to zero) + ZeroMemory(&d3dpp, sizeof(d3dpp)); + + // Recommended by MS; needed for MultiSample. + // Be careful if altering this for FullScreenBlit + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + + d3dpp.BackBufferFormat = d3ddm.Format; + d3dpp.BackBufferCount = 1; + d3dpp.MultiSampleType = _gldGetDeviceMultiSampleType(gld->pD3D, d3ddm.Format, d3dDevType, !ctx->bFullscreen); + d3dpp.AutoDepthStencilFormat = ctx->lpPF->dwDriverData; + d3dpp.EnableAutoDepthStencil = (d3dpp.AutoDepthStencilFormat == D3DFMT_UNKNOWN) ? FALSE : TRUE; + + // TODO: Sync to refresh + + if (ctx->bFullscreen) { + ddlogWarnOption(FALSE); // Don't popup any messages in fullscreen + d3dpp.Windowed = FALSE; + d3dpp.BackBufferWidth = d3ddm.Width; + d3dpp.BackBufferHeight = d3ddm.Height; + d3dpp.hDeviceWindow = ctx->hWnd; + d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; + d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; + // Get better benchmark results? KeithH +// d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_UNLIMITED; + } else { + ddlogWarnOption(glb.bMessageBoxWarnings); // OK to popup messages + d3dpp.Windowed = TRUE; + d3dpp.BackBufferWidth = ctx->dwWidth; + d3dpp.BackBufferHeight = ctx->dwHeight; + d3dpp.hDeviceWindow = ctx->hWnd; + d3dpp.FullScreen_RefreshRateInHz = 0; + d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; + } + hResult = IDirect3DDevice8_Reset(gld->pDev, &d3dpp); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: Reset failed", hResult); + return FALSE; + //goto cleanup_and_return_with_error; + } +*/ + // Obtain dimensions of 'window' + if (ctx->bFullscreen) { + D3DXGetCurrentVideoMode(D3DX_DEFAULT, &d3ddm); + dwWidth = d3ddm.width; + dwHeight = d3ddm.height; + } else { + dwWidth = ctx->dwWidth; + dwHeight = ctx->dwHeight; + } + + // Resize context + hr = gld->pD3DXContext->lpVtbl->Resize(gld->pD3DXContext, dwWidth, dwHeight); + if (FAILED(hr)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "gldResizeDrawable_DX: Resize failed", hr); + return FALSE; + } + + // Clear the resized surface (DaveM) + { + D3DVIEWPORT7 vp1, vp2; + IDirect3DDevice7_GetViewport(gld->pDev, &vp1); + IDirect3DDevice7_GetViewport(gld->pDev, &vp2); + vp2.dwX = 0; + vp2.dwY = 0; + vp2.dwWidth = dwWidth; + vp2.dwHeight = dwHeight; + IDirect3DDevice7_SetViewport(gld->pDev, &vp2); + hr = gld->pD3DXContext->lpVtbl->Clear(gld->pD3DXContext, D3DCLEAR_TARGET); + if (FAILED(hr)) + ddlogError(DDLOG_WARN, "gldResizeDrawable_DX: Clear failed", hr); + IDirect3DDevice7_SetViewport(gld->pDev, &vp1); + } + + // + // Recreate objects + // + _gldCreatePrimitiveBuffer(ctx->glCtx, gld, &gld->PB2d); + _gldCreatePrimitiveBuffer(ctx->glCtx, gld, &gld->PB3d); + + // Signal a complete state update + ctx->glCtx->Driver.UpdateState(ctx->glCtx, _NEW_ALL); + + // Begin a new scene + IDirect3DDevice7_BeginScene(gld->pDev); + ctx->bSceneStarted = TRUE; + + return TRUE; +} + +//--------------------------------------------------------------------------- + +BOOL gldDestroyDrawable_DX( + DGL_ctx *ctx) +{ + GLD_driver_dx7 *lpCtx = NULL; + + // Error if context is NULL. + if (!ctx) + return FALSE; + + // Error if the drawable does not exist. + if (!ctx->glPriv) + return FALSE; + + lpCtx = ctx->glPriv; + +#ifdef _DEBUG + // Dump out stats + ddlogPrintf(DDLOG_SYSTEM, "Usage: M:0x%X%X, D:0x%X%X", + lpCtx->PipelineUsage.qwMesa.HighPart, + lpCtx->PipelineUsage.qwMesa.LowPart, + lpCtx->PipelineUsage.qwD3DFVF.HighPart, + lpCtx->PipelineUsage.qwD3DFVF.LowPart); +#endif + + // Destroy Primtive Buffers + _gldDestroyPrimitiveBuffer(&lpCtx->PB3d); + _gldDestroyPrimitiveBuffer(&lpCtx->PB2d); + + // Release DX interfaces (in reverse order) + SAFE_RELEASE(lpCtx->pDev); + SAFE_RELEASE(lpCtx->pD3D); + //SAFE_RELEASE(lpCtx->pD3DXContext); + lpCtx->pD3DXContext->lpVtbl->Release(lpCtx->pD3DXContext); + + // Free the private drawable data + free(ctx->glPriv); + ctx->glPriv = NULL; + + return TRUE; +} + +//--------------------------------------------------------------------------- + +BOOL gldCreatePrivateGlobals_DX(void) +{ +/* + ZeroMemory(&dx7Globals, sizeof(dx7Globals)); + + // Load d3d8.dll + dx8Globals.hD3D8DLL = LoadLibrary("D3D8.DLL"); + if (dx8Globals.hD3D8DLL == NULL) + return FALSE; + + // Now try and obtain Direct3DCreate8 + dx8Globals.fnDirect3DCreate8 = (FNDIRECT3DCREATE8)GetProcAddress(dx8Globals.hD3D8DLL, "Direct3DCreate8"); + if (dx8Globals.fnDirect3DCreate8 == NULL) { + FreeLibrary(dx8Globals.hD3D8DLL); + return FALSE; + } +*/ + + // Initialise D3DX + return FAILED(D3DXInitialize()) ? FALSE : TRUE; +} + +//--------------------------------------------------------------------------- + +BOOL gldDestroyPrivateGlobals_DX(void) +{ +/* + if (dx7Globals.bDirect3DDevice) { + SAFE_RELEASE(dx7Globals.pDev); + dx7Globals.bDirect3DDevice = FALSE; + } + if (dx7Globals.bDirect3D) { + SAFE_RELEASE(dx7Globals.pD3D); + dx7Globals.bDirect3D = FALSE; + } + + FreeLibrary(dx8Globals.hD3D8DLL); + dx8Globals.hD3D8DLL = NULL; + dx8Globals.fnDirect3DCreate8 = NULL; +*/ + return FAILED(D3DXUninitialize()) ? FALSE : TRUE; +} + +//--------------------------------------------------------------------------- + +static void _BitsFromDisplayFormat( + D3DX_SURFACEFORMAT fmt, + BYTE *cColorBits, + BYTE *cRedBits, + BYTE *cGreenBits, + BYTE *cBlueBits, + BYTE *cAlphaBits) +{ + switch (fmt) { +/* case D3DX_SF_X1R5G5B5: + *cColorBits = 16; + *cRedBits = 5; + *cGreenBits = 5; + *cBlueBits = 5; + *cAlphaBits = 0; + return;*/ + case D3DX_SF_R5G5B5: + *cColorBits = 16; + *cRedBits = 5; + *cGreenBits = 5; + *cBlueBits = 5; + *cAlphaBits = 0; + return; + case D3DX_SF_R5G6B5: + *cColorBits = 16; + *cRedBits = 5; + *cGreenBits = 6; + *cBlueBits = 5; + *cAlphaBits = 0; + return; + case D3DX_SF_X8R8G8B8: + *cColorBits = 32; + *cRedBits = 8; + *cGreenBits = 8; + *cBlueBits = 8; + *cAlphaBits = 0; + return; + case D3DX_SF_A8R8G8B8: + *cColorBits = 32; + *cRedBits = 8; + *cGreenBits = 8; + *cBlueBits = 8; + *cAlphaBits = 8; + return; + } + + // Should not get here! + *cColorBits = 32; + *cRedBits = 8; + *cGreenBits = 8; + *cBlueBits = 8; + *cAlphaBits = 0; +} + +//--------------------------------------------------------------------------- + +static void _BitsFromDepthStencilFormat( + D3DX_SURFACEFORMAT fmt, + BYTE *cDepthBits, + BYTE *cStencilBits) +{ + // NOTE: GL expects either 32 or 16 as depth bits. + switch (fmt) { + case D3DX_SF_Z16S0: + *cDepthBits = 16; + *cStencilBits = 0; + return; + case D3DX_SF_Z32S0: + *cDepthBits = 32; + *cStencilBits = 0; + return; + case D3DX_SF_Z15S1: + *cDepthBits = 15; + *cStencilBits = 1; + return; + case D3DX_SF_Z24S8: + *cDepthBits = 24; + *cStencilBits = 8; + return; + case D3DX_SF_S1Z15: + *cDepthBits = 15; + *cStencilBits = 1; + return; + case D3DX_SF_S8Z24: + *cDepthBits = 24; + *cStencilBits = 8; + return; + } +} + +//--------------------------------------------------------------------------- +/* +BOOL GLD_CheckDepthStencilMatch( + DWORD dwDeviceIndex, + D3DX_SURFACEFORMAT sfWant) +{ + // Emulate function built in to DX9 + D3DX_SURFACEFORMAT sfFound; + int i; + int nFormats = D3DXGetMaxSurfaceFormats(dwDeviceIndex, NULL, D3DX_SC_DEPTHBUFFER); + if (nFormats) { + for (i=0; ilpVtbl->GetZBuffer(pD3DXContext); + + // Get pixel format of depth buffer + ddpf.dwSize = sizeof(ddpf); + pZBuffer->lpVtbl->GetPixelFormat(pZBuffer, &ddpf); + // Done with surface - release it + pZBuffer->lpVtbl->Release(pZBuffer); + + // Done with D3DX context + pD3DXContext->lpVtbl->Release(pD3DXContext); + + // Convert and return + return D3DXMakeSurfaceFormat(&ddpf); +} + +//--------------------------------------------------------------------------- + +BOOL gldBuildPixelformatList_DX(void) +{ + D3DX_DEVICEDESC d3dxdd; + D3DX_VIDMODEDESC d3ddm; + D3DX_SURFACEFORMAT fmt[64]; // 64 should be enough... + DWORD dwDeviceIndex; + DWORD surfClassFlags; +// IDirect3D7 *pD3D = NULL; + HRESULT hr; + int nSupportedFormats = 0; // Total formats + int nDepthOnlyFormats = 0; + int nDepthStencilFormats = 0; + int i; + DGL_pixelFormat *pPF; + BYTE cColorBits, cRedBits, cGreenBits, cBlueBits, cAlphaBits; +// char buf[128]; +// char cat[8]; + + // Direct3D (SW or HW) + // These are arranged so that 'best' pixelformat + // is higher in the list (for ChoosePixelFormat). +/* const D3DFORMAT DepthStencil[4] = { + D3DX_SF_Z16S0, //D3DX_SF_D16, + D3DX_SF_Z15S1, //D3DX_SF_D15S1, + D3DX_SF_Z32S0, //D3DX_SF_D32, + D3DX_SF_Z24S8, //D3DX_SF_D24S8, + //D3DX_SF_D24X8, + //D3DX_SF_D24X4S4, + };*/ + + // Dump DX version + ddlogMessage(GLDLOG_SYSTEM, "DirectX Version : 7.0\n"); + + // Release any existing pixelformat list + if (glb.lpPF) { + free(glb.lpPF); + } + + glb.nPixelFormatCount = 0; + glb.lpPF = NULL; + + // + // Pixelformats for Direct3D (SW or HW) rendering + // + + dwDeviceIndex = (glb.dwDriver == GLDS_DRIVER_REF) ? D3DX_HWLEVEL_REFERENCE : D3DX_DEFAULT; + + // Dump description + D3DXGetDeviceDescription(dwDeviceIndex, &d3dxdd); + ddlogPrintf(GLDLOG_SYSTEM, "Device: %s", d3dxdd.driverDesc); + + // Get display mode + D3DXGetCurrentVideoMode(D3DX_DEFAULT, &d3ddm); + +#if 0 + // Phooey - this don't work... +/* + // Since D3DXGetMaxSurfaceFormats() can lie to us, we'll need a workaround. + // Explicitly test for matching depth/stencil to display bpp. + if (d3ddm.bpp <= 16) { + if (GLD_CheckDepthStencilMatch(dwDeviceIndex, D3DX_SF_Z16S0)) + fmt[nSupportedFormats++] = D3DX_SF_Z16S0; + if (GLD_CheckDepthStencilMatch(dwDeviceIndex, D3DX_SF_Z15S1)) + fmt[nSupportedFormats++] = D3DX_SF_Z15S1; + if (GLD_CheckDepthStencilMatch(dwDeviceIndex, D3DX_SF_S1Z15)) + fmt[nSupportedFormats++] = D3DX_SF_S1Z15; + // Didn't find anything? Try default + if (nSupportedFormats == 0) { + if (GLD_CheckDepthStencilMatch(dwDeviceIndex, D3DX_SF_Z32S0)) + fmt[nSupportedFormats++] = D3DX_SF_Z32S0; + } + } else { + if (GLD_CheckDepthStencilMatch(dwDeviceIndex, D3DX_SF_Z32S0)) + fmt[nSupportedFormats++] = D3DX_SF_Z32S0; + if (GLD_CheckDepthStencilMatch(dwDeviceIndex, D3DX_SF_Z24S8)) + fmt[nSupportedFormats++] = D3DX_SF_Z24S8; + if (GLD_CheckDepthStencilMatch(dwDeviceIndex, D3DX_SF_S8Z24)) + fmt[nSupportedFormats++] = D3DX_SF_S8Z24; + // Didn't find anything? Try default + if (nSupportedFormats == 0) { + if (GLD_CheckDepthStencilMatch(dwDeviceIndex, D3DX_SF_Z16S0)) + fmt[nSupportedFormats++] = D3DX_SF_Z16S0; + } + } +*/ + // Go the Whole Hog... + fmt[nSupportedFormats++] = _gldFindCompatibleDepthStencilFormat(dwDeviceIndex); +#else + // + // Depth buffer formats WITHOUT stencil + // + surfClassFlags = D3DX_SC_DEPTHBUFFER; + nDepthOnlyFormats = D3DXGetMaxSurfaceFormats(dwDeviceIndex, NULL, surfClassFlags); + // + // Depth buffer formats WITH stencil + // + surfClassFlags = D3DX_SC_DEPTHBUFFER | D3DX_SC_STENCILBUFFER; + nDepthStencilFormats = D3DXGetMaxSurfaceFormats(dwDeviceIndex, NULL, surfClassFlags); + + // Work out how many formats we have in total + if ((nDepthOnlyFormats + nDepthStencilFormats) == 0) + return FALSE; // Bail: no compliant pixelformats + + // Get depth buffer formats WITHOUT stencil + surfClassFlags = D3DX_SC_DEPTHBUFFER; + for (i=0; ipfd.dwFlags &= ~PFD_DOUBLEBUFFER; // Remove doublebuffer flag + pPF->pfd.cColorBits = cColorBits; + pPF->pfd.cRedBits = cRedBits; + pPF->pfd.cGreenBits = cGreenBits; + pPF->pfd.cBlueBits = cBlueBits; + pPF->pfd.cAlphaBits = cAlphaBits; + pPF->pfd.cDepthBits = 0; + pPF->pfd.cStencilBits = 0; + pPF->dwDriverData = D3DX_SF_UNKNOWN; + pPF++;*/ + + for (i=0; ipfd.dwFlags &= ~PFD_DOUBLEBUFFER; // Remove doublebuffer flag + pPF->pfd.cColorBits = cColorBits; + pPF->pfd.cRedBits = cRedBits; + pPF->pfd.cGreenBits = cGreenBits; + pPF->pfd.cBlueBits = cBlueBits; + pPF->pfd.cAlphaBits = cAlphaBits; + _BitsFromDepthStencilFormat(fmt[i], &pPF->pfd.cDepthBits, &pPF->pfd.cStencilBits); + pPF->dwDriverData = fmt[i]; + } + + // + // Add double-buffer formats + // + +/* memcpy(pPF, &pfTemplateHW, sizeof(DGL_pixelFormat)); + pPF->pfd.cColorBits = cColorBits; + pPF->pfd.cRedBits = cRedBits; + pPF->pfd.cGreenBits = cGreenBits; + pPF->pfd.cBlueBits = cBlueBits; + pPF->pfd.cAlphaBits = cAlphaBits; + pPF->pfd.cDepthBits = 0; + pPF->pfd.cStencilBits = 0; + pPF->dwDriverData = D3DX_SF_UNKNOWN; + pPF++;*/ + + for (i=0; ipfd.cColorBits = cColorBits; + pPF->pfd.cRedBits = cRedBits; + pPF->pfd.cGreenBits = cGreenBits; + pPF->pfd.cBlueBits = cBlueBits; + pPF->pfd.cAlphaBits = cAlphaBits; + _BitsFromDepthStencilFormat(fmt[i], &pPF->pfd.cDepthBits, &pPF->pfd.cStencilBits); + pPF->dwDriverData = fmt[i]; + } + + // Popup warning message if non RGB color mode + { + // This is a hack. KeithH + HDC hdcDesktop = GetDC(NULL); + DWORD dwDisplayBitDepth = GetDeviceCaps(hdcDesktop, BITSPIXEL); + ReleaseDC(0, hdcDesktop); + if (dwDisplayBitDepth <= 8) { + ddlogPrintf(DDLOG_WARN, "Current Color Depth %d bpp is not supported", dwDisplayBitDepth); + MessageBox(NULL, szColorDepthWarning, "GLDirect", MB_OK | MB_ICONWARNING); + } + } + + // Mark list as 'current' + glb.bPixelformatsDirty = FALSE; + + return TRUE; +} + +//--------------------------------------------------------------------------- + +BOOL gldInitialiseMesa_DX( + DGL_ctx *lpCtx) +{ + GLD_driver_dx7 *gld = NULL; + int MaxTextureSize, TextureLevels; + BOOL bSoftwareTnL; + + if (lpCtx == NULL) + return FALSE; + + gld = lpCtx->glPriv; + if (gld == NULL) + return FALSE; + + if (glb.bMultitexture) { + lpCtx->glCtx->Const.MaxTextureUnits = gld->d3dCaps.wMaxSimultaneousTextures; + // Only support MAX_TEXTURE_UNITS texture units. + // ** If this is altered then the FVF formats must be reviewed **. + if (lpCtx->glCtx->Const.MaxTextureUnits > GLD_MAX_TEXTURE_UNITS_DX7) + lpCtx->glCtx->Const.MaxTextureUnits = GLD_MAX_TEXTURE_UNITS_DX7; + } else { + // Multitexture override + lpCtx->glCtx->Const.MaxTextureUnits = 1; + } + + lpCtx->glCtx->Const.MaxDrawBuffers = 1; + + // max texture size +// MaxTextureSize = min(gld->d3dCaps8.MaxTextureHeight, gld->d3dCaps8.MaxTextureWidth); + MaxTextureSize = min(gld->d3dCaps.dwMaxTextureHeight, gld->d3dCaps.dwMaxTextureWidth); + if (MaxTextureSize == 0) + MaxTextureSize = 256; // Sanity check + + // + // HACK!! + if (MaxTextureSize > 1024) + MaxTextureSize = 1024; // HACK - CLAMP TO 1024 + // HACK!! + // + + // TODO: Check this again for Mesa 5 + // Got to set MAX_TEXTURE_SIZE as max levels. + // Who thought this stupid idea up? ;) + TextureLevels = 0; + // Calculate power-of-two. + while (MaxTextureSize) { + TextureLevels++; + MaxTextureSize >>= 1; + } + lpCtx->glCtx->Const.MaxTextureLevels = (TextureLevels) ? TextureLevels : 8; + + // Defaults + IDirect3DDevice7_SetRenderState(gld->pDev, D3DRENDERSTATE_LIGHTING, FALSE); + IDirect3DDevice7_SetRenderState(gld->pDev, D3DRENDERSTATE_CULLMODE, D3DCULL_NONE); + IDirect3DDevice7_SetRenderState(gld->pDev, D3DRENDERSTATE_DITHERENABLE, TRUE); + IDirect3DDevice7_SetRenderState(gld->pDev, D3DRENDERSTATE_SHADEMODE, D3DSHADE_GOURAUD); + + // Set texture coord set to be used with each stage + IDirect3DDevice7_SetTextureStageState(gld->pDev, 0, D3DTSS_TEXCOORDINDEX, 0); + IDirect3DDevice7_SetTextureStageState(gld->pDev, 1, D3DTSS_TEXCOORDINDEX, 1); + + // Set up Depth buffer + IDirect3DDevice7_SetRenderState(gld->pDev, D3DRENDERSTATE_ZENABLE, + (lpCtx->lpPF->dwDriverData!=D3DX_SF_UNKNOWN) ? D3DZB_TRUE : D3DZB_FALSE); + + // Set the view matrix + { + D3DXMATRIX vm; +#if 1 + D3DXMatrixIdentity(&vm); +#else + D3DXVECTOR3 Eye(0.0f, 0.0f, 0.0f); + D3DXVECTOR3 At(0.0f, 0.0f, -1.0f); + D3DXVECTOR3 Up(0.0f, 1.0f, 0.0f); + D3DXMatrixLookAtRH(&vm, &Eye, &At, &Up); + vm._31 = -vm._31; + vm._32 = -vm._32; + vm._33 = -vm._33; + vm._34 = -vm._34; +#endif + IDirect3DDevice7_SetTransform(gld->pDev, D3DTRANSFORMSTATE_VIEW, &vm); + } + +// DX7 does not support D3DRS_SOFTWAREVERTEXPROCESSING +/* + if (gld->bHasHWTnL) { + if (glb.dwTnL == GLDS_TNL_DEFAULT) + bSoftwareTnL = FALSE; // HW TnL + else { + bSoftwareTnL = ((glb.dwTnL == GLDS_TNL_MESA) || (glb.dwTnL == GLDS_TNL_D3DSW)) ? TRUE : FALSE; + } + } else { + // No HW TnL, so no choice possible + bSoftwareTnL = TRUE; + } + IDirect3DDevice8_SetRenderState(gld->pDev, D3DRS_SOFTWAREVERTEXPROCESSING, bSoftwareTnL); +*/ + +// Dump this in a Release build as well, now. +//#ifdef _DEBUG + ddlogPrintf(DDLOG_INFO, "HW TnL: %s", +// gld->bHasHWTnL ? (bSoftwareTnL ? "Disabled" : "Enabled") : "Unavailable"); + gld->bHasHWTnL ? "Enabled" : "Unavailable"); +//#endif + + // Set up interfaces to Mesa + gldEnableExtensions_DX7(lpCtx->glCtx); + gldInstallPipeline_DX7(lpCtx->glCtx); + gldSetupDriverPointers_DX7(lpCtx->glCtx); + + // Signal a complete state update + lpCtx->glCtx->Driver.UpdateState(lpCtx->glCtx, _NEW_ALL); + + // Start a scene + IDirect3DDevice7_BeginScene(gld->pDev); + lpCtx->bSceneStarted = TRUE; + + return TRUE; +} + +//--------------------------------------------------------------------------- + +BOOL gldSwapBuffers_DX( + DGL_ctx *ctx, + HDC hDC, + HWND hWnd) +{ + HRESULT hr; + GLD_driver_dx7 *gld = NULL; + DWORD dwFlags; + + if (ctx == NULL) + return FALSE; + + gld = ctx->glPriv; + if (gld == NULL) + return FALSE; + + + // End the scene if one is started + if (ctx->bSceneStarted) { + IDirect3DDevice7_EndScene(gld->pDev); + ctx->bSceneStarted = FALSE; + } + + // Needed by D3DX for MDI multi-window apps (DaveM) + if (lpDDClipper) + IDirectDrawClipper_SetHWnd(lpDDClipper, 0, hWnd); + + // Swap the buffers. hWnd may override the hWnd used for CreateDevice() +// hr = IDirect3DDevice8_Present(gld->pDev, NULL, NULL, hWnd, NULL); + + // Set refresh sync flag + dwFlags = glb.bWaitForRetrace ? 0 : D3DX_UPDATE_NOVSYNC; + // Render and show frame + hr = gld->pD3DXContext->lpVtbl->UpdateFrame(gld->pD3DXContext, dwFlags); + if (FAILED(hr)) + ddlogError(DDLOG_WARN, "gldSwapBuffers_DX: UpdateFrame", hr); + + if (hr == DDERR_SURFACELOST) { + hr = gld->pD3DXContext->lpVtbl->RestoreSurfaces(gld->pD3DXContext); + if (FAILED(hr)) + ddlogError(DDLOG_WARN, "gldSwapBuffers_DX: RestoreSurfaces", hr); + } + +exit_swap: + // Begin a new scene + IDirect3DDevice7_BeginScene(gld->pDev); + ctx->bSceneStarted = TRUE; + + return (FAILED(hr)) ? FALSE : TRUE; +} + +//--------------------------------------------------------------------------- + +BOOL gldGetDisplayMode_DX( + DGL_ctx *ctx, + GLD_displayMode *glddm) +{ +// D3DDISPLAYMODE d3ddm; + D3DX_VIDMODEDESC d3ddm; + HRESULT hr; + GLD_driver_dx7 *lpCtx = NULL; + BYTE cColorBits, cRedBits, cGreenBits, cBlueBits, cAlphaBits; + + if ((glddm == NULL) || (ctx == NULL)) + return FALSE; + + lpCtx = ctx->glPriv; + if (lpCtx == NULL) + return FALSE; + + if (lpCtx->pD3D == NULL) + return FALSE; + +// hr = IDirect3D8_GetAdapterDisplayMode(lpCtx->pD3D, glb.dwAdapter, &d3ddm); + hr = D3DXGetCurrentVideoMode(D3DX_DEFAULT, &d3ddm); + if (FAILED(hr)) + return FALSE; + + // Get info from the display format +// _BitsFromDisplayFormat(d3ddm.Format, +// &cColorBits, &cRedBits, &cGreenBits, &cBlueBits, &cAlphaBits); + + glddm->Width = d3ddm.width; + glddm->Height = d3ddm.height; + glddm->BPP = d3ddm.bpp; + glddm->Refresh = d3ddm.refreshRate; + + return TRUE; +} + +//--------------------------------------------------------------------------- + diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_driver_dx8.c b/mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_driver_dx8.c new file mode 100644 index 000000000..7afa9190c --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_driver_dx8.c @@ -0,0 +1,1176 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x/2000/XP/XBox (Win32) +* +* Description: Driver interface code to Mesa +* +****************************************************************************/ + +//#include +#include "dglcontext.h" +#include "ddlog.h" +#include "gld_dx8.h" + +#include "glheader.h" +#include "context.h" +#include "colormac.h" +#include "depth.h" +#include "extensions.h" +#include "macros.h" +#include "matrix.h" +// #include "mem.h" +//#include "mmath.h" +#include "mtypes.h" +#include "texformat.h" +#include "teximage.h" +#include "texstore.h" +#include "vbo/vbo.h" +#include "swrast_setup/swrast_setup.h" +#include "swrast_setup/ss_context.h" +#include "tnl/tnl.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" + +extern BOOL dglSwapBuffers(HDC hDC); + +// HACK: Hack the _33 member of the OpenGL perspective projection matrix +const float _fPersp_33 = 1.6f; + +//--------------------------------------------------------------------------- +// Internal functions +//--------------------------------------------------------------------------- + +void _gld_mesa_warning( + __GLcontext *gc, + char *str) +{ + // Intercept Mesa's internal warning mechanism + gldLogPrintf(GLDLOG_WARN, "Mesa warning: %s", str); +} + +//--------------------------------------------------------------------------- + +void _gld_mesa_fatal( + __GLcontext *gc, + char *str) +{ + // Intercept Mesa's internal fatal-message mechanism + gldLogPrintf(GLDLOG_CRITICAL, "Mesa FATAL: %s", str); + + // Mesa calls abort(0) here. + ddlogClose(); + exit(0); +} + +//--------------------------------------------------------------------------- + +D3DSTENCILOP _gldConvertStencilOp( + GLenum StencilOp) +{ + // Used by Stencil: pass, fail and zfail + + switch (StencilOp) { + case GL_KEEP: + return D3DSTENCILOP_KEEP; + case GL_ZERO: + return D3DSTENCILOP_ZERO; + case GL_REPLACE: + return D3DSTENCILOP_REPLACE; + case GL_INCR: + return D3DSTENCILOP_INCRSAT; + case GL_DECR: + return D3DSTENCILOP_DECRSAT; + case GL_INVERT: + return D3DSTENCILOP_INVERT; + case GL_INCR_WRAP_EXT: // GL_EXT_stencil_wrap + return D3DSTENCILOP_INCR; + case GL_DECR_WRAP_EXT: // GL_EXT_stencil_wrap + return D3DSTENCILOP_DECR; + } + +#ifdef _DEBUG + gldLogMessage(GLDLOG_ERROR, "_gldConvertStencilOp: Unknown StencilOp\n"); +#endif + + return D3DSTENCILOP_KEEP; +} + +//--------------------------------------------------------------------------- + +D3DCMPFUNC _gldConvertCompareFunc( + GLenum CmpFunc) +{ + // Used for Alpha func, depth func and stencil func. + + switch (CmpFunc) { + case GL_NEVER: + return D3DCMP_NEVER; + case GL_LESS: + return D3DCMP_LESS; + case GL_EQUAL: + return D3DCMP_EQUAL; + case GL_LEQUAL: + return D3DCMP_LESSEQUAL; + case GL_GREATER: + return D3DCMP_GREATER; + case GL_NOTEQUAL: + return D3DCMP_NOTEQUAL; + case GL_GEQUAL: + return D3DCMP_GREATEREQUAL; + case GL_ALWAYS: + return D3DCMP_ALWAYS; + }; + +#ifdef _DEBUG + gldLogMessage(GLDLOG_ERROR, "_gldConvertCompareFunc: Unknown CompareFunc\n"); +#endif + + return D3DCMP_ALWAYS; +} + +//--------------------------------------------------------------------------- + +D3DBLEND _gldConvertBlendFunc( + GLenum blend, + GLenum DefaultBlend) +{ + switch (blend) { + case GL_ZERO: + return D3DBLEND_ZERO; + case GL_ONE: + return D3DBLEND_ONE; + case GL_DST_COLOR: + return D3DBLEND_DESTCOLOR; + case GL_SRC_COLOR: + return D3DBLEND_SRCCOLOR; + case GL_ONE_MINUS_DST_COLOR: + return D3DBLEND_INVDESTCOLOR; + case GL_ONE_MINUS_SRC_COLOR: + return D3DBLEND_INVSRCCOLOR; + case GL_SRC_ALPHA: + return D3DBLEND_SRCALPHA; + case GL_ONE_MINUS_SRC_ALPHA: + return D3DBLEND_INVSRCALPHA; + case GL_DST_ALPHA: + return D3DBLEND_DESTALPHA; + case GL_ONE_MINUS_DST_ALPHA: + return D3DBLEND_INVDESTALPHA; + case GL_SRC_ALPHA_SATURATE: + return D3DBLEND_SRCALPHASAT; + } + +#ifdef _DEBUG + gldLogMessage(GLDLOG_ERROR, "_gldConvertBlendFunc: Unknown BlendFunc\n"); +#endif + + return DefaultBlend; +} + +//--------------------------------------------------------------------------- +// Misc. functions +//--------------------------------------------------------------------------- + +void gld_Noop_DX8( + GLcontext *ctx) +{ +#ifdef _DEBUG + gldLogMessage(GLDLOG_ERROR, "gld_Noop called!\n"); +#endif +} + +//--------------------------------------------------------------------------- + +void gld_Error_DX8( + GLcontext *ctx) +{ +#ifdef _DEBUG + // Quite useless. +// gldLogMessage(GLDLOG_ERROR, "ctx->Driver.Error called!\n"); +#endif +} + +//--------------------------------------------------------------------------- +// Required Mesa functions +//--------------------------------------------------------------------------- + +static GLboolean gld_set_draw_buffer_DX8( + GLcontext *ctx, + GLenum mode) +{ + (void) ctx; + if ((mode==GL_FRONT_LEFT) || (mode == GL_BACK_LEFT)) { + return GL_TRUE; + } + else { + return GL_FALSE; + } +} + +//--------------------------------------------------------------------------- + +static void gld_set_read_buffer_DX8( + GLcontext *ctx, + GLframebuffer *buffer, + GLenum mode) +{ + /* separate read buffer not supported */ +/* + ASSERT(buffer == ctx->DrawBuffer); + ASSERT(mode == GL_FRONT_LEFT); +*/ +} + +//--------------------------------------------------------------------------- + +void gld_Clear_DX8( + GLcontext *ctx, + GLbitfield mask, + GLboolean all, + GLint x, + GLint y, + GLint width, + GLint height) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx); + + DWORD dwFlags = 0; + D3DCOLOR Color = 0; + float Z = 0.0f; + DWORD Stencil = 0; + D3DRECT d3dClearRect; + + // TODO: Colourmask + const GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask; + + if (!gld->pDev) + return; + + if (mask & (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT)) { + GLubyte col[4]; + CLAMPED_FLOAT_TO_UBYTE(col[0], ctx->Color.ClearColor[0]); + CLAMPED_FLOAT_TO_UBYTE(col[1], ctx->Color.ClearColor[1]); + CLAMPED_FLOAT_TO_UBYTE(col[2], ctx->Color.ClearColor[2]); + CLAMPED_FLOAT_TO_UBYTE(col[3], ctx->Color.ClearColor[3]); + dwFlags |= D3DCLEAR_TARGET; + Color = D3DCOLOR_RGBA(col[0], col[1], col[2], col[3]); +// ctx->Color.ClearColor[1], +// ctx->Color.ClearColor[2], +// ctx->Color.ClearColor[3]); + } + + if (mask & DD_DEPTH_BIT) { + // D3D8 will fail the Clear call if we try and clear a + // depth buffer and we haven't created one. + // Also, some apps try and clear a depth buffer, + // when a depth buffer hasn't been requested by the app. + if (ctx->Visual.depthBits == 0) { + mask &= ~DD_DEPTH_BIT; // Remove depth bit from mask + } else { + dwFlags |= D3DCLEAR_ZBUFFER; + Z = ctx->Depth.Clear; + } + } + + if (mask & DD_STENCIL_BIT) { + if (ctx->Visual.stencilBits == 0) { + // No stencil bits in depth buffer + mask &= ~DD_STENCIL_BIT; // Remove stencil bit from mask + } else { + dwFlags |= D3DCLEAR_STENCIL; + Stencil = ctx->Stencil.Clear; + } + } + + // Some apps do really weird things with the rect, such as Quake3. + if ((x < 0) || (y < 0) || (width <= 0) || (height <= 0)) { + all = GL_TRUE; + } + + if (!all) { + // Calculate clear subrect + d3dClearRect.x1 = x; + d3dClearRect.y1 = gldCtx->dwHeight - (y + height); + d3dClearRect.x2 = x + width; + d3dClearRect.y2 = d3dClearRect.y1 + height; + } + + // dwFlags will be zero if there's nothing to clear + if (dwFlags) { + _GLD_DX8_DEV(Clear( + gld->pDev, + all ? 0 : 1, + all ? NULL : &d3dClearRect, + dwFlags, + Color, Z, Stencil)); + } + + if (mask & DD_ACCUM_BIT) { + // Clear accumulation buffer + } +} + +//--------------------------------------------------------------------------- + +// Mesa 5: Parameter change +static void gld_buffer_size_DX8( +// GLcontext *ctx, + GLframebuffer *fb, + GLuint *width, + GLuint *height) +{ +// GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + + *width = fb->Width; // gldCtx->dwWidth; + *height = fb->Height; // gldCtx->dwHeight; +} + +//--------------------------------------------------------------------------- + +static void gld_Finish_DX8( + GLcontext *ctx) +{ +} + +//--------------------------------------------------------------------------- + +static void gld_Flush_DX8( + GLcontext *ctx) +{ + GLD_context *gld = GLD_GET_CONTEXT(ctx); + + // TODO: Detect apps that glFlush() then SwapBuffers() ? + + if (gld->EmulateSingle) { + // Emulating a single-buffered context. + // [Direct3D doesn't allow rendering to front buffer] + dglSwapBuffers(gld->hDC); + } +} + +//--------------------------------------------------------------------------- + +void gld_NEW_STENCIL( + GLcontext *ctx) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx); + + // Two-sided stencil. New for Mesa 5 + const GLuint uiFace = 0UL; + + struct gl_stencil_attrib *pStencil = &ctx->Stencil; + + _GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_STENCILENABLE, pStencil->Enabled ? TRUE : FALSE)); + if (pStencil->Enabled) { + _GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_STENCILFUNC, _gldConvertCompareFunc(pStencil->Function[uiFace]))); + _GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_STENCILREF, pStencil->Ref[uiFace])); + _GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_STENCILMASK, pStencil->ValueMask[uiFace])); + _GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_STENCILWRITEMASK, pStencil->WriteMask[uiFace])); + _GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_STENCILFAIL, _gldConvertStencilOp(pStencil->FailFunc[uiFace]))); + _GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_STENCILZFAIL, _gldConvertStencilOp(pStencil->ZFailFunc[uiFace]))); + _GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_STENCILPASS, _gldConvertStencilOp(pStencil->ZPassFunc[uiFace]))); + } +} + +//--------------------------------------------------------------------------- + +void gld_NEW_COLOR( + GLcontext *ctx) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx); + + DWORD dwFlags = 0; + D3DBLEND src; + D3DBLEND dest; + + // Alpha func + _GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_ALPHAFUNC, _gldConvertCompareFunc(ctx->Color.AlphaFunc))); + _GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_ALPHAREF, (DWORD)ctx->Color.AlphaRef)); + _GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_ALPHATESTENABLE, ctx->Color.AlphaEnabled)); + + // Blend func + _GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_ALPHABLENDENABLE, ctx->Color.BlendEnabled)); + src = _gldConvertBlendFunc(ctx->Color.BlendSrcRGB, GL_ONE); + dest = _gldConvertBlendFunc(ctx->Color.BlendDstRGB, GL_ZERO); + _GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_SRCBLEND, src)); + _GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_DESTBLEND, dest)); + + // Color mask + if (ctx->Color.ColorMask[0]) dwFlags |= D3DCOLORWRITEENABLE_RED; + if (ctx->Color.ColorMask[1]) dwFlags |= D3DCOLORWRITEENABLE_GREEN; + if (ctx->Color.ColorMask[2]) dwFlags |= D3DCOLORWRITEENABLE_BLUE; + if (ctx->Color.ColorMask[3]) dwFlags |= D3DCOLORWRITEENABLE_ALPHA; + _GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_COLORWRITEENABLE, dwFlags)); +} + +//--------------------------------------------------------------------------- + +void gld_NEW_DEPTH( + GLcontext *ctx) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx); + + _GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_ZENABLE, ctx->Depth.Test ? D3DZB_TRUE : D3DZB_FALSE)); + _GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_ZFUNC, _gldConvertCompareFunc(ctx->Depth.Func))); + _GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_ZWRITEENABLE, ctx->Depth.Mask ? TRUE : FALSE)); +} + +//--------------------------------------------------------------------------- + +void gld_NEW_POLYGON( + GLcontext *ctx) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx); + + D3DFILLMODE d3dFillMode = D3DFILL_SOLID; + D3DCULL d3dCullMode = D3DCULL_NONE; + int iOffset = 0; + + // Fillmode + switch (ctx->Polygon.FrontMode) { + case GL_POINT: + d3dFillMode = D3DFILL_POINT; + break; + case GL_LINE: + d3dFillMode = D3DFILL_WIREFRAME; + break; + case GL_FILL: + d3dFillMode = D3DFILL_SOLID; + break; + } + _GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_FILLMODE, d3dFillMode)); + + if (ctx->Polygon.CullFlag) { + switch (ctx->Polygon.CullFaceMode) { + case GL_BACK: + if (ctx->Polygon.FrontFace == GL_CCW) + d3dCullMode = D3DCULL_CW; + else + d3dCullMode = D3DCULL_CCW; + break; + case GL_FRONT: + if (ctx->Polygon.FrontFace == GL_CCW) + d3dCullMode = D3DCULL_CCW; + else + d3dCullMode = D3DCULL_CW; + break; + case GL_FRONT_AND_BACK: + d3dCullMode = D3DCULL_NONE; + break; + default: + break; + } + } else { + d3dCullMode = D3DCULL_NONE; + } +// d3dCullMode = D3DCULL_NONE; // TODO: DEBUGGING + _GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_CULLMODE, d3dCullMode)); + + // Polygon offset + // ZBIAS ranges from 0 to 16 and can only move towards the viewer + // Mesa5: ctx->Polygon._OffsetAny removed + if (ctx->Polygon.OffsetFill) { + iOffset = (int)ctx->Polygon.OffsetUnits; + if (iOffset < 0) + iOffset = -iOffset; + else + iOffset = 0; // D3D can't push away + } + _GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_ZBIAS, iOffset)); +} + +//--------------------------------------------------------------------------- + +void gld_NEW_FOG( + GLcontext *ctx) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx); + + D3DCOLOR d3dFogColour; + D3DFOGMODE d3dFogMode = D3DFOG_LINEAR; + + // TODO: Fog is calculated seperately in the Mesa pipeline + _GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_FOGENABLE, FALSE)); + return; + + // Fog enable + _GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_FOGENABLE, ctx->Fog.Enabled)); + if (!ctx->Fog.Enabled) { + _GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_FOGTABLEMODE, D3DFOG_NONE)); + _GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_FOGVERTEXMODE, D3DFOG_NONE)); + return; // If disabled, don't bother setting any fog state + } + + // Fog colour + d3dFogColour = D3DCOLOR_COLORVALUE( ctx->Fog.Color[0], + ctx->Fog.Color[1], + ctx->Fog.Color[2], + ctx->Fog.Color[3]); + _GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_FOGCOLOR, d3dFogColour)); + + // Fog density + _GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_FOGDENSITY, *((DWORD*) (&ctx->Fog.Density)))); + + // Fog start + _GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_FOGSTART, *((DWORD*) (&ctx->Fog.Start)))); + + // Fog end + _GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_FOGEND, *((DWORD*) (&ctx->Fog.End)))); + + // Fog mode + switch (ctx->Fog.Mode) { + case GL_LINEAR: + d3dFogMode = D3DFOG_LINEAR; + break; + case GL_EXP: + d3dFogMode = D3DFOG_EXP; + break; + case GL_EXP2: + d3dFogMode = D3DFOG_EXP2; + break; + } + _GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_FOGTABLEMODE, d3dFogMode)); + _GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_FOGVERTEXMODE, D3DFOG_NONE)); +} + +//--------------------------------------------------------------------------- + +void gld_NEW_LIGHT( + GLcontext *ctx) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx); + DWORD dwSpecularEnable; + + // Shademode + _GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_SHADEMODE, (ctx->Light.ShadeModel == GL_SMOOTH) ? D3DSHADE_GOURAUD : D3DSHADE_FLAT)); + + // Separate specular colour + if (ctx->Light.Enabled) + dwSpecularEnable = (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) ? TRUE: FALSE; + else + dwSpecularEnable = FALSE; + _GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_SPECULARENABLE, dwSpecularEnable)); +} + +//--------------------------------------------------------------------------- + +void gld_NEW_MODELVIEW( + GLcontext *ctx) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx); + + D3DMATRIX m; + //GLfloat *pM = ctx->ModelView.m; + // Mesa5: Model-view is now a stack + GLfloat *pM = ctx->ModelviewMatrixStack.Top->m; + m._11 = pM[0]; + m._12 = pM[1]; + m._13 = pM[2]; + m._14 = pM[3]; + m._21 = pM[4]; + m._22 = pM[5]; + m._23 = pM[6]; + m._24 = pM[7]; + m._31 = pM[8]; + m._32 = pM[9]; + m._33 = pM[10]; + m._34 = pM[11]; + m._41 = pM[12]; + m._42 = pM[13]; + m._43 = pM[14]; + m._44 = pM[15]; + + gld->matModelView = m; +} + +//--------------------------------------------------------------------------- + +void gld_NEW_PROJECTION( + GLcontext *ctx) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx); + + D3DMATRIX m; + //GLfloat *pM = ctx->ProjectionMatrix.m; + // Mesa 5: Now a stack + GLfloat *pM = ctx->ProjectionMatrixStack.Top->m; + m._11 = pM[0]; + m._12 = pM[1]; + m._13 = pM[2]; + m._14 = pM[3]; + + m._21 = pM[4]; + m._22 = pM[5]; + m._23 = pM[6]; + m._24 = pM[7]; + + m._31 = pM[8]; + m._32 = pM[9]; + m._33 = pM[10] / _fPersp_33; // / 1.6f; + m._34 = pM[11]; + + m._41 = pM[12]; + m._42 = pM[13]; + m._43 = pM[14] / 2.0f; + m._44 = pM[15]; + + gld->matProjection = m; +} + +//--------------------------------------------------------------------------- +/* +void gldFrustumHook_DX8( + GLdouble left, + GLdouble right, + GLdouble bottom, + GLdouble top, + GLdouble nearval, + GLdouble farval) +{ + GET_CURRENT_CONTEXT(ctx); + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx); + + // Pass values on to Mesa first (in case we mess with them) + _mesa_Frustum(left, right, bottom, top, nearval, farval); + + _fPersp_33 = farval / (nearval - farval); + +// ddlogPrintf(GLDLOG_SYSTEM, "Frustum: %f", farval/nearval); +} + +//--------------------------------------------------------------------------- + +void gldOrthoHook_DX8( + GLdouble left, + GLdouble right, + GLdouble bottom, + GLdouble top, + GLdouble nearval, + GLdouble farval) +{ + GET_CURRENT_CONTEXT(ctx); + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx); + + // Pass values on to Mesa first (in case we mess with them) + _mesa_Ortho(left, right, bottom, top, nearval, farval); + + _fPersp_33 = 1.6f; + +// ddlogPrintf(GLDLOG_SYSTEM, "Ortho: %f", farval/nearval); +} +*/ +//--------------------------------------------------------------------------- + +void gld_NEW_VIEWPORT( + GLcontext *ctx) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx); + + D3DVIEWPORT8 d3dvp; +// GLint x, y; +// GLsizei w, h; + + // Set depth range + _GLD_DX8_DEV(GetViewport(gld->pDev, &d3dvp)); + // D3D can't do Quake1/Quake2 z-trick + if (ctx->Viewport.Near <= ctx->Viewport.Far) { + d3dvp.MinZ = ctx->Viewport.Near; + d3dvp.MaxZ = ctx->Viewport.Far; + } else { + d3dvp.MinZ = ctx->Viewport.Far; + d3dvp.MaxZ = ctx->Viewport.Near; + } +/* x = ctx->Viewport.X; + y = ctx->Viewport.Y; + w = ctx->Viewport.Width; + h = ctx->Viewport.Height; + if (x < 0) x = 0; + if (y < 0) y = 0; + if (w > gldCtx->dwWidth) w = gldCtx->dwWidth; + if (h > gldCtx->dwHeight) h = gldCtx->dwHeight; + // Ditto for D3D viewport dimensions + if (w+x > gldCtx->dwWidth) w = gldCtx->dwWidth-x; + if (h+y > gldCtx->dwHeight) h = gldCtx->dwHeight-y; + d3dvp.X = x; + d3dvp.Y = gldCtx->dwHeight - (y + h); + d3dvp.Width = w; + d3dvp.Height = h;*/ + _GLD_DX8_DEV(SetViewport(gld->pDev, &d3dvp)); + +// gld->fFlipWindowY = (float)gldCtx->dwHeight; +} + +//--------------------------------------------------------------------------- + +__inline BOOL _gldAnyEvalEnabled( + GLcontext *ctx) +{ + struct gl_eval_attrib *eval = &ctx->Eval; + + if ((eval->AutoNormal) || + (eval->Map1Color4) || + (eval->Map1Index) || + (eval->Map1Normal) || + (eval->Map1TextureCoord1) || + (eval->Map1TextureCoord2) || + (eval->Map1TextureCoord3) || + (eval->Map1TextureCoord4) || + (eval->Map1Vertex3) || + (eval->Map1Vertex4) || + (eval->Map2Color4) || + (eval->Map2Index) || + (eval->Map2Normal) || + (eval->Map2TextureCoord1) || + (eval->Map2TextureCoord2) || + (eval->Map2TextureCoord3) || + (eval->Map2TextureCoord4) || + (eval->Map2Vertex3) || + (eval->Map2Vertex4) + ) + return TRUE; + + return FALSE; +} + +//--------------------------------------------------------------------------- + +BOOL _gldChooseInternalPipeline( + GLcontext *ctx, + GLD_driver_dx8 *gld) +{ +// return TRUE; // DEBUGGING: ALWAYS USE MESA +// return FALSE; // DEBUGGING: ALWAYS USE D3D + + if ((glb.dwTnL == GLDS_TNL_MESA) || (gld->bHasHWTnL == FALSE)) + { + gld->PipelineUsage.qwMesa.QuadPart++; + return TRUE; // Force Mesa TnL + } + + if ((ctx->Light.Enabled) || + (1) || + (ctx->Texture._TexGenEnabled) || + (ctx->Texture._TexMatEnabled) || +// (ctx->Transform._AnyClip) || + (ctx->Scissor.Enabled) || + _gldAnyEvalEnabled(ctx) // Put this last so we can early-out + ) + { + gld->PipelineUsage.qwMesa.QuadPart++; + return TRUE; + } + + gld->PipelineUsage.qwD3DFVF.QuadPart++; + return FALSE; + +/* // Force Mesa pipeline? + if (glb.dwTnL == GLDS_TNL_MESA) { + gld->PipelineUsage.dwMesa.QuadPart++; + return GLD_PIPELINE_MESA; + } + + // Test for functionality not exposed in the D3D pathways + if ((ctx->Texture._GenFlags)) { + gld->PipelineUsage.dwMesa.QuadPart++; + return GLD_PIPELINE_MESA; + } + + // Now decide if vertex shader can be used. + // If two sided lighting is enabled then we must either + // use Mesa TnL or the vertex shader + if (ctx->_TriangleCaps & DD_TRI_LIGHT_TWOSIDE) { + if (gld->VStwosidelight.hShader && !ctx->Fog.Enabled) { + // Use Vertex Shader + gld->PipelineUsage.dwD3D2SVS.QuadPart++; + return GLD_PIPELINE_D3D_VS_TWOSIDE; + } else { + // Use Mesa TnL + gld->PipelineUsage.dwMesa.QuadPart++; + return GLD_PIPELINE_MESA; + } + } + + // Must be D3D fixed-function pipeline + gld->PipelineUsage.dwD3DFVF.QuadPart++; + return GLD_PIPELINE_D3D_FVF; +*/ +} + +//--------------------------------------------------------------------------- + +void gld_update_state_DX8( + GLcontext *ctx, + GLuint new_state) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLD_pb_dx8 *gldPB; + + if (!gld || !gld->pDev) + return; + + _swsetup_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); + _tnl_InvalidateState( ctx, new_state ); + + // SetupIndex will be used in the pipelines for choosing setup function + if ((ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE | DD_SEPARATE_SPECULAR)) || + (ctx->Fog.Enabled)) + { + if (ctx->_TriangleCaps & DD_FLATSHADE) + gld->iSetupFunc = GLD_SI_FLAT_EXTRAS; + else + gld->iSetupFunc = GLD_SI_SMOOTH_EXTRAS; + } else { + if (ctx->_TriangleCaps & DD_FLATSHADE) + gld->iSetupFunc = GLD_SI_FLAT; // Setup flat shade + texture + else + gld->iSetupFunc = GLD_SI_SMOOTH; // Setup smooth shade + texture + } + + gld->bUseMesaTnL = _gldChooseInternalPipeline(ctx, gld); + if (gld->bUseMesaTnL) { + gldPB = &gld->PB2d; + _GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_SOFTWAREVERTEXPROCESSING, TRUE)); + _GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_CLIPPING, FALSE)); + _GLD_DX8_DEV(SetVertexShader(gld->pDev, gldPB->dwFVF)); + } else { + gldPB = &gld->PB3d; + _GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_CLIPPING, TRUE)); +// if (gld->TnLPipeline == GLD_PIPELINE_D3D_VS_TWOSIDE) { +// _GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_SOFTWAREVERTEXPROCESSING, !gld->VStwosidelight.bHardware)); +// _GLD_DX8_DEV(SetVertexShader(gld->pDev, gld->VStwosidelight.hShader)); +// } else { + _GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_SOFTWAREVERTEXPROCESSING, !gld->bHasHWTnL)); + _GLD_DX8_DEV(SetVertexShader(gld->pDev, gldPB->dwFVF)); +// } + } + +#define _GLD_TEST_STATE(a) \ + if (new_state & (a)) { \ + gld##a(ctx); \ + new_state &= ~(a); \ + } + +#define _GLD_TEST_STATE_DX8(a) \ + if (new_state & (a)) { \ + gld##a##_DX8(ctx); \ + new_state &= ~(a); \ + } + +#define _GLD_IGNORE_STATE(a) new_state &= ~(a); + +// if (!gld->bUseMesaTnL) { + // Not required if Mesa is doing the TnL. + // Problem: If gld->bUseMesaTnL is TRUE when these are signaled, + // then we'll miss updating the D3D TnL pipeline. + // Therefore, don't test for gld->bUseMesaTnL + _GLD_TEST_STATE(_NEW_MODELVIEW); + _GLD_TEST_STATE(_NEW_PROJECTION); +// } + + _GLD_TEST_STATE_DX8(_NEW_TEXTURE); // extern, so guard with _DX8 + _GLD_TEST_STATE(_NEW_COLOR); + _GLD_TEST_STATE(_NEW_DEPTH); + _GLD_TEST_STATE(_NEW_POLYGON); + _GLD_TEST_STATE(_NEW_STENCIL); + _GLD_TEST_STATE(_NEW_FOG); + _GLD_TEST_STATE(_NEW_LIGHT); + _GLD_TEST_STATE(_NEW_VIEWPORT); + + _GLD_IGNORE_STATE(_NEW_TRANSFORM); + + +// Stubs for future use. +/* _GLD_TEST_STATE(_NEW_TEXTURE_MATRIX); + _GLD_TEST_STATE(_NEW_COLOR_MATRIX); + _GLD_TEST_STATE(_NEW_ACCUM); + _GLD_TEST_STATE(_NEW_EVAL); + _GLD_TEST_STATE(_NEW_HINT); + _GLD_TEST_STATE(_NEW_LINE); + _GLD_TEST_STATE(_NEW_PIXEL); + _GLD_TEST_STATE(_NEW_POINT); + _GLD_TEST_STATE(_NEW_POLYGONSTIPPLE); + _GLD_TEST_STATE(_NEW_SCISSOR); + _GLD_TEST_STATE(_NEW_PACKUNPACK); + _GLD_TEST_STATE(_NEW_ARRAY); + _GLD_TEST_STATE(_NEW_RENDERMODE); + _GLD_TEST_STATE(_NEW_BUFFERS); + _GLD_TEST_STATE(_NEW_MULTISAMPLE); +*/ + +// For debugging. +#if 0 +#define _GLD_TEST_UNHANDLED_STATE(a) \ + if (new_state & (a)) { \ + gldLogMessage(GLDLOG_ERROR, "Unhandled " #a "\n"); \ + } + _GLD_TEST_UNHANDLED_STATE(_NEW_TEXTURE_MATRIX); + _GLD_TEST_UNHANDLED_STATE(_NEW_COLOR_MATRIX); + _GLD_TEST_UNHANDLED_STATE(_NEW_ACCUM); + _GLD_TEST_UNHANDLED_STATE(_NEW_EVAL); + _GLD_TEST_UNHANDLED_STATE(_NEW_HINT); + _GLD_TEST_UNHANDLED_STATE(_NEW_LINE); + _GLD_TEST_UNHANDLED_STATE(_NEW_PIXEL); + _GLD_TEST_UNHANDLED_STATE(_NEW_POINT); + _GLD_TEST_UNHANDLED_STATE(_NEW_POLYGONSTIPPLE); + _GLD_TEST_UNHANDLED_STATE(_NEW_SCISSOR); + _GLD_TEST_UNHANDLED_STATE(_NEW_PACKUNPACK); + _GLD_TEST_UNHANDLED_STATE(_NEW_ARRAY); + _GLD_TEST_UNHANDLED_STATE(_NEW_RENDERMODE); + _GLD_TEST_UNHANDLED_STATE(_NEW_BUFFERS); + _GLD_TEST_UNHANDLED_STATE(_NEW_MULTISAMPLE); +#undef _GLD_UNHANDLED_STATE +#endif + +#undef _GLD_TEST_STATE +} + +//--------------------------------------------------------------------------- +// Viewport +//--------------------------------------------------------------------------- + +void gld_Viewport_DX8( + GLcontext *ctx, + GLint x, + GLint y, + GLsizei w, + GLsizei h) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx); + + D3DVIEWPORT8 d3dvp; + + if (!gld || !gld->pDev) + return; + + // This is a hack. When the app is minimized, Mesa passes + // w=1 and h=1 for viewport dimensions. Without this test + // we get a GPF in gld_wgl_resize_buffers(). + if ((w==1) && (h==1)) + return; + + // Call ResizeBuffersMESA. This function will early-out + // if no resize is needed. + //ctx->Driver.ResizeBuffersMESA(ctx); + // Mesa 5: Changed parameters + ctx->Driver.ResizeBuffers(gldCtx->glBuffer); + +#if 0 + ddlogPrintf(GLDLOG_SYSTEM, ">> Viewport x=%d y=%d w=%d h=%d", x,y,w,h); +#endif + + // ** D3D viewport must not be outside the render target surface ** + // Sanity check the GL viewport dimensions + if (x < 0) x = 0; + if (y < 0) y = 0; + if (w > gldCtx->dwWidth) w = gldCtx->dwWidth; + if (h > gldCtx->dwHeight) h = gldCtx->dwHeight; + // Ditto for D3D viewport dimensions + if (w+x > gldCtx->dwWidth) w = gldCtx->dwWidth-x; + if (h+y > gldCtx->dwHeight) h = gldCtx->dwHeight-y; + + d3dvp.X = x; + d3dvp.Y = gldCtx->dwHeight - (y + h); + d3dvp.Width = w; + d3dvp.Height = h; + if (ctx->Viewport.Near <= ctx->Viewport.Far) { + d3dvp.MinZ = ctx->Viewport.Near; + d3dvp.MaxZ = ctx->Viewport.Far; + } else { + d3dvp.MinZ = ctx->Viewport.Far; + d3dvp.MaxZ = ctx->Viewport.Near; + } + + // TODO: DEBUGGING +// d3dvp.MinZ = 0.0f; +// d3dvp.MaxZ = 1.0f; + + _GLD_DX8_DEV(SetViewport(gld->pDev, &d3dvp)); + +} + +//--------------------------------------------------------------------------- + +extern BOOL dglWglResizeBuffers(GLcontext *ctx, BOOL bDefaultDriver); + +// Mesa 5: Parameter change +void gldResizeBuffers_DX8( +// GLcontext *ctx) + GLframebuffer *fb) +{ + GET_CURRENT_CONTEXT(ctx); + dglWglResizeBuffers(ctx, TRUE); +} + +//--------------------------------------------------------------------------- +#ifdef _DEBUG +// This is only for debugging. +// To use, plug into ctx->Driver.Enable pointer below. +void gld_Enable( + GLcontext *ctx, + GLenum e, + GLboolean b) +{ + char buf[1024]; + sprintf(buf, "Enable: %s (%s)\n", _mesa_lookup_enum_by_nr(e), b?"TRUE":"FALSE"); + ddlogMessage(DDLOG_SYSTEM, buf); +} +#endif +//--------------------------------------------------------------------------- +// Driver pointer setup +//--------------------------------------------------------------------------- + +extern const GLubyte* _gldGetStringGeneric(GLcontext*, GLenum); + +void gldSetupDriverPointers_DX8( + GLcontext *ctx) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx); + + TNLcontext *tnl = TNL_CONTEXT(ctx); + + // Mandatory functions + ctx->Driver.GetString = _gldGetStringGeneric; + ctx->Driver.UpdateState = gld_update_state_DX8; + ctx->Driver.Clear = gld_Clear_DX8; + ctx->Driver.DrawBuffer = gld_set_draw_buffer_DX8; + ctx->Driver.GetBufferSize = gld_buffer_size_DX8; + ctx->Driver.Finish = gld_Finish_DX8; + ctx->Driver.Flush = gld_Flush_DX8; + ctx->Driver.Error = gld_Error_DX8; + + // Hardware accumulation buffer + ctx->Driver.Accum = NULL; // TODO: gld_Accum; + + // Bitmap functions + ctx->Driver.CopyPixels = gld_CopyPixels_DX8; + ctx->Driver.DrawPixels = gld_DrawPixels_DX8; + ctx->Driver.ReadPixels = gld_ReadPixels_DX8; + ctx->Driver.Bitmap = gld_Bitmap_DX8; + + // Buffer resize + ctx->Driver.ResizeBuffers = gldResizeBuffers_DX8; + + // Texture image functions + ctx->Driver.ChooseTextureFormat = gld_ChooseTextureFormat_DX8; + ctx->Driver.TexImage1D = gld_TexImage1D_DX8; + ctx->Driver.TexImage2D = gld_TexImage2D_DX8; + ctx->Driver.TexImage3D = _mesa_store_teximage3d; + ctx->Driver.TexSubImage1D = gld_TexSubImage1D_DX8; + ctx->Driver.TexSubImage2D = gld_TexSubImage2D_DX8; + ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d; + + ctx->Driver.CopyTexImage1D = gldCopyTexImage1D_DX8; //NULL; + ctx->Driver.CopyTexImage2D = gldCopyTexImage2D_DX8; //NULL; + ctx->Driver.CopyTexSubImage1D = gldCopyTexSubImage1D_DX8; //NULL; + ctx->Driver.CopyTexSubImage2D = gldCopyTexSubImage2D_DX8; //NULL; + ctx->Driver.CopyTexSubImage3D = gldCopyTexSubImage3D_DX8; + ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage; + + // Texture object functions + ctx->Driver.BindTexture = NULL; + ctx->Driver.NewTextureObject = NULL; // Not yet implemented by Mesa!; + ctx->Driver.DeleteTexture = gld_DeleteTexture_DX8; + ctx->Driver.PrioritizeTexture = NULL; + + // Imaging functionality + ctx->Driver.CopyColorTable = NULL; + ctx->Driver.CopyColorSubTable = NULL; + ctx->Driver.CopyConvolutionFilter1D = NULL; + ctx->Driver.CopyConvolutionFilter2D = NULL; + + // State changing functions + ctx->Driver.AlphaFunc = NULL; //gld_AlphaFunc; + ctx->Driver.BlendFuncSeparate = NULL; //gld_BlendFunc; + ctx->Driver.ClearColor = NULL; //gld_ClearColor; + ctx->Driver.ClearDepth = NULL; //gld_ClearDepth; + ctx->Driver.ClearStencil = NULL; //gld_ClearStencil; + ctx->Driver.ColorMask = NULL; //gld_ColorMask; + ctx->Driver.CullFace = NULL; //gld_CullFace; + ctx->Driver.ClipPlane = NULL; //gld_ClipPlane; + ctx->Driver.FrontFace = NULL; //gld_FrontFace; + ctx->Driver.DepthFunc = NULL; //gld_DepthFunc; + ctx->Driver.DepthMask = NULL; //gld_DepthMask; + ctx->Driver.DepthRange = NULL; + ctx->Driver.Enable = NULL; //gld_Enable; + ctx->Driver.Fogfv = NULL; //gld_Fogfv; + ctx->Driver.Hint = NULL; //gld_Hint; + ctx->Driver.Lightfv = NULL; //gld_Lightfv; + ctx->Driver.LightModelfv = NULL; //gld_LightModelfv; + ctx->Driver.LineStipple = NULL; //gld_LineStipple; + ctx->Driver.LineWidth = NULL; //gld_LineWidth; + ctx->Driver.LogicOpcode = NULL; //gld_LogicOpcode; + ctx->Driver.PointParameterfv = NULL; //gld_PointParameterfv; + ctx->Driver.PointSize = NULL; //gld_PointSize; + ctx->Driver.PolygonMode = NULL; //gld_PolygonMode; + ctx->Driver.PolygonOffset = NULL; //gld_PolygonOffset; + ctx->Driver.PolygonStipple = NULL; //gld_PolygonStipple; + ctx->Driver.RenderMode = NULL; //gld_RenderMode; + ctx->Driver.Scissor = NULL; //gld_Scissor; + ctx->Driver.ShadeModel = NULL; //gld_ShadeModel; + ctx->Driver.StencilFunc = NULL; //gld_StencilFunc; + ctx->Driver.StencilMask = NULL; //gld_StencilMask; + ctx->Driver.StencilOp = NULL; //gld_StencilOp; + ctx->Driver.TexGen = NULL; //gld_TexGen; + ctx->Driver.TexEnv = NULL; + ctx->Driver.TexParameter = NULL; + ctx->Driver.TextureMatrix = NULL; //gld_TextureMatrix; + ctx->Driver.Viewport = gld_Viewport_DX8; + + _swsetup_Wakeup(ctx); + + tnl->Driver.RunPipeline = _tnl_run_pipeline; + tnl->Driver.Render.ResetLineStipple = gld_ResetLineStipple_DX8; + tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon; + tnl->Driver.Render.ClippedLine = _tnl_RenderClippedLine; + + // Hook into glFrustum() and glOrtho() +// ctx->Exec->Frustum = gldFrustumHook_DX8; +// ctx->Exec->Ortho = gldOrthoHook_DX8; + +} + +//--------------------------------------------------------------------------- diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_dx8.h b/mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_dx8.h new file mode 100644 index 000000000..7efec7cae --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_dx8.h @@ -0,0 +1,324 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x/2000/XP/XBox (Win32) +* +* Description: GLDirect Direct3D 8.0 header file +* +****************************************************************************/ + +#ifndef _GLD_DX8_H +#define _GLD_DX8_H + +//--------------------------------------------------------------------------- +// Windows includes +//--------------------------------------------------------------------------- + +//#ifndef STRICT +//#define STRICT +//#endif + +//#define WIN32_LEAN_AND_MEAN +//#include +#include +#include + +// MS screwed up with the DX8.1 SDK - there's no compile-time +// method of compiling for 8.0 via the 8.1 SDK unless you +// "make sure you don't use any 8.1 interfaces". +// We CAN use 8.1 D3DX static functions, though - just not new 8.1 interfaces. +// +// D3D_SDK_VERSION is 120 for 8.0 (supported by Windows 95). +// D3D_SDK_VERSION is 220 for 8.1 (NOT supported by Windows 95). +// +#define D3D_SDK_VERSION_DX8_SUPPORT_WIN95 120 + +// Typedef for obtaining function from d3d8.dll +typedef IDirect3D8* (WINAPI *FNDIRECT3DCREATE8) (UINT); + + +//--------------------------------------------------------------------------- +// Defines +//--------------------------------------------------------------------------- + +#ifdef _DEBUG +#define _GLD_TEST_HRESULT(h) \ +{ \ + HRESULT _hr = (h); \ + if (FAILED(_hr)) { \ + gldLogError(GLDLOG_ERROR, #h, _hr); \ + } \ +} +#define _GLD_DX8(func) _GLD_TEST_HRESULT(IDirect3D8_##func##) +#define _GLD_DX8_DEV(func) _GLD_TEST_HRESULT(IDirect3DDevice8_##func##) +#define _GLD_DX8_VB(func) _GLD_TEST_HRESULT(IDirect3DVertexBuffer8_##func##) +#define _GLD_DX8_TEX(func) _GLD_TEST_HRESULT(IDirect3DTexture8_##func##) +#else +#define _GLD_DX8(func) IDirect3D8_##func +#define _GLD_DX8_DEV(func) IDirect3DDevice8_##func +#define _GLD_DX8_VB(func) IDirect3DVertexBuffer8_##func +#define _GLD_DX8_TEX(func) IDirect3DTexture8_##func +#endif + +#define SAFE_RELEASE(p) \ +{ \ + if (p) { \ + (p)->lpVtbl->Release(p); \ + (p) = NULL; \ + } \ +} + +#define SAFE_RELEASE_VB8(p) \ +{ \ + if (p) { \ + IDirect3DVertexBuffer8_Release((p)); \ + (p) = NULL; \ + } \ +} + +#define SAFE_RELEASE_SURFACE8(p) \ +{ \ + if (p) { \ + IDirect3DSurface8_Release((p)); \ + (p) = NULL; \ + } \ +} + +// Setup index. +enum { + GLD_SI_FLAT = 0, + GLD_SI_SMOOTH = 1, + GLD_SI_FLAT_EXTRAS = 2, + GLD_SI_SMOOTH_EXTRAS = 3, +}; +/* +// Internal pipeline +typedef enum { + GLD_PIPELINE_MESA = 0, // Mesa pipeline + GLD_PIPELINE_D3D_FVF = 1, // Direct3D Fixed-function pipeline + GLD_PIPELINE_D3D_VS_TWOSIDE = 2 // Direct3D two-sided-lighting vertex shader +} GLD_tnl_pipeline; +*/ +//--------------------------------------------------------------------------- +// Vertex definitions for Fixed-Function pipeline +//--------------------------------------------------------------------------- + +// +// NOTE: If the number of texture units is altered then most of +// the texture code will need to be revised. +// + +#define GLD_MAX_TEXTURE_UNITS_DX8 2 + +// +// 2D vertex transformed by Mesa +// +#define GLD_FVF_2D_VERTEX ( D3DFVF_XYZRHW | \ + D3DFVF_DIFFUSE | \ + D3DFVF_SPECULAR | \ + D3DFVF_TEX2) +typedef struct { + FLOAT x, y; // 2D raster coords + FLOAT sz; // Screen Z (depth) + FLOAT rhw; // Reciprocal homogenous W + DWORD diffuse; // Diffuse colour + DWORD specular; // For separate-specular support + FLOAT t0_u, t0_v; // 1st set of texture coords + FLOAT t1_u, t1_v; // 2nd set of texture coords +} GLD_2D_VERTEX; + + +// +// 3D vertex transformed by Direct3D +// +#define GLD_FVF_3D_VERTEX ( D3DFVF_XYZ | \ + D3DFVF_DIFFUSE | \ + D3DFVF_TEX2) + +typedef struct { + D3DXVECTOR3 Position; // XYZ Vector in object space + D3DCOLOR Diffuse; // Diffuse colour + D3DXVECTOR2 TexUnit0; // Texture unit 0 + D3DXVECTOR2 TexUnit1; // Texture unit 1 +} GLD_3D_VERTEX; + +//--------------------------------------------------------------------------- +// Vertex Shaders +//--------------------------------------------------------------------------- +/* +// DX8 Vertex Shader +typedef struct { + DWORD hShader; // If NULL, shader is invalid and cannot be used + BOOL bHardware; // If TRUE then shader was created for hardware, + // otherwise shader was created for software. +} GLD_vertexShader; +*/ +//--------------------------------------------------------------------------- +// Structs +//--------------------------------------------------------------------------- + +// This keeps a count of how many times we choose each individual internal +// pathway. Useful for seeing if a certain pathway was ever used by an app, and +// how much each pathway is biased. +// Zero the members at context creation and dump stats at context deletion. +typedef struct { + // Note: DWORD is probably too small + ULARGE_INTEGER qwMesa; // Mesa TnL pipeline + ULARGE_INTEGER qwD3DFVF; // Direct3D Fixed-Function pipeline +// ULARGE_INTEGER dwD3D2SVS; // Direct3D Two-Sided Vertex Shader pipeline +} GLD_pipeline_usage; + +// GLDirect Primitive Buffer (points, lines, triangles and quads) +typedef struct { + // Data for IDirect3DDevice8::CreateVertexBuffer() + DWORD dwStride; // Stride of vertex + DWORD dwUsage; // Usage flags + DWORD dwFVF; // Direct3D Flexible Vertex Format + DWORD dwPool; // Pool flags + + IDirect3DVertexBuffer8 *pVB; // Holds points, lines, tris and quads. + + // Point list is assumed to be at start of buffer + DWORD iFirstLine; // Index of start of line list + DWORD iFirstTriangle; // Index of start of triangle list + + BYTE *pPoints; // Pointer to next free point + BYTE *pLines; // Pointer to next free line + BYTE *pTriangles; // Pointer to next free triangle + + DWORD nPoints; // Number of points ready to render + DWORD nLines; // Number of lines ready to render + DWORD nTriangles; // Number of triangles ready to render +} GLD_pb_dx8; + +// GLDirect DX8 driver data +typedef struct { + // GLDirect vars + BOOL bDoublebuffer; // Doublebuffer (otherwise single-buffered) + BOOL bDepthStencil; // Depth buffer needed (stencil optional) + D3DFORMAT RenderFormat; // Format of back/front buffer + D3DFORMAT DepthFormat; // Format of depth/stencil +// float fFlipWindowY; // Value for flipping viewport Y coord + + // Direct3D vars + D3DCAPS8 d3dCaps8; + BOOL bHasHWTnL; // Device has Hardware Transform/Light? + IDirect3D8 *pD3D; // Base Direct3D8 interface + IDirect3DDevice8 *pDev; // Direct3D8 Device interface + GLD_pb_dx8 PB2d; // Vertices transformed by Mesa + GLD_pb_dx8 PB3d; // Vertices transformed by Direct3D + D3DPRIMITIVETYPE d3dpt; // Current Direct3D primitive type + D3DXMATRIX matProjection; // Projection matrix for D3D TnL + D3DXMATRIX matModelView; // Model/View matrix for D3D TnL + int iSetupFunc; // Which setup functions to use + BOOL bUseMesaTnL; // Whether to use Mesa or D3D for TnL + + // Direct3D vars for two-sided lighting +// GLD_vertexShader VStwosidelight; // Vertex Shader for two-sided lighting +// D3DXMATRIX matWorldViewProj;// World/View/Projection matrix for shaders + + +// GLD_tnl_pipeline TnLPipeline; // Index of current internal pipeline + GLD_pipeline_usage PipelineUsage; +} GLD_driver_dx8; + +#define GLD_GET_DX8_DRIVER(c) (GLD_driver_dx8*)(c)->glPriv + +//--------------------------------------------------------------------------- +// Function prototypes +//--------------------------------------------------------------------------- + +PROC gldGetProcAddress_DX8(LPCSTR a); +void gldEnableExtensions_DX8(GLcontext *ctx); +void gldInstallPipeline_DX8(GLcontext *ctx); +void gldSetupDriverPointers_DX8(GLcontext *ctx); +//void gldResizeBuffers_DX8(GLcontext *ctx); +void gldResizeBuffers_DX8(GLframebuffer *fb); + + +// Texture functions + +void gldCopyTexImage1D_DX8(GLcontext *ctx, GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border); +void gldCopyTexImage2D_DX8(GLcontext *ctx, GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +void gldCopyTexSubImage1D_DX8(GLcontext *ctx, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width ); +void gldCopyTexSubImage2D_DX8(GLcontext *ctx, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height ); +void gldCopyTexSubImage3D_DX8(GLcontext *ctx, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height ); + +void gld_NEW_TEXTURE_DX8(GLcontext *ctx); +void gld_DrawPixels_DX8(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, const struct gl_pixelstore_attrib *unpack, const GLvoid *pixels); +void gld_ReadPixels_DX8(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, const struct gl_pixelstore_attrib *unpack, GLvoid *dest); +void gld_CopyPixels_DX8(GLcontext *ctx, GLint srcx, GLint srcy, GLsizei width, GLsizei height, GLint dstx, GLint dsty, GLenum type); +void gld_Bitmap_DX8(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, const struct gl_pixelstore_attrib *unpack, const GLubyte *bitmap); +const struct gl_texture_format* gld_ChooseTextureFormat_DX8(GLcontext *ctx, GLint internalFormat, GLenum srcFormat, GLenum srcType); +void gld_TexImage2D_DX8(GLcontext *ctx, GLenum target, GLint level, GLint internalFormat, GLint width, GLint height, GLint border, GLenum format, GLenum type, const GLvoid *pixels, const struct gl_pixelstore_attrib *packing, struct gl_texture_object *tObj, struct gl_texture_image *texImage); +void gld_TexImage1D_DX8(GLcontext *ctx, GLenum target, GLint level, GLint internalFormat, GLint width, GLint border, GLenum format, GLenum type, const GLvoid *pixels, const struct gl_pixelstore_attrib *packing, struct gl_texture_object *texObj, struct gl_texture_image *texImage ); +void gld_TexSubImage2D_DX8( GLcontext *ctx, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels, const struct gl_pixelstore_attrib *packing, struct gl_texture_object *texObj, struct gl_texture_image *texImage ); +void gld_TexSubImage1D_DX8(GLcontext *ctx, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels, const struct gl_pixelstore_attrib *packing, struct gl_texture_object *texObj, struct gl_texture_image *texImage); +void gld_DeleteTexture_DX8(GLcontext *ctx, struct gl_texture_object *tObj); +void gld_ResetLineStipple_DX8(GLcontext *ctx); + +// 2D primitive functions + +void gld_Points2D_DX8(GLcontext *ctx, GLuint first, GLuint last); + +void gld_Line2DFlat_DX8(GLcontext *ctx, GLuint v0, GLuint v1); +void gld_Line2DSmooth_DX8(GLcontext *ctx, GLuint v0, GLuint v1); + +void gld_Triangle2DFlat_DX8(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2); +void gld_Triangle2DSmooth_DX8(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2); +void gld_Triangle2DFlatExtras_DX8(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2); +void gld_Triangle2DSmoothExtras_DX8(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2); + +void gld_Quad2DFlat_DX8(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +void gld_Quad2DSmooth_DX8(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +void gld_Quad2DFlatExtras_DX8(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +void gld_Quad2DSmoothExtras_DX8(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3); + +// 3D primitive functions + +void gld_Points3D_DX8(GLcontext *ctx, GLuint first, GLuint last); +void gld_Line3DFlat_DX8(GLcontext *ctx, GLuint v0, GLuint v1); +void gld_Triangle3DFlat_DX8(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2); +void gld_Quad3DFlat_DX8(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +void gld_Line3DSmooth_DX8(GLcontext *ctx, GLuint v0, GLuint v1); +void gld_Triangle3DSmooth_DX8(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2); +void gld_Quad3DSmooth_DX8(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3); + +// Primitive functions for Two-sided-lighting Vertex Shader + +void gld_Points2DTwoside_DX8(GLcontext *ctx, GLuint first, GLuint last); +void gld_Line2DFlatTwoside_DX8(GLcontext *ctx, GLuint v0, GLuint v1); +void gld_Line2DSmoothTwoside_DX8(GLcontext *ctx, GLuint v0, GLuint v1); +void gld_Triangle2DFlatTwoside_DX8(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2); +void gld_Triangle2DSmoothTwoside_DX8(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2); +void gld_Quad2DFlatTwoside_DX8(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +void gld_Quad2DSmoothTwoside_DX8(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3); + +#endif diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_dxerr8.h b/mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_dxerr8.h new file mode 100644 index 000000000..f8e92b936 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_dxerr8.h @@ -0,0 +1,77 @@ +/*==========================================================================; + * + * + * File: dxerr8.h + * Content: DirectX Error Library Include File + * + ****************************************************************************/ + +#ifndef _GLD_DXERR8_H_ +#define _GLD_DXERR8_H_ + + +#include + +// +// DXGetErrorString8 +// +// Desc: Converts an DirectX HRESULT to a string +// +// Args: HRESULT hr Can be any error code from +// DPLAY D3D8 D3DX8 DMUSIC DSOUND +// +// Return: Converted string +// +const char* __stdcall DXGetErrorString8A(HRESULT hr); +const WCHAR* __stdcall DXGetErrorString8W(HRESULT hr); + +#ifdef UNICODE + #define DXGetErrorString8 DXGetErrorString8W +#else + #define DXGetErrorString8 DXGetErrorString8A +#endif + + +// +// DXTrace +// +// Desc: Outputs a formatted error message to the debug stream +// +// Args: CHAR* strFile The current file, typically passed in using the +// __FILE__ macro. +// DWORD dwLine The current line number, typically passed in using the +// __LINE__ macro. +// HRESULT hr An HRESULT that will be traced to the debug stream. +// CHAR* strMsg A string that will be traced to the debug stream (may be NULL) +// BOOL bPopMsgBox If TRUE, then a message box will popup also containing the passed info. +// +// Return: The hr that was passed in. +// +//HRESULT __stdcall DXTraceA( char* strFile, DWORD dwLine, HRESULT hr, char* strMsg, BOOL bPopMsgBox = FALSE ); +//HRESULT __stdcall DXTraceW( char* strFile, DWORD dwLine, HRESULT hr, WCHAR* strMsg, BOOL bPopMsgBox = FALSE ); +HRESULT __stdcall DXTraceA( char* strFile, DWORD dwLine, HRESULT hr, char* strMsg, BOOL bPopMsgBox); +HRESULT __stdcall DXTraceW( char* strFile, DWORD dwLine, HRESULT hr, WCHAR* strMsg, BOOL bPopMsgBox); + +#ifdef UNICODE + #define DXTrace DXTraceW +#else + #define DXTrace DXTraceA +#endif + + +// +// Helper macros +// +#if defined(DEBUG) | defined(_DEBUG) + #define DXTRACE_MSG(str) DXTrace( __FILE__, (DWORD)__LINE__, 0, str, FALSE ) + #define DXTRACE_ERR(str,hr) DXTrace( __FILE__, (DWORD)__LINE__, hr, str, TRUE ) + #define DXTRACE_ERR_NOMSGBOX(str,hr) DXTrace( __FILE__, (DWORD)__LINE__, hr, str, FALSE ) +#else + #define DXTRACE_MSG(str) (0L) + #define DXTRACE_ERR(str,hr) (hr) + #define DXTRACE_ERR_NOMSGBOX(str,hr) (hr) +#endif + + +#endif + diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_ext_dx8.c b/mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_ext_dx8.c new file mode 100644 index 000000000..b51bba9b3 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_ext_dx8.c @@ -0,0 +1,344 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x/2000/XP/XBox (Win32) +* +* Description: GL extensions +* +****************************************************************************/ + +//#include "../GLDirect.h" +//#include "../gld_log.h" +//#include "../gld_settings.h" + +#include +#define GL_GLEXT_PROTOTYPES +#include +#include + +//#include "ddlog.h" +//#include "gld_dx8.h" + +#include "glheader.h" +#include "context.h" +#include "colormac.h" +#include "depth.h" +#include "extensions.h" +#include "macros.h" +#include "matrix.h" +// #include "mem.h" +//#include "mmath.h" +#include "mtypes.h" +#include "texformat.h" +#include "texstore.h" +#include "vbo/vbo.h" +#include "swrast_setup/swrast_setup.h" +#include "swrast_setup/ss_context.h" +#include "tnl/tnl.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" + +#include "dglcontext.h" +#include "extensions.h" + +// For some reason this is not defined in an above header... +extern void _mesa_enable_imaging_extensions(GLcontext *ctx); + +//--------------------------------------------------------------------------- +// Hack for the SGIS_multitexture extension that was removed from Mesa +// NOTE: SGIS_multitexture enums also clash with GL_SGIX_async_pixel + + // NOTE: Quake2 ran *slower* with this enabled, so I've + // disabled it for now. + // To enable, uncomment: + // _mesa_add_extension(ctx, GL_TRUE, szGL_SGIS_multitexture, 0); + +//--------------------------------------------------------------------------- + +enum { + /* Quake2 GL_SGIS_multitexture */ + GL_SELECTED_TEXTURE_SGIS = 0x835B, + GL_SELECTED_TEXTURE_COORD_SET_SGIS = 0x835C, + GL_MAX_TEXTURES_SGIS = 0x835D, + GL_TEXTURE0_SGIS = 0x835E, + GL_TEXTURE1_SGIS = 0x835F, + GL_TEXTURE2_SGIS = 0x8360, + GL_TEXTURE3_SGIS = 0x8361, + GL_TEXTURE_COORD_SET_SOURCE_SGIS = 0x8363, +}; + +//--------------------------------------------------------------------------- + +void APIENTRY gldSelectTextureSGIS( + GLenum target) +{ + GLenum ARB_target = GL_TEXTURE0_ARB + (target - GL_TEXTURE0_SGIS); + glActiveTextureARB(ARB_target); +} + +//--------------------------------------------------------------------------- + +void APIENTRY gldMTexCoord2fSGIS( + GLenum target, + GLfloat s, + GLfloat t) +{ + GLenum ARB_target = GL_TEXTURE0_ARB + (target - GL_TEXTURE0_SGIS); + glMultiTexCoord2fARB(ARB_target, s, t); +} + +//--------------------------------------------------------------------------- + +void APIENTRY gldMTexCoord2fvSGIS( + GLenum target, + const GLfloat *v) +{ + GLenum ARB_target = GL_TEXTURE0_ARB + (target - GL_TEXTURE0_SGIS); + glMultiTexCoord2fvARB(ARB_target, v); +} + +//--------------------------------------------------------------------------- +// Extensions +//--------------------------------------------------------------------------- + +typedef struct { + PROC proc; + char *name; +} GLD_extension; + +GLD_extension GLD_extList[] = { +#ifdef GL_EXT_polygon_offset + { (PROC)glPolygonOffsetEXT, "glPolygonOffsetEXT" }, +#endif + { (PROC)glBlendEquationEXT, "glBlendEquationEXT" }, + { (PROC)glBlendColorEXT, "glBlendColorExt" }, + { (PROC)glVertexPointerEXT, "glVertexPointerEXT" }, + { (PROC)glNormalPointerEXT, "glNormalPointerEXT" }, + { (PROC)glColorPointerEXT, "glColorPointerEXT" }, + { (PROC)glIndexPointerEXT, "glIndexPointerEXT" }, + { (PROC)glTexCoordPointerEXT, "glTexCoordPointer" }, + { (PROC)glEdgeFlagPointerEXT, "glEdgeFlagPointerEXT" }, + { (PROC)glGetPointervEXT, "glGetPointervEXT" }, + { (PROC)glArrayElementEXT, "glArrayElementEXT" }, + { (PROC)glDrawArraysEXT, "glDrawArrayEXT" }, + { (PROC)glAreTexturesResidentEXT, "glAreTexturesResidentEXT" }, + { (PROC)glBindTextureEXT, "glBindTextureEXT" }, + { (PROC)glDeleteTexturesEXT, "glDeleteTexturesEXT" }, + { (PROC)glGenTexturesEXT, "glGenTexturesEXT" }, + { (PROC)glIsTextureEXT, "glIsTextureEXT" }, + { (PROC)glPrioritizeTexturesEXT, "glPrioritizeTexturesEXT" }, + { (PROC)glCopyTexSubImage3DEXT, "glCopyTexSubImage3DEXT" }, + { (PROC)glTexImage3DEXT, "glTexImage3DEXT" }, + { (PROC)glTexSubImage3DEXT, "glTexSubImage3DEXT" }, + { (PROC)glPointParameterfEXT, "glPointParameterfEXT" }, + { (PROC)glPointParameterfvEXT, "glPointParameterfvEXT" }, + + { (PROC)glLockArraysEXT, "glLockArraysEXT" }, + { (PROC)glUnlockArraysEXT, "glUnlockArraysEXT" }, + { NULL, "\0" } +}; + +GLD_extension GLD_multitexList[] = { +/* + { (PROC)glMultiTexCoord1dSGIS, "glMTexCoord1dSGIS" }, + { (PROC)glMultiTexCoord1dvSGIS, "glMTexCoord1dvSGIS" }, + { (PROC)glMultiTexCoord1fSGIS, "glMTexCoord1fSGIS" }, + { (PROC)glMultiTexCoord1fvSGIS, "glMTexCoord1fvSGIS" }, + { (PROC)glMultiTexCoord1iSGIS, "glMTexCoord1iSGIS" }, + { (PROC)glMultiTexCoord1ivSGIS, "glMTexCoord1ivSGIS" }, + { (PROC)glMultiTexCoord1sSGIS, "glMTexCoord1sSGIS" }, + { (PROC)glMultiTexCoord1svSGIS, "glMTexCoord1svSGIS" }, + { (PROC)glMultiTexCoord2dSGIS, "glMTexCoord2dSGIS" }, + { (PROC)glMultiTexCoord2dvSGIS, "glMTexCoord2dvSGIS" }, + { (PROC)glMultiTexCoord2fSGIS, "glMTexCoord2fSGIS" }, + { (PROC)glMultiTexCoord2fvSGIS, "glMTexCoord2fvSGIS" }, + { (PROC)glMultiTexCoord2iSGIS, "glMTexCoord2iSGIS" }, + { (PROC)glMultiTexCoord2ivSGIS, "glMTexCoord2ivSGIS" }, + { (PROC)glMultiTexCoord2sSGIS, "glMTexCoord2sSGIS" }, + { (PROC)glMultiTexCoord2svSGIS, "glMTexCoord2svSGIS" }, + { (PROC)glMultiTexCoord3dSGIS, "glMTexCoord3dSGIS" }, + { (PROC)glMultiTexCoord3dvSGIS, "glMTexCoord3dvSGIS" }, + { (PROC)glMultiTexCoord3fSGIS, "glMTexCoord3fSGIS" }, + { (PROC)glMultiTexCoord3fvSGIS, "glMTexCoord3fvSGIS" }, + { (PROC)glMultiTexCoord3iSGIS, "glMTexCoord3iSGIS" }, + { (PROC)glMultiTexCoord3ivSGIS, "glMTexCoord3ivSGIS" }, + { (PROC)glMultiTexCoord3sSGIS, "glMTexCoord3sSGIS" }, + { (PROC)glMultiTexCoord3svSGIS, "glMTexCoord3svSGIS" }, + { (PROC)glMultiTexCoord4dSGIS, "glMTexCoord4dSGIS" }, + { (PROC)glMultiTexCoord4dvSGIS, "glMTexCoord4dvSGIS" }, + { (PROC)glMultiTexCoord4fSGIS, "glMTexCoord4fSGIS" }, + { (PROC)glMultiTexCoord4fvSGIS, "glMTexCoord4fvSGIS" }, + { (PROC)glMultiTexCoord4iSGIS, "glMTexCoord4iSGIS" }, + { (PROC)glMultiTexCoord4ivSGIS, "glMTexCoord4ivSGIS" }, + { (PROC)glMultiTexCoord4sSGIS, "glMTexCoord4sSGIS" }, + { (PROC)glMultiTexCoord4svSGIS, "glMTexCoord4svSGIS" }, + { (PROC)glMultiTexCoordPointerSGIS, "glMTexCoordPointerSGIS" }, + { (PROC)glSelectTextureSGIS, "glSelectTextureSGIS" }, + { (PROC)glSelectTextureCoordSetSGIS, "glSelectTextureCoordSetSGIS" }, +*/ + { (PROC)glActiveTextureARB, "glActiveTextureARB" }, + { (PROC)glClientActiveTextureARB, "glClientActiveTextureARB" }, + { (PROC)glMultiTexCoord1dARB, "glMultiTexCoord1dARB" }, + { (PROC)glMultiTexCoord1dvARB, "glMultiTexCoord1dvARB" }, + { (PROC)glMultiTexCoord1fARB, "glMultiTexCoord1fARB" }, + { (PROC)glMultiTexCoord1fvARB, "glMultiTexCoord1fvARB" }, + { (PROC)glMultiTexCoord1iARB, "glMultiTexCoord1iARB" }, + { (PROC)glMultiTexCoord1ivARB, "glMultiTexCoord1ivARB" }, + { (PROC)glMultiTexCoord1sARB, "glMultiTexCoord1sARB" }, + { (PROC)glMultiTexCoord1svARB, "glMultiTexCoord1svARB" }, + { (PROC)glMultiTexCoord2dARB, "glMultiTexCoord2dARB" }, + { (PROC)glMultiTexCoord2dvARB, "glMultiTexCoord2dvARB" }, + { (PROC)glMultiTexCoord2fARB, "glMultiTexCoord2fARB" }, + { (PROC)glMultiTexCoord2fvARB, "glMultiTexCoord2fvARB" }, + { (PROC)glMultiTexCoord2iARB, "glMultiTexCoord2iARB" }, + { (PROC)glMultiTexCoord2ivARB, "glMultiTexCoord2ivARB" }, + { (PROC)glMultiTexCoord2sARB, "glMultiTexCoord2sARB" }, + { (PROC)glMultiTexCoord2svARB, "glMultiTexCoord2svARB" }, + { (PROC)glMultiTexCoord3dARB, "glMultiTexCoord3dARB" }, + { (PROC)glMultiTexCoord3dvARB, "glMultiTexCoord3dvARB" }, + { (PROC)glMultiTexCoord3fARB, "glMultiTexCoord3fARB" }, + { (PROC)glMultiTexCoord3fvARB, "glMultiTexCoord3fvARB" }, + { (PROC)glMultiTexCoord3iARB, "glMultiTexCoord3iARB" }, + { (PROC)glMultiTexCoord3ivARB, "glMultiTexCoord3ivARB" }, + { (PROC)glMultiTexCoord3sARB, "glMultiTexCoord3sARB" }, + { (PROC)glMultiTexCoord3svARB, "glMultiTexCoord3svARB" }, + { (PROC)glMultiTexCoord4dARB, "glMultiTexCoord4dARB" }, + { (PROC)glMultiTexCoord4dvARB, "glMultiTexCoord4dvARB" }, + { (PROC)glMultiTexCoord4fARB, "glMultiTexCoord4fARB" }, + { (PROC)glMultiTexCoord4fvARB, "glMultiTexCoord4fvARB" }, + { (PROC)glMultiTexCoord4iARB, "glMultiTexCoord4iARB" }, + { (PROC)glMultiTexCoord4ivARB, "glMultiTexCoord4ivARB" }, + { (PROC)glMultiTexCoord4sARB, "glMultiTexCoord4sARB" }, + { (PROC)glMultiTexCoord4svARB, "glMultiTexCoord4svARB" }, + + // Descent3 doesn't use correct string, hence this hack + { (PROC)glMultiTexCoord4fARB, "glMultiTexCoord4f" }, + + // Quake2 SGIS multitexture + { (PROC)gldSelectTextureSGIS, "glSelectTextureSGIS" }, + { (PROC)gldMTexCoord2fSGIS, "glMTexCoord2fSGIS" }, + { (PROC)gldMTexCoord2fvSGIS, "glMTexCoord2fvSGIS" }, + + { NULL, "\0" } +}; + +//--------------------------------------------------------------------------- + +PROC gldGetProcAddress_DX( + LPCSTR a) +{ + int i; + PROC proc = NULL; + + for (i=0; GLD_extList[i].proc; i++) { + if (!strcmp(a, GLD_extList[i].name)) { + proc = GLD_extList[i].proc; + break; + } + } + + if (glb.bMultitexture) { + for (i=0; GLD_multitexList[i].proc; i++) { + if (!strcmp(a, GLD_multitexList[i].name)) { + proc = GLD_multitexList[i].proc; + break; + } + } + } + + gldLogPrintf(GLDLOG_INFO, "GetProcAddress: %s (%s)", a, proc ? "OK" : "Failed"); + + return proc; +} + +//--------------------------------------------------------------------------- + +void gldEnableExtensions_DX8( + GLcontext *ctx) +{ + GLuint i; + + // Mesa enables some extensions by default. + // This table decides which ones we want to switch off again. + + // NOTE: GL_EXT_compiled_vertex_array appears broken. + + const char *gld_disable_extensions[] = { +// "GL_ARB_transpose_matrix", +// "GL_EXT_compiled_vertex_array", +// "GL_EXT_polygon_offset", +// "GL_EXT_rescale_normal", + "GL_EXT_texture3D", +// "GL_NV_texgen_reflection", + NULL + }; + + const char *gld_multitex_extensions[] = { + "GL_ARB_multitexture", // Quake 3 + NULL + }; + + // Quake 2 engines + const char *szGL_SGIS_multitexture = "GL_SGIS_multitexture"; + + const char *gld_enable_extensions[] = { + "GL_EXT_texture_env_add", // Quake 3 + "GL_ARB_texture_env_add", // Quake 3 + NULL + }; + + for (i=0; gld_disable_extensions[i]; i++) { + _mesa_disable_extension(ctx, gld_disable_extensions[i]); + } + + for (i=0; gld_enable_extensions[i]; i++) { + _mesa_enable_extension(ctx, gld_enable_extensions[i]); + } + + if (glb.bMultitexture) { + for (i=0; gld_multitex_extensions[i]; i++) { + _mesa_enable_extension(ctx, gld_multitex_extensions[i]); + } + + // GL_SGIS_multitexture + // NOTE: Quake2 ran *slower* with this enabled, so I've + // disabled it for now. + // Fair bit slower on GeForce256, + // Much slower on 3dfx Voodoo5 5500. +// _mesa_add_extension(ctx, GL_TRUE, szGL_SGIS_multitexture, 0); + + } + + _mesa_enable_imaging_extensions(ctx); + _mesa_enable_1_3_extensions(ctx); + _mesa_enable_1_4_extensions(ctx); +} + +//--------------------------------------------------------------------------- diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_pipeline_dx8.c b/mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_pipeline_dx8.c new file mode 100644 index 000000000..2baea5744 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_pipeline_dx8.c @@ -0,0 +1,77 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x/2000/XP/XBox (Win32) +* +* Description: Mesa transformation pipeline with GLDirect fastpath +* +****************************************************************************/ + +//#include "../GLDirect.h" + +#include "dglcontext.h" +#include "ddlog.h" +#include "gld_dx8.h" + +#include "tnl/tnl.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" + +//--------------------------------------------------------------------------- + +extern struct tnl_pipeline_stage _gld_d3d_render_stage; +extern struct tnl_pipeline_stage _gld_mesa_render_stage; + +static const struct tnl_pipeline_stage *gld_pipeline[] = { + &_gld_d3d_render_stage, // Direct3D TnL + &_tnl_vertex_transform_stage, + &_tnl_normal_transform_stage, + &_tnl_lighting_stage, + &_tnl_fog_coordinate_stage, /* TODO: Omit fog stage. ??? */ + &_tnl_texgen_stage, + &_tnl_texture_transform_stage, + &_tnl_point_attenuation_stage, + &_gld_mesa_render_stage, // Mesa TnL, D3D rendering + 0, +}; + +//--------------------------------------------------------------------------- + +void gldInstallPipeline_DX8( + GLcontext *ctx) +{ + // Remove any existing pipeline stages, + // then install GLDirect pipeline stages. + + _tnl_destroy_pipeline(ctx); + _tnl_install_pipeline(ctx, gld_pipeline); +} + +//--------------------------------------------------------------------------- diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_primitive_dx8.c b/mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_primitive_dx8.c new file mode 100644 index 000000000..a5b5462f0 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_primitive_dx8.c @@ -0,0 +1,1446 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x/2000/XP/XBox (Win32) +* +* Description: Primitive (points/lines/tris/quads) rendering +* +****************************************************************************/ + +//#include "../GLDirect.h" + +//#include "gld_dx8.h" + +#include "dglcontext.h" +#include "ddlog.h" +#include "gld_dx8.h" + +#include "glheader.h" +#include "context.h" +#include "colormac.h" +#include "depth.h" +#include "extensions.h" +#include "macros.h" +#include "matrix.h" +// #include "mem.h" +//#include "mmath.h" +#include "mtypes.h" +#include "texformat.h" +#include "texstore.h" +#include "vbo/vbo.h" +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "swrast_setup/ss_context.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" + +// Disable compiler complaints about unreferenced local variables +#pragma warning (disable:4101) + +//--------------------------------------------------------------------------- +// Helper defines for primitives +//--------------------------------------------------------------------------- + +//static const float ooZ = 1.0f / 65536.0f; // One over Z + +#define GLD_COLOUR (D3DCOLOR_RGBA(swv->color[0], swv->color[1], swv->color[2], swv->color[3])) +#define GLD_SPECULAR (D3DCOLOR_RGBA(swv->specular[0], swv->specular[1], swv->specular[2], swv->specular[3])) +#define GLD_FLIP_Y(y) (gldCtx->dwHeight - (y)) + +//--------------------------------------------------------------------------- +// 2D vertex setup +//--------------------------------------------------------------------------- + +#define GLD_SETUP_2D_VARS_POINTS \ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); \ + GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx); \ + GLD_2D_VERTEX *pV = (GLD_2D_VERTEX*)gld->PB2d.pPoints; \ + SScontext *ss = SWSETUP_CONTEXT(ctx); \ + SWvertex *swv; \ + DWORD dwSpecularColour; \ + DWORD dwFlatColour + +#define GLD_SETUP_2D_VARS_LINES \ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); \ + GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx); \ + GLD_2D_VERTEX *pV = (GLD_2D_VERTEX*)gld->PB2d.pLines; \ + SScontext *ss = SWSETUP_CONTEXT(ctx); \ + SWvertex *swv; \ + DWORD dwSpecularColour; \ + DWORD dwFlatColour + +#define GLD_SETUP_2D_VARS_TRIANGLES \ + BOOL bFog = ctx->Fog.Enabled; \ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); \ + GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx); \ + GLD_2D_VERTEX *pV = (GLD_2D_VERTEX*)gld->PB2d.pTriangles; \ + SScontext *ss = SWSETUP_CONTEXT(ctx); \ + SWvertex *swv; \ + DWORD dwSpecularColour; \ + DWORD dwFlatColour; \ + GLuint facing = 0; \ + struct vertex_buffer *VB; \ + GLchan (*vbcolor)[4]; \ + GLchan (*vbspec)[4] + +#define GLD_SETUP_GET_SWVERT(s) \ + swv = &ss->verts[##s] + +#define GLD_SETUP_2D_VERTEX \ + pV->x = swv->win[0]; \ + pV->y = GLD_FLIP_Y(swv->win[1]); \ + pV->rhw = swv->win[3] + +#define GLD_SETUP_SMOOTH_COLOUR \ + pV->diffuse = GLD_COLOUR + +#define GLD_SETUP_GET_FLAT_COLOUR \ + dwFlatColour = GLD_COLOUR +#define GLD_SETUP_GET_FLAT_FOG_COLOUR \ + dwFlatColour = _gldComputeFog(ctx, swv) + +#define GLD_SETUP_USE_FLAT_COLOUR \ + pV->diffuse = dwFlatColour + +#define GLD_SETUP_GET_FLAT_SPECULAR \ + dwSpecularColour= GLD_SPECULAR + +#define GLD_SETUP_USE_FLAT_SPECULAR \ + pV->specular = dwSpecularColour + +#define GLD_SETUP_DEPTH \ + pV->sz = swv->win[2] / ctx->DepthMaxF +// pV->z = swv->win[2] * ooZ; + +#define GLD_SETUP_SPECULAR \ + pV->specular = GLD_SPECULAR + +#define GLD_SETUP_FOG \ + pV->diffuse = _gldComputeFog(ctx, swv) + +#define GLD_SETUP_TEX0 \ + pV->t0_u = swv->texcoord[0][0]; \ + pV->t0_v = swv->texcoord[0][1] + +#define GLD_SETUP_TEX1 \ + pV->t1_u = swv->texcoord[1][0]; \ + pV->t1_v = swv->texcoord[1][1] + +#define GLD_SETUP_LIGHTING(v) \ + if (facing == 1) { \ + pV->diffuse = D3DCOLOR_RGBA(vbcolor[##v][0], vbcolor[##v][1], vbcolor[##v][2], vbcolor[##v][3]); \ + if (vbspec) { \ + pV->specular = D3DCOLOR_RGBA(vbspec[##v][0], vbspec[##v][1], vbspec[##v][2], vbspec[##v][3]); \ + } \ + } else { \ + if (bFog) \ + GLD_SETUP_FOG; \ + else \ + GLD_SETUP_SMOOTH_COLOUR; \ + GLD_SETUP_SPECULAR; \ + } + +#define GLD_SETUP_GET_FLAT_LIGHTING(v) \ + if (facing == 1) { \ + dwFlatColour = D3DCOLOR_RGBA(vbcolor[##v][0], vbcolor[##v][1], vbcolor[##v][2], vbcolor[##v][3]); \ + if (vbspec) { \ + dwSpecularColour = D3DCOLOR_RGBA(vbspec[##v][0], vbspec[##v][1], vbspec[##v][2], vbspec[##v][3]); \ + } \ + } + +#define GLD_SETUP_TWOSIDED_LIGHTING \ + /* Two-sided lighting */ \ + if (ctx->_TriangleCaps & DD_TRI_LIGHT_TWOSIDE) { \ + SWvertex *verts = SWSETUP_CONTEXT(ctx)->verts; \ + SWvertex *v[3]; \ + GLfloat ex,ey,fx,fy,cc; \ + /* Get vars for later */ \ + VB = &TNL_CONTEXT(ctx)->vb; \ + vbcolor = (GLchan (*)[4])VB->ColorPtr[1]->data; \ + if (VB->SecondaryColorPtr[1]) { \ + vbspec = (GLchan (*)[4])VB->SecondaryColorPtr[1]->data; \ + } else { \ + vbspec = NULL; \ + } \ + v[0] = &verts[v0]; \ + v[1] = &verts[v1]; \ + v[2] = &verts[v2]; \ + ex = v[0]->win[0] - v[2]->win[0]; \ + ey = v[0]->win[1] - v[2]->win[1]; \ + fx = v[1]->win[0] - v[2]->win[0]; \ + fy = v[1]->win[1] - v[2]->win[1]; \ + cc = ex*fy - ey*fx; \ + facing = (cc < 0.0) ^ ctx->Polygon._FrontBit; \ + } + +//--------------------------------------------------------------------------- +// 3D vertex setup +//--------------------------------------------------------------------------- + +#define GLD_SETUP_3D_VARS_POINTS \ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); \ + GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx); \ + GLD_3D_VERTEX *pV = (GLD_3D_VERTEX*)gld->PB3d.pPoints; \ + TNLcontext *tnl = TNL_CONTEXT(ctx); \ + struct vertex_buffer *VB = &tnl->vb; \ + GLfloat (*p4f)[4]; \ + GLfloat (*tc)[4]; \ + DWORD dwColor; + +#define GLD_SETUP_3D_VARS_LINES \ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); \ + GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx); \ + GLD_3D_VERTEX *pV = (GLD_3D_VERTEX*)gld->PB3d.pLines; \ + TNLcontext *tnl = TNL_CONTEXT(ctx); \ + struct vertex_buffer *VB = &tnl->vb; \ + GLfloat (*p4f)[4]; \ + GLfloat (*tc)[4]; \ + DWORD dwColor; + +#define GLD_SETUP_3D_VARS_TRIANGLES \ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); \ + GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx); \ + GLD_3D_VERTEX *pV = (GLD_3D_VERTEX*)gld->PB3d.pTriangles; \ + TNLcontext *tnl = TNL_CONTEXT(ctx); \ + struct vertex_buffer *VB = &tnl->vb; \ + GLfloat (*p4f)[4]; \ + GLfloat (*tc)[4]; \ + DWORD dwColor; + +#define GLD_SETUP_3D_VERTEX(v) \ + p4f = VB->ObjPtr->data; \ + pV->Position.x = p4f[##v][0]; \ + pV->Position.y = p4f[##v][1]; \ + pV->Position.z = p4f[##v][2]; + +#define GLD_SETUP_SMOOTH_COLOUR_3D(v) \ + p4f = (GLfloat (*)[4])VB->ColorPtr[0]->data; \ + pV->Diffuse = D3DCOLOR_COLORVALUE(p4f[##v][0], p4f[##v][1], p4f[##v][2], p4f[##v][3]); + + +#define GLD_SETUP_GET_FLAT_COLOUR_3D(v) \ + p4f = (GLfloat (*)[4])VB->ColorPtr[0]->data; \ + dwColor = D3DCOLOR_COLORVALUE(p4f[##v][0], p4f[##v][1], p4f[##v][2], p4f[##v][3]); + +#define GLD_SETUP_USE_FLAT_COLOUR_3D \ + pV->Diffuse = dwColor; + +#define GLD_SETUP_TEX0_3D(v) \ + if (VB->TexCoordPtr[0]) { \ + tc = VB->TexCoordPtr[0]->data; \ + pV->TexUnit0.x = tc[##v][0]; \ + pV->TexUnit0.y = tc[##v][1]; \ + } + +#define GLD_SETUP_TEX1_3D(v) \ + if (VB->TexCoordPtr[1]) { \ + tc = VB->TexCoordPtr[1]->data; \ + pV->TexUnit1.x = tc[##v][0]; \ + pV->TexUnit1.y = tc[##v][1]; \ + } + +//--------------------------------------------------------------------------- +// Helper functions +//--------------------------------------------------------------------------- + +__inline DWORD _gldComputeFog( + GLcontext *ctx, + SWvertex *swv) +{ + // Full fog calculation. + // Based on Mesa code. + + GLchan rFog, gFog, bFog; + GLchan fR, fG, fB; + const GLfloat f = swv->fog; + const GLfloat g = 1.0f - f; + + UNCLAMPED_FLOAT_TO_CHAN(rFog, ctx->Fog.Color[RCOMP]); + UNCLAMPED_FLOAT_TO_CHAN(gFog, ctx->Fog.Color[GCOMP]); + UNCLAMPED_FLOAT_TO_CHAN(bFog, ctx->Fog.Color[BCOMP]); + fR = f * swv->color[0] + g * rFog; + fG = f * swv->color[1] + g * gFog; + fB = f * swv->color[2] + g * bFog; + return D3DCOLOR_RGBA(fR, fG, fB, swv->color[3]); +} + +//--------------------------------------------------------------------------- + +void gld_ResetLineStipple_DX8( + GLcontext *ctx) +{ + // TODO: Fake stipple with a 32x32 texture. +} + +//--------------------------------------------------------------------------- +// 2D (post-transformed) primitives +//--------------------------------------------------------------------------- + +void gld_Points2D_DX8( + GLcontext *ctx, + GLuint first, + GLuint last) +{ + GLD_SETUP_2D_VARS_POINTS; + + unsigned i; + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + + // _Size is already clamped to MaxPointSize and MinPointSize + IDirect3DDevice8_SetRenderState(gld->pDev, D3DRS_POINTSIZE, *((DWORD*)&ctx->Point._Size)); + + if (VB->Elts) { + for (i=first; iClipMask[VB->Elts[i]] == 0) { +// _swrast_Point( ctx, &verts[VB->Elts[i]] ); + GLD_SETUP_GET_SWVERT(VB->Elts[i]); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_SMOOTH_COLOUR; + GLD_SETUP_DEPTH; + GLD_SETUP_SPECULAR; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + } + } + } else { + GLD_SETUP_GET_SWVERT(first); + for (i=first; iClipMask[i] == 0) { +// _swrast_Point( ctx, &verts[i] ); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_SMOOTH_COLOUR; + GLD_SETUP_DEPTH; + GLD_SETUP_SPECULAR; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + } + } + } + + gld->PB2d.pPoints = (BYTE*)pV; + gld->PB2d.nPoints += (last-first); +} + +//--------------------------------------------------------------------------- + +void gld_Line2DFlat_DX8( + GLcontext *ctx, + GLuint v0, + GLuint v1) +{ + GLD_SETUP_2D_VARS_LINES; + + GLD_SETUP_GET_SWVERT(v1); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_GET_FLAT_COLOUR; + GLD_SETUP_USE_FLAT_COLOUR; + GLD_SETUP_GET_FLAT_SPECULAR; + GLD_SETUP_USE_FLAT_SPECULAR; + pV++; + + GLD_SETUP_GET_SWVERT(v0); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + GLD_SETUP_USE_FLAT_SPECULAR; + pV++; + + gld->PB2d.pLines = (BYTE*)pV; + gld->PB2d.nLines++; +} + +//--------------------------------------------------------------------------- + +void gld_Line2DSmooth_DX8( + GLcontext *ctx, + GLuint v0, + GLuint v1) +{ + GLD_SETUP_2D_VARS_LINES; + + GLD_SETUP_GET_SWVERT(v0); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_SMOOTH_COLOUR; + GLD_SETUP_DEPTH; + GLD_SETUP_SPECULAR; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + pV++; + + GLD_SETUP_GET_SWVERT(v1); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_SMOOTH_COLOUR; + GLD_SETUP_SPECULAR; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + pV++; + + gld->PB2d.pLines = (BYTE*)pV; + gld->PB2d.nLines++; +} + +//--------------------------------------------------------------------------- + +void gld_Triangle2DFlat_DX8( + GLcontext *ctx, + GLuint v0, + GLuint v1, + GLuint v2) +{ + GLD_SETUP_2D_VARS_TRIANGLES; + + GLD_SETUP_GET_SWVERT(v2); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_GET_FLAT_COLOUR; + GLD_SETUP_USE_FLAT_COLOUR; + pV++;; + + GLD_SETUP_GET_SWVERT(v0); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + pV++; + + GLD_SETUP_GET_SWVERT(v1); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + pV++; + + gld->PB2d.pTriangles = (BYTE*)pV; + gld->PB2d.nTriangles++; +} + +//--------------------------------------------------------------------------- + +void gld_Triangle2DSmooth_DX8( + GLcontext *ctx, + GLuint v0, + GLuint v1, + GLuint v2) +{ + + GLD_SETUP_2D_VARS_TRIANGLES; + + GLD_SETUP_GET_SWVERT(v0); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_SMOOTH_COLOUR; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + pV++; + + GLD_SETUP_GET_SWVERT(v1); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_SMOOTH_COLOUR; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + pV++; + + GLD_SETUP_GET_SWVERT(v2); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_SMOOTH_COLOUR; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + pV++; + + gld->PB2d.pTriangles = (BYTE*)pV; + gld->PB2d.nTriangles++; +} + +//--------------------------------------------------------------------------- + +void gld_Triangle2DFlatExtras_DX8( + GLcontext *ctx, + GLuint v0, + GLuint v1, + GLuint v2) +{ + GLD_SETUP_2D_VARS_TRIANGLES; + + GLD_SETUP_TWOSIDED_LIGHTING(v2); + + GLD_SETUP_GET_SWVERT(v2); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + if (bFog) + GLD_SETUP_GET_FLAT_FOG_COLOUR; + else + GLD_SETUP_GET_FLAT_COLOUR; + GLD_SETUP_GET_FLAT_SPECULAR; + GLD_SETUP_GET_FLAT_LIGHTING(v2); + GLD_SETUP_USE_FLAT_COLOUR; + GLD_SETUP_USE_FLAT_SPECULAR; + pV++; + + GLD_SETUP_GET_SWVERT(v0); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + GLD_SETUP_USE_FLAT_SPECULAR; + pV++; + + GLD_SETUP_GET_SWVERT(v1); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + GLD_SETUP_USE_FLAT_SPECULAR; + pV++; + + gld->PB2d.pTriangles = (BYTE*)pV; + gld->PB2d.nTriangles++; +} + +//--------------------------------------------------------------------------- + +void gld_Triangle2DSmoothExtras_DX8( + GLcontext *ctx, + GLuint v0, + GLuint v1, + GLuint v2) +{ + GLD_SETUP_2D_VARS_TRIANGLES; + + GLD_SETUP_TWOSIDED_LIGHTING(v0); + + GLD_SETUP_GET_SWVERT(v0); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_LIGHTING(v0); + pV++; + + GLD_SETUP_GET_SWVERT(v1); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_LIGHTING(v1); + pV++; + + GLD_SETUP_GET_SWVERT(v2); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_LIGHTING(v2); + pV++; + + gld->PB2d.pTriangles = (BYTE*)pV; + gld->PB2d.nTriangles++; +} + +//--------------------------------------------------------------------------- + +void gld_Quad2DFlat_DX8( + GLcontext *ctx, + GLuint v0, + GLuint v1, + GLuint v2, + GLuint v3) +{ + GLD_SETUP_2D_VARS_TRIANGLES; + + GLD_SETUP_GET_SWVERT(v3); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_GET_FLAT_COLOUR; + GLD_SETUP_USE_FLAT_COLOUR; + pV++; + + GLD_SETUP_GET_SWVERT(v0); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + pV++; + + GLD_SETUP_GET_SWVERT(v1); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + pV++; + + GLD_SETUP_GET_SWVERT(v1); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + pV++; + + GLD_SETUP_GET_SWVERT(v2); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + pV++; + + GLD_SETUP_GET_SWVERT(v3); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + pV++; + + gld->PB2d.pTriangles = (BYTE*)pV; + gld->PB2d.nTriangles += 2; +} + +//--------------------------------------------------------------------------- + +void gld_Quad2DSmooth_DX8( + GLcontext *ctx, + GLuint v0, + GLuint v1, + GLuint v2, + GLuint v3) +{ + GLD_SETUP_2D_VARS_TRIANGLES; + + GLD_SETUP_GET_SWVERT(v0); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_SMOOTH_COLOUR; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + pV++; + + GLD_SETUP_GET_SWVERT(v1); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_SMOOTH_COLOUR; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + pV++; + + GLD_SETUP_GET_SWVERT(v2); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_SMOOTH_COLOUR; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + pV++; + + GLD_SETUP_GET_SWVERT(v2); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_SMOOTH_COLOUR; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + pV++; + + GLD_SETUP_GET_SWVERT(v3); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_SMOOTH_COLOUR; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + pV++; + + GLD_SETUP_GET_SWVERT(v0); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_SMOOTH_COLOUR; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + pV++; + + gld->PB2d.pTriangles = (BYTE*)pV; + gld->PB2d.nTriangles += 2; +} + +//--------------------------------------------------------------------------- + +void gld_Quad2DFlatExtras_DX8( + GLcontext *ctx, + GLuint v0, + GLuint v1, + GLuint v2, + GLuint v3) +{ + GLD_SETUP_2D_VARS_TRIANGLES; + + GLD_SETUP_TWOSIDED_LIGHTING(v3); + + GLD_SETUP_GET_SWVERT(v3); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + if (bFog) + GLD_SETUP_GET_FLAT_FOG_COLOUR; + else + GLD_SETUP_GET_FLAT_COLOUR; + GLD_SETUP_GET_FLAT_SPECULAR; + GLD_SETUP_GET_FLAT_LIGHTING(v3); + GLD_SETUP_USE_FLAT_COLOUR; + GLD_SETUP_USE_FLAT_SPECULAR; + pV++; + + GLD_SETUP_GET_SWVERT(v0); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + GLD_SETUP_USE_FLAT_SPECULAR; + pV++; + + GLD_SETUP_GET_SWVERT(v1); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + GLD_SETUP_USE_FLAT_SPECULAR; + pV++; + + GLD_SETUP_GET_SWVERT(v1); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + GLD_SETUP_USE_FLAT_SPECULAR; + pV++; + + GLD_SETUP_GET_SWVERT(v2); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + GLD_SETUP_USE_FLAT_SPECULAR; + pV++; + + GLD_SETUP_GET_SWVERT(v3); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + GLD_SETUP_USE_FLAT_SPECULAR; + pV++; + + gld->PB2d.pTriangles = (BYTE*)pV; + gld->PB2d.nTriangles += 2; +} + +//--------------------------------------------------------------------------- + +void gld_Quad2DSmoothExtras_DX8( + GLcontext *ctx, + GLuint v0, + GLuint v1, + GLuint v2, + GLuint v3) +{ + GLD_SETUP_2D_VARS_TRIANGLES; + + GLD_SETUP_TWOSIDED_LIGHTING(v0); + + GLD_SETUP_GET_SWVERT(v0); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_LIGHTING(v0); + pV++; + + GLD_SETUP_GET_SWVERT(v1); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_LIGHTING(v1); + pV++; + + GLD_SETUP_GET_SWVERT(v2); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_LIGHTING(v2); + pV++; + + GLD_SETUP_GET_SWVERT(v2); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_LIGHTING(v2); + pV++; + + GLD_SETUP_GET_SWVERT(v3); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_LIGHTING(v3); + pV++; + + GLD_SETUP_GET_SWVERT(v0); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_LIGHTING(v0); + pV++; + + gld->PB2d.pTriangles = (BYTE*)pV; + gld->PB2d.nTriangles += 2; +} + +//--------------------------------------------------------------------------- +// 3D (pre-transformed) primitives +//--------------------------------------------------------------------------- + +void gld_Points3D_DX8( + GLcontext *ctx, + GLuint first, + GLuint last) +{ + GLD_SETUP_3D_VARS_POINTS + + unsigned i; +// struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + + // _Size is already clamped to MaxPointSize and MinPointSize + IDirect3DDevice8_SetRenderState(gld->pDev, D3DRS_POINTSIZE, *((DWORD*)&ctx->Point._Size)); + + if (VB->Elts) { + for (i=first; iClipMask[VB->Elts[i]] == 0) { +// _swrast_Point( ctx, &verts[VB->Elts[i]] ); +// GLD_SETUP_GET_SWVERT(VB->Elts[i]); + GLD_SETUP_3D_VERTEX(VB->Elts[i]) + GLD_SETUP_SMOOTH_COLOUR_3D(i) + GLD_SETUP_TEX0_3D(i) + GLD_SETUP_TEX1_3D(i) + } + } + } else { +// GLD_SETUP_GET_SWVERT(first); + for (i=first; iClipMask[i] == 0) { +// _swrast_Point( ctx, &verts[i] ); + GLD_SETUP_3D_VERTEX(i) + GLD_SETUP_SMOOTH_COLOUR_3D(i) + GLD_SETUP_TEX0_3D(i) + GLD_SETUP_TEX1_3D(i) + } + } + } +/* + for (i=first; iPB3d.pPoints = (BYTE*)pV; + gld->PB3d.nPoints += (last-first); +} + +//--------------------------------------------------------------------------- +// Line functions +//--------------------------------------------------------------------------- + +void gld_Line3DFlat_DX8( + GLcontext *ctx, + GLuint v0, + GLuint v1) +{ + GLD_SETUP_3D_VARS_LINES + + GLD_SETUP_3D_VERTEX(v1) + GLD_SETUP_GET_FLAT_COLOUR_3D(v1) + GLD_SETUP_USE_FLAT_COLOUR_3D + GLD_SETUP_TEX0_3D(v1) + GLD_SETUP_TEX1_3D(v1) + pV++; + + GLD_SETUP_3D_VERTEX(v0) + GLD_SETUP_USE_FLAT_COLOUR_3D + GLD_SETUP_TEX0_3D(v0) + GLD_SETUP_TEX1_3D(v0) + pV++; + + gld->PB3d.pLines = (BYTE*)pV; + gld->PB3d.nLines++; +} + +//--------------------------------------------------------------------------- + +void gld_Line3DSmooth_DX8( + GLcontext *ctx, + GLuint v0, + GLuint v1) +{ + GLD_SETUP_3D_VARS_LINES + + GLD_SETUP_3D_VERTEX(v1) + GLD_SETUP_SMOOTH_COLOUR_3D(v1) + GLD_SETUP_TEX0_3D(v1) + GLD_SETUP_TEX1_3D(v1) + pV++; + + GLD_SETUP_3D_VERTEX(v0) + GLD_SETUP_SMOOTH_COLOUR_3D(v0) + GLD_SETUP_TEX0_3D(v0) + GLD_SETUP_TEX1_3D(v0) + pV++; + + gld->PB3d.pLines = (BYTE*)pV; + gld->PB3d.nLines++; +} + +//--------------------------------------------------------------------------- +// Triangle functions +//--------------------------------------------------------------------------- + +void gld_Triangle3DFlat_DX8( + GLcontext *ctx, + GLuint v0, + GLuint v1, + GLuint v2) +{ + GLD_SETUP_3D_VARS_TRIANGLES + + GLD_SETUP_3D_VERTEX(v2) + GLD_SETUP_TEX0_3D(v2) + GLD_SETUP_TEX1_3D(v2) + GLD_SETUP_GET_FLAT_COLOUR_3D(v2) + GLD_SETUP_USE_FLAT_COLOUR_3D + pV++; + + GLD_SETUP_3D_VERTEX(v0) + GLD_SETUP_TEX0_3D(v0) + GLD_SETUP_TEX1_3D(v0) + GLD_SETUP_USE_FLAT_COLOUR_3D + pV++; + + GLD_SETUP_3D_VERTEX(v1) + GLD_SETUP_TEX0_3D(v1) + GLD_SETUP_TEX1_3D(v1) + GLD_SETUP_USE_FLAT_COLOUR_3D + pV++; + + gld->PB3d.pTriangles = (BYTE*)pV; + gld->PB3d.nTriangles++; +} + +//--------------------------------------------------------------------------- + +void gld_Triangle3DSmooth_DX8( + GLcontext *ctx, + GLuint v0, + GLuint v1, + GLuint v2) +{ + GLD_SETUP_3D_VARS_TRIANGLES + + GLD_SETUP_3D_VERTEX(v0) + GLD_SETUP_SMOOTH_COLOUR_3D(v0) + GLD_SETUP_TEX0_3D(v0) + GLD_SETUP_TEX1_3D(v0) + pV++; + + GLD_SETUP_3D_VERTEX(v1) + GLD_SETUP_SMOOTH_COLOUR_3D(v1) + GLD_SETUP_TEX0_3D(v1) + GLD_SETUP_TEX1_3D(v1) + pV++; + + GLD_SETUP_3D_VERTEX(v2) + GLD_SETUP_SMOOTH_COLOUR_3D(v2) + GLD_SETUP_TEX0_3D(v2) + GLD_SETUP_TEX1_3D(v2) + pV++; + + gld->PB3d.pTriangles = (BYTE*)pV; + gld->PB3d.nTriangles++; +} + +//--------------------------------------------------------------------------- +// Quad functions +//--------------------------------------------------------------------------- + +void gld_Quad3DFlat_DX8( + GLcontext *ctx, + GLuint v0, + GLuint v1, + GLuint v2, + GLuint v3) +{ + GLD_SETUP_3D_VARS_TRIANGLES + + GLD_SETUP_3D_VERTEX(v3) + GLD_SETUP_GET_FLAT_COLOUR_3D(v3) + GLD_SETUP_USE_FLAT_COLOUR_3D + GLD_SETUP_TEX0_3D(v3) + GLD_SETUP_TEX1_3D(v3) + pV++; + + GLD_SETUP_3D_VERTEX(v0) + GLD_SETUP_USE_FLAT_COLOUR_3D + GLD_SETUP_TEX0_3D(v0) + GLD_SETUP_TEX1_3D(v0) + pV++; + + GLD_SETUP_3D_VERTEX(v1) + GLD_SETUP_USE_FLAT_COLOUR_3D + GLD_SETUP_TEX0_3D(v1) + GLD_SETUP_TEX1_3D(v1) + pV++; + + GLD_SETUP_3D_VERTEX(v1) + GLD_SETUP_USE_FLAT_COLOUR_3D + GLD_SETUP_TEX0_3D(v1) + GLD_SETUP_TEX1_3D(v1) + pV++; + + GLD_SETUP_3D_VERTEX(v2) + GLD_SETUP_USE_FLAT_COLOUR_3D + GLD_SETUP_TEX0_3D(v2) + GLD_SETUP_TEX1_3D(v2) + pV++; + + GLD_SETUP_3D_VERTEX(v3) + GLD_SETUP_USE_FLAT_COLOUR_3D + GLD_SETUP_TEX0_3D(v3) + GLD_SETUP_TEX1_3D(v3) + pV++; + + gld->PB3d.pTriangles = (BYTE*)pV; + gld->PB3d.nTriangles += 2; +} + +//--------------------------------------------------------------------------- + +void gld_Quad3DSmooth_DX8( + GLcontext *ctx, + GLuint v0, + GLuint v1, + GLuint v2, + GLuint v3) +{ + GLD_SETUP_3D_VARS_TRIANGLES + + GLD_SETUP_3D_VERTEX(v0) + GLD_SETUP_SMOOTH_COLOUR_3D(v0) + GLD_SETUP_TEX0_3D(v0) + GLD_SETUP_TEX1_3D(v0) + pV++; + + GLD_SETUP_3D_VERTEX(v1) + GLD_SETUP_SMOOTH_COLOUR_3D(v1) + GLD_SETUP_TEX0_3D(v1) + GLD_SETUP_TEX1_3D(v1) + pV++; + + GLD_SETUP_3D_VERTEX(v2) + GLD_SETUP_SMOOTH_COLOUR_3D(v2) + GLD_SETUP_TEX0_3D(v2) + GLD_SETUP_TEX1_3D(v2) + pV++; + + GLD_SETUP_3D_VERTEX(v2) + GLD_SETUP_SMOOTH_COLOUR_3D(v2) + GLD_SETUP_TEX0_3D(v2) + GLD_SETUP_TEX1_3D(v2) + pV++; + + GLD_SETUP_3D_VERTEX(v3) + GLD_SETUP_SMOOTH_COLOUR_3D(v3) + GLD_SETUP_TEX0_3D(v3) + GLD_SETUP_TEX1_3D(v3) + pV++; + + GLD_SETUP_3D_VERTEX(v0) + GLD_SETUP_SMOOTH_COLOUR_3D(v0) + GLD_SETUP_TEX0_3D(v0) + GLD_SETUP_TEX1_3D(v0) + pV++; + + gld->PB3d.pTriangles = (BYTE*)pV; + gld->PB3d.nTriangles += 2; +} + +//--------------------------------------------------------------------------- +// Vertex setup for two-sided-lighting vertex shader +//--------------------------------------------------------------------------- + +/* + +void gld_Points2DTwoside_DX8(GLcontext *ctx, GLuint first, GLuint last) +{ + // NOTE: Two-sided lighting does not apply to Points +} + +//--------------------------------------------------------------------------- + +void gld_Line2DFlatTwoside_DX8(GLcontext *ctx, GLuint v0, GLuint v1) +{ + // NOTE: Two-sided lighting does not apply to Lines +} + +//--------------------------------------------------------------------------- + +void gld_Line2DSmoothTwoside_DX8(GLcontext *ctx, GLuint v0, GLuint v1) +{ + // NOTE: Two-sided lighting does not apply to Lines +} + +//--------------------------------------------------------------------------- + +void gld_Triangle2DFlatTwoside_DX8(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2) +{ +} + +//--------------------------------------------------------------------------- + +void gld_Triangle2DSmoothTwoside_DX8(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx); + GLD_TWOSIDED_VERTEX *pV = (GLD_TWOSIDED_VERTEX*)gld->PBtwosidelight.pTriangles; + SScontext *ss = SWSETUP_CONTEXT(ctx); + SWvertex *swv; + DWORD dwSpecularColour; + DWORD dwFlatColour; + GLuint facing = 0; + struct vertex_buffer *VB; + GLchan (*vbcolor)[4]; + GLchan (*vbspec)[4]; + + // Reciprocal of DepthMax + const float ooDepthMax = 1.0f / ctx->DepthMaxF; + + // 1st vert + swv = &ss->verts[v0]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + // 2nd vert + swv = &ss->verts[v1]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + // 3rd vert + swv = &ss->verts[v2]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + gld->PBtwosidelight.pTriangles = (BYTE*)pV; + gld->PBtwosidelight.nTriangles++; +} + +//--------------------------------------------------------------------------- + +void gld_Quad2DFlatTwoside_DX8(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx); + GLD_TWOSIDED_VERTEX *pV = (GLD_TWOSIDED_VERTEX*)gld->PBtwosidelight.pTriangles; + SScontext *ss = SWSETUP_CONTEXT(ctx); + SWvertex *swv; + DWORD dwSpecularColour; + DWORD dwFlatColour; + GLuint facing = 0; + struct vertex_buffer *VB; + GLchan (*vbcolor)[4]; + GLchan (*vbspec)[4]; + + // Reciprocal of DepthMax + const float ooDepthMax = 1.0f / ctx->DepthMaxF; + + // 1st vert + swv = &ss->verts[v0]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + // 2nd vert + swv = &ss->verts[v1]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + // 3rd vert + swv = &ss->verts[v2]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + // 4th vert + swv = &ss->verts[v2]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + // 5th vert + swv = &ss->verts[v3]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + // 6th vert + swv = &ss->verts[v0]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + gld->PBtwosidelight.pTriangles = (BYTE*)pV; + gld->PBtwosidelight.nTriangles += 2; +} + +//--------------------------------------------------------------------------- + +void gld_Quad2DSmoothTwoside_DX8(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx); + GLD_TWOSIDED_VERTEX *pV = (GLD_TWOSIDED_VERTEX*)gld->PBtwosidelight.pTriangles; + SScontext *ss = SWSETUP_CONTEXT(ctx); + SWvertex *swv; + DWORD dwSpecularColour; + DWORD dwFlatColour; + GLuint facing = 0; + struct vertex_buffer *VB; + GLchan (*vbcolor)[4]; + GLchan (*vbspec)[4]; + + // Reciprocal of DepthMax + const float ooDepthMax = 1.0f / ctx->DepthMaxF; + + // 1st vert + swv = &ss->verts[v0]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + // 2nd vert + swv = &ss->verts[v1]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + // 3rd vert + swv = &ss->verts[v2]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + // 4th vert + swv = &ss->verts[v2]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + // 5th vert + swv = &ss->verts[v3]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + // 6th vert + swv = &ss->verts[v0]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + gld->PBtwosidelight.pTriangles = (BYTE*)pV; + gld->PBtwosidelight.nTriangles += 2; +} + +//--------------------------------------------------------------------------- + +*/ diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_texture_dx8.c b/mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_texture_dx8.c new file mode 100644 index 000000000..f24b3cfb7 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_texture_dx8.c @@ -0,0 +1,2046 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x/2000/XP/XBox (Win32) +* +* Description: Texture / Bitmap functions +* +****************************************************************************/ + +#include "dglcontext.h" +#include "ddlog.h" +#include "gld_dx8.h" + +#include + +#include "texformat.h" +#include "colormac.h" +#include "texstore.h" +#include "image.h" +// #include "mem.h" + +//--------------------------------------------------------------------------- + +#define GLD_FLIP_HEIGHT(y,h) (gldCtx->dwHeight - (y) - (h)) + +//--------------------------------------------------------------------------- +// 1D texture fetch +//--------------------------------------------------------------------------- + +#define CHAN_SRC( t, i, j, k, sz ) \ + ((GLchan *)(t)->Data + (i) * (sz)) +#define UBYTE_SRC( t, i, j, k, sz ) \ + ((GLubyte *)(t)->Data + (i) * (sz)) +#define USHORT_SRC( t, i, j, k ) \ + ((GLushort *)(t)->Data + (i)) +#define FLOAT_SRC( t, i, j, k ) \ + ((GLfloat *)(t)->Data + (i)) + +//--------------------------------------------------------------------------- + +static void gld_fetch_1d_texel_X8R8G8B8( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *texel ) +{ + const GLchan *src = CHAN_SRC( texImage, i, j, k, 4 ); + GLchan *rgba = (GLchan *)texel; + rgba[RCOMP] = src[2]; + rgba[GCOMP] = src[1]; + rgba[BCOMP] = src[0]; + rgba[ACOMP] = CHAN_MAX; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_1d_texel_f_X8R8G8B8( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLfloat *texel ) +{ + const GLchan *src = CHAN_SRC( texImage, i, j, k, 4 ); + texel[RCOMP] = CHAN_TO_FLOAT(src[0]); + texel[GCOMP] = CHAN_TO_FLOAT(src[1]); + texel[BCOMP] = CHAN_TO_FLOAT(src[2]); + texel[ACOMP] = 1.f; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_1d_texel_X1R5G5B5( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *texel ) +{ + const GLushort *src = USHORT_SRC( texImage, i, j, k ); + GLchan *rgba = (GLchan *) texel; GLushort s = *src; + rgba[RCOMP] = UBYTE_TO_CHAN( ((s >> 10) & 0xf8) * 255 / 0xf8 ); + rgba[GCOMP] = UBYTE_TO_CHAN( ((s >> 5) & 0xf8) * 255 / 0xf8 ); + rgba[BCOMP] = UBYTE_TO_CHAN( ((s ) & 0xf8) * 255 / 0xf8 ); + rgba[ACOMP] = CHAN_MAX; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_1d_texel_f_X1R5G5B5( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLfloat *texel ) +{ + const GLushort *src = USHORT_SRC( texImage, i, j, k ); + GLushort s = *src; + texel[RCOMP] = UBYTE_TO_FLOAT( ((s >> 10) & 0xf8) * 255 / 0xf8 ); + texel[GCOMP] = UBYTE_TO_FLOAT( ((s >> 5) & 0xf8) * 255 / 0xf8 ); + texel[BCOMP] = UBYTE_TO_FLOAT( ((s ) & 0xf8) * 255 / 0xf8 ); + texel[ACOMP] = 1.f; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_1d_texel_X4R4G4B4( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *texel ) +{ + const GLushort *src = USHORT_SRC( texImage, i, j, k ); + GLchan *rgba = (GLchan *) texel; GLushort s = *src; + rgba[RCOMP] = UBYTE_TO_CHAN( ((s >> 8) & 0xf) * 255 / 0xf ); + rgba[GCOMP] = UBYTE_TO_CHAN( ((s >> 4) & 0xf) * 255 / 0xf ); + rgba[BCOMP] = UBYTE_TO_CHAN( ((s ) & 0xf) * 255 / 0xf ); + rgba[ACOMP] = CHAN_MAX; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_1d_texel_f_X4R4G4B4( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLfloat *texel ) +{ + const GLushort *src = USHORT_SRC( texImage, i, j, k ); + GLushort s = *src; + texel[RCOMP] = UBYTE_TO_FLOAT( ((s >> 8) & 0xf) * 255 / 0xf ); + texel[GCOMP] = UBYTE_TO_FLOAT( ((s >> 4) & 0xf) * 255 / 0xf ); + texel[BCOMP] = UBYTE_TO_FLOAT( ((s ) & 0xf) * 255 / 0xf ); + texel[ACOMP] = 1.f; +} + +//--------------------------------------------------------------------------- + +#undef CHAN_SRC +#undef UBYTE_SRC +#undef USHORT_SRC +#undef FLOAT_SRC + +//--------------------------------------------------------------------------- +// 2D texture fetch +//--------------------------------------------------------------------------- + +#define CHAN_SRC( t, i, j, k, sz ) \ + ((GLchan *)(t)->Data + ((t)->Width * (j) + (i)) * (sz)) +#define UBYTE_SRC( t, i, j, k, sz ) \ + ((GLubyte *)(t)->Data + ((t)->Width * (j) + (i)) * (sz)) +#define USHORT_SRC( t, i, j, k ) \ + ((GLushort *)(t)->Data + ((t)->Width * (j) + (i))) +#define FLOAT_SRC( t, i, j, k ) \ + ((GLfloat *)(t)->Data + ((t)->Width * (j) + (i))) + +//--------------------------------------------------------------------------- + +static void gld_fetch_2d_texel_X8R8G8B8( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *texel ) +{ + const GLchan *src = CHAN_SRC( texImage, i, j, k, 4 ); + GLchan *rgba = (GLchan *)texel; + rgba[RCOMP] = src[2]; + rgba[GCOMP] = src[1]; + rgba[BCOMP] = src[0]; + rgba[ACOMP] = CHAN_MAX; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_2d_texel_f_X8R8G8B8( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLfloat *texel ) +{ + const GLchan *src = CHAN_SRC( texImage, i, j, k, 4 ); + texel[RCOMP] = CHAN_TO_FLOAT(src[0]); + texel[GCOMP] = CHAN_TO_FLOAT(src[1]); + texel[BCOMP] = CHAN_TO_FLOAT(src[2]); + texel[ACOMP] = 1.f; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_2d_texel_X1R5G5B5( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *texel ) +{ + const GLushort *src = USHORT_SRC( texImage, i, j, k ); + GLchan *rgba = (GLchan *) texel; GLushort s = *src; + rgba[RCOMP] = UBYTE_TO_CHAN( ((s >> 10) & 0xf8) * 255 / 0xf8 ); + rgba[GCOMP] = UBYTE_TO_CHAN( ((s >> 5) & 0xf8) * 255 / 0xf8 ); + rgba[BCOMP] = UBYTE_TO_CHAN( ((s ) & 0xf8) * 255 / 0xf8 ); + rgba[ACOMP] = CHAN_MAX; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_2d_texel_f_X1R5G5B5( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLfloat *texel ) +{ + const GLushort *src = USHORT_SRC( texImage, i, j, k ); + GLushort s = *src; + texel[RCOMP] = UBYTE_TO_FLOAT( ((s >> 10) & 0xf8) * 255 / 0xf8 ); + texel[GCOMP] = UBYTE_TO_FLOAT( ((s >> 5) & 0xf8) * 255 / 0xf8 ); + texel[BCOMP] = UBYTE_TO_FLOAT( ((s ) & 0xf8) * 255 / 0xf8 ); + texel[ACOMP] = 1.f; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_2d_texel_X4R4G4B4( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *texel ) +{ + const GLushort *src = USHORT_SRC( texImage, i, j, k ); + GLchan *rgba = (GLchan *) texel; GLushort s = *src; + rgba[RCOMP] = UBYTE_TO_CHAN( ((s >> 8) & 0xf) * 255 / 0xf ); + rgba[GCOMP] = UBYTE_TO_CHAN( ((s >> 4) & 0xf) * 255 / 0xf ); + rgba[BCOMP] = UBYTE_TO_CHAN( ((s ) & 0xf) * 255 / 0xf ); + rgba[ACOMP] = CHAN_MAX; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_2d_texel_f_X4R4G4B4( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLfloat *texel ) +{ + const GLushort *src = USHORT_SRC( texImage, i, j, k ); + GLushort s = *src; + texel[RCOMP] = UBYTE_TO_FLOAT( ((s >> 8) & 0xf) * 255 / 0xf ); + texel[GCOMP] = UBYTE_TO_FLOAT( ((s >> 4) & 0xf) * 255 / 0xf ); + texel[BCOMP] = UBYTE_TO_FLOAT( ((s ) & 0xf) * 255 / 0xf ); + texel[ACOMP] = 1.f; +} + +//--------------------------------------------------------------------------- + +#undef CHAN_SRC +#undef UBYTE_SRC +#undef USHORT_SRC +#undef FLOAT_SRC + +//--------------------------------------------------------------------------- +// 3D texture fetch +//--------------------------------------------------------------------------- + +#define CHAN_SRC( t, i, j, k, sz ) \ + (GLchan *)(t)->Data + (((t)->Height * (k) + (j)) * \ + (t)->Width + (i)) * (sz) +#define UBYTE_SRC( t, i, j, k, sz ) \ + ((GLubyte *)(t)->Data + (((t)->Height * (k) + (j)) * \ + (t)->Width + (i)) * (sz)) +#define USHORT_SRC( t, i, j, k ) \ + ((GLushort *)(t)->Data + (((t)->Height * (k) + (j)) * \ + (t)->Width + (i))) +#define FLOAT_SRC( t, i, j, k ) \ + ((GLfloat *)(t)->Data + (((t)->Height * (k) + (j)) * \ + (t)->Width + (i))) + +//--------------------------------------------------------------------------- + +static void gld_fetch_3d_texel_X8R8G8B8( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *texel ) +{ + const GLchan *src = CHAN_SRC( texImage, i, j, k, 4 ); + GLchan *rgba = (GLchan *)texel; + rgba[RCOMP] = src[2]; + rgba[GCOMP] = src[1]; + rgba[BCOMP] = src[0]; + rgba[ACOMP] = CHAN_MAX; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_3d_texel_f_X8R8G8B8( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLfloat *texel ) +{ + const GLchan *src = CHAN_SRC( texImage, i, j, k, 4 ); + texel[RCOMP] = CHAN_TO_FLOAT(src[0]); + texel[GCOMP] = CHAN_TO_FLOAT(src[1]); + texel[BCOMP] = CHAN_TO_FLOAT(src[2]); + texel[ACOMP] = 1.f; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_3d_texel_X1R5G5B5( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *texel ) +{ + const GLushort *src = USHORT_SRC( texImage, i, j, k ); + GLchan *rgba = (GLchan *) texel; GLushort s = *src; + rgba[RCOMP] = UBYTE_TO_CHAN( ((s >> 10) & 0xf8) * 255 / 0xf8 ); + rgba[GCOMP] = UBYTE_TO_CHAN( ((s >> 5) & 0xf8) * 255 / 0xf8 ); + rgba[BCOMP] = UBYTE_TO_CHAN( ((s ) & 0xf8) * 255 / 0xf8 ); + rgba[ACOMP] = CHAN_MAX; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_3d_texel_f_X1R5G5B5( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLfloat *texel ) +{ + const GLushort *src = USHORT_SRC( texImage, i, j, k ); + GLushort s = *src; + texel[RCOMP] = UBYTE_TO_FLOAT( ((s >> 10) & 0xf8) * 255 / 0xf8 ); + texel[GCOMP] = UBYTE_TO_FLOAT( ((s >> 5) & 0xf8) * 255 / 0xf8 ); + texel[BCOMP] = UBYTE_TO_FLOAT( ((s ) & 0xf8) * 255 / 0xf8 ); + texel[ACOMP] = 1.f; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_3d_texel_X4R4G4B4( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *texel ) +{ + const GLushort *src = USHORT_SRC( texImage, i, j, k ); + GLchan *rgba = (GLchan *) texel; GLushort s = *src; + rgba[RCOMP] = UBYTE_TO_CHAN( ((s >> 8) & 0xf) * 255 / 0xf ); + rgba[GCOMP] = UBYTE_TO_CHAN( ((s >> 4) & 0xf) * 255 / 0xf ); + rgba[BCOMP] = UBYTE_TO_CHAN( ((s ) & 0xf) * 255 / 0xf ); + rgba[ACOMP] = CHAN_MAX; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_3d_texel_f_X4R4G4B4( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLfloat *texel ) +{ + const GLushort *src = USHORT_SRC( texImage, i, j, k ); + GLushort s = *src; + texel[RCOMP] = UBYTE_TO_FLOAT( ((s >> 8) & 0xf) * 255 / 0xf ); + texel[GCOMP] = UBYTE_TO_FLOAT( ((s >> 4) & 0xf) * 255 / 0xf ); + texel[BCOMP] = UBYTE_TO_FLOAT( ((s ) & 0xf) * 255 / 0xf ); + texel[ACOMP] = 1.f; +} + +//--------------------------------------------------------------------------- + +#undef CHAN_SRC +#undef UBYTE_SRC +#undef USHORT_SRC +#undef FLOAT_SRC + +//--------------------------------------------------------------------------- +// Direct3D texture formats that have no Mesa equivalent +//--------------------------------------------------------------------------- + +const struct gl_texture_format _gld_texformat_X8R8G8B8 = { + MESA_FORMAT_ARGB8888, /* MesaFormat */ + GL_RGBA, /* BaseFormat */ + GL_UNSIGNED_NORMALIZED_ARB, /* DataType */ + 8, /* RedBits */ + 8, /* GreenBits */ + 8, /* BlueBits */ + 0, /* AlphaBits */ + 0, /* LuminanceBits */ + 0, /* IntensityBits */ + 0, /* IndexBits */ + 0, /* DepthBits */ + 4, /* TexelBytes */ + _mesa_texstore_argb8888, /* StoreTexImageFunc */ + gld_fetch_1d_texel_X8R8G8B8, /* FetchTexel1D */ + gld_fetch_2d_texel_X8R8G8B8, /* FetchTexel2D */ + gld_fetch_3d_texel_X8R8G8B8, /* FetchTexel3D */ + gld_fetch_1d_texel_f_X8R8G8B8, /* FetchTexel1Df */ + gld_fetch_2d_texel_f_X8R8G8B8, /* FetchTexel2Df */ + gld_fetch_3d_texel_f_X8R8G8B8, /* FetchTexel3Df */ +}; + +const struct gl_texture_format _gld_texformat_X1R5G5B5 = { + MESA_FORMAT_ARGB1555, /* MesaFormat */ + GL_RGBA, /* BaseFormat */ + GL_UNSIGNED_NORMALIZED_ARB, /* DataType */ + 5, /* RedBits */ + 5, /* GreenBits */ + 5, /* BlueBits */ + 0, /* AlphaBits */ + 0, /* LuminanceBits */ + 0, /* IntensityBits */ + 0, /* IndexBits */ + 0, /* DepthBits */ + 2, /* TexelBytes */ + _mesa_texstore_argb1555, /* StoreTexImageFunc */ + gld_fetch_1d_texel_X1R5G5B5, /* FetchTexel1D */ + gld_fetch_2d_texel_X1R5G5B5, /* FetchTexel2D */ + gld_fetch_3d_texel_X1R5G5B5, /* FetchTexel3D */ + gld_fetch_1d_texel_f_X1R5G5B5, /* FetchTexel1Df */ + gld_fetch_2d_texel_f_X1R5G5B5, /* FetchTexel2Df */ + gld_fetch_3d_texel_f_X1R5G5B5, /* FetchTexel3Df */ +}; + +const struct gl_texture_format _gld_texformat_X4R4G4B4 = { + MESA_FORMAT_ARGB4444, /* MesaFormat */ + GL_RGBA, /* BaseFormat */ + GL_UNSIGNED_NORMALIZED_ARB, /* DataType */ + 4, /* RedBits */ + 4, /* GreenBits */ + 4, /* BlueBits */ + 0, /* AlphaBits */ + 0, /* LuminanceBits */ + 0, /* IntensityBits */ + 0, /* IndexBits */ + 0, /* DepthBits */ + 2, /* TexelBytes */ + _mesa_texstore_argb4444, /* StoreTexImageFunc */ + gld_fetch_1d_texel_X4R4G4B4, /* FetchTexel1D */ + gld_fetch_2d_texel_X4R4G4B4, /* FetchTexel2D */ + gld_fetch_3d_texel_X4R4G4B4, /* FetchTexel3D */ + gld_fetch_1d_texel_f_X4R4G4B4, /* FetchTexel1Df */ + gld_fetch_2d_texel_f_X4R4G4B4, /* FetchTexel2Df */ + gld_fetch_3d_texel_f_X4R4G4B4, /* FetchTexel3Df */ +}; + +//--------------------------------------------------------------------------- +// Texture unit constants +//--------------------------------------------------------------------------- + +// List of possible combinations of texture environments. +// Example: GLD_TEXENV_MODULATE_RGBA means +// GL_MODULATE, GL_RGBA base internal format. +#define GLD_TEXENV_DECAL_RGB 0 +#define GLD_TEXENV_DECAL_RGBA 1 +#define GLD_TEXENV_DECAL_ALPHA 2 +#define GLD_TEXENV_REPLACE_RGB 3 +#define GLD_TEXENV_REPLACE_RGBA 4 +#define GLD_TEXENV_REPLACE_ALPHA 5 +#define GLD_TEXENV_MODULATE_RGB 6 +#define GLD_TEXENV_MODULATE_RGBA 7 +#define GLD_TEXENV_MODULATE_ALPHA 8 +#define GLD_TEXENV_BLEND_RGB 9 +#define GLD_TEXENV_BLEND_RGBA 10 +#define GLD_TEXENV_BLEND_ALPHA 11 +#define GLD_TEXENV_ADD_RGB 12 +#define GLD_TEXENV_ADD_RGBA 13 +#define GLD_TEXENV_ADD_ALPHA 14 + +// Per-stage (i.e. per-unit) texture environment +typedef struct { + DWORD ColorArg1; // Colour argument 1 + D3DTEXTUREOP ColorOp; // Colour operation + DWORD ColorArg2; // Colour argument 2 + DWORD AlphaArg1; // Alpha argument 1 + D3DTEXTUREOP AlphaOp; // Alpha operation + DWORD AlphaArg2; // Alpha argument 2 +} GLD_texenv; + +// TODO: Do we really need to set ARG1 and ARG2 every time? +// They seem to always be TEXTURE and CURRENT respectively. + +// C = Colour out +// A = Alpha out +// Ct = Colour from Texture +// Cf = Colour from fragment (diffuse) +// At = Alpha from Texture +// Af = Alpha from fragment (diffuse) +// Cc = GL_TEXTURE_ENV_COLOUR (GL_BLEND) +const GLD_texenv gldTexEnv[] = { + // DECAL_RGB: C=Ct, A=Af + {D3DTA_TEXTURE, D3DTOP_SELECTARG1, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT}, + // DECAL_RGBA: C=Cf(1-At)+CtAt, A=Af + {D3DTA_TEXTURE, D3DTOP_BLENDTEXTUREALPHA, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT}, + // DECAL_ALPHA: use DECAL_RGB + {D3DTA_TEXTURE, D3DTOP_SELECTARG1, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT}, + + // REPLACE_RGB: C=Ct, A=Af + {D3DTA_TEXTURE, D3DTOP_SELECTARG1, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT}, + // REPLACE_RGBA: C=Ct, A=At + {D3DTA_TEXTURE, D3DTOP_SELECTARG1, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_SELECTARG1, D3DTA_CURRENT}, + // REPLACE_ALPHA: C=Cf, A=At + {D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_SELECTARG1, D3DTA_CURRENT}, + + // MODULATE_RGB: C=CfCt, A=Af + {D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT}, + // MODULATE_RGBA: C=CfCt, A=AfAt + {D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT}, + // MODULATE_ALPHA: C=Cf, A=AfAt + {D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT}, + + // BLEND_RGB: C=Cf(1-Ct)+CcCt, A=Af + {D3DTA_TEXTURE, D3DTOP_LERP, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT}, + // BLEND_RGBA: C=Cf(1-Ct)+CcCt, A=AfAt + {D3DTA_TEXTURE, D3DTOP_LERP, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT}, + // BLEND_ALPHA: C=Cf, A=AfAt + {D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT}, + + // ADD_RGB: C=Cf+Ct, A=Af + {D3DTA_TEXTURE, D3DTOP_ADD, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT}, + // ADD_RGBA: C=Cf+Ct, A=AfAt + {D3DTA_TEXTURE, D3DTOP_ADD, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT}, + // ADD_ALPHA: C=Cf, A=AfAt + {D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT}, +}; + +//--------------------------------------------------------------------------- + +D3DTEXTUREADDRESS _gldConvertWrap( + GLenum wrap) +{ + return (wrap == GL_CLAMP) ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP; +} + +//--------------------------------------------------------------------------- + +D3DTEXTUREFILTERTYPE _gldConvertMagFilter( + GLenum magfilter) +{ + return (magfilter == GL_LINEAR) ? D3DTEXF_LINEAR : D3DTEXF_POINT; +} + +//--------------------------------------------------------------------------- + +void _gldConvertMinFilter( + GLenum minfilter, + D3DTEXTUREFILTERTYPE *min_filter, + D3DTEXTUREFILTERTYPE *mip_filter) +{ + switch (minfilter) { + case GL_NEAREST: + *min_filter = D3DTEXF_POINT; + *mip_filter = D3DTEXF_NONE; + break; + case GL_LINEAR: + *min_filter = D3DTEXF_LINEAR; + *mip_filter = D3DTEXF_NONE; + break; + case GL_NEAREST_MIPMAP_NEAREST: + *min_filter = D3DTEXF_POINT; + *mip_filter = D3DTEXF_POINT; + break; + case GL_LINEAR_MIPMAP_NEAREST: + *min_filter = D3DTEXF_LINEAR; + *mip_filter = D3DTEXF_POINT; + break; + case GL_NEAREST_MIPMAP_LINEAR: + *min_filter = D3DTEXF_POINT; + *mip_filter = D3DTEXF_LINEAR; + break; + case GL_LINEAR_MIPMAP_LINEAR: + *min_filter = D3DTEXF_LINEAR; + *mip_filter = D3DTEXF_LINEAR; + break; + } +} + +//--------------------------------------------------------------------------- + +D3DFORMAT _gldGLFormatToD3DFormat( + GLenum internalFormat) +{ + switch (internalFormat) { + case GL_INTENSITY: + case GL_INTENSITY4: + case GL_INTENSITY8: + case GL_INTENSITY12: + case GL_INTENSITY16: + // LUNIMANCE != INTENSITY, but D3D doesn't have I8 textures + return D3DFMT_L8; + case 1: + case GL_LUMINANCE: + case GL_LUMINANCE4: + case GL_LUMINANCE8: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + return D3DFMT_L8; + case GL_ALPHA: + case GL_ALPHA4: + case GL_ALPHA8: + case GL_ALPHA12: + case GL_ALPHA16: + return D3DFMT_A8; + case GL_COLOR_INDEX: + case GL_COLOR_INDEX1_EXT: + case GL_COLOR_INDEX2_EXT: + case GL_COLOR_INDEX4_EXT: + case GL_COLOR_INDEX8_EXT: + case GL_COLOR_INDEX12_EXT: + case GL_COLOR_INDEX16_EXT: + return D3DFMT_X8R8G8B8; + case 2: + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE4_ALPHA4: + case GL_LUMINANCE6_ALPHA2: + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE12_ALPHA4: + case GL_LUMINANCE12_ALPHA12: + case GL_LUMINANCE16_ALPHA16: + return D3DFMT_A8L8; + case GL_R3_G3_B2: + // TODO: Mesa does not support RGB332 internally + return D3DFMT_X4R4G4B4; //D3DFMT_R3G3B2; + case GL_RGB4: + return D3DFMT_X4R4G4B4; + case GL_RGB5: + return D3DFMT_X1R5G5B5; + case 3: + case GL_RGB: + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + return D3DFMT_R8G8B8; + case GL_RGBA4: + return D3DFMT_A4R4G4B4; + case 4: + case GL_RGBA: + case GL_RGBA2: + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + return D3DFMT_A8R8G8B8; + case GL_RGB5_A1: + return D3DFMT_A1R5G5B5; + } + + // Return an acceptable default + return D3DFMT_A8R8G8B8; +} + +//--------------------------------------------------------------------------- + +GLenum _gldDecodeBaseFormat( + IDirect3DTexture8 *pTex) +{ + // Examine Direct3D texture and return base OpenGL internal texture format + // NOTE: We can't use any base format info from Mesa because D3D might have + // used a different texture format when we used D3DXCreateTexture(). + + // Base internal format is one of (Red Book p355): + // GL_ALPHA, + // GL_LUMINANCE, + // GL_LUMINANCE_ALPHA, + // GL_INTENSITY, + // GL_RGB, + // GL_RGBA + + // NOTE: INTENSITY not used (not supported by Direct3D) + // LUMINANCE has same texture functions as RGB + // LUMINANCE_ALPHA has same texture functions as RGBA + + // TODO: cache format instead of using GetLevelDesc() + D3DSURFACE_DESC desc; + _GLD_DX8_TEX(GetLevelDesc(pTex, 0, &desc)); + + switch (desc.Format) { + case D3DFMT_R8G8B8: + case D3DFMT_X8R8G8B8: + case D3DFMT_R5G6B5: + case D3DFMT_X1R5G5B5: + case D3DFMT_R3G3B2: + case D3DFMT_X4R4G4B4: + case D3DFMT_P8: + case D3DFMT_L8: + return GL_RGB; + case D3DFMT_A8R8G8B8: + case D3DFMT_A1R5G5B5: + case D3DFMT_A4R4G4B4: + case D3DFMT_A8R3G3B2: + case D3DFMT_A8P8: + case D3DFMT_A8L8: + case D3DFMT_A4L4: + return GL_RGBA; + case D3DFMT_A8: + return GL_ALPHA; + // Compressed texture formats. Need to check these... + case D3DFMT_DXT1: + return GL_RGBA; + case D3DFMT_DXT2: + return GL_RGB; + case D3DFMT_DXT3: + return GL_RGBA; + case D3DFMT_DXT4: + return GL_RGB; + case D3DFMT_DXT5: + return GL_RGBA; + } + + // Fell through. Return arbitary default. + return GL_RGBA; +} + +//--------------------------------------------------------------------------- + +const struct gl_texture_format* _gldMesaFormatForD3DFormat( + D3DFORMAT d3dfmt) +{ + switch (d3dfmt) { + case D3DFMT_A8R8G8B8: + return &_mesa_texformat_argb8888; + case D3DFMT_R8G8B8: + return &_mesa_texformat_rgb888; + case D3DFMT_R5G6B5: + return &_mesa_texformat_rgb565; + case D3DFMT_A4R4G4B4: + return &_mesa_texformat_argb4444; + case D3DFMT_A1R5G5B5: + return &_mesa_texformat_argb1555; + case D3DFMT_A8L8: + return &_mesa_texformat_al88; + case D3DFMT_R3G3B2: + return &_mesa_texformat_rgb332; + case D3DFMT_A8: + return &_mesa_texformat_a8; + case D3DFMT_L8: + return &_mesa_texformat_l8; + case D3DFMT_X8R8G8B8: + return &_gld_texformat_X8R8G8B8; + case D3DFMT_X1R5G5B5: + return &_gld_texformat_X1R5G5B5; + case D3DFMT_X4R4G4B4: + return &_gld_texformat_X4R4G4B4; + } + + // If we reach here then we've made an error somewhere else + // by allowing a format that is not supported. + assert(0); + + return NULL; // Shut up compiler warning +} + +//--------------------------------------------------------------------------- +// Copy* functions +//--------------------------------------------------------------------------- + +void gldCopyTexImage1D_DX8( + GLcontext *ctx, + GLenum target, GLint level, + GLenum internalFormat, + GLint x, GLint y, + GLsizei width, GLint border ) +{ + // TODO +} + +//--------------------------------------------------------------------------- + +void gldCopyTexImage2D_DX8( + GLcontext *ctx, + GLenum target, + GLint level, + GLenum internalFormat, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLint border) +{ + // TODO +} + +//--------------------------------------------------------------------------- + +void gldCopyTexSubImage1D_DX8( + GLcontext *ctx, + GLenum target, GLint level, + GLint xoffset, GLint x, GLint y, GLsizei width ) +{ + // TODO +} + +//--------------------------------------------------------------------------- + +void gldCopyTexSubImage2D_DX8( + GLcontext *ctx, + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height) +{ + // TODO +} + +//--------------------------------------------------------------------------- + +void gldCopyTexSubImage3D_DX8( + GLcontext *ctx, + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height ) +{ + // TODO ? +} + +//--------------------------------------------------------------------------- +// Bitmap/Pixel functions +//--------------------------------------------------------------------------- + +#define GLD_FLIP_Y(y) (gldCtx->dwHeight - (y)) + +#define _GLD_FVF_IMAGE (D3DFVF_XYZRHW | D3DFVF_TEX1) + +typedef struct { + FLOAT x, y; // 2D raster coords + FLOAT z; // depth value + FLOAT rhw; // reciprocal homogenous W (always 1.0f) + FLOAT tu, tv; // texture coords +} _GLD_IMAGE_VERTEX; + +//--------------------------------------------------------------------------- + +HRESULT _gldDrawPixels( + GLcontext *ctx, + BOOL bChromakey, // Alpha test for glBitmap() images + GLint x, // GL x position + GLint y, // GL y position (needs flipping) + GLsizei width, // Width of input image + GLsizei height, // Height of input image + IDirect3DSurface8 *pImage) +{ + // + // Draw input image as texture implementing PixelZoom and clipping. + // Any fragment operations currently enabled will be used. + // + + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx); + + IDirect3DTexture8 *pTexture; + D3DSURFACE_DESC d3dsd; + IDirect3DSurface8 *pSurface; + _GLD_IMAGE_VERTEX v[4]; + HRESULT hr; + + float ZoomWidth, ZoomHeight; + float ScaleWidth, ScaleHeight; + + // Create a texture to hold image + hr = D3DXCreateTexture( + gld->pDev, + width, height, + 1, // miplevels + 0, // usage + D3DFMT_A8R8G8B8, // format + D3DPOOL_MANAGED, // pool + &pTexture); + if (FAILED(hr)) + return hr; + + hr = IDirect3DTexture8_GetSurfaceLevel(pTexture, 0, &pSurface); + if (FAILED(hr)) { + IDirect3DTexture8_Release(pTexture); + return hr; + } + + // Copy image into texture + hr = D3DXLoadSurfaceFromSurface( + pSurface, NULL, NULL, // Dest surface + pImage, NULL, NULL, // Src surface + D3DX_FILTER_NONE, + 0); + IDirect3DSurface8_Release(pSurface); + if (FAILED(hr)) { + IDirect3DTexture8_Release(pTexture); + return hr; + } + + // + // Set up the quad like this (ascii-art ahead!) + // + // 3--2 + // | | + // 0--1 + // + // + + // Set depth + v[0].z = v[1].z = v[2].z = v[3].z = ctx->Current.RasterPos[2]; + // Set Reciprocal Homogenous W + v[0].rhw = v[1].rhw = v[2].rhw = v[3].rhw = 1.0f; + + // Set texcoords + // Examine texture size - if different to input width and height + // then we'll need to munge the texcoords to fit. + IDirect3DTexture8_GetLevelDesc(pTexture, 0, &d3dsd); + ScaleWidth = (float)width / (float)d3dsd.Width; + ScaleHeight = (float)height / (float)d3dsd.Height; + v[0].tu = 0.0f; v[0].tv = 0.0f; + v[1].tu = ScaleWidth; v[1].tv = 0.0f; + v[2].tu = ScaleWidth; v[2].tv = ScaleHeight; + v[3].tu = 0.0f; v[3].tv = ScaleHeight; + + // Set raster positions + ZoomWidth = (float)width * ctx->Pixel.ZoomX; + ZoomHeight = (float)height * ctx->Pixel.ZoomY; + + v[0].x = x; v[0].y = GLD_FLIP_Y(y); + v[1].x = x+ZoomWidth; v[1].y = GLD_FLIP_Y(y); + v[2].x = x+ZoomWidth; v[2].y = GLD_FLIP_Y(y+ZoomHeight); + v[3].x = x; v[3].y = GLD_FLIP_Y(y+ZoomHeight); + + // Draw image with full HW acceleration + // NOTE: Be nice to use a State Block for all this state... + IDirect3DDevice8_SetTexture(gld->pDev, 0, pTexture); + IDirect3DDevice8_SetRenderState(gld->pDev, D3DRS_CULLMODE, D3DCULL_NONE); + IDirect3DDevice8_SetRenderState(gld->pDev, D3DRS_CLIPPING, TRUE); + IDirect3DDevice8_SetTextureStageState(gld->pDev, 0, D3DTSS_MINFILTER, D3DTEXF_POINT); + IDirect3DDevice8_SetTextureStageState(gld->pDev, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT); + IDirect3DDevice8_SetTextureStageState(gld->pDev, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT); + IDirect3DDevice8_SetTextureStageState(gld->pDev, 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); + IDirect3DDevice8_SetTextureStageState(gld->pDev, 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); + IDirect3DDevice8_SetTextureStageState(gld->pDev, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + IDirect3DDevice8_SetTextureStageState(gld->pDev, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + IDirect3DDevice8_SetTextureStageState(gld->pDev, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + IDirect3DDevice8_SetTextureStageState(gld->pDev, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + IDirect3DDevice8_SetTextureStageState(gld->pDev, 1, D3DTSS_COLOROP, D3DTOP_DISABLE); + IDirect3DDevice8_SetTextureStageState(gld->pDev, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + IDirect3DDevice8_SetVertexShader(gld->pDev, _GLD_FVF_IMAGE); + + // + // Emulate Chromakey with an Alpha Test. + // [Alpha Test is more widely supported anyway] + // + if (bChromakey) { + // Switch on alpha testing + IDirect3DDevice8_SetRenderState(gld->pDev, D3DRS_ALPHATESTENABLE, TRUE); + // Fragment passes is alpha is greater than reference value + IDirect3DDevice8_SetRenderState(gld->pDev, D3DRS_ALPHAFUNC, D3DCMP_GREATER); + // Set alpha reference value between Bitmap alpha values of + // zero (transparent) and one (opaque). + IDirect3DDevice8_SetRenderState(gld->pDev, D3DRS_ALPHAREF, 0x7f); + } + + IDirect3DDevice8_DrawPrimitiveUP(gld->pDev, D3DPT_TRIANGLEFAN, 2, &v, sizeof(_GLD_IMAGE_VERTEX)); + + // Release texture + IDirect3DDevice8_SetTexture(gld->pDev, 0, NULL); + IDirect3DTexture8_Release(pTexture); + + // Reset state to before we messed it up + FLUSH_VERTICES(ctx, _NEW_ALL); + + return S_OK; +} + +//--------------------------------------------------------------------------- + +void gld_DrawPixels_DX8( + GLcontext *ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid *pixels ) +{ + GLD_context *gldCtx; + GLD_driver_dx8 *gld; + + IDirect3DSurface8 *pImage; + HRESULT hr; + D3DLOCKED_RECT d3dLockedRect; + + const struct gl_texture_format *MesaFormat; + + gldCtx = GLD_GET_CONTEXT(ctx); + gld = GLD_GET_DX8_DRIVER(gldCtx); + + hr = IDirect3DDevice8_CreateImageSurface( + gld->pDev, + width, + height, + D3DFMT_A8R8G8B8, + &pImage); + if (FAILED(hr)) { + return; + } + + // + // Use Mesa to fill in image + // + + // Lock all of surface + hr = IDirect3DSurface8_LockRect(pImage, &d3dLockedRect, NULL, 0); + if (FAILED(hr)) { + IDirect3DSurface8_Release(pImage); + return; + } + + MesaFormat = _mesa_choose_tex_format(ctx, format, format, type); + + // unpack image, apply transfer ops and store directly in texture + MesaFormat->StoreImage( + ctx, + 2, + GL_RGBA, + &_mesa_texformat_argb8888, + d3dLockedRect.pBits, + width, height, 1, 0, 0, 0, + d3dLockedRect.Pitch, + 0, /* dstImageStride */ + format, type, pixels, unpack); + + IDirect3DSurface8_UnlockRect(pImage); + + _gldDrawPixels(ctx, FALSE, x, y, width, height, pImage); + + IDirect3DSurface8_Release(pImage); +} + +//--------------------------------------------------------------------------- + +void gld_ReadPixels_DX8( + GLcontext *ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *pack, + GLvoid *dest) +{ + + GLD_context *gldCtx; + GLD_driver_dx8 *gld; + + IDirect3DSurface8 *pBackbuffer = NULL; + IDirect3DSurface8 *pNativeImage = NULL; + IDirect3DSurface8 *pCanonicalImage = NULL; + + D3DSURFACE_DESC d3dsd; + RECT rcSrc; // Source rect + POINT ptDst; // Dest point + HRESULT hr; + D3DLOCKED_RECT d3dLockedRect; + struct gl_pixelstore_attrib srcPacking; + int i; + GLint DstRowStride; + const struct gl_texture_format *MesaFormat; + + switch (format) { + case GL_STENCIL_INDEX: + case GL_DEPTH_COMPONENT: + return; + } + + MesaFormat = _mesa_choose_tex_format(ctx, format, format, type); + DstRowStride = _mesa_image_row_stride(pack, width, format, type); + + gldCtx = GLD_GET_CONTEXT(ctx); + gld = GLD_GET_DX8_DRIVER(gldCtx); + + // Get backbuffer + hr = IDirect3DDevice8_GetBackBuffer( + gld->pDev, + 0, // First backbuffer + D3DBACKBUFFER_TYPE_MONO, + &pBackbuffer); + if (FAILED(hr)) + return; + + // Get backbuffer description + hr = IDirect3DSurface8_GetDesc(pBackbuffer, &d3dsd); + if (FAILED(hr)) { + goto gld_ReadPixels_DX8_return; + } + + // Create a surface compatible with backbuffer + hr = IDirect3DDevice8_CreateImageSurface( + gld->pDev, + width, + height, + d3dsd.Format, + &pNativeImage); + if (FAILED(hr)) { + goto gld_ReadPixels_DX8_return; + } + + // Compute source rect and dest point + SetRect(&rcSrc, 0, 0, width, height); + OffsetRect(&rcSrc, x, GLD_FLIP_HEIGHT(y, height)); + ptDst.x = ptDst.y = 0; + + // Get source pixels. + // + // This intermediate surface ensure that we can use CopyRects() + // instead of relying on D3DXLoadSurfaceFromSurface(), which may + // try and lock the backbuffer. This way seems safer. + // + hr = IDirect3DDevice8_CopyRects( + gld->pDev, + pBackbuffer, + &rcSrc, + 1, + pNativeImage, + &ptDst); + if (FAILED(hr)) { + goto gld_ReadPixels_DX8_return; + } + + // Create an RGBA8888 surface + hr = IDirect3DDevice8_CreateImageSurface( + gld->pDev, + width, + height, + D3DFMT_A8R8G8B8, + &pCanonicalImage); + if (FAILED(hr)) { + goto gld_ReadPixels_DX8_return; + } + + // Convert to RGBA8888 + hr = D3DXLoadSurfaceFromSurface( + pCanonicalImage, // Dest surface + NULL, NULL, // Dest palette, RECT + pNativeImage, // Src surface + NULL, NULL, // Src palette, RECT + D3DX_FILTER_NONE, // Filter + 0); // Colourkey + if (FAILED(hr)) { + goto gld_ReadPixels_DX8_return; + } + + srcPacking.Alignment = 1; + srcPacking.ImageHeight = height; + srcPacking.LsbFirst = GL_FALSE; + srcPacking.RowLength = 0; + srcPacking.SkipImages = 0; + srcPacking.SkipPixels = 0; + srcPacking.SkipRows = 0; + srcPacking.SwapBytes = GL_FALSE; + + // Lock all of image + hr = IDirect3DSurface8_LockRect(pCanonicalImage, &d3dLockedRect, NULL, 0); + if (FAILED(hr)) { + goto gld_ReadPixels_DX8_return; + } + + // We need to flip the data. Yuck. + // Perhaps Mesa has a span packer we can use in future... + for (i=0; iStoreImage( + ctx, + 2, + GL_RGBA, // base format + MesaFormat, // dst format + pDestRow, // dest addr + width, 1, 1, 0, 0, 0, // src x,y,z & dst offsets x,y,z + DstRowStride, // dst row stride + 0, // dstImageStride + GL_BGRA, // src format + GL_UNSIGNED_BYTE, // src type + pSrcRow, // src addr + &srcPacking); // packing params of source image + } + + IDirect3DSurface8_UnlockRect(pCanonicalImage); + +gld_ReadPixels_DX8_return: + SAFE_RELEASE_SURFACE8(pCanonicalImage); + SAFE_RELEASE_SURFACE8(pNativeImage); + SAFE_RELEASE_SURFACE8(pBackbuffer); +} + +//--------------------------------------------------------------------------- + +void gld_CopyPixels_DX8( + GLcontext *ctx, + GLint srcx, + GLint srcy, + GLsizei width, + GLsizei height, + GLint dstx, + GLint dsty, + GLenum type) +{ + // + // NOTE: Not allowed to copy vidmem to vidmem! + // Therefore we use an intermediate image surface. + // + + GLD_context *gldCtx; + GLD_driver_dx8 *gld; + + IDirect3DSurface8 *pBackbuffer; + D3DSURFACE_DESC d3dsd; + IDirect3DSurface8 *pImage; + RECT rcSrc; // Source rect + POINT ptDst; // Dest point + HRESULT hr; + + // Only backbuffer + if (type != GL_COLOR) + return; + + gldCtx = GLD_GET_CONTEXT(ctx); + gld = GLD_GET_DX8_DRIVER(gldCtx); + + // Get backbuffer + hr = IDirect3DDevice8_GetBackBuffer( + gld->pDev, + 0, // First backbuffer + D3DBACKBUFFER_TYPE_MONO, + &pBackbuffer); + if (FAILED(hr)) + return; + + // Get backbuffer description + hr = IDirect3DSurface8_GetDesc(pBackbuffer, &d3dsd); + if (FAILED(hr)) { + IDirect3DSurface8_Release(pBackbuffer); + return; + } + + // Create a surface compatible with backbuffer + hr = IDirect3DDevice8_CreateImageSurface( + gld->pDev, + width, + height, + d3dsd.Format, + &pImage); + if (FAILED(hr)) { + IDirect3DSurface8_Release(pBackbuffer); + return; + } + + // Compute source rect and dest point + SetRect(&rcSrc, 0, 0, width, height); + OffsetRect(&rcSrc, srcx, GLD_FLIP_HEIGHT(srcy, height)); + ptDst.x = ptDst.y = 0; + + // Get source pixels + hr = IDirect3DDevice8_CopyRects( + gld->pDev, + pBackbuffer, + &rcSrc, + 1, + pImage, + &ptDst); + IDirect3DSurface8_Release(pBackbuffer); + if (FAILED(hr)) { + IDirect3DSurface8_Release(pImage); + return; + } + + _gldDrawPixels(ctx, FALSE, dstx, dsty, width, height, pImage); + + IDirect3DSurface8_Release(pImage); +} + +//--------------------------------------------------------------------------- + +void gld_Bitmap_DX8( + GLcontext *ctx, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + const struct gl_pixelstore_attrib *unpack, + const GLubyte *bitmap) +{ + GLD_context *gldCtx; + GLD_driver_dx8 *gld; + + IDirect3DSurface8 *pImage; + HRESULT hr; + D3DLOCKED_RECT d3dLockedRect; + BYTE *pTempBitmap; + D3DCOLOR clBitmapOne, clBitmapZero; + D3DCOLOR *pBits; + const GLubyte *src; + int i, j, k; + + gldCtx = GLD_GET_CONTEXT(ctx); + gld = GLD_GET_DX8_DRIVER(gldCtx); + + clBitmapZero = D3DCOLOR_RGBA(0,0,0,0); // NOTE: Alpha is Zero + clBitmapOne = D3DCOLOR_COLORVALUE( + ctx->Current.RasterColor[0], + ctx->Current.RasterColor[1], + ctx->Current.RasterColor[2], + 1.0f); // NOTE: Alpha is One + + hr = IDirect3DDevice8_CreateImageSurface( + gld->pDev, + width, + height, + D3DFMT_A8R8G8B8, + &pImage); + if (FAILED(hr)) { + return; + } + + // Lock all of surface + hr = IDirect3DSurface8_LockRect(pImage, &d3dLockedRect, NULL, 0); + if (FAILED(hr)) { + IDirect3DSurface8_Release(pImage); + return; + } + + pTempBitmap = _mesa_unpack_bitmap(width, height, bitmap, unpack); + if (pTempBitmap == NULL) { + IDirect3DSurface8_Release(pImage); + return; + } + + pBits = (D3DCOLOR*)d3dLockedRect.pBits; + + for (i=0; iDefaultPacking, pTempBitmap, width, height, GL_COLOR_INDEX, GL_BITMAP, + 0, i, 0); + for (j=0; j<(width>>3); j++) { + byte = *src++; + for (k=0; k<8; k++) { + *pBits++ = (byte & 128) ? clBitmapOne : clBitmapZero; + byte <<= 1; + } + } + // Fill remaining bits from bitmap + if (width & 7) { + byte = *src; + for (k=0; k<(width & 7); k++) { + *pBits++ = (byte & 128) ? clBitmapOne : clBitmapZero; + byte <<= 1; + } + } + } + + FREE(pTempBitmap); + +/* + // unpack image, apply transfer ops and store directly in texture + texImage->TexFormat->StoreImage( + ctx, + 2, + GL_BITMAP, + &_mesa_texformat_argb8888, + d3dLockedRect.pBits, + width, height, 1, 0, 0, 0, + d3dLockedRect.Pitch, + 0, // dstImageStride + GL_BITMAP, GL_COLOR_INDEX, bitmap, unpack); +*/ + IDirect3DSurface8_UnlockRect(pImage); + + _gldDrawPixels(ctx, TRUE, x, y, width, height, pImage); + + IDirect3DSurface8_Release(pImage); +} + +//--------------------------------------------------------------------------- +// Texture functions +//--------------------------------------------------------------------------- + +void _gldAllocateTexture( + GLcontext *ctx, + struct gl_texture_object *tObj, + struct gl_texture_image *texImage) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx); + + IDirect3DTexture8 *pTex; + D3DFORMAT d3dFormat; + + if (!tObj || !texImage) + return; + + pTex = (IDirect3DTexture8*)tObj->DriverData; + if (pTex) { + // Decide whether we can keep existing D3D texture + // by examining top-level surface. + D3DSURFACE_DESC d3dsd; + _GLD_DX8_TEX(GetLevelDesc(pTex, 0, &d3dsd)); + // Release existing texture if not compatible + if ((d3dsd.Width == texImage->Width) || + (d3dsd.Height == texImage->Height)) + { + return; // Keep the existing texture + } + tObj->DriverData = NULL; + _GLD_DX8_TEX(Release(pTex)); + } + + d3dFormat = _gldGLFormatToD3DFormat(texImage->IntFormat); + D3DXCreateTexture( + gld->pDev, + texImage->Width, + texImage->Height, + // TODO: Re-evaluate mipmapping + (glb.bUseMipmaps) ? D3DX_DEFAULT : 1, + 0, // Usage + d3dFormat, + D3DPOOL_MANAGED, + &pTex); + tObj->DriverData = pTex; +} + +//--------------------------------------------------------------------------- + +const struct gl_texture_format* gld_ChooseTextureFormat_DX8( + GLcontext *ctx, + GLint internalFormat, + GLenum srcFormat, + GLenum srcType) +{ + // [Based on mesa_choose_tex_format()] + // + // We will choose only texture formats that are supported + // by Direct3D. If the hardware doesn't support a particular + // texture format, then the D3DX texture calls that we use + // will automatically use a HW supported format. + // + // The most critical aim is to reduce copying; if we can use + // texture-image data directly then it will be a big performance assist. + // + + switch (internalFormat) { + case GL_INTENSITY: + case GL_INTENSITY4: + case GL_INTENSITY8: + case GL_INTENSITY12: + case GL_INTENSITY16: + return &_mesa_texformat_l8; // D3DFMT_L8 + case 1: + case GL_LUMINANCE: + case GL_LUMINANCE4: + case GL_LUMINANCE8: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + return &_mesa_texformat_l8; // D3DFMT_L8 + case GL_ALPHA: + case GL_ALPHA4: + case GL_ALPHA8: + case GL_ALPHA12: + case GL_ALPHA16: + return &_mesa_texformat_a8; // D3DFMT_A8 + case GL_COLOR_INDEX: + case GL_COLOR_INDEX1_EXT: + case GL_COLOR_INDEX2_EXT: + case GL_COLOR_INDEX4_EXT: + case GL_COLOR_INDEX8_EXT: + case GL_COLOR_INDEX12_EXT: + case GL_COLOR_INDEX16_EXT: + return &_mesa_texformat_rgb565; // D3DFMT_R5G6B5 + // Mesa will convert this for us later... + // return &_mesa_texformat_ci8; // D3DFMT_R5G6B5 + case 2: + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE4_ALPHA4: + case GL_LUMINANCE6_ALPHA2: + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE12_ALPHA4: + case GL_LUMINANCE12_ALPHA12: + case GL_LUMINANCE16_ALPHA16: + return &_mesa_texformat_al88; // D3DFMT_A8L8 + case GL_R3_G3_B2: + return &_mesa_texformat_rgb332; // D3DFMT_R3G3B2 + case GL_RGB4: + case GL_RGBA4: + case GL_RGBA2: + return &_mesa_texformat_argb4444; // D3DFMT_A4R4G4B4 + case 3: + case GL_RGB: + case GL_RGB5: + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + return &_mesa_texformat_rgb565; + case 4: + case GL_RGBA: + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + return &_mesa_texformat_argb8888; + case GL_RGB5_A1: + return &_mesa_texformat_argb1555; + default: + _mesa_problem(NULL, "unexpected format in fxDDChooseTextureFormat"); + return NULL; + } +} + +//--------------------------------------------------------------------------- + +/* +// Safer(?), slower version. +void gld_TexImage2D_DX8( + GLcontext *ctx, + GLenum target, + GLint level, + GLint internalFormat, + GLint width, + GLint height, + GLint border, + GLenum format, + GLenum type, + const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *tObj, + struct gl_texture_image *texImage) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx); + + IDirect3DTexture8 *pTex; + IDirect3DSurface8 *pSurface; + RECT rcSrcRect; + HRESULT hr; + GLint texelBytes = 4; + GLvoid *tempImage; + + if (!tObj || !texImage) + return; + + if (level == 0) { + _gldAllocateTexture(ctx, tObj, texImage); + } + + pTex = (IDirect3DTexture8*)tObj->DriverData; + if (!pTex) + return; // Texture has not been created + if (level >= IDirect3DTexture8_GetLevelCount(pTex)) + return; // Level does not exist + hr = IDirect3DTexture8_GetSurfaceLevel(pTex, level, &pSurface); + if (FAILED(hr)) + return; // Surface level doesn't exist (or just a plain error) + + tempImage = MALLOC(width * height * texelBytes); + if (!tempImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + IDirect3DSurface8_Release(pSurface); + return; + } + // unpack image, apply transfer ops and store in tempImage + texImage->TexFormat->StoreImage(ctx, 2, texImage->Format, + &_mesa_texformat_argb8888, // dest format + tempImage, + width, height, 1, 0, 0, 0, + width * texelBytes, + 0, // dstImageStride + format, type, pixels, packing); + + SetRect(&rcSrcRect, 0, 0, width, height); + D3DXLoadSurfaceFromMemory( + pSurface, + NULL, + NULL, + tempImage, + D3DFMT_A8R8G8B8, + width * texelBytes, + NULL, + &rcSrcRect, + D3DX_FILTER_NONE, + 0); + + FREE(tempImage); + IDirect3DSurface8_Release(pSurface); +} +*/ + +//--------------------------------------------------------------------------- + +// Faster, more efficient version. +// Copies subimage straight to dest texture +void gld_TexImage2D_DX8( + GLcontext *ctx, + GLenum target, + GLint level, + GLint internalFormat, + GLint width, + GLint height, + GLint border, + GLenum format, + GLenum type, + const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *tObj, + struct gl_texture_image *texImage) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx); + + IDirect3DTexture8 *pTex; + IDirect3DSurface8 *pSurface; + HRESULT hr; + D3DLOCKED_RECT d3dLockedRect; + D3DSURFACE_DESC d3dsd; + + if (!tObj || !texImage) + return; + + // GLQUAKE FIX + // Test for input alpha data with non-alpha internalformat + if (((internalFormat==3) || (internalFormat==GL_RGB)) && (format==GL_RGBA)) { + // Input format has alpha, but a non-alpha format has been requested. + texImage->IntFormat = GL_RGBA; + internalFormat = GL_RGBA; + } + + if (level == 0) { + _gldAllocateTexture(ctx, tObj, texImage); + } + + pTex = (IDirect3DTexture8*)tObj->DriverData; + if (!pTex) + return; // Texture has not been created + if (level >= IDirect3DTexture8_GetLevelCount(pTex)) + return; // Level does not exist + hr = IDirect3DTexture8_GetSurfaceLevel(pTex, level, &pSurface); + if (FAILED(hr)) + return; // Surface level doesn't exist (or just a plain error) + + IDirect3DSurface8_GetDesc(pSurface, &d3dsd); + + // Lock all of surface + hr = IDirect3DSurface8_LockRect(pSurface, &d3dLockedRect, NULL, 0); + if (FAILED(hr)) { + IDirect3DSurface8_Release(pSurface); + return; + } + + // unpack image, apply transfer ops and store directly in texture + texImage->TexFormat->StoreImage( + ctx, + 2, + texImage->Format, + _gldMesaFormatForD3DFormat(d3dsd.Format), + d3dLockedRect.pBits, + width, height, 1, 0, 0, 0, + d3dLockedRect.Pitch, + 0, // dstImageStride + format, type, pixels, packing); + + IDirect3DSurface8_UnlockRect(pSurface); + IDirect3DSurface8_Release(pSurface); +} + +//--------------------------------------------------------------------------- + +void gld_TexImage1D_DX8(GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint border, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) +{ + // A 1D texture is a 2D texture with a height of zero + gld_TexImage2D_DX8(ctx, target, level, internalFormat, width, 1, border, format, type, pixels, packing, texObj, texImage); +} + +//--------------------------------------------------------------------------- + +/* +void gld_TexSubImage2D( GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *tObj, + struct gl_texture_image *texImage ) +{ + GLD_GET_CONTEXT + IDirect3DTexture8 *pTex; + IDirect3DSurface8 *pSurface; + D3DFORMAT d3dFormat; + HRESULT hr; + GLint texelBytes = 4; + GLvoid *tempImage; + RECT rcSrcRect; + RECT rcDstRect; + + if (!tObj || !texImage) + return; + + pTex = (IDirect3DTexture8*)tObj->DriverData; + if (!pTex) + return; // Texture has not been created + if (level >= _GLD_DX8_TEX(GetLevelCount(pTex)) + return; // Level does not exist + hr = _GLD_DX8_TEX(GetSurfaceLevel(pTex, level, &pSurface); + if (FAILED(hr)) + return; // Surface level doesn't exist (or just a plain error) + + d3dFormat = _gldGLFormatToD3DFormat(texImage->Format); + tempImage = MALLOC(width * height * texelBytes); + if (!tempImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + IDirect3DSurface8_Release(pSurface); + return; + } + + // unpack image, apply transfer ops and store in tempImage + texImage->TexFormat->StoreImage(ctx, 2, texImage->Format, + &_mesa_texformat_argb8888, // dest format + tempImage, + width, height, 1, 0, 0, 0, + width * texelBytes, + 0, // dstImageStride + format, type, pixels, packing); + + // Source rectangle is whole of input image + SetRect(&rcSrcRect, 0, 0, width, height); + + // Dest rectangle must be offset to dest image + SetRect(&rcDstRect, 0, 0, width, height); + OffsetRect(&rcDstRect, xoffset, yoffset); + + D3DXLoadSurfaceFromMemory( + pSurface, + NULL, + &rcDstRect, + tempImage, + D3DFMT_A8R8G8B8, + width * texelBytes, + NULL, + &rcSrcRect, + D3DX_FILTER_NONE, + 0); + + FREE(tempImage); + IDirect3DSurface8_Release(pSurface); +} +*/ + +//--------------------------------------------------------------------------- + +// Faster, more efficient version. +// Copies subimage straight to dest texture +void gld_TexSubImage2D_DX8( GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *tObj, + struct gl_texture_image *texImage ) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx); + + IDirect3DTexture8 *pTex; + IDirect3DSurface8 *pSurface; + HRESULT hr; + RECT rcDstRect; + D3DLOCKED_RECT d3dLockedRect; + D3DSURFACE_DESC d3dsd; + + if (!tObj || !texImage) + return; + + pTex = (IDirect3DTexture8*)tObj->DriverData; + if (!pTex) + return; // Texture has not been created + if (level >= IDirect3DTexture8_GetLevelCount(pTex)) + return; // Level does not exist + hr = IDirect3DTexture8_GetSurfaceLevel(pTex, level, &pSurface); + if (FAILED(hr)) + return; // Surface level doesn't exist (or just a plain error) + + IDirect3DSurface8_GetDesc(pSurface, &d3dsd); + + // Dest rectangle must be offset to dest image + SetRect(&rcDstRect, 0, 0, width, height); + OffsetRect(&rcDstRect, xoffset, yoffset); + + // Lock sub-rect of surface + hr = IDirect3DSurface8_LockRect(pSurface, &d3dLockedRect, &rcDstRect, 0); + if (FAILED(hr)) { + IDirect3DSurface8_Release(pSurface); + return; + } + + // unpack image, apply transfer ops and store directly in texture + texImage->TexFormat->StoreImage(ctx, 2, texImage->Format, + _gldMesaFormatForD3DFormat(d3dsd.Format), + d3dLockedRect.pBits, + width, height, 1, + 0, 0, 0, // NOTE: d3dLockedRect.pBits is already offset!!! + d3dLockedRect.Pitch, + 0, // dstImageStride + format, type, pixels, packing); + + + IDirect3DSurface8_UnlockRect(pSurface); + IDirect3DSurface8_Release(pSurface); +} + +//--------------------------------------------------------------------------- + +void gld_TexSubImage1D_DX8( GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLsizei width, + GLenum format, GLenum type, + const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) +{ + gld_TexSubImage2D_DX8(ctx, target, level, xoffset, 0, width, 1, format, type, pixels, packing, texObj, texImage); +} + +//--------------------------------------------------------------------------- + +void gld_DeleteTexture_DX8( + GLcontext *ctx, + struct gl_texture_object *tObj) +{ + GLD_context *gld = (GLD_context*)(ctx->DriverCtx); + + if (tObj) { + IDirect3DTexture8 *pTex = (IDirect3DTexture8*)tObj->DriverData; + if (pTex) { +/* // Make sure texture is not bound to a stage before releasing it + for (int i=0; iCurrentTexture[i] == pTex) { + gld->pDev->SetTexture(i, NULL); + gld->CurrentTexture[i] = NULL; + } + }*/ + _GLD_DX8_TEX(Release(pTex)); + tObj->DriverData = NULL; + } + } +} + +//--------------------------------------------------------------------------- + +__inline void _gldSetColorOps( + const GLD_driver_dx8 *gld, + GLuint unit, + DWORD ColorArg1, + D3DTEXTUREOP ColorOp, + DWORD ColorArg2) +{ + _GLD_DX8_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_COLORARG1, ColorArg1)); + _GLD_DX8_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_COLOROP, ColorOp)); + _GLD_DX8_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_COLORARG2, ColorArg2)); +} + +//--------------------------------------------------------------------------- + +__inline void _gldSetAlphaOps( + const GLD_driver_dx8 *gld, + GLuint unit, + DWORD AlphaArg1, + D3DTEXTUREOP AlphaOp, + DWORD AlphaArg2) +{ + _GLD_DX8_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_ALPHAARG1, AlphaArg1)); + _GLD_DX8_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_ALPHAOP, AlphaOp)); + _GLD_DX8_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_ALPHAARG2, AlphaArg2)); +} + +//--------------------------------------------------------------------------- + +void gldUpdateTextureUnit( + GLcontext *ctx, + GLuint unit, + BOOL bPassThrough) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx); + + D3DTEXTUREFILTERTYPE minfilter; + D3DTEXTUREFILTERTYPE mipfilter; + GLenum BaseFormat; + DWORD dwColorArg0; + int iTexEnv = 0; + GLD_texenv *pTexenv; + + // NOTE: If bPassThrough is FALSE then texture stage can be + // disabled otherwise it must pass-through it's current fragment. + + const struct gl_texture_unit *pUnit = &ctx->Texture.Unit[unit]; + const struct gl_texture_object *tObj = pUnit->_Current; + + IDirect3DTexture8 *pTex = NULL; + if (tObj) { + pTex = (IDirect3DTexture8*)tObj->DriverData; + } + + // Enable texturing if unit is enabled and a valid D3D texture exists + // Mesa 5: TEXTUREn_x altered to TEXTURE_nD_BIT + //if (pTex && (pUnit->Enabled & (TEXTURE0_1D | TEXTURE0_2D))) { + if (pTex && (pUnit->_ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT))) { + // Enable texturing + _GLD_DX8_DEV(SetTexture(gld->pDev, unit, pTex)); + } else { + // Disable texturing, then return + _GLD_DX8_DEV(SetTexture(gld->pDev, unit, NULL)); + if (bPassThrough) { + _gldSetColorOps(gld, unit, D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_DIFFUSE); + _gldSetAlphaOps(gld, unit, D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_DIFFUSE); + } else { + _gldSetColorOps(gld, unit, D3DTA_TEXTURE, D3DTOP_DISABLE, D3DTA_DIFFUSE); + _gldSetAlphaOps(gld, unit, D3DTA_TEXTURE, D3DTOP_DISABLE, D3DTA_DIFFUSE); + } + return; + } + + // Texture parameters + _gldConvertMinFilter(tObj->MinFilter, &minfilter, &mipfilter); + _GLD_DX8_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_MINFILTER, minfilter)); + _GLD_DX8_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_MIPFILTER, mipfilter)); + _GLD_DX8_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_MAGFILTER, _gldConvertMagFilter(tObj->MagFilter))); + _GLD_DX8_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_ADDRESSU, _gldConvertWrap(tObj->WrapS))); + _GLD_DX8_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_ADDRESSV, _gldConvertWrap(tObj->WrapT))); + + // Texture priority + _GLD_DX8_TEX(SetPriority(pTex, (DWORD)(tObj->Priority*65535.0f))); + + // Texture environment + // TODO: Examine input texture for alpha and use specific alpha/non-alpha ops. + // See Page 355 of the Red Book. + BaseFormat = _gldDecodeBaseFormat(pTex); + + switch (BaseFormat) { + case GL_RGB: + iTexEnv = 0; + break; + case GL_RGBA: + iTexEnv = 1; + break; + case GL_ALPHA: + iTexEnv = 2; + break; + } + + switch (pUnit->EnvMode) { + case GL_DECAL: + iTexEnv += 0; + break; + case GL_REPLACE: + iTexEnv += 3; + break; + case GL_MODULATE: + iTexEnv += 6; + break; + case GL_BLEND: + // Set blend colour + dwColorArg0 = D3DCOLOR_COLORVALUE(pUnit->EnvColor[0], pUnit->EnvColor[1], pUnit->EnvColor[2], pUnit->EnvColor[3]); + _GLD_DX8_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_COLORARG0, dwColorArg0)); + iTexEnv += 9; + break; + case GL_ADD: + iTexEnv += 12; + break; + } + pTexenv = (GLD_texenv*)&gldTexEnv[iTexEnv]; + _gldSetColorOps(gld, unit, pTexenv->ColorArg1, pTexenv->ColorOp, pTexenv->ColorArg2); + _gldSetAlphaOps(gld, unit, pTexenv->AlphaArg1, pTexenv->AlphaOp, pTexenv->AlphaArg2); +} + +//--------------------------------------------------------------------------- + +void gld_NEW_TEXTURE_DX8( + GLcontext *ctx) +{ + // TODO: Support for three (ATI Radeon) or more (nVidia GeForce3) texture units + + BOOL bUnit0Enabled; + BOOL bUnit1Enabled; + + if (!ctx) + return; // Sanity check + + if (ctx->Const.MaxTextureUnits == 1) { + gldUpdateTextureUnit(ctx, 0, TRUE); + return; + } + + // + // NOTE: THE FOLLOWING RELATES TO TWO TEXTURE UNITS, AND TWO ONLY!! + // + + // Mesa 5: Texture Units altered + //bUnit0Enabled = (ctx->Texture._ReallyEnabled & (TEXTURE0_1D | TEXTURE0_2D)) ? TRUE : FALSE; + //bUnit1Enabled = (ctx->Texture._ReallyEnabled & (TEXTURE1_1D | TEXTURE1_2D)) ? TRUE : FALSE; + bUnit0Enabled = (ctx->Texture.Unit[0]._ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT)) ? TRUE : FALSE; + bUnit1Enabled = (ctx->Texture.Unit[1]._ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT)) ? TRUE : FALSE; + + // If Unit0 is disabled and Unit1 is enabled then we must pass-though + gldUpdateTextureUnit(ctx, 0, (!bUnit0Enabled && bUnit1Enabled) ? TRUE : FALSE); + // We can always disable the last texture unit + gldUpdateTextureUnit(ctx, 1, FALSE); + +#ifdef _DEBUG + { + // Find out whether device supports current renderstates + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx); +// GLD_context *gld = GLD_GET_CONTEXT(ctx); + + DWORD dwPasses; + _GLD_DX8_DEV(ValidateDevice(gld->pDev, &dwPasses)); +// if (FAILED(hr)) { +// gldLogError(GLDLOG_ERROR, "ValidateDevice failed", hr); +// } + if (dwPasses != 1) { + gldLogMessage(GLDLOG_ERROR, "ValidateDevice: Can't do in one pass\n"); + } + } +#endif +}; + +//--------------------------------------------------------------------------- diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_vb_d3d_render_dx8.c b/mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_vb_d3d_render_dx8.c new file mode 100644 index 000000000..cafbf4f5c --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_vb_d3d_render_dx8.c @@ -0,0 +1,249 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x/2000/XP/XBox (Win32) +* +* Description: GLDirect fastpath pipeline stage +* +****************************************************************************/ + +//--------------------------------------------------------------------------- + +//#include "../GLDirect.h" +//#include "../gld_log.h" +//#include "gld_dx8.h" + +#include "dglcontext.h" +#include "ddlog.h" +#include "gld_dx8.h" + +//--------------------------------------------------------------------------- + +#include "glheader.h" +#include "context.h" +#include "macros.h" +// #include "mem.h" +#include "mtypes.h" +//#include "mmath.h" + +#include "math/m_matrix.h" +#include "math/m_xform.h" + +#include "tnl/t_pipeline.h" + +//--------------------------------------------------------------------------- + +__inline void _gldSetVertexShaderConstants( + GLcontext *ctx, + GLD_driver_dx8 *gld) +{ + D3DXMATRIX mat, matView, matProj; + GLfloat *pM; + + // Mesa 5: Altered to a Stack + //pM = ctx->ModelView.m; + pM = ctx->ModelviewMatrixStack.Top->m; + matView._11 = pM[0]; + matView._12 = pM[1]; + matView._13 = pM[2]; + matView._14 = pM[3]; + matView._21 = pM[4]; + matView._22 = pM[5]; + matView._23 = pM[6]; + matView._24 = pM[7]; + matView._31 = pM[8]; + matView._32 = pM[9]; + matView._33 = pM[10]; + matView._34 = pM[11]; + matView._41 = pM[12]; + matView._42 = pM[13]; + matView._43 = pM[14]; + matView._44 = pM[15]; + + // Mesa 5: Altered to a Stack + //pM = ctx->ProjectionMatrix.m; + pM = ctx->ProjectionMatrixStack.Top->m; + matProj._11 = pM[0]; + matProj._12 = pM[1]; + matProj._13 = pM[2]; + matProj._14 = pM[3]; + matProj._21 = pM[4]; + matProj._22 = pM[5]; + matProj._23 = pM[6]; + matProj._24 = pM[7]; + matProj._31 = pM[8]; + matProj._32 = pM[9]; + matProj._33 = pM[10]; + matProj._34 = pM[11]; + matProj._41 = pM[12]; + matProj._42 = pM[13]; + matProj._43 = pM[14]; + matProj._44 = pM[15]; + + D3DXMatrixMultiply( &mat, &matView, &matProj ); + D3DXMatrixTranspose( &mat, &mat ); + + _GLD_DX8_DEV(SetVertexShaderConstant(gld->pDev, 0, &mat, 4)); +} + +//--------------------------------------------------------------------------- + +static GLboolean gld_d3d_render_stage_run( + GLcontext *ctx, + struct tnl_pipeline_stage *stage) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx); + + TNLcontext *tnl; + struct vertex_buffer *VB; + tnl_render_func *tab; + GLint pass; + GLD_pb_dx8 *gldPB = &gld->PB3d; +/* + static int count = 0; + count++; + if (count != 2) + return GL_FALSE; +*/ + // The "check" function should disable this stage, + // but we'll test gld->bUseMesaTnL anyway. + if (gld->bUseMesaTnL) { + // Do nothing in this stage, but continue pipeline + return GL_TRUE; + } + + tnl = TNL_CONTEXT(ctx); + VB = &tnl->vb; + pass = 0; + + tnl->Driver.Render.Start( ctx ); + +#if 0 + // For debugging: Useful to see if an app passes colour data in + // an unusual format. + switch (VB->ColorPtr[0]->Type) { + case GL_FLOAT: + ddlogMessage(GLDLOG_SYSTEM, "ColorPtr: GL_FLOAT\n"); + break; + case GL_UNSIGNED_BYTE: + ddlogMessage(GLDLOG_SYSTEM, "ColorPtr: GL_UNSIGNED_BYTE\n"); + break; + default: + ddlogMessage(GLDLOG_SYSTEM, "ColorPtr: *?*\n"); + break; + } +#endif + + tnl->Driver.Render.Points = gld_Points3D_DX8; + if (ctx->_TriangleCaps & DD_FLATSHADE) { + tnl->Driver.Render.Line = gld_Line3DFlat_DX8; + tnl->Driver.Render.Triangle = gld_Triangle3DFlat_DX8; + tnl->Driver.Render.Quad = gld_Quad3DFlat_DX8; + } else { + tnl->Driver.Render.Line = gld_Line3DSmooth_DX8; + tnl->Driver.Render.Triangle = gld_Triangle3DSmooth_DX8; + tnl->Driver.Render.Quad = gld_Quad3DSmooth_DX8; + } + + _GLD_DX8_VB(Lock(gldPB->pVB, 0, 0, &gldPB->pPoints, D3DLOCK_DISCARD)); + gldPB->nPoints = gldPB->nLines = gldPB->nTriangles = 0; + // Allocate primitive pointers + // gldPB->pPoints is always first + gldPB->pLines = gldPB->pPoints + (gldPB->dwStride * gldPB->iFirstLine); + gldPB->pTriangles = gldPB->pPoints + (gldPB->dwStride * gldPB->iFirstTriangle); + + ASSERT(tnl->Driver.Render.BuildVertices); + ASSERT(tnl->Driver.Render.PrimitiveNotify); + ASSERT(tnl->Driver.Render.Points); + ASSERT(tnl->Driver.Render.Line); + ASSERT(tnl->Driver.Render.Triangle); + ASSERT(tnl->Driver.Render.Quad); + ASSERT(tnl->Driver.Render.ResetLineStipple); + ASSERT(tnl->Driver.Render.Interp); + ASSERT(tnl->Driver.Render.CopyPV); + ASSERT(tnl->Driver.Render.ClippedLine); + ASSERT(tnl->Driver.Render.ClippedPolygon); + ASSERT(tnl->Driver.Render.Finish); + + tab = (VB->Elts ? tnl->Driver.Render.PrimTabElts : tnl->Driver.Render.PrimTabVerts); + + do { + GLuint i, length, flags = 0; + for (i = 0 ; !(flags & PRIM_END) ; i += length) + { + flags = VB->Primitive[i].mode; + length= VB->Primitive[i].count; + ASSERT(length || (flags & PRIM_END)); + ASSERT((flags & PRIM_MODE_MASK) <= GL_POLYGON+1); + if (length) + tab[flags & PRIM_MODE_MASK]( ctx, i, i + length, flags ); + } + } while (tnl->Driver.Render.Multipass && + tnl->Driver.Render.Multipass( ctx, ++pass )); + + _GLD_DX8_VB(Unlock(gldPB->pVB)); + + _GLD_DX8_DEV(SetStreamSource(gld->pDev, 0, gldPB->pVB, gldPB->dwStride)); + + _GLD_DX8_DEV(SetTransform(gld->pDev, D3DTS_PROJECTION, &gld->matProjection)); + _GLD_DX8_DEV(SetTransform(gld->pDev, D3DTS_WORLD, &gld->matModelView)); + + if (gldPB->nPoints) { + _GLD_DX8_DEV(DrawPrimitive(gld->pDev, D3DPT_POINTLIST, 0, gldPB->nPoints)); + gldPB->nPoints = 0; + } + + if (gldPB->nLines) { + _GLD_DX8_DEV(DrawPrimitive(gld->pDev, D3DPT_LINELIST, gldPB->iFirstLine, gldPB->nLines)); + gldPB->nLines = 0; + } + + if (gldPB->nTriangles) { + _GLD_DX8_DEV(DrawPrimitive(gld->pDev, D3DPT_TRIANGLELIST, gldPB->iFirstTriangle, gldPB->nTriangles)); + gldPB->nTriangles = 0; + } + + return GL_FALSE; /* finished the pipe */ +} + +//--------------------------------------------------------------------------- + +const struct tnl_pipeline_stage _gld_d3d_render_stage = +{ + "gld_d3d_render_stage", + NULL, + NULL, + NULL, + NULL, + gld_d3d_render_stage_run /* run */ +}; + +//--------------------------------------------------------------------------- diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_vb_mesa_render_dx8.c b/mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_vb_mesa_render_dx8.c new file mode 100644 index 000000000..9ab562010 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_vb_mesa_render_dx8.c @@ -0,0 +1,448 @@ + +/* + * 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 + */ + + +/* + * Render whole vertex buffers, including projection of vertices from + * clip space and clipping of primitives. + * + * This file makes calls to project vertices and to the point, line + * and triangle rasterizers via the function pointers: + * + * context->Driver.Render.* + * + */ + + +//--------------------------------------------------------------------------- + +//#include "../GLDirect.h" +//#include "../gld_log.h" +//#include "gld_dx8.h" + +#include "dglcontext.h" +#include "ddlog.h" +#include "gld_dx8.h" + +//--------------------------------------------------------------------------- + +#include "glheader.h" +#include "context.h" +#include "macros.h" +// #include "mem.h" +#include "mtypes.h" +//#include "mmath.h" + +#include "math/m_matrix.h" +#include "math/m_xform.h" + +#include "tnl/t_pipeline.h" + +/**********************************************************************/ +/* Clip single primitives */ +/**********************************************************************/ + + +#if defined(USE_IEEE) +#define NEGATIVE(x) (GET_FLOAT_BITS(x) & (1<<31)) +//#define DIFFERENT_SIGNS(x,y) ((GET_FLOAT_BITS(x) ^ GET_FLOAT_BITS(y)) & (1<<31)) +#else +#define NEGATIVE(x) (x < 0) +//#define DIFFERENT_SIGNS(x,y) (x * y <= 0 && x - y != 0) +/* Could just use (x*y<0) except for the flatshading requirements. + * Maybe there's a better way? + */ +#endif + + +#define W(i) coord[i][3] +#define Z(i) coord[i][2] +#define Y(i) coord[i][1] +#define X(i) coord[i][0] +#define SIZE 4 +#define TAG(x) x##_4 +#include "tnl/t_vb_cliptmp.h" + + + +/**********************************************************************/ +/* Clip and render whole begin/end objects */ +/**********************************************************************/ + +#define NEED_EDGEFLAG_SETUP (ctx->_TriangleCaps & DD_TRI_UNFILLED) +#define EDGEFLAG_GET(idx) VB->EdgeFlag[idx] +#define EDGEFLAG_SET(idx, val) VB->EdgeFlag[idx] = val + + +/* Vertices, with the possibility of clipping. + */ +#define RENDER_POINTS( start, count ) \ + tnl->Driver.Render.Points( ctx, start, count ) + +#define RENDER_LINE( v1, v2 ) \ +do { \ + GLubyte c1 = mask[v1], c2 = mask[v2]; \ + GLubyte ormask = c1|c2; \ + if (!ormask) \ + LineFunc( ctx, v1, v2 ); \ + else if (!(c1 & c2 & 0x3f)) \ + clip_line_4( ctx, v1, v2, ormask ); \ +} while (0) + +#define RENDER_TRI( v1, v2, v3 ) \ +do { \ + GLubyte c1 = mask[v1], c2 = mask[v2], c3 = mask[v3]; \ + GLubyte ormask = c1|c2|c3; \ + if (!ormask) \ + TriangleFunc( ctx, v1, v2, v3 ); \ + else if (!(c1 & c2 & c3 & 0x3f)) \ + clip_tri_4( ctx, v1, v2, v3, ormask ); \ +} while (0) + +#define RENDER_QUAD( v1, v2, v3, v4 ) \ +do { \ + GLubyte c1 = mask[v1], c2 = mask[v2]; \ + GLubyte c3 = mask[v3], c4 = mask[v4]; \ + GLubyte ormask = c1|c2|c3|c4; \ + if (!ormask) \ + QuadFunc( ctx, v1, v2, v3, v4 ); \ + else if (!(c1 & c2 & c3 & c4 & 0x3f)) \ + clip_quad_4( ctx, v1, v2, v3, v4, ormask ); \ +} while (0) + + +#define LOCAL_VARS \ + TNLcontext *tnl = TNL_CONTEXT(ctx); \ + struct vertex_buffer *VB = &tnl->vb; \ + const GLuint * const elt = VB->Elts; \ + const GLubyte *mask = VB->ClipMask; \ + const GLuint sz = VB->ClipPtr->size; \ + const tnl_line_func LineFunc = tnl->Driver.Render.Line; \ + const tnl_triangle_func TriangleFunc = tnl->Driver.Render.Triangle; \ + const tnl_quad_func QuadFunc = tnl->Driver.Render.Quad; \ + const GLboolean stipple = ctx->Line.StippleFlag; \ + (void) (LineFunc && TriangleFunc && QuadFunc); \ + (void) elt; (void) mask; (void) sz; (void) stipple; + +#define TAG(x) clip_##x##_verts +#define INIT(x) tnl->Driver.Render.PrimitiveNotify( ctx, x ) +#define RESET_STIPPLE if (stipple) tnl->Driver.Render.ResetLineStipple( ctx ) +#define PRESERVE_VB_DEFS +#include "tnl/t_vb_rendertmp.h" + + + +/* Elts, with the possibility of clipping. + */ +#undef ELT +#undef TAG +#define ELT(x) elt[x] +#define TAG(x) clip_##x##_elts +#include "tnl/t_vb_rendertmp.h" + +/* TODO: do this for all primitives, verts and elts: + */ +static void clip_elt_triangles( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + tnl_render_func render_tris = tnl->Driver.Render.PrimTabElts[GL_TRIANGLES]; + struct vertex_buffer *VB = &tnl->vb; + const GLuint * const elt = VB->Elts; + GLubyte *mask = VB->ClipMask; + GLuint last = count-2; + GLuint j; + (void) flags; + + tnl->Driver.Render.PrimitiveNotify( ctx, GL_TRIANGLES ); + + for (j=start; j < last; j+=3 ) { + GLubyte c1 = mask[elt[j]]; + GLubyte c2 = mask[elt[j+1]]; + GLubyte c3 = mask[elt[j+2]]; + GLubyte ormask = c1|c2|c3; + if (ormask) { + if (start < j) + render_tris( ctx, start, j, 0 ); + if (!(c1&c2&c3&0x3f)) + clip_tri_4( ctx, elt[j], elt[j+1], elt[j+2], ormask ); + start = j+3; + } + } + + if (start < j) + render_tris( ctx, start, j, 0 ); +} + +/**********************************************************************/ +/* Render whole begin/end objects */ +/**********************************************************************/ + +#define NEED_EDGEFLAG_SETUP (ctx->_TriangleCaps & DD_TRI_UNFILLED) +#define EDGEFLAG_GET(idx) VB->EdgeFlag[idx] +#define EDGEFLAG_SET(idx, val) VB->EdgeFlag[idx] = val + + +/* Vertices, no clipping. + */ +#define RENDER_POINTS( start, count ) \ + tnl->Driver.Render.Points( ctx, start, count ) + +#define RENDER_LINE( v1, v2 ) \ + LineFunc( ctx, v1, v2 ) + +#define RENDER_TRI( v1, v2, v3 ) \ + TriangleFunc( ctx, v1, v2, v3 ) + +#define RENDER_QUAD( v1, v2, v3, v4 ) \ + QuadFunc( ctx, v1, v2, v3, v4 ) + +#define TAG(x) _gld_tnl_##x##_verts + +#define LOCAL_VARS \ + TNLcontext *tnl = TNL_CONTEXT(ctx); \ + struct vertex_buffer *VB = &tnl->vb; \ + const GLuint * const elt = VB->Elts; \ + const tnl_line_func LineFunc = tnl->Driver.Render.Line; \ + const tnl_triangle_func TriangleFunc = tnl->Driver.Render.Triangle; \ + const tnl_quad_func QuadFunc = tnl->Driver.Render.Quad; \ + (void) (LineFunc && TriangleFunc && QuadFunc); \ + (void) elt; + +#define RESET_STIPPLE tnl->Driver.Render.ResetLineStipple( ctx ) +#define INIT(x) tnl->Driver.Render.PrimitiveNotify( ctx, x ) +#define RENDER_TAB_QUALIFIER +#define PRESERVE_VB_DEFS +#include "tnl/t_vb_rendertmp.h" + + +/* Elts, no clipping. + */ +#undef ELT +#define TAG(x) _gld_tnl_##x##_elts +#define ELT(x) elt[x] +#include "tnl/t_vb_rendertmp.h" + + +/**********************************************************************/ +/* Helper functions for drivers */ +/**********************************************************************/ +/* +void _tnl_RenderClippedPolygon( GLcontext *ctx, const GLuint *elts, GLuint n ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + GLuint *tmp = VB->Elts; + + VB->Elts = (GLuint *)elts; + tnl->Driver.Render.PrimTabElts[GL_POLYGON]( ctx, 0, n, PRIM_BEGIN|PRIM_END ); + VB->Elts = tmp; +} + +void _tnl_RenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + tnl->Driver.Render.Line( ctx, ii, jj ); +} +*/ + + +/**********************************************************************/ +/* Clip and render whole vertex buffers */ +/**********************************************************************/ + +tnl_points_func _gldSetupPoints[4] = { + gld_Points2D_DX8, + gld_Points2D_DX8, + gld_Points2D_DX8, + gld_Points2D_DX8 +}; +tnl_line_func _gldSetupLine[4] = { + gld_Line2DFlat_DX8, + gld_Line2DSmooth_DX8, + gld_Line2DFlat_DX8, + gld_Line2DSmooth_DX8, +}; +tnl_triangle_func _gldSetupTriangle[4] = { + gld_Triangle2DFlat_DX8, + gld_Triangle2DSmooth_DX8, + gld_Triangle2DFlatExtras_DX8, + gld_Triangle2DSmoothExtras_DX8 +}; +tnl_quad_func _gldSetupQuad[4] = { + gld_Quad2DFlat_DX8, + gld_Quad2DSmooth_DX8, + gld_Quad2DFlatExtras_DX8, + gld_Quad2DSmoothExtras_DX8 +}; + +//--------------------------------------------------------------------------- + +static GLboolean _gld_mesa_render_stage_run( + GLcontext *ctx, + struct tnl_pipeline_stage *stage) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx); + + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + tnl_render_func *tab; + GLint pass = 0; + GLD_pb_dx8 *gldPB; + + /* Allow the drivers to lock before projected verts are built so + * that window coordinates are guarenteed not to change before + * rendering. + */ + ASSERT(tnl->Driver.Render.Start); + + tnl->Driver.Render.Start( ctx ); + + // NOTE: Setting D3DRS_SOFTWAREVERTEXPROCESSING for a mixed-mode device resets + // stream, indices and shader to default values of NULL or 0. +/* if ((ctx->_TriangleCaps & DD_TRI_LIGHT_TWOSIDE) && + gld->VStwosidelight.hShader && + !ctx->Fog.Enabled) + { + IDirect3DDevice8_SetRenderState(gld->pDev, D3DRS_SOFTWAREVERTEXPROCESSING, !gld->VStwosidelight.bHardware); + _GLD_DX8_DEV(SetVertexShader(gld->pDev, gld->VStwosidelight.hShader)); + gldPB = &gld->PBtwosidelight; + tnl->Driver.Render.Points = gld_Points2DTwoside_DX8; + if (ctx->_TriangleCaps & DD_FLATSHADE) { + tnl->Driver.Render.Line = gld_Line2DFlatTwoside_DX8; + tnl->Driver.Render.Triangle = gld_Triangle2DFlatTwoside_DX8; + tnl->Driver.Render.Quad = gld_Quad2DFlatTwoside_DX8; + } else { + tnl->Driver.Render.Line = gld_Line2DSmoothTwoside_DX8; + tnl->Driver.Render.Triangle = gld_Triangle2DSmoothTwoside_DX8; + tnl->Driver.Render.Quad = gld_Quad2DSmoothTwoside_DX8; + } + } else {*/ + IDirect3DDevice8_SetRenderState(gld->pDev, D3DRS_SOFTWAREVERTEXPROCESSING, TRUE); + gldPB = &gld->PB2d; + _GLD_DX8_DEV(SetVertexShader(gld->pDev, gldPB->dwFVF)); + tnl->Driver.Render.Points = _gldSetupPoints[gld->iSetupFunc]; + tnl->Driver.Render.Line = _gldSetupLine[gld->iSetupFunc]; + tnl->Driver.Render.Triangle = _gldSetupTriangle[gld->iSetupFunc]; + tnl->Driver.Render.Quad = _gldSetupQuad[gld->iSetupFunc]; +// } + + _GLD_DX8_VB(Lock(gldPB->pVB, 0, 0, &gldPB->pPoints, D3DLOCK_DISCARD)); + gldPB->nPoints = gldPB->nLines = gldPB->nTriangles = 0; + // Allocate primitive pointers + // gldPB->pPoints is always first + gldPB->pLines = gldPB->pPoints + (gldPB->dwStride * gldPB->iFirstLine); + gldPB->pTriangles = gldPB->pPoints + (gldPB->dwStride * gldPB->iFirstTriangle); + + ASSERT(tnl->Driver.Render.BuildVertices); + ASSERT(tnl->Driver.Render.PrimitiveNotify); + ASSERT(tnl->Driver.Render.Points); + ASSERT(tnl->Driver.Render.Line); + ASSERT(tnl->Driver.Render.Triangle); + ASSERT(tnl->Driver.Render.Quad); + ASSERT(tnl->Driver.Render.ResetLineStipple); + ASSERT(tnl->Driver.Render.Interp); + ASSERT(tnl->Driver.Render.CopyPV); + ASSERT(tnl->Driver.Render.ClippedLine); + ASSERT(tnl->Driver.Render.ClippedPolygon); + ASSERT(tnl->Driver.Render.Finish); + + tnl->Driver.Render.BuildVertices( ctx, 0, VB->Count, ~0 ); + + if (VB->ClipOrMask) { + tab = VB->Elts ? clip_render_tab_elts : clip_render_tab_verts; + clip_render_tab_elts[GL_TRIANGLES] = clip_elt_triangles; + } + else { + tab = (VB->Elts ? + tnl->Driver.Render.PrimTabElts : + tnl->Driver.Render.PrimTabVerts); + } + + do { + GLuint i, length, flags = 0; + for (i = 0 ; !(flags & PRIM_END) ; i += length) { + flags = VB->Primitive[i].mode; + length= VB->Primitive[i].count; + ASSERT(length || (flags & PRIM_END)); + ASSERT((flags & PRIM_MODE_MASK) <= GL_POLYGON+1); + if (length) + tab[flags & PRIM_MODE_MASK]( ctx, i, i + length, flags ); + } + } while (tnl->Driver.Render.Multipass && + tnl->Driver.Render.Multipass( ctx, ++pass )); + + +// tnl->Driver.Render.Finish( ctx ); + + _GLD_DX8_VB(Unlock(gldPB->pVB)); + + _GLD_DX8_DEV(SetStreamSource(gld->pDev, 0, gldPB->pVB, gldPB->dwStride)); + + if (gldPB->nPoints) { + _GLD_DX8_DEV(DrawPrimitive(gld->pDev, D3DPT_POINTLIST, 0, gldPB->nPoints)); + gldPB->nPoints = 0; + } + + if (gldPB->nLines) { + _GLD_DX8_DEV(DrawPrimitive(gld->pDev, D3DPT_LINELIST, gldPB->iFirstLine, gldPB->nLines)); + gldPB->nLines = 0; + } + + if (gldPB->nTriangles) { + _GLD_DX8_DEV(DrawPrimitive(gld->pDev, D3DPT_TRIANGLELIST, gldPB->iFirstTriangle, gldPB->nTriangles)); + gldPB->nTriangles = 0; + } + + return GL_FALSE; /* finished the pipe */ +} + + +/**********************************************************************/ +/* Render pipeline stage */ +/**********************************************************************/ + + + + +//--------------------------------------------------------------------------- + +const struct tnl_pipeline_stage _gld_mesa_render_stage = +{ + "gld_mesa_render_stage", + NULL, + NULL, + NULL, + NULL, + _gld_mesa_render_stage_run /* run */ +}; + +//--------------------------------------------------------------------------- diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_wgl_dx8.c b/mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_wgl_dx8.c new file mode 100644 index 000000000..011d810e9 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dx8/gld_wgl_dx8.c @@ -0,0 +1,1336 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x/2000/XP/XBox (Win32) +* +* Description: GLDirect Direct3D 8.x WGL (WindowsGL) +* +****************************************************************************/ + +#include "dglcontext.h" +#include "gld_driver.h" +#include "gld_dxerr8.h" +#include "gld_dx8.h" + +#include "tnl/tnl.h" +#include "tnl/t_context.h" + +// Copied from dglcontect.c +#define GLDERR_NONE 0 +#define GLDERR_MEM 1 +#define GLDERR_DDRAW 2 +#define GLDERR_D3D 3 +#define GLDERR_BPP 4 +#define GLDERR_DDS 5 +// This external var keeps track of any error +extern int nContextError; + +#define DDLOG_CRITICAL_OR_WARN DDLOG_CRITICAL + +extern void _gld_mesa_warning(GLcontext *, char *); +extern void _gld_mesa_fatal(GLcontext *, char *); + +//--------------------------------------------------------------------------- + +static char szColorDepthWarning[] = +"GLDirect does not support the current desktop\n\ +color depth.\n\n\ +You may need to change the display resolution to\n\ +16 bits per pixel or higher color depth using\n\ +the Windows Display Settings control panel\n\ +before running this OpenGL application.\n"; + +// The only depth-stencil formats currently supported by Direct3D +// Surface Format Depth Stencil Total Bits +// D3DFMT_D32 32 - 32 +// D3DFMT_D15S1 15 1 16 +// D3DFMT_D24S8 24 8 32 +// D3DFMT_D16 16 - 16 +// D3DFMT_D24X8 24 - 32 +// D3DFMT_D24X4S4 24 4 32 + +// This pixel format will be used as a template when compiling the list +// of pixel formats supported by the hardware. Many fields will be +// filled in at runtime. +// PFD flag defaults are upgraded to match ChoosePixelFormat() -- DaveM +static DGL_pixelFormat pfTemplateHW = +{ + { + sizeof(PIXELFORMATDESCRIPTOR), // Size of the data structure + 1, // Structure version - should be 1 + // Flags: + PFD_DRAW_TO_WINDOW | // The buffer can draw to a window or device surface. + PFD_DRAW_TO_BITMAP | // The buffer can draw to a bitmap. (DaveM) + PFD_SUPPORT_GDI | // The buffer supports GDI drawing. (DaveM) + PFD_SUPPORT_OPENGL | // The buffer supports OpenGL drawing. + PFD_DOUBLEBUFFER | // The buffer is double-buffered. + 0, // Placeholder for easy commenting of above flags + PFD_TYPE_RGBA, // Pixel type RGBA. + 16, // Total colour bitplanes (excluding alpha bitplanes) + 5, 0, // Red bits, shift + 5, 0, // Green bits, shift + 5, 0, // Blue bits, shift + 0, 0, // Alpha bits, shift (destination alpha) + 0, // Accumulator bits (total) + 0, 0, 0, 0, // Accumulator bits: Red, Green, Blue, Alpha + 0, // Depth bits + 0, // Stencil bits + 0, // Number of auxiliary buffers + 0, // Layer type + 0, // Specifies the number of overlay and underlay planes. + 0, // Layer mask + 0, // Specifies the transparent color or index of an underlay plane. + 0 // Damage mask + }, + D3DFMT_UNKNOWN, // No depth/stencil buffer +}; + +//--------------------------------------------------------------------------- +// Vertex Shaders +//--------------------------------------------------------------------------- + +// Vertex Shader Declaration +static DWORD dwTwoSidedLightingDecl[] = +{ + D3DVSD_STREAM(0), + D3DVSD_REG(0, D3DVSDT_FLOAT3), // XYZ position + D3DVSD_REG(1, D3DVSDT_FLOAT3), // XYZ normal + D3DVSD_REG(2, D3DVSDT_D3DCOLOR), // Diffuse color + D3DVSD_REG(3, D3DVSDT_D3DCOLOR), // Specular color + D3DVSD_REG(4, D3DVSDT_FLOAT2), // 2D texture unit 0 + D3DVSD_REG(5, D3DVSDT_FLOAT2), // 2D texture unit 1 + D3DVSD_END() +}; + +// Vertex Shader for two-sided lighting +static char *szTwoSidedLightingVS = +// This is a test shader! +"vs.1.0\n" +"m4x4 oPos,v0,c0\n" +"mov oD0,v2\n" +"mov oD1,v3\n" +"mov oT0,v4\n" +"mov oT1,v5\n" +; + +//--------------------------------------------------------------------------- +//--------------------------------------------------------------------------- + +typedef struct { + HINSTANCE hD3D8DLL; // Handle to d3d8.dll + FNDIRECT3DCREATE8 fnDirect3DCreate8; // Direct3DCreate8 function prototype + BOOL bDirect3D; // Persistant Direct3D8 exists + BOOL bDirect3DDevice; // Persistant Direct3DDevice8 exists + IDirect3D8 *pD3D; // Persistant Direct3D8 + IDirect3DDevice8 *pDev; // Persistant Direct3DDevice8 +} GLD_dx8_globals; + +// These are "global" to all DX8 contexts. KeithH +static GLD_dx8_globals dx8Globals; + +//--------------------------------------------------------------------------- +//--------------------------------------------------------------------------- + +BOOL gldGetDXErrorString_DX( + HRESULT hr, + char *buf, + int nBufSize) +{ + // + // Return a string describing the input HRESULT error code + // + + D3DXGetErrorString(hr, buf, nBufSize); + return TRUE; +} + +//--------------------------------------------------------------------------- + +static D3DMULTISAMPLE_TYPE _gldGetDeviceMultiSampleType( + IDirect3D8 *pD3D8, + D3DFORMAT SurfaceFormat, + D3DDEVTYPE d3dDevType, + BOOL Windowed) +{ + int i; + HRESULT hr; + + if (glb.dwMultisample == GLDS_MULTISAMPLE_NONE) + return D3DMULTISAMPLE_NONE; + + if (glb.dwMultisample == GLDS_MULTISAMPLE_FASTEST) { + // Find fastest multisample + for (i=2; i<17; i++) { + hr = IDirect3D8_CheckDeviceMultiSampleType( + pD3D8, + glb.dwAdapter, + d3dDevType, + SurfaceFormat, + Windowed, + (D3DMULTISAMPLE_TYPE)i); + if (SUCCEEDED(hr)) { + return (D3DMULTISAMPLE_TYPE)i; + } + } + } else { + // Find nicest multisample + for (i=16; i>1; i--) { + hr = IDirect3D8_CheckDeviceMultiSampleType( + pD3D8, + glb.dwAdapter, + d3dDevType, + SurfaceFormat, + Windowed, + (D3DMULTISAMPLE_TYPE)i); + if (SUCCEEDED(hr)) { + return (D3DMULTISAMPLE_TYPE)i; + } + } + } + + // Nothing found - return default + return D3DMULTISAMPLE_NONE; +} + +//--------------------------------------------------------------------------- + +void _gldDestroyPrimitiveBuffer( + GLD_pb_dx8 *gldVB) +{ + SAFE_RELEASE(gldVB->pVB); + + // Sanity check... + gldVB->nLines = gldVB->nPoints = gldVB->nTriangles = 0; +} + +//--------------------------------------------------------------------------- + +HRESULT _gldCreatePrimitiveBuffer( + GLcontext *ctx, + GLD_driver_dx8 *lpCtx, + GLD_pb_dx8 *gldVB) +{ + HRESULT hResult; + char *szCreateVertexBufferFailed = "CreateVertexBuffer failed"; + DWORD dwMaxVertices; // Max number of vertices in vertex buffer + DWORD dwVBSize; // Total size of vertex buffer + + // If CVA (Compiled Vertex Array) is used by an OpenGL app, then we + // will need enough vertices to cater for Mesa::Const.MaxArrayLockSize. + // We'll use IMM_SIZE if it's larger (which it should not be). + dwMaxVertices = MAX_ARRAY_LOCK_SIZE; + + // Now calculate how many vertices to allow for in total + // 1 per point, 2 per line, 6 per quad = 9 + dwVBSize = dwMaxVertices * 9 * gldVB->dwStride; + + hResult = IDirect3DDevice8_CreateVertexBuffer( + lpCtx->pDev, + dwVBSize, + gldVB->dwUsage, + gldVB->dwFVF, + gldVB->dwPool, + &gldVB->pVB); + if (FAILED(hResult)) { + ddlogMessage(DDLOG_CRITICAL_OR_WARN, szCreateVertexBufferFailed); + return hResult; + } + + gldVB->nLines = gldVB->nPoints = gldVB->nTriangles = 0; + gldVB->pPoints = gldVB->pLines = gldVB->pTriangles = NULL; + gldVB->iFirstLine = dwMaxVertices; // Index of first line in VB + gldVB->iFirstTriangle = dwMaxVertices*3; // Index of first triangle in VB + + return S_OK; +} + +//--------------------------------------------------------------------------- +// Function: _gldCreateVertexShaders +// Create DX8 Vertex Shaders. +//--------------------------------------------------------------------------- +/* +void _gldCreateVertexShaders( + GLD_driver_dx8 *gld) +{ + DWORD dwFlags; + LPD3DXBUFFER pVSOpcodeBuffer; // Vertex Shader opcode buffer + HRESULT hr; + +#ifdef _DEBUG + dwFlags = D3DXASM_DEBUG; +#else + dwFlags = 0; // D3DXASM_SKIPVALIDATION; +#endif + + ddlogMessage(DDLOG_INFO, "Creating shaders...\n"); + + // Init the shader handle + gld->VStwosidelight.hShader = 0; + + if (gld->d3dCaps8.MaxStreams == 0) { + // Lame DX8 driver doesn't support streams + // Not fatal, as defaults will be used + ddlogMessage(DDLOG_WARN, "Driver doesn't support Vertex Shaders (MaxStreams==0)\n"); + return; + } + + // ** THIS DISABLES VERTEX SHADER SUPPORT ** +// return; + // ** THIS DISABLES VERTEX SHADER SUPPORT ** + + // + // Two-sided lighting + // + +#if 0 + // + // DEBUGGING: Load shader from a text file + // + { + LPD3DXBUFFER pVSErrorBuffer; // Vertex Shader error buffer + hr = D3DXAssembleShaderFromFile( + "twoside.vsh", + dwFlags, + NULL, // No constants + &pVSOpcodeBuffer, + &pVSErrorBuffer); + if (pVSErrorBuffer && pVSErrorBuffer->lpVtbl->GetBufferPointer(pVSErrorBuffer)) + ddlogMessage(DDLOG_INFO, pVSErrorBuffer->lpVtbl->GetBufferPointer(pVSErrorBuffer)); + SAFE_RELEASE(pVSErrorBuffer); + } +#else + { + LPD3DXBUFFER pVSErrorBuffer; // Vertex Shader error buffer + // Assemble ascii shader text into shader opcodes + hr = D3DXAssembleShader( + szTwoSidedLightingVS, + strlen(szTwoSidedLightingVS), + dwFlags, + NULL, // No constants + &pVSOpcodeBuffer, + &pVSErrorBuffer); + if (pVSErrorBuffer && pVSErrorBuffer->lpVtbl->GetBufferPointer(pVSErrorBuffer)) + ddlogMessage(DDLOG_INFO, pVSErrorBuffer->lpVtbl->GetBufferPointer(pVSErrorBuffer)); + SAFE_RELEASE(pVSErrorBuffer); + } +#endif + if (FAILED(hr)) { + ddlogError(DDLOG_WARN, "AssembleShader failed", hr); + SAFE_RELEASE(pVSOpcodeBuffer); + return; + } + +// This is for debugging. Remove to enable vertex shaders in HW +#define _GLD_FORCE_SW_VS 0 + + if (_GLD_FORCE_SW_VS) { + // _GLD_FORCE_SW_VS should be disabled for Final Release + ddlogMessage(DDLOG_SYSTEM, "[Forcing shaders in SW]\n"); + } + + // Try and create shader in hardware. + // NOTE: The D3D Ref device appears to succeed when trying to + // create the device in hardware, but later complains + // when trying to set it with SetVertexShader(). Go figure. + if (_GLD_FORCE_SW_VS || glb.dwDriver == GLDS_DRIVER_REF) { + // Don't try and create a hardware shader with the Ref device + hr = E_FAIL; // COM error/fail result + } else { + gld->VStwosidelight.bHardware = TRUE; + hr = IDirect3DDevice8_CreateVertexShader( + gld->pDev, + dwTwoSidedLightingDecl, + pVSOpcodeBuffer->lpVtbl->GetBufferPointer(pVSOpcodeBuffer), + &gld->VStwosidelight.hShader, + 0); + } + if (FAILED(hr)) { + ddlogMessage(DDLOG_INFO, "... HW failed, trying SW...\n"); + // Failed. Try and create shader for software processing + hr = IDirect3DDevice8_CreateVertexShader( + gld->pDev, + dwTwoSidedLightingDecl, + pVSOpcodeBuffer->lpVtbl->GetBufferPointer(pVSOpcodeBuffer), + &gld->VStwosidelight.hShader, + D3DUSAGE_SOFTWAREPROCESSING); + if (FAILED(hr)) { + gld->VStwosidelight.hShader = 0; // Sanity check + ddlogError(DDLOG_WARN, "CreateVertexShader failed", hr); + return; + } + // Succeeded, but for software processing + gld->VStwosidelight.bHardware = FALSE; + } + + SAFE_RELEASE(pVSOpcodeBuffer); + + ddlogMessage(DDLOG_INFO, "... OK\n"); +} + +//--------------------------------------------------------------------------- + +void _gldDestroyVertexShaders( + GLD_driver_dx8 *gld) +{ + if (gld->VStwosidelight.hShader) { + IDirect3DDevice8_DeleteVertexShader(gld->pDev, gld->VStwosidelight.hShader); + gld->VStwosidelight.hShader = 0; + } +} +*/ +//--------------------------------------------------------------------------- + +LPVOID lpOpaque1 = NULL; +LPVOID lpOpaque2 = NULL; + +BOOL gldCreateDrawable_DX( + DGL_ctx *ctx, +// BOOL bDefaultDriver, + BOOL bDirectDrawPersistant, + BOOL bPersistantBuffers) +{ + // + // bDirectDrawPersistant: applies to IDirect3D8 + // bPersistantBuffers: applies to IDirect3DDevice8 + // + + HRESULT hResult; + GLD_driver_dx8 *lpCtx = NULL; + D3DDEVTYPE d3dDevType; + D3DPRESENT_PARAMETERS d3dpp; + D3DDISPLAYMODE d3ddm; + DWORD dwBehaviourFlags; + D3DADAPTER_IDENTIFIER8 d3dIdent; + + // Error if context is NULL. + if (ctx == NULL) + return FALSE; + + if (ctx->glPriv) { + lpCtx = ctx->glPriv; + // Release any existing interfaces + SAFE_RELEASE(lpCtx->pDev); + SAFE_RELEASE(lpCtx->pD3D); + } else { + lpCtx = (GLD_driver_dx8*)malloc(sizeof(GLD_driver_dx8)); + ZeroMemory(lpCtx, sizeof(lpCtx)); + } + + d3dDevType = (glb.dwDriver == GLDS_DRIVER_HAL) ? D3DDEVTYPE_HAL : D3DDEVTYPE_REF; + // TODO: Check this +// if (bDefaultDriver) +// d3dDevType = D3DDEVTYPE_REF; + + // Use persistant interface if needed + if (bDirectDrawPersistant && dx8Globals.bDirect3D) { + lpCtx->pD3D = dx8Globals.pD3D; + IDirect3D8_AddRef(lpCtx->pD3D); + goto SkipDirectDrawCreate; + } + + // Create Direct3D8 object + lpCtx->pD3D = dx8Globals.fnDirect3DCreate8(D3D_SDK_VERSION_DX8_SUPPORT_WIN95); + if (lpCtx->pD3D == NULL) { + MessageBox(NULL, "Unable to initialize Direct3D8", "GLDirect", MB_OK); + ddlogMessage(DDLOG_CRITICAL_OR_WARN, "Unable to create Direct3D8 interface"); + nContextError = GLDERR_D3D; + goto return_with_error; + } + + // Cache Direct3D interface for subsequent GLRCs + if (bDirectDrawPersistant && !dx8Globals.bDirect3D) { + dx8Globals.pD3D = lpCtx->pD3D; + IDirect3D8_AddRef(dx8Globals.pD3D); + dx8Globals.bDirect3D = TRUE; + } +SkipDirectDrawCreate: + + // Get the display mode so we can make a compatible backbuffer + hResult = IDirect3D8_GetAdapterDisplayMode(lpCtx->pD3D, glb.dwAdapter, &d3ddm); + if (FAILED(hResult)) { + nContextError = GLDERR_D3D; + goto return_with_error; + } + + // Get device caps + hResult = IDirect3D8_GetDeviceCaps(lpCtx->pD3D, glb.dwAdapter, d3dDevType, &lpCtx->d3dCaps8); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "IDirect3D8_GetDeviceCaps failed", hResult); + nContextError = GLDERR_D3D; + goto return_with_error; + } + + // Check for hardware transform & lighting + lpCtx->bHasHWTnL = lpCtx->d3dCaps8.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ? TRUE : FALSE; + + // If this flag is present then we can't default to Mesa + // SW rendering between BeginScene() and EndScene(). + if (lpCtx->d3dCaps8.Caps2 & D3DCAPS2_NO2DDURING3DSCENE) { + ddlogMessage(DDLOG_WARN, + "Warning : No 2D allowed during 3D scene.\n"); + } + + // + // Create the Direct3D context + // + + // Re-use original IDirect3DDevice if persistant buffers exist. + // Note that we test for persistant IDirect3D8 as well + // bDirectDrawPersistant == persistant IDirect3D8 (DirectDraw8 does not exist) + if (bDirectDrawPersistant && bPersistantBuffers && dx8Globals.pD3D && dx8Globals.pDev) { + lpCtx->pDev = dx8Globals.pDev; + IDirect3DDevice8_AddRef(dx8Globals.pDev); + goto skip_direct3ddevice_create; + } + + // Clear the presentation parameters (sets all members to zero) + ZeroMemory(&d3dpp, sizeof(d3dpp)); + + // Recommended by MS; needed for MultiSample. + // Be careful if altering this for FullScreenBlit + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + + d3dpp.BackBufferFormat = d3ddm.Format; + d3dpp.BackBufferCount = 1; + d3dpp.MultiSampleType = _gldGetDeviceMultiSampleType(lpCtx->pD3D, d3ddm.Format, d3dDevType, !ctx->bFullscreen); + d3dpp.AutoDepthStencilFormat = ctx->lpPF->dwDriverData; + d3dpp.EnableAutoDepthStencil = (d3dpp.AutoDepthStencilFormat == D3DFMT_UNKNOWN) ? FALSE : TRUE; + + if (ctx->bFullscreen) { + ddlogWarnOption(FALSE); // Don't popup any messages in fullscreen + d3dpp.Windowed = FALSE; + d3dpp.BackBufferWidth = d3ddm.Width; + d3dpp.BackBufferHeight = d3ddm.Height; + d3dpp.hDeviceWindow = ctx->hWnd; + d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; + + // Support for vertical retrace synchronisation. + // Set default presentation interval in case caps bits are missing + d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; + if (glb.bWaitForRetrace) { + if (lpCtx->d3dCaps8.PresentationIntervals & D3DPRESENT_INTERVAL_ONE) + d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_ONE; + } else { + if (lpCtx->d3dCaps8.PresentationIntervals & D3DPRESENT_INTERVAL_IMMEDIATE) + d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + } + } else { + ddlogWarnOption(glb.bMessageBoxWarnings); // OK to popup messages + d3dpp.Windowed = TRUE; + d3dpp.BackBufferWidth = ctx->dwWidth; + d3dpp.BackBufferHeight = ctx->dwHeight; + d3dpp.hDeviceWindow = ctx->hWnd; + d3dpp.FullScreen_RefreshRateInHz = 0; + // FullScreen_PresentationInterval must be default for Windowed mode + d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; + } + + // Decide if we can use hardware TnL + dwBehaviourFlags = (lpCtx->bHasHWTnL) ? + D3DCREATE_MIXED_VERTEXPROCESSING : D3DCREATE_SOFTWARE_VERTEXPROCESSING; + // Add flag to tell D3D to be thread-safe + if (glb.bMultiThreaded) + dwBehaviourFlags |= D3DCREATE_MULTITHREADED; + // Add flag to tell D3D to be FPU-safe + if (!glb.bFastFPU) + dwBehaviourFlags |= D3DCREATE_FPU_PRESERVE; + hResult = IDirect3D8_CreateDevice(lpCtx->pD3D, + glb.dwAdapter, + d3dDevType, + ctx->hWnd, + dwBehaviourFlags, + &d3dpp, + &lpCtx->pDev); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "IDirect3D8_CreateDevice failed", hResult); + nContextError = GLDERR_D3D; + goto return_with_error; + } + + if (bDirectDrawPersistant && bPersistantBuffers && dx8Globals.pD3D) { + dx8Globals.pDev = lpCtx->pDev; + dx8Globals.bDirect3DDevice = TRUE; + } + +/* + // See if DDraw interfaces are available (DaveM) + hResult = IDirect3D8_QueryInterface(lpCtx->pDev, + &IID_IDirectDraw7, (LPVOID*)&lpOpaque1); + if (FAILED(hResult) || lpOpaque1 == NULL) { + ddlogMessage(DDLOG_INFO, "DirectDraw QueryInterface unavailable\n"); + } + + hResult = IDirect3DDevice8_QueryInterface(lpCtx->pDev, + &IID_IDirectDrawSurface7, (LPVOID*)&lpOpaque2); + if (FAILED(hResult) || lpOpaque2 == NULL) { + ddlogMessage(DDLOG_INFO, "DirectDrawSurface QueryInterface unavialable\n"); + } +*/ + // Dump some useful stats + hResult = IDirect3D8_GetAdapterIdentifier( + lpCtx->pD3D, + glb.dwAdapter, + D3DENUM_NO_WHQL_LEVEL, // Avoids 1 to 2 second delay + &d3dIdent); + if (SUCCEEDED(hResult)) { + ddlogPrintf(DDLOG_INFO, "[Driver Description: %s]", &d3dIdent.Description); + ddlogPrintf(DDLOG_INFO, "[Driver file: %s %d.%d.%02d.%d]", + d3dIdent.Driver, + HIWORD(d3dIdent.DriverVersion.HighPart), + LOWORD(d3dIdent.DriverVersion.HighPart), + HIWORD(d3dIdent.DriverVersion.LowPart), + LOWORD(d3dIdent.DriverVersion.LowPart)); + ddlogPrintf(DDLOG_INFO, "[VendorId: 0x%X, DeviceId: 0x%X, SubSysId: 0x%X, Revision: 0x%X]", + d3dIdent.VendorId, d3dIdent.DeviceId, d3dIdent.SubSysId, d3dIdent.Revision); + } + + // Init projection matrix for D3D TnL + D3DXMatrixIdentity(&lpCtx->matProjection); + lpCtx->matModelView = lpCtx->matProjection; +// gld->bUseMesaProjection = TRUE; + +skip_direct3ddevice_create: + + // Create buffers to hold primitives + lpCtx->PB2d.dwFVF = GLD_FVF_2D_VERTEX; + lpCtx->PB2d.dwPool = D3DPOOL_SYSTEMMEM; + lpCtx->PB2d.dwStride = sizeof(GLD_2D_VERTEX); + lpCtx->PB2d.dwUsage = D3DUSAGE_DONOTCLIP | + D3DUSAGE_DYNAMIC | + D3DUSAGE_SOFTWAREPROCESSING | + D3DUSAGE_WRITEONLY; + hResult = _gldCreatePrimitiveBuffer(ctx->glCtx, lpCtx, &lpCtx->PB2d); + if (FAILED(hResult)) + goto return_with_error; + + lpCtx->PB3d.dwFVF = GLD_FVF_3D_VERTEX; + lpCtx->PB3d.dwPool = D3DPOOL_DEFAULT; + lpCtx->PB3d.dwStride = sizeof(GLD_3D_VERTEX); + lpCtx->PB3d.dwUsage = D3DUSAGE_DYNAMIC | + D3DUSAGE_SOFTWAREPROCESSING | + D3DUSAGE_WRITEONLY; + hResult = _gldCreatePrimitiveBuffer(ctx->glCtx, lpCtx, &lpCtx->PB3d); + if (FAILED(hResult)) + goto return_with_error; + +/* // NOTE: A FVF code of zero indicates a non-FVF vertex buffer (for vertex shaders) + lpCtx->PBtwosidelight.dwFVF = 0; //GLD_FVF_TWOSIDED_VERTEX; + lpCtx->PBtwosidelight.dwPool = D3DPOOL_DEFAULT; + lpCtx->PBtwosidelight.dwStride = sizeof(GLD_TWOSIDED_VERTEX); + lpCtx->PBtwosidelight.dwUsage = D3DUSAGE_DONOTCLIP | + D3DUSAGE_DYNAMIC | + D3DUSAGE_SOFTWAREPROCESSING | + D3DUSAGE_WRITEONLY; + hResult = _gldCreatePrimitiveBuffer(ctx->glCtx, lpCtx, &lpCtx->PBtwosidelight); + if (FAILED(hResult)) + goto return_with_error;*/ + + // Now try and create the DX8 Vertex Shaders +// _gldCreateVertexShaders(lpCtx); + + // Zero the pipeline usage counters + lpCtx->PipelineUsage.qwMesa.QuadPart = +// lpCtx->PipelineUsage.dwD3D2SVS.QuadPart = + lpCtx->PipelineUsage.qwD3DFVF.QuadPart = 0; + + // Assign drawable to GL private + ctx->glPriv = lpCtx; + return TRUE; + +return_with_error: + // Clean up and bail + +// _gldDestroyVertexShaders(lpCtx); + +// _gldDestroyPrimitiveBuffer(&lpCtx->PBtwosidelight); + _gldDestroyPrimitiveBuffer(&lpCtx->PB3d); + _gldDestroyPrimitiveBuffer(&lpCtx->PB2d); + + SAFE_RELEASE(lpCtx->pDev); + SAFE_RELEASE(lpCtx->pD3D); + return FALSE; +} + +//--------------------------------------------------------------------------- + +BOOL gldResizeDrawable_DX( + DGL_ctx *ctx, + BOOL bDefaultDriver, + BOOL bPersistantInterface, + BOOL bPersistantBuffers) +{ + GLD_driver_dx8 *gld = NULL; + D3DDEVTYPE d3dDevType; + D3DPRESENT_PARAMETERS d3dpp; + D3DDISPLAYMODE d3ddm; + HRESULT hResult; + + // Error if context is NULL. + if (ctx == NULL) + return FALSE; + + gld = ctx->glPriv; + if (gld == NULL) + return FALSE; + + if (ctx->bSceneStarted) { + IDirect3DDevice8_EndScene(gld->pDev); + ctx->bSceneStarted = FALSE; + } + + d3dDevType = (glb.dwDriver == GLDS_DRIVER_HAL) ? D3DDEVTYPE_HAL : D3DDEVTYPE_REF; + if (!bDefaultDriver) + d3dDevType = D3DDEVTYPE_REF; // Force Direct3D Reference Rasterise (software) + + // Get the display mode so we can make a compatible backbuffer + hResult = IDirect3D8_GetAdapterDisplayMode(gld->pD3D, glb.dwAdapter, &d3ddm); + if (FAILED(hResult)) { + nContextError = GLDERR_D3D; +// goto return_with_error; + return FALSE; + } + + // Destroy DX8 Vertex Shaders before Reset() +// _gldDestroyVertexShaders(gld); + + // Release POOL_DEFAULT objects before Reset() + if (gld->PB2d.dwPool == D3DPOOL_DEFAULT) + _gldDestroyPrimitiveBuffer(&gld->PB2d); + if (gld->PB3d.dwPool == D3DPOOL_DEFAULT) + _gldDestroyPrimitiveBuffer(&gld->PB3d); +// if (gld->PBtwosidelight.dwPool == D3DPOOL_DEFAULT) +// _gldDestroyPrimitiveBuffer(&gld->PBtwosidelight); + + // Clear the presentation parameters (sets all members to zero) + ZeroMemory(&d3dpp, sizeof(d3dpp)); + + // Recommended by MS; needed for MultiSample. + // Be careful if altering this for FullScreenBlit + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + + d3dpp.BackBufferFormat = d3ddm.Format; + d3dpp.BackBufferCount = 1; + d3dpp.MultiSampleType = _gldGetDeviceMultiSampleType(gld->pD3D, d3ddm.Format, d3dDevType, !ctx->bFullscreen); + d3dpp.AutoDepthStencilFormat = ctx->lpPF->dwDriverData; + d3dpp.EnableAutoDepthStencil = (d3dpp.AutoDepthStencilFormat == D3DFMT_UNKNOWN) ? FALSE : TRUE; + + // TODO: Sync to refresh + + if (ctx->bFullscreen) { + ddlogWarnOption(FALSE); // Don't popup any messages in fullscreen + d3dpp.Windowed = FALSE; + d3dpp.BackBufferWidth = d3ddm.Width; + d3dpp.BackBufferHeight = d3ddm.Height; + d3dpp.hDeviceWindow = ctx->hWnd; + d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; + d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; + // Get better benchmark results? KeithH +// d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_UNLIMITED; + } else { + ddlogWarnOption(glb.bMessageBoxWarnings); // OK to popup messages + d3dpp.Windowed = TRUE; + d3dpp.BackBufferWidth = ctx->dwWidth; + d3dpp.BackBufferHeight = ctx->dwHeight; + d3dpp.hDeviceWindow = ctx->hWnd; + d3dpp.FullScreen_RefreshRateInHz = 0; + d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; + } + hResult = IDirect3DDevice8_Reset(gld->pDev, &d3dpp); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: Reset failed", hResult); + return FALSE; + //goto cleanup_and_return_with_error; + } + + // Explicitly Clear resized surfaces (DaveM) + { + D3DVIEWPORT8 d3dvp1, d3dvp2; + IDirect3DDevice8_GetViewport(gld->pDev, &d3dvp1); + IDirect3DDevice8_GetViewport(gld->pDev, &d3dvp2); + d3dvp1.X = 0; + d3dvp1.Y = 0; + d3dvp1.Width = ctx->dwWidth; + d3dvp1.Height = ctx->dwHeight; + IDirect3DDevice8_SetViewport(gld->pDev, &d3dvp1); + IDirect3DDevice8_Clear(gld->pDev,0,NULL,D3DCLEAR_TARGET,0,0,0); + IDirect3DDevice8_SetViewport(gld->pDev, &d3dvp2); + } + + // + // Recreate POOL_DEFAULT objects + // + if (gld->PB2d.dwPool == D3DPOOL_DEFAULT) { + _gldCreatePrimitiveBuffer(ctx->glCtx, gld, &gld->PB2d); + } + if (gld->PB3d.dwPool == D3DPOOL_DEFAULT) { + _gldCreatePrimitiveBuffer(ctx->glCtx, gld, &gld->PB3d); + } +// if (gld->PBtwosidelight.dwPool == D3DPOOL_DEFAULT) { +// _gldCreatePrimitiveBuffer(ctx->glCtx, gld, &gld->PB2d); +// } + + // Recreate DX8 Vertex Shaders +// _gldCreateVertexShaders(gld); + + // Signal a complete state update + ctx->glCtx->Driver.UpdateState(ctx->glCtx, _NEW_ALL); + + // Begin a new scene + IDirect3DDevice8_BeginScene(gld->pDev); + ctx->bSceneStarted = TRUE; + + return TRUE; +} + +//--------------------------------------------------------------------------- + +BOOL gldDestroyDrawable_DX( + DGL_ctx *ctx) +{ + GLD_driver_dx8 *lpCtx = NULL; + + // Error if context is NULL. + if (!ctx) + return FALSE; + + // Error if the drawable does not exist. + if (!ctx->glPriv) + return FALSE; + + lpCtx = ctx->glPriv; + +#ifdef _DEBUG + // Dump out stats + ddlogPrintf(DDLOG_SYSTEM, "Usage: M:0x%X%X, D:0x%X%X", + lpCtx->PipelineUsage.qwMesa.HighPart, + lpCtx->PipelineUsage.qwMesa.LowPart, + lpCtx->PipelineUsage.qwD3DFVF.HighPart, + lpCtx->PipelineUsage.qwD3DFVF.LowPart); +#endif + +// _gldDestroyVertexShaders(lpCtx); + +// _gldDestroyPrimitiveBuffer(&lpCtx->PBtwosidelight); + _gldDestroyPrimitiveBuffer(&lpCtx->PB3d); + _gldDestroyPrimitiveBuffer(&lpCtx->PB2d); + + SAFE_RELEASE(lpCtx->pDev); + SAFE_RELEASE(lpCtx->pD3D); + + // Free the private drawable data + free(ctx->glPriv); + ctx->glPriv = NULL; + + return TRUE; +} + +//--------------------------------------------------------------------------- + +BOOL gldCreatePrivateGlobals_DX(void) +{ + ZeroMemory(&dx8Globals, sizeof(dx8Globals)); + + // Load d3d8.dll + dx8Globals.hD3D8DLL = LoadLibrary("D3D8.DLL"); + if (dx8Globals.hD3D8DLL == NULL) + return FALSE; + + // Now try and obtain Direct3DCreate8 + dx8Globals.fnDirect3DCreate8 = (FNDIRECT3DCREATE8)GetProcAddress(dx8Globals.hD3D8DLL, "Direct3DCreate8"); + if (dx8Globals.fnDirect3DCreate8 == NULL) { + FreeLibrary(dx8Globals.hD3D8DLL); + return FALSE; + } + + return TRUE; +} + +//--------------------------------------------------------------------------- + +BOOL gldDestroyPrivateGlobals_DX(void) +{ + if (dx8Globals.bDirect3DDevice) { + SAFE_RELEASE(dx8Globals.pDev); + dx8Globals.bDirect3DDevice = FALSE; + } + if (dx8Globals.bDirect3D) { + SAFE_RELEASE(dx8Globals.pD3D); + dx8Globals.bDirect3D = FALSE; + } + + FreeLibrary(dx8Globals.hD3D8DLL); + dx8Globals.hD3D8DLL = NULL; + dx8Globals.fnDirect3DCreate8 = NULL; + + return TRUE; +} + +//--------------------------------------------------------------------------- + +static void _BitsFromDisplayFormat( + D3DFORMAT fmt, + BYTE *cColorBits, + BYTE *cRedBits, + BYTE *cGreenBits, + BYTE *cBlueBits, + BYTE *cAlphaBits) +{ + switch (fmt) { + case D3DFMT_X1R5G5B5: + *cColorBits = 16; + *cRedBits = 5; + *cGreenBits = 5; + *cBlueBits = 5; + *cAlphaBits = 0; + return; + case D3DFMT_R5G6B5: + *cColorBits = 16; + *cRedBits = 5; + *cGreenBits = 6; + *cBlueBits = 5; + *cAlphaBits = 0; + return; + case D3DFMT_X8R8G8B8: + *cColorBits = 32; + *cRedBits = 8; + *cGreenBits = 8; + *cBlueBits = 8; + *cAlphaBits = 0; + return; + case D3DFMT_A8R8G8B8: + *cColorBits = 32; + *cRedBits = 8; + *cGreenBits = 8; + *cBlueBits = 8; + *cAlphaBits = 8; + return; + } + + // Should not get here! + *cColorBits = 32; + *cRedBits = 8; + *cGreenBits = 8; + *cBlueBits = 8; + *cAlphaBits = 0; +} + +//--------------------------------------------------------------------------- + +static void _BitsFromDepthStencilFormat( + D3DFORMAT fmt, + BYTE *cDepthBits, + BYTE *cStencilBits) +{ + // NOTE: GL expects either 32 or 16 as depth bits. + switch (fmt) { + case D3DFMT_D32: + *cDepthBits = 32; + *cStencilBits = 0; + return; + case D3DFMT_D15S1: + *cDepthBits = 16; + *cStencilBits = 1; + return; + case D3DFMT_D24S8: + *cDepthBits = 32; + *cStencilBits = 8; + return; + case D3DFMT_D16: + *cDepthBits = 16; + *cStencilBits = 0; + return; + case D3DFMT_D24X8: + *cDepthBits = 32; + *cStencilBits = 0; + return; + case D3DFMT_D24X4S4: + *cDepthBits = 32; + *cStencilBits = 4; + return; + } +} + +//--------------------------------------------------------------------------- + +BOOL gldBuildPixelformatList_DX(void) +{ + D3DDISPLAYMODE d3ddm; + D3DFORMAT fmt[6]; + IDirect3D8 *pD3D = NULL; + HRESULT hr; + int nSupportedFormats = 0; + int i; + DGL_pixelFormat *pPF; + BYTE cColorBits, cRedBits, cGreenBits, cBlueBits, cAlphaBits; +// char buf[128]; +// char cat[8]; + + // Direct3D (SW or HW) + // These are arranged so that 'best' pixelformat + // is higher in the list (for ChoosePixelFormat). + const D3DFORMAT DepthStencil[6] = { + D3DFMT_D15S1, + D3DFMT_D16, + D3DFMT_D24X8, + D3DFMT_D24X4S4, + D3DFMT_D24S8, + D3DFMT_D32, + }; + + // Dump DX version + ddlogMessage(GLDLOG_SYSTEM, "DirectX Version : 8.0\n"); + + // Release any existing pixelformat list + if (glb.lpPF) { + free(glb.lpPF); + } + + glb.nPixelFormatCount = 0; + glb.lpPF = NULL; + + // + // Pixelformats for Direct3D (SW or HW) rendering + // + + // Get a Direct3D 8.0 interface + pD3D = dx8Globals.fnDirect3DCreate8(D3D_SDK_VERSION_DX8_SUPPORT_WIN95); + if (!pD3D) { + return FALSE; + } + + // We will use the display mode format when finding compliant + // rendertarget/depth-stencil surfaces. + hr = IDirect3D8_GetAdapterDisplayMode(pD3D, glb.dwAdapter, &d3ddm); + if (FAILED(hr)) { + IDirect3D8_Release(pD3D); + return FALSE; + } + + // Run through the possible formats and detect supported formats + for (i=0; i<6; i++) { + hr = IDirect3D8_CheckDeviceFormat( + pD3D, + glb.dwAdapter, + glb.dwDriver==GLDS_DRIVER_HAL ? D3DDEVTYPE_HAL : D3DDEVTYPE_REF, + d3ddm.Format, + D3DUSAGE_DEPTHSTENCIL, + D3DRTYPE_SURFACE, + DepthStencil[i]); + if (FAILED(hr)) + // A failure here is not fatal. + continue; + + // Verify that the depth format is compatible. + hr = IDirect3D8_CheckDepthStencilMatch( + pD3D, + glb.dwAdapter, + glb.dwDriver==GLDS_DRIVER_HAL ? D3DDEVTYPE_HAL : D3DDEVTYPE_REF, + d3ddm.Format, + d3ddm.Format, + DepthStencil[i]); + if (FAILED(hr)) + // A failure here is not fatal, just means depth-stencil + // format is not compatible with this display mode. + continue; + + fmt[nSupportedFormats++] = DepthStencil[i]; + } + + IDirect3D8_Release(pD3D); + + if (nSupportedFormats == 0) + return FALSE; // Bail: no compliant pixelformats + + // Total count of pixelformats is: + // (nSupportedFormats+1)*2 + glb.lpPF = (DGL_pixelFormat *)calloc((nSupportedFormats)*2, sizeof(DGL_pixelFormat)); + glb.nPixelFormatCount = (nSupportedFormats)*2; + if (glb.lpPF == NULL) { + glb.nPixelFormatCount = 0; + return FALSE; + } + + // Get a copy of pointer that we can alter + pPF = glb.lpPF; + + // Cache colour bits from display format + _BitsFromDisplayFormat(d3ddm.Format, &cColorBits, &cRedBits, &cGreenBits, &cBlueBits, &cAlphaBits); + + // + // Add single-buffer formats + // + + // Single-buffer, no depth-stencil buffer +/* memcpy(pPF, &pfTemplateHW, sizeof(DGL_pixelFormat)); + pPF->pfd.dwFlags &= ~PFD_DOUBLEBUFFER; // Remove doublebuffer flag + pPF->pfd.cColorBits = cColorBits; + pPF->pfd.cRedBits = cRedBits; + pPF->pfd.cGreenBits = cGreenBits; + pPF->pfd.cBlueBits = cBlueBits; + pPF->pfd.cAlphaBits = cAlphaBits; + pPF->pfd.cDepthBits = 0; + pPF->pfd.cStencilBits = 0; + pPF->dwDriverData = D3DFMT_UNKNOWN; + pPF++;*/ + + for (i=0; ipfd.dwFlags &= ~PFD_DOUBLEBUFFER; // Remove doublebuffer flag + pPF->pfd.cColorBits = cColorBits; + pPF->pfd.cRedBits = cRedBits; + pPF->pfd.cGreenBits = cGreenBits; + pPF->pfd.cBlueBits = cBlueBits; + pPF->pfd.cAlphaBits = cAlphaBits; + _BitsFromDepthStencilFormat(fmt[i], &pPF->pfd.cDepthBits, &pPF->pfd.cStencilBits); + pPF->dwDriverData = fmt[i]; + } + + // + // Add double-buffer formats + // + +/* memcpy(pPF, &pfTemplateHW, sizeof(DGL_pixelFormat)); + pPF->pfd.cColorBits = cColorBits; + pPF->pfd.cRedBits = cRedBits; + pPF->pfd.cGreenBits = cGreenBits; + pPF->pfd.cBlueBits = cBlueBits; + pPF->pfd.cAlphaBits = cAlphaBits; + pPF->pfd.cDepthBits = 0; + pPF->pfd.cStencilBits = 0; + pPF->dwDriverData = D3DFMT_UNKNOWN; + pPF++;*/ + + for (i=0; ipfd.cColorBits = cColorBits; + pPF->pfd.cRedBits = cRedBits; + pPF->pfd.cGreenBits = cGreenBits; + pPF->pfd.cBlueBits = cBlueBits; + pPF->pfd.cAlphaBits = cAlphaBits; + _BitsFromDepthStencilFormat(fmt[i], &pPF->pfd.cDepthBits, &pPF->pfd.cStencilBits); + pPF->dwDriverData = fmt[i]; + } + + // Popup warning message if non RGB color mode + { + // This is a hack. KeithH + HDC hdcDesktop = GetDC(NULL); + DWORD dwDisplayBitDepth = GetDeviceCaps(hdcDesktop, BITSPIXEL); + ReleaseDC(0, hdcDesktop); + if (dwDisplayBitDepth <= 8) { + ddlogPrintf(DDLOG_WARN, "Current Color Depth %d bpp is not supported", dwDisplayBitDepth); + MessageBox(NULL, szColorDepthWarning, "GLDirect", MB_OK | MB_ICONWARNING); + } + } + + // Mark list as 'current' + glb.bPixelformatsDirty = FALSE; + + return TRUE; +} + +//--------------------------------------------------------------------------- + +BOOL gldInitialiseMesa_DX( + DGL_ctx *lpCtx) +{ + GLD_driver_dx8 *gld = NULL; + int MaxTextureSize, TextureLevels; + BOOL bSoftwareTnL; + + if (lpCtx == NULL) + return FALSE; + + gld = lpCtx->glPriv; + if (gld == NULL) + return FALSE; + + if (glb.bMultitexture) { + lpCtx->glCtx->Const.MaxTextureUnits = gld->d3dCaps8.MaxSimultaneousTextures; + // Only support MAX_TEXTURE_UNITS texture units. + // ** If this is altered then the FVF formats must be reviewed **. + if (lpCtx->glCtx->Const.MaxTextureUnits > GLD_MAX_TEXTURE_UNITS_DX8) + lpCtx->glCtx->Const.MaxTextureUnits = GLD_MAX_TEXTURE_UNITS_DX8; + } else { + // Multitexture override + lpCtx->glCtx->Const.MaxTextureUnits = 1; + } + + // max texture size + MaxTextureSize = min(gld->d3dCaps8.MaxTextureHeight, gld->d3dCaps8.MaxTextureWidth); + if (MaxTextureSize == 0) + MaxTextureSize = 256; // Sanity check + + // + // HACK!! + if (MaxTextureSize > 1024) + MaxTextureSize = 1024; // HACK - CLAMP TO 1024 + // HACK!! + // + + // Got to set MAX_TEXTURE_SIZE as max levels. + // Who thought this stupid idea up? ;) + TextureLevels = 0; + // Calculate power-of-two. + while (MaxTextureSize) { + TextureLevels++; + MaxTextureSize >>= 1; + } + lpCtx->glCtx->Const.MaxTextureLevels = (TextureLevels) ? TextureLevels : 8; + lpCtx->glCtx->Const.MaxDrawBuffers = 1; + + IDirect3DDevice8_SetRenderState(gld->pDev, D3DRS_LIGHTING, FALSE); + IDirect3DDevice8_SetRenderState(gld->pDev, D3DRS_CULLMODE, D3DCULL_NONE); + IDirect3DDevice8_SetRenderState(gld->pDev, D3DRS_DITHERENABLE, TRUE); + IDirect3DDevice8_SetRenderState(gld->pDev, D3DRS_SHADEMODE, D3DSHADE_GOURAUD); + + IDirect3DDevice8_SetRenderState(gld->pDev, D3DRS_ZENABLE, + (lpCtx->lpPF->dwDriverData!=D3DFMT_UNKNOWN) ? D3DZB_TRUE : D3DZB_FALSE); + + // Set the view matrix + { + D3DXMATRIX vm; +#if 1 + D3DXMatrixIdentity(&vm); +#else + D3DXVECTOR3 Eye(0.0f, 0.0f, 0.0f); + D3DXVECTOR3 At(0.0f, 0.0f, -1.0f); + D3DXVECTOR3 Up(0.0f, 1.0f, 0.0f); + D3DXMatrixLookAtRH(&vm, &Eye, &At, &Up); + vm._31 = -vm._31; + vm._32 = -vm._32; + vm._33 = -vm._33; + vm._34 = -vm._34; +#endif + IDirect3DDevice8_SetTransform(gld->pDev, D3DTS_VIEW, &vm); + } + + if (gld->bHasHWTnL) { + if (glb.dwTnL == GLDS_TNL_DEFAULT) + bSoftwareTnL = FALSE; // HW TnL + else { + bSoftwareTnL = ((glb.dwTnL == GLDS_TNL_MESA) || (glb.dwTnL == GLDS_TNL_D3DSW)) ? TRUE : FALSE; + } + } else { + // No HW TnL, so no choice possible + bSoftwareTnL = TRUE; + } + IDirect3DDevice8_SetRenderState(gld->pDev, D3DRS_SOFTWAREVERTEXPROCESSING, bSoftwareTnL); + +// Dump this in a Release build as well, now. +//#ifdef _DEBUG + ddlogPrintf(DDLOG_INFO, "HW TnL: %s", + gld->bHasHWTnL ? (bSoftwareTnL ? "Disabled" : "Enabled") : "Unavailable"); +//#endif + + gldEnableExtensions_DX8(lpCtx->glCtx); + gldInstallPipeline_DX8(lpCtx->glCtx); + gldSetupDriverPointers_DX8(lpCtx->glCtx); + + // Signal a complete state update + lpCtx->glCtx->Driver.UpdateState(lpCtx->glCtx, _NEW_ALL); + + // Start a scene + IDirect3DDevice8_BeginScene(gld->pDev); + lpCtx->bSceneStarted = TRUE; + + return TRUE; +} + +//--------------------------------------------------------------------------- + +BOOL gldSwapBuffers_DX( + DGL_ctx *ctx, + HDC hDC, + HWND hWnd) +{ + HRESULT hr; + GLD_driver_dx8 *gld = NULL; + + if (ctx == NULL) + return FALSE; + + gld = ctx->glPriv; + if (gld == NULL) + return FALSE; + + if (ctx->bSceneStarted) { + IDirect3DDevice8_EndScene(gld->pDev); + ctx->bSceneStarted = FALSE; + } + + // Swap the buffers. hWnd may override the hWnd used for CreateDevice() + hr = IDirect3DDevice8_Present(gld->pDev, NULL, NULL, hWnd, NULL); + + IDirect3DDevice8_BeginScene(gld->pDev); + ctx->bSceneStarted = TRUE; + + return (FAILED(hr)) ? FALSE : TRUE; +} + +//--------------------------------------------------------------------------- + +BOOL gldGetDisplayMode_DX( + DGL_ctx *ctx, + GLD_displayMode *glddm) +{ + D3DDISPLAYMODE d3ddm; + HRESULT hr; + GLD_driver_dx8 *lpCtx = NULL; + BYTE cColorBits, cRedBits, cGreenBits, cBlueBits, cAlphaBits; + + if ((glddm == NULL) || (ctx == NULL)) + return FALSE; + + lpCtx = ctx->glPriv; + if (lpCtx == NULL) + return FALSE; + + if (lpCtx->pD3D == NULL) + return FALSE; + + hr = IDirect3D8_GetAdapterDisplayMode(lpCtx->pD3D, glb.dwAdapter, &d3ddm); + if (FAILED(hr)) + return FALSE; + + // Get info from the display format + _BitsFromDisplayFormat(d3ddm.Format, + &cColorBits, &cRedBits, &cGreenBits, &cBlueBits, &cAlphaBits); + + glddm->Width = d3ddm.Width; + glddm->Height = d3ddm.Height; + glddm->BPP = cColorBits; + glddm->Refresh = d3ddm.RefreshRate; + + return TRUE; +} + +//--------------------------------------------------------------------------- + diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_driver_dx9.c b/mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_driver_dx9.c new file mode 100644 index 000000000..c191564d6 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_driver_dx9.c @@ -0,0 +1,1206 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x/2000/XP/XBox (Win32) +* +* Description: Driver interface code to Mesa +* +****************************************************************************/ + +//#include +#include "dglcontext.h" +#include "ddlog.h" +#include "gld_dx9.h" + +#include "glheader.h" +#include "context.h" +#include "colormac.h" +#include "depth.h" +#include "extensions.h" +#include "macros.h" +#include "matrix.h" +// #include "mem.h" +//#include "mmath.h" +#include "mtypes.h" +#include "texformat.h" +#include "teximage.h" +#include "texstore.h" +#include "vbo/vbo.h" +#include "swrast_setup/swrast_setup.h" +#include "swrast_setup/ss_context.h" +#include "tnl/tnl.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" + +extern BOOL dglSwapBuffers(HDC hDC); + +// HACK: Hack the _33 member of the OpenGL perspective projection matrix +const float _fPersp_33 = 1.6f; + +//--------------------------------------------------------------------------- +// Internal functions +//--------------------------------------------------------------------------- + +void _gld_mesa_warning( + __GLcontext *gc, + char *str) +{ + // Intercept Mesa's internal warning mechanism + gldLogPrintf(GLDLOG_WARN, "Mesa warning: %s", str); +} + +//--------------------------------------------------------------------------- + +void _gld_mesa_fatal( + __GLcontext *gc, + char *str) +{ + // Intercept Mesa's internal fatal-message mechanism + gldLogPrintf(GLDLOG_CRITICAL, "Mesa FATAL: %s", str); + + // Mesa calls abort(0) here. + ddlogClose(); + exit(0); +} + +//--------------------------------------------------------------------------- + +D3DSTENCILOP _gldConvertStencilOp( + GLenum StencilOp) +{ + // Used by Stencil: pass, fail and zfail + + switch (StencilOp) { + case GL_KEEP: + return D3DSTENCILOP_KEEP; + case GL_ZERO: + return D3DSTENCILOP_ZERO; + case GL_REPLACE: + return D3DSTENCILOP_REPLACE; + case GL_INCR: + return D3DSTENCILOP_INCRSAT; + case GL_DECR: + return D3DSTENCILOP_DECRSAT; + case GL_INVERT: + return D3DSTENCILOP_INVERT; + case GL_INCR_WRAP_EXT: // GL_EXT_stencil_wrap + return D3DSTENCILOP_INCR; + case GL_DECR_WRAP_EXT: // GL_EXT_stencil_wrap + return D3DSTENCILOP_DECR; + } + +#ifdef _DEBUG + gldLogMessage(GLDLOG_ERROR, "_gldConvertStencilOp: Unknown StencilOp\n"); +#endif + + return D3DSTENCILOP_KEEP; +} + +//--------------------------------------------------------------------------- + +D3DCMPFUNC _gldConvertCompareFunc( + GLenum CmpFunc) +{ + // Used for Alpha func, depth func and stencil func. + + switch (CmpFunc) { + case GL_NEVER: + return D3DCMP_NEVER; + case GL_LESS: + return D3DCMP_LESS; + case GL_EQUAL: + return D3DCMP_EQUAL; + case GL_LEQUAL: + return D3DCMP_LESSEQUAL; + case GL_GREATER: + return D3DCMP_GREATER; + case GL_NOTEQUAL: + return D3DCMP_NOTEQUAL; + case GL_GEQUAL: + return D3DCMP_GREATEREQUAL; + case GL_ALWAYS: + return D3DCMP_ALWAYS; + }; + +#ifdef _DEBUG + gldLogMessage(GLDLOG_ERROR, "_gldConvertCompareFunc: Unknown CompareFunc\n"); +#endif + + return D3DCMP_ALWAYS; +} + +//--------------------------------------------------------------------------- + +D3DBLEND _gldConvertBlendFunc( + GLenum blend, + GLenum DefaultBlend) +{ + switch (blend) { + case GL_ZERO: + return D3DBLEND_ZERO; + case GL_ONE: + return D3DBLEND_ONE; + case GL_DST_COLOR: + return D3DBLEND_DESTCOLOR; + case GL_SRC_COLOR: + return D3DBLEND_SRCCOLOR; + case GL_ONE_MINUS_DST_COLOR: + return D3DBLEND_INVDESTCOLOR; + case GL_ONE_MINUS_SRC_COLOR: + return D3DBLEND_INVSRCCOLOR; + case GL_SRC_ALPHA: + return D3DBLEND_SRCALPHA; + case GL_ONE_MINUS_SRC_ALPHA: + return D3DBLEND_INVSRCALPHA; + case GL_DST_ALPHA: + return D3DBLEND_DESTALPHA; + case GL_ONE_MINUS_DST_ALPHA: + return D3DBLEND_INVDESTALPHA; + case GL_SRC_ALPHA_SATURATE: + return D3DBLEND_SRCALPHASAT; + } + +#ifdef _DEBUG + gldLogMessage(GLDLOG_ERROR, "_gldConvertBlendFunc: Unknown BlendFunc\n"); +#endif + + return DefaultBlend; +} + +//--------------------------------------------------------------------------- +// Misc. functions +//--------------------------------------------------------------------------- + +void gld_Noop_DX9( + GLcontext *ctx) +{ +#ifdef _DEBUG + gldLogMessage(GLDLOG_ERROR, "gld_Noop called!\n"); +#endif +} + +//--------------------------------------------------------------------------- + +void gld_Error_DX9( + GLcontext *ctx) +{ +#ifdef _DEBUG + // Quite useless. +// gldLogMessage(GLDLOG_ERROR, "ctx->Driver.Error called!\n"); +#endif +} + +//--------------------------------------------------------------------------- +// Required Mesa functions +//--------------------------------------------------------------------------- + +static GLboolean gld_set_draw_buffer_DX9( + GLcontext *ctx, + GLenum mode) +{ + (void) ctx; + if ((mode==GL_FRONT_LEFT) || (mode == GL_BACK_LEFT)) { + return GL_TRUE; + } + else { + return GL_FALSE; + } +} + +//--------------------------------------------------------------------------- + +static void gld_set_read_buffer_DX9( + GLcontext *ctx, + GLframebuffer *buffer, + GLenum mode) +{ + /* separate read buffer not supported */ +/* + ASSERT(buffer == ctx->DrawBuffer); + ASSERT(mode == GL_FRONT_LEFT); +*/ +} + +//--------------------------------------------------------------------------- + +void gld_Clear_DX9( + GLcontext *ctx, + GLbitfield mask, + GLboolean all, + GLint x, + GLint y, + GLint width, + GLint height) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); + + DWORD dwFlags = 0; + D3DCOLOR Color = 0; + float Z = 0.0f; + DWORD Stencil = 0; + D3DRECT d3dClearRect; + + // TODO: Colourmask + const GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask; + + if (!gld->pDev) + return; + + if (mask & (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT)) { + GLubyte col[4]; + CLAMPED_FLOAT_TO_UBYTE(col[0], ctx->Color.ClearColor[0]); + CLAMPED_FLOAT_TO_UBYTE(col[1], ctx->Color.ClearColor[1]); + CLAMPED_FLOAT_TO_UBYTE(col[2], ctx->Color.ClearColor[2]); + CLAMPED_FLOAT_TO_UBYTE(col[3], ctx->Color.ClearColor[3]); + dwFlags |= D3DCLEAR_TARGET; + Color = D3DCOLOR_RGBA(col[0], col[1], col[2], col[3]); + } + + if (mask & DD_DEPTH_BIT) { + // D3D8 will fail the Clear call if we try and clear a + // depth buffer and we haven't created one. + // Also, some apps try and clear a depth buffer, + // when a depth buffer hasn't been requested by the app. + if (ctx->Visual.depthBits == 0) { + mask &= ~DD_DEPTH_BIT; // Remove depth bit from mask + } else { + dwFlags |= D3DCLEAR_ZBUFFER; + Z = ctx->Depth.Clear; + } + } + + if (mask & DD_STENCIL_BIT) { + if (ctx->Visual.stencilBits == 0) { + // No stencil bits in depth buffer + mask &= ~DD_STENCIL_BIT; // Remove stencil bit from mask + } else { + dwFlags |= D3DCLEAR_STENCIL; + Stencil = ctx->Stencil.Clear; + } + } + + // Some apps do really weird things with the rect, such as Quake3. + if ((x < 0) || (y < 0) || (width <= 0) || (height <= 0)) { + all = GL_TRUE; + } + + if (!all) { + // Calculate clear subrect + d3dClearRect.x1 = x; + d3dClearRect.y1 = gldCtx->dwHeight - (y + height); + d3dClearRect.x2 = x + width; + d3dClearRect.y2 = d3dClearRect.y1 + height; +// gldLogPrintf(GLDLOG_INFO, "Rect %d,%d %d,%d", x,y,width,height); + } + + // dwFlags will be zero if there's nothing to clear + if (dwFlags) { + _GLD_DX9_DEV(Clear( + gld->pDev, + all ? 0 : 1, + all ? NULL : &d3dClearRect, + dwFlags, + Color, Z, Stencil)); + } + + if (mask & DD_ACCUM_BIT) { + // Clear accumulation buffer + } +} + +//--------------------------------------------------------------------------- + +// Mesa 5: Parameter change +static void gld_buffer_size_DX9( +// GLcontext *ctx, + GLframebuffer *fb, + GLuint *width, + GLuint *height) +{ +// GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + + *width = fb->Width; // gldCtx->dwWidth; + *height = fb->Height; // gldCtx->dwHeight; +} + +//--------------------------------------------------------------------------- + +static void gld_Finish_DX9( + GLcontext *ctx) +{ +} + +//--------------------------------------------------------------------------- + +static void gld_Flush_DX9( + GLcontext *ctx) +{ + GLD_context *gld = GLD_GET_CONTEXT(ctx); + + // TODO: Detect apps that glFlush() then SwapBuffers() ? + + if (gld->EmulateSingle) { + // Emulating a single-buffered context. + // [Direct3D doesn't allow rendering to front buffer] + dglSwapBuffers(gld->hDC); + } +} + +//--------------------------------------------------------------------------- + +void gld_NEW_STENCIL( + GLcontext *ctx) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); + + // Two-sided stencil. New for Mesa 5 + const GLuint uiFace = 0UL; + + struct gl_stencil_attrib *pStencil = &ctx->Stencil; + + _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILENABLE, pStencil->Enabled ? TRUE : FALSE)); + if (pStencil->Enabled) { + _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILFUNC, _gldConvertCompareFunc(pStencil->Function[uiFace]))); + _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILREF, pStencil->Ref[uiFace])); + _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILMASK, pStencil->ValueMask[uiFace])); + _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILWRITEMASK, pStencil->WriteMask[uiFace])); + _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILFAIL, _gldConvertStencilOp(pStencil->FailFunc[uiFace]))); + _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILZFAIL, _gldConvertStencilOp(pStencil->ZFailFunc[uiFace]))); + _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_STENCILPASS, _gldConvertStencilOp(pStencil->ZPassFunc[uiFace]))); + } +} + +//--------------------------------------------------------------------------- + +void gld_NEW_COLOR( + GLcontext *ctx) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); + + DWORD dwFlags = 0; + D3DBLEND src; + D3DBLEND dest; + + // Alpha func + _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_ALPHAFUNC, _gldConvertCompareFunc(ctx->Color.AlphaFunc))); + _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_ALPHAREF, (DWORD)ctx->Color.AlphaRef)); + _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_ALPHATESTENABLE, ctx->Color.AlphaEnabled)); + + // Blend func + _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_ALPHABLENDENABLE, ctx->Color.BlendEnabled)); + src = _gldConvertBlendFunc(ctx->Color.BlendSrcRGB, GL_ONE); + dest = _gldConvertBlendFunc(ctx->Color.BlendDstRGB, GL_ZERO); + _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_SRCBLEND, src)); + _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_DESTBLEND, dest)); + + // Color mask + if (ctx->Color.ColorMask[0]) dwFlags |= D3DCOLORWRITEENABLE_RED; + if (ctx->Color.ColorMask[1]) dwFlags |= D3DCOLORWRITEENABLE_GREEN; + if (ctx->Color.ColorMask[2]) dwFlags |= D3DCOLORWRITEENABLE_BLUE; + if (ctx->Color.ColorMask[3]) dwFlags |= D3DCOLORWRITEENABLE_ALPHA; + _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_COLORWRITEENABLE, dwFlags)); +} + +//--------------------------------------------------------------------------- + +void gld_NEW_DEPTH( + GLcontext *ctx) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); + + _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_ZENABLE, ctx->Depth.Test ? D3DZB_TRUE : D3DZB_FALSE)); + _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_ZFUNC, _gldConvertCompareFunc(ctx->Depth.Func))); + _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_ZWRITEENABLE, ctx->Depth.Mask ? TRUE : FALSE)); +} + +//--------------------------------------------------------------------------- + +void gld_NEW_POLYGON( + GLcontext *ctx) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); + + D3DFILLMODE d3dFillMode = D3DFILL_SOLID; + D3DCULL d3dCullMode = D3DCULL_NONE; + float fOffset = 0; // Changed from int to float for DX9 + + // Fillmode + switch (ctx->Polygon.FrontMode) { + case GL_POINT: + d3dFillMode = D3DFILL_POINT; + break; + case GL_LINE: + d3dFillMode = D3DFILL_WIREFRAME; + break; + case GL_FILL: + d3dFillMode = D3DFILL_SOLID; + break; + } + _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FILLMODE, d3dFillMode)); + + if (ctx->Polygon.CullFlag) { + switch (ctx->Polygon.CullFaceMode) { + case GL_BACK: + if (ctx->Polygon.FrontFace == GL_CCW) + d3dCullMode = D3DCULL_CW; + else + d3dCullMode = D3DCULL_CCW; + break; + case GL_FRONT: + if (ctx->Polygon.FrontFace == GL_CCW) + d3dCullMode = D3DCULL_CCW; + else + d3dCullMode = D3DCULL_CW; + break; + case GL_FRONT_AND_BACK: + d3dCullMode = D3DCULL_NONE; + break; + default: + break; + } + } else { + d3dCullMode = D3DCULL_NONE; + } +// d3dCullMode = D3DCULL_NONE; // FOR DEBUGGING + _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_CULLMODE, d3dCullMode)); + + // Polygon offset + // ZBIAS ranges from 0 to 16 and can only move towards the viewer + // Mesa5: ctx->Polygon._OffsetAny removed + if (ctx->Polygon.OffsetFill) { + fOffset = ctx->Polygon.OffsetUnits; +// if (iOffset < 0.0f) +// iOffset = -iOffset; +// else +// iOffset = 0.0f; // D3D can't push away + } + // NOTE: SetRenderState() required a DWORD, so need to cast + _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_DEPTHBIAS, *((DWORD*)&fOffset))); +} + +//--------------------------------------------------------------------------- + +void gld_NEW_FOG( + GLcontext *ctx) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); + + D3DCOLOR d3dFogColour; + D3DFOGMODE d3dFogMode = D3DFOG_LINEAR; + + // TODO: Fog is calculated seperately in the Mesa pipeline + _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGENABLE, FALSE)); + return; + + // Fog enable + _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGENABLE, ctx->Fog.Enabled)); + if (!ctx->Fog.Enabled) { + _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGTABLEMODE, D3DFOG_NONE)); + _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGVERTEXMODE, D3DFOG_NONE)); + return; // If disabled, don't bother setting any fog state + } + + // Fog colour + d3dFogColour = D3DCOLOR_COLORVALUE( ctx->Fog.Color[0], + ctx->Fog.Color[1], + ctx->Fog.Color[2], + ctx->Fog.Color[3]); + _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGCOLOR, d3dFogColour)); + + // Fog density + _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGDENSITY, *((DWORD*) (&ctx->Fog.Density)))); + + // Fog start + _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGSTART, *((DWORD*) (&ctx->Fog.Start)))); + + // Fog end + _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGEND, *((DWORD*) (&ctx->Fog.End)))); + + // Fog mode + switch (ctx->Fog.Mode) { + case GL_LINEAR: + d3dFogMode = D3DFOG_LINEAR; + break; + case GL_EXP: + d3dFogMode = D3DFOG_EXP; + break; + case GL_EXP2: + d3dFogMode = D3DFOG_EXP2; + break; + } + _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGTABLEMODE, d3dFogMode)); + _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_FOGVERTEXMODE, D3DFOG_NONE)); +} + +//--------------------------------------------------------------------------- + +void gld_NEW_LIGHT( + GLcontext *ctx) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); + DWORD dwSpecularEnable; + + // Shademode + _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_SHADEMODE, (ctx->Light.ShadeModel == GL_SMOOTH) ? D3DSHADE_GOURAUD : D3DSHADE_FLAT)); + + // Separate specular colour + if (ctx->Light.Enabled) + dwSpecularEnable = (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) ? TRUE: FALSE; + else + dwSpecularEnable = FALSE; + _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_SPECULARENABLE, dwSpecularEnable)); +} + +//--------------------------------------------------------------------------- + +void gld_NEW_MODELVIEW( + GLcontext *ctx) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); + + D3DMATRIX m; + //GLfloat *pM = ctx->ModelView.m; + // Mesa5: Model-view is now a stack + GLfloat *pM = ctx->ModelviewMatrixStack.Top->m; + m._11 = pM[0]; + m._12 = pM[1]; + m._13 = pM[2]; + m._14 = pM[3]; + m._21 = pM[4]; + m._22 = pM[5]; + m._23 = pM[6]; + m._24 = pM[7]; + m._31 = pM[8]; + m._32 = pM[9]; + m._33 = pM[10]; + m._34 = pM[11]; + m._41 = pM[12]; + m._42 = pM[13]; + m._43 = pM[14]; + m._44 = pM[15]; + + gld->matModelView = m; +} + +//--------------------------------------------------------------------------- + +void gld_NEW_PROJECTION( + GLcontext *ctx) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); + + D3DMATRIX m; + //GLfloat *pM = ctx->ProjectionMatrix.m; + // Mesa 5: Now a stack + GLfloat *pM = ctx->ProjectionMatrixStack.Top->m; + m._11 = pM[0]; + m._12 = pM[1]; + m._13 = pM[2]; + m._14 = pM[3]; + + m._21 = pM[4]; + m._22 = pM[5]; + m._23 = pM[6]; + m._24 = pM[7]; + + m._31 = pM[8]; + m._32 = pM[9]; + m._33 = pM[10] / _fPersp_33; // / 1.6f; + m._34 = pM[11]; + + m._41 = pM[12]; + m._42 = pM[13]; + m._43 = pM[14] / 2.0f; + m._44 = pM[15]; + + gld->matProjection = m; +} + +//--------------------------------------------------------------------------- +/* +void gldFrustumHook_DX9( + GLdouble left, + GLdouble right, + GLdouble bottom, + GLdouble top, + GLdouble nearval, + GLdouble farval) +{ + GET_CURRENT_CONTEXT(ctx); + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); + + // Pass values on to Mesa first (in case we mess with them) + _mesa_Frustum(left, right, bottom, top, nearval, farval); + + _fPersp_33 = farval / (nearval - farval); + +// ddlogPrintf(GLDLOG_SYSTEM, "Frustum: %f", farval/nearval); +} + +//--------------------------------------------------------------------------- + +void gldOrthoHook_DX9( + GLdouble left, + GLdouble right, + GLdouble bottom, + GLdouble top, + GLdouble nearval, + GLdouble farval) +{ + GET_CURRENT_CONTEXT(ctx); + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); + + // Pass values on to Mesa first (in case we mess with them) + _mesa_Ortho(left, right, bottom, top, nearval, farval); + + _fPersp_33 = 1.6f; + +// ddlogPrintf(GLDLOG_SYSTEM, "Ortho: %f", farval/nearval); +} +*/ +//--------------------------------------------------------------------------- + +void gld_NEW_VIEWPORT( + GLcontext *ctx) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); + + D3DVIEWPORT9 d3dvp; +// GLint x, y; +// GLsizei w, h; + + // Set depth range + _GLD_DX9_DEV(GetViewport(gld->pDev, &d3dvp)); + // D3D can't do Quake1/Quake2 z-trick + if (ctx->Viewport.Near <= ctx->Viewport.Far) { + d3dvp.MinZ = ctx->Viewport.Near; + d3dvp.MaxZ = ctx->Viewport.Far; + } else { + d3dvp.MinZ = ctx->Viewport.Far; + d3dvp.MaxZ = ctx->Viewport.Near; + } +/* x = ctx->Viewport.X; + y = ctx->Viewport.Y; + w = ctx->Viewport.Width; + h = ctx->Viewport.Height; + if (x < 0) x = 0; + if (y < 0) y = 0; + if (w > gldCtx->dwWidth) w = gldCtx->dwWidth; + if (h > gldCtx->dwHeight) h = gldCtx->dwHeight; + // Ditto for D3D viewport dimensions + if (w+x > gldCtx->dwWidth) w = gldCtx->dwWidth-x; + if (h+y > gldCtx->dwHeight) h = gldCtx->dwHeight-y; + d3dvp.X = x; + d3dvp.Y = gldCtx->dwHeight - (y + h); + d3dvp.Width = w; + d3dvp.Height = h;*/ + _GLD_DX9_DEV(SetViewport(gld->pDev, &d3dvp)); + +// gld->fFlipWindowY = (float)gldCtx->dwHeight; +} + +//--------------------------------------------------------------------------- + +void gld_NEW_SCISSOR( + GLcontext *ctx) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); + + // Bail if IHV driver cannot scissor + if (!gld->bCanScissor) + return; + + // Set scissor rect + if (ctx->Scissor.Enabled) { + RECT rcRect; + // Keep in mind that RECT's need an extra row and column + rcRect.left = ctx->Scissor.X; + rcRect.right = ctx->Scissor.X + ctx->Scissor.Width; // + 1; + rcRect.top = gldCtx->dwHeight - (ctx->Scissor.Y + ctx->Scissor.Height); + rcRect.bottom = rcRect.top + ctx->Scissor.Height; + IDirect3DDevice9_SetScissorRect(gld->pDev, &rcRect); + } + + // Enable/disable scissor as required + _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_SCISSORTESTENABLE, ctx->Scissor.Enabled)); +} + +//--------------------------------------------------------------------------- + +__inline BOOL _gldAnyEvalEnabled( + GLcontext *ctx) +{ + struct gl_eval_attrib *eval = &ctx->Eval; + + if ((eval->AutoNormal) || + (eval->Map1Color4) || + (eval->Map1Index) || + (eval->Map1Normal) || + (eval->Map1TextureCoord1) || + (eval->Map1TextureCoord2) || + (eval->Map1TextureCoord3) || + (eval->Map1TextureCoord4) || + (eval->Map1Vertex3) || + (eval->Map1Vertex4) || + (eval->Map2Color4) || + (eval->Map2Index) || + (eval->Map2Normal) || + (eval->Map2TextureCoord1) || + (eval->Map2TextureCoord2) || + (eval->Map2TextureCoord3) || + (eval->Map2TextureCoord4) || + (eval->Map2Vertex3) || + (eval->Map2Vertex4) + ) + return TRUE; + + return FALSE; +} + +//--------------------------------------------------------------------------- + +BOOL _gldChooseInternalPipeline( + GLcontext *ctx, + GLD_driver_dx9 *gld) +{ +// return TRUE; // DEBUGGING: ALWAYS USE MESA +// return FALSE; // DEBUGGING: ALWAYS USE D3D + + if ((glb.dwTnL == GLDS_TNL_MESA) || (gld->bHasHWTnL == FALSE)) + { + gld->PipelineUsage.qwMesa.QuadPart++; + return TRUE; // Force Mesa TnL + } + + if ((ctx->Light.Enabled) || + (1) || + (ctx->Texture._TexGenEnabled) || + (ctx->Texture._TexMatEnabled) || +// (ctx->Transform._AnyClip) || + (ctx->Scissor.Enabled) || + _gldAnyEvalEnabled(ctx) // Put this last so we can early-out + ) + { + gld->PipelineUsage.qwMesa.QuadPart++; + return TRUE; + } + + gld->PipelineUsage.qwD3DFVF.QuadPart++; + return FALSE; + +/* // Force Mesa pipeline? + if (glb.dwTnL == GLDS_TNL_MESA) { + gld->PipelineUsage.dwMesa.QuadPart++; + return GLD_PIPELINE_MESA; + } + + // Test for functionality not exposed in the D3D pathways + if ((ctx->Texture._GenFlags)) { + gld->PipelineUsage.dwMesa.QuadPart++; + return GLD_PIPELINE_MESA; + } + + // Now decide if vertex shader can be used. + // If two sided lighting is enabled then we must either + // use Mesa TnL or the vertex shader + if (ctx->_TriangleCaps & DD_TRI_LIGHT_TWOSIDE) { + if (gld->VStwosidelight.hShader && !ctx->Fog.Enabled) { + // Use Vertex Shader + gld->PipelineUsage.dwD3D2SVS.QuadPart++; + return GLD_PIPELINE_D3D_VS_TWOSIDE; + } else { + // Use Mesa TnL + gld->PipelineUsage.dwMesa.QuadPart++; + return GLD_PIPELINE_MESA; + } + } + + // Must be D3D fixed-function pipeline + gld->PipelineUsage.dwD3DFVF.QuadPart++; + return GLD_PIPELINE_D3D_FVF; +*/ +} + +//--------------------------------------------------------------------------- + +void gld_update_state_DX9( + GLcontext *ctx, + GLuint new_state) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLD_pb_dx9 *gldPB; + + if (!gld || !gld->pDev) + return; + + _swsetup_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); + _tnl_InvalidateState( ctx, new_state ); + + // SetupIndex will be used in the pipelines for choosing setup function + if ((ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE | DD_SEPARATE_SPECULAR)) || + (ctx->Fog.Enabled)) + { + if (ctx->_TriangleCaps & DD_FLATSHADE) + gld->iSetupFunc = GLD_SI_FLAT_EXTRAS; + else + gld->iSetupFunc = GLD_SI_SMOOTH_EXTRAS; + } else { + if (ctx->_TriangleCaps & DD_FLATSHADE) + gld->iSetupFunc = GLD_SI_FLAT; // Setup flat shade + texture + else + gld->iSetupFunc = GLD_SI_SMOOTH; // Setup smooth shade + texture + } + + gld->bUseMesaTnL = _gldChooseInternalPipeline(ctx, gld); + if (gld->bUseMesaTnL) { + gldPB = &gld->PB2d; + _GLD_DX9_DEV(SetSoftwareVertexProcessing(gld->pDev, TRUE)); + _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_CLIPPING, FALSE)); + _GLD_DX9_DEV(SetVertexShader(gld->pDev, NULL)); + _GLD_DX9_DEV(SetFVF(gld->pDev, gldPB->dwFVF)); + } else { + gldPB = &gld->PB3d; + _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_CLIPPING, TRUE)); +// if (gld->TnLPipeline == GLD_PIPELINE_D3D_VS_TWOSIDE) { +// _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_SOFTWAREVERTEXPROCESSING, !gld->VStwosidelight.bHardware)); +// _GLD_DX9_DEV(SetVertexShader(gld->pDev, gld->VStwosidelight.hShader)); +// } else { +// _GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_SOFTWAREVERTEXPROCESSING, !gld->bHasHWTnL)); + _GLD_DX9_DEV(SetSoftwareVertexProcessing(gld->pDev, !gld->bHasHWTnL)); + _GLD_DX9_DEV(SetVertexShader(gld->pDev, NULL)); + _GLD_DX9_DEV(SetFVF(gld->pDev, gldPB->dwFVF)); +// } + } + +#define _GLD_TEST_STATE(a) \ + if (new_state & (a)) { \ + gld##a(ctx); \ + new_state &= ~(a); \ + } + +#define _GLD_TEST_STATE_DX9(a) \ + if (new_state & (a)) { \ + gld##a##_DX9(ctx); \ + new_state &= ~(a); \ + } + +#define _GLD_IGNORE_STATE(a) new_state &= ~(a); + +// if (!gld->bUseMesaTnL) { + // Not required if Mesa is doing the TnL. + // Problem: If gld->bUseMesaTnL is TRUE when these are signaled, + // then we'll miss updating the D3D TnL pipeline. + // Therefore, don't test for gld->bUseMesaTnL + _GLD_TEST_STATE(_NEW_MODELVIEW); + _GLD_TEST_STATE(_NEW_PROJECTION); +// } + + _GLD_TEST_STATE_DX9(_NEW_TEXTURE); // extern, so guard with _DX9 + _GLD_TEST_STATE(_NEW_COLOR); + _GLD_TEST_STATE(_NEW_DEPTH); + _GLD_TEST_STATE(_NEW_POLYGON); + _GLD_TEST_STATE(_NEW_STENCIL); + _GLD_TEST_STATE(_NEW_FOG); + _GLD_TEST_STATE(_NEW_LIGHT); + _GLD_TEST_STATE(_NEW_VIEWPORT); + + _GLD_IGNORE_STATE(_NEW_TRANSFORM); + + // Scissor Test: New for DX9 + _GLD_TEST_STATE(_NEW_SCISSOR); + +// Stubs for future use. +/* _GLD_TEST_STATE(_NEW_TEXTURE_MATRIX); + _GLD_TEST_STATE(_NEW_COLOR_MATRIX); + _GLD_TEST_STATE(_NEW_ACCUM); + _GLD_TEST_STATE(_NEW_EVAL); + _GLD_TEST_STATE(_NEW_HINT); + _GLD_TEST_STATE(_NEW_LINE); + _GLD_TEST_STATE(_NEW_PIXEL); + _GLD_TEST_STATE(_NEW_POINT); + _GLD_TEST_STATE(_NEW_POLYGONSTIPPLE); + _GLD_TEST_STATE(_NEW_PACKUNPACK); + _GLD_TEST_STATE(_NEW_ARRAY); + _GLD_TEST_STATE(_NEW_RENDERMODE); + _GLD_TEST_STATE(_NEW_BUFFERS); + _GLD_TEST_STATE(_NEW_MULTISAMPLE); +*/ + +// For debugging. +#if 0 +#define _GLD_TEST_UNHANDLED_STATE(a) \ + if (new_state & (a)) { \ + gldLogMessage(GLDLOG_ERROR, "Unhandled " #a "\n"); \ + } + _GLD_TEST_UNHANDLED_STATE(_NEW_TEXTURE_MATRIX); + _GLD_TEST_UNHANDLED_STATE(_NEW_COLOR_MATRIX); + _GLD_TEST_UNHANDLED_STATE(_NEW_ACCUM); + _GLD_TEST_UNHANDLED_STATE(_NEW_EVAL); + _GLD_TEST_UNHANDLED_STATE(_NEW_HINT); + _GLD_TEST_UNHANDLED_STATE(_NEW_LINE); + _GLD_TEST_UNHANDLED_STATE(_NEW_PIXEL); + _GLD_TEST_UNHANDLED_STATE(_NEW_POINT); + _GLD_TEST_UNHANDLED_STATE(_NEW_POLYGONSTIPPLE); +// _GLD_TEST_UNHANDLED_STATE(_NEW_SCISSOR); + _GLD_TEST_UNHANDLED_STATE(_NEW_PACKUNPACK); + _GLD_TEST_UNHANDLED_STATE(_NEW_ARRAY); + _GLD_TEST_UNHANDLED_STATE(_NEW_RENDERMODE); + _GLD_TEST_UNHANDLED_STATE(_NEW_BUFFERS); + _GLD_TEST_UNHANDLED_STATE(_NEW_MULTISAMPLE); +#undef _GLD_UNHANDLED_STATE +#endif + +#undef _GLD_TEST_STATE +} + +//--------------------------------------------------------------------------- +// Viewport +//--------------------------------------------------------------------------- + +void gld_Viewport_DX9( + GLcontext *ctx, + GLint x, + GLint y, + GLsizei w, + GLsizei h) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); + + D3DVIEWPORT9 d3dvp; + + if (!gld || !gld->pDev) + return; + + // This is a hack. When the app is minimized, Mesa passes + // w=1 and h=1 for viewport dimensions. Without this test + // we get a GPF in gld_wgl_resize_buffers(). + if ((w==1) && (h==1)) + return; + + // Call ResizeBuffersMESA. This function will early-out + // if no resize is needed. + //ctx->Driver.ResizeBuffersMESA(ctx); + // Mesa 5: Changed parameters + ctx->Driver.ResizeBuffers(gldCtx->glBuffer); + +#if 0 + ddlogPrintf(GLDLOG_SYSTEM, ">> Viewport x=%d y=%d w=%d h=%d", x,y,w,h); +#endif + + // ** D3D viewport must not be outside the render target surface ** + // Sanity check the GL viewport dimensions + if (x < 0) x = 0; + if (y < 0) y = 0; + if (w > gldCtx->dwWidth) w = gldCtx->dwWidth; + if (h > gldCtx->dwHeight) h = gldCtx->dwHeight; + // Ditto for D3D viewport dimensions + if (w+x > gldCtx->dwWidth) w = gldCtx->dwWidth-x; + if (h+y > gldCtx->dwHeight) h = gldCtx->dwHeight-y; + + d3dvp.X = x; + d3dvp.Y = gldCtx->dwHeight - (y + h); + d3dvp.Width = w; + d3dvp.Height = h; + if (ctx->Viewport.Near <= ctx->Viewport.Far) { + d3dvp.MinZ = ctx->Viewport.Near; + d3dvp.MaxZ = ctx->Viewport.Far; + } else { + d3dvp.MinZ = ctx->Viewport.Far; + d3dvp.MaxZ = ctx->Viewport.Near; + } + + // TODO: DEBUGGING +// d3dvp.MinZ = 0.0f; +// d3dvp.MaxZ = 1.0f; + + _GLD_DX9_DEV(SetViewport(gld->pDev, &d3dvp)); + +} + +//--------------------------------------------------------------------------- + +extern BOOL dglWglResizeBuffers(GLcontext *ctx, BOOL bDefaultDriver); + +// Mesa 5: Parameter change +void gldResizeBuffers_DX9( +// GLcontext *ctx) + GLframebuffer *fb) +{ + GET_CURRENT_CONTEXT(ctx); + dglWglResizeBuffers(ctx, TRUE); +} + +//--------------------------------------------------------------------------- +#ifdef _DEBUG +// This is only for debugging. +// To use, plug into ctx->Driver.Enable pointer below. +void gld_Enable( + GLcontext *ctx, + GLenum e, + GLboolean b) +{ + char buf[1024]; + sprintf(buf, "Enable: %s (%s)\n", _mesa_lookup_enum_by_nr(e), b?"TRUE":"FALSE"); + ddlogMessage(DDLOG_SYSTEM, buf); +} +#endif +//--------------------------------------------------------------------------- +// Driver pointer setup +//--------------------------------------------------------------------------- + +extern const GLubyte* _gldGetStringGeneric(GLcontext*, GLenum); + +void gldSetupDriverPointers_DX9( + GLcontext *ctx) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); + + TNLcontext *tnl = TNL_CONTEXT(ctx); + + // Mandatory functions + ctx->Driver.GetString = _gldGetStringGeneric; + ctx->Driver.UpdateState = gld_update_state_DX9; + ctx->Driver.Clear = gld_Clear_DX9; + ctx->Driver.DrawBuffer = gld_set_draw_buffer_DX9; + ctx->Driver.GetBufferSize = gld_buffer_size_DX9; + ctx->Driver.Finish = gld_Finish_DX9; + ctx->Driver.Flush = gld_Flush_DX9; + ctx->Driver.Error = gld_Error_DX9; + + // Hardware accumulation buffer + ctx->Driver.Accum = NULL; // TODO: gld_Accum; + + // Bitmap functions + ctx->Driver.CopyPixels = gld_CopyPixels_DX9; + ctx->Driver.DrawPixels = gld_DrawPixels_DX9; + ctx->Driver.ReadPixels = gld_ReadPixels_DX9; + ctx->Driver.Bitmap = gld_Bitmap_DX9; + + // Buffer resize + ctx->Driver.ResizeBuffers = gldResizeBuffers_DX9; + + // Texture image functions + ctx->Driver.ChooseTextureFormat = gld_ChooseTextureFormat_DX9; + ctx->Driver.TexImage1D = gld_TexImage1D_DX9; + ctx->Driver.TexImage2D = gld_TexImage2D_DX9; + ctx->Driver.TexImage3D = _mesa_store_teximage3d; + ctx->Driver.TexSubImage1D = gld_TexSubImage1D_DX9; + ctx->Driver.TexSubImage2D = gld_TexSubImage2D_DX9; + ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d; + + ctx->Driver.CopyTexImage1D = gldCopyTexImage1D_DX9; //NULL; + ctx->Driver.CopyTexImage2D = gldCopyTexImage2D_DX9; //NULL; + ctx->Driver.CopyTexSubImage1D = gldCopyTexSubImage1D_DX9; //NULL; + ctx->Driver.CopyTexSubImage2D = gldCopyTexSubImage2D_DX9; //NULL; + ctx->Driver.CopyTexSubImage3D = gldCopyTexSubImage3D_DX9; + ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage; + + // Texture object functions + ctx->Driver.BindTexture = NULL; + ctx->Driver.NewTextureObject = NULL; // Not yet implemented by Mesa!; + ctx->Driver.DeleteTexture = gld_DeleteTexture_DX9; + ctx->Driver.PrioritizeTexture = NULL; + + // Imaging functionality + ctx->Driver.CopyColorTable = NULL; + ctx->Driver.CopyColorSubTable = NULL; + ctx->Driver.CopyConvolutionFilter1D = NULL; + ctx->Driver.CopyConvolutionFilter2D = NULL; + + // State changing functions + ctx->Driver.AlphaFunc = NULL; //gld_AlphaFunc; + ctx->Driver.BlendFuncSeparate = NULL; //gld_BlendFunc; + ctx->Driver.ClearColor = NULL; //gld_ClearColor; + ctx->Driver.ClearDepth = NULL; //gld_ClearDepth; + ctx->Driver.ClearStencil = NULL; //gld_ClearStencil; + ctx->Driver.ColorMask = NULL; //gld_ColorMask; + ctx->Driver.CullFace = NULL; //gld_CullFace; + ctx->Driver.ClipPlane = NULL; //gld_ClipPlane; + ctx->Driver.FrontFace = NULL; //gld_FrontFace; + ctx->Driver.DepthFunc = NULL; //gld_DepthFunc; + ctx->Driver.DepthMask = NULL; //gld_DepthMask; + ctx->Driver.DepthRange = NULL; + ctx->Driver.Enable = NULL; //gld_Enable; + ctx->Driver.Fogfv = NULL; //gld_Fogfv; + ctx->Driver.Hint = NULL; //gld_Hint; + ctx->Driver.Lightfv = NULL; //gld_Lightfv; + ctx->Driver.LightModelfv = NULL; //gld_LightModelfv; + ctx->Driver.LineStipple = NULL; //gld_LineStipple; + ctx->Driver.LineWidth = NULL; //gld_LineWidth; + ctx->Driver.LogicOpcode = NULL; //gld_LogicOpcode; + ctx->Driver.PointParameterfv = NULL; //gld_PointParameterfv; + ctx->Driver.PointSize = NULL; //gld_PointSize; + ctx->Driver.PolygonMode = NULL; //gld_PolygonMode; + ctx->Driver.PolygonOffset = NULL; //gld_PolygonOffset; + ctx->Driver.PolygonStipple = NULL; //gld_PolygonStipple; + ctx->Driver.RenderMode = NULL; //gld_RenderMode; + ctx->Driver.Scissor = NULL; //gld_Scissor; + ctx->Driver.ShadeModel = NULL; //gld_ShadeModel; + ctx->Driver.StencilFunc = NULL; //gld_StencilFunc; + ctx->Driver.StencilMask = NULL; //gld_StencilMask; + ctx->Driver.StencilOp = NULL; //gld_StencilOp; + ctx->Driver.TexGen = NULL; //gld_TexGen; + ctx->Driver.TexEnv = NULL; + ctx->Driver.TexParameter = NULL; + ctx->Driver.TextureMatrix = NULL; //gld_TextureMatrix; + ctx->Driver.Viewport = gld_Viewport_DX9; + + _swsetup_Wakeup(ctx); + + tnl->Driver.RunPipeline = _tnl_run_pipeline; + tnl->Driver.Render.ResetLineStipple = gld_ResetLineStipple_DX9; + tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon; + tnl->Driver.Render.ClippedLine = _tnl_RenderClippedLine; + + // Hook into glFrustum() and glOrtho() +// ctx->Exec->Frustum = gldFrustumHook_DX9; +// ctx->Exec->Ortho = gldOrthoHook_DX9; + +} + +//--------------------------------------------------------------------------- diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_dx9.h b/mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_dx9.h new file mode 100644 index 000000000..aec40ac9d --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_dx9.h @@ -0,0 +1,327 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x/2000/XP/XBox (Win32) +* +* Description: GLDirect Direct3D 9.0 header file +* +****************************************************************************/ + +#ifndef _GLD_DX9_H +#define _GLD_DX9_H + +//--------------------------------------------------------------------------- +// Windows includes +//--------------------------------------------------------------------------- + +//#ifndef STRICT +//#define STRICT +//#endif + +//#define WIN32_LEAN_AND_MEAN +//#include +#include +#include + +// MS screwed up with the DX8.1 SDK - there's no compile-time +// method of compiling for 8.0 via the 8.1 SDK unless you +// "make sure you don't use any 8.1 interfaces". +// We CAN use 8.1 D3DX static functions, though - just not new 8.1 interfaces. +// +// D3D_SDK_VERSION is 120 for 8.0 (supported by Windows 95). +// D3D_SDK_VERSION is 220 for 8.1 (NOT supported by Windows 95). +// +//#define D3D_SDK_VERSION_DX9_SUPPORT_WIN95 120 +//#define D3D_SDK_VERSION_DX91 220 + +// Typedef for obtaining function from d3d8.dll +typedef IDirect3D9* (WINAPI *FNDIRECT3DCREATE9) (UINT); + + +//--------------------------------------------------------------------------- +// Defines +//--------------------------------------------------------------------------- + +#ifdef _DEBUG +#define _GLD_TEST_HRESULT(h) \ +{ \ + HRESULT _hr = (h); \ + if (FAILED(_hr)) { \ + gldLogError(GLDLOG_ERROR, #h, _hr); \ + } \ +} +#define _GLD_DX9(func) _GLD_TEST_HRESULT(IDirect3D9_##func##) +#define _GLD_DX9_DEV(func) _GLD_TEST_HRESULT(IDirect3DDevice9_##func##) +#define _GLD_DX9_VB(func) _GLD_TEST_HRESULT(IDirect3DVertexBuffer9_##func##) +#define _GLD_DX9_TEX(func) _GLD_TEST_HRESULT(IDirect3DTexture9_##func##) +#else +#define _GLD_DX9(func) IDirect3D9_##func +#define _GLD_DX9_DEV(func) IDirect3DDevice9_##func +#define _GLD_DX9_VB(func) IDirect3DVertexBuffer9_##func +#define _GLD_DX9_TEX(func) IDirect3DTexture9_##func +#endif + +#define SAFE_RELEASE(p) \ +{ \ + if (p) { \ + (p)->lpVtbl->Release(p); \ + (p) = NULL; \ + } \ +} + +#define SAFE_RELEASE_VB9(p) \ +{ \ + if (p) { \ + IDirect3DVertexBuffer9_Release((p)); \ + (p) = NULL; \ + } \ +} + +#define SAFE_RELEASE_SURFACE9(p) \ +{ \ + if (p) { \ + IDirect3DSurface9_Release((p)); \ + (p) = NULL; \ + } \ +} + +// Setup index. +enum { + GLD_SI_FLAT = 0, + GLD_SI_SMOOTH = 1, + GLD_SI_FLAT_EXTRAS = 2, + GLD_SI_SMOOTH_EXTRAS = 3, +}; +/* +// Internal pipeline +typedef enum { + GLD_PIPELINE_MESA = 0, // Mesa pipeline + GLD_PIPELINE_D3D_FVF = 1, // Direct3D Fixed-function pipeline + GLD_PIPELINE_D3D_VS_TWOSIDE = 2 // Direct3D two-sided-lighting vertex shader +} GLD_tnl_pipeline; +*/ +//--------------------------------------------------------------------------- +// Vertex definitions for Fixed-Function pipeline +//--------------------------------------------------------------------------- + +// +// NOTE: If the number of texture units is altered then most of +// the texture code will need to be revised. +// + +#define GLD_MAX_TEXTURE_UNITS_DX9 2 + +// +// 2D vertex transformed by Mesa +// +#define GLD_FVF_2D_VERTEX ( D3DFVF_XYZRHW | \ + D3DFVF_DIFFUSE | \ + D3DFVF_SPECULAR | \ + D3DFVF_TEX2) +typedef struct { + FLOAT x, y; // 2D raster coords + FLOAT sz; // Screen Z (depth) + FLOAT rhw; // Reciprocal homogenous W + DWORD diffuse; // Diffuse colour + DWORD specular; // For separate-specular support + FLOAT t0_u, t0_v; // 1st set of texture coords + FLOAT t1_u, t1_v; // 2nd set of texture coords +} GLD_2D_VERTEX; + + +// +// 3D vertex transformed by Direct3D +// +#define GLD_FVF_3D_VERTEX ( D3DFVF_XYZ | \ + D3DFVF_DIFFUSE | \ + D3DFVF_TEX2) + +typedef struct { + D3DXVECTOR3 Position; // XYZ Vector in object space + D3DCOLOR Diffuse; // Diffuse colour + D3DXVECTOR2 TexUnit0; // Texture unit 0 + D3DXVECTOR2 TexUnit1; // Texture unit 1 +} GLD_3D_VERTEX; + +//--------------------------------------------------------------------------- +// Vertex Shaders +//--------------------------------------------------------------------------- +/* +// DX8 Vertex Shader +typedef struct { + DWORD hShader; // If NULL, shader is invalid and cannot be used + BOOL bHardware; // If TRUE then shader was created for hardware, + // otherwise shader was created for software. +} GLD_vertexShader; +*/ +//--------------------------------------------------------------------------- +// Structs +//--------------------------------------------------------------------------- + +// This keeps a count of how many times we choose each individual internal +// pathway. Useful for seeing if a certain pathway was ever used by an app, and +// how much each pathway is biased. +// Zero the members at context creation and dump stats at context deletion. +typedef struct { + // Note: DWORD is probably too small + ULARGE_INTEGER qwMesa; // Mesa TnL pipeline + ULARGE_INTEGER qwD3DFVF; // Direct3D Fixed-Function pipeline +// ULARGE_INTEGER dwD3D2SVS; // Direct3D Two-Sided Vertex Shader pipeline +} GLD_pipeline_usage; + +// GLDirect Primitive Buffer (points, lines, triangles and quads) +typedef struct { + // Data for IDirect3DDevice9::CreateVertexBuffer() + DWORD dwStride; // Stride of vertex + DWORD dwUsage; // Usage flags + DWORD dwFVF; // Direct3D Flexible Vertex Format + DWORD dwPool; // Pool flags + + IDirect3DVertexBuffer9 *pVB; // Holds points, lines, tris and quads. + + // Point list is assumed to be at start of buffer + DWORD iFirstLine; // Index of start of line list + DWORD iFirstTriangle; // Index of start of triangle list + + BYTE *pPoints; // Pointer to next free point + BYTE *pLines; // Pointer to next free line + BYTE *pTriangles; // Pointer to next free triangle + + DWORD nPoints; // Number of points ready to render + DWORD nLines; // Number of lines ready to render + DWORD nTriangles; // Number of triangles ready to render +} GLD_pb_dx9; + +// GLDirect DX9 driver data +typedef struct { + // GLDirect vars + BOOL bDoublebuffer; // Doublebuffer (otherwise single-buffered) + BOOL bDepthStencil; // Depth buffer needed (stencil optional) + D3DFORMAT RenderFormat; // Format of back/front buffer + D3DFORMAT DepthFormat; // Format of depth/stencil +// float fFlipWindowY; // Value for flipping viewport Y coord + + // Direct3D vars + D3DCAPS9 d3dCaps9; + BOOL bHasHWTnL; // Device has Hardware Transform/Light? + IDirect3D9 *pD3D; // Base Direct3D9 interface + IDirect3DDevice9 *pDev; // Direct3D9 Device interface + GLD_pb_dx9 PB2d; // Vertices transformed by Mesa + GLD_pb_dx9 PB3d; // Vertices transformed by Direct3D + D3DPRIMITIVETYPE d3dpt; // Current Direct3D primitive type + D3DXMATRIX matProjection; // Projection matrix for D3D TnL + D3DXMATRIX matModelView; // Model/View matrix for D3D TnL + int iSetupFunc; // Which setup functions to use + BOOL bUseMesaTnL; // Whether to use Mesa or D3D for TnL + + // Direct3D vars for two-sided lighting +// GLD_vertexShader VStwosidelight; // Vertex Shader for two-sided lighting +// D3DXMATRIX matWorldViewProj;// World/View/Projection matrix for shaders + + +// GLD_tnl_pipeline TnLPipeline; // Index of current internal pipeline + GLD_pipeline_usage PipelineUsage; + + BOOL bCanScissor; // Scissor test - new for DX9 +} GLD_driver_dx9; + +#define GLD_GET_DX9_DRIVER(c) (GLD_driver_dx9*)(c)->glPriv + +//--------------------------------------------------------------------------- +// Function prototypes +//--------------------------------------------------------------------------- + +PROC gldGetProcAddress_DX9(LPCSTR a); +void gldEnableExtensions_DX9(GLcontext *ctx); +void gldInstallPipeline_DX9(GLcontext *ctx); +void gldSetupDriverPointers_DX9(GLcontext *ctx); +//void gldResizeBuffers_DX9(GLcontext *ctx); +void gldResizeBuffers_DX9(GLframebuffer *fb); + + +// Texture functions + +void gldCopyTexImage1D_DX9(GLcontext *ctx, GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border); +void gldCopyTexImage2D_DX9(GLcontext *ctx, GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +void gldCopyTexSubImage1D_DX9(GLcontext *ctx, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width ); +void gldCopyTexSubImage2D_DX9(GLcontext *ctx, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height ); +void gldCopyTexSubImage3D_DX9(GLcontext *ctx, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height ); + +void gld_NEW_TEXTURE_DX9(GLcontext *ctx); +void gld_DrawPixels_DX9(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, const struct gl_pixelstore_attrib *unpack, const GLvoid *pixels); +void gld_ReadPixels_DX9(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, const struct gl_pixelstore_attrib *unpack, GLvoid *dest); +void gld_CopyPixels_DX9(GLcontext *ctx, GLint srcx, GLint srcy, GLsizei width, GLsizei height, GLint dstx, GLint dsty, GLenum type); +void gld_Bitmap_DX9(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, const struct gl_pixelstore_attrib *unpack, const GLubyte *bitmap); +const struct gl_texture_format* gld_ChooseTextureFormat_DX9(GLcontext *ctx, GLint internalFormat, GLenum srcFormat, GLenum srcType); +void gld_TexImage2D_DX9(GLcontext *ctx, GLenum target, GLint level, GLint internalFormat, GLint width, GLint height, GLint border, GLenum format, GLenum type, const GLvoid *pixels, const struct gl_pixelstore_attrib *packing, struct gl_texture_object *tObj, struct gl_texture_image *texImage); +void gld_TexImage1D_DX9(GLcontext *ctx, GLenum target, GLint level, GLint internalFormat, GLint width, GLint border, GLenum format, GLenum type, const GLvoid *pixels, const struct gl_pixelstore_attrib *packing, struct gl_texture_object *texObj, struct gl_texture_image *texImage ); +void gld_TexSubImage2D_DX9( GLcontext *ctx, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels, const struct gl_pixelstore_attrib *packing, struct gl_texture_object *texObj, struct gl_texture_image *texImage ); +void gld_TexSubImage1D_DX9(GLcontext *ctx, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels, const struct gl_pixelstore_attrib *packing, struct gl_texture_object *texObj, struct gl_texture_image *texImage); +void gld_DeleteTexture_DX9(GLcontext *ctx, struct gl_texture_object *tObj); +void gld_ResetLineStipple_DX9(GLcontext *ctx); + +// 2D primitive functions + +void gld_Points2D_DX9(GLcontext *ctx, GLuint first, GLuint last); + +void gld_Line2DFlat_DX9(GLcontext *ctx, GLuint v0, GLuint v1); +void gld_Line2DSmooth_DX9(GLcontext *ctx, GLuint v0, GLuint v1); + +void gld_Triangle2DFlat_DX9(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2); +void gld_Triangle2DSmooth_DX9(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2); +void gld_Triangle2DFlatExtras_DX9(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2); +void gld_Triangle2DSmoothExtras_DX9(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2); + +void gld_Quad2DFlat_DX9(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +void gld_Quad2DSmooth_DX9(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +void gld_Quad2DFlatExtras_DX9(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +void gld_Quad2DSmoothExtras_DX9(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3); + +// 3D primitive functions + +void gld_Points3D_DX9(GLcontext *ctx, GLuint first, GLuint last); +void gld_Line3DFlat_DX9(GLcontext *ctx, GLuint v0, GLuint v1); +void gld_Triangle3DFlat_DX9(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2); +void gld_Quad3DFlat_DX9(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +void gld_Line3DSmooth_DX9(GLcontext *ctx, GLuint v0, GLuint v1); +void gld_Triangle3DSmooth_DX9(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2); +void gld_Quad3DSmooth_DX9(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3); + +// Primitive functions for Two-sided-lighting Vertex Shader + +void gld_Points2DTwoside_DX9(GLcontext *ctx, GLuint first, GLuint last); +void gld_Line2DFlatTwoside_DX9(GLcontext *ctx, GLuint v0, GLuint v1); +void gld_Line2DSmoothTwoside_DX9(GLcontext *ctx, GLuint v0, GLuint v1); +void gld_Triangle2DFlatTwoside_DX9(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2); +void gld_Triangle2DSmoothTwoside_DX9(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2); +void gld_Quad2DFlatTwoside_DX9(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +void gld_Quad2DSmoothTwoside_DX9(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3); + +#endif diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_dxerr9.h b/mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_dxerr9.h new file mode 100644 index 000000000..1d6b7b1c7 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_dxerr9.h @@ -0,0 +1,77 @@ +/*==========================================================================; + * + * + * File: dxerr9.h + * Content: DirectX Error Library Include File + * + ****************************************************************************/ + +#ifndef _GLD_DXERR9_H_ +#define _GLD_DXERR9_H_ + + +#include + +// +// DXGetErrorString9 +// +// Desc: Converts an DirectX HRESULT to a string +// +// Args: HRESULT hr Can be any error code from +// DPLAY D3D8 D3DX8 DMUSIC DSOUND +// +// Return: Converted string +// +const char* __stdcall DXGetErrorString9A(HRESULT hr); +const WCHAR* __stdcall DXGetErrorString9W(HRESULT hr); + +#ifdef UNICODE + #define DXGetErrorString9 DXGetErrorString9W +#else + #define DXGetErrorString9 DXGetErrorString9A +#endif + + +// +// DXTrace +// +// Desc: Outputs a formatted error message to the debug stream +// +// Args: CHAR* strFile The current file, typically passed in using the +// __FILE__ macro. +// DWORD dwLine The current line number, typically passed in using the +// __LINE__ macro. +// HRESULT hr An HRESULT that will be traced to the debug stream. +// CHAR* strMsg A string that will be traced to the debug stream (may be NULL) +// BOOL bPopMsgBox If TRUE, then a message box will popup also containing the passed info. +// +// Return: The hr that was passed in. +// +//HRESULT __stdcall DXTraceA( char* strFile, DWORD dwLine, HRESULT hr, char* strMsg, BOOL bPopMsgBox = FALSE ); +//HRESULT __stdcall DXTraceW( char* strFile, DWORD dwLine, HRESULT hr, WCHAR* strMsg, BOOL bPopMsgBox = FALSE ); +HRESULT __stdcall DXTraceA( char* strFile, DWORD dwLine, HRESULT hr, char* strMsg, BOOL bPopMsgBox); +HRESULT __stdcall DXTraceW( char* strFile, DWORD dwLine, HRESULT hr, WCHAR* strMsg, BOOL bPopMsgBox); + +#ifdef UNICODE + #define DXTrace DXTraceW +#else + #define DXTrace DXTraceA +#endif + + +// +// Helper macros +// +#if defined(DEBUG) | defined(_DEBUG) + #define DXTRACE_MSG(str) DXTrace( __FILE__, (DWORD)__LINE__, 0, str, FALSE ) + #define DXTRACE_ERR(str,hr) DXTrace( __FILE__, (DWORD)__LINE__, hr, str, TRUE ) + #define DXTRACE_ERR_NOMSGBOX(str,hr) DXTrace( __FILE__, (DWORD)__LINE__, hr, str, FALSE ) +#else + #define DXTRACE_MSG(str) (0L) + #define DXTRACE_ERR(str,hr) (hr) + #define DXTRACE_ERR_NOMSGBOX(str,hr) (hr) +#endif + + +#endif + diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_ext_dx9.c b/mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_ext_dx9.c new file mode 100644 index 000000000..e8c73a6ff --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_ext_dx9.c @@ -0,0 +1,344 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x/2000/XP/XBox (Win32) +* +* Description: GL extensions +* +****************************************************************************/ + +//#include "../GLDirect.h" +//#include "../gld_log.h" +//#include "../gld_settings.h" + +#include +#define GL_GLEXT_PROTOTYPES +#include +#include + +//#include "ddlog.h" +//#include "gld_dx8.h" + +#include "glheader.h" +#include "context.h" +#include "colormac.h" +#include "depth.h" +#include "extensions.h" +#include "macros.h" +#include "matrix.h" +// #include "mem.h" +//#include "mmath.h" +#include "mtypes.h" +#include "texformat.h" +#include "texstore.h" +#include "vbo/vbo.h" +#include "swrast_setup/swrast_setup.h" +#include "swrast_setup/ss_context.h" +#include "tnl/tnl.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" + +#include "dglcontext.h" +#include "extensions.h" + +// For some reason this is not defined in an above header... +extern void _mesa_enable_imaging_extensions(GLcontext *ctx); + +//--------------------------------------------------------------------------- +// Hack for the SGIS_multitexture extension that was removed from Mesa +// NOTE: SGIS_multitexture enums also clash with GL_SGIX_async_pixel + + // NOTE: Quake2 ran *slower* with this enabled, so I've + // disabled it for now. + // To enable, uncomment: + // _mesa_add_extension(ctx, GL_TRUE, szGL_SGIS_multitexture, 0); + +//--------------------------------------------------------------------------- + +enum { + /* Quake2 GL_SGIS_multitexture */ + GL_SELECTED_TEXTURE_SGIS = 0x835B, + GL_SELECTED_TEXTURE_COORD_SET_SGIS = 0x835C, + GL_MAX_TEXTURES_SGIS = 0x835D, + GL_TEXTURE0_SGIS = 0x835E, + GL_TEXTURE1_SGIS = 0x835F, + GL_TEXTURE2_SGIS = 0x8360, + GL_TEXTURE3_SGIS = 0x8361, + GL_TEXTURE_COORD_SET_SOURCE_SGIS = 0x8363, +}; + +//--------------------------------------------------------------------------- + +void APIENTRY gldSelectTextureSGIS( + GLenum target) +{ + GLenum ARB_target = GL_TEXTURE0_ARB + (target - GL_TEXTURE0_SGIS); + glActiveTextureARB(ARB_target); +} + +//--------------------------------------------------------------------------- + +void APIENTRY gldMTexCoord2fSGIS( + GLenum target, + GLfloat s, + GLfloat t) +{ + GLenum ARB_target = GL_TEXTURE0_ARB + (target - GL_TEXTURE0_SGIS); + glMultiTexCoord2fARB(ARB_target, s, t); +} + +//--------------------------------------------------------------------------- + +void APIENTRY gldMTexCoord2fvSGIS( + GLenum target, + const GLfloat *v) +{ + GLenum ARB_target = GL_TEXTURE0_ARB + (target - GL_TEXTURE0_SGIS); + glMultiTexCoord2fvARB(ARB_target, v); +} + +//--------------------------------------------------------------------------- +// Extensions +//--------------------------------------------------------------------------- + +typedef struct { + PROC proc; + char *name; +} GLD_extension; + +GLD_extension GLD_extList[] = { +#ifdef GL_EXT_polygon_offset + { (PROC)glPolygonOffsetEXT, "glPolygonOffsetEXT" }, +#endif + { (PROC)glBlendEquationEXT, "glBlendEquationEXT" }, + { (PROC)glBlendColorEXT, "glBlendColorExt" }, + { (PROC)glVertexPointerEXT, "glVertexPointerEXT" }, + { (PROC)glNormalPointerEXT, "glNormalPointerEXT" }, + { (PROC)glColorPointerEXT, "glColorPointerEXT" }, + { (PROC)glIndexPointerEXT, "glIndexPointerEXT" }, + { (PROC)glTexCoordPointerEXT, "glTexCoordPointer" }, + { (PROC)glEdgeFlagPointerEXT, "glEdgeFlagPointerEXT" }, + { (PROC)glGetPointervEXT, "glGetPointervEXT" }, + { (PROC)glArrayElementEXT, "glArrayElementEXT" }, + { (PROC)glDrawArraysEXT, "glDrawArrayEXT" }, + { (PROC)glAreTexturesResidentEXT, "glAreTexturesResidentEXT" }, + { (PROC)glBindTextureEXT, "glBindTextureEXT" }, + { (PROC)glDeleteTexturesEXT, "glDeleteTexturesEXT" }, + { (PROC)glGenTexturesEXT, "glGenTexturesEXT" }, + { (PROC)glIsTextureEXT, "glIsTextureEXT" }, + { (PROC)glPrioritizeTexturesEXT, "glPrioritizeTexturesEXT" }, + { (PROC)glCopyTexSubImage3DEXT, "glCopyTexSubImage3DEXT" }, + { (PROC)glTexImage3DEXT, "glTexImage3DEXT" }, + { (PROC)glTexSubImage3DEXT, "glTexSubImage3DEXT" }, + { (PROC)glPointParameterfEXT, "glPointParameterfEXT" }, + { (PROC)glPointParameterfvEXT, "glPointParameterfvEXT" }, + + { (PROC)glLockArraysEXT, "glLockArraysEXT" }, + { (PROC)glUnlockArraysEXT, "glUnlockArraysEXT" }, + { NULL, "\0" } +}; + +GLD_extension GLD_multitexList[] = { +/* + { (PROC)glMultiTexCoord1dSGIS, "glMTexCoord1dSGIS" }, + { (PROC)glMultiTexCoord1dvSGIS, "glMTexCoord1dvSGIS" }, + { (PROC)glMultiTexCoord1fSGIS, "glMTexCoord1fSGIS" }, + { (PROC)glMultiTexCoord1fvSGIS, "glMTexCoord1fvSGIS" }, + { (PROC)glMultiTexCoord1iSGIS, "glMTexCoord1iSGIS" }, + { (PROC)glMultiTexCoord1ivSGIS, "glMTexCoord1ivSGIS" }, + { (PROC)glMultiTexCoord1sSGIS, "glMTexCoord1sSGIS" }, + { (PROC)glMultiTexCoord1svSGIS, "glMTexCoord1svSGIS" }, + { (PROC)glMultiTexCoord2dSGIS, "glMTexCoord2dSGIS" }, + { (PROC)glMultiTexCoord2dvSGIS, "glMTexCoord2dvSGIS" }, + { (PROC)glMultiTexCoord2fSGIS, "glMTexCoord2fSGIS" }, + { (PROC)glMultiTexCoord2fvSGIS, "glMTexCoord2fvSGIS" }, + { (PROC)glMultiTexCoord2iSGIS, "glMTexCoord2iSGIS" }, + { (PROC)glMultiTexCoord2ivSGIS, "glMTexCoord2ivSGIS" }, + { (PROC)glMultiTexCoord2sSGIS, "glMTexCoord2sSGIS" }, + { (PROC)glMultiTexCoord2svSGIS, "glMTexCoord2svSGIS" }, + { (PROC)glMultiTexCoord3dSGIS, "glMTexCoord3dSGIS" }, + { (PROC)glMultiTexCoord3dvSGIS, "glMTexCoord3dvSGIS" }, + { (PROC)glMultiTexCoord3fSGIS, "glMTexCoord3fSGIS" }, + { (PROC)glMultiTexCoord3fvSGIS, "glMTexCoord3fvSGIS" }, + { (PROC)glMultiTexCoord3iSGIS, "glMTexCoord3iSGIS" }, + { (PROC)glMultiTexCoord3ivSGIS, "glMTexCoord3ivSGIS" }, + { (PROC)glMultiTexCoord3sSGIS, "glMTexCoord3sSGIS" }, + { (PROC)glMultiTexCoord3svSGIS, "glMTexCoord3svSGIS" }, + { (PROC)glMultiTexCoord4dSGIS, "glMTexCoord4dSGIS" }, + { (PROC)glMultiTexCoord4dvSGIS, "glMTexCoord4dvSGIS" }, + { (PROC)glMultiTexCoord4fSGIS, "glMTexCoord4fSGIS" }, + { (PROC)glMultiTexCoord4fvSGIS, "glMTexCoord4fvSGIS" }, + { (PROC)glMultiTexCoord4iSGIS, "glMTexCoord4iSGIS" }, + { (PROC)glMultiTexCoord4ivSGIS, "glMTexCoord4ivSGIS" }, + { (PROC)glMultiTexCoord4sSGIS, "glMTexCoord4sSGIS" }, + { (PROC)glMultiTexCoord4svSGIS, "glMTexCoord4svSGIS" }, + { (PROC)glMultiTexCoordPointerSGIS, "glMTexCoordPointerSGIS" }, + { (PROC)glSelectTextureSGIS, "glSelectTextureSGIS" }, + { (PROC)glSelectTextureCoordSetSGIS, "glSelectTextureCoordSetSGIS" }, +*/ + { (PROC)glActiveTextureARB, "glActiveTextureARB" }, + { (PROC)glClientActiveTextureARB, "glClientActiveTextureARB" }, + { (PROC)glMultiTexCoord1dARB, "glMultiTexCoord1dARB" }, + { (PROC)glMultiTexCoord1dvARB, "glMultiTexCoord1dvARB" }, + { (PROC)glMultiTexCoord1fARB, "glMultiTexCoord1fARB" }, + { (PROC)glMultiTexCoord1fvARB, "glMultiTexCoord1fvARB" }, + { (PROC)glMultiTexCoord1iARB, "glMultiTexCoord1iARB" }, + { (PROC)glMultiTexCoord1ivARB, "glMultiTexCoord1ivARB" }, + { (PROC)glMultiTexCoord1sARB, "glMultiTexCoord1sARB" }, + { (PROC)glMultiTexCoord1svARB, "glMultiTexCoord1svARB" }, + { (PROC)glMultiTexCoord2dARB, "glMultiTexCoord2dARB" }, + { (PROC)glMultiTexCoord2dvARB, "glMultiTexCoord2dvARB" }, + { (PROC)glMultiTexCoord2fARB, "glMultiTexCoord2fARB" }, + { (PROC)glMultiTexCoord2fvARB, "glMultiTexCoord2fvARB" }, + { (PROC)glMultiTexCoord2iARB, "glMultiTexCoord2iARB" }, + { (PROC)glMultiTexCoord2ivARB, "glMultiTexCoord2ivARB" }, + { (PROC)glMultiTexCoord2sARB, "glMultiTexCoord2sARB" }, + { (PROC)glMultiTexCoord2svARB, "glMultiTexCoord2svARB" }, + { (PROC)glMultiTexCoord3dARB, "glMultiTexCoord3dARB" }, + { (PROC)glMultiTexCoord3dvARB, "glMultiTexCoord3dvARB" }, + { (PROC)glMultiTexCoord3fARB, "glMultiTexCoord3fARB" }, + { (PROC)glMultiTexCoord3fvARB, "glMultiTexCoord3fvARB" }, + { (PROC)glMultiTexCoord3iARB, "glMultiTexCoord3iARB" }, + { (PROC)glMultiTexCoord3ivARB, "glMultiTexCoord3ivARB" }, + { (PROC)glMultiTexCoord3sARB, "glMultiTexCoord3sARB" }, + { (PROC)glMultiTexCoord3svARB, "glMultiTexCoord3svARB" }, + { (PROC)glMultiTexCoord4dARB, "glMultiTexCoord4dARB" }, + { (PROC)glMultiTexCoord4dvARB, "glMultiTexCoord4dvARB" }, + { (PROC)glMultiTexCoord4fARB, "glMultiTexCoord4fARB" }, + { (PROC)glMultiTexCoord4fvARB, "glMultiTexCoord4fvARB" }, + { (PROC)glMultiTexCoord4iARB, "glMultiTexCoord4iARB" }, + { (PROC)glMultiTexCoord4ivARB, "glMultiTexCoord4ivARB" }, + { (PROC)glMultiTexCoord4sARB, "glMultiTexCoord4sARB" }, + { (PROC)glMultiTexCoord4svARB, "glMultiTexCoord4svARB" }, + + // Descent3 doesn't use correct string, hence this hack + { (PROC)glMultiTexCoord4fARB, "glMultiTexCoord4f" }, + + // Quake2 SGIS multitexture + { (PROC)gldSelectTextureSGIS, "glSelectTextureSGIS" }, + { (PROC)gldMTexCoord2fSGIS, "glMTexCoord2fSGIS" }, + { (PROC)gldMTexCoord2fvSGIS, "glMTexCoord2fvSGIS" }, + + { NULL, "\0" } +}; + +//--------------------------------------------------------------------------- + +PROC gldGetProcAddress_DX( + LPCSTR a) +{ + int i; + PROC proc = NULL; + + for (i=0; GLD_extList[i].proc; i++) { + if (!strcmp(a, GLD_extList[i].name)) { + proc = GLD_extList[i].proc; + break; + } + } + + if (glb.bMultitexture) { + for (i=0; GLD_multitexList[i].proc; i++) { + if (!strcmp(a, GLD_multitexList[i].name)) { + proc = GLD_multitexList[i].proc; + break; + } + } + } + + gldLogPrintf(GLDLOG_INFO, "GetProcAddress: %s (%s)", a, proc ? "OK" : "Failed"); + + return proc; +} + +//--------------------------------------------------------------------------- + +void gldEnableExtensions_DX9( + GLcontext *ctx) +{ + GLuint i; + + // Mesa enables some extensions by default. + // This table decides which ones we want to switch off again. + + // NOTE: GL_EXT_compiled_vertex_array appears broken. + + const char *gld_disable_extensions[] = { +// "GL_ARB_transpose_matrix", +// "GL_EXT_compiled_vertex_array", +// "GL_EXT_polygon_offset", +// "GL_EXT_rescale_normal", + "GL_EXT_texture3D", +// "GL_NV_texgen_reflection", + NULL + }; + + const char *gld_multitex_extensions[] = { + "GL_ARB_multitexture", // Quake 3 + NULL + }; + + // Quake 2 engines + const char *szGL_SGIS_multitexture = "GL_SGIS_multitexture"; + + const char *gld_enable_extensions[] = { + "GL_EXT_texture_env_add", // Quake 3 + "GL_ARB_texture_env_add", // Quake 3 + NULL + }; + + for (i=0; gld_disable_extensions[i]; i++) { + _mesa_disable_extension(ctx, gld_disable_extensions[i]); + } + + for (i=0; gld_enable_extensions[i]; i++) { + _mesa_enable_extension(ctx, gld_enable_extensions[i]); + } + + if (glb.bMultitexture) { + for (i=0; gld_multitex_extensions[i]; i++) { + _mesa_enable_extension(ctx, gld_multitex_extensions[i]); + } + + // GL_SGIS_multitexture + // NOTE: Quake2 ran *slower* with this enabled, so I've + // disabled it for now. + // Fair bit slower on GeForce256, + // Much slower on 3dfx Voodoo5 5500. +// _mesa_add_extension(ctx, GL_TRUE, szGL_SGIS_multitexture, 0); + + } + + _mesa_enable_imaging_extensions(ctx); + _mesa_enable_1_3_extensions(ctx); + _mesa_enable_1_4_extensions(ctx); +} + +//--------------------------------------------------------------------------- diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_pipeline_dx9.c b/mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_pipeline_dx9.c new file mode 100644 index 000000000..2b272aa62 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_pipeline_dx9.c @@ -0,0 +1,77 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x/2000/XP/XBox (Win32) +* +* Description: Mesa transformation pipeline with GLDirect fastpath +* +****************************************************************************/ + +//#include "../GLDirect.h" + +#include "dglcontext.h" +#include "ddlog.h" +#include "gld_dx9.h" + +#include "tnl/tnl.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" + +//--------------------------------------------------------------------------- + +extern struct tnl_pipeline_stage _gld_d3d_render_stage; +extern struct tnl_pipeline_stage _gld_mesa_render_stage; + +static const struct tnl_pipeline_stage *gld_pipeline[] = { + &_gld_d3d_render_stage, // Direct3D TnL + &_tnl_vertex_transform_stage, + &_tnl_normal_transform_stage, + &_tnl_lighting_stage, + &_tnl_fog_coordinate_stage, /* TODO: Omit fog stage. ??? */ + &_tnl_texgen_stage, + &_tnl_texture_transform_stage, + &_tnl_point_attenuation_stage, + &_gld_mesa_render_stage, // Mesa TnL, D3D rendering + 0, +}; + +//--------------------------------------------------------------------------- + +void gldInstallPipeline_DX9( + GLcontext *ctx) +{ + // Remove any existing pipeline stages, + // then install GLDirect pipeline stages. + + _tnl_destroy_pipeline(ctx); + _tnl_install_pipeline(ctx, gld_pipeline); +} + +//--------------------------------------------------------------------------- diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_primitive_dx9.c b/mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_primitive_dx9.c new file mode 100644 index 000000000..403a9d5f8 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_primitive_dx9.c @@ -0,0 +1,1446 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x/2000/XP/XBox (Win32) +* +* Description: Primitive (points/lines/tris/quads) rendering +* +****************************************************************************/ + +//#include "../GLDirect.h" + +//#include "gld_dx8.h" + +#include "dglcontext.h" +#include "ddlog.h" +#include "gld_dx9.h" + +#include "glheader.h" +#include "context.h" +#include "colormac.h" +#include "depth.h" +#include "extensions.h" +#include "macros.h" +#include "matrix.h" +// #include "mem.h" +//#include "mmath.h" +#include "mtypes.h" +#include "texformat.h" +#include "texstore.h" +#include "vbo/vbo.h" +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "swrast_setup/ss_context.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" + +// Disable compiler complaints about unreferenced local variables +#pragma warning (disable:4101) + +//--------------------------------------------------------------------------- +// Helper defines for primitives +//--------------------------------------------------------------------------- + +//static const float ooZ = 1.0f / 65536.0f; // One over Z + +#define GLD_COLOUR (D3DCOLOR_RGBA(swv->color[0], swv->color[1], swv->color[2], swv->color[3])) +#define GLD_SPECULAR (D3DCOLOR_RGBA(swv->specular[0], swv->specular[1], swv->specular[2], swv->specular[3])) +#define GLD_FLIP_Y(y) (gldCtx->dwHeight - (y)) + +//--------------------------------------------------------------------------- +// 2D vertex setup +//--------------------------------------------------------------------------- + +#define GLD_SETUP_2D_VARS_POINTS \ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); \ + GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); \ + GLD_2D_VERTEX *pV = (GLD_2D_VERTEX*)gld->PB2d.pPoints; \ + SScontext *ss = SWSETUP_CONTEXT(ctx); \ + SWvertex *swv; \ + DWORD dwSpecularColour; \ + DWORD dwFlatColour + +#define GLD_SETUP_2D_VARS_LINES \ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); \ + GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); \ + GLD_2D_VERTEX *pV = (GLD_2D_VERTEX*)gld->PB2d.pLines; \ + SScontext *ss = SWSETUP_CONTEXT(ctx); \ + SWvertex *swv; \ + DWORD dwSpecularColour; \ + DWORD dwFlatColour + +#define GLD_SETUP_2D_VARS_TRIANGLES \ + BOOL bFog = ctx->Fog.Enabled; \ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); \ + GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); \ + GLD_2D_VERTEX *pV = (GLD_2D_VERTEX*)gld->PB2d.pTriangles; \ + SScontext *ss = SWSETUP_CONTEXT(ctx); \ + SWvertex *swv; \ + DWORD dwSpecularColour; \ + DWORD dwFlatColour; \ + GLuint facing = 0; \ + struct vertex_buffer *VB; \ + GLchan (*vbcolor)[4]; \ + GLchan (*vbspec)[4] + +#define GLD_SETUP_GET_SWVERT(s) \ + swv = &ss->verts[##s] + +#define GLD_SETUP_2D_VERTEX \ + pV->x = swv->win[0]; \ + pV->y = GLD_FLIP_Y(swv->win[1]); \ + pV->rhw = swv->win[3] + +#define GLD_SETUP_SMOOTH_COLOUR \ + pV->diffuse = GLD_COLOUR + +#define GLD_SETUP_GET_FLAT_COLOUR \ + dwFlatColour = GLD_COLOUR +#define GLD_SETUP_GET_FLAT_FOG_COLOUR \ + dwFlatColour = _gldComputeFog(ctx, swv) + +#define GLD_SETUP_USE_FLAT_COLOUR \ + pV->diffuse = dwFlatColour + +#define GLD_SETUP_GET_FLAT_SPECULAR \ + dwSpecularColour= GLD_SPECULAR + +#define GLD_SETUP_USE_FLAT_SPECULAR \ + pV->specular = dwSpecularColour + +#define GLD_SETUP_DEPTH \ + pV->sz = swv->win[2] / ctx->DepthMaxF +// pV->z = swv->win[2] * ooZ; + +#define GLD_SETUP_SPECULAR \ + pV->specular = GLD_SPECULAR + +#define GLD_SETUP_FOG \ + pV->diffuse = _gldComputeFog(ctx, swv) + +#define GLD_SETUP_TEX0 \ + pV->t0_u = swv->texcoord[0][0]; \ + pV->t0_v = swv->texcoord[0][1] + +#define GLD_SETUP_TEX1 \ + pV->t1_u = swv->texcoord[1][0]; \ + pV->t1_v = swv->texcoord[1][1] + +#define GLD_SETUP_LIGHTING(v) \ + if (facing == 1) { \ + pV->diffuse = D3DCOLOR_RGBA(vbcolor[##v][0], vbcolor[##v][1], vbcolor[##v][2], vbcolor[##v][3]); \ + if (vbspec) { \ + pV->specular = D3DCOLOR_RGBA(vbspec[##v][0], vbspec[##v][1], vbspec[##v][2], vbspec[##v][3]); \ + } \ + } else { \ + if (bFog) \ + GLD_SETUP_FOG; \ + else \ + GLD_SETUP_SMOOTH_COLOUR; \ + GLD_SETUP_SPECULAR; \ + } + +#define GLD_SETUP_GET_FLAT_LIGHTING(v) \ + if (facing == 1) { \ + dwFlatColour = D3DCOLOR_RGBA(vbcolor[##v][0], vbcolor[##v][1], vbcolor[##v][2], vbcolor[##v][3]); \ + if (vbspec) { \ + dwSpecularColour = D3DCOLOR_RGBA(vbspec[##v][0], vbspec[##v][1], vbspec[##v][2], vbspec[##v][3]); \ + } \ + } + +#define GLD_SETUP_TWOSIDED_LIGHTING \ + /* Two-sided lighting */ \ + if (ctx->_TriangleCaps & DD_TRI_LIGHT_TWOSIDE) { \ + SWvertex *verts = SWSETUP_CONTEXT(ctx)->verts; \ + SWvertex *v[3]; \ + GLfloat ex,ey,fx,fy,cc; \ + /* Get vars for later */ \ + VB = &TNL_CONTEXT(ctx)->vb; \ + vbcolor = (GLchan (*)[4])VB->ColorPtr[1]->data; \ + if (VB->SecondaryColorPtr[1]) { \ + vbspec = (GLchan (*)[4])VB->SecondaryColorPtr[1]->data; \ + } else { \ + vbspec = NULL; \ + } \ + v[0] = &verts[v0]; \ + v[1] = &verts[v1]; \ + v[2] = &verts[v2]; \ + ex = v[0]->win[0] - v[2]->win[0]; \ + ey = v[0]->win[1] - v[2]->win[1]; \ + fx = v[1]->win[0] - v[2]->win[0]; \ + fy = v[1]->win[1] - v[2]->win[1]; \ + cc = ex*fy - ey*fx; \ + facing = (cc < 0.0) ^ ctx->Polygon._FrontBit; \ + } + +//--------------------------------------------------------------------------- +// 3D vertex setup +//--------------------------------------------------------------------------- + +#define GLD_SETUP_3D_VARS_POINTS \ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); \ + GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); \ + GLD_3D_VERTEX *pV = (GLD_3D_VERTEX*)gld->PB3d.pPoints; \ + TNLcontext *tnl = TNL_CONTEXT(ctx); \ + struct vertex_buffer *VB = &tnl->vb; \ + GLfloat (*p4f)[4]; \ + GLfloat (*tc)[4]; \ + DWORD dwColor; + +#define GLD_SETUP_3D_VARS_LINES \ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); \ + GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); \ + GLD_3D_VERTEX *pV = (GLD_3D_VERTEX*)gld->PB3d.pLines; \ + TNLcontext *tnl = TNL_CONTEXT(ctx); \ + struct vertex_buffer *VB = &tnl->vb; \ + GLfloat (*p4f)[4]; \ + GLfloat (*tc)[4]; \ + DWORD dwColor; + +#define GLD_SETUP_3D_VARS_TRIANGLES \ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); \ + GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); \ + GLD_3D_VERTEX *pV = (GLD_3D_VERTEX*)gld->PB3d.pTriangles; \ + TNLcontext *tnl = TNL_CONTEXT(ctx); \ + struct vertex_buffer *VB = &tnl->vb; \ + GLfloat (*p4f)[4]; \ + GLfloat (*tc)[4]; \ + DWORD dwColor; + +#define GLD_SETUP_3D_VERTEX(v) \ + p4f = VB->ObjPtr->data; \ + pV->Position.x = p4f[##v][0]; \ + pV->Position.y = p4f[##v][1]; \ + pV->Position.z = p4f[##v][2]; + +#define GLD_SETUP_SMOOTH_COLOUR_3D(v) \ + p4f = (GLfloat (*)[4])VB->ColorPtr[0]->data; \ + pV->Diffuse = D3DCOLOR_COLORVALUE(p4f[##v][0], p4f[##v][1], p4f[##v][2], p4f[##v][3]); + + +#define GLD_SETUP_GET_FLAT_COLOUR_3D(v) \ + p4f = (GLfloat (*)[4])VB->ColorPtr[0]->data; \ + dwColor = D3DCOLOR_COLORVALUE(p4f[##v][0], p4f[##v][1], p4f[##v][2], p4f[##v][3]); + +#define GLD_SETUP_USE_FLAT_COLOUR_3D \ + pV->Diffuse = dwColor; + +#define GLD_SETUP_TEX0_3D(v) \ + if (VB->TexCoordPtr[0]) { \ + tc = VB->TexCoordPtr[0]->data; \ + pV->TexUnit0.x = tc[##v][0]; \ + pV->TexUnit0.y = tc[##v][1]; \ + } + +#define GLD_SETUP_TEX1_3D(v) \ + if (VB->TexCoordPtr[1]) { \ + tc = VB->TexCoordPtr[1]->data; \ + pV->TexUnit1.x = tc[##v][0]; \ + pV->TexUnit1.y = tc[##v][1]; \ + } + +//--------------------------------------------------------------------------- +// Helper functions +//--------------------------------------------------------------------------- + +__inline DWORD _gldComputeFog( + GLcontext *ctx, + SWvertex *swv) +{ + // Full fog calculation. + // Based on Mesa code. + + GLchan rFog, gFog, bFog; + GLchan fR, fG, fB; + const GLfloat f = swv->fog; + const GLfloat g = 1.0 - f; + + UNCLAMPED_FLOAT_TO_CHAN(rFog, ctx->Fog.Color[RCOMP]); + UNCLAMPED_FLOAT_TO_CHAN(gFog, ctx->Fog.Color[GCOMP]); + UNCLAMPED_FLOAT_TO_CHAN(bFog, ctx->Fog.Color[BCOMP]); + fR = f * swv->color[0] + g * rFog; + fG = f * swv->color[1] + g * gFog; + fB = f * swv->color[2] + g * bFog; + return D3DCOLOR_RGBA(fR, fG, fB, swv->color[3]); +} + +//--------------------------------------------------------------------------- + +void gld_ResetLineStipple_DX9( + GLcontext *ctx) +{ + // TODO: Fake stipple with a 32x32 texture. +} + +//--------------------------------------------------------------------------- +// 2D (post-transformed) primitives +//--------------------------------------------------------------------------- + +void gld_Points2D_DX9( + GLcontext *ctx, + GLuint first, + GLuint last) +{ + GLD_SETUP_2D_VARS_POINTS; + + unsigned i; + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + + // _Size is already clamped to MaxPointSize and MinPointSize + IDirect3DDevice9_SetRenderState(gld->pDev, D3DRS_POINTSIZE, *((DWORD*)&ctx->Point._Size)); + + if (VB->Elts) { + for (i=first; iClipMask[VB->Elts[i]] == 0) { +// _swrast_Point( ctx, &verts[VB->Elts[i]] ); + GLD_SETUP_GET_SWVERT(VB->Elts[i]); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_SMOOTH_COLOUR; + GLD_SETUP_DEPTH; + GLD_SETUP_SPECULAR; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + } + } + } else { + GLD_SETUP_GET_SWVERT(first); + for (i=first; iClipMask[i] == 0) { +// _swrast_Point( ctx, &verts[i] ); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_SMOOTH_COLOUR; + GLD_SETUP_DEPTH; + GLD_SETUP_SPECULAR; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + } + } + } + + gld->PB2d.pPoints = (BYTE*)pV; + gld->PB2d.nPoints += (last-first); +} + +//--------------------------------------------------------------------------- + +void gld_Line2DFlat_DX9( + GLcontext *ctx, + GLuint v0, + GLuint v1) +{ + GLD_SETUP_2D_VARS_LINES; + + GLD_SETUP_GET_SWVERT(v1); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_GET_FLAT_COLOUR; + GLD_SETUP_USE_FLAT_COLOUR; + GLD_SETUP_GET_FLAT_SPECULAR; + GLD_SETUP_USE_FLAT_SPECULAR; + pV++; + + GLD_SETUP_GET_SWVERT(v0); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + GLD_SETUP_USE_FLAT_SPECULAR; + pV++; + + gld->PB2d.pLines = (BYTE*)pV; + gld->PB2d.nLines++; +} + +//--------------------------------------------------------------------------- + +void gld_Line2DSmooth_DX9( + GLcontext *ctx, + GLuint v0, + GLuint v1) +{ + GLD_SETUP_2D_VARS_LINES; + + GLD_SETUP_GET_SWVERT(v0); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_SMOOTH_COLOUR; + GLD_SETUP_DEPTH; + GLD_SETUP_SPECULAR; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + pV++; + + GLD_SETUP_GET_SWVERT(v1); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_SMOOTH_COLOUR; + GLD_SETUP_SPECULAR; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + pV++; + + gld->PB2d.pLines = (BYTE*)pV; + gld->PB2d.nLines++; +} + +//--------------------------------------------------------------------------- + +void gld_Triangle2DFlat_DX9( + GLcontext *ctx, + GLuint v0, + GLuint v1, + GLuint v2) +{ + GLD_SETUP_2D_VARS_TRIANGLES; + + GLD_SETUP_GET_SWVERT(v2); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_GET_FLAT_COLOUR; + GLD_SETUP_USE_FLAT_COLOUR; + pV++;; + + GLD_SETUP_GET_SWVERT(v0); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + pV++; + + GLD_SETUP_GET_SWVERT(v1); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + pV++; + + gld->PB2d.pTriangles = (BYTE*)pV; + gld->PB2d.nTriangles++; +} + +//--------------------------------------------------------------------------- + +void gld_Triangle2DSmooth_DX9( + GLcontext *ctx, + GLuint v0, + GLuint v1, + GLuint v2) +{ + + GLD_SETUP_2D_VARS_TRIANGLES; + + GLD_SETUP_GET_SWVERT(v0); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_SMOOTH_COLOUR; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + pV++; + + GLD_SETUP_GET_SWVERT(v1); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_SMOOTH_COLOUR; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + pV++; + + GLD_SETUP_GET_SWVERT(v2); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_SMOOTH_COLOUR; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + pV++; + + gld->PB2d.pTriangles = (BYTE*)pV; + gld->PB2d.nTriangles++; +} + +//--------------------------------------------------------------------------- + +void gld_Triangle2DFlatExtras_DX9( + GLcontext *ctx, + GLuint v0, + GLuint v1, + GLuint v2) +{ + GLD_SETUP_2D_VARS_TRIANGLES; + + GLD_SETUP_TWOSIDED_LIGHTING(v2); + + GLD_SETUP_GET_SWVERT(v2); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + if (bFog) + GLD_SETUP_GET_FLAT_FOG_COLOUR; + else + GLD_SETUP_GET_FLAT_COLOUR; + GLD_SETUP_GET_FLAT_SPECULAR; + GLD_SETUP_GET_FLAT_LIGHTING(v2); + GLD_SETUP_USE_FLAT_COLOUR; + GLD_SETUP_USE_FLAT_SPECULAR; + pV++; + + GLD_SETUP_GET_SWVERT(v0); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + GLD_SETUP_USE_FLAT_SPECULAR; + pV++; + + GLD_SETUP_GET_SWVERT(v1); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + GLD_SETUP_USE_FLAT_SPECULAR; + pV++; + + gld->PB2d.pTriangles = (BYTE*)pV; + gld->PB2d.nTriangles++; +} + +//--------------------------------------------------------------------------- + +void gld_Triangle2DSmoothExtras_DX9( + GLcontext *ctx, + GLuint v0, + GLuint v1, + GLuint v2) +{ + GLD_SETUP_2D_VARS_TRIANGLES; + + GLD_SETUP_TWOSIDED_LIGHTING(v0); + + GLD_SETUP_GET_SWVERT(v0); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_LIGHTING(v0); + pV++; + + GLD_SETUP_GET_SWVERT(v1); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_LIGHTING(v1); + pV++; + + GLD_SETUP_GET_SWVERT(v2); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_LIGHTING(v2); + pV++; + + gld->PB2d.pTriangles = (BYTE*)pV; + gld->PB2d.nTriangles++; +} + +//--------------------------------------------------------------------------- + +void gld_Quad2DFlat_DX9( + GLcontext *ctx, + GLuint v0, + GLuint v1, + GLuint v2, + GLuint v3) +{ + GLD_SETUP_2D_VARS_TRIANGLES; + + GLD_SETUP_GET_SWVERT(v3); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_GET_FLAT_COLOUR; + GLD_SETUP_USE_FLAT_COLOUR; + pV++; + + GLD_SETUP_GET_SWVERT(v0); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + pV++; + + GLD_SETUP_GET_SWVERT(v1); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + pV++; + + GLD_SETUP_GET_SWVERT(v1); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + pV++; + + GLD_SETUP_GET_SWVERT(v2); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + pV++; + + GLD_SETUP_GET_SWVERT(v3); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + pV++; + + gld->PB2d.pTriangles = (BYTE*)pV; + gld->PB2d.nTriangles += 2; +} + +//--------------------------------------------------------------------------- + +void gld_Quad2DSmooth_DX9( + GLcontext *ctx, + GLuint v0, + GLuint v1, + GLuint v2, + GLuint v3) +{ + GLD_SETUP_2D_VARS_TRIANGLES; + + GLD_SETUP_GET_SWVERT(v0); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_SMOOTH_COLOUR; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + pV++; + + GLD_SETUP_GET_SWVERT(v1); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_SMOOTH_COLOUR; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + pV++; + + GLD_SETUP_GET_SWVERT(v2); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_SMOOTH_COLOUR; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + pV++; + + GLD_SETUP_GET_SWVERT(v2); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_SMOOTH_COLOUR; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + pV++; + + GLD_SETUP_GET_SWVERT(v3); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_SMOOTH_COLOUR; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + pV++; + + GLD_SETUP_GET_SWVERT(v0); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_SMOOTH_COLOUR; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + pV++; + + gld->PB2d.pTriangles = (BYTE*)pV; + gld->PB2d.nTriangles += 2; +} + +//--------------------------------------------------------------------------- + +void gld_Quad2DFlatExtras_DX9( + GLcontext *ctx, + GLuint v0, + GLuint v1, + GLuint v2, + GLuint v3) +{ + GLD_SETUP_2D_VARS_TRIANGLES; + + GLD_SETUP_TWOSIDED_LIGHTING(v3); + + GLD_SETUP_GET_SWVERT(v3); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + if (bFog) + GLD_SETUP_GET_FLAT_FOG_COLOUR; + else + GLD_SETUP_GET_FLAT_COLOUR; + GLD_SETUP_GET_FLAT_SPECULAR; + GLD_SETUP_GET_FLAT_LIGHTING(v3); + GLD_SETUP_USE_FLAT_COLOUR; + GLD_SETUP_USE_FLAT_SPECULAR; + pV++; + + GLD_SETUP_GET_SWVERT(v0); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + GLD_SETUP_USE_FLAT_SPECULAR; + pV++; + + GLD_SETUP_GET_SWVERT(v1); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + GLD_SETUP_USE_FLAT_SPECULAR; + pV++; + + GLD_SETUP_GET_SWVERT(v1); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + GLD_SETUP_USE_FLAT_SPECULAR; + pV++; + + GLD_SETUP_GET_SWVERT(v2); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + GLD_SETUP_USE_FLAT_SPECULAR; + pV++; + + GLD_SETUP_GET_SWVERT(v3); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_USE_FLAT_COLOUR; + GLD_SETUP_USE_FLAT_SPECULAR; + pV++; + + gld->PB2d.pTriangles = (BYTE*)pV; + gld->PB2d.nTriangles += 2; +} + +//--------------------------------------------------------------------------- + +void gld_Quad2DSmoothExtras_DX9( + GLcontext *ctx, + GLuint v0, + GLuint v1, + GLuint v2, + GLuint v3) +{ + GLD_SETUP_2D_VARS_TRIANGLES; + + GLD_SETUP_TWOSIDED_LIGHTING(v0); + + GLD_SETUP_GET_SWVERT(v0); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_LIGHTING(v0); + pV++; + + GLD_SETUP_GET_SWVERT(v1); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_LIGHTING(v1); + pV++; + + GLD_SETUP_GET_SWVERT(v2); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_LIGHTING(v2); + pV++; + + GLD_SETUP_GET_SWVERT(v2); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_LIGHTING(v2); + pV++; + + GLD_SETUP_GET_SWVERT(v3); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_LIGHTING(v3); + pV++; + + GLD_SETUP_GET_SWVERT(v0); + GLD_SETUP_2D_VERTEX; + GLD_SETUP_DEPTH; + GLD_SETUP_TEX0; + GLD_SETUP_TEX1; + GLD_SETUP_LIGHTING(v0); + pV++; + + gld->PB2d.pTriangles = (BYTE*)pV; + gld->PB2d.nTriangles += 2; +} + +//--------------------------------------------------------------------------- +// 3D (pre-transformed) primitives +//--------------------------------------------------------------------------- + +void gld_Points3D_DX9( + GLcontext *ctx, + GLuint first, + GLuint last) +{ + GLD_SETUP_3D_VARS_POINTS + + unsigned i; +// struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + + // _Size is already clamped to MaxPointSize and MinPointSize + IDirect3DDevice9_SetRenderState(gld->pDev, D3DRS_POINTSIZE, *((DWORD*)&ctx->Point._Size)); + + if (VB->Elts) { + for (i=first; iClipMask[VB->Elts[i]] == 0) { +// _swrast_Point( ctx, &verts[VB->Elts[i]] ); +// GLD_SETUP_GET_SWVERT(VB->Elts[i]); + GLD_SETUP_3D_VERTEX(VB->Elts[i]) + GLD_SETUP_SMOOTH_COLOUR_3D(i) + GLD_SETUP_TEX0_3D(i) + GLD_SETUP_TEX1_3D(i) + } + } + } else { +// GLD_SETUP_GET_SWVERT(first); + for (i=first; iClipMask[i] == 0) { +// _swrast_Point( ctx, &verts[i] ); + GLD_SETUP_3D_VERTEX(i) + GLD_SETUP_SMOOTH_COLOUR_3D(i) + GLD_SETUP_TEX0_3D(i) + GLD_SETUP_TEX1_3D(i) + } + } + } +/* + for (i=first; iPB3d.pPoints = (BYTE*)pV; + gld->PB3d.nPoints += (last-first); +} + +//--------------------------------------------------------------------------- +// Line functions +//--------------------------------------------------------------------------- + +void gld_Line3DFlat_DX9( + GLcontext *ctx, + GLuint v0, + GLuint v1) +{ + GLD_SETUP_3D_VARS_LINES + + GLD_SETUP_3D_VERTEX(v1) + GLD_SETUP_GET_FLAT_COLOUR_3D(v1) + GLD_SETUP_USE_FLAT_COLOUR_3D + GLD_SETUP_TEX0_3D(v1) + GLD_SETUP_TEX1_3D(v1) + pV++; + + GLD_SETUP_3D_VERTEX(v0) + GLD_SETUP_USE_FLAT_COLOUR_3D + GLD_SETUP_TEX0_3D(v0) + GLD_SETUP_TEX1_3D(v0) + pV++; + + gld->PB3d.pLines = (BYTE*)pV; + gld->PB3d.nLines++; +} + +//--------------------------------------------------------------------------- + +void gld_Line3DSmooth_DX9( + GLcontext *ctx, + GLuint v0, + GLuint v1) +{ + GLD_SETUP_3D_VARS_LINES + + GLD_SETUP_3D_VERTEX(v1) + GLD_SETUP_SMOOTH_COLOUR_3D(v1) + GLD_SETUP_TEX0_3D(v1) + GLD_SETUP_TEX1_3D(v1) + pV++; + + GLD_SETUP_3D_VERTEX(v0) + GLD_SETUP_SMOOTH_COLOUR_3D(v0) + GLD_SETUP_TEX0_3D(v0) + GLD_SETUP_TEX1_3D(v0) + pV++; + + gld->PB3d.pLines = (BYTE*)pV; + gld->PB3d.nLines++; +} + +//--------------------------------------------------------------------------- +// Triangle functions +//--------------------------------------------------------------------------- + +void gld_Triangle3DFlat_DX9( + GLcontext *ctx, + GLuint v0, + GLuint v1, + GLuint v2) +{ + GLD_SETUP_3D_VARS_TRIANGLES + + GLD_SETUP_3D_VERTEX(v2) + GLD_SETUP_TEX0_3D(v2) + GLD_SETUP_TEX1_3D(v2) + GLD_SETUP_GET_FLAT_COLOUR_3D(v2) + GLD_SETUP_USE_FLAT_COLOUR_3D + pV++; + + GLD_SETUP_3D_VERTEX(v0) + GLD_SETUP_TEX0_3D(v0) + GLD_SETUP_TEX1_3D(v0) + GLD_SETUP_USE_FLAT_COLOUR_3D + pV++; + + GLD_SETUP_3D_VERTEX(v1) + GLD_SETUP_TEX0_3D(v1) + GLD_SETUP_TEX1_3D(v1) + GLD_SETUP_USE_FLAT_COLOUR_3D + pV++; + + gld->PB3d.pTriangles = (BYTE*)pV; + gld->PB3d.nTriangles++; +} + +//--------------------------------------------------------------------------- + +void gld_Triangle3DSmooth_DX9( + GLcontext *ctx, + GLuint v0, + GLuint v1, + GLuint v2) +{ + GLD_SETUP_3D_VARS_TRIANGLES + + GLD_SETUP_3D_VERTEX(v0) + GLD_SETUP_SMOOTH_COLOUR_3D(v0) + GLD_SETUP_TEX0_3D(v0) + GLD_SETUP_TEX1_3D(v0) + pV++; + + GLD_SETUP_3D_VERTEX(v1) + GLD_SETUP_SMOOTH_COLOUR_3D(v1) + GLD_SETUP_TEX0_3D(v1) + GLD_SETUP_TEX1_3D(v1) + pV++; + + GLD_SETUP_3D_VERTEX(v2) + GLD_SETUP_SMOOTH_COLOUR_3D(v2) + GLD_SETUP_TEX0_3D(v2) + GLD_SETUP_TEX1_3D(v2) + pV++; + + gld->PB3d.pTriangles = (BYTE*)pV; + gld->PB3d.nTriangles++; +} + +//--------------------------------------------------------------------------- +// Quad functions +//--------------------------------------------------------------------------- + +void gld_Quad3DFlat_DX9( + GLcontext *ctx, + GLuint v0, + GLuint v1, + GLuint v2, + GLuint v3) +{ + GLD_SETUP_3D_VARS_TRIANGLES + + GLD_SETUP_3D_VERTEX(v3) + GLD_SETUP_GET_FLAT_COLOUR_3D(v3) + GLD_SETUP_USE_FLAT_COLOUR_3D + GLD_SETUP_TEX0_3D(v3) + GLD_SETUP_TEX1_3D(v3) + pV++; + + GLD_SETUP_3D_VERTEX(v0) + GLD_SETUP_USE_FLAT_COLOUR_3D + GLD_SETUP_TEX0_3D(v0) + GLD_SETUP_TEX1_3D(v0) + pV++; + + GLD_SETUP_3D_VERTEX(v1) + GLD_SETUP_USE_FLAT_COLOUR_3D + GLD_SETUP_TEX0_3D(v1) + GLD_SETUP_TEX1_3D(v1) + pV++; + + GLD_SETUP_3D_VERTEX(v1) + GLD_SETUP_USE_FLAT_COLOUR_3D + GLD_SETUP_TEX0_3D(v1) + GLD_SETUP_TEX1_3D(v1) + pV++; + + GLD_SETUP_3D_VERTEX(v2) + GLD_SETUP_USE_FLAT_COLOUR_3D + GLD_SETUP_TEX0_3D(v2) + GLD_SETUP_TEX1_3D(v2) + pV++; + + GLD_SETUP_3D_VERTEX(v3) + GLD_SETUP_USE_FLAT_COLOUR_3D + GLD_SETUP_TEX0_3D(v3) + GLD_SETUP_TEX1_3D(v3) + pV++; + + gld->PB3d.pTriangles = (BYTE*)pV; + gld->PB3d.nTriangles += 2; +} + +//--------------------------------------------------------------------------- + +void gld_Quad3DSmooth_DX9( + GLcontext *ctx, + GLuint v0, + GLuint v1, + GLuint v2, + GLuint v3) +{ + GLD_SETUP_3D_VARS_TRIANGLES + + GLD_SETUP_3D_VERTEX(v0) + GLD_SETUP_SMOOTH_COLOUR_3D(v0) + GLD_SETUP_TEX0_3D(v0) + GLD_SETUP_TEX1_3D(v0) + pV++; + + GLD_SETUP_3D_VERTEX(v1) + GLD_SETUP_SMOOTH_COLOUR_3D(v1) + GLD_SETUP_TEX0_3D(v1) + GLD_SETUP_TEX1_3D(v1) + pV++; + + GLD_SETUP_3D_VERTEX(v2) + GLD_SETUP_SMOOTH_COLOUR_3D(v2) + GLD_SETUP_TEX0_3D(v2) + GLD_SETUP_TEX1_3D(v2) + pV++; + + GLD_SETUP_3D_VERTEX(v2) + GLD_SETUP_SMOOTH_COLOUR_3D(v2) + GLD_SETUP_TEX0_3D(v2) + GLD_SETUP_TEX1_3D(v2) + pV++; + + GLD_SETUP_3D_VERTEX(v3) + GLD_SETUP_SMOOTH_COLOUR_3D(v3) + GLD_SETUP_TEX0_3D(v3) + GLD_SETUP_TEX1_3D(v3) + pV++; + + GLD_SETUP_3D_VERTEX(v0) + GLD_SETUP_SMOOTH_COLOUR_3D(v0) + GLD_SETUP_TEX0_3D(v0) + GLD_SETUP_TEX1_3D(v0) + pV++; + + gld->PB3d.pTriangles = (BYTE*)pV; + gld->PB3d.nTriangles += 2; +} + +//--------------------------------------------------------------------------- +// Vertex setup for two-sided-lighting vertex shader +//--------------------------------------------------------------------------- + +/* + +void gld_Points2DTwoside_DX9(GLcontext *ctx, GLuint first, GLuint last) +{ + // NOTE: Two-sided lighting does not apply to Points +} + +//--------------------------------------------------------------------------- + +void gld_Line2DFlatTwoside_DX9(GLcontext *ctx, GLuint v0, GLuint v1) +{ + // NOTE: Two-sided lighting does not apply to Lines +} + +//--------------------------------------------------------------------------- + +void gld_Line2DSmoothTwoside_DX9(GLcontext *ctx, GLuint v0, GLuint v1) +{ + // NOTE: Two-sided lighting does not apply to Lines +} + +//--------------------------------------------------------------------------- + +void gld_Triangle2DFlatTwoside_DX9(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2) +{ +} + +//--------------------------------------------------------------------------- + +void gld_Triangle2DSmoothTwoside_DX9(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); + GLD_TWOSIDED_VERTEX *pV = (GLD_TWOSIDED_VERTEX*)gld->PBtwosidelight.pTriangles; + SScontext *ss = SWSETUP_CONTEXT(ctx); + SWvertex *swv; + DWORD dwSpecularColour; + DWORD dwFlatColour; + GLuint facing = 0; + struct vertex_buffer *VB; + GLchan (*vbcolor)[4]; + GLchan (*vbspec)[4]; + + // Reciprocal of DepthMax + const float ooDepthMax = 1.0f / ctx->DepthMaxF; + + // 1st vert + swv = &ss->verts[v0]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + // 2nd vert + swv = &ss->verts[v1]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + // 3rd vert + swv = &ss->verts[v2]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + gld->PBtwosidelight.pTriangles = (BYTE*)pV; + gld->PBtwosidelight.nTriangles++; +} + +//--------------------------------------------------------------------------- + +void gld_Quad2DFlatTwoside_DX9(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); + GLD_TWOSIDED_VERTEX *pV = (GLD_TWOSIDED_VERTEX*)gld->PBtwosidelight.pTriangles; + SScontext *ss = SWSETUP_CONTEXT(ctx); + SWvertex *swv; + DWORD dwSpecularColour; + DWORD dwFlatColour; + GLuint facing = 0; + struct vertex_buffer *VB; + GLchan (*vbcolor)[4]; + GLchan (*vbspec)[4]; + + // Reciprocal of DepthMax + const float ooDepthMax = 1.0f / ctx->DepthMaxF; + + // 1st vert + swv = &ss->verts[v0]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + // 2nd vert + swv = &ss->verts[v1]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + // 3rd vert + swv = &ss->verts[v2]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + // 4th vert + swv = &ss->verts[v2]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + // 5th vert + swv = &ss->verts[v3]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + // 6th vert + swv = &ss->verts[v0]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + gld->PBtwosidelight.pTriangles = (BYTE*)pV; + gld->PBtwosidelight.nTriangles += 2; +} + +//--------------------------------------------------------------------------- + +void gld_Quad2DSmoothTwoside_DX9(GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); + GLD_TWOSIDED_VERTEX *pV = (GLD_TWOSIDED_VERTEX*)gld->PBtwosidelight.pTriangles; + SScontext *ss = SWSETUP_CONTEXT(ctx); + SWvertex *swv; + DWORD dwSpecularColour; + DWORD dwFlatColour; + GLuint facing = 0; + struct vertex_buffer *VB; + GLchan (*vbcolor)[4]; + GLchan (*vbspec)[4]; + + // Reciprocal of DepthMax + const float ooDepthMax = 1.0f / ctx->DepthMaxF; + + // 1st vert + swv = &ss->verts[v0]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + // 2nd vert + swv = &ss->verts[v1]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + // 3rd vert + swv = &ss->verts[v2]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + // 4th vert + swv = &ss->verts[v2]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + // 5th vert + swv = &ss->verts[v3]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + // 6th vert + swv = &ss->verts[v0]; + pV->Position.x = swv->win[0]; + pV->Position.y = GLD_FLIP_Y(swv->win[1]); + pV->Position.z = swv->win[2] * ooDepthMax; + pV->Position.w = swv->win[3]; + pV->TexUnit0.x = swv->texcoord[0][0]; + pV->TexUnit0.y = swv->texcoord[0][1]; + pV->TexUnit1.x = swv->texcoord[1][0]; + pV->TexUnit1.y = swv->texcoord[1][1]; + pV->FrontDiffuse = GLD_COLOUR; + pV->FrontSpecular = GLD_SPECULAR; + pV++; + + gld->PBtwosidelight.pTriangles = (BYTE*)pV; + gld->PBtwosidelight.nTriangles += 2; +} + +//--------------------------------------------------------------------------- + +*/ diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_texture_dx9.c b/mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_texture_dx9.c new file mode 100644 index 000000000..5a8223561 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_texture_dx9.c @@ -0,0 +1,2104 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x/2000/XP/XBox (Win32) +* +* Description: Texture / Bitmap functions +* +****************************************************************************/ + +#include "dglcontext.h" +#include "ddlog.h" +#include "gld_dx9.h" + +#include + +#include "texformat.h" +#include "colormac.h" +#include "texstore.h" +#include "image.h" +// #include "mem.h" + +//--------------------------------------------------------------------------- + +#define GLD_FLIP_HEIGHT(y,h) (gldCtx->dwHeight - (y) - (h)) + +//--------------------------------------------------------------------------- +// 1D texture fetch +//--------------------------------------------------------------------------- + +#define CHAN_SRC( t, i, j, k, sz ) \ + ((GLchan *)(t)->Data + (i) * (sz)) +#define UBYTE_SRC( t, i, j, k, sz ) \ + ((GLubyte *)(t)->Data + (i) * (sz)) +#define USHORT_SRC( t, i, j, k ) \ + ((GLushort *)(t)->Data + (i)) +#define FLOAT_SRC( t, i, j, k ) \ + ((GLfloat *)(t)->Data + (i)) + +//--------------------------------------------------------------------------- + +static void gld_fetch_1d_texel_X8R8G8B8( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *texel ) +{ + const GLchan *src = CHAN_SRC( texImage, i, j, k, 4 ); + GLchan *rgba = (GLchan *)texel; + rgba[RCOMP] = src[2]; + rgba[GCOMP] = src[1]; + rgba[BCOMP] = src[0]; + rgba[ACOMP] = CHAN_MAX; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_1d_texel_f_X8R8G8B8( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLfloat *texel ) +{ + const GLchan *src = CHAN_SRC( texImage, i, j, k, 4 ); + texel[RCOMP] = CHAN_TO_FLOAT(src[0]); + texel[GCOMP] = CHAN_TO_FLOAT(src[1]); + texel[BCOMP] = CHAN_TO_FLOAT(src[2]); + texel[ACOMP] = 1.f; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_1d_texel_X1R5G5B5( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *texel ) +{ + const GLushort *src = USHORT_SRC( texImage, i, j, k ); + GLchan *rgba = (GLchan *) texel; GLushort s = *src; + rgba[RCOMP] = UBYTE_TO_CHAN( ((s >> 10) & 0xf8) * 255 / 0xf8 ); + rgba[GCOMP] = UBYTE_TO_CHAN( ((s >> 5) & 0xf8) * 255 / 0xf8 ); + rgba[BCOMP] = UBYTE_TO_CHAN( ((s ) & 0xf8) * 255 / 0xf8 ); + rgba[ACOMP] = CHAN_MAX; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_1d_texel_f_X1R5G5B5( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLfloat *texel ) +{ + const GLushort *src = USHORT_SRC( texImage, i, j, k ); + GLushort s = *src; + texel[RCOMP] = UBYTE_TO_FLOAT( ((s >> 10) & 0xf8) * 255 / 0xf8 ); + texel[GCOMP] = UBYTE_TO_FLOAT( ((s >> 5) & 0xf8) * 255 / 0xf8 ); + texel[BCOMP] = UBYTE_TO_FLOAT( ((s ) & 0xf8) * 255 / 0xf8 ); + texel[ACOMP] = 1.f; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_1d_texel_X4R4G4B4( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *texel ) +{ + const GLushort *src = USHORT_SRC( texImage, i, j, k ); + GLchan *rgba = (GLchan *) texel; GLushort s = *src; + rgba[RCOMP] = UBYTE_TO_CHAN( ((s >> 8) & 0xf) * 255 / 0xf ); + rgba[GCOMP] = UBYTE_TO_CHAN( ((s >> 4) & 0xf) * 255 / 0xf ); + rgba[BCOMP] = UBYTE_TO_CHAN( ((s ) & 0xf) * 255 / 0xf ); + rgba[ACOMP] = CHAN_MAX; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_1d_texel_f_X4R4G4B4( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLfloat *texel ) +{ + const GLushort *src = USHORT_SRC( texImage, i, j, k ); + GLushort s = *src; + texel[RCOMP] = UBYTE_TO_FLOAT( ((s >> 8) & 0xf) * 255 / 0xf ); + texel[GCOMP] = UBYTE_TO_FLOAT( ((s >> 4) & 0xf) * 255 / 0xf ); + texel[BCOMP] = UBYTE_TO_FLOAT( ((s ) & 0xf) * 255 / 0xf ); + texel[ACOMP] = 1.f; +} + +//--------------------------------------------------------------------------- + +#undef CHAN_SRC +#undef UBYTE_SRC +#undef USHORT_SRC +#undef FLOAT_SRC + +//--------------------------------------------------------------------------- +// 2D texture fetch +//--------------------------------------------------------------------------- + +#define CHAN_SRC( t, i, j, k, sz ) \ + ((GLchan *)(t)->Data + ((t)->Width * (j) + (i)) * (sz)) +#define UBYTE_SRC( t, i, j, k, sz ) \ + ((GLubyte *)(t)->Data + ((t)->Width * (j) + (i)) * (sz)) +#define USHORT_SRC( t, i, j, k ) \ + ((GLushort *)(t)->Data + ((t)->Width * (j) + (i))) +#define FLOAT_SRC( t, i, j, k ) \ + ((GLfloat *)(t)->Data + ((t)->Width * (j) + (i))) + +//--------------------------------------------------------------------------- + +static void gld_fetch_2d_texel_X8R8G8B8( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *texel ) +{ + const GLchan *src = CHAN_SRC( texImage, i, j, k, 4 ); + GLchan *rgba = (GLchan *)texel; + rgba[RCOMP] = src[2]; + rgba[GCOMP] = src[1]; + rgba[BCOMP] = src[0]; + rgba[ACOMP] = CHAN_MAX; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_2d_texel_f_X8R8G8B8( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLfloat *texel ) +{ + const GLchan *src = CHAN_SRC( texImage, i, j, k, 4 ); + texel[RCOMP] = CHAN_TO_FLOAT(src[0]); + texel[GCOMP] = CHAN_TO_FLOAT(src[1]); + texel[BCOMP] = CHAN_TO_FLOAT(src[2]); + texel[ACOMP] = 1.f; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_2d_texel_X1R5G5B5( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *texel ) +{ + const GLushort *src = USHORT_SRC( texImage, i, j, k ); + GLchan *rgba = (GLchan *) texel; GLushort s = *src; + rgba[RCOMP] = UBYTE_TO_CHAN( ((s >> 10) & 0xf8) * 255 / 0xf8 ); + rgba[GCOMP] = UBYTE_TO_CHAN( ((s >> 5) & 0xf8) * 255 / 0xf8 ); + rgba[BCOMP] = UBYTE_TO_CHAN( ((s ) & 0xf8) * 255 / 0xf8 ); + rgba[ACOMP] = CHAN_MAX; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_2d_texel_f_X1R5G5B5( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLfloat *texel ) +{ + const GLushort *src = USHORT_SRC( texImage, i, j, k ); + GLushort s = *src; + texel[RCOMP] = UBYTE_TO_FLOAT( ((s >> 10) & 0xf8) * 255 / 0xf8 ); + texel[GCOMP] = UBYTE_TO_FLOAT( ((s >> 5) & 0xf8) * 255 / 0xf8 ); + texel[BCOMP] = UBYTE_TO_FLOAT( ((s ) & 0xf8) * 255 / 0xf8 ); + texel[ACOMP] = 1.f; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_2d_texel_X4R4G4B4( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *texel ) +{ + const GLushort *src = USHORT_SRC( texImage, i, j, k ); + GLchan *rgba = (GLchan *) texel; GLushort s = *src; + rgba[RCOMP] = UBYTE_TO_CHAN( ((s >> 8) & 0xf) * 255 / 0xf ); + rgba[GCOMP] = UBYTE_TO_CHAN( ((s >> 4) & 0xf) * 255 / 0xf ); + rgba[BCOMP] = UBYTE_TO_CHAN( ((s ) & 0xf) * 255 / 0xf ); + rgba[ACOMP] = CHAN_MAX; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_2d_texel_f_X4R4G4B4( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLfloat *texel ) +{ + const GLushort *src = USHORT_SRC( texImage, i, j, k ); + GLushort s = *src; + texel[RCOMP] = UBYTE_TO_FLOAT( ((s >> 8) & 0xf) * 255 / 0xf ); + texel[GCOMP] = UBYTE_TO_FLOAT( ((s >> 4) & 0xf) * 255 / 0xf ); + texel[BCOMP] = UBYTE_TO_FLOAT( ((s ) & 0xf) * 255 / 0xf ); + texel[ACOMP] = 1.f; +} + +//--------------------------------------------------------------------------- + +#undef CHAN_SRC +#undef UBYTE_SRC +#undef USHORT_SRC +#undef FLOAT_SRC + +//--------------------------------------------------------------------------- +// 3D texture fetch +//--------------------------------------------------------------------------- + +#define CHAN_SRC( t, i, j, k, sz ) \ + (GLchan *)(t)->Data + (((t)->Height * (k) + (j)) * \ + (t)->Width + (i)) * (sz) +#define UBYTE_SRC( t, i, j, k, sz ) \ + ((GLubyte *)(t)->Data + (((t)->Height * (k) + (j)) * \ + (t)->Width + (i)) * (sz)) +#define USHORT_SRC( t, i, j, k ) \ + ((GLushort *)(t)->Data + (((t)->Height * (k) + (j)) * \ + (t)->Width + (i))) +#define FLOAT_SRC( t, i, j, k ) \ + ((GLfloat *)(t)->Data + (((t)->Height * (k) + (j)) * \ + (t)->Width + (i))) + +//--------------------------------------------------------------------------- + +static void gld_fetch_3d_texel_X8R8G8B8( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *texel ) +{ + const GLchan *src = CHAN_SRC( texImage, i, j, k, 4 ); + GLchan *rgba = (GLchan *)texel; + rgba[RCOMP] = src[2]; + rgba[GCOMP] = src[1]; + rgba[BCOMP] = src[0]; + rgba[ACOMP] = CHAN_MAX; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_3d_texel_f_X8R8G8B8( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLfloat *texel ) +{ + const GLchan *src = CHAN_SRC( texImage, i, j, k, 4 ); + texel[RCOMP] = CHAN_TO_FLOAT(src[0]); + texel[GCOMP] = CHAN_TO_FLOAT(src[1]); + texel[BCOMP] = CHAN_TO_FLOAT(src[2]); + texel[ACOMP] = 1.f; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_3d_texel_X1R5G5B5( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *texel ) +{ + const GLushort *src = USHORT_SRC( texImage, i, j, k ); + GLchan *rgba = (GLchan *) texel; GLushort s = *src; + rgba[RCOMP] = UBYTE_TO_CHAN( ((s >> 10) & 0xf8) * 255 / 0xf8 ); + rgba[GCOMP] = UBYTE_TO_CHAN( ((s >> 5) & 0xf8) * 255 / 0xf8 ); + rgba[BCOMP] = UBYTE_TO_CHAN( ((s ) & 0xf8) * 255 / 0xf8 ); + rgba[ACOMP] = CHAN_MAX; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_3d_texel_f_X1R5G5B5( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLfloat *texel ) +{ + const GLushort *src = USHORT_SRC( texImage, i, j, k ); + GLushort s = *src; + texel[RCOMP] = UBYTE_TO_FLOAT( ((s >> 10) & 0xf8) * 255 / 0xf8 ); + texel[GCOMP] = UBYTE_TO_FLOAT( ((s >> 5) & 0xf8) * 255 / 0xf8 ); + texel[BCOMP] = UBYTE_TO_FLOAT( ((s ) & 0xf8) * 255 / 0xf8 ); + texel[ACOMP] = 1.f; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_3d_texel_X4R4G4B4( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *texel ) +{ + const GLushort *src = USHORT_SRC( texImage, i, j, k ); + GLchan *rgba = (GLchan *) texel; GLushort s = *src; + rgba[RCOMP] = UBYTE_TO_CHAN( ((s >> 8) & 0xf) * 255 / 0xf ); + rgba[GCOMP] = UBYTE_TO_CHAN( ((s >> 4) & 0xf) * 255 / 0xf ); + rgba[BCOMP] = UBYTE_TO_CHAN( ((s ) & 0xf) * 255 / 0xf ); + rgba[ACOMP] = CHAN_MAX; +} + +//--------------------------------------------------------------------------- + +static void gld_fetch_3d_texel_f_X4R4G4B4( + const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLfloat *texel ) +{ + const GLushort *src = USHORT_SRC( texImage, i, j, k ); + GLushort s = *src; + texel[RCOMP] = UBYTE_TO_FLOAT( ((s >> 8) & 0xf) * 255 / 0xf ); + texel[GCOMP] = UBYTE_TO_FLOAT( ((s >> 4) & 0xf) * 255 / 0xf ); + texel[BCOMP] = UBYTE_TO_FLOAT( ((s ) & 0xf) * 255 / 0xf ); + texel[ACOMP] = 1.f; +} + +//--------------------------------------------------------------------------- + +#undef CHAN_SRC +#undef UBYTE_SRC +#undef USHORT_SRC +#undef FLOAT_SRC + +//--------------------------------------------------------------------------- +// Direct3D texture formats that have no Mesa equivalent +//--------------------------------------------------------------------------- + +const struct gl_texture_format _gld_texformat_X8R8G8B8 = { + MESA_FORMAT_ARGB8888, /* MesaFormat */ + GL_RGBA, /* BaseFormat */ + GL_UNSIGNED_NORMALIZED_ARB, /* DataType */ + 8, /* RedBits */ + 8, /* GreenBits */ + 8, /* BlueBits */ + 0, /* AlphaBits */ + 0, /* LuminanceBits */ + 0, /* IntensityBits */ + 0, /* IndexBits */ + 0, /* DepthBits */ + 4, /* TexelBytes */ + _mesa_texstore_argb8888, /* StoreTexImageFunc */ + gld_fetch_1d_texel_X8R8G8B8, /* FetchTexel1D */ + gld_fetch_2d_texel_X8R8G8B8, /* FetchTexel2D */ + gld_fetch_3d_texel_X8R8G8B8, /* FetchTexel3D */ + gld_fetch_1d_texel_f_X8R8G8B8, /* FetchTexel1Df */ + gld_fetch_2d_texel_f_X8R8G8B8, /* FetchTexel2Df */ + gld_fetch_3d_texel_f_X8R8G8B8, /* FetchTexel3Df */ +}; + +const struct gl_texture_format _gld_texformat_X1R5G5B5 = { + MESA_FORMAT_ARGB1555, /* MesaFormat */ + GL_RGBA, /* BaseFormat */ + GL_UNSIGNED_NORMALIZED_ARB, /* DataType */ + 5, /* RedBits */ + 5, /* GreenBits */ + 5, /* BlueBits */ + 0, /* AlphaBits */ + 0, /* LuminanceBits */ + 0, /* IntensityBits */ + 0, /* IndexBits */ + 0, /* DepthBits */ + 2, /* TexelBytes */ + _mesa_texstore_argb1555, /* StoreTexImageFunc */ + gld_fetch_1d_texel_X1R5G5B5, /* FetchTexel1D */ + gld_fetch_2d_texel_X1R5G5B5, /* FetchTexel2D */ + gld_fetch_3d_texel_X1R5G5B5, /* FetchTexel3D */ + gld_fetch_1d_texel_f_X1R5G5B5, /* FetchTexel1Df */ + gld_fetch_2d_texel_f_X1R5G5B5, /* FetchTexel2Df */ + gld_fetch_3d_texel_f_X1R5G5B5, /* FetchTexel3Df */ +}; + +const struct gl_texture_format _gld_texformat_X4R4G4B4 = { + MESA_FORMAT_ARGB4444, /* MesaFormat */ + GL_RGBA, /* BaseFormat */ + GL_UNSIGNED_NORMALIZED_ARB, /* DataType */ + 4, /* RedBits */ + 4, /* GreenBits */ + 4, /* BlueBits */ + 0, /* AlphaBits */ + 0, /* LuminanceBits */ + 0, /* IntensityBits */ + 0, /* IndexBits */ + 0, /* DepthBits */ + 2, /* TexelBytes */ + _mesa_texstore_argb4444, /* StoreTexImageFunc */ + gld_fetch_1d_texel_X4R4G4B4, /* FetchTexel1D */ + gld_fetch_2d_texel_X4R4G4B4, /* FetchTexel2D */ + gld_fetch_3d_texel_X4R4G4B4, /* FetchTexel3D */ + gld_fetch_1d_texel_f_X4R4G4B4, /* FetchTexel1Df */ + gld_fetch_2d_texel_f_X4R4G4B4, /* FetchTexel2Df */ + gld_fetch_3d_texel_f_X4R4G4B4, /* FetchTexel3Df */ +}; + +//--------------------------------------------------------------------------- +// Texture unit constants +//--------------------------------------------------------------------------- + +// List of possible combinations of texture environments. +// Example: GLD_TEXENV_MODULATE_RGBA means +// GL_MODULATE, GL_RGBA base internal format. +#define GLD_TEXENV_DECAL_RGB 0 +#define GLD_TEXENV_DECAL_RGBA 1 +#define GLD_TEXENV_DECAL_ALPHA 2 +#define GLD_TEXENV_REPLACE_RGB 3 +#define GLD_TEXENV_REPLACE_RGBA 4 +#define GLD_TEXENV_REPLACE_ALPHA 5 +#define GLD_TEXENV_MODULATE_RGB 6 +#define GLD_TEXENV_MODULATE_RGBA 7 +#define GLD_TEXENV_MODULATE_ALPHA 8 +#define GLD_TEXENV_BLEND_RGB 9 +#define GLD_TEXENV_BLEND_RGBA 10 +#define GLD_TEXENV_BLEND_ALPHA 11 +#define GLD_TEXENV_ADD_RGB 12 +#define GLD_TEXENV_ADD_RGBA 13 +#define GLD_TEXENV_ADD_ALPHA 14 + +// Per-stage (i.e. per-unit) texture environment +typedef struct { + DWORD ColorArg1; // Colour argument 1 + D3DTEXTUREOP ColorOp; // Colour operation + DWORD ColorArg2; // Colour argument 2 + DWORD AlphaArg1; // Alpha argument 1 + D3DTEXTUREOP AlphaOp; // Alpha operation + DWORD AlphaArg2; // Alpha argument 2 +} GLD_texenv; + +// TODO: Do we really need to set ARG1 and ARG2 every time? +// They seem to always be TEXTURE and CURRENT respectively. + +// C = Colour out +// A = Alpha out +// Ct = Colour from Texture +// Cf = Colour from fragment (diffuse) +// At = Alpha from Texture +// Af = Alpha from fragment (diffuse) +// Cc = GL_TEXTURE_ENV_COLOUR (GL_BLEND) +const GLD_texenv gldTexEnv[] = { + // DECAL_RGB: C=Ct, A=Af + {D3DTA_TEXTURE, D3DTOP_SELECTARG1, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT}, + // DECAL_RGBA: C=Cf(1-At)+CtAt, A=Af + {D3DTA_TEXTURE, D3DTOP_BLENDTEXTUREALPHA, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT}, + // DECAL_ALPHA: use DECAL_RGB + {D3DTA_TEXTURE, D3DTOP_SELECTARG1, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT}, + + // REPLACE_RGB: C=Ct, A=Af + {D3DTA_TEXTURE, D3DTOP_SELECTARG1, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT}, + // REPLACE_RGBA: C=Ct, A=At + {D3DTA_TEXTURE, D3DTOP_SELECTARG1, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_SELECTARG1, D3DTA_CURRENT}, + // REPLACE_ALPHA: C=Cf, A=At + {D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_SELECTARG1, D3DTA_CURRENT}, + + // MODULATE_RGB: C=CfCt, A=Af + {D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT}, + // MODULATE_RGBA: C=CfCt, A=AfAt + {D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT}, + // MODULATE_ALPHA: C=Cf, A=AfAt + {D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT}, + + // BLEND_RGB: C=Cf(1-Ct)+CcCt, A=Af + {D3DTA_TEXTURE, D3DTOP_LERP, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT}, + // BLEND_RGBA: C=Cf(1-Ct)+CcCt, A=AfAt + {D3DTA_TEXTURE, D3DTOP_LERP, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT}, + // BLEND_ALPHA: C=Cf, A=AfAt + {D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT}, + + // ADD_RGB: C=Cf+Ct, A=Af + {D3DTA_TEXTURE, D3DTOP_ADD, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT}, + // ADD_RGBA: C=Cf+Ct, A=AfAt + {D3DTA_TEXTURE, D3DTOP_ADD, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT}, + // ADD_ALPHA: C=Cf, A=AfAt + {D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT}, +}; + +//--------------------------------------------------------------------------- + +D3DTEXTUREADDRESS _gldConvertWrap( + GLenum wrap) +{ + return (wrap == GL_CLAMP) ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP; +} + +//--------------------------------------------------------------------------- + +D3DTEXTUREFILTERTYPE _gldConvertMagFilter( + GLenum magfilter) +{ + return (magfilter == GL_LINEAR) ? D3DTEXF_LINEAR : D3DTEXF_POINT; +} + +//--------------------------------------------------------------------------- + +void _gldConvertMinFilter( + GLenum minfilter, + D3DTEXTUREFILTERTYPE *min_filter, + D3DTEXTUREFILTERTYPE *mip_filter) +{ + switch (minfilter) { + case GL_NEAREST: + *min_filter = D3DTEXF_POINT; + *mip_filter = D3DTEXF_NONE; + break; + case GL_LINEAR: + *min_filter = D3DTEXF_LINEAR; + *mip_filter = D3DTEXF_NONE; + break; + case GL_NEAREST_MIPMAP_NEAREST: + *min_filter = D3DTEXF_POINT; + *mip_filter = D3DTEXF_POINT; + break; + case GL_LINEAR_MIPMAP_NEAREST: + *min_filter = D3DTEXF_LINEAR; + *mip_filter = D3DTEXF_POINT; + break; + case GL_NEAREST_MIPMAP_LINEAR: + *min_filter = D3DTEXF_POINT; + *mip_filter = D3DTEXF_LINEAR; + break; + case GL_LINEAR_MIPMAP_LINEAR: + *min_filter = D3DTEXF_LINEAR; + *mip_filter = D3DTEXF_LINEAR; + break; + } +} + +//--------------------------------------------------------------------------- + +D3DFORMAT _gldGLFormatToD3DFormat( + GLenum internalFormat) +{ + switch (internalFormat) { + case GL_INTENSITY: + case GL_INTENSITY4: + case GL_INTENSITY8: + case GL_INTENSITY12: + case GL_INTENSITY16: + // LUNIMANCE != INTENSITY, but D3D doesn't have I8 textures + return D3DFMT_L8; + case 1: + case GL_LUMINANCE: + case GL_LUMINANCE4: + case GL_LUMINANCE8: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + return D3DFMT_L8; + case GL_ALPHA: + case GL_ALPHA4: + case GL_ALPHA8: + case GL_ALPHA12: + case GL_ALPHA16: + return D3DFMT_A8; + case GL_COLOR_INDEX: + case GL_COLOR_INDEX1_EXT: + case GL_COLOR_INDEX2_EXT: + case GL_COLOR_INDEX4_EXT: + case GL_COLOR_INDEX8_EXT: + case GL_COLOR_INDEX12_EXT: + case GL_COLOR_INDEX16_EXT: + return D3DFMT_X8R8G8B8; + case 2: + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE4_ALPHA4: + case GL_LUMINANCE6_ALPHA2: + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE12_ALPHA4: + case GL_LUMINANCE12_ALPHA12: + case GL_LUMINANCE16_ALPHA16: + return D3DFMT_A8L8; + case GL_R3_G3_B2: + // TODO: Mesa does not support RGB332 internally + return D3DFMT_X4R4G4B4; //D3DFMT_R3G3B2; + case GL_RGB4: + return D3DFMT_X4R4G4B4; + case GL_RGB5: + return D3DFMT_X1R5G5B5; + case 3: + case GL_RGB: + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + return D3DFMT_R8G8B8; + case GL_RGBA4: + return D3DFMT_A4R4G4B4; + case 4: + case GL_RGBA: + case GL_RGBA2: + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + return D3DFMT_A8R8G8B8; + case GL_RGB5_A1: + return D3DFMT_A1R5G5B5; + } + + // Return an acceptable default + return D3DFMT_A8R8G8B8; +} + +//--------------------------------------------------------------------------- + +GLenum _gldDecodeBaseFormat( + IDirect3DTexture9 *pTex) +{ + // Examine Direct3D texture and return base OpenGL internal texture format + // NOTE: We can't use any base format info from Mesa because D3D might have + // used a different texture format when we used D3DXCreateTexture(). + + // Base internal format is one of (Red Book p355): + // GL_ALPHA, + // GL_LUMINANCE, + // GL_LUMINANCE_ALPHA, + // GL_INTENSITY, + // GL_RGB, + // GL_RGBA + + // NOTE: INTENSITY not used (not supported by Direct3D) + // LUMINANCE has same texture functions as RGB + // LUMINANCE_ALPHA has same texture functions as RGBA + + // TODO: cache format instead of using GetLevelDesc() + D3DSURFACE_DESC desc; + _GLD_DX9_TEX(GetLevelDesc(pTex, 0, &desc)); + + switch (desc.Format) { + case D3DFMT_R8G8B8: + case D3DFMT_X8R8G8B8: + case D3DFMT_R5G6B5: + case D3DFMT_X1R5G5B5: + case D3DFMT_R3G3B2: + case D3DFMT_X4R4G4B4: + case D3DFMT_P8: + case D3DFMT_L8: + return GL_RGB; + case D3DFMT_A8R8G8B8: + case D3DFMT_A1R5G5B5: + case D3DFMT_A4R4G4B4: + case D3DFMT_A8R3G3B2: + case D3DFMT_A8P8: + case D3DFMT_A8L8: + case D3DFMT_A4L4: + return GL_RGBA; + case D3DFMT_A8: + return GL_ALPHA; + // Compressed texture formats. Need to check these... + case D3DFMT_DXT1: + return GL_RGBA; + case D3DFMT_DXT2: + return GL_RGB; + case D3DFMT_DXT3: + return GL_RGBA; + case D3DFMT_DXT4: + return GL_RGB; + case D3DFMT_DXT5: + return GL_RGBA; + } + + // Fell through. Return arbitary default. + return GL_RGBA; +} + +//--------------------------------------------------------------------------- + +const struct gl_texture_format* _gldMesaFormatForD3DFormat( + D3DFORMAT d3dfmt) +{ + switch (d3dfmt) { + case D3DFMT_A8R8G8B8: + return &_mesa_texformat_argb8888; + case D3DFMT_R8G8B8: + return &_mesa_texformat_rgb888; + case D3DFMT_R5G6B5: + return &_mesa_texformat_rgb565; + case D3DFMT_A4R4G4B4: + return &_mesa_texformat_argb4444; + case D3DFMT_A1R5G5B5: + return &_mesa_texformat_argb1555; + case D3DFMT_A8L8: + return &_mesa_texformat_al88; + case D3DFMT_R3G3B2: + return &_mesa_texformat_rgb332; + case D3DFMT_A8: + return &_mesa_texformat_a8; + case D3DFMT_L8: + return &_mesa_texformat_l8; + case D3DFMT_X8R8G8B8: + return &_gld_texformat_X8R8G8B8; + case D3DFMT_X1R5G5B5: + return &_gld_texformat_X1R5G5B5; + case D3DFMT_X4R4G4B4: + return &_gld_texformat_X4R4G4B4; + } + + // If we reach here then we've made an error somewhere else + // by allowing a format that is not supported. + assert(0); + + return NULL; // Shut up compiler warning +} + +//--------------------------------------------------------------------------- +// Copy* functions +//--------------------------------------------------------------------------- + +void gldCopyTexImage1D_DX9( + GLcontext *ctx, + GLenum target, GLint level, + GLenum internalFormat, + GLint x, GLint y, + GLsizei width, GLint border ) +{ + // TODO +} + +//--------------------------------------------------------------------------- + +void gldCopyTexImage2D_DX9( + GLcontext *ctx, + GLenum target, + GLint level, + GLenum internalFormat, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLint border) +{ + // TODO +} + +//--------------------------------------------------------------------------- + +void gldCopyTexSubImage1D_DX9( + GLcontext *ctx, + GLenum target, GLint level, + GLint xoffset, GLint x, GLint y, GLsizei width ) +{ + // TODO +} + +//--------------------------------------------------------------------------- + +void gldCopyTexSubImage2D_DX9( + GLcontext *ctx, + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height) +{ + // TODO +} + +//--------------------------------------------------------------------------- + +void gldCopyTexSubImage3D_DX9( + GLcontext *ctx, + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height ) +{ + // TODO ? +} + +//--------------------------------------------------------------------------- +// Bitmap/Pixel functions +//--------------------------------------------------------------------------- + +#define GLD_FLIP_Y(y) (gldCtx->dwHeight - (y)) + +#define _GLD_FVF_IMAGE (D3DFVF_XYZRHW | D3DFVF_TEX1) + +typedef struct { + FLOAT x, y; // 2D raster coords + FLOAT z; // depth value + FLOAT rhw; // reciprocal homogenous W (always 1.0f) + FLOAT tu, tv; // texture coords +} _GLD_IMAGE_VERTEX; + +//--------------------------------------------------------------------------- + +HRESULT _gldDrawPixels( + GLcontext *ctx, + BOOL bChromakey, // Alpha test for glBitmap() images + GLint x, // GL x position + GLint y, // GL y position (needs flipping) + GLsizei width, // Width of input image + GLsizei height, // Height of input image + IDirect3DSurface9 *pImage) +{ + // + // Draw input image as texture implementing PixelZoom and clipping. + // Any fragment operations currently enabled will be used. + // + + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); + + IDirect3DTexture9 *pTexture; + D3DSURFACE_DESC d3dsd; + IDirect3DSurface9 *pSurface; + _GLD_IMAGE_VERTEX v[4]; + HRESULT hr; + + float ZoomWidth, ZoomHeight; + float ScaleWidth, ScaleHeight; + + // Create a texture to hold image + hr = D3DXCreateTexture( + gld->pDev, + width, height, + 1, // miplevels + 0, // usage + D3DFMT_A8R8G8B8, // format + D3DPOOL_MANAGED, // pool + &pTexture); + if (FAILED(hr)) + return hr; + + hr = IDirect3DTexture9_GetSurfaceLevel(pTexture, 0, &pSurface); + if (FAILED(hr)) { + IDirect3DTexture9_Release(pTexture); + return hr; + } + + // Copy image into texture + hr = D3DXLoadSurfaceFromSurface( + pSurface, NULL, NULL, // Dest surface + pImage, NULL, NULL, // Src surface + D3DX_FILTER_NONE, + 0); + IDirect3DSurface9_Release(pSurface); + if (FAILED(hr)) { + IDirect3DTexture9_Release(pTexture); + return hr; + } + + // + // Set up the quad like this (ascii-art ahead!) + // + // 3--2 + // | | + // 0--1 + // + // + + // Set depth + v[0].z = v[1].z = v[2].z = v[3].z = ctx->Current.RasterPos[2]; + // Set Reciprocal Homogenous W + v[0].rhw = v[1].rhw = v[2].rhw = v[3].rhw = 1.0f; + + // Set texcoords + // Examine texture size - if different to input width and height + // then we'll need to munge the texcoords to fit. + IDirect3DTexture9_GetLevelDesc(pTexture, 0, &d3dsd); + ScaleWidth = (float)width / (float)d3dsd.Width; + ScaleHeight = (float)height / (float)d3dsd.Height; + v[0].tu = 0.0f; v[0].tv = 0.0f; + v[1].tu = ScaleWidth; v[1].tv = 0.0f; + v[2].tu = ScaleWidth; v[2].tv = ScaleHeight; + v[3].tu = 0.0f; v[3].tv = ScaleHeight; + + // Set raster positions + ZoomWidth = (float)width * ctx->Pixel.ZoomX; + ZoomHeight = (float)height * ctx->Pixel.ZoomY; + + v[0].x = x; v[0].y = GLD_FLIP_Y(y); + v[1].x = x+ZoomWidth; v[1].y = GLD_FLIP_Y(y); + v[2].x = x+ZoomWidth; v[2].y = GLD_FLIP_Y(y+ZoomHeight); + v[3].x = x; v[3].y = GLD_FLIP_Y(y+ZoomHeight); + + // Draw image with full HW acceleration + // NOTE: Be nice to use a State Block for all this state... + IDirect3DDevice9_SetTexture(gld->pDev, 0, pTexture); + IDirect3DDevice9_SetRenderState(gld->pDev, D3DRS_CULLMODE, D3DCULL_NONE); + IDirect3DDevice9_SetRenderState(gld->pDev, D3DRS_CLIPPING, TRUE); + +// IDirect3DDevice9_SetTextureStageState(gld->pDev, 0, D3DTSS_MINFILTER, D3DTEXF_POINT); +// IDirect3DDevice9_SetTextureStageState(gld->pDev, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT); +// IDirect3DDevice9_SetTextureStageState(gld->pDev, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT); +// IDirect3DDevice9_SetTextureStageState(gld->pDev, 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); +// IDirect3DDevice9_SetTextureStageState(gld->pDev, 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); + IDirect3DDevice9_SetSamplerState(gld->pDev, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT); + IDirect3DDevice9_SetSamplerState(gld->pDev, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT); + IDirect3DDevice9_SetSamplerState(gld->pDev, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); + IDirect3DDevice9_SetSamplerState(gld->pDev, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); + IDirect3DDevice9_SetSamplerState(gld->pDev, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); + + IDirect3DDevice9_SetTextureStageState(gld->pDev, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + IDirect3DDevice9_SetTextureStageState(gld->pDev, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + IDirect3DDevice9_SetTextureStageState(gld->pDev, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + IDirect3DDevice9_SetTextureStageState(gld->pDev, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + IDirect3DDevice9_SetTextureStageState(gld->pDev, 1, D3DTSS_COLOROP, D3DTOP_DISABLE); + IDirect3DDevice9_SetTextureStageState(gld->pDev, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + IDirect3DDevice9_SetVertexShader(gld->pDev, NULL); + IDirect3DDevice9_SetFVF(gld->pDev, _GLD_FVF_IMAGE); + + // + // Emulate Chromakey with an Alpha Test. + // [Alpha Test is more widely supported anyway] + // + if (bChromakey) { + // Switch on alpha testing + IDirect3DDevice9_SetRenderState(gld->pDev, D3DRS_ALPHATESTENABLE, TRUE); + // Fragment passes is alpha is greater than reference value + IDirect3DDevice9_SetRenderState(gld->pDev, D3DRS_ALPHAFUNC, D3DCMP_GREATER); + // Set alpha reference value between Bitmap alpha values of + // zero (transparent) and one (opaque). + IDirect3DDevice9_SetRenderState(gld->pDev, D3DRS_ALPHAREF, 0x7f); + } + + IDirect3DDevice9_DrawPrimitiveUP(gld->pDev, D3DPT_TRIANGLEFAN, 2, &v, sizeof(_GLD_IMAGE_VERTEX)); + + // Release texture + IDirect3DDevice9_SetTexture(gld->pDev, 0, NULL); + IDirect3DTexture9_Release(pTexture); + + // Reset state to before we messed it up + FLUSH_VERTICES(ctx, _NEW_ALL); + + return S_OK; +} + +//--------------------------------------------------------------------------- + +void gld_DrawPixels_DX9( + GLcontext *ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid *pixels ) +{ + GLD_context *gldCtx; + GLD_driver_dx9 *gld; + + IDirect3DSurface9 *pImage; + HRESULT hr; + D3DLOCKED_RECT d3dLockedRect; + + const struct gl_texture_format *MesaFormat; + + MesaFormat = _mesa_choose_tex_format(ctx, format, format, type); + + // Mesa does not currently handle this format. + if (format == GL_BGR) + return; + + gldCtx = GLD_GET_CONTEXT(ctx); + gld = GLD_GET_DX9_DRIVER(gldCtx); + + hr = IDirect3DDevice9_CreateOffscreenPlainSurface( + gld->pDev, + width, + height, + D3DFMT_A8R8G8B8, + D3DPOOL_SCRATCH, + &pImage, + NULL); + if (FAILED(hr)) { + return; + } + + // + // Use Mesa to fill in image + // + + // Lock all of surface + hr = IDirect3DSurface9_LockRect(pImage, &d3dLockedRect, NULL, 0); + if (FAILED(hr)) { + IDirect3DSurface9_Release(pImage); + return; + } + + // unpack image, apply transfer ops and store directly in texture + MesaFormat->StoreImage( + ctx, + 2, + GL_RGBA, + &_mesa_texformat_argb8888, + d3dLockedRect.pBits, + width, height, 1, 0, 0, 0, + d3dLockedRect.Pitch, + 0, /* dstImageStride */ + format, type, pixels, unpack); + + IDirect3DSurface9_UnlockRect(pImage); + + _gldDrawPixels(ctx, FALSE, x, y, width, height, pImage); + + IDirect3DSurface9_Release(pImage); +} + +//--------------------------------------------------------------------------- + +void gld_ReadPixels_DX9( + GLcontext *ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *pack, + GLvoid *dest) +{ + + GLD_context *gldCtx; + GLD_driver_dx9 *gld; + + IDirect3DSurface9 *pBackbuffer = NULL; + IDirect3DSurface9 *pNativeImage = NULL; + IDirect3DSurface9 *pCanonicalImage = NULL; + + D3DSURFACE_DESC d3dsd; + RECT rcSrc; // Source rect + POINT ptDst; // Dest point + HRESULT hr; + D3DLOCKED_RECT d3dLockedRect; + struct gl_pixelstore_attrib srcPacking; + int i; + GLint DstRowStride; + const struct gl_texture_format *MesaFormat; + + switch (format) { + case GL_STENCIL_INDEX: + case GL_DEPTH_COMPONENT: + return; + } + + MesaFormat = _mesa_choose_tex_format(ctx, format, format, type); + DstRowStride = _mesa_image_row_stride(pack, width, format, type); + + gldCtx = GLD_GET_CONTEXT(ctx); + gld = GLD_GET_DX9_DRIVER(gldCtx); + + // Get backbuffer + hr = IDirect3DDevice9_GetBackBuffer( + gld->pDev, + 0, // First swapchain + 0, // First backbuffer + D3DBACKBUFFER_TYPE_MONO, + &pBackbuffer); + if (FAILED(hr)) + return; + + // Get backbuffer description + hr = IDirect3DSurface9_GetDesc(pBackbuffer, &d3dsd); + if (FAILED(hr)) { + goto gld_ReadPixels_DX9_return; + } + + // Create a surface compatible with backbuffer + hr = IDirect3DDevice9_CreateOffscreenPlainSurface( + gld->pDev, + width, + height, + d3dsd.Format, + D3DPOOL_SCRATCH, + &pNativeImage, + NULL); + if (FAILED(hr)) { + goto gld_ReadPixels_DX9_return; + } + + // Compute source rect and dest point + SetRect(&rcSrc, 0, 0, width, height); + OffsetRect(&rcSrc, x, GLD_FLIP_HEIGHT(y, height)); + ptDst.x = ptDst.y = 0; + + // Get source pixels. + // + // This intermediate surface ensure that we can use CopyRects() + // instead of relying on D3DXLoadSurfaceFromSurface(), which may + // try and lock the backbuffer. This way seems safer. + // + // CopyRects has been removed for DX9. + // +/* hr = IDirect3DDevice9_CopyRects( + gld->pDev, + pBackbuffer, + &rcSrc, + 1, + pNativeImage, + &ptDst);*/ + hr = D3DXLoadSurfaceFromSurface( + pNativeImage, // Dest surface + NULL, // Dest palette + &rcSrc, // Dest rect + pBackbuffer, // Src surface + NULL, // Src palette + &rcSrc, // Src rect + D3DX_FILTER_NONE, // Filter + 0 // Colorkey (0=no colorkey) + ); + if (FAILED(hr)) { + goto gld_ReadPixels_DX9_return; + } + + // Create an RGBA8888 surface + hr = IDirect3DDevice9_CreateOffscreenPlainSurface( + gld->pDev, + width, + height, + D3DFMT_A8R8G8B8, + D3DPOOL_SCRATCH, + &pCanonicalImage, + NULL); + if (FAILED(hr)) { + goto gld_ReadPixels_DX9_return; + } + + // Convert to RGBA8888 + hr = D3DXLoadSurfaceFromSurface( + pCanonicalImage, // Dest surface + NULL, NULL, // Dest palette, RECT + pNativeImage, // Src surface + NULL, NULL, // Src palette, RECT + D3DX_FILTER_NONE, // Filter + 0); // Colourkey + if (FAILED(hr)) { + goto gld_ReadPixels_DX9_return; + } + + srcPacking.Alignment = 1; + srcPacking.ImageHeight = height; + srcPacking.LsbFirst = GL_FALSE; + srcPacking.RowLength = 0; + srcPacking.SkipImages = 0; + srcPacking.SkipPixels = 0; + srcPacking.SkipRows = 0; + srcPacking.SwapBytes = GL_FALSE; + + // Lock all of image + hr = IDirect3DSurface9_LockRect(pCanonicalImage, &d3dLockedRect, NULL, 0); + if (FAILED(hr)) { + goto gld_ReadPixels_DX9_return; + } + + // We need to flip the data. Yuck. + // Perhaps Mesa has a span packer we can use in future... + for (i=0; iStoreImage( + ctx, + 2, + GL_RGBA, // base format + MesaFormat, // dst format + pDestRow, // dest addr + width, 1, 1, 0, 0, 0, // src x,y,z & dst offsets x,y,z + DstRowStride, // dst row stride + 0, // dstImageStride + GL_BGRA, // src format + GL_UNSIGNED_BYTE, // src type + pSrcRow, // src addr + &srcPacking); // packing params of source image + } + + IDirect3DSurface9_UnlockRect(pCanonicalImage); + +gld_ReadPixels_DX9_return: + SAFE_RELEASE_SURFACE9(pCanonicalImage); + SAFE_RELEASE_SURFACE9(pNativeImage); + SAFE_RELEASE_SURFACE9(pBackbuffer); +} + +//--------------------------------------------------------------------------- + +void gld_CopyPixels_DX9( + GLcontext *ctx, + GLint srcx, + GLint srcy, + GLsizei width, + GLsizei height, + GLint dstx, + GLint dsty, + GLenum type) +{ + // + // NOTE: Not allowed to copy vidmem to vidmem! + // Therefore we use an intermediate image surface. + // + + GLD_context *gldCtx; + GLD_driver_dx9 *gld; + + IDirect3DSurface9 *pBackbuffer; + D3DSURFACE_DESC d3dsd; + IDirect3DSurface9 *pImage; + RECT rcSrc; // Source rect + POINT ptDst; // Dest point + HRESULT hr; + + // Only backbuffer + if (type != GL_COLOR) + return; + + gldCtx = GLD_GET_CONTEXT(ctx); + gld = GLD_GET_DX9_DRIVER(gldCtx); + + // Get backbuffer + hr = IDirect3DDevice9_GetBackBuffer( + gld->pDev, + 0, // First swapchain + 0, // First backbuffer + D3DBACKBUFFER_TYPE_MONO, + &pBackbuffer); + if (FAILED(hr)) + return; + + // Get backbuffer description + hr = IDirect3DSurface9_GetDesc(pBackbuffer, &d3dsd); + if (FAILED(hr)) { + IDirect3DSurface9_Release(pBackbuffer); + return; + } + + // Create a surface compatible with backbuffer + hr = IDirect3DDevice9_CreateOffscreenPlainSurface( + gld->pDev, + width, + height, + d3dsd.Format, + D3DPOOL_SCRATCH, + &pImage, + NULL); + if (FAILED(hr)) { + IDirect3DSurface9_Release(pBackbuffer); + return; + } + + // Compute source rect and dest point + SetRect(&rcSrc, 0, 0, width, height); + OffsetRect(&rcSrc, srcx, GLD_FLIP_HEIGHT(srcy, height)); + ptDst.x = ptDst.y = 0; + + // Get source pixels +/* hr = IDirect3DDevice8_CopyRects( + gld->pDev, + pBackbuffer, + &rcSrc, + 1, + pImage, + &ptDst);*/ + hr = D3DXLoadSurfaceFromSurface( + pImage, // Dest surface + NULL, // Dest palette + &rcSrc, // Dest rect + pBackbuffer, // Src surface + NULL, // Src palette + &rcSrc, // Src rect + D3DX_FILTER_NONE, // Filter + 0 // Colorkey (0=no colorkey) + ); + IDirect3DSurface9_Release(pBackbuffer); + if (FAILED(hr)) { + IDirect3DSurface9_Release(pImage); + return; + } + + _gldDrawPixels(ctx, FALSE, dstx, dsty, width, height, pImage); + + IDirect3DSurface9_Release(pImage); +} + +//--------------------------------------------------------------------------- + +void gld_Bitmap_DX9( + GLcontext *ctx, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + const struct gl_pixelstore_attrib *unpack, + const GLubyte *bitmap) +{ + GLD_context *gldCtx; + GLD_driver_dx9 *gld; + + IDirect3DSurface9 *pImage; + HRESULT hr; + D3DLOCKED_RECT d3dLockedRect; + BYTE *pTempBitmap; + D3DCOLOR clBitmapOne, clBitmapZero; + D3DCOLOR *pBits; + const GLubyte *src; + int i, j, k; + + gldCtx = GLD_GET_CONTEXT(ctx); + gld = GLD_GET_DX9_DRIVER(gldCtx); + + // A NULL bitmap is valid, but merely advances the raster position + if ((bitmap == NULL) || (width == 0) || (height == 0)) + return; + + clBitmapZero = D3DCOLOR_RGBA(0,0,0,0); // NOTE: Alpha is Zero + clBitmapOne = D3DCOLOR_COLORVALUE( + ctx->Current.RasterColor[0], + ctx->Current.RasterColor[1], + ctx->Current.RasterColor[2], + 1.0f); // NOTE: Alpha is One + + hr = IDirect3DDevice9_CreateOffscreenPlainSurface( + gld->pDev, + width, + height, + D3DFMT_A8R8G8B8, + D3DPOOL_SCRATCH, + &pImage, + NULL); + if (FAILED(hr)) { + return; + } + + // Lock all of surface + hr = IDirect3DSurface9_LockRect(pImage, &d3dLockedRect, NULL, 0); + if (FAILED(hr)) { + IDirect3DSurface9_Release(pImage); + return; + } + + pTempBitmap = _mesa_unpack_bitmap(width, height, bitmap, unpack); + if (pTempBitmap == NULL) { + IDirect3DSurface9_Release(pImage); + return; + } + + pBits = (D3DCOLOR*)d3dLockedRect.pBits; + + for (i=0; iDefaultPacking, pTempBitmap, width, height, GL_COLOR_INDEX, GL_BITMAP, + 0, i, 0); + for (j=0; j<(width>>3); j++) { + byte = *src++; + for (k=0; k<8; k++) { + *pBits++ = (byte & 128) ? clBitmapOne : clBitmapZero; + byte <<= 1; + } + } + // Fill remaining bits from bitmap + if (width & 7) { + byte = *src; + for (k=0; k<(width & 7); k++) { + *pBits++ = (byte & 128) ? clBitmapOne : clBitmapZero; + byte <<= 1; + } + } + } + + FREE(pTempBitmap); + +/* + // unpack image, apply transfer ops and store directly in texture + texImage->TexFormat->StoreImage( + ctx, + 2, + GL_BITMAP, + &_mesa_texformat_argb8888, + d3dLockedRect.pBits, + width, height, 1, 0, 0, 0, + d3dLockedRect.Pitch, + 0, // dstImageStride + GL_BITMAP, GL_COLOR_INDEX, bitmap, unpack); +*/ + IDirect3DSurface9_UnlockRect(pImage); + + _gldDrawPixels(ctx, TRUE, x, y, width, height, pImage); + + IDirect3DSurface9_Release(pImage); +} + +//--------------------------------------------------------------------------- +// Texture functions +//--------------------------------------------------------------------------- + +void _gldAllocateTexture( + GLcontext *ctx, + struct gl_texture_object *tObj, + struct gl_texture_image *texImage) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); + + IDirect3DTexture9 *pTex; + D3DFORMAT d3dFormat; + + if (!tObj || !texImage) + return; + + pTex = (IDirect3DTexture9*)tObj->DriverData; + if (pTex) { + // Decide whether we can keep existing D3D texture + // by examining top-level surface. + D3DSURFACE_DESC d3dsd; + _GLD_DX9_TEX(GetLevelDesc(pTex, 0, &d3dsd)); + // Release existing texture if not compatible + if ((d3dsd.Width == texImage->Width) || + (d3dsd.Height == texImage->Height)) + { + return; // Keep the existing texture + } + tObj->DriverData = NULL; + _GLD_DX9_TEX(Release(pTex)); + } + + d3dFormat = _gldGLFormatToD3DFormat(texImage->IntFormat); + D3DXCreateTexture( + gld->pDev, + texImage->Width, + texImage->Height, + // TODO: Re-evaluate mipmapping + (glb.bUseMipmaps) ? D3DX_DEFAULT : 1, + 0, // Usage + d3dFormat, + D3DPOOL_MANAGED, + &pTex); + tObj->DriverData = pTex; +} + +//--------------------------------------------------------------------------- + +const struct gl_texture_format* gld_ChooseTextureFormat_DX9( + GLcontext *ctx, + GLint internalFormat, + GLenum srcFormat, + GLenum srcType) +{ + // [Based on mesa_choose_tex_format()] + // + // We will choose only texture formats that are supported + // by Direct3D. If the hardware doesn't support a particular + // texture format, then the D3DX texture calls that we use + // will automatically use a HW supported format. + // + // The most critical aim is to reduce copying; if we can use + // texture-image data directly then it will be a big performance assist. + // + + switch (internalFormat) { + case GL_INTENSITY: + case GL_INTENSITY4: + case GL_INTENSITY8: + case GL_INTENSITY12: + case GL_INTENSITY16: + return &_mesa_texformat_l8; // D3DFMT_L8 + case 1: + case GL_LUMINANCE: + case GL_LUMINANCE4: + case GL_LUMINANCE8: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + return &_mesa_texformat_l8; // D3DFMT_L8 + case GL_ALPHA: + case GL_ALPHA4: + case GL_ALPHA8: + case GL_ALPHA12: + case GL_ALPHA16: + return &_mesa_texformat_a8; // D3DFMT_A8 + case GL_COLOR_INDEX: + case GL_COLOR_INDEX1_EXT: + case GL_COLOR_INDEX2_EXT: + case GL_COLOR_INDEX4_EXT: + case GL_COLOR_INDEX8_EXT: + case GL_COLOR_INDEX12_EXT: + case GL_COLOR_INDEX16_EXT: + return &_mesa_texformat_rgb565; // D3DFMT_R5G6B5 + // Mesa will convert this for us later... + // return &_mesa_texformat_ci8; // D3DFMT_R5G6B5 + case 2: + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE4_ALPHA4: + case GL_LUMINANCE6_ALPHA2: + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE12_ALPHA4: + case GL_LUMINANCE12_ALPHA12: + case GL_LUMINANCE16_ALPHA16: + return &_mesa_texformat_al88; // D3DFMT_A8L8 + case GL_R3_G3_B2: + return &_mesa_texformat_rgb332; // D3DFMT_R3G3B2 + case GL_RGB4: + case GL_RGBA4: + case GL_RGBA2: + return &_mesa_texformat_argb4444; // D3DFMT_A4R4G4B4 + case 3: + case GL_RGB: + case GL_RGB5: + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + return &_mesa_texformat_rgb565; + case 4: + case GL_RGBA: + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + return &_mesa_texformat_argb8888; + case GL_RGB5_A1: + return &_mesa_texformat_argb1555; + default: + _mesa_problem(NULL, "unexpected format in fxDDChooseTextureFormat"); + return NULL; + } +} + +//--------------------------------------------------------------------------- + +/* +// Safer(?), slower version. +void gld_TexImage2D_DX9( + GLcontext *ctx, + GLenum target, + GLint level, + GLint internalFormat, + GLint width, + GLint height, + GLint border, + GLenum format, + GLenum type, + const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *tObj, + struct gl_texture_image *texImage) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); + + IDirect3DTexture9 *pTex; + IDirect3DSurface9 *pSurface; + RECT rcSrcRect; + HRESULT hr; + GLint texelBytes = 4; + GLvoid *tempImage; + + if (!tObj || !texImage) + return; + + if (level == 0) { + _gldAllocateTexture(ctx, tObj, texImage); + } + + pTex = (IDirect3DTexture9*)tObj->DriverData; + if (!pTex) + return; // Texture has not been created + if (level >= IDirect3DTexture9_GetLevelCount(pTex)) + return; // Level does not exist + hr = IDirect3DTexture9_GetSurfaceLevel(pTex, level, &pSurface); + if (FAILED(hr)) + return; // Surface level doesn't exist (or just a plain error) + + tempImage = MALLOC(width * height * texelBytes); + if (!tempImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + IDirect3DSurface9_Release(pSurface); + return; + } + // unpack image, apply transfer ops and store in tempImage + texImage->TexFormat->StoreImage(ctx, 2, texImage->Format, + &_mesa_texformat_argb8888, // dest format + tempImage, + width, height, 1, 0, 0, 0, + width * texelBytes, + 0, // dstImageStride + format, type, pixels, packing); + + SetRect(&rcSrcRect, 0, 0, width, height); + D3DXLoadSurfaceFromMemory( + pSurface, + NULL, + NULL, + tempImage, + D3DFMT_A8R8G8B8, + width * texelBytes, + NULL, + &rcSrcRect, + D3DX_FILTER_NONE, + 0); + + FREE(tempImage); + IDirect3DSurface9_Release(pSurface); +} +*/ + +//--------------------------------------------------------------------------- + +// Faster, more efficient version. +// Copies subimage straight to dest texture +void gld_TexImage2D_DX9( + GLcontext *ctx, + GLenum target, + GLint level, + GLint internalFormat, + GLint width, + GLint height, + GLint border, + GLenum format, + GLenum type, + const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *tObj, + struct gl_texture_image *texImage) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); + + IDirect3DTexture9 *pTex; + IDirect3DSurface9 *pSurface; + HRESULT hr; + D3DLOCKED_RECT d3dLockedRect; + D3DSURFACE_DESC d3dsd; + + if (!tObj || !texImage) + return; + + // GLQUAKE FIX + // Test for input alpha data with non-alpha internalformat + if (((internalFormat==3) || (internalFormat==GL_RGB)) && (format==GL_RGBA)) { + // Input format has alpha, but a non-alpha format has been requested. + texImage->IntFormat = GL_RGBA; + internalFormat = GL_RGBA; + } + + if (level == 0) { + _gldAllocateTexture(ctx, tObj, texImage); + } + + pTex = (IDirect3DTexture9*)tObj->DriverData; + if (!pTex) + return; // Texture has not been created + if (level >= IDirect3DTexture9_GetLevelCount(pTex)) + return; // Level does not exist + hr = IDirect3DTexture9_GetSurfaceLevel(pTex, level, &pSurface); + if (FAILED(hr)) + return; // Surface level doesn't exist (or just a plain error) + + IDirect3DSurface9_GetDesc(pSurface, &d3dsd); + + // Lock all of surface + hr = IDirect3DSurface9_LockRect(pSurface, &d3dLockedRect, NULL, 0); + if (FAILED(hr)) { + IDirect3DSurface9_Release(pSurface); + return; + } + + // unpack image, apply transfer ops and store directly in texture + texImage->TexFormat->StoreImage( + ctx, + 2, + texImage->Format, + _gldMesaFormatForD3DFormat(d3dsd.Format), + d3dLockedRect.pBits, + width, height, 1, 0, 0, 0, + d3dLockedRect.Pitch, + 0, // dstImageStride + format, type, pixels, packing); + + IDirect3DSurface9_UnlockRect(pSurface); + IDirect3DSurface9_Release(pSurface); +} + +//--------------------------------------------------------------------------- + +void gld_TexImage1D_DX9(GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint border, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) +{ + // A 1D texture is a 2D texture with a height of zero + gld_TexImage2D_DX9(ctx, target, level, internalFormat, width, 1, border, format, type, pixels, packing, texObj, texImage); +} + +//--------------------------------------------------------------------------- + +/* +void gld_TexSubImage2D( GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *tObj, + struct gl_texture_image *texImage ) +{ + GLD_GET_CONTEXT + IDirect3DTexture9 *pTex; + IDirect3DSurface9 *pSurface; + D3DFORMAT d3dFormat; + HRESULT hr; + GLint texelBytes = 4; + GLvoid *tempImage; + RECT rcSrcRect; + RECT rcDstRect; + + if (!tObj || !texImage) + return; + + pTex = (IDirect3DTexture9*)tObj->DriverData; + if (!pTex) + return; // Texture has not been created + if (level >= _GLD_DX9_TEX(GetLevelCount(pTex)) + return; // Level does not exist + hr = _GLD_DX9_TEX(GetSurfaceLevel(pTex, level, &pSurface); + if (FAILED(hr)) + return; // Surface level doesn't exist (or just a plain error) + + d3dFormat = _gldGLFormatToD3DFormat(texImage->Format); + tempImage = MALLOC(width * height * texelBytes); + if (!tempImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + IDirect3DSurface9_Release(pSurface); + return; + } + + // unpack image, apply transfer ops and store in tempImage + texImage->TexFormat->StoreImage(ctx, 2, texImage->Format, + &_mesa_texformat_argb8888, // dest format + tempImage, + width, height, 1, 0, 0, 0, + width * texelBytes, + 0, // dstImageStride + format, type, pixels, packing); + + // Source rectangle is whole of input image + SetRect(&rcSrcRect, 0, 0, width, height); + + // Dest rectangle must be offset to dest image + SetRect(&rcDstRect, 0, 0, width, height); + OffsetRect(&rcDstRect, xoffset, yoffset); + + D3DXLoadSurfaceFromMemory( + pSurface, + NULL, + &rcDstRect, + tempImage, + D3DFMT_A8R8G8B8, + width * texelBytes, + NULL, + &rcSrcRect, + D3DX_FILTER_NONE, + 0); + + FREE(tempImage); + IDirect3DSurface9_Release(pSurface); +} +*/ + +//--------------------------------------------------------------------------- + +// Faster, more efficient version. +// Copies subimage straight to dest texture +void gld_TexSubImage2D_DX9( GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *tObj, + struct gl_texture_image *texImage ) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); + + IDirect3DTexture9 *pTex; + IDirect3DSurface9 *pSurface; + HRESULT hr; + RECT rcDstRect; + D3DLOCKED_RECT d3dLockedRect; + D3DSURFACE_DESC d3dsd; + + if (!tObj || !texImage) + return; + + pTex = (IDirect3DTexture9*)tObj->DriverData; + if (!pTex) + return; // Texture has not been created + if (level >= IDirect3DTexture9_GetLevelCount(pTex)) + return; // Level does not exist + hr = IDirect3DTexture9_GetSurfaceLevel(pTex, level, &pSurface); + if (FAILED(hr)) + return; // Surface level doesn't exist (or just a plain error) + + IDirect3DSurface9_GetDesc(pSurface, &d3dsd); + + // Dest rectangle must be offset to dest image + SetRect(&rcDstRect, 0, 0, width, height); + OffsetRect(&rcDstRect, xoffset, yoffset); + + // Lock sub-rect of surface + hr = IDirect3DSurface9_LockRect(pSurface, &d3dLockedRect, &rcDstRect, 0); + if (FAILED(hr)) { + IDirect3DSurface9_Release(pSurface); + return; + } + + // unpack image, apply transfer ops and store directly in texture + texImage->TexFormat->StoreImage(ctx, 2, texImage->Format, + _gldMesaFormatForD3DFormat(d3dsd.Format), + d3dLockedRect.pBits, + width, height, 1, + 0, 0, 0, // NOTE: d3dLockedRect.pBits is already offset!!! + d3dLockedRect.Pitch, + 0, // dstImageStride + format, type, pixels, packing); + + + IDirect3DSurface9_UnlockRect(pSurface); + IDirect3DSurface9_Release(pSurface); +} + +//--------------------------------------------------------------------------- + +void gld_TexSubImage1D_DX9( GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLsizei width, + GLenum format, GLenum type, + const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) +{ + gld_TexSubImage2D_DX9(ctx, target, level, xoffset, 0, width, 1, format, type, pixels, packing, texObj, texImage); +} + +//--------------------------------------------------------------------------- + +void gld_DeleteTexture_DX9( + GLcontext *ctx, + struct gl_texture_object *tObj) +{ + GLD_context *gld = (GLD_context*)(ctx->DriverCtx); + + if (tObj) { + IDirect3DTexture9 *pTex = (IDirect3DTexture9*)tObj->DriverData; + if (pTex) { +/* // Make sure texture is not bound to a stage before releasing it + for (int i=0; iCurrentTexture[i] == pTex) { + gld->pDev->SetTexture(i, NULL); + gld->CurrentTexture[i] = NULL; + } + }*/ + _GLD_DX9_TEX(Release(pTex)); + tObj->DriverData = NULL; + } + } +} + +//--------------------------------------------------------------------------- + +__inline void _gldSetColorOps( + const GLD_driver_dx9 *gld, + GLuint unit, + DWORD ColorArg1, + D3DTEXTUREOP ColorOp, + DWORD ColorArg2) +{ + _GLD_DX9_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_COLORARG1, ColorArg1)); + _GLD_DX9_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_COLOROP, ColorOp)); + _GLD_DX9_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_COLORARG2, ColorArg2)); +} + +//--------------------------------------------------------------------------- + +__inline void _gldSetAlphaOps( + const GLD_driver_dx9 *gld, + GLuint unit, + DWORD AlphaArg1, + D3DTEXTUREOP AlphaOp, + DWORD AlphaArg2) +{ + _GLD_DX9_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_ALPHAARG1, AlphaArg1)); + _GLD_DX9_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_ALPHAOP, AlphaOp)); + _GLD_DX9_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_ALPHAARG2, AlphaArg2)); +} + +//--------------------------------------------------------------------------- + +void gldUpdateTextureUnit( + GLcontext *ctx, + GLuint unit, + BOOL bPassThrough) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); + + D3DTEXTUREFILTERTYPE minfilter; + D3DTEXTUREFILTERTYPE mipfilter; + GLenum BaseFormat; + DWORD dwColorArg0; + int iTexEnv = 0; + GLD_texenv *pTexenv; + + // NOTE: If bPassThrough is FALSE then texture stage can be + // disabled otherwise it must pass-through it's current fragment. + + const struct gl_texture_unit *pUnit = &ctx->Texture.Unit[unit]; + const struct gl_texture_object *tObj = pUnit->_Current; + + IDirect3DTexture9 *pTex = NULL; + if (tObj) { + pTex = (IDirect3DTexture9*)tObj->DriverData; + } + + // Enable texturing if unit is enabled and a valid D3D texture exists + // Mesa 5: TEXTUREn_x altered to TEXTURE_nD_BIT + //if (pTex && (pUnit->Enabled & (TEXTURE0_1D | TEXTURE0_2D))) { + if (pTex && (pUnit->_ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT))) { + // Enable texturing + _GLD_DX9_DEV(SetTexture(gld->pDev, unit, pTex)); + } else { + // Disable texturing, then return + _GLD_DX9_DEV(SetTexture(gld->pDev, unit, NULL)); + if (bPassThrough) { + _gldSetColorOps(gld, unit, D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_DIFFUSE); + _gldSetAlphaOps(gld, unit, D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_DIFFUSE); + } else { + _gldSetColorOps(gld, unit, D3DTA_TEXTURE, D3DTOP_DISABLE, D3DTA_DIFFUSE); + _gldSetAlphaOps(gld, unit, D3DTA_TEXTURE, D3DTOP_DISABLE, D3DTA_DIFFUSE); + } + return; + } + + // Texture parameters + _gldConvertMinFilter(tObj->MinFilter, &minfilter, &mipfilter); +// _GLD_DX9_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_MINFILTER, minfilter)); +// _GLD_DX9_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_MIPFILTER, mipfilter)); +// _GLD_DX9_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_MAGFILTER, _gldConvertMagFilter(tObj->MagFilter))); +// _GLD_DX9_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_ADDRESSU, _gldConvertWrap(tObj->WrapS))); +// _GLD_DX9_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_ADDRESSV, _gldConvertWrap(tObj->WrapT))); + _GLD_DX9_DEV(SetSamplerState(gld->pDev, unit, D3DSAMP_MINFILTER, minfilter)); + _GLD_DX9_DEV(SetSamplerState(gld->pDev, unit, D3DSAMP_MIPFILTER, mipfilter)); + _GLD_DX9_DEV(SetSamplerState(gld->pDev, unit, D3DSAMP_MAGFILTER, _gldConvertMagFilter(tObj->MagFilter))); + _GLD_DX9_DEV(SetSamplerState(gld->pDev, unit, D3DSAMP_ADDRESSU, _gldConvertWrap(tObj->WrapS))); + _GLD_DX9_DEV(SetSamplerState(gld->pDev, unit, D3DSAMP_ADDRESSV, _gldConvertWrap(tObj->WrapT))); + + // Texture priority + _GLD_DX9_TEX(SetPriority(pTex, (DWORD)(tObj->Priority*65535.0f))); + + // Texture environment + // TODO: Examine input texture for alpha and use specific alpha/non-alpha ops. + // See Page 355 of the Red Book. + BaseFormat = _gldDecodeBaseFormat(pTex); + + switch (BaseFormat) { + case GL_RGB: + iTexEnv = 0; + break; + case GL_RGBA: + iTexEnv = 1; + break; + case GL_ALPHA: + iTexEnv = 2; + break; + } + + switch (pUnit->EnvMode) { + case GL_DECAL: + iTexEnv += 0; + break; + case GL_REPLACE: + iTexEnv += 3; + break; + case GL_MODULATE: + iTexEnv += 6; + break; + case GL_BLEND: + // Set blend colour + dwColorArg0 = D3DCOLOR_COLORVALUE(pUnit->EnvColor[0], pUnit->EnvColor[1], pUnit->EnvColor[2], pUnit->EnvColor[3]); + _GLD_DX9_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_COLORARG0, dwColorArg0)); + iTexEnv += 9; + break; + case GL_ADD: + iTexEnv += 12; + break; + } + pTexenv = (GLD_texenv*)&gldTexEnv[iTexEnv]; + _gldSetColorOps(gld, unit, pTexenv->ColorArg1, pTexenv->ColorOp, pTexenv->ColorArg2); + _gldSetAlphaOps(gld, unit, pTexenv->AlphaArg1, pTexenv->AlphaOp, pTexenv->AlphaArg2); +} + +//--------------------------------------------------------------------------- + +void gld_NEW_TEXTURE_DX9( + GLcontext *ctx) +{ + // TODO: Support for three (ATI Radeon) or more (nVidia GeForce3) texture units + + BOOL bUnit0Enabled; + BOOL bUnit1Enabled; + + if (!ctx) + return; // Sanity check + + if (ctx->Const.MaxTextureUnits == 1) { + gldUpdateTextureUnit(ctx, 0, TRUE); + return; + } + + // + // NOTE: THE FOLLOWING RELATES TO TWO TEXTURE UNITS, AND TWO ONLY!! + // + + // Mesa 5: Texture Units altered + //bUnit0Enabled = (ctx->Texture._ReallyEnabled & (TEXTURE0_1D | TEXTURE0_2D)) ? TRUE : FALSE; + //bUnit1Enabled = (ctx->Texture._ReallyEnabled & (TEXTURE1_1D | TEXTURE1_2D)) ? TRUE : FALSE; + bUnit0Enabled = (ctx->Texture.Unit[0]._ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT)) ? TRUE : FALSE; + bUnit1Enabled = (ctx->Texture.Unit[1]._ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT)) ? TRUE : FALSE; + + // If Unit0 is disabled and Unit1 is enabled then we must pass-though + gldUpdateTextureUnit(ctx, 0, (!bUnit0Enabled && bUnit1Enabled) ? TRUE : FALSE); + // We can always disable the last texture unit + gldUpdateTextureUnit(ctx, 1, FALSE); + +#ifdef _DEBUG +#if 0 + { + // Find out whether device supports current renderstates + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); +// GLD_context *gld = GLD_GET_CONTEXT(ctx); + + DWORD dwPasses; + _GLD_DX9_DEV(ValidateDevice(gld->pDev, &dwPasses)); +// if (FAILED(hr)) { +// gldLogError(GLDLOG_ERROR, "ValidateDevice failed", hr); +// } + if (dwPasses != 1) { + gldLogMessage(GLDLOG_ERROR, "ValidateDevice: Can't do in one pass\n"); + } + } +#endif +#endif +}; + +//--------------------------------------------------------------------------- diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_vb_d3d_render_dx9.c b/mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_vb_d3d_render_dx9.c new file mode 100644 index 000000000..4fa6bcaf1 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_vb_d3d_render_dx9.c @@ -0,0 +1,263 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x/2000/XP/XBox (Win32) +* +* Description: GLDirect fastpath pipeline stage +* +****************************************************************************/ + +//--------------------------------------------------------------------------- + +//#include "../GLDirect.h" +//#include "../gld_log.h" +//#include "gld_dx8.h" + +#include "dglcontext.h" +#include "ddlog.h" +#include "gld_dx9.h" + +//--------------------------------------------------------------------------- + +#include "glheader.h" +#include "context.h" +#include "macros.h" +// #include "mem.h" +#include "mtypes.h" +//#include "mmath.h" + +#include "math/m_matrix.h" +#include "math/m_xform.h" + +#include "tnl/t_pipeline.h" + +//--------------------------------------------------------------------------- + +__inline void _gldSetVertexShaderConstants( + GLcontext *ctx, + GLD_driver_dx9 *gld) +{ + D3DXMATRIX mat, matView, matProj; + GLfloat *pM; + + // Mesa 5: Altered to a Stack + //pM = ctx->ModelView.m; + pM = ctx->ModelviewMatrixStack.Top->m; + matView._11 = pM[0]; + matView._12 = pM[1]; + matView._13 = pM[2]; + matView._14 = pM[3]; + matView._21 = pM[4]; + matView._22 = pM[5]; + matView._23 = pM[6]; + matView._24 = pM[7]; + matView._31 = pM[8]; + matView._32 = pM[9]; + matView._33 = pM[10]; + matView._34 = pM[11]; + matView._41 = pM[12]; + matView._42 = pM[13]; + matView._43 = pM[14]; + matView._44 = pM[15]; + + // Mesa 5: Altered to a Stack + //pM = ctx->ProjectionMatrix.m; + pM = ctx->ProjectionMatrixStack.Top->m; + matProj._11 = pM[0]; + matProj._12 = pM[1]; + matProj._13 = pM[2]; + matProj._14 = pM[3]; + matProj._21 = pM[4]; + matProj._22 = pM[5]; + matProj._23 = pM[6]; + matProj._24 = pM[7]; + matProj._31 = pM[8]; + matProj._32 = pM[9]; + matProj._33 = pM[10]; + matProj._34 = pM[11]; + matProj._41 = pM[12]; + matProj._42 = pM[13]; + matProj._43 = pM[14]; + matProj._44 = pM[15]; + + D3DXMatrixMultiply( &mat, &matView, &matProj ); + D3DXMatrixTranspose( &mat, &mat ); + + _GLD_DX9_DEV(SetVertexShaderConstantF(gld->pDev, 0, (float*)&mat, 4)); +} + +//--------------------------------------------------------------------------- + +static GLboolean gld_d3d_render_stage_run( + GLcontext *ctx, + struct tnl_pipeline_stage *stage) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); + + TNLcontext *tnl; + struct vertex_buffer *VB; + tnl_render_func *tab; + GLint pass; + GLD_pb_dx9 *gldPB = &gld->PB3d; +/* + static int count = 0; + count++; + if (count != 2) + return GL_FALSE; +*/ + // The "check" function should disable this stage, + // but we'll test gld->bUseMesaTnL anyway. + if (gld->bUseMesaTnL) { + // Do nothing in this stage, but continue pipeline + return GL_TRUE; + } + + tnl = TNL_CONTEXT(ctx); + VB = &tnl->vb; + pass = 0; + + tnl->Driver.Render.Start( ctx ); + +#if 0 + // For debugging: Useful to see if an app passes colour data in + // an unusual format. + switch (VB->ColorPtr[0]->Type) { + case GL_FLOAT: + ddlogMessage(GLDLOG_SYSTEM, "ColorPtr: GL_FLOAT\n"); + break; + case GL_UNSIGNED_BYTE: + ddlogMessage(GLDLOG_SYSTEM, "ColorPtr: GL_UNSIGNED_BYTE\n"); + break; + default: + ddlogMessage(GLDLOG_SYSTEM, "ColorPtr: *?*\n"); + break; + } +#endif + + tnl->Driver.Render.Points = gld_Points3D_DX9; + if (ctx->_TriangleCaps & DD_FLATSHADE) { + tnl->Driver.Render.Line = gld_Line3DFlat_DX9; + tnl->Driver.Render.Triangle = gld_Triangle3DFlat_DX9; + tnl->Driver.Render.Quad = gld_Quad3DFlat_DX9; + } else { + tnl->Driver.Render.Line = gld_Line3DSmooth_DX9; + tnl->Driver.Render.Triangle = gld_Triangle3DSmooth_DX9; + tnl->Driver.Render.Quad = gld_Quad3DSmooth_DX9; + } + + _GLD_DX9_VB(Lock(gldPB->pVB, 0, 0, &gldPB->pPoints, D3DLOCK_DISCARD)); + gldPB->nPoints = gldPB->nLines = gldPB->nTriangles = 0; + // Allocate primitive pointers + // gldPB->pPoints is always first + gldPB->pLines = gldPB->pPoints + (gldPB->dwStride * gldPB->iFirstLine); + gldPB->pTriangles = gldPB->pPoints + (gldPB->dwStride * gldPB->iFirstTriangle); + + ASSERT(tnl->Driver.Render.BuildVertices); + ASSERT(tnl->Driver.Render.PrimitiveNotify); + ASSERT(tnl->Driver.Render.Points); + ASSERT(tnl->Driver.Render.Line); + ASSERT(tnl->Driver.Render.Triangle); + ASSERT(tnl->Driver.Render.Quad); + ASSERT(tnl->Driver.Render.ResetLineStipple); + ASSERT(tnl->Driver.Render.Interp); + ASSERT(tnl->Driver.Render.CopyPV); + ASSERT(tnl->Driver.Render.ClippedLine); + ASSERT(tnl->Driver.Render.ClippedPolygon); + ASSERT(tnl->Driver.Render.Finish); + + tab = (VB->Elts ? tnl->Driver.Render.PrimTabElts : tnl->Driver.Render.PrimTabVerts); + + do { + GLuint i, length, flags = 0; + for (i = 0 ; !(flags & PRIM_END) ; i += length) + { + flags = VB->Primitive[i].mode; + length= VB->Primitive[i].count; + ASSERT(length || (flags & PRIM_END)); + ASSERT((flags & PRIM_MODE_MASK) <= GL_POLYGON+1); + if (length) + tab[flags & PRIM_MODE_MASK]( ctx, i, i + length, flags ); + } + } while (tnl->Driver.Render.Multipass && + tnl->Driver.Render.Multipass( ctx, ++pass )); + + _GLD_DX9_VB(Unlock(gldPB->pVB)); + + _GLD_DX9_DEV(SetStreamSource(gld->pDev, 0, gldPB->pVB, 0, gldPB->dwStride)); + + _GLD_DX9_DEV(SetTransform(gld->pDev, D3DTS_PROJECTION, &gld->matProjection)); + _GLD_DX9_DEV(SetTransform(gld->pDev, D3DTS_WORLD, &gld->matModelView)); + + if (gldPB->nPoints) { + _GLD_DX9_DEV(DrawPrimitive(gld->pDev, D3DPT_POINTLIST, 0, gldPB->nPoints)); + gldPB->nPoints = 0; + } + + if (gldPB->nLines) { + _GLD_DX9_DEV(DrawPrimitive(gld->pDev, D3DPT_LINELIST, gldPB->iFirstLine, gldPB->nLines)); + gldPB->nLines = 0; + } + + if (gldPB->nTriangles) { + _GLD_DX9_DEV(DrawPrimitive(gld->pDev, D3DPT_TRIANGLELIST, gldPB->iFirstTriangle, gldPB->nTriangles)); + gldPB->nTriangles = 0; + } + + return GL_FALSE; /* finished the pipe */ +} + +//--------------------------------------------------------------------------- + +static void gld_d3d_render_stage_check( + GLcontext *ctx, + struct tnl_pipeline_stage *stage) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); + // Is this thread safe? + stage->active = (gld->bUseMesaTnL) ? GL_FALSE : GL_TRUE; + return; +} + + +//--------------------------------------------------------------------------- + +const struct tnl_pipeline_stage _gld_d3d_render_stage = +{ + "gld_d3d_render_stage", + NULL, + NULL, + NULL, + NULL, + gld_d3d_render_stage_run /* run */ +}; + +//--------------------------------------------------------------------------- diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_vb_mesa_render_dx9.c b/mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_vb_mesa_render_dx9.c new file mode 100644 index 000000000..64acab2d2 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_vb_mesa_render_dx9.c @@ -0,0 +1,443 @@ + +/* + * 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 + */ + + +/* + * Render whole vertex buffers, including projection of vertices from + * clip space and clipping of primitives. + * + * This file makes calls to project vertices and to the point, line + * and triangle rasterizers via the function pointers: + * + * context->Driver.Render.* + * + */ + + +//--------------------------------------------------------------------------- + +#include "dglcontext.h" +#include "ddlog.h" +#include "gld_dx9.h" + +//--------------------------------------------------------------------------- + +#include "glheader.h" +#include "context.h" +#include "macros.h" +#include "mtypes.h" +//#include "mmath.h" + +#include "math/m_matrix.h" +#include "math/m_xform.h" + +#include "tnl/t_pipeline.h" + +/**********************************************************************/ +/* Clip single primitives */ +/**********************************************************************/ + + +#if defined(USE_IEEE) +#define NEGATIVE(x) (GET_FLOAT_BITS(x) & (1<<31)) +//#define DIFFERENT_SIGNS(x,y) ((GET_FLOAT_BITS(x) ^ GET_FLOAT_BITS(y)) & (1<<31)) +#else +#define NEGATIVE(x) (x < 0) +//#define DIFFERENT_SIGNS(x,y) (x * y <= 0 && x - y != 0) +/* Could just use (x*y<0) except for the flatshading requirements. + * Maybe there's a better way? + */ +#endif + + +#define W(i) coord[i][3] +#define Z(i) coord[i][2] +#define Y(i) coord[i][1] +#define X(i) coord[i][0] +#define SIZE 4 +#define TAG(x) x##_4 +#include "tnl/t_vb_cliptmp.h" + + + +/**********************************************************************/ +/* Clip and render whole begin/end objects */ +/**********************************************************************/ + +#define NEED_EDGEFLAG_SETUP (ctx->_TriangleCaps & DD_TRI_UNFILLED) +#define EDGEFLAG_GET(idx) VB->EdgeFlag[idx] +#define EDGEFLAG_SET(idx, val) VB->EdgeFlag[idx] = val + + +/* Vertices, with the possibility of clipping. + */ +#define RENDER_POINTS( start, count ) \ + tnl->Driver.Render.Points( ctx, start, count ) + +#define RENDER_LINE( v1, v2 ) \ +do { \ + GLubyte c1 = mask[v1], c2 = mask[v2]; \ + GLubyte ormask = c1|c2; \ + if (!ormask) \ + LineFunc( ctx, v1, v2 ); \ + else if (!(c1 & c2 & 0x3f)) \ + clip_line_4( ctx, v1, v2, ormask ); \ +} while (0) + +#define RENDER_TRI( v1, v2, v3 ) \ +do { \ + GLubyte c1 = mask[v1], c2 = mask[v2], c3 = mask[v3]; \ + GLubyte ormask = c1|c2|c3; \ + if (!ormask) \ + TriangleFunc( ctx, v1, v2, v3 ); \ + else if (!(c1 & c2 & c3 & 0x3f)) \ + clip_tri_4( ctx, v1, v2, v3, ormask ); \ +} while (0) + +#define RENDER_QUAD( v1, v2, v3, v4 ) \ +do { \ + GLubyte c1 = mask[v1], c2 = mask[v2]; \ + GLubyte c3 = mask[v3], c4 = mask[v4]; \ + GLubyte ormask = c1|c2|c3|c4; \ + if (!ormask) \ + QuadFunc( ctx, v1, v2, v3, v4 ); \ + else if (!(c1 & c2 & c3 & c4 & 0x3f)) \ + clip_quad_4( ctx, v1, v2, v3, v4, ormask ); \ +} while (0) + + +#define LOCAL_VARS \ + TNLcontext *tnl = TNL_CONTEXT(ctx); \ + struct vertex_buffer *VB = &tnl->vb; \ + const GLuint * const elt = VB->Elts; \ + const GLubyte *mask = VB->ClipMask; \ + const GLuint sz = VB->ClipPtr->size; \ + const tnl_line_func LineFunc = tnl->Driver.Render.Line; \ + const tnl_triangle_func TriangleFunc = tnl->Driver.Render.Triangle; \ + const tnl_quad_func QuadFunc = tnl->Driver.Render.Quad; \ + const GLboolean stipple = ctx->Line.StippleFlag; \ + (void) (LineFunc && TriangleFunc && QuadFunc); \ + (void) elt; (void) mask; (void) sz; (void) stipple; + +#define TAG(x) clip_##x##_verts +#define INIT(x) tnl->Driver.Render.PrimitiveNotify( ctx, x ) +#define RESET_STIPPLE if (stipple) tnl->Driver.Render.ResetLineStipple( ctx ) +#define PRESERVE_VB_DEFS +#include "tnl/t_vb_rendertmp.h" + + + +/* Elts, with the possibility of clipping. + */ +#undef ELT +#undef TAG +#define ELT(x) elt[x] +#define TAG(x) clip_##x##_elts +#include "tnl/t_vb_rendertmp.h" + +/* TODO: do this for all primitives, verts and elts: + */ +static void clip_elt_triangles( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + tnl_render_func render_tris = tnl->Driver.Render.PrimTabElts[GL_TRIANGLES]; + struct vertex_buffer *VB = &tnl->vb; + const GLuint * const elt = VB->Elts; + GLubyte *mask = VB->ClipMask; + GLuint last = count-2; + GLuint j; + (void) flags; + + tnl->Driver.Render.PrimitiveNotify( ctx, GL_TRIANGLES ); + + for (j=start; j < last; j+=3 ) { + GLubyte c1 = mask[elt[j]]; + GLubyte c2 = mask[elt[j+1]]; + GLubyte c3 = mask[elt[j+2]]; + GLubyte ormask = c1|c2|c3; + if (ormask) { + if (start < j) + render_tris( ctx, start, j, 0 ); + if (!(c1&c2&c3&0x3f)) + clip_tri_4( ctx, elt[j], elt[j+1], elt[j+2], ormask ); + start = j+3; + } + } + + if (start < j) + render_tris( ctx, start, j, 0 ); +} + +/**********************************************************************/ +/* Render whole begin/end objects */ +/**********************************************************************/ + +#define NEED_EDGEFLAG_SETUP (ctx->_TriangleCaps & DD_TRI_UNFILLED) +#define EDGEFLAG_GET(idx) VB->EdgeFlag[idx] +#define EDGEFLAG_SET(idx, val) VB->EdgeFlag[idx] = val + + +/* Vertices, no clipping. + */ +#define RENDER_POINTS( start, count ) \ + tnl->Driver.Render.Points( ctx, start, count ) + +#define RENDER_LINE( v1, v2 ) \ + LineFunc( ctx, v1, v2 ) + +#define RENDER_TRI( v1, v2, v3 ) \ + TriangleFunc( ctx, v1, v2, v3 ) + +#define RENDER_QUAD( v1, v2, v3, v4 ) \ + QuadFunc( ctx, v1, v2, v3, v4 ) + +#define TAG(x) _gld_tnl_##x##_verts + +#define LOCAL_VARS \ + TNLcontext *tnl = TNL_CONTEXT(ctx); \ + struct vertex_buffer *VB = &tnl->vb; \ + const GLuint * const elt = VB->Elts; \ + const tnl_line_func LineFunc = tnl->Driver.Render.Line; \ + const tnl_triangle_func TriangleFunc = tnl->Driver.Render.Triangle; \ + const tnl_quad_func QuadFunc = tnl->Driver.Render.Quad; \ + (void) (LineFunc && TriangleFunc && QuadFunc); \ + (void) elt; + +#define RESET_STIPPLE tnl->Driver.Render.ResetLineStipple( ctx ) +#define INIT(x) tnl->Driver.Render.PrimitiveNotify( ctx, x ) +#define RENDER_TAB_QUALIFIER +#define PRESERVE_VB_DEFS +#include "tnl/t_vb_rendertmp.h" + + +/* Elts, no clipping. + */ +#undef ELT +#define TAG(x) _gld_tnl_##x##_elts +#define ELT(x) elt[x] +#include "tnl/t_vb_rendertmp.h" + + +/**********************************************************************/ +/* Helper functions for drivers */ +/**********************************************************************/ +/* +void _tnl_RenderClippedPolygon( GLcontext *ctx, const GLuint *elts, GLuint n ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + GLuint *tmp = VB->Elts; + + VB->Elts = (GLuint *)elts; + tnl->Driver.Render.PrimTabElts[GL_POLYGON]( ctx, 0, n, PRIM_BEGIN|PRIM_END ); + VB->Elts = tmp; +} + +void _tnl_RenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + tnl->Driver.Render.Line( ctx, ii, jj ); +} +*/ + + +/**********************************************************************/ +/* Clip and render whole vertex buffers */ +/**********************************************************************/ + +tnl_points_func _gldSetupPoints[4] = { + gld_Points2D_DX9, + gld_Points2D_DX9, + gld_Points2D_DX9, + gld_Points2D_DX9 +}; +tnl_line_func _gldSetupLine[4] = { + gld_Line2DFlat_DX9, + gld_Line2DSmooth_DX9, + gld_Line2DFlat_DX9, + gld_Line2DSmooth_DX9, +}; +tnl_triangle_func _gldSetupTriangle[4] = { + gld_Triangle2DFlat_DX9, + gld_Triangle2DSmooth_DX9, + gld_Triangle2DFlatExtras_DX9, + gld_Triangle2DSmoothExtras_DX9 +}; +tnl_quad_func _gldSetupQuad[4] = { + gld_Quad2DFlat_DX9, + gld_Quad2DSmooth_DX9, + gld_Quad2DFlatExtras_DX9, + gld_Quad2DSmoothExtras_DX9 +}; + +//--------------------------------------------------------------------------- + +static GLboolean _gld_mesa_render_stage_run( + GLcontext *ctx, + struct tnl_pipeline_stage *stage) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + GLD_driver_dx9 *gld = GLD_GET_DX9_DRIVER(gldCtx); + + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + tnl_render_func *tab; + GLint pass = 0; + GLD_pb_dx9 *gldPB; + + /* Allow the drivers to lock before projected verts are built so + * that window coordinates are guarenteed not to change before + * rendering. + */ + ASSERT(tnl->Driver.Render.Start); + + tnl->Driver.Render.Start( ctx ); + + // NOTE: Setting D3DRS_SOFTWAREVERTEXPROCESSING for a mixed-mode device resets + // stream, indices and shader to default values of NULL or 0. +/* if ((ctx->_TriangleCaps & DD_TRI_LIGHT_TWOSIDE) && + gld->VStwosidelight.hShader && + !ctx->Fog.Enabled) + { + IDirect3DDevice8_SetRenderState(gld->pDev, D3DRS_SOFTWAREVERTEXPROCESSING, !gld->VStwosidelight.bHardware); + _GLD_DX9_DEV(SetVertexShader(gld->pDev, gld->VStwosidelight.hShader)); + gldPB = &gld->PBtwosidelight; + tnl->Driver.Render.Points = gld_Points2DTwoside_DX9; + if (ctx->_TriangleCaps & DD_FLATSHADE) { + tnl->Driver.Render.Line = gld_Line2DFlatTwoside_DX9; + tnl->Driver.Render.Triangle = gld_Triangle2DFlatTwoside_DX9; + tnl->Driver.Render.Quad = gld_Quad2DFlatTwoside_DX9; + } else { + tnl->Driver.Render.Line = gld_Line2DSmoothTwoside_DX9; + tnl->Driver.Render.Triangle = gld_Triangle2DSmoothTwoside_DX9; + tnl->Driver.Render.Quad = gld_Quad2DSmoothTwoside_DX9; + } + } else {*/ +// IDirect3DDevice8_SetRenderState(gld->pDev, D3DRS_SOFTWAREVERTEXPROCESSING, TRUE); + IDirect3DDevice9_SetSoftwareVertexProcessing(gld->pDev, TRUE); + gldPB = &gld->PB2d; + _GLD_DX9_DEV(SetVertexShader(gld->pDev, NULL)); + _GLD_DX9_DEV(SetFVF(gld->pDev, gldPB->dwFVF)); + tnl->Driver.Render.Points = _gldSetupPoints[gld->iSetupFunc]; + tnl->Driver.Render.Line = _gldSetupLine[gld->iSetupFunc]; + tnl->Driver.Render.Triangle = _gldSetupTriangle[gld->iSetupFunc]; + tnl->Driver.Render.Quad = _gldSetupQuad[gld->iSetupFunc]; +// } + + _GLD_DX9_VB(Lock(gldPB->pVB, 0, 0, &gldPB->pPoints, D3DLOCK_DISCARD)); + gldPB->nPoints = gldPB->nLines = gldPB->nTriangles = 0; + // Allocate primitive pointers + // gldPB->pPoints is always first + gldPB->pLines = gldPB->pPoints + (gldPB->dwStride * gldPB->iFirstLine); + gldPB->pTriangles = gldPB->pPoints + (gldPB->dwStride * gldPB->iFirstTriangle); + + ASSERT(tnl->Driver.Render.BuildVertices); + ASSERT(tnl->Driver.Render.PrimitiveNotify); + ASSERT(tnl->Driver.Render.Points); + ASSERT(tnl->Driver.Render.Line); + ASSERT(tnl->Driver.Render.Triangle); + ASSERT(tnl->Driver.Render.Quad); + ASSERT(tnl->Driver.Render.ResetLineStipple); + ASSERT(tnl->Driver.Render.Interp); + ASSERT(tnl->Driver.Render.CopyPV); + ASSERT(tnl->Driver.Render.ClippedLine); + ASSERT(tnl->Driver.Render.ClippedPolygon); + ASSERT(tnl->Driver.Render.Finish); + + tnl->Driver.Render.BuildVertices( ctx, 0, VB->Count, ~0 ); + + if (VB->ClipOrMask) { + tab = VB->Elts ? clip_render_tab_elts : clip_render_tab_verts; + clip_render_tab_elts[GL_TRIANGLES] = clip_elt_triangles; + } + else { + tab = (VB->Elts ? + tnl->Driver.Render.PrimTabElts : + tnl->Driver.Render.PrimTabVerts); + } + + do { + GLuint i, length, flags = 0; + for (i = 0 ; !(flags & PRIM_END) ; i += length) { + flags = VB->Primitive[i].mode; + length= VB->Primitive[i].count; + ASSERT(length || (flags & PRIM_END)); + ASSERT((flags & PRIM_MODE_MASK) <= GL_POLYGON+1); + if (length) + tab[flags & PRIM_MODE_MASK]( ctx, i, i + length, flags ); + } + } while (tnl->Driver.Render.Multipass && + tnl->Driver.Render.Multipass( ctx, ++pass )); + + +// tnl->Driver.Render.Finish( ctx ); + + _GLD_DX9_VB(Unlock(gldPB->pVB)); + + _GLD_DX9_DEV(SetStreamSource(gld->pDev, 0, gldPB->pVB, 0, gldPB->dwStride)); + + if (gldPB->nPoints) { + _GLD_DX9_DEV(DrawPrimitive(gld->pDev, D3DPT_POINTLIST, 0, gldPB->nPoints)); + gldPB->nPoints = 0; + } + + if (gldPB->nLines) { + _GLD_DX9_DEV(DrawPrimitive(gld->pDev, D3DPT_LINELIST, gldPB->iFirstLine, gldPB->nLines)); + gldPB->nLines = 0; + } + + if (gldPB->nTriangles) { + _GLD_DX9_DEV(DrawPrimitive(gld->pDev, D3DPT_TRIANGLELIST, gldPB->iFirstTriangle, gldPB->nTriangles)); + gldPB->nTriangles = 0; + } + + return GL_FALSE; /* finished the pipe */ +} + + +/**********************************************************************/ +/* Render pipeline stage */ +/**********************************************************************/ + + + + +const struct tnl_pipeline_stage _gld_mesa_render_stage = +{ + "gld_mesa_render_stage", + NULL, + NULL, + NULL, + NULL, + _gld_mesa_render_stage_run /* run */ +}; + +//--------------------------------------------------------------------------- diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_wgl_dx9.c b/mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_wgl_dx9.c new file mode 100644 index 000000000..a03b865bb --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dx9/gld_wgl_dx9.c @@ -0,0 +1,1346 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x/2000/XP/XBox (Win32) +* +* Description: GLDirect Direct3D 8.x WGL (WindowsGL) +* +****************************************************************************/ + +#include "dglcontext.h" +#include "gld_driver.h" +#include "gld_dxerr9.h" +#include "gld_dx9.h" + +#include "tnl/tnl.h" +#include "tnl/t_context.h" + +// Copied from dglcontect.c +#define GLDERR_NONE 0 +#define GLDERR_MEM 1 +#define GLDERR_DDRAW 2 +#define GLDERR_D3D 3 +#define GLDERR_BPP 4 +#define GLDERR_DDS 5 +// This external var keeps track of any error +extern int nContextError; + +#define DDLOG_CRITICAL_OR_WARN DDLOG_CRITICAL + +extern void _gld_mesa_warning(GLcontext *, char *); +extern void _gld_mesa_fatal(GLcontext *, char *); + +//--------------------------------------------------------------------------- + +static char szColorDepthWarning[] = +"GLDirect does not support the current desktop\n\ +color depth.\n\n\ +You may need to change the display resolution to\n\ +16 bits per pixel or higher color depth using\n\ +the Windows Display Settings control panel\n\ +before running this OpenGL application.\n"; + +// The only depth-stencil formats currently supported by Direct3D +// Surface Format Depth Stencil Total Bits +// D3DFMT_D32 32 - 32 +// D3DFMT_D15S1 15 1 16 +// D3DFMT_D24S8 24 8 32 +// D3DFMT_D16 16 - 16 +// D3DFMT_D24X8 24 - 32 +// D3DFMT_D24X4S4 24 4 32 + +// This pixel format will be used as a template when compiling the list +// of pixel formats supported by the hardware. Many fields will be +// filled in at runtime. +// PFD flag defaults are upgraded to match ChoosePixelFormat() -- DaveM +static DGL_pixelFormat pfTemplateHW = +{ + { + sizeof(PIXELFORMATDESCRIPTOR), // Size of the data structure + 1, // Structure version - should be 1 + // Flags: + PFD_DRAW_TO_WINDOW | // The buffer can draw to a window or device surface. + PFD_DRAW_TO_BITMAP | // The buffer can draw to a bitmap. (DaveM) + PFD_SUPPORT_GDI | // The buffer supports GDI drawing. (DaveM) + PFD_SUPPORT_OPENGL | // The buffer supports OpenGL drawing. + PFD_DOUBLEBUFFER | // The buffer is double-buffered. + 0, // Placeholder for easy commenting of above flags + PFD_TYPE_RGBA, // Pixel type RGBA. + 16, // Total colour bitplanes (excluding alpha bitplanes) + 5, 0, // Red bits, shift + 5, 0, // Green bits, shift + 5, 0, // Blue bits, shift + 0, 0, // Alpha bits, shift (destination alpha) + 0, // Accumulator bits (total) + 0, 0, 0, 0, // Accumulator bits: Red, Green, Blue, Alpha + 0, // Depth bits + 0, // Stencil bits + 0, // Number of auxiliary buffers + 0, // Layer type + 0, // Specifies the number of overlay and underlay planes. + 0, // Layer mask + 0, // Specifies the transparent color or index of an underlay plane. + 0 // Damage mask + }, + D3DFMT_UNKNOWN, // No depth/stencil buffer +}; + +//--------------------------------------------------------------------------- +// Vertex Shaders +//--------------------------------------------------------------------------- +/* +// Vertex Shader Declaration +static DWORD dwTwoSidedLightingDecl[] = +{ + D3DVSD_STREAM(0), + D3DVSD_REG(0, D3DVSDT_FLOAT3), // XYZ position + D3DVSD_REG(1, D3DVSDT_FLOAT3), // XYZ normal + D3DVSD_REG(2, D3DVSDT_D3DCOLOR), // Diffuse color + D3DVSD_REG(3, D3DVSDT_D3DCOLOR), // Specular color + D3DVSD_REG(4, D3DVSDT_FLOAT2), // 2D texture unit 0 + D3DVSD_REG(5, D3DVSDT_FLOAT2), // 2D texture unit 1 + D3DVSD_END() +}; + +// Vertex Shader for two-sided lighting +static char *szTwoSidedLightingVS = +// This is a test shader! +"vs.1.0\n" +"m4x4 oPos,v0,c0\n" +"mov oD0,v2\n" +"mov oD1,v3\n" +"mov oT0,v4\n" +"mov oT1,v5\n" +; +*/ +//--------------------------------------------------------------------------- +//--------------------------------------------------------------------------- + +typedef struct { + HINSTANCE hD3D9DLL; // Handle to d3d9.dll + FNDIRECT3DCREATE9 fnDirect3DCreate9; // Direct3DCreate9 function prototype + BOOL bDirect3D; // Persistant Direct3D9 exists + BOOL bDirect3DDevice; // Persistant Direct3DDevice9 exists + IDirect3D9 *pD3D; // Persistant Direct3D9 + IDirect3DDevice9 *pDev; // Persistant Direct3DDevice9 +} GLD_dx9_globals; + +// These are "global" to all DX9 contexts. KeithH +static GLD_dx9_globals dx9Globals; + +//--------------------------------------------------------------------------- +//--------------------------------------------------------------------------- + +BOOL gldGetDXErrorString_DX( + HRESULT hr, + char *buf, + int nBufSize) +{ + // + // Return a string describing the input HRESULT error code + // + + const char *pStr = DXGetErrorString9(hr); + + if (pStr == NULL) + return FALSE; + + if (strlen(pStr) > nBufSize) + strncpy(buf, pStr, nBufSize); + else + strcpy(buf, pStr); + +// D3DXGetErrorString(hr, buf, nBufSize); + + return TRUE; +} + +//--------------------------------------------------------------------------- + +static D3DMULTISAMPLE_TYPE _gldGetDeviceMultiSampleType( + IDirect3D9 *pD3D9, + D3DFORMAT SurfaceFormat, + D3DDEVTYPE d3dDevType, + BOOL Windowed) +{ + int i; + HRESULT hr; + + if (glb.dwMultisample == GLDS_MULTISAMPLE_NONE) + return D3DMULTISAMPLE_NONE; + + if (glb.dwMultisample == GLDS_MULTISAMPLE_FASTEST) { + // Find fastest multisample + for (i=2; i<17; i++) { + hr = IDirect3D9_CheckDeviceMultiSampleType( + pD3D9, + glb.dwAdapter, + d3dDevType, + SurfaceFormat, + Windowed, + (D3DMULTISAMPLE_TYPE)i, + NULL); + if (SUCCEEDED(hr)) { + return (D3DMULTISAMPLE_TYPE)i; + } + } + } else { + // Find nicest multisample + for (i=16; i>1; i--) { + hr = IDirect3D9_CheckDeviceMultiSampleType( + pD3D9, + glb.dwAdapter, + d3dDevType, + SurfaceFormat, + Windowed, + (D3DMULTISAMPLE_TYPE)i, + NULL); + if (SUCCEEDED(hr)) { + return (D3DMULTISAMPLE_TYPE)i; + } + } + } + + // Nothing found - return default + return D3DMULTISAMPLE_NONE; +} + +//--------------------------------------------------------------------------- + +void _gldDestroyPrimitiveBuffer( + GLD_pb_dx9 *gldVB) +{ + SAFE_RELEASE(gldVB->pVB); + + // Sanity check... + gldVB->nLines = gldVB->nPoints = gldVB->nTriangles = 0; +} + +//--------------------------------------------------------------------------- + +HRESULT _gldCreatePrimitiveBuffer( + GLcontext *ctx, + GLD_driver_dx9 *lpCtx, + GLD_pb_dx9 *gldVB) +{ + HRESULT hResult; + char *szCreateVertexBufferFailed = "CreateVertexBuffer failed"; + DWORD dwMaxVertices; // Max number of vertices in vertex buffer + DWORD dwVBSize; // Total size of vertex buffer + + // If CVA (Compiled Vertex Array) is used by an OpenGL app, then we + // will need enough vertices to cater for Mesa::Const.MaxArrayLockSize. + // We'll use IMM_SIZE if it's larger (which it should not be). + dwMaxVertices = MAX_ARRAY_LOCK_SIZE; + + // Now calculate how many vertices to allow for in total + // 1 per point, 2 per line, 6 per quad = 9 + dwVBSize = dwMaxVertices * 9 * gldVB->dwStride; + + hResult = IDirect3DDevice9_CreateVertexBuffer( + lpCtx->pDev, + dwVBSize, + gldVB->dwUsage, + gldVB->dwFVF, + gldVB->dwPool, + &gldVB->pVB, + NULL); + if (FAILED(hResult)) { + ddlogMessage(DDLOG_CRITICAL_OR_WARN, szCreateVertexBufferFailed); + return hResult; + } + + gldVB->nLines = gldVB->nPoints = gldVB->nTriangles = 0; + gldVB->pPoints = gldVB->pLines = gldVB->pTriangles = NULL; + gldVB->iFirstLine = dwMaxVertices; // Index of first line in VB + gldVB->iFirstTriangle = dwMaxVertices*3; // Index of first triangle in VB + + return S_OK; +} + +//--------------------------------------------------------------------------- +// Function: _gldCreateVertexShaders +// Create DX9 Vertex Shaders. +//--------------------------------------------------------------------------- +/* +void _gldCreateVertexShaders( + GLD_driver_dx9 *gld) +{ + DWORD dwFlags; + LPD3DXBUFFER pVSOpcodeBuffer; // Vertex Shader opcode buffer + HRESULT hr; + +#ifdef _DEBUG + dwFlags = D3DXASM_DEBUG; +#else + dwFlags = 0; // D3DXASM_SKIPVALIDATION; +#endif + + ddlogMessage(DDLOG_INFO, "Creating shaders...\n"); + + // Init the shader handle + gld->VStwosidelight.hShader = 0; + + if (gld->d3dCaps8.MaxStreams == 0) { + // Lame DX8 driver doesn't support streams + // Not fatal, as defaults will be used + ddlogMessage(DDLOG_WARN, "Driver doesn't support Vertex Shaders (MaxStreams==0)\n"); + return; + } + + // ** THIS DISABLES VERTEX SHADER SUPPORT ** +// return; + // ** THIS DISABLES VERTEX SHADER SUPPORT ** + + // + // Two-sided lighting + // + +#if 0 + // + // DEBUGGING: Load shader from a text file + // + { + LPD3DXBUFFER pVSErrorBuffer; // Vertex Shader error buffer + hr = D3DXAssembleShaderFromFile( + "twoside.vsh", + dwFlags, + NULL, // No constants + &pVSOpcodeBuffer, + &pVSErrorBuffer); + if (pVSErrorBuffer && pVSErrorBuffer->lpVtbl->GetBufferPointer(pVSErrorBuffer)) + ddlogMessage(DDLOG_INFO, pVSErrorBuffer->lpVtbl->GetBufferPointer(pVSErrorBuffer)); + SAFE_RELEASE(pVSErrorBuffer); + } +#else + { + LPD3DXBUFFER pVSErrorBuffer; // Vertex Shader error buffer + // Assemble ascii shader text into shader opcodes + hr = D3DXAssembleShader( + szTwoSidedLightingVS, + strlen(szTwoSidedLightingVS), + dwFlags, + NULL, // No constants + &pVSOpcodeBuffer, + &pVSErrorBuffer); + if (pVSErrorBuffer && pVSErrorBuffer->lpVtbl->GetBufferPointer(pVSErrorBuffer)) + ddlogMessage(DDLOG_INFO, pVSErrorBuffer->lpVtbl->GetBufferPointer(pVSErrorBuffer)); + SAFE_RELEASE(pVSErrorBuffer); + } +#endif + if (FAILED(hr)) { + ddlogError(DDLOG_WARN, "AssembleShader failed", hr); + SAFE_RELEASE(pVSOpcodeBuffer); + return; + } + +// This is for debugging. Remove to enable vertex shaders in HW +#define _GLD_FORCE_SW_VS 0 + + if (_GLD_FORCE_SW_VS) { + // _GLD_FORCE_SW_VS should be disabled for Final Release + ddlogMessage(DDLOG_SYSTEM, "[Forcing shaders in SW]\n"); + } + + // Try and create shader in hardware. + // NOTE: The D3D Ref device appears to succeed when trying to + // create the device in hardware, but later complains + // when trying to set it with SetVertexShader(). Go figure. + if (_GLD_FORCE_SW_VS || glb.dwDriver == GLDS_DRIVER_REF) { + // Don't try and create a hardware shader with the Ref device + hr = E_FAIL; // COM error/fail result + } else { + gld->VStwosidelight.bHardware = TRUE; + hr = IDirect3DDevice8_CreateVertexShader( + gld->pDev, + dwTwoSidedLightingDecl, + pVSOpcodeBuffer->lpVtbl->GetBufferPointer(pVSOpcodeBuffer), + &gld->VStwosidelight.hShader, + 0); + } + if (FAILED(hr)) { + ddlogMessage(DDLOG_INFO, "... HW failed, trying SW...\n"); + // Failed. Try and create shader for software processing + hr = IDirect3DDevice8_CreateVertexShader( + gld->pDev, + dwTwoSidedLightingDecl, + pVSOpcodeBuffer->lpVtbl->GetBufferPointer(pVSOpcodeBuffer), + &gld->VStwosidelight.hShader, + D3DUSAGE_SOFTWAREPROCESSING); + if (FAILED(hr)) { + gld->VStwosidelight.hShader = 0; // Sanity check + ddlogError(DDLOG_WARN, "CreateVertexShader failed", hr); + return; + } + // Succeeded, but for software processing + gld->VStwosidelight.bHardware = FALSE; + } + + SAFE_RELEASE(pVSOpcodeBuffer); + + ddlogMessage(DDLOG_INFO, "... OK\n"); +} + +//--------------------------------------------------------------------------- + +void _gldDestroyVertexShaders( + GLD_driver_dx9 *gld) +{ + if (gld->VStwosidelight.hShader) { + IDirect3DDevice8_DeleteVertexShader(gld->pDev, gld->VStwosidelight.hShader); + gld->VStwosidelight.hShader = 0; + } +} +*/ +//--------------------------------------------------------------------------- + +BOOL gldCreateDrawable_DX( + DGL_ctx *ctx, +// BOOL bDefaultDriver, + BOOL bDirectDrawPersistant, + BOOL bPersistantBuffers) +{ + // + // bDirectDrawPersistant: applies to IDirect3D9 + // bPersistantBuffers: applies to IDirect3DDevice9 + // + + HRESULT hResult; + GLD_driver_dx9 *lpCtx = NULL; + D3DDEVTYPE d3dDevType; + D3DPRESENT_PARAMETERS d3dpp; + D3DDISPLAYMODE d3ddm; + DWORD dwBehaviourFlags; + D3DADAPTER_IDENTIFIER9 d3dIdent; + + // Error if context is NULL. + if (ctx == NULL) + return FALSE; + + if (ctx->glPriv) { + lpCtx = ctx->glPriv; + // Release any existing interfaces + SAFE_RELEASE(lpCtx->pDev); + SAFE_RELEASE(lpCtx->pD3D); + } else { + lpCtx = (GLD_driver_dx9*)malloc(sizeof(GLD_driver_dx9)); + ZeroMemory(lpCtx, sizeof(lpCtx)); + } + + d3dDevType = (glb.dwDriver == GLDS_DRIVER_HAL) ? D3DDEVTYPE_HAL : D3DDEVTYPE_REF; + // TODO: Check this +// if (bDefaultDriver) +// d3dDevType = D3DDEVTYPE_REF; + + // Use persistant interface if needed + if (bDirectDrawPersistant && dx9Globals.bDirect3D) { + lpCtx->pD3D = dx9Globals.pD3D; + IDirect3D9_AddRef(lpCtx->pD3D); + goto SkipDirectDrawCreate; + } + + // Create Direct3D9 object + lpCtx->pD3D = dx9Globals.fnDirect3DCreate9(D3D_SDK_VERSION); + if (lpCtx->pD3D == NULL) { + MessageBox(NULL, "Unable to initialize Direct3D9", "GLDirect", MB_OK); + ddlogMessage(DDLOG_CRITICAL_OR_WARN, "Unable to create Direct3D9 interface"); + nContextError = GLDERR_D3D; + goto return_with_error; + } + + // Cache Direct3D interface for subsequent GLRCs + if (bDirectDrawPersistant && !dx9Globals.bDirect3D) { + dx9Globals.pD3D = lpCtx->pD3D; + IDirect3D9_AddRef(dx9Globals.pD3D); + dx9Globals.bDirect3D = TRUE; + } +SkipDirectDrawCreate: + + // Get the display mode so we can make a compatible backbuffer + hResult = IDirect3D9_GetAdapterDisplayMode(lpCtx->pD3D, glb.dwAdapter, &d3ddm); + if (FAILED(hResult)) { + nContextError = GLDERR_D3D; + goto return_with_error; + } + + // Get device caps + hResult = IDirect3D9_GetDeviceCaps(lpCtx->pD3D, glb.dwAdapter, d3dDevType, &lpCtx->d3dCaps9); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "IDirect3D9_GetDeviceCaps failed", hResult); + nContextError = GLDERR_D3D; + goto return_with_error; + } + + // Check for hardware transform & lighting + lpCtx->bHasHWTnL = lpCtx->d3dCaps9.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ? TRUE : FALSE; + +/* + // + // GONE FOR DX9? + // + // If this flag is present then we can't default to Mesa + // SW rendering between BeginScene() and EndScene(). + if (lpCtx->d3dCaps9.Caps2 & D3DCAPS2_NO2DDURING3DSCENE) { + ddlogMessage(DDLOG_WARN, + "Warning : No 2D allowed during 3D scene.\n"); + } +*/ + + // + // Create the Direct3D context + // + + // Re-use original IDirect3DDevice if persistant buffers exist. + // Note that we test for persistant IDirect3D9 as well + // bDirectDrawPersistant == persistant IDirect3D9 (DirectDraw9 does not exist) + if (bDirectDrawPersistant && bPersistantBuffers && dx9Globals.pD3D && dx9Globals.pDev) { + lpCtx->pDev = dx9Globals.pDev; + IDirect3DDevice9_AddRef(dx9Globals.pDev); + goto skip_direct3ddevice_create; + } + + // Clear the presentation parameters (sets all members to zero) + ZeroMemory(&d3dpp, sizeof(d3dpp)); + + // Recommended by MS; needed for MultiSample. + // Be careful if altering this for FullScreenBlit + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + + d3dpp.BackBufferFormat = d3ddm.Format; + d3dpp.BackBufferCount = 2; //1; + d3dpp.MultiSampleType = _gldGetDeviceMultiSampleType(lpCtx->pD3D, d3ddm.Format, d3dDevType, !ctx->bFullscreen); + d3dpp.AutoDepthStencilFormat = ctx->lpPF->dwDriverData; + d3dpp.EnableAutoDepthStencil = (d3dpp.AutoDepthStencilFormat == D3DFMT_UNKNOWN) ? FALSE : TRUE; + + if (ctx->bFullscreen) { + ddlogWarnOption(FALSE); // Don't popup any messages in fullscreen + d3dpp.Windowed = FALSE; + d3dpp.BackBufferWidth = d3ddm.Width; + d3dpp.BackBufferHeight = d3ddm.Height; + d3dpp.hDeviceWindow = ctx->hWnd; + d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; + + // Support for vertical retrace synchronisation. + // Set default presentation interval in case caps bits are missing + d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; + if (glb.bWaitForRetrace) { + if (lpCtx->d3dCaps9.PresentationIntervals & D3DPRESENT_INTERVAL_ONE) + d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; + } else { + if (lpCtx->d3dCaps9.PresentationIntervals & D3DPRESENT_INTERVAL_IMMEDIATE) + d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + } + } else { + ddlogWarnOption(glb.bMessageBoxWarnings); // OK to popup messages + d3dpp.Windowed = TRUE; + d3dpp.BackBufferWidth = ctx->dwWidth; + d3dpp.BackBufferHeight = ctx->dwHeight; + d3dpp.hDeviceWindow = ctx->hWnd; + d3dpp.FullScreen_RefreshRateInHz = 0; + // PresentationInterval Windowed mode is optional now in DX9 (DaveM) + d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; + if (glb.bWaitForRetrace) { + d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; + } else { + d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + } + } + + // Decide if we can use hardware TnL + dwBehaviourFlags = (lpCtx->bHasHWTnL) ? + D3DCREATE_MIXED_VERTEXPROCESSING : D3DCREATE_SOFTWARE_VERTEXPROCESSING; + // Add flag to tell D3D to be thread-safe + if (glb.bMultiThreaded) + dwBehaviourFlags |= D3DCREATE_MULTITHREADED; + // Add flag to tell D3D to be FPU-safe + if (!glb.bFastFPU) + dwBehaviourFlags |= D3DCREATE_FPU_PRESERVE; + hResult = IDirect3D9_CreateDevice(lpCtx->pD3D, + glb.dwAdapter, + d3dDevType, + ctx->hWnd, + dwBehaviourFlags, + &d3dpp, + &lpCtx->pDev); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "IDirect3D9_CreateDevice failed", hResult); + nContextError = GLDERR_D3D; + goto return_with_error; + } + + if (bDirectDrawPersistant && bPersistantBuffers && dx9Globals.pD3D) { + dx9Globals.pDev = lpCtx->pDev; + dx9Globals.bDirect3DDevice = TRUE; + } + + // Dump some useful stats + hResult = IDirect3D9_GetAdapterIdentifier( + lpCtx->pD3D, + glb.dwAdapter, + 0, // No WHQL detection (avoid few seconds delay) + &d3dIdent); + if (SUCCEEDED(hResult)) { + ddlogPrintf(DDLOG_INFO, "[Driver Description: %s]", &d3dIdent.Description); + ddlogPrintf(DDLOG_INFO, "[Driver file: %s %d.%d.%02d.%d]", + d3dIdent.Driver, + HIWORD(d3dIdent.DriverVersion.HighPart), + LOWORD(d3dIdent.DriverVersion.HighPart), + HIWORD(d3dIdent.DriverVersion.LowPart), + LOWORD(d3dIdent.DriverVersion.LowPart)); + ddlogPrintf(DDLOG_INFO, "[VendorId: 0x%X, DeviceId: 0x%X, SubSysId: 0x%X, Revision: 0x%X]", + d3dIdent.VendorId, d3dIdent.DeviceId, d3dIdent.SubSysId, d3dIdent.Revision); + } + + // Test to see if IHV driver exposes Scissor Test (new for DX9) + lpCtx->bCanScissor = lpCtx->d3dCaps9.RasterCaps & D3DPRASTERCAPS_SCISSORTEST; + ddlogPrintf(DDLOG_INFO, "Can Scissor: %s", lpCtx->bCanScissor ? "Yes" : "No"); + + // Init projection matrix for D3D TnL + D3DXMatrixIdentity(&lpCtx->matProjection); + lpCtx->matModelView = lpCtx->matProjection; +// gld->bUseMesaProjection = TRUE; + +skip_direct3ddevice_create: + + // Create buffers to hold primitives + lpCtx->PB2d.dwFVF = GLD_FVF_2D_VERTEX; + lpCtx->PB2d.dwPool = D3DPOOL_SYSTEMMEM; + lpCtx->PB2d.dwStride = sizeof(GLD_2D_VERTEX); + lpCtx->PB2d.dwUsage = D3DUSAGE_DONOTCLIP | + D3DUSAGE_DYNAMIC | + D3DUSAGE_SOFTWAREPROCESSING | + D3DUSAGE_WRITEONLY; + hResult = _gldCreatePrimitiveBuffer(ctx->glCtx, lpCtx, &lpCtx->PB2d); + if (FAILED(hResult)) + goto return_with_error; + + lpCtx->PB3d.dwFVF = GLD_FVF_3D_VERTEX; + lpCtx->PB3d.dwPool = D3DPOOL_DEFAULT; + lpCtx->PB3d.dwStride = sizeof(GLD_3D_VERTEX); + lpCtx->PB3d.dwUsage = D3DUSAGE_DYNAMIC | +//DaveM D3DUSAGE_SOFTWAREPROCESSING | + D3DUSAGE_WRITEONLY; + hResult = _gldCreatePrimitiveBuffer(ctx->glCtx, lpCtx, &lpCtx->PB3d); + if (FAILED(hResult)) + goto return_with_error; + +/* // NOTE: A FVF code of zero indicates a non-FVF vertex buffer (for vertex shaders) + lpCtx->PBtwosidelight.dwFVF = 0; //GLD_FVF_TWOSIDED_VERTEX; + lpCtx->PBtwosidelight.dwPool = D3DPOOL_DEFAULT; + lpCtx->PBtwosidelight.dwStride = sizeof(GLD_TWOSIDED_VERTEX); + lpCtx->PBtwosidelight.dwUsage = D3DUSAGE_DONOTCLIP | + D3DUSAGE_DYNAMIC | + D3DUSAGE_SOFTWAREPROCESSING | + D3DUSAGE_WRITEONLY; + hResult = _gldCreatePrimitiveBuffer(ctx->glCtx, lpCtx, &lpCtx->PBtwosidelight); + if (FAILED(hResult)) + goto return_with_error;*/ + + // Now try and create the DX9 Vertex Shaders +// _gldCreateVertexShaders(lpCtx); + + // Zero the pipeline usage counters + lpCtx->PipelineUsage.qwMesa.QuadPart = +// lpCtx->PipelineUsage.dwD3D2SVS.QuadPart = + lpCtx->PipelineUsage.qwD3DFVF.QuadPart = 0; + + // Assign drawable to GL private + ctx->glPriv = lpCtx; + return TRUE; + +return_with_error: + // Clean up and bail + +// _gldDestroyVertexShaders(lpCtx); + +// _gldDestroyPrimitiveBuffer(&lpCtx->PBtwosidelight); + _gldDestroyPrimitiveBuffer(&lpCtx->PB3d); + _gldDestroyPrimitiveBuffer(&lpCtx->PB2d); + + SAFE_RELEASE(lpCtx->pDev); + SAFE_RELEASE(lpCtx->pD3D); + return FALSE; +} + +//--------------------------------------------------------------------------- + +BOOL gldResizeDrawable_DX( + DGL_ctx *ctx, + BOOL bDefaultDriver, + BOOL bPersistantInterface, + BOOL bPersistantBuffers) +{ + GLD_driver_dx9 *gld = NULL; + D3DDEVTYPE d3dDevType; + D3DPRESENT_PARAMETERS d3dpp; + D3DDISPLAYMODE d3ddm; + HRESULT hResult; + + // Error if context is NULL. + if (ctx == NULL) + return FALSE; + + gld = ctx->glPriv; + if (gld == NULL) + return FALSE; + + if (ctx->bSceneStarted) { + IDirect3DDevice9_EndScene(gld->pDev); + ctx->bSceneStarted = FALSE; + } + + d3dDevType = (glb.dwDriver == GLDS_DRIVER_HAL) ? D3DDEVTYPE_HAL : D3DDEVTYPE_REF; + if (!bDefaultDriver) + d3dDevType = D3DDEVTYPE_REF; // Force Direct3D Reference Rasterise (software) + + // Get the display mode so we can make a compatible backbuffer + hResult = IDirect3D9_GetAdapterDisplayMode(gld->pD3D, glb.dwAdapter, &d3ddm); + if (FAILED(hResult)) { + nContextError = GLDERR_D3D; +// goto return_with_error; + return FALSE; + } + + // Destroy DX9 Vertex Shaders before Reset() +// _gldDestroyVertexShaders(gld); + + // Release POOL_DEFAULT objects before Reset() + if (gld->PB2d.dwPool == D3DPOOL_DEFAULT) + _gldDestroyPrimitiveBuffer(&gld->PB2d); + if (gld->PB3d.dwPool == D3DPOOL_DEFAULT) + _gldDestroyPrimitiveBuffer(&gld->PB3d); +// if (gld->PBtwosidelight.dwPool == D3DPOOL_DEFAULT) +// _gldDestroyPrimitiveBuffer(&gld->PBtwosidelight); + + // Clear the presentation parameters (sets all members to zero) + ZeroMemory(&d3dpp, sizeof(d3dpp)); + + // Recommended by MS; needed for MultiSample. + // Be careful if altering this for FullScreenBlit + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + + d3dpp.BackBufferFormat = d3ddm.Format; + d3dpp.BackBufferCount = 1; + d3dpp.MultiSampleType = _gldGetDeviceMultiSampleType(gld->pD3D, d3ddm.Format, d3dDevType, !ctx->bFullscreen); + d3dpp.AutoDepthStencilFormat = ctx->lpPF->dwDriverData; + d3dpp.EnableAutoDepthStencil = (d3dpp.AutoDepthStencilFormat == D3DFMT_UNKNOWN) ? FALSE : TRUE; + + // TODO: Sync to refresh + + if (ctx->bFullscreen) { + ddlogWarnOption(FALSE); // Don't popup any messages in fullscreen + d3dpp.Windowed = FALSE; + d3dpp.BackBufferWidth = d3ddm.Width; + d3dpp.BackBufferHeight = d3ddm.Height; + d3dpp.hDeviceWindow = ctx->hWnd; + d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; + d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; + // Get better benchmark results? KeithH +// d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_UNLIMITED; + } else { + ddlogWarnOption(glb.bMessageBoxWarnings); // OK to popup messages + d3dpp.Windowed = TRUE; + d3dpp.BackBufferWidth = ctx->dwWidth; + d3dpp.BackBufferHeight = ctx->dwHeight; + d3dpp.hDeviceWindow = ctx->hWnd; + d3dpp.FullScreen_RefreshRateInHz = 0; + d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; + } + hResult = IDirect3DDevice9_Reset(gld->pDev, &d3dpp); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: Reset failed", hResult); + return FALSE; + //goto cleanup_and_return_with_error; + } + + // + // Recreate POOL_DEFAULT objects + // + if (gld->PB2d.dwPool == D3DPOOL_DEFAULT) { + _gldCreatePrimitiveBuffer(ctx->glCtx, gld, &gld->PB2d); + } + if (gld->PB3d.dwPool == D3DPOOL_DEFAULT) { + _gldCreatePrimitiveBuffer(ctx->glCtx, gld, &gld->PB3d); + } +// if (gld->PBtwosidelight.dwPool == D3DPOOL_DEFAULT) { +// _gldCreatePrimitiveBuffer(ctx->glCtx, gld, &gld->PB2d); +// } + + // Recreate DX9 Vertex Shaders +// _gldCreateVertexShaders(gld); + + // Signal a complete state update + ctx->glCtx->Driver.UpdateState(ctx->glCtx, _NEW_ALL); + + // Begin a new scene + IDirect3DDevice9_BeginScene(gld->pDev); + ctx->bSceneStarted = TRUE; + + return TRUE; +} + +//--------------------------------------------------------------------------- + +BOOL gldDestroyDrawable_DX( + DGL_ctx *ctx) +{ + GLD_driver_dx9 *lpCtx = NULL; + + // Error if context is NULL. + if (!ctx) + return FALSE; + + // Error if the drawable does not exist. + if (!ctx->glPriv) + return FALSE; + + lpCtx = ctx->glPriv; + +#ifdef _DEBUG + // Dump out stats + ddlogPrintf(DDLOG_SYSTEM, "Usage: M:0x%X%X, D:0x%X%X", + lpCtx->PipelineUsage.qwMesa.HighPart, + lpCtx->PipelineUsage.qwMesa.LowPart, + lpCtx->PipelineUsage.qwD3DFVF.HighPart, + lpCtx->PipelineUsage.qwD3DFVF.LowPart); +#endif + +// _gldDestroyVertexShaders(lpCtx); + +// _gldDestroyPrimitiveBuffer(&lpCtx->PBtwosidelight); + _gldDestroyPrimitiveBuffer(&lpCtx->PB3d); + _gldDestroyPrimitiveBuffer(&lpCtx->PB2d); + + SAFE_RELEASE(lpCtx->pDev); + SAFE_RELEASE(lpCtx->pD3D); + + // Free the private drawable data + free(ctx->glPriv); + ctx->glPriv = NULL; + + return TRUE; +} + +//--------------------------------------------------------------------------- + +BOOL gldCreatePrivateGlobals_DX(void) +{ + ZeroMemory(&dx9Globals, sizeof(dx9Globals)); + + // Load d3d9.dll + dx9Globals.hD3D9DLL = LoadLibrary("D3D9.DLL"); + if (dx9Globals.hD3D9DLL == NULL) + return FALSE; + + // Now try and obtain Direct3DCreate9 + dx9Globals.fnDirect3DCreate9 = (FNDIRECT3DCREATE9)GetProcAddress(dx9Globals.hD3D9DLL, "Direct3DCreate9"); + if (dx9Globals.fnDirect3DCreate9 == NULL) { + FreeLibrary(dx9Globals.hD3D9DLL); + return FALSE; + } + + return TRUE; +} + +//--------------------------------------------------------------------------- + +BOOL gldDestroyPrivateGlobals_DX(void) +{ + if (dx9Globals.bDirect3DDevice) { + SAFE_RELEASE(dx9Globals.pDev); + dx9Globals.bDirect3DDevice = FALSE; + } + if (dx9Globals.bDirect3D) { + SAFE_RELEASE(dx9Globals.pD3D); + dx9Globals.bDirect3D = FALSE; + } + + FreeLibrary(dx9Globals.hD3D9DLL); + dx9Globals.hD3D9DLL = NULL; + dx9Globals.fnDirect3DCreate9 = NULL; + + return TRUE; +} + +//--------------------------------------------------------------------------- + +static void _BitsFromDisplayFormat( + D3DFORMAT fmt, + BYTE *cColorBits, + BYTE *cRedBits, + BYTE *cGreenBits, + BYTE *cBlueBits, + BYTE *cAlphaBits) +{ + switch (fmt) { + case D3DFMT_X1R5G5B5: + *cColorBits = 16; + *cRedBits = 5; + *cGreenBits = 5; + *cBlueBits = 5; + *cAlphaBits = 0; + return; + case D3DFMT_R5G6B5: + *cColorBits = 16; + *cRedBits = 5; + *cGreenBits = 6; + *cBlueBits = 5; + *cAlphaBits = 0; + return; + case D3DFMT_X8R8G8B8: + *cColorBits = 32; + *cRedBits = 8; + *cGreenBits = 8; + *cBlueBits = 8; + *cAlphaBits = 0; + return; + case D3DFMT_A8R8G8B8: + *cColorBits = 32; + *cRedBits = 8; + *cGreenBits = 8; + *cBlueBits = 8; + *cAlphaBits = 8; + return; + } + + // Should not get here! + *cColorBits = 32; + *cRedBits = 8; + *cGreenBits = 8; + *cBlueBits = 8; + *cAlphaBits = 0; +} + +//--------------------------------------------------------------------------- + +static void _BitsFromDepthStencilFormat( + D3DFORMAT fmt, + BYTE *cDepthBits, + BYTE *cStencilBits) +{ + // NOTE: GL expects either 32 or 16 as depth bits. + switch (fmt) { + case D3DFMT_D32: + *cDepthBits = 32; + *cStencilBits = 0; + return; + case D3DFMT_D15S1: + *cDepthBits = 16; + *cStencilBits = 1; + return; + case D3DFMT_D24S8: + *cDepthBits = 32; + *cStencilBits = 8; + return; + case D3DFMT_D16: + *cDepthBits = 16; + *cStencilBits = 0; + return; + case D3DFMT_D24X8: + *cDepthBits = 32; + *cStencilBits = 0; + return; + case D3DFMT_D24X4S4: + *cDepthBits = 32; + *cStencilBits = 4; + return; + } +} + +//--------------------------------------------------------------------------- + +BOOL gldBuildPixelformatList_DX(void) +{ + D3DDISPLAYMODE d3ddm; + D3DFORMAT fmt[6]; + IDirect3D9 *pD3D = NULL; + HRESULT hr; + int nSupportedFormats = 0; + int i; + DGL_pixelFormat *pPF; + BYTE cColorBits, cRedBits, cGreenBits, cBlueBits, cAlphaBits; +// char buf[128]; +// char cat[8]; + + // Direct3D (SW or HW) + // These are arranged so that 'best' pixelformat + // is higher in the list (for ChoosePixelFormat). + const D3DFORMAT DepthStencil[6] = { +// New order: increaing Z, then increasing stencil + D3DFMT_D15S1, + D3DFMT_D16, + D3DFMT_D24X4S4, + D3DFMT_D24X8, + D3DFMT_D24S8, + D3DFMT_D32, + }; + + // Dump DX version + ddlogMessage(GLDLOG_SYSTEM, "DirectX Version : 9.0\n"); + + // Release any existing pixelformat list + if (glb.lpPF) { + free(glb.lpPF); + } + + glb.nPixelFormatCount = 0; + glb.lpPF = NULL; + + // + // Pixelformats for Direct3D (SW or HW) rendering + // + + // Get a Direct3D 9.0 interface + pD3D = dx9Globals.fnDirect3DCreate9(D3D_SDK_VERSION); + if (!pD3D) { + return FALSE; + } + + // We will use the display mode format when finding compliant + // rendertarget/depth-stencil surfaces. + hr = IDirect3D9_GetAdapterDisplayMode(pD3D, glb.dwAdapter, &d3ddm); + if (FAILED(hr)) { + IDirect3D9_Release(pD3D); + return FALSE; + } + + // Run through the possible formats and detect supported formats + for (i=0; i<6; i++) { + hr = IDirect3D9_CheckDeviceFormat( + pD3D, + glb.dwAdapter, + glb.dwDriver==GLDS_DRIVER_HAL ? D3DDEVTYPE_HAL : D3DDEVTYPE_REF, + d3ddm.Format, + D3DUSAGE_DEPTHSTENCIL, + D3DRTYPE_SURFACE, + DepthStencil[i]); + if (FAILED(hr)) + // A failure here is not fatal. + continue; + + // Verify that the depth format is compatible. + hr = IDirect3D9_CheckDepthStencilMatch( + pD3D, + glb.dwAdapter, + glb.dwDriver==GLDS_DRIVER_HAL ? D3DDEVTYPE_HAL : D3DDEVTYPE_REF, + d3ddm.Format, + d3ddm.Format, + DepthStencil[i]); + if (FAILED(hr)) + // A failure here is not fatal, just means depth-stencil + // format is not compatible with this display mode. + continue; + + fmt[nSupportedFormats++] = DepthStencil[i]; + } + + IDirect3D9_Release(pD3D); + + if (nSupportedFormats == 0) + return FALSE; // Bail: no compliant pixelformats + + // Total count of pixelformats is: + // (nSupportedFormats+1)*2 + // UPDATED: nSupportedFormats*2 + glb.lpPF = (DGL_pixelFormat *)calloc(nSupportedFormats*2, sizeof(DGL_pixelFormat)); + glb.nPixelFormatCount = nSupportedFormats*2; + if (glb.lpPF == NULL) { + glb.nPixelFormatCount = 0; + return FALSE; + } + + // Get a copy of pointer that we can alter + pPF = glb.lpPF; + + // Cache colour bits from display format + _BitsFromDisplayFormat(d3ddm.Format, &cColorBits, &cRedBits, &cGreenBits, &cBlueBits, &cAlphaBits); + + // + // Add single-buffer formats + // +/* + // NOTE: No longer returning pixelformats that don't contain depth + // Single-buffer, no depth-stencil buffer + memcpy(pPF, &pfTemplateHW, sizeof(DGL_pixelFormat)); + pPF->pfd.dwFlags &= ~PFD_DOUBLEBUFFER; // Remove doublebuffer flag + pPF->pfd.cColorBits = cColorBits; + pPF->pfd.cRedBits = cRedBits; + pPF->pfd.cGreenBits = cGreenBits; + pPF->pfd.cBlueBits = cBlueBits; + pPF->pfd.cAlphaBits = cAlphaBits; + pPF->pfd.cDepthBits = 0; + pPF->pfd.cStencilBits = 0; + pPF->dwDriverData = D3DFMT_UNKNOWN; + pPF++; +*/ + for (i=0; ipfd.dwFlags &= ~PFD_DOUBLEBUFFER; // Remove doublebuffer flag + pPF->pfd.cColorBits = cColorBits; + pPF->pfd.cRedBits = cRedBits; + pPF->pfd.cGreenBits = cGreenBits; + pPF->pfd.cBlueBits = cBlueBits; + pPF->pfd.cAlphaBits = cAlphaBits; + _BitsFromDepthStencilFormat(fmt[i], &pPF->pfd.cDepthBits, &pPF->pfd.cStencilBits); + pPF->dwDriverData = fmt[i]; + } + + // + // Add double-buffer formats + // + + // NOTE: No longer returning pixelformats that don't contain depth +/* + memcpy(pPF, &pfTemplateHW, sizeof(DGL_pixelFormat)); + pPF->pfd.cColorBits = cColorBits; + pPF->pfd.cRedBits = cRedBits; + pPF->pfd.cGreenBits = cGreenBits; + pPF->pfd.cBlueBits = cBlueBits; + pPF->pfd.cAlphaBits = cAlphaBits; + pPF->pfd.cDepthBits = 0; + pPF->pfd.cStencilBits = 0; + pPF->dwDriverData = D3DFMT_UNKNOWN; + pPF++; +*/ + for (i=0; ipfd.cColorBits = cColorBits; + pPF->pfd.cRedBits = cRedBits; + pPF->pfd.cGreenBits = cGreenBits; + pPF->pfd.cBlueBits = cBlueBits; + pPF->pfd.cAlphaBits = cAlphaBits; + _BitsFromDepthStencilFormat(fmt[i], &pPF->pfd.cDepthBits, &pPF->pfd.cStencilBits); + pPF->dwDriverData = fmt[i]; + } + + // Popup warning message if non RGB color mode + { + // This is a hack. KeithH + HDC hdcDesktop = GetDC(NULL); + DWORD dwDisplayBitDepth = GetDeviceCaps(hdcDesktop, BITSPIXEL); + ReleaseDC(0, hdcDesktop); + if (dwDisplayBitDepth <= 8) { + ddlogPrintf(DDLOG_WARN, "Current Color Depth %d bpp is not supported", dwDisplayBitDepth); + MessageBox(NULL, szColorDepthWarning, "GLDirect", MB_OK | MB_ICONWARNING); + } + } + + // Mark list as 'current' + glb.bPixelformatsDirty = FALSE; + + return TRUE; +} + +//--------------------------------------------------------------------------- + +BOOL gldInitialiseMesa_DX( + DGL_ctx *lpCtx) +{ + GLD_driver_dx9 *gld = NULL; + int MaxTextureSize, TextureLevels; + BOOL bSoftwareTnL; + + if (lpCtx == NULL) + return FALSE; + + gld = lpCtx->glPriv; + if (gld == NULL) + return FALSE; + + if (glb.bMultitexture) { + lpCtx->glCtx->Const.MaxTextureUnits = gld->d3dCaps9.MaxSimultaneousTextures; + // Only support MAX_TEXTURE_UNITS texture units. + // ** If this is altered then the FVF formats must be reviewed **. + if (lpCtx->glCtx->Const.MaxTextureUnits > GLD_MAX_TEXTURE_UNITS_DX9) + lpCtx->glCtx->Const.MaxTextureUnits = GLD_MAX_TEXTURE_UNITS_DX9; + } else { + // Multitexture override + lpCtx->glCtx->Const.MaxTextureUnits = 1; + } + + // max texture size + MaxTextureSize = min(gld->d3dCaps9.MaxTextureHeight, gld->d3dCaps9.MaxTextureWidth); + if (MaxTextureSize == 0) + MaxTextureSize = 256; // Sanity check + + // + // HACK!! + if (MaxTextureSize > 1024) + MaxTextureSize = 1024; // HACK - CLAMP TO 1024 + // HACK!! + // + + // Got to set MAX_TEXTURE_SIZE as max levels. + // Who thought this stupid idea up? ;) + TextureLevels = 0; + // Calculate power-of-two. + while (MaxTextureSize) { + TextureLevels++; + MaxTextureSize >>= 1; + } + lpCtx->glCtx->Const.MaxTextureLevels = (TextureLevels) ? TextureLevels : 8; + lpCtx->glCtx->Const.MaxDrawBuffers = 1; + + IDirect3DDevice9_SetRenderState(gld->pDev, D3DRS_LIGHTING, FALSE); + IDirect3DDevice9_SetRenderState(gld->pDev, D3DRS_CULLMODE, D3DCULL_NONE); + IDirect3DDevice9_SetRenderState(gld->pDev, D3DRS_DITHERENABLE, TRUE); + IDirect3DDevice9_SetRenderState(gld->pDev, D3DRS_SHADEMODE, D3DSHADE_GOURAUD); + + IDirect3DDevice9_SetRenderState(gld->pDev, D3DRS_ZENABLE, + (lpCtx->lpPF->dwDriverData!=D3DFMT_UNKNOWN) ? D3DZB_TRUE : D3DZB_FALSE); + + // Set the view matrix + { + D3DXMATRIX vm; +#if 1 + D3DXMatrixIdentity(&vm); +#else + D3DXVECTOR3 Eye(0.0f, 0.0f, 0.0f); + D3DXVECTOR3 At(0.0f, 0.0f, -1.0f); + D3DXVECTOR3 Up(0.0f, 1.0f, 0.0f); + D3DXMatrixLookAtRH(&vm, &Eye, &At, &Up); + vm._31 = -vm._31; + vm._32 = -vm._32; + vm._33 = -vm._33; + vm._34 = -vm._34; +#endif + IDirect3DDevice9_SetTransform(gld->pDev, D3DTS_VIEW, &vm); + } + + if (gld->bHasHWTnL) { + if (glb.dwTnL == GLDS_TNL_DEFAULT) + bSoftwareTnL = FALSE; // HW TnL + else { + bSoftwareTnL = ((glb.dwTnL == GLDS_TNL_MESA) || (glb.dwTnL == GLDS_TNL_D3DSW)) ? TRUE : FALSE; + } + } else { + // No HW TnL, so no choice possible + bSoftwareTnL = TRUE; + } +// IDirect3DDevice9_SetRenderState(gld->pDev, D3DRS_SOFTWAREVERTEXPROCESSING, bSoftwareTnL); + IDirect3DDevice9_SetSoftwareVertexProcessing(gld->pDev, bSoftwareTnL); + +// Dump this in a Release build as well, now. +//#ifdef _DEBUG + ddlogPrintf(DDLOG_INFO, "HW TnL: %s", + gld->bHasHWTnL ? (bSoftwareTnL ? "Disabled" : "Enabled") : "Unavailable"); +//#endif + + gldEnableExtensions_DX9(lpCtx->glCtx); + gldInstallPipeline_DX9(lpCtx->glCtx); + gldSetupDriverPointers_DX9(lpCtx->glCtx); + + // Signal a complete state update + lpCtx->glCtx->Driver.UpdateState(lpCtx->glCtx, _NEW_ALL); + + // Start a scene + IDirect3DDevice9_BeginScene(gld->pDev); + lpCtx->bSceneStarted = TRUE; + + return TRUE; +} + +//--------------------------------------------------------------------------- + +BOOL gldSwapBuffers_DX( + DGL_ctx *ctx, + HDC hDC, + HWND hWnd) +{ + HRESULT hr; + GLD_driver_dx9 *gld = NULL; + + if (ctx == NULL) + return FALSE; + + gld = ctx->glPriv; + if (gld == NULL) + return FALSE; + + if (ctx->bSceneStarted) { + IDirect3DDevice9_EndScene(gld->pDev); + ctx->bSceneStarted = FALSE; + } + + // Swap the buffers. hWnd may override the hWnd used for CreateDevice() + hr = IDirect3DDevice9_Present(gld->pDev, NULL, NULL, hWnd, NULL); + +exit_swap: + + IDirect3DDevice9_BeginScene(gld->pDev); + ctx->bSceneStarted = TRUE; + +// Debugging code +#ifdef _DEBUG +// ddlogMessage(GLDLOG_WARN, "SwapBuffers\n"); +#endif + + return (FAILED(hr)) ? FALSE : TRUE; +} + +//--------------------------------------------------------------------------- + +BOOL gldGetDisplayMode_DX( + DGL_ctx *ctx, + GLD_displayMode *glddm) +{ + D3DDISPLAYMODE d3ddm; + HRESULT hr; + GLD_driver_dx9 *lpCtx = NULL; + BYTE cColorBits, cRedBits, cGreenBits, cBlueBits, cAlphaBits; + + if ((glddm == NULL) || (ctx == NULL)) + return FALSE; + + lpCtx = ctx->glPriv; + if (lpCtx == NULL) + return FALSE; + + if (lpCtx->pD3D == NULL) + return FALSE; + + hr = IDirect3D9_GetAdapterDisplayMode(lpCtx->pD3D, glb.dwAdapter, &d3ddm); + if (FAILED(hr)) + return FALSE; + + // Get info from the display format + _BitsFromDisplayFormat(d3ddm.Format, + &cColorBits, &cRedBits, &cGreenBits, &cBlueBits, &cAlphaBits); + + glddm->Width = d3ddm.Width; + glddm->Height = d3ddm.Height; + glddm->BPP = cColorBits; + glddm->Refresh = d3ddm.RefreshRate; + + return TRUE; +} + +//--------------------------------------------------------------------------- + diff --git a/mesalib/src/mesa/drivers/windows/gldirect/gldirect.rc b/mesalib/src/mesa/drivers/windows/gldirect/gldirect.rc new file mode 100644 index 000000000..ba0963153 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/gldirect.rc @@ -0,0 +1,43 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: Windows Resource Compiler +* Environment: Windows 95 +* +****************************************************************************/ + +#ifndef WORKSHOP_INVOKED + #include +#endif + +#define FILE_DESCRIPTION "SciTech GLDirect" +#define ORIG_FILENAME "opengl32.dll" +#define FILE_TYPE VFT_DLL + +#include "gldirect/gldver.ver" diff --git a/mesalib/src/mesa/drivers/windows/gldirect/mesasw/colors.h b/mesalib/src/mesa/drivers/windows/gldirect/mesasw/colors.h new file mode 100644 index 000000000..9c1f2a054 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/mesasw/colors.h @@ -0,0 +1,520 @@ +/* File name : colors.h + * Version : 2.3 + * + * Header file for display driver for Mesa 2.3 under + * Windows95 and WindowsNT + * This file defines macros and global variables needed + * for converting color format + * + * Copyright (C) 1996- Li Wei + * Address : Institute of Artificial Intelligence + * : & Robotics + * : Xi'an Jiaotong University + * Email : liwei@aiar.xjtu.edu.cn + * Web page : http://sun.aiar.xjtu.edu.cn + * + * This file and its associations are partially based on the + * Windows NT driver for Mesa, written by Mark Leaming + * (mark@rsinc.com). + */ + +/* + * Macros for pixel format defined + */ + +/* + * Revision 1.1 2004/04/20 11:13:11 alanh + * add SciTech's GLDirect driver for Windows. + * + * This code is donated to Mesa which allows the usage of + * a Direct3D layer (DX7, DX8, DX9 or complete software fallback). + * + * No build system exists for this code yet, that will come..... + * + * Revision 1.1.1.1 1999/08/19 00:55:42 jtg + * Imported sources + * + * Revision 1.2 1999/01/03 03:08:57 brianp + * Ted Jump's changes + * + * Revision 1.1 1999/01/03 03:08:12 brianp + * Initial revision + * + * Revision 2.0.2 1997/4/30 15:58:00 CST by Li Wei(liwei@aiar.xjtu.edu.cn) + * Add LUTs need for dithering + */ + +/* + * Revision 1.1 2004/04/20 11:13:11 alanh + * add SciTech's GLDirect driver for Windows. + * + * This code is donated to Mesa which allows the usage of + * a Direct3D layer (DX7, DX8, DX9 or complete software fallback). + * + * No build system exists for this code yet, that will come..... + * + * Revision 1.1.1.1 1999/08/19 00:55:42 jtg + * Imported sources + * + * Revision 1.2 1999/01/03 03:08:57 brianp + * Ted Jump's changes + * + * Revision 1.1 1999/01/03 03:08:12 brianp + * Initial revision + * + * Revision 2.0.1 1997/4/29 15:52:00 CST by Li Wei(liwei@aiar.xjtu.edu.cn) + * Add BGR8 Macro + */ + +/* + * Revision 1.1 2004/04/20 11:13:11 alanh + * add SciTech's GLDirect driver for Windows. + * + * This code is donated to Mesa which allows the usage of + * a Direct3D layer (DX7, DX8, DX9 or complete software fallback). + * + * No build system exists for this code yet, that will come..... + * + * Revision 1.1.1.1 1999/08/19 00:55:42 jtg + * Imported sources + * + * Revision 1.2 1999/01/03 03:08:57 brianp + * Ted Jump's changes + * + * Revision 1.1 1999/01/03 03:08:12 brianp + * Initial revision + * + * Revision 2.0 1996/11/15 10:55:00 CST by Li Wei(liwei@aiar.xjtu.edu.cn) + * Initial revision + */ +/* Values for wmesa->pixelformat: */ + +#define PF_8A8B8G8R 3 /* 32-bit TrueColor: 8-A, 8-B, 8-G, 8-R */ +#define PF_8R8G8B 4 /* 32-bit TrueColor: 8-R, 8-G, 8-B */ +#define PF_5R6G5B 5 /* 16-bit TrueColor: 5-R, 6-G, 5-B bits */ +#define PF_DITHER8 6 /* Dithered RGB using a lookup table */ +#define PF_LOOKUP 7 /* Undithered RGB using a lookup table */ +#define PF_GRAYSCALE 10 /* Grayscale or StaticGray */ +#define PF_BADFORMAT 11 +#define PF_INDEX8 12 + +char ColorMap16[] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, +0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02, +0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03, +0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, +0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05, +0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06, +0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, +0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08, +0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09, +0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A, +0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B, +0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C, +0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D, +0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E, +0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F, +0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, +0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, +0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, +0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13, +0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14, +0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15, +0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16, +0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17, +0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19, +0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A, +0x1B,0x1B,0x1B,0x1B,0x1B,0x1B,0x1B,0x1B, +0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C, +0x1D,0x1D,0x1D,0x1D,0x1D,0x1D,0x1D,0x1D, +0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E, +0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F}; + +#define BGR8(r,g,b) (unsigned)(((BYTE)(b & 0xc0 | (g & 0xe0)>>2 | (r & 0xe0)>>5))) +#ifdef DDRAW +#define BGR16(r,g,b) ((WORD)(((BYTE)(ColorMap16[b]) | ((BYTE)(g&0xfc) << 3)) | (((WORD)(BYTE)(ColorMap16[r])) << 11))) +#else +#define BGR16(r,g,b) ((WORD)(((BYTE)(ColorMap16[b]) | ((BYTE)(ColorMap16[g]) << 5)) | (((WORD)(BYTE)(ColorMap16[r])) << 10))) +#endif +#define BGR24(r,g,b) (unsigned long)(((DWORD)(((BYTE)(b)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(r))<<16))) << 8) +#define BGR32(r,g,b) (unsigned long)((DWORD)(((BYTE)(b)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(r))<<16))) + + + +/* + * If pixelformat==PF_8A8B8G8R: + */ +#define PACK_8A8B8G8R( R, G, B, A ) \ + ( ((A) << 24) | ((B) << 16) | ((G) << 8) | (R) ) + + +/* + * If pixelformat==PF_8R8G8B: + */ +#define PACK_8R8G8B( R, G, B) ( ((R) << 16) | ((G) << 8) | (B) ) + + +/* + * If pixelformat==PF_5R6G5B: + */ + + +#ifdef DDRAW +#define PACK_5R6G5B( R, G, B) ((WORD)(((BYTE)(ColorMap16[B]) | ((BYTE)(G&0xfc) << 3)) | (((WORD)(BYTE)(ColorMap16[R])) << 11))) +#else +#define PACK_5R6G5B( R, G, B) ((WORD)(((BYTE)(ColorMap16[B]) | ((BYTE)(ColorMap16[G]) << 5)) | (((WORD)(BYTE)(ColorMap16[R])) << 10))) +#endif +/*---------------------------------------------------------------------------- + +Division lookup tables. These tables compute 0-255 divided by 51 and +modulo 51. These tables could approximate gamma correction. + +*/ + +char unsigned const aDividedBy51Rounded[256] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, +}; + +char unsigned const aDividedBy51[256] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, +}; + +char unsigned const aModulo51[256] = +{ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 0, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 0, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 0, +}; + +/*---------------------------------------------------------------------------- + +Multiplication LUTs. These compute 0-5 times 6 and 36. + +*/ + +char unsigned const aTimes6[6] = +{ + 0, 6, 12, 18, 24, 30 +}; + +char unsigned const aTimes36[6] = +{ + 0, 36, 72, 108, 144, 180 +}; + + +/*---------------------------------------------------------------------------- + +Dither matrices for 8 bit to 2.6 bit halftones. + +*/ + +char unsigned const aHalftone16x16[256] = +{ + 0, 44, 9, 41, 3, 46, 12, 43, 1, 44, 10, 41, 3, 46, 12, 43, + 34, 16, 25, 19, 37, 18, 28, 21, 35, 16, 26, 19, 37, 18, 28, 21, + 38, 6, 47, 3, 40, 9, 50, 6, 38, 7, 47, 4, 40, 9, 49, 6, + 22, 28, 13, 31, 25, 31, 15, 34, 22, 29, 13, 32, 24, 31, 15, 34, + 2, 46, 12, 43, 1, 45, 10, 42, 2, 45, 11, 42, 1, 45, 11, 42, + 37, 18, 27, 21, 35, 17, 26, 20, 36, 17, 27, 20, 36, 17, 26, 20, + 40, 8, 49, 5, 38, 7, 48, 4, 39, 8, 48, 5, 39, 7, 48, 4, + 24, 30, 15, 33, 23, 29, 13, 32, 23, 30, 14, 33, 23, 29, 14, 32, + 2, 46, 12, 43, 0, 44, 10, 41, 3, 47, 12, 44, 0, 44, 10, 41, + 37, 18, 27, 21, 35, 16, 25, 19, 37, 19, 28, 22, 35, 16, 25, 19, + 40, 9, 49, 5, 38, 7, 47, 4, 40, 9, 50, 6, 38, 6, 47, 3, + 24, 30, 15, 34, 22, 29, 13, 32, 25, 31, 15, 34, 22, 28, 13, 31, + 1, 45, 11, 42, 2, 46, 11, 42, 1, 45, 10, 41, 2, 46, 11, 43, + 36, 17, 26, 20, 36, 17, 27, 21, 35, 16, 26, 20, 36, 18, 27, 21, + 39, 8, 48, 4, 39, 8, 49, 5, 38, 7, 48, 4, 39, 8, 49, 5, + 23, 29, 14, 33, 24, 30, 14, 33, 23, 29, 13, 32, 24, 30, 14, 33, +}; + +char unsigned const aHalftone8x8[64] = +{ + 0, 38, 9, 47, 2, 40, 11, 50, + 25, 12, 35, 22, 27, 15, 37, 24, + 6, 44, 3, 41, 8, 47, 5, 43, + 31, 19, 28, 15, 34, 21, 31, 18, + 1, 39, 11, 49, 0, 39, 10, 48, + 27, 14, 36, 23, 26, 13, 35, 23, + 7, 46, 4, 43, 7, 45, 3, 42, + 33, 20, 30, 17, 32, 19, 29, 16, +}; + +char unsigned const aHalftone4x4_1[16] = +{ + 0, 25, 6, 31, + 38, 12, 44, 19, + 9, 35, 3, 28, + 47, 22, 41, 15 +}; + +char unsigned const aHalftone4x4_2[16] = +{ + 41, 3, 9, 28, + 35, 15, 22, 47, + 6, 25, 38, 0, + 19, 44, 31, 12 +}; + +/*************************************************************************** + aWinGHalftoneTranslation + + Translates a 2.6 bit-per-pixel halftoned representation into the + slightly rearranged WinG Halftone Palette. +*/ + +char unsigned const aWinGHalftoneTranslation[216] = +{ + 0, + 29, + 30, + 31, + 32, + 249, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 250, + 250, + 57, + 58, + 59, + 251, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 250, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 227, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 151, + 120, + 121, + 122, + 123, + 124, + 228, + 125, + 126, + 229, + 133, + 162, + 135, + 131, + 132, + 137, + 166, + 134, + 140, + 130, + 136, + 143, + 138, + 139, + 174, + 141, + 142, + 177, + 129, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 157, + 152, + 153, + 154, + 155, + 156, + 192, + 158, + 159, + 160, + 161, + 196, + 163, + 164, + 165, + 127, + 199, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 207, + 175, + 176, + 210, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 224, + 193, + 194, + 195, + 252, + 252, + 197, + 198, + 128, + 253, + 252, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 230, + 208, + 209, + 231, + 211, + 212, + 213, + 214, + 215, + 216, + 217, + 218, + 219, + 220, + 221, + 222, + 254, + 223, + 232, + 225, + 226, + 255, +}; diff --git a/mesalib/src/mesa/drivers/windows/gldirect/mesasw/gld_wgl_mesasw.c b/mesalib/src/mesa/drivers/windows/gldirect/mesasw/gld_wgl_mesasw.c new file mode 100644 index 000000000..342a74286 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/mesasw/gld_wgl_mesasw.c @@ -0,0 +1,1720 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x/2000/XP/XBox (Win32) +* +* Description: Mesa Software WGL (WindowsGL) +* +****************************************************************************/ + +#include +#define GL_GLEXT_PROTOTYPES +#include +#include + +#include "glheader.h" +#include "colors.h" +#include "context.h" +#include "colormac.h" +#include "dd.h" +#include "depth.h" +#include "extensions.h" +#include "macros.h" +#include "matrix.h" +// #include "mem.h" +//#include "mmath.h" +#include "mtypes.h" +#include "texformat.h" +#include "texstore.h" +#include "teximage.h" +#include "vbo/vbo.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" + +#include "dglcontext.h" +#include "gld_driver.h" + +//--------------------------------------------------------------------------- +//--------------------------------------------------------------------------- + +DGL_pixelFormat pfTemplateMesaSW = +{ + { + sizeof(PIXELFORMATDESCRIPTOR), // Size of the data structure + 1, // Structure version - should be 1 + // Flags: + PFD_DRAW_TO_WINDOW | // The buffer can draw to a window or device surface. + PFD_DRAW_TO_BITMAP | // The buffer can draw to a bitmap. (DaveM) + PFD_SUPPORT_GDI | // The buffer supports GDI drawing. (DaveM) + PFD_SUPPORT_OPENGL | // The buffer supports OpenGL drawing. + PFD_DOUBLEBUFFER | // The buffer is double-buffered. + 0, // Placeholder for easy commenting of above flags + PFD_TYPE_RGBA, // Pixel type RGBA. + 32, // Total colour bitplanes (excluding alpha bitplanes) + 8, 0, // Red bits, shift + 8, 8, // Green bits, shift + 8, 16, // Blue bits, shift + 8, 24, // Alpha bits, shift (destination alpha) + 64, // Accumulator bits (total) + 16, 16, 16, 16, // Accumulator bits: Red, Green, Blue, Alpha + 16, // Depth bits + 8, // Stencil bits + 0, // Number of auxiliary buffers + 0, // Layer type + 0, // Specifies the number of overlay and underlay planes. + 0, // Layer mask + 0, // Specifies the transparent color or index of an underlay plane. + 0 // Damage mask + }, + 0, // Unused +}; + +//--------------------------------------------------------------------------- +// Extensions +//--------------------------------------------------------------------------- + +typedef struct { + PROC proc; + char *name; +} GLD_extension; + +static GLD_extension GLD_extList[] = { +#ifdef GL_EXT_polygon_offset + { (PROC)glPolygonOffsetEXT, "glPolygonOffsetEXT" }, +#endif + { (PROC)glBlendEquationEXT, "glBlendEquationEXT" }, + { (PROC)glBlendColorEXT, "glBlendColorExt" }, + { (PROC)glVertexPointerEXT, "glVertexPointerEXT" }, + { (PROC)glNormalPointerEXT, "glNormalPointerEXT" }, + { (PROC)glColorPointerEXT, "glColorPointerEXT" }, + { (PROC)glIndexPointerEXT, "glIndexPointerEXT" }, + { (PROC)glTexCoordPointerEXT, "glTexCoordPointer" }, + { (PROC)glEdgeFlagPointerEXT, "glEdgeFlagPointerEXT" }, + { (PROC)glGetPointervEXT, "glGetPointervEXT" }, + { (PROC)glArrayElementEXT, "glArrayElementEXT" }, + { (PROC)glDrawArraysEXT, "glDrawArrayEXT" }, + { (PROC)glAreTexturesResidentEXT, "glAreTexturesResidentEXT" }, + { (PROC)glBindTextureEXT, "glBindTextureEXT" }, + { (PROC)glDeleteTexturesEXT, "glDeleteTexturesEXT" }, + { (PROC)glGenTexturesEXT, "glGenTexturesEXT" }, + { (PROC)glIsTextureEXT, "glIsTextureEXT" }, + { (PROC)glPrioritizeTexturesEXT, "glPrioritizeTexturesEXT" }, + { (PROC)glCopyTexSubImage3DEXT, "glCopyTexSubImage3DEXT" }, + { (PROC)glTexImage3DEXT, "glTexImage3DEXT" }, + { (PROC)glTexSubImage3DEXT, "glTexSubImage3DEXT" }, + { (PROC)glPointParameterfEXT, "glPointParameterfEXT" }, + { (PROC)glPointParameterfvEXT, "glPointParameterfvEXT" }, + { (PROC)glLockArraysEXT, "glLockArraysEXT" }, + { (PROC)glUnlockArraysEXT, "glUnlockArraysEXT" }, + { NULL, "\0" } +}; + +//--------------------------------------------------------------------------- +// WMesa Internal Functions +//--------------------------------------------------------------------------- + +#define PAGE_FILE 0xffffffff + +#define REDBITS 0x03 +#define REDSHIFT 0x00 +#define GREENBITS 0x03 +#define GREENSHIFT 0x03 +#define BLUEBITS 0x02 +#define BLUESHIFT 0x06 + +typedef struct _dibSection { + HDC hDC; + HANDLE hFileMap; + BOOL fFlushed; + LPVOID base; +} WMDIBSECTION, *PWMDIBSECTION; + +typedef struct wmesa_context { + HWND Window; + HDC hDC; + HPALETTE hPalette; + HPALETTE hOldPalette; + HPEN hPen; + HPEN hOldPen; + HCURSOR hOldCursor; + COLORREF crColor; + // 3D projection stuff + RECT drawRect; + UINT uiDIBoffset; + // OpenGL stuff + HPALETTE hGLPalette; + GLuint width; + GLuint height; + GLuint ScanWidth; + GLboolean db_flag; //* double buffered? + GLboolean rgb_flag; //* RGB mode? + GLboolean dither_flag; //* use dither when 256 color mode for RGB? + GLuint depth; //* bits per pixel (1, 8, 24, etc) + ULONG pixel; // current color index or RGBA pixel value + ULONG clearpixel; //* pixel for clearing the color buffers + PBYTE ScreenMem; // WinG memory + BITMAPINFO *IndexFormat; + HPALETTE hPal; // Current Palette + HPALETTE hPalHalfTone; + + + WMDIBSECTION dib; + BITMAPINFO bmi; + HBITMAP hbmDIB; + HBITMAP hOldBitmap; + HBITMAP Old_Compat_BM; + HBITMAP Compat_BM; // Bitmap for double buffering + PBYTE pbPixels; + int nColors; + BYTE cColorBits; + int pixelformat; + + RECT rectOffScreen; + RECT rectSurface; +// HWND hwnd; + DWORD pitch; + PBYTE addrOffScreen; + + // We always double-buffer, for performance reasons, but + // we need to know which of SwapBuffers() or glFlush() to + // handle. If we're emulating, then we update on Flush(), + // otherwise we update on SwapBufers(). KeithH + BOOL bEmulateSingleBuffer; +} WMesaContext, *PWMC; + +#define GLD_GET_WMESA_DRIVER(c) (WMesaContext*)(c)->glPriv + +// TODO: +GLint stereo_flag = 0 ; + +/* If we are double-buffering, we want to get the DC for the + * off-screen DIB, otherwise the DC for the window. + */ +#define DD_GETDC ((Current->db_flag) ? Current->dib.hDC : Current->hDC ) +#define DD_RELEASEDC + +#define FLIP(Y) (Current->height-(Y)-1) + +struct DISPLAY_OPTIONS { + int stereo; + int fullScreen; + int mode; + int bpp; +}; + +struct DISPLAY_OPTIONS displayOptions; + +//--------------------------------------------------------------------------- + +static unsigned char threeto8[8] = { + 0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377 +}; + +static unsigned char twoto8[4] = { + 0, 0x55, 0xaa, 0xff +}; + +static unsigned char oneto8[2] = { + 0, 255 +}; + +//--------------------------------------------------------------------------- + +BYTE DITHER_RGB_2_8BIT( int red, int green, int blue, int pixel, int scanline) +{ + char unsigned redtemp, greentemp, bluetemp, paletteindex; + + //*** now, look up each value in the halftone matrix + //*** using an 8x8 ordered dither. + redtemp = aDividedBy51[red] + + (aModulo51[red] > aHalftone8x8[(pixel%8)*8 + + scanline%8]); + greentemp = aDividedBy51[(char unsigned)green] + + (aModulo51[green] > aHalftone8x8[ + (pixel%8)*8 + scanline%8]); + bluetemp = aDividedBy51[(char unsigned)blue] + + (aModulo51[blue] > aHalftone8x8[ + (pixel%8)*8 +scanline%8]); + + //*** recombine the halftoned rgb values into a palette index + paletteindex = + redtemp + aTimes6[greentemp] + aTimes36[bluetemp]; + + //*** and translate through the wing halftone palette + //*** translation vector to give the correct value. + return aWinGHalftoneTranslation[paletteindex]; +} + +//--------------------------------------------------------------------------- + +static unsigned char componentFromIndex(UCHAR i, UINT nbits, UINT shift) +{ + unsigned char val; + + val = i >> shift; + switch (nbits) { + + case 1: + val &= 0x1; + return oneto8[val]; + + case 2: + val &= 0x3; + return twoto8[val]; + + case 3: + val &= 0x7; + return threeto8[val]; + + default: + return 0; + } +} + +//--------------------------------------------------------------------------- + + +void wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b) +{ + WMesaContext *Current = pwc; + + // Test for invalid scanline parameter. KeithH + if ((iScanLine < 0) || (iScanLine >= pwc->height)) + return; + + if (Current->db_flag) { + LPBYTE lpb = pwc->pbPixels; + UINT nBypp = pwc->cColorBits >> 3; + UINT nOffset = iPixel % nBypp; + + lpb += pwc->ScanWidth * iScanLine; + lpb += iPixel * nBypp; + + if(nBypp == 1){ + if(pwc->dither_flag) + *lpb = DITHER_RGB_2_8BIT(r,g,b,iScanLine,iPixel); + else + *lpb = BGR8(r,g,b); + } + else if(nBypp == 2) + *((LPWORD)lpb) = BGR16(r,g,b); + else if (nBypp == 3) + *((LPDWORD)lpb) = BGR24(r,g,b); + else if (nBypp == 4) + *((LPDWORD)lpb) = BGR32(r,g,b); + } + else{ + SetPixel(Current->hDC, iPixel, iScanLine, RGB(r,g,b)); + } +} + +//--------------------------------------------------------------------------- + +void wmCreateDIBSection( + HDC hDC, + PWMC pwc, // handle of device context + CONST BITMAPINFO *pbmi, // bitmap size, format, and color data + UINT iUsage // color data type indicator: RGB values or palette indices + ) +{ + DWORD dwSize = 0; + DWORD dwScanWidth; + UINT nBypp = pwc->cColorBits / 8; + HDC hic; + + dwScanWidth = (((pwc->ScanWidth * nBypp)+ 3) & ~3); + + pwc->ScanWidth =pwc->pitch = dwScanWidth; + + if (stereo_flag) + pwc->ScanWidth = 2* pwc->pitch; + + dwSize = sizeof(BITMAPINFO) + (dwScanWidth * pwc->height); + + pwc->dib.hFileMap = CreateFileMapping((HANDLE)PAGE_FILE, + NULL, + PAGE_READWRITE | SEC_COMMIT, + 0, + dwSize, + NULL); + + if (!pwc->dib.hFileMap) + return; + + pwc->dib.base = MapViewOfFile(pwc->dib.hFileMap, + FILE_MAP_ALL_ACCESS, + 0, + 0, + 0); + + if(!pwc->dib.base){ + CloseHandle(pwc->dib.hFileMap); + return; + } + + + CopyMemory(pwc->dib.base, pbmi, sizeof(BITMAPINFO)); + + hic = CreateIC("display", NULL, NULL, NULL); + pwc->dib.hDC = CreateCompatibleDC(hic); + + + pwc->hbmDIB = CreateDIBSection(hic, + &(pwc->bmi), + (iUsage ? DIB_PAL_COLORS : DIB_RGB_COLORS), + &(pwc->pbPixels), + pwc->dib.hFileMap, + 0); + pwc->ScreenMem = pwc->addrOffScreen = pwc->pbPixels; + pwc->hOldBitmap = SelectObject(pwc->dib.hDC, pwc->hbmDIB); + + DeleteDC(hic); + + return; + +} + +//--------------------------------------------------------------------------- + +void wmCreatePalette( PWMC pwdc ) +{ + /* Create a compressed and re-expanded 3:3:2 palette */ + int i; + LOGPALETTE *pPal; + BYTE rb, rs, gb, gs, bb, bs; + + pwdc->nColors = 0x100; + + pPal = (PLOGPALETTE)malloc(sizeof(LOGPALETTE) + + pwdc->nColors * sizeof(PALETTEENTRY)); + memset( pPal, 0, sizeof(LOGPALETTE) + pwdc->nColors * sizeof(PALETTEENTRY) ); + + pPal->palVersion = 0x300; + + rb = REDBITS; + rs = REDSHIFT; + gb = GREENBITS; + gs = GREENSHIFT; + bb = BLUEBITS; + bs = BLUESHIFT; + + if (pwdc->db_flag) { + + /* Need to make two palettes: one for the screen DC and one for the DIB. */ + pPal->palNumEntries = pwdc->nColors; + for (i = 0; i < pwdc->nColors; i++) { + pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs ); + pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs ); + pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs ); + pPal->palPalEntry[i].peFlags = 0; + } + pwdc->hGLPalette = CreatePalette( pPal ); + pwdc->hPalette = CreatePalette( pPal ); + } + + else { + pPal->palNumEntries = pwdc->nColors; + for (i = 0; i < pwdc->nColors; i++) { + pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs ); + pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs ); + pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs ); + pPal->palPalEntry[i].peFlags = 0; + } + pwdc->hGLPalette = CreatePalette( pPal ); + } + + free(pPal); + +} + +//--------------------------------------------------------------------------- + +/* This function sets the color table of a DIB section + * to match that of the destination DC + */ +BOOL wmSetDibColors(PWMC pwc) +{ + RGBQUAD *pColTab, *pRGB; + PALETTEENTRY *pPal, *pPE; + int i, nColors; + BOOL bRet=TRUE; + DWORD dwErr=0; + + /* Build a color table in the DIB that maps to the + * selected palette in the DC. + */ + nColors = 1 << pwc->cColorBits; + pPal = (PALETTEENTRY *)malloc( nColors * sizeof(PALETTEENTRY)); + memset( pPal, 0, nColors * sizeof(PALETTEENTRY) ); + GetPaletteEntries( pwc->hGLPalette, 0, nColors, pPal ); + pColTab = (RGBQUAD *)malloc( nColors * sizeof(RGBQUAD)); + for (i = 0, pRGB = pColTab, pPE = pPal; i < nColors; i++, pRGB++, pPE++) { + pRGB->rgbRed = pPE->peRed; + pRGB->rgbGreen = pPE->peGreen; + pRGB->rgbBlue = pPE->peBlue; + } + if(pwc->db_flag) + bRet = SetDIBColorTable(pwc->dib.hDC, 0, nColors, pColTab ); + + if(!bRet) + dwErr = GetLastError(); + + free( pColTab ); + free( pPal ); + + return bRet; +} + +//--------------------------------------------------------------------------- + +static void wmSetPixelFormat( PWMC wc, HDC hDC) +{ + if(wc->rgb_flag) + wc->cColorBits = GetDeviceCaps(hDC, BITSPIXEL); + else + wc->cColorBits = 8; + switch(wc->cColorBits){ + case 8: + if(wc->dither_flag != GL_TRUE) + wc->pixelformat = PF_INDEX8; + else + wc->pixelformat = PF_DITHER8; + break; + case 16: + wc->pixelformat = PF_5R6G5B; + break; + case 32: + wc->pixelformat = PF_8R8G8B; + break; + default: + wc->pixelformat = PF_BADFORMAT; + } +} + +//--------------------------------------------------------------------------- + +/* + * This function creates the DIB section that is used for combined + * GL and GDI calls + */ +BOOL wmCreateBackingStore(PWMC pwc, long lxSize, long lySize) +{ + HDC hdc = pwc->hDC; + LPBITMAPINFO pbmi = &(pwc->bmi); + int iUsage; + + pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + pbmi->bmiHeader.biWidth = lxSize; + pbmi->bmiHeader.biHeight= -lySize; + pbmi->bmiHeader.biPlanes = 1; + if(pwc->rgb_flag) + pbmi->bmiHeader.biBitCount = GetDeviceCaps(pwc->hDC, BITSPIXEL); + else + pbmi->bmiHeader.biBitCount = 8; + pbmi->bmiHeader.biCompression = BI_RGB; + pbmi->bmiHeader.biSizeImage = 0; + pbmi->bmiHeader.biXPelsPerMeter = 0; + pbmi->bmiHeader.biYPelsPerMeter = 0; + pbmi->bmiHeader.biClrUsed = 0; + pbmi->bmiHeader.biClrImportant = 0; + + iUsage = (pbmi->bmiHeader.biBitCount <= 8) ? DIB_PAL_COLORS : DIB_RGB_COLORS; + + pwc->cColorBits = pbmi->bmiHeader.biBitCount; + pwc->ScanWidth = pwc->pitch = lxSize; + pwc->width = lxSize; + pwc->height = lySize; + + wmCreateDIBSection(hdc, pwc, pbmi, iUsage); + + if ((iUsage == DIB_PAL_COLORS) && !(pwc->hGLPalette)) { + wmCreatePalette( pwc ); + wmSetDibColors( pwc ); + } + wmSetPixelFormat(pwc, pwc->hDC); + return TRUE; +} + +//--------------------------------------------------------------------------- + +/* + * Free up the dib section that was created + */ +BOOL wmDeleteBackingStore(PWMC pwc) +{ + SelectObject(pwc->dib.hDC, pwc->hOldBitmap); + DeleteDC(pwc->dib.hDC); + DeleteObject(pwc->hbmDIB); + UnmapViewOfFile(pwc->dib.base); + CloseHandle(pwc->dib.hFileMap); + return TRUE; +} + +//--------------------------------------------------------------------------- + +/* + * Blit memory DC to screen DC + */ +BOOL wmFlush(PWMC pwc, HDC hDC) +{ + BOOL bRet = 0; + DWORD dwErr = 0; + +// Now using bEmulateSingleBuffer in the calling function. KeithH + +// if(pwc->db_flag){ + bRet = BitBlt(hDC, 0, 0, pwc->width, pwc->height, + pwc->dib.hDC, 0, 0, SRCCOPY); +// } + + return bRet; + +} + +//--------------------------------------------------------------------------- +// Support Functions +//--------------------------------------------------------------------------- + +static void flush(GLcontext* ctx) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx); +/* + if((Current->rgb_flag &&!(Current->db_flag)) + ||(!Current->rgb_flag)) + { + wmFlush(Current, Current->hDC); + } +*/ + // Only flush if we're not in double-buffer mode. KeithH + // The demo fractal.c calls glutSwapBuffers() then glFlush()! + if (Current->bEmulateSingleBuffer) { + wmFlush(Current, Current->hDC); + } +} + + +//--------------------------------------------------------------------------- + + +/* + * Set the color index used to clear the color buffer. + */ +static void clear_index(GLcontext* ctx, GLuint index) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx); + Current->clearpixel = index; +} + + + +//--------------------------------------------------------------------------- + +/* + * Set the color used to clear the color buffer. + */ +//static void clear_color( GLcontext* ctx, const GLchan color[4] ) +// Changed for Mesa 5.x. KeithH +static void clear_color( + GLcontext* ctx, + const GLfloat color[4]) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx); + 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]); + Current->clearpixel = RGB(col[0], col[1], col[2]); +} + + +//--------------------------------------------------------------------------- + + +/* + * Clear the specified region of the color buffer using the clear color + * or index as specified by one of the two functions above. + * + * This procedure clears either the front and/or the back COLOR buffers. + * Only the "left" buffer is cleared since we are not stereo. + * Clearing of the other non-color buffers is left to the swrast. + * We also only clear the color buffers if the color masks are all 1's. + * Otherwise, we let swrast do it. + */ + +static clear(GLcontext* ctx, GLbitfield mask, + GLboolean all, GLint x, GLint y, GLint width, GLint height) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx); + DWORD dwColor; + WORD wColor; + BYTE bColor; + LPDWORD lpdw = (LPDWORD)Current->pbPixels; + LPWORD lpw = (LPWORD)Current->pbPixels; + LPBYTE lpb = Current->pbPixels; + int lines; + const GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask; + + if (all){ + x=y=0; + width=Current->width; + height=Current->height; + } + + + /* sanity check - can't have right(stereo) buffers */ + assert((mask & (DD_FRONT_RIGHT_BIT | DD_BACK_RIGHT_BIT)) == 0); + + /* clear alpha */ + if ((mask & (DD_FRONT_LEFT_BIT | DD_BACK_RIGHT_BIT)) && + ctx->DrawBuffer->UseSoftwareAlphaBuffers && + ctx->Color.ColorMask[ACOMP]) { + _swrast_clear_alpha_buffers( ctx ); + } + + if (*colorMask == 0xffffffff && ctx->Color.IndexMask == 0xffffffff) { + if (mask & DD_BACK_LEFT_BIT) { + /* Double-buffering - clear back buffer */ + UINT nBypp = Current->cColorBits / 8; + int i = 0; + int iSize = 0; + + assert(Current->db_flag==GL_TRUE); /* we'd better be double buffer */ + if(nBypp ==1 ){ + iSize = Current->width/4; + bColor = BGR8(GetRValue(Current->clearpixel), + GetGValue(Current->clearpixel), + GetBValue(Current->clearpixel)); + wColor = MAKEWORD(bColor,bColor); + dwColor = MAKELONG(wColor, wColor); + } + if(nBypp == 2){ + iSize = Current->width / 2; + wColor = BGR16(GetRValue(Current->clearpixel), + GetGValue(Current->clearpixel), + GetBValue(Current->clearpixel)); + dwColor = MAKELONG(wColor, wColor); + } + else if(nBypp == 4){ + iSize = Current->width; + dwColor = BGR32(GetRValue(Current->clearpixel), + GetGValue(Current->clearpixel), + GetBValue(Current->clearpixel)); + } + + /* clear a line */ + while(i < iSize){ + *lpdw = dwColor; + lpdw++; + i++; + } + + /* This is the 24bit case */ + if (nBypp == 3) { + iSize = Current->width *3/4; + dwColor = BGR24(GetRValue(Current->clearpixel), + GetGValue(Current->clearpixel), + GetBValue(Current->clearpixel)); + while(i < iSize){ + *lpdw = dwColor; + lpb += nBypp; + lpdw = (LPDWORD)lpb; + i++; + } + } + + i = 0; + if (stereo_flag) + lines = height /2; + else + lines = height; + /* copy cleared line to other lines in buffer */ + do { + memcpy(lpb, Current->pbPixels, iSize*4); + lpb += Current->ScanWidth; + i++; + } + while (iclearpixel); + HBRUSH Brush=CreateSolidBrush(Current->clearpixel); + HPEN Old_Pen=SelectObject(DC,Pen); + HBRUSH Old_Brush=SelectObject(DC,Brush); + Rectangle(DC,x,y,x+width,y+height); + SelectObject(DC,Old_Pen); + SelectObject(DC,Old_Brush); + DeleteObject(Pen); + DeleteObject(Brush); + DD_RELEASEDC; + mask &= ~DD_FRONT_LEFT_BIT; + } /* single-buffer */ + } /* if masks are all 1's */ + + /* Call swrast if there is anything left to clear (like DEPTH) */ + if (mask) + _swrast_Clear( ctx, mask, all, x, y, width, height ); +} + + +//--------------------------------------------------------------------------- + + +static void enable( GLcontext* ctx, GLenum pname, GLboolean enable ) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx); + + if (!Current) + return; + + if (pname == GL_DITHER) { + if(enable == GL_FALSE){ + Current->dither_flag = GL_FALSE; + if(Current->cColorBits == 8) + Current->pixelformat = PF_INDEX8; + } + else{ + if (Current->rgb_flag && Current->cColorBits == 8){ + Current->pixelformat = PF_DITHER8; + Current->dither_flag = GL_TRUE; + } + else + Current->dither_flag = GL_FALSE; + } + } +} + +//--------------------------------------------------------------------------- + +static GLboolean set_draw_buffer( GLcontext* ctx, GLenum mode ) +{ + /* TODO: this could be better */ + if (mode==GL_FRONT_LEFT || mode==GL_BACK_LEFT) { + return GL_TRUE; + } + else { + return GL_FALSE; + } +} + +//--------------------------------------------------------------------------- + + +static void set_read_buffer(GLcontext *ctx, GLframebuffer *colorBuffer, + GLenum buffer ) +{ + /* XXX todo */ + return; +} + + +//--------------------------------------------------------------------------- + + +/* Return characteristics of the output buffer. */ +//static void buffer_size( GLcontext* ctx, GLuint *width, GLuint *height ) +// Altered for Mesa 5.x. KeithH +static void buffer_size( + GLframebuffer *buffer, + GLuint *width, + GLuint *height) +{ + // For some reason the context is not passed into this function. + // Therefore we have to explicitly retrieve it. + GET_CURRENT_CONTEXT(ctx); + + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx); + int New_Size; + RECT CR; + + GetClientRect(Current->Window,&CR); + + *width=CR.right; + *height=CR.bottom; + + New_Size=((*width)!=Current->width) || ((*height)!=Current->height); + + if (New_Size){ + Current->width=*width; + Current->height=*height; + Current->ScanWidth=Current->width; + if ((Current->ScanWidth%sizeof(long))!=0) + Current->ScanWidth+=(sizeof(long)-(Current->ScanWidth%sizeof(long))); + + if (Current->db_flag){ + if (Current->rgb_flag==GL_TRUE && Current->dither_flag!=GL_TRUE){ + wmDeleteBackingStore(Current); + wmCreateBackingStore(Current, Current->width, Current->height); + } + } + + } +} + + + +/**********************************************************************/ +/***** Accelerated point, line, polygon rendering *****/ +/**********************************************************************/ + +/* Accelerated routines are not implemented in 4.0. See OSMesa for ideas. */ + +static void fast_rgb_points( GLcontext* ctx, GLuint first, GLuint last ) +{ +} + +//--------------------------------------------------------------------------- + +/* Return pointer to accelerated points function */ +extern tnl_points_func choose_points_function( GLcontext* ctx ) +{ + return NULL; +} + +//--------------------------------------------------------------------------- + +static void fast_flat_rgb_line( GLcontext* ctx, GLuint v0, + GLuint v1, GLuint pv ) +{ +} + +//--------------------------------------------------------------------------- + +static tnl_line_func choose_line_function( GLcontext* ctx ) +{ +} + + +/**********************************************************************/ +/***** Span-based pixel drawing *****/ +/**********************************************************************/ + + +/* Write a horizontal span of 32-bit color-index pixels with a boolean mask. */ +static void write_ci32_span( const GLcontext* ctx, + GLuint n, GLint x, GLint y, + const GLuint index[], + const GLubyte mask[] ) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx); + GLuint i; + PBYTE Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x; + assert(Current->rgb_flag==GL_FALSE); + for (i=0; iScreenMem+FLIP(y)*Current->ScanWidth+x; + assert(Current->rgb_flag==GL_FALSE); + for (i=0; iScreenMem+FLIP(y)*Current->ScanWidth+x; + assert(Current->rgb_flag==GL_FALSE); + for (i=0; irgb_flag==GL_TRUE) + { + GLuint i; + HDC DC=DD_GETDC; + y=FLIP(y); + if (mask) { + for (i=0; iScreenMem+y*Current->ScanWidth+x; + y = FLIP(y); + if (mask) { + for (i=0; ihPal, + RGB(rgba[i][RCOMP], + rgba[i][GCOMP], + rgba[i][BCOMP])); + } + else { + for (i=0; ihPal, + RGB(rgba[i][RCOMP], + rgba[i][GCOMP], + rgba[i][BCOMP])); + } + } +} + +//--------------------------------------------------------------------------- + +/* Write a horizontal span of RGB color pixels with a boolean mask. */ +static void write_rgb_span( const GLcontext* ctx, + GLuint n, GLint x, GLint y, + const GLubyte rgb[][3], const GLubyte mask[] ) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx); + PWMC pwc = Current; + + if (pwc->rgb_flag==GL_TRUE) + { + GLuint i; + HDC DC=DD_GETDC; + y=FLIP(y); + if (mask) { + for (i=0; iScreenMem+y*Current->ScanWidth+x; + y = FLIP(y); + if (mask) { + for (i=0; ihPal, + RGB(rgb[i][RCOMP], + rgb[i][GCOMP], + rgb[i][BCOMP])); + } + else { + for (i=0; ihPal, + RGB(rgb[i][RCOMP], + rgb[i][GCOMP], + rgb[i][BCOMP])); + } + } +} + +//--------------------------------------------------------------------------- + +/* + * Write a horizontal span of pixels with a boolean mask. The current color + * is used for all pixels. + */ +static void write_mono_rgba_span( const GLcontext* ctx, + GLuint n, GLint x, GLint y, + const GLchan color[4], const GLubyte mask[]) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx); + ULONG pixel = RGB( color[RCOMP], color[GCOMP], color[BCOMP] ); + GLuint i; + HDC DC=DD_GETDC; + PWMC pwc = Current; + assert(Current->rgb_flag==GL_TRUE); + y=FLIP(y); + if(Current->rgb_flag==GL_TRUE){ + for (i=0; irgb_flag==GL_FALSE); + for (i=0; iScreenMem+FLIP(y[i])*Current->ScanWidth+x[i]; + *Mem = index[i]; + } + } +} + + +//--------------------------------------------------------------------------- + + +/* + * Write an array of pixels with a boolean mask. The current color + * index is used for all pixels. + */ +static void write_mono_ci_pixels( const GLcontext* ctx, + GLuint n, + const GLint x[], const GLint y[], + GLuint colorIndex, const GLubyte mask[] ) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx); + GLuint i; + assert(Current->rgb_flag==GL_FALSE); + for (i=0; iScreenMem+FLIP(y[i])*Current->ScanWidth+x[i]; + *Mem = colorIndex; + } + } +} + + +//--------------------------------------------------------------------------- + + +/* Write an array of RGBA pixels with a boolean mask. */ +static void write_rgba_pixels( const GLcontext* ctx, + GLuint n, const GLint x[], const GLint y[], + const GLubyte rgba[][4], const GLubyte mask[] ) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx); + GLuint i; + PWMC pwc = Current; + HDC DC=DD_GETDC; + assert(Current->rgb_flag==GL_TRUE); + for (i=0; irgb_flag==GL_TRUE); + for (i=0; iScreenMem+FLIP(y)*Current->ScanWidth+x; + assert(Current->rgb_flag==GL_FALSE); + for (i=0; irgb_flag==GL_FALSE); + for (i=0; iScreenMem+FLIP(y[i])*Current->ScanWidth+x[i]); + } + } +} + +//--------------------------------------------------------------------------- + +/* Read a horizontal span of color pixels. */ +static void read_rgba_span( const GLcontext* ctx, + GLuint n, GLint x, GLint y, + GLubyte rgba[][4] ) +{ + GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); + WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx); + UINT i; + COLORREF Color; + HDC DC=DD_GETDC; + assert(Current->rgb_flag==GL_TRUE); + y = Current->height - y - 1; + for (i=0; irgb_flag==GL_TRUE); + for (i=0; iheight - y[i] - 1; + Color=GetPixel(DC,x[i],y2); + rgba[i][RCOMP] = GetRValue(Color); + rgba[i][GCOMP] = GetGValue(Color); + rgba[i][BCOMP] = GetBValue(Color); + rgba[i][ACOMP] = 255; + } + } + DD_RELEASEDC; +} + +//--------------------------------------------------------------------------- + +static void wmesa_update_state( + GLcontext *ctx, + GLuint new_state) +{ + _swrast_InvalidateState( ctx, new_state ); + _swsetup_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); + _tnl_InvalidateState( ctx, new_state ); +} + +//--------------------------------------------------------------------------- + +static void wmesa_viewport( + GLcontext *ctx, + GLint x, + GLint y, + GLsizei w, + GLsizei h) +{ +// ctx->Driver.ResizeBuffersMESA(ctx); +} + +//--------------------------------------------------------------------------- + +static void wmesa_update_state_first_time( + GLcontext *ctx, + GLuint new_state) +{ + struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference( ctx ); + TNLcontext *tnl = TNL_CONTEXT(ctx); + + /* + * XXX these function pointers could be initialized just once during + * context creation since they don't depend on any state changes. + * kws - This is true - this function gets called a lot and it + * would be good to minimize setting all this when not needed. + */ + // Good idea, so I'll do it. KeithH. :-) + + ctx->Driver.GetString = _gldGetStringGeneric; + ctx->Driver.UpdateState = wmesa_update_state; + ctx->Driver.DrawBuffer = set_draw_buffer; + ctx->Driver.ResizeBuffers = _swrast_alloc_buffers; + ctx->Driver.GetBufferSize = buffer_size; + + ctx->Driver.Viewport = wmesa_viewport; + + ctx->Driver.Accum = _swrast_Accum; + ctx->Driver.Bitmap = _swrast_Bitmap; + ctx->Driver.Clear = clear; + + ctx->Driver.Flush = flush; + ctx->Driver.ClearIndex = clear_index; + ctx->Driver.ClearColor = clear_color; + ctx->Driver.Enable = enable; + + ctx->Driver.CopyPixels = _swrast_CopyPixels; + ctx->Driver.DrawPixels = _swrast_DrawPixels; + ctx->Driver.ReadPixels = _swrast_ReadPixels; + + 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.CopyColorTable = _swrast_CopyColorTable; + ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable; + ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D; + ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D; + + // Does not apply for Mesa 5.x + //ctx->Driver.BaseCompressedTexFormat = _mesa_base_compressed_texformat; + //ctx->Driver.CompressedTextureSize = _mesa_compressed_texture_size; + //ctx->Driver.GetCompressedTexImage = _mesa_get_compressed_teximage; + + swdd->SetBuffer = set_read_buffer; + + + /* Pixel/span writing functions: */ + swdd->WriteRGBASpan = write_rgba_span; + swdd->WriteRGBSpan = write_rgb_span; + swdd->WriteMonoRGBASpan = write_mono_rgba_span; + swdd->WriteRGBAPixels = write_rgba_pixels; + swdd->WriteMonoRGBAPixels = write_mono_rgba_pixels; + swdd->WriteCI32Span = write_ci32_span; + swdd->WriteCI8Span = write_ci8_span; + swdd->WriteMonoCISpan = write_mono_ci_span; + swdd->WriteCI32Pixels = write_ci32_pixels; + swdd->WriteMonoCIPixels = write_mono_ci_pixels; + + swdd->ReadCI32Span = read_ci32_span; + swdd->ReadRGBASpan = read_rgba_span; + swdd->ReadCI32Pixels = read_ci32_pixels; + swdd->ReadRGBAPixels = read_rgba_pixels; + + + tnl->Driver.RunPipeline = _tnl_run_pipeline; + + wmesa_update_state(ctx, new_state); +} + +//--------------------------------------------------------------------------- +// Driver interface functions +//--------------------------------------------------------------------------- + +BOOL gldCreateDrawable_MesaSW( + DGL_ctx *pCtx, + BOOL bPersistantInterface, + BOOL bPersistantBuffers) +{ + WMesaContext *c; + GLboolean true_color_flag; + GLboolean rgb_flag = GL_TRUE; + GLboolean db_flag = GL_TRUE; + + if (pCtx == NULL) + return FALSE; + + c = (struct wmesa_context * ) calloc(1,sizeof(struct wmesa_context)); + if (!c) + return FALSE; + + pCtx->glPriv = c; + + c->hDC = pCtx->hDC; + c->Window = pCtx->hWnd; + + true_color_flag = GetDeviceCaps(pCtx->hDC, BITSPIXEL) > 8; + + +#ifdef DITHER + if ((true_color_flag==GL_FALSE) && (rgb_flag == GL_TRUE)){ + c->dither_flag = GL_TRUE; + c->hPalHalfTone = WinGCreateHalftonePalette(); + } + else + c->dither_flag = GL_FALSE; +#else + c->dither_flag = GL_FALSE; +#endif + + + if (rgb_flag==GL_FALSE) + { + c->rgb_flag = GL_FALSE; +#if 0 + /* Old WinG stuff???? */ + c->db_flag = db_flag =GL_TRUE; /* WinG requires double buffering */ + printf("Single buffer is not supported in color index mode, ", + "setting to double buffer.\n"); +#endif + } + else + { + c->rgb_flag = GL_TRUE; + } + +// db_flag = pCtx->lpPF->pfd.dwFlags & PFD_DOUBLEBUFFER ? GL_TRUE : GL_FALSE; + db_flag = GL_TRUE; // Force double-buffer + if (db_flag) { + c->db_flag = 1; + /* Double buffered */ + { + wmCreateBackingStore(c, pCtx->dwWidth, pCtx->dwHeight); + + } + } else { + /* Single Buffered */ + if (c->rgb_flag) + c->db_flag = 0; + } + + c->bEmulateSingleBuffer = (pCtx->lpPF->pfd.dwFlags & PFD_DOUBLEBUFFER) + ? FALSE : TRUE; + + return TRUE; +} + +//--------------------------------------------------------------------------- + +BOOL gldResizeDrawable_MesaSW( + DGL_ctx *ctx, + BOOL bDefaultDriver, + BOOL bPersistantInterface, + BOOL bPersistantBuffers) +{ + WMesaContext *c; + + if (ctx == NULL) + return FALSE; + + c = ctx->glPriv; + if (c == NULL) + return FALSE; + + c->hDC = ctx->hDC; + c->Window = ctx->hWnd; +// c->width = ctx->dwWidth; +// c->height = ctx->dwHeight; + + if (c->db_flag) { + wmDeleteBackingStore(c); + wmCreateBackingStore(c, ctx->dwWidth, ctx->dwHeight); + } + + return TRUE; +} + +//--------------------------------------------------------------------------- + +BOOL gldDestroyDrawable_MesaSW( + DGL_ctx *ctx) +{ + WMesaContext *c; + + if (ctx == NULL) + return FALSE; + + c = ctx->glPriv; + if (c == NULL) + return FALSE; + + if (c->hPalHalfTone != NULL) + DeleteObject(c->hPalHalfTone); + + if (c->db_flag) + wmDeleteBackingStore(c); + + free(c); + + ctx->glPriv = NULL; + + return TRUE; +} + +//--------------------------------------------------------------------------- + +BOOL gldCreatePrivateGlobals_MesaSW(void) +{ + // Mesa Software driver needs no private globals + return TRUE; +} + +//--------------------------------------------------------------------------- + +BOOL gldDestroyPrivateGlobals_MesaSW(void) +{ + // Mesa Software driver needs no private globals + return TRUE; +} + +//--------------------------------------------------------------------------- + +BOOL gldBuildPixelformatList_MesaSW(void) +{ + // Release any existing pixelformat list + if (glb.lpPF) { + free(glb.lpPF); + } + + glb.nPixelFormatCount = 0; + glb.lpPF = NULL; + + glb.lpPF = (DGL_pixelFormat *)calloc(2, sizeof(DGL_pixelFormat)); + if (glb.lpPF == NULL) + return FALSE; + // Single-buffered + memcpy(&glb.lpPF[0], &pfTemplateMesaSW, sizeof(DGL_pixelFormat)); + glb.lpPF[0].pfd.dwFlags &= ~PFD_DOUBLEBUFFER; // Remove doublebuffer flag + // Double-buffered + memcpy(&glb.lpPF[1], &pfTemplateMesaSW, sizeof(DGL_pixelFormat)); + glb.nPixelFormatCount = 2; + + // Mark list as 'current' + glb.bPixelformatsDirty = FALSE; + + return TRUE; +} + +//--------------------------------------------------------------------------- + +BOOL gldInitialiseMesa_MesaSW( + DGL_ctx *gld) +{ + GLcontext *ctx; + + if (gld == NULL) + return FALSE; + + ctx = gld->glCtx; + + // Set max texture size to 256 + ctx->Const.MaxTextureLevels = 8; + + // Multitexture enable/disable + ctx->Const.MaxTextureUnits = (glb.bMultitexture) ? MAX_TEXTURE_UNITS : 1; + + /* Initialize the software rasterizer and helper modules.*/ + + // Added this to force max texture diminsion to 256. KeithH + ctx->Const.MaxTextureLevels = 8; + ctx->Const.MaxDrawBuffers = 1; + + _mesa_enable_sw_extensions(ctx); + _mesa_enable_imaging_extensions(ctx); + _mesa_enable_1_3_extensions(ctx); + +// _swrast_CreateContext( ctx ); +// _vbo_CreateContext( ctx ); +// _tnl_CreateContext( ctx ); +// _swsetup_CreateContext( ctx ); + + _swsetup_Wakeup( ctx ); + + wmesa_update_state_first_time(ctx, ~0); + + return TRUE; +} + +//--------------------------------------------------------------------------- + +BOOL gldSwapBuffers_MesaSW( + DGL_ctx *ctx, + HDC hDC, + HWND hWnd) +{ + WMesaContext *c; + + if (ctx == NULL) + return FALSE; + + c = ctx->glPriv; + if (c == NULL) + return FALSE; + + /* If we're swapping the buffer associated with the current context + * we have to flush any pending rendering commands first. + */ + + // Altered to respect bEmulateSingleBuffer. KeithH +// if (c->db_flag) + if (!c->bEmulateSingleBuffer) + wmFlush(c, hDC); + + return TRUE; +} + +//--------------------------------------------------------------------------- + +PROC gldGetProcAddress_MesaSW( + LPCSTR a) +{ + int i; + PROC proc = NULL; + + for (i=0; GLD_extList[i].proc; i++) { + if (!strcmp(a, GLD_extList[i].name)) { + proc = GLD_extList[i].proc; + break; + } + } + + gldLogPrintf(GLDLOG_INFO, "GetProcAddress: %s (%s)", a, proc ? "OK" : "Failed"); + + return proc; +} + +//--------------------------------------------------------------------------- + +BOOL gldGetDisplayMode_MesaSW( + DGL_ctx *ctx, + GLD_displayMode *glddm) +{ + HDC hdcDesktop; + + if (glddm == NULL) + return FALSE; + + // + // A bit hacky... KeithH + // + + hdcDesktop = GetDC(NULL); + glddm->Width = GetDeviceCaps(hdcDesktop, HORZRES); + glddm->Height = GetDeviceCaps(hdcDesktop, VERTRES); + glddm->BPP = GetDeviceCaps(hdcDesktop, BITSPIXEL); + glddm->Refresh = 0; + ReleaseDC(0, hdcDesktop); + + return TRUE; +} + +//--------------------------------------------------------------------------- + diff --git a/mesalib/src/mesa/drivers/windows/gldirect/opengl32.ref b/mesalib/src/mesa/drivers/windows/gldirect/opengl32.ref new file mode 100644 index 000000000..2f71faf21 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/opengl32.ref @@ -0,0 +1,495 @@ +;**************************************************************************** +;* +;* Mesa 3-D graphics library +;* Direct3D Driver Interface +;* +;* ======================================================================== +;* +;* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +;* +;* Permission is hereby granted, free of charge, to any person obtaining a +;* copy of this software and associated documentation files (the "Software"), +;* to deal in the Software without restriction, including without limitation +;* the rights to use, copy, modify, merge, publish, distribute, sublicense, +;* and/or sell copies of the Software, and to permit persons to whom the +;* Software is furnished to do so, subject to the following conditions: +;* +;* The above copyright notice and this permission notice shall be included +;* in all copies or substantial portions of the Software. +;* +;* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +;* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +;* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +;* SCITECH SOFTWARE INC 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. +;* +;* ====================================================================== +;* +;* Language: ANSI C +;* Environment: Windows 9x/2000/XP/XBox (Win32) +;* +;* Description: DLL Module definition file +;* +;****************************************************************************/ + +DESCRIPTION 'GLDirect' + +VERSION 3.0 + +EXPORTS + glAccum + glAlphaFunc + glAreTexturesResident + glArrayElement + glBegin + glBindTexture + glBitmap + glBlendFunc + glCallList + glCallLists + glClear + glClearAccum + glClearIndex + glClearColor + glClearDepth + glClearStencil + glClipPlane + glColor3b + glColor3d + glColor3f + glColor3i + glColor3s + glColor3ub + glColor3ui + glColor3us + glColor4b + glColor4d + glColor4f + glColor4i + glColor4s + glColor4ub + glColor4ui + glColor4us + glColor3bv + glColor3dv + glColor3fv + glColor3iv + glColor3sv + glColor3ubv + glColor3uiv + glColor3usv + glColor4bv + glColor4dv + glColor4fv + glColor4iv + glColor4sv + glColor4ubv + glColor4uiv + glColor4usv + glColorMask + glColorMaterial + glColorPointer + glColorTableEXT + glColorSubTableEXT + glCopyPixels + glCopyTexImage1D + glCopyTexImage2D + glCopyTexSubImage1D + glCopyTexSubImage2D + glCullFace + glDepthFunc + glDepthMask + glDepthRange + glDeleteLists + glDeleteTextures + glDisable + glDisableClientState + glDrawArrays + glDrawBuffer + glDrawElements + glDrawPixels + glEnable + glEnableClientState + glEnd + glEndList + glEvalCoord1d + glEvalCoord1f + glEvalCoord1dv + glEvalCoord1fv + glEvalCoord2d + glEvalCoord2f + glEvalCoord2dv + glEvalCoord2fv + glEvalPoint1 + glEvalPoint2 + glEvalMesh1 + glEdgeFlag + glEdgeFlagv + glEdgeFlagPointer + glEvalMesh2 + glFeedbackBuffer + glFinish + glFlush + glFogf + glFogi + glFogfv + glFogiv + glFrontFace + glFrustum + glGenLists + glGenTextures + glGetBooleanv + glGetClipPlane + glGetColorTableEXT + glGetColorTableParameterivEXT + glGetColorTableParameterfvEXT + glGetDoublev + glGetError + glGetFloatv + glGetIntegerv + glGetLightfv + glGetLightiv + glGetMapdv + glGetMapfv + glGetMapiv + glGetMaterialfv + glGetMaterialiv + glGetPixelMapfv + glGetPixelMapuiv + glGetPixelMapusv + glGetPointerv + glGetPolygonStipple + glGetString + glGetTexEnvfv + glGetTexEnviv + glGetTexGeniv + glGetTexGendv + glGetTexGenfv + glGetTexImage + glGetTexLevelParameterfv + glGetTexLevelParameteriv + glGetTexParameterfv + glGetTexParameteriv + glHint + glIndexd + glIndexf + glIndexi + glIndexs + glIndexub + glIndexdv + glIndexfv + glIndexiv + glIndexsv + glIndexubv + glIndexMask + glIndexPointer + glInterleavedArrays + glInitNames + glIsList + glIsTexture + glLightf + glLighti + glLightfv + glLightiv + glLightModelf + glLightModeli + glLightModelfv + glLightModeliv + glLineWidth + glLineStipple + glListBase + glLoadIdentity + glLoadMatrixd + glLoadMatrixf + glLoadName + glLogicOp + glMap1d + glMap1f + glMap2d + glMap2f + glMapGrid1d + glMapGrid1f + glMapGrid2d + glMapGrid2f + glMaterialf + glMateriali + glMaterialfv + glMaterialiv + glMatrixMode + glMultMatrixd + glMultMatrixf + glNewList + glNormal3b + glNormal3d + glNormal3f + glNormal3i + glNormal3s + glNormal3bv + glNormal3dv + glNormal3fv + glNormal3iv + glNormal3sv + glNormalPointer + glOrtho + glPassThrough + glPixelMapfv + glPixelMapuiv + glPixelMapusv + glPixelStoref + glPixelStorei + glPixelTransferf + glPixelTransferi + glPixelZoom + glPointSize + glPolygonMode + glPolygonOffset + glPolygonOffsetEXT + glPolygonStipple + glPopAttrib + glPopClientAttrib + glPopMatrix + glPopName + glPrioritizeTextures + glPushMatrix + glRasterPos2d + glRasterPos2f + glRasterPos2i + glRasterPos2s + glRasterPos3d + glRasterPos3f + glRasterPos3i + glRasterPos3s + glRasterPos4d + glRasterPos4f + glRasterPos4i + glRasterPos4s + glRasterPos2dv + glRasterPos2fv + glRasterPos2iv + glRasterPos2sv + glRasterPos3dv + glRasterPos3fv + glRasterPos3iv + glRasterPos3sv + glRasterPos4dv + glRasterPos4fv + glRasterPos4iv + glRasterPos4sv + glReadBuffer + glReadPixels + glRectd + glRectf + glRecti + glRects + glRectdv + glRectfv + glRectiv + glRectsv + glScissor + glIsEnabled + glPushAttrib + glPushClientAttrib + glPushName + glRenderMode + glRotated + glRotatef + glSelectBuffer + glScaled + glScalef + glShadeModel + glStencilFunc + glStencilMask + glStencilOp + glTexCoord1d + glTexCoord1f + glTexCoord1i + glTexCoord1s + glTexCoord2d + glTexCoord2f + glTexCoord2i + glTexCoord2s + glTexCoord3d + glTexCoord3f + glTexCoord3i + glTexCoord3s + glTexCoord4d + glTexCoord4f + glTexCoord4i + glTexCoord4s + glTexCoord1dv + glTexCoord1fv + glTexCoord1iv + glTexCoord1sv + glTexCoord2dv + glTexCoord2fv + glTexCoord2iv + glTexCoord2sv + glTexCoord3dv + glTexCoord3fv + glTexCoord3iv + glTexCoord3sv + glTexCoord4dv + glTexCoord4fv + glTexCoord4iv + glTexCoord4sv + glTexCoordPointer + glTexGend + glTexGenf + glTexGeni + glTexGendv + glTexGeniv + glTexGenfv + glTexEnvf + glTexEnvi + glTexEnvfv + glTexEnviv + glTexImage1D + glTexImage2D + glTexParameterf + glTexParameteri + glTexParameterfv + glTexParameteriv + glTexSubImage1D + glTexSubImage2D + glTranslated + glTranslatef + glVertex2d + glVertex2f + glVertex2i + glVertex2s + glVertex3d + glVertex3f + glVertex3i + glVertex3s + glVertex4d + glVertex4f + glVertex4i + glVertex4s + glVertex2dv + glVertex2fv + glVertex2iv + glVertex2sv + glVertex3dv + glVertex3fv + glVertex3iv + glVertex3sv + glVertex4dv + glVertex4fv + glVertex4iv + glVertex4sv + glVertexPointer + glViewport + + glBlendEquationEXT + glBlendColorEXT + glVertexPointerEXT + glNormalPointerEXT + glColorPointerEXT + glIndexPointerEXT + glTexCoordPointerEXT + glEdgeFlagPointerEXT + glGetPointervEXT + glArrayElementEXT + glDrawArraysEXT + glBindTextureEXT + glDeleteTexturesEXT + glGenTexturesEXT + glPrioritizeTexturesEXT + glCopyTexSubImage3DEXT + glTexImage3DEXT + glTexSubImage3DEXT + + glWindowPos4fMESA + glWindowPos2iMESA + glWindowPos2sMESA + glWindowPos2fMESA + glWindowPos2dMESA + glWindowPos2ivMESA + glWindowPos2svMESA + glWindowPos2fvMESA + glWindowPos2dvMESA + glWindowPos3iMESA + glWindowPos3sMESA + glWindowPos3fMESA + glWindowPos3dMESA + glWindowPos3ivMESA + glWindowPos3svMESA + glWindowPos3fvMESA + glWindowPos3dvMESA + glWindowPos4iMESA + glWindowPos4sMESA + glWindowPos4dMESA + glWindowPos4ivMESA + glWindowPos4svMESA + glWindowPos4fvMESA + glWindowPos4dvMESA + glResizeBuffersMESA + + wglCopyContext + wglCreateContext + wglCreateLayerContext + wglDeleteContext + wglDescribeLayerPlane + wglGetCurrentContext + wglGetCurrentDC + wglGetLayerPaletteEntries + wglGetProcAddress + wglMakeCurrent + wglRealizeLayerPalette + wglSetLayerPaletteEntries + wglShareLists + wglSwapLayerBuffers + wglUseFontBitmapsA + wglUseFontBitmapsW + wglUseFontOutlinesA + wglUseFontOutlinesW + +;These functions are identical and therefore share the same addresses + ChoosePixelFormat = wglChoosePixelFormat + DescribePixelFormat = wglDescribePixelFormat + GetPixelFormat = wglGetPixelFormat + SetPixelFormat = wglSetPixelFormat + SwapBuffers = wglSwapBuffers + + wglChoosePixelFormat + wglDescribePixelFormat + wglGetPixelFormat + wglSetPixelFormat + wglSwapBuffers + + glActiveTextureARB + glClientActiveTextureARB + glMultiTexCoord1dARB + glMultiTexCoord1dvARB + glMultiTexCoord1fARB + glMultiTexCoord1fvARB + glMultiTexCoord1iARB + glMultiTexCoord1ivARB + glMultiTexCoord1sARB + glMultiTexCoord1svARB + glMultiTexCoord2dARB + glMultiTexCoord2dvARB + glMultiTexCoord2fARB + glMultiTexCoord2fvARB + glMultiTexCoord2iARB + glMultiTexCoord2ivARB + glMultiTexCoord2sARB + glMultiTexCoord2svARB + glMultiTexCoord3dARB + glMultiTexCoord3dvARB + glMultiTexCoord3fARB + glMultiTexCoord3fvARB + glMultiTexCoord3iARB + glMultiTexCoord3ivARB + glMultiTexCoord3sARB + glMultiTexCoord3svARB + glMultiTexCoord4dARB + glMultiTexCoord4dvARB + glMultiTexCoord4fARB + glMultiTexCoord4fvARB + glMultiTexCoord4iARB + glMultiTexCoord4ivARB + glMultiTexCoord4sARB + glMultiTexCoord4svARB diff --git a/mesalib/src/mesa/glapi/APPLE_vertex_array_object.xml b/mesalib/src/mesa/glapi/APPLE_vertex_array_object.xml new file mode 100644 index 000000000..bd8427eaf --- /dev/null +++ b/mesalib/src/mesa/glapi/APPLE_vertex_array_object.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mesalib/src/mesa/glapi/ARB_copy_buffer.xml b/mesalib/src/mesa/glapi/ARB_copy_buffer.xml new file mode 100644 index 000000000..719816d81 --- /dev/null +++ b/mesalib/src/mesa/glapi/ARB_copy_buffer.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mesalib/src/mesa/glapi/ARB_framebuffer_object.xml b/mesalib/src/mesa/glapi/ARB_framebuffer_object.xml new file mode 100644 index 000000000..b700e7e77 --- /dev/null +++ b/mesalib/src/mesa/glapi/ARB_framebuffer_object.xml @@ -0,0 +1,269 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mesalib/src/mesa/glapi/ARB_map_buffer_range.xml b/mesalib/src/mesa/glapi/ARB_map_buffer_range.xml new file mode 100644 index 000000000..afcb9b6ba --- /dev/null +++ b/mesalib/src/mesa/glapi/ARB_map_buffer_range.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mesalib/src/mesa/glapi/ARB_seamless_cube_map.xml b/mesalib/src/mesa/glapi/ARB_seamless_cube_map.xml new file mode 100644 index 000000000..3cdc84d2b --- /dev/null +++ b/mesalib/src/mesa/glapi/ARB_seamless_cube_map.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/mesalib/src/mesa/glapi/ARB_sync.xml b/mesalib/src/mesa/glapi/ARB_sync.xml new file mode 100644 index 000000000..37f474980 --- /dev/null +++ b/mesalib/src/mesa/glapi/ARB_sync.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mesalib/src/mesa/glapi/ARB_vertex_array_object.xml b/mesalib/src/mesa/glapi/ARB_vertex_array_object.xml new file mode 100644 index 000000000..3b4ab64f5 --- /dev/null +++ b/mesalib/src/mesa/glapi/ARB_vertex_array_object.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mesalib/src/mesa/glapi/EXT_framebuffer_object.xml b/mesalib/src/mesa/glapi/EXT_framebuffer_object.xml new file mode 100644 index 000000000..5559b48b1 --- /dev/null +++ b/mesalib/src/mesa/glapi/EXT_framebuffer_object.xml @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mesalib/src/mesa/glapi/EXT_provoking_vertex.xml b/mesalib/src/mesa/glapi/EXT_provoking_vertex.xml new file mode 100644 index 000000000..f528a2c7d --- /dev/null +++ b/mesalib/src/mesa/glapi/EXT_provoking_vertex.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/mesalib/src/mesa/glapi/EXT_texture_array.xml b/mesalib/src/mesa/glapi/EXT_texture_array.xml new file mode 100644 index 000000000..e5bd9f3c6 --- /dev/null +++ b/mesalib/src/mesa/glapi/EXT_texture_array.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mesalib/src/mesa/glapi/Makefile b/mesalib/src/mesa/glapi/Makefile new file mode 100644 index 000000000..65edab7ce --- /dev/null +++ b/mesalib/src/mesa/glapi/Makefile @@ -0,0 +1,152 @@ +# This file isn't used during a normal compilation since we don't want to +# require Python in order to compile Mesa. +# Instead, when the Mesa developers update/change the API interface it's +# up to him/her to re-run this makefile and check in the newly generated files. + + +TOP = ../../.. +include $(TOP)/configs/current + +OUTPUTS = glprocs.h glapitemp.h glapioffsets.h glapitable.h dispatch.h \ + ../main/enums.c \ + ../x86/glapi_x86.S \ + ../x86-64/glapi_x86-64.S \ + ../sparc/glapi_sparc.S \ + ../drivers/dri/common/extension_helper.h \ + ../../glx/x11/indirect.c \ + ../../glx/x11/indirect.h \ + ../../glx/x11/indirect_init.c \ + ../../glx/x11/indirect_size.h \ + ../../glx/x11/indirect_size.c + + +GLX_DIR = $(XORG_BASE)/glx + +SERVER_GLAPI_FILES = \ + $(GLX_DIR)/glapi.h \ + $(GLX_DIR)/glapi.c \ + $(GLX_DIR)/glthread.c \ + $(GLX_DIR)/glthread.h + +SERVER_OUTPUTS = \ + $(GLX_DIR)/indirect_dispatch.c \ + $(GLX_DIR)/indirect_dispatch_swap.c \ + $(GLX_DIR)/indirect_dispatch.h \ + $(GLX_DIR)/indirect_reqsize.c \ + $(GLX_DIR)/indirect_reqsize.h \ + $(GLX_DIR)/indirect_size.h \ + $(GLX_DIR)/indirect_size_get.c \ + $(GLX_DIR)/indirect_size_get.h \ + $(GLX_DIR)/indirect_table.c \ + $(GLX_DIR)/glapitemp.h \ + $(GLX_DIR)/glapitable.h \ + $(GLX_DIR)/glapioffsets.h \ + $(GLX_DIR)/glprocs.h \ + $(GLX_DIR)/dispatch.h \ + $(SERVER_GLAPI_FILES) + +API_XML = gl_API.xml \ + EXT_framebuffer_object.xml \ + ARB_copy_buffer.xml \ + ARB_framebuffer_object.xml \ + ARB_map_buffer_range.xml \ + ARB_seamless_cube_map.xml \ + ARB_sync.xml \ + ARB_vertex_array_object.xml \ + APPLE_vertex_array_object.xml \ + EXT_provoking_vertex.xml + +COMMON = gl_XML.py glX_XML.py license.py $(API_XML) typeexpr.py +COMMON_GLX = $(COMMON) glX_API.xml glX_XML.py glX_proto_common.py + +all: check-xorg-source $(OUTPUTS) $(SERVER_OUTPUTS) + +check-xorg-source: + @if ! test -d $(GLX_DIR); then \ + echo "ERROR: Must specify path to xserver checkout; set XORG_BASE."; \ + exit 1; \ + fi + +$(GLX_DIR)/%.c: %.c + cp $< $@ + +$(GLX_DIR)/%.h: %.h + cp $< $@ + +glprocs.h $(GLX_DIR)/glprocs.h: gl_procs.py $(COMMON) + $(PYTHON2) $(PYTHON_FLAGS) $< > $@ + +glapitemp.h $(GLX_DIR)/glapitemp.h: gl_apitemp.py $(COMMON) + $(PYTHON2) $(PYTHON_FLAGS) $< > $@ + +glapioffsets.h $(GLX_DIR)/glapioffsets.h: gl_offsets.py $(COMMON) + $(PYTHON2) $(PYTHON_FLAGS) $< > $@ + +glapitable.h $(GLX_DIR)/glapitable.h: gl_table.py $(COMMON) + $(PYTHON2) $(PYTHON_FLAGS) $< > $@ + +dispatch.h $(GLX_DIR)/dispatch.h: gl_table.py $(COMMON) + $(PYTHON2) $(PYTHON_FLAGS) $< -m remap_table > $@ + +../main/enums.c: gl_enums.py $(COMMON) + $(PYTHON2) $(PYTHON_FLAGS) $< > $@ + +../x86/glapi_x86.S: gl_x86_asm.py $(COMMON) + $(PYTHON2) $(PYTHON_FLAGS) $< > $@ + +../x86-64/glapi_x86-64.S: gl_x86-64_asm.py $(COMMON) + $(PYTHON2) $(PYTHON_FLAGS) $< > $@ + +../sparc/glapi_sparc.S: gl_SPARC_asm.py $(COMMON) + $(PYTHON2) $(PYTHON_FLAGS) $< > $@ + + +../drivers/dri/common/extension_helper.h: extension_helper.py $(COMMON) + $(PYTHON2) $(PYTHON_FLAGS) $< > $@ + +../../glx/x11/indirect.c: glX_proto_send.py $(COMMON_GLX) + $(PYTHON2) $(PYTHON_FLAGS) $< -m proto | $(INDENT) $(INDENT_FLAGS) > $@ + +../../glx/x11/indirect.h: glX_proto_send.py $(COMMON_GLX) + $(PYTHON2) $(PYTHON_FLAGS) $< -m init_h > $@ + +../../glx/x11/indirect_init.c: glX_proto_send.py $(COMMON_GLX) + $(PYTHON2) $(PYTHON_FLAGS) $< -m init_c > $@ + +../../glx/x11/indirect_size.h $(GLX_DIR)/indirect_size.h: glX_proto_size.py $(COMMON_GLX) + $(PYTHON2) $(PYTHON_FLAGS) $< -m size_h --only-set -h _INDIRECT_SIZE_H_ \ + | $(INDENT) $(INDENT_FLAGS) > $@ + +../../glx/x11/indirect_size.c: glX_proto_size.py $(COMMON_GLX) + $(PYTHON2) $(PYTHON_FLAGS) $< -m size_c --only-set \ + | $(INDENT) $(INDENT_FLAGS) > $@ + +$(GLX_DIR)/indirect_dispatch.c: glX_proto_recv.py $(COMMON_GLX) + $(PYTHON2) $(PYTHON_FLAGS) $< -m dispatch_c > $@ + +$(GLX_DIR)/indirect_dispatch_swap.c: glX_proto_recv.py $(COMMON_GLX) + $(PYTHON2) $(PYTHON_FLAGS) $< -m dispatch_c -s > $@ + +$(GLX_DIR)/indirect_dispatch.h: glX_proto_recv.py gl_and_glX_API.xml $(COMMON_GLX) + $(PYTHON2) $(PYTHON_FLAGS) $< -m dispatch_h -f gl_and_glX_API.xml -s > $@ + +$(GLX_DIR)/indirect_size_get.h: glX_proto_size.py $(COMMON_GLX) + $(PYTHON2) $(PYTHON_FLAGS) $< -m size_h --only-get -h '_INDIRECT_SIZE_GET_H_' \ + | $(INDENT) $(INDENT_FLAGS) > $@ + +$(GLX_DIR)/indirect_size_get.c: glX_proto_size.py $(COMMON_GLX) + $(PYTHON2) $(PYTHON_FLAGS) $< -m size_c | $(INDENT) $(INDENT_FLAGS) > $@ + +$(GLX_DIR)/indirect_reqsize.h: glX_proto_size.py $(COMMON_GLX) + $(PYTHON2) $(PYTHON_FLAGS) $< -m reqsize_h --only-get -h '_INDIRECT_SIZE_GET_H_' \ + | $(INDENT) $(INDENT_FLAGS) -l200 > $@ + +$(GLX_DIR)/indirect_reqsize.c: glX_proto_size.py $(COMMON_GLX) + $(PYTHON2) $(PYTHON_FLAGS) $< -m reqsize_c | $(INDENT) $(INDENT_FLAGS) > $@ + +$(GLX_DIR)/indirect_table.c: glX_server_table.py gl_and_glX_API.xml $(COMMON_GLX) + $(PYTHON2) $(PYTHON_FLAGS) $< -f gl_and_glX_API.xml > $@ + +clean: + -rm -f *~ *.pyo + -rm -f $(OUTPUTS) diff --git a/mesalib/src/mesa/glapi/extension_helper.py b/mesalib/src/mesa/glapi/extension_helper.py new file mode 100644 index 000000000..83471d89f --- /dev/null +++ b/mesalib/src/mesa/glapi/extension_helper.py @@ -0,0 +1,324 @@ +#!/usr/bin/env python + +# (C) Copyright IBM Corporation 2005 +# 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 +# IBM AND/OR ITS 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 + +import gl_XML +import license +import sys, getopt, string + +vtxfmt = [ + "ArrayElement", \ + "Color3f", \ + "Color3fv", \ + "Color4f", \ + "Color4fv", \ + "EdgeFlag", \ + "EdgeFlagv", \ + "EvalCoord1f", \ + "EvalCoord1fv", \ + "EvalCoord2f", \ + "EvalCoord2fv", \ + "EvalPoint1", \ + "EvalPoint2", \ + "FogCoordfEXT", \ + "FogCoordfvEXT", \ + "Indexf", \ + "Indexfv", \ + "Materialfv", \ + "MultiTexCoord1fARB", \ + "MultiTexCoord1fvARB", \ + "MultiTexCoord2fARB", \ + "MultiTexCoord2fvARB", \ + "MultiTexCoord3fARB", \ + "MultiTexCoord3fvARB", \ + "MultiTexCoord4fARB", \ + "MultiTexCoord4fvARB", \ + "Normal3f", \ + "Normal3fv", \ + "SecondaryColor3fEXT", \ + "SecondaryColor3fvEXT", \ + "TexCoord1f", \ + "TexCoord1fv", \ + "TexCoord2f", \ + "TexCoord2fv", \ + "TexCoord3f", \ + "TexCoord3fv", \ + "TexCoord4f", \ + "TexCoord4fv", \ + "Vertex2f", \ + "Vertex2fv", \ + "Vertex3f", \ + "Vertex3fv", \ + "Vertex4f", \ + "Vertex4fv", \ + "CallList", \ + "CallLists", \ + "Begin", \ + "End", \ + "VertexAttrib1fNV", \ + "VertexAttrib1fvNV", \ + "VertexAttrib2fNV", \ + "VertexAttrib2fvNV", \ + "VertexAttrib3fNV", \ + "VertexAttrib3fvNV", \ + "VertexAttrib4fNV", \ + "VertexAttrib4fvNV", \ + "VertexAttrib1fARB", \ + "VertexAttrib1fvARB", \ + "VertexAttrib2fARB", \ + "VertexAttrib2fvARB", \ + "VertexAttrib3fARB", \ + "VertexAttrib3fvARB", \ + "VertexAttrib4fARB", \ + "VertexAttrib4fvARB", \ + "Rectf", \ + "DrawArrays", \ + "DrawElements", \ + "DrawRangeElements", \ + "EvalMesh1", \ + "EvalMesh2", \ +] + +def all_entrypoints_in_abi(f, abi, api): + for n in f.entry_points: + [category, num] = api.get_category_for_name( n ) + if category not in abi: + return 0 + + return 1 + + +def any_entrypoints_in_abi(f, abi, api): + for n in f.entry_points: + [category, num] = api.get_category_for_name( n ) + if category in abi: + return 1 + + return 0 + + +def condition_for_function(f, abi, all_not_in_ABI): + """Create a C-preprocessor condition for the function. + + There are two modes of operation. If all_not_in_ABI is set, a + condition is only created is all of the entry-point names for f are + not in the selected ABI. If all_not_in_ABI is not set, a condition + is created if any entryp-point name is not in the selected ABI. + """ + + condition = [] + for n in f.entry_points: + [category, num] = api.get_category_for_name( n ) + if category not in abi: + condition.append( 'defined(need_%s)' % (gl_XML.real_category_name( category )) ) + elif all_not_in_ABI: + return [] + + return condition + + +class PrintGlExtensionGlue(gl_XML.gl_print_base): + def __init__(self): + gl_XML.gl_print_base.__init__(self) + + self.name = "extension_helper.py (from Mesa)" + self.license = license.bsd_license_template % ("(C) Copyright IBM Corporation 2005", "IBM") + return + + + def printRealHeader(self): + print '#include "utils.h"' + print '#include "glapi/dispatch.h"' + print '' + return + + + def printBody(self, api): + abi = [ "1.0", "1.1", "1.2", "GL_ARB_multitexture" ] + + category_list = {} + + print '#ifndef NULL' + print '# define NULL 0' + print '#endif' + print '' + + for f in api.functionIterateAll(): + condition = condition_for_function(f, abi, 0) + if len(condition): + print '#if %s' % (string.join(condition, " || ")) + print 'static const char %s_names[] =' % (f.name) + + parameter_signature = '' + for p in f.parameterIterator(): + if p.is_padding: + continue + + # FIXME: This is a *really* ugly hack. :( + + tn = p.type_expr.get_base_type_node() + if p.is_pointer(): + parameter_signature += 'p' + elif tn.integer: + parameter_signature += 'i' + elif tn.size == 4: + parameter_signature += 'f' + else: + parameter_signature += 'd' + + print ' "%s\\0" /* Parameter signature */' % (parameter_signature) + + for n in f.entry_points: + print ' "gl%s\\0"' % (n) + + [category, num] = api.get_category_for_name( n ) + if category not in abi: + c = gl_XML.real_category_name(category) + if not category_list.has_key(c): + category_list[ c ] = [] + + category_list[ c ].append( f ) + + print ' "";' + print '#endif' + print '' + + keys = category_list.keys() + keys.sort() + + for category in keys: + print '#if defined(need_%s)' % (category) + print 'static const struct dri_extension_function %s_functions[] = {' % (category) + + for f in category_list[ category ]: + # A function either has an offset that is + # assigned by the ABI, or it has a remap + # index. + if any_entrypoints_in_abi(f, abi, api): + index_name = "-1" + offset = f.offset + else: + index_name = "%s_remap_index" % (f.name) + offset = -1 + + print ' { %s_names, %s, %d },' % (f.name, index_name, offset) + + + print ' { NULL, 0, 0 }' + print '};' + print '#endif' + print '' + + return + + +class PrintInitDispatch(gl_XML.gl_print_base): + def __init__(self): + gl_XML.gl_print_base.__init__(self) + + self.name = "extension_helper.py (from Mesa)" + self.license = license.bsd_license_template % ("(C) Copyright IBM Corporation 2005", "IBM") + return + + + def do_function_body(self, api, abi, vtxfmt_only): + last_condition_string = None + for f in api.functionIterateByOffset(): + if (f.name in vtxfmt) and not vtxfmt_only: + continue + + if (f.name not in vtxfmt) and vtxfmt_only: + continue + + condition = condition_for_function(f, abi, 1) + condition_string = string.join(condition, " || ") + + if condition_string != last_condition_string: + if last_condition_string: + print '#endif /* %s */' % (last_condition_string) + + if condition_string: + print '#if %s' % (condition_string) + + if vtxfmt_only: + print ' disp->%s = vfmt->%s;' % (f.name, f.name) + else: + print ' disp->%s = _mesa_%s;' % (f.name, f.name) + + last_condition_string = condition_string + + if last_condition_string: + print '#endif /* %s */' % (last_condition_string) + + + + def printBody(self, api): + abi = [ "1.0", "1.1", "1.2", "GL_ARB_multitexture" ] + + print 'void driver_init_exec_table(struct _glapi_table *disp)' + print '{' + self.do_function_body(api, abi, 0) + print '}' + print '' + print 'void driver_install_vtxfmt(struct _glapi_table *disp, const GLvertexformat *vfmt)' + print '{' + self.do_function_body(api, abi, 1) + print '}' + + return + + +def show_usage(): + print "Usage: %s [-f input_file_name] [-m output_mode]" % sys.argv[0] + print " -m output_mode Output mode can be one of 'extensions' or 'exec_init'." + sys.exit(1) + +if __name__ == '__main__': + file_name = "gl_API.xml" + + try: + (args, trail) = getopt.getopt(sys.argv[1:], "f:m:") + except Exception,e: + show_usage() + + mode = "extensions" + for (arg,val) in args: + if arg == "-f": + file_name = val + if arg == '-m': + mode = val + + + api = gl_XML.parse_GL_API( file_name ) + + if mode == "extensions": + printer = PrintGlExtensionGlue() + elif mode == "exec_init": + printer = PrintInitDispatch() + else: + show_usage() + + printer.Print( api ) diff --git a/mesalib/src/mesa/glapi/glX_API.xml b/mesalib/src/mesa/glapi/glX_API.xml new file mode 100644 index 000000000..9e02aa498 --- /dev/null +++ b/mesalib/src/mesa/glapi/glX_API.xml @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mesalib/src/mesa/glapi/glX_XML.py b/mesalib/src/mesa/glapi/glX_XML.py new file mode 100644 index 000000000..4c2e0f95b --- /dev/null +++ b/mesalib/src/mesa/glapi/glX_XML.py @@ -0,0 +1,570 @@ +#!/usr/bin/env python + +# (C) Copyright IBM Corporation 2004, 2005 +# 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 +# IBM AND/OR ITS 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 + +import gl_XML +import license +import sys, getopt, string + + +class glx_item_factory(gl_XML.gl_item_factory): + """Factory to create GLX protocol oriented objects derived from gl_item.""" + + def create_item(self, name, element, context): + if name == "function": + return glx_function(element, context) + elif name == "enum": + return glx_enum(element, context) + elif name == "api": + return glx_api(self) + else: + return gl_XML.gl_item_factory.create_item(self, name, element, context) + + +class glx_enum(gl_XML.gl_enum): + def __init__(self, element, context): + gl_XML.gl_enum.__init__(self, element, context) + + self.functions = {} + + child = element.children + while child: + if child.type == "element" and child.name == "size": + n = child.nsProp( "name", None ) + c = child.nsProp( "count", None ) + m = child.nsProp( "mode", None ) + + if not c: + c = self.default_count + else: + c = int(c) + + if m == "get": + mode = 0 + else: + mode = 1 + + if not self.functions.has_key(n): + self.functions[ n ] = [c, mode] + + child = child.next + + return + + +class glx_function(gl_XML.gl_function): + def __init__(self, element, context): + self.glx_rop = 0 + self.glx_sop = 0 + self.glx_vendorpriv = 0 + + self.glx_vendorpriv_names = [] + + # If this is set to true, it means that GLdouble parameters should be + # written to the GLX protocol packet in the order they appear in the + # prototype. This is different from the "classic" ordering. In the + # classic ordering GLdoubles are written to the protocol packet first, + # followed by non-doubles. NV_vertex_program was the first extension + # to break with this tradition. + + self.glx_doubles_in_order = 0 + + self.vectorequiv = None + self.output = None + self.can_be_large = 0 + self.reply_always_array = 0 + self.dimensions_in_reply = 0 + self.img_reset = None + + self.server_handcode = 0 + self.client_handcode = 0 + self.ignore = 0 + + self.count_parameter_list = [] + self.counter_list = [] + self.parameters_by_name = {} + self.offsets_calculated = 0 + + gl_XML.gl_function.__init__(self, element, context) + return + + + def process_element(self, element): + gl_XML.gl_function.process_element(self, element) + + # If the function already has a vector equivalent set, don't + # set it again. This can happen if an alias to a function + # appears after the function that it aliases. + + if not self.vectorequiv: + self.vectorequiv = element.nsProp("vectorequiv", None) + + + name = element.nsProp("name", None) + if name == self.name: + for param in self.parameters: + self.parameters_by_name[ param.name ] = param + + if len(param.count_parameter_list): + self.count_parameter_list.extend( param.count_parameter_list ) + + if param.counter and param.counter not in self.counter_list: + self.counter_list.append(param.counter) + + + child = element.children + while child: + if child.type == "element" and child.name == "glx": + rop = child.nsProp( 'rop', None ) + sop = child.nsProp( 'sop', None ) + vop = child.nsProp( 'vendorpriv', None ) + + if rop: + self.glx_rop = int(rop) + + if sop: + self.glx_sop = int(sop) + + if vop: + self.glx_vendorpriv = int(vop) + self.glx_vendorpriv_names.append(name) + + self.img_reset = child.nsProp( 'img_reset', None ) + + # The 'handcode' attribute can be one of 'true', + # 'false', 'client', or 'server'. + + handcode = child.nsProp( 'handcode', None ) + if handcode == "false": + self.server_handcode = 0 + self.client_handcode = 0 + elif handcode == "true": + self.server_handcode = 1 + self.client_handcode = 1 + elif handcode == "client": + self.server_handcode = 0 + self.client_handcode = 1 + elif handcode == "server": + self.server_handcode = 1 + self.client_handcode = 0 + else: + raise RuntimeError('Invalid handcode mode "%s" in function "%s".' % (handcode, self.name)) + + self.ignore = gl_XML.is_attr_true( child, 'ignore' ) + self.can_be_large = gl_XML.is_attr_true( child, 'large' ) + self.glx_doubles_in_order = gl_XML.is_attr_true( child, 'doubles_in_order' ) + self.reply_always_array = gl_XML.is_attr_true( child, 'always_array' ) + self.dimensions_in_reply = gl_XML.is_attr_true( child, 'dimensions_in_reply' ) + + child = child.next + + + # Do some validation of the GLX protocol information. As + # new tests are discovered, they should be added here. + + for param in self.parameters: + if param.is_output and self.glx_rop != 0: + raise RuntimeError("Render / RenderLarge commands cannot have outputs (%s)." % (self.name)) + + return + + + def has_variable_size_request(self): + """Determine if the GLX request packet is variable sized. + + The GLX request packet is variable sized in several common + situations. + + 1. The function has a non-output parameter that is counted + by another parameter (e.g., the 'textures' parameter of + glDeleteTextures). + + 2. The function has a non-output parameter whose count is + determined by another parameter that is an enum (e.g., the + 'params' parameter of glLightfv). + + 3. The function has a non-output parameter that is an + image. + + 4. The function must be hand-coded on the server. + """ + + if self.glx_rop == 0: + return 0 + + if self.server_handcode or self.images: + return 1 + + for param in self.parameters: + if not param.is_output: + if param.counter or len(param.count_parameter_list): + return 1 + + return 0 + + + def variable_length_parameter(self): + for param in self.parameters: + if not param.is_output: + if param.counter or len(param.count_parameter_list): + return param + + return None + + + def calculate_offsets(self): + if not self.offsets_calculated: + # Calculate the offset of the first function parameter + # in the GLX command packet. This byte offset is + # measured from the end of the Render / RenderLarge + # header. The offset for all non-pixel commends is + # zero. The offset for pixel commands depends on the + # number of dimensions of the pixel data. + + if len(self.images) and not self.images[0].is_output: + [dim, junk, junk, junk, junk] = self.images[0].get_dimensions() + + # The base size is the size of the pixel pack info + # header used by images with the specified number + # of dimensions. + + if dim <= 2: + offset = 20 + elif dim <= 4: + offset = 36 + else: + raise RuntimeError('Invalid number of dimensions %u for parameter "%s" in function "%s".' % (dim, self.image.name, self.name)) + else: + offset = 0 + + for param in self.parameterIterateGlxSend(): + if param.img_null_flag: + offset += 4 + + if param.name != self.img_reset: + param.offset = offset + if not param.is_variable_length() and not param.is_client_only: + offset += param.size() + + if self.pad_after( param ): + offset += 4 + + + self.offsets_calculated = 1 + return + + + def offset_of(self, param_name): + self.calculate_offsets() + return self.parameters_by_name[ param_name ].offset + + + def parameterIterateGlxSend(self, include_variable_parameters = 1): + """Create an iterator for parameters in GLX request order.""" + + # The parameter lists are usually quite short, so it's easier + # (i.e., less code) to just generate a new list with the + # required elements than it is to create a new iterator class. + + temp = [ [], [], [] ] + for param in self.parameters: + if param.is_output: continue + + if param.is_variable_length(): + temp[2].append( param ) + elif not self.glx_doubles_in_order and param.is_64_bit(): + temp[0].append( param ) + else: + temp[1].append( param ) + + parameters = temp[0] + parameters.extend( temp[1] ) + if include_variable_parameters: + parameters.extend( temp[2] ) + return parameters.__iter__() + + + def parameterIterateCounters(self): + temp = [] + for name in self.counter_list: + temp.append( self.parameters_by_name[ name ] ) + + return temp.__iter__() + + + def parameterIterateOutputs(self): + temp = [] + for p in self.parameters: + if p.is_output: + temp.append( p ) + + return temp + + + def command_fixed_length(self): + """Return the length, in bytes as an integer, of the + fixed-size portion of the command.""" + + if len(self.parameters) == 0: + return 0 + + self.calculate_offsets() + + size = 0 + for param in self.parameterIterateGlxSend(0): + if param.name != self.img_reset and not param.is_client_only: + if size == 0: + size = param.offset + param.size() + else: + size += param.size() + + if self.pad_after( param ): + size += 4 + + for param in self.images: + if param.img_null_flag or param.is_output: + size += 4 + + return size + + + def command_variable_length(self): + """Return the length, as a string, of the variable-sized + portion of the command.""" + + size_string = "" + for p in self.parameterIterateGlxSend(): + if (not p.is_output) and (p.is_variable_length() or p.is_image()): + # FIXME Replace the 1 in the size_string call + # FIXME w/0 to eliminate some un-needed parnes + # FIXME This would already be done, but it + # FIXME adds some extra diffs to the generated + # FIXME code. + + size_string = size_string + " + __GLX_PAD(%s)" % (p.size_string(1)) + + return size_string + + + def command_length(self): + size = self.command_fixed_length() + + if self.glx_rop != 0: + size += 4 + + size = ((size + 3) & ~3) + return "%u%s" % (size, self.command_variable_length()) + + + def opcode_real_value(self): + """Get the true numeric value of the GLX opcode + + Behaves similarly to opcode_value, except for + X_GLXVendorPrivate and X_GLXVendorPrivateWithReply commands. + In these cases the value for the GLX opcode field (i.e., + 16 for X_GLXVendorPrivate or 17 for + X_GLXVendorPrivateWithReply) is returned. For other 'single' + commands, the opcode for the command (e.g., 101 for + X_GLsop_NewList) is returned.""" + + if self.glx_vendorpriv != 0: + if self.needs_reply(): + return 17 + else: + return 16 + else: + return self.opcode_value() + + + def opcode_value(self): + """Get the unique protocol opcode for the glXFunction""" + + if (self.glx_rop == 0) and self.vectorequiv: + equiv = self.context.functions_by_name[ self.vectorequiv ] + self.glx_rop = equiv.glx_rop + + + if self.glx_rop != 0: + return self.glx_rop + elif self.glx_sop != 0: + return self.glx_sop + elif self.glx_vendorpriv != 0: + return self.glx_vendorpriv + else: + return -1 + + + def opcode_rop_basename(self): + """Return either the name to be used for GLX protocol enum. + + Returns either the name of the function or the name of the + name of the equivalent vector (e.g., glVertex3fv for + glVertex3f) function.""" + + if self.vectorequiv == None: + return self.name + else: + return self.vectorequiv + + + def opcode_name(self): + """Get the unique protocol enum name for the glXFunction""" + + if (self.glx_rop == 0) and self.vectorequiv: + equiv = self.context.functions_by_name[ self.vectorequiv ] + self.glx_rop = equiv.glx_rop + self.glx_doubles_in_order = equiv.glx_doubles_in_order + + + if self.glx_rop != 0: + return "X_GLrop_%s" % (self.opcode_rop_basename()) + elif self.glx_sop != 0: + return "X_GLsop_%s" % (self.name) + elif self.glx_vendorpriv != 0: + return "X_GLvop_%s" % (self.name) + else: + raise RuntimeError('Function "%s" has no opcode.' % (self.name)) + + + def opcode_vendor_name(self, name): + if name in self.glx_vendorpriv_names: + return "X_GLvop_%s" % (name) + else: + raise RuntimeError('Function "%s" has no VendorPrivate opcode.' % (name)) + + + def opcode_real_name(self): + """Get the true protocol enum name for the GLX opcode + + Behaves similarly to opcode_name, except for + X_GLXVendorPrivate and X_GLXVendorPrivateWithReply commands. + In these cases the string 'X_GLXVendorPrivate' or + 'X_GLXVendorPrivateWithReply' is returned. For other + single or render commands 'X_GLsop' or 'X_GLrop' plus the + name of the function returned.""" + + if self.glx_vendorpriv != 0: + if self.needs_reply(): + return "X_GLXVendorPrivateWithReply" + else: + return "X_GLXVendorPrivate" + else: + return self.opcode_name() + + + def needs_reply(self): + try: + x = self._needs_reply + except Exception, e: + x = 0 + if self.return_type != 'void': + x = 1 + + for param in self.parameters: + if param.is_output: + x = 1 + break + + self._needs_reply = x + + return x + + + def pad_after(self, p): + """Returns the name of the field inserted after the + specified field to pad out the command header.""" + + for image in self.images: + if image.img_pad_dimensions: + if not image.height: + if p.name == image.width: + return "height" + elif p.name == image.img_xoff: + return "yoffset" + elif not image.extent: + if p.name == image.depth: + # Should this be "size4d"? + return "extent" + elif p.name == image.img_zoff: + return "woffset" + + return None + + + def has_different_protocol(self, name): + """Returns true if the named version of the function uses different protocol from the other versions. + + Some functions, such as glDeleteTextures and + glDeleteTexturesEXT are functionally identical, but have + different protocol. This function returns true if the + named function is an alias name and that named version uses + different protocol from the function that is aliased. + """ + + return (name in self.glx_vendorpriv_names) and self.glx_sop + + + def static_glx_name(self, name): + if self.has_different_protocol(name): + for n in self.glx_vendorpriv_names: + if n in self.static_entry_points: + return n + + return self.static_name(name) + + + def client_supported_for_indirect(self): + """Returns true if the function is supported on the client + side for indirect rendering.""" + + return not self.ignore and (self.offset != -1) and (self.glx_rop or self.glx_sop or self.glx_vendorpriv or self.vectorequiv or self.client_handcode) + + +class glx_function_iterator: + """Class to iterate over a list of glXFunctions""" + + def __init__(self, context): + self.iterator = context.functionIterateByOffset() + return + + + def __iter__(self): + return self + + + def next(self): + f = self.iterator.next() + + if f.client_supported_for_indirect(): + return f + else: + return self.next() + + +class glx_api(gl_XML.gl_api): + def functionIterateGlx(self): + return glx_function_iterator(self) + diff --git a/mesalib/src/mesa/glapi/glX_doc.py b/mesalib/src/mesa/glapi/glX_doc.py new file mode 100644 index 000000000..e9fbbe6f1 --- /dev/null +++ b/mesalib/src/mesa/glapi/glX_doc.py @@ -0,0 +1,280 @@ +#!/usr/bin/env python + +# (C) Copyright IBM Corporation 2004, 2005 +# 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 +# IBM AND/OR ITS 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 + +import gl_XML, glX_XML, glX_proto_common, license +import sys, getopt + + +class glx_doc_item_factory(glX_proto_common.glx_proto_item_factory): + """Factory to create GLX protocol documentation oriented objects derived from glItem.""" + + def create_item(self, name, element, context): + if name == "parameter": + return glx_doc_parameter(element, context) + else: + return glX_proto_common.glx_proto_item_factory.create_item(self, name, element, context) + + +class glx_doc_parameter(gl_XML.gl_parameter): + def packet_type(self, type_dict): + """Get the type string for the packet header + + GLX protocol documentation uses type names like CARD32, + FLOAT64, LISTofCARD8, and ENUM. This function converts the + type of the parameter to one of these names.""" + + list_of = "" + if self.is_array(): + list_of = "LISTof" + + t_name = self.get_base_type_string() + if not type_dict.has_key( t_name ): + type_name = "CARD8" + else: + type_name = type_dict[ t_name ] + + return "%s%s" % (list_of, type_name) + + + def packet_size(self): + p = None + s = self.size() + if s == 0: + a_prod = "n" + b_prod = self.p_type.size + + if not self.count_parameter_list and self.counter: + a_prod = self.counter + elif self.count_parameter_list and not self.counter or self.is_output: + pass + elif self.count_parameter_list and self.counter: + b_prod = self.counter + else: + raise RuntimeError("Parameter '%s' to function '%s' has size 0." % (self.name, self.context.name)) + + ss = "%s*%s" % (a_prod, b_prod) + + return [ss, p] + else: + if s % 4 != 0: + p = "p" + + return [str(s), p] + +class PrintGlxProtoText(gl_XML.gl_print_base): + def __init__(self): + gl_XML.gl_print_base.__init__(self) + self.license = "" + + + def printHeader(self): + return + + + def body_size(self, f): + # At some point, refactor this function and + # glXFunction::command_payload_length. + + size = 0; + size_str = "" + pad_str = "" + plus = "" + for p in f.parameterIterateGlxSend(): + [s, pad] = p.packet_size() + try: + size += int(s) + except Exception,e: + size_str += "%s%s" % (plus, s) + plus = "+" + + if pad != None: + pad_str = pad + + return [size, size_str, pad_str] + + + def print_render_header(self, f): + [size, size_str, pad_str] = self.body_size(f) + size += 4; + + if size_str == "": + s = "%u" % ((size + 3) & ~3) + elif pad_str != "": + s = "%u+%s+%s" % (size, size_str, pad_str) + else: + s = "%u+%s" % (size, size_str) + + print ' 2 %-15s rendering command length' % (s) + print ' 2 %-4u rendering command opcode' % (f.glx_rop) + return + + + def print_single_header(self, f): + [size, size_str, pad_str] = self.body_size(f) + size = ((size + 3) / 4) + 2; + + if f.glx_vendorpriv != 0: + size += 1 + + print ' 1 CARD8 opcode (X assigned)' + print ' 1 %-4u GLX opcode (%s)' % (f.opcode_real_value(), f.opcode_real_name()) + + if size_str == "": + s = "%u" % (size) + elif pad_str != "": + s = "%u+((%s+%s)/4)" % (size, size_str, pad_str) + else: + s = "%u+((%s)/4)" % (size, size_str) + + print ' 2 %-15s request length' % (s) + + if f.glx_vendorpriv != 0: + print ' 4 %-4u vendor specific opcode' % (f.opcode_value()) + + print ' 4 GLX_CONTEXT_TAG context tag' + + return + + + def print_reply(self, f): + print ' =>' + print ' 1 1 reply' + print ' 1 unused' + print ' 2 CARD16 sequence number' + + if f.output == None: + print ' 4 0 reply length' + elif f.reply_always_array: + print ' 4 m reply length' + else: + print ' 4 m reply length, m = (n == 1 ? 0 : n)' + + + output = None + for x in f.parameterIterateOutputs(): + output = x + break + + + unused = 24 + if f.return_type != 'void': + print ' 4 %-15s return value' % (f.return_type) + unused -= 4 + elif output != None: + print ' 4 unused' + unused -= 4 + + if output != None: + print ' 4 CARD32 n' + unused -= 4 + + if output != None: + if not f.reply_always_array: + print '' + print ' if (n = 1) this follows:' + print '' + print ' 4 CARD32 %s' % (output.name) + print ' %-2u unused' % (unused - 4) + print '' + print ' otherwise this follows:' + print '' + + print ' %-2u unused' % (unused) + + [s, pad] = output.packet_size() + print ' %-8s %-15s %s' % (s, output.packet_type( self.type_map ), output.name) + if pad != None: + try: + bytes = int(s) + bytes = 4 - (bytes & 3) + print ' %-8u %-15s unused' % (bytes, "") + except Exception,e: + print ' %-8s %-15s unused, %s=pad(%s)' % (pad, "", pad, s) + else: + print ' %-2u unused' % (unused) + + + def print_body(self, f): + for p in f.parameterIterateGlxSend(): + [s, pad] = p.packet_size() + print ' %-8s %-15s %s' % (s, p.packet_type( self.type_map ), p.name) + if pad != None: + try: + bytes = int(s) + bytes = 4 - (bytes & 3) + print ' %-8u %-15s unused' % (bytes, "") + except Exception,e: + print ' %-8s %-15s unused, %s=pad(%s)' % (pad, "", pad, s) + + def printBody(self, api): + self.type_map = {} + for t in api.typeIterate(): + self.type_map[ "GL" + t.name ] = t.glx_name + + + # At some point this should be expanded to support pixel + # functions, but I'm not going to lose any sleep over it now. + + for f in api.functionIterateByOffset(): + if f.client_handcode or f.server_handcode or f.vectorequiv or len(f.get_images()): + continue + + + if f.glx_rop: + print ' %s' % (f.name) + self.print_render_header(f) + elif f.glx_sop or f.glx_vendorpriv: + print ' %s' % (f.name) + self.print_single_header(f) + else: + continue + + self.print_body(f) + + if f.needs_reply(): + self.print_reply(f) + + print '' + return + + +if __name__ == '__main__': + file_name = "gl_API.xml" + + try: + (args, trail) = getopt.getopt(sys.argv[1:], "f:") + except Exception,e: + show_usage() + + for (arg,val) in args: + if arg == "-f": + file_name = val + + api = gl_XML.parse_GL_API( file_name, glx_doc_item_factory() ) + + printer = PrintGlxProtoText() + printer.Print( api ) diff --git a/mesalib/src/mesa/glapi/glX_proto_common.py b/mesalib/src/mesa/glapi/glX_proto_common.py new file mode 100644 index 000000000..6f094e22b --- /dev/null +++ b/mesalib/src/mesa/glapi/glX_proto_common.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python + +# (C) Copyright IBM Corporation 2004, 2005 +# 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 +# IBM AND/OR ITS 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 + +import gl_XML, glX_XML +import string + + +class glx_proto_item_factory(glX_XML.glx_item_factory): + """Factory to create GLX protocol oriented objects derived from gl_item.""" + + def create_item(self, name, element, context): + if name == "type": + return glx_proto_type(element, context) + else: + return glX_XML.glx_item_factory.create_item(self, name, element, context) + + +class glx_proto_type(gl_XML.gl_type): + def __init__(self, element, context): + gl_XML.gl_type.__init__(self, element, context) + + self.glx_name = element.nsProp( "glx_name", None ) + return + + +class glx_print_proto(gl_XML.gl_print_base): + def size_call(self, func, outputs_also = 0): + """Create C code to calculate 'compsize'. + + Creates code to calculate 'compsize'. If the function does + not need 'compsize' to be calculated, None will be + returned.""" + + compsize = None + + for param in func.parameterIterator(): + if outputs_also or not param.is_output: + if param.is_image(): + [dim, w, h, d, junk] = param.get_dimensions() + + compsize = '__glImageSize(%s, %s, %s, %s, %s, %s)' % (w, h, d, param.img_format, param.img_type, param.img_target) + if not param.img_send_null: + compsize = '(%s != NULL) ? %s : 0' % (param.name, compsize) + + return compsize + + elif len(param.count_parameter_list): + parameters = string.join( param.count_parameter_list, "," ) + compsize = "__gl%s_size(%s)" % (func.name, parameters) + + return compsize + + return None + + + def emit_packet_size_calculation(self, f, bias): + # compsize is only used in the command size calculation if + # the function has a non-output parameter that has a non-empty + # counter_parameter_list. + + compsize = self.size_call(f) + if compsize: + print ' const GLuint compsize = %s;' % (compsize) + + if bias: + print ' const GLuint cmdlen = %s - %u;' % (f.command_length(), bias) + else: + print ' const GLuint cmdlen = %s;' % (f.command_length()) + + #print '' + return compsize diff --git a/mesalib/src/mesa/glapi/glX_proto_recv.py b/mesalib/src/mesa/glapi/glX_proto_recv.py new file mode 100644 index 000000000..f423c6db0 --- /dev/null +++ b/mesalib/src/mesa/glapi/glX_proto_recv.py @@ -0,0 +1,554 @@ +#!/usr/bin/env python + +# (C) Copyright IBM Corporation 2005 +# 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 +# IBM AND/OR ITS 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 + +import gl_XML, glX_XML, glX_proto_common, license +import sys, getopt, string + + +class PrintGlxDispatch_h(gl_XML.gl_print_base): + def __init__(self): + gl_XML.gl_print_base.__init__(self) + + self.name = "glX_proto_recv.py (from Mesa)" + self.license = license.bsd_license_template % ( "(C) Copyright IBM Corporation 2005", "IBM") + + self.header_tag = "_INDIRECT_DISPATCH_H_" + return + + + def printRealHeader(self): + self.printVisibility( "HIDDEN", "hidden" ) + print 'struct __GLXclientStateRec;' + print '' + return + + + def printBody(self, api): + for func in api.functionIterateAll(): + if not func.ignore and not func.vectorequiv: + if func.glx_rop: + print 'extern HIDDEN void __glXDisp_%s(GLbyte * pc);' % (func.name) + print 'extern HIDDEN void __glXDispSwap_%s(GLbyte * pc);' % (func.name) + elif func.glx_sop or func.glx_vendorpriv: + print 'extern HIDDEN int __glXDisp_%s(struct __GLXclientStateRec *, GLbyte *);' % (func.name) + print 'extern HIDDEN int __glXDispSwap_%s(struct __GLXclientStateRec *, GLbyte *);' % (func.name) + + if func.glx_sop and func.glx_vendorpriv: + n = func.glx_vendorpriv_names[0] + print 'extern HIDDEN int __glXDisp_%s(struct __GLXclientStateRec *, GLbyte *);' % (n) + print 'extern HIDDEN int __glXDispSwap_%s(struct __GLXclientStateRec *, GLbyte *);' % (n) + + return + + +class PrintGlxDispatchFunctions(glX_proto_common.glx_print_proto): + def __init__(self, do_swap): + gl_XML.gl_print_base.__init__(self) + self.name = "glX_proto_recv.py (from Mesa)" + self.license = license.bsd_license_template % ( "(C) Copyright IBM Corporation 2005", "IBM") + + self.real_types = [ '', '', 'uint16_t', '', 'uint32_t', '', '', '', 'uint64_t' ] + self.do_swap = do_swap + return + + + def printRealHeader(self): + print '#include ' + print '#include ' + print '#include ' + + print '#include ' + print '#include "indirect_size.h"' + print '#include "indirect_size_get.h"' + print '#include "indirect_dispatch.h"' + print '#include "glxserver.h"' + print '#include "glxbyteorder.h"' + print '#include "indirect_util.h"' + print '#include "singlesize.h"' + print '#include "glapi.h"' + print '#include "glapitable.h"' + print '#include "glthread.h"' + print '#include "dispatch.h"' + print '' + print '#define __GLX_PAD(x) (((x) + 3) & ~3)' + print '' + print 'typedef struct {' + print ' __GLX_PIXEL_3D_HDR;' + print '} __GLXpixel3DHeader;' + print '' + print 'extern GLboolean __glXErrorOccured( void );' + print 'extern void __glXClearErrorOccured( void );' + print '' + print 'static const unsigned dummy_answer[2] = {0, 0};' + print '' + return + + + def printBody(self, api): + if self.do_swap: + self.emit_swap_wrappers(api) + + + for func in api.functionIterateByOffset(): + if not func.ignore and not func.server_handcode and not func.vectorequiv and (func.glx_rop or func.glx_sop or func.glx_vendorpriv): + self.printFunction(func, func.name) + if func.glx_sop and func.glx_vendorpriv: + self.printFunction(func, func.glx_vendorpriv_names[0]) + + + return + + + def printFunction(self, f, name): + if (f.glx_sop or f.glx_vendorpriv) and (len(f.get_images()) != 0): + return + + if not self.do_swap: + base = '__glXDisp' + else: + base = '__glXDispSwap' + + if f.glx_rop: + print 'void %s_%s(GLbyte * pc)' % (base, name) + else: + print 'int %s_%s(__GLXclientState *cl, GLbyte *pc)' % (base, name) + + print '{' + + if f.glx_rop or f.vectorequiv: + self.printRenderFunction(f) + elif f.glx_sop or f.glx_vendorpriv: + if len(f.get_images()) == 0: + self.printSingleFunction(f, name) + else: + print "/* Missing GLX protocol for %s. */" % (name) + + print '}' + print '' + return + + + def swap_name(self, bytes): + return 'bswap_%u_array' % (8 * bytes) + + + def emit_swap_wrappers(self, api): + self.type_map = {} + already_done = [ ] + + for t in api.typeIterate(): + te = t.get_type_expression() + t_size = te.get_element_size() + + if t_size > 1 and t.glx_name: + + t_name = "GL" + t.name + self.type_map[ t_name ] = t.glx_name + + if t.glx_name not in already_done: + real_name = self.real_types[t_size] + + print 'static %s' % (t_name) + print 'bswap_%s( const void * src )' % (t.glx_name) + print '{' + print ' union { %s dst; %s ret; } x;' % (real_name, t_name) + print ' x.dst = bswap_%u( *(%s *) src );' % (t_size * 8, real_name) + print ' return x.ret;' + print '}' + print '' + already_done.append( t.glx_name ) + + for bits in [16, 32, 64]: + print 'static void *' + print 'bswap_%u_array( uint%u_t * src, unsigned count )' % (bits, bits) + print '{' + print ' unsigned i;' + print '' + print ' for ( i = 0 ; i < count ; i++ ) {' + print ' uint%u_t temp = bswap_%u( src[i] );' % (bits, bits) + print ' src[i] = temp;' + print ' }' + print '' + print ' return src;' + print '}' + print '' + + + def fetch_param(self, param): + t = param.type_string() + o = param.offset + element_size = param.size() / param.get_element_count() + + if self.do_swap and (element_size != 1): + if param.is_array(): + real_name = self.real_types[ element_size ] + + swap_func = self.swap_name( element_size ) + return ' (%-8s)%s( (%s *) (pc + %2s), %s )' % (t, swap_func, real_name, o, param.count) + else: + t_name = param.get_base_type_string() + return ' (%-8s)bswap_%-7s( pc + %2s )' % (t, self.type_map[ t_name ], o) + else: + if param.is_array(): + return ' (%-8s)(pc + %2u)' % (t, o) + else: + return '*(%-8s *)(pc + %2u)' % (t, o) + + return None + + + def emit_function_call(self, f, retval_assign, indent): + list = [] + + for param in f.parameterIterator(): + if param.is_padding: + continue + + if param.is_counter or param.is_image() or param.is_output or param.name in f.count_parameter_list or len(param.count_parameter_list): + location = param.name + else: + location = self.fetch_param(param) + + list.append( '%s %s' % (indent, location) ) + + + if len( list ): + print '%s %sCALL_%s( GET_DISPATCH(), (' % (indent, retval_assign, f.name) + print string.join( list, ",\n" ) + print '%s ) );' % (indent) + else: + print '%s %sCALL_%s( GET_DISPATCH(), () );' % (indent, retval_assign, f.name) + return + + + def common_func_print_just_start(self, f, indent): + align64 = 0 + need_blank = 0 + + + f.calculate_offsets() + for param in f.parameterIterateGlxSend(): + # If any parameter has a 64-bit base type, then we + # have to do alignment magic for the while thing. + + if param.is_64_bit(): + align64 = 1 + + + # FIXME img_null_flag is over-loaded. In addition to + # FIXME being used for images, it is used to signify + # FIXME NULL data pointers for vertex buffer object + # FIXME related functions. Re-name it to null_data + # FIXME or something similar. + + if param.img_null_flag: + print '%s const CARD32 ptr_is_null = *(CARD32 *)(pc + %s);' % (indent, param.offset - 4) + cond = '(ptr_is_null != 0) ? NULL : ' + else: + cond = "" + + + type_string = param.type_string() + + if param.is_image(): + offset = f.offset_of( param.name ) + + print '%s %s const %s = (%s) (%s(pc + %s));' % (indent, type_string, param.name, type_string, cond, offset) + + if param.depth: + print '%s __GLXpixel3DHeader * const hdr = (__GLXpixel3DHeader *)(pc);' % (indent) + else: + print '%s __GLXpixelHeader * const hdr = (__GLXpixelHeader *)(pc);' % (indent) + + need_blank = 1 + elif param.is_counter or param.name in f.count_parameter_list: + location = self.fetch_param(param) + print '%s const %s %s = %s;' % (indent, type_string, param.name, location) + need_blank = 1 + elif len(param.count_parameter_list): + if param.size() == 1 and not self.do_swap: + location = self.fetch_param(param) + print '%s %s %s = %s%s;' % (indent, type_string, param.name, cond, location) + else: + print '%s %s %s;' % (indent, type_string, param.name) + need_blank = 1 + + + + if need_blank: + print '' + + if align64: + print '#ifdef __GLX_ALIGN64' + + if f.has_variable_size_request(): + self.emit_packet_size_calculation(f, 4) + s = "cmdlen" + else: + s = str((f.command_fixed_length() + 3) & ~3) + + print ' if ((unsigned long)(pc) & 7) {' + print ' (void) memmove(pc-4, pc, %s);' % (s) + print ' pc -= 4;' + print ' }' + print '#endif' + print '' + + + need_blank = 0 + if self.do_swap: + for param in f.parameterIterateGlxSend(): + if param.count_parameter_list: + o = param.offset + count = param.get_element_count() + type_size = param.size() / count + + if param.counter: + count_name = param.counter + else: + count_name = str(count) + + # This is basically an ugly special- + # case for glCallLists. + + if type_size == 1: + x = [] + x.append( [1, ['BYTE', 'UNSIGNED_BYTE', '2_BYTES', '3_BYTES', '4_BYTES']] ) + x.append( [2, ['SHORT', 'UNSIGNED_SHORT']] ) + x.append( [4, ['INT', 'UNSIGNED_INT', 'FLOAT']] ) + + print ' switch(%s) {' % (param.count_parameter_list[0]) + for sub in x: + for t_name in sub[1]: + print ' case GL_%s:' % (t_name) + + if sub[0] == 1: + print ' %s = (%s) (pc + %s); break;' % (param.name, param.type_string(), o) + else: + swap_func = self.swap_name(sub[0]) + print ' %s = (%s) %s( (%s *) (pc + %s), %s ); break;' % (param.name, param.type_string(), swap_func, self.real_types[sub[0]], o, count_name) + print ' default:' + print ' return;' + print ' }' + else: + swap_func = self.swap_name(type_size) + compsize = self.size_call(f, 1) + print ' %s = (%s) %s( (%s *) (pc + %s), %s );' % (param.name, param.type_string(), swap_func, self.real_types[type_size], o, compsize) + + need_blank = 1 + + else: + for param in f.parameterIterateGlxSend(): + if param.count_parameter_list: + print '%s %s = (%s) (pc + %s);' % (indent, param.name, param.type_string(), param.offset) + need_blank = 1 + + + if need_blank: + print '' + + + return + + + def printSingleFunction(self, f, name): + if name not in f.glx_vendorpriv_names: + print ' xGLXSingleReq * const req = (xGLXSingleReq *) pc;' + else: + print ' xGLXVendorPrivateReq * const req = (xGLXVendorPrivateReq *) pc;' + + print ' int error;' + + if self.do_swap: + print ' __GLXcontext * const cx = __glXForceCurrent(cl, bswap_CARD32( &req->contextTag ), &error);' + else: + print ' __GLXcontext * const cx = __glXForceCurrent(cl, req->contextTag, &error);' + + print '' + if name not in f.glx_vendorpriv_names: + print ' pc += __GLX_SINGLE_HDR_SIZE;' + else: + print ' pc += __GLX_VENDPRIV_HDR_SIZE;' + + print ' if ( cx != NULL ) {' + self.common_func_print_just_start(f, " ") + + + if f.return_type != 'void': + print ' %s retval;' % (f.return_type) + retval_string = "retval" + retval_assign = "retval = " + else: + retval_string = "0" + retval_assign = "" + + + type_size = 0 + answer_string = "dummy_answer" + answer_count = "0" + is_array_string = "GL_FALSE" + + for param in f.parameterIterateOutputs(): + answer_type = param.get_base_type_string() + if answer_type == "GLvoid": + answer_type = "GLubyte" + + + c = param.get_element_count() + type_size = (param.size() / c) + if type_size == 1: + size_scale = "" + else: + size_scale = " * %u" % (type_size) + + + if param.count_parameter_list: + print ' const GLuint compsize = %s;' % (self.size_call(f, 1)) + print ' %s answerBuffer[200];' % (answer_type) + print ' %s %s = __glXGetAnswerBuffer(cl, compsize%s, answerBuffer, sizeof(answerBuffer), %u);' % (param.type_string(), param.name, size_scale, type_size ) + answer_string = param.name + answer_count = "compsize" + + print '' + print ' if (%s == NULL) return BadAlloc;' % (param.name) + print ' __glXClearErrorOccured();' + print '' + elif param.counter: + print ' %s answerBuffer[200];' % (answer_type) + print ' %s %s = __glXGetAnswerBuffer(cl, %s%s, answerBuffer, sizeof(answerBuffer), %u);' % (param.type_string(), param.name, param.counter, size_scale, type_size) + answer_string = param.name + answer_count = param.counter + elif c >= 1: + print ' %s %s[%u];' % (answer_type, param.name, c) + answer_string = param.name + answer_count = "%u" % (c) + + if f.reply_always_array: + is_array_string = "GL_TRUE" + + + self.emit_function_call(f, retval_assign, " ") + + + if f.needs_reply(): + if self.do_swap: + for param in f.parameterIterateOutputs(): + c = param.get_element_count() + type_size = (param.size() / c) + + if type_size > 1: + swap_name = self.swap_name( type_size ) + print ' (void) %s( (uint%u_t *) %s, %s );' % (swap_name, 8 * type_size, param.name, answer_count) + + + reply_func = '__glXSendReplySwap' + else: + reply_func = '__glXSendReply' + + print ' %s(cl->client, %s, %s, %u, %s, %s);' % (reply_func, answer_string, answer_count, type_size, is_array_string, retval_string) + #elif f.note_unflushed: + # print ' cx->hasUnflushedCommands = GL_TRUE;' + + print ' error = Success;' + print ' }' + print '' + print ' return error;' + return + + + def printRenderFunction(self, f): + # There are 4 distinct phases in a rendering dispatch function. + # In the first phase we compute the sizes and offsets of each + # element in the command. In the second phase we (optionally) + # re-align 64-bit data elements. In the third phase we + # (optionally) byte-swap array data. Finally, in the fourth + # phase we actually dispatch the function. + + self.common_func_print_just_start(f, "") + + images = f.get_images() + if len(images): + if self.do_swap: + pre = "bswap_CARD32( & " + post = " )" + else: + pre = "" + post = "" + + img = images[0] + + # swapBytes and lsbFirst are single byte fields, so + # the must NEVER be byte-swapped. + + if not (img.img_type == "GL_BITMAP" and img.img_format == "GL_COLOR_INDEX"): + print ' CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SWAP_BYTES, hdr->swapBytes) );' + + print ' CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_LSB_FIRST, hdr->lsbFirst) );' + + print ' CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_ROW_LENGTH, (GLint) %shdr->rowLength%s) );' % (pre, post) + if img.depth: + print ' CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_IMAGE_HEIGHT, (GLint) %shdr->imageHeight%s) );' % (pre, post) + print ' CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SKIP_ROWS, (GLint) %shdr->skipRows%s) );' % (pre, post) + if img.depth: + print ' CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SKIP_IMAGES, (GLint) %shdr->skipImages%s) );' % (pre, post) + print ' CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SKIP_PIXELS, (GLint) %shdr->skipPixels%s) );' % (pre, post) + print ' CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_ALIGNMENT, (GLint) %shdr->alignment%s) );' % (pre, post) + print '' + + + self.emit_function_call(f, "", "") + return + + +if __name__ == '__main__': + file_name = "gl_API.xml" + + try: + (args, trail) = getopt.getopt(sys.argv[1:], "f:m:s") + except Exception,e: + show_usage() + + mode = "dispatch_c" + do_swap = 0 + for (arg,val) in args: + if arg == "-f": + file_name = val + elif arg == "-m": + mode = val + elif arg == "-s": + do_swap = 1 + + if mode == "dispatch_c": + printer = PrintGlxDispatchFunctions(do_swap) + elif mode == "dispatch_h": + printer = PrintGlxDispatch_h() + else: + show_usage() + + api = gl_XML.parse_GL_API( file_name, glX_proto_common.glx_proto_item_factory() ) + + printer.Print( api ) diff --git a/mesalib/src/mesa/glapi/glX_proto_send.py b/mesalib/src/mesa/glapi/glX_proto_send.py new file mode 100644 index 000000000..daca1b767 --- /dev/null +++ b/mesalib/src/mesa/glapi/glX_proto_send.py @@ -0,0 +1,1042 @@ +#!/usr/bin/env python + +# (C) Copyright IBM Corporation 2004, 2005 +# 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 +# IBM AND/OR ITS 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 +# Jeremy Kolb + +import gl_XML, glX_XML, glX_proto_common, license +import sys, getopt, copy, string + +def convertStringForXCB(str): + tmp = "" + special = [ "ARB" ] + i = 0 + while i < len(str): + if str[i:i+3] in special: + tmp = '%s_%s' % (tmp, string.lower(str[i:i+3])) + i = i + 2; + elif str[i].isupper(): + tmp = '%s_%s' % (tmp, string.lower(str[i])) + else: + tmp = '%s%s' % (tmp, str[i]) + i += 1 + return tmp + +def hash_pixel_function(func): + """Generate a 'unique' key for a pixel function. The key is based on + the parameters written in the command packet. This includes any + padding that might be added for the original function and the 'NULL + image' flag.""" + + + h = "" + hash_pre = "" + hash_suf = "" + for param in func.parameterIterateGlxSend(): + if param.is_image(): + [dim, junk, junk, junk, junk] = param.get_dimensions() + + d = (dim + 1) & ~1 + hash_pre = "%uD%uD_" % (d - 1, d) + + if param.img_null_flag: + hash_suf = "_NF" + + h += "%u" % (param.size()) + + if func.pad_after(param): + h += "4" + + + n = func.name.replace("%uD" % (dim), "") + n = "__glx_%s_%uD%uD" % (n, d - 1, d) + + h = hash_pre + h + hash_suf + return [h, n] + + +class glx_pixel_function_stub(glX_XML.glx_function): + """Dummy class used to generate pixel "utility" functions that are + shared by multiple dimension image functions. For example, these + objects are used to generate shared functions used to send GLX + protocol for TexImage1D and TexImage2D, TexSubImage1D and + TexSubImage2D, etc.""" + + def __init__(self, func, name): + # The parameters to the utility function are the same as the + # parameters to the real function except for the added "pad" + # parameters. + + self.name = name + self.images = [] + self.parameters = [] + self.parameters_by_name = {} + for _p in func.parameterIterator(): + p = copy.copy(_p) + self.parameters.append(p) + self.parameters_by_name[ p.name ] = p + + + if p.is_image(): + self.images.append(p) + p.height = "height" + + if p.img_yoff == None: + p.img_yoff = "yoffset" + + if p.depth: + if p.extent == None: + p.extent = "extent" + + if p.img_woff == None: + p.img_woff = "woffset" + + + pad_name = func.pad_after(p) + if pad_name: + pad = copy.copy(p) + pad.name = pad_name + self.parameters.append(pad) + self.parameters_by_name[ pad.name ] = pad + + + self.return_type = func.return_type + + self.glx_rop = ~0 + self.glx_sop = 0 + self.glx_vendorpriv = 0 + + self.glx_doubles_in_order = func.glx_doubles_in_order + + self.vectorequiv = None + self.output = None + self.can_be_large = func.can_be_large + self.reply_always_array = func.reply_always_array + self.dimensions_in_reply = func.dimensions_in_reply + self.img_reset = None + + self.server_handcode = 0 + self.client_handcode = 0 + self.ignore = 0 + + self.count_parameter_list = func.count_parameter_list + self.counter_list = func.counter_list + self.offsets_calculated = 0 + return + + +class PrintGlxProtoStubs(glX_proto_common.glx_print_proto): + def __init__(self): + glX_proto_common.glx_print_proto.__init__(self) + self.name = "glX_proto_send.py (from Mesa)" + self.license = license.bsd_license_template % ( "(C) Copyright IBM Corporation 2004, 2005", "IBM") + + + self.last_category = "" + self.generic_sizes = [3, 4, 6, 8, 12, 16, 24, 32] + self.pixel_stubs = {} + self.debug = 0 + return + + def printRealHeader(self): + print '' + print '#include ' + print '#include "indirect.h"' + print '#include "glxclient.h"' + print '#include "indirect_size.h"' + print '#include "dispatch.h"' + print '#include "glapi.h"' + print '#include "glthread.h"' + print '#include ' + print '#ifdef USE_XCB' + print '#include ' + print '#include ' + print '#include ' + print '#endif /* USE_XCB */' + + print '' + print '#define __GLX_PAD(n) (((n) + 3) & ~3)' + print '' + self.printFastcall() + self.printNoinline() + print '' + print '#if !defined __GNUC__ || __GNUC__ < 3' + print '# define __builtin_expect(x, y) x' + print '#endif' + print '' + print '/* If the size and opcode values are known at compile-time, this will, on' + print ' * x86 at least, emit them with a single instruction.' + print ' */' + print '#define emit_header(dest, op, size) \\' + print ' do { union { short s[2]; int i; } temp; \\' + print ' temp.s[0] = (size); temp.s[1] = (op); \\' + print ' *((int *)(dest)) = temp.i; } while(0)' + print '' + print """NOINLINE CARD32 +__glXReadReply( Display *dpy, size_t size, void * dest, GLboolean reply_is_always_array ) +{ + xGLXSingleReply reply; + + (void) _XReply(dpy, (xReply *) & reply, 0, False); + if (size != 0) { + if ((reply.length > 0) || reply_is_always_array) { + const GLint bytes = (reply_is_always_array) + ? (4 * reply.length) : (reply.size * size); + const GLint extra = 4 - (bytes & 3); + + _XRead(dpy, dest, bytes); + if ( extra < 4 ) { + _XEatData(dpy, extra); + } + } + else { + (void) memcpy( dest, &(reply.pad3), size); + } + } + + return reply.retval; +} + +NOINLINE void +__glXReadPixelReply( Display *dpy, __GLXcontext * gc, unsigned max_dim, + GLint width, GLint height, GLint depth, GLenum format, GLenum type, + void * dest, GLboolean dimensions_in_reply ) +{ + xGLXSingleReply reply; + GLint size; + + (void) _XReply(dpy, (xReply *) & reply, 0, False); + + if ( dimensions_in_reply ) { + width = reply.pad3; + height = reply.pad4; + depth = reply.pad5; + + if ((height == 0) || (max_dim < 2)) { height = 1; } + if ((depth == 0) || (max_dim < 3)) { depth = 1; } + } + + size = reply.length * 4; + if (size != 0) { + void * buf = Xmalloc( size ); + + if ( buf == NULL ) { + _XEatData(dpy, size); + __glXSetError(gc, GL_OUT_OF_MEMORY); + } + else { + const GLint extra = 4 - (size & 3); + + _XRead(dpy, buf, size); + if ( extra < 4 ) { + _XEatData(dpy, extra); + } + + __glEmptyImage(gc, 3, width, height, depth, format, type, + buf, dest); + Xfree(buf); + } + } +} + +#define X_GLXSingle 0 + +NOINLINE FASTCALL GLubyte * +__glXSetupSingleRequest( __GLXcontext * gc, GLint sop, GLint cmdlen ) +{ + xGLXSingleReq * req; + Display * const dpy = gc->currentDpy; + + (void) __glXFlushRenderBuffer(gc, gc->pc); + LockDisplay(dpy); + GetReqExtra(GLXSingle, cmdlen, req); + req->reqType = gc->majorOpcode; + req->contextTag = gc->currentContextTag; + req->glxCode = sop; + return (GLubyte *)(req) + sz_xGLXSingleReq; +} + +NOINLINE FASTCALL GLubyte * +__glXSetupVendorRequest( __GLXcontext * gc, GLint code, GLint vop, GLint cmdlen ) +{ + xGLXVendorPrivateReq * req; + Display * const dpy = gc->currentDpy; + + (void) __glXFlushRenderBuffer(gc, gc->pc); + LockDisplay(dpy); + GetReqExtra(GLXVendorPrivate, cmdlen, req); + req->reqType = gc->majorOpcode; + req->glxCode = code; + req->vendorCode = vop; + req->contextTag = gc->currentContextTag; + return (GLubyte *)(req) + sz_xGLXVendorPrivateReq; +} + +const GLuint __glXDefaultPixelStore[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 1 }; + +#define zero (__glXDefaultPixelStore+0) +#define one (__glXDefaultPixelStore+8) +#define default_pixel_store_1D (__glXDefaultPixelStore+4) +#define default_pixel_store_1D_size 20 +#define default_pixel_store_2D (__glXDefaultPixelStore+4) +#define default_pixel_store_2D_size 20 +#define default_pixel_store_3D (__glXDefaultPixelStore+0) +#define default_pixel_store_3D_size 36 +#define default_pixel_store_4D (__glXDefaultPixelStore+0) +#define default_pixel_store_4D_size 36 +""" + + for size in self.generic_sizes: + self.print_generic_function(size) + return + + + def printBody(self, api): + + self.pixel_stubs = {} + generated_stubs = [] + + for func in api.functionIterateGlx(): + if func.client_handcode: continue + + # If the function is a pixel function with a certain + # GLX protocol signature, create a fake stub function + # for it. For example, create a single stub function + # that is used to implement both glTexImage1D and + # glTexImage2D. + + if func.glx_rop != 0: + do_it = 0 + for image in func.get_images(): + if image.img_pad_dimensions: + do_it = 1 + break + + + if do_it: + [h, n] = hash_pixel_function(func) + + + self.pixel_stubs[ func.name ] = n + if h not in generated_stubs: + generated_stubs.append(h) + + fake_func = glx_pixel_function_stub( func, n ) + self.printFunction(fake_func, fake_func.name) + + + self.printFunction(func, func.name) + if func.glx_sop and func.glx_vendorpriv: + self.printFunction(func, func.glx_vendorpriv_names[0]) + + return + + + def printFunction(self, func, name): + footer = '}\n' + if func.glx_rop == ~0: + print 'static %s' % (func.return_type) + print '%s( unsigned opcode, unsigned dim, %s )' % (func.name, func.get_parameter_string()) + print '{' + else: + if func.has_different_protocol(name): + if func.return_type == "void": + ret_string = '' + else: + ret_string = "return " + + func_name = func.static_glx_name(name) + print '#define %s %d' % (func.opcode_vendor_name(name), func.glx_vendorpriv) + print '%s gl%s(%s)' % (func.return_type, func_name, func.get_parameter_string()) + print '{' + print ' __GLXcontext * const gc = __glXGetCurrentContext();' + print '' + print '#ifdef GLX_DIRECT_RENDERING' + print ' if (gc->driContext) {' + print ' %sCALL_%s(GET_DISPATCH(), (%s));' % (ret_string, func.name, func.get_called_parameter_string()) + print ' } else' + print '#endif' + print ' {' + + footer = '}\n}\n' + else: + print '#define %s %d' % (func.opcode_name(), func.opcode_value()) + + print '%s __indirect_gl%s(%s)' % (func.return_type, name, func.get_parameter_string()) + print '{' + + + if func.glx_rop != 0 or func.vectorequiv != None: + if len(func.images): + self.printPixelFunction(func) + else: + self.printRenderFunction(func) + elif func.glx_sop != 0 or func.glx_vendorpriv != 0: + self.printSingleFunction(func, name) + pass + else: + print "/* Missing GLX protocol for %s. */" % (name) + + print footer + return + + + def print_generic_function(self, n): + size = (n + 3) & ~3 + print """static FASTCALL NOINLINE void +generic_%u_byte( GLint rop, const void * ptr ) +{ + __GLXcontext * const gc = __glXGetCurrentContext(); + const GLuint cmdlen = %u; + + emit_header(gc->pc, rop, cmdlen); + (void) memcpy((void *)(gc->pc + 4), ptr, %u); + gc->pc += cmdlen; + if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); } +} +""" % (n, size + 4, size) + return + + + def common_emit_one_arg(self, p, pc, adjust, extra_offset): + if p.is_array(): + src_ptr = p.name + else: + src_ptr = "&" + p.name + + if p.is_padding: + print '(void) memset((void *)(%s + %u), 0, %s);' \ + % (pc, p.offset + adjust, p.size_string() ) + elif not extra_offset: + print '(void) memcpy((void *)(%s + %u), (void *)(%s), %s);' \ + % (pc, p.offset + adjust, src_ptr, p.size_string() ) + else: + print '(void) memcpy((void *)(%s + %u + %s), (void *)(%s), %s);' \ + % (pc, p.offset + adjust, extra_offset, src_ptr, p.size_string() ) + + def common_emit_args(self, f, pc, adjust, skip_vla): + extra_offset = None + + for p in f.parameterIterateGlxSend( not skip_vla ): + if p.name != f.img_reset: + self.common_emit_one_arg(p, pc, adjust, extra_offset) + + if p.is_variable_length(): + temp = p.size_string() + if extra_offset: + extra_offset += " + %s" % (temp) + else: + extra_offset = temp + + return + + + def pixel_emit_args(self, f, pc, large): + """Emit the arguments for a pixel function. This differs from + common_emit_args in that pixel functions may require padding + be inserted (i.e., for the missing width field for + TexImage1D), and they may also require a 'NULL image' flag + be inserted before the image data.""" + + if large: + adjust = 8 + else: + adjust = 4 + + for param in f.parameterIterateGlxSend(): + if not param.is_image(): + self.common_emit_one_arg(param, pc, adjust, None) + + if f.pad_after(param): + print '(void) memcpy((void *)(%s + %u), zero, 4);' % (pc, (param.offset + param.size()) + adjust) + + else: + [dim, width, height, depth, extent] = param.get_dimensions() + if f.glx_rop == ~0: + dim_str = "dim" + else: + dim_str = str(dim) + + if param.is_padding: + print '(void) memset((void *)(%s + %u), 0, %s);' \ + % (pc, (param.offset - 4) + adjust, param.size_string() ) + + if param.img_null_flag: + if large: + print '(void) memcpy((void *)(%s + %u), zero, 4);' % (pc, (param.offset - 4) + adjust) + else: + print '(void) memcpy((void *)(%s + %u), (void *)((%s == NULL) ? one : zero), 4);' % (pc, (param.offset - 4) + adjust, param.name) + + + pixHeaderPtr = "%s + %u" % (pc, adjust) + pcPtr = "%s + %u" % (pc, param.offset + adjust) + + if not large: + if param.img_send_null: + condition = '(compsize > 0) && (%s != NULL)' % (param.name) + else: + condition = 'compsize > 0' + + print 'if (%s) {' % (condition) + print ' (*gc->fillImage)(gc, %s, %s, %s, %s, %s, %s, %s, %s, %s);' % (dim_str, width, height, depth, param.img_format, param.img_type, param.name, pcPtr, pixHeaderPtr) + print '} else {' + print ' (void) memcpy( %s, default_pixel_store_%uD, default_pixel_store_%uD_size );' % (pixHeaderPtr, dim, dim) + print '}' + else: + print '__glXSendLargeImage(gc, compsize, %s, %s, %s, %s, %s, %s, %s, %s, %s);' % (dim_str, width, height, depth, param.img_format, param.img_type, param.name, pcPtr, pixHeaderPtr) + + return + + + def large_emit_begin(self, f, op_name = None): + if not op_name: + op_name = f.opcode_real_name() + + print 'const GLint op = %s;' % (op_name) + print 'const GLuint cmdlenLarge = cmdlen + 4;' + print 'GLubyte * const pc = __glXFlushRenderBuffer(gc, gc->pc);' + print '(void) memcpy((void *)(pc + 0), (void *)(&cmdlenLarge), 4);' + print '(void) memcpy((void *)(pc + 4), (void *)(&op), 4);' + return + + + def common_func_print_just_start(self, f, name): + print ' __GLXcontext * const gc = __glXGetCurrentContext();' + + # The only reason that single and vendor private commands need + # a variable called 'dpy' is becuase they use the SyncHandle + # macro. For whatever brain-dead reason, that macro is hard- + # coded to use a variable called 'dpy' instead of taking a + # parameter. + + # FIXME Simplify the logic related to skip_condition and + # FIXME condition_list in this function. Basically, remove + # FIXME skip_condition, and just append the "dpy != NULL" type + # FIXME condition to condition_list from the start. The only + # FIXME reason it's done in this confusing way now is to + # FIXME minimize the diffs in the generated code. + + if not f.glx_rop: + for p in f.parameterIterateOutputs(): + if p.is_image() and (p.img_format != "GL_COLOR_INDEX" or p.img_type != "GL_BITMAP"): + print ' const __GLXattribute * const state = gc->client_state_private;' + break + + print ' Display * const dpy = gc->currentDpy;' + skip_condition = "dpy != NULL" + elif f.can_be_large: + skip_condition = "gc->currentDpy != NULL" + else: + skip_condition = None + + + if f.return_type != 'void': + print ' %s retval = (%s) 0;' % (f.return_type, f.return_type) + + + if name != None and name not in f.glx_vendorpriv_names: + print '#ifndef USE_XCB' + self.emit_packet_size_calculation(f, 0) + if name != None and name not in f.glx_vendorpriv_names: + print '#endif' + + condition_list = [] + for p in f.parameterIterateCounters(): + condition_list.append( "%s >= 0" % (p.name) ) + # 'counter' parameters cannot be negative + print " if (%s < 0) {" % p.name + print " __glXSetError(gc, GL_INVALID_VALUE);" + if f.return_type != 'void': + print " return 0;" + else: + print " return;" + print " }" + + if skip_condition: + condition_list.append( skip_condition ) + + if len( condition_list ) > 0: + if len( condition_list ) > 1: + skip_condition = "(%s)" % (string.join( condition_list, ") && (" )) + else: + skip_condition = "%s" % (condition_list.pop(0)) + + print ' if (__builtin_expect(%s, 1)) {' % (skip_condition) + return 1 + else: + return 0 + + + def printSingleFunction(self, f, name): + self.common_func_print_just_start(f, name) + + if self.debug: + print ' printf( "Enter %%s...\\n", "gl%s" );' % (f.name) + + if name not in f.glx_vendorpriv_names: + + # XCB specific: + print '#ifdef USE_XCB' + if self.debug: + print ' printf("\\tUsing XCB.\\n");' + print ' xcb_connection_t *c = XGetXCBConnection(dpy);' + print ' (void) __glXFlushRenderBuffer(gc, gc->pc);' + xcb_name = 'xcb_glx%s' % convertStringForXCB(name) + + iparams=[] + extra_iparams = [] + output = None + for p in f.parameterIterator(): + if p.is_output: + output = p + + if p.is_image(): + if p.img_format != "GL_COLOR_INDEX" or p.img_type != "GL_BITMAP": + extra_iparams.append("state->storePack.swapEndian") + else: + extra_iparams.append("0") + + # Hardcode this in. lsb_first param (apparently always GL_FALSE) + # also present in GetPolygonStipple, but taken care of above. + if xcb_name == "xcb_glx_read_pixels": + extra_iparams.append("0") + else: + iparams.append(p.name) + + + xcb_request = '%s(%s)' % (xcb_name, ", ".join(["c", "gc->currentContextTag"] + iparams + extra_iparams)) + + if f.needs_reply(): + print ' %s_reply_t *reply = %s_reply(c, %s, NULL);' % (xcb_name, xcb_name, xcb_request) + if output and f.reply_always_array: + print ' (void)memcpy(%s, %s_data(reply), %s_data_length(reply) * sizeof(%s));' % (output.name, xcb_name, xcb_name, output.get_base_type_string()) + + elif output and not f.reply_always_array: + if not output.is_image(): + print ' if (%s_data_length(reply) == 0)' % (xcb_name) + print ' (void)memcpy(%s, &reply->datum, sizeof(reply->datum));' % (output.name) + print ' else' + print ' (void)memcpy(%s, %s_data(reply), %s_data_length(reply) * sizeof(%s));' % (output.name, xcb_name, xcb_name, output.get_base_type_string()) + + + if f.return_type != 'void': + print ' retval = reply->ret_val;' + print ' free(reply);' + else: + print ' ' + xcb_request + ';' + print '#else' + # End of XCB specific. + + + if f.parameters != []: + pc_decl = "GLubyte const * pc =" + else: + pc_decl = "(void)" + + if name in f.glx_vendorpriv_names: + print ' %s __glXSetupVendorRequest(gc, %s, %s, cmdlen);' % (pc_decl, f.opcode_real_name(), f.opcode_vendor_name(name)) + else: + print ' %s __glXSetupSingleRequest(gc, %s, cmdlen);' % (pc_decl, f.opcode_name()) + + self.common_emit_args(f, "pc", 0, 0) + + images = f.get_images() + + for img in images: + if img.is_output: + o = f.command_fixed_length() - 4 + print ' *(int32_t *)(pc + %u) = 0;' % (o) + if img.img_format != "GL_COLOR_INDEX" or img.img_type != "GL_BITMAP": + print ' * (int8_t *)(pc + %u) = state->storePack.swapEndian;' % (o) + + if f.img_reset: + print ' * (int8_t *)(pc + %u) = %s;' % (o + 1, f.img_reset) + + + return_name = '' + if f.needs_reply(): + if f.return_type != 'void': + return_name = " retval" + return_str = " retval = (%s)" % (f.return_type) + else: + return_str = " (void)" + + got_reply = 0 + + for p in f.parameterIterateOutputs(): + if p.is_image(): + [dim, w, h, d, junk] = p.get_dimensions() + if f.dimensions_in_reply: + print " __glXReadPixelReply(dpy, gc, %u, 0, 0, 0, %s, %s, %s, GL_TRUE);" % (dim, p.img_format, p.img_type, p.name) + else: + print " __glXReadPixelReply(dpy, gc, %u, %s, %s, %s, %s, %s, %s, GL_FALSE);" % (dim, w, h, d, p.img_format, p.img_type, p.name) + + got_reply = 1 + else: + if f.reply_always_array: + aa = "GL_TRUE" + else: + aa = "GL_FALSE" + + # gl_parameter.size() returns the size + # of the entire data item. If the + # item is a fixed-size array, this is + # the size of the whole array. This + # is not what __glXReadReply wants. It + # wants the size of a single data + # element in the reply packet. + # Dividing by the array size (1 for + # non-arrays) gives us this. + + s = p.size() / p.get_element_count() + print " %s __glXReadReply(dpy, %s, %s, %s);" % (return_str, s, p.name, aa) + got_reply = 1 + + + # If a reply wasn't read to fill an output parameter, + # read a NULL reply to get the return value. + + if not got_reply: + print " %s __glXReadReply(dpy, 0, NULL, GL_FALSE);" % (return_str) + + + elif self.debug: + # Only emit the extra glFinish call for functions + # that don't already require a reply from the server. + print ' __indirect_glFinish();' + + if self.debug: + print ' printf( "Exit %%s.\\n", "gl%s" );' % (name) + + + print ' UnlockDisplay(dpy); SyncHandle();' + + if name not in f.glx_vendorpriv_names: + print '#endif /* USE_XCB */' + + print ' }' + print ' return%s;' % (return_name) + return + + + def printPixelFunction(self, f): + if self.pixel_stubs.has_key( f.name ): + # Normally gl_function::get_parameter_string could be + # used. However, this call needs to have the missing + # dimensions (e.g., a fake height value for + # glTexImage1D) added in. + + p_string = "" + for param in f.parameterIterateGlxSend(): + if param.is_padding: + continue + + p_string += ", " + param.name + + if param.is_image(): + [dim, junk, junk, junk, junk] = param.get_dimensions() + + if f.pad_after(param): + p_string += ", 1" + + print ' %s(%s, %u%s );' % (self.pixel_stubs[f.name] , f.opcode_name(), dim, p_string) + return + + + if self.common_func_print_just_start(f, None): + trailer = " }" + else: + trailer = None + + + if f.can_be_large: + print 'if (cmdlen <= gc->maxSmallRenderCommandSize) {' + print ' if ( (gc->pc + cmdlen) > gc->bufEnd ) {' + print ' (void) __glXFlushRenderBuffer(gc, gc->pc);' + print ' }' + + if f.glx_rop == ~0: + opcode = "opcode" + else: + opcode = f.opcode_real_name() + + print 'emit_header(gc->pc, %s, cmdlen);' % (opcode) + + self.pixel_emit_args( f, "gc->pc", 0 ) + print 'gc->pc += cmdlen;' + print 'if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); }' + + if f.can_be_large: + print '}' + print 'else {' + + self.large_emit_begin(f, opcode) + self.pixel_emit_args(f, "pc", 1) + + print '}' + + if trailer: print trailer + return + + + def printRenderFunction(self, f): + # There is a class of GL functions that take a single pointer + # as a parameter. This pointer points to a fixed-size chunk + # of data, and the protocol for this functions is very + # regular. Since they are so regular and there are so many + # of them, special case them with generic functions. On + # x86, this saves about 26KB in the libGL.so binary. + + if f.variable_length_parameter() == None and len(f.parameters) == 1: + p = f.parameters[0] + if p.is_pointer(): + cmdlen = f.command_fixed_length() + if cmdlen in self.generic_sizes: + print ' generic_%u_byte( %s, %s );' % (cmdlen, f.opcode_real_name(), p.name) + return + + if self.common_func_print_just_start(f, None): + trailer = " }" + else: + trailer = None + + if self.debug: + print 'printf( "Enter %%s...\\n", "gl%s" );' % (f.name) + + if f.can_be_large: + print 'if (cmdlen <= gc->maxSmallRenderCommandSize) {' + print ' if ( (gc->pc + cmdlen) > gc->bufEnd ) {' + print ' (void) __glXFlushRenderBuffer(gc, gc->pc);' + print ' }' + + print 'emit_header(gc->pc, %s, cmdlen);' % (f.opcode_real_name()) + + self.common_emit_args(f, "gc->pc", 4, 0) + print 'gc->pc += cmdlen;' + print 'if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }' + + if f.can_be_large: + print '}' + print 'else {' + + self.large_emit_begin(f) + self.common_emit_args(f, "pc", 8, 1) + + p = f.variable_length_parameter() + print ' __glXSendLargeCommand(gc, pc, %u, %s, %s);' % (p.offset + 8, p.name, p.size_string()) + print '}' + + if self.debug: + print '__indirect_glFinish();' + print 'printf( "Exit %%s.\\n", "gl%s" );' % (f.name) + + if trailer: print trailer + return + + +class PrintGlxProtoInit_c(gl_XML.gl_print_base): + def __init__(self): + gl_XML.gl_print_base.__init__(self) + + self.name = "glX_proto_send.py (from Mesa)" + self.license = license.bsd_license_template % ( \ +"""Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +(C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM") + return + + + def printRealHeader(self): + print """/** + * \\file indirect_init.c + * Initialize indirect rendering dispatch table. + * + * \\author Kevin E. Martin + * \\author Brian Paul + * \\author Ian Romanick + */ + +#include "indirect_init.h" +#include "indirect.h" +#include "glapi.h" + + +/** + * No-op function used to initialize functions that have no GLX protocol + * support. + */ +static int NoOp(void) +{ + return 0; +} + +/** + * Create and initialize a new GL dispatch table. The table is initialized + * with GLX indirect rendering protocol functions. + */ +__GLapi * __glXNewIndirectAPI( void ) +{ + __GLapi *glAPI; + GLuint entries; + + entries = _glapi_get_dispatch_table_size(); + glAPI = (__GLapi *) Xmalloc(entries * sizeof(void *)); + + /* first, set all entries to point to no-op functions */ + { + int i; + void **dispatch = (void **) glAPI; + for (i = 0; i < entries; i++) { + dispatch[i] = (void *) NoOp; + } + } + + /* now, initialize the entries we understand */""" + + def printRealFooter(self): + print """ + return glAPI; +} +""" + return + + + def printBody(self, api): + for [name, number] in api.categoryIterate(): + if number != None: + preamble = '\n /* %3u. %s */\n\n' % (int(number), name) + else: + preamble = '\n /* %s */\n\n' % (name) + + for func in api.functionIterateByCategory(name): + if func.client_supported_for_indirect(): + print '%s glAPI->%s = __indirect_gl%s;' % (preamble, func.name, func.name) + preamble = '' + + return + + +class PrintGlxProtoInit_h(gl_XML.gl_print_base): + def __init__(self): + gl_XML.gl_print_base.__init__(self) + + self.name = "glX_proto_send.py (from Mesa)" + self.license = license.bsd_license_template % ( \ +"""Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +(C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM") + self.header_tag = "_INDIRECT_H_" + + self.last_category = "" + return + + + def printRealHeader(self): + print """/** + * \\file + * Prototypes for indirect rendering functions. + * + * \\author Kevin E. Martin + * \\author Ian Romanick + */ +""" + self.printVisibility( "HIDDEN", "hidden" ) + self.printFastcall() + self.printNoinline() + + print """ +#include "glxclient.h" + +extern HIDDEN NOINLINE CARD32 __glXReadReply( Display *dpy, size_t size, + void * dest, GLboolean reply_is_always_array ); + +extern HIDDEN NOINLINE void __glXReadPixelReply( Display *dpy, + __GLXcontext * gc, unsigned max_dim, GLint width, GLint height, + GLint depth, GLenum format, GLenum type, void * dest, + GLboolean dimensions_in_reply ); + +extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupSingleRequest( + __GLXcontext * gc, GLint sop, GLint cmdlen ); + +extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupVendorRequest( + __GLXcontext * gc, GLint code, GLint vop, GLint cmdlen ); +""" + + + def printBody(self, api): + for func in api.functionIterateGlx(): + params = func.get_parameter_string() + + print 'extern HIDDEN %s __indirect_gl%s(%s);' % (func.return_type, func.name, params) + + for n in func.entry_points: + if func.has_different_protocol(n): + asdf = func.static_glx_name(n) + if asdf not in func.static_entry_points: + print 'extern HIDDEN %s gl%s(%s);' % (func.return_type, asdf, params) + else: + print 'GLAPI %s GLAPIENTRY gl%s(%s);' % (func.return_type, asdf, params) + + break + + + +def show_usage(): + print "Usage: %s [-f input_file_name] [-m output_mode] [-d]" % sys.argv[0] + print " -m output_mode Output mode can be one of 'proto', 'init_c' or 'init_h'." + print " -d Enable extra debug information in the generated code." + sys.exit(1) + + +if __name__ == '__main__': + file_name = "gl_API.xml" + + try: + (args, trail) = getopt.getopt(sys.argv[1:], "f:m:d") + except Exception,e: + show_usage() + + debug = 0 + mode = "proto" + for (arg,val) in args: + if arg == "-f": + file_name = val + elif arg == "-m": + mode = val + elif arg == "-d": + debug = 1 + + if mode == "proto": + printer = PrintGlxProtoStubs() + elif mode == "init_c": + printer = PrintGlxProtoInit_c() + elif mode == "init_h": + printer = PrintGlxProtoInit_h() + else: + show_usage() + + + printer.debug = debug + api = gl_XML.parse_GL_API( file_name, glX_XML.glx_item_factory() ) + + printer.Print( api ) diff --git a/mesalib/src/mesa/glapi/glX_proto_size.py b/mesalib/src/mesa/glapi/glX_proto_size.py new file mode 100644 index 000000000..95cb5110c --- /dev/null +++ b/mesalib/src/mesa/glapi/glX_proto_size.py @@ -0,0 +1,704 @@ +#!/usr/bin/env python + +# (C) Copyright IBM Corporation 2004, 2005 +# 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 +# IBM AND/OR ITS 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 + +import gl_XML, glX_XML +import license +import sys, getopt, copy, string + + +class glx_enum_function: + def __init__(self, func_name, enum_dict): + self.name = func_name + self.mode = 1 + self.sig = None + + # "enums" is a set of lists. The element in the set is the + # value of the enum. The list is the list of names for that + # value. For example, [0x8126] = {"POINT_SIZE_MIN", + # "POINT_SIZE_MIN_ARB", "POINT_SIZE_MIN_EXT", + # "POINT_SIZE_MIN_SGIS"}. + + self.enums = {} + + # "count" is indexed by count values. Each element of count + # is a list of index to "enums" that have that number of + # associated data elements. For example, [4] = + # {GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR, GL_EMISSION, + # GL_AMBIENT_AND_DIFFUSE} (the enum names are used here, + # but the actual hexadecimal values would be in the array). + + self.count = {} + + + # Fill self.count and self.enums using the dictionary of enums + # that was passed in. The generic Get functions (e.g., + # GetBooleanv and friends) are handled specially here. In + # the data the generic Get functions are refered to as "Get". + + if func_name in ["GetIntegerv", "GetBooleanv", "GetFloatv", "GetDoublev"]: + match_name = "Get" + else: + match_name = func_name + + mode_set = 0 + for enum_name in enum_dict: + e = enum_dict[ enum_name ] + + if e.functions.has_key( match_name ): + [count, mode] = e.functions[ match_name ] + + if mode_set and mode != self.mode: + raise RuntimeError("Not all enums for %s have the same mode." % (func_name)) + + self.mode = mode + + if self.enums.has_key( e.value ): + if e.name not in self.enums[ e.value ]: + self.enums[ e.value ].append( e ) + else: + if not self.count.has_key( count ): + self.count[ count ] = [] + + self.enums[ e.value ] = [ e ] + self.count[ count ].append( e.value ) + + + return + + + def signature( self ): + if self.sig == None: + self.sig = "" + for i in self.count: + if i == None: + raise RuntimeError("i is None. WTF?") + + self.count[i].sort() + for e in self.count[i]: + self.sig += "%04x,%d," % (e, i) + + return self.sig + + + def is_set( self ): + return self.mode + + + def PrintUsingTable(self): + """Emit the body of the __gl*_size function using a pair + of look-up tables and a mask. The mask is calculated such + that (e & mask) is unique for all the valid values of e for + this function. The result of (e & mask) is used as an index + into the first look-up table. If it matches e, then the + same entry of the second table is returned. Otherwise zero + is returned. + + It seems like this should cause better code to be generated. + However, on x86 at least, the resulting .o file is about 20% + larger then the switch-statment version. I am leaving this + code in because the results may be different on other + platforms (e.g., PowerPC or x86-64).""" + + return 0 + count = 0 + for a in self.enums: + count += 1 + + if self.count.has_key(-1): + return 0 + + # Determine if there is some mask M, such that M = (2^N) - 1, + # that will generate unique values for all of the enums. + + mask = 0 + for i in [1, 2, 3, 4, 5, 6, 7, 8]: + mask = (1 << i) - 1 + + fail = 0; + for a in self.enums: + for b in self.enums: + if a != b: + if (a & mask) == (b & mask): + fail = 1; + + if not fail: + break; + else: + mask = 0 + + if (mask != 0) and (mask < (2 * count)): + masked_enums = {} + masked_count = {} + + for i in range(0, mask + 1): + masked_enums[i] = "0"; + masked_count[i] = 0; + + for c in self.count: + for e in self.count[c]: + i = e & mask + enum_obj = self.enums[e][0] + masked_enums[i] = '0x%04x /* %s */' % (e, enum_obj.name ) + masked_count[i] = c + + + print ' static const GLushort a[%u] = {' % (mask + 1) + for e in masked_enums: + print ' %s, ' % (masked_enums[e]) + print ' };' + + print ' static const GLubyte b[%u] = {' % (mask + 1) + for c in masked_count: + print ' %u, ' % (masked_count[c]) + print ' };' + + print ' const unsigned idx = (e & 0x%02xU);' % (mask) + print '' + print ' return (e == a[idx]) ? (GLint) b[idx] : 0;' + return 1; + else: + return 0; + + + def PrintUsingSwitch(self, name): + """Emit the body of the __gl*_size function using a + switch-statement.""" + + print ' switch( e ) {' + + for c in self.count: + for e in self.count[c]: + first = 1 + + # There may be multiple enums with the same + # value. This happens has extensions are + # promoted from vendor-specific or EXT to + # ARB and to the core. Emit the first one as + # a case label, and emit the others as + # commented-out case labels. + + list = {} + for enum_obj in self.enums[e]: + list[ enum_obj.priority() ] = enum_obj.name + + keys = list.keys() + keys.sort() + for k in keys: + j = list[k] + if first: + print ' case GL_%s:' % (j) + first = 0 + else: + print '/* case GL_%s:*/' % (j) + + if c == -1: + print ' return __gl%s_variable_size( e );' % (name) + else: + print ' return %u;' % (c) + + print ' default: return 0;' + print ' }' + + + def Print(self, name): + print 'INTERNAL PURE FASTCALL GLint' + print '__gl%s_size( GLenum e )' % (name) + print '{' + + if not self.PrintUsingTable(): + self.PrintUsingSwitch(name) + + print '}' + print '' + + +class glx_server_enum_function(glx_enum_function): + def __init__(self, func, enum_dict): + glx_enum_function.__init__(self, func.name, enum_dict) + + self.function = func + return + + + def signature( self ): + if self.sig == None: + sig = glx_enum_function.signature(self) + + p = self.function.variable_length_parameter() + if p: + sig += "%u" % (p.size()) + + self.sig = sig + + return self.sig; + + + def Print(self, name, printer): + f = self.function + printer.common_func_print_just_header( f ) + + fixup = [] + + foo = {} + for param_name in f.count_parameter_list: + o = f.offset_of( param_name ) + foo[o] = param_name + + for param_name in f.counter_list: + o = f.offset_of( param_name ) + foo[o] = param_name + + keys = foo.keys() + keys.sort() + for o in keys: + p = f.parameters_by_name[ foo[o] ] + + printer.common_emit_one_arg(p, "pc", 0) + fixup.append( p.name ) + + + print ' GLsizei compsize;' + print '' + + printer.common_emit_fixups(fixup) + + print '' + print ' compsize = __gl%s_size(%s);' % (f.name, string.join(f.count_parameter_list, ",")) + p = f.variable_length_parameter() + print ' return __GLX_PAD(%s);' % (p.size_string()) + + print '}' + print '' + + +class PrintGlxSizeStubs_common(gl_XML.gl_print_base): + do_get = (1 << 0) + do_set = (1 << 1) + + def __init__(self, which_functions): + gl_XML.gl_print_base.__init__(self) + + self.name = "glX_proto_size.py (from Mesa)" + self.license = license.bsd_license_template % ( "(C) Copyright IBM Corporation 2004", "IBM") + + self.emit_set = ((which_functions & PrintGlxSizeStubs_common.do_set) != 0) + self.emit_get = ((which_functions & PrintGlxSizeStubs_common.do_get) != 0) + return + + +class PrintGlxSizeStubs_c(PrintGlxSizeStubs_common): + def printRealHeader(self): + print '' + print '#include ' + if self.emit_get: + print '#include "indirect_size_get.h"' + print '#include "glxserver.h"' + print '#include "indirect_util.h"' + + print '#include "indirect_size.h"' + + print '' + self.printPure() + print '' + self.printFastcall() + print '' + self.printVisibility( "INTERNAL", "internal" ) + print '' + print '' + print '#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__APPLE__)' + print '# undef HAVE_ALIAS' + print '#endif' + print '#ifdef HAVE_ALIAS' + print '# define ALIAS2(from,to) \\' + print ' INTERNAL PURE FASTCALL GLint __gl ## from ## _size( GLenum e ) \\' + print ' __attribute__ ((alias( # to )));' + print '# define ALIAS(from,to) ALIAS2( from, __gl ## to ## _size )' + print '#else' + print '# define ALIAS(from,to) \\' + print ' INTERNAL PURE FASTCALL GLint __gl ## from ## _size( GLenum e ) \\' + print ' { return __gl ## to ## _size( e ); }' + print '#endif' + print '' + print '' + + + def printBody(self, api): + enum_sigs = {} + aliases = [] + + for func in api.functionIterateGlx(): + ef = glx_enum_function( func.name, api.enums_by_name ) + if len(ef.enums) == 0: + continue + + if (ef.is_set() and self.emit_set) or (not ef.is_set() and self.emit_get): + sig = ef.signature() + if enum_sigs.has_key( sig ): + aliases.append( [func.name, enum_sigs[ sig ]] ) + else: + enum_sigs[ sig ] = func.name + ef.Print( func.name ) + + + for [alias_name, real_name] in aliases: + print 'ALIAS( %s, %s )' % (alias_name, real_name) + + + +class PrintGlxSizeStubs_h(PrintGlxSizeStubs_common): + def printRealHeader(self): + print """/** + * \\file + * Prototypes for functions used to determine the number of data elements in + * various GLX protocol messages. + * + * \\author Ian Romanick + */ +""" + self.printPure(); + print '' + self.printFastcall(); + print '' + self.printVisibility( "INTERNAL", "internal" ); + print '' + + + def printBody(self, api): + for func in api.functionIterateGlx(): + ef = glx_enum_function( func.name, api.enums_by_name ) + if len(ef.enums) == 0: + continue + + if (ef.is_set() and self.emit_set) or (not ef.is_set() and self.emit_get): + print 'extern INTERNAL PURE FASTCALL GLint __gl%s_size(GLenum);' % (func.name) + + +class PrintGlxReqSize_common(gl_XML.gl_print_base): + """Common base class for PrintGlxSizeReq_h and PrintGlxSizeReq_h. + + The main purpose of this common base class is to provide the infrastructure + for the derrived classes to iterate over the same set of functions. + """ + + def __init__(self): + gl_XML.gl_print_base.__init__(self) + + self.name = "glX_proto_size.py (from Mesa)" + self.license = license.bsd_license_template % ( "(C) Copyright IBM Corporation 2005", "IBM") + + +class PrintGlxReqSize_h(PrintGlxReqSize_common): + def __init__(self): + PrintGlxReqSize_common.__init__(self) + self.header_tag = "_INDIRECT_REQSIZE_H_" + + + def printRealHeader(self): + self.printVisibility("HIDDEN", "hidden") + print '' + self.printPure() + print '' + + + def printBody(self, api): + for func in api.functionIterateGlx(): + if not func.ignore and func.has_variable_size_request(): + print 'extern PURE HIDDEN int __glX%sReqSize(const GLbyte *pc, Bool swap);' % (func.name) + + +class PrintGlxReqSize_c(PrintGlxReqSize_common): + """Create the server-side 'request size' functions. + + Create the server-side functions that are used to determine what the + size of a varible length command should be. The server then uses + this value to determine if the incoming command packed it malformed. + """ + + def __init__(self): + PrintGlxReqSize_common.__init__(self) + self.counter_sigs = {} + + + def printRealHeader(self): + print '' + print '#include ' + print '#include "glxserver.h"' + print '#include "glxbyteorder.h"' + print '#include "indirect_size.h"' + print '#include "indirect_reqsize.h"' + print '' + print '#define __GLX_PAD(x) (((x) + 3) & ~3)' + print '' + print '#if defined(__CYGWIN__) || defined(__MINGW32__)' + print '# undef HAVE_ALIAS' + print '#endif' + print '#ifdef HAVE_ALIAS' + print '# define ALIAS2(from,to) \\' + print ' GLint __glX ## from ## ReqSize( const GLbyte * pc, Bool swap ) \\' + print ' __attribute__ ((alias( # to )));' + print '# define ALIAS(from,to) ALIAS2( from, __glX ## to ## ReqSize )' + print '#else' + print '# define ALIAS(from,to) \\' + print ' GLint __glX ## from ## ReqSize( const GLbyte * pc, Bool swap ) \\' + print ' { return __glX ## to ## ReqSize( pc, swap ); }' + print '#endif' + print '' + print '' + + + def printBody(self, api): + aliases = [] + enum_functions = {} + enum_sigs = {} + + for func in api.functionIterateGlx(): + if not func.has_variable_size_request(): continue + + ef = glx_server_enum_function( func, api.enums_by_name ) + if len(ef.enums) == 0: continue + + sig = ef.signature() + + if not enum_functions.has_key(func.name): + enum_functions[ func.name ] = sig + + if not enum_sigs.has_key( sig ): + enum_sigs[ sig ] = ef + + + + for func in api.functionIterateGlx(): + # Even though server-handcode fuctions are on "the + # list", and prototypes are generated for them, there + # isn't enough information to generate a size + # function. If there was enough information, they + # probably wouldn't need to be handcoded in the first + # place! + + if func.server_handcode: continue + if not func.has_variable_size_request(): continue + + if enum_functions.has_key(func.name): + sig = enum_functions[func.name] + ef = enum_sigs[ sig ] + + if ef.name != func.name: + aliases.append( [func.name, ef.name] ) + else: + ef.Print( func.name, self ) + + elif func.images: + self.printPixelFunction(func) + elif func.has_variable_size_request(): + a = self.printCountedFunction(func) + if a: aliases.append(a) + + + for [alias_name, real_name] in aliases: + print 'ALIAS( %s, %s )' % (alias_name, real_name) + + return + + + def common_emit_fixups(self, fixup): + """Utility function to emit conditional byte-swaps.""" + + if fixup: + print ' if (swap) {' + for name in fixup: + print ' %s = bswap_32(%s);' % (name, name) + print ' }' + + return + + + def common_emit_one_arg(self, p, pc, adjust): + offset = p.offset + dst = p.string() + src = '(%s *)' % (p.type_string()) + print '%-18s = *%11s(%s + %u);' % (dst, src, pc, offset + adjust); + return + + + def common_func_print_just_header(self, f): + print 'int' + print '__glX%sReqSize( const GLbyte * pc, Bool swap )' % (f.name) + print '{' + + + def printPixelFunction(self, f): + self.common_func_print_just_header(f) + + f.offset_of( f.parameters[0].name ) + [dim, w, h, d, junk] = f.get_images()[0].get_dimensions() + + print ' GLint row_length = * (GLint *)(pc + 4);' + + if dim < 3: + fixup = ['row_length', 'skip_rows', 'alignment'] + print ' GLint image_height = 0;' + print ' GLint skip_images = 0;' + print ' GLint skip_rows = * (GLint *)(pc + 8);' + print ' GLint alignment = * (GLint *)(pc + 16);' + else: + fixup = ['row_length', 'image_height', 'skip_rows', 'skip_images', 'alignment'] + print ' GLint image_height = * (GLint *)(pc + 8);' + print ' GLint skip_rows = * (GLint *)(pc + 16);' + print ' GLint skip_images = * (GLint *)(pc + 20);' + print ' GLint alignment = * (GLint *)(pc + 32);' + + img = f.images[0] + for p in f.parameterIterateGlxSend(): + if p.name in [w, h, d, img.img_format, img.img_type, img.img_target]: + self.common_emit_one_arg(p, "pc", 0) + fixup.append( p.name ) + + print '' + + self.common_emit_fixups(fixup) + + if img.img_null_flag: + print '' + print ' if (*(CARD32 *) (pc + %s))' % (img.offset - 4) + print ' return 0;' + + print '' + print ' return __glXImageSize(%s, %s, %s, %s, %s, %s,' % (img.img_format, img.img_type, img.img_target, w, h, d ) + print ' image_height, row_length, skip_images,' + print ' skip_rows, alignment);' + print '}' + print '' + return + + + def printCountedFunction(self, f): + + sig = "" + offset = 0 + fixup = [] + params = [] + plus = '' + size = '' + param_offsets = {} + + # Calculate the offset of each counter parameter and the + # size string for the variable length parameter(s). While + # that is being done, calculate a unique signature for this + # function. + + for p in f.parameterIterateGlxSend(): + if p.is_counter: + fixup.append( p.name ) + params.append( p ) + elif p.counter: + s = p.size() + if s == 0: s = 1 + + sig += "(%u,%u)" % (f.offset_of(p.counter), s) + size += '%s%s' % (plus, p.size_string()) + plus = ' + ' + + + # If the calculated signature matches a function that has + # already be emitted, don't emit this function. Instead, add + # it to the list of function aliases. + + if self.counter_sigs.has_key(sig): + n = self.counter_sigs[sig]; + alias = [f.name, n] + else: + alias = None + self.counter_sigs[sig] = f.name + + self.common_func_print_just_header(f) + + for p in params: + self.common_emit_one_arg(p, "pc", 0) + + + print '' + self.common_emit_fixups(fixup) + print '' + + print ' return __GLX_PAD(%s);' % (size) + print '}' + print '' + + return alias + + +def show_usage(): + print "Usage: %s [-f input_file_name] -m output_mode [--only-get | --only-set] [--get-alias-set]" % sys.argv[0] + print " -m output_mode Output mode can be one of 'size_c' or 'size_h'." + print " --only-get Only emit 'get'-type functions." + print " --only-set Only emit 'set'-type functions." + print "" + print "By default, both 'get' and 'set'-type functions are emitted." + sys.exit(1) + + +if __name__ == '__main__': + file_name = "gl_API.xml" + + try: + (args, trail) = getopt.getopt(sys.argv[1:], "f:m:h:", ["only-get", "only-set", "header-tag"]) + except Exception,e: + show_usage() + + mode = None + header_tag = None + which_functions = PrintGlxSizeStubs_common.do_get | PrintGlxSizeStubs_common.do_set + + for (arg,val) in args: + if arg == "-f": + file_name = val + elif arg == "-m": + mode = val + elif arg == "--only-get": + which_functions = PrintGlxSizeStubs_common.do_get + elif arg == "--only-set": + which_functions = PrintGlxSizeStubs_common.do_set + elif (arg == '-h') or (arg == "--header-tag"): + header_tag = val + + if mode == "size_c": + printer = PrintGlxSizeStubs_c( which_functions ) + elif mode == "size_h": + printer = PrintGlxSizeStubs_h( which_functions ) + if header_tag: + printer.header_tag = header_tag + elif mode == "reqsize_c": + printer = PrintGlxReqSize_c() + elif mode == "reqsize_h": + printer = PrintGlxReqSize_h() + else: + show_usage() + + api = gl_XML.parse_GL_API( file_name, glX_XML.glx_item_factory() ) + + + printer.Print( api ) diff --git a/mesalib/src/mesa/glapi/glX_server_table.py b/mesalib/src/mesa/glapi/glX_server_table.py new file mode 100644 index 000000000..f3962f875 --- /dev/null +++ b/mesalib/src/mesa/glapi/glX_server_table.py @@ -0,0 +1,411 @@ +#!/bin/env python + +# (C) Copyright IBM Corporation 2005, 2006 +# 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 +# IBM AND/OR ITS 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 + +import gl_XML, glX_XML, glX_proto_common, license +import sys, getopt + + +def log2(value): + for i in range(0, 30): + p = 1 << i + if p >= value: + return i + + return -1 + + +def round_down_to_power_of_two(n): + """Returns the nearest power-of-two less than or equal to n.""" + + for i in range(30, 0, -1): + p = 1 << i + if p <= n: + return p + + return -1 + + +class function_table: + def __init__(self, name, do_size_check): + self.name_base = name + self.do_size_check = do_size_check + + + self.max_bits = 1 + self.next_opcode_threshold = (1 << self.max_bits) + self.max_opcode = 0 + + self.functions = {} + self.lookup_table = [] + + # Minimum number of opcodes in a leaf node. + self.min_op_bits = 3 + self.min_op_count = (1 << self.min_op_bits) + return + + + def append(self, opcode, func): + self.functions[opcode] = func + + if opcode > self.max_opcode: + self.max_opcode = opcode + + if opcode > self.next_opcode_threshold: + bits = log2(opcode) + if (1 << bits) <= opcode: + bits += 1 + + self.max_bits = bits + self.next_opcode_threshold = 1 << bits + return + + + def divide_group(self, min_opcode, total): + """Divide the group starting min_opcode into subgroups. + Returns a tuple containing the number of bits consumed by + the node, the list of the children's tuple, and the number + of entries in the final array used by this node and its + children, and the depth of the subtree rooted at the node.""" + + remaining_bits = self.max_bits - total + next_opcode = min_opcode + (1 << remaining_bits) + empty_children = 0 + + for M in range(0, remaining_bits): + op_count = 1 << (remaining_bits - M); + child_count = 1 << M; + + empty_children = 0 + full_children = 0 + for i in range(min_opcode, next_opcode, op_count): + used = 0 + empty = 0 + + for j in range(i, i + op_count): + if self.functions.has_key(j): + used += 1; + else: + empty += 1; + + + if empty == op_count: + empty_children += 1 + + if used == op_count: + full_children += 1 + + if (empty_children > 0) or (full_children == child_count) or (op_count <= self.min_op_count): + break + + + # If all the remaining bits are used by this node, as is the + # case when M is 0 or remaining_bits, the node is a leaf. + + if (M == 0) or (M == remaining_bits): + return [remaining_bits, [], 0, 0] + else: + children = [] + count = 1 + depth = 1 + all_children_are_nonempty_leaf_nodes = 1 + for i in range(min_opcode, next_opcode, op_count): + n = self.divide_group(i, total + M) + + if not (n[1] == [] and not self.is_empty_leaf(i, n[0])): + all_children_are_nonempty_leaf_nodes = 0 + + children.append(n) + count += n[2] + 1 + + if n[3] >= depth: + depth = n[3] + 1 + + # If all of the child nodes are non-empty leaf nodes, pull + # them up and make this node a leaf. + + if all_children_are_nonempty_leaf_nodes: + return [remaining_bits, [], 0, 0] + else: + return [M, children, count, depth] + + + def is_empty_leaf(self, base_opcode, M): + for op in range(base_opcode, base_opcode + (1 << M)): + if self.functions.has_key(op): + return 0 + break + + return 1 + + + def dump_tree(self, node, base_opcode, remaining_bits, base_entry, depth): + M = node[0] + children = node[1] + child_M = remaining_bits - M + + + # This actually an error condition. + if children == []: + return + + print ' /* [%u] -> opcode range [%u, %u], node depth %u */' % (base_entry, base_opcode, base_opcode + (1 << remaining_bits), depth) + print ' %u,' % (M) + + base_entry += (1 << M) + 1 + + child_index = base_entry + child_base_opcode = base_opcode + for child in children: + if child[1] == []: + if self.is_empty_leaf(child_base_opcode, child_M): + print ' EMPTY_LEAF,' + else: + # Emit the index of the next dispatch + # function. Then add all the + # dispatch functions for this leaf + # node to the dispatch function + # lookup table. + + print ' LEAF(%u),' % (len(self.lookup_table)) + + for op in range(child_base_opcode, child_base_opcode + (1 << child_M)): + if self.functions.has_key(op): + func = self.functions[op] + size = func.command_fixed_length() + + if func.glx_rop != 0: + size += 4 + + size = ((size + 3) & ~3) + + if func.has_variable_size_request(): + size_name = "__glX%sReqSize" % (func.name) + else: + size_name = "" + + if func.glx_vendorpriv == op: + func_name = func.glx_vendorpriv_names[0] + else: + func_name = func.name + + temp = [op, "__glXDisp_%s" % (func_name), "__glXDispSwap_%s" % (func_name), size, size_name] + else: + temp = [op, "NULL", "NULL", 0, ""] + + self.lookup_table.append(temp) + else: + print ' %u,' % (child_index) + child_index += child[2] + + child_base_opcode += 1 << child_M + + print '' + + child_index = base_entry + for child in children: + if child[1] != []: + self.dump_tree(child, base_opcode, remaining_bits - M, child_index, depth + 1) + child_index += child[2] + + base_opcode += 1 << (remaining_bits - M) + + + def Print(self): + # Each dispatch table consists of two data structures. + # + # The first structure is an N-way tree where the opcode for + # the function is the key. Each node switches on a range of + # bits from the opcode. M bits are extracted from the opcde + # and are used as an index to select one of the N, where + # N = 2^M, children. + # + # The tree is stored as a flat array. The first value is the + # number of bits, M, used by the node. For inner nodes, the + # following 2^M values are indexes into the array for the + # child nodes. For leaf nodes, the followign 2^M values are + # indexes into the second data structure. + # + # If an inner node's child index is 0, the child is an empty + # leaf node. That is, none of the opcodes selectable from + # that child exist. Since most of the possible opcode space + # is unused, this allows compact data storage. + # + # The second data structure is an array of pairs of function + # pointers. Each function contains a pointer to a protocol + # decode function and a pointer to a byte-swapped protocol + # decode function. Elements in this array are selected by the + # leaf nodes of the first data structure. + # + # As the tree is traversed, an accumulator is kept. This + # accumulator counts the bits of the opcode consumed by the + # traversal. When accumulator + M = B, where B is the + # maximum number of bits in an opcode, the traversal has + # reached a leaf node. The traversal starts with the most + # significant bits and works down to the least significant + # bits. + # + # Creation of the tree is the most complicated part. At + # each node the elements are divided into groups of 2^M + # elements. The value of M selected is the smallest possible + # value where all of the groups are either empty or full, or + # the groups are a preset minimum size. If all the children + # of a node are non-empty leaf nodes, the children are merged + # to create a single leaf node that replaces the parent. + + tree = self.divide_group(0, 0) + + print '/*****************************************************************/' + print '/* tree depth = %u */' % (tree[3]) + print 'static const int_fast16_t %s_dispatch_tree[%u] = {' % (self.name_base, tree[2]) + self.dump_tree(tree, 0, self.max_bits, 0, 1) + print '};\n' + + # After dumping the tree, dump the function lookup table. + + print 'static const void *%s_function_table[%u][2] = {' % (self.name_base, len(self.lookup_table)) + index = 0 + for func in self.lookup_table: + opcode = func[0] + name = func[1] + name_swap = func[2] + + print ' /* [% 3u] = %5u */ {%s, %s},' % (index, opcode, name, name_swap) + + index += 1 + + print '};\n' + + if self.do_size_check: + var_table = [] + + print 'static const int_fast16_t %s_size_table[%u][2] = {' % (self.name_base, len(self.lookup_table)) + index = 0 + var_table = [] + for func in self.lookup_table: + opcode = func[0] + fixed = func[3] + var = func[4] + + if var != "": + var_offset = "%2u" % (len(var_table)) + var_table.append(var) + else: + var_offset = "~0" + + print ' /* [%3u] = %5u */ {%3u, %s},' % (index, opcode, fixed, var_offset) + index += 1 + + + print '};\n' + + + print 'static const gl_proto_size_func %s_size_func_table[%u] = {' % (self.name_base, len(var_table)) + for func in var_table: + print ' %s,' % (func) + + print '};\n' + + + print 'const struct __glXDispatchInfo %s_dispatch_info = {' % (self.name_base) + print ' %u,' % (self.max_bits) + print ' %s_dispatch_tree,' % (self.name_base) + print ' %s_function_table,' % (self.name_base) + if self.do_size_check: + print ' %s_size_table,' % (self.name_base) + print ' %s_size_func_table' % (self.name_base) + else: + print ' NULL,' + print ' NULL' + print '};\n' + return + + +class PrintGlxDispatchTables(glX_proto_common.glx_print_proto): + def __init__(self): + gl_XML.gl_print_base.__init__(self) + self.name = "glX_server_table.py (from Mesa)" + self.license = license.bsd_license_template % ( "(C) Copyright IBM Corporation 2005, 2006", "IBM") + + self.rop_functions = function_table("Render", 1) + self.sop_functions = function_table("Single", 0) + self.vop_functions = function_table("VendorPriv", 0) + return + + + def printRealHeader(self): + print '#include ' + print '#include "glxserver.h"' + print '#include "glxext.h"' + print '#include "indirect_dispatch.h"' + print '#include "indirect_reqsize.h"' + print '#include "g_disptab.h"' + print '#include "indirect_table.h"' + print '' + return + + + def printBody(self, api): + for f in api.functionIterateAll(): + if not f.ignore and f.vectorequiv == None: + if f.glx_rop != 0: + self.rop_functions.append(f.glx_rop, f) + if f.glx_sop != 0: + self.sop_functions.append(f.glx_sop, f) + if f.glx_vendorpriv != 0: + self.vop_functions.append(f.glx_vendorpriv, f) + + self.sop_functions.Print() + self.rop_functions.Print() + self.vop_functions.Print() + return + + +if __name__ == '__main__': + file_name = "gl_API.xml" + + try: + (args, trail) = getopt.getopt(sys.argv[1:], "f:m") + except Exception,e: + show_usage() + + mode = "table_c" + for (arg,val) in args: + if arg == "-f": + file_name = val + elif arg == "-m": + mode = val + + if mode == "table_c": + printer = PrintGlxDispatchTables() + else: + show_usage() + + + api = gl_XML.parse_GL_API( file_name, glX_XML.glx_item_factory() ) + + + printer.Print( api ) diff --git a/mesalib/src/mesa/glapi/gl_API.dtd b/mesalib/src/mesa/glapi/gl_API.dtd new file mode 100644 index 000000000..30c646c92 --- /dev/null +++ b/mesalib/src/mesa/glapi/gl_API.dtd @@ -0,0 +1,140 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mesalib/src/mesa/glapi/gl_API.xml b/mesalib/src/mesa/glapi/gl_API.xml new file mode 100644 index 000000000..1dfd92be0 --- /dev/null +++ b/mesalib/src/mesa/glapi/gl_API.xml @@ -0,0 +1,12514 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mesalib/src/mesa/glapi/gl_SPARC_asm.py b/mesalib/src/mesa/glapi/gl_SPARC_asm.py new file mode 100644 index 000000000..33e752df3 --- /dev/null +++ b/mesalib/src/mesa/glapi/gl_SPARC_asm.py @@ -0,0 +1,275 @@ +#!/usr/bin/env python + +# (C) Copyright IBM Corporation 2004 +# 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 +# IBM AND/OR ITS 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 + +import license +import gl_XML, glX_XML +import sys, getopt + +class PrintGenericStubs(gl_XML.gl_print_base): + def __init__(self): + gl_XML.gl_print_base.__init__(self) + self.name = "gl_SPARC_asm.py (from Mesa)" + self.license = license.bsd_license_template % ( \ +"""Copyright (C) 1999-2003 Brian Paul All Rights Reserved. +(C) Copyright IBM Corporation 2004""", "BRIAN PAUL, IBM") + + + def printRealHeader(self): + print '#include "glapi/glapioffsets.h"' + print '' + print '#ifdef __arch64__' + print '#define GL_OFF(N)\t((N) * 8)' + print '#define GL_LL\t\tldx' + print '#define GL_TIE_LD(SYM)\t%tie_ldx(SYM)' + print '#define GL_STACK_SIZE\t128' + print '#else' + print '#define GL_OFF(N)\t((N) * 4)' + print '#define GL_LL\t\tld' + print '#define GL_TIE_LD(SYM)\t%tie_ld(SYM)' + print '#define GL_STACK_SIZE\t64' + print '#endif' + print '' + print '#define GLOBL_FN(x) .globl x ; .type x, @function' + print '#define HIDDEN(x) .hidden x' + print '' + print '\t.register %g2, #scratch' + print '\t.register %g3, #scratch' + print '' + print '\t.text' + print '' + print '\tGLOBL_FN(__glapi_sparc_icache_flush)' + print '\tHIDDEN(__glapi_sparc_icache_flush)' + print '\t.type\t__glapi_sparc_icache_flush, @function' + print '__glapi_sparc_icache_flush: /* %o0 = insn_addr */' + print '\tflush\t%o0' + print '\tretl' + print '\t nop' + print '' + print '\t.align\t32' + print '' + print '\t.type\t__glapi_sparc_get_pc, @function' + print '__glapi_sparc_get_pc:' + print '\tretl' + print '\t add\t%o7, %g2, %g2' + print '\t.size\t__glapi_sparc_get_pc, .-__glapi_sparc_get_pc' + print '' + print '#ifdef GLX_USE_TLS' + print '' + print '\tGLOBL_FN(__glapi_sparc_get_dispatch)' + print '\tHIDDEN(__glapi_sparc_get_dispatch)' + print '__glapi_sparc_get_dispatch:' + print '\tmov\t%o7, %g1' + print '\tsethi\t%hi(_GLOBAL_OFFSET_TABLE_-4), %g2' + print '\tcall\t__glapi_sparc_get_pc' + print '\tadd\t%g2, %lo(_GLOBAL_OFFSET_TABLE_+4), %g2' + print '\tmov\t%g1, %o7' + print '\tsethi\t%tie_hi22(_glapi_tls_Dispatch), %g1' + print '\tadd\t%g1, %tie_lo10(_glapi_tls_Dispatch), %g1' + print '\tGL_LL\t[%g2 + %g1], %g2, GL_TIE_LD(_glapi_tls_Dispatch)' + print '\tretl' + print '\t mov\t%g2, %o0' + print '' + print '\t.data' + print '\t.align\t32' + print '' + print '\t/* --> sethi %hi(_glapi_tls_Dispatch), %g1 */' + print '\t/* --> or %g1, %lo(_glapi_tls_Dispatch), %g1 */' + print '\tGLOBL_FN(__glapi_sparc_tls_stub)' + print '\tHIDDEN(__glapi_sparc_tls_stub)' + print '__glapi_sparc_tls_stub: /* Call offset in %g3 */' + print '\tmov\t%o7, %g1' + print '\tsethi\t%hi(_GLOBAL_OFFSET_TABLE_-4), %g2' + print '\tcall\t__glapi_sparc_get_pc' + print '\tadd\t%g2, %lo(_GLOBAL_OFFSET_TABLE_+4), %g2' + print '\tmov\t%g1, %o7' + print '\tsrl\t%g3, 10, %g3' + print '\tsethi\t%tie_hi22(_glapi_tls_Dispatch), %g1' + print '\tadd\t%g1, %tie_lo10(_glapi_tls_Dispatch), %g1' + print '\tGL_LL\t[%g2 + %g1], %g2, GL_TIE_LD(_glapi_tls_Dispatch)' + print '\tGL_LL\t[%g7+%g2], %g1' + print '\tGL_LL\t[%g1 + %g3], %g1' + print '\tjmp\t%g1' + print '\t nop' + print '\t.size\t__glapi_sparc_tls_stub, .-__glapi_sparc_tls_stub' + print '' + print '#define GL_STUB(fn, off)\t\t\t\t\\' + print '\tGLOBL_FN(fn);\t\t\t\t\t\\' + print 'fn:\tba\t__glapi_sparc_tls_stub;\t\t\t\\' + print '\t sethi\tGL_OFF(off), %g3;\t\t\t\\' + print '\t.size\tfn,.-fn;' + print '' + print '#elif defined(PTHREADS)' + print '' + print '\t/* 64-bit 0x00 --> sethi %hh(_glapi_Dispatch), %g1 */' + print '\t/* 64-bit 0x04 --> sethi %lm(_glapi_Dispatch), %g2 */' + print '\t/* 64-bit 0x08 --> or %g1, %hm(_glapi_Dispatch), %g1 */' + print '\t/* 64-bit 0x0c --> sllx %g1, 32, %g1 */' + print '\t/* 64-bit 0x10 --> add %g1, %g2, %g1 */' + print '\t/* 64-bit 0x14 --> ldx [%g1 + %lo(_glapi_Dispatch)], %g1 */' + print '' + print '\t/* 32-bit 0x00 --> sethi %hi(_glapi_Dispatch), %g1 */' + print '\t/* 32-bit 0x04 --> ld [%g1 + %lo(_glapi_Dispatch)], %g1 */' + print '' + print '\t.data' + print '\t.align\t32' + print '' + print '\tGLOBL_FN(__glapi_sparc_pthread_stub)' + print '\tHIDDEN(__glapi_sparc_pthread_stub)' + print '__glapi_sparc_pthread_stub: /* Call offset in %g3 */' + print '\tmov\t%o7, %g1' + print '\tsethi\t%hi(_GLOBAL_OFFSET_TABLE_-4), %g2' + print '\tcall\t__glapi_sparc_get_pc' + print '\t add\t%g2, %lo(_GLOBAL_OFFSET_TABLE_+4), %g2' + print '\tmov\t%g1, %o7' + print '\tsethi\t%hi(_glapi_Dispatch), %g1' + print '\tor\t%g1, %lo(_glapi_Dispatch), %g1' + print '\tsrl\t%g3, 10, %g3' + print '\tGL_LL\t[%g2+%g1], %g2' + print '\tGL_LL\t[%g2], %g1' + print '\tcmp\t%g1, 0' + print '\tbe\t2f' + print '\t nop' + print '1:\tGL_LL\t[%g1 + %g3], %g1' + print '\tjmp\t%g1' + print '\t nop' + print '2:\tsave\t%sp, GL_STACK_SIZE, %sp' + print '\tmov\t%g3, %l0' + print '\tcall\t_glapi_get_dispatch' + print '\t nop' + print '\tmov\t%o0, %g1' + print '\tmov\t%l0, %g3' + print '\tba\t1b' + print '\t restore %g0, %g0, %g0' + print '\t.size\t__glapi_sparc_pthread_stub, .-__glapi_sparc_pthread_stub' + print '' + print '#define GL_STUB(fn, off)\t\t\t\\' + print '\tGLOBL_FN(fn);\t\t\t\t\\' + print 'fn:\tba\t__glapi_sparc_pthread_stub;\t\\' + print '\t sethi\tGL_OFF(off), %g3;\t\t\\' + print '\t.size\tfn,.-fn;' + print '' + print '#else /* Non-threaded version. */' + print '' + print '\t.type __glapi_sparc_nothread_stub, @function' + print '__glapi_sparc_nothread_stub: /* Call offset in %g3 */' + print '\tmov\t%o7, %g1' + print '\tsethi\t%hi(_GLOBAL_OFFSET_TABLE_-4), %g2' + print '\tcall\t__glapi_sparc_get_pc' + print '\t add\t%g2, %lo(_GLOBAL_OFFSET_TABLE_+4), %g2' + print '\tmov\t%g1, %o7' + print '\tsrl\t%g3, 10, %g3' + print '\tsethi\t%hi(_glapi_Dispatch), %g1' + print '\tor\t%g1, %lo(_glapi_Dispatch), %g1' + print '\tGL_LL\t[%g2+%g1], %g2' + print '\tGL_LL\t[%g2], %g1' + print '\tGL_LL\t[%g1 + %g3], %g1' + print '\tjmp\t%g1' + print '\t nop' + print '\t.size\t__glapi_sparc_nothread_stub, .-__glapi_sparc_nothread_stub' + print '' + print '#define GL_STUB(fn, off)\t\t\t\\' + print '\tGLOBL_FN(fn);\t\t\t\t\\' + print 'fn:\tba\t__glapi_sparc_nothread_stub;\t\\' + print '\t sethi\tGL_OFF(off), %g3;\t\t\\' + print '\t.size\tfn,.-fn;' + print '' + print '#endif' + print '' + print '#define GL_STUB_ALIAS(fn, alias) \\' + print ' .globl fn; \\' + print ' .set fn, alias' + print '' + print '\t.text' + print '\t.align\t32' + print '' + print '\t.globl\tgl_dispatch_functions_start' + print '\tHIDDEN(gl_dispatch_functions_start)' + print 'gl_dispatch_functions_start:' + print '' + return + + def printRealFooter(self): + print '' + print '\t.globl\tgl_dispatch_functions_end' + print '\tHIDDEN(gl_dispatch_functions_end)' + print 'gl_dispatch_functions_end:' + return + + def printBody(self, api): + for f in api.functionIterateByOffset(): + name = f.dispatch_name() + + print '\tGL_STUB(gl%s, _gloffset_%s)' % (name, f.name) + + if not f.is_static_entry_point(f.name): + print '\tHIDDEN(gl%s)' % (name) + + for f in api.functionIterateByOffset(): + name = f.dispatch_name() + + if f.is_static_entry_point(f.name): + for n in f.entry_points: + if n != f.name: + text = '\tGL_STUB_ALIAS(gl%s, gl%s)' % (n, f.name) + + if f.has_different_protocol(n): + print '#ifndef GLX_INDIRECT_RENDERING' + print text + print '#endif' + else: + print text + + return + + +def show_usage(): + print "Usage: %s [-f input_file_name] [-m output_mode]" % sys.argv[0] + sys.exit(1) + +if __name__ == '__main__': + file_name = "gl_API.xml" + mode = "generic" + + try: + (args, trail) = getopt.getopt(sys.argv[1:], "m:f:") + except Exception,e: + show_usage() + + for (arg,val) in args: + if arg == '-m': + mode = val + elif arg == "-f": + file_name = val + + if mode == "generic": + printer = PrintGenericStubs() + else: + print "ERROR: Invalid mode \"%s\" specified." % mode + show_usage() + + api = gl_XML.parse_GL_API(file_name, glX_XML.glx_item_factory()) + printer.Print(api) diff --git a/mesalib/src/mesa/glapi/gl_XML.py b/mesalib/src/mesa/glapi/gl_XML.py new file mode 100644 index 000000000..b98919134 --- /dev/null +++ b/mesalib/src/mesa/glapi/gl_XML.py @@ -0,0 +1,964 @@ +#!/usr/bin/env python + +# (C) Copyright IBM Corporation 2004, 2005 +# 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 +# IBM AND/OR ITS 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 + +import libxml2 +import re, sys, string +import typeexpr + + +def parse_GL_API( file_name, factory = None ): + doc = libxml2.readFile( file_name, None, libxml2.XML_PARSE_XINCLUDE + libxml2.XML_PARSE_NOBLANKS + libxml2.XML_PARSE_DTDVALID + libxml2.XML_PARSE_DTDATTR + libxml2.XML_PARSE_DTDLOAD + libxml2.XML_PARSE_NOENT ) + ret = doc.xincludeProcess() + + if not factory: + factory = gl_item_factory() + + api = factory.create_item( "api", None, None ) + api.process_element( doc ) + + # After the XML has been processed, we need to go back and assign + # dispatch offsets to the functions that request that their offsets + # be assigned by the scripts. Typically this means all functions + # that are not part of the ABI. + + for func in api.functionIterateByCategory(): + if func.assign_offset: + func.offset = api.next_offset; + api.next_offset += 1 + + doc.freeDoc() + + return api + + +def is_attr_true( element, name ): + """Read a name value from an element's attributes. + + The value read from the attribute list must be either 'true' or + 'false'. If the value is 'false', zero will be returned. If the + value is 'true', non-zero will be returned. An exception will be + raised for any other value.""" + + value = element.nsProp( name, None ) + if value == "true": + return 1 + elif value == "false": + return 0 + else: + raise RuntimeError('Invalid value "%s" for boolean "%s".' % (value, name)) + + +class gl_print_base: + """Base class of all API pretty-printers. + + In the model-view-controller pattern, this is the view. Any derived + class will want to over-ride the printBody, printRealHader, and + printRealFooter methods. Some derived classes may want to over-ride + printHeader and printFooter, or even Print (though this is unlikely). + """ + + def __init__(self): + # Name of the script that is generating the output file. + # Every derived class should set this to the name of its + # source file. + + self.name = "a" + + + # License on the *generated* source file. This may differ + # from the license on the script that is generating the file. + # Every derived class should set this to some reasonable + # value. + # + # See license.py for an example of a reasonable value. + + self.license = "The license for this file is unspecified." + + + # The header_tag is the name of the C preprocessor define + # used to prevent multiple inclusion. Typically only + # generated C header files need this to be set. Setting it + # causes code to be generated automatically in printHeader + # and printFooter. + + self.header_tag = None + + + # List of file-private defines that must be undefined at the + # end of the file. This can be used in header files to define + # names for use in the file, then undefine them at the end of + # the header file. + + self.undef_list = [] + return + + + def Print(self, api): + self.printHeader() + self.printBody(api) + self.printFooter() + return + + + def printHeader(self): + """Print the header associated with all files and call the printRealHeader method.""" + + print '/* DO NOT EDIT - This file generated automatically by %s script */' \ + % (self.name) + print '' + print '/*' + print ' * ' + self.license.replace('\n', '\n * ') + print ' */' + print '' + if self.header_tag: + print '#if !defined( %s )' % (self.header_tag) + print '# define %s' % (self.header_tag) + print '' + self.printRealHeader(); + return + + + def printFooter(self): + """Print the header associated with all files and call the printRealFooter method.""" + + self.printRealFooter() + + if self.undef_list: + print '' + for u in self.undef_list: + print "# undef %s" % (u) + + if self.header_tag: + print '' + print '#endif /* !defined( %s ) */' % (self.header_tag) + + + def printRealHeader(self): + """Print the "real" header for the created file. + + In the base class, this function is empty. All derived + classes should over-ride this function.""" + return + + + def printRealFooter(self): + """Print the "real" footer for the created file. + + In the base class, this function is empty. All derived + classes should over-ride this function.""" + return + + + def printPure(self): + """Conditionally define `PURE' function attribute. + + Conditionally defines a preprocessor macro `PURE' that wraps + GCC's `pure' function attribute. The conditional code can be + easilly adapted to other compilers that support a similar + feature. + + The name is also added to the file's undef_list. + """ + self.undef_list.append("PURE") + print """# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) +# define PURE __attribute__((pure)) +# else +# define PURE +# endif""" + return + + + def printFastcall(self): + """Conditionally define `FASTCALL' function attribute. + + Conditionally defines a preprocessor macro `FASTCALL' that + wraps GCC's `fastcall' function attribute. The conditional + code can be easilly adapted to other compilers that support a + similar feature. + + The name is also added to the file's undef_list. + """ + + self.undef_list.append("FASTCALL") + print """# if defined(__i386__) && defined(__GNUC__) && !defined(__CYGWIN__) && !defined(__MINGW32__) +# define FASTCALL __attribute__((fastcall)) +# else +# define FASTCALL +# endif""" + return + + + def printVisibility(self, S, s): + """Conditionally define visibility function attribute. + + Conditionally defines a preprocessor macro name S that wraps + GCC's visibility function attribute. The visibility used is + the parameter s. The conditional code can be easilly adapted + to other compilers that support a similar feature. + + The name is also added to the file's undef_list. + """ + + self.undef_list.append(S) + print """# if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) && defined(__ELF__) +# define %s __attribute__((visibility("%s"))) +# else +# define %s +# endif""" % (S, s, S) + return + + + def printNoinline(self): + """Conditionally define `NOINLINE' function attribute. + + Conditionally defines a preprocessor macro `NOINLINE' that + wraps GCC's `noinline' function attribute. The conditional + code can be easilly adapted to other compilers that support a + similar feature. + + The name is also added to the file's undef_list. + """ + + self.undef_list.append("NOINLINE") + print """# if defined(__GNUC__) +# define NOINLINE __attribute__((noinline)) +# else +# define NOINLINE +# endif""" + return + + +def real_function_name(element): + name = element.nsProp( "name", None ) + alias = element.nsProp( "alias", None ) + + if alias: + return alias + else: + return name + + +def real_category_name(c): + if re.compile("[1-9][0-9]*[.][0-9]+").match(c): + return "GL_VERSION_" + c.replace(".", "_") + else: + return c + + +def classify_category(name, number): + """Based on the category name and number, select a numerical class for it. + + Categories are divided into four classes numbered 0 through 3. The + classes are: + + 0. Core GL versions, sorted by version number. + 1. ARB extensions, sorted by extension number. + 2. Non-ARB extensions, sorted by extension number. + 3. Un-numbered extensions, sorted by extension name. + """ + + try: + core_version = float(name) + except Exception,e: + core_version = 0.0 + + if core_version > 0.0: + cat_type = 0 + key = name + elif name.startswith("GL_ARB_") or name.startswith("GLX_ARB_") or name.startswith("WGL_ARB_"): + cat_type = 1 + key = int(number) + else: + if number != None: + cat_type = 2 + key = int(number) + else: + cat_type = 3 + key = name + + + return [cat_type, key] + + +def create_parameter_string(parameters, include_names): + """Create a parameter string from a list of gl_parameters.""" + + list = [] + for p in parameters: + if p.is_padding: + continue + + if include_names: + list.append( p.string() ) + else: + list.append( p.type_string() ) + + if len(list) == 0: list = ["void"] + + return string.join(list, ", ") + + +class gl_item: + def __init__(self, element, context): + self.context = context + self.name = element.nsProp( "name", None ) + self.category = real_category_name( element.parent.nsProp( "name", None ) ) + return + + +class gl_type( gl_item ): + def __init__(self, element, context): + gl_item.__init__(self, element, context) + self.size = int( element.nsProp( "size", None ), 0 ) + + te = typeexpr.type_expression( None ) + tn = typeexpr.type_node() + tn.size = int( element.nsProp( "size", None ), 0 ) + tn.integer = not is_attr_true( element, "float" ) + tn.unsigned = is_attr_true( element, "unsigned" ) + tn.name = "GL" + self.name + te.set_base_type_node( tn ) + + self.type_expr = te + return + + + def get_type_expression(self): + return self.type_expr + + +class gl_enum( gl_item ): + def __init__(self, element, context): + gl_item.__init__(self, element, context) + self.value = int( element.nsProp( "value", None ), 0 ) + + temp = element.nsProp( "count", None ) + if not temp or temp == "?": + self.default_count = -1 + else: + try: + c = int(temp) + except Exception,e: + raise RuntimeError('Invalid count value "%s" for enum "%s" in function "%s" when an integer was expected.' % (temp, self.name, n)) + + self.default_count = c + + return + + + def priority(self): + """Calculate a 'priority' for this enum name. + + When an enum is looked up by number, there may be many + possible names, but only one is the 'prefered' name. The + priority is used to select which name is the 'best'. + + Highest precedence is given to core GL name. ARB extension + names have the next highest, followed by EXT extension names. + Vendor extension names are the lowest. + """ + + if self.name.endswith( "_BIT" ): + bias = 1 + else: + bias = 0 + + if self.category.startswith( "GL_VERSION_" ): + priority = 0 + elif self.category.startswith( "GL_ARB_" ): + priority = 2 + elif self.category.startswith( "GL_EXT_" ): + priority = 4 + else: + priority = 6 + + return priority + bias + + + +class gl_parameter: + def __init__(self, element, context): + self.name = element.nsProp( "name", None ) + + ts = element.nsProp( "type", None ) + self.type_expr = typeexpr.type_expression( ts, context ) + + temp = element.nsProp( "variable_param", None ) + if temp: + self.count_parameter_list = temp.split( ' ' ) + else: + self.count_parameter_list = [] + + # The count tag can be either a numeric string or the name of + # a variable. If it is the name of a variable, the int(c) + # statement will throw an exception, and the except block will + # take over. + + c = element.nsProp( "count", None ) + try: + count = int(c) + self.count = count + self.counter = None + except Exception,e: + count = 1 + self.count = 0 + self.counter = c + + self.count_scale = int(element.nsProp( "count_scale", None )) + + elements = (count * self.count_scale) + if elements == 1: + elements = 0 + + #if ts == "GLdouble": + # print '/* stack size -> %s = %u (before)*/' % (self.name, self.type_expr.get_stack_size()) + # print '/* # elements = %u */' % (elements) + self.type_expr.set_elements( elements ) + #if ts == "GLdouble": + # print '/* stack size -> %s = %u (after) */' % (self.name, self.type_expr.get_stack_size()) + + self.is_client_only = is_attr_true( element, 'client_only' ) + self.is_counter = is_attr_true( element, 'counter' ) + self.is_output = is_attr_true( element, 'output' ) + + + # Pixel data has special parameters. + + self.width = element.nsProp('img_width', None) + self.height = element.nsProp('img_height', None) + self.depth = element.nsProp('img_depth', None) + self.extent = element.nsProp('img_extent', None) + + self.img_xoff = element.nsProp('img_xoff', None) + self.img_yoff = element.nsProp('img_yoff', None) + self.img_zoff = element.nsProp('img_zoff', None) + self.img_woff = element.nsProp('img_woff', None) + + self.img_format = element.nsProp('img_format', None) + self.img_type = element.nsProp('img_type', None) + self.img_target = element.nsProp('img_target', None) + + self.img_pad_dimensions = is_attr_true( element, 'img_pad_dimensions' ) + self.img_null_flag = is_attr_true( element, 'img_null_flag' ) + self.img_send_null = is_attr_true( element, 'img_send_null' ) + + self.is_padding = is_attr_true( element, 'padding' ) + return + + + def compatible(self, other): + return 1 + + + def is_array(self): + return self.is_pointer() + + + def is_pointer(self): + return self.type_expr.is_pointer() + + + def is_image(self): + if self.width: + return 1 + else: + return 0 + + + def is_variable_length(self): + return len(self.count_parameter_list) or self.counter + + + def is_64_bit(self): + count = self.type_expr.get_element_count() + if count: + if (self.size() / count) == 8: + return 1 + else: + if self.size() == 8: + return 1 + + return 0 + + + def string(self): + return self.type_expr.original_string + " " + self.name + + + def type_string(self): + return self.type_expr.original_string + + + def get_base_type_string(self): + return self.type_expr.get_base_name() + + + def get_dimensions(self): + if not self.width: + return [ 0, "0", "0", "0", "0" ] + + dim = 1 + w = self.width + h = "1" + d = "1" + e = "1" + + if self.height: + dim = 2 + h = self.height + + if self.depth: + dim = 3 + d = self.depth + + if self.extent: + dim = 4 + e = self.extent + + return [ dim, w, h, d, e ] + + + def get_stack_size(self): + return self.type_expr.get_stack_size() + + + def size(self): + if self.is_image(): + return 0 + else: + return self.type_expr.get_element_size() + + + def get_element_count(self): + c = self.type_expr.get_element_count() + if c == 0: + return 1 + + return c + + + def size_string(self, use_parens = 1): + s = self.size() + if self.counter or self.count_parameter_list: + list = [ "compsize" ] + + if self.counter and self.count_parameter_list: + list.append( self.counter ) + elif self.counter: + list = [ self.counter ] + + if s > 1: + list.append( str(s) ) + + if len(list) > 1 and use_parens : + return "(%s)" % (string.join(list, " * ")) + else: + return string.join(list, " * ") + + elif self.is_image(): + return "compsize" + else: + return str(s) + + + def format_string(self): + if self.type_expr.original_string == "GLenum": + return "0x%x" + else: + return self.type_expr.format_string() + + + +class gl_function( gl_item ): + def __init__(self, element, context): + self.context = context + self.name = None + + self.entry_points = [] + self.return_type = "void" + self.parameters = [] + self.offset = -1 + self.initialized = 0 + self.images = [] + + self.assign_offset = 0 + + self.static_entry_points = [] + + # Track the parameter string (for the function prototype) + # for each entry-point. This is done because some functions + # change their prototype slightly when promoted from extension + # to ARB extension to core. glTexImage3DEXT and glTexImage3D + # are good examples of this. Scripts that need to generate + # code for these differing aliases need to real prototype + # for each entry-point. Otherwise, they may generate code + # that won't compile. + + self.parameter_strings = {} + + self.process_element( element ) + + return + + + def process_element(self, element): + name = element.nsProp( "name", None ) + alias = element.nsProp( "alias", None ) + + if is_attr_true(element, "static_dispatch"): + self.static_entry_points.append(name) + + self.entry_points.append( name ) + if alias: + true_name = alias + else: + true_name = name + + # Only try to set the offset when a non-alias + # entry-point is being processes. + + offset = element.nsProp( "offset", None ) + if offset: + try: + o = int( offset ) + self.offset = o + except Exception, e: + self.offset = -1 + if offset == "assign": + self.assign_offset = 1 + + + if not self.name: + self.name = true_name + elif self.name != true_name: + raise RuntimeError("Function true name redefined. Was %s, now %s." % (self.name, true_name)) + + + # There are two possible cases. The first time an entry-point + # with data is seen, self.initialized will be 0. On that + # pass, we just fill in the data. The next time an + # entry-point with data is seen, self.initialized will be 1. + # On that pass we have to make that the new values match the + # valuse from the previous entry-point. + + parameters = [] + return_type = "void" + child = element.children + while child: + if child.type == "element": + if child.name == "return": + return_type = child.nsProp( "type", None ) + elif child.name == "param": + param = self.context.factory.create_item( "parameter", child, self.context) + parameters.append( param ) + + child = child.next + + + if self.initialized: + if self.return_type != return_type: + raise RuntimeError( "Return type changed in %s. Was %s, now %s." % (name, self.return_type, return_type)) + + if len(parameters) != len(self.parameters): + raise RuntimeError( "Parameter count mismatch in %s. Was %d, now %d." % (name, len(self.parameters), len(parameters))) + + for j in range(0, len(parameters)): + p1 = parameters[j] + p2 = self.parameters[j] + if not p1.compatible( p2 ): + raise RuntimeError( 'Parameter type mismatch in %s. "%s" was "%s", now "%s".' % (name, p2.name, p2.type_expr.original_string, p1.type_expr.original_string)) + + + if true_name == name or not self.initialized: + self.return_type = return_type + self.parameters = parameters + + for param in self.parameters: + if param.is_image(): + self.images.append( param ) + + if element.children: + self.initialized = 1 + self.parameter_strings[name] = create_parameter_string(parameters, 1) + else: + self.parameter_strings[name] = None + + return + + + def get_images(self): + """Return potentially empty list of input images.""" + return self.images + + + def parameterIterator(self): + return self.parameters.__iter__(); + + + def get_parameter_string(self, entrypoint = None): + if entrypoint: + s = self.parameter_strings[ entrypoint ] + if s: + return s + + return create_parameter_string( self.parameters, 1 ) + + def get_called_parameter_string(self): + p_string = "" + comma = "" + + for p in self.parameterIterator(): + p_string = p_string + comma + p.name + comma = ", " + + return p_string + + + def is_static_entry_point(self, name): + return name in self.static_entry_points + + def dispatch_name(self): + if self.name in self.static_entry_points: + return self.name + else: + return "_dispatch_stub_%u" % (self.offset) + + def static_name(self, name): + if name in self.static_entry_points: + return name + else: + return "_dispatch_stub_%u" % (self.offset) + + +class gl_item_factory: + """Factory to create objects derived from gl_item.""" + + def create_item(self, item_name, element, context): + if item_name == "function": + return gl_function(element, context) + if item_name == "type": + return gl_type(element, context) + elif item_name == "enum": + return gl_enum(element, context) + elif item_name == "parameter": + return gl_parameter(element, context) + elif item_name == "api": + return gl_api(self) + else: + return None + + +class gl_api: + def __init__(self, factory): + self.functions_by_name = {} + self.enums_by_name = {} + self.types_by_name = {} + + self.category_dict = {} + self.categories = [{}, {}, {}, {}] + + self.factory = factory + + self.next_offset = 0 + + typeexpr.create_initial_types() + return + + + def process_element(self, doc): + element = doc.children + while element.type != "element" or element.name != "OpenGLAPI": + element = element.next + + if element: + self.process_OpenGLAPI(element) + return + + + def process_OpenGLAPI(self, element): + child = element.children + while child: + if child.type == "element": + if child.name == "category": + self.process_category( child ) + elif child.name == "OpenGLAPI": + self.process_OpenGLAPI( child ) + + child = child.next + + return + + + def process_category(self, cat): + cat_name = cat.nsProp( "name", None ) + cat_number = cat.nsProp( "number", None ) + + [cat_type, key] = classify_category(cat_name, cat_number) + self.categories[cat_type][key] = [cat_name, cat_number] + + child = cat.children + while child: + if child.type == "element": + if child.name == "function": + func_name = real_function_name( child ) + + temp_name = child.nsProp( "name", None ) + self.category_dict[ temp_name ] = [cat_name, cat_number] + + if self.functions_by_name.has_key( func_name ): + func = self.functions_by_name[ func_name ] + func.process_element( child ) + else: + func = self.factory.create_item( "function", child, self ) + self.functions_by_name[ func_name ] = func + + if func.offset >= self.next_offset: + self.next_offset = func.offset + 1 + + + elif child.name == "enum": + enum = self.factory.create_item( "enum", child, self ) + self.enums_by_name[ enum.name ] = enum + elif child.name == "type": + t = self.factory.create_item( "type", child, self ) + self.types_by_name[ "GL" + t.name ] = t + + + child = child.next + + return + + + def functionIterateByCategory(self, cat = None): + """Iterate over functions by category. + + If cat is None, all known functions are iterated in category + order. See classify_category for details of the ordering. + Within a category, functions are sorted by name. If cat is + not None, then only functions in that category are iterated. + """ + lists = [{}, {}, {}, {}] + + for func in self.functionIterateAll(): + [cat_name, cat_number] = self.category_dict[func.name] + + if (cat == None) or (cat == cat_name): + [func_cat_type, key] = classify_category(cat_name, cat_number) + + if not lists[func_cat_type].has_key(key): + lists[func_cat_type][key] = {} + + lists[func_cat_type][key][func.name] = func + + + functions = [] + for func_cat_type in range(0,4): + keys = lists[func_cat_type].keys() + keys.sort() + + for key in keys: + names = lists[func_cat_type][key].keys() + names.sort() + + for name in names: + functions.append(lists[func_cat_type][key][name]) + + return functions.__iter__() + + + def functionIterateByOffset(self): + max_offset = -1 + for func in self.functions_by_name.itervalues(): + if func.offset > max_offset: + max_offset = func.offset + + + temp = [None for i in range(0, max_offset + 1)] + for func in self.functions_by_name.itervalues(): + if func.offset != -1: + temp[ func.offset ] = func + + + list = [] + for i in range(0, max_offset + 1): + if temp[i]: + list.append(temp[i]) + + return list.__iter__(); + + + def functionIterateAll(self): + return self.functions_by_name.itervalues() + + + def enumIterateByName(self): + keys = self.enums_by_name.keys() + keys.sort() + + list = [] + for enum in keys: + list.append( self.enums_by_name[ enum ] ) + + return list.__iter__() + + + def categoryIterate(self): + """Iterate over categories. + + Iterate over all known categories in the order specified by + classify_category. Each iterated value is a tuple of the + name and number (which may be None) of the category. + """ + + list = [] + for cat_type in range(0,4): + keys = self.categories[cat_type].keys() + keys.sort() + + for key in keys: + list.append(self.categories[cat_type][key]) + + return list.__iter__() + + + def get_category_for_name( self, name ): + if self.category_dict.has_key(name): + return self.category_dict[name] + else: + return ["", None] + + + def typeIterate(self): + return self.types_by_name.itervalues() + + + def find_type( self, type_name ): + if type_name in self.types_by_name: + return self.types_by_name[ type_name ].type_expr + else: + print "Unable to find base type matching \"%s\"." % (type_name) + return None diff --git a/mesalib/src/mesa/glapi/gl_and_glX_API.xml b/mesalib/src/mesa/glapi/gl_and_glX_API.xml new file mode 100644 index 000000000..34c977e9c --- /dev/null +++ b/mesalib/src/mesa/glapi/gl_and_glX_API.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/mesalib/src/mesa/glapi/gl_apitemp.py b/mesalib/src/mesa/glapi/gl_apitemp.py new file mode 100644 index 000000000..a37c08d6c --- /dev/null +++ b/mesalib/src/mesa/glapi/gl_apitemp.py @@ -0,0 +1,253 @@ +#!/usr/bin/env python + +# (C) Copyright IBM Corporation 2004, 2005 +# 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 +# IBM AND/OR ITS 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 + +import gl_XML, glX_XML +import license +import sys, getopt + +class PrintGlOffsets(gl_XML.gl_print_base): + def __init__(self): + gl_XML.gl_print_base.__init__(self) + + self.name = "gl_apitemp.py (from Mesa)" + self.license = license.bsd_license_template % ( \ +"""Copyright (C) 1999-2001 Brian Paul All Rights Reserved. +(C) Copyright IBM Corporation 2004""", "BRIAN PAUL, IBM") + + self.undef_list.append( "KEYWORD1" ) + self.undef_list.append( "KEYWORD1_ALT" ) + self.undef_list.append( "KEYWORD2" ) + self.undef_list.append( "NAME" ) + self.undef_list.append( "DISPATCH" ) + self.undef_list.append( "RETURN_DISPATCH" ) + self.undef_list.append( "DISPATCH_TABLE_NAME" ) + self.undef_list.append( "UNUSED_TABLE_NAME" ) + self.undef_list.append( "TABLE_ENTRY" ) + + + def printFunction(self, f, name): + p_string = "" + o_string = "" + t_string = "" + comma = "" + + if f.is_static_entry_point(name): + keyword = "KEYWORD1" + else: + keyword = "KEYWORD1_ALT" + + n = f.static_name(name) + + for p in f.parameterIterator(): + if p.is_padding: + continue + + if p.is_pointer(): + cast = "(const void *) " + else: + cast = "" + + t_string = t_string + comma + p.format_string() + p_string = p_string + comma + p.name + o_string = o_string + comma + cast + p.name + comma = ", " + + + if f.return_type != 'void': + dispatch = "RETURN_DISPATCH" + else: + dispatch = "DISPATCH" + + if f.has_different_protocol(name): + print '#ifndef GLX_INDIRECT_RENDERING' + + if not f.is_static_entry_point(name): + print '%s %s KEYWORD2 NAME(%s)(%s);' % (keyword, f.return_type, n, f.get_parameter_string(name)) + print '' + + print '%s %s KEYWORD2 NAME(%s)(%s)' % (keyword, f.return_type, n, f.get_parameter_string(name)) + print '{' + if p_string == "": + print ' %s(%s, (), (F, "gl%s();\\n"));' \ + % (dispatch, f.name, name) + else: + print ' %s(%s, (%s), (F, "gl%s(%s);\\n", %s));' \ + % (dispatch, f.name, p_string, name, t_string, o_string) + print '}' + if f.has_different_protocol(name): + print '#endif /* GLX_INDIRECT_RENDERING */' + print '' + return + + def printRealHeader(self): + print '' + self.printVisibility( "HIDDEN", "hidden" ) + print """ +/* + * This file is a template which generates the OpenGL API entry point + * functions. It should be included by a .c file which first defines + * the following macros: + * KEYWORD1 - usually nothing, but might be __declspec(dllexport) on Win32 + * KEYWORD2 - usually nothing, but might be __stdcall on Win32 + * NAME(n) - builds the final function name (usually add "gl" prefix) + * DISPATCH(func, args, msg) - code to do dispatch of named function. + * msg is a printf-style debug message. + * RETURN_DISPATCH(func, args, msg) - code to do dispatch with a return value + * + * Here is an example which generates the usual OpenGL functions: + * #define KEYWORD1 + * #define KEYWORD2 + * #define NAME(func) gl##func + * #define DISPATCH(func, args, msg) \\ + * struct _glapi_table *dispatch = CurrentDispatch; \\ + * (*dispatch->func) args + * #define RETURN DISPATCH(func, args, msg) \\ + * struct _glapi_table *dispatch = CurrentDispatch; \\ + * return (*dispatch->func) args + * + */ + + +#if defined( NAME ) +#ifndef KEYWORD1 +#define KEYWORD1 +#endif + +#ifndef KEYWORD1_ALT +#define KEYWORD1_ALT HIDDEN +#endif + +#ifndef KEYWORD2 +#define KEYWORD2 +#endif + +#ifndef DISPATCH +#error DISPATCH must be defined +#endif + +#ifndef RETURN_DISPATCH +#error RETURN_DISPATCH must be defined +#endif + +""" + return + + + + def printInitDispatch(self, api): + print """ +#endif /* defined( NAME ) */ + +/* + * This is how a dispatch table can be initialized with all the functions + * we generated above. + */ +#ifdef DISPATCH_TABLE_NAME + +#ifndef TABLE_ENTRY +#error TABLE_ENTRY must be defined +#endif + +static _glapi_proc DISPATCH_TABLE_NAME[] = {""" + for f in api.functionIterateByOffset(): + print ' TABLE_ENTRY(%s),' % (f.dispatch_name()) + + print ' /* A whole bunch of no-op functions. These might be called' + print ' * when someone tries to call a dynamically-registered' + print ' * extension function without a current rendering context.' + print ' */' + for i in range(1, 100): + print ' TABLE_ENTRY(Unused),' + + print '};' + print '#endif /* DISPATCH_TABLE_NAME */' + print '' + return + + + def printAliasedTable(self, api): + print """ +/* + * This is just used to silence compiler warnings. + * We list the functions which are not otherwise used. + */ +#ifdef UNUSED_TABLE_NAME +static _glapi_proc UNUSED_TABLE_NAME[] = {""" + + for f in api.functionIterateByOffset(): + for n in f.entry_points: + if n != f.name: + if f.is_static_entry_point(n): + text = ' TABLE_ENTRY(%s),' % (n) + + if f.has_different_protocol(n): + print '#ifndef GLX_INDIRECT_RENDERING' + print text + print '#endif' + else: + print text + print '};' + print '#endif /*UNUSED_TABLE_NAME*/' + print '' + return + + + def printBody(self, api): + for func in api.functionIterateByOffset(): + got_stub = 0 + for n in func.entry_points: + if func.is_static_entry_point(n): + self.printFunction(func, n) + elif not got_stub: + self.printFunction(func, n) + got_stub = 1 + + self.printInitDispatch(api) + self.printAliasedTable(api) + return + + +def show_usage(): + print "Usage: %s [-f input_file_name]" % sys.argv[0] + sys.exit(1) + +if __name__ == '__main__': + file_name = "gl_API.xml" + + try: + (args, trail) = getopt.getopt(sys.argv[1:], "f:") + except Exception,e: + show_usage() + + for (arg,val) in args: + if arg == "-f": + file_name = val + + api = gl_XML.parse_GL_API(file_name, glX_XML.glx_item_factory()) + + printer = PrintGlOffsets() + printer.Print(api) diff --git a/mesalib/src/mesa/glapi/gl_enums.py b/mesalib/src/mesa/glapi/gl_enums.py new file mode 100644 index 000000000..27ab11953 --- /dev/null +++ b/mesalib/src/mesa/glapi/gl_enums.py @@ -0,0 +1,243 @@ +#!/usr/bin/python2 +# -*- Mode: Python; py-indent-offset: 8 -*- + +# (C) Copyright Zack Rusin 2005 +# 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 +# IBM AND/OR ITS 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: +# Zack Rusin + +import license +import gl_XML +import sys, getopt + +class PrintGlEnums(gl_XML.gl_print_base): + + def __init__(self): + gl_XML.gl_print_base.__init__(self) + + self.name = "gl_enums.py (from Mesa)" + self.license = license.bsd_license_template % ( \ +"""Copyright (C) 1999-2005 Brian Paul All Rights Reserved.""", "BRIAN PAUL") + self.enum_table = {} + + + def printRealHeader(self): + print '#include "glheader.h"' + print '#include "mfeatures.h"' + print '#include "enums.h"' + print '#include "imports.h"' + print '' + print 'typedef struct {' + print ' size_t offset;' + print ' int n;' + print '} enum_elt;' + print '' + return + + def print_code(self): + print """ +typedef int (*cfunc)(const void *, const void *); + +/** + * Compare a key name to an element in the \c all_enums array. + * + * \c bsearch always passes the key as the first parameter and the pointer + * to the array element as the second parameter. We can elimiate some + * extra work by taking advantage of that fact. + * + * \param a Pointer to the desired enum name. + * \param b Pointer to an element of the \c all_enums array. + */ +static int compar_name( const char *a, const enum_elt *b ) +{ + return _mesa_strcmp( a, & enum_string_table[ b->offset ] ); +} + +/** + * Compare a key enum value to an element in the \c all_enums array. + * + * \c bsearch always passes the key as the first parameter and the pointer + * to the array element as the second parameter. We can elimiate some + * extra work by taking advantage of that fact. + * + * \param a Pointer to the desired enum name. + * \param b Pointer to an index into the \c all_enums array. + */ +static int compar_nr( const int *a, const unsigned *b ) +{ + return a[0] - all_enums[*b].n; +} + + +static char token_tmp[20]; + +const char *_mesa_lookup_enum_by_nr( int nr ) +{ + unsigned * i; + + i = (unsigned *) _mesa_bsearch(& nr, reduced_enums, + Elements(reduced_enums), + sizeof(reduced_enums[0]), + (cfunc) compar_nr); + + if ( i != NULL ) { + return & enum_string_table[ all_enums[ *i ].offset ]; + } + else { + /* this is not re-entrant safe, no big deal here */ + _mesa_sprintf(token_tmp, "0x%x", nr); + return token_tmp; + } +} + +/* Get the name of an enum given that it is a primitive type. Avoids + * GL_FALSE/GL_POINTS ambiguity and others. + */ +const char *_mesa_lookup_prim_by_nr( int nr ) +{ + switch (nr) { + case GL_POINTS: return "GL_POINTS"; + case GL_LINES: return "GL_LINES"; + case GL_LINE_STRIP: return "GL_LINE_STRIP"; + case GL_LINE_LOOP: return "GL_LINE_LOOP"; + case GL_TRIANGLES: return "GL_TRIANGLES"; + case GL_TRIANGLE_STRIP: return "GL_TRIANGLE_STRIP"; + case GL_TRIANGLE_FAN: return "GL_TRIANGLE_FAN"; + case GL_QUADS: return "GL_QUADS"; + case GL_QUAD_STRIP: return "GL_QUAD_STRIP"; + case GL_POLYGON: return "GL_POLYGON"; + case GL_POLYGON+1: return "OUTSIDE_BEGIN_END"; + default: return ""; + } +} + + + +int _mesa_lookup_enum_by_name( const char *symbol ) +{ + enum_elt * f = NULL; + + if ( symbol != NULL ) { + f = (enum_elt *) _mesa_bsearch(symbol, all_enums, + Elements(all_enums), + sizeof( enum_elt ), + (cfunc) compar_name); + } + + return (f != NULL) ? f->n : -1; +} + +""" + return + + + def printBody(self, api): + self.process_enums( api ) + + keys = self.enum_table.keys() + keys.sort() + + name_table = [] + enum_table = {} + + for enum in keys: + low_pri = 9 + for [name, pri] in self.enum_table[ enum ]: + name_table.append( [name, enum] ) + + if pri < low_pri: + low_pri = pri + enum_table[enum] = name + + + name_table.sort() + + string_offsets = {} + i = 0; + print 'LONGSTRING static const char enum_string_table[] = ' + for [name, enum] in name_table: + print ' "%s\\0"' % (name) + string_offsets[ name ] = i + i += len(name) + 1 + + print ' ;' + print '' + + + print 'static const enum_elt all_enums[%u] =' % (len(name_table)) + print '{' + for [name, enum] in name_table: + print ' { %5u, 0x%08X }, /* %s */' % (string_offsets[name], enum, name) + print '};' + print '' + + print 'static const unsigned reduced_enums[%u] =' % (len(keys)) + print '{' + for enum in keys: + name = enum_table[ enum ] + if [name, enum] not in name_table: + print ' /* Error! %s, 0x%04x */ 0,' % (name, enum) + else: + i = name_table.index( [name, enum] ) + + print ' %4u, /* %s */' % (i, name) + print '};' + + + self.print_code() + return + + + def process_enums(self, api): + self.enum_table = {} + + for obj in api.enumIterateByName(): + if obj.value not in self.enum_table: + self.enum_table[ obj.value ] = [] + + + name = "GL_" + obj.name + priority = obj.priority() + self.enum_table[ obj.value ].append( [name, priority] ) + + +def show_usage(): + print "Usage: %s [-f input_file_name]" % sys.argv[0] + sys.exit(1) + +if __name__ == '__main__': + file_name = "gl_API.xml" + + try: + (args, trail) = getopt.getopt(sys.argv[1:], "f:") + except Exception,e: + show_usage() + + for (arg,val) in args: + if arg == "-f": + file_name = val + + api = gl_XML.parse_GL_API( file_name ) + + printer = PrintGlEnums() + printer.Print( api ) diff --git a/mesalib/src/mesa/glapi/gl_offsets.py b/mesalib/src/mesa/glapi/gl_offsets.py new file mode 100644 index 000000000..59f8d372b --- /dev/null +++ b/mesalib/src/mesa/glapi/gl_offsets.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python + +# (C) Copyright IBM Corporation 2004, 2005 +# 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 +# IBM AND/OR ITS 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 + +import gl_XML +import license +import sys, getopt + +class PrintGlOffsets(gl_XML.gl_print_base): + def __init__(self): + gl_XML.gl_print_base.__init__(self) + + self.name = "gl_offsets.py (from Mesa)" + self.header_tag = '_GLAPI_OFFSETS_H_' + self.license = license.bsd_license_template % ( \ +"""Copyright (C) 1999-2001 Brian Paul All Rights Reserved. +(C) Copyright IBM Corporation 2004""", "BRIAN PAUL, IBM") + return + + def printBody(self, api): + abi = [ "1.0", "1.1", "1.2", "GL_ARB_multitexture" ] + + functions = [] + abi_functions = [] + count = 0 + for f in api.functionIterateByOffset(): + [category, num] = api.get_category_for_name( f.name ) + if category not in abi: + functions.append( [f, count] ) + count += 1 + else: + abi_functions.append( f ) + + + for f in abi_functions: + print '#define _gloffset_%s %d' % (f.name, f.offset) + last_static = f.offset + + print '' + print '#if !defined(IN_DRI_DRIVER)' + print '' + + for [f, index] in functions: + print '#define _gloffset_%s %d' % (f.name, f.offset) + + print '#define _gloffset_FIRST_DYNAMIC %d' % (api.next_offset) + + print '' + print '#else' + print '' + + for [f, index] in functions: + print '#define _gloffset_%s driDispatchRemapTable[%s_remap_index]' % (f.name, f.name) + + print '' + print '#endif /* !defined(IN_DRI_DRIVER) */' + + return + + +def show_usage(): + print "Usage: %s [-f input_file_name]" % sys.argv[0] + sys.exit(1) + +if __name__ == '__main__': + file_name = "gl_API.xml" + + try: + (args, trail) = getopt.getopt(sys.argv[1:], "f:") + except Exception,e: + show_usage() + + for (arg,val) in args: + if arg == "-f": + file_name = val + + api = gl_XML.parse_GL_API( file_name ) + + printer = PrintGlOffsets() + printer.Print( api ) diff --git a/mesalib/src/mesa/glapi/gl_procs.py b/mesalib/src/mesa/glapi/gl_procs.py new file mode 100644 index 000000000..cd1a68cee --- /dev/null +++ b/mesalib/src/mesa/glapi/gl_procs.py @@ -0,0 +1,188 @@ +#!/usr/bin/env python + +# (C) Copyright IBM Corporation 2004, 2005 +# 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 +# IBM AND/OR ITS 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 + +import license +import gl_XML, glX_XML +import sys, getopt + +class PrintGlProcs(gl_XML.gl_print_base): + def __init__(self, long_strings): + gl_XML.gl_print_base.__init__(self) + + self.long_strings = long_strings + self.name = "gl_procs.py (from Mesa)" + self.license = license.bsd_license_template % ( \ +"""Copyright (C) 1999-2001 Brian Paul All Rights Reserved. +(C) Copyright IBM Corporation 2004, 2006""", "BRIAN PAUL, IBM") + + + def printRealHeader(self): + print """ +/* This file is only included by glapi.c and is used for + * the GetProcAddress() function + */ + +typedef struct { + GLint Name_offset; +#if defined(NEED_FUNCTION_POINTER) || defined(GLX_INDIRECT_RENDERING) + _glapi_proc Address; +#endif + GLuint Offset; +} glprocs_table_t; + +#if !defined(NEED_FUNCTION_POINTER) && !defined(GLX_INDIRECT_RENDERING) +# define NAME_FUNC_OFFSET(n,f1,f2,f3,o) { n , o } +#elif defined(NEED_FUNCTION_POINTER) && !defined(GLX_INDIRECT_RENDERING) +# define NAME_FUNC_OFFSET(n,f1,f2,f3,o) { n , (_glapi_proc) f1 , o } +#elif defined(NEED_FUNCTION_POINTER) && defined(GLX_INDIRECT_RENDERING) +# define NAME_FUNC_OFFSET(n,f1,f2,f3,o) { n , (_glapi_proc) f2 , o } +#elif !defined(NEED_FUNCTION_POINTER) && defined(GLX_INDIRECT_RENDERING) +# define NAME_FUNC_OFFSET(n,f1,f2,f3,o) { n , (_glapi_proc) f3 , o } +#endif + +""" + return + + def printRealFooter(self): + print '' + print '#undef NAME_FUNC_OFFSET' + return + + def printFunctionString(self, name): + if self.long_strings: + print ' "gl%s\\0"' % (name) + else: + print " 'g','l',", + for c in name: + print "'%s'," % (c), + + print "'\\0'," + + + def printBody(self, api): + print '' + if self.long_strings: + print 'static const char gl_string_table[] =' + else: + print 'static const char gl_string_table[] = {' + + base_offset = 0 + table = [] + for func in api.functionIterateByOffset(): + name = func.dispatch_name() + self.printFunctionString(func.name) + table.append((base_offset, "gl" + name, "gl" + name, "NULL", func.name)) + + # The length of the function's name, plus 2 for "gl", + # plus 1 for the NUL. + + base_offset += len(func.name) + 3 + + + for func in api.functionIterateByOffset(): + for n in func.entry_points: + if n != func.name: + name = func.dispatch_name() + self.printFunctionString( n ) + + if func.has_different_protocol(n): + alt_name = "gl" + func.static_glx_name(n) + table.append((base_offset, "gl" + name, alt_name, alt_name, func.name)) + else: + table.append((base_offset, "gl" + name, "gl" + name, "NULL", func.name)) + + base_offset += len(n) + 3 + + + if self.long_strings: + print ' ;' + else: + print '};' + + print '' + print '' + print "#ifdef USE_MGL_NAMESPACE" + for func in api.functionIterateByOffset(): + for n in func.entry_points: + if (not func.is_static_entry_point(func.name)) or (func.has_different_protocol(n) and not func.is_static_entry_point(n)): + print '#define gl_dispatch_stub_%u mgl_dispatch_stub_%u' % (func.offset, func.offset) + break + print "#endif /* USE_MGL_NAMESPACE */" + print '' + print '' + print '#if defined(NEED_FUNCTION_POINTER) || defined(GLX_INDIRECT_RENDERING)' + for func in api.functionIterateByOffset(): + for n in func.entry_points: + if (not func.is_static_entry_point(func.name)) or (func.has_different_protocol(n) and not func.is_static_entry_point(n)): + print '%s GLAPIENTRY gl_dispatch_stub_%u(%s);' % (func.return_type, func.offset, func.get_parameter_string()) + break + + print '#endif /* defined(NEED_FUNCTION_POINTER) || defined(GLX_INDIRECT_RENDERING) */' + + print '' + print 'static const glprocs_table_t static_functions[] = {' + + for info in table: + print ' NAME_FUNC_OFFSET(%5u, %s, %s, %s, _gloffset_%s),' % info + + print ' NAME_FUNC_OFFSET(-1, NULL, NULL, NULL, 0)' + print '};' + return + + +def show_usage(): + print "Usage: %s [-f input_file_name] [-m mode]" % sys.argv[0] + print "mode can be one of:" + print " long - Create code for compilers that can handle very" + print " long string constants. (default)" + print " short - Create code for compilers that can only handle" + print " ANSI C89 string constants." + sys.exit(1) + +if __name__ == '__main__': + file_name = "gl_API.xml" + + try: + (args, trail) = getopt.getopt(sys.argv[1:], "f:m:") + except Exception,e: + show_usage() + + long_string = 1 + for (arg,val) in args: + if arg == "-f": + file_name = val + elif arg == "-m": + if val == "short": + long_string = 0 + elif val == "long": + long_string = 1 + else: + show_usage() + + api = gl_XML.parse_GL_API(file_name, glX_XML.glx_item_factory()) + printer = PrintGlProcs(long_string) + printer.Print(api) diff --git a/mesalib/src/mesa/glapi/gl_table.py b/mesalib/src/mesa/glapi/gl_table.py new file mode 100644 index 000000000..55a33748a --- /dev/null +++ b/mesalib/src/mesa/glapi/gl_table.py @@ -0,0 +1,199 @@ +#!/usr/bin/python2 + +# (C) Copyright IBM Corporation 2004 +# 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 +# IBM AND/OR ITS 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 + +import gl_XML +import license +import sys, getopt + +class PrintGlTable(gl_XML.gl_print_base): + def __init__(self): + gl_XML.gl_print_base.__init__(self) + + self.header_tag = '_GLAPI_TABLE_H_' + self.name = "gl_table.py (from Mesa)" + self.license = license.bsd_license_template % ( \ +"""Copyright (C) 1999-2003 Brian Paul All Rights Reserved. +(C) Copyright IBM Corporation 2004""", "BRIAN PAUL, IBM") + return + + + def printBody(self, api): + for f in api.functionIterateByOffset(): + arg_string = f.get_parameter_string() + print ' %s (GLAPIENTRYP %s)(%s); /* %d */' % (f.return_type, f.name, arg_string, f.offset) + + + def printRealHeader(self): + print '#ifndef GLAPIENTRYP' + print '# ifndef GLAPIENTRY' + print '# define GLAPIENTRY' + print '# endif' + print '' + print '# define GLAPIENTRYP GLAPIENTRY *' + print '#endif' + print '' + print '' + print 'struct _glapi_table' + print '{' + return + + + def printRealFooter(self): + print '};' + return + + +class PrintRemapTable(gl_XML.gl_print_base): + def __init__(self): + gl_XML.gl_print_base.__init__(self) + + self.header_tag = '_DISPATCH_H_' + self.name = "gl_table.py (from Mesa)" + self.license = license.bsd_license_template % ("(C) Copyright IBM Corporation 2005", "IBM") + return + + + def printRealHeader(self): + print """ +#include "glapitable.h" +/** + * \\file dispatch.h + * Macros for handling GL dispatch tables. + * + * For each known GL function, there are 3 macros in this file. The first + * macro is named CALL_FuncName and is used to call that GL function using + * the specified dispatch table. The other 2 macros, called GET_FuncName + * can SET_FuncName, are used to get and set the dispatch pointer for the + * named function in the specified dispatch table. + */ +""" + + return + + def printBody(self, api): + print '#define CALL_by_offset(disp, cast, offset, parameters) \\' + print ' (*(cast (GET_by_offset(disp, offset)))) parameters' + print '#define GET_by_offset(disp, offset) \\' + print ' (offset >= 0) ? (((_glapi_proc *)(disp))[offset]) : NULL' + print '#define SET_by_offset(disp, offset, fn) \\' + print ' do { \\' + print ' if ( (offset) < 0 ) { \\' + print ' /* fprintf( stderr, "[%s:%u] SET_by_offset(%p, %d, %s)!\\n", */ \\' + print ' /* __func__, __LINE__, disp, offset, # fn); */ \\' + print ' /* abort(); */ \\' + print ' } \\' + print ' else { \\' + print ' ( (_glapi_proc *) (disp) )[offset] = (_glapi_proc) fn; \\' + print ' } \\' + print ' } while(0)' + print '' + + abi = [ "1.0", "1.1", "1.2", "GL_ARB_multitexture" ] + + functions = [] + abi_functions = [] + count = 0 + for f in api.functionIterateByOffset(): + [category, num] = api.get_category_for_name( f.name ) + if category not in abi: + functions.append( [f, count] ) + count += 1 + else: + abi_functions.append( f ) + + + for f in abi_functions: + print '#define CALL_%s(disp, parameters) (*((disp)->%s)) parameters' % (f.name, f.name) + print '#define GET_%s(disp) ((disp)->%s)' % (f.name, f.name) + print '#define SET_%s(disp, fn) ((disp)->%s = fn)' % (f.name, f.name) + + + print '' + print '#if !defined(IN_DRI_DRIVER)' + print '' + + for [f, index] in functions: + print '#define CALL_%s(disp, parameters) (*((disp)->%s)) parameters' % (f.name, f.name) + print '#define GET_%s(disp) ((disp)->%s)' % (f.name, f.name) + print '#define SET_%s(disp, fn) ((disp)->%s = fn)' % (f.name, f.name) + + print '' + print '#else' + print '' + print '#define driDispatchRemapTable_size %u' % (count) + print 'extern int driDispatchRemapTable[ driDispatchRemapTable_size ];' + print '' + + for [f, index] in functions: + print '#define %s_remap_index %u' % (f.name, index) + + print '' + + for [f, index] in functions: + arg_string = gl_XML.create_parameter_string( f.parameters, 0 ) + cast = '%s (GLAPIENTRYP)(%s)' % (f.return_type, arg_string) + + print '#define CALL_%s(disp, parameters) CALL_by_offset(disp, (%s), driDispatchRemapTable[%s_remap_index], parameters)' % (f.name, cast, f.name) + print '#define GET_%s(disp) GET_by_offset(disp, driDispatchRemapTable[%s_remap_index])' % (f.name, f.name) + print '#define SET_%s(disp, fn) SET_by_offset(disp, driDispatchRemapTable[%s_remap_index], fn)' % (f.name, f.name) + + + print '' + print '#endif /* !defined(IN_DRI_DRIVER) */' + return + + +def show_usage(): + print "Usage: %s [-f input_file_name] [-m mode]" % sys.argv[0] + print " -m mode Mode can be 'table' or 'remap_table'." + sys.exit(1) + +if __name__ == '__main__': + file_name = "gl_API.xml" + + try: + (args, trail) = getopt.getopt(sys.argv[1:], "f:m:") + except Exception,e: + show_usage() + + mode = "table" + for (arg,val) in args: + if arg == "-f": + file_name = val + elif arg == "-m": + mode = val + + if mode == "table": + printer = PrintGlTable() + elif mode == "remap_table": + printer = PrintRemapTable() + else: + show_usage() + + api = gl_XML.parse_GL_API( file_name ) + + printer.Print( api ) diff --git a/mesalib/src/mesa/glapi/gl_x86-64_asm.py b/mesalib/src/mesa/glapi/gl_x86-64_asm.py new file mode 100644 index 000000000..f36ad3a5d --- /dev/null +++ b/mesalib/src/mesa/glapi/gl_x86-64_asm.py @@ -0,0 +1,334 @@ +#!/usr/bin/env python + +# (C) Copyright IBM Corporation 2005 +# 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 +# IBM AND/OR ITS 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 + +import license +import gl_XML, glX_XML +import sys, getopt, copy + +def should_use_push(registers): + for [reg, offset] in registers: + if reg[1:4] == "xmm": + return 0 + + N = len(registers) + return (N & 1) != 0 + + +def local_size(registers): + # The x86-64 ABI says "the value (%rsp - 8) is always a multiple of + # 16 when control is transfered to the function entry point." This + # means that the local stack usage must be (16*N)+8 for some value + # of N. (16*N)+8 = (8*(2N))+8 = 8*(2N+1). As long as N is odd, we + # meet this requirement. + + N = (len(registers) | 1) + return 8*N + + +def save_all_regs(registers): + adjust_stack = 0 + if not should_use_push(registers): + adjust_stack = local_size(registers) + print '\tsubq\t$%u, %%rsp' % (adjust_stack) + + for [reg, stack_offset] in registers: + save_reg( reg, stack_offset, adjust_stack ) + return + + +def restore_all_regs(registers): + adjust_stack = 0 + if not should_use_push(registers): + adjust_stack = local_size(registers) + + temp = copy.deepcopy(registers) + while len(temp): + [reg, stack_offset] = temp.pop() + restore_reg(reg, stack_offset, adjust_stack) + + if adjust_stack: + print '\taddq\t$%u, %%rsp' % (adjust_stack) + return + + +def save_reg(reg, offset, use_move): + if use_move: + if offset == 0: + print '\tmovq\t%s, (%%rsp)' % (reg) + else: + print '\tmovq\t%s, %u(%%rsp)' % (reg, offset) + else: + print '\tpushq\t%s' % (reg) + + return + + +def restore_reg(reg, offset, use_move): + if use_move: + if offset == 0: + print '\tmovq\t(%%rsp), %s' % (reg) + else: + print '\tmovq\t%u(%%rsp), %s' % (offset, reg) + else: + print '\tpopq\t%s' % (reg) + + return + + +class PrintGenericStubs(gl_XML.gl_print_base): + + def __init__(self): + gl_XML.gl_print_base.__init__(self) + + self.name = "gl_x86-64_asm.py (from Mesa)" + self.license = license.bsd_license_template % ("(C) Copyright IBM Corporation 2005", "IBM") + return + + + def get_stack_size(self, f): + size = 0 + for p in f.parameterIterator(): + size += p.get_stack_size() + + return size + + + def printRealHeader(self): + print "/* If we build with gcc's -fvisibility=hidden flag, we'll need to change" + print " * the symbol visibility mode to 'default'." + print ' */' + print '' + print '#include "../x86/assyntax.h"' + print '' + print '#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 303' + print '# pragma GCC visibility push(default)' + print '# define HIDDEN(x) .hidden x' + print '#else' + print '# define HIDDEN(x)' + print '#endif' + print '' + print '# if defined(USE_MGL_NAMESPACE)' + print '# define GL_PREFIX(n) GLNAME(CONCAT(mgl,n))' + print '# define _glapi_Dispatch _mglapi_Dispatch' + print '# else' + print '# define GL_PREFIX(n) GLNAME(CONCAT(gl,n))' + print '# endif' + print '' + print '#if defined(PTHREADS) || defined(SOLARIS_THREADS) || defined(WIN32_THREADS) || defined(BEOS_THREADS)' + print '# define THREADS' + print '#endif' + print '' + print '\t.text' + print '' + print '#ifdef GLX_USE_TLS' + print '' + print '\t.globl _x86_64_get_get_dispatch; HIDDEN(_x86_64_get_get_dispatch)' + print '_x86_64_get_get_dispatch:' + print '\tlea\t_x86_64_get_dispatch(%rip), %rax' + print '\tret' + print '' + print '\t.p2align\t4,,15' + print '_x86_64_get_dispatch:' + print '\tmovq\t_glapi_tls_Dispatch@GOTTPOFF(%rip), %rax' + print '\tmovq\t%fs:(%rax), %rax' + print '\tret' + print '\t.size\t_x86_64_get_dispatch, .-_x86_64_get_dispatch' + print '' + print '#elif defined(PTHREADS)' + print '' + print '\t.extern\t_glapi_Dispatch' + print '\t.extern\t_gl_DispatchTSD' + print '\t.extern\tpthread_getspecific' + print '' + print '\t.p2align\t4,,15' + print '_x86_64_get_dispatch:' + print '\tmovq\t_gl_DispatchTSD(%rip), %rdi' + print '\tjmp\tpthread_getspecific@PLT' + print '' + print '#elif defined(THREADS)' + print '' + print '\t.extern\t_glapi_get_dispatch' + print '' + print '#endif' + print '' + return + + + def printRealFooter(self): + print '' + print '#if defined(GLX_USE_TLS) && defined(__linux__)' + print ' .section ".note.ABI-tag", "a"' + print ' .p2align 2' + print ' .long 1f - 0f /* name length */' + print ' .long 3f - 2f /* data length */' + print ' .long 1 /* note length */' + print '0: .asciz "GNU" /* vendor name */' + print '1: .p2align 2' + print '2: .long 0 /* note data: the ABI tag */' + print ' .long 2,4,20 /* Minimum kernel version w/TLS */' + print '3: .p2align 2 /* pad out section */' + print '#endif /* GLX_USE_TLS */' + print '' + print '#if defined (__ELF__) && defined (__linux__)' + print ' .section .note.GNU-stack,"",%progbits' + print '#endif' + return + + + def printFunction(self, f): + + # The x86-64 ABI divides function parameters into a couple + # classes. For the OpenGL interface, the only ones that are + # relevent are INTEGER and SSE. Basically, the first 8 + # GLfloat or GLdouble parameters are placed in %xmm0 - %xmm7, + # the first 6 non-GLfloat / non-GLdouble parameters are placed + # in registers listed in int_parameters. + # + # If more parameters than that are required, they are passed + # on the stack. Therefore, we just have to make sure that + # %esp hasn't changed when we jump to the actual function. + # Since we're jumping to the function (and not calling it), we + # have to make sure of that anyway! + + int_parameters = ["%rdi", "%rsi", "%rdx", "%rcx", "%r8", "%r9"] + + int_class = 0 + sse_class = 0 + stack_offset = 0 + registers = [] + for p in f.parameterIterator(): + type_name = p.get_base_type_string() + + if p.is_pointer() or (type_name != "GLfloat" and type_name != "GLdouble"): + if int_class < 6: + registers.append( [int_parameters[int_class], stack_offset] ) + int_class += 1 + stack_offset += 8 + else: + if sse_class < 8: + registers.append( ["%%xmm%u" % (sse_class), stack_offset] ) + sse_class += 1 + stack_offset += 8 + + if ((int_class & 1) == 0) and (sse_class == 0): + registers.append( ["%rbp", 0] ) + + + name = f.dispatch_name() + + print '\t.p2align\t4,,15' + print '\t.globl\tGL_PREFIX(%s)' % (name) + print '\t.type\tGL_PREFIX(%s), @function' % (name) + if not f.is_static_entry_point(f.name): + print '\tHIDDEN(GL_PREFIX(%s))' % (name) + print 'GL_PREFIX(%s):' % (name) + print '#if defined(GLX_USE_TLS)' + print '\tcall\t_x86_64_get_dispatch@PLT' + print '\tmovq\t%u(%%rax), %%r11' % (f.offset * 8) + print '\tjmp\t*%r11' + print '#elif defined(PTHREADS)' + + save_all_regs(registers) + print '\tcall\t_x86_64_get_dispatch@PLT' + restore_all_regs(registers) + + if f.offset == 0: + print '\tmovq\t(%rax), %r11' + else: + print '\tmovq\t%u(%%rax), %%r11' % (f.offset * 8) + + print '\tjmp\t*%r11' + + print '#else' + print '\tmovq\t_glapi_Dispatch(%rip), %rax' + print '\ttestq\t%rax, %rax' + print '\tje\t1f' + print '\tmovq\t%u(%%rax), %%r11' % (f.offset * 8) + print '\tjmp\t*%r11' + print '1:' + + save_all_regs(registers) + print '\tcall\t_glapi_get_dispatch' + restore_all_regs(registers) + + print '\tmovq\t%u(%%rax), %%r11' % (f.offset * 8) + print '\tjmp\t*%r11' + print '#endif /* defined(GLX_USE_TLS) */' + + print '\t.size\tGL_PREFIX(%s), .-GL_PREFIX(%s)' % (name, name) + print '' + return + + + def printBody(self, api): + for f in api.functionIterateByOffset(): + self.printFunction(f) + + + for f in api.functionIterateByOffset(): + dispatch = f.dispatch_name() + for n in f.entry_points: + if n != f.name: + if f.is_static_entry_point(n): + text = '\t.globl GL_PREFIX(%s) ; .set GL_PREFIX(%s), GL_PREFIX(%s)' % (n, n, dispatch) + + if f.has_different_protocol(n): + print '#ifndef GLX_INDIRECT_RENDERING' + print text + print '#endif' + else: + print text + + return + +def show_usage(): + print "Usage: %s [-f input_file_name] [-m output_mode]" % sys.argv[0] + sys.exit(1) + +if __name__ == '__main__': + file_name = "gl_API.xml" + mode = "generic" + + try: + (args, trail) = getopt.getopt(sys.argv[1:], "m:f:") + except Exception,e: + show_usage() + + for (arg,val) in args: + if arg == '-m': + mode = val + elif arg == "-f": + file_name = val + + if mode == "generic": + printer = PrintGenericStubs() + else: + print "ERROR: Invalid mode \"%s\" specified." % mode + show_usage() + + api = gl_XML.parse_GL_API(file_name, glX_XML.glx_item_factory()) + printer.Print(api) diff --git a/mesalib/src/mesa/glapi/gl_x86_asm.py b/mesalib/src/mesa/glapi/gl_x86_asm.py new file mode 100644 index 000000000..36f0e31fe --- /dev/null +++ b/mesalib/src/mesa/glapi/gl_x86_asm.py @@ -0,0 +1,270 @@ +#!/usr/bin/env python + +# (C) Copyright IBM Corporation 2004, 2005 +# 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 +# IBM AND/OR ITS 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 + +import license +import gl_XML, glX_XML +import sys, getopt + +class PrintGenericStubs(gl_XML.gl_print_base): + + def __init__(self): + gl_XML.gl_print_base.__init__(self) + + self.name = "gl_x86_asm.py (from Mesa)" + self.license = license.bsd_license_template % ( \ +"""Copyright (C) 1999-2001 Brian Paul All Rights Reserved. +(C) Copyright IBM Corporation 2004, 2005""", "BRIAN PAUL, IBM") + return + + + def get_stack_size(self, f): + size = 0 + for p in f.parameterIterator(): + if p.is_padding: + continue + + size += p.get_stack_size() + + return size + + + def printRealHeader(self): + print '#include "assyntax.h"' + print '#include "glapi/glapioffsets.h"' + print '' + print '#if defined(STDCALL_API)' + print '# if defined(USE_MGL_NAMESPACE)' + print '# define GL_PREFIX(n,n2) GLNAME(CONCAT(mgl,n2))' + print '# else' + print '# define GL_PREFIX(n,n2) GLNAME(CONCAT(gl,n2))' + print '# endif' + print '#else' + print '# if defined(USE_MGL_NAMESPACE)' + print '# define GL_PREFIX(n,n2) GLNAME(CONCAT(mgl,n))' + print '# define _glapi_Dispatch _mglapi_Dispatch' + print '# else' + print '# define GL_PREFIX(n,n2) GLNAME(CONCAT(gl,n))' + print '# endif' + print '#endif' + print '' + print '#define GL_OFFSET(x) CODEPTR(REGOFF(4 * x, EAX))' + print '' + print '#if defined(GNU_ASSEMBLER) && !defined(__DJGPP__) && !defined(__MINGW32__)' + print '#define GLOBL_FN(x) GLOBL x ; .type x, function' + print '#else' + print '#define GLOBL_FN(x) GLOBL x' + print '#endif' + print '' + print '#if defined(PTHREADS) || defined(SOLARIS_THREADS) || defined(WIN32_THREADS) || defined(BEOS_THREADS)' + print '# define THREADS' + print '#endif' + print '' + print '#ifdef GLX_USE_TLS' + print '' + print '#ifdef GLX_X86_READONLY_TEXT' + print '# define CTX_INSNS MOV_L(GS:(EAX), EAX)' + print '#else' + print '# define CTX_INSNS NOP /* Pad for init_glapi_relocs() */' + print '#endif' + print '' + print '# define GL_STUB(fn,off,fn_alt)\t\t\t\\' + print 'ALIGNTEXT16;\t\t\t\t\t\t\\' + print 'GLOBL_FN(GL_PREFIX(fn, fn_alt));\t\t\t\\' + print 'GL_PREFIX(fn, fn_alt):\t\t\t\t\t\\' + print '\tCALL(_x86_get_dispatch) ;\t\t\t\\' + print '\tCTX_INSNS ; \\' + print '\tJMP(GL_OFFSET(off))' + print '' + print '#elif defined(PTHREADS)' + print '# define GL_STUB(fn,off,fn_alt)\t\t\t\\' + print 'ALIGNTEXT16;\t\t\t\t\t\t\\' + print 'GLOBL_FN(GL_PREFIX(fn, fn_alt));\t\t\t\\' + print 'GL_PREFIX(fn, fn_alt):\t\t\t\t\t\\' + print '\tMOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX) ;\t\\' + print '\tTEST_L(EAX, EAX) ;\t\t\t\t\\' + print '\tJE(1f) ;\t\t\t\t\t\\' + print '\tJMP(GL_OFFSET(off)) ;\t\t\t\t\\' + print '1:\tCALL(_x86_get_dispatch) ;\t\t\t\\' + print '\tJMP(GL_OFFSET(off))' + print '#elif defined(THREADS)' + print '# define GL_STUB(fn,off,fn_alt)\t\t\t\\' + print 'ALIGNTEXT16;\t\t\t\t\t\t\\' + print 'GLOBL_FN(GL_PREFIX(fn, fn_alt));\t\t\t\\' + print 'GL_PREFIX(fn, fn_alt):\t\t\t\t\t\\' + print '\tMOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX) ;\t\\' + print '\tTEST_L(EAX, EAX) ;\t\t\t\t\\' + print '\tJE(1f) ;\t\t\t\t\t\\' + print '\tJMP(GL_OFFSET(off)) ;\t\t\t\t\\' + print '1:\tCALL(_glapi_get_dispatch) ;\t\t\t\\' + print '\tJMP(GL_OFFSET(off))' + print '#else /* Non-threaded version. */' + print '# define GL_STUB(fn,off,fn_alt)\t\t\t\\' + print 'ALIGNTEXT16;\t\t\t\t\t\t\\' + print 'GLOBL_FN(GL_PREFIX(fn, fn_alt));\t\t\t\\' + print 'GL_PREFIX(fn, fn_alt):\t\t\t\t\t\\' + print '\tMOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX) ;\t\\' + print '\tJMP(GL_OFFSET(off))' + print '#endif' + print '' + print '#ifdef HAVE_ALIAS' + print '# define GL_STUB_ALIAS(fn,off,fn_alt,alias,alias_alt)\t\\' + print '\t.globl\tGL_PREFIX(fn, fn_alt) ;\t\t\t\\' + print '\t.set\tGL_PREFIX(fn, fn_alt), GL_PREFIX(alias, alias_alt)' + print '#else' + print '# define GL_STUB_ALIAS(fn,off,fn_alt,alias,alias_alt)\t\\' + print ' GL_STUB(fn, off, fn_alt)' + print '#endif' + print '' + print 'SEG_TEXT' + print '' + print '#ifdef GLX_USE_TLS' + print '' + print '\tGLOBL\tGLNAME(_x86_get_dispatch)' + print '\tHIDDEN(GLNAME(_x86_get_dispatch))' + print 'ALIGNTEXT16' + print 'GLNAME(_x86_get_dispatch):' + print '\tcall 1f' + print '1:\tpopl %eax' + print '\taddl $_GLOBAL_OFFSET_TABLE_+[.-1b], %eax' + print '\tmovl _glapi_tls_Dispatch@GOTNTPOFF(%eax), %eax' + print '\tret' + print '' + print '#elif defined(PTHREADS)' + print 'EXTERN GLNAME(_glapi_Dispatch)' + print 'EXTERN GLNAME(_gl_DispatchTSD)' + print 'EXTERN GLNAME(pthread_getspecific)' + print '' + print 'ALIGNTEXT16' + print 'GLNAME(_x86_get_dispatch):' + print '\tSUB_L(CONST(24), ESP)' + print '\tPUSH_L(GLNAME(_gl_DispatchTSD))' + print '\tCALL(GLNAME(pthread_getspecific))' + print '\tADD_L(CONST(28), ESP)' + print '\tRET' + print '#elif defined(THREADS)' + print 'EXTERN GLNAME(_glapi_get_dispatch)' + print '#endif' + print '' + + print '#if defined( GLX_USE_TLS ) && !defined( GLX_X86_READONLY_TEXT )' + print '\t\t.section\twtext, "awx", @progbits' + print '#endif /* defined( GLX_USE_TLS ) */' + + print '' + print '\t\tALIGNTEXT16' + print '\t\tGLOBL GLNAME(gl_dispatch_functions_start)' + print '\t\tHIDDEN(GLNAME(gl_dispatch_functions_start))' + print 'GLNAME(gl_dispatch_functions_start):' + print '' + return + + + def printRealFooter(self): + print '' + print '\t\tGLOBL\tGLNAME(gl_dispatch_functions_end)' + print '\t\tHIDDEN(GLNAME(gl_dispatch_functions_end))' + print '\t\tALIGNTEXT16' + print 'GLNAME(gl_dispatch_functions_end):' + print '' + print '#if defined(GLX_USE_TLS) && defined(__linux__)' + print ' .section ".note.ABI-tag", "a"' + print ' .p2align 2' + print ' .long 1f - 0f /* name length */' + print ' .long 3f - 2f /* data length */' + print ' .long 1 /* note length */' + print '0: .asciz "GNU" /* vendor name */' + print '1: .p2align 2' + print '2: .long 0 /* note data: the ABI tag */' + print ' .long 2,4,20 /* Minimum kernel version w/TLS */' + print '3: .p2align 2 /* pad out section */' + print '#endif /* GLX_USE_TLS */' + print '' + print '#if defined (__ELF__) && defined (__linux__)' + print ' .section .note.GNU-stack,"",%progbits' + print '#endif' + return + + + def printBody(self, api): + for f in api.functionIterateByOffset(): + name = f.dispatch_name() + stack = self.get_stack_size(f) + alt = "%s@%u" % (name, stack) + + print '\tGL_STUB(%s, _gloffset_%s, %s)' % (name, f.name, alt) + + if not f.is_static_entry_point(f.name): + print '\tHIDDEN(GL_PREFIX(%s, %s))' % (name, alt) + + + for f in api.functionIterateByOffset(): + name = f.dispatch_name() + stack = self.get_stack_size(f) + alt = "%s@%u" % (name, stack) + + if f.is_static_entry_point(f.name): + for n in f.entry_points: + if n != f.name: + alt2 = "%s@%u" % (n, stack) + text = '\tGL_STUB_ALIAS(%s, _gloffset_%s, %s, %s, %s)' % (n, f.name, alt2, f.name, alt) + + if f.has_different_protocol(n): + print '#ifndef GLX_INDIRECT_RENDERING' + print text + print '#endif' + else: + print text + + return + +def show_usage(): + print "Usage: %s [-f input_file_name] [-m output_mode]" % sys.argv[0] + sys.exit(1) + +if __name__ == '__main__': + file_name = "gl_API.xml" + mode = "generic" + + try: + (args, trail) = getopt.getopt(sys.argv[1:], "m:f:") + except Exception,e: + show_usage() + + for (arg,val) in args: + if arg == '-m': + mode = val + elif arg == "-f": + file_name = val + + if mode == "generic": + printer = PrintGenericStubs() + else: + print "ERROR: Invalid mode \"%s\" specified." % mode + show_usage() + + api = gl_XML.parse_GL_API(file_name, glX_XML.glx_item_factory()) + printer.Print(api) diff --git a/mesalib/src/mesa/glapi/license.py b/mesalib/src/mesa/glapi/license.py new file mode 100644 index 000000000..02181648e --- /dev/null +++ b/mesalib/src/mesa/glapi/license.py @@ -0,0 +1,47 @@ +# (C) Copyright IBM Corporation 2004 +# 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 +# IBM AND/OR ITS 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 + +bsd_license_template = """%s +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, 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 +%s, +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.""" diff --git a/mesalib/src/mesa/glapi/mesadef.py b/mesalib/src/mesa/glapi/mesadef.py new file mode 100644 index 000000000..0f410fc48 --- /dev/null +++ b/mesalib/src/mesa/glapi/mesadef.py @@ -0,0 +1,222 @@ +#!/usr/bin/env python + + +# Mesa 3-D graphics library +# Version: 4.1 +# +# 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. + + +# Generate the mesa.def file for Windows. +# +# Usage: +# mesadef.py >mesa.def +# Then copy to src/mesa/drivers/windows/gdi +# +# Dependencies: +# The apispec file must be in the current directory. + + + +import apiparser +import string + + +def PrintHead(): + print '; DO NOT EDIT - This file generated automatically by mesadef.py script' + print 'DESCRIPTION \'Mesa (OpenGL work-alike) for Win32\'' + print 'VERSION 6.0' + print ';' + print '; Module definition file for Mesa (OPENGL32.DLL)' + print ';' + print '; Note: The OpenGL functions use the STDCALL' + print '; function calling convention. Microsoft\'s' + print '; OPENGL32 uses this convention and so must the' + print '; Mesa OPENGL32 so that the Mesa DLL can be used' + print '; as a drop-in replacement.' + print ';' + print '; The linker exports STDCALL entry points with' + print '; \'decorated\' names; e.g., _glBegin@0, where the' + print '; trailing number is the number of bytes of ' + print '; parameter data pushed onto the stack. The' + print '; callee is responsible for popping this data' + print '; off the stack, usually via a RETF n instruction.' + print ';' + print '; However, the Microsoft OPENGL32.DLL does not export' + print '; the decorated names, even though the calling convention' + print '; is STDCALL. So, this module definition file is' + print '; needed to force the Mesa OPENGL32.DLL to export the' + print '; symbols in the same manner as the Microsoft DLL.' + print '; Were it not for this problem, this file would not' + print '; be needed (for the gl* functions) since the entry' + print '; points are compiled with dllexport declspec.' + print ';' + print '; However, this file is still needed to export "internal"' + print '; Mesa symbols for the benefit of the OSMESA32.DLL.' + print ';' + print 'EXPORTS' + return +#enddef + + +def PrintTail(): + print ';' + print '; WGL API' + print '\twglChoosePixelFormat' + print '\twglCopyContext' + print '\twglCreateContext' + print '\twglCreateLayerContext' + print '\twglDeleteContext' + print '\twglDescribeLayerPlane' + print '\twglDescribePixelFormat' + print '\twglGetCurrentContext' + print '\twglGetCurrentDC' + print '\twglGetExtensionsStringARB' + print '\twglGetLayerPaletteEntries' + print '\twglGetPixelFormat' + print '\twglGetProcAddress' + print '\twglMakeCurrent' + print '\twglRealizeLayerPalette' + print '\twglSetLayerPaletteEntries' + print '\twglSetPixelFormat' + print '\twglShareLists' + print '\twglSwapBuffers' + print '\twglSwapLayerBuffers' + print '\twglUseFontBitmapsA' + print '\twglUseFontBitmapsW' + print '\twglUseFontOutlinesA' + print '\twglUseFontOutlinesW' + print ';' + print '; Mesa internals - mostly for OSMESA' + print '\t_ac_CreateContext' + print '\t_ac_DestroyContext' + print '\t_ac_InvalidateState' + print '\t_glapi_get_context' + print '\t_glapi_get_proc_address' + print '\t_mesa_buffer_data' + print '\t_mesa_buffer_map' + print '\t_mesa_buffer_subdata' + print '\t_mesa_bzero' + print '\t_mesa_calloc' + print '\t_mesa_choose_tex_format' + print '\t_mesa_compressed_texture_size' + print '\t_mesa_create_framebuffer' + print '\t_mesa_create_visual' + print '\t_mesa_delete_buffer_object' + print '\t_mesa_delete_texture_object' + print '\t_mesa_destroy_framebuffer' + print '\t_mesa_destroy_visual' + print '\t_mesa_enable_1_3_extensions' + print '\t_mesa_enable_1_4_extensions' + print '\t_mesa_enable_1_5_extensions' + print '\t_mesa_enable_sw_extensions' + print '\t_mesa_error' + print '\t_mesa_free' + print '\t_mesa_free_context_data' + print '\t_mesa_get_current_context' + print '\t_mesa_init_default_imports' + print '\t_mesa_initialize_context' + print '\t_mesa_make_current' + print '\t_mesa_memcpy' + print '\t_mesa_memset' + print '\t_mesa_new_buffer_object' + print '\t_mesa_new_texture_object' + print '\t_mesa_problem' + print '\t_mesa_ResizeBuffersMESA' + print '\t_mesa_store_compressed_teximage1d' + print '\t_mesa_store_compressed_teximage2d' + print '\t_mesa_store_compressed_teximage3d' + print '\t_mesa_store_compressed_texsubimage1d' + print '\t_mesa_store_compressed_texsubimage2d' + print '\t_mesa_store_compressed_texsubimage3d' + print '\t_mesa_store_teximage1d' + print '\t_mesa_store_teximage2d' + print '\t_mesa_store_teximage3d' + print '\t_mesa_store_texsubimage1d' + print '\t_mesa_store_texsubimage2d' + print '\t_mesa_store_texsubimage3d' + print '\t_mesa_strcmp' + print '\t_mesa_test_proxy_teximage' + print '\t_mesa_Viewport' + print '\t_swrast_Accum' + print '\t_swrast_alloc_buffers' + print '\t_swrast_Bitmap' + print '\t_swrast_CopyPixels' + print '\t_swrast_DrawPixels' + print '\t_swrast_GetDeviceDriverReference' + print '\t_swrast_Clear' + print '\t_swrast_choose_line' + print '\t_swrast_choose_triangle' + print '\t_swrast_CopyColorSubTable' + print '\t_swrast_CopyColorTable' + print '\t_swrast_CopyConvolutionFilter1D' + print '\t_swrast_CopyConvolutionFilter2D' + print '\t_swrast_copy_teximage1d' + print '\t_swrast_copy_teximage2d' + print '\t_swrast_copy_texsubimage1d' + print '\t_swrast_copy_texsubimage2d' + print '\t_swrast_copy_texsubimage3d' + print '\t_swrast_CreateContext' + print '\t_swrast_DestroyContext' + print '\t_swrast_InvalidateState' + print '\t_swrast_ReadPixels' + print '\t_swrast_zbuffer_address' + print '\t_swsetup_Wakeup' + print '\t_swsetup_CreateContext' + print '\t_swsetup_DestroyContext' + print '\t_swsetup_InvalidateState' + print '\t_tnl_CreateContext' + print '\t_tnl_DestroyContext' + print '\t_tnl_InvalidateState' + print '\t_tnl_MakeCurrent' + print '\t_tnl_run_pipeline' +#enddef + + +records = [] + +def FindOffset(funcName): + for (name, alias, offset) in records: + if name == funcName: + return offset + #endif + #endfor + return -1 +#enddef + + +def EmitEntry(name, returnType, argTypeList, argNameList, alias, offset): + if alias == '': + dispatchName = name + else: + dispatchName = alias + if offset < 0: + offset = FindOffset(dispatchName) + if offset >= 0 and string.find(name, "unused") == -1: + print '\tgl%s' % (name) + # save this info in case we need to look up an alias later + records.append((name, dispatchName, offset)) + +#enddef + + +PrintHead() +apiparser.ProcessSpecFile("APIspec", EmitEntry) +PrintTail() diff --git a/mesalib/src/mesa/glapi/next_available_offset.sh b/mesalib/src/mesa/glapi/next_available_offset.sh new file mode 100644 index 000000000..e7d6c2f4a --- /dev/null +++ b/mesalib/src/mesa/glapi/next_available_offset.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +# +# (C) Copyright IBM Corporation 2004 +# 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 +# IBM AND/OR ITS 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 + +# Trivial shell script to search the API definition file and print out the +# next numerically available API entry-point offset. This could probably +# be made smarter, but it would be better to use the existin Python +# framework to do that. This is just a quick-and-dirty hack. + +num=$(grep 'offset="' gl_API.xml |\ + sed 's/.\+ offset="//g;s/".*$//g' |\ + grep -v '?' |\ + sort -rn |\ + head -1) + +echo $((num + 1)) diff --git a/mesalib/src/mesa/glapi/typeexpr.py b/mesalib/src/mesa/glapi/typeexpr.py new file mode 100644 index 000000000..8ba7de486 --- /dev/null +++ b/mesalib/src/mesa/glapi/typeexpr.py @@ -0,0 +1,292 @@ +#!/usr/bin/env python + +# (C) Copyright IBM Corporation 2005 +# 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 +# IBM AND/OR ITS 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 + +import string, copy + +class type_node: + def __init__(self): + self.pointer = 0 # bool + self.const = 0 # bool + self.signed = 1 # bool + self.integer = 1 # bool + + # If elements is set to non-zero, then field is an array. + self.elements = 0 + + self.name = None + self.size = 0 # type's size in bytes + return + + + def string(self): + """Return string representation of this type_node.""" + s = "" + + if self.pointer: + s = "* " + + if self.const: + s += "const " + + if not self.pointer: + if self.integer: + if self.signed: + s += "signed " + else: + s += "unsigned " + + if self.name: + s += "%s " % (self.name) + + return s + + +class type_table: + def __init__(self): + self.types_by_name = {} + return + + + def add_type(self, type_expr): + self.types_by_name[ type_expr.get_base_name() ] = type_expr + return + + + def find_type(self, name): + if name in self.types_by_name: + return self.types_by_name[ name ] + else: + return None + + +def create_initial_types(): + tt = type_table() + + basic_types = [ + ("char", 1, 1), + ("short", 2, 1), + ("int", 4, 1), + ("long", 4, 1), + ("float", 4, 0), + ("double", 8, 0), + ("enum", 4, 1) + ] + + for (type_name, type_size, integer) in basic_types: + te = type_expression(None) + tn = type_node() + tn.name = type_name + tn.size = type_size + tn.integer = integer + te.expr.append(tn) + tt.add_type( te ) + + type_expression.built_in_types = tt + return + + +class type_expression: + built_in_types = None + + def __init__(self, type_string, extra_types = None): + self.expr = [] + + if not type_string: + return + + self.original_string = type_string + + if not type_expression.built_in_types: + raise RuntimeError("create_initial_types must be called before creating type_expression objects.") + + # Replace '*' with ' * ' in type_string. Then, split the string + # into tokens, separated by spaces. + tokens = string.split( string.replace( type_string, "*", " * " ) ) + + const = 0 + t = None + signed = 0 + unsigned = 0 + + for i in tokens: + if i == "const": + if t and t.pointer: + t.const = 1 + else: + const = 1 + elif i == "signed": + signed = 1 + elif i == "unsigned": + unsigned = 1 + elif i == "*": + # This is a quirky special-case because of the + # way the C works for types. If 'unsigned' is + # specified all by itself, it is treated the + # same as "unsigned int". + + if unsigned: + self.set_base_type( "int", signed, unsigned, const, extra_types ) + const = 0 + signed = 0 + unsigned = 0 + + if not self.expr: + raise RuntimeError("Invalid type expression (dangling pointer)") + + if signed: + raise RuntimeError("Invalid type expression (signed / unsigned applied to pointer)") + + t = type_node() + t.pointer = 1 + self.expr.append( t ) + else: + if self.expr: + raise RuntimeError('Invalid type expression (garbage after pointer qualifier -> "%s")' % (self.original_string)) + + self.set_base_type( i, signed, unsigned, const, extra_types ) + const = 0 + signed = 0 + unsigned = 0 + + if signed and unsigned: + raise RuntimeError("Invalid type expression (both signed and unsigned specified)") + + + if const: + raise RuntimeError("Invalid type expression (dangling const)") + + if unsigned: + raise RuntimeError("Invalid type expression (dangling signed)") + + if signed: + raise RuntimeError("Invalid type expression (dangling unsigned)") + + return + + + def set_base_type(self, type_name, signed, unsigned, const, extra_types): + te = type_expression.built_in_types.find_type( type_name ) + if not te: + te = extra_types.find_type( type_name ) + + if not te: + raise RuntimeError('Unknown base type "%s".' % (type_name)) + + self.expr = copy.deepcopy(te.expr) + + t = self.expr[ len(self.expr) - 1 ] + t.const = const + if signed: + t.signed = 1 + elif unsigned: + t.signed = 0 + + + def set_base_type_node(self, tn): + self.expr = [tn] + return + + + def set_elements(self, count): + tn = self.expr[0] + + tn.elements = count + return + + + def string(self): + s = "" + for t in self.expr: + s += t.string() + + return s + + + def get_base_type_node(self): + return self.expr[0] + + + def get_base_name(self): + if len(self.expr): + return self.expr[0].name + else: + return None + + + def get_element_size(self): + tn = self.expr[0] + + if tn.elements: + return tn.elements * tn.size + else: + return tn.size + + + def get_element_count(self): + tn = self.expr[0] + return tn.elements + + + def get_stack_size(self): + tn = self.expr[ len(self.expr) - 1 ] + + if tn.elements or tn.pointer: + return 4 + elif not tn.integer: + return tn.size + else: + return 4 + + + def is_pointer(self): + tn = self.expr[ len(self.expr) - 1 ] + return tn.pointer + + + def format_string(self): + tn = self.expr[ len(self.expr) - 1 ] + if tn.pointer: + return "%p" + elif not tn.integer: + return "%f" + else: + return "%d" + + + +if __name__ == '__main__': + + types_to_try = [ "int", "int *", "const int *", "int * const", "const int * const", \ + "unsigned * const *", \ + "float", "const double", "double * const"] + + create_initial_types() + + for t in types_to_try: + print 'Trying "%s"...' % (t) + te = type_expression( t ) + print 'Got "%s" (%u, %u).' % (te.string(), te.get_stack_size(), te.get_element_size()) diff --git a/mesalib/src/mesa/main/Makefile.ugl b/mesalib/src/mesa/main/Makefile.ugl new file mode 100644 index 000000000..b440e1364 --- /dev/null +++ b/mesalib/src/mesa/main/Makefile.ugl @@ -0,0 +1,364 @@ +# Mesa 3-D graphics library +# Version: 4.1 +# +# Copyright (C) 2001 Wind River Systems, Inc + +# The MIT License +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. + +# Makefile for core library + +# This makefile can moved all objects files in MESA_OBJ for use with +# ld in windShell or create a library from objects files in their +# associated .c folder. +# +# For an easy inclusion of lib$(CPU)$(TOOL)GL.a in vxworks image, this +# makefile collects together all .o in an only file +# (obj$(CPU)$(TOOL)GL.o). This operation is unnecessary for +# lib$(CPU)$(TOOL)OSMesa.a and lib$(CPU)$(TOOL)UglMesa.a because they +# already contain only one file. +# +##### MACROS ##### +MESA_MAJOR=4 +MESA_MINOR=1 +MESA_TINY=0 +VERSION=$(MESA_MAJOR).$(MESA_MINOR) + +GL_MAJOR = 1 +GL_MINOR = 2 +GL_TINY = 0$(MESA_MAJOR)0$(MESA_MINOR)0$(MESA_TINY) + +##### RULES ##### + +include ..\rules.windml + +#### GL ##### + +GL_SOURCES = \ + api_arrayelt.c \ + api_loopback.c \ + api_noop.c \ + api_validate.c \ + accum.c \ + arbprogram.c \ + attrib.c \ + blend.c \ + bufferobj.c \ + buffers.c \ + clip.c \ + colortab.c \ + context.c \ + convolve.c \ + debug.c \ + depth.c \ + dispatch.c \ + dlist.c \ + drawpix.c \ + enable.c \ + enums.c \ + eval.c \ + extensions.c \ + feedback.c \ + fog.c \ + get.c \ + glapi.c \ + glthread.c \ + hash.c \ + hint.c \ + histogram.c \ + image.c \ + imports.c \ + light.c \ + lines.c \ + matrix.c \ + pixel.c \ + points.c \ + polygon.c \ + rastpos.c \ + state.c \ + stencil.c \ + texcompress.c \ + texformat.c \ + teximage.c \ + texobj.c \ + texstate.c \ + texstore.c \ + texutil.c \ + varray.c \ + vtxfmt.c \ + X86/x86.c \ + X86/common_x86.c \ + X86/3dnow.c \ + X86/sse.c \ + math/m_debug_clip.c \ + math/m_debug_norm.c \ + math/m_debug_vertex.c \ + math/m_debug_xform.c \ + math/m_eval.c \ + math/m_matrix.c \ + math/m_translate.c \ + math/m_vector.c \ + math/m_vertices.c \ + math/m_xform.c \ + array_cache/ac_context.c \ + array_cache/ac_import.c \ + swrast/s_aaline.c \ + swrast/s_aatriangle.c \ + swrast/s_accum.c \ + swrast/s_alpha.c \ + swrast/s_alphabuf.c \ + swrast/s_bitmap.c \ + swrast/s_blend.c \ + swrast/s_buffers.c \ + swrast/s_copypix.c \ + swrast/s_context.c \ + swrast/s_depth.c \ + swrast/s_drawpix.c \ + swrast/s_feedback.c \ + swrast/s_fog.c \ + swrast/s_imaging.c \ + swrast/s_lines.c \ + swrast/s_logic.c \ + swrast/s_masking.c \ + swrast/s_pixeltex.c \ + swrast/s_points.c \ + swrast/s_readpix.c \ + swrast/s_span.c \ + swrast/s_stencil.c \ + swrast/s_texture.c \ + swrast/s_texstore.c \ + swrast/s_triangle.c \ + swrast/s_zoom.c \ + swrast_setup/ss_context.c \ + swrast_setup/ss_triangle.c \ + swrast_setup/ss_vb.c \ + tnl/t_array_api.c \ + tnl/t_array_import.c \ + tnl/t_context.c \ + tnl/t_eval_api.c \ + tnl/t_imm_alloc.c \ + tnl/t_imm_api.c \ + tnl/t_imm_debug.c \ + tnl/t_imm_dlist.c \ + tnl/t_imm_elt.c \ + tnl/t_imm_eval.c \ + tnl/t_imm_exec.c \ + tnl/t_imm_fixup.c \ + tnl/t_pipeline.c \ + tnl/t_vb_fog.c \ + tnl/t_vb_light.c \ + tnl/t_vb_normals.c \ + tnl/t_vb_points.c \ + tnl/t_vb_render.c \ + tnl/t_vb_texgen.c \ + tnl/t_vb_texmat.c \ + tnl/t_vb_vertex.c + +GL_OBJECTS = $(GL_SOURCES:.c=.o) +GL_OBJNAME = $(MESA_LIBDIR)/objMesaGL.o + +#### X86 ##### + +x86_files = \ + X86/common_x86_asm.S \ + X86/glapi_x86.S \ + X86/x86_cliptest.S \ + X86/x86_vertex.S \ + X86/x86_xform2.S \ + X86/x86_xform3.S \ + X86/x86_xform4.S \ + +x3dnow_files = \ + X86/3dnow_normal.S \ + X86/3dnow_vertex.S \ + X86/3dnow_xform1.S \ + X86/3dnow_xform2.S \ + X86/3dnow_xform3.S \ + X86/3dnow_xform4.S + +sse_files = \ + X86/sse_normal.S \ + X86/sse_vertex.S \ + X86/sse_xform1.S \ + X86/sse_xform2.S \ + X86/sse_xform3.S \ + X86/sse_xform4.S + +mmx_files = X86/mmx_blend.S + +X86_OBJNAME = $(MESA_LIBDIR)/objMesaX86.o + +##### UGL ##### + +UGL_SOURCES = \ + windml/ugl_api.c \ + windml/ugl_dd.c \ + windml/ugl_span.c \ + windml/ugl_line.c \ + windml/ugl_tri.c \ + windml/tornado/torMesaUGLInit.c + +UGL_OBJECTS = $(UGL_SOURCES:.c=.o) +UGL_OBJNAME = $(MESA_LIBDIR)/objMesaUGL.o + +##### OS ##### + +OS_SOURCES = OSmesa/osmesa.c windml/tornado/torMesaOSInit.c +OS_OBJECTS = $(OS_SOURCES:.c=.o) +OS_OBJNAME = $(MESA_LIBDIR)/objMesaOS.o + +##### GLUTSHAPES ##### + +GLUTSHAPES_SOURCES = \ + windml/ugl_glutshapes.c \ + windml/tornado/torGLUTShapesInit.c + +GLUTSHAPES_OBJECTS = $(GLUTSHAPES_SOURCES:.c=.o) +GLUTSHAPES_OBJNAME = $(MESA_LIBDIR)/objGLUTShapes.o + +SOURCES = $(GL_SOURCES) $(UGL_SOURCES) $(OS_SOURCES) \ + $(GLUTSHAPES_SOURCES) + +##### TARGETS ##### + +all: depend.$(CPU)$(TOOL) cfgX86 $(X86_OBJNAME) $(GL_OBJNAME)\ +$(UGL_OBJNAME) $(OS_OBJNAME) $(GLUTSHAPES_OBJNAME) + +#histogram.o: +# $(CC) $(CFLAGS) -O1 $(OPTION_OBJECT_ONLY) $(OPTION_OBJECT_NAME)$@ $< + +#image.o: +# $(CC) $(CFLAGS) -O1 $(OPTION_OBJECT_ONLY) $(OPTION_OBJECT_NAME)$@ $< + +cfgX86: +ifdef HAVE_3DNOW +x3dnow_sources = $(x3dnow_files) +CFLAGS_3DNOW = -DUSE_3DNOW_ASM +HAVE_X86 = 1 +endif +ifdef HAVE_SSE +sse_sources = $(sse_files) +CFLAGS_SSE = -DUSE_SSE_ASM +HAVE_X86 = 1 +endif +ifdef HAVE_MMX +mmx_sources = $(mmx_files) +CFLAGS_MMX = -DUSE_MMX_ASM +HAVE_X86 = 1 +endif +ifdef HAVE_X86 +x86_sources = $(x86_files) +CFLAGS_X86 = -DUSE_X86_ASM +endif +X86_SOURCES = $(x86_sources) $(mmx_sources) \ + $(x3dnow_sources) $(sse_sources) +X86_OBJECTS = $(X86_SOURCES:.S=.o) +CFLAGS_USE_X86 = $(CFLAGS_3DNOW) $(CFLAGS_SSE) $(CFLAGS_MMX) $(CFLAGS_X86) + +#X86/matypes.h: mtypes.h tnl/t_context.h X86/gen_matypes.c +# $(CC) -I ./ X86/gen_matypes.c -o X86/gen_matypes +# ./X86/gen_matypes > X86/matypes.h +# $(RM) X86/gen_matypes +# $(RM) X86/gen_matypes.o + +# Make the Mesax86 library +$(X86_OBJNAME): $(X86_OBJECTS) +ifdef HAVE_X86 +# $(LD) -r $(X86_OBJECTS) -o $(MESA_OBJNAME) + $(LD) -r $(X86_OBJECTS) -o $(X86_OBJNAME) +# $(AR) rus $(MESA_LIBNAME) $(X86_OBJNAME) +# $(RM) $(X86_OBJNAME) +endif + +# Make the GL library +$(GL_OBJNAME): $(GL_OBJECTS) +# $(LD) -r $(GL_OBJECTS) -o $(MESA_OBJNAME) + $(LD) -r $(GL_OBJECTS) -o $(GL_OBJNAME) +# $(AR) rus $(MESA_LIBNAME) $(GL_OBJNAME) +# $(AR) rus $(VX_LIBNAME) $(GL_OBJNAME) +# $(RM) $(GL_OBJNAME) + +# Make the UGLMesa library +$(UGL_OBJNAME): $(UGL_OBJECTS) +# $(LD) -r $(UGL_OBJECTS) -o $(MESA_OBJNAME) + $(LD) -r $(UGL_OBJECTS) -o $(UGL_OBJNAME) +# $(AR) rus $(MESA_LIBNAME) $(UGL_OBJNAME) +# $(AR) rus $(VX_LIBNAME) $(UGL_OBJNAME) +# $(RM) $(UGL_OBJNAME) + +# Make the OSMesa library +$(OS_OBJNAME): $(OS_OBJECTS) +# $(LD) -r $(OS_OBJECTS) -o $(MESA_OBJNAME) + $(LD) -r $(OS_OBJECTS) -o $(OS_OBJNAME) +# $(AR) rus $(MESA_LIBNAME) $(OS_OBJNAME) +# $(AR) rus $(VX_LIBNAME) $(OS_OBJNAME) +# $(RM) $(OS_OBJNAME) + +# Make the GLUT Shapes library +$(GLUTSHAPES_OBJNAME): $(GLUTSHAPES_OBJECTS) +# $(LD) -r $(GLUTSHAPES_OBJECTS) -o $(MESA_OBJNAME) + $(LD) -r $(GLUTSHAPES_OBJECTS) -o $(GLUTSHAPES_OBJNAME) +# $(AR) rus $(MESA_LIBNAME) $(GLUTSHAPES_OBJNAME) +# $(AR) rus $(VX_LIBNAME) $(GLUTSHAPES_OBJNAME) +# $(RM) $(GLUTSHAPES_OBJNAME) + +depend.$(CPU)$(TOOL): +ifeq ($(WIND_HOST_TYPE),x86-win32) + @ $(RM) $@ + @ $(ECHO) Creating depend.$(CPU)$(TOOL) +ifneq ($(SOURCES),) + @ for %f in ($(SOURCES)) do \ + $(CC) -MM $(CFLAGS) %f >>$@ +endif +else +Makefile + @ $(RM) $@ + @ $(ECHO) "Creating depend.$(CPU)$(TOOL)" +ifneq ($(SOURCES),) + @ for FILE in $(filter-out $(NODEPENDOBJS), $(SOURCES)); \ + do \ + $(CC) -MM $(CFLAGS) $$FILE \ + | $(TCL) $(BIN_DIR)/depend.tcl $(TGT_DIR) >>$@; \ + done +endif +endif + +.PHONY = clean + +clean: +# $(AR) d $(MESA_LIBNAME) $(GL_OBJNAME) +# $(AR) d $(MESA_LIBNAME) $(UGL_OBJNAME) +# $(AR) d $(MESA_LIBNAME) $(OS_OBJNAME) +# $(AR) d $(MESA_LIBNAME) $(GLUTSHAPES_OBJNAME) +# $(AR) d $(VX_LIBNAME) $(GL_OBJNAME) +# $(AR) d $(VX_LIBNAME) $(UGL_OBJNAME) +# $(AR) d $(VX_LIBNAME) $(OS_OBJNAME) +# $(AR) d $(VX_LIBNAME) $(GLUTSHAPES_OBJNAME) + $(RM) $(GL_OBJECTS) + $(RM) $(UGL_OBJECTS) + $(RM) $(OS_OBJECTS) + $(RM) $(GLUTSHAPES_OBJECTS) + $(RM) $(GL_OBJNAME) + $(RM) $(UGL_OBJNAME) + $(RM) $(OS_OBJNAME) + $(RM) $(GLUTSHAPES_OBJNAME) + $(RM) depend.$(CPU)$(TOOL) + +include depend.$(CPU)$(TOOL) + diff --git a/mesalib/src/mesa/main/Makefile.win b/mesalib/src/mesa/main/Makefile.win new file mode 100644 index 000000000..a27f44c11 --- /dev/null +++ b/mesalib/src/mesa/main/Makefile.win @@ -0,0 +1,208 @@ +# Makefile for Win32 +# +# NOTE: the install target may overwrite important files in the system dirs +# Check first, before making the install target. +# +# This builds both the osmesa and Windows drivers. +# + +!include + +TOP = .. +SUBDIRS = osmesa.dir + +CORE_SRCS = \ + api_loopback.c \ + api_noop.c \ + api_validate.c \ + accum.c \ + arbprogram.c \ + attrib.c \ + blend.c \ + bufferobj.c \ + buffers.c \ + clip.c \ + colortab.c \ + context.c \ + convolve.c \ + debug.c \ + depth.c \ + dispatch.c \ + dlist.c \ + drawpix.c \ + enable.c \ + enums.c \ + eval.c \ + extensions.c \ + feedback.c \ + fog.c \ + get.c \ + glapi.c \ + glthread.c \ + hash.c \ + hint.c \ + histogram.c \ + image.c \ + imports.c \ + light.c \ + lines.c \ + matrix.c \ + nvprogram.c \ + nvfragparse.c \ + nvvertexec.c \ + nvvertparse.c \ + pixel.c \ + points.c \ + polygon.c \ + rastpos.c \ + state.c \ + stencil.c \ + texcompress.c \ + texcompress_fxt1.c \ + texcompress_s3tc.c \ + teximage.c \ + texformat.c \ + texobj.c \ + texstate.c \ + texstore.c \ + varray.c \ + vtxfmt.c \ +# X86\x86.c \ +# X86\common_x86.c \ +# X86\3dnow.c \ +# X86\sse.c \ + math\m_debug_norm.c \ + math\m_debug_xform.c \ + math\m_eval.c \ + math\m_matrix.c \ + math\m_translate.c \ + math\m_vector.c \ + math\m_xform.c \ + array_cache\ac_context.c \ + array_cache\ac_import.c \ + swrast\s_aaline.c \ + swrast\s_aatriangle.c \ + swrast\s_accum.c \ + swrast\s_alpha.c \ + swrast\s_alphabuf.c \ + swrast\s_bitmap.c \ + swrast\s_blend.c \ + swrast\s_buffers.c \ + swrast\s_copypix.c \ + swrast\s_context.c \ + swrast\s_depth.c \ + swrast\s_drawpix.c \ + swrast\s_feedback.c \ + swrast\s_fog.c \ + swrast\s_imaging.c \ + swrast\s_lines.c \ + swrast\s_logic.c \ + swrast\s_masking.c \ + swrast\s_nvfragprog.c \ + swrast\s_pixeltex.c \ + swrast\s_points.c \ + swrast\s_readpix.c \ + swrast\s_span.c \ + swrast\s_stencil.c \ + swrast\s_texstore.c \ + swrast\s_texture.c \ + swrast\s_triangle.c \ + swrast\s_zoom.c \ + swrast_setup\ss_context.c \ + swrast_setup\ss_triangle.c \ + swrast_setup\ss_vb.c \ + tnl\t_array_api.c \ + tnl\t_array_import.c \ + tnl\t_context.c \ + tnl\t_eval_api.c \ + tnl\t_imm_alloc.c \ + tnl\t_imm_api.c \ + tnl\t_imm_debug.c \ + tnl\t_imm_dlist.c \ + tnl\t_imm_elt.c \ + tnl\t_imm_eval.c \ + tnl\t_imm_exec.c \ + tnl\t_imm_fixup.c \ + tnl\t_pipeline.c \ + tnl\t_vb_fog.c \ + tnl\t_vb_light.c \ + tnl\t_vb_normals.c \ + tnl\t_vb_points.c \ + tnl\t_vb_program.c \ + tnl\t_vb_render.c \ + tnl\t_vb_texgen.c \ + tnl\t_vb_texmat.c \ + tnl\t_vb_vertex.c + +DRIVER_SRCS = \ + Trace\tr_context.c \ + Trace\tr_control.c \ + Trace\tr_error.c \ + Trace\tr_support.c \ + Trace\tr_wrapper.c \ + Trace\tr_write.c \ + Windows\wgl.c \ + Windows\wmesa.c + +ASM_SRCS = + +SRCS = $(CORE_SRCS) $(DRIVER_SRCS) + +all : mesadll $(SUBDIRS) + +!include "$(TOP)/mesawin32.mak" + +mesadll : $(MESADLL) + +CFLAGS = $(cvarsdll) $(CFLAGS) -D_OPENGL32_ -DBUILD_GL32 -DNO_PARALLEL -DNO_STEREO +!IFNDEF NODEBUG +CFLAGS = $(CFLAGS) -DMESA_DEBUG +!ENDIF +LFLAGS = $(dlllflags) $(lcommon) $(LFLAGS) + +OBJS = $(ASM_SRCS:.S=.obj) $(CORE_SRCS:.c=.obj) $(DRIVER_SRCS:.c=.obj) +LIBS = winmm.lib $(guilibsdll) + +$(MESADLL) : $(OBJS) mesa.def + $(link) $(LFLAGS) -out:$(MESADLL) -def:mesa.def $(OBJS) $(LIBS) + @echo "copying Mesa dynamic link library to lib directory..." + -copy $(MESADLL) ..\lib + @echo "copying Mesa import library to lib directory..." + -copy $(MESALIB) ..\lib + +$(SUBDIRS) : + @echo. + @echo Making in $* directory + @cd $* + @nmake -f Makefile.win -nologo + @cd .. + +install : $(MESADLL) + @echo. + @echo "copying Mesa dynamic link library to system directory..." + -copy $(MESADLL) $(DLLINSTALL) + @echo "copying Mesa header files to include directory..." + -copy ..\..\include\GL\gl.h $(INCLUDEINSTALL) + -copy ..\..\include\GL\glext.h $(INCLUDEINSTALL) + @echo "copying Mesa import library to library directory..." + -copy $(MESALIB) $(LIBINSTALL) + +clean :: + @del /f tnl\*.obj + @del /f swrast_setup\*.obj + @del /f math\*.obj + @del /f array_cache\*.obj + @del /f swrast\*.obj + @del /f Trace\*.obj + @del /f osmesa\*.obj + @del /f Windows\*.obj + +clobber :: + @del /f OSmesa\*.lib + @del /f OSmesa\*.exp + @del /f OSmesa\*.dll + +# override default inference rule with one that writes the object to +# the same subdir that the c file is in. +.c.obj : + $(cc) $(CFLAGS) -I. $< /Fo$*.obj diff --git a/mesalib/src/mesa/main/get_gen.py b/mesalib/src/mesa/main/get_gen.py new file mode 100644 index 000000000..c7babd1c8 --- /dev/null +++ b/mesalib/src/mesa/main/get_gen.py @@ -0,0 +1,1252 @@ +#!/usr/bin/env python + +# Mesa 3-D graphics library +# +# Copyright (C) 1999-2006 Brian Paul All Rights Reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# 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. + + +# This script is used to generate the get.c file: +# python get_gen.py > get.c + + +import string + + +GLint = 1 +GLenum = 2 +GLfloat = 3 +GLdouble = 4 +GLboolean = 5 +GLfloatN = 6 # A normalized value, such as a color or depth range +GLint64 = 7 + + +TypeStrings = { + GLint : "GLint", + GLenum : "GLenum", + GLfloat : "GLfloat", + GLdouble : "GLdouble", + GLboolean : "GLboolean", + GLint64 : "GLint64" +} + + +# Each entry is a tuple of: +# - the GL state name, such as GL_CURRENT_COLOR +# - the state datatype, one of GLint, GLfloat, GLboolean or GLenum +# - list of code fragments to get the state, such as ["ctx->Foo.Bar"] +# - optional extra code or empty string. If present, "CONVERSION" will be +# replaced by ENUM_TO_FLOAT, INT_TO_FLOAT, etc. +# - optional extensions to check, or None +# +StateVars = [ + ( "GL_ACCUM_RED_BITS", GLint, ["ctx->DrawBuffer->Visual.accumRedBits"], + "", None ), + ( "GL_ACCUM_GREEN_BITS", GLint, ["ctx->DrawBuffer->Visual.accumGreenBits"], + "", None ), + ( "GL_ACCUM_BLUE_BITS", GLint, ["ctx->DrawBuffer->Visual.accumBlueBits"], + "", None ), + ( "GL_ACCUM_ALPHA_BITS", GLint, ["ctx->DrawBuffer->Visual.accumAlphaBits"], + "", None ), + ( "GL_ACCUM_CLEAR_VALUE", GLfloatN, + [ "ctx->Accum.ClearColor[0]", + "ctx->Accum.ClearColor[1]", + "ctx->Accum.ClearColor[2]", + "ctx->Accum.ClearColor[3]" ], + "", None ), + ( "GL_ALPHA_BIAS", GLfloat, ["ctx->Pixel.AlphaBias"], "", None ), + ( "GL_ALPHA_BITS", GLint, ["ctx->DrawBuffer->Visual.alphaBits"], + "", None ), + ( "GL_ALPHA_SCALE", GLfloat, ["ctx->Pixel.AlphaScale"], "", None ), + ( "GL_ALPHA_TEST", GLboolean, ["ctx->Color.AlphaEnabled"], "", None ), + ( "GL_ALPHA_TEST_FUNC", GLenum, ["ctx->Color.AlphaFunc"], "", None ), + ( "GL_ALPHA_TEST_REF", GLfloatN, ["ctx->Color.AlphaRef"], "", None ), + ( "GL_ATTRIB_STACK_DEPTH", GLint, ["ctx->AttribStackDepth"], "", None ), + ( "GL_AUTO_NORMAL", GLboolean, ["ctx->Eval.AutoNormal"], "", None ), + ( "GL_AUX_BUFFERS", GLint, ["ctx->DrawBuffer->Visual.numAuxBuffers"], + "", None ), + ( "GL_BLEND", GLboolean, ["ctx->Color.BlendEnabled"], "", None ), + ( "GL_BLEND_DST", GLenum, ["ctx->Color.BlendDstRGB"], "", None ), + ( "GL_BLEND_SRC", GLenum, ["ctx->Color.BlendSrcRGB"], "", None ), + ( "GL_BLEND_SRC_RGB_EXT", GLenum, ["ctx->Color.BlendSrcRGB"], "", None ), + ( "GL_BLEND_DST_RGB_EXT", GLenum, ["ctx->Color.BlendDstRGB"], "", None ), + ( "GL_BLEND_SRC_ALPHA_EXT", GLenum, ["ctx->Color.BlendSrcA"], "", None ), + ( "GL_BLEND_DST_ALPHA_EXT", GLenum, ["ctx->Color.BlendDstA"], "", None ), + ( "GL_BLEND_EQUATION", GLenum, ["ctx->Color.BlendEquationRGB "], "", None), + ( "GL_BLEND_EQUATION_ALPHA_EXT", GLenum, ["ctx->Color.BlendEquationA "], + "", None ), + ( "GL_BLEND_COLOR_EXT", GLfloatN, + [ "ctx->Color.BlendColor[0]", + "ctx->Color.BlendColor[1]", + "ctx->Color.BlendColor[2]", + "ctx->Color.BlendColor[3]"], "", None ), + ( "GL_BLUE_BIAS", GLfloat, ["ctx->Pixel.BlueBias"], "", None ), + ( "GL_BLUE_BITS", GLint, ["ctx->DrawBuffer->Visual.blueBits"], "", None ), + ( "GL_BLUE_SCALE", GLfloat, ["ctx->Pixel.BlueScale"], "", None ), + ( "GL_CLIENT_ATTRIB_STACK_DEPTH", GLint, + ["ctx->ClientAttribStackDepth"], "", None ), + ( "GL_CLIP_PLANE0", GLboolean, + [ "(ctx->Transform.ClipPlanesEnabled >> 0) & 1" ], "", None ), + ( "GL_CLIP_PLANE1", GLboolean, + [ "(ctx->Transform.ClipPlanesEnabled >> 1) & 1" ], "", None ), + ( "GL_CLIP_PLANE2", GLboolean, + [ "(ctx->Transform.ClipPlanesEnabled >> 2) & 1" ], "", None ), + ( "GL_CLIP_PLANE3", GLboolean, + [ "(ctx->Transform.ClipPlanesEnabled >> 3) & 1" ], "", None ), + ( "GL_CLIP_PLANE4", GLboolean, + [ "(ctx->Transform.ClipPlanesEnabled >> 4) & 1" ], "", None ), + ( "GL_CLIP_PLANE5", GLboolean, + [ "(ctx->Transform.ClipPlanesEnabled >> 5) & 1" ], "", None ), + ( "GL_COLOR_CLEAR_VALUE", GLfloatN, + [ "ctx->Color.ClearColor[0]", + "ctx->Color.ClearColor[1]", + "ctx->Color.ClearColor[2]", + "ctx->Color.ClearColor[3]" ], "", None ), + ( "GL_COLOR_MATERIAL", GLboolean, + ["ctx->Light.ColorMaterialEnabled"], "", None ), + ( "GL_COLOR_MATERIAL_FACE", GLenum, + ["ctx->Light.ColorMaterialFace"], "", None ), + ( "GL_COLOR_MATERIAL_PARAMETER", GLenum, + ["ctx->Light.ColorMaterialMode"], "", None ), + ( "GL_COLOR_WRITEMASK", GLint, + [ "ctx->Color.ColorMask[RCOMP] ? 1 : 0", + "ctx->Color.ColorMask[GCOMP] ? 1 : 0", + "ctx->Color.ColorMask[BCOMP] ? 1 : 0", + "ctx->Color.ColorMask[ACOMP] ? 1 : 0" ], "", None ), + ( "GL_CULL_FACE", GLboolean, ["ctx->Polygon.CullFlag"], "", None ), + ( "GL_CULL_FACE_MODE", GLenum, ["ctx->Polygon.CullFaceMode"], "", None ), + ( "GL_CURRENT_COLOR", GLfloatN, + [ "ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0]", + "ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1]", + "ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2]", + "ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3]" ], + "FLUSH_CURRENT(ctx, 0);", None ), + ( "GL_CURRENT_INDEX", GLfloat, + [ "ctx->Current.Attrib[VERT_ATTRIB_COLOR_INDEX][0]" ], + "FLUSH_CURRENT(ctx, 0);", None ), + ( "GL_CURRENT_NORMAL", GLfloatN, + [ "ctx->Current.Attrib[VERT_ATTRIB_NORMAL][0]", + "ctx->Current.Attrib[VERT_ATTRIB_NORMAL][1]", + "ctx->Current.Attrib[VERT_ATTRIB_NORMAL][2]"], + "FLUSH_CURRENT(ctx, 0);", None ), + ( "GL_CURRENT_RASTER_COLOR", GLfloatN, + ["ctx->Current.RasterColor[0]", + "ctx->Current.RasterColor[1]", + "ctx->Current.RasterColor[2]", + "ctx->Current.RasterColor[3]"], "", None ), + ( "GL_CURRENT_RASTER_DISTANCE", GLfloat, + ["ctx->Current.RasterDistance"], "", None ), + ( "GL_CURRENT_RASTER_INDEX", GLfloat, + ["ctx->Current.RasterIndex"], "", None ), + ( "GL_CURRENT_RASTER_POSITION", GLfloat, + ["ctx->Current.RasterPos[0]", + "ctx->Current.RasterPos[1]", + "ctx->Current.RasterPos[2]", + "ctx->Current.RasterPos[3]"], "", None ), + ( "GL_CURRENT_RASTER_SECONDARY_COLOR", GLfloatN, + ["ctx->Current.RasterSecondaryColor[0]", + "ctx->Current.RasterSecondaryColor[1]", + "ctx->Current.RasterSecondaryColor[2]", + "ctx->Current.RasterSecondaryColor[3]"], "", None ), + ( "GL_CURRENT_RASTER_TEXTURE_COORDS", GLfloat, + ["ctx->Current.RasterTexCoords[texUnit][0]", + "ctx->Current.RasterTexCoords[texUnit][1]", + "ctx->Current.RasterTexCoords[texUnit][2]", + "ctx->Current.RasterTexCoords[texUnit][3]"], + "const GLuint texUnit = ctx->Texture.CurrentUnit;", None ), + ( "GL_CURRENT_RASTER_POSITION_VALID", GLboolean, + ["ctx->Current.RasterPosValid"], "", None ), + ( "GL_CURRENT_TEXTURE_COORDS", GLfloat, + ["ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][0]", + "ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][1]", + "ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][2]", + "ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][3]"], + """const GLuint texUnit = ctx->Texture.CurrentUnit; + FLUSH_CURRENT(ctx, 0);""", None ), + ( "GL_DEPTH_BIAS", GLfloat, ["ctx->Pixel.DepthBias"], "", None ), + ( "GL_DEPTH_BITS", GLint, ["ctx->DrawBuffer->Visual.depthBits"], + "", None ), + ( "GL_DEPTH_CLEAR_VALUE", GLfloatN, ["((GLfloat) ctx->Depth.Clear)"], "", None ), + ( "GL_DEPTH_FUNC", GLenum, ["ctx->Depth.Func"], "", None ), + ( "GL_DEPTH_RANGE", GLfloatN, + [ "ctx->Viewport.Near", "ctx->Viewport.Far" ], "", None ), + ( "GL_DEPTH_SCALE", GLfloat, ["ctx->Pixel.DepthScale"], "", None ), + ( "GL_DEPTH_TEST", GLboolean, ["ctx->Depth.Test"], "", None ), + ( "GL_DEPTH_WRITEMASK", GLboolean, ["ctx->Depth.Mask"], "", None ), + ( "GL_DITHER", GLboolean, ["ctx->Color.DitherFlag"], "", None ), + ( "GL_DOUBLEBUFFER", GLboolean, + ["ctx->DrawBuffer->Visual.doubleBufferMode"], "", None ), + ( "GL_DRAW_BUFFER", GLenum, ["ctx->DrawBuffer->ColorDrawBuffer[0]"], "", None ), + ( "GL_EDGE_FLAG", GLboolean, ["(ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG][0] == 1.0)"], + "FLUSH_CURRENT(ctx, 0);", None ), + ( "GL_FEEDBACK_BUFFER_SIZE", GLint, ["ctx->Feedback.BufferSize"], "", None ), + ( "GL_FEEDBACK_BUFFER_TYPE", GLenum, ["ctx->Feedback.Type"], "", None ), + ( "GL_FOG", GLboolean, ["ctx->Fog.Enabled"], "", None ), + ( "GL_FOG_COLOR", GLfloatN, + [ "ctx->Fog.Color[0]", + "ctx->Fog.Color[1]", + "ctx->Fog.Color[2]", + "ctx->Fog.Color[3]" ], "", None ), + ( "GL_FOG_DENSITY", GLfloat, ["ctx->Fog.Density"], "", None ), + ( "GL_FOG_END", GLfloat, ["ctx->Fog.End"], "", None ), + ( "GL_FOG_HINT", GLenum, ["ctx->Hint.Fog"], "", None ), + ( "GL_FOG_INDEX", GLfloat, ["ctx->Fog.Index"], "", None ), + ( "GL_FOG_MODE", GLenum, ["ctx->Fog.Mode"], "", None ), + ( "GL_FOG_START", GLfloat, ["ctx->Fog.Start"], "", None ), + ( "GL_FRONT_FACE", GLenum, ["ctx->Polygon.FrontFace"], "", None ), + ( "GL_GREEN_BIAS", GLfloat, ["ctx->Pixel.GreenBias"], "", None ), + ( "GL_GREEN_BITS", GLint, ["ctx->DrawBuffer->Visual.greenBits"], + "", None ), + ( "GL_GREEN_SCALE", GLfloat, ["ctx->Pixel.GreenScale"], "", None ), + ( "GL_INDEX_BITS", GLint, ["ctx->DrawBuffer->Visual.indexBits"], + "", None ), + ( "GL_INDEX_CLEAR_VALUE", GLint, ["ctx->Color.ClearIndex"], "", None ), + ( "GL_INDEX_MODE", GLboolean, ["!ctx->DrawBuffer->Visual.rgbMode"], + "", None ), + ( "GL_INDEX_OFFSET", GLint, ["ctx->Pixel.IndexOffset"], "", None ), + ( "GL_INDEX_SHIFT", GLint, ["ctx->Pixel.IndexShift"], "", None ), + ( "GL_INDEX_WRITEMASK", GLint, ["ctx->Color.IndexMask"], "", None ), + ( "GL_LIGHT0", GLboolean, ["ctx->Light.Light[0].Enabled"], "", None ), + ( "GL_LIGHT1", GLboolean, ["ctx->Light.Light[1].Enabled"], "", None ), + ( "GL_LIGHT2", GLboolean, ["ctx->Light.Light[2].Enabled"], "", None ), + ( "GL_LIGHT3", GLboolean, ["ctx->Light.Light[3].Enabled"], "", None ), + ( "GL_LIGHT4", GLboolean, ["ctx->Light.Light[4].Enabled"], "", None ), + ( "GL_LIGHT5", GLboolean, ["ctx->Light.Light[5].Enabled"], "", None ), + ( "GL_LIGHT6", GLboolean, ["ctx->Light.Light[6].Enabled"], "", None ), + ( "GL_LIGHT7", GLboolean, ["ctx->Light.Light[7].Enabled"], "", None ), + ( "GL_LIGHTING", GLboolean, ["ctx->Light.Enabled"], "", None ), + ( "GL_LIGHT_MODEL_AMBIENT", GLfloatN, + ["ctx->Light.Model.Ambient[0]", + "ctx->Light.Model.Ambient[1]", + "ctx->Light.Model.Ambient[2]", + "ctx->Light.Model.Ambient[3]"], "", None ), + ( "GL_LIGHT_MODEL_COLOR_CONTROL", GLenum, + ["ctx->Light.Model.ColorControl"], "", None ), + ( "GL_LIGHT_MODEL_LOCAL_VIEWER", GLboolean, + ["ctx->Light.Model.LocalViewer"], "", None ), + ( "GL_LIGHT_MODEL_TWO_SIDE", GLboolean, ["ctx->Light.Model.TwoSide"], "", None ), + ( "GL_LINE_SMOOTH", GLboolean, ["ctx->Line.SmoothFlag"], "", None ), + ( "GL_LINE_SMOOTH_HINT", GLenum, ["ctx->Hint.LineSmooth"], "", None ), + ( "GL_LINE_STIPPLE", GLboolean, ["ctx->Line.StippleFlag"], "", None ), + ( "GL_LINE_STIPPLE_PATTERN", GLint, ["ctx->Line.StipplePattern"], "", None ), + ( "GL_LINE_STIPPLE_REPEAT", GLint, ["ctx->Line.StippleFactor"], "", None ), + ( "GL_LINE_WIDTH", GLfloat, ["ctx->Line.Width"], "", None ), + ( "GL_LINE_WIDTH_GRANULARITY", GLfloat, + ["ctx->Const.LineWidthGranularity"], "", None ), + ( "GL_LINE_WIDTH_RANGE", GLfloat, + ["ctx->Const.MinLineWidthAA", + "ctx->Const.MaxLineWidthAA"], "", None ), + ( "GL_ALIASED_LINE_WIDTH_RANGE", GLfloat, + ["ctx->Const.MinLineWidth", + "ctx->Const.MaxLineWidth"], "", None ), + ( "GL_LIST_BASE", GLint, ["ctx->List.ListBase"], "", None ), + ( "GL_LIST_INDEX", GLint, ["(ctx->ListState.CurrentList ? ctx->ListState.CurrentList->Name : 0)"], "", None ), + ( "GL_LIST_MODE", GLenum, ["mode"], + """GLenum mode; + if (!ctx->CompileFlag) + mode = 0; + else if (ctx->ExecuteFlag) + mode = GL_COMPILE_AND_EXECUTE; + else + mode = GL_COMPILE;""", None ), + ( "GL_INDEX_LOGIC_OP", GLboolean, ["ctx->Color.IndexLogicOpEnabled"], "", None ), + ( "GL_COLOR_LOGIC_OP", GLboolean, ["ctx->Color.ColorLogicOpEnabled"], "", None ), + ( "GL_LOGIC_OP_MODE", GLenum, ["ctx->Color.LogicOp"], "", None ), + ( "GL_MAP1_COLOR_4", GLboolean, ["ctx->Eval.Map1Color4"], "", None ), + ( "GL_MAP1_GRID_DOMAIN", GLfloat, + ["ctx->Eval.MapGrid1u1", + "ctx->Eval.MapGrid1u2"], "", None ), + ( "GL_MAP1_GRID_SEGMENTS", GLint, ["ctx->Eval.MapGrid1un"], "", None ), + ( "GL_MAP1_INDEX", GLboolean, ["ctx->Eval.Map1Index"], "", None ), + ( "GL_MAP1_NORMAL", GLboolean, ["ctx->Eval.Map1Normal"], "", None ), + ( "GL_MAP1_TEXTURE_COORD_1", GLboolean, ["ctx->Eval.Map1TextureCoord1"], "", None ), + ( "GL_MAP1_TEXTURE_COORD_2", GLboolean, ["ctx->Eval.Map1TextureCoord2"], "", None ), + ( "GL_MAP1_TEXTURE_COORD_3", GLboolean, ["ctx->Eval.Map1TextureCoord3"], "", None ), + ( "GL_MAP1_TEXTURE_COORD_4", GLboolean, ["ctx->Eval.Map1TextureCoord4"], "", None ), + ( "GL_MAP1_VERTEX_3", GLboolean, ["ctx->Eval.Map1Vertex3"], "", None ), + ( "GL_MAP1_VERTEX_4", GLboolean, ["ctx->Eval.Map1Vertex4"], "", None ), + ( "GL_MAP2_COLOR_4", GLboolean, ["ctx->Eval.Map2Color4"], "", None ), + ( "GL_MAP2_GRID_DOMAIN", GLfloat, + ["ctx->Eval.MapGrid2u1", + "ctx->Eval.MapGrid2u2", + "ctx->Eval.MapGrid2v1", + "ctx->Eval.MapGrid2v2"], "", None ), + ( "GL_MAP2_GRID_SEGMENTS", GLint, + ["ctx->Eval.MapGrid2un", + "ctx->Eval.MapGrid2vn"], "", None ), + ( "GL_MAP2_INDEX", GLboolean, ["ctx->Eval.Map2Index"], "", None ), + ( "GL_MAP2_NORMAL", GLboolean, ["ctx->Eval.Map2Normal"], "", None ), + ( "GL_MAP2_TEXTURE_COORD_1", GLboolean, ["ctx->Eval.Map2TextureCoord1"], "", None ), + ( "GL_MAP2_TEXTURE_COORD_2", GLboolean, ["ctx->Eval.Map2TextureCoord2"], "", None ), + ( "GL_MAP2_TEXTURE_COORD_3", GLboolean, ["ctx->Eval.Map2TextureCoord3"], "", None ), + ( "GL_MAP2_TEXTURE_COORD_4", GLboolean, ["ctx->Eval.Map2TextureCoord4"], "", None ), + ( "GL_MAP2_VERTEX_3", GLboolean, ["ctx->Eval.Map2Vertex3"], "", None ), + ( "GL_MAP2_VERTEX_4", GLboolean, ["ctx->Eval.Map2Vertex4"], "", None ), + ( "GL_MAP_COLOR", GLboolean, ["ctx->Pixel.MapColorFlag"], "", None ), + ( "GL_MAP_STENCIL", GLboolean, ["ctx->Pixel.MapStencilFlag"], "", None ), + ( "GL_MATRIX_MODE", GLenum, ["ctx->Transform.MatrixMode"], "", None ), + + ( "GL_MAX_ATTRIB_STACK_DEPTH", GLint, ["MAX_ATTRIB_STACK_DEPTH"], "", None ), + ( "GL_MAX_CLIENT_ATTRIB_STACK_DEPTH", GLint, ["MAX_CLIENT_ATTRIB_STACK_DEPTH"], "", None ), + ( "GL_MAX_CLIP_PLANES", GLint, ["ctx->Const.MaxClipPlanes"], "", None ), + ( "GL_MAX_ELEMENTS_VERTICES", GLint, ["ctx->Const.MaxArrayLockSize"], "", None ), + ( "GL_MAX_ELEMENTS_INDICES", GLint, ["ctx->Const.MaxArrayLockSize"], "", None ), + ( "GL_MAX_EVAL_ORDER", GLint, ["MAX_EVAL_ORDER"], "", None ), + ( "GL_MAX_LIGHTS", GLint, ["ctx->Const.MaxLights"], "", None ), + ( "GL_MAX_LIST_NESTING", GLint, ["MAX_LIST_NESTING"], "", None ), + ( "GL_MAX_MODELVIEW_STACK_DEPTH", GLint, ["MAX_MODELVIEW_STACK_DEPTH"], "", None ), + ( "GL_MAX_NAME_STACK_DEPTH", GLint, ["MAX_NAME_STACK_DEPTH"], "", None ), + ( "GL_MAX_PIXEL_MAP_TABLE", GLint, ["MAX_PIXEL_MAP_TABLE"], "", None ), + ( "GL_MAX_PROJECTION_STACK_DEPTH", GLint, ["MAX_PROJECTION_STACK_DEPTH"], "", None ), + ( "GL_MAX_TEXTURE_SIZE", GLint, ["1 << (ctx->Const.MaxTextureLevels - 1)"], "", None ), + ( "GL_MAX_3D_TEXTURE_SIZE", GLint, ["1 << (ctx->Const.Max3DTextureLevels - 1)"], "", None ), + ( "GL_MAX_TEXTURE_STACK_DEPTH", GLint, ["MAX_TEXTURE_STACK_DEPTH"], "", None ), + ( "GL_MAX_VIEWPORT_DIMS", GLint, + ["ctx->Const.MaxViewportWidth", "ctx->Const.MaxViewportHeight"], + "", None ), + ( "GL_MODELVIEW_MATRIX", GLfloat, + [ "matrix[0]", "matrix[1]", "matrix[2]", "matrix[3]", + "matrix[4]", "matrix[5]", "matrix[6]", "matrix[7]", + "matrix[8]", "matrix[9]", "matrix[10]", "matrix[11]", + "matrix[12]", "matrix[13]", "matrix[14]", "matrix[15]" ], + "const GLfloat *matrix = ctx->ModelviewMatrixStack.Top->m;", None ), + ( "GL_MODELVIEW_STACK_DEPTH", GLint, ["ctx->ModelviewMatrixStack.Depth + 1"], "", None ), + ( "GL_NAME_STACK_DEPTH", GLint, ["ctx->Select.NameStackDepth"], "", None ), + ( "GL_NORMALIZE", GLboolean, ["ctx->Transform.Normalize"], "", None ), + ( "GL_PACK_ALIGNMENT", GLint, ["ctx->Pack.Alignment"], "", None ), + ( "GL_PACK_LSB_FIRST", GLboolean, ["ctx->Pack.LsbFirst"], "", None ), + ( "GL_PACK_ROW_LENGTH", GLint, ["ctx->Pack.RowLength"], "", None ), + ( "GL_PACK_SKIP_PIXELS", GLint, ["ctx->Pack.SkipPixels"], "", None ), + ( "GL_PACK_SKIP_ROWS", GLint, ["ctx->Pack.SkipRows"], "", None ), + ( "GL_PACK_SWAP_BYTES", GLboolean, ["ctx->Pack.SwapBytes"], "", None ), + ( "GL_PACK_SKIP_IMAGES_EXT", GLint, ["ctx->Pack.SkipImages"], "", None ), + ( "GL_PACK_IMAGE_HEIGHT_EXT", GLint, ["ctx->Pack.ImageHeight"], "", None ), + ( "GL_PACK_INVERT_MESA", GLboolean, ["ctx->Pack.Invert"], "", None ), + ( "GL_PERSPECTIVE_CORRECTION_HINT", GLenum, + ["ctx->Hint.PerspectiveCorrection"], "", None ), + ( "GL_PIXEL_MAP_A_TO_A_SIZE", GLint, ["ctx->PixelMaps.AtoA.Size"], "", None ), + ( "GL_PIXEL_MAP_B_TO_B_SIZE", GLint, ["ctx->PixelMaps.BtoB.Size"], "", None ), + ( "GL_PIXEL_MAP_G_TO_G_SIZE", GLint, ["ctx->PixelMaps.GtoG.Size"], "", None ), + ( "GL_PIXEL_MAP_I_TO_A_SIZE", GLint, ["ctx->PixelMaps.ItoA.Size"], "", None ), + ( "GL_PIXEL_MAP_I_TO_B_SIZE", GLint, ["ctx->PixelMaps.ItoB.Size"], "", None ), + ( "GL_PIXEL_MAP_I_TO_G_SIZE", GLint, ["ctx->PixelMaps.ItoG.Size"], "", None ), + ( "GL_PIXEL_MAP_I_TO_I_SIZE", GLint, ["ctx->PixelMaps.ItoI.Size"], "", None ), + ( "GL_PIXEL_MAP_I_TO_R_SIZE", GLint, ["ctx->PixelMaps.ItoR.Size"], "", None ), + ( "GL_PIXEL_MAP_R_TO_R_SIZE", GLint, ["ctx->PixelMaps.RtoR.Size"], "", None ), + ( "GL_PIXEL_MAP_S_TO_S_SIZE", GLint, ["ctx->PixelMaps.StoS.Size"], "", None ), + ( "GL_POINT_SIZE", GLfloat, ["ctx->Point.Size"], "", None ), + ( "GL_POINT_SIZE_GRANULARITY", GLfloat, + ["ctx->Const.PointSizeGranularity"], "", None ), + ( "GL_POINT_SIZE_RANGE", GLfloat, + ["ctx->Const.MinPointSizeAA", + "ctx->Const.MaxPointSizeAA"], "", None ), + ( "GL_ALIASED_POINT_SIZE_RANGE", GLfloat, + ["ctx->Const.MinPointSize", + "ctx->Const.MaxPointSize"], "", None ), + ( "GL_POINT_SMOOTH", GLboolean, ["ctx->Point.SmoothFlag"], "", None ), + ( "GL_POINT_SMOOTH_HINT", GLenum, ["ctx->Hint.PointSmooth"], "", None ), + ( "GL_POINT_SIZE_MIN_EXT", GLfloat, ["ctx->Point.MinSize"], "", None ), + ( "GL_POINT_SIZE_MAX_EXT", GLfloat, ["ctx->Point.MaxSize"], "", None ), + ( "GL_POINT_FADE_THRESHOLD_SIZE_EXT", GLfloat, + ["ctx->Point.Threshold"], "", None ), + ( "GL_DISTANCE_ATTENUATION_EXT", GLfloat, + ["ctx->Point.Params[0]", + "ctx->Point.Params[1]", + "ctx->Point.Params[2]"], "", None ), + ( "GL_POLYGON_MODE", GLenum, + ["ctx->Polygon.FrontMode", + "ctx->Polygon.BackMode"], "", None ), + ( "GL_POLYGON_OFFSET_BIAS_EXT", GLfloat, ["ctx->Polygon.OffsetUnits"], "", None ), + ( "GL_POLYGON_OFFSET_FACTOR", GLfloat, ["ctx->Polygon.OffsetFactor "], "", None ), + ( "GL_POLYGON_OFFSET_UNITS", GLfloat, ["ctx->Polygon.OffsetUnits "], "", None ), + ( "GL_POLYGON_OFFSET_POINT", GLboolean, ["ctx->Polygon.OffsetPoint"], "", None ), + ( "GL_POLYGON_OFFSET_LINE", GLboolean, ["ctx->Polygon.OffsetLine"], "", None ), + ( "GL_POLYGON_OFFSET_FILL", GLboolean, ["ctx->Polygon.OffsetFill"], "", None ), + ( "GL_POLYGON_SMOOTH", GLboolean, ["ctx->Polygon.SmoothFlag"], "", None ), + ( "GL_POLYGON_SMOOTH_HINT", GLenum, ["ctx->Hint.PolygonSmooth"], "", None ), + ( "GL_POLYGON_STIPPLE", GLboolean, ["ctx->Polygon.StippleFlag"], "", None ), + ( "GL_PROJECTION_MATRIX", GLfloat, + [ "matrix[0]", "matrix[1]", "matrix[2]", "matrix[3]", + "matrix[4]", "matrix[5]", "matrix[6]", "matrix[7]", + "matrix[8]", "matrix[9]", "matrix[10]", "matrix[11]", + "matrix[12]", "matrix[13]", "matrix[14]", "matrix[15]" ], + "const GLfloat *matrix = ctx->ProjectionMatrixStack.Top->m;", None ), + ( "GL_PROJECTION_STACK_DEPTH", GLint, + ["ctx->ProjectionMatrixStack.Depth + 1"], "", None ), + ( "GL_READ_BUFFER", GLenum, ["ctx->ReadBuffer->ColorReadBuffer"], "", None ), + ( "GL_RED_BIAS", GLfloat, ["ctx->Pixel.RedBias"], "", None ), + ( "GL_RED_BITS", GLint, ["ctx->DrawBuffer->Visual.redBits"], "", None ), + ( "GL_RED_SCALE", GLfloat, ["ctx->Pixel.RedScale"], "", None ), + ( "GL_RENDER_MODE", GLenum, ["ctx->RenderMode"], "", None ), + ( "GL_RESCALE_NORMAL", GLboolean, + ["ctx->Transform.RescaleNormals"], "", None ), + ( "GL_RGBA_MODE", GLboolean, ["ctx->DrawBuffer->Visual.rgbMode"], + "", None ), + ( "GL_SCISSOR_BOX", GLint, + ["ctx->Scissor.X", + "ctx->Scissor.Y", + "ctx->Scissor.Width", + "ctx->Scissor.Height"], "", None ), + ( "GL_SCISSOR_TEST", GLboolean, ["ctx->Scissor.Enabled"], "", None ), + ( "GL_SELECTION_BUFFER_SIZE", GLint, ["ctx->Select.BufferSize"], "", None ), + ( "GL_SHADE_MODEL", GLenum, ["ctx->Light.ShadeModel"], "", None ), + ( "GL_SHARED_TEXTURE_PALETTE_EXT", GLboolean, + ["ctx->Texture.SharedPalette"], "", None ), + ( "GL_STENCIL_BITS", GLint, ["ctx->DrawBuffer->Visual.stencilBits"], "", None ), + ( "GL_STENCIL_CLEAR_VALUE", GLint, ["ctx->Stencil.Clear"], "", None ), + ( "GL_STENCIL_FAIL", GLenum, + ["ctx->Stencil.FailFunc[ctx->Stencil.ActiveFace]"], "", None ), + ( "GL_STENCIL_FUNC", GLenum, + ["ctx->Stencil.Function[ctx->Stencil.ActiveFace]"], "", None ), + ( "GL_STENCIL_PASS_DEPTH_FAIL", GLenum, + ["ctx->Stencil.ZFailFunc[ctx->Stencil.ActiveFace]"], "", None ), + ( "GL_STENCIL_PASS_DEPTH_PASS", GLenum, + ["ctx->Stencil.ZPassFunc[ctx->Stencil.ActiveFace]"], "", None ), + ( "GL_STENCIL_REF", GLint, + ["ctx->Stencil.Ref[ctx->Stencil.ActiveFace]"], "", None ), + ( "GL_STENCIL_TEST", GLboolean, ["ctx->Stencil.Enabled"], "", None ), + ( "GL_STENCIL_VALUE_MASK", GLint, + ["ctx->Stencil.ValueMask[ctx->Stencil.ActiveFace]"], "", None ), + ( "GL_STENCIL_WRITEMASK", GLint, + ["ctx->Stencil.WriteMask[ctx->Stencil.ActiveFace]"], "", None ), + ( "GL_STEREO", GLboolean, ["ctx->DrawBuffer->Visual.stereoMode"], + "", None ), + ( "GL_SUBPIXEL_BITS", GLint, ["ctx->Const.SubPixelBits"], "", None ), + ( "GL_TEXTURE_1D", GLboolean, ["_mesa_IsEnabled(GL_TEXTURE_1D)"], "", None ), + ( "GL_TEXTURE_2D", GLboolean, ["_mesa_IsEnabled(GL_TEXTURE_2D)"], "", None ), + ( "GL_TEXTURE_3D", GLboolean, ["_mesa_IsEnabled(GL_TEXTURE_3D)"], "", None ), + ( "GL_TEXTURE_1D_ARRAY_EXT", GLboolean, ["_mesa_IsEnabled(GL_TEXTURE_1D_ARRAY_EXT)"], "", ["MESA_texture_array"] ), + ( "GL_TEXTURE_2D_ARRAY_EXT", GLboolean, ["_mesa_IsEnabled(GL_TEXTURE_2D_ARRAY_EXT)"], "", ["MESA_texture_array"] ), + ( "GL_TEXTURE_BINDING_1D", GLint, + ["ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentTex[TEXTURE_1D_INDEX]->Name"], "", None ), + ( "GL_TEXTURE_BINDING_2D", GLint, + ["ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentTex[TEXTURE_2D_INDEX]->Name"], "", None ), + ( "GL_TEXTURE_BINDING_3D", GLint, + ["ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentTex[TEXTURE_3D_INDEX]->Name"], "", None ), + ( "GL_TEXTURE_BINDING_1D_ARRAY_EXT", GLint, + ["ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentTex[TEXTURE_1D_ARRAY_INDEX]->Name"], "", ["MESA_texture_array"] ), + ( "GL_TEXTURE_BINDING_2D_ARRAY_EXT", GLint, + ["ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentTex[TEXTURE_2D_ARRAY_INDEX]->Name"], "", ["MESA_texture_array"] ), + ( "GL_TEXTURE_GEN_S", GLboolean, + ["((ctx->Texture.Unit[ctx->Texture.CurrentUnit].TexGenEnabled & S_BIT) ? 1 : 0)"], "", None ), + ( "GL_TEXTURE_GEN_T", GLboolean, + ["((ctx->Texture.Unit[ctx->Texture.CurrentUnit].TexGenEnabled & T_BIT) ? 1 : 0)"], "", None ), + ( "GL_TEXTURE_GEN_R", GLboolean, + ["((ctx->Texture.Unit[ctx->Texture.CurrentUnit].TexGenEnabled & R_BIT) ? 1 : 0)"], "", None ), + ( "GL_TEXTURE_GEN_Q", GLboolean, + ["((ctx->Texture.Unit[ctx->Texture.CurrentUnit].TexGenEnabled & Q_BIT) ? 1 : 0)"], "", None ), + ( "GL_TEXTURE_MATRIX", GLfloat, + ["matrix[0]", "matrix[1]", "matrix[2]", "matrix[3]", + "matrix[4]", "matrix[5]", "matrix[6]", "matrix[7]", + "matrix[8]", "matrix[9]", "matrix[10]", "matrix[11]", + "matrix[12]", "matrix[13]", "matrix[14]", "matrix[15]" ], + "const GLfloat *matrix = ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Top->m;", None ), + ( "GL_TEXTURE_STACK_DEPTH", GLint, + ["ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Depth + 1"], "", None ), + ( "GL_UNPACK_ALIGNMENT", GLint, ["ctx->Unpack.Alignment"], "", None ), + ( "GL_UNPACK_LSB_FIRST", GLboolean, ["ctx->Unpack.LsbFirst"], "", None ), + ( "GL_UNPACK_ROW_LENGTH", GLint, ["ctx->Unpack.RowLength"], "", None ), + ( "GL_UNPACK_SKIP_PIXELS", GLint, ["ctx->Unpack.SkipPixels"], "", None ), + ( "GL_UNPACK_SKIP_ROWS", GLint, ["ctx->Unpack.SkipRows"], "", None ), + ( "GL_UNPACK_SWAP_BYTES", GLboolean, ["ctx->Unpack.SwapBytes"], "", None ), + ( "GL_UNPACK_SKIP_IMAGES_EXT", GLint, ["ctx->Unpack.SkipImages"], "", None ), + ( "GL_UNPACK_IMAGE_HEIGHT_EXT", GLint, ["ctx->Unpack.ImageHeight"], "", None ), + ( "GL_UNPACK_CLIENT_STORAGE_APPLE", GLboolean, ["ctx->Unpack.ClientStorage"], "", None ), + ( "GL_VIEWPORT", GLint, [ "ctx->Viewport.X", "ctx->Viewport.Y", + "ctx->Viewport.Width", "ctx->Viewport.Height" ], "", None ), + ( "GL_ZOOM_X", GLfloat, ["ctx->Pixel.ZoomX"], "", None ), + ( "GL_ZOOM_Y", GLfloat, ["ctx->Pixel.ZoomY"], "", None ), + + # Vertex arrays + ( "GL_VERTEX_ARRAY", GLboolean, ["ctx->Array.ArrayObj->Vertex.Enabled"], "", None ), + ( "GL_VERTEX_ARRAY_SIZE", GLint, ["ctx->Array.ArrayObj->Vertex.Size"], "", None ), + ( "GL_VERTEX_ARRAY_TYPE", GLenum, ["ctx->Array.ArrayObj->Vertex.Type"], "", None ), + ( "GL_VERTEX_ARRAY_STRIDE", GLint, ["ctx->Array.ArrayObj->Vertex.Stride"], "", None ), + ( "GL_VERTEX_ARRAY_COUNT_EXT", GLint, ["0"], "", None ), + ( "GL_NORMAL_ARRAY", GLenum, ["ctx->Array.ArrayObj->Normal.Enabled"], "", None ), + ( "GL_NORMAL_ARRAY_TYPE", GLenum, ["ctx->Array.ArrayObj->Normal.Type"], "", None ), + ( "GL_NORMAL_ARRAY_STRIDE", GLint, ["ctx->Array.ArrayObj->Normal.Stride"], "", None ), + ( "GL_NORMAL_ARRAY_COUNT_EXT", GLint, ["0"], "", None ), + ( "GL_COLOR_ARRAY", GLboolean, ["ctx->Array.ArrayObj->Color.Enabled"], "", None ), + ( "GL_COLOR_ARRAY_SIZE", GLint, ["ctx->Array.ArrayObj->Color.Size"], "", None ), + ( "GL_COLOR_ARRAY_TYPE", GLenum, ["ctx->Array.ArrayObj->Color.Type"], "", None ), + ( "GL_COLOR_ARRAY_STRIDE", GLint, ["ctx->Array.ArrayObj->Color.Stride"], "", None ), + ( "GL_COLOR_ARRAY_COUNT_EXT", GLint, ["0"], "", None ), + ( "GL_INDEX_ARRAY", GLboolean, ["ctx->Array.ArrayObj->Index.Enabled"], "", None ), + ( "GL_INDEX_ARRAY_TYPE", GLenum, ["ctx->Array.ArrayObj->Index.Type"], "", None ), + ( "GL_INDEX_ARRAY_STRIDE", GLint, ["ctx->Array.ArrayObj->Index.Stride"], "", None ), + ( "GL_INDEX_ARRAY_COUNT_EXT", GLint, ["0"], "", None ), + ( "GL_TEXTURE_COORD_ARRAY", GLboolean, + ["ctx->Array.ArrayObj->TexCoord[ctx->Array.ActiveTexture].Enabled"], "", None ), + ( "GL_TEXTURE_COORD_ARRAY_SIZE", GLint, + ["ctx->Array.ArrayObj->TexCoord[ctx->Array.ActiveTexture].Size"], "", None ), + ( "GL_TEXTURE_COORD_ARRAY_TYPE", GLenum, + ["ctx->Array.ArrayObj->TexCoord[ctx->Array.ActiveTexture].Type"], "", None ), + ( "GL_TEXTURE_COORD_ARRAY_STRIDE", GLint, + ["ctx->Array.ArrayObj->TexCoord[ctx->Array.ActiveTexture].Stride"], "", None ), + ( "GL_TEXTURE_COORD_ARRAY_COUNT_EXT", GLint, ["0"], "", None ), + ( "GL_EDGE_FLAG_ARRAY", GLboolean, ["ctx->Array.ArrayObj->EdgeFlag.Enabled"], "", None ), + ( "GL_EDGE_FLAG_ARRAY_STRIDE", GLint, ["ctx->Array.ArrayObj->EdgeFlag.Stride"], "", None ), + ( "GL_EDGE_FLAG_ARRAY_COUNT_EXT", GLint, ["0"], "", None ), + + # GL_ARB_multitexture + ( "GL_MAX_TEXTURE_UNITS_ARB", GLint, + ["ctx->Const.MaxTextureUnits"], "", ["ARB_multitexture"] ), + ( "GL_ACTIVE_TEXTURE_ARB", GLint, + [ "GL_TEXTURE0_ARB + ctx->Texture.CurrentUnit"], "", ["ARB_multitexture"] ), + ( "GL_CLIENT_ACTIVE_TEXTURE_ARB", GLint, + ["GL_TEXTURE0_ARB + ctx->Array.ActiveTexture"], "", ["ARB_multitexture"] ), + + # GL_ARB_texture_cube_map + ( "GL_TEXTURE_CUBE_MAP_ARB", GLboolean, + ["_mesa_IsEnabled(GL_TEXTURE_CUBE_MAP_ARB)"], "", ["ARB_texture_cube_map"] ), + ( "GL_TEXTURE_BINDING_CUBE_MAP_ARB", GLint, + ["ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentTex[TEXTURE_CUBE_INDEX]->Name"], + "", ["ARB_texture_cube_map"] ), + ( "GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB", GLint, + ["(1 << (ctx->Const.MaxCubeTextureLevels - 1))"], + "", ["ARB_texture_cube_map"]), + + # GL_ARB_texture_compression */ + ( "GL_TEXTURE_COMPRESSION_HINT_ARB", GLint, + ["ctx->Hint.TextureCompression"], "", None ), + ( "GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB", GLint, + ["_mesa_get_compressed_formats(ctx, NULL, GL_FALSE)"], + "", None ), + ( "GL_COMPRESSED_TEXTURE_FORMATS_ARB", GLenum, + [], + """GLint formats[100]; + GLuint i, n = _mesa_get_compressed_formats(ctx, formats, GL_FALSE); + ASSERT(n <= 100); + for (i = 0; i < n; i++) + params[i] = CONVERSION(formats[i]);""", + None ), + + # GL_EXT_compiled_vertex_array + ( "GL_ARRAY_ELEMENT_LOCK_FIRST_EXT", GLint, ["ctx->Array.LockFirst"], + "", ["EXT_compiled_vertex_array"] ), + ( "GL_ARRAY_ELEMENT_LOCK_COUNT_EXT", GLint, ["ctx->Array.LockCount"], + "", ["EXT_compiled_vertex_array"] ), + + # GL_ARB_transpose_matrix + ( "GL_TRANSPOSE_COLOR_MATRIX_ARB", GLfloat, + ["matrix[0]", "matrix[4]", "matrix[8]", "matrix[12]", + "matrix[1]", "matrix[5]", "matrix[9]", "matrix[13]", + "matrix[2]", "matrix[6]", "matrix[10]", "matrix[14]", + "matrix[3]", "matrix[7]", "matrix[11]", "matrix[15]"], + "const GLfloat *matrix = ctx->ColorMatrixStack.Top->m;", None ), + ( "GL_TRANSPOSE_MODELVIEW_MATRIX_ARB", GLfloat, + ["matrix[0]", "matrix[4]", "matrix[8]", "matrix[12]", + "matrix[1]", "matrix[5]", "matrix[9]", "matrix[13]", + "matrix[2]", "matrix[6]", "matrix[10]", "matrix[14]", + "matrix[3]", "matrix[7]", "matrix[11]", "matrix[15]"], + "const GLfloat *matrix = ctx->ModelviewMatrixStack.Top->m;", None ), + ( "GL_TRANSPOSE_PROJECTION_MATRIX_ARB", GLfloat, + ["matrix[0]", "matrix[4]", "matrix[8]", "matrix[12]", + "matrix[1]", "matrix[5]", "matrix[9]", "matrix[13]", + "matrix[2]", "matrix[6]", "matrix[10]", "matrix[14]", + "matrix[3]", "matrix[7]", "matrix[11]", "matrix[15]"], + "const GLfloat *matrix = ctx->ProjectionMatrixStack.Top->m;", None ), + ( "GL_TRANSPOSE_TEXTURE_MATRIX_ARB", GLfloat, + ["matrix[0]", "matrix[4]", "matrix[8]", "matrix[12]", + "matrix[1]", "matrix[5]", "matrix[9]", "matrix[13]", + "matrix[2]", "matrix[6]", "matrix[10]", "matrix[14]", + "matrix[3]", "matrix[7]", "matrix[11]", "matrix[15]"], + "const GLfloat *matrix = ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Top->m;", None ), + + # GL_SGI_color_matrix (also in 1.2 imaging) + ( "GL_COLOR_MATRIX_SGI", GLfloat, + ["matrix[0]", "matrix[1]", "matrix[2]", "matrix[3]", + "matrix[4]", "matrix[5]", "matrix[6]", "matrix[7]", + "matrix[8]", "matrix[9]", "matrix[10]", "matrix[11]", + "matrix[12]", "matrix[13]", "matrix[14]", "matrix[15]" ], + "const GLfloat *matrix = ctx->ColorMatrixStack.Top->m;", None ), + ( "GL_COLOR_MATRIX_STACK_DEPTH_SGI", GLint, + ["ctx->ColorMatrixStack.Depth + 1"], "", None ), + ( "GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI", GLint, + ["MAX_COLOR_STACK_DEPTH"], "", None ), + ( "GL_POST_COLOR_MATRIX_RED_SCALE_SGI", GLfloat, + ["ctx->Pixel.PostColorMatrixScale[0]"], "", None ), + ( "GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI", GLfloat, + ["ctx->Pixel.PostColorMatrixScale[1]"], "", None ), + ( "GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI", GLfloat, + ["ctx->Pixel.PostColorMatrixScale[2]"], "", None ), + ( "GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI", GLfloat, + ["ctx->Pixel.PostColorMatrixScale[3]"], "", None ), + ( "GL_POST_COLOR_MATRIX_RED_BIAS_SGI", GLfloat, + ["ctx->Pixel.PostColorMatrixBias[0]"], "", None ), + ( "GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI", GLfloat, + ["ctx->Pixel.PostColorMatrixBias[1]"], "", None ), + ( "GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI", GLfloat, + ["ctx->Pixel.PostColorMatrixBias[2]"], "", None ), + ( "GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI", GLfloat, + ["ctx->Pixel.PostColorMatrixBias[3]"], "", None ), + + # GL_EXT_convolution (also in 1.2 imaging) + ( "GL_CONVOLUTION_1D_EXT", GLboolean, + ["ctx->Pixel.Convolution1DEnabled"], "", ["EXT_convolution"] ), + ( "GL_CONVOLUTION_2D_EXT", GLboolean, + ["ctx->Pixel.Convolution2DEnabled"], "", ["EXT_convolution"] ), + ( "GL_SEPARABLE_2D_EXT", GLboolean, + ["ctx->Pixel.Separable2DEnabled"], "", ["EXT_convolution"] ), + ( "GL_POST_CONVOLUTION_RED_SCALE_EXT", GLfloat, + ["ctx->Pixel.PostConvolutionScale[0]"], "", ["EXT_convolution"] ), + ( "GL_POST_CONVOLUTION_GREEN_SCALE_EXT", GLfloat, + ["ctx->Pixel.PostConvolutionScale[1]"], "", ["EXT_convolution"] ), + ( "GL_POST_CONVOLUTION_BLUE_SCALE_EXT", GLfloat, + ["ctx->Pixel.PostConvolutionScale[2]"], "", ["EXT_convolution"] ), + ( "GL_POST_CONVOLUTION_ALPHA_SCALE_EXT", GLfloat, + ["ctx->Pixel.PostConvolutionScale[3]"], "", ["EXT_convolution"] ), + ( "GL_POST_CONVOLUTION_RED_BIAS_EXT", GLfloat, + ["ctx->Pixel.PostConvolutionBias[0]"], "", ["EXT_convolution"] ), + ( "GL_POST_CONVOLUTION_GREEN_BIAS_EXT", GLfloat, + ["ctx->Pixel.PostConvolutionBias[1]"], "", ["EXT_convolution"] ), + ( "GL_POST_CONVOLUTION_BLUE_BIAS_EXT", GLfloat, + ["ctx->Pixel.PostConvolutionBias[2]"], "", ["EXT_convolution"] ), + ( "GL_POST_CONVOLUTION_ALPHA_BIAS_EXT", GLfloat, + ["ctx->Pixel.PostConvolutionBias[3]"], "", ["EXT_convolution"] ), + + # GL_EXT_histogram / GL_ARB_imaging + ( "GL_HISTOGRAM", GLboolean, + [ "ctx->Pixel.HistogramEnabled" ], "", ["EXT_histogram"] ), + ( "GL_MINMAX", GLboolean, + [ "ctx->Pixel.MinMaxEnabled" ], "", ["EXT_histogram"] ), + + # GL_SGI_color_table / GL_ARB_imaging + ( "GL_COLOR_TABLE_SGI", GLboolean, + ["ctx->Pixel.ColorTableEnabled[COLORTABLE_PRECONVOLUTION]"], "", ["SGI_color_table"] ), + ( "GL_POST_CONVOLUTION_COLOR_TABLE_SGI", GLboolean, + ["ctx->Pixel.ColorTableEnabled[COLORTABLE_POSTCONVOLUTION]"], "", ["SGI_color_table"] ), + ( "GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI", GLboolean, + ["ctx->Pixel.ColorTableEnabled[COLORTABLE_POSTCOLORMATRIX]"], "", ["SGI_color_table"] ), + + # GL_SGI_texture_color_table + ( "GL_TEXTURE_COLOR_TABLE_SGI", GLboolean, + ["ctx->Texture.Unit[ctx->Texture.CurrentUnit].ColorTableEnabled"], + "", ["SGI_texture_color_table"] ), + + # GL_EXT_secondary_color + ( "GL_COLOR_SUM_EXT", GLboolean, + ["ctx->Fog.ColorSumEnabled"], "", + ["EXT_secondary_color", "ARB_vertex_program"] ), + ( "GL_CURRENT_SECONDARY_COLOR_EXT", GLfloatN, + ["ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0]", + "ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1]", + "ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2]", + "ctx->Current.Attrib[VERT_ATTRIB_COLOR1][3]"], + "FLUSH_CURRENT(ctx, 0);", ["EXT_secondary_color"] ), + ( "GL_SECONDARY_COLOR_ARRAY_EXT", GLboolean, + ["ctx->Array.ArrayObj->SecondaryColor.Enabled"], "", ["EXT_secondary_color"] ), + ( "GL_SECONDARY_COLOR_ARRAY_TYPE_EXT", GLenum, + ["ctx->Array.ArrayObj->SecondaryColor.Type"], "", ["EXT_secondary_color"] ), + ( "GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT", GLint, + ["ctx->Array.ArrayObj->SecondaryColor.Stride"], "", ["EXT_secondary_color"] ), + ( "GL_SECONDARY_COLOR_ARRAY_SIZE_EXT", GLint, + ["ctx->Array.ArrayObj->SecondaryColor.Size"], "", ["EXT_secondary_color"] ), + + # GL_EXT_fog_coord + ( "GL_CURRENT_FOG_COORDINATE_EXT", GLfloat, + ["ctx->Current.Attrib[VERT_ATTRIB_FOG][0]"], + "FLUSH_CURRENT(ctx, 0);", ["EXT_fog_coord"] ), + ( "GL_FOG_COORDINATE_ARRAY_EXT", GLboolean, ["ctx->Array.ArrayObj->FogCoord.Enabled"], + "", ["EXT_fog_coord"] ), + ( "GL_FOG_COORDINATE_ARRAY_TYPE_EXT", GLenum, ["ctx->Array.ArrayObj->FogCoord.Type"], + "", ["EXT_fog_coord"] ), + ( "GL_FOG_COORDINATE_ARRAY_STRIDE_EXT", GLint, ["ctx->Array.ArrayObj->FogCoord.Stride"], + "", ["EXT_fog_coord"] ), + ( "GL_FOG_COORDINATE_SOURCE_EXT", GLenum, ["ctx->Fog.FogCoordinateSource"], + "", ["EXT_fog_coord"] ), + + # GL_EXT_texture_lod_bias + ( "GL_MAX_TEXTURE_LOD_BIAS_EXT", GLfloat, + ["ctx->Const.MaxTextureLodBias"], "", ["EXT_texture_lod_bias"]), + + # GL_EXT_texture_filter_anisotropic + ( "GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT", GLfloat, + ["ctx->Const.MaxTextureMaxAnisotropy"], "", ["EXT_texture_filter_anisotropic"]), + + # GL_ARB_multisample + ( "GL_MULTISAMPLE_ARB", GLboolean, + ["ctx->Multisample.Enabled"], "", None ), + ( "GL_SAMPLE_ALPHA_TO_COVERAGE_ARB", GLboolean, + ["ctx->Multisample.SampleAlphaToCoverage"], "", None ), + ( "GL_SAMPLE_ALPHA_TO_ONE_ARB", GLboolean, + ["ctx->Multisample.SampleAlphaToOne"], "", None ), + ( "GL_SAMPLE_COVERAGE_ARB", GLboolean, + ["ctx->Multisample.SampleCoverage"], "", None ), + ( "GL_SAMPLE_COVERAGE_VALUE_ARB", GLfloat, + ["ctx->Multisample.SampleCoverageValue"], "", None ), + ( "GL_SAMPLE_COVERAGE_INVERT_ARB", GLboolean, + ["ctx->Multisample.SampleCoverageInvert"], "", None ), + ( "GL_SAMPLE_BUFFERS_ARB", GLint, + ["ctx->DrawBuffer->Visual.sampleBuffers"], "", None ), + ( "GL_SAMPLES_ARB", GLint, + ["ctx->DrawBuffer->Visual.samples"], "", None ), + + # GL_IBM_rasterpos_clip + ( "GL_RASTER_POSITION_UNCLIPPED_IBM", GLboolean, + ["ctx->Transform.RasterPositionUnclipped"], "", ["IBM_rasterpos_clip"] ), + + # GL_NV_point_sprite + ( "GL_POINT_SPRITE_NV", GLboolean, ["ctx->Point.PointSprite"], # == GL_POINT_SPRITE_ARB + "", ["NV_point_sprite", "ARB_point_sprite"] ), + ( "GL_POINT_SPRITE_R_MODE_NV", GLenum, ["ctx->Point.SpriteRMode"], + "", ["NV_point_sprite"] ), + ( "GL_POINT_SPRITE_COORD_ORIGIN", GLenum, ["ctx->Point.SpriteOrigin"], + "", ["NV_point_sprite", "ARB_point_sprite"] ), + + # GL_SGIS_generate_mipmap + ( "GL_GENERATE_MIPMAP_HINT_SGIS", GLenum, ["ctx->Hint.GenerateMipmap"], + "", ["SGIS_generate_mipmap"] ), + + # GL_NV_vertex_program + ( "GL_VERTEX_PROGRAM_BINDING_NV", GLint, + ["(ctx->VertexProgram.Current ? ctx->VertexProgram.Current->Base.Id : 0)"], + "", ["NV_vertex_program"] ), + ( "GL_VERTEX_ATTRIB_ARRAY0_NV", GLboolean, + ["ctx->Array.ArrayObj->VertexAttrib[0].Enabled"], "", ["NV_vertex_program"] ), + ( "GL_VERTEX_ATTRIB_ARRAY1_NV", GLboolean, + ["ctx->Array.ArrayObj->VertexAttrib[1].Enabled"], "", ["NV_vertex_program"] ), + ( "GL_VERTEX_ATTRIB_ARRAY2_NV", GLboolean, + ["ctx->Array.ArrayObj->VertexAttrib[2].Enabled"], "", ["NV_vertex_program"] ), + ( "GL_VERTEX_ATTRIB_ARRAY3_NV", GLboolean, + ["ctx->Array.ArrayObj->VertexAttrib[3].Enabled"], "", ["NV_vertex_program"] ), + ( "GL_VERTEX_ATTRIB_ARRAY4_NV", GLboolean, + ["ctx->Array.ArrayObj->VertexAttrib[4].Enabled"], "", ["NV_vertex_program"] ), + ( "GL_VERTEX_ATTRIB_ARRAY5_NV", GLboolean, + ["ctx->Array.ArrayObj->VertexAttrib[5].Enabled"], "", ["NV_vertex_program"] ), + ( "GL_VERTEX_ATTRIB_ARRAY6_NV", GLboolean, + ["ctx->Array.ArrayObj->VertexAttrib[6].Enabled"], "", ["NV_vertex_program"] ), + ( "GL_VERTEX_ATTRIB_ARRAY7_NV", GLboolean, + ["ctx->Array.ArrayObj->VertexAttrib[7].Enabled"], "", ["NV_vertex_program"] ), + ( "GL_VERTEX_ATTRIB_ARRAY8_NV", GLboolean, + ["ctx->Array.ArrayObj->VertexAttrib[8].Enabled"], "", ["NV_vertex_program"] ), + ( "GL_VERTEX_ATTRIB_ARRAY9_NV", GLboolean, + ["ctx->Array.ArrayObj->VertexAttrib[9].Enabled"], "", ["NV_vertex_program"] ), + ( "GL_VERTEX_ATTRIB_ARRAY10_NV", GLboolean, + ["ctx->Array.ArrayObj->VertexAttrib[10].Enabled"], "", ["NV_vertex_program"] ), + ( "GL_VERTEX_ATTRIB_ARRAY11_NV", GLboolean, + ["ctx->Array.ArrayObj->VertexAttrib[11].Enabled"], "", ["NV_vertex_program"] ), + ( "GL_VERTEX_ATTRIB_ARRAY12_NV", GLboolean, + ["ctx->Array.ArrayObj->VertexAttrib[12].Enabled"], "", ["NV_vertex_program"] ), + ( "GL_VERTEX_ATTRIB_ARRAY13_NV", GLboolean, + ["ctx->Array.ArrayObj->VertexAttrib[13].Enabled"], "", ["NV_vertex_program"] ), + ( "GL_VERTEX_ATTRIB_ARRAY14_NV", GLboolean, + ["ctx->Array.ArrayObj->VertexAttrib[14].Enabled"], "", ["NV_vertex_program"] ), + ( "GL_VERTEX_ATTRIB_ARRAY15_NV", GLboolean, + ["ctx->Array.ArrayObj->VertexAttrib[15].Enabled"], "", ["NV_vertex_program"] ), + ( "GL_MAP1_VERTEX_ATTRIB0_4_NV", GLboolean, + ["ctx->Eval.Map1Attrib[0]"], "", ["NV_vertex_program"] ), + ( "GL_MAP1_VERTEX_ATTRIB1_4_NV", GLboolean, + ["ctx->Eval.Map1Attrib[1]"], "", ["NV_vertex_program"] ), + ( "GL_MAP1_VERTEX_ATTRIB2_4_NV", GLboolean, + ["ctx->Eval.Map1Attrib[2]"], "", ["NV_vertex_program"] ), + ( "GL_MAP1_VERTEX_ATTRIB3_4_NV", GLboolean, + ["ctx->Eval.Map1Attrib[3]"], "", ["NV_vertex_program"] ), + ( "GL_MAP1_VERTEX_ATTRIB4_4_NV", GLboolean, + ["ctx->Eval.Map1Attrib[4]"], "", ["NV_vertex_program"] ), + ( "GL_MAP1_VERTEX_ATTRIB5_4_NV", GLboolean, + ["ctx->Eval.Map1Attrib[5]"], "", ["NV_vertex_program"] ), + ( "GL_MAP1_VERTEX_ATTRIB6_4_NV", GLboolean, + ["ctx->Eval.Map1Attrib[6]"], "", ["NV_vertex_program"] ), + ( "GL_MAP1_VERTEX_ATTRIB7_4_NV", GLboolean, + ["ctx->Eval.Map1Attrib[7]"], "", ["NV_vertex_program"] ), + ( "GL_MAP1_VERTEX_ATTRIB8_4_NV", GLboolean, + ["ctx->Eval.Map1Attrib[8]"], "", ["NV_vertex_program"] ), + ( "GL_MAP1_VERTEX_ATTRIB9_4_NV", GLboolean, + ["ctx->Eval.Map1Attrib[9]"], "", ["NV_vertex_program"] ), + ( "GL_MAP1_VERTEX_ATTRIB10_4_NV", GLboolean, + ["ctx->Eval.Map1Attrib[10]"], "", ["NV_vertex_program"] ), + ( "GL_MAP1_VERTEX_ATTRIB11_4_NV", GLboolean, + ["ctx->Eval.Map1Attrib[11]"], "", ["NV_vertex_program"] ), + ( "GL_MAP1_VERTEX_ATTRIB12_4_NV", GLboolean, + ["ctx->Eval.Map1Attrib[12]"], "", ["NV_vertex_program"] ), + ( "GL_MAP1_VERTEX_ATTRIB13_4_NV", GLboolean, + ["ctx->Eval.Map1Attrib[13]"], "", ["NV_vertex_program"] ), + ( "GL_MAP1_VERTEX_ATTRIB14_4_NV", GLboolean, + ["ctx->Eval.Map1Attrib[14]"], "", ["NV_vertex_program"] ), + ( "GL_MAP1_VERTEX_ATTRIB15_4_NV", GLboolean, + ["ctx->Eval.Map1Attrib[15]"], "", ["NV_vertex_program"] ), + + # GL_NV_fragment_program + ( "GL_FRAGMENT_PROGRAM_NV", GLboolean, + ["ctx->FragmentProgram.Enabled"], "", ["NV_fragment_program"] ), + ( "GL_FRAGMENT_PROGRAM_BINDING_NV", GLint, + ["ctx->FragmentProgram.Current ? ctx->FragmentProgram.Current->Base.Id : 0"], + "", ["NV_fragment_program"] ), + ( "GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV", GLint, + ["MAX_NV_FRAGMENT_PROGRAM_PARAMS"], "", ["NV_fragment_program"] ), + + # GL_NV_texture_rectangle + ( "GL_TEXTURE_RECTANGLE_NV", GLboolean, + ["_mesa_IsEnabled(GL_TEXTURE_RECTANGLE_NV)"], "", ["NV_texture_rectangle"] ), + ( "GL_TEXTURE_BINDING_RECTANGLE_NV", GLint, + ["ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentTex[TEXTURE_RECT_INDEX]->Name"], + "", ["NV_texture_rectangle"] ), + ( "GL_MAX_RECTANGLE_TEXTURE_SIZE_NV", GLint, + ["ctx->Const.MaxTextureRectSize"], "", ["NV_texture_rectangle"] ), + + # GL_EXT_stencil_two_side + ( "GL_STENCIL_TEST_TWO_SIDE_EXT", GLboolean, + ["ctx->Stencil.TestTwoSide"], "", ["EXT_stencil_two_side"] ), + ( "GL_ACTIVE_STENCIL_FACE_EXT", GLenum, + ["ctx->Stencil.ActiveFace ? GL_BACK : GL_FRONT"], + "", ["EXT_stencil_two_side"] ), + + # GL_NV_light_max_exponent + ( "GL_MAX_SHININESS_NV", GLfloat, + ["ctx->Const.MaxShininess"], "", ["NV_light_max_exponent"] ), + ( "GL_MAX_SPOT_EXPONENT_NV", GLfloat, + ["ctx->Const.MaxSpotExponent"], "", ["NV_light_max_exponent"] ), + + # GL_ARB_vertex_buffer_object + ( "GL_ARRAY_BUFFER_BINDING_ARB", GLint, + ["ctx->Array.ArrayBufferObj->Name"], "", None ), + ( "GL_VERTEX_ARRAY_BUFFER_BINDING_ARB", GLint, + ["ctx->Array.ArrayObj->Vertex.BufferObj->Name"], "", None ), + ( "GL_NORMAL_ARRAY_BUFFER_BINDING_ARB", GLint, + ["ctx->Array.ArrayObj->Normal.BufferObj->Name"], "", None ), + ( "GL_COLOR_ARRAY_BUFFER_BINDING_ARB", GLint, + ["ctx->Array.ArrayObj->Color.BufferObj->Name"], "", None ), + ( "GL_INDEX_ARRAY_BUFFER_BINDING_ARB", GLint, + ["ctx->Array.ArrayObj->Index.BufferObj->Name"], "", None ), + ( "GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB", GLint, + ["ctx->Array.ArrayObj->TexCoord[ctx->Array.ActiveTexture].BufferObj->Name"], + "", None ), + ( "GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB", GLint, + ["ctx->Array.ArrayObj->EdgeFlag.BufferObj->Name"], "", None ), + ( "GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB", GLint, + ["ctx->Array.ArrayObj->SecondaryColor.BufferObj->Name"], + "", None ), + ( "GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB", GLint, + ["ctx->Array.ArrayObj->FogCoord.BufferObj->Name"], + "", None ), + # GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB - not supported + ( "GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB", GLint, + ["ctx->Array.ElementArrayBufferObj->Name"], + "", None ), + + # GL_EXT_pixel_buffer_object + ( "GL_PIXEL_PACK_BUFFER_BINDING_EXT", GLint, + ["ctx->Pack.BufferObj->Name"], "", ["EXT_pixel_buffer_object"] ), + ( "GL_PIXEL_UNPACK_BUFFER_BINDING_EXT", GLint, + ["ctx->Unpack.BufferObj->Name"], "", ["EXT_pixel_buffer_object"] ), + + # GL_ARB_vertex_program + ( "GL_VERTEX_PROGRAM_ARB", GLboolean, # == GL_VERTEX_PROGRAM_NV + ["ctx->VertexProgram.Enabled"], "", + ["ARB_vertex_program", "NV_vertex_program"] ), + ( "GL_VERTEX_PROGRAM_POINT_SIZE_ARB", GLboolean, # == GL_VERTEX_PROGRAM_POINT_SIZE_NV + ["ctx->VertexProgram.PointSizeEnabled"], "", + ["ARB_vertex_program", "NV_vertex_program"] ), + ( "GL_VERTEX_PROGRAM_TWO_SIDE_ARB", GLboolean, # == GL_VERTEX_PROGRAM_TWO_SIDE_NV + ["ctx->VertexProgram.TwoSideEnabled"], "", + ["ARB_vertex_program", "NV_vertex_program"] ), + ( "GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB", GLint, # == GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV + ["ctx->Const.MaxProgramMatrixStackDepth"], "", + ["ARB_vertex_program", "ARB_fragment_program", "NV_vertex_program"] ), + ( "GL_MAX_PROGRAM_MATRICES_ARB", GLint, # == GL_MAX_TRACK_MATRICES_NV + ["ctx->Const.MaxProgramMatrices"], "", + ["ARB_vertex_program", "ARB_fragment_program", "NV_vertex_program"] ), + ( "GL_CURRENT_MATRIX_STACK_DEPTH_ARB", GLboolean, # == GL_CURRENT_MATRIX_STACK_DEPTH_NV + ["ctx->CurrentStack->Depth + 1"], "", + ["ARB_vertex_program", "ARB_fragment_program", "NV_vertex_program"] ), + ( "GL_CURRENT_MATRIX_ARB", GLfloat, # == GL_CURRENT_MATRIX_NV + ["matrix[0]", "matrix[1]", "matrix[2]", "matrix[3]", + "matrix[4]", "matrix[5]", "matrix[6]", "matrix[7]", + "matrix[8]", "matrix[9]", "matrix[10]", "matrix[11]", + "matrix[12]", "matrix[13]", "matrix[14]", "matrix[15]" ], + "const GLfloat *matrix = ctx->CurrentStack->Top->m;", + ["ARB_vertex_program", "ARB_fragment_program", "NV_fragment_program"] ), + ( "GL_TRANSPOSE_CURRENT_MATRIX_ARB", GLfloat, + ["matrix[0]", "matrix[4]", "matrix[8]", "matrix[12]", + "matrix[1]", "matrix[5]", "matrix[9]", "matrix[13]", + "matrix[2]", "matrix[6]", "matrix[10]", "matrix[14]", + "matrix[3]", "matrix[7]", "matrix[11]", "matrix[15]"], + "const GLfloat *matrix = ctx->CurrentStack->Top->m;", + ["ARB_vertex_program", "ARB_fragment_program"] ), + ( "GL_MAX_VERTEX_ATTRIBS_ARB", GLint, + ["ctx->Const.VertexProgram.MaxAttribs"], "", ["ARB_vertex_program"] ), + ( "GL_PROGRAM_ERROR_POSITION_ARB", GLint, # == GL_PROGRAM_ERROR_POSITION_NV + ["ctx->Program.ErrorPos"], "", ["NV_vertex_program", + "ARB_vertex_program", "NV_fragment_program", "ARB_fragment_program"] ), + + # GL_ARB_fragment_program + ( "GL_FRAGMENT_PROGRAM_ARB", GLboolean, + ["ctx->FragmentProgram.Enabled"], "", ["ARB_fragment_program"] ), + ( "GL_MAX_TEXTURE_COORDS_ARB", GLint, # == GL_MAX_TEXTURE_COORDS_NV + ["ctx->Const.MaxTextureCoordUnits"], "", + ["ARB_fragment_program", "NV_fragment_program"] ), + ( "GL_MAX_TEXTURE_IMAGE_UNITS_ARB", GLint, # == GL_MAX_TEXTURE_IMAGE_UNITS_NV + ["ctx->Const.MaxTextureImageUnits"], "", + ["ARB_fragment_program", "NV_fragment_program"] ), + + # GL_EXT_depth_bounds_test + ( "GL_DEPTH_BOUNDS_TEST_EXT", GLboolean, + ["ctx->Depth.BoundsTest"], "", ["EXT_depth_bounds_test"] ), + ( "GL_DEPTH_BOUNDS_EXT", GLfloat, + ["ctx->Depth.BoundsMin", "ctx->Depth.BoundsMax"], + "", ["EXT_depth_bounds_test"] ), + + # GL_ARB_draw_buffers + ( "GL_MAX_DRAW_BUFFERS_ARB", GLint, + ["ctx->Const.MaxDrawBuffers"], "", None ), + ( "GL_DRAW_BUFFER0_ARB", GLenum, + ["ctx->DrawBuffer->ColorDrawBuffer[0]"], "", None ), + ( "GL_DRAW_BUFFER1_ARB", GLenum, + ["buffer"], + """GLenum buffer; + if (pname - GL_DRAW_BUFFER0_ARB >= ctx->Const.MaxDrawBuffers) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGet(GL_DRAW_BUFFERx_ARB)"); + return; + } + buffer = ctx->DrawBuffer->ColorDrawBuffer[1];""", None ), + ( "GL_DRAW_BUFFER2_ARB", GLenum, + ["buffer"], + """GLenum buffer; + if (pname - GL_DRAW_BUFFER0_ARB >= ctx->Const.MaxDrawBuffers) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGet(GL_DRAW_BUFFERx_ARB)"); + return; + } + buffer = ctx->DrawBuffer->ColorDrawBuffer[2];""", None ), + ( "GL_DRAW_BUFFER3_ARB", GLenum, + ["buffer"], + """GLenum buffer; + if (pname - GL_DRAW_BUFFER0_ARB >= ctx->Const.MaxDrawBuffers) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGet(GL_DRAW_BUFFERx_ARB)"); + return; + } + buffer = ctx->DrawBuffer->ColorDrawBuffer[3];""", None ), + # XXX Add more GL_DRAW_BUFFERn_ARB entries as needed in the future + + # GL_OES_read_format + ( "GL_IMPLEMENTATION_COLOR_READ_TYPE_OES", GLint, + ["ctx->Const.ColorReadType"], "", ["OES_read_format"] ), + ( "GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES", GLint, + ["ctx->Const.ColorReadFormat"], "", ["OES_read_format"] ), + + # GL_ATI_fragment_shader + ( "GL_NUM_FRAGMENT_REGISTERS_ATI", GLint, ["6"], "", ["ATI_fragment_shader"] ), + ( "GL_NUM_FRAGMENT_CONSTANTS_ATI", GLint, ["8"], "", ["ATI_fragment_shader"] ), + ( "GL_NUM_PASSES_ATI", GLint, ["2"], "", ["ATI_fragment_shader"] ), + ( "GL_NUM_INSTRUCTIONS_PER_PASS_ATI", GLint, ["8"], "", ["ATI_fragment_shader"] ), + ( "GL_NUM_INSTRUCTIONS_TOTAL_ATI", GLint, ["16"], "", ["ATI_fragment_shader"] ), + ( "GL_COLOR_ALPHA_PAIRING_ATI", GLboolean, ["GL_TRUE"], "", ["ATI_fragment_shader"] ), + ( "GL_NUM_LOOPBACK_COMPONENTS_ATI", GLint, ["3"], "", ["ATI_fragment_shader"] ), + ( "GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI", GLint, ["3"], "", ["ATI_fragment_shader"] ), + + # OpenGL 2.0 + ( "GL_STENCIL_BACK_FUNC", GLenum, ["ctx->Stencil.Function[1]"], "", None ), + ( "GL_STENCIL_BACK_VALUE_MASK", GLint, ["ctx->Stencil.ValueMask[1]"], "", None ), + ( "GL_STENCIL_BACK_WRITEMASK", GLint, ["ctx->Stencil.WriteMask[1]"], "", None ), + ( "GL_STENCIL_BACK_REF", GLint, ["ctx->Stencil.Ref[1]"], "", None ), + ( "GL_STENCIL_BACK_FAIL", GLenum, ["ctx->Stencil.FailFunc[1]"], "", None ), + ( "GL_STENCIL_BACK_PASS_DEPTH_FAIL", GLenum, ["ctx->Stencil.ZFailFunc[1]"], "", None ), + ( "GL_STENCIL_BACK_PASS_DEPTH_PASS", GLenum, ["ctx->Stencil.ZPassFunc[1]"], "", None ), + + # GL_EXT_framebuffer_object + ( "GL_FRAMEBUFFER_BINDING_EXT", GLint, ["ctx->DrawBuffer->Name"], "", + ["EXT_framebuffer_object"] ), + ( "GL_RENDERBUFFER_BINDING_EXT", GLint, + ["ctx->CurrentRenderbuffer ? ctx->CurrentRenderbuffer->Name : 0"], "", + ["EXT_framebuffer_object"] ), + ( "GL_MAX_COLOR_ATTACHMENTS_EXT", GLint, + ["ctx->Const.MaxColorAttachments"], "", + ["EXT_framebuffer_object"] ), + ( "GL_MAX_RENDERBUFFER_SIZE_EXT", GLint, + ["ctx->Const.MaxRenderbufferSize"], "", + ["EXT_framebuffer_object"] ), + + # GL_EXT_framebuffer_blit + # NOTE: GL_DRAW_FRAMEBUFFER_BINDING_EXT == GL_FRAMEBUFFER_BINDING_EXT + ( "GL_READ_FRAMEBUFFER_BINDING_EXT", GLint, ["ctx->ReadBuffer->Name"], "", + ["EXT_framebuffer_blit"] ), + + # GL_EXT_provoking_vertex + ( "GL_PROVOKING_VERTEX_EXT", GLboolean, + ["ctx->Light.ProvokingVertex"], "", ["EXT_provoking_vertex"] ), + ( "GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT", GLboolean, + ["ctx->Const.QuadsFollowProvokingVertexConvention"], "", + ["EXT_provoking_vertex"] ), + + # GL_ARB_fragment_shader + ( "GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB", GLint, + ["ctx->Const.FragmentProgram.MaxUniformComponents"], "", + ["ARB_fragment_shader"] ), + ( "GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB", GLenum, + ["ctx->Hint.FragmentShaderDerivative"], "", ["ARB_fragment_shader"] ), + + # GL_ARB_vertex_shader + ( "GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB", GLint, + ["ctx->Const.VertexProgram.MaxUniformComponents"], "", + ["ARB_vertex_shader"] ), + ( "GL_MAX_VARYING_FLOATS_ARB", GLint, + ["ctx->Const.MaxVarying * 4"], "", ["ARB_vertex_shader"] ), + ( "GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB", GLint, + ["ctx->Const.MaxVertexTextureImageUnits"], "", ["ARB_vertex_shader"] ), + ( "GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB", GLint, + ["MAX_COMBINED_TEXTURE_IMAGE_UNITS"], "", ["ARB_vertex_shader"] ), + + # GL_ARB_shader_objects + # Actually, this token isn't part of GL_ARB_shader_objects, but is + # close enough for now. + ( "GL_CURRENT_PROGRAM", GLint, + ["ctx->Shader.CurrentProgram ? ctx->Shader.CurrentProgram->Name : 0"], + "", ["ARB_shader_objects"] ), + + # GL_ARB_framebuffer_object + ( "GL_MAX_SAMPLES", GLint, ["ctx->Const.MaxSamples"], "", + ["ARB_framebuffer_object"] ), + + # GL_APPLE_vertex_array_object + ( "GL_VERTEX_ARRAY_BINDING_APPLE", GLint, ["ctx->Array.ArrayObj->Name"], "", + ["APPLE_vertex_array_object"] ), + + # GL_ARB_seamless_cube_map + ( "GL_TEXTURE_CUBE_MAP_SEAMLESS", GLboolean, ["ctx->Texture.CubeMapSeamless"], "", + ["ARB_seamless_cube_map"] ), + + # GL_ARB_sync + ( "GL_MAX_SERVER_WAIT_TIMEOUT", GLint64, ["ctx->Const.MaxServerWaitTimeout"], "", + ["ARB_sync"] ), +] + + +def ConversionFunc(fromType, toType): + """Return the name of the macro to convert between two data types.""" + if fromType == toType: + return "" + elif fromType == GLfloat and toType == GLint: + return "IROUND" + elif fromType == GLfloat and toType == GLint64: + return "IROUND64" + elif fromType == GLfloatN and toType == GLfloat: + return "" + elif fromType == GLint and toType == GLfloat: # but not GLfloatN! + return "(GLfloat)" + elif fromType == GLint and toType == GLint64: + return "(GLint64)" + elif fromType == GLint64 and toType == GLfloat: # but not GLfloatN! + return "(GLfloat)" + else: + if fromType == GLfloatN: + fromType = GLfloat + fromStr = TypeStrings[fromType] + fromStr = string.upper(fromStr[2:]) + toStr = TypeStrings[toType] + toStr = string.upper(toStr[2:]) + return fromStr + "_TO_" + toStr + + +def EmitGetFunction(stateVars, returnType): + """Emit the code to implement glGetBooleanv, glGetIntegerv or glGetFloatv.""" + assert (returnType == GLboolean or + returnType == GLint or + returnType == GLint64 or + returnType == GLfloat) + + strType = TypeStrings[returnType] + # Capitalize first letter of return type + if returnType == GLint: + function = "GetIntegerv" + elif returnType == GLboolean: + function = "GetBooleanv" + elif returnType == GLfloat: + function = "GetFloatv" + elif returnType == GLint64: + function = "GetInteger64v" + else: + abort() + + if returnType == GLint64: + print "#if FEATURE_ARB_sync" + + print "void GLAPIENTRY" + print "_mesa_%s( GLenum pname, %s *params )" % (function, strType) + print "{" + print " GET_CURRENT_CONTEXT(ctx);" + print " ASSERT_OUTSIDE_BEGIN_END(ctx);" + print "" + print " if (!params)" + print " return;" + print "" + print " if (ctx->NewState)" + print " _mesa_update_state(ctx);" + print "" + print " if (ctx->Driver.%s &&" % function + print " ctx->Driver.%s(ctx, pname, params))" % function + print " return;" + print "" + print " switch (pname) {" + + for (name, varType, state, optionalCode, extensions) in stateVars: + print " case " + name + ":" + if extensions: + if len(extensions) == 1: + print (' CHECK_EXT1(%s, "%s");' % + (extensions[0], function)) + elif len(extensions) == 2: + print (' CHECK_EXT2(%s, %s, "%s");' % + (extensions[0], extensions[1], function)) + elif len(extensions) == 3: + print (' CHECK_EXT3(%s, %s, %s, "%s");' % + (extensions[0], extensions[1], extensions[2], function)) + else: + assert len(extensions) == 4 + print (' CHECK_EXT4(%s, %s, %s, %s, "%s");' % + (extensions[0], extensions[1], extensions[2], extensions[3], function)) + conversion = ConversionFunc(varType, returnType) + if optionalCode: + optionalCode = string.replace(optionalCode, "CONVERSION", conversion); + print " {" + print " " + optionalCode + n = len(state) + for i in range(n): + if conversion: + print " params[%d] = %s(%s);" % (i, conversion, state[i]) + else: + print " params[%d] = %s;" % (i, state[i]) + if optionalCode: + print " }" + print " break;" + + print " default:" + print ' _mesa_error(ctx, GL_INVALID_ENUM, "gl%s(pname=0x%%x)", pname);' % function + print " }" + print "}" + if returnType == GLint64: + print "#endif /* FEATURE_ARB_sync */" + print "" + return + + + +def EmitHeader(): + """Print the get.c file header.""" + print """ +/*** + *** NOTE!!! DO NOT EDIT THIS FILE!!! IT IS GENERATED BY get_gen.py + ***/ + +#include "glheader.h" +#include "context.h" +#include "enable.h" +#include "extensions.h" +#include "fbobject.h" +#include "get.h" +#include "macros.h" +#include "mtypes.h" +#include "state.h" +#include "texcompress.h" + + +#define FLOAT_TO_BOOLEAN(X) ( (X) ? GL_TRUE : GL_FALSE ) + +#define INT_TO_BOOLEAN(I) ( (I) ? GL_TRUE : GL_FALSE ) + +#define INT64_TO_BOOLEAN(I) ( (I) ? GL_TRUE : GL_FALSE ) +#define INT64_TO_INT(I) ( (GLint)((I > INT_MAX) ? INT_MAX : ((I < INT_MIN) ? INT_MIN : (I))) ) + +#define BOOLEAN_TO_INT(B) ( (GLint) (B) ) +#define BOOLEAN_TO_INT64(B) ( (GLint64) (B) ) +#define BOOLEAN_TO_FLOAT(B) ( (B) ? 1.0F : 0.0F ) + +#define ENUM_TO_INT64(E) ( (GLint64) (E) ) + + +/* + * Check if named extension is enabled, if not generate error and return. + */ +#define CHECK_EXT1(EXT1, FUNC) \\ + if (!ctx->Extensions.EXT1) { \\ + _mesa_error(ctx, GL_INVALID_ENUM, FUNC "(0x%x)", (int) pname); \\ + return; \\ + } + +/* + * Check if either of two extensions is enabled. + */ +#define CHECK_EXT2(EXT1, EXT2, FUNC) \\ + if (!ctx->Extensions.EXT1 && !ctx->Extensions.EXT2) { \\ + _mesa_error(ctx, GL_INVALID_ENUM, FUNC "(0x%x)", (int) pname); \\ + return; \\ + } + +/* + * Check if either of three extensions is enabled. + */ +#define CHECK_EXT3(EXT1, EXT2, EXT3, FUNC) \\ + if (!ctx->Extensions.EXT1 && !ctx->Extensions.EXT2 && \\ + !ctx->Extensions.EXT3) { \\ + _mesa_error(ctx, GL_INVALID_ENUM, FUNC "(0x%x)", (int) pname); \\ + return; \\ + } + +/* + * Check if either of four extensions is enabled. + */ +#define CHECK_EXT4(EXT1, EXT2, EXT3, EXT4, FUNC) \\ + if (!ctx->Extensions.EXT1 && !ctx->Extensions.EXT2 && \\ + !ctx->Extensions.EXT3 && !ctx->Extensions.EXT4) { \\ + _mesa_error(ctx, GL_INVALID_ENUM, FUNC "(0x%x)", (int) pname); \\ + return; \\ + } + +""" + return + + + +def EmitGetDoublev(): + print """ +void GLAPIENTRY +_mesa_GetDoublev( GLenum pname, GLdouble *params ) +{ + const GLfloat magic = -1234.5F; + GLfloat values[16]; + GLuint i; + + if (!params) + return; + + /* Init temp array to magic numbers so we can figure out how many values + * are returned by the GetFloatv() call. + */ + for (i = 0; i < 16; i++) + values[i] = magic; + + _mesa_GetFloatv(pname, values); + + for (i = 0; i < 16 && values[i] != magic; i++) + params[i] = (GLdouble) values[i]; +} +""" + + + + +EmitHeader() +# XXX Maybe sort the StateVars list +EmitGetFunction(StateVars, GLboolean) +EmitGetFunction(StateVars, GLfloat) +EmitGetFunction(StateVars, GLint) +EmitGetFunction(StateVars, GLint64) +EmitGetDoublev() + diff --git a/mesalib/src/mesa/main/sources b/mesalib/src/mesa/main/sources new file mode 100644 index 000000000..5d9d99040 --- /dev/null +++ b/mesalib/src/mesa/main/sources @@ -0,0 +1,158 @@ +# List of source files in this directory used for X.org xserver build +MESA_MAIN_SOURCES = \ +accum.c \ +api_arrayelt.c \ +api_exec.c \ +api_loopback.c \ +api_noop.c \ +api_validate.c \ +arrayobj.c \ +attrib.c \ +blend.c \ +bufferobj.c \ +buffers.c \ +clear.c \ +clip.c \ +colortab.c \ +context.c \ +convolve.c \ +debug.c \ +depth.c \ +depthstencil.c \ +dlist.c \ +dlopen.c \ +drawpix.c \ +enable.c \ +enums.c \ +eval.c \ +execmem.c \ +extensions.c \ +fbobject.c \ +feedback.c \ +fog.c \ +framebuffer.c \ +get.c \ +getstring.c \ +hash.c \ +hint.c \ +histogram.c \ +image.c \ +imports.c \ +light.c \ +lines.c \ +matrix.c \ +mipmap.c \ +mm.c \ +multisample.c \ +occlude.c \ +pixel.c \ +pixelstore.c \ +points.c \ +polygon.c \ +readpix.c \ +rastpos.c \ +rbadaptors.c \ +renderbuffer.c \ +scissor.c \ +state.c \ +stencil.c \ +texcompress.c \ +texcompress_fxt1.c \ +texcompress_s3tc.c \ +texenv.c \ +texenvprogram.c \ +texformat.c \ +texgen.c \ +texgetimage.c \ +teximage.c \ +texobj.c \ +texparam.c \ +texrender.c \ +texstate.c \ +texstore.c \ +varray.c \ +$(VSNPRINTF_SOURCES) \ +vtxfmt.c + +MESA_VSNPRINTF_SOURCES = \ +vsnprintf.c + +MESA_MAIN_HEADERS = \ +accum.h \ +api_arrayelt.h \ +api_exec.h \ +api_loopback.h \ +api_noop.h \ +api_validate.h \ +arrayobj.h \ +attrib.h \ +bitset.h \ +blend.h \ +bufferobj.h \ +buffers.h \ +clear.h \ +clip.h \ +colormac.h \ +colortab.h \ +config.h \ +context.h \ +convolve.h \ +dd.h \ +debug.h \ +depth.h \ +depthstencil.h \ +dlist.h \ +dlopen.h \ +drawpix.h \ +enable.h \ +enums.h \ +eval.h \ +extensions.h \ +fbobject.h \ +feedback.h \ +fog.h \ +framebuffer.h \ +get.h \ +glheader.h \ +hash.h \ +hint.h \ +histogram.h \ +image.h \ +imports.h \ +light.h \ +lines.h \ +macros.h \ +matrix.h \ +mipmap.h \ +mm.h \ +mtypes.h \ +multisample.h \ +occlude.h \ +pixel.h \ +pixelstore.h \ +points.h \ +polygon.h \ +rastpos.h \ +rbadaptors.h \ +readpix.h \ +renderbuffer.h \ +simple_list.h \ +scissor.h \ +state.h \ +stencil.h \ +texcompress.h \ +texenv.h \ +texenvprogram.h \ +texformat.h \ +texformat_tmp.h \ +texgen.h \ +teximage.h \ +texobj.h \ +texparam.h \ +texrender.h \ +texstate.h \ +texstore.h \ +varray.h \ +version.h \ +vtxfmt.h \ +vtxfmt_tmp.h diff --git a/mesalib/src/mesa/shader/grammar/grammar.syn b/mesalib/src/mesa/shader/grammar/grammar.syn new file mode 100644 index 000000000..5d99f65bf --- /dev/null +++ b/mesalib/src/mesa/shader/grammar/grammar.syn @@ -0,0 +1,567 @@ +/* + * Mesa 3-D graphics library + * Version: 6.2 + * + * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * 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. + */ + + /** + * \file grammar.syn + * syntax of .syn script - used to validate other syntax files + * \author Michal Krol + */ + +.syntax grammar; + +/* declaration */ +.emtcode DECLARATION_END 0 +.emtcode DECLARATION_EMITCODE 1 +.emtcode DECLARATION_ERRORTEXT 2 +.emtcode DECLARATION_REGBYTE 3 +.emtcode DECLARATION_LEXER 4 +.emtcode DECLARATION_RULE 5 + +/* specifier */ +.emtcode SPECIFIER_END 0 +.emtcode SPECIFIER_AND_TAG 1 +.emtcode SPECIFIER_OR_TAG 2 +.emtcode SPECIFIER_CHARACTER_RANGE 3 +.emtcode SPECIFIER_CHARACTER 4 +.emtcode SPECIFIER_STRING 5 +.emtcode SPECIFIER_IDENTIFIER 6 +.emtcode SPECIFIER_TRUE 7 +.emtcode SPECIFIER_FALSE 8 +.emtcode SPECIFIER_DEBUG 9 + +/* identifier */ +.emtcode IDENTIFIER_SIMPLE 0 +.emtcode IDENTIFIER_LOOP 1 + +/* error */ +.emtcode ERROR_NOT_PRESENT 0 +.emtcode ERROR_PRESENT 1 + +/* emit */ +.emtcode EMIT_NULL 0 +.emtcode EMIT_INTEGER 1 +.emtcode EMIT_IDENTIFIER 2 +.emtcode EMIT_CHARACTER 3 +.emtcode EMIT_LAST_CHARACTER 4 +.emtcode EMIT_CURRENT_POSITION 5 + +.errtext INVALID_GRAMMAR "internal error 2001: invalid grammar script" +.errtext SYNTAX_EXPECTED "internal error 2002: '.syntax' keyword expected" +.errtext IDENTIFIER_EXPECTED "internal error 2003: identifier expected" +.errtext MISSING_SEMICOLON "internal error 2004: missing ';'" +.errtext INTEGER_EXPECTED "internal error 2005: integer value expected" +.errtext STRING_EXPECTED "internal error 2006: string expected" + +/* + ::= ".syntax" ";" +*/ +grammar + grammar_1 .error INVALID_GRAMMAR; +grammar_1 + optional_space .and ".syntax" .error SYNTAX_EXPECTED .and space .and identifier .and + semicolon .and declaration_list .and optional_space .and '\0' .emit DECLARATION_END; + +/* + ::= + | "" +*/ +optional_space + space .or .true; + +/* + ::= * +*/ +space + single_space .and .loop single_space; + +/* + ::= + | +*/ +single_space + white_char .or comment_block; + +/* + ::= " " + | "\t" + | "\n" + | "\r" +*/ +white_char + ' ' .or '\t' .or '\n' .or '\r'; + +/* + ::= "/" "*" +*/ +comment_block + '/' .and '*' .and comment_rest; + +/* + ::= * + | * "*" +*/ +comment_rest + .loop comment_char_no_star .and comment_rest_1; +comment_rest_1 + comment_end .or comment_rest_2; +comment_rest_2 + '*' .and comment_rest; + +/* + ::= All ASCII characters except "*" and "\0" +*/ +comment_char_no_star + '\x2B'-'\xFF' .or '\x01'-'\x29'; + +/* + ::= "*" "/" +*/ +comment_end + '*' .and '/'; + +/* + ::= +*/ +identifier + identifier_ne .error IDENTIFIER_EXPECTED; + +/* + ::= * +*/ +identifier_ne + first_idchar .emit * .and .loop follow_idchar .emit * .and .true .emit '\0'; + +/* + ::= "a"-"z" + | "A"-"Z" + | "_" +*/ +first_idchar + 'a'-'z' .or 'A'-'Z' .or '_'; + +/* + ::= + | +*/ +follow_idchar + first_idchar .or digit_dec; + +/* + ::= "0"-"9" +*/ +digit_dec + '0'-'9'; + +/* + ::= ";" +*/ +semicolon + optional_space .and ';' .error MISSING_SEMICOLON .and optional_space; + +/* + ::= + | +*/ +declaration_list + declaration .and .loop declaration; + +/* + ::= + | + | + | +*/ +declaration + emitcode_definition .emit DECLARATION_EMITCODE .or + errortext_definition .emit DECLARATION_ERRORTEXT .or + regbyte_definition .emit DECLARATION_REGBYTE .or + lexer_definition .emit DECLARATION_LEXER .or + rule_definition .emit DECLARATION_RULE; + +/* + ::= ".emtcode" +*/ +emitcode_definition + ".emtcode" .and space .and identifier .and space .and integer .and space_or_null; + +/* + ::= +*/ +integer + integer_ne .error INTEGER_EXPECTED; + +/* + ::= + | +*/ +integer_ne + hex_integer .emit 0x10 .or dec_integer .emit 10; + +/* + :: * +*/ +hex_integer + hex_prefix .and digit_hex .emit * .and .loop digit_hex .emit * .and .true .emit '\0'; + +/* + ::= "0x" + | "0X" +*/ +hex_prefix + '0' .and hex_prefix_1; +hex_prefix_1 + 'x' .or 'X'; + +/* + ::= "0"-"9" + | "a"-"f" + | "A"-"F" +*/ +digit_hex + '0'-'9' .or 'a'-'f' .or 'A'-'F'; + +/* + :: * +*/ +dec_integer + digit_dec .emit * .and .loop digit_dec .emit * .and .true .emit '\0'; + +/* + ::= + | "\0" +*/ +space_or_null + space .or '\0'; + +/* + ::= ".errtext" +*/ +errortext_definition + ".errtext" .and space .and identifier .and space .and string .and space_or_null; + +/* + ::= +*/ +string + string_ne .error STRING_EXPECTED; + +/* + ::= "\"" "\"" +*/ +string_ne + '"' .and .loop string_char_double_quotes .and '"' .emit '\0'; + +/* + ::= + | + | "\'" +*/ +string_char_double_quotes + escape_sequence .or string_char .emit * .or '\'' .emit *; + +/* + ::= All ASCII characters except "\'", "\"", "\n", "\r", + "\0" and "\\" +*/ +string_char + '\x5D'-'\xFF' .or '\x28'-'\x5B' .or '\x23'-'\x26' .or '\x0E'-'\x21' .or '\x0B'-'\x0C' .or + '\x01'-'\x09'; + +/* + ::= "\\" +*/ +escape_sequence + '\\' .emit * .and escape_code; + +/* + ::= + | + | +*/ +escape_code + simple_escape_code .emit * .or hex_escape_code .or oct_escape_code; + +/* + ::= "\'" + | "\"" + | "?" + | "\\" + | "a" + | "b" + | "f" + | "n" + | "r" + | "t" + | "v" +*/ +simple_escape_code + '\'' .or '"' .or '?' .or '\\' .or 'a' .or 'b' .or 'f' .or 'n' .or 'r' .or 't' .or 'v'; + +/* + ::= "x" * +*/ +hex_escape_code + 'x' .emit * .and digit_hex .emit * .and .loop digit_hex .emit *; + +/* + ::= +*/ +oct_escape_code + digit_oct .emit * .and optional_digit_oct .and optional_digit_oct; + +/* + ::= "0"-"7" +*/ +digit_oct + '0'-'7'; + +/* + ::= + | "" +*/ +optional_digit_oct + digit_oct .emit * .or .true; + +/* + ::= ".regbyte" +*/ +regbyte_definition + ".regbyte" .and space .and identifier .and space .and integer .and space_or_null; + +/* + ::= ".string" ";" +*/ +lexer_definition + ".string" .and space .and identifier .and semicolon; + +/* + ::= +*/ +rule_definition + identifier_ne .and space .and definition; + +/* + ::= ";" +*/ +definition + specifier .and optional_specifiers_and_or .and semicolon .emit SPECIFIER_END; + +/* + ::= + | + | "" +*/ +optional_specifiers_and_or + and_specifiers .emit SPECIFIER_AND_TAG .or or_specifiers .emit SPECIFIER_OR_TAG .or .true; + +/* + ::= +*/ +specifier + specifier_condition .and optional_space .and specifier_rule; + +/* + ::= ".if" "(" ")" +*/ +specifier_condition + specifier_condition_1 .or .true; +specifier_condition_1 + ".if" .and optional_space .and '(' .and optional_space .and left_operand .and operator .and + right_operand .and optional_space .and ')'; + +/* + ::= +*/ +left_operand + identifier; + +/* + ::= "!=" + | "==" +*/ +operator + operator_1 .or operator_2; +operator_1 + optional_space .and '!' .and '=' .and optional_space; +operator_2 + optional_space .and '=' .and '=' .and optional_space; + +/* + ::= +*/ +right_operand + integer; + +/* + ::= * + | * + | * + | ".true" * + | ".false" * + | ".debug" * + | * +*/ +specifier_rule + specifier_rule_1 .and optional_error .and .loop emit .and .true .emit EMIT_NULL; +specifier_rule_1 + character_range .emit SPECIFIER_CHARACTER_RANGE .or + character .emit SPECIFIER_CHARACTER .or + string_ne .emit SPECIFIER_STRING .or + ".true" .emit SPECIFIER_TRUE .or + ".false" .emit SPECIFIER_FALSE .or + ".debug" .emit SPECIFIER_DEBUG .or + advanced_identifier .emit SPECIFIER_IDENTIFIER; + +/* + ::= "\'" ::= + | + | "\"" +*/ +string_char_single_quotes + escape_sequence .or string_char .emit * .or '"' .emit *; + +/* + ::= "-" +*/ +character_range + character .and optional_space .and '-' .and optional_space .and character; + +/* + ::= +*/ +advanced_identifier + optional_loop .and identifier; + +/* + ::= ".loop" + | "" +*/ +optional_loop + optional_loop_1 .emit IDENTIFIER_LOOP .or .true .emit IDENTIFIER_SIMPLE; +optional_loop_1 + ".loop" .and space; + +/* + ::= + | "" +*/ +optional_error + error .emit ERROR_PRESENT .or .true .emit ERROR_NOT_PRESENT; + +/* + :: ".error" +*/ +error + space .and ".error" .and space .and identifier; + +/* + ::= + | +*/ +emit + emit_output .or emit_regbyte; + +/* + ::= ".emit" +*/ +emit_output + space .and ".emit" .and space .and emit_param; + +/* + ::= + | + | + | "*" + | "$" +*/ +emit_param + integer_ne .emit EMIT_INTEGER .or + identifier_ne .emit EMIT_IDENTIFIER .or + character .emit EMIT_CHARACTER .or + '*' .emit EMIT_LAST_CHARACTER .or + '$' .emit EMIT_CURRENT_POSITION; + +/* + ::= ".load" +*/ +emit_regbyte + space .and ".load" .and space .and identifier .and space .and emit_param; + +/* + ::= * +*/ +and_specifiers + and_specifier .and .loop and_specifier; + +/* + ::= * +*/ +or_specifiers + or_specifier .and .loop or_specifier; + +/* + ::= ".and" +*/ +and_specifier + space .and ".and" .and space .and specifier; + +/* + ::= ".or" +*/ +or_specifier + space .and ".or" .and space .and specifier; + + +.string __string_filter; + +/* + <__string_filter> ::= <__first_identifier_char> <__next_identifier_char>* +*/ +__string_filter + __first_identifier_char .and .loop __next_identifier_char; + +/* + <__first_identifier_char> ::= "a"-"z" + | "A"-"Z" + | "_" + | "." +*/ +__first_identifier_char + 'a'-'z' .or 'A'-'Z' .or '_' .or '.'; + +/* + <__next_identifier_char> ::= "a"-"z" + | "A"-"Z" + | "_" + | "0"-"9" +*/ +__next_identifier_char + 'a'-'z' .or 'A'-'Z' .or '_' .or '0'-'9'; + diff --git a/mesalib/src/mesa/swrast/NOTES b/mesalib/src/mesa/swrast/NOTES new file mode 100644 index 000000000..f906e41b9 --- /dev/null +++ b/mesalib/src/mesa/swrast/NOTES @@ -0,0 +1,55 @@ +INTRODUCTION + +Mesa's native software rasterizer. This module provides the fallback +paths for rasterization operations and states that aren't accelerated +in hardware drivers, and as the full rasterization engine in software +drivers. + +The swrast module 'stands alone', relying only on interfaces to core +mesa and it's own driver interface. It knows nothing about the tnl or +other modules, allowing it to be used for fallback paths in future tnl +schemes without modification. + +As well as providing triangle/line/point rasterization functionality, +the module provides implementations of the pixel operations +(ReadPixels, etc), and texture operations (CopyTexSubImage) which may +be plugged in to the core Mesa driver interface where accelerated +versions of these operations are unavailable. + + +STATE + +To create and destroy the module: + + GLboolean _swrast_CreateContext( GLcontext *ctx ); + void _swrast_DestroyContext( GLcontext *ctx ); + +This module tracks state changes internally and maintains derived +values based on the current state. For this to work, the driver +ensure the following funciton is called whenever the state changes and +the swsetup module is 'awake': + + void _swrast_InvalidateState( GLcontext *ctx, GLuint new_state ); + +There is no explicit call to put the swrast module to sleep. + + +CUSTOMIZATION + + void (*choose_point)( GLcontext * ); + void (*choose_line)( GLcontext * ); + void (*choose_triangle)( GLcontext * ); + +Drivers may add additional triangle/line/point functions to swrast by +overriding these functions. It is necessary for the driver to be very +careful that it doesn't return an inappropriate function, eg a +rasterization function in feedback mode. See the X11 driver for +examples. + +DRIVER INTERFACE + +The swrast device driver provides swrast primarily with span- and +pixel- level interfaces to a framebuffer, with a few additional hooks +for locking and setting the read buffer. + +See the definition of struct swrast_device_driver in swrast.h. \ No newline at end of file diff --git a/mesalib/src/mesa/swrast_setup/NOTES b/mesalib/src/mesa/swrast_setup/NOTES new file mode 100644 index 000000000..c6cb4ab34 --- /dev/null +++ b/mesalib/src/mesa/swrast_setup/NOTES @@ -0,0 +1,65 @@ +INTRODUCTION + +A helper module which provides glue to bind the software rasterizer to +the software t&l module. The main task of this module is to build +swrast vertices from the t&l vertex_buffer structs, and to use them to +perform triangle setup functions not implemented in the software +rasterizer. + +The module implements a full set of functions to plug into the +t_vb_render.c driver interface (tnl->Driver.Render.*). + +There are strong advantages to decoupling the software rasterizer from +the t&l module, primarily allowing hardware drivers better control +over fallbacks, the removal of implicit knowledge about the software +rasterizer in the t&l module, allowing the two modules to evolve +independently and allowing either to be substituted with equivalent +functionality from another codebase. + +This module implements triangle/quad setup for offset, unfilled and +twoside-lit triangles. The software rasterizer doesn't handle these +primitives directly. + +Hardware rasterization drivers typically use this module in situations +where no hardware rasterization is possible, ie during total +fallbacks. + +STATE + +To create and destroy the module: + + GLboolean _swsetup_CreateContext( GLcontext *ctx ); + void _swsetup_DestroyContext( GLcontext *ctx ); + +The module is not active by default, and must be installed by calling +_swrast_Wakeup(). This function installs internal swrast_setup +functions into all the tnl->Driver.Render driver hooks, thus taking +over the task of rasterization entirely: + + void _swrast_Wakeup( GLcontext *ctx ); + + +This module tracks state changes internally and maintains derived +values based on the current state. For this to work, the driver +ensure the following funciton is called whenever the state changes and +the swsetup module is 'awake': + + void _swsetup_InvalidateState( GLcontext *ctx, GLuint new_state ); + +There is no explicit call to put the swsetup module to sleep. Simply +install other function pointers into all the tnl->Driver.Render.* +hooks, and (optionally) cease calling _swsetup_InvalidateState(). + +DRIVER INTERFACE + +The module offers a minimal driver interface: + + void (*Start)( GLcontext *ctx ); + void (*Finish)( GLcontext *ctx ); + +These are called before and after the completion of all swrast drawing +activity. As swrast doesn't call callbacks during triangle, line or +point rasterization, these are necessary to provide locking hooks for +some drivers. They may otherwise be left null. + + diff --git a/mesalib/src/mesa/tnl/NOTES b/mesalib/src/mesa/tnl/NOTES new file mode 100644 index 000000000..c39b43485 --- /dev/null +++ b/mesalib/src/mesa/tnl/NOTES @@ -0,0 +1,102 @@ +INTRODUCTION + +A generic, configurable software implementation of GL transformation & +lighting. + +This module provides an implementation of the routines required by the +'vtxfmt' mechanism of core mesa for tnl functionality in all +combinations of compile and execute modes. + +Most current drivers use the tnl module exclusively to provide this +functionality, though there is an experimental alternate +implementation provided by the tnl_dd/t_dd_imm_* files which can +handle a small subset of GL states in execute mode only. + + +STATE + +To create and destroy the module: + + GLboolean _tnl_CreateContext( GLcontext *ctx ); + void _tnl_DestroyContext( GLcontext *ctx ); + +The module is not active by default, and must be installed by calling +_tnl_Wakeup(). This function installs internal tnl functions into all +the vtxfmt dispatch hooks, thus taking over the task of transformation +and lighting entirely: + + void _tnl_wakeup_exec( GLcontext *ctx ); + void _tnl_wakeup_save_exec( GLcontext *ctx ); + + +This module tracks state changes internally and maintains derived +values based on the current state. For this to work, the driver +ensure the following funciton is called whenever the state changes and +the swsetup module is 'awake': + + void _tnl_InvalidateState( GLcontext *ctx, GLuint new_state ); + +There is no explicit call to put the tnl module to sleep. Simply +install other function pointers into all the vtxfmt dispatch slots, +and (optionally) cease calling _tnl_InvalidateState(). + +CUSTOMIZATION + +The module provides customizability through several mechanisms. The +most important is by allowing drivers to specify the pipeline through +which vertex data is passed, including its eventual transfer to +rasterization hardware (or software). + +The default pipeline is specified in t_pipeline.c, and is usually a +starting point for driver pipelines. Some drivers will remove a stage +where hardware provides support for the implemented operation (for +instance fog where per-pixel hardware fog is available, as in the dri +tdfx driver), or add stages to shortcircuit latter operations (for +example taking advantage of hardware support for strips and other +higher-level primitives (for example the radeon driver). + +In addition, the following functions provide further tweaks: + +extern void +_tnl_need_projected_coords( GLcontext *ctx, GLboolean flag ); + + - Direct the default vertex transformation stage to + produce/not produce projected clip coordinates. + +extern void +_tnl_need_dlist_loopback( GLcontext *ctx, GLboolean flag ); + + - Direct the display list component of the tnl module to + replay display lists as 'glVertex' type calls, rather than + passing the display list data directly into the tnl pipeline + mechanism. + + This allows display lists to be replayed by the tnl module + even when the module is not strictly active. + + +extern void +_tnl_need_dlist_norm_lengths( GLcontext *ctx, GLboolean flag ); + + - Direct the display list component to enable/disable caching + 1/length values for display list normals. Doing so is + ususally helpful when lighting is performed in software, but + wasteful otherwise. + + +DRIVER INTERFACE + +The module itself offers a minimal driver interface: + + void (*RunPipeline)( GLcontext *ctx ); + +Normally this is set to _tnl_RunPipeline(), however the driver can use +this hook to wrap checks or other code around this call. + +In addition, the driver interface for the default render pipeline +stage is housed in the tnl context struct (this could be cleaner). + + +RENDER DRIVER INTERFACE + +See t_context.h for the definition and explanation of this. \ No newline at end of file -- cgit v1.2.3