--User changes

-Disable Start button in final render dialog when Pause is clicked.

--Bug fixes
 -Rapidly changing spinner values was causing the OpenCL renderer to report a failure, when it was really just aborting.

--Code changes
 -Renderers never internally set abort to true due to a failure. Abort is only set to true by the calling code.
This commit is contained in:
Person 2018-10-05 19:50:38 -07:00
parent 784bd9cca2
commit a0b658481a
15 changed files with 36 additions and 36 deletions

View File

@ -6,7 +6,7 @@
<ProductVersion>3.7</ProductVersion>
<ProjectGuid>{c8096c47-e358-438c-a520-146d46b0637d}</ProjectGuid>
<SchemaVersion>2.0</SchemaVersion>
<OutputName>Fractorium_1.0.0.12</OutputName>
<OutputName>Fractorium_1.0.0.13</OutputName>
<OutputType>Package</OutputType>
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' AND '$(MSBuildExtensionsPath32)' != '' ">$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?define ProductVersion="1.0.0.12" ?>
<?define ProductVersion="1.0.0.13" ?>
<?define ProductName="Fractorium $(var.ProductVersion) ($(var.GpuType))" ?>
<?define UpgradeCode="{4714cd15-bfba-44f6-8059-9e1466ebfa6e}"?>
<?define Manufacturer="Fractorium"?>
@ -13,7 +13,7 @@
<!--
Change this for every release.
-->
<?define ProductCode="{B4D001AE-F268-41A2-9B33-CAFB26056DC3}"?>
<?define ProductCode="{E78B38F9-F4BC-408A-A36B-5C494FA88D21}"?>
<Product Id="$(var.ProductCode)" Name="$(var.ProductName)" Language="1033" Version="$(var.ProductVersion)" Manufacturer="$(var.Manufacturer)" UpgradeCode="$(var.UpgradeCode)">
<Package

Binary file not shown.

View File

@ -49,8 +49,8 @@
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1, 0, 0, 12
PRODUCTVERSION 1, 0, 0, 12
FILEVERSION 1, 0, 0, 13
PRODUCTVERSION 1, 0, 0, 13
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -67,12 +67,12 @@
BEGIN
VALUE "CompanyName", "Open Source"
VALUE "FileDescription", "Renders fractal flames as animations with motion blur"
VALUE "FileVersion", "1.0.0.12"
VALUE "FileVersion", "1, 0, 0, 13"
VALUE "InternalName", "EmberAnimate.exe"
VALUE "LegalCopyright", "Copyright (C) Matt Feemster 2018, GPL v3"
VALUE "OriginalFilename", "EmberAnimate.exe"
VALUE "ProductName", "Ember Animate"
VALUE "ProductVersion", "1.0.0.12"
VALUE "ProductVersion", "1, 0, 0, 13"
END
END
BLOCK "VarFileInfo"

Binary file not shown.

View File

@ -49,8 +49,8 @@
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1, 0, 0, 12
PRODUCTVERSION 1, 0, 0, 12
FILEVERSION 1, 0, 0, 13
PRODUCTVERSION 1, 0, 0, 13
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -67,12 +67,12 @@
BEGIN
VALUE "CompanyName", "Open Source"
VALUE "FileDescription", "Manipulates fractal flames parameter files"
VALUE "FileVersion", "1.0.0.12"
VALUE "FileVersion", "1, 0, 0, 13"
VALUE "InternalName", "EmberGenome.exe"
VALUE "LegalCopyright", "Copyright (C) Matt Feemster 2018, GPL v3"
VALUE "OriginalFilename", "EmberGenome.exe"
VALUE "ProductName", "Ember Genome"
VALUE "ProductVersion", "1.0.0.12"
VALUE "ProductVersion", "1, 0, 0, 13"
END
END
BLOCK "VarFileInfo"

View File

@ -49,8 +49,8 @@
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1, 0, 0, 12
PRODUCTVERSION 1, 0, 0, 12
FILEVERSION 1, 0, 0, 13
PRODUCTVERSION 1, 0, 0, 13
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -67,12 +67,12 @@
BEGIN
VALUE "CompanyName", "Open Source"
VALUE "FileDescription", "Renders fractal flames as single images"
VALUE "FileVersion", "1.0.0.12"
VALUE "FileVersion", "1, 0, 0, 13"
VALUE "InternalName", "EmberRender.exe"
VALUE "LegalCopyright", "Copyright (C) Matt Feemster 2018, GPL v3"
VALUE "OriginalFilename", "EmberRender.exe"
VALUE "ProductName", "Ember Render"
VALUE "ProductVersion", "1.0.0.12"
VALUE "ProductVersion", "1, 0, 0, 13"
END
END
BLOCK "VarFileInfo"

