RTMCopyRam and Dx9?

I’m trying to bring a render-to-texture texture into the main ram to peak at some pixel values. Using RTMCopyRam during texture binding seems to do the trick for opengl, but under dx9, I’m getting a SetRenderTarget error.

Does anybody have any experience with this issue or know of any workarounds?

:display:gsg:dxgsg9(error): SetRenderTarget  at (c:\panda_source5_15\panda3d\pan
da\src\dxgsg9\wdxGraphicsBuffer9.cxx:477), hr=D3DERR_INVALIDCALL: Invalid call
tex = Texture()
winprops = WindowProperties()
winprops.setSize( 128, 128)
fbprops = FrameBufferProperties()
fbprops.setColorBits(1)
fbprops.setAlphaBits(1)
fbprops.setStencilBits(0)
fbprops.setMultisamples(0)
fbprops.setDepthBits( 0 )
objBuffer = base.graphicsEngine.makeOutput(base.pipe, 'hello', -10, fbprops, winprops, GraphicsPipe.BFRefuseWindow, base.win.getGsg(), base.win)
objBuffer.addRenderTexture(tex, GraphicsOutput.RTMCopyRam, GraphicsOutput.RTPColor)

Ok. I figured out a workaround. Use

base.graphicsEngine.extractTextureData( tex, base.win.getGsg())

This acts like a one shot transfer of the texture to the system Ram.

Have you tried it with the latest buildbot version? I’m just curious to know whether this dx9 problem has been fixed on the trunk.

David

Summary:

RTMCopyRam:

Opengl seems to be working fine with both offscreen and parasite buffers. ~transfer rate 500MB/s
Dx9 only works with parasite buffers and is 1/3-1/2 speed of opengl.

Latest build doesn’t change anything

Using: base.graphicsEngine.extractTextureData

Opengl is about 1/2-1/3 speed of RTMCopyRam
Dx9 ~same speed as Opengl

Latest build is a bit slower all around and opengl DOESN"T function when ‘threading-model Cull/Draw’ is enabled.

But Dx9 offscreen buffers are now working properly with ‘threading-model Cull/Draw’


Measurements of the time it takes to transfer a 512x512 texture using RTMCopyRam from the GPU to the system RAM (using a GTX260, Winxp 32bit):

->with an old non-threading (~1.7.8?)build that I have

**Off-screen buffer

opengl: 2.1ms
dx9: <!!non-functional>

**Parasite buffer
opengl: 3.3ms
dx9: 5.8ms

->with the latest buildbot 10/30 build

**Off-screen buffer
opengl (without threading-model cull/draw): 2.3ms
opengl (w/ threading-model cull/draw): 2.0ms

dx9 (without threading-model cull/draw): <!!non-functional>
dx9 (threading-model cull/draw): <!!non-functional>

**Parasite buffer:

opengl (without threading-model cull/draw): 4.0ms
opengl (w/ threading-model cull/draw): 3.0ms

dx9 (without threading-model cull/draw)6.1ms:
dx9 (threading-model cull/draw): 6 ms

from pandac.PandaModules import *
from pandac.PandaModules import loadPrcFileData
#loadPrcFileData('', 'threading-model Cull/Draw')
loadPrcFileData('', 'load-display pandadx9')
import __Header
import direct.directbase.DirectStart

base.cam.node().setActive(0)
base.cam.setPos(0, -10, 0 )

npModel = loader.loadModel('smiley')
npModel.reparentTo( render )

winprops = WindowProperties()
winprops.setSize( 512, 512 )
fbprops = FrameBufferProperties()
fbprops.setColorBits(1)
fbprops.setAlphaBits(1)

#buffer1 = base.graphicsEngine.makeOutput(base.pipe, '1033', -2, fbprops, winprops, GraphicsPipe.BFRefuseWindow, base.win.getGsg(), base.win)
buffer1 = base.graphicsEngine.makeParasite( base.win, '1033', -2, 512, 512 )

tex = Texture()
buffer1.addRenderTexture( tex, GraphicsOutput.RTMCopyRam, GraphicsOutput.RTPColor )
#buffer1.addRenderTexture( tex, GraphicsOutput.RTMBindOrCopy, GraphicsOutput.RTPColor )
#buffer1.addRenderTexture( tex, GraphicsOutput.RTMCopyTexture, GraphicsOutput.RTPColor )
buffer1.setClearColorActive( True )
buffer1.setClearDepthActive( True )
buffer1.setClearStencilActive( True )

cam = base.makeCamera( buffer1, sort = -10, scene = render )
cam.setPos( 0, -50, 0 )
cam.reparentTo( base.cam )

# card = CardMaker('testname')
# card.setFrame(0, 1, 0, 1)
# card.setHasUvs( True )
# npCard = NodePath(card.generate())
# npCard.setTexture(tex)
# npCard.reparentTo( render2d )

run()

Now using RTMBindOrCopy and base.graphicsEngine.extractTextureData to transfer the data every frame

->with an old non-threading (~1.7.8?)build that I have

**Off-screen buffer

opengl: 6.4ms
dx9: 5.4ms

**Parasite buffer
opengl: 6.4ms
dx9: 5.4ms

->with the latest buildbot 10/30 build

**Off-screen buffer
opengl (without threading-model cull/draw): 7.6ms
opengl (w/ threading-model cull/draw): <!!Non functional>

dx9 (without threading-model cull/draw): 6ms
dx9 (threading-model cull/draw): 5ms

**Parasite buffer:

opengl (without threading-model cull/draw): 7.2ms
opengl (w/ threading-model cull/draw): <!!Non functional>

dx9 (without threading-model cull/draw): 5.1ms
dx9 (threading-model cull/draw): 6ms

buffer1 = base.graphicsEngine.makeParasite( base.win, '1033', -2, 512, 512 )
def ttask(task):
	if globalClock.getFrameCount() > 10:
		base.graphicsEngine.extractTextureData( tex, base.win.getGsg())
	return task.cont

taskMgr.add( ttask, 'hello' )