12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798 |
- /*
- Simple DirectMedia Layer
- Copyright (C) 1997-2024 Sam Lantinga <[email protected]>
- 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 "SDL_internal.h"
- #include "SDL_sysgpu.h"
- // FIXME: This could probably use SDL_ObjectValid
- #define CHECK_DEVICE_MAGIC(device, retval) \
- if (device == NULL) { \
- SDL_SetError("Invalid GPU device"); \
- return retval; \
- }
- #define CHECK_COMMAND_BUFFER \
- if (((CommandBufferCommonHeader *)command_buffer)->submitted) { \
- SDL_assert_release(!"Command buffer already submitted!"); \
- return; \
- }
- #define CHECK_COMMAND_BUFFER_RETURN_FALSE \
- if (((CommandBufferCommonHeader *)command_buffer)->submitted) { \
- SDL_assert_release(!"Command buffer already submitted!"); \
- return false; \
- }
- #define CHECK_COMMAND_BUFFER_RETURN_NULL \
- if (((CommandBufferCommonHeader *)command_buffer)->submitted) { \
- SDL_assert_release(!"Command buffer already submitted!"); \
- return NULL; \
- }
- #define CHECK_ANY_PASS_IN_PROGRESS(msg, retval) \
- if ( \
- ((CommandBufferCommonHeader *)command_buffer)->render_pass.in_progress || \
- ((CommandBufferCommonHeader *)command_buffer)->compute_pass.in_progress || \
- ((CommandBufferCommonHeader *)command_buffer)->copy_pass.in_progress) { \
- SDL_assert_release(!msg); \
- return retval; \
- }
- #define CHECK_RENDERPASS \
- if (!((Pass *)render_pass)->in_progress) { \
- SDL_assert_release(!"Render pass not in progress!"); \
- return; \
- }
- #define CHECK_GRAPHICS_PIPELINE_BOUND \
- if (!((CommandBufferCommonHeader *)RENDERPASS_COMMAND_BUFFER)->graphics_pipeline_bound) { \
- SDL_assert_release(!"Graphics pipeline not bound!"); \
- return; \
- }
- #define CHECK_COMPUTEPASS \
- if (!((Pass *)compute_pass)->in_progress) { \
- SDL_assert_release(!"Compute pass not in progress!"); \
- return; \
- }
- #define CHECK_COMPUTE_PIPELINE_BOUND \
- if (!((CommandBufferCommonHeader *)COMPUTEPASS_COMMAND_BUFFER)->compute_pipeline_bound) { \
- SDL_assert_release(!"Compute pipeline not bound!"); \
- return; \
- }
- #define CHECK_COPYPASS \
- if (!((Pass *)copy_pass)->in_progress) { \
- SDL_assert_release(!"Copy pass not in progress!"); \
- return; \
- }
- #define CHECK_TEXTUREFORMAT_ENUM_INVALID(enumval, retval) \
- if (enumval <= SDL_GPU_TEXTUREFORMAT_INVALID || enumval >= SDL_GPU_TEXTUREFORMAT_MAX_ENUM_VALUE) { \
- SDL_assert_release(!"Invalid texture format enum!"); \
- return retval; \
- }
- #define CHECK_VERTEXELEMENTFORMAT_ENUM_INVALID(enumval, retval) \
- if (enumval <= SDL_GPU_VERTEXELEMENTFORMAT_INVALID || enumval >= SDL_GPU_VERTEXELEMENTFORMAT_MAX_ENUM_VALUE) { \
- SDL_assert_release(!"Invalid vertex format enum!"); \
- return retval; \
- }
- #define CHECK_COMPAREOP_ENUM_INVALID(enumval, retval) \
- if (enumval <= SDL_GPU_COMPAREOP_INVALID || enumval >= SDL_GPU_COMPAREOP_MAX_ENUM_VALUE) { \
- SDL_assert_release(!"Invalid compare op enum!"); \
- return retval; \
- }
- #define CHECK_STENCILOP_ENUM_INVALID(enumval, retval) \
- if (enumval <= SDL_GPU_STENCILOP_INVALID || enumval >= SDL_GPU_STENCILOP_MAX_ENUM_VALUE) { \
- SDL_assert_release(!"Invalid stencil op enum!"); \
- return retval; \
- }
- #define CHECK_BLENDOP_ENUM_INVALID(enumval, retval) \
- if (enumval <= SDL_GPU_BLENDOP_INVALID || enumval >= SDL_GPU_BLENDOP_MAX_ENUM_VALUE) { \
- SDL_assert_release(!"Invalid blend op enum!"); \
- return retval; \
- }
- #define CHECK_BLENDFACTOR_ENUM_INVALID(enumval, retval) \
- if (enumval <= SDL_GPU_BLENDFACTOR_INVALID || enumval >= SDL_GPU_BLENDFACTOR_MAX_ENUM_VALUE) { \
- SDL_assert_release(!"Invalid blend factor enum!"); \
- return retval; \
- }
- #define CHECK_SWAPCHAINCOMPOSITION_ENUM_INVALID(enumval, retval) \
- if (enumval < 0 || enumval >= SDL_GPU_SWAPCHAINCOMPOSITION_MAX_ENUM_VALUE) { \
- SDL_assert_release(!"Invalid swapchain composition enum!"); \
- return retval; \
- }
- #define CHECK_PRESENTMODE_ENUM_INVALID(enumval, retval) \
- if (enumval < 0 || enumval >= SDL_GPU_PRESENTMODE_MAX_ENUM_VALUE) { \
- SDL_assert_release(!"Invalid present mode enum!"); \
- return retval; \
- }
- #define COMMAND_BUFFER_DEVICE \
- ((CommandBufferCommonHeader *)command_buffer)->device
- #define RENDERPASS_COMMAND_BUFFER \
- ((Pass *)render_pass)->command_buffer
- #define RENDERPASS_DEVICE \
- ((CommandBufferCommonHeader *)RENDERPASS_COMMAND_BUFFER)->device
- #define COMPUTEPASS_COMMAND_BUFFER \
- ((Pass *)compute_pass)->command_buffer
- #define COMPUTEPASS_DEVICE \
- ((CommandBufferCommonHeader *)COMPUTEPASS_COMMAND_BUFFER)->device
- #define COPYPASS_COMMAND_BUFFER \
- ((Pass *)copy_pass)->command_buffer
- #define COPYPASS_DEVICE \
- ((CommandBufferCommonHeader *)COPYPASS_COMMAND_BUFFER)->device
- // Drivers
- #ifndef SDL_GPU_DISABLED
- static const SDL_GPUBootstrap *backends[] = {
- #ifdef SDL_GPU_METAL
- &MetalDriver,
- #endif
- #ifdef SDL_GPU_VULKAN
- &VulkanDriver,
- #endif
- #ifdef SDL_GPU_D3D12
- &D3D12Driver,
- #endif
- #ifdef SDL_GPU_D3D11
- &D3D11Driver,
- #endif
- NULL
- };
- #endif // !SDL_GPU_DISABLED
- // Internal Utility Functions
- SDL_GPUGraphicsPipeline *SDL_GPU_FetchBlitPipeline(
- SDL_GPUDevice *device,
- SDL_GPUTextureType source_texture_type,
- SDL_GPUTextureFormat destination_format,
- SDL_GPUShader *blit_vertex_shader,
- SDL_GPUShader *blit_from_2d_shader,
- SDL_GPUShader *blit_from_2d_array_shader,
- SDL_GPUShader *blit_from_3d_shader,
- SDL_GPUShader *blit_from_cube_shader,
- SDL_GPUShader *blit_from_cube_array_shader,
- BlitPipelineCacheEntry **blit_pipelines,
- Uint32 *blit_pipeline_count,
- Uint32 *blit_pipeline_capacity)
- {
- SDL_GPUGraphicsPipelineCreateInfo blit_pipeline_create_info;
- SDL_GPUColorTargetDescription color_target_desc;
- SDL_GPUGraphicsPipeline *pipeline;
- if (blit_pipeline_count == NULL) {
- // use pre-created, format-agnostic pipelines
- return (*blit_pipelines)[source_texture_type].pipeline;
- }
- for (Uint32 i = 0; i < *blit_pipeline_count; i += 1) {
- if ((*blit_pipelines)[i].type == source_texture_type && (*blit_pipelines)[i].format == destination_format) {
- return (*blit_pipelines)[i].pipeline;
- }
- }
- // No pipeline found, we'll need to make one!
- SDL_zero(blit_pipeline_create_info);
- SDL_zero(color_target_desc);
- color_target_desc.blend_state.color_write_mask = 0xF;
- color_target_desc.format = destination_format;
- blit_pipeline_create_info.target_info.color_target_descriptions = &color_target_desc;
- blit_pipeline_create_info.target_info.num_color_targets = 1;
- blit_pipeline_create_info.target_info.depth_stencil_format = SDL_GPU_TEXTUREFORMAT_D16_UNORM; // arbitrary
- blit_pipeline_create_info.target_info.has_depth_stencil_target = false;
- blit_pipeline_create_info.vertex_shader = blit_vertex_shader;
- if (source_texture_type == SDL_GPU_TEXTURETYPE_CUBE) {
- blit_pipeline_create_info.fragment_shader = blit_from_cube_shader;
- } else if (source_texture_type == SDL_GPU_TEXTURETYPE_CUBE_ARRAY) {
- blit_pipeline_create_info.fragment_shader = blit_from_cube_array_shader;
- } else if (source_texture_type == SDL_GPU_TEXTURETYPE_2D_ARRAY) {
- blit_pipeline_create_info.fragment_shader = blit_from_2d_array_shader;
- } else if (source_texture_type == SDL_GPU_TEXTURETYPE_3D) {
- blit_pipeline_create_info.fragment_shader = blit_from_3d_shader;
- } else {
- blit_pipeline_create_info.fragment_shader = blit_from_2d_shader;
- }
- blit_pipeline_create_info.multisample_state.sample_count = SDL_GPU_SAMPLECOUNT_1;
- blit_pipeline_create_info.multisample_state.enable_mask = false;
- blit_pipeline_create_info.primitive_type = SDL_GPU_PRIMITIVETYPE_TRIANGLELIST;
- pipeline = SDL_CreateGPUGraphicsPipeline(
- device,
- &blit_pipeline_create_info);
- if (pipeline == NULL) {
- SDL_SetError("Failed to create GPU pipeline for blit");
- return NULL;
- }
- // Cache the new pipeline
- EXPAND_ARRAY_IF_NEEDED(
- (*blit_pipelines),
- BlitPipelineCacheEntry,
- *blit_pipeline_count + 1,
- *blit_pipeline_capacity,
- *blit_pipeline_capacity * 2)
- (*blit_pipelines)[*blit_pipeline_count].pipeline = pipeline;
- (*blit_pipelines)[*blit_pipeline_count].type = source_texture_type;
- (*blit_pipelines)[*blit_pipeline_count].format = destination_format;
- *blit_pipeline_count += 1;
- return pipeline;
- }
- void SDL_GPU_BlitCommon(
- SDL_GPUCommandBuffer *command_buffer,
- const SDL_GPUBlitInfo *info,
- SDL_GPUSampler *blit_linear_sampler,
- SDL_GPUSampler *blit_nearest_sampler,
- SDL_GPUShader *blit_vertex_shader,
- SDL_GPUShader *blit_from_2d_shader,
- SDL_GPUShader *blit_from_2d_array_shader,
- SDL_GPUShader *blit_from_3d_shader,
- SDL_GPUShader *blit_from_cube_shader,
- SDL_GPUShader *blit_from_cube_array_shader,
- BlitPipelineCacheEntry **blit_pipelines,
- Uint32 *blit_pipeline_count,
- Uint32 *blit_pipeline_capacity)
- {
- CommandBufferCommonHeader *cmdbufHeader = (CommandBufferCommonHeader *)command_buffer;
- SDL_GPURenderPass *render_pass;
- TextureCommonHeader *src_header = (TextureCommonHeader *)info->source.texture;
- TextureCommonHeader *dst_header = (TextureCommonHeader *)info->destination.texture;
- SDL_GPUGraphicsPipeline *blit_pipeline;
- SDL_GPUColorTargetInfo color_target_info;
- SDL_GPUViewport viewport;
- SDL_GPUTextureSamplerBinding texture_sampler_binding;
- BlitFragmentUniforms blit_fragment_uniforms;
- Uint32 layer_divisor;
- blit_pipeline = SDL_GPU_FetchBlitPipeline(
- cmdbufHeader->device,
- src_header->info.type,
- dst_header->info.format,
- blit_vertex_shader,
- blit_from_2d_shader,
- blit_from_2d_array_shader,
- blit_from_3d_shader,
- blit_from_cube_shader,
- blit_from_cube_array_shader,
- blit_pipelines,
- blit_pipeline_count,
- blit_pipeline_capacity);
- SDL_assert(blit_pipeline != NULL);
- color_target_info.load_op = info->load_op;
- color_target_info.clear_color = info->clear_color;
- color_target_info.store_op = SDL_GPU_STOREOP_STORE;
- color_target_info.texture = info->destination.texture;
- color_target_info.mip_level = info->destination.mip_level;
- color_target_info.layer_or_depth_plane = info->destination.layer_or_depth_plane;
- color_target_info.cycle = info->cycle;
- render_pass = SDL_BeginGPURenderPass(
- command_buffer,
- &color_target_info,
- 1,
- NULL);
- viewport.x = (float)info->destination.x;
- viewport.y = (float)info->destination.y;
- viewport.w = (float)info->destination.w;
- viewport.h = (float)info->destination.h;
- viewport.min_depth = 0;
- viewport.max_depth = 1;
- SDL_SetGPUViewport(
- render_pass,
- &viewport);
- SDL_BindGPUGraphicsPipeline(
- render_pass,
- blit_pipeline);
- texture_sampler_binding.texture = info->source.texture;
- texture_sampler_binding.sampler =
- info->filter == SDL_GPU_FILTER_NEAREST ? blit_nearest_sampler : blit_linear_sampler;
- SDL_BindGPUFragmentSamplers(
- render_pass,
- 0,
- &texture_sampler_binding,
- 1);
- blit_fragment_uniforms.left = (float)info->source.x / (src_header->info.width >> info->source.mip_level);
- blit_fragment_uniforms.top = (float)info->source.y / (src_header->info.height >> info->source.mip_level);
- blit_fragment_uniforms.width = (float)info->source.w / (src_header->info.width >> info->source.mip_level);
- blit_fragment_uniforms.height = (float)info->source.h / (src_header->info.height >> info->source.mip_level);
- blit_fragment_uniforms.mip_level = info->source.mip_level;
- layer_divisor = (src_header->info.type == SDL_GPU_TEXTURETYPE_3D) ? src_header->info.layer_count_or_depth : 1;
- blit_fragment_uniforms.layer_or_depth = (float)info->source.layer_or_depth_plane / layer_divisor;
- if (info->flip_mode & SDL_FLIP_HORIZONTAL) {
- blit_fragment_uniforms.left += blit_fragment_uniforms.width;
- blit_fragment_uniforms.width *= -1;
- }
- if (info->flip_mode & SDL_FLIP_VERTICAL) {
- blit_fragment_uniforms.top += blit_fragment_uniforms.height;
- blit_fragment_uniforms.height *= -1;
- }
- SDL_PushGPUFragmentUniformData(
- command_buffer,
- 0,
- &blit_fragment_uniforms,
- sizeof(blit_fragment_uniforms));
- SDL_DrawGPUPrimitives(render_pass, 3, 1, 0, 0);
- SDL_EndGPURenderPass(render_pass);
- }
- // Driver Functions
- #ifndef SDL_GPU_DISABLED
- static const SDL_GPUBootstrap * SDL_GPUSelectBackend(SDL_PropertiesID props)
- {
- Uint32 i;
- SDL_GPUShaderFormat format_flags = 0;
- const char *gpudriver;
- SDL_VideoDevice *_this = SDL_GetVideoDevice();
- if (_this == NULL) {
- SDL_SetError("Video subsystem not initialized");
- return NULL;
- }
- if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_PRIVATE_BOOL, false)) {
- format_flags |= SDL_GPU_SHADERFORMAT_PRIVATE;
- }
- if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_SPIRV_BOOL, false)) {
- format_flags |= SDL_GPU_SHADERFORMAT_SPIRV;
- }
- if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_DXBC_BOOL, false)) {
- format_flags |= SDL_GPU_SHADERFORMAT_DXBC;
- }
- if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_DXIL_BOOL, false)) {
- format_flags |= SDL_GPU_SHADERFORMAT_DXIL;
- }
- if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_MSL_BOOL, false)) {
- format_flags |= SDL_GPU_SHADERFORMAT_MSL;
- }
- if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_METALLIB_BOOL, false)) {
- format_flags |= SDL_GPU_SHADERFORMAT_METALLIB;
- }
- gpudriver = SDL_GetHint(SDL_HINT_GPU_DRIVER);
- if (gpudriver == NULL) {
- gpudriver = SDL_GetStringProperty(props, SDL_PROP_GPU_DEVICE_CREATE_NAME_STRING, NULL);
- }
- // Environment/Properties override...
- if (gpudriver != NULL) {
- for (i = 0; backends[i]; i += 1) {
- if (SDL_strcasecmp(gpudriver, backends[i]->name) == 0) {
- if (!(backends[i]->shader_formats & format_flags)) {
- SDL_SetError("Required shader format for backend %s not provided!", gpudriver);
- return NULL;
- }
- if (backends[i]->PrepareDriver(_this)) {
- return backends[i];
- }
- }
- }
- SDL_SetError("SDL_HINT_GPU_DRIVER %s unsupported!", gpudriver);
- return NULL;
- }
- for (i = 0; backends[i]; i += 1) {
- if ((backends[i]->shader_formats & format_flags) == 0) {
- // Don't select a backend which doesn't support the app's shaders.
- continue;
- }
- if (backends[i]->PrepareDriver(_this)) {
- return backends[i];
- }
- }
- SDL_SetError("No supported SDL_GPU backend found!");
- return NULL;
- }
- static void SDL_GPU_FillProperties(
- SDL_PropertiesID props,
- SDL_GPUShaderFormat format_flags,
- bool debug_mode,
- const char *name)
- {
- if (format_flags & SDL_GPU_SHADERFORMAT_PRIVATE) {
- SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_PRIVATE_BOOL, true);
- }
- if (format_flags & SDL_GPU_SHADERFORMAT_SPIRV) {
- SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_SPIRV_BOOL, true);
- }
- if (format_flags & SDL_GPU_SHADERFORMAT_DXBC) {
- SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_DXBC_BOOL, true);
- }
- if (format_flags & SDL_GPU_SHADERFORMAT_DXIL) {
- SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_DXIL_BOOL, true);
- }
- if (format_flags & SDL_GPU_SHADERFORMAT_MSL) {
- SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_MSL_BOOL, true);
- }
- if (format_flags & SDL_GPU_SHADERFORMAT_METALLIB) {
- SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_METALLIB_BOOL, true);
- }
- SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_DEBUGMODE_BOOL, debug_mode);
- SDL_SetStringProperty(props, SDL_PROP_GPU_DEVICE_CREATE_NAME_STRING, name);
- }
- #endif // SDL_GPU_DISABLED
- bool SDL_GPUSupportsShaderFormats(
- SDL_GPUShaderFormat format_flags,
- const char *name)
- {
- #ifndef SDL_GPU_DISABLED
- bool result;
- SDL_PropertiesID props = SDL_CreateProperties();
- SDL_GPU_FillProperties(props, format_flags, false, name);
- result = SDL_GPUSupportsProperties(props);
- SDL_DestroyProperties(props);
- return result;
- #else
- SDL_SetError("SDL not built with GPU support");
- return false;
- #endif
- }
- bool SDL_GPUSupportsProperties(SDL_PropertiesID props)
- {
- #ifndef SDL_GPU_DISABLED
- return (SDL_GPUSelectBackend(props) != NULL);
- #else
- SDL_SetError("SDL not built with GPU support");
- return false;
- #endif
- }
- SDL_GPUDevice *SDL_CreateGPUDevice(
- SDL_GPUShaderFormat format_flags,
- bool debug_mode,
- const char *name)
- {
- #ifndef SDL_GPU_DISABLED
- SDL_GPUDevice *result;
- SDL_PropertiesID props = SDL_CreateProperties();
- SDL_GPU_FillProperties(props, format_flags, debug_mode, name);
- result = SDL_CreateGPUDeviceWithProperties(props);
- SDL_DestroyProperties(props);
- return result;
- #else
- SDL_SetError("SDL not built with GPU support");
- return NULL;
- #endif // SDL_GPU_DISABLED
- }
- SDL_GPUDevice *SDL_CreateGPUDeviceWithProperties(SDL_PropertiesID props)
- {
- #ifndef SDL_GPU_DISABLED
- bool debug_mode;
- bool preferLowPower;
- SDL_GPUDevice *result = NULL;
- const SDL_GPUBootstrap *selectedBackend;
- selectedBackend = SDL_GPUSelectBackend(props);
- if (selectedBackend != NULL) {
- debug_mode = SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_DEBUGMODE_BOOL, true);
- preferLowPower = SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_PREFERLOWPOWER_BOOL, false);
- result = selectedBackend->CreateDevice(debug_mode, preferLowPower, props);
- if (result != NULL) {
- result->backend = selectedBackend->name;
- result->shader_formats = selectedBackend->shader_formats;
- result->debug_mode = debug_mode;
- }
- }
- return result;
- #else
- SDL_SetError("SDL not built with GPU support");
- return NULL;
- #endif // SDL_GPU_DISABLED
- }
- void SDL_DestroyGPUDevice(SDL_GPUDevice *device)
- {
- CHECK_DEVICE_MAGIC(device, );
- device->DestroyDevice(device);
- }
- int SDL_GetNumGPUDrivers(void)
- {
- #ifndef SDL_GPU_DISABLED
- return SDL_arraysize(backends) - 1;
- #else
- return 0;
- #endif
- }
- const char * SDL_GetGPUDriver(int index)
- {
- if (index < 0 || index >= SDL_GetNumGPUDrivers()) {
- SDL_InvalidParamError("index");
- return NULL;
- }
- #ifndef SDL_GPU_DISABLED
- return backends[index]->name;
- #else
- return NULL;
- #endif
- }
- const char * SDL_GetGPUDeviceDriver(SDL_GPUDevice *device)
- {
- CHECK_DEVICE_MAGIC(device, NULL);
- return device->backend;
- }
- SDL_GPUShaderFormat SDL_GetGPUShaderFormats(SDL_GPUDevice *device)
- {
- CHECK_DEVICE_MAGIC(device, SDL_GPU_SHADERFORMAT_INVALID);
- return device->shader_formats;
- }
- Uint32 SDL_GPUTextureFormatTexelBlockSize(
- SDL_GPUTextureFormat format)
- {
- switch (format) {
- case SDL_GPU_TEXTUREFORMAT_BC1_RGBA_UNORM:
- case SDL_GPU_TEXTUREFORMAT_BC1_RGBA_UNORM_SRGB:
- case SDL_GPU_TEXTUREFORMAT_BC4_R_UNORM:
- return 8;
- case SDL_GPU_TEXTUREFORMAT_BC2_RGBA_UNORM:
- case SDL_GPU_TEXTUREFORMAT_BC3_RGBA_UNORM:
- case SDL_GPU_TEXTUREFORMAT_BC5_RG_UNORM:
- case SDL_GPU_TEXTUREFORMAT_BC7_RGBA_UNORM:
- case SDL_GPU_TEXTUREFORMAT_BC6H_RGB_FLOAT:
- case SDL_GPU_TEXTUREFORMAT_BC6H_RGB_UFLOAT:
- case SDL_GPU_TEXTUREFORMAT_BC2_RGBA_UNORM_SRGB:
- case SDL_GPU_TEXTUREFORMAT_BC3_RGBA_UNORM_SRGB:
- case SDL_GPU_TEXTUREFORMAT_BC7_RGBA_UNORM_SRGB:
- return 16;
- case SDL_GPU_TEXTUREFORMAT_R8_UNORM:
- case SDL_GPU_TEXTUREFORMAT_R8_SNORM:
- case SDL_GPU_TEXTUREFORMAT_A8_UNORM:
- case SDL_GPU_TEXTUREFORMAT_R8_UINT:
- return 1;
- case SDL_GPU_TEXTUREFORMAT_B5G6R5_UNORM:
- case SDL_GPU_TEXTUREFORMAT_B4G4R4A4_UNORM:
- case SDL_GPU_TEXTUREFORMAT_B5G5R5A1_UNORM:
- case SDL_GPU_TEXTUREFORMAT_R16_FLOAT:
- case SDL_GPU_TEXTUREFORMAT_R8G8_SNORM:
- case SDL_GPU_TEXTUREFORMAT_R8G8_UNORM:
- case SDL_GPU_TEXTUREFORMAT_R8G8_UINT:
- case SDL_GPU_TEXTUREFORMAT_R16_UNORM:
- case SDL_GPU_TEXTUREFORMAT_R16_SNORM:
- case SDL_GPU_TEXTUREFORMAT_R16_UINT:
- return 2;
- case SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM:
- case SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM:
- case SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM_SRGB:
- case SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM_SRGB:
- case SDL_GPU_TEXTUREFORMAT_R32_FLOAT:
- case SDL_GPU_TEXTUREFORMAT_R16G16_FLOAT:
- case SDL_GPU_TEXTUREFORMAT_R11G11B10_UFLOAT:
- case SDL_GPU_TEXTUREFORMAT_R8G8B8A8_SNORM:
- case SDL_GPU_TEXTUREFORMAT_R10G10B10A2_UNORM:
- case SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UINT:
- case SDL_GPU_TEXTUREFORMAT_R16G16_UINT:
- case SDL_GPU_TEXTUREFORMAT_R16G16_UNORM:
- case SDL_GPU_TEXTUREFORMAT_R16G16_SNORM:
- return 4;
- case SDL_GPU_TEXTUREFORMAT_R16G16B16A16_FLOAT:
- case SDL_GPU_TEXTUREFORMAT_R16G16B16A16_UNORM:
- case SDL_GPU_TEXTUREFORMAT_R16G16B16A16_SNORM:
- case SDL_GPU_TEXTUREFORMAT_R32G32_FLOAT:
- case SDL_GPU_TEXTUREFORMAT_R16G16B16A16_UINT:
- return 8;
- case SDL_GPU_TEXTUREFORMAT_R32G32B32A32_FLOAT:
- return 16;
- case SDL_GPU_TEXTUREFORMAT_ASTC_4x4_UNORM:
- case SDL_GPU_TEXTUREFORMAT_ASTC_5x4_UNORM:
- case SDL_GPU_TEXTUREFORMAT_ASTC_5x5_UNORM:
- case SDL_GPU_TEXTUREFORMAT_ASTC_6x5_UNORM:
- case SDL_GPU_TEXTUREFORMAT_ASTC_6x6_UNORM:
- case SDL_GPU_TEXTUREFORMAT_ASTC_8x5_UNORM:
- case SDL_GPU_TEXTUREFORMAT_ASTC_8x6_UNORM:
- case SDL_GPU_TEXTUREFORMAT_ASTC_8x8_UNORM:
- case SDL_GPU_TEXTUREFORMAT_ASTC_10x5_UNORM:
- case SDL_GPU_TEXTUREFORMAT_ASTC_10x6_UNORM:
- case SDL_GPU_TEXTUREFORMAT_ASTC_10x8_UNORM:
- case SDL_GPU_TEXTUREFORMAT_ASTC_10x10_UNORM:
- case SDL_GPU_TEXTUREFORMAT_ASTC_12x10_UNORM:
- case SDL_GPU_TEXTUREFORMAT_ASTC_12x12_UNORM:
- case SDL_GPU_TEXTUREFORMAT_ASTC_4x4_UNORM_SRGB:
- case SDL_GPU_TEXTUREFORMAT_ASTC_5x4_UNORM_SRGB:
- case SDL_GPU_TEXTUREFORMAT_ASTC_5x5_UNORM_SRGB:
- case SDL_GPU_TEXTUREFORMAT_ASTC_6x5_UNORM_SRGB:
- case SDL_GPU_TEXTUREFORMAT_ASTC_6x6_UNORM_SRGB:
- case SDL_GPU_TEXTUREFORMAT_ASTC_8x5_UNORM_SRGB:
- case SDL_GPU_TEXTUREFORMAT_ASTC_8x6_UNORM_SRGB:
- case SDL_GPU_TEXTUREFORMAT_ASTC_8x8_UNORM_SRGB:
- case SDL_GPU_TEXTUREFORMAT_ASTC_10x5_UNORM_SRGB:
- case SDL_GPU_TEXTUREFORMAT_ASTC_10x6_UNORM_SRGB:
- case SDL_GPU_TEXTUREFORMAT_ASTC_10x8_UNORM_SRGB:
- case SDL_GPU_TEXTUREFORMAT_ASTC_10x10_UNORM_SRGB:
- case SDL_GPU_TEXTUREFORMAT_ASTC_12x10_UNORM_SRGB:
- case SDL_GPU_TEXTUREFORMAT_ASTC_12x12_UNORM_SRGB:
- case SDL_GPU_TEXTUREFORMAT_ASTC_4x4_FLOAT:
- case SDL_GPU_TEXTUREFORMAT_ASTC_5x4_FLOAT:
- case SDL_GPU_TEXTUREFORMAT_ASTC_5x5_FLOAT:
- case SDL_GPU_TEXTUREFORMAT_ASTC_6x5_FLOAT:
- case SDL_GPU_TEXTUREFORMAT_ASTC_6x6_FLOAT:
- case SDL_GPU_TEXTUREFORMAT_ASTC_8x5_FLOAT:
- case SDL_GPU_TEXTUREFORMAT_ASTC_8x6_FLOAT:
- case SDL_GPU_TEXTUREFORMAT_ASTC_8x8_FLOAT:
- case SDL_GPU_TEXTUREFORMAT_ASTC_10x5_FLOAT:
- case SDL_GPU_TEXTUREFORMAT_ASTC_10x6_FLOAT:
- case SDL_GPU_TEXTUREFORMAT_ASTC_10x8_FLOAT:
- case SDL_GPU_TEXTUREFORMAT_ASTC_10x10_FLOAT:
- case SDL_GPU_TEXTUREFORMAT_ASTC_12x10_FLOAT:
- case SDL_GPU_TEXTUREFORMAT_ASTC_12x12_FLOAT:
- return 16;
- default:
- SDL_assert_release(!"Unrecognized TextureFormat!");
- return 0;
- }
- }
- bool SDL_GPUTextureSupportsFormat(
- SDL_GPUDevice *device,
- SDL_GPUTextureFormat format,
- SDL_GPUTextureType type,
- SDL_GPUTextureUsageFlags usage)
- {
- CHECK_DEVICE_MAGIC(device, false);
- if (device->debug_mode) {
- CHECK_TEXTUREFORMAT_ENUM_INVALID(format, false)
- }
- return device->SupportsTextureFormat(
- device->driverData,
- format,
- type,
- usage);
- }
- bool SDL_GPUTextureSupportsSampleCount(
- SDL_GPUDevice *device,
- SDL_GPUTextureFormat format,
- SDL_GPUSampleCount sample_count)
- {
- CHECK_DEVICE_MAGIC(device, 0);
- if (device->debug_mode) {
- CHECK_TEXTUREFORMAT_ENUM_INVALID(format, 0)
- }
- return device->SupportsSampleCount(
- device->driverData,
- format,
- sample_count);
- }
- // State Creation
- SDL_GPUComputePipeline *SDL_CreateGPUComputePipeline(
- SDL_GPUDevice *device,
- const SDL_GPUComputePipelineCreateInfo *createinfo)
- {
- CHECK_DEVICE_MAGIC(device, NULL);
- if (createinfo == NULL) {
- SDL_InvalidParamError("createinfo");
- return NULL;
- }
- if (device->debug_mode) {
- if (createinfo->format == SDL_GPU_SHADERFORMAT_INVALID) {
- SDL_assert_release(!"Shader format cannot be INVALID!");
- return NULL;
- }
- if (!(createinfo->format & device->shader_formats)) {
- SDL_assert_release(!"Incompatible shader format for GPU backend");
- return NULL;
- }
- if (createinfo->num_readwrite_storage_textures > MAX_COMPUTE_WRITE_TEXTURES) {
- SDL_assert_release(!"Compute pipeline write-only texture count cannot be higher than 8!");
- return NULL;
- }
- if (createinfo->num_readwrite_storage_buffers > MAX_COMPUTE_WRITE_BUFFERS) {
- SDL_assert_release(!"Compute pipeline write-only buffer count cannot be higher than 8!");
- return NULL;
- }
- if (createinfo->threadcount_x == 0 ||
- createinfo->threadcount_y == 0 ||
- createinfo->threadcount_z == 0) {
- SDL_assert_release(!"Compute pipeline threadCount dimensions must be at least 1!");
- return NULL;
- }
- }
- return device->CreateComputePipeline(
- device->driverData,
- createinfo);
- }
- SDL_GPUGraphicsPipeline *SDL_CreateGPUGraphicsPipeline(
- SDL_GPUDevice *device,
- const SDL_GPUGraphicsPipelineCreateInfo *graphicsPipelineCreateInfo)
- {
- CHECK_DEVICE_MAGIC(device, NULL);
- if (graphicsPipelineCreateInfo == NULL) {
- SDL_InvalidParamError("graphicsPipelineCreateInfo");
- return NULL;
- }
- if (device->debug_mode) {
- if (graphicsPipelineCreateInfo->target_info.num_color_targets > 0 && graphicsPipelineCreateInfo->target_info.color_target_descriptions == NULL) {
- SDL_assert_release(!"Color target descriptions array pointer cannot be NULL if num_color_targets is greater than zero!");
- return NULL;
- }
- for (Uint32 i = 0; i < graphicsPipelineCreateInfo->target_info.num_color_targets; i += 1) {
- CHECK_TEXTUREFORMAT_ENUM_INVALID(graphicsPipelineCreateInfo->target_info.color_target_descriptions[i].format, NULL);
- if (IsDepthFormat(graphicsPipelineCreateInfo->target_info.color_target_descriptions[i].format)) {
- SDL_assert_release(!"Color target formats cannot be a depth format!");
- return NULL;
- }
- if (graphicsPipelineCreateInfo->target_info.color_target_descriptions[i].blend_state.enable_blend) {
- const SDL_GPUColorTargetBlendState *blend_state = &graphicsPipelineCreateInfo->target_info.color_target_descriptions[i].blend_state;
- CHECK_BLENDFACTOR_ENUM_INVALID(blend_state->src_color_blendfactor, NULL)
- CHECK_BLENDFACTOR_ENUM_INVALID(blend_state->dst_color_blendfactor, NULL)
- CHECK_BLENDOP_ENUM_INVALID(blend_state->color_blend_op, NULL)
- CHECK_BLENDFACTOR_ENUM_INVALID(blend_state->src_alpha_blendfactor, NULL)
- CHECK_BLENDFACTOR_ENUM_INVALID(blend_state->dst_alpha_blendfactor, NULL)
- CHECK_BLENDOP_ENUM_INVALID(blend_state->alpha_blend_op, NULL)
- }
- }
- if (graphicsPipelineCreateInfo->target_info.has_depth_stencil_target) {
- CHECK_TEXTUREFORMAT_ENUM_INVALID(graphicsPipelineCreateInfo->target_info.depth_stencil_format, NULL);
- if (!IsDepthFormat(graphicsPipelineCreateInfo->target_info.depth_stencil_format)) {
- SDL_assert_release(!"Depth-stencil target format must be a depth format!");
- return NULL;
- }
- }
- if (graphicsPipelineCreateInfo->vertex_input_state.num_vertex_buffers > 0 && graphicsPipelineCreateInfo->vertex_input_state.vertex_buffer_descriptions == NULL) {
- SDL_assert_release(!"Vertex buffer descriptions array pointer cannot be NULL!");
- return NULL;
- }
- if (graphicsPipelineCreateInfo->vertex_input_state.num_vertex_buffers > MAX_VERTEX_BUFFERS) {
- SDL_assert_release(!"The number of vertex buffer descriptions in a vertex input state must not exceed 16!");
- return NULL;
- }
- if (graphicsPipelineCreateInfo->vertex_input_state.num_vertex_attributes > 0 && graphicsPipelineCreateInfo->vertex_input_state.vertex_attributes == NULL) {
- SDL_assert_release(!"Vertex attributes array pointer cannot be NULL!");
- return NULL;
- }
- if (graphicsPipelineCreateInfo->vertex_input_state.num_vertex_attributes > MAX_VERTEX_ATTRIBUTES) {
- SDL_assert_release(!"The number of vertex attributes in a vertex input state must not exceed 16!");
- return NULL;
- }
- Uint32 locations[MAX_VERTEX_ATTRIBUTES];
- for (Uint32 i = 0; i < graphicsPipelineCreateInfo->vertex_input_state.num_vertex_attributes; i += 1) {
- CHECK_VERTEXELEMENTFORMAT_ENUM_INVALID(graphicsPipelineCreateInfo->vertex_input_state.vertex_attributes[i].format, NULL);
- locations[i] = graphicsPipelineCreateInfo->vertex_input_state.vertex_attributes[i].location;
- for (Uint32 j = 0; j < i; j += 1) {
- if (locations[j] == locations[i]) {
- SDL_assert_release(!"Each vertex attribute location in a vertex input state must be unique!");
- }
- }
- }
- if (graphicsPipelineCreateInfo->depth_stencil_state.enable_depth_test) {
- CHECK_COMPAREOP_ENUM_INVALID(graphicsPipelineCreateInfo->depth_stencil_state.compare_op, NULL)
- }
- if (graphicsPipelineCreateInfo->depth_stencil_state.enable_stencil_test) {
- const SDL_GPUStencilOpState *stencil_state = &graphicsPipelineCreateInfo->depth_stencil_state.back_stencil_state;
- CHECK_COMPAREOP_ENUM_INVALID(stencil_state->compare_op, NULL)
- CHECK_STENCILOP_ENUM_INVALID(stencil_state->fail_op, NULL)
- CHECK_STENCILOP_ENUM_INVALID(stencil_state->pass_op, NULL)
- CHECK_STENCILOP_ENUM_INVALID(stencil_state->depth_fail_op, NULL)
- }
- }
- return device->CreateGraphicsPipeline(
- device->driverData,
- graphicsPipelineCreateInfo);
- }
- SDL_GPUSampler *SDL_CreateGPUSampler(
- SDL_GPUDevice *device,
- const SDL_GPUSamplerCreateInfo *createinfo)
- {
- CHECK_DEVICE_MAGIC(device, NULL);
- if (createinfo == NULL) {
- SDL_InvalidParamError("createinfo");
- return NULL;
- }
- return device->CreateSampler(
- device->driverData,
- createinfo);
- }
- SDL_GPUShader *SDL_CreateGPUShader(
- SDL_GPUDevice *device,
- const SDL_GPUShaderCreateInfo *createinfo)
- {
- CHECK_DEVICE_MAGIC(device, NULL);
- if (createinfo == NULL) {
- SDL_InvalidParamError("createinfo");
- return NULL;
- }
- if (device->debug_mode) {
- if (createinfo->format == SDL_GPU_SHADERFORMAT_INVALID) {
- SDL_assert_release(!"Shader format cannot be INVALID!");
- return NULL;
- }
- if (!(createinfo->format & device->shader_formats)) {
- SDL_assert_release(!"Incompatible shader format for GPU backend");
- return NULL;
- }
- }
- return device->CreateShader(
- device->driverData,
- createinfo);
- }
- SDL_GPUTexture *SDL_CreateGPUTexture(
- SDL_GPUDevice *device,
- const SDL_GPUTextureCreateInfo *createinfo)
- {
- CHECK_DEVICE_MAGIC(device, NULL);
- if (createinfo == NULL) {
- SDL_InvalidParamError("createinfo");
- return NULL;
- }
- if (device->debug_mode) {
- bool failed = false;
- const Uint32 MAX_2D_DIMENSION = 16384;
- const Uint32 MAX_3D_DIMENSION = 2048;
- // Common checks for all texture types
- CHECK_TEXTUREFORMAT_ENUM_INVALID(createinfo->format, NULL)
- if (createinfo->width <= 0 || createinfo->height <= 0 || createinfo->layer_count_or_depth <= 0) {
- SDL_assert_release(!"For any texture: width, height, and layer_count_or_depth must be >= 1");
- failed = true;
- }
- if (createinfo->num_levels <= 0) {
- SDL_assert_release(!"For any texture: num_levels must be >= 1");
- failed = true;
- }
- if ((createinfo->usage & SDL_GPU_TEXTUREUSAGE_GRAPHICS_STORAGE_READ) && (createinfo->usage & SDL_GPU_TEXTUREUSAGE_SAMPLER)) {
- SDL_assert_release(!"For any texture: usage cannot contain both GRAPHICS_STORAGE_READ and SAMPLER");
- failed = true;
- }
- if (createinfo->sample_count > SDL_GPU_SAMPLECOUNT_1 &&
- (createinfo->usage & (SDL_GPU_TEXTUREUSAGE_SAMPLER |
- SDL_GPU_TEXTUREUSAGE_GRAPHICS_STORAGE_READ |
- SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_READ |
- SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_WRITE))) {
- SDL_assert_release(!"For multisample textures: usage cannot contain SAMPLER or STORAGE flags");
- failed = true;
- }
- if (IsDepthFormat(createinfo->format) && (createinfo->usage & ~(SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET | SDL_GPU_TEXTUREUSAGE_SAMPLER))) {
- SDL_assert_release(!"For depth textures: usage cannot contain any flags except for DEPTH_STENCIL_TARGET and SAMPLER");
- failed = true;
- }
- if (IsIntegerFormat(createinfo->format) && (createinfo->usage & SDL_GPU_TEXTUREUSAGE_SAMPLER)) {
- SDL_assert_release(!"For any texture: usage cannot contain SAMPLER for textures with an integer format");
- failed = true;
- }
- if (createinfo->type == SDL_GPU_TEXTURETYPE_CUBE) {
- // Cubemap validation
- if (createinfo->width != createinfo->height) {
- SDL_assert_release(!"For cube textures: width and height must be identical");
- failed = true;
- }
- if (createinfo->width > MAX_2D_DIMENSION || createinfo->height > MAX_2D_DIMENSION) {
- SDL_assert_release(!"For cube textures: width and height must be <= 16384");
- failed = true;
- }
- if (createinfo->layer_count_or_depth != 6) {
- SDL_assert_release(!"For cube textures: layer_count_or_depth must be 6");
- failed = true;
- }
- if (createinfo->sample_count > SDL_GPU_SAMPLECOUNT_1) {
- SDL_assert_release(!"For cube textures: sample_count must be SDL_GPU_SAMPLECOUNT_1");
- failed = true;
- }
- if (!SDL_GPUTextureSupportsFormat(device, createinfo->format, SDL_GPU_TEXTURETYPE_CUBE, createinfo->usage)) {
- SDL_assert_release(!"For cube textures: the format is unsupported for the given usage");
- failed = true;
- }
- } else if (createinfo->type == SDL_GPU_TEXTURETYPE_CUBE_ARRAY) {
- // Cubemap array validation
- if (createinfo->width != createinfo->height) {
- SDL_assert_release(!"For cube array textures: width and height must be identical");
- failed = true;
- }
- if (createinfo->width > MAX_2D_DIMENSION || createinfo->height > MAX_2D_DIMENSION) {
- SDL_assert_release(!"For cube array textures: width and height must be <= 16384");
- failed = true;
- }
- if (createinfo->layer_count_or_depth % 6 != 0) {
- SDL_assert_release(!"For cube array textures: layer_count_or_depth must be a multiple of 6");
- failed = true;
- }
- if (createinfo->sample_count > SDL_GPU_SAMPLECOUNT_1) {
- SDL_assert_release(!"For cube array textures: sample_count must be SDL_GPU_SAMPLECOUNT_1");
- failed = true;
- }
- if (!SDL_GPUTextureSupportsFormat(device, createinfo->format, SDL_GPU_TEXTURETYPE_CUBE_ARRAY, createinfo->usage)) {
- SDL_assert_release(!"For cube array textures: the format is unsupported for the given usage");
- failed = true;
- }
- } else if (createinfo->type == SDL_GPU_TEXTURETYPE_3D) {
- // 3D Texture Validation
- if (createinfo->width > MAX_3D_DIMENSION || createinfo->height > MAX_3D_DIMENSION || createinfo->layer_count_or_depth > MAX_3D_DIMENSION) {
- SDL_assert_release(!"For 3D textures: width, height, and layer_count_or_depth must be <= 2048");
- failed = true;
- }
- if (createinfo->usage & SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET) {
- SDL_assert_release(!"For 3D textures: usage must not contain DEPTH_STENCIL_TARGET");
- failed = true;
- }
- if (createinfo->sample_count > SDL_GPU_SAMPLECOUNT_1) {
- SDL_assert_release(!"For 3D textures: sample_count must be SDL_GPU_SAMPLECOUNT_1");
- failed = true;
- }
- if (!SDL_GPUTextureSupportsFormat(device, createinfo->format, SDL_GPU_TEXTURETYPE_3D, createinfo->usage)) {
- SDL_assert_release(!"For 3D textures: the format is unsupported for the given usage");
- failed = true;
- }
- } else {
- if (createinfo->type == SDL_GPU_TEXTURETYPE_2D_ARRAY) {
- // Array Texture Validation
- if (createinfo->usage & SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET) {
- SDL_assert_release(!"For array textures: usage must not contain DEPTH_STENCIL_TARGET");
- failed = true;
- }
- if (createinfo->sample_count > SDL_GPU_SAMPLECOUNT_1) {
- SDL_assert_release(!"For array textures: sample_count must be SDL_GPU_SAMPLECOUNT_1");
- failed = true;
- }
- }
- if (createinfo->sample_count > SDL_GPU_SAMPLECOUNT_1 && createinfo->num_levels > 1) {
- SDL_assert_release(!"For 2D multisample textures: num_levels must be 1");
- failed = true;
- }
- if (!SDL_GPUTextureSupportsFormat(device, createinfo->format, SDL_GPU_TEXTURETYPE_2D, createinfo->usage)) {
- SDL_assert_release(!"For 2D textures: the format is unsupported for the given usage");
- failed = true;
- }
- }
- if (failed) {
- return NULL;
- }
- }
- return device->CreateTexture(
- device->driverData,
- createinfo);
- }
- SDL_GPUBuffer *SDL_CreateGPUBuffer(
- SDL_GPUDevice *device,
- const SDL_GPUBufferCreateInfo *createinfo)
- {
- CHECK_DEVICE_MAGIC(device, NULL);
- if (createinfo == NULL) {
- SDL_InvalidParamError("createinfo");
- return NULL;
- }
- return device->CreateBuffer(
- device->driverData,
- createinfo->usage,
- createinfo->size);
- }
- SDL_GPUTransferBuffer *SDL_CreateGPUTransferBuffer(
- SDL_GPUDevice *device,
- const SDL_GPUTransferBufferCreateInfo *createinfo)
- {
- CHECK_DEVICE_MAGIC(device, NULL);
- if (createinfo == NULL) {
- SDL_InvalidParamError("createinfo");
- return NULL;
- }
- return device->CreateTransferBuffer(
- device->driverData,
- createinfo->usage,
- createinfo->size);
- }
- // Debug Naming
- void SDL_SetGPUBufferName(
- SDL_GPUDevice *device,
- SDL_GPUBuffer *buffer,
- const char *text)
- {
- CHECK_DEVICE_MAGIC(device, );
- if (buffer == NULL) {
- SDL_InvalidParamError("buffer");
- return;
- }
- if (text == NULL) {
- SDL_InvalidParamError("text");
- }
- device->SetBufferName(
- device->driverData,
- buffer,
- text);
- }
- void SDL_SetGPUTextureName(
- SDL_GPUDevice *device,
- SDL_GPUTexture *texture,
- const char *text)
- {
- CHECK_DEVICE_MAGIC(device, );
- if (texture == NULL) {
- SDL_InvalidParamError("texture");
- return;
- }
- if (text == NULL) {
- SDL_InvalidParamError("text");
- }
- device->SetTextureName(
- device->driverData,
- texture,
- text);
- }
- void SDL_InsertGPUDebugLabel(
- SDL_GPUCommandBuffer *command_buffer,
- const char *text)
- {
- if (command_buffer == NULL) {
- SDL_InvalidParamError("command_buffer");
- return;
- }
- if (text == NULL) {
- SDL_InvalidParamError("text");
- return;
- }
- if (COMMAND_BUFFER_DEVICE->debug_mode) {
- CHECK_COMMAND_BUFFER
- }
- COMMAND_BUFFER_DEVICE->InsertDebugLabel(
- command_buffer,
- text);
- }
- void SDL_PushGPUDebugGroup(
- SDL_GPUCommandBuffer *command_buffer,
- const char *name)
- {
- if (command_buffer == NULL) {
- SDL_InvalidParamError("command_buffer");
- return;
- }
- if (name == NULL) {
- SDL_InvalidParamError("name");
- return;
- }
- if (COMMAND_BUFFER_DEVICE->debug_mode) {
- CHECK_COMMAND_BUFFER
- }
- COMMAND_BUFFER_DEVICE->PushDebugGroup(
- command_buffer,
- name);
- }
- void SDL_PopGPUDebugGroup(
- SDL_GPUCommandBuffer *command_buffer)
- {
- if (command_buffer == NULL) {
- SDL_InvalidParamError("command_buffer");
- return;
- }
- if (COMMAND_BUFFER_DEVICE->debug_mode) {
- CHECK_COMMAND_BUFFER
- }
- COMMAND_BUFFER_DEVICE->PopDebugGroup(
- command_buffer);
- }
- // Disposal
- void SDL_ReleaseGPUTexture(
- SDL_GPUDevice *device,
- SDL_GPUTexture *texture)
- {
- CHECK_DEVICE_MAGIC(device, );
- if (texture == NULL) {
- return;
- }
- device->ReleaseTexture(
- device->driverData,
- texture);
- }
- void SDL_ReleaseGPUSampler(
- SDL_GPUDevice *device,
- SDL_GPUSampler *sampler)
- {
- CHECK_DEVICE_MAGIC(device, );
- if (sampler == NULL) {
- return;
- }
- device->ReleaseSampler(
- device->driverData,
- sampler);
- }
- void SDL_ReleaseGPUBuffer(
- SDL_GPUDevice *device,
- SDL_GPUBuffer *buffer)
- {
- CHECK_DEVICE_MAGIC(device, );
- if (buffer == NULL) {
- return;
- }
- device->ReleaseBuffer(
- device->driverData,
- buffer);
- }
- void SDL_ReleaseGPUTransferBuffer(
- SDL_GPUDevice *device,
- SDL_GPUTransferBuffer *transfer_buffer)
- {
- CHECK_DEVICE_MAGIC(device, );
- if (transfer_buffer == NULL) {
- return;
- }
- device->ReleaseTransferBuffer(
- device->driverData,
- transfer_buffer);
- }
- void SDL_ReleaseGPUShader(
- SDL_GPUDevice *device,
- SDL_GPUShader *shader)
- {
- CHECK_DEVICE_MAGIC(device, );
- if (shader == NULL) {
- return;
- }
- device->ReleaseShader(
- device->driverData,
- shader);
- }
- void SDL_ReleaseGPUComputePipeline(
- SDL_GPUDevice *device,
- SDL_GPUComputePipeline *compute_pipeline)
- {
- CHECK_DEVICE_MAGIC(device, );
- if (compute_pipeline == NULL) {
- return;
- }
- device->ReleaseComputePipeline(
- device->driverData,
- compute_pipeline);
- }
- void SDL_ReleaseGPUGraphicsPipeline(
- SDL_GPUDevice *device,
- SDL_GPUGraphicsPipeline *graphics_pipeline)
- {
- CHECK_DEVICE_MAGIC(device, );
- if (graphics_pipeline == NULL) {
- return;
- }
- device->ReleaseGraphicsPipeline(
- device->driverData,
- graphics_pipeline);
- }
- // Command Buffer
- SDL_GPUCommandBuffer *SDL_AcquireGPUCommandBuffer(
- SDL_GPUDevice *device)
- {
- SDL_GPUCommandBuffer *command_buffer;
- CommandBufferCommonHeader *commandBufferHeader;
- CHECK_DEVICE_MAGIC(device, NULL);
- command_buffer = device->AcquireCommandBuffer(
- device->driverData);
- if (command_buffer == NULL) {
- return NULL;
- }
- commandBufferHeader = (CommandBufferCommonHeader *)command_buffer;
- commandBufferHeader->device = device;
- commandBufferHeader->render_pass.command_buffer = command_buffer;
- commandBufferHeader->render_pass.in_progress = false;
- commandBufferHeader->graphics_pipeline_bound = false;
- commandBufferHeader->compute_pass.command_buffer = command_buffer;
- commandBufferHeader->compute_pass.in_progress = false;
- commandBufferHeader->compute_pipeline_bound = false;
- commandBufferHeader->copy_pass.command_buffer = command_buffer;
- commandBufferHeader->copy_pass.in_progress = false;
- commandBufferHeader->submitted = false;
- return command_buffer;
- }
- // Uniforms
- void SDL_PushGPUVertexUniformData(
- SDL_GPUCommandBuffer *command_buffer,
- Uint32 slot_index,
- const void *data,
- Uint32 length)
- {
- if (command_buffer == NULL) {
- SDL_InvalidParamError("command_buffer");
- return;
- }
- if (data == NULL) {
- SDL_InvalidParamError("data");
- return;
- }
- if (COMMAND_BUFFER_DEVICE->debug_mode) {
- CHECK_COMMAND_BUFFER
- }
- COMMAND_BUFFER_DEVICE->PushVertexUniformData(
- command_buffer,
- slot_index,
- data,
- length);
- }
- void SDL_PushGPUFragmentUniformData(
- SDL_GPUCommandBuffer *command_buffer,
- Uint32 slot_index,
- const void *data,
- Uint32 length)
- {
- if (command_buffer == NULL) {
- SDL_InvalidParamError("command_buffer");
- return;
- }
- if (data == NULL) {
- SDL_InvalidParamError("data");
- return;
- }
- if (COMMAND_BUFFER_DEVICE->debug_mode) {
- CHECK_COMMAND_BUFFER
- }
- COMMAND_BUFFER_DEVICE->PushFragmentUniformData(
- command_buffer,
- slot_index,
- data,
- length);
- }
- void SDL_PushGPUComputeUniformData(
- SDL_GPUCommandBuffer *command_buffer,
- Uint32 slot_index,
- const void *data,
- Uint32 length)
- {
- if (command_buffer == NULL) {
- SDL_InvalidParamError("command_buffer");
- return;
- }
- if (data == NULL) {
- SDL_InvalidParamError("data");
- return;
- }
- if (COMMAND_BUFFER_DEVICE->debug_mode) {
- CHECK_COMMAND_BUFFER
- }
- COMMAND_BUFFER_DEVICE->PushComputeUniformData(
- command_buffer,
- slot_index,
- data,
- length);
- }
- // Render Pass
- SDL_GPURenderPass *SDL_BeginGPURenderPass(
- SDL_GPUCommandBuffer *command_buffer,
- const SDL_GPUColorTargetInfo *color_target_infos,
- Uint32 num_color_targets,
- const SDL_GPUDepthStencilTargetInfo *depth_stencil_target_info)
- {
- CommandBufferCommonHeader *commandBufferHeader;
- if (command_buffer == NULL) {
- SDL_InvalidParamError("command_buffer");
- return NULL;
- }
- if (color_target_infos == NULL && num_color_targets > 0) {
- SDL_InvalidParamError("color_target_infos");
- return NULL;
- }
- if (num_color_targets > MAX_COLOR_TARGET_BINDINGS) {
- SDL_SetError("num_color_targets exceeds MAX_COLOR_TARGET_BINDINGS");
- return NULL;
- }
- if (COMMAND_BUFFER_DEVICE->debug_mode) {
- CHECK_COMMAND_BUFFER_RETURN_NULL
- CHECK_ANY_PASS_IN_PROGRESS("Cannot begin render pass during another pass!", NULL)
- for (Uint32 i = 0; i < num_color_targets; i += 1) {
- TextureCommonHeader *textureHeader = (TextureCommonHeader *)color_target_infos[i].texture;
- if (color_target_infos[i].cycle && color_target_infos[i].load_op == SDL_GPU_LOADOP_LOAD) {
- SDL_assert_release(!"Cannot cycle color target when load op is LOAD!");
- }
- if (color_target_infos[i].store_op == SDL_GPU_STOREOP_RESOLVE || color_target_infos[i].store_op == SDL_GPU_STOREOP_RESOLVE_AND_STORE) {
- if (color_target_infos[i].resolve_texture == NULL) {
- SDL_assert_release(!"Store op is RESOLVE or RESOLVE_AND_STORE but resolve_texture is NULL!");
- } else {
- TextureCommonHeader *resolveTextureHeader = (TextureCommonHeader *)color_target_infos[i].resolve_texture;
- if (textureHeader->info.sample_count == SDL_GPU_SAMPLECOUNT_1) {
- SDL_assert_release(!"Store op is RESOLVE or RESOLVE_AND_STORE but texture is not multisample!");
- }
- if (resolveTextureHeader->info.sample_count != SDL_GPU_SAMPLECOUNT_1) {
- SDL_assert_release(!"Resolve texture must have a sample count of 1!");
- }
- if (resolveTextureHeader->info.format != textureHeader->info.format) {
- SDL_assert_release(!"Resolve texture must have the same format as its corresponding color target!");
- }
- if (resolveTextureHeader->info.type == SDL_GPU_TEXTURETYPE_3D) {
- SDL_assert_release(!"Resolve texture must not be of TEXTURETYPE_3D!");
- }
- if (!(resolveTextureHeader->info.usage & SDL_GPU_TEXTUREUSAGE_COLOR_TARGET)) {
- SDL_assert_release(!"Resolve texture usage must include COLOR_TARGET!");
- }
- }
- }
- }
- if (depth_stencil_target_info != NULL) {
- TextureCommonHeader *textureHeader = (TextureCommonHeader *)depth_stencil_target_info->texture;
- if (!(textureHeader->info.usage & SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET)) {
- SDL_assert_release(!"Depth target must have been created with the DEPTH_STENCIL_TARGET usage flag!");
- }
- if (depth_stencil_target_info->cycle && (depth_stencil_target_info->load_op == SDL_GPU_LOADOP_LOAD || depth_stencil_target_info->stencil_load_op == SDL_GPU_LOADOP_LOAD)) {
- SDL_assert_release(!"Cannot cycle depth target when load op or stencil load op is LOAD!");
- }
- if (depth_stencil_target_info->store_op == SDL_GPU_STOREOP_RESOLVE ||
- depth_stencil_target_info->stencil_store_op == SDL_GPU_STOREOP_RESOLVE ||
- depth_stencil_target_info->store_op == SDL_GPU_STOREOP_RESOLVE_AND_STORE ||
- depth_stencil_target_info->stencil_store_op == SDL_GPU_STOREOP_RESOLVE_AND_STORE) {
- SDL_assert_release(!"RESOLVE store ops are not supported for depth-stencil targets!");
- }
- }
- }
- COMMAND_BUFFER_DEVICE->BeginRenderPass(
- command_buffer,
- color_target_infos,
- num_color_targets,
- depth_stencil_target_info);
- commandBufferHeader = (CommandBufferCommonHeader *)command_buffer;
- commandBufferHeader->render_pass.in_progress = true;
- return (SDL_GPURenderPass *)&(commandBufferHeader->render_pass);
- }
- void SDL_BindGPUGraphicsPipeline(
- SDL_GPURenderPass *render_pass,
- SDL_GPUGraphicsPipeline *graphics_pipeline)
- {
- CommandBufferCommonHeader *commandBufferHeader;
- if (render_pass == NULL) {
- SDL_InvalidParamError("render_pass");
- return;
- }
- if (graphics_pipeline == NULL) {
- SDL_InvalidParamError("graphics_pipeline");
- return;
- }
- RENDERPASS_DEVICE->BindGraphicsPipeline(
- RENDERPASS_COMMAND_BUFFER,
- graphics_pipeline);
- commandBufferHeader = (CommandBufferCommonHeader *)RENDERPASS_COMMAND_BUFFER;
- commandBufferHeader->graphics_pipeline_bound = true;
- }
- void SDL_SetGPUViewport(
- SDL_GPURenderPass *render_pass,
- const SDL_GPUViewport *viewport)
- {
- if (render_pass == NULL) {
- SDL_InvalidParamError("render_pass");
- return;
- }
- if (viewport == NULL) {
- SDL_InvalidParamError("viewport");
- return;
- }
- if (RENDERPASS_DEVICE->debug_mode) {
- CHECK_RENDERPASS
- }
- RENDERPASS_DEVICE->SetViewport(
- RENDERPASS_COMMAND_BUFFER,
- viewport);
- }
- void SDL_SetGPUScissor(
- SDL_GPURenderPass *render_pass,
- const SDL_Rect *scissor)
- {
- if (render_pass == NULL) {
- SDL_InvalidParamError("render_pass");
- return;
- }
- if (scissor == NULL) {
- SDL_InvalidParamError("scissor");
- return;
- }
- if (RENDERPASS_DEVICE->debug_mode) {
- CHECK_RENDERPASS
- }
- RENDERPASS_DEVICE->SetScissor(
- RENDERPASS_COMMAND_BUFFER,
- scissor);
- }
- void SDL_SetGPUBlendConstants(
- SDL_GPURenderPass *render_pass,
- SDL_FColor blend_constants)
- {
- if (render_pass == NULL) {
- SDL_InvalidParamError("render_pass");
- return;
- }
- if (RENDERPASS_DEVICE->debug_mode) {
- CHECK_RENDERPASS
- }
- RENDERPASS_DEVICE->SetBlendConstants(
- RENDERPASS_COMMAND_BUFFER,
- blend_constants);
- }
- void SDL_SetGPUStencilReference(
- SDL_GPURenderPass *render_pass,
- Uint8 reference)
- {
- if (render_pass == NULL) {
- SDL_InvalidParamError("render_pass");
- return;
- }
- if (RENDERPASS_DEVICE->debug_mode) {
- CHECK_RENDERPASS
- }
- RENDERPASS_DEVICE->SetStencilReference(
- RENDERPASS_COMMAND_BUFFER,
- reference);
- }
- void SDL_BindGPUVertexBuffers(
- SDL_GPURenderPass *render_pass,
- Uint32 first_binding,
- const SDL_GPUBufferBinding *bindings,
- Uint32 num_bindings)
- {
- if (render_pass == NULL) {
- SDL_InvalidParamError("render_pass");
- return;
- }
- if (bindings == NULL && num_bindings > 0) {
- SDL_InvalidParamError("bindings");
- return;
- }
- if (RENDERPASS_DEVICE->debug_mode) {
- CHECK_RENDERPASS
- }
- RENDERPASS_DEVICE->BindVertexBuffers(
- RENDERPASS_COMMAND_BUFFER,
- first_binding,
- bindings,
- num_bindings);
- }
- void SDL_BindGPUIndexBuffer(
- SDL_GPURenderPass *render_pass,
- const SDL_GPUBufferBinding *binding,
- SDL_GPUIndexElementSize index_element_size)
- {
- if (render_pass == NULL) {
- SDL_InvalidParamError("render_pass");
- return;
- }
- if (binding == NULL) {
- SDL_InvalidParamError("binding");
- return;
- }
- if (RENDERPASS_DEVICE->debug_mode) {
- CHECK_RENDERPASS
- }
- RENDERPASS_DEVICE->BindIndexBuffer(
- RENDERPASS_COMMAND_BUFFER,
- binding,
- index_element_size);
- }
- void SDL_BindGPUVertexSamplers(
- SDL_GPURenderPass *render_pass,
- Uint32 first_slot,
- const SDL_GPUTextureSamplerBinding *texture_sampler_bindings,
- Uint32 num_bindings)
- {
- if (render_pass == NULL) {
- SDL_InvalidParamError("render_pass");
- return;
- }
- if (texture_sampler_bindings == NULL && num_bindings > 0) {
- SDL_InvalidParamError("texture_sampler_bindings");
- return;
- }
- if (RENDERPASS_DEVICE->debug_mode) {
- CHECK_RENDERPASS
- }
- RENDERPASS_DEVICE->BindVertexSamplers(
- RENDERPASS_COMMAND_BUFFER,
- first_slot,
- texture_sampler_bindings,
- num_bindings);
- }
- void SDL_BindGPUVertexStorageTextures(
- SDL_GPURenderPass *render_pass,
- Uint32 first_slot,
- SDL_GPUTexture *const *storage_textures,
- Uint32 num_bindings)
- {
- if (render_pass == NULL) {
- SDL_InvalidParamError("render_pass");
- return;
- }
- if (storage_textures == NULL && num_bindings > 0) {
- SDL_InvalidParamError("storage_textures");
- return;
- }
- if (RENDERPASS_DEVICE->debug_mode) {
- CHECK_RENDERPASS
- }
- RENDERPASS_DEVICE->BindVertexStorageTextures(
- RENDERPASS_COMMAND_BUFFER,
- first_slot,
- storage_textures,
- num_bindings);
- }
- void SDL_BindGPUVertexStorageBuffers(
- SDL_GPURenderPass *render_pass,
- Uint32 first_slot,
- SDL_GPUBuffer *const *storage_buffers,
- Uint32 num_bindings)
- {
- if (render_pass == NULL) {
- SDL_InvalidParamError("render_pass");
- return;
- }
- if (storage_buffers == NULL && num_bindings > 0) {
- SDL_InvalidParamError("storage_buffers");
- return;
- }
- if (RENDERPASS_DEVICE->debug_mode) {
- CHECK_RENDERPASS
- }
- RENDERPASS_DEVICE->BindVertexStorageBuffers(
- RENDERPASS_COMMAND_BUFFER,
- first_slot,
- storage_buffers,
- num_bindings);
- }
- void SDL_BindGPUFragmentSamplers(
- SDL_GPURenderPass *render_pass,
- Uint32 first_slot,
- const SDL_GPUTextureSamplerBinding *texture_sampler_bindings,
- Uint32 num_bindings)
- {
- if (render_pass == NULL) {
- SDL_InvalidParamError("render_pass");
- return;
- }
- if (texture_sampler_bindings == NULL && num_bindings > 0) {
- SDL_InvalidParamError("texture_sampler_bindings");
- return;
- }
- if (RENDERPASS_DEVICE->debug_mode) {
- CHECK_RENDERPASS
- }
- RENDERPASS_DEVICE->BindFragmentSamplers(
- RENDERPASS_COMMAND_BUFFER,
- first_slot,
- texture_sampler_bindings,
- num_bindings);
- }
- void SDL_BindGPUFragmentStorageTextures(
- SDL_GPURenderPass *render_pass,
- Uint32 first_slot,
- SDL_GPUTexture *const *storage_textures,
- Uint32 num_bindings)
- {
- if (render_pass == NULL) {
- SDL_InvalidParamError("render_pass");
- return;
- }
- if (storage_textures == NULL && num_bindings > 0) {
- SDL_InvalidParamError("storage_textures");
- return;
- }
- if (RENDERPASS_DEVICE->debug_mode) {
- CHECK_RENDERPASS
- }
- RENDERPASS_DEVICE->BindFragmentStorageTextures(
- RENDERPASS_COMMAND_BUFFER,
- first_slot,
- storage_textures,
- num_bindings);
- }
- void SDL_BindGPUFragmentStorageBuffers(
- SDL_GPURenderPass *render_pass,
- Uint32 first_slot,
- SDL_GPUBuffer *const *storage_buffers,
- Uint32 num_bindings)
- {
- if (render_pass == NULL) {
- SDL_InvalidParamError("render_pass");
- return;
- }
- if (storage_buffers == NULL && num_bindings > 0) {
- SDL_InvalidParamError("storage_buffers");
- return;
- }
- if (RENDERPASS_DEVICE->debug_mode) {
- CHECK_RENDERPASS
- }
- RENDERPASS_DEVICE->BindFragmentStorageBuffers(
- RENDERPASS_COMMAND_BUFFER,
- first_slot,
- storage_buffers,
- num_bindings);
- }
- void SDL_DrawGPUIndexedPrimitives(
- SDL_GPURenderPass *render_pass,
- Uint32 num_indices,
- Uint32 num_instances,
- Uint32 first_index,
- Sint32 vertex_offset,
- Uint32 first_instance)
- {
- if (render_pass == NULL) {
- SDL_InvalidParamError("render_pass");
- return;
- }
- if (RENDERPASS_DEVICE->debug_mode) {
- CHECK_RENDERPASS
- CHECK_GRAPHICS_PIPELINE_BOUND
- }
- RENDERPASS_DEVICE->DrawIndexedPrimitives(
- RENDERPASS_COMMAND_BUFFER,
- num_indices,
- num_instances,
- first_index,
- vertex_offset,
- first_instance);
- }
- void SDL_DrawGPUPrimitives(
- SDL_GPURenderPass *render_pass,
- Uint32 num_vertices,
- Uint32 num_instances,
- Uint32 first_vertex,
- Uint32 first_instance)
- {
- if (render_pass == NULL) {
- SDL_InvalidParamError("render_pass");
- return;
- }
- if (RENDERPASS_DEVICE->debug_mode) {
- CHECK_RENDERPASS
- CHECK_GRAPHICS_PIPELINE_BOUND
- }
- RENDERPASS_DEVICE->DrawPrimitives(
- RENDERPASS_COMMAND_BUFFER,
- num_vertices,
- num_instances,
- first_vertex,
- first_instance);
- }
- void SDL_DrawGPUPrimitivesIndirect(
- SDL_GPURenderPass *render_pass,
- SDL_GPUBuffer *buffer,
- Uint32 offset,
- Uint32 draw_count)
- {
- if (render_pass == NULL) {
- SDL_InvalidParamError("render_pass");
- return;
- }
- if (buffer == NULL) {
- SDL_InvalidParamError("buffer");
- return;
- }
- if (RENDERPASS_DEVICE->debug_mode) {
- CHECK_RENDERPASS
- CHECK_GRAPHICS_PIPELINE_BOUND
- }
- RENDERPASS_DEVICE->DrawPrimitivesIndirect(
- RENDERPASS_COMMAND_BUFFER,
- buffer,
- offset,
- draw_count);
- }
- void SDL_DrawGPUIndexedPrimitivesIndirect(
- SDL_GPURenderPass *render_pass,
- SDL_GPUBuffer *buffer,
- Uint32 offset,
- Uint32 draw_count)
- {
- if (render_pass == NULL) {
- SDL_InvalidParamError("render_pass");
- return;
- }
- if (buffer == NULL) {
- SDL_InvalidParamError("buffer");
- return;
- }
- if (RENDERPASS_DEVICE->debug_mode) {
- CHECK_RENDERPASS
- CHECK_GRAPHICS_PIPELINE_BOUND
- }
- RENDERPASS_DEVICE->DrawIndexedPrimitivesIndirect(
- RENDERPASS_COMMAND_BUFFER,
- buffer,
- offset,
- draw_count);
- }
- void SDL_EndGPURenderPass(
- SDL_GPURenderPass *render_pass)
- {
- CommandBufferCommonHeader *commandBufferCommonHeader;
- if (render_pass == NULL) {
- SDL_InvalidParamError("render_pass");
- return;
- }
- if (RENDERPASS_DEVICE->debug_mode) {
- CHECK_RENDERPASS
- }
- RENDERPASS_DEVICE->EndRenderPass(
- RENDERPASS_COMMAND_BUFFER);
- commandBufferCommonHeader = (CommandBufferCommonHeader *)RENDERPASS_COMMAND_BUFFER;
- commandBufferCommonHeader->render_pass.in_progress = false;
- commandBufferCommonHeader->graphics_pipeline_bound = false;
- }
- // Compute Pass
- SDL_GPUComputePass *SDL_BeginGPUComputePass(
- SDL_GPUCommandBuffer *command_buffer,
- const SDL_GPUStorageTextureReadWriteBinding *storage_texture_bindings,
- Uint32 num_storage_texture_bindings,
- const SDL_GPUStorageBufferReadWriteBinding *storage_buffer_bindings,
- Uint32 num_storage_buffer_bindings)
- {
- CommandBufferCommonHeader *commandBufferHeader;
- if (command_buffer == NULL) {
- SDL_InvalidParamError("command_buffer");
- return NULL;
- }
- if (storage_texture_bindings == NULL && num_storage_texture_bindings > 0) {
- SDL_InvalidParamError("storage_texture_bindings");
- return NULL;
- }
- if (storage_buffer_bindings == NULL && num_storage_buffer_bindings > 0) {
- SDL_InvalidParamError("storage_buffer_bindings");
- return NULL;
- }
- if (num_storage_texture_bindings > MAX_COMPUTE_WRITE_TEXTURES) {
- SDL_InvalidParamError("num_storage_texture_bindings");
- return NULL;
- }
- if (num_storage_buffer_bindings > MAX_COMPUTE_WRITE_BUFFERS) {
- SDL_InvalidParamError("num_storage_buffer_bindings");
- return NULL;
- }
- if (COMMAND_BUFFER_DEVICE->debug_mode) {
- CHECK_COMMAND_BUFFER_RETURN_NULL
- CHECK_ANY_PASS_IN_PROGRESS("Cannot begin compute pass during another pass!", NULL)
- for (Uint32 i = 0; i < num_storage_texture_bindings; i += 1) {
- TextureCommonHeader *header = (TextureCommonHeader *)storage_texture_bindings[i].texture;
- if (!(header->info.usage & SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_WRITE) && !(header->info.usage & SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_SIMULTANEOUS_READ_WRITE)) {
- SDL_assert_release(!"Texture must be created with COMPUTE_STORAGE_WRITE or COMPUTE_STORAGE_SIMULTANEOUS_READ_WRITE flag");
- return NULL;
- }
- }
- // TODO: validate buffer usage?
- }
- COMMAND_BUFFER_DEVICE->BeginComputePass(
- command_buffer,
- storage_texture_bindings,
- num_storage_texture_bindings,
- storage_buffer_bindings,
- num_storage_buffer_bindings);
- commandBufferHeader = (CommandBufferCommonHeader *)command_buffer;
- commandBufferHeader->compute_pass.in_progress = true;
- return (SDL_GPUComputePass *)&(commandBufferHeader->compute_pass);
- }
- void SDL_BindGPUComputePipeline(
- SDL_GPUComputePass *compute_pass,
- SDL_GPUComputePipeline *compute_pipeline)
- {
- CommandBufferCommonHeader *commandBufferHeader;
- if (compute_pass == NULL) {
- SDL_InvalidParamError("compute_pass");
- return;
- }
- if (compute_pipeline == NULL) {
- SDL_InvalidParamError("compute_pipeline");
- return;
- }
- if (COMPUTEPASS_DEVICE->debug_mode) {
- CHECK_COMPUTEPASS
- }
- COMPUTEPASS_DEVICE->BindComputePipeline(
- COMPUTEPASS_COMMAND_BUFFER,
- compute_pipeline);
- commandBufferHeader = (CommandBufferCommonHeader *)COMPUTEPASS_COMMAND_BUFFER;
- commandBufferHeader->compute_pipeline_bound = true;
- }
- void SDL_BindGPUComputeSamplers(
- SDL_GPUComputePass *compute_pass,
- Uint32 first_slot,
- const SDL_GPUTextureSamplerBinding *texture_sampler_bindings,
- Uint32 num_bindings)
- {
- if (compute_pass == NULL) {
- SDL_InvalidParamError("compute_pass");
- return;
- }
- if (texture_sampler_bindings == NULL && num_bindings > 0) {
- SDL_InvalidParamError("texture_sampler_bindings");
- return;
- }
- if (COMPUTEPASS_DEVICE->debug_mode) {
- CHECK_COMPUTEPASS
- }
- COMPUTEPASS_DEVICE->BindComputeSamplers(
- COMPUTEPASS_COMMAND_BUFFER,
- first_slot,
- texture_sampler_bindings,
- num_bindings);
- }
- void SDL_BindGPUComputeStorageTextures(
- SDL_GPUComputePass *compute_pass,
- Uint32 first_slot,
- SDL_GPUTexture *const *storage_textures,
- Uint32 num_bindings)
- {
- if (compute_pass == NULL) {
- SDL_InvalidParamError("compute_pass");
- return;
- }
- if (storage_textures == NULL && num_bindings > 0) {
- SDL_InvalidParamError("storage_textures");
- return;
- }
- if (COMPUTEPASS_DEVICE->debug_mode) {
- CHECK_COMPUTEPASS
- }
- COMPUTEPASS_DEVICE->BindComputeStorageTextures(
- COMPUTEPASS_COMMAND_BUFFER,
- first_slot,
- storage_textures,
- num_bindings);
- }
- void SDL_BindGPUComputeStorageBuffers(
- SDL_GPUComputePass *compute_pass,
- Uint32 first_slot,
- SDL_GPUBuffer *const *storage_buffers,
- Uint32 num_bindings)
- {
- if (compute_pass == NULL) {
- SDL_InvalidParamError("compute_pass");
- return;
- }
- if (storage_buffers == NULL && num_bindings > 0) {
- SDL_InvalidParamError("storage_buffers");
- return;
- }
- if (COMPUTEPASS_DEVICE->debug_mode) {
- CHECK_COMPUTEPASS
- }
- COMPUTEPASS_DEVICE->BindComputeStorageBuffers(
- COMPUTEPASS_COMMAND_BUFFER,
- first_slot,
- storage_buffers,
- num_bindings);
- }
- void SDL_DispatchGPUCompute(
- SDL_GPUComputePass *compute_pass,
- Uint32 groupcount_x,
- Uint32 groupcount_y,
- Uint32 groupcount_z)
- {
- if (compute_pass == NULL) {
- SDL_InvalidParamError("compute_pass");
- return;
- }
- if (COMPUTEPASS_DEVICE->debug_mode) {
- CHECK_COMPUTEPASS
- CHECK_COMPUTE_PIPELINE_BOUND
- }
- COMPUTEPASS_DEVICE->DispatchCompute(
- COMPUTEPASS_COMMAND_BUFFER,
- groupcount_x,
- groupcount_y,
- groupcount_z);
- }
- void SDL_DispatchGPUComputeIndirect(
- SDL_GPUComputePass *compute_pass,
- SDL_GPUBuffer *buffer,
- Uint32 offset)
- {
- if (compute_pass == NULL) {
- SDL_InvalidParamError("compute_pass");
- return;
- }
- if (COMPUTEPASS_DEVICE->debug_mode) {
- CHECK_COMPUTEPASS
- CHECK_COMPUTE_PIPELINE_BOUND
- }
- COMPUTEPASS_DEVICE->DispatchComputeIndirect(
- COMPUTEPASS_COMMAND_BUFFER,
- buffer,
- offset);
- }
- void SDL_EndGPUComputePass(
- SDL_GPUComputePass *compute_pass)
- {
- CommandBufferCommonHeader *commandBufferCommonHeader;
- if (compute_pass == NULL) {
- SDL_InvalidParamError("compute_pass");
- return;
- }
- if (COMPUTEPASS_DEVICE->debug_mode) {
- CHECK_COMPUTEPASS
- }
- COMPUTEPASS_DEVICE->EndComputePass(
- COMPUTEPASS_COMMAND_BUFFER);
- commandBufferCommonHeader = (CommandBufferCommonHeader *)COMPUTEPASS_COMMAND_BUFFER;
- commandBufferCommonHeader->compute_pass.in_progress = false;
- commandBufferCommonHeader->compute_pipeline_bound = false;
- }
- // TransferBuffer Data
- void *SDL_MapGPUTransferBuffer(
- SDL_GPUDevice *device,
- SDL_GPUTransferBuffer *transfer_buffer,
- bool cycle)
- {
- CHECK_DEVICE_MAGIC(device, NULL);
- if (transfer_buffer == NULL) {
- SDL_InvalidParamError("transfer_buffer");
- return NULL;
- }
- return device->MapTransferBuffer(
- device->driverData,
- transfer_buffer,
- cycle);
- }
- void SDL_UnmapGPUTransferBuffer(
- SDL_GPUDevice *device,
- SDL_GPUTransferBuffer *transfer_buffer)
- {
- CHECK_DEVICE_MAGIC(device, );
- if (transfer_buffer == NULL) {
- SDL_InvalidParamError("transfer_buffer");
- return;
- }
- device->UnmapTransferBuffer(
- device->driverData,
- transfer_buffer);
- }
- // Copy Pass
- SDL_GPUCopyPass *SDL_BeginGPUCopyPass(
- SDL_GPUCommandBuffer *command_buffer)
- {
- CommandBufferCommonHeader *commandBufferHeader;
- if (command_buffer == NULL) {
- SDL_InvalidParamError("command_buffer");
- return NULL;
- }
- if (COMMAND_BUFFER_DEVICE->debug_mode) {
- CHECK_COMMAND_BUFFER_RETURN_NULL
- CHECK_ANY_PASS_IN_PROGRESS("Cannot begin copy pass during another pass!", NULL)
- }
- COMMAND_BUFFER_DEVICE->BeginCopyPass(
- command_buffer);
- commandBufferHeader = (CommandBufferCommonHeader *)command_buffer;
- commandBufferHeader->copy_pass.in_progress = true;
- return (SDL_GPUCopyPass *)&(commandBufferHeader->copy_pass);
- }
- void SDL_UploadToGPUTexture(
- SDL_GPUCopyPass *copy_pass,
- const SDL_GPUTextureTransferInfo *source,
- const SDL_GPUTextureRegion *destination,
- bool cycle)
- {
- if (copy_pass == NULL) {
- SDL_InvalidParamError("copy_pass");
- return;
- }
- if (source == NULL) {
- SDL_InvalidParamError("source");
- return;
- }
- if (destination == NULL) {
- SDL_InvalidParamError("destination");
- return;
- }
- if (COPYPASS_DEVICE->debug_mode) {
- CHECK_COPYPASS
- if (source->transfer_buffer == NULL) {
- SDL_assert_release(!"Source transfer buffer cannot be NULL!");
- return;
- }
- if (destination->texture == NULL) {
- SDL_assert_release(!"Destination texture cannot be NULL!");
- return;
- }
- }
- COPYPASS_DEVICE->UploadToTexture(
- COPYPASS_COMMAND_BUFFER,
- source,
- destination,
- cycle);
- }
- void SDL_UploadToGPUBuffer(
- SDL_GPUCopyPass *copy_pass,
- const SDL_GPUTransferBufferLocation *source,
- const SDL_GPUBufferRegion *destination,
- bool cycle)
- {
- if (copy_pass == NULL) {
- SDL_InvalidParamError("copy_pass");
- return;
- }
- if (source == NULL) {
- SDL_InvalidParamError("source");
- return;
- }
- if (destination == NULL) {
- SDL_InvalidParamError("destination");
- return;
- }
- if (COPYPASS_DEVICE->debug_mode) {
- CHECK_COPYPASS
- if (source->transfer_buffer == NULL) {
- SDL_assert_release(!"Source transfer buffer cannot be NULL!");
- return;
- }
- if (destination->buffer == NULL) {
- SDL_assert_release(!"Destination buffer cannot be NULL!");
- return;
- }
- }
- COPYPASS_DEVICE->UploadToBuffer(
- COPYPASS_COMMAND_BUFFER,
- source,
- destination,
- cycle);
- }
- void SDL_CopyGPUTextureToTexture(
- SDL_GPUCopyPass *copy_pass,
- const SDL_GPUTextureLocation *source,
- const SDL_GPUTextureLocation *destination,
- Uint32 w,
- Uint32 h,
- Uint32 d,
- bool cycle)
- {
- if (copy_pass == NULL) {
- SDL_InvalidParamError("copy_pass");
- return;
- }
- if (source == NULL) {
- SDL_InvalidParamError("source");
- return;
- }
- if (destination == NULL) {
- SDL_InvalidParamError("destination");
- return;
- }
- if (COPYPASS_DEVICE->debug_mode) {
- CHECK_COPYPASS
- if (source->texture == NULL) {
- SDL_assert_release(!"Source texture cannot be NULL!");
- return;
- }
- if (destination->texture == NULL) {
- SDL_assert_release(!"Destination texture cannot be NULL!");
- return;
- }
- }
- COPYPASS_DEVICE->CopyTextureToTexture(
- COPYPASS_COMMAND_BUFFER,
- source,
- destination,
- w,
- h,
- d,
- cycle);
- }
- void SDL_CopyGPUBufferToBuffer(
- SDL_GPUCopyPass *copy_pass,
- const SDL_GPUBufferLocation *source,
- const SDL_GPUBufferLocation *destination,
- Uint32 size,
- bool cycle)
- {
- if (copy_pass == NULL) {
- SDL_InvalidParamError("copy_pass");
- return;
- }
- if (source == NULL) {
- SDL_InvalidParamError("source");
- return;
- }
- if (destination == NULL) {
- SDL_InvalidParamError("destination");
- return;
- }
- if (COPYPASS_DEVICE->debug_mode) {
- CHECK_COPYPASS
- if (source->buffer == NULL) {
- SDL_assert_release(!"Source buffer cannot be NULL!");
- return;
- }
- if (destination->buffer == NULL) {
- SDL_assert_release(!"Destination buffer cannot be NULL!");
- return;
- }
- }
- COPYPASS_DEVICE->CopyBufferToBuffer(
- COPYPASS_COMMAND_BUFFER,
- source,
- destination,
- size,
- cycle);
- }
- void SDL_DownloadFromGPUTexture(
- SDL_GPUCopyPass *copy_pass,
- const SDL_GPUTextureRegion *source,
- const SDL_GPUTextureTransferInfo *destination)
- {
- if (copy_pass == NULL) {
- SDL_InvalidParamError("copy_pass");
- return;
- }
- if (source == NULL) {
- SDL_InvalidParamError("source");
- return;
- }
- if (destination == NULL) {
- SDL_InvalidParamError("destination");
- return;
- }
- if (COPYPASS_DEVICE->debug_mode) {
- CHECK_COPYPASS
- if (source->texture == NULL) {
- SDL_assert_release(!"Source texture cannot be NULL!");
- return;
- }
- if (destination->transfer_buffer == NULL) {
- SDL_assert_release(!"Destination transfer buffer cannot be NULL!");
- return;
- }
- }
- COPYPASS_DEVICE->DownloadFromTexture(
- COPYPASS_COMMAND_BUFFER,
- source,
- destination);
- }
- void SDL_DownloadFromGPUBuffer(
- SDL_GPUCopyPass *copy_pass,
- const SDL_GPUBufferRegion *source,
- const SDL_GPUTransferBufferLocation *destination)
- {
- if (copy_pass == NULL) {
- SDL_InvalidParamError("copy_pass");
- return;
- }
- if (source == NULL) {
- SDL_InvalidParamError("source");
- return;
- }
- if (destination == NULL) {
- SDL_InvalidParamError("destination");
- return;
- }
- if (COPYPASS_DEVICE->debug_mode) {
- CHECK_COPYPASS
- if (source->buffer == NULL) {
- SDL_assert_release(!"Source buffer cannot be NULL!");
- return;
- }
- if (destination->transfer_buffer == NULL) {
- SDL_assert_release(!"Destination transfer buffer cannot be NULL!");
- return;
- }
- }
- COPYPASS_DEVICE->DownloadFromBuffer(
- COPYPASS_COMMAND_BUFFER,
- source,
- destination);
- }
- void SDL_EndGPUCopyPass(
- SDL_GPUCopyPass *copy_pass)
- {
- if (copy_pass == NULL) {
- SDL_InvalidParamError("copy_pass");
- return;
- }
- if (COPYPASS_DEVICE->debug_mode) {
- CHECK_COPYPASS
- }
- COPYPASS_DEVICE->EndCopyPass(
- COPYPASS_COMMAND_BUFFER);
- ((CommandBufferCommonHeader *)COPYPASS_COMMAND_BUFFER)->copy_pass.in_progress = false;
- }
- void SDL_GenerateMipmapsForGPUTexture(
- SDL_GPUCommandBuffer *command_buffer,
- SDL_GPUTexture *texture)
- {
- if (command_buffer == NULL) {
- SDL_InvalidParamError("command_buffer");
- return;
- }
- if (texture == NULL) {
- SDL_InvalidParamError("texture");
- return;
- }
- if (COMMAND_BUFFER_DEVICE->debug_mode) {
- CHECK_COMMAND_BUFFER
- CHECK_ANY_PASS_IN_PROGRESS("Cannot generate mipmaps during a pass!", )
- TextureCommonHeader *header = (TextureCommonHeader *)texture;
- if (header->info.num_levels <= 1) {
- SDL_assert_release(!"Cannot generate mipmaps for texture with num_levels <= 1!");
- return;
- }
- if (!(header->info.usage & SDL_GPU_TEXTUREUSAGE_SAMPLER) || !(header->info.usage & SDL_GPU_TEXTUREUSAGE_COLOR_TARGET)) {
- SDL_assert_release(!"GenerateMipmaps texture must be created with SAMPLER and COLOR_TARGET usage flags!");
- return;
- }
- }
- COMMAND_BUFFER_DEVICE->GenerateMipmaps(
- command_buffer,
- texture);
- }
- void SDL_BlitGPUTexture(
- SDL_GPUCommandBuffer *command_buffer,
- const SDL_GPUBlitInfo *info)
- {
- if (command_buffer == NULL) {
- SDL_InvalidParamError("command_buffer");
- return;
- }
- if (info == NULL) {
- SDL_InvalidParamError("info");
- return;
- }
- if (COMMAND_BUFFER_DEVICE->debug_mode) {
- CHECK_COMMAND_BUFFER
- CHECK_ANY_PASS_IN_PROGRESS("Cannot blit during a pass!", )
- // Validation
- bool failed = false;
- TextureCommonHeader *srcHeader = (TextureCommonHeader *)info->source.texture;
- TextureCommonHeader *dstHeader = (TextureCommonHeader *)info->destination.texture;
- if (srcHeader == NULL) {
- SDL_assert_release(!"Blit source texture must be non-NULL");
- return; // attempting to proceed will crash
- }
- if (dstHeader == NULL) {
- SDL_assert_release(!"Blit destination texture must be non-NULL");
- return; // attempting to proceed will crash
- }
- if (srcHeader->info.sample_count != SDL_GPU_SAMPLECOUNT_1) {
- SDL_assert_release(!"Blit source texture must have a sample count of 1");
- failed = true;
- }
- if ((srcHeader->info.usage & SDL_GPU_TEXTUREUSAGE_SAMPLER) == 0) {
- SDL_assert_release(!"Blit source texture must be created with the SAMPLER usage flag");
- failed = true;
- }
- if ((dstHeader->info.usage & SDL_GPU_TEXTUREUSAGE_COLOR_TARGET) == 0) {
- SDL_assert_release(!"Blit destination texture must be created with the COLOR_TARGET usage flag");
- failed = true;
- }
- if (IsDepthFormat(srcHeader->info.format)) {
- SDL_assert_release(!"Blit source texture cannot have a depth format");
- failed = true;
- }
- if (info->source.w == 0 || info->source.h == 0 || info->destination.w == 0 || info->destination.h == 0) {
- SDL_assert_release(!"Blit source/destination regions must have non-zero width, height, and depth");
- failed = true;
- }
- if (failed) {
- return;
- }
- }
- COMMAND_BUFFER_DEVICE->Blit(
- command_buffer,
- info);
- }
- // Submission/Presentation
- bool SDL_WindowSupportsGPUSwapchainComposition(
- SDL_GPUDevice *device,
- SDL_Window *window,
- SDL_GPUSwapchainComposition swapchain_composition)
- {
- CHECK_DEVICE_MAGIC(device, false);
- if (window == NULL) {
- SDL_InvalidParamError("window");
- return false;
- }
- if (device->debug_mode) {
- CHECK_SWAPCHAINCOMPOSITION_ENUM_INVALID(swapchain_composition, false)
- }
- return device->SupportsSwapchainComposition(
- device->driverData,
- window,
- swapchain_composition);
- }
- bool SDL_WindowSupportsGPUPresentMode(
- SDL_GPUDevice *device,
- SDL_Window *window,
- SDL_GPUPresentMode present_mode)
- {
- CHECK_DEVICE_MAGIC(device, false);
- if (window == NULL) {
- SDL_InvalidParamError("window");
- return false;
- }
- if (device->debug_mode) {
- CHECK_PRESENTMODE_ENUM_INVALID(present_mode, false)
- }
- return device->SupportsPresentMode(
- device->driverData,
- window,
- present_mode);
- }
- bool SDL_ClaimWindowForGPUDevice(
- SDL_GPUDevice *device,
- SDL_Window *window)
- {
- CHECK_DEVICE_MAGIC(device, false);
- if (window == NULL) {
- SDL_InvalidParamError("window");
- return false;
- }
- return device->ClaimWindow(
- device->driverData,
- window);
- }
- void SDL_ReleaseWindowFromGPUDevice(
- SDL_GPUDevice *device,
- SDL_Window *window)
- {
- CHECK_DEVICE_MAGIC(device, );
- if (window == NULL) {
- SDL_InvalidParamError("window");
- return;
- }
- device->ReleaseWindow(
- device->driverData,
- window);
- }
- bool SDL_SetGPUSwapchainParameters(
- SDL_GPUDevice *device,
- SDL_Window *window,
- SDL_GPUSwapchainComposition swapchain_composition,
- SDL_GPUPresentMode present_mode)
- {
- CHECK_DEVICE_MAGIC(device, false);
- if (window == NULL) {
- SDL_InvalidParamError("window");
- return false;
- }
- if (device->debug_mode) {
- CHECK_SWAPCHAINCOMPOSITION_ENUM_INVALID(swapchain_composition, false)
- CHECK_PRESENTMODE_ENUM_INVALID(present_mode, false)
- }
- return device->SetSwapchainParameters(
- device->driverData,
- window,
- swapchain_composition,
- present_mode);
- }
- SDL_GPUTextureFormat SDL_GetGPUSwapchainTextureFormat(
- SDL_GPUDevice *device,
- SDL_Window *window)
- {
- CHECK_DEVICE_MAGIC(device, SDL_GPU_TEXTUREFORMAT_INVALID);
- if (window == NULL) {
- SDL_InvalidParamError("window");
- return SDL_GPU_TEXTUREFORMAT_INVALID;
- }
- return device->GetSwapchainTextureFormat(
- device->driverData,
- window);
- }
- bool SDL_AcquireGPUSwapchainTexture(
- SDL_GPUCommandBuffer *command_buffer,
- SDL_Window *window,
- SDL_GPUTexture **swapchain_texture,
- Uint32 *swapchain_texture_width,
- Uint32 *swapchain_texture_height)
- {
- if (command_buffer == NULL) {
- SDL_InvalidParamError("command_buffer");
- return false;
- }
- if (window == NULL) {
- SDL_InvalidParamError("window");
- return false;
- }
- if (swapchain_texture == NULL) {
- SDL_InvalidParamError("swapchain_texture");
- return false;
- }
- if (COMMAND_BUFFER_DEVICE->debug_mode) {
- CHECK_COMMAND_BUFFER_RETURN_FALSE
- CHECK_ANY_PASS_IN_PROGRESS("Cannot acquire a swapchain texture during a pass!", false)
- }
- return COMMAND_BUFFER_DEVICE->AcquireSwapchainTexture(
- command_buffer,
- window,
- swapchain_texture,
- swapchain_texture_width,
- swapchain_texture_height);
- }
- bool SDL_SubmitGPUCommandBuffer(
- SDL_GPUCommandBuffer *command_buffer)
- {
- CommandBufferCommonHeader *commandBufferHeader = (CommandBufferCommonHeader *)command_buffer;
- if (command_buffer == NULL) {
- SDL_InvalidParamError("command_buffer");
- return false;
- }
- if (COMMAND_BUFFER_DEVICE->debug_mode) {
- CHECK_COMMAND_BUFFER_RETURN_FALSE
- if (
- commandBufferHeader->render_pass.in_progress ||
- commandBufferHeader->compute_pass.in_progress ||
- commandBufferHeader->copy_pass.in_progress) {
- SDL_assert_release(!"Cannot submit command buffer while a pass is in progress!");
- return false;
- }
- }
- commandBufferHeader->submitted = true;
- return COMMAND_BUFFER_DEVICE->Submit(
- command_buffer);
- }
- SDL_GPUFence *SDL_SubmitGPUCommandBufferAndAcquireFence(
- SDL_GPUCommandBuffer *command_buffer)
- {
- CommandBufferCommonHeader *commandBufferHeader = (CommandBufferCommonHeader *)command_buffer;
- if (command_buffer == NULL) {
- SDL_InvalidParamError("command_buffer");
- return NULL;
- }
- if (COMMAND_BUFFER_DEVICE->debug_mode) {
- CHECK_COMMAND_BUFFER_RETURN_NULL
- if (
- commandBufferHeader->render_pass.in_progress ||
- commandBufferHeader->compute_pass.in_progress ||
- commandBufferHeader->copy_pass.in_progress) {
- SDL_assert_release(!"Cannot submit command buffer while a pass is in progress!");
- return NULL;
- }
- }
- commandBufferHeader->submitted = true;
- return COMMAND_BUFFER_DEVICE->SubmitAndAcquireFence(
- command_buffer);
- }
- bool SDL_WaitForGPUIdle(
- SDL_GPUDevice *device)
- {
- CHECK_DEVICE_MAGIC(device, false);
- return device->Wait(
- device->driverData);
- }
- bool SDL_WaitForGPUFences(
- SDL_GPUDevice *device,
- bool wait_all,
- SDL_GPUFence *const *fences,
- Uint32 num_fences)
- {
- CHECK_DEVICE_MAGIC(device, false);
- if (fences == NULL && num_fences > 0) {
- SDL_InvalidParamError("fences");
- return false;
- }
- return device->WaitForFences(
- device->driverData,
- wait_all,
- fences,
- num_fences);
- }
- bool SDL_QueryGPUFence(
- SDL_GPUDevice *device,
- SDL_GPUFence *fence)
- {
- CHECK_DEVICE_MAGIC(device, false);
- if (fence == NULL) {
- SDL_InvalidParamError("fence");
- return false;
- }
- return device->QueryFence(
- device->driverData,
- fence);
- }
- void SDL_ReleaseGPUFence(
- SDL_GPUDevice *device,
- SDL_GPUFence *fence)
- {
- CHECK_DEVICE_MAGIC(device, );
- if (fence == NULL) {
- return;
- }
- device->ReleaseFence(
- device->driverData,
- fence);
- }
|