Use task dispatcher provided by user.

pull/216/head
castano 14 years ago
parent 66c9729097
commit a2f0e566c7

@ -30,11 +30,11 @@
namespace nv
{
struct CompressorInterface
{
virtual ~CompressorInterface() {}
virtual void compress(nvtt::AlphaMode alphaMode, uint w, uint h, const float * rgba, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions) = 0;
};
struct CompressorInterface
{
virtual ~CompressorInterface() {}
virtual void compress(nvtt::AlphaMode alphaMode, uint w, uint h, const float * rgba, nvtt::TaskDispatcher * dispatcher, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions) = 0;
};
} // nv namespace

@ -126,7 +126,7 @@ struct CompressorContext
};
// Each task compresses one row.
void CompressorTask(void * data, size_t i)
void CompressorTask(void * data, int i)
{
CompressorContext * d = (CompressorContext *) data;
@ -143,7 +143,7 @@ void CompressorTask(void * data, size_t i)
}
}
void FixedBlockCompressor::compress(nvtt::AlphaMode alphaMode, uint w, uint h, const float * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions)
void FixedBlockCompressor::compress(nvtt::AlphaMode alphaMode, uint w, uint h, const float * data, nvtt::TaskDispatcher * dispatcher, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions)
{
CompressorContext context;
context.alphaMode = alphaMode;
@ -158,12 +158,7 @@ void FixedBlockCompressor::compress(nvtt::AlphaMode alphaMode, uint w, uint h, c
context.compressor = this;
static SequentialTaskDispatcher sequential;
//static AppleTaskDispatcher concurrent;
static OpenMPTaskDispatcher concurrent;
//TaskDispatcher * dispatcher = &sequential;
TaskDispatcher * dispatcher = &concurrent;
SequentialTaskDispatcher sequential;
// Use a single thread to compress small textures.
if (context.bh < 4) dispatcher = &sequential;
@ -182,7 +177,7 @@ void FixedBlockCompressor::compress(nvtt::AlphaMode alphaMode, uint w, uint h, c
void ColorSetCompressor::compress(AlphaMode alphaMode, uint w, uint h, const float * data, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions)
void ColorSetCompressor::compress(AlphaMode alphaMode, uint w, uint h, const float * data, nvtt::TaskDispatcher * dispatcher, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions)
{
const uint bs = blockSize();
const uint bw = (w + 3) / 4;

@ -35,7 +35,7 @@ namespace nv
struct FixedBlockCompressor : public CompressorInterface
{
virtual void compress(nvtt::AlphaMode alphaMode, uint w, uint h, const float * rgba, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions);
virtual void compress(nvtt::AlphaMode alphaMode, uint w, uint h, const float * rgba, nvtt::TaskDispatcher * dispatcher, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions);
virtual void compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output) = 0;
virtual uint blockSize() const = 0;
@ -43,7 +43,7 @@ namespace nv
struct ColorSetCompressor : public CompressorInterface
{
virtual void compress(nvtt::AlphaMode alphaMode, uint w, uint h, const float * rgba, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions);
virtual void compress(nvtt::AlphaMode alphaMode, uint w, uint h, const float * rgba, nvtt::TaskDispatcher * dispatcher, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions);
virtual void compressBlock(ColorSet & set, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output) = 0;
virtual uint blockSize() const = 0;

@ -122,7 +122,7 @@ namespace
void PixelFormatConverter::compress(nvtt::AlphaMode /*alphaMode*/, uint w, uint h, const float * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions)
void PixelFormatConverter::compress(nvtt::AlphaMode /*alphaMode*/, uint w, uint h, const float * data, nvtt::TaskDispatcher * dispatcher, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions)
{
nvDebugCheck (compressionOptions.format == nvtt::Format_RGBA);

@ -31,7 +31,7 @@ namespace nv
{
struct PixelFormatConverter : public CompressorInterface
{
virtual void compress(nvtt::AlphaMode alphaMode, uint w, uint h, const float * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions);
virtual void compress(nvtt::AlphaMode alphaMode, uint w, uint h, const float * data, nvtt::TaskDispatcher * dispatcher, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions);
};
} // nv namespace

@ -56,7 +56,7 @@ static Color32 toRgbe8(float r, float g, float b)
}
void CompressorRGBE::compress(nvtt::AlphaMode /*alphaMode*/, uint w, uint h, const float * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions)
void CompressorRGBE::compress(nvtt::AlphaMode /*alphaMode*/, uint w, uint h, const float * data, nvtt::TaskDispatcher * dispatcher, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions)
{
nvDebugCheck (compressionOptions.format == nvtt::Format_RGBE);

@ -30,7 +30,7 @@ namespace nv
{
struct CompressorRGBE : public CompressorInterface
{
virtual void compress(nvtt::AlphaMode alphaMode, uint w, uint h, const float * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions);
virtual void compress(nvtt::AlphaMode alphaMode, uint w, uint h, const float * data, nvtt::TaskDispatcher * dispatcher, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions);
};
} // nv namespace

@ -64,6 +64,8 @@ Compressor::Compressor() : m(*new Compressor::Private())
m.cuda = NULL;
enableCudaAcceleration(m.cudaSupported);
m.dispatcher = &m.defaultDispatcher;
}
Compressor::~Compressor()
@ -96,6 +98,16 @@ bool Compressor::isCudaAccelerationEnabled() const
return m.cudaEnabled;
}
void Compressor::setTaskDispatcher(TaskDispatcher * disp)
{
if (disp == NULL) {
m.dispatcher = &m.defaultDispatcher;
}
else {
m.dispatcher = disp;
}
}
// Input Options API.
bool Compressor::process(const InputOptions & inputOptions, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const
@ -318,7 +330,7 @@ bool Compressor::Private::compress(AlphaMode alphaMode, int w, int h, int d, int
}
else
{
compressor->compress(alphaMode, w, h, rgba, compressionOptions, outputOptions);
compressor->compress(alphaMode, w, h, rgba, dispatcher, compressionOptions, outputOptions);
}
return true;

@ -30,6 +30,7 @@
#include "nvtt/Compressor.h"
#include "nvtt/cuda/CudaCompressorDXT.h"
#include "nvtt.h"
#include "TaskDispatcher.h"
namespace nv
{
@ -51,18 +52,19 @@ namespace nvtt
void quantize(TexImage & tex, const CompressionOptions::Private & compressionOptions) const;
bool outputHeader(nvtt::TextureType textureType, int w, int h, int d, int mipmapCount, bool isNormalMap, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const;
//bool outputHeader(const InputOptions::Private & inputOptions, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const;
nv::CompressorInterface * chooseCpuCompressor(const CompressionOptions::Private & compressionOptions) const;
nv::CompressorInterface * chooseGpuCompressor(const CompressionOptions::Private & compressionOptions) const;
nv::CompressorInterface * chooseCpuCompressor(const CompressionOptions::Private & compressionOptions) const;
nv::CompressorInterface * chooseGpuCompressor(const CompressionOptions::Private & compressionOptions) const;
bool cudaSupported;
bool cudaEnabled;
bool cudaSupported;
bool cudaEnabled;
nv::AutoPtr<nv::CudaContext> cuda;
nv::AutoPtr<nv::CudaContext> cuda;
TaskDispatcher * dispatcher;
//SequentialTaskDispatcher defaultDispatcher;
ConcurrentTaskDispatcher defaultDispatcher;
};
} // nvtt namespace

@ -10,16 +10,14 @@
// Gran Central Dispatch (GCD/libdispatch)
// http://developer.apple.com/mac/library/documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html
#if NV_OS_DARWIN && defined(HAVE_DISPATCH_H)
#define HAVE_GCD 1
#include <dispatch/dispatch.h>
#endif
#if NV_OS_WIN32 && _MSC_VER >= 1600
#define HAVE_PPL 1
#endif
// Parallel Patterns Library (PPL) is part of Microsoft's concurrency runtime:
// http://msdn.microsoft.com/en-us/library/dd504870.aspx
#if defined(HAVE_PPL)
#if NV_OS_WIN32 && _MSC_VER >= 1600
#define HAVE_PPL 1
#include <array>
//#include <ppl.h>
#endif
@ -35,8 +33,8 @@ namespace nvtt {
struct SequentialTaskDispatcher : public TaskDispatcher
{
virtual void dispatch(Task * task, void * context, size_t count) {
for (size_t i = 0; i < count; i++) {
virtual void dispatch(Task * task, void * context, int count) {
for (int i = 0; i < count; i++) {
task(context, i);
}
}
@ -46,9 +44,9 @@ namespace nvtt {
struct OpenMPTaskDispatcher : public TaskDispatcher
{
virtual void dispatch(Task * task, void * context, size_t count) {
virtual void dispatch(Task * task, void * context, int count) {
#pragma omp parallel for
for (int i = 0; i < int(count); i++) {
for (int i = 0; i < count; i++) {
task(context, i);
}
}
@ -61,9 +59,21 @@ namespace nvtt {
// Task dispatcher using Apple's Grand Central Dispatch.
struct AppleTaskDispatcher : public TaskDispatcher
{
virtual void dispatch(Task * task, void * context, size_t count) {
dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_apply_f(count, q, context, task);
// @@ This is really lame, but I refuse to use size_t in the public API.
struct BlockContext {
Task * task;
void * context;
};
static void block(void * context, size_t id) {
BlockContext * ctx = (BlockContext *)context;
ctx->task(ctx->context, int(id));
}
virtual void dispatch(Task * task, void * context, int count) {
dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
BlockContext blockCtx = { task, context };
dispatch_apply_f(count, q, &blockCtx, block);
}
};
@ -71,42 +81,41 @@ namespace nvtt {
#if defined(HAVE_PPL)
class CountingIterator
{
public:
CountingIterator() : i(0) {}
CountingIterator(const CountingIterator & rhs) : i(0) {}
explicit CountingIterator(int x) : i(x) {}
//const int & base() const;
const int & operator*() const { return i; }
CountingIterator & operator++() { i++; return *this; }
CountingIterator & operator--() { i--; return *this; }
private:
int i;
class CountingIterator
{
public:
CountingIterator() : i(0) {}
CountingIterator(const CountingIterator & rhs) : i(0) {}
explicit CountingIterator(int x) : i(x) {}
const int & operator*() const { return i; }
CountingIterator & operator++() { i++; return *this; }
CountingIterator & operator--() { i--; return *this; }
private:
int i;
};
struct TaskFunctor {
TaskFunctor(Task * task, void * context) : task(task), context(context) {}
void operator()(int & n) const {
task(context, n);
}
Task * task;
void * context;
};
struct TaskFunctor {
TaskFunctor(Task * task, void * context) : task(task), context(context) {}
void operator()(int & n) const {
task(context, n);
}
Task * task;
void * context;
};
// Using Microsoft's concurrency runtime.
// Task dispatcher using Microsoft's concurrency runtime.
struct MicrosoftTaskDispatcher : public TaskDispatcher
{
virtual void dispatch(Task * task, void * context, size_t count)
virtual void dispatch(Task * task, void * context, int count)
{
CountingIterator begin(0);
CountingIterator end((int)count);
TaskFunctor func(task, context);
std::for_each(begin, end, func);
//std::parallel_for_each(begin, end, func);
//parallel_for_each(begin, end, func);
}
};
@ -114,22 +123,35 @@ namespace nvtt {
#if defined(HAVE_TBB)
struct TaskFunctor {
TaskFunctor(Task * task, void * context) : task(task), context(context) {}
void operator()(int & n) const {
task(context, n);
}
Task * task;
void * context;
struct TaskFunctor {
TaskFunctor(Task * task, void * context) : task(task), context(context) {}
void operator()(int & n) const {
task(context, n);
}
Task * task;
void * context;
};
// Task dispatcher using Inte's Thread Building Blocks.
struct IntelTaskDispatcher : public TaskDispatcher
{
virtual void dispatch(Task * task, void * context, size_t count) {
parallel_for(blocked_range<size_t>(0, count, 1), TaskFunctor(task, context));
virtual void dispatch(Task * task, void * context, int count) {
parallel_for(blocked_range<int>(0, count, 1), TaskFunctor(task, context));
}
};
#endif
#if defined(HAVE_OPENMP)
typedef OpenMPTaskDispatcher ConcurrentTaskDispatcher;
#elif defined(HAVE_TBB)
typedef IntelTaskDispatcher ConcurrentTaskDispatcher;
#elif defined(HAVE_PPL)
typedef MicrosoftTaskDispatcher ConcurrentTaskDispatcher;
#elif defined(HAVE_GCD)
typedef AppleTaskDispatcher ConcurrentTaskDispatcher;
#else
typedef SequentialTaskDispatcher ConcurrentTaskDispatcher;
#endif
} // namespace nvtt

@ -125,7 +125,7 @@ CudaCompressor::CudaCompressor(CudaContext & ctx) : m_ctx(ctx)
}
void CudaCompressor::compress(nvtt::AlphaMode alphaMode, uint w, uint h, const float * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions)
void CudaCompressor::compress(nvtt::AlphaMode alphaMode, uint w, uint h, const float * data, nvtt::TaskDispatcher * dispatcher, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions)
{
nvDebugCheck(cuda::isHardwarePresent());

@ -54,7 +54,7 @@ namespace nv
{
CudaCompressor(CudaContext & ctx);
virtual void compress(nvtt::AlphaMode alphaMode, uint w, uint h, const float * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions);
virtual void compress(nvtt::AlphaMode alphaMode, uint w, uint h, const float * data, nvtt::TaskDispatcher * dispatcher, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions);
virtual void setup(cudaArray * image, const nvtt::CompressionOptions::Private & compressionOptions) = 0;
virtual void compressBlocks(uint first, uint count, uint w, uint h, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output) = 0;

@ -26,8 +26,6 @@
#ifndef NVTT_H
#define NVTT_H
#include <stddef.h> // size_t @@ Use or own define?
// Function linkage
#if NVTT_SHARED
@ -333,11 +331,11 @@ namespace nvtt
NVTT_API void setUserVersion(int version);
};
typedef void Task(void * context, size_t id);
typedef void Task(void * context, int id);
struct TaskDispatcher
{
virtual void dispatch(Task * task, void * context, size_t count) = 0;
virtual void dispatch(Task * task, void * context, int count) = 0;
};
/// Context.

Loading…
Cancel
Save