Shader.cpp 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. // Copyright (C) 2009-2021, 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. {
  11. Shader* Shader::newInstance(GrManager* manager, const ShaderInitInfo& init)
  12. {
  13. class ShaderCreateCommand final : public GlCommand
  14. {
  15. public:
  16. ShaderPtr m_shader;
  17. StringAuto m_source;
  18. DynamicArrayAuto<ShaderSpecializationConstValue> m_constValues;
  19. ShaderCreateCommand(Shader* shader, ConstWeakArray<U8> bin,
  20. ConstWeakArray<ShaderSpecializationConstValue> constValues,
  21. const CommandBufferAllocator<U8>& alloc)
  22. : m_shader(shader)
  23. , m_source(alloc)
  24. , m_constValues(alloc)
  25. {
  26. m_source.create(reinterpret_cast<const char*>(&bin[0]));
  27. if(constValues.getSize())
  28. {
  29. m_constValues.create(constValues.getSize());
  30. memcpy(&m_constValues[0], &constValues[0], m_constValues.getByteSize());
  31. }
  32. }
  33. Error operator()(GlState&)
  34. {
  35. ShaderImpl& impl = static_cast<ShaderImpl&>(*m_shader);
  36. Error err = impl.init(m_source.toCString(), m_constValues);
  37. GlObject::State oldState =
  38. impl.setStateAtomically((err) ? GlObject::State::ERROR : GlObject::State::CREATED);
  39. ANKI_ASSERT(oldState == GlObject::State::TO_BE_CREATED);
  40. (void)oldState;
  41. return err;
  42. }
  43. };
  44. ANKI_ASSERT(!init.m_binary.isEmpty());
  45. ShaderImpl* impl = manager->getAllocator().newInstance<ShaderImpl>(manager, init.getName());
  46. impl->getRefcount().fetchAdd(1); // Hold a reference in case the command finishes and deletes quickly
  47. // Need to pre-init because some funcs ask for members and we don't want to serialize
  48. impl->preInit(init);
  49. // Copy source to the command buffer
  50. CommandBufferPtr cmdb = manager->newCommandBuffer(CommandBufferInitInfo());
  51. CommandBufferImpl& cmdbimpl = static_cast<CommandBufferImpl&>(*cmdb);
  52. CommandBufferAllocator<U8> alloc = cmdbimpl.getInternalAllocator();
  53. cmdbimpl.pushBackNewCommand<ShaderCreateCommand>(impl, init.m_binary, init.m_constValues, alloc);
  54. cmdbimpl.flush();
  55. return impl;
  56. }
  57. } // end namespace anki