// // ================================================================== // Copyright 2014 Autodesk, Inc. All rights reserved. // // This computer source code and related instructions and comments are // the unpublished confidential and proprietary information of Autodesk, // Inc. and are protected under applicable copyright and trade secret // law. They may not be disclosed to, copied or used by any third party // without the prior written consent of Autodesk, Inc. // ================================================================== // //! \file synColor/GPUAdaptor.h //! //! \brief GPU adaptor abstraction layer definition and smart pointer definition. //! See the SYNCOLOR::GPUAdaptor description for the usage pattern. //! #ifndef _SYNCOLOR_GPU_ADAPTOR_H #define _SYNCOLOR_GPU_ADAPTOR_H #include #include #include #include #include SYN_VISIBILITY_PUSH namespace SYNCOLOR { class GPUAdaptorPtr; //------------------------------------------------------------------------------------------------ // //! //! When finalizing a color transform for rendering, SynColor can create a GPU renderer for the //! the transform. When this is requested, a GPU shader program that implements the color transform //! rendering is built. The shader can be applied to the active graphics frame buffer via the //! SYNCOLOR::Transform::applyGPU call. //! //! To achieve this SynColor requires a GPU adaptor at transform finalization. GPU adaptors //! for OpenGL using the GLSL or the Cg shader languages are available and a GPU adaptor for DirectX 11 //! using HLSL is in the works. If it is necessary to use a different graphics toolkit or if the //! adaptor behavior is not adequate for the intended application then a custom GPU adaptor needs //! to be written. The following information explains the calling sequence of adaptor methods. //! See each method description for details about their intent. //! //! __GPU adaptor method call sequence:__ //! //! Setup phase methods: //! //! begin() // Perform any required set-up. //! releaseProgram() // Clear any GPU resources held by the adaptor. //! acquireInputTexture() // Obtain any input texture related resources. //! getInputTextureName() // Obtain the string corresponding to the input texture resource name. //! //! For each color operator in the transform any of these methods could be called: //! //! getResourceNamePrefix() // Obtain a prefix to use for all GPU resources. //! getTextureDimensions() // Calculate the width and height of a texture to hold the given texture size. //! acquireUniform() // Create and store a uniform variable of the specified type. See UniformType. //! acquire1DTexture() // Create and store a linear texture. //! acquire2DTexture() // Create and store a planar texture. //! acquire3DTexture() // Create and store a volumetric texture. //! //! GPU shader program finalization methods: //! //! acquireProgram() // Create and store a GPU program handle. //! buildProgram() // Compile and link the shader program. //! end() // Perform any specific clean up. //! //! Method used when calling SYNCOLOR::Transform::applyGPU(): //! //! drawQuad() // Render into the currently active destination render buffer. //! //! All GPU adaptor methods are required to return a SYNCOLOR::SynStatus. An error code //! other that SYNCOLOR::ERROR_NONE will cause the SYNCOLOR::finalize or SYNCOLOR::Transform::applyGPU //! calls to abort and return the error as well. A special error code is reserved for GPU //! adaptor errors. If the GPU adaptor method encounters an error, the SYNCOLOR::SynStatus //! usage pattern should be as follows: //! //! SYNCOLOR::SynStatus status; // Initialized to SYNCOLOR::ERROR_NONE. //! ... //! if() { //! status.setErrorCode(SYNCOLOR::ERROR_RENDERER_GPU_ADAPTOR_ERROR); //! status.setErrorMessage(); //! } //! //! return status; //! //! On the application side, the error message can be retrieved by calling SYNCOLOR::SynStatus::getErrorMessage(). //! class SYN_EXPORT GPUAdaptor { public: //---------------------------------------------------------------------------------------------- //! List of supported shader languages. //! enum ShaderLanguage { LANGUAGE_GLSL = 0, //!< GLSL LANGUAGE_CG, //!< Cg LANGUAGE_HLSL, //!< HLSL LANGUAGE_GLSL_CORE //!< GLSL Core profile }; //---------------------------------------------------------------------------------------------- //! List of supported GPU pipelines. //! enum PipelineType { PIPELINE_RGBA_FLOAT = 0 //!< Only floating point RGBA GPU pipelines are supported. }; //---------------------------------------------------------------------------------------------- //! List of supported uniform types. //! enum UniformType { UNIFORM_DOUBLE = 0,//!< Double. UNIFORM_BOOL //!< Boolean. }; //---------------------------------------------------------------------------------------------- public: //! \brief Constructor. //! //! \param lang Adaptor shader language. //! \param pipeline Adaptor GPU pipeline type. //! GPUAdaptor(ShaderLanguage lang, PipelineType pipeline); //! \brief Destructor. //! virtual ~GPUAdaptor(); //! \brief Adaptor unique ID //! //! This function is used as a key in the SynColor caching system. Each GPU adaptor //! instance should return a different ID. //! //! \return virtual const char* getUniqueId() const = 0; //! \brief Clone the GPU Adaptor. //! //! This method needs to return a copy of 'this' GPUAdaptor. //! //! \return Cloned instance. virtual GPUAdaptorPtr clone() const = 0; //! \brief Perform any GPU toolkit specific set-up for creating shader programs. //! //! This method is always called before any other adaptor method when finalizing a color transform. //! The default implementation simply returns without error. //! //! \param uid Transform unique id. See Transfor::getUniqueId(). //! //! \return Must return a SYNCOLOR::SynStatus. See the GPUAdaptor class description for details. //! virtual SynStatus begin(const char* uid); //! \brief Perform any GPU toolkit specific cleanup following shader program creation. //! //! This method is the last one called when finalizing a transform. It is always called when //! an adaptor method returns an error. The default implementation simply returns without error. //! //! \return Must return a SYNCOLOR::SynStatus. See the GPUAdaptor class description for //! details. //! virtual SynStatus end(); //! \brief Prefix for uniquely identifying resources names. //! //! Some applications may require that textures, uniforms, and helper methods be uniquely //! named. If this is the case the implementation of this method needs to return a prefix //! unique to the GPUAdaptor instance. //! //! A unique prefix would be necessary for example if the shader code from multiple color //! transform need to be integrated into a larger shader program. In this case the resources //! need to be uniquely identified. //! //! \return Resource name prefix unique to the GPUAdaptor instance. //! virtual const char* getResourcesNamesPrefix() const = 0; //! \brief Create and store a GPU program handle. //! //! In the OpenGL model, this method corresponds to a call to glCreateProgram(). //! //! \return Must return a SYNCOLOR::SynStatus. See the GPUAdaptor class description for //! details. virtual SynStatus acquireProgram() = 0; //! \brief Clear any GPU resources held by the adaptor. //! //! The intent of this method is to release any textures and uniforms created by the adaptor //! instance. It also needs to delete the shader program. //! //! \return Must return a SYNCOLOR::SynStatus. See the GPUAdaptor class description for //! details. //! virtual SynStatus releaseProgram() = 0; //! \brief Build a shader program and finalize its associated resources. //! //! This method receives the shader program text pieces for compilation or integration //! into another shader program. The pieces provided are the variable and resource //! declarations, the helper methods, and the color transform shader program header, body, //! and footer. //! //! An OpenGL implementation of this methods that produces a single shader program to render //! the color transform would for example concatenate the shader text pieces and build the //! shader program via glCompileShader() and glLinkProgram(). //! //! \param shaderDeclarations Variable and resource declaration text. //! \param shaderHelperMethods Helper function definitions text. //! \param shaderMainHeader Color transform shader header text. //! \param shaderMainBody Color transform shader body text. //! \param shaderMainFooter Color transform shader text footer. //! //! \return Must return a SYNCOLOR::SynStatus. See the GPUAdaptor class description for //! details. virtual SynStatus buildProgram(const char* shaderDeclarations, const char* shaderHelperMethods, const char* shaderMainHeader, const char* shaderMainBody, const char* shaderMainFooter) = 0; //! \brief Create a uniform variable of the specified type. //! //! Uniforms in color transforms correspond to dynamic properties of the transforms such as //! exposure or contrast. Changes to the values of these properties need to be updated prior //! to rendering the transform. The GPU adaptor needs to retain the memory location of the //! uniform value and apply its content to the uniform in the drawQuad() method. Dynamic property //! values are updated via the SYNCOLOR::Transform::setDynamicProperty call. //! //! //! \param id Dynamic property id for this uniform. See DynamicProperty::Ids. //! \param name Uniform name. //! \param type Uniform type //! \param value Memory location of the uniform value. Corresponds to a pointer of the uniform type. //! //! \sa UniformType, drawQuad(). //! //! \return Must return a SYNCOLOR::SynStatus. See the GPUAdaptor class description for //! details. //! virtual SynStatus acquireUniform(DynamicProperty::Ids id, const char* name, UniformType type, const void* value) = 0; //! \brief Calculate the width and height of a texture to hold the given texture size. //! //! When deciding whether to use a 1-d or 2-d texture to hold a look-up table, SynColor needs //! a hint. The implementation of this method needs to provide, based on the GPU toolkit or //! GPU device constraints, the width and height of a texture that will hold the specified //! number of values. //! //! If the height returned is 1, SynColor will request a 1-d texture via the acquire1DTexture() //! adaptor method. Otherwise, acquire2DTexture() will be called to create a 2-d texture. //! //! \param numValues Number of values that the texture needs to hold. //! \param width Texture width return value. //! \param height Texture height return value. //! //! \return Must return a SYNCOLOR::SynStatus. See the GPUAdaptor class description for //! details. //! virtual SynStatus getTextureDimensions(unsigned numValues, unsigned& width, unsigned& height) = 0; //! \brief Create and store a linear texture. //! //! The GPU adaptor needs to retain the handle to the texture and release it in the releaseProgram() call. //! //! \param name Texture name. //! \param values Values to copied into the texture. //! \param size Number of texture values. // //! \return Must return a SYNCOLOR::SynStatus. See the GPUAdaptor class description for //! details. //! virtual SynStatus acquire1DTexture(const char* name, const void* values, unsigned size) = 0; //! \brief Create and store a planar texture. //! //! The GPU adaptor needs to retain the handle to the texture and release it in the releaseProgram() call. //! //! \param name Texture name. //! \param width Texture width. //! \param height Texture height. //! \param values Values to be copied into the texture. // //! \return Must return a SYNCOLOR::SynStatus. See the GPUAdaptor class description for //! details. //! virtual SynStatus acquire2DTexture(const char* name, unsigned width, unsigned height, const void* values) = 0; //! \brief Create and store a volumetric texture. //! //! The GPU adaptor needs to retain the handle to the texture and release it in the releaseProgram() call. //! //! \param name Texture name. //! \param dim Texture dimension. The texture will be of size dim x dim x dim. //! \param linearInterpolation Whether linear interpolation of texel values is needed. //! \param values Values to be copied into the texture. //! \param size Values buffer size. // //! \return Must return a SYNCOLOR::SynStatus. See the GPUAdaptor class description for //! details. //! virtual SynStatus acquire3DTexture(const char* name, unsigned dim, bool linearInterpolation, const void* values, unsigned size) = 0; //! \brief Obtain any input texture related resources. //! //! This method needs to create the input texture name to be used in the shader program. //! //! \sa GPUAdaptor::getInputTextureName(). //! //! \return Must return a SYNCOLOR::SynStatus. See the GPUAdaptor class description for //! details. //! virtual SynStatus acquireInputTexture() = 0; //! \brief Obtain the input texture name. //! //! The input texture name is needed for inclusion in the shader declaration text. //! //! \return Texture identification. //! virtual const char* getInputTextureName() const = 0; //! \brief Render into the currently active destination render buffer. //! //! This method is for applying the color transform shader on the input texture. //! The input texture provided is mapped to the input texture name supplied by //! getInputTextureName(). //! //! \param inTexHandle Input texture handle. //! \param texCoords Input texture coordinates. //! \param screenCoords Destination screen coordinates. // //! \return Must return a SYNCOLOR::SynStatus. See the GPUAdaptor class description for //! details. //! virtual SynStatus drawQuad(unsigned inTexHandle, const SYNCOLOR::Vertices& texCoords, const SYNCOLOR::Vertices& screenCoords) const = 0; //! \brief Shader language configured. //! //! The shader language is specified at the constructor. //! //! \return Adaptor shader language. //! ShaderLanguage getShaderLanguage() const; protected: //! \brief GPU pipeline type configured. //! //! The pipeline type is specified at the constructor. //! //! \return Adaptor expected pipelined type. //! PipelineType _getPipelineType() const; private: ShaderLanguage _lang; //!< Shader language for constructing the color transform shader. PipelineType _pipelineType; //!< GPU pipeline type for which the color transform shader is built. }; //------------------------------------------------------------------------------------------------ //! \brief GPU Adaptor smart pointer. //! //! Class that manages sharing of GPU adaptor instances. Implements a shared pointer where only //! the last instance holding a specific GPUAdaptor instance will delete it. //! class SYN_EXPORT GPUAdaptorPtr { public: //! \brief Empty constructor. //! GPUAdaptorPtr(); //! \brief Initialization Constructor. //! //! \param pAdaptor GPUAdaptor pointer to manage. //! explicit GPUAdaptorPtr(GPUAdaptor* pAdaptor); //! \brief Destructor. //! //! If no other GPUAdaptorPtr shares the underlying pointer, the GPUAdaptor is deleted. //! ~GPUAdaptorPtr(); //! \brief Constant dereferencing operator. //! //! \return Pointer to the underlying non-modifiable GPUAdaptor instance. //! const GPUAdaptor* operator->() const; //! \brief Dereferencing operator. //! //! \return Pointer to the underlying GPUAdaptor instance. //! GPUAdaptor* operator->(); //! \brief Get the constant instance pointer. //! //! \return Pointer to the underlying non-modifiable GPUAdaptor instance. //! const GPUAdaptor* get() const; //! \brief Get the instance pointer. //! //! \return Pointer to the underlying GPUAdaptor instance. //! GPUAdaptor* get(); //! \brief Copy constructor. //! //! The resulting GPUAdaptorPtr shares the instance pointer with the //! GPUAdaptorPtr passed as argument. //! //! \param rhs GPUAdaptorPtr containing the pointer to share. //! GPUAdaptorPtr(const GPUAdaptorPtr& rhs); //! \brief Equality operator. //! //! The resulting GPUAdaptorPtr shares the instance pointer with the //! GPUAdaptorPtr passed as argument. //! //! \param rhs Constant GPUAdaptorPtr to share. //! //! \return Reference to the current instance. //! GPUAdaptorPtr& operator=(const GPUAdaptorPtr& rhs); //! \brief Equality operator. //! //! The resulting GPUAdaptorPtr shares the instance pointer with the //! GPUAdaptorPtr passed as argument. //! //! \param rhs GPUAdaptorPtr to share. //! //! \return Refernce to the current instance. //! GPUAdaptorPtr& operator=(GPUAdaptor * rhs); private: void* _pImpl; //!< Opaque smart pointer data. }; }; SYN_VISIBILITY_POP #endif // _SYNCOLOR_GPU_ADAPTOR_H