Binary file not shown.

View File

@ -37,7 +37,7 @@ static void sincos(float x, float* s, float* c)
namespace EmberNs
{
#define EMBER_VERSION "1.0.0.12"
#define EMBER_VERSION "1.0.0.13"
#define EPS6 T(1e-6)
#define EPS std::numeric_limits<T>::epsilon()//Apoplugin.h uses -20, but it's more mathematically correct to do it this way.
#define ISAAC_SIZE 4

View File

@ -528,8 +528,15 @@ eRenderStatus Renderer<T, bucketT>::Run(vector<v4F>& finalImage, double time, si
sampleItersToDo = std::min<size_t>(sampleItersToDo, itersPerTemporalSample - m_LastIter);
EmberStats stats = Iterate(sampleItersToDo, temporalSample);//The heavy work is done here.
//Abort does not indicate an error, it just means the process was interrupted, most likely by the user on the GUI.
if (m_Abort)
{
success = eRenderStatus::RENDER_ABORT;
goto Finish;
}
//If no iters were executed, something went catastrophically wrong.
if (stats.m_Iters == 0)
if (!stats.m_Success && stats.m_Iters == 0)
{
AddToReport("Zero iterations ran, rendering failed, aborting.\n");
success = eRenderStatus::RENDER_ERROR;
@ -537,12 +544,6 @@ eRenderStatus Renderer<T, bucketT>::Run(vector<v4F>& finalImage, double time, si
goto Finish;
}
if (m_Abort)
{
success = eRenderStatus::RENDER_ABORT;
goto Finish;
}
//Accumulate stats whether this batch ran to completion or exited prematurely.
m_LastIter += stats.m_Iters;//Sum of iter count of all threads, reset each temporal sample.
m_Stats.m_Iters += stats.m_Iters;//Sum of iter count of all threads, cumulative from beginning to end.

View File

@ -61,6 +61,7 @@ public:
void Clear()
{
m_Success = true;
m_Iters = 0;
m_Badvals = 0;
m_IterMs = 0;
@ -69,6 +70,7 @@ public:
EmberStats& operator += (const EmberStats& stats)
{
m_Success &= stats.m_Success;
m_Iters += stats.m_Iters;
m_Badvals += stats.m_Badvals;
m_IterMs += stats.m_IterMs;
@ -76,6 +78,7 @@ public:
return *this;
}
bool m_Success = true;
size_t m_Iters, m_Badvals;
double m_IterMs, m_RenderMs;
};

View File

@ -787,9 +787,9 @@ eRenderStatus RendererCL<T, bucketT>::AccumulatorToFinalImage(vector<v4F>& pixel
template <typename T, typename bucketT>
EmberStats RendererCL<T, bucketT>::Iterate(size_t iterCount, size_t temporalSample)
{
bool b = true;
EmberStats stats;//Do not record bad vals with with GPU. If the user needs to investigate bad vals, use the CPU.
static std::string loc = __FUNCTION__;
bool& b = stats.m_Success;
//Only need to do this once on the beginning of a new render. Last iter will always be 0 at the beginning of a full render or temporal sample.
if (m_LastIter == 0)
@ -868,15 +868,10 @@ EmberStats RendererCL<T, bucketT>::Iterate(size_t iterCount, size_t temporalSamp
dev->m_Calls = 0;
b = RunIter(iterCount, temporalSample, stats.m_Iters);
if (!b || stats.m_Iters == 0)//If no iters were executed, something went catastrophically wrong.
m_Abort = true;
stats.m_IterMs = m_IterTimer.Toc();
}
else
{
m_Abort = true;
ErrorStr(loc, "Iiteration failed", nullptr);
}
@ -1000,7 +995,7 @@ bool RendererCL<T, bucketT>::RunIter(size_t iterCount, size_t temporalSample, si
auto& wrapper = m_Devices[dev]->m_Wrapper;
intmax_t itersRemaining = 0;
while (b && (atomLaunchesRan.fetch_add(1) + 1 <= launches) && ((itersRemaining = atomItersRemaining.load()) > 0) && !m_Abort)
while (b && (atomLaunchesRan.fetch_add(1) + 1 <= launches) && ((itersRemaining = atomItersRemaining.load()) > 0) && success && !m_Abort)
{
//Check if the user wanted to suspend the process.
while (Paused())
@ -1053,7 +1048,6 @@ bool RendererCL<T, bucketT>::RunIter(size_t iterCount, size_t temporalSample, si
1)))
{
success = false;
m_Abort = true;
ErrorStr(loc, "Error running iteration program", m_Devices[dev].get());
atomLaunchesRan.fetch_sub(1);
break;
@ -1117,7 +1111,7 @@ bool RendererCL<T, bucketT>::RunIter(size_t iterCount, size_t temporalSample, si
Join(threadVec);
itersRan = atomItersRan.load();
if (m_Devices.size() > 1)//Determine whether/when to sum histograms of secondary devices with the primary.
if (success && m_Devices.size() > 1)//Determine whether/when to sum histograms of secondary devices with the primary.
{
if (((TemporalSamples() == 1) || (temporalSample == TemporalSamples() - 1)) &&//If there are no temporal samples (not animating), or the current one is the last... (probably doesn't matter anymore since we never use multiple renders for a single frame when animating, instead each frame gets its own renderer).
((m_LastIter + itersRan) >= ItersPerTemporalSample()))//...and the required number of iters for that sample have completed...
@ -1270,7 +1264,6 @@ eRenderStatus RendererCL<T, bucketT>::RunDensityFilter()
//t2.Tic();
if (b && !(b = RunDensityFilterPrivate(kernelIndex, gridW, gridH, blockSizeW, blockSizeH, chunkSizeW, chunkSizeH, colChunkPass, rowChunkPass)))
{
m_Abort = true;
ErrorStr(loc, "Running DE filter program for row chunk "s + std::to_string(rowChunkPass) + ", col chunk "s + std::to_string(colChunkPass) + " failed", m_Devices[0].get());
}

View File

@ -58,7 +58,7 @@
<enum>QFrame::NoFrame</enum>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;Fractorium 1.0.0.12&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;A Qt-based fractal flame editor which uses a C++ re-write of the flam3 algorithm named Ember and a GPU capable version named EmberCL which implements a portion of the cuburn algorithm in OpenCL.&lt;/span&gt;&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;a href=&quot;http://fractorium.com&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;fractorium.com&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;Fractorium 1.0.0.13&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;A Qt-based fractal flame editor which uses a C++ re-write of the flam3 algorithm named Ember and a GPU capable version named EmberCL which implements a portion of the cuburn algorithm in OpenCL.&lt;/span&gt;&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;a href=&quot;http://fractorium.com&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;fractorium.com&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>

View File

@ -700,6 +700,8 @@ void FractoriumFinalRenderDialog::Pause(bool paused)
m_Controller->Pause(false);
ui.FinalRenderPauseButton->setText("Pause");
}
ui.FinalRenderStartButton->setEnabled(!paused);
}
/// <summary>

View File

@ -394,8 +394,9 @@ bool FractoriumEmberController<T>::Render()
{
//if (m_Renderer->Run(m_FinalImage, 0) == RENDER_OK)//Full, non-incremental render for debugging.
bool update = iterBegin || m_Fractorium->m_Settings->ContinuousUpdate();
eRenderStatus result;
if (m_Renderer->Run(m_FinalImage, 0, m_SubBatchCount, update) == eRenderStatus::RENDER_OK)//Force output on iterBegin or if the settings specify to always do it.
if ((result = m_Renderer->Run(m_FinalImage, 0, m_SubBatchCount, update)) == eRenderStatus::RENDER_OK)//Force output on iterBegin or if the settings specify to always do it.
{
//The amount to increment sub batch while rendering proceeds is purely empirical.
//Change later if better values can be derived/observed.
@ -491,7 +492,7 @@ bool FractoriumEmberController<T>::Render()
//}
}
}
else//Something went very wrong, show error report.
else if (result != eRenderStatus::RENDER_ABORT)//If error was returned, something went very wrong, show error report.
{
auto errors = m_Renderer->ErrorReport();
success = false;