forked from Lainports/freebsd-ports
- Add an memory alignment patch for graphics/blender Changelog: https://github.com/imageworks/OpenShadingLanguage/blob/master/CHANGES PR: 196278 Submitted by: FreeBSD@ShaneWare.Biz (maintainer)
181 lines
8.4 KiB
Diff
181 lines
8.4 KiB
Diff
--- ./src/include/OSL/oslexec.h.orig
|
|
+++ ./src/include/OSL/oslexec.h
|
|
@@ -428,7 +428,8 @@ class OSLEXECPUBLIC ShadingSystem
|
|
std::string getstats (int level=1) const;
|
|
|
|
void register_closure (string_view name, int id, const ClosureParam *params,
|
|
- PrepareClosureFunc prepare, SetupClosureFunc setup);
|
|
+ PrepareClosureFunc prepare, SetupClosureFunc setup,
|
|
+ int alignment = 1);
|
|
/// Query either by name or id an existing closure. If name is non
|
|
/// NULL it will use it for the search, otherwise id would be used
|
|
/// and the name will be placed in name if successful. Also return
|
|
--- ./src/liboslexec/oslexec_pvt.h
|
|
+++ ./src/liboslexec/oslexec_pvt.h
|
|
@@ -44,6 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
#include <OpenImageIO/paramlist.h>
|
|
#include <OpenImageIO/refcnt.h>
|
|
|
|
+#include "OSL/genclosure.h"
|
|
#include "OSL/oslexec.h"
|
|
#include "OSL/oslclosure.h"
|
|
#include "osl_pvt.h"
|
|
@@ -693,13 +694,16 @@ class ClosureRegistry {
|
|
std::vector<ClosureParam> params;
|
|
// the needed size for the structure
|
|
int struct_size;
|
|
+ // the needed alignment of the structure
|
|
+ int alignment;
|
|
// Creation callbacks
|
|
PrepareClosureFunc prepare;
|
|
SetupClosureFunc setup;
|
|
};
|
|
|
|
void register_closure (string_view name, int id, const ClosureParam *params,
|
|
- PrepareClosureFunc prepare, SetupClosureFunc setup);
|
|
+ PrepareClosureFunc prepare, SetupClosureFunc setup,
|
|
+ int alignmen = 1);
|
|
|
|
const ClosureEntry *get_entry (ustring name) const;
|
|
const ClosureEntry *get_entry (int id) const {
|
|
@@ -855,7 +859,8 @@ class ShadingSystemImpl
|
|
ustring *alloc_string_constants (size_t n) { return m_string_pool.alloc (n); }
|
|
|
|
void register_closure (string_view name, int id, const ClosureParam *params,
|
|
- PrepareClosureFunc prepare, SetupClosureFunc setup);
|
|
+ PrepareClosureFunc prepare, SetupClosureFunc setup,
|
|
+ int alignment = 1);
|
|
bool query_closure (const char **name, int *id,
|
|
const ClosureParam **params);
|
|
const ClosureRegistry::ClosureEntry *find_closure(ustring name) const {
|
|
@@ -1120,19 +1125,24 @@ class SimplePool {
|
|
char * alloc(size_t size, size_t alignment=1) {
|
|
// Alignment must be power of two
|
|
DASSERT ((alignment & (alignment - 1)) == 0);
|
|
- // Fail if beyond allocation limits or senseless alignment
|
|
- if (size > BlockSize || (size & (alignment - 1)) != 0)
|
|
+ // Fail if beyond allocation limits (we make sure there's enough space
|
|
+ // for alignment padding here as well).
|
|
+ if (size + alignment - 1 > BlockSize)
|
|
return NULL;
|
|
- m_block_offset -= (m_block_offset & (alignment - 1)); // Fix up alignment
|
|
- if (size <= m_block_offset) {
|
|
+ // Fix up alignment
|
|
+ size_t alignment_offset = alignment_offset_calc(alignment);
|
|
+ if (size + alignment_offset <= m_block_offset) {
|
|
// Enough space in current block
|
|
- m_block_offset -= size;
|
|
+ m_block_offset -= size + alignment_offset;
|
|
} else {
|
|
// Need to allocate a new block
|
|
m_current_block++;
|
|
m_block_offset = BlockSize - size;
|
|
if (m_blocks.size() == m_current_block)
|
|
m_blocks.push_back(new char[BlockSize]);
|
|
+ alignment_offset = alignment_offset_calc(alignment);
|
|
+ DASSERT (m_block_offset >= alignment_offset);
|
|
+ m_block_offset -= alignment_offset;
|
|
}
|
|
return m_blocks[m_current_block] + m_block_offset;
|
|
}
|
|
@@ -1140,6 +1150,10 @@ class SimplePool {
|
|
void clear () { m_current_block = 0; m_block_offset = BlockSize; }
|
|
|
|
private:
|
|
+ inline size_t alignment_offset_calc(size_t alignment) {
|
|
+ return (((uintptr_t)m_blocks[m_current_block] + m_block_offset) & (alignment - 1));
|
|
+ }
|
|
+
|
|
std::vector<char *> m_blocks;
|
|
size_t m_current_block;
|
|
size_t m_block_offset;
|
|
@@ -1320,7 +1334,9 @@ class OSLEXECPUBLIC ShadingContext {
|
|
ClosureComponent * closure_component_allot(int id, size_t prim_size, int nattrs) {
|
|
size_t needed = sizeof(ClosureComponent) + (prim_size >= 4 ? prim_size - 4 : 0)
|
|
+ sizeof(ClosureComponent::Attr) * nattrs;
|
|
- ClosureComponent *comp = (ClosureComponent *) m_closure_pool.alloc(needed);
|
|
+ int alignment = m_shadingsys.find_closure(id)->alignment;
|
|
+ size_t alignment_offset = closure_alignment_offset_calc(alignment);
|
|
+ ClosureComponent *comp = (ClosureComponent *) (m_closure_pool.alloc(needed + alignment_offset, alignment) + alignment_offset);
|
|
comp->type = ClosureColor::COMPONENT;
|
|
comp->id = id;
|
|
comp->size = prim_size;
|
|
@@ -1335,7 +1351,9 @@ class OSLEXECPUBLIC ShadingContext {
|
|
// Allocate the component and the mul back to back
|
|
size_t needed = sizeof(ClosureComponent) + (prim_size >= 4 ? prim_size - 4 : 0)
|
|
+ sizeof(ClosureComponent::Attr) * nattrs;
|
|
- ClosureComponent *comp = (ClosureComponent *) m_closure_pool.alloc(needed);
|
|
+ int alignment = m_shadingsys.find_closure(id)->alignment;
|
|
+ size_t alignment_offset = closure_alignment_offset_calc(alignment);
|
|
+ ClosureComponent *comp = (ClosureComponent *) (m_closure_pool.alloc(needed + alignment_offset, alignment) + alignment_offset);
|
|
comp->type = ClosureColor::COMPONENT;
|
|
comp->id = id;
|
|
comp->size = prim_size;
|
|
@@ -1486,6 +1504,14 @@ class OSLEXECPUBLIC ShadingContext {
|
|
// Buffering of error messages and printfs
|
|
typedef std::pair<ErrorHandler::ErrCode, std::string> ErrorItem;
|
|
mutable std::vector<ErrorItem> m_buffered_errors;
|
|
+
|
|
+ // Calculate offset needed to align ClosureComponent's mem to a given alignment.
|
|
+ inline size_t closure_alignment_offset_calc(size_t alignment) {
|
|
+ return alignment == 1
|
|
+ ? 0
|
|
+ : alignment - (reckless_offsetof(ClosureComponent, mem) & (alignment - 1));
|
|
+ }
|
|
+
|
|
};
|
|
|
|
|
|
--- ./src/liboslexec/shadingsys.cpp
|
|
+++ ./src/liboslexec/shadingsys.cpp
|
|
@@ -284,9 +284,10 @@ void
|
|
ShadingSystem::register_closure (string_view name, int id,
|
|
const ClosureParam *params,
|
|
PrepareClosureFunc prepare,
|
|
- SetupClosureFunc setup)
|
|
+ SetupClosureFunc setup,
|
|
+ int alignment)
|
|
{
|
|
- return m_impl->register_closure (name, id, params, prepare, setup);
|
|
+ return m_impl->register_closure (name, id, params, prepare, setup, alignment);
|
|
}
|
|
|
|
|
|
@@ -798,7 +799,8 @@ void
|
|
ShadingSystemImpl::register_closure (string_view name, int id,
|
|
const ClosureParam *params,
|
|
PrepareClosureFunc prepare,
|
|
- SetupClosureFunc setup)
|
|
+ SetupClosureFunc setup,
|
|
+ int alignment)
|
|
{
|
|
for (int i = 0; params && params[i].type != TypeDesc(); ++i) {
|
|
if (params[i].key == NULL && params[i].type.size() != (size_t)params[i].field_size) {
|
|
@@ -806,7 +808,7 @@ ShadingSystemImpl::register_closure (string_view name, int id,
|
|
return;
|
|
}
|
|
}
|
|
- m_closure_registry.register_closure(name, id, params, prepare, setup);
|
|
+ m_closure_registry.register_closure(name, id, params, prepare, setup, alignment);
|
|
}
|
|
|
|
|
|
@@ -2554,7 +2556,8 @@ void
|
|
ClosureRegistry::register_closure (string_view name, int id,
|
|
const ClosureParam *params,
|
|
PrepareClosureFunc prepare,
|
|
- SetupClosureFunc setup)
|
|
+ SetupClosureFunc setup,
|
|
+ int alignment)
|
|
{
|
|
if (m_closure_table.size() <= (size_t)id)
|
|
m_closure_table.resize(id + 1);
|
|
@@ -2578,6 +2581,7 @@ ClosureRegistry::register_closure (string_view name, int id,
|
|
}
|
|
entry.prepare = prepare;
|
|
entry.setup = setup;
|
|
+ entry.alignment = alignment;
|
|
m_closure_name_to_id[ustring(name)] = id;
|
|
}
|
|
|
|
|