From e9e7839133a2e7784f87a47b4f8bf7e97f595b51 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Mon, 28 Nov 2016 17:31:56 +0100 Subject: [PATCH] Create drawergen tool --- .gitignore | 2 + src/CMakeLists.txt | 118 +-- src/r_compiler/llvmdrawers.cpp | 866 ------------------ src/r_draw_rgba.cpp | 22 +- src/r_drawers.cpp | 423 +++++++++ src/{r_compiler/llvmdrawers.h => r_drawers.h} | 44 +- src/r_drawt_rgba.cpp | 6 +- src/r_poly_triangle.cpp | 2 +- src/r_poly_triangle.h | 2 +- src/r_swrenderer.cpp | 4 +- tools/CMakeLists.txt | 1 + tools/drawergen/CMakeLists.txt | 133 +++ tools/drawergen/drawergen.cpp | 664 ++++++++++++++ .../fixedfunction/drawcolumncodegen.cpp | 21 +- .../fixedfunction/drawcolumncodegen.h | 0 .../fixedfunction/drawercodegen.cpp | 21 +- .../drawergen}/fixedfunction/drawercodegen.h | 35 +- .../fixedfunction/drawskycodegen.cpp | 21 +- .../drawergen}/fixedfunction/drawskycodegen.h | 0 .../fixedfunction/drawspancodegen.cpp | 21 +- .../fixedfunction/drawspancodegen.h | 0 .../fixedfunction/drawtrianglecodegen.cpp | 21 +- .../fixedfunction/drawtrianglecodegen.h | 0 .../fixedfunction/drawwallcodegen.cpp | 21 +- .../fixedfunction/drawwallcodegen.h | 0 .../drawergen}/llvm_include.h | 0 tools/drawergen/precomp.h | 5 + .../drawergen}/ssa/ssa_barycentric_weight.h | 0 .../drawergen}/ssa/ssa_bool.cpp | 2 +- .../drawergen}/ssa/ssa_bool.h | 0 .../drawergen}/ssa/ssa_float.cpp | 2 +- .../drawergen}/ssa/ssa_float.h | 0 .../drawergen}/ssa/ssa_float_ptr.cpp | 2 +- .../drawergen}/ssa/ssa_float_ptr.h | 0 .../drawergen}/ssa/ssa_for_block.cpp | 2 +- .../drawergen}/ssa/ssa_for_block.h | 0 .../drawergen}/ssa/ssa_function.cpp | 2 +- .../drawergen}/ssa/ssa_function.h | 0 .../drawergen}/ssa/ssa_if_block.cpp | 2 +- .../drawergen}/ssa/ssa_if_block.h | 0 .../drawergen}/ssa/ssa_int.cpp | 2 +- .../drawergen}/ssa/ssa_int.h | 0 .../drawergen}/ssa/ssa_int_ptr.cpp | 2 +- .../drawergen}/ssa/ssa_int_ptr.h | 0 .../drawergen}/ssa/ssa_phi.h | 0 .../drawergen}/ssa/ssa_scope.cpp | 2 +- .../drawergen}/ssa/ssa_scope.h | 0 .../drawergen}/ssa/ssa_short.cpp | 2 +- .../drawergen}/ssa/ssa_short.h | 0 .../drawergen}/ssa/ssa_stack.h | 0 .../drawergen}/ssa/ssa_struct_type.cpp | 2 +- .../drawergen}/ssa/ssa_struct_type.h | 0 .../drawergen}/ssa/ssa_ubyte.cpp | 2 +- .../drawergen}/ssa/ssa_ubyte.h | 0 .../drawergen}/ssa/ssa_ubyte_ptr.cpp | 2 +- .../drawergen}/ssa/ssa_ubyte_ptr.h | 0 .../drawergen}/ssa/ssa_value.cpp | 2 +- .../drawergen}/ssa/ssa_value.h | 0 .../drawergen}/ssa/ssa_vec16ub.cpp | 2 +- .../drawergen}/ssa/ssa_vec16ub.h | 0 .../drawergen}/ssa/ssa_vec4f.cpp | 2 +- .../drawergen}/ssa/ssa_vec4f.h | 0 .../drawergen}/ssa/ssa_vec4f_ptr.cpp | 2 +- .../drawergen}/ssa/ssa_vec4f_ptr.h | 0 .../drawergen}/ssa/ssa_vec4i.cpp | 2 +- .../drawergen}/ssa/ssa_vec4i.h | 0 .../drawergen}/ssa/ssa_vec4i_ptr.cpp | 2 +- .../drawergen}/ssa/ssa_vec4i_ptr.h | 0 .../drawergen}/ssa/ssa_vec8s.cpp | 2 +- .../drawergen}/ssa/ssa_vec8s.h | 0 tools/drawergen/trustinfo.rc | 6 + tools/drawergen/trustinfo.txt | 16 + 72 files changed, 1407 insertions(+), 1108 deletions(-) delete mode 100644 src/r_compiler/llvmdrawers.cpp create mode 100644 src/r_drawers.cpp rename src/{r_compiler/llvmdrawers.h => r_drawers.h} (93%) create mode 100644 tools/drawergen/CMakeLists.txt create mode 100644 tools/drawergen/drawergen.cpp rename {src/r_compiler => tools/drawergen}/fixedfunction/drawcolumncodegen.cpp (96%) rename {src/r_compiler => tools/drawergen}/fixedfunction/drawcolumncodegen.h (100%) rename {src/r_compiler => tools/drawergen}/fixedfunction/drawercodegen.cpp (92%) rename {src/r_compiler => tools/drawergen}/fixedfunction/drawercodegen.h (81%) rename {src/r_compiler => tools/drawergen}/fixedfunction/drawskycodegen.cpp (91%) rename {src/r_compiler => tools/drawergen}/fixedfunction/drawskycodegen.h (100%) rename {src/r_compiler => tools/drawergen}/fixedfunction/drawspancodegen.cpp (94%) rename {src/r_compiler => tools/drawergen}/fixedfunction/drawspancodegen.h (100%) rename {src/r_compiler => tools/drawergen}/fixedfunction/drawtrianglecodegen.cpp (98%) rename {src/r_compiler => tools/drawergen}/fixedfunction/drawtrianglecodegen.h (100%) rename {src/r_compiler => tools/drawergen}/fixedfunction/drawwallcodegen.cpp (94%) rename {src/r_compiler => tools/drawergen}/fixedfunction/drawwallcodegen.h (100%) rename {src/r_compiler => tools/drawergen}/llvm_include.h (100%) create mode 100644 tools/drawergen/precomp.h rename {src/r_compiler => tools/drawergen}/ssa/ssa_barycentric_weight.h (100%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_bool.cpp (99%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_bool.h (100%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_float.cpp (99%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_float.h (100%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_float_ptr.cpp (99%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_float_ptr.h (100%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_for_block.cpp (98%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_for_block.h (100%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_function.cpp (98%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_function.h (100%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_if_block.cpp (98%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_if_block.h (100%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_int.cpp (99%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_int.h (100%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_int_ptr.cpp (99%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_int_ptr.h (100%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_phi.h (100%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_scope.cpp (98%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_scope.h (100%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_short.cpp (99%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_short.h (100%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_stack.h (100%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_struct_type.cpp (97%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_struct_type.h (100%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_ubyte.cpp (98%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_ubyte.h (100%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_ubyte_ptr.cpp (99%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_ubyte_ptr.h (100%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_value.cpp (98%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_value.h (100%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_vec16ub.cpp (99%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_vec16ub.h (100%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_vec4f.cpp (99%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_vec4f.h (100%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_vec4f_ptr.cpp (98%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_vec4f_ptr.h (100%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_vec4i.cpp (99%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_vec4i.h (100%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_vec4i_ptr.cpp (98%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_vec4i_ptr.h (100%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_vec8s.cpp (99%) rename {src/r_compiler => tools/drawergen}/ssa/ssa_vec8s.h (100%) create mode 100644 tools/drawergen/trustinfo.rc create mode 100644 tools/drawergen/trustinfo.txt diff --git a/.gitignore b/.gitignore index 7cc9d98607..a001e38de8 100644 --- a/.gitignore +++ b/.gitignore @@ -48,3 +48,5 @@ /build_vc2015-64 /build /llvm +/src/r_drawersasm.obj +/src/r_drawersasm.o diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d19951f9f1..458acf6ad9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -293,47 +293,6 @@ if( NOT NO_OPENAL ) endif() endif() - -# Path where it looks for the LLVM compiled files on Windows -set( LLVM_PRECOMPILED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../llvm" ) - -if( NOT WIN32 ) - set( LLVM_COMPONENTS core support asmparser asmprinter bitreader bitwriter codegen ipo - irreader transformutils instrumentation profiledata runtimedyld - object instcombine linker analysis selectiondag scalaropts vectorize executionengine - mc mcdisassembler mcparser mcjit target x86asmprinter x86info x86desc x86utils x86codegen ) - - # Example LLVM_DIR folder: C:/Development/Environment/Src/llvm-3.9.0/build/lib/cmake/llvm - find_package(LLVM REQUIRED CONFIG) - message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") - message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}") - llvm_map_components_to_libnames( llvm_libs ${LLVM_COMPONENTS} ) - include_directories( ${LLVM_INCLUDE_DIRS} ) - set( ZDOOM_LIBS ${ZDOOM_LIBS} ${llvm_libs} ) -else() - set( LLVM_COMPONENTS core support asmparser asmprinter bitreader bitwriter codegen passes ipo - irreader transformutils instrumentation profiledata debuginfocodeview runtimedyld - object instcombine linker analysis selectiondag scalaropts vectorize executionengine - mc mcdisassembler mcparser mcjit target x86asmprinter x86info x86desc x86utils x86codegen ) - - include_directories( "${LLVM_PRECOMPILED_DIR}/include" ) - if( X64 ) - include_directories( "${LLVM_PRECOMPILED_DIR}/64bit-include" ) - set( llvm_libs_base "${LLVM_PRECOMPILED_DIR}/64bit-" ) - else() - include_directories( "${LLVM_PRECOMPILED_DIR}/32bit-include" ) - set( llvm_libs_base "${LLVM_PRECOMPILED_DIR}/32bit-" ) - endif() - foreach(buildtype IN ITEMS RELEASE DEBUG) - set( llvm_libs_${buildtype} "${llvm_libs_base}${buildtype}" ) - set( LLVM_${buildtype}_LIBS "" ) - foreach( llvm_module ${LLVM_COMPONENTS} ) - find_library( LLVM_${llvm_module}_LIBRARY_${buildtype} LLVM${llvm_module} PATHS ${llvm_libs_${buildtype}} ) - set( LLVM_${buildtype}_LIBS ${LLVM_${buildtype}_LIBS} ${LLVM_${llvm_module}_LIBRARY_${buildtype}} ) - endforeach( llvm_module ) - endforeach(buildtype) -endif() - if( NOT NO_FMOD ) # Search for FMOD include files if( NOT WIN32 ) @@ -644,11 +603,6 @@ if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE ) set( CMAKE_EXE_LINKER_FLAGS "-stdlib=libc++ ${CMAKE_EXE_LINKER_FLAGS}" ) endif () - # Linux - add these flags for LLVM compatibility to prevent crashing - if ( UNIX AND NOT APPLE ) - set( CMAKE_EXE_LINKER_FLAGS "-Wl,--exclude-libs,ALL ${CMAKE_EXE_LINKER_FLAGS}" ) - endif() - # Remove extra warnings when using the official DirectX headers. # Also, TDM-GCC 4.4.0 no longer accepts glibc-style printf formats as valid, # which is a royal pain. The previous version I had been using was fine with them. @@ -719,6 +673,20 @@ add_custom_target( revision_check ALL WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} DEPENDS updaterevision ) +# Run drawer codegen tool + +if ( WIN32 ) + add_custom_target( drawergen_target ALL + COMMAND drawergen src/r_drawersasm.obj + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + DEPENDS drawergen ) +else() + add_custom_target( drawergen_target ALL + COMMAND drawergen src/r_drawersasm.o + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + DEPENDS drawergen ) +endif() + # Libraries ZDoom needs message( STATUS "Fluid synth libs: ${FLUIDSYNTH_LIBRARIES}" ) @@ -933,9 +901,6 @@ file( GLOB HEADER_FILES posix/*.h posix/cocoa/*.h posix/sdl/*.h - r_compiler/*.h - r_compiler/ssa/*.h - r_compiler/fixedfunction/*.h r_data/*.h resourcefiles/*.h sfmt/*.h @@ -1083,6 +1048,7 @@ set( FASTMATH_PCH_SOURCES r_draw_rgba.cpp r_drawt.cpp r_drawt_rgba.cpp + r_drawers.cpp r_thread.cpp r_main.cpp r_plane.cpp @@ -1485,33 +1451,6 @@ set (PCH_SOURCES fragglescript/t_spec.cpp fragglescript/t_variable.cpp fragglescript/t_cmd.cpp - r_compiler/llvmdrawers.cpp - r_compiler/ssa/ssa_bool.cpp - r_compiler/ssa/ssa_float.cpp - r_compiler/ssa/ssa_float_ptr.cpp - r_compiler/ssa/ssa_for_block.cpp - r_compiler/ssa/ssa_function.cpp - r_compiler/ssa/ssa_if_block.cpp - r_compiler/ssa/ssa_int.cpp - r_compiler/ssa/ssa_int_ptr.cpp - r_compiler/ssa/ssa_short.cpp - r_compiler/ssa/ssa_scope.cpp - r_compiler/ssa/ssa_struct_type.cpp - r_compiler/ssa/ssa_ubyte.cpp - r_compiler/ssa/ssa_ubyte_ptr.cpp - r_compiler/ssa/ssa_value.cpp - r_compiler/ssa/ssa_vec4f.cpp - r_compiler/ssa/ssa_vec4f_ptr.cpp - r_compiler/ssa/ssa_vec4i.cpp - r_compiler/ssa/ssa_vec4i_ptr.cpp - r_compiler/ssa/ssa_vec8s.cpp - r_compiler/ssa/ssa_vec16ub.cpp - r_compiler/fixedfunction/drawercodegen.cpp - r_compiler/fixedfunction/drawspancodegen.cpp - r_compiler/fixedfunction/drawwallcodegen.cpp - r_compiler/fixedfunction/drawcolumncodegen.cpp - r_compiler/fixedfunction/drawskycodegen.cpp - r_compiler/fixedfunction/drawtrianglecodegen.cpp r_data/sprites.cpp r_data/voxels.cpp r_data/renderstyle.cpp @@ -1528,6 +1467,16 @@ set (PCH_SOURCES ) enable_precompiled_headers( g_pch.h PCH_SOURCES ) +if ( WIN32 ) + set (CODEGENOBJ_SOURCES + r_drawersasm.obj + ) +else() + set (CODEGENOBJ_SOURCES + r_drawersasm.o + ) +endif() + add_executable( zdoom WIN32 MACOSX_BUNDLE ${HEADER_FILES} ${NOT_COMPILED_SOURCE_FILES} @@ -1557,8 +1506,11 @@ add_executable( zdoom WIN32 MACOSX_BUNDLE math/tanh.c math/fastsin.cpp zzautozend.cpp + r_drawersasm.obj ) +set_source_files_properties( ${CODEGENOBJ_SOURCES} PROPERTIES EXTERNAL_OBJECT true GENERATED true) + set_source_files_properties( ${FASTMATH_SOURCES} PROPERTIES COMPILE_FLAGS ${ZD_FASTMATH_FLAG} ) set_source_files_properties( xlat/parse_xlat.cpp PROPERTIES OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/xlat_parser.c" ) set_source_files_properties( sc_man.cpp PROPERTIES OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/sc_man_scanner.h" ) @@ -1579,15 +1531,6 @@ endif() target_link_libraries( zdoom ${ZDOOM_LIBS} gdtoa dumb lzma ) -if( WIN32 ) - foreach(debuglib ${LLVM_DEBUG_LIBS}) - target_link_libraries( zdoom debug ${debuglib} ) - endforeach(debuglib) - foreach(releaselib ${LLVM_RELEASE_LIBS}) - target_link_libraries( zdoom optimized ${releaselib} ) - endforeach(releaselib) -endif() - include_directories( . g_doom g_heretic @@ -1608,7 +1551,7 @@ include_directories( . ${CMAKE_BINARY_DIR}/gdtoa ${SYSTEM_SOURCES_DIR} ) -add_dependencies( zdoom revision_check ) +add_dependencies( zdoom revision_check drawergen_target ) # Due to some quirks, we need to do this in this order if( NOT ZDOOM_OUTPUT_OLDSTYLE ) @@ -1750,9 +1693,6 @@ source_group("Render Data\\Resource Headers" REGULAR_EXPRESSION "^${CMAKE_CURREN source_group("Render Data\\Resource Sources" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/r_data/.+\\.cpp$") source_group("Render Data\\Textures" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/textures/.+") source_group("Render Interface" FILES r_defs.h r_renderer.h r_sky.cpp r_sky.h r_state.h r_utility.cpp r_utility.h) -source_group("Render Compiler" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/r_compiler/.+") -source_group("Render Compiler\\SSA" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/r_compiler/ssa/.+") -source_group("Render Compiler\\Fixed Function" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/r_compiler/fixedfunction/.+") source_group("Resource Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/resourcefiles/.+") source_group("POSIX Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/posix/.+") source_group("Cocoa Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/posix/cocoa/.+") diff --git a/src/r_compiler/llvmdrawers.cpp b/src/r_compiler/llvmdrawers.cpp deleted file mode 100644 index babb7c6e70..0000000000 --- a/src/r_compiler/llvmdrawers.cpp +++ /dev/null @@ -1,866 +0,0 @@ -/* -** LLVM code generated drawers -** Copyright (c) 2016 Magnus Norddahl -** -** This software is provided 'as-is', without any express or implied -** warranty. In no event will the authors be held liable for any damages -** arising from the use of this software. -** -** Permission is granted to anyone to use this software for any purpose, -** including commercial applications, and to alter it and redistribute it -** freely, subject to the following restrictions: -** -** 1. The origin of this software must not be misrepresented; you must not -** claim that you wrote the original software. If you use this software -** in a product, an acknowledgment in the product documentation would be -** appreciated but is not required. -** 2. Altered source versions must be plainly marked as such, and must not be -** misrepresented as being the original software. -** 3. This notice may not be removed or altered from any source distribution. -** -*/ - -#include "i_system.h" -#include "r_compiler/llvm_include.h" -#include "r_compiler/fixedfunction/drawspancodegen.h" -#include "r_compiler/fixedfunction/drawwallcodegen.h" -#include "r_compiler/fixedfunction/drawcolumncodegen.h" -#include "r_compiler/fixedfunction/drawskycodegen.h" -#include "r_compiler/fixedfunction/drawtrianglecodegen.h" -#include "r_compiler/ssa/ssa_function.h" -#include "r_compiler/ssa/ssa_scope.h" -#include "r_compiler/ssa/ssa_for_block.h" -#include "r_compiler/ssa/ssa_if_block.h" -#include "r_compiler/ssa/ssa_stack.h" -#include "r_compiler/ssa/ssa_function.h" -#include "r_compiler/ssa/ssa_struct_type.h" -#include "r_compiler/ssa/ssa_value.h" -#include "r_compiler/ssa/ssa_barycentric_weight.h" -#include "x86.h" -#include "c_cvars.h" -#include "version.h" -#include "m_misc.h" - -CUSTOM_CVAR(String, llvm_cpu, "auto", CVAR_ARCHIVE | CVAR_NOINITCALL) -{ - Printf("You must restart " GAMENAME " for this change to take effect.\n"); -} - -class LLVMProgram -{ -public: - LLVMProgram(); - - void CreateModule(); - std::string GetTargetCPU(); - bool LoadCachedModule(int version, std::string targetCPU); - void CreateEE(int version, std::string targetCPU, bool optimize); - std::string GenerateAssembly(std::string cpuName); - std::string DumpModule(); - void StopLogFatalErrors(); - - template - Func *GetProcAddress(const std::string &name) { return reinterpret_cast(PointerToFunction(name.c_str())); } - - llvm::LLVMContext &context() { return *mContext; } - llvm::Module *module() { return mModule.get(); } - llvm::ExecutionEngine *engine() { return mEngine.get(); } - -private: - void SaveCachedModule(llvm::Module *module, int version, std::string targetCPU); - FString GetDrawerCacheFilename(int version, FString cpu); - void *PointerToFunction(const char *name); - - llvm::TargetMachine *machine = nullptr; - std::unique_ptr mContext; - std::unique_ptr mModule; - std::unique_ptr mEngine; -}; - -class LLVMDrawersImpl : public LLVMDrawers -{ -public: - LLVMDrawersImpl(); - -private: - void CodegenDrawColumn(const char *name, DrawColumnVariant variant, DrawColumnMethod method); - void CodegenDrawSpan(const char *name, DrawSpanVariant variant); - void CodegenDrawWall(const char *name, DrawWallVariant variant, int columns); - void CodegenDrawSky(const char *name, DrawSkyVariant variant, int columns); - void CodegenDrawTriangle(const std::string &name, TriDrawVariant variant, TriBlendMode blendmode, bool truecolor); - - static llvm::Type *GetDrawColumnArgsStruct(llvm::LLVMContext &context); - static llvm::Type *GetDrawSpanArgsStruct(llvm::LLVMContext &context); - static llvm::Type *GetDrawWallArgsStruct(llvm::LLVMContext &context); - static llvm::Type *GetDrawSkyArgsStruct(llvm::LLVMContext &context); - static llvm::Type *GetWorkerThreadDataStruct(llvm::LLVMContext &context); - static llvm::Type *GetTriVertexStruct(llvm::LLVMContext &context); - static llvm::Type *GetTriMatrixStruct(llvm::LLVMContext &context); - static llvm::Type *GetTriUniformsStruct(llvm::LLVMContext &context); - static llvm::Type *GetTriDrawTriangleArgs(llvm::LLVMContext &context); - - LLVMProgram mProgram; -}; - -///////////////////////////////////////////////////////////////////////////// - -LLVMDrawers *LLVMDrawers::Singleton = nullptr; - -void LLVMDrawers::Create() -{ - if (!Singleton) - Singleton = new LLVMDrawersImpl(); -} - -void LLVMDrawers::Destroy() -{ - delete Singleton; - Singleton = nullptr; -} - -LLVMDrawers *LLVMDrawers::Instance() -{ - return Singleton; -} - -///////////////////////////////////////////////////////////////////////////// - -LLVMDrawersImpl::LLVMDrawersImpl() -{ - int version = 8; // Increment this number if the drawer codegen is modified (forces recreation of the module). - std::string targetCPU = mProgram.GetTargetCPU(); - bool loaded = mProgram.LoadCachedModule(version, targetCPU); - if (!loaded) - { - mProgram.CreateModule(); - - CodegenDrawColumn("FillColumn", DrawColumnVariant::Fill, DrawColumnMethod::Normal); - CodegenDrawColumn("FillColumnAdd", DrawColumnVariant::FillAdd, DrawColumnMethod::Normal); - CodegenDrawColumn("FillColumnAddClamp", DrawColumnVariant::FillAddClamp, DrawColumnMethod::Normal); - CodegenDrawColumn("FillColumnSubClamp", DrawColumnVariant::FillSubClamp, DrawColumnMethod::Normal); - CodegenDrawColumn("FillColumnRevSubClamp", DrawColumnVariant::FillRevSubClamp, DrawColumnMethod::Normal); - CodegenDrawColumn("DrawColumn", DrawColumnVariant::Draw, DrawColumnMethod::Normal); - CodegenDrawColumn("DrawColumnAdd", DrawColumnVariant::DrawAdd, DrawColumnMethod::Normal); - CodegenDrawColumn("DrawColumnShaded", DrawColumnVariant::DrawShaded, DrawColumnMethod::Normal); - CodegenDrawColumn("DrawColumnAddClamp", DrawColumnVariant::DrawAddClamp, DrawColumnMethod::Normal); - CodegenDrawColumn("DrawColumnSubClamp", DrawColumnVariant::DrawSubClamp, DrawColumnMethod::Normal); - CodegenDrawColumn("DrawColumnRevSubClamp", DrawColumnVariant::DrawRevSubClamp, DrawColumnMethod::Normal); - CodegenDrawColumn("DrawColumnTranslated", DrawColumnVariant::DrawTranslated, DrawColumnMethod::Normal); - CodegenDrawColumn("DrawColumnTlatedAdd", DrawColumnVariant::DrawTlatedAdd, DrawColumnMethod::Normal); - CodegenDrawColumn("DrawColumnAddClampTranslated", DrawColumnVariant::DrawAddClampTranslated, DrawColumnMethod::Normal); - CodegenDrawColumn("DrawColumnSubClampTranslated", DrawColumnVariant::DrawSubClampTranslated, DrawColumnMethod::Normal); - CodegenDrawColumn("DrawColumnRevSubClampTranslated", DrawColumnVariant::DrawRevSubClampTranslated, DrawColumnMethod::Normal); - CodegenDrawColumn("DrawColumnRt1", DrawColumnVariant::Draw, DrawColumnMethod::Rt1); - CodegenDrawColumn("DrawColumnRt1Copy", DrawColumnVariant::DrawCopy, DrawColumnMethod::Rt1); - CodegenDrawColumn("DrawColumnRt1Add", DrawColumnVariant::DrawAdd, DrawColumnMethod::Rt1); - CodegenDrawColumn("DrawColumnRt1Shaded", DrawColumnVariant::DrawShaded, DrawColumnMethod::Rt1); - CodegenDrawColumn("DrawColumnRt1AddClamp", DrawColumnVariant::DrawAddClamp, DrawColumnMethod::Rt1); - CodegenDrawColumn("DrawColumnRt1SubClamp", DrawColumnVariant::DrawSubClamp, DrawColumnMethod::Rt1); - CodegenDrawColumn("DrawColumnRt1RevSubClamp", DrawColumnVariant::DrawRevSubClamp, DrawColumnMethod::Rt1); - CodegenDrawColumn("DrawColumnRt1Translated", DrawColumnVariant::DrawTranslated, DrawColumnMethod::Rt1); - CodegenDrawColumn("DrawColumnRt1TlatedAdd", DrawColumnVariant::DrawTlatedAdd, DrawColumnMethod::Rt1); - CodegenDrawColumn("DrawColumnRt1AddClampTranslated", DrawColumnVariant::DrawAddClampTranslated, DrawColumnMethod::Rt1); - CodegenDrawColumn("DrawColumnRt1SubClampTranslated", DrawColumnVariant::DrawSubClampTranslated, DrawColumnMethod::Rt1); - CodegenDrawColumn("DrawColumnRt1RevSubClampTranslated", DrawColumnVariant::DrawRevSubClampTranslated, DrawColumnMethod::Rt1); - CodegenDrawColumn("DrawColumnRt4", DrawColumnVariant::Draw, DrawColumnMethod::Rt4); - CodegenDrawColumn("DrawColumnRt4Copy", DrawColumnVariant::DrawCopy, DrawColumnMethod::Rt4); - CodegenDrawColumn("DrawColumnRt4Add", DrawColumnVariant::DrawAdd, DrawColumnMethod::Rt4); - CodegenDrawColumn("DrawColumnRt4Shaded", DrawColumnVariant::DrawShaded, DrawColumnMethod::Rt4); - CodegenDrawColumn("DrawColumnRt4AddClamp", DrawColumnVariant::DrawAddClamp, DrawColumnMethod::Rt4); - CodegenDrawColumn("DrawColumnRt4SubClamp", DrawColumnVariant::DrawSubClamp, DrawColumnMethod::Rt4); - CodegenDrawColumn("DrawColumnRt4RevSubClamp", DrawColumnVariant::DrawRevSubClamp, DrawColumnMethod::Rt4); - CodegenDrawColumn("DrawColumnRt4Translated", DrawColumnVariant::DrawTranslated, DrawColumnMethod::Rt4); - CodegenDrawColumn("DrawColumnRt4TlatedAdd", DrawColumnVariant::DrawTlatedAdd, DrawColumnMethod::Rt4); - CodegenDrawColumn("DrawColumnRt4AddClampTranslated", DrawColumnVariant::DrawAddClampTranslated, DrawColumnMethod::Rt4); - CodegenDrawColumn("DrawColumnRt4SubClampTranslated", DrawColumnVariant::DrawSubClampTranslated, DrawColumnMethod::Rt4); - CodegenDrawColumn("DrawColumnRt4RevSubClampTranslated", DrawColumnVariant::DrawRevSubClampTranslated, DrawColumnMethod::Rt4); - CodegenDrawSpan("DrawSpan", DrawSpanVariant::Opaque); - CodegenDrawSpan("DrawSpanMasked", DrawSpanVariant::Masked); - CodegenDrawSpan("DrawSpanTranslucent", DrawSpanVariant::Translucent); - CodegenDrawSpan("DrawSpanMaskedTranslucent", DrawSpanVariant::MaskedTranslucent); - CodegenDrawSpan("DrawSpanAddClamp", DrawSpanVariant::AddClamp); - CodegenDrawSpan("DrawSpanMaskedAddClamp", DrawSpanVariant::MaskedAddClamp); - CodegenDrawWall("vlinec1", DrawWallVariant::Opaque, 1); - CodegenDrawWall("vlinec4", DrawWallVariant::Opaque, 4); - CodegenDrawWall("mvlinec1", DrawWallVariant::Masked, 1); - CodegenDrawWall("mvlinec4", DrawWallVariant::Masked, 4); - CodegenDrawWall("tmvline1_add", DrawWallVariant::Add, 1); - CodegenDrawWall("tmvline4_add", DrawWallVariant::Add, 4); - CodegenDrawWall("tmvline1_addclamp", DrawWallVariant::AddClamp, 1); - CodegenDrawWall("tmvline4_addclamp", DrawWallVariant::AddClamp, 4); - CodegenDrawWall("tmvline1_subclamp", DrawWallVariant::SubClamp, 1); - CodegenDrawWall("tmvline4_subclamp", DrawWallVariant::SubClamp, 4); - CodegenDrawWall("tmvline1_revsubclamp", DrawWallVariant::RevSubClamp, 1); - CodegenDrawWall("tmvline4_revsubclamp", DrawWallVariant::RevSubClamp, 4); - CodegenDrawSky("DrawSky1", DrawSkyVariant::Single, 1); - CodegenDrawSky("DrawSky4", DrawSkyVariant::Single, 4); - CodegenDrawSky("DrawDoubleSky1", DrawSkyVariant::Double, 1); - CodegenDrawSky("DrawDoubleSky4", DrawSkyVariant::Double, 4); - for (int i = 0; i < NumTriBlendModes(); i++) - { - CodegenDrawTriangle("TriDraw8_" + std::to_string(i), TriDrawVariant::DrawNormal, (TriBlendMode)i, false); - CodegenDrawTriangle("TriDraw32_" + std::to_string(i), TriDrawVariant::DrawNormal, (TriBlendMode)i, true); - CodegenDrawTriangle("TriFill8_" + std::to_string(i), TriDrawVariant::FillNormal, (TriBlendMode)i, false); - CodegenDrawTriangle("TriFill32_" + std::to_string(i), TriDrawVariant::FillNormal, (TriBlendMode)i, true); - CodegenDrawTriangle("TriDrawSubsector8_" + std::to_string(i), TriDrawVariant::DrawSubsector, (TriBlendMode)i, false); - CodegenDrawTriangle("TriDrawSubsector32_" + std::to_string(i), TriDrawVariant::DrawSubsector, (TriBlendMode)i, true); - CodegenDrawTriangle("TriFillSubsector8_" + std::to_string(i), TriDrawVariant::FillSubsector, (TriBlendMode)i, false); - CodegenDrawTriangle("TriFillSubsector32_" + std::to_string(i), TriDrawVariant::FillSubsector, (TriBlendMode)i, true); - } - CodegenDrawTriangle("TriStencil", TriDrawVariant::Stencil, TriBlendMode::Copy, false); - CodegenDrawTriangle("TriStencilClose", TriDrawVariant::StencilClose, TriBlendMode::Copy, false); - } - - mProgram.CreateEE(version, targetCPU, !loaded); - - FillColumn = mProgram.GetProcAddress("FillColumn"); - FillColumnAdd = mProgram.GetProcAddress("FillColumnAdd"); - FillColumnAddClamp = mProgram.GetProcAddress("FillColumnAddClamp"); - FillColumnSubClamp = mProgram.GetProcAddress("FillColumnSubClamp"); - FillColumnRevSubClamp = mProgram.GetProcAddress("FillColumnRevSubClamp"); - DrawColumn = mProgram.GetProcAddress("DrawColumn"); - DrawColumnAdd = mProgram.GetProcAddress("DrawColumnAdd"); - DrawColumnShaded = mProgram.GetProcAddress("DrawColumnShaded"); - DrawColumnAddClamp = mProgram.GetProcAddress("DrawColumnAddClamp"); - DrawColumnSubClamp = mProgram.GetProcAddress("DrawColumnSubClamp"); - DrawColumnRevSubClamp = mProgram.GetProcAddress("DrawColumnRevSubClamp"); - DrawColumnTranslated = mProgram.GetProcAddress("DrawColumnTranslated"); - DrawColumnTlatedAdd = mProgram.GetProcAddress("DrawColumnTlatedAdd"); - DrawColumnAddClampTranslated = mProgram.GetProcAddress("DrawColumnAddClampTranslated"); - DrawColumnSubClampTranslated = mProgram.GetProcAddress("DrawColumnSubClampTranslated"); - DrawColumnRevSubClampTranslated = mProgram.GetProcAddress("DrawColumnRevSubClampTranslated"); - DrawColumnRt1 = mProgram.GetProcAddress("DrawColumnRt1"); - DrawColumnRt1Copy = mProgram.GetProcAddress("DrawColumnRt1Copy"); - DrawColumnRt1Add = mProgram.GetProcAddress("DrawColumnRt1Add"); - DrawColumnRt1Shaded = mProgram.GetProcAddress("DrawColumnRt1Shaded"); - DrawColumnRt1AddClamp = mProgram.GetProcAddress("DrawColumnRt1AddClamp"); - DrawColumnRt1SubClamp = mProgram.GetProcAddress("DrawColumnRt1SubClamp"); - DrawColumnRt1RevSubClamp = mProgram.GetProcAddress("DrawColumnRt1RevSubClamp"); - DrawColumnRt1Translated = mProgram.GetProcAddress("DrawColumnRt1Translated"); - DrawColumnRt1TlatedAdd = mProgram.GetProcAddress("DrawColumnRt1TlatedAdd"); - DrawColumnRt1AddClampTranslated = mProgram.GetProcAddress("DrawColumnRt1AddClampTranslated"); - DrawColumnRt1SubClampTranslated = mProgram.GetProcAddress("DrawColumnRt1SubClampTranslated"); - DrawColumnRt1RevSubClampTranslated = mProgram.GetProcAddress("DrawColumnRt1RevSubClampTranslated"); - DrawColumnRt4 = mProgram.GetProcAddress("DrawColumnRt4"); - DrawColumnRt4Copy = mProgram.GetProcAddress("DrawColumnRt4Copy"); - DrawColumnRt4Add = mProgram.GetProcAddress("DrawColumnRt4Add"); - DrawColumnRt4Shaded = mProgram.GetProcAddress("DrawColumnRt4Shaded"); - DrawColumnRt4AddClamp = mProgram.GetProcAddress("DrawColumnRt4AddClamp"); - DrawColumnRt4SubClamp = mProgram.GetProcAddress("DrawColumnRt4SubClamp"); - DrawColumnRt4RevSubClamp = mProgram.GetProcAddress("DrawColumnRt4RevSubClamp"); - DrawColumnRt4Translated = mProgram.GetProcAddress("DrawColumnRt4Translated"); - DrawColumnRt4TlatedAdd = mProgram.GetProcAddress("DrawColumnRt4TlatedAdd"); - DrawColumnRt4AddClampTranslated = mProgram.GetProcAddress("DrawColumnRt4AddClampTranslated"); - DrawColumnRt4SubClampTranslated = mProgram.GetProcAddress("DrawColumnRt4SubClampTranslated"); - DrawColumnRt4RevSubClampTranslated = mProgram.GetProcAddress("DrawColumnRt4RevSubClampTranslated"); - DrawSpan = mProgram.GetProcAddress("DrawSpan"); - DrawSpanMasked = mProgram.GetProcAddress("DrawSpanMasked"); - DrawSpanTranslucent = mProgram.GetProcAddress("DrawSpanTranslucent"); - DrawSpanMaskedTranslucent = mProgram.GetProcAddress("DrawSpanMaskedTranslucent"); - DrawSpanAddClamp = mProgram.GetProcAddress("DrawSpanAddClamp"); - DrawSpanMaskedAddClamp = mProgram.GetProcAddress("DrawSpanMaskedAddClamp"); - vlinec1 = mProgram.GetProcAddress("vlinec1"); - vlinec4 = mProgram.GetProcAddress("vlinec4"); - mvlinec1 = mProgram.GetProcAddress("mvlinec1"); - mvlinec4 = mProgram.GetProcAddress("mvlinec4"); - tmvline1_add = mProgram.GetProcAddress("tmvline1_add"); - tmvline4_add = mProgram.GetProcAddress("tmvline4_add"); - tmvline1_addclamp = mProgram.GetProcAddress("tmvline1_addclamp"); - tmvline4_addclamp = mProgram.GetProcAddress("tmvline4_addclamp"); - tmvline1_subclamp = mProgram.GetProcAddress("tmvline1_subclamp"); - tmvline4_subclamp = mProgram.GetProcAddress("tmvline4_subclamp"); - tmvline1_revsubclamp = mProgram.GetProcAddress("tmvline1_revsubclamp"); - tmvline4_revsubclamp = mProgram.GetProcAddress("tmvline4_revsubclamp"); - DrawSky1 = mProgram.GetProcAddress("DrawSky1"); - DrawSky4 = mProgram.GetProcAddress("DrawSky4"); - DrawDoubleSky1 = mProgram.GetProcAddress("DrawDoubleSky1"); - DrawDoubleSky4 = mProgram.GetProcAddress("DrawDoubleSky4"); - for (int i = 0; i < NumTriBlendModes(); i++) - { - TriDrawNormal8.push_back(mProgram.GetProcAddress("TriDraw8_" + std::to_string(i))); - TriDrawNormal32.push_back(mProgram.GetProcAddress("TriDraw32_" + std::to_string(i))); - TriFillNormal8.push_back(mProgram.GetProcAddress("TriFill8_" + std::to_string(i))); - TriFillNormal32.push_back(mProgram.GetProcAddress("TriFill32_" + std::to_string(i))); - TriDrawSubsector8.push_back(mProgram.GetProcAddress("TriDrawSubsector8_" + std::to_string(i))); - TriDrawSubsector32.push_back(mProgram.GetProcAddress("TriDrawSubsector32_" + std::to_string(i))); - TriFillSubsector8.push_back(mProgram.GetProcAddress("TriFillSubsector8_" + std::to_string(i))); - TriFillSubsector32.push_back(mProgram.GetProcAddress("TriFillSubsector32_" + std::to_string(i))); - } - TriStencil = mProgram.GetProcAddress("TriStencil"); - TriStencilClose = mProgram.GetProcAddress("TriStencilClose"); - -#if 0 - std::vector foo(1024 * 4); - std::vector boo(256 * 256 * 4); - DrawColumnArgs args = { 0 }; - WorkerThreadData thread = { 0 }; - thread.core = 0; - thread.num_cores = 1; - thread.pass_start_y = 0; - thread.pass_end_y = 3600; - thread.temp = foo.data(); - foo[125 * 4] = 1234; - foo[126 * 4] = 1234; - for (int i = 0; i < 16; i++) - boo[i] = i; - args.dest = boo.data() + 4; - args.dest_y = 125; - args.pitch = 256; - args.count = 1; - args.texturefrac = 0; - args.flags = 0; - args.iscale = 252769; - args.light = 256; - args.color = 4279179008; - args.srcalpha = 12; - args.destalpha = 256; - args.light_red = 192; - args.light_green = 256; - args.light_blue = 128; - DrawColumnRt4AddClamp(&args, &thread); -#endif - - mProgram.StopLogFatalErrors(); -} - -void LLVMDrawersImpl::CodegenDrawColumn(const char *name, DrawColumnVariant variant, DrawColumnMethod method) -{ - llvm::IRBuilder<> builder(mProgram.context()); - SSAScope ssa_scope(&mProgram.context(), mProgram.module(), &builder); - - SSAFunction function(name); - function.add_parameter(GetDrawColumnArgsStruct(mProgram.context())); - function.add_parameter(GetWorkerThreadDataStruct(mProgram.context())); - function.create_public(); - - DrawColumnCodegen codegen; - codegen.Generate(variant, method, function.parameter(0), function.parameter(1)); - - builder.CreateRetVoid(); - - if (llvm::verifyFunction(*function.func)) - I_FatalError("verifyFunction failed for CodegenDrawColumn()"); -} - -void LLVMDrawersImpl::CodegenDrawSpan(const char *name, DrawSpanVariant variant) -{ - llvm::IRBuilder<> builder(mProgram.context()); - SSAScope ssa_scope(&mProgram.context(), mProgram.module(), &builder); - - SSAFunction function(name); - function.add_parameter(GetDrawSpanArgsStruct(mProgram.context())); - function.create_public(); - - DrawSpanCodegen codegen; - codegen.Generate(variant, function.parameter(0)); - - builder.CreateRetVoid(); - - if (llvm::verifyFunction(*function.func)) - I_FatalError("verifyFunction failed for CodegenDrawSpan()"); -} - -void LLVMDrawersImpl::CodegenDrawWall(const char *name, DrawWallVariant variant, int columns) -{ - llvm::IRBuilder<> builder(mProgram.context()); - SSAScope ssa_scope(&mProgram.context(), mProgram.module(), &builder); - - SSAFunction function(name); - function.add_parameter(GetDrawWallArgsStruct(mProgram.context())); - function.add_parameter(GetWorkerThreadDataStruct(mProgram.context())); - function.create_public(); - - DrawWallCodegen codegen; - codegen.Generate(variant, columns == 4, function.parameter(0), function.parameter(1)); - - builder.CreateRetVoid(); - - if (llvm::verifyFunction(*function.func)) - I_FatalError("verifyFunction failed for CodegenDrawWall()"); -} - -void LLVMDrawersImpl::CodegenDrawSky(const char *name, DrawSkyVariant variant, int columns) -{ - llvm::IRBuilder<> builder(mProgram.context()); - SSAScope ssa_scope(&mProgram.context(), mProgram.module(), &builder); - - SSAFunction function(name); - function.add_parameter(GetDrawSkyArgsStruct(mProgram.context())); - function.add_parameter(GetWorkerThreadDataStruct(mProgram.context())); - function.create_public(); - - DrawSkyCodegen codegen; - codegen.Generate(variant, columns == 4, function.parameter(0), function.parameter(1)); - - builder.CreateRetVoid(); - - if (llvm::verifyFunction(*function.func)) - I_FatalError("verifyFunction failed for CodegenDrawSky()"); -} - -void LLVMDrawersImpl::CodegenDrawTriangle(const std::string &name, TriDrawVariant variant, TriBlendMode blendmode, bool truecolor) -{ - llvm::IRBuilder<> builder(mProgram.context()); - SSAScope ssa_scope(&mProgram.context(), mProgram.module(), &builder); - - SSAFunction function(name); - function.add_parameter(GetTriDrawTriangleArgs(mProgram.context())); - function.add_parameter(GetWorkerThreadDataStruct(mProgram.context())); - function.create_public(); - - DrawTriangleCodegen codegen; - codegen.Generate(variant, blendmode, truecolor, function.parameter(0), function.parameter(1)); - - builder.CreateRetVoid(); - - if (llvm::verifyFunction(*function.func)) - I_FatalError("verifyFunction failed for CodegenDrawTriangle(%d, %d, %d)", (int)variant, (int)blendmode, (int)truecolor); -} - -llvm::Type *LLVMDrawersImpl::GetDrawColumnArgsStruct(llvm::LLVMContext &context) -{ - std::vector elements; - elements.push_back(llvm::Type::getInt8PtrTy(context)); // uint32_t *dest; - elements.push_back(llvm::Type::getInt8PtrTy(context)); // const uint32_t *source; - elements.push_back(llvm::Type::getInt8PtrTy(context)); // const uint32_t *source2; - elements.push_back(llvm::Type::getInt8PtrTy(context)); // uint8_t *colormap; - elements.push_back(llvm::Type::getInt8PtrTy(context)); // uint8_t *translation; - elements.push_back(llvm::Type::getInt8PtrTy(context)); // const uint32_t *basecolors; - elements.push_back(llvm::Type::getInt32Ty(context)); // int32_t pitch; - elements.push_back(llvm::Type::getInt32Ty(context)); // int32_t count; - elements.push_back(llvm::Type::getInt32Ty(context)); // int32_t dest_y; - elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t iscale; - elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t texturefracx; - elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t textureheight; - elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t texturefrac; - elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t light; - elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t color; - elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t srccolor; - elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t srcalpha; - elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t destalpha; - elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_alpha; - elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_red; - elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_green; - elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_blue; - elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t fade_alpha; - elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t fade_red; - elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t fade_green; - elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t fade_blue; - elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t desaturate; - elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t flags; - return llvm::StructType::create(context, elements, "DrawColumnArgs", false)->getPointerTo(); -} - -llvm::Type *LLVMDrawersImpl::GetDrawSpanArgsStruct(llvm::LLVMContext &context) -{ - std::vector elements; - elements.push_back(llvm::Type::getInt8PtrTy(context)); // uint8_t *destorg; - elements.push_back(llvm::Type::getInt8PtrTy(context)); // const uint32_t *source; - elements.push_back(llvm::Type::getInt32Ty(context)); // int32_t destpitch; - elements.push_back(llvm::Type::getInt32Ty(context)); // int32_t xfrac; - elements.push_back(llvm::Type::getInt32Ty(context)); // int32_t yfrac; - elements.push_back(llvm::Type::getInt32Ty(context)); // int32_t xstep; - elements.push_back(llvm::Type::getInt32Ty(context)); // int32_t ystep; - elements.push_back(llvm::Type::getInt32Ty(context)); // int32_t x1; - elements.push_back(llvm::Type::getInt32Ty(context)); // int32_t x2; - elements.push_back(llvm::Type::getInt32Ty(context)); // int32_t y; - elements.push_back(llvm::Type::getInt32Ty(context)); // int32_t xbits; - elements.push_back(llvm::Type::getInt32Ty(context)); // int32_t ybits; - elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t light; - elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t srcalpha; - elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t destalpha; - elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_alpha; - elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_red; - elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_green; - elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_blue; - elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t fade_alpha; - elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t fade_red; - elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t fade_green; - elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t fade_blue; - elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t desaturate; - elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t flags; - return llvm::StructType::create(context, elements, "DrawSpanArgs", false)->getPointerTo(); -} - -llvm::Type *LLVMDrawersImpl::GetDrawWallArgsStruct(llvm::LLVMContext &context) -{ - std::vector elements; - elements.push_back(llvm::Type::getInt8PtrTy(context)); - for (int i = 0; i < 8; i++) - elements.push_back(llvm::Type::getInt8PtrTy(context)); - for (int i = 0; i < 25; i++) - elements.push_back(llvm::Type::getInt32Ty(context)); - elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_alpha; - elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_red; - elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_green; - elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_blue; - elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t fade_alpha; - elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t fade_red; - elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t fade_green; - elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t fade_blue; - elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t desaturate; - elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t flags; - return llvm::StructType::create(context, elements, "DrawWallArgs", false)->getPointerTo(); -} - -llvm::Type *LLVMDrawersImpl::GetDrawSkyArgsStruct(llvm::LLVMContext &context) -{ - std::vector elements; - elements.push_back(llvm::Type::getInt8PtrTy(context)); - for (int i = 0; i < 8; i++) - elements.push_back(llvm::Type::getInt8PtrTy(context)); - for (int i = 0; i < 15; i++) - elements.push_back(llvm::Type::getInt32Ty(context)); - return llvm::StructType::create(context, elements, "DrawSkyArgs", false)->getPointerTo(); -} - -llvm::Type *LLVMDrawersImpl::GetWorkerThreadDataStruct(llvm::LLVMContext &context) -{ - std::vector elements; - for (int i = 0; i < 4; i++) - elements.push_back(llvm::Type::getInt32Ty(context)); - elements.push_back(llvm::Type::getInt8PtrTy(context)); - return llvm::StructType::create(context, elements, "ThreadData", false)->getPointerTo(); -} - -llvm::Type *LLVMDrawersImpl::GetTriVertexStruct(llvm::LLVMContext &context) -{ - std::vector elements; - for (int i = 0; i < 4 + TriVertex::NumVarying; i++) - elements.push_back(llvm::Type::getFloatTy(context)); - return llvm::StructType::create(context, elements, "TriVertex", false)->getPointerTo(); -} - -llvm::Type *LLVMDrawersImpl::GetTriMatrixStruct(llvm::LLVMContext &context) -{ - std::vector elements; - for (int i = 0; i < 4 * 4; i++) - elements.push_back(llvm::Type::getFloatTy(context)); - return llvm::StructType::create(context, elements, "TriMatrix", false)->getPointerTo(); -} - -llvm::Type *LLVMDrawersImpl::GetTriUniformsStruct(llvm::LLVMContext &context) -{ - std::vector elements; - elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t light; - elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t subsectorDepth; - elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t color; - elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t srcalpha; - elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t destalpha; - elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_alpha; - elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_red; - elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_green; - elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_blue; - elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t fade_alpha; - elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t fade_red; - elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t fade_green; - elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t fade_blue; - elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t desaturate; - elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t flags; - elements.push_back(GetTriMatrixStruct(context)); // TriMatrix objectToClip - return llvm::StructType::create(context, elements, "TriUniforms", false)->getPointerTo(); -} - -llvm::Type *LLVMDrawersImpl::GetTriDrawTriangleArgs(llvm::LLVMContext &context) -{ - std::vector elements; - elements.push_back(llvm::Type::getInt8PtrTy(context)); // uint8_t *dest; - elements.push_back(llvm::Type::getInt32Ty(context)); // int32_t pitch; - elements.push_back(GetTriVertexStruct(context)); // TriVertex *v1; - elements.push_back(GetTriVertexStruct(context)); // TriVertex *v2; - elements.push_back(GetTriVertexStruct(context)); // TriVertex *v3; - elements.push_back(llvm::Type::getInt32Ty(context)); // int32_t clipleft; - elements.push_back(llvm::Type::getInt32Ty(context)); // int32_t clipright; - elements.push_back(llvm::Type::getInt32Ty(context)); // int32_t cliptop; - elements.push_back(llvm::Type::getInt32Ty(context)); // int32_t clipbottom; - elements.push_back(llvm::Type::getInt8PtrTy(context)); // const uint8_t *texturePixels; - elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t textureWidth; - elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t textureHeight; - elements.push_back(llvm::Type::getInt8PtrTy(context)); // const uint8_t *translation; - elements.push_back(GetTriUniformsStruct(context)); // const TriUniforms *uniforms; - elements.push_back(llvm::Type::getInt8PtrTy(context)); // uint8_t *stencilValues; - elements.push_back(llvm::Type::getInt32PtrTy(context)); // uint32_t *stencilMasks; - elements.push_back(llvm::Type::getInt32Ty(context)); // int32_t stencilPitch; - elements.push_back(llvm::Type::getInt8Ty(context)); // uint8_t stencilTestValue; - elements.push_back(llvm::Type::getInt8Ty(context)); // uint8_t stencilWriteValue; - elements.push_back(llvm::Type::getInt32PtrTy(context)); // uint32_t *subsectorGBuffer; - elements.push_back(llvm::Type::getInt8PtrTy(context)); // const uint8_t *colormaps; - elements.push_back(llvm::Type::getInt8PtrTy(context)); // const uint8_t *RGB32k; - elements.push_back(llvm::Type::getInt8PtrTy(context)); // const uint8_t *BaseColors; - return llvm::StructType::create(context, elements, "TriDrawTriangle", false)->getPointerTo(); -} - -///////////////////////////////////////////////////////////////////////////// - -namespace { static bool LogFatalErrors = false; } - -LLVMProgram::LLVMProgram() -{ - using namespace llvm; - - // We have to extra careful about this because both LLVM and ZDoom made - // the very unwise decision to hook atexit. To top it off, LLVM decided - // to log something in the atexit handler.. - LogFatalErrors = true; - - install_fatal_error_handler([](void *user_data, const std::string& reason, bool gen_crash_diag) { - if (LogFatalErrors) - I_FatalError("LLVM fatal error: %s", reason.c_str()); - }); - - InitializeNativeTarget(); - InitializeNativeTargetAsmPrinter(); - - mContext = std::make_unique(); -} - -void LLVMProgram::CreateModule() -{ - mModule = std::make_unique("render", context()); -} - -bool LLVMProgram::LoadCachedModule(int version, std::string targetCPU) -{ - FString filename = GetDrawerCacheFilename(version, targetCPU.c_str()); - FILE *file = fopen(filename, "rb"); - if (!file) - return false; - - bool success = false; - std::string data; - - fseek(file, 0, SEEK_END); - int length = ftell(file); - fseek(file, 0, SEEK_SET); - if (length > 0) - { - data.resize(length); - success = fread(&data[0], length, 1, file) == 1; - } - - fclose(file); - if (!success) - return false; - - auto result = llvm::parseBitcodeFile(llvm::MemoryBufferRef(data, filename.GetChars()), *mContext.get()); - if (!result) - return false; - -#if LLVM_VERSION_MAJOR < 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 8) - mModule.reset(result.get()); -#else - mModule = std::move(result.get()); -#endif - return true; -} - -void LLVMProgram::SaveCachedModule(llvm::Module *module, int version, std::string targetCPU) -{ - std::string str; - llvm::raw_string_ostream stream(str); - llvm::WriteBitcodeToFile(module, stream); - std::string data = stream.str(); - - FString filename = GetDrawerCacheFilename(version, targetCPU.c_str()); - FILE *file = fopen(filename, "wb"); - if (file) - { - fwrite(data.data(), data.size(), 1, file); - fclose(file); - } -} - -FString LLVMProgram::GetDrawerCacheFilename(int version, FString cpu) -{ - FString path = M_GetCachePath(true); - FString filename; - filename.Format("%s/LLVMDrawers-%d-%s.bc", path.GetChars(), version, cpu.GetChars()); - return filename; -} - -std::string LLVMProgram::GetTargetCPU() -{ - using namespace llvm; - std::string mcpu = sys::getHostCPUName(); - if (std::string(CPU.CPUString).find("G840") != std::string::npos && mcpu == "sandybridge") - mcpu = "westmere"; // Pentium G840 is misdetected as a sandy bridge CPU - - if (stricmp(llvm_cpu, "auto") != 0) - { - mcpu = llvm_cpu; - Printf("Overriding LLVM CPU target to %s\n", mcpu.c_str()); - } - return mcpu; -} - -void LLVMProgram::CreateEE(int version, std::string targetCPU, bool optimize) -{ - using namespace llvm; - - std::string errorstring; - - llvm::Module *module = mModule.get(); - EngineBuilder engineBuilder(std::move(mModule)); - engineBuilder.setErrorStr(&errorstring); - engineBuilder.setOptLevel(CodeGenOpt::Aggressive); - engineBuilder.setEngineKind(EngineKind::JIT); - engineBuilder.setMCPU(targetCPU); - machine = engineBuilder.selectTarget(); - if (!machine) - I_FatalError("Could not create LLVM target machine"); - -#if LLVM_VERSION_MAJOR < 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 8) - std::string targetTriple = machine->getTargetTriple(); -#else - std::string targetTriple = machine->getTargetTriple().getTriple(); -#endif - std::string cpuName = machine->getTargetCPU(); - Printf("LLVM target triple: %s\n", targetTriple.c_str()); - Printf("LLVM target CPU: %s\n", cpuName.c_str()); - - if (optimize) - { - Printf("Optimizing drawers..\n"); - - module->setTargetTriple(targetTriple); -#if LLVM_VERSION_MAJOR < 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 8) - module->setDataLayout(new DataLayout(*machine->getSubtargetImpl()->getDataLayout())); -#else - module->setDataLayout(machine->createDataLayout()); -#endif - - legacy::FunctionPassManager PerFunctionPasses(module); - legacy::PassManager PerModulePasses; - -#if LLVM_VERSION_MAJOR > 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 8) - PerFunctionPasses.add(createTargetTransformInfoWrapperPass(machine->getTargetIRAnalysis())); - PerModulePasses.add(createTargetTransformInfoWrapperPass(machine->getTargetIRAnalysis())); -#endif - - PassManagerBuilder passManagerBuilder; - passManagerBuilder.OptLevel = 3; - passManagerBuilder.SizeLevel = 0; - passManagerBuilder.Inliner = createFunctionInliningPass(); - passManagerBuilder.SLPVectorize = true; - passManagerBuilder.LoopVectorize = true; - passManagerBuilder.LoadCombine = true; - passManagerBuilder.populateModulePassManager(PerModulePasses); - passManagerBuilder.populateFunctionPassManager(PerFunctionPasses); - - // Run function passes: - PerFunctionPasses.doInitialization(); - for (llvm::Function &func : *module) - { - if (!func.isDeclaration()) - PerFunctionPasses.run(func); - } - PerFunctionPasses.doFinalization(); - - // Run module passes: - PerModulePasses.run(*module); - - SaveCachedModule(module, version, targetCPU); - } - - Printf("Compiling drawers..\n"); - - // Create execution engine and generate machine code - mEngine.reset(engineBuilder.create(machine)); - if (!mEngine) - I_FatalError("Could not create LLVM execution engine: %s", errorstring.c_str()); - - mEngine->finalizeObject(); -} - -std::string LLVMProgram::GenerateAssembly(std::string cpuName) -{ - using namespace llvm; - - std::string errorstring; - - llvm::Module *module = mModule.get(); - EngineBuilder engineBuilder(std::move(mModule)); - engineBuilder.setErrorStr(&errorstring); - engineBuilder.setOptLevel(CodeGenOpt::Aggressive); - engineBuilder.setEngineKind(EngineKind::JIT); - engineBuilder.setMCPU(cpuName); - machine = engineBuilder.selectTarget(); - if (!machine) - I_FatalError("Could not create LLVM target machine"); - -#if LLVM_VERSION_MAJOR < 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 8) - std::string targetTriple = machine->getTargetTriple(); -#else - std::string targetTriple = machine->getTargetTriple().getTriple(); -#endif - - module->setTargetTriple(targetTriple); -#if LLVM_VERSION_MAJOR < 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 8) - module->setDataLayout(new DataLayout(*machine->getSubtargetImpl()->getDataLayout())); -#else - module->setDataLayout(machine->createDataLayout()); -#endif - - legacy::FunctionPassManager PerFunctionPasses(module); - legacy::PassManager PerModulePasses; - -#if LLVM_VERSION_MAJOR > 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 8) - PerFunctionPasses.add(createTargetTransformInfoWrapperPass(machine->getTargetIRAnalysis())); - PerModulePasses.add(createTargetTransformInfoWrapperPass(machine->getTargetIRAnalysis())); -#endif - - SmallString<16*1024> str; -#if LLVM_VERSION_MAJOR < 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 8) - raw_svector_ostream vecstream(str); - formatted_raw_ostream stream(vecstream); -#else - raw_svector_ostream stream(str); -#endif - machine->addPassesToEmitFile(PerModulePasses, stream, TargetMachine::CGFT_AssemblyFile); - - PassManagerBuilder passManagerBuilder; - passManagerBuilder.OptLevel = 3; - passManagerBuilder.SizeLevel = 0; - passManagerBuilder.Inliner = createFunctionInliningPass(); - passManagerBuilder.SLPVectorize = true; - passManagerBuilder.LoopVectorize = true; - passManagerBuilder.LoadCombine = true; - passManagerBuilder.populateModulePassManager(PerModulePasses); - passManagerBuilder.populateFunctionPassManager(PerFunctionPasses); - - // Run function passes: - PerFunctionPasses.doInitialization(); - for (llvm::Function &func : *module) - { - if (!func.isDeclaration()) - PerFunctionPasses.run(func); - } - PerFunctionPasses.doFinalization(); - - // Run module passes: - PerModulePasses.run(*module); - - return str.c_str(); -} - -std::string LLVMProgram::DumpModule() -{ - std::string str; - llvm::raw_string_ostream stream(str); -#if LLVM_VERSION_MAJOR < 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 8) - mModule->print(stream, nullptr); -#else - mModule->print(stream, nullptr, false, true); -#endif - return stream.str(); -} - -void *LLVMProgram::PointerToFunction(const char *name) -{ - return reinterpret_cast(mEngine->getFunctionAddress(name)); -} - -void LLVMProgram::StopLogFatalErrors() -{ - LogFatalErrors = false; -} diff --git a/src/r_draw_rgba.cpp b/src/r_draw_rgba.cpp index b7be3ceed3..716b30c0d3 100644 --- a/src/r_draw_rgba.cpp +++ b/src/r_draw_rgba.cpp @@ -38,7 +38,7 @@ #include "r_data/colormaps.h" #include "r_plane.h" #include "r_draw_rgba.h" -#include "r_compiler/llvmdrawers.h" +#include "r_drawers.h" #include "gl/data/gl_matrix.h" #include "gi.h" @@ -105,7 +105,7 @@ public: { if (thread->skipped_by_thread(args.y)) return; - LLVMDrawers::Instance()->DrawSpan(&args); + Drawers::Instance()->DrawSpan(&args); } FString DebugInfo() override @@ -146,7 +146,7 @@ public: { if (thread->skipped_by_thread(args.y)) return; - LLVMDrawers::Instance()->DrawSpanMasked(&args); + Drawers::Instance()->DrawSpanMasked(&args); } }; @@ -157,7 +157,7 @@ public: { if (thread->skipped_by_thread(args.y)) return; - LLVMDrawers::Instance()->DrawSpanTranslucent(&args); + Drawers::Instance()->DrawSpanTranslucent(&args); } }; @@ -168,7 +168,7 @@ public: { if (thread->skipped_by_thread(args.y)) return; - LLVMDrawers::Instance()->DrawSpanMaskedTranslucent(&args); + Drawers::Instance()->DrawSpanMaskedTranslucent(&args); } }; @@ -179,7 +179,7 @@ public: { if (thread->skipped_by_thread(args.y)) return; - LLVMDrawers::Instance()->DrawSpanAddClamp(&args); + Drawers::Instance()->DrawSpanAddClamp(&args); } }; @@ -190,7 +190,7 @@ public: { if (thread->skipped_by_thread(args.y)) return; - LLVMDrawers::Instance()->DrawSpanMaskedAddClamp(&args); + Drawers::Instance()->DrawSpanMaskedAddClamp(&args); } }; @@ -251,7 +251,7 @@ public: void Execute(DrawerThread *thread) override { WorkerThreadData d = ThreadData(thread); - LLVMDrawers::Instance()->vlinec4(&args, &d); + Drawers::Instance()->vlinec4(&args, &d); } FString DebugInfo() override @@ -312,7 +312,7 @@ public: void Execute(DrawerThread *thread) override { WorkerThreadData d = ThreadData(thread); - LLVMDrawers::Instance()->vlinec1(&args, &d); + Drawers::Instance()->vlinec1(&args, &d); } FString DebugInfo() override @@ -383,7 +383,7 @@ public: void Execute(DrawerThread *thread) override { WorkerThreadData d = ThreadData(thread); - LLVMDrawers::Instance()->DrawColumn(&args, &d); + Drawers::Instance()->DrawColumn(&args, &d); } }; @@ -438,7 +438,7 @@ public: \ void Execute(DrawerThread *thread) override \ { \ WorkerThreadData d = ThreadData(thread); \ - LLVMDrawers::Instance()->func(&args, &d); \ + Drawers::Instance()->func(&args, &d); \ } \ }; diff --git a/src/r_drawers.cpp b/src/r_drawers.cpp new file mode 100644 index 0000000000..6d4aaa055d --- /dev/null +++ b/src/r_drawers.cpp @@ -0,0 +1,423 @@ +/* +** LLVM code generated drawers +** Copyright (c) 2016 Magnus Norddahl +** +** This software is provided 'as-is', without any express or implied +** warranty. In no event will the authors be held liable for any damages +** arising from the use of this software. +** +** Permission is granted to anyone to use this software for any purpose, +** including commercial applications, and to alter it and redistribute it +** freely, subject to the following restrictions: +** +** 1. The origin of this software must not be misrepresented; you must not +** claim that you wrote the original software. If you use this software +** in a product, an acknowledgment in the product documentation would be +** appreciated but is not required. +** 2. Altered source versions must be plainly marked as such, and must not be +** misrepresented as being the original software. +** 3. This notice may not be removed or altered from any source distribution. +** +*/ + +#include "i_system.h" +#include "r_drawers.h" +#include "x86.h" +#include "c_cvars.h" +#include "version.h" +#include "m_misc.h" + +CUSTOM_CVAR(String, llvm_cpu, "auto", CVAR_ARCHIVE | CVAR_NOINITCALL) +{ + Printf("You must restart " GAMENAME " for this change to take effect.\n"); +} + +///////////////////////////////////////////////////////////////////////////// + +extern "C" +{ + void DrawColumn_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void DrawColumnAdd_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void DrawColumnShaded_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void DrawColumnAddClamp_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void DrawColumnSubClamp_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void DrawColumnRevSubClamp_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void DrawColumnTranslated_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void DrawColumnTlatedAdd_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void DrawColumnAddClampTranslated_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void DrawColumnSubClampTranslated_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void DrawColumnRevSubClampTranslated_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void FillColumn_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void FillColumnAdd_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void FillColumnAddClamp_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void FillColumnSubClamp_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void FillColumnRevSubClamp_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void DrawColumnRt1_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void DrawColumnRt1Copy_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void DrawColumnRt1Add_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void DrawColumnRt1Shaded_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void DrawColumnRt1AddClamp_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void DrawColumnRt1SubClamp_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void DrawColumnRt1RevSubClamp_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void DrawColumnRt1Translated_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void DrawColumnRt1TlatedAdd_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void DrawColumnRt1AddClampTranslated_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void DrawColumnRt1SubClampTranslated_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void DrawColumnRt1RevSubClampTranslated_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void DrawColumnRt4_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void DrawColumnRt4Copy_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void DrawColumnRt4Add_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void DrawColumnRt4Shaded_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void DrawColumnRt4AddClamp_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void DrawColumnRt4SubClamp_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void DrawColumnRt4RevSubClamp_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void DrawColumnRt4Translated_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void DrawColumnRt4TlatedAdd_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void DrawColumnRt4AddClampTranslated_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void DrawColumnRt4SubClampTranslated_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void DrawColumnRt4RevSubClampTranslated_SSE2(const DrawColumnArgs *, const WorkerThreadData *); + void DrawSpan_SSE2(const DrawSpanArgs *); + void DrawSpanMasked_SSE2(const DrawSpanArgs *); + void DrawSpanTranslucent_SSE2(const DrawSpanArgs *); + void DrawSpanMaskedTranslucent_SSE2(const DrawSpanArgs *); + void DrawSpanAddClamp_SSE2(const DrawSpanArgs *); + void DrawSpanMaskedAddClamp_SSE2(const DrawSpanArgs *); + void vlinec1_SSE2(const DrawWallArgs *, const WorkerThreadData *); + void vlinec4_SSE2(const DrawWallArgs *, const WorkerThreadData *); + void mvlinec1_SSE2(const DrawWallArgs *, const WorkerThreadData *); + void mvlinec4_SSE2(const DrawWallArgs *, const WorkerThreadData *); + void tmvline1_add_SSE2(const DrawWallArgs *, const WorkerThreadData *); + void tmvline4_add_SSE2(const DrawWallArgs *, const WorkerThreadData *); + void tmvline1_addclamp_SSE2(const DrawWallArgs *, const WorkerThreadData *); + void tmvline4_addclamp_SSE2(const DrawWallArgs *, const WorkerThreadData *); + void tmvline1_subclamp_SSE2(const DrawWallArgs *, const WorkerThreadData *); + void tmvline4_subclamp_SSE2(const DrawWallArgs *, const WorkerThreadData *); + void tmvline1_revsubclamp_SSE2(const DrawWallArgs *, const WorkerThreadData *); + void tmvline4_revsubclamp_SSE2(const DrawWallArgs *, const WorkerThreadData *); + void DrawSky1_SSE2(const DrawSkyArgs *, const WorkerThreadData *); + void DrawSky4_SSE2(const DrawSkyArgs *, const WorkerThreadData *); + void DrawDoubleSky1_SSE2(const DrawSkyArgs *, const WorkerThreadData *); + void DrawDoubleSky4_SSE2(const DrawSkyArgs *, const WorkerThreadData *); + void TriDrawNormal8_0_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawNormal8_1_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawNormal8_2_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawNormal8_3_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawNormal8_4_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawNormal8_5_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawNormal8_6_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawNormal8_7_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawNormal8_8_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawNormal8_9_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawNormal8_10_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawNormal8_11_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawNormal8_12_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawNormal32_0_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawNormal32_1_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawNormal32_2_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawNormal32_3_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawNormal32_4_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawNormal32_5_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawNormal32_6_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawNormal32_7_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawNormal32_8_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawNormal32_9_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawNormal32_10_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawNormal32_11_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawNormal32_12_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillNormal8_0_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillNormal8_1_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillNormal8_2_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillNormal8_3_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillNormal8_4_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillNormal8_5_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillNormal8_6_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillNormal8_7_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillNormal8_8_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillNormal8_9_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillNormal8_10_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillNormal8_11_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillNormal8_12_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillNormal32_0_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillNormal32_1_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillNormal32_2_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillNormal32_3_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillNormal32_4_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillNormal32_5_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillNormal32_6_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillNormal32_7_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillNormal32_8_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillNormal32_9_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillNormal32_10_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillNormal32_11_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillNormal32_12_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawSubsector8_0_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawSubsector8_1_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawSubsector8_2_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawSubsector8_3_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawSubsector8_4_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawSubsector8_5_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawSubsector8_6_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawSubsector8_7_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawSubsector8_8_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawSubsector8_9_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawSubsector8_10_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawSubsector8_11_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawSubsector8_12_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawSubsector32_0_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawSubsector32_1_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawSubsector32_2_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawSubsector32_3_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawSubsector32_4_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawSubsector32_5_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawSubsector32_6_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawSubsector32_7_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawSubsector32_8_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawSubsector32_9_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawSubsector32_10_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawSubsector32_11_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawSubsector32_12_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillSubsector8_0_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillSubsector8_1_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillSubsector8_2_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillSubsector8_3_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillSubsector8_4_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillSubsector8_5_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillSubsector8_6_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillSubsector8_7_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillSubsector8_8_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillSubsector8_9_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillSubsector8_10_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillSubsector8_11_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillSubsector8_12_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillSubsector32_0_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillSubsector32_1_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillSubsector32_2_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillSubsector32_3_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillSubsector32_4_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillSubsector32_5_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillSubsector32_6_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillSubsector32_7_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillSubsector32_8_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillSubsector32_9_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillSubsector32_10_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillSubsector32_11_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillSubsector32_12_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriStencil_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriStencilClose_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); +} + +///////////////////////////////////////////////////////////////////////////// + +Drawers *Drawers::Instance() +{ + static Drawers drawers; + static bool firstcall = true; + + if (!firstcall) + return &drawers; + + drawers.DrawColumn = DrawColumn_SSE2; + drawers.DrawColumnAdd = DrawColumnAdd_SSE2; + drawers.DrawColumnShaded = DrawColumnShaded_SSE2; + drawers.DrawColumnAddClamp = DrawColumnAddClamp_SSE2; + drawers.DrawColumnSubClamp = DrawColumnSubClamp_SSE2; + drawers.DrawColumnRevSubClamp = DrawColumnRevSubClamp_SSE2; + drawers.DrawColumnTranslated = DrawColumnTranslated_SSE2; + drawers.DrawColumnTlatedAdd = DrawColumnTlatedAdd_SSE2; + drawers.DrawColumnAddClampTranslated = DrawColumnAddClampTranslated_SSE2; + drawers.DrawColumnSubClampTranslated = DrawColumnSubClampTranslated_SSE2; + drawers.DrawColumnRevSubClampTranslated = DrawColumnRevSubClampTranslated_SSE2; + drawers.FillColumn = FillColumn_SSE2; + drawers.FillColumnAdd = FillColumnAdd_SSE2; + drawers.FillColumnAddClamp = FillColumnAddClamp_SSE2; + drawers.FillColumnSubClamp = FillColumnSubClamp_SSE2; + drawers.FillColumnRevSubClamp = FillColumnRevSubClamp_SSE2; + drawers.DrawColumnRt1 = DrawColumnRt1_SSE2; + drawers.DrawColumnRt1Copy = DrawColumnRt1Copy_SSE2; + drawers.DrawColumnRt1Add = DrawColumnRt1Add_SSE2; + drawers.DrawColumnRt1Shaded = DrawColumnRt1Shaded_SSE2; + drawers.DrawColumnRt1AddClamp = DrawColumnRt1AddClamp_SSE2; + drawers.DrawColumnRt1SubClamp = DrawColumnRt1SubClamp_SSE2; + drawers.DrawColumnRt1RevSubClamp = DrawColumnRt1RevSubClamp_SSE2; + drawers.DrawColumnRt1Translated = DrawColumnRt1Translated_SSE2; + drawers.DrawColumnRt1TlatedAdd = DrawColumnRt1TlatedAdd_SSE2; + drawers.DrawColumnRt1AddClampTranslated = DrawColumnRt1AddClampTranslated_SSE2; + drawers.DrawColumnRt1SubClampTranslated = DrawColumnRt1SubClampTranslated_SSE2; + drawers.DrawColumnRt1RevSubClampTranslated = DrawColumnRt1RevSubClampTranslated_SSE2; + drawers.DrawColumnRt4 = DrawColumnRt4_SSE2; + drawers.DrawColumnRt4Copy = DrawColumnRt4Copy_SSE2; + drawers.DrawColumnRt4Add = DrawColumnRt4Add_SSE2; + drawers.DrawColumnRt4Shaded = DrawColumnRt4Shaded_SSE2; + drawers.DrawColumnRt4AddClamp = DrawColumnRt4AddClamp_SSE2; + drawers.DrawColumnRt4SubClamp = DrawColumnRt4SubClamp_SSE2; + drawers.DrawColumnRt4RevSubClamp = DrawColumnRt4RevSubClamp_SSE2; + drawers.DrawColumnRt4Translated = DrawColumnRt4Translated_SSE2; + drawers.DrawColumnRt4TlatedAdd = DrawColumnRt4TlatedAdd_SSE2; + drawers.DrawColumnRt4AddClampTranslated = DrawColumnRt4AddClampTranslated_SSE2; + drawers.DrawColumnRt4SubClampTranslated = DrawColumnRt4SubClampTranslated_SSE2; + drawers.DrawColumnRt4RevSubClampTranslated = DrawColumnRt4RevSubClampTranslated_SSE2; + drawers.DrawSpan = DrawSpan_SSE2; + drawers.DrawSpanMasked = DrawSpanMasked_SSE2; + drawers.DrawSpanTranslucent = DrawSpanTranslucent_SSE2; + drawers.DrawSpanMaskedTranslucent = DrawSpanMaskedTranslucent_SSE2; + drawers.DrawSpanAddClamp = DrawSpanAddClamp_SSE2; + drawers.DrawSpanMaskedAddClamp = DrawSpanMaskedAddClamp_SSE2; + drawers.vlinec1 = vlinec1_SSE2; + drawers.vlinec4 = vlinec4_SSE2; + drawers.mvlinec1 = mvlinec1_SSE2; + drawers.mvlinec4 = mvlinec4_SSE2; + drawers.tmvline1_add = tmvline1_add_SSE2; + drawers.tmvline4_add = tmvline4_add_SSE2; + drawers.tmvline1_addclamp = tmvline1_addclamp_SSE2; + drawers.tmvline4_addclamp = tmvline4_addclamp_SSE2; + drawers.tmvline1_subclamp = tmvline1_subclamp_SSE2; + drawers.tmvline4_subclamp = tmvline4_subclamp_SSE2; + drawers.tmvline1_revsubclamp = tmvline1_revsubclamp_SSE2; + drawers.tmvline4_revsubclamp = tmvline4_revsubclamp_SSE2; + drawers.DrawSky1 = DrawSky1_SSE2; + drawers.DrawSky4 = DrawSky4_SSE2; + drawers.DrawDoubleSky1 = DrawDoubleSky1_SSE2; + drawers.DrawDoubleSky4 = DrawDoubleSky4_SSE2; + drawers.TriDrawNormal8.push_back(TriDrawNormal8_0_SSE2); + drawers.TriDrawNormal8.push_back(TriDrawNormal8_1_SSE2); + drawers.TriDrawNormal8.push_back(TriDrawNormal8_2_SSE2); + drawers.TriDrawNormal8.push_back(TriDrawNormal8_3_SSE2); + drawers.TriDrawNormal8.push_back(TriDrawNormal8_4_SSE2); + drawers.TriDrawNormal8.push_back(TriDrawNormal8_5_SSE2); + drawers.TriDrawNormal8.push_back(TriDrawNormal8_6_SSE2); + drawers.TriDrawNormal8.push_back(TriDrawNormal8_7_SSE2); + drawers.TriDrawNormal8.push_back(TriDrawNormal8_8_SSE2); + drawers.TriDrawNormal8.push_back(TriDrawNormal8_9_SSE2); + drawers.TriDrawNormal8.push_back(TriDrawNormal8_10_SSE2); + drawers.TriDrawNormal8.push_back(TriDrawNormal8_11_SSE2); + drawers.TriDrawNormal8.push_back(TriDrawNormal8_12_SSE2); + drawers.TriDrawNormal32.push_back(TriDrawNormal32_0_SSE2); + drawers.TriDrawNormal32.push_back(TriDrawNormal32_1_SSE2); + drawers.TriDrawNormal32.push_back(TriDrawNormal32_2_SSE2); + drawers.TriDrawNormal32.push_back(TriDrawNormal32_3_SSE2); + drawers.TriDrawNormal32.push_back(TriDrawNormal32_4_SSE2); + drawers.TriDrawNormal32.push_back(TriDrawNormal32_5_SSE2); + drawers.TriDrawNormal32.push_back(TriDrawNormal32_6_SSE2); + drawers.TriDrawNormal32.push_back(TriDrawNormal32_7_SSE2); + drawers.TriDrawNormal32.push_back(TriDrawNormal32_8_SSE2); + drawers.TriDrawNormal32.push_back(TriDrawNormal32_9_SSE2); + drawers.TriDrawNormal32.push_back(TriDrawNormal32_10_SSE2); + drawers.TriDrawNormal32.push_back(TriDrawNormal32_11_SSE2); + drawers.TriDrawNormal32.push_back(TriDrawNormal32_12_SSE2); + drawers.TriFillNormal8.push_back(TriFillNormal8_0_SSE2); + drawers.TriFillNormal8.push_back(TriFillNormal8_1_SSE2); + drawers.TriFillNormal8.push_back(TriFillNormal8_2_SSE2); + drawers.TriFillNormal8.push_back(TriFillNormal8_3_SSE2); + drawers.TriFillNormal8.push_back(TriFillNormal8_4_SSE2); + drawers.TriFillNormal8.push_back(TriFillNormal8_5_SSE2); + drawers.TriFillNormal8.push_back(TriFillNormal8_6_SSE2); + drawers.TriFillNormal8.push_back(TriFillNormal8_7_SSE2); + drawers.TriFillNormal8.push_back(TriFillNormal8_8_SSE2); + drawers.TriFillNormal8.push_back(TriFillNormal8_9_SSE2); + drawers.TriFillNormal8.push_back(TriFillNormal8_10_SSE2); + drawers.TriFillNormal8.push_back(TriFillNormal8_11_SSE2); + drawers.TriFillNormal8.push_back(TriFillNormal8_12_SSE2); + drawers.TriFillNormal32.push_back(TriFillNormal32_0_SSE2); + drawers.TriFillNormal32.push_back(TriFillNormal32_1_SSE2); + drawers.TriFillNormal32.push_back(TriFillNormal32_2_SSE2); + drawers.TriFillNormal32.push_back(TriFillNormal32_3_SSE2); + drawers.TriFillNormal32.push_back(TriFillNormal32_4_SSE2); + drawers.TriFillNormal32.push_back(TriFillNormal32_5_SSE2); + drawers.TriFillNormal32.push_back(TriFillNormal32_6_SSE2); + drawers.TriFillNormal32.push_back(TriFillNormal32_7_SSE2); + drawers.TriFillNormal32.push_back(TriFillNormal32_8_SSE2); + drawers.TriFillNormal32.push_back(TriFillNormal32_9_SSE2); + drawers.TriFillNormal32.push_back(TriFillNormal32_10_SSE2); + drawers.TriFillNormal32.push_back(TriFillNormal32_11_SSE2); + drawers.TriFillNormal32.push_back(TriFillNormal32_12_SSE2); + drawers.TriDrawSubsector8.push_back(TriDrawSubsector8_0_SSE2); + drawers.TriDrawSubsector8.push_back(TriDrawSubsector8_1_SSE2); + drawers.TriDrawSubsector8.push_back(TriDrawSubsector8_2_SSE2); + drawers.TriDrawSubsector8.push_back(TriDrawSubsector8_3_SSE2); + drawers.TriDrawSubsector8.push_back(TriDrawSubsector8_4_SSE2); + drawers.TriDrawSubsector8.push_back(TriDrawSubsector8_5_SSE2); + drawers.TriDrawSubsector8.push_back(TriDrawSubsector8_6_SSE2); + drawers.TriDrawSubsector8.push_back(TriDrawSubsector8_7_SSE2); + drawers.TriDrawSubsector8.push_back(TriDrawSubsector8_8_SSE2); + drawers.TriDrawSubsector8.push_back(TriDrawSubsector8_9_SSE2); + drawers.TriDrawSubsector8.push_back(TriDrawSubsector8_10_SSE2); + drawers.TriDrawSubsector8.push_back(TriDrawSubsector8_11_SSE2); + drawers.TriDrawSubsector8.push_back(TriDrawSubsector8_12_SSE2); + drawers.TriDrawSubsector32.push_back(TriDrawSubsector32_0_SSE2); + drawers.TriDrawSubsector32.push_back(TriDrawSubsector32_1_SSE2); + drawers.TriDrawSubsector32.push_back(TriDrawSubsector32_2_SSE2); + drawers.TriDrawSubsector32.push_back(TriDrawSubsector32_3_SSE2); + drawers.TriDrawSubsector32.push_back(TriDrawSubsector32_4_SSE2); + drawers.TriDrawSubsector32.push_back(TriDrawSubsector32_5_SSE2); + drawers.TriDrawSubsector32.push_back(TriDrawSubsector32_6_SSE2); + drawers.TriDrawSubsector32.push_back(TriDrawSubsector32_7_SSE2); + drawers.TriDrawSubsector32.push_back(TriDrawSubsector32_8_SSE2); + drawers.TriDrawSubsector32.push_back(TriDrawSubsector32_9_SSE2); + drawers.TriDrawSubsector32.push_back(TriDrawSubsector32_10_SSE2); + drawers.TriDrawSubsector32.push_back(TriDrawSubsector32_11_SSE2); + drawers.TriDrawSubsector32.push_back(TriDrawSubsector32_12_SSE2); + drawers.TriFillSubsector8.push_back(TriFillSubsector8_0_SSE2); + drawers.TriFillSubsector8.push_back(TriFillSubsector8_1_SSE2); + drawers.TriFillSubsector8.push_back(TriFillSubsector8_2_SSE2); + drawers.TriFillSubsector8.push_back(TriFillSubsector8_3_SSE2); + drawers.TriFillSubsector8.push_back(TriFillSubsector8_4_SSE2); + drawers.TriFillSubsector8.push_back(TriFillSubsector8_5_SSE2); + drawers.TriFillSubsector8.push_back(TriFillSubsector8_6_SSE2); + drawers.TriFillSubsector8.push_back(TriFillSubsector8_7_SSE2); + drawers.TriFillSubsector8.push_back(TriFillSubsector8_8_SSE2); + drawers.TriFillSubsector8.push_back(TriFillSubsector8_9_SSE2); + drawers.TriFillSubsector8.push_back(TriFillSubsector8_10_SSE2); + drawers.TriFillSubsector8.push_back(TriFillSubsector8_11_SSE2); + drawers.TriFillSubsector8.push_back(TriFillSubsector8_12_SSE2); + drawers.TriFillSubsector32.push_back(TriFillSubsector32_0_SSE2); + drawers.TriFillSubsector32.push_back(TriFillSubsector32_1_SSE2); + drawers.TriFillSubsector32.push_back(TriFillSubsector32_2_SSE2); + drawers.TriFillSubsector32.push_back(TriFillSubsector32_3_SSE2); + drawers.TriFillSubsector32.push_back(TriFillSubsector32_4_SSE2); + drawers.TriFillSubsector32.push_back(TriFillSubsector32_5_SSE2); + drawers.TriFillSubsector32.push_back(TriFillSubsector32_6_SSE2); + drawers.TriFillSubsector32.push_back(TriFillSubsector32_7_SSE2); + drawers.TriFillSubsector32.push_back(TriFillSubsector32_8_SSE2); + drawers.TriFillSubsector32.push_back(TriFillSubsector32_9_SSE2); + drawers.TriFillSubsector32.push_back(TriFillSubsector32_10_SSE2); + drawers.TriFillSubsector32.push_back(TriFillSubsector32_11_SSE2); + drawers.TriFillSubsector32.push_back(TriFillSubsector32_12_SSE2); + drawers.TriStencil = TriStencil_SSE2; + drawers.TriStencilClose = TriStencilClose_SSE2; + + firstcall = false; + return &drawers; +} + +Drawers::Drawers() +{ + // To do: setup pointers +} + +FString DrawWallArgs::ToString() +{ + FString info; + info.Format("dest_y = %i, count = %i, flags = %i, texturefrac[0] = %u, textureheight[0] = %u", dest_y, count, flags, texturefrac[0], textureheight[0]); + return info; +} + +FString DrawSpanArgs::ToString() +{ + FString info; + info.Format("x1 = %i, x2 = %i, y = %i, flags = %i", x1, x2, y, flags); + return info; +} + +FString DrawColumnArgs::ToString() +{ + FString info; + info.Format("dest_y = %i, count = %i, flags = %i, iscale = %i (%f), texturefrac = %i (%f)", dest_y, count, flags, iscale, ((fixed_t)iscale) / (float)FRACUNIT, texturefrac, ((fixed_t)texturefrac) / (float)FRACUNIT); + return info; +} + +FString DrawSkyArgs::ToString() +{ + FString info; + info.Format("dest_y = %i, count = %i", dest_y, count); + return info; +} diff --git a/src/r_compiler/llvmdrawers.h b/src/r_drawers.h similarity index 93% rename from src/r_compiler/llvmdrawers.h rename to src/r_drawers.h index c5eb96f4c9..17168b6f31 100644 --- a/src/r_compiler/llvmdrawers.h +++ b/src/r_drawers.h @@ -22,6 +22,11 @@ #pragma once +#include +#include + +class FString; + struct WorkerThreadData { int32_t core; @@ -63,12 +68,7 @@ struct DrawWallArgs nearest_filter = 2 }; - FString ToString() - { - FString info; - info.Format("dest_y = %i, count = %i, flags = %i, texturefrac[0] = %u, textureheight[0] = %u", dest_y, count, flags, texturefrac[0], textureheight[0]); - return info; - } + FString ToString(); }; struct DrawSpanArgs @@ -105,12 +105,7 @@ struct DrawSpanArgs nearest_filter = 2 }; - FString ToString() - { - FString info; - info.Format("x1 = %i, x2 = %i, y = %i, flags = %i", x1, x2, y, flags); - return info; - } + FString ToString(); }; struct DrawColumnArgs @@ -150,12 +145,7 @@ struct DrawColumnArgs nearest_filter = 2 }; - FString ToString() - { - FString info; - info.Format("dest_y = %i, count = %i, flags = %i, iscale = %i (%f), texturefrac = %i (%f)", dest_y, count, flags, iscale, ((fixed_t)iscale) / (float)FRACUNIT, texturefrac, ((fixed_t)texturefrac) / (float)FRACUNIT); - return info; - } + FString ToString(); }; struct DrawSkyArgs @@ -173,12 +163,7 @@ struct DrawSkyArgs uint32_t top_color; uint32_t bottom_color; - FString ToString() - { - FString info; - info.Format("dest_y = %i, count = %i", dest_y, count); - return info; - } + FString ToString(); }; struct TriVertex @@ -273,14 +258,12 @@ enum class TriBlendMode inline int NumTriBlendModes() { return (int)TriBlendMode::TranslateRevSub + 1; } -class LLVMDrawers +class Drawers { public: - virtual ~LLVMDrawers() { } + Drawers(); - static void Create(); - static void Destroy(); - static LLVMDrawers *Instance(); + static Drawers *Instance(); void(*DrawColumn)(const DrawColumnArgs *, const WorkerThreadData *) = nullptr; void(*DrawColumnAdd)(const DrawColumnArgs *, const WorkerThreadData *) = nullptr; @@ -358,7 +341,4 @@ public: std::vector TriFillSubsector32; void(*TriStencil)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr; void(*TriStencilClose)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr; - -private: - static LLVMDrawers *Singleton; }; diff --git a/src/r_drawt_rgba.cpp b/src/r_drawt_rgba.cpp index 29a315a8c0..57de59eba3 100644 --- a/src/r_drawt_rgba.cpp +++ b/src/r_drawt_rgba.cpp @@ -43,7 +43,7 @@ #include "r_things.h" #include "v_video.h" #include "r_draw_rgba.h" -#include "r_compiler/llvmdrawers.h" +#include "r_drawers.h" extern unsigned int dc_tspans[4][MAXHEIGHT]; extern unsigned int *dc_ctspan[4]; @@ -107,7 +107,7 @@ public: void Execute(DrawerThread *thread) override { WorkerThreadData d = ThreadData(thread); - LLVMDrawers::Instance()->DrawColumnRt1(&args, &d); + Drawers::Instance()->DrawColumnRt1(&args, &d); } FString DebugInfo() override @@ -124,7 +124,7 @@ public: \ void Execute(DrawerThread *thread) override \ { \ WorkerThreadData d = ThreadData(thread); \ - LLVMDrawers::Instance()->func(&args, &d); \ + Drawers::Instance()->func(&args, &d); \ } \ }; diff --git a/src/r_poly_triangle.cpp b/src/r_poly_triangle.cpp index f08d060e8f..ed7ab55b99 100644 --- a/src/r_poly_triangle.cpp +++ b/src/r_poly_triangle.cpp @@ -78,7 +78,7 @@ void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, TriDrawVarian if (drawargs.vcount < 3) return; - auto llvm = LLVMDrawers::Instance(); + auto llvm = Drawers::Instance(); void(*drawfunc)(const TriDrawTriangleArgs *, WorkerThreadData *); int bmode = (int)blendmode; switch (variant) diff --git a/src/r_poly_triangle.h b/src/r_poly_triangle.h index 270dda8948..1c07ce5bd0 100644 --- a/src/r_poly_triangle.h +++ b/src/r_poly_triangle.h @@ -24,7 +24,7 @@ #include "r_draw.h" #include "r_thread.h" -#include "r_compiler/llvmdrawers.h" +#include "r_drawers.h" #include "r_data/r_translate.h" #include "r_data/colormaps.h" diff --git a/src/r_swrenderer.cpp b/src/r_swrenderer.cpp index 708b465e1b..74a6da8232 100644 --- a/src/r_swrenderer.cpp +++ b/src/r_swrenderer.cpp @@ -43,7 +43,7 @@ #include "textures/textures.h" #include "r_data/voxels.h" #include "r_draw_rgba.h" -#include "r_compiler/llvmdrawers.h" +#include "r_drawers.h" #include "r_poly.h" EXTERN_CVAR(Bool, r_shadercolormaps) @@ -57,12 +57,10 @@ void R_InitRenderer(); FSoftwareRenderer::FSoftwareRenderer() { - LLVMDrawers::Create(); } FSoftwareRenderer::~FSoftwareRenderer() { - LLVMDrawers::Destroy(); } //========================================================================== diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 8a97243bb8..f4fe251e1b 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -7,5 +7,6 @@ if( WIN32 AND NOT CMAKE_SIZEOF_VOID_P MATCHES "8" ) endif() add_subdirectory( updaterevision ) add_subdirectory( zipdir ) +add_subdirectory( drawergen ) set( CROSS_EXPORTS ${CROSS_EXPORTS} PARENT_SCOPE ) diff --git a/tools/drawergen/CMakeLists.txt b/tools/drawergen/CMakeLists.txt new file mode 100644 index 0000000000..eef5a0a944 --- /dev/null +++ b/tools/drawergen/CMakeLists.txt @@ -0,0 +1,133 @@ +cmake_minimum_required( VERSION 2.8.7 ) + +include(../../precompiled_headers.cmake) + +# Path where it looks for the LLVM compiled files on Windows +set( LLVM_PRECOMPILED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../llvm" ) + +if( NOT DRAWERGEN_LIBS ) + set( DRAWERGEN_LIBS "" ) +endif() + +include_directories( . ) + +file( GLOB HEADER_FILES + *.h + ssa/*.h + fixedfunction/*.h +) + +if( NOT WIN32 ) + set( LLVM_COMPONENTS core support asmparser asmprinter bitreader bitwriter codegen ipo + irreader transformutils instrumentation profiledata runtimedyld + object instcombine linker analysis selectiondag scalaropts vectorize executionengine + mc mcdisassembler mcparser mcjit target x86asmprinter x86info x86desc x86utils x86codegen ) + + # Example LLVM_DIR folder: C:/Development/Environment/Src/llvm-3.9.0/build/lib/cmake/llvm + find_package(LLVM REQUIRED CONFIG) + message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") + message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}") + llvm_map_components_to_libnames( llvm_libs ${LLVM_COMPONENTS} ) + include_directories( ${LLVM_INCLUDE_DIRS} ) + set( DRAWERGEN_LIBS ${DRAWERGEN_LIBS} ${llvm_libs} ) +else() + set( LLVM_COMPONENTS core support asmparser asmprinter bitreader bitwriter codegen passes ipo + irreader transformutils instrumentation profiledata debuginfocodeview runtimedyld + object instcombine linker analysis selectiondag scalaropts vectorize executionengine + mc mcdisassembler mcparser mcjit target x86asmprinter x86info x86desc x86utils x86codegen ) + + include_directories( "${LLVM_PRECOMPILED_DIR}/include" ) + if( X64 ) + include_directories( "${LLVM_PRECOMPILED_DIR}/64bit-include" ) + set( llvm_libs_base "${LLVM_PRECOMPILED_DIR}/64bit-" ) + else() + include_directories( "${LLVM_PRECOMPILED_DIR}/32bit-include" ) + set( llvm_libs_base "${LLVM_PRECOMPILED_DIR}/32bit-" ) + endif() + foreach(buildtype IN ITEMS RELEASE DEBUG) + set( llvm_libs_${buildtype} "${llvm_libs_base}${buildtype}" ) + set( LLVM_${buildtype}_LIBS "" ) + foreach( llvm_module ${LLVM_COMPONENTS} ) + find_library( LLVM_${llvm_module}_LIBRARY_${buildtype} LLVM${llvm_module} PATHS ${llvm_libs_${buildtype}} ) + set( LLVM_${buildtype}_LIBS ${LLVM_${buildtype}_LIBS} ${LLVM_${llvm_module}_LIBRARY_${buildtype}} ) + endforeach( llvm_module ) + endforeach(buildtype) +endif() + +if( WIN32 ) + if( MSVC_VERSION GREATER 1399 ) + # VC 8+ adds a manifest automatically to the executable. We need to + # merge ours with it. + set( MT_MERGE ON ) + else() + set( TRUSTINFO trustinfo.rc ) + endif() +else( WIN32 ) + set( TRUSTINFO "" ) +endif() + +set (SOURCES + drawergen.cpp + ssa/ssa_bool.cpp + ssa/ssa_float.cpp + ssa/ssa_float_ptr.cpp + ssa/ssa_for_block.cpp + ssa/ssa_function.cpp + ssa/ssa_if_block.cpp + ssa/ssa_int.cpp + ssa/ssa_int_ptr.cpp + ssa/ssa_short.cpp + ssa/ssa_scope.cpp + ssa/ssa_struct_type.cpp + ssa/ssa_ubyte.cpp + ssa/ssa_ubyte_ptr.cpp + ssa/ssa_value.cpp + ssa/ssa_vec4f.cpp + ssa/ssa_vec4f_ptr.cpp + ssa/ssa_vec4i.cpp + ssa/ssa_vec4i_ptr.cpp + ssa/ssa_vec8s.cpp + ssa/ssa_vec16ub.cpp + fixedfunction/drawercodegen.cpp + fixedfunction/drawspancodegen.cpp + fixedfunction/drawwallcodegen.cpp + fixedfunction/drawcolumncodegen.cpp + fixedfunction/drawskycodegen.cpp + fixedfunction/drawtrianglecodegen.cpp +) +enable_precompiled_headers( precomp.h SOURCES ) + +if( NOT CMAKE_CROSSCOMPILING ) + add_executable( drawergen ${SOURCES} ${TRUSTINFO} ${HEADER_FILES} ) + set( CROSS_EXPORTS ${CROSS_EXPORTS} drawergen PARENT_SCOPE ) +endif() + +if( MT_MERGE ) + add_custom_command(TARGET drawergen POST_BUILD + COMMAND mt -inputresource:$ -manifest ${CMAKE_CURRENT_SOURCE_DIR}/trustinfo.txt -outputresource:$ -nologo + COMMENT "Embedding trustinfo into drawergen" ) +endif() + +# Linux - add these flags for LLVM compatibility to prevent crashing +#if ( UNIX AND NOT APPLE ) +# set( CMAKE_EXE_LINKER_FLAGS "-Wl,--exclude-libs,ALL ${CMAKE_EXE_LINKER_FLAGS}" ) +#endif() + +target_link_libraries( drawergen ${DRAWERGEN_LIBS} ) + +if( WIN32 ) + foreach(debuglib ${LLVM_DEBUG_LIBS}) + target_link_libraries( drawergen debug ${debuglib} ) + endforeach(debuglib) + foreach(releaselib ${LLVM_RELEASE_LIBS}) + target_link_libraries( drawergen optimized ${releaselib} ) + endforeach(releaselib) +endif() + +#source_group("Render Compiler" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/r_compiler/.+") +#source_group("Render Compiler\\SSA" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/r_compiler/ssa/.+") +#source_group("Render Compiler\\Fixed Function" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/r_compiler/fixedfunction/.+") + +source_group("Compiler" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/.+\\.(cpp|h)$") +source_group("Compiler\\SSA" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/ssa/.+") +source_group("Compiler\\Fixed Function" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/fixedfunction/.+") diff --git a/tools/drawergen/drawergen.cpp b/tools/drawergen/drawergen.cpp new file mode 100644 index 0000000000..dfe5fc11be --- /dev/null +++ b/tools/drawergen/drawergen.cpp @@ -0,0 +1,664 @@ +/* +** LLVM code generated drawers +** Copyright (c) 2016 Magnus Norddahl +** +** This software is provided 'as-is', without any express or implied +** warranty. In no event will the authors be held liable for any damages +** arising from the use of this software. +** +** Permission is granted to anyone to use this software for any purpose, +** including commercial applications, and to alter it and redistribute it +** freely, subject to the following restrictions: +** +** 1. The origin of this software must not be misrepresented; you must not +** claim that you wrote the original software. If you use this software +** in a product, an acknowledgment in the product documentation would be +** appreciated but is not required. +** 2. Altered source versions must be plainly marked as such, and must not be +** misrepresented as being the original software. +** 3. This notice may not be removed or altered from any source distribution. +** +*/ + +#include "precomp.h" +#include "fixedfunction/drawspancodegen.h" +#include "fixedfunction/drawwallcodegen.h" +#include "fixedfunction/drawcolumncodegen.h" +#include "fixedfunction/drawskycodegen.h" +#include "fixedfunction/drawtrianglecodegen.h" +#include "ssa/ssa_function.h" +#include "ssa/ssa_scope.h" +#include "ssa/ssa_for_block.h" +#include "ssa/ssa_if_block.h" +#include "ssa/ssa_stack.h" +#include "ssa/ssa_function.h" +#include "ssa/ssa_struct_type.h" +#include "ssa/ssa_value.h" +#include "ssa/ssa_barycentric_weight.h" +#include + +class Exception : public std::exception +{ +public: + Exception(const std::string &message) : message(message) { } + const char *what() const override { return message.c_str(); } + +private: + std::string message; +}; + +class LLVMProgram +{ +public: + LLVMProgram(); + + void CreateModule(); + std::string GenerateAssembly(std::string cpuName); + std::vector GenerateObjectFile(std::string cpuName); + std::string DumpModule(); + + llvm::LLVMContext &context() { return *mContext; } + llvm::Module *module() { return mModule.get(); } + +private: + llvm::TargetMachine *machine = nullptr; + std::unique_ptr mContext; + std::unique_ptr mModule; +}; + +class LLVMDrawers +{ +public: + LLVMDrawers(const std::string &cpuName, const std::string namePostfix); + + std::vector ObjectFile; + +private: + void CodegenDrawColumn(const char *name, DrawColumnVariant variant, DrawColumnMethod method); + void CodegenDrawSpan(const char *name, DrawSpanVariant variant); + void CodegenDrawWall(const char *name, DrawWallVariant variant, int columns); + void CodegenDrawSky(const char *name, DrawSkyVariant variant, int columns); + void CodegenDrawTriangle(const std::string &name, TriDrawVariant variant, TriBlendMode blendmode, bool truecolor); + + static llvm::Type *GetDrawColumnArgsStruct(llvm::LLVMContext &context); + static llvm::Type *GetDrawSpanArgsStruct(llvm::LLVMContext &context); + static llvm::Type *GetDrawWallArgsStruct(llvm::LLVMContext &context); + static llvm::Type *GetDrawSkyArgsStruct(llvm::LLVMContext &context); + static llvm::Type *GetWorkerThreadDataStruct(llvm::LLVMContext &context); + static llvm::Type *GetTriVertexStruct(llvm::LLVMContext &context); + static llvm::Type *GetTriMatrixStruct(llvm::LLVMContext &context); + static llvm::Type *GetTriUniformsStruct(llvm::LLVMContext &context); + static llvm::Type *GetTriDrawTriangleArgs(llvm::LLVMContext &context); + + LLVMProgram mProgram; + std::string mNamePostfix; +}; + +///////////////////////////////////////////////////////////////////////////// + +LLVMDrawers::LLVMDrawers(const std::string &cpuName, const std::string namePostfix) : mNamePostfix(namePostfix) +{ + mProgram.CreateModule(); + + CodegenDrawColumn("FillColumn", DrawColumnVariant::Fill, DrawColumnMethod::Normal); + CodegenDrawColumn("FillColumnAdd", DrawColumnVariant::FillAdd, DrawColumnMethod::Normal); + CodegenDrawColumn("FillColumnAddClamp", DrawColumnVariant::FillAddClamp, DrawColumnMethod::Normal); + CodegenDrawColumn("FillColumnSubClamp", DrawColumnVariant::FillSubClamp, DrawColumnMethod::Normal); + CodegenDrawColumn("FillColumnRevSubClamp", DrawColumnVariant::FillRevSubClamp, DrawColumnMethod::Normal); + CodegenDrawColumn("DrawColumn", DrawColumnVariant::Draw, DrawColumnMethod::Normal); + CodegenDrawColumn("DrawColumnAdd", DrawColumnVariant::DrawAdd, DrawColumnMethod::Normal); + CodegenDrawColumn("DrawColumnShaded", DrawColumnVariant::DrawShaded, DrawColumnMethod::Normal); + CodegenDrawColumn("DrawColumnAddClamp", DrawColumnVariant::DrawAddClamp, DrawColumnMethod::Normal); + CodegenDrawColumn("DrawColumnSubClamp", DrawColumnVariant::DrawSubClamp, DrawColumnMethod::Normal); + CodegenDrawColumn("DrawColumnRevSubClamp", DrawColumnVariant::DrawRevSubClamp, DrawColumnMethod::Normal); + CodegenDrawColumn("DrawColumnTranslated", DrawColumnVariant::DrawTranslated, DrawColumnMethod::Normal); + CodegenDrawColumn("DrawColumnTlatedAdd", DrawColumnVariant::DrawTlatedAdd, DrawColumnMethod::Normal); + CodegenDrawColumn("DrawColumnAddClampTranslated", DrawColumnVariant::DrawAddClampTranslated, DrawColumnMethod::Normal); + CodegenDrawColumn("DrawColumnSubClampTranslated", DrawColumnVariant::DrawSubClampTranslated, DrawColumnMethod::Normal); + CodegenDrawColumn("DrawColumnRevSubClampTranslated", DrawColumnVariant::DrawRevSubClampTranslated, DrawColumnMethod::Normal); + CodegenDrawColumn("DrawColumnRt1", DrawColumnVariant::Draw, DrawColumnMethod::Rt1); + CodegenDrawColumn("DrawColumnRt1Copy", DrawColumnVariant::DrawCopy, DrawColumnMethod::Rt1); + CodegenDrawColumn("DrawColumnRt1Add", DrawColumnVariant::DrawAdd, DrawColumnMethod::Rt1); + CodegenDrawColumn("DrawColumnRt1Shaded", DrawColumnVariant::DrawShaded, DrawColumnMethod::Rt1); + CodegenDrawColumn("DrawColumnRt1AddClamp", DrawColumnVariant::DrawAddClamp, DrawColumnMethod::Rt1); + CodegenDrawColumn("DrawColumnRt1SubClamp", DrawColumnVariant::DrawSubClamp, DrawColumnMethod::Rt1); + CodegenDrawColumn("DrawColumnRt1RevSubClamp", DrawColumnVariant::DrawRevSubClamp, DrawColumnMethod::Rt1); + CodegenDrawColumn("DrawColumnRt1Translated", DrawColumnVariant::DrawTranslated, DrawColumnMethod::Rt1); + CodegenDrawColumn("DrawColumnRt1TlatedAdd", DrawColumnVariant::DrawTlatedAdd, DrawColumnMethod::Rt1); + CodegenDrawColumn("DrawColumnRt1AddClampTranslated", DrawColumnVariant::DrawAddClampTranslated, DrawColumnMethod::Rt1); + CodegenDrawColumn("DrawColumnRt1SubClampTranslated", DrawColumnVariant::DrawSubClampTranslated, DrawColumnMethod::Rt1); + CodegenDrawColumn("DrawColumnRt1RevSubClampTranslated", DrawColumnVariant::DrawRevSubClampTranslated, DrawColumnMethod::Rt1); + CodegenDrawColumn("DrawColumnRt4", DrawColumnVariant::Draw, DrawColumnMethod::Rt4); + CodegenDrawColumn("DrawColumnRt4Copy", DrawColumnVariant::DrawCopy, DrawColumnMethod::Rt4); + CodegenDrawColumn("DrawColumnRt4Add", DrawColumnVariant::DrawAdd, DrawColumnMethod::Rt4); + CodegenDrawColumn("DrawColumnRt4Shaded", DrawColumnVariant::DrawShaded, DrawColumnMethod::Rt4); + CodegenDrawColumn("DrawColumnRt4AddClamp", DrawColumnVariant::DrawAddClamp, DrawColumnMethod::Rt4); + CodegenDrawColumn("DrawColumnRt4SubClamp", DrawColumnVariant::DrawSubClamp, DrawColumnMethod::Rt4); + CodegenDrawColumn("DrawColumnRt4RevSubClamp", DrawColumnVariant::DrawRevSubClamp, DrawColumnMethod::Rt4); + CodegenDrawColumn("DrawColumnRt4Translated", DrawColumnVariant::DrawTranslated, DrawColumnMethod::Rt4); + CodegenDrawColumn("DrawColumnRt4TlatedAdd", DrawColumnVariant::DrawTlatedAdd, DrawColumnMethod::Rt4); + CodegenDrawColumn("DrawColumnRt4AddClampTranslated", DrawColumnVariant::DrawAddClampTranslated, DrawColumnMethod::Rt4); + CodegenDrawColumn("DrawColumnRt4SubClampTranslated", DrawColumnVariant::DrawSubClampTranslated, DrawColumnMethod::Rt4); + CodegenDrawColumn("DrawColumnRt4RevSubClampTranslated", DrawColumnVariant::DrawRevSubClampTranslated, DrawColumnMethod::Rt4); + CodegenDrawSpan("DrawSpan", DrawSpanVariant::Opaque); + CodegenDrawSpan("DrawSpanMasked", DrawSpanVariant::Masked); + CodegenDrawSpan("DrawSpanTranslucent", DrawSpanVariant::Translucent); + CodegenDrawSpan("DrawSpanMaskedTranslucent", DrawSpanVariant::MaskedTranslucent); + CodegenDrawSpan("DrawSpanAddClamp", DrawSpanVariant::AddClamp); + CodegenDrawSpan("DrawSpanMaskedAddClamp", DrawSpanVariant::MaskedAddClamp); + CodegenDrawWall("vlinec1", DrawWallVariant::Opaque, 1); + CodegenDrawWall("vlinec4", DrawWallVariant::Opaque, 4); + CodegenDrawWall("mvlinec1", DrawWallVariant::Masked, 1); + CodegenDrawWall("mvlinec4", DrawWallVariant::Masked, 4); + CodegenDrawWall("tmvline1_add", DrawWallVariant::Add, 1); + CodegenDrawWall("tmvline4_add", DrawWallVariant::Add, 4); + CodegenDrawWall("tmvline1_addclamp", DrawWallVariant::AddClamp, 1); + CodegenDrawWall("tmvline4_addclamp", DrawWallVariant::AddClamp, 4); + CodegenDrawWall("tmvline1_subclamp", DrawWallVariant::SubClamp, 1); + CodegenDrawWall("tmvline4_subclamp", DrawWallVariant::SubClamp, 4); + CodegenDrawWall("tmvline1_revsubclamp", DrawWallVariant::RevSubClamp, 1); + CodegenDrawWall("tmvline4_revsubclamp", DrawWallVariant::RevSubClamp, 4); + CodegenDrawSky("DrawSky1", DrawSkyVariant::Single, 1); + CodegenDrawSky("DrawSky4", DrawSkyVariant::Single, 4); + CodegenDrawSky("DrawDoubleSky1", DrawSkyVariant::Double, 1); + CodegenDrawSky("DrawDoubleSky4", DrawSkyVariant::Double, 4); + for (int i = 0; i < NumTriBlendModes(); i++) + { + CodegenDrawTriangle("TriDrawNormal8_" + std::to_string(i), TriDrawVariant::DrawNormal, (TriBlendMode)i, false); + CodegenDrawTriangle("TriDrawNormal32_" + std::to_string(i), TriDrawVariant::DrawNormal, (TriBlendMode)i, true); + CodegenDrawTriangle("TriFillNormal8_" + std::to_string(i), TriDrawVariant::FillNormal, (TriBlendMode)i, false); + CodegenDrawTriangle("TriFillNormal32_" + std::to_string(i), TriDrawVariant::FillNormal, (TriBlendMode)i, true); + CodegenDrawTriangle("TriDrawSubsector8_" + std::to_string(i), TriDrawVariant::DrawSubsector, (TriBlendMode)i, false); + CodegenDrawTriangle("TriDrawSubsector32_" + std::to_string(i), TriDrawVariant::DrawSubsector, (TriBlendMode)i, true); + CodegenDrawTriangle("TriFillSubsector8_" + std::to_string(i), TriDrawVariant::FillSubsector, (TriBlendMode)i, false); + CodegenDrawTriangle("TriFillSubsector32_" + std::to_string(i), TriDrawVariant::FillSubsector, (TriBlendMode)i, true); + } + CodegenDrawTriangle("TriStencil", TriDrawVariant::Stencil, TriBlendMode::Copy, false); + CodegenDrawTriangle("TriStencilClose", TriDrawVariant::StencilClose, TriBlendMode::Copy, false); + + ObjectFile = mProgram.GenerateObjectFile(cpuName); +} + +void LLVMDrawers::CodegenDrawColumn(const char *name, DrawColumnVariant variant, DrawColumnMethod method) +{ + llvm::IRBuilder<> builder(mProgram.context()); + SSAScope ssa_scope(&mProgram.context(), mProgram.module(), &builder); + + SSAFunction function(name + mNamePostfix); + function.add_parameter(GetDrawColumnArgsStruct(mProgram.context())); + function.add_parameter(GetWorkerThreadDataStruct(mProgram.context())); + function.create_public(); + + DrawColumnCodegen codegen; + codegen.Generate(variant, method, function.parameter(0), function.parameter(1)); + + builder.CreateRetVoid(); + + if (llvm::verifyFunction(*function.func)) + throw Exception("verifyFunction failed for CodegenDrawColumn()"); +} + +void LLVMDrawers::CodegenDrawSpan(const char *name, DrawSpanVariant variant) +{ + llvm::IRBuilder<> builder(mProgram.context()); + SSAScope ssa_scope(&mProgram.context(), mProgram.module(), &builder); + + SSAFunction function(name + mNamePostfix); + function.add_parameter(GetDrawSpanArgsStruct(mProgram.context())); + function.create_public(); + + DrawSpanCodegen codegen; + codegen.Generate(variant, function.parameter(0)); + + builder.CreateRetVoid(); + + if (llvm::verifyFunction(*function.func)) + throw Exception("verifyFunction failed for CodegenDrawSpan()"); +} + +void LLVMDrawers::CodegenDrawWall(const char *name, DrawWallVariant variant, int columns) +{ + llvm::IRBuilder<> builder(mProgram.context()); + SSAScope ssa_scope(&mProgram.context(), mProgram.module(), &builder); + + SSAFunction function(name + mNamePostfix); + function.add_parameter(GetDrawWallArgsStruct(mProgram.context())); + function.add_parameter(GetWorkerThreadDataStruct(mProgram.context())); + function.create_public(); + + DrawWallCodegen codegen; + codegen.Generate(variant, columns == 4, function.parameter(0), function.parameter(1)); + + builder.CreateRetVoid(); + + if (llvm::verifyFunction(*function.func)) + throw Exception("verifyFunction failed for CodegenDrawWall()"); +} + +void LLVMDrawers::CodegenDrawSky(const char *name, DrawSkyVariant variant, int columns) +{ + llvm::IRBuilder<> builder(mProgram.context()); + SSAScope ssa_scope(&mProgram.context(), mProgram.module(), &builder); + + SSAFunction function(name + mNamePostfix); + function.add_parameter(GetDrawSkyArgsStruct(mProgram.context())); + function.add_parameter(GetWorkerThreadDataStruct(mProgram.context())); + function.create_public(); + + DrawSkyCodegen codegen; + codegen.Generate(variant, columns == 4, function.parameter(0), function.parameter(1)); + + builder.CreateRetVoid(); + + if (llvm::verifyFunction(*function.func)) + throw Exception("verifyFunction failed for CodegenDrawSky()"); +} + +void LLVMDrawers::CodegenDrawTriangle(const std::string &name, TriDrawVariant variant, TriBlendMode blendmode, bool truecolor) +{ + llvm::IRBuilder<> builder(mProgram.context()); + SSAScope ssa_scope(&mProgram.context(), mProgram.module(), &builder); + + SSAFunction function(name + mNamePostfix); + function.add_parameter(GetTriDrawTriangleArgs(mProgram.context())); + function.add_parameter(GetWorkerThreadDataStruct(mProgram.context())); + function.create_public(); + + DrawTriangleCodegen codegen; + codegen.Generate(variant, blendmode, truecolor, function.parameter(0), function.parameter(1)); + + builder.CreateRetVoid(); + + if (llvm::verifyFunction(*function.func)) + throw Exception(std::string("verifyFunction failed for CodegenDrawTriangle(") + std::to_string((int)variant) + ", " + std::to_string((int)blendmode) + ", " + std::to_string((int)truecolor) + ")"); +} + +llvm::Type *LLVMDrawers::GetDrawColumnArgsStruct(llvm::LLVMContext &context) +{ + std::vector elements; + elements.push_back(llvm::Type::getInt8PtrTy(context)); // uint32_t *dest; + elements.push_back(llvm::Type::getInt8PtrTy(context)); // const uint32_t *source; + elements.push_back(llvm::Type::getInt8PtrTy(context)); // const uint32_t *source2; + elements.push_back(llvm::Type::getInt8PtrTy(context)); // uint8_t *colormap; + elements.push_back(llvm::Type::getInt8PtrTy(context)); // uint8_t *translation; + elements.push_back(llvm::Type::getInt8PtrTy(context)); // const uint32_t *basecolors; + elements.push_back(llvm::Type::getInt32Ty(context)); // int32_t pitch; + elements.push_back(llvm::Type::getInt32Ty(context)); // int32_t count; + elements.push_back(llvm::Type::getInt32Ty(context)); // int32_t dest_y; + elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t iscale; + elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t texturefracx; + elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t textureheight; + elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t texturefrac; + elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t light; + elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t color; + elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t srccolor; + elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t srcalpha; + elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t destalpha; + elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_alpha; + elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_red; + elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_green; + elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_blue; + elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t fade_alpha; + elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t fade_red; + elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t fade_green; + elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t fade_blue; + elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t desaturate; + elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t flags; + return llvm::StructType::create(context, elements, "DrawColumnArgs", false)->getPointerTo(); +} + +llvm::Type *LLVMDrawers::GetDrawSpanArgsStruct(llvm::LLVMContext &context) +{ + std::vector elements; + elements.push_back(llvm::Type::getInt8PtrTy(context)); // uint8_t *destorg; + elements.push_back(llvm::Type::getInt8PtrTy(context)); // const uint32_t *source; + elements.push_back(llvm::Type::getInt32Ty(context)); // int32_t destpitch; + elements.push_back(llvm::Type::getInt32Ty(context)); // int32_t xfrac; + elements.push_back(llvm::Type::getInt32Ty(context)); // int32_t yfrac; + elements.push_back(llvm::Type::getInt32Ty(context)); // int32_t xstep; + elements.push_back(llvm::Type::getInt32Ty(context)); // int32_t ystep; + elements.push_back(llvm::Type::getInt32Ty(context)); // int32_t x1; + elements.push_back(llvm::Type::getInt32Ty(context)); // int32_t x2; + elements.push_back(llvm::Type::getInt32Ty(context)); // int32_t y; + elements.push_back(llvm::Type::getInt32Ty(context)); // int32_t xbits; + elements.push_back(llvm::Type::getInt32Ty(context)); // int32_t ybits; + elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t light; + elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t srcalpha; + elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t destalpha; + elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_alpha; + elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_red; + elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_green; + elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_blue; + elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t fade_alpha; + elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t fade_red; + elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t fade_green; + elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t fade_blue; + elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t desaturate; + elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t flags; + return llvm::StructType::create(context, elements, "DrawSpanArgs", false)->getPointerTo(); +} + +llvm::Type *LLVMDrawers::GetDrawWallArgsStruct(llvm::LLVMContext &context) +{ + std::vector elements; + elements.push_back(llvm::Type::getInt8PtrTy(context)); + for (int i = 0; i < 8; i++) + elements.push_back(llvm::Type::getInt8PtrTy(context)); + for (int i = 0; i < 25; i++) + elements.push_back(llvm::Type::getInt32Ty(context)); + elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_alpha; + elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_red; + elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_green; + elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_blue; + elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t fade_alpha; + elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t fade_red; + elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t fade_green; + elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t fade_blue; + elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t desaturate; + elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t flags; + return llvm::StructType::create(context, elements, "DrawWallArgs", false)->getPointerTo(); +} + +llvm::Type *LLVMDrawers::GetDrawSkyArgsStruct(llvm::LLVMContext &context) +{ + std::vector elements; + elements.push_back(llvm::Type::getInt8PtrTy(context)); + for (int i = 0; i < 8; i++) + elements.push_back(llvm::Type::getInt8PtrTy(context)); + for (int i = 0; i < 15; i++) + elements.push_back(llvm::Type::getInt32Ty(context)); + return llvm::StructType::create(context, elements, "DrawSkyArgs", false)->getPointerTo(); +} + +llvm::Type *LLVMDrawers::GetWorkerThreadDataStruct(llvm::LLVMContext &context) +{ + std::vector elements; + for (int i = 0; i < 4; i++) + elements.push_back(llvm::Type::getInt32Ty(context)); + elements.push_back(llvm::Type::getInt8PtrTy(context)); + return llvm::StructType::create(context, elements, "ThreadData", false)->getPointerTo(); +} + +llvm::Type *LLVMDrawers::GetTriVertexStruct(llvm::LLVMContext &context) +{ + std::vector elements; + for (int i = 0; i < 4 + TriVertex::NumVarying; i++) + elements.push_back(llvm::Type::getFloatTy(context)); + return llvm::StructType::create(context, elements, "TriVertex", false)->getPointerTo(); +} + +llvm::Type *LLVMDrawers::GetTriMatrixStruct(llvm::LLVMContext &context) +{ + std::vector elements; + for (int i = 0; i < 4 * 4; i++) + elements.push_back(llvm::Type::getFloatTy(context)); + return llvm::StructType::create(context, elements, "TriMatrix", false)->getPointerTo(); +} + +llvm::Type *LLVMDrawers::GetTriUniformsStruct(llvm::LLVMContext &context) +{ + std::vector elements; + elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t light; + elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t subsectorDepth; + elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t color; + elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t srcalpha; + elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t destalpha; + elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_alpha; + elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_red; + elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_green; + elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_blue; + elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t fade_alpha; + elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t fade_red; + elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t fade_green; + elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t fade_blue; + elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t desaturate; + elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t flags; + elements.push_back(GetTriMatrixStruct(context)); // TriMatrix objectToClip + return llvm::StructType::create(context, elements, "TriUniforms", false)->getPointerTo(); +} + +llvm::Type *LLVMDrawers::GetTriDrawTriangleArgs(llvm::LLVMContext &context) +{ + std::vector elements; + elements.push_back(llvm::Type::getInt8PtrTy(context)); // uint8_t *dest; + elements.push_back(llvm::Type::getInt32Ty(context)); // int32_t pitch; + elements.push_back(GetTriVertexStruct(context)); // TriVertex *v1; + elements.push_back(GetTriVertexStruct(context)); // TriVertex *v2; + elements.push_back(GetTriVertexStruct(context)); // TriVertex *v3; + elements.push_back(llvm::Type::getInt32Ty(context)); // int32_t clipleft; + elements.push_back(llvm::Type::getInt32Ty(context)); // int32_t clipright; + elements.push_back(llvm::Type::getInt32Ty(context)); // int32_t cliptop; + elements.push_back(llvm::Type::getInt32Ty(context)); // int32_t clipbottom; + elements.push_back(llvm::Type::getInt8PtrTy(context)); // const uint8_t *texturePixels; + elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t textureWidth; + elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t textureHeight; + elements.push_back(llvm::Type::getInt8PtrTy(context)); // const uint8_t *translation; + elements.push_back(GetTriUniformsStruct(context)); // const TriUniforms *uniforms; + elements.push_back(llvm::Type::getInt8PtrTy(context)); // uint8_t *stencilValues; + elements.push_back(llvm::Type::getInt32PtrTy(context)); // uint32_t *stencilMasks; + elements.push_back(llvm::Type::getInt32Ty(context)); // int32_t stencilPitch; + elements.push_back(llvm::Type::getInt8Ty(context)); // uint8_t stencilTestValue; + elements.push_back(llvm::Type::getInt8Ty(context)); // uint8_t stencilWriteValue; + elements.push_back(llvm::Type::getInt32PtrTy(context)); // uint32_t *subsectorGBuffer; + elements.push_back(llvm::Type::getInt8PtrTy(context)); // const uint8_t *colormaps; + elements.push_back(llvm::Type::getInt8PtrTy(context)); // const uint8_t *RGB32k; + elements.push_back(llvm::Type::getInt8PtrTy(context)); // const uint8_t *BaseColors; + return llvm::StructType::create(context, elements, "TriDrawTriangle", false)->getPointerTo(); +} + +///////////////////////////////////////////////////////////////////////////// + +LLVMProgram::LLVMProgram() +{ + mContext = std::make_unique(); +} + +void LLVMProgram::CreateModule() +{ + mModule = std::make_unique("render", context()); +} + +std::string LLVMProgram::GenerateAssembly(std::string cpuName) +{ + using namespace llvm; + + std::string errorstring; + + llvm::Module *module = mModule.get(); + EngineBuilder engineBuilder(std::move(mModule)); + engineBuilder.setErrorStr(&errorstring); + engineBuilder.setOptLevel(CodeGenOpt::Aggressive); + engineBuilder.setEngineKind(EngineKind::JIT); + engineBuilder.setMCPU(cpuName); + machine = engineBuilder.selectTarget(); + if (!machine) + throw Exception("Could not create LLVM target machine"); + +#if LLVM_VERSION_MAJOR < 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 8) + std::string targetTriple = machine->getTargetTriple(); +#else + std::string targetTriple = machine->getTargetTriple().getTriple(); +#endif + + module->setTargetTriple(targetTriple); +#if LLVM_VERSION_MAJOR < 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 8) + module->setDataLayout(new DataLayout(*machine->getSubtargetImpl()->getDataLayout())); +#else + module->setDataLayout(machine->createDataLayout()); +#endif + + legacy::FunctionPassManager PerFunctionPasses(module); + legacy::PassManager PerModulePasses; + +#if LLVM_VERSION_MAJOR > 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 8) + PerFunctionPasses.add(createTargetTransformInfoWrapperPass(machine->getTargetIRAnalysis())); + PerModulePasses.add(createTargetTransformInfoWrapperPass(machine->getTargetIRAnalysis())); +#endif + + SmallString<16 * 1024> str; +#if LLVM_VERSION_MAJOR < 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 8) + raw_svector_ostream vecstream(str); + formatted_raw_ostream stream(vecstream); +#else + raw_svector_ostream stream(str); +#endif + machine->addPassesToEmitFile(PerModulePasses, stream, TargetMachine::CGFT_AssemblyFile); + + PassManagerBuilder passManagerBuilder; + passManagerBuilder.OptLevel = 3; + passManagerBuilder.SizeLevel = 0; + passManagerBuilder.Inliner = createFunctionInliningPass(); + passManagerBuilder.SLPVectorize = true; + passManagerBuilder.LoopVectorize = true; + passManagerBuilder.LoadCombine = true; + passManagerBuilder.populateModulePassManager(PerModulePasses); + passManagerBuilder.populateFunctionPassManager(PerFunctionPasses); + + // Run function passes: + PerFunctionPasses.doInitialization(); + for (llvm::Function &func : *module) + { + if (!func.isDeclaration()) + PerFunctionPasses.run(func); + } + PerFunctionPasses.doFinalization(); + + // Run module passes: + PerModulePasses.run(*module); + + return str.c_str(); +} + +std::vector LLVMProgram::GenerateObjectFile(std::string cpuName) +{ + using namespace llvm; + + std::string errorstring; + + llvm::Module *module = mModule.get(); + EngineBuilder engineBuilder(std::move(mModule)); + engineBuilder.setErrorStr(&errorstring); + engineBuilder.setOptLevel(CodeGenOpt::Aggressive); + engineBuilder.setEngineKind(EngineKind::JIT); + engineBuilder.setMCPU(cpuName); + machine = engineBuilder.selectTarget(); + if (!machine) + throw Exception("Could not create LLVM target machine"); + +#if LLVM_VERSION_MAJOR < 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 8) + std::string targetTriple = machine->getTargetTriple(); +#else + std::string targetTriple = machine->getTargetTriple().getTriple(); +#endif + + module->setTargetTriple(targetTriple); +#if LLVM_VERSION_MAJOR < 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 8) + module->setDataLayout(new DataLayout(*machine->getSubtargetImpl()->getDataLayout())); +#else + module->setDataLayout(machine->createDataLayout()); +#endif + + legacy::FunctionPassManager PerFunctionPasses(module); + legacy::PassManager PerModulePasses; + +#if LLVM_VERSION_MAJOR > 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 8) + PerFunctionPasses.add(createTargetTransformInfoWrapperPass(machine->getTargetIRAnalysis())); + PerModulePasses.add(createTargetTransformInfoWrapperPass(machine->getTargetIRAnalysis())); +#endif + + SmallString<16 * 1024> str; +#if LLVM_VERSION_MAJOR < 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 8) + raw_svector_ostream vecstream(str); + formatted_raw_ostream stream(vecstream); +#else + raw_svector_ostream stream(str); +#endif + machine->addPassesToEmitFile(PerModulePasses, stream, TargetMachine::CGFT_ObjectFile); + + PassManagerBuilder passManagerBuilder; + passManagerBuilder.OptLevel = 3; + passManagerBuilder.SizeLevel = 0; + passManagerBuilder.Inliner = createFunctionInliningPass(); + passManagerBuilder.SLPVectorize = true; + passManagerBuilder.LoopVectorize = true; + passManagerBuilder.LoadCombine = true; + passManagerBuilder.populateModulePassManager(PerModulePasses); + passManagerBuilder.populateFunctionPassManager(PerFunctionPasses); + + // Run function passes: + PerFunctionPasses.doInitialization(); + for (llvm::Function &func : *module) + { + if (!func.isDeclaration()) + PerFunctionPasses.run(func); + } + PerFunctionPasses.doFinalization(); + + // Run module passes: + PerModulePasses.run(*module); + + // Return the resulting object file + std::vector data; + data.resize(str.size()); + memcpy(data.data(), str.data(), data.size()); + return data; +} + +std::string LLVMProgram::DumpModule() +{ + std::string str; + llvm::raw_string_ostream stream(str); +#if LLVM_VERSION_MAJOR < 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 8) + mModule->print(stream, nullptr); +#else + mModule->print(stream, nullptr, false, true); +#endif + return stream.str(); +} + +///////////////////////////////////////////////////////////////////////////// + +int main(int argc, char **argv) +{ + if (argc != 2) + { + std::cerr << "Usage: " << argv[0] << "" << std::endl; + return 1; + } + + llvm::install_fatal_error_handler([](void *user_data, const std::string& reason, bool gen_crash_diag) + { + std::cerr << "LLVM fatal error: " << reason; + exit(1); + }); + + llvm::InitializeNativeTarget(); + llvm::InitializeNativeTargetAsmPrinter(); + + std::string cpuName = "pentium4"; + std::cout << "Compiling drawer code for " << cpuName << ".." << std::endl; + + LLVMDrawers drawersSSE2(cpuName, "_SSE2"); + + FILE *file = fopen(argv[1], "wb"); + if (file == nullptr) + { + std::cerr << "Unable to open " << argv[1] << " for writing." << std::endl; + return 1; + } + + int result = fwrite(drawersSSE2.ObjectFile.data(), drawersSSE2.ObjectFile.size(), 1, file); + fclose(file); + + if (result != 1) + { + std::cerr << "Could not write data to " << argv[1] << std::endl; + return 1; + } + + //LLVMDrawers drawersSSE4("core2"); + //LLVMDrawers drawersAVX("sandybridge"); + //LLVMDrawers drawersAVX2("haswell"); + + return 0; +} diff --git a/src/r_compiler/fixedfunction/drawcolumncodegen.cpp b/tools/drawergen/fixedfunction/drawcolumncodegen.cpp similarity index 96% rename from src/r_compiler/fixedfunction/drawcolumncodegen.cpp rename to tools/drawergen/fixedfunction/drawcolumncodegen.cpp index 45a75cdcb8..0ce34c83c9 100644 --- a/src/r_compiler/fixedfunction/drawcolumncodegen.cpp +++ b/tools/drawergen/fixedfunction/drawcolumncodegen.cpp @@ -20,17 +20,16 @@ ** */ -#include "i_system.h" -#include "r_compiler/llvm_include.h" -#include "r_compiler/fixedfunction/drawcolumncodegen.h" -#include "r_compiler/ssa/ssa_function.h" -#include "r_compiler/ssa/ssa_scope.h" -#include "r_compiler/ssa/ssa_for_block.h" -#include "r_compiler/ssa/ssa_if_block.h" -#include "r_compiler/ssa/ssa_stack.h" -#include "r_compiler/ssa/ssa_function.h" -#include "r_compiler/ssa/ssa_struct_type.h" -#include "r_compiler/ssa/ssa_value.h" +#include "precomp.h" +#include "fixedfunction/drawcolumncodegen.h" +#include "ssa/ssa_function.h" +#include "ssa/ssa_scope.h" +#include "ssa/ssa_for_block.h" +#include "ssa/ssa_if_block.h" +#include "ssa/ssa_stack.h" +#include "ssa/ssa_function.h" +#include "ssa/ssa_struct_type.h" +#include "ssa/ssa_value.h" void DrawColumnCodegen::Generate(DrawColumnVariant variant, DrawColumnMethod method, SSAValue args, SSAValue thread_data) { diff --git a/src/r_compiler/fixedfunction/drawcolumncodegen.h b/tools/drawergen/fixedfunction/drawcolumncodegen.h similarity index 100% rename from src/r_compiler/fixedfunction/drawcolumncodegen.h rename to tools/drawergen/fixedfunction/drawcolumncodegen.h diff --git a/src/r_compiler/fixedfunction/drawercodegen.cpp b/tools/drawergen/fixedfunction/drawercodegen.cpp similarity index 92% rename from src/r_compiler/fixedfunction/drawercodegen.cpp rename to tools/drawergen/fixedfunction/drawercodegen.cpp index 65b726b934..c1d24f5940 100644 --- a/src/r_compiler/fixedfunction/drawercodegen.cpp +++ b/tools/drawergen/fixedfunction/drawercodegen.cpp @@ -20,17 +20,16 @@ ** */ -#include "i_system.h" -#include "r_compiler/llvm_include.h" -#include "r_compiler/fixedfunction/drawercodegen.h" -#include "r_compiler/ssa/ssa_function.h" -#include "r_compiler/ssa/ssa_scope.h" -#include "r_compiler/ssa/ssa_for_block.h" -#include "r_compiler/ssa/ssa_if_block.h" -#include "r_compiler/ssa/ssa_stack.h" -#include "r_compiler/ssa/ssa_function.h" -#include "r_compiler/ssa/ssa_struct_type.h" -#include "r_compiler/ssa/ssa_value.h" +#include "precomp.h" +#include "fixedfunction/drawercodegen.h" +#include "ssa/ssa_function.h" +#include "ssa/ssa_scope.h" +#include "ssa/ssa_for_block.h" +#include "ssa/ssa_if_block.h" +#include "ssa/ssa_stack.h" +#include "ssa/ssa_function.h" +#include "ssa/ssa_struct_type.h" +#include "ssa/ssa_value.h" SSABool DrawerCodegen::line_skipped_by_thread(SSAInt line, SSAWorkerThread thread) { diff --git a/src/r_compiler/fixedfunction/drawercodegen.h b/tools/drawergen/fixedfunction/drawercodegen.h similarity index 81% rename from src/r_compiler/fixedfunction/drawercodegen.h rename to tools/drawergen/fixedfunction/drawercodegen.h index ef6e8d11ef..8404f3acd9 100644 --- a/src/r_compiler/fixedfunction/drawercodegen.h +++ b/tools/drawergen/fixedfunction/drawercodegen.h @@ -22,22 +22,22 @@ #pragma once -#include "r_compiler/llvmdrawers.h" -#include "r_compiler/ssa/ssa_value.h" -#include "r_compiler/ssa/ssa_vec4f.h" -#include "r_compiler/ssa/ssa_vec4i.h" -#include "r_compiler/ssa/ssa_vec8s.h" -#include "r_compiler/ssa/ssa_vec16ub.h" -#include "r_compiler/ssa/ssa_int.h" -#include "r_compiler/ssa/ssa_int_ptr.h" -#include "r_compiler/ssa/ssa_short.h" -#include "r_compiler/ssa/ssa_ubyte_ptr.h" -#include "r_compiler/ssa/ssa_vec4f_ptr.h" -#include "r_compiler/ssa/ssa_vec4i_ptr.h" -#include "r_compiler/ssa/ssa_stack.h" -#include "r_compiler/ssa/ssa_bool.h" -#include "r_compiler/ssa/ssa_barycentric_weight.h" -#include "r_compiler/llvm_include.h" +#include "precomp.h" +#include "ssa/ssa_value.h" +#include "ssa/ssa_vec4f.h" +#include "ssa/ssa_vec4i.h" +#include "ssa/ssa_vec8s.h" +#include "ssa/ssa_vec16ub.h" +#include "ssa/ssa_int.h" +#include "ssa/ssa_int_ptr.h" +#include "ssa/ssa_short.h" +#include "ssa/ssa_ubyte_ptr.h" +#include "ssa/ssa_vec4f_ptr.h" +#include "ssa/ssa_vec4i_ptr.h" +#include "ssa/ssa_stack.h" +#include "ssa/ssa_bool.h" +#include "ssa/ssa_barycentric_weight.h" +#include "llvm_include.h" class SSAWorkerThread { @@ -90,3 +90,6 @@ public: // Calculates the final alpha values to be used when combined with the source texture alpha channel SSAInt calc_blend_bgalpha(SSAVec4i fg, SSAInt destalpha); }; + +#define FRACBITS 16 +#define FRACUNIT (1< + +1 RT_MANIFEST "trustinfo.txt" diff --git a/tools/drawergen/trustinfo.txt b/tools/drawergen/trustinfo.txt new file mode 100644 index 0000000000..5216df6503 --- /dev/null +++ b/tools/drawergen/trustinfo.txt @@ -0,0 +1,16 @@ + + + + + Drawergen for the ZDoom source build process. + + + + + + + +