Line 0
Link Here
|
|
|
1 |
--- src/liboslexec/oslexec_pvt.h.orig 2014-12-04 12:01:54 UTC |
2 |
+++ src/liboslexec/oslexec_pvt.h |
3 |
@@ -44,6 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
4 |
#include <OpenImageIO/paramlist.h> |
5 |
#include <OpenImageIO/refcnt.h> |
6 |
|
7 |
+#include "OSL/genclosure.h" |
8 |
#include "OSL/oslexec.h" |
9 |
#include "OSL/oslclosure.h" |
10 |
#include "osl_pvt.h" |
11 |
@@ -627,13 +628,16 @@ public: |
12 |
std::vector<ClosureParam> params; |
13 |
// the needed size for the structure |
14 |
int struct_size; |
15 |
+ // the needed alignment of the structure |
16 |
+ int alignment; |
17 |
// Creation callbacks |
18 |
PrepareClosureFunc prepare; |
19 |
SetupClosureFunc setup; |
20 |
}; |
21 |
|
22 |
void register_closure (string_view name, int id, const ClosureParam *params, |
23 |
- PrepareClosureFunc prepare, SetupClosureFunc setup); |
24 |
+ PrepareClosureFunc prepare, SetupClosureFunc setup, |
25 |
+ int alignment = 1); |
26 |
|
27 |
const ClosureEntry *get_entry (ustring name) const; |
28 |
const ClosureEntry *get_entry (int id) const { |
29 |
@@ -789,7 +793,8 @@ public: |
30 |
ustring *alloc_string_constants (size_t n) { return m_string_pool.alloc (n); } |
31 |
|
32 |
void register_closure (string_view name, int id, const ClosureParam *params, |
33 |
- PrepareClosureFunc prepare, SetupClosureFunc setup); |
34 |
+ PrepareClosureFunc prepare, SetupClosureFunc setup, |
35 |
+ int alignment = 1); |
36 |
bool query_closure (const char **name, int *id, |
37 |
const ClosureParam **params); |
38 |
const ClosureRegistry::ClosureEntry *find_closure(ustring name) const { |
39 |
@@ -1049,19 +1054,24 @@ public: |
40 |
char * alloc(size_t size, size_t alignment=1) { |
41 |
// Alignment must be power of two |
42 |
DASSERT ((alignment & (alignment - 1)) == 0); |
43 |
- // Fail if beyond allocation limits or senseless alignment |
44 |
- if (size > BlockSize || (size & (alignment - 1)) != 0) |
45 |
+ // Fail if beyond allocation limits (we make sure there's enough space |
46 |
+ // for alignment padding here as well). |
47 |
+ if (size + alignment - 1 > BlockSize) |
48 |
return NULL; |
49 |
- m_block_offset -= (m_block_offset & (alignment - 1)); // Fix up alignment |
50 |
- if (size <= m_block_offset) { |
51 |
+ // Fix up alignment |
52 |
+ size_t alignment_offset = alignment_offset_calc(alignment); |
53 |
+ if (size + alignment_offset <= m_block_offset) { |
54 |
// Enough space in current block |
55 |
- m_block_offset -= size; |
56 |
+ m_block_offset -= size + alignment_offset; |
57 |
} else { |
58 |
// Need to allocate a new block |
59 |
m_current_block++; |
60 |
m_block_offset = BlockSize - size; |
61 |
if (m_blocks.size() == m_current_block) |
62 |
m_blocks.push_back(new char[BlockSize]); |
63 |
+ alignment_offset = alignment_offset_calc(alignment); |
64 |
+ DASSERT (m_block_offset >= alignment_offset); |
65 |
+ m_block_offset -= alignment_offset; |
66 |
} |
67 |
return m_blocks[m_current_block] + m_block_offset; |
68 |
} |
69 |
@@ -1069,6 +1079,10 @@ public: |
70 |
void clear () { m_current_block = 0; m_block_offset = BlockSize; } |
71 |
|
72 |
private: |
73 |
+ inline size_t alignment_offset_calc(size_t alignment) { |
74 |
+ return (((uintptr_t)m_blocks[m_current_block] + m_block_offset) & (alignment - 1)); |
75 |
+ } |
76 |
+ |
77 |
std::vector<char *> m_blocks; |
78 |
size_t m_current_block; |
79 |
size_t m_block_offset; |
80 |
@@ -1243,7 +1257,9 @@ public: |
81 |
ClosureComponent * closure_component_allot(int id, size_t prim_size, int nattrs) { |
82 |
size_t needed = sizeof(ClosureComponent) + (prim_size >= 4 ? prim_size - 4 : 0) |
83 |
+ sizeof(ClosureComponent::Attr) * nattrs; |
84 |
- ClosureComponent *comp = (ClosureComponent *) m_closure_pool.alloc(needed); |
85 |
+ int alignment = m_shadingsys.find_closure(id)->alignment; |
86 |
+ size_t alignment_offset = closure_alignment_offset_calc(alignment); |
87 |
+ ClosureComponent *comp = (ClosureComponent *) (m_closure_pool.alloc(needed + alignment_offset, alignment) + alignment_offset); |
88 |
comp->type = ClosureColor::COMPONENT; |
89 |
comp->id = id; |
90 |
comp->size = prim_size; |
91 |
@@ -1258,7 +1274,9 @@ public: |
92 |
// Allocate the component and the mul back to back |
93 |
size_t needed = sizeof(ClosureComponent) + (prim_size >= 4 ? prim_size - 4 : 0) |
94 |
+ sizeof(ClosureComponent::Attr) * nattrs; |
95 |
- ClosureComponent *comp = (ClosureComponent *) m_closure_pool.alloc(needed); |
96 |
+ int alignment = m_shadingsys.find_closure(id)->alignment; |
97 |
+ size_t alignment_offset = closure_alignment_offset_calc(alignment); |
98 |
+ ClosureComponent *comp = (ClosureComponent *) (m_closure_pool.alloc(needed + alignment_offset, alignment) + alignment_offset); |
99 |
comp->type = ClosureColor::COMPONENT; |
100 |
comp->id = id; |
101 |
comp->size = prim_size; |
102 |
@@ -1409,6 +1427,13 @@ private: |
103 |
// Buffering of error messages and printfs |
104 |
typedef std::pair<ErrorHandler::ErrCode, std::string> ErrorItem; |
105 |
mutable std::vector<ErrorItem> m_buffered_errors; |
106 |
+ |
107 |
+ // Calculate offset needed to align ClosureComponent's mem to a given alignment. |
108 |
+ inline size_t closure_alignment_offset_calc(size_t alignment) { |
109 |
+ return alignment == 1 ? 0 : |
110 |
+ alignment - (reckless_offsetof(ClosureComponent, mem) & (alignment - 1)); |
111 |
+ } |
112 |
+ |
113 |
}; |
114 |
|
115 |
|