Shader.cpp 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. // Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include <AnKi/Gr/Shader.h>
  6. #include <AnKi/Gr/gl/ShaderImpl.h>
  7. #include <AnKi/Gr/gl/CommandBufferImpl.h>
  8. #include <AnKi/Gr/GrManager.h>
  9. namespace anki {
  10. Shader* Shader::newInstance(GrManager* manager, const ShaderInitInfo& init)
  11. {
  12. class ShaderCreateCommand final : public GlCommand
  13. {
  14. public:
  15. ShaderPtr m_shader;
  16. StringRaii m_source;
  17. DynamicArrayRaii<ShaderSpecializationConstValue> m_constValues;
  18. ShaderCreateCommand(Shader* shader, ConstWeakArray<U8> bin, ConstWeakArray<ShaderSpecializationConstValue> constValues,
  19. const CommandBufferAllocator<U8>& alloc)
  20. : m_shader(shader)
  21. , m_source(alloc)
  22. , m_constValues(alloc)
  23. {
  24. m_source.create(reinterpret_cast<const char*>(&bin[0]));
  25. if(constValues.getSize())
  26. {
  27. m_constValues.create(constValues.getSize());
  28. memcpy(&m_constValues[0], &constValues[0], m_constValues.getByteSize());
  29. }
  30. }
  31. Error operator()(GlState&)
  32. {
  33. ShaderImpl& impl = static_cast<ShaderImpl&>(*m_shader);
  34. Error err = impl.init(m_source.toCString(), m_constValues);
  35. GlObject::State oldState = impl.setStateAtomically((err) ? GlObject::State::ERROR : GlObject::State::CREATED);
  36. ANKI_ASSERT(oldState == GlObject::State::TO_BE_CREATED);
  37. (void)oldState;
  38. return err;
  39. }
  40. };
  41. ANKI_ASSERT(!init.m_binary.isEmpty());
  42. ShaderImpl* impl = manager->getAllocator().newInstance<ShaderImpl>(manager, init.getName());
  43. impl->getRefcount().fetchAdd(1); // Hold a reference in case the command finishes and deletes quickly
  44. // Need to pre-init because some funcs ask for members and we don't want to serialize
  45. impl->preInit(init);
  46. // Copy source to the command buffer
  47. CommandBufferPtr cmdb = manager->newCommandBuffer(CommandBufferInitInfo());
  48. CommandBufferImpl& cmdbimpl = static_cast<CommandBufferImpl&>(*cmdb);
  49. CommandBufferAllocator<U8> alloc = cmdbimpl.getInternalAllocator();
  50. cmdbimpl.pushBackNewCommand<ShaderCreateCommand>(impl, init.m_binary, init.m_constValues, alloc);
  51. cmdbimpl.flush();
  52. return impl;
  53. }
  54. } // end namespace anki