-
Notifications
You must be signed in to change notification settings - Fork 211
/
buffers.factor
166 lines (129 loc) · 5.55 KB
/
buffers.factor
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
! Copyright (C) 2009 Joe Groff.
! See https://factorcode.org/license.txt for BSD license.
USING: accessors alien alien.c-types alien.data arrays byte-arrays
combinators destructors gpu kernel math opengl opengl.gl
typed ui.gadgets.worlds variants ;
IN: gpu.buffers
VARIANT: buffer-upload-pattern
stream-upload static-upload dynamic-upload ;
VARIANT: buffer-usage-pattern
draw-usage read-usage copy-usage ;
VARIANT: buffer-access-mode
read-access write-access read-write-access ;
VARIANT: buffer-kind
vertex-buffer index-buffer
pixel-unpack-buffer pixel-pack-buffer
transform-feedback-buffer ;
TUPLE: buffer < gpu-object
{ upload-pattern buffer-upload-pattern }
{ usage-pattern buffer-usage-pattern }
{ kind buffer-kind } ;
<PRIVATE
: gl-buffer-usage ( buffer -- usage )
[ upload-pattern>> ] [ usage-pattern>> ] bi 2array {
{ { stream-upload draw-usage } [ GL_STREAM_DRAW ] }
{ { stream-upload read-usage } [ GL_STREAM_READ ] }
{ { stream-upload copy-usage } [ GL_STREAM_COPY ] }
{ { static-upload draw-usage } [ GL_STATIC_DRAW ] }
{ { static-upload read-usage } [ GL_STATIC_READ ] }
{ { static-upload copy-usage } [ GL_STATIC_COPY ] }
{ { dynamic-upload draw-usage } [ GL_DYNAMIC_DRAW ] }
{ { dynamic-upload read-usage } [ GL_DYNAMIC_READ ] }
{ { dynamic-upload copy-usage } [ GL_DYNAMIC_COPY ] }
} case ; inline
: gl-access ( access -- gl-access )
{
{ read-access [ GL_READ_ONLY ] }
{ write-access [ GL_WRITE_ONLY ] }
{ read-write-access [ GL_READ_WRITE ] }
} case ; inline
: gl-target ( kind -- target )
{
{ vertex-buffer [ GL_ARRAY_BUFFER ] }
{ index-buffer [ GL_ELEMENT_ARRAY_BUFFER ] }
{ pixel-unpack-buffer [ GL_PIXEL_UNPACK_BUFFER ] }
{ pixel-pack-buffer [ GL_PIXEL_PACK_BUFFER ] }
{ transform-feedback-buffer [ GL_TRANSFORM_FEEDBACK_BUFFER ] }
} case ; inline
: get-buffer-int ( target enum -- value )
0 int <ref> [ glGetBufferParameteriv ] keep int deref ; inline
: bind-buffer ( buffer -- target )
[ kind>> gl-target dup ] [ handle>> glBindBuffer ] bi ; inline
PRIVATE>
M: buffer dispose
[ [ delete-gl-buffer ] when* f ] change-handle drop ;
TUPLE: buffer-ptr
{ buffer buffer read-only }
{ offset integer read-only } ;
C: <buffer-ptr> buffer-ptr
TUPLE: buffer-range < buffer-ptr
{ size integer read-only } ;
C: <buffer-range> buffer-range
UNION: gpu-data-ptr buffer-ptr c-ptr ;
TYPED: buffer-size ( buffer: buffer -- size: integer )
bind-buffer GL_BUFFER_SIZE get-buffer-int ;
: buffer-ptr>range ( buffer-ptr -- buffer-range )
[ buffer>> ] [ offset>> ] bi
2dup [ buffer-size ] dip -
buffer-range boa ; inline
:: allocate-buffer ( buffer size initial-data -- )
buffer bind-buffer :> target
target size initial-data buffer gl-buffer-usage glBufferData ; inline
: allocate-byte-array ( buffer byte-array -- )
[ byte-length ] [ ] bi allocate-buffer ; inline
TYPED: <buffer> ( upload: buffer-upload-pattern
usage: buffer-usage-pattern
kind: buffer-kind
size: integer
initial-data
--
buffer: buffer )
[ [ gen-gl-buffer ] 3dip buffer boa dup ] 2dip allocate-buffer
window-resource ;
TYPED: byte-array>buffer ( byte-array
upload: buffer-upload-pattern
usage: buffer-usage-pattern
kind: buffer-kind
--
buffer: buffer )
[ ] 3curry dip
[ byte-length ] [ ] bi <buffer> ;
TYPED:: update-buffer ( buffer-ptr: buffer-ptr size: integer data -- )
buffer-ptr buffer>> :> buffer
buffer bind-buffer :> target
target buffer-ptr offset>> size data glBufferSubData ;
TYPED:: read-buffer ( buffer-ptr: buffer-ptr size: integer -- data: byte-array )
buffer-ptr buffer>> :> buffer
buffer bind-buffer :> target
size <byte-array> :> data
target buffer-ptr offset>> size data glGetBufferSubData
data ;
TYPED:: copy-buffer ( to-buffer-ptr: buffer-ptr from-buffer-ptr: buffer-ptr size: integer -- )
GL_COPY_WRITE_BUFFER to-buffer-ptr buffer>> glBindBuffer
GL_COPY_READ_BUFFER from-buffer-ptr buffer>> glBindBuffer
GL_COPY_READ_BUFFER GL_COPY_WRITE_BUFFER
from-buffer-ptr offset>> to-buffer-ptr offset>>
size glCopyBufferSubData ;
: (grow-buffer-size) ( target-size old-size -- new-size )
[ 2dup > ] [ 2 * ] while nip ; inline
TYPED: grow-buffer ( buffer: buffer target-size: integer -- )
over buffer-size 2dup >
[ (grow-buffer-size) f allocate-buffer ] [ 3drop ] if ; inline
:: with-mapped-buffer ( ..a buffer access quot: ( ..a alien -- ..b ) -- ..b )
buffer bind-buffer :> target
target access gl-access glMapBuffer
quot call
target glUnmapBuffer drop ; inline
:: with-mapped-buffer-array ( ..a buffer access c-type quot: ( ..a array -- ..b ) -- ..b )
buffer buffer-size c-type heap-size /i :> len
buffer access [ len c-type <c-direct-array> quot call ] with-mapped-buffer ; inline
:: with-bound-buffer ( ..a buffer target quot: ( ..a -- ..b ) -- ..b )
target gl-target buffer glBindBuffer
quot call ; inline
: with-buffer-ptr ( ..a buffer-ptr target quot: ( ..a c-ptr -- ..b ) -- ..b )
[ [ offset>> <alien> ] [ buffer>> handle>> ] bi ] 2dip
with-bound-buffer ; inline
: with-gpu-data-ptr ( ..a gpu-data-ptr target quot: ( ..a c-ptr -- ..b ) -- ..b )
pick buffer-ptr?
[ with-buffer-ptr ]
[ [ gl-target 0 glBindBuffer ] dip call ] if ; inline