2
votes

I want to do some calculations on a 8bit image sent by a camera, and I just can't figure out the way to access them.

Following is my code to create the texture object / resource view:

D3D11_TEXTURE2D_DESC tDesc;
tDesc.Height = 480;
tDesc.Width = 640;
tDesc.Usage = D3D11_USAGE_DYNAMIC;
tDesc.MipLevels = 1;
tDesc.ArraySize = 1;
tDesc.SampleDesc.Count = 1;
tDesc.SampleDesc.Quality = 0;
tDesc.Format = DXGI_FORMAT_R8_UINT;
tDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
tDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
tDesc.MiscFlags = 0;

V_RETURN(pd3dDevice->CreateTexture2D(&tDesc, NULL, &g_pCurrentImage));

D3D11_SHADER_RESOURCE_VIEW_DESC rvDesc;
g_pCurrentImage->GetDesc(&tDesc);
rvDesc.Format = DXGI_FORMAT_R8_UINT;
rvDesc.Texture2D.MipLevels = tDesc.MipLevels;
rvDesc.Texture2D.MostDetailedMip = tDesc.MipLevels - 1;
rvDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2D;
V_RETURN(pd3dDevice->CreateShaderResourceView(g_pCurrentImage, &rvDesc, &g_pImageRV));

I update the texture with following code:

if( !g_updateDone ) {
    D3D11_MAPPED_SUBRESOURCE resource;
    resource.pData = g_Images.pData;
    resource.RowPitch = 640;
    resource.DepthPitch = 1;
    okay = pd3dImmediateContext->Map(g_pCurrentImage, 0, D3D11_MAP_WRITE_DISCARD, 0, &resource);
    g_updateDone = true;
    }
pd3dImmediateContext->PSSetShaderResources(0, 1, &g_pImageRV);

The HLSL File (takes a quad, displays as quad on screen):

//-----------------------------------------------------------------------------------------
// Textures and Samplers
//-----------------------------------------------------------------------------------------

Texture2D <int> g_txDiffuse : register( t0 );
SamplerState g_samLinear : register( s0 );

//--------------------------------------------------------------------------------------
// shader input/output structure
//--------------------------------------------------------------------------------------

struct VS_INPUT
{
    float4 Position     : POSITION; // vertex position 
    float2 TextureUV    : TEXCOORD0;// vertex texture coords 
};

struct VS_OUTPUT
{
    float4 Position     : SV_POSITION; // vertex position 
    float2 TextureUV    : TEXCOORD0;   // vertex texture coords 
};

//--------------------------------------------------------------------------------------
// This shader computes standard transform and lighting
//--------------------------------------------------------------------------------------
VS_OUTPUT RenderSceneVS( VS_INPUT input )
{
    VS_OUTPUT Output;

    Output.Position = input.Position;

    Output.TextureUV = input.TextureUV; 

    return Output;    
}

//--------------------------------------------------------------------------------------
// This shader outputs the pixel's color by modulating the texture's
// color with diffuse material color
//--------------------------------------------------------------------------------------

float4 RenderScenePS( VS_OUTPUT In ) : SV_TARGET
{ 
    int3 loc;
    loc.x = 0;
    loc.y = 0;
    loc.z = 0;
    int r = g_txDiffuse.Load(loc);
    float fTest = (float) r;

    fTest = fTest / 256;

    return float4( In.TextureUV.x, In.TextureUV.y, In.TextureUV.x + In.TextureUV.y, fTest);
}

When I try to run this, I get an error X4532: cannot map expression to pixel shader instruction set

When I try to debug it, when I try to see the data of the g_pCurrentImage, it just says cannot display surface, and when replacing that with

return float4( In.TextureUV.x, In.TextureUV.y, In.TextureUV.x + In.TextureUV.y, 1);

the DirectX debugger (PIX in this case) just ignores the first lines, they are never reached and thus I cannot debug it. I have run out of options on how to deal with this, all I want to do are some basic math instructions, yet I am completely unable to get the pixel shader to work.

1
What arguments are you using to compile the shader when you get the X4532 error, and what line number is it being reported on? That compiles fine for me in fxc with "fxc /Tps_4_0 /ERenderScenePS <filename>".Jesse Hall

1 Answers

0
votes

The way you're trying to get data into the texture doesn't work. The Map() call fills out the D3D11_MAPPED_SUBRESOURCE structure: it gives you a pointer to write the data into, and tells you what row and slice pitch you must respect. So you call Map(), write your data into the provided pointer, and then call Unmap().

Alternately you can use the UpdateSubresource() method, which takes the pointer and pitch info you provide and copies the data into the texture, like you're trying to do with Map().