exploring better stereo drawcall techniques

This commit is contained in:
Sam Gateau 2018-11-30 00:42:49 -08:00
parent 6b163f0a17
commit 74bedbc2cc
7 changed files with 73 additions and 6 deletions

View file

@ -26,6 +26,8 @@ bool DebugHmdDisplayPlugin::isSupported() const {
void DebugHmdDisplayPlugin::resetSensors() { void DebugHmdDisplayPlugin::resetSensors() {
_currentRenderFrameInfo.renderPose = glm::mat4(); // identity _currentRenderFrameInfo.renderPose = glm::mat4(); // identity
_currentRenderFrameInfo.renderPose = glm::translate(glm::mat4(), glm::vec3(0.0f, 1.76f, 0.0f));
} }
bool DebugHmdDisplayPlugin::beginFrameRender(uint32_t frameIndex) { bool DebugHmdDisplayPlugin::beginFrameRender(uint32_t frameIndex) {
@ -35,6 +37,8 @@ bool DebugHmdDisplayPlugin::beginFrameRender(uint32_t frameIndex) {
// FIXME simulate head movement // FIXME simulate head movement
//_currentRenderFrameInfo.renderPose = ; //_currentRenderFrameInfo.renderPose = ;
//_currentRenderFrameInfo.presentPose = _currentRenderFrameInfo.renderPose; //_currentRenderFrameInfo.presentPose = _currentRenderFrameInfo.renderPose;
_currentRenderFrameInfo.renderPose = glm::translate(glm::mat4(), glm::vec3(0.0f, 1.76f, 0.0f));
_currentRenderFrameInfo.presentPose = _currentRenderFrameInfo.renderPose;
withNonPresentThreadLock([&] { withNonPresentThreadLock([&] {
_frameInfos[frameIndex] = _currentRenderFrameInfo; _frameInfos[frameIndex] = _currentRenderFrameInfo;
@ -71,6 +75,7 @@ bool DebugHmdDisplayPlugin::internalActivate() {
_eyeOffsets[1][3] = vec4{ 0.0327499993, 0.0, -0.0149999997, 1.0 }; _eyeOffsets[1][3] = vec4{ 0.0327499993, 0.0, -0.0149999997, 1.0 };
_renderTargetSize = { 3024, 1680 }; _renderTargetSize = { 3024, 1680 };
_cullingProjection = _eyeProjections[0]; _cullingProjection = _eyeProjections[0];
// This must come after the initialization, so that the values calculated // This must come after the initialization, so that the values calculated
// above are available during the customizeContext call (when not running // above are available during the customizeContext call (when not running
// in threaded present mode) // in threaded present mode)

View file

@ -410,20 +410,24 @@ void GLBackend::render(const Batch& batch) {
renderPassTransfer(batch); renderPassTransfer(batch);
} }
#ifdef GPU_STEREO_DRAWCALL_INSTANCED //#ifdef GPU_STEREO_DRAWCALL_INSTANCED
#ifdef GPU_STEREO_VIEWPORT_CLIPPED
if (_stereo.isStereo()) { if (_stereo.isStereo()) {
glEnable(GL_CLIP_DISTANCE0); glEnable(GL_CLIP_DISTANCE0);
} }
#endif #endif
//#endif
{ {
PROFILE_RANGE(render_gpu_gl_detail, _stereo.isStereo() ? "Render Stereo" : "Render"); PROFILE_RANGE(render_gpu_gl_detail, _stereo.isStereo() ? "Render Stereo" : "Render");
renderPassDraw(batch); renderPassDraw(batch);
} }
#ifdef GPU_STEREO_DRAWCALL_INSTANCED //#ifdef GPU_STEREO_DRAWCALL_INSTANCED
#ifdef GPU_STEREO_VIEWPORT_CLIPPED
if (_stereo.isStereo()) { if (_stereo.isStereo()) {
glDisable(GL_CLIP_DISTANCE0); glDisable(GL_CLIP_DISTANCE0);
} }
#endif #endif
//#endif
// Restore the saved stereo state for the next batch // Restore the saved stereo state for the next batch
_stereo._enable = savedStereo; _stereo._enable = savedStereo;

View file

@ -36,7 +36,8 @@
#define GPU_STEREO_TECHNIQUE_DOUBLED_SIMPLE #define GPU_STEREO_TECHNIQUE_DOUBLED_SIMPLE
#else #else
//#define GPU_STEREO_TECHNIQUE_DOUBLED_SMARTER //#define GPU_STEREO_TECHNIQUE_DOUBLED_SMARTER
#define GPU_STEREO_TECHNIQUE_INSTANCED //#define GPU_STEREO_TECHNIQUE_INSTANCED
#define GPU_STEREO_TECHNIQUE_INSTANCED_MULTIVIEWPORT
#endif #endif
// Let these be configured by the one define picked above // Let these be configured by the one define picked above
@ -51,6 +52,13 @@
#ifdef GPU_STEREO_TECHNIQUE_INSTANCED #ifdef GPU_STEREO_TECHNIQUE_INSTANCED
#define GPU_STEREO_DRAWCALL_INSTANCED #define GPU_STEREO_DRAWCALL_INSTANCED
#define GPU_STEREO_VIEWPORT_CLIPPED
#define GPU_STEREO_CAMERA_BUFFER
#endif
#ifdef GPU_STEREO_TECHNIQUE_INSTANCED_MULTIVIEWPORT
#define GPU_STEREO_DRAWCALL_INSTANCED
#define GPU_STEREO_MULTI_VIEWPORT
#define GPU_STEREO_CAMERA_BUFFER #define GPU_STEREO_CAMERA_BUFFER
#endif #endif

View file

@ -39,6 +39,45 @@ void GLBackend::do_setViewportTransform(const Batch& batch, size_t paramOffset)
#ifdef GPU_STEREO_DRAWCALL_INSTANCED #ifdef GPU_STEREO_DRAWCALL_INSTANCED
{ {
#ifdef GPU_STEREO_MULTI_VIEWPORT
ivec4& vp = _transform._viewport;
auto sideWidth = vp.z / 2;
vec4 leftRight[3];
// Mono
leftRight[0] = vp;
// Left side
leftRight[1] = vp;
leftRight[1].x = 0;
leftRight[1].z = sideWidth;
// right side
leftRight[2] = vp;
leftRight[2].x = sideWidth;
leftRight[2].z = sideWidth;
glViewportArrayv(0, 3, (float*)leftRight);
// Where we assign the GL viewport
if (_stereo.isStereo()) {
// ivec4 leftRight[3];
// leftRight[0] = vp;
vp.z /= 2;
/* leftRight[1] = vp; // left side
leftRight[2] = vp; // right side
leftRight[2].x += vp.z;
glViewportArrayv(0, 3, (float*) leftRight);
*/
if (_stereo._pass) {
vp.x += vp.z;
}
} else {
// glViewport(vp.x, vp.y, vp.z, vp.w);
}
#else
ivec4& vp = _transform._viewport; ivec4& vp = _transform._viewport;
glViewport(vp.x, vp.y, vp.z, vp.w); glViewport(vp.x, vp.y, vp.z, vp.w);
@ -49,6 +88,7 @@ void GLBackend::do_setViewportTransform(const Batch& batch, size_t paramOffset)
vp.x += vp.z; vp.x += vp.z;
} }
} }
#endif
} }
#else #else
if (!_inRenderTransferPass && !isStereo()) { if (!_inRenderTransferPass && !isStereo()) {

View file

@ -168,10 +168,15 @@ TransformObject getTransformObject() {
vec2 eyeOffsetScale = vec2(-0.5, +0.5); vec2 eyeOffsetScale = vec2(-0.5, +0.5);
uint eyeIndex = uint(_stereoSide); uint eyeIndex = uint(_stereoSide);
#ifndef GPU_GLES #ifndef GPU_GLES
#ifdef GPU_GL450
gl_ViewportIndex = _stereoSide + 1;
// gl_ViewportIndex = 2 - _stereoSide;
#else
gl_ClipDistance[0] = dot(<$clipPos$>, eyeClipEdge[eyeIndex]); gl_ClipDistance[0] = dot(<$clipPos$>, eyeClipEdge[eyeIndex]);
#endif #endif
float newClipPosX = <$clipPos$>.x * 0.5 + eyeOffsetScale[eyeIndex] * <$clipPos$>.w; #endif
<$clipPos$>.x = newClipPosX; // float newClipPosX = <$clipPos$>.x * 0.5 + eyeOffsetScale[eyeIndex] * <$clipPos$>.w;
// <$clipPos$>.x = newClipPosX;
#endif #endif
#else #else

View file

@ -1,4 +1,5 @@
#version 450 core #version 450 core
#extension GL_ARB_shader_viewport_layer_array : require
#define GPU_GL450 #define GPU_GL450
#define GPU_SSBO_TRANSFORM_OBJECT #define GPU_SSBO_TRANSFORM_OBJECT
#define BITFIELD int #define BITFIELD int

View file

@ -190,6 +190,10 @@ def processCommand(line):
if (dialect == '310es'): spirvCrossDialect = '320es' if (dialect == '310es'): spirvCrossDialect = '320es'
spirvCrossArgs = [spirvCrossExec, '--output', glslFile, spirvFile, '--version', spirvCrossDialect] spirvCrossArgs = [spirvCrossExec, '--output', glslFile, spirvFile, '--version', spirvCrossDialect]
if (dialect == '410'): spirvCrossArgs.append('--no-420pack-extension') if (dialect == '410'): spirvCrossArgs.append('--no-420pack-extension')
if (dialect == '450'):
spirvCrossArgs.append('--extension')
spirvCrossArgs.append('GL_ARB_shader_viewport_layer_array')
executeSubprocess(spirvCrossArgs) executeSubprocess(spirvCrossArgs)
else: else:
# This logic is necessary because cmake will agressively keep re-executing the shadergen # This logic is necessary because cmake will agressively keep re-executing the shadergen