Using DirectX 9,I'm trying to run a HLSL pixel shader on video frame data while copying it from one texture buffer to another texture buffer without displaying it. StretchRect at the end is what copies the data from pOffsceenSurface to pTextureSurface, which should pass through the pixel shader. The video data does get passed over and I can read it back, but the shader isn't being applied.
What do I need to do to process the texture through the shader? And does register(S0) get automatically filled, or how do I set the source? The code I have allows configuring register(C0), register(C1), etc. through m_pPixelConstantTable, but not the S registers. Some shaders take S0 and S1 so it needs to be configured somehow.
Here's the code
HRESULT D3D9RenderImpl::SetPixelShader(LPCSTR pPixelShaderName, LPCSTR entryPoint, LPCSTR shaderModel, LPSTR* ppError)
{
CComPtr<ID3DXBuffer> code;
CComPtr<ID3DXBuffer> errMsg;
HR(D3DXCompileShaderFromFile(pPixelShaderName, NULL, NULL, entryPoint, shaderModel, 0, &code, &errMsg, &m_pPixelConstantTable));
return m_pDevice->CreatePixelShader((DWORD*)code->GetBufferPointer(), &m_pPixelShader);
}
HRESULT D3D9RenderImpl::CreateScene(void)
{
HR(m_pDevice->Clear(D3DADAPTER_DEFAULT, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0));
HR(m_pDevice->BeginScene());
HR(m_pDevice->SetFVF(D3DFVF_CUSTOMVERTEX));
// when I debug, m_pPixelShader does get set properly)
HR(m_pDevice->SetPixelShader(m_pPixelShader));
HR(m_pDevice->SetTexture(0, m_pTexture));
HR(m_pDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2));
return m_pDevice->EndScene();
}
HRESULT D3D9RenderImpl::Present(void)
{
HR(m_pDevice->ColorFill(m_pTextureSurface, NULL, D3DCOLOR_ARGB(0xFF, 0, 0, 0)));
return(m_pDevice->StretchRect(m_pOffsceenSurface, NULL, m_pTextureSurface, NULL, D3DTEXF_LINEAR));
// This line doesn't seem necessary
// return m_pDevice->Present(NULL, NULL, NULL, NULL);
}
What's missing?
EDIT: Here's what I'm rendering to
HRESULT D3D9RenderImpl::CreateRenderTarget()
{
// HR(m_pDevice->CreateTexture(width, height, 1, D3DUSAGE_RENDERTARGET, m_displayMode.Format, D3DPOOL_DEFAULT, &m_pTexture, NULL));
HR(m_pDevice->CreateTexture(m_videoWidth, m_videoHeight, 1, D3DUSAGE_RENDERTARGET, m_format, D3DPOOL_DEFAULT, &m_pTexture, NULL));
HR(m_pTexture->GetSurfaceLevel(0, &m_pTextureSurface));
HR(m_pDevice->CreateVertexBuffer(sizeof(VERTEX) * 4, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &m_pVertexBuffer, NULL));
VERTEX vertexArray[] =
{
{ D3DXVECTOR3(0, 0, 0), D3DCOLOR_ARGB(255, 255, 255, 255), D3DXVECTOR2(0, 0) }, // top left
{ D3DXVECTOR3(m_videoWidth, 0, 0), D3DCOLOR_ARGB(255, 255, 255, 255), D3DXVECTOR2(1, 0) }, // top right
{ D3DXVECTOR3(m_videoWidth, m_videoHeight, 0), D3DCOLOR_ARGB(255, 255, 255, 255), D3DXVECTOR2(1, 1) }, // bottom right
{ D3DXVECTOR3(0, m_videoHeight, 0), D3DCOLOR_ARGB(255, 255, 255, 255), D3DXVECTOR2(0, 1) }, // bottom left
};
VERTEX *vertices;
HR(m_pVertexBuffer->Lock(0, 0, (void**)&vertices, D3DLOCK_DISCARD));
memcpy(vertices, vertexArray, sizeof(vertexArray));
HR(m_pVertexBuffer->Unlock());
return m_pDevice->SetRenderTarget(0, m_pTextureSurface);
}
StretchRect
would go through a pixel shader? What you need to do here is to render a screen-filling quad to a render target texture. \$\endgroup\$