#pragma once #include "EmberCLPch.h" #include "OpenCLWrapper.h" #include "IterOpenCLKernelCreator.h" #include "DEOpenCLKernelCreator.h" #include "FinalAccumOpenCLKernelCreator.h" /// /// RendererCLBase and RendererCL classes. /// namespace EmberCLns { /// /// Serves only as an interface for OpenCL specific rendering functions. /// class EMBERCL_API RendererCLBase { public: virtual ~RendererCLBase() { } virtual bool ReadFinal(byte* pixels) = 0; virtual bool ClearFinal() = 0; }; /// /// RendererCL is a derivation of the basic CPU renderer which /// overrides various functions to render on the GPU using OpenCL. /// Since this class derives from EmberReport and also contains an /// OpenCLWrapper member which also derives from EmberReport, the /// reporting functions are overridden to aggregate the errors from /// both sources. /// It does not support different types for T and bucketT, so it only has one template argument /// and uses both for the base. /// template class EMBERCL_API RendererCL : public Renderer, public RendererCLBase { using EmberNs::Renderer::RendererBase::Abort; using EmberNs::Renderer::RendererBase::EarlyClip; using EmberNs::Renderer::RendererBase::Transparency; using EmberNs::Renderer::RendererBase::EnterResize; using EmberNs::Renderer::RendererBase::LeaveResize; using EmberNs::Renderer::RendererBase::FinalRasW; using EmberNs::Renderer::RendererBase::FinalRasH; using EmberNs::Renderer::RendererBase::SuperRasW; using EmberNs::Renderer::RendererBase::SuperRasH; using EmberNs::Renderer::RendererBase::SuperSize; using EmberNs::Renderer::RendererBase::BytesPerChannel; using EmberNs::Renderer::RendererBase::TemporalSamples; using EmberNs::Renderer::RendererBase::ItersPerTemporalSample; using EmberNs::Renderer::RendererBase::FuseCount; using EmberNs::Renderer::RendererBase::DensityFilterOffset; using EmberNs::Renderer::RendererBase::m_ProgressParameter; using EmberNs::Renderer::RendererBase::m_YAxisUp; using EmberNs::Renderer::RendererBase::m_LockAccum; using EmberNs::Renderer::RendererBase::m_Abort; using EmberNs::Renderer::RendererBase::m_NumChannels; using EmberNs::Renderer::RendererBase::m_LastIter; using EmberNs::Renderer::RendererBase::m_LastIterPercent; using EmberNs::Renderer::RendererBase::m_Stats; using EmberNs::Renderer::RendererBase::m_Callback; using EmberNs::Renderer::RendererBase::m_Rand; using EmberNs::Renderer::RendererBase::m_RenderTimer; using EmberNs::Renderer::RendererBase::m_IterTimer; using EmberNs::Renderer::RendererBase::m_ProgressTimer; using EmberNs::Renderer::RendererBase::EmberReport::m_ErrorReport; using EmberNs::Renderer::m_RotMat; using EmberNs::Renderer::m_Ember; using EmberNs::Renderer::CenterX; using EmberNs::Renderer::CenterY; using EmberNs::Renderer::K1; using EmberNs::Renderer::K2; using EmberNs::Renderer::Supersample; using EmberNs::Renderer::HighlightPower; using EmberNs::Renderer::HistBuckets; using EmberNs::Renderer::AccumulatorBuckets; using EmberNs::Renderer::GetDensityFilter; using EmberNs::Renderer::GetSpatialFilter; using EmberNs::Renderer::CoordMap; using EmberNs::Renderer::XformDistributions; using EmberNs::Renderer::XformDistributionsSize; public: RendererCL(uint platform = 0, uint device = 0, bool shared = false, GLuint outputTexID = 0); ~RendererCL(); //Non-virtual member functions for OpenCL specific tasks. bool Init(uint platform, uint device, bool shared, GLuint outputTexID); bool SetOutputTexture(GLuint outputTexID); //Iters per kernel/block/grid. inline uint IterCountPerKernel() const; inline uint IterCountPerBlock() const; inline uint IterCountPerGrid() const; //Kernels per block. inline uint IterBlockKernelWidth() const; inline uint IterBlockKernelHeight() const; inline uint IterBlockKernelCount() const; //Kernels per grid. inline uint IterGridKernelWidth() const; inline uint IterGridKernelHeight() const; inline uint IterGridKernelCount() const; //Blocks per grid. inline uint IterGridBlockWidth() const; inline uint IterGridBlockHeight() const; inline uint IterGridBlockCount() const; uint PlatformIndex(); uint DeviceIndex(); bool ReadHist(); bool ReadAccum(); bool ReadPoints(vector>& vec); bool ClearHist(); bool ClearAccum(); bool WritePoints(vector>& vec); #ifdef TEST_CL bool WriteRandomPoints(); #endif string IterKernel(); //Virtual functions overridden from RendererCLBase. virtual bool ReadFinal(byte* pixels); virtual bool ClearFinal(); //Public virtual functions overridden from Renderer or RendererBase. virtual size_t MemoryAvailable() override; virtual bool Ok() const override; virtual void NumChannels(size_t numChannels) override; virtual void DumpErrorReport() override; virtual void ClearErrorReport() override; virtual size_t SubBatchSize() const override; virtual size_t ThreadCount() const override; virtual bool CreateDEFilter(bool& newAlloc) override; virtual bool CreateSpatialFilter(bool& newAlloc) override; virtual eRendererType RendererType() const override; virtual string ErrorReportString() override; virtual vector ErrorReport() override; virtual bool RandVec(vector>& randVec) override; #ifndef TEST_CL protected: #endif //Protected virtual functions overridden from Renderer. virtual void MakeDmap(T colorScalar) override; virtual bool Alloc() override; virtual bool ResetBuckets(bool resetHist = true, bool resetAccum = true) override; virtual eRenderStatus LogScaleDensityFilter() override; virtual eRenderStatus GaussianDensityFilter() override; virtual eRenderStatus AccumulatorToFinalImage(byte* pixels, size_t finalOffset) override; virtual EmberStats Iterate(size_t iterCount, size_t temporalSample) override; private: //Private functions for making and running OpenCL programs. bool BuildIterProgramForEmber(bool doAccum = true); bool RunIter(size_t iterCount, size_t temporalSample, size_t& itersRan); eRenderStatus RunLogScaleFilter(); eRenderStatus RunDensityFilter(); eRenderStatus RunFinalAccum(); bool ClearBuffer(const string& bufferName, uint width, uint height, uint elementSize); bool RunDensityFilterPrivate(uint kernelIndex, uint gridW, uint gridH, uint blockW, uint blockH, uint chunkSizeW, uint chunkSizeH, uint chunkW, uint chunkH); int MakeAndGetDensityFilterProgram(size_t ss, uint filterWidth); int MakeAndGetFinalAccumProgram(T& alphaBase, T& alphaScale); int MakeAndGetGammaCorrectionProgram(); void FillSeeds(); //Private functions passing data to OpenCL programs. DensityFilterCL ConvertDensityFilter(); SpatialFilterCL ConvertSpatialFilter(); void ConvertEmber(Ember& ember, EmberCL& emberCL, vector>& xformsCL); static CarToRasCL ConvertCarToRas(const CarToRas& carToRas); bool m_Init; bool m_NVidia; bool m_DoublePrecision; uint m_IterCountPerKernel; uint m_IterBlocksWide, m_IterBlockWidth; uint m_IterBlocksHigh, m_IterBlockHeight; uint m_MaxDEBlockSizeW; uint m_MaxDEBlockSizeH; uint m_WarpSize; size_t m_Calls; //Buffer names. string m_EmberBufferName; string m_XformsBufferName; string m_ParVarsBufferName; string m_SeedsBufferName; string m_DistBufferName; string m_CarToRasBufferName; string m_DEFilterParamsBufferName; string m_SpatialFilterParamsBufferName; string m_DECoefsBufferName; string m_DEWidthsBufferName; string m_DECoefIndicesBufferName; string m_SpatialFilterCoefsBufferName; string m_HistBufferName; string m_AccumBufferName; string m_FinalImageName; string m_PointsBufferName; //Kernels. string m_IterKernel; OpenCLWrapper m_Wrapper; cl::ImageFormat m_PaletteFormat; cl::ImageFormat m_FinalFormat; cl::Image2D m_Palette; IMAGEGL2D m_AccumImage; GLuint m_OutputTexID; EmberCL m_EmberCL; vector> m_XformsCL; vector m_Seeds; Palette m_DmapCL;//Used instead of the base class' m_Dmap because OpenCL only supports float textures. CarToRasCL m_CarToRasCL; DensityFilterCL m_DensityFilterCL; SpatialFilterCL m_SpatialFilterCL; IterOpenCLKernelCreator m_IterOpenCLKernelCreator; DEOpenCLKernelCreator m_DEOpenCLKernelCreator; FinalAccumOpenCLKernelCreator m_FinalAccumOpenCLKernelCreator; pair> m_Params; Ember m_LastBuiltEmber; }; }