- backend update from GZDoom.

This commit is contained in:
Christoph Oelckers 2021-02-12 14:44:54 +01:00
parent 5b6aa372ea
commit c96e04e6c9
28 changed files with 352 additions and 119 deletions

View file

@ -527,6 +527,10 @@ void F2DDrawer::AddTexture(FGameTexture* img, DrawParms& parms)
offset = osave; offset = osave;
} }
DShape2D::~DShape2D() {
delete lastParms;
}
//========================================================================== //==========================================================================
// //
// //
@ -553,6 +557,20 @@ void F2DDrawer::AddShape(FGameTexture* img, DShape2D* shape, DrawParms& parms)
dg.mTranslationId = 0; dg.mTranslationId = 0;
SetStyle(img, parms, vertexcolor, dg); SetStyle(img, parms, vertexcolor, dg);
if (shape->lastParms == nullptr) {
shape->lastParms = new DrawParms(parms);
}
else if (shape->lastParms->vertexColorChange(parms)) {
shape->needsVertexUpload = true;
if (!shape->uploadedOnce) {
shape->bufIndex = -1;
shape->buffers.Clear();
shape->lastCommand = nullptr;
}
delete shape->lastParms;
shape->lastParms = new DrawParms(parms);
}
if (!img->isHardwareCanvas() && parms.TranslationId != -1) if (!img->isHardwareCanvas() && parms.TranslationId != -1)
dg.mTranslationId = parms.TranslationId; dg.mTranslationId = parms.TranslationId;
@ -605,6 +623,7 @@ void F2DDrawer::AddShape(FGameTexture* img, DShape2D* shape, DrawParms& parms)
shape->bufIndex += 1; shape->bufIndex += 1;
shape->buffers.Reserve(1); shape->buffers.Reserve(1);
auto buf = &shape->buffers[shape->bufIndex]; auto buf = &shape->buffers[shape->bufIndex];
auto verts = TArray<TwoDVertex>(dg.mVertCount, true); auto verts = TArray<TwoDVertex>(dg.mVertCount, true);
@ -625,9 +644,15 @@ void F2DDrawer::AddShape(FGameTexture* img, DShape2D* shape, DrawParms& parms)
buf->UploadData(&verts[0], dg.mVertCount, &shape->mIndices[0], shape->mIndices.Size()); buf->UploadData(&verts[0], dg.mVertCount, &shape->mIndices[0], shape->mIndices.Size());
shape->needsVertexUpload = false; shape->needsVertexUpload = false;
shape->uploadedOnce = true;
} }
dg.shape2DBufIndex = shape->bufIndex; dg.shape2DBufIndex = shape->bufIndex;
AddCommand(&dg); dg.shapeLastCmd = true;
if (shape->lastCommand != nullptr) {
shape->lastCommand->shapeLastCmd = false;
}
auto c = AddCommand(&dg);
shape->lastCommand = &mData[c];
offset = osave; offset = osave;
} }

View file

@ -34,32 +34,6 @@ enum EClearWhich
class F2DVertexBuffer; class F2DVertexBuffer;
class DShape2D : public DObject
{
DECLARE_CLASS(DShape2D,DObject)
public:
DShape2D()
{
transform.Identity();
}
TArray<int> mIndices;
TArray<DVector2> mVertices;
TArray<DVector2> mCoords;
double minx = 0.0;
double maxx = 0.0;
double miny = 0.0;
double maxy = 0.0;
DMatrix3x3 transform;
TArray<F2DVertexBuffer> buffers;
bool needsVertexUpload = true;
int bufIndex = -1;
};
struct F2DPolygons struct F2DPolygons
{ {
TArray<FVector4> vertices; TArray<FVector4> vertices;
@ -74,6 +48,7 @@ struct F2DPolygons
}; };
class DShape2D;
class F2DDrawer class F2DDrawer
{ {
@ -150,6 +125,7 @@ public:
DShape2D* shape2D; DShape2D* shape2D;
int shape2DBufIndex; int shape2DBufIndex;
int shape2DIndexCount; int shape2DIndexCount;
bool shapeLastCmd;
RenderCommand() RenderCommand()
{ {
@ -262,6 +238,39 @@ public:
bool mIsFirstPass = true; bool mIsFirstPass = true;
}; };
class DShape2D : public DObject
{
DECLARE_CLASS(DShape2D,DObject)
public:
DShape2D()
{
transform.Identity();
}
TArray<int> mIndices;
TArray<DVector2> mVertices;
TArray<DVector2> mCoords;
double minx = 0.0;
double maxx = 0.0;
double miny = 0.0;
double maxy = 0.0;
DMatrix3x3 transform;
TArray<F2DVertexBuffer> buffers;
bool needsVertexUpload = true;
int bufIndex = -1;
F2DDrawer::RenderCommand* lastCommand = nullptr;
bool uploadedOnce = false;
DrawParms* lastParms;
~DShape2D();
};
//=========================================================================== //===========================================================================
// //
// Vertex buffer for 2D drawer // Vertex buffer for 2D drawer

View file

@ -206,6 +206,17 @@ struct DrawParms
double patchscalex, patchscaley; double patchscalex, patchscaley;
double rotateangle; double rotateangle;
IntRect viewport; IntRect viewport;
bool vertexColorChange(const DrawParms& other) {
return
this->Alpha != other.Alpha ||
this->fillcolor != other.fillcolor ||
this->colorOverlay != other.colorOverlay ||
this->color != other.color ||
this->style.Flags != other.style.Flags ||
this->style.BlendOp != other.style.BlendOp ||
this->desaturate != other.desaturate;
}
}; };
struct Va_List struct Va_List

View file

@ -209,7 +209,7 @@ protected:
// the complete set of sound effects // the complete set of sound effects
TArray<sfxinfo_t> S_sfx; TArray<sfxinfo_t> S_sfx;
FRolloffInfo S_Rolloff; FRolloffInfo S_Rolloff{};
TArray<uint8_t> S_SoundCurve; TArray<uint8_t> S_SoundCurve;
TMap<int, int> ResIdMap; TMap<int, int> ResIdMap;
TArray<FRandomSoundList> S_rnd; TArray<FRandomSoundList> S_rnd;

View file

@ -97,9 +97,6 @@ private:
#else #else
// Windows and macOS // Windows and macOS
#ifndef _M_ARM
#include "x86.h"
#endif
extern double PerfToSec, PerfToMillisec; extern double PerfToSec, PerfToMillisec;

View file

@ -706,13 +706,17 @@ int PClass::FindVirtualIndex(FName name, PFunction::Variant *variant, PFunction
if (!(parentfunc->Variants[0].ArgFlags[a] & VARF_Optional)) return -1; if (!(parentfunc->Variants[0].ArgFlags[a] & VARF_Optional)) return -1;
} }
// Todo: extend the prototype // Extend the prototype
TArray<PType*> argumentTypes = proto->ArgumentTypes;
for (unsigned a = proto->ArgumentTypes.Size(); a < vproto->ArgumentTypes.Size(); a++) for (unsigned a = proto->ArgumentTypes.Size(); a < vproto->ArgumentTypes.Size(); a++)
{ {
proto->ArgumentTypes.Push(vproto->ArgumentTypes[a]); argumentTypes.Push(vproto->ArgumentTypes[a]);
variant->ArgFlags.Push(parentfunc->Variants[0].ArgFlags[a]); variant->ArgFlags.Push(parentfunc->Variants[0].ArgFlags[a]);
variant->ArgNames.Push(NAME_None); variant->ArgNames.Push(NAME_None);
} }
variant->Proto = NewPrototype(proto->ReturnTypes, argumentTypes);
} }
return i; return i;
} }

View file

@ -37,7 +37,6 @@
#include "cmdlib.h" #include "cmdlib.h"
#include "i_system.h" #include "i_system.h"
#include "gameconfigfile.h" #include "gameconfigfile.h"
#include "x86.h"
bool I_WriteIniFailed() bool I_WriteIniFailed()

View file

