Created
August 12, 2010 22:29
-
-
Save erichocean/521884 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 43ed2e9f37751e8ab43a4036186638f19fdcdf7e Mon Sep 17 00:00:00 2001 | |
From: Erich Ocean <[email protected]> | |
Date: Thu, 12 Aug 2010 15:25:52 -0700 | |
Subject: [PATCH] initial ptex support | |
--- | |
src/liboslexec/master.cpp | 8 ++++ | |
src/liboslexec/optexture.cpp | 95 ++++++++++++++++++++++++++++++++++++++++++ | |
src/liboslexec/osl_ptex.h | 66 +++++++++++++++++++++++++++++ | |
src/liboslexec/oslexec_pvt.h | 25 +++++++++++ | |
src/liboslexec/oslops.h | 8 ++++ | |
5 files changed, 202 insertions(+), 0 deletions(-) | |
create mode 100644 src/liboslexec/osl_ptex.h | |
diff --git a/src/liboslexec/master.cpp b/src/liboslexec/master.cpp | |
index 6989d6b..39ae697 100644 | |
--- a/src/liboslexec/master.cpp | |
+++ b/src/liboslexec/master.cpp | |
@@ -239,6 +239,11 @@ static OpNameEntry op_name_entries[] = { | |
{ "ge", OP_ge }, | |
{ "getattribute", OP_getattribute }, | |
{ "getmessage", OP_getmessage }, | |
+#ifdef OSL_PTEX | |
+ { "getptexturefaceinfo", OP_getptexturefaceinfo }, | |
+ { "getptextureinfo", OP_getptextureinfo }, | |
+ { "getptexturemetadata", OP_getptexturemetadata }, | |
+#endif | |
{ "gettextureinfo", OP_gettextureinfo }, | |
{ "gt", OP_gt }, | |
{ "hair_diffuse", OP_hair_diffuse }, | |
@@ -285,6 +290,9 @@ static OpNameEntry op_name_entries[] = { | |
{ "pow", OP_pow }, | |
{ "printf", OP_printf }, | |
{ "psnoise", OP_psnoise }, | |
+#ifdef OSL_PTEX | |
+ { "ptexture", OP_ptexture }, | |
+#endif | |
{ "radians", OP_radians }, | |
{ "reflect", OP_reflect }, | |
{ "reflection", OP_reflection }, | |
diff --git a/src/liboslexec/optexture.cpp b/src/liboslexec/optexture.cpp | |
index d233428..b614a6a 100644 | |
--- a/src/liboslexec/optexture.cpp | |
+++ b/src/liboslexec/optexture.cpp | |
@@ -327,6 +327,101 @@ DECLOP (OP_gettextureinfo) | |
} | |
+#ifdef OSL_PTEX | |
+DECLOP (OP_ptexture) | |
+{ | |
+ // Grab the required arguments: result, filename, filter, sharp, face, s, t, sw1, tw1, sw2, tw2 | |
+ DASSERT (nargs >= 11); | |
+ Symbol &Result (exec->sym (args[0])); | |
+ Symbol &Filename (exec->sym (args[1])); | |
+ Symbol &Filter (exec->sym (args[2])); | |
+ DASSERT (Filename.typespec().is_string() && Filter.typespec().is_string()); | |
+ DASSERT (!Filename.typespec().is_varying() && !Filter.typespec().is_varying()); | |
+ Symbol &Sharp (exec->sym (args[3])); | |
+ DASSERT (Sharp.typespec().is_float()); | |
+ DASSERT (!Sharp.typespec().is_varying()); | |
+ Symbol &Face (exec->sym (args[4])); | |
+ DASSERT (Face.typespec().is_int()); | |
+ Symbol &S (exec->sym (args[5])); | |
+ Symbol &T (exec->sym (args[6])); | |
+ DASSERT (S.typespec().is_float() && T.typespec().is_float()); | |
+ Symbol &Sw1 (exec->sym (args[ 7])); | |
+ Symbol &Tw1 (exec->sym (args[ 8])); | |
+ Symbol &Sw2 (exec->sym (args[ 9])); | |
+ Symbol &Tw2 (exec->sym (args[10])); | |
+ DASSERT (Sw1.typespec().is_float()); | |
+ DASSERT (Tw1.typespec().is_float()); | |
+ DASSERT (Sw2.typespec().is_float()); | |
+ DASSERT (Tw2.typespec().is_float()); | |
+ | |
+ exec->adjust_varying (Result, true); | |
+ | |
+ float zero = 0.0f; | |
+ VaryingRef<float> result ((float *)Result.data(), Result.step()); | |
+ VaryingRef<int> face ((int *)Face.data(), Face.step()); | |
+ VaryingRef<float> s ((float *)S.data(), S.step()); | |
+ VaryingRef<float> t ((float *)T.data(), T.step()); | |
+ VaryingRef<float> sw1 ((float *)Sw1.data(), Sw1.step()); | |
+ VaryingRef<float> tw1 ((float *)Tw1.data(), Tw1.step()); | |
+ VaryingRef<float> sw2 ((float *)Sw2.data(), Sw2.step()); | |
+ VaryingRef<float> tw2 ((float *)Tw2.data(), Tw2.step()); | |
+ ustring filename = *(ustring *)Filename.data(); | |
+ ustring filter = *(ustring *)Filter.data(); | |
+ float sharp = *(float *)Sharp.data(); | |
+ | |
+ VaryingRef<int> firstchannel (NULL); | |
+ VaryingRef<float> width (NULL); | |
+ VaryingRef<float> blur (NULL); | |
+ VaryingRef<ustring> wrap (NULL); | |
+ VaryingRef<float> alpha (NULL); | |
+ Symbol* Alpha = NULL; | |
+ int nchannels = Result.typespec().simpletype().aggregate; | |
+ | |
+ for (int a = 11; a < nargs; ++a) { | |
+ Symbol &Name (exec->sym (args[a])); | |
+ DASSERT (Name.typespec().is_string() && | |
+ "optional ptexture token must be a string"); | |
+ DASSERT (a+1 < nargs && "malformed argument list for ptexture"); | |
+ if (Name.is_varying()) { | |
+ exec->warning ("optional ptexture argument is a varying string! Seems pretty fishy."); | |
+ } | |
+ ++a; // advance to next argument | |
+ Symbol &Val (exec->sym (args[a])); | |
+ TypeDesc valtype = Val.typespec().simpletype (); | |
+ ustring name = * (ustring *) Name.data(); | |
+ if (name == Strings::width && valtype == TypeDesc::FLOAT) { | |
+ width.init ((float *)Val.data(), Val.step()); | |
+ } else if (name == Strings::blur && valtype == TypeDesc::FLOAT) { | |
+ blur.init ((float *)Val.data(), Val.step()); | |
+ } else if (name == Strings::wrap && valtype == TypeDesc::STRING) { | |
+ wrap.init ((ustring *)Val.data(), Val.step()); | |
+ } else if (name == Strings::firstchannel && valtype == TypeDesc::INT) { | |
+ firstchannel.init ((int *)Val.data(), Val.step()); | |
+ } else if (name == Strings::alpha && valtype == TypeDesc::FLOAT) { | |
+ exec->adjust_varying (Val, true); | |
+ alpha.init ((float *)Val.data(), Val.step()); | |
+ Alpha = &Val; | |
+ } else { | |
+ exec->error ("Unknown ptexture optional argument: \"%s\", <%s> (%s:%d)", | |
+ name.c_str(), | |
+ valtype.c_str(), | |
+ exec->op().sourcefile().c_str(), | |
+ exec->op().sourceline()); | |
+ } | |
+ } | |
+ | |
+ if (alpha) | |
+ nchannels += 1; | |
+ | |
+ PtexSystem *ptexsys = exec->ptexsystem (); | |
+ PtexFilter *filter; | |
+ if (!ptexsys->get_filter(Filename, PtexFilter::Options(PtexSystem::filter_type(filter), false, sharp), &filter)) | |
+ exec->error ("ptexture lookup failed (%s:%d): %s", | |
+ exec->op().sourcefile().c_str(), | |
+ exec->op().sourceline(), | |
+ err.c_str()); | |
+} | |
+ | |
}; // namespace pvt | |
}; // namespace OSL | |
diff --git a/src/liboslexec/osl_ptex.h b/src/liboslexec/osl_ptex.h | |
new file mode 100644 | |
index 0000000..a09afce | |
--- /dev/null | |
+++ b/src/liboslexec/osl_ptex.h | |
@@ -0,0 +1,66 @@ | |
+#ifndef OSL_PTEX_H | |
+#define OSL_PTEX_H | |
+ | |
+#include <string> | |
+#include <map> | |
+ | |
+#include "oslexec.h" | |
+#include "Ptexture.h" | |
+ | |
+#ifdef OSL_NAMESPACE | |
+namespace OSL_NAMESPACE { | |
+#endif | |
+ | |
+namespace OSL { | |
+ | |
+class PtexSystem | |
+{ | |
+public: | |
+ PtexSystem(PtexCache *ptexcache) : m_ptexcache(ptexcache) { } | |
+ | |
+ PtexCache *ptexcache() { return m_ptexcache; } | |
+ | |
+ bool get_filter(std::string const &name, PtexFilter::Options const &options, PtexFilter **result) { | |
+ PtexFilterKey k(name, options); | |
+ std::map<PtexFilterKey, PtexFilter*>::const_iterator f = m_filtercache.find(k); | |
+ | |
+ if (f != m_filtercache.end()) { | |
+ *result = f->second; | |
+ return true; | |
+ } else { | |
+ Ptex::String s; | |
+ PtexTexture *tex = m_ptexcache->get(name.c_str(), s); | |
+ if (!tex) | |
+ return false; | |
+ | |
+ // XXX release texture? | |
+ PtexFilter *filter = PtexFilter::getFilter(tex, options); | |
+ m_filtercache.insert(PtexFilterKey(name, options), filter); | |
+ *result = filter; | |
+ return true; | |
+ } | |
+ } | |
+ | |
+ ~PtexSystem() { | |
+ for (std::map<PtexFilterKey, PtexFilter*>::const_iterator i = m_filtercache.begin(); | |
+ i != m_filtercache.end(); | |
+ ++i) { | |
+ i->second->release(); | |
+ } | |
+ m_ptexcache->release(); | |
+ } | |
+private: | |
+ PtexCache *m_ptexcache; | |
+ | |
+ struct PtexFilterKey { | |
+ std::string name; | |
+ PtexFilter::Options options; | |
+ PtexFilterKey(std::string const &_name, PtexFilter::Options const &_options) : name(_name), options(_options) { } | |
+ }; | |
+ | |
+ std::map<PtexFilterKey, PtexFilter*> m_filtercache; | |
+}; | |
+ | |
+} // namespace OSL | |
+ | |
+#endif | |
diff --git a/src/liboslexec/oslexec_pvt.h b/src/liboslexec/oslexec_pvt.h | |
index dfcfca6..74eb215 100644 | |
--- a/src/liboslexec/oslexec_pvt.h | |
+++ b/src/liboslexec/oslexec_pvt.h | |
@@ -43,6 +43,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
#include "oslexec.h" | |
#include "oslclosure.h" | |
#include "osl_pvt.h" | |
+#ifdef OSL_PTEX | |
+#include "osl_ptex.h" | |
+#endif | |
#include "constantpool.h" | |
using namespace OSL; | |
using namespace OSL::pvt; | |
@@ -433,9 +436,16 @@ private: | |
class ShadingSystemImpl : public ShadingSystem | |
{ | |
public: | |
+#ifdef OSL_PTEX | |
+ ShadingSystemImpl (RendererServices *renderer=NULL, | |
+ TextureSystem *texturesystem=NULL, | |
+ ErrorHandler *err=NULL, | |
+ PtexSystem *ptexsystem=NULL); | |
+#else | |
ShadingSystemImpl (RendererServices *renderer=NULL, | |
TextureSystem *texturesystem=NULL, | |
ErrorHandler *err=NULL); | |
+#endif | |
virtual ~ShadingSystemImpl (); | |
virtual bool attribute (const std::string &name, TypeDesc type, const void *val); | |
@@ -507,6 +517,12 @@ public: | |
/// | |
TextureSystem *texturesys () const { return m_texturesys; } | |
+#ifdef OSL_PTEX | |
+ /// Return a pointer to the Ptex cache. | |
+ /// | |
+ PtexSystem *ptexsystem () const { return m_ptexsystem; } | |
+#endif | |
+ | |
/// Round up to an 8-byte boundary. | |
/// FIXME -- do we want to round up to 16-byte boundaries for | |
/// hardware SIMD reasons? | |
@@ -576,6 +592,9 @@ private: | |
RendererServices *m_renderer; ///< Renderer services | |
TextureSystem *m_texturesys; ///< Texture system | |
+#ifdef OSL_PTEX | |
+ PtexSystem *m_ptexsystem; ///< Ptex system | |
+#endif | |
ErrorHandler *m_err; ///< Error handler | |
std::list<std::string> m_errseen, m_warnseen; | |
@@ -1008,6 +1027,12 @@ public: | |
/// | |
TextureSystem *texturesys () const { return m_shadingsys->texturesys(); } | |
+#ifdef OSL_PTEX | |
+ /// Get a pointer to the PtexSystem for this execution. | |
+ /// | |
+ PtexCache *ptexcache () const { return m_shadingsys->ptexcache(); } | |
+#endif | |
+ | |
/// Get the 4x4 matrix that transforms points from the named 'from' | |
/// coordinate system to "common" space for the given shading point. | |
void get_matrix (Matrix44 &result, ustring from, int whichpoint=0); | |
diff --git a/src/liboslexec/oslops.h b/src/liboslexec/oslops.h | |
index d07bec7..39d7f38 100644 | |
--- a/src/liboslexec/oslops.h | |
+++ b/src/liboslexec/oslops.h | |
@@ -132,6 +132,11 @@ DECLOP (OP_ge); | |
DECLOP (OP_getattribute); | |
DECLOP (OP_getmessage); | |
DECLOP (OP_gettextureinfo); | |
+#ifdef OSL_PTEX | |
+DECLOP (OP_getptexturefaceinfo); | |
+DECLOP (OP_getptextureinfo); | |
+DECLOP (OP_getptexturemetadata); | |
+#endif | |
DECLOP (OP_gt); | |
DECLOP (OP_hair_diffuse); | |
DECLOP (OP_hair_specular); | |
@@ -182,6 +187,9 @@ DECLOP (OP_point); | |
DECLOP (OP_pow); | |
DECLOP (OP_printf); | |
DECLOP (OP_psnoise); | |
+#ifdef OSL_PTEX | |
+DECLOP (OP_ptexture); | |
+#endif | |
DECLOP (OP_radians); | |
//DECLOP (OP_random); | |
//DECLOP (OP_raylevel); | |
-- | |
1.7.0.4 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment