Create drawergen tool

This commit is contained in:
Magnus Norddahl 2016-11-28 17:31:56 +01:00
parent ccafe27b22
commit e9e7839133
72 changed files with 1407 additions and 1108 deletions

2
.gitignore vendored
View file

@ -48,3 +48,5 @@
/build_vc2015-64 /build_vc2015-64
/build /build
/llvm /llvm
/src/r_drawersasm.obj
/src/r_drawersasm.o

View file

@ -293,47 +293,6 @@ if( NOT NO_OPENAL )
endif() endif()
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 ) if( NOT NO_FMOD )
# Search for FMOD include files # Search for FMOD include files
if( NOT WIN32 ) 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}" ) set( CMAKE_EXE_LINKER_FLAGS "-stdlib=libc++ ${CMAKE_EXE_LINKER_FLAGS}" )
endif () 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. # Remove extra warnings when using the official DirectX headers.
# Also, TDM-GCC 4.4.0 no longer accepts glibc-style printf formats as valid, # 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. # 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} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
DEPENDS updaterevision ) 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 # Libraries ZDoom needs
message( STATUS "Fluid synth libs: ${FLUIDSYNTH_LIBRARIES}" ) message( STATUS "Fluid synth libs: ${FLUIDSYNTH_LIBRARIES}" )
@ -933,9 +901,6 @@ file( GLOB HEADER_FILES
posix/*.h posix/*.h
posix/cocoa/*.h posix/cocoa/*.h
posix/sdl/*.h posix/sdl/*.h
r_compiler/*.h
r_compiler/ssa/*.h
r_compiler/fixedfunction/*.h
r_data/*.h r_data/*.h
resourcefiles/*.h resourcefiles/*.h
sfmt/*.h sfmt/*.h
@ -1083,6 +1048,7 @@ set( FASTMATH_PCH_SOURCES
r_draw_rgba.cpp r_draw_rgba.cpp
r_drawt.cpp r_drawt.cpp
r_drawt_rgba.cpp r_drawt_rgba.cpp
r_drawers.cpp
r_thread.cpp r_thread.cpp
r_main.cpp r_main.cpp
r_plane.cpp r_plane.cpp
@ -1485,33 +1451,6 @@ set (PCH_SOURCES
fragglescript/t_spec.cpp fragglescript/t_spec.cpp
fragglescript/t_variable.cpp fragglescript/t_variable.cpp
fragglescript/t_cmd.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/sprites.cpp
r_data/voxels.cpp r_data/voxels.cpp
r_data/renderstyle.cpp r_data/renderstyle.cpp
@ -1528,6 +1467,16 @@ set (PCH_SOURCES
) )
enable_precompiled_headers( g_pch.h 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 add_executable( zdoom WIN32 MACOSX_BUNDLE
${HEADER_FILES} ${HEADER_FILES}
${NOT_COMPILED_SOURCE_FILES} ${NOT_COMPILED_SOURCE_FILES}
@ -1557,8 +1506,11 @@ add_executable( zdoom WIN32 MACOSX_BUNDLE
math/tanh.c math/tanh.c
math/fastsin.cpp math/fastsin.cpp
zzautozend.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( ${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( 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" ) 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 ) 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( . include_directories( .
g_doom g_doom
g_heretic g_heretic
@ -1608,7 +1551,7 @@ include_directories( .
${CMAKE_BINARY_DIR}/gdtoa ${CMAKE_BINARY_DIR}/gdtoa
${SYSTEM_SOURCES_DIR} ) ${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 # Due to some quirks, we need to do this in this order
if( NOT ZDOOM_OUTPUT_OLDSTYLE ) 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\\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 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 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("Resource Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/resourcefiles/.+")
source_group("POSIX Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/posix/.+") source_group("POSIX Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/posix/.+")
source_group("Cocoa Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/posix/cocoa/.+") source_group("Cocoa Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/posix/cocoa/.+")

View file

@ -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<typename Func>
Func *GetProcAddress(const std::string &name) { return reinterpret_cast<Func*>(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<llvm::LLVMContext> mContext;
std::unique_ptr<llvm::Module> mModule;
std::unique_ptr<llvm::ExecutionEngine> 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<void(const DrawColumnArgs *, const WorkerThreadData *)>("FillColumn");
FillColumnAdd = mProgram.GetProcAddress<void(const DrawColumnArgs *, const WorkerThreadData *)>("FillColumnAdd");
FillColumnAddClamp = mProgram.GetProcAddress<void(const DrawColumnArgs *, const WorkerThreadData *)>("FillColumnAddClamp");
FillColumnSubClamp = mProgram.GetProcAddress<void(const DrawColumnArgs *, const WorkerThreadData *)>("FillColumnSubClamp");
FillColumnRevSubClamp = mProgram.GetProcAddress<void(const DrawColumnArgs *, const WorkerThreadData *)>("FillColumnRevSubClamp");
DrawColumn = mProgram.GetProcAddress<void(const DrawColumnArgs *, const WorkerThreadData *)>("DrawColumn");
DrawColumnAdd = mProgram.GetProcAddress<void(const DrawColumnArgs *, const WorkerThreadData *)>("DrawColumnAdd");
DrawColumnShaded = mProgram.GetProcAddress<void(const DrawColumnArgs *, const WorkerThreadData *)>("DrawColumnShaded");
DrawColumnAddClamp = mProgram.GetProcAddress<void(const DrawColumnArgs *, const WorkerThreadData *)>("DrawColumnAddClamp");
DrawColumnSubClamp = mProgram.GetProcAddress<void(const DrawColumnArgs *, const WorkerThreadData *)>("DrawColumnSubClamp");
DrawColumnRevSubClamp = mProgram.GetProcAddress<void(const DrawColumnArgs *, const WorkerThreadData *)>("DrawColumnRevSubClamp");
DrawColumnTranslated = mProgram.GetProcAddress<void(const DrawColumnArgs *, const WorkerThreadData *)>("DrawColumnTranslated");
DrawColumnTlatedAdd = mProgram.GetProcAddress<void(const DrawColumnArgs *, const WorkerThreadData *)>("DrawColumnTlatedAdd");
DrawColumnAddClampTranslated = mProgram.GetProcAddress<void(const DrawColumnArgs *, const WorkerThreadData *)>("DrawColumnAddClampTranslated");
DrawColumnSubClampTranslated = mProgram.GetProcAddress<void(const DrawColumnArgs *, const WorkerThreadData *)>("DrawColumnSubClampTranslated");
DrawColumnRevSubClampTranslated = mProgram.GetProcAddress<void(const DrawColumnArgs *, const WorkerThreadData *)>("DrawColumnRevSubClampTranslated");
DrawColumnRt1 = mProgram.GetProcAddress<void(const DrawColumnArgs *, const WorkerThreadData *)>("DrawColumnRt1");
DrawColumnRt1Copy = mProgram.GetProcAddress<void(const DrawColumnArgs *, const WorkerThreadData *)>("DrawColumnRt1Copy");
DrawColumnRt1Add = mProgram.GetProcAddress<void(const DrawColumnArgs *, const WorkerThreadData *)>("DrawColumnRt1Add");
DrawColumnRt1Shaded = mProgram.GetProcAddress<void(const DrawColumnArgs *, const WorkerThreadData *)>("DrawColumnRt1Shaded");
DrawColumnRt1AddClamp = mProgram.GetProcAddress<void(const DrawColumnArgs *, const WorkerThreadData *)>("DrawColumnRt1AddClamp");
DrawColumnRt1SubClamp = mProgram.GetProcAddress<void(const DrawColumnArgs *, const WorkerThreadData *)>("DrawColumnRt1SubClamp");
DrawColumnRt1RevSubClamp = mProgram.GetProcAddress<void(const DrawColumnArgs *, const WorkerThreadData *)>("DrawColumnRt1RevSubClamp");
DrawColumnRt1Translated = mProgram.GetProcAddress<void(const DrawColumnArgs *, const WorkerThreadData *)>("DrawColumnRt1Translated");
DrawColumnRt1TlatedAdd = mProgram.GetProcAddress<void(const DrawColumnArgs *, const WorkerThreadData *)>("DrawColumnRt1TlatedAdd");
DrawColumnRt1AddClampTranslated = mProgram.GetProcAddress<void(const DrawColumnArgs *, const WorkerThreadData *)>("DrawColumnRt1AddClampTranslated");
DrawColumnRt1SubClampTranslated = mProgram.GetProcAddress<void(const DrawColumnArgs *, const WorkerThreadData *)>("DrawColumnRt1SubClampTranslated");
DrawColumnRt1RevSubClampTranslated = mProgram.GetProcAddress<void(const DrawColumnArgs *, const WorkerThreadData *)>("DrawColumnRt1RevSubClampTranslated");
DrawColumnRt4 = mProgram.GetProcAddress<void(const DrawColumnArgs *, const WorkerThreadData *)>("DrawColumnRt4");
DrawColumnRt4Copy = mProgram.GetProcAddress<void(const DrawColumnArgs *, const WorkerThreadData *)>("DrawColumnRt4Copy");
DrawColumnRt4Add = mProgram.GetProcAddress<void(const DrawColumnArgs *, const WorkerThreadData *)>("DrawColumnRt4Add");
DrawColumnRt4Shaded = mProgram.GetProcAddress<void(const DrawColumnArgs *, const WorkerThreadData *)>("DrawColumnRt4Shaded");
DrawColumnRt4AddClamp = mProgram.GetProcAddress<void(const DrawColumnArgs *, const WorkerThreadData *)>("DrawColumnRt4AddClamp");
DrawColumnRt4SubClamp = mProgram.GetProcAddress<void(const DrawColumnArgs *, const WorkerThreadData *)>("DrawColumnRt4SubClamp");
DrawColumnRt4RevSubClamp = mProgram.GetProcAddress<void(const DrawColumnArgs *, const WorkerThreadData *)>("DrawColumnRt4RevSubClamp");
DrawColumnRt4Translated = mProgram.GetProcAddress<void(const DrawColumnArgs *, const WorkerThreadData *)>("DrawColumnRt4Translated");
DrawColumnRt4TlatedAdd = mProgram.GetProcAddress<void(const DrawColumnArgs *, const WorkerThreadData *)>("DrawColumnRt4TlatedAdd");
DrawColumnRt4AddClampTranslated = mProgram.GetProcAddress<void(const DrawColumnArgs *, const WorkerThreadData *)>("DrawColumnRt4AddClampTranslated");
DrawColumnRt4SubClampTranslated = mProgram.GetProcAddress<void(const DrawColumnArgs *, const WorkerThreadData *)>("DrawColumnRt4SubClampTranslated");
DrawColumnRt4RevSubClampTranslated = mProgram.GetProcAddress<void(const DrawColumnArgs *, const WorkerThreadData *)>("DrawColumnRt4RevSubClampTranslated");
DrawSpan = mProgram.GetProcAddress<void(const DrawSpanArgs *)>("DrawSpan");
DrawSpanMasked = mProgram.GetProcAddress<void(const DrawSpanArgs *)>("DrawSpanMasked");
DrawSpanTranslucent = mProgram.GetProcAddress<void(const DrawSpanArgs *)>("DrawSpanTranslucent");
DrawSpanMaskedTranslucent = mProgram.GetProcAddress<void(const DrawSpanArgs *)>("DrawSpanMaskedTranslucent");
DrawSpanAddClamp = mProgram.GetProcAddress<void(const DrawSpanArgs *)>("DrawSpanAddClamp");
DrawSpanMaskedAddClamp = mProgram.GetProcAddress<void(const DrawSpanArgs *)>("DrawSpanMaskedAddClamp");
vlinec1 = mProgram.GetProcAddress<void(const DrawWallArgs *, const WorkerThreadData *)>("vlinec1");
vlinec4 = mProgram.GetProcAddress<void(const DrawWallArgs *, const WorkerThreadData *)>("vlinec4");
mvlinec1 = mProgram.GetProcAddress<void(const DrawWallArgs *, const WorkerThreadData *)>("mvlinec1");
mvlinec4 = mProgram.GetProcAddress<void(const DrawWallArgs *, const WorkerThreadData *)>("mvlinec4");
tmvline1_add = mProgram.GetProcAddress<void(const DrawWallArgs *, const WorkerThreadData *)>("tmvline1_add");
tmvline4_add = mProgram.GetProcAddress<void(const DrawWallArgs *, const WorkerThreadData *)>("tmvline4_add");
tmvline1_addclamp = mProgram.GetProcAddress<void(const DrawWallArgs *, const WorkerThreadData *)>("tmvline1_addclamp");
tmvline4_addclamp = mProgram.GetProcAddress<void(const DrawWallArgs *, const WorkerThreadData *)>("tmvline4_addclamp");
tmvline1_subclamp = mProgram.GetProcAddress<void(const DrawWallArgs *, const WorkerThreadData *)>("tmvline1_subclamp");
tmvline4_subclamp = mProgram.GetProcAddress<void(const DrawWallArgs *, const WorkerThreadData *)>("tmvline4_subclamp");
tmvline1_revsubclamp = mProgram.GetProcAddress<void(const DrawWallArgs *, const WorkerThreadData *)>("tmvline1_revsubclamp");
tmvline4_revsubclamp = mProgram.GetProcAddress<void(const DrawWallArgs *, const WorkerThreadData *)>("tmvline4_revsubclamp");
DrawSky1 = mProgram.GetProcAddress<void(const DrawSkyArgs *, const WorkerThreadData *)>("DrawSky1");
DrawSky4 = mProgram.GetProcAddress<void(const DrawSkyArgs *, const WorkerThreadData *)>("DrawSky4");
DrawDoubleSky1 = mProgram.GetProcAddress<void(const DrawSkyArgs *, const WorkerThreadData *)>("DrawDoubleSky1");
DrawDoubleSky4 = mProgram.GetProcAddress<void(const DrawSkyArgs *, const WorkerThreadData *)>("DrawDoubleSky4");
for (int i = 0; i < NumTriBlendModes(); i++)
{
TriDrawNormal8.push_back(mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDraw8_" + std::to_string(i)));
TriDrawNormal32.push_back(mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDraw32_" + std::to_string(i)));
TriFillNormal8.push_back(mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriFill8_" + std::to_string(i)));
TriFillNormal32.push_back(mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriFill32_" + std::to_string(i)));
TriDrawSubsector8.push_back(mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDrawSubsector8_" + std::to_string(i)));
TriDrawSubsector32.push_back(mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDrawSubsector32_" + std::to_string(i)));
TriFillSubsector8.push_back(mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriFillSubsector8_" + std::to_string(i)));
TriFillSubsector32.push_back(mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriFillSubsector32_" + std::to_string(i)));
}
TriStencil = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriStencil");
TriStencilClose = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriStencilClose");
#if 0
std::vector<uint32_t> foo(1024 * 4);
std::vector<uint32_t> 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<llvm::Type *> 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<llvm::Type *> 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<llvm::Type *> 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<llvm::Type *> 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<llvm::Type *> 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<llvm::Type *> 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<llvm::Type *> 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<llvm::Type *> 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<llvm::Type *> 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<LLVMContext>();
}
void LLVMProgram::CreateModule()
{
mModule = std::make_unique<llvm::Module>("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<void*>(mEngine->getFunctionAddress(name));
}
void LLVMProgram::StopLogFatalErrors()
{
LogFatalErrors = false;
}

View file

@ -38,7 +38,7 @@
#include "r_data/colormaps.h" #include "r_data/colormaps.h"
#include "r_plane.h" #include "r_plane.h"
#include "r_draw_rgba.h" #include "r_draw_rgba.h"
#include "r_compiler/llvmdrawers.h" #include "r_drawers.h"
#include "gl/data/gl_matrix.h" #include "gl/data/gl_matrix.h"
#include "gi.h" #include "gi.h"
@ -105,7 +105,7 @@ public:
{ {
if (thread->skipped_by_thread(args.y)) if (thread->skipped_by_thread(args.y))
return; return;
LLVMDrawers::Instance()->DrawSpan(&args); Drawers::Instance()->DrawSpan(&args);
} }
FString DebugInfo() override FString DebugInfo() override
@ -146,7 +146,7 @@ public:
{ {
if (thread->skipped_by_thread(args.y)) if (thread->skipped_by_thread(args.y))
return; return;
LLVMDrawers::Instance()->DrawSpanMasked(&args); Drawers::Instance()->DrawSpanMasked(&args);
} }
}; };
@ -157,7 +157,7 @@ public:
{ {
if (thread->skipped_by_thread(args.y)) if (thread->skipped_by_thread(args.y))
return; return;
LLVMDrawers::Instance()->DrawSpanTranslucent(&args); Drawers::Instance()->DrawSpanTranslucent(&args);
} }
}; };
@ -168,7 +168,7 @@ public:
{ {
if (thread->skipped_by_thread(args.y)) if (thread->skipped_by_thread(args.y))
return; return;
LLVMDrawers::Instance()->DrawSpanMaskedTranslucent(&args); Drawers::Instance()->DrawSpanMaskedTranslucent(&args);
} }
}; };
@ -179,7 +179,7 @@ public:
{ {
if (thread->skipped_by_thread(args.y)) if (thread->skipped_by_thread(args.y))
return; return;
LLVMDrawers::Instance()->DrawSpanAddClamp(&args); Drawers::Instance()->DrawSpanAddClamp(&args);
} }
}; };
@ -190,7 +190,7 @@ public:
{ {
if (thread->skipped_by_thread(args.y)) if (thread->skipped_by_thread(args.y))
return; return;
LLVMDrawers::Instance()->DrawSpanMaskedAddClamp(&args); Drawers::Instance()->DrawSpanMaskedAddClamp(&args);
} }
}; };
@ -251,7 +251,7 @@ public:
void Execute(DrawerThread *thread) override void Execute(DrawerThread *thread) override
{ {
WorkerThreadData d = ThreadData(thread); WorkerThreadData d = ThreadData(thread);
LLVMDrawers::Instance()->vlinec4(&args, &d); Drawers::Instance()->vlinec4(&args, &d);
} }
FString DebugInfo() override FString DebugInfo() override
@ -312,7 +312,7 @@ public:
void Execute(DrawerThread *thread) override void Execute(DrawerThread *thread) override
{ {
WorkerThreadData d = ThreadData(thread); WorkerThreadData d = ThreadData(thread);
LLVMDrawers::Instance()->vlinec1(&args, &d); Drawers::Instance()->vlinec1(&args, &d);
} }
FString DebugInfo() override FString DebugInfo() override
@ -383,7 +383,7 @@ public:
void Execute(DrawerThread *thread) override void Execute(DrawerThread *thread) override
{ {
WorkerThreadData d = ThreadData(thread); WorkerThreadData d = ThreadData(thread);
LLVMDrawers::Instance()->DrawColumn(&args, &d); Drawers::Instance()->DrawColumn(&args, &d);
} }
}; };
@ -438,7 +438,7 @@ public: \
void Execute(DrawerThread *thread) override \ void Execute(DrawerThread *thread) override \
{ \ { \
WorkerThreadData d = ThreadData(thread); \ WorkerThreadData d = ThreadData(thread); \
LLVMDrawers::Instance()->func(&args, &d); \ Drawers::Instance()->func(&args, &d); \
} \ } \
}; };

423
src/r_drawers.cpp Normal file
View file

@ -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;
}

View file

@ -22,6 +22,11 @@
#pragma once #pragma once
#include <cstdint>
#include <vector>
class FString;
struct WorkerThreadData struct WorkerThreadData
{ {
int32_t core; int32_t core;
@ -63,12 +68,7 @@ struct DrawWallArgs
nearest_filter = 2 nearest_filter = 2
}; };
FString ToString() 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;
}
}; };
struct DrawSpanArgs struct DrawSpanArgs
@ -105,12 +105,7 @@ struct DrawSpanArgs
nearest_filter = 2 nearest_filter = 2
}; };
FString ToString() FString ToString();
{
FString info;
info.Format("x1 = %i, x2 = %i, y = %i, flags = %i", x1, x2, y, flags);
return info;
}
}; };
struct DrawColumnArgs struct DrawColumnArgs
@ -150,12 +145,7 @@ struct DrawColumnArgs
nearest_filter = 2 nearest_filter = 2
}; };
FString ToString() 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;
}
}; };
struct DrawSkyArgs struct DrawSkyArgs
@ -173,12 +163,7 @@ struct DrawSkyArgs
uint32_t top_color; uint32_t top_color;
uint32_t bottom_color; uint32_t bottom_color;
FString ToString() FString ToString();
{
FString info;
info.Format("dest_y = %i, count = %i", dest_y, count);
return info;
}
}; };
struct TriVertex struct TriVertex
@ -273,14 +258,12 @@ enum class TriBlendMode
inline int NumTriBlendModes() { return (int)TriBlendMode::TranslateRevSub + 1; } inline int NumTriBlendModes() { return (int)TriBlendMode::TranslateRevSub + 1; }
class LLVMDrawers class Drawers
{ {
public: public:
virtual ~LLVMDrawers() { } Drawers();
static void Create(); static Drawers *Instance();
static void Destroy();
static LLVMDrawers *Instance();
void(*DrawColumn)(const DrawColumnArgs *, const WorkerThreadData *) = nullptr; void(*DrawColumn)(const DrawColumnArgs *, const WorkerThreadData *) = nullptr;
void(*DrawColumnAdd)(const DrawColumnArgs *, const WorkerThreadData *) = nullptr; void(*DrawColumnAdd)(const DrawColumnArgs *, const WorkerThreadData *) = nullptr;
@ -358,7 +341,4 @@ public:
std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriFillSubsector32; std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriFillSubsector32;
void(*TriStencil)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr; void(*TriStencil)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
void(*TriStencilClose)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr; void(*TriStencilClose)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
private:
static LLVMDrawers *Singleton;
}; };

View file

@ -43,7 +43,7 @@
#include "r_things.h" #include "r_things.h"
#include "v_video.h" #include "v_video.h"
#include "r_draw_rgba.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_tspans[4][MAXHEIGHT];
extern unsigned int *dc_ctspan[4]; extern unsigned int *dc_ctspan[4];
@ -107,7 +107,7 @@ public:
void Execute(DrawerThread *thread) override void Execute(DrawerThread *thread) override
{ {
WorkerThreadData d = ThreadData(thread); WorkerThreadData d = ThreadData(thread);
LLVMDrawers::Instance()->DrawColumnRt1(&args, &d); Drawers::Instance()->DrawColumnRt1(&args, &d);
} }
FString DebugInfo() override FString DebugInfo() override
@ -124,7 +124,7 @@ public: \
void Execute(DrawerThread *thread) override \ void Execute(DrawerThread *thread) override \
{ \ { \
WorkerThreadData d = ThreadData(thread); \ WorkerThreadData d = ThreadData(thread); \
LLVMDrawers::Instance()->func(&args, &d); \ Drawers::Instance()->func(&args, &d); \
} \ } \
}; };

View file

@ -78,7 +78,7 @@ void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, TriDrawVarian
if (drawargs.vcount < 3) if (drawargs.vcount < 3)
return; return;
auto llvm = LLVMDrawers::Instance(); auto llvm = Drawers::Instance();
void(*drawfunc)(const TriDrawTriangleArgs *, WorkerThreadData *); void(*drawfunc)(const TriDrawTriangleArgs *, WorkerThreadData *);
int bmode = (int)blendmode; int bmode = (int)blendmode;
switch (variant) switch (variant)

View file

@ -24,7 +24,7 @@
#include "r_draw.h" #include "r_draw.h"
#include "r_thread.h" #include "r_thread.h"
#include "r_compiler/llvmdrawers.h" #include "r_drawers.h"
#include "r_data/r_translate.h" #include "r_data/r_translate.h"
#include "r_data/colormaps.h" #include "r_data/colormaps.h"

View file

@ -43,7 +43,7 @@
#include "textures/textures.h" #include "textures/textures.h"
#include "r_data/voxels.h" #include "r_data/voxels.h"
#include "r_draw_rgba.h" #include "r_draw_rgba.h"
#include "r_compiler/llvmdrawers.h" #include "r_drawers.h"
#include "r_poly.h" #include "r_poly.h"
EXTERN_CVAR(Bool, r_shadercolormaps) EXTERN_CVAR(Bool, r_shadercolormaps)
@ -57,12 +57,10 @@ void R_InitRenderer();
FSoftwareRenderer::FSoftwareRenderer() FSoftwareRenderer::FSoftwareRenderer()
{ {
LLVMDrawers::Create();
} }
FSoftwareRenderer::~FSoftwareRenderer() FSoftwareRenderer::~FSoftwareRenderer()
{ {
LLVMDrawers::Destroy();
} }
//========================================================================== //==========================================================================

View file

@ -7,5 +7,6 @@ if( WIN32 AND NOT CMAKE_SIZEOF_VOID_P MATCHES "8" )
endif() endif()
add_subdirectory( updaterevision ) add_subdirectory( updaterevision )
add_subdirectory( zipdir ) add_subdirectory( zipdir )
add_subdirectory( drawergen )
set( CROSS_EXPORTS ${CROSS_EXPORTS} PARENT_SCOPE ) set( CROSS_EXPORTS ${CROSS_EXPORTS} PARENT_SCOPE )

View file

@ -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:$<TARGET_FILE:drawergen> -manifest ${CMAKE_CURRENT_SOURCE_DIR}/trustinfo.txt -outputresource:$<TARGET_FILE:drawergen> -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/.+")

View file

@ -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 <iostream>
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<uint8_t> 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<llvm::LLVMContext> mContext;
std::unique_ptr<llvm::Module> mModule;
};
class LLVMDrawers
{
public:
LLVMDrawers(const std::string &cpuName, const std::string namePostfix);
std::vector<uint8_t> 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<llvm::Type *> 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<llvm::Type *> 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<llvm::Type *> 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<llvm::Type *> 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<llvm::Type *> 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<llvm::Type *> 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<llvm::Type *> 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<llvm::Type *> 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<llvm::Type *> 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<llvm::LLVMContext>();
}
void LLVMProgram::CreateModule()
{
mModule = std::make_unique<llvm::Module>("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<uint8_t> 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<uint8_t> 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] << "<output filename>" << 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;
}

View file

@ -20,17 +20,16 @@
** **
*/ */
#include "i_system.h" #include "precomp.h"
#include "r_compiler/llvm_include.h" #include "fixedfunction/drawcolumncodegen.h"
#include "r_compiler/fixedfunction/drawcolumncodegen.h" #include "ssa/ssa_function.h"
#include "r_compiler/ssa/ssa_function.h" #include "ssa/ssa_scope.h"
#include "r_compiler/ssa/ssa_scope.h" #include "ssa/ssa_for_block.h"
#include "r_compiler/ssa/ssa_for_block.h" #include "ssa/ssa_if_block.h"
#include "r_compiler/ssa/ssa_if_block.h" #include "ssa/ssa_stack.h"
#include "r_compiler/ssa/ssa_stack.h" #include "ssa/ssa_function.h"
#include "r_compiler/ssa/ssa_function.h" #include "ssa/ssa_struct_type.h"
#include "r_compiler/ssa/ssa_struct_type.h" #include "ssa/ssa_value.h"
#include "r_compiler/ssa/ssa_value.h"
void DrawColumnCodegen::Generate(DrawColumnVariant variant, DrawColumnMethod method, SSAValue args, SSAValue thread_data) void DrawColumnCodegen::Generate(DrawColumnVariant variant, DrawColumnMethod method, SSAValue args, SSAValue thread_data)
{ {

View file

@ -20,17 +20,16 @@
** **
*/ */
#include "i_system.h" #include "precomp.h"
#include "r_compiler/llvm_include.h" #include "fixedfunction/drawercodegen.h"
#include "r_compiler/fixedfunction/drawercodegen.h" #include "ssa/ssa_function.h"
#include "r_compiler/ssa/ssa_function.h" #include "ssa/ssa_scope.h"
#include "r_compiler/ssa/ssa_scope.h" #include "ssa/ssa_for_block.h"
#include "r_compiler/ssa/ssa_for_block.h" #include "ssa/ssa_if_block.h"
#include "r_compiler/ssa/ssa_if_block.h" #include "ssa/ssa_stack.h"
#include "r_compiler/ssa/ssa_stack.h" #include "ssa/ssa_function.h"
#include "r_compiler/ssa/ssa_function.h" #include "ssa/ssa_struct_type.h"
#include "r_compiler/ssa/ssa_struct_type.h" #include "ssa/ssa_value.h"
#include "r_compiler/ssa/ssa_value.h"
SSABool DrawerCodegen::line_skipped_by_thread(SSAInt line, SSAWorkerThread thread) SSABool DrawerCodegen::line_skipped_by_thread(SSAInt line, SSAWorkerThread thread)
{ {

View file

@ -22,22 +22,22 @@
#pragma once #pragma once
#include "r_compiler/llvmdrawers.h" #include "precomp.h"
#include "r_compiler/ssa/ssa_value.h" #include "ssa/ssa_value.h"
#include "r_compiler/ssa/ssa_vec4f.h" #include "ssa/ssa_vec4f.h"
#include "r_compiler/ssa/ssa_vec4i.h" #include "ssa/ssa_vec4i.h"
#include "r_compiler/ssa/ssa_vec8s.h" #include "ssa/ssa_vec8s.h"
#include "r_compiler/ssa/ssa_vec16ub.h" #include "ssa/ssa_vec16ub.h"
#include "r_compiler/ssa/ssa_int.h" #include "ssa/ssa_int.h"
#include "r_compiler/ssa/ssa_int_ptr.h" #include "ssa/ssa_int_ptr.h"
#include "r_compiler/ssa/ssa_short.h" #include "ssa/ssa_short.h"
#include "r_compiler/ssa/ssa_ubyte_ptr.h" #include "ssa/ssa_ubyte_ptr.h"
#include "r_compiler/ssa/ssa_vec4f_ptr.h" #include "ssa/ssa_vec4f_ptr.h"
#include "r_compiler/ssa/ssa_vec4i_ptr.h" #include "ssa/ssa_vec4i_ptr.h"
#include "r_compiler/ssa/ssa_stack.h" #include "ssa/ssa_stack.h"
#include "r_compiler/ssa/ssa_bool.h" #include "ssa/ssa_bool.h"
#include "r_compiler/ssa/ssa_barycentric_weight.h" #include "ssa/ssa_barycentric_weight.h"
#include "r_compiler/llvm_include.h" #include "llvm_include.h"
class SSAWorkerThread class SSAWorkerThread
{ {
@ -90,3 +90,6 @@ public:
// Calculates the final alpha values to be used when combined with the source texture alpha channel // Calculates the final alpha values to be used when combined with the source texture alpha channel
SSAInt calc_blend_bgalpha(SSAVec4i fg, SSAInt destalpha); SSAInt calc_blend_bgalpha(SSAVec4i fg, SSAInt destalpha);
}; };
#define FRACBITS 16
#define FRACUNIT (1<<FRACBITS)

View file

@ -20,17 +20,16 @@
** **
*/ */
#include "i_system.h" #include "precomp.h"
#include "r_compiler/llvm_include.h" #include "fixedfunction/drawskycodegen.h"
#include "r_compiler/fixedfunction/drawskycodegen.h" #include "ssa/ssa_function.h"
#include "r_compiler/ssa/ssa_function.h" #include "ssa/ssa_scope.h"
#include "r_compiler/ssa/ssa_scope.h" #include "ssa/ssa_for_block.h"
#include "r_compiler/ssa/ssa_for_block.h" #include "ssa/ssa_if_block.h"
#include "r_compiler/ssa/ssa_if_block.h" #include "ssa/ssa_stack.h"
#include "r_compiler/ssa/ssa_stack.h" #include "ssa/ssa_function.h"
#include "r_compiler/ssa/ssa_function.h" #include "ssa/ssa_struct_type.h"
#include "r_compiler/ssa/ssa_struct_type.h" #include "ssa/ssa_value.h"
#include "r_compiler/ssa/ssa_value.h"
void DrawSkyCodegen::Generate(DrawSkyVariant variant, bool fourColumns, SSAValue args, SSAValue thread_data) void DrawSkyCodegen::Generate(DrawSkyVariant variant, bool fourColumns, SSAValue args, SSAValue thread_data)
{ {

View file

@ -20,17 +20,16 @@
** **
*/ */
#include "i_system.h" #include "precomp.h"
#include "r_compiler/llvm_include.h" #include "fixedfunction/drawspancodegen.h"
#include "r_compiler/fixedfunction/drawspancodegen.h" #include "ssa/ssa_function.h"
#include "r_compiler/ssa/ssa_function.h" #include "ssa/ssa_scope.h"
#include "r_compiler/ssa/ssa_scope.h" #include "ssa/ssa_for_block.h"
#include "r_compiler/ssa/ssa_for_block.h" #include "ssa/ssa_if_block.h"
#include "r_compiler/ssa/ssa_if_block.h" #include "ssa/ssa_stack.h"
#include "r_compiler/ssa/ssa_stack.h" #include "ssa/ssa_function.h"
#include "r_compiler/ssa/ssa_function.h" #include "ssa/ssa_struct_type.h"
#include "r_compiler/ssa/ssa_struct_type.h" #include "ssa/ssa_value.h"
#include "r_compiler/ssa/ssa_value.h"
void DrawSpanCodegen::Generate(DrawSpanVariant variant, SSAValue args) void DrawSpanCodegen::Generate(DrawSpanVariant variant, SSAValue args)
{ {

View file

@ -20,17 +20,16 @@
** **
*/ */
#include "i_system.h" #include "precomp.h"
#include "r_compiler/llvm_include.h" #include "fixedfunction/drawtrianglecodegen.h"
#include "r_compiler/fixedfunction/drawtrianglecodegen.h" #include "ssa/ssa_function.h"
#include "r_compiler/ssa/ssa_function.h" #include "ssa/ssa_scope.h"
#include "r_compiler/ssa/ssa_scope.h" #include "ssa/ssa_for_block.h"
#include "r_compiler/ssa/ssa_for_block.h" #include "ssa/ssa_if_block.h"
#include "r_compiler/ssa/ssa_if_block.h" #include "ssa/ssa_stack.h"
#include "r_compiler/ssa/ssa_stack.h" #include "ssa/ssa_function.h"
#include "r_compiler/ssa/ssa_function.h" #include "ssa/ssa_struct_type.h"
#include "r_compiler/ssa/ssa_struct_type.h" #include "ssa/ssa_value.h"
#include "r_compiler/ssa/ssa_value.h"
void DrawTriangleCodegen::Generate(TriDrawVariant variant, TriBlendMode blendmode, bool truecolor, SSAValue args, SSAValue thread_data) void DrawTriangleCodegen::Generate(TriDrawVariant variant, TriBlendMode blendmode, bool truecolor, SSAValue args, SSAValue thread_data)
{ {

View file

@ -20,17 +20,16 @@
** **
*/ */
#include "i_system.h" #include "precomp.h"
#include "r_compiler/llvm_include.h" #include "fixedfunction/drawwallcodegen.h"
#include "r_compiler/fixedfunction/drawwallcodegen.h" #include "ssa/ssa_function.h"
#include "r_compiler/ssa/ssa_function.h" #include "ssa/ssa_scope.h"
#include "r_compiler/ssa/ssa_scope.h" #include "ssa/ssa_for_block.h"
#include "r_compiler/ssa/ssa_for_block.h" #include "ssa/ssa_if_block.h"
#include "r_compiler/ssa/ssa_if_block.h" #include "ssa/ssa_stack.h"
#include "r_compiler/ssa/ssa_stack.h" #include "ssa/ssa_function.h"
#include "r_compiler/ssa/ssa_function.h" #include "ssa/ssa_struct_type.h"
#include "r_compiler/ssa/ssa_struct_type.h" #include "ssa/ssa_value.h"
#include "r_compiler/ssa/ssa_value.h"
void DrawWallCodegen::Generate(DrawWallVariant variant, bool fourColumns, SSAValue args, SSAValue thread_data) void DrawWallCodegen::Generate(DrawWallVariant variant, bool fourColumns, SSAValue args, SSAValue thread_data)
{ {

View file

@ -0,0 +1,5 @@
#pragma once
#include "llvm_include.h"
#include "../../src/r_drawers.h"

View file

@ -20,7 +20,7 @@
** **
*/ */
#include "r_compiler/llvm_include.h" #include "precomp.h"
#include "ssa_bool.h" #include "ssa_bool.h"
#include "ssa_ubyte.h" #include "ssa_ubyte.h"
#include "ssa_vec4i.h" #include "ssa_vec4i.h"

View file

@ -20,7 +20,7 @@
** **
*/ */
#include "r_compiler/llvm_include.h" #include "precomp.h"
#include "ssa_float.h" #include "ssa_float.h"
#include "ssa_int.h" #include "ssa_int.h"
#include "ssa_scope.h" #include "ssa_scope.h"

View file

@ -20,7 +20,7 @@
** **
*/ */
#include "r_compiler/llvm_include.h" #include "precomp.h"
#include "ssa_float_ptr.h" #include "ssa_float_ptr.h"
#include "ssa_scope.h" #include "ssa_scope.h"

View file

@ -20,7 +20,7 @@
** **
*/ */
#include "r_compiler/llvm_include.h" #include "precomp.h"
#include "ssa_for_block.h" #include "ssa_for_block.h"
#include "ssa_scope.h" #include "ssa_scope.h"

View file

@ -20,7 +20,7 @@
** **
*/ */
#include "r_compiler/llvm_include.h" #include "precomp.h"
#include "ssa_function.h" #include "ssa_function.h"
#include "ssa_int.h" #include "ssa_int.h"
#include "ssa_scope.h" #include "ssa_scope.h"

View file

@ -20,7 +20,7 @@
** **
*/ */
#include "r_compiler/llvm_include.h" #include "precomp.h"
#include "ssa_if_block.h" #include "ssa_if_block.h"
#include "ssa_scope.h" #include "ssa_scope.h"

View file

@ -20,7 +20,7 @@
** **
*/ */
#include "r_compiler/llvm_include.h" #include "precomp.h"
#include "ssa_int.h" #include "ssa_int.h"
#include "ssa_float.h" #include "ssa_float.h"
#include "ssa_ubyte.h" #include "ssa_ubyte.h"

View file

@ -20,7 +20,7 @@
** **
*/ */
#include "r_compiler/llvm_include.h" #include "precomp.h"
#include "ssa_int_ptr.h" #include "ssa_int_ptr.h"
#include "ssa_scope.h" #include "ssa_scope.h"

View file

@ -20,7 +20,7 @@
** **
*/ */
#include "r_compiler/llvm_include.h" #include "precomp.h"
#include "ssa_scope.h" #include "ssa_scope.h"
#include "ssa_int.h" #include "ssa_int.h"

View file

@ -20,7 +20,7 @@
** **
*/ */
#include "r_compiler/llvm_include.h" #include "precomp.h"
#include "ssa_short.h" #include "ssa_short.h"
#include "ssa_float.h" #include "ssa_float.h"
#include "ssa_int.h" #include "ssa_int.h"

View file

@ -20,7 +20,7 @@
** **
*/ */
#include "r_compiler/llvm_include.h" #include "precomp.h"
#include "ssa_struct_type.h" #include "ssa_struct_type.h"
#include "ssa_scope.h" #include "ssa_scope.h"

View file

@ -20,7 +20,7 @@
** **
*/ */
#include "r_compiler/llvm_include.h" #include "precomp.h"
#include "ssa_ubyte.h" #include "ssa_ubyte.h"
#include "ssa_int.h" #include "ssa_int.h"
#include "ssa_scope.h" #include "ssa_scope.h"

View file

@ -20,7 +20,7 @@
** **
*/ */
#include "r_compiler/llvm_include.h" #include "precomp.h"
#include "ssa_ubyte_ptr.h" #include "ssa_ubyte_ptr.h"
#include "ssa_scope.h" #include "ssa_scope.h"

View file

@ -20,7 +20,7 @@
** **
*/ */
#include "r_compiler/llvm_include.h" #include "precomp.h"
#include "ssa_value.h" #include "ssa_value.h"
#include "ssa_int.h" #include "ssa_int.h"
#include "ssa_scope.h" #include "ssa_scope.h"

View file

@ -20,7 +20,7 @@
** **
*/ */
#include "r_compiler/llvm_include.h" #include "precomp.h"
#include "ssa_vec16ub.h" #include "ssa_vec16ub.h"
#include "ssa_vec8s.h" #include "ssa_vec8s.h"
#include "ssa_vec4i.h" #include "ssa_vec4i.h"

View file

@ -20,7 +20,7 @@
** **
*/ */
#include "r_compiler/llvm_include.h" #include "precomp.h"
#include "ssa_vec4f.h" #include "ssa_vec4f.h"
#include "ssa_vec4i.h" #include "ssa_vec4i.h"
#include "ssa_float.h" #include "ssa_float.h"

View file

@ -20,7 +20,7 @@
** **
*/ */
#include "r_compiler/llvm_include.h" #include "precomp.h"
#include "ssa_vec4f_ptr.h" #include "ssa_vec4f_ptr.h"
#include "ssa_scope.h" #include "ssa_scope.h"

View file

@ -20,7 +20,7 @@
** **
*/ */
#include "r_compiler/llvm_include.h" #include "precomp.h"
#include "ssa_vec4i.h" #include "ssa_vec4i.h"
#include "ssa_vec4f.h" #include "ssa_vec4f.h"
#include "ssa_vec8s.h" #include "ssa_vec8s.h"

View file

@ -20,7 +20,7 @@
** **
*/ */
#include "r_compiler/llvm_include.h" #include "precomp.h"
#include "ssa_vec4i_ptr.h" #include "ssa_vec4i_ptr.h"
#include "ssa_scope.h" #include "ssa_scope.h"

View file

@ -20,7 +20,7 @@
** **
*/ */
#include "r_compiler/llvm_include.h" #include "precomp.h"
#include "ssa_vec8s.h" #include "ssa_vec8s.h"
#include "ssa_vec4i.h" #include "ssa_vec4i.h"
#include "ssa_vec16ub.h" #include "ssa_vec16ub.h"

View file

@ -0,0 +1,6 @@
// This resource script is for compiling with MinGW only. Visual C++
// compilations use the manifest tool to insert the manifest instead.
#include <WinUser.h>
1 RT_MANIFEST "trustinfo.txt"

View file

@ -0,0 +1,16 @@
<!-- Ignore any warnings about Unrecognized Element "trustInfo" -->
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity version="1.0.0.0"
processorArchitecture="X86"
name="UpdateRevision"
type="win32" />
<description>Drawergen for the ZDoom source build process.</description>
<ms_asmv3:trustInfo xmlns:ms_asmv3="urn:schemas-microsoft-com:asm.v3">
<ms_asmv3:security>
<ms_asmv3:requestedPrivileges>
<ms_asmv3:requestedExecutionLevel level="asInvoker" uiAccess="false" />
</ms_asmv3:requestedPrivileges>
</ms_asmv3:security>
</ms_asmv3:trustInfo>
</assembly>