[Constants]
; 0 = Regular 3D Vision
; 1 = Reversed 3D Vision
; 2 = Side by Side
; 3 = Reversed Side by Side
; 4 = Top and Bottom
; 5 = Reversed Top and Bottom
; 6 = Line interlacing
; 7 = Reversed Line interlacing
global persist $mode = 0

[Present]
; Enables a custom shader that allows the stereo output mode to be
; changed to Side-by-Side or Top-and-Bottom. If you are using SLI and this
; isn't working properly (partially blank or stuck image) you may need to also
; set StereoFlagsDX10 = 0x00000008 in the [Profile] section:

if stereo_active && $mode
	; Set IniParams only when actually running this shader and restore the
	; original value afterwards so that no one else needs to care which
	; variable we used, but at the cost of two IniParams updates per frame.
	local $bak = x
	x = $mode
	special = draw_3dmigoto_overlay
	if sli && $mode >= 2
		run = CustomShader3DVision2SBSDownscalePass1
		run = CustomShader3DVision2SBSDownscalePass2
	else
		run = CustomShader3DVision2SBS
	endif
	x = $bak
endif

;------------------------------------------------------------------------------------------------------
; The following custom shader can convert 3D Vision to Side-by-Side and
; Top-and-Bottom for use with 3D TVs & projectors - to enable this uncomment
; the 'include = ShaderFixes\3dvision2sbs.ini' in the [Include] section, set 3D
; Vision to output "checkerboard" in the control panel (which will remove the
; 720p limitation) and enable this either via the F11 key, or by setting a
; default for $\ShaderFixes\3dvision2sbs.ini\mode in the [Constants] section.
; If you are using SLI and this isn't working properly (partially blank or
; stuck image) you may need to also set StereoFlagsDX10 = 0x00000008 in the
; [Profile] section.

[Resource3DVision2SBSBackupTexture]
[CustomShader3DVision2SBS]
; Load a custom vertex + pixel shader:
vs = 3dvision2sbs.hlsl
ps = 3dvision2sbs.hlsl
; Explicitly unbind other shader types for safety:
hs = null
ds = null
gs = null
; Disable the OM blend stage that could interfere with the shader:
blend = disable
; Disable front/back face culling so the vertices can be in any rotation:
cull = none
; Use a triangle strip topology so we only have to output four vertices:
topology = triangle_strip
; Clear all render + depth targets to avoid compatibility issues:
run = BuiltInCommandListUnbindAllRenderTargets
; Bind the back buffer as a render target. set_viewport ensures that the view
; port is the size of the buffer so the draw call will work:
o0 = set_viewport bb
; Back up any textures that were in the ps-t100 slot. The CustomResource
; section will already back up a lot of state, including shaders, render
; targets, depth targets, UAVs, viewports, blend state, rasterizer state,
; primitive topology, etc. but it does not back up textures:
Resource3DVision2SBSBackupTexture = reference ps-t100
; Use the reverse stereo blit to give the shader access to the back buffers of
; both eyes:
ps-t100 = stereo2mono bb
; Some rare games (e.g. Onechanbara Z2) use MSAA back buffers, which cannot be
; directly used with the reverse stereo blit and must be resolved to non MSAA
; versions first. The symptoms will be a black screen after enabling this
; shader with F11. In that case, replace the above line with these two:
; ps-t100 = resolve_msaa bb
; ps-t100 = stereo2mono ps-t100
; Draw four vertices. The vertex shader will construct coordinates to cover the
; full screen using the SV_VertexID semantic so we don't need vertex buffers:
draw = 4, 0
; Restore the original texture from the ps-t100 slot:
post ps-t100 = reference Resource3DVision2SBSBackupTexture

[Resource3DVision2SBSHalfHeight]
height_multiply = 0.5
[Resource3DVision2SBSHalfWidth]
width_multiply = 0.5

