home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 275 / DPCS0111DVD.ISO / Toolkit / Audio-Visual / VirtualDub / Source / VirtualDub-1.9.10-src.7z / src / Asuka / source / fxc.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2009-09-14  |  44.3 KB  |  1,134 lines

  1. //    Asuka - VirtualDub Build/Post-Mortem Utility
  2. //    Copyright (C) 2005 Avery Lee
  3. //
  4. //    This program is free software; you can redistribute it and/or modify
  5. //    it under the terms of the GNU General Public License as published by
  6. //    the Free Software Foundation; either version 2 of the License, or
  7. //    (at your option) any later version.
  8. //
  9. //    This program is distributed in the hope that it will be useful,
  10. //    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. //    GNU General Public License for more details.
  13. //
  14. //    You should have received a copy of the GNU General Public License
  15. //    along with this program; if not, write to the Free Software
  16. //    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18. #include "stdafx.h"
  19. #include <vector>
  20. #include <list>
  21. #include <string>
  22. #include <d3d9.h>
  23. #include <d3dx9.h>
  24. #include <objbase.h>
  25. #include <vd2/system/refcount.h>
  26. #include <vd2/system/filesys.h>
  27. #include <vd2/system/math.h>
  28. #include <vd2/system/vdstl.h>
  29.  
  30. #pragma comment(lib, "d3dx9")
  31.  
  32. #define NOT_IMPLEMENTED() puts(__FUNCTION__); return E_NOTIMPL
  33. #define NOT_IMPLEMENTED_VOID()
  34.  
  35. namespace
  36. {
  37.     static const char *const kTextureNames[]={
  38.         "vd_srctexture",
  39.         "vd_src2atexture",
  40.         "vd_src2btexture",
  41.         "vd_srcpaltexture",
  42.         "vd_temptexture",
  43.         "vd_temp2texture",
  44.         "vd_cubictexture",
  45.         "vd_hevenoddtexture",
  46.         "vd_dithertexture",
  47.         "vd_interphtexture",
  48.         "vd_interpvtexture",
  49.     };
  50.  
  51.     static const char *const kParameterNames[]={
  52.         "vd_vpsize",
  53.         "vd_cvpsize",
  54.         "vd_texsize",
  55.         "vd_tex2size",
  56.         "vd_srcsize",
  57.         "vd_tempsize",
  58.         "vd_temp2size",
  59.         "vd_vpcorrect",
  60.         "vd_vpcorrect2",
  61.         "vd_tvpcorrect",
  62.         "vd_tvpcorrect2",
  63.         "vd_t2vpcorrect",
  64.         "vd_t2vpcorrect2",
  65.         "vd_time",
  66.         "vd_interphtexsize",
  67.         "vd_interpvtexsize",
  68.         "vd_fieldinfo",
  69.     };
  70. }
  71.  
  72. namespace
  73. {
  74.     class DummyD3DVertexShader : public IDirect3DVertexShader9 {
  75.     public:
  76.         DummyD3DVertexShader(IDirect3DDevice9 *pDevice, const DWORD *pByteCode) : mRefCount(0), mpDevice(pDevice), mByteCode(pByteCode, pByteCode + (D3DXGetShaderSize(pByteCode) >> 2)) {}
  77.  
  78.         /*** IUnknown methods ***/
  79.         HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObj) {
  80.             if (riid == IID_IDirect3DVertexShader9)
  81.                 *ppvObj = static_cast<IDirect3DVertexShader9 *>(this);
  82.             else if (riid == IID_IUnknown)
  83.                 *ppvObj = static_cast<IUnknown *>(this);
  84.             else {
  85.                 *ppvObj = NULL;
  86.                 return E_NOINTERFACE;
  87.             }
  88.  
  89.             AddRef();
  90.             return S_OK;
  91.         }
  92.  
  93.         ULONG    STDMETHODCALLTYPE AddRef() {
  94.             return (ULONG)InterlockedIncrement(&mRefCount);
  95.         }
  96.         ULONG    STDMETHODCALLTYPE Release() {
  97.             ULONG rv = (ULONG)InterlockedDecrement(&mRefCount);
  98.             if (!rv)
  99.                 delete this;
  100.             return rv;
  101.         }
  102.  
  103.         /*** IDirect3DVertexShader9 methods ***/
  104.         HRESULT STDMETHODCALLTYPE GetDevice(IDirect3DDevice9** ppDevice) {
  105.             *ppDevice = mpDevice;
  106.             (*ppDevice)->AddRef();
  107.             return S_OK;
  108.         }
  109.  
  110.         HRESULT STDMETHODCALLTYPE GetFunction(void* p, UINT* pSizeOfData) {
  111.             UINT bytes = (UINT)(mByteCode.size() << 2);
  112.  
  113.             if (!p)
  114.                 *pSizeOfData = bytes;
  115.             else if (*pSizeOfData < bytes)
  116.                 return D3DERR_INVALIDCALL;
  117.             else {
  118.                 *pSizeOfData = bytes;
  119.                 memcpy(p, &mByteCode[0], bytes);
  120.             }
  121.  
  122.             return S_OK;
  123.         }
  124.  
  125.     protected:
  126.         volatile LONG mRefCount;
  127.         vdrefptr<IDirect3DDevice9> mpDevice;
  128.         std::vector<DWORD> mByteCode;
  129.     };
  130.  
  131.     class DummyD3DPixelShader : public IDirect3DPixelShader9 {
  132.     public:
  133.         DummyD3DPixelShader(IDirect3DDevice9 *pDevice, const DWORD *pByteCode) : mRefCount(0), mpDevice(pDevice), mByteCode(pByteCode, pByteCode + (D3DXGetShaderSize(pByteCode) >> 2)) {}
  134.  
  135.         /*** IUnknown methods ***/
  136.         HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObj) {
  137.             if (riid == IID_IDirect3DPixelShader9)
  138.                 *ppvObj = static_cast<IDirect3DPixelShader9 *>(this);
  139.             else if (riid == IID_IUnknown)
  140.                 *ppvObj = static_cast<IUnknown *>(this);
  141.             else {
  142.                 *ppvObj = NULL;
  143.                 return E_NOINTERFACE;
  144.             }
  145.  
  146.             AddRef();
  147.             return S_OK;
  148.         }
  149.  
  150.         ULONG    STDMETHODCALLTYPE AddRef() {
  151.             return (ULONG)InterlockedIncrement(&mRefCount);
  152.         }
  153.         ULONG    STDMETHODCALLTYPE Release() {
  154.             ULONG rv = (ULONG)InterlockedDecrement(&mRefCount);
  155.             if (!rv)
  156.                 delete this;
  157.             return rv;
  158.         }
  159.  
  160.         /*** IDirect3DPixelShader9 methods ***/
  161.         HRESULT STDMETHODCALLTYPE GetDevice(IDirect3DDevice9** ppDevice) {
  162.             *ppDevice = mpDevice;
  163.             (*ppDevice)->AddRef();
  164.             return S_OK;
  165.         }
  166.  
  167.         HRESULT STDMETHODCALLTYPE GetFunction(void* p, UINT* pSizeOfData) {
  168.             UINT bytes = (UINT)(mByteCode.size() << 2);
  169.  
  170.             if (!p)
  171.                 *pSizeOfData = bytes;
  172.             else if (*pSizeOfData < bytes)
  173.                 return D3DERR_INVALIDCALL;
  174.             else {
  175.                 *pSizeOfData = bytes;
  176.                 memcpy(p, &mByteCode[0], bytes);
  177.             }
  178.  
  179.             return S_OK;
  180.         }
  181.  
  182.     protected:
  183.         volatile LONG mRefCount;
  184.         vdrefptr<IDirect3DDevice9> mpDevice;
  185.         std::vector<DWORD> mByteCode;
  186.     };
  187.  
  188.     class DummyD3DBaseTexture : public IDirect3DBaseTexture9
  189.     {
  190.     public:
  191.         DummyD3DBaseTexture(IDirect3DDevice9 *pDevice, uint32 id) : mRefCount(0), mpDevice(pDevice), mId(id) {}
  192.  
  193.         /*** IUnknown methods ***/
  194.         HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObj) {
  195.             if (riid == IID_IDirect3DBaseTexture9)
  196.                 *ppvObj = static_cast<IDirect3DBaseTexture9 *>(this);
  197.             else if (riid == IID_IDirect3DResource9)
  198.                 *ppvObj = static_cast<IDirect3DResource9 *>(this);
  199.             else if (riid == IID_IUnknown)
  200.                 *ppvObj = static_cast<IUnknown *>(this);
  201.             else {
  202.                 *ppvObj = NULL;
  203.                 return E_NOINTERFACE;
  204.             }
  205.  
  206.             AddRef();
  207.             return S_OK;
  208.         }
  209.  
  210.         ULONG    STDMETHODCALLTYPE AddRef() {
  211.             return (ULONG)InterlockedIncrement(&mRefCount);
  212.         }
  213.         ULONG    STDMETHODCALLTYPE Release() {
  214.             ULONG rv = (ULONG)InterlockedDecrement(&mRefCount);
  215.             if (!rv)
  216.                 delete this;
  217.             return rv;
  218.         }
  219.  
  220.         /*** IDirect3DResource9 methods ***/
  221.         HRESULT STDMETHODCALLTYPE GetDevice(IDirect3DDevice9** ppDevice) {
  222.             *ppDevice = mpDevice;
  223.             (*ppDevice)->AddRef();
  224.             return S_OK;
  225.         }
  226.  
  227.         HRESULT STDMETHODCALLTYPE SetPrivateData(REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) { NOT_IMPLEMENTED(); }
  228.         HRESULT STDMETHODCALLTYPE GetPrivateData(REFGUID refguid,void* pData,DWORD* pSizeOfData) { NOT_IMPLEMENTED(); }
  229.         HRESULT STDMETHODCALLTYPE FreePrivateData(REFGUID refguid) { NOT_IMPLEMENTED(); }
  230.         DWORD    STDMETHODCALLTYPE SetPriority(DWORD PriorityNew) { NOT_IMPLEMENTED_VOID(); return 0; }
  231.         DWORD    STDMETHODCALLTYPE GetPriority() { return 0; }
  232.         void    STDMETHODCALLTYPE PreLoad() {}
  233.         D3DRESOURCETYPE STDMETHODCALLTYPE GetType() {
  234.             return D3DRTYPE_TEXTURE;
  235.         }
  236.         DWORD    STDMETHODCALLTYPE SetLOD(DWORD LODNew) { NOT_IMPLEMENTED_VOID(); return 0; }
  237.         DWORD    STDMETHODCALLTYPE GetLOD() { return 0; }
  238.         DWORD    STDMETHODCALLTYPE GetLevelCount() { return 1; }
  239.         HRESULT STDMETHODCALLTYPE SetAutoGenFilterType(D3DTEXTUREFILTERTYPE FilterType) { NOT_IMPLEMENTED(); }
  240.         D3DTEXTUREFILTERTYPE STDMETHODCALLTYPE GetAutoGenFilterType() {
  241.             return D3DTEXF_LINEAR;
  242.         }
  243.         void    STDMETHODCALLTYPE GenerateMipSubLevels() {}
  244.  
  245.     public:
  246.         uint32 GetId() const { return mId; }
  247.  
  248.     protected:
  249.         volatile LONG mRefCount;
  250.         vdrefptr<IDirect3DDevice9> mpDevice;
  251.         uint32 mId;
  252.     };
  253.  
  254.     class DummyD3DDevice : public IDirect3DDevice9 {
  255.     public:
  256.         DummyD3DDevice() : mRefCount(0) {}
  257.  
  258.         /*** IUnknown methods ***/
  259.         HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObj) {
  260.             if (riid == IID_IDirect3DDevice9)
  261.                 *ppvObj = static_cast<IDirect3DDevice9 *>(this);
  262.             else if (riid == IID_IUnknown)
  263.                 *ppvObj = static_cast<IUnknown *>(this);
  264.             else {
  265.                 *ppvObj = NULL;
  266.                 return E_NOINTERFACE;
  267.             }
  268.  
  269.             AddRef();
  270.             return S_OK;
  271.         }
  272.  
  273.         ULONG    STDMETHODCALLTYPE AddRef() {
  274.             return (ULONG)InterlockedIncrement(&mRefCount);
  275.         }
  276.         ULONG    STDMETHODCALLTYPE Release() {
  277.             ULONG rv = (ULONG)InterlockedDecrement(&mRefCount);
  278.             if (!rv)
  279.                 delete this;
  280.             return rv;
  281.         }
  282.  
  283.         /*** IDirect3DDevice9 methods ***/
  284.         HRESULT STDMETHODCALLTYPE TestCooperativeLevel() { NOT_IMPLEMENTED(); }
  285.         UINT    STDMETHODCALLTYPE GetAvailableTextureMem() { return 16777216; }
  286.         HRESULT STDMETHODCALLTYPE EvictManagedResources() { NOT_IMPLEMENTED(); }
  287.         HRESULT STDMETHODCALLTYPE GetDirect3D(IDirect3D9** ppD3D9) { NOT_IMPLEMENTED(); }
  288.         HRESULT STDMETHODCALLTYPE GetDeviceCaps(D3DCAPS9* pCaps) { NOT_IMPLEMENTED(); }
  289.         HRESULT STDMETHODCALLTYPE GetDisplayMode(UINT iSwapChain,D3DDISPLAYMODE* pMode) { NOT_IMPLEMENTED(); }
  290.         HRESULT STDMETHODCALLTYPE GetCreationParameters(D3DDEVICE_CREATION_PARAMETERS *pParameters) { NOT_IMPLEMENTED(); }
  291.         HRESULT STDMETHODCALLTYPE SetCursorProperties(UINT XHotSpot,UINT YHotSpot,IDirect3DSurface9* pCursorBitmap) { NOT_IMPLEMENTED(); }
  292.         void    STDMETHODCALLTYPE SetCursorPosition(int X,int Y,DWORD Flags) {}
  293.         BOOL    STDMETHODCALLTYPE ShowCursor(BOOL bShow) { return TRUE; }
  294.         HRESULT STDMETHODCALLTYPE CreateAdditionalSwapChain(D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DSwapChain9** pSwapChain) { NOT_IMPLEMENTED(); }
  295.         HRESULT STDMETHODCALLTYPE GetSwapChain(UINT iSwapChain,IDirect3DSwapChain9** pSwapChain) { NOT_IMPLEMENTED(); }
  296.         UINT    STDMETHODCALLTYPE GetNumberOfSwapChains() { return 1; }
  297.         HRESULT STDMETHODCALLTYPE Reset(D3DPRESENT_PARAMETERS* pPresentationParameters) { NOT_IMPLEMENTED(); }
  298.         HRESULT STDMETHODCALLTYPE Present(CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion) { NOT_IMPLEMENTED(); }
  299.         HRESULT STDMETHODCALLTYPE GetBackBuffer(UINT iSwapChain,UINT iBackBuffer,D3DBACKBUFFER_TYPE Type,IDirect3DSurface9** ppBackBuffer) { NOT_IMPLEMENTED(); }
  300.         HRESULT STDMETHODCALLTYPE GetRasterStatus(UINT iSwapChain,D3DRASTER_STATUS* pRasterStatus) { NOT_IMPLEMENTED(); }
  301.         HRESULT STDMETHODCALLTYPE SetDialogBoxMode(BOOL bEnableDialogs) { NOT_IMPLEMENTED(); }
  302.         void    STDMETHODCALLTYPE SetGammaRamp(UINT iSwapChain,DWORD Flags,CONST D3DGAMMARAMP* pRamp) { }
  303.         void    STDMETHODCALLTYPE GetGammaRamp(UINT iSwapChain,D3DGAMMARAMP* pRamp) { NOT_IMPLEMENTED_VOID(); }
  304.         HRESULT STDMETHODCALLTYPE CreateTexture(UINT Width,UINT Height,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DTexture9** ppTexture,HANDLE* pSharedHandle) { NOT_IMPLEMENTED(); }
  305.         HRESULT STDMETHODCALLTYPE CreateVolumeTexture(UINT Width,UINT Height,UINT Depth,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DVolumeTexture9** ppVolumeTexture,HANDLE* pSharedHandle) { NOT_IMPLEMENTED(); }
  306.         HRESULT STDMETHODCALLTYPE CreateCubeTexture(UINT EdgeLength,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DCubeTexture9** ppCubeTexture,HANDLE* pSharedHandle) { NOT_IMPLEMENTED(); }
  307.         HRESULT STDMETHODCALLTYPE CreateVertexBuffer(UINT Length,DWORD Usage,DWORD FVF,D3DPOOL Pool,IDirect3DVertexBuffer9** ppVertexBuffer,HANDLE* pSharedHandle) { NOT_IMPLEMENTED(); }
  308.         HRESULT STDMETHODCALLTYPE CreateIndexBuffer(UINT Length,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DIndexBuffer9** ppIndexBuffer,HANDLE* pSharedHandle) { NOT_IMPLEMENTED(); }
  309.         HRESULT STDMETHODCALLTYPE CreateRenderTarget(UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,DWORD MultisampleQuality,BOOL Lockable,IDirect3DSurface9** ppSurface,HANDLE* pSharedHandle) { NOT_IMPLEMENTED(); }
  310.         HRESULT STDMETHODCALLTYPE CreateDepthStencilSurface(UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,DWORD MultisampleQuality,BOOL Discard,IDirect3DSurface9** ppSurface,HANDLE* pSharedHandle) { NOT_IMPLEMENTED(); }
  311.         HRESULT STDMETHODCALLTYPE UpdateSurface(IDirect3DSurface9* pSourceSurface,CONST RECT* pSourceRect,IDirect3DSurface9* pDestinationSurface,CONST POINT* pDestPoint) { NOT_IMPLEMENTED(); }
  312.         HRESULT STDMETHODCALLTYPE UpdateTexture(IDirect3DBaseTexture9* pSourceTexture,IDirect3DBaseTexture9* pDestinationTexture) { NOT_IMPLEMENTED(); }
  313.         HRESULT STDMETHODCALLTYPE GetRenderTargetData(IDirect3DSurface9* pRenderTarget,IDirect3DSurface9* pDestSurface) { NOT_IMPLEMENTED(); }
  314.         HRESULT STDMETHODCALLTYPE GetFrontBufferData(UINT iSwapChain,IDirect3DSurface9* pDestSurface) { NOT_IMPLEMENTED(); }
  315.         HRESULT STDMETHODCALLTYPE StretchRect(IDirect3DSurface9* pSourceSurface,CONST RECT* pSourceRect,IDirect3DSurface9* pDestSurface,CONST RECT* pDestRect,D3DTEXTUREFILTERTYPE Filter) { NOT_IMPLEMENTED(); }
  316.         HRESULT STDMETHODCALLTYPE ColorFill(IDirect3DSurface9* pSurface,CONST RECT* pRect,D3DCOLOR color) { NOT_IMPLEMENTED(); }
  317.         HRESULT STDMETHODCALLTYPE CreateOffscreenPlainSurface(UINT Width,UINT Height,D3DFORMAT Format,D3DPOOL Pool,IDirect3DSurface9** ppSurface,HANDLE* pSharedHandle) { NOT_IMPLEMENTED(); }
  318.         HRESULT STDMETHODCALLTYPE SetRenderTarget(DWORD RenderTargetIndex,IDirect3DSurface9* pRenderTarget) { NOT_IMPLEMENTED(); }
  319.         HRESULT STDMETHODCALLTYPE GetRenderTarget(DWORD RenderTargetIndex,IDirect3DSurface9** ppRenderTarget) { NOT_IMPLEMENTED(); }
  320.         HRESULT STDMETHODCALLTYPE SetDepthStencilSurface(IDirect3DSurface9* pNewZStencil) { NOT_IMPLEMENTED(); }
  321.         HRESULT STDMETHODCALLTYPE GetDepthStencilSurface(IDirect3DSurface9** ppZStencilSurface) { NOT_IMPLEMENTED(); }
  322.         HRESULT STDMETHODCALLTYPE BeginScene() { NOT_IMPLEMENTED(); }
  323.         HRESULT STDMETHODCALLTYPE EndScene() { NOT_IMPLEMENTED(); }
  324.         HRESULT STDMETHODCALLTYPE Clear(DWORD Count,CONST D3DRECT* pRects,DWORD Flags,D3DCOLOR Color,float Z,DWORD Stencil) { NOT_IMPLEMENTED(); }
  325.         HRESULT STDMETHODCALLTYPE SetTransform(D3DTRANSFORMSTATETYPE State,CONST D3DMATRIX* pMatrix) { NOT_IMPLEMENTED(); }
  326.         HRESULT STDMETHODCALLTYPE GetTransform(D3DTRANSFORMSTATETYPE State,D3DMATRIX* pMatrix) { NOT_IMPLEMENTED(); }
  327.         HRESULT STDMETHODCALLTYPE MultiplyTransform(D3DTRANSFORMSTATETYPE,CONST D3DMATRIX*) { NOT_IMPLEMENTED(); }
  328.         HRESULT STDMETHODCALLTYPE SetViewport(CONST D3DVIEWPORT9* pViewport) { NOT_IMPLEMENTED(); }
  329.         HRESULT STDMETHODCALLTYPE GetViewport(D3DVIEWPORT9* pViewport) { NOT_IMPLEMENTED(); }
  330.         HRESULT STDMETHODCALLTYPE SetMaterial(CONST D3DMATERIAL9* pMaterial) { NOT_IMPLEMENTED(); }
  331.         HRESULT STDMETHODCALLTYPE GetMaterial(D3DMATERIAL9* pMaterial) { NOT_IMPLEMENTED(); }
  332.         HRESULT STDMETHODCALLTYPE SetLight(DWORD Index,CONST D3DLIGHT9*) { NOT_IMPLEMENTED(); }
  333.         HRESULT STDMETHODCALLTYPE GetLight(DWORD Index,D3DLIGHT9*) { NOT_IMPLEMENTED(); }
  334.         HRESULT STDMETHODCALLTYPE LightEnable(DWORD Index,BOOL Enable) { NOT_IMPLEMENTED(); }
  335.         HRESULT STDMETHODCALLTYPE GetLightEnable(DWORD Index,BOOL* pEnable) { NOT_IMPLEMENTED(); }
  336.         HRESULT STDMETHODCALLTYPE SetClipPlane(DWORD Index,CONST float* pPlane) { NOT_IMPLEMENTED(); }
  337.         HRESULT STDMETHODCALLTYPE GetClipPlane(DWORD Index,float* pPlane) { NOT_IMPLEMENTED(); }
  338.         HRESULT STDMETHODCALLTYPE GetRenderState(D3DRENDERSTATETYPE State,DWORD* pValue) { NOT_IMPLEMENTED(); }
  339.         HRESULT STDMETHODCALLTYPE CreateStateBlock(D3DSTATEBLOCKTYPE Type,IDirect3DStateBlock9** ppSB) { NOT_IMPLEMENTED(); }
  340.         HRESULT STDMETHODCALLTYPE BeginStateBlock() { NOT_IMPLEMENTED(); }
  341.         HRESULT STDMETHODCALLTYPE EndStateBlock(IDirect3DStateBlock9** ppSB) { NOT_IMPLEMENTED(); }
  342.         HRESULT STDMETHODCALLTYPE SetClipStatus(CONST D3DCLIPSTATUS9* pClipStatus) { NOT_IMPLEMENTED(); }
  343.         HRESULT STDMETHODCALLTYPE GetClipStatus(D3DCLIPSTATUS9* pClipStatus) { NOT_IMPLEMENTED(); }
  344.         HRESULT STDMETHODCALLTYPE GetTexture(DWORD Stage,IDirect3DBaseTexture9** ppTexture) { NOT_IMPLEMENTED(); }
  345.         HRESULT STDMETHODCALLTYPE GetTextureStageState(DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD* pValue) { NOT_IMPLEMENTED(); }
  346.         HRESULT STDMETHODCALLTYPE GetSamplerState(DWORD Sampler,D3DSAMPLERSTATETYPE Type,DWORD* pValue) { NOT_IMPLEMENTED(); }
  347.         HRESULT STDMETHODCALLTYPE ValidateDevice(DWORD* pNumPasses) { NOT_IMPLEMENTED(); }
  348.         HRESULT STDMETHODCALLTYPE SetPaletteEntries(UINT PaletteNumber,CONST PALETTEENTRY* pEntries) { NOT_IMPLEMENTED(); }
  349.         HRESULT STDMETHODCALLTYPE GetPaletteEntries(UINT PaletteNumber,PALETTEENTRY* pEntries) { NOT_IMPLEMENTED(); }
  350.         HRESULT STDMETHODCALLTYPE SetCurrentTexturePalette(UINT PaletteNumber) { NOT_IMPLEMENTED(); }
  351.         HRESULT STDMETHODCALLTYPE GetCurrentTexturePalette(UINT *PaletteNumber) { NOT_IMPLEMENTED(); }
  352.         HRESULT STDMETHODCALLTYPE SetScissorRect(CONST RECT* pRect) { NOT_IMPLEMENTED(); }
  353.         HRESULT STDMETHODCALLTYPE GetScissorRect(RECT* pRect) { NOT_IMPLEMENTED(); }
  354.         HRESULT STDMETHODCALLTYPE SetSoftwareVertexProcessing(BOOL bSoftware) { NOT_IMPLEMENTED(); }
  355.         BOOL    STDMETHODCALLTYPE GetSoftwareVertexProcessing() { return FALSE; }
  356.         HRESULT STDMETHODCALLTYPE SetNPatchMode(float nSegments) { NOT_IMPLEMENTED(); }
  357.         float    STDMETHODCALLTYPE GetNPatchMode() { return 0; }
  358.         HRESULT STDMETHODCALLTYPE DrawPrimitive(D3DPRIMITIVETYPE PrimitiveType,UINT StartVertex,UINT PrimitiveCount) { NOT_IMPLEMENTED(); }
  359.         HRESULT STDMETHODCALLTYPE DrawIndexedPrimitive(D3DPRIMITIVETYPE,INT BaseVertexIndex,UINT MinVertexIndex,UINT NumVertices,UINT startIndex,UINT primCount) { NOT_IMPLEMENTED(); }
  360.         HRESULT STDMETHODCALLTYPE DrawPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType,UINT PrimitiveCount,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) { NOT_IMPLEMENTED(); }
  361.         HRESULT STDMETHODCALLTYPE DrawIndexedPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex,UINT NumVertices,UINT PrimitiveCount,CONST void* pIndexData,D3DFORMAT IndexDataFormat,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) { NOT_IMPLEMENTED(); }
  362.         HRESULT STDMETHODCALLTYPE ProcessVertices(UINT SrcStartIndex,UINT DestIndex,UINT VertexCount,IDirect3DVertexBuffer9* pDestBuffer,IDirect3DVertexDeclaration9* pVertexDecl,DWORD Flags) { NOT_IMPLEMENTED(); }
  363.         HRESULT STDMETHODCALLTYPE CreateVertexDeclaration(CONST D3DVERTEXELEMENT9* pVertexElements,IDirect3DVertexDeclaration9** ppDecl) { NOT_IMPLEMENTED(); }
  364.         HRESULT STDMETHODCALLTYPE SetVertexDeclaration(IDirect3DVertexDeclaration9* pDecl) { NOT_IMPLEMENTED(); }
  365.         HRESULT STDMETHODCALLTYPE GetVertexDeclaration(IDirect3DVertexDeclaration9** ppDecl) { NOT_IMPLEMENTED(); }
  366.         HRESULT STDMETHODCALLTYPE SetFVF(DWORD FVF) { NOT_IMPLEMENTED(); }
  367.         HRESULT STDMETHODCALLTYPE GetFVF(DWORD* pFVF) { NOT_IMPLEMENTED(); }
  368.         HRESULT STDMETHODCALLTYPE GetVertexShader(IDirect3DVertexShader9** ppShader) { NOT_IMPLEMENTED(); }
  369.         HRESULT STDMETHODCALLTYPE GetVertexShaderConstantF(UINT StartRegister,float* pConstantData,UINT Vector4fCount) { NOT_IMPLEMENTED(); }
  370.         HRESULT STDMETHODCALLTYPE GetVertexShaderConstantI(UINT StartRegister,int* pConstantData,UINT Vector4iCount) { NOT_IMPLEMENTED(); }
  371.         HRESULT STDMETHODCALLTYPE GetVertexShaderConstantB(UINT StartRegister,BOOL* pConstantData,UINT BoolCount) { NOT_IMPLEMENTED(); }
  372.         HRESULT STDMETHODCALLTYPE SetStreamSource(UINT StreamNumber,IDirect3DVertexBuffer9* pStreamData,UINT OffsetInBytes,UINT Stride) { NOT_IMPLEMENTED(); }
  373.         HRESULT STDMETHODCALLTYPE GetStreamSource(UINT StreamNumber,IDirect3DVertexBuffer9** ppStreamData,UINT* pOffsetInBytes,UINT* pStride) { NOT_IMPLEMENTED(); }
  374.         HRESULT STDMETHODCALLTYPE SetStreamSourceFreq(UINT StreamNumber,UINT Setting) { NOT_IMPLEMENTED(); }
  375.         HRESULT STDMETHODCALLTYPE GetStreamSourceFreq(UINT StreamNumber,UINT* pSetting) { NOT_IMPLEMENTED(); }
  376.         HRESULT STDMETHODCALLTYPE SetIndices(IDirect3DIndexBuffer9* pIndexData) { NOT_IMPLEMENTED(); }
  377.         HRESULT STDMETHODCALLTYPE GetIndices(IDirect3DIndexBuffer9** ppIndexData) { NOT_IMPLEMENTED(); }
  378.         HRESULT STDMETHODCALLTYPE GetPixelShader(IDirect3DPixelShader9** ppShader) { NOT_IMPLEMENTED(); }
  379.         HRESULT STDMETHODCALLTYPE GetPixelShaderConstantI(UINT StartRegister,int* pConstantData,UINT Vector4iCount) { NOT_IMPLEMENTED(); }
  380.         HRESULT STDMETHODCALLTYPE GetPixelShaderConstantF(UINT StartRegister,float* pConstantData,UINT Vector4fCount) { NOT_IMPLEMENTED(); }
  381.         HRESULT STDMETHODCALLTYPE GetPixelShaderConstantB(UINT StartRegister,BOOL* pConstantData,UINT BoolCount) { NOT_IMPLEMENTED(); }
  382.         HRESULT STDMETHODCALLTYPE DrawRectPatch(UINT Handle,CONST float* pNumSegs,CONST D3DRECTPATCH_INFO* pRectPatchInfo) { NOT_IMPLEMENTED(); }
  383.         HRESULT STDMETHODCALLTYPE DrawTriPatch(UINT Handle,CONST float* pNumSegs,CONST D3DTRIPATCH_INFO* pTriPatchInfo) { NOT_IMPLEMENTED(); }
  384.         HRESULT STDMETHODCALLTYPE DeletePatch(UINT Handle) { NOT_IMPLEMENTED(); }
  385.         HRESULT STDMETHODCALLTYPE CreateQuery(D3DQUERYTYPE Type,IDirect3DQuery9** ppQuery) { NOT_IMPLEMENTED(); }
  386.  
  387.         HRESULT STDMETHODCALLTYPE CreateVertexShader(CONST DWORD* pFunction,IDirect3DVertexShader9** ppShader) {
  388.             *ppShader = new DummyD3DVertexShader(this, pFunction);
  389.             (*ppShader)->AddRef();
  390.             return S_OK;
  391.         }
  392.  
  393.         HRESULT STDMETHODCALLTYPE CreatePixelShader(CONST DWORD* pFunction,IDirect3DPixelShader9** ppShader) {
  394.             *ppShader = new DummyD3DPixelShader(this, pFunction);
  395.             (*ppShader)->AddRef();
  396.             return S_OK;
  397.         }
  398.  
  399.         HRESULT STDMETHODCALLTYPE SetVertexShader(IDirect3DVertexShader9* pShader) { return S_OK; }
  400.         HRESULT STDMETHODCALLTYPE SetVertexShaderConstantF(UINT StartRegister,CONST float* pConstantData,UINT Vector4fCount) { return S_OK; }
  401.         HRESULT STDMETHODCALLTYPE SetVertexShaderConstantI(UINT StartRegister,CONST int* pConstantData,UINT Vector4iCount) { return S_OK; }
  402.         HRESULT STDMETHODCALLTYPE SetVertexShaderConstantB(UINT StartRegister,CONST BOOL* pConstantData,UINT  BoolCount) { return S_OK; }
  403.  
  404.         HRESULT STDMETHODCALLTYPE SetPixelShader(IDirect3DPixelShader9* pShader) { return S_OK; }
  405.         HRESULT STDMETHODCALLTYPE SetPixelShaderConstantF(UINT StartRegister,CONST float* pConstantData,UINT Vector4fCount) { return S_OK; }
  406.         HRESULT STDMETHODCALLTYPE SetPixelShaderConstantI(UINT StartRegister,CONST int* pConstantData,UINT Vector4iCount) { return S_OK; }
  407.         HRESULT STDMETHODCALLTYPE SetPixelShaderConstantB(UINT StartRegister,CONST BOOL* pConstantData,UINT  BoolCount) { return S_OK; }
  408.  
  409.         // We need to record these.
  410.         HRESULT STDMETHODCALLTYPE SetTexture(DWORD Stage,IDirect3DBaseTexture9* pTexture) {
  411.             if (pTexture && mRequiredCaps.MaxSimultaneousTextures <= Stage)
  412.                 mRequiredCaps.MaxSimultaneousTextures = Stage + 1;
  413.  
  414.             uint32 token = 0x30000000 + (Stage << 12);
  415.  
  416.             if (pTexture)
  417.                 token += static_cast<DummyD3DBaseTexture *>(pTexture)->GetId();
  418.  
  419.             mAccumulatedStates.push_back(token);
  420.             return S_OK;
  421.         }
  422.  
  423.         HRESULT STDMETHODCALLTYPE SetTextureStageState(DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD Value) {
  424.             if ((Type == D3DTSS_COLOROP || Type == D3DTSS_ALPHAOP) && Value != D3DTOP_DISABLE) {
  425.                 if (mRequiredCaps.MaxTextureBlendStages <= Stage)
  426.                     mRequiredCaps.MaxTextureBlendStages = Stage + 1;
  427.  
  428.                 switch(Value) {
  429.                     case D3DTOP_ADD:                        mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_ADD; break;
  430.                     case D3DTOP_ADDSIGNED:                    mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_ADDSIGNED; break;
  431.                     case D3DTOP_ADDSIGNED2X:                mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_ADDSIGNED2X; break;
  432.                     case D3DTOP_ADDSMOOTH:                    mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_ADDSMOOTH; break;
  433.                     case D3DTOP_BLENDCURRENTALPHA:            mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_BLENDCURRENTALPHA; break;
  434.                     case D3DTOP_BLENDDIFFUSEALPHA:            mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_BLENDDIFFUSEALPHA; break;
  435.                     case D3DTOP_BLENDFACTORALPHA:            mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_BLENDFACTORALPHA; break;
  436.                     case D3DTOP_BLENDTEXTUREALPHA:            mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_BLENDTEXTUREALPHA; break;
  437.                     case D3DTOP_BLENDTEXTUREALPHAPM:        mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_BLENDTEXTUREALPHAPM; break;
  438.                     case D3DTOP_BUMPENVMAP:                    mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_BUMPENVMAP; break;
  439.                     case D3DTOP_BUMPENVMAPLUMINANCE:        mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_BUMPENVMAPLUMINANCE; break;
  440.                     case D3DTOP_DISABLE:                    mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_DISABLE; break;
  441.                     case D3DTOP_DOTPRODUCT3:                mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_DOTPRODUCT3; break;
  442.                     case D3DTOP_LERP:                        mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_LERP; break;
  443.                     case D3DTOP_MODULATE:                    mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_MODULATE; break;
  444.                     case D3DTOP_MODULATE2X:                    mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_MODULATE2X; break;
  445.                     case D3DTOP_MODULATE4X:                    mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_MODULATE4X; break;
  446.                     case D3DTOP_MODULATEALPHA_ADDCOLOR:        mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR; break;
  447.                     case D3DTOP_MODULATECOLOR_ADDALPHA:        mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA; break;
  448.                     case D3DTOP_MODULATEINVALPHA_ADDCOLOR:    mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR; break;
  449.                     case D3DTOP_MODULATEINVCOLOR_ADDALPHA:    mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA; break;
  450.                     case D3DTOP_MULTIPLYADD:                mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_MULTIPLYADD; break;
  451.                     case D3DTOP_PREMODULATE:                mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_PREMODULATE; break;
  452.                     case D3DTOP_SELECTARG1:                    mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_SELECTARG1; break;
  453.                     case D3DTOP_SELECTARG2:                    mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_SELECTARG2; break;
  454.                     case D3DTOP_SUBTRACT:                    mRequiredCaps.TextureOpCaps |= D3DTEXOPCAPS_SUBTRACT; break;
  455.                 }
  456.             }
  457.  
  458.             uint32 token = 0x10000000 + (Stage << 24) + (Type << 12);
  459.  
  460.             if (Value < 0xFFF) {
  461.                 mAccumulatedStates.push_back(token + Value);
  462.             } else {
  463.                 mAccumulatedStates.push_back(token + 0xFFF);
  464.                 mAccumulatedStates.push_back(Value);
  465.             }
  466.             return S_OK;
  467.         }
  468.  
  469.         HRESULT STDMETHODCALLTYPE SetRenderState(D3DRENDERSTATETYPE State,DWORD Value) {
  470.             switch(State) {
  471.                 case D3DRS_BLENDOP:
  472.                     if (Value != D3DBLENDOP_ADD)
  473.                         mRequiredCaps.PrimitiveMiscCaps |= D3DPMISCCAPS_BLENDOP;
  474.                     break;
  475.  
  476.                 case D3DRS_SRCBLEND:
  477.                 case D3DRS_DESTBLEND:
  478.                     {
  479.                         DWORD blendCap = 0;
  480.  
  481.                         switch(Value) {
  482.                             case D3DBLEND_BLENDFACTOR:
  483.                                 blendCap = D3DPBLENDCAPS_BLENDFACTOR;
  484.                                 break;
  485.                             case D3DBLEND_BOTHINVSRCALPHA:
  486.                                 blendCap = D3DPBLENDCAPS_BOTHINVSRCALPHA;
  487.                                 break;
  488.                             case D3DBLEND_BOTHSRCALPHA:
  489.                                 blendCap = D3DPBLENDCAPS_BOTHSRCALPHA;
  490.                                 break;
  491.                             case D3DBLEND_DESTALPHA:
  492.                                 blendCap = D3DPBLENDCAPS_DESTALPHA;
  493.                                 break;
  494.                             case D3DBLEND_DESTCOLOR:
  495.                                 blendCap = D3DPBLENDCAPS_DESTCOLOR;
  496.                                 break;
  497.                             case D3DBLEND_INVDESTALPHA:
  498.                                 blendCap = D3DPBLENDCAPS_INVDESTALPHA;
  499.                                 break;
  500.                             case D3DBLEND_INVDESTCOLOR:
  501.                                 blendCap = D3DPBLENDCAPS_INVDESTCOLOR;
  502.                                 break;
  503.                             case D3DBLEND_INVSRCALPHA:
  504.                                 blendCap = D3DPBLENDCAPS_INVSRCALPHA;
  505.                                 break;
  506.                             case D3DBLEND_INVSRCCOLOR:
  507.                                 blendCap = D3DPBLENDCAPS_INVSRCCOLOR;
  508.                                 break;
  509.                             case D3DBLEND_ONE:
  510.                                 blendCap = D3DPBLENDCAPS_ONE;
  511.                                 break;
  512.                             case D3DBLEND_SRCALPHA:
  513.                                 blendCap = D3DPBLENDCAPS_SRCALPHA;
  514.                                 break;
  515.                             case D3DBLEND_SRCALPHASAT:
  516.                                 blendCap = D3DPBLENDCAPS_SRCALPHASAT;
  517.                                 break;
  518.                             case D3DBLEND_SRCCOLOR:
  519.                                 blendCap = D3DPBLENDCAPS_SRCCOLOR;
  520.                                 break;
  521.                             case D3DBLEND_ZERO:
  522.                                 blendCap = D3DPBLENDCAPS_ZERO;
  523.                                 break;
  524.                         }
  525.  
  526.                         if (State == D3DRS_SRCBLEND)
  527.                             mRequiredCaps.SrcBlendCaps |= blendCap;
  528.                         else
  529.                             mRequiredCaps.DestBlendCaps |= blendCap;
  530.                     }
  531.                     break;
  532.             }
  533.  
  534.             if (Value < 0xFFF) {
  535.                 mAccumulatedStates.push_back((State << 12) + Value);
  536.             } else {
  537.                 mAccumulatedStates.push_back((State << 12) + 0xFFF);
  538.                 mAccumulatedStates.push_back(Value);
  539.             }
  540.             return S_OK;
  541.         }
  542.  
  543.         HRESULT STDMETHODCALLTYPE SetSamplerState(DWORD Sampler,D3DSAMPLERSTATETYPE Type,DWORD Value) {
  544.             uint32 token = 0x20000000 + (Sampler << 24) + (Type << 12);
  545.  
  546.             if (Value < 0xFFF) {
  547.                 mAccumulatedStates.push_back(token + Value);
  548.             } else {
  549.                 mAccumulatedStates.push_back(token + 0xFFF);
  550.                 mAccumulatedStates.push_back(Value);
  551.             }
  552.             return S_OK;
  553.         }
  554.  
  555.     public:
  556.         const uint32 *GetStates() const { return &mAccumulatedStates[0]; }
  557.         int GetStateCount() const { return (int)mAccumulatedStates.size(); }
  558.  
  559.         void ClearStates() { mAccumulatedStates.clear(); }
  560.  
  561.         const D3DCAPS9& GetRequiredCaps() const { return mRequiredCaps; }
  562.         void ClearRequiredCaps() {
  563.             memset(&mRequiredCaps, 0, sizeof mRequiredCaps);
  564.         }
  565.  
  566.     protected:
  567.         volatile LONG mRefCount;
  568.  
  569.         D3DCAPS9 mRequiredCaps;
  570.  
  571.         vdfastvector<uint32> mAccumulatedStates;
  572.     };
  573. }
  574.  
  575. namespace {
  576.     struct PassInfo {
  577.         int mVertexShaderIndex;
  578.         int mPixelShaderIndex;
  579.         int mStateStart;
  580.         int mStateEnd;
  581.         int mRenderTarget;
  582.         uint8 mViewportW;
  583.         uint8 mViewportH;
  584.         uint8 mBumpEnvScale;
  585.         bool mbClipPosition;
  586.         bool mbRTDoClear;
  587.         uint32 mRTClearColor;
  588.     };
  589.  
  590.     void DeleteShaderConstantTable(std::vector<uint32>& shader) {
  591.         LPCVOID data;
  592.         UINT size;
  593.         if (D3D_OK == D3DXFindShaderComment((const DWORD *)&shader[0], MAKEFOURCC('C', 'T', 'A', 'B'), &data, &size)) {
  594.             ptrdiff_t offset = (char *)data - (char *)&shader[0];
  595.  
  596.             VDASSERT(!(offset & 3));
  597.             VDASSERT(offset >= 8);
  598.  
  599.             // convert to dword offset
  600.             offset >>= 2;
  601.             size = (size + 3) >> 2;
  602.  
  603.             VDASSERT(offset + size <= shader.size());
  604.  
  605.             // erase comment token, fourcc, and comment data
  606.             shader.erase(shader.begin() + (offset - 2), shader.begin() + offset + size);
  607.         }
  608.     }
  609.  
  610.     void EmitShaderConstants(vdfastvector<uint32>& states, ID3DXConstantTable *pConstants, bool pixelShader) {
  611.         D3DXCONSTANTTABLE_DESC desc;
  612.         HRESULT hr;
  613.         hr = pConstants->GetDesc(&desc);
  614.         if (FAILED(hr)) {
  615.             printf("ID3DXConstantTable::GetDesc() failed, HRESULT=%08x\n", hr);
  616.             exit(20);
  617.         }
  618.  
  619.         D3DXCONSTANT_DESC descArray[16];
  620.         uint32 baseOffset = pixelShader ? 0x40000000 : 0x00000000;
  621.  
  622.         for(UINT i=0; i<desc.Constants; ++i) {
  623.             D3DXHANDLE hConstant = pConstants->GetConstant(NULL, i);
  624.             UINT count = 16;
  625.  
  626.             hr = pConstants->GetConstantDesc(hConstant, descArray, &count);
  627.             if (FAILED(hr)) {
  628.                 printf("ID3DXConstantTable::GetConstantDesc() failed, HRESULT=%08x\n", hr);
  629.                 exit(20);
  630.             }
  631.  
  632.             for(UINT dc=0; dc<count; ++dc) {
  633.                 const D3DXCONSTANT_DESC& desc = descArray[dc];
  634.  
  635.                 switch(desc.RegisterSet) {
  636.                     case D3DXRS_BOOL:
  637.                     case D3DXRS_INT4:
  638.                     case D3DXRS_FLOAT4:
  639.                         {
  640.                             for(int index=0; index<sizeof(kParameterNames)/sizeof(kParameterNames[0]); ++index) {
  641.                                 if (!strcmp(kParameterNames[index], desc.Name)) {
  642.                                     switch(desc.RegisterSet) {
  643.                                     case D3DXRS_BOOL:
  644.                                         states.push_back(baseOffset + 0x80000000 + (desc.RegisterIndex << 12) + index);
  645.                                         break;
  646.                                     case D3DXRS_INT4:
  647.                                         states.push_back(baseOffset + 0x90000000 + (desc.RegisterIndex << 12) + index);
  648.                                         break;
  649.                                     case D3DXRS_FLOAT4:
  650.                                         states.push_back(baseOffset + 0xA0000000 + (desc.RegisterIndex << 12) + index);
  651.                                         break;
  652.                                     }
  653.                                     goto param_found;
  654.                                 }
  655.                             }
  656.  
  657.                             printf("Error: Unknown constant: %s\n", desc.Name);
  658.                             exit(10);
  659.                         }
  660. param_found:
  661.                         break;
  662.                     case D3DXRS_SAMPLER:
  663.                         if (!strncmp(desc.Name, "vd_", 3)) {
  664.                             for(int index=0; index<sizeof(kTextureNames)/sizeof(kTextureNames[0]); ++index) {
  665.                                 if (!strcmp(kTextureNames[index], desc.Name)) {
  666.                                     UINT samplerIndex = pConstants->GetSamplerIndex(hConstant);
  667.                                     states.push_back(0x30000000 + (samplerIndex << 24) + index + 1);
  668.                                     goto texture_found;
  669.                                 }
  670.                             }
  671.  
  672.                             printf("Error: Unknown texture: %s\n", desc.Name);
  673.                             exit(10);
  674.                         }
  675. texture_found:
  676.                         break;
  677.                 }
  678.             }
  679.         }
  680.     }
  681. }
  682.  
  683. void tool_fxc(const vdfastvector<const char *>& args, const vdfastvector<const char *>& switches, bool amd64) {
  684.     if (args.size() != 2) {
  685.         puts("usage: asuka fxc source.fx target.cpp");
  686.         exit(5);
  687.     }
  688.  
  689.     const char *filename = args[0];
  690.  
  691.     printf("Asuka: Compiling effect file (Direct3D): %s -> %s.\n", filename, args[1]);
  692.  
  693.     vdrefptr<DummyD3DDevice> pDevice(new DummyD3DDevice);
  694.  
  695.     vdrefptr<ID3DXEffect> pEffect;
  696.     vdrefptr<ID3DXBuffer> pErrors;
  697.  
  698.     DWORD flags = D3DXSHADER_NO_PRESHADER;
  699.  
  700. #ifdef D3DXSHADER_USE_LEGACY_D3DX9_31_DLL
  701.     // The V32 compiler seems to be broken in that it thinks "point" and "linear" are
  702.     // keywords.
  703.     flags |= D3DXSHADER_USE_LEGACY_D3DX9_31_DLL;
  704. #endif
  705.  
  706.     HRESULT hr = D3DXCreateEffectFromFile(pDevice, filename, NULL, NULL, flags, NULL, ~pEffect, ~pErrors);
  707.  
  708.     if (FAILED(hr)) {
  709.         printf("Effect compilation failed for \"%s\"\n", filename);
  710.  
  711.         if (pErrors)
  712.             puts((const char *)pErrors->GetBufferPointer());
  713.  
  714.         exit(10);
  715.     }
  716.  
  717.     pErrors.clear();
  718.  
  719. #if 0
  720.     vdrefptr<ID3DXBuffer> pDisasm;
  721.     hr = D3DXDisassembleEffect(pEffect, FALSE, ~pDisasm);
  722.  
  723.     if (SUCCEEDED(hr))
  724.         puts((const char *)pDisasm->GetBufferPointer());
  725.  
  726.     pDisasm.clear();
  727. #endif
  728.  
  729.     // dump the effect
  730.     D3DXEFFECT_DESC desc;
  731.     pEffect->GetDesc(&desc);
  732.  
  733.     vdrefptr<DummyD3DBaseTexture> pDummyTextures[sizeof(kTextureNames) / sizeof(kTextureNames[0])];
  734.  
  735.     for(int i=0; i<sizeof(kTextureNames) / sizeof(kTextureNames[0]); ++i) {
  736.         pDummyTextures[i] = new DummyD3DBaseTexture(pDevice, i+1);
  737.  
  738.         pEffect->SetTexture(kTextureNames[i], pDummyTextures[i]);
  739.     }
  740.  
  741.     FILE *f = fopen(args[1], "w");
  742.     if (!f) {
  743.         printf("Couldn't open %s for write\n", args[1]);
  744.         exit(10);
  745.     }
  746.  
  747.     fprintf(f, "// Effect data auto-generated by Asuka from %s. DO NOT EDIT!\n", VDFileSplitPath(filename));
  748.  
  749.     fprintf(f, "\n");
  750.     fprintf(f, "struct PassInfo {\n");
  751.     fprintf(f, "\tint mVertexShaderIndex;\n");
  752.     fprintf(f, "\tint mPixelShaderIndex;\n");
  753.     fprintf(f, "\tint mStateStart;\n");
  754.     fprintf(f, "\tint mStateEnd;\n");
  755.     fprintf(f, "\tint mRenderTarget;\n");
  756.     fprintf(f, "\tuint8 mViewportW;\n");
  757.     fprintf(f, "\tuint8 mViewportH;\n");
  758.     fprintf(f, "\tuint8 mBumpEnvScale;\n");
  759.     fprintf(f, "\tbool mbClipPosition;\n");
  760.     fprintf(f, "\tbool mbRTDoClear;\n");
  761.     fprintf(f, "\tuint32 mRTClearColor;\n");
  762.     fprintf(f, "};\n");
  763.  
  764.     fprintf(f, "\n");
  765.     fprintf(f, "struct TechniqueInfo {\n");
  766.     fprintf(f, "\tconst PassInfo *mpPasses;\n");
  767.     fprintf(f, "\tuint32 mPassCount;\n");
  768.     fprintf(f, "\tuint32 mPSVersionRequired;\n");
  769.     fprintf(f, "\tuint32 mVSVersionRequired;\n");
  770.     fprintf(f, "\tuint32 mPrimitiveMiscCaps;\n");
  771.     fprintf(f, "\tuint32 mMaxSimultaneousTextures;\n");
  772.     fprintf(f, "\tuint32 mMaxTextureBlendStages;\n");
  773.     fprintf(f, "\tuint32 mSrcBlendCaps;\n");
  774.     fprintf(f, "\tuint32 mDestBlendCaps;\n");
  775.     fprintf(f, "\tuint32 mTextureOpCaps;\n");
  776.     fprintf(f, "\tfloat mPixelShader1xMaxValue;\n");
  777.     fprintf(f, "};\n");
  778.  
  779.     fprintf(f, "\n");
  780.     fprintf(f, "struct EffectInfo {\n");
  781.     fprintf(f, "\tconst uint32 *mpShaderData;\n");
  782.     fprintf(f, "\tconst uint32 *mVertexShaderOffsets;\n");
  783.     fprintf(f, "\tuint32 mVertexShaderCount;\n");
  784.     fprintf(f, "\tconst uint32 *mPixelShaderOffsets;\n");
  785.     fprintf(f, "\tuint32 mPixelShaderCount;\n");
  786.     fprintf(f, "};\n");
  787.  
  788.     std::list<std::vector<uint32> > mVertexShaders;
  789.     std::list<std::vector<uint32> > mPixelShaders;
  790.     vdfastvector<uint32> mStates;
  791.  
  792.     pDevice->ClearStates();
  793.  
  794.     for(int technique=0; technique<(int)desc.Techniques; ++technique) {
  795.         D3DXHANDLE hTechnique = pEffect->GetTechnique(technique);
  796.         D3DXTECHNIQUE_DESC techDesc;
  797.  
  798.         pEffect->GetTechniqueDesc(hTechnique, &techDesc);
  799.         pEffect->SetTechnique(hTechnique);
  800.  
  801.         pDevice->ClearRequiredCaps();
  802.  
  803.         UINT passCount = 0;
  804.         if (FAILED(pEffect->Begin(&passCount, D3DXFX_DONOTSAVESTATE))) {
  805.             puts("Begin failed!");
  806.             exit(20);
  807.         }
  808.  
  809.         vdfastvector<PassInfo> mPasses;
  810.         uint32 maxVSVersion = 0;
  811.         uint32 maxPSVersion = 0;
  812.  
  813.         for(int pass=0; pass<(int)passCount; ++pass) {
  814.             D3DXHANDLE hPass = pEffect->GetPass(hTechnique, pass);
  815.             D3DXPASS_DESC passDesc;
  816.  
  817.             pEffect->GetPassDesc(hPass, &passDesc);
  818.  
  819.             int stateStart = mStates.size();
  820.  
  821.             int psIndex = -1;
  822.             if (passDesc.pPixelShaderFunction) {
  823.                 std::vector<uint32> ps(passDesc.pPixelShaderFunction, passDesc.pPixelShaderFunction + (D3DXGetShaderSize(passDesc.pPixelShaderFunction) >> 2));
  824.  
  825.                 DeleteShaderConstantTable(ps);
  826.  
  827.                 // slow... fix if perf bottleneck
  828.                 int psIndex2 = 0;
  829.                 for(std::list<std::vector<uint32> >::const_iterator it(mPixelShaders.begin()), itEnd(mPixelShaders.end()); it!=itEnd; ++it, ++psIndex2) {
  830.                     if (*it == ps) {
  831.                         psIndex = psIndex2;
  832.                         break;
  833.                     }
  834.                 }
  835.  
  836.                 if (psIndex < 0) {
  837.                     mPixelShaders.push_back(std::vector<uint32>());
  838.                     mPixelShaders.back().swap(ps);
  839.                     psIndex = mPixelShaders.size() - 1;
  840.                 }
  841.  
  842.                 vdrefptr<ID3DXConstantTable> pConstantTable;
  843.                 if (D3D_OK == D3DXGetShaderConstantTable(passDesc.pPixelShaderFunction, ~pConstantTable))
  844.                     EmitShaderConstants(mStates, pConstantTable, true);
  845.  
  846.                 uint32 psVersion = passDesc.pPixelShaderFunction[0] & 0xffff;
  847.                 if (psVersion > maxPSVersion)
  848.                     maxPSVersion = psVersion;
  849.             }
  850.  
  851.             int vsIndex = -1;
  852.             if (passDesc.pVertexShaderFunction) {
  853.                 std::vector<uint32> vs(passDesc.pVertexShaderFunction, passDesc.pVertexShaderFunction + (D3DXGetShaderSize(passDesc.pVertexShaderFunction) >> 2));
  854.  
  855.                 DeleteShaderConstantTable(vs);
  856.  
  857.                 // slow... fix if perf bottleneck
  858.                 int vsIndex2 = 0;
  859.                 for(std::list<std::vector<uint32> >::const_iterator it(mVertexShaders.begin()), itEnd(mVertexShaders.end()); it!=itEnd; ++it, ++vsIndex2) {
  860.                     if (*it == vs) {
  861.                         vsIndex = vsIndex2;
  862.                         break;
  863.                     }
  864.                 }
  865.  
  866.                 if (vsIndex < 0) {
  867.                     mVertexShaders.push_back(std::vector<uint32>());
  868.                     mVertexShaders.back().swap(vs);
  869.                     vsIndex = mVertexShaders.size() - 1;
  870.                 }
  871.  
  872.                 vdrefptr<ID3DXConstantTable> pConstantTable;
  873.                 if (D3D_OK == D3DXGetShaderConstantTable(passDesc.pVertexShaderFunction, ~pConstantTable))
  874.                     EmitShaderConstants(mStates, pConstantTable, false);
  875.  
  876.                 uint32 vsVersion = passDesc.pVertexShaderFunction[0] & 0xffff;
  877.                 if (vsVersion > maxVSVersion)
  878.                     maxVSVersion = vsVersion;
  879.             }
  880.  
  881.             hr = pEffect->BeginPass(pass);
  882.             if (FAILED(hr)) {
  883.                 puts("BeginPass failed!");
  884.                 exit(20);
  885.             }
  886.  
  887.             int stateCount = pDevice->GetStateCount();
  888.             if (stateCount > 0) {
  889.                 const uint32 *p = pDevice->GetStates();
  890.                 mStates.insert(mStates.end(), p, p+stateCount);
  891.             }
  892.             int stateEnd = mStates.size();
  893.  
  894.             pDevice->ClearStates();
  895.  
  896.             PassInfo pi;
  897.             pi.mVertexShaderIndex = vsIndex;
  898.             pi.mPixelShaderIndex = psIndex;
  899.             pi.mStateStart = stateStart;
  900.             pi.mStateEnd = stateEnd;
  901.             pi.mRenderTarget = -1;
  902.             pi.mViewportW = 0;
  903.             pi.mViewportH = 0;
  904.  
  905.             // force first pass to always default to main RT
  906.             if (!pass) {
  907.                 pi.mRenderTarget = 0;
  908.                 pi.mViewportW = 2;
  909.                 pi.mViewportH = 2;
  910.             }
  911.  
  912.             D3DXHANDLE hRTAnno = pEffect->GetAnnotationByName(hPass, "vd_target");
  913.             if (hRTAnno) {
  914.                 LPCSTR s;
  915.                 if (SUCCEEDED(pEffect->GetString(hRTAnno, &s))) {
  916.                     if (!*s) {
  917.                         pi.mRenderTarget = 0;
  918.  
  919.                         // main RT defaults to out,out instead of full,full
  920.                         pi.mViewportW = 2;
  921.                         pi.mViewportH = 2;
  922.                     } else if (!strcmp(s, "temp"))
  923.                         pi.mRenderTarget = 1;
  924.                     else if (!strcmp(s, "temp2"))
  925.                         pi.mRenderTarget = 2;
  926.                     else {
  927.                         printf("Error: Unknown render target: %s\n", s);
  928.                         exit(10);
  929.                     }
  930.                 }
  931.             }
  932.  
  933.             D3DXHANDLE hVPAnno = pEffect->GetAnnotationByName(hPass, "vd_viewport");
  934.             if (hVPAnno) {
  935.                 LPCSTR s;
  936.                 if (SUCCEEDED(pEffect->GetString(hVPAnno, &s))) {
  937.                     bool valid = true;
  938.  
  939.                     const char *brk = strchr(s, ',');
  940.                     if (!brk)
  941.                         valid = false;
  942.  
  943.                     if (valid) {
  944.                         std::string hvp(s, brk);
  945.  
  946.                         if (hvp == "src")
  947.                             pi.mViewportW = 1;
  948.                         else if (hvp == "out")
  949.                             pi.mViewportW = 2;
  950.                         else if (hvp == "unclipped")
  951.                             pi.mViewportW = 3;
  952.                         else if (hvp == "full")
  953.                             pi.mViewportW = 0;
  954.                         else
  955.                             valid = false;
  956.                     }
  957.  
  958.                     if (valid) {
  959.                         ++brk;
  960.                         while(*brk == ' ')
  961.                             ++brk;
  962.  
  963.                         if (!strcmp(brk, "src"))
  964.                             pi.mViewportH = 1;
  965.                         else if (!strcmp(brk, "out"))
  966.                             pi.mViewportH = 2;
  967.                         else if (!strcmp(brk, "unclipped"))
  968.                             pi.mViewportH = 3;
  969.                         else if (!strcmp(brk, "full"))
  970.                             pi.mViewportH = 0;
  971.                         else
  972.                             valid = false;
  973.                     }
  974.  
  975.                     if (!valid) {
  976.                         printf("Error: Invalid viewport annotation: %s\n", s);
  977.                         exit(10);
  978.                     }
  979.                 }
  980.             }
  981.  
  982.             pi.mbClipPosition = false;
  983.             D3DXHANDLE hClipPosAnno = pEffect->GetAnnotationByName(hPass, "vd_clippos");
  984.             if (hClipPosAnno) {
  985.                 BOOL b;
  986.                 if (SUCCEEDED(pEffect->GetBool(hClipPosAnno, &b))) {
  987.                     if (b)
  988.                         pi.mbClipPosition = true;
  989.                 }
  990.             }
  991.  
  992.             pi.mbRTDoClear = false;
  993.             pi.mRTClearColor = 0;
  994.             D3DXHANDLE hRTClearAnno = pEffect->GetAnnotationByName(hPass, "vd_clear");
  995.             if (hRTClearAnno) {
  996.                 D3DXVECTOR4 v;
  997.                 if (SUCCEEDED(pEffect->GetVector(hRTClearAnno, &v))) {
  998.                     pi.mRTClearColor    = (VDClampedRoundFixedToUint8Fast(v.x) << 16)
  999.                                         + (VDClampedRoundFixedToUint8Fast(v.y) <<  8)
  1000.                                         + (VDClampedRoundFixedToUint8Fast(v.z) <<  0)
  1001.                                         + (VDClampedRoundFixedToUint8Fast(v.w) << 24);
  1002.  
  1003.                     pi.mbRTDoClear = true;
  1004.                 }
  1005.             }
  1006.  
  1007.             pi.mBumpEnvScale = 0;
  1008.             D3DXHANDLE hBESAnno = pEffect->GetAnnotationByName(hPass, "vd_bumpenvscale");
  1009.             if (hBESAnno) {
  1010.                 LPCSTR s;
  1011.                 if (SUCCEEDED(pEffect->GetString(hBESAnno, &s))) {
  1012.                     for(int i=0; i<sizeof(kParameterNames)/sizeof(kParameterNames[0]); ++i) {
  1013.                         if (!strcmp(s, kParameterNames[i])) {
  1014.                             pi.mBumpEnvScale = i+1;
  1015.                             break;
  1016.                         }
  1017.                     }
  1018.  
  1019.                     if (!pi.mBumpEnvScale) {
  1020.                         printf("Error: Unknown source for bump-map environment matrix scale: %s\n", s);
  1021.                         exit(10);
  1022.                     }
  1023.                 }
  1024.             }
  1025.  
  1026.             mPasses.push_back(pi);
  1027.  
  1028.             pEffect->EndPass();
  1029.         }
  1030.  
  1031.         pEffect->End();
  1032.  
  1033.         // emit passes
  1034.         fprintf(f, "static const PassInfo g_technique_%s_passes[]={\n", techDesc.Name);
  1035.         for(int i=0; i<(int)passCount; ++i) {
  1036.             const PassInfo& pi = mPasses[i];
  1037.             fprintf(f, "\t{ %d, %d, %d, %d, %d, %d, %d, %d, %s, %s, 0x%08x },\n"
  1038.                 , pi.mVertexShaderIndex
  1039.                 , pi.mPixelShaderIndex
  1040.                 , pi.mStateStart
  1041.                 , pi.mStateEnd
  1042.                 , pi.mRenderTarget
  1043.                 , pi.mViewportW
  1044.                 , pi.mViewportH
  1045.                 , pi.mBumpEnvScale
  1046.                 , pi.mbClipPosition ? "true" : "false"
  1047.                 , pi.mbRTDoClear ? "true" : "false"
  1048.                 , pi.mRTClearColor);
  1049.         }
  1050.         fprintf(f, "};\n");
  1051.  
  1052.         const D3DCAPS9& caps = pDevice->GetRequiredCaps();
  1053.  
  1054.         fprintf(f, "static const TechniqueInfo g_technique_%s={\n", techDesc.Name);
  1055.         fprintf(f, "\tg_technique_%s_passes, %d,\n", techDesc.Name, passCount);
  1056.         fprintf(f, "\tD3DPS_VERSION(%d,%d),\n", maxPSVersion >> 8, maxPSVersion & 255);
  1057.         fprintf(f, "\tD3DVS_VERSION(%d,%d),\n", maxVSVersion >> 8, maxVSVersion & 255);
  1058.         fprintf(f, "\t0x%08x,\n", caps.PrimitiveMiscCaps);
  1059.         fprintf(f, "\t0x%08x,\n", caps.MaxSimultaneousTextures);
  1060.         fprintf(f, "\t0x%08x,\n", caps.MaxTextureBlendStages);
  1061.         fprintf(f, "\t0x%08x,\n", caps.SrcBlendCaps);
  1062.         fprintf(f, "\t0x%08x,\n", caps.DestBlendCaps);
  1063.         fprintf(f, "\t0x%08x,\n", caps.TextureOpCaps);
  1064.         fprintf(f, "\t%d.f,\n", maxPSVersion >= 0x0104 ? 2 : maxPSVersion >= 0x0101 ? 1 : 0);
  1065.         fprintf(f, "};\n");
  1066.     }
  1067.  
  1068.     // Emit state array.
  1069.     const int stateCount = mStates.size();
  1070.     if (stateCount > 0) {
  1071.         fprintf(f, "static const uint32 g_states[]={\n");
  1072.         for(int i=0; i<stateCount; i+=8) {
  1073.             fprintf(f, "\t");
  1074.             for(int j=i; j<i+8 && j<stateCount; ++j) {
  1075.                 fprintf(f, "0x%08x,", mStates[j]);
  1076.             }
  1077.             fprintf(f, "\n");
  1078.         }
  1079.         fprintf(f, "};\n");
  1080.     }
  1081.  
  1082.     // Emit all vertex and pixel shaders
  1083.     std::list<std::vector<uint32> >::iterator it, itEnd;
  1084.  
  1085.     std::vector<uint32> mShaderData;
  1086.     vdfastvector<int> mVertexShaderOffsets;
  1087.     vdfastvector<int> mPixelShaderOffsets;
  1088.  
  1089.     for(it=mVertexShaders.begin(), itEnd=mVertexShaders.end(); it!=itEnd; ++it) {
  1090.         mVertexShaderOffsets.push_back(mShaderData.size());
  1091.         mShaderData.insert(mShaderData.end(), it->begin(), it->end());
  1092.     }
  1093.     mVertexShaderOffsets.push_back(mShaderData.size());
  1094.  
  1095.     for(it=mPixelShaders.begin(), itEnd=mPixelShaders.end(); it!=itEnd; ++it) {
  1096.         mPixelShaderOffsets.push_back(mShaderData.size());
  1097.         mShaderData.insert(mShaderData.end(), it->begin(), it->end());
  1098.     }
  1099.     mPixelShaderOffsets.push_back(mShaderData.size());
  1100.  
  1101.     fprintf(f, "static const uint32 g_shaderData[]={\n");
  1102.     for(int i=0, count=mShaderData.size(); i<count; i+=8) {
  1103.         fprintf(f, "\t");
  1104.         for(int j=i; j<i+8 && j<count; ++j) {
  1105.             fprintf(f, "0x%08x,", mShaderData[j]);
  1106.         }
  1107.         fprintf(f, "\n");
  1108.     }
  1109.     fprintf(f, "};\n");
  1110.  
  1111.     // output shader list
  1112.     fprintf(f, "static const uint32 g_shaderOffsets[]={\n");
  1113.     fprintf(f, "\t");
  1114.     for(int i=0; i<(int)mVertexShaderOffsets.size(); ++i)
  1115.         fprintf(f, "%d,", mVertexShaderOffsets[i]);
  1116.     fprintf(f, "\n");
  1117.     fprintf(f, "\t");
  1118.     for(int i=0; i<(int)mPixelShaderOffsets.size(); ++i)
  1119.         fprintf(f, "%d,", mPixelShaderOffsets[i]);
  1120.     fprintf(f, "\n");
  1121.     fprintf(f, "};\n");
  1122.  
  1123.     // output effect data
  1124.     fprintf(f, "static const EffectInfo g_effect={\n");
  1125.         fprintf(f, "\tg_shaderData,\n");
  1126.         fprintf(f, "\tg_shaderOffsets+0, %d,\n", mVertexShaderOffsets.size() - 1);
  1127.         fprintf(f, "\tg_shaderOffsets+%d, %d\n", mVertexShaderOffsets.size(), mPixelShaderOffsets.size() - 1);
  1128.     fprintf(f, "};\n");
  1129.     fclose(f);
  1130.  
  1131.     printf("Asuka: %d techniques, %d shader bytes, %d state bytes.\n", desc.Techniques, mShaderData.size()*4, mStates.size()*4);
  1132.     printf("Asuka: Compilation was successful.\n");
  1133. }
  1134.