18 #include "precompiled.h"
34 #include "nvtt/nvtt.h"
50 size_t off =
buffer.size();
52 memcpy(&
buffer[off], data, size);
81 #endif // CONFIG2_NVTT
102 #define EL(x) int el_##x = XeroFile.GetElementID(#x)
103 #define AT(x) int at_##x = XeroFile.GetAttributeID(#x)
122 LOGERROR(L
"Invalid texture settings file \"%ls\" (unrecognised root element)", path.
string().c_str());
126 std::auto_ptr<SettingsFile> settings(
new SettingsFile());
130 if (child.GetNodeName() == el_file)
136 if (attr.Name == at_pattern)
138 p.
pattern = attr.Value.FromUTF8();
140 else if (attr.Name == at_format)
145 else if (v ==
"dxt3")
147 else if (v ==
"dxt5")
149 else if (v ==
"rgba")
152 LOGERROR(L
"Invalid attribute value <file format='%hs'>", v.c_str());
154 else if (attr.Name == at_mipmap)
159 else if (v ==
"false")
162 LOGERROR(L
"Invalid attribute value <file mipmap='%hs'>", v.c_str());
164 else if (attr.Name == at_normal)
169 else if (v ==
"false")
172 LOGERROR(L
"Invalid attribute value <file normal='%hs'>", v.c_str());
174 else if (attr.Name == at_alpha)
179 else if (v ==
"player")
181 else if (v ==
"transparency")
184 LOGERROR(L
"Invalid attribute value <file alpha='%hs'>", v.c_str());
186 else if (attr.Name == at_filter)
191 else if (v ==
"triangle")
193 else if (v ==
"kaiser")
196 LOGERROR(L
"Invalid attribute value <file filter='%hs'>", v.c_str());
198 else if (attr.Name == at_kaiserwidth)
202 else if (attr.Name == at_kaiseralpha)
206 else if (attr.Name == at_kaiserstretch)
216 settings->patterns.push_back(p);
220 return settings.release();
236 for (
size_t i = 0; i < settingsFiles.size(); ++i)
238 for (
size_t j = 0; j < settingsFiles[i]->patterns.size(); ++j)
240 Match p = settingsFiles[i]->patterns[j];
281 ENSURE(nvtt::version() >= NVTT_VERSION);
324 if (
m_VFS->LoadFile(src, file, fileSize) < 0)
326 LOGERROR(L
"Failed to load texture \"%ls\"", src.
string().c_str());
333 LOGERROR(L
"Failed to decode texture \"%ls\"", src.
string().c_str());
344 LOGERROR(L
"Failed to convert grayscale texture \"%ls\" - only RGB textures are currently supported", src.
string().c_str());
351 LOGERROR(L
"Failed to transform texture \"%ls\"", src.
string().c_str());
362 for (
size_t i = 0; i < tex.
w * tex.
h; ++i)
364 if (data[i*4+3] != 0xFF)
375 request->dest = dest;
376 request->texture = texture;
380 request->inputOptions.setMipmapGeneration(settings.
mipmap ==
MIP_TRUE);
383 request->inputOptions.setAlphaMode(nvtt::AlphaMode_Transparency);
385 request->inputOptions.setAlphaMode(nvtt::AlphaMode_None);
387 request->isDXT1a =
false;
391 request->compressionOptions.setFormat(nvtt::Format_RGBA);
393 request->compressionOptions.setPixelFormat(32, 0xFF, 0xFF00, 0xFF0000, 0xFF000000u);
398 request->compressionOptions.setFormat(nvtt::Format_DXT1);
402 request->compressionOptions.setFormat(nvtt::Format_DXT1a);
403 request->isDXT1a =
true;
407 request->compressionOptions.setFormat(nvtt::Format_DXT3);
411 request->compressionOptions.setFormat(nvtt::Format_DXT5);
415 request->inputOptions.setMipmapFilter(nvtt::MipmapFilter_Box);
417 request->inputOptions.setMipmapFilter(nvtt::MipmapFilter_Triangle);
419 request->inputOptions.setMipmapFilter(nvtt::MipmapFilter_Kaiser);
422 request->inputOptions.setNormalMap(
true);
426 request->inputOptions.setWrapMode(nvtt::WrapMode_Mirror);
428 request->compressionOptions.setQuality(
m_HighQuality ? nvtt::Quality_Production : nvtt::Quality_Fastest);
433 request->inputOptions.setTextureLayout(nvtt::TextureType_2D, tex.
w, tex.
h);
434 request->inputOptions.setMipmapData(
tex_get_data(&tex), tex.
w, tex.
h);
449 LOGERROR(L
"Failed to convert texture \"%ls\" (NVTT not available)", src.
string().c_str());
457 shared_ptr<ConversionResult> result;
482 size_t size = result->output.buffer.size();
485 memcpy(file.get(), &result->output.buffer[0], size);
486 if (
m_VFS->CreateFile(result->dest, file, size) < 0)
494 texture = result->texture;
499 #else // #if CONFIG2_NVTT
536 shared_ptr<ConversionRequest> request = textureConverter->
m_RequestQueue.front();
542 result->dest = request->dest;
543 result->texture = request->texture;
545 request->outputOptions.setOutputHandler(&result->output);
553 nvtt::Compressor compressor;
554 result->ret = compressor.process(request->inputOptions, request->compressionOptions, request->outputOptions);
563 if (request->isDXT1a && result->ret && result->output.buffer.size() > 80)
564 result->output.buffer[80] |= 1;
#define PROFILE2_EVENT(name)
Record the named event at the current time.
#define UNUSED(param)
mark a function parameter as unused and avoid the corresponding compiler warning. ...
bool Poll(CTexturePtr &texture, VfsPath &dest, bool &ok)
Returns the result of a successful ConvertTexture call.
std::deque< shared_ptr< ConversionResult > > m_ResultQueue
PSRETURN Load(const PIVFS &vfs, const VfsPath &filename)
Load from an XML file (with invisible XMB caching).
#define XERO_ITER_ATTR(parent_element, attribute)
Status tex_transform_to(Tex *t, size_t new_flags)
Change <t>'s pixel format (2nd version) (note: this is equivalent to tex_transform(t, t->flags^new_flags).
const PSRETURN PSRETURN_OK
static const uintptr_t maxSectorSize
flags & TEX_DXT is a field indicating compression.
indicates the image contains an alpha channel.
SettingsFile * LoadSettings(const VfsPath &path) const
Load a texture conversion settings XML file.
indicates the image is 8bpp greyscale.
Texture conversion settings.
#define XERO_ITER_EL(parent_element, child_element)
int match_wildcard(const wchar_t *s, const wchar_t *w)
see if string matches pattern.
pthread_mutex_t m_WorkerMutex
void Hash(MD5 &hash)
Append this object's state to the given hash.
indicates B and R pixel components are exchanged.
static void * RunThread(void *data)
virtual void beginImage(int size, int width, int height, int depth, int face, int miplevel)
LIB_API void debug_SetThreadName(const char *name)
inform the debugger of the current thread's name.
void SDL_DestroySemaphore(SDL_sem *sem)
#define ENSURE(expr)
ensure the expression <expr> evaluates to non-zero.
#define PROFILE2(region)
Starts timing from now until the end of the current scope.
void Update(const u8 *data, size_t len)
int pthread_create(pthread_t *thread_id, const void *attr, void *(*func)(void *), void *arg)
Representation of <File> line from settings XML file.
nvtt::OutputOptions outputOptions
New profiler (complementing the older CProfileManager)
void RegisterCurrentThread(const std::string &name)
Call in any thread to enable the profiler in that thread.
const String & string() const
u8 * tex_get_data(const Tex *t)
rationale: since Tex is a struct, its fields are accessible to callers.
int pthread_mutex_lock(pthread_mutex_t *m)
nvtt::InputOptions inputOptions
nvtt::CompressionOptions compressionOptions
int pthread_mutex_init(pthread_mutex_t *m, const pthread_mutexattr_t *)
Representation of settings XML file.
stores all data describing an image.
bool IsBusy()
Returns whether there is currently a queued request from ConvertTexture().
SDL_sem * SDL_CreateSemaphore(int cnt)
BufferOutputHandler output
static Status AllocateAligned(shared_ptr< T > &p, size_t size, size_t alignment=cacheLineSize)
XMBElement GetRoot() const
int pthread_mutex_unlock(pthread_mutex_t *m)
Texture conversion helper class.
Result from worker thread.
int pthread_join(pthread_t thread, void **value_ptr)
~CTextureConverter()
Destroy texture converter and wait to shut down worker thread.
std::string GetAttributeString(const int ID) const
int pthread_mutex_destroy(pthread_mutex_t *m)
int SDL_SemPost(SDL_sem *sem)
virtual bool writeData(const void *data, int size)
void RecordSyncMarker()
Non-main threads should call this occasionally, especially if it's been a long time since their last ...
Request for worker thread to process.
Output handler to collect NVTT's output into a simplistic buffer.
int SDL_SemWait(SDL_sem *sem)
size_t flags
see TexFlags and "Format Conversion" in docs.
Status tex_decode(const shared_ptr< u8 > &data, size_t dataSize, Tex *t)
decode an in-memory texture file into texture object.
std::deque< shared_ptr< ConversionRequest > > m_RequestQueue
void tex_free(Tex *t)
free all resources associated with the image and make further use of it impossible.
bool ConvertTexture(const CTexturePtr &texture, const VfsPath &src, const VfsPath &dest, const Settings &settings)
Begin converting a texture, using the given settings.
Settings ComputeSettings(const std::wstring &filename, const std::vector< SettingsFile * > &settingsFiles) const
Match a sequence of settings files against a given texture filename, and return the resulting setting...
CTextureConverter(PIVFS vfs, bool highQuality)
Construct texture converter, for use with files in the given vfs.
shared_ptr< CTexture > CTexturePtr