#pragma region CPL License /* Nuclex Native Framework Copyright (C) 2002-2013 Nuclex Development Labs This library is free software; you can redistribute it and/or modify it under the terms of the IBM Common Public License as published by the IBM Corporation; either version 1.0 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the IBM Common Public License for more details. You should have received a copy of the IBM Common Public License along with this library */ #pragma endregion // CPL License #ifndef NUCLEX_GRAPHICS_RASTERIZATION_SHADER_H #define NUCLEX_GRAPHICS_RASTERIZATION_SHADER_H #include "Resource.h" #include "Usage.h" #include "../Helpers/ConcurrentObserverSet.h" #include #include namespace Nuclex { namespace Graphics { namespace Rasterization { // ------------------------------------------------------------------------------------------- // class GenericConstantBuffer; class Texture; // ------------------------------------------------------------------------------------------- // }}} // namespace Nuclex::Graphics::Rasterization namespace Nuclex { namespace Graphics { namespace Introspection { // ------------------------------------------------------------------------------------------- // struct ShaderMetadata; // ------------------------------------------------------------------------------------------- // }}} // namespace Nuclex::Graphics::Introspection namespace Nuclex { namespace Graphics { namespace Rasterization { // ------------------------------------------------------------------------------------------- // ///Contains GPU program instructions class Shader : public Resource { #pragma region class Observer /// Receives notifications from the shader when it changes public: class Observer : public Resource::Observer { /// Frees the resources used by the observer public: virtual ~Observer() {} /// Called right before the shader is destroyed public: virtual void Destroying() = 0; /// Called when a constant buffer has been set /// /// Index of the constant buffer that has been assigned /// /// /// This only indicates when a constant buffer is assigned, not if its contents /// change (for this, the constant buffer itself needs to be observed) /// public: virtual void ConstantBufferChanged(std::size_t constantBufferIndex) = 0; /// Called when a texture has been set /// Index of the texture that has been assigned /// /// This only indicates when a texture is assigned, not if its contents /// change (for this, the texture itself needs to be observed) /// public: virtual void TextureChanged(std::size_t textureIndex) = 0; }; #pragma endregion // class Observer /// Initializes a new shader containing the specified code /// Compiled code that will be run by the GPU /// Length of the code in bytes protected: NUCLEX_GRAPHICS_API Shader( const std::uint8_t *const bytecode, std::size_t length ); /// Creates a copy of an existing shader /// Existing shader that will be copied /// /// The copy will not take over the existing shader's attached observers. /// protected: NUCLEX_GRAPHICS_API Shader(const Shader &other); /// Destroys the shader public: NUCLEX_GRAPHICS_API virtual ~Shader(); /// Informations about the shader /// Metadata describing the shader's inputs and constants public: NUCLEX_GRAPHICS_API const Introspection::ShaderMetadata &Metadata() const { return *this->metadata.get(); } /// Returns the capacity of the buffer in bytes /// The number of bytes that fit in the buffer public: NUCLEX_GRAPHICS_API std::size_t GetProgramLengthInBytes() const { return this->length; } /// Accesses the memory used by the buffer /// The memory storing the buffer contents public: NUCLEX_GRAPHICS_API const std::uint8_t *AccessMemory() const { return this->bytecode; } /// Counts the number of constant buffers that can be bound /// The number of constant buffers that can be bound to the shader public: NUCLEX_GRAPHICS_API std::size_t CountConstantBufferSlots() const; /// Retrieves the constant buffer with the specified slot index /// Index of the constant buffer that will be retrieved /// The constant buffer in the specified slot public: NUCLEX_GRAPHICS_API const std::shared_ptr GetConstantBuffer( std::size_t index ) const; /// Selects the constant buffer for the specified slot index /// Index of the constant buffer that will be selected /// Constant buffer that will be selected public: NUCLEX_GRAPHICS_API void SetConstantBuffer( std::size_t index, const std::shared_ptr &constantBuffer ); /// Counts the number of textures that can be bound /// The number of textures that can be bound to the shader public: NUCLEX_GRAPHICS_API std::size_t CountTextureSlots() const; /// Retrieves the texture with the specified slot index /// Index of the texture that will be retrieved /// The texture in the specified slot public: NUCLEX_GRAPHICS_API const std::shared_ptr GetTexture( std::size_t index ) const; /// Selects the texture for the specified slot index /// Index of the texture that will be selected /// Constant buffer that will be selected public: NUCLEX_GRAPHICS_API void SetTexture( std::size_t index, const std::shared_ptr &texture ); /// Retrieves the observer attached by the specified owner /// Owner whose observer will be looked up /// The observer registered by the specified owner or a nullptr public: NUCLEX_GRAPHICS_API Observer *GetObserver(const void *owner) const; /// Attaches an observer to the shader /// The observer's owner, used as a unique key /// Observer that will be attached to the shader public: NUCLEX_GRAPHICS_API void AttachObserver(const void *owner, Observer *observer); /// Detaches the specified owner's observer from the shader /// Owner whose observer will be detached public: NUCLEX_GRAPHICS_API void DetachObserver(const void *owner); /// Copies the contents of another shader into this shader /// Other shader whose contents will be copied /// A reference to this shader protected: NUCLEX_GRAPHICS_API Shader &operator =(const Shader &other); /// Notifies all observers that the shader is about to be destroyed protected: NUCLEX_GRAPHICS_API void OnDestroying(); /// Notifies all observers that a constant buffer has been assigned /// /// Index of the constant buffer that has been assigned /// protected: NUCLEX_GRAPHICS_API void OnConstantBufferChanged(std::size_t constantBufferIndex); /// Notifies all observers that a texture has been assigned /// Index of the texture that has been assigned protected: NUCLEX_GRAPHICS_API void OnTextureChanged(std::size_t textureIndex); /// The contents of the buffer /// /// The buffer pointer is constant (since a buffer is allocated once and cannot be /// resized or replaced), but the data is not. /// private: std::uint8_t *const bytecode; /// The buffer's capacity in bytes private: const std::size_t length; /// Observers to changes happening to the buffer private: Helpers::ConcurrentObserverSet observers; /// Constant buffers the user has currently selected private: std::unique_ptr[]> constantBuffers; /// Textures the user has currently selected private: std::unique_ptr[]> textures; /// Metadata describing the shader private: std::unique_ptr metadata; }; // ------------------------------------------------------------------------------------------- // }}} // namespace Nuclex::Graphics::Rasterization #endif // NUCLEX_GRAPHICS_RASTERIZATION_SHADER_H