Skip to content

Instantly share code, notes, and snippets.

@erichocean
Created August 12, 2010 22:29
Show Gist options
  • Save erichocean/521884 to your computer and use it in GitHub Desktop.
Save erichocean/521884 to your computer and use it in GitHub Desktop.
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