Welcome to mirror list, hosted at ThFree Co, Russian Federation.

SpuDoubleBuffer.h « BulletMultiThreaded « bullet2 « extern - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: a0695744bd52782696a47538aac74a222941f6bf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#ifndef DOUBLE_BUFFER_H
#define DOUBLE_BUFFER_H

#include "SpuFakeDma.h"
#include "LinearMath/btScalar.h"


///DoubleBuffer
template<class T, int size>
class DoubleBuffer
{
#if defined(__SPU__) || defined(USE_LIBSPE2)
	ATTRIBUTE_ALIGNED128( T m_buffer0[size] ) ;
	ATTRIBUTE_ALIGNED128( T m_buffer1[size] ) ;
#else
	T m_buffer0[size];
	T m_buffer1[size];
#endif
	
	T *m_frontBuffer;
	T *m_backBuffer;

	unsigned int m_dmaTag;
	bool m_dmaPending;
public:
	bool	isPending() const { return m_dmaPending;}
	DoubleBuffer();

	void init ();

	// dma get and put commands
	void backBufferDmaGet(uint64_t ea, unsigned int numBytes, unsigned int tag);
	void backBufferDmaPut(uint64_t ea, unsigned int numBytes, unsigned int tag);

	// gets pointer to a buffer
	T *getFront();
	T *getBack();

	// if back buffer dma was started, wait for it to complete
	// then move back to front and vice versa
	T *swapBuffers();
};

template<class T, int size>
DoubleBuffer<T,size>::DoubleBuffer()
{
	init ();
}

template<class T, int size>
void DoubleBuffer<T,size>::init()
{
	this->m_dmaPending = false;
	this->m_frontBuffer = &this->m_buffer0[0];
	this->m_backBuffer = &this->m_buffer1[0];
}

template<class T, int size>
void
DoubleBuffer<T,size>::backBufferDmaGet(uint64_t ea, unsigned int numBytes, unsigned int tag)
{
	m_dmaPending = true;
	m_dmaTag = tag;
	if (numBytes)
	{
		m_backBuffer = (T*)cellDmaLargeGetReadOnly(m_backBuffer, ea, numBytes, tag, 0, 0);
	}
}

template<class T, int size>
void
DoubleBuffer<T,size>::backBufferDmaPut(uint64_t ea, unsigned int numBytes, unsigned int tag)
{
	m_dmaPending = true;
	m_dmaTag = tag;
	cellDmaLargePut(m_backBuffer, ea, numBytes, tag, 0, 0);
}

template<class T, int size>
T *
DoubleBuffer<T,size>::getFront()
{
	return m_frontBuffer;
}

template<class T, int size>
T *
DoubleBuffer<T,size>::getBack()
{
	return m_backBuffer;
}

template<class T, int size>
T *
DoubleBuffer<T,size>::swapBuffers()
{
	if (m_dmaPending)
	{
		cellDmaWaitTagStatusAll(1<<m_dmaTag);
		m_dmaPending = false;
	}

	T *tmp = m_backBuffer;
	m_backBuffer = m_frontBuffer;
	m_frontBuffer = tmp;

	return m_frontBuffer;
}

#endif