Now there is a further hangup. Try changing the line count in line 22 of the program to 768 and see tearing at the top of the frame (at least I do). So I made an educated guess and subtracted 16 from the line count and the tearing went away, so maybe there is a bug in DirectX?
All true. There will have to be synchronization between drawing and buffer flipping.if you write to the Screen before it is flipped, you will write
to the false buffer. So you need to wait until the flip is finished.
It can be just possible, that you could write onto a sprite while
waiting for the flip and until the sprite is finished and the flip is
done, write the sprite to the screen, start waiting for the next
flip and draw the next frame onto the sprite. That would be
something like a dripple buffer.
Code: Select all
Global now.q, then.q, maxFreq.q, ct, null = 0, threadID1, readyFlag, threadKillFlag = #False
Global Dim duration.f(100)
Structure D3DRaster_STATUS
InVBlank.l
ScanLine.l
EndStructure
Define.D3DRaster_STATUS Raster
Define.IDirect3DDevice9 D3DDeviceInterface
Procedure Flip(null)
Shared D3DDeviceInterface, Raster, readyFlag
ct = 0
Repeat
QueryPerformanceCounter_(@then.q)
Delay(15) ;GIVE THE CPU A REST FOR APPROXIMATELY 700 SCAN LINES AT 60 Hz REFRESH RATE
Repeat
D3DDeviceInterface\GetRasterStatus(0, @Raster)
Until Raster\ScanLine = 768 - 16 ;CHANGE THIS VALUE TO 768 TO SEE TEARING AT THE TOP
;Until Raster\ScanLine = 768
FlipBuffers()
QueryPerformanceCounter_(@n.q)
dur.f = (n.q - then.q) / maxFreq
If ct < 30 And readyFlag = #True
duration(ct) = dur ;(n - then) / maxFreq
ct + 1
EndIf
If threadKillFlag = #True: KillThread(threadID1): EndIf
ForEver
EndProcedure
MessageRequester("", "When you see two colored boxes, quit by pressing any key.")
readyFlag = #False
QueryPerformanceFrequency_(@maxFreq): maxFreq / 1000
InitSprite()
InitKeyboard()
OpenScreen(1024, 768, 32, "", #PB_Screen_NoSynchronization) ;, 60)
;SetFrameRate(60)
StartDrawing(ScreenOutput())
Box(0,0,200,768, $ff0000)
StopDrawing()
FlipBuffers()
StartDrawing(ScreenOutput())
;Box(0,0,200,768, $ff0000)
Box(200,0,200,768, $00ffff)
StopDrawing()
!extrn _PB_Screen_Direct3DDevice
!MOV dword EAX, [_PB_Screen_Direct3DDevice]
!MOV dword [v_D3DDeviceInterface],EAX
threadID1 = CreateThread(@Flip(), null)
SetPriorityClass_(GetCurrentProcess_(), #REALTIME_PRIORITY_CLASS)
SetThreadPriority_(ThreadID(threadID1), #THREAD_PRIORITY_TIME_CRITICAL)
Delay(500)
readyFlag = #True
Repeat
ExamineKeyboard()
Until KeyboardPushed(#PB_Key_All)
threadKillFlag = #True
SetThreadPriority_(GetCurrentThread_(), #THREAD_PRIORITY_NORMAL)
SetPriorityClass_(GetCurrentProcess_(), #NORMAL_PRIORITY_CLASS)
CloseScreen()
OpenConsole()
For ct = 1 To 30
If duration(ct) <> 0
PrintN(StrF(duration(ct),2) + " ms" + Chr(9) + StrF(1/duration(ct)*1000,2) + " fps")
EndIf
Next
PrintN(Chr(10) + "Press any key to exit."): While Inkey() = "": Delay(5): Wend: CloseConsole()
End