1 /*---------------------------------------------------------------------------*\
5 * Copyright (C) 2000-2002 by the OpenSG Forum *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
15 * This library is free software; you can redistribute it and/or modify it *
16 * under the terms of the GNU Library General Public License as published *
17 * by the Free Software Foundation, version 2. *
19 * This library is distributed in the hope that it will be useful, but *
20 * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
22 * Library General Public License for more details. *
24 * You should have received a copy of the GNU Library General Public *
25 * License along with this library; if not, write to the Free Software *
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
37 \*---------------------------------------------------------------------------*/
45 #include "OSGConfig.h"
48 #include "OSGGLFuncProtos.h"
50 #include "OSGAction.h"
51 #include "OSGCamera.h"
52 #include "OSGSceneFileHandler.h"
53 #include "OSGVolumeDraw.h"
55 #include "OSGDrawEnv.h"
56 #include "OSGComputeShaderAlgorithm.h"
58 #include "OSGTextureImageChunk.h"
59 #include "OSGComputeShaderChunk.h"
60 #include "OSGChunkMaterial.h"
62 #include "OSGShaderStorageBufferObjChunk.h"
63 #include "OSGShaderStorageBufferObjRefChunk.h"
64 #include "OSGShaderStorageBufferObjStdLayoutChunk.h"
65 #include "OSGUniformBufferObjChunk.h"
66 #include "OSGUniformBufferObjStd140Chunk.h"
70 // Documentation for this class is emited in the
71 // OSGComputeShaderAlgorithmBase.cpp file.
72 // To modify it, please change the .fcd file (OSGComputeShaderAlgorithm.fcd)
73 // and regenerate the base file.
75 UInt32
ComputeShaderAlgorithm::_arbComputeShader
=
76 Window::invalidExtensionID
;
78 UInt32
ComputeShaderAlgorithm::_arbComputeVariableGroupSize
=
79 Window::invalidExtensionID
;
81 UInt32
ComputeShaderAlgorithm::_arbShaderImageLoadStore
=
82 Window::invalidExtensionID
;
84 UInt32
ComputeShaderAlgorithm:: FuncIdDispatchCompute
=
85 Window::invalidFunctionID
;
87 UInt32
ComputeShaderAlgorithm:: FuncIdDispatchComputeGroupSize
=
88 Window::invalidFunctionID
;
90 UInt32
ComputeShaderAlgorithm:: FuncIdMemoryBarrier
=
91 Window::invalidFunctionID
;
93 /*-------------------------------------------------------------------------*/
96 void ComputeShaderAlgorithm::changed(ConstFieldMaskArg whichField
,
100 Inherited::changed(whichField
, origin
, details
);
103 /*-------------------------------------------------------------------------*/
106 void ComputeShaderAlgorithm::dump(
107 UInt32
OSG_CHECK_ARG(uiIndent
),
108 const BitVector
OSG_CHECK_ARG(bvFlags
)) const
110 SLOG
<< "Dump ComputeShaderAlgorithm NI" << std::endl
;
113 /*-------------------------------------------------------------------------*/
116 ComputeShaderAlgorithm::ComputeShaderAlgorithm(void) :
121 ComputeShaderAlgorithm::ComputeShaderAlgorithm(
122 const ComputeShaderAlgorithm
&source
) :
128 /*-------------------------------------------------------------------------*/
131 ComputeShaderAlgorithm::~ComputeShaderAlgorithm(void)
135 /*-------------------------------------------------------------------------*/
138 Action::ResultE
ComputeShaderAlgorithm::renderEnter(Action
*pAction
)
140 return Action::Continue
;
143 Action::ResultE
ComputeShaderAlgorithm::renderLeave(Action
*pAction
)
145 return Action::Continue
;
148 void ComputeShaderAlgorithm::execute(HardwareContext
*pContext
,
151 Window
*pWin
= pEnv
->getWindow();
153 if(!pWin
->hasExtOrVersion(_arbComputeShader
, 0x0403, 0xFFFF))
155 FWARNING(("OpenGL compute shader is not supported, couldn't find "
156 "extension 'GL_ARB_compute_shader'!\n"));
161 if(_sfUseVariableWorkGroupSize
.getValue() == true &&
162 !pWin
->hasExtOrVersion(_arbComputeVariableGroupSize
, 0x0403, 0xFFFF))
164 FWARNING(("OpenGL variable group size is not supported, couldn't find "
165 "extension 'GL_ARB_compute_variable_group_size'!\n"));
170 if(_sfUseMemoryBarrier
.getValue() == true &&
171 !pWin
->hasExtOrVersion(_arbShaderImageLoadStore
, 0x0402))
173 FWARNING(("OpenGL memory barrier is not supported, couldn't find "
174 "extension 'GL_ARB_shader_image_load_store'!\n"));
179 if(_sfComputeShader
.getValue() == NULL
)
184 MFTextureImagesType::const_iterator tIt
= _mfTextureImages
.begin();
185 MFTextureImagesType::const_iterator tEnd
= _mfTextureImages
.end ();
189 for(; tIt
!= tEnd
; ++tIt
, ++uiSlot
)
193 (*tIt
)->activate(pEnv
, uiSlot
);
197 _sfComputeShader
.getValue()->activate(pEnv
, 0);
200 // Buffer objects might introspect the shader code. Therefore their activation must
201 // happen after the activation of the shader itself.
203 if (_sfChunkMaterial
.getValue() != NULL
)
205 const MFUnrecStateChunkPtr
*chunks
= _sfChunkMaterial
.getValue()->getMFChunks();
206 const MFInt32
*slots
= _sfChunkMaterial
.getValue()->getMFSlots ();
208 for(SizeT i
= 0; i
< chunks
->size(); ++i
)
210 StateChunk
* chunk
= (*chunks
)[i
];
213 UInt32 slot
= (*slots
)[i
];
215 if ( chunk
->getType().isDerivedFrom(ShaderStorageBufferObjChunk::getClassType())
216 || chunk
->getType().isDerivedFrom(ShaderStorageBufferObjRefChunk::getClassType())
217 || chunk
->getType().isDerivedFrom(ShaderStorageBufferObjStdLayoutChunk::getClassType())
218 || chunk
->getType().isDerivedFrom(UniformBufferObjChunk::getClassType())
219 || chunk
->getType().isDerivedFrom(UniformBufferObjStd140Chunk::getClassType())
220 || chunk
->getType().isDerivedFrom(TextureImageChunk::getClassType())
223 chunk
->activate(pEnv
, slot
);
229 if (_sfUseVariableWorkGroupSize
.getValue() == true)
231 OSGGETGLFUNCBYID_GL4(glDispatchComputeGroupSizeARB
,
232 osgGlDispatchComputeGroupSizeARB
,
233 ComputeShaderAlgorithm::FuncIdDispatchComputeGroupSize
,
236 osgGlDispatchComputeGroupSizeARB(_sfDispatchConfig
.getValue()[0],
237 _sfDispatchConfig
.getValue()[1],
238 _sfDispatchConfig
.getValue()[2],
239 _sfWorkGroupSize
.getValue()[0],
240 _sfWorkGroupSize
.getValue()[1],
241 _sfWorkGroupSize
.getValue()[2]);
245 OSGGETGLFUNCBYID_GL4(glDispatchCompute
,
246 osgGlDispatchCompute
,
247 ComputeShaderAlgorithm::FuncIdDispatchCompute
,
250 osgGlDispatchCompute(_sfDispatchConfig
.getValue()[0],
251 _sfDispatchConfig
.getValue()[1],
252 _sfDispatchConfig
.getValue()[2]);
255 if (_sfUseMemoryBarrier
.getValue() == true)
257 OSGGETGLFUNCBYID_GL4(glMemoryBarrier
,
259 ComputeShaderAlgorithm::FuncIdMemoryBarrier
,
262 osgGlMemoryBarrier(_sfMemoryBarrier
.getValue());
265 _sfComputeShader
.getValue()->deactivate(pEnv
, 0);
267 if (_sfChunkMaterial
.getValue() != NULL
)
269 const MFUnrecStateChunkPtr
*chunks
= _sfChunkMaterial
.getValue()->getMFChunks();
270 const MFInt32
*slots
= _sfChunkMaterial
.getValue()->getMFSlots ();
272 for(SizeT i
= 0; i
< chunks
->size(); ++i
)
274 StateChunk
* chunk
= (*chunks
)[i
];
277 UInt32 slot
= (*slots
)[i
];
279 if ( chunk
->getType().isDerivedFrom(ShaderStorageBufferObjChunk::getClassType())
280 || chunk
->getType().isDerivedFrom(ShaderStorageBufferObjRefChunk::getClassType())
281 || chunk
->getType().isDerivedFrom(ShaderStorageBufferObjStdLayoutChunk::getClassType())
282 || chunk
->getType().isDerivedFrom(UniformBufferObjChunk::getClassType())
283 || chunk
->getType().isDerivedFrom(UniformBufferObjStd140Chunk::getClassType())
284 || chunk
->getType().isDerivedFrom(TextureImageChunk::getClassType())
287 chunk
->deactivate(pEnv
, slot
);
293 tIt
= _mfTextureImages
.begin();
296 for(; tIt
!= tEnd
; ++tIt
, ++uiSlot
)
300 (*tIt
)->deactivate(pEnv
, uiSlot
);
307 /*-------------------------------------------------------------------------*/
310 /*-------------------------------------------------------------------------*/
313 void ComputeShaderAlgorithm::initMethod(InitPhase ePhase
)
315 Inherited::initMethod(ePhase
);
317 if(ePhase
== TypeObject::SystemPost
)
320 Window::registerExtension("GL_ARB_compute_shader");
322 _arbComputeVariableGroupSize
=
323 Window::registerExtension("GL_ARB_compute_variable_group_size");
325 _arbShaderImageLoadStore
=
326 Window::registerExtension("GL_ARB_shader_image_load_store");
328 FuncIdDispatchCompute
=
329 Window::registerFunction
330 (OSG_DLSYM_UNDERSCORE
"glDispatchCompute",
333 FuncIdDispatchComputeGroupSize
=
334 Window::registerFunction
335 (OSG_DLSYM_UNDERSCORE
"glDispatchComputeGroupSizeARB",
336 _arbComputeVariableGroupSize
);
338 FuncIdMemoryBarrier
=
339 Window::registerFunction
340 (OSG_DLSYM_UNDERSCORE
"glMemoryBarrier",
341 _arbShaderImageLoadStore
);