1 /* 2 * Copyright (C) 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef RENDER_RENDER__NODE_CONTEXT_PSO_MANAGER_H 17 #define RENDER_RENDER__NODE_CONTEXT_PSO_MANAGER_H 18 19 #include <cstddef> 20 #include <cstdint> 21 22 #include <base/containers/unique_ptr.h> 23 #include <base/containers/unordered_map.h> 24 #include <base/containers/vector.h> 25 #include <render/namespace.h> 26 #include <render/nodecontext/intf_node_context_pso_manager.h> 27 #include <render/render_data_structures.h> 28 #include <render/resource_handle.h> 29 30 #include "device/gpu_resource_handle_util.h" 31 #include "device/pipeline_state_object.h" 32 33 RENDER_BEGIN_NAMESPACE() 34 class Device; 35 class ShaderManager; 36 struct PipelineLayout; 37 struct ViewportDesc; 38 struct ScissorDesc; 39 struct LowLevelRenderPassData; 40 struct LowLevelPipelineLayoutData; 41 42 struct ShaderSpecializationConstantDataWrapper { 43 BASE_NS::vector<ShaderSpecialization::Constant> constants; 44 BASE_NS::vector<uint32_t> data; 45 }; 46 struct VertexInputDeclarationDataWrapper { 47 BASE_NS::vector<VertexInputDeclaration::VertexInputBindingDescription> bindingDescriptions; 48 BASE_NS::vector<VertexInputDeclaration::VertexInputAttributeDescription> attributeDescriptions; 49 }; 50 51 /** 52 NodeContextPsoManager implementation. 53 */ 54 class NodeContextPsoManager final : public INodeContextPsoManager { 55 public: 56 NodeContextPsoManager(Device& device, ShaderManager& shaderManager); 57 ~NodeContextPsoManager() = default; 58 59 RenderHandle GetComputePsoHandle(const RenderHandle shader, const RenderHandle pipelineLayout, 60 const ShaderSpecializationConstantDataView& shaderSpecialization) override; 61 RenderHandle GetComputePsoHandle(const RenderHandle shader, const PipelineLayout& pipelineLayout, 62 const ShaderSpecializationConstantDataView& shaderSpecialization) override; 63 64 RenderHandle GetGraphicsPsoHandle(const RenderHandle shader, const RenderHandle graphicsState, 65 const RenderHandle pipelineLayout, const RenderHandle vertexInputDeclaration, 66 const ShaderSpecializationConstantDataView& shaderSpecialization, 67 const DynamicStateFlags dynamicStateFlags) override; 68 RenderHandle GetGraphicsPsoHandle(const RenderHandle shader, const RenderHandle graphicsState, 69 const PipelineLayout& pipelineLayout, const VertexInputDeclarationView& vertexInputDeclarationView, 70 const ShaderSpecializationConstantDataView& shaderSpecialization, 71 const DynamicStateFlags dynamicStateFlags) override; 72 RenderHandle GetGraphicsPsoHandle(const RenderHandle shader, const GraphicsState& graphicsState, 73 const PipelineLayout& pipelineLayout, const VertexInputDeclarationView& vertexInputDeclarationView, 74 const ShaderSpecializationConstantDataView& shaderSpecialization, 75 const DynamicStateFlags dynamicStateFlags) override; 76 77 const ComputePipelineStateObject* GetComputePso( 78 const RenderHandle handle, const LowLevelPipelineLayoutData* pipelineLayoutData); 79 // with GL(ES) psoStateHash is 0 and renderPassData, and pipelineLayoutData are nullptr 80 // with vulkan psoStateHash has renderpass compatibility hash and additional descriptor set hash 81 const GraphicsPipelineStateObject* GetGraphicsPso(const RenderHandle handle, const RenderPassDesc& renderPassDesc, 82 const BASE_NS::array_view<const RenderPassSubpassDesc> renderPassSubpassDescs, const uint32_t subpassIndex, 83 const uint64_t psoStateHash, const LowLevelRenderPassData* renderPassData, 84 const LowLevelPipelineLayoutData* pipelineLayoutData); 85 86 // only used for validation (just copy pipeline layout) 87 #if (RENDER_VALIDATION_ENABLED == 1) 88 const PipelineLayout& GetComputePsoPipelineLayout(const RenderHandle handle) const; 89 const PipelineLayout& GetGraphicsPsoPipelineLayout(const RenderHandle handle) const; 90 #endif 91 92 private: 93 Device& device_; 94 ShaderManager& shaderMgr_; 95 96 // graphics state handle should be invalid if custom graphics state is given 97 RenderHandle GetGraphicsPsoHandleImpl(const RenderHandle shaderHandle, const RenderHandle graphicsStateHandle, 98 const PipelineLayout& pipelineLayout, const VertexInputDeclarationView& vertexInputDeclarationView, 99 const ShaderSpecializationConstantDataView& shaderSpecialization, const DynamicStateFlags dynamicStateFlags, 100 const GraphicsState* graphicsState); 101 102 struct ComputePipelineStateCreationData { 103 RenderHandle shaderHandle; 104 PipelineLayout pipelineLayout; 105 ShaderSpecializationConstantDataWrapper shaderSpecialization; 106 }; 107 struct ComputePipelineStateCache { 108 BASE_NS::vector<ComputePipelineStateCreationData> psoCreationData; 109 BASE_NS::vector<BASE_NS::unique_ptr<ComputePipelineStateObject>> pipelineStateObjects; 110 // hash (shader hash), resource handle 111 BASE_NS::unordered_map<uint64_t, RenderHandle> hashToHandle; 112 113 #if (RENDER_VALIDATION_ENABLED == 1) 114 BASE_NS::unordered_map<RenderHandle, PipelineLayout> handleToPipelineLayout; 115 #endif 116 }; 117 ComputePipelineStateCache computePipelineStateCache_; 118 119 struct GraphicsPipelineStateCreationData { 120 RenderHandle shaderHandle; 121 RenderHandle graphicsStateHandle; 122 PipelineLayout pipelineLayout; 123 DynamicStateFlags dynamicStateFlags { DynamicStateFlagBits::CORE_DYNAMIC_STATE_UNDEFINED }; 124 125 VertexInputDeclarationDataWrapper vertexInputDeclaration; 126 ShaderSpecializationConstantDataWrapper shaderSpecialization; 127 BASE_NS::unique_ptr<GraphicsState> customGraphicsState; 128 }; 129 struct GraphicsPipelineStateCache { 130 BASE_NS::vector<GraphicsPipelineStateCreationData> psoCreationData; 131 // (handle.id (+ vk renderpass compatibility hash) 132 // vulkan needs pso per every render pass configuration (for GL array would be enough, but we use 133 // renderhandle.id) 134 BASE_NS::unordered_map<uint64_t, BASE_NS::unique_ptr<GraphicsPipelineStateObject>> pipelineStateObjects; 135 // hash (shader hash), resource handle 136 BASE_NS::unordered_map<uint64_t, RenderHandle> hashToHandle; 137 138 #if (RENDER_VALIDATION_ENABLED == 1) 139 BASE_NS::unordered_map<RenderHandle, PipelineLayout> handleToPipelineLayout; 140 #endif 141 }; 142 GraphicsPipelineStateCache graphicsPipelineStateCache_; 143 }; 144 RENDER_END_NAMESPACE() 145 146 #endif // CORE__RENDER__NODE_CONTEXT_PSO_MANAGER_H 147