Show More
Commit Description:
Tweak calculations....
Commit Description:
Tweak calculations.
Prevent a negative number of visitors and separate visitors from donors.
References:
File last commit:
Show/Diff file:
Action:
FNA/lib/FNA3D/src/FNA3D.c
1523 lines | 25.8 KiB | text/x-c | CLexer
1523 lines | 25.8 KiB | text/x-c | CLexer
r690 | /* FNA3D - 3D Graphics Library for FNA | |||
* | ||||
* Copyright (c) 2020-2022 Ethan Lee | ||||
* | ||||
* 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. | ||||
* | ||||
* Ethan "flibitijibibo" Lee <flibitijibibo@flibitijibibo.com> | ||||
* | ||||
*/ | ||||
#include "FNA3D_Driver.h" | ||||
#include "FNA3D_Tracing.h" | ||||
#include <SDL.h> | ||||
#if !SDL_VERSION_ATLEAST(2, 0, 12) | ||||
#error "SDL version older than 2.0.12" | ||||
#endif /* !SDL_VERSION_ATLEAST */ | ||||
/* Drivers */ | ||||
static const FNA3D_Driver *drivers[] = { | ||||
#if FNA3D_DRIVER_D3D11 | ||||
&D3D11Driver, | ||||
#endif | ||||
#if FNA3D_DRIVER_OPENGL | ||||
&OpenGLDriver, | ||||
#endif | ||||
#if FNA3D_DRIVER_VULKAN /* TODO: Bump this to the top when Vulkan is done! */ | ||||
&VulkanDriver, | ||||
#endif | ||||
#if FNA3D_DRIVER_GNMX | ||||
&GNMXDriver, | ||||
#endif | ||||
NULL | ||||
}; | ||||
/* Logging */ | ||||
static void FNA3D_Default_LogInfo(const char *msg) | ||||
{ | ||||
SDL_LogInfo( | ||||
SDL_LOG_CATEGORY_APPLICATION, | ||||
"%s", | ||||
msg | ||||
); | ||||
} | ||||
static void FNA3D_Default_LogWarn(const char *msg) | ||||
{ | ||||
SDL_LogWarn( | ||||
SDL_LOG_CATEGORY_APPLICATION, | ||||
"%s", | ||||
msg | ||||
); | ||||
} | ||||
static void FNA3D_Default_LogError(const char *msg) | ||||
{ | ||||
SDL_LogError( | ||||
SDL_LOG_CATEGORY_APPLICATION, | ||||
"%s", | ||||
msg | ||||
); | ||||
} | ||||
static FNA3D_LogFunc FNA3D_LogInfoFunc = FNA3D_Default_LogInfo; | ||||
static FNA3D_LogFunc FNA3D_LogWarnFunc = FNA3D_Default_LogWarn; | ||||
static FNA3D_LogFunc FNA3D_LogErrorFunc = FNA3D_Default_LogError; | ||||
#define MAX_MESSAGE_SIZE 1024 | ||||
void FNA3D_LogInfo(const char *fmt, ...) | ||||
{ | ||||
char msg[MAX_MESSAGE_SIZE]; | ||||
va_list ap; | ||||
va_start(ap, fmt); | ||||
SDL_vsnprintf(msg, sizeof(msg), fmt, ap); | ||||
va_end(ap); | ||||
FNA3D_LogInfoFunc(msg); | ||||
} | ||||
void FNA3D_LogWarn(const char *fmt, ...) | ||||
{ | ||||
char msg[MAX_MESSAGE_SIZE]; | ||||
va_list ap; | ||||
va_start(ap, fmt); | ||||
SDL_vsnprintf(msg, sizeof(msg), fmt, ap); | ||||
va_end(ap); | ||||
FNA3D_LogWarnFunc(msg); | ||||
} | ||||
void FNA3D_LogError(const char *fmt, ...) | ||||
{ | ||||
char msg[MAX_MESSAGE_SIZE]; | ||||
va_list ap; | ||||
va_start(ap, fmt); | ||||
SDL_vsnprintf(msg, sizeof(msg), fmt, ap); | ||||
va_end(ap); | ||||
FNA3D_LogErrorFunc(msg); | ||||
} | ||||
#undef MAX_MESSAGE_SIZE | ||||
void FNA3D_HookLogFunctions( | ||||
FNA3D_LogFunc info, | ||||
FNA3D_LogFunc warn, | ||||
FNA3D_LogFunc error | ||||
) { | ||||
FNA3D_LogInfoFunc = info; | ||||
FNA3D_LogWarnFunc = warn; | ||||
FNA3D_LogErrorFunc = error; | ||||
} | ||||
/* Version API */ | ||||
uint32_t FNA3D_LinkedVersion(void) | ||||
{ | ||||
return FNA3D_COMPILED_VERSION; | ||||
} | ||||
/* Driver Functions */ | ||||
static int32_t selectedDriver = -1; | ||||
uint32_t FNA3D_PrepareWindowAttributes(void) | ||||
{ | ||||
uint32_t result = 0; | ||||
uint32_t i; | ||||
const char *hint = SDL_GetHint("FNA3D_FORCE_DRIVER"); | ||||
for (i = 0; drivers[i] != NULL; i += 1) | ||||
{ | ||||
if (hint != NULL) | ||||
{ | ||||
if (SDL_strcmp(hint, drivers[i]->Name) != 0) | ||||
{ | ||||
continue; | ||||
} | ||||
} | ||||
if (drivers[i]->PrepareWindowAttributes(&result)) | ||||
{ | ||||
break; | ||||
} | ||||
} | ||||
if (drivers[i] == NULL) | ||||
{ | ||||
FNA3D_LogError("No supported FNA3D driver found!"); | ||||
} | ||||
else | ||||
{ | ||||
selectedDriver = i; | ||||
} | ||||
return result; | ||||
} | ||||
FNA3DAPI void FNA3D_GetDrawableSize(void* window, int32_t *w, int32_t *h) | ||||
{ | ||||
if (selectedDriver < 0) | ||||
{ | ||||
FNA3D_LogError("Call FNA3D_PrepareWindowAttributes first!"); | ||||
return; | ||||
} | ||||
drivers[selectedDriver]->GetDrawableSize(window, w, h); | ||||
} | ||||
/* Init/Quit */ | ||||
FNA3D_Device* FNA3D_CreateDevice( | ||||
FNA3D_PresentationParameters *presentationParameters, | ||||
uint8_t debugMode | ||||
) { | ||||
TRACE_CREATEDEVICE | ||||
if (selectedDriver < 0) | ||||
{ | ||||
FNA3D_LogError("Call FNA3D_PrepareWindowAttributes first!"); | ||||
return NULL; | ||||
} | ||||
return drivers[selectedDriver]->CreateDevice( | ||||
presentationParameters, | ||||
debugMode | ||||
); | ||||
} | ||||
void FNA3D_DestroyDevice(FNA3D_Device *device) | ||||
{ | ||||
TRACE_DESTROYDEVICE | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->DestroyDevice(device); | ||||
} | ||||
/* Presentation */ | ||||
void FNA3D_SwapBuffers( | ||||
FNA3D_Device *device, | ||||
FNA3D_Rect *sourceRectangle, | ||||
FNA3D_Rect *destinationRectangle, | ||||
void* overrideWindowHandle | ||||
) { | ||||
TRACE_SWAPBUFFERS | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->SwapBuffers( | ||||
device->driverData, | ||||
sourceRectangle, | ||||
destinationRectangle, | ||||
overrideWindowHandle | ||||
); | ||||
} | ||||
/* Drawing */ | ||||
void FNA3D_Clear( | ||||
FNA3D_Device *device, | ||||
FNA3D_ClearOptions options, | ||||
FNA3D_Vec4 *color, | ||||
float depth, | ||||
int32_t stencil | ||||
) { | ||||
TRACE_CLEAR | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->Clear(device->driverData, options, color, depth, stencil); | ||||
} | ||||
void FNA3D_DrawIndexedPrimitives( | ||||
FNA3D_Device *device, | ||||
FNA3D_PrimitiveType primitiveType, | ||||
int32_t baseVertex, | ||||
int32_t minVertexIndex, | ||||
int32_t numVertices, | ||||
int32_t startIndex, | ||||
int32_t primitiveCount, | ||||
FNA3D_Buffer *indices, | ||||
FNA3D_IndexElementSize indexElementSize | ||||
) { | ||||
TRACE_DRAWINDEXEDPRIMITIVES | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->DrawIndexedPrimitives( | ||||
device->driverData, | ||||
primitiveType, | ||||
baseVertex, | ||||
minVertexIndex, | ||||
numVertices, | ||||
startIndex, | ||||
primitiveCount, | ||||
indices, | ||||
indexElementSize | ||||
); | ||||
} | ||||
void FNA3D_DrawInstancedPrimitives( | ||||
FNA3D_Device *device, | ||||
FNA3D_PrimitiveType primitiveType, | ||||
int32_t baseVertex, | ||||
int32_t minVertexIndex, | ||||
int32_t numVertices, | ||||
int32_t startIndex, | ||||
int32_t primitiveCount, | ||||
int32_t instanceCount, | ||||
FNA3D_Buffer *indices, | ||||
FNA3D_IndexElementSize indexElementSize | ||||
) { | ||||
TRACE_DRAWINSTANCEDPRIMITIVES | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->DrawInstancedPrimitives( | ||||
device->driverData, | ||||
primitiveType, | ||||
baseVertex, | ||||
minVertexIndex, | ||||
numVertices, | ||||
startIndex, | ||||
primitiveCount, | ||||
instanceCount, | ||||
indices, | ||||
indexElementSize | ||||
); | ||||
} | ||||
void FNA3D_DrawPrimitives( | ||||
FNA3D_Device *device, | ||||
FNA3D_PrimitiveType primitiveType, | ||||
int32_t vertexStart, | ||||
int32_t primitiveCount | ||||
) { | ||||
TRACE_DRAWPRIMITIVES | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->DrawPrimitives( | ||||
device->driverData, | ||||
primitiveType, | ||||
vertexStart, | ||||
primitiveCount | ||||
); | ||||
} | ||||
/* Mutable Render States */ | ||||
void FNA3D_SetViewport(FNA3D_Device *device, FNA3D_Viewport *viewport) | ||||
{ | ||||
TRACE_SETVIEWPORT | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->SetViewport(device->driverData, viewport); | ||||
} | ||||
void FNA3D_SetScissorRect(FNA3D_Device *device, FNA3D_Rect *scissor) | ||||
{ | ||||
TRACE_SETSCISSORRECT | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->SetScissorRect(device->driverData, scissor); | ||||
} | ||||
void FNA3D_GetBlendFactor( | ||||
FNA3D_Device *device, | ||||
FNA3D_Color *blendFactor | ||||
) { | ||||
/* Not traced! */ | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->GetBlendFactor(device->driverData, blendFactor); | ||||
} | ||||
void FNA3D_SetBlendFactor( | ||||
FNA3D_Device *device, | ||||
FNA3D_Color *blendFactor | ||||
) { | ||||
TRACE_SETBLENDFACTOR | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->SetBlendFactor(device->driverData, blendFactor); | ||||
} | ||||
int32_t FNA3D_GetMultiSampleMask(FNA3D_Device *device) | ||||
{ | ||||
/* Not traced! */ | ||||
if (device == NULL) | ||||
{ | ||||
return 0; | ||||
} | ||||
return device->GetMultiSampleMask(device->driverData); | ||||
} | ||||
void FNA3D_SetMultiSampleMask(FNA3D_Device *device, int32_t mask) | ||||
{ | ||||
TRACE_SETMULTISAMPLEMASK | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->SetMultiSampleMask(device->driverData, mask); | ||||
} | ||||
int32_t FNA3D_GetReferenceStencil(FNA3D_Device *device) | ||||
{ | ||||
/* Not traced! */ | ||||
if (device == NULL) | ||||
{ | ||||
return 0; | ||||
} | ||||
return device->GetReferenceStencil(device->driverData); | ||||
} | ||||
void FNA3D_SetReferenceStencil(FNA3D_Device *device, int32_t ref) | ||||
{ | ||||
TRACE_SETREFERENCESTENCIL | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->SetReferenceStencil(device->driverData, ref); | ||||
} | ||||
/* Immutable Render States */ | ||||
void FNA3D_SetBlendState( | ||||
FNA3D_Device *device, | ||||
FNA3D_BlendState *blendState | ||||
) { | ||||
TRACE_SETBLENDSTATE | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->SetBlendState(device->driverData, blendState); | ||||
} | ||||
void FNA3D_SetDepthStencilState( | ||||
FNA3D_Device *device, | ||||
FNA3D_DepthStencilState *depthStencilState | ||||
) { | ||||
TRACE_SETDEPTHSTENCILSTATE | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->SetDepthStencilState(device->driverData, depthStencilState); | ||||
} | ||||
void FNA3D_ApplyRasterizerState( | ||||
FNA3D_Device *device, | ||||
FNA3D_RasterizerState *rasterizerState | ||||
) { | ||||
TRACE_APPLYRASTERIZERSTATE | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->ApplyRasterizerState(device->driverData, rasterizerState); | ||||
} | ||||
void FNA3D_VerifySampler( | ||||
FNA3D_Device *device, | ||||
int32_t index, | ||||
FNA3D_Texture *texture, | ||||
FNA3D_SamplerState *sampler | ||||
) { | ||||
TRACE_VERIFYSAMPLER | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->VerifySampler(device->driverData, index, texture, sampler); | ||||
} | ||||
void FNA3D_VerifyVertexSampler( | ||||
FNA3D_Device *device, | ||||
int32_t index, | ||||
FNA3D_Texture *texture, | ||||
FNA3D_SamplerState *sampler | ||||
) { | ||||
TRACE_VERIFYVERTEXSAMPLER | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->VerifyVertexSampler(device->driverData, index, texture, sampler); | ||||
} | ||||
void FNA3D_ApplyVertexBufferBindings( | ||||
FNA3D_Device *device, | ||||
FNA3D_VertexBufferBinding *bindings, | ||||
int32_t numBindings, | ||||
uint8_t bindingsUpdated, | ||||
int32_t baseVertex | ||||
) { | ||||
TRACE_APPLYVERTEXBUFFERBINDINGS | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->ApplyVertexBufferBindings( | ||||
device->driverData, | ||||
bindings, | ||||
numBindings, | ||||
bindingsUpdated, | ||||
baseVertex | ||||
); | ||||
} | ||||
/* Render Targets */ | ||||
void FNA3D_SetRenderTargets( | ||||
FNA3D_Device *device, | ||||
FNA3D_RenderTargetBinding *renderTargets, | ||||
int32_t numRenderTargets, | ||||
FNA3D_Renderbuffer *depthStencilBuffer, | ||||
FNA3D_DepthFormat depthFormat, | ||||
uint8_t preserveTargetContents | ||||
) { | ||||
TRACE_SETRENDERTARGETS | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->SetRenderTargets( | ||||
device->driverData, | ||||
renderTargets, | ||||
numRenderTargets, | ||||
depthStencilBuffer, | ||||
depthFormat, | ||||
preserveTargetContents | ||||
); | ||||
} | ||||
void FNA3D_ResolveTarget( | ||||
FNA3D_Device *device, | ||||
FNA3D_RenderTargetBinding *target | ||||
) { | ||||
TRACE_RESOLVETARGET | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->ResolveTarget(device->driverData, target); | ||||
} | ||||
/* Backbuffer Functions */ | ||||
void FNA3D_ResetBackbuffer( | ||||
FNA3D_Device *device, | ||||
FNA3D_PresentationParameters *presentationParameters | ||||
) { | ||||
TRACE_RESETBACKBUFFER | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->ResetBackbuffer(device->driverData, presentationParameters); | ||||
} | ||||
void FNA3D_ReadBackbuffer( | ||||
FNA3D_Device *device, | ||||
int32_t x, | ||||
int32_t y, | ||||
int32_t w, | ||||
int32_t h, | ||||
void* data, | ||||
int32_t dataLength | ||||
) { | ||||
TRACE_READBACKBUFFER | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->ReadBackbuffer( | ||||
device->driverData, | ||||
x, | ||||
y, | ||||
w, | ||||
h, | ||||
data, | ||||
dataLength | ||||
); | ||||
} | ||||
void FNA3D_GetBackbufferSize( | ||||
FNA3D_Device *device, | ||||
int32_t *w, | ||||
int32_t *h | ||||
) { | ||||
/* Not traced! */ | ||||
if (device == NULL) | ||||
{ | ||||
*w = 0; | ||||
*h = 0; | ||||
return; | ||||
} | ||||
device->GetBackbufferSize(device->driverData, w, h); | ||||
} | ||||
FNA3D_SurfaceFormat FNA3D_GetBackbufferSurfaceFormat(FNA3D_Device *device) | ||||
{ | ||||
/* Not traced! */ | ||||
if (device == NULL) | ||||
{ | ||||
return FNA3D_SURFACEFORMAT_COLOR; | ||||
} | ||||
return device->GetBackbufferSurfaceFormat(device->driverData); | ||||
} | ||||
FNA3D_DepthFormat FNA3D_GetBackbufferDepthFormat(FNA3D_Device *device) | ||||
{ | ||||
/* Not traced! */ | ||||
if (device == NULL) | ||||
{ | ||||
return FNA3D_DEPTHFORMAT_NONE; | ||||
} | ||||
return device->GetBackbufferDepthFormat(device->driverData); | ||||
} | ||||
int32_t FNA3D_GetBackbufferMultiSampleCount(FNA3D_Device *device) | ||||
{ | ||||
/* Not traced! */ | ||||
if (device == NULL) | ||||
{ | ||||
return 0; | ||||
} | ||||
return device->GetBackbufferMultiSampleCount(device->driverData); | ||||
} | ||||
/* Textures */ | ||||
FNA3D_Texture* FNA3D_CreateTexture2D( | ||||
FNA3D_Device *device, | ||||
FNA3D_SurfaceFormat format, | ||||
int32_t width, | ||||
int32_t height, | ||||
int32_t levelCount, | ||||
uint8_t isRenderTarget | ||||
) { | ||||
/* We're stuck tracing _after_ the call instead of _before_, because | ||||
* of threading issues. This can cause timing issues! | ||||
*/ | ||||
FNA3D_Texture *result; | ||||
if (device == NULL) | ||||
{ | ||||
return NULL; | ||||
} | ||||
result = device->CreateTexture2D( | ||||
device->driverData, | ||||
format, | ||||
width, | ||||
height, | ||||
levelCount, | ||||
isRenderTarget | ||||
); | ||||
TRACE_CREATETEXTURE2D | ||||
return result; | ||||
} | ||||
FNA3D_Texture* FNA3D_CreateTexture3D( | ||||
FNA3D_Device *device, | ||||
FNA3D_SurfaceFormat format, | ||||
int32_t width, | ||||
int32_t height, | ||||
int32_t depth, | ||||
int32_t levelCount | ||||
) { | ||||
/* We're stuck tracing _after_ the call instead of _before_, because | ||||
* of threading issues. This can cause timing issues! | ||||
*/ | ||||
FNA3D_Texture *result; | ||||
if (device == NULL) | ||||
{ | ||||
return NULL; | ||||
} | ||||
result = device->CreateTexture3D( | ||||
device->driverData, | ||||
format, | ||||
width, | ||||
height, | ||||
depth, | ||||
levelCount | ||||
); | ||||
TRACE_CREATETEXTURE3D | ||||
return result; | ||||
} | ||||
FNA3D_Texture* FNA3D_CreateTextureCube( | ||||
FNA3D_Device *device, | ||||
FNA3D_SurfaceFormat format, | ||||
int32_t size, | ||||
int32_t levelCount, | ||||
uint8_t isRenderTarget | ||||
) { | ||||
/* We're stuck tracing _after_ the call instead of _before_, because | ||||
* of threading issues. This can cause timing issues! | ||||
*/ | ||||
FNA3D_Texture *result; | ||||
if (device == NULL) | ||||
{ | ||||
return NULL; | ||||
} | ||||
result = device->CreateTextureCube( | ||||
device->driverData, | ||||
format, | ||||
size, | ||||
levelCount, | ||||
isRenderTarget | ||||
); | ||||
TRACE_CREATETEXTURECUBE | ||||
return result; | ||||
} | ||||
void FNA3D_AddDisposeTexture( | ||||
FNA3D_Device *device, | ||||
FNA3D_Texture *texture | ||||
) { | ||||
TRACE_ADDDISPOSETEXTURE | ||||
if (device == NULL || texture == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->AddDisposeTexture(device->driverData, texture); | ||||
} | ||||
void FNA3D_SetTextureData2D( | ||||
FNA3D_Device *device, | ||||
FNA3D_Texture *texture, | ||||
int32_t x, | ||||
int32_t y, | ||||
int32_t w, | ||||
int32_t h, | ||||
int32_t level, | ||||
void* data, | ||||
int32_t dataLength | ||||
) { | ||||
TRACE_SETTEXTUREDATA2D | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->SetTextureData2D( | ||||
device->driverData, | ||||
texture, | ||||
x, | ||||
y, | ||||
w, | ||||
h, | ||||
level, | ||||
data, | ||||
dataLength | ||||
); | ||||
} | ||||
void FNA3D_SetTextureData3D( | ||||
FNA3D_Device *device, | ||||
FNA3D_Texture *texture, | ||||
int32_t x, | ||||
int32_t y, | ||||
int32_t z, | ||||
int32_t w, | ||||
int32_t h, | ||||
int32_t d, | ||||
int32_t level, | ||||
void* data, | ||||
int32_t dataLength | ||||
) { | ||||
TRACE_SETTEXTUREDATA3D | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->SetTextureData3D( | ||||
device->driverData, | ||||
texture, | ||||
x, | ||||
y, | ||||
z, | ||||
w, | ||||
h, | ||||
d, | ||||
level, | ||||
data, | ||||
dataLength | ||||
); | ||||
} | ||||
void FNA3D_SetTextureDataCube( | ||||
FNA3D_Device *device, | ||||
FNA3D_Texture *texture, | ||||
int32_t x, | ||||
int32_t y, | ||||
int32_t w, | ||||
int32_t h, | ||||
FNA3D_CubeMapFace cubeMapFace, | ||||
int32_t level, | ||||
void* data, | ||||
int32_t dataLength | ||||
) { | ||||
TRACE_SETTEXTUREDATACUBE | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->SetTextureDataCube( | ||||
device->driverData, | ||||
texture, | ||||
x, | ||||
y, | ||||
w, | ||||
h, | ||||
cubeMapFace, | ||||
level, | ||||
data, | ||||
dataLength | ||||
); | ||||
} | ||||
void FNA3D_SetTextureDataYUV( | ||||
FNA3D_Device *device, | ||||
FNA3D_Texture *y, | ||||
FNA3D_Texture *u, | ||||
FNA3D_Texture *v, | ||||
int32_t yWidth, | ||||
int32_t yHeight, | ||||
int32_t uvWidth, | ||||
int32_t uvHeight, | ||||
void* data, | ||||
int32_t dataLength | ||||
) { | ||||
TRACE_SETTEXTUREDATAYUV | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->SetTextureDataYUV( | ||||
device->driverData, | ||||
y, | ||||
u, | ||||
v, | ||||
yWidth, | ||||
yHeight, | ||||
uvWidth, | ||||
uvHeight, | ||||
data, | ||||
dataLength | ||||
); | ||||
} | ||||
void FNA3D_GetTextureData2D( | ||||
FNA3D_Device *device, | ||||
FNA3D_Texture *texture, | ||||
int32_t x, | ||||
int32_t y, | ||||
int32_t w, | ||||
int32_t h, | ||||
int32_t level, | ||||
void* data, | ||||
int32_t dataLength | ||||
) { | ||||
TRACE_GETTEXTUREDATA2D | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->GetTextureData2D( | ||||
device->driverData, | ||||
texture, | ||||
x, | ||||
y, | ||||
w, | ||||
h, | ||||
level, | ||||
data, | ||||
dataLength | ||||
); | ||||
} | ||||
void FNA3D_GetTextureData3D( | ||||
FNA3D_Device *device, | ||||
FNA3D_Texture *texture, | ||||
int32_t x, | ||||
int32_t y, | ||||
int32_t z, | ||||
int32_t w, | ||||
int32_t h, | ||||
int32_t d, | ||||
int32_t level, | ||||
void* data, | ||||
int32_t dataLength | ||||
) { | ||||
TRACE_SETTEXTUREDATA3D | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->GetTextureData3D( | ||||
device->driverData, | ||||
texture, | ||||
x, | ||||
y, | ||||
z, | ||||
w, | ||||
h, | ||||
d, | ||||
level, | ||||
data, | ||||
dataLength | ||||
); | ||||
} | ||||
void FNA3D_GetTextureDataCube( | ||||
FNA3D_Device *device, | ||||
FNA3D_Texture *texture, | ||||
int32_t x, | ||||
int32_t y, | ||||
int32_t w, | ||||
int32_t h, | ||||
FNA3D_CubeMapFace cubeMapFace, | ||||
int32_t level, | ||||
void* data, | ||||
int32_t dataLength | ||||
) { | ||||
TRACE_GETTEXTUREDATACUBE | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->GetTextureDataCube( | ||||
device->driverData, | ||||
texture, | ||||
x, | ||||
y, | ||||
w, | ||||
h, | ||||
cubeMapFace, | ||||
level, | ||||
data, | ||||
dataLength | ||||
); | ||||
} | ||||
/* Renderbuffers */ | ||||
FNA3D_Renderbuffer* FNA3D_GenColorRenderbuffer( | ||||
FNA3D_Device *device, | ||||
int32_t width, | ||||
int32_t height, | ||||
FNA3D_SurfaceFormat format, | ||||
int32_t multiSampleCount, | ||||
FNA3D_Texture *texture | ||||
) { | ||||
/* We're stuck tracing _after_ the call instead of _before_, because | ||||
* of threading issues. This can cause timing issues! | ||||
*/ | ||||
FNA3D_Renderbuffer *result; | ||||
if (device == NULL) | ||||
{ | ||||
return NULL; | ||||
} | ||||
result = device->GenColorRenderbuffer( | ||||
device->driverData, | ||||
width, | ||||
height, | ||||
format, | ||||
multiSampleCount, | ||||
texture | ||||
); | ||||
TRACE_GENCOLORRENDERBUFFER | ||||
return result; | ||||
} | ||||
FNA3D_Renderbuffer* FNA3D_GenDepthStencilRenderbuffer( | ||||
FNA3D_Device *device, | ||||
int32_t width, | ||||
int32_t height, | ||||
FNA3D_DepthFormat format, | ||||
int32_t multiSampleCount | ||||
) { | ||||
/* We're stuck tracing _after_ the call instead of _before_, because | ||||
* of threading issues. This can cause timing issues! | ||||
*/ | ||||
FNA3D_Renderbuffer *result; | ||||
if (device == NULL) | ||||
{ | ||||
return NULL; | ||||
} | ||||
result = device->GenDepthStencilRenderbuffer( | ||||
device->driverData, | ||||
width, | ||||
height, | ||||
format, | ||||
multiSampleCount | ||||
); | ||||
TRACE_GENDEPTHSTENCILRENDERBUFFER | ||||
return result; | ||||
} | ||||
void FNA3D_AddDisposeRenderbuffer( | ||||
FNA3D_Device *device, | ||||
FNA3D_Renderbuffer *renderbuffer | ||||
) { | ||||
TRACE_ADDDISPOSERENDERBUFFER | ||||
if (device == NULL || renderbuffer == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->AddDisposeRenderbuffer( | ||||
device->driverData, | ||||
renderbuffer | ||||
); | ||||
} | ||||
/* Vertex Buffers */ | ||||
FNA3D_Buffer* FNA3D_GenVertexBuffer( | ||||
FNA3D_Device *device, | ||||
uint8_t dynamic, | ||||
FNA3D_BufferUsage usage, | ||||
int32_t sizeInBytes | ||||
) { | ||||
/* We're stuck tracing _after_ the call instead of _before_, because | ||||
* of threading issues. This can cause timing issues! | ||||
*/ | ||||
FNA3D_Buffer *result; | ||||
if (device == NULL) | ||||
{ | ||||
return NULL; | ||||
} | ||||
result = device->GenVertexBuffer( | ||||
device->driverData, | ||||
dynamic, | ||||
usage, | ||||
sizeInBytes | ||||
); | ||||
TRACE_GENVERTEXBUFFER | ||||
return result; | ||||
} | ||||
void FNA3D_AddDisposeVertexBuffer( | ||||
FNA3D_Device *device, | ||||
FNA3D_Buffer *buffer | ||||
) { | ||||
TRACE_ADDDISPOSEVERTEXBUFFER | ||||
if (device == NULL || buffer == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->AddDisposeVertexBuffer(device->driverData, buffer); | ||||
} | ||||
void FNA3D_SetVertexBufferData( | ||||
FNA3D_Device *device, | ||||
FNA3D_Buffer *buffer, | ||||
int32_t offsetInBytes, | ||||
void* data, | ||||
int32_t elementCount, | ||||
int32_t elementSizeInBytes, | ||||
int32_t vertexStride, | ||||
FNA3D_SetDataOptions options | ||||
) { | ||||
TRACE_SETVERTEXBUFFERDATA | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->SetVertexBufferData( | ||||
device->driverData, | ||||
buffer, | ||||
offsetInBytes, | ||||
data, | ||||
elementCount, | ||||
elementSizeInBytes, | ||||
vertexStride, | ||||
options | ||||
); | ||||
} | ||||
void FNA3D_GetVertexBufferData( | ||||
FNA3D_Device *device, | ||||
FNA3D_Buffer *buffer, | ||||
int32_t offsetInBytes, | ||||
void* data, | ||||
int32_t elementCount, | ||||
int32_t elementSizeInBytes, | ||||
int32_t vertexStride | ||||
) { | ||||
TRACE_GETVERTEXBUFFERDATA | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->GetVertexBufferData( | ||||
device->driverData, | ||||
buffer, | ||||
offsetInBytes, | ||||
data, | ||||
elementCount, | ||||
elementSizeInBytes, | ||||
vertexStride | ||||
); | ||||
} | ||||
/* Index Buffers */ | ||||
FNA3D_Buffer* FNA3D_GenIndexBuffer( | ||||
FNA3D_Device *device, | ||||
uint8_t dynamic, | ||||
FNA3D_BufferUsage usage, | ||||
int32_t sizeInBytes | ||||
) { | ||||
/* We're stuck tracing _after_ the call instead of _before_, because | ||||
* of threading issues. This can cause timing issues! | ||||
*/ | ||||
FNA3D_Buffer *result; | ||||
if (device == NULL) | ||||
{ | ||||
return NULL; | ||||
} | ||||
result = device->GenIndexBuffer( | ||||
device->driverData, | ||||
dynamic, | ||||
usage, | ||||
sizeInBytes | ||||
); | ||||
TRACE_GENINDEXBUFFER | ||||
return result; | ||||
} | ||||
void FNA3D_AddDisposeIndexBuffer( | ||||
FNA3D_Device *device, | ||||
FNA3D_Buffer *buffer | ||||
) { | ||||
TRACE_ADDDISPOSEINDEXBUFFER | ||||
if (device == NULL || buffer == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->AddDisposeIndexBuffer(device->driverData, buffer); | ||||
} | ||||
void FNA3D_SetIndexBufferData( | ||||
FNA3D_Device *device, | ||||
FNA3D_Buffer *buffer, | ||||
int32_t offsetInBytes, | ||||
void* data, | ||||
int32_t dataLength, | ||||
FNA3D_SetDataOptions options | ||||
) { | ||||
TRACE_SETINDEXBUFFERDATA | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->SetIndexBufferData( | ||||
device->driverData, | ||||
buffer, | ||||
offsetInBytes, | ||||
data, | ||||
dataLength, | ||||
options | ||||
); | ||||
} | ||||
void FNA3D_GetIndexBufferData( | ||||
FNA3D_Device *device, | ||||
FNA3D_Buffer *buffer, | ||||
int32_t offsetInBytes, | ||||
void* data, | ||||
int32_t dataLength | ||||
) { | ||||
TRACE_GETINDEXBUFFERDATA | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->GetIndexBufferData( | ||||
device->driverData, | ||||
buffer, | ||||
offsetInBytes, | ||||
data, | ||||
dataLength | ||||
); | ||||
} | ||||
/* Effects */ | ||||
void FNA3D_CreateEffect( | ||||
FNA3D_Device *device, | ||||
uint8_t *effectCode, | ||||
uint32_t effectCodeLength, | ||||
FNA3D_Effect **effect, | ||||
MOJOSHADER_effect **effectData | ||||
) { | ||||
/* We're stuck tracing _after_ the call instead of _before_, because | ||||
* of threading issues. This can cause timing issues! | ||||
*/ | ||||
if (device == NULL) | ||||
{ | ||||
*effect = NULL; | ||||
*effectData = NULL; | ||||
return; | ||||
} | ||||
device->CreateEffect( | ||||
device->driverData, | ||||
effectCode, | ||||
effectCodeLength, | ||||
effect, | ||||
effectData | ||||
); | ||||
TRACE_CREATEEFFECT | ||||
} | ||||
void FNA3D_CloneEffect( | ||||
FNA3D_Device *device, | ||||
FNA3D_Effect *cloneSource, | ||||
FNA3D_Effect **effect, | ||||
MOJOSHADER_effect **effectData | ||||
) { | ||||
/* We're stuck tracing _after_ the call instead of _before_, because | ||||
* of threading issues. This can cause timing issues! | ||||
*/ | ||||
if (device == NULL) | ||||
{ | ||||
*effect = NULL; | ||||
*effectData = NULL; | ||||
return; | ||||
} | ||||
device->CloneEffect( | ||||
device->driverData, | ||||
cloneSource, | ||||
effect, | ||||
effectData | ||||
); | ||||
TRACE_CLONEEFFECT | ||||
} | ||||
void FNA3D_AddDisposeEffect( | ||||
FNA3D_Device *device, | ||||
FNA3D_Effect *effect | ||||
) { | ||||
TRACE_ADDDISPOSEEFFECT | ||||
if (device == NULL || effect == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->AddDisposeEffect(device->driverData, effect); | ||||
} | ||||
void FNA3D_SetEffectTechnique( | ||||
FNA3D_Device *device, | ||||
FNA3D_Effect *effect, | ||||
MOJOSHADER_effectTechnique *technique | ||||
) { | ||||
TRACE_SETEFFECTTECHNIQUE | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->SetEffectTechnique(device->driverData, effect, technique); | ||||
} | ||||
void FNA3D_ApplyEffect( | ||||
FNA3D_Device *device, | ||||
FNA3D_Effect *effect, | ||||
uint32_t pass, | ||||
MOJOSHADER_effectStateChanges *stateChanges | ||||
) { | ||||
TRACE_APPLYEFFECT | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->ApplyEffect( | ||||
device->driverData, | ||||
effect, | ||||
pass, | ||||
stateChanges | ||||
); | ||||
} | ||||
void FNA3D_BeginPassRestore( | ||||
FNA3D_Device *device, | ||||
FNA3D_Effect *effect, | ||||
MOJOSHADER_effectStateChanges *stateChanges | ||||
) { | ||||
TRACE_BEGINPASSRESTORE | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->BeginPassRestore( | ||||
device->driverData, | ||||
effect, | ||||
stateChanges | ||||
); | ||||
} | ||||
void FNA3D_EndPassRestore( | ||||
FNA3D_Device *device, | ||||
FNA3D_Effect *effect | ||||
) { | ||||
TRACE_ENDPASSRESTORE | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->EndPassRestore(device->driverData, effect); | ||||
} | ||||
/* Queries */ | ||||
FNA3D_Query* FNA3D_CreateQuery(FNA3D_Device *device) | ||||
{ | ||||
/* We're stuck tracing _after_ the call instead of _before_, because | ||||
* of threading issues. This can cause timing issues! | ||||
*/ | ||||
FNA3D_Query *result; | ||||
if (device == NULL) | ||||
{ | ||||
return NULL; | ||||
} | ||||
result = device->CreateQuery(device->driverData); | ||||
TRACE_CREATEQUERY | ||||
return result; | ||||
} | ||||
void FNA3D_AddDisposeQuery(FNA3D_Device *device, FNA3D_Query *query) | ||||
{ | ||||
TRACE_ADDDISPOSEQUERY | ||||
if (device == NULL || query == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->AddDisposeQuery(device->driverData, query); | ||||
} | ||||
void FNA3D_QueryBegin(FNA3D_Device *device, FNA3D_Query *query) | ||||
{ | ||||
TRACE_QUERYBEGIN | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->QueryBegin(device->driverData, query); | ||||
} | ||||
void FNA3D_QueryEnd(FNA3D_Device *device, FNA3D_Query *query) | ||||
{ | ||||
TRACE_QUERYEND | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->QueryEnd(device->driverData, query); | ||||
} | ||||
uint8_t FNA3D_QueryComplete(FNA3D_Device *device, FNA3D_Query *query) | ||||
{ | ||||
/* Not traced! */ | ||||
if (device == NULL) | ||||
{ | ||||
return 1; | ||||
} | ||||
return device->QueryComplete(device->driverData, query); | ||||
} | ||||
int32_t FNA3D_QueryPixelCount( | ||||
FNA3D_Device *device, | ||||
FNA3D_Query *query | ||||
) { | ||||
TRACE_QUERYPIXELCOUNT | ||||
if (device == NULL) | ||||
{ | ||||
return 0; | ||||
} | ||||
return device->QueryPixelCount(device->driverData, query); | ||||
} | ||||
/* Feature Queries */ | ||||
uint8_t FNA3D_SupportsDXT1(FNA3D_Device *device) | ||||
{ | ||||
/* Not traced! */ | ||||
if (device == NULL) | ||||
{ | ||||
return 0; | ||||
} | ||||
return device->SupportsDXT1(device->driverData); | ||||
} | ||||
uint8_t FNA3D_SupportsS3TC(FNA3D_Device *device) | ||||
{ | ||||
/* Not traced! */ | ||||
if (device == NULL) | ||||
{ | ||||
return 0; | ||||
} | ||||
return device->SupportsS3TC(device->driverData); | ||||
} | ||||
uint8_t FNA3D_SupportsBC7(FNA3D_Device *device) | ||||
{ | ||||
/* Not traced! */ | ||||
if (device == NULL) | ||||
{ | ||||
return 0; | ||||
} | ||||
return device->SupportsBC7(device->driverData); | ||||
} | ||||
uint8_t FNA3D_SupportsHardwareInstancing(FNA3D_Device *device) | ||||
{ | ||||
/* Not traced! */ | ||||
if (device == NULL) | ||||
{ | ||||
return 0; | ||||
} | ||||
return device->SupportsHardwareInstancing(device->driverData); | ||||
} | ||||
uint8_t FNA3D_SupportsNoOverwrite(FNA3D_Device *device) | ||||
{ | ||||
/* Not traced! */ | ||||
if (device == NULL) | ||||
{ | ||||
return 0; | ||||
} | ||||
return device->SupportsNoOverwrite(device->driverData); | ||||
} | ||||
uint8_t FNA3D_SupportsSRGBRenderTargets(FNA3D_Device *device) | ||||
{ | ||||
/* Not traced! */ | ||||
if (device == NULL) | ||||
{ | ||||
return 0; | ||||
} | ||||
return device->SupportsSRGBRenderTargets(device->driverData); | ||||
} | ||||
void FNA3D_GetMaxTextureSlots( | ||||
FNA3D_Device *device, | ||||
int32_t *textures, | ||||
int32_t *vertexTextures | ||||
) { | ||||
/* Not traced! */ | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->GetMaxTextureSlots( | ||||
device->driverData, | ||||
textures, | ||||
vertexTextures | ||||
); | ||||
} | ||||
int32_t FNA3D_GetMaxMultiSampleCount( | ||||
FNA3D_Device *device, | ||||
FNA3D_SurfaceFormat format, | ||||
int32_t multiSampleCount | ||||
) { | ||||
/* Not traced! */ | ||||
if (device == NULL) | ||||
{ | ||||
return 0; | ||||
} | ||||
return device->GetMaxMultiSampleCount( | ||||
device->driverData, | ||||
format, | ||||
multiSampleCount | ||||
); | ||||
} | ||||
/* Debugging */ | ||||
void FNA3D_SetStringMarker(FNA3D_Device *device, const char *text) | ||||
{ | ||||
TRACE_SETSTRINGMARKER | ||||
if (device == NULL) | ||||
{ | ||||
return; | ||||
} | ||||
device->SetStringMarker(device->driverData, text); | ||||
} | ||||
/* External Interop */ | ||||
void FNA3D_GetSysRendererEXT( | ||||
FNA3D_Device *device, | ||||
FNA3D_SysRendererEXT *sysrenderer | ||||
) { | ||||
#ifdef FNA3D_TRACING | ||||
SDL_assert(0 && "Tracing does not support SysRendererEXT!"); | ||||
#endif | ||||
if ( device == NULL || | ||||
sysrenderer == NULL || | ||||
sysrenderer->version != FNA3D_SYSRENDERER_VERSION_EXT ) | ||||
{ | ||||
return; | ||||
} | ||||
device->GetSysRenderer( | ||||
device->driverData, | ||||
sysrenderer | ||||
); | ||||
} | ||||
FNA3D_Texture* FNA3D_CreateSysTextureEXT( | ||||
FNA3D_Device *device, | ||||
FNA3D_SysTextureEXT *systexture | ||||
) { | ||||
#ifdef FNA3D_TRACING | ||||
SDL_assert(0 && "Tracing does not support SysTextureEXT!"); | ||||
#endif | ||||
if ( device == NULL || | ||||
systexture == NULL || | ||||
systexture->version != FNA3D_SYSRENDERER_VERSION_EXT ) | ||||
{ | ||||
return NULL; | ||||
} | ||||
return device->CreateSysTexture( | ||||
device->driverData, | ||||
systexture | ||||
); | ||||
} | ||||
/* vim: set noexpandtab shiftwidth=8 tabstop=8: */ | ||||