diff options
author | Campbell Barton <ideasman42@gmail.com> | 2017-06-29 13:09:05 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2017-06-29 13:09:05 +0300 |
commit | 34566aa96910e29eceb45d29c9d50471452f8d73 (patch) | |
tree | d812ea307ac66744bbb78efeccd41967f4eaea52 /intern/gawain | |
parent | 2343dcf0d272c0cbc3f185d674eb93d24b4f29e7 (diff) |
Gawain: add method of stepping over data directly
This avoids using GWN_vertbuf_attr_set which needs to calculate the
offset and perform a memcpy every call.
Exposing the data directly allows us to avoid a memcpy in some cases
and means we can write to the vertex buffer's memory directly.
Diffstat (limited to 'intern/gawain')
-rw-r--r-- | intern/gawain/gawain/common.h | 7 | ||||
-rw-r--r-- | intern/gawain/gawain/vertex_buffer.h | 25 | ||||
-rw-r--r-- | intern/gawain/src/vertex_buffer.c | 20 |
3 files changed, 52 insertions, 0 deletions
diff --git a/intern/gawain/gawain/common.h b/intern/gawain/gawain/common.h index e21b241160d..e96a3b5c2a2 100644 --- a/intern/gawain/gawain/common.h +++ b/intern/gawain/gawain/common.h @@ -25,3 +25,10 @@ #if TRUST_NO_ONE #include <assert.h> #endif + +/* GWN_INLINE */ +#if defined(_MSC_VER) +# define GWN_INLINE static __forceinline +#else +# define GWN_INLINE static inline __attribute__((always_inline)) __attribute__((__unused__)) +#endif
\ No newline at end of file diff --git a/intern/gawain/gawain/vertex_buffer.h b/intern/gawain/gawain/vertex_buffer.h index 46f83f5c551..57179062df4 100644 --- a/intern/gawain/gawain/vertex_buffer.h +++ b/intern/gawain/gawain/vertex_buffer.h @@ -49,6 +49,31 @@ void GWN_vertbuf_attr_set(Gwn_VertBuf*, unsigned a_idx, unsigned v_idx, const vo void GWN_vertbuf_attr_fill(Gwn_VertBuf*, unsigned a_idx, const void* data); // tightly packed, non interleaved input data void GWN_vertbuf_attr_fill_stride(Gwn_VertBuf*, unsigned a_idx, unsigned stride, const void* data); +// For low level access only +typedef struct { + unsigned size; + unsigned stride; + GLubyte* data; + GLubyte* data_init; +#if TRUST_NO_ONE + // Only for overflow check + GLubyte* _data_end; +#endif +} Gwn_VertBufRaw; + +GWN_INLINE void *GWN_vertbuf_raw_step(Gwn_VertBufRaw *a) + { + GLubyte* data = a->data; + a->data += a->stride; +#if TRUST_NO_ONE + assert(data < a->_data_end); +#endif + return (void *)data; + } + +void GWN_vertbuf_attr_get_raw_data(Gwn_VertBuf*, unsigned a_idx, Gwn_VertBufRaw *access); + + // TODO: decide whether to keep the functions below // doesn't immediate mode satisfy these needs? diff --git a/intern/gawain/src/vertex_buffer.c b/intern/gawain/src/vertex_buffer.c index 03691b0c21d..a9b481261f3 100644 --- a/intern/gawain/src/vertex_buffer.c +++ b/intern/gawain/src/vertex_buffer.c @@ -151,6 +151,26 @@ void GWN_vertbuf_attr_fill_stride(Gwn_VertBuf* verts, unsigned a_idx, unsigned s } } +void GWN_vertbuf_attr_get_raw_data(Gwn_VertBuf* verts, unsigned a_idx, Gwn_VertBufRaw *access) + { + const Gwn_VertFormat* format = &verts->format; + const Gwn_VertAttr* a = format->attribs + a_idx; + +#if TRUST_NO_ONE + assert(a_idx < format->attrib_ct); + assert(verts->data != NULL); // data must be in main mem +#endif + + access->size = a->sz; + access->stride = format->stride; + access->data = (GLubyte*)verts->data + a->offset; + access->data_init = access->data; +#if TRUST_NO_ONE + access->_data_end = access->data_init + (size_t)(verts->vertex_ct * format->stride); +#endif + } + + static void VertexBuffer_prime(Gwn_VertBuf* verts) { const unsigned buffer_sz = GWN_vertbuf_size_get(verts); |