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() {
_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) {
@ -35,6 +37,8 @@ bool DebugHmdDisplayPlugin::beginFrameRender(uint32_t frameIndex) {
// FIXME simulate head movement
//_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([&] {
_frameInfos[frameIndex] = _currentRenderFrameInfo;
@ -71,6 +75,7 @@ bool DebugHmdDisplayPlugin::internalActivate() {
_eyeOffsets[1][3] = vec4{ 0.0327499993, 0.0, -0.0149999997, 1.0 };
_renderTargetSize = { 3024, 1680 };
_cullingProjection = _eyeProjections[0];
// This must come after the initialization, so that the values calculated
// above are available during the customizeContext call (when not running
// in threaded present mode)

View file

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

View file

@ -36,7 +36,8 @@
#define GPU_STEREO_TECHNIQUE_DOUBLED_SIMPLE
#else
//#define GPU_STEREO_TECHNIQUE_DOUBLED_SMARTER
#define GPU_STEREO_TECHNIQUE_INSTANCED
//#define GPU_STEREO_TECHNIQUE_INSTANCED
#define GPU_STEREO_TECHNIQUE_INSTANCED_MULTIVIEWPORT
#endif
// Let these be configured by the one define picked above
@ -51,6 +52,13 @@
#ifdef GPU_STEREO_TECHNIQUE_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
#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_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;
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;
}
}
#endif
}
#else
if (!_inRenderTransferPass && !isStereo()) {
@ -123,7 +163,7 @@ void GLBackend::TransformStageState::preUpdate(size_t commandIndex, const Stereo
if (_invalidView || _invalidProj || _invalidViewport) {
size_t offset = _cameraUboSize * _cameras.size();
Vec2 finalJitter = _projectionJitter / Vec2(framebufferSize);
Vec2 finalJitter = _projectionJitter / Vec2(framebufferSize);
_cameraOffsets.push_back(TransformStageState::Pair(commandIndex, offset));
if (stereo.isStereo()) {

View file

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

View file

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

View file

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