mirror of
https://bitbucket.org/mfeemster/fractorium.git
synced 2025-01-22 05:30:06 -05:00
9e94170a70
--User Changes Size is no longer fixed to the window size. Size scaling is done differently in the final render dialog. This fixes several bugs. Remove Xml saving size from settings and options dialog, it no longer applies. Final render can be broken into strips. Set default save path to the desktop if none is found in the settings file. Set default output size to 1920x1080 if none is found in the settings file. --Bug Fixes Better memory size reporting in final render dialog. --Code Changes Migrate to C++11, Qt 5.3.1, and Visual Studio 2013. Change most instances of unsigned int to size_t, and int to intmax_t. Add m_OrigPixPerUnit and m_ScaleType to Ember for scaling purposes. Replace some sprintf_s() calls in XmlToEmber with ostringstream. Move more non-templated members into RendererBase. Add CopyVec() overload that takes a per element function pointer. Add vector Memset(). Replace '&' with '+' instead of "&" in XmlToEmber for much faster parsing. Break strips rendering out into EmberCommon and call from EmberRender and Fractorium. Make AddAndWriteBuffer() just call WriteBuffer(). Make AddAndWriteImage() delete the existing image first before replacing it. Add SetOutputTexture() to RendererCL to support making new textures in response to resize events. Remove multiple return statements in RendererCL, and replace with a bool that tracks results. Add ToDouble(), MakeEnd(), ToString() and Exists() wrappers in Fractorium. Add Size() wrapper in EmberFile. Make QString function arguments const QString&, and string with const string&. Make ShowCritical() wrapper for invoking a message box from another thread. Add combo box to TwoButtonWidget and rename.
219 lines
7.4 KiB
C++
219 lines
7.4 KiB
C++
#pragma once
|
|
|
|
#include "EmberCLPch.h"
|
|
|
|
/// <summary>
|
|
/// OpenCLWrapper, Spk, NamedBuffer, NamedImage2D, NamedImage2DGL classes.
|
|
/// </summary>
|
|
|
|
namespace EmberCLns
|
|
{
|
|
#if CL_VERSION_1_2
|
|
#define IMAGEGL2D cl::ImageGL
|
|
#else
|
|
#define IMAGEGL2D cl::Image2DGL
|
|
#endif
|
|
|
|
/// <summary>
|
|
/// Class to contain all of the things needed to store an OpenCL program.
|
|
/// The name of it, the source, the compiled program object and the kernel.
|
|
/// </summary>
|
|
class EMBERCL_API Spk
|
|
{
|
|
public:
|
|
string m_Name;
|
|
cl::Program::Sources m_Source;
|
|
cl::Program m_Program;
|
|
cl::Kernel m_Kernel;
|
|
};
|
|
|
|
/// <summary>
|
|
/// Class to hold an OpenCL buffer with a name to identify it by.
|
|
/// </summary>
|
|
class EMBERCL_API NamedBuffer
|
|
{
|
|
public:
|
|
NamedBuffer()
|
|
{
|
|
}
|
|
|
|
NamedBuffer(cl::Buffer& buff, string name)
|
|
{
|
|
m_Buffer = buff;
|
|
m_Name = name;
|
|
}
|
|
|
|
cl::Buffer m_Buffer;
|
|
string m_Name;
|
|
};
|
|
|
|
/// <summary>
|
|
/// Class to hold a 2D image with a name to identify it by.
|
|
/// </summary>
|
|
class EMBERCL_API NamedImage2D
|
|
{
|
|
public:
|
|
NamedImage2D()
|
|
{
|
|
}
|
|
|
|
NamedImage2D(cl::Image2D& image, string name)
|
|
{
|
|
m_Image = image;
|
|
m_Name = name;
|
|
}
|
|
|
|
cl::Image2D m_Image;
|
|
string m_Name;
|
|
};
|
|
|
|
/// <summary>
|
|
/// Class to hold a 2D image that is mapped to an OpenGL texture
|
|
/// and a name to identify it by.
|
|
/// </summary>
|
|
class EMBERCL_API NamedImage2DGL
|
|
{
|
|
public:
|
|
NamedImage2DGL()
|
|
{
|
|
}
|
|
|
|
NamedImage2DGL(IMAGEGL2D& image, string name)
|
|
{
|
|
m_Image = image;
|
|
m_Name = name;
|
|
}
|
|
|
|
IMAGEGL2D m_Image;
|
|
string m_Name;
|
|
};
|
|
|
|
/// <summary>
|
|
/// Running kernels in OpenCL can require quite a bit of setup, tear down and
|
|
/// general housekeeping. This class helps shield the user from such hassles.
|
|
/// It's main utility is in holding collections of programs, buffers and images
|
|
/// all identified by names. That way, a user can access them as needed without
|
|
/// having to pollute their code.
|
|
/// In addition, writing to an existing object by name determines if the object
|
|
/// can be overwritten, or if it needs to be deleted and replaced by the new one.
|
|
/// This class derives from EmberReport, so the caller is able
|
|
/// to retrieve a text dump of error information if any errors occur.
|
|
/// </summary>
|
|
class EMBERCL_API OpenCLWrapper : public EmberReport
|
|
{
|
|
public:
|
|
OpenCLWrapper();
|
|
bool CheckOpenCL();
|
|
bool Init(unsigned int platform, unsigned int device, bool shared = false);
|
|
|
|
//Programs.
|
|
bool AddProgram(std::string name, std::string& program, std::string& entryPoint, bool doublePrecision);
|
|
void ClearPrograms();
|
|
|
|
//Buffers.
|
|
bool AddBuffer(const string& name, size_t size, cl_mem_flags flags = CL_MEM_READ_WRITE);
|
|
bool AddAndWriteBuffer(const string& name, void* data, size_t size, cl_mem_flags flags = CL_MEM_READ_WRITE);
|
|
bool WriteBuffer(const string& name, void* data, size_t size);
|
|
bool WriteBuffer(unsigned int bufferIndex, void* data, size_t size);
|
|
bool ReadBuffer(const string& name, void* data, size_t size);
|
|
bool ReadBuffer(unsigned int bufferIndex, void* data, size_t size);
|
|
int FindBufferIndex(const string& name);
|
|
unsigned int GetBufferSize(const string& name);
|
|
unsigned int GetBufferSize(unsigned int bufferIndex);
|
|
void ClearBuffers();
|
|
|
|
//Images.
|
|
bool AddAndWriteImage(const string& name, cl_mem_flags flags, const cl::ImageFormat& format, ::size_t width, ::size_t height, ::size_t row_pitch, void* data = NULL, bool shared = false, GLuint texName = 0);
|
|
bool WriteImage2D(unsigned int index, bool shared, ::size_t width, ::size_t height, ::size_t row_pitch, void* data);
|
|
bool ReadImage(const string& name, ::size_t width, ::size_t height, ::size_t row_pitch, bool shared, void* data);
|
|
bool ReadImage(unsigned int imageIndex, ::size_t width, ::size_t height, ::size_t row_pitch, bool shared, void* data);
|
|
int FindImageIndex(const string& name, bool shared);
|
|
unsigned int GetImageSize(const string& name, bool shared);
|
|
unsigned int GetImageSize(unsigned int imageIndex, bool shared);
|
|
bool CompareImageParams(cl::Image& image, cl_mem_flags flags, const cl::ImageFormat& format, ::size_t width, ::size_t height, ::size_t row_pitch);
|
|
void ClearImages(bool shared);
|
|
bool CreateImage2D(cl::Image2D& image2D, cl_mem_flags flags, cl::ImageFormat format, ::size_t width, ::size_t height, ::size_t row_pitch = 0, void* data = NULL);
|
|
bool CreateImage2DGL(IMAGEGL2D& image2DGL, cl_mem_flags flags, GLenum target, GLint miplevel, GLuint texobj);
|
|
bool EnqueueAcquireGLObjects(const string& name);
|
|
bool EnqueueAcquireGLObjects(IMAGEGL2D& image);
|
|
bool EnqueueReleaseGLObjects(const string& name);
|
|
bool EnqueueReleaseGLObjects(IMAGEGL2D& image);
|
|
bool EnqueueAcquireGLObjects(const VECTOR_CLASS<cl::Memory>* memObjects = NULL);
|
|
bool EnqueueReleaseGLObjects(const VECTOR_CLASS<cl::Memory>* memObjects = NULL);
|
|
bool CreateSampler(cl::Sampler& sampler, cl_bool normalizedCoords, cl_addressing_mode addressingMode, cl_filter_mode filterMode);
|
|
|
|
//Arguments.
|
|
bool SetBufferArg(unsigned int kernelIndex, unsigned int argIndex, string name);
|
|
bool SetBufferArg(unsigned int kernelIndex, unsigned int argIndex, unsigned int bufferIndex);
|
|
bool SetImageArg(unsigned int kernelIndex, unsigned int argIndex, bool shared, string name);
|
|
bool SetImageArg(unsigned int kernelIndex, unsigned int argIndex, bool shared, unsigned int imageIndex);
|
|
|
|
/// <summary>
|
|
/// Set an argument in the specified kernel, at the specified argument index.
|
|
/// Must keep this here in the .h because it's templated.
|
|
/// </summary>
|
|
/// <param name="kernelIndex">Index of the kernel whose argument will be set</param>
|
|
/// <param name="argIndex">Index of the argument to set</param>
|
|
/// <param name="arg">The argument value to set</param>
|
|
/// <returns>True if success, else false</returns>
|
|
template <typename T>
|
|
bool SetArg(unsigned int kernelIndex, unsigned int argIndex, T arg)
|
|
{
|
|
if (m_Init && kernelIndex < m_Programs.size())
|
|
{
|
|
cl_int err = m_Programs[kernelIndex].m_Kernel.setArg(argIndex, arg);
|
|
|
|
return CheckCL(err, "cl::Kernel::setArg()");
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
//Kernels.
|
|
int FindKernelIndex(const string& name);
|
|
bool RunKernel(unsigned int kernelIndex, unsigned int totalGridWidth, unsigned int totalGridHeight, unsigned int totalGridDepth, unsigned int blockWidth, unsigned int blockHeight, unsigned int blockDepth);
|
|
|
|
//Info.
|
|
template<typename T>
|
|
T GetInfo(size_t platform, size_t device, cl_device_info name);
|
|
string PlatformName(size_t platform);
|
|
vector<string> PlatformNames();
|
|
string DeviceName(size_t platform, size_t device);
|
|
vector<string> DeviceNames(size_t platform);
|
|
string DeviceAndPlatformNames();
|
|
string DumpInfo();
|
|
|
|
//Accessors.
|
|
bool Ok();
|
|
bool Shared();
|
|
cl::Context Context();
|
|
unsigned int PlatformIndex();
|
|
unsigned int DeviceIndex();
|
|
unsigned int LocalMemSize();
|
|
|
|
static void MakeEvenGridDims(unsigned int blockW, unsigned int blockH, unsigned int& gridW, unsigned int& gridH);
|
|
|
|
private:
|
|
bool CreateContext(bool shared);
|
|
bool CreateSPK(std::string& name, std::string& program, std::string& entryPoint, Spk& spk, bool doublePrecision);
|
|
bool CheckCL(cl_int err, const char* name);
|
|
std::string ErrorToStringCL(cl_int err);
|
|
|
|
bool m_Init;
|
|
bool m_Shared;
|
|
unsigned int m_PlatformIndex;
|
|
unsigned int m_DeviceIndex;
|
|
unsigned int m_LocalMemSize;
|
|
cl::Platform m_Platform;
|
|
cl::Context m_Context;
|
|
cl::Device m_Device;
|
|
cl::CommandQueue m_Queue;
|
|
std::vector<cl::Platform> m_Platforms;
|
|
std::vector<std::vector<cl::Device>> m_Devices;
|
|
std::vector<cl::Device> m_DeviceVec;
|
|
std::vector<Spk> m_Programs;
|
|
std::vector<NamedBuffer> m_Buffers;
|
|
std::vector<NamedImage2D> m_Images;
|
|
std::vector<NamedImage2DGL> m_GLImages;
|
|
};
|
|
} |