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#include "Managers/BsGpuProgramManager.h"
4#include "RenderAPI/BsRenderAPI.h"
5
6namespace bs
7{
8 SPtr<GpuProgram> GpuProgramManager::create(const GPU_PROGRAM_DESC& desc)
9 {
10 GpuProgram* program = new (bs_alloc<GpuProgram>()) GpuProgram(desc);
11 SPtr<GpuProgram> ret = bs_core_ptr<GpuProgram>(program);
12 ret->_setThisPtr(ret);
13 ret->initialize();
14
15 return ret;
16 }
17
18 SPtr<GpuProgram> GpuProgramManager::createEmpty(const String& language, GpuProgramType type)
19 {
20 GPU_PROGRAM_DESC desc;
21 desc.language = language;
22 desc.type = type;
23
24 GpuProgram* program = new (bs_alloc<GpuProgram>()) GpuProgram(desc);
25 SPtr<GpuProgram> ret = bs_core_ptr<GpuProgram>(program);
26 ret->_setThisPtr(ret);
27
28 return ret;
29 }
30
31 namespace ct
32 {
33 String sNullLang = "null";
34
35 /** Null GPU program used in place of GPU programs we cannot create. Null programs don't do anything. */
36 class NullProgram final : public GpuProgram
37 {
38 public:
39 NullProgram()
40 :GpuProgram(GPU_PROGRAM_DESC(), GDF_DEFAULT)
41 { }
42
43 ~NullProgram() = default;
44
45 bool isSupported() const override { return false; }
46 };
47
48 SPtr<GpuProgram> NullProgramFactory::create(const GPU_PROGRAM_DESC& desc, GpuDeviceFlags deviceMask)
49 {
50 SPtr<NullProgram> ret = bs_shared_ptr_new<NullProgram>();
51 ret->_setThisPtr(ret);
52
53 return ret;
54 }
55
56 SPtr<GpuProgram> NullProgramFactory::create(GpuProgramType type, GpuDeviceFlags deviceMask)
57 {
58 SPtr<NullProgram> ret = bs_shared_ptr_new<NullProgram>();
59 ret->_setThisPtr(ret);
60
61 return ret;
62 }
63
64 SPtr<GpuProgramBytecode> NullProgramFactory::compileBytecode(const GPU_PROGRAM_DESC& desc)
65 {
66 auto bytecode = bs_shared_ptr_new<GpuProgramBytecode>();
67 bytecode->compilerId = "Null";
68
69 return bytecode;
70 }
71
72 GpuProgramManager::GpuProgramManager()
73 {
74 mNullFactory = bs_new<NullProgramFactory>();
75 addFactory(sNullLang, mNullFactory);
76 }
77
78 GpuProgramManager::~GpuProgramManager()
79 {
80 bs_delete((NullProgramFactory*)mNullFactory);
81 }
82
83 void GpuProgramManager::addFactory(const String& language, GpuProgramFactory* factory)
84 {
85 Lock lock(mMutex);
86
87 mFactories[language] = factory;
88 }
89
90 void GpuProgramManager::removeFactory(const String& language)
91 {
92 Lock lock(mMutex);
93
94 auto iter = mFactories.find(language);
95 if (iter != mFactories.end())
96 mFactories.erase(iter);
97 }
98
99 GpuProgramFactory* GpuProgramManager::getFactory(const String& language)
100 {
101 auto iter = mFactories.find(language);
102 if (iter == mFactories.end())
103 iter = mFactories.find(sNullLang);
104
105 return iter->second;
106 }
107
108 bool GpuProgramManager::isLanguageSupported(const String& lang)
109 {
110 Lock lock(mMutex);
111
112 auto iter = mFactories.find(lang);
113 return iter != mFactories.end();
114 }
115
116 SPtr<GpuProgram> GpuProgramManager::create(const GPU_PROGRAM_DESC& desc, GpuDeviceFlags deviceMask)
117 {
118 SPtr<GpuProgram> ret = createInternal(desc, deviceMask);
119 ret->initialize();
120
121 return ret;
122 }
123
124 SPtr<GpuProgram> GpuProgramManager::createInternal(const GPU_PROGRAM_DESC& desc, GpuDeviceFlags deviceMask)
125 {
126 GpuProgramFactory* factory = getFactory(desc.language);
127 SPtr<GpuProgram> ret = factory->create(desc, deviceMask);
128
129 return ret;
130 }
131
132 SPtr<GpuProgramBytecode> GpuProgramManager::compileBytecode(const GPU_PROGRAM_DESC& desc)
133 {
134 GpuProgramFactory* factory = getFactory(desc.language);
135 return factory->compileBytecode(desc);
136 }
137 }
138}
139