@ -45,9 +45,9 @@
#include <fcntl.h> #include <fcntl.h>
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#include <sys/ioctl.h>
#include <SDL.h> #include <SDL.h>
#include "x86.h"
#include "version.h" #include "version.h"
#include "cmdlib.h" #include "cmdlib.h"
@ -57,6 +57,7 @@
#include "v_font.h" #include "v_font.h"
#include "c_cvars.h" #include "c_cvars.h"
#include "palutil.h" #include "palutil.h"
#include "st_start.h"
#ifndef NO_GTK #ifndef NO_GTK
@ -71,6 +72,8 @@ double PerfToSec, PerfToMillisec;
CVAR(Bool, con_printansi, true, CVAR_GLOBALCONFIG|CVAR_ARCHIVE); CVAR(Bool, con_printansi, true, CVAR_GLOBALCONFIG|CVAR_ARCHIVE);
CVAR(Bool, con_4bitansi, false, CVAR_GLOBALCONFIG|CVAR_ARCHIVE); CVAR(Bool, con_4bitansi, false, CVAR_GLOBALCONFIG|CVAR_ARCHIVE);
extern FStartupScreen *StartScreen;
void I_SetIWADInfo() void I_SetIWADInfo()
{ {
} }
@ -132,6 +135,42 @@ void CalculateCPUSpeed()
{ {
} }
void CleanProgressBar()
{
if (!isatty(STDOUT_FILENO)) return;
struct winsize sizeOfWindow;
ioctl(STDOUT_FILENO, TIOCGWINSZ, &sizeOfWindow);
fprintf(stdout,"\0337\033[%d;%dH\033[0J\0338",sizeOfWindow.ws_row, 0);
fflush(stdout);
}
static int ProgressBarCurPos, ProgressBarMaxPos;
void RedrawProgressBar(int CurPos, int MaxPos)
{
if (!isatty(STDOUT_FILENO)) return;
CleanProgressBar();
struct winsize sizeOfWindow;
ioctl(STDOUT_FILENO, TIOCGWINSZ, &sizeOfWindow);
double progVal = std::clamp((double)CurPos / (double)MaxPos,0.0,1.0);
int curProgVal = std::clamp(int(sizeOfWindow.ws_col * progVal),0,(int)sizeOfWindow.ws_col);
char progressBuffer[512];
memset(progressBuffer,'.',512);
progressBuffer[sizeOfWindow.ws_col - 1] = 0;
int lengthOfStr = 0;
while (curProgVal-- > 0)
{
progressBuffer[lengthOfStr++] = '=';
if (lengthOfStr >= sizeOfWindow.ws_col - 1) break;
}
fprintf(stdout, "\0337\033[%d;%dH\033[2K[%s\033[%d;%dH]\0338", sizeOfWindow.ws_row, 0, progressBuffer, sizeOfWindow.ws_row, sizeOfWindow.ws_col);
fflush(stdout);
ProgressBarCurPos = CurPos;
ProgressBarMaxPos = MaxPos;
}
void I_PrintStr(const char *cp) void I_PrintStr(const char *cp)
{ {
const char * srcp = cp; const char * srcp = cp;
@ -183,8 +222,10 @@ void I_PrintStr(const char *cp)
} }
} }
if (StartScreen) CleanProgressBar();
fputs(printData.GetChars(),stdout); fputs(printData.GetChars(),stdout);
fputs("\033[0m",stdout); fputs("\033[0m",stdout);
if (StartScreen) RedrawProgressBar(ProgressBarCurPos,ProgressBarMaxPos);
} }
int I_PickIWad (WadStuff *wads, int numwads, bool showwin, int defaultiwad) int I_PickIWad (WadStuff *wads, int numwads, bool showwin, int defaultiwad)

View file

