HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RV_Render.h
Go to the documentation of this file.
1 
2 /*
3  * PROPRIETARY INFORMATION. This software is proprietary to
4  * Side Effects Software Inc., and is not to be reproduced,
5  * transmitted, or disclosed in any way without written permission.
6  *
7  * NAME: RV_Render.h ( RV Library, C++)
8  *
9  * COMMENTS:
10  * Class to do render work with RV library
11  * Represents the set of resources and render state
12  * for a single frame/thread
13  */
14 
15 #ifndef RV_Render_h
16 #define RV_Render_h
17 
18 #include "RV_API.h"
19 
20 #include <UT/UT_FixedArray.h>
21 #include <UT/UT_Map.h>
22 #include <UT/UT_Rect.h>
23 #include <UT/UT_Set.h>
24 #include <RE/RE_Types.h>
25 #include <UT/UT_UniquePtr.h>
26 
27 #include <utility>
28 
29 #include "RV_VK.h"
30 #include "RV_Instance.h"
31 #include "RV_ShaderBlock.h"
32 #include "RV_Type.h"
33 #include "RV_VKCommandBuffer.h"
34 #include "RV_VKDescriptorSet.h"
35 #include "RV_VKPipeline.h"
36 
37 class GR_GeoRenderVK;
38 
39 class RV_Instance;
40 class RV_Geometry;
42 class RV_ShaderProgram;
43 class RV_ShaderCompute;
45 class RV_OcclusionQuery;
46 
47 class RV_VKBuffer;
48 class RV_VKCommandBufferAllocator;
49 class RV_VKCommandBuffer;
50 class RV_Framebuffer;
51 class RV_VKImage;
53 
56 
57 typedef std::pair<VkPipelineStageFlags,VkPipelineStageFlags> RV_BarrierScope;
58 
60 
61 /// Per-thread object for rendering Vulkan objects, which maintains the state
62 /// and a cache of various Vulkan entities
64 {
65 public:
66  RV_Render(RV_Instance* inst);
67  ~RV_Render();
68 
69  RV_Render(const RV_Render&) = delete;
70  RV_Render(RV_Render&&) = delete;
71 
72  /// The instance associated with this render
73  RV_Instance* instance() { return myInst; }
74  /// The raw vulkan device
75  VkDevice device() { return myInst->getDevice(); }
76 
77  // Current Command buffer
78  // - separate Compute + Transfer + Main CB?
79  // - functions to start command buffer
80  // - functions to flush command buffer
81  // - function to get command buffer
82  /// The currently recording command buffer
83  RV_VKCommandBuffer* getCurrentCB();
84 
85  /// Start rendering a single frame
86  void beginFrame();
87  /// End rendering a single frame
88  void endFrame();
89  /// Returns true if currently rendering a frame
90  bool isInFrame() { return myIsInFrame; }
91 
92  /// Begin rendering to the current framebuffer. 'img_op' can be LOAD (keep
93  /// contents), CLEAR (discard and set to a constant) or DONT_CARE.
94  bool beginRendering(RV_ImageOp img_op = RV_IMAGE_LOAD);
95  /// End rendering.
96  void endRendering();
97  /// Query if Vulkan is rendering. Cannot upload buffers or textures while
98  /// rendering.
99  bool isRendering();
100 
101  // --------------------------------
102  // Render State
103  // helper class to hold the required render state
104  // Includes (TODO):
105  // - current command buffer
106  // - pipeline state (all elements provided in pipeline creation
107  // - current bound pipeline
108  // - current descriptor sets
109  // - current framebuffer + render pass
110  // - current vertex state (i.e. which vert buffers bound)
111  // - current clear color / clear depth
112 
113  /// Reset the cached render state in this object to Vulkan defaults.
114  void resetRenderState();
115 
116  /// Return the current pipeline State
117  RV_VKPipelineStateInfo* getPipelineState() { return &pipeState(); }
118 
119  // shader state
120 
121  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
122  // Pipeline State
123 
124  // state management
125 
126  /// Reset the pipeline state to Vulkan defaults.
127  void resetPipeState();
128  /// Send the current pipeline state to the GPU.
129  void commitPipeState();
130  /// Save the existing state so that the state can be modified, then restored
131  /// to its previous state with popPipeState()
132  void pushPipeState();
133  /// Restore the pipeline state from a previous pushPipeState().
134  void popPipeState();
135 
136  // Poly Raster + Sample State
137  /// Set the sample mask for multisample rendering
138  void setSampleMask(uint32 mask);
139  /// Set the color channel mask
140  void setColorMask(bool red, bool green, bool blue, bool alpha);
141  /// Set the primitive culling mode, for backface or frontface culling
142  void setCullMode(bool enable, bool back_face = true, bool is_ccw = true);
143  /// Set the width of line primitives (may not be supported on all platforms)
144  void setLineWidth(float width);
145  /// Set the polygon draw mode - FILL (normal), LINES (outline),
146  /// POINTS (vertices).
147  void setPolygonMode(RV_PolygonMode mode);
148 
149  // Depth State
150 
151  /// Set the depth state for zbuffer operations.
152  void setDepthState(
153  bool enable,
155  bool writing = true,
156  float near = 0.0,
157  float far = 1.0,
158  bool clamp = false);
159  /// Set the polygon depth bias to reduce z-fighting for overlapping objects
160  void setDepthBias(bool enable, float zconst, float zslope, float clamp = 0.f);
161  // If true, depth is reversed (near at 1.0, far at 0.0). Any calls to set
162  // depth state will reverse the z function.
163 
164  /// Convenience method to map near to 1.0 and far to 0.0 so that the depth
165  /// state will be converted to the correct comparisons (LESS -> GREATER)
166  void setReverseDepth(bool reverse);
167  /// Query if reverse depth mapping is enabled.
168  bool isReverseDepth() const { return myIsReverseDepth; }
169 
170  // Stencil State
171 
172  /// Enable stencil buffer rendering. Framebuffer must have a stencil buffer.
173  void setStencilEnable(bool enable);
174  /// Define the stencil test
175  void setStencilTest(
177  uint8 ref,
178  uint8 compare_mask,
179  bool set_back = true);
180  /// Define the stencil operation based on the stencil test result. If
181  /// 'set_back' is true, also set the same values for backfacing polygons.
182  void setStencilOp(
183  RE_SOperation stencil_fail,
184  RE_SOperation depth_fail,
185  RE_SOperation pass,
186  uint8 write_mask,
187  bool set_back = true);
188  /// Define the stencil test for backfacing polygons
189  void setStencilBackTest(
191  uint8 ref,
192  uint8 compare_mask);
193  /// Define the stencil operation for backfacing polygons
194  void setStencilBackOp(
195  RE_SOperation stencil_fail,
196  RE_SOperation depth_fail,
197  RE_SOperation pass,
198  uint8 write_mask);
199 
200  // TODO: logic state set
201 
202  /// Define the viewport for rendering
203  void setViewport2DI(bool enable, const UT_DimRect &rect);
204 
205  /// Define the scissor (clip) area
206  void setScissor2DI(bool enable, const UT_DimRect &rect);
207 
208  /// Enable logic operations instead of color, plus the operation (AND,OR,etc)
209  void setLogicOp(bool enable, RV_LogicOp = RV_LOGIC_NO_OP);
210 
211  // Blend State
212  /// Enable framebuffer blending
213  void setBlendEnable(bool blend);
214 
215  // functions to set color/alpha separately
216 
217  /// Set the blending weights for color and alpha
218  void setBlendFunction(RE_BlendSourceFactor source_factor,
219  RE_BlendDestFactor dest_factor);
220  /// Set the blending weights for color only
221  void setColorBlendFunction(RE_BlendSourceFactor source_factor,
222  RE_BlendDestFactor dest_factor);
223  /// Set the blending weights for alpha only
224  void setAlphaBlendFunction(RE_BlendSourceFactor source_factor,
225  RE_BlendDestFactor dest_factor);
226  /// Set the blending operator (add, subtract, multiply, etc)
227  void setBlendEquation(RE_BlendEquation eq);
228 
229 
230  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
231  // Command Buffer Binding State
232 
234  {
235  DrawTask() = default;
236  virtual ~DrawTask() {};
237 
238  virtual bool runDraw(RV_Render* r) = 0;
239  };
240 
241  struct DrawState
242  {
243  // Bound sets
245 
246  // Bound pipeline
249 
251  };
252 
254  {
256  int connect,
257  const RV_OverrideList* override_list,
258  int inst = -1)
259  : myGeo(geo)
260  , myConnectGroup(connect)
261  , myConnectRange(1)
262  , myInstanceGroup(inst)
263  , myOverrides(override_list ? *override_list : RV_OverrideList())
264  {
265  }
266 
268  int connect,
269  int connect_num,
270  const RV_OverrideList* override_list,
271  int inst = -1)
272  : myGeo(geo)
273  , myConnectGroup(connect)
274  , myConnectRange(connect_num)
275  , myInstanceGroup(inst)
276  , myOverrides(override_list ? *override_list : RV_OverrideList())
277  {
278  }
279 
280  ~DefaultDrawTask() override {}
281 
282  bool runDraw(RV_Render* r) override;
283 
284  // Bound Vertex state + Input State
285  // plus draw params needed for geo to get vert + idx buffers
291  };
292 // WIP: allow recording bind state for deferring draws
293 #define WIP_VULKAN_DEFER_DRAW
294 #ifdef WIP_VULKAN_DEFER_DRAW
296  bool myIsDeferring = false;
297 
298  void clearDraws();
299  void queueDraw(
300  RV_Geometry* geo,
301  int connect,
302  int connect_num,
303  const RV_OverrideList* override_list,
304  int inst = -1);
306  void runDraws();
307 #endif
308 
309  // call vkCmdBind functions for all bound state
310  void refreshBindings();
311 
312  // should be called before a draw
313  bool prepareForDraw();
314 
316  {
317 #ifdef WIP_VULKAN_DEFER_DRAW
318  UT_ASSERT_MSG(!myIsDeferring, "RV_Render::getPushConstants "
319  "Called while in deferred mode, bound values will likely "
320  "be lost");
321 #endif
322  return myPushConstants;
323  }
324 
325  /// Return the bound variable set at index 'set_num'
326  RV_ShaderVariableSet* getSet(int set_num);
327  /// Remove a bound variable set by index
328  void unbindSet(int set_num);
329  /// Remove a bound variable set by object
330  void unbindSet(RV_ShaderVariableSet* set);
331  /// Bind a variable set to the specific shader program
332  bool bindSet(RV_ShaderVariableSet* set,
333  const RV_ShaderProgramBase* shr);
334 
335  /// Store the current shader
336  void pushShader();
337  /// Store the current shader and set the new shader to 'sh'
339  /// Restore the previous shader saved by pushShader()
340  void popShader();
341  /// Set the current shader to 'sh'
343  /// Get the current shader.
345  /// Get the current graphics shader. If the current shader is compute, return
346  /// null.
348  /// Get the current compute shader. If the current shader is graphics, return
349  /// null.
351 
352  /// Save the current render framebuffer
353  void pushDrawFramebuffer();
354  /// Save the current render framebuffer and make a new framebuffer active
356  /// Restore the previously pushed framebuffer from pushDrawFramebuffer().
357  void popDrawFramebuffer();
358  /// Make a new framebuffer active
360  /// Get the current framebuffer (may be null)
362 
363  /// Return the currently active occlusion query
364  const RV_OcclusionQuery* getQuery() const { return myCurOccludeQuery; }
365  /// Make occlusion query 'q' the active query (only 1 can be active at once)
367  { myCurOccludeQuery = q; }
368 
369  // TODO:
370  // void bindVertexState();
371 
372  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
373  // Actions
374 
375  /// End the current command buffer and start a new one. Wait until it is
376  /// executed if 'wait_for_finish' is true.
377  void flush(bool wait_for_finish);
378 
379  /// Run the current compute shader with explicit workgroup sizes. Returns
380  /// false if there is no compute shader bound.
381  bool runCompute(int wg_x, int wg_y, int wg_z);
382  /// Run the current compute shader with workgroup sizes stored in the given
383  /// buffer. Returns false if there is no compute shader bound.
385 
386  /// Draw the geometry 'geo' with the given connectivity group
387  void draw(
388  RV_Geometry* geo,
389  int connect_index,
390  const RV_OverrideList* override_list = nullptr);
391  /// Draw the geometry 'geo' with instancing with the given connectivity group
392  /// abd given instance group
393  void drawInstanced(
394  RV_Geometry* geo,
395  int connect_index,
396  int instance_group,
397  const RV_OverrideList* override_list = nullptr);
398 
399  /// Draw a range of connectivity groups
400  void drawRange(
401  RV_Geometry* geo,
402  int connect_index,
403  int connect_num,
404  const RV_OverrideList* override_list = nullptr);
405 
406  /// Draw using instancing a range of connectivity groups
407  void drawInstancedRange(
408  RV_Geometry* geo,
409  int connect_index,
410  int connect_num,
411  int inst_group,
412  const RV_OverrideList* override_list= nullptr);
413 
414  /// Render a deferred draw task
415  void draw(UT_UniquePtr<DrawTask> task);
416 
417 
418  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
419  // Sync
420 #define WIP_VULKAN_DEFER_BARRIERS
421 #ifdef WIP_VULKAN_DEFER_BARRIERS
422 
423  /// Add a barrier for buffer synchronization
424  void addBufferBarrier(
425  RV_BarrierScope scope,
426  const VkBufferMemoryBarrier& barrier,
427  RV_VKBuffer* buf);
428  /// Add a barrier for image synchronization
429  void addImageBarrier(
430  RV_BarrierScope scope,
431  const VkImageMemoryBarrier& barrier,
432  RV_VKImage* img);
433 
434  /// Remove all currently added barriers
435  void clearBarriers();
436  /// Execute all commands with barriers
437  void executeAllBarriers();
438  /// Execute all commands on some queues (graphics, compute, transfer).
440 
442  {
448  };
449 
450  // List of barriers waiting to be added to the commandbuffer
451  // -- any barrier MUST be added before a command in its DST stage is run
452  // inserted by DST RV_STAGE_GROUP
455 
456  // List of barriers that have been added, and were added later than ALL
457  // cmds included from their src stage -- inserted by SRC RV_STAGE_GROUP
459 
460  // counters for debugging
461  int myFrameExecBarrierCount = 0;
462  int myFrameMemBarrierCount = 0;
463 #endif
464 
465 private:
466  void privInitCB();
467  void privSubmitCB(bool wait_for_finish);
468 
469  // Vulkan Instance used to create this render
470  RV_Instance* myInst;
471 
473  RV_VKCommandBuffer* myCurrentCB = nullptr;
474 
475  // Pipeline state -- i.e. state that is part of dynamic state
476  // compiled into graphics pipeline
477  UT_Array<RV_VKPipelineStateInfo> myPipeStateStack;
478  RV_VKPipelineStateInfo& pipeState();
479 
480  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
481  // Binding State
482  static const int theMaxSets = 8;
484  UT_Array<bool> myDirtySetFlags;
485 
486  UT_Array<RV_ShaderProgramBase*> myShaderStack;
487  UT_Array<RV_Framebuffer*> myFramebufferStack;
488  RV_OcclusionQuery* myCurOccludeQuery = nullptr;
489 
490  RV_PushConstants myPushConstants;
491 
492  bool myIsInFrame = false;
493  bool myIsRendering = false;
494  bool myIsReverseDepth = false;
495 };
496 
497 /// Destroy VK resource after command buffer is executed,
498 /// when it will no longer be in-use by the GPU
499 template<class T>
501 {
503 }
504 
505 #endif
A collection of Vulkan UBO, SSBO, and Image shader bindings (descriptor set)
void drawInstanced(RV_Geometry *geo, int connect_index, int instance_group, const RV_OverrideList *override_list=nullptr)
RV_VKPipelineStateInfo * getPipelineState()
Return the current pipeline State.
Definition: RV_Render.h:117
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glcorearb.h:2540
bool runCompute(int wg_x, int wg_y, int wg_z)
RV_PushConstants & getPushConstants()
Definition: RV_Render.h:315
VkDevice device()
The raw vulkan device.
Definition: RV_Render.h:75
void addBufferBarrier(RV_BarrierScope scope, const VkBufferMemoryBarrier &barrier, RV_VKBuffer *buf)
Add a barrier for buffer synchronization.
RV_ImageOp
Definition: RV_Type.h:390
RV_ShaderProgram * getGraphicsShader()
Unsorted map container.
Definition: UT_Map.h:107
UT_Array< RV_VKBuffer * > myBuffers
Definition: RV_Render.h:446
void pushShader()
Store the current shader.
UT_UniquePtr< DrawTask > myTask
Definition: RV_Render.h:250
GLbitfield stages
Definition: glcorearb.h:1931
GLenum clamp
Definition: glcorearb.h:1234
void executeAllBarriers()
Execute all commands with barriers.
const GLdouble * v
Definition: glcorearb.h:837
void pushDrawFramebuffer()
Save the current render framebuffer.
RV_ShaderVariableSet * getSet(int set_num)
Return the bound variable set at index 'set_num'.
void setQuery(RV_OcclusionQuery *q)
Make occlusion query 'q' the active query (only 1 can be active at once)
Definition: RV_Render.h:366
UT_Array< RV_VKImage * > myImages
Definition: RV_Render.h:447
void draw(RV_Geometry *geo, int connect_index, const RV_OverrideList *override_list=nullptr)
Draw the geometry 'geo' with the given connectivity group.
int64 exint
Definition: SYS_Types.h:125
RV_StageGroup
Definition: RV_Type.h:429
Object that represents drawable geometry. This object holds vertex, instancing and index buffers for ...
Definition: RV_Geometry.h:164
void executeBarriers(RV_StageGroup stages)
Execute all commands on some queues (graphics, compute, transfer).
void reverse(I begin, I end)
Definition: pugixml.cpp:7190
RV_ShaderProgramBase * getShader()
Get the current shader.
void drawInstancedRange(RV_Geometry *geo, int connect_index, int connect_num, int inst_group, const RV_OverrideList *override_list=nullptr)
Draw using instancing a range of connectivity groups.
std::pair< VkPipelineStageFlags, VkPipelineStageFlags > RV_BarrierScope
Definition: RV_Render.h:55
RV_VKCommandBuffer::Callback RVmakeDestroyPtrTask(UT_UniquePtr< T > obj)
void flush(bool wait_for_finish)
VkFlags VkPipelineStageFlags
Definition: vulkan_core.h:2401
GLdouble GLdouble GLdouble q
Definition: glad.h:2445
GLdouble far
Definition: glcorearb.h:143
void unbindSet(int set_num)
Remove a bound variable set by index.
DefaultDrawTask(RV_Geometry *geo, int connect, const RV_OverrideList *override_list, int inst=-1)
Definition: RV_Render.h:255
void clearBarriers()
Remove all currently added barriers.
RV_VKCommandBuffer * getCurrentCB()
The currently recording command buffer.
UT_Array< VkBufferMemoryBarrier > myBufBarriers
Definition: RV_Render.h:444
UT_FixedArray< rv_BarrierMap, RV_STAGE_NUM > myWaitingBarriers
Definition: RV_Render.h:454
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
#define UT_ASSERT_MSG(ZZ,...)
Definition: UT_Assert.h:159
unsigned char uint8
Definition: SYS_Types.h:36
vint4 blend(const vint4 &a, const vint4 &b, const vbool4 &mask)
Definition: simd.h:4784
virtual ~DrawTask()
Definition: RV_Render.h:236
bool prepareForDraw()
GLfloat f
Definition: glcorearb.h:1926
bool isInFrame()
Returns true if currently rendering a frame.
Definition: RV_Render.h:90
Compute shader object.
GLintptr offset
Definition: glcorearb.h:665
std::array< T, N > UT_FixedArray
Definition: UT_FixedArray.h:19
UT_Array< DrawState > myRecordedDraws
Definition: RV_Render.h:295
GLint ref
Definition: glcorearb.h:124
DefaultDrawTask(RV_Geometry *geo, int connect, int connect_num, const RV_OverrideList *override_list, int inst=-1)
Definition: RV_Render.h:267
void setShader(RV_ShaderProgramBase *sh)
Set the current shader to 'sh'.
UT_Array< RV_ShaderVariableSet * > mySets
Definition: RV_Render.h:244
const RV_OcclusionQuery * getQuery() const
Return the currently active occlusion query.
Definition: RV_Render.h:364
Occlusion query object.
Definition: RV_Query.h:31
RV_VKPipelineStateInfo myPipelineState
Definition: RV_Render.h:248
UT_Array< VkMemoryBarrier > myGenBarriers
Definition: RV_Render.h:445
GLfloat green
Definition: glcorearb.h:112
RV_PolygonMode
Definition: RV_Type.h:413
GLint GLuint mask
Definition: glcorearb.h:124
#define RV_API
Definition: RV_API.h:10
RV_StageGroup RVgetStageGroup(VkPipelineStageFlags stage_bits)
UT_Array< VkImageMemoryBarrier > myImgBarriers
Definition: RV_Render.h:443
RE_BlendEquation
Definition: RE_Types.h:532
GLfloat GLfloat GLfloat alpha
Definition: glcorearb.h:112
RE_ZFunction
Definition: RE_Types.h:471
bool isReverseDepth() const
Query if reverse depth mapping is enabled.
Definition: RV_Render.h:168
Handle to the main interface of Vulkan.
Definition: RV_Instance.h:36
bool runComputeIndirect(RV_VKBuffer *buf, exint offset=0)
GLint void * img
Definition: glcorearb.h:556
void bindDrawFramebuffer(RV_Framebuffer *fb)
Make a new framebuffer active.
void popDrawFramebuffer()
Restore the previously pushed framebuffer from pushDrawFramebuffer().
void RVdestroyVKPtr(RV_Render *r, UT_UniquePtr< T > v)
Definition: RV_Render.h:500
void addCompletionCallback(const Callback &callback)
GLenum mode
Definition: glcorearb.h:99
RV_Instance * instance()
The instance associated with this render.
Definition: RV_Render.h:73
void popShader()
Restore the previous shader saved by pushShader()
UT_Map< RV_BarrierScope, rv_MemoryBarriers > rv_BarrierMap
Definition: RV_Render.h:453
GLenum func
Definition: glcorearb.h:783
RV_Framebuffer * getDrawFramebuffer()
Get the current framebuffer (may be null)
RV_LogicOp
Definition: RV_Type.h:420
RE_SOperation
Definition: RE_Types.h:495
UT_FixedArray< UT_Set< RV_BarrierScope >, RV_STAGE_NUM > myActiveBarriers
Definition: RV_Render.h:458
RE_BlendSourceFactor
Definition: RE_Types.h:507
RV_ShaderProgram * myShader
Definition: RV_Render.h:247
unsigned int uint32
Definition: SYS_Types.h:40
GLint GLsizei width
Definition: glcorearb.h:103
void runDraws()
void queueDraw(RV_Geometry *geo, int connect, int connect_num, const RV_OverrideList *override_list, int inst=-1)
void addImageBarrier(RV_BarrierScope scope, const VkImageMemoryBarrier &barrier, RV_VKImage *img)
Add a barrier for image synchronization.
GLboolean r
Definition: glcorearb.h:1222
GLfloat GLfloat blue
Definition: glcorearb.h:112
A vulkan buffer object.
Definition: RV_VKBuffer.h:80
void drawRange(RV_Geometry *geo, int connect_index, int connect_num, const RV_OverrideList *override_list=nullptr)
Draw a range of connectivity groups.
virtual bool runDraw(RV_Render *r)=0
RV_OverrideList myOverrides
Definition: RV_Render.h:290
RV_ShaderCompute * getComputeShader()
RE_SFunction
Definition: RE_Types.h:483
png_structrp int png_fixed_point red
Definition: png.h:1083
void refreshBindings()
void clearDraws()
bool bindSet(RV_ShaderVariableSet *set, const RV_ShaderProgramBase *shr)
Bind a variable set to the specific shader program.
RE_BlendDestFactor
Definition: RE_Types.h:520