Skip to main content
GameDev.net gamedev.net
🔒 Locked

Init FP render target with pixel shader

Started by neneboricua19 Dec 26, 2003 at 3:31 PM 5 replies 2.1k views
Original Post
neneboricua19
neneboricua19
I''m trying to initialize all the values of a floating point render target using a pixel shader. The reason I don''t just call IDirect3DDevice9::Clear is because I want to initialize the value of each element of the render target to some kind of MAX_FLOAT value and not a regular 32bit ARGB color. I thought that the best way to do this was to render a screen-aligned quad and just have a pixel shader write out the floating point value that I want the render target initialized to. I loaded this value as a constant to inside the shader. The problem is that it seems that the pixel shader is never run. The vertex shader runs just fine, but the pixel shader never runs. Normally, I would think that this is because the screen-aligned quad isn''t being transformed properly so no pixels are being rasterized. But I''ve used this same transformation to draw other screen aligned quads and it works just fine. I''ve even tried to load another pixel shader that also computes values on a screen-aligned quad (but does much more work) and it runs fine. It just seems that this very simple pixel shader doesn''t want to run. Here is the shader (I''ve tried in both HSLS and regular assembly):
// HSLS version

// Clearing to gray as default.  Real value will be loaded by app.

float4 g_vClearColor = float4( 0.5f, 0.5f, 0.5f, 0.5f );

float4 main() : COLOR0
{
	return g_vClearColor;
}

// Assembly version

// c0 is loaded with a value from the app by calling SetPixelShaderConstantF

ps_2_0
mov oC0, c0
Could it be that the shader is just too simple for D3D to run it somehow? I''ve tried replacing this shader with a much more complicated shader and D3D will execute the complex shader (albiet, with incorrect results because I had not loaded all the proper data but at least it runs), but not this simple one. In the main app, I call SetVertexDeclaration, SetVertexShader, and SetPixelShader with the appropriate values. I also check the HRESULT variables and the debug spew and everything seems to be fine. I''ve also tried running on the REF device to make sure everything is ok and i get the same results. I use the REF device so that I can step into the pixel shaders. I''ve done this with the more complicated shader but I''m not able to step into this simple one. Does anyone have an idea as to why this simple shader will not run? neneboricua
poly-gone
poly-gone
Does your graphics card fully support fp render targets. The complexity of the shader doesn''t have anything to do with it.
neneboricua19
neneboricua19
Yes, my card supports FP targets. I''m running on an ATI Radeon 9600 Pro. I''ve successfully used FP targets on other occasions (for example, when implementing shadow mapping on another project). Just to make sure, the app also calls CheckDepthStencilMatch with D3DFMT_A32B32G32R32F as the render target format. The result checks out. Also, the caps bits say that FP targets are supported.

You''re right in that the complexity of the shader shouldn''t have anything to do with whether a shader is run or not but that''s what it seems like is hapenning. The complex shader runs, yet the simple shader does not.

I''ve been trying to get around this for the past 2 days so if anyone has any ideas, please let me know.

neneboricua
Muhammad Haggag
Muhammad Haggag
Not sure if this helps, but anyway:

- You say it doesn''t produce the correct results on REF, too. In 99% of the cases, this indicates an app bug. Double (triple, quadraple-) check your code. When you replace the simple shader by the complex one, do you just replace the shader (in an FX file, for example) or do you do some code changes?
Maybe you''ve changed something, or went through a different code path?

- Try adding "useless" complexity to your shader. Like multiplying by a constant (1,1,1,1) and adding to a constant that is (0,0,0,0). Maybe throw in a couple of useless texture reads
Make sure you enter the shader in asm (because most probably the HLSL shader will optimize things for you, and remove the useless ops). Keep doing that and see whether it works or not.

Muhammad Haggag

don
don
Going about this a different way, could you fill the render target by using StretchRect from a 1x1 pixel RT lockable surface that you''ve set the pixel value to beforehand?

You''d have to make sure that the card supports the D3DTEXF_POINT filtering mode for StretchRect, otherwise it''s a crap shoot as to what sort of filtering it would do if you specify D3DTEXF_NONE. I''ve seen some cards do some flavor of linear filtering and others do point sampling in this case.
neneboricua19
neneboricua19
I tried to add useless complexity, disabled shader optimization, rewrote the shader loading code, etc... but none of that stuff worked!

In the end, I took don''s advice, except that since my card doesn''t support point filtering using StretchRect, I just created a seperate surface and initialized it at load time with the floating point value I want to clear my main surface to. Then when I want to clear the main surface, I call StretchRect but with no scaling and use D3DTEXF_NONE as the flitering method. This works just fine.

I still have no idea why I couldn''t just load a simple shader instead of that complicated one. Oh well. Don''t have the time to dig into that too much. Need to move on.

Thanks for the help,
neneboricua
Muhammad Haggag
Muhammad Haggag
But this really shouldn''t be ignored. It has to be identified as an app bug, driver bug or runtime bug.

I understand that you don''t have the time now, but I hope you consider doing a simple repro later.

Muhammad Haggag

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.