@ -68,6 +68,9 @@ class FTTYStartupScreen : public FStartupScreen
// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
extern void RedrawProgressBar(int CurPos, int MaxPos);
extern void CleanProgressBar();
// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
@ -139,13 +142,15 @@ FTTYStartupScreen::~FTTYStartupScreen()
// //
// FTTYStartupScreen :: Progress // FTTYStartupScreen :: Progress
// //
// If there was a progress bar, this would move it. But the basic TTY
// startup screen doesn't have one, so this function does nothing.
//
//=========================================================================== //===========================================================================
void FTTYStartupScreen::Progress() void FTTYStartupScreen::Progress()
{ {
if (CurPos < MaxPos)
{
++CurPos;
}
RedrawProgressBar(CurPos, MaxPos);
} }
//=========================================================================== //===========================================================================
@ -163,6 +168,7 @@ void FTTYStartupScreen::NetInit(const char *message, int numplayers)
{ {
termios rawtermios; termios rawtermios;
CleanProgressBar();
fprintf (stderr, "Press 'Q' to abort network game synchronization."); fprintf (stderr, "Press 'Q' to abort network game synchronization.");
// Set stdin to raw mode so we can get keypresses in ST_CheckNetAbort() // Set stdin to raw mode so we can get keypresses in ST_CheckNetAbort()
// immediately without waiting for an EOL. // immediately without waiting for an EOL.
@ -197,14 +203,15 @@ void FTTYStartupScreen::NetInit(const char *message, int numplayers)
//=========================================================================== //===========================================================================
void FTTYStartupScreen::NetDone() void FTTYStartupScreen::NetDone()
{ {
CleanProgressBar();
// Restore stdin settings // Restore stdin settings
if (DidNetInit) if (DidNetInit)
{ {
tcsetattr (STDIN_FILENO, TCSANOW, &OldTermIOS); tcsetattr (STDIN_FILENO, TCSANOW, &OldTermIOS);
printf ("\n"); printf ("\n");
DidNetInit = false; DidNetInit = false;
} }
} }
//=========================================================================== //===========================================================================

View file

@ -35,7 +35,6 @@
#include <windows.h> #include <windows.h>
#include "hardware.h" #include "hardware.h"
#include "x86.h"
#include "templates.h" #include "templates.h"
#include "version.h" #include "version.h"
#include "c_console.h" #include "c_console.h"

View file

@ -40,7 +40,6 @@
#include "gl_sysfb.h" #include "gl_sysfb.h"
#include "hardware.h" #include "hardware.h"
#include "x86.h"
#include "templates.h" #include "templates.h"
#include "version.h" #include "version.h"
#include "c_console.h" #include "c_console.h"

View file

@ -2,7 +2,6 @@
#define __GL_CLOCK_H #define __GL_CLOCK_H
#include "stats.h" #include "stats.h"
#include "x86.h"
#include "m_fixed.h" #include "m_fixed.h"
extern glcycle_t RenderWall,SetupWall,ClipWall; extern glcycle_t RenderWall,SetupWall,ClipWall;

View file

@ -183,12 +183,14 @@ void Draw2D(F2DDrawer *drawer, FRenderState &state)
state.SetVertexBuffer(&cmd.shape2D->buffers[cmd.shape2DBufIndex]); state.SetVertexBuffer(&cmd.shape2D->buffers[cmd.shape2DBufIndex]);
state.DrawIndexed(DT_Triangles, 0, cmd.shape2DIndexCount); state.DrawIndexed(DT_Triangles, 0, cmd.shape2DIndexCount);
state.SetVertexBuffer(&vb); state.SetVertexBuffer(&vb);
if (cmd.shape2D->bufIndex > 0 && cmd.shape2DBufIndex == cmd.shape2D->bufIndex) if (cmd.shape2D->bufIndex > 0 && cmd.shapeLastCmd)
{ {
cmd.shape2D->needsVertexUpload = true; cmd.shape2D->needsVertexUpload = true;
cmd.shape2D->buffers.Clear(); cmd.shape2D->buffers.Clear();
cmd.shape2D->lastCommand = nullptr;
cmd.shape2D->bufIndex = -1; cmd.shape2D->bufIndex = -1;
} }
cmd.shape2D->uploadedOnce = false;
} }
else else
{ {

View file

@ -28,7 +28,6 @@
#include "model.h" #include "model.h"
#include "poly_thread.h" #include "poly_thread.h"
#include "screen_triangle.h" #include "screen_triangle.h"
#include "x86.h"
#ifndef NO_SSE #ifndef NO_SSE
#include <immintrin.h> #include <immintrin.h>

View file

@ -29,7 +29,6 @@
#include "poly_triangle.h" #include "poly_triangle.h"
#include "poly_thread.h" #include "poly_thread.h"
#include "screen_triangle.h" #include "screen_triangle.h"
#include "x86.h"
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

View file

@ -24,7 +24,6 @@
#include "templates.h" #include "templates.h"
#include "poly_thread.h" #include "poly_thread.h"
#include "screen_scanline_setup.h" #include "screen_scanline_setup.h"
#include "x86.h"
#include <cmath> #include <cmath>
#ifndef NO_SSE #ifndef NO_SSE

View file

@ -24,7 +24,6 @@
#include "templates.h" #include "templates.h"
#include "poly_thread.h" #include "poly_thread.h"
#include "screen_scanline_setup.h" #include "screen_scanline_setup.h"
#include "x86.h"
#include <cmath> #include <cmath>
static uint32_t SampleTexture(uint32_t u, uint32_t v, const void* texPixels, int texWidth, int texHeight, bool texBgra) static uint32_t SampleTexture(uint32_t u, uint32_t v, const void* texPixels, int texWidth, int texHeight, bool texBgra)

View file

@ -30,7 +30,6 @@
#include "screen_blend.h" #include "screen_blend.h"
#include "screen_scanline_setup.h" #include "screen_scanline_setup.h"
#include "screen_shader.h" #include "screen_shader.h"
#include "x86.h"
#include <cmath> #include <cmath>
static void WriteDepth(int y, int x0, int x1, PolyTriangleThreadData* thread) static void WriteDepth(int y, int x0, int x1, PolyTriangleThreadData* thread)

View file

@ -68,6 +68,8 @@ void VKBuffer::SetData(size_t size, const void *data, bool staticdata)
{ {
auto fb = GetVulkanFrameBuffer(); auto fb = GetVulkanFrameBuffer();
size = std::max(size, (size_t)16); // For supporting zero byte buffers
if (staticdata) if (staticdata)
{ {
mPersistent = false; mPersistent = false;
@ -122,6 +124,8 @@ void VKBuffer::SetData(size_t size, const void *data, bool staticdata)
void VKBuffer::SetSubData(size_t offset, size_t size, const void *data) void VKBuffer::SetSubData(size_t offset, size_t size, const void *data)
{ {
size = std::max(size, (size_t)16); // For supporting zero byte buffers
auto fb = GetVulkanFrameBuffer(); auto fb = GetVulkanFrameBuffer();
if (mStaging) if (mStaging)
{ {
@ -141,6 +145,8 @@ void VKBuffer::SetSubData(size_t offset, size_t size, const void *data)
void VKBuffer::Resize(size_t newsize) void VKBuffer::Resize(size_t newsize)
{ {
newsize = std::max(newsize, (size_t)16); // For supporting zero byte buffers
auto fb = GetVulkanFrameBuffer(); auto fb = GetVulkanFrameBuffer();
// Grab old buffer // Grab old buffer
@ -187,6 +193,8 @@ void VKBuffer::Unmap()
void *VKBuffer::Lock(unsigned int size) void *VKBuffer::Lock(unsigned int size)
{ {
size = std::max(size, (unsigned int)16); // For supporting zero byte buffers
if (!mBuffer) if (!mBuffer)
{ {
// The model mesh loaders lock multiple non-persistent buffers at the same time. This is not allowed in vulkan. // The model mesh loaders lock multiple non-persistent buffers at the same time. This is not allowed in vulkan.

View file

@ -158,6 +158,9 @@ void VkHardwareTexture::CreateImage(FTexture *tex, int translation, int flags)
void VkHardwareTexture::CreateTexture(int w, int h, int pixelsize, VkFormat format, const void *pixels) void VkHardwareTexture::CreateTexture(int w, int h, int pixelsize, VkFormat format, const void *pixels)
{ {
if (w <= 0 || h <= 0)
throw CVulkanError("Trying to create zero size texture");
auto fb = GetVulkanFrameBuffer(); auto fb = GetVulkanFrameBuffer();
int totalSize = w * h * pixelsize; int totalSize = w * h * pixelsize;

View file

@ -2486,6 +2486,8 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
{ {
newfunc->ArgFlags.Push(sym->Variants[0].ArgFlags[i]); newfunc->ArgFlags.Push(sym->Variants[0].ArgFlags[i]);
} }
newfunc->Proto = sym->Variants[0].Proto;
} }
} }
} }

View file

@ -333,8 +333,29 @@ void JitCompiler::SetupSimpleFrame()
} }
} }
if (sfunc->NumArgs != argsPos || regd > sfunc->NumRegD || regf > sfunc->NumRegF || rega > sfunc->NumRegA) const char *errorDetails = nullptr;
I_FatalError("JIT: sfunc->NumArgs != argsPos || regd > sfunc->NumRegD || regf > sfunc->NumRegF || rega > sfunc->NumRegA");
if (sfunc->NumArgs != argsPos)
{
errorDetails = "arguments";
}
else if (regd > sfunc->NumRegD)
{
errorDetails = "integer registers";
}
else if (regf > sfunc->NumRegF)
{
errorDetails = "floating point registers";
}
else if (rega > sfunc->NumRegA)
{
errorDetails = "address registers";
}
if (errorDetails)
{
I_FatalError("JIT: inconsistent number of %s for function %s", errorDetails, sfunc->PrintableName.GetChars());
}
for (int i = regd; i < sfunc->NumRegD; i++) for (int i = regd; i < sfunc->NumRegD; i++)
cc.xor_(regD[i], regD[i]); cc.xor_(regD[i], regD[i]);

View file

@ -496,6 +496,11 @@ void FTextureManager::ReplaceTexture (FTextureID picnum, FGameTexture *newtextur
if (unsigned(index) >= Textures.Size()) if (unsigned(index) >= Textures.Size())
return; return;
if (newtexture->GetTexture())
{
calcShouldUpscale(newtexture); // calculate this once at insertion
}
auto oldtexture = Textures[index].Texture; auto oldtexture = Textures[index].Texture;
newtexture->SetName(oldtexture->GetName()); newtexture->SetName(oldtexture->GetName());

View file

@ -165,6 +165,24 @@ bool FileExists (const char *filename)
return res && !isdir; return res && !isdir;
} }
//==========================================================================
//
// FileReadable
//
// Returns true if the file can be read.
//
//==========================================================================
bool FileReadable(const char *filename)
{
#ifndef _WIN32
return access (filename, R_OK) == 0;
#else
auto wstr = WideString(filename);
return _waccess (wstr.c_str(), 4) == 0;
#endif
}
//========================================================================== //==========================================================================
// //
// DirExists // DirExists

View file

@ -33,6 +33,7 @@ char(&_ArraySizeHelper(T(&array)[N]))[N];
#define myoffsetof(type,identifier) ((size_t)&((type *)alignof(type))->identifier - alignof(type)) #define myoffsetof(type,identifier) ((size_t)&((type *)alignof(type))->identifier - alignof(type))
bool FileExists (const char *filename); bool FileExists (const char *filename);
bool FileReadable (const char *filename);
bool DirExists(const char *filename); bool DirExists(const char *filename);
bool DirEntryExists (const char *pathname, bool *isdir = nullptr); bool DirEntryExists (const char *pathname, bool *isdir = nullptr);
bool GetFileInfo(const char* pathname, size_t* size, time_t* time); bool GetFileInfo(const char* pathname, size_t* size, time_t* time);

View file

@ -58,18 +58,11 @@ FString DumpCPUInfo(const CPUInfo *cpu)
#ifdef __GNUC__ #ifdef __GNUC__
#if defined(__i386__) && defined(__PIC__) #define __cpuidex(output, func, subfunc) \
// %ebx may by the PIC register. */ __asm__ __volatile__("cpuid" \
#define __cpuid(output, func) \ : "=a" ((output)[0]), "=b" ((output)[1]), "=c" ((output)[2]), "=d" ((output)[3]) \
__asm__ __volatile__("xchgl\t%%ebx, %1\n\t" \ : "a" (func), "c" (subfunc));
"cpuid\n\t" \ #define __cpuid(output, func) __cpuidex(output, func, 0)
"xchgl\t%%ebx, %1\n\t" \
: "=a" ((output)[0]), "=r" ((output)[1]), "=c" ((output)[2]), "=d" ((output)[3]) \
: "a" (func));
#else
#define __cpuid(output, func) __asm__ __volatile__("cpuid" : "=a" ((output)[0]),\
"=b" ((output)[1]), "=c" ((output)[2]), "=d" ((output)[3]) : "a" (func));
#endif
#endif #endif
void CheckCPUID(CPUInfo *cpu) void CheckCPUID(CPUInfo *cpu)
@ -81,52 +74,9 @@ void CheckCPUID(CPUInfo *cpu)
cpu->DataL1LineSize = 32; // Assume a 32-byte cache line cpu->DataL1LineSize = 32; // Assume a 32-byte cache line
#if !defined(_M_IX86) && !defined(__i386__) && !defined(_M_X64) && !defined(__amd64__)
return;
#else
#if defined(_M_IX86) || defined(__i386__)
// Old 486s do not have CPUID, so we must test for its presence.
// This code is adapted from the samples in AMD's document
// entitled "AMD-K6 MMX Processor Multimedia Extensions."
#ifndef __GNUC__
__asm
{
pushfd // save EFLAGS
pop eax // store EFLAGS in EAX
mov ecx,eax // save in ECX for later testing
xor eax,0x00200000 // toggle bit 21
push eax // put to stack
popfd // save changed EAX to EFLAGS
pushfd // push EFLAGS to TOS
pop eax // store EFLAGS in EAX
cmp eax,ecx // see if bit 21 has changed
jne haveid // if no change, then no CPUID
}
return;
haveid:
#else
int oldfd, newfd;
__asm__ __volatile__("\t"
"pushf\n\t"
"popl %0\n\t"
"movl %0,%1\n\t"
"xorl $0x200000,%0\n\t"
"pushl %0\n\t"
"popf\n\t"
"pushf\n\t"
"popl %0\n\t"
: "=r" (newfd), "=r" (oldfd));
if (oldfd == newfd)
{
return;
}
#endif
#endif
// Get vendor ID // Get vendor ID
__cpuid(foo, 0); __cpuid(foo, 0);
const int maxid = foo[0];
cpu->dwVendorID[0] = foo[1]; cpu->dwVendorID[0] = foo[1];
cpu->dwVendorID[1] = foo[3]; cpu->dwVendorID[1] = foo[3];
cpu->dwVendorID[2] = foo[2]; cpu->dwVendorID[2] = foo[2];
@ -198,7 +148,17 @@ haveid:
cpu->FeatureFlags[3] = foo[3]; // AMD feature flags cpu->FeatureFlags[3] = foo[3]; // AMD feature flags
} }
} }
#endif
if (maxid >= 7)
{
__cpuidex(foo, 7, 0);
cpu->FeatureFlags[4] = foo[1];
cpu->FeatureFlags[5] = foo[2];
cpu->FeatureFlags[6] = foo[3];
__cpuidex(foo, 7, 1);
cpu->FeatureFlags[7] = foo[0];
}
} }
FString DumpCPUInfo(const CPUInfo *cpu) FString DumpCPUInfo(const CPUInfo *cpu)
@ -252,8 +212,13 @@ FString DumpCPUInfo(const CPUInfo *cpu)
if (cpu->bSSSE3) out += (" SSSE3"); if (cpu->bSSSE3) out += (" SSSE3");
if (cpu->bSSE41) out += (" SSE4.1"); if (cpu->bSSE41) out += (" SSE4.1");
if (cpu->bSSE42) out += (" SSE4.2"); if (cpu->bSSE42) out += (" SSE4.2");
if (cpu->b3DNow) out += (" 3DNow!"); if (cpu->bAVX) out += (" AVX");
if (cpu->b3DNowPlus) out += (" 3DNow!+"); if (cpu->bAVX2) out += (" AVX2");
if (cpu->bAVX512_F) out += (" AVX512");
if (cpu->bF16C) out += (" F16C");
if (cpu->bFMA3) out += (" FMA3");
if (cpu->bBMI1) out += (" BMI1");
if (cpu->bBMI2) out += (" BMI2");
if (cpu->HyperThreading) out += (" HyperThreading"); if (cpu->HyperThreading) out += (" HyperThreading");
out += ("\n"); out += ("\n");
} }