[CustomShader3DVision2SBSDownscalePass1]
; Load a custom vertex + pixel shader:
vs = 3dvision2sbs.hlsl
ps = 3dvision2sbs_sli_downscale_pass1.hlsl
; Explicitly unbind other shader types for safety:
hs = null
ds = null
gs = null
; Disable the OM blend stage that could interfere with the shader:
blend = disable
; Disable front/back face culling so the vertices can be in any rotation:
cull = none
; Use a triangle strip topology so we only have to output four vertices:
topology = triangle_strip
; Clear all render + depth targets to avoid compatibility issues:
run = BuiltInCommandListUnbindAllRenderTargets

if $mode >= 4
	; Make our Resource3DVision2SBSHalfHeight compatible with the back buffer's
	; description, but with the height overridden in the above resource section:
	Resource3DVision2SBSHalfHeight = copy_desc bb
	; Then bind it as the render target. set_viewport ensures that the view port is
	; the size of the buffer so the draw call will work:
	o0 = set_viewport Resource3DVision2SBSHalfHeight
else
	Resource3DVision2SBSHalfWidth = copy_desc bb
	o0 = set_viewport Resource3DVision2SBSHalfWidth
endif

; Back up any textures that were in the ps-t100 slot. The CustomResource
; section will already back up a lot of state, including shaders, render
; targets, depth targets, UAVs, viewports, blend state, rasterizer state,
; primitive topology, etc. but it does not back up textures:
Resource3DVision2SBSBackupTexture = reference ps-t100
; Bind the back buffer as a texture:
ps-t100 = bb
; Draw four vertices. The vertex shader will construct coordinates to cover the
; full screen using the SV_VertexID semantic so we don't need vertex buffers:
draw = 4, 0
[CustomShader3DVision2SBSDownscalePass2]
; Load a custom vertex + pixel shader:
vs = 3dvision2sbs.hlsl
ps = 3dvision2sbs_sli_downscale_pass2.hlsl
; Explicitly unbind other shader types for safety:
hs = null
ds = null
gs = null
; Disable the OM blend stage that could interfere with the shader:
blend = disable
; Disable front/back face culling so the vertices can be in any rotation:
cull = none
; Use a triangle strip topology so we only have to output four vertices:
topology = triangle_strip
; Clear all render + depth targets to avoid compatibility issues:
run = BuiltInCommandListUnbindAllRenderTargets
; Bind the back buffer as a render target. set_viewport ensures that the view
; port is the size of the buffer so the draw call will work:
o0 = set_viewport bb
; Use the reverse stereo blit to give the shader access to the downscaled back
; buffers of both eyes:
if $mode >= 4
	ps-t100 = stereo2mono Resource3DVision2SBSHalfHeight
else
	ps-t100 = stereo2mono Resource3DVision2SBSHalfWidth
endif
; Some rare games (e.g. Onechanbara Z2) use MSAA back buffers, which cannot be
; directly used with the reverse stereo blit and must be resolved to non MSAA
; versions first. The symptoms will be a black screen after enabling this
; shader with F11. In that case, replace the above line with these two:
; ps-t100 = resolve_msaa bb
; ps-t100 = stereo2mono ps-t100
; Draw four vertices. The vertex shader will construct coordinates to cover the
; full screen using the SV_VertexID semantic so we don't need vertex buffers:
draw = 4, 0
; Restore the original texture from the ps-t100 slot:
post ps-t100 = reference Resource3DVision2SBSBackupTexture

[KeyChange3DVision2SBSOutputMode]
key = no_modifiers F11
; 0 = Regular 3D Vision
; 1 = Reversed 3D Vision
; 2 = Side by Side
; 3 = Reversed Side by Side
; 4 = Top and Bottom
; 5 = Reversed Top and Bottom
; 6 = Line interlacing
; 7 = Line interlacing reverse
$mode = 1, 2, 3, 4, 5, 6 , 7, 0
type = cycle
