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 "Utility/BsModule.h"
7#include "Error/BsException.h"
8#include "RenderAPI/BsGpuProgram.h"
9
10namespace bs
11{
12 /** @addtogroup RenderAPI-Internal
13 * @{
14 */
15
16 /**
17 * Manager responsible for creating GPU programs. It will automatically try to find the appropriate handler for a
18 * specific GPU program language and create the program if possible.
19 *
20 * @note Sim thread only.
21 */
22 class BS_CORE_EXPORT GpuProgramManager : public Module<GpuProgramManager>
23 {
24 public:
25 /** @copydoc GpuProgram::create */
26 SPtr<GpuProgram> create(const GPU_PROGRAM_DESC& desc);
27
28 /**
29 * Creates a completely empty and uninitialized GpuProgram. Should only be used for specific purposes, like
30 * deserialization, as it requires additional manual initialization that is not required normally.
31 */
32 SPtr<GpuProgram> createEmpty(const String& language, GpuProgramType type);
33 };
34
35 namespace ct
36 {
37 /** Factory responsible for creating GPU programs of a certain type. */
38 class BS_CORE_EXPORT GpuProgramFactory
39 {
40 public:
41 GpuProgramFactory() = default;
42 virtual ~GpuProgramFactory() = default;
43
44 /** @copydoc GpuProgram::create */
45 virtual SPtr<GpuProgram> create(const GPU_PROGRAM_DESC& desc, GpuDeviceFlags deviceMask = GDF_DEFAULT) = 0;
46
47 /** @copydoc bs::GpuProgramManager::createEmpty */
48 virtual SPtr<GpuProgram> create(GpuProgramType type, GpuDeviceFlags deviceMask = GDF_DEFAULT) = 0;
49
50 /** @copydoc GpuProgram::compileBytecode */
51 virtual SPtr<GpuProgramBytecode> compileBytecode(const GPU_PROGRAM_DESC& desc) = 0;
52 };
53
54 /**
55 * Manager responsible for creating GPU programs. It will automatically try to find the appropriate handler for a
56 * specific GPU program language and create the program if possible.
57 *
58 * @note Core thread only unless otherwise specified.
59 */
60 class BS_CORE_EXPORT GpuProgramManager : public Module<GpuProgramManager>
61 {
62 public:
63 GpuProgramManager();
64 virtual ~GpuProgramManager();
65
66 /**
67 * Registers a new factory that is able to create GPU programs for a certain language. If any other factory for the
68 * same language exists, it will overwrite it.
69 */
70 void addFactory(const String& language, GpuProgramFactory* factory);
71
72 /**
73 * Unregisters a GPU program factory, essentially making it not possible to create GPU programs using the language
74 * the factory supported.
75 */
76 void removeFactory(const String& language);
77
78 /** Query if a GPU program language is supported (for example "hlsl", "glsl"). Thread safe. */
79 bool isLanguageSupported(const String& language);
80
81 /** @copydoc GpuProgram::create */
82 SPtr<GpuProgram> create(const GPU_PROGRAM_DESC& desc, GpuDeviceFlags deviceMask = GDF_DEFAULT);
83
84 /** @copydoc GpuProgram::compileBytecode */
85 SPtr<GpuProgramBytecode> compileBytecode(const GPU_PROGRAM_DESC& desc);
86
87 protected:
88 friend class bs::GpuProgram;
89
90 /**
91 * Creates a GPU program without initializing it.
92 *
93 * @see create
94 */
95 SPtr<GpuProgram> createInternal(const GPU_PROGRAM_DESC& desc, GpuDeviceFlags deviceMask = GDF_DEFAULT);
96
97 /** Attempts to find a factory for the specified language. Returns null if it cannot find one. */
98 GpuProgramFactory* getFactory(const String& language);
99
100 protected:
101 Mutex mMutex;
102
103 UnorderedMap<String, GpuProgramFactory*> mFactories;
104 GpuProgramFactory* mNullFactory; /**< Factory for dealing with GPU programs that can't be created. */
105 };
106
107 /** Factory that creates null GPU programs. */
108 class BS_CORE_EXPORT NullProgramFactory : public GpuProgramFactory
109 {
110 public:
111 NullProgramFactory() = default;
112 ~NullProgramFactory() = default;
113
114 SPtr<GpuProgram> create(const GPU_PROGRAM_DESC& desc, GpuDeviceFlags deviceMask) override;
115 SPtr<GpuProgram> create(GpuProgramType type, GpuDeviceFlags deviceMask) override;
116 SPtr<GpuProgramBytecode> compileBytecode(const GPU_PROGRAM_DESC& desc) override;
117 };
118 }
119 /** @} */
120}