View file

@ -33,12 +33,37 @@ struct CPUInfo // 92 bytes
uint8_t APICID; uint8_t APICID;
uint32_t bSSE3:1; uint32_t bSSE3:1;
uint32_t DontCare1:8; uint32_t bPCLMULQDQ:1;
uint32_t bDTES64:1;
uint32_t bMONITOR:1;
uint32_t bDSCPL:1;
uint32_t bVMX:1;
uint32_t bSMX:1;
uint32_t bEST:1;
uint32_t bTM2:1;
uint32_t bSSSE3:1; uint32_t bSSSE3:1;
uint32_t DontCare1a:9; uint32_t bCNXTID:1;
uint32_t bSDBG:1;
uint32_t bFMA3:1;
uint32_t bCX16:1;
uint32_t bXTPR:1;
uint32_t bPDCM:1;
uint32_t bReverved1:1;
uint32_t bPCID:1;
uint32_t bDCA:1;
uint32_t bSSE41:1; uint32_t bSSE41:1;
uint32_t bSSE42:1; uint32_t bSSE42:1;
uint32_t DontCare2a:11; uint32_t bX2APIC:1;
uint32_t bMOVBE:1;
uint32_t bPOPCNT:1;
uint32_t bTSCDL:1;
uint32_t bAES:1;
uint32_t bXSAVE:1;
uint32_t bOSXSAVE:1;
uint32_t bAVX:1;
uint32_t bF16C:1;
uint32_t bRDRND:1;
uint32_t bHypervisor:1;
uint32_t bFPU:1; uint32_t bFPU:1;
uint32_t bVME:1; uint32_t bVME:1;
@ -50,7 +75,7 @@ struct CPUInfo // 92 bytes
uint32_t bMCE:1; uint32_t bMCE:1;
uint32_t bCX8:1; uint32_t bCX8:1;
uint32_t bAPIC:1; uint32_t bAPIC:1;
uint32_t bReserved1:1; uint32_t bReserved2:1;
uint32_t bSEP:1; uint32_t bSEP:1;
uint32_t bMTRR:1; uint32_t bMTRR:1;
uint32_t bPGE:1; uint32_t bPGE:1;
@ -60,7 +85,7 @@ struct CPUInfo // 92 bytes
uint32_t bPSE36:1; uint32_t bPSE36:1;
uint32_t bPSN:1; uint32_t bPSN:1;
uint32_t bCFLUSH:1; uint32_t bCFLUSH:1;
uint32_t bReserved2:1; uint32_t bReserved3:1;
uint32_t bDS:1; uint32_t bDS:1;
uint32_t bACPI:1; uint32_t bACPI:1;
uint32_t bMMX:1; uint32_t bMMX:1;
@ -70,7 +95,7 @@ struct CPUInfo // 92 bytes
uint32_t bSS:1; uint32_t bSS:1;
uint32_t bHTT:1; uint32_t bHTT:1;
uint32_t bTM:1; uint32_t bTM:1;
uint32_t bReserved3:1; uint32_t bReserved4:1;
uint32_t bPBE:1; uint32_t bPBE:1;
uint32_t DontCare2:22; uint32_t DontCare2:22;
@ -79,8 +104,107 @@ struct CPUInfo // 92 bytes
uint32_t DontCare3:6; uint32_t DontCare3:6;
uint32_t b3DNowPlus:1; uint32_t b3DNowPlus:1;
uint32_t b3DNow:1; uint32_t b3DNow:1;
uint32_t bFSGSBASE:1;
uint32_t bIA32_TSC_ADJUST:1;
uint32_t bSGX:1;
uint32_t bBMI1:1;
uint32_t bHLE:1;
uint32_t bAVX2:1;
uint32_t bFDP_EXCPTN_ONLY:1;
uint32_t bSMEP:1;
uint32_t bBMI2:1;
uint32_t bERMS:1;
uint32_t bINVPCID:1;
uint32_t bRTM:1;
uint32_t bPQM:1;
uint32_t bFPU_CS_DS:1;
uint32_t bMPX:1;
uint32_t bPQE:1;
uint32_t bAVX512_F:1;
uint32_t bAVX512_DQ:1;
uint32_t bRDSEED:1;
uint32_t bADX:1;
uint32_t bSMAP:1;
uint32_t bAVX512_IFMA:1;
uint32_t bPCOMMIT:1;
uint32_t bCLFLUSHOPT:1;
uint32_t bCLWB:1;
uint32_t bINTEL_PT:1;
uint32_t bAVX512_PF:1;
uint32_t bAVX512_ER:1;
uint32_t bAVX512_CD:1;
uint32_t bSHA:1;
uint32_t bAVX512_BW:1;
uint32_t bAVX512_VL:1;
uint32_t bPREFETCHWT1:1;
uint32_t bAVX512_VBMI:1;
uint32_t bUMIP:1;
uint32_t bPKU:1;
uint32_t bOSPKE:1;
uint32_t bWAITPKG:1;
uint32_t bAVX512_VBMI2:1;
uint32_t bCET_SS:1;
uint32_t bGFNI:1;
uint32_t bVAES:1;
uint32_t bVPCLMULQDQ:1;
uint32_t bAVX512_VNNI:1;
uint32_t bAVX512_BITALG:1;
uint32_t bReserved5:1;
uint32_t bAVX512_VPOPCNTDQ:1;
uint32_t bReserved6:1;
uint32_t b5L_PAGING:1;
uint32_t MAWAU:5;
uint32_t bRDPID:1;
uint32_t bReserved7:1;
uint32_t bReserved8:1;
uint32_t bCLDEMOTE:1;
uint32_t bReserved9:1;
uint32_t bMOVDIRI:1;
uint32_t bMOVDIR64B:1;
uint32_t bENQCMD:1;
uint32_t bSGX_LC:1;
uint32_t bPKS:1;
uint32_t bReserved10:1;
uint32_t bReserved11:1;
uint32_t bAVX512_4VNNIW:1;
uint32_t bAVX512_4FMAPS:1;
uint32_t bFSRM:1;
uint32_t bReserved12:1;
uint32_t bReserved13:1;
uint32_t bReserved14:1;
uint32_t bAVX512_VP2INTERSECT:1;
uint32_t bSRBDS_CTRL:1;
uint32_t bMD_CLEAR:1;
uint32_t bReserved15:1;
uint32_t bReserved16:1;
uint32_t bTSX_FORCE_ABORT:1;
uint32_t bSERIALIZE:1;
uint32_t bHYBRID:1;
uint32_t bTSXLDTRK:1;
uint32_t bReserved17:1;
uint32_t bPCONFIG:1;
uint32_t bLBR:1;
uint32_t bCET_IBT:1;
uint32_t bReserved18:1;
uint32_t bAMX_BF16:1;
uint32_t bReserved19:1;
uint32_t bAMX_TILE:1;
uint32_t bAMX_INT8:1;
uint32_t bIBRS_IBPB:1;
uint32_t bSTIBP:1;
uint32_t bL1D_FLUSH:1;
uint32_t bIA32_ARCH_CAPABILITIES:1;
uint32_t bIA32_CORE_CAPABILITIES:1;
uint32_t bSSBD:1;
uint32_t DontCare4:5;
uint32_t bAVX512_BF16:1;
uint32_t DontCare5:26;
}; };
uint32_t FeatureFlags[4]; uint32_t FeatureFlags[8];
}; };
uint8_t AMDStepping; uint8_t AMDStepping;
@ -103,7 +227,6 @@ struct CPUInfo // 92 bytes
extern CPUInfo CPU; extern CPUInfo CPU;
struct PalEntry;
void CheckCPUID (CPUInfo *cpu); void CheckCPUID (CPUInfo *cpu);
FString DumpCPUInfo (const CPUInfo *cpu); FString DumpCPUInfo (const CPUInfo *cpu);

