1#include "EffectsCommon.h"
2#include "DefaultIOHandler.h"
5#include "../IBuffers.h"
7#include "Foundation/Logging/Logger.h"
14#ifdef COGSRENDERING_GFX_ANNOTATE
18 size_t last = filename.
length();
21 if (t != std::string::npos) {
26 if (t != std::string::npos) {
31 return filename.
substr(first, last - first);
39void Cogs::EffectsCommon::initialize(IBuffers * buffers)
42 defaultHandler = std::make_unique<DefaultIOHandler>();
43 handler = defaultHandler.get();
46 LOG_DEBUG(logger,
"Custom IOHandler set.");
48 this->buffers = buffers;
60 Utilities::readFile(handler, description.
effect, contents.effect);
62 if (!Utilities::readFile(handler, description.
vertexShader, contents.vertexShader)) {
63 LOG_WARNING(logger,
"Failed to read vertex shader %s.", std::string(description.
vertexShader).c_str());
66 if(!contents.vertexShader.content.size()) {
67 LOG_WARNING(logger,
"Vertex shader %s is empty.", std::string(description.
vertexShader).c_str());
72 Utilities::readFile(handler, description.
geometryShader, contents.geometryShader);
76 Utilities::readFile(handler, description.
pixelShader, contents.pixelShader);
80 Utilities::readFile(handler, description.
hullShader, contents.hullShader);
84 Utilities::readFile(handler, description.
domainShader, contents.domainShader);
88 return loadEffectContents(sourceDescription, contents);
90 return loadEffectSource(description);
101 Utilities::preprocessContent(handler, description.
effect, contents.effect);
103 Utilities::preprocessContent(handler, description.
vertexShader, contents.vertexShader);
106 Utilities::preprocessContent(handler, description.
geometryShader, contents.geometryShader);
110 Utilities::preprocessContent(handler, description.
hullShader, contents.hullShader);
114 Utilities::preprocessContent(handler, description.
domainShader, contents.domainShader);
117 Utilities::preprocessContent(handler, description.
pixelShader, contents.pixelShader);
120 return loadEffectContents(description, contents);
123Cogs::EffectHandle Cogs::EffectsCommon::loadEffectContents(
const EffectDescription & description,
const EffectContents & contents)
125 if (contents.effect.content.size()) {
126 return load(contents.effect,
129 description.vsEntryPoint.size() ? description.vsEntryPoint.data() :
"VShader",
130 description.gsEntryPoint.size() ? description.gsEntryPoint.data() :
"GShader",
131 description.psEntryPoint.size() ? description.psEntryPoint.data() :
"PShader",
134 return load(contents.vertexShader,
136 contents.domainShader,
137 contents.geometryShader,
138 contents.pixelShader,
139 description.vsEntryPoint.size() ? description.vsEntryPoint.data() :
"main",
140 description.hsEntryPoint.size() ? description.hsEntryPoint.data() :
"main",
141 description.dsEntryPoint.size() ? description.dsEntryPoint.data() :
"main",
142 description.gsEntryPoint.size() ? description.gsEntryPoint.data() :
"main",
143 description.psEntryPoint.size() ? description.psEntryPoint.data() :
"main",
152#ifdef COGSRENDERING_GFX_ANNOTATE
153 annotate(e, tryToName(fileName));
163#ifdef COGSRENDERING_GFX_ANNOTATE
164 annotateVS(e, tryToName(vsFileName));
165 annotatePS(e, tryToName(psFileName));
174 desc.vertexShader = vsFileName;
175 desc.pixelShader = psFileName;
176 desc.definitions = defines;
177 desc.flags = effectFlags;
180 auto e = loadEffect(desc);
182#ifdef COGSRENDERING_GFX_ANNOTATE
183 annotateVS(e, tryToName(vsFileName));
184 annotatePS(e, tryToName(psFileName));
198 desc.vertexShader = vsSource;
199 desc.pixelShader = psSource;
200 desc.definitions = defines;
204 return loadEffectSource(desc);
215 desc.vertexShader = vsSource;
216 desc.geometryShader = gsSource;
217 desc.pixelShader = psSource;
218 desc.definitions = defines;
222 return loadEffectSource(desc);
228 desc.effect = fileName;
229 desc.definitions = defines;
233 auto e = loadEffect(desc);
239 const ProcessedContent & psSource,
240 const StringView & vsEntryPoint,
241 const StringView & psEntryPoint,
242 const EffectDescription & desc)
244 return load(vsSource, ProcessedContent(), psSource, vsEntryPoint,
nullptr, psEntryPoint, desc);
248 const ProcessedContent & gsSource,
249 const ProcessedContent & psSource,
250 const StringView & vsEntryPoint,
251 const StringView & gsEntryPoint,
252 const StringView & psEntryPoint,
253 const EffectDescription & desc)
255 return load(vsSource,
270 template<
typename Collection>
271 uint8_t getSlot(Collection & collection,
const StringView & name)
275 if (it == collection.end())
return Cogs::NoBinding;
277 return (uint8_t)it->second;
280 uint64_t encode(uint8_t vsSlot, uint8_t hsSlot, uint8_t dsSlot, uint8_t gsSlot, uint8_t psSlot)
282 if ((vsSlot == NoBinding) &&
283 (hsSlot == NoBinding) &&
284 (dsSlot == NoBinding) &&
285 (gsSlot == NoBinding) &&
286 (psSlot == NoBinding))
291 return ((
static_cast<uint64_t
>(vsSlot) << 0) |
292 (
static_cast<uint64_t
>(hsSlot) << 8) |
293 (
static_cast<uint64_t
>(dsSlot) << 16) |
294 (
static_cast<uint64_t
>(gsSlot) << 24) |
295 (
static_cast<uint64_t
>(psSlot) << 32) |
296 (
static_cast<uint64_t
>(1) << 63));
300 uint64_t encode(uint8_t csSlot)
302 return encode(csSlot, NoBinding, NoBinding, NoBinding, NoBinding);
305 template<
typename Effect>
306 uint64_t getSlots(Effect & effect,
const StringView & name)
308 const uint8_t vsSlot = getSlot(effect.vertexShader.reflection.slots, name);
309 const uint8_t hsSlot = getSlot(effect.hullShader.reflection.slots, name);
310 const uint8_t dsSlot = getSlot(effect.domainShader.reflection.slots, name);
311 const uint8_t gsSlot = getSlot(effect.geometryShader.reflection.slots, name);
312 const uint8_t psSlot = getSlot(effect.pixelShader.reflection.slots, name);
314 return encode(vsSlot, hsSlot, dsSlot, gsSlot, psSlot);
317 template<
typename Effect>
318 int64_t getTextureSlots(Effect & effect,
const StringView & name)
320 const uint8_t vsSlot = getSlot(effect.vertexShader.reflection.textures, name);
321 const uint8_t hsSlot = getSlot(effect.hullShader.reflection.textures, name);
322 const uint8_t dsSlot = getSlot(effect.domainShader.reflection.textures, name);
323 const uint8_t gsSlot = getSlot(effect.geometryShader.reflection.textures, name);
324 const uint8_t psSlot = getSlot(effect.pixelShader.reflection.textures, name);
326 return encode(vsSlot, hsSlot, dsSlot, gsSlot, psSlot);
329 template<
typename Effect>
330 int64_t getSamplerSlots(Effect & effect,
const StringView & name)
332 const uint8_t vsSlot = getSlot(effect.vertexShader.reflection.samplers, name);
333 const uint8_t hsSlot = getSlot(effect.hullShader.reflection.samplers, name);
334 const uint8_t dsSlot = getSlot(effect.domainShader.reflection.samplers, name);
335 const uint8_t gsSlot = getSlot(effect.geometryShader.reflection.samplers, name);
336 const uint8_t psSlot = getSlot(effect.pixelShader.reflection.samplers, name);
338 return encode(vsSlot, hsSlot, dsSlot, gsSlot, psSlot);
341 template<
typename Effect>
342 int64_t getBufferUAVSlots(Effect & effect,
const StringView & name)
344 const uint8_t vsSlot = getSlot(effect.vertexShader.reflection.bufferUAVs, name);
345 const uint8_t hsSlot = getSlot(effect.hullShader.reflection.bufferUAVs, name);
346 const uint8_t dsSlot = getSlot(effect.domainShader.reflection.bufferUAVs, name);
347 const uint8_t gsSlot = getSlot(effect.geometryShader.reflection.bufferUAVs, name);
348 const uint8_t psSlot = getSlot(effect.pixelShader.reflection.bufferUAVs, name);
350 return encode(vsSlot, hsSlot, dsSlot, gsSlot, psSlot);
353 template<
typename Effect>
354 int64_t getBufferSRVSlots(Effect & effect,
const StringView & name)
356 const uint8_t vsSlot = getSlot(effect.vertexShader.reflection.bufferSRVs, name);
357 const uint8_t hsSlot = getSlot(effect.hullShader.reflection.bufferSRVs, name);
358 const uint8_t dsSlot = getSlot(effect.domainShader.reflection.bufferSRVs, name);
359 const uint8_t gsSlot = getSlot(effect.geometryShader.reflection.bufferSRVs, name);
360 const uint8_t psSlot = getSlot(effect.pixelShader.reflection.bufferSRVs, name);
362 return encode(vsSlot, hsSlot, dsSlot, gsSlot, psSlot);
371 auto & effect = effects[effectHandle];
373 auto existingEffectVariable = effect.effectVariables.find(
id);
375 if (existingEffectVariable != effect.effectVariables.end()) {
382 auto cbVariable = constantBuffer.variables.find(
id);
384 if (!HandleIsValid(constantBuffer.buffer)) {
385 constantBuffer.memoryBuffer.resize(constantBuffer.size);
389 if (cbVariable != constantBuffer.variables.end()) {
391 variable.buffer = &constantBuffer;
392 variable.offset = constantBuffer.offsets[cbVariable->second];
393 variable.size = constantBuffer.sizes[cbVariable->second];
395 effectVariable.variables.push_back(variable);
399 for (
auto & shader : effect.shaders) {
400 for (
auto & constantBuffer : shader.reflection.constantBuffers) {
401 addEffectVariable(constantBuffer);
405 auto variablePointer = &(effect.effectVariables[id] = effectVariable);
412 auto & effect = effects[effectHandle];
414 if (effect.computeShader.shader) {
423 auto & effect = this->effects[effectHandle];
425 if (effect.computeShader.shader) {
434 auto & effect = this->effects[effectHandle];
436 if (effect.computeShader.shader) {
445 auto & effect = this->effects[effectHandle];
447 if (effect.computeShader.shader) {
448 BufferBinding binding = { getSlot(effect.computeShader.reflection.bufferUAVs, name), getSlot(effect.computeShader.reflection.bufferSRVs, name) };
450 return bufferBindings.addResource(std::move(binding));
452 BufferBinding binding = { getBufferUAVSlots(effect, name), getBufferSRVSlots(effect, name) };
454 return bufferBindings.addResource(std::move(binding));
460 bufferBindings.removeResource(bufferBindingHandle);
463void Cogs::Effect::buildSignature()
467 for (
size_t i = 0; i < ShaderType::NumShaderTypes; ++i) {
468 auto & shader = shaders[i];
470 signature.slots[SlotType::CBV].values[i] =
static_cast<uint32_t
>(shader.reflection.slots.size());
471 signature.slots[SlotType::SRV].values[i] = shader.reflection.srvSlots;
472 signature.slots[SlotType::Sampler].values[i] =
static_cast<uint32_t
>(shader.reflection.samplers.size());
473 signature.slots[SlotType::UAV].values[i] =
static_cast<uint32_t
>(shader.reflection.bufferUAVs.size());
476 const uint32_t numUAVSlotsReservedForRT = 1;
477 signature.slots[SlotType::UAV].values[ShaderType::PixelShader] += numUAVSlotsReservedForRT;
480 for (
size_t i = 0; i < SlotType::NumSlotTypes; ++i) {
481 for (
size_t j = 0; j < ShaderType::NumShaderTypes; ++j) {
482 if (signature.slots[i].values[j]) {
483 signature.slots[i].rangeIndex[j] = range++;
Log implementation class.
Provides a weakly referenced view over the contents of a string.
size_t find_last_of(const StringView characters, size_t pos=NoPosition) const noexcept
See std::basic_string::find_last_of.
constexpr size_t size() const noexcept
Get the size of the string.
constexpr size_t length() const noexcept
Get the length of the string.
constexpr StringView substr(size_t offset, size_t count=NoPosition) const noexcept
Get the given sub string.
constexpr Log getLogger(const char(&name)[LEN]) noexcept
Contains all Cogs related functionality.
constexpr size_t hash() noexcept
Simple getter function that returns the initial value for fnv1a hashing.
std::vector< PreprocessorDefinition > PreprocessorDefinitions
A set of preprocessor definitions.
@ Write
The buffer can be mapped and written to by the CPU after creation.
@ ConstantBuffer
The buffer can be bound as input to effects as a constant buffer.
Contains an effect description used to load a single effect.
StringView geometryShader
Geometry shader file name or source.
StringView effect
Effect file name or source.
StringView domainShader
Domain shader file name or source.
StringView vertexShader
Vertex shader file name or source.
EffectDescriptionType type
Type of effect description. Defaults to file names.
StringView pixelShader
Pixel shader file name or source.
StringView hullShader
Hull shader file name or source.
EEffectFlags
Effect source flags.
@ GeometryShader
Effect source contains geometry shader.
ConstantBufferBindingHandle getConstantBufferBinding(EffectHandle effectHandle, const StringView &name) override
Get a handle to a constant buffer binding, mapping how to bind a constant buffer to the given effect.
BufferBindingHandle getBufferBinding(EffectHandle effectHandle, const StringView &name) override
Get a handle to a buffer binding.
SamplerStateBindingHandle getSamplerStateBinding(EffectHandle effectHandle, const StringView &name, const unsigned int slot) override
Get a handle to a sampler state object binding, mapping how to bind the sampler state to the given ef...
void releaseBufferBinding(BufferBindingHandle bufferBindingHandle) override
Release a handle to a buffer binding.
EffectVariableHandle getEffectVariable(EffectHandle effectHandle, const StringView &name) override
Get a handle to the variable with the given name in the effect with the given effectHandle.
TextureBindingHandle getTextureBinding(EffectHandle effectHandle, const StringView &name, const unsigned int slot) override
Get a handle to a texture object binding, mapping how to bind textures to the given effect.
EffectHandle loadEffect(const EffectDescription &description) final
Load an effect from the given description.
static const Handle_t InvalidHandle
Represents an invalid handle.
@ Dynamic
Buffer will be loaded and modified with some frequency.