Beispiel #1
0
  GPUContextDX9::PixelShaderHandle GPUContextDX9::createPixelShader( const char* inSource )
  {
    IDirect3DPixelShader9* shader;
    HRESULT result;
    LPD3DXBUFFER codeBuffer;
    LPD3DXBUFFER errorBuffer;

    result = D3DXAssembleShader( inSource, strlen(inSource), NULL, NULL, 0, &codeBuffer, &errorBuffer );
    if( errorBuffer != NULL )
    {
      const char* errorMessage = (const char*)errorBuffer->GetBufferPointer();
      GPUWARN << "Pixel shader failed to compile:\n" << errorMessage;
      return NULL;
    }
    else if( FAILED(result) )
    {
      GPUWARN << "Pixel shader failed to compile.";
      return NULL;
    }

    result = _device->CreatePixelShader( (DWORD*)codeBuffer->GetBufferPointer(), &shader );
    codeBuffer->Release();

    if( FAILED(result) )
    {
      DX9WARN << "Failed to allocate pixel shader.";
      return NULL;
    }

    return (PixelShaderHandle)shader;
  }
//----------------------------------------------------------------------------
PdrPixelShader::PdrPixelShader (Renderer* renderer,
								const PixelShader* pshader)
{
	IDirect3DDevice9* device = renderer->mData->mDevice;

	// 编译汇编着色器代码
	const char* programText =
		pshader->GetProgram(PixelShader::GetProfile())->c_str();

	int shaderKey = pshader->GetShaderKey();
	assertion(0!=shaderKey, "shaderKey must not be 0.\n");
	std::map<int, Renderer::SharePdrData>::iterator it = renderer->mSharePdrPixelShaders.find(shaderKey);
	if (it != renderer->mSharePdrPixelShaders.end())
	{
		mShader = (IDirect3DPixelShader9*)(it->second.DataPtr);
		mShader->AddRef();
	}
	else
	{
		int programLength = (int)strlen(programText);
		LPD3DXBUFFER compiledShader = 0;
		LPD3DXBUFFER errors = 0;
		HRESULT hr = D3DXAssembleShader(programText, programLength, 0, 0, 0,
			&compiledShader, &errors);
#ifdef _DEBUG
		if (errors)
		{
			DWORD size = errors->GetBufferSize();
			PX2_UNUSED(size);
			char* data = (char*)errors->GetBufferPointer();
			PX2_UNUSED(data);
			assertion(false, "Failed to assemble pixel shader.\n");
		}
#endif
		PX2_UNUSED(hr);
		assertion(hr == D3D_OK && compiledShader,
			"Failed to assemble pixel shader: %s\n", DXGetErrorString(hr));

		// 创建像素着色器
		hr = device->CreatePixelShader( 
			(DWORD*)(compiledShader->GetBufferPointer()), &mShader);
		assertion(hr == D3D_OK, "Failed to create pixel shader\n");

		// 释放需要释放的数据
		if (compiledShader)
		{
			compiledShader->Release();
		}
		if (errors)
		{
			errors->Release();
		}
				
		renderer->mSharePdrPixelShaders[shaderKey].DataPtr = mShader;
		((IDirect3DPixelShader9*)renderer->mSharePdrPixelShaders[shaderKey].DataPtr)
			->AddRef();
	}
}
//----------------------------------------------------------------------------
PdrPixelShader::PdrPixelShader (Renderer* renderer,
                                const PixelShader* pshader)
{
    IDirect3DDevice9* device = renderer->mData->mDevice;

    // Compile the shader to assembly code.
    const char* programText =
        pshader->GetProgram(PixelShader::GetProfile())->c_str();
    int programLength = (int)strlen(programText);
    LPD3DXBUFFER compiledShader = 0;
    LPD3DXBUFFER errors = 0;
    HRESULT hr = D3DXAssembleShader(programText, programLength, 0, 0, 0,
                                    &compiledShader, &errors);
#ifdef _DEBUG
    if (errors)
    {
        DWORD size = errors->GetBufferSize();
        WM5_UNUSED(size);
        char* data = (char*)errors->GetBufferPointer();
        WM5_UNUSED(data);
        assertion(false, "Failed to assemble pixel shader.\n");
    }
#endif
    WM5_UNUSED(hr);
    assertion(hr == D3D_OK && compiledShader,
              "Failed to assemble pixel shader: %s\n", DXGetErrorString(hr));

    // Create the pixel shader.
    hr = device->CreatePixelShader(
             (DWORD*)(compiledShader->GetBufferPointer()), &mShader);
    assertion(hr == D3D_OK, "Failed to create pixel shader\n");

    // Release buffers, if necessary.
    if (compiledShader)
    {
        compiledShader->Release();
    }
    if (errors)
    {
        errors->Release();
    }
}
bool ShaderVariation::Create()
{
    Release();

    if (!graphics_)
        return false;

    if (!owner_)
    {
        compilerOutput_ = "Owner shader has expired";
        return false;
    }

    // Check for up-to-date bytecode on disk
    String path, name, extension;
    SplitPath(owner_->GetName(), path, name, extension);
    extension = type_ == VS ? ".vs3" : ".ps3";

    String binaryShaderName = graphics_->GetShaderCacheDir() + name + "_" + StringHash(defines_).ToString() + extension;

    if (!LoadByteCode(binaryShaderName))
    {
        // Compile shader if don't have valid bytecode
        if (!Compile())
            return false;
        // Save the bytecode after successful compile, but not if the source is from a package
        if (owner_->GetTimeStamp())
            SaveByteCode(binaryShaderName);
    }

    // Then create shader from the bytecode
    IDirect3DDevice9* device = graphics_->GetImpl()->GetDevice();
    if (type_ == VS)
    {
        HRESULT hr = device->CreateVertexShader(
            (const DWORD*)&byteCode_[0],
            (IDirect3DVertexShader9**)&object_.ptr_);
        if (FAILED(hr))
        {
            ATOMIC_SAFE_RELEASE(object_.ptr_);
            compilerOutput_ = "Could not create vertex shader (HRESULT " + ToStringHex((unsigned)hr) + ")";
        }
    }
    else
    {
        HRESULT hr = device->CreatePixelShader(
            (const DWORD*)&byteCode_[0],
            (IDirect3DPixelShader9**)&object_.ptr_);
        if (FAILED(hr))
        {
            ATOMIC_SAFE_RELEASE(object_.ptr_);
            compilerOutput_ = "Could not create pixel shader (HRESULT " + ToStringHex((unsigned)hr) + ")";
        }
    }

    // The bytecode is not needed on Direct3D9 after creation, so delete it to save memory
    byteCode_.Clear();
    byteCode_.Reserve(0);

    return object_.ptr_ != 0;
}
    void CFullscreenTriangleDrawer::CreateDX9Resources()
    {
        HRESULT hr = S_OK;

        float VertexData[] =
        {
            -1.0f,  1.0f, 0.0f, 0.0f, 0.0f,
            3.0f,  1.0f, 0.0f, 2.0f, 0.0f,
            -1.0f, -3.0f, 0.0f, 0.0f, 2.0f,
        };

        IDirect3DDevice9* pDevice = static_cast<IDirect3DDevice9*>( gD3DDevice );

        // Vertex buffer
        hr = pDevice->CreateVertexBuffer( sizeof( VertexData ), D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &m_pVertexBuffer, NULL );
        CRY_ASSERT( SUCCEEDED( hr ) );

        float* pVertexBuffer = NULL;
        hr = m_pVertexBuffer->Lock( 0, 0, ( void** )&pVertexBuffer, 0 );
        CRY_ASSERT( SUCCEEDED( hr ) );
        memcpy( pVertexBuffer, VertexData, sizeof( VertexData ) );
        m_pVertexBuffer->Unlock();

        // Vertex declaration
        D3DVERTEXELEMENT9 VertexElements[] =
        {
            {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
            {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
            D3DDECL_END()
        };
        hr = pDevice->CreateVertexDeclaration( VertexElements, &m_pVertexDeclaration );
        CRY_ASSERT( SUCCEEDED( hr ) );

        // Vertex shader

        /*
        // FSTriangle.vs
        // fxc /O2 /T vs_2_0 /E VSMain
        float Width : register(c0);
        float Height : register(c1);

        struct VertexPT
        {
            float4 PositionL : POSITION0;
            float2 TexCoord  : TEXCOORD0;
        };

        VertexPT VSMain(VertexPT vsIn)
        {
            vsIn.PositionL += float4(-0.5 / Width, 0.5 / Height, 0, 0);
            return vsIn;
        }
        */

        const char CompiledVS[] =
        {
            0x00, 0x02, 0xfe, 0xff, 0xfe, 0xff, 0x28, 0x00, 0x43, 0x54, 0x41, 0x42,
            0x1c, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x02, 0xfe, 0xff,
            0x02, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00,
            0x62, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00,
            0x01, 0x00, 0x06, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x5c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
            0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x65, 0x69, 0x67,
            0x68, 0x74, 0x00, 0xab, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x01, 0x00,
            0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x69, 0x64, 0x74,
            0x68, 0x00, 0x76, 0x73, 0x5f, 0x32, 0x5f, 0x30, 0x00, 0x4d, 0x69, 0x63,
            0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48,
            0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43,
            0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39,
            0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0xab, 0xab,
            0x51, 0x00, 0x00, 0x05, 0x02, 0x00, 0x0f, 0xa0, 0x00, 0x00, 0x00, 0xbf,
            0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0f, 0x90,
            0x1f, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x80, 0x01, 0x00, 0x0f, 0x90,
            0x06, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0xa0,
            0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x80,
            0x02, 0x00, 0x00, 0xa0, 0x06, 0x00, 0x00, 0x02, 0x01, 0x00, 0x01, 0x80,
            0x01, 0x00, 0x00, 0xa0, 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0x80,
            0x01, 0x00, 0x00, 0x80, 0x02, 0x00, 0x55, 0xa0, 0x01, 0x00, 0x00, 0x02,
            0x00, 0x00, 0x0c, 0x80, 0x02, 0x00, 0xaa, 0xa0, 0x02, 0x00, 0x00, 0x03,
            0x00, 0x00, 0x0f, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xe4, 0x90,
            0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x03, 0xe0, 0x01, 0x00, 0xe4, 0x90,
            0xff, 0xff, 0x00, 0x00,
        };

        hr = pDevice->CreateVertexShader( ( DWORD* )CompiledVS, &m_pVertexShader9 );
        CRY_ASSERT( SUCCEEDED( hr ) );

        // Pixel shader

        /*
        // FSTriangle.ps
        // fxc /O2 /T ps_2_0 /E PSMain
        texture Texture : register(s0);

        sampler PointSampler = sampler_state
        {
            Texture = <Texture>;
            MinFilter = Point;
            MagFilter = Point;
            MipFilter = Point;
            MaxAnisotropy = 1;
            AddressU  = CLAMP;
            AddressV  = CLAMP;
        };

        struct VertexPT
        {
            float4 PositionL : POSITION0;
            float2 TexCoord  : TEXCOORD0;
        };

        float4 PSMain(VertexPT psIn) : COLOR
        {
            return tex2D(PointSampler, psIn.TexCoord);
        }

        */

        const char CompiledPS[] =
        {
            0x00, 0x02, 0xff, 0xff, 0xfe, 0xff, 0x23, 0x00, 0x43, 0x54, 0x41, 0x42,
            0x1c, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff,
            0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00,
            0x50, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
            0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x50, 0x6f, 0x69, 0x6e, 0x74, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72,
            0x00, 0xab, 0xab, 0xab, 0x04, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00,
            0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x73, 0x5f, 0x32,
            0x5f, 0x30, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74,
            0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68,
            0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65,
            0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33,
            0x31, 0x31, 0x31, 0x00, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80,
            0x00, 0x00, 0x03, 0xb0, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x90,
            0x00, 0x08, 0x0f, 0xa0, 0x42, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0f, 0x80,
            0x00, 0x00, 0xe4, 0xb0, 0x00, 0x08, 0xe4, 0xa0, 0x01, 0x00, 0x00, 0x02,
            0x00, 0x08, 0x0f, 0x80, 0x00, 0x00, 0xe4, 0x80, 0xff, 0xff, 0x00, 0x00,
        };
        hr = pDevice->CreatePixelShader( ( DWORD* )CompiledPS, &m_pPixelShader9 );
        CRY_ASSERT( SUCCEEDED( hr ) );

        hr = pDevice->CreateStateBlock( D3DSBT_ALL, &m_pStateBlock );
        CRY_ASSERT( SUCCEEDED( hr ) );
    }
bool CD3D9Shader::_Create()
{
	LPD3DXBUFFER pBuffer = ( m_pCode && m_pCode->GetBufferPointer() ) ? *reinterpret_cast<LPD3DXBUFFER*>( m_pCode->GetBufferPointer() ) : ALCHEMY_NULL;
	if(pBuffer)
	{
		LPD3DXBUFFER pAdditionalBuffer = ( m_pAdditionalCode && m_pAdditionalCode->GetBufferPointer() ) ? *reinterpret_cast<LPD3DXBUFFER*>( m_pAdditionalCode->GetBufferPointer() ) : ALCHEMY_NULL;

		IEffect::EFFECTTYPE Type = GetShaderType();
		if(Type == IEffect::VERTEX_SHADER)
		{
			IDirect3DDevice9* pDevice = static_cast<CD3D9Device&>( GetGraphicsResourcePool() ).GetDevice();
			if(pDevice && pDevice->CreateVertexShader( reinterpret_cast<const DWORD*>( pBuffer->GetBufferPointer() ), &m_Shader.pVertexShader) == D3D_OK)
			{
				pBuffer->Release();

				m_pCode->Release();

				m_pCode = ALCHEMY_NULL;

				return true;
			}
		}
		else if(Type == IEffect::FRAGMENT_SHADER)
		{
			IDirect3DDevice9* pDevice = static_cast<CD3D9Device&>( GetGraphicsResourcePool() ).GetDevice();
			if(pDevice && pDevice->CreatePixelShader( reinterpret_cast<const DWORD*>( pBuffer->GetBufferPointer() ), &m_Shader.pPixelShader) == D3D_OK)
			{
				pBuffer->Release();

				m_pCode->Release();

				m_pCode = ALCHEMY_NULL;

				return true;
			}
		}
		else if(pAdditionalBuffer)
		{
			IDirect3DDevice9* pDevice = static_cast<CD3D9Device&>( GetGraphicsResourcePool() ).GetDevice();

			if(pDevice && pDevice->CreateVertexShader( reinterpret_cast<const DWORD*>( pBuffer->GetBufferPointer() ), &m_Shader.pVertexShader) == D3D_OK)
			{
				pBuffer->Release();

				m_pCode->Release();

				m_pCode = ALCHEMY_NULL;

				return true;
			}

			if(pDevice && pDevice->CreatePixelShader( reinterpret_cast<const DWORD*>( pAdditionalBuffer->GetBufferPointer() ), &m_Shader.pPixelShader) == D3D_OK)
			{
				pAdditionalBuffer->Release();

				m_pAdditionalCode->Release();

				m_pAdditionalCode = ALCHEMY_NULL;

				return true;
			}
		}
	}

	if(m_pCode)
	{
		m_pCode->Release();

		m_pCode = ALCHEMY_NULL;
	}

	if(m_pAdditionalCode)
	{
		m_pAdditionalCode->Release();

		m_pAdditionalCode = ALCHEMY_NULL;
	}

	return false;
}