mirror of
https://bitbucket.org/mfeemster/fractorium.git
synced 2025-02-23 13:31:31 -05:00
--Bug fixes
-Available memory size checking in the final render dialog was accidentally removed during the multi-gpu work last year. Add it back in.
This commit is contained in:
parent
32d6982210
commit
6ff8aa0722
@ -933,6 +933,7 @@ bool OpenCLWrapper::Shared() const { return m_Shared; }
|
||||
const cl::Context& OpenCLWrapper::Context() const { return m_Context; }
|
||||
size_t OpenCLWrapper::PlatformIndex() const { return m_PlatformIndex; }
|
||||
size_t OpenCLWrapper::DeviceIndex() const { return m_DeviceIndex; }
|
||||
size_t OpenCLWrapper::TotalDeviceIndex() const { return m_Info->TotalDeviceIndex(m_PlatformIndex, m_DeviceIndex); }
|
||||
const string& OpenCLWrapper::DeviceName() const { return m_Info->DeviceName(m_PlatformIndex, m_DeviceIndex); }
|
||||
size_t OpenCLWrapper::LocalMemSize() const { return m_LocalMemSize; }
|
||||
size_t OpenCLWrapper::GlobalMemSize() const { return m_GlobalMemSize; }
|
||||
|
@ -172,8 +172,8 @@ public:
|
||||
const cl::Context& Context() const;
|
||||
size_t PlatformIndex() const;
|
||||
size_t DeviceIndex() const;
|
||||
const string& DeviceName() const;
|
||||
size_t TotalDeviceIndex() const;
|
||||
const string& DeviceName() const;
|
||||
size_t LocalMemSize() const;
|
||||
size_t GlobalMemSize() const;
|
||||
size_t MaxAllocSize() const;
|
||||
|
@ -394,6 +394,14 @@ const string& RendererCL<T, bucketT>::DEKernel() const { return m_DEOpenCLKernel
|
||||
template <typename T, typename bucketT>
|
||||
const string& RendererCL<T, bucketT>::FinalAccumKernel() const { return m_FinalAccumOpenCLKernelCreator.FinalAccumKernel(EarlyClip(), Renderer<T, bucketT>::NumChannels(), Transparency()); }
|
||||
|
||||
/// <summary>
|
||||
/// Get the a const referece to the devices this renderer will use.
|
||||
/// Use this cautiously and do not use const_cast to manipulate the vector.
|
||||
/// </summary>
|
||||
/// <returns>A const reference to a vector of unique_ptr of devices</returns>
|
||||
template <typename T, typename bucketT>
|
||||
const vector<unique_ptr<RendererClDevice>>& RendererCL<T, bucketT>::Devices() const { return m_Devices; }
|
||||
|
||||
/// <summary>
|
||||
/// Virtual functions overridden from RendererCLBase.
|
||||
/// </summary>
|
||||
|
@ -135,6 +135,9 @@ public:
|
||||
const string& DEKernel() const;
|
||||
const string& FinalAccumKernel() const;
|
||||
|
||||
//Access to underlying OpenCL structures. Use cautiously.
|
||||
const vector<unique_ptr<RendererClDevice>>& Devices() const;
|
||||
|
||||
//Virtual functions overridden from RendererCLBase.
|
||||
virtual bool ReadFinal(byte* pixels);
|
||||
virtual bool ClearFinal();
|
||||
|
@ -55,6 +55,4 @@ bool RendererClDevice::Ok() const { return m_Init; }
|
||||
bool RendererClDevice::Shared() const { return m_Shared; }
|
||||
bool RendererClDevice::Nvidia() const { return m_NVidia; }
|
||||
size_t RendererClDevice::WarpSize() const { return m_WarpSize; }
|
||||
size_t RendererClDevice::PlatformIndex() const { return m_PlatformIndex; }
|
||||
size_t RendererClDevice::DeviceIndex() const { return m_DeviceIndex; }
|
||||
}
|
||||
|
@ -24,8 +24,6 @@ public:
|
||||
bool Shared() const;
|
||||
bool Nvidia() const;
|
||||
size_t WarpSize() const;
|
||||
size_t PlatformIndex() const;
|
||||
size_t DeviceIndex() const;
|
||||
|
||||
size_t m_Calls;
|
||||
OpenCLWrapper m_Wrapper;
|
||||
|
@ -748,62 +748,23 @@ bool FractoriumFinalRenderDialog::CreateControllerFromGUI(bool createRenderer)
|
||||
/// assign the result to the table cell as text.
|
||||
/// Report errors if not enough memory is available for any of the selected devices.
|
||||
/// </summary>
|
||||
/// <returns>True devices and a controller is present, else false.</returns>
|
||||
/// <returns>True if devices and a controller is present, else false.</returns>
|
||||
bool FractoriumFinalRenderDialog::SetMemory()
|
||||
{
|
||||
if (isVisible() && CreateControllerFromGUI(true))
|
||||
{
|
||||
bool error = false;
|
||||
tuple<size_t, size_t, size_t> p = m_Controller->SyncAndComputeMemory();
|
||||
QString s;
|
||||
auto p = m_Controller->SyncAndComputeMemory();
|
||||
ui.FinalRenderParamsTable->item(m_MemoryCellIndex, 1)->setText(ToString<qulonglong>(get<1>(p)));
|
||||
ui.FinalRenderParamsTable->item(m_ItersCellIndex, 1)->setText(ToString<qulonglong>(get<2>(p)));
|
||||
|
||||
if (OpenCL() && !m_Wrappers.empty())
|
||||
{
|
||||
auto devices = Devices();
|
||||
|
||||
for (size_t i = 0; i < m_Wrappers.size(); i++)
|
||||
{
|
||||
if (devices.contains(int(i)))
|
||||
{
|
||||
size_t histSize = get<0>(p);
|
||||
size_t totalSize = get<1>(p);
|
||||
size_t maxAlloc = m_Wrappers[i].MaxAllocSize();
|
||||
size_t totalAvail = m_Wrappers[i].GlobalMemSize();
|
||||
QString temp;
|
||||
|
||||
if (histSize > maxAlloc)
|
||||
{
|
||||
temp = "Histogram/Accumulator memory size of " + ToString<qulonglong>(histSize) +
|
||||
" is greater than the max OpenCL allocation size of " + ToString<qulonglong>(maxAlloc);
|
||||
}
|
||||
|
||||
if (totalSize > totalAvail)
|
||||
{
|
||||
temp += "\n\nTotal required memory size of " + ToString<qulonglong>(totalSize) +
|
||||
" is greater than the max OpenCL available memory of " + ToString<qulonglong>(totalAvail);
|
||||
}
|
||||
|
||||
if (!temp.isEmpty())
|
||||
{
|
||||
error = true;
|
||||
s += QString::fromStdString(m_Wrappers[i].DeviceName()) + ":\n" + temp + "\n\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!s.isEmpty())
|
||||
s += "Rendering will most likely fail.";
|
||||
|
||||
ui.FinalRenderTextOutput->setText(s);
|
||||
}
|
||||
|
||||
if (!error)
|
||||
if (OpenCL())
|
||||
ui.FinalRenderTextOutput->setText(m_Controller->CheckMemory(p));
|
||||
else
|
||||
ui.FinalRenderTextOutput->clear();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -931,6 +931,85 @@ void FinalRenderEmberController<T>::SetProgressComplete(int val)
|
||||
QMetaObject::invokeMethod(m_FinalRenderDialog->ui.FinalRenderAccumProgress, "setValue", Qt::QueuedConnection, Q_ARG(int, val));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if the amount of required memory is greater than that available on
|
||||
/// all required OpenCL devices. Also check if enough space is available for the max allocation.
|
||||
/// No check is done for CPU renders.
|
||||
/// Report errors if not enough memory is available for any of the selected devices.
|
||||
/// </summary>
|
||||
/// <returns>A string with an error report if required memory exceeds available memory on any device, else empty string.</returns>
|
||||
template <typename T>
|
||||
QString FinalRenderEmberController<T>::CheckMemory(const tuple<size_t, size_t, size_t>& p)
|
||||
{
|
||||
bool error = false;
|
||||
QString s;
|
||||
size_t histSize = get<0>(p);
|
||||
size_t totalSize = get<1>(p);
|
||||
auto& selectedDevices = m_FinalRenderDialog->Devices();
|
||||
static vector<RendererCL<T, float>*> clRenderers;
|
||||
clRenderers.clear();
|
||||
|
||||
//Find all OpenCL renderers currently being used and place them in a vector of pointers.
|
||||
if (m_FinalRenderDialog->DoSequence())
|
||||
{
|
||||
for (auto& r : m_Renderers)
|
||||
if (auto clr = dynamic_cast<RendererCL<T, float>*>(r.get()))
|
||||
clRenderers.push_back(clr);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (auto clr = dynamic_cast<RendererCL<T, float>*>(m_Renderer.get()))
|
||||
clRenderers.push_back(clr);
|
||||
}
|
||||
|
||||
//Iterate through each renderer and examine each device it's using.
|
||||
for (auto r : clRenderers)
|
||||
{
|
||||
auto& devices = r->Devices();
|
||||
|
||||
for (auto& d : devices)
|
||||
{
|
||||
auto& wrapper = d->m_Wrapper;
|
||||
auto index = wrapper.TotalDeviceIndex();
|
||||
|
||||
if (selectedDevices.contains(int(index)))
|
||||
{
|
||||
bool err = false;
|
||||
QString temp;
|
||||
size_t maxAlloc = wrapper.MaxAllocSize();
|
||||
size_t totalAvail = wrapper.GlobalMemSize();
|
||||
|
||||
if (histSize > maxAlloc)
|
||||
{
|
||||
err = true;
|
||||
temp = "Histogram/Accumulator memory size of " + ToString<qulonglong>(histSize) +
|
||||
" is greater than the max OpenCL allocation size of " + ToString<qulonglong>(maxAlloc);
|
||||
}
|
||||
|
||||
if (totalSize > totalAvail)
|
||||
{
|
||||
if (err)
|
||||
temp += "\n\n";
|
||||
|
||||
temp += "Total required memory size of " + ToString<qulonglong>(totalSize) +
|
||||
" is greater than the max OpenCL available memory of " + ToString<qulonglong>(totalAvail);
|
||||
}
|
||||
|
||||
if (!temp.isEmpty())
|
||||
{
|
||||
error = true;
|
||||
s += QString::fromStdString(wrapper.DeviceName()) + ":\n" + temp + "\n\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!s.isEmpty())
|
||||
s += "Rendering will most likely fail.";
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
template class FinalRenderEmberController<float>;
|
||||
|
||||
#ifdef DO_DOUBLE
|
||||
|
@ -13,7 +13,6 @@
|
||||
/// </summary>
|
||||
class Fractorium;
|
||||
class FractoriumFinalRenderDialog;
|
||||
//class FractoriumEmberControllerBase;
|
||||
|
||||
/// <summary>
|
||||
/// Used to hold the options specified in the current state of the Gui for performing the final render.
|
||||
@ -68,6 +67,7 @@ public:
|
||||
virtual double OriginalAspect() { return 1; }
|
||||
virtual QString ComposePath(const QString& name) { return ""; }
|
||||
virtual void CancelRender() { }
|
||||
virtual QString CheckMemory(const tuple<size_t, size_t, size_t>& p) { return ""; }
|
||||
|
||||
bool CreateRendererFromGUI();
|
||||
void Output(const QString& s);
|
||||
@ -126,6 +126,7 @@ public:
|
||||
virtual QString Name() const override { return QString::fromStdString(m_Ember->m_Name); }
|
||||
virtual QString ComposePath(const QString& name) override;
|
||||
virtual void CancelRender() override;
|
||||
virtual QString CheckMemory(const tuple<size_t, size_t, size_t>& p) override;
|
||||
|
||||
//Non Virtual functions.
|
||||
EmberNs::Renderer<T, float>* FirstOrDefaultRenderer();
|
||||
|
Loading…
Reference in New Issue
Block a user