1//************************************ bs::framework - Copyright 2018 Marko Pintera **************************************//
2//*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********//
3#pragma once
4
5#include "BsCorePrerequisites.h"
6#include "CoreThread/BsCoreObject.h"
7#include "Allocators/BsGroupAlloc.h"
8
9namespace bs
10{
11 /** @addtogroup RenderAPI-Internal
12 * @{
13 */
14
15 /** Helper structure used for initializing GpuPipelineParamInfo. */
16 struct GPU_PIPELINE_PARAMS_DESC
17 {
18 SPtr<GpuParamDesc> fragmentParams;
19 SPtr<GpuParamDesc> vertexParams;
20 SPtr<GpuParamDesc> geometryParams;
21 SPtr<GpuParamDesc> hullParams;
22 SPtr<GpuParamDesc> domainParams;
23 SPtr<GpuParamDesc> computeParams;
24 };
25
26 /** Binding location for a single GPU program parameter. */
27 struct GpuParamBinding
28 {
29 UINT32 set = (UINT32)-1;
30 UINT32 slot = (UINT32)-1;
31 };
32
33 /** Contains code common to both sim and core thread implementations of GpuPipelineParamInfo. */
34 class BS_CORE_EXPORT GpuPipelineParamInfoBase
35 {
36 public:
37 /** Types of GPU parameters. */
38 enum class ParamType
39 {
40 ParamBlock, Texture, LoadStoreTexture, Buffer, SamplerState, Count
41 };
42
43 /** Constructs the object using the provided GPU parameter descriptors. */
44 GpuPipelineParamInfoBase(const GPU_PIPELINE_PARAMS_DESC& desc);
45 virtual ~GpuPipelineParamInfoBase() = default;
46
47 /** Gets the total number of sets. */
48 UINT32 getNumSets() const { return mNumSets; }
49
50 /** Returns the total number of elements across all sets. */
51 UINT32 getNumElements() const { return mNumElements; }
52
53 /** Returns the number of elements in all sets for the specified parameter type. */
54 UINT32 getNumElements(ParamType type) { return mNumElementsPerType[(int)type]; }
55
56 /**
57 * Converts a set/slot combination into a sequential index that maps to the parameter in that parameter type's
58 * array.
59 *
60 * If the set or slot is out of valid range, the method logs an error and returns -1. Only performs range checking
61 * in debug mode.
62 */
63 UINT32 getSequentialSlot(ParamType type, UINT32 set, UINT32 slot) const;
64
65 /** Converts a sequential slot index into a set/slot combination. */
66 void getBinding(ParamType type, UINT32 sequentialSlot, UINT32& set, UINT32& slot) const;
67
68 /**
69 * Finds set/slot indices of a parameter with the specified name for the specified GPU program stage. Set/slot
70 * indices are set to -1 if a stage doesn't have a block with the specified name.
71 */
72 void getBinding(GpuProgramType progType, ParamType type, const String& name, GpuParamBinding &binding);
73
74 /**
75 * Finds set/slot indices of a parameter with the specified name for every GPU program stage. Set/slot indices are
76 * set to -1 if a stage doesn't have a block with the specified name.
77 */
78 void getBindings(ParamType type, const String& name, GpuParamBinding(&bindings)[GPT_COUNT]);
79
80 /** Returns descriptions of individual parameters for the specified GPU program type. */
81 const SPtr<GpuParamDesc>& getParamDesc(GpuProgramType type) const { return mParamDescs[(int)type]; }
82
83 protected:
84 /** Information about a single set in the param info object. */
85 struct SetInfo
86 {
87 UINT32* slotIndices;
88 ParamType* slotTypes;
89 UINT32* slotSamplers;
90 UINT32 numSlots;
91 };
92
93 /** Information how a resource maps to a certain set/slot. */
94 struct ResourceInfo
95 {
96 UINT32 set;
97 UINT32 slot;
98 };
99
100 std::array<SPtr<GpuParamDesc>, 6> mParamDescs;
101
102 UINT32 mNumSets;
103 UINT32 mNumElements;
104 SetInfo* mSetInfos;
105 UINT32 mNumElementsPerType[(int)ParamType::Count];
106 ResourceInfo* mResourceInfos[(int)ParamType::Count];
107
108 GroupAlloc mAlloc;
109 };
110
111 /** Holds meta-data about a set of GPU parameters used by a single pipeline state. */
112 class BS_CORE_EXPORT GpuPipelineParamInfo : public CoreObject, public GpuPipelineParamInfoBase
113 {
114 public:
115 virtual ~GpuPipelineParamInfo() = default;
116
117 /**
118 * Retrieves a core implementation of this object usable only from the core thread.
119 *
120 * @note Core thread only.
121 */
122 SPtr<ct::GpuPipelineParamInfo> getCore() const;
123
124 /**
125 * Constructs the object using the provided GPU parameter descriptors.
126 *
127 * @param[in] desc Object containing parameter descriptions for individual GPU program stages.
128 */
129 static SPtr<GpuPipelineParamInfo> create(const GPU_PIPELINE_PARAMS_DESC& desc);
130
131 private:
132 GpuPipelineParamInfo(const GPU_PIPELINE_PARAMS_DESC& desc);
133
134 /** @copydoc CoreObject::createCore */
135 SPtr<ct::CoreObject> createCore() const override;
136 };
137
138 namespace ct
139 {
140 /** Core thread version of a bs::GpuPipelineParamInfo. */
141 class BS_CORE_EXPORT GpuPipelineParamInfo : public CoreObject, public GpuPipelineParamInfoBase
142 {
143 public:
144 virtual ~GpuPipelineParamInfo() = default;
145
146 /**
147 * @copydoc bs::GpuPipelineParamInfo::create
148 * @param[in] deviceMask Mask that determines on which GPU devices should the buffer be created on.
149 */
150 static SPtr<GpuPipelineParamInfo> create(const GPU_PIPELINE_PARAMS_DESC& desc,
151 GpuDeviceFlags deviceMask = GDF_DEFAULT);
152
153 protected:
154 friend class RenderStateManager;
155
156 GpuPipelineParamInfo(const GPU_PIPELINE_PARAMS_DESC& desc, GpuDeviceFlags deviceMask);
157 };
158 }
159
160 /** @} */
161}