View file

@ -107,7 +107,7 @@ class StatusBarCore native ui
native double, double, double, double StatusbarToRealCoords(double x, double y=0, double w=0, double h=0); native double, double, double, double StatusbarToRealCoords(double x, double y=0, double w=0, double h=0);
native void DrawTexture(TextureID texture, Vector2 pos, int flags = 0, double Alpha = 1., Vector2 box = (-1, -1), Vector2 scale = (1, 1)); native void DrawTexture(TextureID texture, Vector2 pos, int flags = 0, double Alpha = 1., Vector2 box = (-1, -1), Vector2 scale = (1, 1));
native void DrawImage(String texture, Vector2 pos, int flags = 0, double Alpha = 1., Vector2 box = (-1, -1), Vector2 scale = (1, 1)); native void DrawImage(String texture, Vector2 pos, int flags = 0, double Alpha = 1., Vector2 box = (-1, -1), Vector2 scale = (1, 1));
native void DrawString(HUDFont font, String string, Vector2 pos, int flags = 0, int translation = Font.CR_UNTRANSLATED, double Alpha = 1., int wrapwidth = -1, int linespacing = 4, Vector2 scale = (1, 1)); native void DrawString(HUDFont font, String string, Vector2 pos, int flags = 0, int translation = Font.CR_UNTRANSLATED, double Alpha = 1., int wrapwidth = -1, int linespacing = 4, Vector2 scale = (1, 1), int pt = 0);
native double, double, double, double TransformRect(double x, double y, double w, double h, int flags = 0); native double, double, double, double TransformRect(double x, double y, double w, double h, int flags = 0);
native void Fill(Color col, double x, double y, double w, double h, int flags = 0); native void Fill(Color col, double x, double y, double w, double h, int flags = 0);
native void SetClipRect(double x, double y, double w, double h, int flags = 0); native void SetClipRect(double x, double y, double w, double h, int flags = 0);