12 #ifndef hifi_gpu_vk_VKBackend_h
13 #define hifi_gpu_vk_VKBackend_h
24 #include <gpu/Forward.h>
25 #include <gpu/Context.h>
27 #include <vk/Config.h>
28 #include <vk/Context.h>
29 #include <vk/VulkanDebug.h>
30 #include <vulkan/vulkan_core.h>
31 #include <glad/glad.h>
33 #include "VKForward.h"
34 #include "VKPipelineCache.h"
35 #include "../../../../vk/src/vk/Context.h"
38 #define GPU_STEREO_TECHNIQUE_INSTANCED
41 #ifdef GPU_STEREO_TECHNIQUE_DOUBLED_SIMPLE
42 #define GPU_STEREO_DRAWCALL_DOUBLED
45 #ifdef GPU_STEREO_TECHNIQUE_DOUBLED_SMARTER
46 #define GPU_STEREO_DRAWCALL_DOUBLED
47 #define GPU_STEREO_CAMERA_BUFFER
50 #ifdef GPU_STEREO_TECHNIQUE_INSTANCED
51 #define GPU_STEREO_DRAWCALL_INSTANCED
52 #define GPU_STEREO_CAMERA_BUFFER
55 namespace gpu {
namespace vk {
57 class VKAttachmentTexture;
59 static const int MAX_NUM_UNIFORM_BUFFERS = 14;
61 static const int32_t MIN_REQUIRED_TEXTURE_IMAGE_UNITS = 16;
62 static const int32_t MIN_REQUIRED_COMBINED_UNIFORM_BLOCKS = 70;
63 static const int32_t MIN_REQUIRED_COMBINED_TEXTURE_IMAGE_UNITS = 48;
64 static const int32_t MIN_REQUIRED_UNIFORM_BUFFER_BINDINGS = 36;
65 static const int32_t MIN_REQUIRED_UNIFORM_LOCATIONS = 1024;
67 static const int MAX_NUM_RESOURCE_BUFFERS = 16;
68 static const int MAX_NUM_RESOURCE_TEXTURES = 16;
70 class VKInputFormat :
public GPUObject {
72 static VKInputFormat* sync(
const Stream::Format& inputFormat);
80 class VKBackend :
public Backend,
public std::enable_shared_from_this<VKBackend> {
85 static BackendPointer createBackend();
88 static const uint INVALID_SAVED_CAMERA_SLOT = (uint)-1;
97 mat4 correctionInverse;
98 mat4 unflippedCorrection;
99 mat4 flippedCorrection;
100 bool mirrorViewCorrection {
false };
103 struct UniformStageState;
105 struct TransformStageState {
106 #ifdef GPU_STEREO_CAMERA_BUFFER
108 TransformCamera _cams[2];
111 Cameras(
const TransformCamera& cam) { _cams[0] = cam; };
112 Cameras(
const TransformCamera& camL,
const TransformCamera& camR) {
118 using CameraBufferElement = Cameras;
120 using CameraBufferElement = TransformCamera;
122 using TransformCameras = std::vector<CameraBufferElement>;
124 struct ViewProjectionState {
126 Transform _correctedView;
127 Transform _previousCorrectedView;
129 Mat4 _previousProjection;
132 void copyExceptPrevious(
const ViewProjectionState& other) {
134 _correctedView = other._correctedView;
135 _projection = other._projection;
136 _viewIsCamera = other._viewIsCamera;
140 struct SaveTransform {
141 ViewProjectionState _state;
142 size_t _cameraOffset { INVALID_OFFSET };
145 TransformCamera _camera;
146 TransformCameras _cameras;
147 std::array<SaveTransform, gpu::Batch::MAX_TRANSFORM_SAVE_SLOT_COUNT> _savedTransforms;
149 mutable std::map<std::string, VkDeviceSize> _drawCallInfoOffsets;
152 size_t _cameraUboSize{ 0 };
153 ViewProjectionState _viewProjectionState;
154 uint _currentSavedTransformSlot { INVALID_SAVED_CAMERA_SLOT };
155 bool _skybox{
false };
157 PresentFrame _presentFrame;
158 bool _viewCorrectionEnabled{
true };
160 bool _viewCorrectionEnabledForFramePlayer{
false };
163 std::vector<Vec2> _offsetSequence;
164 Vec2 _offset { 0.0f };
165 float _scale { 0.f };
166 unsigned int _currentSampleIndex { 0 };
167 bool _isEnabled {
false };
170 Jitter _projectionJitter;
171 Vec4i _viewport{ 0, 0, 1, 1 };
172 Vec2 _depthRange{ 0.0f, 1.0f };
173 bool _invalidView{
false };
174 bool _invalidProj{
false };
175 bool _invalidViewport{
false };
177 bool _enabledDrawcallInfoBuffer{
false };
179 using Pair = std::pair<size_t, size_t>;
180 using List = std::list<Pair>;
182 mutable List::const_iterator _camerasItr;
183 mutable size_t _currentCameraOffset{ INVALID_OFFSET };
185 void pushCameraBufferElement(
const StereoState& stereo,
const StereoState& prevStereo, TransformCameras& cameras)
const;
186 void preUpdate(
size_t commandIndex,
const StereoState& stereo,
const StereoState& prevStereo, Vec2u framebufferSize);
187 void update(
size_t commandIndex,
const StereoState& stereo, VKBackend::UniformStageState &uniform, FrameData ¤tFrame)
const;
188 void bindCurrentCamera(
int stereoSide, VKBackend::UniformStageState &uniform, FrameData ¤tFrame)
const;
191 void preUpdateTransform();
192 void transferTransformState(
const Batch& batch);
195 struct InputStageState {
196 bool _invalidFormat {
true };
197 bool _lastUpdateStereoState {
false };
198 FormatReference _format { GPU_REFERENCE_INIT_VALUE };
199 std::string _formatKey;
201 typedef std::bitset<MAX_NUM_ATTRIBUTES> ActivationCache;
202 ActivationCache _attributeActivation { 0 };
204 typedef std::bitset<MAX_NUM_INPUT_BUFFERS> BuffersState;
206 BuffersState _invalidBuffers { 0 };
207 BuffersState _attribBindingBuffers { 0 };
209 std::array<BufferReference, MAX_NUM_INPUT_BUFFERS> _buffers;
210 std::array<Offset, MAX_NUM_INPUT_BUFFERS> _bufferOffsets;
211 std::array<Offset, MAX_NUM_INPUT_BUFFERS> _bufferStrides;
212 std::array<VkBuffer, MAX_NUM_INPUT_BUFFERS> _bufferVBOs;
214 BufferReference _indexBuffer;
215 Offset _indexBufferOffset { 0 };
216 Type _indexBufferType { UINT32 };
218 BufferReference _indirectBuffer;
219 Offset _indirectBufferOffset { 0 };
220 Offset _indirectBufferStride { 0 };
222 uint32_t _defaultVAO { 0 };
227 void resetInputStage();
229 struct UniformStageState {
231 BufferReference buffer{};
232 uint32_t offset{ 0 };
235 BufferState& operator=(
const BufferState& other) =
delete;
246 std::array<BufferState, MIN_REQUIRED_UNIFORM_BUFFER_BINDINGS> _buffers;
249 void updateVkDescriptorWriteSetsUniform(
const Cache::PipelineLayout &layout,
250 std::vector<VkWriteDescriptorSet> &oldSets,
251 std::vector<VkDescriptorBufferInfo> &oldBufferInfos,
252 bool hasPipelineChanged);
253 void releaseUniformBuffer(uint32_t slot);
254 void resetUniformStage();
256 struct ResourceStageState {
257 struct TextureState {
258 TexturePointer texture{};
259 TextureState& operator=(
const TextureState& other) =
delete;
265 BufferReference buffer{};
266 BufferState& operator=(
const BufferState& other) =
delete;
271 std::array<BufferState, MAX_NUM_RESOURCE_BUFFERS> _buffers{};
272 std::array<TextureState, MAX_NUM_RESOURCE_TEXTURES> _textures{};
275 void updateVkDescriptorWriteSetsTexture(
const Cache::PipelineLayout &layout,
276 std::vector<VkWriteDescriptorSet> &oldSets,
277 std::vector<VkDescriptorImageInfo> &oldImageInfos,
278 bool hasPipelineChanged);
280 void bindResourceTexture(uint32_t slot,
const TexturePointer& texture);
281 void releaseResourceTexture(uint32_t slot);
282 void resetTextureStage();
284 void updateVkDescriptorWriteSetsStorage(
const Cache::PipelineLayout &layout,
285 std::vector<VkWriteDescriptorSet> &oldSets,
286 std::vector<VkDescriptorBufferInfo> &oldBufferInfos,
287 bool hasPipelineChanged);
288 void releaseResourceBuffer(uint32_t slot);
289 void resetResourceStage();
298 struct QueryStageState {
299 uint32_t _rangeQueryDepth{ 0 };
302 void resetQueryStage();
304 VkRenderPass _currentVkRenderPass{ VK_NULL_HANDLE };
305 gpu::FramebufferReference _currentFramebuffer{
nullptr };
306 VkFramebuffer _currentVkFramebuffer{ VK_NULL_HANDLE };
307 bool _hasFramebufferChanged {
false};
309 void updateRenderPass();
310 void updateAttachmentLayoutsAfterRenderPass();
311 void resetRenderPass();
316 std::vector<VkBufferMemoryBarrier> bufferBarriers;
318 std::vector<VkDescriptorSet> uniformDescriptorSets;
319 std::vector<VkDescriptorSet> textureDescriptorSets;
320 std::vector<VkDescriptorSet> storageDescriptorSets;
321 VkDescriptorPool _descriptorPool;
322 std::vector<std::shared_ptr<gpu::Buffer>> _buffers;
323 std::vector<VkRenderPass> _renderPasses;
325 std::shared_ptr<gpu::Buffer> _objectBuffer;
326 std::shared_ptr<gpu::Buffer> _cameraBuffer;
327 std::shared_ptr<gpu::Buffer> _drawCallInfoBuffer;
329 std::shared_ptr<gpu::Buffer> _glUniformBuffer;
330 std::vector<uint8_t> _glUniformData;
331 std::unordered_map<int, size_t> _glUniformOffsetMap;
332 size_t _glUniformBufferPosition {0};
334 size_t _bufferTransferCounterTransferPass {0};
335 size_t _bufferTransferCounterRenderPass {0};
336 size_t _uniformBufferTransferCounter {0};
337 size_t _vertexBufferTransferCounter {0};
338 size_t _indexBufferTransferCounter {0};
339 size_t _resourceBufferTransferCounter {0};
340 size_t _bufferTransferredBytes{0};
342 size_t _bufferCreationCounter {0};
343 size_t _bufferResizeCounter {0};
346 void addBufferBarrier(
const VkBufferMemoryBarrier &barrier);
348 void addGlUniform(
size_t size,
const void *data,
size_t commandIndex);
350 FrameData(VKBackend *backend);
351 FrameData() =
delete;
357 void createDescriptorPool();
362 void draw(VkPrimitiveTopology mode, uint32 numVertices, uint32 startVertex);
363 void renderPassTransfer(
const Batch& batch);
364 void renderPassDraw(
const Batch& batch);
365 void transferGlUniforms();
367 void updateTransform(
const Batch& batch);
368 void updatePipeline();
370 vk::VKFramebuffer* syncGPUObject(
const Framebuffer *framebuffer);
371 VKBuffer* syncGPUObject(
const Buffer *buffer);
372 VKBuffer* syncGPUObjectNoTransfer(
const Buffer *buffer);
373 VKTexture* syncGPUObject(
const std::shared_ptr<Texture> &texture);
374 VKQuery* syncGPUObject(
const Query *query);
376 void blitToFramebuffer(VKAttachmentTexture &input,
const Vec4i& srcViewport, VKAttachmentTexture &output,
const Vec4i& dstViewport);
381 void shutdown()
override;
382 vks::Context& getContext() {
return _context; }
383 void syncProgram(
const gpu::ShaderPointer& program)
override {}
384 void syncCache()
override {}
386 void recycle()
const override {}
387 void updatePresentFrame(
const Mat4& correction =
Mat4(),
bool primary =
true)
override;
388 void executeFrame(
const FramePointer& frame)
final;
389 void render(
const Batch& batch)
final;
390 bool isTextureManagementSparseEnabled()
const override;
391 bool supportedTextureFormat(
const gpu::Element& format)
const override;
392 const std::string& getVersion()
const override;
393 void downloadFramebuffer(
const FramebufferPointer& srcFramebuffer,
const Vec4i& region, QImage& destImage)
final;
394 void setDrawCommandBuffer(VkCommandBuffer commandBuffer);
395 size_t getNumInputBuffers()
const {
return _input._invalidBuffers.size(); }
396 VkDescriptorImageInfo getDefaultTextureDescriptorInfo();
398 void enableContextViewCorrectionForFramePlayer() { _transform._viewCorrectionEnabledForFramePlayer =
true; };
399 void setIsFramePlayer(
bool isFramePlayer) { _isFramePlayer = isFramePlayer; };
401 static gpu::Primitive getPrimitiveTopologyFromCommand(Batch::Command command,
const Batch& batch,
size_t paramOffset);
403 int getRealUniformLocation(
int location);
405 static size_t getTotalMemory() {
return 8000000; }
406 static size_t getDedicatedMemory() {
return 8000000; }
407 static size_t getAvailableMemory() {
return 5000000; }
408 static bool availableMemoryKnown() {
return true; }
411 virtual void store_glUniform1i(
const Batch& batch,
size_t paramOffset)
final;
412 virtual void store_glUniform1f(
const Batch& batch,
size_t paramOffset)
final;
413 virtual void store_glUniform2f(
const Batch& batch,
size_t paramOffset)
final;
414 virtual void store_glUniform3f(
const Batch& batch,
size_t paramOffset)
final;
415 virtual void store_glUniform4f(
const Batch& batch,
size_t paramOffset)
final;
416 virtual void store_glUniform3fv(
const Batch& batch,
size_t paramOffset)
final;
417 virtual void store_glUniform4fv(
const Batch& batch,
size_t paramOffset)
final;
418 virtual void store_glUniform4iv(
const Batch& batch,
size_t paramOffset)
final;
419 virtual void store_glUniformMatrix3fv(
const Batch& batch,
size_t paramOffset)
final;
420 virtual void store_glUniformMatrix4fv(
const Batch& batch,
size_t paramOffset)
final;
423 virtual void do_draw(
const Batch& batch,
size_t paramOffset)
final;
424 virtual void do_drawIndexed(
const Batch& batch,
size_t paramOffset)
final;
425 virtual void do_drawInstanced(
const Batch& batch,
size_t paramOffset)
final;
426 virtual void do_drawIndexedInstanced(
const Batch& batch,
size_t paramOffset)
final;
427 virtual void do_multiDrawIndirect(
const Batch& batch,
size_t paramOffset)
final;
428 virtual void do_multiDrawIndexedIndirect(
const Batch& batch,
size_t paramOffset)
final;
431 virtual void do_setInputFormat(
const Batch& batch,
size_t paramOffset)
final;
432 virtual void do_setInputBuffer(
const Batch& batch,
size_t paramOffset)
final;
433 virtual void do_setIndexBuffer(
const Batch& batch,
size_t paramOffset)
final;
434 virtual void do_setIndirectBuffer(
const Batch& batch,
size_t paramOffset)
final;
435 virtual void do_generateTextureMips(
const Batch& batch,
size_t paramOffset)
final;
436 virtual void do_generateTextureMipsWithPipeline(
const Batch& batch,
size_t paramOffset)
final;
438 virtual void do_glUniform1i(
const Batch& batch,
size_t paramOffset)
final;
439 virtual void do_glUniform1f(
const Batch& batch,
size_t paramOffset)
final;
440 virtual void do_glUniform2f(
const Batch& batch,
size_t paramOffset)
final;
441 virtual void do_glUniform3f(
const Batch& batch,
size_t paramOffset)
final;
442 virtual void do_glUniform4f(
const Batch& batch,
size_t paramOffset)
final;
443 virtual void do_glUniform3fv(
const Batch& batch,
size_t paramOffset)
final;
444 virtual void do_glUniform4fv(
const Batch& batch,
size_t paramOffset)
final;
445 virtual void do_glUniform4iv(
const Batch& batch,
size_t paramOffset)
final;
446 virtual void do_glUniformMatrix3fv(
const Batch& batch,
size_t paramOffset)
final;
447 virtual void do_glUniformMatrix4fv(
const Batch& batch,
size_t paramOffset)
final;
450 virtual void do_setModelTransform(
const Batch& batch,
size_t paramOffset)
final;
451 virtual void do_setViewTransform(
const Batch& batch,
size_t paramOffset)
final;
452 virtual void do_setProjectionTransform(
const Batch& batch,
size_t paramOffset)
final;
453 virtual void do_setProjectionJitterEnabled(
const Batch& batch,
size_t paramOffset)
final;
454 virtual void do_setProjectionJitterSequence(
const Batch& batch,
size_t paramOffset)
final;
455 virtual void do_setProjectionJitterScale(
const Batch& batch,
size_t paramOffset)
final;
457 virtual void do_setViewportTransform(
const Batch& batch,
size_t paramOffset)
final;
458 virtual void do_setDepthRangeTransform(
const Batch& batch,
size_t paramOffset)
final;
459 virtual void do_saveViewProjectionTransform(
const Batch& batch,
size_t paramOffset)
final;
460 virtual void do_setSavedViewProjectionTransform(
const Batch& batch,
size_t paramOffset)
final;
461 virtual void do_copySavedViewProjectionTransformToBuffer(
const Batch& batch,
size_t paramOffset)
final;
464 virtual void do_setUniformBuffer(
const Batch& batch,
size_t paramOffset)
final;
467 virtual void do_setResourceBuffer(
const Batch& batch,
size_t paramOffset)
final;
468 virtual void do_setResourceTexture(
const Batch& batch,
size_t paramOffset)
final;
469 virtual void do_setResourceTextureTable(
const Batch& batch,
size_t paramOffset)
final;
470 virtual void do_setResourceFramebufferSwapChainTexture(
const Batch& batch,
size_t paramOffset)
final;
473 virtual void do_setPipeline(
const Batch& batch,
size_t paramOffset)
final;
476 virtual void do_setFramebuffer(
const Batch& batch,
size_t paramOffset)
final;
477 virtual void do_setFramebufferSwapChain(
const Batch& batch,
size_t paramOffset)
final;
478 virtual void do_clearFramebuffer(
const Batch& batch,
size_t paramOffset)
final;
479 virtual void do_blit(
const Batch& batch,
size_t paramOffset)
final;
480 virtual void do_advance(
const Batch& batch,
size_t paramOffset)
final;
481 virtual void do_setStateBlendFactor(
const Batch& batch,
size_t paramOffset)
final;
482 virtual void do_setStateScissorRect(
const Batch& batch,
size_t paramOffset)
final;
485 virtual void do_beginQuery(
const Batch& batch,
size_t paramOffset)
final;
486 virtual void do_endQuery(
const Batch& batch,
size_t paramOffset)
final;
487 virtual void do_getQuery(
const Batch& batch,
size_t paramOffset)
final;
490 virtual void do_resetStages(
const Batch& batch,
size_t paramOffset)
final;
492 virtual void do_disableContextViewCorrection(
const Batch& batch,
size_t paramOffset)
final;
493 virtual void do_restoreContextViewCorrection(
const Batch& batch,
size_t paramOffset)
final;
494 virtual void do_setContextMirrorViewCorrection(
const Batch& batch,
size_t paramOffset)
final;
496 virtual void do_disableContextStereo(
const Batch& batch,
size_t paramOffset)
final;
497 virtual void do_restoreContextStereo(
const Batch& batch,
size_t paramOffset)
final;
500 virtual void do_runLambda(
const Batch& batch,
size_t paramOffset)
final;
501 virtual void do_startNamedCall(
const Batch& batch,
size_t paramOffset)
final;
502 virtual void do_stopNamedCall(
const Batch& batch,
size_t paramOffset)
final;
505 virtual void do_pushProfileRange(
const Batch& batch,
size_t paramOffset)
final;
506 virtual void do_popProfileRange(
const Batch& batch,
size_t paramOffset)
final;
510 void initBeforeFirstFrame();
512 void initTransform();
513 void initDefaultTexture();
517 void acquireFrameData();
520 void releaseFrameData() { _currentFrame.reset(); };
523 void recyclePreviousFrame();
526 void releaseExternalTexture(GLuint
id,
const Texture::ExternalRecycler& recycler);
529 VKFramebuffer *_outputTexture{
nullptr };
531 struct TextureManagementStageState {
532 bool _sparseCapable{
false };
533 std::shared_ptr<VKTextureTransferEngine> _transferEngine;
534 } _textureManagement;
536 virtual void initTextureManagementStage();
537 virtual void killTextureManagementStage();
539 void transitionInputImageLayouts();
545 std::unordered_set<VKFramebuffer*> _framebuffers;
546 std::unordered_set<VKBuffer*> _buffers;
547 std::unordered_set<VKTexture*> _textures;
548 std::unordered_set<VKQuery*> _queries;
549 void perFrameCleanup();
551 void beforeShutdownCleanup();
552 void dumpVmaMemoryStats();
555 std::vector<VkWriteDescriptorSet> uniformVkWriteDescriptorSets;
556 std::vector<VkDescriptorBufferInfo> uniformVkDescriptorBufferInfo;
557 std::vector<VkWriteDescriptorSet> textureVkWriteDescriptorSets;
558 std::vector<VkDescriptorImageInfo> textureVkDescriptorBufferInfo;
559 std::vector<VkWriteDescriptorSet> storageVkWriteDescriptorSets;
560 std::vector<VkDescriptorBufferInfo> storageVkDescriptorBufferInfo;
562 std::mutex _externalTexturesMutex;
563 std::list<std::pair<GLuint, Texture::ExternalRecycler>> _externalTexturesTrash;
567 VkPipelineCache _pipelineCache;
569 vks::Context& _context{ vks::Context::get() };
570 std::shared_ptr<gpu::Texture> _defaultTexture;
571 VKTexture* _defaultTextureVk{
nullptr };
572 VkDescriptorImageInfo _defaultTextureImageInfo{};
573 std::shared_ptr<gpu::Texture> _defaultSkyboxTexture;
574 VKTexture* _defaultSkyboxTextureVk{
nullptr };
575 VkDescriptorImageInfo _defaultSkyboxTextureImageInfo{};
576 friend class VKBuffer;
577 friend class VKFramebuffer;
578 friend class VKQuery;
579 VkCommandBuffer _currentCommandBuffer;
580 size_t _commandIndex{ 0 };
581 int _currentDraw{ -1 };
582 bool _inRenderTransferPass{
false };
584 Vec4i _currentScissorRect{ 0 };
586 std::vector<std::shared_ptr<FrameData>> _framePool;
587 std::deque<std::shared_ptr<FrameData>> _framesToReuse;
589 std::shared_ptr<FrameData> _currentFrame;
591 std::shared_ptr<FrameData> _currentlyRenderedFrame;
593 std::shared_ptr<FrameData> _previouslyRenderedFrame;
594 size_t _frameCounter{ 0 };
597 std::atomic<bool> isBackendShutdownComplete{
false };
599 typedef void (VKBackend::*CommandCall)(
const Batch&, size_t);
600 static std::array<VKBackend::CommandCall, Batch::NUM_COMMANDS> _commandCalls;
601 static const size_t INVALID_OFFSET = (size_t)-1;
602 static size_t UNIFORM_BUFFER_OFFSET_ALIGNMENT;
603 bool _isFramePlayer {
false};
604 bool _isInitialized {
false};
Provides the Mat4 scripting interface.
Definition: Mat4.h:44
Definition: gpu/src/gpu/Context.h:29
static void init()
Creates graphics-API specific Backend object.
Definition: gpu/src/gpu/Context.h:42
Definition: gpu/src/gpu/Framebuffer.h:27