/* 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 * */ #include "FNA3D_Driver.h" #include "FNA3D_Tracing.h" #include #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: */