3 #ifndef SYNCHRONIZED_TEXTURE_HEAP_OPENCL_H
4 #define SYNCHRONIZED_TEXTURE_HEAP_OPENCL_H
14 #if ( SETTING_OPENCL != 0 )
19 #include "synchronized_texture_heap_base.h"
20 #include "synchronized_detail_octree.h"
26 #include <unordered_set>
35 namespace Synchronized {
45 template<
int t_ColorFormat >
50 typedef cl_mem OpenCLType;
53 inline TextureHeap( std::shared_ptr< OpenCL::State >
const& pState,
unsigned int const logSize );
56 inline Pointer Allocate(
unsigned int const logSize );
59 inline void Synchronize();
62 inline OpenCLType OpenCLConvert()
const;
74 inline void OpenCLWrite(
void*
const destination,
size_t const rowPitch,
size_t const slicePitch )
const;
77 inline unsigned int References()
const;
79 inline void AddReference();
80 inline void ReleaseReference();
84 inline unsigned int const LogSize()
const;
86 inline void Mark()
const;
89 inline Color< t_ColorFormat >
const* Get(
size_t const index = 0 )
const;
90 inline void Set(
size_t const index, Color< t_ColorFormat >
const& value );
95 unsigned int m_refcount;
97 TextureHeap* m_pParent;
99 unsigned int m_logSize;
101 Color< t_ColorFormat >* m_array;
109 typedef Color< t_ColorFormat >
const element_type;
110 typedef cl_uint OpenCLType;
114 inline Pointer( Pointer
const& other );
120 inline void swap( Pointer& other );
122 inline unsigned int use_count()
const;
123 inline bool unique()
const;
126 inline Color< t_ColorFormat >
const*
get()
const;
128 inline void Assign(
size_t const index, Color< t_ColorFormat >
const& data )
const;
131 inline Pointer
const& operator=( Pointer
const& other );
134 inline operator bool()
const;
136 inline Color< t_ColorFormat >
const* operator->()
const;
137 inline Color< t_ColorFormat >
const& operator*()
const;
139 inline Color< t_ColorFormat >
const& operator[](
size_t const index )
const;
141 inline bool operator==( Pointer
const& other )
const;
142 inline bool operator!=( Pointer
const& other )
const;
145 inline OpenCLType OpenCLConvert()
const;
150 inline Pointer( Object* pointer );
156 friend struct TextureHeap< t_ColorFormat, PLATFORM_OPENCL >;
163 struct ObjectComparison {
165 inline bool operator()( Object
const*
const pLeft, Object
const*
const pRight )
const;
169 inline void FreeObject( Object
const* pObject );
171 inline void MarkObject( Object
const* pObject );
174 typedef std::unordered_set< Object const* > MarkedObjects;
177 std::shared_ptr< OpenCL::State > m_pState;
178 std::unique_ptr< _cl_mem, OpenCL::Deleter< _cl_mem > > m_image;
181 MarkedObjects m_markedObjects;
192 template<
int t_ColorFormat >
193 TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::Object::Object( TextureHeap*
const pParent,
Vector< unsigned int, 3 > const& coordinates,
unsigned int const logSize ) :
195 m_pParent( pParent ),
196 m_coordinates( coordinates ),
197 m_logSize( logSize ),
198 m_array( new Color< t_ColorFormat >[ 1u << ( 3 * m_logSize ) ] )
203 template<
int t_ColorFormat >
204 TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::Object::~Object() {
206 assert( m_refcount == 0 );
207 assert( m_pParent != NULL );
208 m_pParent->FreeObject(
this );
213 template<
int t_ColorFormat >
214 void TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::Object::OpenCLWrite(
void*
const destination,
size_t const rowPitch,
size_t const slicePitch )
const {
218 Color< t_ColorFormat >
const* kk = m_array;
219 uint8_t* iiDestination =
reinterpret_cast< uint8_t*
>( destination );
220 for (
unsigned int ii = 0; ii < ( 1u << m_logSize ); ++ii ) {
222 uint8_t* jjDestination = iiDestination;
223 for (
unsigned int jj = 0; jj < ( 1u << m_logSize ); ++jj ) {
225 OpenCLType* kkDestination =
reinterpret_cast< OpenCLType*
>( jjDestination );
226 OpenCLType* kkDestinationEnd = kkDestination + ( 1u << m_logSize );
227 for ( ; kkDestination != kkDestinationEnd; ++kkDestination, ++kk )
229 jjDestination += rowPitch;
232 iiDestination += slicePitch;
237 template<
int t_ColorFormat >
238 unsigned int TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::Object::References()
const {
244 template<
int t_ColorFormat >
245 void TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::Object::AddReference() {
251 template<
int t_ColorFormat >
252 void TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::Object::ReleaseReference() {
254 assert( m_refcount > 0 );
255 if ( --m_refcount == 0 )
260 template<
int t_ColorFormat >
263 return m_coordinates;
267 template<
int t_ColorFormat >
268 unsigned int const TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::Object::LogSize()
const {
274 template<
int t_ColorFormat >
275 void TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::Object::Mark()
const {
277 assert( m_pParent != NULL );
278 m_pParent->MarkObject(
this );
282 template<
int t_ColorFormat >
283 Color< t_ColorFormat >
const* TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::Object::Get(
size_t const index )
const {
285 assert( index < ( 1u << ( 3 * m_logSize ) ) );
286 return( m_array + index );
290 template<
int t_ColorFormat >
291 void TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::Object::Set(
size_t const index, Color< t_ColorFormat >
const& data ) {
293 assert( index < ( 1u << ( 3 * m_logSize ) ) );
294 m_array[ index ] = data;
306 template<
int t_ColorFormat >
307 TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::Pointer::Pointer() : m_pointer( NULL ) {
311 template<
int t_ColorFormat >
312 TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::Pointer::Pointer( Pointer
const& other ) : m_pointer( other.m_pointer ) {
314 if ( m_pointer != NULL )
315 m_pointer->AddReference();
319 template<
int t_ColorFormat >
320 TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::Pointer::~Pointer() {
326 template<
int t_ColorFormat >
327 void TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::Pointer::reset() {
329 if ( m_pointer != NULL ) {
331 m_pointer->ReleaseReference();
337 template<
int t_ColorFormat >
338 void TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::Pointer::swap( Pointer& other ) {
340 std::swap( m_pointer, other.m_pointer );
344 template<
int t_ColorFormat >
345 unsigned int TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::Pointer::use_count()
const {
347 unsigned int result = 0;
348 if ( m_pointer != NULL )
349 result = m_pointer->References();
354 template<
int t_ColorFormat >
355 bool TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::Pointer::unique()
const {
357 return( use_count() == 1 );
361 template<
int t_ColorFormat >
362 Color< t_ColorFormat >
const* TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::Pointer::get()
const {
364 return m_pointer->Get();
368 template<
int t_ColorFormat >
369 void TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::Pointer::Assign(
size_t const index, Color< t_ColorFormat >
const& data )
const {
371 m_pointer->Set( index, data );
375 template<
int t_ColorFormat >
376 typename TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::Pointer
const& TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::Pointer::operator=( Pointer
const& other ) {
378 if ( m_pointer != other.m_pointer ) {
381 m_pointer = other.m_pointer;
382 if ( m_pointer != NULL )
383 m_pointer->AddReference();
390 template<
int t_ColorFormat >
391 TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::Pointer::operator bool()
const {
393 return( m_pointer != NULL );
397 template<
int t_ColorFormat >
398 Color< t_ColorFormat >
const* TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::Pointer::operator->()
const {
400 return m_pointer->Get();
404 template<
int t_ColorFormat >
405 Color< t_ColorFormat >
const& TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::Pointer::operator*()
const {
407 return *m_pointer->Get();
411 template<
int t_ColorFormat >
412 Color< t_ColorFormat >
const& TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::Pointer::operator[](
size_t const index )
const {
414 return *m_pointer->Get( index );
418 template<
int t_ColorFormat >
419 bool TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::Pointer::operator==( Pointer
const& other )
const {
421 return( m_pointer == other.m_pointer );
425 template<
int t_ColorFormat >
426 bool TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::Pointer::operator!=( Pointer
const& other )
const {
428 return( m_pointer != other.m_pointer );
432 template<
int t_ColorFormat >
433 TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::Pointer::Pointer( Object* pointer ) : m_pointer( pointer ) {
435 if ( m_pointer != NULL )
436 m_pointer->AddReference();
440 template<
int t_ColorFormat >
441 typename TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::Pointer::OpenCLType TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::Pointer::OpenCLConvert()
const {
443 TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::Pointer::OpenCLType result = OPENCL_NULL;
444 if ( m_pointer != NULL ) {
447 assert( coordinates[ 0 ] < ( 1u << 11 ) );
448 assert( coordinates[ 1 ] < ( 1u << 11 ) );
449 assert( coordinates[ 2 ] < ( 1u << 10 ) );
450 result = ( ( ( coordinates[ 2 ] << 11 ) + coordinates[ 1 ] ) << 11 ) + coordinates[ 0 ];
463 template<
int t_ColorFormat >
464 bool TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::ObjectComparison::operator()( Object
const*
const pLeft, Object
const*
const pRight )
const {
469 assert( leftCoordinates[ 0 ] < ( 1u << 11 ) );
470 assert( leftCoordinates[ 1 ] < ( 1u << 11 ) );
471 assert( leftCoordinates[ 2 ] < ( 1u << 10 ) );
474 assert( rightCoordinates[ 0 ] < ( 1u << 11 ) );
475 assert( rightCoordinates[ 1 ] < ( 1u << 11 ) );
476 assert( rightCoordinates[ 2 ] < ( 1u << 10 ) );
478 for (
int ii = 10; ( comparison == 0 ) && ( ii >= 0 ); --ii ) {
480 unsigned int const mask = ( 1u << ii );
482 for (
int jj = 2; jj >= 0; --jj ) {
484 unsigned int const left = ( leftCoordinates[ jj ] & mask );
485 unsigned int const right = ( rightCoordinates[ jj ] & mask );
486 if ( left < right ) {
491 else if ( left > right ) {
499 return( comparison < 0 );
510 template<
int t_ColorFormat >
511 TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::TextureHeap( std::shared_ptr< OpenCL::State >
const& pState,
unsigned int const logSize ) : m_pState( pState ) {
513 assert( logSize <= 10 );
517 cl_int result = CL_SUCCESS;
519 if ( result != CL_SUCCESS )
524 template<
int t_ColorFormat >
525 typename TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::Pointer TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::Allocate(
unsigned int const logSize ) {
528 Object* pObject =
new Object(
this, coordinates, logSize );
529 MarkObject( pObject );
530 return Pointer( pObject );
534 template<
int t_ColorFormat >
535 void TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::Synchronize() {
537 if ( ! m_markedObjects.empty() ) {
539 typename MarkedObjects::size_type
const size = m_markedObjects.size();
540 std::unique_ptr< Object const* > markedObjects(
new Object
const*[ size ] );
541 std::copy( m_markedObjects.begin(), m_markedObjects.end(), markedObjects.get() );
542 std::sort( markedObjects.get(), markedObjects.get() + size, ObjectComparison() );
543 Object
const*
const*
const iiBegin = markedObjects.get();
544 Object
const*
const*
const iiEnd = markedObjects.get() + size;
546 detail::Octree markedTree( m_freeTree.Height() );
547 for ( Object
const*
const* ii = iiBegin; ii != iiEnd; ++ii )
548 markedTree.Insert( ( *ii )->Coordinates(), ( *ii )->LogSize() );
550 typedef std::pair< Vector< unsigned int, 3 >,
unsigned int > Leaf;
551 unsigned int const leaves = markedTree.CountLeaves();
552 std::unique_ptr< Leaf > markedLeaves(
new Leaf[ leaves ] );
553 markedTree.Leaves( markedLeaves.get() );
554 Leaf
const*
const jjBegin = markedLeaves.get();
555 Leaf
const*
const jjEnd = markedLeaves.get() + leaves;
557 Object
const*
const* ii = iiBegin;
558 Leaf
const* jj = jjBegin;
559 for ( ; jj != jjEnd; ++jj ) {
561 assert( ii != iiEnd );
563 unsigned int const mask = ( 1u << jj->second ) - 1;
565 size_t origin[ 3 ] = { jj->first[ 0 ], jj->first[ 1 ], jj->first[ 2 ] };
566 size_t region[ 3 ] = { ( 1u << jj->second ), ( 1u << jj->second ), ( 1u << jj->second ) };
568 size_t slicePitch = 0;
570 cl_int result = CL_SUCCESS;
571 void*
const buffer = clEnqueueMapImage(
585 if ( result != CL_SUCCESS )
588 Object
const*
const* iiNext = ii;
589 for ( ; iiNext != iiEnd; ++iiNext ) {
593 ( ( coordinates[ 0 ] & ~mask ) != jj->first[ 0 ] ) ||
594 ( ( coordinates[ 1 ] & ~mask ) != jj->first[ 1 ] ) ||
595 ( ( coordinates[ 2 ] & ~mask ) != jj->first[ 2 ] )
601 assert( ii != iiNext );
603 for ( ; ii != iiNext; ++ii ) {
606 uint8_t*
const destination = (
607 reinterpret_cast< uint8_t*
>( buffer ) +
608 ( coordinates[ 2 ] & mask ) * slicePitch +
609 ( coordinates[ 1 ] & mask ) * rowPitch +
612 ( *ii )->OpenCLWrite( destination, rowPitch, slicePitch );
615 clEnqueueUnmapMemObject(
624 assert( ii == iiEnd );
626 m_markedObjects.clear();
631 template<
int t_ColorFormat >
632 typename TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::OpenCLType TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::OpenCLConvert()
const {
634 return m_image.get();
638 template<
int t_ColorFormat >
639 void TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::FreeObject( Object
const* pObject ) {
641 m_markedObjects.erase( pObject );
642 m_freeTree.Insert( pObject->Coordinates(), pObject->LogSize() );
646 template<
int t_ColorFormat >
647 void TextureHeap< t_ColorFormat, PLATFORM_OPENCL >::MarkObject( Object
const* pObject ) {
649 m_markedObjects.insert( pObject );
660 #endif // SETTING_OPENCL
665 #endif // SYNCHRONIZED_TEXTURE_HEAP_OPENCL_H