Compare commits

..

218 Commits

Author SHA1 Message Date
CamilleLaVey f6a73525a3 Revert "[spv, vk, qcom] SFC 1 x 2 + SPVE." 2025-12-26 00:13:42 -03:00
CamilleLaVey afab4aa558 Revert "Fix building" 2025-12-26 00:13:42 -03:00
CamilleLaVey 5fbfbb66cf Revert "another smol fix" 2025-12-26 00:13:42 -03:00
CamilleLaVey 99258dd645 Revert "duplicate noms noms" 2025-12-26 00:13:42 -03:00
CamilleLaVey 48c732d7f6 Revert "fix for the fix of the fix" 2025-12-26 00:13:42 -03:00
CamilleLaVey 77265157de Revert "fix it goddamn" 2025-12-26 00:13:42 -03:00
CamilleLaVey 5c6488e6de Revert "Ya basta vulkaaaan" 2025-12-26 00:13:41 -03:00
CamilleLaVey 12465c4bee Ya basta vulkaaaan 2025-12-26 00:13:41 -03:00
CamilleLaVey 7e846ed444 fix it goddamn 2025-12-26 00:13:41 -03:00
CamilleLaVey d4edf36c47 fix for the fix of the fix 2025-12-26 00:13:41 -03:00
CamilleLaVey 7b21bb07d5 duplicate noms noms 2025-12-26 00:13:41 -03:00
CamilleLaVey 8063f80df9 another smol fix 2025-12-26 00:13:41 -03:00
CamilleLaVey 075ecc6e39 Fix building 2025-12-26 00:13:40 -03:00
CamilleLaVey 81cd6cea66 [spv, vk, qcom] SFC 1 x 2 + SPVE. 2025-12-26 00:13:40 -03:00
CamilleLaVey 2d78333479 [shader_enviroment] TICEntry limits to Empty 2025-12-26 00:13:40 -03:00
CamilleLaVey 6a0b274b1a [vk] Start of a downhill 2025-12-26 00:12:35 -03:00
CamilleLaVey 805b53657c [vk] sRGB format handling for Storage. 2025-12-26 00:12:35 -03:00
CamilleLaVey 51c6f898a6 [vk] Ordering UnsupportedFormatKey 2025-12-26 00:12:34 -03:00
CamilleLaVey 2141ab8bdf [vk] Image Remaining Layers 3D 2025-12-26 00:12:34 -03:00
CamilleLaVey 40169ed983 [vk] Another try with Depth/Stencil handling 2025-12-26 00:12:34 -03:00
CamilleLaVey dd8bad8486 [vk, qcom] Code clean-up. 2025-12-26 00:12:34 -03:00
CamilleLaVey 0fe10f57f0 [revert] Added linear filtering in texture blitting operations 2025-12-26 00:12:34 -03:00
CamilleLaVey 8e3475632a Fix building 2025-12-26 00:12:34 -03:00
CamilleLaVey 8651647736 [vk] SL complete removal 2025-12-26 00:12:32 -03:00
CamilleLaVey 185e0c18f2 [revert] Allocate data transfer from Maxwell to VK using Sample Locations as channel for MSAA 2025-12-26 00:11:45 -03:00
CamilleLaVey 9eab1a6d05 [revert] SL Sample Count Clamp 2025-12-26 00:11:45 -03:00
CamilleLaVey ddf441d30e [revert] SL Table order 2025-12-26 00:11:45 -03:00
CamilleLaVey 2d617438b0 [vk] SL Table order 2025-12-26 00:11:45 -03:00
CamilleLaVey 7d69ff6044 [vk] SL Sample Count Clamp 2025-12-26 00:11:45 -03:00
CamilleLaVey 4b0f581973 [vk] DrainPendingBuild 2025-12-26 00:11:44 -03:00
CamilleLaVey b03cc654f3 [vk, qcom[ Removed parallel compilling from qcom entirely 2025-12-26 00:11:44 -03:00
CamilleLaVey 2fa36de465 [vk, qcom, turnip] TimelineSemaphore removal 2025-12-26 00:11:44 -03:00
CamilleLaVey 2434be8610 [vk] Adjusted Texel Block View for Depth/Stencil attachment images 2025-12-26 00:11:44 -03:00
CamilleLaVey 624879a21b [vk, qcom] SFC disabled 2025-12-26 00:11:44 -03:00
CamilleLaVey 8bd4c76b22 [maxwell, vk] Allocate data transfer from Maxwell to VK using Sample Locations as channel for MSAA 2025-12-26 00:11:44 -03:00
CamilleLaVey e96972c62e [vk] Removed unused extensions 2025-12-26 00:11:43 -03:00
CamilleLaVey f96297d188 [revert] Adjusting unused features 2025-12-26 00:11:43 -03:00
CamilleLaVey 66968f2f47 [revert] fix building 2025-12-26 00:11:43 -03:00
CamilleLaVey 1585cfd5af [vk] TEST: SFC + WGML 2025-12-26 00:11:43 -03:00
CamilleLaVey 963cf1b726 fix building 2025-12-26 00:11:43 -03:00
CamilleLaVey db0e652299 [vk, qcom] Adjusting unused features 2025-12-26 00:11:43 -03:00
CamilleLaVey 9c7be0fafd [vk] Hotfix for DepthBounds and StencilMask. 2025-12-26 00:11:43 -03:00
CamilleLaVey 05b067a18f [revert] Update Gradle to 8.13.1 2025-12-26 00:11:42 -03:00
CamilleLaVey a95de7c62b [Android] Core 1++ 2025-12-26 00:11:42 -03:00
CamilleLaVey bbce9ffeed another one 2025-12-26 00:11:42 -03:00
CamilleLaVey 2168b76f91 Missing header 2025-12-26 00:11:42 -03:00
CamilleLaVey e03c453e8f [vk] Exception modified & logged 2025-12-26 00:11:42 -03:00
CamilleLaVey be38719fa0 [hle] BufferDescritorC 2025-12-26 00:11:42 -03:00
CamilleLaVey eba14cf142 [vk, qcom] TimelineSemaphore syncs to GPUTick. 2025-12-26 00:11:41 -03:00
CamilleLaVey c05eff593c [gl] WaitTick 2025-12-26 00:11:41 -03:00
CamilleLaVey a8cbd910d8 [gl, vk] Access Tracking Synchronization 2025-12-26 00:11:41 -03:00
CamilleLaVey bfcce2609b [vk] SurfaceType Depth/Stencil 2025-12-26 00:11:41 -03:00
CamilleLaVey a9ca6e59bb [vk] SamplerComponentType upgraded DepthCompareSampling 2025-12-26 00:11:41 -03:00
CamilleLaVey 4f53810276 [Vk] Sample Locations Adjustments for Depth/Stencil 2025-12-26 00:11:41 -03:00
CamilleLaVey 400744178c [vk] Sample Location Depth Bit 2025-12-26 00:11:40 -03:00
CamilleLaVey e30654b76b [vk] Increased PipelineWorkers for testing purposes 2025-12-26 00:11:40 -03:00
CamilleLaVey d9d021be62 [vk] KeepAliveTick in Scheduler 2025-12-26 00:11:40 -03:00
CamilleLaVey 9411fcd352 [vk] Sample Locations ordering 2025-12-26 00:11:40 -03:00
CamilleLaVey 9190b6c761 Hotfix 2025-12-26 00:11:40 -03:00
CamilleLaVey 4a3d1913ac [vk] Re-introduction to MSAA - Sample Locations 2025-12-26 00:11:40 -03:00
CamilleLaVey 95782cc7a9 [vk, mobile, vendor] MegaBuffer removal 2025-12-26 00:11:40 -03:00
CamilleLaVey 525e878ddc [vk, pipeline] Added In-flight conditional for multiple pipeline compilations 2025-12-26 00:11:39 -03:00
CamilleLaVey 49894f3897 [vk, qcom] Extending GetTotalPipelineWorker resources. 2025-12-26 00:11:39 -03:00
CamilleLaVey 822d485e18 [vk] SanitizeComponent Adjustment 2025-12-26 00:11:39 -03:00
CamilleLaVey ae48fe0a13 [vk] DualBlendFactor 2025-12-26 00:11:39 -03:00
CamilleLaVey 1a75757bbf [vk] CounterStreamer 2025-12-26 00:11:39 -03:00
CamilleLaVey f8d93780b5 [vk, qcom] Re-enabling CBC for further testing 2025-12-26 00:11:39 -03:00
CamilleLaVey b047a13f31 [vk] Sanitize Format/Component 2025-12-26 00:11:38 -03:00
CamilleLaVey 59271973a5 [vk] Extended PixelFormat for Depth/Stencil 2025-12-26 00:11:38 -03:00
CamilleLaVey 679aeb7692 [vk] Reordering PixelFormatNumeric 2025-12-26 00:11:38 -03:00
CamilleLaVey fd40618fd8 Added missing headers 2025-12-26 00:11:38 -03:00
CamilleLaVey a064cf76a3 [gl, vk] Corroborating new helpers order 2025-12-26 00:11:38 -03:00
CamilleLaVey 25636a90be Meow 2025-12-26 00:11:38 -03:00
CamilleLaVey 0152770fd7 [vk] Extending TF handling 2025-12-26 00:11:37 -03:00
CamilleLaVey 457beec066 [gl, vk, spv] Added component type handling for texture buffers and resolve pixel format variants 2025-12-26 00:11:37 -03:00
CamilleLaVey 01faf544e8 Saving Private Windows 2025-12-26 00:11:37 -03:00
CamilleLaVey 1164f17d8f [vk] Formatting missing formats 2025-12-26 00:11:37 -03:00
CamilleLaVey 89c679d08d another missing brace 2025-12-26 00:11:37 -03:00
CamilleLaVey 1d1e352a73 If this get builded i'll be able to actually, truly and sincely fly 2025-12-26 00:11:37 -03:00
CamilleLaVey d026d17805 missing brace 2025-12-26 00:11:37 -03:00
CamilleLaVey fc3b5a0b68 quick fix 2025-12-26 00:11:36 -03:00
CamilleLaVey 993a34273f [vk] TextureType extended 2025-12-26 00:11:36 -03:00
CamilleLaVey 54b186ef34 [vk] Adjustment BitScaleHelper 2025-12-26 00:11:36 -03:00
CamilleLaVey 71bf2b33a7 [vk] BufferCache NullBuffer handling 2025-12-26 00:11:36 -03:00
CamilleLaVey 409dbb9581 [vk] Runtime to change image layout 2025-12-26 00:11:36 -03:00
CamilleLaVey 0aa138b707 [vk] TextureFilter 2025-12-26 00:11:36 -03:00
CamilleLaVey f5668bada0 [gl, vk] SupportLinearFilter patch 2025-12-26 00:11:35 -03:00
CamilleLaVey e366f702ef [vk] Wrapper for Sampler Image Filter 2025-12-26 00:11:35 -03:00
CamilleLaVey 088de307d2 [vk, rasterizer] Re-order post Sample Locations removal 2025-12-26 00:11:35 -03:00
CamilleLaVey 11b83e7b73 [revert] Opcode Promotion path emulation 2025-12-26 00:11:35 -03:00
CamilleLaVey 771786523c [revert] lambda enemy of da world 2025-12-26 00:11:35 -03:00
CamilleLaVey 6b9135d53b [revert] The next step of the human kind before it's doom 2025-12-26 00:11:35 -03:00
CamilleLaVey 48a80afa79 [vk] The next step of the human kind before it's doom 2025-12-26 00:11:35 -03:00
CamilleLaVey cbc65e20dc lambda enemy of da world 2025-12-26 00:11:34 -03:00
CamilleLaVey 9dccd2013d [vk, gl, spv] Opcode Promotion path emulation 2025-12-26 00:11:34 -03:00
CamilleLaVey f5172f88e8 [vk] Fixing wrong enabling logic 2025-12-26 00:11:34 -03:00
CamilleLaVey 5ca605fb8a [vk] NullDescriptor guard 2025-12-26 00:11:34 -03:00
CamilleLaVey 91e134ee17 [vk] Adjusted Transform Feedback 2025-12-26 00:11:32 -03:00
CamilleLaVey 061fe400d8 [vk] Adjusted Query Cache 2025-12-26 00:08:10 -03:00
CamilleLaVey 7e79effa03 [vk, qcom] Shader Float Control changed handling 2025-12-26 00:08:10 -03:00
CamilleLaVey ab8905e36b [vk] Removed Sample Locations 2025-12-26 00:08:10 -03:00
CamilleLaVey da344eb513 [vk] removed ImageViewType function 2025-12-26 00:08:09 -03:00
CamilleLaVey 7b78b2dd1f [spv, vk] reworked texture view handling and added layer count overrides 2025-12-26 00:08:09 -03:00
CamilleLaVey 93f4cccb76 [vk] Unused mark for subgroups variables 2025-12-26 00:08:09 -03:00
CamilleLaVey b190dcb937 [revert] UWU 2025-12-26 00:08:09 -03:00
CamilleLaVey c8d01912e1 [Re-introduced] Color output handling in SPIR-V emission 2025-12-26 00:08:09 -03:00
CamilleLaVey 7347be7196 [Re-introduced] Added linear filtering in texture blitting operations 2025-12-26 00:08:09 -03:00
CamilleLaVey d3ea3e8852 [spv, qcom] Ensuring SPV 1.3 2025-12-26 00:08:09 -03:00
CamilleLaVey e4b6e5feff [android] Update Gradle to 8.13.1 2025-12-26 00:08:08 -03:00
CamilleLaVey 3ca3161d5c [vk, qcom] UWU 2025-12-26 00:08:08 -03:00
CamilleLaVey 5029fcf5bf [revert] Added linear filtering in texture blitting operations 2025-12-26 00:08:08 -03:00
CamilleLaVey aa3953f3e2 [revert] Color output handling in SPIR-V emission. 2025-12-26 00:08:08 -03:00
CamilleLaVey cef455d515 [vk] Remove forced stencil format handling in TextureCacheRuntime 2025-12-26 00:08:08 -03:00
CamilleLaVey 02d45d6a8c [revert] TiledCacheBarrier starter 2025-12-26 00:08:08 -03:00
CamilleLaVey 0c45096e6f [vk, qcom] Returned subgroups functions to QCOM 2025-12-26 00:08:07 -03:00
CamilleLaVey 3117521da9 [vk] Added support for Stencil component type in texture handling 2025-12-26 00:08:07 -03:00
CamilleLaVey 459b26465e [vk, qcom] Graphics Subgroup bugged 2025-12-26 00:08:07 -03:00
CamilleLaVey 105817f9d2 [vk] Added support for sample locations in depth and depth-stencil surfaces 2025-12-26 00:08:07 -03:00
CamilleLaVey 4c1b86a4bb [spv] SamplerComponentType 2025-12-26 00:08:07 -03:00
CamilleLaVey 90aebee96b [revert] Tightened SSBO tracking heuristics 2025-12-26 00:08:07 -03:00
CamilleLaVey b48bc13c7c [Revert] Adjusted Track function for bias handling and alignment checks for storage buffers 2025-12-26 00:08:07 -03:00
CamilleLaVey 0026b477c5 [gl, vk] Implement SampledView method for ImageView 2025-12-26 00:08:06 -03:00
CamilleLaVey 9992e5d39c [ir, spv] Added support for sampler component types in texture handling 2025-12-26 00:08:06 -03:00
CamilleLaVey 611b3332ce [spv] Color output handling in SPIR-V emission. 2025-12-26 00:08:06 -03:00
CamilleLaVey 60f00f58ba [vk] Added linear filtering in texture blitting operations 2025-12-26 00:08:06 -03:00
CamilleLaVey 458302b3f5 [spv, qcom] Implement warp intrinsics support 2025-12-26 00:08:06 -03:00
CamilleLaVey a793a132fc [vk] Conditioning Conditional Rendering #2 2025-12-26 00:08:06 -03:00
CamilleLaVey 122385b795 [vk, qcom] Removed SPIR-V 1.4 for qcom 2025-12-26 00:08:05 -03:00
CamilleLaVey adbbd92a9d [vk] Adjustments to Sample Locations 2025-12-26 00:08:05 -03:00
CamilleLaVey d3392954bf [host] Adjusted Track function for bias handling and alignment checks for storage buffers 2025-12-26 00:08:05 -03:00
CamilleLaVey 39506ae599 [host] Added logging for OOM cases with fastmem relation 2025-12-26 00:08:05 -03:00
CamilleLaVey 4bafce0e2a [ir, nvn] Tightened SSBO tracking heuristics 2025-12-26 00:08:05 -03:00
Caio Oliveira 145f1bae5c Revert "Controlled SPV features on QCOM"
This reverts commit 907b041ec6fb4f16750155f4c41e17389f2e385d.
2025-12-26 00:08:05 -03:00
CamilleLaVey d6f14f5519 Controlled SPV features on QCOM 2025-12-26 00:08:04 -03:00
CamilleLaVey f40774a4b9 [vk, qcom] Disabling VK_KHR_push_descriptor for qcom 2025-12-26 00:08:04 -03:00
CamilleLaVey b30b1d6b09 [vk, vendor, mobile] Improved mobile staging buffer data 2025-12-26 00:08:04 -03:00
CamilleLaVey 3b91d0b146 [vk, rasterizer] Update sample location handling for MSAA configurations 2025-12-26 00:08:04 -03:00
CamilleLaVey 75bfe1b4d8 [vk, rasterizer] offsets float x Uint 2025-12-26 00:08:04 -03:00
CamilleLaVey edc6b909b5 [vk] Sample Locations Structure 2025-12-26 00:08:04 -03:00
CamilleLaVey 09817947c4 [vk, rasterizer] TiledCacheBarrier starter 2025-12-26 00:08:04 -03:00
CamilleLaVey e66bc40b8b [maxwell, vk] VK_EXT_Sample_Locations 2025-12-26 00:08:02 -03:00
CamilleLaVey 1bd8012450 [vk, qcom] Removed 500.800.51 compilling parallel restriction 2025-12-26 00:07:38 -03:00
CamilleLaVey d763cafca6 [vk, qcom] Adjusting Sampler Budget reserved value 2025-12-26 00:07:38 -03:00
CamilleLaVey c14175e481 [vk, qcom] UniformBufferAlignment set by hardware capabilities 2025-12-26 00:07:38 -03:00
CamilleLaVey 79f6a6096f [vk, qcom] Samplers Budget Management 2025-12-26 00:07:38 -03:00
CamilleLaVey fd53dc0748 [vk, qcom] Extending limits of broken parallel compiling to 512.800.51 2025-12-26 00:07:37 -03:00
CamilleLaVey 3619fe7e99 [vk, qcom] Binding buffer limits 2025-12-26 00:07:37 -03:00
CamilleLaVey 79ca29d468 [vk, vendor] Clamping memory usage in mobile gpu's 2025-12-26 00:07:37 -03:00
CamilleLaVey 8ed13cf80a [vk, qcom] Remove VK_EXT_CUSTOM_BORDER_COLOR 2025-12-26 00:07:37 -03:00
CamilleLaVey 04c29645a2 Fix building 2025-12-25 23:57:02 -03:00
CamilleLaVey 5666401685 Warning fix 2025-12-25 23:57:01 -03:00
CamilleLaVey be6e577bc2 [vk, pipeline, query_cache, rasterizer] transformFeedback buffering handling update 2025-12-25 23:57:01 -03:00
Caio Oliveira 875829f8fc Partially reverts "[vk] Changing conditions for Swapchain maintenance1 "
This reverts commit 3fc3b5fdad.
2025-12-25 23:57:01 -03:00
CamilleLaVey fec98b8913 [revert] Resolving conflicting changes 2025-12-25 23:57:01 -03:00
CamilleLaVey e6ec42ee9d Revert "[vk] Ensure image view flags are resolved" 2025-12-25 23:57:01 -03:00
CamilleLaVey bc70f1b32d Revert "[vk, texture_cache] Preveting ARGB8 get misinterpretated with depth formats" 2025-12-25 23:57:01 -03:00
CamilleLaVey 94674c9143 Revert "[vk, texture_cache] BGRA8 Depth/Stencil format convertions" 2025-12-25 23:57:00 -03:00
CamilleLaVey 287dcd0bcf Revert "[maxwell] Logging for HDR wrong convertions into depth formats"
This reverts commit 66c26e39fe.
2025-12-25 23:57:00 -03:00
CamilleLaVey cb19579b44 Revert "[surface, vk, pipeline, texture_cache] Refactor image view handling and add normalized compatible format utility"
This reverts commit 6a230bec1a.
2025-12-25 23:57:00 -03:00
CamilleLaVey dd4deb9796 Revert "[spir-v] Add is_integer flag to texture descriptors and update image type handling" 2025-12-25 23:57:00 -03:00
CamilleLaVey 38caca49c6 Revert "[vk, pipeline, texture_cache] Renamed MakeView parametter" 2025-12-25 23:57:00 -03:00
CamilleLaVey 5a5d4b549a [vk] Gating advanced ExtendedDynamicState1 2025-12-25 23:57:00 -03:00
CamilleLaVey 2add5905b5 [licences] Updating licenses on missing files 2025-12-25 23:57:00 -03:00
CamilleLaVey b517cfcbf3 [vk] Line rasterization and Alpha features adjusments (again) 2025-12-25 23:56:59 -03:00
CamilleLaVey 79b78de780 [vk, scheduler] Applying finising call for TF when it's not getting used 2025-12-25 23:56:59 -03:00
CamilleLaVey 352da451c0 [vk, qcom] Returning forced SScaled and UScaled formats emulations to Adreno. 2025-12-25 23:56:59 -03:00
CamilleLaVey 8ffdf69831 [vk, vendor] Forcing BGR5 emulation path due to driver misbehavior. 2025-12-25 23:56:59 -03:00
CamilleLaVey 0e4cd4ecd9 [vk] ExtendedDynamicState repair #2 2025-12-25 23:56:59 -03:00
CamilleLaVey 5919f2d860 [vk] Depth State Refresh Update. 2025-12-25 23:56:59 -03:00
CamilleLaVey cd2f57d1e2 [vk, compute_pass] Conditioning Conditional Rendering 2025-12-25 23:56:58 -03:00
CamilleLaVey c441d1883b [spir-v, emit] Flat Decoration Adjustment 2025-12-25 23:56:58 -03:00
CamilleLaVey e56accf146 [spir-v, emit] SPV Image Missmatch 2025-12-25 23:56:58 -03:00
CamilleLaVey cf37a68e07 [vk, rasterizer] Clamping Render-Area out of limits 2025-12-25 23:56:58 -03:00
CamilleLaVey a2892fccdb [vk, rasterizer, state_tracker] LineMode disabled from scheduler 2025-12-25 23:56:58 -03:00
CamilleLaVey c4b0d116e9 [surface, vk, pipeline, texture_cache] Texture Sampling Fix 2025-12-25 23:56:58 -03:00
CamilleLaVey 58fb3487d1 [vk, swapchain] Swapchaing Image VkQueue 2025-12-25 23:56:58 -03:00
CamilleLaVey 7d8c1baa87 [vk, graphics, pipeline, rasterizer] Alpha Coverage Adjustment 2025-12-25 23:56:57 -03:00
CamilleLaVey ac23e3100f [vk, pipeline, texture_cache] Renamed MakeView parametter 2025-12-25 23:56:57 -03:00
CamilleLaVey 14d3d5814b [spir-v] Add is_integer flag to texture descriptors and update image type handling 2025-12-25 23:56:57 -03:00
CamilleLaVey 04e0b3147b [surface, vk, pipeline, texture_cache] Refactor image view handling and add normalized compatible format utility 2025-12-25 23:56:57 -03:00
CamilleLaVey cb3495621e [vk] Removing false remove feature logging for robustness2 and image robustness. 2025-12-25 23:56:57 -03:00
CamilleLaVey fbb513c83d [vk] ExtendedDynamicState repair #1 2025-12-25 23:56:57 -03:00
CamilleLaVey 8dfc42b45a [spir-v] Flat decorations for input interfaces 2025-12-25 23:56:56 -03:00
CamilleLaVey 977904cd27 [vk] VK_EXT_multi_draw 2025-12-25 23:56:54 -03:00
CamilleLaVey 0c26513484 [vk] Declaring features from Maintenance5 2025-12-25 23:53:26 -03:00
CamilleLaVey 2fb238ab56 [vk] Fixing logging statements 2025-12-25 23:53:26 -03:00
CamilleLaVey 2209efb618 [vk] Removing Image Robustness from EXT list. 2025-12-25 23:53:26 -03:00
CamilleLaVey 7d3380b38d [vk] ExtendedDynamicState impl close to Vulkan specs 2025-12-25 23:53:26 -03:00
CamilleLaVey d161d5e7a2 [vk, rasterizer] Reduce FlushWork constant drawcalls 2025-12-25 23:53:26 -03:00
CamilleLaVey 2aa0bc9f0f [vk] Moving Maintenance features to wrapper 2025-12-25 23:53:26 -03:00
CamilleLaVey 07cf4451c2 [vk] Re-ordering tiling format features 2025-12-25 23:53:25 -03:00
CamilleLaVey 2e8e808958 [vk] Re-ordering format feature 2025-12-25 23:53:25 -03:00
CamilleLaVey 6aa581abeb [vk] Robustness2 and Image Robustness 2025-12-25 23:53:25 -03:00
CamilleLaVey f9043627be [maxwell] Logging for HDR wrong convertions into depth formats 2025-12-25 23:53:25 -03:00
CamilleLaVey 1ddad7c59a [vk, texture_cache] BGRA8 Depth/Stencil format convertions 2025-12-25 23:53:25 -03:00
CamilleLaVey 5cea80588b [vk, texture_cache] Preveting ARGB8 get misinterpretated with depth formats 2025-12-25 23:53:25 -03:00
CamilleLaVey df34184914 [vk] Adjusting Custom Border Color 2025-12-25 23:53:24 -03:00
CamilleLaVey c78ad84d1e [vk] Adjusting VIDS 2025-12-25 23:53:24 -03:00
CamilleLaVey 3fe0f1829a [vk] Changing conditions for Swapchain maintenance1 2025-12-25 23:53:24 -03:00
CamilleLaVey 63527a377b [vk] Ensure image view flags are resolved 2025-12-25 23:53:24 -03:00
CamilleLaVey c58d42a5e5 [vk] Aliging ExtendedDynamicState2 2025-12-25 23:53:24 -03:00
CamilleLaVey eb3b4a9242 [vk, spir-v] Conditioning creation of VK_EXT_Shader_Stencil_Export in SPIR-V 2025-12-25 23:53:24 -03:00
CamilleLaVey 03c9adf480 fixing building error. 2025-12-25 23:53:24 -03:00
CamilleLaVey 66e97f718d [vk, texture_cache, vendor] Adding path for hardware resolve on shader stencil export/ MSAA image blits 2025-12-25 23:53:23 -03:00
CamilleLaVey 7ba5a3d6a0 [vk] Return VK 1.3 as main target, treat VK 1.4 core features as extensions if driver supports it 2025-12-25 23:53:23 -03:00
CamilleLaVey 4c223fdd11 [vk] Ordering double cases specified and allocating them in the correct please on GetSuitability phase 2025-12-25 23:53:23 -03:00
CamilleLaVey b7fcb84749 Dammed macros. 2025-12-25 23:53:23 -03:00
CamilleLaVey 607dd6adac Fix building issues 2025-12-25 23:53:23 -03:00
CamilleLaVey 8663923709 [vk, qcom] VertexInputDynamicState ban removal 2025-12-25 23:53:23 -03:00
CamilleLaVey 273a0788be [vk] Bumping features to 1.4 2025-12-25 23:53:22 -03:00
CamilleLaVey 1cc6a3c5b3 [vk] Updated maintenance features 2025-12-25 23:53:22 -03:00
CamilleLaVey 2b059c5584 [vk, amd, qcom] Removed older driver workarounds 2025-12-25 23:53:22 -03:00
CamilleLaVey ba5bb52c11 [vk, spir-v] Adding decoration for NonWritable buffers if vertexPipelineStoresAndAtomics isn't available 2025-12-25 23:53:22 -03:00
CamilleLaVey a65552af38 [vk, buffer_cache] Aligning VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT logic 2025-12-25 23:53:22 -03:00
CamilleLaVey 50e85e232e [vk., vendor] Adding driver id flag in blacklist 2025-12-25 23:53:22 -03:00
CamilleLaVey 1bc297dc70 [Refactor, vk] DynamicState, ExtendedDynamicState and VertexInputDynamicState 2025-12-25 23:53:21 -03:00
Caio Oliveira d25f9501e8 Revert "[vk] attempt to continue even if unsuitable driver (#3087)"
This reverts commit 7a98ee4ead.
2025-12-25 23:53:21 -03:00
Caio Oliveira 8db7de42a4 Revert "[video_core] Fix inconsistency between EDS and VIDS settings (#3148)"
This reverts commit 7157d5167e.
2025-12-25 23:53:21 -03:00
135 changed files with 7882 additions and 2049 deletions
+2 -2
View File
@@ -174,8 +174,8 @@ if ((MSVC AND NOT (CMAKE_BUILD_TYPE MATCHES "Debug|RelWithDebInfo") OR ANDROID))
endif()
option(YUZU_USE_BUNDLED_SIRIT "Download bundled sirit" ${BUNDLED_SIRIT_DEFAULT})
# FreeBSD 15+ has libusb, versions below should disable it
cmake_dependent_option(ENABLE_LIBUSB "Enable the use of LibUSB" ON "WIN32 OR PLATFORM_LINUX OR PLATFORM_FREEBSD OR APPLE" OFF)
# Re-allow on FreeBSD once its on mainline ports
cmake_dependent_option(ENABLE_LIBUSB "Enable the use of LibUSB" ON "WIN32 OR PLATFORM_LINUX OR APPLE" OFF)
cmake_dependent_option(ENABLE_OPENGL "Enable OpenGL" ON "NOT WIN32 OR NOT ARCHITECTURE_arm64" OFF)
mark_as_advanced(FORCE ENABLE_OPENGL)
@@ -143,21 +143,8 @@ class ReleaseAdapter(
binding.containerDownloads.removeAllViews()
release.artifacts.forEach { artifact ->
val alreadyInstalled = try {
// Prefer fast check via ViewModel list; fallback to helper if needed
driverViewModel.driverData.any {
File(it.first).name.equals(artifact.name, ignoreCase = true)
} || GpuDriverHelper.isDriverZipInstalledByName(artifact.name)
} catch (_: Exception) {
false
}
val button = MaterialButton(binding.root.context).apply {
text = if (alreadyInstalled) {
context.getString(R.string.installed_label, artifact.name)
} else {
artifact.name
}
text = artifact.name
setTextAppearance(
com.google.android.material.R.style.TextAppearance_Material3_LabelLarge
)
@@ -167,7 +154,7 @@ class ReleaseAdapter(
com.google.android.material.R.color.m3_button_background_color_selector
)
)
setIconResource(if (alreadyInstalled) R.drawable.ic_check else R.drawable.ic_import)
setIconResource(R.drawable.ic_import)
iconTint = ColorStateList.valueOf(
MaterialColors.getColor(
this,
@@ -180,22 +167,7 @@ class ReleaseAdapter(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
isEnabled = !alreadyInstalled
setOnClickListener {
// Double-check just before starting (race-proof)
if (GpuDriverHelper.isDriverZipInstalledByName(artifact.name)) {
Toast.makeText(
context,
context.getString(R.string.driver_already_installed),
Toast.LENGTH_SHORT
).show()
// Update UI to reflect installed state
this.isEnabled = false
this.text = context.getString(R.string.installed_label, artifact.name)
this.setIconResource(R.drawable.ic_check)
return@setOnClickListener
}
val dialogBinding =
DialogProgressBinding.inflate(LayoutInflater.from(context))
dialogBinding.progressBar.isIndeterminate = true
@@ -261,10 +233,6 @@ class ReleaseAdapter(
driverViewModel.onDriverAdded(Pair(driverPath, driverData))
progressDialog.dismiss()
// Update button to installed state
this@apply.isEnabled = false
this@apply.text = context.getString(R.string.installed_label, artifact.name)
this@apply.setIconResource(R.drawable.ic_check)
Toast.makeText(
context,
context.getString(
@@ -14,6 +14,7 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
FASTMEM_EXCLUSIVES("cpuopt_fastmem_exclusives"),
CORE_SYNC_CORE_SPEED("sync_core_speed"),
RENDERER_USE_SPEED_LIMIT("use_speed_limit"),
USE_FAST_CPU_TIME("use_fast_cpu_time"),
USE_CUSTOM_CPU_TICKS("use_custom_cpu_ticks"),
SKIP_CPU_INNER_INVALIDATION("skip_cpu_inner_invalidation"),
CPUOPT_UNSAFE_HOST_MMU("cpuopt_unsafe_host_mmu"),
@@ -22,11 +23,11 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
RENDERER_USE_DISK_SHADER_CACHE("use_disk_shader_cache"),
RENDERER_FORCE_MAX_CLOCK("force_max_clock"),
RENDERER_ASYNCHRONOUS_SHADERS("use_asynchronous_shaders"),
RENDERER_FAST_GPU("use_fast_gpu_time"),
RENDERER_REACTIVE_FLUSHING("use_reactive_flushing"),
SYNC_MEMORY_OPERATIONS("sync_memory_operations"),
BUFFER_REORDER_DISABLE("disable_buffer_reorder"),
RENDERER_DEBUG("debug"),
RENDERER_PATCH_OLD_QCOM_DRIVERS("patch_old_qcom_drivers"),
RENDERER_VERTEX_INPUT_DYNAMIC_STATE("vertex_input_dynamic_state"),
RENDERER_PROVOKING_VERTEX("provoking_vertex"),
RENDERER_DESCRIPTOR_INDEXING("descriptor_indexing"),
@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -9,7 +6,8 @@ package org.yuzu.yuzu_emu.features.settings.model
import org.yuzu.yuzu_emu.utils.NativeConfig
enum class ByteSetting(override val key: String) : AbstractByteSetting {
AUDIO_VOLUME("volume"),;
AUDIO_VOLUME("volume"),
RENDERER_DYNA_STATE("dyna_state");
override fun getByte(needsGlobal: Boolean): Byte = NativeConfig.getByte(key, needsGlobal)
@@ -27,8 +27,6 @@ enum class IntSetting(override val key: String) : AbstractIntSetting {
RENDERER_SCREEN_LAYOUT("screen_layout"),
RENDERER_ASPECT_RATIO("aspect_ratio"),
RENDERER_OPTIMIZE_SPIRV_OUTPUT("optimize_spirv_output"),
RENDERER_DYNA_STATE("dyna_state"),
DMA_ACCURACY("dma_accuracy"),
AUDIO_OUTPUT_ENGINE("output_engine"),
MAX_ANISOTROPY("max_anisotropy"),
@@ -43,7 +41,7 @@ enum class IntSetting(override val key: String) : AbstractIntSetting {
SOC_OVERLAY_POSITION("soc_overlay_position"),
MEMORY_LAYOUT("memory_layout_mode"),
FSR_SHARPENING_SLIDER("fsr_sharpening_slider"),
RENDERER_SAMPLE_SHADING("sample_shading_fraction"),
RENDERER_SAMPLE_SHADING_FRACTION("sample_shading_fraction"),
FAST_CPU_TIME("fast_cpu_time"),
CPU_TICKS("cpu_ticks"),
FAST_GPU_TIME("fast_gpu_time"),
@@ -26,6 +26,7 @@ object Settings {
SECTION_INPUT_PLAYER_EIGHT,
SECTION_APP_SETTINGS(R.string.app_settings),
SECTION_DEBUG(R.string.preferences_debug),
SECTION_EDEN_VEIL(R.string.eden_veil),
SECTION_APPLETS(R.string.applets_menu);
}
@@ -132,7 +132,7 @@ abstract class SettingsItem(
)
put(
SingleChoiceSetting(
IntSetting.RENDERER_DYNA_STATE,
ByteSetting.RENDERER_DYNA_STATE,
titleId = R.string.dyna_state,
descriptionId = R.string.dyna_state_description,
choicesId = R.array.dynaStateEntries,
@@ -160,9 +160,16 @@ abstract class SettingsItem(
descriptionId = R.string.descriptor_indexing_description
)
)
put(
SwitchSetting(
BooleanSetting.RENDERER_SAMPLE_SHADING,
titleId = R.string.sample_shading,
descriptionId = R.string.sample_shading_description
)
)
put(
SliderSetting(
IntSetting.RENDERER_SAMPLE_SHADING,
IntSetting.RENDERER_SAMPLE_SHADING_FRACTION,
titleId = R.string.sample_shading_fraction,
descriptionId = R.string.sample_shading_fraction_description,
units = "%"
@@ -619,6 +626,13 @@ abstract class SettingsItem(
descriptionId = R.string.renderer_asynchronous_shaders_description
)
)
put(
SwitchSetting(
BooleanSetting.RENDERER_FAST_GPU,
titleId = R.string.use_fast_gpu_time,
descriptionId = R.string.use_fast_gpu_time_description
)
)
put(
SingleChoiceSetting(
IntSetting.FAST_GPU_TIME,
@@ -628,6 +642,13 @@ abstract class SettingsItem(
valuesId = R.array.gpuValues
)
)
put(
SwitchSetting(
BooleanSetting.USE_FAST_CPU_TIME,
titleId = R.string.use_fast_cpu_time,
descriptionId = R.string.use_fast_cpu_time_description
)
)
put(
SingleChoiceSetting(
IntSetting.FAST_CPU_TIME,
@@ -745,14 +766,6 @@ abstract class SettingsItem(
descriptionId = R.string.renderer_debug_description
)
)
// BCn texture patching debug override
put(
SwitchSetting(
BooleanSetting.RENDERER_PATCH_OLD_QCOM_DRIVERS,
titleId = R.string.patch_old_qcom_drivers,
descriptionId = R.string.patch_old_qcom_drivers_description
)
)
put(
SwitchSetting(
BooleanSetting.USE_AUTO_STUB,
@@ -107,6 +107,7 @@ class SettingsFragmentPresenter(
MenuTag.SECTION_INPUT_PLAYER_EIGHT -> addInputPlayer(sl, 7)
MenuTag.SECTION_APP_SETTINGS -> addThemeSettings(sl)
MenuTag.SECTION_DEBUG -> addDebugSettings(sl)
MenuTag.SECTION_EDEN_VEIL -> addEdenVeilSettings(sl)
MenuTag.SECTION_APPLETS -> addAppletSettings(sl)
}
settingsList = sl
@@ -178,6 +179,14 @@ class SettingsFragmentPresenter(
menuKey = MenuTag.SECTION_DEBUG
)
)
add(
SubmenuSetting(
titleId = R.string.eden_veil,
descriptionId = R.string.eden_veil_description,
iconId = R.drawable.ic_eden_veil,
menuKey = MenuTag.SECTION_EDEN_VEIL
)
)
add(
SubmenuSetting(
titleId = R.string.applets_menu,
@@ -208,61 +217,30 @@ class SettingsFragmentPresenter(
add(BooleanSetting.USE_CUSTOM_RTC.key)
add(LongSetting.CUSTOM_RTC.key)
add(HeaderSetting(R.string.cpu))
add(IntSetting.FAST_CPU_TIME.key)
add(BooleanSetting.USE_LRU_CACHE.key)
add(BooleanSetting.CORE_SYNC_CORE_SPEED.key)
add(IntSetting.MEMORY_LAYOUT.key)
add(BooleanSetting.USE_CUSTOM_CPU_TICKS.key)
add(IntSetting.CPU_TICKS.key)
add(HeaderSetting(R.string.network))
add(StringSetting.WEB_TOKEN.key)
add(StringSetting.WEB_USERNAME.key)
}
}
// TODO(crueter): sub-submenus?
private fun addGraphicsSettings(sl: ArrayList<SettingsItem>) {
sl.apply {
// add(IntSetting.RENDERER_NVDEC_EMULATION.key)
add(IntSetting.RENDERER_RESOLUTION.key)
add(IntSetting.RENDERER_VSYNC.key)
add(IntSetting.RENDERER_SHADER_BACKEND.key)
add(IntSetting.RENDERER_SCALING_FILTER.key)
add(IntSetting.FSR_SHARPENING_SLIDER.key)
add(IntSetting.RENDERER_ANTI_ALIASING.key)
add(IntSetting.RENDERER_OPTIMIZE_SPIRV_OUTPUT.key)
add(HeaderSetting(R.string.advanced))
add(HeaderSetting(R.string.backend))
add(IntSetting.RENDERER_ACCURACY.key)
add(IntSetting.DMA_ACCURACY.key)
add(IntSetting.MAX_ANISOTROPY.key)
add(IntSetting.RENDERER_VRAM_USAGE_MODE.key)
add(IntSetting.RENDERER_ASTC_DECODE_METHOD.key)
add(IntSetting.RENDERER_ASTC_RECOMPRESSION.key)
add(BooleanSetting.SYNC_MEMORY_OPERATIONS.key)
add(IntSetting.RENDERER_RESOLUTION.key)
add(BooleanSetting.RENDERER_USE_DISK_SHADER_CACHE.key)
add(BooleanSetting.RENDERER_FORCE_MAX_CLOCK.key)
add(BooleanSetting.RENDERER_ASYNCHRONOUS_SHADERS.key)
add(BooleanSetting.RENDERER_REACTIVE_FLUSHING.key)
add(HeaderSetting(R.string.hacks))
add(HeaderSetting(R.string.processing))
add(IntSetting.FAST_GPU_TIME.key)
add(BooleanSetting.SKIP_CPU_INNER_INVALIDATION.key)
add(BooleanSetting.RENDERER_ASYNCHRONOUS_SHADERS.key)
add(HeaderSetting(R.string.extensions))
add(IntSetting.RENDERER_DYNA_STATE.key)
add(BooleanSetting.RENDERER_VERTEX_INPUT_DYNAMIC_STATE.key)
add(BooleanSetting.RENDERER_PROVOKING_VERTEX.key)
add(BooleanSetting.RENDERER_DESCRIPTOR_INDEXING.key)
add(IntSetting.RENDERER_SAMPLE_SHADING.key)
add(IntSetting.RENDERER_VSYNC.key)
add(IntSetting.RENDERER_ANTI_ALIASING.key)
add(IntSetting.MAX_ANISOTROPY.key)
add(IntSetting.RENDERER_SCALING_FILTER.key)
add(IntSetting.FSR_SHARPENING_SLIDER.key)
add(HeaderSetting(R.string.display))
@@ -472,6 +450,42 @@ class SettingsFragmentPresenter(
}
}
private fun addEdenVeilSettings(sl: ArrayList<SettingsItem>) {
sl.apply {
add(HeaderSetting(R.string.veil_extensions))
add(ByteSetting.RENDERER_DYNA_STATE.key)
add(BooleanSetting.RENDERER_VERTEX_INPUT_DYNAMIC_STATE.key)
add(BooleanSetting.RENDERER_PROVOKING_VERTEX.key)
add(BooleanSetting.RENDERER_DESCRIPTOR_INDEXING.key)
add(BooleanSetting.RENDERER_SAMPLE_SHADING.key)
add(IntSetting.RENDERER_SAMPLE_SHADING_FRACTION.key)
add(HeaderSetting(R.string.veil_renderer))
add(IntSetting.DMA_ACCURACY.key)
add(BooleanSetting.BUFFER_REORDER_DISABLE.key)
add(BooleanSetting.RENDERER_FAST_GPU.key)
add(IntSetting.FAST_GPU_TIME.key)
add(IntSetting.RENDERER_SHADER_BACKEND.key)
add(IntSetting.RENDERER_NVDEC_EMULATION.key)
add(IntSetting.RENDERER_ASTC_DECODE_METHOD.key)
add(IntSetting.RENDERER_ASTC_RECOMPRESSION.key)
add(IntSetting.RENDERER_VRAM_USAGE_MODE.key)
add(IntSetting.RENDERER_OPTIMIZE_SPIRV_OUTPUT.key)
add(HeaderSetting(R.string.veil_misc))
add(BooleanSetting.USE_FAST_CPU_TIME.key)
add(IntSetting.FAST_CPU_TIME.key)
add(BooleanSetting.USE_CUSTOM_CPU_TICKS.key)
add(IntSetting.CPU_TICKS.key)
add(BooleanSetting.SKIP_CPU_INNER_INVALIDATION.key)
add(BooleanSetting.CPUOPT_UNSAFE_HOST_MMU.key)
add(BooleanSetting.USE_LRU_CACHE.key)
add(BooleanSetting.CORE_SYNC_CORE_SPEED.key)
add(BooleanSetting.SYNC_MEMORY_OPERATIONS.key)
add(IntSetting.MEMORY_LAYOUT.key)
}
}
private fun addAppletSettings(sl: ArrayList<SettingsItem>) {
sl.apply {
add(IntSetting.SWKBD_APPLET.key)
@@ -1145,26 +1159,17 @@ class SettingsFragmentPresenter(
private fun addDebugSettings(sl: ArrayList<SettingsItem>) {
sl.apply {
add(HeaderSetting(R.string.gpu))
add(IntSetting.RENDERER_BACKEND.key)
add(BooleanSetting.RENDERER_DEBUG.key)
add(BooleanSetting.RENDERER_PATCH_OLD_QCOM_DRIVERS.key)
add(BooleanSetting.BUFFER_REORDER_DISABLE.key)
add(HeaderSetting(R.string.cpu))
add(IntSetting.CPU_BACKEND.key)
add(IntSetting.CPU_ACCURACY.key)
add(BooleanSetting.USE_AUTO_STUB.key)
add(SettingsItem.FASTMEM_COMBINED)
add(BooleanSetting.CPUOPT_UNSAFE_HOST_MMU.key)
add(HeaderSetting(R.string.log))
add(BooleanSetting.DEBUG_FLUSH_BY_LINE.key)
add(HeaderSetting(R.string.general))
add(IntSetting.DEBUG_KNOBS.key)
}
}
@@ -186,10 +186,6 @@ class GamesFragment : Fragment() {
val currentViewType = getCurrentViewType()
val savedViewType = if (isLandscape || currentViewType != GameAdapter.VIEW_TYPE_CAROUSEL) currentViewType else GameAdapter.VIEW_TYPE_GRID
//This prevents Grid/List views from reusing scaled or otherwise modified ViewHolders left over from the carousel.
adapter = null
recycledViewPool.clear()
gameAdapter.setViewType(savedViewType)
currentFilter = preferences.getInt(PREF_SORT_TYPE, View.NO_ID)
@@ -238,18 +238,4 @@ object GpuDriverHelper {
driverStorageDirectory.mkdirs()
}
}
/**
* Checks if a driver zip with the given filename is already present and valid in the
* internal driver storage directory. Validation requires a readable meta.json with a name.
*/
fun isDriverZipInstalledByName(fileName: String): Boolean {
// Normalize separators in case upstream sent a path
val baseName = fileName.substringAfterLast('/')
.substringAfterLast('\\')
val candidate = File("$driverStoragePath$baseName")
if (!candidate.exists() || candidate.length() == 0L) return false
val metadata = getMetadataFromZip(candidate)
return metadata.name != null
}
}
@@ -1,6 +1,9 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
package org.yuzu.yuzu_emu.ui
import android.content.Context
@@ -52,24 +55,6 @@ class CarouselRecyclerView @JvmOverloads constructor(
private val preferences =
PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
private val carouselAdapterObserver = object : RecyclerView.AdapterDataObserver() {
override fun onChanged() {
if (!pendingScrollAfterReload) return
doOnNextLayout {
refreshView()
pendingScrollAfterReload = false
}
}
}
private val isCarouselMode: Boolean
get() {
val lm = layoutManager as? LinearLayoutManager
return lm != null &&
lm.orientation == RecyclerView.HORIZONTAL &&
lm !is androidx.recyclerview.widget.GridLayoutManager
}
var flingMultiplier: Float = 1f
var pendingScrollAfterReload: Boolean = false
@@ -85,18 +70,6 @@ class CarouselRecyclerView @JvmOverloads constructor(
setChildrenDrawingOrderEnabled(true)
}
override fun setAdapter(adapter: Adapter<*>?) {
val oldAdapter = this.adapter as? GameAdapter
if (oldAdapter !== adapter) {
oldAdapter?.unregisterAdapterDataObserver(carouselAdapterObserver)
}
super.setAdapter(adapter)
(adapter as? GameAdapter)?.registerAdapterDataObserver(carouselAdapterObserver)
}
private fun calculateCenter(width: Int, paddingStart: Int, paddingEnd: Int): Int {
return paddingStart + (width - paddingStart - paddingEnd) / 2
}
@@ -106,14 +79,14 @@ class CarouselRecyclerView @JvmOverloads constructor(
}
private fun getLayoutManagerCenter(layoutManager: RecyclerView.LayoutManager): Int {
if (isCarouselMode) {
return calculateCenter(
return if (layoutManager is LinearLayoutManager) {
calculateCenter(
layoutManager.width,
layoutManager.paddingStart,
layoutManager.paddingEnd
)
} else {
return width / 2
width / 2
}
}
@@ -122,8 +95,6 @@ class CarouselRecyclerView @JvmOverloads constructor(
}
fun restoreScrollState(position: Int = 0, attempts: Int = 0) {
if (!isCarouselMode) return
val lm = layoutManager as? LinearLayoutManager ?: return
if (lm.findLastVisibleItemPosition() == RecyclerView.NO_POSITION && attempts < 10) {
post { restoreScrollState(position, attempts + 1) }
@@ -133,10 +104,6 @@ class CarouselRecyclerView @JvmOverloads constructor(
}
fun getClosestChildPosition(fullRange: Boolean = false): Int {
if (!isCarouselMode) {
return RecyclerView.NO_POSITION
}
val lm = layoutManager as? LinearLayoutManager ?: return RecyclerView.NO_POSITION
var minDistance = Int.MAX_VALUE
var closestPosition = RecyclerView.NO_POSITION
@@ -236,22 +203,15 @@ class CarouselRecyclerView @JvmOverloads constructor(
}
fun refreshView() {
if (isCarouselMode) {
updateChildScalesAndAlpha()
focusCenteredCard()
}
updateChildScalesAndAlpha()
focusCenteredCard()
}
fun notifyInsetsReady(newBottomInset: Int) {
if (bottomInset != newBottomInset) {
bottomInset = newBottomInset
}
if (isCarouselMode) {
setupCarousel(true)
} else {
setupCarousel(false)
}
setupCarousel(true)
}
fun notifyLaidOut(fallBackBottomInset: Int) {
@@ -261,10 +221,7 @@ class CarouselRecyclerView @JvmOverloads constructor(
if (gameAdapter.cardSize != newCardSize) {
gameAdapter.setCardSize(newCardSize)
}
if (isCarouselMode) {
setupCarousel(true)
}
setupCarousel(true)
}
fun cardSize(bottomInset: Int): Int {
@@ -295,6 +252,17 @@ class CarouselRecyclerView @JvmOverloads constructor(
internalFlingMultiplier
).coerceIn(1f, 5f)
gameAdapter .registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
override fun onChanged() {
if (pendingScrollAfterReload) {
doOnNextLayout {
refreshView()
pendingScrollAfterReload = false
}
}
}
})
// Detach SnapHelper during setup
pagerSnapHelper?.attachToRecyclerView(null)
@@ -353,27 +321,22 @@ class CarouselRecyclerView @JvmOverloads constructor(
override fun onScrollStateChanged(state: Int) {
super.onScrollStateChanged(state)
if (state == RecyclerView.SCROLL_STATE_IDLE && isCarouselMode) {
if (state == RecyclerView.SCROLL_STATE_IDLE) {
focusCenteredCard()
}
}
override fun scrollToPosition(position: Int) {
if (isCarouselMode) {
(layoutManager as? LinearLayoutManager)?.scrollToPositionWithOffset(position, overlapPx)
doOnNextLayout {
refreshView()
}
} else {
super.scrollToPosition(position)
(layoutManager as? LinearLayoutManager)?.scrollToPositionWithOffset(position, overlapPx)
doOnNextLayout {
refreshView()
}
}
private var lastFocusSearchTime: Long = 0
override fun focusSearch(focused: View, direction: Int): View? {
if (!isCarouselMode) {
return super.focusSearch(focused, direction)
}
if (layoutManager !is LinearLayoutManager) return super.focusSearch(focused, direction)
val vh = findContainingViewHolder(focused) ?: return super.focusSearch(focused, direction)
val itemCount = adapter?.itemCount ?: return super.focusSearch(focused, direction)
val position = vh.bindingAdapterPosition
@@ -408,8 +371,6 @@ class CarouselRecyclerView @JvmOverloads constructor(
focused
}
}
// Prevent focus from escaping to external UI elements when forced snapping was removed
View.FOCUS_DOWN -> focused
else -> super.focusSearch(focused, direction)
}
}
@@ -473,7 +434,7 @@ class CarouselRecyclerView @JvmOverloads constructor(
// NEEDED: fixes center snapping, but introduces ghost movement
override fun findSnapView(layoutManager: RecyclerView.LayoutManager): View? {
if (!isCarouselMode) return null
if (layoutManager !is LinearLayoutManager) return null
return layoutManager.findViewByPosition(getClosestChildPosition())
}
@@ -482,10 +443,12 @@ class CarouselRecyclerView @JvmOverloads constructor(
layoutManager: RecyclerView.LayoutManager,
targetView: View
): IntArray? {
if (!isCarouselMode) {
return super.calculateDistanceToFinalSnap(layoutManager, targetView)
if (layoutManager !is LinearLayoutManager) {
return super.calculateDistanceToFinalSnap(
layoutManager,
targetView
)
}
val out = IntArray(2)
out[0] = getChildDistanceToCenter(targetView).toInt()
out[1] = 0
@@ -498,11 +461,8 @@ class CarouselRecyclerView @JvmOverloads constructor(
velocityX: Int,
velocityY: Int
): Int {
if (!isCarouselMode) return RecyclerView.NO_POSITION
if (layoutManager !is LinearLayoutManager) return RecyclerView.NO_POSITION
val closestPosition = this@CarouselRecyclerView.getClosestChildPosition()
if (closestPosition == RecyclerView.NO_POSITION) return RecyclerView.NO_POSITION
val internalMaxFling = resources.getInteger(R.integer.carousel_max_fling_count)
val maxFling = preferences.getInt(CAROUSEL_MAX_FLING_COUNT, internalMaxFling).coerceIn(
1,
@@ -83,7 +83,10 @@
<string name="show_fw_version_description">عرض إصدار الفيرموير المثبت</string>
<!-- Eden\'s Veil -->
<string name="eden_veil">ميزات Eden</string>
<string name="eden_veil_description">إعدادات تجريبية لتحسين الأداء والقدرة. قد تتسبب هذه الإعدادات في ظهور شاشات سوداء أو مشكلات أخرى في اللعبة.</string>
<string name="veil_extensions">ملحقات وحدة معالجة الرسومات</string>
<string name="dyna_state">الحالة الديناميكية الموسعة</string>
<string name="dyna_state_description">يتحكم في عدد المميزات التي يمكن استخدامها في الحالة الديناميكية الموسعة. الأرقام الأعلى تسمح بميزات أكثر ويمكن أن تعزز الأداء، ولكن قد تسبب مشكلات مع بعض السائقين والبائعين. قد تختلف القيمة الافتراضية بحسب نظامك وقدرات الأجهزة. يمكن تغيير هذه القيمة حتى يتم تحقيق الاستقرار وجودة الصورة الأفضل.</string>
<string name="disabled">معطل</string>
@@ -93,18 +96,24 @@
<string name="provoking_vertex_description">يحسن الإضاءة ومعالجة الرؤوس في بعض الألعاب. مدعوم فقط على وحدات معالجة الرسومات Vulkan 1.0+.</string>
<string name="descriptor_indexing">فهرسة الوصف</string>
<string name="descriptor_indexing_description">يحسن معالجة النسيج والمخزن المؤقت، بالإضافة إلى طبقة الترجمة Maxwell. مدعوم من بعض وحدات معالجة الرسومات Vulkan 1.1 وجميع وحدات معالجة الرسومات Vulkan 1.2+.</string>
<string name="sample_shading">تظليل العينة</string>
<string name="sample_shading_description">يسمح لتظلل الأجزاء بتنفيذ كل عينة في جزء متعدد العينات بدلاً من مرة واحدة لكل جزء. يحسن جودة الرسومات على حساب بعض الأداء. لا تدعم هذه الإضافة سوى أجهزة Vulkan 1.1+ فقط.</string>
<string name="sample_shading_fraction">نسبة التظليل النموذجية</string>
<string name="sample_shading_fraction_description">كثافة تمرير تظليل العينة. تؤدي القيم الأعلى إلى تحسين الجودة بشكل أكبر، ولكنها تقلل أيضًا من الأداء إلى حد كبير.</string>
<string name="veil_renderer">العارض</string>
<string name="sync_memory_operations">مزامنة عمليات الذاكرة</string>
<string name="sync_memory_operations_description">يضمن اتساق البيانات بين عمليات الحوسبة والذاكرة. هذا الخيار قد يحل المشكلات في بعض الألعاب، ولكن قد يقلل الأداء في بعض الحالات. يبدو أن الألعاب التي تستخدم Unreal Engine 4 هي الأكثر تأثرًا.</string>
<string name="buffer_reorder_disable">تعطيل إعادة ترتيب المخزن المؤقت</string>
<string name="buffer_reorder_disable_description">عند تحديده، يتم تعطيل إعادة ترتيب تحميلات الذاكرة المعينة، مما يسمح بربط التحميلات بعمليات سحب محددة. قد يؤدي ذلك إلى انخفاض الأداء في بعض الحالات.</string>
<string name="veil_misc">وحدة المعالجة المركزية والذاكرة</string>
<string name="use_sync_core">مزامنة سرعة النواة</string>
<string name="use_sync_core_description">قم بمزامنة سرعة النواة مع النسبة المئوية للسرعة القصوى لتحسين الأداء دون تغيير السرعة الفعلية للعبة.</string>
<string name="use_lru_cache">تمكين ذاكرة التخزين المؤقتة LRU</string>
<string name="use_lru_cache_description">قم بتمكين أو تعطيل ذاكرة التخزين المؤقتة الأقل استخدامًا (LRU)، مما يزيد من الأداء عن طريق توفير استخدام معالج وحدة المعالجة المركزية. قد تواجه بعض الألعاب مشكلات مع هذا الإعداد، لذا قم بتعطيله إذا لم يتم تشغيل اللعبة أو تعطلت بشكل عشوائي.</string>
<string name="use_fast_cpu_time">وقت وحدة المعالجة المركزية السريع</string>
<string name="use_fast_cpu_time_description">يجبر وحدة المعالجة المركزية المحاكاة على العمل بسرعة أعلى، مما يقلل من بعض محددات معدل الإطارات. هذا الخيار غير مستقر وقد يسبب مشاكل، وقد يرى المستخدمون بأجهزة أضعف انخفاضًا في الأداء.</string>
<string name="custom_cpu_ticks">تخصيص دورات المعالج</string>
<string name="custom_cpu_ticks_description">قم بتعيين قيمة مخصصة لدورات المعالج. القيم الأعلى يمكن أن تزيد من الأداء، ولكنها قد تتسبب أيضًا في تجميد اللعبة. يوصى باستخدام نطاق 77-21000.</string>
<string name="cpu_ticks">دورات</string>
@@ -471,7 +480,9 @@
<string name="network">الشبكة</string>
<!-- Graphics settings strings -->
<string name="backend">الخلفية</string>
<string name="display">الشاشة</string>
<string name="processing">تأثيرات بعد المعالجة</string>
<string name="renderer_accuracy">مستوى الدقة</string>
<string name="renderer_resolution">الدقة (الإرساء/محمول)</string>
@@ -488,6 +499,8 @@
<string name="renderer_optimize_spirv_output_description">يعمل على تحسين أداء برامج التظليل المجمعة لتحسين كفاءة وحدة معالجة الرسومات، ولكنه قد يؤدي إلى زيادة وقت التحميل وإبطاء السرعة في البداية.</string>
<string name="renderer_asynchronous_shaders">استخدم تظليل غير متزامن</string>
<string name="renderer_asynchronous_shaders_description">يقوم بتجميع التظليل بشكل غير متزامن. قد يقلل ذلك من التقطعات ولكنه قد يؤدي أيضًا إلى حدوث أخطاء.</string>
<string name="use_fast_gpu_time">استخدم وقت المعالج الرسومي السريع</string>
<string name="use_fast_gpu_time_description">يجبر معظم الألعاب على التشغيل بأعلى دقة أصلية لها. هذا الخيار غير آمن وقد يتسبب في مشاكل.</string>
<string name="fast_gpu_time">عامل زيادة تردد وحدة معالجة الرسومات</string>
<string name="fast_gpu_time_description">استخدم 128 لأقصى أداء و512 لأقصى دقة رسومية.</string>
<string name="renderer_reactive_flushing">استخدم التنظيف التفاعلي</string>
@@ -865,8 +878,9 @@
<string name="clock_fast">سريع (2000MHz)</string>
<!-- GPU overclock factors -->
<string name="fast_gpu_medium">متوسط (256)</string>
<string name="fast_gpu_high">مرتفع (512)</string>
<string name="gpu_low">منخفض (128)</string>
<string name="gpu_medium">متوسط (256)</string>
<string name="gpu_high">مرتفع (512)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">مئوية</string>
@@ -59,7 +59,10 @@
<string name="show_fw_version_description">وەشانی فریموێری نەصبکراو پیشان بدە</string>
<!-- Eden\'s Veil -->
<string name="eden_veil">حجاب عدن</string>
<string name="eden_veil_description">ڕێکخستنە تاقیکارییەکان بۆ باشترکردنی کارایی و توانا. ئەم ڕێکخستنانە لەوانەیە ببێتە هۆی شاشە ڕەشەکان یان کێشەیتری یاری.</string>
<string name="veil_extensions">پاشکۆکانی GPU</string>
<string name="dyna_state">الحالة الديناميكية الممتدة</string>
<string name="dyna_state_description">کۆntrolی ژمارەی تایبەتمەندییەکان دەکات کە دەتوانرێت لە دۆخی هایپرDynamic بەکاربهێنرێت. ژمارەی زیاتر ڕێگە بە تایبەتمەندییەکی زیاتر دەدات و دەتوانێت کارایی باشتر بکات، بەڵام لەوانەیە کێشە دروست بکات لەگەڵ هەندێک لە درایڤەرەکان و فرۆشەکان. نرخی گریمانەیی دەگۆڕێت بەپێی سیستەم و تواناکانی hardwareی تۆ. دەتوانیت ئەم نرخە بگۆڕیت تا جێگیری و جێیەکی بینینی باشتر دەستبکەوێت.</string>
<string name="disabled">ناچالاک</string>
@@ -67,18 +70,24 @@
<string name="provoking_vertex_description">يحسن الإضاءة ومعالجة الرؤوس في بعض الألعاب. مدعوم فقط على وحدات معالجة الرسومات التي تدعم فولكان 1.0+.</string>
<string name="descriptor_indexing">فهرسة الواصفات</string>
<string name="descriptor_indexing_description">يحسن معالجة القوام والمخازن المؤقتة، بالإضافة إلى طبقة ترجمة ماكسويل. مدعوم من قبل بعض وحدات معالجة الرسومات التي تدعم فولكان 1.1 وجميع وحدات معالجة الرسومات التي تدعم فولكان 1.2+.</string>
<string name="sample_shading">سێبەندی نمونە</string>
<string name="sample_shading_description">ڕێگە بە شێدەری پارچە دەدات کە بۆ هەر نمونەیەک لە پارچەی فرە نمونەیدا جێبەجێ بکات لە جیاتی جێبەجێکردنی بۆ هەر پارچەیەک. جۆرایی گرافیک باشتر دەکات بە بەهای هەندێک لە کارایی. تەنها ئامێرەکانی Vulkan 1.1+ پشتگیری ئەم درێژکراوە دەکەن.</string>
<string name="sample_shading_fraction">پێکهاتەی سێبەرکردنی نموونە</string>
<string name="sample_shading_fraction_description">چڕی تێپەڕاندنی سێبەرکردنی نموونە. بەهای زیاتر کوالێتی باشتر دەکات بەڵام کارایی زیاتر کەم دەکاتەوە.</string>
<string name="veil_renderer">رێندرەر</string>
<string name="sync_memory_operations">هاوبەشیی کردارەکانی بیرگە</string>
<string name="sync_memory_operations_description">دڵنیایی داتا لە نێوان کردارەکانی کۆمپیوتەر و بیرگە. ئەم هەڵبژاردە کێشەکان لە هەندێک یاری چارەسەر دەکات، بەڵام لە هەندێک حاڵەت کارایی کەم دەکاتەوە. وا دیارە یارییەکانی Unreal Engine 4 زۆرترین کاریگەریان هەیە.</string>
<string name="buffer_reorder_disable">ڕێکخستنەوەی بافر ناچالاک بکە</string>
<string name="buffer_reorder_disable_description">کە دیاریکرا، ڕێکخستنەوەی بارکردنی بیرگەی نەخشەکراو ناچالاک دەکات کە ڕێگەدەدات بارکردنەکان بە ڕەسمی دیاریکراو ببەسترێت. لە هەندێک حاڵەتدا کاراییمان دەکاتەوە.</string>
<string name="veil_misc">CPU و بیرگە</string>
<string name="use_sync_core">مزامنة سرعة النواة</string>
<string name="use_sync_core_description">خێرایی تیکەکانی ناوک ڕێکبخە لەگەڵ ڕێژەی خێرایی بەرزترین بۆ باشترکردنی کارایی بەبێ گۆڕینی خێرایی ڕاستەقینەی یارییەکە.</string>
<string name="use_lru_cache">تمكين ذاكرة التخزين المؤقت LRU</string>
<string name="use_lru_cache_description">چالاک یان ناچالاککردنی کاشەی LRU، کارایی باشتر دەکات بە هەڵگرتنی بەکارهێنانی پرۆسەی CPU. هەندێک یاری کێشەی لەگەڵ هەیە، بەتایبەتی TotK 1.2.1، بۆیە بیخەوێنە ئەگەر یاریەکە نەگەڕێت یان بە هەڕەمەکی بشکێت.</string>
<string name="use_fast_cpu_time">کاتی CPU خێرا</string>
<string name="use_fast_cpu_time_description">CPUی شبیهسازیکراو بە زۆرکردنی کاتژمێر وادەکات بە خێرایی زیاتر کاربکات، ئەمەش هەندێک لە سنووردارکەرانی FPS کەم دەکاتەوە. ئەم هەڵبژاردە هەڵە و لەوانەیە کێشە دروست بکات، و لەوانەیە کەسی بە CPUی بێهێز کارایی کەمتر ببینێت.</string>
<string name="custom_cpu_ticks">تیکی CPU هەڵبژێردراو</string>
<string name="custom_cpu_ticks_description">بەهای هەڵبژێردراوی تیکی CPU دابنێ. بەهای زیاتر دەتوانن کارایی زیاد بکەن، بەڵام لەوانەیە بووەستانی یاریش دروست بکەن. ئامۆژگاری بە نێوان 77-21000 دەکرێت.</string>
<string name="cpu_ticks">تیک</string>
@@ -364,7 +373,9 @@
<string name="network">تۆڕ</string>
<!-- Graphics settings strings -->
<string name="backend">پاشبنەما</string>
<string name="display">پیشاندان</string>
<string name="processing">پاشپڕۆسەکردن</string>
<string name="renderer_accuracy">ئاستی وردبینی</string>
<string name="renderer_resolution">ڕوونی (دۆخی دەستی/دۆخی دۆک)</string>
@@ -381,6 +392,8 @@
<string name="renderer_optimize_spirv_output_description">شێیدەرە کۆمپایلکراوەکان باش دەکات بۆ باشترکردنی کارایی GPU.</string>
<string name="renderer_asynchronous_shaders">بەکارهێنانی سێبەری ناهاوسەنگ</string>
<string name="renderer_asynchronous_shaders_description">کۆمپایلکردنی شادەرەکان بەشێوەی ناڕێک. ئەمە ڕەنگە کەمکردنەوەی ستەتەر بکات بەڵام لەوانەیە هەڵەش دروست بکات.</string>
<string name="use_fast_gpu_time">بەکارهێنانی کاتی GPU خێرا</string>
<string name="use_fast_gpu_time_description">زۆربەی یارییەکان بەرزی ڕەزولوشنی ڕەسەنی خۆیان دادەمەزرێنێت. ئەم هەڵبژاردە هەڵەیە و لەوانەیە کێشە دروست بکات.</string>
<string name="fast_gpu_time">فاکتۆری خێراکردنی GPU</string>
<string name="fast_gpu_time_description">128 بەکاربهێنە بۆ باشترین کارایی و 512 بۆ باشترین وردی گرافیک.</string>
<string name="renderer_reactive_flushing">بەکارهێنانی بەرپێچدەرەوە</string>
@@ -594,8 +607,9 @@
<string name="clock_fast">خێرا (2000MHz)</string>
<!-- GPU overclock factors -->
<string name="fast_gpu_medium">ناوەند (256)</string>
<string name="fast_gpu_high">بەرز (512)</string>
<string name="gpu_low">نزم (128)</string>
<string name="gpu_medium">ناوەند (256)</string>
<string name="gpu_high">بەرز (512)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">سیلیزی</string>
@@ -59,7 +59,10 @@
<string name="show_fw_version_description">Zobrazí nainstalovanou verzi firmwaru</string>
<!-- Eden\'s Veil -->
<string name="eden_veil">Edenův závoj</string>
<string name="eden_veil_description">Experimentální nastavení pro zlepšení výkonu a schopností. Tato nastavení mohou způsobit černé obrazovky nebo další herní problémy.</string>
<string name="veil_extensions">Rozšíření GPU</string>
<string name="dyna_state">Rozšířený dynamický stav</string>
<string name="dyna_state_description">Ovládá počet funkcí, které lze použít v rozšířeném dynamickém stavu. Vyšší hodnoty umožňují více funkcí a mohou zvýšit výkon, ale mohou způsobit problémy s některými ovladači a výrobci. Výchozí hodnota se může lišit v závislosti na vašem systému a hardwarových schopnostech. Tuto hodnotu lze měnit, dokud nedosáhnete stability a lepší vizuální kvality.</string>
<string name="disabled">Vypnuto</string>
@@ -67,18 +70,24 @@
<string name="provoking_vertex_description">Zlepšuje osvětlení a zpracování vertexů v některých hrách. Podporováno pouze na GPU s Vulkan 1.0+.</string>
<string name="descriptor_indexing">Indexování deskriptorů</string>
<string name="descriptor_indexing_description">Zlepšuje zpracování textur a bufferů, stejně jako Maxwell překladovou vrstvu. Podporováno některými GPU s Vulkan 1.1 a všemi GPU s Vulkan 1.2+.</string>
<string name="sample_shading">Vzorkovací stínování</string>
<string name="sample_shading_description">Umožňuje fragment shaderu provádět výpočty pro každý vzorek ve fragmentu s více vzorky namísto jednou pro fragment. Zlepšuje kvalitu grafiky na úkor výkonu. Tuto funkci podporují pouze zařízení s Vulkan 1.1+.</string>
<string name="sample_shading_fraction">Podíl stínování vzorku</string>
<string name="sample_shading_fraction_description">Intenzita průchodu stínování vzorku. Vyšší hodnoty zlepšují kvalitu, ale také výrazněji snižují výkon.</string>
<string name="veil_renderer">Renderer</string>
<string name="sync_memory_operations">Synchronizace paměťových operací</string>
<string name="sync_memory_operations_description">Zajišťuje konzistenci dat mezi výpočetními a paměťovými operacemi. Tato volba by měla opravit problémy v některých hrách, ale může v některých případech snížit výkon. Nejvíce postižené se zdají být hry s Unreal Engine 4.</string>
<string name="buffer_reorder_disable">Zakázat přeřazování vyrovnávací paměti</string>
<string name="buffer_reorder_disable_description">Při zaškrtnutí zakáže přeřazování nahrání mapované paměti, což umožňuje spojit nahrání s konkrétními vykresleními. V některých případech může snížit výkon.</string>
<string name="veil_misc">CPU a paměť</string>
<string name="use_sync_core">Synchronizovat rychlost jádra</string>
<string name="use_sync_core_description">Synchronizuje rychlost jádra s maximálním procentem rychlosti, aby se zlepšil výkon bez změny skutečné rychlosti hry.</string>
<string name="use_lru_cache">Povolit LRU mezipaměť</string>
<string name="use_lru_cache_description">Povolte nebo zakažte mezipaměť LRU, čímž zvýšíte výkon snížením využití procesoru CPU. Některé hry s ní mají problémy, zejména TotK 1.2.1, takže ji deaktivujte, pokud hra neběží nebo náhodně padá.</string>
<string name="use_fast_cpu_time">Rychlý čas CPU</string>
<string name="use_fast_cpu_time_description">Nutí emulované CPU běžet na vyšší frekvenci, čímž snižuje některé limity FPS. Tato volba je nestabilní a může způsobit problémy a slabší CPU mohou mít snížený výkon.</string>
<string name="custom_cpu_ticks">Vlastní CPU takty</string>
<string name="custom_cpu_ticks_description">Nastavte vlastní hodnotu CPU taktů. Vyšší hodnoty mohou zvýšit výkon, ale mohou také způsobit zamrznutí hry. Doporučuje se rozsah 7721000.</string>
<string name="cpu_ticks">Takty</string>
@@ -352,7 +361,9 @@
<string name="network">Síť</string>
<!-- Graphics settings strings -->
<string name="backend">Backend</string>
<string name="display">Zobrazení</string>
<string name="processing">Postprocesing</string>
<string name="renderer_accuracy">Úroveň přesnosti</string>
<string name="renderer_resolution">Rozlišení (Handheld/Docked)</string>
@@ -369,6 +380,8 @@
<string name="renderer_optimize_spirv_output_description">Optimalizuje zkompilovaný shader pro zvýšení efektivity GPU.</string>
<string name="renderer_asynchronous_shaders">Asynchronní shadery</string>
<string name="renderer_asynchronous_shaders_description">Kompiluje stínovače asynchronně. Může to snížit trhání, ale také způsobit grafické chyby.</string>
<string name="use_fast_gpu_time">Použít rychlý čas GPU</string>
<string name="use_fast_gpu_time_description">Nutí většinu her běžet v jejich nativním rozlišení. Tato volba je nestabilní a může způsobovat problémy.</string>
<string name="fast_gpu_time">Faktor přetaktování GPU</string>
<string name="fast_gpu_time_description">Použijte 128 pro maximální výkon a 512 pro maximální věrnost grafiky.</string>
<string name="renderer_reactive_flushing">Reaktivní flushing</string>
@@ -584,8 +597,9 @@
<string name="clock_fast">Rychlé (2000MHz)</string>
<!-- GPU overclock factors -->
<string name="fast_gpu_medium">Střední (256)</string>
<string name="fast_gpu_high">Vysoké (512)</string>
<string name="gpu_low">Nízké (128)</string>
<string name="gpu_medium">Střední (256)</string>
<string name="gpu_high">Vysoké (512)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">Celsia</string>
@@ -67,7 +67,10 @@
<string name="show_fw_version_description">Zeigt die installierte Firmware-Version an</string>
<!-- Eden\'s Veil -->
<string name="eden_veil">Edens Schleier</string>
<string name="eden_veil_description">Experimentelle Einstellungen zur Verbesserung der Leistung und Funktionalität. Diese Einstellungen können schwarze Bildschirme oder andere Spielprobleme verursachen.</string>
<string name="veil_extensions">GPU-Erweiterungen</string>
<string name="dyna_state">Erweiterter dynamischer Status</string>
<string name="dyna_state_description">Steuert die Anzahl der Funktionen, die im Erweiterten Dynamischen Zustand verwendet werden können. Höhere Werte ermöglichen mehr Funktionen und können die Leistung steigern, können jedoch bei einigen Treibern und Herstellern zu Problemen führen. Der Standardwert kann je nach System und Hardwarefähigkeiten variieren. Dieser Wert kann geändert werden, bis Stabilität und eine bessere visuelle Qualität erreicht sind.</string>
<string name="disabled">Deaktiviert</string>
@@ -75,18 +78,24 @@
<string name="provoking_vertex_description">Verbessert die Beleuchtung und die Vertex-Verarbeitung in einigen Spielen. Wird nur von GPUs mit Vulkan 1.0+ unterstützt.</string>
<string name="descriptor_indexing">Deskriptor-Indizierung</string>
<string name="descriptor_indexing_description">Verbessert die Textur- und Puffer-Verarbeitung sowie die Maxwell-Übersetzungsschicht. Wird von einigen Vulkan 1.1-GPUs und allen Vulkan 1.2+-GPUs unterstützt.</string>
<string name="sample_shading">Sample Shading</string>
<string name="sample_shading_description">Ermöglicht dem Fragment-Shader, pro Sample in einem mehrfach gesampleten Fragment ausgeführt zu werden, anstatt einmal pro Fragment. Verbessert die Grafikqualität auf Kosten der Leistung. Nur Vulkan 1.1+-Geräte unterstützen diese Erweiterung.</string>
<string name="sample_shading_fraction">Sample-Shading-Anteil</string>
<string name="sample_shading_fraction_description">Die Intensität des Sample-Shading-Durchgangs. Höhere Werte verbessern die Qualität stärker, beeinträchtigen aber auch die Leistung stärker.</string>
<string name="veil_renderer">Renderer</string>
<string name="sync_memory_operations">Speicheroperationen synchronisieren</string>
<string name="sync_memory_operations_description">Stellt die Datenkonsistenz zwischen Compute- und Speicheroperationen sicher. Diese Option sollte Probleme in einigen Spielen beheben, kann aber in einigen Fällen die Leistung verringern. Spiele mit Unreal Engine 4 scheinen am stärksten betroffen zu sein.</string>
<string name="buffer_reorder_disable">Puffer-Neuanordnung deaktivieren</string>
<string name="buffer_reorder_disable_description">Wenn aktiviert, wird die Neuanordnung von gemappten Speicher-Uploads deaktiviert, was die Zuordnung von Uploads zu bestimmten Zeichenvorgängen ermöglicht. Kann in einigen Fällen die Leistung verringern.</string>
<string name="veil_misc">CPU und Speicher</string>
<string name="use_sync_core">Kern-Geschwindigkeit synchronisieren</string>
<string name="use_sync_core_description">Synchronisiert die Taktrate des Kerns mit der maximalen Geschwindigkeit, um die Leistung zu verbessern, ohne die tatsächliche Spielgeschwindigkeit zu verändern.</string>
<string name="use_lru_cache">LRU-Cache aktivieren</string>
<string name="use_lru_cache_description">Aktivieren oder deaktivieren Sie den LRU-Cache, um die Leistung durch Einsparung von CPU-Prozessorauslastung zu verbessern. Einige Spiele haben Probleme damit, insbesondere TotK 1.2.1, deaktivieren Sie es also, wenn das Spiel nicht startet oder zufällig abstürzt.</string>
<string name="use_fast_cpu_time">Schnelle CPU-Zeit</string>
<string name="use_fast_cpu_time_description">Zwingt die emulierte CPU, mit höherer Taktrate zu laufen, wodurch bestimmte FPS-Begrenzungen reduziert werden. Diese Option ist unsauber und kann Probleme verursachen, und schwächere CPUs können eine geringere Leistung aufweisen.</string>
<string name="custom_cpu_ticks">Benutzerdefinierte CPU-Ticks</string>
<string name="custom_cpu_ticks_description">Legen Sie einen benutzerdefinierten Wert für CPU-Ticks fest. Höhere Werte können die Leistung steigern, aber auch zum Einfrieren des Spiels führen. Ein Bereich von 7721000 wird empfohlen.</string>
<string name="cpu_ticks">Ticks</string>
@@ -408,7 +417,9 @@ Wird der Handheld-Modus verwendet, verringert es die Auflösung und erhöht die
<string name="network">Netzwerk</string>
<!-- Graphics settings strings -->
<string name="backend">Backend</string>
<string name="display">Anzeige</string>
<string name="processing">Nachbearbeitung</string>
<string name="renderer_accuracy">Genauigkeitsstufe</string>
<string name="renderer_resolution">Auflösung (Handheld/Gedockt)</string>
@@ -425,6 +436,8 @@ Wird der Handheld-Modus verwendet, verringert es die Auflösung und erhöht die
<string name="renderer_optimize_spirv_output_description">Optimiert den kompilierten Shader, um die GPU-Effizienz zu verbessern.</string>
<string name="renderer_asynchronous_shaders">Asynchrone Shader</string>
<string name="renderer_asynchronous_shaders_description">Kompiliert Shader asynchron. Dies kann Ruckler reduzieren, aber auch Grafikfehler verursachen.</string>
<string name="use_fast_gpu_time">Schnelle GPU-Zeit verwenden</string>
<string name="use_fast_gpu_time_description">Erzwingt bei den meisten Spielen die höchste native Auflösung. Diese Option ist experimentell und kann Probleme verursachen.</string>
<string name="fast_gpu_time">GPU-Übertaktungsfaktor</string>
<string name="fast_gpu_time_description">Verwenden Sie 128 für maximale Leistung und 512 für maximale Grafikqualität.</string>
<string name="renderer_reactive_flushing">Reaktives Flushing</string>
@@ -757,8 +770,9 @@ Wirklich fortfahren?</string>
<string name="clock_fast">Schnell (2000MHz)</string>
<!-- GPU overclock factors -->
<string name="fast_gpu_medium">Mittel (256)</string>
<string name="fast_gpu_high">Hoch (512)</string>
<string name="gpu_low">Niedrig (128)</string>
<string name="gpu_medium">Mittel (256)</string>
<string name="gpu_high">Hoch (512)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">Celsius</string>
@@ -80,7 +80,10 @@
<string name="show_fw_version_description">Muestra la versión del firmware instalado</string>
<!-- Eden\'s Veil -->
<string name="eden_veil">Velo de Eden</string>
<string name="eden_veil_description">Configuraciones experimentales para mejorar el rendimiento y la capacidad. Estas configuraciones pueden causar pantallas negras u otros problemas en el juego.</string>
<string name="veil_extensions">Extensiones de la GPU</string>
<string name="dyna_state">Estado dinámico extendido</string>
<string name="dyna_state_description">Controla el número de características que se pueden usar en el estado dinámico extendido. Los números más altos permiten más características y pueden aumentar el rendimiento, pero pueden causar problemas con algunos controladores y proveedores. El valor predeterminado puede variar dependiendo de las capacidades de su sistema y hardware. Este valor se puede cambiar hasta que se logre la estabilidad y una mejor calidad visual.</string>
<string name="disabled">Desactivado</string>
@@ -88,18 +91,24 @@
<string name="provoking_vertex_description">Mejora la iluminación y el manejo de vértices en ciertos juegos. Solo es compatible con las GPU Vulkan 1.0+.</string>
<string name="descriptor_indexing">Indexación del descriptor</string>
<string name="descriptor_indexing_description">Mejora la textura y el manejo del búfer, así como la capa de traducción Maxwell. Compatible con algunas GPU Vulkan 1.1 y todas las GPU Vulkan 1.2+.</string>
<string name="sample_shading">Sombreado de muestra</string>
<string name="sample_shading_description">Permite que el sombreador de fragmentos se ejecute por muestra en un fragmento de múltiples muestras en lugar de una vez por fragmento. Mejora la calidad gráfica a costa de algo de rendimiento. Solo los dispositivos Vulkan 1.1+ admiten esta extensión.</string>
<string name="sample_shading_fraction">Fracción de sombreado de muestra</string>
<string name="sample_shading_fraction_description">La intensidad del paso de sombreado de la muestra. Los valores más altos mejoran más la calidad, pero también reducen el rendimiento en mayor medida.</string>
<string name="veil_renderer">Renderizador</string>
<string name="sync_memory_operations">Sincronizar operaciones de memoria</string>
<string name="sync_memory_operations_description">Garantiza la consistencia de los datos entre las operaciones de computación y memoria. Esta opción debería solucionar problemas en algunos juegos, pero también puede reducir el rendimiento en algunos casos. Los juegos de Unreal Engine 4 a menudo ven los cambios más significativos de los mismos.</string>
<string name="buffer_reorder_disable">Desactivar reordenamiento de búfer</string>
<string name="buffer_reorder_disable_description">Cuando está marcado, desactiva el reordenamiento de las cargas de memoria mapeada, lo que permite asociar cargas con dibujos específicos. Puede reducir el rendimiento en algunos casos.</string>
<string name="veil_misc">CPU y memoria</string>
<string name="use_sync_core">Sincronizar la velocidad del núcleo</string>
<string name="use_sync_core_description">Sincroniza la velocidad del núcleo con el porcentaje máximo de velocidad para mejorar el rendimiento sin alterar la velocidad real del juego.</string>
<string name="use_lru_cache">Habilitar caché LRU</string>
<string name="use_lru_cache_description">Habilite o deshabilite la caché menos utilizada recientemente (LRU), aumentando el rendimiento al ahorrar el uso del proceso de la CPU. Algunos juegos pueden ver problemas con esta configuración, así que desactívela si el juego no arranca o se bloquea aleatoriamente.</string>
<string name="use_fast_cpu_time">Tiempo de CPU rápido</string>
<string name="use_fast_cpu_time_description">Obliga a la CPU emulada a ejecutarse a un reloj más alto, reduciendo ciertos limitadores de FPS. Esta opción es inestable y puede causar problemas, y las CPU más débiles pueden ver un rendimiento reducido.</string>
<string name="custom_cpu_ticks">Ticks de CPU personalizados</string>
<string name="custom_cpu_ticks_description">Establezca un valor personalizado de los ciclos de la CPU. Los valores más altos pueden aumentar el rendimiento, pero también pueden hacer que el juego se congele. Se recomienda un rango de 7721000.</string>
<string name="cpu_ticks">Ciclos</string>
@@ -426,7 +435,9 @@
<string name="network">Red</string>
<!-- Graphics settings strings -->
<string name="backend">Backend</string>
<string name="display">Pantalla</string>
<string name="processing">Postprocesado</string>
<string name="renderer_accuracy">Nivel de precisión</string>
<string name="renderer_resolution">Resolución (Portátil/Sobremesa)</string>
@@ -443,6 +454,8 @@
<string name="renderer_optimize_spirv_output_description">Optimiza el sombreador compilado para mejorar la eficiencia de la GPU.</string>
<string name="renderer_asynchronous_shaders">Usar shaders asíncronos</string>
<string name="renderer_asynchronous_shaders_description">Compila los shaders de forma asíncrona. Esto puede reducir los tirones, pero también puede introducir errores gráficos.</string>
<string name="use_fast_gpu_time">Usar tiempo rápido de GPU</string>
<string name="use_fast_gpu_time_description">Fuerza a la mayoría de juegos a ejecutarse en su resolución nativa más alta. Esta opción es inestable y puede causar problemas.</string>
<string name="fast_gpu_time">Factor de overclock de GPU</string>
<string name="fast_gpu_time_description">Usa 128 para máximo rendimiento y 512 para máxima fidelidad gráfica.</string>
<string name="renderer_reactive_flushing">Usar limpieza reactiva</string>
@@ -800,8 +813,9 @@
<string name="clock_fast">Rápido (2000MHz)</string>
<!-- GPU overclock factors -->
<string name="fast_gpu_medium">Medio (256)</string>
<string name="fast_gpu_high">Alto (512)</string>
<string name="gpu_low">Bajo (128)</string>
<string name="gpu_medium">Medio (256)</string>
<string name="gpu_high">Alto (512)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">Celsius</string>
@@ -60,6 +60,11 @@
<string name="show_fw_version_description">نسخه نصب شده فریمور را نمایش می‌دهد</string>
<!-- Eden\'s Veil -->
<string name="veil_extensions">افزونه‌های GPU</string>
<string name="veil_renderer">رندرر</string>
<string name="veil_misc">پردازنده و حافظه</string>
<string name="eden_veil">پرده عدن</string>
<string name="eden_veil_description">تنظیمات آزمایشی برای بهبود عملکرد و قابلیت. این تنظیمات ممکن است باعث نمایش صفحه سیاه یا سایر مشکلات بازی شود.</string>
<string name="sync_memory_operations">همگام‌سازی عملیات حافظه</string>
<string name="sync_memory_operations_description">اطمینان از سازگاری داده‌ها بین عملیات محاسباتی و حافظه. این گزینه ممکن است مشکلات برخی بازی‌ها را رفع کند، اما در برخی موارد ممکن است عملکرد را کاهش دهد. به نظر می‌رسد بازی‌های با Unreal Engine 4 بیشترین تأثیر را داشته باشند.</string>
<string name="buffer_reorder_disable">غیرفعال کردن مرتب‌سازی مجدد بافر</string>
@@ -81,19 +86,26 @@
<string name="provoking_vertex_description">نورپردازی و مدیریت رأس را در برخی بازی‌ها بهبود می‌بخشد. فقط در کارت‌های گرافیک با پشتیبانی از ولکان 1.0+ قابل استفاده است</string>
<string name="descriptor_indexing">نمایه‌سازی توصیفگر</string>
<string name="descriptor_indexing_description">مدیریت بافت‌ها و بافرها و همچنین لایه ترجمه ماکسول را بهبود می‌بخشد. توسط برخی کارت‌های گرافیک ولکان 1.1 و تمام کارت‌های گرافیک ولکان 1.2+ پشتیبانی می‌شود</string>
<string name="use_fast_gpu_time">استفاده از زمان سریع GPU</string>
<string name="use_fast_gpu_time_description">باعث می‌شود بیشتر بازی‌ها با بالاترین رزولوشن اصلی اجرا شوند. این گزینه ممکن است مشکلاتی ایجاد کند.</string>
<string name="fast_gpu_time">فاکتور اورکلاک GPU</string>
<string name="fast_gpu_time_description">برای حداکثر عملکرد از 128 و برای حداکثر وفاداری گرافیکی از 512 استفاده کنید.</string>
<string name="fast_gpu_medium">متوسط (256)</string>
<string name="fast_gpu_high">بالا (512)</string>
<string name="gpu_low">پایین (128)</string>
<string name="gpu_medium">متوسط (256)</string>
<string name="gpu_high">بالا (512)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">سلسیوس</string>
<string name="temperature_fahrenheit">فارنهایت</string>
<string name="use_fast_cpu_time">زمان CPU سریع</string>
<string name="use_fast_cpu_time_description">CPU شبیه‌سازی شده را مجبور می‌کند با سرعت کلاک بالاتر کار کند، که برخی محدودکننده‌های FPS را کاهش می‌دهد. این گزینه ناپایدار است و ممکن است باعث مشکلات شود و CPUهای ضعیف‌تر ممکن است کاهش عملکرد را تجربه کنند.</string>
<string name="fast_cpu_time">سرعت کلاک CPU</string>
<string name="fast_cpu_time_description">از Boost (1700MHz) برای کار با بالاترین سرعت کلاک بومی سوئیچ یا Fast (2000MHz) برای کار با دو برابر سرعت استفاده کنید.</string>
<string name="memory_layout">چیدمان حافظه</string>
<string name="memory_layout_description">(آزمایشی) چیدمان حافظه شبیه‌سازی شده را تغییر می‌دهد. این تنظیم عملکرد را افزایش نمی‌دهد، اما ممکن است به بازی‌هایی که از رزولوشن بالا با استفاده از مادها استفاده می‌کنند کمک کند. در تلفن‌های با 8 گیگابایت رم یا کمتر استفاده نشود.</string>
<string name="sample_shading">سایه‌زنی نمونه</string>
<string name="sample_shading_description">اجازه می‌دهد شیدر قطعه در هر نمونه از یک قطعه چندنمونه‌ای اجرا شود به جای یک بار برای هر قطعه. کیفیت گرافیک را به بهای کاهش عملکرد بهبود می‌بخشد. فقط دستگاه‌های Vulkan 1.1+ از این افزونه پشتیبانی می‌کنند.</string>
<string name="sample_shading_fraction">کسر سایه‌زنی نمونه</string>
<string name="sample_shading_fraction_description">شدت مرحله سایه‌زنی نمونه. مقادیر بالاتر کیفیت را بیشتر بهبود می‌بخشد اما عملکرد را نیز به میزان بیشتری کاهش می‌دهد.</string>
<string name="custom_cpu_ticks">تیک‌های CPU سفارشی</string>
@@ -436,7 +448,9 @@
<string name="network">شبکه</string>
<!-- Graphics settings strings -->
<string name="backend">بک‌اند</string>
<string name="display">نمایش</string>
<string name="processing">پس‌پردازش</string>
<string name="renderer_accuracy">سطح دقت</string>
<string name="renderer_resolution">وضوح تصویر (دستی/متصل)</string>
<string name="renderer_vsync">حالت VSync</string>
@@ -80,7 +80,10 @@
<string name="show_fw_version_description">Affiche la version du firmware installé</string>
<!-- Eden\'s Veil -->
<string name="eden_veil">Voile d\'Eden</string>
<string name="eden_veil_description">Paramètres expérimentaux pour améliorer les performances et les capacités. Ces paramètres peuvent causer des écrans noirs ou d\'autres problèmes de jeu.</string>
<string name="veil_extensions">Extensions GPU</string>
<string name="dyna_state">État dynamique étendu</string>
<string name="dyna_state_description">Contrôle le nombre de fonctionnalités utilisables dans l\'état dynamique étendu. Des valeurs plus élevées permettent plus de fonctionnalités et peuvent augmenter les performances, mais peuvent causer des problèmes avec certains pilotes et fabricants. La valeur par défaut peut varier selon votre système et vos capacités matérielles. Cette valeur peut être modifiée jusqu\'à obtenir une stabilité et une meilleure qualité visuelle.</string>
<string name="disabled">Désactivé</string>
@@ -90,18 +93,24 @@
<string name="provoking_vertex_description">Améliore l`éclairage et la gestion des vertex dans certains jeux. Pris en charge uniquement par les GPU Vulkan 1.0+.</string>
<string name="descriptor_indexing">Indexation des descripteurs</string>
<string name="descriptor_indexing_description">Améliore la gestion des textures et des tampons, ainsi que la couche de traduction Maxwell. Pris en charge par certains GPU Vulkan 1.1 et tous les GPU Vulkan 1.2+.</string>
<string name="sample_shading">Échantillonnage de shading</string>
<string name="sample_shading_description">Permet au fragment shader de s\'exécuter par échantillon dans un fragment multi-échantillonné au lieu d\'une fois par fragment. Améliore la qualité graphique au détriment des performances. Seuls les appareils Vulkan 1.1+ prennent en charge cette extension.</string>
<string name="sample_shading_fraction">Fraction d\'ombrage d\'échantillon</string>
<string name="sample_shading_fraction_description">L\'intensité de la passe d\'ombrage d\'échantillon. Des valeurs plus élevées améliorent davantage la qualité mais réduisent aussi plus fortement les performances.</string>
<string name="veil_renderer">Rendu</string>
<string name="sync_memory_operations">Synchroniser les opérations mémoire</string>
<string name="sync_memory_operations_description">Garantit la cohérence des données entre les opérations de calcul et de mémoire. Cette option devrait résoudre les problèmes dans certains jeux, mais peut réduire les performances dans certains cas. Les jeux utilisant Unreal Engine 4 semblent être les plus affectés.</string>
<string name="buffer_reorder_disable">Désactiver le réordonnancement du tampon</string>
<string name="buffer_reorder_disable_description">Lorsqu\'il est coché, désactive le réordonnancement des téléchargements de mémoire mappée, permettant d\'associer les téléchargements à des dessins spécifiques. Peut réduire les performances dans certains cas.</string>
<string name="veil_misc">CPU et mémoire</string>
<string name="use_sync_core">Synchroniser la vitesse du cœur</string>
<string name="use_sync_core_description">Synchronise la vitesse du cœur avec le pourcentage de vitesse maximal pour améliorer les performances sans modifier la vitesse réelle du jeu.</string>
<string name="use_lru_cache">Activer le cache LRU</string>
<string name="use_lru_cache_description">Active ou désactive le cache LRU (Least Recently Used) pour améliorer les performances en réduisant lutilisation du processeur. Certains jeux peuvent rencontrer des problèmes avec ce réglage ; désactivez-le si le jeu ne démarre pas ou plante de manière aléatoire.</string>
<string name="use_fast_cpu_time">Temps CPU rapide</string>
<string name="use_fast_cpu_time_description">Force le CPU émulé à fonctionner à une fréquence plus élevée, réduisant certains limiteurs de FPS. Cette option est instable et peut causer des problèmes, et les CPU plus faibles peuvent voir une baisse de performance.</string>
<string name="custom_cpu_ticks">Ticks CPU personnalisés</string>
<string name="custom_cpu_ticks_description">Définissez une valeur personnalisée de ticks CPU. Des valeurs plus élevées peuvent améliorer les performances, mais peuvent aussi provoquer des gels du jeu. Une plage de 77 à 21000 est recommandée.</string>
<string name="cpu_ticks">Ticks</string>
@@ -442,7 +451,9 @@
<string name="network">Réseau</string>
<!-- Graphics settings strings -->
<string name="backend">Backend</string>
<string name="display">Affichage</string>
<string name="processing">Post-traitement</string>
<string name="renderer_accuracy">Niveau de précision</string>
<string name="renderer_resolution">Résolution (Mode Portable/Mode TV)</string>
@@ -459,6 +470,8 @@
<string name="renderer_optimize_spirv_output_description">Optimise le shader compilé pour améliorer l\'efficacité du GPU.</string>
<string name="renderer_asynchronous_shaders">Utiliser les shaders asynchrones</string>
<string name="renderer_asynchronous_shaders_description">Compile les shaders de manière asynchrone. Cela peut réduire les saccades mais peut aussi provoquer des problèmes graphiques.</string>
<string name="use_fast_gpu_time">Utiliser le temps GPU rapide</string>
<string name="use_fast_gpu_time_description">Force la plupart des jeux à utiliser leur résolution native maximale. Cette option est expérimentale et peut causer des problèmes.</string>
<string name="fast_gpu_time">Facteur d\'overclocking GPU</string>
<string name="fast_gpu_time_description">Utilisez 128 pour des performances maximales et 512 pour une fidélité graphique maximale.</string>
<string name="renderer_reactive_flushing">Utiliser le vidage réactif</string>
@@ -827,8 +840,9 @@
<string name="clock_fast">Rapide (2000MHz)</string>
<!-- GPU overclock factors -->
<string name="fast_gpu_medium">Moyen (256)</string>
<string name="fast_gpu_high">Élevé (512)</string>
<string name="gpu_low">Faible (128)</string>
<string name="gpu_medium">Moyen (256)</string>
<string name="gpu_high">Élevé (512)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">Celsius</string>
@@ -59,7 +59,10 @@
<string name="show_fw_version_description">מציג את גרסת הקושחה המותקנת</string>
<!-- Eden\'s Veil -->
<string name="eden_veil">עדן וייל</string>
<string name="eden_veil_description">הגדרות ניסיוניות לשיפור ביצועים ויכולות. הגדרות אלו עלולות לגרום למסכים שחורים או לבעיות אחרות במשחק.</string>
<string name="veil_extensions">הרחבות GPU</string>
<string name="dyna_state">מצב דינמי מורחב</string>
<string name="dyna_state_description">שולט במספר התכונות שניתן להשתמש בהן במצב דינמי מורחב. מספרים גבוהים יותר מאפשרים יותר תכונות ויכולים לשפר את הביצועים, אך עלולים לגרום לבעיות עם כמה מנהלי התקנים וספקים. הערך המוגדר כברירת מחדל עשוי להשתנות בהתאם למערכת שלך ויכולות החומרה. ניתן לשנות ערך זה עד להשגת יציבות ואיכות ויזואלית טובה יותר.</string>
<string name="disabled">מושבת</string>
@@ -67,18 +70,24 @@
<string name="provoking_vertex_description">משפר תאורה וטיפול בקודקודים במשחקים מסוימים. נתמך רק בכרטיסי מסך עם Vulkan 1.0+.</string>
<string name="descriptor_indexing">אינדוקס תיאורים</string>
<string name="descriptor_indexing_description">משפר טיפול במרקמים ומאגרים, כמו גם בשכבת התרגום של Maxwell. נתמך בחלק מכרטיסי ה-Vulkan 1.1 ובכל כרטיסי ה-Vulkan 1.2+.</string>
<string name="sample_shading">דגימת צל</string>
<string name="sample_shading_description">מאפשר לשברי הצללה לרוץ לכל דגימה בקטע רב-דגימות במקום פעם אחת לקטע. משפר את איכות הגרפיקה במחיר של ביצועים. רק מכשירי Vulkan 1.1+ תומכים בהרחבה זו.</string>
<string name="sample_shading_fraction">שבר הצללה לדוגמה</string>
<string name="sample_shading_fraction_description">עוצמת מעבר ההצללה לדוגמה. ערכים גבוהים יותר משפרים את האיכות יותר אך גם מפחיתים את הביצועים במידה רבה יותר.</string>
<string name="veil_renderer">רנדרר</string>
<string name="sync_memory_operations">סנכרון פעולות זיכרון</string>
<string name="sync_memory_operations_description">מבטיח עקביות נתונים בין פעולות חישוב וזיכרון. אפשרות זו אמורה לתקן בעיות במשחקים מסוימים, אך עלולה להפחית ביצועים במקרים מסוימים. נראה שהמשחקים עם Unreal Engine 4 הם המושפעים ביותר.</string>
<string name="buffer_reorder_disable">השבת סידור מחדש של חוצץ</string>
<string name="buffer_reorder_disable_description">כאשר מסומן, מבטל את סידור מחדש של העלאות זיכרון ממופה המאפשר לשייך העלאות עם ציורים ספציפיים. עלול להפחית ביצועים במקרים מסוימים.</string>
<string name="veil_misc">מעבד וזיכרון</string>
<string name="use_sync_core">סנכרון מהירות ליבה</string>
<string name="use_sync_core_description">סנכרן את מהירות הליבה לאחוז המהירות המרבי כדי לשפר ביצועים מבלי לשנות את מהירות המשחק בפועל.</string>
<string name="use_lru_cache">הפעלת מטמון LRU</string>
<string name="use_lru_cache_description">הפעל או השבת מטמון LRU לשיפור ביצועים על ידי חיסכון בשימוש במעבד. לחלק מהמשחקים כמו TotK 1.2.1 יש בעיות - השבת אם המשחק לא עולה או קורס באקראי.</string>
<string name="use_fast_cpu_time">זמן CPU מהיר</string>
<string name="use_fast_cpu_time_description">מכריח את ה-CPU המדומה לפעול במהירות שעון גבוהה יותר, מה שמפחית חלק ממגבילי ה-FPS. אפשרות זו אינה יציבה ועלולה לגרום לבעיות, ומעבדים חלשים יותר עשויים לראות ירידה בביצועים.</string>
<string name="custom_cpu_ticks">טיקי CPU מותאמים</string>
<string name="custom_cpu_ticks_description">הגדר ערך מותאם לטיקי CPU. ערכים גבוהים יותר עשויים לשפר ביצועים, אך גם עלולים לגרום להקפאת המשחק. מומלץ טווח של 77-21000.</string>
<string name="cpu_ticks">טיקים</string>
@@ -388,7 +397,9 @@
<string name="network">רשת</string>
<!-- Graphics settings strings -->
<string name="backend">בקאנד</string>
<string name="display">תצוגה</string>
<string name="processing">עיבוד לאחר</string>
<string name="renderer_accuracy">רמת דיוק</string>
<string name="renderer_resolution">רזולוציה (מעוגן/נייד)</string>
@@ -405,6 +416,8 @@
<string name="renderer_optimize_spirv_output_description">משפר את השאדר המהודר כדי להגביר את יעילות ה-GPU.</string>
<string name="renderer_asynchronous_shaders">השתמש בשיידרים אסינכרונים</string>
<string name="renderer_asynchronous_shaders_description">מקמפל שיידרים באופן אסינכרוני. זה עשוי להפחית קפיצות אך גם עלול לגרום לתקלות גרפיות.</string>
<string name="use_fast_gpu_time">השתמש בזמן GPU מהיר</string>
<string name="use_fast_gpu_time_description">מאלץ את רוב המשחקים לרוץ ברזולוציה המקורית הגבוהה ביותר שלהם. אפשרות זו עלולה לגרום לבעיות.</string>
<string name="fast_gpu_time">גורם אובר-קלוק ל-GPU</string>
<string name="fast_gpu_time_description">השתמש ב-128 לביצועים מקסימליים וב-512 לנאמנות גרפית מקסימלית.</string>
<string name="renderer_reactive_flushing">השתמש בהבהוב תגובתי</string>
@@ -629,8 +642,9 @@
<string name="clock_fast">מהיר (2000MHz)</string>
<!-- GPU overclock factors -->
<string name="fast_gpu_medium">בינוני (256)</string>
<string name="fast_gpu_high">גבוה (512)</string>
<string name="gpu_low">נמוך (128)</string>
<string name="gpu_medium">בינוני (256)</string>
<string name="gpu_high">גבוה (512)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">צלזיוס</string>
@@ -59,7 +59,10 @@
<string name="show_fw_version_description">A telepített firmver verziójának megjelenítése</string>
<!-- Eden\'s Veil -->
<string name="eden_veil">Eden Fátyla</string>
<string name="eden_veil_description">Kísérleti beállítások a teljesítmény és képesség javításához. Ezek a beállítások fekete képernyőket vagy más játékproblémákat okozhatnak.</string>
<string name="veil_extensions">GPU kiterjesztések</string>
<string name="dyna_state">Kiterjesztett Dinamikus Állapot</string>
<string name="dyna_state_description">Szabályozza a Kiterjesztett Dynamikus Állapotban használható funkciók számát. A magasabb értékek több funkciót tesznek lehetővé és növelhetik a teljesítményt, de problémákat okozhatnak egyes meghajtókkal és gyártókkal. Az alapértelmezett érték eltérő lehet a rendszertől és a hardverképességektől függően. Ez az érték módosítható, amíg el nem éri a stabilitást és a jobb vizuális minőséget.</string>
<string name="disabled">Letiltva</string>
@@ -67,18 +70,24 @@
<string name="provoking_vertex_description">Javítja a világítást és a csúcskezelést bizonyos játékokban. Csak Vulkan 1.0+ GPU-kon támogatott.</string>
<string name="descriptor_indexing">Deskriptor Indexelés</string>
<string name="descriptor_indexing_description">Javítja a textúrák és pufferek kezelését, valamint a Maxwell fordítási réteget. Néhány Vulkan 1.1 GPU és minden Vulkan 1.2+ GPU támogatja.</string>
<string name="sample_shading">Mintavételezés árnyékolás</string>
<string name="sample_shading_description">Lehetővé teszi, hogy a fragment shader mintánként fusson egy többmintás fragmentben a fragmentenkénti futtatás helyett. Javítja a grafikai minőséget a teljesítmény rovására. Csak Vulkan 1.1+ eszközök támogatják ezt a kiterjesztést.</string>
<string name="sample_shading_fraction">Mintavételezés árnyékolási hányad</string>
<string name="sample_shading_fraction_description">A mintavételezés árnyékolási lépés intenzitása. A magasabb értékek jobb minőséget eredményeznek, de nagyobb mértékben csökkentik a teljesítményt.</string>
<string name="veil_renderer">Megjelenítő</string>
<string name="sync_memory_operations">Memória-műveletek szinkronizálása</string>
<string name="sync_memory_operations_description">Biztosítja az adatok konzisztenciáját a számítási és memória-műveletek között. Ez az opciónak javítania kell néhány játékban előforduló problémát, de bizonyos esetekben csökkentheti a teljesítményt. Az Unreal Engine 4-et használó játékok látszanak a legérintettebbek.</string>
<string name="buffer_reorder_disable">Puffer újrarendezés letiltása</string>
<string name="buffer_reorder_disable_description">Ha be van jelölve, letiltja a leképezett memória feltöltéseinek újrarendezését, lehetővé téve a feltöltések összerendelését konkrét rajzolásokkal. Bizonyos esetekben csökkentheti a teljesítményt.</string>
<string name="veil_misc">CPU és memória</string>
<string name="use_sync_core">Magsebesség szinkronizálása</string>
<string name="use_sync_core_description">A mag sebességének szinkronizálása a maximális sebesség százalékával a teljesítmény javítása érdekében a játék tényleges sebességének megváltoztatása nélkül.</string>
<string name="use_lru_cache">LRU gyorsítótár engedélyezése</string>
<string name="use_lru_cache_description">Engedélyezi vagy letiltja az LRU gyorsítótárat, növelve a teljesítményt a CPU használat csökkentésével. Néhány játéknak (különösen a TotK 1.2.1-nek) problémája lehet vele - tiltsa le, ha a játék nem indul el vagy véletlenszerűen összeomlik.</string>
<string name="use_fast_cpu_time">Gyors CPU idő</string>
<string name="use_fast_cpu_time_description">Kényszeríti az emulált CPU-t, hogy magasabb órajelen fusson, csökkentve bizonyos FPS korlátozókat. Ez az opció instabil és problémákat okozhat, és gyengébb CPU-k csökkentett teljesítményt tapasztalhatnak.</string>
<string name="custom_cpu_ticks">Egyéni CPU tick-ek</string>
<string name="custom_cpu_ticks_description">Egyéni CPU tick érték beállítása. A magasabb értékek növelhetik a teljesítményt, de a játék befagyását is okozhatják. 7721000 közötti tartomány ajánlott.</string>
<string name="cpu_ticks">Tick-ek</string>
@@ -383,7 +392,9 @@
<string name="network">Hálózat</string>
<!-- Graphics settings strings -->
<string name="backend">Backend</string>
<string name="display">Kijelző</string>
<string name="processing">Utófeldolgozás</string>
<string name="renderer_accuracy">Pontosság szintje</string>
<string name="renderer_resolution">Felbontás (Kézi/Dockolt)</string>
@@ -400,6 +411,8 @@
<string name="renderer_optimize_spirv_output_description">Optimalizálja a lefordított shadert a GPU hatékonyságának javításáért.</string>
<string name="renderer_asynchronous_shaders">Aszinkron árnyékolók használata</string>
<string name="renderer_asynchronous_shaders_description">A shaderek aszinkron fordítása. Csökkentheti a belassulásokat, de hibákat is okozhat.</string>
<string name="use_fast_gpu_time">Gyors GPU idő használata</string>
<string name="use_fast_gpu_time_description">A legtöbb játékot a natív felbontásukon futtatja. Ez az opció instabil és problémákat okozhat.</string>
<string name="fast_gpu_time">GPU túlóra faktor</string>
<string name="fast_gpu_time_description">Használj 128-at a maximális teljesítményért és 512-t a maximális grafikai minőségért.</string>
<string name="renderer_reactive_flushing">Reaktív ürítés használata</string>
@@ -724,8 +737,9 @@
<string name="clock_fast">Gyors (2000MHz)</string>
<!-- GPU overclock factors -->
<string name="fast_gpu_medium">Közepes (256)</string>
<string name="fast_gpu_high">Magas (512)</string>
<string name="gpu_low">Alacsony (128)</string>
<string name="gpu_medium">Közepes (256)</string>
<string name="gpu_high">Magas (512)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">Celsius</string>
@@ -80,7 +80,10 @@
<string name="show_fw_version_description">Menampilkan versi firmware yang terinstal</string>
<!-- Eden\'s Veil -->
<string name="eden_veil">Eden\'s Veil</string>
<string name="eden_veil_description">Pengaturan eksperimental untuk meningkatkan kinerja dan kemampuan. Pengaturan ini dapat menyebabkan layar hitam atau masalah game lainnya.</string>
<string name="veil_extensions">Ekstensi GPU</string>
<string name="dyna_state">Status Dinamis Ekstensi</string>
<string name="dyna_state_description">Mengontrol jumlah fitur yang dapat digunakan dalam Extended Dynamic State. Angka yang lebih tinggi memungkinkan lebih banyak fitur dan dapat meningkatkan performa, tetapi dapat menyebabkan masalah dengan beberapa driver dan vendor. Nilai default dapat bervariasi tergantung pada sistem dan kemampuan hardware Anda. Nilai ini dapat diubah hingga stabilitas dan kualitas visual yang lebih baik tercapai.</string>
<string name="disabled">Dinonaktifkan</string>
@@ -88,18 +91,24 @@
<string name="provoking_vertex_description">Meningkatkan pencahayaan dan penanganan vertex di beberapa game. Hanya didukung di GPU Vulkan 1.0+.</string>
<string name="descriptor_indexing">Pengindeks Deskriptor</string>
<string name="descriptor_indexing_description">Meningkatkan penanganan tekstur dan buffer, serta lapisan terjemahan Maxwell. Didukung oleh beberapa GPU Vulkan 1.1 dan semua GPU Vulkan 1.2+.</string>
<string name="sample_shading">Pencahayaan Sampel</string>
<string name="sample_shading_description">Memungkinkan fragment shader dieksekusi per sampel dalam fragmen multisampel alih-alih sekali per fragmen. Meningkatkan kualitas grafis dengan mengorbankan kinerja. Hanya perangkat Vulkan 1.1+ yang mendukung ekstensi ini.</string>
<string name="sample_shading_fraction">Fraksi Pencahayaan Sampel</string>
<string name="sample_shading_fraction_description">Intensitas proses pencahayaan sampel. Nilai lebih tinggi meningkatkan kualitas lebih baik tetapi juga mengurangi performa lebih besar.</string>
<string name="veil_renderer">Renderer</string>
<string name="sync_memory_operations">Sinkronisasi Operasi Memori</string>
<string name="sync_memory_operations_description">Memastikan konsistensi data antara operasi komputasi dan memori. Opsi ini seharusnya memperbaiki masalah di beberapa game, tetapi mungkin mengurangi performa dalam beberapa kasus. Game dengan Unreal Engine 4 tampaknya yang paling terpengaruh.</string>
<string name="buffer_reorder_disable">Nonaktifkan Penyusunan Ulang Buffer</string>
<string name="buffer_reorder_disable_description">Ketika dicentang, menonaktifkan penyusunan ulang unggahan memori yang dipetakan yang memungkinkan mengaitkan unggahan dengan gambar tertentu. Dapat mengurangi kinerja dalam beberapa kasus.</string>
<string name="veil_misc">CPU dan Memori</string>
<string name="use_sync_core">Sinkronisasi Kecepatan Inti</string>
<string name="use_sync_core_description">Sinkronkan kecepatan inti dengan persentase kecepatan maksimum untuk meningkatkan performa tanpa mengubah kecepatan sebenarnya dari permainan.</string>
<string name="use_lru_cache">Aktifkan LRU Cache</string>
<string name="use_lru_cache_description">Aktifkan atau nonaktifkan cache LRU untuk meningkatkan performa dengan mengurangi penggunaan proses CPU. Beberapa game seperti TotK 1.2.1 memiliki masalah - nonaktifkan jika game tidak mau berjalan atau crash acak.</string>
<string name="use_fast_cpu_time">Waktu CPU Cepat</string>
<string name="use_fast_cpu_time_description">Memaksa CPU emulasi berjalan pada kecepatan clock yang lebih tinggi, mengurangi beberapa pembatas FPS. Opsi ini tidak stabil dan dapat menyebabkan masalah, dan CPU yang lebih lemah mungkin mengalami penurunan kinerja.</string>
<string name="custom_cpu_ticks">Ticks CPU Kustom</string>
<string name="custom_cpu_ticks_description">Atur nilai ticks CPU kustom. Nilai yang lebih tinggi dapat meningkatkan kinerja, tetapi juga dapat menyebabkan game membeku. Kisaran 7721000 direkomendasikan.</string>
<string name="cpu_ticks">Ticks</string>
@@ -418,7 +427,9 @@
<string name="network">Jaringan</string>
<!-- Graphics settings strings -->
<string name="backend">Backend</string>
<string name="display">Tampilan</string>
<string name="processing">Pascaproses</string>
<string name="renderer_accuracy">Tingkatan Akurasi</string>
<string name="renderer_resolution">Resolusi (Handheld/Docked)</string>
@@ -435,6 +446,8 @@
<string name="renderer_optimize_spirv_output_description">Mengoptimalkan shader yang dikompilasi untuk meningkatkan efisiensi GPU.</string>
<string name="renderer_asynchronous_shaders">Gunakan shader asinkron</string>
<string name="renderer_asynchronous_shaders_description">Kompilasi shader secara asinkron. Ini dapat mengurangi lag tetapi juga dapat menyebabkan glitch.</string>
<string name="use_fast_gpu_time">Gunakan Waktu GPU Cepat</string>
<string name="use_fast_gpu_time_description">Memaksa sebagian besar game berjalan pada resolusi asli tertinggi. Opsi ini mungkin menyebabkan masalah.</string>
<string name="fast_gpu_time">Faktor Overclock GPU</string>
<string name="fast_gpu_time_description">Gunakan 128 untuk kinerja maksimal dan 512 untuk kesetiaan grafis maksimal.</string>
<string name="renderer_reactive_flushing">Gunakan reactive flushing</string>
@@ -773,8 +786,9 @@
<string name="clock_fast">Cepat (2000MHz)</string>
<!-- GPU overclock factors -->
<string name="fast_gpu_medium">Sedang (256)</string>
<string name="fast_gpu_high">Tinggi (512)</string>
<string name="gpu_low">Rendah (128)</string>
<string name="gpu_medium">Sedang (256)</string>
<string name="gpu_high">Tinggi (512)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">Celsius</string>
@@ -80,7 +80,10 @@
<string name="show_fw_version_description">Visualizza la versione del firmware installato</string>
<!-- Eden\'s Veil -->
<string name="eden_veil">Velo di Eden</string>
<string name="eden_veil_description">Impostazioni sperimentali per migliorare prestazioni e capacità. Queste impostazioni possono causare schermate nere o altri problemi di gioco.</string>
<string name="veil_extensions">Estensioni GPU</string>
<string name="dyna_state">Stato dinamico esteso</string>
<string name="dyna_state_description">Controlla il numero di funzioni utilizzabili nello Stato Dinamico Esteso. Valori più alti consentono più funzioni e possono aumentare le prestazioni, ma potrebbero causare problemi con alcuni driver e vendor. Il valore predefinito può variare in base al sistema e alle capacità hardware. Questo valore può essere modificato finché non si raggiunge la stabilità e una migliore qualità visiva.</string>
<string name="disabled">Disabilitato</string>
@@ -88,18 +91,24 @@
<string name="provoking_vertex_description">Migliora illuminazione e gestione dei vertici in alcuni giochi. Supportato solo su GPU Vulkan 1.0+.</string>
<string name="descriptor_indexing">Indicizzazione descrittori</string>
<string name="descriptor_indexing_description">Migliora la gestione di texture e buffer, nonché il livello di traduzione Maxwell. Supportato da alcune GPU Vulkan 1.1 e tutte le GPU Vulkan 1.2+.</string>
<string name="sample_shading">Shading campione</string>
<string name="sample_shading_description">Permette al fragment shader di eseguire per campione in un frammento multi-campione invece che una volta per frammento. Migliora la qualità grafica a scapito delle prestazioni. Solo i dispositivi Vulkan 1.1+ supportano questa estensione.</string>
<string name="sample_shading_fraction">Frazione di ombreggiatura campione</string>
<string name="sample_shading_fraction_description">L\'intensità della passata di ombreggiatura campione. Valori più alti migliorano la qualità ma riducono maggiormente le prestazioni.</string>
<string name="veil_renderer">Renderer</string>
<string name="sync_memory_operations">Sincronizza operazioni di memoria</string>
<string name="sync_memory_operations_description">Garantisce la coerenza dei dati tra le operazioni di calcolo e memoria. Questa opzione dovrebbe risolvere problemi in alcuni giochi, ma potrebbe ridurre le prestazioni in alcuni casi. I giochi con Unreal Engine 4 sembrano essere i più colpiti.</string>
<string name="buffer_reorder_disable">Disabilita riordino buffer</string>
<string name="buffer_reorder_disable_description">Se selezionato, disabilita il riordino dei caricamenti di memoria mappata consentendo di associare i caricamenti a disegni specifici. Potrebbe ridurre le prestazioni in alcuni casi.</string>
<string name="veil_misc">CPU e Memoria</string>
<string name="use_sync_core">Sincronizza velocità core</string>
<string name="use_sync_core_description">Sincronizza la velocità del core con la percentuale massima di velocità per migliorare le prestazioni senza alterare la velocità effettiva del gioco.</string>
<string name="use_lru_cache">Abilita cache LRU</string>
<string name="use_lru_cache_description">Abilita o disabilita la cache LRU per migliorare le prestazioni riducendo l\'uso della CPU. Alcuni giochi come TotK 1.2.1 hanno problemi - disabilitalo se il gioco non si avvia o crasha casualmente.</string>
<string name="use_fast_cpu_time">Tempo CPU veloce</string>
<string name="use_fast_cpu_time_description">Forza la CPU emulata a funzionare a una frequenza più alta, riducendo alcuni limitatori di FPS. Questa opzione è instabile e può causare problemi, e CPU più deboli potrebbero vedere prestazioni ridotte.</string>
<string name="custom_cpu_ticks">Tick CPU personalizzati</string>
<string name="custom_cpu_ticks_description">Imposta un valore personalizzato per i tick della CPU. Valori più alti possono aumentare le prestazioni, ma possono anche causare il blocco del gioco. Si consiglia un intervallo di 7721000.</string>
<string name="cpu_ticks">Tick</string>
@@ -427,7 +436,9 @@
<string name="network">Rete</string>
<!-- Graphics settings strings -->
<string name="backend">Backend</string>
<string name="display">Schermo</string>
<string name="processing">Post-elaborazione</string>
<string name="renderer_accuracy">Livello di accuratezza</string>
<string name="renderer_resolution">Risoluzione (Portatile/Docked)</string>
@@ -444,6 +455,8 @@
<string name="renderer_optimize_spirv_output_description">Ottimizza lo shader compilato per migliorare l\'efficienza della GPU.</string>
<string name="renderer_asynchronous_shaders">Usa shaders asincrone</string>
<string name="renderer_asynchronous_shaders_description">Compila gli shader in modo asincrono. Può ridurre gli scatti, ma può anche causare glitch grafici.</string>
<string name="use_fast_gpu_time">Usa tempo GPU veloce</string>
<string name="use_fast_gpu_time_description">Forza la maggior parte dei giochi a funzionare alla massima risoluzione nativa. Questa opzione è instabile e può causare problemi.</string>
<string name="fast_gpu_time">Fattore di overclock GPU</string>
<string name="fast_gpu_time_description">Usa 128 per prestazioni massime e 512 per fedeltà grafica massima.</string>
<string name="renderer_reactive_flushing">Abilita il Reactive Flushing</string>
@@ -812,8 +825,9 @@
<string name="clock_fast">Veloce (2000MHz)</string>
<!-- GPU overclock factors -->
<string name="fast_gpu_medium">Medio (256)</string>
<string name="fast_gpu_high">Alto (512)</string>
<string name="gpu_low">Basso (128)</string>
<string name="gpu_medium">Medio (256)</string>
<string name="gpu_high">Alto (512)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">Celsius</string>
@@ -59,7 +59,10 @@
<string name="show_fw_version_description">インストールされているファームウェアのバージョンを表示</string>
<!-- Eden\'s Veil -->
<string name="eden_veil">エデンのベール</string>
<string name="eden_veil_description">パフォーマンスと機能を向上させる実験的な設定。この設定は黒画面やその他のゲームの問題を引き起こす可能性があります。</string>
<string name="veil_extensions">GPU拡張機能</string>
<string name="dyna_state">拡張ダイナミックステート</string>
<string name="dyna_state_description">拡張ダイナミックステートで使用できる機能の数を制御します。数値が高いほどより多くの機能が使用可能になり、パフォーマンスが向上する可能性がありますが、一部のドライバーやベンダーで問題が発生する可能性があります。デフォルト値は、お使いのシステムとハードウェアの機能によって異なります。安定性とより良い画質が得られるまでこの値を変更できます。</string>
<string name="disabled">無効</string>
@@ -67,18 +70,24 @@
<string name="provoking_vertex_description">特定のゲームで照明と頂点処理を改善します。Vulkan 1.0+ GPUでのみサポートされています。</string>
<string name="descriptor_indexing">ディスクリプタインデキシング</string>
<string name="descriptor_indexing_description">テクスチャとバッファの処理、およびMaxwell翻訳レイヤーを改善します。一部のVulkan 1.1 GPUとすべてのVulkan 1.2+ GPUでサポートされています。</string>
<string name="sample_shading">サンプルシェーディング</string>
<string name="sample_shading_description">マルチサンプルフラグメントでフラグメントシェーダーをフラグメントごとではなくサンプルごとに実行できるようにします。パフォーマンスを犠牲にしてグラフィック品質を向上させます。Vulkan 1.1+デバイスのみがこの拡張機能をサポートしています。</string>
<string name="sample_shading_fraction">サンプルシェーディング率</string>
<string name="sample_shading_fraction_description">サンプルシェーディング処理の強度。高い値ほど品質は向上しますが、パフォーマンスも大きく低下します。</string>
<string name="veil_renderer">レンダラー</string>
<string name="sync_memory_operations">メモリ操作の同期</string>
<string name="sync_memory_operations_description">計算処理とメモリ操作間のデータ一貫性を保証します。 このオプションは一部のゲームの問題を修正しますが、場合によってはパフォーマンスが低下する可能性があります。 Unreal Engine 4のゲームが最も影響を受けるようです。</string>
<string name="buffer_reorder_disable">バッファの再並べ替えを無効化</string>
<string name="buffer_reorder_disable_description">チェック時、マップされたメモリのアップロードの再並べ替えを無効化し、特定の描画に関連付けることができます。場合によってはパフォーマンスが低下する可能性があります。</string>
<string name="veil_misc">CPUとメモリ</string>
<string name="use_sync_core">コア速度の同期</string>
<string name="use_sync_core_description">コアの速度を最大速度パーセンテージに同期させ、ゲームの実際の速度を変えずにパフォーマンスを向上させます。</string>
<string name="use_lru_cache">LRUキャッシュを有効化</string>
<string name="use_lru_cache_description">LRUキャッシュを有効/無効にし、CPUプロセスの使用を節約してパフォーマンスを向上させます。TotK 1.2.1など一部のゲームで問題が発生する可能性があるため、ゲームが起動しない場合やランダムにクラッシュする場合は無効にしてください。</string>
<string name="use_fast_cpu_time">高速CPU時間</string>
<string name="use_fast_cpu_time_description">エミュレートされたCPUをより高いクロックで動作させ、特定のFPSリミッターを削減します。このオプションは不安定で問題を引き起こす可能性があり、弱いCPUではパフォーマンスが低下する可能性があります。</string>
<string name="custom_cpu_ticks">カスタムCPUティック</string>
<string name="custom_cpu_ticks_description">CPUティックのカスタム値を設定します。高い値はパフォーマンスを向上させる可能性がありますが、ゲームがフリーズする可能性もあります。77〜21000の範囲が推奨されます。</string>
<string name="cpu_ticks">ティック</string>
@@ -217,7 +226,7 @@
<string name="view_grid">グリッド表示</string>
<string name="view_grid_compact">コンパクトグリッド</string>
<string name="view_carousel">カルーセル</string>
<string name="game_image_desc"> のスクリーンショット %1$s</string>
<string name="game_image_desc"> のスクリーンショット %1$s</string>
<string name="folder">フォルダ</string>
<string name="dont_show_again">再表示しない</string>
<string name="home_search">検索</string>
@@ -264,7 +273,7 @@
<string name="import_save_warning">セーブデータをインポート</string>
<string name="import_save_warning_description">警告:選択したファイルで全てのセーブファイルを上書きします。そのまま続きましょうか?</string>
<string name="save_files_importing">セーブファイルをインポート中...</string>
<string name="save_files_exporting">セーブファイルを エクスポート </string>
<string name="save_files_exporting">セーブファイルを エクスポート </string>
<string name="save_file_imported_success">インポートが完了しました</string>
<string name="save_file_invalid_zip_structure">セーブデータのディレクトリ構造が無効</string>
<string name="save_file_invalid_zip_structure_description">最初のサブフォルダ名は、ゲームのタイトルIDである必要があります。</string>
@@ -383,7 +392,9 @@
<string name="network">ネットワーク</string>
<!-- Graphics settings strings -->
<string name="backend">バックエンド</string>
<string name="display">ディスプレイ</string>
<string name="processing">後処理</string>
<string name="renderer_accuracy">精度</string>
<string name="renderer_resolution">解像度(携帯モード/TVモード)</string>
@@ -398,6 +409,8 @@
<string name="renderer_optimize_spirv_output_description">コンパイル済みシェーダーを最適化し、GPUの効率を向上させます。</string>
<string name="renderer_asynchronous_shaders">非同期シェーダー</string>
<string name="renderer_asynchronous_shaders_description">シェーダーを非同期でコンパイルします。これによりカクつきが減る可能性がありますが、グラフィックの不具合が発生する場合もあります。</string>
<string name="use_fast_gpu_time">高速GPU時間を使用</string>
<string name="use_fast_gpu_time_description">ほとんどのゲームを最高のネイティブ解像度で強制的に実行します。このオプションは不安定で問題を引き起こす可能性があります。</string>
<string name="fast_gpu_time">GPUオーバークロック係数</string>
<string name="fast_gpu_time_description">最大パフォーマンスには128、最大グラフィック忠実度には512を使用します。</string>
<string name="renderer_reactive_flushing">即時書き込み</string>
@@ -629,8 +642,9 @@
<string name="clock_fast">高速 (2000MHz)</string>
<!-- GPU overclock factors -->
<string name="fast_gpu_medium"> (256)</string>
<string name="fast_gpu_high"> (512)</string>
<string name="gpu_low"> (128)</string>
<string name="gpu_medium"> (256)</string>
<string name="gpu_high">高 (512)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">摂氏</string>
@@ -59,7 +59,10 @@
<string name="show_fw_version_description">설치된 펌웨어 버전을 표시합니다</string>
<!-- Eden\'s Veil -->
<string name="eden_veil">에덴의 베일</string>
<string name="eden_veil_description">성능 및 기능을 향상시키기 위한 실험적 설정. 이 설정은 검은 화면 또는 기타 게임 문제를 일으킬 수 있습니다.</string>
<string name="veil_extensions">GPU 확장 기능</string>
<string name="dyna_state">확장 동적 상태</string>
<string name="dyna_state_description">확장 동적 상태에서 사용할 수 있는 기능의 수를 제어합니다. 높은 값은 더 많은 기능을 허용하고 성능을 높일 수 있지만, 일부 드라이버 및 벤더에서 문제를 일으킬 수 있습니다. 기본값은 시스템 및 하드웨어 기능에 따라 다를 수 있습니다. 안정성과 더 나은 시각적 품질이 달성될 때까지 이 값을 변경할 수 있습니다.</string>
<string name="disabled">비활성화됨</string>
@@ -67,18 +70,24 @@
<string name="provoking_vertex_description">일부 게임에서 조명과 버텍스 처리를 개선합니다. Vulkan 1.0+ GPU에서만 지원됩니다.</string>
<string name="descriptor_indexing">디스크립터 인덱싱</string>
<string name="descriptor_indexing_description">텍스처 및 버퍼 처리와 Maxwell 변환 레이어를 개선합니다. 일부 Vulkan 1.1 GPU 및 모든 Vulkan 1.2+ GPU에서 지원됩니다.</string>
<string name="sample_shading">샘플 쉐이딩</string>
<string name="sample_shading_description">멀티샘플 프래그먼트에서 프래그먼트 쉐이더가 프래그먼트당 한 번이 아니라 샘플당 실행되도록 합니다. 성능을 희생하여 그래픽 품질을 향상시킵니다. Vulkan 1.1+ 장치만 이 확장을 지원합니다.</string>
<string name="sample_shading_fraction">샘플 쉐이딩 비율</string>
<string name="sample_shading_fraction_description">샘플 쉐이딩 패스의 강도. 값이 높을수록 품질이 더 향상되지만 성능도 더 크게 저하됩니다.</string>
<string name="veil_renderer">렌더러</string>
<string name="sync_memory_operations">메모리 작업 동기화</string>
<string name="sync_memory_operations_description">컴퓨팅 및 메모리 작업 간 데이터 일관성을 보장합니다. 이 옵션은 일부 게임의 문제를 해결할 수 있지만 경우에 따라 성능이 저하될 수 있습니다. Unreal Engine 4 게임이 가장 큰 영향을 받는 것으로 보입니다.</string>
<string name="buffer_reorder_disable">버퍼 재정렬 비활성화</string>
<string name="buffer_reorder_disable_description">체크 시, 매핑된 메모리 업로드의 재정렬을 비활성화하여 특정 그리기와 업로드를 연결할 수 있습니다. 경우에 따라 성능이 저하될 수 있습니다.</string>
<string name="veil_misc">CPU 및 메모리</string>
<string name="use_sync_core">코어 속도 동기화</string>
<string name="use_sync_core_description">코어 틱 속도를 최대 속도 백분율과 동기화하여 게임의 실제 속도를 변경하지 않고 성능을 향상시킵니다.</string>
<string name="use_lru_cache">LRU 캐시 사용</string>
<string name="use_lru_cache_description">LRU 캐시를 활성화 또는 비활성화하여 CPU 프로세스 사용을 절약하고 성능을 향상시킵니다. TotK 1.2.1을 포함한 일부 게임에서 문제가 발생할 수 있으므로 게임이 부팅되지 않거나 무작위로 충돌하는 경우 비활성화하세요.</string>
<string name="use_fast_cpu_time">빠른 CPU 시간</string>
<string name="use_fast_cpu_time_description">에뮬레이트된 CPU를 더 높은 클럭으로 실행하여 특정 FPS 제한기를 줄입니다. 이 옵션은 불안정하며 문제를 일으킬 수 있고, 약한 CPU는 성능 저하를 볼 수 있습니다.</string>
<string name="custom_cpu_ticks">사용자 정의 CPU 틱</string>
<string name="custom_cpu_ticks_description">CPU 틱의 사용자 정의 값을 설정합니다. 높은 값은 성능을 향상시킬 수 있지만 게임이 멈출 수도 있습니다. 77~21000 범위를 권장합니다.</string>
<string name="cpu_ticks"></string>
@@ -383,7 +392,9 @@
<string name="network">네트워크</string>
<!-- Graphics settings strings -->
<string name="backend">백엔드</string>
<string name="display">디스플레이</string>
<string name="processing">후처리</string>
<string name="renderer_accuracy">정확도 수준</string>
<string name="renderer_resolution">해상도 (휴대 모드/독 모드)</string>
@@ -398,6 +409,8 @@
<string name="renderer_optimize_spirv_output_description">컴파일된 셰이더를 최적화하여 GPU 효율성을 향상시킵니다.</string>
<string name="renderer_asynchronous_shaders">비동기 셰이더 사용</string>
<string name="renderer_asynchronous_shaders_description">셰이더를 비동기적으로 컴파일합니다. 이로 인해 끊김 현상이 줄어들 수 있지만 그래픽 오류가 발생할 수도 있습니다.</string>
<string name="use_fast_gpu_time">빠른 GPU 시간 사용</string>
<string name="use_fast_gpu_time_description">대부분의 게임을 최고 네이티브 해상도로 강제 실행합니다. 이 옵션은 불안정하여 문제를 일으킬 수 있습니다.</string>
<string name="fast_gpu_time">GPU 오버클럭 팩터</string>
<string name="fast_gpu_time_description">최대 성능을 위해 128을, 최대 그래픽 충실도를 위해 512를 사용하십시오.</string>
<string name="renderer_reactive_flushing">반응형 플러싱 사용</string>
@@ -683,8 +696,9 @@
<string name="clock_fast">빠름 (2000MHz)</string>
<!-- GPU overclock factors -->
<string name="fast_gpu_medium">중간 (256)</string>
<string name="fast_gpu_high">높음 (512)</string>
<string name="gpu_low">낮음 (128)</string>
<string name="gpu_medium">중간 (256)</string>
<string name="gpu_high">높음 (512)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">섭씨</string>
@@ -59,7 +59,10 @@
<string name="show_fw_version_description">Viser den installerte firmwareversjonen</string>
<!-- Eden\'s Veil -->
<string name="eden_veil">Edens slør</string>
<string name="eden_veil_description">Eksperimentelle innstillinger for å forbedre ytelse og funksjonalitet. Disse innstillingene kan forårsake svarte skjermer eller andre spillproblemer.</string>
<string name="veil_extensions">GPU-utvidelser</string>
<string name="dyna_state">Utvidet dynamisk tilstand</string>
<string name="dyna_state_description">Kontrollerer antall funksjoner som kan brukes i Utvidet Dynamisk Tilstand. Høyere tall tillater flere funksjoner og kan øke ytelsen, men kan forårsake problemer med noen drivere og leverandører. Standardverdien kan variere avhengig av systemet og maskinvareevnene dine. Denne verdien kan endres til stabilitet og bedre visuell kvalitet er oppnådd.</string>
<string name="disabled">Deaktivert</string>
@@ -67,18 +70,24 @@
<string name="provoking_vertex_description">Forbedrer belysning og vertexhåndtering i enkelte spill. Støttes kun på Vulkan 1.0+ GPU-er.</string>
<string name="descriptor_indexing">Beskrivelsesindeksering</string>
<string name="descriptor_indexing_description">Forbedrer tekstur- og bufferhåndtering, samt Maxwell-oversettelseslaget. Støttes av noen Vulkan 1.1 GPU-er og alle Vulkan 1.2+ GPU-er.</string>
<string name="sample_shading">Prøvegjengivelse</string>
<string name="sample_shading_description">Lar fragment-shaderen kjøres per prøve i et flerprøvefragment i stedet for en gang per fragment. Forbedrer grafikkvaliteten på bekostning av ytelse. Bare Vulkan 1.1+-enheter støtter denne utvidelsen.</string>
<string name="sample_shading_fraction">Prøveskyggebrøk</string>
<string name="sample_shading_fraction_description">Intensiteten til prøveskyggepasseringen. Høyere verdier forbedrer kvaliteten mer, men reduserer også ytelsen i større grad.</string>
<string name="veil_renderer">Renderer</string>
<string name="sync_memory_operations">Synkroniser minneoperasjoner</string>
<string name="sync_memory_operations_description">Sikrer datakonsistens mellom beregnings- og minneoperasjoner. Dette alternativet bør fikse problemer i noen spill, men kan redusere ytelsen i noen tilfeller. Spill med Unreal Engine 4 ser ut til å være de mest berørte.</string>
<string name="buffer_reorder_disable">Deaktiver bufferomorganisering</string>
<string name="buffer_reorder_disable_description">Når merket, deaktiveres omorganisering av kartlagt minneopplasting som tillater å knytte opplastinger til spesifikke tegninger. Kan redusere ytelsen i noen tilfeller.</string>
<string name="veil_misc">CPU og minne</string>
<string name="use_sync_core">Synkroniser kjernespeed</string>
<string name="use_sync_core_description">Synkroniser kjernens hastighet med maksimal hastighetsprosent for å forbedre ytelsen uten å endre spillets faktiske hastighet.</string>
<string name="use_lru_cache">Aktiver LRU-mellomlager</string>
<string name="use_lru_cache_description">Aktiver eller deaktiver LRU-mellomlager for å forbedre ytelsen ved å spare CPU-prosessorbruk. Noen spill som TotK 1.2.1 har problemer med dette - deaktiver hvis spillet ikke starter eller krasjer tilfeldig.</string>
<string name="use_fast_cpu_time">Rask CPU-tid</string>
<string name="use_fast_cpu_time_description">Tvinger den emulerte CPU-en til å kjøre med høyere klokkehastighet, noe som reduserer visse FPS-begrensninger. Dette alternativet er ustabilt og kan forårsake problemer, og svakere CPU-er kan oppleve redusert ytelse.</string>
<string name="custom_cpu_ticks">Egendefinerte CPU-takter</string>
<string name="custom_cpu_ticks_description">Angi en egendefinert verdi for CPU-takter. Høyere verdier kan øke ytelsen, men kan også føre til at spret fryser. Et område på 7721000 anbefales.</string>
<string name="cpu_ticks">Takter</string>
@@ -364,7 +373,9 @@
<string name="network">Nettverk</string>
<!-- Graphics settings strings -->
<string name="backend">Backend</string>
<string name="display">Skjerm</string>
<string name="processing">Etterbehandling</string>
<string name="renderer_accuracy">Nøyaktighetsnivå</string>
<string name="renderer_resolution">Oppløsning (håndholdt/dokket)</string>
@@ -381,6 +392,8 @@
<string name="renderer_optimize_spirv_output_description">Optimaliserer den kompilerte shaderen for å forbedre GPU-effektiviteten.</string>
<string name="renderer_asynchronous_shaders">Bruk asynkrone shaders</string>
<string name="renderer_asynchronous_shaders_description">Kompilerer shadere asynkront. Dette kan redusere rykk, men kan også forårsake grafiske feil.</string>
<string name="use_fast_gpu_time">Bruk rask GPU-tid</string>
<string name="use_fast_gpu_time_description">Tvinger de fleste spill til å kjøre i høyeste oppløsning. Dette alternativet er ustabilt og kan forårsake problemer.</string>
<string name="fast_gpu_time">GPU-overklokkingsfaktor</string>
<string name="fast_gpu_time_description">Bruk 128 for maksimal ytelse og 512 for maksimal grafikkvalitet.</string>
<string name="renderer_reactive_flushing">Bruk reaktiv spyling</string>
@@ -607,8 +620,9 @@
<string name="clock_fast">Rask (2000MHz)</string>
<!-- GPU overclock factors -->
<string name="fast_gpu_medium">Middels (256)</string>
<string name="fast_gpu_high">Høy (512)</string>
<string name="gpu_low">Lav (128)</string>
<string name="gpu_medium">Middels (256)</string>
<string name="gpu_high">Høy (512)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">Celsius</string>
@@ -83,7 +83,10 @@
<string name="show_fw_version_description">Wyświetla zainstalowaną wersję firmware</string>
<!-- Eden\'s Veil -->
<string name="eden_veil">Zasłona Edenu</string>
<string name="eden_veil_description">Eksperymentalne ustawienia poprawiające wydajność i możliwości. Te ustawienia mogą powodować czarne ekrany lub inne problemy z grą.</string>
<string name="veil_extensions">Rozszerzenia GPU</string>
<string name="dyna_state">Rozszerzony stan dynamiczny</string>
<string name="dyna_state_description">Kontroluje liczbę funkcji, które mogą być używane w Rozszerzonym Stanie Dynamicznym. Wyższe wartości pozwalają na więcej funkcji i mogą zwiększyć wydajność, ale mogą powodować problemy z niektórymi sterownikami i producentami. Wartość domyślna może się różnić w zależności od systemu i możliwości sprzętowych. Tę wartość można zmieniać, aż do osiągnięcia stabilności i lepszej jakości wizualnej.</string>
<string name="disabled">Wyłączone</string>
@@ -93,18 +96,24 @@
<string name="provoking_vertex_description">Poprawia oświetlenie i obsługę wierzchołków w niektórych grach. Obsługiwane tylko przez GPU Vulkan 1.0+.</string>
<string name="descriptor_indexing">Indeksowanie deskryptorów</string>
<string name="descriptor_indexing_description">Poprawia obsługę tekstur i buforów oraz warstwę tłumaczenia Maxwell. Obsługiwane przez niektóre GPU Vulkan 1.1 i wszystkie GPU Vulkan 1.2+.</string>
<string name="sample_shading">Cieniowanie próbek</string>
<string name="sample_shading_description">Pozwala shaderowi fragmentów wykonywać się na próbkę w fragmencie wielopróbkowym zamiast raz na fragment. Poprawia jakość grafiki kosztem wydajności. Tylko urządzenia Vulkan 1.1+ obsługują to rozszerzenie.</string>
<string name="sample_shading_fraction">Ułamek cieniowania próbki</string>
<string name="sample_shading_fraction_description">Intensywność przebiegu cieniowania próbki. Wyższe wartości poprawiają jakość, ale także w większym stopniu zmniejszają wydajność.</string>
<string name="veil_renderer">Renderer</string>
<string name="sync_memory_operations">Synchronizuj operacje pamięci</string>
<string name="sync_memory_operations_description">Zapewnia spójność danych między operacjami obliczeniowymi i pamięciowymi. Ta opcja powinna naprawiać problemy w niektórych grach, ale może zmniejszyć wydajność w niektórych przypadkach. Gry z Unreal Engine 4 wydają się być najbardziej dotknięte.</string>
<string name="buffer_reorder_disable">Wyłącz przestawianie bufora</string>
<string name="buffer_reorder_disable_description">Po zaznaczeniu wyłącza przestawianie załadowań zmapowanej pamięci, umożliwiając powiązanie załadowań z konkretnymi rysunkami. Może zmniejszyć wydajność w niektórych przypadkach.</string>
<string name="veil_misc">Procesor i pamięć</string>
<string name="use_sync_core">Synchronizuj prędkość rdzenia</string>
<string name="use_sync_core_description">Synchronizuje prędkość rdzenia z maksymalnym procentem prędkości, aby poprawić wydajność bez zmiany rzeczywistej prędkości gry.</string>
<string name="use_lru_cache">Włącz pamięć podręczną LRU</string>
<string name="use_lru_cache_description">Włącz lub wyłącz pamięć podręczną LRU, aby poprawić wydajność poprzez zmniejszenie użycia procesora. Niektóre gry, takie jak TotK 1.2.1, mogą mieć problemy - wyłącz, jeśli gra się nie uruchamia lub losowo zawiesza.</string>
<string name="use_fast_cpu_time">Szybki czas CPU</string>
<string name="use_fast_cpu_time_description">Wymusza działanie emulowanego procesora z wyższą częstotliwością taktowania, zmniejszając niektóre ograniczenia FPS. Ta opcja jest niestabilna i może powodować problemy, a słabsze procesory mogą doświadczyć zmniejszonej wydajności.</string>
<string name="custom_cpu_ticks">Niestandardowe takty CPU</string>
<string name="custom_cpu_ticks_description">Ustaw niestandardową wartość taktów CPU. Wyższe wartości mogą zwiększyć wydajność, ale mogą też powodować zawieszanie się gry. Zalecany zakres to 7721000.</string>
<string name="cpu_ticks">Takty</string>
@@ -467,7 +476,9 @@
<string name="network">Sieć</string>
<!-- Graphics settings strings -->
<string name="backend">Backend</string>
<string name="display">Wyświetlacz</string>
<string name="processing">Postprocessing</string>
<string name="renderer_accuracy">Poziom precyzji emulacji</string>
<string name="renderer_resolution">Rozdzielczość (Handheld/Zadokowany)</string>
@@ -484,6 +495,8 @@
<string name="renderer_optimize_spirv_output_description">Optymalizuje skompilowany shader w celu poprawy wydajności GPU.</string>
<string name="renderer_asynchronous_shaders">Wyłącz synchronizację shaderów</string>
<string name="renderer_asynchronous_shaders_description">Kompiluje shadery asynchronicznie. Może to zmniejszyć zacinanie, ale może też powodować błędy graficzne.</string>
<string name="use_fast_gpu_time">Użyj szybkiego czasu GPU</string>
<string name="use_fast_gpu_time_description">Wymusza na większości gier działanie w najwyższej natywnej rozdzielczości. Ta opcja może powodować problemy.</string>
<string name="fast_gpu_time">Współczynnik overclockingu GPU</string>
<string name="fast_gpu_time_description">Użyj 128 dla maksymalnej wydajności i 512 dla maksymalnej wierności graficznej.</string>
<string name="renderer_reactive_flushing">Użyj spłukiwania reaktywnego - reactive flushing</string>
@@ -861,8 +874,9 @@
<string name="clock_fast">Szybkie (2000MHz)</string>
<!-- GPU overclock factors -->
<string name="fast_gpu_medium">Średnie (256)</string>
<string name="fast_gpu_high">Wysokie (512)</string>
<string name="gpu_low">Niskie (128)</string>
<string name="gpu_medium">Średnie (256)</string>
<string name="gpu_high">Wysokie (512)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">Celsjusza</string>
@@ -80,7 +80,10 @@
<string name="show_fw_version_description">Exibir a versão do firmware instalado</string>
<!-- Eden\'s Veil -->
<string name="eden_veil">Véu do Éden</string>
<string name="eden_veil_description">Configurações experimentais que podem melhorar a performance e recursos do emulador. Essas configurações podem causar telas pretas ou outros problemas durante o jogo.</string>
<string name="veil_extensions">Extensões da GPU</string>
<string name="dyna_state">Extended Dynamic State</string>
<string name="dyna_state_description">Estado Dinâmico Estendido: Controla o nível de recursos que podem ser usados no Extended Dynamic State. Níveis mais altos permitem mais recursos e podem melhorar o desempenho, mas podem causar problemas com alguns drivers e fabricantes. O nível padrão pode variar dependendo do seu sistema e das capacidades do hardware. Este valor pode ser ajustado até que se alcance estabilidade e melhor qualidade visual.</string>
<string name="disabled">Desativado</string>
@@ -88,18 +91,24 @@
<string name="provoking_vertex_description">Vértice Provocante: Melhora a iluminação e o processamento de vértices em certos jogos. Suportado apenas em GPUs com Vulkan 1.0 ou superior.</string>
<string name="descriptor_indexing">Descriptor Indexing</string>
<string name="descriptor_indexing_description">Indexação de Descritores: Melhora o processamento de texturas e buffers, assim como a camada de tradução Maxwell. Suportado por algumas GPUs Vulkan 1.1 e todas as GPUs Vulkan 1.2 ou superiores.</string>
<string name="sample_shading">Sample Shading</string>
<string name="sample_shading_description">Amostragem de Sombreamento: Permite que o shader de fragmento seja processado por cada amostra em fragmentos multiamostrados, em vez de executar uma vez por fragmento, melhorando a qualidade gráfica, porém impactando levemente o desempenho. Funciona apenas em dispositivos Vulkan 1.1 ou superiores.</string>
<string name="sample_shading_fraction">Sample Shading Fraction</string>
<string name="sample_shading_fraction_description">Fração de Sombreamento de Amostra: Define a intensidade do sample shading. Quanto maior, melhor a qualidade, mas maior o impacto no desempenho.</string>
<string name="veil_renderer">Renderizador</string>
<string name="sync_memory_operations">Sincronizar Operações de Memória</string>
<string name="sync_memory_operations_description">Garante a consistência de dados entre operações de computação e memória. Esta opção pode corrigir problemas em alguns jogos, mas também pode reduzir o desempenho, sendo os jogos da Unreal Engine 4 os mais afetados.</string>
<string name="buffer_reorder_disable">Desativar Reordenação de Buffers</string>
<string name="buffer_reorder_disable_description">Quando marcado, desativa a reordenação de uploads de memória mapeada, permitindo associar uploads a desenhos específicos. Pode reduzir o desempenho em alguns casos.</string>
<string name="veil_misc">CPU e Memória</string>
<string name="use_sync_core">Sincronizar Velocidade do Núcleo</string>
<string name="use_sync_core_description">Aumenta a velocidade do ciclo do núcleo até o máximo para melhorar o desempenho, mantendo a velocidade real do jogo inalterada.</string>
<string name="use_lru_cache">Ativar Cache LRU</string>
<string name="use_lru_cache_description">O cache Least Recently Used (LRU, ou Itens Menos Usados) aumenta o desempenho, economizando o uso do processador. Alguns jogos podem apresentar problemas com esta configuração. Desative-a caso o jogo não inicie ou trave aleatoriamente.</string>
<string name="use_fast_cpu_time">Tempo Rápido na CPU</string>
<string name="use_fast_cpu_time_description">Força a CPU emulada a rodar em um clock mais alto, reduzindo certos limitadores de FPS. Esta opção é instável e pode causar problemas. CPUs mais fracas podem ter desempenho reduzido.</string>
<string name="custom_cpu_ticks">Ciclos da CPU Personalizados</string>
<string name="custom_cpu_ticks_description">Defina um valor personalizado de ciclos da CPU. Valores mais altos podem aumentar o desempenho, mas também podem fazer o jogo travar. Recomenda-se usar valores entre 77 e 21000.</string>
<string name="cpu_ticks">Ciclos</string>
@@ -426,7 +435,9 @@
<string name="network">Rede</string>
<!-- Graphics settings strings -->
<string name="backend">Backend</string>
<string name="display">Tela</string>
<string name="processing">Pós-Processamento</string>
<string name="renderer_accuracy">Nível de precisão</string>
<string name="renderer_resolution">Resolução (Portátil/Modo TV)</string>
@@ -443,6 +454,8 @@
<string name="renderer_optimize_spirv_output_description">Otimiza o shader compilado para melhorar a eficiência da GPU.</string>
<string name="renderer_asynchronous_shaders">Usar shaders assíncronos </string>
<string name="renderer_asynchronous_shaders_description">Compila shaders de forma assíncrona. Isso pode reduzir engasgos, mas também pode introduzir falhas gráficas.</string>
<string name="use_fast_gpu_time">Usar tempo rápido de GPU</string>
<string name="use_fast_gpu_time_description">Força a maioria dos jogos a rodar em sua resolução nativa máxima. Esta opção é instável e pode causar problemas.</string>
<string name="fast_gpu_time">Fator de overclock da GPU</string>
<string name="fast_gpu_time_description">Use 128 para desempenho máximo e 512 para fidelidade gráfica máxima.</string>
<string name="renderer_reactive_flushing">Usar flushing reativo</string>
@@ -801,8 +814,9 @@ uma tentativa de mapeamento automático</string>
<string name="clock_fast">Rápido (2000MHz)</string>
<!-- GPU overclock factors -->
<string name="fast_gpu_medium">Médio (256)</string>
<string name="fast_gpu_high">Alto (512)</string>
<string name="gpu_low">Baixo (128)</string>
<string name="gpu_medium">Médio (256)</string>
<string name="gpu_high">Alto (512)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">Celsius</string>
@@ -59,7 +59,10 @@
<string name="show_fw_version_description">Mostra a versão do firmware instalado</string>
<!-- Eden\'s Veil -->
<string name="eden_veil">Véu do Éden</string>
<string name="eden_veil_description">Definições experimentais para melhorar o desempenho e capacidade. Estas definições podem causar ecrãs pretos ou outros problemas no jogo.</string>
<string name="veil_extensions">Extensões da GPU</string>
<string name="dyna_state">Estado Dinâmico Estendido</string>
<string name="dyna_state_description">Controla o número de funcionalidades que podem ser utilizadas no Estado Dinâmico Alargado. Valores mais elevados permitem mais funcionalidades e podem aumentar o desempenho, mas podem causar problemas com alguns controladores e fabricantes. O valor predefinido pode variar consoante o seu sistema e capacidades de hardware. Este valor pode ser alterado até ser alcançada a estabilidade e uma melhor qualidade visual.</string>
<string name="disabled">Desativado</string>
@@ -67,18 +70,24 @@
<string name="provoking_vertex_description">Melhora a iluminação e o tratamento de vértices em certos jogos. Suportado apenas em GPUs Vulkan 1.0+.</string>
<string name="descriptor_indexing">Indexação de descritores</string>
<string name="descriptor_indexing_description">Melhora o tratamento de texturas e buffers, assim como a camada de tradução Maxwell. Suportado por algumas GPUs Vulkan 1.1 e todas Vulkan 1.2+.</string>
<string name="sample_shading">Amostragem de sombreamento</string>
<string name="sample_shading_description">Permite que o fragment shader seja executado por amostra num fragmento multi-amostrado em vez de uma vez por fragmento. Melhora a qualidade gráfica à custa de desempenho. Apenas dispositivos Vulkan 1.1+ suportam esta extensão.</string>
<string name="sample_shading_fraction">Fração de Sombreamento de Amostra</string>
<string name="sample_shading_fraction_description">A intensidade da passagem de sombreamento de amostra. Valores mais elevados melhoram a qualidade, mas também reduzem o desempenho numa maior medida.</string>
<string name="veil_renderer">Renderizador</string>
<string name="sync_memory_operations">Sincronizar Operações de Memória</string>
<string name="sync_memory_operations_description">Garante a consistência dos dados entre operações de computação e memória. Esta opção deve corrigir problemas em alguns jogos, mas pode reduzir o desempenho nalguns casos. Os jogos com Unreal Engine 4 parecem ser os mais afectados.</string>
<string name="buffer_reorder_disable">Desativar reordenação de buffer</string>
<string name="buffer_reorder_disable_description">Quando assinalado, desativa a reordenação de carregamentos de memória mapeada, permitindo associar carregamentos a desenhos específicos. Pode reduzir o desempenho nalguns casos.</string>
<string name="veil_misc">CPU e Memória</string>
<string name="use_sync_core">Sincronizar velocidade do núcleo</string>
<string name="use_sync_core_description">Sincroniza a velocidade do núcleo com a percentagem máxima de velocidade para melhorar o desempenho sem alterar a velocidade real do jogo.</string>
<string name="use_lru_cache">Ativar cache LRU</string>
<string name="use_lru_cache_description">Ative ou desative a cache LRU para melhorar desempenho poupando uso do processador. Alguns jogos como TotK 1.2.1 têm problemas - desative se o jogo não iniciar ou falhar aleatoriamente.</string>
<string name="use_fast_cpu_time">Tempo de CPU rápido</string>
<string name="use_fast_cpu_time_description">Força a CPU emulada a funcionar a uma velocidade de relógio mais alta, reduzindo certos limitadores de FPS. Esta opção é instável e pode causar problemas, e CPUs mais fracas podem ter desempenho reduzido.</string>
<string name="custom_cpu_ticks">Ticks de CPU personalizados</string>
<string name="custom_cpu_ticks_description">Defina um valor personalizado para ticks de CPU. Valores mais altos podem aumentar o desempenho, mas também podem causar bloqueios no jogo. Um intervalo de 7721000 é recomendado.</string>
<string name="cpu_ticks">Ticks</string>
@@ -387,7 +396,9 @@
<string name="network">Rede</string>
<!-- Graphics settings strings -->
<string name="backend">Backend</string>
<string name="display">Ecrã</string>
<string name="processing">Pós-processamento</string>
<string name="renderer_accuracy">Nível de precisão</string>
<string name="renderer_resolution">Resolução (Portátil/Ancorado)</string>
@@ -404,6 +415,8 @@
<string name="renderer_optimize_spirv_output_description">Otimiza o shader compilado para melhorar a eficiência da GPU.</string>
<string name="renderer_asynchronous_shaders">Usa shaders assíncronos </string>
<string name="renderer_asynchronous_shaders_description">Compila shaders de forma assíncrona. Isto pode reduzir engasgadelas, mas também pode introduzir falhas gráficas.</string>
<string name="use_fast_gpu_time">Usar tempo rápido de GPU</string>
<string name="use_fast_gpu_time_description">Força a maioria dos jogos a executar na sua resolução nativa mais alta. Esta opção é instável e pode causar problemas.</string>
<string name="fast_gpu_time">Fator de overclock da GPU</string>
<string name="fast_gpu_time_description">Use 128 para desempenho máximo e 512 para fidelidade gráfica máxima.</string>
<string name="renderer_reactive_flushing">Usar flushing reativo</string>
@@ -736,8 +749,9 @@ uma tentativa de mapeamento automático</string>
<string name="clock_fast">Rápido (2000MHz)</string>
<!-- GPU overclock factors -->
<string name="fast_gpu_medium">Médio (256)</string>
<string name="fast_gpu_high">Alto (512)</string>
<string name="gpu_low">Baixo (128)</string>
<string name="gpu_medium">Médio (256)</string>
<string name="gpu_high">Alto (512)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">Celsius</string>
@@ -83,7 +83,10 @@
<string name="show_fw_version_description">Отображает установленную версию прошивки</string>
<!-- Eden\'s Veil -->
<string name="eden_veil">Покров Эдема</string>
<string name="eden_veil_description">Экспериментальные настройки для улучшения производительности и возможностей. Эти настройки могут вызывать черные экраны или другие проблемы в игре.</string>
<string name="veil_extensions">Расширения ГПУ</string>
<string name="dyna_state">Расширенное динамическое состояние</string>
<string name="dyna_state_description">Управляет количеством функций, которые можно использовать в расширенном динамическом состоянии. Более высокие значения позволяют использовать больше функций и могут повысить производительность, но могут вызвать проблемы с некоторыми драйверами и производителями. Значение по умолчанию может варьироваться в зависимости от вашей системы и возможностей оборудования. Это значение можно изменять до достижения стабильности и лучшего визуального качества.</string>
<string name="disabled">Отключено</string>
@@ -93,18 +96,24 @@
<string name="provoking_vertex_description">Улучшает освещение и обработку вершин в некоторых играх. Поддерживается только ГПУ с Vulkan 1.0+.</string>
<string name="descriptor_indexing">Индексирование дескрипторов</string>
<string name="descriptor_indexing_description">Улучшает обработку текстур и буферов, а также слой перевода Maxwell. Поддерживается некоторыми ГПУ Vulkan 1.1 и всеми ГПУ Vulkan 1.2+.</string>
<string name="sample_shading">Сэмпловый шейдинг</string>
<string name="sample_shading_description">Позволяет шейдеру фрагментов выполняться на каждый сэмпл в мультисэмпловом фрагменте вместо одного раза на фрагмент. Улучшает качество графики ценой производительности. Только устройства с Vulkan 1.1+ поддерживают это расширение.</string>
<string name="sample_shading_fraction">Доля сэмплового затенения</string>
<string name="sample_shading_fraction_description">Интенсивность прохода сэмплового затенения. Более высокие значения улучшают качество, но и сильнее снижают производительность.</string>
<string name="veil_renderer">Рендеринг</string>
<string name="sync_memory_operations">Синхронизация операций с памятью</string>
<string name="sync_memory_operations_description">Обеспечивает согласованность данных между вычислительными операциями и операциями с памятью. Эта опция должна исправлять проблемы в некоторых играх, но может снижать производительность в некоторых случаях. Наиболее сильно это затрагивает игры на Unreal Engine 4.</string>
<string name="buffer_reorder_disable">Отключить переупорядочивание буфера</string>
<string name="buffer_reorder_disable_description">При включении отключает переупорядочивание загрузки отображенной памяти, позволяя связывать загрузки с конкретными отрисовками. В некоторых случаях может снизить производительность.</string>
<string name="veil_misc">Процессор и память</string>
<string name="use_sync_core">Синхронизация скорости ядра</string>
<string name="use_sync_core_description">Синхронизирует скорость ядра с максимальным процентом скорости для улучшения производительности без изменения фактической скорости игры.</string>
<string name="use_lru_cache">Включить LRU-кеш</string>
<string name="use_lru_cache_description">Включите или отключите кэш LRU (наименее недавно использованный), повышая производительность за счёт снижения нагрузки на ЦП. Некоторые игры могут работать с ним некорректно (например, TotK 1.2.1), поэтому отключите, если игра не запускается или случайно вылетает.</string>
<string name="use_fast_cpu_time">Быстрое время ЦП</string>
<string name="use_fast_cpu_time_description">Заставляет эмулируемый процессор работать на более высокой частоте, уменьшая некоторые ограничители FPS. Эта опция нестабильна и может вызывать проблемы, а более слабые процессоры могут показывать снижение производительности.</string>
<string name="custom_cpu_ticks">Пользовательские такты ЦП</string>
<string name="custom_cpu_ticks_description">Установите пользовательское значение тактов ЦП. Более высокие значения могут увеличить производительность, но также могут вызвать зависание игры. Рекомендуется диапазон 77–21000.</string>
<string name="cpu_ticks">Такты</string>
@@ -467,7 +476,9 @@
<string name="network">Сеть</string>
<!-- Graphics settings strings -->
<string name="backend">Бэкенд</string>
<string name="display">Дисплей</string>
<string name="processing">Постобработка</string>
<string name="renderer_accuracy">Уровень точности</string>
<string name="renderer_resolution">Разрешение (портативное/в док-станции)</string>
@@ -484,6 +495,8 @@
<string name="renderer_optimize_spirv_output_description">Оптимизирует скомпилированный шейдер для повышения эффективности ГПУ.</string>
<string name="renderer_asynchronous_shaders">Использовать асинхронные шейдеры</string>
<string name="renderer_asynchronous_shaders_description">Компилирует шейдеры асинхронно. Это может уменьшить подтормаживания, но также может вызвать графические артефакты.</string>
<string name="use_fast_gpu_time">Использовать быстрое время ГПУ</string>
<string name="use_fast_gpu_time_description">Заставляет большинство игр работать в максимальном нативном разрешении. Эта опция может вызывать проблемы.</string>
<string name="fast_gpu_time">Фактор разгона ГПУ</string>
<string name="fast_gpu_time_description">Используйте 128 для максимальной производительности и 512 для максимальной графической точности.</string>
<string name="renderer_reactive_flushing">Реактивная очистка</string>
@@ -861,8 +874,9 @@
<string name="clock_fast">Быстрая (2000MHz)</string>
<!-- GPU overclock factors -->
<string name="fast_gpu_medium">Средний (256)</string>
<string name="fast_gpu_high">Высокий (512)</string>
<string name="gpu_low">Низкий (128)</string>
<string name="gpu_medium">Средний (256)</string>
<string name="gpu_high">Высокий (512)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">Цельсий</string>
@@ -57,7 +57,10 @@
<string name="show_fw_version_description">Приказује инсталирану верзију фирмвера</string>
<!-- Eden\'s Veil -->
<string name="eden_veil">Еденова аукција</string>
<string name="eden_veil_description">Експериментална подешавања за побољшање перформанси и способности. Ова подешавања могу изазвати црне екране или друге проблеме у игри.</string>
<string name="veil_extensions">ГПУ екстензије</string>
<string name="dyna_state">Проширена динамичка држава</string>
<string name="dyna_state_description">Управља бројем функција које се могу користити у Проширеном динамичком стању. Веће вредности омогућавају више функција и могу повећати перформансе, али могу изазвати проблеме са неким драјверима и произвођачима. Подразумевана вредност може се разликовати у зависности од вашег система и хардверских могућности. Ова вредност се може мењати док се не постигне стабилност и бољи визуелни квалитет.</string>
<string name="disabled">Искључено</string>
@@ -65,18 +68,24 @@
<string name="provoking_vertex_description">Побољшава осветљење и вертификат руковања у одређеним играма. Подржан само на Вулкану 1.0+ ГПУ-у.</string>
<string name="descriptor_indexing">Индексирање дескриптора</string>
<string name="descriptor_indexing_description">Побољшава текстуру и руковање међуспремника, као и преводилачки слој Маквелл. Подржани од стране неких Вулкана 1.1 ГПУ-а и сви Вулкан 1.2+ ГПУ.</string>
<string name="sample_shading">Семпловање сенчења</string>
<string name="sample_shading_description">Омогућава фрагмент шејдеру да се извршава по узорку у вишеузорачном фрагменту уместо једном по фрагменту. Побољшава квалитет графике на рачун перформанси. Само Vulkan 1.1+ уређаји подржавају ову екстензију.</string>
<string name="sample_shading_fraction">Удео сенчења узорка</string>
<string name="sample_shading_fraction_description">Интензитет проласка сенчења узорка. Веће вредности побољшавају квалитет више, али такође више смањују перформансе.</string>
<string name="veil_renderer">Рендерер</string>
<string name="sync_memory_operations">Синхронизација меморијских операција</string>
<string name="sync_memory_operations_description">Осигурава конзистентност података између рачунских и меморијских операција. Ова опција би требало да поправи проблеме у неким играма, али може смањити перформансе у неким случајевима. Чини се да су игре са Unreal Engine 4 највише погођене.</string>
<string name="buffer_reorder_disable">Онемогући преуређивање бафера</string>
<string name="buffer_reorder_disable_description">Када је означено, онемогућава преуређивање учитавања мапиране меморије што омогућава повезивање учитавања са одређеним цртањима. Може у неким случајевима смањити перформансе.</string>
<string name="veil_misc">CPU и меморија</string>
<string name="use_sync_core">Синхронизујте брзину језгре</string>
<string name="use_sync_core_description">Синхронизујте језгро Тицк Брзина брзине максималне брзине да бисте побољшали перформансе без измене стварне брзине игре.</string>
<string name="use_lru_cache">Омогући ЛРУ кеш</string>
<string name="use_lru_cache_description">Омогућите или онемогућите најмање недавно коришћене (ЛРУ) кеш меморије, све веће перформансе штедећи употребу процеса ЦПУ-а. Неке игре са њом имају проблеме, посебно тотк 1.2.1, тако да онемогућите ако се игра не покрене или се руши насумично.</string>
<string name="use_fast_cpu_time">Брзо време ЦПУ-а</string>
<string name="use_fast_cpu_time_description">Присиљава опомена ЦПУ-а како би се покренуло на вишим сатима, смањујући одређене ФПС ограничења. Ова опција је хакира и може проузроковати проблеме и слабији ЦПУ-ови могу видети смањене перформансе.</string>
<string name="custom_cpu_ticks">Прилагођени CPU тактови</string>
<string name="custom_cpu_ticks_description">Поставите прилагођену вредност CPU тактова. Веће вредности могу повећати перформансе, али могу изазвати залеђивање игре. Препоручује се опсег 77–21000.</string>
<string name="cpu_ticks">Тактови</string>
@@ -386,7 +395,9 @@
<string name="network">Мрежа</string>
<!-- Graphics settings strings -->
<string name="backend">Бекенд</string>
<string name="display">Приказ</string>
<string name="processing">Постпроцесирање</string>
<string name="renderer_accuracy">Ниво тачности</string>
<string name="renderer_resolution">Резолуција (ручно / прикључено)</string>
@@ -403,6 +414,8 @@
<string name="renderer_optimize_spirv_output_description">Оптимизира састављена схадер за побољшање ефикасности ГПУ-а.</string>
<string name="renderer_asynchronous_shaders">Користите асинхроне схадера</string>
<string name="renderer_asynchronous_shaders_description">Саставља схадера асинхроно. Ово може умањити затезаче, али могу такође да уведе пропусте.</string>
<string name="use_fast_gpu_time">Користите брзи ГПУ време</string>
<string name="use_fast_gpu_time_description">Присиљава већину игара да се покрене у својој највишој родној резолуцији. Ова опција је хаковна и може проузроковати проблеме.</string>
<string name="fast_gpu_time">ГПУ оверклок фактора</string>
<string name="fast_gpu_time_description">Користите 128 за максималне перформансе и 512 за максималну верност графике.</string>
<string name="renderer_reactive_flushing">Користите реактивно испирање</string>
@@ -733,8 +746,9 @@
<string name="clock_fast">Брзи (2000МХз)</string>
<!-- GPU overclock factors -->
<string name="fast_gpu_medium">Средња (256)</string>
<string name="fast_gpu_high">Висок (512)</string>
<string name="gpu_low">Ниско (128)</string>
<string name="gpu_medium">Средња (256)</string>
<string name="gpu_high">Висок (512)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">Целзијус</string>
@@ -83,7 +83,10 @@
<string name="show_fw_version_description">Відображає встановлену версію прошивки</string>
<!-- Eden\'s Veil -->
<string name="eden_veil">Завіса Eden</string>
<string name="eden_veil_description">Експериментальні налаштування для покращення продуктивності та сумісності. Ці налаштування можуть викликати збої, зокрема чорний екран.</string>
<string name="veil_extensions">Розширення GPU</string>
<string name="dyna_state">Розширений динамічний стан</string>
<string name="dyna_state_description">Керує кількістю функцій, які можна використовувати в розширеному динамічному стані. Вищі значення дозволяють більше функцій і можуть підвищити продуктивність, але можуть спричинити проблеми з деякими драйверами та постачальниками. Значення за замовчуванням може відрізнятися залежно від вашої системи та апаратних можливостей. Це значення можна змінювати, док не буде досягнуто стабільності та кращої якості зображення.</string>
<string name="disabled">Вимкнено</string>
@@ -93,18 +96,24 @@
<string name="provoking_vertex_description">Покращує освітлення та взаємодію з вершинами у деяких іграх. Лише для ГП з підтримкою Vulkan 1.0+.</string>
<string name="descriptor_indexing">Індексація дескрипторів</string>
<string name="descriptor_indexing_description">Покращує обробку текстур та буферів, а також шар перекладу Maxwell. Підтримується деякими GPU Vulkan 1.1 та всіма GPU Vulkan 1.2+.</string>
<string name="sample_shading">Шейдинг зразків</string>
<string name="sample_shading_description">Дозволяє шейдеру фрагментів виконуватися на кожен семпл у багатосемпловому фрагменті замість одного разу на фрагмент. Покращує якість графіки за рахунок продуктивності. Лише пристрої з Vulkan 1.1+ підтримують це розширення.</string>
<string name="sample_shading_fraction">Частка затінення зразка</string>
<string name="sample_shading_fraction_description">Інтенсивність проходу затінення зразка. Вищі значення покращують якість, але й сильніше знижують продуктивність.</string>
<string name="veil_renderer">Візуалізатор</string>
<string name="sync_memory_operations">Синхронізація операцій з пам\'яттю</string>
<string name="sync_memory_operations_description">Забезпечує узгодженість даних між обчислювальними операціями та операціями з пам\'яттю. Ця опція має виправляти проблеми в деяких іграх, але може знижувати продуктивність у деяких випадках. Ігри на Unreal Engine 4, здається, найбільш постраждалі.</string>
<string name="buffer_reorder_disable">Вимкнути переупорядкування буфера</string>
<string name="buffer_reorder_disable_description">Якщо позначено, вимикає переупорядкування завантажень відображеної пам\'яті, що дозволяє пов\'язувати завантаження з конкретними малюваннями. Може знизити продуктивність у деяких випадках.</string>
<string name="veil_misc">Процесор і пам\'ять</string>
<string name="use_sync_core">Синхронізувати швидкість ядра</string>
<string name="use_sync_core_description">Синхронізує швидкість ядра з максимальним відсотком швидкості для покращення продуктивності без зміни реальної швидкості гри.</string>
<string name="use_lru_cache">Увімкнути LRU-кеш</string>
<string name="use_lru_cache_description">Увімкніть або вимкніть кеш LRU (Least Recently Used) для покращення продуктивності шляхом зменшення навантаження на CPU. Деякі ігри (зокрема TotK 1.2.1) можуть працювати некоректно - вимкніть, якщо гра не запускається або раптово вилітає.</string>
<string name="use_fast_cpu_time">Швидкий час CPU</string>
<string name="use_fast_cpu_time_description">Змушує емульований процесор працювати на вищій тактовій частоті, зменшуючи деякі обмежувачі FPS. Ця опція нестабільна і може спричинити проблеми, а слабші CPU можуть мати знижену продуктивність.</string>
<string name="custom_cpu_ticks">Користувацькі такти CPU</string>
<string name="custom_cpu_ticks_description">Встановіть користувацьке значення тактів CPU. Вищі значення можуть покращити продуктивність, але також можуть спричинити зависання гри. Рекомендується діапазон 77–21000.</string>
<string name="cpu_ticks">Такти</string>
@@ -467,7 +476,9 @@
<string name="network">Мережа</string>
<!-- Graphics settings strings -->
<string name="backend">Бекенд</string>
<string name="display">Дисплей</string>
<string name="processing">Постобробка</string>
<string name="renderer_accuracy">Рівень точності</string>
<string name="renderer_resolution">Роздільна здатність (Портативний/Док)</string>
@@ -484,6 +495,8 @@
<string name="renderer_optimize_spirv_output_description">Оптимізує скомпільований шейдер для покращення ефективності GPU.</string>
<string name="renderer_asynchronous_shaders">Асинхронні шейдери</string>
<string name="renderer_asynchronous_shaders_description">Компілює шейдери асинхронно. Це може зменшити затримки, але також може спричинити графічні баги.</string>
<string name="use_fast_gpu_time">Використовувати швидкий час GPU</string>
<string name="use_fast_gpu_time_description">Змушує більшість ігор працювати з найвищою нативною роздільною здатністю. Цей параметр є нестабільним і може призвести до збоїв.</string>
<string name="fast_gpu_time">Фактор розгону GPU</string>
<string name="fast_gpu_time_description">Використовуйте 128 для максимальної продуктивності та 512 для максимальної графічної точності.</string>
<string name="renderer_reactive_flushing">Реактивне очищення</string>
@@ -861,8 +874,9 @@
<string name="clock_fast">Швидка (2000MHz)</string>
<!-- GPU overclock factors -->
<string name="fast_gpu_medium">Середній (256)</string>
<string name="fast_gpu_high">Високий (512)</string>
<string name="gpu_low">Низький (128)</string>
<string name="gpu_medium">Середній (256)</string>
<string name="gpu_high">Високий (512)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">Цельсій</string>
@@ -59,7 +59,10 @@
<string name="show_fw_version_description">Hiển thị phiên bản firmware đã cài đặt</string>
<!-- Eden\'s Veil -->
<string name="eden_veil">Mành che của Eden</string>
<string name="eden_veil_description">Cài đặt thử nghiệm để cải thiện hiệu suất và khả năng. Những cài đặt này có thể gây ra màn hình đen hoặc các vấn đề khác trong trò chơi.</string>
<string name="veil_extensions">Tiện ích mở rộng GPU</string>
<string name="dyna_state">Trạng thái động mở rộng</string>
<string name="dyna_state_description">Điều khiển số tính năng có thể được sử dụng trong Trạng thái Động Mở rộng. Giá trị cao hơn cho phép nhiều tính năng hơn và có thể tăng hiệu suất, nhưng có thể gây ra sự cố với một số trình điều khiển và nhà cung cấp. Giá trị mặc định có thể thay đổi tùy thuộc vào hệ thống và khả năng phần cứng của bạn. Giá trị này có thể được thay đổi cho đến khi đạt được độ ổn định và chất lượng hình ảnh tốt hơn.</string>
<string name="disabled">Đã tắt</string>
@@ -67,18 +70,24 @@
<string name="provoking_vertex_description">Cải thiện ánh sáng và xử lý đỉnh trong một số trò chơi. Chỉ được hỗ trợ trên GPU Vulkan 1.0+.</string>
<string name="descriptor_indexing">Lập chỉ mục bộ mô tả</string>
<string name="descriptor_indexing_description">Cải thiện xử lý kết cấu và bộ đệm, cũng như lớp dịch Maxwell. Được hỗ trợ bởi một số GPU Vulkan 1.1 và tất cả GPU Vulkan 1.2+.</string>
<string name="sample_shading">Tô bóng mẫu</string>
<string name="sample_shading_description">Cho phép fragment shader thực thi trên mỗi mẫu trong một fragment đa mẫu thay vì một lần mỗi fragment. Cải thiện chất lượng đồ họa với chi phí hiệu suất. Chỉ thiết bị Vulkan 1.1+ hỗ trợ tiện ích mở rộng này.</string>
<string name="sample_shading_fraction">Phần trăm tô bóng mẫu</string>
<string name="sample_shading_fraction_description">Cường độ của bước tô bóng mẫu. Giá trị cao hơn cải thiện chất lượng tốt hơn nhưng cũng giảm hiệu suất nhiều hơn.</string>
<string name="veil_renderer">Trình kết xuất</string>
<string name="sync_memory_operations">Đồng bộ hoá thao tác bộ nhớ</string>
<string name="sync_memory_operations_description">Đảm bảo tính nhất quán dữ liệu giữa các thao tác tính toán và bộ nhớ. Tùy chọn này nên khắc phục sự cố trong một số trò chơi, nhưng có thể làm giảm hiệu suất trong một số trường hợp. Các trò chơi với Unreal Engine 4 có vẻ bị ảnh hưởng nhiều nhất.</string>
<string name="buffer_reorder_disable">Tắt sắp xếp lại bộ đệm</string>
<string name="buffer_reorder_disable_description">Khi được chọn, sẽ tắt tính năng sắp xếp lại các lần tải lên bộ nhớ đã ánh xạ, cho phép liên kết các lần tải lên với các bản vẽ cụ thể. Có thể làm giảm hiệu suất trong một số trường hợp.</string>
<string name="veil_misc">CPU và Bộ nhớ</string>
<string name="use_sync_core">Đồng bộ tốc độ lõi</string>
<string name="use_sync_core_description">Đồng bộ tốc độ lõi với tỷ lệ phần trăm tốc độ tối đa để cải thiện hiệu suất mà không làm thay đổi tốc độ thực tế của trò chơi.</string>
<string name="use_lru_cache">Bật bộ nhớ đệm LRU</string>
<string name="use_lru_cache_description">Bật hoặc tắt bộ nhớ đệm LRU để cải thiện hiệu suất bằng cách tiết kiệm quy trình sử dụng CPU. Một số trò chơi như TotK 1.2.1 có vấn đề - hãy tắt nếu trò chơi không khởi động hoặc bị treo ngẫu nhiên.</string>
<string name="use_fast_cpu_time">Thời gian CPU nhanh</string>
<string name="use_fast_cpu_time_description">Buộc CPU mô phỏng chạy ở tốc độ xung nhịp cao hơn, giảm một số giới hạn FPS. Tùy chọn này không ổn định và có thể gây ra sự cố, và CPU yếu hơn có thể thấy hiệu suất giảm.</string>
<string name="custom_cpu_ticks">Tích CPU tùy chỉnh</string>
<string name="custom_cpu_ticks_description">Đặt giá trị tích CPU tùy chỉnh. Giá trị cao hơn có thể tăng hiệu suất, nhưng cũng có thể khiến trò chơi bị đơ. Phạm vi 7721000 được khuyến nghị.</string>
<string name="cpu_ticks">Tích</string>
@@ -362,7 +371,9 @@
<string name="network">Mạng</string>
<!-- Graphics settings strings -->
<string name="backend">Backend</string>
<string name="display">Hiển thị</string>
<string name="processing">Hậu xử lý</string>
<string name="renderer_accuracy">Mức độ chính xác</string>
<string name="renderer_resolution">Độ phân giải (Handheld/Docked)</string>
@@ -379,6 +390,8 @@
<string name="renderer_optimize_spirv_output_description">Tối ưu hóa shader đã biên dịch để cải thiện hiệu suất GPU.</string>
<string name="renderer_asynchronous_shaders">Dùng các shader bất đồng bộ</string>
<string name="renderer_asynchronous_shaders_description">Biên dịch shader không đồng bộ. Điều này có thể giảm giật lag nhưng cũng có thể gây ra lỗi đồ họa.</string>
<string name="use_fast_gpu_time">Sử dụng thời gian GPU nhanh</string>
<string name="use_fast_gpu_time_description">Buộc hầu hết các trò chơi chạy ở độ phân giải gốc cao nhất. Tùy chọn này có thể gây ra sự cố.</string>
<string name="fast_gpu_time">Hệ số ép xung GPU</string>
<string name="fast_gpu_time_description">Sử dụng 128 để có hiệu suất tối đa và 512 để có độ trung thực đồ họa tối đa.</string>
<string name="renderer_reactive_flushing">Bật xả tương ứng</string>
@@ -607,8 +620,9 @@
<string name="clock_fast">Nhanh (2000MHz)</string>
<!-- GPU overclock factors -->
<string name="fast_gpu_medium">Trung bình (256)</string>
<string name="fast_gpu_high">Cao (512)</string>
<string name="gpu_low">Thấp (128)</string>
<string name="gpu_medium">Trung bình (256)</string>
<string name="gpu_high">Cao (512)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">Celsius</string>
@@ -80,7 +80,10 @@
<string name="show_fw_version_description">显示已安装的固件版本</string>
<!-- Eden\'s Veil -->
<string name="eden_veil">伊甸之幕</string>
<string name="eden_veil_description">实验性设置以提高性能和能力。这些设置可能会导致黑屏或其他游戏问题。</string>
<string name="veil_extensions">GPU扩展</string>
<string name="dyna_state">扩展动态状态</string>
<string name="dyna_state_description">控制扩展动态状态中可使用的功能数量。数值越高,允许的功能越多,并可能提高性能,但可能会导致某些驱动程序和供应商出现问题。默认值可能因系统和硬件能力而异。可以更改此值,直到实现稳定性和更好的视觉质量。</string>
<string name="disabled">已禁用</string>
@@ -90,18 +93,24 @@
<string name="provoking_vertex_description">改善某些游戏中的光照和顶点处理。仅支持Vulkan 1.0+ GPU。</string>
<string name="descriptor_indexing">描述符索引</string>
<string name="descriptor_indexing_description">改进纹理和缓冲区处理以及Maxwell转换层。部分Vulkan 1.1 GPU和所有Vulkan 1.2+ GPU支持。</string>
<string name="sample_shading">采样着色</string>
<string name="sample_shading_description">允许片段着色器在多采样片段中每个样本执行一次,而不是每个片段执行一次。以提高性能为代价改善图形质量。仅Vulkan 1.1+设备支持此扩展。</string>
<string name="sample_shading_fraction">采样着色比例</string>
<string name="sample_shading_fraction_description">采样着色处理的强度。值越高,质量改善越多,但性能降低也越明显。</string>
<string name="veil_renderer">渲染器</string>
<string name="sync_memory_operations">同步内存操作</string>
<string name="sync_memory_operations_description">确保计算和内存操作之间的数据一致性。 此选项应能修复某些游戏中的问题,但在某些情况下可能会降低性能。 使用Unreal Engine 4的游戏似乎受影响最大。</string>
<string name="buffer_reorder_disable">禁用缓冲重排序</string>
<string name="buffer_reorder_disable_description">勾选时,禁用映射内存上传的重排序功能,允许将上传与特定绘制关联。在某些情况下可能会降低性能。</string>
<string name="veil_misc">CPU和内存</string>
<string name="use_sync_core">同步核心速度</string>
<string name="use_sync_core_description">将核心速度与最大速度百分比同步,在不改变游戏实际速度的情况下提高性能。</string>
<string name="use_lru_cache">启用LRU缓存</string>
<string name="use_lru_cache_description">启用或禁用LRU缓存,通过节省CPU进程使用来提高性能。某些游戏可能存在问题,特别是TotK 1.2.1,如果游戏无法启动或随机崩溃,请禁用此选项。</string>
<string name="use_fast_cpu_time">快速 CPU 时间</string>
<string name="use_fast_cpu_time_description">强制模拟 CPU 以更高的时钟速度运行,减少某些 FPS 限制器。此选项不稳定,可能会导致问题,较弱的 CPU 可能会看到性能下降。</string>
<string name="custom_cpu_ticks">自定义CPU时钟</string>
<string name="custom_cpu_ticks_description">设置自定义的CPU时钟值。更高的值可能提高性能,但也可能导致游戏卡顿。建议范围为77-21000。</string>
<string name="cpu_ticks">时钟</string>
@@ -458,7 +467,9 @@
<string name="network">网络</string>
<!-- Graphics settings strings -->
<string name="backend">后端</string>
<string name="display">显示</string>
<string name="processing">后处理</string>
<string name="renderer_accuracy">精度等级</string>
<string name="renderer_resolution">分辨率 (掌机模式/主机模式)</string>
@@ -475,6 +486,8 @@
<string name="renderer_optimize_spirv_output_description">优化编译后的着色器以提高GPU效率。</string>
<string name="renderer_asynchronous_shaders">使用异步着色器</string>
<string name="renderer_asynchronous_shaders_description">异步编译着色器。这可能会减少卡顿,但也可能会导致图形错误。</string>
<string name="use_fast_gpu_time">使用快速GPU时间</string>
<string name="use_fast_gpu_time_description">强制大多数游戏以最高原生分辨率运行。此选项不稳定,可能导致问题。</string>
<string name="fast_gpu_time">GPU 超频系数</string>
<string name="fast_gpu_time_description">使用 128 以获得最大性能,使用 512 以获得最大图形保真度。</string>
<string name="renderer_reactive_flushing">启用反应性刷新</string>
@@ -852,8 +865,9 @@
<string name="clock_fast">快速 (2000MHz)</string>
<!-- GPU overclock factors -->
<string name="fast_gpu_medium"> (256)</string>
<string name="fast_gpu_high"> (512)</string>
<string name="gpu_low"> (128)</string>
<string name="gpu_medium"> (256)</string>
<string name="gpu_high">高 (512)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">摄氏度</string>
@@ -83,7 +83,10 @@
<string name="show_fw_version_description">顯示已安裝的韌體版本</string>
<!-- Eden\'s Veil -->
<string name="eden_veil">伊甸之幕</string>
<string name="eden_veil_description">實驗性設定以提高效能和相容性。這些設定可能會導致黑螢幕或其他遊戲問題。</string>
<string name="veil_extensions">GPU擴充功能</string>
<string name="dyna_state">擴展動態狀態</string>
<string name="dyna_state_description">控制擴展動態狀態中可使用的功能數量。數值越高,允許的功能越多,並可能提高效能,但可能會導致某些驅動程式和硬體出現問題。預設值可能因系統和硬體能力而異。可以變更此值,直到獲得更佳的穩定性和更好的視覺品質。</string>
<string name="disabled">已停用</string>
@@ -93,18 +96,24 @@
<string name="provoking_vertex_description">改善某些遊戲中的光照和頂點處理。僅支援Vulkan 1.0+ GPU。</string>
<string name="descriptor_indexing">描述符索引</string>
<string name="descriptor_indexing_description">改進紋理和緩衝區處理以及Maxwell轉換層。部分Vulkan 1.1 GPU和所有Vulkan 1.2+ GPU支援。</string>
<string name="sample_shading">取樣著色</string>
<string name="sample_shading_description">允許片段著色器在多取樣片段中每個樣本執行一次,而不是每個片段執行一次。以提高效能為代價改善圖形品質。僅Vulkan 1.1+裝置支援此擴充功能。</string>
<string name="sample_shading_fraction">採樣著色比例</string>
<string name="sample_shading_fraction_description">採樣著色處理的強度。數值越高,品質改善越多,但效能降低也越明顯。</string>
<string name="veil_renderer">渲染器</string>
<string name="sync_memory_operations">同步記憶體操作</string>
<string name="sync_memory_operations_description">確保計算和記憶體操作之間的資料一致性。 此選項應能修復某些遊戲中的問題,但在某些情況下可能會降低效能。 使用Unreal Engine 4的遊戲似乎受影響最大。</string>
<string name="buffer_reorder_disable">停用緩衝區重新排序</string>
<string name="buffer_reorder_disable_description">勾選時,停用映射記憶體上傳的重新排序功能,允許將上傳與特定繪製關聯。某些情況下可能會降低效能。</string>
<string name="veil_misc">CPU與記憶體</string>
<string name="use_sync_core">同步核心速度</string>
<string name="use_sync_core_description">將核心速度與最大速度百分比同步,在不改變遊戲實際速度的情況下提高效能。</string>
<string name="use_lru_cache">啟用LRU快取</string>
<string name="use_lru_cache_description">啟用或停用LRU快取,透過節省CPU進程使用率來提高效能。某些遊戲可能存在問題,特別是薩爾達傳說:王國之淚 v1.2.1(更新),如果遊戲無法啟動或隨機崩潰,請停用此選項。</string>
<string name="use_fast_cpu_time">快速 CPU 時間</string>
<string name="use_fast_cpu_time_description">強制模擬 CPU 以更高的時脈運行,減少某些 FPS 限制。此選項不穩定,可能會導致問題,較弱的 CPU 可能會看到效能下降。</string>
<string name="custom_cpu_ticks">自訂CPU時脈</string>
<string name="custom_cpu_ticks_description">自訂CPU時脈。更高的值可能提高效能,但也可能導致遊戲卡死。建議範圍為77-21000。</string>
<string name="cpu_ticks">時脈</string>
@@ -461,7 +470,9 @@
<string name="network">網路</string>
<!-- Graphics settings strings -->
<string name="backend">後端</string>
<string name="display">顯示</string>
<string name="processing">後處理</string>
<string name="renderer_accuracy">準確度層級</string>
<string name="renderer_resolution">解析度 (手提/底座)</string>
@@ -478,6 +489,8 @@
<string name="renderer_optimize_spirv_output_description">最佳化編譯後的著色器以提高GPU效率。</string>
<string name="renderer_asynchronous_shaders">使用非同步著色器</string>
<string name="renderer_asynchronous_shaders_description">非同步編譯著色器。這可能會減少卡頓,但也可能導致圖形錯誤。</string>
<string name="use_fast_gpu_time">使用快速GPU時間</string>
<string name="use_fast_gpu_time_description">強制大多數遊戲以最高原生解析度運行。此選項不穩定,可能導致問題。</string>
<string name="fast_gpu_time">GPU 超頻係數</string>
<string name="fast_gpu_time_description">使用 128 以獲得最大效能,使用 512 以獲得最大圖形保真度。</string>
<string name="renderer_reactive_flushing">使用重新啟用排清</string>
@@ -855,8 +868,9 @@
<string name="clock_fast">快速 (2000MHz)</string>
<!-- GPU overclock factors -->
<string name="fast_gpu_medium"> (256)</string>
<string name="fast_gpu_high"> (512)</string>
<string name="gpu_low"> (128)</string>
<string name="gpu_medium"> (256)</string>
<string name="gpu_high">高 (512)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">攝氏度</string>
+6 -11
View File
@@ -34,7 +34,6 @@
</integer-array>
<string-array name="clockNames">
<item>@string/off</item>
<item>@string/clock_boost</item>
<item>@string/clock_fast</item>
</string-array>
@@ -42,7 +41,6 @@
<integer-array name="clockValues">
<item>0</item>
<item>1</item>
<item>2</item>
</integer-array>
<string-array name="languageNames">
@@ -504,9 +502,6 @@
<item>3</item>
<item>4</item>
<item>5</item>
<item>6</item>
<item>7</item>
<item>8</item>
</integer-array>
<string-array name="verticalAlignmentEntries">
@@ -553,9 +548,9 @@
</integer-array>
<string-array name="gpuEntries">
<item>@string/off</item>
<item>@string/fast_gpu_medium</item>
<item>@string/fast_gpu_high</item>
<item>@string/gpu_low</item>
<item>@string/gpu_medium</item>
<item>@string/gpu_high</item>
</string-array>
<integer-array name="gpuValues">
@@ -576,9 +571,9 @@
<string-array name="dynaStateEntries">
<item>@string/disabled</item>
<item>ExtendedDynamicState 1</item>
<item>ExtendedDynamicState 2</item>
<item>ExtendedDynamicState 3</item>
<item>1</item>
<item>2</item>
<item>3</item>
</string-array>
<integer-array name="dynaStateValues">
+74 -75
View File
@@ -88,24 +88,60 @@
<string name="show_fw_version_description">Display the installed firmware version</string>
<!-- Eden\'s Veil -->
<string name="eden_veil">Eden\'s Veil</string>
<string name="eden_veil_description">Experimental settings to improve performance and capability. These settings may cause black screens or other game issues.</string>
<string name="veil_extensions">GPU Extensions</string>
<string name="dyna_state">Extended Dynamic State</string>
<string name="dyna_state_description">Controls the number of features that can be used in Extended Dynamic State. Higher numbers allow for more features and can increase performance, but may cause issues with some drivers and vendors. The default value may vary depending on your system and hardware capabilities. This value can be changed until stability and a better visual quality are achieved.</string>
<string name="disabled">Disabled</string>
<string name="vertex_input_dynamic_state">Vertex Input Dynamic State</string>
<string name="vertex_input_dynamic_state_description">Enables vertex input dynamic state feature for better quality and performance.</string>
<string name="provoking_vertex">Provoking Vertex</string>
<string name="provoking_vertex_description">Improves lighting and vertex handling in certain games. Only supported on Vulkan 1.0+ GPUs.</string>
<string name="descriptor_indexing">Descriptor Indexing</string>
<string name="descriptor_indexing_description">Improves texture and buffer handling, as well as the Maxwell translation layer. Supported by some Vulkan 1.1 GPUs and all Vulkan 1.2+ GPUs.</string>
<string name="sample_shading">Sample Shading</string>
<string name="sample_shading_description">Allows the fragment shader to execute per sample in a multi-sampled fragment instead once per fragment. Improves graphics quality at the cost of some performance. Only Vulkan 1.1+ devices support this extension.</string>
<string name="sample_shading_fraction">Sample Shading Fraction</string>
<string name="sample_shading_fraction_description">The intensity of the sample shading pass. Higher values improve quality more but also reduce performance to a greater extent.</string>
<string name="veil_renderer">Renderer</string>
<string name="sync_memory_operations">Sync Memory Operations</string>
<string name="sync_memory_operations_description">Ensures data consistency between compute and memory operations. This option should fix issues in some games, but may also reduce performance in some cases. Unreal Engine 4 games often see the most significant changes thereof.</string>
<string name="buffer_reorder_disable">Disable Buffer Reorder</string>
<string name="buffer_reorder_disable_description">When checked, disables reordering of mapped memory uploads which allows to associate uploads with specific draws. May reduce performance in some cases.</string>
<string name="veil_misc">CPU and Memory</string>
<string name="use_sync_core">Synchronize Core Speed</string>
<string name="use_sync_core_description">Synchronize the core tick speed to the maximum speed percentage to improve performance without altering the game\'s actual speed.</string>
<string name="use_lru_cache">Enable LRU Cache</string>
<string name="use_lru_cache_description">Enable or disable the Least Recently Used (LRU) cache, increasing performance by saving CPU process usage. Some games may see issues with this setting, so disable it if the game doesn\'t boot or crashes randomly.</string>
<string name="use_fast_cpu_time">Fast CPU Time</string>
<string name="use_fast_cpu_time_description">Forces the emulated CPU to run at a higher clock, reducing certain FPS limiters. This option is hacky and may cause issues, and weaker CPUs may see reduced performance.</string>
<string name="custom_cpu_ticks">Custom CPU Ticks</string>
<string name="custom_cpu_ticks_description">Set a custom value of CPU ticks. Higher values can increase performance, but may also cause the game to freeze. A range of 7721000 is recommended.</string>
<string name="cpu_ticks">Ticks</string>
<string name="skip_cpu_inner_invalidation">Skip CPU Inner Invalidation</string>
<string name="skip_cpu_inner_invalidation_description">Skips certain CPU-side cache invalidations during memory updates, reducing CPU usage and improving it\'s performance. This may cause glitches or crashes on some games.</string>
<string name="cpuopt_unsafe_host_mmu">Enable Host MMU Emulation</string>
<string name="cpuopt_unsafe_host_mmu_description">This optimization speeds up memory accesses by the guest program. Enabling it causes guest memory reads/writes to be done directly into memory and make use of Host\'s MMU. Disabling this forces all memory accesses to use Software MMU Emulation.</string>
<string name="fast_cpu_time">CPU Clock</string>
<string name="fast_cpu_time_description">Use Boost (1700MHz) to run at the Switch\'s highest native clock, or Fast (2000MHz) to run at 2x clock.</string>
<string name="memory_layout">Memory Layout</string>
<string name="memory_layout_description">(EXPERIMENTAL) Change the emulated memory layout. This setting will not increase performance, but may help with games utilizing high resolutions via mods. Do not use on phones with 8GB of RAM or less. Only works on the Dynarmic (JIT) backend.</string>
<string name="dma_accuracy">DMA Accuracy</string>
<string name="dma_accuracy_description">Controls the DMA precision accuracy. Safe precision can fix issues in some games, but it can also impact performance in some cases. If unsure, leave this on Default.</string>
<string name="debug_knobs">Debug knobs</string>
<string name="debug_knobs_description">For development use only.</string>
<string name="debug_knobs_hint">0 to 65535</string>
<!-- Shader Backend -->
<string name="shader_backend">Shader Backend</string>
<string name="shader_backend_description">Choose how shaders are compiled and translated for your GPU.</string>
<string name="shader_backend_glsl">GLSL</string>
<string name="shader_backend_glasm">GLASM</string>
<string name="shader_backend_spirv">SPIRV</string>
<string name="shader_backend_spirv">Spir-V</string>
<!-- NVDEC Emulation -->
<string name="nvdec_emulation">NVDEC Emulation</string>
@@ -114,7 +150,7 @@
<string name="nvdec_emulation_gpu">GPU</string>
<string name="nvdec_emulation_none">None</string>
<!-- Optimize SPIRV output -->
<!-- Optimize Spir-V output -->
<string name="never">Never</string>
<string name="on_load">On Load</string>
<string name="always">Always</string>
@@ -437,15 +473,6 @@
<string name="use_custom_rtc_description">Allows you to set a custom real-time clock separate from your current system time.</string>
<string name="set_custom_rtc">Set custom RTC</string>
<!-- CPU -->
<string name="fast_cpu_time">CPU Overclock</string>
<string name="fast_cpu_time_description">Forces the emulated CPU to run at a higher clock, reducing certain FPS limiters. Use Boost (1700MHz) to run at the Switch\'s highest native clock, or Fast (2000MHz) to run at 2x clock.</string>
<string name="custom_cpu_ticks">Custom CPU Ticks</string>
<string name="custom_cpu_ticks_description">Set a custom value of CPU ticks. Higher values can increase performance, but may also cause the game to freeze. A range of 7721000 is recommended.</string>
<string name="cpu_ticks">Ticks</string>
<string name="memory_layout">Memory Layout</string>
<string name="memory_layout_description">(EXPERIMENTAL) Change the emulated memory layout. This setting will not increase performance, but may help with games utilizing high resolutions via mods. Do not use on phones with 8GB of RAM or less. Only works on the Dynarmic (JIT) backend.</string>
<string name="generate">Generate</string>
<!-- Network settings strings -->
@@ -456,73 +483,35 @@
<string name="network">Network</string>
<!-- Graphics settings strings -->
<string name="backend">Backend</string>
<string name="display">Display</string>
<string name="processing">Post-Processing</string>
<string name="renderer_accuracy">Accuracy level</string>
<string name="renderer_resolution">Resolution (Handheld/Docked)</string>
<string name="renderer_vsync">VSync mode</string>
<string name="shader_backend">Shader Backend</string>
<string name="shader_backend_description">Choose how shaders are compiled and translated for your GPU.</string>
<string name="renderer_screen_layout">Orientation</string>
<string name="renderer_aspect_ratio">Aspect ratio</string>
<string name="renderer_scaling_filter">Window adapting filter</string>
<string name="fsr_sharpness">FSR sharpness</string>
<string name="fsr_sharpness_description">Determines how sharpened the image will look while using FSR\'s dynamic contrast</string>
<string name="renderer_anti_aliasing">Anti-aliasing method</string>
<string name="renderer_optimize_spirv_output">Optimize SPIRV output</string>
<string name="renderer_optimize_spirv_output_description">Optimizes compiled shaders to improve GPU efficiency, but may introduce longer loading times and initial slowdowns.</string>
<string name="advanced">Advanced</string>
<string name="renderer_accuracy">Accuracy level</string>
<string name="dma_accuracy">DMA Accuracy</string>
<string name="dma_accuracy_description">Controls the DMA precision accuracy. Safe precision can fix issues in some games, but it can also impact performance in some cases. If unsure, leave this on Default.</string>
<string name="anisotropic_filtering">Anisotropic filtering</string>
<string name="anisotropic_filtering_description">Improves the quality of textures when viewed at oblique angles</string>
<string name="vram_usage_mode">VRAM Usage Mode</string>
<string name="vram_usage_mode_description">Control how aggressively the emulator allocates and frees GPU memory.</string>
<string name="accelerate_astc">ASTC Decoding Method</string>
<string name="accelerate_astc_description">Pick how ASTC-compressed textures are decoded for rendering: CPU (slow, safe), GPU (fast, recommended), or CPU Async (no stutters, may cause issues)</string>
<string name="astc_recompression">ASTC Recompression Method</string>
<string name="astc_recompression_description">Choose how ASTC textures are recompressed to improve compatibility and performance. Enabling this option saves VRAM but may lower texture quality.</string>
<string name="sync_memory_operations">Sync Memory Operations</string>
<string name="sync_memory_operations_description">Ensures data consistency between compute and memory operations. This option should fix issues in some games, but may also reduce performance in some cases. Unreal Engine 4 games often see the most significant changes thereof.</string>
<string name="use_disk_shader_cache">Disk shader cache</string>
<string name="use_disk_shader_cache_description">Reduces stuttering by locally storing and loading generated shaders.</string>
<string name="renderer_force_max_clock">Force maximum clocks (Adreno only)</string>
<string name="renderer_force_max_clock_description">Forces the GPU to run at the maximum possible clocks (thermal constraints will still be applied).</string>
<string name="renderer_reactive_flushing">Use reactive flushing</string>
<string name="renderer_reactive_flushing_description">Improves rendering accuracy in some games at the cost of performance.</string>
<string name="hacks">Hacks</string>
<string name="fast_gpu_time">Fast GPU Time</string>
<string name="fast_gpu_time_description">Forces most games to run at their highest native resolution. Use 256 for maximal performance and 512 for maximal graphics fidelity.</string>
<string name="skip_cpu_inner_invalidation">Skip CPU Inner Invalidation</string>
<string name="skip_cpu_inner_invalidation_description">Skips certain CPU-side cache invalidations during memory updates, reducing CPU usage and improving it\'s performance. This may cause glitches or crashes on some games.</string>
<string name="renderer_optimize_spirv_output">Optimize Spir-V output</string>
<string name="renderer_optimize_spirv_output_description">Optimizes compiled shaders to improve GPU efficiency, but may introduce longer loading times and initial slowdowns.</string>
<string name="renderer_asynchronous_shaders">Use asynchronous shaders</string>
<string name="renderer_asynchronous_shaders_description">Compiles shaders asynchronously. This may reduce stutters but may also introduce glitches.</string>
<string name="extensions">Extensions</string>
<string name="dyna_state">Extended Dynamic State</string>
<string name="dyna_state_description">Controls the number of features that can be used in Extended Dynamic State. Higher numbers allow for more features and can increase performance, but may cause issues with some drivers and vendors.</string>
<string name="disabled">Disabled</string>
<string name="vertex_input_dynamic_state">Vertex Input Dynamic State</string>
<string name="vertex_input_dynamic_state_description">Enables vertex input dynamic state feature for better quality and performance.</string>
<string name="provoking_vertex">Provoking Vertex</string>
<string name="provoking_vertex_description">Improves lighting and vertex handling in certain games. Only supported on Vulkan 1.0+ GPUs.</string>
<string name="descriptor_indexing">Descriptor Indexing</string>
<string name="descriptor_indexing_description">Improves texture and buffer handling, as well as the Maxwell translation layer. Supported by some Vulkan 1.1 GPUs and all Vulkan 1.2+ GPUs.</string>
<string name="sample_shading_fraction">Sample Shading</string>
<string name="sample_shading_fraction_description">Allows the fragment shader to execute per sample in a multi-sampled fragment instead once per fragment. Improves graphics quality at the cost of some performance.</string>
<string name="display">Display</string>
<string name="renderer_screen_layout">Orientation</string>
<string name="renderer_aspect_ratio">Aspect ratio</string>
<string name="vertical_alignment">Vertical alignment</string>
<string name="picture_in_picture">Picture in Picture</string>
<string name="picture_in_picture_description">Minimize window when placed in the background</string>
<string name="use_fast_gpu_time">Use Fast GPU Time</string>
<string name="use_fast_gpu_time_description">Forces most games to run at their highest native resolution. This option is hacky and may cause issues.</string>
<string name="fast_gpu_time">GPU Overclock Factor</string>
<string name="fast_gpu_time_description">Use 128 for maximal performance and 512 for maximal graphics fidelity.</string>
<string name="renderer_reactive_flushing">Use reactive flushing</string>
<string name="renderer_reactive_flushing_description">Improves rendering accuracy in some games at the cost of performance.</string>
<string name="use_disk_shader_cache">Disk shader cache</string>
<string name="use_disk_shader_cache_description">Reduces stuttering by locally storing and loading generated shaders.</string>
<string name="anisotropic_filtering">Anisotropic filtering</string>
<string name="anisotropic_filtering_description">Improves the quality of textures when viewed at oblique angles</string>
<string name="warning_resolution">Resolution scaling to 2x or higher is known to cause issues, and may result in significant slowdowns of your device.</string>
@@ -535,8 +524,6 @@
<string name="renderer_api">API</string>
<string name="renderer_debug">Graphics debugging</string>
<string name="renderer_debug_description">Sets the graphics API to a slow debugging mode.</string>
<string name="patch_old_qcom_drivers">BCn Texture Patching</string>
<string name="patch_old_qcom_drivers_description">Override automatic BCn texture format detection on Adreno GPUs. Normally auto-detected based on Android version (enabled on API 28+).</string>
<string name="fastmem">Fastmem</string>
<string name="log">Logging</string>
@@ -674,7 +661,6 @@
<string name="select_gpu_driver_default">Default</string>
<string name="select_gpu_driver_error">Invalid driver selected</string>
<string name="driver_already_installed">Driver already installed</string>
<string name="installed_label">%1$s (Installed)</string>
<string name="system_gpu_driver">System GPU driver</string>
<string name="installing_driver">Installing driver…</string>
@@ -895,9 +881,9 @@
<string name="clock_fast">Fast (2000MHz)</string>
<!-- GPU overclock factors -->
<string name="off">Off</string>
<string name="fast_gpu_medium">Medium (256)</string>
<string name="fast_gpu_high">High (512)</string>
<string name="gpu_low">Low (128)</string>
<string name="gpu_medium">Medium (256)</string>
<string name="gpu_high">High (512)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">Celsius</string>
@@ -947,17 +933,27 @@
<string name="dma_accuracy_unsafe">Unsafe</string>
<string name="dma_accuracy_safe">Safe</string>
<!-- ASTC Decoding Method -->
<string name="accelerate_astc">ASTC Decoding Method</string>
<string name="accelerate_astc_description">Pick how ASTC-compressed textures are decoded for rendering: CPU (slow, safe), GPU (fast, recommended), or CPU Async (no stutters, may cause issues)</string>
<!-- ASTC Decoding Method Choices -->
<string name="accelerate_astc_cpu">CPU</string>
<string name="accelerate_astc_gpu">GPU</string>
<string name="accelerate_astc_async">CPU Asynchronously</string>
<!-- ASTC Recompression Method -->
<string name="astc_recompression">ASTC Recompression Method</string>
<string name="astc_recompression_description">Choose how ASTC textures are recompressed to improve compatibility and performance. Enabling this option saves VRAM but may lower texture quality.</string>
<!-- ASTC Recompression Method Choices -->
<string name="astc_recompression_uncompressed">Uncompressed</string>
<string name="astc_recompression_bc1">BC1 (Low Quality)</string>
<string name="astc_recompression_bc3">BC3 (Medium Quality)</string>
<!-- ASTC Recompression Method Choices -->
<string name="vram_usage_mode">VRAM Usage Mode</string>
<string name="vram_usage_mode_description">Control how aggressively the emulator allocates and frees GPU memory.</string>
<string name="vram_usage_conservative">Conservative</string>
<string name="vram_usage_aggressive">Aggressive</string>
@@ -1107,12 +1103,15 @@
<string name="gray">Gray</string>
<!-- Picture-In-Picture -->
<string name="picture_in_picture">Picture in Picture</string>
<string name="picture_in_picture_description">Minimize window when placed in the background</string>
<string name="pause">Pause</string>
<string name="play">Play</string>
<string name="mute">Mute</string>
<string name="unmute">Unmute</string>
<!-- Emulation vertical alignment -->
<string name="vertical_alignment">Vertical alignment</string>
<string name="top">Top</string>
<string name="center">Center</string>
<string name="bottom">Bottom</string>
@@ -272,31 +272,35 @@ void CommandBuffer::GenerateBiquadFilterCommand(const s32 node_id, EffectInfoBas
effect_info.GetStateBuffer() + channel * sizeof(VoiceState::BiquadFilterState))};
if (behavior->IsEffectInfoVersion2Supported()) {
const auto& parameter{
const auto& p{
*reinterpret_cast<BiquadFilterInfo::ParameterVersion2*>(effect_info.GetParameter())};
if (parameter.state <= EffectInfoBase::ParameterState::Updated && IsChannelCountValid(parameter.channel_count) && channel >= 0 && channel < parameter.channel_count) {
cmd.input = buffer_offset + parameter.inputs[channel];
cmd.output = buffer_offset + parameter.outputs[channel];
// Convert float coefficients to Q2.14 fixed-point as expected by the legacy DSP path.
cmd.biquad.b[0] = ToQ14Clamped(parameter.b[0]);
cmd.biquad.b[1] = ToQ14Clamped(parameter.b[1]);
cmd.biquad.b[2] = ToQ14Clamped(parameter.b[2]);
cmd.biquad.a[0] = ToQ14Clamped(parameter.a[0]);
cmd.biquad.a[1] = ToQ14Clamped(parameter.a[1]);
if (!IsChannelCountValid(p.channel_count) || channel < 0 || channel >= p.channel_count) {
return;
}
cmd.input = buffer_offset + p.inputs[channel];
cmd.output = buffer_offset + p.outputs[channel];
// Convert float coefficients to Q2.14 fixed-point as expected by the legacy DSP path.
cmd.biquad.b[0] = ToQ14Clamped(p.b[0]);
cmd.biquad.b[1] = ToQ14Clamped(p.b[1]);
cmd.biquad.b[2] = ToQ14Clamped(p.b[2]);
cmd.biquad.a[0] = ToQ14Clamped(p.a[0]);
cmd.biquad.a[1] = ToQ14Clamped(p.a[1]);
} else {
const auto& parameter{
const auto& p{
*reinterpret_cast<BiquadFilterInfo::ParameterVersion1*>(effect_info.GetParameter())};
if (IsChannelCountValid(parameter.channel_count) && channel >= 0 && channel < parameter.channel_count) {
cmd.input = buffer_offset + parameter.inputs[channel];
cmd.output = buffer_offset + parameter.outputs[channel];
cmd.biquad.b = parameter.b;
cmd.biquad.a = parameter.a;
if (!IsChannelCountValid(p.channel_count) || channel < 0 || channel >= p.channel_count) {
return;
}
cmd.input = buffer_offset + p.inputs[channel];
cmd.output = buffer_offset + p.outputs[channel];
cmd.biquad.b = p.b;
cmd.biquad.a = p.a;
}
// Effects always use the fixed-point coefficient path on the DSP.
@@ -374,10 +374,8 @@ void CommandGenerator::GenerateBiquadFilterEffectCommand(const s16 buffer_offset
LOG_ERROR(Service_Audio, "Biquad filter parameter is null");
return;
}
if (parameter->state <= EffectInfoBase::ParameterState::Updated) {
param_state = parameter->state;
channel_count = parameter->channel_count;
}
param_state = parameter->state;
channel_count = parameter->channel_count;
} else {
const auto* parameter =
reinterpret_cast<const BiquadFilterInfo::ParameterVersion1*>(effect_info.GetParameter());
+1
View File
@@ -32,6 +32,7 @@ void SinkStream::AppendBuffer(SinkBuffer& buffer, std::span<s16> samples) {
auto yuzu_volume = Settings::Volume();
if (yuzu_volume > 1.0f)
yuzu_volume = 0.6f + 20.0f * std::log10(yuzu_volume);
yuzu_volume = std::max(yuzu_volume, 0.001f);
auto const volume = system_volume * device_volume * yuzu_volume;
if (system_channels > device_channels) {
+1 -1
View File
@@ -251,7 +251,7 @@ else()
target_link_libraries(common PUBLIC Boost::headers)
endif()
target_link_libraries(common PUBLIC Boost::filesystem Boost::context)
target_link_libraries(common PUBLIC Boost::filesystem)
if (lz4_ADDED)
target_include_directories(common PRIVATE ${lz4_SOURCE_DIR}/lib)
+69 -88
View File
@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -8,87 +5,47 @@
#include "common/assert.h"
#include "common/fiber.h"
#include "common/virtual_buffer.h"
#include <boost/context/detail/fcontext.hpp>
#define MCO_USE_VMEM_ALLOCATOR
#define MINICORO_IMPL
#include "common/minicoro.h"
namespace Common {
constexpr std::size_t default_stack_size = 512 * 1024;
struct Fiber::FiberImpl {
FiberImpl() : stack{default_stack_size}, rewind_stack{default_stack_size} {}
VirtualBuffer<u8> stack;
VirtualBuffer<u8> rewind_stack;
FiberImpl() {}
std::mutex guard;
std::function<void()> entry_point;
std::function<void()> rewind_point;
std::shared_ptr<Fiber> previous_fiber;
bool is_thread_fiber{};
bool released{};
bool is_thread_fiber{};
Fiber* next_fiber{};
Fiber** next_fiber_ptr;
std::function<void()> entry_point;
u8* stack_limit{};
u8* rewind_stack_limit{};
boost::context::detail::fcontext_t context{};
boost::context::detail::fcontext_t rewind_context{};
mco_coro* context;
};
void Fiber::SetRewindPoint(std::function<void()>&& rewind_func) {
impl->rewind_point = std::move(rewind_func);
}
void Fiber::Start(boost::context::detail::transfer_t& transfer) {
ASSERT(impl->previous_fiber != nullptr);
impl->previous_fiber->impl->context = transfer.fctx;
impl->previous_fiber->impl->guard.unlock();
impl->previous_fiber.reset();
impl->entry_point();
UNREACHABLE();
}
void Fiber::OnRewind([[maybe_unused]] boost::context::detail::transfer_t& transfer) {
ASSERT(impl->context != nullptr);
impl->context = impl->rewind_context;
impl->rewind_context = nullptr;
u8* tmp = impl->stack_limit;
impl->stack_limit = impl->rewind_stack_limit;
impl->rewind_stack_limit = tmp;
impl->rewind_point();
UNREACHABLE();
}
void Fiber::FiberStartFunc(boost::context::detail::transfer_t transfer) {
auto* fiber = static_cast<Fiber*>(transfer.data);
fiber->Start(transfer);
}
void Fiber::RewindStartFunc(boost::context::detail::transfer_t transfer) {
auto* fiber = static_cast<Fiber*>(transfer.data);
fiber->OnRewind(transfer);
Fiber::Fiber() : impl{std::make_unique<FiberImpl>()} {
impl->is_thread_fiber = true;
}
Fiber::Fiber(std::function<void()>&& entry_point_func) : impl{std::make_unique<FiberImpl>()} {
impl->entry_point = std::move(entry_point_func);
impl->stack_limit = impl->stack.data();
impl->rewind_stack_limit = impl->rewind_stack.data();
u8* stack_base = impl->stack_limit + default_stack_size;
impl->context =
boost::context::detail::make_fcontext(stack_base, impl->stack.size(), FiberStartFunc);
auto desc = mco_desc_init(
[](mco_coro* coro) { reinterpret_cast<Fiber*>(coro->user_data)->impl->entry_point(); }, 0);
desc.user_data = this;
mco_result res = mco_create(&impl->context, &desc);
ASSERT(res == MCO_SUCCESS);
}
Fiber::Fiber() : impl{std::make_unique<FiberImpl>()} {}
Fiber::~Fiber() {
if (impl->released) {
return;
}
// Make sure the Fiber is not being used
const bool locked = impl->guard.try_lock();
ASSERT_MSG(locked, "Destroying a fiber that's still running");
if (locked) {
impl->guard.unlock();
DestroyPre();
if (impl->is_thread_fiber) {
DestroyThreadFiber();
} else {
DestroyWorkFiber();
}
}
@@ -97,42 +54,66 @@ void Fiber::Exit() {
if (!impl->is_thread_fiber) {
return;
}
impl->guard.unlock();
DestroyPre();
DestroyThreadFiber();
}
void Fiber::DestroyPre() {
// Make sure the Fiber is not being used
const bool locked = impl->guard.try_lock();
ASSERT_MSG(locked, "Destroying a fiber that's still running");
if (locked) {
impl->guard.unlock();
}
impl->released = true;
}
void Fiber::Rewind() {
ASSERT(impl->rewind_point);
ASSERT(impl->rewind_context == nullptr);
u8* stack_base = impl->rewind_stack_limit + default_stack_size;
impl->rewind_context =
boost::context::detail::make_fcontext(stack_base, impl->stack.size(), RewindStartFunc);
boost::context::detail::jump_fcontext(impl->rewind_context, this);
void Fiber::DestroyWorkFiber() {
mco_result res = mco_destroy(impl->context);
ASSERT(res == MCO_SUCCESS);
}
void Fiber::DestroyThreadFiber() {
if (*impl->next_fiber_ptr) {
*impl->next_fiber_ptr = nullptr;
}
}
void Fiber::YieldTo(std::weak_ptr<Fiber> weak_from, Fiber& to) {
to.impl->guard.lock();
to.impl->previous_fiber = weak_from.lock();
auto transfer = boost::context::detail::jump_fcontext(to.impl->context, &to);
// "from" might no longer be valid if the thread was killed
if (auto from = weak_from.lock()) {
if (from->impl->previous_fiber == nullptr) {
ASSERT_MSG(false, "previous_fiber is nullptr!");
return;
if (!from->impl->is_thread_fiber) {
// Set next fiber
from->impl->next_fiber = &to;
// Yield from thread
if (!from->impl->released) {
from->impl->guard.unlock();
mco_yield(from->impl->context);
}
} else {
from->impl->guard.lock();
// Keep running next fiber until they've ran out
auto& next_fiber_ptr = from->impl->next_fiber_ptr;
next_fiber_ptr = &from->impl->next_fiber;
*next_fiber_ptr = &to;
for ([[maybe_unused]] unsigned round = 0; *next_fiber_ptr; round++) {
auto next = *next_fiber_ptr;
*next_fiber_ptr = nullptr;
next_fiber_ptr = &next->impl->next_fiber;
// Stop if new thread is thread fiber
if (next->impl->is_thread_fiber)
break;
// Resume new thread
next->impl->guard.lock();
mco_result res = mco_resume(next->impl->context);
ASSERT(res == MCO_SUCCESS);
}
from->impl->guard.unlock();
}
from->impl->previous_fiber->impl->context = transfer.fctx;
from->impl->previous_fiber->impl->guard.unlock();
from->impl->previous_fiber.reset();
}
}
std::shared_ptr<Fiber> Fiber::ThreadToFiber() {
std::shared_ptr<Fiber> fiber = std::shared_ptr<Fiber>{new Fiber()};
fiber->impl->guard.lock();
fiber->impl->is_thread_fiber = true;
return fiber;
return std::shared_ptr<Fiber>{new Fiber()};
}
} // namespace Common
+4 -16
View File
@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -9,9 +6,7 @@
#include <functional>
#include <memory>
namespace boost::context::detail {
struct transfer_t;
}
#include "common/minicoro.h"
namespace Common {
@@ -41,25 +36,18 @@ public:
Fiber(Fiber&&) = default;
Fiber& operator=(Fiber&&) = default;
/// Yields control from Fiber 'from' to Fiber 'to'
/// Fiber 'from' must be the currently running fiber.
static void YieldTo(std::weak_ptr<Fiber> weak_from, Fiber& to);
[[nodiscard]] static std::shared_ptr<Fiber> ThreadToFiber();
void SetRewindPoint(std::function<void()>&& rewind_func);
void Rewind();
/// Only call from main thread's fiber
void Exit();
private:
Fiber();
void OnRewind(boost::context::detail::transfer_t& transfer);
void Start(boost::context::detail::transfer_t& transfer);
static void FiberStartFunc(boost::context::detail::transfer_t transfer);
static void RewindStartFunc(boost::context::detail::transfer_t transfer);
void DestroyPre();
void DestroyWorkFiber();
void DestroyThreadFiber();
struct FiberImpl;
std::unique_ptr<FiberImpl> impl;
+4 -1
View File
@@ -578,7 +578,10 @@ public:
#endif
int flags = (fd > 0 ? MAP_SHARED : MAP_PRIVATE) | MAP_FIXED;
void* ret = mmap(virtual_base + virtual_offset, length, prot_flags, flags, fd, host_offset);
ASSERT_MSG(ret != MAP_FAILED, "mmap: {}", strerror(errno));
ASSERT_MSG(ret != MAP_FAILED,
"mmap(virt_off=0x{:X}, host_off=0x{:X}, len=0x{:X}, virt_size=0x{:X}, backing_size=0x{:X}, perms=0x{:X}) failed: {}",
virtual_offset, host_offset, length, virtual_size, backing_size,
static_cast<u32>(perms), strerror(errno));
}
void Unmap(size_t virtual_offset, size_t length) {
File diff suppressed because it is too large Load Diff
+131 -130
View File
@@ -241,13 +241,21 @@ struct Values {
SwitchableSetting<CpuAccuracy, true> cpu_accuracy{linkage, CpuAccuracy::Auto,
"cpu_accuracy", Category::Cpu};
SwitchableSetting<bool> vtable_bouncing{linkage, true, "vtable_bouncing", Category::Cpu};
SwitchableSetting<bool> use_fast_cpu_time{linkage,
false,
"use_fast_cpu_time",
Category::Cpu,
Specialization::Paired,
true,
true};
SwitchableSetting<CpuClock> fast_cpu_time{linkage,
CpuClock::Off,
CpuClock::Boost,
"fast_cpu_time",
Category::Cpu,
Specialization::Default,
true,
true};
true,
&use_fast_cpu_time};
SwitchableSetting<bool> use_custom_cpu_ticks{linkage,
false,
@@ -326,58 +334,28 @@ struct Values {
SwitchableSetting<int> vulkan_device{linkage, 0, "vulkan_device", Category::Renderer,
Specialization::RuntimeList};
// Graphics Settings
ResolutionScalingInfo resolution_info{};
SwitchableSetting<ResolutionSetup> resolution_setup{linkage, ResolutionSetup::Res1X,
"resolution_setup", Category::Renderer};
SwitchableSetting<VSyncMode, true> vsync_mode{linkage,
VSyncMode::Fifo,
"use_vsync",
Category::Renderer,
Specialization::RuntimeList,
true,
true};
SwitchableSetting<ScalingFilter> scaling_filter{linkage,
ScalingFilter::Bilinear,
"scaling_filter",
Category::Renderer,
Specialization::Default,
true,
true};
SwitchableSetting<int, true> fsr_sharpening_slider{linkage,
25,
0,
200,
"fsr_sharpening_slider",
Category::Renderer,
Specialization::Scalar |
Specialization::Percentage,
true,
true};
SwitchableSetting<AspectRatio, true> aspect_ratio{linkage,
AspectRatio::R16_9,
"aspect_ratio",
Category::Renderer,
Specialization::Default,
true,
true};
SwitchableSetting<AntiAliasing> anti_aliasing{linkage,
AntiAliasing::None,
"anti_aliasing",
Category::Renderer,
Specialization::Default,
true,
true};
SwitchableSetting<bool> use_disk_shader_cache{linkage, true, "use_disk_shader_cache",
Category::Renderer};
SwitchableSetting<SpirvOptimizeMode, true> optimize_spirv_output{linkage,
SpirvOptimizeMode::Never,
"optimize_spirv_output",
Category::Renderer};
SwitchableSetting<bool> use_asynchronous_gpu_emulation{
linkage, true, "use_asynchronous_gpu_emulation", Category::Renderer};
SwitchableSetting<AstcDecodeMode, true> accelerate_astc{linkage,
#ifdef ANDROID
AstcDecodeMode::Cpu,
#else
AstcDecodeMode::Gpu,
#endif
"accelerate_astc",
Category::Renderer};
SwitchableSetting<VSyncMode, true> vsync_mode{
linkage, VSyncMode::Fifo,
"use_vsync", Category::Renderer, Specialization::RuntimeList, true,
true};
SwitchableSetting<NvdecEmulation> nvdec_emulation{linkage, NvdecEmulation::Gpu,
"nvdec_emulation", Category::Renderer};
// *nix platforms may have issues with the borderless windowed fullscreen mode.
// Default to exclusive fullscreen on these platforms for now.
SwitchableSetting<FullscreenMode, true> fullscreen_mode{linkage,
@@ -391,6 +369,41 @@ struct Values {
Specialization::Default,
true,
true};
SwitchableSetting<AspectRatio, true> aspect_ratio{linkage,
AspectRatio::R16_9,
"aspect_ratio",
Category::Renderer,
Specialization::Default,
true,
true};
ResolutionScalingInfo resolution_info{};
SwitchableSetting<ResolutionSetup> resolution_setup{linkage, ResolutionSetup::Res1X,
"resolution_setup", Category::Renderer};
SwitchableSetting<ScalingFilter> scaling_filter{linkage,
ScalingFilter::Bilinear,
"scaling_filter",
Category::Renderer,
Specialization::Default,
true,
true};
SwitchableSetting<AntiAliasing> anti_aliasing{linkage,
AntiAliasing::None,
"anti_aliasing",
Category::Renderer,
Specialization::Default,
true,
true};
SwitchableSetting<int, true> fsr_sharpening_slider{linkage,
25,
0,
200,
"fsr_sharpening_slider",
Category::Renderer,
Specialization::Scalar |
Specialization::Percentage,
true,
true};
SwitchableSetting<u8, false> bg_red{
linkage, 0, "bg_red", Category::Renderer, Specialization::Default, true, true};
@@ -421,14 +434,6 @@ struct Values {
true,
true};
SwitchableSetting<VramUsageMode, true> vram_usage_mode{linkage,
VramUsageMode::Conservative,
"vram_usage_mode",
Category::RendererAdvanced};
SwitchableSetting<NvdecEmulation> nvdec_emulation{linkage, NvdecEmulation::Gpu,
"nvdec_emulation", Category::RendererAdvanced};
SwitchableSetting<AnisotropyMode, true> max_anisotropy{linkage,
#ifdef ANDROID
AnisotropyMode::Default,
@@ -437,21 +442,21 @@ struct Values {
#endif
"max_anisotropy",
Category::RendererAdvanced};
SwitchableSetting<AstcDecodeMode, true> accelerate_astc{linkage,
#ifdef ANDROID
AstcDecodeMode::Cpu,
#else
AstcDecodeMode::Gpu,
#endif
"accelerate_astc",
Category::RendererAdvanced};
SwitchableSetting<AstcRecompression, true> astc_recompression{linkage,
AstcRecompression::Uncompressed,
"astc_recompression",
Category::RendererAdvanced};
SwitchableSetting<VramUsageMode, true> vram_usage_mode{linkage,
VramUsageMode::Conservative,
"vram_usage_mode",
Category::RendererAdvanced};
SwitchableSetting<bool> skip_cpu_inner_invalidation{linkage,
false,
"skip_cpu_inner_invalidation",
Category::RendererAdvanced,
Specialization::Default,
true,
true};
SwitchableSetting<bool> sync_memory_operations{linkage,
false,
"sync_memory_operations",
@@ -459,23 +464,15 @@ struct Values {
Specialization::Default,
true,
true};
SwitchableSetting<bool> async_presentation{linkage,
#ifdef ANDROID
true,
#else
false,
#endif
"async_presentation", Category::RendererAdvanced};
SwitchableSetting<bool> renderer_force_max_clock{linkage, false, "force_max_clock",
Category::RendererAdvanced};
SwitchableSetting<bool> use_disk_shader_cache{linkage, true, "use_disk_shader_cache",
Category::RendererAdvanced};
SwitchableSetting<bool> use_vulkan_driver_pipeline_cache{
linkage, true, "use_vulkan_driver_pipeline_cache", Category::RendererAdvanced,
Specialization::Default};
SwitchableSetting<bool> enable_compute_pipelines{linkage, false, "enable_compute_pipelines",
Category::RendererAdvanced};
SwitchableSetting<bool> use_video_framerate{linkage, false, "use_video_framerate",
Category::RendererAdvanced};
SwitchableSetting<bool> use_reactive_flushing{linkage,
#ifdef ANDROID
false,
@@ -484,61 +481,71 @@ struct Values {
#endif
"use_reactive_flushing",
Category::RendererAdvanced};
SwitchableSetting<bool> use_asynchronous_shaders{linkage, false, "use_asynchronous_shaders",
Category::RendererAdvanced};
SwitchableSetting<bool> use_fast_gpu_time{linkage,
true,
"use_fast_gpu_time",
Category::RendererAdvanced,
Specialization::Paired,
true,
true};
SwitchableSetting<GpuOverclock> fast_gpu_time{linkage,
GpuOverclock::Low,
"fast_gpu_time",
Category::RendererAdvanced,
Specialization::Default,
true,
true,
&use_fast_gpu_time};
SwitchableSetting<bool> use_vulkan_driver_pipeline_cache{linkage,
true,
"use_vulkan_driver_pipeline_cache",
Category::RendererAdvanced,
Specialization::Default,
true,
true};
SwitchableSetting<bool> enable_compute_pipelines{linkage, false, "enable_compute_pipelines",
Category::RendererAdvanced};
SwitchableSetting<bool> use_video_framerate{linkage, false, "use_video_framerate",
Category::RendererAdvanced};
SwitchableSetting<bool> barrier_feedback_loops{linkage, true, "barrier_feedback_loops",
Category::RendererAdvanced};
// Renderer Hacks //
SwitchableSetting<GpuOverclock> fast_gpu_time{linkage,
GpuOverclock::Medium,
"fast_gpu_time",
Category::RendererAdvanced,
Specialization::Default};
SwitchableSetting<bool> skip_cpu_inner_invalidation{linkage,
false,
"skip_cpu_inner_invalidation",
Category::RendererAdvanced,
Specialization::Default,
true,
true};
SwitchableSetting<bool> async_presentation{linkage,
#ifdef ANDROID
true,
#else
false,
#endif
"async_presentation", Category::RendererAdvanced};
SwitchableSetting<bool> use_asynchronous_shaders{linkage, false, "use_asynchronous_shaders",
Category::RendererAdvanced};
SwitchableSetting<ExtendedDynamicState> dyna_state{linkage,
SwitchableSetting<u8, true> dyna_state{linkage,
#if defined (_WIN32)
ExtendedDynamicState::EDS3,
3,
#elif defined (__FreeBSD__)
ExtendedDynamicState::EDS3,
3,
#elif defined (ANDROID)
ExtendedDynamicState::Disabled,
0,
#elif defined (__APPLE__)
ExtendedDynamicState::Disabled,
0,
#else
ExtendedDynamicState::EDS2,
2,
#endif
0,
3,
"dyna_state",
Category::RendererExtensions};
SwitchableSetting<u32, true> sample_shading{linkage,
0,
0,
100,
"sample_shading_fraction",
Category::RendererExtensions,
Specialization::Scalar};
Category::RendererExtensions,
Specialization::Scalar};
SwitchableSetting<bool> vertex_input_dynamic_state{linkage, true, "vertex_input_dynamic_state", Category::RendererExtensions};
SwitchableSetting<bool> provoking_vertex{linkage, false, "provoking_vertex", Category::RendererExtensions};
SwitchableSetting<bool> descriptor_indexing{linkage, false, "descriptor_indexing", Category::RendererExtensions};
SwitchableSetting<bool> sample_shading{linkage, false, "sample_shading", Category::RendererExtensions, Specialization::Paired};
SwitchableSetting<u32, true> sample_shading_fraction{linkage,
50,
0,
100,
"sample_shading_fraction",
Category::RendererExtensions,
Specialization::Scalar,
true,
false,
&sample_shading};
Setting<bool> renderer_debug{linkage, false, "debug", Category::RendererDebug};
Setting<bool> renderer_shader_feedback{linkage, false, "shader_feedback",
@@ -549,11 +556,6 @@ struct Values {
linkage, false, "disable_shader_loop_safety_checks", Category::RendererDebug};
Setting<bool> enable_renderdoc_hotkey{linkage, false, "renderdoc_hotkey",
Category::RendererDebug};
#if defined(ANDROID) && defined(ARCHITECTURE_arm64)
// Debug override for automatic BCn patching detection
Setting<bool> patch_old_qcom_drivers{linkage, true, "patch_old_qcom_drivers",
Category::RendererDebug};
#endif
SwitchableSetting<bool> disable_buffer_reorder{linkage, false, "disable_buffer_reorder",
Category::RendererDebug,
Specialization::Default,
@@ -742,10 +744,9 @@ struct Values {
// WebService
Setting<std::string> web_api_url{linkage, "api.ynet-fun.xyz", "web_api_url",
Category::WebService};
Setting<std::string> eden_username{linkage, "Eden", "eden_username",
Setting<std::string> eden_username{linkage, std::string(), "eden_username",
Category::WebService};
Setting<std::string> eden_token{linkage, "njausoolxygtpvraofqunuufhmupriifnpfggjxefntlyglr",
"eden_token", Category::WebService};
Setting<std::string> eden_token{linkage, std::string(), "eden_token", Category::WebService};
// Add-Ons
std::map<u64, std::vector<std::string>> disabled_addons;
+2 -3
View File
@@ -137,7 +137,7 @@ ENUM(GpuAccuracy, Low, Medium, High);
ENUM(DmaAccuracy, Default, Unsafe, Safe);
ENUM(CpuBackend, Dynarmic, Nce);
ENUM(CpuAccuracy, Auto, Accurate, Unsafe, Paranoid, Debugging);
ENUM(CpuClock, Off, Boost, Fast)
ENUM(CpuClock, Boost, Fast)
ENUM(MemoryLayout, Memory_4Gb, Memory_6Gb, Memory_8Gb, Memory_10Gb, Memory_12Gb);
ENUM(ConfirmStop, Ask_Always, Ask_Based_On_Game, Ask_Never);
ENUM(FullscreenMode, Borderless, Exclusive);
@@ -149,9 +149,8 @@ ENUM(AspectRatio, R16_9, R4_3, R21_9, R16_10, Stretch);
ENUM(ConsoleMode, Handheld, Docked);
ENUM(AppletMode, HLE, LLE);
ENUM(SpirvOptimizeMode, Never, OnLoad, Always);
ENUM(GpuOverclock, Normal, Medium, High)
ENUM(GpuOverclock, Low, Medium, High)
ENUM(TemperatureUnits, Celsius, Fahrenheit)
ENUM(ExtendedDynamicState, Disabled, EDS1, EDS2, EDS3);
template <typename Type>
inline std::string_view CanonicalizeEnum(Type id) {
+11
View File
@@ -130,6 +130,17 @@ public:
ResetStorageBit(id.index);
}
[[nodiscard]] bool Contains(SlotId id) const noexcept {
if (!id) {
return false;
}
const size_t word = id.index / 64;
if (word >= stored_bitset.size()) {
return false;
}
return ((stored_bitset[word] >> (id.index % 64)) & 1) != 0;
}
[[nodiscard]] Iterator begin() noexcept {
const auto it = std::ranges::find_if(stored_bitset, [](u64 value) { return value != 0; });
if (it == stored_bitset.end()) {
+9 -10
View File
@@ -195,20 +195,19 @@ u64 CoreTiming::GetClockTicks() const {
u64 fres;
if (is_multicore) [[likely]] {
fres = clock->GetCNTPCT();
} else {
fres = Common::WallClock::CPUTickToCNTPCT(cpu_ticks);
}
} else {
fres = Common::WallClock::CPUTickToCNTPCT(cpu_ticks);
}
const auto overclock = Settings::values.fast_cpu_time.GetValue();
if (overclock != Settings::CpuClock::Off) {
fres = (u64) ((double) fres * (1.7 + 0.3 * u32(overclock)));
if (Settings::values.use_fast_cpu_time) {
fres = (u64) ((double) fres
* (1.7 + 0.3 * (u32) Settings::values.fast_cpu_time.GetValue()));
}
if (Settings::values.sync_core_speed.GetValue()) {
const auto ticks = double(fres);
const auto speed_limit = double(Settings::values.speed_limit.GetValue())*0.01;
return u64(ticks/speed_limit);
const double ticks = static_cast<double>(fres);
const double speed_limit = static_cast<double>(Settings::values.speed_limit.GetValue())*0.01;
return static_cast<u64>(ticks/speed_limit);
} else {
return fres;
}
+5 -5
View File
@@ -15,8 +15,8 @@ namespace HLE::ApiVersion {
// Horizon OS version constants.
constexpr u8 HOS_VERSION_MAJOR = 21;
constexpr u8 HOS_VERSION_MINOR = 1;
constexpr u8 HOS_VERSION_MICRO = 0;
constexpr u8 HOS_VERSION_MINOR = 0;
constexpr u8 HOS_VERSION_MICRO = 1;
// NintendoSDK version constants.
@@ -24,9 +24,9 @@ constexpr u8 SDK_REVISION_MAJOR = 1;
constexpr u8 SDK_REVISION_MINOR = 0;
constexpr char PLATFORM_STRING[] = "NX";
constexpr char VERSION_HASH[] = "0d7a6334ddc3d637f69ec3976b17a260efd68fd4";
constexpr char DISPLAY_VERSION[] = "21.1.0";
constexpr char DISPLAY_TITLE[] = "NintendoSDK Firmware for NX 21.1.0-1.0";
constexpr char VERSION_HASH[] = "066a75e6fab7316de34b88b60d229a0b2729e421";
constexpr char DISPLAY_VERSION[] = "21.0.1";
constexpr char DISPLAY_TITLE[] = "NintendoSDK Firmware for NX 21.0.1-1.0";
// Atmosphere version constants.
+2 -42
View File
@@ -6,7 +6,6 @@
#include "core/core.h"
#include "core/core_timing.h"
#include "core/hle/kernel/k_memory_manager.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/k_resource_limit.h"
#include "core/hle/kernel/svc.h"
@@ -272,47 +271,8 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle
Result GetSystemInfo(Core::System& system, uint64_t* out, SystemInfoType info_type, Handle handle,
uint64_t info_subtype) {
const u32 info_id = static_cast<u32>(info_type);
R_UNLESS(info_id <= 2, ResultInvalidEnumValue);
R_UNLESS(handle == 0, ResultInvalidHandle);
if (info_id < 2) {
R_UNLESS(info_subtype <= 3, ResultInvalidCombination);
auto& memory_manager = system.Kernel().MemoryManager();
const auto pool = static_cast<KMemoryManager::Pool>(info_subtype);
switch (info_type) {
case SystemInfoType::TotalPhysicalMemorySize:
*out = memory_manager.GetSize(pool);
break;
case SystemInfoType::UsedPhysicalMemorySize:
*out = memory_manager.GetSize(pool) - memory_manager.GetFreeSize(pool);
break;
default:
R_THROW(ResultInvalidEnumValue);
}
} else {
R_UNLESS(info_subtype <= 1, ResultInvalidCombination);
constexpr u64 PrivilegedProcessLowestId = 1;
constexpr u64 PrivilegedProcessHighestId = 8;
switch (info_subtype) {
case 0:
*out = PrivilegedProcessLowestId;
break;
case 1:
*out = PrivilegedProcessHighestId;
break;
default:
R_THROW(ResultInvalidCombination);
}
}
R_SUCCEED();
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result GetInfo64(Core::System& system, uint64_t* out, InfoType info_type, Handle handle,
+59 -15
View File
@@ -1,8 +1,12 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <algorithm>
#include <array>
#include <cstring>
#include <sstream>
#include <boost/range/algorithm_ext/erase.hpp>
@@ -187,7 +191,7 @@ void HLERequestContext::ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming) {
buffer_w_descriptors.push_back(rp.PopRaw<IPC::BufferDescriptorABW>());
}
const auto buffer_c_offset = rp.GetCurrentOffset() + command_header->data_size;
buffer_c_offset = rp.GetCurrentOffset() + command_header->data_size;
if (!command_header->IsTipc()) {
// Padding to align to 16 bytes
@@ -294,7 +298,15 @@ Result HLERequestContext::WriteToOutgoingCommandBuffer() {
}
// Write the domain objects to the command buffer, these go after the raw untranslated data.
// TODO(Subv): This completely ignores C buffers.
if (buffer_c_offset != 0 && !buffer_c_descriptors.empty()) {
constexpr u32 WORDS_PER_DESCRIPTOR = sizeof(IPC::BufferDescriptorC) / sizeof(u32);
u32 descriptor_offset = buffer_c_offset;
for (const auto& descriptor : buffer_c_descriptors) {
std::memcpy(&cmd_buf[descriptor_offset], &descriptor, sizeof(descriptor));
descriptor_offset += WORDS_PER_DESCRIPTOR;
}
}
if (GetManager()->IsDomain()) {
current_offset = domain_offset - static_cast<u32>(outgoing_domain_objects.size());
@@ -393,10 +405,14 @@ std::size_t HLERequestContext::WriteBuffer(const void* buffer, std::size_t size,
const bool is_buffer_b{BufferDescriptorB().size() > buffer_index &&
BufferDescriptorB()[buffer_index].Size()};
const std::size_t buffer_size{GetWriteBufferSize(buffer_index)};
if (buffer_size == 0) {
LOG_WARNING(Core, "WriteBuffer target index {} has zero capacity", buffer_index);
return 0;
}
if (size > buffer_size) {
LOG_CRITICAL(Core, "size ({:016X}) is greater than buffer_size ({:016X})", size,
buffer_size);
size = buffer_size; // TODO(bunnei): This needs to be HW tested
LOG_WARNING(Core, "size ({:016X}) is greater than buffer_size ({:016X}); clamping",
size, buffer_size);
size = buffer_size;
}
if (is_buffer_b) {
@@ -418,15 +434,25 @@ std::size_t HLERequestContext::WriteBuffer(const void* buffer, std::size_t size,
std::size_t HLERequestContext::WriteBufferB(const void* buffer, std::size_t size,
std::size_t buffer_index) const {
if (buffer_index >= BufferDescriptorB().size() || size == 0) {
if (buffer_index >= BufferDescriptorB().size()) {
LOG_WARNING(Core, "WriteBufferB invalid buffer index {}", buffer_index);
return 0;
}
if (size == 0) {
LOG_WARNING(Core, "skip empty buffer write (B)");
return 0;
}
const auto buffer_size{BufferDescriptorB()[buffer_index].Size()};
if (buffer_size == 0) {
LOG_WARNING(Core, "WriteBufferB target index {} has zero capacity", buffer_index);
return 0;
}
if (size > buffer_size) {
LOG_CRITICAL(Core, "size ({:016X}) is greater than buffer_size ({:016X})", size,
buffer_size);
size = buffer_size; // TODO(bunnei): This needs to be HW tested
LOG_WARNING(Core, "size ({:016X}) is greater than buffer_size ({:016X}); clamping",
size, buffer_size);
size = buffer_size;
}
memory.WriteBlock(BufferDescriptorB()[buffer_index].Address(), buffer, size);
@@ -435,15 +461,25 @@ std::size_t HLERequestContext::WriteBufferB(const void* buffer, std::size_t size
std::size_t HLERequestContext::WriteBufferC(const void* buffer, std::size_t size,
std::size_t buffer_index) const {
if (buffer_index >= BufferDescriptorC().size() || size == 0) {
if (buffer_index >= BufferDescriptorC().size()) {
LOG_WARNING(Core, "WriteBufferC invalid buffer index {}", buffer_index);
return 0;
}
if (size == 0) {
LOG_WARNING(Core, "skip empty buffer write (C)");
return 0;
}
const auto buffer_size{BufferDescriptorC()[buffer_index].Size()};
if (buffer_size == 0) {
LOG_WARNING(Core, "WriteBufferC target index {} has zero capacity", buffer_index);
return 0;
}
if (size > buffer_size) {
LOG_CRITICAL(Core, "size ({:016X}) is greater than buffer_size ({:016X})", size,
buffer_size);
size = buffer_size; // TODO(bunnei): This needs to be HW tested
LOG_WARNING(Core, "size ({:016X}) is greater than buffer_size ({:016X}); clamping",
size, buffer_size);
size = buffer_size;
}
memory.WriteBlock(BufferDescriptorC()[buffer_index].Address(), buffer, size);
@@ -473,12 +509,20 @@ std::size_t HLERequestContext::GetWriteBufferSize(std::size_t buffer_index) cons
ASSERT_OR_EXECUTE_MSG(
BufferDescriptorB().size() > buffer_index, { return 0; },
"BufferDescriptorB invalid buffer_index {}", buffer_index);
return BufferDescriptorB()[buffer_index].Size();
const auto size = BufferDescriptorB()[buffer_index].Size();
if (size == 0) {
LOG_WARNING(Core, "BufferDescriptorB index {} has zero size", buffer_index);
}
return size;
} else {
ASSERT_OR_EXECUTE_MSG(
BufferDescriptorC().size() > buffer_index, { return 0; },
"BufferDescriptorC invalid buffer_index {}", buffer_index);
return BufferDescriptorC()[buffer_index].Size();
const auto size = BufferDescriptorC()[buffer_index].Size();
if (size == 0) {
LOG_WARNING(Core, "BufferDescriptorC index {} has zero size", buffer_index);
}
return size;
}
return 0;
}
+4
View File
@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -422,6 +425,7 @@ private:
u32 data_payload_offset{};
u32 handles_offset{};
u32 domain_offset{};
u32 buffer_c_offset{};
std::weak_ptr<SessionRequestManager> manager{};
bool is_deferred{false};
-2
View File
@@ -91,8 +91,6 @@ public:
static const FunctionInfo functions[] = {
{0, &ILogger::Log, "Log"},
{1, &ILogger::SetDestination, "SetDestination"},
{2, nullptr, "TransmitHashedLog"}, //20.0.0+
{3, nullptr, "DevNotify"}, //20.0.0+
};
RegisterHandlers(functions);
}
@@ -100,6 +100,14 @@ Status BufferQueueConsumer::AcquireBuffer(BufferItem* out_buffer,
slots[slot].needs_cleanup_on_release = false;
slots[slot].buffer_state = BufferState::Acquired;
// Mark tracked buffer history records as acquired
for (auto& buffer_history_record : core->buffer_history) {
if (buffer_history_record.frame_number == core->frame_counter) {
buffer_history_record.state = BufferState::Acquired;
break;
}
}
// TODO: for now, avoid resetting the fence, so that when we next return this
// slot to the producer, it will wait for the fence to pass. We should fix this
// by properly waiting for the fence in the BufferItemConsumer.
@@ -14,9 +14,18 @@
namespace Service::android {
BufferQueueCore::BufferQueueCore() = default;
BufferQueueCore::~BufferQueueCore() = default;
void BufferQueueCore::PushHistory(u64 frame_number, s64 queue_time, s64 presentation_time, BufferState state) {
buffer_history_pos = (buffer_history_pos + 1) % BUFFER_HISTORY_SIZE;
buffer_history[buffer_history_pos] = BufferHistoryInfo{
.frame_number = frame_number,
.queue_time = queue_time,
.presentation_time = presentation_time,
.state = state,
};
}
void BufferQueueCore::SignalDequeueCondition() {
dequeue_possible.store(true);
dequeue_condition.notify_all();
@@ -18,12 +18,29 @@
#include "core/hle/service/nvnflinger/buffer_item.h"
#include "core/hle/service/nvnflinger/buffer_queue_defs.h"
#include "core/hle/service/nvnflinger/buffer_slot.h"
#include "core/hle/service/nvnflinger/pixel_format.h"
#include "core/hle/service/nvnflinger/status.h"
#include "core/hle/service/nvnflinger/window.h"
namespace Service::android {
#ifdef _MSC_VER
#pragma pack(push, 1)
struct BufferHistoryInfo {
#elif defined(__GNUC__) || defined(__clang__)
struct __attribute__((packed)) BufferHistoryInfo {
#endif
u64 frame_number;
s64 queue_time;
s64 presentation_time;
BufferState state;
};
#ifdef _MSC_VER
#pragma pack(pop)
#endif
static_assert(sizeof(BufferHistoryInfo) == 0x1C, "BufferHistoryInfo must be 28 bytes");
class IConsumerListener;
class IProducerListener;
@@ -33,10 +50,13 @@ class BufferQueueCore final {
public:
static constexpr s32 INVALID_BUFFER_SLOT = BufferItem::INVALID_BUFFER_SLOT;
static constexpr u32 BUFFER_HISTORY_SIZE = 8;
BufferQueueCore();
~BufferQueueCore();
void PushHistory(u64 frame_number, s64 queue_time, s64 presentation_time, BufferState state);
private:
void SignalDequeueCondition();
bool WaitForDequeueCondition(std::unique_lock<std::mutex>& lk);
@@ -72,6 +92,8 @@ private:
const s32 max_acquired_buffer_count{}; // This is always zero on HOS
bool buffer_has_been_queued{};
u64 frame_counter{};
std::array<BufferHistoryInfo, BUFFER_HISTORY_SIZE> buffer_history{};
u32 buffer_history_pos{BUFFER_HISTORY_SIZE-1};
u32 transform_hint{};
bool is_allocating{};
mutable std::condition_variable_any is_allocating_condition;
@@ -515,6 +515,8 @@ Status BufferQueueProducer::QueueBuffer(s32 slot, const QueueBufferInput& input,
slots[slot].buffer_state = BufferState::Queued;
++core->frame_counter;
slots[slot].frame_number = core->frame_counter;
slots[slot].queue_time = timestamp;
slots[slot].presentation_time = 0;
item.acquire_called = slots[slot].acquire_called;
item.graphic_buffer = slots[slot].graphic_buffer;
@@ -547,6 +549,15 @@ Status BufferQueueProducer::QueueBuffer(s32 slot, const QueueBufferInput& input,
// mark it as freed
if (core->StillTracking(*front)) {
slots[front->slot].buffer_state = BufferState::Free;
// Mark tracked buffer history records as free
for (auto& buffer_history_record : core->buffer_history) {
if (buffer_history_record.frame_number == front->frame_number) {
buffer_history_record.state = BufferState::Free;
break;
}
}
// Reset the frame number of the freed buffer so that it is the first in line to
// be dequeued again
slots[front->slot].frame_number = 0;
@@ -560,6 +571,7 @@ Status BufferQueueProducer::QueueBuffer(s32 slot, const QueueBufferInput& input,
}
}
core->PushHistory(core->frame_counter, slots[slot].queue_time, slots[slot].presentation_time, BufferState::Queued);
core->buffer_has_been_queued = true;
core->SignalDequeueCondition();
output->Inflate(core->default_width, core->default_height, core->transform_hint,
@@ -810,6 +822,10 @@ Status BufferQueueProducer::SetPreallocatedBuffer(s32 slot,
return Status::NoError;
}
Kernel::KReadableEvent* BufferQueueProducer::GetNativeHandle(u32 type_id) {
return &buffer_wait_event->GetReadableEvent();
}
void BufferQueueProducer::Transact(u32 code, std::span<const u8> parcel_data,
std::span<u8> parcel_reply, u32 flags) {
// Values used by BnGraphicBufferProducer onTransact
@@ -929,9 +945,49 @@ void BufferQueueProducer::Transact(u32 code, std::span<const u8> parcel_data,
status = SetBufferCount(buffer_count);
break;
}
case TransactionId::GetBufferHistory:
LOG_DEBUG(Service_Nvnflinger, "(STUBBED) called, transaction=GetBufferHistory");
case TransactionId::GetBufferHistory: {
LOG_DEBUG(Service_Nvnflinger, "called, transaction=GetBufferHistory");
const s32 request = parcel_in.Read<s32>();
if (request <= 0) {
parcel_out.Write(Status::BadValue);
parcel_out.Write<s32>(0);
break;
}
constexpr u32 history_max = BufferQueueCore::BUFFER_HISTORY_SIZE;
std::array<BufferHistoryInfo, history_max> buffer_history_snapshot{};
s32 valid_index{};
{
std::scoped_lock lk(core->mutex);
const u32 current_history_pos = core->buffer_history_pos;
u32 index_reversed{};
for (u32 i = 0; i < history_max; ++i) {
// Wrap values backwards e.g. 7, 6, 5, etc. in the range of 0-7
index_reversed = (current_history_pos + history_max - i) % history_max;
const auto& current_history_buffer = core->buffer_history[index_reversed];
// Here we use the frame number as a terminator.
// Because a buffer without frame_number is not considered complete
if (current_history_buffer.frame_number == 0) {
break;
}
buffer_history_snapshot[valid_index] = current_history_buffer;
++valid_index;
}
}
const s32 limit = std::min(request, valid_index);
parcel_out.Write(Status::NoError);
parcel_out.Write<s32>(limit);
for (s32 i = 0; i < limit; ++i) {
parcel_out.Write(buffer_history_snapshot[i]);
}
break;
}
default:
ASSERT_MSG(false, "Unimplemented TransactionId {}", code);
break;
@@ -944,8 +1000,5 @@ void BufferQueueProducer::Transact(u32 code, std::span<const u8> parcel_data,
(std::min)(parcel_reply.size(), serialized.size()));
}
Kernel::KReadableEvent* BufferQueueProducer::GetNativeHandle(u32 type_id) {
return &buffer_wait_event->GetReadableEvent();
}
} // namespace Service::android
@@ -89,6 +89,8 @@ private:
s32 current_callback_ticket{};
std::condition_variable_any callback_condition;
u64 position;
Service::Nvidia::NvCore::NvMap& nvmap;
};
@@ -37,6 +37,7 @@ struct BufferSlot final {
bool needs_cleanup_on_release{};
bool attached_by_consumer{};
bool is_preallocated{};
s64 queue_time{}, presentation_time{};
};
} // namespace Service::android
+19 -21
View File
@@ -94,9 +94,10 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QObject* parent)
tr("Change the accuracy of the emulated CPU (for debugging only)."));
INSERT(Settings, cpu_backend, tr("Backend:"), QString());
INSERT(Settings, use_fast_cpu_time, QString(), QString());
INSERT(Settings,
fast_cpu_time,
tr("CPU Overclock"),
tr("Fast CPU Time"),
tr("Overclocks the emulated CPU to remove some FPS limiters. Weaker CPUs may see reduced performance, "
"and certain games may behave improperly.\nUse Boost (1700MHz) to run at the Switch's highest native "
"clock, or Fast (2000MHz) to run at 2x clock."));
@@ -207,6 +208,11 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QObject* parent)
tr("Runs an additional optimization pass over generated SPIRV shaders.\n"
"Will increase time required for shader compilation.\nMay slightly improve "
"performance.\nThis feature is experimental."));
INSERT(
Settings,
use_asynchronous_gpu_emulation,
tr("Use asynchronous GPU emulation"),
tr("Uses an extra CPU thread for rendering.\nThis option should always remain enabled."));
INSERT(Settings,
nvdec_emulation,
tr("NVDEC emulation:"),
@@ -252,8 +258,6 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QObject* parent)
INSERT(Settings, bg_blue, QString(), QString());
// Renderer (Advanced Graphics)
INSERT(Settings, use_asynchronous_gpu_emulation, QString(), QString());
INSERT(Settings, sync_memory_operations, tr("Sync Memory Operations"),
tr("Ensures data consistency between compute and memory operations.\nThis option fixes issues in games, but may degrade performance.\nUnreal Engine 4 games often see the most significant changes thereof."));
INSERT(Settings,
@@ -281,13 +285,14 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QObject* parent)
tr("Controls the DMA precision accuracy. Safe precision fixes issues in some games but may degrade performance."));
INSERT(Settings,
use_asynchronous_shaders,
tr("Enable asynchronous shader compilation"),
tr("Enable asynchronous shader compilation (Hack)"),
tr("May reduce shader stutter."));
INSERT(Settings, use_fast_gpu_time, QString(), QString());
INSERT(Settings,
fast_gpu_time,
tr("Fast GPU Time"),
tr("Fast GPU Time (Hack)"),
tr("Overclocks the emulated GPU to increase dynamic resolution and render "
"distance.\nUse 256 for maximal performance and 512 for maximal graphics fidelity."));
"distance.\nUse 128 for maximal performance and 512 for maximal graphics fidelity."));
INSERT(Settings,
use_vulkan_driver_pipeline_cache,
@@ -319,10 +324,10 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QObject* parent)
tr("Improves rendering of transparency effects in specific games."));
// Renderer (Extensions)
INSERT(Settings, dyna_state, tr("Extended Dynamic State"),
tr("Controls the number of features that can be used in Extended Dynamic State.\n"
"Higher numbers allow for more features and can increase performance, but may cause "
"additional graphical issues."));
INSERT(Settings,
dyna_state,
tr("Extended Dynamic State"),
tr("Controls the number of features that can be used in Extended Dynamic State.\nHigher numbers allow for more features and can increase performance, but may cause issues.\nThe default value is per-system."));
INSERT(Settings,
vertex_input_dynamic_state,
@@ -341,8 +346,10 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QObject* parent)
tr("Improves texture & buffer handling and the Maxwell translation layer.\n"
"Some Vulkan 1.1+ and all 1.2+ devices support this extension."));
INSERT(Settings, sample_shading, QString(), QString());
INSERT(Settings,
sample_shading,
sample_shading_fraction,
tr("Sample Shading"),
tr("Allows the fragment shader to execute per sample in a multi-sampled fragment "
"instead of once per fragment. Improves graphics quality at the cost of performance.\n"
@@ -702,7 +709,6 @@ std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QObject* parent)
}});
translations->insert({Settings::EnumMetadata<Settings::CpuClock>::Index(),
{
PAIR(CpuClock, Off, tr("Off")),
PAIR(CpuClock, Boost, tr("Boost (1700MHz)")),
PAIR(CpuClock, Fast, tr("Fast (2000MHz)")),
}});
@@ -715,19 +721,11 @@ std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QObject* parent)
}});
translations->insert({Settings::EnumMetadata<Settings::GpuOverclock>::Index(),
{
PAIR(GpuOverclock, Normal, tr("Off")),
PAIR(GpuOverclock, Low, tr("Low (128)")),
PAIR(GpuOverclock, Medium, tr("Medium (256)")),
PAIR(GpuOverclock, High, tr("High (512)")),
}});
translations->insert({Settings::EnumMetadata<Settings::ExtendedDynamicState>::Index(),
{
PAIR(ExtendedDynamicState, Disabled, tr("Disabled")),
PAIR(ExtendedDynamicState, EDS1, tr("ExtendedDynamicState 1")),
PAIR(ExtendedDynamicState, EDS2, tr("ExtendedDynamicState 2")),
PAIR(ExtendedDynamicState, EDS3, tr("ExtendedDynamicState 3")),
}});
#undef PAIR
#undef CTX_PAIR
@@ -11,6 +11,7 @@
#include <vector>
#include <spirv-tools/optimizer.hpp>
#include "common/logging/log.h"
#include "common/settings.h"
#include "shader_recompiler/backend/spirv/emit_spirv.h"
#include "shader_recompiler/backend/spirv/emit_spirv_instructions.h"
@@ -439,15 +440,23 @@ void SetupCapabilities(const Profile& profile, const Info& info, EmitContext& ct
ctx.AddExtension("SPV_KHR_shader_draw_parameters");
ctx.AddCapability(spv::Capability::DrawParameters);
}
if ((info.uses_subgroup_vote || info.uses_subgroup_invocation_id ||
info.uses_subgroup_shuffles) &&
profile.support_vote) {
const bool stage_supports_warp = profile.SupportsWarpIntrinsics(ctx.stage);
const bool needs_warp_intrinsics = info.uses_subgroup_vote ||
info.uses_subgroup_invocation_id ||
info.uses_subgroup_shuffles;
if (needs_warp_intrinsics && profile.support_vote && stage_supports_warp) {
ctx.AddCapability(spv::Capability::GroupNonUniformBallot);
ctx.AddCapability(spv::Capability::GroupNonUniformShuffle);
if (!profile.warp_size_potentially_larger_than_guest) {
// vote ops are only used when not taking the long path
ctx.AddCapability(spv::Capability::GroupNonUniformVote);
}
} else if (needs_warp_intrinsics && !stage_supports_warp) {
LOG_WARNING(Shader,
"Warp intrinsics requested in stage {} but the device does not report subgroup "
"support; falling back to scalar approximations",
static_cast<u32>(ctx.stage));
}
if (info.uses_int64_bit_atomics && profile.support_int64_atomics) {
ctx.AddCapability(spv::Capability::Int64Atomics);
@@ -491,9 +491,24 @@ void EmitSetPatch(EmitContext& ctx, IR::Patch patch, Id value) {
}
void EmitSetFragColor(EmitContext& ctx, u32 index, u32 component, Id value) {
const AttributeType output_type{ctx.runtime_info.color_output_types[index]};
Id pointer_type{ctx.output_f32};
Id store_value{value};
switch (output_type) {
case AttributeType::SignedInt:
pointer_type = ctx.output_s32;
store_value = ctx.OpBitcast(ctx.S32[1], value);
break;
case AttributeType::UnsignedInt:
pointer_type = ctx.output_u32;
store_value = ctx.OpBitcast(ctx.U32[1], value);
break;
default:
break;
}
const Id component_id{ctx.Const(component)};
const Id pointer{ctx.OpAccessChain(ctx.output_f32, ctx.frag_color.at(index), component_id)};
ctx.OpStore(pointer, value);
const Id pointer{ctx.OpAccessChain(pointer_type, ctx.frag_color.at(index), component_id)};
ctx.OpStore(pointer, store_value);
}
void EmitSetSampleMask(EmitContext& ctx, Id value) {
@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -195,6 +198,41 @@ Id Texture(EmitContext& ctx, IR::TextureInstInfo info, [[maybe_unused]] const IR
}
}
Id TextureColorResultType(EmitContext& ctx, const TextureDefinition& def) {
switch (def.component_type) {
case SamplerComponentType::Float:
case SamplerComponentType::Depth:
return ctx.F32[4];
case SamplerComponentType::Sint:
return ctx.S32[4];
case SamplerComponentType::Stencil:
return ctx.U32[4];
case SamplerComponentType::Uint:
return ctx.U32[4];
}
throw InvalidArgument("Invalid sampler component type {}", def.component_type);
}
Id TextureSampleResultToFloat(EmitContext& ctx, const TextureDefinition& def, Id color) {
switch (def.component_type) {
case SamplerComponentType::Float:
case SamplerComponentType::Depth:
return color;
case SamplerComponentType::Sint:
return ctx.OpConvertSToF(ctx.F32[4], color);
case SamplerComponentType::Stencil:
{
const Id converted{ctx.OpConvertUToF(ctx.F32[4], color)};
const Id inv255{ctx.Const(1.0f / 255.0f)};
const Id scale{ctx.ConstantComposite(ctx.F32[4], inv255, inv255, inv255, inv255)};
return ctx.OpFMul(ctx.F32[4], converted, scale);
}
case SamplerComponentType::Uint:
return ctx.OpConvertUToF(ctx.F32[4], color);
}
throw InvalidArgument("Invalid sampler component type {}", def.component_type);
}
Id TextureImage(EmitContext& ctx, IR::TextureInstInfo info, const IR::Value& index) {
if (!index.IsImmediate() || index.U32() != 0) {
throw NotImplementedException("Indirect image indexing");
@@ -449,31 +487,39 @@ Id EmitBoundImageWrite(EmitContext&) {
Id EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
Id bias_lc, const IR::Value& offset) {
const auto info{inst->Flags<IR::TextureInstInfo>()};
const TextureDefinition& def{ctx.textures.at(info.descriptor_index)};
const Id color_type{TextureColorResultType(ctx, def)};
const Id texture{Texture(ctx, info, index)};
Id color{};
if (ctx.stage == Stage::Fragment) {
const ImageOperands operands(ctx, info.has_bias != 0, false, info.has_lod_clamp != 0,
bias_lc, offset);
return Emit(&EmitContext::OpImageSparseSampleImplicitLod,
&EmitContext::OpImageSampleImplicitLod, ctx, inst, ctx.F32[4],
Texture(ctx, info, index), coords, operands.MaskOptional(), operands.Span());
color = Emit(&EmitContext::OpImageSparseSampleImplicitLod,
&EmitContext::OpImageSampleImplicitLod, ctx, inst, color_type, texture,
coords, operands.MaskOptional(), operands.Span());
} else {
// We can't use implicit lods on non-fragment stages on SPIR-V. Maxwell hardware behaves as
// if the lod was explicitly zero. This may change on Turing with implicit compute
// derivatives
const Id lod{ctx.Const(0.0f)};
const ImageOperands operands(ctx, false, true, info.has_lod_clamp != 0, lod, offset);
return Emit(&EmitContext::OpImageSparseSampleExplicitLod,
&EmitContext::OpImageSampleExplicitLod, ctx, inst, ctx.F32[4],
Texture(ctx, info, index), coords, operands.Mask(), operands.Span());
color = Emit(&EmitContext::OpImageSparseSampleExplicitLod,
&EmitContext::OpImageSampleExplicitLod, ctx, inst, color_type, texture,
coords, operands.Mask(), operands.Span());
}
return TextureSampleResultToFloat(ctx, def, color);
}
Id EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
Id lod, const IR::Value& offset) {
const auto info{inst->Flags<IR::TextureInstInfo>()};
const TextureDefinition& def{ctx.textures.at(info.descriptor_index)};
const Id color_type{TextureColorResultType(ctx, def)};
const ImageOperands operands(ctx, false, true, false, lod, offset);
return Emit(&EmitContext::OpImageSparseSampleExplicitLod,
&EmitContext::OpImageSampleExplicitLod, ctx, inst, ctx.F32[4],
Texture(ctx, info, index), coords, operands.Mask(), operands.Span());
const Id color{Emit(&EmitContext::OpImageSparseSampleExplicitLod,
&EmitContext::OpImageSampleExplicitLod, ctx, inst, color_type,
Texture(ctx, info, index), coords, operands.Mask(), operands.Span())};
return TextureSampleResultToFloat(ctx, def, color);
}
Id EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index,
@@ -509,13 +555,18 @@ Id EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Va
Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
const IR::Value& offset, const IR::Value& offset2) {
const auto info{inst->Flags<IR::TextureInstInfo>()};
const TextureDefinition& def{ctx.textures.at(info.descriptor_index)};
const Id color_type{TextureColorResultType(ctx, def)};
const ImageOperands operands(ctx, offset, offset2);
const Id texture{Texture(ctx, info, index)};
if (ctx.profile.need_gather_subpixel_offset) {
coords = ImageGatherSubpixelOffset(ctx, info, TextureImage(ctx, info, index), coords);
}
return Emit(&EmitContext::OpImageSparseGather, &EmitContext::OpImageGather, ctx, inst,
ctx.F32[4], Texture(ctx, info, index), coords, ctx.Const(info.gather_component),
operands.MaskOptional(), operands.Span());
const Id color{
Emit(&EmitContext::OpImageSparseGather, &EmitContext::OpImageGather, ctx, inst, color_type,
texture, coords, ctx.Const(info.gather_component), operands.MaskOptional(),
operands.Span())};
return TextureSampleResultToFloat(ctx, def, color);
}
Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
@@ -533,6 +584,9 @@ Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, const IR::Value& index,
Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id offset,
Id lod, Id ms) {
const auto info{inst->Flags<IR::TextureInstInfo>()};
const TextureDefinition* def =
info.type == TextureType::Buffer ? nullptr : &ctx.textures.at(info.descriptor_index);
const Id result_type{def ? TextureColorResultType(ctx, *def) : ctx.F32[4]};
AddOffsetToCoordinates(ctx, info, coords, offset);
if (info.type == TextureType::Buffer) {
lod = Id{};
@@ -542,8 +596,13 @@ Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id c
lod = Id{};
}
const ImageOperands operands(lod, ms);
return Emit(&EmitContext::OpImageSparseFetch, &EmitContext::OpImageFetch, ctx, inst, ctx.F32[4],
TextureImage(ctx, info, index), coords, operands.MaskOptional(), operands.Span());
Id color{Emit(&EmitContext::OpImageSparseFetch, &EmitContext::OpImageFetch, ctx, inst,
result_type, TextureImage(ctx, info, index), coords, operands.MaskOptional(),
operands.Span())};
if (def) {
color = TextureSampleResultToFloat(ctx, *def, color);
}
return color;
}
Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id lod,
@@ -588,14 +647,17 @@ Id EmitImageQueryLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, I
Id EmitImageGradient(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
Id derivatives, const IR::Value& offset, Id lod_clamp) {
const auto info{inst->Flags<IR::TextureInstInfo>()};
const TextureDefinition& def{ctx.textures.at(info.descriptor_index)};
const Id color_type{TextureColorResultType(ctx, def)};
const auto operands = info.num_derivatives == 3
? ImageOperands(ctx, info.has_lod_clamp != 0, derivatives,
ctx.Def(offset), {}, lod_clamp)
: ImageOperands(ctx, info.has_lod_clamp != 0, derivatives,
info.num_derivatives, offset, lod_clamp);
return Emit(&EmitContext::OpImageSparseSampleExplicitLod,
&EmitContext::OpImageSampleExplicitLod, ctx, inst, ctx.F32[4],
Texture(ctx, info, index), coords, operands.Mask(), operands.Span());
const Id color{Emit(&EmitContext::OpImageSparseSampleExplicitLod,
&EmitContext::OpImageSampleExplicitLod, ctx, inst, color_type,
Texture(ctx, info, index), coords, operands.Mask(), operands.Span())};
return TextureSampleResultToFloat(ctx, def, color);
}
Id EmitImageRead(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords) {
@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -78,9 +81,25 @@ Id AddPartitionBase(EmitContext& ctx, Id thread_id) {
const Id partition_base{ctx.OpShiftLeftLogical(ctx.U32[1], partition_idx, ctx.Const(5u))};
return ctx.OpIAdd(ctx.U32[1], thread_id, partition_base);
}
bool SupportsWarpIntrinsics(const EmitContext& ctx) {
return ctx.profile.SupportsWarpIntrinsics(ctx.stage);
}
void SetAlwaysInBounds(EmitContext& ctx, IR::Inst* inst) {
SetInBoundsFlag(inst, ctx.true_value);
}
Id FallbackBallotMask(EmitContext& ctx, Id pred) {
const Id full_mask{ctx.Const(0xFFFFFFFFu)};
return ctx.OpSelect(ctx.U32[1], pred, full_mask, ctx.u32_zero_value);
}
} // Anonymous namespace
Id EmitLaneId(EmitContext& ctx) {
if (!SupportsWarpIntrinsics(ctx)) {
return ctx.u32_zero_value;
}
const Id id{GetThreadId(ctx)};
if (!ctx.profile.warp_size_potentially_larger_than_guest) {
return id;
@@ -89,6 +108,9 @@ Id EmitLaneId(EmitContext& ctx) {
}
Id EmitVoteAll(EmitContext& ctx, Id pred) {
if (!SupportsWarpIntrinsics(ctx)) {
return pred;
}
if (!ctx.profile.warp_size_potentially_larger_than_guest) {
return ctx.OpGroupNonUniformAll(ctx.U1, SubgroupScope(ctx), pred);
}
@@ -102,6 +124,9 @@ Id EmitVoteAll(EmitContext& ctx, Id pred) {
}
Id EmitVoteAny(EmitContext& ctx, Id pred) {
if (!SupportsWarpIntrinsics(ctx)) {
return pred;
}
if (!ctx.profile.warp_size_potentially_larger_than_guest) {
return ctx.OpGroupNonUniformAny(ctx.U1, SubgroupScope(ctx), pred);
}
@@ -115,6 +140,9 @@ Id EmitVoteAny(EmitContext& ctx, Id pred) {
}
Id EmitVoteEqual(EmitContext& ctx, Id pred) {
if (!SupportsWarpIntrinsics(ctx)) {
return pred;
}
if (!ctx.profile.warp_size_potentially_larger_than_guest) {
return ctx.OpGroupNonUniformAllEqual(ctx.U1, SubgroupScope(ctx), pred);
}
@@ -129,6 +157,9 @@ Id EmitVoteEqual(EmitContext& ctx, Id pred) {
}
Id EmitSubgroupBallot(EmitContext& ctx, Id pred) {
if (!SupportsWarpIntrinsics(ctx)) {
return FallbackBallotMask(ctx, pred);
}
const Id ballot{ctx.OpGroupNonUniformBallot(ctx.U32[4], SubgroupScope(ctx), pred)};
if (!ctx.profile.warp_size_potentially_larger_than_guest) {
return ctx.OpCompositeExtract(ctx.U32[1], ballot, 0U);
@@ -137,27 +168,46 @@ Id EmitSubgroupBallot(EmitContext& ctx, Id pred) {
}
Id EmitSubgroupEqMask(EmitContext& ctx) {
if (!SupportsWarpIntrinsics(ctx)) {
return ctx.u32_zero_value;
}
return LoadMask(ctx, ctx.subgroup_mask_eq);
}
Id EmitSubgroupLtMask(EmitContext& ctx) {
if (!SupportsWarpIntrinsics(ctx)) {
return ctx.u32_zero_value;
}
return LoadMask(ctx, ctx.subgroup_mask_lt);
}
Id EmitSubgroupLeMask(EmitContext& ctx) {
if (!SupportsWarpIntrinsics(ctx)) {
return ctx.u32_zero_value;
}
return LoadMask(ctx, ctx.subgroup_mask_le);
}
Id EmitSubgroupGtMask(EmitContext& ctx) {
if (!SupportsWarpIntrinsics(ctx)) {
return ctx.u32_zero_value;
}
return LoadMask(ctx, ctx.subgroup_mask_gt);
}
Id EmitSubgroupGeMask(EmitContext& ctx) {
if (!SupportsWarpIntrinsics(ctx)) {
return ctx.u32_zero_value;
}
return LoadMask(ctx, ctx.subgroup_mask_ge);
}
Id EmitShuffleIndex(EmitContext& ctx, IR::Inst* inst, Id value, Id index, Id clamp,
Id segmentation_mask) {
if (!SupportsWarpIntrinsics(ctx)) {
SetAlwaysInBounds(ctx, inst);
return value;
}
const Id not_seg_mask{ctx.OpNot(ctx.U32[1], segmentation_mask)};
const Id thread_id{EmitLaneId(ctx)};
const Id min_thread_id{ComputeMinThreadId(ctx, thread_id, segmentation_mask)};
@@ -177,6 +227,10 @@ Id EmitShuffleIndex(EmitContext& ctx, IR::Inst* inst, Id value, Id index, Id cla
Id EmitShuffleUp(EmitContext& ctx, IR::Inst* inst, Id value, Id index, Id clamp,
Id segmentation_mask) {
if (!SupportsWarpIntrinsics(ctx)) {
SetAlwaysInBounds(ctx, inst);
return value;
}
const Id thread_id{EmitLaneId(ctx)};
const Id max_thread_id{GetMaxThreadId(ctx, thread_id, clamp, segmentation_mask)};
Id src_thread_id{ctx.OpISub(ctx.U32[1], thread_id, index)};
@@ -192,6 +246,10 @@ Id EmitShuffleUp(EmitContext& ctx, IR::Inst* inst, Id value, Id index, Id clamp,
Id EmitShuffleDown(EmitContext& ctx, IR::Inst* inst, Id value, Id index, Id clamp,
Id segmentation_mask) {
if (!SupportsWarpIntrinsics(ctx)) {
SetAlwaysInBounds(ctx, inst);
return value;
}
const Id thread_id{EmitLaneId(ctx)};
const Id max_thread_id{GetMaxThreadId(ctx, thread_id, clamp, segmentation_mask)};
Id src_thread_id{ctx.OpIAdd(ctx.U32[1], thread_id, index)};
@@ -207,6 +265,10 @@ Id EmitShuffleDown(EmitContext& ctx, IR::Inst* inst, Id value, Id index, Id clam
Id EmitShuffleButterfly(EmitContext& ctx, IR::Inst* inst, Id value, Id index, Id clamp,
Id segmentation_mask) {
if (!SupportsWarpIntrinsics(ctx)) {
SetAlwaysInBounds(ctx, inst);
return value;
}
const Id thread_id{EmitLaneId(ctx)};
const Id max_thread_id{GetMaxThreadId(ctx, thread_id, clamp, segmentation_mask)};
Id src_thread_id{ctx.OpBitwiseXor(ctx.U32[1], thread_id, index)};
@@ -28,27 +28,41 @@ enum class Operation {
FPMax,
};
Id ImageType(EmitContext& ctx, const TextureDescriptor& desc) {
Id ComponentScalarType(EmitContext& ctx, SamplerComponentType component_type) {
switch (component_type) {
case SamplerComponentType::Float:
case SamplerComponentType::Depth:
return ctx.F32[1];
case SamplerComponentType::Sint:
return ctx.S32[1];
case SamplerComponentType::Stencil:
return ctx.U32[1];
case SamplerComponentType::Uint:
return ctx.U32[1];
}
throw InvalidArgument("Invalid sampler component type {}", component_type);
}
Id ImageType(EmitContext& ctx, const TextureDescriptor& desc, Id sampled_type) {
const spv::ImageFormat format{spv::ImageFormat::Unknown};
const Id type{ctx.F32[1]};
const bool depth{desc.is_depth};
const bool ms{desc.is_multisample};
switch (desc.type) {
case TextureType::Color1D:
return ctx.TypeImage(type, spv::Dim::Dim1D, depth, false, false, 1, format);
return ctx.TypeImage(sampled_type, spv::Dim::Dim1D, depth, false, false, 1, format);
case TextureType::ColorArray1D:
return ctx.TypeImage(type, spv::Dim::Dim1D, depth, true, false, 1, format);
return ctx.TypeImage(sampled_type, spv::Dim::Dim1D, depth, true, false, 1, format);
case TextureType::Color2D:
case TextureType::Color2DRect:
return ctx.TypeImage(type, spv::Dim::Dim2D, depth, false, ms, 1, format);
return ctx.TypeImage(sampled_type, spv::Dim::Dim2D, depth, false, ms, 1, format);
case TextureType::ColorArray2D:
return ctx.TypeImage(type, spv::Dim::Dim2D, depth, true, ms, 1, format);
return ctx.TypeImage(sampled_type, spv::Dim::Dim2D, depth, true, ms, 1, format);
case TextureType::Color3D:
return ctx.TypeImage(type, spv::Dim::Dim3D, depth, false, false, 1, format);
return ctx.TypeImage(sampled_type, spv::Dim::Dim3D, depth, false, false, 1, format);
case TextureType::ColorCube:
return ctx.TypeImage(type, spv::Dim::Cube, depth, false, false, 1, format);
return ctx.TypeImage(sampled_type, spv::Dim::Cube, depth, false, false, 1, format);
case TextureType::ColorArrayCube:
return ctx.TypeImage(type, spv::Dim::Cube, depth, true, false, 1, format);
return ctx.TypeImage(sampled_type, spv::Dim::Cube, depth, true, false, 1, format);
case TextureType::Buffer:
break;
}
@@ -315,6 +329,9 @@ void DefineSsbos(EmitContext& ctx, StorageTypeDefinition& type_def,
ctx.Decorate(id, spv::Decoration::Binding, binding);
ctx.Decorate(id, spv::Decoration::DescriptorSet, 0U);
ctx.Name(id, fmt::format("ssbo{}", index));
if (!desc.is_written) {
ctx.Decorate(id, spv::Decoration::NonWritable);
}
if (ctx.profile.supported_spirv >= 0x00010400) {
ctx.interfaces.push_back(id);
}
@@ -546,6 +563,7 @@ void EmitContext::DefineCommonTypes(const Info& info) {
output_f32 = Name(TypePointer(spv::StorageClass::Output, F32[1]), "output_f32");
output_u32 = Name(TypePointer(spv::StorageClass::Output, U32[1]), "output_u32");
output_s32 = Name(TypePointer(spv::StorageClass::Output, S32[1]), "output_s32");
if (info.uses_int8 && profile.support_int8) {
AddCapability(spv::Capability::Int8);
@@ -1359,7 +1377,8 @@ void EmitContext::DefineImageBuffers(const Info& info, u32& binding) {
void EmitContext::DefineTextures(const Info& info, u32& binding, u32& scaling_index) {
textures.reserve(info.texture_descriptors.size());
for (const TextureDescriptor& desc : info.texture_descriptors) {
const Id image_type{ImageType(*this, desc)};
const Id result_type{ComponentScalarType(*this, desc.component_type)};
const Id image_type{ImageType(*this, desc, result_type)};
const Id sampled_type{TypeSampledImage(image_type)};
const Id pointer_type{TypePointer(spv::StorageClass::UniformConstant, sampled_type)};
const Id desc_type{DescType(*this, sampled_type, pointer_type, desc.count)};
@@ -1372,8 +1391,10 @@ void EmitContext::DefineTextures(const Info& info, u32& binding, u32& scaling_in
.sampled_type = sampled_type,
.pointer_type = pointer_type,
.image_type = image_type,
.result_type = result_type,
.count = desc.count,
.is_multisample = desc.is_multisample,
.component_type = desc.component_type,
});
if (profile.supported_spirv >= 0x00010400) {
interfaces.push_back(id);
@@ -1416,6 +1437,7 @@ void EmitContext::DefineImages(const Info& info, u32& binding, u32& scaling_inde
void EmitContext::DefineInputs(const IR::Program& program) {
const Info& info{program.info};
const VaryingState loads{info.loads.mask | info.passthrough.mask};
const bool stage_supports_warp = profile.SupportsWarpIntrinsics(stage);
if (info.uses_workgroup_id) {
workgroup_id = DefineInput(*this, U32[3], false, spv::BuiltIn::WorkgroupId);
@@ -1432,24 +1454,37 @@ void EmitContext::DefineInputs(const IR::Program& program) {
}
if (info.uses_sample_id) {
sample_id = DefineInput(*this, U32[1], false, spv::BuiltIn::SampleId);
if (stage == Stage::Fragment) {
Decorate(sample_id, spv::Decoration::Flat);
}
}
if (info.uses_is_helper_invocation) {
is_helper_invocation = DefineInput(*this, U1, false, spv::BuiltIn::HelperInvocation);
}
if (info.uses_subgroup_mask) {
if (info.uses_subgroup_mask && stage_supports_warp) {
subgroup_mask_eq = DefineInput(*this, U32[4], false, spv::BuiltIn::SubgroupEqMaskKHR);
subgroup_mask_lt = DefineInput(*this, U32[4], false, spv::BuiltIn::SubgroupLtMaskKHR);
subgroup_mask_le = DefineInput(*this, U32[4], false, spv::BuiltIn::SubgroupLeMaskKHR);
subgroup_mask_gt = DefineInput(*this, U32[4], false, spv::BuiltIn::SubgroupGtMaskKHR);
subgroup_mask_ge = DefineInput(*this, U32[4], false, spv::BuiltIn::SubgroupGeMaskKHR);
if (stage == Stage::Fragment) {
Decorate(subgroup_mask_eq, spv::Decoration::Flat);
Decorate(subgroup_mask_lt, spv::Decoration::Flat);
Decorate(subgroup_mask_le, spv::Decoration::Flat);
Decorate(subgroup_mask_gt, spv::Decoration::Flat);
Decorate(subgroup_mask_ge, spv::Decoration::Flat);
}
}
if (info.uses_fswzadd || info.uses_subgroup_invocation_id || info.uses_subgroup_shuffles ||
(profile.warp_size_potentially_larger_than_guest &&
(info.uses_subgroup_vote || info.uses_subgroup_mask))) {
if (stage_supports_warp &&
(info.uses_fswzadd || info.uses_subgroup_invocation_id || info.uses_subgroup_shuffles ||
(profile.warp_size_potentially_larger_than_guest &&
(info.uses_subgroup_vote || info.uses_subgroup_mask)))) {
AddCapability(spv::Capability::GroupNonUniform);
subgroup_local_invocation_id =
DefineInput(*this, U32[1], false, spv::BuiltIn::SubgroupLocalInvocationId);
Decorate(subgroup_local_invocation_id, spv::Decoration::Flat);
if (stage == Stage::Fragment) {
Decorate(subgroup_local_invocation_id, spv::Decoration::Flat);
}
}
if (info.uses_fswzadd) {
const Id f32_one{Const(1.0f)};
@@ -1461,6 +1496,9 @@ void EmitContext::DefineInputs(const IR::Program& program) {
}
if (loads[IR::Attribute::PrimitiveId]) {
primitive_id = DefineInput(*this, U32[1], false, spv::BuiltIn::PrimitiveId);
if (stage == Stage::Fragment) {
Decorate(primitive_id, spv::Decoration::Flat);
}
}
if (loads[IR::Attribute::Layer]) {
AddCapability(spv::Capability::Geometry);
@@ -1552,17 +1590,21 @@ void EmitContext::DefineInputs(const IR::Program& program) {
if (stage != Stage::Fragment) {
continue;
}
switch (info.interpolation[index]) {
case Interpolation::Smooth:
// Default
// Decorate(id, spv::Decoration::Smooth);
break;
case Interpolation::NoPerspective:
Decorate(id, spv::Decoration::NoPerspective);
break;
case Interpolation::Flat:
const bool is_integer = input_type == AttributeType::SignedInt ||
input_type == AttributeType::UnsignedInt;
if (is_integer) {
Decorate(id, spv::Decoration::Flat);
break;
} else {
switch (info.interpolation[index]) {
case Interpolation::Smooth:
break;
case Interpolation::NoPerspective:
Decorate(id, spv::Decoration::NoPerspective);
break;
case Interpolation::Flat:
Decorate(id, spv::Decoration::Flat);
break;
}
}
}
if (stage == Stage::TessellationEval) {
@@ -1658,7 +1700,18 @@ void EmitContext::DefineOutputs(const IR::Program& program) {
if (!info.stores_frag_color[index] && !profile.need_declared_frag_colors) {
continue;
}
frag_color[index] = DefineOutput(*this, F32[4], std::nullopt);
const AttributeType output_type{runtime_info.color_output_types[index]};
const Id vec_type = [&, output_type]() -> Id {
switch (output_type) {
case AttributeType::SignedInt:
return S32[4];
case AttributeType::UnsignedInt:
return U32[4];
default:
return F32[4];
}
}();
frag_color[index] = DefineOutput(*this, vec_type, std::nullopt);
Decorate(frag_color[index], spv::Decoration::Location, index);
Name(frag_color[index], fmt::format("frag_color{}", index));
}
@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -36,8 +39,10 @@ struct TextureDefinition {
Id sampled_type;
Id pointer_type;
Id image_type;
Id result_type;
u32 count;
bool is_multisample;
SamplerComponentType component_type;
};
struct TextureBufferDefinition {
@@ -244,6 +249,7 @@ public:
Id output_f32{};
Id output_u32{};
Id output_s32{};
Id image_buffer_type{};
Id image_u32{};
+5
View File
@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -22,6 +25,8 @@ public:
[[nodiscard]] virtual TextureType ReadTextureType(u32 raw_handle) = 0;
[[nodiscard]] virtual SamplerComponentType ReadTextureComponentType(u32 raw_handle) = 0;
[[nodiscard]] virtual TexturePixelFormat ReadTexturePixelFormat(u32 raw_handle) = 0;
[[nodiscard]] virtual bool IsTexturePixelFormatInteger(u32 raw_handle) = 0;
@@ -396,6 +396,10 @@ bool IsTexturePixelFormatInteger(Environment& env, const ConstBufferAddr& cbuf)
return env.IsTexturePixelFormatInteger(GetTextureHandle(env, cbuf));
}
SamplerComponentType ReadTextureComponentType(Environment& env, const ConstBufferAddr& cbuf) {
return env.ReadTextureComponentType(GetTextureHandle(env, cbuf));
}
class Descriptors {
public:
explicit Descriptors(TextureBufferDescriptors& texture_buffer_descriptors_,
@@ -433,7 +437,9 @@ public:
u32 Add(const TextureDescriptor& desc) {
const u32 index{Add(texture_descriptors, desc, [&desc](const auto& existing) {
return desc.type == existing.type && desc.is_depth == existing.is_depth &&
return desc.type == existing.type &&
desc.component_type == existing.component_type &&
desc.is_depth == existing.is_depth &&
desc.has_secondary == existing.has_secondary &&
desc.cbuf_index == existing.cbuf_index &&
desc.cbuf_offset == existing.cbuf_offset &&
@@ -666,10 +672,12 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo
.secondary_shift_left = cbuf.secondary_shift_left,
.count = cbuf.count,
.size_shift = DESCRIPTOR_SIZE_SHIFT,
.component_type = ReadTextureComponentType(env, cbuf),
});
} else {
index = descriptors.Add(TextureDescriptor{
.type = flags.type,
.component_type = ReadTextureComponentType(env, cbuf),
.is_depth = flags.is_depth != 0,
.is_multisample = is_multisample,
.has_secondary = cbuf.has_secondary,
+13
View File
@@ -1,9 +1,15 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <limits>
#include "common/common_types.h"
#include "shader_recompiler/stage.h"
namespace Shader {
@@ -46,6 +52,8 @@ struct Profile {
bool support_multi_viewport{};
bool support_geometry_streams{};
u32 warp_stage_support_mask{std::numeric_limits<u32>::max()};
bool warp_size_potentially_larger_than_guest{};
bool lower_left_origin_mode{};
@@ -90,6 +98,11 @@ struct Profile {
u64 min_ssbo_alignment{};
u32 max_user_clip_distances{};
bool SupportsWarpIntrinsics(Stage stage) const {
const u32 bit = 1u << static_cast<u32>(stage);
return (warp_stage_support_mask & bit) != 0;
}
};
} // namespace Shader
+4
View File
@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -80,6 +83,7 @@ struct TransformFeedbackVarying {
struct RuntimeInfo {
std::array<AttributeType, 32> generic_input_types{};
std::array<AttributeType, 8> color_output_types{};
VaryingState previous_stage_stores;
std::map<IR::Attribute, IR::Attribute> previous_stage_legacy_stores_mapping;
+13
View File
@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -151,6 +154,14 @@ enum class ImageFormat : u32 {
R32G32B32A32_UINT,
};
enum class SamplerComponentType : u8 {
Float,
Sint,
Uint,
Depth,
Stencil,
};
enum class Interpolation {
Smooth,
Flat,
@@ -183,6 +194,7 @@ struct TextureBufferDescriptor {
u32 secondary_shift_left;
u32 count;
u32 size_shift;
SamplerComponentType component_type;
auto operator<=>(const TextureBufferDescriptor&) const = default;
};
@@ -204,6 +216,7 @@ using ImageBufferDescriptors = boost::container::small_vector<ImageBufferDescrip
struct TextureDescriptor {
TextureType type;
SamplerComponentType component_type;
bool is_depth;
bool is_multisample;
bool has_secondary;
+94 -17
View File
@@ -407,6 +407,12 @@ void BufferCache<P>::SetComputeUniformBufferState(u32 mask,
template <class P>
void BufferCache<P>::UnbindGraphicsStorageBuffers(size_t stage) {
if constexpr (requires { runtime.ShouldLimitDynamicStorageBuffers(); }) {
if (runtime.ShouldLimitDynamicStorageBuffers()) {
channel_state->total_graphics_storage_buffers -=
static_cast<u32>(std::popcount(channel_state->enabled_storage_buffers[stage]));
}
}
channel_state->enabled_storage_buffers[stage] = 0;
channel_state->written_storage_buffers[stage] = 0;
}
@@ -414,8 +420,26 @@ void BufferCache<P>::UnbindGraphicsStorageBuffers(size_t stage) {
template <class P>
bool BufferCache<P>::BindGraphicsStorageBuffer(size_t stage, size_t ssbo_index, u32 cbuf_index,
u32 cbuf_offset, bool is_written) {
const bool already_enabled =
((channel_state->enabled_storage_buffers[stage] >> ssbo_index) & 1U) != 0;
if constexpr (requires { runtime.ShouldLimitDynamicStorageBuffers(); }) {
if (runtime.ShouldLimitDynamicStorageBuffers() && !already_enabled) {
const u32 max_bindings = runtime.GetMaxDynamicStorageBuffers();
if (channel_state->total_graphics_storage_buffers >= max_bindings) {
LOG_WARNING(HW_GPU,
"Skipping graphics storage buffer {} due to driver limit {}",
ssbo_index, max_bindings);
return false;
}
}
}
channel_state->enabled_storage_buffers[stage] |= 1U << ssbo_index;
channel_state->written_storage_buffers[stage] |= (is_written ? 1U : 0U) << ssbo_index;
if constexpr (requires { runtime.ShouldLimitDynamicStorageBuffers(); }) {
if (runtime.ShouldLimitDynamicStorageBuffers() && !already_enabled) {
++channel_state->total_graphics_storage_buffers;
}
}
const auto& cbufs = maxwell3d->state.shader_stages[stage];
const GPUVAddr ssbo_addr = cbufs.const_buffers[cbuf_index].address + cbuf_offset;
@@ -446,6 +470,12 @@ void BufferCache<P>::BindGraphicsTextureBuffer(size_t stage, size_t tbo_index, G
template <class P>
void BufferCache<P>::UnbindComputeStorageBuffers() {
if constexpr (requires { runtime.ShouldLimitDynamicStorageBuffers(); }) {
if (runtime.ShouldLimitDynamicStorageBuffers()) {
channel_state->total_compute_storage_buffers -=
static_cast<u32>(std::popcount(channel_state->enabled_compute_storage_buffers));
}
}
channel_state->enabled_compute_storage_buffers = 0;
channel_state->written_compute_storage_buffers = 0;
channel_state->image_compute_texture_buffers = 0;
@@ -459,8 +489,26 @@ void BufferCache<P>::BindComputeStorageBuffer(size_t ssbo_index, u32 cbuf_index,
ssbo_index);
return;
}
const bool already_enabled =
((channel_state->enabled_compute_storage_buffers >> ssbo_index) & 1U) != 0;
if constexpr (requires { runtime.ShouldLimitDynamicStorageBuffers(); }) {
if (runtime.ShouldLimitDynamicStorageBuffers() && !already_enabled) {
const u32 max_bindings = runtime.GetMaxDynamicStorageBuffers();
if (channel_state->total_compute_storage_buffers >= max_bindings) {
LOG_WARNING(HW_GPU,
"Skipping compute storage buffer {} due to driver limit {}",
ssbo_index, max_bindings);
return;
}
}
}
channel_state->enabled_compute_storage_buffers |= 1U << ssbo_index;
channel_state->written_compute_storage_buffers |= (is_written ? 1U : 0U) << ssbo_index;
if constexpr (requires { runtime.ShouldLimitDynamicStorageBuffers(); }) {
if (runtime.ShouldLimitDynamicStorageBuffers() && !already_enabled) {
++channel_state->total_compute_storage_buffers;
}
}
const auto& launch_desc = kepler_compute->launch_description;
if (((launch_desc.const_buffer_enable_mask >> cbuf_index) & 1) == 0) {
@@ -793,9 +841,23 @@ void BufferCache<P>::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32
const u32 size = (std::min)(binding.size, (*channel_state->uniform_buffer_sizes)[stage][index]);
Buffer& buffer = slot_buffers[binding.buffer_id];
TouchBuffer(buffer, binding.buffer_id);
const bool use_fast_buffer = binding.buffer_id != NULL_BUFFER_ID &&
size <= channel_state->uniform_buffer_skip_cache_size &&
!memory_tracker.IsRegionGpuModified(device_addr, size);
const bool has_host_buffer = binding.buffer_id != NULL_BUFFER_ID;
const u32 offset = has_host_buffer ? buffer.Offset(device_addr) : 0;
const bool needs_alignment_stream = [&]() {
if constexpr (IS_OPENGL) {
return false;
} else {
if (!has_host_buffer) {
return false;
}
const u32 alignment = runtime.GetUniformBufferAlignment();
return alignment > 1 && (offset % alignment) != 0;
}
}();
const bool use_fast_buffer = needs_alignment_stream ||
(has_host_buffer &&
size <= channel_state->uniform_buffer_skip_cache_size &&
!memory_tracker.IsRegionGpuModified(device_addr, size));
if (use_fast_buffer) {
if constexpr (IS_OPENGL) {
if (runtime.HasFastBufferSubData()) {
@@ -834,7 +896,6 @@ void BufferCache<P>::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32
if (!needs_bind) {
return;
}
const u32 offset = buffer.Offset(device_addr);
if constexpr (IS_OPENGL) {
// Mark the index as dirty if offset doesn't match
const bool is_copy_bind = offset != 0 && !runtime.SupportsNonZeroUniformOffset();
@@ -951,9 +1012,30 @@ void BufferCache<P>::BindHostComputeUniformBuffers() {
TouchBuffer(buffer, binding.buffer_id);
const u32 size =
(std::min)(binding.size, (*channel_state->compute_uniform_buffer_sizes)[index]);
const bool has_host_buffer = binding.buffer_id != NULL_BUFFER_ID;
const u32 offset = has_host_buffer ? buffer.Offset(binding.device_addr) : 0;
const bool needs_alignment_stream = [&]() {
if constexpr (IS_OPENGL) {
return false;
} else {
if (!has_host_buffer) {
return false;
}
const u32 alignment = runtime.GetUniformBufferAlignment();
return alignment > 1 && (offset % alignment) != 0;
}
}();
if constexpr (!IS_OPENGL) {
if (needs_alignment_stream) {
const std::span<u8> span =
runtime.BindMappedUniformBuffer(0, binding_index, size);
device_memory.ReadBlockUnsafe(binding.device_addr, span.data(), size);
return;
}
}
SynchronizeBuffer(buffer, binding.device_addr, size);
const u32 offset = buffer.Offset(binding.device_addr);
buffer.MarkUsage(offset, size);
if constexpr (NEEDS_BIND_UNIFORM_INDEX) {
runtime.BindComputeUniformBuffer(binding_index, buffer, offset, size);
@@ -1705,26 +1787,21 @@ Binding BufferCache<P>::StorageBufferBinding(GPUVAddr ssbo_addr, u32 cbuf_index,
return NULL_BINDING;
}
// xbzk: New size logic. Fixes MCI.
// If ever the * comment below prove wrong, the 'if' block may be removed.
const auto size = [&]() {
const bool is_nvn_cbuf = cbuf_index == 0;
// The NVN driver buffer (index 0) is known to pack the SSBO address followed by its size.
if (is_nvn_cbuf) {
// * The NVN driver buffer (index 0) is known to pack the SSBO address followed by its size.
const u64 next_qword = gpu_memory->Read<u64>(ssbo_addr + 8);
const u32 upper_32 = static_cast<u32>(next_qword >> 32);
// Hardware-based detection: GPU addresses have non-zero upper bits
if (upper_32 == 0) {
// This is a size field, not a GPU address
return static_cast<u32>(next_qword); // Return lower_32
const u32 ssbo_size = gpu_memory->Read<u32>(ssbo_addr + 8);
if (ssbo_size != 0) {
return ssbo_size;
}
}
// Fall through: either not NVN cbuf (Doom Eternal & +), or NVN but ssbo_addr+8 is a GPU address (MCI)
// Other titles (notably Doom Eternal) may use STG/LDG on buffer addresses in custom defined
// cbufs, which do not store the sizes adjacent to the addresses, so use the fully
// mapped buffer size for now.
const u32 memory_layout_size = static_cast<u32>(gpu_memory->GetMemoryLayoutSize(gpu_addr));
// Cap at 8MB to prevent allocator overflow from misinterpreted addresses
return (std::min)(memory_layout_size, static_cast<u32>(8_MiB));
}();
// Alignment only applies to the offset of the buffer
const u32 alignment = runtime.GetStorageBufferAlignment();
const GPUVAddr aligned_gpu_addr = Common::AlignDown(gpu_addr, alignment);
@@ -8,6 +8,7 @@
#include <algorithm>
#include <array>
#include <bit>
#include <functional>
#include <memory>
#include <mutex>
@@ -132,6 +133,9 @@ public:
u32 enabled_compute_storage_buffers = 0;
u32 written_compute_storage_buffers = 0;
u32 total_graphics_storage_buffers = 0;
u32 total_compute_storage_buffers = 0;
std::array<u32, NUM_STAGES> enabled_texture_buffers{};
std::array<u32, NUM_STAGES> written_texture_buffers{};
std::array<u32, NUM_STAGES> image_texture_buffers{};
+6
View File
@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -235,6 +238,9 @@ constexpr Table MakeViewTable() {
EnableRange(view, VIEW_CLASS_ASTC_10x10_RGBA);
EnableRange(view, VIEW_CLASS_ASTC_12x10_RGBA);
EnableRange(view, VIEW_CLASS_ASTC_12x12_RGBA);
Enable(view, PixelFormat::D24_UNORM_S8_UINT, PixelFormat::S8_UINT);
Enable(view, PixelFormat::S8_UINT_D24_UNORM, PixelFormat::S8_UINT);
Enable(view, PixelFormat::D32_FLOAT_S8_UINT, PixelFormat::S8_UINT);
return view;
}
+8 -3
View File
@@ -91,6 +91,10 @@ public:
uncommitted_operations.clear();
}
QueueFence(new_fence);
if (!new_fence->IsStubbed()) {
std::scoped_lock lock{texture_cache.mutex};
texture_cache.CommitPendingGpuAccesses(new_fence->WaitTick());
}
fences.push(std::move(new_fence));
if (should_flush) {
rasterizer.FlushCommands();
@@ -179,7 +183,7 @@ private:
return;
}
}
PopAsyncFlushes();
PopAsyncFlushes(current_fence->WaitTick());
auto operations = std::move(pending_operations.front());
pending_operations.pop_front();
for (auto& operation : operations) {
@@ -214,7 +218,7 @@ private:
if (!current_fence->IsStubbed()) {
WaitFence(current_fence);
}
PopAsyncFlushes();
PopAsyncFlushes(current_fence->WaitTick());
for (auto& operation : current_operations) {
operation();
}
@@ -237,10 +241,11 @@ private:
query_cache.HasUncommittedFlushes();
}
void PopAsyncFlushes() {
void PopAsyncFlushes(u64 completed_tick) {
{
std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
texture_cache.PopAsyncFlushes();
texture_cache.CompleteGpuAccesses(completed_tick);
buffer_cache.PopAsyncFlushes();
}
query_cache.PopAsyncFlushes();
+5 -4
View File
@@ -13,7 +13,6 @@
#include "common/assert.h"
#include "common/settings.h"
#include "common/settings_enums.h"
#include "core/core.h"
#include "core/core_timing.h"
#include "core/frontend/emu_window.h"
@@ -201,10 +200,12 @@ struct GPU::Impl {
[[nodiscard]] u64 GetTicks() const {
u64 gpu_tick = system.CoreTiming().GetGPUTicks();
Settings::GpuOverclock overclock = Settings::values.fast_gpu_time.GetValue();
if (overclock != Settings::GpuOverclock::Normal) {
gpu_tick /= 256 * u64(overclock);
if (Settings::values.use_fast_gpu_time.GetValue()) {
gpu_tick /= (u64) (128
* std::pow(2,
static_cast<u32>(
Settings::values.fast_gpu_time.GetValue())));
}
return gpu_tick;
+6
View File
@@ -211,6 +211,12 @@ void QueryCacheBase<Traits>::CounterClose(QueryType counter_type) {
streamer->CloseCounter();
}
template <typename Traits>
bool QueryCacheBase<Traits>::HasStreamer(QueryType counter_type) const {
const size_t index = static_cast<size_t>(counter_type);
return impl->streamers[index] != nullptr;
}
template <typename Traits>
void QueryCacheBase<Traits>::CounterReset(QueryType counter_type) {
size_t index = static_cast<size_t>(counter_type);
@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
@@ -92,6 +95,8 @@ public:
void CounterReset(QueryType counter_type);
[[nodiscard]] bool HasStreamer(QueryType counter_type) const;
void CounterClose(QueryType counter_type);
void CounterReport(GPUVAddr addr, QueryType counter_type, QueryPropertiesFlags flags,
@@ -198,6 +198,10 @@ public:
return device.CanReportMemoryUsage();
}
u32 GetUniformBufferAlignment() const {
return static_cast<u32>(device.GetUniformBufferAlignment());
}
u32 GetStorageBufferAlignment() const {
return static_cast<u32>(device.GetShaderStorageBufferAlignment());
}
@@ -7,13 +7,50 @@
#include <cstring>
#include <bit>
#include <numeric>
#include <optional>
#include "common/cityhash.h"
#include "common/settings.h" // for enum class Settings::ShaderBackend
#include "video_core/renderer_opengl/gl_compute_pipeline.h"
#include "video_core/renderer_opengl/gl_shader_manager.h"
#include "video_core/renderer_opengl/gl_shader_util.h"
#include "video_core/surface.h"
namespace OpenGL {
namespace {
std::optional<VideoCore::Surface::PixelFormatNumeric>
NumericFromComponentType(Shader::SamplerComponentType component_type) {
using VideoCore::Surface::PixelFormatNumeric;
switch (component_type) {
case Shader::SamplerComponentType::Float:
return PixelFormatNumeric::Float;
case Shader::SamplerComponentType::Sint:
return PixelFormatNumeric::Sint;
case Shader::SamplerComponentType::Uint:
return PixelFormatNumeric::Uint;
default:
return std::nullopt;
}
}
VideoCore::Surface::PixelFormat ResolveTexelBufferFormat(
VideoCore::Surface::PixelFormat format, Shader::SamplerComponentType component_type) {
const auto desired_numeric = NumericFromComponentType(component_type);
if (!desired_numeric) {
return format;
}
const auto current_numeric = VideoCore::Surface::GetPixelFormatNumericType(format);
if (*desired_numeric == current_numeric) {
return format;
}
if (const auto variant =
VideoCore::Surface::FindPixelFormatVariant(format, *desired_numeric)) {
return *variant;
}
return format;
}
} // Anonymous namespace
using Shader::ImageBufferDescriptor;
using Tegra::Texture::TexturePair;
@@ -174,8 +211,12 @@ void ComputePipeline::Configure() {
is_written = desc.is_written;
}
ImageView& image_view{texture_cache.GetImageView(views[texbuf_index].id)};
auto buffer_format = image_view.format;
if constexpr (!is_image) {
buffer_format = ResolveTexelBufferFormat(buffer_format, desc.component_type);
}
buffer_cache.BindComputeTextureBuffer(texbuf_index, image_view.GpuAddr(),
image_view.BufferSize(), image_view.format,
image_view.BufferSize(), buffer_format,
is_written, is_image);
++texbuf_index;
}
@@ -205,7 +246,8 @@ void ComputePipeline::Configure() {
for (const auto& desc : info.texture_descriptors) {
for (u32 index = 0; index < desc.count; ++index) {
ImageView& image_view{texture_cache.GetImageView((views_it++)->id)};
textures[texture_binding] = image_view.Handle(desc.type);
textures[texture_binding] =
image_view.SampledView(desc.type, desc.component_type);
if (texture_cache.IsRescaling(image_view)) {
texture_scaling_mask |= 1u << texture_binding;
}
@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -25,6 +28,10 @@ public:
void Wait();
[[nodiscard]] u64 WaitTick() const noexcept {
return 0;
}
private:
OGLSync sync_object;
};
@@ -6,6 +6,7 @@
#include <algorithm>
#include <array>
#include <optional>
#include <string>
#include <vector>
#include <bit>
@@ -18,6 +19,7 @@
#include "video_core/renderer_opengl/gl_shader_util.h"
#include "video_core/renderer_opengl/gl_state_tracker.h"
#include "video_core/shader_notify.h"
#include "video_core/surface.h"
#include "video_core/texture_cache/texture_cache.h"
#if defined(_MSC_VER) && defined(NDEBUG)
@@ -39,6 +41,38 @@ using VideoCommon::ImageId;
constexpr u32 MAX_TEXTURES = 64;
constexpr u32 MAX_IMAGES = 8;
std::optional<VideoCore::Surface::PixelFormatNumeric>
NumericFromComponentType(Shader::SamplerComponentType component_type) {
using VideoCore::Surface::PixelFormatNumeric;
switch (component_type) {
case Shader::SamplerComponentType::Float:
return PixelFormatNumeric::Float;
case Shader::SamplerComponentType::Sint:
return PixelFormatNumeric::Sint;
case Shader::SamplerComponentType::Uint:
return PixelFormatNumeric::Uint;
default:
return std::nullopt;
}
}
VideoCore::Surface::PixelFormat ResolveTexelBufferFormat(
VideoCore::Surface::PixelFormat format, Shader::SamplerComponentType component_type) {
const auto desired_numeric = NumericFromComponentType(component_type);
if (!desired_numeric) {
return format;
}
const auto current_numeric = VideoCore::Surface::GetPixelFormatNumericType(format);
if (*desired_numeric == current_numeric) {
return format;
}
if (const auto variant =
VideoCore::Surface::FindPixelFormatVariant(format, *desired_numeric)) {
return *variant;
}
return format;
}
GLenum Stage(size_t stage_index) {
switch (stage_index) {
case 0:
@@ -397,8 +431,12 @@ bool GraphicsPipeline::ConfigureImpl(bool is_indexed) {
is_written = desc.is_written;
}
ImageView& image_view{texture_cache.GetImageView(texture_buffer_it->id)};
auto buffer_format = image_view.format;
if constexpr (!is_image) {
buffer_format = ResolveTexelBufferFormat(buffer_format, desc.component_type);
}
buffer_cache.BindGraphicsTextureBuffer(stage, index, image_view.GpuAddr(),
image_view.BufferSize(), image_view.format,
image_view.BufferSize(), buffer_format,
is_written, is_image);
++index;
++texture_buffer_it;
@@ -483,7 +521,8 @@ bool GraphicsPipeline::ConfigureImpl(bool is_indexed) {
for (const auto& desc : info.texture_descriptors) {
for (u32 index = 0; index < desc.count; ++index) {
ImageView& image_view{texture_cache.GetImageView((views_it++)->id)};
textures[texture_binding] = image_view.Handle(desc.type);
textures[texture_binding] =
image_view.SampledView(desc.type, desc.component_type);
if (texture_cache.IsRescaling(image_view)) {
texture_scaling_mask |= 1u << stage_texture_binding;
}
@@ -220,6 +220,7 @@ ShaderCache::ShaderCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
.support_gl_sparse_textures = device.HasSparseTexture2(),
.support_gl_derivative_control = device.HasDerivativeControl(),
.support_geometry_streams = true,
.warp_stage_support_mask = 0xFFFFFFFFu,
.warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyLargerThanGuest(),
@@ -692,6 +692,15 @@ bool TextureCacheRuntime::HasNativeASTC() const noexcept {
return device.HasASTC();
}
bool TextureCacheRuntime::SupportsLinearFilter(VideoCore::Surface::PixelFormat format) const noexcept {
using VideoCore::Surface::GetFormatType;
using VideoCore::Surface::IsPixelFormatInteger;
if (IsPixelFormatInteger(format)) {
return false;
}
return GetFormatType(format) == VideoCore::Surface::SurfaceType::ColorTexture;
}
Image::Image(TextureCacheRuntime& runtime_, const VideoCommon::ImageInfo& info_, GPUVAddr gpu_addr_,
VAddr cpu_addr_)
: VideoCommon::ImageBase(info_, gpu_addr_, cpu_addr_), runtime{&runtime_} {
@@ -1229,6 +1238,13 @@ GLuint ImageView::StorageView(Shader::TextureType texture_type, Shader::ImageFor
return view;
}
GLuint ImageView::SampledView(Shader::TextureType view_type,
Shader::SamplerComponentType /*component_type*/) {
// OpenGL swizzles already configure depth/stencil selection per TIC entry,
// so fall back to the default view handle.
return Handle(view_type);
}
void ImageView::SetupView(Shader::TextureType view_type) {
views[static_cast<size_t>(view_type)] = MakeView(view_type, internal_format);
}
@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -13,6 +16,7 @@
#include "video_core/renderer_opengl/gl_resource_manager.h"
#include "video_core/renderer_opengl/gl_staging_buffer_pool.h"
#include "video_core/renderer_opengl/util_shaders.h"
#include "video_core/surface.h"
#include "video_core/texture_cache/image_view_base.h"
#include "video_core/texture_cache/texture_cache_base.h"
@@ -129,6 +133,8 @@ public:
return false;
}
bool SupportsLinearFilter(VideoCore::Surface::PixelFormat format) const noexcept;
bool HasBrokenTextureViewFormats() const noexcept {
return has_broken_texture_view_formats;
}
@@ -137,6 +143,8 @@ public:
void TickFrame() {}
void WaitForGpuTick(u64) {}
StateTracker& GetStateTracker() {
return state_tracker;
}
@@ -264,6 +272,9 @@ public:
[[nodiscard]] GLuint StorageView(Shader::TextureType texture_type,
Shader::ImageFormat image_format);
[[nodiscard]] GLuint SampledView(Shader::TextureType view_type,
Shader::SamplerComponentType component_type);
[[nodiscard]] GLuint Handle(Shader::TextureType handle_type) const noexcept {
return views[static_cast<size_t>(handle_type)];
}
+108 -114
View File
@@ -20,122 +20,116 @@ struct FormatTuple {
GLenum format = GL_NONE;
GLenum type = GL_NONE;
};
#define SURFACE_FORMAT_LIST \
SURFACE_FORMAT_ELEM(GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, A8B8G8R8_UNORM) \
SURFACE_FORMAT_ELEM(GL_RGBA8_SNORM, GL_RGBA, GL_BYTE, A8B8G8R8_SNORM) \
SURFACE_FORMAT_ELEM(GL_RGBA8I, GL_RGBA_INTEGER, GL_BYTE, A8B8G8R8_SINT) \
SURFACE_FORMAT_ELEM(GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, A8B8G8R8_UINT) \
SURFACE_FORMAT_ELEM(GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, R5G6B5_UNORM) \
SURFACE_FORMAT_ELEM(GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV, B5G6R5_UNORM) \
SURFACE_FORMAT_ELEM(GL_RGB5_A1, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, A1R5G5B5_UNORM) \
SURFACE_FORMAT_ELEM(GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, A2B10G10R10_UNORM) \
SURFACE_FORMAT_ELEM(GL_RGB10_A2UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, A2B10G10R10_UINT) \
SURFACE_FORMAT_ELEM(GL_RGB10_A2, GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, A2R10G10B10_UNORM) \
SURFACE_FORMAT_ELEM(GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, A1B5G5R5_UNORM) \
SURFACE_FORMAT_ELEM(GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, A5B5G5R1_UNORM) \
SURFACE_FORMAT_ELEM(GL_R8, GL_RED, GL_UNSIGNED_BYTE, R8_UNORM) \
SURFACE_FORMAT_ELEM(GL_R8_SNORM, GL_RED, GL_BYTE, R8_SNORM) \
SURFACE_FORMAT_ELEM(GL_R8I, GL_RED_INTEGER, GL_BYTE, R8_SINT) \
SURFACE_FORMAT_ELEM(GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE, R8_UINT) \
SURFACE_FORMAT_ELEM(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT, R16G16B16A16_FLOAT) \
SURFACE_FORMAT_ELEM(GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT, R16G16B16A16_UNORM) \
SURFACE_FORMAT_ELEM(GL_RGBA16_SNORM, GL_RGBA, GL_SHORT, R16G16B16A16_SNORM) \
SURFACE_FORMAT_ELEM(GL_RGBA16I, GL_RGBA_INTEGER, GL_SHORT, R16G16B16A16_SINT) \
SURFACE_FORMAT_ELEM(GL_RGBA16UI, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, R16G16B16A16_UINT) \
SURFACE_FORMAT_ELEM(GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, B10G11R11_FLOAT) \
SURFACE_FORMAT_ELEM(GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT, R32G32B32A32_UINT) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_NONE, GL_NONE, BC1_RGBA_UNORM) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_NONE, GL_NONE, BC2_UNORM) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_NONE, GL_NONE, BC3_UNORM) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_RED_RGTC1, GL_NONE, GL_NONE, BC4_UNORM) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_SIGNED_RED_RGTC1, GL_NONE, GL_NONE, BC4_SNORM) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_RG_RGTC2, GL_NONE, GL_NONE, BC5_UNORM) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_SIGNED_RG_RGTC2, GL_NONE, GL_NONE, BC5_SNORM) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_RGBA_BPTC_UNORM, GL_NONE, GL_NONE, BC7_UNORM) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, GL_NONE, GL_NONE, BC6H_UFLOAT) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT, GL_NONE, GL_NONE, BC6H_SFLOAT) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_RGBA_ASTC_4x4_KHR, GL_NONE, GL_NONE, ASTC_2D_4X4_UNORM) \
SURFACE_FORMAT_ELEM(GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, B8G8R8A8_UNORM) \
SURFACE_FORMAT_ELEM(GL_RGBA32F, GL_RGBA, GL_FLOAT, R32G32B32A32_FLOAT) \
SURFACE_FORMAT_ELEM(GL_RGBA32I, GL_RGBA_INTEGER, GL_INT, R32G32B32A32_SINT) \
SURFACE_FORMAT_ELEM(GL_RG32F, GL_RG, GL_FLOAT, R32G32_FLOAT) \
SURFACE_FORMAT_ELEM(GL_RG32I, GL_RG_INTEGER, GL_INT, R32G32_SINT) \
SURFACE_FORMAT_ELEM(GL_R32F, GL_RED, GL_FLOAT, R32_FLOAT) \
SURFACE_FORMAT_ELEM(GL_R16F, GL_RED, GL_HALF_FLOAT, R16_FLOAT) \
SURFACE_FORMAT_ELEM(GL_R16, GL_RED, GL_UNSIGNED_SHORT, R16_UNORM) \
SURFACE_FORMAT_ELEM(GL_R16_SNORM, GL_RED, GL_SHORT, R16_SNORM) \
SURFACE_FORMAT_ELEM(GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT, R16_UINT) \
SURFACE_FORMAT_ELEM(GL_R16I, GL_RED_INTEGER, GL_SHORT, R16_SINT) \
SURFACE_FORMAT_ELEM(GL_RG16, GL_RG, GL_UNSIGNED_SHORT, R16G16_UNORM) \
SURFACE_FORMAT_ELEM(GL_RG16F, GL_RG, GL_HALF_FLOAT, R16G16_FLOAT) \
SURFACE_FORMAT_ELEM(GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT, R16G16_UINT) \
SURFACE_FORMAT_ELEM(GL_RG16I, GL_RG_INTEGER, GL_SHORT, R16G16_SINT) \
SURFACE_FORMAT_ELEM(GL_RG16_SNORM, GL_RG, GL_SHORT, R16G16_SNORM) \
SURFACE_FORMAT_ELEM(GL_RGB32F, GL_RGB, GL_FLOAT, R32G32B32_FLOAT) \
SURFACE_FORMAT_ELEM(GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, A8B8G8R8_SRGB) \
SURFACE_FORMAT_ELEM(GL_RG8, GL_RG, GL_UNSIGNED_BYTE, R8G8_UNORM) \
SURFACE_FORMAT_ELEM(GL_RG8_SNORM, GL_RG, GL_BYTE, R8G8_SNORM) \
SURFACE_FORMAT_ELEM(GL_RG8I, GL_RG_INTEGER, GL_BYTE, R8G8_SINT) \
SURFACE_FORMAT_ELEM(GL_RG8UI, GL_RG_INTEGER, GL_UNSIGNED_BYTE, R8G8_UINT) \
SURFACE_FORMAT_ELEM(GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT, R32G32_UINT) \
SURFACE_FORMAT_ELEM(GL_RGB16F, GL_RGBA, GL_HALF_FLOAT, R16G16B16X16_FLOAT) \
SURFACE_FORMAT_ELEM(GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT, R32_UINT) \
SURFACE_FORMAT_ELEM(GL_R32I, GL_RED_INTEGER, GL_INT, R32_SINT) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_RGBA_ASTC_8x8_KHR, GL_NONE, GL_NONE, ASTC_2D_8X8_UNORM) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_RGBA_ASTC_8x5_KHR, GL_NONE, GL_NONE, ASTC_2D_8X5_UNORM) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_RGBA_ASTC_5x4_KHR, GL_NONE, GL_NONE, ASTC_2D_5X4_UNORM) \
SURFACE_FORMAT_ELEM(GL_SRGB8_ALPHA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, B8G8R8A8_SRGB) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, GL_NONE, GL_NONE, BC1_RGBA_SRGB) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, GL_NONE, GL_NONE, BC2_SRGB) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, GL_NONE, GL_NONE, BC3_SRGB) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM, GL_NONE, GL_NONE, BC7_SRGB) \
SURFACE_FORMAT_ELEM(GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4_REV, A4B4G4R4_UNORM) \
SURFACE_FORMAT_ELEM(GL_R8, GL_RED, GL_UNSIGNED_BYTE, G4R4_UNORM) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, GL_NONE, GL_NONE, ASTC_2D_4X4_SRGB) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, GL_NONE, GL_NONE, ASTC_2D_8X8_SRGB) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, GL_NONE, GL_NONE, ASTC_2D_8X5_SRGB) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, GL_NONE, GL_NONE, ASTC_2D_5X4_SRGB) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_RGBA_ASTC_5x5_KHR, GL_NONE, GL_NONE, ASTC_2D_5X5_UNORM) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, GL_NONE, GL_NONE, ASTC_2D_5X5_SRGB) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_RGBA_ASTC_10x8_KHR, GL_NONE, GL_NONE, ASTC_2D_10X8_UNORM) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, GL_NONE, GL_NONE, ASTC_2D_10X8_SRGB) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_RGBA_ASTC_6x6_KHR, GL_NONE, GL_NONE, ASTC_2D_6X6_UNORM) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, GL_NONE, GL_NONE, ASTC_2D_6X6_SRGB) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_RGBA_ASTC_10x6_KHR, GL_NONE, GL_NONE, ASTC_2D_10X6_UNORM) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, GL_NONE, GL_NONE, ASTC_2D_10X6_SRGB) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_RGBA_ASTC_10x5_KHR, GL_NONE, GL_NONE, ASTC_2D_10X5_UNORM) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, GL_NONE, GL_NONE, ASTC_2D_10X5_SRGB) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_RGBA_ASTC_10x10_KHR, GL_NONE, GL_NONE, ASTC_2D_10X10_UNORM) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, GL_NONE, GL_NONE, ASTC_2D_10X10_SRGB) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_RGBA_ASTC_12x10_KHR, GL_NONE, GL_NONE, ASTC_2D_12X10_UNORM) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, GL_NONE, GL_NONE, ASTC_2D_12X10_SRGB) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_RGBA_ASTC_12x12_KHR, GL_NONE, GL_NONE, ASTC_2D_12X12_UNORM) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, GL_NONE, GL_NONE, ASTC_2D_12X12_SRGB) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_RGBA_ASTC_8x6_KHR, GL_NONE, GL_NONE, ASTC_2D_8X6_UNORM) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, GL_NONE, GL_NONE, ASTC_2D_8X6_SRGB) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_RGBA_ASTC_6x5_KHR, GL_NONE, GL_NONE, ASTC_2D_6X5_UNORM) \
SURFACE_FORMAT_ELEM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, GL_NONE, GL_NONE, ASTC_2D_6X5_SRGB) \
SURFACE_FORMAT_ELEM(GL_RGB9_E5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, E5B9G9R9_FLOAT) \
SURFACE_FORMAT_ELEM(GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, D32_FLOAT) \
SURFACE_FORMAT_ELEM(GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, D16_UNORM) \
SURFACE_FORMAT_ELEM(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT_24_8, X8_D24_UNORM) \
SURFACE_FORMAT_ELEM(GL_STENCIL_INDEX8, GL_STENCIL, GL_UNSIGNED_BYTE, S8_UINT) \
SURFACE_FORMAT_ELEM(GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, D24_UNORM_S8_UINT) \
SURFACE_FORMAT_ELEM(GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, S8_UINT_D24_UNORM) \
SURFACE_FORMAT_ELEM(GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, D32_FLOAT_S8_UINT)
constexpr std::array<FormatTuple, VideoCore::Surface::MaxPixelFormat> FORMAT_TABLE = {{
#define SURFACE_FORMAT_ELEM(a1, a2, a3, name) {a1, a2, a3},
SURFACE_FORMAT_LIST
#undef SURFACE_FORMAT_ELEM
{GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV}, // A8B8G8R8_UNORM
{GL_RGBA8_SNORM, GL_RGBA, GL_BYTE}, // A8B8G8R8_SNORM
{GL_RGBA8I, GL_RGBA_INTEGER, GL_BYTE}, // A8B8G8R8_SINT
{GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE}, // A8B8G8R8_UINT
{GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5}, // R5G6B5_UNORM
{GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV}, // B5G6R5_UNORM
{GL_RGB5_A1, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV}, // A1R5G5B5_UNORM
{GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV}, // A2B10G10R10_UNORM
{GL_RGB10_A2UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV}, // A2B10G10R10_UINT
{GL_RGB10_A2, GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV}, // A2R10G10B10_UNORM
{GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV}, // A1B5G5R5_UNORM
{GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1}, // A5B5G5R1_UNORM
{GL_R8, GL_RED, GL_UNSIGNED_BYTE}, // R8_UNORM
{GL_R8_SNORM, GL_RED, GL_BYTE}, // R8_SNORM
{GL_R8I, GL_RED_INTEGER, GL_BYTE}, // R8_SINT
{GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE}, // R8_UINT
{GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT}, // R16G16B16A16_FLOAT
{GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT}, // R16G16B16A16_UNORM
{GL_RGBA16_SNORM, GL_RGBA, GL_SHORT}, // R16G16B16A16_SNORM
{GL_RGBA16I, GL_RGBA_INTEGER, GL_SHORT}, // R16G16B16A16_SINT
{GL_RGBA16UI, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT}, // R16G16B16A16_UINT
{GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV}, // B10G11R11_FLOAT
{GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT}, // R32G32B32A32_UINT
{GL_COMPRESSED_RGBA_S3TC_DXT1_EXT}, // BC1_RGBA_UNORM
{GL_COMPRESSED_RGBA_S3TC_DXT3_EXT}, // BC2_UNORM
{GL_COMPRESSED_RGBA_S3TC_DXT5_EXT}, // BC3_UNORM
{GL_COMPRESSED_RED_RGTC1}, // BC4_UNORM
{GL_COMPRESSED_SIGNED_RED_RGTC1}, // BC4_SNORM
{GL_COMPRESSED_RG_RGTC2}, // BC5_UNORM
{GL_COMPRESSED_SIGNED_RG_RGTC2}, // BC5_SNORM
{GL_COMPRESSED_RGBA_BPTC_UNORM}, // BC7_UNORM
{GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT}, // BC6H_UFLOAT
{GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT}, // BC6H_SFLOAT
{GL_COMPRESSED_RGBA_ASTC_4x4_KHR}, // ASTC_2D_4X4_UNORM
{GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV}, // B8G8R8A8_UNORM
{GL_RGBA32F, GL_RGBA, GL_FLOAT}, // R32G32B32A32_FLOAT
{GL_RGBA32I, GL_RGBA_INTEGER, GL_INT}, // R32G32B32A32_SINT
{GL_RG32F, GL_RG, GL_FLOAT}, // R32G32_FLOAT
{GL_RG32I, GL_RG_INTEGER, GL_INT}, // R32G32_SINT
{GL_R32F, GL_RED, GL_FLOAT}, // R32_FLOAT
{GL_R16F, GL_RED, GL_HALF_FLOAT}, // R16_FLOAT
{GL_R16, GL_RED, GL_UNSIGNED_SHORT}, // R16_UNORM
{GL_R16_SNORM, GL_RED, GL_SHORT}, // R16_SNORM
{GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT}, // R16_UINT
{GL_R16I, GL_RED_INTEGER, GL_SHORT}, // R16_SINT
{GL_RG16, GL_RG, GL_UNSIGNED_SHORT}, // R16G16_UNORM
{GL_RG16F, GL_RG, GL_HALF_FLOAT}, // R16G16_FLOAT
{GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT}, // R16G16_UINT
{GL_RG16I, GL_RG_INTEGER, GL_SHORT}, // R16G16_SINT
{GL_RG16_SNORM, GL_RG, GL_SHORT}, // R16G16_SNORM
{GL_RGB32F, GL_RGB, GL_FLOAT}, // R32G32B32_FLOAT
{GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV}, // A8B8G8R8_SRGB
{GL_RG8, GL_RG, GL_UNSIGNED_BYTE}, // R8G8_UNORM
{GL_RG8_SNORM, GL_RG, GL_BYTE}, // R8G8_SNORM
{GL_RG8I, GL_RG_INTEGER, GL_BYTE}, // R8G8_SINT
{GL_RG8UI, GL_RG_INTEGER, GL_UNSIGNED_BYTE}, // R8G8_UINT
{GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT}, // R32G32_UINT
{GL_RGB16F, GL_RGBA, GL_HALF_FLOAT}, // R16G16B16X16_FLOAT
{GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT}, // R32_UINT
{GL_R32I, GL_RED_INTEGER, GL_INT}, // R32_SINT
{GL_COMPRESSED_RGBA_ASTC_8x8_KHR}, // ASTC_2D_8X8_UNORM
{GL_COMPRESSED_RGBA_ASTC_8x5_KHR}, // ASTC_2D_8X5_UNORM
{GL_COMPRESSED_RGBA_ASTC_5x4_KHR}, // ASTC_2D_5X4_UNORM
{GL_SRGB8_ALPHA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV}, // B8G8R8A8_SRGB
{GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT}, // BC1_RGBA_SRGB
{GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT}, // BC2_SRGB
{GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT}, // BC3_SRGB
{GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM}, // BC7_SRGB
{GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4_REV}, // A4B4G4R4_UNORM
{GL_R8, GL_RED, GL_UNSIGNED_BYTE}, // G4R4_UNORM
{GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR}, // ASTC_2D_4X4_SRGB
{GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR}, // ASTC_2D_8X8_SRGB
{GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR}, // ASTC_2D_8X5_SRGB
{GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR}, // ASTC_2D_5X4_SRGB
{GL_COMPRESSED_RGBA_ASTC_5x5_KHR}, // ASTC_2D_5X5_UNORM
{GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR}, // ASTC_2D_5X5_SRGB
{GL_COMPRESSED_RGBA_ASTC_10x8_KHR}, // ASTC_2D_10X8_UNORM
{GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR}, // ASTC_2D_10X8_SRGB
{GL_COMPRESSED_RGBA_ASTC_6x6_KHR}, // ASTC_2D_6X6_UNORM
{GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR}, // ASTC_2D_6X6_SRGB
{GL_COMPRESSED_RGBA_ASTC_10x6_KHR}, // ASTC_2D_10X6_UNORM
{GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR}, // ASTC_2D_10X6_SRGB
{GL_COMPRESSED_RGBA_ASTC_10x5_KHR}, // ASTC_2D_10X5_UNORM
{GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR}, // ASTC_2D_10X5_SRGB
{GL_COMPRESSED_RGBA_ASTC_10x10_KHR}, // ASTC_2D_10X10_UNORM
{GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR}, // ASTC_2D_10X10_SRGB
{GL_COMPRESSED_RGBA_ASTC_12x10_KHR}, // ASTC_2D_12X10_UNORM
{GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR}, // ASTC_2D_12X10_SRGB
{GL_COMPRESSED_RGBA_ASTC_12x12_KHR}, // ASTC_2D_12X12_UNORM
{GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR}, // ASTC_2D_12X12_SRGB
{GL_COMPRESSED_RGBA_ASTC_8x6_KHR}, // ASTC_2D_8X6_UNORM
{GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR}, // ASTC_2D_8X6_SRGB
{GL_COMPRESSED_RGBA_ASTC_6x5_KHR}, // ASTC_2D_6X5_UNORM
{GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR}, // ASTC_2D_6X5_SRGB
{GL_RGB9_E5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV}, // E5B9G9R9_FLOAT
{GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT}, // D32_FLOAT
{GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}, // D16_UNORM
{GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT_24_8}, // X8_D24_UNORM
{GL_STENCIL_INDEX8, GL_STENCIL, GL_UNSIGNED_BYTE}, // S8_UINT
{GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8}, // D24_UNORM_S8_UINT
{GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8}, // S8_UINT_D24_UNORM
{GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL,
GL_FLOAT_32_UNSIGNED_INT_24_8_REV}, // D32_FLOAT_S8_UINT
}};
constexpr FormatTuple GetFormatTuple(VideoCore::Surface::PixelFormat pixel_format) noexcept {
switch (pixel_format) {
#define SURFACE_FORMAT_ELEM(a1, a2, a3, name) case VideoCore::Surface::PixelFormat::name: return {a1, a2, a3};
SURFACE_FORMAT_LIST
#undef SURFACE_FORMAT_ELEM
#undef SURFACE_FORMAT_LIST
default: UNREACHABLE();
}
inline const FormatTuple& GetFormatTuple(VideoCore::Surface::PixelFormat pixel_format) {
ASSERT(static_cast<size_t>(pixel_format) < FORMAT_TABLE.size());
return FORMAT_TABLE[static_cast<size_t>(pixel_format)];
}
inline GLenum VertexFormat(Maxwell::VertexAttribute attrib) {
+19 -3
View File
@@ -525,18 +525,24 @@ BlitImageHelper::BlitImageHelper(const Device& device_, Scheduler& scheduler_,
nullptr, PUSH_CONSTANT_RANGE<VK_SHADER_STAGE_FRAGMENT_BIT, sizeof(float) * 4>))),
full_screen_vert(BuildShader(device, FULL_SCREEN_TRIANGLE_VERT_SPV)),
blit_color_to_color_frag(BuildShader(device, BLIT_COLOR_FLOAT_FRAG_SPV)),
blit_depth_stencil_frag(BuildShader(device, VULKAN_BLIT_DEPTH_STENCIL_FRAG_SPV)),
blit_depth_stencil_frag(device.IsExtShaderStencilExportSupported()
? BuildShader(device, VULKAN_BLIT_DEPTH_STENCIL_FRAG_SPV)
: vk::ShaderModule{}),
clear_color_vert(BuildShader(device, VULKAN_COLOR_CLEAR_VERT_SPV)),
clear_color_frag(BuildShader(device, VULKAN_COLOR_CLEAR_FRAG_SPV)),
clear_stencil_frag(BuildShader(device, VULKAN_DEPTHSTENCIL_CLEAR_FRAG_SPV)),
convert_depth_to_float_frag(BuildShader(device, CONVERT_DEPTH_TO_FLOAT_FRAG_SPV)),
convert_float_to_depth_frag(BuildShader(device, CONVERT_FLOAT_TO_DEPTH_FRAG_SPV)),
convert_abgr8_to_d24s8_frag(BuildShader(device, CONVERT_ABGR8_TO_D24S8_FRAG_SPV)),
convert_abgr8_to_d24s8_frag(device.IsExtShaderStencilExportSupported()
? BuildShader(device, CONVERT_ABGR8_TO_D24S8_FRAG_SPV)
: vk::ShaderModule{}),
convert_abgr8_to_d32f_frag(BuildShader(device, CONVERT_ABGR8_TO_D32F_FRAG_SPV)),
convert_d32f_to_abgr8_frag(BuildShader(device, CONVERT_D32F_TO_ABGR8_FRAG_SPV)),
convert_d24s8_to_abgr8_frag(BuildShader(device, CONVERT_D24S8_TO_ABGR8_FRAG_SPV)),
convert_s8d24_to_abgr8_frag(BuildShader(device, CONVERT_S8D24_TO_ABGR8_FRAG_SPV)),
convert_abgr8_srgb_to_d24s8_frag(BuildShader(device, CONVERT_ABGR8_SRGB_TO_D24S8_FRAG_SPV)),
convert_abgr8_srgb_to_d24s8_frag(device.IsExtShaderStencilExportSupported()
? BuildShader(device, CONVERT_ABGR8_SRGB_TO_D24S8_FRAG_SPV)
: vk::ShaderModule{}),
convert_rgba_to_bgra_frag(BuildShader(device, CONVERT_RGBA8_TO_BGRA8_FRAG_SPV)),
convert_yuv420_to_rgb_comp(BuildShader(device, CONVERT_YUV420_TO_RGB_COMP_SPV)),
convert_rgb_to_yuv420_comp(BuildShader(device, CONVERT_RGB_TO_YUV420_COMP_SPV)),
@@ -667,6 +673,11 @@ void BlitImageHelper::ConvertR16ToD16(const Framebuffer* dst_framebuffer,
void BlitImageHelper::ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer,
const ImageView& src_image_view) {
if (!device.IsExtShaderStencilExportSupported()) {
// Shader requires VK_EXT_shader_stencil_export which is not available
LOG_WARNING(Render_Vulkan, "ConvertABGR8ToD24S8 requires shader_stencil_export, skipping");
return;
}
ConvertPipelineDepthTargetEx(convert_abgr8_to_d24s8_pipeline, dst_framebuffer->RenderPass(),
convert_abgr8_to_d24s8_frag);
Convert(*convert_abgr8_to_d24s8_pipeline, dst_framebuffer, src_image_view);
@@ -702,6 +713,11 @@ void BlitImageHelper::ConvertS8D24ToABGR8(const Framebuffer* dst_framebuffer,
void BlitImageHelper::ConvertABGR8SRGBToD24S8(const Framebuffer* dst_framebuffer,
const ImageView& src_image_view) {
if (!device.IsExtShaderStencilExportSupported()) {
// Shader requires VK_EXT_shader_stencil_export which is not available
LOG_WARNING(Render_Vulkan, "ConvertABGR8SRGBToD24S8 requires shader_stencil_export, skipping");
return;
}
ConvertPipelineDepthTargetEx(convert_abgr8_srgb_to_d24s8_pipeline,
dst_framebuffer->RenderPass(),
convert_abgr8_srgb_to_d24s8_frag);
@@ -59,7 +59,7 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, DynamicFe
raw1 = 0;
extended_dynamic_state.Assign(features.has_extended_dynamic_state ? 1 : 0);
extended_dynamic_state_2.Assign(features.has_extended_dynamic_state_2 ? 1 : 0);
extended_dynamic_state_2_extra.Assign(features.has_extended_dynamic_state_2_extra ? 1 : 0);
extended_dynamic_state_2_logic_op.Assign(features.has_extended_dynamic_state_2_logic_op ? 1 : 0);
extended_dynamic_state_3_blend.Assign(features.has_extended_dynamic_state_3_blend ? 1 : 0);
extended_dynamic_state_3_enables.Assign(features.has_extended_dynamic_state_3_enables ? 1 : 0);
dynamic_vertex_input.Assign(features.has_dynamic_vertex_input ? 1 : 0);
@@ -157,7 +157,7 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, DynamicFe
return static_cast<u16>(array.stride.Value());
});
}
if (!extended_dynamic_state_2_extra) {
if (!extended_dynamic_state_2_logic_op) {
dynamic_state.Refresh2(regs, topology_, extended_dynamic_state_2);
}
if (!extended_dynamic_state_3_blend) {
@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -20,9 +23,11 @@ using Maxwell = Tegra::Engines::Maxwell3D::Regs;
struct DynamicFeatures {
bool has_extended_dynamic_state;
bool has_extended_dynamic_state_2;
bool has_extended_dynamic_state_2_extra;
bool has_extended_dynamic_state_2_logic_op;
bool has_extended_dynamic_state_2_patch_control_points;
bool has_extended_dynamic_state_3_blend;
bool has_extended_dynamic_state_3_enables;
bool has_dual_source_blend;
bool has_dynamic_vertex_input;
};
@@ -186,7 +191,7 @@ struct FixedPipelineState {
u32 raw1;
BitField<0, 1, u32> extended_dynamic_state;
BitField<1, 1, u32> extended_dynamic_state_2;
BitField<2, 1, u32> extended_dynamic_state_2_extra;
BitField<2, 1, u32> extended_dynamic_state_2_logic_op;
BitField<3, 1, u32> extended_dynamic_state_3_blend;
BitField<4, 1, u32> extended_dynamic_state_3_enables;
BitField<5, 1, u32> dynamic_vertex_input;
+135 -125
View File
@@ -105,141 +105,148 @@ VkCompareOp DepthCompareFunction(Tegra::Texture::DepthCompareFunc depth_compare_
}
} // namespace Sampler
namespace {
constexpr u32 Attachable = 1 << 0;
constexpr u32 Storage = 1 << 1;
struct FormatTuple {
VkFormat format{}; ///< Vulkan format
s32 usage = 0; ///< Describes image format usage
VkFormat format; ///< Vulkan format
int usage = 0; ///< Describes image format usage
} constexpr tex_format_tuples[] = {
{VK_FORMAT_A8B8G8R8_UNORM_PACK32, Attachable | Storage}, // A8B8G8R8_UNORM
{VK_FORMAT_A8B8G8R8_SNORM_PACK32, Attachable | Storage}, // A8B8G8R8_SNORM
{VK_FORMAT_A8B8G8R8_SINT_PACK32, Attachable | Storage}, // A8B8G8R8_SINT
{VK_FORMAT_A8B8G8R8_UINT_PACK32, Attachable | Storage}, // A8B8G8R8_UINT
{VK_FORMAT_R5G6B5_UNORM_PACK16, Attachable}, // R5G6B5_UNORM
{VK_FORMAT_B5G6R5_UNORM_PACK16}, // B5G6R5_UNORM
{VK_FORMAT_A1R5G5B5_UNORM_PACK16, Attachable}, // A1R5G5B5_UNORM
{VK_FORMAT_A2B10G10R10_UNORM_PACK32, Attachable | Storage}, // A2B10G10R10_UNORM
{VK_FORMAT_A2B10G10R10_UINT_PACK32, Attachable | Storage}, // A2B10G10R10_UINT
{VK_FORMAT_A2R10G10B10_UNORM_PACK32, Attachable}, // A2R10G10B10_UNORM
{VK_FORMAT_A1R5G5B5_UNORM_PACK16, Attachable}, // A1B5G5R5_UNORM (flipped with swizzle)
{VK_FORMAT_R5G5B5A1_UNORM_PACK16}, // A5B5G5R1_UNORM (specially swizzled)
{VK_FORMAT_R8_UNORM, Attachable | Storage}, // R8_UNORM
{VK_FORMAT_R8_SNORM, Attachable | Storage}, // R8_SNORM
{VK_FORMAT_R8_SINT, Attachable | Storage}, // R8_SINT
{VK_FORMAT_R8_UINT, Attachable | Storage}, // R8_UINT
{VK_FORMAT_R16G16B16A16_SFLOAT, Attachable | Storage}, // R16G16B16A16_FLOAT
{VK_FORMAT_R16G16B16A16_UNORM, Attachable | Storage}, // R16G16B16A16_UNORM
{VK_FORMAT_R16G16B16A16_SNORM, Attachable | Storage}, // R16G16B16A16_SNORM
{VK_FORMAT_R16G16B16A16_SINT, Attachable | Storage}, // R16G16B16A16_SINT
{VK_FORMAT_R16G16B16A16_UINT, Attachable | Storage}, // R16G16B16A16_UINT
{VK_FORMAT_B10G11R11_UFLOAT_PACK32, Attachable | Storage}, // B10G11R11_FLOAT
{VK_FORMAT_R32G32B32A32_UINT, Attachable | Storage}, // R32G32B32A32_UINT
{VK_FORMAT_BC1_RGBA_UNORM_BLOCK}, // BC1_RGBA_UNORM
{VK_FORMAT_BC2_UNORM_BLOCK}, // BC2_UNORM
{VK_FORMAT_BC3_UNORM_BLOCK}, // BC3_UNORM
{VK_FORMAT_BC4_UNORM_BLOCK}, // BC4_UNORM
{VK_FORMAT_BC4_SNORM_BLOCK}, // BC4_SNORM
{VK_FORMAT_BC5_UNORM_BLOCK}, // BC5_UNORM
{VK_FORMAT_BC5_SNORM_BLOCK}, // BC5_SNORM
{VK_FORMAT_BC7_UNORM_BLOCK}, // BC7_UNORM
{VK_FORMAT_BC6H_UFLOAT_BLOCK}, // BC6H_UFLOAT
{VK_FORMAT_BC6H_SFLOAT_BLOCK}, // BC6H_SFLOAT
{VK_FORMAT_ASTC_4x4_UNORM_BLOCK}, // ASTC_2D_4X4_UNORM
{VK_FORMAT_B8G8R8A8_UNORM, Attachable | Storage}, // B8G8R8A8_UNORM
{VK_FORMAT_R32G32B32A32_SFLOAT, Attachable | Storage}, // R32G32B32A32_FLOAT
{VK_FORMAT_R32G32B32A32_SINT, Attachable | Storage}, // R32G32B32A32_SINT
{VK_FORMAT_R32G32_SFLOAT, Attachable | Storage}, // R32G32_FLOAT
{VK_FORMAT_R32G32_SINT, Attachable | Storage}, // R32G32_SINT
{VK_FORMAT_R32_SFLOAT, Attachable | Storage}, // R32_FLOAT
{VK_FORMAT_R16_SFLOAT, Attachable | Storage}, // R16_FLOAT
{VK_FORMAT_R16_UNORM, Attachable | Storage}, // R16_UNORM
{VK_FORMAT_R16_SNORM, Attachable | Storage}, // R16_SNORM
{VK_FORMAT_R16_UINT, Attachable | Storage}, // R16_UINT
{VK_FORMAT_R16_SINT, Attachable | Storage}, // R16_SINT
{VK_FORMAT_R16G16_UNORM, Attachable | Storage}, // R16G16_UNORM
{VK_FORMAT_R16G16_SFLOAT, Attachable | Storage}, // R16G16_FLOAT
{VK_FORMAT_R16G16_UINT, Attachable | Storage}, // R16G16_UINT
{VK_FORMAT_R16G16_SINT, Attachable | Storage}, // R16G16_SINT
{VK_FORMAT_R16G16_SNORM, Attachable | Storage}, // R16G16_SNORM
{VK_FORMAT_R32G32B32_SFLOAT}, // R32G32B32_FLOAT
{VK_FORMAT_A8B8G8R8_SRGB_PACK32, Attachable | Storage}, // A8B8G8R8_SRGB
{VK_FORMAT_R8G8_UNORM, Attachable | Storage}, // R8G8_UNORM
{VK_FORMAT_R8G8_SNORM, Attachable | Storage}, // R8G8_SNORM
{VK_FORMAT_R8G8_SINT, Attachable | Storage}, // R8G8_SINT
{VK_FORMAT_R8G8_UINT, Attachable | Storage}, // R8G8_UINT
{VK_FORMAT_R32G32_UINT, Attachable | Storage}, // R32G32_UINT
{VK_FORMAT_R16G16B16A16_SFLOAT, Attachable | Storage}, // R16G16B16X16_FLOAT
{VK_FORMAT_R32_UINT, Attachable | Storage}, // R32_UINT
{VK_FORMAT_R32_SINT, Attachable | Storage}, // R32_SINT
{VK_FORMAT_ASTC_8x8_UNORM_BLOCK}, // ASTC_2D_8X8_UNORM
{VK_FORMAT_ASTC_8x5_UNORM_BLOCK}, // ASTC_2D_8X5_UNORM
{VK_FORMAT_ASTC_5x4_UNORM_BLOCK}, // ASTC_2D_5X4_UNORM
{VK_FORMAT_B8G8R8A8_SRGB, Attachable | Storage}, // B8G8R8A8_SRGB
{VK_FORMAT_BC1_RGBA_SRGB_BLOCK}, // BC1_RGBA_SRGB
{VK_FORMAT_BC2_SRGB_BLOCK}, // BC2_SRGB
{VK_FORMAT_BC3_SRGB_BLOCK}, // BC3_SRGB
{VK_FORMAT_BC7_SRGB_BLOCK}, // BC7_SRGB
{VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT}, // A4B4G4R4_UNORM
{VK_FORMAT_R4G4_UNORM_PACK8}, // G4R4_UNORM
{VK_FORMAT_ASTC_4x4_SRGB_BLOCK}, // ASTC_2D_4X4_SRGB
{VK_FORMAT_ASTC_8x8_SRGB_BLOCK}, // ASTC_2D_8X8_SRGB
{VK_FORMAT_ASTC_8x5_SRGB_BLOCK}, // ASTC_2D_8X5_SRGB
{VK_FORMAT_ASTC_5x4_SRGB_BLOCK}, // ASTC_2D_5X4_SRGB
{VK_FORMAT_ASTC_5x5_UNORM_BLOCK}, // ASTC_2D_5X5_UNORM
{VK_FORMAT_ASTC_5x5_SRGB_BLOCK}, // ASTC_2D_5X5_SRGB
{VK_FORMAT_ASTC_10x8_UNORM_BLOCK}, // ASTC_2D_10X8_UNORM
{VK_FORMAT_ASTC_10x8_SRGB_BLOCK}, // ASTC_2D_10X8_SRGB
{VK_FORMAT_ASTC_6x6_UNORM_BLOCK}, // ASTC_2D_6X6_UNORM
{VK_FORMAT_ASTC_6x6_SRGB_BLOCK}, // ASTC_2D_6X6_SRGB
{VK_FORMAT_ASTC_10x6_UNORM_BLOCK}, // ASTC_2D_10X6_UNORM
{VK_FORMAT_ASTC_10x6_SRGB_BLOCK}, // ASTC_2D_10X6_SRGB
{VK_FORMAT_ASTC_10x5_UNORM_BLOCK}, // ASTC_2D_10X5_UNORM
{VK_FORMAT_ASTC_10x5_SRGB_BLOCK}, // ASTC_2D_10X5_SRGB
{VK_FORMAT_ASTC_10x10_UNORM_BLOCK}, // ASTC_2D_10X10_UNORM
{VK_FORMAT_ASTC_10x10_SRGB_BLOCK}, // ASTC_2D_10X10_SRGB
{VK_FORMAT_ASTC_12x10_UNORM_BLOCK}, // ASTC_2D_12X10_UNORM
{VK_FORMAT_ASTC_12x10_SRGB_BLOCK}, // ASTC_2D_12X10_SRGB
{VK_FORMAT_ASTC_12x12_UNORM_BLOCK}, // ASTC_2D_12X12_UNORM
{VK_FORMAT_ASTC_12x12_SRGB_BLOCK}, // ASTC_2D_12X12_SRGB
{VK_FORMAT_ASTC_8x6_UNORM_BLOCK}, // ASTC_2D_8X6_UNORM
{VK_FORMAT_ASTC_8x6_SRGB_BLOCK}, // ASTC_2D_8X6_SRGB
{VK_FORMAT_ASTC_6x5_UNORM_BLOCK}, // ASTC_2D_6X5_UNORM
{VK_FORMAT_ASTC_6x5_SRGB_BLOCK}, // ASTC_2D_6X5_SRGB
{VK_FORMAT_E5B9G9R9_UFLOAT_PACK32}, // E5B9G9R9_FLOAT
// Depth formats
{VK_FORMAT_D32_SFLOAT, Attachable}, // D32_FLOAT
{VK_FORMAT_D16_UNORM, Attachable}, // D16_UNORM
{VK_FORMAT_X8_D24_UNORM_PACK32, Attachable}, // X8_D24_UNORM
// Stencil formats
{VK_FORMAT_S8_UINT, Attachable}, // S8_UINT
// DepthStencil formats
{VK_FORMAT_D24_UNORM_S8_UINT, Attachable}, // D24_UNORM_S8_UINT
{VK_FORMAT_D24_UNORM_S8_UINT, Attachable}, // S8_UINT_D24_UNORM (emulated)
{VK_FORMAT_D32_SFLOAT_S8_UINT, Attachable}, // D32_FLOAT_S8_UINT
};
static_assert(std::size(tex_format_tuples) == VideoCore::Surface::MaxPixelFormat);
constexpr bool IsZetaFormat(PixelFormat pixel_format) {
return pixel_format >= PixelFormat::MaxColorFormat && pixel_format < PixelFormat::MaxDepthStencilFormat;
return pixel_format >= PixelFormat::MaxColorFormat &&
pixel_format < PixelFormat::MaxDepthStencilFormat;
}
FormatInfo SurfaceFormat(const Device& device, FormatType format_type, bool with_srgb, PixelFormat pixel_format) {
u32 const usage_attachable = 1 << 0;
u32 const usage_storage = 1 << 1;
FormatTuple tuple;
switch (pixel_format) {
#define SURFACE_FORMAT_LIST \
SURFACE_FORMAT_ELEM(VK_FORMAT_A8B8G8R8_UNORM_PACK32, usage_attachable | usage_storage, A8B8G8R8_UNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_A8B8G8R8_SNORM_PACK32, usage_attachable | usage_storage, A8B8G8R8_SNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_A8B8G8R8_SINT_PACK32, usage_attachable | usage_storage, A8B8G8R8_SINT) \
SURFACE_FORMAT_ELEM(VK_FORMAT_A8B8G8R8_UINT_PACK32, usage_attachable | usage_storage, A8B8G8R8_UINT) \
SURFACE_FORMAT_ELEM(VK_FORMAT_R5G6B5_UNORM_PACK16, usage_attachable, R5G6B5_UNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_B5G6R5_UNORM_PACK16, 0, B5G6R5_UNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_A1R5G5B5_UNORM_PACK16, usage_attachable, A1R5G5B5_UNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_A2B10G10R10_UNORM_PACK32, usage_attachable | usage_storage, A2B10G10R10_UNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_A2B10G10R10_UINT_PACK32, usage_attachable | usage_storage, A2B10G10R10_UINT) \
SURFACE_FORMAT_ELEM(VK_FORMAT_A2R10G10B10_UNORM_PACK32, usage_attachable, A2R10G10B10_UNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_A1R5G5B5_UNORM_PACK16, usage_attachable, A1B5G5R5_UNORM) /*flipped with swizzle*/ \
SURFACE_FORMAT_ELEM(VK_FORMAT_R5G5B5A1_UNORM_PACK16, 0, A5B5G5R1_UNORM) /*specially swizzled*/ \
SURFACE_FORMAT_ELEM(VK_FORMAT_R8_UNORM, usage_attachable | usage_storage, R8_UNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_R8_SNORM, usage_attachable | usage_storage, R8_SNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_R8_SINT, usage_attachable | usage_storage, R8_SINT) \
SURFACE_FORMAT_ELEM(VK_FORMAT_R8_UINT, usage_attachable | usage_storage, R8_UINT) \
SURFACE_FORMAT_ELEM(VK_FORMAT_R16G16B16A16_SFLOAT, usage_attachable | usage_storage, R16G16B16A16_FLOAT) \
SURFACE_FORMAT_ELEM(VK_FORMAT_R16G16B16A16_UNORM, usage_attachable | usage_storage, R16G16B16A16_UNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_R16G16B16A16_SNORM, usage_attachable | usage_storage, R16G16B16A16_SNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_R16G16B16A16_SINT, usage_attachable | usage_storage, R16G16B16A16_SINT) \
SURFACE_FORMAT_ELEM(VK_FORMAT_R16G16B16A16_UINT, usage_attachable | usage_storage, R16G16B16A16_UINT) \
SURFACE_FORMAT_ELEM(VK_FORMAT_B10G11R11_UFLOAT_PACK32, usage_attachable | usage_storage, B10G11R11_FLOAT) \
SURFACE_FORMAT_ELEM(VK_FORMAT_R32G32B32A32_UINT, usage_attachable | usage_storage, R32G32B32A32_UINT) \
SURFACE_FORMAT_ELEM(VK_FORMAT_BC1_RGBA_UNORM_BLOCK, 0, BC1_RGBA_UNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_BC2_UNORM_BLOCK, 0, BC2_UNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_BC3_UNORM_BLOCK, 0, BC3_UNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_BC4_UNORM_BLOCK, 0, BC4_UNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_BC4_SNORM_BLOCK, 0, BC4_SNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_BC5_UNORM_BLOCK, 0, BC5_UNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_BC5_SNORM_BLOCK, 0, BC5_SNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_BC7_UNORM_BLOCK, 0, BC7_UNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_BC6H_UFLOAT_BLOCK, 0, BC6H_UFLOAT) \
SURFACE_FORMAT_ELEM(VK_FORMAT_BC6H_SFLOAT_BLOCK, 0, BC6H_SFLOAT) \
SURFACE_FORMAT_ELEM(VK_FORMAT_ASTC_4x4_UNORM_BLOCK, 0, ASTC_2D_4X4_UNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_B8G8R8A8_UNORM, usage_attachable | usage_storage, B8G8R8A8_UNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_R32G32B32A32_SFLOAT, usage_attachable | usage_storage, R32G32B32A32_FLOAT) \
SURFACE_FORMAT_ELEM(VK_FORMAT_R32G32B32A32_SINT, usage_attachable | usage_storage, R32G32B32A32_SINT) \
SURFACE_FORMAT_ELEM(VK_FORMAT_R32G32_SFLOAT, usage_attachable | usage_storage, R32G32_FLOAT) \
SURFACE_FORMAT_ELEM(VK_FORMAT_R32G32_SINT, usage_attachable | usage_storage, R32G32_SINT) \
SURFACE_FORMAT_ELEM(VK_FORMAT_R32_SFLOAT, usage_attachable | usage_storage, R32_FLOAT) \
SURFACE_FORMAT_ELEM(VK_FORMAT_R16_SFLOAT, usage_attachable | usage_storage, R16_FLOAT) \
SURFACE_FORMAT_ELEM(VK_FORMAT_R16_UNORM, usage_attachable | usage_storage, R16_UNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_R16_SNORM, usage_attachable | usage_storage, R16_SNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_R16_UINT, usage_attachable | usage_storage, R16_UINT) \
SURFACE_FORMAT_ELEM(VK_FORMAT_R16_SINT, usage_attachable | usage_storage, R16_SINT) \
SURFACE_FORMAT_ELEM(VK_FORMAT_R16G16_UNORM, usage_attachable | usage_storage, R16G16_UNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_R16G16_SFLOAT, usage_attachable | usage_storage, R16G16_FLOAT) \
SURFACE_FORMAT_ELEM(VK_FORMAT_R16G16_UINT, usage_attachable | usage_storage, R16G16_UINT) \
SURFACE_FORMAT_ELEM(VK_FORMAT_R16G16_SINT, usage_attachable | usage_storage, R16G16_SINT) \
SURFACE_FORMAT_ELEM(VK_FORMAT_R16G16_SNORM, usage_attachable | usage_storage, R16G16_SNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_R32G32B32_SFLOAT, 0, R32G32B32_FLOAT) \
SURFACE_FORMAT_ELEM(VK_FORMAT_A8B8G8R8_SRGB_PACK32, usage_attachable, A8B8G8R8_SRGB) \
SURFACE_FORMAT_ELEM(VK_FORMAT_R8G8_UNORM, usage_attachable | usage_storage, R8G8_UNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_R8G8_SNORM, usage_attachable | usage_storage, R8G8_SNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_R8G8_SINT, usage_attachable | usage_storage, R8G8_SINT) \
SURFACE_FORMAT_ELEM(VK_FORMAT_R8G8_UINT, usage_attachable | usage_storage, R8G8_UINT) \
SURFACE_FORMAT_ELEM(VK_FORMAT_R32G32_UINT, usage_attachable | usage_storage, R32G32_UINT) \
SURFACE_FORMAT_ELEM(VK_FORMAT_R16G16B16A16_SFLOAT, usage_attachable | usage_storage, R16G16B16X16_FLOAT) \
SURFACE_FORMAT_ELEM(VK_FORMAT_R32_UINT, usage_attachable | usage_storage, R32_UINT) \
SURFACE_FORMAT_ELEM(VK_FORMAT_R32_SINT, usage_attachable | usage_storage, R32_SINT) \
SURFACE_FORMAT_ELEM(VK_FORMAT_ASTC_8x8_UNORM_BLOCK, 0, ASTC_2D_8X8_UNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_ASTC_8x5_UNORM_BLOCK, 0, ASTC_2D_8X5_UNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_ASTC_5x4_UNORM_BLOCK, 0, ASTC_2D_5X4_UNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_B8G8R8A8_SRGB, usage_attachable, B8G8R8A8_SRGB) \
SURFACE_FORMAT_ELEM(VK_FORMAT_BC1_RGBA_SRGB_BLOCK, 0, BC1_RGBA_SRGB) \
SURFACE_FORMAT_ELEM(VK_FORMAT_BC2_SRGB_BLOCK, 0, BC2_SRGB) \
SURFACE_FORMAT_ELEM(VK_FORMAT_BC3_SRGB_BLOCK, 0, BC3_SRGB) \
SURFACE_FORMAT_ELEM(VK_FORMAT_BC7_SRGB_BLOCK, 0, BC7_SRGB) \
SURFACE_FORMAT_ELEM(VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT, 0, A4B4G4R4_UNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_R4G4_UNORM_PACK8, 0, G4R4_UNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_ASTC_4x4_SRGB_BLOCK, 0, ASTC_2D_4X4_SRGB) \
SURFACE_FORMAT_ELEM(VK_FORMAT_ASTC_8x8_SRGB_BLOCK, 0, ASTC_2D_8X8_SRGB) \
SURFACE_FORMAT_ELEM(VK_FORMAT_ASTC_8x5_SRGB_BLOCK, 0, ASTC_2D_8X5_SRGB) \
SURFACE_FORMAT_ELEM(VK_FORMAT_ASTC_5x4_SRGB_BLOCK, 0, ASTC_2D_5X4_SRGB) \
SURFACE_FORMAT_ELEM(VK_FORMAT_ASTC_5x5_UNORM_BLOCK, 0, ASTC_2D_5X5_UNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_ASTC_5x5_SRGB_BLOCK, 0, ASTC_2D_5X5_SRGB) \
SURFACE_FORMAT_ELEM(VK_FORMAT_ASTC_10x8_UNORM_BLOCK, 0, ASTC_2D_10X8_UNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_ASTC_10x8_SRGB_BLOCK, 0, ASTC_2D_10X8_SRGB) \
SURFACE_FORMAT_ELEM(VK_FORMAT_ASTC_6x6_UNORM_BLOCK, 0, ASTC_2D_6X6_UNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_ASTC_6x6_SRGB_BLOCK, 0, ASTC_2D_6X6_SRGB) \
SURFACE_FORMAT_ELEM(VK_FORMAT_ASTC_10x6_UNORM_BLOCK, 0, ASTC_2D_10X6_UNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_ASTC_10x6_SRGB_BLOCK, 0, ASTC_2D_10X6_SRGB) \
SURFACE_FORMAT_ELEM(VK_FORMAT_ASTC_10x5_UNORM_BLOCK, 0, ASTC_2D_10X5_UNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_ASTC_10x5_SRGB_BLOCK, 0, ASTC_2D_10X5_SRGB) \
SURFACE_FORMAT_ELEM(VK_FORMAT_ASTC_10x10_UNORM_BLOCK, 0, ASTC_2D_10X10_UNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_ASTC_10x10_SRGB_BLOCK, 0, ASTC_2D_10X10_SRGB) \
SURFACE_FORMAT_ELEM(VK_FORMAT_ASTC_12x10_UNORM_BLOCK, 0, ASTC_2D_12X10_UNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_ASTC_12x10_SRGB_BLOCK, 0, ASTC_2D_12X10_SRGB) \
SURFACE_FORMAT_ELEM(VK_FORMAT_ASTC_12x12_UNORM_BLOCK, 0, ASTC_2D_12X12_UNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_ASTC_12x12_SRGB_BLOCK, 0, ASTC_2D_12X12_SRGB) \
SURFACE_FORMAT_ELEM(VK_FORMAT_ASTC_8x6_UNORM_BLOCK, 0, ASTC_2D_8X6_UNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_ASTC_8x6_SRGB_BLOCK, 0, ASTC_2D_8X6_SRGB) \
SURFACE_FORMAT_ELEM(VK_FORMAT_ASTC_6x5_UNORM_BLOCK, 0, ASTC_2D_6X5_UNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_ASTC_6x5_SRGB_BLOCK, 0, ASTC_2D_6X5_SRGB) \
SURFACE_FORMAT_ELEM(VK_FORMAT_E5B9G9R9_UFLOAT_PACK32, 0, E5B9G9R9_FLOAT) \
/* Depth formats */ \
SURFACE_FORMAT_ELEM(VK_FORMAT_D32_SFLOAT, usage_attachable, D32_FLOAT) \
SURFACE_FORMAT_ELEM(VK_FORMAT_D16_UNORM, usage_attachable, D16_UNORM) \
SURFACE_FORMAT_ELEM(VK_FORMAT_X8_D24_UNORM_PACK32, usage_attachable, X8_D24_UNORM) \
/* Stencil formats */ \
SURFACE_FORMAT_ELEM(VK_FORMAT_S8_UINT, usage_attachable, S8_UINT) \
/* DepthStencil formats */ \
SURFACE_FORMAT_ELEM(VK_FORMAT_D24_UNORM_S8_UINT, usage_attachable, D24_UNORM_S8_UINT) \
SURFACE_FORMAT_ELEM(VK_FORMAT_D24_UNORM_S8_UINT, usage_attachable, S8_UINT_D24_UNORM) /* emulated */ \
SURFACE_FORMAT_ELEM(VK_FORMAT_D32_SFLOAT_S8_UINT, usage_attachable, D32_FLOAT_S8_UINT)
#define SURFACE_FORMAT_ELEM(res, usage, pixel) case PixelFormat::pixel: tuple = {res, usage}; break;
SURFACE_FORMAT_LIST
default: UNREACHABLE_MSG("unknown format {}", pixel_format);
#undef SURFACE_FORMAT_ELEM
#undef SURFACE_FORMAT_LIST
}
bool const is_srgb = with_srgb && VideoCore::Surface::IsPixelFormatSRGB(pixel_format);
} // Anonymous namespace
FormatInfo SurfaceFormat(const Device& device, FormatType format_type, bool with_srgb,
PixelFormat pixel_format) {
ASSERT(static_cast<size_t>(pixel_format) < std::size(tex_format_tuples));
FormatTuple tuple = tex_format_tuples[static_cast<size_t>(pixel_format)];
// Transcode on hardware that doesn't support ASTC natively
if (!device.IsOptimalAstcSupported() && VideoCore::Surface::IsPixelFormatASTC(pixel_format)) {
const bool is_srgb = with_srgb && VideoCore::Surface::IsPixelFormatSRGB(pixel_format);
switch (Settings::values.astc_recompression.GetValue()) {
case Settings::AstcRecompression::Uncompressed:
if (is_srgb) {
tuple.format = VK_FORMAT_A8B8G8R8_SRGB_PACK32;
} else {
tuple.format = VK_FORMAT_A8B8G8R8_UNORM_PACK32;
tuple.usage |= usage_storage;
tuple.usage |= Storage;
}
break;
case Settings::AstcRecompression::Bc1:
@@ -252,6 +259,7 @@ FormatInfo SurfaceFormat(const Device& device, FormatType format_type, bool with
}
// Transcode on hardware that doesn't support BCn natively
if (!device.IsOptimalBcnSupported() && VideoCore::Surface::IsPixelFormatBCn(pixel_format)) {
const bool is_srgb = with_srgb && VideoCore::Surface::IsPixelFormatSRGB(pixel_format);
if (pixel_format == PixelFormat::BC4_SNORM) {
tuple.format = VK_FORMAT_R8_SNORM;
} else if (pixel_format == PixelFormat::BC4_UNORM) {
@@ -260,7 +268,8 @@ FormatInfo SurfaceFormat(const Device& device, FormatType format_type, bool with
tuple.format = VK_FORMAT_R8G8_SNORM;
} else if (pixel_format == PixelFormat::BC5_UNORM) {
tuple.format = VK_FORMAT_R8G8_UNORM;
} else if (pixel_format == PixelFormat::BC6H_SFLOAT || pixel_format == PixelFormat::BC6H_UFLOAT) {
} else if (pixel_format == PixelFormat::BC6H_SFLOAT ||
pixel_format == PixelFormat::BC6H_UFLOAT) {
tuple.format = VK_FORMAT_R16G16B16A16_SFLOAT;
} else if (is_srgb) {
tuple.format = VK_FORMAT_A8B8G8R8_SRGB_PACK32;
@@ -268,8 +277,9 @@ FormatInfo SurfaceFormat(const Device& device, FormatType format_type, bool with
tuple.format = VK_FORMAT_A8B8G8R8_UNORM_PACK32;
}
}
bool const attachable = (tuple.usage & usage_attachable) != 0;
bool const storage = (tuple.usage & usage_storage) != 0;
const bool attachable = (tuple.usage & Attachable) != 0;
const bool storage = (tuple.usage & Storage) != 0;
VkFormatFeatureFlags usage{};
switch (format_type) {
case FormatType::Buffer:
@@ -189,12 +189,16 @@ inline void PushImageDescriptors(TextureCache& texture_cache,
const VideoCommon::ImageViewId image_view_id{(views++)->id};
const VideoCommon::SamplerId sampler_id{*(samplers++)};
ImageView& image_view{texture_cache.GetImageView(image_view_id)};
const VkImageView vk_image_view{image_view.Handle(desc.type)};
const VkImageView vk_image_view{
image_view.SampledView(desc.type, desc.component_type)};
const Sampler& sampler{texture_cache.GetSampler(sampler_id)};
const bool use_fallback_sampler{sampler.HasAddedAnisotropy() &&
!image_view.SupportsAnisotropy()};
const VkSampler vk_sampler{use_fallback_sampler ? sampler.HandleWithDefaultAnisotropy()
: sampler.Handle()};
const bool supports_linear_filter{
texture_cache.SupportsLinearFilter(image_view.format)};
const bool supports_depth_compare_sampling{
image_view.SupportsDepthCompareSampling()};
const VkSampler vk_sampler{
sampler.SelectHandle(supports_linear_filter, image_view.SupportsAnisotropy(),
supports_depth_compare_sampling)};
guest_descriptor_queue.AddSampledImage(vk_image_view, vk_sampler);
rescaling.PushTexture(texture_cache.IsRescaling(image_view));
}
@@ -280,7 +280,6 @@ void Layer::UpdateRawImage(const Tegra::FramebufferConfig& framebuffer, size_t i
Tegra::Texture::UnswizzleTexture(
mapped_span.subspan(image_offset, linear_size), std::span(host_ptr, tiled_size),
bytes_per_pixel, framebuffer.width, framebuffer.height, 1, block_height_log2, 0);
buffer.Flush(); // Ensure host writes are visible before the GPU copy.
}
const VkBufferImageCopy copy{
@@ -7,6 +7,7 @@
#include <algorithm>
#include <array>
#include <cstring>
#include <limits>
#include <span>
#include <vector>
@@ -333,6 +334,13 @@ BufferCacheRuntime::BufferCacheRuntime(const Device& device_, MemoryAllocator& m
staging_pool{staging_pool_}, guest_descriptor_queue{guest_descriptor_queue_},
quad_index_pass(device, scheduler, descriptor_pool, staging_pool,
compute_pass_descriptor_queue) {
const VkDriverIdKHR driver_id = device.GetDriverID();
limit_dynamic_storage_buffers = driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY ||
driver_id == VK_DRIVER_ID_MESA_TURNIP ||
driver_id == VK_DRIVER_ID_ARM_PROPRIETARY;
if (limit_dynamic_storage_buffers) {
max_dynamic_storage_buffers = device.GetMaxDescriptorSetStorageBuffersDynamic();
}
if (device.GetDriverID() != VK_DRIVER_ID_QUALCOMM_PROPRIETARY) {
// TODO: FixMe: Uint8Pass compute shader does not build on some Qualcomm drivers.
uint8_pass = std::make_unique<Uint8Pass>(device, scheduler, descriptor_pool, staging_pool,
@@ -408,6 +416,10 @@ bool BufferCacheRuntime::CanReportMemoryUsage() const {
return device.CanReportMemoryUsage();
}
u32 BufferCacheRuntime::GetUniformBufferAlignment() const {
return static_cast<u32>(device.GetUniformBufferAlignment());
}
u32 BufferCacheRuntime::GetStorageBufferAlignment() const {
return static_cast<u32>(device.GetStorageBufferAlignment());
}
@@ -583,7 +595,15 @@ void BufferCacheRuntime::BindVertexBuffer(u32 index, VkBuffer buffer, u32 offset
if (index >= device.GetMaxVertexInputBindings()) {
return;
}
if (device.IsExtExtendedDynamicStateSupported()) {
if (!device.HasNullDescriptor() && buffer == VK_NULL_HANDLE) {
ReserveNullBuffer();
buffer = *null_buffer;
offset = 0;
size = std::numeric_limits<u32>::max();
}
// Use BindVertexBuffers2EXT only if EDS1 is supported AND VIDS is not active
// When VIDS is active, the pipeline doesn't declare VERTEX_INPUT_BINDING_STRIDE as dynamic
if (device.IsExtExtendedDynamicStateSupported() && !device.IsExtVertexInputDynamicStateSupported()) {
scheduler.Record([index, buffer, offset, size, stride](vk::CommandBuffer cmdbuf) {
const VkDeviceSize vk_offset = buffer != VK_NULL_HANDLE ? offset : 0;
const VkDeviceSize vk_size = buffer != VK_NULL_HANDLE ? size : VK_WHOLE_SIZE;
@@ -623,7 +643,8 @@ void BufferCacheRuntime::BindVertexBuffers(VideoCommon::HostBindings<Buffer>& bi
if (binding_count == 0) {
return;
}
if (device.IsExtExtendedDynamicStateSupported()) {
// Use BindVertexBuffers2EXT only if EDS1 is supported AND VIDS is not active
if (device.IsExtExtendedDynamicStateSupported() && !device.IsExtVertexInputDynamicStateSupported()) {
scheduler.Record([bindings_ = std::move(bindings),
buffer_handles_ = std::move(buffer_handles),
binding_count](vk::CommandBuffer cmdbuf) {
@@ -680,27 +701,50 @@ void BufferCacheRuntime::BindTransformFeedbackBuffers(VideoCommon::HostBindings<
}
void BufferCacheRuntime::ReserveNullBuffer() {
const VkBufferUsageFlags expected_usage = NullBufferUsageFlags();
if (null_buffer && null_buffer_usage_flags != expected_usage) {
RefreshNullBuffer();
}
if (!null_buffer) {
null_buffer = CreateNullBuffer();
}
}
VkBufferUsageFlags BufferCacheRuntime::NullBufferUsageFlags() const {
VkBufferUsageFlags usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT |
VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT |
VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT |
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT |
VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
if (device.IsExtTransformFeedbackSupported()) {
usage |= VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT;
}
return usage;
}
void BufferCacheRuntime::RefreshNullBuffer() {
if (!null_buffer) {
return;
}
scheduler.Finish();
null_buffer.reset();
null_buffer = CreateNullBuffer();
}
vk::Buffer BufferCacheRuntime::CreateNullBuffer() {
VkBufferCreateInfo create_info{
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.size = 4,
.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT |
VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT,
.usage = NullBufferUsageFlags(),
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.queueFamilyIndexCount = 0,
.pQueueFamilyIndices = nullptr,
};
if (device.IsExtTransformFeedbackSupported()) {
create_info.usage |= VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT;
}
vk::Buffer ret = memory_allocator.CreateBuffer(create_info, MemoryUsage::DeviceLocal);
null_buffer_usage_flags = create_info.usage;
if (device.HasDebuggingToolAttached()) {
ret.SetObjectNameEXT("Null buffer");
}
@@ -6,6 +6,8 @@
#pragma once
#include <limits>
#include "video_core/buffer_cache/buffer_cache_base.h"
#include "video_core/buffer_cache/memory_tracker_base.h"
#include "video_core/buffer_cache/usage_tracker.h"
@@ -94,6 +96,8 @@ public:
bool CanReportMemoryUsage() const;
u32 GetUniformBufferAlignment() const;
u32 GetStorageBufferAlignment() const;
[[nodiscard]] StagingBufferRef UploadStagingBuffer(size_t size);
@@ -127,6 +131,9 @@ public:
void BindTransformFeedbackBuffers(VideoCommon::HostBindings<Buffer>& bindings);
/// Forces destruction and recreation of the shared null buffer so new usage flags take effect.
void RefreshNullBuffer();
std::span<u8> BindMappedUniformBuffer([[maybe_unused]] size_t /*stage*/,
[[maybe_unused]] u32 /*binding_index*/,
u32 size) {
@@ -155,6 +162,14 @@ public:
guest_descriptor_queue.AddTexelBuffer(buffer.View(offset, size, format));
}
bool ShouldLimitDynamicStorageBuffers() const {
return limit_dynamic_storage_buffers;
}
u32 GetMaxDynamicStorageBuffers() const {
return max_dynamic_storage_buffers;
}
private:
void BindBuffer(VkBuffer buffer, u32 offset, u32 size) {
guest_descriptor_queue.AddBuffer(buffer, offset, size);
@@ -162,6 +177,7 @@ private:
void ReserveNullBuffer();
vk::Buffer CreateNullBuffer();
VkBufferUsageFlags NullBufferUsageFlags() const;
struct UniformRing {
static constexpr size_t NUM_FRAMES = 3;
@@ -191,9 +207,13 @@ private:
std::shared_ptr<QuadStripIndexBuffer> quad_strip_index_buffer;
vk::Buffer null_buffer;
VkBufferUsageFlags null_buffer_usage_flags = 0;
std::unique_ptr<Uint8Pass> uint8_pass;
QuadIndexedPass quad_index_pass;
bool limit_dynamic_storage_buffers = false;
u32 max_dynamic_storage_buffers = std::numeric_limits<u32>::max();
};
struct BufferCacheParams {
@@ -418,6 +418,9 @@ ConditionalRenderingResolvePass::ConditionalRenderingResolvePass(
void ConditionalRenderingResolvePass::Resolve(VkBuffer dst_buffer, VkBuffer src_buffer,
u32 src_offset, bool compare_to_zero) {
if (!device.IsExtConditionalRendering()) {
return;
}
const size_t compare_size = compare_to_zero ? 8 : 24;
compute_pass_descriptor_queue.Acquire();
@@ -448,7 +451,7 @@ void ConditionalRenderingResolvePass::Resolve(VkBuffer dst_buffer, VkBuffer src_
cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_COMPUTE, *layout, 0, set, {});
cmdbuf.Dispatch(1, 1, 1);
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT, 0, write_barrier);
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, write_barrier);
});
}
@@ -459,10 +462,14 @@ QueriesPrefixScanPass::QueriesPrefixScanPass(
device_, descriptor_pool_, QUERIES_SCAN_DESCRIPTOR_SET_BINDINGS,
QUERIES_SCAN_DESCRIPTOR_UPDATE_TEMPLATE, QUERIES_SCAN_BANK_INFO,
COMPUTE_PUSH_CONSTANT_RANGE<sizeof(QueriesPrefixScanPushConstants)>,
device_.IsSubgroupFeatureSupported(VK_SUBGROUP_FEATURE_BASIC_BIT) &&
device_.IsSubgroupFeatureSupported(VK_SUBGROUP_FEATURE_ARITHMETIC_BIT) &&
device_.IsSubgroupFeatureSupported(VK_SUBGROUP_FEATURE_SHUFFLE_BIT) &&
device_.IsSubgroupFeatureSupported(VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT)
device_.IsSubgroupFeatureSupported(VK_SUBGROUP_FEATURE_BASIC_BIT,
VK_SHADER_STAGE_COMPUTE_BIT) &&
device_.IsSubgroupFeatureSupported(VK_SUBGROUP_FEATURE_ARITHMETIC_BIT,
VK_SHADER_STAGE_COMPUTE_BIT) &&
device_.IsSubgroupFeatureSupported(VK_SUBGROUP_FEATURE_SHUFFLE_BIT,
VK_SHADER_STAGE_COMPUTE_BIT) &&
device_.IsSubgroupFeatureSupported(VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT,
VK_SHADER_STAGE_COMPUTE_BIT)
? std::span<const u32>(QUERIES_PREFIX_SCAN_SUM_COMP_SPV)
: std::span<const u32>(QUERIES_PREFIX_SCAN_SUM_NOSUBGROUPS_COMP_SPV)),
scheduler{scheduler_}, compute_pass_descriptor_queue{compute_pass_descriptor_queue_} {}
@@ -470,6 +477,14 @@ QueriesPrefixScanPass::QueriesPrefixScanPass(
void QueriesPrefixScanPass::Run(VkBuffer accumulation_buffer, VkBuffer dst_buffer,
VkBuffer src_buffer, size_t number_of_sums,
size_t min_accumulation_limit, size_t max_accumulation_limit) {
constexpr VkAccessFlags BASE_DST_ACCESS = VK_ACCESS_SHADER_READ_BIT |
VK_ACCESS_TRANSFER_READ_BIT |
VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT |
VK_ACCESS_INDIRECT_COMMAND_READ_BIT |
VK_ACCESS_INDEX_READ_BIT |
VK_ACCESS_UNIFORM_READ_BIT;
const VkAccessFlags conditional_access =
device.IsExtConditionalRendering() ? VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT : 0;
size_t current_runs = number_of_sums;
size_t offset = 0;
while (current_runs != 0) {
@@ -486,22 +501,18 @@ void QueriesPrefixScanPass::Run(VkBuffer accumulation_buffer, VkBuffer dst_buffe
scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([this, descriptor_data, min_accumulation_limit, max_accumulation_limit,
runs_to_do, used_offset](vk::CommandBuffer cmdbuf) {
runs_to_do, used_offset, conditional_access](vk::CommandBuffer cmdbuf) {
static constexpr VkMemoryBarrier read_barrier{
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
};
static constexpr VkMemoryBarrier write_barrier{
const VkMemoryBarrier write_barrier{
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT |
VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT |
VK_ACCESS_INDIRECT_COMMAND_READ_BIT | VK_ACCESS_INDEX_READ_BIT |
VK_ACCESS_UNIFORM_READ_BIT |
VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT,
.dstAccessMask = BASE_DST_ACCESS | conditional_access,
};
const QueriesPrefixScanPushConstants uniforms{
.min_accumulation_base = static_cast<u32>(min_accumulation_limit),
@@ -519,8 +530,7 @@ void QueriesPrefixScanPass::Run(VkBuffer accumulation_buffer, VkBuffer dst_buffe
cmdbuf.PushConstants(*layout, VK_SHADER_STAGE_COMPUTE_BIT, uniforms);
cmdbuf.Dispatch(1, 1, 1);
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT, 0,
write_barrier);
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, write_barrier);
});
}
}
@@ -18,14 +18,49 @@
#include "video_core/renderer_vulkan/vk_scheduler.h"
#include "video_core/renderer_vulkan/vk_update_descriptor.h"
#include "video_core/shader_notify.h"
#include "video_core/surface.h"
#include "video_core/texture_cache/texture_cache.h"
#include "video_core/vulkan_common/vulkan_device.h"
#include "video_core/vulkan_common/vulkan_wrapper.h"
#include <optional>
namespace Vulkan {
using Shader::ImageBufferDescriptor;
using Shader::Backend::SPIRV::RESCALING_LAYOUT_WORDS_OFFSET;
using Tegra::Texture::TexturePair;
using VideoCore::Surface::PixelFormat;
using VideoCore::Surface::PixelFormatNumeric;
static std::optional<PixelFormatNumeric> NumericFromComponentType(
Shader::SamplerComponentType component_type) {
switch (component_type) {
case Shader::SamplerComponentType::Float:
return PixelFormatNumeric::Float;
case Shader::SamplerComponentType::Sint:
return PixelFormatNumeric::Sint;
case Shader::SamplerComponentType::Uint:
return PixelFormatNumeric::Uint;
default:
return std::nullopt;
}
}
static PixelFormat ResolveTexelBufferFormat(PixelFormat format,
Shader::SamplerComponentType component_type) {
const auto desired_numeric = NumericFromComponentType(component_type);
if (!desired_numeric) {
return format;
}
const auto current_numeric = VideoCore::Surface::GetPixelFormatNumericType(format);
if (*desired_numeric == current_numeric) {
return format;
}
if (const auto variant = VideoCore::Surface::FindPixelFormatVariant(format, *desired_numeric)) {
return *variant;
}
return format;
}
ComputePipeline::ComputePipeline(const Device& device_, vk::PipelineCache& pipeline_cache_,
DescriptorPool& descriptor_pool,
@@ -182,8 +217,12 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute,
is_written = desc.is_written;
}
ImageView& image_view = texture_cache.GetImageView(views[index].id);
VideoCore::Surface::PixelFormat buffer_format = image_view.format;
if constexpr (!is_image) {
buffer_format = ResolveTexelBufferFormat(buffer_format, desc.component_type);
}
buffer_cache.BindComputeTextureBuffer(index, image_view.GpuAddr(),
image_view.BufferSize(), image_view.format,
image_view.BufferSize(), buffer_format,
is_written, is_image);
++index;
}
@@ -34,6 +34,10 @@ public:
void Wait();
[[nodiscard]] u64 WaitTick() const noexcept {
return wait_tick;
}
private:
Scheduler& scheduler;
u64 wait_tick = 0;
@@ -5,6 +5,8 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include <algorithm>
#include <array>
#include <optional>
#include <iostream>
#include <span>
@@ -23,7 +25,9 @@
#include "video_core/renderer_vulkan/vk_texture_cache.h"
#include "video_core/renderer_vulkan/vk_update_descriptor.h"
#include "video_core/shader_notify.h"
#include "video_core/texture_cache/samples_helper.h"
#include "video_core/texture_cache/texture_cache.h"
#include "video_core/surface.h"
#include "video_core/vulkan_common/vulkan_device.h"
#if defined(_MSC_VER) && defined(NDEBUG)
@@ -44,10 +48,83 @@ using Tegra::Texture::TexturePair;
using VideoCore::Surface::PixelFormat;
using VideoCore::Surface::PixelFormatFromDepthFormat;
using VideoCore::Surface::PixelFormatFromRenderTargetFormat;
using VideoCore::Surface::PixelFormatNumeric;
constexpr size_t NUM_STAGES = Maxwell::MaxShaderStage;
constexpr size_t MAX_IMAGE_ELEMENTS = 64;
std::optional<PixelFormatNumeric> NumericFromComponentType(
Shader::SamplerComponentType component_type) {
switch (component_type) {
case Shader::SamplerComponentType::Float:
return PixelFormatNumeric::Float;
case Shader::SamplerComponentType::Sint:
return PixelFormatNumeric::Sint;
case Shader::SamplerComponentType::Uint:
return PixelFormatNumeric::Uint;
default:
return std::nullopt;
}
}
PixelFormat ResolveTexelBufferFormat(PixelFormat format,
Shader::SamplerComponentType component_type) {
const auto desired_numeric = NumericFromComponentType(component_type);
if (!desired_numeric) {
return format;
}
const auto current_numeric = VideoCore::Surface::GetPixelFormatNumericType(format);
if (*desired_numeric == current_numeric) {
return format;
}
if (const auto variant = VideoCore::Surface::FindPixelFormatVariant(format, *desired_numeric)) {
return *variant;
}
return format;
}
bool UsesDualSourceFactor(Maxwell::Blend::Factor factor) {
switch (factor) {
case Maxwell::Blend::Factor::Source1Color_D3D:
case Maxwell::Blend::Factor::Source1Color_GL:
case Maxwell::Blend::Factor::OneMinusSource1Color_D3D:
case Maxwell::Blend::Factor::OneMinusSource1Color_GL:
case Maxwell::Blend::Factor::Source1Alpha_D3D:
case Maxwell::Blend::Factor::Source1Alpha_GL:
case Maxwell::Blend::Factor::OneMinusSource1Alpha_D3D:
case Maxwell::Blend::Factor::OneMinusSource1Alpha_GL:
return true;
default:
return false;
}
}
Maxwell::Blend::Factor FallbackDualSourceFactor(Maxwell::Blend::Factor factor) {
switch (factor) {
case Maxwell::Blend::Factor::Source1Color_D3D:
case Maxwell::Blend::Factor::Source1Color_GL:
return Maxwell::Blend::Factor::SourceColor_D3D;
case Maxwell::Blend::Factor::OneMinusSource1Color_D3D:
case Maxwell::Blend::Factor::OneMinusSource1Color_GL:
return Maxwell::Blend::Factor::OneMinusSourceColor_D3D;
case Maxwell::Blend::Factor::Source1Alpha_D3D:
case Maxwell::Blend::Factor::Source1Alpha_GL:
return Maxwell::Blend::Factor::SourceAlpha_D3D;
case Maxwell::Blend::Factor::OneMinusSource1Alpha_D3D:
case Maxwell::Blend::Factor::OneMinusSource1Alpha_GL:
return Maxwell::Blend::Factor::OneMinusSourceAlpha_D3D;
default:
return factor;
}
}
bool AttachmentUsesDualSource(const FixedPipelineState::BlendingAttachment& blend) {
return UsesDualSourceFactor(blend.SourceRGBFactor()) ||
UsesDualSourceFactor(blend.DestRGBFactor()) ||
UsesDualSourceFactor(blend.SourceAlphaFactor()) ||
UsesDualSourceFactor(blend.DestAlphaFactor());
}
DescriptorLayoutBuilder MakeBuilder(const Device& device, std::span<const Shader::Info> infos) {
DescriptorLayoutBuilder builder{device};
for (size_t index = 0; index < infos.size(); ++index) {
@@ -263,6 +340,7 @@ GraphicsPipeline::GraphicsPipeline(
std::ranges::copy(info->constant_buffer_used_sizes, uniform_buffer_sizes[stage].begin());
num_textures += Shader::NumDescriptors(info->texture_descriptors);
}
fragment_has_color0_output = stage_infos[NUM_STAGES - 1].stores_frag_color[0];
auto func{[this, shader_notify, &render_pass_cache, &descriptor_pool, pipeline_statistics] {
DescriptorLayoutBuilder builder{MakeBuilder(device, stage_infos)};
uses_push_descriptor = builder.CanUsePushDescriptor();
@@ -416,8 +494,12 @@ bool GraphicsPipeline::ConfigureImpl(bool is_indexed) {
is_written = desc.is_written;
}
ImageView& image_view{texture_cache.GetImageView(texture_buffer_it->id)};
VideoCore::Surface::PixelFormat buffer_format = image_view.format;
if constexpr (!is_image) {
buffer_format = ResolveTexelBufferFormat(buffer_format, desc.component_type);
}
buffer_cache.BindGraphicsTextureBuffer(stage, index, image_view.GpuAddr(),
image_view.BufferSize(), image_view.format,
image_view.BufferSize(), buffer_format,
is_written, is_image);
++index;
++texture_buffer_it;
@@ -702,13 +784,18 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
.lineWidth = 1.0f,
// TODO(alekpop): Transfer from regs
};
const bool smooth_lines_supported =
device.IsExtLineRasterizationSupported() && device.SupportsSmoothLines();
const bool stippled_lines_supported =
device.IsExtLineRasterizationSupported() && device.SupportsStippledRectangularLines();
VkPipelineRasterizationLineStateCreateInfoEXT line_state{
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT,
.pNext = nullptr,
.lineRasterizationMode = key.state.smooth_lines != 0
.lineRasterizationMode = key.state.smooth_lines != 0 && smooth_lines_supported
? VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT
: VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT,
.stippledLineEnable = dynamic.line_stipple_enable ? VK_TRUE : VK_FALSE,
.stippledLineEnable =
(dynamic.line_stipple_enable && stippled_lines_supported) ? VK_TRUE : VK_FALSE,
.lineStippleFactor = key.state.line_stipple_factor,
.lineStipplePattern = static_cast<uint16_t>(key.state.line_stipple_pattern),
};
@@ -739,17 +826,25 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
provoking_vertex.pNext = std::exchange(rasterization_ci.pNext, &provoking_vertex);
}
const VkPipelineMultisampleStateCreateInfo multisample_ci{
const bool supports_alpha_output = fragment_has_color0_output;
const bool alpha_to_one_supported = device.SupportsAlphaToOne();
const auto msaa_mode = key.state.msaa_mode.Value();
const VkSampleCountFlagBits vk_samples = MaxwellToVK::MsaaMode(msaa_mode);
VkPipelineMultisampleStateCreateInfo multisample_ci{
.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.rasterizationSamples = MaxwellToVK::MsaaMode(key.state.msaa_mode),
.sampleShadingEnable = Settings::values.sample_shading.GetValue() > 0 ? VK_TRUE : VK_FALSE,
.minSampleShading = f32(Settings::values.sample_shading.GetValue()) / 100.0f,
.rasterizationSamples = vk_samples,
.sampleShadingEnable = Settings::values.sample_shading.GetValue() ? VK_TRUE : VK_FALSE,
.minSampleShading = static_cast<float>(Settings::values.sample_shading_fraction.GetValue()) / 100.0f,
.pSampleMask = nullptr,
.alphaToCoverageEnable = key.state.alpha_to_coverage_enabled != 0 ? VK_TRUE : VK_FALSE,
.alphaToOneEnable = key.state.alpha_to_one_enabled != 0 ? VK_TRUE : VK_FALSE,
.alphaToCoverageEnable =
supports_alpha_output && key.state.alpha_to_coverage_enabled != 0 ? VK_TRUE : VK_FALSE,
.alphaToOneEnable = supports_alpha_output && alpha_to_one_supported &&
key.state.alpha_to_one_enabled != 0 ? VK_TRUE : VK_FALSE,
};
const VkPipelineDepthStencilStateCreateInfo depth_stencil_ci{
.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
.pNext = nullptr,
@@ -763,14 +858,20 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
.stencilTestEnable = dynamic.stencil_enable,
.front = GetStencilFaceState(dynamic.front),
.back = GetStencilFaceState(dynamic.back),
.minDepthBounds = f32(key.state.depth_bounds_min),
.maxDepthBounds = f32(key.state.depth_bounds_max),
.minDepthBounds = static_cast<f32>(key.state.depth_bounds_min),
.maxDepthBounds = static_cast<f32>(key.state.depth_bounds_max),
};
if (dynamic.depth_bounds_enable && !device.IsDepthBoundsSupported()) {
LOG_WARNING(Render_Vulkan, "Depth bounds is enabled but not supported");
}
static_vector<VkPipelineColorBlendAttachmentState, Maxwell::NumRenderTargets> cb_attachments;
const size_t num_attachments{NumAttachments(key.state)};
const bool supports_dual_source_blend = device.SupportsDualSourceBlend();
const u32 max_dual_source_attachments = supports_dual_source_blend
? device.MaxFragmentDualSrcAttachments()
: 0;
u32 granted_dual_source_attachments = 0;
bool logged_dual_source_warning = false;
for (size_t index = 0; index < num_attachments; ++index) {
static constexpr std::array mask_table{
VK_COLOR_COMPONENT_R_BIT,
@@ -784,13 +885,30 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
for (size_t i = 0; i < mask_table.size(); ++i) {
write_mask |= mask[i] ? mask_table[i] : 0;
}
const bool attachment_uses_dual_source = AttachmentUsesDualSource(blend);
const bool allow_dual_source = attachment_uses_dual_source && supports_dual_source_blend &&
granted_dual_source_attachments < max_dual_source_attachments;
if (allow_dual_source) {
++granted_dual_source_attachments;
} else if (attachment_uses_dual_source && !logged_dual_source_warning) {
LOG_WARNING(Render_Vulkan,
"Dual-source blend factors exceed device limit (maxFragmentDualSrcAttachments={}), falling back to single-source factors",
max_dual_source_attachments);
logged_dual_source_warning = true;
}
const auto sanitize_factor = [&](Maxwell::Blend::Factor factor) {
if (allow_dual_source || !UsesDualSourceFactor(factor)) {
return factor;
}
return FallbackDualSourceFactor(factor);
};
cb_attachments.push_back({
.blendEnable = blend.enable != 0,
.srcColorBlendFactor = MaxwellToVK::BlendFactor(blend.SourceRGBFactor()),
.dstColorBlendFactor = MaxwellToVK::BlendFactor(blend.DestRGBFactor()),
.srcColorBlendFactor = MaxwellToVK::BlendFactor(sanitize_factor(blend.SourceRGBFactor())),
.dstColorBlendFactor = MaxwellToVK::BlendFactor(sanitize_factor(blend.DestRGBFactor())),
.colorBlendOp = MaxwellToVK::BlendEquation(blend.EquationRGB()),
.srcAlphaBlendFactor = MaxwellToVK::BlendFactor(blend.SourceAlphaFactor()),
.dstAlphaBlendFactor = MaxwellToVK::BlendFactor(blend.DestAlphaFactor()),
.srcAlphaBlendFactor = MaxwellToVK::BlendFactor(sanitize_factor(blend.SourceAlphaFactor())),
.dstAlphaBlendFactor = MaxwellToVK::BlendFactor(sanitize_factor(blend.DestAlphaFactor())),
.alphaBlendOp = MaxwellToVK::BlendEquation(blend.EquationAlpha()),
.colorWriteMask = write_mask,
});
@@ -806,14 +924,25 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
.blendConstants = {}
};
static_vector<VkDynamicState, 34> dynamic_states{
VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR,
VK_DYNAMIC_STATE_DEPTH_BIAS, VK_DYNAMIC_STATE_BLEND_CONSTANTS,
VK_DYNAMIC_STATE_DEPTH_BOUNDS, VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
VK_DYNAMIC_STATE_STENCIL_WRITE_MASK, VK_DYNAMIC_STATE_STENCIL_REFERENCE,
VK_DYNAMIC_STATE_VIEWPORT,
VK_DYNAMIC_STATE_SCISSOR,
VK_DYNAMIC_STATE_DEPTH_BIAS,
VK_DYNAMIC_STATE_LINE_WIDTH,
};
if (device.UsesAdvancedCoreDynamicState()) {
static constexpr std::array core_dynamic_states{
VK_DYNAMIC_STATE_BLEND_CONSTANTS,
VK_DYNAMIC_STATE_DEPTH_BOUNDS,
VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
VK_DYNAMIC_STATE_STENCIL_REFERENCE,
};
dynamic_states.insert(dynamic_states.end(), core_dynamic_states.begin(),
core_dynamic_states.end());
}
if (key.state.extended_dynamic_state) {
std::vector<VkDynamicState> extended{
static constexpr std::array extended{
VK_DYNAMIC_STATE_CULL_MODE_EXT,
VK_DYNAMIC_STATE_FRONT_FACE_EXT,
VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT,
@@ -823,51 +952,68 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT,
VK_DYNAMIC_STATE_STENCIL_OP_EXT,
};
if (!device.IsExtVertexInputDynamicStateSupported()) {
extended.push_back(VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT);
}
if (key.state.dynamic_vertex_input) {
dynamic_states.push_back(VK_DYNAMIC_STATE_VERTEX_INPUT_EXT);
}
dynamic_states.insert(dynamic_states.end(), extended.begin(), extended.end());
if (key.state.extended_dynamic_state_2) {
static constexpr std::array extended2{
VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT,
VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT,
VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT,
};
dynamic_states.insert(dynamic_states.end(), extended2.begin(), extended2.end());
// VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT is part of EDS1
// Only use it if VIDS is not active (VIDS replaces it with full vertex input control)
if (!key.state.dynamic_vertex_input) {
dynamic_states.push_back(VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT);
}
if (key.state.extended_dynamic_state_2_extra) {
dynamic_states.push_back(VK_DYNAMIC_STATE_LOGIC_OP_EXT);
}
// VK_DYNAMIC_STATE_VERTEX_INPUT_EXT (VIDS) - Independent from EDS
// Provides full dynamic vertex input control, replaces VERTEX_INPUT_BINDING_STRIDE
if (key.state.dynamic_vertex_input) {
dynamic_states.push_back(VK_DYNAMIC_STATE_VERTEX_INPUT_EXT);
}
// EDS2 - Core (3 states)
if (key.state.extended_dynamic_state_2) {
static constexpr std::array extended2{
VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT,
VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT,
VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT,
};
dynamic_states.insert(dynamic_states.end(), extended2.begin(), extended2.end());
}
// EDS2 - LogicOp (granular)
if (key.state.extended_dynamic_state_2_logic_op) {
dynamic_states.push_back(VK_DYNAMIC_STATE_LOGIC_OP_EXT);
}
// EDS3 - Blending (composite: 3 states)
if (key.state.extended_dynamic_state_3_blend) {
static constexpr std::array extended3{
VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT,
VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT,
VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT,
};
dynamic_states.insert(dynamic_states.end(), extended3.begin(), extended3.end());
}
// EDS3 - Enables (composite: per-feature)
if (key.state.extended_dynamic_state_3_enables) {
if (device.SupportsDynamicState3DepthClampEnable()) {
dynamic_states.push_back(VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT);
}
if (key.state.extended_dynamic_state_3_blend) {
static constexpr std::array extended3{
VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT,
VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT,
VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT,
// VK_DYNAMIC_STATE_COLOR_BLEND_ADVANCED_EXT,
};
dynamic_states.insert(dynamic_states.end(), extended3.begin(), extended3.end());
if (device.SupportsDynamicState3LogicOpEnable()) {
dynamic_states.push_back(VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT);
}
if (key.state.extended_dynamic_state_3_enables) {
static constexpr std::array extended3{
VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT,
VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT,
// additional state3 extensions
VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT,
VK_DYNAMIC_STATE_CONSERVATIVE_RASTERIZATION_MODE_EXT,
VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT,
VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT,
VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT,
VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT,
VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT,
};
dynamic_states.insert(dynamic_states.end(), extended3.begin(), extended3.end());
if (device.SupportsDynamicState3LineRasterizationMode()) {
dynamic_states.push_back(VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT);
}
if (device.SupportsDynamicState3ConservativeRasterizationMode()) {
dynamic_states.push_back(VK_DYNAMIC_STATE_CONSERVATIVE_RASTERIZATION_MODE_EXT);
}
if (device.SupportsDynamicState3LineStippleEnable()) {
dynamic_states.push_back(VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT);
}
if (device.SupportsDynamicState3AlphaToCoverageEnable()) {
dynamic_states.push_back(VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT);
}
if (device.SupportsDynamicState3AlphaToOneEnable()) {
dynamic_states.push_back(VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT);
}
}
@@ -82,6 +82,17 @@ public:
const std::array<const Shader::Info*, NUM_STAGES>& infos);
bool HasDynamicVertexInput() const noexcept { return key.state.dynamic_vertex_input; }
bool SupportsAlphaToCoverage() const noexcept {
return fragment_has_color0_output;
}
bool SupportsAlphaToOne() const noexcept {
return fragment_has_color0_output;
}
bool UsesExtendedDynamicState() const noexcept {
return key.state.extended_dynamic_state != 0;
}
GraphicsPipeline& operator=(GraphicsPipeline&&) noexcept = delete;
GraphicsPipeline(GraphicsPipeline&&) noexcept = delete;
@@ -149,6 +160,7 @@ private:
std::array<u32, 5> enabled_uniform_buffer_masks{};
VideoCommon::UniformBufferSizes uniform_buffer_sizes{};
u32 num_textures{};
bool fragment_has_color0_output{};
vk::DescriptorSetLayout descriptor_set_layout;
DescriptorAllocator descriptor_allocator;
@@ -36,6 +36,7 @@
#include "video_core/renderer_vulkan/vk_scheduler.h"
#include "video_core/renderer_vulkan/vk_shader_util.h"
#include "video_core/renderer_vulkan/vk_update_descriptor.h"
#include "video_core/surface.h"
#include "video_core/shader_cache.h"
#include "video_core/shader_environment.h"
#include "video_core/shader_notify.h"
@@ -105,6 +106,41 @@ Shader::CompareFunction MaxwellToCompareFunction(Maxwell::ComparisonOp compariso
return {};
}
Shader::AttributeType RenderTargetAttributeType(Tegra::RenderTargetFormat format) {
if (format == Tegra::RenderTargetFormat::NONE) {
return Shader::AttributeType::Float;
}
const auto pixel_format{
VideoCore::Surface::PixelFormatFromRenderTargetFormat(format)};
if (!VideoCore::Surface::IsPixelFormatInteger(pixel_format)) {
return Shader::AttributeType::Float;
}
if (VideoCore::Surface::IsPixelFormatSignedInteger(pixel_format)) {
return Shader::AttributeType::SignedInt;
}
return Shader::AttributeType::UnsignedInt;
}
VkShaderStageFlagBits StageToVkStage(Shader::Stage stage) {
switch (stage) {
case Shader::Stage::VertexA:
case Shader::Stage::VertexB:
return VK_SHADER_STAGE_VERTEX_BIT;
case Shader::Stage::TessellationControl:
return VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
case Shader::Stage::TessellationEval:
return VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
case Shader::Stage::Geometry:
return VK_SHADER_STAGE_GEOMETRY_BIT;
case Shader::Stage::Fragment:
return VK_SHADER_STAGE_FRAGMENT_BIT;
case Shader::Stage::Compute:
return VK_SHADER_STAGE_COMPUTE_BIT;
default:
return VK_SHADER_STAGE_VERTEX_BIT;
}
}
Shader::AttributeType CastAttributeType(const FixedPipelineState::VertexAttribute& attr) {
if (attr.enabled == 0) {
return Shader::AttributeType::Disabled;
@@ -146,7 +182,8 @@ Shader::AttributeType AttributeType(const FixedPipelineState& state, size_t inde
Shader::RuntimeInfo MakeRuntimeInfo(std::span<const Shader::IR::Program> programs,
const GraphicsPipelineCacheKey& key,
const Shader::IR::Program& program,
const Shader::IR::Program* previous_program) {
const Shader::IR::Program* previous_program,
const Vulkan::Device& device) {
Shader::RuntimeInfo info;
if (previous_program) {
info.previous_stage_stores = previous_program->info.stores;
@@ -168,10 +205,14 @@ Shader::RuntimeInfo MakeRuntimeInfo(std::span<const Shader::IR::Program> program
info.fixed_state_point_size = point_size;
}
if (key.state.xfb_enabled) {
auto [varyings, count] =
VideoCommon::MakeTransformFeedbackVaryings(key.state.xfb_state);
info.xfb_varyings = varyings;
info.xfb_count = count;
if (device.IsExtTransformFeedbackSupported()) {
auto [varyings, count] =
VideoCommon::MakeTransformFeedbackVaryings(key.state.xfb_state);
info.xfb_varyings = varyings;
info.xfb_count = count;
} else {
LOG_WARNING(Render_Vulkan, "XFB requested in pipeline key but device lacks VK_EXT_transform_feedback; ignoring XFB decorations");
}
}
info.convert_depth_mode = gl_ndc;
}
@@ -218,10 +259,14 @@ Shader::RuntimeInfo MakeRuntimeInfo(std::span<const Shader::IR::Program> program
info.fixed_state_point_size = point_size;
}
if (key.state.xfb_enabled != 0) {
auto [varyings, count] =
VideoCommon::MakeTransformFeedbackVaryings(key.state.xfb_state);
info.xfb_varyings = varyings;
info.xfb_count = count;
if (device.IsExtTransformFeedbackSupported()) {
auto [varyings, count] =
VideoCommon::MakeTransformFeedbackVaryings(key.state.xfb_state);
info.xfb_varyings = varyings;
info.xfb_count = count;
} else {
LOG_WARNING(Render_Vulkan, "XFB requested in pipeline key but device lacks VK_EXT_transform_feedback; ignoring XFB decorations");
}
}
info.convert_depth_mode = gl_ndc;
break;
@@ -229,6 +274,10 @@ Shader::RuntimeInfo MakeRuntimeInfo(std::span<const Shader::IR::Program> program
info.alpha_test_func = MaxwellToCompareFunction(
key.state.UnpackComparisonOp(key.state.alpha_test_func.Value()));
info.alpha_test_reference = std::bit_cast<float>(key.state.alpha_test_ref);
for (size_t index = 0; index < Maxwell::NumRenderTargets; ++index) {
const auto format = static_cast<Tegra::RenderTargetFormat>(key.state.color_formats[index]);
info.color_output_types[index] = RenderTargetAttributeType(format);
}
break;
default:
break;
@@ -269,8 +318,8 @@ size_t GetTotalPipelineWorkers() {
const size_t max_core_threads =
std::max<size_t>(static_cast<size_t>(std::thread::hardware_concurrency()), 2ULL) - 1ULL;
#ifdef ANDROID
// Leave at least a few cores free in android
constexpr size_t free_cores = 3ULL;
// Leave at least one core free on Android to reduce thermal pressure.
constexpr size_t free_cores = 1ULL;
if (max_core_threads <= free_cores) {
return 1ULL;
}
@@ -317,6 +366,7 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
"VkPipelineBuilder"),
serialization_thread(1, "VkPipelineSerialization") {
const auto& float_control{device.FloatControlProperties()};
const bool float_controls_supported{device.IsKhrShaderFloatControlsSupported()};
const VkDriverId driver_id{device.GetDriverID()};
profile = Shader::Profile{
.supported_spirv = device.SupportedSpirvVersion(),
@@ -326,20 +376,24 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
.support_int16 = device.IsShaderInt16Supported(),
.support_int64 = device.IsShaderInt64Supported(),
.support_vertex_instance_id = false,
.support_float_controls = device.IsKhrShaderFloatControlsSupported(),
.support_separate_denorm_behavior =
.support_float_controls = float_controls_supported,
.support_separate_denorm_behavior = float_controls_supported &&
float_control.denormBehaviorIndependence == VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL,
.support_separate_rounding_mode =
.support_separate_rounding_mode = float_controls_supported &&
float_control.roundingModeIndependence == VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL,
.support_fp16_denorm_preserve = float_control.shaderDenormPreserveFloat16 != VK_FALSE,
.support_fp32_denorm_preserve = float_control.shaderDenormPreserveFloat32 != VK_FALSE,
.support_fp16_denorm_flush = float_control.shaderDenormFlushToZeroFloat16 != VK_FALSE,
.support_fp32_denorm_flush = float_control.shaderDenormFlushToZeroFloat32 != VK_FALSE,
.support_fp16_signed_zero_nan_preserve =
.support_fp16_denorm_preserve = float_controls_supported &&
float_control.shaderDenormPreserveFloat16 != VK_FALSE,
.support_fp32_denorm_preserve = float_controls_supported &&
float_control.shaderDenormPreserveFloat32 != VK_FALSE,
.support_fp16_denorm_flush = float_controls_supported &&
float_control.shaderDenormFlushToZeroFloat16 != VK_FALSE,
.support_fp32_denorm_flush = float_controls_supported &&
float_control.shaderDenormFlushToZeroFloat32 != VK_FALSE,
.support_fp16_signed_zero_nan_preserve = float_controls_supported &&
float_control.shaderSignedZeroInfNanPreserveFloat16 != VK_FALSE,
.support_fp32_signed_zero_nan_preserve =
.support_fp32_signed_zero_nan_preserve = float_controls_supported &&
float_control.shaderSignedZeroInfNanPreserveFloat32 != VK_FALSE,
.support_fp64_signed_zero_nan_preserve =
.support_fp64_signed_zero_nan_preserve = float_controls_supported &&
float_control.shaderSignedZeroInfNanPreserveFloat64 != VK_FALSE,
.support_explicit_workgroup_layout = device.IsKhrWorkgroupMemoryExplicitLayoutSupported(),
.support_vote = device.IsSubgroupFeatureSupported(VK_SUBGROUP_FEATURE_VOTE_BIT),
@@ -395,6 +449,27 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
.support_conditional_barrier = device.SupportsConditionalBarriers(),
};
profile.warp_stage_support_mask = 0;
static constexpr std::array kAllStages{
Shader::Stage::VertexA, Shader::Stage::VertexB,
Shader::Stage::TessellationControl, Shader::Stage::TessellationEval,
Shader::Stage::Geometry, Shader::Stage::Fragment,
Shader::Stage::Compute,
};
for (const auto stage : kAllStages) {
const auto vk_stage = StageToVkStage(stage);
if (device.SupportsWarpIntrinsics(vk_stage)) {
profile.warp_stage_support_mask |= 1u << static_cast<u32>(stage);
}
}
profile.support_vote = profile.warp_stage_support_mask != 0;
if (!profile.SupportsWarpIntrinsics(Shader::Stage::Fragment)) {
LOG_WARNING(Render_Vulkan,
"Fragment shaders lack subgroup support on this driver; warp intrinsics will be "
"approximated and visual artifacts may remain");
}
if (device.GetMaxVertexInputAttributes() < Maxwell::NumVertexAttributes) {
LOG_WARNING(Render_Vulkan, "maxVertexInputAttributes is too low: {} < {}",
device.GetMaxVertexInputAttributes(), Maxwell::NumVertexAttributes);
@@ -404,14 +479,40 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
device.GetMaxVertexInputBindings(), Maxwell::NumVertexArrays);
}
dynamic_features = DynamicFeatures{
.has_extended_dynamic_state = device.IsExtExtendedDynamicStateSupported(),
.has_extended_dynamic_state_2 = device.IsExtExtendedDynamicState2Supported(),
.has_extended_dynamic_state_2_extra = device.IsExtExtendedDynamicState2ExtrasSupported(),
.has_extended_dynamic_state_3_blend = device.IsExtExtendedDynamicState3BlendingSupported(),
.has_extended_dynamic_state_3_enables = device.IsExtExtendedDynamicState3EnablesSupported(),
.has_dynamic_vertex_input = device.IsExtVertexInputDynamicStateSupported(),
};
LOG_INFO(Render_Vulkan, "DynamicState setting value: {}", Settings::values.dyna_state.GetValue());
dynamic_features = {};
// User granularity enforced in vulkan_device.cpp switch statement:
// Level 0: Core Dynamic States only
// Level 1: Core + EDS1
// Level 2: Core + EDS1 + EDS2 (accumulative)
// Level 3: Core + EDS1 + EDS2 + EDS3 (accumulative)
// Here we only verify if extensions were successfully loaded by the device
dynamic_features.has_extended_dynamic_state =
device.IsExtExtendedDynamicStateSupported();
dynamic_features.has_extended_dynamic_state_2 =
device.IsExtExtendedDynamicState2Supported();
dynamic_features.has_extended_dynamic_state_2_logic_op =
device.IsExtExtendedDynamicState2ExtrasSupported();
dynamic_features.has_extended_dynamic_state_2_patch_control_points = false;
dynamic_features.has_extended_dynamic_state_3_blend =
device.IsExtExtendedDynamicState3BlendingSupported();
dynamic_features.has_dual_source_blend = device.SupportsDualSourceBlend();
if (!dynamic_features.has_dual_source_blend) {
LOG_WARNING(Render_Vulkan, "Dual-source blending unsupported, disabling dynamic blend");
dynamic_features.has_extended_dynamic_state_3_blend = false;
}
dynamic_features.has_extended_dynamic_state_3_enables =
device.IsExtExtendedDynamicState3EnablesSupported();
// VIDS: Independent toggle (not affected by dyna_state levels)
dynamic_features.has_dynamic_vertex_input =
device.IsExtVertexInputDynamicStateSupported() &&
Settings::values.vertex_input_dynamic_state.GetValue();
}
PipelineCache::~PipelineCache() {
@@ -421,6 +522,13 @@ PipelineCache::~PipelineCache() {
}
}
void PipelineCache::DrainPendingBuilds() {
if (!device.HasBrokenParallelShaderCompiling()) {
return;
}
workers.WaitForRequests();
}
GraphicsPipeline* PipelineCache::CurrentGraphicsPipeline() {
if (!RefreshStages(graphics_key.unique_hashes)) {
@@ -451,12 +559,17 @@ ComputePipeline* PipelineCache::CurrentComputePipeline() {
.shared_memory_size = qmd.shared_alloc,
.workgroup_size{qmd.block_dim_x, qmd.block_dim_y, qmd.block_dim_z},
};
const auto [pair, is_new]{compute_cache.try_emplace(key)};
const auto [pair, inserted]{compute_cache.try_emplace(key)};
auto& pipeline{pair->second};
if (!is_new) {
return pipeline.get();
if (!pipeline) {
auto [slot, should_build] = AcquireComputeBuildSlot(key);
if (!should_build) {
WaitForBuildCompletion(slot);
} else {
pipeline = CreateComputePipeline(key, shader);
ReleaseComputeBuildSlot(key, slot);
}
}
pipeline = CreateComputePipeline(key, shader);
return pipeline.get();
}
@@ -516,8 +629,8 @@ void PipelineCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading
dynamic_features.has_extended_dynamic_state ||
(key.state.extended_dynamic_state_2 != 0) !=
dynamic_features.has_extended_dynamic_state_2 ||
(key.state.extended_dynamic_state_2_extra != 0) !=
dynamic_features.has_extended_dynamic_state_2_extra ||
(key.state.extended_dynamic_state_2_logic_op != 0) !=
dynamic_features.has_extended_dynamic_state_2_logic_op ||
(key.state.extended_dynamic_state_3_blend != 0) !=
dynamic_features.has_extended_dynamic_state_3_blend ||
(key.state.extended_dynamic_state_3_enables != 0) !=
@@ -572,13 +685,20 @@ void PipelineCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading
}
GraphicsPipeline* PipelineCache::CurrentGraphicsPipelineSlowPath() {
const auto [pair, is_new]{graphics_cache.try_emplace(graphics_key)};
const auto [pair, inserted]{graphics_cache.try_emplace(graphics_key)};
auto& pipeline{pair->second};
if (is_new) {
pipeline = CreateGraphicsPipeline();
}
if (!pipeline) {
return nullptr;
const auto key = pair->first;
auto [slot, should_build] = AcquireGraphicsBuildSlot(key);
if (!should_build) {
WaitForBuildCompletion(slot);
} else {
pipeline = CreateGraphicsPipeline();
ReleaseGraphicsBuildSlot(key, slot);
}
if (!pipeline) {
return nullptr;
}
}
if (current_pipeline) {
current_pipeline->AddTransition(pipeline.get());
@@ -601,6 +721,7 @@ GraphicsPipeline* PipelineCache::BuiltPipeline(GraphicsPipeline* pipeline) const
if (draw_state.index_buffer.count <= 6 || draw_state.vertex_buffer.count <= 6) {
return pipeline;
}
scheduler.KeepAliveTick();
return nullptr;
}
@@ -671,7 +792,7 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline(
const size_t stage_index{index - 1};
infos[stage_index] = &program.info;
const auto runtime_info{MakeRuntimeInfo(programs, key, program, previous_stage)};
const auto runtime_info{MakeRuntimeInfo(programs, key, program, previous_stage, device)};
ConvertLegacyToGeneric(program, runtime_info);
const std::vector<u32> code{EmitSPIRV(profile, runtime_info, program, binding, this->optimize_spirv_output)};
device.SaveShader(code);
@@ -704,6 +825,10 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline(
}
LOG_ERROR(Render_Vulkan, "{}", exception.what());
return nullptr;
} catch (const vk::Exception& exception) {
LOG_ERROR(Render_Vulkan, "Failed to create graphics pipeline 0x{:016x}: {}", key.Hash(),
exception.what());
return nullptr;
}
std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline() {
@@ -767,6 +892,19 @@ std::unique_ptr<ComputePipeline> PipelineCache::CreateComputePipeline(
}
auto program{TranslateProgram(pools.inst, pools.block, env, cfg, host_info)};
const VkDriverIdKHR driver_id = device.GetDriverID();
const bool needs_shared_mem_clamp =
driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY ||
driver_id == VK_DRIVER_ID_ARM_PROPRIETARY;
const u32 max_shared_memory = device.GetMaxComputeSharedMemorySize();
if (needs_shared_mem_clamp && program.shared_memory_size > max_shared_memory) {
LOG_WARNING(Render_Vulkan,
"Compute shader 0x{:016x} requests {}KB shared memory but device max is {}KB - clamping",
key.unique_hash,
program.shared_memory_size / 1024,
max_shared_memory / 1024);
program.shared_memory_size = max_shared_memory;
}
const std::vector<u32> code{EmitSPIRV(profile, program, this->optimize_spirv_output)};
device.SaveShader(code);
vk::ShaderModule spv_module{BuildShader(device, code)};
@@ -782,6 +920,10 @@ std::unique_ptr<ComputePipeline> PipelineCache::CreateComputePipeline(
} catch (const Shader::Exception& exception) {
LOG_ERROR(Render_Vulkan, "{}", exception.what());
return nullptr;
} catch (const vk::Exception& exception) {
LOG_ERROR(Render_Vulkan, "Failed to create compute pipeline 0x{:016x}: {}", key.Hash(),
exception.what());
return nullptr;
}
void PipelineCache::SerializeVulkanPipelineCache(const std::filesystem::path& filename,
@@ -879,4 +1021,68 @@ vk::PipelineCache PipelineCache::LoadVulkanPipelineCache(const std::filesystem::
}
}
auto PipelineCache::AcquireGraphicsBuildSlot(const GraphicsPipelineCacheKey& key)
-> std::pair<InFlightPipelinePtr, bool> {
std::scoped_lock lock(graphics_inflight_mutex);
auto [it, inserted] = graphics_inflight_builds.try_emplace(key);
if (inserted || !it->second) {
it->second = std::make_shared<InFlightPipelineBuild>();
return {it->second, true};
}
return {it->second, false};
}
auto PipelineCache::AcquireComputeBuildSlot(const ComputePipelineCacheKey& key)
-> std::pair<InFlightPipelinePtr, bool> {
std::scoped_lock lock(compute_inflight_mutex);
auto [it, inserted] = compute_inflight_builds.try_emplace(key);
if (inserted || !it->second) {
it->second = std::make_shared<InFlightPipelineBuild>();
return {it->second, true};
}
return {it->second, false};
}
void PipelineCache::ReleaseGraphicsBuildSlot(const GraphicsPipelineCacheKey& key,
const InFlightPipelinePtr& slot) {
if (!slot) {
return;
}
{
std::scoped_lock slot_lock(slot->mutex);
slot->building = false;
}
slot->cv.notify_all();
std::scoped_lock map_lock(graphics_inflight_mutex);
auto it = graphics_inflight_builds.find(key);
if (it != graphics_inflight_builds.end() && it->second == slot) {
graphics_inflight_builds.erase(it);
}
}
void PipelineCache::ReleaseComputeBuildSlot(const ComputePipelineCacheKey& key,
const InFlightPipelinePtr& slot) {
if (!slot) {
return;
}
{
std::scoped_lock slot_lock(slot->mutex);
slot->building = false;
}
slot->cv.notify_all();
std::scoped_lock map_lock(compute_inflight_mutex);
auto it = compute_inflight_builds.find(key);
if (it != compute_inflight_builds.end() && it->second == slot) {
compute_inflight_builds.erase(it);
}
}
void PipelineCache::WaitForBuildCompletion(const InFlightPipelinePtr& slot) const {
if (!slot) {
return;
}
std::unique_lock lock(slot->mutex);
slot->cv.wait(lock, [&] { return !slot->building; });
}
} // namespace Vulkan

Some files were not shown because too many files have changed in this diff Show More