|
Post by (X) on Jan 17, 2024 20:32:21 GMT 1
I asked Bing:
What does D2SwapChain do? It seems to help with screen tearing. Does it give us access to the screen as a bitmap.
Bing answered:
While D2DSwapChain does not directly give you access to D2DBitmap, you can create a D2DBitmap from the back buffer of the swap chain. This is typically done by using the CreateBitmapFromWicBitmap method. This allows you to draw onto the D2DBitmap and then present the updated image to the swap chain, which will then be displayed on the screen.
Here is a GFA provided demo...
' ' D2SwapChain ' $Library "direct2d"
Global Object Win1RT, swapchain, d2ddev, d2dcontext, d2dbitmap OpenW 1, 0, 0, 320, 360, ~15
Set Win1RT = D2GetRT(Me.hWnd) ' window RT D2SwapChain Me.hWnd, swapchain, d2ddev, d2dcontext, d2dbitmap Trace swapchain
Do Sleep Until Me Is Nothing
Sub Win_1_Paint D2BeginDraw Win1RT, D2C_White D2ForeColor = D2C_Brown D2Box 20, 20, 120, 120 D2DefLine , 0 ' no outline D2PBox 20, 150, 120, 270 ' Create and select a 50% transparent fillpattern D2DefLine ' restore default D2DefFill ARGB(128, 0, 128, 0) D2Box 70, 20, 240, 120 D2DefLine , 0 ' no outline D2PBox 70, 150, 240, 270 D2EndDraw EndSub
|
|
|
Post by Roger Cabo on Jan 17, 2024 23:37:06 GMT 1
Interesting..
Does it give us access to the screen as a bitmap? And how to access the bitmap? :-)
|
|
|
Post by (X) on Jan 18, 2024 0:35:31 GMT 1
Interesting.. Does it give us access to the screen as a bitmap? And how to access the bitmap? :-) Bing answered: While D2DSwapChain does not directly give you access to D2DBitmap...
1) You can create a D2DBitmap from the back buffer of the swap chain. This is typically done by using the CreateBitmapFromWicBitmap method.
2) This allows you to draw onto the D2DBitmap and then
3) present the updated image to the swap chain, which will then be displayed on the screen.
|
|
|
Post by Roger Cabo on Jan 18, 2024 16:55:31 GMT 1
Hmm.. I didn't understand an advantage of this process..
D2SwapChain Me.hWnd, swapchain, d2ddev, d2dcontext, d2dbitmap ...
At first i thought I'm able to display the the back buffer anywhere at the screen But it clears simply the screen.. anyway of x,y
D2Put 500,500 d2dbitmap
I wrote another example where
$Library "gfawinx" $Library "UpdateRT" $Library "direct2d"
// ........................................................................................................ // Calculate speed of passing a bitmap to D2D in real time (ouch!) // ........................................................................................................
OpenW 1, 0, 0, _X, _Y, ~15
Global Object Win1RT Set Win1RT = D2GetRT(Win_1.hWnd) Set Me = Win_1
// ........................................................................................................ // Create a bitmap in the PC Ram Type BITMAPINFOHEADER - DWord biSize - Long biWidth, biHeight - Word biPlanes, biBitCount - DWord biCompression, biSizeImage - Long biXPelsPerMeter, biYPelsPerMeter - DWord biClrUsed, biClrImportant End Type
Type BITMAPINFO bmh As BITMAPINFOHEADER End Type
Global bminfo As BITMAPINFO
bminfo.bmh.biSize = SizeOf(bminfo.bmh) bminfo.bmh.biWidth = Win_1.Width / PixelsToTwipX(1) bminfo.bmh.biHeight = Win_1.Height / PixelsToTwipY(1) bminfo.bmh.biPlanes = 1 bminfo.bmh.biBitCount = 32 // ... biCompression, biSizeImage, biXPelsPerMeter, biYPelsPerMeter, biClrUsed, und biClrImportant = 0
Global RenderBmpRamAdr As Long
// ... Create a Bitmap in the PC Ram Global RenderDib As Handle = CreateDIBSection(Null, bminfo, DIB_RGB_COLORS, V:RenderBmpRamAdr, Null, 0)
Global Object D2DRenderBMP
// ... ..................................... .... // ... I didn't understand the how it's used .... // ... ..................................... .... Global Object swapchain, d2ddev, d2dcontext, d2dbitmap D2SwapChain Me.hWnd, swapchain, d2ddev, d2dcontext, d2dbitmap
Global t# = Timer Global counter% Global frames# FontSize = 18 Do D2BeginDraw Win1RT, D2C_Black RenderLoop() // D2EndDraw // <---- Do not! Then you're able calculate performance and display by simple Print AT(,) PeekEvent Until Me Is Nothing || MouseK
Proc RenderLoop() Static wait$ = "Wait!" Print AT(1, 1); wait$ counter%++ Dim td# = Timer // LByte (A|R|G|B) // 0.5ms at 4K MemZero RenderBmpRamAdr, bminfo.bmh.biWidth * bminfo.bmh.biHeight * 4 // fastest for clr the RenderBmpRamAdr memory. Dim mz# = Timer - td# // D2Bitmap takes about 6ms on my machine... that's quite a lot! // The bitmap must pass through the north bridge to the GPU... But the bandwidth through the north bridge is about 100GB/s... peanuts for the system. // Unfortunately, that takes too much time!! Set D2DRenderBMP = D2Bitmap(RenderDib, WICBitmapUsePremultipliedAlpha /* <--- fastest */) D2Put 0, 0, D2DRenderBMP td# = (Timer - td#) * 1000 If Timer - t# => 1 wait$ = "" t# = Timer // ~158 on UHD. ~260 on HD Print AT(1, 1); " Depends on the screen size!" Print "------------------------------------------" Print " MemZero RenderBmpRamAdr ms: " & mz# Print " Loops per second : " & counter Print " Set D2DRenderBMP = D2Bitmap() call ms " & td# counter% = 0 EndIf EndProc
|
|
|
Post by (X) on Feb 27, 2024 1:28:47 GMT 1
I wrote to our Help Doc editor about D2SwapChain... I love a good puzzle and this one may indeed be a stumper. We'll see how long this nut takes to crack!
|
|
|
Post by dragonjim on Feb 27, 2024 12:08:54 GMT 1
For added information and functionality, here are two methods of the SwapChain object in the form of functions:
$Library "C:\Program Files (x86)\GFABASIC32\Include\UpdateRT.lg32" $Library "C:\Program Files (x86)\GFABASIC32\Include\direct2d.lg32" UpdateRuntime ' Patches GfaWin23.Ocx
GUID IID_ID3D11Texture2D = 6f15aaf2-d208-4e89-9ab4-489535d34f9c GUID IID_IDXGISwapChain1 = 790a45f7-0d42-4876-983a-0a55cfe6f4aa Type IDXGISwapChain1Vtbl ' inherits from IDXGISwapChain - Long QueryInterface, AddRef, Release - Long SetPrivateData, SetPrivateDataInterface, GetPrivateData, GetParent - Long GetDevice - Long Present, GetBuffer, SetFullscreenState, GetFullscreenState, GetDesc, _ ResizeBuffers, ResizeTarget, GetContainingOutput, GetFrameStatistics, GetLastPresentCount ' Methods - Long GetDesc1, GetFullscreenDesc, GetHwnd, GetCoreWindow, Present1, IsTemporaryMonoSupported, _ GetRestrictToOutput, SetBackgroundColor, GetBackgroundColor, SetRotation, GetRotation EndType
Global Object Win1RT, swapchain, d2ddev, d2dcontext, d2dbitmap OpenW 1, 0, 0, 320, 360, ~15 Set Win1RT = D2GetRT(Me.hWnd) ' window RT D2SwapChain Me.hWnd, swapchain, d2ddev, d2dcontext, d2dbitmap
Function D2SwapChain_Present(swapchain As Object, iSyncInterval As Int32, iFlags As Int32) /* Purpose: The IDXGISwapChain::Present method is used to display a rendered image to the user. It’s the point where your frame gets presented on the screen. /* Parameters: /* - iSyncInterval: An integer that specifies how to synchronize the presentation of a frame with the vertical blank. Depending on the swap effect model _ (e.g., discard, sequential, or flip), different values are used. For example: _ For the bit-block transfer (bitblt) model (used with DXGI_SWAP_EFFECT_DISCARD or DXGI_SWAP_EFFECT_SEQUENTIAL), _ values range from 0 (immediate presentation) to 4 (synchronize after the nth vertical blank). _ For the flip model (used with DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL), _ values range from 0 (cancel remaining time on the previously presented frame) to 4 (synchronize presentation for at least n vertical blanks). /* - iFlags: An integer value that contains swap-chain presentation options. These options are defined by the DXGI_PRESENT constants. /* Return Value : Possible return values include: _ S_OK: Presentation succeeded. _ DXGI_ERROR_DEVICE_RESET or DXGI_ERROR_DEVICE_REMOVED: Indicates issues related to the graphics device. _ DXGI_STATUS_OCCLUDED: The window is partially or completely obscured. _ D3DDDIERR_DEVICEREMOVED: The video card has been physically removed or had a driver upgrade. Local hr = StdCall({{{V:swapchain}} + OffsetOf(IDXGISwapChain1Vtbl.Present)})({V:swapchain}, iSyncInterval, iFlags) Assert hr <> 0 ' SwapChain_Present failed EndFunction Function D2SwapChain_GetBackBuffer(swapchain As Object, iBackBuffer As Int32, Optional iType As Int32) /* Purpose: The GetBackBuffer method retrieves a back buffer from the device’s swap chain. Back buffers are essential for rendering and displaying frames. /* Parameters: /* - iBackBuffer: An index representing the back buffer object to return. Back buffers are numbered from 0 to the total number of back buffers minus one. _ Note that a value of 0 corresponds to the first back buffer, not the front buffer. The front buffer is not accessible through this method. /* - Type: The type of back buffer requested. In Direct3D 9, stereo view is not supported, so the only valid value for this parameter is D3DBACKBUFFER_TYPE_MONO. /* Return Value : _ If the method succeeds, the return value is D3D_OK. _ If iBackBuffer exceeds the total number of back buffers, the function fails and returns D3DERR_INVALIDCALL. If iType = 0 Then iType = IID_ID3D11Texture2D Local backBuffer As Int32 Local hr = StdCall({{{V:swapchain}} + OffsetOf(IDXGISwapChain1Vtbl.GetBuffer)})({V:swapchain}, iBackBuffer, iType, V:backBuffer) Assert hr <> 0 ' Failed to get Back Buffer handle Return backBuffer EndFunction
|
|