⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dx9runtime.cpp

📁 用于GPU通用计算的编程语言BrookGPU 0.4
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// dx9runtime.cpp#include "dx9runtime.hpp"#include "dx9window.hpp"//#include "../../dx9/dx9pixelshader.hpp"//#include "../../dx9/dx9vertexshader.hpp"#include "dx9texture.hpp"#include <windows.h>#include <d3d9.h>#include <d3dx9.h>namespace brook{  static const float kInterpolantBias = 0.05f;  static const char* kPassthroughVertexShaderSource =    "vs.1.1\n"    "dcl_position v0\n"    "dcl_texcoord0 v1\n"    "dcl_texcoord1 v2\n"    "dcl_texcoord2 v3\n"    "dcl_texcoord3 v4\n"    "dcl_texcoord4 v5\n"    "dcl_texcoord5 v6\n"    "dcl_texcoord6 v7\n"    "dcl_texcoord7 v8\n"    "mov oPos, v0\n"    "mov oT0, v1\n"    "mov oT1, v2\n"    "mov oT2, v3\n"    "mov oT3, v4\n"    "mov oT4, v5\n"    "mov oT5, v6\n"    "mov oT6, v7\n"    "mov oT7, v8\n"    ;  static const char* kPassthroughPixelShaderSource =    "ps_2_0\n"    "dcl t0.xy\n"    "dcl_2d s0\n"    "texld r0, t0, s0\n"    "mov oC0, r0\n"    ;  static const D3DVERTEXELEMENT9 kDX9VertexElements[] =  {    { 0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },    { 0, 4*sizeof(float), D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },    { 0, 8*sizeof(float), D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1 },    { 0, 12*sizeof(float), D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2 },    { 0, 16*sizeof(float), D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 3 },    { 0, 20*sizeof(float), D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 4 },    { 0, 24*sizeof(float), D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 5 },    { 0, 28*sizeof(float), D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 6 },    { 0, 32*sizeof(float), D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 7 },    D3DDECL_END()  };  struct DX9Vertex  {    float4 position;    float4 texcoords[8]; // TIM: TODO: named constant  };  class GPUContextDX9Impl : public GPUContextDX9  {  public:    static GPUContextDX9Impl* create( void* inContextValue );    virtual bool isRenderTextureFormatValid( D3DFORMAT inFormat );    virtual IDirect3DDevice9* getDevice() {        return _device;    }    virtual int getShaderFormatRank( const char* inNameString ) const;    virtual bool isTextureExtentValid( unsigned int inExtent ) const {        return inExtent <= 2048; // TIM: arbitrary and hardcoded... bad    }    virtual float4 getStreamIndexofConstant( TextureHandle inTexture ) const;    virtual float4 getStreamGatherConstant(      unsigned int inRank, const unsigned int* inDomainMin,      const unsigned int* inDomainMax, const unsigned int* inExtents ) const;    virtual void      get1DInterpolant( const float4 &start,       const float4 &end,      const unsigned int outputWidth,      GPUInterpolant &interpolant) const;    virtual void       get2DInterpolant( const float2 &start,       const float2 &end,      const unsigned int outputWidth,      const unsigned int outputHeight,       GPUInterpolant &interpolant) const;    virtual void     getStreamInterpolant( const TextureHandle texture,                          unsigned int rank,                          const unsigned int* domainMin,                          const unsigned int* domainMax,                          const unsigned int outputWidth,                          const unsigned int outputHeight,                           GPUInterpolant &interpolant) const;        virtual void    getStreamOutputRegion( const TextureHandle texture,                           unsigned int rank,                           const unsigned int* domainMin,                           const unsigned int* domainMax,                           GPURegion &region) const;    virtual void       getStreamReduceInterpolant( const TextureHandle texture,      const unsigned int outputWidth,      const unsigned int outputHeight,       const unsigned int minX,      const unsigned int maxX,       const unsigned int minY,      const unsigned int maxY,      GPUInterpolant &interpolant) const;    virtual void      getStreamReduceOutputRegion( const TextureHandle texture,      const unsigned int minX,      const unsigned int maxX,       const unsigned int minY,      const unsigned int maxY,      GPURegion &region) const;    virtual TextureHandle createTexture2D( size_t inWidth, size_t inHeight, TextureFormat inFormat );    virtual void releaseTexture( TextureHandle inTexture );    virtual void setTextureData( TextureHandle inTexture, const float* inData, size_t inStrideBytes, size_t inComponentCount,      unsigned int inRank,      const unsigned int* inDomainMin,      const unsigned int* inDomainMax,      const unsigned int* inExtents, bool inUsesAddressTranslation );    virtual void getTextureData( TextureHandle inTexture, float* outData, size_t inStrideBytes, size_t inComponentCount,      unsigned int inRank,      const unsigned int* inDomainMin,      const unsigned int* inDomainMax,      const unsigned int* inExtents, bool inUsesAddressTranslation );    virtual PixelShaderHandle createPixelShader( const char* inSource );    VertexShaderHandle createVertexShader( const char* inSource );    virtual VertexShaderHandle getPassthroughVertexShader() {      return _passthroughVertexShader;    }    virtual PixelShaderHandle getPassthroughPixelShader() {      return _passthroughPixelShader;    }    virtual void beginScene();    virtual void endScene();    virtual void bindConstant( PixelShaderHandle ps, size_t inIndex, const float4& inValue );    virtual void bindTexture( size_t inIndex, TextureHandle inTexture );    virtual void bindOutput( size_t inIndex, TextureHandle inTexture );    virtual void disableOutput( size_t inIndex );    virtual void bindPixelShader( PixelShaderHandle inPixelShader );    virtual void bindVertexShader( VertexShaderHandle inVertexShader );    virtual void setOutputDomainMode( bool inUsingOutputDomain ) {
    }    virtual void setAddressTranslationMode( bool inUsingAddressTranslation ) {
    }    virtual void drawRectangle(      const GPURegion& outputRegion,       const GPUInterpolant* interpolants,       unsigned int numInterpolants );    /* hacky functions for rendering - will be deprecated soon */    virtual void* getTextureRenderData( TextureHandle inTexture );    virtual void synchronizeTextureRenderData( TextureHandle inTexture );  private:    GPUContextDX9Impl();    bool initialize( void* inContextValue );    DX9Window* _window;    IDirect3D9* _direct3D;    IDirect3DDevice9* _device;    D3DFORMAT _adapterFormat;    VertexShaderHandle _passthroughVertexShader;    PixelShaderHandle _passthroughPixelShader;    IDirect3DVertexBuffer9* _vertexBuffer;    IDirect3DVertexDeclaration9* _vertexDecl;    enum {      kMaximumSamplerCount = 16,      kMaximumOutputCount = 4    };    DX9Texture* _boundTextures[16];    DX9Texture* _boundOutputs[4];    D3DCAPS9 _deviceCaps;    bool _supportsPS2B;    bool _supportsPS2A;    bool _supportsPS30;    bool _isNV;    bool _isATI;	bool _shouldBiasInterpolants;  };  GPURuntimeDX9* GPURuntimeDX9::create( void* inContextValue )  {    GPUContextDX9Impl* context = GPUContextDX9Impl::create( inContextValue );    if( !context )      return NULL;    GPURuntimeDX9* result = new GPURuntimeDX9();    if( !result->initialize( context ) )    {      delete context;      return NULL;    }    return result;  }  GPUContextDX9Impl* GPUContextDX9Impl::create( void* inContextValue )  {    GPUContextDX9Impl* result = new GPUContextDX9Impl();    if( result->initialize( inContextValue ) )      return result;    delete result;    return NULL;  }  GPUContextDX9Impl::GPUContextDX9Impl()  {  }  bool GPUContextDX9Impl::initialize( void* inContextValue )  {    HRESULT result;    if( inContextValue == NULL )    {
      _window = DX9Window::create();      if( _window == NULL )      {        DX9WARN << "Could not create offscreen window.";        return false;      }      HWND windowHandle = _window->getWindowHandle();      _direct3D = Direct3DCreate9( D3D_SDK_VERSION );      if( _direct3D == NULL )      {        DX9WARN << "Could not create Direct3D interface.";        return false;      }      D3DPRESENT_PARAMETERS deviceDesc;      ZeroMemory( &deviceDesc, sizeof(deviceDesc) );      deviceDesc.Windowed = TRUE;      deviceDesc.SwapEffect = D3DSWAPEFFECT_DISCARD;      deviceDesc.BackBufferFormat = D3DFMT_UNKNOWN;      deviceDesc.EnableAutoDepthStencil = FALSE;      deviceDesc.AutoDepthStencilFormat = D3DFMT_D24S8;      result = _direct3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, windowHandle,        D3DCREATE_HARDWARE_VERTEXPROCESSING, &deviceDesc, &_device );      if( FAILED(result) )      {        DX9WARN << "Could not create Direct3D device.";        return false;      }    }    else    {
      _window = NULL;
      _device = (IDirect3DDevice9*)inContextValue;
      _device->GetDirect3D( &_direct3D );
    }    // retrieve adapter format    D3DDISPLAYMODE mode;    result = _device->GetDisplayMode( 0, &mode );    DX9AssertResult( result, "GetDisplayMode failed" );    _adapterFormat = mode.Format;    // get device caps    result = _device->GetDeviceCaps( &_deviceCaps );    DX9AssertResult( result, "GetDeviceCaps failed" );        // Ian:  There are many more differences than this between PS2B and     // PS2A but the biggie that we're going to count on is the number of     // outputs.    _supportsPS2B = _deviceCaps.PS20Caps.NumInstructionSlots >= 512 &&      _deviceCaps.PS20Caps.NumTemps >= 32 &&      _deviceCaps.NumSimultaneousRTs >= 4;    _supportsPS2A = _deviceCaps.PS20Caps.NumInstructionSlots >= 512 &&      _deviceCaps.PS20Caps.NumTemps >= 22 &&      _deviceCaps.PS20Caps.Caps & D3DPS20CAPS_NODEPENDENTREADLIMIT &&      _deviceCaps.NumSimultaneousRTs >= 1;    _supportsPS30 = (_deviceCaps.MaxPixelShader30InstructionSlots >= 512);    // TIM: this is *not* future-proof, but I don't know a way to    // get something like the GL vendor string from DX    _isNV = _supportsPS30;    _isATI = !_isNV;	_shouldBiasInterpolants = true; // all runtimes seem to prefer this    // create vertex buffer    static const int kMaxVertexCount = 64;    result = _device->CreateVertexBuffer(      kMaxVertexCount*sizeof(DX9Vertex), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &_vertexBuffer, NULL );    DX9AssertResult( result, "CreateVertexBuffer failed" );    result = _device->CreateVertexDeclaration( kDX9VertexElements, &_vertexDecl );    DX9AssertResult( result, "CreateVertexDeclaration failed" );    // TIM: set up initial state    result = _device->SetRenderState( D3DRS_ZENABLE, D3DZB_FALSE );    GPUAssert( !FAILED(result), "SetRenderState failed" );    _passthroughVertexShader = createVertexShader( kPassthroughVertexShaderSource );    _passthroughPixelShader = createPixelShader( kPassthroughPixelShaderSource );    for( size_t i = 0; i < kMaximumOutputCount; i++ )      _boundOutputs[i] = NULL;    for( size_t t = 0; t < kMaximumSamplerCount; t++ )      _boundTextures[t] = NULL;    return true;  }  bool GPUContextDX9Impl::isRenderTextureFormatValid( D3DFORMAT inFormat )  {      HRESULT result = _direct3D->CheckDeviceFormat(        D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,        _adapterFormat,        D3DUSAGE_RENDERTARGET,        D3DRTYPE_TEXTURE,        inFormat );      return result == S_OK;  }  int GPUContextDX9Impl::getShaderFormatRank( const char* inNameString ) const  {    if( strcmp( "ps20", inNameString ) == 0 )      return 1;    if( _supportsPS2A && strcmp( "ps2a", inNameString ) == 0 )      return 2;    if( _supportsPS2B && strcmp( "ps2b", inNameString ) == 0 )      return 3;    if( _supportsPS30 && strcmp( "ps30", inNameString ) == 0 )      return 4;    return -1;  }  float4 GPUContextDX9Impl::getStreamIndexofConstant( TextureHandle inTexture ) const  {    DX9Texture* texture = (DX9Texture*)inTexture;    int textureWidth = texture->getWidth();    int textureHeight = texture->getHeight();    return float4( (float)textureWidth, (float)textureHeight, 0, 0 );  }  float4 GPUContextDX9Impl::getStreamGatherConstant(    unsigned int inRank, const unsigned int* inDomainMin,    const unsigned int* inDomainMax, const unsigned int* inExtents ) const  {    float scaleX = 1.0f;    float scaleY = 1.0f;    float offsetX = 0.0f;    float offsetY = 0.0f;    if( inRank == 1 )    {
      unsigned int base = inDomainMin[0];
      unsigned int width = inExtents[0];

      scaleX = 1.0f / width;
      offsetX = base + (0.5f / width);
    }    else    {
      unsigned int baseX = inDomainMin[1];
      unsigned int baseY = inDomainMin[0];
      unsigned int width = inExtents[1];
      unsigned int height = inExtents[0];

      scaleX = 1.0f / width;
      scaleY = 1.0f / height;
      offsetX = (baseX + 0.5f) / width;
      offsetY = (baseY + 0.5f) / height;    }//    float offsetX = 1.0f / (1 << 15);//0.5f / width;//    float offsetY = 1.0f / (1 << 15);//0.5f / height;    return float4( scaleX, scaleY, offsetX, offsetY );  }  void GPUContextDX9Impl::get1DInterpolant( const float4 &start,     const float4 &end,    const unsigned int outputWidth,    GPUInterpolant &interpolant) const  {    float4 f1 = start;    float4 f2;    f2.x = end.x + end.x - start.x;    f2.y = end.y + end.y - start.y;    f2.z = end.z + end.z - start.z;    f2.w = end.w + end.w - start.w;    interpolant.vertices[0] = f1;    interpolant.vertices[1] = f2;     interpolant.vertices[2] = f1;  }  void GPUContextDX9Impl::get2DInterpolant( const float2 &start,     const float2 &end,    const unsigned int outputWidth,    const unsigned int outputHeight,     GPUInterpolant &interpolant) const  {    float4 f1 = float4( start.x, start.y, 0, 1 );    float4 f2;    f2.x = end.x + end.x - start.x;    f2.y = start.y;    f2.z = 0;    f2.w = 1;    float4 f3;    f3.x = start.x;    f3.y = end.y + end.y - start.y;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -