[Bf-blender-cvs] [9e50469] cycles-ptex-06: Checkpoint
Nicholas Bishop
noreply at git.blender.org
Thu Jan 15 20:13:19 CET 2015
Commit: 9e5046980fbbf0f9c6884d13f8fa792f27104806
Author: Nicholas Bishop
Date: Tue Jan 13 10:42:03 2015 +0100
Branches: cycles-ptex-06
https://developer.blender.org/rB9e5046980fbbf0f9c6884d13f8fa792f27104806
Checkpoint
===================================================================
M intern/cycles/blender/blender_mesh.cpp
M intern/cycles/kernel/kernel_textures.h
M intern/cycles/kernel/svm/svm_image.h
M intern/cycles/render/image.cpp
M intern/cycles/render/image.h
M intern/cycles/render/scene.h
===================================================================
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index 561a4d0..60e9fcb 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -430,18 +430,29 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
float3 *fdata = attr->data_float3();
size_t i = 0;
+ b_mesh.tessfaces.begin(f);
for(l->data.begin(t); t != l->data.end(); ++t, ++i) {
+ const float ptex_face_id = (float)f->ptex_face_index();
+
fdata[0] = get_float3(t->uv1());
fdata[1] = get_float3(t->uv2());
fdata[2] = get_float3(t->uv3());
+ fdata[0].z = (float)ptex_face_id;
+ fdata[1].z = (float)ptex_face_id;
+ fdata[2].z = (float)ptex_face_id;
fdata += 3;
if(nverts[i] == 4) {
fdata[0] = get_float3(t->uv1());
fdata[1] = get_float3(t->uv3());
fdata[2] = get_float3(t->uv4());
+ fdata[0].z = (float)ptex_face_id;
+ fdata[1].z = (float)ptex_face_id;
+ fdata[2].z = (float)ptex_face_id;
fdata += 3;
}
+
+ ++f;
}
}
diff --git a/intern/cycles/kernel/kernel_textures.h b/intern/cycles/kernel/kernel_textures.h
index 374dc6d..ca2da1f 100644
--- a/intern/cycles/kernel/kernel_textures.h
+++ b/intern/cycles/kernel/kernel_textures.h
@@ -71,6 +71,9 @@ KERNEL_TEX(float, texture_float, __lookup_table)
/* sobol */
KERNEL_TEX(uint, texture_uint, __sobol_directions)
+/* ptex */
+KERNEL_TEX(uint, texture_uint, __ptex_table)
+
/* full-float image */
KERNEL_IMAGE_TEX(float4, texture_image_float4, __tex_image_float_000)
KERNEL_IMAGE_TEX(float4, texture_image_float4, __tex_image_float_001)
diff --git a/intern/cycles/kernel/svm/svm_image.h b/intern/cycles/kernel/svm/svm_image.h
index 9948a19..6cafa52 100644
--- a/intern/cycles/kernel/svm/svm_image.h
+++ b/intern/cycles/kernel/svm/svm_image.h
@@ -354,6 +354,37 @@ ccl_device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y,
#endif
+// Adapted from GPU Pro 4 Listing 2.2
+ccl_device float2 ptex_compute_uv(uint face_id,
+ float2 face_uv,
+ uint nlog2,
+ uint tex_width,
+ uint tex_height,
+ uint res_offset,
+ uint row_offset,
+ uint border_size)
+{
+ float face_width = 1 << nlog2;
+ // TODO
+ float face_height = face_width;
+ float bordered_face_width = face_width + 2 * border_size;
+ float bordered_face_height = bordered_face_width;
+
+ int faces_per_row = (int)tex_width / (int)bordered_face_width;
+ int face_index_in_block = face_id - res_offset;
+
+ float2 face_origin =
+ make_float2((face_index_in_block % faces_per_row) * bordered_face_width,
+ (face_index_in_block / faces_per_row) * bordered_face_height +
+ row_offset);
+
+ float2 uv = make_float2(face_width, face_height) * face_uv;
+ uv += make_float2(border_size, border_size);
+ uv += face_origin;
+
+ return uv / make_float2(tex_width, tex_height);
+}
+
ccl_device void svm_node_tex_image(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
{
uint id = node.y;
@@ -363,7 +394,35 @@ ccl_device void svm_node_tex_image(KernelGlobals *kg, ShaderData *sd, float *sta
float3 co = stack_load_float3(stack, co_offset);
uint use_alpha = stack_valid(alpha_offset);
- float4 f = svm_image_texture(kg, id, co.x, co.y, srgb, use_alpha);
+
+ // TODO: test hacks for Ptex
+ uint face_id = (uint)co[2];
+ uint offset = kernel_tex_fetch(__ptex_table, id);
+ float tex_width = (float)kernel_tex_fetch(__ptex_table, offset);
+ offset++;
+ float tex_height = (float)kernel_tex_fetch(__ptex_table, offset);
+ offset++;
+ offset += 3 * face_id;
+ uint origin_x = kernel_tex_fetch(__ptex_table, offset);
+ offset++;
+ uint origin_y = kernel_tex_fetch(__ptex_table, offset);
+ offset++;
+ uint ures = kernel_tex_fetch(__ptex_table, offset);
+ offset++;
+ uint vres = kernel_tex_fetch(__ptex_table, offset);
+ offset++;
+
+ float xco = (float)origin_x + co.x * ures;
+ float yco = (float)origin_y + co.y * ures;
+
+ float uco = (float)xco / tex_width;
+ float vco = (float)yco / tex_height;
+
+ float4 f = svm_image_texture(kg, id, uco, vco, srgb, use_alpha);
+ f.x = co[0];
+ f.y = co[1];
+ f.z = 0;
+ //float4 f = svm_image_texture(kg, id, co.x, co.y, srgb, use_alpha);
if(stack_valid(out_offset))
stack_store_float3(stack, out_offset, make_float3(f.x, f.y, f.z));
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index 61a0a81..ef69ba0 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -27,8 +27,182 @@
#include <OSL/oslexec.h>
#endif
+#ifdef WITH_PTEX
+#include <Ptexture.h>
+#endif
+
CCL_NAMESPACE_BEGIN
+struct PtexXY {
+ uint x, y;
+ uint ures, vres;
+};
+
+typedef std::map<int, PtexXY> PtexCoordMap;
+
+struct PtexPackedTexture {
+ PtexPackedTexture() : width(0), height(0) {}
+
+ vector<uint8_t> texels;
+
+ PtexCoordMap face_coord_map;
+
+ int width;
+ int height;
+
+ int num_channels;
+
+ void test_write() {
+ // Quick test to visually examine the packed output
+ const char *filename = "/tmp/packed.png";
+ ImageOutput *out = ImageOutput::create(filename);
+ if (out) {
+ ImageSpec spec(width, height, num_channels, TypeDesc::UINT8);
+ out->open(filename, spec);
+ out->write_image(TypeDesc::UINT8, texels.data());
+ std::cout << "ptex test written: " << filename << std::endl;
+ out->close();
+ }
+ }
+};
+
+struct OrdVal {
+ vector<int> face_ids;
+ int elem_width;
+ int elem_per_row;
+ int num_rows;
+ int ures, vres;
+};
+
+static int ptex_data_type_size_in_bytes(const Ptex::DataType dt)
+{
+ switch (dt) {
+ case Ptex::dt_uint8:
+ return 1;
+ case Ptex::dt_uint16:
+ return 2;
+ case Ptex::dt_half:
+ return 2;
+ case Ptex::dt_float:
+ return 4;
+ }
+
+ // Error
+ return 0;
+}
+
+// TODO
+static bool ptex_pack(PtexPackedTexture *output, const char *path,
+ const int width, PtexCache *ptex_cache) {
+ Ptex::String error;
+ PtexPtr<PtexTexture> r(ptex_cache->get(path, error));
+
+ if(!r) {
+ std::cerr << error.c_str() << std::endl;
+ return false;
+ }
+
+ // TODO: for now packing all faces as squares
+
+ // Sorted, res -> face_id array. int8_t matches Ptex api
+
+ typedef std::map<int, OrdVal> Ord;
+ Ord ord;
+
+ const uint border = 1;
+
+ const int num_faces = r->numFaces();
+ for (int face_index = 0; face_index < num_faces; face_index++) {
+ const Ptex::FaceInfo &face_info = r->getFaceInfo(face_index);
+ const Ptex::Res &res = face_info.res;
+ const int larger = std::max(res.u(), res.v());
+ if (ord.find(larger) == ord.end()) {
+ ord[larger] = OrdVal();
+ }
+
+ ord[larger].face_ids.push_back(face_index);
+
+ ord[larger].ures = res.u() + 2 * border;
+ ord[larger].vres = res.v() + 2 * border;
+ }
+
+ // TODO: for now only packing mipmap level zero
+
+ // Calc size
+ output->width = width;
+ output->height = 0;
+ for (Ord::iterator iter = ord.begin(); iter != ord.end(); ++iter) {
+ OrdVal &val = iter->second;
+ const int res = iter->first;
+
+ val.elem_width = border + res + border;
+ val.elem_per_row = output->width / val.elem_width;
+ const int num_elem = val.face_ids.size();
+
+ val.num_rows = num_elem / val.elem_per_row;
+ if ((num_elem % val.elem_per_row) != 0) {
+ val.num_rows += 1;
+ }
+
+ output->height += val.elem_width * val.num_rows;
+ }
+
+
+ const int type_size_in_bytes = ptex_data_type_size_in_bytes(r->dataType());
+ const int texel_size_in_bytes = r->numChannels() * type_size_in_bytes;
+
+ output->num_channels = r->numChannels();
+
+ output->texels.resize(output->width * output->height *
+ texel_size_in_bytes);
+
+ // Copy face textures
+ uint dst_y = 0;
+ bool yinc = false;
+
+ const int dst_stride = output->width * texel_size_in_bytes;
+ for (Ord::const_iterator iter = ord.begin(); iter != ord.end(); ++iter) {
+ const OrdVal &val = iter->second;
+ const int num_elem = val.face_ids.size();
+ int column = 0;
+ uint dst_x = 0;
+
+ for (int i = 0; i < num_elem; i++) {
+ const int face_id = val.face_ids[i];
+
+ PtexXY coord = {dst_x + border, dst_y + border, (uint)val.ures, (uint)val.vres};
+ output->face_coord_map[face_id] = coord;
+
+ const int dst_offset = ((coord.y * output->width + coord.x) *
+ texel_size_in_bytes);
+
+ r->getData(face_id,
+ output->texels.data() + dst_offset,
+ dst_stride);
+
+ // TODO: have to fill in borders too...
+
+ dst_x += val.elem_width;
+ yinc = true;
+
+ column += 1;
+ if (column == val.elem_per_row) {
+ column = 0;
+ dst_x = 0;
+ dst_y += val.elem_width;
+ yinc = false;
+ }
+ }
+
+ if (yinc) {
+ dst_y += val.elem_width;
+ yinc = false;
+ }
+ }
+
+ return true;
+}
+
ImageManager::ImageManager()
{
need_update = true;
@@ -39,6 +213,11 @@ ImageManager::ImageManager()
tex_num_images = TEX_NUM_IMAGES;
tex_num_float_images = TEX_NUM_FLOAT_IMAGES;
tex_image_byte_start = TEX_IMAGE_BYTE_START;
+
+#ifdef WITH_PTEX
+ size_t maxmem = 16384 * 1024;
+ ptex_cache = PtexCache::create(0, maxmem);
+#endif
}
ImageManager::~ImageManager()
@@ -348,7 +527,8 @@ void ImageManager::tag_reload_image(const string& filename, void *builtin_data,
}
}
-bool ImageManager::file_load_image(Image *img, device_vector<uchar4>& tex_img)
+bool ImageManager::file_load_image(Image *img, device_vector<uchar4>& tex_img,
+ DeviceScene *dscene, int slot)
{
if(img->filename == "")
return false;
@@ -356,7 +536,24 @@ bool ImageManager::file_load_image(Image *img, device_vector<uchar4>& tex_img)
ImageInput *in = NULL;
int width, height, depth, components;
- if(!img->builtin_data) {
+ PtexPackedTexture ptex_packed_texture;
+ bool use_ptex = false;
+ if(string_endswith(img->filename, ".ptx")) {
+ // Arbitrary choice for now...
+ width = 1 << 10;
+
+ ptex_pack(&ptex_packed_texture, img->filename.c_str(),
+ width, ptex_cache);
+
+ ptex_packed_texture.test_write();
+
+ height = ptex_packed_texture.height;
+ depth = 1;
+ components = ptex_packed_texture.num_channels;
+
+ use_ptex = true;
+ }
+ else if(!img->builtin_data) {
/* load image from file through OIIO */
in = ImageInput::create(img->filename);
@@ -421,6 +618,42 @@ bool ImageManager::file_load_image(
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list